Homebrew mini metal PDP-8 (1976) Intersil 6100 code

Pleased to meet you, then :-).

I confess to still being puzzled about the correct ordering.

I have been studying the page at 5400 in your 7384 ordering. That page appears to me to be an interrupt service routine. It has two paths, a short one that doesn’t modify LINK, and another more complex path that needs to (and does) save and restore LINK. The longer path also seems to fetch and output character graphics, or some such thing. Hard to be sure without a description of the device involved, but it computes a pointer into auto-index register 16 and then outputs stuff pointed to in a loop (as if it were drawing characters).

Inside that part of the interrupt handler, there is some code starting at address 5460. This takes location 147, masks it, adds it to a table address from 5565, saves the result in 154, then branches to that place. I believe this is attempting to make use of the table of JMP instructions which can be found just following 5466. Essentially a “computed goto” depending on the state recorded in location 147.

The problem is, the base address of this table, as recorded in location 5565, is 7466, not 5466. Which would imply that this code only works correctly when loaded at 7400 instead of 5400. Either to code must get relocated, or we have the ordering not quite right.

Vince

1 Like

Also, moving 5400 to 7400 changes 7776 and 7777 to
0400 / Possible starting address
JMP I .-1 / Restart
which seems plausible.

1 Like

Thanks! Very interesting and strange.

The bit order and one of the 2 ROM combinations must be correct as I found text. Also the ROM stickers imply these pairs.
Relocation of 1 or more pages is possible and likely due to the empty page and as the RAM (768 words, 6 pages) is smaller than the ROM. But then there must be code or hardware for that. I don’t know the memory mapping. Bus and some registers could have 16 bits.

I’m not an expert, but starting from regular address 400 doesn’t make much sense to me. (Writing 1k words, after that TAD 0 and a NOP. Also much code inside page 0 which should rather be data, especially 147 and 154).
When moving everything up by 2000, 6000 with the text would be another memory field or moved as well. But what page is then at 400 and earlier? Or at the original 5400?

I tried swapping pages 5400-5577 to 7500-7777. Starting from 7400 there’s soon a HLT, a 6300 IOT and a NOP.

The device doesn’t have graphics. Just an LCD display. The table of 7 jump targets is interesting. They all load from 153 which is 7356. That is BCD encoded 777 and is either for outputting 3x_ on diplay location 4 but more likely here for 7 buttons (or 8 when not branching). I have 7 control mode keys and 8 instruction keys. Numpad 0-7 is also possible. Or 7 segments for the LCD.
Maybe a similar jump list at 3661 (ROM 7384, 4 targets for instructions OR+brackets ?)

At around 2513 seems to be values for the LCD. 4314 = 2xblank for 2 digits. There’s 3x777 and 4x 14 single blanks? And 4x7001. 6314 confirmed 3x blank. Also of interest 6 or 7 06xx values starting at 2505. Baud settings maybe at 4552.
/ and XON for printout at 6542.

I concur that at this point, the likely-hood that bit ordering is wrong is vanishingly small.

I found two more uses of the “computed goto” idiom. One is at 0420 in your 7384 dump, and suggests that the code currently ad 0xxx should be at 2xxx. The other is at 3651(as you mentioned) and suggests the code currently at 2xxx should be at 0xxx. If 4xxx should be 6xxx, then presumably 6xxx should be at 4xxx. That would imply a ROM ordering of 84736251.

I’d love to know more about the I/O environment, and the LCD in particular. Do you know which IOT control it and how? Even knowing that 4314 somehow encodes a pair of blanks is news, and helps explain what I suspect is a text unpacking routine. I still have no idea what you mean when you refer to baud settings or “/ and XON”.

Vince

Don’t forget about radix-50 text encoding, if all else fails.

8473… would result in having the empty page at page 0. I had excluded that then as I thought the start would be at 0.
Starting from 400 first seems plausible. But it overwrites everything with 3527 starting at 11. Maybe this is the RAM check? After that there are infinite loops. At 20 3527 acts then as instruction what is probably wrong. (But RAM <>ROM). Trace run below.

The LCD is the most interesting and complicated part. I’ve described it in 3 posts:

Help with c code (bit reversal) - #41 by mainframetom

Help reading EPROM (Intersil IM6654A) and analyze firmware - #64 by mainframetom

I don’t know the IOT. In the manual I have a table but I doubt that it’s stored as such. 2 characters forming one word, addition of 2 BCD values. Mainly for Ex and Fx. F0=0320. E0=360. 2 fixed values (bit patterns) for location 4 3x blank 6314 and 3x_ =7356. With that logic 4314 should be 2xblank. And 14 1x. 356 1x_

The LCD positions building 4 units/addresses AP1-AP4 0051-54 and can only be loaded. The allowed operation is stored at 762. There’s a command to delete all locations that is unit 0050. All this is only confirmed for the LCD of the PLC but it’s the same style. Loading itself is another instruction eg
…if…
then load AP4 040054 (4=load)
with decimal 8 070010 (7=with decimal, 10=octal)

I don’t know if there’s an LCD driver IC. I can’t remove that PCB without destroying it. The display can’t display text except F and E.
Text (mnemonics) stored at 6000 can only be printed out or exported. The text don’t have blanks. 00 as separator.

The baud settings are operands when exporting or importing. Eg import F 0 (r) (b) ADR, r=0 without reflection, 1 with reflection. b= 0 TTY 110 baud, 1=TTY 300 baud, 2=TTY 600 baud, 3=TTY 1200 baud, 4=Audio 110 baud… 7 Audio 1200 baud. Possible pattern found described here

PDP-8 mystery data, 8 values, LCD bit pattern?

/ and XON: A printout starting with /L 00000 - 00007 S: 0000270003. “/” is ASCII 2F what is 0057 octal. That is stored at 6542 followed by 21 what is control character XON (DC1). XOFF 23 is at 6570, CR+LF 15/12 could be at 572. The mnemonics printed after that aren’t stored as ASCII but as a unique Sixbit. You found a table here

Festo mnemonics text found in ROM code (new PDP-8 encoding)

[0400] IRQ,DLY,IE=0,1,0 L/AC:0/0000 MQ:0000 IR:6007 CAF        ;KK8-E: Clear all flags
[0401] IRQ,DLY,IE=0,1,0 L/AC:0/0000 MQ:0000 IR:1354 TAD @@54   ;Add operand to AC, Current page @@54
[0402] IRQ,DLY,IE=0,1,0 L/AC:0/6100 MQ:0000 IR:6415 SRS1       ;DP8-EAEB: Read Status 1
[0403] IRQ,DLY,IE=0,1,0 L/AC:0/6100 MQ:0000 IR:1273 TAD @@73   ;Add operand to AC, Current page @@73
[0404] IRQ,DLY,IE=0,1,0 L/AC:1/0402 MQ:0000 IR:6415 SRS1       ;DP8-EAEB: Read Status 1
[0405] IRQ,DLY,IE=0,1,0 L/AC:1/0402 MQ:0000 IR:1300 TAD @@00   ;Add operand to AC, Current page @@00
[0406] IRQ,DLY,IE=0,1,0 L/AC:1/1002 MQ:0000 IR:6414 SRS2       ;DP8-EAEB: Read Status 2
[0407] IRQ,DLY,IE=0,1,0 L/AC:1/1002 MQ:0000 IR:1272 TAD @@72   ;Add operand to AC, Current page @@72
[0410] IRQ,DLY,IE=0,1,0 L/AC:1/3527 MQ:0000 IR:7421 MQL        ;Load MQ from AC then clear AC
[0411] IRQ,DLY,IE=0,1,0 L/AC:1/0000 MQ:3527 IR:1270 TAD @@70   ;Add operand to AC, Current page @@70
[0412] IRQ,DLY,IE=0,1,0 L/AC:1/7411 MQ:3527 IR:3000 DCA 0000   ;Deposit AC to memory then clear AC, ZP 0000 
[0413] IRQ,DLY,IE=0,1,0 L/AC:1/0000 MQ:3527 IR:1313 TAD @@13   ;Add operand to AC, Current page @@13
[0414] IRQ,DLY,IE=0,1,0 L/AC:1/0010 MQ:3527 IR:3010 DCA 0010   ;Deposit AC to memory then clear AC, ZP 0010
[0415] IRQ,DLY,IE=0,1,0 L/AC:1/0000 MQ:3527 IR:7501 MQA        ;OR MQ with AC
[0416] IRQ,DLY,IE=0,1,0 L/AC:1/3527 MQ:3527 IR:3410 DCA I 0010 ;Deposit AC to memory then clear AC, Indexed ZP 0010 [Auto pre-inc]
[0417] IRQ,DLY,IE=0,1,0 L/AC:1/0000 MQ:3527 IR:2000 ISZ 0000   ;Increment operand and skip if zero, ZP 0000 
[0420] IRQ,DLY,IE=0,1,0 L/AC:1/0000 MQ:3527 IR:5215 JMP @@15   ;Jump Current page @@15
[0415] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:3527 IR:7501 MQA        ;OR MQ with AC

[0426] IRQ,DLY,IE=0,0,0 L/AC:1/3527 MQ:3527 IR:7041 CIA        ;2s Complement AC
[0427] IRQ,DLY,IE=0,0,0 L/AC:1/4251 MQ:3527 IR:1410 TAD I 0010 ;Add operand to AC, Indexed ZP 0010 [Auto pre-inc]
[0430] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:3527 IR:7640 SZA CLA    ;Skip on AC = 0, Clear AC
[0432] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:3527 IR:2000 ISZ 0000   ;Increment operand and skip if zero, ZP 0000 

[0431] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:3527 IR:5335 JMP @@35   ;Jump Current page @@35
[0535] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:3527 IR:1271 TAD @@71   ;Add operand to AC, Current page @@71
[0536] IRQ,DLY,IE=0,0,0 L/AC:1/0371 MQ:3527 IR:6410 SSRG       ;DP8-EAEB: Skip if Ring Flag
[0537] IRQ,DLY,IE=0,0,0 L/AC:1/0371 MQ:3527 IR:1010 TAD 0010   ;Add operand to AC, ZP 0010
[0540] IRQ,DLY,IE=0,0,0 L/AC:1/0407 MQ:3527 IR:6411 SSCA       ;DP8-EAEB: Skip if CarrierAGC Flag
[0541] IRQ,DLY,IE=0,0,0 L/AC:1/0407 MQ:3527 IR:5341 JMP @@41   ;Jump Current page @@41
[0541] IRQ,DLY,IE=0,0,0 L/AC:1/0407 MQ:3527 IR:5341 JMP @@41   ;Jump Current page @@41

[0542] IRQ,DLY,IE=0,0,0 L/AC:1/0407 MQ:3527 IR:7001 IAC;Increment AC
[0543] IRQ,DLY,IE=0,0,0 L/AC:1/0410 MQ:3527 IR:7001 IAC;Increment AC
[0544] IRQ,DLY,IE=0,0,0 L/AC:1/0411 MQ:3527 IR:7001 IAC;Increment AC
[0545] IRQ,DLY,IE=0,0,0 L/AC:1/0412 MQ:3527 IR:7001 IAC;Increment AC
[0546] IRQ,DLY,IE=0,0,0 L/AC:1/0413 MQ:3527 IR:3142 DCA 0142   ;Deposit AC to memory then clear AC, ZP 0142
[0547] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:3527 IR:1036 TAD 0036   ;Add operand to AC, ZP 0036
[0550] IRQ,DLY,IE=0,0,0 L/AC:1/3527 MQ:3527 IR:3141 DCA 0141   ;Deposit AC to memory then clear AC, ZP 0141
[0551] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:3527 IR:3151 DCA 0151   ;Deposit AC to memory then clear AC, ZP 0151
[0552] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:3527 IR:3076 DCA 0076   ;Deposit AC to memory then clear AC, ZP 0076
[0553] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:3527 IR:4017 JMS 0017   ;Jump to subroutine ZP 0017
[0020] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:3527 IR:3527 DCA I 0127 ;Deposit AC to memory then clear AC, Indexed ZP 0127
[0021] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:3527 IR:3527 DCA I 0127 ;Deposit AC to memory then clear AC, Indexed ZP 0127

Thanks, I’ll try to get up to speed.

I’m thinking that device at 641x isn’t doing our simulators much good. I want to figure out how to configure it out of my SIMH runs. From reading the source, I’d thought the test pattern was 2525, not 3527.

Anyway, I ran the simulation for a while, then interrupted it and had a look around. Here’s what ended up in page 0:
0000/1157 5427 7000 7000 7000 7000 7000 7000
0010/0534 0140 0000 0000 0000 0000 0000 0557
0020/1417 3131 5531 0400 1423 2023 5021 7400
0030/0602 0600 0601 0603 0604 0007 0010 0037
0040/4314 7777 7777 7777 0652 0600 0047 0047
0050/4314 7777 6314 4000 0014 0014 0014 0014
0060/0000 0000 0000 0000 0000 0000 0000 0000
0070/0000 0000 0000 0000 0000 0000 0000 0000
0100/0000 0000 0000 0000 0000 0000 0000 0000
0110/0000 0000 0000 0000 0000 0000 0000 0000
0120/0000 0000 0000 0000 0000 0000 0000 0000
0130/0000 0000 0000 0000 0000 0000 0000 0000
0140/0000 0010 0004 0000 0000 0000 0000 0000
0150/0000 0000 0000 0000 0000 0000 0000 0000
0160/0000 0000 0000 0000 0000 0000 0000 0000
0170/0000 0000 0000 0000 0000 0000 0000 0000

Vince

1 Like

This is interesting, as we finally get to see what “JMS 17” does.
Apparently it fetches the next word, then branches to the address contained there. A kind of “far JMP”:
JMS 17 /Far JMP
6100 /Destination address

The address in auto-index 17 is also very convenient for fetching arguments and even doing a ‘return’, converting the far JMP into far JMS. The value 0557 actually suggests that the JMS 17 at 0553 had gone to 6100, had fetched a couple of arguments there, and eventually returned to location 0557.

I tried ROM 8473 on different emulators. I think the 641x instructions aren’t a problem there.

I also found 2525. And it’s loaded correctly into MB. We have 1002 added, a sum of a device status read (2 bits). We can simply manually change that. Test pattern is written to pages 0+1.

There’s later a loop in 1152 writing data. After that a jump to 1 and to 7400 and 7436. Then 542, 20, 1123, 20, 1133, After IOF a loop at 1142 and 1152 and back to 1142.
I had to manually skip 2x to reach 1123 on pd8emu.

But at some point when there’s a branch to 20 (after 1164 or 553), that contains later the test pattern as well and that turns into an instruction. Maybe due to different 6100 behavior. Maybe it should be 17? Or 20 at current page instead of page 0. Or start at 400 is wrong.

The far jump sounds plausible. But at 6102 is a JMP I 23.

Data:
That data from 20-57 is a copy from 475 (2475 in ROM 7384). As said that looks like an LCD output. Probably the (default) LCD memory content. And having this on page 0 it’s maybe the temp storage. Or all possible LCD outputs. Or a mask for input or error output.

The line at 40 first looks like 3 digits and that would be the lower line and 4x14 with 4 digits the upper line. But the 3 digits (decimal) holding 4 values. And the upper line is octal. One of the 7777 could be the value. 6314 are 3 blks that must be the lower line.

I assume that 4000 is the little square that automatically appears as separator. The 06xx could be the special symbols. There’s a little dot in the upper line (displayed when power up) and 4 symbols at the left of the lower line. 2 symbols are for the remote-control mode each having 2 variants, the other 2 are * and ; for programming represent ELSE and FURTHERMORE which both is a “1”, the left digit from an instruction. Error code E (top left) can blink, same the remote-control symbols. On the MacOS emu 0652 is 8bit ASCII for “*” and 47 for “'” what is part of the remote-control symbols. But could be a coincidence.

I aligned it this way. I think data continues, even over the next page. A bit later again 0652. 060x could also be addresses for the display. Or maybe not LCD at all.

 0602 0600 0601 0603 
 0604 0007 0010 0037 4314 7777 7777 7777 
 0652 0600 0047 0047 4314 7777 6314 
 4000 0014 0014 0014 0014 1271              4x blank
 6410 1010                                  (still data?
 6411 5341 
  _   7001 7001 7001 7001     
 3142 1036
 3141 3151 3076 4017 
 6100 1123 
 0000 1133
 0652 0000 7053 7010 
 0400 0064 
 7767 1113
 1071 2371 7773 7760 3200 0000 0000 0000

At 0023 I see another “far call” code trampoline, implemented without auto-indexing. Perhaps this allows nested far calls, each with their own argument/return pointer.

1 Like

The code is very hard to check when running from another address with an empty page 0.
I think I’ll better populate page 0 (ROM) first with your memory output.
I will check some other emulators supporting different PDP-8 models. (Aconit, Wineight). I haven’t checked that on SIMH yet.

I still haven’t found any code reading my tables but maybe I just have.
Finding code for the text table should be the easiest as there’s known the most. Maybe the pointer isn’t 4000 but 4001 or 3777 or at the end of value 1 or end of the table. The mnemonics are sorted by unit numbers and these are in table 1 and 4. The printout control characters and code are around 4541. I think a far jump to 2700 (just above table 1). Near that an AND 77 for extracting the unit and interesting 65xx IOTs.

Most tables are now together.
Table 1 at 2742-2777
Table 2 at 3000-4000
Table 3 at 4000-4200
(Table 4) at 2144.

I only found these 2 interesting code segments both with 2 IOTs writing 2 words. (TTY input or less likely keyboard?). The future operands from page 0 are unknown. JMS I 30 will be to 602. There’s a JMP I 33 what is to 603 at there’s a JMP I 34 what is 604 and there’s a JMP I 45 what is 600. There’s a JMP I 32 what is 601 there’s again JMP I 30. Not sure if this is plausible. 45 is in the middle of my assumed LCD default values.

[7605] IRQ,DLY,IE=0,1,0 L/AC:0/0000 MQ:0000 IR:6417 SRCD       ;DP8-EAEB: Read Character Detected
[7606] IRQ,DLY,IE=0,1,0 L/AC:0/0000 MQ:0000 IR:6407 SRTA       ;DP8-EAEB: Read Transfer Address Register
[7607] IRQ,DLY,IE=0,1,0 L/AC:0/0000 MQ:0000 IR:7450 SNA        ;Skip on AC <> 0
[7610] IRQ,DLY,IE=0,1,0 L/AC:0/0000 MQ:0000 IR:5302 JMP @@02   ;Jump Current page @@02
[7702] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:1164 TAD 0164   ;Add operand to AC, ZP 0164
[7703] IRQ,DLY,IE=0,0,0 L/AC:0/7000 MQ:0000 IR:0035 AND 0035   ;AND operand with AC, ZP 0035
[7704] IRQ,DLY,IE=0,0,0 L/AC:0/7000 MQ:0000 IR:3164 DCA 0164   ;Deposit AC to memory then clear AC, ZP 0164
[7705] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:3163 DCA 0163   ;Deposit AC to memory then clear AC, ZP 0163
[7706] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:5301 JMP @@01   ;Jump Current page @@01
[7701] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:5430 JMP I 0030 ;Jump Indexed ZP 0030
[7000] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:5123 JMP 0123   ;Jump ZP 0123
[0123] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:7000 No operation;

[7625] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:6417 SRCD       ;DP8-EAEB: Read Character Detected
[7626] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:6407 SRTA       ;DP8-EAEB: Read Transfer Address Register
[7627] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:7650 SNA CLA    ;Skip on AC <> 0, Clear AC
[7630] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:5236 JMP @@36   ;Jump Current page @@36
[7636] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:1136 TAD 0136   ;Add operand to AC, ZP 0136
[7637] IRQ,DLY,IE=0,0,0 L/AC:0/7000 MQ:0000 IR:1136 TAD 0136   ;Add operand to AC, ZP 0136
[7640] IRQ,DLY,IE=0,0,0 L/AC:1/6000 MQ:0000 IR:3136 DCA 0136   ;Deposit AC to memory then clear AC, ZP 0136
[7641] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:0000 IR:2135 ISZ 0135   ;Increment operand and skip if zero, ZP 0135
[7642] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:0000 IR:5224 JMP @@24   ;Jump Current page @@24
[7624] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:0000 IR:1136 TAD 0136   ;Add operand to AC, ZP 0136
[7625] IRQ,DLY,IE=0,0,0 L/AC:1/6000 MQ:0000 IR:6417 SRCD       ;DP8-EAEB: Read Character Detected
[7626] IRQ,DLY,IE=0,0,0 L/AC:1/6000 MQ:0000 IR:6407 SRTA       ;DP8-EAEB: Read Transfer Address Register
[7627] IRQ,DLY,IE=0,0,0 L/AC:1/6000 MQ:0000 IR:7650 SNA CLA    ;Skip on AC <> 0, Clear AC
[7631] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:0000 IR:1131 TAD 0131   ;Add operand to AC, ZP 0131
[7632] IRQ,DLY,IE=0,0,0 L/AC:1/7000 MQ:0000 IR:7640 SZA CLA    ;Skip on AC = 0, Clear AC
[7633] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:0000 IR:5302 JMP @@02   ;Jump Current page @@02
[7702] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:0000 IR:1164 TAD 0164   ;Add operand to AC, ZP 0164
[7703] IRQ,DLY,IE=0,0,0 L/AC:1/7000 MQ:0000 IR:0035 AND 0035   ;AND operand with AC, ZP 0035
[7704] IRQ,DLY,IE=0,0,0 L/AC:1/7000 MQ:0000 IR:3164 DCA 0164   ;Deposit AC to memory then clear AC, ZP 0164
[7705] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:0000 IR:3163 DCA 0163   ;Deposit AC to memory then clear AC, ZP 0163

I should point out another possible purpose for these call trampolines.

A common problem with ROM and PDP-8 code is that the JMS instruction wants to modify RAM in the instruction area. Moving the target to page zero (with a trampoline there) allows all the rest to be ROM, except for page 0. This simplifies the rest of the hardware, which was probably done here.

1 Like

The manual states that in case of a faulty RAM there’s the error code E9 followed by the address displayed on the upper line.
E9 is 0371. That is stored at 471 and that code happens at 535 after skips at 421 and 431. Then an infinite loop. There’s no output of that on page 0 except the count (RAM location -1) at 10. So IOTs 6410+6411 must be for the LCD. After that soon an index jump to 1123 for finally writing contents to page 0. At 1151 there are 49 words written with 0, locations 46-126.

[0431] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:3527 IR:5335 JMP @@35   ;Jump Current page @@35
[0535] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:3527 IR:1271 TAD @@71   ;Add operand to AC, Current page @@71
[0536] IRQ,DLY,IE=0,0,0 L/AC:1/0371 MQ:3527 IR:6410 SSRG       ;DP8-EAEB: Skip if Ring Flag
[0537] IRQ,DLY,IE=0,0,0 L/AC:1/0371 MQ:3527 IR:1010 TAD 0010   ;Add operand to AC, ZP 0010
[0540] IRQ,DLY,IE=0,0,0 L/AC:1/0403 MQ:3527 IR:6411 SSCA       ;DP8-EAEB: Skip if CarrierAGC Flag
[0541] IRQ,DLY,IE=0,0,0 L/AC:1/0403 MQ:3527 IR:5341 JMP @@41   ;Jump Current page @@41
[0541] IRQ,DLY,IE=0,0,0 L/AC:1/0403 MQ:3527 IR:5341 JMP @@41   ;Jump Current page @@41

A faulty ROM (unknown IRQs) results in E8 0004 and other hardware transfer errors in E8 0001 (or 2, 3). E8 is 0370 but that isn’t stored in ROM.
(On my emulator there are 4 different test patterns written (7256, 6534, 5270) and after that 0.)

After 1151 there’s 10 added and 370 written to 40, so E8 instead of 2 blanks followed by 407 and an infinite loop.

[0022] IRQ,DLY,IE=0,0,1 L/AC:1/0000 MQ:0000 IR:5531 JMP I 0131 ;Jump Indexed ZP 0131
[7010] IRQ,DLY,IE=0,0,1 L/AC:1/0000 MQ:0000 IR:1031 TAD 0031   ;Add operand to AC, ZP 0031
[7011] IRQ,DLY,IE=0,0,1 L/AC:1/0600 MQ:0000 IR:3045 DCA 0045   ;Deposit AC to memory then clear AC, ZP 0045
[7012] IRQ,DLY,IE=0,0,1 L/AC:1/0000 MQ:0000 IR:1417 TAD I 0017 ;Add operand to AC, Indexed ZP 0017 [Auto pre-inc]
[7013] IRQ,DLY,IE=0,0,1 L/AC:1/0400 MQ:0000 IR:3143 DCA 0143   ;Deposit AC to memory then clear AC, ZP 0143
[7014] IRQ,DLY,IE=0,0,1 L/AC:1/0000 MQ:0000 IR:1141 TAD 0141   ;Add operand to AC, ZP 0141
[7015] IRQ,DLY,IE=0,0,1 L/AC:1/0010 MQ:0000 IR:1237 TAD @@37   ;Add operand to AC, Current page @@37
[7016] IRQ,DLY,IE=0,0,1 L/AC:1/0370 MQ:0000 IR:3040 DCA 0040   ;Deposit AC to memory then clear AC, ZP 0040

Plausible data written to page 0 obviously confirms this ROM combination.

I now try to find code for the CRC check. With that I can find how the text is read and printed and maybe the key mapping.
Checksum calculation is probably similar like on PDP-8, but my sum has 6 digits (or up to 10) for an imported dedicated code region with 6 digits. A later comparison error would result in E3 xxxx (0363 not in ROM). A CRC check is initiated by F2 (322) and a printout with CRC by F1 (321 at 4707 but I haven’t found out how this is accessed). Maybe again calculated.

I found this code, but I didn’t know 0371 represents ‘E9’ (not even ‘f9’?). I was pretty sure it was attempting to display the pointer from location 0010.

I’m doing ‘br 0407;d ac 0;c’ in my simh.ini in an effort to clear AC after the initialization IOTs. That seems fine, and I get to my breakpoint at 0463. I can see that it has called the page 0 setup routine at 7731, then gone to 00456 to set up and enable interrupts.

The code at 00463 is strange, though. After setting 0072 and 0076 to 2000, it does a JMP I 31, which starts a loop, cycling via indirect JMPs to 0600, 0601, 0602, 0603, 0604, then back to 0600. Maybe the interrupt service can affect these pointers and break us out of the loop?

It definitely does, in at least a couple of cases.

1 Like

The display is only uppercase. F0=320, F9= 331, E0=360. Blk 0=300. _0=340.
I found an output of 360 0 (E0 0 =Numpad key not allowed) eg when starting from 1044, and E8 004 (ROM error) but also E8 007 and 407 what is not documented. Either the AC contents weren’t yet correct or maybe the right value is BCD as well. I can’t guarantee that these values are LCD codes here at all. But looks likely.

Concerning CRC: I wondered how a 6 digit instruction is stored. It’s 17 bits (1-4-12) and photos of a cart suggest that each bit is written to a different IC. There are 2 pairs of 3 daughter boards with 12 and 4 chips each. I think the single bit is stored on the chips on the base PCB. That represents ELSE and FURTHERMORE both for 1, the 2 left buttons on the panel for a parallel program and also a new rung on a ladder logic.

So a CRC is not that simple and probably done in 3 parts. But to reduce space maybe one shared code with different indexed values.
I’m not sure if I’ll ever find code for that. So I first tried to continue after the RAM check.

I found an assumed far jump at 2241 target to 6400. Starting from that I got a 7356 output (3x_) and 2x16 replacing 14. 7356 is indexed from an index. Indexed at 7775, copied to 10 and then indexed again. I also found 37 instead of 47 written to 46.

[6400] IRQ,DLY,IE=0,1,0 L/AC:0/0000 MQ:0000 IR:1072 TAD 0072   ;Add operand to AC, ZP 0072
[6401] IRQ,DLY,IE=0,1,0 L/AC:0/0000 MQ:0000 IR:0204 AND @@04   ;AND operand with AC, Current page @@04
[6402] IRQ,DLY,IE=0,1,0 L/AC:0/0000 MQ:0000 IR:3072 DCA 0072   ;Deposit AC to memory then clear AC, ZP 0072
[6403] IRQ,DLY,IE=0,1,0 L/AC:0/0000 MQ:0000 IR:4017 JMS 0017   ;Jump to subroutine ZP 0017
[0020] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:1417 TAD I 0017 ;Add operand to AC, Indexed ZP 0017 [Auto pre-inc]
[0021] IRQ,DLY,IE=0,0,0 L/AC:0/7761 MQ:0000 IR:3131 DCA 0131   ;Deposit AC to memory then clear AC, ZP 0131
[0022] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:5531 JMP I 0131 ;Jump Indexed ZP 0131
[7761] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:1375 TAD @@75   ;Add operand to AC, Current page @@75
[7762] IRQ,DLY,IE=0,0,0 L/AC:0/3574 MQ:0000 IR:3010 DCA 0010   ;Deposit AC to memory then clear AC, ZP 0010
[7763] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:1410 TAD I 0010 ;Add operand to AC, Indexed ZP 0010 [Auto pre-inc]
[7764] IRQ,DLY,IE=0,0,0 L/AC:0/0016 MQ:0000 IR:3054 DCA 0054   ;Deposit AC to memory then clear AC, ZP 0054
[7765] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:1054 TAD 0054   ;Add operand to AC, ZP 0054
[7766] IRQ,DLY,IE=0,0,0 L/AC:0/0016 MQ:0000 IR:3055 DCA 0055   ;Deposit AC to memory then clear AC, ZP 0055
[7767] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:1410 TAD I 0010 ;Add operand to AC, Indexed ZP 0010 [Auto pre-inc]
[7770] IRQ,DLY,IE=0,0,0 L/AC:0/7356 MQ:0000 IR:3052 DCA 0052   ;Deposit AC to memory then clear AC, ZP 0052
[7771] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:3060 DCA 0060   ;Deposit AC to memory then clear AC, ZP 0060
[7772] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:3061 DCA 0061   ;Deposit AC to memory then clear AC, ZP 0061
[7773] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:3062 DCA 0062   ;Deposit AC to memory then clear AC, ZP 0062
[7774] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:5020 JMP 0020   ;Jump ZP 0020
[0020] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:1417 TAD I 0017 ;Add operand to AC, Indexed ZP 0017 [Auto pre-inc]
[0021] IRQ,DLY,IE=0,0,0 L/AC:0/1566 MQ:0000 IR:3131 DCA 0131   ;Deposit AC to memory then clear AC, ZP 0131

0040: 4314 7777 7777 7777 0652 0600 0047 0047 -LCD upper. 2x blk, 7777 or 4x0, default
0050: 4314 7777 7356 4000 0016 0016 0014 0014 2xblk on left, 3x_ right for entering a (decimal) value. 16=1x_?

I don’t know why there are 5 600x pointers. 4 locations + symbols of the LCD. 2+3 digits. Or 2x2 or 4+else that could be anything. 4 keys + enter.

I still have a deep confusion about the LCD display, which doesn’t seem to be getting any better. Perhaps the memory error code at 0535 will illustrate my confusion. The code there loads from 0471 the value 0371 (0x0F9), then does an IOT 6410. I’m assuming this loads the AC value into the LCD, then clears AC. The code then loads location 0010, which points to where the error occurred, and does IOT 6411.

Somehow, this creates the text “E9” on one line, and the address from location 0010 is somehow displayed as readable text on another. The 6100 CPU then does “JMP .”, with the interrupts off, so it presumably has no more involvement.

So how the heck are things encoded for IOTs 6410 and 6411? Is IOT 6410 always text, with a character chart somewhere? Is 6411 always a word value to display in numeric form? Or is the address being in the range of 0011-0177 somehow requesting a numeric display? Is the last digit of the IOT being used as a line number, or is that somehow coming from AC too?

It seems in general that there’s far too much going on with the display to be encoded with a 12 bit output value per line.

Or is the 0371 also a pointer, pointing at 0371, which seems to have 4527 4524 4167 0032 0261 0000 stored there?? Which might encode something, but still doesn’t explain the friendly display of the address.

The LCD has 4 locations addressed separately + symbols. There’s no text output except E and F for error and function.
I have a table with the BCD combinations. Numbers are I think just stored in octal, so there’s mainly of interest the combinations with E,F, blank and _ with the rest. 3 bits forming one digit, which are then added.

E left=360, “_” right= 16=376.
11- 11 1 -110
3 - 7- 6

F9 7777
*E8 999

E and F can only be displayed on the left positions, on upper right only an octal word, on lower right 3 decimal values (stored as octal 4 digits).
Error messages differ, some show the address like the faulty RAM cel, others show an encoded wrong key from what key group. Error can show E 0000 or E0 0000. Again, the programming is meant for the PLC which has the same LCD. I can only confirm the error messages on my device. E0-E9. Half of them are about BUS errors in combination with the PLC. The rest about RAM/ROM error and wrong key combination or syntax error. There must be tables of allowed keys and syntax and their error codes.

ASCII text output is reserved or was planned and should not work on this ROM. I assumed the empty page for that but that turned out page 0. There’s already one undocumented instruction for loading text obviously for an external display or an upcoming version. So loading one register with ASCII instead of decimal or memory content.
Some errors are severe like a ROM error, so there’s a loop. Others like a wrong key can be fixed and cleared.

The only character chart is that for a printout, mnemonics stored at 4000-4177.

Thanks! I think I get it this time.

You mention 4 regions. I’m aware of a two digit “bcd” region, a three digit “bcd” region, and an 4 digit octal region. What and where is the fourth region?

AP1. | AP2
AP3. | AP4
Two regions with 2 digits on the left, 2 on the right, top left=location 1.

A1-| A2
88 -8888

88- .888

A3 - A4

I tried also a start from 200. Very similar but overwriting pages 1, 2 and more. 1KWords.

After start from 400 and continue after the RAM check, with some skips reaching 431, skip after 7403 to 7404 there’s 7600 written to 32 where we have the 600x jumps.

Starting from 7600 , over 731, 740 and 670 I have this adding 1 take a 14 from 56, rotate left 4x → 320 +14 from 57=334 +4000 from 53.
320=F 334= F blank. 4000 is probably a squared symbol between location 3+4. So at 40 there’s very likely LCD values.

F is displayed when pressing the F key. So maybe I’ve found a keyboard IOT. Needs more checking. Just found.

(After 731 there’s a full loop starting again at 400.)

0000: 7421 5427 0000 0000 0000 0000 0000 0000
0010: 0020 0000 0000 0000 0000 0000 0000 0554
0020: 0000 3131 5531 0400 1423 2023 5021 7400
0030: 0602 0600 7600 0605 0604 0007 0010 0514
0040: 4314 7777 7761 7777 0652 0600 0047 0047
0050: 4334 7777 6314 4000 0014 0014 0014 0014 (later 4334)
0060: 0000 0000 0000 0000 0000 0000 0000 0000
0070: 0000 0000 2000 0000 0000 0000 0000 0000

[0670] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:0000 IR:1014 TAD 0014   ;Add operand to AC, ZP 0014
[0671] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:0000 IR:7040 CMA        ;Complement AC
[0672] IRQ,DLY,IE=0,0,0 L/AC:1/7777 MQ:0000 IR:0145 AND 0145   ;AND operand with AC, ZP 0145
[0673] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:0000 IR:7421 MQL        ;Load MQ from AC then clear AC
[0674] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:0000 IR:1145 TAD 0145   ;Add operand to AC, ZP 0145
[0675] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:0000 IR:7040 CMA        ;Complement AC
[0676] IRQ,DLY,IE=0,0,0 L/AC:1/7777 MQ:0000 IR:0014 AND 0014   ;AND operand with AC, ZP 0014
[0677] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:0000 IR:7501 MQA        ;OR MQ with AC
[0700] IRQ,DLY,IE=0,0,0 L/AC:1/0000 MQ:0000 IR:7001 IAC;Increment AC
[0701] IRQ,DLY,IE=0,0,0 L/AC:1/0001 MQ:0000 IR:6416 SSBE       ;DP8-EAEB: Skip on Bus Error
[0702] IRQ,DLY,IE=0,0,0 L/AC:1/0001 MQ:0000 IR:1125 TAD 0125   ;Add operand to AC, ZP 0125
[0703] IRQ,DLY,IE=0,0,0 L/AC:1/0001 MQ:0000 IR:6416 SSBE       ;DP8-EAEB: Skip on Bus Error
[0704] IRQ,DLY,IE=0,0,0 L/AC:1/0001 MQ:0000 IR:1056 TAD 0056   ;Add operand to AC, ZP 0056
[0705] IRQ,DLY,IE=0,0,0 L/AC:1/0015 MQ:0000 IR:7106 CLL RTL    ;Clear L, Rotate AC & L left twice
[0706] IRQ,DLY,IE=0,0,0 L/AC:0/0064 MQ:0000 IR:7006 RTL        ;Rotate AC & L left twice
[0707] IRQ,DLY,IE=0,0,0 L/AC:0/0320 MQ:0000 IR:1057 TAD 0057   ;Add operand to AC, ZP 0057
[0710] IRQ,DLY,IE=0,0,0 L/AC:0/0334 MQ:0000 IR:1053 TAD 0053   ;Add operand to AC, ZP 0053
[0711] IRQ,DLY,IE=0,0,0 L/AC:0/4334 MQ:0000 IR:1060 TAD 0060   ;Add operand to AC, ZP 0060
[0712] IRQ,DLY,IE=0,0,0 L/AC:0/4334 MQ:0000 IR:3050 DCA 0050   ;Deposit AC to memory then clear AC, ZP 0050
[0713] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:1046 TAD 0046   ;Add operand to AC, ZP 0046
[0714] IRQ,DLY,IE=0,0,0 L/AC:0/0047 MQ:0000 IR:3010 DCA 0010   ;Deposit AC to memory then clear AC, ZP 0010
[0715] IRQ,DLY,IE=0,0,0 L/AC:0/0000 MQ:0000 IR:1410 TAD I 0010 ;Add operand to AC, Indexed ZP 0010 [Auto pre-inc]
[0716] IRQ,DLY,IE=0,0,0 L/AC:0/4334 MQ:0000 IR:6410 SSRG       ;DP8-EAEB: Skip if Ring Flag
[0717] IRQ,DLY,IE=0,0,0 L/AC:0/4334 MQ:0000 IR:1410 TAD I 0010 ;Add operand to AC, Indexed ZP 0010 [Auto pre-inc]