Now for the Assembler listing: those who wish to assemble the ZXGT code given with these articles should note the following. All numbers starting $ are hexadecimal. All RST commands are in hex but the dollar is not given. The labels are L0 to L255. All comment lines should be omitted. This is one third of the code. You will require a Rem of length 2,303 bytes as the first line in the machine. Note that this means that
The remaining two-thirds of the code almost fill the machine by themselves, so this third must be assembled and then deleted.
The entry point to the complete compiler is 17389 — use Rand Usr 17389 — for the code to be put in a Rem at line two or 17381 if you wish it to ask where the code is to be put.
The entry to the code generated by ZXGT is at 18823.
Next month we shall give details of the way that the compiler translates Basic with examples from the standard Basic repertoire. We shall also supply a complete listing of the compiler in machine code.
Code: Select all
(C) Copyright 1983.
Personal Software Services.
Start at location 16514 with the
ZXGT header .The two HALTs cause
the rest of the statement to be
blanked out in BASIC.
CP A
CP L
XOR H
CP C
HALT
HALT
This short section contains a
series of fixed Jumping points
which are used to get from the
first half to the second half of
the code.
L201: JP L151 ;PRINT
L202: JP L131 ;SCROLL
L203: JP L51 ;GET KEY
L204: JP L53 ;TEST KEY
L205: JP L165 ;PAUSE
L206: JP L100 ;MULTIPLY
L207: JP 0 ;PLOT
L208: JP L60 ;RST 10
L209: JP L65 ;$B6B
L210: JP L20 ;DIVIDE
L211: JP L99 ;RANDOM
L212: JP L80 ;GETNUM
L213: JP L187 ;REM
L214: JP L241 ;SAVE
When the break key is pressed we
come to here and do a RST to the
ROM.
L252: RST 08
ADC A,H
Routine to print a 16 bit signed
integer which is held in the HL
register pair. A leading space
is added.
L151: PUSH HL
PUSH DE
XOR A
CALL L60
BIT 7,H
JR Z,L153
LD A,22
CALL L60
CALL L231
L153: LD DE,10000
CALL L160
JR NC,L154
LD DE,1000
CALL L160
JR NC,L155
LD DE,100
CALL L160
JR NC,L156
LD E,10
CALL L160
JR NC,L157
JP L158
L154: CALL L120
L155: LD DE,1000
CALL L120
L156: LD DE,100
CALL L120
L157: LD E,10
CALL L120
L158: LD E,1
CALL L120
XOR A
POP DE
POP HL
JP L60
L160: PUSH HL
AND A
SBC HL,DE
POP HL
RET
Repeatedly Subtract DE from HL
until the result is negative. If
A starts with character code 28
(=char 0) It finishes with the
character code of the left hand
digit of HL. Print this
character.
L120: LD A,28
AND A
L121: SBC HL,DE
JR C,L122
INC A
JR L121
L122: ADD HL,DE
JP L60
Negate a 16 bit Integer
L231: LD A,H
CPL
LD H,A
LD A,L
CPL
LD L,A
INC HL
RET
Scroll the screen up 1 line
L131: LD HL,(16396)
LD DE,33
PUSH HL
LD BC,0
ADD HL,BC
INC HL
PUSH HL
ADD HL,DE
EX DE,HL
LD HL,726
SBC HL,BC
EX (SP),HL
POP BC
EX DE,HL
LDIR
POP HL
LD BC,$02B6
ADD HL,BC
LD (16398),HL
LD A,3
LD ($4039),A
LD A,3
LD ($403A),A
RET
Wait for a key to be pressed,
return the value in the A
register and test for break. Rub
out is trapped and waits for
another key to be pressed.
L51: CALL $2BB
INC H
JR NZ,L51
L57: CALL $2BB
LD A,L
CP $FF
JR Z,L57
L54: LD BC,$FD7F
XOR A
PUSH HL
SBC HL,BC
POP HL
JP Z,L252
LD BC,$FCEF
XOR A
PUSH HL
SBC HL,BC
POP HL
JR Z,L51
LD B,H
INC H
RET Z
LD C,L
CALL $7BD
LD A,(HL)
CP 0
RET
See If any key is pressed, works
like INKEY$
L53: CALL $2BB
LD A,H
CP $FE
JR Z,L51
JR L54
Pause for n l/50ths of a sec
leaving If a key is pressed.
L165: SET 7,H
LD (16436),HL
L166: LD HL,(16436)
LD A,H
AND $7F
OR L
RET Z
CALL L53
JR Z,L166
Multiply two 16 bit signed
integers together. One in HL,
the other in DE. Result in HL.
L100: LD B,16
LD C,D
LD A,E
EX DE,HL
LD HL,0
L101: SRL C
RRA
JR NC,L102
ADD HL,DE
L102: EX DE,HL
ADD HL,HL
EX DE,HL
DJNZ L101
RET
Plot or unplot a pixel on the
screen. Assumes a full 24 line
32 character screen.
L0: LD A,$2B
SUB B
JP C,L253
LD B,A
LD A,1
SRA B
JR NC,L1
LD A,4
L1: SRA C
JR NC,L2
RLC A
L2: PUSH AF
CALL L15
LD A,(HL)
RLC A
CP $10
JR NC,L4
RRC A
JR NC,L3
XOR $8F
L3: LD B,A
L4: LD DE,$0C9E
LD A,($4030)
SUB E
JP M,L6
POP AF
CPL
AND B
JR L7
L6: POP AF
OR B
L7: CP 8
JR C,L8
XOR $8F
L8: JP L60
L15: LD A,23
SUB B
JP C,L253
LD A,C
AND $1F
LD C,A
PUSH BC
PUSH BC
PUSH BC
XOR A
RL B
RL B
RL B
LD L,B
LD H,A
ADD HL,HL
ADD HL,HL
POP BC
LD C,B
LD B,A
ADD HL,BC
POP BC
LD B,A
ADD HL,BC
LD BC,(16396)
ADD HL,BC
INC HL
LD (16398),HL
POP BC
LD A,24
SUB B
LD (16442),A
LD A,33
SUB C
LD (16441),A
RET
Print the character at token
that is held In the A register.
If we are at the bottom of the
screen then display a ? and wait
for a key to be pressed. If it
is the COPY key make a copy. If
it is the SLOW key scroll up at
two lines per second. If it is
the CONTINUE key then clear the
screen and continue. Break
returns to BASIC. Any other key
causes a fast scroll.
L60: PUSH DE
PUSH HL
PUSH BC
PUSH AF
LD A,(16442)
CP 2
JR Z,L63
POP AF
L73: CP 118
JR Z,L61
CP 64
JR NC,L68
L78: LD HL,(16398)
LD (HL),A
INC HL
LD (16398),HL
LD A,(16441)
DEC A
LD (16441),A
LD A,(HL)
CP 118
JR NZ,L64
L62: LD A,(16442)
DEC A
LD (16442),A
INC HL
LD (16398),HL
LD A,33
LD (16441),A
JR L64
L61: LD HL,(16398)
L74: LD A,(HL)
CP 118
JR Z,L62
INC HL
JR L74
L63: LD HL,(16396)
LD BC,760
ADD HL,BC
LD A,143
LD (HL),A
L66: CALL L53
JR Z,L66
CP 40
JR Z,L67
CP 63
JR Z,L75
CP 41
CALL Z,L76
CALL L131
JR L79
L67: CALL $A2A
L79: POP AF
JR L73
L64: POP BC
POP HL
POP DE
RET
L75: CALL $869
JR L66
L76: LD HL,10000
L77: DEC HL
LD A,L
OR H
JR NZ,L77
RET
Print a sequence of characters.
DE points to where the
characters are and BC is the
number of them there are.
Printing is started at the
present cursor position.
L65: LD A,B
OR C
RET Z
LD A,(DE)
CALL L60
INC DE
DEC BC
JR L65
Expand Tokens Into the full
keywords adding blanks front and
back where necessary.
L68: CP 67
JR C,L69
CP 192
RES 6,A
JP C,L78
AND $3F
L69: LD HL,$111
LD B,A
INC B
CP 33
JR NC,L70
XOR A
CALL L60
L70: BIT 7,(HL)
INC HL
JR Z,L70
DJNZ L70
L71: LD A,(HL)
BIT 7,A
JR NZ,L72
CALL L60
INC HL
JR L71
L72: AND $3F
CALL L60
XOR A
JP L73
An overflow of some sort has
occured so report an error B.
L253: RST $08
ADC A,D
Divide the signed integer in HL
by the signed integer in DE,
result is in HL.
L20: LD A,E
OR D
JR Z,L253
CALL L40
PUSH BC
LD A,H
OR D
RLCA
JR C,L253
LD C,E
LD B,D
LD DE,0
PUSH DE
EX DE,HL
INC HL
L21: ADD HL,HL
EX DE,HL
ADD HL,HL
LD A,C
SUB L
LD A,B
SBC A,H
EX DE,HL
JR NC,L21
EX DE,HL
L22: EX DE,HL
L35: XOR A
LD A,H
RRA
LD H,A
LD A,L
RRA
LD L,A
OR H
JR Z,L23
EX DE,HL
XOR A
RR H
RR L
LD A,C
SUB L
LD A,B
SBC A,H
JP M,L22
LD A,C
SUB L
LD C,A
LD A,B
SBC A,H
LD B,A
EX (SP),HL
ADD HL,DE
EX (SP),HL
JR L22
L23: POP HL
POP BC
BIT 7,B
JP NZ,L231
RET
Find the sign of the division
and make both divisor and
dividend positive. Sign is in B.
L40: LD B,H
LD A,H
RLA
CALL C,L231
EX DE,HL
LD A,H
XOR B
LD B,A
BIT 7,H
JP NZ,L231
RET
Generate a pseudo random integer
number using the standard
Sinclair Seed. The result is.
always between 0 and 32768.
L99: LD DE,(16434)
LD H,E
LD L,$FD
LD A,D
OR A
SBC HL,DE
SBC A,0
SBC HL,DE
SBC A,0
LD E,A
LD D,0
SBC HL,DE
JR NC,+1
INC HL
LD (16434),HL
RES 7,H
RET
Make a REM statement to contain
the code which we are
generating. This REM always
contains two ll8's at the start
to stop BASIC trying to list the
machine code. There is a call to
ROM in here and this routine
must be executed in FAST mode.
The length of code arrives in
BC. On return HL is the address
of the first location available.
18816 is the location of the
first character in the REM.
L187: INC BC
INC BC
PUSH BC
LD HL,6
ADD HL,BC
LD B,H
LD C,L
LD HL,18816
CALL $9A3
INC HL
LD A, 118
LD (DE),A
LD (HL),0
INC HL
LD (HL),2
INC HL
POP BC
INC BC
INC BC
LD (HL),C
INC HL
LD (HL),B
INC HL
LD (HL),234
INC HL
LD (HL),A
INC HL
LD (HL),A
INC HL
RET
Get a signed integer from the
keyboard - used for INPUT and to
ask user where the code should
be put (see the second half of
the code).
The result is returned in the HL
register pair.
L80: LD HL,0
PUSH HL
L82: PUSH HL
L89: CALL L51
CP 22
JR NZ,L87
POP HL
POP DE
PUSH AF
PUSH HL
CALL L60
JR L89
L87: CP 118
POP HL
JR Z,L88
ADD HL,HL
PUSH HL
ADD HL,HL
ADD HL,HL
POP DE
ADD HL,DE
SUB 28
LD B,0
LD C,A
ADD HL,BC
ADD A,28
CALL L60
JR L82
L88: POP AF
CALL Z,L231
L92: RET
Save the code away into the the
location pointed to by location
16507. If the SLOW key is
pressed display the location and
contents - useful in debugging.
L241: PUSH BC
PUSH HL
LD HL,(16507)
PUSH AF
LD (HL),A
PUSH HL
INC HL
LD (16507),HL
CALL L53
CP 41
JR NZ,L242
LD A,118
CALL L60
POP HL
CALL L151
POP AF
LD H,0
LD L,A
CALL L151
JR L243
L242: POP HL
POP AF
L243: POP HL
POP BC
XOR A
RET