2023-11-16 18:19:54 -05:00

213 lines
4.2 KiB
Plaintext

PAGE
SBTTL "--- MAIN LOOP ---"
MLOOP: LDA #0
STA NARGS ; RESET # ARGUMENTS
JSR NEXTPC ; GET NEXT INSTRUCTION INTO [A]
STA OPCODE ; SAVE IT HERE
IF DEBUG
LDA SECTOR+LO
STA MBYTE
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 #$B0
BCS DC1
JMP OP1 ; OR MAYBE A 1-OP
DC1: CMP #$C0
BCS OPEXT
JMP OP0 ; PERHAPS A 0-OP
; --------------
; HANDLE AN X-OP
; --------------
OPEXT: JSR NEXTPC ; GRAB THE ARGUMENT ID BYTE
STA ABYTE ; HOLD IT HERE
LDX #0
STX ADEX ; INIT ARGUMENT INDEX
BEQ OPX1 ; JUMP TO TOP OF LOOP
OPX0: 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 ; RETRIEVE 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 OPX0 ; 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 #1 -- ILLEGAL X-OP ***
LDA #1
JMP ZERROR
; ---------------
; 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 0-OP TABLE ADDR
LDY #HIGH OPT0 ; INTO [X/Y]
AND #%00001111 ; ISOLATE 0-OP ID BITS
CMP #NOPS0 ; OUT OF RANGE?
BCC DODIS ; NO, DISPATCH IT
; *** ERROR #2 -- ILLEGAL 0-OP ***
LDA #2
JMP ZERROR
; -------------
; 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 ; MOVE [VALUE] TO [ARG1], UPDATE [NARGS]
LDX #LOW OPT1 ; GET ADDR OF 1-OP TABLE
LDY #HIGH OPT1 ; INTO [X/Y]
LDA OPCODE ; RESTORE OPCODE
AND #%00001111 ; ISOLATE OP ID BITS
CMP #NOPS1 ; IF WITHIN RANGE,
BCC DODIS ; EXECUTE THE 1-OP
; *** ERROR #3 -- ILLEGAL 1-OP ***
BADOP1: LDA #3
JMP ZERROR
; -------------
; 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 [NARGS]
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 2ND [VALUE]
STA ARG2+LO ; INTO [ARG2]
LDA VALUE+HI
STA ARG2+HI
INC NARGS ; UPDATE ARGUMENT COUNT
; EXECUTE A 2-OP OR EXTENDED 2-OP
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 #4 -- ILLEGAL 2-OP ****
BADOP2: LDA #4
JMP ZERROR
; --------------------------------------
; MOVE [VALUE] TO [ARG1], UPDATE [NARGS]
; --------------------------------------
V2A1: LDA VALUE+LO
STA ARG1+LO
LDA VALUE+HI
STA ARG1+HI
INC NARGS
RTS
END