1 /*--------------------------------------------------
2 TGB Dual - Gameboy Emulator -
3 Copyright (C) 2001 Hii
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 //---------------------------------------
21 // MBC エミュレーション部 (MBC1/2/3/5/7,HuC-1,MMM01,Rumble,RTC,Motion-Sensor,etc...)
22 // MBC emulation unit (MBC1/2/3/5/7,HuC-1,MMM01,Rumble,RTC,Motion-Sensor,etc...)
23
24 #include "gb.h"
25
mbc(gb * ref)26 mbc::mbc(gb *ref)
27 {
28 ref_gb=ref;
29
30 reset();
31 }
32
~mbc()33 mbc::~mbc()
34 {
35
36 }
37
reset()38 void mbc::reset()
39 {
40 ref_gb->get_rom()->set_first(0);
41 rom_page=ref_gb->get_rom()->get_rom();
42 sram_page=ref_gb->get_rom()->get_sram();
43
44 mbc1_16_8=true;
45 mbc1_dat=0;
46 ext_is_ram=true;
47
48 mbc7_adr=0;
49 mbc7_dat=0;
50 mbc7_write_enable=false;
51 mbc7_idle=false;
52 mbc7_cs=0;
53 mbc7_sk=0;
54 mbc7_state=0;
55 mbc7_buf=0;
56 mbc7_count=0;
57 mbc7_ret=0;
58
59 huc1_16_8=true;
60 huc1_dat=0;
61
62 if (ref_gb->get_rom()->get_info()->cart_type==0xFD){
63 ext_is_ram=false;
64 }
65 }
66
read(word adr)67 byte mbc::read(word adr)
68 {
69 return 0;
70 }
71
write(word adr,byte dat)72 void mbc::write(word adr,byte dat)
73 {
74 switch(ref_gb->get_rom()->get_info()->cart_type){
75 case 1:
76 case 2:
77 case 3:
78 mbc1_write(adr,dat);
79 break;
80 case 5:
81 case 6:
82 mbc2_write(adr,dat);
83 break;
84 case 0x0F:
85 case 0x10:
86 case 0x11:
87 case 0x12:
88 case 0x13:
89 mbc3_write(adr,dat);
90 break;
91 case 0x19:
92 case 0x1A:
93 case 0x1B:
94 case 0x1C:
95 case 0x1D:
96 case 0x1E:
97 mbc5_write(adr,dat);
98 break;
99 case 0x22:
100 mbc7_write(adr,dat);
101 break;
102 case 0xFD:
103 tama5_write(adr,dat);
104 break;
105 case 0xFE:
106 huc3_write(adr,dat);
107 break;
108 case 0xFF:
109 huc1_write(adr,dat);
110 break;
111 case 0x100:
112 mmm01_write(adr,dat);
113 break;
114 }
115 }
116
ext_read(word adr)117 byte mbc::ext_read(word adr)
118 {
119 switch(ref_gb->get_rom()->get_info()->cart_type){
120 case 1:
121 case 2:
122 case 3:
123 case 5:
124 case 6:
125 return 0;
126 case 0x0F:
127 case 0x10:
128 case 0x11:
129 case 0x12:
130 case 0x13:
131 // extern FILE *file;
132 // fprintf(file,"external read [%04X]\n",adr);
133 if (mbc3_latch){
134 switch(mbc3_timer){
135 case 8: return mbc3_sec;
136 case 9: return mbc3_min;
137 case 10: return mbc3_hour;
138 case 11: return mbc3_dayl;
139 case 12: return mbc3_dayh;
140 }
141 }
142 return ref_gb->get_renderer()->get_time(mbc3_timer);
143 case 0x19:
144 case 0x1A:
145 case 0x1B:
146 case 0x1C:
147 case 0x1D:
148 case 0x1E:
149 return 0;
150 case 0x22: // コロコロカービィ // Korokoro Kirby
151 switch(adr&0xa0f0)
152 {
153 case 0xA000:
154 return 0;
155 case 0xA010:
156 return 0;
157 case 0xA020:
158 return ref_gb->get_renderer()->get_sensor(true)&0xff;
159 case 0xA030:
160 return (ref_gb->get_renderer()->get_sensor(true)>>8)&0xf;
161 case 0xA040:
162 return ref_gb->get_renderer()->get_sensor(false)&0xff;
163 case 0xA050:
164 return (ref_gb->get_renderer()->get_sensor(false)>>8)&0xf;
165 case 0xA060:
166 return 0;
167 case 0xA070:
168 return 0;
169 case 0xA080:
170 return mbc7_ret;
171 }
172 return 0xff;
173 case 0xFD:
174 // extern FILE *file;
175 // fprintf(file,"%04X : TAMA5 ext_read %04X \n",ref_gb->get_cpu()->get_regs()->PC,adr);
176 return 1;
177 case 0xFE:
178 // extern FILE *file;
179 // fprintf(file,"%04X : HuC-3 ext_read %04X \n",ref_gb->get_cpu()->get_regs()->PC,adr);
180 return 1;
181 case 0xFF:
182 return 0;
183 }
184 return 0;
185 }
186
ext_write(word adr,byte dat)187 void mbc::ext_write(word adr,byte dat)
188 {
189 int i;
190
191 switch(ref_gb->get_rom()->get_info()->cart_type){
192 case 1:
193 case 2:
194 case 3:
195 case 5:
196 case 6:
197 case 0x19:
198 case 0x1A:
199 case 0x1B:
200 case 0x1C:
201 case 0x1D:
202 case 0x1E:
203 case 0xFF:
204 break;
205 case 0x0F:
206 case 0x10:
207 case 0x11:
208 case 0x12:
209 case 0x13:
210 ref_gb->get_renderer()->set_time(mbc3_timer,dat);
211 break;
212 case 0xFE: //HuC-3
213 // extern FILE *file;
214 // fprintf(file,"%04X : HuC-3 ext_write %04X <= %02X\n",ref_gb->get_cpu()->get_regs()->PC,adr,dat);
215 break;
216 case 0xFD: //TAMA5
217 // extern FILE *file;
218 // fprintf(file,"%04X : TAMA5 ext_write %04X <= %02X\n",ref_gb->get_cpu()->get_regs()->PC,adr,dat);
219 break;
220 case 0x22: // コロコロカービィ // Korokoro Kirby
221 if (adr==0xA080){
222 int bef_cs=mbc7_cs,bef_sk=mbc7_sk;
223
224 mbc7_cs=dat>>7;
225 mbc7_sk=(dat>>6)&1;
226
227 if (!bef_cs&&mbc7_cs){
228 if (mbc7_state==5){
229 if (mbc7_write_enable){
230 *(ref_gb->get_rom()->get_sram()+mbc7_adr*2)=mbc7_buf>>8;
231 *(ref_gb->get_rom()->get_sram()+mbc7_adr*2+1)=mbc7_buf&0xff;
232 //// fprintf(file,"書き込み完了\n");
233 // fprintf(file,"Write complete\n");
234 }
235 mbc7_state=0;
236 mbc7_ret=1;
237 //// fprintf(file,"書き込み受理 ステート:なし\n");
238 // fprintf(file,"State writing acceptance: no\n");
239 }
240 else{
241 mbc7_idle=true; // アイドル状態突入
242 mbc7_state=0;
243 //// fprintf(file,"アイドル状態突入 ステート:アイドル状態\n");
244 // fprintf(file,"Idle: idle state rush\n");
245 }
246 }
247
248 if (!bef_sk&&mbc7_sk){ // クロック立ち上がり // Rising edge of the clock
249 if (mbc7_idle){ // アイドル状態であれば // If idle
250 if (dat&0x02){
251 mbc7_idle=false; // アイドル状態解除 // Idle state release
252 mbc7_count=0;
253 mbc7_state=1;
254 //// fprintf(file,"アイドル状態解除 ステート:コマンド認識\n");
255 // fprintf(file,"Command recognition: release idle state\n");
256 }
257 }
258 else{
259 switch(mbc7_state){
260 case 1: // コマンド受付 // Command reception
261 mbc7_buf<<=1;
262 mbc7_buf|=(dat&0x02)?1:0;
263 mbc7_count++;
264 if (mbc7_count==2){ // 受付終了 // Exit Reception
265 mbc7_state=2;
266 mbc7_count=0;
267 mbc7_op_code=mbc7_buf&3;
268 }
269 break;
270 case 2: // アドレス受信 // Address received
271 mbc7_buf<<=1;
272 mbc7_buf|=(dat&0x02)?1:0;
273 mbc7_count++;
274 if (mbc7_count==8){ // 受付終了 // Exit Reception
275 mbc7_state=3;
276 mbc7_count=0;
277 mbc7_adr=mbc7_buf&0xff;
278 if (mbc7_op_code==0){
279 if ((mbc7_adr>>6)==0){
280 //// fprintf(file,"書き込み消去禁止 ステート:なし\n");
281 // fprintf(file,"erasing state prohibited : No\n");
282 mbc7_write_enable=false;
283 mbc7_state=0;
284 }
285 else if ((mbc7_adr>>6)==3){
286 //// fprintf(file,"書き込み消去許可 ステート:なし\n");
287 // fprintf(file,"erasing the authorized state : No\n");
288 mbc7_write_enable=true;
289 mbc7_state=0;
290 }
291 }
292 else{
293 //// fprintf(file,"アドレス:%02X ステート:データ受信\n",mbc7_adr);
294 // fprintf(file,"Address: %02X State: Data reception\n",mbc7_adr);
295 }
296 }
297 break;
298 case 3: // データ // Data
299 mbc7_buf<<=1;
300 mbc7_buf|=(dat&0x02)?1:0;
301 mbc7_count++;
302
303 switch(mbc7_op_code){
304 case 0:
305 if (mbc7_count==16){
306 if ((mbc7_adr>>6)==0){
307 //// fprintf(file,"書き込み消去禁止 ステート:なし\n");
308 // fprintf(file,"erasing state prohibited : No\n");
309 mbc7_write_enable=false;
310 mbc7_state=0;
311 }
312 else if ((mbc7_adr>>6)==1){
313 if (mbc7_write_enable){
314 for (i=0;i<256;i++){
315 *(ref_gb->get_rom()->get_sram()+i*2)=mbc7_buf>>8;
316 *(ref_gb->get_rom()->get_sram()+i*2)=mbc7_buf&0xff;
317 }
318 }
319 //// fprintf(file,"全アドレス書き込み %04X ステート:なし\n",mbc7_buf);
320 // fprintf(file,"Write all addresses %04X State: No\n",mbc7_buf);
321 mbc7_state=5;
322 }
323 else if ((mbc7_adr>>6)==2){
324 if (mbc7_write_enable){
325 for (i=0;i<256;i++)
326 *(word*)(ref_gb->get_rom()->get_sram()+i*2)=0xffff;
327 }
328 //// fprintf(file,"全アドレス消去 ステート:なし\n");
329 // fprintf(file,"erased state all addresses : None\n");
330 mbc7_state=5;
331 }
332 else if ((mbc7_adr>>6)==3){
333 //// fprintf(file,"書き込み消去許可 ステート:なし\n");
334 // fprintf(file,"erasing the authorized state : No\n");
335 mbc7_write_enable=true;
336 mbc7_state=0;
337 }
338 mbc7_count=0;
339 }
340 break;
341 case 1:
342 if (mbc7_count==16){
343 //// fprintf(file,"書き込み [%02X]<-%04X ステート:書き込み待ちフレーム\n",mbc7_adr,mbc7_buf);
344 // fprintf(file,"Writing [%02X]<-%04X State: Frame waiting to be written\n",mbc7_adr,mbc7_buf);
345 mbc7_count=0;
346 mbc7_state=5;
347 mbc7_ret=0;
348 }
349 break;
350 case 2:
351 if (mbc7_count==1){
352 //// fprintf(file,"ダミー受信完了 ステート:読み出し可\n");
353 // fprintf(file,"Readable: State reception complete dummy\n");
354 mbc7_state=4;
355 mbc7_count=0;
356 mbc7_buf=(ref_gb->get_rom()->get_sram()[mbc7_adr*2]<<8)|(ref_gb->get_rom()->get_sram()[mbc7_adr*2+1]);
357 //// fprintf(file,"受信データ %04X\n",mbc7_buf);
358 // fprintf(file,"Received data %04X\n",mbc7_buf);
359 }
360 break;
361 case 3:
362 if (mbc7_count==16){
363 //// fprintf(file,"消去 [%02X] ステート:書き込み待ちフレーム\n",mbc7_adr,mbc7_buf);
364 // fprintf(file,"Elimination [%02X] State: Frame waiting to be written\n",mbc7_adr,mbc7_buf);
365 mbc7_count=0;
366 mbc7_state=5;
367 mbc7_ret=0;
368 mbc7_buf=0xffff;
369 }
370 break;
371 }
372 break;
373 }
374 }
375 }
376
377 if (bef_sk&&!mbc7_sk){ // クロック立ち下り // Falling clock
378 if (mbc7_state==4){ // 読み出し中 // While reading
379 mbc7_ret=(mbc7_buf&0x8000)?1:0;
380 mbc7_buf<<=1;
381 mbc7_count++;
382 //// fprintf(file,"読み出し中 %d ビット目\n",mbc7_count);
383 // fprintf(file,"While reading %dth bit\n",mbc7_count);
384 if (mbc7_count==16){
385 mbc7_count=0;
386 mbc7_state=0;
387 //// fprintf(file,"読み出し完了 ステート:なし\n");
388 // fprintf(file,"Read state complete: No\n");
389 }
390 }
391 }
392 }
393
394 break;
395 }
396 }
397
get_state()398 int mbc::get_state()
399 {
400 switch(ref_gb->get_rom()->get_info()->cart_type){
401 case 1:
402 case 2:
403 case 3:
404 return mbc1_dat|(mbc1_16_8?0x100:0);
405 case 5:
406 case 6:
407 return 0;
408 case 0x0F:
409 case 0x10:
410 case 0x11:
411 case 0x12:
412 case 0x13:
413 return (mbc3_timer&0xf)|((mbc3_latch&1)<<4)|((mbc3_sec&0x3f)<<5)|((mbc3_min&0x3f)<<11)|
414 ((mbc3_hour&0x1f)<<17)|(mbc3_dayl<<22)|((mbc3_dayh&1)<<30);
415 case 0x19:
416 case 0x1A:
417 case 0x1B:
418 case 0x1C:
419 case 0x1D:
420 case 0x1E:
421 return mbc5_dat;
422 case 0xFF:
423 return huc1_dat|(huc1_16_8?0x100:0);
424 default:
425 return 0;
426 }
427 }
428
set_state(int dat)429 void mbc::set_state(int dat)
430 {
431 switch(ref_gb->get_rom()->get_info()->cart_type){
432 case 1:
433 case 2:
434 case 3:
435 mbc1_dat=dat&0xFF;
436 mbc1_16_8=((dat>>8)&1?true:false);
437 break;
438 case 5:
439 case 6:
440 break;
441 case 0x0F:
442 case 0x10:
443 case 0x11:
444 case 0x12:
445 case 0x13:
446 mbc3_timer=dat&0x0F;
447 dat>>=4;
448 mbc3_latch=dat&1;
449 dat>>=1;
450 mbc3_sec=dat&0x3f;
451 dat>>=6;
452 mbc3_min=dat&0x3f;
453 dat>>=6;
454 mbc3_hour=dat&0x1f;
455 dat>>=5;
456 mbc3_dayl=dat&0xff;
457 dat>>=8;
458 mbc3_dayh=dat&1;
459 break;
460 case 0x19:
461 case 0x1A:
462 case 0x1B:
463 case 0x1C:
464 case 0x1D:
465 case 0x1E:
466 mbc5_dat=dat&0xFFFF;
467 break;
468 case 0xFF:
469 huc1_dat=dat&0xFF;
470 huc1_16_8=((dat>>8)&1?true:false);
471 break;
472 }
473 }
474
set_page(int rom,int sram)475 void mbc::set_page(int rom,int sram)
476 {
477 rom_page=ref_gb->get_rom()->get_rom()+rom*0x4000;
478 sram_page=ref_gb->get_rom()->get_sram()+sram*0x2000;
479 }
480
481 static int rom_size_tbl[]={2,4,8,16,32,64,128,256,512};
482 static int ram_size_tbl[]={0,1,1,4,16,8};
483
mbc1_write(word adr,byte dat)484 void mbc::mbc1_write(word adr,byte dat)
485 {
486 if (mbc1_16_8){//16/8モード
487 switch(adr>>13){
488 case 0:
489 break;
490 case 1:
491 mbc1_dat=(mbc1_dat&0x60)+(dat&0x1F);
492 rom_page=ref_gb->get_rom()->get_rom()+0x4000*((mbc1_dat==0?1:mbc1_dat)&(rom_size_tbl[ref_gb->get_rom()->get_info()->rom_size]-1))-0x4000;
493 break;
494 case 2:
495 mbc1_dat=((dat<<5)&0x60)+(mbc1_dat&0x1F);
496 rom_page=ref_gb->get_rom()->get_rom()+0x4000*((mbc1_dat==0?1:mbc1_dat)&(rom_size_tbl[ref_gb->get_rom()->get_info()->rom_size]-1))-0x4000;
497 break;
498 case 3:
499 if (dat&1)
500 mbc1_16_8=false;
501 else
502 mbc1_16_8=true;
503 // mbc1_dat=0;
504 break;
505 }
506 }
507 else{//4/32モード
508 switch(adr>>13){
509 case 0:
510 break;
511 case 1:
512 rom_page=ref_gb->get_rom()->get_rom()+0x4000*((dat==0?1:dat)&0x1F&(rom_size_tbl[ref_gb->get_rom()->get_info()->rom_size]-1))-0x4000;
513 break;
514 case 2:
515 sram_page=ref_gb->get_rom()->get_sram()+0x2000*(dat&3);
516 break;
517 case 3:
518 if (dat&1)
519 mbc1_16_8=false;
520 else
521 mbc1_16_8=true;
522 // mbc1_dat=0;
523 break;
524 }
525 }
526 }
527
mbc2_write(word adr,byte dat)528 void mbc::mbc2_write(word adr,byte dat)
529 {
530 if ((adr>=0x2000)&&(adr<=0x3FFF))
531 rom_page=ref_gb->get_rom()->get_rom()+0x4000*(((dat&0x0F)==0?1:dat&0x0F)-1);
532 }
533
mbc3_write(word adr,byte dat)534 void mbc::mbc3_write(word adr,byte dat)
535 {
536 switch(adr>>13){
537 case 0:
538 if (dat==0x0a)
539 ext_is_ram=true;
540 else{
541 ext_is_ram=false;
542 mbc3_timer=0;
543 }
544 break;
545 case 1:
546 rom_page=ref_gb->get_rom()->get_rom()+0x4000*((dat==0?1:dat)&0x7F&(rom_size_tbl[ref_gb->get_rom()->get_info()->rom_size]-1))-0x4000;
547 break;
548 case 2:
549 if (dat<8){
550 sram_page=ref_gb->get_rom()->get_sram()+0x2000*(dat&7&(ram_size_tbl[ref_gb->get_rom()->get_info()->ram_size]-1));
551 ext_is_ram=true;
552 }
553 else{
554 ext_is_ram=false;
555 mbc3_timer=dat&0x0F;
556 }
557 break;
558 case 3://RTCラッチ // RTC latch
559 if (dat==0){ // Latchはずす // Disconnect latch
560 mbc3_latch=0;
561 }
562 else if (dat==1){ // データをLatchする // Latch the data to
563 if (!mbc3_latch){
564 mbc3_sec=ref_gb->get_renderer()->get_time(8);
565 mbc3_min=ref_gb->get_renderer()->get_time(9);
566 mbc3_hour=ref_gb->get_renderer()->get_time(10);
567 mbc3_dayl=ref_gb->get_renderer()->get_time(11);
568 mbc3_dayh=ref_gb->get_renderer()->get_time(12);
569 }
570 mbc3_latch=1;
571 }
572
573 break;
574 }
575 }
576
mbc5_write(word adr,byte dat)577 void mbc::mbc5_write(word adr,byte dat)
578 {
579 switch(adr>>12){
580 case 0:
581 case 1:
582 break;
583 case 2:
584 mbc5_dat&=0x0100;
585 mbc5_dat|=dat;
586 rom_page=ref_gb->get_rom()->get_rom()+0x4000*(mbc5_dat&(rom_size_tbl[ref_gb->get_rom()->get_info()->rom_size]-1))-0x4000;
587 break;
588 case 3:
589 mbc5_dat&=0x00FF;
590 mbc5_dat|=(dat&1)<<8;
591 rom_page=ref_gb->get_rom()->get_rom()+0x4000*(mbc5_dat&(rom_size_tbl[ref_gb->get_rom()->get_info()->rom_size]-1))-0x4000;
592 break;
593 case 4:
594 case 5:
595 if (ref_gb->get_rom()->get_info()->cart_type==0x1C||ref_gb->get_rom()->get_info()->cart_type==0x1D||ref_gb->get_rom()->get_info()->cart_type==0x1E){//Rumble カートリッジ
596 sram_page=ref_gb->get_rom()->get_sram()+0x2000*(dat&0x07&(ram_size_tbl[ref_gb->get_rom()->get_info()->ram_size]-1));
597 if (dat&0x8)
598 ref_gb->get_renderer()->set_bibrate(true);
599 else
600 ref_gb->get_renderer()->set_bibrate(false);
601 }
602 else
603 sram_page=ref_gb->get_rom()->get_sram()+0x2000*(dat&0x0f&(ram_size_tbl[ref_gb->get_rom()->get_info()->ram_size]-1));
604 break;
605 }
606 }
607
mbc7_write(word adr,byte dat)608 void mbc::mbc7_write(word adr,byte dat)
609 {
610 switch(adr>>13){
611 case 0:
612 break;
613 case 1:
614 rom_page=ref_gb->get_rom()->get_rom()+0x4000*((dat==0?1:dat)&0x7F&(rom_size_tbl[ref_gb->get_rom()->get_info()->rom_size]-1))-0x4000;
615 // rom_page=ref_gb->get_rom()->get_rom()+0x4000*(dat&0x3f)-0x4000;
616 break;
617 case 2:
618 if (dat<8){
619 sram_page=ref_gb->get_rom()->get_sram()+0x2000*(dat&3);
620 ext_is_ram=false;
621 }
622 else
623 ext_is_ram=false;
624 break;
625 case 3: // 0x40 が モーションセンサーにマップだが、他のものがマップされることは無い。
626 // But mapped to a motion sensor, but not the other things that will be mapped.
627 break;
628 }
629 }
630
huc1_write(word adr,byte dat)631 void mbc::huc1_write(word adr,byte dat)
632 {
633 if (huc1_16_8){//16/8モード
634 switch(adr>>13){
635 case 0:
636 break;
637 case 1:
638 huc1_dat=(huc1_dat&0x60)+(dat&0x3F);
639 rom_page=ref_gb->get_rom()->get_rom()+0x4000*((huc1_dat==0?1:huc1_dat)&(rom_size_tbl[ref_gb->get_rom()->get_info()->rom_size]-1))-0x4000;
640 break;
641 case 2:
642 huc1_dat=((dat<<5)&0x60)+(huc1_dat&0x3F);
643 rom_page=ref_gb->get_rom()->get_rom()+0x4000*((huc1_dat==0?1:huc1_dat)&(rom_size_tbl[ref_gb->get_rom()->get_info()->rom_size]-1))-0x4000;
644 break;
645 case 3:
646 if (dat&1)
647 huc1_16_8=false;
648 else
649 huc1_16_8=true;
650 huc1_dat=0;
651 break;
652 }
653 }
654 else{//4/32モード
655 switch(adr>>13){
656 case 0:
657 break;
658 case 1:
659 rom_page=ref_gb->get_rom()->get_rom()+0x4000*((dat==0?1:dat)&0x3F&(rom_size_tbl[ref_gb->get_rom()->get_info()->rom_size]-1))-0x4000;
660 break;
661 case 2:
662 sram_page=ref_gb->get_rom()->get_sram()+0x2000*(dat&3);
663 break;
664 case 3:
665 if (dat&1)
666 huc1_16_8=false;
667 else
668 huc1_16_8=true;
669 huc1_dat=0;
670 break;
671 }
672 }
673 }
674
huc3_write(word adr,byte dat)675 void mbc::huc3_write(word adr,byte dat)
676 {
677 // extern FILE *file;
678 // fprintf(file,"%04X : HuC-3 write %04X <= %02X\n",ref_gb->get_cpu()->get_regs()->PC,adr,dat);
679 switch(adr>>13){
680 case 0:
681 if (dat==0xA)
682 ext_is_ram=true;
683 else if (dat==0x0B){
684 ext_is_ram=false;
685 }
686 else if (dat==0x0C){
687 ext_is_ram=false;
688 }
689 else if (dat==0x0D){
690 ext_is_ram=false;
691 }
692 else {
693 ext_is_ram=false;
694 }
695 break;
696 case 1:
697 rom_page=ref_gb->get_rom()->get_rom()+0x4000*((dat==0?1:dat)&0x7F&(rom_size_tbl[ref_gb->get_rom()->get_info()->rom_size]-1))-0x4000;
698 break;
699 case 2:
700 if (dat<8){
701 sram_page=ref_gb->get_rom()->get_sram()+0x2000*(dat&3);
702 ext_is_ram=true;
703 }
704 else{
705 // ext_is_ram=false;
706 // mbc3_timer=dat&0x0F;
707 }
708 break;
709 case 3://RTCラッチ
710 /* if (dat==0){ // Latchはずす // Disconnect Latch
711 mbc3_latch=0;
712 }
713 else if (dat==1){ // データをLatchする // Latch the data to
714 if (!mbc3_latch){
715 mbc3_sec=ref_gb->get_renderer()->get_time(8);
716 mbc3_min=ref_gb->get_renderer()->get_time(9);
717 mbc3_hour=ref_gb->get_renderer()->get_time(10);
718 mbc3_dayl=ref_gb->get_renderer()->get_time(11);
719 mbc3_dayh=ref_gb->get_renderer()->get_time(12);
720 }
721 mbc3_latch=1;
722 }
723 */
724 break;
725 }
726 }
727
tama5_write(word adr,byte dat)728 void mbc::tama5_write(word adr,byte dat)
729 {
730 // extern FILE *file;
731 // fprintf(file,"TAMA5 write %04X <= %02X\n",adr,dat);
732 }
733
mmm01_write(word adr,byte dat)734 void mbc::mmm01_write(word adr,byte dat)
735 {
736 if (mbc1_16_8){//16/8モード // 16/8 mode
737 switch(adr>>13){
738 case 0:
739 break;
740 case 1:
741 mbc1_dat=(mbc1_dat&0x60)+(dat&0x1F);
742 rom_page=ref_gb->get_rom()->get_rom()+0x4000*((mbc1_dat==0?1:mbc1_dat)&(rom_size_tbl[ref_gb->get_rom()->get_info()->rom_size]-1))-0x4000;
743 break;
744 case 2:
745 mbc1_dat=((dat<<5)&0x60)+(mbc1_dat&0x1F);
746 rom_page=ref_gb->get_rom()->get_rom()+0x4000*((mbc1_dat==0?1:mbc1_dat)&(rom_size_tbl[ref_gb->get_rom()->get_info()->rom_size]-1))-0x4000;
747 break;
748 case 3:
749 if (dat&1)
750 mbc1_16_8=false;
751 else
752 mbc1_16_8=true;
753 mbc1_dat=0;
754 break;
755 }
756 }
757 else{//4/32モード // 4/32 mode
758 switch(adr>>13){
759 case 0:
760 break;
761 case 1:
762 rom_page=ref_gb->get_rom()->get_rom()+0x4000*(((dat&3)*0x10+(dat==0?1:dat))&0x0f&(rom_size_tbl[ref_gb->get_rom()->get_info()->rom_size]-1))-0x4000;
763 break;
764 case 2:
765 ref_gb->get_rom()->set_first((dat&3)*0x10);
766 rom_page=ref_gb->get_rom()->get_rom()+0x4000*((dat&3)*0x10);
767 mbc1_dat=dat&3;
768 // sram_page=ref_gb->get_rom()->get_sram()+0x2000*(dat&3);
769 break;
770 case 3:
771 if (dat&1)
772 mbc1_16_8=false;
773 else
774 mbc1_16_8=true;
775 // mbc1_dat=0;
776 break;
777 }
778 }
779 }
780
781
serialize(serializer & s)782 void mbc::serialize(serializer &s)
783 {
784 byte* rom = ref_gb->get_rom()->get_rom();
785 byte* sram = ref_gb->get_rom()->get_sram();
786
787 int tmp;
788
789 tmp = ( rom_page- rom)/0x4000; s_VAR(tmp); rom_page = rom + tmp*0x4000;
790 tmp = (sram_page-sram)/0x2000; s_VAR(tmp); sram_page = sram + tmp*0x2000;
791
792 tmp = get_state(); s_VAR(tmp); set_state(tmp);
793
794 s_VAR(ext_is_ram);
795
796 // all of the below were originally not in the save state format.
797 s_VAR(mbc1_16_8); s_VAR(mbc1_dat);
798
799 s_VAR(mbc3_latch); s_VAR(mbc3_sec); s_VAR(mbc3_min); s_VAR(mbc3_hour);
800 s_VAR(mbc3_dayl); s_VAR(mbc3_dayh); s_VAR(mbc3_timer);
801
802 s_VAR(mbc5_dat);
803
804 s_VAR(mbc7_write_enable);
805 s_VAR(mbc7_idle); s_VAR(mbc7_cs); s_VAR(mbc7_sk); s_VAR(mbc7_op_code);
806 s_VAR(mbc7_adr); s_VAR(mbc7_dat); s_VAR(mbc7_ret); s_VAR(mbc7_state);
807 s_VAR(mbc7_buf); s_VAR(mbc7_count);
808
809 s_VAR(huc1_16_8); s_VAR(huc1_dat);
810 }
811
812