mirror of
https://github.com/edmccard/twoapple-reboot.git
synced 2024-06-17 14:29:27 +00:00
Improve test runner.
This commit is contained in:
parent
71f7a46e21
commit
ed8dc37bb4
|
@ -16,6 +16,15 @@ Build by running `make` in the `src` directory; if the dependencies aren't insta
|
||||||
make GTKD=/path/to/gtkd DERELICT=/path/to/Derelict2
|
make GTKD=/path/to/gtkd DERELICT=/path/to/Derelict2
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
There are tests for the 6502/65C02 emulation:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd test
|
||||||
|
rdmd runtests.d --help
|
||||||
|
```
|
||||||
|
|
||||||
### Use
|
### Use
|
||||||
For now, see README.orig
|
For now, see README.orig
|
||||||
|
|
||||||
|
|
71
test/base.d
71
test/base.d
|
@ -1,10 +1,11 @@
|
||||||
module test.base;
|
module test.base;
|
||||||
|
|
||||||
|
|
||||||
import std.algorithm, std.array, std.conv, std.exception, std.stdio,
|
import std.algorithm, std.array, std.conv, std.exception, std.getopt,
|
||||||
std.string;
|
std.stdio, std.string;
|
||||||
|
|
||||||
import test.cpu, test.opcodes;
|
import test.cpu, test.opcodes;
|
||||||
|
import cpu.data_d6502;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3334,3 +3335,69 @@ void test_opcode_timing(T)(ubyte opcode, busreport report)
|
||||||
auto run = connect(setup, run_timing_test!T(expected, report));
|
auto run = connect(setup, run_timing_test!T(expected, report));
|
||||||
run.run(opcode);
|
run.run(opcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
version(Strict)
|
||||||
|
enum testStrict = true;
|
||||||
|
else
|
||||||
|
enum testStrict = false;
|
||||||
|
version(Cumulative)
|
||||||
|
enum testCumulative = true;
|
||||||
|
else
|
||||||
|
enum testCumulative = false;
|
||||||
|
|
||||||
|
|
||||||
|
struct CheckOptions
|
||||||
|
{
|
||||||
|
enum Addr
|
||||||
|
{
|
||||||
|
IMP, IMM, ZP, ZPX, ZPY, IZX, IZY, ABS, ABX, ABY, IND, REL,
|
||||||
|
ZPI, ABI, NP1, NP8, KIL
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] opcodes;
|
||||||
|
ubyte[] codes6502;
|
||||||
|
ubyte[] codes65C02;
|
||||||
|
Addr[] addr;
|
||||||
|
|
||||||
|
this(string[] args)
|
||||||
|
{
|
||||||
|
getopt(args, "op", &opcodes, "addr", &addr);
|
||||||
|
foreach (op; opcodes)
|
||||||
|
{
|
||||||
|
if (op.startsWith("0x") || op.startsWith("0X"))
|
||||||
|
op = op[2..$];
|
||||||
|
if (isNumeric(op))
|
||||||
|
{
|
||||||
|
int code = to!int(op, 16);
|
||||||
|
if (code >= 0x00 && code <= 0xFF)
|
||||||
|
{
|
||||||
|
codes6502 ~= [cast(ubyte)code];
|
||||||
|
codes65C02 ~= [cast(ubyte)code];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (code, name; OP_NAMES_6502)
|
||||||
|
if (name == op) codes6502 ~= [cast(ubyte)code];
|
||||||
|
foreach (code, name; OP_NAMES_65C02)
|
||||||
|
if (name == op) codes65C02 ~= [cast(ubyte)code];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (a; addr)
|
||||||
|
{
|
||||||
|
foreach (code, mode; ADDR_MODES_6502)
|
||||||
|
if (a == mode) codes6502 ~= [cast(ubyte)code];
|
||||||
|
foreach (code, mode; ADDR_MODES_65C02)
|
||||||
|
if (a == mode) codes65C02 ~= [cast(ubyte)code];
|
||||||
|
}
|
||||||
|
if (opcodes.empty && addr.empty)
|
||||||
|
{
|
||||||
|
codes6502 = codes65C02 = new ubyte[256];
|
||||||
|
foreach (code; 0..256)
|
||||||
|
{
|
||||||
|
codes6502[code] = cast(ubyte)code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
142
test/runtests.d
Normal file
142
test/runtests.d
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
import std.array, std.exception, std.getopt, std.process, std.stdio,
|
||||||
|
std.traits;
|
||||||
|
|
||||||
|
|
||||||
|
enum OpDefs
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Delegates = 1,
|
||||||
|
Functions = 2,
|
||||||
|
Switch = 4,
|
||||||
|
NestedSwitch = 8,
|
||||||
|
All = 15
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Tests
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Func = 1,
|
||||||
|
Bus = 2,
|
||||||
|
Dec = 4,
|
||||||
|
All = 7
|
||||||
|
}
|
||||||
|
|
||||||
|
string[OpDefs] defStrings;
|
||||||
|
string[Tests] fNames;
|
||||||
|
|
||||||
|
static this()
|
||||||
|
{
|
||||||
|
fNames = [
|
||||||
|
Tests.Func:" test_func.d ",
|
||||||
|
Tests.Bus:" test_bus.d ",
|
||||||
|
Tests.Dec:" test_decimal.d "
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
version(DigitalMars)
|
||||||
|
{
|
||||||
|
static this()
|
||||||
|
{
|
||||||
|
defStrings = [
|
||||||
|
OpDefs.Delegates:" -version=OpDelegates",
|
||||||
|
OpDefs.Functions:" -version=OpFunctions",
|
||||||
|
OpDefs.Switch:" -version=OpSwitch",
|
||||||
|
OpDefs.NestedSwitch:" -version=OpNestedSwitch"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
string[] stStrings = [" ", " -version=Strict"];
|
||||||
|
string[] cmStrings = [" ", " -version=Cumulative"];
|
||||||
|
}
|
||||||
|
else version(GNU)
|
||||||
|
{
|
||||||
|
static assert(false, "TODO: add support for GDC.");
|
||||||
|
}
|
||||||
|
else version(LDC)
|
||||||
|
{
|
||||||
|
static assert(false, "TODO: add support for LDC.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
static assert(false, "Unknown compiler.");
|
||||||
|
|
||||||
|
|
||||||
|
OpDefs opdefs;
|
||||||
|
bool strict, cumulative;
|
||||||
|
Tests tests;
|
||||||
|
bool help;
|
||||||
|
|
||||||
|
OpDefs[] deflist;
|
||||||
|
Tests[] testlist;
|
||||||
|
|
||||||
|
void main(string[] args)
|
||||||
|
{
|
||||||
|
if (args.length == 1)
|
||||||
|
writeln("(running default tests; use --help for options)");
|
||||||
|
|
||||||
|
getopt(args,
|
||||||
|
std.getopt.config.passThrough,
|
||||||
|
"def", &deflist,
|
||||||
|
"test", &testlist,
|
||||||
|
"help", &help);
|
||||||
|
|
||||||
|
if (help)
|
||||||
|
{
|
||||||
|
writeln(
|
||||||
|
`Options:
|
||||||
|
--test=type Func, Bus, Dec, or All
|
||||||
|
--def=style Delegates, Functions, Switch, or NestedSwitch
|
||||||
|
--op=num test opcode 'num' (num is hex)
|
||||||
|
--op=name test all opcodes named 'name'
|
||||||
|
--addr=mode test all opcodes with addressing mode 'mode'
|
||||||
|
|
||||||
|
(All options con be specified multiple times.
|
||||||
|
--op and --addr have no effect on decimal mode tests.)`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(def; deflist) opdefs |= def;
|
||||||
|
foreach(test; testlist) tests |= test;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
runTests(args);
|
||||||
|
}
|
||||||
|
catch (ErrnoException e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
void runTests(string[] args)
|
||||||
|
{
|
||||||
|
// If no opdef specified, use Delegates.
|
||||||
|
if (opdefs == OpDefs.None) opdefs = OpDefs.Delegates;
|
||||||
|
|
||||||
|
int defcount;
|
||||||
|
foreach (def; EnumMembers!OpDefs)
|
||||||
|
if ((opdefs & def) && def != OpDefs.All) defcount++;
|
||||||
|
|
||||||
|
// If no tests specified, run all (but exclude Dec by default if
|
||||||
|
// running with more than one opdef).
|
||||||
|
if (tests == Tests.None)
|
||||||
|
tests = Tests.Func | Tests.Bus;
|
||||||
|
if (!defcount) tests |= Tests.Dec;
|
||||||
|
|
||||||
|
foreach (def; EnumMembers!OpDefs)
|
||||||
|
if ((opdefs & def) && def != OpDefs.All)
|
||||||
|
foreach (test; EnumMembers!Tests)
|
||||||
|
if ((tests & test) && test != Tests.All)
|
||||||
|
runTest(def, test, args[1..$]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void runTest(OpDefs def, Tests test, string[] args)
|
||||||
|
{
|
||||||
|
writeln("Using ", defStrings[def]);
|
||||||
|
foreach (s; [false, true])
|
||||||
|
{
|
||||||
|
foreach (c; [false, true])
|
||||||
|
{
|
||||||
|
writeln("With strict=", s, " cumulative=", c);
|
||||||
|
string cmdline = defStrings[def] ~ stStrings[s] ~ cmStrings[c] ~
|
||||||
|
fNames[test] ~ join(args, " ");
|
||||||
|
system("rdmd --force -I.. -I../src " ~ cmdline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,42 +1,23 @@
|
||||||
module test.test_bus;
|
module test.test_bus;
|
||||||
|
|
||||||
|
|
||||||
|
import std.stdio;
|
||||||
|
|
||||||
import test.base, test.cpu;
|
import test.base, test.cpu;
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main(string[] args)
|
||||||
{
|
{
|
||||||
|
auto opts = CheckOptions(args);
|
||||||
auto report = report_timing_debug();
|
auto report = report_timing_debug();
|
||||||
|
|
||||||
alias CPU!("65C02", false, false) T1;
|
alias CPU!("6502", testStrict, testCumulative) T1;
|
||||||
for (int op = 0x00; op < 0x100; op++)
|
writeln("Testing bus/timing, 6502");
|
||||||
|
foreach (op; opts.codes6502)
|
||||||
test_opcode_timing!T1(cast(ubyte)op, report);
|
test_opcode_timing!T1(cast(ubyte)op, report);
|
||||||
|
|
||||||
alias CPU!("65C02", true, false) T2;
|
alias CPU!("65C02", testStrict, testCumulative) T2;
|
||||||
for (int op = 0x00; op < 0x100; op++)
|
writeln("Testing bus/timing, 65C02");
|
||||||
|
foreach (op; opts.codes65C02)
|
||||||
test_opcode_timing!T2(cast(ubyte)op, report);
|
test_opcode_timing!T2(cast(ubyte)op, report);
|
||||||
|
|
||||||
alias CPU!("6502", false, false) T3;
|
|
||||||
for (int op = 0x00; op < 0x100; op++)
|
|
||||||
test_opcode_timing!T3(cast(ubyte)op, report);
|
|
||||||
|
|
||||||
alias CPU!("6502", true, false) T4;
|
|
||||||
for (int op = 0x00; op < 0x100; op++)
|
|
||||||
test_opcode_timing!T4(cast(ubyte)op, report);
|
|
||||||
|
|
||||||
alias CPU!("65C02", false, true) T5;
|
|
||||||
for (int op = 0x00; op < 0x100; op++)
|
|
||||||
test_opcode_timing!T5(cast(ubyte)op, report);
|
|
||||||
|
|
||||||
alias CPU!("65C02", true, true) T6;
|
|
||||||
for (int op = 0x00; op < 0x100; op++)
|
|
||||||
test_opcode_timing!T6(cast(ubyte)op, report);
|
|
||||||
|
|
||||||
alias CPU!("6502", false, true) T7;
|
|
||||||
for (int op = 0x00; op < 0x100; op++)
|
|
||||||
test_opcode_timing!T7(cast(ubyte)op, report);
|
|
||||||
|
|
||||||
alias CPU!("6502", true, true) T8;
|
|
||||||
for (int op = 0x00; op < 0x100; op++)
|
|
||||||
test_opcode_timing!T8(cast(ubyte)op, report);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
rdmd @testopts test_func.d
|
|
||||||
rdmd @testopts test_bus.d
|
|
||||||
rdmd @testopts test_decimal.d
|
|
||||||
|
|
|
@ -228,6 +228,7 @@ if (isCpu!T)
|
||||||
|
|
||||||
version(Benchmark)
|
version(Benchmark)
|
||||||
{
|
{
|
||||||
|
static assert(!testStrict && !testCumulative);
|
||||||
import std.datetime, std.stdio;
|
import std.datetime, std.stdio;
|
||||||
void f0()
|
void f0()
|
||||||
{
|
{
|
||||||
|
@ -246,24 +247,10 @@ else
|
||||||
{
|
{
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
writeln("Testing decimal mode, NMOS(Strict.no, Cumulative.no)");
|
writeln("Testing decimal mode, 6502");
|
||||||
testDecimalMode!(CPU!("6502", false, false))();
|
testDecimalMode!(CPU!("6502", testStrict, testCumulative))();
|
||||||
writeln("Testing decimal mode, CMOS(Strict.no, Cumulative.no)");
|
|
||||||
testDecimalMode!(CPU!("65C02", false, false))();
|
|
||||||
|
|
||||||
writeln("Testing decimal mode, NMOS(Strict.no, Cumulative.yes)");
|
writeln("Testing decimal mode, 65C02");
|
||||||
testDecimalMode!(CPU!("6502", false, true))();
|
testDecimalMode!(CPU!("65C02", testStrict, testCumulative))();
|
||||||
writeln("Testing decimal mode, CMOS(Strict.no, Cumulative.yes)");
|
|
||||||
testDecimalMode!(CPU!("65C02", false, true))();
|
|
||||||
|
|
||||||
writeln("Testing decimal mode, NMOS(Strict.yes, Cumulative.no)");
|
|
||||||
testDecimalMode!(CPU!("6502", true, false))();
|
|
||||||
writeln("Testing decimal mode, CMOS(Strict.yes, Cumulative.no)");
|
|
||||||
testDecimalMode!(CPU!("65C02", true, false))();
|
|
||||||
|
|
||||||
writeln("Testing decimal mode, NMOS(Strict.yes, Cumulative.yes)");
|
|
||||||
testDecimalMode!(CPU!("6502", true, true))();
|
|
||||||
writeln("Testing decimal mode, CMOS(Strict.yes, Cumulative.yes)");
|
|
||||||
testDecimalMode!(CPU!("65C02", true, true))();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,23 @@
|
||||||
module test.test_func;
|
module test.test_func;
|
||||||
|
|
||||||
|
|
||||||
|
import std.stdio;
|
||||||
|
|
||||||
import test.base, test.cpu;
|
import test.base, test.cpu;
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main(string[] args)
|
||||||
{
|
{
|
||||||
|
auto opts = CheckOptions(args);
|
||||||
auto report = report_debug();
|
auto report = report_debug();
|
||||||
|
|
||||||
alias CPU!("65C02", false, false) T1;
|
alias CPU!("6502", testStrict, testCumulative) T1;
|
||||||
foreach (opcode; 0..255)
|
writeln("Testing functionality, 6502");
|
||||||
|
foreach (opcode; opts.codes6502)
|
||||||
test_one_opcode!T1(cast(ubyte)opcode, report);
|
test_one_opcode!T1(cast(ubyte)opcode, report);
|
||||||
|
|
||||||
alias CPU!("6502", false, false) T2;
|
alias CPU!("65C02", testStrict, testCumulative) T2;
|
||||||
foreach (opcode; 0..255)
|
writeln("Testing functionality, 65C02");
|
||||||
|
foreach (opcode; opts.codes65C02)
|
||||||
test_one_opcode!T2(cast(ubyte)opcode, report);
|
test_one_opcode!T2(cast(ubyte)opcode, report);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user