--- Orao.pm 2007/08/04 15:43:28 126 +++ Orao.pm 2007/08/04 22:47:32 138 @@ -32,21 +32,17 @@ =head1 FUNCTIONS -=head2 boot - -Start emulator, open L, load initial ROM images, and render memory +=head2 run - my $emu = Orao->new({}); - $emu->boot; +Start emulator, open L, load initial ROM images, and start emulator loop =cut our $emu; -select(STDERR); $| = 1; - -sub boot { +sub run { my $self = shift; + warn "Orao calling upstream init\n"; $self->SUPER::init( read => sub { $self->read( @_ ) }, @@ -58,6 +54,7 @@ warn "emulating ", $#mem, " bytes of memory\n"; # $self->scale( 2 ); + $self->show_mem( 1 ); $self->open_screen; $self->load_rom({ @@ -83,15 +80,11 @@ $self->trace( 0 ); $self->debug( 0 ); - warn "rendering video memory\n"; - $self->render_vram( @mem[ 0x6000 .. 0x7fff ] ); + warn "rendering memory\n"; + $self->render_mem( @mem ); if ( $self->show_mem ) { - warn "rendering memory map\n"; - - $self->render_mem( @mem ); - my @mmap = ( 0x0000, 0x03FF, 'nulti blok', 0x0400, 0x5FFF, 'korisnički RAM (23K)', @@ -103,13 +96,18 @@ 0xE000, 0xFFFF, 'sistemski ROM', ); + print "Orao memory map:"; + + while ( @mmap ) { + my ( $from, $to, $desc ) = splice(@mmap, 0, 3); + printf("%04x-%04x %s\n", $from, $to, $desc); + } + } - $self->sync; + $self->trace( $trace ); $self->debug( $debug ); - #( $A, $P, $X, $Y, $S, $IPeriod ) = ( 1, 2, 3, 4, 5, 6 ); - warn "Orao boot finished", $self->trace ? ' trace' : '', $self->debug ? ' debug' : '', @@ -117,39 +115,31 @@ M6502::reset(); - $self->booted( 1 ); -} - -=head2 run - -Run interactive emulation loop - - $emu->run; - -=cut - -sub run { - my $self = shift; - - $self->boot if ( ! $self->booted ); - # $self->load_tape( '../oraoigre/bdash.tap' ); $self->loop( sub { - M6502::exec( $_[0] ); + my $run_for = shift; + warn sprintf("about to exec from PC %04x for %d cycles\n", $PC, $run_for) if $self->trace; + M6502::exec( $run_for ); $self->render_vram; }); }; + =head1 Helper functions +=head2 write_chunk + +Write chunk directly into memory, updateing vram if needed + + $emu->write_chunk( 0x1000, $chunk_data ); + =cut -# write chunk directly into memory, updateing vram if needed -sub _write_chunk { +sub write_chunk { my $self = shift; my ( $addr, $chunk ) = @_; - $self->write_chunk( $addr, $chunk ); + $self->SUPER::write_chunk( $addr, $chunk ); my $end = $addr + length($chunk); my ( $f, $t ) = ( 0x6000, 0x7fff ); @@ -162,8 +152,8 @@ $t = $end if ( $end < $t ); warn sprintf("refresh video ram %04x-%04x\n", $f, $t); - $self->render_vram( @mem[ 0x6000 .. 0x7fff ] ); - $self->render_mem( @mem ) if $self->show_mem; + $self->render_vram; + $self->render_mem( @mem ); } =head2 load_image @@ -192,34 +182,17 @@ if ( $size == 65538 ) { $addr = 0; warn sprintf "loading oraoemu 64k dump %s at %04x - %04x %02x\n", $path, $addr, $addr+$size-1, $size; - $self->_write_chunk( $addr, substr($buff,2) ); + $self->write_chunk( $addr, substr($buff,2) ); return 1; } elsif ( $size == 32800 ) { $addr = 0; warn sprintf "loading oraoemu 1.3 dump %s at %04x - %04x %02x\n", $path, $addr, $addr+$size-1, $size; - $self->_write_chunk( $addr, substr($buff,0x20) ); + $self->write_chunk( $addr, substr($buff,0x20) ); return 1; } - printf "loading %s at %04x - %04x %02x\n", $path, $addr, $addr+$size-1, $size; - $self->_write_chunk( $addr, $buff ); - return 1; - - my $chunk; - - my $pos = 0; - - while ( my $long = substr($buff,$pos,4) ) { - my @b = split(//, $long, 4); - $chunk .= - ( $b[3] || '' ) . - ( $b[2] || '' ) . - ( $b[1] || '' ) . - ( $b[0] || '' ); - $pos += 4; - } - - $self->_write_chunk( $addr, $chunk ); + printf "loading %s at %04x - %04x %02x\n", $path, $addr, $addr+$size-1, $size; + $self->write_chunk( $addr, $buff ); return 1; }; @@ -365,6 +338,7 @@ sub read { my $self = shift; my ($addr) = @_; + return if ( $addr > 0xffff ); my $byte = $mem[$addr]; confess sprintf("can't find memory at address %04x",$addr) unless defined($byte); warn sprintf("# Orao::read(%04x) = %02x\n", $addr, $byte) if $self->trace; @@ -397,7 +371,7 @@ return $self->read_tape; } - $self->mmap_pixel( $addr, 0, $byte, 0 ); + $self->mmap_pixel( $addr, 0, $byte, 0 ) if $self->show_mem; return $byte; } @@ -422,12 +396,13 @@ confess sprintf "write access 0x%04x > 0xafff aborting\n", $addr; } - $self->mmap_pixel( $addr, $byte, 0, 0 ); - + $self->mmap_pixel( $addr, $byte, 0, 0 ) if $self->show_mem; $mem[$addr] = $byte; return; } +=head1 Architecture specific + =head2 render_vram Render one frame of video ram @@ -456,8 +431,6 @@ sub render_vram { my $self = shift; - return unless $self->booted; - my $pixels = pack("C*", map { $flip[$_] } @mem[ 0x6000 .. 0x7fff ]); my $vram = SDL::Surface->new( @@ -472,6 +445,21 @@ $self->render_frame( $vram ); } +=head2 cpu_PC + +Helper metod to set or get PC for current architecture + +=cut + +sub cpu_PC { + my ( $self, $addr ) = @_; + if ( defined($addr) ) { + $PC = $addr; + warn sprintf("running from PC %04x\n", $PC); + }; + return $PC; +} + =head1 AUTHOR Dobrica Pavlinusic, C<< >>