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 )