mirror of
https://github.com/erkyrath/infocom-zcode-terps.git
synced 2026-01-20 09:45:23 +00:00
577 lines
10 KiB
Plaintext
577 lines
10 KiB
Plaintext
PAGE
|
|
SBTTL "--- MACHINE-DEPENDENT ROUTINES: ATARI ---"
|
|
|
|
; ------------
|
|
; CLEAR SCREEN
|
|
; ------------
|
|
|
|
; CLEAR SCREEN TO WHITE IF [ARG1] NEGATIVE
|
|
; CLEAR SCREEN TO BLACK IF [ARG1] POSITIVE
|
|
|
|
GCLEAR: LDA #LOW SCREEN ; MAKE [I] POINT TO
|
|
STA I+LO ; THE 1ST BYTE OF
|
|
LDA #HIGH SCREEN ; SCREEN RAM
|
|
STA I+HI
|
|
|
|
LDX #30 ; # PAGES TO CLEAR
|
|
LDY #0 ; INIT LOOP INDEX
|
|
|
|
LDA ARG1+HI ; IF [ARG1]
|
|
BMI GCLSN ; NEGATIVE CLEAR TO WHITE
|
|
LDA #00
|
|
BEQ GCLS ; CLEAR SCREEN TO BLACK
|
|
GCLSN: LDA #$FF ; ELSE CLEAR TO WHITE
|
|
GCLS: STA (I),Y
|
|
INY
|
|
BNE GCLS
|
|
INC I+HI
|
|
DEX
|
|
BNE GCLS
|
|
RTS
|
|
|
|
; ------------------------
|
|
; TEXT (ATARI SCREEN CODE)
|
|
; ------------------------
|
|
|
|
ERRM: DB 41,110,116,101,114,110,97,108,0 ; INTERNAL
|
|
DB 37,114,114,111,114,0,3,0 ; ERROR #
|
|
ERRML EQU $-ERRM
|
|
|
|
ENDM: DB 37,46,36,0,47,38,0 ; END OF
|
|
DB 51,37,51,51,41,47,46 ; SESSION
|
|
ENDML EQU $-ENDM
|
|
|
|
; -----
|
|
; ERROR
|
|
; -----
|
|
|
|
; ENTRY: ERROR CODE IN [A]
|
|
|
|
GERROR: STA $00 ; SAVE ERROR CODE
|
|
JSR STATUS ; SET UP STATUS LINE
|
|
|
|
LDX #LOW ERRM ; GET LSB
|
|
LDA #HIGH ERRM ; AND MSB OF TEXT ADDRESS
|
|
LDY #ERRML ; AND ITS LENGTH
|
|
JSR PRINT ; PRINT "INTERNAL ERROR #"
|
|
|
|
LDA $00 ; RETRIEVE ERROR CODE
|
|
JSR HEX ; DISPLAY IT IN HEX
|
|
LDA #0
|
|
JSR CHAR ; PRINT A SPACE
|
|
JMP GOVER ; AND PRINT "GAME OVER"
|
|
|
|
; ----
|
|
; QUIT
|
|
; ----
|
|
|
|
GQUIT: JSR STATUS ; SET UP MESSAGE LINE
|
|
LDA #13
|
|
STA CURSOR ; CENTER TEXT
|
|
|
|
GOVER: LDX #LOW ENDM ; LSB AND
|
|
LDA #HIGH ENDM ; MSB OF TEXT ADDRESS
|
|
LDY #ENDML ; LENGTH
|
|
JSR PRINT ; PRINT "GAME OVER"
|
|
|
|
HOLD: LDA CONSOL ; WAIT FOR CONSOLE KEYPRESS
|
|
CMP #7
|
|
BEQ HOLD
|
|
LETGO: LDA CONSOL ; WAIT FOR KEY RELEASE
|
|
CMP #7
|
|
BNE LETGO
|
|
|
|
JMP COLD ; AND DO A COLDSTART
|
|
|
|
; -----------------
|
|
; CLEAR STATUS LINE
|
|
; -----------------
|
|
|
|
NEWLIN: LDX #79
|
|
LDA #0
|
|
NEWL0: STA TEXT,X
|
|
DEX
|
|
BPL NEWL0
|
|
RTS
|
|
|
|
; ------------------
|
|
; SET UP STATUS LINE
|
|
; ------------------
|
|
|
|
; FOR ERRORS & DEBUGGER
|
|
|
|
STATUS: JSR NEWLIN
|
|
|
|
LDA #0
|
|
STA CURSOR
|
|
|
|
LDX #LOW DL1 ; TELL THE D-LIST WHERE
|
|
LDA #HIGH DL1 ; TO START ITSELF
|
|
STX DLTOP+LO
|
|
STA DLTOP+HI
|
|
STX SDLSTL+LO ; ALSO TELL ANTIC
|
|
STA SDLSTL+HI ; WHERE TO FIND OUR LIST
|
|
RTS
|
|
|
|
; ----------------
|
|
; PRINT [A] IN HEX
|
|
; ----------------
|
|
|
|
; HEX CHARS IN ATARI SCREEN CODE
|
|
|
|
HCHARS: DB 16,17,18,19,20,21,22,23,24,25 ; 0-9
|
|
DB 33,34,35,36,37,38 ; A-F
|
|
|
|
HEX: PHA ; SAVE HERE
|
|
LSR A ; SHIFT TOP NIBBLE
|
|
LSR A ; INTO POSITION
|
|
LSR A
|
|
LSR A
|
|
JSR NIBBLE ; AND PRINT IT
|
|
PLA ; RETRIEVE BYTE
|
|
|
|
NIBBLE: AND #%00001111 ; ISOLATE BITS 3-0
|
|
TAX
|
|
LDA HCHARS,X
|
|
|
|
; FALL THROUGH ...
|
|
|
|
; -----------------
|
|
; PRINT CHAR IN [A]
|
|
; -----------------
|
|
|
|
CHAR: LDX CURSOR
|
|
STA TEXT,X
|
|
INC CURSOR
|
|
RTS
|
|
|
|
; ----------
|
|
; PRINT TEXT
|
|
; ----------
|
|
|
|
; ENTRY: TEXT ADDRESS IN [X/A] (LSB/MSB)
|
|
; TEXT LENGTH IN [Y]
|
|
|
|
PRINT: STX LINE+LO ; LSB OF ADDRESS
|
|
STA LINE+HI ; MSB OF ADDRESS
|
|
STY LEN ; LENGTH
|
|
|
|
LDY #0
|
|
LDX CURSOR
|
|
PR0: LDA (LINE),Y
|
|
STA TEXT,X
|
|
INX
|
|
INY
|
|
DEC LEN
|
|
BNE PR0
|
|
STX CURSOR
|
|
RTS
|
|
|
|
; ------
|
|
; MEMTOP
|
|
; ------
|
|
|
|
; EXIT: [A]=$A0 IF 48K, ELSE [A]=0
|
|
|
|
MEMTOP: LDA #0 ; CLEAR $A000
|
|
STA $A000
|
|
LDX $A000 ; CHECK THE VALUE
|
|
BNE EMPTY ; RETURN [A]=0 IF NON-ZERO
|
|
LDA #$A0 ; ELSE RETURN $A0
|
|
EMPTY: RTS
|
|
|
|
; ------
|
|
; RANDOM
|
|
; ------
|
|
|
|
; EXIT: RANDOM 16-BIT WORD IN [X/A]
|
|
|
|
DORAND: LDA RANDOM
|
|
NOP ; A PAUSE ...
|
|
LDX RANDOM
|
|
RTS
|
|
|
|
; ------------
|
|
; SIMPLE DELAY
|
|
; ------------
|
|
|
|
; ENTRY: NEGATIVE JIFFY COUNT IN [VALUE]
|
|
|
|
DELAY: LDA #0 ; WAIT A JIFFY
|
|
STA RTCLOK
|
|
DEL1: LDA RTCLOK
|
|
BEQ DEL1
|
|
|
|
INC VALUE+LO
|
|
BNE DELAY
|
|
INC VALUE+HI
|
|
BNE DELAY
|
|
|
|
BEQ MOVED ; GET A VALUE AND RETURN
|
|
|
|
; -----
|
|
; INPUT
|
|
; -----
|
|
|
|
GINPUT: LDA ARG1+LO ; MOVE [ARG1] INTO [VALUE]
|
|
STA VALUE+LO
|
|
LDA ARG1+HI
|
|
STA VALUE+HI
|
|
|
|
LDA NARGS ; IF THERE ARE 2 ARGS THEN DO THE TABLE
|
|
CMP #1 ; ITERATIONS
|
|
BEQ NOIT
|
|
JMP ITRATE ; YES VIRGINIA, A JUMP
|
|
|
|
NOIT: LDA VALUE+HI
|
|
BMI DELAY ; DO A SIMPLE DELAY
|
|
|
|
ORA VALUE+LO ; IF NON-ZERO,
|
|
BNE TICK ; ENTER SENSE LOOP
|
|
|
|
MOVED: JSR SENSE ; ELSE READ JUST ONCE
|
|
MOVED2: JMP PUTBYT ; ELSE RETURN [A]
|
|
|
|
; INPUT SENSE LOOP
|
|
|
|
TICK: JSR SENSE ; GET READING INTO [A]
|
|
CMP #%10001111 ; ANY INPUT?
|
|
BNE MOVED2 ; YES, RETURN IT
|
|
|
|
LDA #0 ; ELSE WAIT 1 JIFFY
|
|
STA RTCLOK
|
|
TICK1: LDA RTCLOK
|
|
BEQ TICK1
|
|
|
|
JSR DECVAL ; DECREMENT COUNT
|
|
LDA VALUE+LO
|
|
ORA VALUE+HI ; ZERO YET?
|
|
BNE TICK ; NO, LOOP BACK
|
|
|
|
BEQ MOVED ; RETURN
|
|
|
|
; -------------------------
|
|
; CHECK KEYBOARD & JOYSTICK
|
|
; -------------------------
|
|
|
|
; EXIT: INPUT STATUS IN [A]
|
|
|
|
SENSE: LDA #0
|
|
STA ATRACT ; KILL ATTRACT MODE
|
|
|
|
LDA CH ; READ THE KEYBOARD REGISTER
|
|
CMP #$FF ; KEY PRESSED YET?
|
|
BEQ STICK ; IF NOT, CHECK STICK
|
|
|
|
TAY ; ELSE SAVE KEYCODE HERE
|
|
LDX #$FF ; RESET THE
|
|
STX CH ; KEYBOARD REGISTER
|
|
AND #%11000000 ; SHIFT OR CTRL CHAR?
|
|
BNE STICK ; IGNORE IF SO
|
|
|
|
LDA ATASCI,Y ; GET ATASCII CODE INTO [A]
|
|
|
|
CMP #'a' ; CONVERT TO
|
|
BCC KEXIT ; UPPER CASE ALPHA
|
|
CMP #'z'+1 ; IF NECESSARY
|
|
BCS KEXIT
|
|
SEC
|
|
SBC #$20
|
|
|
|
KEXIT: AND #%01111111 ; MAKE SURE IT'S POSITIVE
|
|
RTS
|
|
|
|
; CHECK THE JOYSTICK
|
|
|
|
STICK: LDA STICK0
|
|
AND #%00001111 ; MASK GARBAGE
|
|
LDX STRIG0 ; ALSO CHECK TRIGGER
|
|
BNE STIKEX ; EXIT IF NOT PRESSED
|
|
ORA #%00010000 ; ELSE SET BIT 4
|
|
|
|
STIKEX: ORA #%10000000 ; NEGATIVE FOR STICK READING
|
|
RTS ; RETURN WITH CODE IN [A]
|
|
|
|
; ------------------------
|
|
; ATASCII CONVERSION TABLE
|
|
; ------------------------
|
|
|
|
ATASCI: DB $6C,$6A,$3B,$8A,$8B,$6B,$2B,$2A
|
|
DB $6F,$80,$70,$75,$9B,$69,$2D,$3D
|
|
DB $76,$80,$63,$8C,$8D,$62,$78,$7A
|
|
DB $34,$80,$33,$36,$1B,$35,$32,$31
|
|
DB $2C,$20,$2E,$6E,$80,$6D,$2F,$81
|
|
DB $72,$80,$65,$79,$7F,$74,$77,$71
|
|
DB $39,$80,$30,$37,$7E,$38,$3C,$3E
|
|
DB $66,$68,$64,$80,$82,$67,$73,$61
|
|
|
|
; --------------------
|
|
; DUMP BLOCK TO SCREEN
|
|
; --------------------
|
|
|
|
; ENTRY: BLOCK TO DUMP IN [BLOCK] (TOP BYTE IN [BLOCK+7])
|
|
; X-COORDINATE IN [X], Y-COORDINATE IN [A]
|
|
|
|
DUMP: STX TOX ; SAVE X-COORDINATE
|
|
ASL A ; MULTIPLY Y-COORD BY 8
|
|
ASL A ; TO GET MODE LINE (0-191)
|
|
ASL A
|
|
TAY ; USE AS INDEX
|
|
|
|
LDX #7 ; INIT BLOCK-FETCHING INDEX
|
|
|
|
DUMP0: LDA VLOWS,Y ; GET LSB OF LINE ADDR
|
|
CLC
|
|
ADC TOX ; ADD X-POS
|
|
STA TOADR+LO ; TO GET LSB OF SCREEN ADDR
|
|
LDA VHIGHS,Y ; GET MSB OF LINE ADDR
|
|
ADC #0
|
|
STA TOADR+HI ; FORM MSB OF SCREEN ADDR
|
|
|
|
LDA BLOCK,X ; GET BLOCK DATA
|
|
|
|
DB $8D ; 6502 "STA nnnn" INSTRUCTION
|
|
TOADR: DW $0000 ; SCREEN RAM ADDRESS
|
|
|
|
INY ; NEXT SCAN LINE
|
|
DEX ; DONE 8 BYTES YET?
|
|
BPL DUMP0 ; NO, FETCH MORE
|
|
RTS
|
|
|
|
; -----------------------------------------------
|
|
; DUMP BLOCK TO SCREEN WITH MASK
|
|
;
|
|
; IF THE MASK BIT IS 1 THEN THE SCREEN SHOWS THRU
|
|
; IF THE MASK BIT IS 0 THEN THE ICON IS DISPLAYED
|
|
; -----------------------------------------------
|
|
|
|
; ENTRY: BLOCK TO DUMP IN [BLOCK] (TOP BYTE IN [BLOCK+7])
|
|
; MASK IN [MASK]
|
|
; X-COORDINATE IN [X], Y-COORDINATE IN [A]
|
|
|
|
DMPMSK: STX TOX ; SAVE X-COORDINATE
|
|
ASL A ; MULTIPLY Y-COORD BY 8
|
|
ASL A ; TO GET MODE LINE (0-191)
|
|
ASL A
|
|
TAY ; USE AS INDEX
|
|
|
|
LDX #7 ; INIT BLOCK-FETCHING INDEX
|
|
|
|
DMSK0: LDA VLOWS,Y ; GET LSB OF LINE ADDR
|
|
CLC
|
|
ADC TOX ; ADD X-POS
|
|
STA TOADR2+LO+1 ; TO GET LSB OF SCREEN ADDR
|
|
STA TOADR3+LO+1
|
|
LDA VHIGHS,Y ; GET MSB OF LINE ADDR
|
|
ADC #0
|
|
STA TOADR2+HI+1 ; FORM MSB OF SCREEN ADDR
|
|
STA TOADR3+HI+1
|
|
|
|
TOADR2: LDA $FFFF ; DUMMY GET SCREEN BYTE
|
|
EOR BLOCK,X
|
|
AND MASK,X
|
|
EOR BLOCK,X
|
|
TOADR3: STA $FFFF ; DUMMY PUT BACK ON SCREEN
|
|
|
|
INY ; NEXT SCAN LINE
|
|
DEX ; DONE 8 BYTES YET?
|
|
BPL DMSK0 ; NO, FETCH MORE
|
|
RTS
|
|
|
|
; -----
|
|
; SOUND
|
|
; -----
|
|
|
|
; PLAY SOUND [ARG1] (1-127)
|
|
|
|
GSOUND: LDA ARG1+LO
|
|
BMI SNDERR ; RANGE ERROR!
|
|
CMP #SOUNDS+1
|
|
BCS SNDERR ; SOUND NOT DEFINED
|
|
|
|
SEC
|
|
SBC #1 ; ZERO-ALIGN
|
|
ASL A ; AND WORD-ALIGN
|
|
TAX ; THE SOUND ID INDEX
|
|
LDA STABLE+LO,X ; GET LSB OF EXECUTION ADDR
|
|
STA PLAY+LO
|
|
LDA STABLE+HI,X ; AND MSB
|
|
STA PLAY+HI
|
|
|
|
DB $4C ; 6502 "JMP" INSTRUCTION
|
|
PLAY: DW $0000 ; SOUND JUMP VECTOR
|
|
|
|
; *** ERROR #13: UNDEFINED SOUND ***
|
|
|
|
SNDERR: LDA #13
|
|
JMP GERROR
|
|
|
|
; -----
|
|
; COPY?
|
|
; -----
|
|
|
|
; IS THIS A LEGAL COPY OF THE DISK?
|
|
|
|
GCOPYP EQU PREDS
|
|
|
|
; -------
|
|
; VERIFY?
|
|
; -------
|
|
|
|
; ARE THE GAME AND IMAGE FILES INTACT?
|
|
; NOTE: THIS DOES NOT OBSERVE EXTRA BIT LOW
|
|
; BUT USES EXTRA BIT HIGH! Le
|
|
|
|
GVERP: LDA #0 ; CLEAR
|
|
STA J+LO ; ACCUM FOR CHECKSUM
|
|
STA J+HI
|
|
STA K+LO
|
|
STA DBLOCK ; START AT 1ST GAME SECTOR
|
|
STA VPCH ; START @ BYTE 0064
|
|
STA VPC0 ; USE AS HIGH BIT
|
|
LDA #64 ; 64 W/LOW BIT IN VPC0
|
|
STA VPCL
|
|
|
|
LDA GBEGIN+GLEN ; SET BYTE LENGTH
|
|
STA I+HI ; FOR GAME CHECK
|
|
LDA GBEGIN+GLEN+1 ; (LENGTH IN WORDS -
|
|
ASL A ; SO MULTIPLY BY 2
|
|
STA I+LO ; TO GET BYTES
|
|
ROL I+HI
|
|
ROL K+LO
|
|
JMP READIN ; READ 1ST PAGE IN
|
|
|
|
VSUM: LDA VPCL ; NEW PAGE?
|
|
BNE VSUM2 ; NO, CONTINUE
|
|
READIN: LDX #0 ; SET UP FOR GETDSK
|
|
STX DBTOP
|
|
STX DCNT
|
|
INX
|
|
STX DUNIT
|
|
|
|
LDA #$52 ; "READ"
|
|
STA DCOMND
|
|
LDA #HIGH BUFFER ; NO MOVE
|
|
STA DBUFF+HI
|
|
LDA DBLOCK
|
|
JSR GETGME
|
|
|
|
VSUM2: LDY VPCL ; GET THIS BYTE
|
|
LDA BUFFER,Y
|
|
INC VPCL ; SET FOR NEXT BYTE
|
|
BNE VSUM3
|
|
INC VPCH
|
|
BNE VSUM3
|
|
INC VPC0
|
|
|
|
VSUM3: CLC
|
|
ADC J+LO ; ADD IT TO ACCUM
|
|
STA J+LO
|
|
BCC VSUM0
|
|
INC J+HI
|
|
VSUM0: LDA VPCL ; CHECK IF ALL BYTES DONE
|
|
CMP I+LO
|
|
BNE VSUM
|
|
LDA VPCH
|
|
CMP I+HI
|
|
BNE VSUM
|
|
LDA VPC0
|
|
CMP K+LO
|
|
BNE VSUM ; AS WORD ALIGNED SIZE
|
|
|
|
LDA GBEGIN+GCHECK
|
|
CMP J+HI
|
|
BEQ VSUM4
|
|
JMP BADVER ; OOPS
|
|
VSUM4: LDA GBEGIN+GCHECK+1
|
|
CMP J+LO
|
|
BEQ IFILE
|
|
JMP BADVER
|
|
|
|
; GAME FILE OK, CHECK IMAGE FILE
|
|
|
|
IFILE: LDA #0
|
|
STA K+LO
|
|
LDA ICODE+LO ; FIND VIRTUAL IBEGIN
|
|
STA J+LO
|
|
LDA ICODE+HI
|
|
STA J+HI
|
|
LDY #ILEN ; OFFSET TO LENGTH
|
|
LDA (J),Y
|
|
STA I+HI ; SET I TO LENGTH
|
|
INY
|
|
LDA (J),Y
|
|
ASL A ; *2 AS WORD VALUE
|
|
STA I+LO
|
|
ROL I+HI
|
|
ROL K+LO
|
|
|
|
LDY #ICHECK ; GET CHECKSUM
|
|
LDA (J),Y ; WHILE IT'S EASY
|
|
STA CHKSUM+HI ; SAVE IT HERE
|
|
INY
|
|
LDA (J),Y
|
|
STA CHKSUM+LO
|
|
|
|
LDA #0 ; CLEAR FOR IMAGE FILE
|
|
STA J+LO
|
|
STA J+HI
|
|
STA VPCH
|
|
STA VPC0
|
|
STA DBLOCK ; SET TO START OF IMAGE SECTORS.
|
|
LDA #8
|
|
STA VPCL ; HEADER OF IMAGE FILE
|
|
JMP IRDIN
|
|
|
|
ISUM: LDA VPCL ; NEW PAGE?
|
|
BNE ISUM2 ; NO, CONTINUE
|
|
IRDIN: LDX #0 ; SET UP FOR GETDSK
|
|
STX DBTOP
|
|
STX DCNT
|
|
INX
|
|
STX DUNIT
|
|
|
|
LDA #$52 ; "READ"
|
|
STA DCOMND
|
|
LDA #HIGH BUFFER ; NO MOVE
|
|
STA DBUFF+HI
|
|
LDA DBLOCK
|
|
JSR GETIMG
|
|
|
|
ISUM2: LDY VPCL ; GET THIS BYTE
|
|
LDA BUFFER,Y
|
|
INC VPCL ; SET FOR NEXT BYTE
|
|
BNE ISUM3
|
|
INC VPCH
|
|
BNE ISUM3
|
|
INC VPC0
|
|
|
|
ISUM3: CLC
|
|
ADC J+LO ; ADD IT TO ACCUM
|
|
STA J+LO
|
|
BCC ISUM0
|
|
INC J+HI
|
|
ISUM0: LDA VPCL ; CHECK IF ALL BYTES DONE
|
|
CMP I+LO
|
|
BNE ISUM
|
|
LDA VPCH
|
|
CMP I+HI
|
|
BNE ISUM
|
|
LDA VPC0
|
|
CMP K+LO
|
|
BNE ISUM ; AS WORD ALIGNED SIZE
|
|
|
|
LDA CHKSUM+LO ; COMPARE TO SAVED CHECKSUM
|
|
CMP J+LO
|
|
BNE BADVER
|
|
LDA CHKSUM+HI
|
|
CMP J+HI
|
|
BNE BADVER
|
|
|
|
JMP PREDS ; SUCCESS!
|
|
|
|
BADVER: JMP PREDF
|
|
|
|
END
|
|
|