Episode 1: Hello, PCjr!

Episode 1: Hello, PCjr!

That old PCjr I cut my coding teeth on 25 years ago is still with us, and presumably still in perfect working order, boxed up in my parents' basement. In addition, an original IBM PC model 5150 is boxed up in the attic, given to me by my father-in-law (he thinks he's getting rid of junk; I am honored to have this piece of history). I hope to be able to set up these dinosaurs and play with them from time to time, but right now there's no room in the house.

So for our coding adventure, we'll use something more convenient: DOSBox, a DOS emulator for x86. DOSBox can act like a PCjr, supporting the video modes and PC speaker we expect to find on the real thing. The application is pretty easy to download and install, so I won't expound on that, instead I'll just show you the dosbox.conf configuration file I used:

[dosbox]
machine=pcjr
memsize=0

[cpu]
cycles=315

[render]
scaler=normal3x

[dos]
ems=false

The first line tells DOSBox to emulate a PCjr by supporting the three extra video modes that the PCjr's Video Gate Array is capable of, in addition to the standard CGA and text modes. It also simulates the PCjr's cartridge slot by allowing you to load cartridge ROMs ripped to .jrc files, but we won't use that feature.  The next line specifies high memory size of 0. DOSBox still allocates 1 MB of RAM for low memory, which is about triple what the PCjr could actually support, so that's the best we can do.

The cycles parameter roughly corresponds to the speed at which DOSBox's simulated processor will run instructions. For the 4.77MHz Intel 8088 processor in the PCjr, this value is about 315 as specified here. We will be operating at tiny resolutions on a big monitor, so we will use the scaler parameter to triple the screen size.  Finally we tell DOSBox to disable EMS (expanded memory), as the PCjr has no such thing.

We also need an assembler to translate our assembly code into an executable format.  Very little is done here; there's no compiling and linking as in other languages, instead the assembler just encodes the instructions line-by-line into a numerical format the CPU can act on natively. We'll use NASM, a free x86 assembler capable of writing .COM files, the simplest PC executable format which hasn't changed much since the days of the PCjr.

We have our tools all set up.  Let's run something!  Type this into a text editor:

[cpu 8086]
[org 100h]

mov dx, str_msg
mov ah, 9h
int 21h

mov ax, 4c00h
int 21h

str_msg: db 'Hello, PCjr!', 0ah, 0dh, '$'

Save it as test.asm, then open a console to the same folder and compile it with this:

nasm test.asm -f bin -o test.com

Then run it like this (assuming you saved the dosbox.conf given earlier to the same folder):

dosbox test.com

And you should see this:

We've written our first assembly-language program, assembled it into an executable format that can be understood all the way back to the days of the original PC, and run it in a DOS emulator set up to emulate the PCjr. For an explanation of what our code does, continue to the next episode!

Full source for this episode can be downloaded at:
https://github.com/josh2112/pcjr-asm-game/tree/episode-1