I’ve been spending more time lately diving into reverse engineering of the Fadal CNC control. I upgraded my CPU card to a 1400-2 so that my control would have look-ahead and continuous contouring. This feature was lacking in the 1400-1 CPU and caused the machine to pause briefly between linking moves.
After acquiring the 1400-2 CPU I tried using my 1460-0 memory expansion with it, and while I got it working, according to the Fadal board compatibility matrix, this is not a supported configuration. I went on eBay and looked for the 1460-1 memory expansion and was underwhelmed how simplified and cost reduced it was in comparison to the 1460-0. This reignited an idea I had during my last reverse engineering sprint: why not design and build my own memory expansion? Well, after a bit of reverse engineering and a couple board revisions and component revisions, I got a working result. I now have a single board 384KB solution just like the 1460-2 board for the later controls.
Back to the 1400-2 CPU card
I started examining the 1400-2 CPU and right away some things popped out at me, it has 2 SPLD (Simple Programmable Logic Devices) chips and 2 256-bit PROM chips. The latter was quite puzzling and I speculated at first they may be using them as a lookup matrix for some logic shortcut. It is even deeper than that!
Quick question: When you have 4 EPROMs on your CPU board, each are 64KB in size, your reset vector is at the top of the FXXXX segment, and your video memory is mapped less than 16KB below the top of the segment, how do you map your reset vector when your EPROM is 64KB?
The answer is you don’t! One of the PROMs contains the reset vector jump that the CPU executes upon reset. Since the PROM is 32 8-bit words, it easily maps into the address space ending at FFFFF. I discovered this gem by deduction, see the 1400-1 EPROMs are fairly straightforward, you find the reset vector 16 bytes below the top of one of the EPROM images, but on the 1400-2 there is no such jump. I was scratching my head trying to figure out if I was missing something or they were obfuscating how it worked
The answer came from my HP 1651B logic analyzer. I connected it to the CPU and monitored the address/data, rd/wr, address enable, and reset signals, so I could capture the exact code the CPU is executing on reset. The PROM contains the following machine code at the reset vector:
fff0: ea fa ff 00 30 jmp 0x3000:0xfffa
What that translates to is “long jump to address 0x3FFFA”, and at that address you will find the following further jump:
fffa: e9 e0 2b jmp 0x2bdd
And that address is the beginning of the control initialization code that sets up the machine and begins primary execution.
Another interesting tidbit I noticed when looking at the 1400-2 CPU is the use of some CD4006 Quad Bilateral Switch ICs. The 1460-1 memory expansion has these as well, and it wasn’t immediately clear why until I started examining high resolution photographs of the 1400-2 CPU card.
Fadal used PAL (Programmable Array Logic) chips to simplify the memory addressing on both the CPU and memory expansion cards. The CPU card now has 6 SRAM chips of 32KB each, so there are 6 chip enables and there is segment address decoding — chips are decoded in pairs at address 0x0000 and 0x8000. Something has to coordinate enabling the RAM chips when the requested address is present on the CPU’s address bus. They used a PAL for this purpose. But the interesting part is that they routed the enable lines through the CD4066 switches and tied the switch logic to the brownout circuit. They must have not had the ability to tri-state the output of the PAL until the brownout circuit enabled the memory, so they routed the signals through the CD4066 chips with those acting to either route the enable to VCC or to the PAL chip when the brownout detector came up. I suspect they used the CD4066 because the memory VCC is separate from main board VCC, so the CD4066 would just treat that as an isolated analog signal, referenced to common ground. This way they reduce the parasitic draw by not powering another chip from the battery backup.
In my own memory board I used a simpler approach: I used an MCP100 supervisory circuit with push-pull output to provide the brownout detection. This is the master gate signal that enables all of the chips on the board, so unless this puts out a high signal, all of the chips are held in a tri-state or disabled state and memory address lines are shunted to ground. Rather than decoding the addresses with a PAL, I just used an 8-to-3 line priority encoder to decode the memory addresses and provide enable/gating logic. This works out to provide 8 separate segments and allows 1 memory board to work with the 1400-1 and 1400-2 CPU card, covering all possible memory expansion addresses.