mirror of
https://github.com/erkyrath/infocom-zcode-terps.git
synced 2026-01-11 23:43:24 +00:00
217 lines
4.2 KiB
Plaintext
217 lines
4.2 KiB
Plaintext
PAGE
|
|
SBTTL "--- MAIN LOOP ---"
|
|
|
|
MLOOP: LDX #$FF ; RESET THE
|
|
TXS ; HARDWARE STACK
|
|
INX ; = 0
|
|
STX NARGS ; CLEAR # ARGS
|
|
JSR NEXTPC ; GET Z-BYTE INTO [A]
|
|
STA OPCODE ; FLAGS ARE SET
|
|
|
|
IF DEBUG
|
|
LDA #0 ; BREAKPOINT #0
|
|
JSR DOBUG
|
|
LDA OPCODE
|
|
ENDIF
|
|
|
|
; DECODE AN OPCODE
|
|
|
|
TAX ; SET FLAGS
|
|
BMI DC0 ; IF POSITIVE,
|
|
JMP OP2 ; IT'S A 2-OP
|
|
|
|
DC0: CMP #$E0 ; IS IT "CALL"?
|
|
BNE DC1
|
|
JMP GCALL
|
|
|
|
DC1: CMP #$B0
|
|
BCS DC2
|
|
JMP OP1 ; OR MAYBE A 1-OP
|
|
|
|
DC2: CMP #$C0
|
|
BCS OPEXT
|
|
JMP OP0 ; PERHAPS A 0-OP
|
|
|
|
; --------------
|
|
; HANDLE AN X-OP
|
|
; --------------
|
|
|
|
OPEXT: JSR NEXTPC ; GRAB ARGUMENT BYTE
|
|
STA ABYTE ; HOLD IT HERE
|
|
|
|
LDX #0
|
|
STX ADEX ; INIT LOOP INDEX
|
|
BEQ OPX1 ; JUMP INTO LOOP
|
|
|
|
TOPX: LDA ABYTE ; GET ARG BYTE
|
|
ASL A ; SHIFT NEXT 2 ARG BITS
|
|
ASL A ; INTO BITS 7 & 6
|
|
STA ABYTE ; HOLD FOR LATER
|
|
|
|
OPX1: AND #%11000000 ; MASK OUT GARBAGE BITS
|
|
BNE OPX2
|
|
JSR GETLNG ; 00 = LONG IMMEDIATE
|
|
JMP OPXNXT
|
|
|
|
OPX2: CMP #%01000000 ; IS IT A SHORT IMMEDIATE?
|
|
BNE OPX3 ; NO, KEEP GUESSING
|
|
JSR GETSHT ; 01 = SHORT IMMEDIATE
|
|
JMP OPXNXT
|
|
|
|
OPX3: CMP #%10000000 ; LAST TEST
|
|
BNE OPX4 ; 11 = NO MORE ARGUMENTS
|
|
JSR GETVAR ; 10 = VARIABLE
|
|
|
|
OPXNXT: LDX ADEX ; ARGUMENT INDEX
|
|
LDA VALUE+LO ; GRAB LSB OF VALUE
|
|
STA ARG1+LO,X ; STORE IN ARGUMENT TABLE
|
|
LDA VALUE+HI ; GRAB MSB OF VALUE
|
|
STA ARG1+HI,X ; STORE THAT, TOO
|
|
|
|
INC NARGS ; UPDATE ARGUMENT COUNTER
|
|
|
|
INX
|
|
INX
|
|
STX ADEX ; UPDATE INDEX
|
|
CPX #8 ; DONE 4 ARGUMENTS YET?
|
|
BCC TOPX ; NO, GET SOME MORE
|
|
|
|
; ALL X-OP ARGUMENTS READY
|
|
|
|
OPX4: LDA OPCODE ; IS THIS
|
|
CMP #$E0 ; AN EXTENDED 2-OP?
|
|
BCS DOXOP ; NO, IT'S A REAL X-OP
|
|
JMP OP2EX ; ELSE TREAT IT LIKE A 2-OP
|
|
|
|
DOXOP: LDX #LOW OPTX ; GET ADDR OF X-OP TABLE
|
|
LDY #HIGH OPTX ; INTO [X/Y]
|
|
AND #%00011111 ; ISOLATE OP ID BITS
|
|
CMP #NOPSX ; IS IT A LEGAL X-OP?
|
|
BCC DODIS ; YUP; TIME TO DISPATCH IT
|
|
|
|
; *** ERROR #2: UNDEFINED X-OP ***
|
|
|
|
LDA #2
|
|
JMP GERROR
|
|
|
|
; ---------------
|
|
; OPCODE DISPATCH
|
|
; ---------------
|
|
|
|
; ENTRY: MASKED OPCODE INDEX IN [A]
|
|
; OP-TABLE ADDR IN X/Y (LSB/MSB)
|
|
|
|
DODIS: STX I+LO ; SAVE TABLE ADDRESS
|
|
STY I+HI ; IN A POINTER
|
|
|
|
ASL A ; WORD-ALIGN THE OP INDEX
|
|
TAY
|
|
LDA (I),Y ; GET LSB OF DISPATCH ADDRESS
|
|
STA GO+LO ; INSTALL AS JSR OPERAND
|
|
INY
|
|
LDA (I),Y ; SAME WITH MSB
|
|
STA GO+HI
|
|
|
|
DB $20 ; 6502 "JSR" OPCODE
|
|
GO: DW $0000 ; DUMMY OPERAND BYTES
|
|
|
|
JMP MLOOP ; GO BACK FOR ANOTHER OPCODE
|
|
|
|
; -------------
|
|
; HANDLE A 0-OP
|
|
; -------------
|
|
|
|
OP0: LDX #LOW OPT0 ; GET ADDR OF 0-OP TABLE
|
|
LDY #HIGH OPT0 ; INTO [X/Y]
|
|
AND #%00001111 ; ISOLATE OP ID BITS
|
|
CMP #NOPS0 ; OUT OF RANGE?
|
|
BCC DODIS ; NO, DISPATCH
|
|
|
|
; *** ERROR #3: UNDEFINED 0-OP ***
|
|
|
|
LDA #3
|
|
JMP GERROR
|
|
|
|
; -------------
|
|
; HANDLE A 1-OP
|
|
; -------------
|
|
|
|
OP1: AND #%00110000 ; ISOLATE ARGUMENT BITS
|
|
BNE OP1A
|
|
JSR GETLNG ; 00 = LONG IMMEDIATE
|
|
JMP OP1EX
|
|
|
|
OP1A: CMP #%00010000 ; TEST AGAIN
|
|
BNE OP1B
|
|
JSR GETSHT ; 01 = SHORT IMMEDIATE
|
|
JMP OP1EX
|
|
|
|
OP1B: CMP #%00100000 ; ONE MORE TEST
|
|
BNE BADOP1 ; UNDEFINED STATE!
|
|
JSR GETVAR ; 10 = VARIABLE
|
|
|
|
OP1EX: JSR V2A1 ; VALUE TO [ARG1], UPDATE COUNT
|
|
LDX #LOW OPT1 ; LSB OF DISPATCH TABLE
|
|
LDY #HIGH OPT1 ; MSB
|
|
LDA OPCODE ; RESTORE OPCODE
|
|
AND #%00001111 ; ISOLATE OP ID BITS
|
|
CMP #NOPS1 ; IF WITHIN RANGE,
|
|
BCC DODIS ; EXECUTE THE 1-OP
|
|
|
|
; *** ERROR #4: UNDEFINED 1-OP ***
|
|
|
|
BADOP1: LDA #4
|
|
JMP GERROR
|
|
|
|
; -------------
|
|
; HANDLE A 2-OP
|
|
; -------------
|
|
|
|
OP2: AND #%01000000 ; ISOLATE 1ST ARG BIT
|
|
BNE OP2A
|
|
JSR GETSHT ; 0 = SHORT IMMEDIATE
|
|
JMP OP2B
|
|
OP2A: JSR GETVAR ; 1 = VARIABLE
|
|
OP2B: JSR V2A1 ; VALUE TO [ARG1], UPDATE COUNT
|
|
|
|
LDA OPCODE ; RESTORE OPCODE BYTE
|
|
AND #%00100000 ; ISOLATE 2ND ARG BIT
|
|
BNE OP2C
|
|
JSR GETSHT ; 0 = SHORT IMMEDIATE
|
|
JMP OP2D
|
|
OP2C: JSR GETVAR ; 1 = VARIABLE
|
|
OP2D: LDA VALUE+LO ; MOVE VALUE TO [ARG2]
|
|
STA ARG2+LO
|
|
LDA VALUE+HI
|
|
STA ARG2+HI
|
|
INC NARGS ; UPDATE COUNT
|
|
|
|
; ENTRY FOR EXTENDED 2-OPS
|
|
|
|
OP2EX: LDX #LOW OPT2 ; LSB OF DISPATCH TABLE
|
|
LDY #HIGH OPT2 ; MSB
|
|
LDA OPCODE ; RESTORE OPCODE BYTE
|
|
AND #%00011111 ; ISOLATE OP ID BITS
|
|
CMP #NOPS2
|
|
BCS BADOP2 ; ERROR IF OUT OF RANGE
|
|
JMP DODIS ; ELSE DISPATCH
|
|
|
|
; *** ERROR #5: UNDEFINED 2-OP ****
|
|
|
|
BADOP2: LDA #5
|
|
JMP GERROR
|
|
|
|
; --------------------------------------
|
|
; MOVE [VALUE] TO [ARG1], UPDATE [NARGS]
|
|
; --------------------------------------
|
|
|
|
V2A1: LDA VALUE+LO
|
|
STA ARG1+LO
|
|
LDA VALUE+HI
|
|
STA ARG1+HI
|
|
INC NARGS
|
|
RTS
|
|
|
|
END
|
|
|