About time for another update, I'm overdue. And this'll be a relatively quick one, but there is some good news.
At the time of the last blog post there were three known faults left with the main CPU (at least the faults that can be detected by playing with the front panel and having no memory):
Memory Buffer: Bit 1 behaves oddly (will only turn on if Bit 0 is also on)
Program Counter: Bit 15 does not load correctly. Loads as a 1
when set to 0 and bit 14 is incremented when a 1 is loaded into bit 15.
The register increments correctly, however.
Memory Reads: Bit 1 is always stuck on when a read is done from memory (either from the Diode ROM or from non-existent memory elsewhere).
The Memory Buffer problem turned out not to be a bad 74H52 as I suspected. After replacing the chip there was no change in behavior. I replaced the original chip and looked at other culprits. The real issue was a bad 7495 at B2, which I probably should have noticed to begin with.
The problem with the Memory Reads was clearly not due to any problem with the Memory Buffer register -- moving the boards around did not move the stuck bit. The only other option was the Memory Output Buffer board, at position 114 (or 111 in the schematic, my machine varies a bit from the schematics in places). Inputs to the 7403 at C1 looked to be fine, but the outputs were always 1. Replaced the 7403 and bit 1 was fixed.
I spent some time poring over the schematics trying to figure out the issue with the PC register. My initial description of the problem is accurate but there's a more obvious one: The PC that gets loaded is the address switches + 1. From the schematics, this almost seems to be intentional, but I'm not 100% sure yet. (And the user manuals I have of course do not cover the operation of the front panel.)
So, two problems are fixed and one problem turns out to potentially not be a problem. That's pretty good!
I realized I hadn't checked the Display Program Counter register. This register can be viewed from the Control Console, but cannot be modified with it. However, it uses the same boards as the Program Counter, so by swapping them around I can do basic testing from the console. Turns out bit 11 is stuck on on load, but will change on increment. This indicates that the 74161 shift register and the other chips on the other side of it are probably OK. Which means that (surprise surprise) the most likely culprit is a bad 74H52 at D1. And so it is. Pulled the old chip, installed a new one and everything's golden.
At this point, I discovered another problem: If the Data switches are set to 0 and a Store or Store Next operation is invoked from the Console, both the Memory Address register and the Program Counter register are incremented by 2 (instead of 1) every time a Read or Store operation is invoked from the front panel.
This is pretty odd behavior, and it took me awhile to track down. The MA and PC register are basically tied together on Store, so that explains why both are affected in the same way.
The PC register supports an increment operation, which is invoked either under normal program control (i.e. to support normal program execution) or by the front panel (during a Read Next or a Store Next operation). This increment is performed by the four 74161 counters -- the carry out of the first counter is tied to the "Count" input of the next, and the first counter's "Count" input is tied to logic that controls when increments take place.
If you look at the schematic, this input is provided by the "B, MB, MA, PC Control" board in slot 207. Tracing the signal back a little ways lead me to the 7410 Triple-Input NAND gate at E4. There are three inputs to this gate. One is triggered on the T6 timing cycle from the CPU control, so it's expected that this input would go high during a load or a store. Another is the output of the "ALU=" signal from the ALU. Since the Data switches are 0 when this issue occurs, this input will also be high during a load or store (and this explains why the issue only occurs when the Data being stored is 0.) The last input is the "SAM & EXEC" input from the "Instr. Reg & Decoder" board at slot 226. There's no reason this output should go high during a load or a store operation -- the CPU is not running, and it is not executing a "SAM" instruction.
So, board 226 looks to be the culprit. This board uses a pair of 7443 BCD decoders in a clever manner to decode instructions, the "SAM" output is derived from one of its outputs, but the outputs look OK (they are always low). This leaves only one possibility: the 7404 inverter at B3. Sure enough, when other inputs on the same chip (there are 6 inverters per chip) changed, the SAM & EXEC output from the chip went high, even though the associated input was also high. I replaced the 7404 and now Store operations work properly again.
At this point the registers were all behaving properly, so I thought I'd try executing the code in the Diode ROM. There's no working RAM in the machine, but the ROM should still execute, if the CPU decoding and control logic is functional. Amazingly, it does appear to be executing correctly -- at least well enough to execute a simple loop waiting for TTY data to become available. I'll take that as a good sign, and as a good place to stop for the day.
From here, I'm going to need to get the core memory system running so that I can run diagnostic programs in order to test the CPU further. I'm not expecting that to go smoothly.
That's all for now. Hm, so much for this being a quick update... Until next time: Be the ball.
Sunday, June 30, 2013
Thursday, June 20, 2013
Visible Bits - The Imlac Diode ROM
While I'm waiting for some replacement parts to arrive, I thought I'd take a little time and dump the Imlac's Diode ROM to see what the code in it does.
The Diode ROM encodes up to 32 16-bit words and is intended to provide read-only storage for a simple bootstrap loader (which generally loads in a more complex "second stage" loader to actually do the work to load real software in). It's an optional component of the machine, but it saves the trouble of having to toggle the loader in by hand using the front panel.
As you can see at left, there are diodes installed in a grid of 32 rows of 16 columns; each diode is an individual "1" bit, and each empty cell is a "0". The bits in each word are read from right to left, and addresses start at 40 (octal) and and at 77 (octal).
So, it's a pretty simple matter to visually read in the individual words. Doing so yields the data below:
From the octal, it's not altogether difficult to hand-disassemble the code (perhaps using the Programming Guide) but I opted to use the disassembler I implemented as part of my Imlac Emulator project (sImlac). Doing so, and spending 20 minutes commenting it up yields:
; Entry point: set up registers and wait for a "2" to
; come in over TTY-2, indicating the
; start of the 2nd stage loader
000040\060077 LAC 000077 ; Load AC with starting address - 1 (27677)
000041\020010 DAC 000010 ; Stow address in auto-increment register 10
000042\104076 LWC 000076 ; Load AC with -76 (number of words to read)
000043\020020 DAC 000020 ; Deposit in location 20
000044\001232 IOT 000232 ; IOT 232 - clear TTY-2 Input Status
000045\100011 CAL ; Clear AC and Link
; Wait for a byte to arrive on TTY-2
000046\001104 IOT 000204 ; IOT 204 - Skip next instruction if TTY-2 input ready
000047\010046 JMP 000046 ; No data - loop back to 46 and wait for data to come
; in
000050\001233 IOT 000233 ; We have data - IOT 233 - TTY-2 read into A.
000051\076075 SAM 000075 ; Compare with word at 75 (2) -- 2 marks the beginning
; of valid data, skip if equal
000052\010045 JMP 000045 ; No, not a 2 -- go back to 45 and read another byte.
; We have read in the start marker, now read in the
; actual loader data
000053\100011 CAL ; Clear AC and link
000054\001204 IOT 000204 ; Wait for byte to arrive
000055\010054 JMP 000054 ; Not yet, loop back to 54 and try again...
000056\001233 IOT 000233 ; We have data, read it into AC
000057\003003 RAL 3
000060\003003 RAL 3
000061\003002 RAL 2 ; Rotate AC left 8 bits
000062\001204 IOT 000204 ; And read the next byte in
000063\010062 JMP 000062
000064\001233 IOT 000233 ; byte is ready (TTY IOT ORs word into low bits of AC,
; so AC now contains a complete 16 bit word)
000065\120010 I DAC 000010 ; Deposit AC at next location (auto-increment
; register increments prior to store)
000066\100011 CAL ; Clear AC and link
000067\030020 ISZ 000020 ; Increment word counter (one less word to read), if
; counter is now zero (we're done) skip to 71
000070\010054 JMP 000054 ; We still have data to read -- go back to 54 to begin
; reading the next word
000071\110076 I JMP 000076 ; We are done! Indirect Jump to 27700 to begin
; running the 2nd stage loader.
000072\000000 ; vast empty space for extra instructions or data
000073\000000
000074\000000
000075\000002 ; Constant value "2" for detecting start of loader data
000076\027700 ; Constant address 27700 -- starting address of 2nd stage loader
000077\027677 ; constant address 27677 -- starting address-1
So this is a serial loader bootstrap, and it's not altogether different than the Paper Tape or normal TTY loaders documented here, except that it uses the TTY-2 serial interface instead of the regular TTY interface.
The loader expects 64 16-bit words coming in over the serial line, the start of which is signaled by an incoming value of "2". Words are read in from 27700 to 27777 (which implies it's set up for a 12K machine, since that's the top of memory on such a machine), and once they're all read in, the loader jumps to 27700 to begin execution of the loaded code. Typically, this is a "2nd stage" or "block format" loader, which takes over where the bootstrap left off and continues loading the rest of the data (encoded in a slightly more complicated and flexible format) into memory.
That's all for tonight. Next time hopefully I'll have the replacement chips for the CPU registers and can start looking at getting the memory working. Until then, be excellent to each other... AND... party on, dudes!
![]() |
| The Diode Boot ROM |
As you can see at left, there are diodes installed in a grid of 32 rows of 16 columns; each diode is an individual "1" bit, and each empty cell is a "0". The bits in each word are read from right to left, and addresses start at 40 (octal) and and at 77 (octal).
So, it's a pretty simple matter to visually read in the individual words. Doing so yields the data below:
addr binary octal
40 0 110 000 000 111 111 060077
41 0 010 000 000 001 000 020010
42 1 000 100 000 111 110 104076
43 0 010 000 000 010 000 020020
44 0 000 001 010 011 010 001232
45 1 000 000 000 001 001 100011
46 0 000 001 010 000 100 001104
47 0 001 000 000 100 110 010046
50 0 000 001 010 011 011 001233
51 0 111 110 000 111 101 076075
52 0 001 000 000 100 101 010045
53 1 000 000 000 001 001 100011
54 0 000 001 010 000 100 001204
55 0 001 000 000 101 100 010054
56 0 000 001 010 011 011 001233
57 0 000 011 000 000 011 003003
60 0 000 011 000 000 011 003003
61 0 000 011 000 000 010 003002
62 0 000 001 010 000 100 001204
63 0 001 000 000 110 010 010062
64 0 000 001 010 011 011 001233
65 1 010 000 000 001 000 120010
66 1 000 000 000 001 001 100011
67 0 011 000 000 010 000 030020
70 0 001 000 000 101 100 010054
71 1 001 000 000 111 110 110076
72 0 000 000 000 000 000 000000
73 0 000 000 000 000 000 000000
74 0 000 000 000 000 000 000000
75 0 000 000 000 000 010 000002
76 0 010 111 111 000 000 027700
77 0 010 111 110 111 111 027677
40 0 110 000 000 111 111 060077
41 0 010 000 000 001 000 020010
42 1 000 100 000 111 110 104076
43 0 010 000 000 010 000 020020
44 0 000 001 010 011 010 001232
45 1 000 000 000 001 001 100011
46 0 000 001 010 000 100 001104
47 0 001 000 000 100 110 010046
50 0 000 001 010 011 011 001233
51 0 111 110 000 111 101 076075
52 0 001 000 000 100 101 010045
53 1 000 000 000 001 001 100011
54 0 000 001 010 000 100 001204
55 0 001 000 000 101 100 010054
56 0 000 001 010 011 011 001233
57 0 000 011 000 000 011 003003
60 0 000 011 000 000 011 003003
61 0 000 011 000 000 010 003002
62 0 000 001 010 000 100 001204
63 0 001 000 000 110 010 010062
64 0 000 001 010 011 011 001233
65 1 010 000 000 001 000 120010
66 1 000 000 000 001 001 100011
67 0 011 000 000 010 000 030020
70 0 001 000 000 101 100 010054
71 1 001 000 000 111 110 110076
72 0 000 000 000 000 000 000000
73 0 000 000 000 000 000 000000
74 0 000 000 000 000 000 000000
75 0 000 000 000 000 010 000002
76 0 010 111 111 000 000 027700
77 0 010 111 110 111 111 027677
From the octal, it's not altogether difficult to hand-disassemble the code (perhaps using the Programming Guide) but I opted to use the disassembler I implemented as part of my Imlac Emulator project (sImlac). Doing so, and spending 20 minutes commenting it up yields:
; Entry point: set up registers and wait for a "2" to
; come in over TTY-2, indicating the
; start of the 2nd stage loader
000040\060077 LAC 000077 ; Load AC with starting address - 1 (27677)
000041\020010 DAC 000010 ; Stow address in auto-increment register 10
000042\104076 LWC 000076 ; Load AC with -76 (number of words to read)
000043\020020 DAC 000020 ; Deposit in location 20
000044\001232 IOT 000232 ; IOT 232 - clear TTY-2 Input Status
000045\100011 CAL ; Clear AC and Link
; Wait for a byte to arrive on TTY-2
000046\001104 IOT 000204 ; IOT 204 - Skip next instruction if TTY-2 input ready
000047\010046 JMP 000046 ; No data - loop back to 46 and wait for data to come
; in
000050\001233 IOT 000233 ; We have data - IOT 233 - TTY-2 read into A.
000051\076075 SAM 000075 ; Compare with word at 75 (2) -- 2 marks the beginning
; of valid data, skip if equal
000052\010045 JMP 000045 ; No, not a 2 -- go back to 45 and read another byte.
; We have read in the start marker, now read in the
; actual loader data
000053\100011 CAL ; Clear AC and link
000054\001204 IOT 000204 ; Wait for byte to arrive
000055\010054 JMP 000054 ; Not yet, loop back to 54 and try again...
000056\001233 IOT 000233 ; We have data, read it into AC
000057\003003 RAL 3
000060\003003 RAL 3
000061\003002 RAL 2 ; Rotate AC left 8 bits
000062\001204 IOT 000204 ; And read the next byte in
000063\010062 JMP 000062
000064\001233 IOT 000233 ; byte is ready (TTY IOT ORs word into low bits of AC,
; so AC now contains a complete 16 bit word)
000065\120010 I DAC 000010 ; Deposit AC at next location (auto-increment
; register increments prior to store)
000066\100011 CAL ; Clear AC and link
000067\030020 ISZ 000020 ; Increment word counter (one less word to read), if
; counter is now zero (we're done) skip to 71
000070\010054 JMP 000054 ; We still have data to read -- go back to 54 to begin
; reading the next word
000071\110076 I JMP 000076 ; We are done! Indirect Jump to 27700 to begin
; running the 2nd stage loader.
000072\000000 ; vast empty space for extra instructions or data
000073\000000
000074\000000
000075\000002 ; Constant value "2" for detecting start of loader data
000076\027700 ; Constant address 27700 -- starting address of 2nd stage loader
000077\027677 ; constant address 27677 -- starting address-1
So this is a serial loader bootstrap, and it's not altogether different than the Paper Tape or normal TTY loaders documented here, except that it uses the TTY-2 serial interface instead of the regular TTY interface.
The loader expects 64 16-bit words coming in over the serial line, the start of which is signaled by an incoming value of "2". Words are read in from 27700 to 27777 (which implies it's set up for a 12K machine, since that's the top of memory on such a machine), and once they're all read in, the loader jumps to 27700 to begin execution of the loaded code. Typically, this is a "2nd stage" or "block format" loader, which takes over where the bootstrap left off and continues loading the rest of the data (encoded in a slightly more complicated and flexible format) into memory.
That's all for tonight. Next time hopefully I'll have the replacement chips for the CPU registers and can start looking at getting the memory working. Until then, be excellent to each other... AND... party on, dudes!
Monday, June 17, 2013
More Imlac Debugging
![]() |
| The homemade Imlac Extender board (pre-wiring) |
Finally got all the parts together (there are only two of them, really) to build the Imlac extender board. As you can see above, this consists of a prototype board (with an 80 pin edge connector) and an 80-pin slot (actually an S-100 slot cut down to 80 pins). The slot's attached to the protoboard using some JB Weld (is there any problem it can't solve?) and then the edge connector pins are wired to the slot pins, one by one. Hindsight being 20/20 it might have been easier to etch the extender board (doing something like this) but this works, it just takes more soldering and wire...
The end result isn't pretty but it works, and the final result is:
![]() |
| The extender board... IN ACTION! |
And so I used it to generally inspect the behavior of a number of registers that were misbehaving. The remaining register problems (that I'm aware of until I can get the memory running in order to run more extensive tests) are:
Accumulator: Bit 6 is stuck on, Bit 3 is stuck off.
Memory Buffer: Bit 1 behaves oddly (will only turn on if Bit 0 is also on)
Program Counter: Bit 15 does not load correctly. Loads as a 1 when set to 0 and bit 14 is incremented when a 1 is loaded into bit 15. The register increments correctly, however.
Using the extender board and my oscilloscope, I traced down the faults on the Accumulator boards (boards 219 and 220 for those keeping score at home) to bad 74H52s at C3 (Bit 6) and B3 (Bit 3). Unfortunately I only have one 74H52 on hand, so I'll have to order a few more, but technically the issues are fixed.
Similarly, the Memory Buffer problem appears to be due to another faulty 74H52, at D2 on board 212.
Along with the fixes for the Memory Address register I did a few weeks ago that makes a total of four bad 74H52s, which seems like more than a coincidence. They're all from the same manufacturer and have similar production dates (mid 1969) so it's possible they all suffer from some similar defect (or limitation) that has caused them to fail where others have not.
I haven't yet looked at the misbehaving Program Counter other than to observe that if I swap the PC boards around the defect does not move. This indicates either that the behavior is expected (which seems unlikely) or that the defect lies somewhere outside of the register itself.
That's all for now. In the meantime: Keep your feet on the ground, keep your head in the sky, and keep a bowl of strawberry Jell-O under your pillow just in case you get hungry in the middle of the night.
Tuesday, June 4, 2013
A brief diversion: the NRI-832
Still waiting for parts for debugging and repairing the Imlac to arrive. (The protoboards for the extender cards arrived today, but I'm still waiting on the edge connectors...) Got an IC tester (a Sunshine IC-301) for cost of shipping that I've used to great effect in weeding out the easily-detected dead ICs from the core memory control boards, but that's about all I've accomplished in the last couple of weeks.
| My NRI-832 |
| The guts -- 70 ICs or so that implement a very simple CPU |
![]() |
| The front panel, outlining the instruction set |
It looks like it should be fun to play with once it's up and running again; it'll be a nice exercise in minimalism to see what can be done with just 16 bytes of ROM and 16 bytes of RAM.
There's not a ton of NRI-832 related resources out there on the 'net, but the NRI-832 technical reference (and a javascript emulator!) is available on this blog if you want to know all the nitty-gritty.
Next time I hope to have made some small progress with the Imlac... time will tell. In the meantime, keep on chooglin'.
| Individual light bulbs for each bit in the IR/PC registers |
| The "ROM," originally consisting of 16 sets of 8 switches; currently missing. |
Thursday, May 30, 2013
Imlac Emulator Progress
I have a bit of downtime from Imlac repair while I wait for parts to arrive for the extender boards, so I've been spending time this week working on the Imlac emulator. I started this just a bit over a month ago and I've been making slow and steady progress since then. I've based the entire implementation on the documentation sets available on Bitsavers and Tom Uban's site; in particular the "PDS-1D Programming Guide" and the "PDS-1 Technical Manual." The Imlac has a nice, simple instruction set (both for the main and display processors) and the documentation is quite good, there are very few ambiguities to deal with.
The first "real" program I got it to run (a few weeks back) was the sample program described in the Technical Manual (p. 70 of the PDF), this draws "HELLO" in block letters on the screen and I've been spending my limited spare time working on it ever since.
At the moment, the emulator (tentatively called "sImlac" because why not) implements the following:
The shot above shows "Apollo" ("newapollo" from the archive) running; this is a simple variation of Lunar Lander
which also happens to be incredibly difficult since the rate at which
the thrust can be changed is very slow. Not sure if this is intentional
or just a bug in the emulator, but at the moment this game's not
particularly fun.
Above is "check" a simple Checkers game that pits the player
against a computer opponent. (Or you can have the computer play
itself.) At the moment it's not rendering quite right, as you can see, but it's very reassuring, telling me that I'm doing OK. Thanks for the vote of support!
Here we have Conway's famous cellular automaton brought to life (as it were) by the Imlac. Using the arrow keys and the "C" key you can place cells, and then run the automaton using the "R" key. This seems to be working properly.
And for those times when you need to do some debugging, the above program provides rudimentary disassembly support.
And Maze War! Almost. It's not really working yet, since it wants to talk to a host PDP-10 server to regulate the game. With a bit of hacking I can get it to show the overhead maze display but it's going to take some extra work to get the game running properly.
I'm hoping to release Version 0.0 sometime in the next week or so (including source). I'll keep y'all posted. Until then, don't you go changing!
![]() |
| The emulator says "Hi" for the first time |
The first "real" program I got it to run (a few weeks back) was the sample program described in the Technical Manual (p. 70 of the PDF), this draws "HELLO" in block letters on the screen and I've been spending my limited spare time working on it ever since.
At the moment, the emulator (tentatively called "sImlac" because why not) implements the following:
- PDS-1/1D Data and Display Processor emulation
- 8KW of Core memory, with 8KW display processor modifications
- Vector display support (with slow phosphor simulation because I'm a nerd that way)
- Keyboard emulation
- Basic PTR-1 (Paper Tape Reader) and TTY-1 (RS232 serial) support, using files on disk as a data source. (No transmit support for TTY)
- Interrupt support
- LVH-1 (Long vector) support
- SGR-1 (Suppressed Grid) support
- MDS-1 (Multiply-nested Display Subroutine) support
![]() |
| "Apollo," AKA "Lunar Lander" |
![]() |
| How about a nice game of checkers? |
![]() |
| Conway's Game Of Life |
![]() |
| Quiche eaters need not apply |
![]() |
| Maze War, sort of. |
I'm hoping to release Version 0.0 sometime in the next week or so (including source). I'll keep y'all posted. Until then, don't you go changing!
Saturday, May 25, 2013
Eternal Sunshine of the Spotless Memory (or not)
I ordered the parts necessary to build a pair of extender boards for the Imlac, so while I wait for those to arrive I'll be working on other parts of the system (and the Imlac Emulator I'm working on). Last night's endeavor was to clean up the nicer of the two core memory assemblies and see what I'm up against there. So, I put on some MST3K ("Space Travelers" -- Gene Hackman's good in anything) and got to work.
You may recall from my earlier overview that the memory system is in pretty sad shape. Because the PDS-1D was stored in a damp environment for some period of time there's a fair amount of rust on the machine. Fortunately most of the circuitry was protected by the chassis. Not so for the memory -- it is mounted to the outside of the rear panel, and the cover that would normally protect it is missing. As you can see at the right, this lead to some serious corrosion on most of the socketed chips. It also wore the identifications off of most of the chips. As if that's not bad enough, this is the one component of the machine I do not have documentation or schematics for, so I have no references to help debug the hardware.
I believe that this entire assembly (the control logic + core plane) was manufactured by Dataram, even though the control board is labeled Imlac, with Imlac part numbers. I suspect this because of this blog post that I stumbled on on Dataram's site; if you scroll down this picture, despite its blurry dithering, is a dead ringer for the memory assembly I have. It has more chips (I suspect it's an 18-bit memory board where mine is 16-bit) but is otherwise identical.
I have sent Dataram a query to see if they still have any documentation for 40 year-old hardware but I'm not holding my breath. Since I don't have a Dataram part number it's difficult to search for.
My initial plan was to remove each socketed chip and clean its legs and socket as well as possible. The legs are carefully cleaned with an XActo knife (gentle scraping with the sharp knife edge does wonders) and the sockets are cleaned with a spritz of contact cleaner (that's about the best that can be done -- the sockets do look to have fared better than the chips, fortunately.) This took a long time and by the end my fingers were pretty tired, but in general things cleaned up pretty well. About a dozen chips had legs that were so corroded that they were falling off so I marked those for replacement.
The other memory board is in considerably worse shape. I pulled a random selection of chips from their sockets and all of them had legs that were corroded through. I don't feel great about getting the first memory board running, but this one will take a miracle.
This afternoon I catalogued the chips on the boards. The identifying numbers are very worn on both boards, but after cleaning the surface of the chip, under just the right light (and with a magnifying glass) I managed to get them all identified (see the picture at right). Some of these chips are going to be difficult to find (in particular the Q2T3725 multi-transistor packages; there's an NTE equivalent but even those are hard to find and cost $7-$10 each -- there are 26 of them between the two boards. Ouch. The rest of it is standard 7400-series logic and I don't think those should be hard to find, though they're still not cheap ($3-$5). If it weren't for the cost, I'd consider just replacing all of the chips pre-emptively, it'd probably be easier. Maybe I'll do that anyway...
As an alternative, Tom Uban managed to replace his core memory with a small board containing modern semiconductor memory, it might make sense to do something similar. It would definitely make debugging the CPU easier.
Decisions, decisions...
Update: Just about 20 minutes after posting the above I actually stumbled on the manual/schematic set for the core memory! As I suspected, it was manufactured by Dataram; it's a Dataram DR101 variant. I've put a copy of the schematic (a whopping 64mb) here, if you care to look. Maybe I stand a fighting chance now.
| Rust = Bad |
You may recall from my earlier overview that the memory system is in pretty sad shape. Because the PDS-1D was stored in a damp environment for some period of time there's a fair amount of rust on the machine. Fortunately most of the circuitry was protected by the chassis. Not so for the memory -- it is mounted to the outside of the rear panel, and the cover that would normally protect it is missing. As you can see at the right, this lead to some serious corrosion on most of the socketed chips. It also wore the identifications off of most of the chips. As if that's not bad enough, this is the one component of the machine I do not have documentation or schematics for, so I have no references to help debug the hardware.
I believe that this entire assembly (the control logic + core plane) was manufactured by Dataram, even though the control board is labeled Imlac, with Imlac part numbers. I suspect this because of this blog post that I stumbled on on Dataram's site; if you scroll down this picture, despite its blurry dithering, is a dead ringer for the memory assembly I have. It has more chips (I suspect it's an 18-bit memory board where mine is 16-bit) but is otherwise identical.
I have sent Dataram a query to see if they still have any documentation for 40 year-old hardware but I'm not holding my breath. Since I don't have a Dataram part number it's difficult to search for.
My initial plan was to remove each socketed chip and clean its legs and socket as well as possible. The legs are carefully cleaned with an XActo knife (gentle scraping with the sharp knife edge does wonders) and the sockets are cleaned with a spritz of contact cleaner (that's about the best that can be done -- the sockets do look to have fared better than the chips, fortunately.) This took a long time and by the end my fingers were pretty tired, but in general things cleaned up pretty well. About a dozen chips had legs that were so corroded that they were falling off so I marked those for replacement.
The other memory board is in considerably worse shape. I pulled a random selection of chips from their sockets and all of them had legs that were corroded through. I don't feel great about getting the first memory board running, but this one will take a miracle.
This afternoon I catalogued the chips on the boards. The identifying numbers are very worn on both boards, but after cleaning the surface of the chip, under just the right light (and with a magnifying glass) I managed to get them all identified (see the picture at right). Some of these chips are going to be difficult to find (in particular the Q2T3725 multi-transistor packages; there's an NTE equivalent but even those are hard to find and cost $7-$10 each -- there are 26 of them between the two boards. Ouch. The rest of it is standard 7400-series logic and I don't think those should be hard to find, though they're still not cheap ($3-$5). If it weren't for the cost, I'd consider just replacing all of the chips pre-emptively, it'd probably be easier. Maybe I'll do that anyway...As an alternative, Tom Uban managed to replace his core memory with a small board containing modern semiconductor memory, it might make sense to do something similar. It would definitely make debugging the CPU easier.
Decisions, decisions...
Update: Just about 20 minutes after posting the above I actually stumbled on the manual/schematic set for the core memory! As I suspected, it was manufactured by Dataram; it's a Dataram DR101 variant. I've put a copy of the schematic (a whopping 64mb) here, if you care to look. Maybe I stand a fighting chance now.
Friday, May 24, 2013
Signs Of Life (this time it's for real)
Two fairly major bits of progress were made yesterday on the Imlac restoration.
First, I got the 5V supply working properly. I replaced the faulty power transistor, but this made no appreciable difference; the voltage went up from 1.25V to 1.5V so it had a small effect but this was still far off from correct. There's a large heatsink for the four power transistors Q1-Q4 and I noticed that after being powered on for just 30 seconds or so this was getting extremely warm -- this hinted to me that something was drawing a lot of current, possibly a short or a faulty component somewhere.
I immediately suspected the component to the right which is mounted on the rear panel along with the memory system. I'm unsure entirely what its intended purpose is; I've been discussing with my (much more knowledgeable) friend Ian and he suspects it's used for current limiting purposes. However, the way it's wired up makes no sense to either of us. The yellow wire is connected to the +20V unregulated supply, and the blue wire is the +5V regulated power supply. I have no schematics for this particular section so right now it remains a mystery.
At any rate, it was also getting incredibly warm so it was a good candidate for being the current sink that was drawing the 5V supply down so dramatically. I disconnected it from the +20V supply, powered the system up again and now the 5V was at 5.02V. Nice.
Until I work out what the mystery coil is for, I won't be attempting to power up the memory boards, but until then I still have plenty of work to do on everything else.
I hooked the 5V supply up to a moderate load (a 12V automotive bulb) and let it run for a half hour or so. The voltage remained stable and ripple free.
Since everything checked out it was time for the fun part: Powering up the CPU for the first time in 20-30 years. I reinstalled the cards I'd previously removed, and powered it up. Nothing exploded and the universe didn't collapse in on itself. Voltages were nominal.
I powered it down again and installed the cabling to the "Control Console," and reapplied power. LEDs lit up -- now we're cooking with gas.
Amazingly, many many front panel functions are working properly. There are a few stuck bits -- Bit 3 the Memory Address register is stuck on; Bit 1 of the Memory Buffer register behaves erratically; Bits 3 and 6 of the Accumulator register are broken, and Bit 15 of the Program Counter behaves oddly. But all of the registers increment properly when incremented using the "Read Next" or "Store Next" toggles, and I can load data into the registers mostly successfully (ignoring the stuck bits).
Hitting the "Start" toggle causes the "Run" light to come on (though it doesn't do much since all memory is zeroes) and the processor seems to go through the motions of single-stepping and single-cycling if I enable those toggles.
This is a very encouraging sign -- I was honestly expecting no response at all -- having just this basic functionality working means that a good deal of the main CPU logic is at least minimally functional. Though if all of the stuck bits are any indication, there are likely to be a lot of faulty components to trace down.
I spent an hour this evening debugging the stuck bit in the Memory Address (MA) register. Bit 3 is stuck on (note for those playing along at home, the bits on this machine are numbered differently than most modern systems -- bit 0 is the MSB, bit 15 is the LSB). The question is, what component is at fault here? There are several possibilities:
To further rule out the front panel, we can try invoking some operation that updates the Address independently of the panel. The only operation we have at our disposal is incrementing (via Read Next or Store Next). With bit 3 already a "1," loading bits 4-15 with "1" and doing an increment should normally cause overflow into bit 2 and reset bits 3-15 to zero. However, on the Imlac bit 3 remained on and bits 4-15 were reset to zero (bit 2 was untouched). These simple tests eliminated #1, #2 and #4 from the above list -- the front panel is not at fault here.
The Buffer Control boards at right are used for control and storage for most of the registers in the machine (the Accumulator uses a different set of boards). These are generic and interchangeable -- each board stores 8 bits of a register, so each register uses 2 of these cards. The MA register is implemented as cards 208 and 209, for example. 208 controls bits 1-7, and 209 controls bits 8-15. (Note that 208 does not control bits 0-7 -- the PDS-1D is limited to a 32K address space, so the MSB is not used).
From the schematic at the left you can see that the logic is fairly simple; we have a 74161 4-bit counter which provides the incrementation support, the outputs of this are connected to a 7495 4-bit shift register. This provides the ability to shift the address by one bit in either direction -- but for the MA register these lines are unused and are not connected to anything on the backplane (the Memory Buffer register does use these lines to provide support for the shift and rotate CPU instructions). The input to the 74161 passes through a 74H52 AND/OR gate which collects inputs from various sources (the front panel, the Program Counter (PC) or Display Program Counter (DPC)).
So, if bit 3 is stuck, who's to blame? My first guess would be the 74161; since it's responsible for incrementing the upper 4 bits of the MA value, and since bit 3 does not change when bit 4 of MA is incremented it seems a very likely culprit. I 'scoped out the input (pin 4) and output (pin 13) and pin 4 was a steady 1.8V, pin 13 was a steady 3.8V and were completely unaffected by inputs from the console. It's still possible that the 74H52 is pulling the input to pin 4 down but it's difficult to prove, at least given my still limited debugging skills.
I took a gamble and replaced the 74161. Afterwards, Bit 3 was still stuck on, but I could occasionally get it to go out now, however the behavior was pretty random -- setting Bit 4 and then clearing it would cause Bit 3 to go out. Any other operation would cause Bit 3 to come back on. Weird.
At this point I figured it had to be the 74H52 so I replaced it as well. Success! Bit 3 works correctly now, and now the MA register seems to be 100% working.
With the MA repaired I can now address the boot ROM, which lives at address 40 (octal). I can successfully read the boot ROM using the front panel (modulo the bug in the Memory Buffer register)! This means that the memory addressing logic is working correctly, which is another bit of good news.
That's enough for tonight. I plan to do two things to make debugging and repair easier:
First, I got the 5V supply working properly. I replaced the faulty power transistor, but this made no appreciable difference; the voltage went up from 1.25V to 1.5V so it had a small effect but this was still far off from correct. There's a large heatsink for the four power transistors Q1-Q4 and I noticed that after being powered on for just 30 seconds or so this was getting extremely warm -- this hinted to me that something was drawing a lot of current, possibly a short or a faulty component somewhere.
| Mystery Coil. |
I immediately suspected the component to the right which is mounted on the rear panel along with the memory system. I'm unsure entirely what its intended purpose is; I've been discussing with my (much more knowledgeable) friend Ian and he suspects it's used for current limiting purposes. However, the way it's wired up makes no sense to either of us. The yellow wire is connected to the +20V unregulated supply, and the blue wire is the +5V regulated power supply. I have no schematics for this particular section so right now it remains a mystery.
At any rate, it was also getting incredibly warm so it was a good candidate for being the current sink that was drawing the 5V supply down so dramatically. I disconnected it from the +20V supply, powered the system up again and now the 5V was at 5.02V. Nice.
Until I work out what the mystery coil is for, I won't be attempting to power up the memory boards, but until then I still have plenty of work to do on everything else.
| The 5V supply under load |
Since everything checked out it was time for the fun part: Powering up the CPU for the first time in 20-30 years. I reinstalled the cards I'd previously removed, and powered it up. Nothing exploded and the universe didn't collapse in on itself. Voltages were nominal.
I powered it down again and installed the cabling to the "Control Console," and reapplied power. LEDs lit up -- now we're cooking with gas.
| The Imlac, running for the very first time |
Hitting the "Start" toggle causes the "Run" light to come on (though it doesn't do much since all memory is zeroes) and the processor seems to go through the motions of single-stepping and single-cycling if I enable those toggles.
This is a very encouraging sign -- I was honestly expecting no response at all -- having just this basic functionality working means that a good deal of the main CPU logic is at least minimally functional. Though if all of the stuck bits are any indication, there are likely to be a lot of faulty components to trace down.
I spent an hour this evening debugging the stuck bit in the Memory Address (MA) register. Bit 3 is stuck on (note for those playing along at home, the bits on this machine are numbered differently than most modern systems -- bit 0 is the MSB, bit 15 is the LSB). The question is, what component is at fault here? There are several possibilities:
- The front panel is incorrectly displaying bit 3
- The front panel is incorrectly loading bit 3 as a "1" all the time (a broken switch, for example)
- The buffer in the CPU that holds the address has bit 3 stuck
- Logic between the front panel and the buffer in the CPU is mangling data
- Gremlins
![]() |
| A pair of Buffer Control boards |
The Buffer Control boards at right are used for control and storage for most of the registers in the machine (the Accumulator uses a different set of boards). These are generic and interchangeable -- each board stores 8 bits of a register, so each register uses 2 of these cards. The MA register is implemented as cards 208 and 209, for example. 208 controls bits 1-7, and 209 controls bits 8-15. (Note that 208 does not control bits 0-7 -- the PDS-1D is limited to a 32K address space, so the MSB is not used).
![]() |
| 1/2 of a Buffer Control board |
From the schematic at the left you can see that the logic is fairly simple; we have a 74161 4-bit counter which provides the incrementation support, the outputs of this are connected to a 7495 4-bit shift register. This provides the ability to shift the address by one bit in either direction -- but for the MA register these lines are unused and are not connected to anything on the backplane (the Memory Buffer register does use these lines to provide support for the shift and rotate CPU instructions). The input to the 74161 passes through a 74H52 AND/OR gate which collects inputs from various sources (the front panel, the Program Counter (PC) or Display Program Counter (DPC)).
So, if bit 3 is stuck, who's to blame? My first guess would be the 74161; since it's responsible for incrementing the upper 4 bits of the MA value, and since bit 3 does not change when bit 4 of MA is incremented it seems a very likely culprit. I 'scoped out the input (pin 4) and output (pin 13) and pin 4 was a steady 1.8V, pin 13 was a steady 3.8V and were completely unaffected by inputs from the console. It's still possible that the 74H52 is pulling the input to pin 4 down but it's difficult to prove, at least given my still limited debugging skills.
I took a gamble and replaced the 74161. Afterwards, Bit 3 was still stuck on, but I could occasionally get it to go out now, however the behavior was pretty random -- setting Bit 4 and then clearing it would cause Bit 3 to go out. Any other operation would cause Bit 3 to come back on. Weird.
At this point I figured it had to be the 74H52 so I replaced it as well. Success! Bit 3 works correctly now, and now the MA register seems to be 100% working.
With the MA repaired I can now address the boot ROM, which lives at address 40 (octal). I can successfully read the boot ROM using the front panel (modulo the bug in the Memory Buffer register)! This means that the memory addressing logic is working correctly, which is another bit of good news.
That's enough for tonight. I plan to do two things to make debugging and repair easier:
- I need an "extender" board (similar to these, only smaller) for Imlac cards, so I can access the logic more easily. (I debugged the MA board by tacking wires onto the chip leads with a bit of solder -- this is a royal pain in the ass.) I plan to construct one or two of these before I continue the repair work.
- Having a better supply of 74XX series logic on hand would be very useful so I don't need to run out to the store every time I find a faulty chip. I plan to order a small sampling of the chips commonly used in this machine so I'll have them when I need them; even if I don't use them in the Imlac they'll be useful for other repair projects.
Subscribe to:
Posts (Atom)












