mirror of
https://github.com/michaelcmartin/Ophis.git
synced 2024-11-04 11:05:12 +00:00
Test suite: new tests for basic I/O and binary transforms
This commit is contained in:
parent
6e30cc4153
commit
47be777884
@ -2,6 +2,7 @@
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
import os
|
||||
import os.path
|
||||
|
||||
pythonpath = sys.executable
|
||||
@ -10,14 +11,22 @@ ophispath = os.path.join(homepath, "..", "bin", "ophis")
|
||||
|
||||
failed = 0
|
||||
|
||||
# These are some simple routines for forwarding to Ophis. It relies
|
||||
# on the standard input/output capabilities; we'll only go around it
|
||||
# when explicitly testing the input/output file capabilities.
|
||||
|
||||
def assemble_string(asm, options=[]):
|
||||
p = subprocess.Popen([pythonpath, ophispath, "-o", "-", "-"] + options,
|
||||
|
||||
def assemble_raw(asm="", options=[]):
|
||||
p = subprocess.Popen([pythonpath, ophispath] + options,
|
||||
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
return p.communicate(asm)
|
||||
|
||||
|
||||
def assemble_string(asm, options=[]):
|
||||
return assemble_raw(asm, ["-o", "-", "-"] + options)
|
||||
|
||||
|
||||
def test_string(test_name, asm, expected, options=[]):
|
||||
(out, err) = assemble_string(asm, options)
|
||||
if out == expected:
|
||||
@ -41,8 +50,13 @@ def test_file(test_name, fname, ename, options=[]):
|
||||
test_string(test_name, asm, expected, options)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "Using Python interpreter:", pythonpath
|
||||
# And now, the actual test suites. First, the most basic techniques
|
||||
# are tested - these are the ones the test harness *itself* depends
|
||||
# on, then we start running through the features.
|
||||
|
||||
def test_basic():
|
||||
print
|
||||
print "==== BASIC OPERATION ===="
|
||||
test_string('Basic Ophis operation', '.byte "Hello, world!", 10',
|
||||
'Hello, world!\n')
|
||||
if failed == 0:
|
||||
@ -51,6 +65,7 @@ if __name__ == '__main__':
|
||||
test_file('Undocumented instructions', 'test6510.oph', 'test6510.bin',
|
||||
['-u'])
|
||||
test_file('65c02 extensions', 'test65c02.oph', 'test65c02.bin', ['-c'])
|
||||
test_file('Wide instructions', 'testwide.oph', 'testwide.bin', ['-c'])
|
||||
test_file('Branch restrictions (6502)', 'longbranch.oph', None,
|
||||
['--no-branch-extend'])
|
||||
test_file('Branch restrictions (65c02)', 'branch_c02.oph', None,
|
||||
@ -64,7 +79,143 @@ if __name__ == '__main__':
|
||||
test_file('Branch extension, correct code (65c02)',
|
||||
'branch_c02_ref.oph', 'branch_c02.bin', ['-c'])
|
||||
|
||||
if failed > 0:
|
||||
print "Total test case failures: %d" % failed
|
||||
|
||||
def test_outfile():
|
||||
global failed
|
||||
print "\n==== INPUT AND OUTPUT ===="
|
||||
if os.path.exists("ophis.bin"):
|
||||
print "TEST SUITE FAILED: unclean test environment (ophis.bin exists)"
|
||||
failed += 1
|
||||
return
|
||||
elif os.path.exists("custom.bin"):
|
||||
print "TEST SUITE FAILED: unclean test environment (custom.bin exists)"
|
||||
failed += 1
|
||||
return
|
||||
|
||||
# Test 1: Defaults
|
||||
try:
|
||||
assemble_raw('.byte "Hello, world!", 10', ['-'])
|
||||
f = open('ophis.bin', 'rb')
|
||||
if f.read() != 'Hello, world!\n':
|
||||
print "Default output filename: FAILED (bad output)"
|
||||
failed += 1
|
||||
else:
|
||||
print "Default output filename: SUCCESS"
|
||||
f.close()
|
||||
os.unlink('ophis.bin')
|
||||
except:
|
||||
print "Default output filename: FAILED (exception)"
|
||||
failed += 1
|
||||
|
||||
# Test 2: Command line override
|
||||
try:
|
||||
assemble_raw('.byte "Hello, world!", 10', ['-', '-o', 'custom.bin'])
|
||||
f = open('custom.bin', 'rb')
|
||||
if f.read() != 'Hello, world!\n':
|
||||
print "Commandline output filename: FAILED (bad output)"
|
||||
failed += 1
|
||||
else:
|
||||
print "Commandline output filename: SUCCESS"
|
||||
f.close()
|
||||
os.unlink('custom.bin')
|
||||
except:
|
||||
print "Commandline output filename: FAILED (exception)"
|
||||
failed += 1
|
||||
|
||||
# Test 3: Pragma override
|
||||
try:
|
||||
assemble_raw('.outfile "custom.bin"\n.byte "Hello, world!", 10', ['-'])
|
||||
f = open('custom.bin', 'rb')
|
||||
if f.read() != 'Hello, world!\n':
|
||||
print "Commandline output filename: FAILED (bad output)"
|
||||
failed += 1
|
||||
else:
|
||||
print "Commandline output filename: SUCCESS"
|
||||
f.close()
|
||||
os.unlink('custom.bin')
|
||||
except:
|
||||
print "Commandline output filename: FAILED (exception)"
|
||||
failed += 1
|
||||
|
||||
# Test 4: Command line override of .outfile
|
||||
try:
|
||||
assemble_raw('.outfile "custom2.bin"\n'
|
||||
'.byte "Hello, world!", 10', ['-', '-o', 'custom.bin'])
|
||||
f = open('custom.bin', 'rb')
|
||||
if f.read() != 'Hello, world!\n':
|
||||
print "Commandline override of pragma: FAILED (bad output)"
|
||||
failed += 1
|
||||
else:
|
||||
print "Commandline override of pragma: SUCCESS"
|
||||
f.close()
|
||||
os.unlink('custom.bin')
|
||||
except:
|
||||
print "Commandline override of pragma: FAILED (exception)"
|
||||
failed += 1
|
||||
|
||||
# Test 5: Pragma repetition priority
|
||||
try:
|
||||
assemble_raw('.outfile "custom.bin"\n'
|
||||
'.outfile "custom2.bin"\n'
|
||||
'.byte "Hello, world!", 10', ['-'])
|
||||
f = open('custom.bin', 'rb')
|
||||
if f.read() != 'Hello, world!\n':
|
||||
print "Pragma repetition: FAILED (bad output)"
|
||||
failed += 1
|
||||
else:
|
||||
print "Pragma repetition: SUCCESS"
|
||||
f.close()
|
||||
os.unlink('custom.bin')
|
||||
except:
|
||||
print "Pragma repetition: FAILED (exception)"
|
||||
failed += 1
|
||||
|
||||
# Test 6: multiple input files
|
||||
try:
|
||||
out = assemble_raw('', ['-o', '-', '-u',
|
||||
os.path.join(homepath, "testbase.oph"),
|
||||
os.path.join(homepath, "test6510.oph")])[0]
|
||||
f = open(os.path.join(homepath, "testbase.bin"), 'rb')
|
||||
s = f.read()
|
||||
f.close()
|
||||
f = open(os.path.join(homepath, "test6510.bin"), 'rb')
|
||||
s += f.read()
|
||||
f.close()
|
||||
if out != s:
|
||||
print "Multiple input files: FAILED (bad output)"
|
||||
failed += 1
|
||||
else:
|
||||
print "Multiple input files: SUCCESS"
|
||||
except:
|
||||
print "Multiple input files: FAILED (exception)"
|
||||
failed += 1
|
||||
|
||||
|
||||
def test_transforms():
|
||||
print "\n==== BINARY TRANSFORM PASSES ===="
|
||||
print "Simple zero page selection: SUCCESS (covered in basic tests)"
|
||||
test_string('Chained collapse', '.org $fa \n lda + \n lda ^ \n * rts \n',
|
||||
'\xa5\xfe\xa5\xfc\x60')
|
||||
test_string('Reversible collapse', '.org $fb \n bne ^+200 \n lda ^ \n',
|
||||
'\xf0\x03\x4c\xc5\x01\xad\x00\x01')
|
||||
|
||||
|
||||
def test_systematic():
|
||||
test_outfile()
|
||||
test_transforms()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "Using Python interpreter:", pythonpath
|
||||
|
||||
test_basic()
|
||||
|
||||
if failed == 0:
|
||||
test_systematic()
|
||||
else:
|
||||
print "All test cases succeeded"
|
||||
print "\nBasic test cases failed, aborting test."
|
||||
|
||||
if failed > 0:
|
||||
print "\nTotal test case failures: %d" % failed
|
||||
else:
|
||||
print "\nAll test cases succeeded"
|
||||
|
BIN
tests/testwide.bin
Normal file
BIN
tests/testwide.bin
Normal file
Binary file not shown.
61
tests/testwide.oph
Normal file
61
tests/testwide.oph
Normal file
@ -0,0 +1,61 @@
|
||||
; Test file for 'wide' 65(c)02 opcode compliance
|
||||
|
||||
; This odd little source file uses every absolute addressing mode of
|
||||
; every opcode, and uses the opcode itself as the argument to each
|
||||
; instruction. The resulting binary's bytes are thus in strictly
|
||||
; increasing numerical order. Since this uses wide instructions, they
|
||||
; should be separated by zeroes.
|
||||
|
||||
; This test file also uses 65c02 extensions and will require the -c
|
||||
; options to Ophis.
|
||||
|
||||
|
||||
TSB.W $0C
|
||||
ORA.W $0D
|
||||
ASL.W $0E
|
||||
ORA.W $19, Y
|
||||
TRB.W $1C
|
||||
ORA.W $1D, X
|
||||
ASL.W $1E, X
|
||||
BIT.W $2C
|
||||
AND.W $2D
|
||||
ROL.W $2E
|
||||
AND.W $39, Y
|
||||
AND.W $3D, X
|
||||
ROL.W $3E, X
|
||||
EOR.W $4D
|
||||
LSR.W $4E
|
||||
EOR.W $59, Y
|
||||
EOR.W $5D, X
|
||||
LSR.W $5E, X
|
||||
ADC.W $6D
|
||||
ROR.W $6E
|
||||
ADC.W $79, Y
|
||||
ADC.W $7D, X
|
||||
ROR.W $7E, X
|
||||
STY.W $8C
|
||||
STA.W $8D
|
||||
STX.W $8E
|
||||
STA.W $99, Y
|
||||
STZ.W $9C
|
||||
STA.W $9D, X
|
||||
STZ.W $9E, X
|
||||
LDY.W $AC
|
||||
LDA.W $AD
|
||||
LDX.W $AE
|
||||
LDA.W $B9,Y
|
||||
LDY.W $BC, X
|
||||
LDA.W $BD, X
|
||||
LDX.W $BE, Y
|
||||
CPY.W $CC
|
||||
CMP.W $CD
|
||||
DEC.W $CE
|
||||
CMP.W $D9, Y
|
||||
CMP.W $DD, X
|
||||
DEC.W $DE, X
|
||||
CPX.W $EC
|
||||
SBC.W $ED
|
||||
INC.W $EE
|
||||
SBC.W $F9, Y
|
||||
SBC.W $FD, X
|
||||
INC.W $FE, X
|
Loading…
Reference in New Issue
Block a user