|
|
|
@ -8,11 +8,10 @@
|
|
|
|
|
; categories, and then alphabetically. Categories are ordered so that the 8bit
|
|
|
|
|
; opcodes come first, then the 16bit ones. 0xff ends the chain
|
|
|
|
|
instrNames:
|
|
|
|
|
; Branching instructions. They are all shortcuts to BRBC/BRBS. Their respective
|
|
|
|
|
; bits are listed in instrBRBits. These are not in alphabetical order, but
|
|
|
|
|
; rather in "bit order". All "bit set" instructions first (10th bit clear), then
|
|
|
|
|
; all "bit clear" ones (10th bit set). Inside this order, they're then in "sss"
|
|
|
|
|
; order (bit number alias for BRBC/BRBS)
|
|
|
|
|
; Branching instructions. They are all shortcuts to BRBC/BRBS. These are not in
|
|
|
|
|
; alphabetical order, but rather in "bit order". All "bit set" instructions
|
|
|
|
|
; first (10th bit clear), then all "bit clear" ones (10th bit set). Inside this
|
|
|
|
|
; order, they're then in "sss" order (bit number alias for BRBC/BRBS).
|
|
|
|
|
.db "BRCS", 0
|
|
|
|
|
.db "BREQ", 0
|
|
|
|
|
.db "BRMI", 0
|
|
|
|
@ -32,7 +31,7 @@ instrNames:
|
|
|
|
|
.equ I_BRBS 16
|
|
|
|
|
.db "BRBS", 0
|
|
|
|
|
.db "BRBC", 0
|
|
|
|
|
; Rd(5) + Rr(5)
|
|
|
|
|
; Rd(5) + Rr(5) (from here, instrUpMasks1)
|
|
|
|
|
.equ I_ADC 18
|
|
|
|
|
.db "ADC", 0
|
|
|
|
|
.db "ADD", 0
|
|
|
|
@ -47,8 +46,21 @@ instrNames:
|
|
|
|
|
.db "OR", 0
|
|
|
|
|
.db "SBC", 0
|
|
|
|
|
.db "SUB", 0
|
|
|
|
|
; no arg
|
|
|
|
|
.equ I_BREAK 31
|
|
|
|
|
.equ I_ANDI 31
|
|
|
|
|
.db "ANDI", 0
|
|
|
|
|
.db "CPI", 0
|
|
|
|
|
.db "LDI", 0
|
|
|
|
|
.db "ORI", 0
|
|
|
|
|
.db "SBCI", 0
|
|
|
|
|
.db "SBR", 0
|
|
|
|
|
.db "SUBI", 0
|
|
|
|
|
.equ I_BLD 38
|
|
|
|
|
.db "BLD", 0
|
|
|
|
|
.db "BST", 0
|
|
|
|
|
.db "SBRC", 0
|
|
|
|
|
.db "SBRS", 0
|
|
|
|
|
; no arg (from here, instrUpMasks2)
|
|
|
|
|
.equ I_BREAK 42
|
|
|
|
|
.db "BREAK", 0
|
|
|
|
|
.db "CLC", 0
|
|
|
|
|
.db "CLH", 0
|
|
|
|
@ -76,7 +88,7 @@ instrNames:
|
|
|
|
|
.db "SLEEP", 0
|
|
|
|
|
.db "WDR", 0
|
|
|
|
|
; Rd(5)
|
|
|
|
|
.equ I_ASR 57
|
|
|
|
|
.equ I_ASR 68
|
|
|
|
|
.db "ASR", 0
|
|
|
|
|
.db "COM", 0
|
|
|
|
|
.db "DEC", 0
|
|
|
|
@ -111,6 +123,20 @@ instrUpMasks1:
|
|
|
|
|
.db 0b00101000 ; OR
|
|
|
|
|
.db 0b00001000 ; SBC
|
|
|
|
|
.db 0b00011000 ; SUB
|
|
|
|
|
; Rd(4) + K(8): XXXXKKKK ddddKKKK
|
|
|
|
|
.db 0b01110000 ; ANDI
|
|
|
|
|
.db 0b00110000 ; CPI
|
|
|
|
|
.db 0b11100000 ; LDI
|
|
|
|
|
.db 0b01100000 ; ORI
|
|
|
|
|
.db 0b01000000 ; SBCI
|
|
|
|
|
.db 0b01100000 ; SBR
|
|
|
|
|
.db 0b01010000 ; SUBI
|
|
|
|
|
; Rd(5) + bit: XXXXXXXd ddddXbbb: lonely bit in LSB is 0 in all cases, so we
|
|
|
|
|
; ignore it.
|
|
|
|
|
.db 0b11111000 ; BLD
|
|
|
|
|
.db 0b11111010 ; BST
|
|
|
|
|
.db 0b11111100 ; SBRC
|
|
|
|
|
.db 0b11111110 ; SBRS
|
|
|
|
|
|
|
|
|
|
; 16-bit constant masks associated with each instruction. In the same order as
|
|
|
|
|
; in instrNames
|
|
|
|
@ -158,25 +184,6 @@ instrUpMasks2:
|
|
|
|
|
.db 0b10010100, 0b00000010 ; SWAP
|
|
|
|
|
.db 0b10010010, 0b00000100 ; XCH
|
|
|
|
|
|
|
|
|
|
instrBRBits:
|
|
|
|
|
; 1st bit is 3rd bit of MSB and the other 3 are the lower bits of LSB
|
|
|
|
|
.db 0b0000 ; BRCS
|
|
|
|
|
.db 0b0001 ; BREQ
|
|
|
|
|
.db 0b0010 ; BRMI
|
|
|
|
|
.db 0b0011 ; BRVS
|
|
|
|
|
.db 0b0100 ; BRLT
|
|
|
|
|
.db 0b0101 ; BRHS
|
|
|
|
|
.db 0b0110 ; BRTS
|
|
|
|
|
.db 0b0111 ; BRIE
|
|
|
|
|
.db 0b1000 ; BRCC
|
|
|
|
|
.db 0b1001 ; BRNE
|
|
|
|
|
.db 0b1010 ; BRPL
|
|
|
|
|
.db 0b1011 ; BRVC
|
|
|
|
|
.db 0b1100 ; BRGE
|
|
|
|
|
.db 0b1101 ; BRHC
|
|
|
|
|
.db 0b1110 ; BRTC
|
|
|
|
|
.db 0b1111 ; BRID
|
|
|
|
|
|
|
|
|
|
; Same signature as getInstID in instr.asm
|
|
|
|
|
; Reads string in (HL) and returns the corresponding ID (I_*) in A. Sets Z if
|
|
|
|
|
; there's a match.
|
|
|
|
@ -215,24 +222,29 @@ getInstID:
|
|
|
|
|
parseInstruction:
|
|
|
|
|
; BC, during .spit, is ORred to the spitted opcode.
|
|
|
|
|
ld bc, 0
|
|
|
|
|
; Save Instr ID in D, which is less volatile than A. In almost all
|
|
|
|
|
; cases, we fetch the opcode constant at the end of the processing.
|
|
|
|
|
ld d, a
|
|
|
|
|
cp I_ADC
|
|
|
|
|
jp c, .BR
|
|
|
|
|
cp I_BREAK
|
|
|
|
|
cp I_ANDI
|
|
|
|
|
jr c, .spitRd5Rr5
|
|
|
|
|
cp I_BLD
|
|
|
|
|
jr c, .spitRdK8
|
|
|
|
|
cp I_BREAK
|
|
|
|
|
jr c, .spitRdBit
|
|
|
|
|
cp I_ASR
|
|
|
|
|
jr c, .spitNoArg
|
|
|
|
|
; spitRd5
|
|
|
|
|
ld d, a ; save A for later
|
|
|
|
|
call .readR5
|
|
|
|
|
ret nz
|
|
|
|
|
call .placeRd
|
|
|
|
|
ld a, d ; restore A
|
|
|
|
|
; continue to .spitNoArg
|
|
|
|
|
.spitNoArg:
|
|
|
|
|
call .getUp2
|
|
|
|
|
jr .spit
|
|
|
|
|
|
|
|
|
|
.spitRd5Rr5:
|
|
|
|
|
ld d, a ; save A for later
|
|
|
|
|
call .readR5
|
|
|
|
|
ret nz
|
|
|
|
|
call .placeRd
|
|
|
|
@ -251,10 +263,49 @@ parseInstruction:
|
|
|
|
|
rra \ rra \ rra
|
|
|
|
|
or b
|
|
|
|
|
ld b, a
|
|
|
|
|
ld a, d ; restore A
|
|
|
|
|
call .getUp1
|
|
|
|
|
; now that's our MSB
|
|
|
|
|
jr .spitMSB
|
|
|
|
|
|
|
|
|
|
.spitRdK8:
|
|
|
|
|
call .readR4
|
|
|
|
|
ret nz
|
|
|
|
|
call .placeRd
|
|
|
|
|
call readComma
|
|
|
|
|
call readWord
|
|
|
|
|
call parseExpr
|
|
|
|
|
ret nz
|
|
|
|
|
ld a, c
|
|
|
|
|
ld a, 0xff
|
|
|
|
|
call .IX2A
|
|
|
|
|
ret nz
|
|
|
|
|
push af ; --> lvl 1
|
|
|
|
|
; let's start with the 4 lower bits
|
|
|
|
|
and 0xf
|
|
|
|
|
or c
|
|
|
|
|
; We now have our LSB in A. Let's spit it now.
|
|
|
|
|
call ioPutB
|
|
|
|
|
pop af ; <-- lvl 1
|
|
|
|
|
; and now those high 4 bits
|
|
|
|
|
and 0xf0
|
|
|
|
|
rra \ rra \ rra \ rra
|
|
|
|
|
ld b, a
|
|
|
|
|
call .getUp1
|
|
|
|
|
jr .spitMSB
|
|
|
|
|
|
|
|
|
|
.spitRdBit:
|
|
|
|
|
call .readR5
|
|
|
|
|
ret nz
|
|
|
|
|
call .placeRd
|
|
|
|
|
call readComma
|
|
|
|
|
ret nz
|
|
|
|
|
call .readBit
|
|
|
|
|
ret nz
|
|
|
|
|
; LSB is in A and is ready to go
|
|
|
|
|
call ioPutB
|
|
|
|
|
call .getUp1
|
|
|
|
|
jr .spitMSB
|
|
|
|
|
|
|
|
|
|
.spit:
|
|
|
|
|
; LSB is spit *before* MSB
|
|
|
|
|
inc hl
|
|
|
|
@ -329,13 +380,8 @@ parseInstruction:
|
|
|
|
|
; upcode becomes 0b111101
|
|
|
|
|
inc b
|
|
|
|
|
.rdBRBS:
|
|
|
|
|
call readWord
|
|
|
|
|
call .readBit
|
|
|
|
|
ret nz
|
|
|
|
|
call parseExpr
|
|
|
|
|
ld a, 7
|
|
|
|
|
call .IX2A
|
|
|
|
|
ret nz
|
|
|
|
|
ld c, a
|
|
|
|
|
call readComma
|
|
|
|
|
ret nz
|
|
|
|
|
jr .spitBR2
|
|
|
|
@ -349,19 +395,30 @@ parseInstruction:
|
|
|
|
|
ld c, a
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
; Fetch a 8-bit upcode specified by instr index in A and set that upcode in HL
|
|
|
|
|
; Fetch a 8-bit upcode specified by instr index in D and set that upcode in HL
|
|
|
|
|
.getUp1:
|
|
|
|
|
ld a, d
|
|
|
|
|
sub I_ADC
|
|
|
|
|
ld hl, instrUpMasks1
|
|
|
|
|
jp addHL
|
|
|
|
|
|
|
|
|
|
; Fetch a 16-bit upcode specified by instr index in A and set that upcode in HL
|
|
|
|
|
; Fetch a 16-bit upcode specified by instr index in D and set that upcode in HL
|
|
|
|
|
.getUp2:
|
|
|
|
|
ld a, d
|
|
|
|
|
sub I_BREAK
|
|
|
|
|
sla a ; A * 2
|
|
|
|
|
ld hl, instrUpMasks2
|
|
|
|
|
jp addHL
|
|
|
|
|
|
|
|
|
|
.readR4:
|
|
|
|
|
call .readR5
|
|
|
|
|
ret nz
|
|
|
|
|
; has to be in the 16-31 range
|
|
|
|
|
sub 0x10
|
|
|
|
|
jp c, unsetZ
|
|
|
|
|
cp a ; ensure Z
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
; read a rXX argument and return register number in A.
|
|
|
|
|
; Set Z for success.
|
|
|
|
|
.readR5:
|
|
|
|
@ -376,6 +433,18 @@ parseInstruction:
|
|
|
|
|
ld a, 31
|
|
|
|
|
jr .IX2A
|
|
|
|
|
|
|
|
|
|
.readBit:
|
|
|
|
|
call readWord
|
|
|
|
|
ret nz
|
|
|
|
|
call parseExpr
|
|
|
|
|
ld a, 7
|
|
|
|
|
call .IX2A
|
|
|
|
|
ret nz
|
|
|
|
|
or c
|
|
|
|
|
ld c, a
|
|
|
|
|
cp a ; ensure Z
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
; Put IX's LSB into A and, additionally, ensure that the new value is <=
|
|
|
|
|
; than what was previously in A.
|
|
|
|
|
; Z for success.
|
|
|
|
|