CPU-Z80-Disassembler

 view release on metacpan or  search on metacpan

t/Instruction.t  view on Meta::CPAN

#!perl

use strict;
use warnings;

use Test::More;

use_ok 'CPU::Z80::Disassembler::Instruction';

my $mem;
my $instr;

#------------------------------------------------------------------------------
# test one instruction
sub t_instr (@) {
	my($factory, $addr, $limit, $size, $opcode, $args, 
	   $is_call, $is_branch, $is_break_flow,
	   $string, $dump) = @_;
	
	my $caller_line = (caller)[2];
	ok 1, "[line $caller_line]";

	isa_ok $instr = CPU::Z80::Disassembler::Instruction->$factory(
												$mem, $addr, $limit), 
			'CPU::Z80::Disassembler::Instruction';

	is $instr->memory, 	$mem, 		"memory";
	is $instr->addr, 	$addr, 		"addr = $addr";
	is $instr->size, 	$size, 		"size = $size";
	is $instr->opcode, 	$opcode, 	"opcode = $opcode";
	is !!$instr->is_code, !!($opcode !~ /def|org/), "is_code = ".
									(!!$instr->is_code);
	
	for my $arg (qw( N NN DIS STR )) {
		ok exists($args->{$arg}) ? 
				_list_str($args->{$arg}) eq _list_str($instr->$arg) :
				!defined($instr->$arg),	
			"$arg = ".(exists($args->{$arg}) ? 
							_list_str($args->{$arg}) : 
							'undef');
	}
	
	is $instr->next_addr,	$addr+$size,	"next_addr";

	my @next_code;
	push @next_code, $instr->NN if $instr->opcode =~ /jr|jp .*NN|djnz|call|rst/;
	push @next_code, $instr->next_addr unless $instr->opcode =~ /ret$|reti|retn|jp NN|jr NN|call NN|rst|jp \(|org/;
	is_deeply [$instr->next_code], \@next_code;
	
	my $bytes = [];
	for (0 .. $size-1) {
		push @$bytes, $mem->peek($addr+$_);
	}
	is_deeply $instr->bytes,	$bytes,		"bytes = @$bytes";
	
	is !!$instr->is_call,		!!$is_call,	
									"is_call = $is_call";
	is !!$instr->is_branch,		!!$is_branch,
									"is_branch = $is_branch";
	is !!$instr->is_break_flow,	!!$is_break_flow,
									"is_break_flow = $is_break_flow";
	
	is $instr->as_string,	$string,	"as_string = $string";
	is $instr->dump,		$dump,		"dump = \n$dump";
	
	my $asm = " " x 8 . $string . "\n";
	$asm .= "\n" if $opcode =~ /jp NN|jp \(|jr NN|ret[in]?$|org/;
	is $instr->asm,			$asm,		"asm = \n$asm";
	
}

sub _list_str {
	my($v) = @_;
	ref($v) ? join(",", @$v) : $v;
}


#------------------------------------------------------------------------------
isa_ok $mem = CPU::Z80::Disassembler::Memory->new, 
			'CPU::Z80::Disassembler::Memory';



( run in 1.354 second using v1.01-cache-2.11-cpan-6de40a662fe )