ROM calls
ROM calls essentially call the same routines that ZX Spectrum BASIC calls.
Pros | Cons |
---|---|
Requires very little effort on behalf of the programmer, and no knowledge of the complex Spectrum screen memory layout | |
Built into ROM, so does not take up as much RAM as custom print routines. | |
As feature-rich as the Spectrum PRINT command. | Flexibility comes with a huge perfomance hit. |
Can output to other channels, including printers |
First, we’ll define some EQUs in order to make our code a bit more readable.
;
; ROM routine addresses
;
ROM_CLS EQU 0x0DAF ; Clears the screen and opens channel 2
ROM_OPEN_CHANNEL EQU 0x1601 ; Open a channel
ROM_PRINT EQU 0x203C ; Print a string
;
; PRINT control codes - work with ROM_PRINT and RST 0x10
;
INK EQU 0x10
PAPER EQU 0x11
FLASH EQU 0x12
BRIGHT EQU 0x13
INVERSE EQU 0x14
OVER EQU 0x15
AT EQU 0x16
TAB EQU 0x17
CR EQU 0x0C
Before the ROM routines can be called, Channel #2 (Screen) needs to be opened. This can be done by:
- Calling ROM_CLS, which clears the screen and opens Channel #2, or
- Calling ROM_OPEN_CHANNEL, which does not clear the screen
;
; You can either do this...
;
CALL ROM_CLS ; Clear screen and open Channel 2 (Screen)
;
; Or this...
;
LD A, 2 ; Open Channel 2 (Screen) without clearing
CALL ROM_OPEN_CHANNEL
A single character can be printed by using the Z80 instruction RST 0x10. This will clear the screen and print the character A in the top-left hand corner. The Spectrum uses a variant of ASCII, so the character ‘A’ is character code 65. A full list of character codes can be found here.
;
; Simple PRINT example
;
CALL ROM_CLS ; Clear screen and open Channel 2 (Screen)
LD A, 65 ; The character code for A
RST 0x10 ; Print the character
RET
The RST instructions are a set of 8 Z80 instructions that are effectively a shortcut CALL to 8 fixed locations in the first 64 bytes of memory. RST 0x10 is equivalent to CALL 0x0010; you could use the latter, but it would take an extra 2 bytes up and be a bit slower.
In the case of the Spectrum, these RST routines are all in the ROM.
We can use the PRINT control codes to control output.
For more information on control codes, please hop over to this page.
CALL ROM_CLS ; Clear screen and open Channel 2 (Screen)
;
; Print a single character at screen position (15, 1)
;
LD A, AT ; AT control character
RST 0x10
LD A, 1 ; Y
RST 0x10
LD A, 15 ; X
RST 0x10
LD A, INK ; Ink colour
RST 0x10
LD A, 2 ; Red
RST 0x10
LD A, 65 ; Character to print
RST 0x10
RET
Multiple characters can be printed by calling the ROM_PRINT routine in the ZX Spectrum ROM. The string can contain any of the Spectrum characters, including the control codes.
LD DE, TEXT ; Address of the string
LD BC, TEXT_LEN ; The string length
CALL ROM_PRINT
RET
;
; Text for the ROM print routine
;
TEXT: DB AT, 10, 2, INK, 2, "Hello World!"
TEXT_LEN: EQU $ - TEXT1
I prefer to have my strings zero-terminated, so that I do not have to pass the length to the print routine. So we could write our own PRINT routine using RST 0x10 as follows:
;
; Print the string TEXT2 using my zero-terminated string print routine
;
LD DE, TEXT
CALL MY_PRINT
;
; My print routine
; DE: Address of the string
;
MY_PRINT: LD A, (DE) ; Get the character
CP 0 ; CP with 0
RET Z ; Ret if it is zero
RST 0x10 ; Otherwise print the character
INC DE ; Inc to the next character in the string
JR MY_PRINT ; Loop
;
; Text for my print routine
;
TEXT: DB AT, 12, 2, INK, 1, PAPER, 6, BRIGHT, 1, "Hello World!", 0
Next: Writing direct to screen memory