/[VRac]/Orao.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /Orao.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 35 - (show annotations)
Mon Jul 30 21:53:04 2007 UTC (16 years, 8 months ago) by dpavlin
Original Path: M6502/Orao.pm
File size: 5231 byte(s)
tests now pass
1 package Orao;
2
3 use warnings;
4 use strict;
5
6 use Carp;
7 use lib './lib';
8 #use Time::HiRes qw(time);
9 use File::Slurp;
10 use Data::Dump qw/dump/;
11 use M6502;
12
13 use base qw(Class::Accessor M6502 Screen);
14 __PACKAGE__->mk_accessors(qw(debug trace run_for mem_dump trace));
15
16 =head1 NAME
17
18 Orao - Orao emulator
19
20 =head1 VERSION
21
22 Version 0.02
23
24 =cut
25
26 our $VERSION = '0.02';
27
28 =head1 SUMMARY
29
30 Emulator or Orao 8-bit 6502 machine popular in Croatia
31
32 =cut
33
34 =head2 init
35
36 Start emulator
37
38 =cut
39
40 our $orao;
41
42 sub init {
43 my $self = shift;
44 warn "Orao calling upstream init\n";
45 $self->SUPER::init( $self, @_ );
46
47 warn "staring Orao $Orao::VERSION emulation\n";
48
49 $self->open_screen;
50 $self->load_rom({
51 0x1000 => 'dump/SCRINV.BIN',
52 0xC000 => 'rom/BAS12.ROM',
53 0xE000 => 'rom/CRT12.ROM',
54 });
55
56 $self->load_oraoemu( 'dump/orao-1.2' );
57 $self->load_oraoemu( 'dump/SCRINV.BIN' );
58 $PC = 0x1000;
59
60 $orao = $self;
61
62 # $self->prompt( 0x1000 );
63
64 warn "rendering memory map\n";
65
66 my @mmap = (
67 0x0000, 0x03FF, 'nulti blok',
68 0x0400, 0x5FFF, 'korisnièki RAM (23K)',
69 0x6000, 0x7FFF, 'video RAM',
70 0x8000, 0x9FFF, 'sistemske lokacije',
71 0xA000, 0xAFFF, 'ekstenzija',
72 0xB000, 0xBFFF, 'DOS',
73 0xC000, 0xDFFF, 'BASIC ROM',
74 0xE000, 0xFFFF, 'sistemski ROM',
75 );
76
77 foreach my $i ( 0 .. $#mmap / 3 ) {
78 my $o = $i * 3;
79 my ( $from, $to, $desc ) = @mmap[$o,$o+1,$o+2];
80 printf "%04x - %04x - %s\n", $from, $to, $desc;
81 for my $a ( $from .. $to ) {
82 $orao->read( $a );
83 }
84 $self->sync;
85 }
86
87 warn "Orao init finished\n";
88
89 }
90
91 =head2 load_rom
92
93 called to init memory and load initial rom images
94
95 $orao->load_rom;
96
97 =cut
98
99 sub load_rom {
100 my ($self, $loaded_files) = @_;
101
102 #my $time_base = time();
103
104 foreach my $addr ( sort keys %$loaded_files ) {
105 my $path = $loaded_files->{$addr};
106 $self->load_oraoemu( $path, $addr );
107 }
108 }
109
110
111 =head2 load_oraoemu
112
113 =cut
114
115 sub load_oraoemu {
116 my $self = shift;
117 my ( $path, $addr ) = @_;
118
119 my $size = -s $path || confess "no size for $path: $!";
120
121 my $buff = read_file( $path );
122
123 if ( $size == 65538 ) {
124 $addr = 0;
125 warn sprintf "loading oraoemu 64k dump %s at %04x - %04x %02x\n", $path, $addr, $addr+$size-1, $size;
126 $self->write_chunk( $addr, substr($buff,2) );
127 return;
128 } elsif ( $size == 32800 ) {
129 $addr = 0;
130 warn sprintf "loading oraoemu 1.3 dump %s at %04x - %04x %02x\n", $path, $addr, $addr+$size-1, $size;
131 #$self->write_chunk( $addr, substr($buff,0x20) );
132 $self->poke_code( $addr, map { ord($_) } split(//,substr($buff,0x20)) );
133 return;
134 }
135 printf "loading %s at %04x - %04x %02x\n", $path, $addr, $addr+$size-1, $size;
136 return $self->poke_code( $addr, map { ord($_) } split(//,$buff) );
137 return $self->write_chunk( $addr, $buff );
138
139 my $chunk;
140
141 my $pos = 0;
142
143 while ( my $long = substr($buff,$pos,4) ) {
144 my @b = split(//, $long, 4);
145 $chunk .=
146 ( $b[3] || '' ) .
147 ( $b[2] || '' ) .
148 ( $b[1] || '' ) .
149 ( $b[0] || '' );
150 $pos += 4;
151 }
152
153 $self->write_chunk( $addr, $chunk );
154
155 };
156
157 =head2 save_dump
158
159 $orao->save_dump( 'filename', $from, $to );
160
161 =cut
162
163 sub save_dump {
164 my $self = shift;
165
166 my ( $path, $from, $to ) = @_;
167
168 $from ||= 0;
169 $to ||= 0xffff;
170
171 open(my $fh, '>', $path) || die "can't open $path: $!";
172 print $fh $self->read_chunk( $from, $to );
173 close($fh);
174
175 my $size = -s $path;
176 warn sprintf "saved %s %d %x bytes\n", $path, $size, $size;
177 }
178
179 =head2 hexdump
180
181 $orao->hexdump( $address );
182
183 =cut
184
185 sub hexdump {
186 my $self = shift;
187 my $a = shift;
188 return sprintf(" %04x %s\n", $a,
189 join(" ",
190 map {
191 sprintf( "%02x", $_ )
192 } $self->ram( $a, $a+8 )
193 )
194 );
195 }
196
197 =head2 prompt
198
199 $orao->prompt( $address, $last_command );
200
201 =cut
202
203 sub prompt {
204 my $self = shift;
205 my $a = shift;
206 my $last = shift;
207 print STDERR $self->hexdump( $a ),
208 $last ? "[$last] " : '',
209 "> ";
210 my $in = <STDIN>;
211 chomp($in);
212 $in ||= $last;
213 $last = $in;
214 return split(/\s+/, $in) if $in;
215 }
216
217 =head1 Memory management
218
219 Orao implements all I/O using mmap addresses. This was main reason why
220 L<Acme::6502> was just too slow to handle it.
221
222 =cut
223
224 =head2 read
225
226 Read from memory
227
228 $byte = read( $address );
229
230 =cut
231
232 sub read {
233 my $self = shift;
234 my ($addr) = @_;
235 my $byte = $mem[$addr];
236 warn "# Orao::read(",dump(@_),") = ",dump( $byte ),"\n" if $self->debug;
237 $self->mmap_pixel( $addr, 0, $byte, 0 );
238 return $byte;
239 }
240
241 =head2 write
242
243 Write into emory
244
245 write( $address, $byte );
246
247 =cut
248
249 sub write {
250 my $self = shift;
251 warn "# Orao::write(",dump(@_),")\n" if $self->debug;
252 my ($addr,$byte) = @_;
253
254 if ( $addr >= 0x6000 && $addr < 0x8000 ) {
255 $self->vram( $addr - 0x6000 , $byte );
256 }
257
258 if ( $addr > 0xafff ) {
259 warn sprintf "access to %04x above affff aborting\n", $addr;
260 return -1;
261 }
262 if ( $addr == 0x8800 ) {
263 warn sprintf "sound ignored: %x\n", $byte;
264 }
265
266 $self->mmap_pixel( $addr, $byte, 0, 0 );
267
268 $mem[$addr] = $byte;
269 }
270
271
272 =head1 AUTHOR
273
274 Dobrica Pavlinusic, C<< <dpavlin@rot13.org> >>
275
276 =head1 BUGS
277
278 =head1 ACKNOWLEDGEMENTS
279
280 See also L<http://www.foing.hr/~fng_josip/orao.htm> which is source of all
281 info about this machine (and even hardware implementation from 2007).
282
283 =head1 COPYRIGHT & LICENSE
284
285 Copyright 2007 Dobrica Pavlinusic, All Rights Reserved.
286
287 This program is free software; you can redistribute it and/or modify it
288 under the same terms as Perl itself.
289
290 =cut
291
292 1; # End of Orao

  ViewVC Help
Powered by ViewVC 1.1.26