Hi Bob,
I've just started playing with assembly language on an (emulated) ZX81. On a machine with an expanded display file (that is, on a machine with > 3KB RAM), the main thing to know is that there *must* be 25 Newline characters otherwise the machine will crash (or at least the display will become completely messed up).
The beginning of the display file is pointed to by the 16-bit value held at 16396 and 16397.
The first character must be a ZX81 newline character (decimal 118), this is followed by 32 display characters and then the line is terminated with another newline character. Each of the following lines is terminated by a newline character. Do not overwrite these characters by mistake!
I wrote the following routine for writing to the screen. You call MAKE_TABLE once at the beginning of your program, and then call PRINT_CHAR with a line, column and character value each time you want to put a character on screen. It uses a lookup table to hold the location of the first character of each line, and then adds the column position to get to the screen location.
I assemble this into a BIN file using the Pasmo assembler, then use a utility called BIN2P to transform that into a .P file with a BASIC loader ready to use in an emulator. (These tools are available for Linux, others will probably be able to advise what's best under Windows).
I'm very much a beginner at assembly language, so forgive anything that isn't clear or is suboptimal. The code is here, everyone please feel free to use it as you like:
- Code: Select all
; Print Character Routine
;
; Prints a character at a
; specified print position.
;
;
; Entry point to print the character
;
; Registers:
; A -> Line
; B -> Column
; C -> Character to Print
PRINT_CHAR LD D, 00 ; Zero high byte of line counter
ADD A, A ; Multiply line offset by two (2 bytes per line address)
LD E, A
LD HL, ADDRESS_TABLE ; Point to beginning of screen address table
ADD HL, DE ; Move pointer to address of beginning of screen line
LD E, (HL) ; Store low byte of screen address
INC HL
LD D, (HL) ; Store high byte of screen address
EX DE, HL ; Place screen address into HL
LD D, 0 ; Put column position
LD E, B ; into DE.
ADD HL, DE ; Point HL to character position on line
LD (HL), C ; Put character into display file
RET
;
; This routine only needs to be called once to create the screen line address table
;
MAKE_TABLE LD HL, ADDRESS_TABLE ; Address table pointer
LD DE, (16396) ; D_FILE
INC DE ; Step over first control character
LD B, 24 ; Count 24 lines
TABLE_LOOP LD (HL), E ; Store address of
INC HL ; first character
LD (HL), D ; of each screen line.
INC HL
PUSH BC
LD BC, 33 ; Add 33 characters
EX DE, HL ; to screen address pointer
ADD HL, BC ; (32 visible characters
EX DE, HL ; plus newline)
POP BC
DJNZ TABLE_LOOP ; Loop to process next line
RET
ADDRESS_TABLE DS 48 ; Reserve space for the 24 line addresses
Cheers,
Colin.