I was wondering if it is possible to run 8-bit applications within QEMU. I know that the x86 architecture can run 16-bit applications, but can it also run 8-bit applications?
-
15Define "8-bit application".– Criticizing Israel not allowedCommented Jun 10, 2016 at 4:25
-
10there's no 8-bit x86. although it's possible to emulate other 8-bit architectures– phuclvCommented Jun 11, 2016 at 16:49
-
3This question does not make much sense without more clarifications. Why are you mentioning QEMU? Are you asking about whether the x86 can operate as an 8 bit processor or whether QEMU does emulate such (hypothetical) 8 bit mode of the x86 properly?– Laurent GiroudCommented Jul 3, 2016 at 4:54
-
3@hippietrail 8086 is not an 8-bit architecture. 8088 is just 8086 with a smaller external bus– phuclvCommented Apr 27, 2020 at 8:20
-
3@hippietrail no, 4004 and 8008 are 4 and 8-bit CPUs. 8086 and 8088 are 16-bit ones. 80-bit is the width of an x87 register and has no relation to integer registers in x86 whatsoever– phuclvCommented Apr 27, 2020 at 9:30
6 Answers
There are several aspects to consider to answer your question.
The x86 architecture is backwards-compatible with the first CPU of the line, the 8086 (and its sibling, the 8088). What this means is that, when a modern Intel (or AMD) processor boots up, it starts in a mode which is compatible with the 8086 — if the motherboard's BIOS support is good enough, you can still boot MS-DOS on a brand-new PC (albeit not from a floppy disk!). (Presumably you could also boot CP/M-86, but I haven't tried that. Other 16-bit operating systems, such as OS/2, Coherent or Xenix, are more demanding and tend not to work — Fun with virtualization goes into the specifics). The 8086 and 8088 are 16-bit CPUs, inasmuch as they process data internally 16 bits at a time. As newer CPUs introduced wider internal data busses, new modes were added to support them, so you get 32-bit binaries and now 64-bit binaries, and it's even possible to mix and match. So a modern, 64-bit x86-compatible CPU can still run 16-bit binary code, at least in some modes (64-bit mode, or "long mode", doesn't support real-mode 16-bit code; it's possible to work around this using VT-x).
Running an application doesn't just require CPU support though, it also requires operating system support. So you can't just take a 16-bit DOS or Windows binary and run it on a Linux system, or even on a Windows 10 system — you need some sort of emulation layer, not for the CPU, but for the operating system services and virtualised hardware. This is where tools such as NTVDM, DOSBox or Wine come in.
What would it mean to run an 8-bit binary on an x86 CPU? On the CPU side, the closest 8-bit CPU is the 8080, but the 8086/8088 is different enough that it's not binary-compatible with the 8080; so you can't directly run an 8080 binary on an 8086, let alone on a more modern x86 CPU. On the operating system side, the best you could hope for would be that your application was built for CP/M; so you'd need some sort of CP/M-compatible layer (or perhaps CP/M-86 or DOS which was somewhat backwards-compatible).
As mcleod_ideafix points out, the x86 is source-code compatible with the 8080, i.e. the 8086 supports all the features of the 8080 and the Intel assembler mnemonics for the 8080 can be (in most cases) mechanically converted to equivalent 8086 assembly. But you'd still need to adapt the application to the target operating system, as well as the new target CPU. (Stephen P. Morse's 8086 history covers this in more detail.)
So in summary, you can't take an 8-bit binary and run it directly on an x86 processor. If you're careful, you may be able to rebuild an 8-bit 8080 assembly language program for the 8086, and run it under CP/M-86 or DOS. Thanks to the x86 architecture's support for 8-bit operations, you can write an 8-bit style application (i.e. using only 8-bit arithmetic and logical operations, but 16-bit pointers) and run it on a 16-bit operating system (the BIOS supports this rather well, as does DOS). But to me this isn't quite the same as the 16-bit and 32-bit support on modern 64-bit systems, because the 16-bit nature of the architecture leaks into its 8-bit support: for example, 8-bit DIV
always divides the 16-bit AX
, which means you can't simply pretend AL
and AH
are separate 8-bit registers unless you avoid DIV
, MUL
etc. entirely.
QEMU itself doesn't emulate any 8-bit CPUs. There are many 8-bit emulators for modern systems though, some including the operating environment — examples include Stefan Tramm's 8080 CP/M emulator, the Toledo 8080 emulator, Z80pack...
-
9Technically, long mode can run 16-bit protected mode code, just not virtual 8086 code. For the Windows-specific case, the 16-bit Windows APIs are still not available in 64-bit Windows, but this isn't a CPU limitation. (DOS applications, on the other hand, are real/virtual 8086 and won't work without emulation.)– BobCommented Jun 9, 2016 at 23:53
-
5"you can't simply pretend AL and AH are separate 8-bit registers unless you avoid DIV, MUL etc. entirely" -- of course, the 8080 didn't have any such instructions anyway, so you'd probably be avoiding them as a matter of course.– JulesCommented Jun 10, 2016 at 19:21
-
1@Jules yes indeed, if you're porting 8-bit code — I was thinking more along the lines of developing new 8-bit code. The same consideration applies to the 16- to 32-bit switch, and to the 32- to 64-bit switch, since they all introduced new instructions that don't have smaller equivalents, so I suppose my argument is contrived. Commented Jun 10, 2016 at 19:23
-
2@Radovan I’m mentioning DOSBox and Wine in the context of emulating the operating system services, not the CPU. You’re right about DOSBox emulating the CPU (DOSEMU does so too in some circumstances, since it’s hard to run 16-bit code in VM86-mode while in long mode on 64-bit CPUs). Commented Aug 11, 2017 at 12:50
-
1Windows 10 32 bits edition supports 16 bits applications. One can say that it's its "raison d'être". That version exists mainly for that purpose, as x86 without 64 bit support (Athlon XP, Pentium 4, Dothan, etc.) would be so slow anyway that there would be no point in installing windows 10 on them. Commented Apr 27, 2020 at 9:50
The 8086 is source-code compatible with the 8080 (the other way around is not true). This means that most assembly code written for the 8080 can be assembled so that 8086 instructions are emitted. The only exceptions would be self-modifying code or code that relies on interrupts, which are handled differently on both processors.
In fact, some assemblers, like PASMO, are able to generate .COM programs for DOS or CP/M 86 from the same 8080 assembly code. Digital Research also had XLT86, a 8080 to 8086 translator.
Even if they were not source code compatible, the x86 architecture has 8-bit registers, and can perform 8-bit loads and stores, and 8-bit ALU operations, so it is capable of running 8-bit applications (understanding that 8-bit applications are those applications that use 8 bit data types, 8 bit operations, and 16 bit addresses)
-
4"the x86 architecture has 8-bit registers, and can perform 8-bit loads and stores, and 8-bit ALU operations, so it is capable of running 8-bit applications " This is the key salient point and answers the question. Commented Jun 10, 2016 at 0:56
-
3As I recall, the instructions are 1 for 1 so it can be mechanicly translated, even without source. You just have to figure out what are actual instructions and not embedded data tables.– JDługoszCommented Jun 11, 2016 at 10:51
A few 16-bit processors can run 8-bit code: the NEC V20 series. The V20 and V30 are the ones you might encounter in a PC. The V20 is a pin-compatible substitute for the 8088, and the V30 for the 8086. These processors have a BRKEM instruction (in Intel's notation it would most likely be 'INTEM') which switches to the 8080 instruction set and jumps to an interrupt vector. A RETEM instruction would switch back. Some CP/M emulators, such as 22NICE could use this mode to virtualise CP/M programs rather than emulating the CPU -- provided the CP/M program only used 8080 instructions, not any of the Z80 extensions.
As far as I know QEMU does not emulate this aspect of the V20 / V30, so it wouldn't be possible to run 8-bit programs within mainline QEMU. The QEMU wiki does mention a separate Z80 fork that can run Spectrum programs.
-
2Nice, I'd forgotten about the 8080 mode in the V series! Commented Jun 10, 2016 at 9:39
-
1Ha! Years of x86 programming back in the day (and having targeted V series chips on occasion) and I learn something new decades later! I knew about the 186 instruction set support, but had never run across 8080 mode before! Commented Jun 11, 2016 at 17:39
There is no such thing as an 8-bit application for the x86 architecture, because the x86 architecture has always been at least 16-bit right from the first generation of x86 processors.
The x86 does allow access to 8-bit registers, but the code is still 16-bit and the processor is still running as a 16-bit processor.
Of course, if you're trying to run 8-bit applications for a different architecture (a lot of people use the term "8-bit" generically to refer to old games and applications made for e.g. the BBC Micro, Commodore 64, early Nintendo game systems, and many other classic retrocomputers) then you will need to find an emulator for that system. In that case, your x86 processor is not running the application directly, but is running the emulator application (just like any other application that you run on your x86 processor) which in turn is running the 8-bit application "in software". You should take a look at MESS if this is what you want.
Some supplemental things:
Years ago, I used a program that emulated 8 bit CP/M on 16 bit DOS machines that were not the special NEC V20/V30 nor the dual-CPU AT&T design. It worked quite well and was not that much slower than the real thing. And since modern x86_64 CPUs can still run DOS, that program would still work if I could find it.
x86_64 CPUs can run 16 bit code and even virtual-86 code without resorting to the hardware-virtualization extensions. It is just that due to some historical accidents, Microsoft Windows was written on the assumption that any CPU other than 32 bit x86 wouldn't have any of the PC features, so for no good reason 64 bit Windows lacks support for such things as hardware accelerated full screen command prompts, the fallback 640x480 VGA Driver and the subsystems that run 16 bit x86 programs.
The trick to run 16 bit x86 modes from a long mode x86_64 OS is that ever since the 386, switching the entire CPU to any of its other modes is quick and painless for any OS designer who understands the architecture (rather than just the "suggested" ways to use it). So to run 16 bit code, a 64 bit OS would need duplicate copies of some of the smaller control tables (GDT, LDT, IDT, but not the page tables), plus mode switching glue code. Then at any context switch, the OS can freely enter whichever mode supports the code being switched to.
If you are looking for modern emulators for classic 8 bit CPUs, you may need to first decide if you are looking for a game focused emulator, a productivity/compatibility code emulator or a research cycle-counting emulator (slow). Each will do its primary job to the detriment of its ability to do the others.
There are also modern 8 bit CPUs, such as the PIC and AVR CPUs from Microchip Inc. Most of those have excellent emulation tools as part of their development packages.
-
2Judging by how a quick-to-make-but-less-than-ideal fix for a security flaw in LDT fixups was related to Wine on Linux temporarily losing support for running Win16 programs, I think what you describe is how Wine actually implements Win16-on-Linux64 support.– ssokolowCommented Apr 28, 2020 at 1:38
-
2"Microsoft Windows was written on the assumption that any CPU other than 32 bit x86 wouldn't have any of the PC features, so for no good reason 64 bit Windows lacks support for such things as hardware accelerated full screen command prompts, the fallback 640x480 VGA Driver and the subsystems that run 16 bit x86 programs." - Which is especially irritating given that at least one of the features you mention (16-bit support via NTVDM) was implemented (via software emulation) on the completely-non-x86 (Alpha, MIPS, PPC) versions of Windows NT from the 1990s.– VikkiCommented Jun 7, 2021 at 0:58
As mcleod_ideafix pointed out, the x86 architecture is source-compatible with the x80 architecture. This basically means that if you have the original assembly file of a program, you can rougly translate it to x86 bytecode. Of course, you still need some form of assembly file to compile it, but you might have a look at Dynamic Recompilation.
However, just executing code isn't everything for an emulated system. In fact, most 8-bit systems will use some form of Memory-mapped I/O or Port-mapped I/O. Of course, there is always the possibility to detect those, and then replace them with a call to a function defined by the emulator. The same goes, for example, for Z-80 opcodes, which are used a lot and which are basically incompatible with x86.
The real matter, however, is the fact that you wont need recompilation. In fact, most of those systems from the 80's did have clock rates in the 1-5mHz rate. When you run this on a Gigahertz CPU, you would only need a really tiny fraction of the CPU time. Of course, this is a little different when implementing a later system, like some arcade systems, but those doesn't tend to use 8-bit CPU's.
To be honest, the complexity of using dynamic recompilation to catch all those cases isn't worth the try. Use a good, well tested x80/z80 emulation library, or write your own for the matter, it is much easier, saver, and makes your code also a little bit more portable, in case you would have to port it to a smartphone, for exemple.