--- Galaksija.pm 2007/08/04 22:40:14 137 +++ Galaksija.pm 2007/09/30 19:47:32 185 @@ -6,9 +6,11 @@ use Carp qw/confess/; use File::Slurp; use Data::Dump qw/dump/; -use Z80; # import +use Z80; +use Screen; +use Time::HiRes qw/time/; -use base qw(Class::Accessor VRac Z80 Screen Prefs); +use base qw(Class::Accessor VRac Z80 Screen Prefs Session); __PACKAGE__->mk_accessors(qw(booted)); =head1 NAME @@ -17,11 +19,11 @@ =head1 VERSION -Version 0.00 +Version 0.01 =cut -our $VERSION = '0.00'; +our $VERSION = '0.01'; =head1 SUMMARY @@ -57,7 +59,7 @@ $self->open_screen; $self->load_rom({ 0x0000, 'rom/Galaksija/ROM1.BIN', - 0x2000, 'rom/Galaksija/ROM2.BIN', + 0x1000, 'rom/Galaksija/ROM2.BIN', # 0xE000, 'rom/Galaksija/GAL_PLUS.BIN', }); @@ -65,7 +67,7 @@ $mem[$_] = 0xff foreach ( 0x2000 .. 0x2800 ); # display - $mem[$_] = ' ' foreach ( 0x2800 .. 0x2a00 ); + $mem[$_] = 0x20 foreach ( 0x2800 .. 0x2a00 ); # 6116-ice $mem[$_] = 0 foreach ( 0x2a00 .. 0x4000 ); @@ -90,8 +92,15 @@ Z80::reset(); + my $hor_pos = 0; + $self->loop( sub { - Z80::exec( $_[0] ); + my $run_for = shift; + Z80::exec( $run_for ); + if ( $hor_pos != $mem[ 0x2ba8 ] ) { + warn "scroll 0x2ba8", $self->hexdump( 0x2ba8 ); + $hor_pos = $mem[ 0x2ba8 ]; + } $self->render_vram; }); @@ -110,10 +119,6 @@ =cut -my $keyboard_none = 255; - -my $keyboard = {}; - sub read { my $self = shift; my ($addr) = @_; @@ -121,6 +126,11 @@ confess sprintf("can't find memory at address %04x",$addr) unless defined($byte); warn sprintf("# Galaksija::read(%04x) = %02x\n", $addr, $byte) if $self->trace; + if ( $addr >= 0x2000 && $addr <= 0x2036 ) { +# printf("## keyread 0x%04x = %02x\n", $addr, $byte); + $self->key_pressed( 1 ); # force process of events + } + $self->mmap_pixel( $addr, 0, $byte, 0 ) if $self->show_mem; return $byte; } @@ -138,6 +148,8 @@ my ($addr,$byte) = @_; warn sprintf("# Galaksija::write(%04x,%02x)\n", $addr, $byte) if $self->trace; + return if ( $addr > 0x4000 ); + $self->mmap_pixel( $addr, $byte, 0, 0 ) if $self->show_mem; $mem[$addr] = $byte; return; @@ -145,22 +157,152 @@ =head1 Architecture specific +=cut + +my @keymap = ( + 'a' .. 'z', + qw/up down left right space/, + '0' .. '9', + ':', '"', ',', '=', '.', '/', 'return', 'tab', + 'left alt', 'backspace', 'scroll lock', 'left shift' +); + +my $remap_key2addr; +my $o = 1; + +foreach my $key ( @keymap ) { + $remap_key2addr->{$key} = 0x2000 + $o; + $o++; +} + +printf("keymap is mmaped 0x%04x - 0x%04x\n", 0x2000, $o); + +=head2 key_down + +=cut + +sub key_down { + my ( $self, $key ) = @_; + if ( ! defined( $remap_key2addr->{$key} ) ) { + warn "unknown key pressed: $key [ignoring]\n"; + return; + } + printf("registered key down: $key address: %04x\n", $remap_key2addr->{$key} ); + $self->write( $remap_key2addr->{$key}, 0xfe ); +} + +=head2 key_up + +=cut + +sub key_up { + my ( $self, $key ) = @_; + if ( ! defined( $remap_key2addr->{$key} ) ) { + warn "unknown key released: $key [ignoring]\n"; + return; + } + warn "registred key up: $key ", $remap_key2addr->{$key}; + $self->write( $remap_key2addr->{$key}, 0xff ); +} + =head2 render_vram -Simple hex dumper of text buffer +Render characters as graphic =cut +my $char_rom = 'rom/Galaksija/CHRGEN.BIN'; + +my @chars = map { ord($_) } split(//, read_file( $char_rom )); +warn "loaded ", $#chars, " bytes from $char_rom\n"; + +my @char2pos; + +# maken from mess/video/galaxy.c +foreach my $char ( 0 .. 255 ) { + my $c = $char; + if ( ( $c > 63 && $c < 96 ) || ( $c > 127 && $c < 192 ) ) { + $c -= 64; + } elsif ( $c > 191 ) { + $c -= 128; + } + $char2pos[ $char ] = ( $c & 0x7f ); +} + +#warn "## chars2pos = ",dump( @char2pos ); + +sub screen_width { 256 } +sub screen_height { 16 * 13 } + sub render_vram { my $self = shift; + my $t = time(); + + my $addr = 0x2800; + + my @pixels = ("\x00") x ( 32 * 16 * 13 ); + my $a = 0; + + for my $y ( 0 .. 15 ) { + for my $x ( 0 .. 31 ) { + my $c = $mem[ $addr++ ]; + $c = $char2pos[ $c ]; + for my $l ( 0 .. 12 ) { + my $o = $l << 5; # *32 + my $co = ( $l << 7 ) | $c; + $pixels[ $a + $x + $o ] = $flip[ $chars[ $co ] ]; + } + } + $a += ( 32 * 13 ); # next line + } + + my $vram = SDL::Surface->new( + -width => $self->screen_width, + -height => $self->screen_height, + -depth => 1, # 1 bit per pixel + -pitch => 32, # bytes per line + -from => pack("C*", @pixels), + ); + $vram->set_colors( 0, $white, $black ); + + $self->render_frame( $vram ); + +# $self->render_vram_text; + + printf("frame in %.2fs\n", time()-$t) if $self->debug; +} + + +=head2 render_vram_text + +Simple hex dumper of text buffer + +=cut + +my $last_dump = ''; + +sub render_vram_text { + my $self = shift; + my $addr = 0x2800; - print " "; # FIXME auch! + my $dump; + for my $y ( 0 .. 15 ) { - printf "%2d: %s\n",$y, join('', map { sprintf("%02x ",$_) } @mem[ $addr .. $addr+31 ] ); +# $dump .= sprintf "%2d: %s\n",$y, join('', map { sprintf("%02x ",$_) } @mem[ $addr .. $addr+31 ] ); + $dump .= sprintf "%2d: %s\n",$y, join('', map { chr( $_ ) } @mem[ $addr .. $addr+31 ] ); $addr += 32; } + + if ( $mem[ 0x2bb0 ] ) { + warn "scroll", $self->hexdump( 0x2bb0 ); + } + + if ( $dump ne $last_dump ) { + print $dump; + $last_dump = $dump; + } } =head2 cpu_PC @@ -186,14 +328,17 @@ Dobrica Pavlinusic, C<< >> -Based on Galaxy Win emulator L - =head1 BUGS +Galaksija Plus isn't emulated. I don't have additional rom, but I would +B to have support for this machine. So if you have ROM for Galaksija +Plus, get in touch! + =head1 ACKNOWLEDGEMENTS -See also L<> which is source of all -info about this machine (and even hardware implementation from 2007). +Based on Galaxy emulator L for Windows which +is in turn based on DOS version by Miodrag Jevremoviæ +L. =head1 COPYRIGHT & LICENSE