mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-30 20:28:05 +11:00
zasm: add automated tests and fix a bunch of bugs
A python script generates all possibilities for all supported instructions and compare zasm output with scas. After having fixed a couple of bugs, all tests pass!
This commit is contained in:
parent
8ce528c752
commit
f6dddaa380
152
apps/zasm/tests/geninstrs.py
Executable file
152
apps/zasm/tests/geninstrs.py
Executable file
@ -0,0 +1,152 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# Generate almost all possible combination for instructions from instruction
|
||||||
|
# tables
|
||||||
|
|
||||||
|
argspecTbl = {
|
||||||
|
'A': "A",
|
||||||
|
'B': "B",
|
||||||
|
'C': "C",
|
||||||
|
'D': "D",
|
||||||
|
'E': "E",
|
||||||
|
'H': "H",
|
||||||
|
'L': "L",
|
||||||
|
'h': "HL",
|
||||||
|
'l': "(HL)",
|
||||||
|
'd': "DE",
|
||||||
|
'e': "(DE)",
|
||||||
|
'b': "BC",
|
||||||
|
'c': "(BC)",
|
||||||
|
'a': "AF",
|
||||||
|
'f': "AF'",
|
||||||
|
'x': "(IX)",
|
||||||
|
'y': "(IY)",
|
||||||
|
's': "SP",
|
||||||
|
'p': "(SP)",
|
||||||
|
'Z': "Z",
|
||||||
|
'z': "NZ",
|
||||||
|
'=': "NC",
|
||||||
|
'+': "P",
|
||||||
|
'-': "M",
|
||||||
|
'1': "PO",
|
||||||
|
'2': "PE",
|
||||||
|
}
|
||||||
|
|
||||||
|
argGrpTbl = {
|
||||||
|
chr(0x01): "bdha",
|
||||||
|
chr(0x02): "ZzC=",
|
||||||
|
chr(0x03): "bdhs",
|
||||||
|
chr(0x0a): "ZzC=+-12",
|
||||||
|
chr(0x0b): "BCDEHLA",
|
||||||
|
}
|
||||||
|
|
||||||
|
instrTBlPrimary = [
|
||||||
|
("ADC", 'A', 'l', 0, 0x8e),
|
||||||
|
("ADC", 'A', 0xb, 0, 0b10001000),
|
||||||
|
("ADC", 'A', 'n', 0, 0xce ),
|
||||||
|
("ADD", 'A', 'l', 0, 0x86 ),
|
||||||
|
("ADD", 'A', 0xb, 0, 0b10000000),
|
||||||
|
("ADD", 'A', 'n', 0, 0xc6 ),
|
||||||
|
("ADD", 'h', 0x3, 4, 0b00001001 ),
|
||||||
|
("AND", 'l', 0, 0, 0xa6 ),
|
||||||
|
("AND", 0xb, 0, 0, 0b10100000),
|
||||||
|
("AND", 'n', 0, 0, 0xe6 ),
|
||||||
|
("CALL", 0xa, 'N', 3, 0b11000100),
|
||||||
|
("CALL", 'N', 0, 0, 0xcd ),
|
||||||
|
("CCF", 0, 0, 0, 0x3f ),
|
||||||
|
("CP", 'l', 0, 0, 0xbe ),
|
||||||
|
("CP", 0xb, 0, 0, 0b10111000),
|
||||||
|
("CP", 'n', 0, 0, 0xfe ),
|
||||||
|
("CPL", 0, 0, 0, 0x2f ),
|
||||||
|
("DAA", 0, 0, 0, 0x27 ),
|
||||||
|
("DI", 0, 0, 0, 0xf3 ),
|
||||||
|
("DEC", 'l', 0, 0, 0x35 ),
|
||||||
|
("DEC", 0xb, 0, 3, 0b00000101),
|
||||||
|
("DEC", 0x3, 0, 4, 0b00001011),
|
||||||
|
("DJNZ", 'n', 0,0x80, 0x10 ),
|
||||||
|
("EI", 0, 0, 0, 0xfb ),
|
||||||
|
("EX", 'p', 'h', 0, 0xe3 ),
|
||||||
|
("EX", 'a', 'f', 0, 0x08 ),
|
||||||
|
("EX", 'd', 'h', 0, 0xeb ),
|
||||||
|
("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):
|
||||||
|
if not argspec:
|
||||||
|
return ''
|
||||||
|
if not isinstance(argspec, str):
|
||||||
|
argspec = chr(argspec)
|
||||||
|
if argspec in 'nmNM':
|
||||||
|
bits = 16 if argspec in 'NM' else 8
|
||||||
|
nbs = [str(1 << i) for i in range(bits)]
|
||||||
|
if argspec in 'mM':
|
||||||
|
nbs = [f"({n})" for n in nbs]
|
||||||
|
return nbs
|
||||||
|
if argspec in argspecTbl:
|
||||||
|
return [argspecTbl[argspec]]
|
||||||
|
grp = argGrpTbl[argspec]
|
||||||
|
return [argspecTbl[a] for a in grp]
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
for n, a1, a2, f, op in instrTBlPrimary:
|
||||||
|
args1 = genargs(a1)
|
||||||
|
if args1:
|
||||||
|
for arg1 in args1:
|
||||||
|
args2 = genargs(a2)
|
||||||
|
if args2:
|
||||||
|
for arg2 in args2:
|
||||||
|
print(f"{n} {arg1}, {arg2}")
|
||||||
|
else:
|
||||||
|
print(f"{n} {arg1}")
|
||||||
|
else:
|
||||||
|
print(n)
|
||||||
|
pass
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
23
apps/zasm/tests/runtests.sh
Executable file
23
apps/zasm/tests/runtests.sh
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
TMPFILE=$(mktemp)
|
||||||
|
SCAS=scas
|
||||||
|
ZASM=../emul/zasm
|
||||||
|
|
||||||
|
./geninstrs.py | \
|
||||||
|
while read line; do
|
||||||
|
echo $line | tee "${TMPFILE}"
|
||||||
|
EXPECTED=$($SCAS -o - "${TMPFILE}" | xxd)
|
||||||
|
ACTUAL=$(echo $line | $ZASM | xxd)
|
||||||
|
if [ "$ACTUAL" == "$EXPECTED" ]; then
|
||||||
|
echo ok
|
||||||
|
else
|
||||||
|
echo actual
|
||||||
|
echo $ACTUAL
|
||||||
|
echo expected
|
||||||
|
echo $EXPECTED
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
@ -223,7 +223,7 @@ toWord:
|
|||||||
readArg:
|
readArg:
|
||||||
push de
|
push de
|
||||||
ld de, tmpBuf
|
ld de, tmpBuf
|
||||||
ld a, 6
|
ld a, 8
|
||||||
call readWord
|
call readWord
|
||||||
push hl
|
push hl
|
||||||
ld hl, tmpBuf
|
ld hl, tmpBuf
|
||||||
@ -363,6 +363,7 @@ findInGroup:
|
|||||||
jr z, .specialGroupCC
|
jr z, .specialGroupCC
|
||||||
cp 0xb
|
cp 0xb
|
||||||
jr z, .specialGroupABCDEHL
|
jr z, .specialGroupABCDEHL
|
||||||
|
jr nc, .notfound ; > 0xb? not a group
|
||||||
pop af
|
pop af
|
||||||
; regular group
|
; regular group
|
||||||
push de
|
push de
|
||||||
@ -660,7 +661,8 @@ argspecTbl:
|
|||||||
; we also need argspecs for the condition flags
|
; we also need argspecs for the condition flags
|
||||||
.db 'Z', "Z", 0, 0, 0
|
.db 'Z', "Z", 0, 0, 0
|
||||||
.db 'z', "NZ", 0, 0
|
.db 'z', "NZ", 0, 0
|
||||||
.db '^', "C", 0, 0, 0
|
; C is in conflict with the C register. The situation is ambiguous, but
|
||||||
|
; doesn't cause actual problems.
|
||||||
.db '=', "NC", 0, 0
|
.db '=', "NC", 0, 0
|
||||||
.db '+', "P", 0, 0, 0
|
.db '+', "P", 0, 0, 0
|
||||||
.db '-', "M", 0, 0, 0
|
.db '-', "M", 0, 0, 0
|
||||||
@ -682,11 +684,11 @@ argspecTbl:
|
|||||||
; The table below is in order, starting with group 0x01
|
; The table below is in order, starting with group 0x01
|
||||||
argGrpTbl:
|
argGrpTbl:
|
||||||
.db "bdha" ; 0x01
|
.db "bdha" ; 0x01
|
||||||
.db "Zz^=" ; 0x02
|
.db "ZzC=" ; 0x02
|
||||||
.db "bdhs" ; 0x03
|
.db "bdhs" ; 0x03
|
||||||
|
|
||||||
argGrpCC:
|
argGrpCC:
|
||||||
.db "Zz^=+-12" ; 0xa
|
.db "zZ=C12+-" ; 0xa
|
||||||
argGrpABCDEHL:
|
argGrpABCDEHL:
|
||||||
.db "BCDEHL_A" ; 0xb
|
.db "BCDEHL_A" ; 0xb
|
||||||
|
|
||||||
@ -705,15 +707,15 @@ argGrpABCDEHL:
|
|||||||
; decreased by 2 (djnz, jr).
|
; decreased by 2 (djnz, jr).
|
||||||
|
|
||||||
instrTBlPrimary:
|
instrTBlPrimary:
|
||||||
.db "ADC", 0, 'A', 'h', 0, 0x8e ; ADC A, HL
|
.db "ADC", 0, 'A', 'l', 0, 0x8e ; ADC A, (HL)
|
||||||
.db "ADC", 0, 'A', 0xb, 0, 0b10001000 ; ADC A, r
|
.db "ADC", 0, 'A', 0xb, 0, 0b10001000 ; ADC A, r
|
||||||
.db "ADC", 0, 'A', 'n', 0, 0xce ; ADC A, n
|
.db "ADC", 0, 'A', 'n', 0, 0xce ; ADC A, n
|
||||||
.db "ADD", 0, 'A', 'h', 0, 0x86 ; ADD A, HL
|
.db "ADD", 0, 'A', 'l', 0, 0x86 ; ADD A, (HL)
|
||||||
.db "ADD", 0, 'A', 0xb, 0, 0b10000000 ; ADD A, r
|
.db "ADD", 0, 'A', 0xb, 0, 0b10000000 ; ADD A, r
|
||||||
.db "ADD", 0, 'A', 'n', 0, 0xc6 ; ADD A, n
|
.db "ADD", 0, 'A', 'n', 0, 0xc6 ; ADD A, n
|
||||||
.db "ADD", 0, 'h', 0x3, 4, 0b00001001 ; ADD HL, ss
|
.db "ADD", 0, 'h', 0x3, 4, 0b00001001 ; ADD HL, ss
|
||||||
.db "AND", 0, 'l', 0, 0, 0xa6 ; AND (HL)
|
.db "AND", 0, 'l', 0, 0, 0xa6 ; AND (HL)
|
||||||
.db "AND", 0, 0xa, 0, 0, 0b10100000 ; AND r
|
.db "AND", 0, 0xb, 0, 0, 0b10100000 ; AND r
|
||||||
.db "AND", 0, 'n', 0, 0, 0xe6 ; AND n
|
.db "AND", 0, 'n', 0, 0, 0xe6 ; AND n
|
||||||
.db "CALL", 0xa, 'N', 3, 0b11000100 ; CALL cc, NN
|
.db "CALL", 0xa, 'N', 3, 0b11000100 ; CALL cc, NN
|
||||||
.db "CALL", 'N', 0, 0, 0xcd ; CALL NN
|
.db "CALL", 'N', 0, 0, 0xcd ; CALL NN
|
||||||
@ -741,15 +743,15 @@ instrTBlPrimary:
|
|||||||
.db "JP",0,0, 'l', 0, 0, 0xe9 ; JP (HL)
|
.db "JP",0,0, 'l', 0, 0, 0xe9 ; JP (HL)
|
||||||
.db "JP",0,0, 'N', 0, 0, 0xc3 ; JP NN
|
.db "JP",0,0, 'N', 0, 0, 0xc3 ; JP NN
|
||||||
.db "JR",0,0, 'n', 0,0x80, 0x18 ; JR e
|
.db "JR",0,0, 'n', 0,0x80, 0x18 ; JR e
|
||||||
.db "JR",0,0,'^','n',0x80, 0x38 ; JR C, e
|
.db "JR",0,0,'C','n',0x80, 0x38 ; JR C, e
|
||||||
.db "JR",0,0,'=','n',0x80, 0x30 ; JR NC, e
|
.db "JR",0,0,'=','n',0x80, 0x30 ; JR NC, e
|
||||||
.db "JR",0,0,'Z','n',0x80, 0x28 ; JR Z, e
|
.db "JR",0,0,'Z','n',0x80, 0x28 ; JR Z, e
|
||||||
.db "JR",0,0,'z','n',0x80, 0x20 ; JR NZ, e
|
.db "JR",0,0,'z','n',0x80, 0x20 ; JR NZ, e
|
||||||
.db "LD",0,0, 'c', 'A', 0, 0x02 ; LD (BC), A
|
.db "LD",0,0, 'c', 'A', 0, 0x02 ; LD (BC), A
|
||||||
.db "LD",0,0, 'e', 'A', 0, 0x12 ; LD (DE), A
|
.db "LD",0,0, 'e', 'A', 0, 0x12 ; LD (DE), A
|
||||||
.db "LD",0,0, 'A', 'c', 0, 0x0a ; LD A, (BC)
|
.db "LD",0,0, 'A', 'c', 0, 0x0a ; LD A, (BC)
|
||||||
.db "LD",0,0, 'A', 'e', 0, 0x0a ; LD A, (DE)
|
.db "LD",0,0, 'A', 'e', 0, 0x1a ; LD A, (DE)
|
||||||
.db "LD",0,0, 's', 'h', 0, 0x0a ; LD SP, HL
|
.db "LD",0,0, 's', 'h', 0, 0xf9 ; LD SP, HL
|
||||||
.db "LD",0,0, 'l', 0xb, 0, 0b01110000 ; LD (HL), r
|
.db "LD",0,0, 'l', 0xb, 0, 0b01110000 ; LD (HL), r
|
||||||
.db "LD",0,0, 0xb, 'l', 3, 0b01000110 ; LD r, (HL)
|
.db "LD",0,0, 0xb, 'l', 3, 0b01000110 ; LD r, (HL)
|
||||||
.db "LD",0,0, 'l', 'n', 0, 0x36 ; LD (HL), n
|
.db "LD",0,0, 'l', 'n', 0, 0x36 ; LD (HL), n
|
||||||
@ -765,16 +767,16 @@ instrTBlPrimary:
|
|||||||
.db "OUT", 0, 'm', 'A', 0, 0xd3 ; OUT (n), A
|
.db "OUT", 0, 'm', 'A', 0, 0xd3 ; OUT (n), A
|
||||||
.db "POP", 0, 0x1, 0, 4, 0b11000001 ; POP qq
|
.db "POP", 0, 0x1, 0, 4, 0b11000001 ; POP qq
|
||||||
.db "PUSH", 0x1, 0, 4, 0b11000101 ; PUSH qq
|
.db "PUSH", 0x1, 0, 4, 0b11000101 ; PUSH qq
|
||||||
.db "RET", 0, 0xa, 0, 3, 0b11000000 ; RET cc
|
|
||||||
.db "RET", 0, 0, 0, 0, 0xc9 ; RET
|
.db "RET", 0, 0, 0, 0, 0xc9 ; RET
|
||||||
|
.db "RET", 0, 0xa, 0, 3, 0b11000000 ; RET cc
|
||||||
.db "RLA", 0, 0, 0, 0, 0x17 ; RLA
|
.db "RLA", 0, 0, 0, 0, 0x17 ; RLA
|
||||||
.db "RLCA", 0, 0, 0, 0x07 ; RLCA
|
.db "RLCA", 0, 0, 0, 0x07 ; RLCA
|
||||||
.db "RRA", 0, 0, 0, 0, 0x1f ; RRA
|
.db "RRA", 0, 0, 0, 0, 0x1f ; RRA
|
||||||
.db "RRCA", 0, 0, 0, 0x0f ; RRCA
|
.db "RRCA", 0, 0, 0, 0x0f ; RRCA
|
||||||
.db "SBC", 0, 'A', 'h', 0, 0x9e ; SBC A, HL
|
.db "SBC", 0, 'A', 'l', 0, 0x9e ; SBC A, (HL)
|
||||||
.db "SBC", 0, 'A', 0xb, 0, 0b10011000 ; SBC A, r
|
.db "SBC", 0, 'A', 0xb, 0, 0b10011000 ; SBC A, r
|
||||||
.db "SCF", 0, 0, 0, 0, 0x37 ; SCF
|
.db "SCF", 0, 0, 0, 0, 0x37 ; SCF
|
||||||
.db "SUB", 0, 'A', 'h', 0, 0x96 ; SUB A, HL
|
.db "SUB", 0, 'A', 'l', 0, 0x96 ; SUB A, (HL)
|
||||||
.db "SUB", 0, 'A', 0xb, 0, 0b10010000 ; SUB A, r
|
.db "SUB", 0, 'A', 0xb, 0, 0b10010000 ; SUB A, r
|
||||||
.db "SUB", 0, 'n', 0, 0, 0xd6 ; SUB n
|
.db "SUB", 0, 'n', 0, 0, 0xd6 ; SUB n
|
||||||
.db "XOR", 0, 'l', 0, 0, 0xae ; XOR (HL)
|
.db "XOR", 0, 'l', 0, 0, 0xae ; XOR (HL)
|
||||||
|
Loading…
Reference in New Issue
Block a user