CPU-Z80-Disassembler
view release on metacpan or search on metacpan
t/data/zx48.asm view on Meta::CPAN
; update X_PTR to the location reached by CH_ADD and jump to ED-ERROR
; where the error will be cancelled and the loop begin again from ED-AGAIN
; above. The position of the error will be apparent when the lower screen is
; reprinted. If no error then the re-iteration is to ED-LOOP below when
; input is arriving from the keyboard.
;; ED-LOOP
L0F38: CALL L15D4 ; 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-$01) ; on PIP value for duration.
LD HL,$00C8 ; and pitch.
CALL L03B5 ; routine BEEPER gives click - effective
; with rubber keyboard.
POP AF ; get saved key value.
LD HL,L0F38 ; 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,L0F81 ; forward to ADD-CHAR if so.
CP $07 ; lower than 7 ?
JR C,L0F81 ; 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,L0F92 ; 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,L0F6C ; 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+$37) ; test FLAGX - Is this INPUT LINE ?
JP Z,L101E ; jump to ED-IGNORE if not, else
CALL L15D4 ; routine WAIT-KEY - input address is KEY-NEXT
; but is reset to KEY-INPUT
LD E,A ; save first in E
;; ED-CONTR
L0F6C: CALL L15D4 ; routine WAIT-KEY for control.
; input address will be key-next.
PUSH DE ; saved code/parameters
LD HL,($5C5B) ; fetch address of keyboard cursor from K_CUR
RES 0,(IY+$07) ; set MODE to 'L'
CALL L1655 ; routine MAKE-ROOM makes 2/3 spaces at cursor
POP BC ; restore code/parameters
INC HL ; address first location
LD (HL),B ; place code (ink etc.)
INC HL ; address next
LD (HL),C ; place possible parameter. If only one
; then DE points to this location also.
JR L0F8B ; 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
L0F81: RES 0,(IY+$07) ; set MODE to 'L'
X0F85: LD HL,($5C5B) ; fetch address of keyboard cursor from K_CUR
CALL L1652 ; routine ONE-SPACE creates one space.
; either a continuation of above or from ED-CONTR with ED-LOOP on stack.
;; ADD-CH-1
L0F8B: LD (DE),A ; load current character to last new location.
INC DE ; address next
LD ($5C5B),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
L0F92: LD E,A ; character to E.
LD D,$00 ; prepare to add.
LD HL,L0FA0 - 7 ; 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,($5C5B) ; 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
L0FA0: DEFB L0FA9 - $ ; 07d offset $09 to Address: ED-EDIT
DEFB L1007 - $ ; 08d offset $66 to Address: ED-LEFT
DEFB L100C - $ ; 09d offset $6A to Address: ED-RIGHT
DEFB L0FF3 - $ ; 10d offset $50 to Address: ED-DOWN
DEFB L1059 - $ ; 11d offset $B5 to Address: ED-UP
DEFB L1015 - $ ; 12d offset $70 to Address: ED-DELETE
DEFB L1024 - $ ; 13d offset $7E to Address: ED-ENTER
DEFB L1076 - $ ; 14d offset $CF to Address: ED-SYMBOL
DEFB L107C - $ ; 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
L0FA9: LD HL,($5C49) ; fetch E_PPC the last line number entered.
; Note. may not exist and may follow program.
BIT 5,(IY+$37) ; test FLAGX - input mode ?
JP NZ,L1097 ; jump forward to CLEAR-SP if not in editor.
CALL L196E ; routine LINE-ADDR to find address of line
; or following line if it doesn't exist.
CALL L1695 ; 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,L1097 ; 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.
LD C,(HL) ; transfer to C
INC HL ; 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 B,H ; transfer adjusted value
LD C,L ; to BC register.
CALL L1F05 ; routine TEST-ROOM checks free memory.
CALL L1097 ; routine CLEAR-SP clears editing area.
LD HL,($5C51) ; 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 L1601 ; routine CHAN-OPEN opens it
POP HL ; drop line address
DEC HL ; make it point to first byte of line num.
DEC (IY+$0F) ; 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 L1855 ; routine OUT-LINE outputs the BASIC line
; to the editing area.
INC (IY+$0F) ; restore E_PPC_lo to the previous value.
LD HL,($5C59) ; address E_LINE in editing area.
INC HL ; advance
INC HL ; past space
INC HL ; and digit characters
INC HL ; of line number.
LD ($5C5B),HL ; update K_CUR to address start of BASIC.
POP HL ; restore the address of CURCHL.
CALL L1615 ; 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
L0FF3: BIT 5,(IY+$37) ; test FLAGX - Input Mode ?
JR NZ,L1001 ; skip to ED-STOP if so
LD HL,$5C49 ; address E_PPC - 'current line'
CALL L190F ; routine LN-FETCH fetches number of next
; line or same if at end of program.
JR L106E ; forward to ED-LIST to produce an
; automatic listing.
; ---
;; ED-STOP
L1001: LD (IY+$00),$10 ; set ERR_NR to 'STOP in INPUT' code
JR L1024 ; 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
L1007: CALL L1031 ; routine ED-EDGE moves left if possible
JR L1011 ; 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
L100C: 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
L1011: LD ($5C5B),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
L1015: CALL L1031 ; routine ED-EDGE moves cursor to left.
LD BC,$0001 ; of character to be deleted.
JP L19E8 ; 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
L101E: CALL L15D4 ; routine WAIT-KEY to ignore keystroke.
CALL L15D4 ; routine WAIT-KEY to ignore next key.
; -------------
; Enter/newline
; -------------
; The enter key has been pressed to have BASIC line or input accepted.
;; ED-ENTER
L1024: POP HL ; discard address ED-LOOP
POP HL ; drop address ED-ERROR
;; ED-END
L1026: POP HL ; the previous value of ERR_SP
LD ($5C3D),HL ; is restored to ERR_SP system variable
BIT 7,(IY+$00) ; 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
L1031: SCF ; carry flag must be set to call the nested
CALL L1195 ; 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 B,H ; transfer HL - cursor address
LD C,L ; to BC register pair.
; at this point DE addresses start of line.
;; ED-EDGE-1
L103E: LD H,D ; transfer DE - leftmost pointer
LD L,E ; 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,L1051 ; 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,L1051 ; forward to ED-EDGE-2 if not
; HL has been incremented twice
INC HL ; increment a third time for 'at'/'tab'
;; ED-EDGE-2
L1051: 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,L103E ; 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
L1059: BIT 5,(IY+$37) ; test FLAGX - input mode ?
RET NZ ; return if not in editor - to ED-LOOP.
LD HL,($5C49) ; get current line from E_PPC
CALL L196E ; routine LINE-ADDR gets address
EX DE,HL ; and previous in DE
CALL L1695 ; routine LINE-NO gets prev line number
LD HL,$5C4A ; set HL to E_PPC_hi as next routine stores
; top first.
CALL L191C ; 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
L106E: CALL L1795 ; routine AUTO-LIST lists to upper screen
; including adjusted current line.
LD A,$00 ; select lower screen again
JP L1601 ; 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
L1076: BIT 7,(IY+$37) ; test FLAGX - is this INPUT LINE ?
JR Z,L1024 ; back to ED-ENTER if not to treat as if
; enter had been pressed.
; else continue and add code to buffer.
; Next is chr$ 15
; Note that ADD-CHAR precedes the table so we can't offset to it directly.
;; ED-GRAPH
L107C: JP L0F81 ; jump back to ADD-CHAR
t/data/zx48.asm view on Meta::CPAN
; Note. while in Extended/Graphics mode,
; the Extended Mode/Graphics key is pressed
; again to get out.
;; KEY-FLAG
L10F4: SET 3,(IY+$02) ; update TV_FLAG - show key state has changed
CP A ; clear carry and reset zero flags -
; no actual key returned.
RET ; make the return.
; ---
; now deal with colour controls - 16-23 ink, 24-31 paper
;; KEY-CONTR
L10FA: 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,L1105 ; forward to KEY-DATA with INK 16d and
; colour in C.
INC A ; else change from INK to PAPER (17d) if so.
;; KEY-DATA
L1105: LD (IY-$2D),C ; put the colour (0-7)/state(0/1) in KDATA
LD DE,L110D ; address: KEY-NEXT will be next input stream
JR L1113 ; forward to KEY-CHAN to change it ...
; ---
; ... so that INPUT_AD directs control to here at next call to WAIT-KEY
;; KEY-NEXT
L110D: LD A,($5C0D) ; pick up the parameter stored in KDATA.
LD DE,L10A8 ; address: KEY-INPUT will be next input stream
; continue to restore default channel and
; make a return with the control code.
;; KEY-CHAN
L1113: LD HL,($5C4F) ; 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
LD (HL),E ; and update the input
INC HL ; routine address for
LD (HL),D ; the next call to WAIT-KEY.
;; KEY-DONE2
L111B: 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
L111D: CALL L0D4D ; routine TEMPS sets temporary attributes.
RES 3,(IY+$02) ; update TV_FLAG - signal no change in mode
RES 5,(IY+$02) ; update TV_FLAG - signal don't clear lower
; screen.
LD HL,($5C8A) ; fetch SPOSNL
PUSH HL ; and save on stack.
LD HL,($5C3D) ; fetch ERR_SP
PUSH HL ; and save also
LD HL,L1167 ; address: ED-FULL
PUSH HL ; is pushed as the error routine
LD ($5C3D),SP ; and ERR_SP made to point to it.
LD HL,($5C82) ; fetch ECHO_E
PUSH HL ; and push also
SCF ; set carry flag to control SET-DE
CALL L1195 ; call routine SET-DE
; if in input DE = WORKSP
; if in edit DE = E_LINE
EX DE,HL ; start address to HL
CALL L187D ; 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 L18E1 ; routine OUT-CURS considers a
; terminating cursor.
LD HL,($5C8A) ; fetch updated SPOSNL
EX (SP),HL ; exchange with ECHO_E on stack
EX DE,HL ; transfer ECHO_E to DE
CALL L0D4D ; 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
L1150: LD A,($5C8B) ; fetch SPOSNL_hi is current line
SUB D ; compare with old
JR C,L117C ; forward to ED-C-DONE if no blanking
JR NZ,L115E ; forward to ED-SPACES if line has changed
LD A,E ; old column to A
SUB (IY+$50) ; subtract new in SPOSNL_lo
JR NC,L117C ; forward to ED-C-DONE if no backfilling.
;; ED-SPACES
L115E: LD A,$20 ; prepare a space.
PUSH DE ; save old line/column.
CALL L09F4 ; 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 L1150 ; 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
L1167: LD D,$00 ; prepare to moan.
LD E,(IY-$02) ; fetch RASP value.
LD HL,$1A90 ; set pitch or tone period.
CALL L03B5 ; routine BEEPER.
LD (IY+$00),$FF ; clear ERR_NR.
LD DE,($5C8A) ; fetch SPOSNL.
JR L117E ; forward to ED-C-END
; -------
; the exit point from line printing continues here.
;; ED-C-DONE
L117C: POP DE ; fetch new line/column.
POP HL ; fetch the error address.
t/data/zx48.asm view on Meta::CPAN
; the program 'end-marker' then the previous line is used and if that
; should also be unacceptable then zero is used as it must be a direct
; command. The program end-marker is the variables end-marker $80, or
; if variables exist, then the first character of any variable name.
;; LINE-ZERO
L168F: DEFB $00, $00 ; dummy line number used for direct commands
;; LINE-NO-A
L1691: EX DE,HL ; fetch the previous line to HL and set
LD DE,L168F ; DE to LINE-ZERO should HL also fail.
; -> The Entry Point.
;; LINE-NO
L1695: LD A,(HL) ; fetch the high byte - max $2F
AND $C0 ; mask off the invalid bits.
JR NZ,L1691 ; to LINE-NO-A if an end-marker.
LD D,(HL) ; reload the high byte.
INC HL ; 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
L169E: LD HL,($5C63) ; STKBOT first location of calculator stack
DEC HL ; make one less than new location
CALL L1655 ; routine MAKE-ROOM creates the room.
INC HL ; address the first new location
INC HL ; advance to second
POP BC ; restore old WORKSP
LD ($5C61),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
L16B0: LD HL,($5C59) ; fetch E_LINE
LD (HL),$0D ; insert carriage return
LD ($5C5B),HL ; make K_CUR keyboard cursor point there.
INC HL ; next location
LD (HL),$80 ; holds end-marker $80
INC HL ; next location becomes
LD ($5C61),HL ; start of WORKSP
; This entry point is used prior to input and prior to the execution,
; or parsing, of each statement.
;; SET-WORK
L16BF: LD HL,($5C61) ; fetch WORKSP value
LD ($5C63),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
L16C5: LD HL,($5C63) ; fetch STKBOT value
LD ($5C65),HL ; and place in STKEND.
PUSH HL ; perhaps an obsolete entry point.
LD HL,$5C92 ; normal location of MEM-0
LD ($5C68),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
L16D4: LD DE,($5C59) ; fetch start of edit line from E_LINE.
JP L19E5 ; 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
L16DB: INC HL ; address the next pair of values.
; -> The Entry Point.
;; INDEXER
L16DC: LD A,(HL) ; fetch the first byte of pair
AND A ; is it the end-marker ?
RET Z ; return with carry reset if so.
CP C ; is it the required character ?
t/data/zx48.asm view on Meta::CPAN
; available for checking if they are direct
; commands.
LD H,A ; transfer the modified
LD L,C ; line number to HL.
LD ($5C49),HL ; update E_PPC to new line number.
CALL L196E ; routine LINE-ADDR gets the address of the
; line.
; This routine is called from AUTO-LIST
;; LIST-ALL
L1833: LD E,$01 ; signal current line not yet printed
;; LIST-ALL-2
L1835: CALL L1855 ; routine OUT-LINE outputs a BASIC line
; using PRINT-OUT and makes an early return
; when no more lines to print. >>>
RST 10H ; PRINT-A prints the carriage return (in A)
BIT 4,(IY+$02) ; test TV_FLAG - automatic listing ?
JR Z,L1835 ; back to LIST-ALL-2 if not
; (loop exit is via OUT-LINE)
; continue here if an automatic listing required.
LD A,($5C6B) ; fetch DF_SZ lower display file size.
SUB (IY+$4F) ; subtract S_POSN_hi ithe current line number.
JR NZ,L1835 ; 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,$5C6C ; fetch S_TOP the rough estimate.
CALL L190F ; 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 L1835 ; 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
L1855: LD BC,($5C49) ; fetch E_PPC the current line which may be
; unchecked and not exist.
CALL L1980 ; routine CP-LINES finds match or line after.
LD D,$3E ; prepare cursor '>' in D.
JR Z,L1865 ; 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
L1865: LD (IY+$2D),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 L1A28 ; 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+$01) ; update FLAGS - signal leading space required.
LD A,D ; fetch the cursor.
AND A ; test for zero.
JR Z,L1881 ; to OUT-LINE3 if zero.
RST 10H ; PRINT-A prints '>' the current line cursor.
; this entry point is called from ED-COPY
;; OUT-LINE2
L187D: SET 0,(IY+$01) ; update FLAGS - suppress leading space.
;; OUT-LINE3
L1881: PUSH DE ; save flag E for a return value.
EX DE,HL ; save HL address in DE.
RES 2,(IY+$30) ; update FLAGS2 - signal NOT in QUOTES.
LD HL,$5C3B ; point to FLAGS.
RES 2,(HL) ; signal 'K' mode. (starts before keyword)
BIT 5,(IY+$37) ; test FLAGX - input mode ?
JR Z,L1894 ; forward to OUT-LINE4 if not.
SET 2,(HL) ; signal 'L' mode. (used for input)
;; OUT-LINE4
L1894: LD HL,($5C5F) ; 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,L18A1 ; forward to OUT-LINE5 if not.
LD A,$3F ; load A with '?' the error marker.
CALL L18C1 ; routine OUT-FLASH to print flashing marker.
;; OUT-LINE5
L18A1: CALL L18E1 ; 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 L18B6 ; 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,L18B4 ; to OUT-LINE6, if so, as line is finished.
EX DE,HL ; save the pointer in DE.
CALL L1937 ; routine OUT-CHAR to output character/token.
JR L1894 ; back to OUT-LINE4 until entire line is done.
; ---
;; OUT-LINE6
L18B4: 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
L18B6: 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
L18C1: EXX ; switch in alternate set
LD HL,($5C8F) ; 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 ($5C8F),HL ; resave ATTR_T and MASK-T
LD HL,$5C91 ; address P_FLAG
LD D,(HL) ; fetch to D
PUSH DE ; and save.
LD (HL),$00 ; clear inverse, over, ink/paper 9
CALL L09F4 ; routine PRINT-OUT outputs character
; without the need to vector via RST 10.
POP HL ; pop P_FLAG to H.
LD (IY+$57),H ; and restore system variable P_FLAG.
POP HL ; restore temporary masks
LD ($5C8F),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
L18E1: LD HL,($5C5B) ; 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,($5C41) ; fetch MODE 0='KLC', 1='E', 2='G'.
RLC A ; double the value and set flags.
JR Z,L18F3 ; 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 L1909 ; 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
L18F3: LD HL,$5C3B ; 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,L1909 ; 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+$30) ; test FLAGS2 - consider caps lock ?
; which is maintained by KEY-INPUT.
JR Z,L1909 ; forward to OUT-C-2 if not set to print.
LD A,$43 ; alter 'L' to 'C'.
;; OUT-C-2
L1909: PUSH DE ; save address pointer but OK as OUT-FLASH
; uses alternate set without RST 10.
CALL L18C1 ; 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
L190F: LD E,(HL) ; fetch low byte
INC HL ; 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 L196E ; routine LINE-ADDR gets address in HL.
CALL L1695 ; 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
;; LN-STORE
L191C: BIT 5,(IY+$37) ; test FLAGX - input mode ?
RET NZ ; return if so.
; Note. above already checked by ED-UP/ED-DOWN.
LD (HL),D ; save high byte of line number.
DEC HL ; address lower
t/data/zx48.asm view on Meta::CPAN
; the addition.
SBC HL,BC ; cancel the last addition
DEC A ; and decrement the digit.
JR Z,L1925 ; back to OUT-SP-2 if it is zero.
JP L15EF ; jump back to exit via OUT-CODE. ->
; -------------------------------------
; Outputting characters in a BASIC line
; -------------------------------------
; This subroutine ...
;; OUT-CHAR
L1937: CALL L2D1B ; routine NUMERIC tests if it is a digit ?
JR NC,L196C ; 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,L196C ; to OUT-CH-3 to output controls and space.
RES 2,(IY+$01) ; initialize FLAGS to 'K' mode and leave
; unchanged if this character would precede
; a keyword.
CP $CB ; is character 'THEN' token ?
JR Z,L196C ; to OUT-CH-3 to output if so.
CP $3A ; is it ':' ?
JR NZ,L195A ; to OUT-CH-1 if not statement separator
; to change mode back to 'L'.
BIT 5,(IY+$37) ; FLAGX - Input Mode ??
JR NZ,L1968 ; 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+$30) ; test FLAGS2 - is the ':' within quotes ?
JR Z,L196C ; to OUT-CH-3 if ':' is outside quoted text.
JR L1968 ; to OUT-CH-2 as ':' is within quotes
; ---
;; OUT-CH-1
L195A: CP $22 ; is it quote character '"' ?
JR NZ,L1968 ; to OUT-CH-2 with others to set 'L' mode.
PUSH AF ; save character.
LD A,($5C6A) ; fetch FLAGS2.
XOR $04 ; toggle the quotes flag.
LD ($5C6A),A ; update FLAGS2
POP AF ; and restore character.
;; OUT-CH-2
L1968: SET 2,(IY+$01) ; update FLAGS - signal L mode if the cursor
; is next.
;; OUT-CH-3
L196C: RST 10H ; 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
L196E: PUSH HL ; save line number in HL register
LD HL,($5C53) ; fetch start of program from PROG
LD D,H ; transfer address to
LD E,L ; the DE register pair.
;; LINE-AD-1
L1974: POP BC ; restore the line number to BC
CALL L1980 ; 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 L19B8 ; routine NEXT-ONE finds address of next
; line number in DE, previous in HL.
EX DE,HL ; switch so next in HL
JR L1974 ; 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
L1980: 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
LD A,(HL) ; number and pick up in A.
DEC HL ; step back to first position.
CP C ; now compare.
RET ; zero set if exact match.
; carry set if yet to match.
; no carry indicates a match or
; next available BASIC line or
; program end marker.
; -------------------
; Find each statement
; -------------------
; The single entry point EACH-STMT is used to
; 1) To find the D'th statement in a line.
; 2) To find a token in held E.
t/data/zx48.asm view on Meta::CPAN
BIT 6,(IY+$01) ; test FLAGS - numeric or string result ?
JP NZ,L1C8A ; jump back to REPORT-C if not string
; 'Nonsense in BASIC'.
JR L20FA ; forward to IN-PROMPT to set up workspace.
; ---
; the jump was here for other variables.
;; IN-ITEM-3
L20ED: CALL L2C8D ; routine ALPHA checks if character is
; a suitable variable name.
JP NC,L21AF ; forward to IN-NEXT-1 if not
CALL L1C1F ; routine CLASS-01 returns destination
; address of variable to be assigned.
RES 7,(IY+$37) ; update FLAGX - signal not INPUT LINE.
;; IN-PROMPT
L20FA: CALL L2530 ; routine SYNTAX-Z
JP Z,L21B2 ; forward to IN-NEXT-2 if checking syntax.
CALL L16BF ; routine SET-WORK clears workspace.
LD HL,$5C71 ; 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,L211C ; forward to IN-PR-2 if so as that is
; all the space that is required.
LD A,($5C3B) ; 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,L211A ; forward to IN-PR-1 if so
LD C,$03 ; increase space to three bytes for the
; pair of surrounding quotes.
;; IN-PR-1
L211A: OR (HL) ; if numeric result, set bit 6 of FLAGX.
LD (HL),A ; and update system variable
;; IN-PR-2
L211C: RST 30H ; 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,L2129 ; 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
L2129: LD ($5C5B),HL ; set keyboard cursor K_CUR to HL
BIT 7,(IY+$37) ; test FLAGX - is this INPUT LINE ??
JR NZ,L215E ; forward to IN-VAR-3 if so as input will
; be accepted without checking its syntax.
LD HL,($5C5D) ; fetch CH_ADD
PUSH HL ; and save on stack.
LD HL,($5C3D) ; fetch ERR_SP
PUSH HL ; and save on stack
;; IN-VAR-1
L213A: LD HL,L213A ; address: IN-VAR-1 - this address
PUSH HL ; is saved on stack to handle errors.
BIT 4,(IY+$30) ; test FLAGS2 - is K channel in use ?
JR Z,L2148 ; forward to IN-VAR-2 if not using the
; keyboard for input. (??)
LD ($5C3D),SP ; set ERR_SP to point to IN-VAR-1 on stack.
;; IN-VAR-2
L2148: LD HL,($5C61) ; set HL to WORKSP - start of workspace.
CALL L11A7 ; routine REMOVE-FP removes floating point
; forms when looping in error condition.
LD (IY+$00),$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 L0F2C ; 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+$01) ; update FLAGS - signal checking syntax
CALL L21B9 ; 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 L2161 ; jump forward to IN-VAR-4
; ---
; the jump was to here when using INPUT LINE.
;; IN-VAR-3
L215E: CALL L0F2C ; 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
L2161: LD (IY+$22),$00 ; set K_CUR_hi to a low value so that the cursor
; no longer appears in the input line.
CALL L21D6 ; routine IN-CHAN-K tests if the keyboard
; is being used for input.
JR NZ,L2174 ; forward to IN-VAR-5 if using another input
; channel.
; continue here if using the keyboard.
CALL L111D ; 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,($5C82) ; fetch line and column from ECHO_E
CALL L0DD9 ; routine CL-SET sets S-POSNL to those
; values.
; if using another input channel rejoin here.
;; IN-VAR-5
L2174: LD HL,$5C71 ; 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,L219B ; forward to IN-VAR-6 if INPUT LINE.
POP HL ; drop the looping address
POP HL ; drop the address of previous
; error handler.
LD ($5C3D),HL ; set ERR_SP to point to it.
POP HL ; drop original CH_ADD which points to
; INPUT command in BASIC line.
LD ($5C5F),HL ; save in X_PTR while input is assigned.
SET 7,(IY+$01) ; update FLAGS - Signal running program
CALL L21B9 ; 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,($5C5F) ; fetch stored CH_ADD value from X_PTR.
LD (IY+$26),$00 ; set X_PTR_hi so that iy is no longer relevant.
LD ($5C5D),HL ; put restored value back in CH_ADD
JR L21B2 ; 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
L219B: LD HL,($5C63) ; STKBOT points to the end of the input.
LD DE,($5C61) ; WORKSP points to the beginning.
SCF ; prepare for true subtraction.
SBC HL,DE ; subtract to get length
LD B,H ; transfer it to
LD C,L ; the BC register pair.
CALL L2AB2 ; routine STK-STO-$ stores parameters on
; the calculator stack.
CALL L2AFF ; routine LET assigns it to destination.
JR L21B2 ; 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"'.
; ---
; the jump was to here when ALPHA found more items while looking for
; a variable name.
( run in 0.791 second using v1.01-cache-2.11-cpan-39bf76dae61 )