mirror of
https://github.com/erkyrath/infocom-zcode-terps.git
synced 2026-02-08 01:01:24 +00:00
445 lines
7.5 KiB
NASM
445 lines
7.5 KiB
NASM
PAGE
|
|
SBTTL 'GAME I/O'
|
|
|
|
|
|
;INTERNAL ERROR
|
|
|
|
;ENTRY: ERROR CODE IN A
|
|
|
|
ERRM: DB "INTERNAL ERROR "
|
|
ENUMB: DB "00."
|
|
ERRML EQU $-ERRM
|
|
|
|
ZERROR: LDY #1 ;CONVERT ERROR BYTE IN A
|
|
ECON: JSR DIV10 ;TO ASCII DECIMAL IN ENUMB
|
|
ORA #'0' ;DIV10 RETS REMAINDER IN A (LSD)
|
|
STA ENUMB,Y
|
|
TXA ;AND QUOTIENT IN X (WILL BE MSD)
|
|
DEY
|
|
BPL ECON ;DO BOTH DIGITS
|
|
|
|
JSR ZCRLF ;CLEAR BUFFER
|
|
LDA #0
|
|
STA SCRIPT ;DISABLE SCRIPTING
|
|
|
|
LDX #LOW ERRM ;PRINT MSG
|
|
LDA #HIGH ERRM
|
|
LDY #ERRML
|
|
JSR DLINE
|
|
|
|
;FALL THROUGH ...
|
|
|
|
;QUIT/RESTART
|
|
|
|
ZSTART: ;FLUSH BUFFER, DEMAND <RET> TO RESTART, GO TO WARM START
|
|
|
|
JSR ZCRLF ;FLUSH BUFFER
|
|
LDX #LOW TORES
|
|
LDA #HIGH TORES
|
|
LDY #TORESL
|
|
JSR DLINE ;"PRESS <RET> TO RESTART"
|
|
|
|
JSR GETRET ;WAIT FOR <RET>
|
|
JMP WARM1 ;AND DO WARMSTART
|
|
|
|
|
|
TORES: DB "End of story."
|
|
DB EOL
|
|
DB "Press <RETURN> to restart."
|
|
DB EOL
|
|
TORESL EQU $-TORES
|
|
|
|
ZQUIT EQU ZSTART ;0-OP
|
|
|
|
|
|
|
|
;PRINT VERSION #
|
|
|
|
VERS: DB "ACORN Version A"
|
|
DB EOL
|
|
VERSL EQU $-VERS
|
|
|
|
VERNUM: JSR ZCRLF ;CLEAR BUFFER
|
|
LDX #LOW VERS
|
|
LDA #HIGH VERS
|
|
LDY #VERSL
|
|
JMP DLINE ;DISPL VERSION # (RET TO CALLING FROM DLINE)
|
|
|
|
|
|
;************************
|
|
;RETURN TOP RAM PAGE IN A
|
|
;************************
|
|
|
|
MEMTOP: LDA #$7B ;IT'S A GIVEN
|
|
RTS
|
|
|
|
|
|
;****************************
|
|
;RETURN RANDOM BYTES IN A & X
|
|
;****************************
|
|
|
|
RANDOM: LDA #3 ; READ INTERVAL TIMER
|
|
LDX #LOW CLOCK
|
|
LDY #HIGH CLOCK
|
|
JSR OSWORD
|
|
LDA CLOCK
|
|
ADC RAND1
|
|
TAX
|
|
LDA CLOCK+1
|
|
SBC RAND2
|
|
STA RAND1
|
|
STX RAND2
|
|
CLC
|
|
RTS
|
|
|
|
; CLOCK = LSB, CLOCK+4 = MSB
|
|
|
|
CLOCK: DB 0,0,0,0,0
|
|
|
|
;*******************
|
|
;Z-PRINT A CHARACTER MOVE A (1) CHAR TO LBUFF, IF EOL REACHED
|
|
;******************* (CHAR OR ACTUAL), DISPLAY/PRINT LINE
|
|
|
|
;ENTRY: ASCII CHAR IN A
|
|
|
|
COUT: CMP #EOL ;IF EOL
|
|
BNE COUT1
|
|
JMP ZCRLF
|
|
COUT1: CMP #SPACE ;IGNORE ALL OTHER CONTROLS
|
|
BCC CEX ;(OUT)
|
|
|
|
COUT2: LDX LENGTH ;ELSE GET LINE POINTER
|
|
STA LBUFF,X ;ADD CHAR TO BUFFER
|
|
CPX #XSIZE ;END OF LINE?
|
|
BCC COUT3
|
|
JMP FLUSH
|
|
COUT3: INC LENGTH ;ELSE UPDATE POINTER
|
|
CEX: RTS
|
|
|
|
;*******************
|
|
;FLUSH OUTPUT BUFFER - PRINT UP THRU LAST FULL WORD (MARKED BY BLANK)
|
|
;******************* IF NO BLANK PRINT ENTIRE BUFFR
|
|
; MOVE ANY REMAINING CHARS TO TOP OF BUFFER FOR
|
|
; NEXT LINE
|
|
|
|
;ENTRY: LENGTH OF BUFFER IN X
|
|
|
|
FLUSH: LDA #SPACE
|
|
|
|
FL0: CMP LBUFF,X ;FIND LAST SPACE CHAR
|
|
BEQ FL1 ;IN THE LINE
|
|
DEX
|
|
BNE FL0
|
|
LDX #XSIZE ;IF NONE FOUND, FLUSH ENTIRE LINE
|
|
|
|
FL1: STX OLDLEN ;SAVE OLD LINE END POS HERE
|
|
STX LENGTH ;MAKE IT NEW LINE LENGTH
|
|
JSR ZCRLF ;PRINT LINE UP TO LAST SPACE
|
|
|
|
;START NEW LINE WITH REMAINDER OF OLD
|
|
|
|
LDX OLDLEN ;GET OLD LINE POS
|
|
LDY #0 ;START NEW LINE AT BEGINNING
|
|
FL2: INX
|
|
CPX #XSIZE ;CONTINUE IF
|
|
BCC FL3 ;INSIDE OR
|
|
BEQ FL3 ;AT END OF LINE (ie NOT ENTIRE LINE)
|
|
STY LENGTH ;ELSE SET NEW LINE LENGTH TO 0
|
|
RTS
|
|
|
|
FL3: LDA LBUFF,X ;GET CHAR FROM OLD LINE
|
|
STA LBUFF,Y ;MOVE TO START OF NEW LINE
|
|
INY ;UPDATE LENGTH OF NEW LINE
|
|
BNE FL2 ;MOVE ALL CHARS
|
|
|
|
|
|
;**************
|
|
;CARRIAGE RETURN
|
|
;**************
|
|
|
|
ZCRLF: INC LINCNT ;NEW LINE GOING OUT
|
|
LDA LINCNT ;IS IT TIME TO
|
|
CMP #LMAX ;PRINT "MORE" YET?
|
|
BCC CR1 ;NO, CONTINUE
|
|
|
|
;SCREEN FULL; PRINT "MORE"
|
|
|
|
JSR ZUSL ;UPDATE STATUS LINE
|
|
LDX #LOW MORE
|
|
LDA #HIGH MORE
|
|
LDY #MOREL
|
|
JSR DLINE ;DISPLAY "MORE"
|
|
|
|
JSR OSRDCH ;WAIT FOR ANY CHAR
|
|
|
|
;ERASE "MORE"
|
|
|
|
LDY #MOREL ;GET # CHARS DISPLAYED
|
|
ZCR0: LDA #BACKSP
|
|
JSR OSWRCH ;BACK UP ERASING AS GO
|
|
DEY
|
|
BNE ZCR0 ;COVER ALL LETTERS
|
|
|
|
LDA #1
|
|
STA LINCNT ;RESET FOR NEW SCREEN FULL
|
|
|
|
;AND GO DO MORE
|
|
|
|
CR1: LDX LENGTH
|
|
LDA #EOL ;INSTALL EOL AT
|
|
STA LBUFF,X ;END OF CURRENT LINE
|
|
INC LENGTH ;UPDATE LINE LENGTH
|
|
|
|
LINOUT: LDY LENGTH ;IF BUFFER EMPTY
|
|
BEQ LINEX ;DON'T PRINT ANYTHING
|
|
|
|
STY PRLEN ;SAVE LENGTH FOR "PPRINT"
|
|
LDX #0 ;SEND CONTENTS OF LBUFF TO SCREEN
|
|
LOUT: LDA LBUFF,X
|
|
JSR CHAR
|
|
INX
|
|
DEY
|
|
BNE LOUT ;DO ALL CHARS
|
|
|
|
JSR PPRINT ;PRINT LBUFF IF ENABLED
|
|
|
|
LINEX: LDA #0 ;RESET LINE LENGTH TO TOP
|
|
STA LENGTH
|
|
RTS ;AND RETURN
|
|
|
|
MORE: DB "-MORE-"
|
|
MOREL EQU $-MORE
|
|
|
|
|
|
;**********************
|
|
;UPDATE THE STATUS LINE
|
|
;**********************
|
|
|
|
ZUSL: LDA LENGTH ;SAVE ALL STRING-PRINTING VARIABLES
|
|
PHA
|
|
LDA MPCH
|
|
PHA
|
|
LDA MPCM
|
|
PHA
|
|
LDA MPCL
|
|
PHA
|
|
LDA TSET
|
|
PHA
|
|
LDA PSET
|
|
PHA
|
|
LDA ZWORD+HI
|
|
PHA
|
|
LDA ZWORD+LO
|
|
PHA
|
|
LDA ZFLAG
|
|
PHA
|
|
LDA DIGITS
|
|
PHA
|
|
|
|
LDX #XSIZE
|
|
USL0: LDA LBUFF,X ;MOVE CONTENTS OF LBUFF
|
|
STA BUFSAV,X ;TO BUFSAV
|
|
LDA #SPACE ;CLEAR LBUFF WITH SPACES
|
|
STA LBUFF,X
|
|
DEX
|
|
BPL USL0
|
|
|
|
LDA #0
|
|
STA LENGTH ;RESET LINE LENGTH
|
|
STA SCRIPT ;DISABLE SCRIPTING
|
|
|
|
LDA #RDCPOS ;GET CURSOR POSITION
|
|
JSR OSBYTE
|
|
STX OLDX ;SAVE REGULAR POSITION OF CURSOR
|
|
STY OLDY
|
|
|
|
LDA #HOME ;HOME CURSOR
|
|
JSR VDU
|
|
LDA #BLUE ;SET STATUS LINE TO BLUE SO STANDS OUT
|
|
JSR COUT ;PLACE COLOR CONTROL IN LBUFF SO WHEN PRINTS
|
|
;WILL BE INCLUDED IN LINE COUNT
|
|
;(NO NEED TO RESET, COMMAND AFFECTS 1 LINE ONLY)
|
|
;MOVE ROOM DESCRIPTION TO LBUFF
|
|
|
|
LDA #16 ;GLOBAL VAR #16 9ROOM ID)
|
|
JSR GETVRG ;GET IT INTO VALUE
|
|
LDA VALUE+LO
|
|
JSR PRNTDC ;PRINT SHORT ROOM DESC.
|
|
|
|
LDA #23 ;MOVE LINE INDEX UP
|
|
STA LENGTH ;TO TIME/SCORE POSITION
|
|
LDA #SPACE
|
|
JSR COUT ; OUTPUT A SPACE FOR SAFETY
|
|
|
|
LDA #17 ;GLOBAL VAR #17 (SCORE/HOURS)
|
|
JSR GETVRG ;GET IT INTO VALUE
|
|
|
|
LDA TIMEFL ;GET MODE FLAG
|
|
BNE DOTIME ;USE TIME MODE IF NON-ZERO
|
|
|
|
;PRINT 'SCORE' (DO BY HAND NO REGISTERS PRESERVED THRU COUT)
|
|
|
|
LDA #'S'
|
|
JSR COUT
|
|
LDA #'c'
|
|
JSR COUT
|
|
LDA #'o'
|
|
JSR COUT
|
|
LDA #'r'
|
|
JSR COUT
|
|
LDA #'e'
|
|
JSR COUT
|
|
LDA #':'
|
|
JSR COUT
|
|
LDA #SPACE
|
|
JSR COUT
|
|
|
|
LDA VALUE+LO ;MOVE SCORE VALUE
|
|
STA QUOT+LO ;INTO QUOT
|
|
LDA VALUE+HI ;FOR PRINTING
|
|
STA QUOT+HI
|
|
JSR NUMBER ;CONVERT TO DECIMAL, MOVE TO LBUFF ("PRINT")
|
|
|
|
LDA #'/' ;PRINT A SLASH
|
|
BNE MOVMIN ;BRANCH ALWAYS
|
|
|
|
|
|
;PRINT 'TIME'
|
|
|
|
DOTIME: LDA #'T'
|
|
JSR COUT
|
|
LDA #'i'
|
|
JSR COUT
|
|
LDA #'m'
|
|
JSR COUT
|
|
LDA #'e'
|
|
JSR COUT
|
|
LDA #':'
|
|
JSR COUT
|
|
LDA #SPACE
|
|
JSR COUT
|
|
|
|
LDA VALUE+LO ;00 IS REALLY 24
|
|
BNE DTO
|
|
LDA #24
|
|
DTO: CMP #13 ;HOURS > 12?
|
|
BCC DT1 ;NO, SKIP THIS
|
|
SBC #12 ;CONVERT TO 1-12
|
|
DT1: STA QUOT+LO ;MOVE FOR PRINTING
|
|
LDA #0
|
|
STA QUOT+HI ;CLEAR MSB
|
|
JSR NUMBER
|
|
|
|
LDA #':' ;COLON
|
|
|
|
MOVMIN: JSR COUT ;PRINT SLASH OR COLON
|
|
|
|
LDA #18 ;GLOBAL VAR #18 (MOVES/MINUTES)
|
|
JSR GETVRG ;MOVE TO VALUE
|
|
LDA VALUE+LO ;MOVE TO QUOT
|
|
STA QUOT+LO
|
|
LDA VALUE+HI
|
|
STA QUOT+HI
|
|
|
|
LDA TIMEFL ;WHICH MODE?
|
|
BNE DOMINS ;TIME IF NZ
|
|
|
|
;PRINT # OF MOVES
|
|
|
|
JSR NUMBER ;CONVERT & MOVE TO LBUFF
|
|
JMP STATEX ;ALL DONE
|
|
|
|
;PRINT MINUTES
|
|
|
|
DOMINS: LDA VALUE+LO ;CHECK MINUTES
|
|
CMP #10 ;IF OVER 10
|
|
BCS DOMO ;CONTINUE
|
|
LDA #'0' ;ELSE PRINT A
|
|
JSR COUT ;PADDING "0" FIRST
|
|
|
|
DOMO: JSR NUMBER ;CONVERT, MOVE TO PRINT
|
|
LDA #SPACE
|
|
JSR COUT ;SEPARATE THINGS
|
|
|
|
LDA #17 ;CHECK 'HOURS' AGAIN
|
|
JSR GETVRG
|
|
LDA VALUE+LO
|
|
CMP #12 ;PAST NOON
|
|
BCS DOPM ;YES, "PM"
|
|
|
|
LDA #'a' ;ELSE "AM"
|
|
BNE DOXM ;BRANCH ALWAYS
|
|
|
|
DOPM: LDA #'p'
|
|
|
|
DOXM: JSR COUT
|
|
LDA #'m'
|
|
JSR COUT
|
|
|
|
;STATUS LINE READY
|
|
|
|
STATEX: LDA #40 ;PRINT THE ENTIRE STATUS LINE ***LINE LENGTH PROB?****
|
|
STA LENGTH
|
|
JSR CR1
|
|
|
|
LDX #XSIZE ;RESTORE OLD LBUFF
|
|
USLX: LDA BUFSAV,X
|
|
STA LBUFF,X
|
|
DEX
|
|
BPL USLX ;MOVE ALL CHARS
|
|
|
|
PLA ;RESTORE ALL SAVED VARIABLES
|
|
STA DIGITS
|
|
PLA
|
|
STA ZFLAG
|
|
PLA
|
|
STA ZWORD+LO
|
|
PLA
|
|
STA ZWORD+HI
|
|
PLA
|
|
STA PSET
|
|
PLA
|
|
STA TSET
|
|
PLA
|
|
STA MPCL
|
|
PLA
|
|
STA MPCM
|
|
PLA
|
|
STA MPCH
|
|
PLA
|
|
STA LENGTH
|
|
|
|
;RESTORE CURSOR
|
|
LDA #MVTXC ;MOVE TEXT CURSOR
|
|
JSR VDU
|
|
LDA OLDX ;TO OLD COORDINATES
|
|
JSR VDU
|
|
LDA OLDY
|
|
JSR VDU
|
|
|
|
LDX #$FF
|
|
STX SCRIPT ;RE-ENABLE SCRIPTING
|
|
INX
|
|
STX MPCFLG ;(0) INVALIDATE MPC
|
|
RTS
|
|
|
|
|
|
;****************
|
|
;DIVIDE [A] BY 10
|
|
;****************
|
|
|
|
;EXIT: QUOTIENT IN X, REMAINDER IN A
|
|
|
|
DIV10: LDX #0 ;START WITH ZERO QUOTIENT
|
|
|
|
D10L: CMP #10 ;IF DIVISOR < 10,
|
|
BCC D10EX ;WE'RE DONE
|
|
SBC #10 ;ELSE SUBTRACT ANOTHER 10
|
|
INX ;UPDATE QUOTIENT
|
|
BNE D10L ;BRANCH ALWAYS
|
|
|
|
D10EX: RTS
|
|
|
|
|
|
END
|