I am writing an emulator for this board in order to support Localtalk for the MAME. The information on Internet reveals enough to get started and I also got hold of a romset. The whole CPU power is located on what they consider an I/O board but it really does all the rendering of Postscript and emulation of the old Diablo 630 daisy wheel protocol.
I found some pictures here that I stitched together:
As can be seen there was a few areas missing at the bottom of the PCB but it is really helpful when trying to trace board. Unfortunately the board is one of the first revs using a TPI6523 while the romset has been proven to use the newer VIA6522 chip, the same as used in the Commodore 64 btw :)
Obviously the pcb has more than two layers as the connectors to the left, unfortunately not pictures as the front panel covered that part of the pcb, has no visible traces and there are in-penetrable areas of copper on both sides in that area
torsdag 24 november 2016
fredag 18 november 2016
The Prodigy #5 - add a timer interrupt
After "properly" hooking up a VIA device the next thing we want is to see how the ROM is programming it. As we now have hooked the VIA up properly there will be no warnings on the MAME debugger console (Ctl-L remember?) But this can also be achieved by using watch points in the MAME debugger, like
wp 0x2000,f,w
and then just hitting F5 a couple of times when the watch point triggers, or as in my case, temporary instrument the VIA driver with some proper printouts. Then it is just to decode the bytes written to see what it is up to:
This reveals a lot how the PCB are designed but for now we are just interested in the interrupts as the code seems to be waiting in a tight loop for something to end up in the RAM area, most probably delivered by an interrupt. The last line gives us a clue what interrupt that might be, the Timer 2 interrupt is enabled, we just need to hook it up to the CPU and see where it takes us.
By pressing F7 in the MAME debugger it will execute the ROM until an interrupt happens, and indeed it stops immediately
0x79F8 is indeed the right vector. Now if we set a breakpoint after the tight loop we identified prior enabling the interrupts, let's see what happens.
Hmm, it doesn't trigger. Lets fake input via the RAM location at 0x30 through the memory window (Ctl-M)
Click at the low nibble of the memory location first because the high seems reset all bits set faster than the editor can zero them, and voila!
It obviously hits the bp but more important is that the interrupt routine seems fiddling with the 0x30 as well. Next step is to examine the interrupt routine and discover the port usage, mañana! Next->
wp 0x2000,f,w
and then just hitting F5 a couple of times when the watch point triggers, or as in my case, temporary instrument the VIA driver with some proper printouts. Then it is just to decode the bytes written to see what it is up to:
This reveals a lot how the PCB are designed but for now we are just interested in the interrupts as the code seems to be waiting in a tight loop for something to end up in the RAM area, most probably delivered by an interrupt. The last line gives us a clue what interrupt that might be, the Timer 2 interrupt is enabled, we just need to hook it up to the CPU and see where it takes us.
By pressing F7 in the MAME debugger it will execute the ROM until an interrupt happens, and indeed it stops immediately
0x79F8 is indeed the right vector. Now if we set a breakpoint after the tight loop we identified prior enabling the interrupts, let's see what happens.
Hmm, it doesn't trigger. Lets fake input via the RAM location at 0x30 through the memory window (Ctl-M)
Click at the low nibble of the memory location first because the high seems reset all bits set faster than the editor can zero them, and voila!
It obviously hits the bp but more important is that the interrupt routine seems fiddling with the 0x30 as well. Next step is to examine the interrupt routine and discover the port usage, mañana! Next->
The Prodigy #4 - add some RAM and a VIA device
The latest findings in the effort to preserve and emulate the Prodigy reveals that we need to move ROM to address 0x6000 and add some RAM. The easiest way to allow something on both 0x6000 for execution and 0xe000 in order to provide a reset vector from 0xFFFC is simply to ignore address lane A15 such that the ROM is selected in both places. No circuits I have seen on the PCB so far tells me that we have a more advanced decoding so lets ignore A15!
In MAME this is done using the AM_MIRROR macro with an argument that tells MAME what lanes to ignore for this particular device, in our case the argument is 0x8000 as we want to ignore A15. Adding some RAM at 0x0000 is simple, the M58725P is a 2KB so the range is between 0x0000 and 0x07ff:
So lets fire up the MAME debugger again and see where we end up:
Hiya, the PC after reset point at the address 0x60B7, just like we wanted! :) All good so far. Lets what we miss in our address map by opening the console (Ctl-L) and run the code (F5).
Interesting, there are just a few accesses to the VIA at startup and then the CPU lies in a tight loop waiting for address 0x30 to change while stepping up address 0x7A. This suggests that the VIA will change address 0x30 using interrupts, unless the VIA is very strangely mapped to these addresses directly! Lets hook it up and see what happens.
Don't worry I have submitted this skeleton driver to Github so you don't need to stitch it together yourself and figure where they end up in the driver. These steps are the minimum when adding a new device. In addition we need to configure drivers for the interrupt and what will happen when the ports are accessed, but that is for later, c ya! Next-->
In MAME this is done using the AM_MIRROR macro with an argument that tells MAME what lanes to ignore for this particular device, in our case the argument is 0x8000 as we want to ignore A15. Adding some RAM at 0x0000 is simple, the M58725P is a 2KB so the range is between 0x0000 and 0x07ff:
So lets fire up the MAME debugger again and see where we end up:
Hiya, the PC after reset point at the address 0x60B7, just like we wanted! :) All good so far. Lets what we miss in our address map by opening the console (Ctl-L) and run the code (F5).
Interesting, there are just a few accesses to the VIA at startup and then the CPU lies in a tight loop waiting for address 0x30 to change while stepping up address 0x7A. This suggests that the VIA will change address 0x30 using interrupts, unless the VIA is very strangely mapped to these addresses directly! Lets hook it up and see what happens.
Add the definitions of the VIA driver |
Initiate the instantiated VIA device called m_via |
Tell MAME that this is a required device, not a lot option or otherwise optional in any way |
Map the device to the address space we have identified |
Add the device to the machine, lets use the CPU 2MHz crystal for now |
Don't worry I have submitted this skeleton driver to Github so you don't need to stitch it together yourself and figure where they end up in the driver. These steps are the minimum when adding a new device. In addition we need to configure drivers for the interrupt and what will happen when the ports are accessed, but that is for later, c ya! Next-->
The Prodigy #3 - make a ROM adapter
Well, the cheap ass adapter to get the R2912 ROM read involved a manual step to reassemble the ROM in which case I may have done it wrong and hunting ghost bugs afterwards. In any case when I saw the image to the left below I decided to go for the correct adapter and read out the R2912 as a 2764.
This worked out beautifully and we can now establish that the Rockwell R2912 is pin compatible with a 2364 mask programmable ROM. I wonder about the R2907 still but that's not our problem at the moment. :)
In order to fit the new ROM file into the MAME driver we need the following adjustments to the code:
We start at 0xe000 as rom now is 8KB or 0x2000 bytes in hex so the reset vector is at 0xFFFC. We also need to enlarge the size of "roms" region to 0x2000 and update the size of the rom to 0x2000. The offset where we load the rom within the "roms" section is still 0x0000 though.
Firing up MAME again we see that the reset vector now seems to be 0x60B7 which is within the identified actual ROM area. Since we mapped the "roms" at the top we end up in nowhere:
By setting the PC to 0xE0B7 we can observe and step though the actual code as long as it is position independent:
Now we end up in real code and it does stuff that will tell us more about the system. We can see that the code store things at 0xAB and 0x2003. The latter look very much like a device address which usually is decoded at a nice even address boundary such as 0x2000. This means the RAM is mapped at 0x0000.
So I will map some RAM at 0x0000 and the VIA at 0x2000 next, stay tuned Next -->
This worked out beautifully and we can now establish that the Rockwell R2912 is pin compatible with a 2364 mask programmable ROM. I wonder about the R2907 still but that's not our problem at the moment. :)
In order to fit the new ROM file into the MAME driver we need the following adjustments to the code:
We start at 0xe000 as rom now is 8KB or 0x2000 bytes in hex so the reset vector is at 0xFFFC. We also need to enlarge the size of "roms" region to 0x2000 and update the size of the rom to 0x2000. The offset where we load the rom within the "roms" section is still 0x0000 though.
Firing up MAME again we see that the reset vector now seems to be 0x60B7 which is within the identified actual ROM area. Since we mapped the "roms" at the top we end up in nowhere:
By setting the PC to 0xE0B7 we can observe and step though the actual code as long as it is position independent:
Now we end up in real code and it does stuff that will tell us more about the system. We can see that the code store things at 0xAB and 0x2003. The latter look very much like a device address which usually is decoded at a nice even address boundary such as 0x2000. This means the RAM is mapped at 0x0000.
So I will map some RAM at 0x0000 and the VIA at 0x2000 next, stay tuned Next -->
torsdag 17 november 2016
The Prodigy #2 - identify the ROM type
Once we have some ROM code to work with it is time to take a look at it in action. I do that by writing a minimal skeleton driver for the MAME emulator:
The driver is just assuming that the CPU is a 6502 and that the 2KB ROM is mapped at he highest possible adresses as the reset vector must be in the ROM area. No RAM or other devices are assumed at this point as they can be easily added later when we know more.
This allows me to open up the ROM:s in the MAME debugger and start looking around. First I look at the reset vector to see where the entry point is:
Disappointingly the reset vector at adress 0xFFFC and 0xFFFD is very wrong! :(
It points at 0x0111 which is a quite unlikely remapping of the ROM. Either ROM is trashed, I didn't read it correctly or both. Even if it is mapped somewhere else the reset vector must be mapped to these addresses at power up reset. We can check this by review the disassembly view
The first observation scrolling through the code is that is seems ok, no strange trashed areas or so.
Now we look for absolute jumps which to some degree of certainty will reveal some addresses of ROM code. It does, but now the second important finding is that the jumps are more than 2KB apart, eg JSR $6580 on address $FB7A and JMP $749D on address $FB7F.
This tells us two things, the ROM executes in the $6000 range upwards probably towards the $7FFF mark which should be an 8KB ROM! I errornously assumed that 8KB didn't fit in a 24 pin DIP package but I vaguely remembered a device called 2364 and indeed a search away I found a data sheet and an instructable how to make some 2364-27xx adapters.
So I think I'll go for the 'cheap-ass' adapter and wish the Prodigy ROM is not clocked, hiya! Next-->
The driver is just assuming that the CPU is a 6502 and that the 2KB ROM is mapped at he highest possible adresses as the reset vector must be in the ROM area. No RAM or other devices are assumed at this point as they can be easily added later when we know more.
This allows me to open up the ROM:s in the MAME debugger and start looking around. First I look at the reset vector to see where the entry point is:
Disappointingly the reset vector at adress 0xFFFC and 0xFFFD is very wrong! :(
It points at 0x0111 which is a quite unlikely remapping of the ROM. Either ROM is trashed, I didn't read it correctly or both. Even if it is mapped somewhere else the reset vector must be mapped to these addresses at power up reset. We can check this by review the disassembly view
The first observation scrolling through the code is that is seems ok, no strange trashed areas or so.
Now we look for absolute jumps which to some degree of certainty will reveal some addresses of ROM code. It does, but now the second important finding is that the jumps are more than 2KB apart, eg JSR $6580 on address $FB7A and JMP $749D on address $FB7F.
This tells us two things, the ROM executes in the $6000 range upwards probably towards the $7FFF mark which should be an 8KB ROM! I errornously assumed that 8KB didn't fit in a 24 pin DIP package but I vaguely remembered a device called 2364 and indeed a search away I found a data sheet and an instructable how to make some 2364-27xx adapters.
So I think I'll go for the 'cheap-ass' adapter and wish the Prodigy ROM is not clocked, hiya! Next-->
The preservation of the Prodigy Chess computer
I really like chess computers but usually they are too integrated to easily preserve so they kind of piled up in the garage: A Boris Diplomat, already preserved by Sean Riddle, a Mephisto Mini and a Mephisto Tutor among others. However this time I bid for an ACI Destiny Prodigy and got it!
The first thing to do in order to preserve an old MCU design is to check if anyone has done it before or if there are pictures of the inside already. I found plenty of information of this classic but no emulation in MAME or elsewhere easily found. Great, lets do it!
Among all the information on the net I found pictures of the PCB revealing it has a very discrete design, that is it uses a 6502 with external RAM and ROM chips that are easily accessible. So carefully I opened the chess computer revealing the PCB. Here I stumbled on the first issues, the RAM and ROM were not of brands I already knew:
The RAM is a Mitsubishi M58725P which I didn't recognize but a quick Google revealed that it is pin compatible with a standard 6116 2KB static RAM. So far so good. The ROM however, a Rockwell R2912, has no information easily available on Internet. The chess sites mentions that the ROM is 8KB but that would require more pins than the 24 shown in the pictures. I also saw that the pictures showed a R2907 so the information can refer to 8Kbit aka 1KB x 8 bits. EDIT: But didn't!
Interestingly enough the PCB from the net had other RAM and ROM brand, so my PCB was clearly a newer revision than the pictured one found on the Internet. Since I had no data sheet available the next step is to follow the traces and see if I can figure out what they are. This is done by a simple beeper:
I was looking carefully for circuits that could generate a negative voltage from batteries but none were found if it was even possible at the time to a cost suitable for a consumer grade product. I didn't think so and put the ROM into the ROM reader which happily read the ROM as a 2716!
Now starts the work of figuring out the inner secrets of the Prodigy hidden in the PCB and revealed by the ROM code. I will collect all info I find on my Prodigy page, stay tuned! Next-->
Prenumerera på:
Inlägg (Atom)