mirror of
https://github.com/erkyrath/infocom-zcode-terps.git
synced 2026-01-27 12:22:34 +00:00
Initial commit.
This commit is contained in:
308
atari/read.src
Normal file
308
atari/read.src
Normal file
@@ -0,0 +1,308 @@
|
||||
PAGE
|
||||
SBTTL "--- READ HANDLER ---"
|
||||
|
||||
; ----
|
||||
; READ
|
||||
; ----
|
||||
|
||||
; READ LINE INTO TABLE [ARG1]; PARSE INTO TABLE [ARG2]
|
||||
|
||||
ZREAD: JSR ZUSL ; UPDATE THE STATUS LINE
|
||||
|
||||
LDA ARG1+HI ; MAKE THE TABLE ADDRESSES
|
||||
CLC ; ABSOLUTE
|
||||
ADC ZCODE ; LSBS NEED NOT CHANGE
|
||||
STA ARG1+HI
|
||||
|
||||
LDA ARG2+HI
|
||||
CLC
|
||||
ADC ZCODE
|
||||
STA ARG2+HI
|
||||
|
||||
JSR INPUT ; READ LINE; RETURN LENGTH IN [A]
|
||||
STA LINLEN ; SAVE # CHARS IN LINE
|
||||
|
||||
LDA #0
|
||||
STA WRDLEN ; INIT # CHARS IN WORD COUNTER
|
||||
|
||||
LDY #1 ; POINT TO "# WORDS READ" SLOT
|
||||
STA (ARG2),Y ; AND CLEAR IT ([A] = 0)
|
||||
|
||||
STY SOURCE ; INIT SOURCE TABLE PNTR ([Y] = 1)
|
||||
INY ; = 2
|
||||
STY RESULT ; AND RESULT TABLE POINTER
|
||||
|
||||
; MAIN LOOP STARTS HERE
|
||||
|
||||
READL: LDY #0 ; POINT TO "MAX # WORDS" SLOT
|
||||
LDA (ARG2),Y ; AND READ IT
|
||||
|
||||
BEQ RLERR ; IF ENTRY IS ZERO, PATCH IT (BM 5/14/85)
|
||||
CMP #60 ; IF ENTRY <= 59,
|
||||
BCC RL0 ; CONTINUE
|
||||
|
||||
RLERR: LDA #59 ; FORCE # TOKENS
|
||||
STA (ARG2),Y ; TO BE 59
|
||||
|
||||
RL0: INY ; (Y = 1) POINT TO "# WORDS READ" SLOT
|
||||
CMP (ARG2),Y ; TOO MANY WORDS?
|
||||
BCC RLEX ; EXIT IF SO (BM 5/1/85)
|
||||
|
||||
RL1: LDA LINLEN
|
||||
ORA WRDLEN ; OUT OF CHARS AND WORDS?
|
||||
BNE RL2 ; NOT YET
|
||||
|
||||
RLEX: RTS ; ELSE EXIT
|
||||
|
||||
RL2: LDA WRDLEN ; GET WORD LENGTH
|
||||
CMP #6 ; 6 CHARS DONE?
|
||||
BCC RL3 ; NO, KEEP GOING
|
||||
JSR FLUSHW ; ELSE FLUSH REMAINDER OF WORD
|
||||
|
||||
RL3: LDA WRDLEN ; GET WORD LENGTH AGAIN
|
||||
BNE READL2 ; CONTINUE IF NOT FIRST CHAR
|
||||
|
||||
; START A NEW WORD
|
||||
|
||||
LDX #5 ; CLEAR Z-WORD INPUT BUFFER
|
||||
RLL: STA IN,X ; [A] = 0
|
||||
DEX
|
||||
BPL RLL
|
||||
|
||||
JSR EFIND ; GET BASE ADDRESS INTO [ENTRY]
|
||||
LDA SOURCE ; STORE THE START POS OF THE WORD
|
||||
LDY #3 ; INTO THE "WORD START" SLOT
|
||||
STA (ENTRY),Y ; OF THE RESULT TABLE
|
||||
|
||||
TAY
|
||||
LDA (ARG1),Y ; GET A CHAR FROM SOURCE BUFFER
|
||||
JSR SIB ; IS IT A SELF-INSERTING BREAK?
|
||||
BCS DOSIB ; YES IF CARRY WAS SET
|
||||
|
||||
JSR NORM ; IS IT A "NORMAL" BREAK?
|
||||
BCC READL2 ; NO, CONTINUE
|
||||
|
||||
INC SOURCE ; ELSE FLUSH THE STRANDED BREAK
|
||||
DEC LINLEN ; UPDATE # CHARS LEFT IN LINE
|
||||
JMP READL ; AND LOOP
|
||||
|
||||
READL2: LDA LINLEN ; OUT OF CHARS YET?
|
||||
BEQ READL3 ; LOOKS THAT WAY
|
||||
|
||||
LDY SOURCE
|
||||
LDA (ARG1),Y ; ELSE GRAB NEXT CHAR
|
||||
JSR BREAK ; IS IT A BREAK?
|
||||
BCS READL3 ; YES IF CARRY WAS SET
|
||||
|
||||
LDX WRDLEN ; ELSE STORE THE CHAR
|
||||
STA IN,X ; INTO THE INPUT BUFFER
|
||||
|
||||
DEC LINLEN ; ONE LESS CHAR IN LINE
|
||||
INC WRDLEN ; ONE MORE IN WORD
|
||||
INC SOURCE ; POINT TO NEXT CHAR IN SOURCE
|
||||
JMP READL ; AND LOOP BACK
|
||||
|
||||
DOSIB: STA IN ; PUT THE BREAK INTO 1ST WORD SLOT
|
||||
DEC LINLEN ; ONE LESS CHAR IN LINE
|
||||
INC WRDLEN ; ONE MORE IN WORD BUFFER
|
||||
INC SOURCE ; POINT TO NEXT SOURCE CHAR
|
||||
|
||||
READL3: LDA WRDLEN ; ANY CHARS IN WORD YET?
|
||||
BEQ READL ; APPARENTLY NOT, SO LOOP BACK
|
||||
|
||||
JSR EFIND ; GET ENTRY ADDR INTO [ENTRY]
|
||||
LDA WRDLEN ; GET ACTUAL LNGTH OF WORD
|
||||
LDY #2 ; STORE IT IN "WORD LENGTH" SLOT
|
||||
STA (ENTRY),Y ; OF THE CURRENT ENTRY
|
||||
|
||||
JSR CONZST ; CONVERT ASCII IN [IN] TO Z-STRING
|
||||
JSR FINDW ; AND LOOK IT UP IN VOCABULARY
|
||||
|
||||
LDY #1
|
||||
LDA (ARG2),Y ; FETCH THE # WORDS READ
|
||||
CLC
|
||||
ADC #1 ; INCREMENT IT
|
||||
STA (ARG2),Y ; AND UPDATE
|
||||
|
||||
JSR EFIND ; MAKE [ENTRY] POINT TO ENTRY
|
||||
|
||||
LDY #0
|
||||
STY WRDLEN ; CLEAR # CHARS IN WORD
|
||||
LDA VALUE+HI ; GET MSB OF VOCAB ENTRY ADDRESS
|
||||
STA (ENTRY),Y ; AND STORE IN 1ST SLOT OF ENTRY
|
||||
INY
|
||||
LDA VALUE+LO ; ALSO STORE LSB IN 2ND SLOT
|
||||
STA (ENTRY),Y
|
||||
|
||||
LDA RESULT ; UPDATE THE
|
||||
CLC ; RESULT TABLE POINTER
|
||||
ADC #4 ; SO IT POINTS TO THE
|
||||
STA RESULT ; NEXT ENTRY
|
||||
|
||||
JMP READL ; AND LOOP BACK
|
||||
|
||||
; -----------------------------------
|
||||
; FIND BASE ADDR OF RESULT ENTRY SLOT
|
||||
; -----------------------------------
|
||||
|
||||
EFIND: LDA ARG2+LO ; LSB OF RESULT TABLE BASE
|
||||
CLC
|
||||
ADC RESULT ; AND CURRENT POINTER
|
||||
STA ENTRY+LO ; SAVE IN [ENTRY]
|
||||
LDA ARG2+HI ; ALSO ADD MSB
|
||||
ADC #0
|
||||
STA ENTRY+HI
|
||||
RTS
|
||||
|
||||
; ----------
|
||||
; FLUSH WORD
|
||||
; ----------
|
||||
|
||||
FLUSHW: LDA LINLEN ; ANY CHARS LEFT IN LINE?
|
||||
BEQ FLEX ; NO, SCRAM
|
||||
|
||||
LDY SOURCE ; GET CURRENT CHAR POINTER
|
||||
LDA (ARG1),Y ; AND GRAB A CHAR
|
||||
JSR BREAK ; IS IT A BREAK?
|
||||
BCS FLEX ; EXIT IF SO
|
||||
DEC LINLEN ; ELSE UPDATE CHAR COUNT
|
||||
INC WRDLEN ; AND WORD-CHAR COUNT
|
||||
INC SOURCE ; AND CHAR POINTER
|
||||
BNE FLUSHW ; AND LOOP BACK (ALWAYS)
|
||||
|
||||
FLEX: RTS
|
||||
|
||||
; ---------------------------------
|
||||
; IS CHAR IN [A] ANY TYPE OF BREAK?
|
||||
; ---------------------------------
|
||||
|
||||
BREAK: JSR SIB ; CHECK FOR A SIB FIRST
|
||||
BCS FBRK ; EXIT NOW IF MATCHED
|
||||
|
||||
; ELSE FALL THROUGH ...
|
||||
|
||||
; --------------------------------
|
||||
; IS CHAR IN [A] A "NORMAL" BREAK?
|
||||
; --------------------------------
|
||||
|
||||
NORM: LDX #NBRKS-1 ; NUMBER OF "NORMAL" BREAKS
|
||||
NBL: CMP BRKTBL,X ; MATCHED?
|
||||
BEQ FBRK ; YES, EXIT
|
||||
DEX
|
||||
BPL NBL ; NO, KEEP LOOKING
|
||||
CLC ; NO MATCH, CLEAR CARRY
|
||||
RTS ; AND RETURN
|
||||
|
||||
; ------------------
|
||||
; NORMAL BREAK CHARS
|
||||
; ------------------
|
||||
|
||||
BRKTBL: DB "!?,." ; IN ORDER OF
|
||||
DB $0D ; ASCENDING FREQUENCY
|
||||
DB SPACE ; SPACE CHAR IS TESTED FIRST FOR SPEED
|
||||
|
||||
NBRKS EQU $-BRKTBL ; # NORMAL BREAKS
|
||||
|
||||
; ---------------------
|
||||
; IS CHAR IN [A] A SIB?
|
||||
; ---------------------
|
||||
|
||||
SIB: TAX ; SAVE TEST CHAR
|
||||
LDY #0 ; 1ST BYTE IN VOCAB TABLE
|
||||
LDA (VOCAB),Y ; HAS # SIBS
|
||||
TAY ; USE AS AN INDEX
|
||||
TXA ; RESTORE TEST CHAR
|
||||
SBL: CMP (VOCAB),Y ; MATCHED?
|
||||
BEQ FBRK ; YES, REPORT IT
|
||||
DEY
|
||||
BNE SBL ; ELSE KEEP LOOPING
|
||||
CLC ; NO MATCH, SO
|
||||
RTS ; EXIT WITH CARRY CLEAR
|
||||
|
||||
FBRK: SEC ; EXIT WITH CARRY SET
|
||||
RTS ; IF MATCHED WITH A BREAK CHAR
|
||||
|
||||
; -----------------
|
||||
; VOCABULARY SEARCH
|
||||
; -----------------
|
||||
|
||||
; ENTRY: 4-BYTE TARGET Z-WORD IN [OUT]
|
||||
; EXIT: ABS ENTRY ADDRESS IN [VALUE] IF FOUND;
|
||||
; OTHERWISE [VALUE] = 0
|
||||
|
||||
FINDW: LDY #0 ; GET # SIBS
|
||||
LDA (VOCAB),Y ; IN VOCAB TABLE
|
||||
CLC ; INCREMENT IT
|
||||
ADC #1 ; FOR PROPER ALIGNMENT
|
||||
ADC VOCAB+LO ; NOW ADD THE BASE ADDR OF THE TABLE
|
||||
STA VALUE+LO ; TO GET THE ACTUAL BASE ADDR
|
||||
LDA VOCAB+HI ; OF THE VOCAB ENTRIES
|
||||
ADC #0 ; WHICH IS SAVED
|
||||
STA VALUE+HI ; IN [VALUE]
|
||||
|
||||
LDA (VALUE),Y ; GET # BYTES PER ENTRY ([Y] = 0)
|
||||
STA ESIZE ; SAVE IT HERE
|
||||
|
||||
JSR INCVAL ; POINT TO NEXT BYTE
|
||||
LDA (VALUE),Y ; GET # ENTRIES IN TABLE (MSB)
|
||||
STA NENTS+HI ; AND STUFF IT IN [NENTS]
|
||||
|
||||
JSR INCVAL ; NEXT BYTE
|
||||
LDA (VALUE),Y ; DON'T FORGET THE LSB!
|
||||
STA NENTS+LO
|
||||
|
||||
JSR INCVAL ; [VALUE] NOW POINTS TO 1ST ENTRY
|
||||
|
||||
; BEGIN THE SEARCH!
|
||||
|
||||
FWL1: LDY #0
|
||||
LDA (VALUE),Y ; GET 1ST BYTE OF ENTRY
|
||||
CMP OUT ; MATCHED 1ST BYTE OF TARGET?
|
||||
BNE WNEXT ; NO, SKIP TO NEXT WORD
|
||||
|
||||
INY
|
||||
LDA (VALUE),Y
|
||||
CMP OUT+1 ; 2ND BYTE MATCHED?
|
||||
BNE WNEXT ; NOPE
|
||||
|
||||
INY
|
||||
LDA (VALUE),Y
|
||||
CMP OUT+2 ; 3RD BYTE?
|
||||
BNE WNEXT ; SORRY ...
|
||||
|
||||
INY
|
||||
LDA (VALUE),Y
|
||||
CMP OUT+3 ; LAST BYTE
|
||||
BEQ FWSUCC ; FOUND IT!
|
||||
|
||||
WNEXT: LDA ESIZE ; GET ENTRY SIZE
|
||||
CLC ; AND ADD IT TO ENTRY ADDRESS
|
||||
ADC VALUE+LO ; TO MAKE [VALUE]
|
||||
STA VALUE+LO ; POINT TO THE NEXT ENTRY
|
||||
BCC WNX
|
||||
INC VALUE+HI
|
||||
|
||||
WNX: LDA NENTS+LO ; DECREMENT THE
|
||||
SEC ; ENTRY COUNTER
|
||||
SBC #1
|
||||
STA NENTS+LO
|
||||
BCS WNX1
|
||||
DEC NENTS+HI
|
||||
|
||||
WNX1: ORA NENTS+HI ; KEEP SEARCHING
|
||||
BNE FWL1 ; UNTIL COUNT IS ZERO
|
||||
|
||||
STA VALUE+LO
|
||||
STA VALUE+HI
|
||||
RTS ; THEN RETURN WITH [VALUE] = 0
|
||||
|
||||
; ENTRY MATCHED!
|
||||
|
||||
FWSUCC: LDA VALUE+HI ; CONVERT ABSOLUTE ENTRY ADDRESS
|
||||
SEC ; IN [VALUE]
|
||||
SBC ZCODE ; TO RELATIVE Z-ADDRESS
|
||||
STA VALUE+HI ; LSB NEEDN'T CHANGE
|
||||
RTS
|
||||
|
||||
END
|
||||
|
||||
Reference in New Issue
Block a user