An 8086 Monitor
Any 8086 S-100 board normally needs a built in monitor
program to monitor its ability to interact with other S-100 bus boards.
Unlike the typical situation for 8 bit CPU's there are typically no space
limitations so more code can be added than you would normally see in say a Z80
monitor for example. That said, it is usually desirable not to have the
monitor ROM extend below the region found in an IBM-PC (F0000-FFFFFH). For
example the PC Video board RAM at A0000H- BFFFFH (and/or) C7FFFH-EFFFFH. Above
F0000H everything is up
for grabs for us. We will use this space here for extensive board
system diagnostics, we will write our own code to
emulate standard PC calls so the software "thinks" it is talking to an IBM-PC.
To do this we need quite a bit of space. Our 8086 monitor therefore will start at F8000H with much of the code space up
to FFFFFH filled with true monitor type commands.
Here is a typical layout:-
The 8086 (and above) family of CPU's all start from a reset at FFFF0H in RAM.
This includes by the way the 80286, 80386 etc., CPU's. In an 8086 there is
not much forward space left, (16 bytes), so at that location there is always a
jump downwards to the start of the actual monitor. (As an aside, the 8089 I/O
coprocessor actually uses some of the remaining 16 bytes there).
Remember all addresses on the 8086 are obtained by adding a 4 bit shifted left
CS: register value with the IP register. The so called "Segment:offset addressing
scheme". Put another way:-
8086 20 bit Address = ZZZZZZZZZZZZ
Upon reset the 8086 CS register will have F000H, the IP register FFF0H, so the
initial reset address is FFFF0H. In our monitor at that address we jump
immediately to F8000H which is the start of the monitor. The first thing
we do is set a few things up. We set the DS,ES and SS segment registers to this
same CS (F000H) value (upon reset they were all 0's). This way when we
want to print strings etc the DS: is pointing to the same EPROM location as the
mov ax,cs ;Note cs will be F000H
mov ds,ax ;DS will also be F000H
mov es,ax ;As will ES
Next we need to setup a valid stack pointer to a valid RAM location. Now
normally with a board like this you would use a 1MG RAM board so the stack would
be just below the EEPROM at ~ F7FFFH. However I did not want to make that
a requirement. I wrote a little module to find the top of available RAM and
place the stack segment and stack pointer there. So for example this
monitor (and CPM86+) would work would work fine with only 128K or
RAM. I do not recommend this however.
With a valid stack we CALL a routine to print a signon message, initialize some
and display the current value of the stack segment and SP.
If you enter the "K" command you will see all the monitors options. Here is a
picture of the screen:-
Most of the commands are self explanatory. However there is one feature
you need to keep in mind and that has to do with memory addressing.
Most monitor commands are modeled after the TDL/Zapple/Z80 commands. Because we
are now dealing with potentially up to 1MG of RAM for many commands, the start,
stop RAM locations can take up to 5 digits. However the actual span/range
for any command is limited to 64K.
The following example fills RAM with 76H from 1A000H to 21234H.
Of course for the lowest 64K of RAM the "normal" 4,3,2 or 1 byte formats can be
Note because of the 64K range limitation, the following will give an error
F1A000,31234,76 or F1A000,1B000,76
I considered using the Intel style Segment:Offset (xxxx:yyyy) approach,
but decided against it, because calculations can sometimes be frustrating, also
I want to later extend the monitor for Intel true 32 bit CPU's and the 68K
family. That said, it was a pain to do because we always have to check
segment wrap around!
The monitor consists of 3 main sections. It assumes an 8086 (does not use
opcodes of the 80286+)
This is a classical monitor. Display, Change RAM/ports etc.
This is a self contained set of routines run diagnostic tests on the
S100Computers IDE board.
This fairly complex section. It emulates most of the IBM-PC ROM BIOS
interrupts (hard & soft) such that MS-DOS (V4.01)/FreeDOS can be run on
the system - without DOS modifications.
The first section of the monitor is very generic and should work with very little
modification for any hardware setup. Only console I/O etc need to be adjusted
for your setup.
The second main section of the monitor is activated with the "N" command. This brings up
the Dual Board IDE diagnostic package with its own menu shown here:-
This menu allows you to check out your IDE Drives/CF Cards with the 8086 board
and our Dual
IDE Board. For example if you can copy (exactly) one CF card to
another using the "Y" command. Afterwards the "V" command will read each
sector and verify that both cards are identical. You need to be able
to demonstrate this before you install CPM86+ or MSDOS in your system.
The software itself is a little tricky because again we cannot make any
assumptions as to how much RAM is in the system. I wanted to have the disk
sector buffers up out of the way in top memory. I used the SS:[BP+offset]
to access all IDE drive parameters and buffers. Because we are using the SS
segment the whole process will work with any memory configuration. The
other commands are fairly straightforward and are the same as for the equivalent
8 bit program
(bottom of the page).
Here is a short video demonstrating some of the 8086 Monitor menu items for the basic
monitor commands and the IDE drive(s) "N" sub-menu commands:-
The third section of the monitor is activated with the "X" command. This brings up
the "IBM-PC BIOS" diagnostic package and run time routines. This
part is the most complex part of the monitor and represents in fact the bulk of
The "X" command brings up its own sub-menu which is shown here:-
Most of the commands are fairly self explanatory as you
use them. The main function of the diagnostic commands (E,F,G,O etc) is to
checkout that the 8259A interrupt hardware is functioning correctly. For
example with the "E" command, when you hit the keyboard, an interrupt is
generated (V1 on the S-100 bus) and the key is stored in the BIOS keyboard
There are also tests for the floppy and hard disk drive sector read and write
interrupts. If you are using the ZFDC and IDE controller boards
these tests should work without any modifications. If you are using
another floppy or hard disk controller board you will need to modify (carefully)
the code in these sections. These diagnostic routines allow you to see the
contents of a read sector. It's critical you are reading the same sector
as defined by the IBM-PC parameters.
On a PC (at least the early ones) sectors are defined is terms of
Cylinders, Heads & Sectors. INT 13H interrupts for sector reads and writes
designate sectors in a somewhat convoluted way (for historical reasons),
parameters passed are always as follows:-
AH = 02h
AL = number of sectors to read/written (must be nonzero)
CH = low eight bits of cylinder number
CL = sector number 1-63 (bits 0-5). The high two bits are for cylinder bits 6-7. (hard disk only)
DH = head number
DL = drive number (bit 7 set for hard disk)
ES:BX -> data buffer
Throughout the INT 13 section you will see these values
used a lot. Because only 16 heads are allowed with this format a
hard disk can only get to 512MG. To go to higher disk capacities you
need a later version of MSDOS and a BIOS that utilizes "LBA" addressing.
Both formats are implemented on our IDE board but for now I will stick with
Fortunately there are excellent descriptions elsewhere on the web about these
issues. One of the best is the famous "Ralf
Brown Interrupt List". This is a must read for
anybody doing a MS-DOS/PC BIOS.
Here is a short video demonstrating some of the 8086 Monitor menu items for the IBM_PC
BIOS monitor commands, the "X" sub-menu commands:-
Here is another short video demonstrating the use of the 8086 Monitor debugging
output option where information about all software interrupts is sent to another
As you look over the code it may be helpful in understanding
the Hard Disk sector R/W section to understand in MS-DOS how sectors are
identified in the "Cylinder, Head Sector", (CHS) format. See
here. Remember unlike CPM, MS-DOS may ask for a run of up to 80H
contiguous sectors in one BIOS call. It is the BIOS'es job to take care of
end of track, heads etc.
The complete source code listing for
this monitor can be found at the bottom of this page
The source code itself (8086 Monitor.zip) can be downloaded
also found at the bottom of this page.
If you are not familiar with 8086 assembly language code you should study this
program in detail. It utilized a number of the key features of the 8086
CPU and is fairly well documented.
Burning a Monitor PROM using NASM
are over 13,000 lines of code in the 8086 monitor! A while back I rewrote the
early CPM86.A86 code to be compatible with the
public domain 8086 assembler called NASM.
I regret I did not do this earlier. It is a fast, efficient and uses a clear logical syntax. See the home page that describes this assembler. All my more
recent versions of 8086 code use the NASM assembler.
NASM info can be
found here:- http://www.nasm.us/
Amongst the many output file formats that NASM generates is a .bin file.
This is a straight binary byte output of the assembly code -- exactly what a
programmer uses. The Windows 7 version of NASM is included in the above
Monitor.zip file at the bottom of this page. I recommend you use this system setup instead of the
older Digital Research version.
To burn a 28C256 EEPROM's with a
Load the 8086.BIN file. Select Even bytes (1st of 2) for one ROM and "From File
HEX address" and "Buffer Address" leave them as 0000H in the load dialog boxes.
The Edit BOX the code should appear at 4000H-7FFFH in a 28C256 EEPROM.
Simply press the "Program" button.
Repeat for ODD addresses.
Currently we only need the top half of a 28C256 EEPROM. The jumpers on the
8086 board are set to only read the EEPROM for addresses F8000 to FFFFFH.
This leaves the RAM space below the monitor free. Of course should you
need more or less EEPROM space you just configure the jumpers on the 8086 board
differently. (Early versions of the monitor in fact used only 28C64's).
You will notice that I put the stack (and BP buffers) lower down in RAM, at
segment D000H. This is to allow the RAM at E000H to be free and utilized
for the many early test versions of the monitor. This way when they are loaded
from the PC with the monitor "W" command they do not overwrite the current
stack. Clearly you can later move then up if you really need the extra
First Time Installation of the 8086 Monitor
Starting off for the first time with an 8086 on the S-100 bus is a bit
challenging. The problem is that the 8086 family of CPU's all start after
a reset at FFFF0H in high RAM. Your typical 8 bit Z80/8080 starts at 0H in
RAM and cannot reach an address past FFFFH in RAM. What is need is a quick
way to get the initialized 8086 to jump down to (say) 500H in RAM. The
EA 00 50 00 00
in memory in a ROM at FFFF0H will do this.
I have outlined various ways you can get this code at that location
To test and configure this 8086 monitor for initial usage I have written a small
custom version (it does not contain the IDE or IBM-PC BIOS code) for testing purposes. It
can be downloaded here.
You should load this version with CPM's SID into RAM at 500H with the command:-
(This will load the image to 600H to ~3000H). (CPM adds 100H!)
(This will place the code at the correct absolute address 500H in RAM)
After switching to your 8086 Board (IN, port EDH), have the 8086 jump to there
At location FFFF0H:- EA 00 05 00 00 (either in its
onboard EEPROM or done by hand in RAM).
The monitor should sign on. This however is a "fragile" version of the
monitor. It is used to debug basic things like console I/O etc. The stack
is located at 4FFH -- do not overwrite it! That said many of the basics
display/modify/move RAM etc functions should work. With it you should be able to
see all RAM 0-1MB.
Do not however spend a lot of time with this version. Once you have console I/O
going, burn a ROM version for the high memory addressee (at F8000H).
Once you have a PROM based version of the 8086 monitor running things get much
simpler. You may still need debugging. For this reason in the
monitor code there is a line:-
MONITOR_ROM EQU FALSE
;TRUE = Monitor at F000:8000H, FALSE = Monitor in a RAM area (E000:0000H)
When FALSE the monitor code will be assembled to reside at
E000:0000H in RAM
(change as you require). You can assemble the code on your PC with NASM,
and move it across to your CPM80 system. Then use the monitor "W" command
(or the CPM PCLOAD.COM program)
to deposit the program in RAM. You can also use the (old) monitor "Y"
command to move code at 100H in RAM (loaded with SID for example), up to
E0000H, however this approach is now superseded by the combined "W" & "G"
commands in the more recent versions of the monitor.
This monitor will boot IBM's MS-DOS
(Currently V4.01) and FreeDOS unaltered from
1.44M 3.5" floppy disk. The code can be easily modified to do the same thing
from a 5" disk.
More importantly the monitor will also boot MS-DOS from drive #2 on our IDE
Board. All "well behaved" MS-DOS programs seem to work. The code can be
easily modified to utilize the IDE drive #1 (or the older single IDE drive
boards). Take care however, you don't want to overwrite your CPM system.
Very important! You can place the 1.44M Floppy disk or CF-CARD in a standard
Windows 7 PC and read, copy modify files going back and forth between both
computers. The CF card (currently) appears as a 512M disk to
I have yet to write code to allow formatting of disks and drives. The former is
fairly easy with our ZFDC board. For the one time requirement of the Hard
disk/CF Card using a PC is easiest. It's best to try and do this on an
older PC that allows you to set the Hard Disk "type". Use a custom
type of 255 cylinders, 16 heads and 256 sectors. Alternatively if
you know how, you can alter the Hard Disk Partition Table Parameters. Much of
this is amply discussed on the web.
From V7.0 onwards the monitor incorporates three console output options. You can
either send console data to the Propeller driven
Console I/O board,
Lava-10 Video board or to an
IBM-PC CGA/VGA compatible video board (Monitor "B" command). Currently I am using the Lomas "Color
Magic S-100 board" for the third option. (A future Cirrus Logic GP-5420 based S-100 video
board is being planned!).
Currently the BIOS utilizes only two S-100 hardware interrupts.
VI0. This is for the
system tick. On a PC this interrupt is generated 18.2 times a second (by a 8254
programmable timer). In my early system I utilize the
MM581657A clock chip to generate a system tick. It outputs an interrupt every 0.1 seconds.
The BIOS software needs to be adjusting for the slower system tick so the
handler matches that used in the IBM-PC BIOS.
More recently I have switched over to using our
Support board that utilizes the same 8254 Timer the IBM-PC utilized
for the system tick. The PC uses an unusual clock frequency (1.193MHz) to drive
the timer. I generated this frequency using a common 14.318 MHz TV oscillator
and a 74LS92 divide by 12 counter. This generates the required 18.2
VI1. This is the
keyboard input interrupt. Whenever a keyboard key is pressed this interrupt is
triggered. The interrupt inputs the keyboard character(s) and places it in the
BIOS keyboard buffer. In this BIOS we input data from our Propeller driven
Console IO board. Unfortunately I did not include interrupt capabilities on
the early versions of that board. A serious oversight! Fortunately there is a patch area on
the board and an unused Propeller pin (pin 17). By adding one 74LS07 chip
you can bring pin 17 to the S100 bus via an Open Collector output to S-100 line
#5 (VI1). See the bottom of the page
here for more details.
The V2 of this board now incorporates that feature.
Note MSDOS will not sign on unless these interrupts are implemented in hardware
(typically with the
The links below will contain the most recent versions of the above software.
Note, it may change over time and may not correlate
exactly with the text in the article above.
EARLY VERSION OF THE
8086 MONITOR SOFTWARE (Digital Research ASM86 format)
8086 MONITOR SOFTWARE (Using
MM58167 Clock Chip)
MOST CURRENT VERSION PDF FILE OF THE
8086 MONITOR (Using DS12887 Clock Chip+ Lava Output) (V10.33a
MOST CURRENT VERSION OF THE 8086 MONITOR SOFTWARE (Using DS12887 Clock Chip+Lava
and Documentation (2/8/2013)
This page was last modified