Skip to content
/ mon86 Public

Intel 8086 monitor for embedded development

Notifications You must be signed in to change notification settings

mfld-fr/mon86

Repository files navigation

*** WORK IN PROGRESS ***


MON86 is yet another monitor for a 8086/8088/80186/80188 based system.

That old 16 bits processor architecture is still used today in some devices
(SBC, MCU, SoC, FPGA, etc) that reuse the huge hardware and code base from
the legacy and popular PC/XT/AT platform to build embedded systems.

The monitor is a tool used on such embedded systems to take control of the
target just after booting, and before loading / executing a more complex
software like a native application or an operating system.

It provides basic functions, such as read / write the registers, read / write
the memory, and execute code. It also allows to trace instructions, or to use
the break instruction, when acting as a master task.

MON86 is either loaded into the target RAM by the bootloader from any suitable
device, or burned into the EEPROM / Flash for direct execution.

It communicates with the development system through the simplest and available
interface (typically the asynchronous serial port), and with a simple and human
readable protocol.

Since that protocol only supports basic operations, the monitor could be in
turn drived from the development system by some utilities, to implement more
complex and user-friendly commands, like loading and run an executable.


SERIAL COMMUNICATION PROTOCOL

The monitor receives ASCII characters from the serial interface and groups them
by tokens. All characters are converted to uppercase. The tokens are separated
by at least one space (any character code <= 32 is translated into a space).

Each token is either an immediate value as an hexadecimal number (4 digits max,
without any prefix nor suffix), or a command with a concatenated prefix letter,
and a suffix hexadecimal digit.

The commands are:
	A-F  (reserved for immediate value)
	O    Set the offset
	S    Set the segment
	L    Set the length (reserved)
	R    Read byte from [segment:offset]
	W    Write byte to [segment:offset]
	Ji   Get the register (i)
	Ki   Set the register (i)
	P    Call the far procedure at [segment:offset]
	T    Execute the slave task
	Z    (reserved for status)

Possible values for the (i) index register:

	0    AX
	1    CX
	2    DX
	3    BX
	4    SP
	5    BP
	6    SI
	7    DI
	8    ES
	9    CS
	A    SS
	B    DS
	C    IP
	D    FL
	E-F  (reserved)

A command uses the previous immediate value, which is saved to avoid repeating
it for the next command.

After each immediate value or command, the monitor writes a status with the same
format as a command, with the 'Z' prefix:

	Z0   success
	Z1   end of stream
	Z2   bad token length
	Z3   bad token value
	Z4   bad index
	Z5   slave interrupted by trace (INT 01h)
	Z6   slave interrupted by break (INT 03h)
	Z7   slave returned by RETF or IRET

Example 1: read 3 bytes from [1234h:5678h] that contains bytes AAh, BBh and CCh:
'1234 S 5678 O R R R' returns 'Z0 Z0 Z0 Z0 AA Z0 BB Z0 CC Z0'

Example 2: write 3 bytes AAh, BBh and CCh to [1234h:5678h]
'1234 S 5678 O AA W BB W CC W' returns 'Z0 Z0 Z0 Z0 Z0 Z0 Z0 Z0 Z0 Z0'

Example 3: call far procedure at [1234h:5678h]
'1234 S 5678 O P' returns 'Z0 Z0 Z0 Z0 Z0'

Example 4: start slave in trace mode at [1000h:0] with data/stack in segment 2000
'2000 K8 KA KB 1000 K9' sets CS=1000h and DS=ES=SS=2000h
'0 K4 KC'               sets IP=SP=0
'100 KD T'              sets TF flag and start slave


MASTER AND SLAVE TASKS

In order to minimize as much as possible the side-effect of the monitor on the
the tested code, it can acts as a master that controls a slave task, each of
them having their own execution context. Context switching is performed with
the help of the trace / break 8086 interrupts (INT01h and INT03h).


CONTEXT SWITCHING

Context registers are saved on the top of the task stack, following an order
that eases the context switching and the interrupt handling. For the slave,
they are followed by the master return address, to allow to terminate and to
give control back to the master through a simple RETF / IRET.

Stack before SS:SP switch:

	Offset  Register or value
	00h     AX
	02h     CX
	04h     DX
	06h     BX
	08h     SP (dummy)
	0Ah     BP
	0Ch     SI
	0Eh     DI
	10h     ES
	12h     DS
	14h     pointer to interrupt number
	16h     IP slave
	18h     CS slave
	1Ah     FL slave
	1Ch     IP master
	1Eh     CS master
	20h     FL master

Remaining of the context data is stored in a static structure pointed by the
vector [0:3FCh] (INT FFh):

	Offset  Register or value
	00      magic as NOP IRET to protect against INT FFh
	02      SP slave
	04      SS slave
	06      SP master
	08      SS master
	0A      slave run flag
	0B      slave returned flag

About

Intel 8086 monitor for embedded development

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published