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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 87 - (hide annotations)
Thu Aug 2 11:08:10 2007 UTC (16 years, 9 months ago) by dpavlin
File MIME type: text/plain
File size: 4221 byte(s)
- transfer debug state into C, added accesor M6502->debug();
- update_*_R functions to keep perl vars in sync with C
- tests
1 dpavlin 24 #include <EXTERN.h>
2     #include <perl.h>
3     #include "M6502.h"
4     #include "config.h"
5    
6     static PerlInterpreter *my_perl;
7    
8     static M6502 *R;
9    
10 dpavlin 81 byte Debug6502(M6502 *R) {
11     dump_R;
12     return 1; // continue emulation
13     }
14    
15 dpavlin 25 /** Rd6502()/Wr6502/Op6502() *********************************/
16     /** These functions are called when access to RAM occurs. **/
17     /** They allow to control memory access. Op6502 is the same **/
18     /** as Rd6502, but used to read *opcodes* only, when many **/
19     /** checks can be skipped to make it fast. It is only **/
20     /** required if there is a #define FAST_RDOP. **/
21     /************************************ TO BE WRITTEN BY USER **/
22    
23 dpavlin 28 byte mem(word Addr) {
24     byte byte;
25 dpavlin 27 int count;
26 dpavlin 85 debugf(("mem(%04x)", Addr));
27 dpavlin 27 dSP;
28     ENTER;
29     SAVETMPS;
30     PUSHMARK(SP);
31 dpavlin 28 XPUSHs( sv_2mortal( newSViv( Addr ) ) );
32 dpavlin 27 PUTBACK;
33 dpavlin 84 count = call_pv("M6502::read", G_ARRAY | G_EVAL );
34 dpavlin 85 debugf(("got %d values", count));
35 dpavlin 84 SPAGAIN;
36 dpavlin 87 if (SvTRUE(ERRSV)) {
37     printf("ERROR: %s", SvPV_nolen( ERRSV ) );
38 dpavlin 84 exit(1);
39     }
40 dpavlin 27 if ( count != 1 ) {
41     printf("expect 1 return value, got %d", count);
42     exit(1);
43     }
44     SV *sv;
45     sv = POPs;
46 dpavlin 28 byte = SvIV(sv);
47 dpavlin 27 FREETMPS;
48     LEAVE;
49 dpavlin 85 debugf(("mem(%04x) = %02x", Addr, byte));
50 dpavlin 28 return byte;
51     }
52    
53     byte Rd6502(register word Addr) {
54     byte Value;
55 dpavlin 84 // Value = mem(Addr);
56     Value = 0x42;
57 dpavlin 85 debugf(("Rd6502(%04x) = %02x", Addr, Value));
58 dpavlin 27 return Value;
59 dpavlin 25 }
60    
61     void Wr6502(register word Addr,register byte Value) {
62 dpavlin 85 debugf(("Wr6502(%04x,%02x)", Addr, Value));
63 dpavlin 27 dSP;
64     ENTER;
65     SAVETMPS;
66     PUSHMARK(SP);
67     XPUSHs( sv_2mortal( newSViv( Addr ) ) );
68     XPUSHs( sv_2mortal( newSViv( Value ) ) );
69     PUTBACK;
70 dpavlin 33 call_pv("Arch::write", G_DISCARD );
71 dpavlin 27 FREETMPS;
72     LEAVE;
73 dpavlin 25 }
74    
75     byte Op6502(register word Addr) {
76     byte Op;
77 dpavlin 28 Op = mem(Addr);
78 dpavlin 85 debugf(("Op6502(%04x,%02x) PC:%04x", Addr, Op, R->PC.W));
79 dpavlin 40 return Op;
80 dpavlin 25 }
81    
82     /** Loop6502() ***********************************************/
83     /** 6502 emulation calls this function periodically to **/
84     /** check if the system hardware requires any interrupts. **/
85     /** This function must return one of following values: **/
86     /** INT_NONE, INT_IRQ, INT_NMI, or INT_QUIT to exit the **/
87     /** emulation loop. **/
88     /************************************ TO BE WRITTEN BY USER **/
89 dpavlin 42
90     int hw_int = INT_NONE;
91    
92 dpavlin 25 byte Loop6502(register M6502 *R) {
93 dpavlin 85 debugf(("Loop6502"));
94 dpavlin 25 dump_R;
95 dpavlin 42 return hw_int;
96 dpavlin 25 }
97    
98     /** Patch6502() **********************************************/
99     /** Emulation calls this function when it encounters an **/
100     /** unknown opcode. This can be used to patch the code to **/
101     /** emulate BIOS calls, such as disk and tape access. The **/
102     /** function should return 1 if the exception was handled, **/
103     /** or 0 if the opcode was truly illegal. **/
104     /************************************ TO BE WRITTEN BY USER **/
105     byte Patch6502(register byte Op,register M6502 *R) {
106 dpavlin 85 debugf(("Patch6502(%02x)", Op));
107 dpavlin 25 dump_R;
108 dpavlin 66 hw_int = INT_QUIT;
109 dpavlin 28 return 0;
110 dpavlin 25 }
111    
112 dpavlin 80 void run_forever(void) {
113     printf("entered run_forever\n");
114    
115     R = malloc(sizeof(M6502));
116     if (!R) {
117     printf("can't alloc %d bytes for M6502", sizeof(M6502));
118     exit(1);
119     }
120    
121     printf("reset CPU\n");
122     Reset6502(R);
123    
124     printf("call Arch::init\n");
125     dSP;
126     PUSHMARK(SP);
127     call_pv("Arch::init", G_DISCARD | G_NOARGS );
128     FREETMPS;
129     LEAVE;
130    
131     int cycles = 1;
132     while ( cycles ) {
133     dSP;
134     PUSHMARK(SP);
135     call_pv("Arch::cli", G_DISCARD | G_NOARGS );
136 dpavlin 86 pull_R;
137 dpavlin 80 FREETMPS;
138     LEAVE;
139     cycles = SvIV( get_sv("M6502::run_for", FALSE) );
140     if ( cycles > 0 ) {
141     printf("run CPU for %d cycles\n", cycles);
142     dump_R;
143     //Run6502(R);
144     Exec6502(R, cycles);
145     dump_R;
146 dpavlin 86 push_R;
147 dpavlin 80 printf("end of %d cycles CPU run\n", cycles);
148     } else {
149     printf("no cpu cycles set for run\n");
150     cycles = 1; // never exit, prevents segfault
151     }
152     }
153     free(R);
154     }
155    
156 dpavlin 25 /**
157     * main code
158     *
159     **/
160    
161 dpavlin 24 int main(int argc, char **argv) {
162 dpavlin 30 char *command_line[] = {"", "-e", EMU_START };
163 dpavlin 24 my_perl = perl_alloc();
164     perl_construct(my_perl);
165 dpavlin 29 if (perl_parse(my_perl, xs_init, 3, command_line, (char **)NULL)) {
166 dpavlin 31 printf("Failed to parse initial: %s\n", EMU_START );
167 dpavlin 24 return 0;
168     }
169     perl_run(my_perl);
170     if (SvTRUE(ERRSV)) {
171     printf("Failed to execute\n");
172     return 0;
173     } else {
174 dpavlin 80 run_forever();
175 dpavlin 24 }
176     perl_destruct(my_perl);
177     perl_free(my_perl);
178     return 0;
179     }

  ViewVC Help
Powered by ViewVC 1.1.26