1 /*  gngb, a game boy color emulator
2  *  Copyright (C) 2001 Peponas Thomas & Peponas Mathieu
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU Library General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18 
19 // 26-apr-2006 Analogic joy auto calibrator changes by Iván Dominguez Martin (XWolf")
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <SDL.h>
24 #include "memory.h"
25 #include "emu.h"
26 #include "cpu.h"
27 #include "rom.h"
28 #include "vram.h"
29 #include "interrupt.h"
30 #include "frame_skip.h"
31 #include "sound.h"
32 #include "serial.h"
33 #include "message.h"
34 #include "sgb.h"
35 
36 Uint16 key[SDLK_LAST];
37 
38 Uint8 vram_pal_line_temp[160][4];
39 
40 static Uint8 gb_pad;
41 
42 Uint8 rom_mask;
43 Uint16 nb_rom_page;
44 Uint16 nb_ram_page;
45 Uint16 nb_vram_page;
46 Uint16 nb_wram_page;
47 Uint16 active_rom_page=0;
48 Uint16 active_ram_page=0;
49 Uint16 active_vram_page=0;
50 Uint16 active_wram_page=0;
51 Uint8 **rom_page=NULL;
52 Uint8 **ram_page=NULL;
53 Uint8 **vram_page=NULL;
54 Uint8 **wram_page=NULL;
55 Uint8 oam_space[0xa0];
56 Uint8 himem[0x160];
57 
58 Uint8 ram_enable=0;
59 
60 Uint8 mbc1_mem_mode=MBC1_16_8_MEM_MODE;
61 Uint8 mbc1_line=0;
62 Uint8 mbc5_lower=0;
63 Uint8 mbc5_upper=0;
64 Uint8 mbc7_lower=0;
65 Uint8 mbc7_upper=0;
66 
67 Uint16 sensor_x=0x7ff,sensor_y=0x7ff;
68 
69 Uint8 ram_mask;
70 
71 MEM_READ_ENTRY mem_read_tab[0x10];
72 MEM_WRITE_ENTRY mem_write_tab[0x10];
73 
74 Sint16 joy_x_min=0,joy_x_max=0,joy_y_min=0,joy_y_max=0;
75 
76 void (*select_rom_page)(Uint16 adr,Uint8 v);
77 void (*select_ram_page)(Uint16 adr,Uint8 v);
78 
79 Uint8 IOMem[256]=
80 {0xCF, 0x00, 0x7E, 0xFF, 0xAD, 0x00, 0x00, 0xF8, 0xFF, 0xFF,
81  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x80, 0xBF, 0xF0, 0xFF,
82  0xBF, 0xFF, 0x3F, 0x00, 0xFF, 0xBF, 0x7F, 0xFF, 0x9F, 0xFF,
83  0xBF, 0xFF, 0xFF, 0x00, 0x00, 0xBF, 0x77, 0xF3, 0xF1, 0x00,
84  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFE,
85  0x0E, 0x7F, 0x00, 0xFF, 0x58, 0xDF, 0x00, 0xEC, 0x00, 0xBF,
86  0x0c, 0xED, 0x03, 0xF7, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00,
87  0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x7E, 0xFF, 0xFE,
88  0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
89  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90  0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xC1, 0x20, 0x00, 0x00,
91  0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
93 
94 DMA_INFO dma_info;
95 
96 /* Ram Info:
97    Because some roms use Ram Space to communicate Ram can't always be in
98    direct access */
99 
100 Uint8 ram_can_direct_access=1;
101 Uint8 (*mem_read_a000_bfff)(Uint16 adr)=NULL;
102 void (*mem_write_a000_bfff)(Uint16 adr,Uint8 v)=NULL;
103 
104 /* Read Function */
105 
106 Uint8 mbc7_read_a000_bfff(Uint16 adr);
107 Uint8 timer_read_a000_bfff(Uint16 adr);
108 
109 Uint8 mem_read_a000_bfff_default(Uint16 adr);
110 Uint8 mem_read_f000_ffff_default(Uint16 adr);
111 
112 /* Write Function */
113 
114 void mem_write_0000_1fff_default(Uint16 adr,Uint8 v);
115 void mem_write_2000_3fff_default(Uint16 adr,Uint8 v);
116 void mem_write_4000_5fff_default(Uint16 adr,Uint8 v);
117 void mem_write_6000_7fff_default(Uint16 adr,Uint8 v);
118 void mem_write_a000_bfff_default(Uint16 adr,Uint8 v);
119 void mem_write_f000_ffff_default(Uint16 adr,Uint8 v);
120 
121 void mbc1_write_4000_5fff(Uint16 adr,Uint8 v);
122 void mbc1_write_6000_7fff(Uint16 adr,Uint8 v);
123 
124 void rumble_write_4000_5fff(Uint16 adr,Uint8 v);
125 
126 void timer_write_4000_5fff(Uint16 adr,Uint8 v);
127 void timer_write_6000_7fff(Uint16 adr,Uint8 v);
128 void timer_write_a000_bfff(Uint16 adr,Uint8 v);
129 
130 void mbc7_write_a000_bfff(Uint16 adr,Uint8 v);
131 
132 /* Fast Mem Function */
133 
set_mem_read_direct_access(Uint8 mem_area,Uint8 * buf)134 __inline__ void set_mem_read_direct_access(Uint8 mem_area,Uint8 *buf) {
135   mem_read_tab[mem_area].type=MEM_DIRECT_ACCESS;
136   mem_read_tab[mem_area].b=buf;
137 }
138 
set_mem_write_direct_access(Uint8 mem_area,Uint8 * buf)139 __inline__ void set_mem_write_direct_access(Uint8 mem_area,Uint8 *buf) {
140   mem_write_tab[mem_area].type=MEM_DIRECT_ACCESS;
141   mem_write_tab[mem_area].b=buf;
142 }
143 
set_mem_read_fun_access(Uint8 mem_area,Uint8 (* fun)(Uint16 adr))144 __inline__ void set_mem_read_fun_access(Uint8 mem_area,Uint8 (*fun)(Uint16 adr)) {
145   mem_read_tab[mem_area].type=MEM_FUN_ACCESS;
146   mem_read_tab[mem_area].f=fun;
147 }
148 
set_mem_write_fun_access(Uint8 mem_area,void (* fun)(Uint16 adr,Uint8 v))149 __inline__ void set_mem_write_fun_access(Uint8 mem_area,void (*fun)(Uint16 adr,Uint8 v)) {
150   mem_write_tab[mem_area].type=MEM_FUN_ACCESS;
151   mem_write_tab[mem_area].f=fun;
152 }
153 
set_active_rom_page(Uint16 page)154 __inline__ void set_active_rom_page(Uint16 page) {
155   Uint8 i;
156   active_rom_page=page&rom_mask;
157   for(i=0;i<4;i++) {
158     set_mem_read_direct_access(i,&rom_page[0][i*0x1000]);
159     set_mem_read_direct_access(i+4,&rom_page[active_rom_page][i*0x1000]);
160   }
161 }
162 
set_active_vram_page(Uint16 page)163 __inline__ void set_active_vram_page(Uint16 page) {
164   Uint8 i;
165   active_vram_page=page&0x01;
166   for(i=0;i<2;i++) {
167     set_mem_read_direct_access(i+8,&vram_page[active_vram_page][i*0x1000]);
168     set_mem_write_direct_access(i+8,&vram_page[active_vram_page][i*0x1000]);
169   }
170 }
171 
set_active_ram_page(Uint16 page)172 __inline__ void set_active_ram_page(Uint16 page) {
173   Uint8 i;
174   active_ram_page=page&ram_mask;
175   if (ram_can_direct_access) {
176     for(i=0;i<2;i++) {
177       set_mem_read_direct_access(i+0x0A,&ram_page[active_ram_page][i*0x1000]);
178       set_mem_write_direct_access(i+0x0A,&ram_page[active_ram_page][i*0x1000]);
179     }
180   }
181 }
182 
set_active_wram_page(Uint16 page)183 __inline__ void set_active_wram_page(Uint16 page) {
184   int i;
185   active_wram_page=page&0x07;
186   if (!active_wram_page) active_wram_page=1;
187 
188   set_mem_read_direct_access(0x0C,&wram_page[0][0]);
189   set_mem_read_direct_access(0x0D,&wram_page[active_wram_page][0]);
190   set_mem_read_direct_access(0x0E,&wram_page[0][0]);
191 
192   set_mem_write_direct_access(0x0C,&wram_page[0][0]);
193   set_mem_write_direct_access(0x0D,&wram_page[active_wram_page][0]);
194   set_mem_write_direct_access(0x0E,&wram_page[0][0]);
195 }
196 
disable_ram(void)197 __inline__ void disable_ram(void) {
198   Uint8 i;
199   for(i=0;i<2;i++) {
200     set_mem_read_fun_access(i+0x0A,mem_read_a000_bfff);
201     set_mem_write_fun_access(i+0x0A,mem_write_a000_bfff);
202   }
203   ram_enable=0;
204 }
205 
enable_ram(void)206 __inline__ void enable_ram(void) {
207   set_active_ram_page(active_ram_page);
208   ram_enable=1;
209 }
210 
select_default(Uint16 adr,Uint8 v)211 void select_default(Uint16 adr,Uint8 v)
212 {
213   // do nothing
214 }
215 
mbc1_select_page(Uint16 adr,Uint8 v)216 void mbc1_select_page(Uint16 adr,Uint8 v)
217 {
218   Uint8 bank=v&rom_mask;
219   if (bank<1) bank=1;
220   set_active_rom_page(bank);
221 }
222 
mbc2_select_page(Uint16 adr,Uint8 v)223 void mbc2_select_page(Uint16 adr,Uint8 v)
224 {
225   Uint8 bank;
226   if (adr==0x2100) {
227     bank=v&rom_mask;
228     if (bank<1) bank=1;
229     set_active_rom_page(bank);
230   }
231 }
232 
mbc3_select_page(Uint16 adr,Uint8 v)233 void mbc3_select_page(Uint16 adr,Uint8 v)
234 {
235   Uint8 bank=v&rom_mask;
236   if (bank<1) bank=1;
237   set_active_rom_page(bank);
238 }
239 
mbc5_select_page(Uint16 adr,Uint8 v)240 void mbc5_select_page(Uint16 adr,Uint8 v)
241 {
242   Uint16 bank;
243   if (adr>=0x2000 && adr<0x3000)
244     mbc5_lower=v;
245   if (adr>=0x3000 && adr<0x4000 && nb_rom_page>=256) {
246     mbc5_upper=v&0x01;
247   }
248   bank=mbc5_lower+((mbc5_upper)?256:0);
249   set_active_rom_page(bank);
250 }
251 
252 
gbmemory_init(void)253 void gbmemory_init(void)
254 {
255   //gbmemory_reset();
256 
257   memset(key,0,256);
258   memset(oam_space,0,0xa0);
259   memcpy(&himem[0x60],IOMem,0xff);
260 
261   DIVID=0x00;
262   TIME_MOD=0x00;
263   TIME_CONTROL=0x00;
264   TIME_COUNTER=0x00;
265 
266   NR10=0x80;
267   NR11=0xbf;
268   NR12=0xf3;
269   NR14=0xbf;
270   NR21=0x3f;
271   NR21=0x00;
272   NR24=0xbf;
273   NR30=0x7f;
274   NR31=0xff;
275   NR32=0x9f;
276   NR33=0xbf;
277   NR41=0xff;
278   NR42=0x00;
279   NR43=0x00;
280   NR44=0xbf;
281   NR50=0x77;
282   NR51=0xf3;
283   /* FIXME: SGB value != */
284   NR52=0xf1;
285 
286   CMP_LINE=0x00;
287   INT_ENABLE=0x00;
288 
289   dma_info.type=NO_DMA;
290 
291   if (rom_type&MBC1) select_rom_page=mbc1_select_page;
292   else if (rom_type&MBC2) select_rom_page=mbc2_select_page;
293   else if (rom_type&MBC3) select_rom_page=mbc3_select_page;
294   else if (rom_type&MBC5) select_rom_page=mbc5_select_page;
295   else select_rom_page=select_default;
296 
297   gbmemory_reset();
298 }
299 
gbmemory_reset(void)300 void gbmemory_reset(void) {
301   int i;
302 
303   memset(key,0,256);
304   memset(oam_space,0,0xa0);
305   memcpy(&himem[0x60],IOMem,0xff);
306 
307   DIVID=0x00;
308   TIME_MOD=0x00;
309   TIME_CONTROL=0x00;
310   TIME_COUNTER=0x00;
311 
312   NR10=0x80;
313   NR11=0xbf;
314   NR12=0xf3;
315   NR14=0xbf;
316   NR21=0x3f;
317   NR21=0x00;
318   NR24=0xbf;
319   NR30=0x7f;
320   NR31=0xff;
321   NR32=0x9f;
322   NR33=0xbf;
323   NR41=0xff;
324   NR42=0x00;
325   NR43=0x00;
326   NR44=0xbf;
327   NR50=0x77;
328   NR51=0xf3;
329   /* FIXME: SGB value != */
330   NR52=0xf1;
331 
332   /*for(i=0xFF30;i<0xFF3f;i++) {
333     mem_write_ff(i,(i%8));
334   }*/
335 
336   LCDCCONT=0x91;
337   CURLINE=0x00;
338   CMP_LINE=0x00;
339 
340   INT_ENABLE=0x00;
341   INT_FLAG=0x00;
342 
343   WRAM_BANK=0x00;
344   VRAM_BANK=0x00;
345 
346   dma_info.type=NO_DMA;
347 
348   active_rom_page=1;
349   active_ram_page=0;
350   active_vram_page=0;
351   active_wram_page=1;
352 
353   ram_enable=0;
354 
355   /* FAST MEM SYSTEM */
356 
357   /* ROM */
358   set_mem_write_fun_access(0x00,mem_write_0000_1fff_default);
359   set_mem_write_fun_access(0x01,mem_write_0000_1fff_default);
360   set_mem_write_fun_access(0x02,mem_write_2000_3fff_default);
361   set_mem_write_fun_access(0x03,mem_write_2000_3fff_default);
362   set_mem_write_fun_access(0x04,mem_write_4000_5fff_default);
363   set_mem_write_fun_access(0x05,mem_write_4000_5fff_default);
364   set_mem_write_fun_access(0x06,mem_write_6000_7fff_default);
365   set_mem_write_fun_access(0x07,mem_write_6000_7fff_default);
366 
367   if (rom_type&MBC1) select_rom_page=mbc1_select_page;
368   else if (rom_type&MBC2) select_rom_page=mbc2_select_page;
369   else if (rom_type&MBC3) select_rom_page=mbc3_select_page;
370   else if (rom_type&MBC5) select_rom_page=mbc5_select_page;
371   else select_rom_page=select_default;
372 
373   set_mem_write_fun_access(0x02,select_rom_page);
374   set_mem_write_fun_access(0x03,select_rom_page);
375 
376   for(i=0;i<4;i++) {
377     set_mem_read_direct_access(i,&rom_page[0][i*0x1000]);
378     set_mem_read_direct_access(i+4,&rom_page[active_rom_page][i*0x1000]);
379   }
380 
381   if (rom_type&MBC1) {
382     set_mem_write_fun_access(0x04,mbc1_write_4000_5fff);
383     set_mem_write_fun_access(0x05,mbc1_write_4000_5fff);
384     set_mem_write_fun_access(0x06,mbc1_write_6000_7fff);
385     set_mem_write_fun_access(0x07,mbc1_write_6000_7fff);
386   }
387 
388   if (rom_type&RUMBLE) {
389     set_mem_write_fun_access(0x04,rumble_write_4000_5fff);
390     set_mem_write_fun_access(0x05,rumble_write_4000_5fff);
391   }
392 
393   if (rom_type&TIMER) {
394     set_mem_write_fun_access(0x04,timer_write_4000_5fff);
395     set_mem_write_fun_access(0x05,timer_write_4000_5fff);
396     set_mem_write_fun_access(0x06,timer_write_6000_7fff);
397     set_mem_write_fun_access(0x07,timer_write_6000_7fff);
398   }
399 
400   /* VRAM */
401   for(i=0;i<2;i++) {
402     set_mem_read_direct_access(i+8,&vram_page[0][i*0x1000]);
403     set_mem_write_direct_access(i+8,&vram_page[0][i*0x1000]);
404   }
405 
406   /* RAM */
407   if (rom_type&TIMER) {
408     ram_can_direct_access=0;
409     mem_write_a000_bfff=timer_write_a000_bfff;
410     mem_read_a000_bfff=timer_read_a000_bfff;
411      for(i=0;i<2;i++) {
412        set_mem_read_fun_access(i+0x0A,mem_read_a000_bfff);
413        set_mem_write_fun_access(i+0x0A,mem_write_a000_bfff);
414      }
415   } else {
416     ram_can_direct_access=1;
417     mem_read_a000_bfff=mem_read_a000_bfff_default;
418     mem_write_a000_bfff=mem_write_a000_bfff_default;
419     for(i=0;i<2;i++) {
420       set_mem_read_direct_access(i+0x0A,&ram_page[0][i*0x1000]);
421       set_mem_write_direct_access(i+0x0A,&ram_page[0][i*0x1000]);
422     }
423   }
424 
425   /* WRAM */
426   set_mem_read_direct_access(0x0C,&wram_page[0][0]);
427   set_mem_read_direct_access(0x0D,&wram_page[active_wram_page][0]);
428   set_mem_read_direct_access(0x0E,&wram_page[0][0]);
429 
430   set_mem_write_direct_access(0x0C,&wram_page[0][0]);
431   set_mem_write_direct_access(0x0D,&wram_page[active_wram_page][0]);
432   set_mem_write_direct_access(0x0E,&wram_page[0][0]);
433 
434   /* OAM HIMEM */
435   set_mem_read_fun_access(0x0f,mem_read_f000_ffff_default);
436   set_mem_write_fun_access(0x0f,mem_write_f000_ffff_default);
437 }
438 
push_stack_word(Uint16 v)439 void push_stack_word(Uint16 v)
440 {
441   Uint8 h=((v&0xff00)>>8);
442   Uint8 l=(v&0x00ff);
443 
444   --gbcpu->sp.w;
445   mem_write_fast(gbcpu->sp.w,h);
446   --gbcpu->sp.w;
447   mem_write_fast(gbcpu->sp.w,l);
448 }
449 
alloc_mem_page(Uint16 nb_page,Uint32 size)450 Uint8 **alloc_mem_page(Uint16 nb_page,Uint32 size)
451 {
452   Uint8 **page;
453   int i;
454   page=(Uint8 **)malloc(sizeof(Uint8 *)*nb_page);
455   for(i=0;i<nb_page;i++) {
456     page[i]=(Uint8 *)malloc(sizeof(Uint8)*size);
457     memset(page[i],0,size);
458   }
459   return page;
460 }
461 
free_mem_page(Uint8 ** page,Uint16 nb_page)462 void free_mem_page(Uint8 **page,Uint16 nb_page)
463 {
464   int i;
465   for(i=0;i<nb_page;i++) {
466     free(page[i]);
467     page[i]=NULL;
468   }
469   free(page);
470 }
471 
472 /* DMA FUNCTIONS */
473 
do_hdma(void)474 __inline__ void do_hdma(void) {
475   int i;
476   Uint8 t;
477 
478   for(i=0;i<16;i++) {
479     mem_read_fast(dma_info.src,t);
480     dma_info.src++;
481     mem_write_fast(dma_info.dest,t);
482     dma_info.dest++;
483   }
484 
485   HDMA_CTRL1=(dma_info.src&0xff00)>>8;
486   HDMA_CTRL2=(dma_info.src&0xf0);
487   HDMA_CTRL3=(dma_info.dest&0xff00)>>8;
488   HDMA_CTRL4=(dma_info.dest&0xf0);
489 
490   HDMA_CTRL5--;
491   dma_info.lg-=16;
492   if (HDMA_CTRL5==0xff) dma_info.type=NO_DMA;
493 }
494 
do_gdma(void)495 __inline__ void do_gdma(void) {
496   int i;
497   Uint8 t;
498   Uint8 bk;
499   Uint8 *d=&vram_page[active_vram_page][dma_info.dest&0x1fff];
500 
501   for(i=0;i<dma_info.lg;i++) {
502     mem_read_fast(dma_info.src,t);
503     dma_info.src++;
504     mem_write_fast(dma_info.dest,t);
505     dma_info.dest++;
506   }
507   /*} else {
508     for(i=0;i<dma_info.lg;i++) {
509     t=mem_read(dma_info.src);
510     dma_info.src++;
511     mem_write(dma_info.dest++,t);
512     }
513     }*/
514 
515   HDMA_CTRL1=(dma_info.src&0xff00)>>8;
516   HDMA_CTRL2=(dma_info.src&0xf0);
517   HDMA_CTRL3=(dma_info.dest&0xff00)>>8;
518   HDMA_CTRL4=(dma_info.dest&0xf0);
519   if (!conf.gdma_cycle) {
520     HDMA_CTRL5=0xff;
521     dma_info.type=NO_DMA;
522   } else dma_info.type=GDMA;
523 }
524 
525 
hdma_request(Uint8 v)526 __inline__ void hdma_request(Uint8 v)
527 {
528   /* FIXME : control are necesary ( i think ) */
529   //if (LCDCCONT&0x80) {
530 
531   if (dma_info.type==HDMA) {
532     int i;
533     Uint8 t;
534     for(i=0;i<dma_info.lg;i++) {
535       t=mem_read(dma_info.src);
536       dma_info.src++;
537       mem_write(dma_info.dest++,t);
538     }
539   }
540 
541   dma_info.src=((HDMA_CTRL1<<4)|(HDMA_CTRL2>>4))<<4;
542   dma_info.dest=((((HDMA_CTRL3&31)|0x80)<<4)|(HDMA_CTRL4>>4))<<4;
543   dma_info.lg=((v&0x7f)+1)<<4;
544   HDMA_CTRL5=v&0x7f;
545   dma_info.type=HDMA;
546 
547   if ((LCDCSTAT&0x03)==0x00) do_hdma();
548     /*} else  {
549       dma_info.v=v;
550       dma_info.src=(HDMA_CTRL1<<8)|(HDMA_CTRL2&0xf0);
551       dma_info.dest=(HDMA_CTRL3<<8)|(HDMA_CTRL4&0xf0)|0x8000;
552       dma_info.lg=((v&0x7f)+1)<<4;
553       HDMA_CTRL5=0xff;
554       dma_info.type=NO_DMA;
555       do_gdma();
556       }*/
557 }
558 
gdma_request(Uint8 v)559 __inline__ void gdma_request(Uint8 v)
560 {
561   dma_info.src=((HDMA_CTRL1<<4)|(HDMA_CTRL2>>4))<<4;
562   dma_info.dest=((((HDMA_CTRL3&31)|0x80)<<4)|(HDMA_CTRL4>>4))<<4;
563   dma_info.lg=((v&0x7f)+1)<<4;
564 
565   /* FIXME: gdma: how many cycle take GDMA ? */
566   dma_info.gdma_cycle=((((gbcpu->mode==DOUBLE_SPEED)?110:220)+((v&0x7f)*7.63))*0.000001)*
567     (((gbcpu->mode==DOUBLE_SPEED)?4194304*2:4194304));
568 
569   /* TGB: */
570   dma_info.gdma_cycle=456*2+((v&0x7f)+1)*32*(gbcpu->mode==DOUBLE_SPEED?2:1);
571 
572 
573 
574   /* FIXME: gdma: control are necesary ( i think ) */
575   do_gdma();
576 }
577 
578 
do_dma(Uint8 v)579 __inline__ void do_dma(Uint8 v)
580 {
581   Uint16 a=v<<8;
582   Uint8 bank;
583   int i;
584 
585   DMA=v;
586 
587   if (a>=0xfea0 && a<0xffff)
588     memcpy(oam_space,&himem[a-0xfea0],0xa0);
589 
590   if (a>=0xe000 && a<0xfe00) a-=0x2000;  // echo mem
591 
592   bank=(a&0xf000)>>12;
593   switch(bank) {
594   case 0x00:
595   case 0x01:
596   case 0x02:
597   case 0x03:memcpy(oam_space,&rom_page[0][a],0xa0);return;
598   case 0x04:
599   case 0x05:
600   case 0x06:
601   case 0x07:memcpy(oam_space,&rom_page[active_rom_page][a-0x4000],0xa0);return;
602   case 0x08:
603   case 0x09:memcpy(oam_space,&vram_page[active_vram_page][a-0x8000],0xa0);return;
604   case 0x0a:
605   case 0x0b:memcpy(oam_space,&ram_page[active_ram_page][a-0xa000],0xa0);return;
606   case 0x0c:memcpy(oam_space,&wram_page[0][a-0xc000],0xa0);return;
607   case 0x0d:memcpy(oam_space,&wram_page[active_wram_page][a-0xd000],0xa0);return;
608   default:
609     for(i=0;i<0xa0;i++)
610       oam_space[i]=mem_read(a+i);
611     break;
612   }
613 }
614 
615 /* READ FUNCTIONS */
616 
mem_read_ff(Uint16 adr)617 __inline__ Uint8 mem_read_ff(Uint16 adr)
618 {
619   if (adr==0xff00) {
620     Uint8 t=0xff;
621     /*if (sgb.check) {
622       sgb.check=0;
623       return GB_PAD;
624       }*/
625     // if (GB_PAD==0x30)
626     //printf("read GB_PAD %02x\n",GB_PAD);
627     /* FIXME */
628     /* if (GB_PAD==0x03) {
629       printf("determine type\n");
630       return (gameboy_type==SUPER_GAMEBOY)?0x3f:0xff;
631       }*/
632     //printf("%d %02x\n",sgb.b_i,GB_PAD);
633     /*if (GB_PAD==0x30) return 0xff;
634       if (GB_PAD==0x10) GB_PAD=((~(gb_pad&0x0f))&0xdf);
635       else if (GB_PAD==0x20) GB_PAD=((~(gb_pad>>4))&0xef);
636       return GB_PAD;*/
637 
638     // if (GB_PAD==0xff) return ((conf.gb_type&SUPER_GAMEBOY)?0x3f:0xff);
639 
640     switch(GB_PAD&0x30) {
641     case 0x00:
642     case 0xff:t=0xff;break;
643     case 0x10:t=((~(gb_pad&0x0f)))|0x10; break;
644     case 0x20:t=((~(gb_pad>>4)))|0x20; break;
645     case 0x30:t=(((!sgb.player)?(~0x00):(~0x01)));break;
646     }
647     /*if (GB_PAD==0x10) GB_PAD=((~(gb_pad&0x0f)))|0x10;
648       else if (GB_PAD==0x20) GB_PAD=((~(gb_pad>>4)))|0x20;
649       return GB_PAD;*/
650     //if (sgb.player&0x80) {
651     if (conf.gb_type&SUPER_GAMEBOY) t/*GB_PAD*/&=0x3f;
652       /*      sgb.player&=(~0x80);
653 	      }*/
654     return  t;
655     //GB_PAD=t;
656     //return GB_PAD;
657   }
658 
659   /*  if (adr==0xff01 && conf.serial_on) {
660     Sint8 a=gbserial_check();
661     if (a>=0) SB=a;
662     else SB=0xff;
663     return SB;
664     } else return SB;*/
665 
666 
667   if (conf.gb_type&COLOR_GAMEBOY) {
668     if (adr==0xff4d) {
669       if (gbcpu->mode==DOUBLE_SPEED) return CPU_SPEED|0x80;
670       else return 0x00;
671     }
672 
673     if (adr==0xff69) {
674       if (BGPAL_SPE&0x01)
675 	return pal_col_bck_gb[(BGPAL_SPE&0x38)>>3][(BGPAL_SPE&0x06)>>1]>>8;
676     else return pal_col_bck_gb[(BGPAL_SPE&0x38)>>3][(BGPAL_SPE&0x06)>>1]&0xff;
677     }
678 
679     if (adr==0xff6b) {
680       if (OBJPAL_SPE&0x01)
681 	return pal_col_obj_gb[(OBJPAL_SPE&0x38)>>3][(OBJPAL_SPE&0x06)>>1]>>8;
682       else return pal_col_obj_gb[(OBJPAL_SPE&0x38)>>3][(OBJPAL_SPE&0x06)>>1]&0xff;
683     }
684   }
685 
686   if (adr>=0xff10 && adr<=0xff3f && conf.sound) return read_sound_reg(adr);
687   return himem[adr-0xfea0];
688 }
689 
mem_read_a000_bfff_default(Uint16 adr)690 Uint8 mem_read_a000_bfff_default(Uint16 adr) {
691   if (!ram_enable) return 0xff;
692   return ram_page[active_ram_page][adr-0xa000];
693 }
694 
mem_read_f000_ffff_default(Uint16 adr)695 Uint8 mem_read_f000_ffff_default(Uint16 adr) {
696   if (adr>=0xff00) return mem_read_ff(adr);
697   if (adr>=0xfe00 && adr<0xfea0) return oam_space[adr-0xfe00];
698   if (adr>=0xfea0 && adr<0xff00) return himem[adr-0xfea0];
699   return 0xff;
700 }
701 
702 
timer_read_a000_bfff(Uint16 adr)703 Uint8 timer_read_a000_bfff(Uint16 adr) {
704   /* FIXME: Timer and ram enable ???? */
705   if (!ram_enable) return 0xFF;
706   if (rom_timer->reg_sel&0x08)
707     return rom_timer->regl[rom_timer->reg_sel&0x07];
708   return ram_page[active_ram_page][adr-0xa000];
709 }
710 
mem_read_default(Uint16 adr)711 Uint8 mem_read_default(Uint16 adr)
712 {
713   Uint8 bank;
714 
715   if (adr>=0xfe00 && adr<0xfea0) return oam_space[adr-0xfe00];
716   if (adr>=0xfea0 && adr<0xff00) return himem[adr-0xfea0];
717   if (adr>=0xff00) return mem_read_ff(adr);
718   if (adr>=0xe000 && adr<0xfe00) adr-=0x2000;  // echo mem
719 
720   bank=(adr&0xf000)>>12;
721   switch(bank) {
722   case 0x00:
723   case 0x01:
724   case 0x02:
725   case 0x03:return rom_page[0][adr];
726   case 0x04:
727   case 0x05:
728   case 0x06:
729   case 0x07:return rom_page[active_rom_page][adr-0x4000];
730   case 0x08:
731   case 0x09:return vram_page[active_vram_page][adr-0x8000];
732   case 0x0a:
733   case 0x0b:
734     if (!ram_enable) return 0xff;
735     if (rom_type&TIMER && rom_timer->reg_sel&0x08)
736       return rom_timer->regl[rom_timer->reg_sel&0x07];
737     return ram_page[active_ram_page][adr-0xa000];
738   case 0x0c:return wram_page[0][adr-0xc000];
739   case 0x0d:return wram_page[active_wram_page][adr-0xd000];
740   }
741   return 0xFF;
742 }
743 
update_gb_pad(void)744 __inline__ void update_gb_pad(void) {
745   gb_pad=0;
746   if (!conf.play_movie) {
747 
748     if (conf.use_joy) {
749       Sint16 joy_x_pos=joy_axis[jmap[PAD_LEFT]];
750       Sint16 joy_y_pos=joy_axis[jmap[PAD_UP]];
751       Sint16 joy_x_mid=(joy_x_max-joy_x_min) / 2;
752       Sint16 joy_y_mid=(joy_y_max-joy_y_min) / 2;
753       Sint16 joy_x_qua=joy_x_mid / 2;
754       Sint16 joy_y_qua=joy_y_mid / 2;
755 
756       if ((joy_but[jmap[PAD_START]]) || (key[kmap[PAD_START]])) gb_pad|=0x08; /* Start */
757       if ((joy_but[jmap[PAD_SELECT]]) || (key[kmap[PAD_SELECT]])) gb_pad|=0x04; /* Select */
758       if ((joy_but[jmap[PAD_A]]) || (key[kmap[PAD_A]])) gb_pad|=0x01; /* A */
759       if ((joy_but[jmap[PAD_B]]) || (key[kmap[PAD_B]])) gb_pad|=0x02; /* B */
760 
761       /*if ((joy_axis[jmap[PAD_LEFT]]<-10000) || (key[kmap[PAD_LEFT]])) gb_pad|=0x20;
762       if ((joy_axis[jmap[PAD_RIGHT]]>10000) || (key[kmap[PAD_RIGHT]])) gb_pad|=0x10;
763       if ((joy_axis[jmap[PAD_UP]]<-10000) ||  (key[kmap[PAD_UP]])) gb_pad|=0x40;
764       if ((joy_axis[jmap[PAD_DOWN]]>10000) || (key[kmap[PAD_DOWN]])) gb_pad|=0x80;*/
765 
766       if (joy_x_pos>joy_x_max) joy_x_max=joy_x_pos;
767       if (joy_x_pos<joy_x_min) joy_x_min=joy_x_pos;
768       if (joy_y_pos>joy_y_max) joy_y_max=joy_y_pos;
769       if (joy_y_pos<joy_y_min) joy_y_min=joy_y_pos;
770 
771       if ((joy_x_pos<(joy_x_mid-joy_x_qua)) || (key[kmap[PAD_LEFT]])) gb_pad|=0x20;
772       if ((joy_x_pos>(joy_x_mid+joy_x_qua)) || (key[kmap[PAD_RIGHT]])) gb_pad|=0x10;
773       if ((joy_y_pos<(joy_y_mid-joy_y_qua)) ||  (key[kmap[PAD_UP]])) gb_pad|=0x40;
774       if ((joy_y_pos>(joy_y_mid+joy_y_qua)) || (key[kmap[PAD_DOWN]])) gb_pad|=0x80;
775 
776     } else {
777 
778       //      if (!joy_but) {
779       if (key[kmap[PAD_START]]) gb_pad|=0x08; /* Start */
780       if (key[kmap[PAD_SELECT]]) gb_pad|=0x04; /* Select */
781       if (key[kmap[PAD_A]]) gb_pad|=0x01; /* A */
782       if (key[kmap[PAD_B]]) gb_pad|=0x02; /* B */
783       //  } else {
784       //      if ((joy_but[jmap[PAD_START]]) || (key[kmap[PAD_START]])) gb_pad|=0x08; /* Start */
785       //      if ((joy_but[jmap[PAD_SELECT]]) || (key[kmap[PAD_SELECT]])) gb_pad|=0x04; /* Select */
786       //      if ((joy_but[jmap[PAD_A]]) || (key[kmap[PAD_A]])) gb_pad|=0x01; /* A */
787       //      if ((joy_but[jmap[PAD_B]]) || (key[kmap[PAD_B]])) gb_pad|=0x02; /* B */
788       //    }
789 
790       //    if (!joy_axis) {
791       if (key[kmap[PAD_LEFT]]) gb_pad|=0x20;
792       if (key[kmap[PAD_RIGHT]]) gb_pad|=0x10;
793       if (key[kmap[PAD_UP]]) gb_pad|=0x40;
794       if (key[kmap[PAD_DOWN]]) gb_pad|=0x80;
795       //} else {
796       //if ((joy_axis[jmap[PAD_LEFT]]<-1000) || (key[kmap[PAD_LEFT]])) gb_pad|=0x20;
797       //if ((joy_axis[jmap[PAD_RIGHT]]>1000) || (key[kmap[PAD_RIGHT]])) gb_pad|=0x10;
798       //if ((joy_axis[jmap[PAD_UP]]<-1000) ||  (key[kmap[PAD_UP]])) gb_pad|=0x40;
799       //if ((joy_axis[jmap[PAD_DOWN]]>1000) || (key[kmap[PAD_DOWN]])) gb_pad|=0x80;
800       //}
801     }
802 
803     if (conf.save_movie) movie_add_pad(gb_pad);
804   } else {
805     gb_pad=movie_get_next_pad();
806   }
807 }
808 
809 extern Uint8 win_line;
810 
write2lcdccont(Uint8 v)811 __inline__ void write2lcdccont(Uint8 v)
812 {
813   if ((LCDCCONT&0x80) && (!(v&0x80))) {  // LCDC go to off
814     gblcdc->mode=HBLANK_PER;
815     LCDCSTAT=(LCDCSTAT&0xfc);
816     CURLINE=0;
817     gblcdc->cycle=0;
818 
819     dma_info.type=NO_DMA;
820     HDMA_CTRL5=0xff;
821     clear_screen();
822     reset_frame_skip();
823   }
824 
825   if ((!(LCDCCONT&0x80)) && (v&0x80)) { // LCDC go to on
826     gblcdc_set_on();
827   }
828   LCDCCONT=v;
829 }
830 
mem_write_ff(Uint16 adr,Uint8 v)831 __inline__ void mem_write_ff(Uint16 adr,Uint8 v) {
832   Uint16 a;
833   Uint8 c,p;
834 
835   if (conf.gb_type&COLOR_GAMEBOY) {
836     if (adr==0xff4d) {
837       if (v&0x80 || v&0x01) {
838 	go2double_speed();
839 	/* FIXME: */
840 	get_nb_cycle();
841       }
842       CPU_SPEED=(v&0xfe);
843       return;
844     }
845 
846     if (adr==0xff4f) {
847       set_active_vram_page(v);
848       VRAM_BANK=active_vram_page;
849       return;
850     }
851 
852     if (adr==0xff55) {   // HDMA & GDMA
853       if (v&0x80) hdma_request(v);
854       else gdma_request(v);
855       return;
856     }
857 
858     if (adr==0xff68) {
859       BGPAL_SPE=v&0xbf;
860       if (BGPAL_SPE&0x01)
861 	BGPAL_DATA=pal_col_bck_gb[(BGPAL_SPE>>3)&0x07][(BGPAL_SPE>>1)&0x03]>>8;
862       else BGPAL_DATA=pal_col_bck_gb[(BGPAL_SPE>>3)&0x07][(BGPAL_SPE>>1)&0x03]&0xff;
863       return;
864     }
865 
866     if (adr==0xff69) {
867 
868       c=(BGPAL_SPE>>1)&0x03;
869       p=(BGPAL_SPE>>3)&0x07;
870       if (BGPAL_SPE&0x01)
871 	pal_col_bck_gb[p][c]=(pal_col_bck_gb[p][c]&0x00ff)|(v<<8);
872       else pal_col_bck_gb[p][c]=(pal_col_bck_gb[p][c]&0xff00)|v;
873 
874       pal_col_bck[p][c]=Filter[pal_col_bck_gb[p][c]&0x7FFF];
875       if (BGPAL_SPE&0x80) {
876 	a=BGPAL_SPE&0x3f;
877 	a++;
878 	BGPAL_SPE=(a&0x3f)|0x80;
879       }
880       BGPAL_DATA=v;
881       return;
882     }
883 
884     if (adr==0xff6a) {
885       OBJPAL_SPE=v&0xbf;
886       if (OBJPAL_SPE&0x01)
887 	OBJPAL_DATA=pal_col_obj_gb[(OBJPAL_SPE>>3)&0x07][(OBJPAL_SPE>>1)&0x03]>>8;
888       else OBJPAL_DATA=pal_col_obj_gb[(OBJPAL_SPE>>3)&0x07][(OBJPAL_SPE>>1)&0x03]&0xff;
889       return;
890     }
891 
892     if (adr==0xff6b) {
893       c=(OBJPAL_SPE>>1)&0x03;
894       p=(OBJPAL_SPE>>3)&0x07;
895       if (OBJPAL_SPE&0x01)
896 	pal_col_obj_gb[p][c]=(pal_col_obj_gb[p][c]&0x00ff)|(v<<8);
897       else pal_col_obj_gb[p][c]=(pal_col_obj_gb[p][c]&0xff00)|v;
898 
899       pal_col_obj[p][c]=Filter[pal_col_obj_gb[p][c]&0x7FFF];
900       if (OBJPAL_SPE&0x80) {
901 	a=OBJPAL_SPE&0x3f;
902 	a++;
903 	OBJPAL_SPE=(a&0x3f)|0x80;
904       }
905       OBJPAL_DATA=v;
906       return;
907     }
908 
909     if (adr==0xff70) {
910       set_active_wram_page(v);
911       WRAM_BANK=active_wram_page;
912       return;
913     }
914   } // end COLOR_GAMEBOY
915 
916   // Update sound if necessary
917   if (adr>=0xff10 && adr<=0xff3f && conf.sound) {
918     write_sound_reg(adr,v);
919     return;
920   }
921 
922   switch(adr) {
923   case 0xff00:
924     if (sgb.on) { // sgb transfert
925       switch(v) {
926       case 0x00:sgb_init_transfer();return;
927       case 0x10:sgb.b=1;break;
928       case 0x20:sgb.b=0;break;
929       case 0x30:
930 	if (sgb.b_i==-1) {sgb.b_i=0;return;}
931 	if (sgb.b_i==128 /*&& sgb.b==0*/) {
932 	  sgb_exec_cmd();
933 	  sgb.on=0;
934 	  return;
935 	}
936 	sgb.pack[sgb.b_i/8]=(sgb.pack[sgb.b_i/8]>>1)|(sgb.b<<(8-sgb.b%8));
937 	sgb.b_i++;
938       }
939     } else {
940       if (v==0x00) {
941 	if (conf.gb_type&SUPER_GAMEBOY) sgb_init_transfer();
942 	return;
943       }
944       if (v==0x30 ) GB_PAD=0xff;
945       else GB_PAD=v;
946       update_gb_pad();
947     }
948     break;
949     /* EXPERIMENTAL */
950   case 0xff01:
951     SB=v;
952     break;
953   case 0xff02:
954 
955     /*    SC=v&0x81;
956 	  if ((v&0x80)&&(v&0x01)) serial_cycle_todo=512;
957 	  break;*/
958 
959     if (!conf.serial_on) {
960       if ((v&0x81)==0x81) {
961 	SB=0xff;
962 	SC=v&0x7f;
963 	set_interrupt(SERIAL_INT);
964       }
965     } else {
966       /* Start Tranfer ? */
967       // printf("Write %02x\n",v);
968       if ((v&0x80)==0x80) {
969 	if ((v&0x01)==0x01) {	/* Internal Clock  */
970 	  gbserial_write(SB);
971 	  printf("Server write %02x\n",SB);
972 	  serial_cycle_todo=4096;
973 	  //serial_cycle_todo=4096/2;
974 	  //serial_cycle_todo=1024;
975 	} else {
976 	  gbserial.wait=1;
977 	  // gbserial_send(SB);	/* External Clock */
978 	  //gbserial.check=1;
979 	  //serial_cycle_todo=4096;
980 	  //	  gbserial_send(SB);
981 	}
982 	SC=(v&0x81);
983       } else {
984 	//SB=0xff;
985 	//gbserial.check=0;
986       }
987 
988       /*if ((v&0x81)==0x81) {
989 	gbserial_send(SB);
990 	serial_cycle_todo=4096;
991 	} */
992       SC=(v&0x81);
993     }
994 
995     /*    if (conf.serial_on) {
996       if ((v&0x81)==0x81) {
997 	gbserial_send(SB);
998 	//serial_cycle_todo=4096*2;
999       }
1000     }
1001     SB=0xff;
1002     SC=v&0x7f;*/
1003     break;
1004   case 0xff0f:
1005     unset_interrupt(((INT_FLAG)^(v&0x1f))^(v&0x1f));
1006     if (v&0x1f) set_interrupt(v&0x1f);
1007     break;
1008   case 0xffff:
1009     INT_ENABLE=v&0x1f;
1010     break;
1011   case 0xff04:DIVID=0;break;
1012   case 0xff05:
1013     TIME_COUNTER=v;
1014     /* FIXME */
1015     gbtimer->cycle=0;
1016     break;
1017   case 0xff06:
1018     TIME_MOD=v;
1019     break;
1020   case 0xff07:
1021     if (v&4) {
1022       switch(v&3) {
1023       case 0: gbtimer->clk_inc=1024;break;
1024       case 1: gbtimer->clk_inc=16;break;
1025       case 2: gbtimer->clk_inc=64;break;
1026       case 3: gbtimer->clk_inc=256;break;
1027       }
1028     } else gbtimer->clk_inc=0;
1029     gbtimer->cycle=gbtimer->clk_inc;
1030     /* FIXME */
1031     /*if (!(TIME_CONTROL&0x04))
1032       gbtimer->cycle+=gbtimer->clk_inc;
1033       else gbtimer->cycle=gbtimer->clk_inc;*/
1034     //    if ((v&0x04) && !(TIME_CONTROL&0x04)) gbtimer->cycle=0;
1035     TIME_CONTROL=v;
1036     break;
1037   case 0xff40:
1038     write2lcdccont(v);
1039     break;
1040   case 0xff41:
1041     /* Emulate Normal Gameboy Bug (fix Legend Of Zerd) */
1042     if (!(conf.gb_type&COLOR_GAMEBOY)) {
1043       //if (!(LCDCSTAT&0x03) || (LCDCSTAT&0x03)==0x01) set_interrupt(LCDC_INT);
1044       if (!(LCDCSTAT&0x02))
1045 	/* FIXME: Stat write bug */
1046 	set_interrupt(LCDC_INT);
1047       //if ((v&0x20) && (!(LCDCSTAT&0x20)) && (LCDCSTAT&0x02)) set_interrupt(LCDC_INT);
1048 
1049       LCDCSTAT=(LCDCSTAT&0x07)|(v&0x78);
1050       if (CURLINE<0x91 && CURLINE==CMP_LINE) {
1051 	LCDCSTAT|=0x04;
1052 	if (LCDCSTAT&0x40 && LCDCCONT&0x80) set_interrupt(LCDC_INT);
1053       }
1054     } else {
1055       /*FIXME: LCDCSTAT write */
1056       LCDCSTAT=(LCDCSTAT&0x07)|(v&0x78);
1057       if (CURLINE<0x91 && CURLINE==CMP_LINE) {
1058 	LCDCSTAT|=0x04;
1059 	if (LCDCSTAT&0x40 && LCDCCONT&0x80) set_interrupt(LCDC_INT);
1060       }
1061     }
1062     break;
1063   case 0xff44:
1064     CURLINE=0;
1065     if (LCDCCONT&0x80) gblcdc_set_on();
1066     break;
1067   case 0xff45:CMP_LINE=v;
1068     /* FIXME */
1069     if (CURLINE==CMP_LINE) LCDCSTAT|=0x04;
1070     else LCDCSTAT&=~0x04;
1071     if (LCDCCONT&0x80 && LCDCSTAT&0x40 && LCDCSTAT&0x04 && (LCDCSTAT&0x02)==0x02)
1072       set_interrupt(LCDC_INT);
1073     break;
1074   case 0xff46:      // DMA
1075     do_dma(v);
1076     break;
1077   case 0xff47:
1078     gb_set_pal_bck(v);
1079     break;
1080   case 0xff48:
1081     OBJ0PAL=v;
1082     pal_obj[0][0]=OBJ0PAL&3;
1083     pal_obj[0][1]=(OBJ0PAL>>2)&3;
1084     pal_obj[0][2]=(OBJ0PAL>>4)&3;
1085     pal_obj[0][3]=(OBJ0PAL>>6)&3;
1086     break;
1087   case 0xff49:
1088     OBJ1PAL=v;
1089     pal_obj[1][0]=OBJ1PAL&3;
1090     pal_obj[1][1]=(OBJ1PAL>>2)&3;
1091     pal_obj[1][2]=(OBJ1PAL>>4)&3;
1092     pal_obj[1][3]=(OBJ1PAL>>6)&3;
1093     break;
1094   case 0xff4d:CPU_SPEED=0x80;break;
1095   default:
1096     himem[adr-0xfea0]=v;
1097     break;
1098   }
1099 }
1100 
1101 /* Mbc1 */
1102 
mbc1_write_4000_5fff(Uint16 adr,Uint8 v)1103 void mbc1_write_4000_5fff(Uint16 adr,Uint8 v) {
1104   if (mbc1_mem_mode==MBC1_16_8_MEM_MODE)
1105     mbc1_line=v&0x03;
1106   else set_active_ram_page(v);
1107 }
1108 
mbc1_write_6000_7fff(Uint16 adr,Uint8 v)1109 void mbc1_write_6000_7fff(Uint16 adr,Uint8 v) {
1110  if (!v) mbc1_mem_mode=MBC1_16_8_MEM_MODE;
1111  else if (v==1) mbc1_mem_mode=MBC1_4_32_MEM_MODE;
1112 }
1113 
1114 /* Rumble */
1115 
rumble_write_4000_5fff(Uint16 adr,Uint8 v)1116 void rumble_write_4000_5fff(Uint16 adr,Uint8 v) {
1117   /* FIXME: Rumble write v&0x08 we must active ram Page ????? */
1118   set_active_ram_page(v);
1119   if (conf.rumble_on && v&0x08) rb_on=1;
1120 }
1121 
1122 /* Timer */
1123 
rom_timer_lock(void)1124 __inline__ void rom_timer_lock(void) {
1125   memcpy(rom_timer->regl,rom_timer->reg,sizeof(Uint8)*5);
1126 }
1127 
rom_timer_write(Uint8 v)1128 __inline__ void rom_timer_write(Uint8 v) {
1129   if (!(rom_timer->reg_sel&0x08)) return;
1130   switch(rom_timer->reg_sel&0x07) {
1131   case 0x00:rom_timer->reg[0]=(v%60);break;  // seconds
1132   case 0x01:rom_timer->reg[1]=(v%60);break;  // minutes
1133   case 0x02:rom_timer->reg[2]=(v%24);break;  // hours
1134   case 0x03:rom_timer->reg[3]=v;break;       // dayl
1135   case 0x04:rom_timer->reg[4]=v;break;       // dayh,start|stop,day carry
1136   }
1137 }
1138 
timer_write_a000_bfff(Uint16 adr,Uint8 v)1139 void timer_write_a000_bfff(Uint16 adr,Uint8 v) {
1140   /* FIXME: timer write and ram enable ????? */
1141   if (!ram_enable) return;
1142   if (rom_timer->reg_sel&0x08) {
1143     rom_timer_write(v);
1144     return;
1145   }
1146   ram_page[active_ram_page][adr-0xa000]=v;
1147 }
1148 
timer_write_4000_5fff(Uint16 adr,Uint8 v)1149 void timer_write_4000_5fff(Uint16 adr,Uint8 v) {
1150   rom_timer->reg_sel=v&0x0f;
1151 }
1152 
timer_write_6000_7fff(Uint16 adr,Uint8 v)1153 void timer_write_6000_7fff(Uint16 adr,Uint8 v) {
1154   if (!rom_timer->latch && v) rom_timer_lock();
1155   rom_timer->latch=v;
1156 }
1157 
1158 
1159 /* Write Function Default */
1160 
mem_write_0000_1fff_default(Uint16 adr,Uint8 v)1161 void mem_write_0000_1fff_default(Uint16 adr,Uint8 v) {
1162   if ((v&0x0f)==0x0a) enable_ram();
1163   else disable_ram();
1164 }
1165 
mem_write_2000_3fff_default(Uint16 adr,Uint8 v)1166 void mem_write_2000_3fff_default(Uint16 adr,Uint8 v) {
1167   select_rom_page(adr,v);
1168 }
1169 
mem_write_4000_5fff_default(Uint16 adr,Uint8 v)1170 void mem_write_4000_5fff_default(Uint16 adr,Uint8 v) {
1171   set_active_ram_page(v);
1172 }
1173 
mem_write_6000_7fff_default(Uint16 adr,Uint8 v)1174 void mem_write_6000_7fff_default(Uint16 adr,Uint8 v) {
1175   //printf("WARNING: Write %02x at %04x\n",v,adr);
1176 }
1177 
mem_write_a000_bfff_default(Uint16 adr,Uint8 v)1178 void mem_write_a000_bfff_default(Uint16 adr,Uint8 v) {
1179   if (!ram_enable) return;
1180   ram_page[active_ram_page][adr-0xa000]=v;
1181 }
1182 
1183 /*void mem_write_c000_dfff_default(Uint16 adr,Uint8 v) {
1184   Uint8 bk;
1185   bk=(adr&0xf000)>>12;
1186   switch(bk) {
1187   case 0xc:wram_page[0][adr-0xc000]=v;return;
1188   case 0xd:wram_page[active_wram_page][adr-0xd000]=v;return;
1189   }
1190 }
1191 
1192 void mem_write_e000_efff_default(Uint16 adr,Uint8 v) {
1193   wram_page[0][adr-0xe000]=v;
1194   }*/
1195 
mem_write_f000_ffff_default(Uint16 adr,Uint8 v)1196 void mem_write_f000_ffff_default(Uint16 adr,Uint8 v) {
1197   if (adr>=0xff00) {
1198     mem_write_ff(adr,v);
1199     return;
1200   }
1201   if (adr>=0xfe00 && adr<0xfea0) {
1202     oam_space[adr-0xfe00]=v;
1203     return;
1204   }
1205   if (adr>=0xfea0 && adr<0xff00) {
1206     himem[adr-0xfea0]=v;
1207     return;
1208   }
1209   wram_page[active_wram_page][adr-0xf000]=v;
1210 }
1211 
1212 
1213 /*void mem_write_0000_7fff(Uint16 adr,Uint8 v) {
1214   Uint8 bk;
1215 
1216   bk=(adr&0xf000)>>12;
1217   switch(bk) {
1218   case 0:
1219   case 1:
1220     if ((v&0x0f)==0x0a) enable_ram();
1221     else disable_ram();
1222     return;
1223   case 2:
1224   case 3:select_rom_page(adr,v);return;
1225   case 4:
1226   case 5:
1227     if (rom_type&MBC1) {
1228       if (mbc1_mem_mode==MBC1_16_8_MEM_MODE)
1229 	mbc1_line=v&0x03;
1230       else set_active_ram_page(v);
1231       return;
1232     }
1233     else set_active_ram_page(v);
1234     if (rom_type&RUMBLE && conf.rumble_on && v&0x08) rb_on=1;
1235     if (rom_type&TIMER) rom_timer->reg_sel=v&0x0f;
1236     return;
1237   case 6:
1238   case 7:
1239     if (rom_type&MBC1) {
1240       if (!v) mbc1_mem_mode=MBC1_16_8_MEM_MODE;
1241       else if (v==1) mbc1_mem_mode=MBC1_4_32_MEM_MODE;
1242       return;
1243     }
1244     if (rom_type&TIMER) {
1245       if (!rom_timer->latch && v) rom_timer_lock();
1246       rom_timer->latch=v;
1247     }
1248     return;
1249   default:
1250     printf("Warning: Write 0000 7fff bank %02x\n",bk);break;
1251   }
1252   }*/
1253 
mem_write_default(Uint16 adr,Uint8 v)1254 void mem_write_default(Uint16 adr,Uint8 v)
1255 {
1256   Uint8 bk;
1257 
1258   if (adr>=0xfe00 && adr<0xfea0) {
1259     oam_space[adr-0xfe00]=v;
1260     return;
1261   }
1262 
1263   if (adr>=0xfea0 && adr<0xff00) {
1264     himem[adr-0xfea0]=v;
1265     return;
1266   }
1267 
1268   if (adr>=0xff00) {
1269     mem_write_ff(adr,v);
1270     return;
1271   }
1272 
1273   if (adr>=0xe000 && adr<0xfe00) adr-=0x2000;  // echo mem
1274 
1275   bk=(adr&0xf000)>>12;
1276   switch(bk) {
1277   case 0:
1278   case 1:
1279     if ((v&0x0f)==0x0a) enable_ram();
1280     else disable_ram();
1281     return;
1282     //ram_enable=((v&0x0f)==0x0a)?(1):(0);return;
1283   case 2:
1284   case 3:select_rom_page(adr,v);return;
1285   case 4:
1286   case 5:
1287     if (rom_type&MBC1) {
1288       if (mbc1_mem_mode==MBC1_16_8_MEM_MODE)
1289 	mbc1_line=v&0x03;
1290       else set_active_ram_page(v);
1291       return;
1292     }
1293     else set_active_ram_page(v);
1294 
1295     if (rom_type&RUMBLE && conf.rumble_on && v&0x08) rb_on=1;
1296 
1297     if (rom_type&TIMER) {
1298       rom_timer->reg_sel=v&0x0f;
1299       //      printf("select %02x \n",rom_timer->reg_sel);
1300     }
1301     return;
1302   case 6:
1303   case 7:
1304     if (rom_type&MBC1) {
1305       if (!v) mbc1_mem_mode=MBC1_16_8_MEM_MODE;
1306       else if (v==1) mbc1_mem_mode=MBC1_4_32_MEM_MODE;
1307       return;
1308     }
1309     if (rom_type&TIMER) {
1310       if (!rom_timer->latch && v) rom_timer_lock();
1311       rom_timer->latch=v;
1312     }
1313     return;
1314   case 8:
1315   case 9:vram_page[active_vram_page][adr-0x8000]=v;return;
1316   case 0xa:
1317   case 0xb:
1318     if (!ram_enable) return;
1319     if (rom_type&TIMER && rom_timer->reg_sel&0x08) {
1320       rom_timer_write(v);
1321       return;
1322     }
1323     ram_page[active_ram_page][adr-0xa000]=v;
1324     return;
1325   case 0xc:wram_page[0][adr-0xc000]=v;return;
1326   case 0xd:wram_page[active_wram_page][adr-0xd000]=v;return;
1327   }
1328 }
1329