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