5 ms·
I was wondering about the registers, why not use the "standard" mapping for BC/DE/HL => CX/DX/BX, and DI for A? One disadvantage of this would be you have to "
by rep_lodsb 3y ago
I was wondering about the registers, why not use the "standard" mapping for BC/DE/HL => CX/DX/BX, and DI for A?
One disadvantage of this would be you have to "xchg ax,di" before and after every accumulator op, but that is a single byte opcode (and on the 8088, instruction fetch is the main bottleneck). Just from intuition, it seems like for common code sequences like "MOV D,H ! MOV E,L", having the byte registers directly addressable would be a win. But maybe you profiled how common the various instructions are in real code?
>Amusingly, getting this emulator going today would involve running another emulator to emulate this first iteration of the now venerable x86 architecture.
Not necessarily. Modern x86 CPUs running in 64-bit mode still support 16-bit code/data segments (the only thing not supported is 64 bit OS + V86 mode, and you don't need that for 8080 emulation). At least on Linux, this is made available to userspace via the modify_ldt syscall.
Of course, when you have 16-bit code and a CP/M emulator, might as well also make it run CP/M-86 programs (most of which do not use the kind of segment arithmetic that would require V86 mode). Then the 8080 CPU emulator would be just another code segment, and probably the easier part to write, compared to the code necessary to emulate the CP/M filesystem on Linux.
- billforsternz 3y agoGood question and extra information, thanks. I wasn't aware of 16 bit code/data segments on 64 bit x86 CPUs. I don't think I seriously considered using di for A (I've sort of started using a convention of lower case = 8086 registers, upper case = 8080 register so I may as well stick to it). Simply because of the many cases like the two I've used as examples, both of which are really simplified by having an 8086 8 bit register for A. As a 8080/Z80 programmer learning 8086 at the time, it took me a while to realise that al being off-limits for register A due to lodsb wasn't really a big problem, because any of the 8086 8 bit registers had equivalent expressability to the 8080 accumulator. At that point I stopped worrying about using the standard 8080 -> 8086 register mappings. It's more than possible that I was seduced by apparent simplicity and actual runtime performance could have been tweaked a little higher on average by something with a little more superficial complexity. I was in a hurry and looking to get my 8 bit tools running on my new box over a weekend or similar I think (I can't really remember exactly). It was such a long time ago that I've forgotten a lot. Only after I wrote the "shower thought" post above did I remember that as well as dh, I had bp in reserve (basically I'd forgotten about bp). I suppose the extra resource (bp) meant even a normal dispatch loop emulator could also be written without needing to emulate any 8080 register with memory, contrary to what I wrote about above. One optimisation I think I did do was actually to emulate MVI A,imm and other single byte immediate instructions with a lodsw rather than a lodsb, effectively prefetching the next opcode. I had the 256 opcode routines packed together initially, then I'd distribute them to their ultimate 0x0000, 0x0101, 0x0202 ... locations at runtime and append the lodsb; mov ah,al; jmp ax suffix then. So no problem if the code for MVI A,imm was lodsw; mov dl,al; mov al,ah; jmp ax; The appended suffix would still be there, it would just never execute. My first implementation of this emulator took the form of a binary prefix that could be prepended to any CP/M 80 .com file with the Operating System's concatenate command (PIP ?), to make a CP/M 86 .cmd file. Later on I adapted it to MS-DOS with a similar deployment strategy, not a huge job because the basic system calls I needed were close cousins to MS-DOS equivalents. As you say, quite different for Linux. In general the window of widespread usefulness for this tool was limited; basically the time when CPM/80 software was still competitively capable and PCs were still not at least an order of magnitude faster than their CP/M 80 predecessors (after that point conventional emulators were fine). I never took the chance to try and share my code with the world, that was harder then. So it never helped out anyone but me sadly. Love your rep_lodsb handle by the way.