1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-26 04:18:09 +11:00

Compare commits

...

5 Commits

Author SHA1 Message Date
Virgil Dupras
30d6fdb16b ti/lcd: use brand new support for IX in SRL and RR 2019-11-10 22:07:44 -05:00
Virgil Dupras
2bff486cd2 Update bootstrap binaries 2019-11-10 22:03:46 -05:00
Virgil Dupras
5f6b303e75 zasm: add IX/IY support to SRL, RR and RL 2019-11-10 22:03:18 -05:00
Virgil Dupras
506c3d0a96 zasm: generalize handling of IX/IY in 0xcb upcode family
There's a couple of bit fiddling instructions that didn't have their
IX/IY variant implemented yet and without this commit, each of them
would have required a special routine. Not anymore.
2019-11-10 21:02:18 -05:00
Virgil Dupras
d9d6093287 zasm: simplify (IX/Y+d) handling
We now require less special handling.
2019-11-10 20:16:50 -05:00
9 changed files with 693 additions and 465 deletions

View File

@ -2,7 +2,7 @@
; Number of rows in the argspec table ; Number of rows in the argspec table
.equ ARGSPEC_TBL_CNT 33 .equ ARGSPEC_TBL_CNT 33
; Number of rows in the primary instructions table ; Number of rows in the primary instructions table
.equ INSTR_TBL_CNT 162 .equ INSTR_TBL_CNT 147
; size in bytes of each row in the primary instructions table ; size in bytes of each row in the primary instructions table
.equ INSTR_TBL_ROWSIZE 6 .equ INSTR_TBL_ROWSIZE 6
; Instruction IDs They correspond to the index of the table in instrNames ; Instruction IDs They correspond to the index of the table in instrNames
@ -84,12 +84,18 @@ checkNOrM:
cp 'M' cp 'M'
ret ret
; Checks whether A is 'n', 'm', 'x' or 'y' ; Checks whether A is 'n', 'm'
checknmxy: checknm:
cp 'n' cp 'n'
ret z ret z
cp 'm' cp 'm'
ret
checklxy:
cp 'l'
ret z ret z
; Checks whether A is 'x', 'y'
checkxy:
cp 'x' cp 'x'
ret z ret z
cp 'y' cp 'y'
@ -330,6 +336,7 @@ findInGroup:
ret ret
; Compare argspec from instruction table in A with argument in (HL). ; Compare argspec from instruction table in A with argument in (HL).
; IX must point to argspec row.
; For constant args, it's easy: if A == (HL), it's a success. ; For constant args, it's easy: if A == (HL), it's a success.
; If it's not this, then we check if it's a numerical arg. ; If it's not this, then we check if it's a numerical arg.
; If A is a group ID, we do something else: we check that (HL) exists in the ; If A is a group ID, we do something else: we check that (HL) exists in the
@ -342,11 +349,21 @@ matchArg:
; not an exact match. Before we continue: is A zero? Because if it is, ; not an exact match. Before we continue: is A zero? Because if it is,
; we have to stop right here: no match possible. ; we have to stop right here: no match possible.
or a or a
jr nz, .skip ; not a zero, we can continue jr nz, .skip1 ; not a zero, we can continue
; zero, stop here ; zero, stop here
cp 1 ; unset Z cp 1 ; unset Z
ret ret
.skip: .skip1:
; If our argspec is 'l', then we also match 'x' and 'y'
cp 'l'
jr nz, .skip2
; Does it accept IX and IY?
bit 4, (ix+3)
ld a, (hl)
jp nz, checkxy ; bit set: our result is checkxy
; doesn't accept? then we don't match
jp unsetZ
.skip2:
; Alright, let's start with a special case. Is it part of the special ; Alright, let's start with a special case. Is it part of the special
; "BIT" group, 0xc? If yes, we actually expect a number, which will ; "BIT" group, 0xc? If yes, we actually expect a number, which will
; then be ORed like a regular group index. ; then be ORed like a regular group index.
@ -429,78 +446,19 @@ matchPrimaryRow:
; Handle like a regular "JP (IX+d)" except that we refuse any displacement: if ; Handle like a regular "JP (IX+d)" except that we refuse any displacement: if
; a displacement is specified, we error out. ; a displacement is specified, we error out.
handleJPIX:
ld a, 0xdd
jr handleJPIXY
handleJPIY:
ld a, 0xfd
handleJPIXY: handleJPIXY:
ld (INS_UPCODE), a
ld a, (INS_CURARG1+1) ld a, (INS_CURARG1+1)
cp 0 ; numerical argument *must* be zero or a ; numerical argument *must* be zero
jr nz, .error jr nz, .error
; ok, we're good ; ok, we're good
ld a, 0xe9 ; second upcode ld a, 0xe9 ; second upcode
ld (INS_UPCODE+1), a ld (INS_UPCODE), a
ld c, 2 ld c, 1
ret ret
.error: .error:
ld c, 0 ld c, 0
ret ret
; Handle the first argument of BIT. Sets Z if first argument is valid, unset it
; if there's an error.
handleBIT:
ld a, (INS_CURARG1+1)
cp 8
jr nc, .error ; >= 8? error
; We're good
cp a ; ensure Z
ret
.error:
ld c, 0
jp unsetZ
handleBITIX:
ld a, 0xdd
ld b, 0b01000110
jr _handleBITIXY
handleBITIY:
ld a, 0xfd
ld b, 0b01000110
jr _handleBITIXY
handleSETIX:
ld a, 0xdd
ld b, 0b11000110
jr _handleBITIXY
handleSETIY:
ld a, 0xfd
ld b, 0b11000110
jr _handleBITIXY
handleRESIX:
ld a, 0xdd
ld b, 0b10000110
jr _handleBITIXY
handleRESIY:
ld a, 0xfd
ld b, 0b10000110
_handleBITIXY:
ld (INS_UPCODE), a ; first upcode
call handleBIT
ret nz ; error
ld a, 0xcb ; 2nd upcode
ld (INS_UPCODE+1), a
ld a, (INS_CURARG2+1) ; IXY displacement
ld (INS_UPCODE+2), a
ld a, (INS_CURARG1+1) ; 0-7
rla
rla
rla
or b ; 4th upcode
ld (INS_UPCODE+3), a
ld c, 4
ret
handleBITR: handleBITR:
ld b, 0b01000000 ld b, 0b01000000
jr _handleBITR jr _handleBITR
@ -510,8 +468,6 @@ handleSETR:
handleRESR: handleRESR:
ld b, 0b10000000 ld b, 0b10000000
_handleBITR: _handleBITR:
call handleBIT
ret nz ; error
; get group value ; get group value
ld a, (INS_CURARG2+1) ; group value ld a, (INS_CURARG2+1) ; group value
ld c, a ld c, a
@ -520,7 +476,7 @@ _handleBITR:
ld (INS_UPCODE), a ld (INS_UPCODE), a
; get bit value ; get bit value
ld a, (INS_CURARG1+1) ; 0-7 ld a, (INS_CURARG1+1) ; 0-7
rla rlca ; clears cary if any
rla rla
rla rla
; Now we have group value in stack, bit value in A (properly shifted) ; Now we have group value in stack, bit value in A (properly shifted)
@ -557,58 +513,40 @@ handleIM:
ld c, 2 ld c, 2
ret ret
handleLDIXn:
ld a, 0xdd
jr handleLDIXYn
handleLDIYn:
ld a, 0xfd
handleLDIXYn: handleLDIXYn:
ld (INS_UPCODE), a
ld a, 0x36 ; second upcode ld a, 0x36 ; second upcode
ld (INS_UPCODE+1), a ld (INS_UPCODE), a
ld a, (INS_CURARG1+1) ; IXY displacement ld a, (INS_CURARG1+1) ; IXY displacement
ld (INS_UPCODE+2), a ld (INS_UPCODE+1), a
ld a, (INS_CURARG2+1) ; N ld a, (INS_CURARG2+1) ; N
ld (INS_UPCODE+3), a ld (INS_UPCODE+2), a
ld c, 4 ld c, 3
ret ret
handleLDIXr:
ld a, 0xdd
jr handleLDIXYr
handleLDIYr:
ld a, 0xfd
handleLDIXYr: handleLDIXYr:
ld (INS_UPCODE), a
ld a, (INS_CURARG2+1) ; group value ld a, (INS_CURARG2+1) ; group value
or 0b01110000 ; second upcode or 0b01110000 ; second upcode
ld (INS_UPCODE+1), a ld (INS_UPCODE), a
ld a, (INS_CURARG1+1) ; IXY displacement ld a, (INS_CURARG1+1) ; IXY displacement
ld (INS_UPCODE+2), a ld (INS_UPCODE+1), a
ld c, 3 ld c, 2
ret ret
handleLDrIX:
ld a, 0xdd
jr handleLDrIXY
handleLDrIY:
ld a, 0xfd
handleLDrIXY: handleLDrIXY:
ld (INS_UPCODE), a
ld a, (INS_CURARG1+1) ; group value ld a, (INS_CURARG1+1) ; group value
rla \ rla \ rla rlca \ rla \ rla
or 0b01000110 ; second upcode or 0b01000110 ; second upcode
ld (INS_UPCODE+1), a ld (INS_UPCODE), a
ld a, (INS_CURARG2+1) ; IXY displacement ld a, (INS_CURARG2+1) ; IXY displacement
ld (INS_UPCODE+2), a ld (INS_UPCODE+1), a
ld c, 3 ld c, 2
ret ret
handleLDrr: handleLDrr:
; first argument is displaced by 3 bits, second argument is not ; first argument is displaced by 3 bits, second argument is not
; displaced and we or that with a leading 0b01000000 ; displaced and we or that with a leading 0b01000000
ld a, (INS_CURARG1+1) ; group value ld a, (INS_CURARG1+1) ; group value
rla rlca
rla rla
rla rla
ld c, a ; store it ld c, a ; store it
@ -630,6 +568,39 @@ spitUpcode:
; First, let's go in IX mode. It's easier to deal with offsets here. ; First, let's go in IX mode. It's easier to deal with offsets here.
push de \ pop ix push de \ pop ix
; before we begin, are we in a 'l' argspec? Is it flagged for IX/IY
; acceptance? If yes, a 'x' or 'y' instruction? Check this on both
; args and if we detect a 'x' or 'y', things are *always* the same:
; the upcode is exactly the same as its (HL) counterpart except that
; it is preceeded by 0xdd or 0xfd. If we're 'x' or 'y', then it means
; that we've already been matched to a 'l' argspec, so after spitting
; 0xdd or 0xfd, we can continue as normal.
ld a, (ix+1)
call checklxy
jr z, .isl
ld a, (ix+2)
call checklxy
jr nz, .begin ; no point in checking further.
.isl:
ld a, (INS_CURARG1)
cp 'x'
jr z, .isx
cp 'y'
jr z, .isy
ld a, (INS_CURARG2)
cp 'x'
jr z, .isx
cp 'y'
jr z, .isy
jr .begin
.isx:
ld a, 0xdd
call ioPutB
jr .begin
.isy:
ld a, 0xfd
call ioPutB
.begin:
; Are we a "special instruction"? ; Are we a "special instruction"?
bit 5, (ix+3) bit 5, (ix+3)
jr z, .normalInstr ; not set: normal instruction jr z, .normalInstr ; not set: normal instruction
@ -644,10 +615,9 @@ spitUpcode:
; we begin by writing our "base upcode", which can be one or two bytes ; we begin by writing our "base upcode", which can be one or two bytes
ld a, (ix+4) ; first upcode ld a, (ix+4) ; first upcode
ld (INS_UPCODE), a ld (INS_UPCODE), a
ld de, INS_UPCODE ; from this point, DE points to "where we are" ; from this point, DE points to "where we are" in terms of upcode
; in terms of upcode writing. ; writing.
inc de ; make DE point to where we should write next. ld de, INS_UPCODE+1
ld c, 1 ; C holds our upcode count ld c, 1 ; C holds our upcode count
; Now, let's determine if we have one or two upcode. As a general rule, ; Now, let's determine if we have one or two upcode. As a general rule,
@ -718,13 +688,19 @@ spitUpcode:
ld hl, INS_CURARG1 ld hl, INS_CURARG1
call checkNOrM call checkNOrM
jr z, .withWord jr z, .withWord
call checknmxy call checknm
jr z, .withByte
ld a, (INS_CURARG1)
call checkxy
jr z, .withByte jr z, .withByte
ld a, (ix+2) ; second argspec ld a, (ix+2) ; second argspec
ld hl, INS_CURARG2 ld hl, INS_CURARG2
call checkNOrM call checkNOrM
jr z, .withWord jr z, .withWord
call checknmxy call checknm
jr z, .withByte
ld a, (INS_CURARG2)
call checkxy
jr z, .withByte jr z, .withByte
; nope, no number, alright, we're finished here ; nope, no number, alright, we're finished here
jr .writeIO jr .writeIO
@ -800,7 +776,14 @@ spitUpcode:
inc c inc c
; to writeIO ; to writeIO
.writeIO: .writeIO:
; Before we write IO, let's check a very specific case: is our first
; upcode 0xcb and our byte count == 3? If yes, then swap the two last
; bytes. In all instructions except 0xcb ones, IX/IY displacement comes
; last, but in all 0xcb instructions, they come 2nd last.
call .checkCB
; Let's write INS_UPCODE to IO ; Let's write INS_UPCODE to IO
dec c \ inc c ; is C zero?
jr z, .numberTruncated
ld b, c ; save output byte count ld b, c ; save output byte count
ld hl, INS_UPCODE ld hl, INS_UPCODE
.loopWrite: .loopWrite:
@ -809,7 +792,7 @@ spitUpcode:
jr nz, .ioError jr nz, .ioError
inc hl inc hl
djnz .loopWrite djnz .loopWrite
; Z is set by INC HL cp a ; ensure Z
jr .end jr .end
.numberTruncated: .numberTruncated:
; Z already unset ; Z already unset
@ -825,6 +808,21 @@ spitUpcode:
pop de pop de
pop ix pop ix
ret ret
.checkCB:
ld a, (INS_UPCODE)
cp 0xcb
ret nz
ld a, c
cp 3
ret nz
; We are in 0xcb + displacement situation. Swap bytes 2 and 3.
ld a, (INS_UPCODE+1)
ex af, af'
ld a, (INS_UPCODE+2)
ld (INS_UPCODE+1), a
ex af, af'
ld (INS_UPCODE+2), a
ret
; Parse argument in (HL) and place it in (DE) ; Parse argument in (HL) and place it in (DE)
; Sets Z on success, reset on error. ; Sets Z on success, reset on error.
@ -1066,48 +1064,39 @@ instrNames:
; Bit 5: Indicates that this row is handled very specially: the next two bytes ; Bit 5: Indicates that this row is handled very specially: the next two bytes
; aren't upcode bytes, but a routine address to call to handle this case with ; aren't upcode bytes, but a routine address to call to handle this case with
; custom code. ; custom code.
; Bit 4: When in an 'l' argspec, this means "I accept IX and IY variants".
instrTBl: instrTBl:
.db I_ADC, 'A', 'l', 0, 0x8e , 0 ; ADC A, (HL) .db I_ADC, 'A', 'l', 0, 0x8e , 0 ; ADC A, (HL)
.db I_ADC, 'A', 0xb, 0, 0b10001000 , 0 ; ADC A, r .db I_ADC, 'A', 0xb, 0, 0b10001000 , 0 ; ADC A, r
.db I_ADC, 'A', 'n', 0, 0xce , 0 ; ADC A, n .db I_ADC, 'A', 'n', 0, 0xce , 0 ; ADC A, n
.db I_ADC, 'h', 0x3, 0x44, 0xed, 0b01001010 ; ADC HL, ss .db I_ADC, 'h', 0x3, 0x44, 0xed, 0b01001010 ; ADC HL, ss
.db I_ADD, 'A', 'l', 0, 0x86 , 0 ; ADD A, (HL) .db I_ADD, 'A', 'l', 0x10, 0x86 , 0 ; ADD A, (HL) + (IX/Y)
.db I_ADD, 'A', 0xb, 0, 0b10000000 , 0 ; ADD A, r .db I_ADD, 'A', 0xb, 0, 0b10000000 , 0 ; ADD A, r
.db I_ADD, 'A', 'n', 0, 0xc6 , 0 ; ADD A, n .db I_ADD, 'A', 'n', 0, 0xc6 , 0 ; ADD A, n
.db I_ADD, 'h', 0x3, 4, 0b00001001 , 0 ; ADD HL, ss .db I_ADD, 'h', 0x3, 4, 0b00001001 , 0 ; ADD HL, ss
.db I_ADD, 'X', 0x4, 0x44, 0xdd, 0b00001001 ; ADD IX, pp .db I_ADD, 'X', 0x4, 0x44, 0xdd, 0b00001001 ; ADD IX, pp
.db I_ADD, 'Y', 0x5, 0x44, 0xfd, 0b00001001 ; ADD IY, rr .db I_ADD, 'Y', 0x5, 0x44, 0xfd, 0b00001001 ; ADD IY, rr
.db I_ADD, 'A', 'x', 0, 0xdd, 0x86 ; ADD A, (IX+d) .db I_AND, 'l', 0, 0x10, 0xa6 , 0 ; AND (HL) + (IX/Y)
.db I_ADD, 'A', 'y', 0, 0xfd, 0x86 ; ADD A, (IY+d)
.db I_AND, 'l', 0, 0, 0xa6 , 0 ; AND (HL)
.db I_AND, 0xb, 0, 0, 0b10100000 , 0 ; AND r .db I_AND, 0xb, 0, 0, 0b10100000 , 0 ; AND r
.db I_AND, 'n', 0, 0, 0xe6 , 0 ; AND n .db I_AND, 'n', 0, 0, 0xe6 , 0 ; AND n
.db I_AND, 'x', 0, 0, 0xdd, 0xa6 ; AND (IX+d) .db I_BIT, 0xc, 'l', 0x53, 0xcb, 0b01000110 ; BIT b, (HL) + (IX/Y)
.db I_AND, 'y', 0, 0, 0xfd, 0xa6 ; AND (IY+d) .db I_BIT, 0xc, 0xb, 0x20 \ .dw handleBITR ; BIT b, r
.db I_BIT, 0xc, 'l', 0x43, 0xcb, 0b01000110 ; BIT b, (HL)
.db I_BIT, 'n', 'x', 0x20 \ .dw handleBITIX ; BIT b, (IX+d)
.db I_BIT, 'n', 'y', 0x20 \ .dw handleBITIY ; BIT b, (IY+d)
.db I_BIT, 'n', 0xb, 0x20 \ .dw handleBITR ; BIT b, r
.db I_CALL,0xa, 'N', 3, 0b11000100 , 0 ; CALL cc, NN .db I_CALL,0xa, 'N', 3, 0b11000100 , 0 ; CALL cc, NN
.db I_CALL,'N', 0, 0, 0xcd , 0 ; CALL NN .db I_CALL,'N', 0, 0, 0xcd , 0 ; CALL NN
.db I_CCF, 0, 0, 0, 0x3f , 0 ; CCF .db I_CCF, 0, 0, 0, 0x3f , 0 ; CCF
.db I_CP, 'l', 0, 0, 0xbe , 0 ; CP (HL) .db I_CP, 'l', 0, 0x10, 0xbe , 0 ; CP (HL) + (IX/Y)
.db I_CP, 0xb, 0, 0, 0b10111000 , 0 ; CP r .db I_CP, 0xb, 0, 0, 0b10111000 , 0 ; CP r
.db I_CP, 'n', 0, 0, 0xfe , 0 ; CP n .db I_CP, 'n', 0, 0, 0xfe , 0 ; CP n
.db I_CP, 'x', 0, 0, 0xdd, 0xbe ; CP (IX+d)
.db I_CP, 'y', 0, 0, 0xfd, 0xbe ; CP (IY+d)
.db I_CPD, 0, 0, 0, 0xed, 0xa9 ; CPD .db I_CPD, 0, 0, 0, 0xed, 0xa9 ; CPD
.db I_CPDR,0, 0, 0, 0xed, 0xb9 ; CPDR .db I_CPDR,0, 0, 0, 0xed, 0xb9 ; CPDR
.db I_CPI, 0, 0, 0, 0xed, 0xa1 ; CPI .db I_CPI, 0, 0, 0, 0xed, 0xa1 ; CPI
.db I_CPIR,0, 0, 0, 0xed, 0xb1 ; CPIR .db I_CPIR,0, 0, 0, 0xed, 0xb1 ; CPIR
.db I_CPL, 0, 0, 0, 0x2f , 0 ; CPL .db I_CPL, 0, 0, 0, 0x2f , 0 ; CPL
.db I_DAA, 0, 0, 0, 0x27 , 0 ; DAA .db I_DAA, 0, 0, 0, 0x27 , 0 ; DAA
.db I_DEC, 'l', 0, 0, 0x35 , 0 ; DEC (HL) .db I_DEC, 'l', 0, 0x10, 0x35 , 0 ; DEC (HL) + (IX/Y)
.db I_DEC, 'X', 0, 0, 0xdd, 0x2b ; DEC IX .db I_DEC, 'X', 0, 0, 0xdd, 0x2b ; DEC IX
.db I_DEC, 'x', 0, 0, 0xdd, 0x35 ; DEC (IX+d)
.db I_DEC, 'Y', 0, 0, 0xfd, 0x2b ; DEC IY .db I_DEC, 'Y', 0, 0, 0xfd, 0x2b ; DEC IY
.db I_DEC, 'y', 0, 0, 0xfd, 0x35 ; DEC (IY+d)
.db I_DEC, 0xb, 0, 3, 0b00000101 , 0 ; DEC r .db I_DEC, 0xb, 0, 3, 0b00000101 , 0 ; DEC r
.db I_DEC, 0x3, 0, 4, 0b00001011 , 0 ; DEC ss .db I_DEC, 0x3, 0, 4, 0b00001011 , 0 ; DEC ss
.db I_DI, 0, 0, 0, 0xf3 , 0 ; DI .db I_DI, 0, 0, 0, 0xf3 , 0 ; DI
@ -1123,22 +1112,20 @@ instrTBl:
.db I_IM, 'n', 0, 0x20 \ .dw handleIM ; IM {0,1,2} .db I_IM, 'n', 0, 0x20 \ .dw handleIM ; IM {0,1,2}
.db I_IN, 'A', 'm', 0, 0xdb , 0 ; IN A, (n) .db I_IN, 'A', 'm', 0, 0xdb , 0 ; IN A, (n)
.db I_IN, 0xb, 'k', 0x43, 0xed, 0b01000000 ; IN r, (C) .db I_IN, 0xb, 'k', 0x43, 0xed, 0b01000000 ; IN r, (C)
.db I_INC, 'l', 0, 0, 0x34 , 0 ; INC (HL) .db I_INC, 'l', 0, 0x10, 0x34 , 0 ; INC (HL) + (IX/Y)
.db I_INC, 'X', 0, 0, 0xdd , 0x23 ; INC IX .db I_INC, 'X', 0, 0, 0xdd , 0x23 ; INC IX
.db I_INC, 'x', 0, 0, 0xdd , 0x34 ; INC (IX+d)
.db I_INC, 'Y', 0, 0, 0xfd , 0x23 ; INC IY .db I_INC, 'Y', 0, 0, 0xfd , 0x23 ; INC IY
.db I_INC, 'y', 0, 0, 0xfd , 0x34 ; INC (IY+d)
.db I_INC, 0xb, 0, 3, 0b00000100 , 0 ; INC r .db I_INC, 0xb, 0, 3, 0b00000100 , 0 ; INC r
.db I_INC, 0x3, 0, 4, 0b00000011 , 0 ; INC ss .db I_INC, 0x3, 0, 4, 0b00000011 , 0 ; INC ss
.db I_IND, 0, 0, 0, 0xed, 0xaa ; IND .db I_IND, 0, 0, 0, 0xed, 0xaa ; IND
.db I_INDR,0, 0, 0, 0xed, 0xba ; INDR .db I_INDR,0, 0, 0, 0xed, 0xba ; INDR
.db I_INI, 0, 0, 0, 0xed, 0xa2 ; INI .db I_INI, 0, 0, 0, 0xed, 0xa2 ; INI
.db I_INIR,0, 0, 0, 0xed, 0xb2 ; INIR .db I_INIR,0, 0, 0, 0xed, 0xb2 ; INIR
.db I_JP, 'x', 0, 0x20 \ .dw handleJPIXY ; JP (IX)
.db I_JP, 'y', 0, 0x20 \ .dw handleJPIXY ; JP (IY)
.db I_JP, 'l', 0, 0, 0xe9 , 0 ; JP (HL) .db I_JP, 'l', 0, 0, 0xe9 , 0 ; JP (HL)
.db I_JP, 0xa, 'N', 3, 0b11000010 , 0 ; JP cc, NN .db I_JP, 0xa, 'N', 3, 0b11000010 , 0 ; JP cc, NN
.db I_JP, 'N', 0, 0, 0xc3 , 0 ; JP NN .db I_JP, 'N', 0, 0, 0xc3 , 0 ; JP NN
.db I_JP, 'x', 0, 0x20 \ .dw handleJPIX ; JP (IX)
.db I_JP, 'y', 0, 0x20 \ .dw handleJPIY ; JP (IY)
.db I_JR, 'n', 0, 0x80, 0x18 , 0 ; JR e .db I_JR, 'n', 0, 0x80, 0x18 , 0 ; JR e
.db I_JR, 'C', 'n', 0x80, 0x38 , 0 ; JR C, e .db I_JR, 'C', 'n', 0x80, 0x38 , 0 ; JR C, e
.db I_JR, '=', 'n', 0x80, 0x30 , 0 ; JR NC, e .db I_JR, '=', 'n', 0x80, 0x30 , 0 ; JR NC, e
@ -1171,23 +1158,21 @@ instrTBl:
.db I_LD, 'Y', 'M', 0, 0xfd, 0x2a ; LD IY, (NN) .db I_LD, 'Y', 'M', 0, 0xfd, 0x2a ; LD IY, (NN)
.db I_LD, 'M', 0x3, 0x44, 0xed, 0b01000011 ; LD (NN), dd .db I_LD, 'M', 0x3, 0x44, 0xed, 0b01000011 ; LD (NN), dd
.db I_LD, 0x3, 'M', 0x44, 0xed, 0b01001011 ; LD dd, (NN) .db I_LD, 0x3, 'M', 0x44, 0xed, 0b01001011 ; LD dd, (NN)
.db I_LD, 'x', 'n', 0x20 \ .dw handleLDIXn ; LD (IX+d), n .db I_LD, 'x', 'n', 0x20 \ .dw handleLDIXYn ; LD (IX+d), n
.db I_LD, 'y', 'n', 0x20 \ .dw handleLDIYn ; LD (IY+d), n .db I_LD, 'y', 'n', 0x20 \ .dw handleLDIXYn ; LD (IY+d), n
.db I_LD, 'x', 0xb, 0x20 \ .dw handleLDIXr ; LD (IX+d), r .db I_LD, 'x', 0xb, 0x20 \ .dw handleLDIXYr ; LD (IX+d), r
.db I_LD, 'y', 0xb, 0x20 \ .dw handleLDIYr ; LD (IY+d), r .db I_LD, 'y', 0xb, 0x20 \ .dw handleLDIXYr ; LD (IY+d), r
.db I_LD, 0xb, 'x', 0x20 \ .dw handleLDrIX ; LD r, (IX+d) .db I_LD, 0xb, 'x', 0x20 \ .dw handleLDrIXY ; LD r, (IX+d)
.db I_LD, 0xb, 'y', 0x20 \ .dw handleLDrIY ; LD r, (IY+d) .db I_LD, 0xb, 'y', 0x20 \ .dw handleLDrIXY ; LD r, (IY+d)
.db I_LDD, 0, 0, 0, 0xed, 0xa8 ; LDD .db I_LDD, 0, 0, 0, 0xed, 0xa8 ; LDD
.db I_LDDR,0, 0, 0, 0xed, 0xb8 ; LDDR .db I_LDDR,0, 0, 0, 0xed, 0xb8 ; LDDR
.db I_LDI, 0, 0, 0, 0xed, 0xa0 ; LDI .db I_LDI, 0, 0, 0, 0xed, 0xa0 ; LDI
.db I_LDIR,0, 0, 0, 0xed, 0xb0 ; LDIR .db I_LDIR,0, 0, 0, 0xed, 0xb0 ; LDIR
.db I_NEG, 0, 0, 0, 0xed, 0x44 ; NEG .db I_NEG, 0, 0, 0, 0xed, 0x44 ; NEG
.db I_NOP, 0, 0, 0, 0x00 , 0 ; NOP .db I_NOP, 0, 0, 0, 0x00 , 0 ; NOP
.db I_OR, 'l', 0, 0, 0xb6 , 0 ; OR (HL) .db I_OR, 'l', 0, 0x10, 0xb6 , 0 ; OR (HL) + (IX/Y)
.db I_OR, 0xb, 0, 0, 0b10110000 , 0 ; OR r .db I_OR, 0xb, 0, 0, 0b10110000 , 0 ; OR r
.db I_OR, 'n', 0, 0, 0xf6 , 0 ; OR n .db I_OR, 'n', 0, 0, 0xf6 , 0 ; OR n
.db I_OR, 'x', 0, 0, 0xdd, 0xb6 ; OR (IX+d)
.db I_OR, 'y', 0, 0, 0xfd, 0xb6 ; OR (IY+d)
.db I_OTDR,0, 0, 0, 0xed, 0xbb ; OTDR .db I_OTDR,0, 0, 0, 0xed, 0xbb ; OTDR
.db I_OTIR,0, 0, 0, 0xed, 0xb3 ; OTIR .db I_OTIR,0, 0, 0, 0xed, 0xb3 ; OTIR
.db I_OUT, 'm', 'A', 0, 0xd3 , 0 ; OUT (n), A .db I_OUT, 'm', 'A', 0, 0xd3 , 0 ; OUT (n), A
@ -1198,19 +1183,19 @@ instrTBl:
.db I_PUSH,'X', 0, 0, 0xdd, 0xe5 ; PUSH IX .db I_PUSH,'X', 0, 0, 0xdd, 0xe5 ; PUSH IX
.db I_PUSH,'Y', 0, 0, 0xfd, 0xe5 ; PUSH IY .db I_PUSH,'Y', 0, 0, 0xfd, 0xe5 ; PUSH IY
.db I_PUSH,0x1, 0, 4, 0b11000101 , 0 ; PUSH qq .db I_PUSH,0x1, 0, 4, 0b11000101 , 0 ; PUSH qq
.db I_RES, 0xc, 'l', 0x43, 0xcb, 0b10000110 ; RES b, (HL) .db I_RES, 0xc, 'l', 0x53, 0xcb, 0b10000110 ; RES b, (HL) + (IX/Y)
.db I_RES, 'n', 'x', 0x20 \ .dw handleRESIX ; RES b, (IX+d) .db I_RES, 0xc, 0xb, 0x20 \ .dw handleRESR ; RES b, r
.db I_RES, 'n', 'y', 0x20 \ .dw handleRESIY ; RES b, (IY+d)
.db I_RES, 'n', 0xb, 0x20 \ .dw handleRESR ; RES b, r
.db I_RET, 0, 0, 0, 0xc9 , 0 ; RET .db I_RET, 0, 0, 0, 0xc9 , 0 ; RET
.db I_RET, 0xa, 0, 3, 0b11000000 , 0 ; RET cc .db I_RET, 0xa, 0, 3, 0b11000000 , 0 ; RET cc
.db I_RETI,0, 0, 0, 0xed, 0x4d ; RETI .db I_RETI,0, 0, 0, 0xed, 0x4d ; RETI
.db I_RETN,0, 0, 0, 0xed, 0x45 ; RETN .db I_RETN,0, 0, 0, 0xed, 0x45 ; RETN
.db I_RL, 0xb, 0,0x40, 0xcb, 0b00010000 ; RL r .db I_RL, 0xb, 0,0x40, 0xcb, 0b00010000 ; RL r
.db I_RL, 'l', 0,0x10, 0xcb, 0b00010110 ; RL (HL) + (IX/Y)
.db I_RLA, 0, 0, 0, 0x17 , 0 ; RLA .db I_RLA, 0, 0, 0, 0x17 , 0 ; RLA
.db I_RLC, 0xb, 0,0x40, 0xcb, 0b00000000 ; RLC r .db I_RLC, 0xb, 0,0x40, 0xcb, 0b00000000 ; RLC r
.db I_RLCA,0, 0, 0, 0x07 , 0 ; RLCA .db I_RLCA,0, 0, 0, 0x07 , 0 ; RLCA
.db I_RR, 0xb, 0,0x40, 0xcb, 0b00011000 ; RR r .db I_RR, 0xb, 0,0x40, 0xcb, 0b00011000 ; RR r
.db I_RR, 'l', 0,0x10, 0xcb, 0b00011110 ; RR (HL) + (IX/Y)
.db I_RRA, 0, 0, 0, 0x1f , 0 ; RRA .db I_RRA, 0, 0, 0, 0x1f , 0 ; RRA
.db I_RRC, 0xb, 0,0x40, 0xcb, 0b00001000 ; RRC r .db I_RRC, 0xb, 0,0x40, 0xcb, 0b00001000 ; RRC r
.db I_RRCA,0, 0, 0, 0x0f , 0 ; RRCA .db I_RRCA,0, 0, 0, 0x0f , 0 ; RRCA
@ -1218,12 +1203,11 @@ instrTBl:
.db I_SBC, 'A', 0xb, 0, 0b10011000 , 0 ; SBC A, r .db I_SBC, 'A', 0xb, 0, 0b10011000 , 0 ; SBC A, r
.db I_SBC,'h',0x3,0x44, 0xed, 0b01000010 ; SBC HL, ss .db I_SBC,'h',0x3,0x44, 0xed, 0b01000010 ; SBC HL, ss
.db I_SCF, 0, 0, 0, 0x37 , 0 ; SCF .db I_SCF, 0, 0, 0, 0x37 , 0 ; SCF
.db I_SET, 0xc, 'l', 0x43, 0xcb, 0b11000110 ; SET b, (HL) .db I_SET, 0xc, 'l', 0x53, 0xcb, 0b11000110 ; SET b, (HL) + (IX/Y)
.db I_SET, 'n', 'x', 0x20 \ .dw handleSETIX ; SET b, (IX+d) .db I_SET, 0xc, 0xb, 0x20 \ .dw handleSETR ; SET b, r
.db I_SET, 'n', 'y', 0x20 \ .dw handleSETIY ; SET b, (IY+d)
.db I_SET, 'n', 0xb, 0x20 \ .dw handleSETR ; SET b, r
.db I_SLA, 0xb, 0,0x40, 0xcb, 0b00100000 ; SLA r .db I_SLA, 0xb, 0,0x40, 0xcb, 0b00100000 ; SLA r
.db I_SRL, 0xb, 0,0x40, 0xcb, 0b00111000 ; SRL r .db I_SRL, 0xb, 0,0x40, 0xcb, 0b00111000 ; SRL r
.db I_SRL, 'l', 0,0x10, 0xcb, 0b00111110 ; SRL (HL) + (IX/Y)
.db I_SUB, 'l', 0, 0, 0x96 , 0 ; SUB (HL) .db I_SUB, 'l', 0, 0, 0x96 , 0 ; SUB (HL)
.db I_SUB, 0xb, 0, 0, 0b10010000 , 0 ; SUB r .db I_SUB, 0xb, 0, 0, 0b10010000 , 0 ; SUB r
.db I_SUB, 'n', 0, 0, 0xd6 , 0 ; SUB n .db I_SUB, 'n', 0, 0, 0xd6 , 0 ; SUB n

View File

@ -142,19 +142,22 @@ ioPutBack:
ret ret
ioPutB: ioPutB:
push hl push hl ; --> lvl 1
ld hl, (IO_PC) ld hl, (IO_PC)
inc hl inc hl
ld (IO_PC), hl ld (IO_PC), hl
pop hl pop hl ; <-- lvl 1
push af push af ; --> lvl 1
call zasmIsFirstPass call zasmIsFirstPass
jr z, .skip jr z, .skip
pop af pop af ; <-- lvl 1
push ix ; --> lvl 1
ld ix, IO_OUT_BLK ld ix, IO_OUT_BLK
jp _blkPutB call _blkPutB
pop ix ; <-- lvl 1
ret
.skip: .skip:
pop af pop af ; <-- lvl 1
cp a ; ensure Z cp a ; ensure Z
ret ret

View File

@ -258,17 +258,12 @@ lcdSendGlyph:
ret z ; zero? nothing to do ret z ; zero? nothing to do
push bc ; --> lvl 1 push bc ; --> lvl 1
xor a xor a
ld b, a ld (ix+FNT_HEIGHT), a
ld a, (ix)
; TODO: support SRL (IX) and RR (IX) in zasm
.shiftLoop: .shiftLoop:
srl a srl (ix)
rr b rr (ix+FNT_HEIGHT)
dec c dec c
jr nz, .shiftLoop jr nz, .shiftLoop
ld (ix), a
ld a, b
ld (ix+FNT_HEIGHT), a
pop bc ; <-- lvl 1 pop bc ; <-- lvl 1
ret ret

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,177 @@
jp runTests
.inc "err.h"
.inc "core.asm"
.inc "parse.asm"
.inc "zasm/const.asm"
.inc "lib/util.asm"
.inc "zasm/util.asm"
.inc "lib/parse.asm"
.inc "zasm/parse.asm"
.inc "zasm/expr.asm"
.equ INS_RAMSTART RAMSTART
.inc "zasm/instr.asm"
zasmGetPC:
ret
zasmIsFirstPass:
jp unsetZ
readWord:
readComma:
symFindVal:
xor a
ret
ioPutB:
push hl
ld hl, SPITBOWL
push af
ld a, (SPITCNT)
call addHL
inc a
ld (SPITCNT), a
pop af
ld (hl), a
pop hl
cp a
ret
runTests:
call testMatchArg
call testSpitUpcode
xor a
halt
testSpitUpcode:
ld ix, .t1
call .test
ld ix, .t2
call .test
ld ix, .t3
call .test
ld ix, .t4
call .test
ld ix, .t5
call .test
ret
.test:
; init spitbowl
xor a
ld (SPITCNT), a
ld (SPITBOWL), a
ld (SPITBOWL+1), a
ld (SPITBOWL+2), a
ld (SPITBOWL+3), a
push ix \ pop de
call intoDE
ld a, (ix+2)
ld (INS_CURARG1), a
ld a, (ix+3)
ld (INS_CURARG1+1), a
ld a, (ix+4)
ld (INS_CURARG1+2), a
ld a, (ix+5)
ld (INS_CURARG2), a
ld a, (ix+6)
ld (INS_CURARG2+1), a
ld a, (ix+7)
ld (INS_CURARG2+2), a
call spitUpcode
jp nz, fail
ld a, (SPITCNT)
cp (ix+8)
jp nz, fail
ld a, (SPITBOWL)
cp (ix+9)
jp nz, fail
ld a, (SPITBOWL+1)
cp (ix+10)
jp nz, fail
ld a, (SPITBOWL+2)
cp (ix+11)
jp nz, fail
ld a, (SPITBOWL+3)
cp (ix+12)
jp nz, fail
jp nexttest
; Test data is a argspec pointer in instrTBl followed by 2*3 bytes of CURARG
; followed by the expected spit, 1 byte cnt + 4 bytes spits.
.t1:
.dw instrTBl+17*6 ; CCF
.db 0, 0, 0
.db 0, 0, 0
.db 1, 0x3f, 0, 0, 0
.t2:
.dw instrTBl+10*6 ; AND (IX+0x42)
.db 'x', 0x42, 0
.db 0, 0, 0
.db 3, 0xdd, 0xa6, 0x42, 0
.t3:
.dw instrTBl+13*6 ; BIT 4, (IX+3)
.db 'N', 4, 0
.db 'x', 3, 0
.db 4, 0xdd, 0xcb, 0x03, 0x66
.t4:
.dw instrTBl+18*6 ; CP (IX+5)
.db 'x', 5, 0
.db 0, 0, 0
.db 3, 0xdd, 0xbe, 0x05, 0
.t5:
.dw instrTBl+4*6 ; ADD A, (IX+5)
.db 'A', 0, 0
.db 'x', 5, 0
.db 3, 0xdd, 0x86, 0x05, 0
testMatchArg:
ld iy, .t1
call .test
ret
.test:
ld hl, SPITBOWL
ld a, (iy+2)
ld (hl), a
push iy \ pop de
call intoDE
push de \ pop ix
ld a, (ix+1)
call matchArg
jp nz, fail
ld a, (iy+3)
ld (hl), a
ld a, (ix+2)
call matchArg
jp nz, fail
jp nexttest
; Test data is argspec pointer followed by two bytes: first bytes of our two
; CURARG.
.t1:
.dw instrTBl+4*6 ; ADD A, (IX)
.db 'A', 'x'
nexttest:
ld a, (testNum)
inc a
ld (testNum), a
ret
fail:
ld a, (testNum)
halt
testNum: .db 1
SPITCNT:
.db 0
SPITBOWL:
.db 0, 0, 0, 0
DIREC_LASTVAL:
.db 0, 0
RAMSTART:

View File

@ -19,6 +19,24 @@ ADC HL, DE
ADC HL, HL ADC HL, HL
ADC HL, SP ADC HL, SP
ADD A, (HL) ADD A, (HL)
ADD A, (IX)
ADD A, (IX+1)
ADD A, (IX-1)
ADD A, (IX+10)
ADD A, (IX-10)
ADD A, (IX+100)
ADD A, (IX-100)
ADD A, (IX+127)
ADD A, (IX-127)
ADD A, (IY)
ADD A, (IY+1)
ADD A, (IY-1)
ADD A, (IY+10)
ADD A, (IY-10)
ADD A, (IY+100)
ADD A, (IY-100)
ADD A, (IY+127)
ADD A, (IY-127)
ADD A, B ADD A, B
ADD A, C ADD A, C
ADD A, D ADD A, D
@ -46,40 +64,7 @@ ADD IY, BC
ADD IY, DE ADD IY, DE
ADD IY, IY ADD IY, IY
ADD IY, SP ADD IY, SP
ADD A, (IX)
ADD A, (IX+1)
ADD A, (IX-1)
ADD A, (IX+10)
ADD A, (IX-10)
ADD A, (IX+100)
ADD A, (IX-100)
ADD A, (IX+127)
ADD A, (IX-127)
ADD A, (IY)
ADD A, (IY+1)
ADD A, (IY-1)
ADD A, (IY+10)
ADD A, (IY-10)
ADD A, (IY+100)
ADD A, (IY-100)
ADD A, (IY+127)
ADD A, (IY-127)
AND (HL) AND (HL)
AND B
AND C
AND D
AND E
AND H
AND L
AND A
AND 1
AND 2
AND 4
AND 8
AND 16
AND 32
AND 64
AND 128
AND (IX+1) AND (IX+1)
AND (IX-1) AND (IX-1)
AND (IX+10) AND (IX+10)
@ -96,84 +81,99 @@ AND (IY+100)
AND (IY-100) AND (IY-100)
AND (IY+127) AND (IY+127)
AND (IY-127) AND (IY-127)
BIT 1, (HL) AND B
BIT 2, (HL) AND C
BIT 4, (HL) AND D
BIT 1, (IX) AND E
BIT 1, (IX+1) AND H
BIT 1, (IX-1) AND L
BIT 1, (IX+10) AND A
BIT 1, (IX-10) AND 1
BIT 1, (IX+100) AND 2
BIT 1, (IX-100) AND 4
BIT 1, (IX+127) AND 8
BIT 1, (IX-127) AND 16
BIT 2, (IX) AND 32
BIT 2, (IX+1) AND 64
BIT 2, (IX-1) AND 128
BIT 2, (IX+10) BIT 0, (HL)
BIT 2, (IX-10) BIT 0, (IX)
BIT 2, (IX+100) BIT 0, (IX+1)
BIT 2, (IX-100) BIT 0, (IX-1)
BIT 2, (IX+127) BIT 0, (IX+10)
BIT 2, (IX-127) BIT 0, (IX-10)
BIT 4, (IX) BIT 0, (IX+100)
BIT 4, (IX+1) BIT 0, (IX-100)
BIT 4, (IX-1) BIT 0, (IX+127)
BIT 4, (IX+10) BIT 0, (IX-127)
BIT 4, (IX-10) BIT 0, (IY)
BIT 4, (IX+100) BIT 0, (IY+1)
BIT 4, (IX-100) BIT 0, (IY-1)
BIT 4, (IX+127) BIT 0, (IY+10)
BIT 4, (IX-127) BIT 0, (IY-10)
BIT 1, (IY) BIT 0, (IY+100)
BIT 1, (IY+1) BIT 0, (IY-100)
BIT 1, (IY-1) BIT 0, (IY+127)
BIT 1, (IY+10) BIT 0, (IY-127)
BIT 1, (IY-10) BIT 3, (HL)
BIT 1, (IY+100) BIT 3, (IX)
BIT 1, (IY-100) BIT 3, (IX+1)
BIT 1, (IY+127) BIT 3, (IX-1)
BIT 1, (IY-127) BIT 3, (IX+10)
BIT 2, (IY) BIT 3, (IX-10)
BIT 2, (IY+1) BIT 3, (IX+100)
BIT 2, (IY-1) BIT 3, (IX-100)
BIT 2, (IY+10) BIT 3, (IX+127)
BIT 2, (IY-10) BIT 3, (IX-127)
BIT 2, (IY+100) BIT 3, (IY)
BIT 2, (IY-100) BIT 3, (IY+1)
BIT 2, (IY+127) BIT 3, (IY-1)
BIT 2, (IY-127) BIT 3, (IY+10)
BIT 4, (IY) BIT 3, (IY-10)
BIT 4, (IY+1) BIT 3, (IY+100)
BIT 4, (IY-1) BIT 3, (IY-100)
BIT 4, (IY+10) BIT 3, (IY+127)
BIT 4, (IY-10) BIT 3, (IY-127)
BIT 4, (IY+100) BIT 7, (HL)
BIT 4, (IY-100) BIT 7, (IX)
BIT 4, (IY+127) BIT 7, (IX+1)
BIT 4, (IY-127) BIT 7, (IX-1)
BIT 1, B BIT 7, (IX+10)
BIT 1, C BIT 7, (IX-10)
BIT 1, D BIT 7, (IX+100)
BIT 1, E BIT 7, (IX-100)
BIT 1, H BIT 7, (IX+127)
BIT 1, L BIT 7, (IX-127)
BIT 1, A BIT 7, (IY)
BIT 2, B BIT 7, (IY+1)
BIT 2, C BIT 7, (IY-1)
BIT 2, D BIT 7, (IY+10)
BIT 2, E BIT 7, (IY-10)
BIT 2, H BIT 7, (IY+100)
BIT 2, L BIT 7, (IY-100)
BIT 2, A BIT 7, (IY+127)
BIT 4, B BIT 7, (IY-127)
BIT 4, C BIT 0, B
BIT 4, D BIT 0, C
BIT 4, E BIT 0, D
BIT 4, H BIT 0, E
BIT 4, L BIT 0, H
BIT 4, A BIT 0, L
BIT 0, A
BIT 3, B
BIT 3, C
BIT 3, D
BIT 3, E
BIT 3, H
BIT 3, L
BIT 3, A
BIT 7, B
BIT 7, C
BIT 7, D
BIT 7, E
BIT 7, H
BIT 7, L
BIT 7, A
CALL Z, 1 CALL Z, 1
CALL Z, 2 CALL Z, 2
CALL Z, 4 CALL Z, 4
@ -320,21 +320,6 @@ CALL 16384
CALL 32768 CALL 32768
CCF CCF
CP (HL) CP (HL)
CP B
CP C
CP D
CP E
CP H
CP L
CP A
CP 1
CP 2
CP 4
CP 8
CP 16
CP 32
CP 64
CP 128
CP (IX) CP (IX)
CP (IX+1) CP (IX+1)
CP (IX-1) CP (IX-1)
@ -353,6 +338,21 @@ CP (IY+100)
CP (IY-100) CP (IY-100)
CP (IY+127) CP (IY+127)
CP (IY-127) CP (IY-127)
CP B
CP C
CP D
CP E
CP H
CP L
CP A
CP 1
CP 2
CP 4
CP 8
CP 16
CP 32
CP 64
CP 128
CPD CPD
CPDR CPDR
CPI CPI
@ -360,7 +360,6 @@ CPIR
CPL CPL
DAA DAA
DEC (HL) DEC (HL)
DEC IX
DEC (IX) DEC (IX)
DEC (IX+1) DEC (IX+1)
DEC (IX-1) DEC (IX-1)
@ -370,7 +369,6 @@ DEC (IX+100)
DEC (IX-100) DEC (IX-100)
DEC (IX+127) DEC (IX+127)
DEC (IX-127) DEC (IX-127)
DEC IY
DEC (IY) DEC (IY)
DEC (IY+1) DEC (IY+1)
DEC (IY-1) DEC (IY-1)
@ -380,6 +378,8 @@ DEC (IY+100)
DEC (IY-100) DEC (IY-100)
DEC (IY+127) DEC (IY+127)
DEC (IY-127) DEC (IY-127)
DEC IX
DEC IY
DEC B DEC B
DEC C DEC C
DEC D DEC D
@ -433,7 +433,6 @@ IN H, (C)
IN L, (C) IN L, (C)
IN A, (C) IN A, (C)
INC (HL) INC (HL)
INC IX
INC (IX) INC (IX)
INC (IX+1) INC (IX+1)
INC (IX-1) INC (IX-1)
@ -443,7 +442,6 @@ INC (IX+100)
INC (IX-100) INC (IX-100)
INC (IX+127) INC (IX+127)
INC (IX-127) INC (IX-127)
INC IY
INC (IY) INC (IY)
INC (IY+1) INC (IY+1)
INC (IY-1) INC (IY-1)
@ -453,6 +451,8 @@ INC (IY+100)
INC (IY-100) INC (IY-100)
INC (IY+127) INC (IY+127)
INC (IY-127) INC (IY-127)
INC IX
INC IY
INC B INC B
INC C INC C
INC D INC D
@ -468,6 +468,8 @@ IND
INDR INDR
INI INI
INIR INIR
JP (IX)
JP (IY)
JP (HL) JP (HL)
JP Z, 1 JP Z, 1
JP Z, 2 JP Z, 2
@ -613,8 +615,6 @@ JP 4096
JP 8192 JP 8192
JP 16384 JP 16384
JP 32768 JP 32768
JP (IX)
JP (IY)
JR $+1 JR $+1
JR $+2 JR $+2
JR $+4 JR $+4
@ -1576,21 +1576,6 @@ LDIR
NEG NEG
NOP NOP
OR (HL) OR (HL)
OR B
OR C
OR D
OR E
OR H
OR L
OR A
OR 1
OR 2
OR 4
OR 8
OR 16
OR 32
OR 64
OR 128
OR (IX) OR (IX)
OR (IX+1) OR (IX+1)
OR (IX-1) OR (IX-1)
@ -1609,6 +1594,21 @@ OR (IY+100)
OR (IY-100) OR (IY-100)
OR (IY+127) OR (IY+127)
OR (IY-127) OR (IY-127)
OR B
OR C
OR D
OR E
OR H
OR L
OR A
OR 1
OR 2
OR 4
OR 8
OR 16
OR 32
OR 64
OR 128
OTDR OTDR
OTIR OTIR
OUT (1), A OUT (1), A
@ -1638,84 +1638,84 @@ PUSH BC
PUSH DE PUSH DE
PUSH HL PUSH HL
PUSH AF PUSH AF
RES 1, (HL) RES 0, (HL)
RES 2, (HL) RES 0, (IX)
RES 4, (HL) RES 0, (IX+1)
RES 1, (IX) RES 0, (IX-1)
RES 1, (IX+1) RES 0, (IX+10)
RES 1, (IX-1) RES 0, (IX-10)
RES 1, (IX+10) RES 0, (IX+100)
RES 1, (IX-10) RES 0, (IX-100)
RES 1, (IX+100) RES 0, (IX+127)
RES 1, (IX-100) RES 0, (IX-127)
RES 1, (IX+127) RES 0, (IY)
RES 1, (IX-127) RES 0, (IY+1)
RES 2, (IX) RES 0, (IY-1)
RES 2, (IX+1) RES 0, (IY+10)
RES 2, (IX-1) RES 0, (IY-10)
RES 2, (IX+10) RES 0, (IY+100)
RES 2, (IX-10) RES 0, (IY-100)
RES 2, (IX+100) RES 0, (IY+127)
RES 2, (IX-100) RES 0, (IY-127)
RES 2, (IX+127) RES 3, (HL)
RES 2, (IX-127) RES 3, (IX)
RES 4, (IX) RES 3, (IX+1)
RES 4, (IX+1) RES 3, (IX-1)
RES 4, (IX-1) RES 3, (IX+10)
RES 4, (IX+10) RES 3, (IX-10)
RES 4, (IX-10) RES 3, (IX+100)
RES 4, (IX+100) RES 3, (IX-100)
RES 4, (IX-100) RES 3, (IX+127)
RES 4, (IX+127) RES 3, (IX-127)
RES 4, (IX-127) RES 3, (IY)
RES 1, (IY) RES 3, (IY+1)
RES 1, (IY+1) RES 3, (IY-1)
RES 1, (IY-1) RES 3, (IY+10)
RES 1, (IY+10) RES 3, (IY-10)
RES 1, (IY-10) RES 3, (IY+100)
RES 1, (IY+100) RES 3, (IY-100)
RES 1, (IY-100) RES 3, (IY+127)
RES 1, (IY+127) RES 3, (IY-127)
RES 1, (IY-127) RES 7, (HL)
RES 2, (IY) RES 7, (IX)
RES 2, (IY+1) RES 7, (IX+1)
RES 2, (IY-1) RES 7, (IX-1)
RES 2, (IY+10) RES 7, (IX+10)
RES 2, (IY-10) RES 7, (IX-10)
RES 2, (IY+100) RES 7, (IX+100)
RES 2, (IY-100) RES 7, (IX-100)
RES 2, (IY+127) RES 7, (IX+127)
RES 2, (IY-127) RES 7, (IX-127)
RES 4, (IY) RES 7, (IY)
RES 4, (IY+1) RES 7, (IY+1)
RES 4, (IY-1) RES 7, (IY-1)
RES 4, (IY+10) RES 7, (IY+10)
RES 4, (IY-10) RES 7, (IY-10)
RES 4, (IY+100) RES 7, (IY+100)
RES 4, (IY-100) RES 7, (IY-100)
RES 4, (IY+127) RES 7, (IY+127)
RES 4, (IY-127) RES 7, (IY-127)
RES 1, B RES 0, B
RES 1, C RES 0, C
RES 1, D RES 0, D
RES 1, E RES 0, E
RES 1, H RES 0, H
RES 1, L RES 0, L
RES 1, A RES 0, A
RES 2, B RES 3, B
RES 2, C RES 3, C
RES 2, D RES 3, D
RES 2, E RES 3, E
RES 2, H RES 3, H
RES 2, L RES 3, L
RES 2, A RES 3, A
RES 4, B RES 7, B
RES 4, C RES 7, C
RES 4, D RES 7, D
RES 4, E RES 7, E
RES 4, H RES 7, H
RES 4, L RES 7, L
RES 4, A RES 7, A
RET RET
RET Z RET Z
RET NZ RET NZ
@ -1734,6 +1734,25 @@ RL E
RL H RL H
RL L RL L
RL A RL A
RL (HL)
RL (IX)
RL (IX+1)
RL (IX-1)
RL (IX+10)
RL (IX-10)
RL (IX+100)
RL (IX-100)
RL (IX+127)
RL (IX-127)
RL (IY)
RL (IY+1)
RL (IY-1)
RL (IY+10)
RL (IY-10)
RL (IY+100)
RL (IY-100)
RL (IY+127)
RL (IY-127)
RLA RLA
RLC B RLC B
RLC C RLC C
@ -1750,6 +1769,25 @@ RR E
RR H RR H
RR L RR L
RR A RR A
RR (HL)
RR (IX)
RR (IX+1)
RR (IX-1)
RR (IX+10)
RR (IX-10)
RR (IX+100)
RR (IX-100)
RR (IX+127)
RR (IX-127)
RR (IY)
RR (IY+1)
RR (IY-1)
RR (IY+10)
RR (IY-10)
RR (IY+100)
RR (IY-100)
RR (IY+127)
RR (IY-127)
RRA RRA
RRC B RRC B
RRC C RRC C
@ -1772,84 +1810,84 @@ SBC HL, DE
SBC HL, HL SBC HL, HL
SBC HL, SP SBC HL, SP
SCF SCF
SET 1, (HL) SET 0, (HL)
SET 2, (HL) SET 0, (IX)
SET 4, (HL) SET 0, (IX+1)
SET 1, (IX) SET 0, (IX-1)
SET 1, (IX+1) SET 0, (IX+10)
SET 1, (IX-1) SET 0, (IX-10)
SET 1, (IX+10) SET 0, (IX+100)
SET 1, (IX-10) SET 0, (IX-100)
SET 1, (IX+100) SET 0, (IX+127)
SET 1, (IX-100) SET 0, (IX-127)
SET 1, (IX+127) SET 0, (IY)
SET 1, (IX-127) SET 0, (IY+1)
SET 2, (IX) SET 0, (IY-1)
SET 2, (IX+1) SET 0, (IY+10)
SET 2, (IX-1) SET 0, (IY-10)
SET 2, (IX+10) SET 0, (IY+100)
SET 2, (IX-10) SET 0, (IY-100)
SET 2, (IX+100) SET 0, (IY+127)
SET 2, (IX-100) SET 0, (IY-127)
SET 2, (IX+127) SET 3, (HL)
SET 2, (IX-127) SET 3, (IX)
SET 4, (IX) SET 3, (IX+1)
SET 4, (IX+1) SET 3, (IX-1)
SET 4, (IX-1) SET 3, (IX+10)
SET 4, (IX+10) SET 3, (IX-10)
SET 4, (IX-10) SET 3, (IX+100)
SET 4, (IX+100) SET 3, (IX-100)
SET 4, (IX-100) SET 3, (IX+127)
SET 4, (IX+127) SET 3, (IX-127)
SET 4, (IX-127) SET 3, (IY)
SET 1, (IY) SET 3, (IY+1)
SET 1, (IY+1) SET 3, (IY-1)
SET 1, (IY-1) SET 3, (IY+10)
SET 1, (IY+10) SET 3, (IY-10)
SET 1, (IY-10) SET 3, (IY+100)
SET 1, (IY+100) SET 3, (IY-100)
SET 1, (IY-100) SET 3, (IY+127)
SET 1, (IY+127) SET 3, (IY-127)
SET 1, (IY-127) SET 7, (HL)
SET 2, (IY) SET 7, (IX)
SET 2, (IY+1) SET 7, (IX+1)
SET 2, (IY-1) SET 7, (IX-1)
SET 2, (IY+10) SET 7, (IX+10)
SET 2, (IY-10) SET 7, (IX-10)
SET 2, (IY+100) SET 7, (IX+100)
SET 2, (IY-100) SET 7, (IX-100)
SET 2, (IY+127) SET 7, (IX+127)
SET 2, (IY-127) SET 7, (IX-127)
SET 4, (IY) SET 7, (IY)
SET 4, (IY+1) SET 7, (IY+1)
SET 4, (IY-1) SET 7, (IY-1)
SET 4, (IY+10) SET 7, (IY+10)
SET 4, (IY-10) SET 7, (IY-10)
SET 4, (IY+100) SET 7, (IY+100)
SET 4, (IY-100) SET 7, (IY-100)
SET 4, (IY+127) SET 7, (IY+127)
SET 4, (IY-127) SET 7, (IY-127)
SET 1, B SET 0, B
SET 1, C SET 0, C
SET 1, D SET 0, D
SET 1, E SET 0, E
SET 1, H SET 0, H
SET 1, L SET 0, L
SET 1, A SET 0, A
SET 2, B SET 3, B
SET 2, C SET 3, C
SET 2, D SET 3, D
SET 2, E SET 3, E
SET 2, H SET 3, H
SET 2, L SET 3, L
SET 2, A SET 3, A
SET 4, B SET 7, B
SET 4, C SET 7, C
SET 4, D SET 7, D
SET 4, E SET 7, E
SET 4, H SET 7, H
SET 4, L SET 7, L
SET 4, A SET 7, A
SLA B SLA B
SLA C SLA C
SLA D SLA D
@ -1864,6 +1902,25 @@ SRL E
SRL H SRL H
SRL L SRL L
SRL A SRL A
SRL (HL)
SRL (IX)
SRL (IX+1)
SRL (IX-1)
SRL (IX+10)
SRL (IX-10)
SRL (IX+100)
SRL (IX-100)
SRL (IX+127)
SRL (IX-127)
SRL (IY)
SRL (IY+1)
SRL (IY-1)
SRL (IY+10)
SRL (IY-10)
SRL (IY+100)
SRL (IY-100)
SRL (IY+127)
SRL (IY-127)
SUB (HL) SUB (HL)
SUB B SUB B
SUB C SUB C

View File

@ -56,6 +56,12 @@ argGrpTbl = {
chr(0x0b): "BCDEHLA", chr(0x0b): "BCDEHLA",
} }
# whenever we encounter the "(HL)" version of these instructions, spit IX/IY
# too.
instrsWithIXY = {
'ADD', 'AND', 'BIT', 'CP', 'DEC', 'INC', 'OR', 'RES', 'RL', 'RR', 'SET',
'SRL'}
def cleanupLine(line): def cleanupLine(line):
line = line.strip() line = line.strip()
idx = line.rfind(';') idx = line.rfind(';')
@ -107,6 +113,8 @@ def genargs(argspec):
return result return result
if argspec in argspecTbl: if argspec in argspecTbl:
return [argspecTbl[argspec]] return [argspecTbl[argspec]]
if argspec == chr(0xc): # special BIT "b" group
return ['0', '3', '7']
grp = argGrpTbl[argspec] grp = argGrpTbl[argspec]
return [argspecTbl[a] for a in grp] return [argspecTbl[a] for a in grp]
@ -131,13 +139,14 @@ def main():
a2 = eval(row[2]) a2 = eval(row[2])
args1 = genargs(a1) args1 = genargs(a1)
# special case handling # special case handling
if n in instrsWithIXY and a1 == 'l':
args1 += genargs('x')
args1 += genargs('y')
if n == 'JP' and isinstance(a1, str) and a1 in 'xy': if n == 'JP' and isinstance(a1, str) and a1 in 'xy':
# we don't test the displacements for IX/IY because there can't be # we don't test the displacements for IX/IY because there can't be
# any. # any.
args1 = args1[:1] args1 = args1[:1]
if n in {'BIT', 'SET', 'RES'}:
# we only want to keep 1, 2, 4
args1 = args1[:3]
if n in {'JR', 'DJNZ'} and a1 == 'n': if n in {'JR', 'DJNZ'} and a1 == 'n':
args1 = eargs(args1) args1 = eargs(args1)
if n == 'IM': if n == 'IM':
@ -145,6 +154,9 @@ def main():
if args1: if args1:
for arg1 in args1: for arg1 in args1:
args2 = genargs(a2) args2 = genargs(a2)
if n in instrsWithIXY and a2 == 'l':
args2 += genargs('x')
args2 += genargs('y')
if args2: if args2:
if n in {'JR', 'DJNZ'} and a2 == 'n': if n in {'JR', 'DJNZ'} and a2 == 'n':
args2 = eargs(args2) args2 = eargs(args2)