zasm: add support for extended instructions

This commit is contained in:
Virgil Dupras 2019-04-20 22:37:38 -04:00
parent 70f61ec451
commit 115dc18971
3 changed files with 194 additions and 191 deletions

View File

@ -2,6 +2,8 @@
# Generate almost all possible combination for instructions from instruction # Generate almost all possible combination for instructions from instruction
# tables # tables
import sys
argspecTbl = { argspecTbl = {
'A': "A", 'A': "A",
'B': "B", 'B': "B",
@ -39,82 +41,34 @@ argGrpTbl = {
chr(0x0b): "BCDEHLA", chr(0x0b): "BCDEHLA",
} }
instrTBlPrimary = [ def cleanupLine(line):
("ADC", 'A', 'l', 0, 0x8e), line = line.strip()
("ADC", 'A', 0xb, 0, 0b10001000), idx = line.rfind(';')
("ADC", 'A', 'n', 0, 0xce ), if idx >= 0:
("ADD", 'A', 'l', 0, 0x86 ), line = line[:idx]
("ADD", 'A', 0xb, 0, 0b10000000), return line
("ADD", 'A', 'n', 0, 0xc6 ),
("ADD", 'h', 0x3, 4, 0b00001001 ), def getDbLines(fp, tblname):
("AND", 'l', 0, 0, 0xa6 ), lookingFor = f"{tblname}:"
("AND", 0xb, 0, 0, 0b10100000), line = fp.readline()
("AND", 'n', 0, 0, 0xe6 ), while line:
("CALL", 0xa, 'N', 3, 0b11000100), line = cleanupLine(line)
("CALL", 'N', 0, 0, 0xcd ), if line == lookingFor:
("CCF", 0, 0, 0, 0x3f ), break
("CP", 'l', 0, 0, 0xbe ), line = fp.readline()
("CP", 0xb, 0, 0, 0b10111000), else:
("CP", 'n', 0, 0, 0xfe ), raise Exception(f"{tblname} not found")
("CPL", 0, 0, 0, 0x2f ),
("DAA", 0, 0, 0, 0x27 ), result = []
("DI", 0, 0, 0, 0xf3 ), line = fp.readline()
("DEC", 'l', 0, 0, 0x35 ), while line:
("DEC", 0xb, 0, 3, 0b00000101), line = cleanupLine(line)
("DEC", 0x3, 0, 4, 0b00001011), if line:
("DJNZ", 'n', 0,0x80, 0x10 ), if not line.startswith('.db'):
("EI", 0, 0, 0, 0xfb ), break
("EX", 'p', 'h', 0, 0xe3 ), result.append([s.strip() for s in line[4:].split(',')])
("EX", 'a', 'f', 0, 0x08 ), line = fp.readline()
("EX", 'd', 'h', 0, 0xeb ), return result
("EXX", 0, 0, 0, 0xd9 ),
("HALT", 0, 0, 0, 0x76 ),
("IN", 'A', 'm', 0, 0xdb ),
("INC", 'l', 0, 0, 0x34 ),
("INC", 0xb, 0, 3, 0b00000100),
("INC", 0x3, 0, 4, 0b00000011),
("JP", 'l', 0, 0, 0xe9 ),
("JP", 'N', 0, 0, 0xc3 ),
("JR", 'n', 0,0x80, 0x18 ),
("JR",'C','n',0x80, 0x38 ),
("JR",'=','n',0x80, 0x30 ),
("JR",'Z','n',0x80, 0x28 ),
("JR",'z','n',0x80, 0x20 ),
("LD", 'c', 'A', 0, 0x02 ),
("LD", 'e', 'A', 0, 0x12 ),
("LD", 'A', 'c', 0, 0x0a ),
("LD", 'A', 'e', 0, 0x0a ),
("LD", 's', 'h', 0, 0x0a ),
("LD", 'l', 0xb, 0, 0b01110000),
("LD", 0xb, 'l', 3, 0b01000110),
("LD", 'l', 'n', 0, 0x36 ),
("LD", 0xb, 'n', 3, 0b00000110),
("LD", 0x3, 'N', 4, 0b00000001),
("LD", 'M', 'A', 0, 0x32 ),
("LD", 'A', 'M', 0, 0x3a ),
("LD", 'M', 'h', 0, 0x22 ),
("LD", 'h', 'M', 0, 0x2a ),
("NOP", 0, 0, 0, 0x00 ),
("OR", 'l', 0, 0, 0xb6 ),
("OR", 0xb, 0, 0, 0b10110000),
("OUT", 'm', 'A', 0, 0xd3 ),
("POP", 0x1, 0, 4, 0b11000001),
("PUSH", 0x1, 0, 4, 0b11000101),
("RET", 0xa, 0, 3, 0b11000000),
("RET", 0, 0, 0, 0xc9 ),
("RLA", 0, 0, 0, 0x17 ),
("RLCA", 0, 0, 0, 0x07 ),
("RRA", 0, 0, 0, 0x1f ),
("RRCA", 0, 0, 0, 0x0f ),
("SBC", 'A', 'l', 0, 0x9e ),
("SBC", 'A', 0xb, 0, 0b10011000),
("SCF", 0, 0, 0, 0x37 ),
("SUB", 'A', 'l', 0, 0x96 ),
("SUB", 'A', 0xb, 0, 0b10010000),
("SUB", 'n', 0, 0, 0xd6 ),
("XOR", 'l', 0, 0, 0xae ),
("XOR", 0xb, 0, 0, 0b10101000),
]
def genargs(argspec): def genargs(argspec):
if not argspec: if not argspec:
@ -134,7 +88,15 @@ def genargs(argspec):
def main(): def main():
for n, a1, a2, f, op in instrTBlPrimary: asmfile = sys.argv[1]
with open(asmfile, 'rt') as fp:
instrTbl = getDbLines(fp, 'instrTBl')
for row in instrTbl:
n = eval(row[0])
# we need to adjust for zero-char name filling
arg1index = 5 - len(n)
a1 = eval(row[arg1index])
a2 = eval(row[arg1index+1])
args1 = genargs(a1) args1 = genargs(a1)
if args1: if args1:
for arg1 in args1: for arg1 in args1:

View File

@ -5,8 +5,9 @@ set -e
TMPFILE=$(mktemp) TMPFILE=$(mktemp)
SCAS=scas SCAS=scas
ZASM=../emul/zasm ZASM=../emul/zasm
ASMFILE=../zasm.asm
./geninstrs.py | \ ./geninstrs.py $ASMFILE | \
while read line; do while read line; do
echo $line | tee "${TMPFILE}" echo $line | tee "${TMPFILE}"
EXPECTED=$($SCAS -o - "${TMPFILE}" | xxd) EXPECTED=$($SCAS -o - "${TMPFILE}" | xxd)

View File

@ -4,9 +4,9 @@
; Number of rows in the argspec table ; Number of rows in the argspec table
ARGSPEC_TBL_CNT .equ 27 ARGSPEC_TBL_CNT .equ 27
; Number of rows in the primary instructions table ; Number of rows in the primary instructions table
INSTR_TBLP_CNT .equ 74 INSTR_TBL_CNT .equ 75
; size in bytes of each row in the primary instructions table ; size in bytes of each row in the primary instructions table
INSTR_TBLP_ROWSIZE .equ 8 INSTR_TBL_ROWSIZE .equ 9
; *** Code *** ; *** Code ***
.org USER_CODE .org USER_CODE
@ -37,6 +37,16 @@ rlaX:
; Copy BC bytes from (HL) to (DE). ; Copy BC bytes from (HL) to (DE).
copy: copy:
; first, let's see if BC is zero. if it is, we have nothing to do.
; remember: 16-bit inc/dec don't modify flags. that's why we check B
; and C separately.
inc b
dec b
jr nz, .proceed
inc c
dec c
ret z ; zero? nothing to do
.proceed:
push bc push bc
push de push de
push hl push hl
@ -500,9 +510,23 @@ getUpcode:
push ix push ix
push de push de
push hl push hl
push bc
; 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.
ld ixh, d ld ixh, d
ld ixl, e ld ixl, e
; we begin by writing our "base upcode", which can be one or two bytes
ld a, (ix+7) ; first upcode
ld (curUpcode), a
ld de, curUpcode ; from this point, DE points to "where we are"
; in terms of upcode writing.
inc de ; make DE point to where we should write next.
ld a, (ix+8) ; second upcode
cp 0 ; do we have a second upcode?
jr z, .onlyOneUpcode
; we have two upcodes
ld (de), a
inc de
.onlyOneUpcode:
; now, let's see if we're dealing with a group here ; now, let's see if we're dealing with a group here
ld a, (ix+4) ; first argspec ld a, (ix+4) ; first argspec
call isGroupId call isGroupId
@ -510,49 +534,52 @@ getUpcode:
; First arg not a group. Maybe second is? ; First arg not a group. Maybe second is?
ld a, (ix+5) ; 2nd argspec ld a, (ix+5) ; 2nd argspec
call isGroupId call isGroupId
jr nz, .notgroup jr nz, .writeExtraBytes ; not a group? nothing to do. go to
; next step: write extra bytes
; Second arg is group ; Second arg is group
ld de, curArg2 ld hl, curArg2
jr .isGroup jr .isGroup
.firstArgIsGroup: .firstArgIsGroup:
ld de, curArg1 ld hl, curArg1
.isGroup: .isGroup:
; A is a group, good, now let's get its value. DE is pointing to ; A is a group, good, now let's get its value. HL is pointing to
; the argument. ; the argument. A little bit of stack gymnastic is necessary to put
ld h, a ; A into H and (HL) into A.
ld a, (de) push af
ld a, (hl)
pop hl ; from push af 2 lines above
call findInGroup ; we don't check for match, it's supposed to call findInGroup ; we don't check for match, it's supposed to
; always match. Something is very wrong if it ; always match. Something is very wrong if it
; doesn't ; doesn't
; Now, we have our arg "group value" in A. Were going to need to ; Now, we have our arg "group value" in A. Were going to need to
; displace it left by the number of steps specified in the table. ; displace it left by the number of steps specified in the table.
push bc
push af push af
ld a, (ix+6) ; displacement bit ld a, (ix+6) ; displacement bit
and a, 0xf ; we only use the lower nibble. and a, 0xf ; we only use the lower nibble.
ld b, a ld b, a
pop af pop af
call rlaX call rlaX
pop bc
; At this point, we have a properly displaced value in A. We'll want ; At this point, we have a properly displaced value in A. We'll want
; to OR it with the opcode. ; to OR it with the opcode.
or (ix+7) ; upcode ; However, we first have to verify whether this ORing takes place on
; the second upcode or the first.
; Success! bit 6, (ix+6)
jr .writeFirstOpcode jr z, .firstUpcode ; not set: first upcode
.notgroup: or (ix+8) ; second upcode
; not a group? easy as pie: we return the opcode directly. ld (curUpcode+1), a
ld a, (ix+7) ; upcode is on 8th byte jr .writeExtraBytes
.writeFirstOpcode: .firstUpcode:
; At the end, we have our final opcode in A! or (ix+7) ; first upcode
ld de, curUpcode ld (curUpcode), a
ld (de), a jr .writeExtraBytes
.writeExtraBytes:
; Good, we are probably finished here for many primary opcodes. However, ; Good, we are probably finished here for many primary opcodes. However,
; some primary opcodes take 8 or 16 bit constants as an argument and ; some primary opcodes take 8 or 16 bit constants as an argument and
; if that's the case here, we need to write it too. ; if that's the case here, we need to write it too.
; We still have our instruction row in IX. Let's revisit it. ; We still have our instruction row in IX and we have DE pointing to
; where we should write next (which could be the second or the third
; byte of curUpcode).
ld a, (ix+4) ; first argspec ld a, (ix+4) ; first argspec
ld hl, curArg1 ld hl, curArg1
call checkNOrM call checkNOrM
@ -569,9 +596,9 @@ getUpcode:
jr z, .withByte jr z, .withByte
cp 'm' cp 'm'
jr z, .withByte jr z, .withByte
; nope, no number, aright, only one opcode ; nope, no number, alright, we're finished here
ld a, 1 ld c, 1
jr .end jr .computeBytesWritten
.withByte: .withByte:
; verify that the MSB in argument is zero ; verify that the MSB in argument is zero
inc hl inc hl
@ -589,23 +616,34 @@ getUpcode:
dec (hl) dec (hl)
dec (hl) dec (hl)
.skipDecrease: .skipDecrease:
inc de
ldi ldi
ld a, 2 ld c, 2
jr .end jr .computeBytesWritten
.withWord: .withWord:
inc de
inc hl ; HL now points to LSB inc hl ; HL now points to LSB
; Clear to proceed. HL already points to our number ; Clear to proceed. HL already points to our number
ldi ; LSB written, we point to MSB now ldi ; LSB written, we point to MSB now
ldi ; MSB written ldi ; MSB written
ld a, 3 ld c, 3
jr .computeBytesWritten
.computeBytesWritten:
; At this point, everything that we needed to write in curUpcode is
; written an C is 1 if we have no extra byte, 2 if we have an extra
; byte and 3 if we have an extra word. What we need to do here is check
; if ix+8 is non-zero and increase C if it is.
ld a, (ix+8)
cp 0
jr z, .end ; no second upcode? nothing to do.
; We have 2 base upcodes
inc c
jr .end jr .end
.numberTruncated: .numberTruncated:
; problem: not zero, so value is truncated. error ; problem: not zero, so value is truncated. error
xor a xor c
.end: .end:
ld a, c
pop bc
pop hl pop hl
pop de pop de
pop ix pop ix
@ -628,13 +666,13 @@ parseLine:
ret ret
.noerror: .noerror:
push de push de
ld de, instrTBlPrimary ld de, instrTBl
ld b, INSTR_TBLP_CNT ld b, INSTR_TBL_CNT
.loop: .loop:
ld a, (de) ld a, (de)
call matchPrimaryRow call matchPrimaryRow
jr z, .match jr z, .match
ld a, INSTR_TBLP_ROWSIZE ld a, INSTR_TBL_ROWSIZE
call JUMP_ADDDE call JUMP_ADDDE
djnz .loop djnz .loop
; no match ; no match
@ -720,88 +758,90 @@ argGrpABCDEHL:
; 1 byte for arg constant ; 1 byte for arg constant
; 1 byte for 2nd arg constant ; 1 byte for 2nd arg constant
; 1 byte displacement for group arguments + flags ; 1 byte displacement for group arguments + flags
; 1 byte for upcode ; 2 bytes for upcode (2nd byte is zero if instr is one byte)
; ;
; The displacement bit is split in 2 nibbles: lower nibble is the displacement ; The displacement bit is split in 2 nibbles: lower nibble is the displacement
; value, upper nibble is for flags. There is one flag currently, on bit 7, that ; value, upper nibble is for flags. There is one flag currently, on bit 7, that
; indicates that the numerical argument is of the 'e' type and has to be ; indicates that the numerical argument is of the 'e' type and has to be
; decreased by 2 (djnz, jr). ; decreased by 2 (djnz, jr). On bit 6, it indicates that the group argument's
; value is to be placed on the second upcode rather than the first.
instrTBlPrimary: instrTBl:
.db "ADC", 0, 'A', 'l', 0, 0x8e ; ADC A, (HL) .db "ADC", 0, 'A', 'l', 0, 0x8e , 0 ; ADC A, (HL)
.db "ADC", 0, 'A', 0xb, 0, 0b10001000 ; ADC A, r .db "ADC", 0, 'A', 0xb, 0, 0b10001000 , 0 ; ADC A, r
.db "ADC", 0, 'A', 'n', 0, 0xce ; ADC A, n .db "ADC", 0, 'A', 'n', 0, 0xce , 0 ; ADC A, n
.db "ADD", 0, 'A', 'l', 0, 0x86 ; ADD A, (HL) .db "ADC", 0,'h',0x3,0x44, 0xed, 0b01001010 ; ADC HL, ss
.db "ADD", 0, 'A', 0xb, 0, 0b10000000 ; ADD A, r .db "ADD", 0, 'A', 'l', 0, 0x86 , 0 ; ADD A, (HL)
.db "ADD", 0, 'A', 'n', 0, 0xc6 ; ADD A, n .db "ADD", 0, 'A', 0xb, 0, 0b10000000 , 0 ; ADD A, r
.db "ADD", 0, 'h', 0x3, 4, 0b00001001 ; ADD HL, ss .db "ADD", 0, 'A', 'n', 0, 0xc6 , 0 ; ADD A, n
.db "AND", 0, 'l', 0, 0, 0xa6 ; AND (HL) .db "ADD", 0, 'h', 0x3, 4, 0b00001001 , 0 ; ADD HL, ss
.db "AND", 0, 0xb, 0, 0, 0b10100000 ; AND r .db "AND", 0, 'l', 0, 0, 0xa6 , 0 ; AND (HL)
.db "AND", 0, 'n', 0, 0, 0xe6 ; AND n .db "AND", 0, 0xb, 0, 0, 0b10100000 , 0 ; AND r
.db "CALL", 0xa, 'N', 3, 0b11000100 ; CALL cc, NN .db "AND", 0, 'n', 0, 0, 0xe6 , 0 ; AND n
.db "CALL", 'N', 0, 0, 0xcd ; CALL NN .db "CALL", 0xa, 'N', 3, 0b11000100 , 0 ; CALL cc, NN
.db "CCF", 0, 0, 0, 0, 0x3f ; CCF .db "CALL", 'N', 0, 0, 0xcd , 0 ; CALL NN
.db "CP",0,0, 'l', 0, 0, 0xbe ; CP (HL) .db "CCF", 0, 0, 0, 0, 0x3f , 0 ; CCF
.db "CP",0,0, 0xb, 0, 0, 0b10111000 ; CP r .db "CP",0,0, 'l', 0, 0, 0xbe , 0 ; CP (HL)
.db "CP",0,0, 'n', 0, 0, 0xfe ; CP n .db "CP",0,0, 0xb, 0, 0, 0b10111000 , 0 ; CP r
.db "CPL", 0, 0, 0, 0, 0x2f ; CPL .db "CP",0,0, 'n', 0, 0, 0xfe , 0 ; CP n
.db "DAA", 0, 0, 0, 0, 0x27 ; DAA .db "CPL", 0, 0, 0, 0, 0x2f , 0 ; CPL
.db "DI",0,0, 0, 0, 0, 0xf3 ; DI .db "DAA", 0, 0, 0, 0, 0x27 , 0 ; DAA
.db "DEC", 0, 'l', 0, 0, 0x35 ; DEC (HL) .db "DI",0,0, 0, 0, 0, 0xf3 , 0 ; DI
.db "DEC", 0, 0xb, 0, 3, 0b00000101 ; DEC r .db "DEC", 0, 'l', 0, 0, 0x35 , 0 ; DEC (HL)
.db "DEC", 0, 0x3, 0, 4, 0b00001011 ; DEC s .db "DEC", 0, 0xb, 0, 3, 0b00000101 , 0 ; DEC r
.db "DJNZ", 'n', 0,0x80, 0x10 ; DJNZ e .db "DEC", 0, 0x3, 0, 4, 0b00001011 , 0 ; DEC s
.db "EI",0,0, 0, 0, 0, 0xfb ; EI .db "DJNZ", 'n', 0,0x80, 0x10 , 0 ; DJNZ e
.db "EX",0,0, 'p', 'h', 0, 0xe3 ; EX (SP), HL .db "EI",0,0, 0, 0, 0, 0xfb , 0 ; EI
.db "EX",0,0, 'a', 'f', 0, 0x08 ; EX AF, AF' .db "EX",0,0, 'p', 'h', 0, 0xe3 , 0 ; EX (SP), HL
.db "EX",0,0, 'd', 'h', 0, 0xeb ; EX DE, HL .db "EX",0,0, 'a', 'f', 0, 0x08 , 0 ; EX AF, AF'
.db "EXX", 0, 0, 0, 0, 0xd9 ; EXX .db "EX",0,0, 'd', 'h', 0, 0xeb , 0 ; EX DE, HL
.db "HALT", 0, 0, 0, 0x76 ; HALT .db "EXX", 0, 0, 0, 0, 0xd9 , 0 ; EXX
.db "IN",0,0, 'A', 'm', 0, 0xdb ; IN A, (n) .db "HALT", 0, 0, 0, 0x76 , 0 ; HALT
.db "INC", 0, 'l', 0, 0, 0x34 ; INC (HL) .db "IN",0,0, 'A', 'm', 0, 0xdb , 0 ; IN A, (n)
.db "INC", 0, 0xb, 0, 3, 0b00000100 ; INC r .db "INC", 0, 'l', 0, 0, 0x34 , 0 ; INC (HL)
.db "INC", 0, 0x3, 0, 4, 0b00000011 ; INC s .db "INC", 0, 0xb, 0, 3, 0b00000100 , 0 ; INC r
.db "JP",0,0, 'l', 0, 0, 0xe9 ; JP (HL) .db "INC", 0, 0x3, 0, 4, 0b00000011 , 0 ; INC s
.db "JP",0,0, 'N', 0, 0, 0xc3 ; JP NN .db "JP",0,0, 'l', 0, 0, 0xe9 , 0 ; JP (HL)
.db "JR",0,0, 'n', 0,0x80, 0x18 ; JR e .db "JP",0,0, 'N', 0, 0, 0xc3 , 0 ; JP NN
.db "JR",0,0,'C','n',0x80, 0x38 ; JR C, e .db "JR",0,0, 'n', 0,0x80, 0x18 , 0 ; JR e
.db "JR",0,0,'=','n',0x80, 0x30 ; JR NC, e .db "JR",0,0,'C','n',0x80, 0x38 , 0 ; JR C, e
.db "JR",0,0,'Z','n',0x80, 0x28 ; JR Z, e .db "JR",0,0,'=','n',0x80, 0x30 , 0 ; JR NC, e
.db "JR",0,0,'z','n',0x80, 0x20 ; JR NZ, e .db "JR",0,0,'Z','n',0x80, 0x28 , 0 ; JR Z, e
.db "LD",0,0, 'c', 'A', 0, 0x02 ; LD (BC), A .db "JR",0,0,'z','n',0x80, 0x20 , 0 ; JR NZ, e
.db "LD",0,0, 'e', 'A', 0, 0x12 ; LD (DE), A .db "LD",0,0, 'c', 'A', 0, 0x02 , 0 ; LD (BC), A
.db "LD",0,0, 'A', 'c', 0, 0x0a ; LD A, (BC) .db "LD",0,0, 'e', 'A', 0, 0x12 , 0 ; LD (DE), A
.db "LD",0,0, 'A', 'e', 0, 0x1a ; LD A, (DE) .db "LD",0,0, 'A', 'c', 0, 0x0a , 0 ; LD A, (BC)
.db "LD",0,0, 's', 'h', 0, 0xf9 ; LD SP, HL .db "LD",0,0, 'A', 'e', 0, 0x1a , 0 ; LD A, (DE)
.db "LD",0,0, 'l', 0xb, 0, 0b01110000 ; LD (HL), r .db "LD",0,0, 's', 'h', 0, 0xf9 , 0 ; LD SP, HL
.db "LD",0,0, 0xb, 'l', 3, 0b01000110 ; LD r, (HL) .db "LD",0,0, 'l', 0xb, 0, 0b01110000 , 0 ; LD (HL), r
.db "LD",0,0, 'l', 'n', 0, 0x36 ; LD (HL), n .db "LD",0,0, 0xb, 'l', 3, 0b01000110 , 0 ; LD r, (HL)
.db "LD",0,0, 0xb, 'n', 3, 0b00000110 ; LD r, (HL) .db "LD",0,0, 'l', 'n', 0, 0x36 , 0 ; LD (HL), n
.db "LD",0,0, 0x3, 'N', 4, 0b00000001 ; LD dd, n .db "LD",0,0, 0xb, 'n', 3, 0b00000110 , 0 ; LD r, (HL)
.db "LD",0,0, 'M', 'A', 0, 0x32 ; LD (NN), A .db "LD",0,0, 0x3, 'N', 4, 0b00000001 , 0 ; LD dd, n
.db "LD",0,0, 'A', 'M', 0, 0x3a ; LD A, (NN) .db "LD",0,0, 'M', 'A', 0, 0x32 , 0 ; LD (NN), A
.db "LD",0,0, 'M', 'h', 0, 0x22 ; LD (NN), HL .db "LD",0,0, 'A', 'M', 0, 0x3a , 0 ; LD A, (NN)
.db "LD",0,0, 'h', 'M', 0, 0x2a ; LD HL, (NN) .db "LD",0,0, 'M', 'h', 0, 0x22 , 0 ; LD (NN), HL
.db "NOP", 0, 0, 0, 0, 0x00 ; NOP .db "LD",0,0, 'h', 'M', 0, 0x2a , 0 ; LD HL, (NN)
.db "OR",0,0, 'l', 0, 0, 0xb6 ; OR (HL) .db "NOP", 0, 0, 0, 0, 0x00 , 0 ; NOP
.db "OR",0,0, 0xb, 0, 0, 0b10110000 ; OR r .db "OR",0,0, 'l', 0, 0, 0xb6 , 0 ; OR (HL)
.db "OUT", 0, 'm', 'A', 0, 0xd3 ; OUT (n), A .db "OR",0,0, 0xb, 0, 0, 0b10110000 , 0 ; OR r
.db "POP", 0, 0x1, 0, 4, 0b11000001 ; POP qq .db "OUT", 0, 'm', 'A', 0, 0xd3 , 0 ; OUT (n), A
.db "PUSH", 0x1, 0, 4, 0b11000101 ; PUSH qq .db "POP", 0, 0x1, 0, 4, 0b11000001 , 0 ; POP qq
.db "RET", 0, 0, 0, 0, 0xc9 ; RET .db "PUSH", 0x1, 0, 4, 0b11000101 , 0 ; PUSH qq
.db "RET", 0, 0xa, 0, 3, 0b11000000 ; RET cc .db "RET", 0, 0, 0, 0, 0xc9 , 0 ; RET
.db "RLA", 0, 0, 0, 0, 0x17 ; RLA .db "RET", 0, 0xa, 0, 3, 0b11000000 , 0 ; RET cc
.db "RLCA", 0, 0, 0, 0x07 ; RLCA .db "RLA", 0, 0, 0, 0, 0x17 , 0 ; RLA
.db "RRA", 0, 0, 0, 0, 0x1f ; RRA .db "RLCA", 0, 0, 0, 0x07 , 0 ; RLCA
.db "RRCA", 0, 0, 0, 0x0f ; RRCA .db "RRA", 0, 0, 0, 0, 0x1f , 0 ; RRA
.db "SBC", 0, 'A', 'l', 0, 0x9e ; SBC A, (HL) .db "RRCA", 0, 0, 0, 0x0f , 0 ; RRCA
.db "SBC", 0, 'A', 0xb, 0, 0b10011000 ; SBC A, r .db "SBC", 0, 'A', 'l', 0, 0x9e , 0 ; SBC A, (HL)
.db "SCF", 0, 0, 0, 0, 0x37 ; SCF .db "SBC", 0, 'A', 0xb, 0, 0b10011000 , 0 ; SBC A, r
.db "SUB", 0, 'A', 'l', 0, 0x96 ; SUB A, (HL) .db "SCF", 0, 0, 0, 0, 0x37 , 0 ; SCF
.db "SUB", 0, 'A', 0xb, 0, 0b10010000 ; SUB A, r .db "SUB", 0, 'A', 'l', 0, 0x96 , 0 ; SUB A, (HL)
.db "SUB", 0, 'n', 0, 0, 0xd6 ; SUB n .db "SUB", 0, 'A', 0xb, 0, 0b10010000 , 0 ; SUB A, r
.db "XOR", 0, 'l', 0, 0, 0xae ; XOR (HL) .db "SUB", 0, 'n', 0, 0, 0xd6 , 0 ; SUB n
.db "XOR", 0, 0xb, 0, 0, 0b10101000 ; XOR r .db "XOR", 0, 'l', 0, 0, 0xae , 0 ; XOR (HL)
.db "XOR", 0, 0xb, 0, 0, 0b10101000 , 0 ; XOR r
; *** Variables *** ; *** Variables ***