CPU-Z80-Disassembler

 view release on metacpan or  search on metacpan

t/data/zx48_benchmark.asm  view on Meta::CPAN

;** An Assembly File Listing to generate a 16K ROM for the ZX Spectrum **
;************************************************************************

; -------------------------
; Last updated: 13-DEC-2004
; -------------------------

; TASM cross-assembler directives. 
; ( comment out, perhaps, for other assemblers - see Notes at end.)

;#define DEFB .BYTE      
;#define DEFW .WORD
;#define DEFM .TEXT
;#define ORG  .ORG
;#define EQU  .EQU
;#define equ  .EQU

;   It is always a good idea to anchor, using ORGs, important sections such as 
;   the character bitmaps so that they don't move as code is added and removed.

;   Generally most approaches try to maintain main entry points as they are
;   often used by third-party software. 


KSTATE        equ $5C00         ; Used in reading the keyboard.
KSTATE1       equ $5C01         ; 
KSTATE2       equ $5C02         ; 
KSTATE3       equ $5C03         ; 
KSTATE4       equ $5C04         ; 
KSTATE5       equ $5C05         ; 
KSTATE6       equ $5C06         ; 
KSTATE7       equ $5C07         ; 
LAST_K        equ $5C08         ; Stores newly pressed key.
REPDEL        equ $5C09         ; Time (in 50ths of a second in 60ths of a second in
                                ; N. America) that a key must be held down before it
                                ; repeats. This starts off at 35, but you can POKE
                                ; in other values.
REPPER        equ $5C0A         ; Delay (in 50ths of a second in 60ths of a second in
                                ; N. America) between successive repeats of a key
                                ; held down: initially 5.
DEFADD        equ $5C0B         ; Address of arguments of user defined function if
                                ; one is being evaluated; otherwise 0.
K_DATA        equ $5C0D         ; Stores 2nd byte of colour controls entered
                                ; from keyboard .
TVDATA        equ $5C0E         ; Stores bytes of coiour, AT and TAB controls going
                                ; to television.
STRMS         equ $5C10         ; Addresses of channels attached to streams.
CHARS         equ $5C36         ; 256 less than address of character set (which
                                ; starts with space and carries on to the copyright
                                ; symbol). Normally in ROM, but you can set up your
                                ; own in RAM and make CHARS point to it.
RASP          equ $5C38         ; Length of warning buzz.
PIP           equ $5C39         ; Length of keyboard click.
ERR_NR        equ $5C3A         ; 1 less than the report code. Starts off at 255 (for 1)
                                ; so PEEK 23610 gives 255.
FLAGS         equ $5C3B         ; Various flags to control the BASIC system.
TV_FLAG       equ $5C3C         ; Flags associated with the television.
ERR_SP        equ $5C3D         ; Address of item on machine stack to be used as
                                ; error return.
LIST_SP       equ $5C3F         ; Address of return address from automatic listing.
MODE          equ $5C41         ; Specifies K, L, C. E or G cursor.
NEWPPC        equ $5C42         ; Line to be jumped to.
NSPPC         equ $5C44         ; Statement number in line to be jumped to. Poking
                                ; first NEWPPC and then NSPPC forces a jump to
                                ; a specified statement in a line.
PPC           equ $5C45         ; Line number of statement currently being executed.
SUBPPC        equ $5C47         ; Number within line of statement being executed.
BORDCR        equ $5C48         ; Border colour * 8; also contains the attributes
                                ; normally used for the lower half of the screen.
E_PPC         equ $5C49         ; Number of current line (with program cursor).
VARS          equ $5C4B         ; Address of variables.
DEST          equ $5C4D         ; Address of variable in assignment.
CHANS         equ $5C4F         ; Address of channel data.
CURCHL        equ $5C51         ; Address of information currently being used for
                                ; input and output.
PROG          equ $5C53         ; Address of BASIC program.
NXTLIN        equ $5C55         ; Address of next line in program.
DATADD        equ $5C57         ; Address of terminator of last DATA item.
E_LINE        equ $5C59         ; Address of command being typed in.
K_CUR         equ $5C5B         ; Address of cursor.
CH_ADD        equ $5C5D         ; Address of the next character to be interpreted:
                                ; the character after the argument of PEEK, or
                                ; the NEWLINE at the end of a POKE statement.
X_PTR         equ $5C5F         ; Address of the character after the ? marker.
WORKSP        equ $5C61         ; Address of temporary work space.
STKBOT        equ $5C63         ; Address of bottom of calculator stack.
STKEND        equ $5C65         ; Address of start of spare space.
BREG          equ $5C67         ; Calculator's b register.
MEM           equ $5C68         ; Address of area used for calculator's memory.
                                ; (Usually MEMBOT, but not always.)
FLAGS2        equ $5C6A         ; More flags.
DF_SZ         equ $5C6B         ; The number of lines (including one blank line)
                                ; in the lower part of the screen.
S_TOP         equ $5C6C         ; The number of the top program line in automatic
                                ; listings.
OLDPPC        equ $5C6E         ; Line number to which CONTINUE jumps.
OSPCC         equ $5C70         ; Number within line of statement to which
                                ; CONTINUE jumps.
FLAGX         equ $5C71         ; Various flags.
STRLEN        equ $5C72         ; Length of string type destination in assignment.
T_ADDR        equ $5C74         ; Address of next item in syntax table (very unlikely
                                ; to be useful).
SEED          equ $5C76         ; The seed for RND. This is the variable that is set
                                ; by RANDOMIZE.
FRAMES        equ $5C78         ; 3 byte (least significant first), frame counter.
                                ; Incremented every 20ms. See Chapter 18.
FRAMES3       equ $5C7A         ; 3rd byte of FRAMES
UDG           equ $5C7B         ; Address of 1st user defined graphic You can change
                                ; this for instance to save space by having fewer
                                ; user defined graphics.
COORDS        equ $5C7D         ; x-coordinate of last point plotted.
COORDS_hi     equ $5C7E         ; y-coordinate of last point plotted.
P_POSN        equ $5C7F         ; 33 column number of printer position
PR_CC         equ $5C80         ; Full address of next position for LPRINT to print at
                                ; (in ZX printer buffer). Legal values 5B00 - 5B1F.
                                ; [Not used in 128K mode or when certain peripherals
                                ; are attached]
ECHO_E        equ $5C82         ; 33 column number and 24 line number (in lower half)
                                ; of end of input buffer.
DF_CC         equ $5C84         ; Address in display file of PRINT position.
DFCCL         equ $5C86         ; Like DF CC for lower part of screen.
S_POSN        equ $5C88         ; 33 column number for PRINT position
S_POSN_hi     equ $5C89         ; 24 line number for PRINT position.
SPOSNL        equ $5C8A         ; Like S POSN for lower part
SCR_CT        equ $5C8C         ; Counts scrolls: it is always 1 more than the number
                                ; of scrolls that will be done before stopping with
                                ; scroll? If you keep poking this with a number
                                ; bigger than 1 (say 255), the screen will scroll
                                ; on and on without asking you.
ATTR_P        equ $5C8D         ; Permanent current colours, etc (as set up by colour
                                ; statements).
MASK_P        equ $5C8E         ; Used for transparent colours, etc. Any bit that
                                ; is 1 shows that the corresponding attribute bit
                                ; is taken not from ATTR P, but from what is already
                                ; on the screen.
ATTR_T        equ $5C8F         ; Temporary current colours, etc (as set up by
                                ; colour items).
MASK_T        equ $5C90         ; Like MASK P, but temporary.
P_FLAG        equ $5C91         ; More flags.
MEMBOT        equ $5C92         ; Calculator's memory area; used to store numbers

t/data/zx48_benchmark.asm  view on Meta::CPAN

; input is arriving from the keyboard.

;; ED-LOOP

ED_LOOP:
        call WAIT_KEY           ; routine WAIT-KEY gets key possibly
                                ; changing the mode.
        push af                 ; save key.
        ld d, $00               ; and give a short click based
        ld e, (iy+PIP-IY0)      ; on PIP value for duration.
        ld hl, $00C8            ; and pitch.
        call BEEPER             ; routine BEEPER gives click - effective
                                ; with rubber keyboard.
        pop af                  ; get saved key value.
        ld hl, ED_LOOP          ; address: ED-LOOP is loaded to HL.
        push hl                 ; and pushed onto stack.

; At this point there is a looping return address on the stack, an error
; handler and an input stream set up to supply characters.
; The character that has been received can now be processed.

        cp $18                  ; range 24 to 255 ?
        jr nc, ADD_CHAR         ; forward to ADD-CHAR if so.

        cp $07                  ; lower than 7 ?
        jr c, ADD_CHAR          ; forward to ADD-CHAR also.
                                ; Note. This is a 'bug' and chr$ 6, the comma
                                ; control character, should have had an
                                ; entry in the ED-KEYS table.
                                ; Steven Vickers, 1984, Pitman.

        cp $10                  ; less than 16 ?
        jr c, ED_KEYS           ; forward to ED-KEYS if editing control
                                ; range 7 to 15 dealt with by a table

        ld bc, $0002            ; prepare for ink/paper etc.
        ld d, a                 ; save character in D
        cp $16                  ; is it ink/paper/bright etc. ?
        jr c, ED_CONTR          ; forward to ED-CONTR if so

                                ; leaves 22d AT and 23d TAB
                                ; which can't be entered via KEY-INPUT.
                                ; so this code is never normally executed
                                ; when the keyboard is used for input.

        inc bc                  ; if it was AT/TAB - 3 locations required
        bit 7, (iy+FLAGX-IY0)   ; test FLAGX  - Is this INPUT LINE ?
        jp z, ED_IGNORE         ; jump to ED-IGNORE if not, else

        call WAIT_KEY           ; routine WAIT-KEY - input address is KEY-NEXT
                                ; but is reset to KEY-INPUT
        ld e, a                 ; save first in E

;; ED-CONTR

ED_CONTR:
        call WAIT_KEY           ; routine WAIT-KEY for control.
                                ; input address will be key-next.

        push de                 ; saved code/parameters
        ld hl, (K_CUR)          ; fetch address of keyboard cursor from K_CUR
        res 0, (iy+MODE-IY0)    ; set MODE to 'L'

        call MAKE_ROOM          ; routine MAKE-ROOM makes 2/3 spaces at cursor

        pop bc                  ; restore code/parameters
        inc hl                  ; address first location
        ldi (hl), b             ; place code (ink etc.)
                                ; address next
        ld (hl), c              ; place possible parameter. If only one
                                ; then DE points to this location also.
        jr ADD_CH_1             ; forward to ADD-CH-1


; ------------------------
; Add code to current line
; ------------------------
; this is the branch used to add normal non-control characters
; with ED-LOOP as the stacked return address.
; it is also the OUTPUT service routine for system channel 'R'.

;; ADD-CHAR

ADD_CHAR:
        res 0, (iy+MODE-IY0)    ; set MODE to 'L'


X0F85:
        ld hl, (K_CUR)          ; fetch address of keyboard cursor from K_CUR

        call ONE_SPACE          ; routine ONE-SPACE creates one space.

; either a continuation of above or from ED-CONTR with ED-LOOP on stack.

;; ADD-CH-1

ADD_CH_1:
        ldi (de), a             ; load current character to last new location.
                                ; address next
        ld (K_CUR), de          ; and update K_CUR system variable.
        ret                     ; return - either a simple return
                                ; from ADD-CHAR or to ED-LOOP on stack.


; ---

; a branch of the editing loop to deal with control characters
; using a look-up table.

;; ED-KEYS

ED_KEYS:
        ld e, a                 ; character to E.
        ld d, $00               ; prepare to add.
        ld hl, ed_keys_t-$07    ; base address of editing keys table. $0F99
        add hl, de              ; add E
        ld e, (hl)              ; fetch offset to E
        add hl, de              ; add offset for address of handling routine.
        push hl                 ; push the address on machine stack.
        ld hl, (K_CUR)          ; load address of cursor from K_CUR.
        ret                     ; Make an indirect jump forward to routine.


; ------------------
; Editing keys table
; ------------------
; For each code in the range $07 to $0F this table contains a
; single offset byte to the routine that services that code.
; Note. for what was intended there should also have been an
; entry for chr$ 6 with offset to ed-symbol.

;; ed-keys-t

ed_keys_t:
        defb ED_EDIT - $        ; 07d offset $09 to Address: ED-EDIT
        defb ED_LEFT - $        ; 08d offset $66 to Address: ED-LEFT
        defb ED_RIGHT - $       ; 09d offset $6A to Address: ED-RIGHT
        defb ED_DOWN - $        ; 10d offset $50 to Address: ED-DOWN
        defb ED_UP - $          ; 11d offset $B5 to Address: ED-UP
        defb ED_DELETE - $      ; 12d offset $70 to Address: ED-DELETE
        defb ED_ENTER - $       ; 13d offset $7E to Address: ED-ENTER
        defb ED_SYMBOL - $      ; 14d offset $CF to Address: ED-SYMBOL
        defb ED_GRAPH - $       ; 15d offset $D4 to Address: ED-GRAPH

; ---------------
; Handle EDIT key
; ---------------
; The user has pressed SHIFT 1 to bring edit line down to bottom of screen.
; Alternatively the user wishes to clear the input buffer and start again.
; Alternatively ...

;; ED-EDIT

ED_EDIT:
        ld hl, (E_PPC)          ; fetch E_PPC the last line number entered.
                                ; Note. may not exist and may follow program.
        bit 5, (iy+FLAGX-IY0)   ; test FLAGX  - input mode ?
        jp nz, CLEAR_SP         ; jump forward to CLEAR-SP if not in editor.

        call LINE_ADDR          ; routine LINE-ADDR to find address of line
                                ; or following line if it doesn't exist.
        call LINE_NO            ; routine LINE-NO will get line number from
                                ; address or previous line if at end-marker.
        ld a, d                 ; if there is no program then DE will
        or e                    ; contain zero so test for this.
        jp z, CLEAR_SP          ; jump to CLEAR-SP if so.

; Note. at this point we have a validated line number, not just an
; approximation and it would be best to update E_PPC with the true
; cursor line value which would enable the line cursor to be suppressed
; in all situations - see shortly.

        push hl                 ; save address of line.
        inc hl                  ; address low byte of length.
        ldi c, (hl)             ; transfer to C
                                ; next to high byte
        ld b, (hl)              ; transfer to B.
        ld hl, $000A            ; an overhead of ten bytes
        add hl, bc              ; is added to length.
        ld bc, hl               ; transfer adjusted value
                                ; to BC register.
        call TEST_ROOM          ; routine TEST-ROOM checks free memory.
        call CLEAR_SP           ; routine CLEAR-SP clears editing area.
        ld hl, (CURCHL)         ; address CURCHL
        ex (sp), hl             ; swap with line address on stack
        push hl                 ; save line address underneath

        ld a, $FF               ; select system channel 'R'
        call CHAN_OPEN          ; routine CHAN-OPEN opens it

        pop hl                  ; drop line address
        dec hl                  ; make it point to first byte of line num.
        dec (iy+E_PPC-IY0)      ; decrease E_PPC_lo to suppress line cursor.
                                ; Note. ineffective when E_PPC is one
                                ; greater than last line of program perhaps
                                ; as a result of a delete.
                                ; credit. Paul Harrison 1982.

        call OUT_LINE           ; routine OUT-LINE outputs the BASIC line
                                ; to the editing area.
        inc (iy+E_PPC-IY0)      ; restore E_PPC_lo to the previous value.
        ld hl, (E_LINE)         ; address E_LINE in editing area.
        inc hl                  ; advance
        inc hl                  ; past space
        inc hl                  ; and digit characters
        inc hl                  ; of line number.

        ld (K_CUR), hl          ; update K_CUR to address start of BASIC.
        pop hl                  ; restore the address of CURCHL.
        call CHAN_FLAG          ; routine CHAN-FLAG sets flags for it.

        ret                     ; RETURN to ED-LOOP.


; -------------------
; Cursor down editing
; -------------------
;   The BASIC lines are displayed at the top of the screen and the user
;   wishes to move the cursor down one line in edit mode.
;   With INPUT LINE, this key must be used instead of entering STOP.

;; ED-DOWN

ED_DOWN:
        bit 5, (iy+FLAGX-IY0)   ; test FLAGX  - Input Mode ?
        jr nz, ED_STOP          ; skip to ED-STOP if so

        ld hl, E_PPC            ; address E_PPC - 'current line'
        call LN_FETCH           ; routine LN-FETCH fetches number of next
                                ; line or same if at end of program.
        jr ED_LIST              ; forward to ED-LIST to produce an
                                ; automatic listing.


; ---

;; ED-STOP

ED_STOP:
        ld (iy+ERR_NR-IY0), $10 ; set ERR_NR to 'STOP in INPUT' code
        jr ED_ENTER             ; forward to ED-ENTER to produce error.


; -------------------
; Cursor left editing
; -------------------
; This acts on the cursor in the lower section of the screen in both
; editing and input mode.

;; ED-LEFT

ED_LEFT:
        call ED_EDGE            ; routine ED-EDGE moves left if possible
        jr ED_CUR               ; forward to ED-CUR to update K-CUR
                                ; and return to ED-LOOP.


; --------------------
; Cursor right editing
; --------------------
; This acts on the cursor in the lower screen in both editing and input
; mode and moves it to the right.

;; ED-RIGHT

ED_RIGHT:
        ld a, (hl)              ; fetch addressed character.
        cp $0D                  ; is it carriage return ?
        ret z                   ; return if so to ED-LOOP

        inc hl                  ; address next character

;; ED-CUR

ED_CUR:
        ld (K_CUR), hl          ; update K_CUR system variable
        ret                     ; return to ED-LOOP


; --------------
; DELETE editing
; --------------
; This acts on the lower screen and deletes the character to left of
; cursor. If control characters are present these are deleted first
; leaving the naked parameter (0-7) which appears as a '?' except in the
; case of chr$ 6 which is the comma control character. It is not mandatory
; to delete these second characters.

;; ED-DELETE

ED_DELETE:
        call ED_EDGE            ; routine ED-EDGE moves cursor to left.
        ld bc, $0001            ; of character to be deleted.
        jp RECLAIM_2            ; to RECLAIM-2 reclaim the character.


; ------------------------------------------
; Ignore next 2 codes from key-input routine
; ------------------------------------------
; Since AT and TAB cannot be entered this point is never reached
; from the keyboard. If inputting from a tape device or network then
; the control and two following characters are ignored and processing
; continues as if a carriage return had been received.
; Here, perhaps, another Spectrum has said print #15; AT 0,0; "This is yellow"
; and this one is interpreting input #15; a$.

;; ED-IGNORE

ED_IGNORE:
        call WAIT_KEY           ; routine WAIT-KEY to ignore keystroke.
        call WAIT_KEY           ; routine WAIT-KEY to ignore next key.

; -------------
; Enter/newline
; -------------
; The enter key has been pressed to have BASIC line or input accepted.

;; ED-ENTER

ED_ENTER:
        pop hl                  ; discard address ED-LOOP
        pop hl                  ; drop address ED-ERROR

;; ED-END

ED_END:
        pop hl                  ; the previous value of ERR_SP
        ld (ERR_SP), hl         ; is restored to ERR_SP system variable
        bit 7, (iy+ERR_NR-IY0)  ; is ERR_NR $FF (= 'OK') ?
        ret nz                  ; return if so

        ld sp, hl               ; else put error routine on stack
        ret                     ; and make an indirect jump to it.


; -----------------------------
; Move cursor left when editing
; -----------------------------
; This routine moves the cursor left. The complication is that it must
; not position the cursor between control codes and their parameters.
; It is further complicated in that it deals with TAB and AT characters
; which are never present from the keyboard.
; The method is to advance from the beginning of the line each time,
; jumping one, two, or three characters as necessary saving the original
; position at each jump in DE. Once it arrives at the cursor then the next
; legitimate leftmost position is in DE.

;; ED-EDGE

ED_EDGE:
        scf                     ; carry flag must be set to call the nested
        call SET_DE             ; subroutine SET-DE.
                                ; if input   then DE=WORKSP
                                ; if editing then DE=E_LINE
        sbc hl, de              ; subtract address from start of line
        add hl, de              ; and add back.
        inc hl                  ; adjust for carry.
        pop bc                  ; drop return address
        ret c                   ; return to ED-LOOP if already at left
                                ; of line.

        push bc                 ; resave return address - ED-LOOP.
        ld bc, hl               ; transfer HL - cursor address
                                ; to BC register pair.
                                ; at this point DE addresses start of line.

;; ED-EDGE-1

ED_EDGE_1:
        ld hl, de               ; transfer DE - leftmost pointer
                                ; to HL
        inc hl                  ; address next leftmost character to
                                ; advance position each time.
        ld a, (de)              ; pick up previous in A
        and $F0                 ; lose the low bits
        cp $10                  ; is it INK to TAB $10-$1F ?
                                ; that is, is it followed by a parameter ?
        jr nz, ED_EDGE_2        ; to ED-EDGE-2 if not
                                ; HL has been incremented once

        inc hl                  ; address next as at least one parameter.

; in fact since 'tab' and 'at' cannot be entered the next section seems
; superfluous.
; The test will always fail and the jump to ED-EDGE-2 will be taken.

        ld a, (de)              ; reload leftmost character
        sub $17                 ; decimal 23 ('tab')
        adc a, $00              ; will be 0 for 'tab' and 'at'.
        jr nz, ED_EDGE_2        ; forward to ED-EDGE-2 if not
                                ; HL has been incremented twice

        inc hl                  ; increment a third time for 'at'/'tab'

;; ED-EDGE-2

ED_EDGE_2:
        and a                   ; prepare for true subtraction
        sbc hl, bc              ; subtract cursor address from pointer
        add hl, bc              ; and add back
                                ; Note when HL matches the cursor position BC,
                                ; there is no carry and the previous
                                ; position is in DE.
        ex de, hl               ; transfer result to DE if looping again.
                                ; transfer DE to HL to be used as K-CUR
                                ; if exiting loop.
        jr c, ED_EDGE_1         ; back to ED-EDGE-1 if cursor not matched.

        ret                     ; return.


; -----------------
; Cursor up editing
; -----------------
; The main screen displays part of the BASIC program and the user wishes
; to move up one line scrolling if necessary.
; This has no alternative use in input mode.

;; ED-UP

ED_UP:
        bit 5, (iy+FLAGX-IY0)   ; test FLAGX  - input mode ?
        ret nz                  ; return if not in editor - to ED-LOOP.

        ld hl, (E_PPC)          ; get current line from E_PPC
        call LINE_ADDR          ; routine LINE-ADDR gets address
        ex de, hl               ; and previous in DE
        call LINE_NO            ; routine LINE-NO gets prev line number
        ld hl, $5C4A            ; set HL to E_PPC_hi as next routine stores
                                ; top first.
        call LN_STORE           ; routine LN-STORE loads DE value to HL
                                ; high byte first - E_PPC_lo takes E

; this branch is also taken from ed-down.

;; ED-LIST

ED_LIST:
        call AUTO_LIST          ; routine AUTO-LIST lists to upper screen
                                ; including adjusted current line.
        ld a, $00               ; select lower screen again
        jp CHAN_OPEN            ; exit via CHAN-OPEN to ED-LOOP


; --------------------------------
; Use of symbol and graphics codes
; --------------------------------
; These will not be encountered with the keyboard but would be handled
; otherwise as follows.
; As noted earlier, Vickers says there should have been an entry in
; the KEYS table for chr$ 6 which also pointed here.
; If, for simplicity, two Spectrums were both using #15 as a bi-directional
; channel connected to each other:-
; then when the other Spectrum has said PRINT #15; x, y
; input #15; i ; j  would treat the comma control as a newline and the
; control would skip to input j.
; You can get round the missing chr$ 6 handler by sending multiple print
; items separated by a newline '.

; chr$14 would have the same functionality.

; This is chr$ 14.
;; ED-SYMBOL

ED_SYMBOL:
        bit 7, (iy+FLAGX-IY0)   ; test FLAGX - is this INPUT LINE ?
        jr z, ED_ENTER          ; back to ED-ENTER if not to treat as if

t/data/zx48_benchmark.asm  view on Meta::CPAN

; now deal with colour controls - 16-23 ink, 24-31 paper

;; KEY-CONTR

KEY_CONTR:
        ld b, a                 ; make a copy of character.
        and $07                 ; mask to leave bits 0-7
        ld c, a                 ; and store in C.
        ld a, $10               ; initialize to 16d - INK.
        bit 3, b                ; was it paper ?
        jr nz, KEY_DATA         ; forward to KEY-DATA with INK 16d and
                                ; colour in C.

        inc a                   ; else change from INK to PAPER (17d) if so.

;; KEY-DATA

KEY_DATA:
        ld (iy+K_DATA-IY0), c   ; put the colour (0-7)/state(0/1) in KDATA
        ld de, KEY_NEXT         ; address: KEY-NEXT will be next input stream
        jr KEY_CHAN             ; forward to KEY-CHAN to change it ...


; ---

; ... so that INPUT_AD directs control to here at next call to WAIT-KEY

;; KEY-NEXT

KEY_NEXT:
        ld a, (K_DATA)          ; pick up the parameter stored in KDATA.
        ld de, KEY_INPUT        ; address: KEY-INPUT will be next input stream
                                ; continue to restore default channel and
                                ; make a return with the control code.

;; KEY-CHAN

KEY_CHAN:
        ld hl, (CHANS)          ; address start of CHANNELS area using CHANS
                                ; system variable.
                                ; Note. One might have expected CURCHL to
                                ; have been used.
        inc hl                  ; step over the
        inc hl                  ; output address
        ldi (hl), e             ; and update the input
                                ; routine address for
        ld (hl), d              ; the next call to WAIT-KEY.

;; KEY-DONE2

KEY_DONE2:
        scf                     ; set carry flag to show a key has been found
        ret                     ; and return.


; --------------------
; Lower screen copying
; --------------------
; This subroutine is called whenever the line in the editing area or
; input workspace is required to be printed to the lower screen.
; It is by calling this routine after any change that the cursor, for
; instance, appears to move to the left.
; Remember the edit line will contain characters and tokens
; e.g. "1000 LET a=1" is 8 characters.

;; ED-COPY

ED_COPY:
        call TEMPS              ; routine TEMPS sets temporary attributes.
        res 3, (iy+TV_FLAG-IY0) ; update TV_FLAG  - signal no change in mode
        res 5, (iy+TV_FLAG-IY0) ; update TV_FLAG  - signal don't clear lower
                                ; screen.
        ld hl, (SPOSNL)         ; fetch SPOSNL
        push hl                 ; and save on stack.

        ld hl, (ERR_SP)         ; fetch ERR_SP
        push hl                 ; and save also
        ld hl, ED_FULL          ; address: ED-FULL
        push hl                 ; is pushed as the error routine
        ld (ERR_SP), sp         ; and ERR_SP made to point to it.

        ld hl, (ECHO_E)         ; fetch ECHO_E
        push hl                 ; and push also

        scf                     ; set carry flag to control SET-DE
        call SET_DE             ; call routine SET-DE
                                ; if in input DE = WORKSP
                                ; if in edit  DE = E_LINE
        ex de, hl               ; start address to HL

        call OUT_LINE2          ; routine OUT-LINE2 outputs entire line up to
                                ; carriage return including initial
                                ; characterized line number when present.
        ex de, hl               ; transfer new address to DE
        call OUT_CURS           ; routine OUT-CURS considers a
                                ; terminating cursor.

        ld hl, (SPOSNL)         ; fetch updated SPOSNL
        ex (sp), hl             ; exchange with ECHO_E on stack
        ex de, hl               ; transfer ECHO_E to DE
        call TEMPS              ; routine TEMPS to re-set attributes
                                ; if altered.

; the lower screen was not cleared, at the outset, so if deleting then old
; text from a previous print may follow this line and requires blanking.

;; ED-BLANK

ED_BLANK:
        ld a, ($5C8B)           ; fetch SPOSNL_hi is current line
        sub d                   ; compare with old
        jr c, ED_C_DONE         ; forward to ED-C-DONE if no blanking

        jr nz, ED_SPACES        ; forward to ED-SPACES if line has changed

        ld a, e                 ; old column to A
        sub (iy+SPOSNL-IY0)     ; subtract new in SPOSNL_lo
        jr nc, ED_C_DONE        ; forward to ED-C-DONE if no backfilling.

;; ED-SPACES

ED_SPACES:
        ld a, $20               ; prepare a space.
        push de                 ; save old line/column.
        call PRINT_OUT          ; routine PRINT-OUT prints a space over
                                ; any text from previous print.
                                ; Note. Since the blanking only occurs when
                                ; using $09F4 to print to the lower screen,
                                ; there is no need to vector via a RST 10
                                ; and we can use this alternate set.
        pop de                  ; restore the old line column.
        jr ED_BLANK             ; back to ED-BLANK until all old text blanked.


; -------------------------------
; THE 'EDITOR-FULL' ERROR ROUTINE
; -------------------------------
;   This is the error routine addressed by ERR_SP.  This is not for the out of
;   memory situation as we're just printing.  The pitch and duration are exactly
;   the same as used by ED-ERROR from which this has been augmented.  The
;   situation is that the lower screen is full and a rasp is given to suggest
;   that this is perhaps not the best idea you've had that day.

;; ED-FULL

ED_FULL:
        ld d, $00               ; prepare to moan.
        ld e, (iy+RASP-IY0)     ; fetch RASP value.
        ld hl, $1A90            ; set pitch or tone period.

        call BEEPER             ; routine BEEPER.

        ld (iy+ERR_NR-IY0), $FF ; clear ERR_NR.
        ld de, (SPOSNL)         ; fetch SPOSNL.
        jr ED_C_END             ; forward to ED-C-END

t/data/zx48_benchmark.asm  view on Meta::CPAN


LINE_NO_A:
        ex de, hl               ; fetch the previous line to HL and set
        ld de, LINE_ZERO        ; DE to LINE-ZERO should HL also fail.

; -> The Entry Point.

;; LINE-NO

LINE_NO:
        ld a, (hl)              ; fetch the high byte - max $2F
        and $C0                 ; mask off the invalid bits.
        jr nz, LINE_NO_A        ; to LINE-NO-A if an end-marker.

        ldi d, (hl)             ; reload the high byte.
                                ; advance address.
        ld e, (hl)              ; pick up the low byte.
        ret                     ; return from here.


; -------------------
; Handle reserve room
; -------------------
; This is a continuation of the restart BC-SPACES

;; RESERVE

RESERVE:
        ld hl, (STKBOT)         ; STKBOT first location of calculator stack
        dec hl                  ; make one less than new location
        call MAKE_ROOM          ; routine MAKE-ROOM creates the room.
        inc hl                  ; address the first new location
        inc hl                  ; advance to second
        pop bc                  ; restore old WORKSP
        ld (WORKSP), bc         ; system variable WORKSP was perhaps
                                ; changed by POINTERS routine.
        pop bc                  ; restore count for return value.
        ex de, hl               ; switch. DE = location after first new space
        inc hl                  ; HL now location after new space
        ret                     ; return.


; ---------------------------
; Clear various editing areas
; ---------------------------
; This routine sets the editing area, workspace and calculator stack
; to their minimum configurations as at initialization and indeed this
; routine could have been relied on to perform that task.
; This routine uses HL only and returns with that register holding
; WORKSP/STKBOT/STKEND though no use is made of this. The routines also
; reset MEM to its usual place in the systems variable area should it
; have been relocated to a FOR-NEXT variable. The main entry point
; SET-MIN is called at the start of the MAIN-EXEC loop and prior to
; displaying an error.

;; SET-MIN

SET_MIN:
        ld hl, (E_LINE)         ; fetch E_LINE
        ld (hl), $0D            ; insert carriage return
        ld (K_CUR), hl          ; make K_CUR keyboard cursor point there.
        inc hl                  ; next location
        ldi (hl), $80           ; holds end-marker $80
                                ; next location becomes
        ld (WORKSP), hl         ; start of WORKSP

; This entry point is used prior to input and prior to the execution,
; or parsing, of each statement.

;; SET-WORK

SET_WORK:
        ld hl, (WORKSP)         ; fetch WORKSP value
        ld (STKBOT), hl         ; and place in STKBOT

; This entry point is used to move the stack back to its normal place
; after temporary relocation during line entry and also from ERROR-3

;; SET-STK

SET_STK:
        ld hl, (STKBOT)         ; fetch STKBOT value
        ld (STKEND), hl         ; and place in STKEND.

        push hl                 ; perhaps an obsolete entry point.
        ld hl, MEMBOT           ; normal location of MEM-0
        ld (MEM), hl            ; is restored to system variable MEM.
        pop hl                  ; saved value not required.
        ret                     ; return.


; ------------------
; Reclaim edit-line?
; ------------------
; This seems to be legacy code from the ZX80/ZX81 as it is 
; not used in this ROM.
; That task, in fact, is performed here by the dual-area routine CLEAR-SP.
; This routine is designed to deal with something that is known to be in the
; edit buffer and not workspace.
; On entry, HL must point to the end of the something to be deleted.

;; REC-EDIT

REC_EDIT:
        ld de, (E_LINE)         ; fetch start of edit line from E_LINE.
        jp RECLAIM_1            ; jump forward to RECLAIM-1.


; --------------------------
; The Table INDEXING routine
; --------------------------
; This routine is used to search two-byte hash tables for a character
; held in C, returning the address of the following offset byte.
; if it is known that the character is in the table e.g. for priorities,
; then the table requires no zero end-marker. If this is not known at the
; outset then a zero end-marker is required and carry is set to signal
; success.

;; INDEXER-1

INDEXER_1:

t/data/zx48_benchmark.asm  view on Meta::CPAN

                                ; line.

; This routine is called from AUTO-LIST

;; LIST-ALL

LIST_ALL:
        ld e, $01               ; signal current line not yet printed

;; LIST-ALL-2

LIST_ALL_2:
        call OUT_LINE           ; routine OUT-LINE outputs a BASIC line
                                ; using PRINT-OUT and makes an early return
                                ; when no more lines to print. >>>

        rst $10                 ; PRINT-A prints the carriage return (in A)

        bit 4, (iy+TV_FLAG-IY0) ; test TV_FLAG  - automatic listing ?
        jr z, LIST_ALL_2        ; back to LIST-ALL-2 if not
                                ; (loop exit is via OUT-LINE)

; continue here if an automatic listing required.

        ld a, (DF_SZ)           ; fetch DF_SZ lower display file size.
        sub (iy+S_POSN_hi-IY0)  ; subtract S_POSN_hi ithe current line number.
        jr nz, LIST_ALL_2       ; back to LIST-ALL-2 if upper screen not full.

        xor e                   ; A contains zero, E contains one if the
                                ; current edit line has not been printed
                                ; or zero if it has (from OUT-LINE).
        ret z                   ; return if the screen is full and the line
                                ; has been printed.

; continue with automatic listings if the screen is full and the current
; edit line is missing. OUT-LINE will scroll automatically.

        push hl                 ; save the pointer address.
        push de                 ; save the E flag.
        ld hl, S_TOP            ; fetch S_TOP the rough estimate.
        call LN_FETCH           ; routine LN-FETCH updates S_TOP with
                                ; the number of the next line.
        pop de                  ; restore the E flag.
        pop hl                  ; restore the address of the next line.
        jr LIST_ALL_2           ; back to LIST-ALL-2.


; ------------------------
; Print a whole BASIC line
; ------------------------
; This routine prints a whole BASIC line and it is called
; from LIST-ALL to output the line to current channel
; and from ED-EDIT to 'sprint' the line to the edit buffer.

;; OUT-LINE

OUT_LINE:
        ld bc, (E_PPC)          ; fetch E_PPC the current line which may be
                                ; unchecked and not exist.
        call CP_LINES           ; routine CP-LINES finds match or line after.
        ld d, $3E               ; prepare cursor '>' in D.
        jr z, OUT_LINE1         ; to OUT-LINE1 if matched or line after.

        ld de, $0000            ; put zero in D, to suppress line cursor.
        rl e                    ; pick up carry in E if line before current
                                ; leave E zero if same or after.

;; OUT-LINE1

OUT_LINE1:
        ld (iy+BREG-IY0), e     ; save flag in BREG which is spare.
        ld a, (hl)              ; get high byte of line number.
        cp $40                  ; is it too high ($2F is maximum possible) ?
        pop bc                  ; drop the return address and
        ret nc                  ; make an early return if so >>>

        push bc                 ; save return address
        call OUT_NUM_2          ; routine OUT-NUM-2 to print addressed number
                                ; with leading space.
        inc hl                  ; skip low number byte.
        inc hl                  ; and the two
        inc hl                  ; length bytes.
        res 0, (iy+FLAGS-IY0)   ; update FLAGS - signal leading space required.
        ld a, d                 ; fetch the cursor.
        and a                   ; test for zero.
        jr z, OUT_LINE3         ; to OUT-LINE3 if zero.


        rst $10                 ; PRINT-A prints '>' the current line cursor.

; this entry point is called from ED-COPY

;; OUT-LINE2

OUT_LINE2:
        set 0, (iy+FLAGS-IY0)   ; update FLAGS - suppress leading space.

;; OUT-LINE3

OUT_LINE3:
        push de                 ; save flag E for a return value.
        ex de, hl               ; save HL address in DE.
        res 2, (iy+FLAGS2-IY0)  ; update FLAGS2 - signal NOT in QUOTES.

        ld hl, FLAGS            ; point to FLAGS.
        res 2, (hl)             ; signal 'K' mode. (starts before keyword)
        bit 5, (iy+FLAGX-IY0)   ; test FLAGX - input mode ?
        jr z, OUT_LINE4         ; forward to OUT-LINE4 if not.

        set 2, (hl)             ; signal 'L' mode. (used for input)

;; OUT-LINE4

OUT_LINE4:
        ld hl, (X_PTR)          ; fetch X_PTR - possibly the error pointer
                                ; address.
        and a                   ; clear the carry flag.
        sbc hl, de              ; test if an error address has been reached.
        jr nz, OUT_LINE5        ; forward to OUT-LINE5 if not.

        ld a, $3F               ; load A with '?' the error marker.
        call OUT_FLASH          ; routine OUT-FLASH to print flashing marker.

;; OUT-LINE5

OUT_LINE5:
        call OUT_CURS           ; routine OUT-CURS will print the cursor if
                                ; this is the right position.
        ex de, hl               ; restore address pointer to HL.
        ld a, (hl)              ; fetch the addressed character.
        call NUMBER             ; routine NUMBER skips a hidden floating
                                ; point number if present.
        inc hl                  ; now increment the pointer.
        cp $0D                  ; is character end-of-line ?
        jr z, OUT_LINE6         ; to OUT-LINE6, if so, as line is finished.

        ex de, hl               ; save the pointer in DE.
        call OUT_CHAR           ; routine OUT-CHAR to output character/token.

        jr OUT_LINE4            ; back to OUT-LINE4 until entire line is done.


; ---

;; OUT-LINE6

OUT_LINE6:
        pop de                  ; bring back the flag E, zero if current
                                ; line printed else 1 if still to print.
        ret                     ; return with A holding $0D


; -------------------------
; Check for a number marker
; -------------------------
; this subroutine is called from two processes. while outputting BASIC lines
; and while searching statements within a BASIC line.
; during both, this routine will pass over an invisible number indicator
; and the five bytes floating-point number that follows it.
; Note that this causes floating point numbers to be stripped from
; the BASIC line when it is fetched to the edit buffer by OUT_LINE.
; the number marker also appears after the arguments of a DEF FN statement
; and may mask old 5-byte string parameters.

;; NUMBER

NUMBER:
        cp $0E                  ; character fourteen ?
        ret nz                  ; return if not.

        inc hl                  ; skip the character
        inc hl                  ; and five bytes
        inc hl                  ; following.
        inc hl
        inc hl
        inc hl
        ld a, (hl)              ; fetch the following character
        ret                     ; for return value.


; --------------------------
; Print a flashing character
; --------------------------
; This subroutine is called from OUT-LINE to print a flashing error
; marker '?' or from the next routine to print a flashing cursor e.g. 'L'.
; However, this only gets called from OUT-LINE when printing the edit line
; or the input buffer to the lower screen so a direct call to $09F4 can
; be used, even though out-line outputs to other streams.
; In fact the alternate set is used for the whole routine.

;; OUT-FLASH

OUT_FLASH:
        exx                     ; switch in alternate set

        ld hl, (ATTR_T)         ; fetch L = ATTR_T, H = MASK-T
        push hl                 ; save masks.
        res 7, h                ; reset flash mask bit so active.
        set 7, l                ; make attribute FLASH.
        ld (ATTR_T), hl         ; resave ATTR_T and MASK-T

        ld hl, P_FLAG           ; address P_FLAG
        ld d, (hl)              ; fetch to D
        push de                 ; and save.
        ld (hl), $00            ; clear inverse, over, ink/paper 9

        call PRINT_OUT          ; routine PRINT-OUT outputs character
                                ; without the need to vector via RST 10.

        pop hl                  ; pop P_FLAG to H.
        ld (iy+P_FLAG-IY0), h   ; and restore system variable P_FLAG.
        pop hl                  ; restore temporary masks
        ld (ATTR_T), hl         ; and restore system variables ATTR_T/MASK_T

        exx                     ; switch back to main set
        ret                     ; return


; ----------------
; Print the cursor
; ----------------
; This routine is called before any character is output while outputting
; a BASIC line or the input buffer. This includes listing to a printer
; or screen, copying a BASIC line to the edit buffer and printing the
; input buffer or edit buffer to the lower screen. It is only in the
; latter two cases that it has any relevance and in the last case it
; performs another very important function also.

;; OUT-CURS

OUT_CURS:
        ld hl, (K_CUR)          ; fetch K_CUR the current cursor address
        and a                   ; prepare for true subtraction.
        sbc hl, de              ; test against pointer address in DE and
        ret nz                  ; return if not at exact position.

; the value of MODE, maintained by KEY-INPUT, is tested and if non-zero
; then this value 'E' or 'G' will take precedence.

        ld a, (MODE)            ; fetch MODE  0='KLC', 1='E', 2='G'.
        rlc a                   ; double the value and set flags.
        jr z, OUT_C_1           ; to OUT-C-1 if still zero ('KLC').

        add a, $43              ; add 'C' - will become 'E' if originally 1
                                ; or 'G' if originally 2.
        jr OUT_C_2              ; forward to OUT-C-2 to print.


; ---

; If mode was zero then, while printing a BASIC line, bit 2 of flags has been
; set if 'THEN' or ':' was encountered as a main character and reset otherwise.
; This is now used to determine if the 'K' cursor is to be printed but this
; transient state is also now transferred permanently to bit 3 of FLAGS
; to let the interrupt routine know how to decode the next key.

;; OUT-C-1

OUT_C_1:
        ld hl, FLAGS            ; Address FLAGS
        res 3, (hl)             ; signal 'K' mode initially.
        ld a, $4B               ; prepare letter 'K'.
        bit 2, (hl)             ; test FLAGS - was the
                                ; previous main character ':' or 'THEN' ?
        jr z, OUT_C_2           ; forward to OUT-C-2 if so to print.

        set 3, (hl)             ; signal 'L' mode to interrupt routine.
                                ; Note. transient bit has been made permanent.
        inc a                   ; augment from 'K' to 'L'.

        bit 3, (iy+FLAGS2-IY0)  ; test FLAGS2 - consider caps lock ?
                                ; which is maintained by KEY-INPUT.
        jr z, OUT_C_2           ; forward to OUT-C-2 if not set to print.

        ld a, $43               ; alter 'L' to 'C'.

;; OUT-C-2

OUT_C_2:
        push de                 ; save address pointer but OK as OUT-FLASH
                                ; uses alternate set without RST 10.

        call OUT_FLASH          ; routine OUT-FLASH to print.

        pop de                  ; restore and
        ret                     ; return.


; ----------------------------
; Get line number of next line
; ----------------------------
; These two subroutines are called while editing.
; This entry point is from ED-DOWN with HL addressing E_PPC
; to fetch the next line number.
; Also from AUTO-LIST with HL addressing S_TOP just to update S_TOP
; with the value of the next line number. It gets fetched but is discarded.
; These routines never get called while the editor is being used for input.

;; LN-FETCH

LN_FETCH:
        ldi e, (hl)             ; fetch low byte
                                ; address next
        ld d, (hl)              ; fetch high byte.
        push hl                 ; save system variable hi pointer.
        ex de, hl               ; line number to HL,
        inc hl                  ; increment as a starting point.
        call LINE_ADDR          ; routine LINE-ADDR gets address in HL.
        call LINE_NO            ; routine LINE-NO gets line number in DE.
        pop hl                  ; restore system variable hi pointer.

; This entry point is from the ED-UP with HL addressing E_PPC_hi

t/data/zx48_benchmark.asm  view on Meta::CPAN



; -------------------------------------
; Outputting characters in a BASIC line
; -------------------------------------
; This subroutine ...

;; OUT-CHAR

OUT_CHAR:
        call NUMERIC            ; routine NUMERIC tests if it is a digit ?
        jr nc, OUT_CH_3         ; to OUT-CH-3 to print digit without
                                ; changing mode. Will be 'K' mode if digits
                                ; are at beginning of edit line.

        cp $21                  ; less than quote character ?
        jr c, OUT_CH_3          ; to OUT-CH-3 to output controls and space.

        res 2, (iy+FLAGS-IY0)   ; initialize FLAGS to 'K' mode and leave
                                ; unchanged if this character would precede
                                ; a keyword.

        cp $CB                  ; is character 'THEN' token ?
        jr z, OUT_CH_3          ; to OUT-CH-3 to output if so.

        cp $3A                  ; is it ':' ?
        jr nz, OUT_CH_1         ; to OUT-CH-1 if not statement separator
                                ; to change mode back to 'L'.

        bit 5, (iy+FLAGX-IY0)   ; FLAGX  - Input Mode ??
        jr nz, OUT_CH_2         ; to OUT-CH-2 if in input as no statements.
                                ; Note. this check should seemingly be at
                                ; the start. Commands seem inappropriate in
                                ; INPUT mode and are rejected by the syntax
                                ; checker anyway.
                                ; unless INPUT LINE is being used.

        bit 2, (iy+FLAGS2-IY0)  ; test FLAGS2 - is the ':' within quotes ?
        jr z, OUT_CH_3          ; to OUT-CH-3 if ':' is outside quoted text.

        jr OUT_CH_2             ; to OUT-CH-2 as ':' is within quotes


; ---

;; OUT-CH-1

OUT_CH_1:
        cp $22                  ; is it quote character '"'  ?
        jr nz, OUT_CH_2         ; to OUT-CH-2 with others to set 'L' mode.

        push af                 ; save character.
        ld a, (FLAGS2)          ; fetch FLAGS2.
        xor $04                 ; toggle the quotes flag.
        ld (FLAGS2), a          ; update FLAGS2
        pop af                  ; and restore character.

;; OUT-CH-2

OUT_CH_2:
        set 2, (iy+FLAGS-IY0)   ; update FLAGS - signal L mode if the cursor
                                ; is next.

;; OUT-CH-3

OUT_CH_3:
        rst $10                 ; PRINT-A vectors the character to
                                ; channel 'S', 'K', 'R' or 'P'.
        ret                     ; return.


; -------------------------------------------
; Get starting address of line, or line after
; -------------------------------------------
; This routine is used often to get the address, in HL, of a BASIC line
; number supplied in HL, or failing that the address of the following line
; and the address of the previous line in DE.

;; LINE-ADDR

LINE_ADDR:
        push hl                 ; save line number in HL register
        ld hl, (PROG)           ; fetch start of program from PROG
        ld de, hl               ; transfer address to
                                ; the DE register pair.

;; LINE-AD-1

LINE_AD_1:
        pop bc                  ; restore the line number to BC
        call CP_LINES           ; routine CP-LINES compares with that
                                ; addressed by HL
        ret nc                  ; return if line has been passed or matched.
                                ; if NZ, address of previous is in DE

        push bc                 ; save the current line number
        call NEXT_ONE           ; routine NEXT-ONE finds address of next
                                ; line number in DE, previous in HL.
        ex de, hl               ; switch so next in HL
        jr LINE_AD_1            ; back to LINE-AD-1 for another comparison


; --------------------
; Compare line numbers
; --------------------
; This routine compares a line number supplied in BC with an addressed
; line number pointed to by HL.

;; CP-LINES

CP_LINES:
        ld a, (hl)              ; Load the high byte of line number and
        cp b                    ; compare with that of supplied line number.
        ret nz                  ; return if yet to match (carry will be set).

        inc hl                  ; address low byte of
        ldd a, (hl)             ; number and pick up in A.
                                ; step back to first position.
        cp c                    ; now compare.
        ret                     ; zero set if exact match.
                                ; carry set if yet to match.

t/data/zx48_benchmark.asm  view on Meta::CPAN

;; IN-ITEM-3

IN_ITEM_3:
        call ALPHA              ; routine ALPHA checks if character is
                                ; a suitable variable name.
        jp nc, IN_NEXT_1        ; forward to IN-NEXT-1 if not

        call CLASS_01           ; routine CLASS-01 returns destination
                                ; address of variable to be assigned.
        res 7, (iy+FLAGX-IY0)   ; update FLAGX  - signal not INPUT LINE.

;; IN-PROMPT

IN_PROMPT:
        call SYNTAX_Z           ; routine SYNTAX-Z
        jp z, IN_NEXT_2         ; forward to IN-NEXT-2 if checking syntax.

        call SET_WORK           ; routine SET-WORK clears workspace.
        ld hl, FLAGX            ; point to system variable FLAGX
        res 6, (hl)             ; signal string result.
        set 5, (hl)             ; signal in Input Mode for editor.
        ld bc, $0001            ; initialize space required to one for
                                ; the carriage return.
        bit 7, (hl)             ; test FLAGX - INPUT LINE in use ?
        jr nz, IN_PR_2          ; forward to IN-PR-2 if so as that is
                                ; all the space that is required.

        ld a, (FLAGS)           ; load accumulator from FLAGS
        and $40                 ; mask to test BIT 6 of FLAGS and clear
                                ; the other bits in A.
                                ; numeric result expected ?
        jr nz, IN_PR_1          ; forward to IN-PR-1 if so

        ld c, $03               ; increase space to three bytes for the
                                ; pair of surrounding quotes.

;; IN-PR-1

IN_PR_1:
        or (hl)                 ; if numeric result, set bit 6 of FLAGX.
        ld (hl), a              ; and update system variable

;; IN-PR-2

IN_PR_2:
        rst $30                 ; BC-SPACES opens 1 or 3 bytes in workspace
        ld (hl), $0D            ; insert carriage return at last new location.
        ld a, c                 ; fetch the length, one or three.
        rrca                    ; lose bit 0.
        rrca                    ; test if quotes required.
        jr nc, IN_PR_3          ; forward to IN-PR-3 if not.

        ld a, $22               ; load the '"' character
        ld (de), a              ; place quote in first new location at DE.
        dec hl                  ; decrease HL - from carriage return.
        ld (hl), a              ; and place a quote in second location.

;; IN-PR-3

IN_PR_3:
        ld (K_CUR), hl          ; set keyboard cursor K_CUR to HL
        bit 7, (iy+FLAGX-IY0)   ; test FLAGX  - is this INPUT LINE ??
        jr nz, IN_VAR_3         ; forward to IN-VAR-3 if so as input will
                                ; be accepted without checking its syntax.

        ld hl, (CH_ADD)         ; fetch CH_ADD
        push hl                 ; and save on stack.
        ld hl, (ERR_SP)         ; fetch ERR_SP
        push hl                 ; and save on stack

;; IN-VAR-1

IN_VAR_1:
        ld hl, IN_VAR_1         ; address: IN-VAR-1 - this address
        push hl                 ; is saved on stack to handle errors.
        bit 4, (iy+FLAGS2-IY0)  ; test FLAGS2  - is K channel in use ?
        jr z, IN_VAR_2          ; forward to IN-VAR-2 if not using the
                                ; keyboard for input. (??)

        ld (ERR_SP), sp         ; set ERR_SP to point to IN-VAR-1 on stack.

;; IN-VAR-2

IN_VAR_2:
        ld hl, (WORKSP)         ; set HL to WORKSP - start of workspace.
        call REMOVE_FP          ; routine REMOVE-FP removes floating point
                                ; forms when looping in error condition.
        ld (iy+ERR_NR-IY0), $FF ; set ERR_NR to 'OK' cancelling the error.
                                ; but X_PTR causes flashing error marker
                                ; to be displayed at each call to the editor.
        call EDITOR             ; routine EDITOR allows input to be entered
                                ; or corrected if this is second time around.

; if we pass to next then there are no system errors

        res 7, (iy+FLAGS-IY0)   ; update FLAGS  - signal checking syntax
        call IN_ASSIGN          ; routine IN-ASSIGN checks syntax using
                                ; the VAL-FET-2 and powerful SCANNING routines.
                                ; any syntax error and its back to IN-VAR-1.
                                ; but with the flashing error marker showing
                                ; where the error is.
                                ; Note. the syntax of string input has to be
                                ; checked as the user may have removed the
                                ; bounding quotes or escaped them as with
                                ; "hat" + "stand" for example.
                                ; proceed if syntax passed.

        jr IN_VAR_4             ; jump forward to IN-VAR-4


; ---

; the jump was to here when using INPUT LINE.

;; IN-VAR-3

IN_VAR_3:
        call EDITOR             ; routine EDITOR is called for input

; when ENTER received rejoin other route but with no syntax check.

; INPUT and INPUT LINE converge here.

;; IN-VAR-4

IN_VAR_4:
        ld (iy+$22), $00        ; set K_CUR_hi to a low value so that the cursor
                                ; no longer appears in the input line.

        call IN_CHAN_K          ; routine IN-CHAN-K tests if the keyboard
                                ; is being used for input.
        jr nz, IN_VAR_5         ; forward to IN-VAR-5 if using another input
                                ; channel.

; continue here if using the keyboard.

        call ED_COPY            ; routine ED-COPY overprints the edit line
                                ; to the lower screen. The only visible
                                ; affect is that the cursor disappears.
                                ; if you're inputting more than one item in
                                ; a statement then that becomes apparent.

        ld bc, (ECHO_E)         ; fetch line and column from ECHO_E
        call CL_SET             ; routine CL-SET sets S-POSNL to those
                                ; values.

; if using another input channel rejoin here.

;; IN-VAR-5

IN_VAR_5:
        ld hl, FLAGX            ; point HL to FLAGX
        res 5, (hl)             ; signal not in input mode
        bit 7, (hl)             ; is this INPUT LINE ?
        res 7, (hl)             ; cancel the bit anyway.
        jr nz, IN_VAR_6         ; forward to IN-VAR-6 if INPUT LINE.

        pop hl                  ; drop the looping address
        pop hl                  ; drop the address of previous
                                ; error handler.
        ld (ERR_SP), hl         ; set ERR_SP to point to it.
        pop hl                  ; drop original CH_ADD which points to
                                ; INPUT command in BASIC line.
        ld (X_PTR), hl          ; save in X_PTR while input is assigned.
        set 7, (iy+FLAGS-IY0)   ; update FLAGS - Signal running program
        call IN_ASSIGN          ; routine IN-ASSIGN is called again
                                ; this time the variable will be assigned
                                ; the input value without error.
                                ; Note. the previous example now
                                ; becomes "hatstand"

        ld hl, (X_PTR)          ; fetch stored CH_ADD value from X_PTR.
        ld (iy+$26), $00        ; set X_PTR_hi so that iy is no longer relevant.
        ld (CH_ADD), hl         ; put restored value back in CH_ADD
        jr IN_NEXT_2            ; forward to IN-NEXT-2 to see if anything
                                ; more in the INPUT list.


; ---

; the jump was to here with INPUT LINE only

;; IN-VAR-6

IN_VAR_6:
        ld hl, (STKBOT)         ; STKBOT points to the end of the input.
        ld de, (WORKSP)         ; WORKSP points to the beginning.
        scf                     ; prepare for true subtraction.
        sbc hl, de              ; subtract to get length
        ld bc, hl               ; transfer it to
                                ; the BC register pair.
        call STK_STO__          ; routine STK-STO-$ stores parameters on
                                ; the calculator stack.
        call LET                ; routine LET assigns it to destination.
        jr IN_NEXT_2            ; forward to IN-NEXT-2 as print items
                                ; not allowed with INPUT LINE.
                                ; Note. that "hat" + "stand" will, for
                                ; example, be unchanged as also would
                                ; 'PRINT "Iris was here"'.



( run in 0.597 second using v1.01-cache-2.11-cpan-39bf76dae61 )