Tuesday, June 30, 2020

The 3179 terminal has arrived! Some bad news as well

The third time on the truck is the lucky trip, as the box was delivered at noon today. The packaging was intact and the terminal inside was well padded. I hauled it around to the bench to begin some testing.

The blinking light and beeps from the Logic Element that sits below the CRT suggest that this unit is working properly. The real evidence comes from what you see on the screen and how it responds over the coax cable, but this was a good start.

The bad news is that the CRT is exceedingly dim. At full brightness adjustment I can just barely see a thin blue line down near the bottom, probably a divider between the status line and the user accessible lines of the display. When I flip the test switch I don't see any characters - the screen should fill with characters to test out the character ROM mapping - but that could be due to the lack of a connected keyboard.

The most likely scenario here is that the tube is really worn out with massive oxidation on the cathode reducing electron emissions to paltry levels. There could be other failures in the Display Element or Logic Element that are causing this, but I suspect not. The reason is that the ebay listing for this had two terminals offered, and the picture showed the blue line about the same apparent brightness on both. Separate monitors and logic elements, unlikely to have the same electrical defect. 

I will turn it on at night and see what may appear in the dark while the Test switch is thrown. Again, I don't know if that would work sans keyboard. The other test I can do is to hook it up to my 3174 substitute and interrogate the terminal ID. If it responds properly that suggests at least partial correct operation of the Logic Element (base box).

Simple solution to the wrap around buffer problem

THE CHALLENGE

My buffer is 2000 characters, with the first 80 reserved for the status line at the bottom of the screen. The remaining 1920 characters wrap, that is location 1999 is line 24, column 80 if you move one character down you should be at location 80, line 1 column 1. This is not straightforward modulo 1920 math because of the status line at the beginning. 

In may places, my code will be moving through a field indexing from the first character position to the last. Fields can exist where the start position is high in the buffer but the field wraps around so that the end position is low. In one test case, my last field on the screen began at location 240 (line 3 column 1) and extended through the rest of the buffer. It was therefore terminated when it wrapped around and encountered the attribute character at location 81 (line 1 column 2). Thus line 1 column 1 was the last position in the field. Yes, it is a contrived example but the code must work properly for all legit cases. 

SIMPLE SOLUTION

In every spot where I accept a buffer address, I handle the wrapping. That is, if I am presented an address less than 80, I add 1920 so that I have 'backed up' to the tail end of the buffer. If I see an address beyond 1999, I subtract 1920 from it so that I wrap around to the low end. 

This allows a 'for' loop to work properly marching up from a start address near the bottom of the screen and its end address being near the top. The loop will calculate indexes that move beyond the end address 1999 but my fix will cause the actual access to wrap. 

3178 terminal code fleshed out including shadow buffer

SHADOW BUFFER

I created a Buffer class that maintains a 2000 character buffer. My code in terminal now writes to the buffer object for insertion in that shadow buffer, with the buffer object also writing a copy through to the regen buffer inside the 3178 terminal. 

Whenever data is written to the buffer object, but not by key press actions, I run a method that builds a list of tuples defining the fields found in the buffer. This is done by scanning the buffer for attributes. These field tuples also indicate whether fields are protected, numeric and when their contents were modified by key presses after it was written by the mainframe (or my fixed code in the terminal script). 

The list of fields helps in implementing the TAB, BACKTAB, HOME, ER INP and ERASE EOF keys correctly, as I can locate the unprotected fields for movement and erasure. 

OPERATOR INFORMATION AREA (STATUS LINE)

The bottom line on the screen is not accessible by the application programmer or mainframe. It is used by the control unit (CU) such as the IBM 3174 to signal important information about the state of the terminal and its interaction with the mainframe.

When the terminal is considered busy or locked due to operator error, symbols appear in columns 9 to 17. I implement these to display the symbols for 'key not allowed in this cursor location', 'this location is numeric only' and 'lengthy operation underway, please wait'. 

In columns 37 to 41, the state of the terminal is displayed. The first column will have a symbol to indicate that the shift key or lock is engaged. The next column contains a symbol to show that the terminal is in insert rather than regular mode. The final columns show the characters NUM when the field is numeric only. 

I modified my terminal program so that it correctly displays the shift, insert and numeric state, as well as displaying the lock and busy conditions. 

A COMPLEXITY TO HANDLE

I found some of my logic falling apart because these buffers are circular. That is, just after cell location 1999 (line 24, column 80) we wrap around to cell location 80 (line 1, column 1). Calculating lengths of fields and matching when the cursor is in a field fails in the last field since it has to wrap around.

Quite a bit of the added functionality worked well, but I found a list of other defects to address. I will keep going on this effort because I am still waiting for Andrew Kay to produce a version of oec that makes use of my keyboard and I am still waiting for my color 3179 terminal.

Fedex sent me the alert that the package was due to be delivered on June 27 by 9PM. In the early evening of that day, they changed the projection to June 28th (Sunday). I was heartened to see that it was marked as onboard the delivery truck on Sunday morning. However, suddenly in the early evening of Sunday, the status went to "Pending, no delivery date set". 

Today, Monday the 29th, I received another message claiming it would be delivered today by 9PM and once again the box was reported as onboard the truck. And, again, in the early evening the status changed to "Pending, no delivery date set". I placed a WTF call to Fedex. 

Their automated systems insisted it was on the truck and coming today. I asked for an agent to show him how it was two days in a row of sham "on the truck" followed by "Pending" but he insisted that it was going to come tonight. He offered to have me call back tomorrow if it once again didn't arrive and they would then, and only then, call their third rate Fedex Home operation that was actually supposed to delivery it, to seek answers. 

It didn't arrive tonight. The service commitment date was June 27th. It has sat in the local area since that time, sometimes pretending to be onboard a truck. Tomorrow morning I firmly expect to receive another cheery promise that it will be delivered and another baseless assertion that it is onboard the truck for delivery. And I know that when I call Fedex, they will contact Fedex Hopeless and be told that . . . it is on the truck. 

Sunday, June 28, 2020

Continuing to update my terminal code to better emulate the 3174-3178 behavior

While I am waiting for Andrew Kay to make some modifications in his oec 3174 emulator project necessary to support the keyboard on my terminal, I can improve my understanding of the terminal and have fun playing around.

I was expecting to receive my 3179 color terminal yesterday, but Fedex abruptly notified me late in the afternoon that they would deliver today rather than yesterday. I had noticed it was listed as sitting in Tracy and not on a truck all day.  I then turned to the Python code to enhance what I had been doing.

My initial work put out a fixed screen of data and managed the fields based on hardcoded locations. Far better for me to emulate the full functionality with arbitrary screen contents and any number of fields at any locations. Thus I built a class called Buffer that would handle this for me and do write-through to the regen buffer inside the 3178.

It builds a list of field tuples upon request. This is called whenever the 'host' writes to it (or my startup where I set initial screen contents). This is a bit wasteful of processor time but safer than trying to sort out the minimum changes to the attribute list based on each write from the host. 

Having the list of attributes allows me to provide functions that validate whether a field is protected or numeric. Eventually it will allow Insert and Delete key operation which moves data but stops at the end of the current field. 

New Apollo items loaned to me including a late model EL panel

The collector who had loaned the three Apollo items to me for my display project brought over three more yesterday! I have a later model Electroluminescent Display Panel which should glow with the correct colors that were visible to the astronauts. He loaned me a second relay module which I will test out. The third item is some kind of display that marketed at auction as coming from an Apollo Command Module but we are not certain.

MYSTERY DISPLAY EXAMINATION, REASONS TO DOUBT IT WAS IN THE SPACECRAFT

The new display has identifications that tie it to Marshall Space Flight Center (Huntsville Alabama), the designer and system integrator of the Saturn V and IB vehicles. The only information I could find on the contract number is that it was finalized in June of 1967. That is relatively late in the design cycle for Apollo. 

Secondly, looking closely at the frosted glass front I can't see any signs of traces to suggest this is electroluminescent, as stated in the auction and as used throughout the spacecraft due to the very low power consumption of that technology. 

Third, its connectors on the rear are a pair of circular sets of solder pins, much like only vacuum tube sockets. This kind of connector and reliance on solder would not have been used in the spacecraft.

Fourth, its body size is much taller and wider than the visible screen area. There is no location in any of the Apollo spacecraft, CM or LM, where we find a similarly shaped indicator. More importantly, no spot has reserved space free of other indicators or controls to match the tall and wide shape of this object. 

Our conclusion is that this is an indicator of some sort procured to support the Apollo program, but likely was used in some ground support equipment. I looked at images of every console in the KSC launch control room as well as all the mission control consoles at JSC, but none had that indicator attached. 

I is probably one of those displays that shows numbers by mechanically moving masks so that the incandescent bulb inside shines on the frosted screen with the pattern of the desired digit(s). Big and bulky enough to house the lamp, solenoids and moving masks. 

Connectors on mystery indicator module

SWITCHING TO THE NEWER EL PANEL MODULE

I switched over to the newer EL panel module, which was boxed and appeared to be an unused spare part thus new-old-stock. When I activated it, the brightness was dramatically better. More importantly to me, it had the proper wavelength. The early version I previously had used was shifted to the blue-green while this one is a nice central green that would have been the color seen by all the astronauts and technicians. 

The COMP ACTY segment works as well, a nice bright rectangle that was illuminated when the Apollo Guidance Computer was running any code other than its idle task. Thus the flickering and percentage of time it was illuminated gave an indication of CPU busy. 

I wired up another driver circuit and the relay in the Relay Module that was used to drive this indicator. That relay is NOT a latching type. It is only energized when the input signal is on. 

New-Old-Spare display panel in operation

GOING FOR BIGGER THINGS, ADDING THE SECOND RELAY MODULE

Next up I am going to wire up the second Relay Module to control the five digits in the R1 row on the display. Those are to the right of the sign I am already driving. This will require five new driver circuits, 93 additional pins, a new relay module plate for the connector, and lots of additional wirewrap connections. 

Normally, to drive the five digits would require five selection line drivers, five column latch drivers, and five column unlatch drivers. However, I realized that I could double the connections from my existing latch and unlatch drivers that are wired to Relay Module 1. As long as I only select the row in one of the modules at a time, this is okay as current will only flow through one relay coil at a time. Thus, I have discrete row select drivers but share the latch/unlatch outputs. 

Friday, June 26, 2020

A session playing with the quick and dirty 3174 connected to the 3178 terminal

I made use of my quick and dirty program to write some initial content into the regen buffer for display. It consists of four fields, two protected and one of them intensified. I choose the first console message of MVS 3.8 at IPL time for the first row, protected and intensified, with the rest of that line being a normal intensity unprotected field. 

I picked a common response during IPL as the second line, in a normal protected field, and set the remainder of the buffer to be a normal unprotected field.

My 3174 program should control when I can type into areas and which areas are off limits, as well as showing the desired content on the screen at all time. It is my hypothesis that the terminal itself only interprets the intensity/normal/hidden attribute, but ignores protected or numeric. Here are some screen shots to show the session. 

Data written initially by my program

Initial screen contents

Updating the screen down on line 4 and testing protected and numeric fields

I used the down arrow to advance the cursor one line lower, the typed in some text. This appeared just as I had expected. I then moved up with the arrow keys to the midst of the intensified and protected part of the first line. As I suspected, what I typed overwrote the characters on the screen. Finally, I moved to the middle of the second line, which I had marked as unprotected but numeric. Typed letters wrote right over the field. 

QUICK MOD TO KNOW WHETHER FIELDS ARE PROTECTED AND/OR NUMERIC

I haven't implemented the buffer in my CU yet, I am only writing data to the regen buffer in the terminal. Before I code up the substantial change to manage the buffer and shadow it to regen, I put some quick and dirty functions I can interrogate to ask whether a field is protected and whether it is numeric. I also have a function that gives the cursor position of the next field, allowing me to mimic the TAB key.

As I process keystrokes, but before I write them to the regen buffer, I check for protected fields. If it is protected, I write the status line section that shows the error of attempting entry in a protected field. I pseudo-lock the terminal, meaning I will only accept a RESET key to unblock it. The RESET key erases the error status on line 25.

Testing again

Updated unprotected areas and wrote 05 into numeric field

Status sign indication for protected or alpha-into-numeric field

After pressing RESET to unlock terminal

More numeric input permitted on line 2

I was generally satisfied with this recreation of functionality. I didn't get the TAB support to operate correctly but that wasn't pressing to fix. 

A tale of two buffers - 3178 terminal and the 3174 control unit

I received a question from a reader from which I realized that I wasn't clear enough in talking about the display and buffer side. This post is a quick amplification

WHATS INSIDE THE TERMINAL THAT DRIVES THE DISPLAY

The box under the CRT monitor is called the Logic Element. It has a 2000 character buffer inside which I call the regen buffer. The logic element is sweeping the CRT beam across the screen, left to right and stepping down after each sweep until it gets to the bottom of the screen. As the logic does this sweep, it advances the index into the regen buffer as it moves from each character cell to the next.

A character cell is a rectangular group of pixels where the pattern of the desired visible character is painted. My terminal has 80 character cells across a line and 25 lines stacked vertically. The user accessible and programmer accessible area is the first 24 lines, with the final line used for status feedback to the operator. 

The logic element begins at the top left corner of the screen, in character cell line 1 column 1. It uses the value of the byte in that first regen buffer position to look up the pixel pattern from the character ROM. Technically, the CRT scans the top row of pixels for all eighty cells then returns to sweep the second row of pixels for all eighty cells and so forth until it finishes the bottom row of the character cell. At that time it moves from line 1 to line 2, the next set of rows comprising the character cells in line 2 and begins with the top row of pixels of that line. 

The CRT is completing this sweep from top left corner to bottom right corner 60 times per second. The regen buffer is used to regenerate the pixels every 1/60 second as the phosphor fades rapidly. 

The logic element has some register that keep track of state, including the cursor position, an index in the regen buffer and thus a character cell somewhere on the screen. When the CRT sweep is moving through the cell whose position matches the cursor position, extra pixels are painted to show the cursor shape. 

A write from the control unit (CU) to the terminal will put the character(s) sent into the regen buffer starting at the current cursor position, then updating that position to just beyond the newly written characters. 

One final task for the CRT sweep is to recognize attribute bytes as they are encountered in the regen buffer. They don't cause a visible character to be painted in the cell; it appears blank. However, if the attribute byte signifies an intense field, the brightness of the beam is increased while painting this character cell and all further cells until an attribute further down the buffer sets intensity back to normal. 

The 3179 color terminal interprets the attribute byte slightly differently, showing the character cell in red, blue, green or white. Optional features add more colors but use a different attribute memory, not the regen buffer. 

WHAT IS INSIDE THE CONTROL UNIT

The CU also has a 2000 character buffer. It should be a mirror of the regen buffer. All read and write operations between the mainframe and the CU occur into the buffer in the CU, but the 3174 then copies them to the regen buffer. The two buffers should always be in sync. The CU addresses its buffer as it needs but its timing is not connected to the CRT sweep going on and the active position in the regen buffer. 

It is in the CU where keyboard and display are logically joined. The CU knows what cursor position is set in the terminal, thus it knows the field that is active at any moment. If the attributes of the field limit what can be entered to the field by the operator, it is the CU that enforces it. If a field is marked numeric, the keyboard is considered to be shifted up and the upper character of each keycap is intended when the key is pressed. The operator does not have to Up Shift in this case. If the field is marked protected, then no data can be entered into the field, which is enforced by the CU.

Movement keys are handled in the CU. For simple arrow functions it just updates the cursor position in both its and the terminal's regen buffer. If it is a TAB, the CU looks forward in the regen buffer from the current cursor position until it finds an attribute byte for a field that is unprotected. It sets the cursor position to the next cell after that attribute byte. This can move anywhere from 2 characters to almost 1920 characters depending on how far away the unprotected attribute byte is sitting. 

The attribute byte of a field has a Modified bit, which is turned off when the field is received from the mainframe and is turned on if any characters are entered in the field due to operator keypresses. This allows the CU to send back only modified fields to the mainframe, disregarding those fields that were not changed. 

Normal keypresses involve only the CU and the terminal, with characters changing on the screen and cursor movement taking place. However, a number of control keys are intended to be sent to the mainframe to indicate various operator choices. For example, the ENTER key causes the CU to respond to the mainframe with a message indicating ENTER was hit. Typically there will be an exchange between mainframe and CU at this point while the operator waits at the terminal. 

Other keys can request program actions, keys such as PF3 or PA1. These presses cause the CU to respond to the mainframe with a message indicating which of those keys was struck. This may be the only interaction between CU and mainframe or the program may decide to write some new data into the CU (and regen) buffer.