--------------------------------------------------------

THE ZX81 ROM DISASSEMBLY - PART A

by Dr.IAN LOGAN

--------------------------------------------------------

THE 'START'

The NMI generator is turned off and BC set to
the 'top of possible RAM'

0000 START      OUT     (+FD),A
                LD      BC,+7FFF
                JP      03CB,RAM-CHECK


THE 'ERROR' RESTART

0008 ERROR-1    LD      HL,(CH-ADD)
                LD      (X-PTR),HL
                JR      0056,ERROR-2


THE 'PRINT A CHARACTER' RESTART

The code of the character to be printed is in
the A register.

0010 PRINT-A    AND     A
                JP      NZ,07F1,PRINT-CH
                JP      07F5,PRINT-SP.
                DEFB    +FF


THE 'COLLECT CHARACTER' RESTART

The A register is set with the character
addressed by CH-ADD. Spaces are ignored.

0018 GET-CH.    LD      HL,(CH-ADD)
                LD      A,(HL)
001C TEST-SP.   AND     A
                RET     NZ
                NOP
                NOP


THE 'COLLECT NEXT CHARACTER' RESTART

CH-ADD is incremented before the character
is fetched.

0020 NEXT-CH    CALL    0049,CH-ADD+1
                JR      001C,TEST-SP.
                DEFB    +FF
                DEFB    +FF
                DEFB    +FF


THE 'FP-CALCULATOR' RESTART

A direct jump is made to the calculator
routine.

0028 FP-CALC.   JP      199D,CALCULATE


THE 'END-CALC' SUBROUTINE

The byte 34 ends a RST 0028 operation.

002B END-CALC.  POP     AF
                EXX
                EX      (SP),HL
                EXX
                RET


THE 'MAKE BC SPACES' RESTART

BC spaces are made available for different
purposes.

0030 BC-SPACES  PUSH    BC
                LD      HL,(E-LINE)
                PUSH    HL
                JP      1488,RESERVE


THE 'INTERRUPT' RESTART

B holds the line number and C the number of
the scan line.

0038 INTERRUPT  DEC     C
                JP      NZ,0045,SCAN-LINE
                POP     HL
                DEC     B
                RET     Z
                SET     3,C
0041 WAIT-INT.  LD      R,A
                El
                JP      (HL)
0045 SCAN-LINE  POP     DE
                RET     Z
                JR      0041,WAIT-INT.


THE 'INCREMENT CH-ADD' SUBROUTINE

The pointer CH-ADD is incremented and the
cursor ignored.

0049 CH-ADD+1   LD      HL,(CH-ADD)
004C CURSOR-SO  INC     HL
004D TEMP-PTR.  LD      (CH-ADD),HL
                LD      A,(HL)
                CP      +7F
                RET     NZ
                JR      004C,CURSOR-SO


THE 'ERROR-2' ROUTINE

L is loaded with the 'data byte'.

0056 ERROR-2    POP     HL
                LD      L,(HL)
0058 ERROR-3    LD      (ERR-NR),L
                LD      SP,(ERR-SP)
                CALL    0207,SLOW/FAST
                JP      14BC,SET-MEM
                DEFB    +FF


THE 'NMI' ROUTINE

This routine is entered whenever a 'SLOW'
NM interrupt occurs.

0066 NMI        EX      AF,A'F'
                INC     A
                JP      M,006D NMI-RET
                JR      Z,006F NMI-CONT.
006D NMI-RET    EX      AF,A'F'
                RET


THE PREPARE FOR 'SLOW' DISPLAY ROUTINE

The main registers are preserved on the
stack, the NMI generator is switched off and
a jump is made into the display routine. (IX
holding 0281 or 028F)

006F NMI-CONT   EX      AF,A'F'
                PUSH    AF
                PUSH    BC
                PUSH    DE
                PUSH    HL
                LD      HL,(D-FILE)
                SET     7,H
                HALT
                OUT     (+FD),A
                JP      (IX)


THE KEY TABLES

The 'unshifted' character codes         007E - 00A4

The 'shifted' character codes           00A5 - 00CB

The 'function' character codes          00CC - 00F2

The 'graphic' character codes           00F3 - 0110

The 'token' tables                      0111 - 01FB


THE 'LOAD/SAVE UPDATE' SUBROUTINE

HL is incremented until it matches the current
value in 'E-LINE'.

0lFC LOAD/SAVE  INC     HL
                EX      DE,HL
                LD      HL,(E-LINE)
                SCF
                SBC     HL,DE
                EX      DE,HL
                RET     NC
                POP     HL


THE DISPLAY ROUTINES:

i) Test for SLOW or FAST Mode.

The SLOW flag, Bit 6 of CDFLAG is tested, and
a return is made if the program is in FAST
mode or 'SLOW' display is not available.

0207 SLOW/FAST  LD      HL,+CDFLAG
                LD      A,(HL)
                RLA
                XOR     (HL)
                RLA
                RET     NC
                LD      A,+7F
                EX      AF,A'F'
                LD      B,+ll
                OUT     (+FE),A
0216 LOOP-11    DJNZ    0216,LOOP-11
                OUT     (+FD),A
                EX      AF,A'F'
                RLA
                JR      NC,0226,NO-SLOW
                SET     7,(HL)
                PUSH    AF
                PUSH    BC
                PUSH    DE
                PUSH    HL
                JR      0229,DISPLAY-1
0226 NO-SLOW    RES     6,(HL)
                RET

ii) The main display routine.

The frame counter is first collected and
decremented. A return is made if the frame
counter reaches zero.

0229 DISPLAY-1  LD      HL,(FRAMES)
                DEC     HL
022D DISPLAY-P  LD      A,+7F
                AND     H
                OR      L
                LD      A,H
                JR      NZ,0237,ANOTHER
                RLA
                JR      0239,OVER-NC
0237 ANOTHER    LD      B,(HL)
                SCF
0239 OVER-NC    LD      H,A
                LD      (FRAMES),HL
                RET     NC

The keyboard is now read, and a return is
made if a new key has been pressed.
Otherwise a display is produced.

023E DISPLAY-2  CALL    02BB,KEYBOARD
                LD      BC,(LAST-K)
                LD      (LAST-K),HL
                LD      A,B
                ADD     A,+02
                SBC     HL,BC
                LD      A,(DEBOUNCE)
                OR      H
                OR      L
                LD      E,B
                LD      B,+0B
                LD      HL,+CDFLAG
                RES     0,(HL)
                JR      NZ,0264,NO-KEY
                BIT     7,(HL)
                SET     0,(HL)
                RET     Z
                DEC     B
                NOP
                SCF
0264 NO-KEY     LD      HL,+DEBOUNCE
                CCF
                RL      B
026A LOOP-B     DJNZ    026A,LOOP-B
                LD      B,(HL)
                LD      A,E
                CP      +FE
                SBC     A,A
                LD      B,+lF
                OR      (HL)
                AND     B
                RRA
                LD      (HL),A
                OUT     (+FF),A
                LD      HL,(D-FILE)
                SET     7,H
                CALL    0292,DISPLAY-3
                LD      A,R
                LD      BC,+1901
                LD      A,+F5
                CALL    02B5,DISPLAY-5
                DEC     HL
                CALL    0292,DISPLAY-3
                JP      0229,DISPLAY-1

The IX register is loaded with the 'return'
address, and the main registers are
restored after a 'slow' display.

0292 DISPLAY-3  POP     IX
                LD      C,(MARGIN)
                BIT     7,(CDFLAG)
                JR      Z,02A9,DISPLAY-4
                LD      A,C
                NEG
                INC     A
                EX      AF,A'F'
                OUT     (+FE),A
                POP     HL
                POP     DE
                POP     BC
                POP     AF
                RET

Sets up the A and B registers for the display.

02A9 DISPLAY-4  LD      A,+FC
                LD      B,+01
                CALL 02B5,DISPLAY-5
                DEC     HL
                EX      (SP),HL
                EX      (SP),HL
                JP      (IX)

Sets up the refresh register and waits for an
interrupt.

02B5 DISPLAY-5  LD      R,A
                LD      A,+DD
                EI
                JP      (HL)


THE 'KEYBOARD SCANNING' SUBROUTINE

The keyboard is scanned eight times and the
result built up in the HL register pair. MARGIN
is also determined.

02BB - KEYBOARD LD      HL,+FFFF
                LD      BC +FEFE
                IN      A,(C)
                OR      +01
02C5 EACH-LINE  OR      +E0
                LD      D,A
                CPL
                CP      +01
                SBC     A,A
                OR      B
                AND     L
                LD      L,A
                LD      A,H
                AND     D
                LD      H,A
                RLC     B
                IN      A,(C)
                JR      C,02C5,EACH-LINE
                RRA
                RL      H
                RLA
                RLA
                RLA
                SBC     A,A
                AND     +18
                ADD     A,+1F
                LD      (MARGIN),A
                RET


THE 'SET FAST MODE' SUBROUTINE

The NMI generator is turned off and bit 7 of
CDFLAG is RESET. Bit 6 will remain SET if
the overall mode is SLOW, i.e. in PAUSE.

02E7 SET-FAST   BIT     7,(CDFLAG)
                RET     Z
                HALT
                OUT     (+FD),A
                RES     7,(CDFLAG)
                RET

REPORT-F -  No name supplied.

02F4 REPORT-F   RST     0008,ERROR-1
                DEFB    +0E


THE 'SAVE' COMMAND ROUTINE

HL is set to point to the start of the program
name. There is a 6 second header and then
the bytes of the name and the program are
passed out to the cassette recorder.

02F6 SAVE       CALL    03A8,NAME
                JR      C,02F4,REPORT-F
                EX      DE,HL
                LD      DE,+12CB
02FF HEADER     CALL    0F46,BREAK-1
                JR      NC,0332,BREAK-2
0304 DELAY-1    DJNZ    0304,DELAY-1
                DEC     DE
                LD      A,D
                OR      E
                JR      NZ,02FF,HEADER
030B OUT-NAME   CALL    031E,OUT-BYTE
                BIT     7,(HL)
                INC     HL
                JR      Z,030B OUT-NAME
                LD      HL,+VERSN
0316 OUT-PROG.  CALL    031E,OUT-BYTE
                CALL    01FC,LOAD/SAVE
                JR      0316,OUT-PROG.
031E OUT-BYTE   LD      E,(HL)
                SCF
0320 EACH-BIT   RL      E
                RET     Z
                SBC     A,A
                AND     +05
                ADD     +04
                LD      C,A
0329 PULSES     OUT     (+FF),A
                LD      B,+23
032D DELAY-2    DJNZ    032D,DELAY-2
                CALL    0F46,BREAK-1
0332 BREAK-2    JR      NC,03A6,REPORT-D
                LD      B,+1E
0336 DELAY-3    DJNZ    0336,DELAY-3
                DEC     C
                JR      NZ,0329,PULSES
033B DELAY-4    AND     A
                DJNZ    033B,DELAY-4
                JR      0320,EACH-BIT


THE 'LOAD' COMMAND ROUTINE

The bytes collected from the tape are
matched against the program name and then
the program is loaded into RAM.

0340 LOAD       CALL    03A8,NAME
                RL      D
                RRC     D
0347 NEXT-PROG  CALL    034C,IN-BYTE
                JR      0347,NEXT-PROG
034C IN-BYTE    LD      C,+01
034E NEXT-BIT   LD      B,+00
0350 BREAK-3    LD      A,+7F
                IN      A,(+FE)
                OUT     (+FF),A
                RRA
                JR      NC,03A2,BREAK-4
                RLA
                RLA
                JR      C,0385,GET-BIT
                DJNZ    0350,BREAK-3
                POP     AF
                CP      D
0361 RESTART    JP      NC,03E5,INITIAL.
                LD      H,D
                LD      L,E
0366 IN-NAME    CALL    034C,IN-BYTE
                BIT     7,D
                LD      A,C
                JR      NZ,0371,MATCHING
                CP      (HL)
                JR      NZ,0347 NEXT-PROG
0371 MATCHING   INC     HL
                RLA
                JR      NC,0366,IN-NAME
                INC     (E-LINE-hi.)
                LD      HL, + VERSN
037B IN-PROG.   LD      D,B
                CALL    034C,IN-BYTE
                LD      (HL),C
                CALL    01FC,LOAD/SAVE
                JR      037B,IN-PROG
0385 GET-BIT    PUSH    DE
                LD      E,+94
0388 TRAILER    LD      B,+1A
038A COUNTER    DEC     E
                IN      A,(+FE)
                RLA
                BIT     7,E
                LD      A,E
                JR      C,0388,TRAILER
                DJNZ    038A,COUNTER
                POP     DE
                JR      NZ,039C,BIT-DONE
                CP      +56
                JR      NC,034E,NEXT-BIT
039C BIT-DONE   CCF
                RL      C
                JR      NC,034E,N EXT-BIT
                RET
03A2 BREAK-4    LD A,D
                AND     A
                JR      Z,0361,RESTART


REPORT-D -  Break pressed

03A6 REPORT-D   RST     0008,ERROR-1
                DEFB    +0C


THE 'PROGRAM NAME' SUBROUTINE

The name is checked for 'report C', 'FAST'
mode is selected and the final letter of the
name is inverted.

03A8 NAME       CALL    0F55,SCANNING
                LD      A,(FLAGS)
                ADD     A,A
                JP      M,0D9A,REPORT-C
                POP     HL
                RET     NC
                PUSH    HL
                CALL    02E7,SET-FAST
                CALL    13F8 STK-FETCH
                LD      H,D
                LD      L,E
                DEC     C
                RET     M
                ADD     HL,BC
                SET     7,(HL)
                RET


THE 'NEW' COMMAND ROUTINE

'FAST' mode is selected and BC is loaded
with the present value of RAMTOP.

03C3 NEW        CALL    02E7 SET-FAST
                LD      BC,(RAMTOP)
                DEC     BC


THE RAM-CHECK ROUTINE

Starting with location RAMTOP-1 an attempt
is made to fill each location with 02. The
addresses are decremented until 3FFF is
reached. Each location is then read-back until
the first address that does not fetch 02 is
found. This address is RAMTOP.

03CB RAM-CHECK  LD      H,B
                LD      L,C
                LD      A,+3F
03CF RAM-FILL   LD      (HL), +02
                DEC     HL
                CP      H
                JR      NZ,03CF,RAM-FILL
03D5 RAM-READ   AND     A
                SBC     HL,BC
                ADD     HL,BC
                INC     HL
                JR      NC,03E2,SET-TOP
                DEC     (HL)
                JR      Z,03E2,SET-TOP
                DEC     (HL)
                JR      Z,03D5,RAM-READ
03E2 SET-TOP    LD      (RAMTOP),HL


THE INITIALISATION ROUTINE

The different tasks of the initialisation routine
are:

i.      Set the top location in RAM to hold 3E.
ii.     Set the stack pointer to point to the
        next location below
iii.    Set ERR-SP to hold the address two
        Iocations below the stack pointer.
iv.     Set the register to hold 1E.
v.      Select interrupt mode 1.
vi.     Set the IY register to hold ERR-NR as
        its base address.
vii.    Select 'SLOW' mode.
viii.   Set D-FILE to hold PROGRAM, i.e. No
        program present.
ix.     Make a collapsed D-FILE.
x.      Set VARS.
xi.     CALL CLEAR command routine.
xii.    Put the cursor in the edit line.
xiii.   Produce a 'SLOW' display.

03E5 INITIAL    LD      HL,(RAMTOP)
                DEC     HL
i.              LD      (HL),+3E
                DEC     HL
ii.             LD      SP,HL
                DEC     HL
iii.            DEC     HL
                LD      (ERR-SP},HL
iv.             LD      A,+1E
                LD      I,A
v.              IMl
                LD      IY,+ERR-NR
vi.             LD      (CDFLAG),+40
vii.            LD      HL,+PROGRAM
viii.           LD      (D-FILE),HL
ix.             LD      B,+l9
0408 LINE       LD      (HL),+76
                INC     HL
                DJNZ    0408,LINE
x.              LD      (VARS),HL
xi.             CALL    149A,CLEAR
0413 N/L-ONLY   CALL    14AD,CURSOR-IN
xiii.           CALL    0207,SLOW/F AST


PRODUCE THE BASIC LISTING

The 'upper' part of the display is produced by
first calling the CLS command routine, then
the BASIC program is listed from S-TOP.
The use of the 'cursor down' key also causes
the 'upper' part of the display to be rebuilt.

0419 UPPER      CALL    0A2A,CLS
                LD      HL,(E-PPC}
                LD      DE,(S-TOP)
                AND     A
                SBC     HL,DE
                EX      DE,HL
                JR      NC,042D,ADDR.TOP
                ADD     HL,DE
                LD      (S-TOP),HL
042D ADDR-TOP   CALL    09D8,LINE-ADDR
                JR      Z,0433, LIST-TOP
                EX      DE,HL
0433 LIST-TOP   CALL    073E,LIST-PROG
                DEC     (BERG)
                JR      NZ,0472,LOWER
                LD      HL,(E-PPC)
                CALL    09D8, LINE-ADDR
                LD      HL,(CH-ADD)
                SCF
                SBC     HL,DE
                LD      HL,+S-TOP
                JR      NC,0457,INC-LINE
                EX      DE,HL
                LD      A,(HL)
                INC     HL
                LDI
                LD      (DE),A
                JR      0419,UPPER

'cursor down' entry point.

0454 DOWN-KEY   LD      HL,+E-PPC
0457 INC-LINE   LD      E,(HL)
                INC     HL
                LD      D,(HL)
                PUSH    HL
                EX      DE,HL
                INC     HL
                CALL    09D8,LINE-ADDR
                CALL    05BB,LINE-NO.
                POP     HL
0464 KEY-INPUT  BIT     5,(FLAGX)
                JR      NZ,0472,LOWER
                LD      (HL),D
                DEC     HL
                LD      (HL),E
                JR      0419,UPPER


COPY THE EDIT-LINE

The 'lower' part of the display is formed by
copying the edit.line from the workspace to
the bottom of the screen.
First floating point numbers are removed,
then the blank part of the screen is defined
and finally the edit.line is copied over with
the 'lower' part of the screen being expanded
if necessary.

The EDIT-INP. entry point comes into use
when EDIT is used in reply to a request for
INPUT.

046F EDIT-INP.  CALL    14AD,CURSOR-IN
0472 LOWER      LD      HL,(E-LINE)
0475 EACH-CHAR  LD      A,(HL)
                CP      +7E
                JR      NZ,0482,END-LINE
                LD      BC,+0006
                CALL    0A60,RECLAIM-2
                JR      0475,EACH-CHAR
0482 END-LINE   CP      +76
                INC     HL
                JR      NZ,0475,EACH-CHAR
0487 EDIT-LINE  CALL    0537 CURSOR
048A EDIT-ROOM  CALL    0A1F,LINE-ENDS
                LD      HL,(E-LINE)
                LD      (ERR-NR),+FF
                CALL    0766,COPY-LINE
                BIT     7,(ERR-NR)
                JR      NZ,04C1,DISPLAY-6
                LD      A,(DF-SZ)
                CP      +18
                JR      NC,04C1,DISPLAY-6
                INC     A
                LD      (DF-SZ),A
                LD      B,A
                LD      C,+01
                CALL    0918,LOC.-ADDR
                LD      D,H
                LD      E,L
                LD      A,(HL)
04Bl FREE-LINE  DEC     HL
                CP      (HL)
                JR      NZ,04Bl,FREE-LINE
                INC     HL
                EX      DE,HL
                LD      A,(RAMTOP-hi.)
                CP      +4D
                CALL    C,0A5D,RECLAIM-1
                JR      048A,EDIT-ROOM


WAITING FOR A KEY

The syntax error pointer is set to zero and a
display is produced. Once a key has been
pressed the display is terminated. The
pressing of 'multiple keys' causes a jump
backto LOWER.

04C1 DISPLAY-6  LD      HL,+0000
                LD      (X-PTR),HL
                LD      HL, + CDFLAG
                BIT     7,(HL)
                CALL    Z,0229,DISPLAY-1
04CF SLOW-DISP  BIT     0,(HL)
                JR      Z,04CF,SLOW-DISP
                LD      BC,(LAST-K)
                CALL    0F4B,D-BOUNCE
                CALL    07BD,DECODE
                JR      NC,0472,LOWER


MODE SORTING

The differing modes give differing values for
the keys of the keyboard. These are obtained
from the key tables.

04DF MODE-SORT  LD      A,(MODE)
                DEC     A
                JP      M,0508,FETCH-2
                JR      NZ,04F7,FETCH-1
                LD      (MODE),A
                DEC     E
                LD      A,E
                SUB     +27
                JR      C,04F2,FUNC-BASE
                LO      E,A
04F2 FUNC-BASE  LD      HL,+00CC
                JR      0505,TABLE-ADD
04F7 FETCH-l    LD      A,(HL)
                CP      +76
                JR      Z,052B,K/L-KEY
                CP      +40
                SET     7,A
                JR      C,051B,ENTER
                LD      HL,+00C7
0505 TABLE-ADD  ADD     HL,DE
                JR      0515,FETCH-3
0508 FETCH-2    LD      A,(HL)
                BIT     2,FLAGS
                JR      NZ,0516,TEST-CURS
                ADD     A,+C0
                CP      +E6
                JR      NC,0516,TEST-CURS
0515 FETCH-3    LD      A,(HL)
0516 TEST-CURS  CP      +F0
                JP      PE,052D,KEY-SORT
051B ENTER      LD      E,A
                CALL    0537,CURSOR
                LD      A,E
                CALL    0526,ADD-CHAR
0523 BACK-NEXT  JP      0472,LOWER


THE 'ADD-CHAR' SUBROUTINE

All of the RAM from (HL) to STKEND is
moved up by one byte and the character code
in the A register is entered into the extra
location.

0526 ADD-CHAR   CALL    099B,ONE-SPACE
                LD      (DE),A
                RET


SORTING THE CURSOR KEYS

The addresses of the different routines for
the cursor keys are obtained by adding the
character code twice to the base address
0482. The address is then stacked.

052B K/L-KEY    LD      A,+78
052D KEY-SORT   LD      E,A
                LD      HL,+0482
                ADD     HL,DE
                ADD     HL,DE
                LD      C,(HL)
                INC     HL
                LD      B,(HL)
                PUSH    BC


CHOOSING K v. L MODE

The characters in the edit.line are read in turn.

Initially K-mode is selected but it will be
changed to L-mode unless the line holds only
the cursor or the last token is THEN. The RET
Z instruction takes the program to the cursor
key routines.

0537 CURSOR     LD      HL, (E-LINE)
                BIT     5,(FLAGX)
                JR      NZ,0556,L-MODE
0540 K-MODE     RES     2,(FLAGS)
0544 TEST-CHAR  LD      A,(HL)
                CP      +7F
                RET     Z
                INC     HL
                CALL    07B4,NUMBER
                JR      Z,0544,TEST-CHAR
                CP      +26 TEST-CHAR
                JR      C,0544,
                CP      +DE
                JR      Z,0540,K-MODE
0556 L-MODE     SET     2,(FLAGS)
                JR      0544,TEST-CHAR


THE 'CLEAR-ONE' SUBROUTINE

The single character (HL) is overwritten by
moving all of the RAM from (HL+1)-STKEND
down by one byte.

055C CLEAR-ONE  LD      BC,+0001
                JP      0A60,RECLAIM-2


THE CURSOR KEYTABLE

0562    | 9F    05 | UP-KEY     059F
0564    | 54    04 | DOWN-KEY   0454
0566    | 76    05 | LEFT-KEY   0576
0568    | 7F    05 | RIGHT-KEY  057F
056A    | AF    05 | GRAPHICS   05AF
056C    | C4    05 | EDIT-KEY   05C4
056E    | 0C    06 | N/L-KEY    060C
0570    | 8B    05 | RUBOUT     058B
0572    | AF    05 | FUNCTION   05AF
0574    | AF    05 | FUNCTION   05AF


THE CURSOR LEFT ROUTINE

0576 LEFT-KEY   CALL    0593,LEFT-EDGE
                LD      A,(HL)
                LD      (HL),+7F
                INC     HL
                JR      0588,GET-CODE


THE CURSOR RIGHT ROUTINE

057F RIGHT-KEY  INC     HL
                LD      A,(HL)
                CP      +76
                JR      Z,059D,ENDED-2
                LD      (HL),+7F
                DEC     HL
0588 GET-CODE   LD      (HL),A
0589 ENDED-1    JR      0523,BACK-NEXT


THE RUBOUT ROUTINE

058B RUBOUT     CALL    0593,LEFT-EDGE
                CALL    055C,CLEAR-ONE
                JR      0589,ENDED-1


THE 'LEFT-EDGE' SUBROUTINE

The first character in the edit-line is tested
against +7F, the cursor.

0593 LEFT-EDGE  DEC     HL
                LD      DE,(E-LINE)
                LD      A,(DE)
                CP      +7F
                RET     NZ
                POP     DE
059D ENDED-2    JR      0589,ENDED-1


THE CURSOR UP ROUTINE

059F UP-KEY     LD      HL,(E-PPC)
                CALL    09D8,LINE-ADDR
                EX      DE,HL
                CALL    05BB,LINE-NO.
                LD      HL,+E-PPC-hi.
                JP      0464,KEY-INPUT


THE FUNCTION KEY ROUTINE

05AF FUNCTION   LD      A,E
                AND     +07
                LD      (MODE),A
                JR      059D,ENDED-2


THE 'COLLECT LINE NUMBER' SUBROUTINE

The subroutine is entered at LINE-NO, with
an address in HL, If a line number is to be
found at that position then it is returned in
DE, otherwise DE is returned with +0000.

05B7 ZERO-DE    EX      DE,HL
                LD      DE,+04C2
05BB LINE-NO.   LD      A,(HL)
                AND     +C0
                JR      NZ,05B7,ZERO-DE
                LD      D,(HL)
                INC     HL
                LD      E,(HL)
                RET


THE EDIT KEY ROUTINE

First the 'lower' part of the screen is cleared,
hen the flag that shows whether the INPUT
Command is being followed, is tested and a
return made if the flag is set.
Next the line to be edited is located. Its
number is printed, followed by the cursor, but
before the line itself is copied into the
workspace a test for sufficient room is made.
A return is made if there is not enough
available RAM.

05C4 EDIT-KEY   CALL    0A1F,LINE-ENDS
                LD      HL, + EDIT-INP.
                PUSH    HL
                BIT     5,(FLAGX)
                RET     NZ
                LD      HL,(E-LINE)
                LD      (DF-CC),HL
                LD      HL,+1821
                LD      (S-POSN),HL
                LD      HL,(E-PPC)
                CALL    09D8,LINE-ADDR
                CALL    05BB,LINE-NO.
                LD      A,D
                OR      E
                RET     Z
                DEC     HL
                CALL    0AA5,OUT-NO.
                INC     HL
                LD      C,(HL)
                INC     HL
                LD      B,(HL)
                INC     HL
                LD      DE,(DF-CC)
                LD      A,+7F
                LD      (DE),A
                INC     DE
                PUSH    HL
                LD      HL, + 001D
                ADD     HL,DE
                ADD     HL,BC
                SBC     HL,SP
                POP     HL
                RET     NC
                LDIR
                EX      DE,HL
                POP     DE
                CALL    14A6,SET-STK-B
                JR      059D,ENDED-2


THE NEWLINE KEY ROUTINE

The NEWLINE key can be used in three
separate situations and these have to be
dealt with in different ways.
The first part of the routine is common to all
situations.

The 'lower' part of the screen is cleared. The
PRBUFF is also cleared unless the INPUT
command is being used, or the direct
command COPY. The line is then scanned to
check for syntax errors. The cursor is
removed and the line number found, if present.

060C N/L-KEY    CALL    0A1F,LINE-ENDS
                LD      HL,+LOWER
                BIT     5,(FLAGX)
                JR      NZ,0629,NOW-SCAN
                LD      HL,(E-LINE)
                LD      A,(H L)
                CP      +FF
                JR      Z,0626,STK-UPPER
                CALL    08E2,CLEAR-PRB
                CALL    0A2A,CLS
0626 STK-UPPER  LD      HL, + UPPER
0629 NOW-SCAN   PUSH    HL
                CALL    0CBA, LINE-SCAN
                POP     HL
                CALL    0537,CURSOR
                CALL    055C,CLEAR-ONE
                CALL    0A73,E-LINE-NO
                JR      NZ,064E,N/L-INP.
                LD      A,B
                OR      C
                JP      NZ,06E0,N/L-LINE

The second part sets up the required
parameters for the execution of the line, either
as a BASIC line or as an INPUT line.

An empty line is detected and the program jumps
back to the initialization routine.

                DEC     BC
                DEC     BC
                LD      (RPC),BC
                LD      (DF-SIZE),+02
                LD      DE,(DFILE)
                JR      0661,TEST-NULL
064E N/L-INP    CP      +76
                JR      Z,0664,N/L-NULL
                LD      BC,(T-ADDR)
                CALL    0918,LOC-ADDR
                LD      DE,(NXT-LIN)
                LD      (DF-SIZE),+02
0661 TEST-NULL  RST     0018,GET-CH
                CP      +76
0664 N/L-NULL   JP      Z,+0413,N/L-ONLY
                LD      (FLAGS),+80
                EX      DE,HL

The third part of the routine is the 'line
execution loop'. When a BASIC program is
being RUN, it is this 'loop' that leads to the
execution of the BASIC lines in their correct
order.

In the case of the INPUT command, the 'line'
is detected and input in the LINE-RUN
subroutine.
066C NEXT-LINE  LD      (NXTLIN),HL
                EX      DE,HL
                CALL    004D,TEMP-PTR
                CALL    0CC1,LINE-RUN
                RES     1,(FLAGS)
                LD      A,+C0
                LD      (X-PTR-hi),A
                CALL    14A3,X-TEMP
                RES     5,(FLAGX)
                BIT     7,(ERR-NR)
                JR      Z,06AE,STOP-LINE
                LD      HL,(NXTLIN)
                AND     (HL)
                JR      NZ,06AE STOP-LINE
                LD      D,(HL)
                INC     HL
                LD      E,(HL)
                LD      (PPC),DE
                INC     HL
                LD      E,(HL)
                INC     HL
                LD      D,(HL)
                INC     HL
                EX      DE,HL
                ADD     HL,DE
                CALL    0F46,BREAK-1
                JR      C,066C,NEXT-LINE

The third part of the routine is used to
produce the report at the end of a RUN, after
other direct commands and following the use
of the BREAK key.

                LD      HL,+ERR-NR
                BIT     7,(HL)
                JR      Z,06AE,STOP-LINE
                LD      (HL),+0C
06AE STOP-LINE  BIT     7,(PR-CC)
                CALL    Z,0871,COPY-BUFF
                LD      BC,+0121
                CALL    0918,LOC-ADDR
                LD      A,(ERR-NR)
                LD      BC,(PPC)
                INC     A
                JR      Z,06D1,REPORT
                CP      +09
                JR      NZ,06CA,CONTINUE
                INC     BC
06CA CONTINUE   LD      (OLDPPC),BC
                JR      NZ,06D1,REPORT
                DEC     BC
06D1 REPORT     CALL    07EB,OUT-CODE
                LD      A,+18
                RST     0010,PRINT-A
                CALL    0A98,OUT-NUM
                CALL    14AD,CURSOR-IN
                JP      04C1,DISPLAY-6

The fourth part of the routine is involved in
the entering of the BASIC line into its correct
position in the BASIC program.

Initially a search is made to see if there is
already a line with the same name number. If
a line is found then it is 'reclaimed'.

The new line is then copied from the
workspace to its correct place in the BASIC
program.

06E0 N/L-LINE   LD      (E-PPC),BC
                LD      HL,(CH-ADD)
                EX      DE,HL
                LD      HL,+N/L-ONLY
                PUSH    HL
                LD      HL,(STKBOT)
                SBC     HL,DE
                PUSH    HL
                PUSH    BC
                CALL    02E7,SET-FAST
                CALL    0A2A,CLS
                POP     HL
                CALL    09DB,LINE-ADD
                JR      NZ,0705,COPY-OVER
                CALL    09F2,NEXT-ONE
                CALL    0A6O,RECLAIM-2
0705 COPY-OVER  POP     BC
                LD      A,C
                DEC     A
                OR      B
                RET     Z
                PUSH    BC
                INC     BC
                INC     BC
                INC     BC
                INC     BC
                DEC     HL
                CALL    099E,MAKE-ROOM
                CALL    0207,SL0W/FAST
                POP     BC
                PUSH    BC
                INC     DE
                LD      HL,(STKBOT)
                DEC     HL
                LDDR
                LD      HL,(E-PPC)
                EX      DE,HL
                POP     BC
                LD      (HL),B
                DEC     HL
                LD      (HL),C
                DEC     HL
                LD      (HL),E
                DEC     HL
                LD      (HL),D
                RET


THE 'LIST' COMMAND ROUTINE

The 'LIST' command will list the BASIC
program from a given line, or line zero if no
number is supplied.
The first part of the routine finds the
'parameter' and saves the line number in
E-PPC. The second part of the routine
repeatedly calls the OUT-LINE subroutine
until either the screen is full or the last line
has been printed.

072C LLIST      SET     1,(FLAGS)
0730 LIST       CALL    0EA7,FIND-INT.
                LD      A,B
                AND     +3F
                LD      H,A
                LD      L,C
                LD      (E-PPC),HL
                CALL    09D8,LINE-ADDR
073E LIST-PROG  LD      E,+00
0740 UNTIL-END  CALL    0745,OUT-LINE
                JR      0740,UNTIL-END


THE 'PRINT A BASIC LINE' SUBROUTINE

The first part of the routine fetches the line
number of the 'current cursor line' and tests
against the line number that it is to print The
line number is then printed followed by the
'current line cursor' if required, or a space if
not.

0745 OUT-LINE   LD      BC,(E-PPC)
                CALL    09EA,CP-LINES
                LD      D, +92
                JR      Z,0755,TEST-END
                LD      DE, +0000
                RL      E
0755 TEST-END   LD      (BERG),E
                LD      A,(HL)
                CP      + 40
                POP     BC
                RET     NC
                PUSH    BC
                CALL    0AA5,OUT-NO.
                INC     HL
                LD      A,D
                RST     0010,PRINT-A
                INC     HL
                INC     HL



The second part of the routine prints the
actual line. By comparing CH-ADD & X-PTR
the routine tests to see if the syntax error
marker should be printed. The routine also
tests for floating point numbers and jumps
over them. When a 'token' is found a call is
made to the 'token printing' subroutine. When
the cursor marker is found the appropriate
cursor is printed.

0766 COPY-LINE  LD      (CH-ADD),HL
                SET     0,(FLAGS)
076D MORE-LINE  LD      BC,(X-PTR)
                LD      HL,(CH-ADD)
                AND     A
                SBC     HL,BC
                JR      NZ,077C,TEST-NUM
                LD      A,+B8
                RST     0010,PRINT-A
077C TEST-NUM.  LD      HL,(CH-ADD)
                LD      A,(HL)
                INC     HL
                CALL    07B4,NUMBER
                LD      (CH-ADD),HL
                JR      Z,076D,MORE-LINE
                CP      +7F
                JR      Z,079D,0UT-CURS
                CP      +76
                JR      Z,07EE,OUT-CH
                BIT     6,A
                JR      Z,079A,NOT-TOKEN
                CALL    094B,TOKENS
                JR      076D,MORE-LINE
079A NOT-TOKEN  RST     0010,PRINT-A
                JR      076D,MORE-LINE
079D OUT-CURS.  LD      A,(MODE)
                LD      B,+AB
                AND     A
                JR      NZ,07AA,FLAGS-2
                LD      A,(FLAGS)
                LD      B,+B0
07AA FLAGS-2    RRA
                RRA
                AND     +01
                ADD     A,B
                CALL    07F5,PRINT-SP
                JR      076D,MORE-LINE


THE 'NUMBER' SUBROUTINE

This subroutine tests the character in the
register against the 'number marker'. If a
match occurs then the value in the HL
register pair is incremented five times, so
to either skip over the floating point number
or to reserve 5 bytes for such a number.

07B4 NUMBER     CP      +7E
                RET     NZ
                INC     HL
                INC     HL
                INC     HL
                INC     HL
                INC     HL
                RET


THE 'KEYBOARD DECODE' SUBROUTINE

The dIfferent 'key values', held in the BC
register pair, are 'decoded' into the usual
ZXB1 character codes by looking-up the key
table at 007E. (007D + 1) The character code
specified as (HL).

07BD DECODE     LD      D,+00
                SRA     B
                SBC     A,A
                OR      +26
                LD      L,+05
                SUB     L
07C7 KEY-LINE   ADD     A,L
                SCF
                RR      C
                JR      C,07C7,KEY-LINE
                INC     C
                RET     NZ
                LD      C,B
                DEC     L
                LD      L,+01
                JR      NZ,07C7,KEY-LINE
                LD      HL,+007D
                LD      E,A
                ADD     HL,DE
                SCF
                RET


THE 'PRINTING' SUBROUTINE

The two little routines WRITE-CH & WRITE
are the essential parts of the printing
subroutine. However before a character can
be actually printed it is necessary for S-POSN
to be collected and tested and the display
eaxpanded if required.
The various entry points to the subroutine are
involved with the conversion of Hex. codes to
ZX81 character codes.

i) Printing digits:

07DC LEAD-SP.   LD      A,E
                AND     A
                RET     M
                JR      07Fl,PRINT-CH
07E1 OUT-DIGIT  XOR     A
07E2 DIGIT-INC  ADD     HL,BC
                INC     A
                JR      C,07E2,DIGIT-INC
                SBC     HL,BC
                DEC     A
                JR      Z,07DC,LEAD-SP
07EB OUT-CODE   LD      E,+1C
                ADD     A,E
07EE OUT-CH     AND     A
                JR      Z,07F5,PRINT-SP

ii) Printing characters:

07F1 PRINT-CH.  RES     0,(FLAGS)
07F5 PRINT-SP.  EXX
                PUSH    HL
                BIT     1,(FLAGS)
                JR      NZ,0802,LPRINT-A
                CALL    0808,ENTER-CH
                JR      0805,PRINT-EXX
0802 LPRINT-A   CALL    0851,LPRINT-CH
0805 PRINT-EXX  POP     HL
                EXX
                RET

     iii) Testing S-POSN:

0808 ENTER-CH   LD      D,A
                LD      BC,(S-POSN)
                LD      A,C
                CP      +21
                JR      Z,082C,TEST-LOW
0812 TEST-N/L   LD      A,+76
                CP      D
                JR      Z,0847,WRITE-N/L
                LD      HL,(DF-CC)
                CP      (HL)
                LD      A,D
                JR      NZ,083E,WRITE-CH
                DEC     C
                JR      NZ,083A,EXPAND-1
                INC     HL
                LD      (DF-CC),HL
                LD      C,+21
                DEC     B
                LD      (S-POSN),BC
082C TEST-LOW   LD      A,B
                CP      (DF-SZ)
                JR      Z,0835,REPORT
                AND     A
                JR      NZ,08l2,TEST-N/L

iv) REPORT-5 - insufficient room:

0835 REPORT-5   LD      L,+04
                JP      0058,ERROR-3

v) Expand the display:

083A EXPAND-1   CALL    099B,ONE-SPACE
                EX      DE,HL

vi) Writing an actual code:

083E WRITE-CH   LD      (HL),A
                INC     HL
                LD      (DF-CC),HL
                DEC     (S-POSN-lo.)
                RET

vii) Writing a N/L:

This is performed by decrementing the 'line
counter' and using LOC.ADDR to give the
correct values for DF-CC & S-POSN.

0847 WRITE-N/L  LD      C,+21
                DEC     B
                SET     0,(FLAGS)
                JP      0918,LOC.-ADDR


THE 'LPRINT-CH' SUBROUTINE

Characters are added one by one to the
printer buffer. Once the buffer is full, or a N/L
character is entered the buffer is emptied.

0851 LPRINT-CH  CP      +76
                JR      Z,0871,COPY-BUFF
                LD      C,A
                LD      A,(PR-CC)
                AND     +7F
                CP      +5C
                LD      L,A
                LD      H,+40
                CALL    Z,0871,COPY-BUFF
                LD      (HL),C
                INC     L
                LD      (PR-CC),L
                RET


THE 'COPY' COMMAND ROUTINE

The COPY command routine starts with the D
register being loaded with Hex.l6, being the
number ot Iines in a full display.  The Copy*D
routine is then used  to output these lines to
the printer.

0869 COPY       LD       D,+16
                LD       HL,+D-FILE
                INC      HL
                JR       0876,COPY*D

In COPY-BUFF the D register is only required
to be given the value Hex.01.

0871 COPY-BUFF  LD      D,+01
                LD      HL,+PRBUFF

In COPY*D a loop is set up with D being the
counter.

0876 COPY*D     CALL    02E7,SET-FAST
                PUSH    BC
087A COPY-LOOP  PUSH    HL
                XOR     A
                LD      E,A
087D COPY-TIME  OUT     (+FB),A
                POP     HL
0880 COPY-BRK   CALL    0F46,BREAK-1
                JR      C,088A,COPY-CONT
                RRA
                OUT     (+FB),A
0888 REPORT-D2  RST     0008,ERROR-1
                DEFB    +0C
088A COPY-CONT  IN      A,(+FB)
                ADD     A,A
                JP      M,08DE,COPY-END
                JR      NC,0880,COPY-BRK
                PUSH    HL
                PUSH    DE
                LD      A,D
                CP      +02
                SBC     A,A
                AND     E
                RLCA
                AND     E
                LD      D,A
089C COPY-NEXT  LD      C,(HL)
                LD      A,C
                INC     HL
                CP      +76
                JR      Z,08C7,COPY-N/L
                PUSH    HL
                SLA     A
                ADD     A,A
                ADD     A,A
                LD      H,+0F
                RL      H
                ADD     A,E
                LD      L,A
                RL      C
                SBC     A,A
                XOR     (HL)
                LD      C,A
                LD      B,+08
08B5 COPY-BITS  LD      A,D
                RLC     C
                RRA
                LD      H,A
08BA COPY-WAIT  IN      A,(+FB)
                RRA
                JR      NC,08BA,COPY-WAIT
                LD      A,H
                OUT     (+FB),A
                DJNZ    08B5,COPY-BITS
                POP     HL
                JR      089C,COPY-NEXT
08C7 COPY-N/L   IN      A,(+FB)
                RRA
                JR      NC,08C7,COPY-N/L
                LD      A,D
                RRCA
                OUT     (+FB),A
                POP     DE
                INC     E
                BIT     3,E
                JR      Z,087D,COPY-TIME
                POP     BC
                DEC     D
                JR      NZ,087A,COPY-LOOP
                LD      A,+04
                OUT     (+FB),A
08DE COPY-END   CALL    0207,SlOW-FAST
                POP     BC


THE 'CLEAR PRINTER BUFFER' SUBROUTINE

The printer buffer is cleared by overwriting it
with Hex.00 characters and setting the final
location to Hex.76.

08E2 CLEAR-PRB  LD      HL,+405C
                LD      (HL),+76
                LD      B,+20
08E9 PRB-BYTES  DEC     HL
                LD      (HL),+00
                DJNZ    08E9,PRB-BYTES
                LD      A,L
                SET     7,A
                LD      (PR-CC),A
                RET


THE 'PRINT AT' SUBROUTINE

This routine checks the validity of the
parameters given with the PRINT AT
command. If the parameters are invalid an
error is signalled otherwise the correct
S-POSN & DF-CC is obtained by using the
LOC.-ADDR routine.

08F5 PRINT-AT   LD      A,+17
                SUB     B
                JR      C,0905,WRONG-VAL
08FA TEST-VAL.  CP      (DF-SZ)
                JP      C,0835,REPORT-5
                INC     A
                LD      B,A
                LD      A,+1F
                SUB     C
0905 WRONG-VAL  JP      C,0EAD,REPORT-B
                ADD     A,+02
                LD      C,A
090B SET-FIELD  BIT     1,(FLAGS)
                JR      Z,0918,LOC.-ADDR

The LPRINT AT command sets the value of
PR-CC.

                LD      A,+5D
                SUB     C
                LD      (PR-CC),A
                RET


THE 'LOC.-ADDR' SUBROUTINE

This important subroutine sets the value of
DF-CC for given values of a display location.
If the display is collapsed and thereby does
not truly hoid the position then the required
line is expanded.

0918 LOC.-ADDR  LD      (S-POSN),BC
                LD      HL,(VARS)
                LD      D,C
                LD      A,+22
                SUB     C
                LD      C,A
                LD      A,+76
                INC     B
0927 LOOK-BACK  DEC     HL
                CP      (HL)
                JR      NZ,0927,LOOK-BACK
                DJNZ    0927,LOOK-BACK
                INC     HL
                CPIR
                DEC     HL
                LD      (DF-CC),HL
                SCF
                RET     PO
                DEC     D
                RET     Z
                PUSH    BC
                CALL    099E,MAKE-ROOM
                POP     BC
                LD      B,C
                LD      H,D
                LD      L,E
0940 EXPAND-2   LD      (HL),+00
                DEC     HL
                DJNZ    0940,EXPAND-2
                EX      DE,HL
                INC     HL
                LD      (DF-CC),HL
                RET


THE 'EXPAND TOKENS' SUBROUTINE

The character codes that are considered to
be tokens are expanded using this subroutine.
The address of each 'expanded token' in the
'token table' is found using TOKEN-ADD. The
leading space is printed if specified by bit 0
of FLAGS, the letters of the token-word are
then printed and a trailing space is added if
needed.

094B TOKENS 	PUSH	AF
                CALL    0975,TOKEN-ADD
                JR      NC,0959,ALL-CHARS
                BIT     0,(FLAGS)
                JR      NZ,0959,ALL-CHARS
                XOR     A
                RST     0010,PRINT-A
0959 ALL-CHARS	LD      A,(BC)
                AND     +3F
                RST     0010,PRINT-A
                LD      A,(BC)
                INC     BC
                ADD     A,A
                JR      NC,0959,ALL-CHARS
                POP     BC
                BIT     7,B
                RET     Z
                CP      +1A
                JR      Z,096D,TRAIL-SP.
                CP      +38
                RET     C
096D TRAIL-SP.  XOR     A
                SET     0,(FLAGS)
                JP      07F5,PRINT-SP.

In TOKEN-ADD the base address of the
TOKEN TABLE is hex.0111. The words in this
table are found in turn and when the required
word has been located a return is made with
BC pointing to the start of the word.

0975 TOKEN-ADD  PUSH    HL
                LD      HL,+0111
                BIT     7,A
                JR      Z,097F,TEST-HIGH
                AND     +3F
097F TEST-HIGH  CP      +43
                JR      NC,0993,FOUND
                LD      B,A
                INC     B
0985 WORDS      BIT     7,(HL)
                INC     HL
                JR      Z,0985,WORDS
                DJNZ    0985,WORDS
                BIT     6,A
                JR      NZ,0992,COMP-FLAG
                CP      +18
0992 COMP-FLAG  CCF
0993 FOUND      LD      B,H
                LD      C,L
                POP     HL
                RET     NC
                LD      A,(BC)
                ADD     A,+E4
                RET


THE 'ONE-SPACE' SUBROUTINE

Whenever a single space is required in the
program area or the display file then this
subroutine is called.

099B ONE-SPACE  LD      BC,+0001


THE 'MAKE-ROOM' SUBROUTINE

This routine creates BC spaces from the
location (HL).

099E MAKE-ROOM  PUSH    HL
                CALL    0EC5,TEST-ROOM
                POP     HL
                CALL    09AD,POINTERS
                LD      HL,(STKEND)
                EX      DE,HL
                LDDR
                RET


THE 'CHANGE ALL POINTERS' SUBROUTINE

Whenever some of the pointers require to be
changed this subroutine is called with the
amount of change in BC, and HL determining
which pointers are to be chariged. All pointers
that point lower than HL will not be altered.

09AD POINTERS   PUSH    AF
                PUSH    HL
                LD      HL,+D-FILE
                LD      A,+09
09B4 NEXT-PTR   LD      E,(HL)
                INC     HL
                LD      D,(HL)
                EX      (SP),HL
                AND     A
                SBC     HL,DE
                ADD     HL,DE
                EX      (SP),HL
                JR      NC,09C8,PTR-DONE
                PUSH    DE
                EX      DE,HL
                ADD     HL,BC
                EX      DE,HL
                LD      (HL),D
                DEC     HL
                LD      (HL),E
                INC     HL
                POP     DE
09C8 PTR-DONE   INC     HL
                DEC     A
                JR      NZ,09B4,NEXT-PTR
                EX      DE,HL
                POP     DE
                POP     AF
                AND     A
                SBC     HL,DE
                LD      B,H
                LD      C,L
                INC     BC
                ADD     HL DE
                EX      DE,HL
                RET


THE 'LINE-ADDR' SUBROUTINE

For a given BASIC line number this subroutin=B7
will return the starting address of the actual
line (ar~d the Z flag set) or the starting addres
of the following line if it does not exist (C
reset).

09D8 LINE-ADDR  PUSH    HL
                LD      HL,+PROGRAM
                LD      D,H
                LD      E,L
09DE NEXT-TEST  POP     BC
                CALL    09EA,CP-LINES
                RET     NC
                PUSH    BC
                CALL    09F2,NEXT-ONE
                EX      DE,HL
                JR      09DE,NEXT-TEST


THE 'COMPARE LINE NUMBERS' SUBROUTINE

The line number in (HL) is compared to the
the number in BC.

09EA CP-LINES   LD      A,(HL)
                CP      B
                RET     NZ
                INC     HL
                LD      A,(HL)
                DEC     HL
                CP      C
                RET


THE 'NEXT LINE or VARIABLE' SUBROUTINE

This subroutine very cleverly finds the start of
the next BASIC line or the start of the next
variable in the variable area. Line numbers are
identified by the high byte being less than
Hex.40, and the different types of variables are
identified by their differing bits 6 & 7.

09F2 NEXT-ONE   PUSH    HL
                LD      A,(HL)
                CP      +40
                JR      C,0A0F,LINES
                BIT     5,A
                JR      Z,0A10,BIT-5-NIL
                ADD     A,A
                JP      M,0A01,NEXT+FIVE
                CCF
0A01 NEXT+FIVE  LD      BC,+0005
                JR      NC,0A08,NEXT-LETT
                LD      C,+11
0A08 NEXT-LETT  RLA
                INC     HL
                LD      A,(HL)
                JR      NC,0A08,NEXT-LETT
                JR      0A15,NEXT-ADD
0A0F LINES      INC     HL
0A70 BIT-5-NIL  INC     HL
                LD      C,(HL)
                INC     HL
                LD      B,(HL)
                INC     HL
0A15 NEXT-ADD   ADD     HL,BC
                POP     DE


THE 'DIFFERENCE' SUBROUTINE

This subroutine finds the difference in value
between the contents of the HL and DE
register pairs. The result is returned in the BC
reglster pair.

0A17 DIFFER     AND     A
                SBC     HL,DE
                LD      B,H
                LD      C,L
                ADD     HL,DE
                EX      DE,HL
                RET


THE 'LINE ENDS' SUBROUTINE

The lines of the 'lower' screen are cleared by
this subroutine.

0A1F LINE-ENDS  LD      B,(DF-SZ)
                PUSH    BC
                CALL    0A2C,B-LINES
                POP     BC
                DEC     B
                JR      0A2C,B-LINES


THE 'CLS' COMMAND ROUTINE

i) The B register is loaded with Hex.lB, the
number of lines in Ihe display file.

0A2A CLS        LD      B,+18

ii) The address of the start of that part of the
display file that is to be cleared is found and a
test is made to see if more, or less, than
3 1/4 K. of RAM is fitted.

0A2C B-LINES    RES     1,(FLAGS)
                LD      C,+21
                PUSH    BC
                CALL    0918,LOC.-ADDR
                POP     BC
                LD      A,(RAMTOP-hi.)
                CP      +4D
                JR      C,0A52,COLLAPSED

iii) As an expanded display file is required, a
suitable number of spaces is printed so as to
clear the specified number of lines.

                SET     7,(S-POSN-hi.)
0A42 CLEAR-LOC  XOR     A
                CALL    07F5,PRINT-SP.
                LD      HL,(S-POSN)
                LD      A,L
                OR      H
                AND     +7E
                JR      NZ,0A42,CLEAR-LOC
                JP      0918,LOC.-ADDR

iv) As a collapsed display file is required a
LDIR instruction is used to copy a N/L
character the number of times specified in the
C register (formerly B). The system variable
VARS is then found and excess memory
reclaimed.

0A52 COLLAPSED  LD      D,H
                LD      E,L
                DEC     HL
                LD      C,B
                LD      B,+00
                LDIR
                LD      HL,(VARS)


THE 'RECLAIMING' SUBROUTINES

The pointers are first changed and then the
specified area of RAM is reclaimed by using a
LDIR instruction to overwrite the unwanted
part of the RAM contents.

0A5D RECLAIM-1  CALL    0A17,DIFFER
0A60 RECLAIM-2  PUSH    BC
                LD      A,B
                CPL
                LD      B,A
                LD      A,C
                CPL
                LD      C,A
                INC     BC
                CALL    09AD,POINTERS
                EX      DE,HL
                POP     HL
                ADD     HL,DE
                PUSH    DE
                LDIR
                POP     HL
                RET


THE 'E-LINE NUMBER' SUBROUTINE

This routine is used to find out whether the
current E-Line starts with a valid line number.
i.e.1-9999. The pointer CH-ADD is used
temporarily to point along the E-LINE. A return
is made if the INPUT command is being
executed. The INT-TO-FP routine is called to
collect the possible number and the FP-TO-BC
routine called to form an integer value. The
value is then tested against dec.0-10,000.
The subroutine returns via the SET-MEM
subroutine that resets STKEND

0A73 E-LINE-NO  LD      HL,(E-LINE)
                CALL    004D,TEMP-PTR
                RST     0018,GET-CH.
                BIT     5,(FLAGX)
                RET     NZ
                LD      HL,+MEMBOT
                LD      (STKEND),HL
                CALL    1548,INT-TO-FP
                CALL    158A,FP-TO-BC
                JR      C,0A91,NO-NUMBER
                LD      HL,+D8F0
                ADD     HL,BC
0A91 NO-NUMBER  JP      C,0D9A,REPORT-C
                CP      A
                JP      14BC,SET-MEM


THE 'REPORT & LINE NUMBER' PRINTING SUBROUTINES

The OUT-NUM. entry point is used to print the
error report line numbers and the OUT-NO.
entry point is used for printing line numbers at
the start of BASIC lines.

0A98 OUT-NUM.   PUSH    DE
                PUSH    HL
                XOR     A
                BIT     7,B
                JR      NZ,0ABF,UNITS
                LD      H,B
                LD      L,C
                LD      E,+FF
                JR      0AAD,THOUSAND
0AA5 OUT-NO.    PUSH    DE
                LD      D,(HL)
                INC     HL
                LD      E,(HL)
                PUSH    HL
                EX      DE,HL
                LD      E,+00
0AAD THOUSAND   LD      BC,+FC18
                CALL    07E1,OUT-DIGIT
                LO      BC,FF9C
                CALL    07E1,OUT-DIGIT
                LD      C,+F6
                CALL    07E1,OUT-DIGIT
                LD      A,L
0ABF UNITS      CALL    07EB,OUT-CODE
                POP     H L
                POP     DE
                RET


THE 'UNSTACK-Z' SUBROUTINE

Bit 7 of FLAGS is set during the execution of
a BASIC line but reset during syntax checking.
This subroutine calls SYNTAX-Z and then
either simply returns using a JP (HL)
instruction during the execution of a BASIC
line, or uses a RET Z instruction to 'return' to
the address above on the stack during syntax
checking.

0AC5 UNSTACK-Z CALL     0DA6,SYNTAX-Z
               POP      HL
               RET      Z
               JP       (HL)


THE 'LPRINT' COMMAND ROUTINE

Bit 1 of FLAGS is set whenever a LPRINT
command is executed.

0ACB LPRINT     SET     1,(FLAGS)


THE 'PRINT' COMMAND ROUTINE

This routine is fairly complex but fortunately it
can be broken into simple parts.

i) Test for PRINT alone.

0ACF PRINT      LD       A,(HL)
                CP       +76
                JP       Z,0B84,PRINT-END

ii) A loop is now set up to deal with each
constituent part of a PRINT line.
First, the next character is tested to see if it is
a 'comma' or a 'semi-colon'.

0AD5 PRINT-1    SUB     +1A
                ADC     A,+00
                JR      Z,0B44,SPACING

iii) If the next character is an 'AT' it is dealt with
as follows:

Test for 'AT'
                CP      +A7
                JR      NZ,0AFA,NOT-AT

The next character is collected.

                RST     0020,NEXT-CH.

The next expression is identified.

                CALL    0D92,CLASS-6

A test is made for the correct separator -
a comma.

                CP      +1A
                JP      NZ,0D9A,REPORT-C

The next character is collected.

                RST     0020,NEXT-CH

The next expression is identitied.

                CALL    0D92,CLASS-6

A test is made to see if a line is being executed
or syntax is being checked. An indirect jump is
made to PRINT-ON if syntax is being checked.

                CALL    0B4E,SYNTAX-ON

The particulars of the two expressions are both
on the calculator stack but they need to be
switched over. This is done using a RST 0028
instruction and the literal 01.

                RST     0028,FP-CALC.
                DEFB    +01
                        (exchange, 1A72)
                DEFB    +34
                        (end-calc.,O02B)

The two expressions on the stack are then
'loaded' into the BC register pair by calling
STK-TO-BC.

                CALL    0BF5,STK-TO-BC

With the PRINT AT parameters now in BC the
usual routine can be called to set DF-CC &
S-POSN and a jump is then made to PRINT-ON

                CALL    08F5,PRINT-AT
                JR      0B37,PRINT-ON

iv) If the next character is a 'TAB' it is dealt wit
as follows:

Test for 'TAB'

0AFA NOT-AT     CP      +A8
                JR      NZ,0B31,NOT-TAB

The single 'following expression' is collected.
The syntax flag is checked and the value of the
expression 'loaded' into the A register.

                RST     0020,NEXT-CH.
                CAll    0D92,CLASS-6
                CALL    0B4E,SYNTAX-QN
                CAlL    0C02,STK-TO-A

The 'parameter' is then tested and the new
values of DF-CC & S-POSN are found by calling
TEST-VAL.

                JP      NZ,0EAD,REPORT-8
                AND     +1F
                LD      C,A
                BIT     1,(FLAGS)
                JR      Z,0B1E,TAB-TEST
                SUB     (PR-CC)
                SET     7,A
                ADD     A,+3C
                CALL    NC,0871,COPY-BUFF
0B1E TAB-TEST   ADD     A,(S-POSN-lo.)
                CP      +21
                LD      A,(S-POSN-hi.)
                SBC     A,+01
                CALL    08FA,TEST-VAL
                SET     0,(FLAGS)
                JR      0B37,PRINT-ON

v) The expression that comes next is collected
and printed by using the PRINT-STK subroutine.

0B31 NOT-TAB    CALL    0F55,SCANNING
                CALL    0B55,PRINT-STK

vi) The routine now proceeds to check for
another expression.

0B37 PRINT-ON   RST     0018,GET-CH.
                SUB     +1A
                ADC     A,+00
                JR      Z,0B44,SPACING
                CALL    0D1D,CHECK-END
                JP      0B84,PRINT-END

vii) The two characters 'comma & semi-colon'
are now separated.

0B44 SPACING    CALL    NC,0B8B,FIELD
                RST     0020,NEXT-CH.
                CP      +76
                RET     Z
                JP      0AD5,PRINT-1

viii) The SYNTAX-ON subroutine causes a jump
to PRINT-ON if syntax is being checked.

0B4E SYNTAX-ON  CALL    0DA6,SYNTAX-Z
                RET     NZ
                POP     HL
                JR      0B37,PRINT-ON

ix) The PRINT-STK routine collects the details of
a string from the calculator stack. A number is
dealt with by jumping to PRINT-FP, whereas a
string is dealt with in the 'print string' section.
First the syntax flag is read.

0B55 PRINT-STK  CALL    0AC5,UNSTACK-2
                BIT     6,(FLAGS)
                CALL    Z,13F8,STK-FETCH
                JR      Z,0B6B,PR-STR-4
                JP      15DB,PRINT-FP

x) The string printing routine.

The length of the string is held in the BC register
pair and the starting address of the string is
held in the DE register pair.

0B64 PR-STR-1   LD      A,+0B
0B66 PR-STR-2   RST     0010,PRINT-A
0B67 PR-STR-3   LD      DE,(X-PTR)
0B6B PR-STR-4   LD      A,B
                OR      C
                DEC     BC
                RET     Z
                LD      A,(DE)
                INC     DE
                LD      (X-PTR),DE
                BIT     6,A
                JR      Z,0B66,PR-STR-2
                CP      +C0
                JR      Z,0B64,PR-STR-1
                PUSH    BC
                CALL    094B,TOKENS
                POP     BC
                JR      0B67,PR-STR-3

xi) The PRINT-END routine.

The syntax flag is read and a N/L character is
printed during line execution.

0B84 PRINT-END  CALL    0AC5,UNSTACK-Z
                LD      A,+76
                RST     0010,PRINT-A
                RET

xii) The FIELD subroutine.

The appropriate value of S-POSN (and PR-CC if
required) is found.

0B8B FIELD      CALL    0AC5,UNSTACK-Z
                SET     0,(FLAGS)
                XOR     A
                RST     001O,PRINT-A
                LD      BC,(S-POSN)
                LD      A,C
                BIT     1,(FLAGS)
                JR      Z,0BA4,CENTRE
                LD      A,+5D
                SUB     (PR-CC)
0BA4 CENTRE     LD      C,+11
                CP      C
                JR      NC,0BAB,RIGHT
                LD      C,+01
0BAB RIGHT      CALL    090B,SET-FIELD
                RET


THE 'PLOT & UNPLOT' COMMAND ROUTINES

Initially the x & y co-ordinates are fetched and
tested. Then they are converted to row & column
numbers. The value formed in the A register
distinguishes which pixel is being identified.

0BAF PLOT/UNP.  CALL    0BF5,STK-TO-BC
                LD      (COORDS),BC
                LD      A,+2B
                SUB     B
                JP      C,0EAD,REPORT-B
                LD      B,A
                LD      A,+01
                SRA     B
                JR      NC,0BC5,COLUMNS
                LD      A, + 04
0BC5 COLUMNS    SRA     C
                JR      NC,0BCA,FIND-ADDR
                RLCA
0BCA FIND-ADDR  PUSH    AF
                CALL    08F5,PRINT-AT
                LD      A,(HL)
                RLCA
                CP      +10
                JR      NC,0BDA,TABLE-PTR
                RRCA
                JR      NC,0BD9,SQ-SAVED
                XOR     +8F
0BD9 SQ-SAVED   LD      B,A
0BDA TABLE-PTR  LD      DE,+0C9E

The two operations of PLOTting and UNPLOTting
are distinguished by referring to T-ADDR and
comparing the value against the constant 0C9E
that is the value of the address of the UNPLOT
command in the syntax table.

                LD      A,(T-ADDR)
                SUB     E
                JP      M,0BE9,PLOT
                POP     AF
                CPL
                AND     B
                JR      0BEB,UNPLOT
0BE9 PLOT       POP     AF
                OR      B
0BEB UNPLOT     CP      +08
                JR      C,0BF1,PLOT-END
                XOR     +8F
0BF1 PLOT-END   EXX
                RST     0010,PRINT-A
                EXX
                RET


THE 'STK-TO-BC' SUBROUTINE

This subroutine 'loads' two floating point
numbers into the BC register pair. The
subroutine is therefore used to pick up
parameters in the range 00-FF.

0BF5 STK-TO-BC  CALL    0C02,STK-TO-A
                LD      B,A
                PUSH    BC
                CALL    0C02,STK-TO-A
                LD      E,C
                POP     BC
                LD      D,C
                LD      C,A
                RET


THE 'STK-TO-A' SUBROUTINE

This subroutine 'loads' the A register with the
floating point number held at the top of the
calculator stack. The number must be in the
range 00-FF.

0C02 STK-TO-A   CALL    15CD,FP-TO-A
                JP      C,0EAD,REPORT-B
                LD      C,+01
                RET     Z
                LD      C,+FF
                RET


THE 'SCROLL' COMMAND ROUTINE

The first part of the routine sets the correct
values of DF-CC and S-POSN to allow for the
next printing to occur at the start of the bottom
line + 1.

Next the end address of the first line in the
display file is identified and the whole of the
display file moved to overwrite this line.

0C0E SCROLL     LD      B,(DF-SZ)
                LD      C,+21
                CALL    0918,LOC.-ADDR
                CALL    099B,ONE-SPACE
                LD      A,(HL)
                LD      (DE),A
                INC     (S-POSN-hi.)
                LD      HL,(D-FILE)
                INC     HL
                LD      D,H
                LD      E,L
                CPIR
                JP      0A5D,RECLAIM-1

--------------------------------------------------------

THE SYNTAX TABLES

i) The offset table.

There is an offset value for each ot the BASIC
commands and by adding this offset to the value
of the address where it is found, the correct
address for the command in the parameter table
is obtained.

0C29      8B         LPRINT       0CB4
0C2A      8D         LLIST        0CBl
0C2B      2D         STOP         0C58
0C2C      7F         SLOW         0CAB
0C2D      81         FAST         0CAE
0C2E      49         NEW          0C77
0C2F      75         SCROLl       0CA1
0C30      5F         CONT         0CBF
0C31      40         DIM          0C71
0C32      42         REM          0C74
0C33      2B         FOR          0C5E
0C34      17         GOTO         0C4B
0C35      1F         GOSUB        0C54
0C36      37         INPUT        0C6D
0C37      52         LOAD         0C89
0C38      45         LIST         0C7D
0C39      0F         LET          0C48
0C3A      6D         PAUSE        0CA7
0C3B      2B         NEXT         0C66
0C3C      44         POKE         0C80
0C3D      2D         PRINT        0C6A
0C3E      5A         PLOT         0C98
0C3F      3B         RUN          0C7A
0C40      4C         SAVE         0C8C=20
0C41      45         RAND         0C86
0C42      0D         IF           0C4F
0C43      52         CLS          0C95
0C44      5A         UNPLOT       0C9E
0Cd5      4D         CLEAR        0C92
0C46      15         RETURN       0C5B
0C47      6A         COPY         0CB1


ii) The parameter table.

For each of the BASIC commands there are
between 3 & 8 entries in the parameter table.
The command classes for each of the
commands are given, together with the required
separators and these are followed by the
address of the appropriate routine.

0C48 P-LET      01      CLASS-1
                14      '='
                02      CLASS-2

0C4B P-GOTO     06      CLASS-6
                00      CLASS-0
                81
                0E      GOTO,0EB1

0C4F P-IF       06      CLASS-6
                DE      'THEN'
                05      CLASS-5
                AB
                0D      IF,0DAB

0C54 P-GOSUB    06      CLASS-6
                00      CLASS-0
                B5
                0E      GOSUB,0EB5

0C58 P-STOP     00      CLASS-0
                DC
                0C      STOP,0CDC

0C5B P-RETURN   00      CLASS-0
                D8
                0E      RETURN,0EDB

0C5E P-FOR      04      CLASS-4
                1A      '='
                06      CLASS-6
                DF      'TO'
                06      CLASS-6
                05      CLASS-5
                B9
                0D      FOR,0DB9

0C66 P-NEXT     04      CLASS-4
                00      CLASS-0
                2E
                0E      NEXT,0E2E

0C6A P-PRINT    05      CLASS-5
                CF
                0A      PRINT,0ACF

0C6D P-INPUT    01       CLASS-1
                00       CLASS-0
                E9
                0E       INPUT,0EE9

0C71 P-DIM      05       CLASS-5
                09
                14       DIM,1409

0C74P-REM       05       CLASS-5
                6A
                0D       REM,0D6A

0C77 P-NEW      00       CLASS-0
                C3
                03       NEW-03C3

0C7A P-RUN      03       CLASS-3
                AF
                0E       RUN,0EAF

0C7D P-LIST     03       CLASS-3
                30
                07       LIST,0730

0C80 P-POKE     06       CLASS-6
                1A       ','
                06       CLASS-6
                92
                0E       POKE,0E92

0C86 P-RAND     03       CLASS-3
                6C
                0E       RAND,0E6C

0C89 P-LOAD     05       CLASS-5
                40
                03       LOAD,0340

0CBC P-SAVE     05       CLASS-5
                F6
                02       SAVE,02F6

0CBF P-CONT     00       CLASS-0
                7C
                0E       CONT,0E7C

0C92 P-CLEAR    00       CLASS-0
                9A
                14       CLEAR,l49A

0C95 P-CLS      00       CLASS-0
                2A
                0A       CLS,0A2A

0C98 P-PLOT     06       CLASS-6
                1A       ','
                06       CLASS-6
                00       CLASS-0
                AF
                0B       PLOT/UNP.,0BAF

0C9E P-UNPLOT   06       CLASS-6
                1A       ','
                06       CLASS-6
                00       CLASS-0
                AF
                0B       PLOT/UNP.,0BAF

0CA4 P-SCROLL   00       CLASS-0
                0E
                UC      SCROLL,0C0E

0CA7 P-PAUSE    06      CLASS-6
                00      CLASS-0
                32
                0F      PAUSE,0F32

0CAB P-SLOW     00      CLASS-0
                2B
                0F      SLOW,0F2B

0CAE P-FAST     00      CLASS-0
                23
                0F      FAST,0F23

0CB1 P-COPY     00      CLASS-0
                69
                08      COPY,0869

0CB4 P-LPRINT   05      CLASS-5
                CB
                0A      LPRINT,0ACB

0CB7 P-LLIST    03      CLASS-3
                2C
                07      LLIST,072C


THE 'LINE SCANNING' ROUTINE

The BASIC interpreter scans each line for BASIC
commands and as each one is found the
appropriate command routine is followed.

The different parts of the routine are:

i) The LINE-SCAN entry point leads to the line
number being checked for validity.

0CBA LINE-SCAN  LD      (FLAGS),+01
                CALL    0A73,E-LINE-NO

ii) The LINE-RUN entry point is used when
replying to an INPUT prompt and this fact has
be identified.

0CC1 LINE-RUN   CALL    14BC,SET-MEM
                LD      HL,+ERR-NR
                LD      (HL),+FF
                LD      HL,+FLAGX
                BIT     5,(HL)
                JR      Z,0CDE,LINE-NULL

iii) The INPUT reply is tested to see if STOP was
entered.
                CP      +E3
                LD      A,(HL)
                JP      NZ,0D6F,INPUT-RE
                CALL    0DA6,SYNTAX-2
                RET     Z

iv) If appropriate, report D is given.

                RST     0008,ERROR-1
                DEFB    +0C


THE 'STOP' COMMAND ROUTINE

The only action is to give report 9.

0CDC STOP       RST     0008,ERROR-1
                DEFB    +08

v) A return is made if the line is 'null'.

0CDE LINE-NULL  RST     0018,GET-CH.
                LD      B,+00
                CP      +76
                RET     Z

vi) The first character is tested so as to check
that it is a command.

                LD      C,A
                RST     0020,NEXT-CH.
                LD      A,C
                SUB     +E1
                JR      C,0D26,REPORT-C

vii) The offset for the command is found from
the offset table.

                LD      C,A
                LD      HL,+0C29
                ADD     HL,BC
                LD      C,(HL)
                ADD     HL,BC
                JR      0CF7,GET-PARAM

viii) The parameters are fetched in turn by a loc
that returns to 0CF4.
The soparators are identitied by the test against
+0B.

0CF4 SCAN-LOOP  LD      HL,(T-ADDR)
0CF7 GET-PARAM  LD      A,(HL)
                INC     HL
                LD      (T-ADDR),HL
                LD      BC,+0CF4
                PUSH    BC
                LD      C,A
                CP      +0B
                JR      NC,0D10,SEPARATOR

ix) The address of the command class routine
obtained by reference to the command class
table at 0D16. A jump is made to the appropriate
routine.

                LD      HL,+0D16
                LD      B,+00
                ADD     HL,BC
                LD      C,(HL)
                ADD     HL,BC
                PUSH    HL
                RST     0018,GET-CH .
                RET

x) The correctness of the separator is simply
tested by the following routine.

0D10 SEPARATOR  RST     0018,GET-CH.
                CP      C
                JR      NZ,0D26,REPORT-C
                RST     0020,NEXT-CH.
                RET


THE COMMAND CLASS TABLE

The addresses for the seven different command
classes are found from this table.

0D16            17      CLASS-0,0D2D
0D17            25      CLASS-1,0D3C
0D18            53      CLASS-2,0D6B
0D19            0F      CLASS-3,0D28
0D1A            6B      CLASS-4.0D85
0D1B            13      CLASS-5,0D2E
0D1C            7B      CLASS-6,0D92


THE 'CHECK-END' SUBROUTINE

Line scanning is finished when the N/L character
is reached.

0D1D CHECK-END  CALL    0DA6,SYNTAX-Z
                RET     NZ
                POP     BC

0D22 CHECK-2    LD      A,(HL)
                CP      +76
                RET     Z

0D26 REPORT-C2  JR      0D9A,REPORT-C


THE 'COMMAND CLASS 3' ROUTINE

The commands RUN, LIST, RAND and LLIST can
be followed by a N/L or a number.


0D28 CLASS-3    CP      +76
                CALL    0D9C,NO-TO-STK


THE 'COMMAND CLASS 0' ROUTINE

An entry here will cause the zero flag to be set
prior to a call to CHECK-END.

0D2D CLASS-0    CP      A


THE 'COMMAND CLASS 5' ROUTINE

The commands IF, FOR, PRINT, DIM, REM,
LOAD, SAVE and LPRINT all have class 5 as
their last command class. A jump is made to the
command routine directly.

0D2E CLASS-5    POP     BC
                CALL    Z,0D1D,CHECK-END
                EX      DE,HL
                LD      HL,(T-ADDR)
                LD      C,(HL)
                INC     HL
                LD      B,(HL)
                EX      DE,HL
0D3A CLASS-END  PUSH    BC
                RET


THE 'COMMAND CLASS 1' ROUTINE

The commands LET and INPUT both require that
a variable be specified. The command class 1
routine collects the details of the variable and
stores them in the required places.

0D3C CLASS-1    CALL    111C,LOOK-VARS
0D3F CLASS-4-2  LD      (FLAGX),+00
                JR      NC,0D4D,SET-STK
                SET     7,(FLAGX)
                JR      NZ 0D63,SET-STRLN
0D4B REPORT-2   RST     0008,ERROR-1
                DEFB    +01
0D4D SET-STK    CALL    Z,11A7,STK-VAR
                BIT     6,(FLAGS)
                JR      NZ,0D63,SET-STRLN
                XOR     A
                CALL    0DA6,SYNTAX-Z
                CALL    NZ,13F8,STK-FETCH
                LD      HL,+FLAGX
                OR      (HL)
                LD      (HL),A
                EX      DE,HL
0D63 SET-STRLN  LD      (STRLEN),BC
                LD      (DEST),HL
0D6A REM        RET


THE 'COMMAND CLASS 2' ROUTINE

The value assigned to a variable in a LET
command or in reply to an INPUT prompt is
evaluated by calling SCANNING. If the value is
appropriate then an indirect jump is made to the
LET routine at 1321.

0D6B CLASS-2    POP     BC
                LD      A,(FLAGS)
0D6F INPUT-REP  PUSH    AF
                CALL    0F55,SCANNING
                POP     AF
                LD      BC,+1321
                LD      D,(FLAGS)
                XOR     D
                AND     +40
                JR      NZ,0D9A,REPORT-C
                BIT     7,D
                JR      NZ,0D3A,CLASS-END
                JR      0D22,CHECK-2


THE 'COMMAND CLASS 4' ROUTINE

The specified variable for the FOR and the NEXT
commands are dealt with by this routine. Only
single character variables are allowed and these
are identified by their having both bits 5 & 6 set.

0D85 CLASS-4    CALL    111C,LOOK-VARS
                PUSH    AF
                LD      A,C
                OR      +9F
                INC     A
                JR      NZ,0D9A,REPORT-C
                POP     AF
                JR      0D3F,CLASS-4-2


THE 'COMMAND CLASS 6' ROUTINE

CLASS-6 denotes that the following expression
must yield an integer value.
The SCANNlNG routine evaluates the expressic
and a numeric value will give bit 6 of FLAGS
set.

0D92 CLASS-6    CALL    0F55,SCANNING
                BIT     6,(FLAGS)
                RET     NZ

REPORT-C - no numeric value.

0D9A REPORT-C   RST     0008,ERROR-1
                DEFB    +0B


THE 'NO-TO-STK' SUBROUTINE

During execution of a line this routine leads to
number being placed on the calculator stack. If
the zero flag is reset on entry the number put on
the stack will be the result of evaluating the
'next' expression, but if the zero flag is set then
zero will be placed on the stack by using a
RST 0028 instruction.

0D9C NO-TO-STK  JR      NZ,0D92,CLASS-6
                CALL    0DA6,SYNTAX-Z
                RET     Z
                RST     0028,FP-CALC.
                DEFB    +A0
                        (stk-zero, 1A51)
                DEFB    +34
                        (end-calc.,002B)
                RET


THE 'SYNTAX-Z' SUBROUTINE

A simple test of bit 7 of FLAGS will give the zero
flag reset during execution and set during
syntax checking. i.e. SYNTAX gives Z set.

0DA6 SYNTAX-Z   BIT     7,(FLAGS)
                RET


THE 'IF' COMMAND ROUTINE

At this point the value of the expression
between the 'IF' and the 'THEN' is known, and is
on the top of the calculator stack.

During execution the result is deleted from the
stack but the pointer DE is still available. The
logical value of (DE) is tested and a return made
if zero otherwise the routine jumps to
LINE-NULL to execute the rest of the line.

0DAB IF         CALL    0DA6,SYNTAX-Z
                JR      Z,0DB6,IF-END
                RST     0028,FP-CALC.
                DEFB    +02
                        (delete,19E3)
                DEFB    +34
                        (end-calc.,002B)
                LD      A,(DE)
                AND     A
                RET     Z
0DB6 IF-END     JP      0CDE,LINE-NULL


THE 'FOR' COMMAND ROUTINE

This routine is made up of the following parts:

i) If a STEP variable is given then this is found
and put on the stack, otherwise the value one
is used.

0DB9 FOR        CP      +EO
                JR      NZ,0DC6,USE-ONE
                RST     0020,NEXT-CH.
                CALL    0D92,CLASS-6
                CALL    0D1D,CHECK-END
                JR      0DCC,REORDER
0DC6 USE-ONE    CALL    0D1D,CHECK-END
                RST     0028,FP-CALC.
                DEFB    +A1
                        (stk-one,1A51)
                DEFB    +34
                        (end-calc.,002B)

ii) The top three values on the stack, the 'value',
the 'limit' & the 'step' are re-ordered to give
'limit-step-value'.

0DCC REORDER  	RST     0028,FP-CALC.
             	DEFB    +C0
                  	(st-mem-0,1A63)
             	DEFB    +02
                    	(delete,19E3)
             	DEFB    +01
                    	(exchange,1A72)
             	DEFB    +E0
                    	(get-mem-O,1A451
             	DEFB    +01
                   	(exchange,1A72)
             	DEFB    +34
                   	(end-calc,002B)

iii) The LET routine is used to locate an
address in the VARS area for the FOR variable.
If the variable already exists then it is
overwritten, if not then the variable is added to
the end of the VARS. The 'limit' & the 'step' are
then transferred.

                CALL    1321,LET
                LD      (MEM),HL
                DEC     HL
                LD      A,(HL)
                SET     7,(H L)
                LD      BC,+0006
                ADD     HL,BC
                RLCA
                JR      C,0DEA,LMT+STEP
                SLA     C
                CALL    099E,MAKE-ROOM
                INC     HL
0DEA LMT+STEP   PUSH    HL
                RST     0028,FP-CALC.
                DEFB    +02
                        (delete,l9E3)
                DEFB    +02
                        (delete,19E3)
                DEFB    +34
                        (end-calc.,0028)
                POP     HL
                EX      DE,HL
                LD      C,+0A
                LDIR

iv) The current line number is fetched,
incremented and added to the variable.

               	LD      HL,(PPC)
               	EX      DE,HL
               	INC     DE
               	LD      (HL),E
               	INC     HL
               	LD      (HL),D

v) The NEXT-LOOP subroutine is called to
check that a 'looping' is possible. If it is not
possible then NXTLIN is set to the appropriate
line number for jumping over the whole of the
FOR-NEXT loop.

                CALL    0E5A,NEXT-LOOP
                RET     NC
                BIT     7,(PPC-hi.)
                RET     NZ
                LD      B,(STRLEN)
                RES     6,B
                LD      HL (NXTLIN)
0E0E NXTLIN-NO  LD      A,(HL)
                AND     +C0
                JR      NZ,0E2A,FOR-END
                PUSH    BC
                CALL    09F2,NEXT-ONE
                POP     BC
                INC     HL
                INC     HL
                INC     HL
                CALL    004C,CURSOR-SO
                RST     0018,GET-CH.
                CP      +F3
                EX      DE,HL
                JR      NZ,0E0E,NXTLIN-NO
                EX      DE,HL
                RST     0020,NEXT-CH
                EX      DE,HL
                CP      B
                JR      NZ,0E0E,NXTLIN-NO
0E2A FOR-END    LD      (NXTLINE,HL
                RET


THE 'NEXT' COMMAND ROUTINE

In this routine the address of the variable is
collected from DEST. Next MEM is loaded with
this address so that a RST 0028 instruction can
be used to manipulate the different parts of the
variable when the 'step' is added to the 'value'.

0E2E NEXT       BIT     1,(FLAGX)
                JP      NZ,0D4B,REPORT-2
                LD      HL,(DEST)
                BIT     7,(HL)
                JR      Z,0E58,REPORT-1
                INC     HL
                LD      (MEM),HL
                RST     0028,FP-CALC.
                DEFB    +E0
                        (get-mem-0,1A45)
                DEFB    +E2
                        (get-mem-2,1A45)
                DEFB    +0F
                        (addition,1755)
                DEFB    +C0
                        (st-mem-0,1A63)
                DEFB    +02
                        (delete,19E3)
                DEFB    +34
                        (end-calc.,002B)
                CALL    0E5A,NEXT-LOOP
                RET     C

An indirect jump is now made to the line
number given in the last two bytes of the
variable.

                LD      HL,(MEM)
                LD      DE,+000F
                ADD     HL,DE
                LD      E,(HL)
                INC     HL
                LD      D,(HL)
                EX      DE,HL
                JR      0E86,GOTO-2


REPORT-1 - 'NEXT' without 'FOR' error

0E58 REPORT-1   RST     0008,ERROR-1
                DEFB    +00


THE 'NEXT-LOOP' SUBROUTINE

This subroutine is called by both the 'FOR' and
the 'NEXT' command routines.

When called by the 'FOR' routine it determines
whether or not a jump past the whole of the
FOR-NEXT loop is to be made.

When called by the 'NEXT' command routine it
determines whether another loop is, or is not,
possible.

The routine tests the 'step' and then compares
the 'limit' and the 'value'. The carry flag is set,
or reset, as required.

0E5A NEXT-LOOP  RST     0028,FP-CALC.
                DEFB    +E1
                        (get-mem-1,1A45)
                DEFB    +E0
                        (get-mem-0,1A45)
                DEFB    +E2
                        (get-mem-2,1A45)
                DEFB    +32
                        (less-0,1ACE)
                DEFB    +00
                        (jump-true 1C2F)
                DEFB    +02, to 0E62
                DEFB    +01
                        (exchange,1A72)
0E62 LMT-V-VAL  DEFB    +03
                        (subtract,174C)
                DEFB    +33
                        (greater-0,1ADB)
                DEFB    +00
                        (jump-true,1C2F)
                DEFB    +04, to 0E69
                DEFB    +34
                        (end-calc.,002B)
                AND     A
                RET
0E69 IMPOSS.    DEFB    +34
                        (end-calc,002B)
                SCF
                RET


THE 'RAND' COMMAND ROUTINE

The FIND-INT. subroutine is called to show
whether a number was given with the RAND
command. If not then FRAMES is used.

0E6C RAND       CALL    0EA7,FIND-INT
                LD      A,B
                OR      C
                JR      NZ,0E77,SET-SEED
                LD      BC,(FRAMES)
0E77 SET-SEED   LD      (SEED),BC
                RET


THE 'CONT' COMMAND ROUTINE

The value of OLDPPC is fetched and used.

0E7C CONT       LD      HL,(OLDPPC)
                JR      0E86,GOTO-2


THE 'GOTO' COMMAND ROUTINE

The line number is collected, tested and then
passed to LINE-ADDR. The address returned is
loaded into NXTLIN.

0E81 GOTO       CALL    0EA7,FIND-INT.
                LD      H,B
                LD      L,C
0E86 GOTO-2     LD      A,H
                CP      +F0
                JR      NC,0EAD,REPORT-B
                CALL    09DB,LINE-ADDR.
                LD      (NXTLIN),HL
                RET


THE 'POKE' COMMAND ROUTINE

The value to be entered is collected from the
stack using FP-TO-A and the address of the
location to be filled is collected using
FIND-INT.

0E92 POKE       CALL    15CD,FP-TO-A
                JR      C,0EAD,REPORT-B
                JR      Z,0E9B,POKE-SAVE
                NEG
0E9B POKE-SAVE  PUSH    AF
                CALL    0EA7,FIND-INT.
                POP     AF
                BIT     7,(ERR-NR)
                RET     Z
                LD      (BC),A
                RET


THE 'FIND-INT.' SUBROUTINE

The integer value of the floating point number
on the top of the stack is found. Report B is
given if the value exceeds 65535 decimal.

0EA7 FIND-INT.  CALL    158A,FP-TO-BC
                JR      C,0EAD,REPORT-B
                RET     Z


REPORT-B -  integer out of range

0EAD REPORT-B   RST     0008,ERROR-1
                DEFB    +0A


THE 'RUN' COMMAND ROUTINE

The line number is determined and a jump
made to the CLEAR command routine.

0EAF RUN        CALL    0E81,GOTO
                JP      149A,CLEAR


THE 'GOSUB' COMMAND ROUTINE

The current line number is fetched,
incremented and stacked. The line number of
the subroutine is determined and the registers
set up for the TEST-ROOM subroutine.

0EB5 GOSUB      LD      HL,(PPC)
                INC     HL
                EX      (SP),HL
                PUSH    HL
                LD      (ERR-SP),SP
                CALL    0E81,GOTO
                LD      BC,+0006


THE 'TEST-ROOM' SUBROUTINE

This subroutine tests the value of STKEND
against the stack pointer allowing 36 bytes for
other variables. Report 4 is given if there is
insufficient room.

0EC5 TEST-ROOM  LD      HL,(STKEND)
                ADD     HL,BC
                JR      C,0ED3,REPORT-4
                EX      DE,HL
                LD      HL,+0024
                ADD     HL,DE
                SBC	HL,SP
                RET     C


REPORT-4 ---  out of RAM

0ED3 REPORT-4   LD      L,+03
                JP      0058,ERROR-3


THE 'RETURN' COMMAND ROUTINE=20

The 'return' line number is taken off the 'gosub
stack' and tested to show that it is a real line
number. Report 7 is given if there is a mistake.

0ED8 RETURN     POP     HL
                EX      (SP),HL
                LD      A,H
                CP      +3E
                JR      Z,0EE5,REPORT 7
                LD      (ERR-SP),SP
                JR      0E86,GOTO-2


REPORT-7 -  return without gosub

The Stack is restored and report 7 given.

0EE5 REPORT-7   EX      (SP),HL
                PUSH    HL
                RST     0008,ERROR-1
                DEFB    +06


THE 'INPUT' COMMAND ROUTINE

A test for report 8 is made and the workspace is
cleared. Then the appropriate prompt
characters are printed and the cursor marker
added  Finally a jump to LOWER is made so
that the edit-line can be printed.

0EE9 INPUT      BIT     7,(PPC-hi.)
                JR      NZ,0F21,REPORT-8
                CALL    14A3,X-TEMP
                LD      HL,+FLAGX
                SET     5,(HL)
                RES     6,(HL)
                LD      A,(FLAGS)
                AND     +40
                LD      BC,+0002
                JR      NZ,0F05,PROMPT
                LD      C,+04
0F05 PROMPT     OR      (HL)
                LD      (HL),A
                RST     0030,BC-SPACES
                LD      (HL),+76
                LD      A,C
                RRCA
                RRCA
                JR      C,0F14,ENTER-CUR
                LD      A,+0B
                LD      (DE),A
                DEC     HL
                LD      (HL),A
0F14 ENTER-CUR  DEC     HL
                LD      (HL),+7F
                LD      HL,(S-POSN)
                LD      (T-ADDR),HL
                POP     HL
                JP      0472,LOWER


REPORT-8 -  input as direct command

0F21 REPORT-8   RST     0008,ERROR-1
                DEFB    +07


THE 'FAST' COMMAND ROUTINE

The SET-FAST routine is called to reset bit 7 of
CDFLAG, and then bit 6 is reset.

0F23 FAST       CALL    02E7,SET-FAST
                RES     6,(CDFLAG)
                RET


THE 'SLOW' COMMAND ROUTINE

The 'true' slow/fast flag - bit 6 of CDFLAG is
set and a jump made to SLOW/FAST that
copies this flag to bit 7 for compute and
display.

0F2B SLOW       SET     6,(CDFLAG)
                JP      0207,SLOW/FAST


THE 'PAUSE' COMMAND ROUTINE

The parameter of the PAUSE command is
determined. Fast mode is selected for the
period of the PAUSE and the DISPLAY-P
routine called.

On returning the correct mode, SLOW or FAST
is selected and the value of FRAMES-hi set to
hex.FF. A jump to D-BOUNCE is then made.

Note: In the 'unimproved' ROM the value given
to FRAMES-hi. was determined by a SET 7,
(FRAMES-hi.) instruction and this failed to
ensure that the 15th. bit of FRAMES would
remain set as the first action of DISPLAY
routine is to decrement FRAMES.

0F32 PAUSE      CALL    0EA7,FIND-INT.
                CALL    02E7,SET-FAST
                LD      H,B
                LD      L,C
                CALL    022D,DISPLAY-P
                CALL    0207,SLOW/FAST
                LD      (FRAMES-hi.),+FF
                JR      0F4B,D-BOUNCE


THE 'BREAK-1' SUBROUTINE

The 'break' key is tested.

0F46 BREAK-1    LD      A,+7F
                IN      A,(+FE)
                RRA


THE 'DEBOUNCE' SUBROUTINE

The system variable is set to its required value
of Hex.FF.

********************************************************

The forward references:

0F55    SCANNING
111C    LOOK-VARS
11A7    STK-VAR
1321    LET
13F8    STK-FETCH
1488    RESERVE
149A    CLEAR
14A3    X-TEMP
14A6    SET-STK-B
l4AD    CURSOR-IN
l4BC    SET-MEM
1548    INT-TO-FP
158A    FP-TO-BC
15CD    FP-TO-A
15DB    PRINT-FP
199D    CALCULATE


RST 0028 literals:

00      jump-true           1C2F
01      exchange            1A72
02      delete              19E3
03      subtract            174C
0F      addition            1755
32      less-0              1ADB
33      greater-0           1ACE
34      end-calc.           002B
A0      stk-zero            1A51
A1      stk-one             1A51
C0      st-mem-0            1A63
C1      st-mem-1            1A63
C2      st-mem-2            1A63
E0      get-mem-0           1A45
E1      get-mem-1           1A45
E2      get-mem-2           1A45

********************************************************


--------------------------------------------------------
"THE ZX81 ROM DISASSEMBLY - by Dr.IAN LOGAN"

Version: 2.1 (1999 May 15)
Address: <http://www.ime.usp.br/~einar/zx81roma.zip>
Contact: Einar Saukas <einar@ime.usp.br>
Thanks:  Wilf Rigter <Wilf.Rigter@Powertech.bc.ca>
        & David Gonzales <dgonzal@classic.msn.com>
--------------------------------------------------------

