I’ve covered PC compatibility in the past, and tried to explain how just having an x86 CPU and running DOS does not necessarily make your machine compatible with an IBM PC. At the time, this was mainly about the IBM PCjr (and its clone, the Tandy 1000), which is still relatively close to a regular PC. As such you could create software that would run on both IBM PCs and compatibles, and on the PCjr/Tandy, with custom code paths for specific functionality, such as sound and graphics.
But pretty much all other DOS/x86-based machines failed, as their hardware was too different, and their marketshare was too small for developers to bother adding support. In fact, the main reason that the Tandy 1000 existed at all, is because the earlier Tandy 2000 was falling into the trap of not being compatible enough. The Tandy 1000 may actually not be a very good example, as Tandy tried to make it nearly 100% compatible, fixing the main reason why the IBM PCjr also failed. So later Tandy 1000 models were more or less a ‘best of both worlds’: nearly 100% compatible with IBM PC, but also offering the enhanced graphics and sound capabilities of the PCjr.
Meanwhile, in Japan…
In Japan however, things took a different turn. The Japanese do not just use the Latin alphabet that is used on all Western machines, including the IBM PC. The Japanese language uses more complex glyphs. They have multiple systems, such as kanji, katakana and hiragana. To display these in a comfortably readable form, you need a high-resolution display. Also, where Latin letters encode sounds, a kanji glyph encodes a word or part of a word. This means that your glyph alphabet contains over 50000 characters, a lot more than the maximum of 256 characters in your usual 8-bit Western character set.
So the Japanese market had very specific requirements, that PCs could not fulfill in the early DOS days. You couldn’t just replace the character ROM on your PC and make it display Japanese text (IBM did later develop the 5550 and the JX, a derivative of the PCjr, specifically for the Japanese market, and later, they developed the DOS/V variant, which added support for Japanese text to their PS/2 line, using standard VGA hardware, which by now had caught up in terms of resolution).
Instead, Japanese companies jumped into the niche of developing business machines for the home market. Most notably NEC. In 1981 they introduced the PC-8800 series, an 8-bit home computer based on a Z80 CPU and BASIC. In 1982, the PC-9800 series followed, a more high-end 16-bit business-oriented personal computer based on an 8086 CPU and MS-DOS. These families of machines became known as PC-88 and PC-98 respectively (Note that the ‘PC’ name here is not a reference to IBM, as NEC had already released the PC-8000 series in 1979).
In this article, I will be looking at the PC-98 specifically. So let’s start by doing that literally: here are some pictures to give an impression of what these machines looked like. They look very much like IBM PC clones, don’t they?
For more machines, specs and background info, I suggest this NEC Retro site.
How compatible is it?
It has an 8086 CPU, an NEC 765 floppy controller, an 8237 DMA controller, an 8253 programmable interval timer, and two 8259A programmable interrupt controllers. Sounds just like a PC, doesn’t it (okay, two PICs sounds more like an AT actually, so NEC was ahead of its time here)?
Well it would be, if it used the same IO addresses for these devices. But it doesn’t. What makes it especially weird is that since it has always been a system with a 16-bit bus (using an 8086 as opposed to the 8088 in early PCs), NEC chose to map any IO registers of 8-bit devices either on even addresses only, or on odd addresses only (so the 16-bit bus is seen as two 8-bit buses). For example, where the first 8259A on a PC is mapped to ports 0x20 and 0x21, the PC-98 places it at 0x00 and 0x02, leaving 0x01 as a ‘gap’ in between. The 8237 DMA controller is actually mapped on address 0x01, 0x03 and so on.
Another major difference is that the base frequency of the PIT is not 1.19 MHz like on the PC, but depending on the model, it can be either 1.99 MHz or 2.46 MHz.
And like the PCjr and the Tandy 1000EX/HX models, it has an expansion bus, but it is not the ISA bus. The PC-98 uses the C-bus. So you cannot use standard expansion cards for IBM PCs in this machine.
Clearly the video system isn’t compatible with any PC standard either. It does not even use int 10h as the video BIOS. Speaking of BIOS, the PC-98 BIOS is not compatible with the IBM PC BIOS either. But as said, the video system was far superior to the IBM PC at the time. The first version in 1982 already supported 640×400 with 8 colours, based on NEC’s own uPD7220 video controller. In 1985 they extended this with a palette of 4096 colours to choose from, and an optional 16 colour mode if an extra RAM board was installed. In 1986 the extra RAM became standard on new models, and they also added a hardware blitter for block transfers, raster operations and bit shifting.
What’s also interesting is that they chose to actually use TWO uPD7220 chips in a single machine. One of them is used for text mode, the other for bitmapped graphics mode. They each have their own video memory, and are used in parallel. So you can actually overlay text and graphics on a single screen.
But, on the other hand…
There are two things that we can use to our advantage:
- It runs (an NEC PC-98 OEM version of) MS-DOS
- A lot of the hardware is the same as on the PC
So this means that for basic functionality such as file and text I/O, memory management and such, we don’t need the BIOS. We can use MS-DOS for that, which abstracts the machine-specific BIOS stuff away. Also, if we write code that uses the 8237, 8253, 8259A or other similar hardware, in most cases we only need to change the I/O-addresses they use, and adjust for the different PIT frequency (and other minor details, such as the different cascaded configuration of the two PICs and different IRQs for devices), and we can make it work on the PC-98.
So just like with Tandy and PCjr, we can write DOS programs and make them work on PC-98. We can even write a single program that can run on both types of systems, even though it is a bit more complicated than on Tandy/PCjr (on those you mainly had to avoid using DMA, and you should be aware that the keyboard is different, so you should only access it via BIOS, or have separate routines for the different machines).
I decided to give this a try. I have made my own little ‘SDK’ of headers and library functions for ASM and C over the years, which includes quite a few constants for addressing I/O ports or memory areas of all sorts of PC and Tandy/PCjr hardware (I modeled it after the Amiga NDK). I figured I would try a PC-98 emulator and port my VGM player over to the PC-98, and update the SDK with PC-98 support in the process.
A convenient emulator is DOSBox-X. It is a fork of DOSBox, which adds a PC-98 machine, among other features, and like DOSBox, the BIOS and DOS emulation is built-in, and you can just mount host directories as drives, so you don’t have to juggle all sorts of ROMs and disk images to get the system running. If you want a more serious emulator though, Neko Project 21/W is one of the more compatible/accurate ones.
And indeed, you can just use OpenWatcom C to write a DOS application, and it will work, as the basic runtime only requires DOS interrupts, no BIOS or direct hardware access. All the BIOS and direct hardware access is done via my ‘SDK’ anyway, so as long as I write the correct code for PC-98 BIOS and addresses, I can use any hardware from C (or assembly of course).
What’s more, it turns out to be relatively simple to detect whether you are running on an IBM PC-compatible or a PC-98 compatible machine. A trick that is used is to call int 10h with AH=0Fh. On an IBM PC-compatible, this will return information about the current video mode, with AH containing the number of columns. On the PC-98, this will not be implemented, so after the call, the value of AH will be unaffected. Since there is no video mode with 15 columns, you can assume that if AH is 0Fh after the call, that you are running on a PC-98 machine.
Anyway, before long I had a basic version of my VGM player working on both the IBM PC and the PC-98. It’s a pretty fun and quirky platform so far. So I might be looking into the graphics chip in the near future.
If you also like to play around with DOS and x86, and want to give the PC-98 a try, here are some good resources (you might need to translate, as most documentation can only be found in Japanese):
Pingback: When is a PC not a PC? The PC-98 – OSnews
Any chances you’ll make your SDK public? I am interested in DOS programming and having such a thing would make things easier
That was the idea yes, but so far I haven’t had the opportunity to extract this code into a separate, public repository. An earlier pre-release, dubbed the ‘SerdacoSDK’ was released for the Serdaco parallel port devices: https://hackaday.io/project/158474-s2p-tiny-parallel-port-general-midi-synthesizer/log/160344-serdaco-sdk-by-scali-support-for-s2p
I’ve managed to export the SDK-related stuff from my work-in-progress repository to a public Github: https://github.com/Scalibq/DOS_SDK
Pingback: PC-98: La alternativa japonesa al IBM PC – NeoTeo
Pingback: Știri #67 - BreakingPoint