A uPD7810/uPD7811 disassembler is included in MAME.
- Download the complete MAME binaries from http://mamedev.org/
- Run the self-extracting MAME executable file
- Delete all files except unidasm.exe
- Copy unicows.dll into same directory as unidasm.exe (unicows.dll is included in the "QMP" MP3-player, for some bizarre reason unidasm.exe requires this dll, but it is unable to find it when it's located in your MP3-players directory)
- Usage example: To disassemble the CPC printer ROMs, type this at commandline prompt:
- unidasm dmp2000.rom -arch upd7810 -basepc 2000h >dmp2000.txt
- unidasm nlq401.rom -arch upd7810 -basepc 0000h >nlq401.txt
The assembler syntax is rather confusing.
- The opcode names are unneccessarily complicated. For example, instead of using "MOV" for all transfers, there are lots of commands; depending on whether the operands are 8bit or 16bit, registers, immediates, internal or external memory locations, etc.
- Conditionals are pretty unconventional: Unlike as on other CPUs, there are no opcodes like "jump if equal", instead there are opcodes like "compare and if equal then skip next opcode".
The next opcode becomes conditionally executed, aside from conditional jumps, this can be also used with other opcodes, so one can program conditional MOV, OR, AND, CALL, etc.
Altogether it's pretty cool - once when one is familar with it. The "if-then-skip" requires some reverse thinking since humans would tendencially prefer "if-then-execute".
Aside from comparisions there are some other opcodes that set the skip flag, some rotate commands, and decrement commands (where the skip condition is N=-1, not N=0) (to implement a decrement without skip one must put a NOP behind it).
There are two other conditional effects: Some opcodes like "LXI HL,imm16" cause any following "LXI HL,imm16" opcode(s) to be skipped; when used after a compare opcode, this can produce a IF-THEN-ELSE effect; it can be also useful when "in-jumping" into a function. Finally, RETS performs are RET and sets the skip-flag (so the next opcode, at the return address/after the CALL opcode, will be skipped)
Internal ROM and MODE0/MODE1 Pins
The processor exists in two versions: 7810 without internal ROM, and 7811 with 4K internal ROM. Normally, one would obviously use the ROM-less 7810 if one doesn't use the internal ROM. However, for whatever reason, it seems to be quite common to use a 7811 with its internal ROM disabled.
The uPD781x datasheet doesn't contain useful info on how to do this, but the uPD78C1x (CMOS version) datasheet contains at least some fragments on how the MODE0 and MODE1 pins affect internal/external ROM mapping. Judging from that information, the following four combinations seem to be supported:
|LOW||LOW||External ROM, 4K at 0000h..0FFFh (only lower 4bit of Port F used for memory access, upper 4bit can be used as I/O signals)||No hardware known to use this|
|LOW||HIGH||External ROM, 16K at 0000h..3FFFh (only lower 6bit of Port F used for memory access, upper 2bit can be used as I/O signals)||Schneider NLQ401 Printer (uPD7811 with internal ROM disabled)|
|HIGH||LOW||Internal ROM, 4K at 0000h..0FFFh (in this case initialization code in internal ROM can configure Port F for whatever usage by software)||Amstrad DMP2000/DMP3000 Printers (uPD7811 with internal ROM enabled)|
|HIGH||HIGH||External ROM, 63.75K at 0000h..FEFFh (all 8bit of Port F used as memory address)||Amstrad DMP3160 (with ROM-less uPD7810), Roland TR-909 Drumcomputer (uPD7811 with internal ROM disabled)|
Examples for hardware that uses a uPD7811 with its internal ROM disabled: Schneider NLQ401 printer, Roland TR-909 Drumcomputer. Reportedly it can also happen that dealers are shipping uPD7811 chips when one has ordered uPD7810 chips. Unknown why that is happening (possibly the chips might do contain BIOSes that turned out to contain software bugs, or that were produced in too high quantities).