50 |
} |
} |
51 |
|
|
52 |
|
|
53 |
|
=head1 Memory management |
54 |
|
|
55 |
|
VRac implements callback for all I/O operations. This was main reason why |
56 |
|
L<Acme::6502> module with tied memory was too slow to emulate L<Orao>, so I |
57 |
|
had to write C binding for L<M6502>. |
58 |
|
|
59 |
|
B<This functions will die with stack trace when called>. They should be |
60 |
|
implemented for each architecture. |
61 |
|
|
62 |
|
=cut |
63 |
|
|
64 |
|
=head2 read |
65 |
|
|
66 |
|
Read from memory |
67 |
|
|
68 |
|
$byte = read( $address ); |
69 |
|
|
70 |
|
=cut |
71 |
|
|
72 |
|
sub read { |
73 |
|
my $self = shift; |
74 |
|
confess "please implement $self::read()"; |
75 |
|
} |
76 |
|
|
77 |
|
=head2 write |
78 |
|
|
79 |
|
Write into emory |
80 |
|
|
81 |
|
write( $address, $byte ); |
82 |
|
|
83 |
|
=cut |
84 |
|
|
85 |
|
sub write { |
86 |
|
my $self = shift; |
87 |
|
confess "please implement $self::write()"; |
88 |
|
} |
89 |
|
|
90 |
=head1 Helper functions |
=head1 Helper functions |
91 |
|
|
92 |
=head2 load_rom |
=head2 load_rom |
147 |
$from ||= 0; |
$from ||= 0; |
148 |
$to ||= 0xffff; |
$to ||= 0xffff; |
149 |
|
|
150 |
open(my $fh, '>', $path) || die "can't open $path: $!"; |
if ( open(my $fh, '>', $path) ) { |
151 |
print $fh $self->read_chunk( $from, $to ); |
print $fh $self->read_chunk( $from, $to ); |
152 |
close($fh); |
close($fh); |
153 |
|
|
154 |
|
my $size = -s $path; |
155 |
|
warn sprintf "saved %s %04x-%04x %d %x bytes\n", $path, $from, $to, $size, $size; |
156 |
|
} else { |
157 |
|
warn "can't create $path: $!"; |
158 |
|
} |
159 |
|
|
|
my $size = -s $path; |
|
|
warn sprintf "saved %s %d %x bytes\n", $path, $size, $size; |
|
160 |
} |
} |
161 |
|
|
162 |
=head2 hexdump |
=head2 hexdump |
182 |
); |
); |
183 |
} |
} |
184 |
|
|
185 |
=head1 Memory management |
=head2 append_to_file |
|
|
|
|
VRac implements all I/O using mmap addresses. This was main reason why |
|
|
L<Acme::6502> was just too slow to handle it. |
|
186 |
|
|
187 |
=cut |
$self->append_to_file( '/path/to/file', $byte, $byte ... ); |
|
|
|
|
=head2 read |
|
|
|
|
|
Read from memory |
|
|
|
|
|
$byte = read( $address ); |
|
188 |
|
|
189 |
=cut |
=cut |
190 |
|
|
191 |
sub read { |
sub append_to_file { |
192 |
my $self = shift; |
my $self = shift; |
193 |
confess "please implement $self::read()"; |
my $path = shift || confess "no path?"; |
194 |
} |
my $bytes = join('', @_); |
195 |
|
|
196 |
=head2 write |
open(my $fh, '>>', $path) || confess "can't open $path: $!"; |
197 |
|
|
198 |
Write into emory |
print $fh $bytes; |
199 |
|
warn sprintf("## append_to_file('%s',%s)\n", $path, dump($bytes)); |
|
write( $address, $byte ); |
|
|
|
|
|
=cut |
|
|
|
|
|
sub write { |
|
|
my $self = shift; |
|
|
confess "please implement $self::write()"; |
|
200 |
} |
} |
201 |
|
|
202 |
=head1 Command Line |
=head1 Command Line |