Sunday, October 27, 2024

Kaypro II Keyboards

I recently went to the swap meet at the System Source Museum in Hunt Valley Maryland and scored a Kaypro II off the "free pile". The system appeared to have suffered some water damage and even though the power LED came on, I got no other life out of it. I will show more about this system in a future post. To help with the troubleshooting I pulled out a Kaypro II I had acquired a long time ago and probably hadn't powered up in decades. I quickly realized that they keyboards on both units did not work. Outwardly both the keyboards looked the same, but internally they were very different. I will take a look at them in this post. 

Keytronics Keyboard

The keyboard on the system I had is by Keytronics. When I tested it, I found that none of the keys worked so I suspected it might be a problem with they keyboard logic. I took the keyboard apart and found that it is a capacitive touch keyboard with foam and foil key switches.

Here is a look at the PCB with the mechanical parts removed. 


Since this keyboard has capacitive key switches a direct electrical connection is not needed between the contacts to trigger the keypress. Normally the key is activated by a foam and foil pad on the bottom of the key, but I found you can also trigger the keys my just touching them with your fingers. 

Here is the bottom of the keyboards mechanics. The foam-and-foil pads had badly deteriorated which is why the keyboard no longer worked. Beyond this issue everything else on the keyboard worked fine. Replacement pads are available from texelec.com but I decided to hold off getting these until I determined if I was going to need the second keyboard or not. 


SMK Keyboard


The system I got from the swap meet had an SMK keyboard. This one was badly water damaged, this picture is from after I refurbished it which I will cover in another post. Unlike the Keytronics keyboard this one uses individual mechanical key switches. 

Here are the mechanical parts of the key switch. The bottom and top of the case which just snap together, the plunger which attached to the keycap and the spring that holds the plunger up. 



Here are the two electrical contacts. 



When the key is not depressed the bump on the side of the plunger hold the two contacts open.


When the key is pressed the bump moves down allowing the contacts to close thus activating the switch. When the key is released the spring returns it to the top position. 



Theory of Operation

Despite the differences in the key switches these two keyboards function basically the same way. Here is a simplified block diagram of the keyboard electronics.
Like most keyboards these use a scanning matrix to read the keys. The keys are organized into a grid of rows and columns with a key switch at each intersection. Note that this doesn't necessarily correspond to the physical layout of the keyboard. To read the matrix a 4 bit value is placed on the inputs of a 4-16 line decoder chip which enables one of the keyboard columns. The rows can then be read in parallel and if any of them are active then the key or keys that were pressed can be determined. Once a column is read the 4 bit value is incremented to read the next column. This process repeats until all columns are read. 

In these keyboards the whole process in managed by an Intel 8048 series microcontroller. The controller has program in it's internal ROM that does the scanning process, handles key de-bouncing, key repeat and communication with the system. The communication happens over a bi-directional serial connection. The 8048 doesn't have any built in serial hardware so the interface uses two digital I/O pins. An internal timer generates a periodic interrupt which allows the software to achieve the proper serial baud rate without an actual serial clock. When key presses are detected they are sent over the serial interface to the system. 

The keyboard can also receive a limited set of commands from the system over this interface. These commands can generate a short beep or long beep, can turn off the beep when a key is pressed, and finally there is a test commend that causes the keyboard to send a hex AA back to the system.

The micorcontroller also has a few other miscellaneous digital IO connections. First, it directly controls the caps lock LED, and on the Keytronics keyboard there is an option for up to 8 more LEDs which aren't used on the Kaypro. It also has an output that controls the beeper in the keyboard which generates the key click sound. The Kaypro does not have any internal sound capability so some programs used the keyboard beeper to generate rudimentary sounds. 

Since the Keytronics keyboard uses capacitive touch keys, it cannot connect the row and columns lines directly to digital IO pins. To handle these the keyboard uses two special chips made by Exar, the 22-950-3B row driver and 22-908-03 sense amplified. This also leads to a difference in how the Shift, Control and Caps lock keys are read. The SMK Keyboard reads them directly through digital IO pins on the controller instead of reading them through the matrix. Due to the special chips needed for the capacitive keys, the Keytronics reads these key as part of the scanning matrix. 



Wednesday, August 28, 2024

Odyssey 2 Voice Development System


A couple months ago I ran across a post on the AtariAge forums by Dale Crum about an unusual Odyssey 2 that he found. The system looked like a stock O2 with the Voice module screwed to it. Inside the base unit was a extra circuit board that connected to the Voice with a ribbon cable. After studying the pictures of the unit we came to the conclusion that this was a system used to develop sound samples for the O2 Voice games.

The Odyssey 2 Voice uses an General Instruments SP0256 Voice Processor chip. Normally this chip uses specially manufactured serial ROMs for the voice data. These chips were very efficient for the production units but they would have made it hard to develop the sound samples. General Instruments provided a solution to this in the form of the Speech Field Development Board. This board contained a special chip that allowed the SP0256 to use standard EPROMs instead of serial ROMs which provided an easy way to develop new voice samples. 

The system basically worked ok, but there was no sound from the Voice module when playing voice enabled games. Dale decided to send the system to me so I could try to repair it and also dump the EPROMs from the development board in case they had samples on them that had never been released. 

The first step was to dump the EPROMs, since they were standard 2732 EPROMs this was a simple task. We were also fortunate that the EPROMs had their checksums values written on the labels so I could quickly confirm that the data on the chips was valid. We were hoping to find something interesting on them but in the end we found that the data on the chips was an exact match for what is in the production version of the Voice module. 

With the EPROMs dumped I turned my attention to getting the voice module to work. The system had a second AC adapter that was being used to power the development board. I quickly realized that this adapter was dead, I got no voltage out of it. This was stock O2 adapter and since they are sealed I decided not to try to open it to see what went wrong. I went through my stock pile of AC adapters and found another one with the same specs. 

With the new AC adapter hooked up I tried KC's Crazy Chase again to test the voice. A few of the voice samples played but others were missing and in some cases the wrong sample played. Before I could start troubleshooting this problem I lost all the sounds from the Voice again. Checking the replacement AC adapter I found it had also died. Since this one was mine I decided to cut it open and see what went wrong. These are AC-to-AC adapters so there is not much to them, and I found that a thermal fuse in the transformer had blown. 

I dug up another transformer, in this case a standard NES supply which provides the same voltage but had a little higher current rating. I did some careful testing to see if the development board was drawing to much current, but eventually determined that current draw was fine. I decided to resume troubleshooting and did not encounter any more power supply problem. The first replacement AC adapter I used was old so I can only assume that it was not in good condition and the board just put a little to much load on it. 

With the power supply issue resolved I went back to troubleshooting the Voice problem. I started to probe the signals that are used to address the SP0256 and found one line that didn't look right. I inspected the ribbon cable that runs from the development board to the Voice module. Here is a picture of the connector that plugs into the socket where the SP0256 normally is on the Voice.


I was initially concerned about the two bent over pins, but this turns out to be normal. These are the pins for power and ground, and since the development board has it's own power supply there we bend over to isolate the two power supplies. The real problem was the broken pin the the upper left. This was one of the addressing pins which explains why the incorrect samples were played at certain times. The is a pretty unique cable so replacing it would not have been easy so I needed to try to repair it. I gouged out a little of the plastic at the based of the pin and then soldered on a pin I took from a spare connector. It wasn't a great repair but this connector won't often be disconnected so it should work. With that pin repaired everything worked perfectly. 

Dale has put together a great web site with all the information about this system:

https://odysseytalks.com/

I also took this opportunity to trace out the schematics for the development board. They will be available on the Odyssey Talks web site and are also in this thread at AtariAge:

https://forums.atariage.com/topic/360799-odyssey-2-the-voice-oddity/?do=findComment&comment=5520852


Wednesday, July 3, 2024

Odyssey 2 - Joystick Repair

I recently started going through the Odyssey 2 units I have to test them all out. I had a few joysticks that weren't working well so I decided to dig into how to service them. Unlike most joysticks of this era these can be a little tricky to work ok.

To disassemble the joystick first remove the two screws from the bottom which will allow the top cover to be removed. You can see how dirty the ones I worked on were.


If you want to remove the cable it has a connector that just pushes on to a row of contacts on the flex circuit. To remove this hold down on the flex circuit right by the connector and gently pull the connector off. 

The plastic knob on the top of the stick is just pressure fit, at least on the ones I worked on. To get it off I held the joystick shaft with one pair of pliers and pulled the knob off with another set of pliers. 


Disassembling the actual stick assembly is the trickiest part of this repair. It is held together by a locking washer which fits into a groove on the shaft. To get this off, push down on the black part to compress the spring and give some room to access the lock washer. Grab the lock washer with a pair of needle nose pliers and gently bend it down to spread the teeth on the inside, this will give just enough room to pull it off. So far I have not broken one of these but it looks like replacements aren't hard to get. They are generally referred to as "pushnut washers", it would just be a matter of finding the right size. 



I have found one stick that used a c-clip instead of a pushnut. Not sure if this was a manufacturing variation or if someone just used it in an earlier repair. 

With the lock washer removed the joystick assembly comes apart. Under this you can see the flex circuit assembly. The bottom of the joystick assembly pushes on segments of the flex circuit as you move the stick which activates one of four directional "switches" in the flex circuit. 



Looking at the bottom of the stick there seems to be two variations. The one on the left has a disk that locks into the bottom of the stick to hold the metal shaft in place. Most of the sticks I have do not have this part, so it may have eventually been removed to save money. It is not actually needed since the spring pressure hold that shaft in place. 



Getting the disk off can be a little tricky. It rotates to unlock the three tabs, but each tab has a little protrusion on the bottom that locks into a slot to prevent the disk from rotating. To get it off I put a very small flat blade screwdriver under the end of each tab and pried up carefully to release tab. After doing this to each one I use a pair of needle nose pliers placed in two of the three tabs to rotate the disk. 



Here is what the disk looks like when removed from the stick. 


I was recently working on a pair of sticks which had a odd feature. The one on the right is a "normal" stick which has a ridge around the top of the cylinder that hold the metal shaft of the stick in place, you insert the stick from the bottom and the ridge keeps it from coming out the top. The one on the left is missing this ridge so you can actually pull up on the stick. Both sticks were like this so I don't know if this was just wear or if there was a reason this ridge was removed. 



In general these sticks are built pretty well, so if anything it is going to fail it is the flex circuit. I have seen two different failures of these, damage to the traces on the flex circuit creating an open to one or more of the switches, or one or more of the switches being stuck on. 

You can test the switches with an Ohm meter, measuring between the Common and one of the other traces. The traces are pretty fragile so be careful not to scratch them up too much with the meter probe. It may be best to leave the connector connected and measure from contacts on the side of the connector. 


So far when I have found opens in the traces it has been right at the bend where the edge connector enters the rest of the assembly. To repair this I used a conductive pen I found on Amazon...


Just cleanup the traces with some alcohol and then draw over the break with the pen. For the one I was working on it look a few passes with the pen to get it to start working, just give it some time to dry between each pass. 

The other failure I saw was one of the buttons being stuck on. To fix this I carefully heated up the flex circuit with a hair dryer and pealed the two layers apart near the switch that was stuck. Once I had it unstuck I pressed the layers back together. This did fix the problem, although I don't know if it will stay fixed when the stick is used. 

After repairing the flex circuit and cleaning all the parts I reassembled the sticks using the reverse of the disassembly procedure.  

 

Sunday, April 28, 2024

Odyssey 2 X/Y Position Registers

Update: After first publishing this article I read the notes in the O2 MAME driver and it indicated that there was some other unexpected behavior with these registers. I did some testing and have updated the article with the new findings.    

    I recently set up a development system for the Odyssey 2 so I could dig into some of the capabilities of the system. I am looking to improve the documentation I wrote back in the 90's to support the home-brew community and maybe improve the O2EM emulator. The first thing I took a look at is the X/Y position registers which seem to work differently then any of the current documentation describes.

    The purpose of these registers is to get the current X and Y position of the electron beam that is drawing the graphics on the CRT. Knowing the position could be useful to do mid-screen graphics changes. The registers are read from the VDC chip at location $A5 for the X position and $A4 for the Y position. 

   There seems to be two ways to read these registers. First you can bring bit one of the VDC Control Register ($A0) to 1 (&H02) and then back to 0. This will latch in the current beam position and they can then be read and will not change until this bit is strobed again. Second you can bring bit one of the VDC Control Register (&HA0) to 1 at which point the registers will follow the beam position, but you cannot read the Y position until you have first read the X position. The game Blockout read the Y position like this, it reads the X registers, throws away the value and then reads the Y. 

. Bit one in the VDC Status Register (&HA1) is supposed to indicate that the beam has been latched, but it seems to just follow the state of the latch bit in the control register, so wouldn't seem to have a purpose, but I will explain later what I think it is for. 

    I did same tests on the X register and could not get reliable results from reading it. Even if it was reliable the CPU just wouldn't be fast enough to read the registers for any meaningful purpose. 

    The Y register starts at 0 at the end of VBlank and increments to $F7 before the start of the next VBlank. It remains $F7 for the duration of VBlank before resetting back to 0. 

    According to the Intel datasheet on the 8244 VDC chip, there is a pin called STB that can also be used to latch the beam position. This pin is not used on the Odyssey 2, but I assume the intention of this pin was to support a light gun. This would also explain the need for bit one in the status register which indicates that the position has been latched, I assume this bit would also be set by the external pin. 

    A test program can be found here that demonstrates the relationship between the scanline counter and the Y Position Register.

https://github.com/danlb2000/Odyssey-2/tree/main/PositionRegiserTest

    The program resets the counter to a specified value and then records the value of Y Position register when the timer IRQ happens. It also changes the screen color at that time to demonstrate how mid screen color changes work. During the vertical blank it displays the value of the Y Position on screen. Adjusting the value of  TIMER_START will show different values on the screen. The program can also be re-configured to show the value of Y Position during VBlank. 

As of this writing neither MAME nor O2EM give the same results for this test as the real hardware.




Sunday, April 14, 2024

Magnavox Odyssey 2

 

Image is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported license.



The Odyssey 2, known as the Philips Videopac G7000 in Europe, was a cartridge based videogame console developed by Magnavox and released in 1978. My first exposure to this machine was back in the late 70's when one of my friends had one. In 1996 I wrote the first emulator of the system, O2EM. At the time there was no publicly available information on the system so I ended up having to reverse engineer it. Eventually the project was taken over by Andre de la Rocha who continued to update it. 

Processor: Intel 8048

Speed: .36 MHz clock speed

RAM: 128 Bytes + 64 Bytes in processor

ROM: BIOS: 1K (Internal to processor)
            Cartridges: 2K address space, 2 bank select inputs for up to 8K bank switched carts

Sound: Intel 8244 custom Audio/Video IC
             24-bit shift register, clockable at 2 frequencies; noise generator

Graphics: Intel 8244 custom Audio/Video IC

Graphics RAM: 256 bytes of video control registers
Colors: 16
Sprites: 4, 8x8 pixel, 1 color
Background Graphics: 9x8 grid of lines or blocks. Each segment individually controllable
          28 Character objects from predefined internal character set

I/O: 2, 8 direction digital joysticks with one fire button

        48 key QWERT membrane keyboard with reset button        

Ports: Cartridge ports doubles as a system expansion port

           Early versions of the system had joystick ports, but later systems hardwired the joysticks

The system was a big leap forward compared to the dedicated "pong" console Magnavox had been producing up to that point, but was not as flexible as the Atari 2600. The graphics system is quite limited with the four 8x8 sprites being the only objects where the programmer had complete control of the shape which made if difficult to port existing games to the system. The 8048, which was designed to be an embedded controller, is also a little tricky to use for game programming. It has a very lean instruction set, for example it has no subtraction instructions, and no comparison instruction. 

I have recently setup a development system that will allow me to run software directly on the hardware so I can study the operation of the system in more detail. This will allow me to update the technical documentation I wrote back in the 90s and possibly make some improvements to O2EM.

If you are interested in more information about the system I recommend this Facebook group which has a good collection of available O2 documentation and example code.

Odyssey 2 and Videopac Homebrew Games





Thursday, February 22, 2024

Centurion FCC Shift and Carry

This is one of a series of articles about the Centurion FFC board's custom CPU. In this post I will look at the shift and carry logic. I will start with the shift logic. 

In the 2901 chip slice there are two places where data can be shifted, as it enters the RAM and as it enters the Q registers. On either end of the shift registers is a pin that can be used to shift a bit into the register or view the bit being shift out. Since the register can be shifted in either direction, these pins can behave as either inputs our outputs depending on the direction of the shift. 


These shift pins are cascaded between the two 2901s to create 8-bit shift registers with either ended labeled ALU.Q0/ALU.Q7 and ALU.RAM0/ALU.RAM1.

Looking at the FCC logic the 74LS241 is used to handle these bits depending on the direction of the shift. The enables on the chip are connected to ALU control bit 7 which will be low for down shifts and high for up shifts. Depending on the direction of the shift ALU.RAM0 or ALU.RAM7 is connected to Shift.RAMout and the other to Shift.RAMin. Q is connected the same way to Shift.QOut and Shift.Qin. 



Now lets look at where these signals are used. We will start with the ShiftIns. There are two 74LS151 multiplexers that handle the ShiftIns. The one for Q is controlled by microcode bits H10-H12 and the one for RAM by microcode bits H14-H16. 


The input options are the same for both registers:

0 = Always 0
1 = Always 1
2 = The shift out from the registers, thus forming a rotate operation
3 = The shift out of the other shift registers, this allowing Q to be shifted into RAM and RAM shifted in to Q.
4,5= The inverted and non-inverted Flag Bit. See my previous post for more details on these. 
6 = The Carry flag from the ALU
7 = The Sign flag from the ALU

The shift outs go a couple different places, most of which we have covered already. First, they go to Shift In Mux which I covered above, and they go to the Flag Mux which I showed in a previous post. The final place they go is to the Carry Mux which selects in the input to the ALU Carry In signal. The mux is controlled by the MP.H84-MP.H86 microcode bits. 



The input options for the Carry Mux are:

0 = Always 0
1 = Always 1
2 = RAM Shift Out from the ALU
3 = Q Shift Out from the ALU
6 = ALU Carry Out
7 = ALU Sign



Sunday, November 5, 2023

Centurion CPU Branch/Skip Logic

 This is one of a series of articles about the Centurion FFC board's custom CPU.  In my post on the microcode sequencer I explained that branches in the code can be controlled by the Test input to the sequencer. In this post I will show where that test signal comes from. 

We will start with the Branch/Skip selector. The select inputs come from three bits (M.H35-MP.H37) of the microcode so eight different conditions can be selected. The condition then passes through an XOR gate where it is combined with  microcode bit MP.H34 which can invert any of the the conditions. Finally this passes to the Test input of the microcode sequencer. 


Now let's look at the conditions. Input zero is tied directly to +5 so allows for a branch always condition. I will cover the FlagReg input later in this post. The next four inputs are condition bits from the ALU, Zero, Carry, Overflow and Sign. The final two inputs come directly from the drive control hardware which makes it easy for the CPU to react to specific conditions in the driver controller. 

The Branch/Skip selector selects a condition that is happening on the current microcode instruction. The Mux input on the other hand allows for the checking of a condition that happened during the previous instruction. 


The Flag Mux works similar to the Branch/Skip Selector. The flag is selected by microcode bits MP.H31 - MP.H33 and then goes through an XOR gate where microcode bit MP.H3g controls whether it is inverted or not. From here is passes for 74LS74 flip flop which latches the flag value using the system clock. The outputs of the flip flop go to the Branch/Skip Selector but they also go to the Shift and Carry muxes where they can become inputs to the ALU. I will cover this in a future post. 

Now lets look at the conditions. Condition zero, just like the branch select, is tied high so represents a branch always condition. Condition one is interesting, it is just the output of the Flag Mux, so this allows the condition to be carried forward one more cycle. Conditions two and three come from the output of the ALU shift registers. Finally four through sever are condition flags from the ALU.