Sunday, June 30, 2013

Solving the last of the obvious faults

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.

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 Boot ROM
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:




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

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!
So now I can get at the chips on the boards while the machine is running and poke and prod and generally inspect the behavior of parts of the machine much more easily.

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
So instead, today I'll talk about my latest acquisition, an NRI-832 computer.  This computer was offered as a kit as part of a correspondence course from the National Radio Institute in 1971-1972, making it one of the earliest (if not the earliest) commercially available computer kits.  (It was a contemporary to the Kenbak-1, for example.)  The NRI-832 used approximately 75 integrated circuits to build an 8-bit processor (with a 5-bit address space) featuring a simple but adequate instruction set.  16 sets of 8 toggle switches on the front panel provided read-only storage for 16 instructions, and an additional 16 bytes of actual RAM could be added to the system (without this expansion, the system had only 1 byte of read/write storage).  The intent of the kit was to teach the basics of computer design and programming and while it was a very limited system it was still a computer one could have at home, and in 1971 that was nothing to sneeze at.  The kit retailed for $503.

The guts -- 70 ICs or so that implement a very simple CPU
I snagged this off of eBay for what I consider an amazing price given the computer's historical significance and rarity; every now and then you just get lucky.  This particular specimen is going to need a bit of work as it appears that assembly was never completed by its original owner.  Most notably missing is the PCB that holds the 128 toggle switches for program entry, but it's also pretty clear that a lot of the wiring was never completed.  But on the plus side, all of the logic is present and schematics and manuals are available so it's not an impossible task.  Building the toggle switch panel is going to be time consuming, involving a lot of soldering, but it's not difficult.
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.