Acme-6502
view release on metacpan or search on metacpan
lib/Acme/6502.pm view on Meta::CPAN
package Acme::6502;
use warnings FATAL => 'all';
use strict;
use Carp;
our $VERSION = '0.77';
# CPU flags
use constant {
N => 0x80,
V => 0x40,
R => 0x20,
B => 0x10,
D => 0x08,
I => 0x04,
Z => 0x02,
C => 0x01
};
use constant FLAGS => 'NVRBDIZC';
# Other CPU constants
use constant {
STACK => 0x0100,
BREAK => 0xFFFE
};
# Opcode to thunk into perlspace
use constant {
ESCAPE_OP => 0x0B,
ESCAPE_SIG => 0xAD
};
BEGIN {
for my $reg ( qw(a x y s p pc) ) {
no strict 'refs';
*{ __PACKAGE__ . "\::get_${reg}" } = sub {
my $self = shift;
return $self->{ reg }->{ $reg };
};
*{ __PACKAGE__ . "\::set_${reg}" } = sub {
my ( $self, $v ) = @_;
$self->{ reg }->{ $reg } = $v;
};
}
}
sub new {
my $class = shift;
my $self = bless { }, $class;
$self->_BUILD( @_ );
return $self;
}
my @OP_CACHE;
sub _BUILD {
my( $self, $args ) = @_;
$args ||= {};
$self->{ mem } = [ ( 0 ) x 65536 ];
$self->{ reg } = {
map { $_ => 0 } qw( a x y s p pc )
};
$self->{ os } = [ ];
$self->{ jumptab } = $args->{ jumptab } || 0xFA00;
$self->{ zn } = [ $self->Z, ( 0 ) x 127, ( $self->N ) x 128 ];
my $bad_inst = $self->can( '_bad_inst' );
@OP_CACHE = (
_inst( # 00 BRK
_push( '($pc + 1) >> 8', '($pc + 1)' ),
_push( '$p | B' ),
'$p = $p | I | B & ~D;',
_jmp_i( BREAK )
),
_inst( _ora( _zpix() ) ), # 01 ORA (zp, x)
$bad_inst, # 02
$bad_inst, # 03
_inst( _tsb( _zp() ) ), # 04 TSB zp
_inst( _ora( _zp() ) ), # 05 ORA zp
_inst( _asl( _zp() ) ), # 06 ASL zp
$bad_inst, # 07
_inst( _push( '$p | R' ) ), # 08 PHP
_inst( _ora( _imm() ) ), # 09 ORA #imm
_inst( _asl( _acc() ) ), # 0A ASL A
$bad_inst, # 0B
_inst( _tsb( _abs() ) ), # 0C TSB zp
_inst( _ora( _abs() ) ), # 0D ORA abs
_inst( _asl( _abs() ) ), # 0E ASL abs
$bad_inst, # 0F BBR0 rel
_inst( _bfz( _rel(), N ) ), # 10 BPL rel
_inst( _ora( _zpiy() ) ), # 11 ORA (zp), y
_inst( _ora( _zpi() ) ), # 12 ORA (zp)
$bad_inst, # 13
_inst( _trb( _zpi() ) ), # 14 TRB (zp)
_inst( _ora( _zpx() ) ), # 15 ORA zp, x
_inst( _asl( _zpx() ) ), # 16 ASL zp, x
$bad_inst, # 17
_inst( '$p &= ~C;' ), # 18 CLC
_inst( _ora( _absy() ) ), # 19 ORA abs, y
_inst( _inc( _acc() ) ), # 1A INC A
$bad_inst, # 1B
_inst( _trb( _abs() ) ), # 1C TRB abs
_inst( _ora( _absx() ) ), # 1D ORA abs, x
_inst( _asl( _absx() ) ), # 1E ASL abs, x
( run in 0.842 second using v1.01-cache-2.11-cpan-5b529ec07f3 )