--- M6502/M6502.pm 2007/07/30 17:56:13 30 +++ M6502/M6502.pm 2007/07/31 09:37:01 42 @@ -5,6 +5,8 @@ use Data::Dump qw/dump/; use Carp qw/confess/; +use Exporter 'import'; +our @EXPORT = qw'@mem $PC $A $P $X $Y $S $IPeriod $run_for'; =head1 NAME @@ -24,6 +26,8 @@ our ( $A, $P, $X, $Y, $S ) = (0) x 5; # Set IPeriod to number of CPU cycles between calls to Loop6502 our $IPeriod = 1; +# Exec6502 cycles +our $run_for = 0; =head1 init @@ -32,8 +36,9 @@ =cut sub init { - warn "inside init\n"; - print "stdout\n"; + my $self = shift; + warn dump(@_); + warn "inside init low-level M6502 from $self\n"; }; =head2 read @@ -67,7 +72,8 @@ =head2 poke_code -Write series of bytes into memory without passing through MMU +Write series of bytes into memory passing through MMU (C and C) +functions. If you don't want to trigger MMU, use C. $emu->poke_code( 0xbeef, 0xff, 0x00, 0xff, 0x00, 0xaa ); @@ -77,7 +83,22 @@ my $self = shift; my $addr = shift; warn sprintf("# poke_code(%04x,%s)\n", $addr, dump( @_ )) if $self->debug; - $mem[$addr++] = $_ foreach @_; + #$mem[$addr++] = $_ foreach @_; + $self->write($addr++, $_) foreach @_; +} + +=head2 write_chunk + +Low-level update of memory, overriding user specified MMU functions C and C + + $emu->write_chunk( $address, $chunk_of_data ); + +=cut + +sub write_chunk { + my ($self, $addr, $chunk) = @_; + my $len = length($chunk); + splice @mem, $addr, $len, unpack('C*', $chunk); } =head2 ram @@ -91,13 +112,49 @@ sub ram { my $self = shift; my ($from,$to) = @_; + warn "ram($from,$to)\n"; if ($from + $to) { printf "ram %04x - %04x\n", $from, $to; - return $mem[$from .. $to - 1]; + return @mem[$from .. $to - 1]; } printf "ram %04x\n", $from; return $mem[$from] if defined($from); confess "no from address"; } +=head2 prompt + +Call this after C<< $run_for >> cycles have been run on processor + +=cut + +sub prompt { + warn "prompt -- you should override this\n"; + return 1; +} + +=head2 push_R + +called by C to push changes in registars back to perl variables + +=cut + +sub push_R { + warn "push_R(",dump(@_),")\n"; + my ( $a, $p, $x, $y, $s, $pc ) = @_; + $PC = $pc; + $S=$s; $X=$x; $Y=$y; $P=$p; $A=$a; + dump_R(); +} + +=head2 dump_R + +helper function which dumps registers + +=cut + +sub dump_R { + warn sprintf("PC: %04x A:%02x P:%02x X:%02x Y:%02x S:%02x\n", $PC, $A, $P, $X, $Y, $S); +} + 1;