SCMon-v1-0-userguide-e1-0-0
SCMon-v1-0-userguide-e1-0-0
Monitor
User Guide
1
API function $06, output line............................................................................49
API function $07, output new line.................................................................... 50
API function $08, get version details................................................................ 51
API function $09, claim jump table entry..........................................................53
API function $0A, delay.................................................................................... 55
API function $0B, output embedded message.................................................. 56
API function $0C, read jump table entry........................................................... 58
API function $0D, select console input/output device....................................... 59
API function $0E, select console input device....................................................59
API function $0F, select console output device................................................. 59
API function $10, input a character from the specified device.......................... 60
API function $11, output a character to the specified device............................ 60
API function $12, poll idle events......................................................................61
API function $13, configure idle events.............................................................62
API function $14, timer 1 event set up..............................................................63
API function $15, timer 2 event set up..............................................................63
API function $16, timer 3 event set up..............................................................63
API function $17, output port initialise............................................................. 64
API function $18, write to output port..............................................................64
API function $19, read from output port.......................................................... 64
API function $1A, test output port bit...............................................................64
API function $1B, set output port bit................................................................ 64
API function $1C, clear output port bit............................................................. 64
API function $1D, invert output port bit........................................................... 64
API function $1E, input port initialise............................................................... 65
API function $1F, read from input port............................................................. 65
API function $20, test input port bit................................................................. 65
API function $21, set baud rate........................................................................ 66
API function $22, execute command line..........................................................67
API function $23, get pointer to command line................................................ 68
API function $24, skip delimiter in command line............................................. 68
API function $25, skip non-delimeters in command line....................................68
API function $26, get hexadecimal parameter from command line.................. 68
API function $27, get current console device numbers......................................69
API function $28, get top of free memory.........................................................70
API function $29, set top of free memory......................................................... 70
SOURCE CODE AND ASSEMBLY.................................................................................... 71
Small Computer Workshop...............................................................................71
Customising the Small Computer Monitor........................................................ 72
Memory Map................................................................................................... 72
TARGET HARDWARE..................................................................................................74
Hardware type 1: Small Computer Workshop Simulator (Z80)..........................74
Hardware type 2: Small Computer Development Kit (Z80)................................74
2
Hardware type 3: RC2014................................................................................ 75
Hardware type 4: SC101...................................................................................76
Hardware type 5: LiNC80................................................................................. 76
Hardware type 6: Tom’s SBC............................................................................ 76
Bugs, Quirks, Limitations and To do list............................................................ 78
Bugs.................................................................................................................78
Quirks.............................................................................................................. 78
Limitations.......................................................................................................78
To do list.......................................................................................................... 78
HISTORY................................................................................................................. 79
FUTURE PLANS........................................................................................................ 81
CONTACT INFORMATION............................................................................................ 82
LiNC80............................................................................................................. 82
RC2014............................................................................................................ 82
SC101...............................................................................................................82
Tom’s SBC........................................................................................................ 82
3
Overview
The Small Computer Monitor is a classic machine code monitor enabling debugging
of programs and general tinkering with hardware and software. It can also act as a
boot ROM, so no other software is required on the target computer system.
The Monitor includes a capable debugging environment with the following features:
Boot loader to load Intel HEX files from a PC or similar
Memory display and editing
Register display and editing
In-line disassembler
In-line assembler
Breakpoint debugging
Single step debugging (without the need for special hardware)
The monitor can be modified for different hardware and can be compiled with only
the basic features in order to fit in a small ROM.
An executable file version of the Small Computer Monitor can also be compiled, thus
allowing it to be run from a storage device rather than from ROM.
The standard releases of the Monitor are implemented without using interrupts,
thus leaving them free for applications and additional device drivers.
The Monitor can be extended by adding extra ‘Apps’ in the ROM using the Monitor’s
ROM filing system. These extensions are automatically integrated into the Monitor.
The ROM filing system works across multiple ROM banks on systems where ROM
banks can be selected in software.
This document describes the Small Computer Monitor as configured for any of the
following systems:
LiNC80 (available in kit form)
RC2014 (available in kit form)
4
Conventions
Within this guide hexadecimal numbers are prefixed by either ‘$’ or ‘0x’, unless the
number is a command parameter. Command parameters default to hexadecimal, so
no prefix is required.
Serial port
The default configuration is to use a terminal or terminal emulation software to
communicate with the target hardware running the Small Computer Monitor
program.
The primary serial port is usually set for 115200 bits per second (assuming the clock
is 7.3728 MHz), 8 data bits, 1 stop bit, no parity, no flow control (hardware flow
control is optional and system dependent). Line termination is Carriage Return ($0D)
plus Line Feed ($0A). There should not normally be any need to add delays when
sending characters to the target.
LiNC80 systems
The LiNC80 is an open system and can thus have diverse hardware, although the
main board is pretty well equipped on its own. The Small Computer Monitor
program is designed to work with the official modules, and may not work with third
party modules.
The standard ROM for the LiNC80 contains the Small Computer Monitor, Grant
Searle’s adaptation of Microsoft BASIC and a CP/M loader for Compact Flash. This all
fits in the first ROM bank (16k bytes). In the second ROM bank it has a version of
Grant Searle’s monitor/loader system for BASIC and CP/M.
The default console device is usually the second serial port (SIO B) and it is usually
initialised to 115200 baud, 8 data bits, 1 stop bit, no parity, hardware flow control.
The other serial port (SIO A) is usually initialised to 9600 baud, 8 data bits, 1 stop bit,
no parity, hardware flow control.
The default console device can be changed by writing the required device number to
locations 0x0040 of the ROM.
The default baud rates can be changed by writing the required baud rate codes to
locations 0x0041(SIO port A) and 0x0042 (SIO port B) of the ROM. The SIO clock
source jumpers must be set to the CTC in order for these baud rates to be used.
The Small Computer Monitor for LiNC80 does not use Interrupts.
5
RC2014 systems
The RC2014 is an open system and can thus have diverse hardware. The Small
Computer Monitor program is designed to work with the official modules, and may
not work with third party modules.
Configuration R1 contains just the Small Computer Monitor and runs on all standard
RC2014 kits (Mini, Classic, Plus and Pro). It fits in an 8k byte ROM which is mapped
into memory from address $0000 to $1FFF. It requires RAM from $FD00 to $FFFF,
leaving the rest free for the user. The ROM is not paged out of memory during
operation.
The default console device is the first serial port detected and it is usually initialised
to 115200 baud, 8 data bits, 1 stop bit, no parity, no flow control.
The default console device can be changed by writing the required device number to
locations 0x0040 of the ROM.
The Small Computer Monitor for RC2014 does not use Interrupts.
6
Commands
The Small Computer Monitor is designed to be used with a simple serial terminal or
terminal emulation software. Commands are therefore typed in plain text and
results are displayed on the terminal.
Parameters are shown, in this document, enclosed by “<” and “>”, and further
enclosed by “[“ and “]” if the parameter is optional. So “E [<start-address>]”
describes a command “E” with the start address as an optional parameter.
Command names and any parameters are delimited by a space character. Single
letter commands are the exception as they do not require a space between the
single letter command and the first parameter.
Monitor commands are not case sensitive, so can be typed in either upper or lower
case, or any combination of upper and lower case.
In the examples below, user input is in a Bold Italic font, while the results are shown
in a Regular font. Special key presses, such as Escape, are shown enclosed in curly
brackets. Thus the example below means the user types “b 5000” followed by the
Return key, and the monitor displays “Breakpoint set”.
b 5000 {return}
Breakpoint set
Unless otherwise stated, parameters are hexadecimal numbers, such as FF12. There
is no need to prefix them with a hexadecimal identifier or a numeric character. The
exception to this rule is some operands in the assembler need a prefix.
7
? or Help
Syntax: HELP
Or syntax: ?
This displays a list of the monitor commands together with their syntax.
For example:
help {return}
Small Computer Monitor by Stephen C Cousins (www.scc.me.uk)
Version 1.0.0 configuration L1 for Z80 based LiNC80 systems
Monitor commands:
A [<address>] = Assemble | D [<address>] = Disassemble
M [<address>] = Memory display | E [<address>] = Edit memory
R [<name>] = Registers/edit | F [<name>] = Flags/edit
B [<address>] = Breakpoint | S [<address>] = Single step
I <port> = Input from port | O <port> <data> = Output to port
G [<address>] = Go to program
BAUD <device> <rate> | CONSOLE <device>
FILL <start> <end> <byte> | API <function> [<A>] [<DE>]
DEVICES, DIR, HELP, RESET
The configuration identifier, ’L1’ in the above example, indicates which build this
code is. One source code version can be tailored by conditional assembly for
different configurations. Each of these configurations has a unique configuration
identifier. Some configuration identifiers refer to the same hardware but with
different options, such as different memory locations. So a ROM version may have a
different identifier to a soft-loading version.
Minor configuration identifiers, the numeric character, indicate the build variant.
8
API function call
Syntax: API <function number> [<A register value>] [<DE register value>]
This command enables API functions to be called from the monitor prompt.
On completion of the API function the monitor displays the returned value of the
register A and the register pair DE.
API 1 {return}
Nothing happens until a character is available from the console input device, which
is a long winded way of saying nothing happens until you press a key. If the letter “a”
is pressed the monitor displays:
61 0021
To output a pling character (“!”), which has ASCII value $21, enter the command:
API 2 21 {return}
!21 0021
9
Note the pling character (“!”) is displayed before the returned register values.
The first thing to do is to specify which port you wish to control. This is done by
calling API function $17 with the port number in the A register. In this example the
port address used is $00, thus the API command is:
API 17 0 {return}
00 0000
Api 1B 2 {return}
04 0002
There is also a set of API functions for handling a simple input port.
10
Assemble instructions
Syntax: A [<memory address>]
The memory address parameter is optional. If supplied the assembler begins at the
specified address. If not, the last referenced address is used instead.
The user may then enter a new instruction mnemonic and operands which is
assembled into machine code and entered into memory at the address shown. The
new instruction is then displayed in the format specified above, and the next
instruction displayed.
For example:
A 8000 {return}
8000: C3 56 10 .V. JP $1056 >
8003: 00 . NOP > ld a,12 {return}
8003: 3E 12 >. LD A,$12
8005: 00 . NOP >
Instead of entering a new instruction, the user can press {return} to move to the
next instruction, or {escape} to exit the assembler and return to the monitor prompt.
Entering a period character (“.”) followed by {return} also exits the assembler.
The delimiter between the operation and the first operand must be a space, while
the delimiter between operands can be a comma or a space.
The assembler supports all the documented Z80 instructions and uses standard Zilog
mnemonics. A good reference document is Zilog’s Z80 CPU User Manual, just search
for “zilog um0080”.
11
To clarify that a hexadecimal number is intended, and not a register name, it is
sometimes necessary to ensure the first character is numeric (ie. 0 to 9, not A to F).
So prefixing B with a zero clarifies it is intended to be a hexadecimal number.
For example:
When entering the address for a relative jump, the address can be either the
displacement or the absolute address. An address of $00 to $FF is treated as a
displacement, while an address of $0100 to $FFFF is treated as an absolute address.
Absolute addresses must be within range of a relative jump or an error message will
be shown.
For example:
a 8010 {return}
8010: 00 . NOP > jr 30
8010: 18 30 .0 JR $30 (to $8042)
8012: 00 . NOP > jr 8010
8012: 18 FC .. JR $FC (to $8010)
8014: 00 . NOP > jr 9999
Bad parameter
8014: 00 . NOP >
12
Baud rate setting
Syntax: BAUD <device identifier> <baud rate code>
Not all systems have software selectable baud rates. Some have their baud rates set
in hardware with jumpers, while others may have a single fixed rate.
The first parameter is the device identifier. This can be the console device number
from 1 to 6, or the letter ‘A’ or ‘B’ for the two channels of a typical Z80 SIO device.
The second parameter is the baud rate code. This can either be a number from $1 to
$C, representing the 12 baud rate options, or it can be the first two digits of the
baud rate, such as $96 for 9600 baud.
13
Breakpoint set or clear
Syntax: B [<memory address>]
To set the breakpoint, enter the command ‘B’ followed by the address at which the
breakpoint should be set. The breakpoint can only be set in random access memory
(RAM), not in read only memory (ROM). Only one breakpoint is provided.
For example:
b 8000 {return}
Breakpoint set
To clear the breakpoint, enter the command ‘B’ with or without an address. If no
address is specified the current breakpoint is cleared. If an address is specified the
current breakpoint is cleared and then the new breakpoint is set.
For example:
B {return}
Breakpoint cleared
To continue execution after a breakpoint, use the “Go” command without specifying
an address. Just enter G {return}.
Breakpoints (and single stepping) work by replacing the instruction in memory with
the instruction RST 28. This causes a call to the Monitor to handle the breakpoint (or
step). If a RST 28 instruction is encountered that is not there as a breakpoint or step
instruction, program execution stops and “Trap” is displayed.
14
Console
Syntax: CONSOLE <device identifier>
The Small Computer Monitor supports a number (currently 6) of console style input
and output devices. This command allows selection of which one is the current
console device and thus provides input and output for the monitor’s command line
interpreter.
Devices are numbered 1 to 6, with the first two often also having alternative
identifiers of “A” and “B”.
The Monitor sets a suitable default console device at reset. However, this can be
changed in the ROM by writing the required device number ($01 to $06) to address
$0040.
The Hardware section of this guide details the supported ports and their console
device numbers.
If you have two serial ports with a terminal connected to each, you can swap
between them with the commands “Console 1” and “Console 2” (or “Console 3”
depending on your hardware configuration).
There is also an API function to select the console device from within software.
15
Devices
Syntax: DEVICES
For example:
Devices {return}
1 = Z80 SIO port A (@80)
2 = Z80 SIO port B (@82)
3 = 6850 ACIA #2 (@40)
The Small Computer Monitor can detect the presence of some hardware devices and
includes driver software to support them.
The real reason for this feature is to support a range of serial interfaces and the
variety of configurations found on modular and expandable computer systems. By
detecting the presence of these devices the Small Computer Monitor can configure
itself to use whichever devices are available and thus avoid the need for multiple
versions of this program.
In addition to using whichever serial device is detected for its own input and output,
the Small Computer Monitor passes on this benefit to any software that makes use
to the Monitor’s API.
When the ACIA device is detected the Small Computer Monitor initialises it for
115200 bits per second (assuming the clock is 7.3728 MHz), 8 data bits, 1 stop bit,
no parity, no flow control, no interrupts. It is then configured as the console input
and output device.
When the SIO device is detected the Small Computer Monitor initialises the system’s
default channel, usually to 115200 bits per second (assuming the clock is 7.3728
MHz), 8 data bits, 1 stop bit, no parity, flow control is system dependent , no
interrupts. It is then configured as the console input and output device. The other
channel is initialised at reset, but is not used unless the user selects it as the console
device. It is therefore free to be configured and used as required.
16
Directory file list
Syntax: DIR
Or syntax: ROM
The Small Computer Monitor can include a ROM filing system. This command lists
the files found in the ROM.
For example:
DIR {return}
Monitor .EXE
BASIC .COM
WBASIC .COM
BASIC .HLP
CPM .COM
CPM .HLP
If the system provides multiple banks of ROM, the Monitor searches them all for
files.
Command (COM) files are used to extend the Small Computer Monitor. These can
not normally be used by other installed software as they usually depend on the
presence of the Small Computer Monitor. Due to their dependence on the Monitor
they must either be in the same ROM bank or be relocated to RAM before being run.
Executable (EXE) files can be run from the Monitor’s command line, but they do not
otherwise make use of the Monitor’s facilities. They are standalone programs that
can run without the Monitor and thus can be started from other installed software.
Software in ROM that can be used to “boot” the system, such as the Small Computer
Monitor itself, are EXEcutable files.
17
Disassemble instructions
Syntax: D [<memory address>]
For example:
d 1066 {return}
1066: C3 03 FF ... JP $FF03
1069: 31 80 FE 1.. LD SP,$FE80
106C: 11 00 00 ... LD DE,$0000
106F: 21 00 10 !.. LD HL,$1000
1072: 01 69 00 .i. LD BC,$0069
1075: ED B0 .. LDIR
After the block of instructions is shown, the user can press {return} to display the
next block, or {escape} to exit the disassembler and return to the monitor prompt.
Alternatively, a new command can be entered without first returning to the monitor
prompt.
The disassembler supports all the official documented Z80 instructions and uses
standard Zilog mnemonics. Invalid op-code sequences are displayed as “????”.
When disassembling a relative jump instruction, both the displacement and the
absolute address is shown:
d 5010 {return}
5010: 18 30 .0 JR $30 (to $5042)
18
Edit memory
Syntax: E [<memory address>]
The memory editor is presented in a similar way to the assembler, but instead of
entering instruction mnemonics you enter hexadecimal or ASCII values.
The memory address parameter is optional. If supplied the editor begins at the
specified address. If not, the last referenced address is used instead.
The user may then enter new memory contents, press {return} to move to the next
instruction, or {escape} to exit the editor and return to the monitor prompt. Entering
“^” followed by the return key causes the editor to go back one location. Entering a
period character (“.”) followed by {return} also exits the memory editor.
Hexadecimal numbers are entered without the need to clarify as hexadecimal. ASCII
characters are entered by preceding with a quote character.
For example:
e 8040 {return}
8040: 00 . NOP > 3e ff
8042: 00 . NOP > "Hellp
8047: 00 . NOP > ^
8046: 70 p LD (HL),B > "o
8047: 00 . NOP >
19
Fill memory
Syntax: FILL <first address> <last address> <data byte>
Use this command to fill an area of memory with a specified data byte.
It is unlikely the memory will be totally clear, but if it were then a memory display
command would look something like this.
m 8000 {return}
8000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
8010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
8020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
8030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
8040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
8050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
8060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
8070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
We could then enter a fill command to write a specified value, in this case $55, to a
range of memory locations, in this case $8010 to $801F.
We should then be able to see the result by issuing another memory display
command.
m 8000 {return}
8000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
8010: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUUUUUU
8020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
8030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
8040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
8050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
8060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
8070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
20
Flags display or modify
Syntax: F [<name>]
f {return}
PC:0001 AF:00D7 BC:0003 DE:0004 HL:0005 IX:0006 IY:0007 Flags:SZ-H-PNC
The flags register is shown in hexadecimal as part of the AF register pair and also as
individual flag bits. If the flag letter is shown, the flag is set, otherwise is it clear.
Valid parameters include the flag letter (eg. “Z”), the flag letter prefixed with “N” (eg.
“NZ”) and the ‘condition’ in conditional instructions (eg. “PO” in “JP PO, <address>”).
Thus there are several ways to reference the flags. Due to a conflict between
Positive (P) and Parity (P), the parity flag is set with “Pa”, not just “P”.
The table below shows valid flag names in square brackets and valid condition
names in curly brackets and valid .
f z {return}
PC:0001 AF:0042 BC:0003 DE:0004 HL:0005 IX:0006 IY:0007 Flags:-Z----N-
21
Go to program
Syntax: G [<memory address>]
If the program being executed is written as a subroutine, whereby it ends with a RET
(return) instruction, then at the end of the program, control is passed back to the
monitor and a monitor prompt is displayed. If the program does not return then
control does not pass back to the monitor until the system is reset or a breakpoint is
encountered. Of course if the program has a problem and crashes then anything can
happen!
In the example below the test program runs until the breakpoint is reached.
a 8000 {return}
8000: 00 . NOP > ld a,55 {return}
8000: 3E 55 >. LD A,$55
8002: 00 . NOP > ret {return}
8002: C9 . RET
d 8000 {return}
8000: 3E 55 >. LD A,$55
8002: C9 . RET
r {return}
PC:0000 AF:0002 BC:0003 DE:0004 HL:1234 IX:0006 IY:0007 Flags:------N-
SP:FE7E AF'0012 BC'0013 DE'0014 HL'0015 (S)0016 IR:0017 Flags'---H--N-
b 8002 {return}
Breakpoint set
g 8000 {return}
Breakpoint
PC:8002 AF:5502 BC:0003 DE:0004 HL:1234 IX:0006 IY:0007 Flags:------N-
22
Input from port
Syntax: I <port address>
The specified input port address is read and the result displayed in hexadecimal.
For example:
I F0 {return}
00
The Z80 has a separate address range for input/output (I/O) devices, together with
separate processor instructions to access them. This command addresses devices in
the I/O space, not the memory space. Generally the I/O space is limited to 256
addresses ($00 to $FF).
Users of the official LiNC80 digital I/O card can typically read the switch inputs with
the command:
I 30 {return}
Users of the official RC2014 digital I/O card can typically read the switch inputs with
the command:
I 0 {return}
23
Memory display
Syntax: M [<memory address>]
A block of memory is displayed, with each line showing the memory address in
hexadecimal, the contents of sixteen memory locations in hexadecimal, and the
contents of those sixteen memory locations in ASCII. Non-printable ASCII characters
are shown as dots.
The memory address parameter is optional. If supplied the memory will be displayed
starting at the specified address. If not, the memory display starts from the last
address referenced.
For example:
m 1080 {return}
1080: 19 10 F9 3E 00 11 AC 10 CD 83 19 3E 01 11 AE 10 ...>.......>....
1090: CD 83 19 CD C1 24 CD 90 17 11 B0 10 CD 50 18 CD .....$.......P..
10A0: D8 24 31 80 FE CD 3F 11 C3 22 12 C9 ED 4D ED 45 .$1...?.."...M.E
10B0: 05 05 53 6D 61 6C 6C 20 43 6F 6D 70 75 74 65 72 ..Small Computer
10C0: 20 4D 6F 6E 69 74 6F 72 20 62 79 20 53 74 65 70 Monitor by Step
10D0: 68 65 6E 20 43 20 43 6F 75 73 69 6E 73 05 56 65 hen C Cousins.Ve
10E0: 72 73 69 6F 6E 20 30 2E 31 2E 32 20 66 6F 72 20 rsion 0.1.2 for
10F0: 00 50 43 3A 2C 41 46 3A 2C 42 43 3A 2C 44 45 3A .PC:,AF:,BC:,DE:
Pressing {escape} will exit the memory display mode and return to the monitor
prompt.
Alternatively a new command can be entered without first returning to the monitor
prompt.
24
Output to port
Syntax: O <port address> <data byte>
The specified data byte is written to the specified output port address.
For example:
O F0 5 {return}
The Z80 has a separate address range for input/output (I/O) devices, together with
separate processor instructions to access them. This command addresses devices in
the I/O space, not the memory space. Generally the I/O space is limited to 256
addresses ($00 to $FF).
Users of the official LiNC80 digital I/O card can typically write to the LED outputs
with the command:
O 30 5 {return}
Users of the official RC2014 digital I/O card can typically write to the LED outputs
with the command:
O 0 5 {return}
In the above examples the value 5 is written to the LED output latch. In binary the
number 5 is 00000101, thus bits 0 and 2 are ON. This results in LED 0 and LED 2
lighting up.
25
Registers display or edit
Syntax: R [<name of register>]
This command can either display the current processor registers or edit the value of
a processor register.
For example:
r {return}
PC:0001 AF:0002 BC:0003 DE:0004 HL:0005 IX:0006 IY:0007 Flags:------N-
SP:0011 AF'0012 BC'0013 DE'0014 HL'0015 (S)0016 IR:0017 Flags'---H--N-
When the optional parameter is entered, the specified register can be edited.
26
For example:
r hl {return}
HL: 0005 1234 {return}
In the above example the HL register pair is specified. The current value of HL is
displayed (0005) and the user can either enter a new value for HL (1234), or press
{escape} to leave the register unchanged. Entering the command “r” now shows the
updated registers:
r {return}
PC:0001 AF:0002 BC:0003 DE:0004 HL:1234 IX:0006 IY:0007 Flags:------N-
SP:0011 AF'0012 BC'0013 DE'0014 HL'0015 (S)0016 IR:0017 Flags'---H--N-
27
Reset
Syntax: RESET
This command performs a software reset, similar to pressing the reset button.
It can not perform a physical hardware reset on the electronics, but it does run the
same software as a hardware reset.
All execution stops, including interrupt routines. The monitor then restarts.
The Small Computer Monitor outputs a sign-on message to the console output
device (usually a terminal) followed by the monitor prompt character (‘*’). For
example:
28
Step one instruction
Syntax: S [<memory address>]
Pressing the Return key then causes a single instruction to be executed, and the
resulting processor registers and flags to be displayed.
Pressing {return} again will step another instruction and again display the processor
state.
Pressing {escape} will exit single stepping mode and return to the monitor prompt.
Alternatively a new command can be entered without first returning to the monitor
prompt.
s 8000 {return}
PC:8000 AF:0040 BC:125C DE:FF86 HL:8000 IX:2034 IY:0007 Flags:-Z------
8000: 3E 02 >. LD A,$02
PC:8002 AF:0240 BC:125C DE:FF86 HL:8000 IX:2034 IY:0007 Flags:-Z------
8002: CD 10 80 ... CALL $8010
PC:8010 AF:0240 BC:125C DE:FF86 HL:8000 IX:2034 IY:0007 Flags:-Z------
8010: 3C < INC A
PC:8011 AF:0300 BC:125C DE:FF86 HL:8000 IX:2034 IY:0007 Flags:--------
8011: C9 . RET
PC:8005 AF:0300 BC:125C DE:FF86 HL:8000 IX:2034 IY:0007 Flags:--------
8005: C9 . RET
Similarly, calls into the monitor code are stepped over. This means calling the
Monitor’s API appears as just one step and not hundreds.
29
When a call into read only memory or monitor code occurs, the message: “Stepping
over code in ROM or in monitor” is displayed.
Single stepping (and breakpoints) work by replacing the instruction in memory with
the instruction RST 28. This causes a call to the monitor to handle the step (or
breakpoint). If a RST 28 instruction is encountered that is not there as a breakpoint
or step instruction, program execution stops and “Trap” is displayed. Single stepping
can not pass a “Trap” instruction.
30
Hex File Loader
The Small Computer Monitor includes a means of receiving an Intel Hex File from
the serial port.
Terminal programs usually have a feature called “Send text file” (or similar). This
opens a file on the PC and ‘sends’ it to the target as if it were typed in on the
terminal.
Some terminal programs allow text to be ‘Pasted’ into the terminal as if typed in.
This can be a convenient way of taking a Hex File from another program and sending
it to the target system.
Assemblers usually have a means of creating an Intel Hex File, thus it is quick and
easy to author a program on a PC and send it to target hardware running the Small
Computer Monitor.
:1040000021354006090E80EDB3061A3E41F5DB80EE
:10401000CB5728FAF1D3813CCD2A4010F0DB80CB7E
:104020004728FADB81D38118F4C9F5C50E0911645C
:1040300000F7C1F1C91814C403C105681100FFFFDE
:00000001FF
When the Small Computer Monitor has received the whole file it displays either
“Ready” or “File error”. If it appears to hang it is probably because it has not
received the correct file termination sequence.
It is not usually necessary to set the terminal to add any delays as it sends the
characters, as the monitor can handle hex file loading at a continuous 115200 bits
per second when the processor is running at 7.3 MHz.
31
Self-test
The Small Computer Monitor has a simple self-test feature which runs at reset.
To see the output of the test you need a status display port. This is usually a simple
output port with 8 LEDs connected. Without this module the test may still help
when using an oscilloscope for fault finding as the sequence is simple and repeats if
no RAM is found.
The status display port for the LiNC80 is the optional digital I/O module, or
equivalent, and this must have its output port set to the default address of $30.
The status display port for the RC2014 is the optional digital I/O module, or
equivalent, and this must have its output port set to the default address of $00.
As long as the power, processor, clock and bus are basically sound the self-test
should run. It does not depend on working RAM or a working serial port.
At reset the self-test flashes each LED on the status display port in turn. This takes
about half a second to complete. If the LEDs flash in sequence you know the power,
processor, bus, ROM and clock are basically working.
After that it does a very limited RAM test. It only tests a few locations, but probably
enough to spot a serious fault with the upper 32k of RAM. If it fails the LEDs repeat
their sequence and the test repeats, so constantly flashing LEDs indicate a RAM
fault.
If the RAM test passes then the LEDs are all turned off and the monitor tries to
identify the serial module. If this fails bit 0 LED is turned on to indicate the problem.
A pass through without failure will be indicated by all LEDs off (after the initial cycle)
and hopeful a message on the terminal. At this point, with or without a message on
the terminal, the other main modules look in good shape.
Other ROM based software, such as 32k MS BASIC, should stand a good chance of
running on a system that passes this test.
A pass without a sign on message on the terminal suggests the problem likely relates
to the serial interface or terminal.
32
If the LEDs don't even manage the initial sequence, it likely means the processor is
not running the code correctly so the fault could be on any of the main modules or
the bus, but hopefully it will be a good solid 'digital' fault.
It is worth stripping the system to the minimum at some point when trying the
self-test, so that only the processor, clock, ROM and status display port are present.
33
ROM Filing System
The Small Computer Monitor supports a simple read only Filing System designed to
allow data and program files to be stored in ROM.
To achieve this ROMs need to include a table of contents. Any ROM without this
table will not be able to share its files.
The table is stored at the top of each ROM or ROM bank, and contains one or more
file references. The first reference is stored in the top 16 bytes, the second reference
in the 16 bytes below that, and so on. The end of the table is determined by the
absence of the next logical reference.
For a system with multiple ROM banks, each 16k bytes long and starting at address
0x0000, the first file reference in the each bank is at 0x3FF0, the second at 0x3FE0,
and so on.
Each file reference has two identifier bytes providing a fairly reliable way of
determining if the block of 16 bytes is a file reference. Further checks can be made
by testing all eight bytes of the file name for valid characters (ASCII 0x20 to 0x7F).
The file name contains eight ASCII characters. File names shorter than eight
characters long have the unused trailing bytes filled with ASCII spaces (0x20). The
file name can contain characters A to Z, a to z, 0 to 9, underscore and hyphen. File
names must be at least two characters long so as not to conflict with single letter
monitor commands.
Each file reference also includes: file type, file attribute flags, file location and file
length.
34
File reference
Each file in the ROM Filing System requires a file reference as described below.
File types:
Flag bits:
35
File type and flags byte
The file type and flags byte specifies the file type (0 to 15) and four flags indicating
special attributes of the file.
File type 2 - Executable code that does not use the Monitor
The EXE file is for programs that run independently of the Monitor. These programs
are totally self contained and can be launched by any other software that is able to
scan the ROM Filing System and take the necessary action.
36
The following example shows how to include a CPM loader command.
37
BASIC
Grant Searle’s popular adaptation of classic Microsoft BASIC can run on all the retro
computer systems currently supported by the Small Computer Monitor.
The BASIC interpreter can either be in the same ROM as the Monitor, or
downloaded to RAM using a terminal program. Some configurations of the Monitor
ROM include BASIC, others do not. Use the Monitor’s Help command to see if BASIC
is included.
There are currently three builds of BASIC. The choice of which build to use depends
on the hardware configuration. In each case the BASIC interpreter is the same, it is
only the memory map which differs.
The first two are most likely to be in ROM along with the Monitor, while the third is
likely to be used as a download to RAM. If none of these are optimal, then the Small
Computer Workshop program can be used to build a more suitable configuration.
In each case the Monitor supplies the required hardware support. One of the
advantages of running from the Monitor is that BASIC inherits the Monitor’s range
of hardware support, such as different serial interfaces, and also has access to the
Monitor’s API.
38
Starting BASIC
The LiNC80’s standard ROM includes the Monitor and BASIC. The following brief
guide to using BASIC assumes this is the set up you are using.
To start BASIC from the Monitor, type the command “BASIC” and press the Return
key. You should see something like this:
BASIC {return}
Memory top?
The “Memory top” question allows you to enter the highest location in memory that
BASIC will use, thus allowing space to be set aside for,say, machine code routines. If
you just press Return, a suitable default is used.
There is plenty of support on the internet for this version of BASIC, so it is not being
duplicated here.
To return to BASIC from the Monitor, without clearing the BASIC program, use the
Monitor’s “WBASIC” command. That’s “W” for Warm start.
39
Using the Monitor’s API from BASIC
In order to access the Monitor’s API, the following steps are required.
DOKE the API entry point address to memory
POKE the API call number to memory
POKE or DOKE call parameters to memory
Call the API using the BASIC statement: N=USR(0)
PEEK or DEEK resulting values from memory
LIST {return}
10 DOKE &H4004,&H34: REM Set USR() call address *(see note below)
20 POKE &HFFF4,8: REM API function number 8
30 N=USR(0): REM call Monitor API
40 PRINT "Version ";PEEK(&HFFF7);".";PEEK(&HFFF6)
Ok
RUN {return}
Version 1 . 0
Ok
The table below shows the mappings of API registers to BASIC’s memory locations,
and memory access statements to access then.
40
CP/M
CP/M was a very popular operating system in the late 70s and 80s, and was available
for many different computers. Early versions of Microsoft’s DOS were essentially a
copy of CP/M.
Some configurations of the Small Computer Monitor include a CP/M loader. Use the
Monitor’s Help command to see if this feature is included.
The CP/M loader is just a loader. It is not CP/M. The loader looks for a Compact Flash
card and attempts to load CP/M from that, in much the same way MS-DOS is loaded
from disk. You therefore need a Compact Flash card with CP/M already installed on
it.
Installing CP/M on a Compact Flash card is beyond the scope of this guide. Suppliers
of retro computer kits provide documentation and a suitable version of CP/M. For
homebrew systems a good source of information is Grant’s Searle’s website at
http://searle.hostei.com/grant/cpm/
Assuming the CP/M loader is included in your configuration of the Monitor, and you
have a Compact Flash with a suitable version of CP/M already installed on it, plus a
Compact Flash interface on your retro system, then the command “CPM” should
start CP/M.
A>
Because CP/M is a complete operating system, it does not use the Monitor at all
once loaded. CP/M has its own device drivers and thus you need a version of CP/M
to match your hardware. If the Monitor works on your hardware, but CP/M does not,
it is most likely to be due to an incompatible version of CP/M or a faulty installation
of CP/M.
41
Application Programming Interface (API)
The monitor provides an Application Programming Interface (API) to enable other
software to use some of its features.
42
$24 Skip delimiter in command line
$25 Skip non-delimiter in command line
$26 Get hexadecimal parameter from command line
$27 Get current console I/O device numbers
$28 Get top of free memory
$29 Set top of free memory
To access these functions from a program, a CALL is made to address $0030¶ with
the function number in the C register. Any parameters and results are passed in
other registers.
Unless otherwise stated, calling any of these functions may result in registers AF, BC,
DE and HL being modified and therefore they may not contain the same value after
the function call as they did before the call. Registers IX IY I AF' BC' DE' HL' are not
modified (unless otherwise stated).
The Z80 processor has a special instruction to CALL a few specific addresses in
memory. This is called a Restart instruction and has the mnemonic RST.
RST 30 performs the same function as CALL $0030, but it does it with a single byte
instruction. It is therefore smaller and faster.
¶
Address $0030 and RST 30 only apply if the Small Computer Monitor is located at
the bottom of memory or the bottom of memory is RAM allowing the Monitor to
modify these locations.
If the Small Computer Monitor is not located at the bottom of memory, then the API
call address is the start of the Monitor + $0030. Thus if the monitor starts at address
$E000, the API call address is $E030.
However, if the monitor can write to lower memory, due to RAM being located
there and not ROM, then it is able to write the relevant jump instruction to location
$0030. In which case the CALL $0030 or RST 30 instructions can still be used.
43
API function $00, system reset
Parameters: A = Reset type
0 = Cold start monitor
1 = Warm start monitor
Returns: none
This function performs a system reset, either a cold start or a warm start.
A cold start is similar to pressing the reset button. It can not perform a physical
hardware reset on the electronics, but it does run the same software as a hardware
reset.
A warm start returns to the monitor prompt, but does not re-initialise hardware and
workspace.
A cold start terminates interrupts and stops the user program. The monitor then
restarts. Memory is not cleared, but essential variables are initialised.
The Small Computer Monitor outputs a sign-on message to the console output
device (usually a serial terminal). For example:
44
API function $01, input character
Parameters: none
Returns: A = Character input from console
This function waits for a character from the current console input device, usually a
serial terminal.
Example:
45
API function $02, output character
Parameters: A = Character to output to console
Returns: A = Character output to console
This function outputs the specified character to the current console output device,
usually a serial terminal.
The function does not return until the character has been output.
Example:
The above example causes a pling character (‘!’) to be output to the console.
By combining this example with the previous example, we can input a character
from the console and then output it to the console, thus enabling us to see what we
have typed. The example below repeats this process until the Return key is pressed.
46
API function $03, input status
Parameters: none
Returns: NZ flagged if an input character is available from the console
This function checks the status of the current console input device, usually a serial
terminal.
Example:
This function is provided to allow a program to run whilst checking regularly for an
input character. Using the input character function would not work well here as it
waits for a character, thus blocking further execution of the program until a
character is available.
47
API function $04, input line
Parameters: DE = Start of line in memory
A = Maximum size of line in memory
Returns: DE = Start of line in memory
A = Number of characters in the line
This function inputs a line of characters from the console input device.
The line contains any characters entered from the console input device until a
Carriage Return character (ASCII $0D) is entered. The line ends when the Carriage
Return is entered but does not include the Carriage Return character.
The line is input to memory starting at DE and is returned as a null (zero) terminated
list of characters. Register A sets the maximum size of the line in bytes, which must
include one byte for the null terminator.
On return the null (zero) terminated line of characters is stored in memory at the
requested location. This location is returned in DE. Register A contains the number
of characters in the line, excluding the null terminator.
For example:
After the line “hi” is entered, DE is $9000, A is $02 and the memory contains:
9000: 68 69 00
48
API function $05, input line default
Parameters: none
Returns: DE = Start of line
A = Number of characters in line
Input a line of characters from the console input device to the default line buffer.
The functions is similar to function 4, above, except the memory used is the memory
reserved for the monitor’s own line input. As a result the line will be overwritten
when characters are entered at the monitor prompt.
The benefit of using this function is that it does not require its own memory
allocation and the call is simpler:
49
API function $06, output line
Parameters: DE = Start of line in memory
Returns: none
This function outputs the specified line of characters to the output device.
The line of characters must be null (zero) terminated. The line is therefore in the
same format as the input line obtained with functions 4 and 5.
To embed a new line code into the string it is best to avoid specifically using Carriage
Return and/or Line Feed as the sequence varies with different hardware. The
monitor provides a special character to signify a new line. This is the constant
kNewLine which has the value 5. The above example can be modified to include a
cursor move to the start of the next line:
50
API function $07, output new line
Parameters: none
Returns: none
This function outputs a new line character sequence to the console output device.
This will cause the console’s cursor to move to the start of the next line. The
character or characters output will depend on the console device. Typically this will
be a Carriage Return and Line Feed (ASCII $0D, $0A).
A more complete example, below, outputs a ‘!’, then a new line, then another ‘!’.
51
API function $08, get version details
Parameters: none
Returns: D, E and A are the monitor source code version
D = Major, E = Minor, A = Revision
B, C are the configuration identifier
B = Major configuration identifier (ASCII character)
Letters are official release configurations
Numbers are development, user or custom
C = Minor configuration identifier (ASCII character)
Numbers 1 to 9 are official release configurations
Number 0 is a user or custom configuration
H and L are the target hardware ID
H = Primary ID, L = Options
This function returns details of the monitor code version, the configuration identifier
characters and the target hardware identifier.
The configuration identifier characters indicate which build this code is. One source
code version can be tailored by conditional assembly for different configurations.
Each of these configurations has a unique configuration identifier. Some
configuration identifiers refer to the same hardware but with different
configurations, such as different memory locations. So a ROM version may have a
different identifier to a soft-loading version.
All other upper case letters are reserved for official configurations of the Monitor.
52
L, bit 0 set if serial 6850 ACIA detected
L, bit 1 set if serial SIO/2 detected
L, bit 2 set if serial 6850 ACIA #2 detected
L, bit 3 to 7 = Not currently used, all cleared to zero
H=4 Small Computer 101
L, bit 0 set if serial 6850 ACIA detected
L, bit 1 set if serial SIO/2 detected
L, bit 2 set if serial 6850 ACIA #2 detected
L, bit 3 to 7 = Not currently used, all cleared to zero
H=5 LiNC80
L, bit 0 set if the on-board serial SIO/2 detected
L, bit 1 to 7 = Not currently used, all cleared to zero
H=6 Tom’s SBC
L, bit 0 set if the on-board serial SIO/2 detected
L, bit 1 to 7 = Not currently used, all cleared to zero
53
API function $09, claim jump table entry
Parameters: A = Entry number (0 to n)
DE = Address of function code
Returns: none
Some system features, such as console in and out, are redirected through a jump
table in RAM. This function enables these jump table entries to be set to jump to any
code required.
By changing the console input and output routines, any custom hardware can be
integrated into the monitor and used instead of the standard hardware.
54
If the monitor program is in ROM and that ROM is mapped to the very bottom of
memory, it is not possible to directly change the interrupt code for interrupt mode 1
and non-markable interrupts. This is because code for these interrupts must begin at
fixed locations in memory which happen to be very near the bottom of memory, just
where the ROM is! By redirecting these interrupts through the jump table it is
possible to configure your own interrupt handler. The same redirection feature is
provided to Restart instructions $08, $10, $18 which are used for console input and
output, and Restart $20, which is currently free to be used as required. Also Restart
instructions $28 (breakpoint handler) and $30 (API handler) are redirected through
this table.
In the example below, the console input routine is replaced by a new routine at
location $9000.
55
API function $0A, delay
Parameters: DE = Number of milliseconds delay
Returns: none
This function simply waits for the specified number of milliseconds to pass before
returning.
The delay is created by a simple software loop and during this time the processor is
not looking for key presses or any other activity. Therefore, unless the system is
using interrupts to capture such actions, they will be missed.
The delay time is dependent on the clock speed of the processor. If a non-standard
clock speed is used the delay time will be some multiple or fraction of DE
milliseconds.
This function assumes a processor clock speed is 7.3728 MHz. If the speed is
different from this then the delay times will be proportionally shorter or longer.
In this example there is a delay of 2 seconds before the monitor prompt is shown.
When entering this code with the assembler, the first instruction is “LD DE,+2000”.
The plus sign indicates a decimal number. Once entered this is shown in
hexadecimal as $07D0.
56
API function $0B, output embedded message
Parameters: A = Message number (0 to n)
Returns: none
This function outputs messages embedded in the Small Computer Monitor to the
console output device.
System messages
$00 Message = None (null)
$01 Message = “Small Computer Monitor ”
$02 Message = “Devices detected:”
$03 Message = <About this version of the monitor>
$04 Message = <List of hardware devices detected>
Monitor messages
$20 Message = “Bad command”
$21 Message = “Bad parameter”
$22 Message = “Syntax error”
$23 Message = “Breakpoint set”
$24 Message = “Breakpoint cleared”
$25 Message = “Unable to set breakpoint here”
$26 Message = Monitor commands Help text
$27 Message = “Feature not included”
$28 Message = “Ready”
$29 Message = “File error”
All the message end with a new line character sequence, except for message $00
and $01. Message zero outputs nothing.
The following example displays information about the Small Computer Monitor.
57
API function $0C, read jump table entry
Parameters: A = Entry number (0 to n)
Returns: DE = Address of function code
Some system features, such as console in and out, are redirected through a jump
table in RAM. This function enables these jump table entry addresses to be read.
See function $09 (claim jump table entry) for list of jump table functions.
58
API function $0D, select console input/output device
API function $0E, select console input device
API function $0F, select console output device
Parameters: A = Device number (1 to 6)
Returns: none
The Small Computer Monitor supports a number (currently 6) of console style input
and output devices. These functions allow selection of which one is the current
console input device and which one is the current console output device.
The current device is the one which provides input and/or output for the monitor’s
command line interpreter. It is also the one which, by default, is the input and
output for the user’s programs.
The first function selects the device which provides both console input and console
output, while the other two functions allow selection of just input or just output.
Device 1 is usually set as the default console device at reset. However, this can be
changed in the ROM by writing the required device number ($01 to $06) to address
$0040.
The Hardware section of this guide details the supported ports and their console
device numbers.
If you have two serial ports with a terminal connected to each, you can swap
between them with this function (or with the Console command).
59
API function $10, input a character from the specified device
Parameters: E = Device number (1 to 6)
Returns: A = Character input from the specified device (if there is one)
NZ is flagged if a character has been input
If the device is not able to accept the character the function returns with the Z flag
set. This can occur, for example, when a serial output device is busy.
In the example below the pling character (“!”) is output to device 4. If the device is
busy the request is repeated until in succeeds. If the specified device, in this case 4,
does not exist the API function will always return the failed status and this
subroutine will never complete.
60
API function $12, poll idle events
Parameters: none
Returns: none
The Small Computer Monitor supports a system of timer events which are generated
when the processor is otherwise idle.
When the system is doing such things as waiting for console input it can be set to
repeatedly poll the idle event handler. This looks for timer events and, when
appropriate, calls the user functions configured to handle them.
By doing this the Small Computer Monitor makes it easy to have simple background
task running. These timer events are really handy for activities like flashing lights.
There is a slight problem however. Small computers often don’t include a hardware
timer. As a result the time period of the events generated is not accurate. It is
reasonable when simply waiting for user input, but becomes very inaccurate under
less predictable conditions.
Fortunately the LiNC80 does have a hardware timer (a Z80 CTC) so event times are
usually pretty accurate. However, standard RC2014 systems do not.
This function allows events to be polled when the processor would otherwise be
busy for extended periods and thus not checking for events. To keep background
events running this call should be made regularly by any program which runs for
more than a few milliseconds. Even doing this the timer events will be very erratic
on systems without a hardware timer.
Fortunately not all activities that need regular processing require accurate timing. A
thermostatically controlled heating system, for example, would work just fine with
this kind of crude timing.
The following example shows the code required to poll background events.
Don’t forget when making any API calls the processor’s registers can be changed by
that call, so it may be necessary to store important registers before the call and
restore them after.
61
API function $13, configure idle events
Parameters: A = Event mode:
0 = Off (no events are detected)
1 = Timer events enabled
Returns: none
This function enables selection of the event mode. Mode zero is Off (no events are
detected). Mode one enables timer events.
Following a processor reset the event mode is zero, the Small Computer Monitor
does not look for events.
62
API function $14, timer 1 event set up
API function $15, timer 2 event set up
API function $16, timer 3 event set up
Parameters: A = Event time period
DE = Address of timer event handler
Returns: none
The Small Computer Monitor supports three event timers. This group of functions
enables these timers to be set up.
Timer 3 has a resolution of 100 milliseconds and can be set to a period of 100 to
25500 milliseconds (0.1 to 25.5 seconds).
When the specified timer event occurs the subroutine at address DE is called. This
subroutine should only be a short piece of code that does not keep the processor
busy for long. It must also preserve all the processor’s registers, with the exception
of AF and HL which are preserved automatically.
The timer events are only detected when event mode 1 is set by API call $13.
An explanation of the timer accuracy issue is given above (API function $12).
The following code inverts the state of bit 1 on the current digital output port:
To call this code every 0.5 seconds and thus repeatedly toggle the output bit, issue
these API calls:
API 16 5 8000 {return}
API 13 1 {return}
To first API call sets Timer 3 to run the code at $8000 every 5 x 100 milliseconds. The
second API call enables the timers. To stop the timers enter:
API 13 0 {return}
63
API function $17, output port initialise
Parameters: A = Output port address
Returns: A = Output port data byte (which will be zero)
This function sets the output port address to be used for subsequent output port
functions. The output port is cleared (all outputs low/off) by this call.
This set of functions allows a simple 8-bit output port, such as the LiNC80 or RC2014
digital I/O module’s LED port, to be manipulated.
64
API function $1E, input port initialise
Parameters: A = Input port address
Returns: A = Input port data byte
This function sets the input port address to be used for subsequent input port
functions.
This set of functions allows a simple 8-bit input port, such as the LiNC80 or RC2014
digital I/O module’s input port, to be accessed.
65
API function $21, set baud rate
Parameters: A = Device identifier ($1 to $6, or $A or $B)
E = Baud rate code
Returns: A = 0 if either parameter is invalid on the target system
Not all systems have software selectable baud rates. The LiNC80 does have software
selectable baud rates, while standard RC2014 systems do not.
Parameter A is the device identifier. This can be the console device number from $1
to $6, or $A or $B for the two channels of a typical Z80 SIO device.
Parameter E is the baud rate code. This can either be a number from $1 to $C,
representing the 12 baud rate options, or it can be the first two digits of the baud
rate, such as $96 for 9600 baud.
66
API function $22, execute command line
Parameters: DE = Pointer to command line string
Returns: A = 0 and Z flagged if command recognised and executed
Register pair DE points to a null terminated string, which the monitor attempts to
execute. Any monitor command can be specified.
G 9100 {return}
67
API function $23, get pointer to command line
Parameters: none
Returns: DE = Pointer to current location in command line string
The group of functions is designed to allow a Monitor extension App to read its
parameters from the command line that launched it.
Monitor extension Apps are included in the ROM and integrate themselves into the
Monitor. The BASIC interpreter is an example of a Monitor extension App.
Providing the App is in the same ROM bank as the Monitor, or is relocated to RAM
before running, it can use these APIs to read command line parameters. Such Apps
are listed as “.COM” programs, where “COM” stands for Monitor COMmands.
68
API function $27, get current console device numbers
Parameters: none
Returns: D = Current console output device (1 to 6)
E = Current console input device (1 to 6)
The currently selected console input and output device numbers are returned.
The input and output device will usually be the same, but they can be different.
Typically this function returns D = 1 and E = 1, indicating the current console device
for both input and output is device 1 (usually the first serial port).
69
API function $28, get top of free memory
Parameters: none
Returns: DE = Highest location not in use by the Monitor
These functions enable the top of free memory to be determined and also to be
changed.
The top of free memory is the highest location in RAM which is not being used by
the Monitor. Typically this will be $FBFF.
Any software that requires some private memory can lower this location with the
“set top of free memory” API, thus claiming some space. A device driver may wish to
do this.
70
Source Code and Assembly
The source code for the Small Computer Monitor is freely available. Assembling it
requires the Small Computer Workshop program which is now provided with the
Monitor source code.
The Small Computer Workshop program is available for download, but be warned it
is not finished, not everything works and it is rather buggy. Having said that it is still
the easiest way to modify the Small Computer Monitor.
Initially it was hoped that an assembler could be designed that could cope with all
variations of syntax and conventions. This however was deemed unrealistic due to
71
the extra code complexity it created and the problem caused by some mutually
exclusive features.
The final decision was to write the system in the way that provided the most
desirable features without creating unnecessary complications. The resulting
assembler is, ironically, not totally compatible with any other and thus exasperates
the very compatibility problem originally identified. However, it is also not
hampered by any restrictions such compatibility would have imposed.
The assembler has a ‘C’ style pre-processor which includes some special statements
relating to the development environment, such as #TARGET. It also supports a range
of IF.. ELSE.. END and INCLUDE statements to allow conditional assembly, which is
how it supports different builds of functionality options and target hardware options,
from the same source code.
Assembler directives are prefixed with a period (‘.’), such as “.ORG”. Assembler
directives include support for memory sections using “.CODE” and “.DATA”.
Local labels are supported. These begin with the ‘@’ character. These labels are local
to the most recent global label, allowing local labels to be reused in other functions.
There are quite a few local versions of the label “@Loop” in the source code!
However, it is possible to make small changes to the hex file before programming
the ROM, or to the image before running in RAM.
Location $0040 contains the default console device number. This can be any device
from $01 to $06. To select device 3 as the default console device, change this
location from its typical value of $01 to $03. The DEVICES command lists the
available devices. See commands CONSOLE and DEVICES for more details.
Location $0041 contains the baud rate code for console device 1, which is typically
port A of a Z80 SIO. The valid baud rate codes are listed in the monitor commands
section for the Baud command, and in the API section for the Set baud rate API.
Not all hardware supports software selectable baud rates.
Location $0042 contains the baud rate code for console device 2.
72
Memory Map
The Small Computer Monitor’s code can be assembled to almost anywhere in
memory and so can its workspace (in RAM). However, there are some locations in
the bottom of memory which have fixed uses and can not be moved.
The standard build places the monitor code starting at $0000 and currently extends
to nearly 8 kbytes. Workspace and stack is at the very top of memory from about
$FC00 to $FFFF.
The fixed locations at the bottom of memory are determined by the Z80’s special
features, namely hardware reset, restart instructions and interrupt service. These
addresses can fall within the monitor ROM or be in RAM.
If the monitor code is assembled to the bottom of memory, these special locations
are included in the monitor code and are thus set up as required. If the monitor is
assembled elsewhere in memory these locations must be in RAM and are written to
during initialisation to establish the required contents.
73
Target Hardware
The Small Computer Monitor can be built for a range of Z80 based computer
hardware and simulators.
The Monitor code can be run from ROM or RAM, and can be assembled to any
desired location. However, to fully utilise features such as its Application
Programming Interface (API) and Breakpoints it must either be running at the
bottom of memory (from location $0000 upwards) or the bottom of memory must
be in RAM to allow the monitor to write Jump instructions to key locations in the
range $0000 to $0068. Very simple Z80 hardware is likely to meet this requirement
by having ROM at location $0000. More sophisticated hardware will likely have ROM
at location $0000 but allow it to be paged out and replaced by RAM once the system
is up and running.
The Monitor makes use of one optional hardware feature; a simple input/output
port, with the output assumed to have 8 LEDs connected. The output port is used for
the self-test status display. The input and output ports are used as the default ports
for the API’s port functions.
The hardware does not need to support interrupts as the Monitor does not currently
use them. Thus interrupts are currently free for user programs and additional device
drivers.
Currently the Monitor’s full feature set occupies nearly 8k bytes of code space and
requires about 1000 bytes of RAM (including stack space). The code size can be
significantly reduced by excluding features like the in-line assembler.
74
Hardware type 3: RC2014
Type 3 hardware covers RC2014 systems using the Z80 processor. Official RC2014
modules are available from “Semachthemonkey” via Tindie:
https://www.tindie.com/stores/Semachthemonkey/
Z80 based RC2014 systems are supported provided they meet the ROM/RAM
requirements above and use one of the serial I/O modules listed below as the
primary connection to a terminal or terminal emulation software.
As all the currently available complete RC2014 kits (Mini, Classic, Plus and Pro) meet
these requirements the Small Computer Monitor is compatible with all of them. All
these kits provide a means of running the Small Computer Monitor from ROM,
whilst some also provide configurations suitable to run the Small Computer Monitor
in RAM.
The standard RC2014 build is designed to run from ROM starting at address $0000. It
is an 8 kbyte ROM image which supports the serial I/O modules listed below.
The Small Computer Monitor auto detects these modules so one version of the
Monitor code supports all of the above modules, although you can only have one of
these in the system, at the same base I/O address, at a time.
75
The optional status display port is at I/O address $00, which is typically the RC2014
digital I/O module. The output port of the digital I/O module has 8 LEDs connected
which light when the output is set to ‘1’ (a logic high). This module is also used by
default by the API port functions.
If the Small Computer Monitor is unable to identify a suitable serial module at reset
it turns On bit 0 LED of the status display port (digital I/O module) to indicate the
problem.
Grant Searle’s original SIO design has different register order to the official RC2014
module. Any module following Grant’s design should work. This includes the popular
SIO module by Dr. Scott M. Baker (tested).
The optional status display port is at I/O address $30, which is typically the LiNC80
digital I/O module. The output port of the digital I/O module has 8 LEDs connected
which light when the output is set to ‘1’ (a logic high). This module is also used by
default by the API port functions.
If the Small Computer Monitor is unable to identify the serial interface at reset it
turns On bit 0 LED of the status display port (digital I/O module) to indicate the
problem.
Tom’s SBC has a Z80 processor, 64k RAM, 32 or 64k ROM, two serial ports via a Z80
SIO, and a Compact Flash card connected via an 8-bit IDE port provides storage. It
76
does not have a general purpose expansion bus and does not have a status display
port.
77
Bugs, Quirks, Limitations and To do list
This section details all those embarrassing little issues that make software
development such fun and mean software it is never really finished.
Bugs
The outstanding bugs are currently:
B0001 Fixed: Assembling a JR instruction with an out of range address is not
detected.
Quirks
Q0001 Fixed: The assembler’s Restart instruction parameter must be a two digit
hexadecimal number and must not be prefixed with “$” or “0x”. Thus the
instruction “RST 08” is valid, while “RST 8” and “RST $08” are not.
Q0002 Fixed: The assembler and disassembler’s handling of instructions JP (HL), JP
(IX) and JP (IY) does not follow standard Z80 mnemonics. These are actually
input and output as JP HL, JP IX and JP IY.
Limitations
L0001 Fixed: The Intel hex file loader does not currently check the integrity of the
data by testing the file’s checksum values.
L0002 Fixed: The assembler does not trap all cases where parameter values are
too large and those it does trap are only indicated by the message “Syntax
error”.
L1003 The assembler and disassembler only handles the official Zilog documented
Z80 instructions.
To do list
T0001 Fix the bugs!
T0002 Consider addressing any Quirks and Limitations
T0003 Expose more functionality via the API
78
History
This section documents the release history of the Small Computer Monitor.
79
Reduced assembler’s need for hex prefixes
Added support for second ACIA at address $40
Default console device set at $0040 in the ROM
80
Future Plans
It is my intention to continue development of the Small Computer Monitor; to fix
bugs, add additional hardware support and increase functionality.
81
Contact Information
If you wish to contact me regarding the Small Computer Monitor please use the
contact page at www.scc.me.uk.
LiNC80
Issues related to the LiNC80 can be posted on the google group “LiNC80”.
Information about the LiNC80 and its accessories, and links to the store page where
kits can be purchased can be found at http://linc.no/go/linc80
RC2014
Issues related to the RC2014 can be posted on the google group “RC2014-Z80”.
Information about the RC2014 can be found at www.rc2014.co.uk
Kits are available from www.tindie.com
SC101
Information and support can be found at www.scc.me.uk
Tom’s SBC
Issues relating to Tom’s SBC can be posted at
https://groups.google.com/forum/#!topic/rc2014-z80/IFkzQh3bHhY
Information can be found at https://easyeda.com/peabody1929
82