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

Diff of /M6502/M6502.xs

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 82 by dpavlin, Wed Aug 1 21:40:17 2007 UTC revision 108 by dpavlin, Fri Aug 3 09:18:08 2007 UTC
# Line 7  Line 7 
7  #include "M6502.h"  #include "M6502.h"
8  #include "config.h"  #include "config.h"
9    
10  M6502 *R;  M6502 *R = NULL;
11    int debug = 0;
12    
13  void  byte opCache[CACHE_SIZE];
14  run (void) {  
15          debugf(("M6502::run"));  void update_C_R(void) {
16          run_forever();          R->A = SvIV( get_sv("M6502::A", FALSE) );
17            R->P = SvIV( get_sv("M6502::P", FALSE) );
18            R->X = SvIV( get_sv("M6502::X", FALSE) );
19            R->Y = SvIV( get_sv("M6502::Y", FALSE) );
20            R->S = SvIV( get_sv("M6502::S", FALSE) );
21            R->PC.W = SvIV( get_sv("M6502::PC", FALSE) );
22            R->IPeriod = SvIV( get_sv("M6502::IPeriod", FALSE) );
23            R->IRequest = SvIV( get_sv("M6502::IRequest", FALSE) );
24            R->IAutoReset = SvIV( get_sv("M6502::IAutoReset", FALSE) );
25            R->TrapBadOps = SvIV( get_sv("M6502::TrapBadOps", FALSE) );
26            R->Trap = SvIV( get_sv("M6502::Trap", FALSE) );
27            R->Trace = SvIV( get_sv("M6502::Trace", FALSE) );
28            debugf(("pull_R finished"));
29            dump_R;
30  }  }
31    
32  void  void update_perl_R(void) {
33            debugf(("update_perl_R"));
34            dSP;
35            ENTER;
36            SAVETMPS;
37            PUSHMARK(SP);
38            XPUSHs( sv_2mortal( newSViv( R->A ) ) );
39            XPUSHs( sv_2mortal( newSViv( R->P ) ) );
40            XPUSHs( sv_2mortal( newSViv( R->X ) ) );
41            XPUSHs( sv_2mortal( newSViv( R->Y ) ) );
42            XPUSHs( sv_2mortal( newSViv( R->S ) ) );
43            XPUSHs( sv_2mortal( newSViv( R->PC.W ) ) );
44            XPUSHs( sv_2mortal( newSViv( R->IPeriod ) ) );
45            XPUSHs( sv_2mortal( newSViv( R->ICount ) ) );
46            XPUSHs( sv_2mortal( newSViv( R->IRequest ) ) );
47            XPUSHs( sv_2mortal( newSViv( R->IAutoReset ) ) );
48            XPUSHs( sv_2mortal( newSViv( R->TrapBadOps ) ) );
49            XPUSHs( sv_2mortal( newSViv( R->Trap ) ) );
50            XPUSHs( sv_2mortal( newSViv( R->Trace ) ) );
51            PUTBACK;
52            call_pv("M6502::_update_perl_R", G_DISCARD );
53            debugf(("_update_perl_R returned to C"));
54            dump_R;
55            FREETMPS;
56            LEAVE;
57    }
58    
59    /** Debug6502() **********************************************/
60    
61    byte Debug6502(M6502 *R) {
62            dump_R;
63            return 1; // continue emulation
64    }
65    
66    /** Rd6502()/Wr6502/Op6502() *********************************/
67    /** These functions are called when access to RAM occurs.   **/
68    /** They allow to control memory access. Op6502 is the same **/
69    /** as Rd6502, but used to read *opcodes* only, when many   **/
70    /** checks can be skipped to make it fast. It is only       **/
71    /** required if there is a #define FAST_RDOP.               **/
72    /************************************ TO BE WRITTEN BY USER **/
73    
74    byte mem(word Addr) {
75            byte byte;
76            int count;
77            debugf(("mem(%04x)", Addr));
78            dSP;
79            ENTER;
80            SAVETMPS;
81            PUSHMARK(SP);
82            XPUSHs( sv_2mortal( newSViv( Addr ) ) );
83            PUTBACK;
84            count = call_pv("M6502::_read", G_ARRAY | G_EVAL );
85            debugf(("got %d values", count));
86            SPAGAIN;
87            if (SvTRUE(ERRSV)) {
88                    printf("ERROR: %s", SvPV_nolen( ERRSV ) );
89                    exit(1);
90            }
91            if ( count != 1 ) {
92                    printf("expect 1 return value, got %d", count);
93                    exit(1);
94            }
95            SV *sv;
96            sv = POPs;
97            byte = SvIV(sv);
98            FREETMPS;
99            LEAVE;
100            debugf(("mem(%04x) = %02x", Addr, byte));
101            opCache[Addr] = byte;
102            return byte;
103    }
104    
105    byte Rd6502(register word Addr) {
106            byte Value;
107            Value = mem(Addr);
108            debugf(("Rd6502(%04x) = %02x", Addr, Value));
109            return Value;
110    }
111    
112    void Wr6502(register word Addr,register byte Value) {
113            debugf(("Wr6502(%04x,%02x)", Addr, Value));
114            opCache[Addr] = Value;
115            dSP;
116            ENTER;
117            SAVETMPS;
118            PUSHMARK(SP);
119            XPUSHs( sv_2mortal( newSViv( Addr ) ) );
120            XPUSHs( sv_2mortal( newSViv( Value ) ) );
121            PUTBACK;
122            call_pv("M6502::_write", G_DISCARD );
123            FREETMPS;
124            LEAVE;
125    }
126    
127    byte Op6502(register word Addr) {
128            byte Op;
129            if ( opCache[Addr] ) return opCache[Addr];
130            Op = mem(Addr);
131            debugf(("Op6502(%04x,%02x) PC:%04x", Addr, Op, R->PC.W));
132            return Op;
133    }
134    
135    /** Loop6502() ***********************************************/
136    /** 6502 emulation calls this function periodically to      **/
137    /** check if the system hardware requires any interrupts.   **/
138    /** This function must return one of following values:      **/
139    /** INT_NONE, INT_IRQ, INT_NMI, or INT_QUIT to exit the     **/
140    /** emulation loop.                                         **/
141    /************************************ TO BE WRITTEN BY USER **/
142    
143    int hw_int = INT_NONE;
144    
145    byte Loop6502(register M6502 *R) {
146            debugf(("Loop6502"));
147            dump_R;
148            return hw_int;
149    }
150    
151    /** Patch6502() **********************************************/
152    /** Emulation calls this function when it encounters an     **/
153    /** unknown opcode. This can be used to patch the code to   **/
154    /** emulate BIOS calls, such as disk and tape access. The   **/
155    /** function should return 1 if the exception was handled,  **/
156    /** or 0 if the opcode was truly illegal.                   **/
157    /************************************ TO BE WRITTEN BY USER **/
158    byte Patch6502(register byte Op,register M6502 *R) {
159            debugf(("Patch6502(%02x)", Op));
160            dump_R;
161            hw_int = INT_QUIT;
162            return 0;
163    }
164    
165    /*************************************************************/
166    
167    int
168  reset (void) {  reset (void) {
169          debugf(("M6502::reset called"));          debugf(("M6502::reset called"));
170            if ( ! R ) {
171                    debugf(("allocating space for R"));
172                    R = malloc(sizeof(M6502));
173                    if (!R) {
174                            PerlIO_stdoutf("can't alloc %d bytes for M6502", sizeof(M6502));
175                            exit(1);
176                    }
177                    memset( opCache, 0, sizeof(opCache) );
178            }
179          Reset6502(R);          Reset6502(R);
180            debugf(("Reset6502 over"));
181            update_perl_R();
182          dump_R;          dump_R;
183            return 1;
184    }
185    
186    int exec(int cycles) {
187            int left;
188            debugf(("exec for %d cycles", cycles));
189    
190            if (!R) reset();
191    
192            update_C_R();
193            left = Exec6502(R, cycles);
194            update_perl_R();
195            debugf(("end of %d cycles CPU run\n", cycles));
196            return left;
197    }
198    
199    int set_debug(int state) {
200            debug = state;
201            return debug;
202    }
203    
204    int get_debug(void) {
205            return debug;
206  }  }
207    
208  MODULE = M6502          PACKAGE = M6502  MODULE = M6502          PACKAGE = M6502
209    
210  PROTOTYPES: DISABLE  PROTOTYPES: DISABLE
211    
212    int
213    set_debug(int state)
214    
215    int
216    get_debug()
217    
218    int
219    reset()
220    
221  void  void
222  run()  update_C_R()
223    
224  void  void
225  reset()  update_perl_R()
226    
227    int
228    exec(int cycles)

Legend:
Removed from v.82  
changed lines
  Added in v.108

  ViewVC Help
Powered by ViewVC 1.1.26