/[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

Contents of /M6502/perl.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 84 - (show annotations)
Wed Aug 1 22:01:15 2007 UTC (16 years, 9 months ago) by dpavlin
File MIME type: text/plain
File size: 5678 byte(s)
commented enough code so that my minimal example doesn't segfault
1 #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 void pull_R(M6502 *R) {
11 R->A = SvIV( get_sv("M6502::A", FALSE) );
12 R->P = SvIV( get_sv("M6502::P", FALSE) );
13 R->X = SvIV( get_sv("M6502::X", FALSE) );
14 R->Y = SvIV( get_sv("M6502::Y", FALSE) );
15 R->S = SvIV( get_sv("M6502::S", FALSE) );
16 R->PC.W = SvIV( get_sv("M6502::PC", FALSE) );
17 R->IPeriod = SvIV( get_sv("M6502::IPeriod", FALSE) );
18 R->IRequest = SvIV( get_sv("M6502::IRequest", FALSE) );
19 R->IAutoReset = SvIV( get_sv("M6502::IAutoReset", FALSE) );
20 R->TrapBadOps = SvIV( get_sv("M6502::TrapBadOps", FALSE) );
21 R->Trap = SvIV( get_sv("M6502::Trap", FALSE) );
22 R->Trace = SvIV( get_sv("M6502::Trace", FALSE) );
23 printf("pull_R finished\n");
24 dump_R;
25 }
26
27 void push_R(M6502 *R) {
28 dSP;
29 ENTER;
30 SAVETMPS;
31 PUSHMARK(SP);
32 XPUSHs( sv_2mortal( newSViv( R->A ) ) );
33 XPUSHs( sv_2mortal( newSViv( R->P ) ) );
34 XPUSHs( sv_2mortal( newSViv( R->X ) ) );
35 XPUSHs( sv_2mortal( newSViv( R->Y ) ) );
36 XPUSHs( sv_2mortal( newSViv( R->S ) ) );
37 XPUSHs( sv_2mortal( newSViv( R->PC.W ) ) );
38 XPUSHs( sv_2mortal( newSViv( R->IPeriod ) ) );
39 XPUSHs( sv_2mortal( newSViv( R->ICount ) ) );
40 XPUSHs( sv_2mortal( newSViv( R->IRequest ) ) );
41 XPUSHs( sv_2mortal( newSViv( R->IAutoReset ) ) );
42 XPUSHs( sv_2mortal( newSViv( R->TrapBadOps ) ) );
43 XPUSHs( sv_2mortal( newSViv( R->Trap ) ) );
44 XPUSHs( sv_2mortal( newSViv( R->Trace ) ) );
45 PUTBACK;
46 call_pv("M6502::push_R", G_DISCARD );
47 printf("push_R called\n");
48 dump_R;
49 FREETMPS;
50 LEAVE;
51 }
52
53 byte Debug6502(M6502 *R) {
54 dump_R;
55 return 1; // continue emulation
56 }
57
58 /** Rd6502()/Wr6502/Op6502() *********************************/
59 /** These functions are called when access to RAM occurs. **/
60 /** They allow to control memory access. Op6502 is the same **/
61 /** as Rd6502, but used to read *opcodes* only, when many **/
62 /** checks can be skipped to make it fast. It is only **/
63 /** required if there is a #define FAST_RDOP. **/
64 /************************************ TO BE WRITTEN BY USER **/
65
66 byte mem(word Addr) {
67 byte byte;
68 int count;
69 debugf(("mem(%04x)\n", Addr));
70 dSP;
71 ENTER;
72 SAVETMPS;
73 PUSHMARK(SP);
74 XPUSHs( sv_2mortal( newSViv( Addr ) ) );
75 PUTBACK;
76 count = call_pv("M6502::read", G_ARRAY | G_EVAL );
77 debugf(("got %d values\n", count));
78 SPAGAIN;
79 if (SvTrue(ERRSV)) {
80 display_message("ERROR: %s", SvPV_nolen( ERRSV ) );
81 exit(1);
82 }
83 if ( count != 1 ) {
84 printf("expect 1 return value, got %d", count);
85 exit(1);
86 }
87 SV *sv;
88 sv = POPs;
89 byte = SvIV(sv);
90 FREETMPS;
91 LEAVE;
92 debugf(("mem(%04x) = %02x\n", Addr, byte));
93 return byte;
94 }
95
96 byte Rd6502(register word Addr) {
97 byte Value;
98 // Value = mem(Addr);
99 Value = 0x42;
100 debugf(("Rd6502(%04x) = %02x\n", Addr, Value));
101 return Value;
102 }
103
104 void Wr6502(register word Addr,register byte Value) {
105 debugf(("Wr6502(%04x,%02x)\n", Addr, Value));
106 dSP;
107 ENTER;
108 SAVETMPS;
109 PUSHMARK(SP);
110 XPUSHs( sv_2mortal( newSViv( Addr ) ) );
111 XPUSHs( sv_2mortal( newSViv( Value ) ) );
112 PUTBACK;
113 call_pv("Arch::write", G_DISCARD );
114 FREETMPS;
115 LEAVE;
116 }
117
118 byte Op6502(register word Addr) {
119 byte Op;
120 Op = mem(Addr);
121 debugf(("Op6502(%04x,%02x) PC:%04x\n", Addr, Op, R->PC.W));
122 return Op;
123 }
124
125 /** Loop6502() ***********************************************/
126 /** 6502 emulation calls this function periodically to **/
127 /** check if the system hardware requires any interrupts. **/
128 /** This function must return one of following values: **/
129 /** INT_NONE, INT_IRQ, INT_NMI, or INT_QUIT to exit the **/
130 /** emulation loop. **/
131 /************************************ TO BE WRITTEN BY USER **/
132
133 int hw_int = INT_NONE;
134
135 byte Loop6502(register M6502 *R) {
136 debugf(("Loop6502\n"));
137 dump_R;
138 return hw_int;
139 }
140
141 /** Patch6502() **********************************************/
142 /** Emulation calls this function when it encounters an **/
143 /** unknown opcode. This can be used to patch the code to **/
144 /** emulate BIOS calls, such as disk and tape access. The **/
145 /** function should return 1 if the exception was handled, **/
146 /** or 0 if the opcode was truly illegal. **/
147 /************************************ TO BE WRITTEN BY USER **/
148 byte Patch6502(register byte Op,register M6502 *R) {
149 debugf(("Patch6502(%02x)\n", Op));
150 dump_R;
151 hw_int = INT_QUIT;
152 return 0;
153 }
154
155 void run_forever(void) {
156 printf("entered run_forever\n");
157
158 R = malloc(sizeof(M6502));
159 if (!R) {
160 printf("can't alloc %d bytes for M6502", sizeof(M6502));
161 exit(1);
162 }
163
164 printf("reset CPU\n");
165 Reset6502(R);
166
167 printf("call Arch::init\n");
168 dSP;
169 PUSHMARK(SP);
170 call_pv("Arch::init", G_DISCARD | G_NOARGS );
171 FREETMPS;
172 LEAVE;
173
174 int cycles = 1;
175 while ( cycles ) {
176 dSP;
177 PUSHMARK(SP);
178 call_pv("Arch::cli", G_DISCARD | G_NOARGS );
179 pull_R(R);
180 FREETMPS;
181 LEAVE;
182 cycles = SvIV( get_sv("M6502::run_for", FALSE) );
183 if ( cycles > 0 ) {
184 printf("run CPU for %d cycles\n", cycles);
185 dump_R;
186 //Run6502(R);
187 Exec6502(R, cycles);
188 dump_R;
189 push_R(R);
190 printf("end of %d cycles CPU run\n", cycles);
191 } else {
192 printf("no cpu cycles set for run\n");
193 cycles = 1; // never exit, prevents segfault
194 }
195 }
196 free(R);
197 }
198
199 /**
200 * main code
201 *
202 **/
203
204 int main(int argc, char **argv) {
205 char *command_line[] = {"", "-e", EMU_START };
206 my_perl = perl_alloc();
207 perl_construct(my_perl);
208 if (perl_parse(my_perl, xs_init, 3, command_line, (char **)NULL)) {
209 printf("Failed to parse initial: %s\n", EMU_START );
210 return 0;
211 }
212 perl_run(my_perl);
213 if (SvTRUE(ERRSV)) {
214 printf("Failed to execute\n");
215 return 0;
216 } else {
217 run_forever();
218 }
219 perl_destruct(my_perl);
220 perl_free(my_perl);
221 return 0;
222 }

  ViewVC Help
Powered by ViewVC 1.1.26