Emulator developer releases expansive Intel 286 test suite • The Register

The developer of MartyPC, an emulator for vintage Intel-compatible hardware that targets cycle accuracy, has released a test suite for Intel’s classic 80286 processor and compatibles – created, in a fit of raw enthusiasm and hyperfocus, by single-stepping a physical chip from the mid-1980s through the execution of almost 1.5 million instructions.

SvarDOS: DR-DOS reborn

SvarDOS: DR-DOS is reborn as an open source operating system

READ MORE

“The real-mode test suite contains 326 instruction forms,” developer and vintage computing enthusiast Daniel Balsom explains of his latest open source release, “containing nearly 1.5 million instruction executions with over 32 million cycle states captured. Each test provides initial and final CPU states including registers and memory. Each test also includes cycle activity for each instruction, including the values of the address and data buses, bus controller signals, miscellaneous pin status, and processor T-state [individual cycle states].”

The demo has a lot of Back to the Future references, and so I named my emulator Marty after Marty McFly. It was sort of cheeky – I didn’t really have any expectation I’d ever be able to emulate 8088MPH, as at the time there was only one emulator, 86box, that could do it

In short, it’s a wealth of data the likes of which the world hasn’t seen outside of an Intel lab in the early 1980s, painstakingly gathered through exhaustive effort and more than a little ingenuity.

It’s a hard(ware) job

The test suite’s purpose is to assist Balsom in adding support for the 286 to MartyPC. Released in 1982 as a version of the 80186, the successor to 8086, with memory management and protection functions specifically tailored for multitasking, Intel’s 286 was described by Rolm architect Robert Childs as delivering “mainframe-level functions and performance directly to the office desk, for the first time, at a cost-effective price” in the foreword to Morse & Albert’s 1986 reference The 80286 Architecture. Despite having been developed with industrial control and telecommunications systems in mind, that promise of boosted performance – a doubling for the same clock speed, for common workloads – saw the 286 picked to power IBM’s PC/AT and its innumerable “IBM compatible” clones.

While many emulator developers are happy to call a job done when the emulation is complete enough to run popular software titles – an entirely reasonable approach for those who don’t want to get bogged down by edge cases – Balsom sets a higher standard. Like rival emulator PCem, MartyPC targets cycle-accurate emulation – and in order to deliver that, the developer needed a way to validate its operation.

“It really comes down to the demoscene,” Balsom explained in an interview with El Reg. “When I started work on a PC/XT emulator, there was a particular demo – 8088 MPH – that was infamous for being difficult to emulate (its tagline was ‘We Break Your Emulators’). The demo has a lot of Back to the Future references, and so I named my emulator Marty after Marty McFly. It was sort of cheeky – I didn’t really have any expectation I’d ever be able to emulate 8088 MPH, as at the time there was only one emulator, 86box, that could do it.”

The new test suite, which follows the release of an even more expansive suite covering Intel’s simpler eight-bit 8088, was created using original hardware – not an Intel chip but a second-source “clone” chip, the Harris N80C286-12. The reason: avoidance of Intel’s use of the depletion-load NMOS (N-type metal-oxide semiconductor) chip fabrication process in favor of the more clock-speed-forgiving CMOS (complementary metal-oxide semiconductor).

“A CMOS process CPU generally requires less power, but it also can be a fully static design,” Balsom explains, “meaning that it can be clocked very slowly (or not at all) without losing state or malfunctioning. Therefore, a CMOS 80C286 was the ideal choice for generating these tests. It just happens that Harris 80C286 CPUs are the most widely available model.”

Arduino control

Stepping a CPU through each individual cycle by hand may have been a fun way to spend an evening in the days of the venerable Intel 4004, but when you’re looking to capture tens of millions of T-states, it’s not really an option – nor is reading the memory status from front-panel lights, as mesmerizing as they might be.

For that job, Balsom developed the ArduinoX86. Designed as a “shield” add-on for the Arduino Giga microcontroller development board, the ArduinoX86 stands in as a controller for the Intel 8086, 8088, 80186, and now 80286. With this, a PC can take control of the target CPU over a serial link to the microcontroller and run it step-by-step while recording all states for later analysis. More importantly, the captured data can be used to write tests for validating the cycle-level accuracy of an emulator like MartyPC – or even for validating that a “clone” second-source chip works as you’d expect.

The result is an automated version of the ability to single-step early microcomputers, slowing the chip down to the point where a low-cost microcontroller with a USB serial link can reasonably capture every processor state from every cycle one by one. The captured data is then processed into a binary format dubbed Machine Opcode Operation (MOO), for which Balsom provides Rust and Python code along with a script to convert the files to JSON format roughly matching that in which Balsom’s previous test suites were released.

“The way I run my own tests is that the emulator logs cycle states,” Balsom tells us, “and then they can be printed side-by-side with the cycles recorded by the test. This saves a lot of guesswork in asking ‘Where is my emulator inaccurate?’ and lets you focus on one instruction at a time.”

Real protection

At the time of writing, Balsom’s test suite covered only the “real” mode of the 286 – described by 8086 architect Stephen Morse in The 80286 Architecture as “like a very fast 8086” and in which the shiny new features of the chip are disabled in favor of guaranteed backwards compatibility with 8086 and 8088 code.

The chip has a second virtual, or protected, mode, which introduces memory management and protection features specifically created for use by true multitasking operating systems. This, it seems, may prove more challenging. “Creating tests for protected mode is non-trivial,” Balsom admits, “as memory cannot be randomized (or the vast majority of instructions would immediately triple-fault.)”

That doesn’t mean Balsom’s work is done, however. The developer is already working on tests for the processor’s third operating mode, known as unreal mode. “Unreal mode is still real mode,” Balsom writes. “However, using the LOADALL instruction the segment descriptor cache can be initialized to arbitrary values.” This then unlocks a key feature of the 286, which was admittedly not in heavy commercial use until towards the end of its lifespan owing to the high price of dynamic memory components: support for up to 16 MB of RAM, a big jump from the 1 MB limit of the 8086/8088 and the 80286 operating in real mode.

Then, of course, comes the payoff: adding provably cycle-accurate emulation of the 286 to MartyPC before jumping straight back on the test generation and development treadmill to do the same for its 1985 successor, the 32-bit 386.

“Primarily emulator makers,” Balsom tells us of the target audience for the test suite, “but if anyone is interested in old hardware research, they might find mining the tests useful. The existence of accurate 286 emulators does benefit retro software developers as well.

“Plus, just hooking the 286 to the Arduino revealed some interesting things about the 286’s behavior, like the fact it pushes things in different order than the 8086 did when executing interrupts and that it seems to fill its prefetch queue entirely after any jump. I don’t know if anyone knew about this stuff before – probably back in the day, but this knowledge gets lost over time.”

Balsom’s 80286 test suite is available on GitHub under the permissive MIT license, with separate repositories for the MOO handling code, ArduinoX86 CPU controller, and MartyPC itself. ®

Leave a Comment