OSDN Git Service

[VM] TRY:Use namespace {VMNAME} to separate around VMs. This feature still apply...
[csp-qt/common_source_project-fm7.git] / source / src / vm / pyuta / memory.cpp
1 /*
2         TOMY PyuTa Emulator 'ePyuTa'
3
4         Author : Takeda.Toshiya
5         Date   : 2007.07.15 -
6
7         [ memory ]
8 */
9
10
11 #include "./memory.h"
12 #include "../datarec.h"
13 #include "../tms9995.h"
14
15 namespace PYUTA {
16 #define SET_BANK(s, e, w, r) { \
17         int sb = (s) >> 12, eb = (e) >> 12; \
18         for(int i = sb; i <= eb; i++) { \
19                 if((w) == wdmy) { \
20                         wbank[i] = wdmy; \
21                 } else { \
22                         wbank[i] = (w) + 0x1000 * (i - sb); \
23                 } \
24                 if((r) == rdmy) { \
25                         rbank[i] = rdmy; \
26                 } else { \
27                         rbank[i] = (r) + 0x1000 * (i - sb); \
28                 } \
29         } \
30 }
31
32 #define ENABLE_CART() { \
33         if(ctype == 3) { \
34                 SET_BANK(0x0000, 0x3fff, wdmy, ipl); \
35                 SET_BANK(0x4000, 0xbfff, wdmy, cart); \
36         } else { \
37                 SET_BANK(0x0000, 0x7fff, wdmy, ipl); \
38                 SET_BANK(0x8000, 0xbfff, wdmy, cart); \
39         } \
40         cart_enabled = true; \
41 }
42
43 #define DISABLE_CART() { \
44         SET_BANK(0x0000, 0x7fff, wdmy, ipl); \
45         SET_BANK(0x8000, 0xbfff, wdmy, basic); \
46         cart_enabled = false; \
47 }
48
49 void MEMORY::initialize()
50 {
51         memset(ipl, 0xff, sizeof(ipl));
52         memset(basic, 0xff, sizeof(basic));
53         memset(cart, 0xff, sizeof(cart));
54         memset(rdmy, 0xff, sizeof(rdmy));
55         
56         // load rom images
57         FILEIO* fio = new FILEIO();
58         if(fio->Fopen(create_local_path(_T("IPL.ROM")), FILEIO_READ_BINARY)) {
59                 fio->Fread(ipl, sizeof(ipl), 1);
60                 fio->Fclose();
61         }
62         if(fio->Fopen(create_local_path(_T("BASIC.ROM")), FILEIO_READ_BINARY)) {
63                 fio->Fread(basic, sizeof(basic), 1);
64                 fio->Fclose();
65                 has_extrom = true;
66         } else {
67                 has_extrom = false;
68         }
69         delete fio;
70         
71         // set memory map
72         DISABLE_CART();
73         SET_BANK(0xc000, 0xffff, wdmy, rdmy);
74         
75         // get keyboard and joystick buffers
76         key = emu->get_key_buffer();
77         joy = emu->get_joy_buffer();
78         
79         ctype = 0;
80 }
81
82 void MEMORY::reset()
83 {
84         cmt_signal = cmt_remote = false;
85 }
86
87 void MEMORY::write_data8(uint32_t addr, uint32_t data)
88 {
89         addr &= 0xffff;
90         if(addr < 0xe000) {
91                 wbank[addr >> 12][addr & 0xfff] = data;
92         } else if(addr == 0xe000) {
93                 d_vdp->write_io8(0, data);
94         } else if(addr == 0xe002) {
95                 d_vdp->write_io8(1, data);
96         } else if(addr == 0xe108 && has_extrom) {
97                 DISABLE_CART();
98         } else if(addr == 0xe10c && has_extrom) {
99                 ENABLE_CART();
100         } else if(addr == 0xe810) {
101                 // printer data
102         } else if(addr == 0xe840) {
103                 // printer strobe
104         } else if(addr == 0xe200) {
105                 d_psg->write_io8(0, data);
106         } else if(0xee00 <= addr && addr <= 0xeeff) {
107                 // cmt
108                 if(!(addr & 0x1f)) {
109                         bool signal = ((addr & 0x20) != 0);
110                         bool remote = (data == 0);
111                         switch((addr >> 6) & 3) {
112                         case 0:
113                                 if(cmt_signal != signal) {
114                                         d_cmt->write_signal(SIG_DATAREC_MIC, signal ? 1 : 0, 1);
115                                         cmt_signal = signal;
116                                 }
117                                 break;
118                         case 1:
119                                 if(cmt_remote != remote) {
120                                         if(!remote) {
121                                                 d_cpu->write_signal(SIG_TMS9995_INT4, 0, 1);
122                                         }
123                                         d_cmt->write_signal(SIG_DATAREC_REMOTE, remote ? 1 : 0, 1);
124                                         cmt_remote = remote;
125                                 }
126                                 break;
127                         }
128                 }
129         }
130 }
131
132 uint32_t MEMORY::read_data8(uint32_t addr)
133 {
134         uint32_t val = 0;
135         
136         addr &= 0xffff;
137         if(addr < 0xe000) {
138                 return rbank[addr >> 12][addr & 0xfff];
139         } else if(addr == 0xe000) {
140                 return d_vdp->read_io8(0);
141         } else if(addr == 0xe002) {
142                 return d_vdp->read_io8(1);
143         } else if(addr == 0xe110) {
144                 return 0;       // tutor 0x42 ???
145         } else if(addr == 0xe800) {
146                 // PyuTa Jr. JOY1
147                 if(joy[0] & 0x10) val |= 0x04;  // JOY1 B1
148                 if(joy[0] & 0x20) val |= 0x08;  // JOY1 B2
149                 if(joy[0] & 0x02) val |= 0x10;  // JOY1 DOWN
150                 if(joy[0] & 0x04) val |= 0x20;  // JOY1 LEFT
151                 if(joy[0] & 0x01) val |= 0x40;  // JOY1 UP
152                 if(joy[0] & 0x08) val |= 0x80;  // JOY1 RIGHT
153                 return val;
154         } else if(addr == 0xe820) {
155                 // printer busy
156                 return 0;
157         } else if(addr == 0xea00) {
158                 // PyuTa Jr. KEY
159                 if(key[0x0d]             ) val |= 0x04; // RETURN
160                 if(key[0x20]             ) val |= 0x08; // PALLETE -> SPACE
161                 if(key[0x71]             ) val |= 0x10; // MOD -> F2
162                 if(key[0x70]             ) val |= 0x20; // MON -> F1
163                 if(key[0x31] || key[0x61]) val |= 0x40; // 1
164                 if(key[0x32] || key[0x62]) val |= 0x80; // 2
165                 return val;
166         } else if(addr == 0xec00) {
167                 // PyuTa Jr. KEY
168                 if(key[0x5a]) val |= 0x04;      // COLOR SELECT << -> Z
169                 if(key[0x58]) val |= 0x08;      // COLOR SELECT >> -> X
170                 if(key[0x25]) val |= 0x10;      // LEFT
171                 if(key[0x26]) val |= 0x20;      // UP
172                 if(key[0x28]) val |= 0x40;      // DOWN
173                 if(key[0x27]) val |= 0x80;      // RIGHT
174                 return val;
175         } else if(addr == 0xee00) {
176                 // PyuTa Jr. JOY2
177                 if(joy[1] & 0x10) val |= 0x04;  // JOY2 B1
178                 if(joy[1] & 0x20) val |= 0x08;  // JOY2 B2
179                 if(joy[1] & 0x02) val |= 0x10;  // JOY2 DOWN
180                 if(joy[1] & 0x04) val |= 0x20;  // JOY2 LEFT
181                 if(joy[1] & 0x01) val |= 0x40;  // JOY2 UP
182                 if(joy[1] & 0x08) val |= 0x80;  // JOY2 RIGHT
183                 return val;
184         } else {
185                 return 0xff;    // pull up ?
186         }
187 }
188
189 void MEMORY::write_io8(uint32_t addr, uint32_t data)
190 {
191         // CRU OUT
192 }
193
194 uint32_t MEMORY::read_io8(uint32_t addr)
195 {
196         // CRU IN
197         uint32_t val = 0;
198         
199         switch(addr) {
200         case 0xec0:
201                 if(key[0x31] || key[0x61]) val |= 0x01; // 1
202                 if(key[0x32] || key[0x62]) val |= 0x02; // 2
203                 if(key[0x51]             ) val |= 0x04; // Q
204                 if(key[0x57]             ) val |= 0x08; // W
205                 if(key[0x41]             ) val |= 0x10; // A
206                 if(key[0x53]             ) val |= 0x20; // S
207                 if(key[0x5a]             ) val |= 0x40; // Z
208                 if(key[0x58]             ) val |= 0x80; // X
209                 return val;
210         case 0xec1:
211                 if(key[0x33] || key[0x63]) val |= 0x01; // 3
212                 if(key[0x34] || key[0x64]) val |= 0x02; // 4
213                 if(key[0x45]             ) val |= 0x04; // E
214                 if(key[0x52]             ) val |= 0x08; // R
215                 if(key[0x44]             ) val |= 0x10; // D
216                 if(key[0x46]             ) val |= 0x20; // F
217                 if(key[0x43]             ) val |= 0x40; // C
218                 if(key[0x56]             ) val |= 0x80; // V
219                 return val;
220         case 0xec2:
221                 if(key[0x35] || key[0x65]) val |= 0x01; // 5
222                 if(key[0x36] || key[0x66]) val |= 0x02; // 6
223                 if(key[0x54]             ) val |= 0x04; // T
224                 if(key[0x59]             ) val |= 0x08; // Y
225                 if(key[0x47]             ) val |= 0x10; // G
226                 if(key[0x48]             ) val |= 0x20; // H
227                 if(key[0x42]             ) val |= 0x40; // B
228                 if(key[0x4e]             ) val |= 0x80; // N
229                 return val;
230         case 0xec3:
231                 if(key[0x37] || key[0x67]) val |= 0x01; // 7
232                 if(key[0x38] || key[0x68]) val |= 0x02; // 8
233                 if(key[0x39] || key[0x69]) val |= 0x04; // 9
234                 if(key[0x55]             ) val |= 0x08; // U
235                 if(key[0x49]             ) val |= 0x10; // I
236                 if(key[0x4a]             ) val |= 0x20; // J
237                 if(key[0x4b]             ) val |= 0x40; // K
238                 if(key[0x4d]             ) val |= 0x80; // M
239                 return val;
240         case 0xec4:
241                 if(key[0x30] || key[0x60]      ) val |= 0x01;   // 0
242                 if(key[0xbd]                   ) val |= 0x02;   // -
243                 if(key[0x4f] || (joy[0] & 0x10)) val |= 0x04;   // O    JOY1 B1
244                 if(key[0x50] || (joy[0] & 0x20)) val |= 0x08;   // P    JOY1 B2
245                 if(key[0x4c] || (joy[0] & 0x02)) val |= 0x10;   // L    JOY1 DOWN
246                 if(key[0xbb] || (joy[0] & 0x04)) val |= 0x20;   // ;    JOY1 LEFT
247                 if(key[0xbc] || (joy[0] & 0x01)) val |= 0x40;   // ,    JOY1 UP
248                 if(key[0xbe] || (joy[0] & 0x08)) val |= 0x80;   // .    JOY1 RIGHT
249                 return val;
250         case 0xec5:
251                 if(key[0xdc] || (joy[1] & 0x10)) val |= 0x04;   // YEN  JOY2 B1
252                 if(key[0xc0] || (joy[1] & 0x20)) val |= 0x08;   // @    JOY2 B2
253                 if(key[0xba] || (joy[1] & 0x02)) val |= 0x10;   // :    JOY2 DOWN
254                 if(key[0xdd] || (joy[1] & 0x04)) val |= 0x20;   // ]    JOY2 LEFT
255                 if(key[0xbf] || (joy[1] & 0x01)) val |= 0x40;   // /    JOY2 UP
256                 if(key[0xe2] || (joy[1] & 0x08)) val |= 0x80;   // _    JOY2 RIGHT
257                 return val;
258         case 0xec6:
259                 if(key[0x11]) val |= 0x02;      // EISUU -> CTRL
260                 if(key[0x10]) val |= 0x04;      // KIGOU -> SHIFT
261                 if(key[0x70]) val |= 0x08;      // MON -> F1
262                 if(key[0x0d]) val |= 0x10;      // RETURN
263                 if(key[0x71]) val |= 0x40;      // MOD -> F2
264                 if(key[0x20]) val |= 0x80;      // SPACE
265                 return val;
266         case 0xec7:
267                 if(key[0x25]) val |= 0x01;      // LEFT
268                 if(key[0x26]) val |= 0x02;      // UP
269                 if(key[0x28]) val |= 0x04;      // DOWN
270                 if(key[0x27]) val |= 0x08;      // RIGHT
271                 return val;
272         case 0xed0:
273                 // cmt
274                 return cmt_signal ? 1 : 0;
275         }
276         return 0xff;    // pull down ?
277 }
278
279 void MEMORY::write_signal(int id, uint32_t data, uint32_t mask)
280 {
281         // from cmt
282         bool signal = ((data & mask) != 0);
283         if(cmt_signal != signal) {
284                 if(cmt_remote) {
285                         d_cpu->write_signal(SIG_TMS9995_INT4, signal ? 1 : 0, 1);
286                 }
287                 cmt_signal = signal;
288         }
289 }
290
291 void MEMORY::open_cart(const _TCHAR* file_path)
292 {
293         // open cart
294         FILEIO* fio = new FILEIO();
295         
296         if(fio->Fopen(file_path, FILEIO_READ_BINARY)) {
297                 // 8kb
298                 ctype = fio->Fread(cart, 0x2000, 1);
299                 memcpy(cart + 0x2000, cart, 0x2000);
300                 // 16kb
301                 ctype += fio->Fread(cart + 0x2000, 0x2000, 1);
302                 // 32kb
303                 ctype += fio->Fread(cart + 0x4000, 0x4000, 1);
304                 fio->Fclose();
305                 
306                 ENABLE_CART();
307         }
308         delete fio;
309 }
310
311 void MEMORY::close_cart()
312 {
313         ctype = 0;
314         DISABLE_CART();
315 }
316
317 #define STATE_VERSION   1
318
319 bool MEMORY::process_state(FILEIO* state_fio, bool loading)
320 {
321         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
322                 return false;
323         }
324         if(!state_fio->StateCheckInt32(this_device_id)) {
325                 return false;
326         }
327         state_fio->StateBool(cmt_signal);
328         state_fio->StateBool(cmt_remote);
329         state_fio->StateBool(has_extrom);
330         state_fio->StateBool(cart_enabled);
331         state_fio->StateInt32(ctype);
332         
333         // post process
334         if(loading) {
335                 if(cart_enabled) {
336                         ENABLE_CART();
337                 } else {
338                         DISABLE_CART();
339                 }
340         }
341         return true;
342 }
343 }