#!perl
# $Id: sjasmplus.t,v 1.1 2010/11/20 20:38:52 Paulo Exp $
use warnings;
use strict;
use Test::More;
use File::Slurp;
my $asm_file = "sjasmplus.asm";
my $bin_file = "sjasmplus.bin";
my $log_file = "sjasmplus.log";
unless ( $ENV{RELEASE_TESTING} ) {
plan( skip_all => "Author tests not required unless RELEASE_TESTING" );
}
use_ok 'Asm::Z80::Table';
#------------------------------------------------------------------------------
# assemble with sjasmplus, compare assembly bytes
assemble("", ""); # empty input file
my @tests;
isa_ok my $iter = Asm::Z80::Table->iterator, 'CODE';
my($full_asm, $full_obj) = ("", "");
my $last;
while (my($tokens, $bytes) = $iter->()) {
for (@$tokens) {
if ($_ eq 'N') { $_ = 1; }
elsif ($_ eq 'DIS') { $_ = 2; }
elsif ($_ eq 'NDIS') { $_ = 3; }
elsif ($_ eq 'NN') { $_ = 4; }
else {}
}
for (@$bytes) {
if ($_ eq 'N') { $_ = 1; }
elsif ($_ eq 'DIS') { $_ = 2; }
elsif ($_ eq 'DIS+1') { $_ = 3; }
elsif ($_ eq 'NDIS') { $_ = -3 & 0xFF; }
elsif ($_ eq 'NDIS+1') { $_ = (-3+1) & 0xFF; }
elsif ($_ eq 'NNl') { $_ = 4; }
elsif ($_ eq 'NNh') { $_ = 0; }
elsif ($_ eq 'NNo') { $_ = 2; }
else {}
}
my $asm = join(' ', @$tokens);
my $obj = join('', map {chr} @$bytes);
# jr/djnz have to be compiled separately; group others by instruction
if ($asm =~ /jr|djnz/) {
assemble($asm, $obj);
}
elsif ($last && substr($asm,0,2) ne $last) {
# changed
assemble($full_asm, $full_obj);
($full_asm, $full_obj) = ("\t$asm\n", $obj);
}
else {
# concatenate
$full_asm .= "\t$asm\n";
$full_obj .= $obj;
}
$last = substr($asm,0,2);
}
assemble($full_asm, $full_obj);
unlink $asm_file, $bin_file, $log_file;
done_testing();
#------------------------------------------------------------------------------
# assemble given code
sub assemble {
my($asm, $obj) = @_;
for ($asm) {
# convert rst x --> rst x*8 (x in 1..7)
s/(rst\s+)(\d+)/ $2 < 8 && $2 > 0 ? $1."8*".$2 : $1.$2 /giem;
# convert 'jr po', etc to 'jp po'
s/^jr(\s+(po|pe|p|m)\s*,)/jp$1/gim;
}
unlink $bin_file, $log_file;
write_file($asm_file,
"
macro stop
db 0xDD, 0xDD, 0x00
endm
output $bin_file
$asm
");
my $cmd = "sjasmplus $asm_file > $log_file";
my $ret = system $cmd;
is $ret, 0, $cmd;
is read_file($bin_file, binmode => ':raw'), $obj, $asm;
like read_file($log_file), qr/^Errors: 0, warnings: 0,/mi, $log_file;
die unless read_file($bin_file, binmode => ':raw') eq $obj;
}
#------------------------------------------------------------------------------
# assemble in blocks of code