Old school 8080 EPROM disassembly - is it making sense? - Page 1
Forum section: electronics / general

author: SilverSolder
author_rank: Super Contributor
timestamp: February 08, 2021, 03:56:33 am
content: I dumped the firmware out of an Intel 8080A powered vintage Fluke DMM, and ran it through the DASMx disassembler to see if anything interesting can be gleaned...I don't know anything about the 8080A, and suspect the program author might have used "tricks" that the disassembler struggles to understand.If anyone with 8080 experience has a minute to look at the startup code and the first few jumps just to verify that the disassembler is not doing anything crazy, it would be highly appreciated!

author: retiredfeline
author_rank: Frequent Contributor
timestamp: February 08, 2021, 04:03:00 am
content: The initial bytes are the various vectors, the first being the reset vector. If you note where it jumps to you can find the "main" program which will make more sense.

author: SilverSolder
author_rank: Super Contributor
timestamp: February 08, 2021, 04:22:21 am
content: Quote from: retiredfeline on February 08, 2021, 04:03:00 amFrom what I have gleaned, the 1970's 8080A starts executing at address 0000, no vectors or anything like that?

author: retiredfeline
author_rank: Frequent Contributor
timestamp: February 08, 2021, 04:25:00 am
content: That's what I mean by a vector. 0 is the reset vector. After that come interrupt vectors.

author: SilverSolder
author_rank: Super Contributor
timestamp: February 08, 2021, 04:29:16 am
content: Quote from: retiredfeline on February 08, 2021, 04:25:00 amMy understanding is that 8080A starts executing at address 0000, it does not have a reset vector - it literally starts with the program counter at zero and gets going from there and expects the program to start there.

author: retiredfeline
author_rank: Frequent Contributor
timestamp: February 08, 2021, 04:34:19 am
content: You can split hairs and call it what you want but the fact that there is only limited space 8 bytes IIRC before the next vector means that in practice a jump is usually put there.

author: SilverSolder
author_rank: Super Contributor
timestamp: February 08, 2021, 04:57:38 am
content: Quote from: retiredfeline on February 08, 2021, 04:34:19 amOK understood. It is just a bit unusual to me that it isn't a table of addresses, but actual code being executed in those locations...The disassembler found the following code block at 0000, which does seem to jump elsewhere as you suggest.Code:;org00000H;L0000:inxhlxih,0407CHcallL23A0callL2188pophlxid,00004Hdaddlxid,X4066mvic,004HcallL1EA6dcxhcallL1E9BxraastaX41BCret

author: retiredfeline
author_rank: Frequent Contributor
timestamp: February 08, 2021, 05:08:39 am
content: Quote from: SilverSolder on February 08, 2021, 04:57:38 amIt's simpler to implement in hardware, just mov PC,#0, instead of mov PC,(0), in pseudocode.I would question whether what you have is a valid dump. The code at 0 (I was on a mobile before) looks too complicated for a reset entry. Are there any other EPROMs? Any trickery with address lines so that EPROM halves are swapped?Maybe someone else has already dumped this DMM EPROM and you can just download it to compare?

author: SilverSolder
author_rank: Super Contributor
timestamp: February 08, 2021, 05:25:08 am
content: The code is spread across two EPROMS and verified good with another owner who also extracted the ROM.I just concatenated them in the order of their designators in the diagram... u23 and u24Let me try to disassemble the other one separately and see if that makes more sense, thanks for the hints -

author: SilverSolder
author_rank: Super Contributor
timestamp: February 08, 2021, 05:30:14 am
content: OK so starting with the other EPROM first, the disassembled code probably looks more like you are saying?So the code at 0000 is the reset... and L0010: could be an interrupt "vector"?Code:;CPU:Intel 8080 (MCS-80/85 family);;;org00000H;mvih,0C0Hmvim,0FFHjmpL02DB;db0BBH, 0FBH, 0F5H, 03AHdb00CH, 041H, 0C3H, 053Hdb00CH;L0010:lxid,X401Amvic,00CHjmpL2214;db0F5H, 0E5H, 0D5H, 0C5Hdb02AH, 012H, 041H, 0E9Hdb0F5H, 0E5H, 0D5H, 0C5Hdb02AH, 012H, 041H, 0E9Hdb0CDH, 0AEH, 013H, 02AHdb0C8H, 041H, 0E9H, 0FFHdb0F5H, 0E5H, 02AH, 010Hdb041H, 0E9H, 0FFH, 0FFH;L0038:out000Hdilxisp,04800HcallL0091xraastaX41FDcallL2938callL01EDL004B:callL0214xraastaX41F8callL34A3callL087DcallL2201callL0E62callL0EABcallL0962callL0445callL26E0callL0500lxid,04069HcallL2848callL16B8callL007CjmpL004B;L007C:ldaX41F8oraarnzdcrastaX41F8out048Hret;L0088:out008Hret;L008B:out000Hret;L008E:out040Hret;[...]

author: retiredfeline
author_rank: Frequent Contributor
timestamp: February 08, 2021, 05:32:28 am
content: Yes, looks like you should concatenate in the order U24 + U23. Also the code starting 38H is an interrupt service routine.Also is there any way you can hint to DASM that there is code starting at 08H, 18H, and so forth? Those are the RST vectors. There may be code there that DASM is confusing for constants due to misalignment.

author: SilverSolder
author_rank: Super Contributor
timestamp: February 08, 2021, 05:45:01 am
content: Awesome, thanks for the help - talk about missing the forest due to the trees!The disassembler output looks better now (attached).[edit:] added full listing with hex offsets

author: SilverSolder
author_rank: Super Contributor
timestamp: February 08, 2021, 06:17:28 am
content: Quote from: retiredfeline on February 08, 2021, 05:32:28 amYes, there are ways to do that, it seems. I only have a couple of hours experience with DASMx so will have to experiment with that later.Looks like a lot of work, if you want to understand everything going on there...

author: retiredfeline
author_rank: Frequent Contributor
timestamp: February 08, 2021, 06:23:19 am
content: BTW the fact that the 8-bit checksum ends in 00 suggests that there may be a self-test routine inside, or is a big coincidence, so if you decide to hack the code, you should maintain the checksum at 00 by altering some unused byte somewhere.

author: abyrvalg
author_rank: Frequent Contributor
timestamp: February 08, 2021, 09:25:16 am
content: Small recommendation: don’t loose the time learning DASMx, it’s workflow is slow and painful by design (run a pass, look at the output, edit symbol/code/data definition file, run again, observe the changes, repeat). Try Ghidra instead, it is “interactive” - you convert to code/data/rename right in the output window and see the results immediately (with nicely highlighted syntax), follow the jumps/calls in one click (instead of searching the text for label names) and much more.

author: SilverSolder
author_rank: Super Contributor
timestamp: February 08, 2021, 03:13:22 pm
content: Quote from: abyrvalg on February 08, 2021, 09:25:16 amThank you, I had never heard of it. The Ghidra site does not mention 8080 as a supported processor, but does mention Z80. Is Z80 "good enough for Australia" when the object code is 8080?

author: abyrvalg
author_rank: Frequent Contributor
timestamp: February 08, 2021, 04:23:45 pm
content: Yes, Z80 is backward-compatible with 8080. There are minor changes in instructions naming style (i.e. all kinds of MOVx are just MOV now), but the binary encoding remains the same.

author: retiredfeline
author_rank: Frequent Contributor
timestamp: February 08, 2021, 09:52:15 pm
content: Quote from: SilverSolder on February 08, 2021, 03:13:22 pmIt seems the 8085 is supported. This has just a couple more instructions over the 8080, RIM and SIM. Use that. Unfortunately the Z80 turns some unused 8080 opcodes into valid Z80 instructions and the opcode stream might confuse the disassembler.

author: floobydust
author_rank: Super Contributor
timestamp: February 08, 2021, 10:50:08 pm
content: Weird, that disassembly output op-code had me wondering what they are good for:MOV B,B (8080) or LD B,B (Z80)For disassembling the code, the hardest part is knowing when it's code verses a table. Once I know a subroutine, I search and replace the address with a text label i.e. OUT_LCD.Eventually the code starts to make sense.http://popolony2k.com.br/xtras/programming/asm/nemesis-lonestar/8080-z80-instruction-set.html

author: JohnnyMalaria
author_rank: Super Contributor
timestamp: February 08, 2021, 11:14:03 pm
content: Instructions that seem to have no use such as LD B,B are useful if you want to create a carefully timed routine. e.g., LD B, B takes 4 cycles and requires one byte. Of course, NOP does the same. There are some others that can be used to clear/set certain bits in the flags register, too.There's also the possibility that the code uses many of the undocumented instructions. Unless your disassembler is savvy enough, it may just dump them as dbs or, perhaps worse, meaningless instructions. I remember many years ago being delighted that the Z80A in my ZX Spectrum supported a large set of the undocumented instructions and had an extra set of registers (the details are lost to time).

author: floobydust
author_rank: Super Contributor
timestamp: February 08, 2021, 11:26:48 pm
content: Gees I have three books on 8080 and Z-80 assembly language programming on my shelf. I looked and LD r,r' does nothing but waste time if the source and target register are the same.Point is during disassembling of code, if the instructions seem to make no sense, then you're in data/a table or offsetting instructions by a byte.

author: JohnnyMalaria
author_rank: Super Contributor
timestamp: February 08, 2021, 11:34:17 pm
content: A possible reason for things like LD B,B is in self-modifying code. Back when 1K RAM was a luxury, I can imagine a clever so-and-so purposely changing code during execution. e.g., replace opcode 0x40 with 0x41 and LD B,B becomes LD B,C. Life was simple without protected mode etc

author: SilverSolder
author_rank: Super Contributor
timestamp: February 08, 2021, 11:53:04 pm
content: They are VERY space constrained, there is no "fat" in these EPROMS - I can hardly believe they managed to get all the features of this DMM into just 16K. The disassembler found three jumps out of the EPROM address space... presumably into RAM... self modifying code?Ignoring branch outside ROM to 40D8 at address 25A2Ignoring branch outside ROM to 40E9 at address 25B9Ignoring branch outside ROM to 40CB at address 2555

author: WattsThat
author_rank: Frequent Contributor
timestamp: February 09, 2021, 01:55:52 am
content: Yes, jumping to ram was a common trick. It was used for what I called dynamic dispatch, store a jump opcode followed by the address which could change dynamically based upon a parser state or whatever was changing.Those weird tables that don’t make sense might be single byte jump tables, so long as the msb of of the address is the same, you only need to store the lsb offset which saves a byte for every entry. It was common to use everything below 100h for entry points, less of course the vector locations which you’ve already figured out.There are all kinds of ways to squeeze space in micros, almost all the tricks make disassembly more difficult. But nothing can escape patience and persistence. The code is in front of you, all you have to do is make it give up its secrets. Yeah, easy, right?PS: When looking for self-modifying code, it is best to have memorized jmp, ret and call opcodes. It was more common in systems running out of ram.

author: SilverSolder
author_rank: Super Contributor
timestamp: February 09, 2021, 02:00:15 am
content: Quote from: abyrvalg on February 08, 2021, 09:25:16 amWow... Ghidra is one amazing tool! It seems to have turned the object code back into a C program... not just a disassembler, but a decompiler! Magic... truly amazing.There is a pretty big difference in the result when choosing 8085 vs Z80, I ended up preferring the 8085 output.It is pretty obvious how the program starts, and ends up in what looks like its main loop!Code:void RST0(void){ushort uVar1;short sVar2;undefined in_L;undefined *puVar3;byte bVar4;*(undefined *)CONCAT11(0xc0,in_L) = 0xff;puVar3 = (undefined *)CONCAT11(0xe0,in_L);do {*puVar3 = 0xff;bVar4 = (char)((ushort)puVar3 >> 8) + 1;puVar3 = (undefined *)((ushort)puVar3 & 0xff | (ushort)bVar4 << 8);} while (bVar4 != 0);sVar2 = 0x452c;do {uVar1 = (ushort)sVar2 >> 8;bVar4 = (byte)sVar2;sVar2 = sVar2 + -1;} while ((byte)((byte)uVar1 | bVar4) != 0);disableMaskableInterrupts();_DAT_ram_47fe = 0x41;FUN_ram_0091();DAT_ram_41fd = 0;_DAT_ram_47fe = 0x48;FUN_ram_2938();_DAT_ram_47fe = 0x4b;FUN_ram_01ed();do {_DAT_ram_47fe = 0x4e;FUN_ram_0214();DAT_ram_41f8 = 0;_DAT_ram_47fe = 0x55;FUN_ram_34a3();_DAT_ram_47fe = 0x58;FUN_ram_087d();_DAT_ram_47fe = 0x5b;FUN_ram_2201();_DAT_ram_47fe = 0x5e;FUN_ram_0e62();_DAT_ram_47fe = 0x61;FUN_ram_0eab();_DAT_ram_47fe = 100;FUN_ram_0962();_DAT_ram_47fe = 0x67;FUN_ram_0445();_DAT_ram_47fe = 0x6a;FUN_ram_26e0();_DAT_ram_47fe = 0x6d;FUN_ram_0500();_DAT_ram_47fe = 0x73;FUN_ram_2848();_DAT_ram_47fe = 0x76;FUN_ram_16b8();_DAT_ram_47fe = 0x79;FUN_ram_007c();} while( true );}

author: abyrvalg
author_rank: Frequent Contributor
timestamp: February 09, 2021, 11:05:46 am
content: Quote from: SilverSolder on February 08, 2021, 11:53:04 pmThe code at 40CB-40F9 is copied from 2309 (copy done by code at 00F8-0103)

author: SilverSolder
author_rank: Super Contributor
timestamp: February 09, 2021, 04:15:08 pm
content: Attached disassembly listing from the Ghidra tool.I still can't get over how comprehensive it is. It knew about the reset jump table without being told, too.We know that the absolutely first thing this instrument does when it starts, is1) Somehow it figures out which hardware it is running in - this code is used in two different models of the instrument2) Depending on what hardware was identified, it will display one of the two strings below in the LED display (ignore spaces in front):HI - 5.0.6HI - 6.0.7It is not immediately obvious to me how the 8080 gets input from the outside world to help identify the hardware....

author: m k
author_rank: Super Contributor
timestamp: February 10, 2021, 04:11:05 pm
content: It can use I/O channel or direct memory style, where pheripheral is just a part of RAM.Activation can be polled or from other direction by interrupts.Start of your code isCode:ram:0000 26 c0 LD H,0xc0ram:0002 36 ff LD (HL),0xffram:0004 c3 db 02 JP LAB_ram_02dbMnemonics are different if you read Intel manuals, there this LD opcode is MVI and (HL) is M.The code says: put 0xff to address 0xc0**.So it doesn't care what is in the L-part of HL.It can be a pheripheral decoder, where high side of address is pulling pins down and then selecting something.Code continuesCode:ram:02db 3e ff LD A,0xffram:02dd 26 e0 LD H,0xe0LAB_ram_02df XREF: ram:02e1(j)ram:02df 77 LD (HL),Aram:02e0 24 INC Hram:02e1 c2 df 02 JP NZ,LAB_ram_02dfram:02e4 11 2c 45 LD DE,0x452cLAB_ram_02e7 XREF: ram:02ea(j)ram:02e7 7a LD A,Dram:02e8 b3 OR Eram:02e9 1b DEC DEram:02ea c2 e7 02 JP NZ,LAB_ram_02e7ram:02ed c3 38 00 JP RST7 undefined RST7()Now H is 0xe0 and L is ignored again.Here 0xff is put to 0xe0**-0xff**.Then there is a delay, keep in mind that there DE has endians sort of mixed.Finally jump to 0x0038, from where the sort of a warm startup begins.Code:ram:0038 d3 00 OUT (0x0),Aram:003a f3 DIram:003b 31 00 48 LD SP,0x4800ram:003e cd 91 00 CALL FUN_ram_0091 undefined FUN_ram_0091()ram:0041 af XOR Aram:0042 32 fd 41 LD (DAT_ram_41fd),AThere A is put out to I/O port 0x0 and then interrupts are didabled.Register A is again what ever it happens to be so it must be a result from the earlier delay.Next stack pointer is initialized and so normal operation is pretty much ready to go.(CALL has a rational place to put its return address)

author: SilverSolder
author_rank: Super Contributor
timestamp: February 11, 2021, 03:21:25 am
content: Very interesting,Looking at how the instrument boots, the entire sequence is:- Figure out what it is (out of two possible models)- Displays "HI - 5.0.6" or "HI - 6.0.7" to show the version number of the firmware to the world- Short delay of about a second,- Then it scans all installed options,- Displays the one digit ID number of all the options across the digits of the display, leaving blanks where the option is not installed- Another short delay of about a second,- Finally start the main loop of the codeAre you saying the first point where the code learns something about the outside world already at 0002, when it writes to some "magic address" that may trigger an interrupt?

author: Roman oh
author_rank: Regular Contributor
timestamp: February 11, 2021, 09:28:31 am
content: Hi, guys.I just came across this thread today.Background - I'm retired now, but cut my teeth in intel 4004, then 8080 and 8085. I've written more lines of 8080/8085 assembler than I've had hot lunches, and fielded a number of hardware devices with 8080 and (more so) 8085controllers. But that was all a long time ago.By coincidence, as owner of two 8506's and one 8502 (and never ceasing to be amazed at how precise they are (accuracy is another matter) I started exactly this exercise on my own about 3 weeks ago, working with 6.0.6. I was thinking that maybe I could hack the IEEE488 code to make it more tractable in my environment. I started at the beginning (location 0) and tried to follow the threads, working with the schematics. I did work out the following, from looking at the schematics. But it may or may not be correct, because the deeper I went, the less it all made sense.For what it's worth:- code starts executing at RST0 (address 0000), of course. Does what looks like a quick hardware reset and then jumps (via a short delay at 0x02d6 in my version (0x02db in 6.0.7)) to 0x0038 where there are calls to a list of subroutines, the first few of which appear to do housekeeping like clearing RAM, presetting some code in RAM areas that it uses, and then a loop starting at 0x004b down to 0x0079 which forms the main instrument foreground loop.Then:-RST1 (0x0008) looks like the entry point for the 400Hz (480Hz in the 60Hz world) interrupt-RST2 (0x0010) looks like the entry point for interrupts from the parallel interface-RST3 (0x0018) looks like the entry point for interrupts from the bit serial interface-RST4 (0x0020) looks like the entry point for interrupts from the IEEE488 interface-RST5 (0x0028) , despite having code at that point, does not appear to be capable of activation by the hardware-RST6 (0x0030) looks like an entry for ACK timeouts. Whenever the CPU addresses a piece of hardware (other than the controller itself), it suspends the CPU until the offboard card raises an Acknowledge response. But it only waits for a short time, and if no ACK is received, this interrupt terminates the WAIT period and then the CPU.....does....something-RST7 (0x0038) isn't used as an interrupt entry, but is the start of the main code, as described earlier.And yes, some code executes from RAM, and a number of IO statements are not completely obvious from looking at the schematics, and after a couple of days of treating this like an interesting jigsaw puzzle, I went off to do other things. (Probably easier to fix my 488 challenges at the other end!).Then I came across this thread... which I shall watch avidly, and may get re-enthusedRoman-

author: SilverSolder
author_rank: Super Contributor
timestamp: February 11, 2021, 02:18:00 pm
content: Quote from: Roman oh on February 11, 2021, 09:28:31 amHey @Roman, welcome to the EEVblog where you seem to be a good fit for Dave's philosophy - "Don't turn it on, take it apart!"There is another thread about these meters that is not so much about the 8080 code but interesting nevertheless:https://www.eevblog.com/forum/testgear/some-old-school-instruments-showing-how-its-done-(hp-3325a-and-fluke-8506a)/msg3086825/#msg3086825One member recently uploaded the binaries for 6.0.7 which you could use to update your meters, if you have an EPROM programmer?It's funny how your description of the structure of the program seems to match what the Ghidra tool extracted out of it:Code:void RST0(void){ushort uVar1;short sVar2;undefined in_L;undefined *puVar3;byte bVar4;*(undefined *)CONCAT11(0xc0,in_L) = 0xff;puVar3 = (undefined *)CONCAT11(0xe0,in_L);do {*puVar3 = 0xff;bVar4 = (char)((ushort)puVar3 >> 8) + 1;puVar3 = (undefined *)((ushort)puVar3 & 0xff | (ushort)bVar4 << 8);} while (bVar4 != 0);sVar2 = 0x452c;do {uVar1 = (ushort)sVar2 >> 8;bVar4 = (byte)sVar2;sVar2 = sVar2 + -1;} while ((byte)((byte)uVar1 | bVar4) != 0);disableMaskableInterrupts();_DAT_ram_47fe = 0x41;FUN_ram_0091();DAT_ram_41fd = 0;_DAT_ram_47fe = 0x48;FUN_ram_2938();_DAT_ram_47fe = 0x4b;FUN_ram_01ed();do {_DAT_ram_47fe = 0x4e;FUN_ram_0214();DAT_ram_41f8 = 0;_DAT_ram_47fe = 0x55;FUN_ram_34a3();_DAT_ram_47fe = 0x58;FUN_ram_087d();_DAT_ram_47fe = 0x5b;FUN_ram_2201();_DAT_ram_47fe = 0x5e;FUN_ram_0e62();_DAT_ram_47fe = 0x61;FUN_ram_0eab();_DAT_ram_47fe = 100;FUN_ram_0962();_DAT_ram_47fe = 0x67;FUN_ram_0445();_DAT_ram_47fe = 0x6a;FUN_ram_26e0();_DAT_ram_47fe = 0x6d;FUN_ram_0500();_DAT_ram_47fe = 0x73;FUN_ram_2848();_DAT_ram_47fe = 0x76;FUN_ram_16b8();_DAT_ram_47fe = 0x79;FUN_ram_007c();} while( true );}

author: m k
author_rank: Super Contributor
timestamp: February 11, 2021, 04:59:25 pm
content: Quote from: SilverSolder on February 11, 2021, 03:21:25 amCould be but it's generally too early.Interesting part is the coding of that delay and then start of RST7.Since delay could be easily coded without those LD and OR there are probably accurate timing something.Then that OUT 0,A from start of RST7.Since there are no place for return address a possible interrupt must be one way only, but situation is also known so putting something to A and jumping to RST7 is completely valid.There also seems to be only one IN A,0.One other thing.I seem to have seen some irregularities in that Ghidra file, but disassembling is not an easy thing to do completely accurately.Like Roman said RST5, like those others are known code addresses and must contain a valid code but if you check your earlier files one had one of them ignored.Address 7 then is the opposite, it's a no code but one of your earlier files have continued from there and failed.Generally you have to add those code and data points manually.Good disassembler would follow all jumps and calls but it is still powerless when partial length of data is in question.A bit more from RST7.Code:ram:004b cd 14 02 CALL FUN_ram_0214 undefined FUN_ram_0214()LAB_ram_004e XREF: FUN_ram_0d4d:0211(j)ram:004e af XOR Aram:004f 32 f8 41 LD (DAT_ram_41f8),Aram:0052 cd a3 34 CALL FUN_ram_34a3 undefined FUN_ram_34a3()ram:0055 cd 7d 08 CALL FUN_ram_087d undefined FUN_ram_087d()That 0x0055 seems to be already demanding a bit.Code:ram:087d 3a 10 40 LD A,(DAT_ram_4010)ram:0880 b7 OR Aram:0881 c8 RET Zram:0882 cd 8e 00 CALL FUN_ram_008e undefined FUN_ram_008e()ram:0885 76 HALTram:0886 c3 7d 08 JP FUN_ram_087d undefined FUN_ram_087d()Code:ram:008e d3 40 OUT (DAT_io_0040),Aram:0090 c9 RETSo when value in 0x4010 is >0 it is put out to I/O port 0x40 and CPU is halted.

author: SilverSolder
author_rank: Super Contributor
timestamp: February 11, 2021, 05:35:42 pm
content: QuoteCould that be where it identifies what model it is?

author: m k
author_rank: Super Contributor
timestamp: February 11, 2021, 07:10:22 pm
content: Anything interruptible can happen before that RST7 and all non maskable ones anytime.Some processors have interrupts disabled at the start but DI indicates that it is not the case here.Usually things are put in order first but it's not a must.If everything is static and inside a subroutine handled there are no need to do any initializings.Yet my guess is that it is a delay of 1s where some other parts are timed.At the right of the Ghidra file there are XREFs.Those are addresses from where the local address is accessed.There seems to be no turning backs to those early addresses.

author: m k
author_rank: Super Contributor
timestamp: February 13, 2021, 10:06:59 am
content: Wonky vision may have had issues.Code:ICn(A14-8) (A15 = enable)6543210---111- ohms converter---1-11 current shunts??????? IEEE 4886543210 20mA current loop1-1---1 status in1-1--1- data in1-11--- data out-11-1-- continue (D7 -> _INT)6543210 parallel interface-1-1--1 data out-1-1-1- control out-1-11-- D7 -> ???1-1---1 data in1-1--1- control in1-1-1-- module status (GND -> _INT)6543210 external trigger111----65432101----11 keyboard-1---11 display--11--1 signal conditioner--11-1- A9 active filter--111-- A10A2 Fast RR A/D converter--_+11- ???--1--11 A11A1 attenuator

author: SilverSolder
author_rank: Super Contributor
timestamp: February 13, 2021, 03:16:38 pm
content: Quote from: m k on February 13, 2021, 10:06:59 amThe universe of possible options that were available as separate plug-in cards (that could be present on the system bus) are:OptionDescription01 AC/DC Converter - Averaging (model 8505A only, mutually exclusive with option 09)02 Ohms Converter03 Current Shunts05 IEEE-488 Interface (Options 5, 6, 7 are mutually exclusive)06 Bit Serial Asynchronous Interface (Options 5, 6, 7 are mutually exclusive)07 Parallel Interface (Options 5, 6, 7 are mutually exclusive)08 Isolator (standard)09 AC/DC Converter - RMS (model 8505A only, mutually exclusive with option 01)0A Thermal RMS Converter (model 8506A only, standard)I am not aware of a 20mA current loop option... maybe that is the mysterious missing Option 04 in the list?

author: Roman oh
author_rank: Regular Contributor
timestamp: February 14, 2021, 12:58:42 pm
content: Thanks, SilversolderDon't see how to directly quote snippets (despite reading some advice on how to) soQuote from Silversolder:Hey @Roman, welcome to the EEVblog where you seem to be a good fit for Dave's philosophy - "Don't turn it on, take it apart!"There is another thread about these meters that is not so much about the 8080 code but interesting nevertheless:https://www.eevblog.com/forum/testgear/some-old-school-instruments-showing-how-its-done-(hp-3325a-and-fluke-8506a)/msg3086825/#msg3086825One member recently uploaded the binaries for 6.0.7 which you could use to update your meters, if you have an EPROM programmer?It's funny how your description of the structure of the program seems to match what the Ghidra tool extracted out of it:OKFirst - been watching, and a member and casual poster for a while, but after a quiet period came back to this thread and saw I had been declared a non-person, so I had to recreate myselfI actually got to this thread from the other that you identified; like the OP on that thread, I am continually amazed at how good and stable these things are. I have two of them from very uncertain backgrounds, not been calibrated in many many years, and seldom more than a few ppm (well...10 or 20 or so) apart on AC, DC and ohms!And I saw the pointer to 6.0.7 - mine were 6.0.4 and 6.0.6 - I now have one at 6.0.7 and am trying to find a fourth 2764 for the second one (I am reluctant to erase the originals until I have some months of stable operation). Tried to do something clever today with a 27128, looking at the (notionally) unused A13 on pin 26, but that didn't seem to work. I'll keep working it.And I am quite comforted (rather than amused) at the fact that my code analysis is confirmed by Ghira. I am about to set that up (I was using DASMx) and I think the first thing has has piqued my curiosity is "what is changed from 6.0.6 to 6.0.7?"Sadly (?) where I am there is not much Covid restriction, and it's a lovely summer, so I guess this is a longer term undertaking...I will say (again) that I am quite impressed with how much knowledge there is out there, and the willingness of people to share. Now in MY day........!!!!!R

author: m k
author_rank: Super Contributor
timestamp: February 14, 2021, 01:01:03 pm
content: My mistake, I didn't look.Bit Serial has both, no RS-232 controls though, it seems.It also seems that External Trigger is Isolator (standard).The device is also demonstrating how discretes do IEEE-488.One thing I don't seem to understand is how that I/O is operated and where.it seems that OUT(+A11) is only SCAN ADV and IN is only ID1-3.Code:ICn(A14-8) (A15 = enable)6543210 IEEE 488 (605-22 of manual)-11--1- response register1-11--- control register-1-1--1 software reset1-1---1 status register1-1--1- data register6543210 Bit Serial (606-20 of manual)1-1---1 STATIN1-1--1- DATIN-11-1-- COUT1-11--- DATOUTA d7 a 1B d6 b 13C d5 c 10D d4 d 8E d3 e 7F d2 f 2G d1 g 11H d0 dp 9ram:015e 21 ec 3e LD HL,0x3eecram:0161 11 f6 3e LD DE,0x3ef6ram:3c9a 1234567890bCdEFAHL-(6 bytes)ram:3eec HI-5.0.6ram:3ef6 HI-6.0.7OTSeems that back in the day when this Fluke was introduced others had different meters.I had 2, kaise SK-300 and Simpson 461.kaise is still here but unfortunately Simpson is MIA.

author: Roman oh
author_rank: Regular Contributor
timestamp: February 14, 2021, 01:16:44 pm
content: Quote from: m k on Yesterday at 10:06:59 amWonky vision may have had issues.Code: ICn(A14-8) (A15 = enable)6543210---111- ohms converter---1-11 current shunts? IEEE 4886543210 20mA current loop1-1---1 status in1-1--1- data in1-11--- data out-11-1-- continue (D7 -> _INT)6543210 parallel interface-1-1--1 data out-1-1-1- control out-1-11-- D7 ->1-1---1 data in1-1--1- control in1-1-1-- module status (GND -> _INT)6543210 external trigger111----65432101----11 keyboard-1---11 display--11--1 signal conditioner--11-1- A9 active filter--111-- A10A2 Fast RR A/D converter--_+11---1--11 A11A1 attenuatorThe universe of possible options that were available as separate plug-in cards (that could be present on the system bus) are:Option Description01 AC/DC Converter - Averaging (model 8505A only, mutually exclusive with option 09)02 Ohms Converter03 Current Shunts05 IEEE-488 Interface (Options 5, 6, 7 are mutually exclusive)06 Bit Serial Asynchronous Interface (Options 5, 6, 7 are mutually exclusive)07 Parallel Interface (Options 5, 6, 7 are mutually exclusive)08 Isolator (standard)09 AC/DC Converter - RMS (model 8505A only, mutually exclusive with option 01)0A Thermal RMS Converter (model 8506A only, standard)Guys,It took me a couple of hours of circuit analysis to come up with this ICn table that mk generated. I think I got the same answer, and also partially traced IEEE488 but sadly the schematics don't identify the functions involved so the best I have is the IC pin numbers on my version of the schematic6543210-11--1- U12-61-11--- U12-10-1-1--1 U13-61-1---1 U13-91-1--1- U13-10Did you (m k) generate this the long way, as I did, or do you have a clever tool or some other information? And is wonky vision a Thing?And (for SilverSolder) where did your Option List come from? Is that in one of the manuals somewhere?

author: SilverSolder
author_rank: Super Contributor
timestamp: February 14, 2021, 04:00:22 pm
content: Quote from: Roman oh on February 14, 2021, 12:58:42 pmThe only way I know is to quote the whole thing, then break it up withCode: ... BBCodes.Quote from: Roman oh on February 14, 2021, 12:58:42 pmI think I may have been the OP of the other thread, if we are talking about the same one.Yes, I'd also be interested to see a diff between the various versions, but without understanding the basics of what is going on in there, I left that for another day!Also, it would be fun to try to make a new release!I compiled the option list by looking in both the 8505A and 8506A manuals.

author: SilverSolder
author_rank: Super Contributor
timestamp: February 14, 2021, 04:25:19 pm
content: Quote from: m k on February 14, 2021, 01:01:03 pmAh, I didn't realize. I've never seen a Bit Serial card, in my defense!QuoteYes, they are the same card and are standard.QuoteBack in the day, I think I had a Radio Shack analog meter!These Flukes cost as much as a car back then... I wouldn't even have known they existed!

author: m k
author_rank: Super Contributor
timestamp: February 15, 2021, 10:50:09 am
content: At the very right of Ghidra CodeBrowser window are small markings.Red ones seems to be something the browser doesn't like.My version was missing opcode 0xAE, XOR (HL).Ghidra\Prosessors\8085\data\languages has a file 8085.slaspecI added there a middle XRA part from below.Something else should probably be added also but I have absolutely no glue what it could be.Code::XRI imm8 is op0_8=0xee; imm8 {AC_flag = 0;CY_flag = 0;P_flag = 0;A = A ^ imm8;setResultFlags(A);}:XRA (HL) is op0_8=0xae & HL {AC_flag = 0;CY_flag = 0;P_flag = 0;A = A ^ *:1 HL;setResultFlags(A);}:CMP reg0_3 is op6_2=0x2 & bits3_3=0x7 & reg0_3 {setSubtractFlags(A,reg0_3);cmp:1 = A - reg0_3;setResultFlags(cmp);}Quote from: Roman oh on February 14, 2021, 01:16:44 pmOld way with market binocular enhanced pair of tomato samples.It is not helping much eighter that manual has all circuit sheets divided in three pages.

author: Roman oh
author_rank: Regular Contributor
timestamp: February 15, 2021, 12:47:42 pm
content: Quote from m k:One thing I don't seem to understand is how that I/O is operated and where.it seems that OUT(+A11) is only SCAN ADV and IN is only ID1-3.Code: ICn(A14-8) (A15 = enable)6543210 IEEE 488 (605-22 of manual)-11--1- response register1-11--- control register-1-1--1 software reset1-1---1 status register1-1--1- data register6543210 Bit Serial (606-20 of manual)1-1---1 STATIN1-1--1- DATIN-11-1-- COUT1-11--- DATOUTA d7 a 1B d6 b 13C d5 c 10D d4 d 8E d3 e 7F d2 f 2G d1 g 11H d0 dp 9I note references by you to to pages (605-22, 606-20) in "the manual". These pages don't appear in any 8505/8506 manuals that I have. 605-14 is the last page (schematic) of the IEEE488 section that I can find. Can you tell me where there is a better manual?And it's not clear to me what the little table at the bottom of the above quote means....

author: SilverSolder
author_rank: Super Contributor
timestamp: February 15, 2021, 01:53:03 pm
content: The "newest" manual I know of is this one, it is from 91 or so:https://xdevs.com/doc/Fluke/8505A/Manuals/fluke_8505a_multimeter_sm.pdfIt sounds like the page numbering scheme fits this version?Don't forget the errata at the end of the manual, there are some pretty big changes (DC signal conditioner completely new circuit, among other things).

author: m k
author_rank: Super Contributor
timestamp: February 15, 2021, 06:39:14 pm
content: Dang, I was using Mar-83 8506A manual from electrotanya.I was also sure that Bit Serial U9 is something internally numbered.Can't say I'm familiar with that chip.Code:6543210--11001 DC signal Conditioner--1-1-1 AC RMS ConverterNew Ohms Converter is different, old manual is also missing or misplaced the left part of its schematics.New model uses IC4-0 through a logic array.Emulating with Z80 emulator with i8080 code.ram:0147 cd 85 05 CALL FUN_ram_0585is not returning.When call happens A = 3 and 0x400f = 0.Code:ram:0585 21 0f 40 LXI HL,0x400fram:0588 86 ADD (HL=>DAT_ram_400f)LAB_ram_0589 XREF: ram:058a(j)ram:0589 be CMP (HL=>DAT_ram_400f)ram:058a c2 89 05 JNZ LAB_ram_0589ram:058d c9 RETQuote from: Roman oh on February 15, 2021, 12:47:42 pmAccess of 7-segment 5082-7651, new manual has a bit more difficult type.

author: SilverSolder
author_rank: Super Contributor
timestamp: February 15, 2021, 06:51:42 pm
content: All the different modules from the different years are still compatible with each other, based on getting away with swapping them freely between the different units.The first thing seen on the display when the meter is switched on is "HI - 5.0.6" (depending on version number) - I can't figure out where that happens!

author: Roman oh
author_rank: Regular Contributor
timestamp: February 16, 2021, 02:49:23 am
content: Quote from mk:Dang, I was using Mar-83 8506A manual from electrotanya.Ooops, my oversight... I didn't read the text of my manual clearly enough. The data is indeed in my manual but I was looking for PAGE 605-22 instead of PARA 605-22. Might have been late at nightThanks

author: m k
author_rank: Super Contributor
timestamp: February 16, 2021, 05:49:54 pm
content: I should get a bigger screen.Quote from: SilverSolder on February 15, 2021, 06:51:42 pmSloppy description from me.Their module selection gates are different.QuoteSame here.0x1c09 it could be.These things are very time consuming, specially this.Following anything is also very difficult without the actual device.One should connect an analyzing thing of some sort.0x0788 copies greetings text to RAM area 0x4042, but in every other location.0xc3 keyboard data0xa3 display dataX(extras)0xa2 display dataN(numbers*6+1)0xa1 display/keyboard addressChips are rising edge, means that latching is happening when address is dropped, happens shortly by _DBIN and WAIT.When display dataX is dropped it enables display dataN and combined address if d7 was 0.When combined address is dropped it flips in new d7.Other stuff.0x0720 moves ascii 8506A0x072d reads an 8bit HW address and ascii byte, finally DFC123-56789A0x125f seems to be some accepted ascii inputs.

author: SilverSolder
author_rank: Super Contributor
timestamp: February 16, 2021, 06:06:39 pm
content: I actually found a MIS-7191K test controller card... but unable to find any kind of documentation for it whatsoever!It looks like it might be able to stop execution by suppressing ACKs on the bus - maybe it can do other things!

author: SilverSolder
author_rank: Super Contributor
timestamp: February 16, 2021, 06:11:49 pm
content: Quote from: m k on February 16, 2021, 05:49:54 pmGPIB command processing? - it should accept single and two character commands like R2, S3, ?, and so on

author: SilverSolder
author_rank: Super Contributor
timestamp: February 16, 2021, 07:44:18 pm
content: It seems all the external cards are on a 7 bit address bus, taken from A8..A14:I guess that means only the high byte of a 16 bit address actually matters, when it comes to I/O off the controller card? - I should have looked at the diagram before looking at the code!

author: m k
author_rank: Super Contributor
timestamp: February 17, 2021, 11:50:42 am
content: Yes,first line of those earlier bit masks try to explain that.It's also incomplete addressing, only set bits are checked.Those few new modules from new manual have first gates where few zero bits are also checked.Quote from: SilverSolder on February 16, 2021, 06:11:49 pmI have tried those but they have evaded, though there are stuff that are almost.Maybe it's this not very usual hardware doing its tricks.Maybe there are no data+data but something like address+data, or addr+addr+data.Hugging 7-segments!Front panel addresses, 0 = active.Code:d U3 U U6 11 10 V 4 345 13 12 U 5 124 14 15 T 6 133 6 7 S 72 4 5 W 81 3 2 X 90 R 10Data 0x4042 7 pairs, segment data + address, U4-10.My Ghidra listing has two reds.Jump to RAM is explained earlier and jumping to the middle of a cammand is also fine.The function 0x23b7 has two entry points, first has A = 0x80 and second has A = 0.Register B value from the beginning is not used.Address 0x23b9+1 is XRA A, can that be a memory optimization by a historical compiler.If so can it be recognized?That test board is so seventies

author: m k
author_rank: Super Contributor
timestamp: February 18, 2021, 06:55:48 pm
content: It seems that there are mostly always more than one operation happening, or code has a possible addon upgrade included.It also seems that some calls are from stack.183a2a '*' RST723 '#'2f '/'25 '%'Is it accpted that above is GPIB?

author: SilverSolder
author_rank: Super Contributor
timestamp: February 18, 2021, 08:45:46 pm
content: Quote from: m k on February 18, 2021, 06:55:48 pmI think you are on to something! Those are a list of GPIB commands.'*' - Perform a reset'#' - Go to Local mode (lock out Remote)'/' - Toggles between 8 and 16 bit mode, for the Duplex Parallel Interface (option 7)'%' - Halt: Any reading or recall value commanded (but not yet returned) can be discarded by sending the halt (%)commandAnother interesting remote command is theHigh Speed Reading Mode.'!' - Enter simplified high speed reading mode where the instrument runs in a tight loop: - read the ADC and transmit the reading as a 3 byte code, as fast as it can. (Apparently, 500 readings per second is possible in this mode - the instrument literally only does I/O... it could be interesting to find the code that does it, since it is likely to be as simple and fast as possible!).

author: Roman oh
author_rank: Regular Contributor
timestamp: February 20, 2021, 12:41:13 pm
content: Quote from: SilverSolder on February 16, 2021, 06:06:39 pmWow! How does one "actually find" a hen's tooth? Dumpster Dive? Old bloke next door used to work for Fluke and had a yard sale? Or just been sitting in my shed for years and can't remember where it came from?I suspect that this is of most use in debugging the instrument hardware - ie, force a particular state (IC0-IC6) onto a peripheral card, and examine the response, rather than track the CPU execution itself. But still a cool thing to have.

author: SilverSolder
author_rank: Super Contributor
timestamp: February 20, 2021, 01:31:35 pm
content: Quote from: Roman oh on February 20, 2021, 12:41:13 pmYou can find all kinds of weird stuff on eBay!QuoteThere are four test modules mentioned in the manual:Extender Card Fluke Model MIS-7011KBus Monitor Fluke Model MIS-7013KStatic Controller Fluke Model MIS-7190KTest Module Fluke Model MIS-7191K"Test Module" is wonderfully vague! - I would have thought the "Static Controller" is the one to exercise the non-controller hardware, and the "Test Module" can perhaps pretend to be any of the other modules, letting you manually control the communication with the controller? - will need to play around with it some more!

author: SilverSolder
author_rank: Super Contributor
timestamp: February 20, 2021, 05:31:19 pm
content: Is there a way to single step the 8080 in the actual device, by adding some (hopefully minimal) amount of hardware?

author: SilverSolder
author_rank: Super Contributor
timestamp: February 20, 2021, 07:52:19 pm
content: Annotated IEEE-488 piggyback board schematic attached.

author: m k
author_rank: Super Contributor
timestamp: February 21, 2021, 12:06:57 pm
content: What kind of messages are displayed?I know the normal one, greetings text and partial modules found text, starting with C.What kind ofs are error messages?Is text "Error" displayes and so on.Somewhere is said that '?' is displayed, what it look like?When is sign in front of exponent displayed, is it with exponent only?What device specific messages are outputted?I know the one with "8505 :" but are there others.

author: SilverSolder
author_rank: Super Contributor
timestamp: February 21, 2021, 05:24:51 pm
content: Quote from: m k on February 21, 2021, 12:06:57 pmThere are actually very few textual messages. I have edited the manual's explanations so they are easier to understand if you don't have the hardware:1) There is the "HI-5.0.6" version number at start, that goes away after a short time. (around one second, maybe less)2) Then there is the installed module scan. If a module is missing, its corresponding number will be replaced by a space in the array of presumably hex digits. This also remains displayed for about one second.3) Then there are some "momentary error messages" that are recoverable without a reset:Error 0Attempt to set zero in wrong function (not V DC or OHMS) or an overrange has been entered.Error 1"Store" function attempted during overload condition. Change to higher range or (if storing cal correction factors) use lower value source.Error 6Display overflow. Check offset and scaling values.Error 7External Reference - voltage on one input exceeds 20V dc.Error 8Controller module is faulty. Replace controller module.Error bIllegal push button sequence in Calibration mode.Error CInvalid push-button sequence, or illegal value entered.Error dCalibration Memory faulty or not installed. Occurs when storing into, or recalling from, Calibration Memory, or at power-up. Replace or install Calibration Memory chip.Error FCal Memory check-sum problem. Restart the meter. If necessary, reprogram Cal Memory. Replacement of Calibration Memory may be required.Error HOhms connection problem. Verify that all connections are proper. Check input fuses. Check input lead polarity in four terminal connections.4) Finally there are the "latching error messages" that are unrecoverable, the meter has to be powered down:Error(No error ID) System error, usually appears at power-up or reset. Repeat power-up or reset.Error 2Filter module faulty or not installed.Error 3DC Signal Conditioner module faulty or not installed.Error 4OHMS, A DC, or A AC error. Applicable module may be faulty or not installed. Check for bad input level.Error 5Analog to Digital Converter Module error.Error 9Function selection error. The function module selected is faulty or not installed. V DC problem causes Error 3.Error EMore than one type of ac converter, or the wrong type of ac converter for the instrument, is installed. Also appears when a Calibration Memory module from an 8502A is installed (it should not be installed in 8505A 0r 8506A which have calibration EPROM in the controller itself)

author: Roman oh
author_rank: Regular Contributor
timestamp: February 22, 2021, 12:17:33 am
content: Quote from: SilverSolder on February 20, 2021, 05:31:19 pmYou presumably saw my post in the other thread, about simulation of the software. Single stepping? There lies madnessThe thing executes in excess of 100K instructions (lots of loops, of course) just in the first few throes of initialisation!

author: SilverSolder
author_rank: Super Contributor
timestamp: February 22, 2021, 12:27:18 am
content: Quote from: Roman oh on February 22, 2021, 12:17:33 amOne could look for a certain combination of address and data, and halt on that? Just an Arduino that sits and sniffs the bus could probably keep up with most of what an 8080 is trying to do?I'm just not sure if an 8080 can be stopped, once it gets going!

author: m k
author_rank: Super Contributor
timestamp: February 27, 2021, 07:05:27 pm
content: Is the machine asking "YES?" anytime?Is it telling "Err. on" any other time?

author: SilverSolder
author_rank: Super Contributor
timestamp: February 28, 2021, 02:26:30 am
content: Quote from: m k on February 27, 2021, 07:05:27 pmYes, it does ask when entering some parameters after pushing some of the controls on the front - it can say a few other very short things.For example, to display the High PEAK value in PEAK mode, you press a sequence of buttons as follows:BUTTON DISPLAY<RECALL> "?" (including the quotes! using a 7 segment display, it does look a little crude)<HI> YES?<PEAK> (displays the actual value)

author: m k
author_rank: Super Contributor
timestamp: February 28, 2021, 06:37:18 pm
content: I think I've now got mostly all possible texts.Am I missing something?1234567890bCdEFAHL-HI-5.0.6HI-6.0.7r100r300r 1r 3r 10r 30r100r500Err. onErr. oFErrorCLEAr?YES?PASS"?"HILOI've also made a disassembler and ignoring memory orientation seems to give more reasonable listing.Means that code is listed when it is accessed.It has few bugs though, one is legendary, it can save but load is garbage.

author: SilverSolder
author_rank: Super Contributor
timestamp: February 28, 2021, 08:56:01 pm
content: Quote from: m k on February 28, 2021, 06:37:18 pmThat is pretty cool - looks like resistance is futile!I guess 8080 disassemblers don't grow on trees these days?1234567890bCdEFAHL- List of valid alphanumerics, maybe array indexed? maybe for errors and to identify options on bootHI-5.0.6 Version number for 8505aHI-6.0.7 Version number for 8506ar100 100mVAC range (-3 in exponent display) (8506a only)r300 300mVAC range (-3 in exponent display) (8506a only)r 1 1VAC range (8506a only)r 3 3VAC range (8506a only)r 10 10VAC range (8506a only)r 30 30VAC range (8506a only)r100 100VAC range (8506a only)r500 500VAC range (8506a only)Err. on Latching errors enabled (during calibration)Err. oF (should have 2Fs?) Latching errors disabled (during calibration)Error Can occur by itself but usually followed by an alphanumericCLEAr? Displayed when confirming clearing of stored cal constants (during calibration)YES? Used when recalling HI or LO peakPASS In LIMITS mode, display indicates HI, LO, PASS instead of a numeric value"?" Prompt whenever STORE or RECALL button is pressed on panel. (Asking e.g. "Store what?")HI Used with LIMITS mode, and PEAK modeLO Used with LIMITS mode, and PEAK mode

author: m k
author_rank: Super Contributor
timestamp: March 02, 2021, 04:01:55 pm
content: Many Z80 thingies can do 8080 or 8085 stuff, emulating also, but finally something is always missing.Since 7-segmant is a bit slow to check I did a viewer.(Win32)It's also quite good for repetitions.It only reads first 65k but can be extended if needed.

author: SilverSolder
author_rank: Super Contributor
timestamp: March 02, 2021, 04:20:34 pm
content: Quote from: m k on March 02, 2021, 04:01:55 pmThat is super nifty tool! What address did you find the display strings at?

author: m k
author_rank: Super Contributor
timestamp: March 02, 2021, 07:41:42 pm
content: From 506_607.bin3c9a 1234567890bCdEFAHL-3eec HI-5.0.63ef6 HI-6.0.73f46 r1003f4c r3003f52 r 13f58 r 33f5e r 103f64 r 303f6a r1003f70 r500304f Err. on3df8 Err. oF3bd1 Error3cf9 CLEAr?3ad0 YES?3b00 PASS3bd8 "?"3b06 HI3b0c LO

author: m k
author_rank: Super Contributor
timestamp: March 03, 2021, 07:29:24 pm
content: I already started seeing those 7-segments directly from hex.New viewer version, minor changes.Now upper right follows upper left checks.No idea how that 4-segment(?) part is coded.Educated guess says that 0x80 is a like with 7-segment.Texts are clearly 6 wide.Maybe it would be better to start from earlier model.8500A seems to be 5,5 digits.What is the first wider one, 8502A?

author: SilverSolder
author_rank: Super Contributor
timestamp: March 03, 2021, 09:17:39 pm
content: 8505A is 6.5 digs (has a 7.5dig averaging mode)8506A is the same

author: dietert1
author_rank: Super Contributor
timestamp: March 09, 2021, 09:26:40 am
content: Finally i noticed that backplane address lines IC0..IC6 are inverted from the 8080A address bus. Backplane addressing in the disassembly looks like..MVI H,0E5H ;backplane addressMOV M,A ;write A to hardware register..This operates the active filter module at backplane address 1A. Another example: After power-on front panel operations are in the sequence of six writes at 23, 22, 21,23, 22, 21 and finally a read at 43. In the firmware those adresses are coded as DC, DD, DE and BC. Now it makes a little more sense.Regards, Dieter

author: SilverSolder
author_rank: Super Contributor
timestamp: March 09, 2021, 12:52:20 pm
content: Quote from: dietert1 on March 09, 2021, 09:26:40 amThat was a good catch! The outlines of a programming model is beginning to emerge from the fog!

author: m k
author_rank: Super Contributor
timestamp: March 09, 2021, 06:13:48 pm
content: Since hex coding, even 8080, is a pain I did a simple assembler inside the emulator.Then when testing it I lost some time again.The test code was from "Radio Shack" manual page 178.I didn't realise my Adobe Reader DC does OCR trace on the fly by default.(few characters didn't match)Emulator generally is not totally insane.At least it put "Error" to display memory area, no wonder, without a HW map.A bit different what an old Z80 emulator did, maybe there are some nuances, like always so no AC flag.

author: SilverSolder
author_rank: Super Contributor
timestamp: March 09, 2021, 06:33:06 pm
content: Quote from: m k on March 09, 2021, 06:13:48 pmThat sounds pretty amazing! - The code scans the installed option cards on boot, the controller might give up if basic parts are missing, like the A/D converter?

author: m k
author_rank: Super Contributor
timestamp: March 10, 2021, 12:49:16 pm
content: Quote from: dietert1 on March 09, 2021, 09:26:40 amYes,the chip is regular(14001) NOR.Many things are active low.It seems to be also a norm that drawn part is a priority.Like front panel, where address lines in and out of the chip are not parallel in picture.It's also nesessary to check all.Like Isolator, where IC4 has double meaning, part of Isolator address and IC4-7 as 0xF clocking ID0 as _INT, and ID1 if INA.

author: m k
author_rank: Super Contributor
timestamp: March 19, 2021, 07:32:18 pm
content: If making a disassembler took few hours and assembler twice of that the emulator is a bit different.Then, unluckily, didn't remember, I also thought that adding a flag for 8085 is a nice addendum.Anyway, what is the absolute minimum configuration that is showing some life on screen, is it already stated somewhere?Should the emulator treat stuff like XTHL as potential external data exchange?(quite theoretical IMO, not here anyway)

author: dietert1
author_rank: Super Contributor
timestamp: March 20, 2021, 08:52:54 am
content: I think it's not a matter of hours. Look at this video what they used in the past:One of those units appeared on ebay, but i thought i don't want to get into this. Also i'm a bit tired of the logic analyzer work.So i made a STM32 board with a backplane interface, based on a Nucleo-32 STM32F303. It has 4 KByte of single cycle SRAM and 64K Flash and runs up to 72 MHz. Some of its ports are 5V tolerant, others need a level shifter. It's not yet complete.First i thought i want a sniffer to log all backplane cycles over USB. Then i added two 374 bus registers to let it drive the bus, too. It can also be a backplane slave module or even the controller. Then i thought i can put the 8080A binary into it and implement the simulator i have been using under Win32. I mean it runs circles around a 8080A and one will need delay loops to get a similar instruction timing to the 8080A. For me this is low priority, more or less a fun exercise.Regards, Dieter

author: SilverSolder
author_rank: Super Contributor
timestamp: March 20, 2021, 08:53:16 pm
content: Quote from: dietert1 on March 20, 2021, 08:52:54 amThat looks crazy cool!Step 1 in replacing the entire controller board with a new CPU!Can that board be programmed in the Arduino environment?

author: dietert1
author_rank: Super Contributor
timestamp: March 20, 2021, 10:01:15 pm
content: Yes, there seems to be support here:https://github.com/stm32duinoandhttps://www.stm32duino.com/As far as i know, that was initiated by a freelancer and is now maintained by STM. I think they have board files for the Nucleo-32 boards, that are all very similar.Regards, Dieter

author: peter-h
author_rank: Super Contributor
timestamp: March 22, 2021, 10:21:54 am
content: I have not done disassembly for many years but the general rule used to be that you do a hex dump first to visually identify any text, and you feed that to the disassembler as exclusions.This is vital because 8080/Z80 opcodes often look like text. In fact an old trick was to execute the copyright message so if somebody changed it, some register would end up with the wrong valueThere were loads of very clever disassemblers around in the old days. Always multiple passes.

author: dietert1
author_rank: Super Contributor
timestamp: March 22, 2021, 11:54:19 am
content: The 8502A/8505/6A binaries we have been looking at are well obfuscated. For example they store strings as 7-segment display bytes instead of ASCII. Somebody made a special viewer already to discover those texts. For the GPIB commands these instruments use single character codes that are immediately fed into a large computed goto, so there are no command strings to discover, either. They run small parts of the firmware from RAM copies. They push return addresses to stack by hand in an effort to reuse code and so on and so on. Hacker work at its best, full of surprising ideas.The 8502A firmware i looked at has about 12 KBytes of code and about 1 KByte of constants, for example those jump tables for the computed goto. I used an open-source disassembler from Adam Thompsonhttps://hackeradam.com/lets-write-a-simple-disassembler-for-the-intel-8080-microprocessor/that i debugged and adapted a bit.Regards, Dieter

author: SilverSolder
author_rank: Super Contributor
timestamp: March 22, 2021, 01:35:13 pm
content: Wonder how much is intentional obfuscation, and how much is the result of trying to cram as much as possible into the available space? - The design may date as far back as the late 70's, where 16K of program space might have been eye-bleedingly expensive?

author: m k
author_rank: Super Contributor
timestamp: March 23, 2021, 02:21:25 pm
content: This RAM code seems to be a calculation adjustment thing.It also seems to be an addendum.Maybe measurement corrections of earlier version are done with fixed tables.

author: SilverSolder
author_rank: Super Contributor
timestamp: March 23, 2021, 04:36:55 pm
content: Could this be where the calibration constants are applied?I like the way you listed the code in Excel like that, makes it easier to see what is going on.We should have column-editors for all programming languages!

author: dietert1
author_rank: Super Contributor
timestamp: March 25, 2021, 07:58:51 am
content: Here i have a measurement of the external trigger timing. Three signals are taken from the non-isolated side of the isolation module: INT, ACK* and X Trigger signal. The rising edge of the external trigger sets the interrupt. On average interrupt handling takes about 54 usec. There are two ACK cycles from the isolator, first the INA cycle, then a cycle with IC=0x70. Statistics and histogram are included. Difference between min and max handling time is about 15 usec.In external trigger mode the display of the 8502A blanks. With standard data format, the maximum trigger rate is about 40 Hz. It requires reading from the communication interface, otherwise the instrument stops taking data and ignores external trigger signals. One cannot simply use a backplane sniffer to get the ADC results via USB, in order to save the delay by GPIB communication. That won't work.Regards, Dieter

author: m k
author_rank: Super Contributor
timestamp: March 27, 2021, 07:14:33 pm
content: Inverting things continue.Hardware addressing is partially exclusive.Addresses E5h and E6h are front panel only, zero at 18h is an exclusion part.Then ECh has 03h as exclusion part, where it is excluding front panel and including parallel(ACh) interface something.Ohms converter and Current shunts are also possible for E*h but not without low bits.Somewhere was that Isolator can be less than F*h also, maybe that is the reason.(Edit: no, it was something else)The very firstMVI H, 0xC0MVI (HL), 0xFFis resetting everything.Nothing is answering there but all HW gates go to off position.Something for later use.506_607 file has a program check at 180h and it adds the whole code.Other versions are possibly similar.In case the code must be changed do it so that the operation is not changing, the result is possibly used later.Something like0x0180 21 00 00 LXI HL, 0x40000x0183 3E 00 MVI A, 0x00 ; original result0x0185 C3 92 01 JMP 0x01920x0188 00 NOP ; free bytes...0x0191 00 NOP0x0192 F5 PUSH AF

author: m k
author_rank: Super Contributor
timestamp: March 29, 2021, 05:38:16 pm
content: Wrong,and how long since I commented it my self.Some(much more) time lost again but totally own fault this time.So address E3h is IC4+IC3+IC2 and nothing to do with the front panel or the Isolator.(like dietert1 said)First front panel access is later and addresses are DCh, DDh and DEh.And small correction to resetting thing.Only unguarded side of gates are reset.Isolator is not moving that to the other(King Willie) side.0x421D "8505A DFC123-56789A",0result after sending FFh to HW addressessource 0746h("EEPROM" = 00)0x4234 8 * (5bytes from EEPROM + 88h + (10h - 17h))0x426C 5 * (5bytes from EEPROM + 88h + (0 - 4))loaded backwards from 49FEh49FFh is first tested for 55h0x40A7 (7seg)C1235679Ahard coded skip for '4' and hard coded change from '8' to '9'separately added 'A'

author: SilverSolder
author_rank: Super Contributor
timestamp: March 29, 2021, 10:55:05 pm
content: Quote from: m k on March 29, 2021, 05:38:16 pmThis looks like the part where it displays the installed modules (the second thing that happens during boot).Out of the string 'C1235679A', the non-installed modules are blanked out. I'll take a picture of the display so you can see what I mean...

author: SilverSolder
author_rank: Super Contributor
timestamp: April 01, 2021, 12:38:48 am
content: 8505A and 8506A installed modules display during boot:

author: m k
author_rank: Super Contributor
timestamp: April 01, 2021, 06:17:19 pm
content: Very good!The use of that last digit of main display was still a bit fuzzy, not any more.There also seems to be a double led use of two of those led bars.(page 285/323 of new 8505A manual)U26 and U24 pins 5 and 16, when other pairs have opposite parities.I have to get those HW addresses coded to the emulator.Now it has all possible things "installed", not very practical.Normally the control rolls around 400Fh when it's waiting interrupts happening.Somewhere is also a place jumping to it self, if memory serves.Some kind of a hibernation or wait mode is also present.Maybe it has been pointed out already somewhere.Code:0x087D 3A 10 40 LDA (0x4010)0x0880 B7 ORA A0x0881 C8 RZ0x0882 CD 8E 00 CALL 0x008E ; OUT 0x400x0885 76 HLT0x0886 C3 7D 08 JMP 0x087DIf interrupt(releasing halt) is returning without resetting 4010h it's halted again in no time.Those calibration things.Earlier RAM code seems to be Hex but EEPROM could be BCD.Many data parts are 5 bytes long and0x20BA 80 19 99 99What is this 2A34h then?Jump to (3A17h + 12(bitC) + 2L)Maybe it's totally practical after all.Code:0x2A34 79 MOV A, C0x2A35 06 FF MVI B, 0xFF0x2A37 04 INR B0x2A38 1F RAR0x2A39 D2 37 2A JNC 0x2A370x2A3C 78 MOV A, B0x2A3D 87 ADD A0x2A3E 87 ADD A0x2A3F 47 MOV B, A0x2A40 87 ADD A0x2A41 80 ADD B0x2A42 85 ADD L0x2A43 85 ADD L0x2A44 2A 0E 41 LHLD (0x410E)0x2A47 E5 PUSH HL0x2A48 21 17 3A LXI HL, 0x3A170x2A4B 5F MOV E, A0x2A4C 16 00 MVI D, 0x000x2A4E 19 DAD DE0x2A4F 5E MOV E, (HL)0x2A50 23 INX HL0x2A51 56 MOV D, (HL)0x2A52 EB XCHG0x2A53 E9 PCHL ;---------->*

author: dietert1
author_rank: Super Contributor
timestamp: April 01, 2021, 08:55:41 pm
content: I think that is a computed call via a jump table at 3A17 (array of short). The return address comes from 410E and gets pushed by hand. Actually there seem to be several jump tables indexed by B, each one with 6 destination addresses of 2 bytes. So B gets multiplied by 12 and L gets multiplied by 2.Regards, DieterPS: The 8502A V3.0.0 has the same code at 205C and the code "MOV A, C" you start with is not an entry point. The jump table is at 2D1B and has a total of 36 destinations.

author: m k
author_rank: Super Contributor
timestamp: April 10, 2021, 04:59:55 pm
content: Real entry point(293Dh) is far away.I'd say too far for the purpose.Though one could also say that 2A15h is more of an entry point sinceCode:0x2A15 31 00 48 LXI SP, 0x48000x2A18 AF XRA A0x2A19 3A B6 41 LDA (0x41B6)0x2A1C B7 ORA A0x2A1D C5 PUSH BC0x2A1E E5 PUSH HL0x2A1F C4 54 2A CNZ 0x2A540x2A22 E1 POP HL0x2A23 C1 POP BC0x2A24 AF XRA ABut it's not called from out of this section.First XRA is not needed so maybe this is an updated part.Or maybe it's just a programmers habit.In that section isCode:0x2963 2C INR L0x2964 3E 61 MVI A, 0x610x2966 BD CMP L0x2967 C0 RNZ0x2968 2E 55 MVI L, 0x550x296A C9 RETFirst thought was that it's some sort of a calculation thing but it's just a simple data area limiter.That ASCII 'a' just happened to be there.Personally I wouldn't trust my self so much, I'd use RNC for return.Some interrupt stuff.I've missed the MarkINT(A14 + OUT + 8xFLine),It's vector (manual page 297/323) is U21 pin 11 and D1 so 08h and RST1.But it needs A14 with OUT so for pretty long time I just couldn't understand when that happens.I've also found a polarity error in front panel stuff so no help from there.Luckily I spotted a phrase "the port number is duplicated on the address bus" p97/224 of RS $3.95 manual.So OUT 40h is actually OUT 4040h and use of A14 is perfectly clear.For Scan Adv I've messed with polarities all by my self but OUT 48h actually being OUT 4848h make the use of A11 also clear.Has this U18 and its Alt. jumper being an argumental center earlier?Maybe it was a different hardware.INAID1 (D4, 10h, RST2) Ext TriggerID2 (D4-3, 18h, RST3) Bit Serial, ParallelID3 (D5, 20h, RST4) IEEE-1488ACK (U21 D6) is D5-4, 30h, RST6.MARKINT (U21 D1) is D1, 08h, RST1.Below should be everything related to RST instructions.Code:0x00B4 21 F8 0B LXI HL, 0x0BF80x00B7 22 12 41 SHLD (0x4112) ; RST3 & 4 jump0x00BA 21 FE 0B LXI HL, 0x0BFE0x00BD 22 10 41 SHLD (0x4110) ; RST6 jump0x01E6 21 5F 0B LXI HL, 0x0B5F ; front panel stuff0x01E9 22 10 41 SHLD (0x4110) ; RST6 jump0x0BF8 C1 POP BC0x0BF9 D1 POP DE0x0BFA E1 POP HL0x0BFB F1 POP AF0x0BFC FB EI0x0BFD C9 RET0x0BFE 26 C0 MVI H, 0xC0 ; not MarkINT without0x0C00 36 FF MVI (HL), 0xFF ; rising edge of OUT0x0C02 C3 FA 0B JMP 0x0BFA0x0CF4 21 B4 0D LXI HL, 0x0DB40x0CF7 22 C8 41 SHLD (0x41C8) ; RST5 jump; ...0x0D0E 2A AC 41 LHLD (0x41AC)0x0D11 22 12 41 SHLD (0x4112) ; RST3 & 4 jump0x0DEA 21 FF 0D LXI HL, 0x0DFF0x0DED 22 C8 41 SHLD (0x41C8) ; RST5 jump0x0DF0 21 32 0E LXI HL, 0x0E320x0DF3 22 12 41 SHLD (0x4112) ; RST3 & 4 jump0x0E59 21 7B 1A LXI HL, 0x1A7B0x0E5C 22 C8 41 SHLD (0x41C8) ; RST5 jump0x1371 CD 88 13 CALL 0x13880x1374 78 MOV A, B0x1375 FE 31 CPI 0x310x1377 C2 81 13 JNZ 0x13810x137A 21 B4 0D LXI HL, 0x0DB40x137D 22 C8 41 SHLD (0x41C8) ; RST5 jump0x1380 C9 RET0x1381 21 B5 0D LXI HL, 0x0DB50x1384 22 C8 41 SHLD (0x41C8) ; RST5 jump0x1387 C9 RET0x1388 3A CB 41 LDA (0x41CB) ; RST5 Isolator=FF if 41CBbit00x138B E6 01 ANI 0x010x138D C8 RZ0x138E 3E FF MVI A, 0xFF0x1390 32 CA 41 STA (0x41CA)0x1393 C9 RET0x1394 CD AE 13 CALL 0x13AE ; Isolator=FF if 41CBbit00x1397 AF XRA A0x1398 32 CA 41 STA (0x41CA)0x139B 2F CMA0x139C 32 C8 41 STA (0x41C8) ; RST5 jump0x139F 32 C9 41 STA (0x41C9) ; FFFF (RST7?)0x13A2 C9 RET0x145C 21 99 15 LXI HL, 0x1599 ; inc (400F)0x145F 22 10 41 SHLD (0x4110) ; RST6 jump0x1462 11 40 40 LXI DE, 0x40400x1465 1A LDAX (DE)0x1466 F6 40 ORI 0x40 ; 7th digit?0x1468 12 STAX (DE) ; front or rear0x1469 C9 RET0x158A 26 D3 MVI H, 0xD30x158C 11 98 1A LXI DE, 0x1A980x158F 36 00 MVI (HL), 0x000x1591 EB XCHG0x1592 22 AC 41 SHLD (0x41AC)0x1595 22 12 41 SHLD (0x4112) ; RST3 & 4 jump0x1598 C9 RET0x3117 CD 88 13 CALL 0x1388 ; (41CA)=FF if 41CBbit00x311A 21 00 02 LXI HL, 0x0200 ; 2nd code set0x311D 22 C8 41 SHLD (0x41C8) ; RST5 jump0x3120 21 40 40 LXI HL, 0x40400x3123 7E MOV A, (HL)0x3124 E6 20 ANI 0x200x3126 F5 PUSH AF0x3127 7E MOV A, (HL)0x3128 E6 DF ANI 0xDF0x312A 77 MOV (HL), A0x312B CD 38 29 CALL 0x2938 ; 0 to 4165h0x312E F1 POP AF0x312F 31 00 48 LXI SP, 0x48000x3132 C2 14 02 JNZ 0x02140x3135 CD 66 10 CALL 0x10660x3138 C3 4E 00 JMP 0x004E ; all done, go back; 2nd code set; never called directly by code starting from 00000x0200 CD AE 13 CALL 0x13AE0x0203 31 00 48 LXI SP, 0x48000x0206 CD 52 02 CALL 0x0252 ; clear stuff0x0209 21 14 02 LXI HL, 0x02140x020C E5 PUSH HL0x020D FB EI0x020E CD 66 10 CALL 0x10660x0211 C3 4E 00 JMP 0x004E ; all done, go back0x13AE 3A CB 41 LDA (0x41CB)0x13B1 E6 01 ANI 0x010x13B3 C8 RZ0x13B4 26 8F MVI H, 0x8F0x13B6 3E FF MVI A, 0xFF0x13B8 F3 DI0x13B9 77 MOV (HL), A0x13BA 00 NOP0x13BB FB EI0x13BC C9 RET; RST1; set front panel stuff; depending what is in register H; new SP from 4292h; jump to 1C10h; and much more from there0x1C09 21 00 00 LXI HL, 0x00000x1C0C 39 DAD SP0x1C0D 22 92 42 SHLD (0x4292)0x1C10 26 E3 MVI H, 0xE30x1C12 36 0C MVI (HL), 0x0C; RST2; fill 0Ch pieces of A to 401Ah and up0x0010 11 1A 40 LXI DE, 0x401A0x0013 0E 0C MVI C, 0x0C0x0015 C3 14 22 JMP 0x2214; RST30x0018 F5 PUSH AF0x0019 E5 PUSH HL0x001A D5 PUSH DE0x001B C5 PUSH BC0x001C 2A 12 41 LHLD (0x4112)0x001F E9 PCHL ;---------->*; RST40x0020 F5 PUSH AF0x0021 E5 PUSH HL0x0022 D5 PUSH DE0x0023 C5 PUSH BC0x0024 2A 12 41 LHLD (0x4112)0x0027 E9 PCHL ;---------->*; RST50x0028 CD AE 13 CALL 0x13AE ; Isolator=FF if 41CBbit00x002B 2A C8 41 LHLD (0x41C8)0x002E E9 PCHL ;---------->*; RST60x0030 F5 PUSH AF0x0031 E5 PUSH HL0x0032 2A 10 41 LHLD (0x4110)0x0035 E9 PCHL ;---------->*; RST7; pretty hard start

author: mdubinko
author_rank: Contributor
timestamp: November 16, 2021, 07:50:54 am
content: Hey @SilverSolder and all,I love that folks are looking at this. Wondering if there is any new progress to report. Do you have a repo or wiki somewhere to accumulate community knowledge over time?Has anyone looked at U20 data, which seems to store the calibration information? Understanding the format there might help decipher some of the code.And would there be any benefit in looking at diffs between different versions? That too might give important hints to the structure of the code.

author: SilverSolder
author_rank: Super Contributor
timestamp: November 16, 2021, 10:48:57 pm
content: Quote from: mdubinko on November 16, 2021, 07:50:54 amWelcome to the "crazy corner"!I am not aware of anyone deciphering U20, it may not be a super difficult project? - perhaps, monitor the chip while updating calibration numbers? Another approach might be to look at the firmware and perhaps try to decode where it is accessing U20...

author: mdubinko
author_rank: Contributor
timestamp: November 20, 2021, 12:10:57 am
content: May I suggest setting up a dedicated space for collaboration? I can imagine a wiki working well, but something with revision control might be even better. The more eyeballs, the more shallow the problem of figuring it out.I'd offer my github space if it helps. I already have one extreme niche reverse-assembly project going on there.

author: SilverSolder
author_rank: Super Contributor
timestamp: November 21, 2021, 02:30:00 pm
content: Quote from: mdubinko on November 20, 2021, 12:10:57 amThere are benefits to just keeping it here on the eevblog, the "barrier to entry" is extremely low for forum participants and we can kind of dip in and out, depending on how busy we are.Eventually, these instruments will yield all their secrets to us!

author: m k
author_rank: Super Contributor
timestamp: December 06, 2021, 01:21:09 pm
content: I've not forgotten this.Just had an unusually long period of spare time deprevation, so stuff are pretty much queued.I also have my own 8505A now, fully loaded but otherwise unknown and said to be broken.Possibly one for west murricans also but not sure how ebay would take that.Wouldn't mind eighter if somebody creates a trusted bargain freight for small(ish) packages, it can be slow.Don't know about the barrier.Can't find a thread I was looking yesterday.Maybe I should "RTFM" and use search.