/[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 87 - (show annotations)
Thu Aug 2 11:08:10 2007 UTC (16 years, 8 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 #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 byte Debug6502(M6502 *R) {
11 dump_R;
12 return 1; // continue emulation
13 }
14
15 /** 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 byte mem(word Addr) {
24 byte byte;
25 int count;
26 debugf(("mem(%04x)", Addr));
27 dSP;
28 ENTER;
29 SAVETMPS;
30 PUSHMARK(SP);
31 XPUSHs( sv_2mortal( newSViv( Addr ) ) );
32 PUTBACK;
33 count = call_pv("M6502::read", G_ARRAY | G_EVAL );
34 debugf(("got %d values", count));
35 SPAGAIN;
36 if (SvTRUE(ERRSV)) {
37 printf("ERROR: %s", SvPV_nolen( ERRSV ) );
38 exit(1);
39 }
40 if ( count != 1 ) {
41 printf("expect 1 return value, got %d", count);
42 exit(1);
43 }
44 SV *sv;
45 sv = POPs;
46 byte = SvIV(sv);
47 FREETMPS;
48 LEAVE;
49 debugf(("mem(%04x) = %02x", Addr, byte));
50 return byte;
51 }
52
53 byte Rd6502(register word Addr) {
54 byte Value;
55 // Value = mem(Addr);
56 Value = 0x42;
57 debugf(("Rd6502(%04x) = %02x", Addr, Value));
58 return Value;
59 }
60
61 void Wr6502(register word Addr,register byte Value) {
62 debugf(("Wr6502(%04x,%02x)", Addr, Value));
63 dSP;
64 ENTER;
65 SAVETMPS;
66 PUSHMARK(SP);
67 XPUSHs( sv_2mortal( newSViv( Addr ) ) );
68 XPUSHs( sv_2mortal( newSViv( Value ) ) );
69 PUTBACK;
70 call_pv("Arch::write", G_DISCARD );
71 FREETMPS;
72 LEAVE;
73 }
74
75 byte Op6502(register word Addr) {
76 byte Op;
77 Op = mem(Addr);
78 debugf(("Op6502(%04x,%02x) PC:%04x", Addr, Op, R->PC.W));
79 return Op;
80 }
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
90 int hw_int = INT_NONE;
91
92 byte Loop6502(register M6502 *R) {
93 debugf(("Loop6502"));
94 dump_R;
95 return hw_int;
96 }
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 debugf(("Patch6502(%02x)", Op));
107 dump_R;
108 hw_int = INT_QUIT;
109 return 0;
110 }
111
112 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 pull_R;
137 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 push_R;
147 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 /**
157 * main code
158 *
159 **/
160
161 int main(int argc, char **argv) {
162 char *command_line[] = {"", "-e", EMU_START };
163 my_perl = perl_alloc();
164 perl_construct(my_perl);
165 if (perl_parse(my_perl, xs_init, 3, command_line, (char **)NULL)) {
166 printf("Failed to parse initial: %s\n", EMU_START );
167 return 0;
168 }
169 perl_run(my_perl);
170 if (SvTRUE(ERRSV)) {
171 printf("Failed to execute\n");
172 return 0;
173 } else {
174 run_forever();
175 }
176 perl_destruct(my_perl);
177 perl_free(my_perl);
178 return 0;
179 }

  ViewVC Help
Powered by ViewVC 1.1.26