Sunday, July 5, 2020

Implemented the Num Lock feature on my terminal


The 029 and 129 keypunches that would have been the data entry devices of choice prior to the arrival of these terminals created punched cards. The card was often divided into fields by a program drum or equivalent program card ready by the 129. 

Fields could be skipped over, automatically duplicated from the contents of the prior data card, and forced to be numeric (shifted). Thus, the operator would type away without having to hold the shift key for numeric fields and without having to space over any areas of the card that were not being updated.

Since the keyboard type I have, Data Entry Keypunch, is usually associated with the same type of tasks as were done by the keypunch operators, it makes sense that it would allow similar efficiency for typing - skips, auto numeric shift, etc. This explains the special role of a numeric & protected field in forcing a skip operation. 

A feature could be installed in the 3174 or other control unit, Num Lock, which would treat any numeric & unprotected key as if the operator had already held down the numeric shift key or set numeric lock. As soon as you tabbed or autoskipped into a numeric field, the terminal was in numeric mode to interpret key presses as the upper character printed on the cap. 

Implementation was simple, as I already had logic in place to identify the numeric field and display NUM on the Operator Information Area (status line). I only had to implement the equivalent of Numeric Lock to force it to be shifted. And, of course, I had to remove the shift when we exited the numeric field. 

Saturday, July 4, 2020

Added auto-skip behavior to my 3178 terminal


Autoskip is a behavior that the terminal exhibits as you type in the last character position of a field. It will skip to the beginning of the next field, or further, depending on the attributes of the next field. If the next field is both numeric and protected, it continues until it finds the next unprotected field. However, if the immediately next field is unprotected or alpha protected, then the cursor will be sitting at the start of that field. 

Essentially there are two types of autoskip that the terminal implements. Normally it just positions the cursor at the start of the next field, whether that can be typed into or not. The alternate is triggered by having a numeric+protected field immediately after the current one. In the alternate case, the autoskip acts like an auto TAB instead. 


At the point that we have a character typed and ready to be placed into the buffer/screen in the last position of a field, I look forward to find the appropriate start of field position, either the immediate next one or the first unprotected one, using the rules above. I mark this movement, then proceed to process the typed character.

After the typed character is written to the screen, if an autoskip movement was requested, I move the cursor there. Thus when I key in the last position of a field, I see that typed character on the screen and the cursor is now at the first position of an appropriate field further down the screen. 

Implementing Cursor Select key functionality


One feature available on 3270 type terminals is the light pen. This is a pen shaped object on the end of the flexible cable (actually a fiber optic cable). When it is pointed at certain fields on the screen which are defined with the ability to be selected, the control unit (CU) sends a selection status to the mainframe indicating which field was selected using the pen. 

The attribute byte interprets its 2 bit display field as 
  • 00 - Normal, not selectable
  • 01 - Normal, selectable
  • 10 - Intensified, selectable
  • 11 - Hidden, not selectable
Fields that are marked selectable must also have a specific designator character after the attribute. There are two broad categories of these fields, selection fields and attention fields. The selection field allows the operator to select an item usually from a list but does not signal the host of this event. The attention field on the other hand does signal the host.

If the field has a question mark as the designator character, it is a selection field. If the light pen or CURS SEL key is used with the cursor in that field, the CU will change the ? to a > character which is a visual indication that it was selected. This field is marked modified so that the host can read modified fields at some later time and get this. The user can hit a selected field again and reset it to unmodified with a ? displayed.

There are two subtypes of attention fields. Both create an event (similar to when the operator hits a key like ENTER or PA1 or PF5). With a designator of space or null, what is transmitted to the host with that event is only the address of the field that was selected by the pen or CURS SEL key. If the designator is &, then the event sends back both the address and the rest of the data in that selected field. 


The CURS SEL key is provided for those who do not have a light pen attachment on the terminal or who wish to use the keyboard exclusively. When the cursor is in a field that is set up as selectable, if the CURS SEL key is pressed and the designator character is ?, >, &, space or null, then it behaves just as if the light pen had been touched to that field. 


I added a test function in the Buffer object, isSelectable, to be used when the CURS SEL key is detected. When processing that key, I retrieve the first character of the field itself and interpret it as the designator. If not a designator, the keypress is ignored. If it is a ? or >, I toggle the character in the buffer.  If it is an &, space or null, I issue a print indicating that we had an attention selection event.

Friday, July 3, 2020

Continuing to test my 3174 substitute functionality and fix bugs


I found a number of places where the code wasn't doing what it should. As an example, it is possible to enter characters past the right end of an unprotected field, wiping out the attribute character immediately following. It was necessary to identify these and flag them as protected.

I was also failing to handle Insert mode properly for space bar keypresses, as it was treated differently from the other characters, as if it were a control key. The Backspace key is a control function and I erroneously grouped them as if they were similar. I moved Space over with the other characters and that was resolved. 

My initial code for the Tab and Backtab keys just moved to the next or previous field, but it should have skipped over any protected fields. Thus, Tab means the cursor will go to the next unprotected field. Used a simple while loop that executes repeated movement to the next field if the field is protected, stopping when it reaches the next unprotected one. 

The terminal has a down shift key, which is used to temporarily cancel the effect of the Shift Lock key (actually not capital versus lower case letters but lower versus upper character printed on the key cap). However, I wasn't processing that properly nor was I updating the status line as needed.

Once everything seems totally solid, I will film a video using the terminal and upload it to YouTube. I set up a very simple form, entering name, ID number and some notes. It will demonstrate the various movement and data entry methods as well as the status line and appropriate validity checking. 

Wired second Relay Module to animate the R1 digits on the Apollo DSKY panel


I don't know what is going on with delivery services this week, but once again I had a bizarre elongation of a shipment occur here in Northern California. The plate was laser cut by Ponoko and ready for shipment by UPS Next Day air by midday Monday. Since I live less than 30 miles from Ponoko that should be an easy delivery for UPS. 

However, UPS never showed up on Monday to pick up packages. Tuesday they accepted the Next Day Air package but then absolutely nothing happened all day Tuesday and up until very late Wednesday, totally blowing the delivery 'promise' of next day air. Finally by late evening it began moving and was delivered Thursday, turning an overnight shipment into a three day shipment. 

Putting that aside, the plate was perfect as usual and I quickly mounted all the pins to allow me to enter five bit codes into five rows of relays, thus switching the segments on the EL panel to light up all five digits of the first (R1) register row. This adds to the Prog, Verb and Noun digits, the COMP ACTY light and the sign for R1 that were already being controlled by the first relay module.


I paralleled a number of lines between the two relay modules, such as the AC high and low wires and all the set and unset (latch/unlatch) connections. Therefore, when my Arduino activates a set for one of the five columns that encode a digit value, it will be present on that column of BOTH relay modules. Since both the set/unset and the selection lines must be active to actually operate a relay coil, as long as the select lines are unique to each relay module, this will work fine.

I did have to build five more driver circuits for the new select lines, hook those drivers to the Arduino and finish updating my firmware to allow me to put values into the digits. Fortunately the components arrived on time from Mouser today. These driver circuits were wired to the select lines on the new relay module. 

Before I completed wiring the new module up to the segments for the R1 register on the EL panel, I tested the latch and unlatch for the digits. I set a few test values and checked for switched AC on the output pins of the relay module.

Once all appeared well, I did the wirewrap connection of the 35 wires from the R1 digits between Relay Module 2 and the EL Display Panel Module. Some visual inspection and sanity checking were conducted before firing up the project. Mainly I wanted to detect dead shorts of the high voltage AC and insure there was no leak of the AC over into the low voltage DC control lines. 


Here is a view of the panel working with everything I have wired up. If I wanted to take it to the next level, I would have to build a new PCB with 74 relays to take the place of Relay Modules 3 and 4, strictly to light the ten digits spread across R2 and R3 as well as the sign for those two rows. 

Leftmost digit of R1 intentionally blank

Since the relays would need to work safely with 275VAC on the contacts, I can't just grab the cheapest relays. In an ideal world, I would need 54 latching DPDT relays but that would make the cost and size extremely high, so I can settle for SPST relays with one per segment being controlled. 

Frankly, the additional cost and work goes up dramatically yet the incremental value of seeing the other two register lines is not commensurately high. Therefore, I will stop at this point and declare the project a success. 

Wednesday, July 1, 2020

Starting point for my substitute keyboard for the IBM 3179 terminal


There were three IBM part numbers for type M keyboards for use with this terminal - 1385151, 1389160, 1693640 - with the latter having a very similar Data Entry Keypunch key arrangement to my 3178 keyboards while the others are typewriter style arrangements.  

These use a 5 pin DIN connector but not the same as used on PC/AT keyboards, having a bidirectional serial protocol using a data and a clock line. The protocol is known to be the same as used with newer terminals such as PS/2. That also means the protocol is well described.
Serial protocol with the 3179 keyboard and terminal
Presumed commands from terminal to keyboard


Whether I will attach one of my 3178 keyboards through a converter or just build a converter that talks to more modern systems, I can start with the open source code and documentation of the TMK keyboard project. It includes kicad PCB designs for converter boards as well as the firmware. 

This will not be a direct use since the purpose of the TMK code is to make use of physical keyboards such as what I am seeking, using them with modern systems via PS/2 or USB connections. In a sense, the reverse of what I want to do, which is use something modern to pretend to be the physical keyboard.


There are still some unknowns even with everything I will know after reading over the TMK project information. It would be easiest to simply capture the dialog between a keyboard and a logic element, but I don't have the keyboard so that is moot. 

The Logic Element of my 3179 terminal will either interrogate the keyboard for its keyboard ID or will do a Reset which expects the keyboard ID to be returned. I don't know what to return that will satisfy the Logic Element, but I might be able to find out from others who have converted real keyboards to use with their PCs as they may have captured or be able to capture the returned ID. 

The keyboard is sent a request to adopt a scan code set, basically a mapping of physical keys to the returned code. Many modern type M keyboards will only speak one set, the modern one, but my keyboard may have worked with an earlier set. I don't know what it was or how to respond to the scan code set request message.

The 3179 Guide document mentions the need to set eight dip switches on the bottom of the keyboard to a particular configuration that matches what the Logic Element expects, or they will suffer a mis-configuration error. Perhaps this eight bit code is the terminal ID to be returned?


I have a connector layout for the keyboard but it has much more than just the power, data and clock lines that are analogous to the 3179 keyboard. I see the additional signals
  • Reset
  • Data Available
  • ACK
  • CMD0
  • CMD1
  • PE
  • PE
Unverified pin assignment for 3178 keyboard

Since the scan codes are purported to be unidirectional, keyboard to logic element, the additional lines may be to transfer requests to the keyboard. On the other hand, Data Available sure sounds like a signal going to the logic element. 

I may have to wire up a logic analyzer and capture some traffic between my 3178 Keyboard and its Logic Element in order to understand these pins more fully. The keyboard enclosure contains a clicker that can be switched on or off by the host, which may account for some of the commands that could come. Further, I would expect that there is a way to ask for the keyboard ID which is decimal 9 in this case. 

Tuesday, June 30, 2020

First test of 3179 terminal in darkness


The Operator Information Area (status line) across the bottom had a symbol and the number 3, which the User Guide for the terminal gives as the error "Keyboard not attached or functional". That is indeed the condition here as I don't have a keyboard to attach. The three keyboards I have are the type with a rectangular connector to fit to the 3178, while this terminal uses a circular DIN style connector. 

Test mode but failing with keyboard missing error (3)


When I put the terminal into TEST mode using the Test/Normal switch, it beeped a few times and showed the word TEST on the status line. No characters were displayed above the blue line. Upon reading the Guide for the terminal it became obvious that the keyboard error message above stops any further testing or action. Until I bypass that error or substitute a keyboard, I won't get any further.


I do have documentation of the pin assignments for the keyboard connector, essentially it has +5V, a clock and a data signal. I imagine I can work out the details of the protocol and enough to at least convince the Logic Element that the keyboard is present and working, although it might require a microcontroller or small FPGA. 

An interesting possibility is if the keyboards I have for the 3178 use a compatible protocol, even though they have a different connector, I might be able to bridge one to the other. This is a bit more unknown that the paragraph above.

Finally, I still have an extraordinarily dim CRT at full brightness. As you can see from the picture taken with flash, with the terminal illuminated the blue line is swamped, same as with daylight. 

Blue line almost invisible in bright lighting

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


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. 


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. 

Monday, June 29, 2020

3178 terminal code fleshed out including 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. 


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. 


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.


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


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


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. 


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


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. 


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. 

Thursday, June 25, 2020

My quick and dirty 3174 control unit brings the 3178 terminal to life


Andrew has done a brilliant job building a substantially complete 3174 controller for use with two terminal types, a 3483 and a 3279-2, both of which he owns. However, the 3178 has a different keyboard layout, therefore a majority of the keycaps will be misinterpreted by his existing code.

I am helping build a mapping for my keyboard to fit into his code, but it will be a bit of time before it is integrated and I have the entire oec package running. In the interim, I made use of his pycoax package of utility tools and built a python program to act as a simple 3174. 


Almost all the functionality of the 3270 class terminals is implemented in the control unit (CU), such as the 3174. The terminal sends keystrokes back in response to polls from the CU but otherwise ignores the keypresses. 

The other, independent half of the terminal is a 2000 byte buffer, called the regen buffer, organized into 24 lines of 80 characters plus a special final line that is called the Operator Information Area but could casually be called the status line. The CU will write data into the regen buffer and those bytes select a character that is displayed on the screen. 

The operator is accustomed to pressing keys and seeing the character matching that keycap appear on the screen at the location where the cursor is positioned. Arrow keys allow movement of the cursor around the screen, and other control keys can effect the screen in different ways. However, the connection between keystroke and screen appearance is totally controlled by the CU.


I built a module that associates each scan code from the keyboard with its role. There are three types of scan codes that are returned to the CU - hardware events, control keys and characters that display on the screen. Control keys can be the arrow movements, TAB keys and many other types. 

The scan code for a given physical key is fixed, however the character or function associated with that key depends on two modifier conditions. The ALT key is held down to cause a given key to be interpreted as its ALT modified role. If the operator has shifted the keyboard to upper case, by use of keys like Up Shift or Caps Lock, then the scan code is interpreted as its shifted role. If the keyboard is not shifted up and the ALT key is not depressed, then the key is interpreted in its base role. 

My table for scan codes keeps track of several facts for each code. For keys that produce a displayable character, we store the regen buffer code to display the character in both the base role and the shifted role. We also store the ASCII character for base and shifted roles. For keys that produce a control function, we store the base and ALT function. A few codes represent hardware events such as Power On Reset Complete, but we can ignore these. 

My quick and dirty program loops sending POLL commands to the 3178. We receive back scan codes when a key or event has occurred. I look up the scan code and act appropriately.

If the code is a displayable character, I pick up the regen buffer code and write that character into the regen buffer. In that way, the pressed key shows up as a character on the screen. If the key is pressed while the keyboard is shifted up, I use the shifted version instead of the base version. For example, the keycap with J on it will pick up the code for a J if not shifted, but if the keyboard is shifted up, we pick up the code for 4 instead. The keycap shows J on the bottom and 4 on the top of the cap. 

I also keep track of the cursor position. The terminal maps the first 80 characters of the regen buffer to the bottom status line, then begins at position 81 with the top left position, line 1, column 1. Each time the user types a character that can be displayed, I write its code to the buffer and bump the cursor position up by 1. 

I then implement a number of the control keys, based on the key pressed and whether the ALT key is also depressed. The arrow keys increment or decrement the cursor position by 1 or 80, thus moving the cursor up, down, left or right. The HOME key moves the cursor to line 1 column 1. New Line moves the cursor to column 1 of the next line. A few others are implemented.

Many of the control keys just send a special code to the program but don't affect the displayed screen image or contents of the regen buffer. Program Function keys (PF1 to PF24), Program Action keys (PA1 to PA3), RESET, ENTER, and PRINT are examples. All I do when I receive one is print a message on my laptop screen 


The current state of my program uses the terminal as a single unformatted display. This means that there are no attributes for individual fields, such as protected from user modification. It means that the field oriented functions such as TAB are not relevant. 

I enjoyed typing text, moving the cursor about and changing text on the screen. I watched the program recognize the various control keys. It was time to up my game, so that I could implement more functionality including field behavior. 

Over the next few days I will implement a shadow 2000 character buffer in the CU, writing displayable characters in both buffers. I will recognize and implement the function of attributes. These appear as blank positions on the screen, because the terminal doesn't display a character for any regen code in the range of xC0 to xFF. Those are the ranges of value that represent attributes. Ignored by the terminal in the regen buffer but important to the CU.

When a key is pressed, the CU must pay attention to the attribute that covers the current cursor location. If the field attribute is protected, the character is NOT placed into the buffers at that location. Instead, the status line shows an error status and all keypresses are ignored until the RESET key is pressed. 

The TAB function scans forward from the current cursor position until it finds the next unprotected attribute and sets the cursor one past that byte. Keys like INS and DEL control whether a pressed key replaces the data at the cursor location, is squeezed in moving the rest to the right, or the char is removed and the remainder pulled left; all of the movements are within the current field only. 

When the attributes are written, they have the M (modified) bit off. When a keypress causes a new character to be placed in the field, the CU will switch on the M bit. Generally the mainframe is only sent fields whose M bit is on, minimizing the data transferred over comm lines or a channel. 

Wednesday, June 24, 2020

Keyboard and character set of my 3178 terminal


Data Entry Keypunch keyboard from the IBM 3178 terminal


The reason that the main screen characters are restricted to the range of 0x00 to 0xBF is that the way the controller and terminal distinguishes an attribute byte from a data byte is through the high bit being 1. A screen on a 3270 is typically broken into fields, each beginning with an attribute byte. This byte specifies how the subsequent screen positions behave, up until the next attribute byte. It may protect a field from update by the operator, make the characters intensified, or restrict the typed information to be numeric. 

Screen character codes on the 3178

The bottom line of a display is a special area, called the Operator Information Area. It is always protected so that the operator cannot type in it and the arrow/tab keys won't move the cursor there. Because it is not programmable, it does not need nor use attribute bytes. Thus, for this special last line, the codes from 0xC0 to 0xFF can represent displayable characters that are only used in this area. 

Special characters for OIA line, courtesy Andrew Kay

Developing my scan code functionality for the 3178 terminal and keyboard


The 3178 sends back scan codes to its control unit, whether a real IBM 3174, some other CU, or the 3174 substitute I am working with. The CU will take such actions as writing a character on the screen that corresponds to the keycap you just pushed. It also tracks the case you are in, such as holding the 
Shift Up button or the Upper Case Lock button having been pressed. Finally, it has an ALT key that is a modifier to select an alternate function for a given key. 

The scan codes are not ASCII. They are not EBCDIC. They are not even the native character set of the display. They don't have a fixed assignment to a character; instead they represent some internal logic for how the keys are wired. 

Since the 3178 terminal can have a variety of keyboards, such as 75 or 87 key, with different arrangements of keycaps. Some are intended for Data Entry, some are considered Typewriter style, others may suit programming better. Thus, the CU has to know the specific keyboard installed on the terminal so that it can interpret a scan code. A given physical key on the keyboard may have the same scan code across all keyboard types, but its keycap and the intended character or function will vary.

I extracted all the scan codes returned by my keyboard, which has 87 keys in a version of the Data Entry Keypunch style. I will make use of this to convert the key that was pressed into the intended character. Further, some keys represent characters that will display on the screen, some represent hardware status, and some represent control functions that must be executed.

As an example of control functions, the TAB key is intended to cause the CU to move the cursor to the first position of the next field on the screen. The ENTER key is used to signal to the mainframe that all desired keystrokes have been entered into the screen and thus the application should read the typed field to begin processing. 


The 3270 style terminals use a byte to represent a character that should be displayed in each position of the screen. There are 255 possible characters, plus null, which supports a decent sized character set of upper and lower case letters, numbers, special symbols and quite a few characters for use with foreign (but latin alphabet oriented) languages. 

Of the 256 possible codes, 1/4 of them are reserved for special control symbols that are used on the bottom status line (called an Operator Information Area). The remaining 192 characters are used on the main display area, usually some multiple of 12 lines by 80 characters which depends on the terminal model. Mine is a 24 line by 80 character display.

The code used is not ASCII or EBCDIC. It is an internal code that indexes into a character ROM to choose the pixels to illuminate in each character cell. x80 encodes the lower case letter a, while xA0 is the upper case version of A. x22 encodes the numeric digit 2 while x18 represents the question mark. 


Programs on the mainframe who are sending text to place on the screen, and who are receiving the typed input from the operator, don't receive scan codes nor the internal 3270 character set. All data is translated into EBCDIC usually, unless an uncommon feature was installed that provides ASCII instead. The upper case letter A is xC0 in EBCDIC and the digit 2 is xF2.


Thus, when I hit the keycap marked A on my keyboard, it sends scan code x182. That is translated to xA0 for display on the screen and to xC0 for transmission from the CU to the mainframe host. This is layer one of the conversion required. 

Also, the role of a keycap depends on whether the operator has shifted to upper case. The keycap on my terminal represents an X in lower case and a question mark in upper case. Thus, the CU has to know whether the current state is shifted up or not. Keys such as Shift to Upper, Lock in Upper, and Shift to Lower are used to adjust that current state. These keys are unique in having two scancodes associated with each one.

When pressing Shift to Upper, the code x136 is transmitted, then when the key is released it sends x336. The CU will remember that we are in upper case based on having seen an x136 and drops back to lower when it receives the x336 code. In a similar way, the ALT key sends x13e as it is depressed and x33e when released. 

The numeric keypad on my terminal makes use of both of these. In normal mode (not upper case and not ALT), the twelve keys produce program function codes PF1 thru PF12. If ALT is active (key held down), then these produce PF13 thru PF24 instead. If instead the CU is in upper case mode then the pad produces the ten digits, decimal point and TAB. We can be in upper case mode by holding down the Shift to Upper key, or by having pressed the Lock Upper Case keycap. 

One fact that may not be obvious is that the keyboard has no way to produce lower case letters. When in lower case mode, a keycap such as B produces the upper case B character. Then shifted to upper case it represents the exclamation point (!)character. Applications can send the code x81 to display a lower case b or xA1 to display an upper case B, but the keyboard only produces capital letter codes. 


To the operator, it appears that when the cursor is blinking in a field that is not protected, any key that is pressed produces the associated character on the screen immediately. Further, movement keys such as TAB or down arrow move the cursor immediately. Control keys such as CLEAR cause the entire screen to become blank. 

None of those actions are done in the terminal. Instead, scan codes are sent to the CU which in turn makes appropriate changes to the screen in front of the operator. Pressing the keycap for a C will cause the CU to update the screen at the point of the cursor with the code xA2 and we see the C displayed. 

Pushing TAB tells the control unit to look through its buffer to find the start position of the next unprotected field and move the cursor to that point. The user sees the cursor jump. Hitting CLEAR sends the code to the CU, when then erases groups of four character positions at a time until the entire screen is cleared.

When the keycap marked B is pressed, the CU decides if it is sending a B or a ! to that screen position. It does so based on what it had last seen done with the shift keys. The keypad on the right is even more complicated. Pressing the keycap labeled PF4/4 will be interpreted as a PF4, a PF16 or a character 4 depending on whether the ALT key or the shift state is active. 

When a user has the cursor in a protected field but presses the G keycap, the CU receives that scan code but locks the terminal and displays a status character on the last line that informs the operator that data cannot be typed at the current cursor location. The scan code is still sent, it is just thrown away by the CU. 


I built a Python object that, when given a scan code, can tell us if this is a control key, a hardware status such as Power On Reset Complete, or a screen oriented keycap. Further, it can give us the 3270 native code for that scan code, to write to the screen. It can also give us the ASCII equivalent which I can use in the program for diagnostic or logical purposes.

Later we can convert the native 3270 characters to their EBCDIC equivalents for transmission back to a mainframe host, but that is not in the first version of this code. 

Serial link bug in 3174 substitute system is corrected!

Andrew Kay, the designer of the 3174 substitute project (Andrew's project page)has hunted down and exterminated the bug that caused the spurious character injection into the serial stream. It was not a flaw in his code but some undesirable behavior of the pyserial library interface with Windows drivers for the USB port and virtual COM port. Having spotted the conditions that triggered this misbehavior, he changed his code so those conditions did not occur. 

Now that this works, I can continue with two minor projects. The first is the exploration of the behavior of my 3178 terminal and experimentation with different streams of commands. The second is the installation of Andrew's full 3174 emulation package and testing with that. The package will allow me to use my physical 3178 terminal with real and virtual mainframes, particularly Hercules the mainframe emulator. 

Tuesday, June 23, 2020

Working on the issues with second digit of VERB display on DSKY panel


Initially my only problem was with the top horizontal segment (F) being absent. I did some touching and inspecting of the wiring and pin placement of the connector on the EL Panel and found that the top three segments were now blank - E, F and H.

After some probing of the wires I recovered the function of segment E, but F and H remain blanked. I already knew from logical analysis that it wasn't a problem in the Arduino or driver board. This is because the code to set up a digit is the same for all positions, the drivers that select the VERB area also control the working digit, and the drivers that control set or reset of the latching relays for the digits are the same for all digits. 

Therefore, any failure of the microcontroller or driver board would not affect just one digit position. Similarly the power supply is common for all digits and lighted segments. 

The likely suspects are:
  • Wiring between Relay Module and pins for segments F/H
  • Contact from the connector to the EL panel for those two pins
  • Failure inside the EL panel, similar to how the COMP ACTY segment doesn't work
  • Failure of relay contacts/wiring inside the Relay Module
  • Failure of the relay itself to latch or unlatch
A look at the wiring of the relays in the Relay Module shows that failure of segment H is isolated to one relay and one set of contacts, but the failure of segment F would also cause segment M to fail, which we are not seeing. plus that relay drives segments E and N. This makes the failure of the relay latching extremely unlikely, and the only internal failure in the module the could explain this is double failure of two independent wires inside the module.  

I decided to do a binary search for the cause. First step was to use my voltmeter to determine whether the pins for F and H were receiving high voltage when selected. If so, the issue was in the EL Display Panel Module or connector If not, I had to look backwards to the Relay Module. 

The result was definitive. I had full voltage on all the segment pins for that digit, so they should all be lighting. However, they weren't. This excludes many of the suspects from above and leaves a smaller list 
  • The miniWasp connector is not making good contact, even though the tail has voltage
  • Something has failed inside the EL Display Panel Module itself. 
The three failed segments (yes, I am back to all three of E, F and H being blank) are not contiguous pins on the back of the module. Two are adjacent but the third is far away. The only closeness is that they are the three upper segments of the digit, top horizontal and the two upper vertical segments. There could be a common fault in the module causing this problem.

On the other hand, I had rocked the connector block slightly to see how difficult it would be to remove when I swap for the newer EL panel. The segment defect began after that action. Thus I could have a connector/connection problem. 


The owner of the DSKY parts I am using has kindly offered to drop off two additional modules. One is a second relay module and the other is a different and newer EL Panel Module.

The second relay module would necessitate significant additional wiring and six new transistor driver circuits. It also means I have to remove the EL Panel Module connector and add 35 more pins to light the five digits of the R1 field which I can now accommodate with the added relays in the second module.

The Arduino would need six additional output pins and some minor reprogramming.

The electroluminescent panel I am currently using is the first iteration of the specs. Among other characteristics that changed for the later production panels used on missions, the wavelength of the light is 5100 angstroms, a blueish-green color.

The versions that were installed in the actual spacecraft and ground simulators were shifted to a wavelength of 5300 angstroms, more of a yellowish-green.  I am excited to receive the newer EL panel module because I will then see the display exactly as the astronauts saw them. 

The Vintage Computer Festival takes place in a number of locations each year, including the VCF-WEST out here in Silicon Valley. Due to the pandemic, it won't be feasible to have the large crowds and interactions this year. The organizers have decided to conduct a virtual festival. There will be five minute videos in place of a physical exhibit.

In past years, I have exhibited my restored IBM 1130 mainframe and a life size working replica, a restored Xerox Alto, working teletypes, and talked about our restoration of an Apollo Guidance Computer, all in person. This year I will talk about the challenges, solutions and work involved in lighting up the DSKY panel. 

Monday, June 22, 2020

Finished testing DSKY project


I did continuity tests and resistance tests for safety. All the relay coil wiring is low voltage DC (14V) while the contacts controlling the electroluminescent display are switching 275VAC 800 Hz. If the two mix, it won't be a good thing for the relay coils, diodes, nor for my driver transistor circuits and the Arduino. 


The high voltage is output from two sets of pins on the Power Supply Module, labeled 800LO and 800HI although the notion of low and high have no real meaning for alternating current. The 800LO side are connected to a pair of pins on the EL Display Panel Module that are called 'ground' but are really a common side of the many capacitors formed by the segments on the panel. 800LO is also connected to the Relay Module as it grounds segments when they don't have 800HI applied to them. 

The 800HI lines are tied directly to the pin on the EL Display Panel Module that illuminates lines and rectangles behind lettering, as well as to many input pins on the Relay Module. I suspect that having a separate 800HI for each column of the five bit relays for a digit helps with ground testing and checkout. It certainly isn't a matter of dividing up total current, because the usage of the entire display panel is quite slight. 

I took the time to clean up the small breadboard where I had built the replica of the output driver circuit inside the Apollo Guidance Computer which feeds an 800 Hz square wave into the first transformer of the Power Supply Module. On the Apollo spacecraft there is a dimmer (potentiometer) that can short part of the signal across the first transformer primary, thus reducing the output voltage and as a result, dimming the panel. I put in a 10K resistor which represents the dimmer wide open on the bright side. 


With all digits and signs off, when I applied power I saw the lines and text blocks illuminated, showing that all appeared well. I had written a simple command language for the Arduino with verbs PROG, VERB, NOUN and SIGN for the display elements I am lighting. 

Firing up a serial monitor (terminal program) to the Arduino, I commanded that all digits be set to 8 and the sign be turned to plus. This lights all segments I have wired, confirming that the Power Supply Module is able to deliver consistent brightness even with all segments on. 

With all segments active I found that I have one segment that is not lighting. The rightmost digit of the VERB section is missing its top horizontal line. It turns a 6 into a b with that segment missing, but doesn't impact digits like 1 and 4 that don't use it. Tomorrow I will check through the wiring and do more testing until I know why this is happening and what actions will restore full operation.

I then issued a mix of commands causing different digits and signs to show on the EL Display Panel Module. Once the missing segment is working, this completes the entire project to demonstrate the use of Apollo hardware producing the display output. 

As a proof of concept, I set up the display with certain digits and a sign showing, then powered everything off. When I later switched on power, the same display is visible. This is due to the use of latching relays in the Relay Module. They retain their state even across a power outage and only consume current when switching on or off. 

Sunday, June 21, 2020

Experimenting with my 3178 terminal using Andrew Kay's 3174 control unit replacement


Andrew provides a set of scripts that accomplish functions such as polling, writing data to the screen, moving the cursor location, and all the others that are available to send between an IBM control unit and a 3270 class terminal 

One of them wrote Hello world! three times across the first line of the terminal. The second one polled the terminal for responses as well as writing Be sure to drink your ovaltine on the screen. The character mapping that I had found on bitsavers wasn't helpful but Andrew took pictures of the result of all possible hex data values. 


I updated the 'ovaltine' script slightly just to experiment with the keyboard and to try out the special control characters that are displayed on the lowest (status) line of the terminal. At the end I looped doing polls of the terminal, printing out the scan code of any returned keypresses. 

Scan codes for 'hello world!' keypresses


IBM documentation on the 3270 terminals described the process of an operator entering data into fields and then hitting Enter as a local activity. It implied that you use the arrow keys to move the cursor around, then when the cursor is in an unprotected field, keys you press show up on screen and are marked as a modified field. The Enter is the only action sent on, with the mainframe program then reading modified fields to extract the newly typed data. 

It suggested that you could change it several times but only the final is seen when you hit Enter. I presumed, incorrectly, that the local process described above was done totally in the terminal and didn't involve the 3174 control unit except for when the Enter key was pressed. 

As I began to experiment, I realized that the keyboard and the display side are independent. They share a coax interface to the 3174 but nothing done on the keyboard directly affects the display on monitor.

Instead, the 3174 continuously polls the terminal and receives responses to every keypress! The 3174 is then responsible for sending an echo of the character back over coax to the display buffer. 

This explains why there is no configuration switch on the terminal to indicate which of the many keyboard types are attached. The system programmer will configure the 3174 to tell it which keyboard, such as typewriter or data entry style, so that the control unit can decide that a given scan code for a keypress is a given screen character. 

Some keyboards have the numbers across the top, others have them shifted above letters, as a consequence the 3174 has to decode the keyboard and convert that to a given 3270 character. 

A request for Terminal ID returns information about which keyboard is attached, what the size of the screen display is, and the protocol spoken. 

Much of what I thought was handled in the terminal is purely processed in the 3174. The screen has attributes at the front of each field which set the intensity, hide the data and determine if the field can be typed into. Since the KB and display buffer are independent, protecting a field is solely done in the 3174 not the terminal.

Even tabbing to get to the next field is done totally in the 3174, which maintains a shadow buffer to match the one in the terminal driving the CRT. 

Saturday, June 20, 2020

IBM 3174 Control Unit replacement is working after long painful debugging


The Python side software was generating various errors where lengths didn't match, responses didn't make sense, or other logical issues. As I had discovered, most of the issues seemed to be caused by extraneous characters injected into the serial stream (usually a hexadecimal F0 but sometimes others). I hunted the cause by replacing everything that was suspect and adding in appropriate debugging output.

I swapped USB cables, Arduino Mega machines, even moved to an older Windows 7 pro laptop, reinstalled software . . . nothing made a difference. 


I modified the code in the Arduino to simply echo back the exact message it received, nothing more. I could communicate flawlessly with the Arduino using the IDE Serial Monitor. That seemed to confirm that the USB ports, Arduino and other elements of the link were working properly. Secondarily I started the program which also proved that it was echoing correctly with no added characters.

I then tried to unwind everything that might be messing up writing from Python. The code used the SLIP library, a protocol to send packets over serial. It frames the start and end with the control character \xC0 and has various escape codes just in case the data inside the packet must be \xC0 or the escape code itself. 

I wrote a state machine to read the stream with the SLIP protocol and to write directly to pyserial's serial stream, bypassing the sliplib entirely. No change. I varied every configuration parameter or sequence of code I could, without a change. 


Finally, I realized that this corruption seemed to be introduced by the initial reset command sent from laptop down to the Arduino. I modified the code to skip that function, and the issue went away. I still don't know why it malfunctions, but I have a suitable bypass. I can move on to more interesting tasks - interacting with the 3178 terminal. 

It is late and dark out where the terminal is sitting, but I was able to interrogate the terminal ID, terminal status and to write some data on the screen. This is a great beginning.

Friday, June 19, 2020

More than 3/4 done verifying segment patterns for various codes sent to DSKY Relay Module


I found that I had skipped wiring one of the five AC high lines that feed the five columns of relays for every digit, thus the H segment of the displays was not being connected to power. I corrected that and began to get much better results.

The sign display was not switching, which I quickly traced to my omission of the Arduino code to set the pins for + and - to output mode. They began switching just like the digits and the continuity tracer showed them activated or open as appropriate. 

I began to send unique digit values to all six positions, which flagged a wiring error in the cable from the Arduino to the transistor breadboard, where two pin positions were inadvertently swapped. That was set straight.


I checked out all ten digit values for correct segment activation, including moving values between positions such as VERB to PROG. I was completely satisfied with the PROG and NOUN digits, but still have some odd behavior with the two VERB digits. Tomorrow when I get back to testing I can finalize those digits as well.


There is a fixed text/line pin and two grounds on the EL Panel that need to be wired, combined with the AC high and AC low outputs from the Power Supply Module and those connections to the Relay Module. 

I will set all segments on and check for shorts to any of the control lines, basically accomplishing the remaining checks to assure me it is safe to hook up the high voltage AC to the relays and make the entire display project work.

It shouldn't be long before I have the display lit and digits/signs dancing on it as commanded by the Arduino program. 

Using Arduino to switch the DSKY Relay Module and some QA testing


Each of my circuits is designed to be off by default, as when the Arduino is not active. They are all activated by driving the input line to +5V, which either delivers +14V for set and unset lines or grounds the row select line. I ran the wiring to the Arduino, then anchored that unit onto the board. 

Just before I connected each lead to the Arduino from the board, I tested the voltage present on that lead to be sure that I didn't have +14V leaking since that would blow the Arduino input-output circuit. This took only a few minutes and I was ready to bring it up to do some power testing.


The code in the Arduino lets me issue commands to set various values in the PROG, VERB and NOUN displays as well as setting the sign to blank, plus or minus. It has a simple command interface where I can turn the sign to + by typing sign +, then turn it off by typing simply sign. In the same way, I can put the two digits of VERB to 36 by typing verb 36 then turn them off by issuing verb with no parameter. 

To verify that I was turning on the proper segments of the display I had to first gang together the high voltage AC leads to the relay module. Each of the five columns for a digit has its own AC power line. 
There are also two low side AC lines that need to be bridged in the external wiring. 

As well, the VERB and NOUN lines require a jumper between two pins to provide AC. These two pins are connected to another relay that is flashed on and off at about 2/3 Hz or forced steadily on, based on whether those digits should flash or not. 

The bridged high AC lines are connected to the various segment outputs based on the state of the latching relays and the five bit code entered into the row that controls a digit. I can do a continuity test from high AC to the individual segments, seeing that they are turned on or off appropriately for each entered code. 

The code I ran that was expected to put 8 in every digit position, lighting all segments, instead put a 6 in as far as segment lighting. It was consistent across all six digits which means it is something that I am doing wrong. The code for 8 is 11101 while the code for 6 is 11100 thus one possibility is a fault driving the low bit. The code looks fine and the hardware worked perfectly when set manually, so I moved on to another possibility.

If I am entering the code reversed, e.g. putting in 10111 then since that is not a valid bit code value the results could well be the same as a 6, by accident.  To check this I selected two values which are symmetric opposites and set all the digits to one of them. If the segments that are active match the opposite, I would know what my problem is and how to fix it quickly. 

I chose 2 and 7 whose patterns are 11001 and 10011, thus entering the code 2 would either display 2 or 7 depending on whether I have reversed the order. The results were not what I expected. I had all the proper segments for displaying the digit 2 except that once again the H segment was inactive.

This tells me that I have something wired wrong where high AC is not getting to the relay contacts that lead to all the H segments. Off to study the schematics of the Relay Module. 

While I had all the segments active (except H) I did a sanity test, checking to be sure that the AC high and AC low lines didn't have continuity. That worked out okay, something essential for when I hook everything up and use the Power Supply Module. 

Thursday, June 18, 2020

EL Panel wired to Relay module, Relay Module wired to transistor driver breadboard, breadboard hooked to Arduino


There are 44 segments of the EL Panel Module that are switched on and off by the relay contacts in the Relay Module in order to display the two digit PROG, two digit VERB, two digit NOUN, and the sign for the R1 row. The segments for an individual digit are in a contiguous block of pins on the EL panel, but scattered across the Relay Module connector. 

I thus had first wired the segments on the EL panel and grouped them in sets of seven (one digit's segments), six of those groupings plus a pair of wires for the horizontal and vertical sign segments. I then took each group, stripped the end of the wires and used a continuity checker (beeped them) to make sure I knew exactly which segment belonged to the wire. 

After doing the wire-wrap connection, all 44 wires were hooked to their corresponding points on the Relay Module. Previously I had wired up a group of pins that provide the 275VAC 800 Hz power that causes the segments to glow. In addition, I had wired the 20 signals that select individual relays and cause them to latch or unlatch, selected in a matrix with some lines fed +14V and others pulled to ground to cause just one relay's coil to activate. 

EL Panel wired to Relay Module


I had designed and built a board that sinks current to ground to select each of the six digits or the two sign segments, as a row. Also on that board were twelve two-transistor circuits that would source +14V to either the latch or the unlatch side of a relay column. These needed to be connected to an Arduino to switch on those transistor circuits, and the output connected to the appropriate pin on the Relay Module.

The wire used to wrap the pins on the connectors of the EL Panel and Relay Module have a square tail so that as the wire is wrapped it bends and grips tightly. I did not, however, have such tails on the breadboard nor on the Arduino, so other connection methods had to be arranged.

The Arduino was easy - I used male to male cables with pins that fit both the breadboard holes and the Arduino connectors. One cable had eight lines for the row select, two others had six lines each for the column set and the column unset function. An Arduino Mega 2560 was easily able to accommodate the number of I/O pins. 

I first tried sticking in a connector post of the same type that fits into an Arduino, then doing a wirewrap on the pin. I found that the round shape of the connector post did not form that good tight grip that is possible with square tails. 

I decided on a hybrid approach. I got some hookup wire that would fit decently in the breadboard holes but also slid into the wirewrap tool. I then wrapped the wires coming from the Relay Module onto bits of bared hookup wire, soldering the connection in place and snipping off that small section. It was inserted into the breadboard for each of the twenty blue wires coming from the Relay Module.

Transistor driver circuits, Arduino cable on right and blue wires inserted on outputs


There is so much wiring to this project and a dangerous mix of high voltage AC, 14V DC and TTL level voltages. With 137 pin locations on the Relay Module and 160 locations on the EL Panel, the opportunity for error was high. Further, any inadvertent shorts might connect the AC onto the control lines and blow out my driver circuits. 

I therefore plan a set of checks and tests before full scale operation to mitigate those risks above. The first test was done by providing +14V to the transistor driver board, manually touching a +5V lead to the inputs that will eventually be driven by the Arduino, and listening for the barely audible click of the relays latching and unlatching. This let me check for proper voltages, ensure that the Arduino won't be damaged by +14V backflow, and see that all the relays click away as expected.

I selected each of the six digit rows, then while that was active I touched the latch and unlatch columns one by one to ensure I was getting switching of the relay it controlled. I then selected each of the sign segments and while it was active did a latch and unlatch of the relay. All was good.


Each digit is chosen by setting a specific pattern of latched and unlatched relays in that row. There are five columns, since the DSKY uses a five bit code to pick the value 0-9 or blank. This means that each time I want to change one of the digits, I have to select a row and then latch/unlatch five relays to choose the digit value. Doing this manually would be tedious, thus the desire to write a program for the Arduino.

I will issue simple text commands at the terminal monitor, such as PROG 63 or SIGN +, which will select each of the two digit rows and set the code in the five columns. Pretty easy for me and not much of a program for the Arduino. I am mostly done with the code, thus once it is debugged fully I can hook up the Arduino and cause digit values to be set into the Relay Module, changing them rapidly.