mirror of
https://github.com/erkyrath/infocom-zcode-terps.git
synced 2026-01-16 16:19:19 +00:00
367 lines
6.1 KiB
Plaintext
367 lines
6.1 KiB
Plaintext
PAGE
|
|
SBTTL "--- Z-STRING HANDLERS ---"
|
|
|
|
; -----------------
|
|
; POINT TO Z-STRING
|
|
; -----------------
|
|
|
|
SETSTR: CLRA
|
|
ASL TEMP+1
|
|
ROL TEMP
|
|
ROLA
|
|
STA MPCH
|
|
LDD TEMP
|
|
STD MPCM
|
|
CLR MPCFLG
|
|
ZSTEX: RTS
|
|
|
|
; --------------
|
|
; PRINT Z-STRING
|
|
; --------------
|
|
|
|
PZSTR: CLR CSPERM ; PERMANENT CHARSET
|
|
CLR STBYTF ; RESET STRING BYTE FLAG
|
|
LDA #$FF
|
|
STA CSTEMP ; NO TEMP CHARSET ACTIVE
|
|
|
|
PZSTRL: JSR GETZCH ; GET A Z-CHARACTER
|
|
BCS ZSTEX ; END OF STRING IF CARRY SET
|
|
STA MASK ; SAVE CHAR HERE
|
|
BEQ PZSTRS ; O = SPACE CHAR
|
|
CMPA #4 ; IS THIS AN F-WORD?
|
|
BLO PZSTRF ; APPARENTLY SO
|
|
CMPA #6 ; SHIFT CHAR?
|
|
BLO PZSTRT ; YES, CHANGE CHARSET
|
|
|
|
JSR GETMOD
|
|
TSTA ; IS THIS CHARSET 0?
|
|
BNE PZSTR1 ; NOPE
|
|
|
|
; PRINT LOWER-CASE CHAR (CHARSET 0)
|
|
|
|
LDA #$61-6 ; ASCII "a" MINUS Z-OFFSET
|
|
PZSTP0: ADDA MASK ; ADD CHARACTER
|
|
PZSTP1: JSR COUT ; PRINT RESULT
|
|
BRA PZSTRL ; AND FETCH ANOTHER Z-CHAR
|
|
|
|
; CHARSET 1 OR 2?
|
|
|
|
PZSTR1: CMPA #1 ; SET 1?
|
|
BNE PZSTR2 ; NOPE, IT'S SET 2
|
|
|
|
; PRINT UPPER-CASE CHAR (CHARSET 1)
|
|
|
|
LDA #$41-6 ; ASCII "A" MINUS Z-OFFSET
|
|
BRA PZSTP0 ; AND SO ON ...
|
|
|
|
; DECODE/PRINT CHARSET 2
|
|
|
|
PZSTR2: LDB MASK ; RETRIEVE Z-CHAR
|
|
SUBB #6 ; CONVERT TO ZERO-ALIGNED INDEX
|
|
BEQ PZSTRA ; IF ZERO, IT'S "DIRECT" ASCII
|
|
LDX #CHRTBL ; ELSE GET BASE OF DECODE TABLE
|
|
LDA B,X ; GET CHAR FROM TABLE
|
|
BRA PZSTP1 ; AND PRINT IT!
|
|
|
|
; DECODE/PRINT A "DIRECT" ASCII CHAR
|
|
|
|
PZSTRA: JSR GETZCH ; GET NEXT Z-BYTE
|
|
ASLA ; SHIFT INTO POSITION
|
|
ASLA
|
|
ASLA
|
|
ASLA
|
|
ASLA
|
|
STA MASK ; SAVE MSB
|
|
JSR GETZCH ; FETCH LSB
|
|
STA MASK+1 ; SAVE THAT, TOO
|
|
LDA MASK ; GET MSB
|
|
ORA MASK+1 ; SUPERIMPOSE LSB
|
|
BRA PZSTP1 ; AND PRINT RESULT
|
|
|
|
; PRINT A SPACE
|
|
|
|
PZSTRS: LDA #$20
|
|
BRA PZSTP1
|
|
|
|
; CHANGE CHARACTER SETS
|
|
|
|
PZSTRT: SUBA #3 ; CONVERT TO 1 OR 2
|
|
TFR A,B
|
|
BSR GETMOD
|
|
BNE PZSTRP ; NO, DO PERMANENT SHIFT
|
|
STB CSTEMP ; JUST A TEMP-SHIFT
|
|
BRA PZSTRL
|
|
|
|
PZSTRP: STB CSPERM ; PERMANENT SHIFT
|
|
CMPA CSPERM ; NEW SET SAME AS OLD?
|
|
BEQ PZSTRL ; YES, EXIT
|
|
CLR CSPERM ; ELSE BACK TO SET 0
|
|
BRA PZSTRL ; BEFORE FINISHING
|
|
|
|
; HANDLE AN F-WORD
|
|
|
|
PZSTRF: DECA ; CONVERT TO 0-2
|
|
LDB #64 ; TIMES 64
|
|
MUL
|
|
STB PZSTFO ; SAVE FOR LATER
|
|
JSR GETZCH ; GET F-WORD INDEX
|
|
TFR A,B ; MOVE IT
|
|
ASLB ; FORM WORD-ALIGNED INDEX
|
|
ADDB PZSTFO ; ADD OFFSET
|
|
LDX FWORDS ; GET BASE ADDR OF FWORDS TABLE
|
|
ABX ; ADD THE OFFSET
|
|
LDD ,X ; GET THE FWORD POINTER
|
|
STD TEMP ; AND SAVE IT
|
|
|
|
; SAVE THE STATE OF CURRENT Z-PRINT
|
|
|
|
LDA MPCH
|
|
PSHS A
|
|
LDA CSPERM
|
|
LDB STBYTF
|
|
LDX MPCM
|
|
LDY ZSTWRD
|
|
PSHS Y,X,B,A
|
|
|
|
JSR SETSTR ; PRINT THE F-WORD
|
|
JSR PZSTR ; POINTED TO BY [TEMP]
|
|
|
|
; RESTORE THE OLD Z-STRING
|
|
|
|
PULS Y,X,B,A
|
|
STY ZSTWRD
|
|
STX MPCM
|
|
STB STBYTF
|
|
STA CSPERM
|
|
PULS A
|
|
STA MPCH
|
|
|
|
LDA #$FF
|
|
STA CSTEMP ; DISABLE TEMP CHARSET
|
|
CLR MPCFLG ; MPC HAS CHANGED!
|
|
JMP PZSTRL ; CONTINUE INNOCENTLY
|
|
|
|
; ----------------------
|
|
; RETURN CURRENT CHARSET
|
|
; ----------------------
|
|
|
|
GETMOD: LDA CSTEMP
|
|
BPL GM
|
|
LDA CSPERM
|
|
RTS
|
|
|
|
GM: LDB #$FF
|
|
STB CSTEMP
|
|
RTS
|
|
|
|
; ---------------
|
|
; GET NEXT Z-CHAR
|
|
; ---------------
|
|
|
|
GETZCH: LDA STBYTF ; WHICH BYTE?
|
|
BPL GTZ0
|
|
COMB ; SET CARRY
|
|
RTS ; TO INDICATE "NO MORE CHARS"
|
|
|
|
GTZ0: BNE GETZH1 ; NOT FIRST CHAR
|
|
INC STBYTF
|
|
JSR GETWRD
|
|
LDD TEMP
|
|
STD ZSTWRD
|
|
LSRA
|
|
LSRA
|
|
GTEXIT: ANDA #%00011111
|
|
CLRB ; CLEAR CARRY
|
|
RTS
|
|
|
|
GETZH1: DECA
|
|
BNE GETZH2 ; MUST BE LAST CHAR
|
|
LDA #2
|
|
STA STBYTF
|
|
LDD ZSTWRD
|
|
LSRA
|
|
RORB
|
|
LDA ZSTWRD
|
|
LSRA
|
|
LSRA
|
|
RORB
|
|
LSRB
|
|
LSRB
|
|
LSRB
|
|
GETZH3: TFR B,A ; EXPECTED HERE
|
|
BRA GTEXIT
|
|
|
|
GETZH2: CLR STBYTF
|
|
LDD ZSTWRD
|
|
BPL GETZH3
|
|
COM STBYTF ; INDICATE END OF STRING
|
|
BRA GETZH3
|
|
|
|
; -------------------
|
|
; CONVERT TO Z-STRING
|
|
; -------------------
|
|
|
|
CONZST: LDD #$0505 ; FILL OUTPUT BUFFER
|
|
STD ZSTBUO ; WITH PAD CHARS
|
|
STD ZSTBUO+2
|
|
STD ZSTBUO+4
|
|
|
|
INCA ; = 6
|
|
STA MASK ; INIT CHAR COUNT
|
|
|
|
CLR VAL ; RESET OUTPUT AND
|
|
CLR TEMP ; INPUT INDEXES
|
|
|
|
CNZSL1: LDB TEMP
|
|
INC TEMP
|
|
LDX #ZSTBUI ; POINT TO INPUT BUFFER
|
|
LDA B,X ; GRAB NEXT CHAR
|
|
STA MASK+1 ; SAVE IT HERE
|
|
BNE CNZSL2 ; IF CHAR WAS ZERO,
|
|
LDA #5 ; USE A Z-PAD
|
|
BRA CNZSLO
|
|
|
|
CNZSL2: LDA MASK+1
|
|
JSR ZCHRCS ; WHICH CHARSET TO USE?
|
|
TSTA
|
|
BEQ CNZSLC ; IF CHARSET 0, USE LOWER CASE
|
|
ADDA #3
|
|
LDB VAL ; OUTPUT A TEMP SHIFT
|
|
LDX #ZSTBUO
|
|
STA B,X
|
|
INC VAL
|
|
DEC MASK
|
|
LBEQ CNZSLE
|
|
|
|
CNZSLC: LDA MASK+1
|
|
JSR ZCHRCS
|
|
DECA
|
|
BPL CNZSC1 ; NOT CHARSET 0!
|
|
LDA MASK+1
|
|
SUBA #$61-6 ; ASCII "a" MINUS 6
|
|
|
|
CNZSLO: LDB VAL
|
|
LDX #ZSTBUO
|
|
STA B,X
|
|
INC VAL
|
|
DEC MASK
|
|
BEQ CNZSLE ; ALL FINISHED
|
|
BRA CNZSL1 ; ELSE LOOP BACK FOR MORE
|
|
|
|
CNZSC1: BNE CNZSC3 ; MUST BE CHARSET 3
|
|
LDA MASK+1
|
|
SUBA #$41-6 ; ASCII "A" MINUS 6
|
|
BRA CNZSLO
|
|
|
|
CNZSC3: LDA MASK+1
|
|
JSR CNZS2M ; IS IT IN TABLE?
|
|
BNE CNZSLO ; YES, OUTPUT THE CHAR
|
|
LDA #6 ; ELSE IT'S A "DIRECT" ASCII CHAR
|
|
LDB VAL
|
|
LDX #ZSTBUO
|
|
STA B,X ; SEND "DIRECT" TO OUTPUT
|
|
INC VAL
|
|
DEC MASK
|
|
BEQ CNZSLE ; NO MORE ROOM!
|
|
|
|
; CONVERT CHAR TO 2-BYTE DIRECT ASCII
|
|
|
|
LDA MASK+1
|
|
LSRA
|
|
LSRA
|
|
LSRA
|
|
LSRA
|
|
LSRA
|
|
ANDA #%00000011
|
|
LDB VAL
|
|
LDX #ZSTBUO
|
|
STA B,X
|
|
INC VAL
|
|
DEC MASK
|
|
BEQ CNZSLE ; NO MORE ROOM!
|
|
LDA MASK+1
|
|
ANDA #%00011111 ; FORM 2ND Z-BYTE
|
|
BRA CNZSLO ; AND OUTPUT IT
|
|
|
|
; ----------------------
|
|
; SEARCH CHARSET 3 TABLE
|
|
; ----------------------
|
|
|
|
CNZS2M: LDX #CHRTBL
|
|
LDB #25
|
|
CNLOOP: CMPA B,X
|
|
BEQ CNOK
|
|
DECB
|
|
BNE CNLOOP
|
|
RTS ; RETURN ZERO IN B IF NO MATCH
|
|
|
|
CNOK: TFR B,A ; EXPECTED IN [A]
|
|
ADDA #6 ; CONVERT TO Z-CHAR
|
|
RTS
|
|
|
|
; -------------------------
|
|
; DETERMINE CHARSET OF CHAR
|
|
; -------------------------
|
|
|
|
ZCHRCS: CMPA #$61 ; ASCII "a"
|
|
BLO ZCHR1
|
|
CMPA #$7B ; ASCII "z"+1
|
|
BHS ZCHR1
|
|
CLRA ; IT'S CHARSET 0
|
|
RTS
|
|
|
|
ZCHR1: CMPA #$41 ; ASCII "A"
|
|
BLO ZCHR2
|
|
CMPA #$5B ; ASCII "Z"+1
|
|
BHS ZCHR2
|
|
LDA #1 ; IT'S CHARSET 1
|
|
RTS
|
|
|
|
ZCHR2: TSTA
|
|
BEQ ZCHRX ; EXIT IF ZERO
|
|
BMI ZCHRX ; OR NEGATIVE
|
|
LDA #2 ; ELSE IT'S CHARSET 2
|
|
ZCHRX: RTS
|
|
|
|
; ---------------
|
|
; CRUSH 6 Z-CHARS
|
|
; ---------------
|
|
|
|
CNZSLE: LDD ZSTBUO ; HANDLE 1ST TRIPLET
|
|
ASLB
|
|
ASLB
|
|
ASLB
|
|
ASLB
|
|
ROLA
|
|
ASLB
|
|
ROLA
|
|
ORB ZSTBUO+2
|
|
STD ZSTBUO
|
|
|
|
LDD ZSTBUO+3 ; HANDLE 2ND TRIPLET
|
|
ASLB
|
|
ASLB
|
|
ASLB
|
|
ASLB
|
|
ROLA
|
|
ASLB
|
|
ROLA
|
|
ORB ZSTBUO+5
|
|
ORA #%10000000 ; SET SIGN BIT OF LAST Z-BYTE
|
|
STD ZSTBUO+2
|
|
RTS
|
|
|
|
; ----------------------
|
|
; CHARSET 2 DECODE TABLE
|
|
; ----------------------
|
|
|
|
CHRTBL: DB 0 ; DUMMY BYTE
|
|
DB $0D ; CARRIAGE RETURN
|
|
DB "0123456789.,!?_#"
|
|
DB $27 ; SINGLE QUOTE
|
|
DB $22 ; DOUBLE QUOTE
|
|
DB "/\-:()"
|
|
|
|
END
|
|
|