/[VRac]/M6502/M6502.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

Annotation of /M6502/M6502.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 74 - (hide annotations)
Tue Jul 31 23:48:19 2007 UTC (16 years, 9 months ago) by dpavlin
File size: 3658 byte(s)
Implemented all R parts which are public in perl
1 dpavlin 24 package M6502;
2    
3     use strict;
4     use warnings;
5    
6 dpavlin 27 use Data::Dump qw/dump/;
7 dpavlin 29 use Carp qw/confess/;
8 dpavlin 34 use Exporter 'import';
9 dpavlin 74 our @EXPORT = qw'@mem $PC $A $P $X $Y $S $IPeriod $ICount $IRequest $IAutoReset $TrapBadOps $Trap $Trace $run_for $debug';
10 dpavlin 27
11 dpavlin 29 =head1 NAME
12 dpavlin 24
13 dpavlin 54 M6502 - perl bindings for M6502 CPU emulator
14 dpavlin 29
15     =cut
16    
17 dpavlin 50 my $debug = 0;
18 dpavlin 24
19 dpavlin 29 our $VERSION = qw(0.0.1);
20 dpavlin 27
21 dpavlin 29 our @mem = (0xff) x 0x10000; # 64M
22    
23 dpavlin 25 # program counter
24 dpavlin 34 our $PC = 0xbeef;
25 dpavlin 25 # CPU registars
26 dpavlin 36 our ( $A, $P, $X, $Y, $S ) = (0) x 5;
27 dpavlin 74
28     our $IPeriod=1; # Set IPeriod to number of CPU cycles between calls to Loop6502
29     our $ICount;
30     our $IRequest; # Set to the INT_IRQ when pending IRQ
31     our $IAutoReset; # Set to 1 to autom. reset IRequest
32     our $TrapBadOps=1; # Set to 1 to warn of illegal opcodes
33     our $Trap; # Set Trap to address to trace from
34     our $Trace; # Set Trace=1 to start tracing
35    
36 dpavlin 40 # Exec6502 cycles
37 dpavlin 42 our $run_for = 0;
38 dpavlin 24
39 dpavlin 54 =head1 FUNCTIONS
40 dpavlin 26
41 dpavlin 54 =head2 init
42    
43 dpavlin 26 Called before C<Run6502>
44    
45     =cut
46    
47     sub init {
48 dpavlin 33 my $self = shift;
49     warn "inside init low-level M6502 from $self\n";
50 dpavlin 26 };
51 dpavlin 27
52     =head2 read
53    
54     Read from memory
55    
56     $byte = read( $address );
57    
58     =cut
59    
60     sub read {
61     my ($addr) = @_;
62     my $byte = $mem[$addr];
63 dpavlin 50 warn "## M6502::read(",dump(@_),") = ",dump( $byte ),"\n" if $debug;
64 dpavlin 27 return $byte;
65     }
66    
67     =head2 write
68    
69     Write into emory
70    
71     write( $address, $byte );
72    
73     =cut
74    
75     sub write {
76 dpavlin 50 warn "## M6502::write(",dump(@_),")\n" if $debug;
77 dpavlin 27 my ($addr,$byte) = @_;
78     $mem[$addr] = $byte;
79     }
80 dpavlin 29
81     =head2 poke_code
82    
83 dpavlin 42 Write series of bytes into memory passing through MMU (C<read> and C<write>)
84     functions. If you don't want to trigger MMU, use C<write_chunk>.
85 dpavlin 29
86     $emu->poke_code( 0xbeef, 0xff, 0x00, 0xff, 0x00, 0xaa );
87    
88     =cut
89    
90     sub poke_code {
91     my $self = shift;
92     my $addr = shift;
93 dpavlin 50 warn sprintf("## M6502::poke_code(%04x,%s)\n", $addr, dump( @_ )) if $self->debug;
94 dpavlin 42 #$mem[$addr++] = $_ foreach @_;
95 dpavlin 51 # call low-level write
96     Arch::write($addr++, $_) foreach @_;
97 dpavlin 29 }
98    
99 dpavlin 51 =head2 ram
100    
101     Read series of bytes into memory without MMU interaction
102    
103     my @code = $emu->ram( 0xc000, 0xc1000 );
104    
105     =cut
106    
107     sub ram {
108     my $self = shift;
109     my ( $from, $to ) = @_;
110     warn sprintf("## M6502::ram(%04x,%04x)\n", $from, $to) if $self->debug;
111     return @mem[ $from .. $to ];
112     }
113    
114 dpavlin 31 =head2 write_chunk
115    
116 dpavlin 42 Low-level update of memory, overriding user specified MMU functions C<read> and C<write>
117    
118 dpavlin 31 $emu->write_chunk( $address, $chunk_of_data );
119    
120     =cut
121    
122     sub write_chunk {
123     my ($self, $addr, $chunk) = @_;
124     my $len = length($chunk);
125     splice @mem, $addr, $len, unpack('C*', $chunk);
126     }
127    
128 dpavlin 42 =head2 prompt
129    
130     Call this after C<< $run_for >> cycles have been run on processor
131    
132     =cut
133    
134     sub prompt {
135     warn "prompt -- you should override this\n";
136     return 1;
137     }
138    
139 dpavlin 38 =head2 push_R
140    
141     called by C<perl.c> to push changes in registars back to perl variables
142    
143     =cut
144    
145     sub push_R {
146 dpavlin 50 warn "## M6502::push_R(",dump(@_),")\n" if $debug;
147 dpavlin 74 ( $A, $P, $X, $Y, $S, $PC, $IPeriod, $ICount, $IRequest, $IAutoReset, $TrapBadOps, $Trap, $Trace ) = @_;
148 dpavlin 38 dump_R();
149     }
150    
151     =head2 dump_R
152    
153 dpavlin 68 helper function which dumps registers in humanly readable form
154 dpavlin 38
155 dpavlin 68 my $dump = dump_R;
156    
157 dpavlin 38 =cut
158    
159     sub dump_R {
160 dpavlin 74 my $dump = sprintf(" PC: %04x A:%02x P:%02x X:%02x Y:%02x S:%02x "
161     . "IPeriod:%d ICount:%d IRequest:%02x IAutoReset:%02x TrapBadOps:%d Trap:%d Trace:%d"
162     . "\n",
163     $PC, $A, $P, $X, $Y, $S, $IPeriod, $ICount, $IRequest, $IAutoReset, $TrapBadOps, $Trap, $Trace,
164     );
165 dpavlin 68 warn "## M6502::dump_R $dump" if $debug;
166     return $dump;
167 dpavlin 38 }
168    
169 dpavlin 55 =head1 SEE ALSO
170 dpavlin 54
171 dpavlin 55 L<Orao> is sample implementation using this module
172    
173 dpavlin 54 =head1 AUTHOR
174    
175     Dobrica Pavlinusic, C<< <dpavlin@rot13.org> >>
176    
177     =head1 COPYRIGHT & LICENSE
178    
179     Copyright 2007 Dobrica Pavlinusic, All Rights Reserved.
180    
181     This program is free software; you can redistribute it and/or modify it
182     under the same terms as Perl itself.
183    
184     =cut
185 dpavlin 24 1;

  ViewVC Help
Powered by ViewVC 1.1.26