1 /*  gngeo a neogeo emulator
2  *  Copyright (C) 2001 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 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22 
23 #include "emu.h"
24 #include "video.h"
25 #include "memory.h"
26 #include "pd4990a.h"
27 #include "transpack.h"
28 
29 #ifdef GP2X
30 #include "ym2610-940/940shared.h"
31 #endif
32 
33 Uint32 bankaddress = 0;
34 extern int current_line;
35 
36 
37 
neogeo_sound_irq(int irq)38 void neogeo_sound_irq(int irq) {
39 	//printf("neogeo_sound_irq %d\n",irq);
40 #ifndef ENABLE_940T
41 	if (irq) {
42 		cpu_z80_raise_irq(0);
43 	} else
44 	cpu_z80_lower_irq();
45 #endif
46 	//printf("neogeo_sound_end %d\n",irq);
47 }
48 
read_neo_control(void)49 static __inline__ Uint16 read_neo_control(void) {
50 	unsigned int scan;
51 
52 	if (!conf.raster) {
53 
54 #ifdef PROCESSOR_ARM
55 #ifdef USE_CYCLONE
56 		scan = current_line;
57 		/*
58 		 printf("%d %d %d\n",current_line,
59 		 (cpu_68k_getcycle()/3)>>7,
60 		 (int)(cpu_68k_getcycle() / 766.28));
61 		 */
62 #else
63 		scan = cpu_68k_getcycle()/3;
64 		scan = scan>>7;
65 #endif
66 #else
67 		scan = cpu_68k_getcycle() / 766.28; /* current scanline */
68 #endif
69 
70 		//	scan+=0x100;
71 		//	if (scan >=0x200) scan=scan-0x108;
72 		scan += 0xF8;
73 
74 		return (scan << 7) | (conf.pal << 3) | (neogeo_frame_counter & 0x0007); /* frame counter */
75 
76 	} else {
77 		scan = current_line /*+ 22*/; /* current scanline */
78 		//scan+=0x110;
79 		//if (scan >=0x200) scan=scan-0x108;
80 		scan += 0xF8;
81 
82 		return (scan << 7) | (conf.pal << 3) | (neogeo_frame_counter & 0x0007); /* frame counter */
83 	}
84 }
85 
write_neo_control(Uint16 data)86 __inline__ void write_neo_control(Uint16 data) {
87 	neogeo_frame_counter_speed = (((data >> 8) & 0xff) + 1);
88 	memory.vid.irq2control = data & 0xff;
89 	return;
90 }
91 
write_irq2pos(Uint32 data)92 __inline__ void write_irq2pos(Uint32 data) {
93 	memory.vid.irq2pos = data;
94 	if (memory.vid.irq2control & 0x20) {
95 		int line = (memory.vid.irq2pos + 0x3b) / 0x180; /* turfmast goes as low as 0x145 */
96 		memory.vid.irq2start = line + current_line;
97 	}
98 }
99 
100 #ifndef ENABLE_940T
101 /* Z80 IO port handler */
z80_port_read(Uint16 PortNo)102 Uint8 z80_port_read(Uint16 PortNo)
103 {
104 	//printf("z80_port_read PC=%04x p=%04x ",cpu_z80_get_pc(),PortNo);
105 	//printf("z80_port_read p=%04x \n",PortNo);
106 	switch (PortNo & 0xff) {
107 		case 0x0:
108 		pending_command = 0;
109 		//printf("Reseting command. Return sndcode %x\n",sound_code);
110 		return sound_code;
111 		break;
112 
113 		case 0x4:
114 		//printf("v=%02x\n",YM2610_status_port_0_A_r(0));
115 		return YM2610_status_port_A_r(0);
116 		break;
117 
118 		case 0x5:
119 		//printf("v=%02x\n",YM2610_read_port_0_r(0));
120 		return YM2610_read_port_r(0);
121 		break;
122 
123 		case 0x6:
124 		//printf("v=%02x\n",YM2610_status_port_0_B_r(0));
125 		return YM2610_status_port_B_r(0);
126 		break;
127 
128 		case 0x08:
129 		//printf("v=00 (sb3)\n");
130 		cpu_z80_switchbank(3, PortNo);
131 		return 0;
132 		break;
133 
134 		case 0x09:
135 		//printf("v=00 (sb2)\n");
136 		cpu_z80_switchbank(2, PortNo);
137 		return 0;
138 		break;
139 
140 		case 0x0a:
141 		//printf("v=00 (sb1)\n");
142 		cpu_z80_switchbank(1, PortNo);
143 		return 0;
144 		break;
145 
146 		case 0x0b:
147 		//printf("v=00 (sb0)\n");
148 		cpu_z80_switchbank(0, PortNo);
149 		return 0;
150 		break;
151 	};
152 
153 	return 0;
154 }
155 
z80_port_write(Uint16 PortNb,Uint8 Value)156 void z80_port_write(Uint16 PortNb, Uint8 Value)
157 {
158 	Uint8 data = Value;
159 	//printf("z80_port_write PC=%04x OP=%02x p=%04x v=%02x\n",cpu_z80_get_pc(),memory.rom.cpu_z80.p[cpu_z80_get_pc()],PortNb,Value);
160 	//printf("Write port %04x %02x\n",PortNb,Value);
161 	switch (PortNb & 0xff) {
162 		case 0x4:
163 		YM2610_control_port_A_w(0, data);
164 		break;
165 
166 		case 0x5:
167 		YM2610_data_port_A_w(0, data);
168 		break;
169 
170 		case 0x6:
171 		YM2610_control_port_B_w(0, data);
172 		break;
173 
174 		case 0x7:
175 		YM2610_data_port_B_w(0, data);
176 		break;
177 
178 		case 0xC:
179 		//printf("Setting result code to %0x\n",Value);
180 		result_code = Value;
181 		break;
182 	}
183 }
184 #endif
185 
186 /* Protection hack */
protection_9a37(Uint32 addr)187 Uint16 protection_9a37(Uint32 addr) {
188 	return 0x9a37;
189 }
190 
191 /* fetching function */
192 /**** INVALID FETCHING ****/
mem68k_fetch_invalid_byte(Uint32 addr)193 Uint8 mem68k_fetch_invalid_byte(Uint32 addr) {
194 	return 0xF0;
195 }
196 
mem68k_fetch_invalid_word(Uint32 addr)197 Uint16 mem68k_fetch_invalid_word(Uint32 addr) {
198 	return 0xF0F0;
199 }
200 
mem68k_fetch_invalid_long(Uint32 addr)201 Uint32 mem68k_fetch_invalid_long(Uint32 addr) {
202 	return 0xF0F0F0F0;
203 }
204 
205 /**** RAM FETCHING ****/
mem68k_fetch_ram_byte(Uint32 addr)206 Uint8 mem68k_fetch_ram_byte(Uint32 addr) {
207 	//  printf("mem68k_fetch_ram_byte %x\n",addr);
208 	addr &= 0xffff;
209 	return (READ_BYTE_ROM(memory.ram + addr));
210 }
211 
mem68k_fetch_ram_word(Uint32 addr)212 Uint16 mem68k_fetch_ram_word(Uint32 addr) {
213 	//printf("mem68k_fetch_ram_word %08x %04x\n",addr,READ_WORD_RAM(memory.ram + (addr&0xffff)));
214 	addr &= 0xffff;
215 	return (READ_WORD_ROM(memory.ram + addr));
216 }
217 
218 LONG_FETCH(mem68k_fetch_ram)
219 ;
220 
221 /**** CPU ****/
mem68k_fetch_cpu_byte(Uint32 addr)222 Uint8 mem68k_fetch_cpu_byte(Uint32 addr) {
223 	addr &= 0xFFFFF;
224 
225 	return (READ_BYTE_ROM(memory.rom.cpu_m68k.p + addr));
226 }
227 
mem68k_fetch_cpu_word(Uint32 addr)228 Uint16 mem68k_fetch_cpu_word(Uint32 addr) {
229 	addr &= 0xFFFFF;
230 
231 	return (READ_WORD_ROM(memory.rom.cpu_m68k.p + addr));
232 }
233 
234 LONG_FETCH(mem68k_fetch_cpu)
235 ;
236 
237 /**** BIOS ****/
mem68k_fetch_bios_byte(Uint32 addr)238 Uint8 mem68k_fetch_bios_byte(Uint32 addr) {
239 	addr &= 0x1FFFF;
240 	return (READ_BYTE_ROM(memory.rom.bios_m68k.p + addr));
241 }
242 
mem68k_fetch_bios_word(Uint32 addr)243 Uint16 mem68k_fetch_bios_word(Uint32 addr) {
244 	addr &= 0x1FFFF;
245 	return (READ_WORD_ROM(memory.rom.bios_m68k.p + addr));
246 }
247 
248 LONG_FETCH(mem68k_fetch_bios)
249 ;
250 
251 /**** SRAM ****/
mem68k_fetch_sram_byte(Uint32 addr)252 Uint8 mem68k_fetch_sram_byte(Uint32 addr) {
253 	return memory.sram[addr - 0xd00000];
254 }
255 
mem68k_fetch_sram_word(Uint32 addr)256 Uint16 mem68k_fetch_sram_word(Uint32 addr) {
257 	addr -= 0xd00000;
258 	return (memory.sram[addr] << 8) | (memory.sram[addr + 1] & 0xff);
259 }
260 
261 LONG_FETCH(mem68k_fetch_sram)
262 ;
263 
264 /**** PALETTE ****/
mem68k_fetch_pal_byte(Uint32 addr)265 Uint8 mem68k_fetch_pal_byte(Uint32 addr) {
266 	addr &= 0xffff;
267 	if (addr <= 0x1fff)
268 		return current_pal[addr];
269 	return 0;
270 }
271 
mem68k_fetch_pal_word(Uint32 addr)272 Uint16 mem68k_fetch_pal_word(Uint32 addr) {
273 	addr &= 0xffff;
274 	if (addr <= 0x1fff)
275 		return READ_WORD(&current_pal[addr]);
276 	return 0;
277 }
278 
279 LONG_FETCH(mem68k_fetch_pal)
280 ;
281 
282 /**** VIDEO ****/
mem68k_fetch_video_byte(Uint32 addr)283 Uint8 mem68k_fetch_video_byte(Uint32 addr) {
284 	//printf("mem6k_fetch_video_byte %08x\n",addr);
285 	if (!(addr&0x1))
286 			return mem68k_fetch_video_word(addr)>>8;
287 	else {
288 		Uint32 lpc=cpu_68k_getpc()+2;
289 		switch((lpc&0xF00000)>>20) {
290 		case 0x0:
291 			return READ_WORD(&memory.rom.cpu_m68k.p+(lpc&0xFFFFF));
292 			break;
293 		case 0x2:
294 			return READ_WORD(&memory.rom.cpu_m68k.p+bankaddress+(lpc&0xFFFFF));
295 			break;
296 		case 0xC:
297 			if (lpc<=0xc1FFff)
298 				return READ_WORD(&memory.rom.bios_m68k.p+(lpc&0xFFFFF));
299 			break;
300 		}
301 	}
302 //	addr &= 0xFFFF;
303 //	if (addr == 0xe)
304 //		return 0xff;
305 	return 0xFF;
306 }
307 
mem68k_fetch_video_word(Uint32 addr)308 Uint16 mem68k_fetch_video_word(Uint32 addr) {
309 	//printf("mem68k_fetch_video_word %08x\n",addr);
310 	addr &= 0x7;
311 	/*
312 	 if (addr==0x00)
313 	 return vptr;
314 	 */
315 	if (addr == 0x00 || addr == 0x02 || addr == 0x0a)
316 		return memory.vid.rbuf;//READ_WORD(&memory.vid.ram[memory.vid.vptr << 1]);
317 	if (addr == 0x04)
318 		return memory.vid.modulo;
319 	if (addr == 0x06)
320 		return read_neo_control();
321 	return 0;
322 }
323 LONG_FETCH(mem68k_fetch_video)
324 ;
325 
326 /**** CONTROLLER ****/
mem68k_fetch_ctl1_byte(Uint32 addr)327 Uint8 mem68k_fetch_ctl1_byte(Uint32 addr) {
328 	addr &= 0xFFFF;
329 	if (addr == 0x00)
330 		return memory.intern_p1;
331 	if (addr == 0x01)
332 		return (conf.test_switch ? 0xFE : 0xFF);
333 
334 	if (addr == 0x81) {
335 		return (conf.test_switch ? 0x00 : 0x80);
336 	}
337 
338 	return 0;
339 }
340 
mem68k_fetch_ctl1_word(Uint32 addr)341 Uint16 mem68k_fetch_ctl1_word(Uint32 addr) {
342 	//  printf("mem68k_fetch_ctl1_word\n");
343 	return 0;
344 }
345 
mem68k_fetch_ctl1_long(Uint32 addr)346 Uint32 mem68k_fetch_ctl1_long(Uint32 addr) {
347 	//  printf("mem68k_fetch_ctl1_long\n");
348 	return 0;
349 }
350 
mem68k_fetch_ctl2_byte(Uint32 addr)351 Uint8 mem68k_fetch_ctl2_byte(Uint32 addr) {
352 	if ((addr & 0xFFFF) == 0x00)
353 		return memory.intern_p2;
354 	if ((addr & 0xFFFF) == 0x01)
355 		return 0xFF;
356 	return 0;
357 }
358 
mem68k_fetch_ctl2_word(Uint32 addr)359 Uint16 mem68k_fetch_ctl2_word(Uint32 addr) {
360 	return 0;
361 }
362 
mem68k_fetch_ctl2_long(Uint32 addr)363 Uint32 mem68k_fetch_ctl2_long(Uint32 addr) {
364 	return 0;
365 }
366 
mem68k_fetch_ctl3_byte(Uint32 addr)367 Uint8 mem68k_fetch_ctl3_byte(Uint32 addr) {
368 	//printf("Fetch ctl3 byte %x\n",addr);
369 	if ((addr & 0xFFFF) == 0x0)
370 		return memory.intern_start;
371 	return 0;
372 }
373 
mem68k_fetch_ctl3_word(Uint32 addr)374 Uint16 mem68k_fetch_ctl3_word(Uint32 addr) {
375 	/*
376 	 printf("Fetch ctl3 word %x\n",addr);
377 	 if ((addr & 0xFFFF) == 0x0)
378 	 return memory.intern_start | 0xFF00;
379 	 */
380 	return 0;
381 }
382 
mem68k_fetch_ctl3_long(Uint32 addr)383 Uint32 mem68k_fetch_ctl3_long(Uint32 addr) {
384 	return 0;
385 }
386 
mem68k_fetch_coin_byte(Uint32 addr)387 Uint8 mem68k_fetch_coin_byte(Uint32 addr) {
388 	addr &= 0xFFFF;
389 	if (addr == 0x1) {
390 		int coinflip = read_4990_testbit();
391 		int databit = read_4990_databit();
392 		return memory.intern_coin ^ (coinflip << 6) ^ (databit << 7);
393 	}
394 	if (addr == 0x0) {
395 		int res = 0;
396 		if (conf.sound) {
397 			//printf("fetch coin byte, rescoe= %x\n",result_code);
398 #ifdef ENABLE_940T
399 
400 			res |= shared_ctl->result_code;
401 			if (shared_ctl->pending_command)
402 				res &= 0x7f;
403 #else
404 			res |= result_code;
405 			if (pending_command)
406 			res &= 0x7f;
407 #endif
408 		} else {
409 			res |= 0x01;
410 		}
411 		return res;
412 	}
413 	return 0;
414 }
415 
mem68k_fetch_coin_word(Uint32 addr)416 Uint16 mem68k_fetch_coin_word(Uint32 addr) {
417 	return 0;
418 }
419 
mem68k_fetch_coin_long(Uint32 addr)420 Uint32 mem68k_fetch_coin_long(Uint32 addr) {
421 	return 0;
422 }
423 
424 /**** MEMCARD ****/
425 /* Even byte are FF
426  Odd  byte are data;
427  */
mem68k_fetch_memcrd_byte(Uint32 addr)428 Uint8 mem68k_fetch_memcrd_byte(Uint32 addr) {
429 	addr &= 0xFFF;
430 	if (addr & 1)
431 		return 0xFF;
432 	else
433 		return memory.memcard[addr >> 1];
434 }
435 
mem68k_fetch_memcrd_word(Uint32 addr)436 Uint16 mem68k_fetch_memcrd_word(Uint32 addr) {
437 	addr &= 0xFFF;
438 	return memory.memcard[addr >> 1] | 0xff00;
439 }
440 
mem68k_fetch_memcrd_long(Uint32 addr)441 Uint32 mem68k_fetch_memcrd_long(Uint32 addr) {
442 	return 0;
443 }
444 
445 /* storring function */
446 /**** INVALID STORE ****/
mem68k_store_invalid_byte(Uint32 addr,Uint8 data)447 void mem68k_store_invalid_byte(Uint32 addr, Uint8 data) {
448 	if (addr != 0x300001)
449 		printf("Invalid write b %x %x \n", addr, data);
450 	else {
451 		memory.watchdog = 0;
452 		//printf("restet_watchdog\n");
453 	}
454 }
mem68k_store_invalid_word(Uint32 addr,Uint16 data)455 void mem68k_store_invalid_word(Uint32 addr, Uint16 data) {
456 	printf("Invalid write w %x %x \n", addr, data);
457 }
mem68k_store_invalid_long(Uint32 addr,Uint32 data)458 void mem68k_store_invalid_long(Uint32 addr, Uint32 data) {
459 	printf("Invalid write l %x %x \n", addr, data);
460 }
461 
462 /**** RAM ****/
mem68k_store_ram_byte(Uint32 addr,Uint8 data)463 void mem68k_store_ram_byte(Uint32 addr, Uint8 data) {
464 	addr &= 0xffff;
465 	WRITE_BYTE_ROM(memory.ram + addr,data);
466 	return;
467 }
468 
mem68k_store_ram_word(Uint32 addr,Uint16 data)469 void mem68k_store_ram_word(Uint32 addr, Uint16 data) {
470 	//printf("Store rom word %08x %04x\n",addr,data);
471 	addr &= 0xffff;
472 	WRITE_WORD_ROM(memory.ram + addr,data);
473 	return;
474 }
475 
476 LONG_STORE(mem68k_store_ram)
477 ;
478 
479 /**** SRAM ****/
mem68k_store_sram_byte(Uint32 addr,Uint8 data)480 void mem68k_store_sram_byte(Uint32 addr, Uint8 data) {
481 	if (sram_lock)
482 		return;
483 	/*
484 	 if (addr == 0xd00000 + sram_protection_hack && ((data & 0xff) == 0x01))
485 	 return;
486 	 */
487 	memory.sram[addr - 0xd00000] = data;
488 }
489 
mem68k_store_sram_word(Uint32 addr,Uint16 data)490 void mem68k_store_sram_word(Uint32 addr, Uint16 data) {
491 	if (sram_lock)
492 		return;
493 	/*
494 	 if (addr == 0xd00000 + sram_protection_hack
495 	 && ((data & 0xffff) == 0x01))
496 	 return;
497 	 */
498 	addr -= 0xd00000;
499 	memory.sram[addr] = data >> 8;
500 	memory.sram[addr + 1] = data & 0xff;
501 }
502 
503 LONG_STORE(mem68k_store_sram)
504 ;
505 
506 /**** PALETTE ****/
convert_pal(Uint16 npal)507 /*static __inline__ */Uint16 convert_pal(Uint16 npal) {
508 	int r = 0, g = 0, b = 0;
509 	r = ((npal >> 7) & 0x1e) | ((npal >> 14) & 0x01);
510 	g = ((npal >> 3) & 0x1e) | ((npal >> 13) & 0x01);
511 	b = ((npal << 1) & 0x1e) | ((npal >> 12) & 0x01);
512 
513 	return (r << 11) + (g << 6) + b;
514 }
515 
update_all_pal(void)516 void update_all_pal(void) {
517 	int i;
518 	Uint32 *pc_pal1 = (Uint32*) memory.vid.pal_host[0];
519 	Uint32 *pc_pal2 = (Uint32*) memory.vid.pal_host[1];
520 	for (i = 0; i < 0x1000; i++) {
521 		//pc_pal1[i] = convert_pal(READ_WORD_ROM(&memory.pal1[i<<1]));
522 		//pc_pal2[i] = convert_pal(READ_WORD_ROM(&memory.pal2[i<<1]));
523 		pc_pal1[i] = convert_pal(READ_WORD(&memory.vid.pal_neo[0][i<<1]));
524 		pc_pal2[i] = convert_pal(READ_WORD(&memory.vid.pal_neo[1][i<<1]));
525 	}
526 }
527 
mem68k_store_pal_byte(Uint32 addr,Uint8 data)528 void mem68k_store_pal_byte(Uint32 addr, Uint8 data) {
529 	/* TODO: verify this */
530 	addr &= 0xffff;
531 	if (addr <= 0x1fff) {
532 		Uint16 a = READ_WORD(&current_pal[addr & 0xfffe]);
533 		if (addr & 0x1)
534 			a = data | (a & 0xff00);
535 		else
536 			a = (a & 0xff) | (data << 8);
537 		WRITE_WORD(&current_pal[addr & 0xfffe], a);
538 		if ((addr >> 1) & 0xF)
539 			current_pc_pal[(addr) >> 1] = convert_pal(a);
540 		else
541 			current_pc_pal[(addr) >> 1] = 0xF81F;
542 	}
543 }
544 
mem68k_store_pal_word(Uint32 addr,Uint16 data)545 void mem68k_store_pal_word(Uint32 addr, Uint16 data) {
546 	//printf("Store pal word @ %08x %08x %04x\n",cpu_68k_getpc(),addr,data);
547 	addr &= 0xffff;
548 	if (addr <= 0x1fff) {
549 		WRITE_WORD(&current_pal[addr], data);
550 		if ((addr >> 1) & 0xF)
551 			current_pc_pal[(addr) >> 1] = convert_pal(data);
552 		else
553 			current_pc_pal[(addr) >> 1] = 0xF81F;
554 	}
555 }
556 
557 LONG_STORE(mem68k_store_pal)
558 ;
559 
560 /**** VIDEO ****/
mem68k_store_video_byte(Uint32 addr,Uint8 data)561 void mem68k_store_video_byte(Uint32 addr, Uint8 data) {
562 	/* garou write at 3c001f, 3c000f, 3c0015 */
563 	/* wjammers write, and fetch at 3c0000 .... */
564 	//printf("mem68k_store_video_byte %08x %02x @pc=%08x\n",addr,data,cpu_68k_getpc());
565 	if (!(addr&0x1)) {
566 		mem68k_store_video_word(addr,(data<<8)|data);
567 	}
568 }
569 
mem68k_store_video_word(Uint32 addr,Uint16 data)570 void mem68k_store_video_word(Uint32 addr, Uint16 data) {
571     //data&=0xFFFF;
572     //printf("mem68k_store_video_word %08x %04x @pc=%08x\n",addr,data,cpu_68k_getpc());
573 	addr &= 0xF;
574 	switch (addr) {
575 	case 0x0:
576 		memory.vid.vptr = data & 0xffff;
577 		memory.vid.rbuf = READ_WORD(&memory.vid.ram[memory.vid.vptr << 1]);
578 		break;
579 	case 0x2:
580 		//printf("Store %04x to video %08x @pc=%08x\n",data,vptr<<1,cpu_68k_getpc());
581 		WRITE_WORD(&memory.vid.ram[memory.vid.vptr << 1], data);
582 		memory.vid.vptr = (memory.vid.vptr & 0x8000) + ((memory.vid.vptr
583 				+ memory.vid.modulo) & 0x7fff);
584 		memory.vid.rbuf = READ_WORD(&memory.vid.ram[memory.vid.vptr << 1]);
585 		break;
586 	case 0x4:
587 		if (data&0x4000)
588 			data|=0x8000;
589 		else
590 			data&=0x7FFF;
591 
592 		memory.vid.modulo = (int) data;
593 		break;
594 	case 0x6:
595 		write_neo_control(data);
596 		break;
597 	case 0x8:
598 		write_irq2pos((memory.vid.irq2pos & 0xffff) | ((Uint32) data << 16));
599 		break;
600 	case 0xa:
601 		write_irq2pos((memory.vid.irq2pos & 0xffff0000) | (Uint32) data);
602 		break;
603 	case 0xc:
604 		/* games write 7 or 4 at 0x3c000c at every frame */
605 		/* IRQ acknowledge */
606 		break;
607 	}
608 
609 }
610 LONG_STORE(mem68k_store_video)
611 ;
612 
613 
614 /**** PD4990 ****/
mem68k_store_pd4990_byte(Uint32 addr,Uint8 data)615 void mem68k_store_pd4990_byte(Uint32 addr, Uint8 data) {
616 	write_4990_control_w(addr, data);
617 }
618 
mem68k_store_pd4990_word(Uint32 addr,Uint16 data)619 void mem68k_store_pd4990_word(Uint32 addr, Uint16 data) {
620 	write_4990_control_w(addr, data);
621 }
622 
mem68k_store_pd4990_long(Uint32 addr,Uint32 data)623 void mem68k_store_pd4990_long(Uint32 addr, Uint32 data) {
624 	write_4990_control_w(addr, data);
625 }
626 
627 /**** Z80 ****/
mem68k_store_z80_byte(Uint32 addr,Uint8 data)628 void mem68k_store_z80_byte(Uint32 addr, Uint8 data) {
629 	if (addr == 0x320000) {
630 		sound_code = data & 0xff;
631 		pending_command = 1;
632 		//printf("B Pending command. Sound_code=%02x\n",sound_code);
633 		if (conf.sound) {
634 #ifdef ENABLE_940T
635 			//printf("%d\n",shared_ctl->pending_command);
636 			shared_ctl->sound_code = sound_code;
637 			shared_ctl->pending_command = pending_command;
638 			//shared_ctl->pending_command=pending_command++;
639 			shared_ctl->nmi_pending = 1;
640 
641 			if (conf.accurate940) {
642 				while (CHECK_BUSY(JOB940_RUN_Z80)
643 						&& shared_ctl->pending_command)
644 					;
645 				if (shared_ctl->nmi_pending) {
646 					gp2x_add_job940(JOB940_RUN_Z80_NMI);
647 					while (CHECK_BUSY(JOB940_RUN_Z80_NMI))
648 						;
649 				}
650 			}
651 #else
652 			cpu_z80_nmi();
653 			cpu_z80_run(300);
654 #endif
655 		}
656 	}
657 }
mem68k_store_z80_word(Uint32 addr,Uint16 data)658 void mem68k_store_z80_word(Uint32 addr, Uint16 data) {
659 	/* tpgolf use word store for sound */
660 	if (addr == 0x320000) {
661 		sound_code = data >> 8;
662 		pending_command = 1;
663 		//printf("W Pending command. Sound_code=%02x\n",sound_code);
664 		if (conf.sound) {
665 #ifdef ENABLE_940T
666 			shared_ctl->sound_code = sound_code;
667 			shared_ctl->pending_command = pending_command;
668 			shared_ctl->nmi_pending = 1;
669 			if (conf.accurate940) {
670 				while (CHECK_BUSY(JOB940_RUN_Z80))
671 					;
672 				if (shared_ctl->nmi_pending) {
673 					gp2x_add_job940(JOB940_RUN_Z80_NMI);
674 					while (CHECK_BUSY(JOB940_RUN_Z80_NMI))
675 						;
676 				}
677 			}
678 #else
679 			cpu_z80_nmi();
680 			cpu_z80_run(300);
681 #endif
682 		}
683 	}
684 }
mem68k_store_z80_long(Uint32 addr,Uint32 data)685 void mem68k_store_z80_long(Uint32 addr, Uint32 data) {
686 	/* I don't think any game will use long store for sound.... */
687 	printf("Z80L %x %04x\n", addr, data);
688 }
689 
690 /**** SETTINGS ****/
mem68k_store_setting_byte(Uint32 addr,Uint8 data)691 void mem68k_store_setting_byte(Uint32 addr, Uint8 data) {
692 	//printf("mem68k_store_setting_byte %08x\n",addr);
693 	addr &= 0xFFFF;
694 	if (addr == 0x0003) {
695 		printf("Selecting Bios Vector\n");
696 		memcpy(memory.rom.cpu_m68k.p, memory.rom.bios_m68k.p, 0x80);
697 		memory.current_vector=0;
698 	}
699 
700 	if (addr == 0x0013) {
701 		printf("Selecting Game Vector\n");
702 		memcpy(memory.rom.cpu_m68k.p, memory.game_vector, 0x80);
703 		memory.current_vector=1;
704 	}
705 
706 	if (addr == 0x000b) { /* select board fix */
707 		current_fix = memory.rom.bios_sfix.p;
708 		fix_usage = memory.fix_board_usage;
709 		memory.vid.currentfix=0;
710 		return;
711 	}
712 	if (addr == 0x001b) { /* select game fix */
713 		current_fix = memory.rom.game_sfix.p;
714 		fix_usage = memory.fix_game_usage;
715 		memory.vid.currentfix=1;
716 		return;
717 	}
718 	if (addr == 0x000d) { /* sram lock */
719 		sram_lock = 1;
720 		return;
721 	}
722 	if (addr == 0x001d) { /* sram unlock */
723 		sram_lock = 0;
724 		return;
725 	}
726 	if (addr == 0x000f) { /* set palette 2 */
727 		current_pal = memory.vid.pal_neo[1];
728 		current_pc_pal = (Uint32 *) memory.vid.pal_host[1];
729 		memory.vid.currentpal=1;
730 		return;
731 	}
732 	if (addr == 0x001f) { /* set palette 1 */
733 		current_pal = memory.vid.pal_neo[0];
734 		current_pc_pal = (Uint32 *) memory.vid.pal_host[0];
735 		memory.vid.currentpal = 0;
736 		return;
737 	}
738 	/* garou write 0 to 3a0001 -> enable display, 3a0011 -> disable display */
739 	//printf("unknow mem68k_store_setting_byte %x %x\n",addr,data);
740 
741 }
742 
mem68k_store_setting_word(Uint32 addr,Uint16 data)743 void mem68k_store_setting_word(Uint32 addr, Uint16 data) {
744 	/* TODO: Some game use it */
745 	// printf("mem68k_store_setting_word USED????\n");
746 	mem68k_store_setting_byte(addr,data);
747 	return;
748 	addr &= 0xFFFFFe;
749 	if (addr == 0x3a0002) {
750 		memcpy(memory.rom.cpu_m68k.p, memory.rom.bios_m68k.p, 0x80);
751 	}
752 
753 	if (addr == 0x3a0012) {
754 		memcpy(memory.rom.cpu_m68k.p, memory.game_vector, 0x80);
755 	}
756 	if (addr == 0x3a000a) {
757 		current_fix = memory.rom.bios_sfix.p;
758 		fix_usage = memory.fix_board_usage;
759 		return;
760 	}
761 	if (addr == 0x3a001a) {
762 		current_fix = memory.rom.game_sfix.p;
763 		fix_usage = memory.fix_game_usage;
764 		return;
765 	}
766 	if (addr == 0x3a000c) {
767 		sram_lock = 1;
768 		return;
769 	}
770 	if (addr == 0x3a001c) {
771 		sram_lock = 0;
772 		return;
773 	}
774 	if (addr == 0x3a000e) {
775 		current_pal = memory.vid.pal_neo[1];
776 		current_pc_pal = (Uint32 *) memory.vid.pal_host[1];
777 		return;
778 	}
779 	if (addr == 0x3a001e) {
780 		current_pal = memory.vid.pal_neo[0];
781 		current_pc_pal = (Uint32 *) memory.vid.pal_host[0];
782 		return;
783 	}
784 }
785 
mem68k_store_setting_long(Uint32 addr,Uint32 data)786 void mem68k_store_setting_long(Uint32 addr, Uint32 data) {
787 	//printf("setting long\n");
788 }
789 
790 /**** MEMCARD ****/
mem68k_store_memcrd_byte(Uint32 addr,Uint8 data)791 void mem68k_store_memcrd_byte(Uint32 addr, Uint8 data) {
792 	addr &= 0xFFF;
793 	memory.memcard[addr >> 1] = data;
794 }
mem68k_store_memcrd_word(Uint32 addr,Uint16 data)795 void mem68k_store_memcrd_word(Uint32 addr, Uint16 data) {
796 	addr &= 0xFFF;
797 	memory.memcard[addr >> 1] = data & 0xff;
798 }
mem68k_store_memcrd_long(Uint32 addr,Uint32 data)799 void mem68k_store_memcrd_long(Uint32 addr, Uint32 data) {
800 }
801 
802 /**** bankswitchers ****/
803 static Uint16 neogeo_rng = 0x2345;
804 
sma_random(void)805 Uint16 sma_random(void) {
806 	Uint16 old = neogeo_rng;
807 
808 	Uint16 newbit = ((neogeo_rng >> 2) ^ (neogeo_rng >> 3) ^ (neogeo_rng >> 5)
809 			^ (neogeo_rng >> 6) ^ (neogeo_rng >> 7) ^ (neogeo_rng >> 11)
810 			^ (neogeo_rng >> 12) ^ (neogeo_rng >> 15)) & 1;
811 
812 	neogeo_rng = (neogeo_rng << 1) | newbit;
813 
814 	return old;
815 }
816 
817 /* Normal bankswitcher */
mem68k_fetch_bk_normal_byte(Uint32 addr)818 Uint8 mem68k_fetch_bk_normal_byte(Uint32 addr) {
819 	addr &= 0xFFFFF;
820     if (memory.bksw_unscramble) { /* SMA prot & random number generator */
821         Uint32 a=addr&0xFFFFFE;
822 		if (a == 0xfe446) {
823 			//printf("Prot reading B %08x\n", addr);
824 			return (addr&0x1?0x9a:0x37);
825 		}
826 		if (memory.sma_rng_addr && addr>=0x2fff00 &&
827             (((a & 0xFF) == (memory.sma_rng_addr & 0xFF)) ||
828              ((a & 0xFF) == memory.sma_rng_addr >> 8))) {
829             //printf("SMA_Random B %08x\n",addr);
830 			return (addr&0x1?sma_random()>>8:sma_random()&0xFF);
831         }
832 	}
833 	return (READ_BYTE_ROM(memory.rom.cpu_m68k.p + bankaddress + addr));
834 }
835 
mem68k_fetch_bk_normal_word(Uint32 addr)836 Uint16 mem68k_fetch_bk_normal_word(Uint32 addr) {
837 	addr &= 0xFFFFF;
838 	if (memory.bksw_unscramble) { /* SMA prot & random number generator */
839 		if (addr == 0xfe446) {
840 			//printf("Prot reading W %08x\n", addr);
841 			return 0x9a37;
842 		}
843 		if (memory.sma_rng_addr && addr>=0x2fff00 &&
844             (((addr & 0xFF) == (memory.sma_rng_addr & 0xFF)) ||
845              ((addr & 0xFF) == memory.sma_rng_addr >> 8))) {
846             //printf("SMA_Random W %08x\n",addr);
847 			return sma_random();
848         }
849 	}
850 	return (READ_WORD_ROM(memory.rom.cpu_m68k.p + bankaddress + addr));
851 }
852 
853 LONG_FETCH(mem68k_fetch_bk_normal)
854 ;
855 
bankswitch(Uint32 address,Uint8 data)856 static void bankswitch(Uint32 address, Uint8 data) {
857 
858 	if (memory.rom.cpu_m68k.size <= 0x100000)
859 		return;
860 
861 	if (address >= 0x2FFFF0) {
862 		data = data & 0x7;
863 		bankaddress = (data + 1) * 0x100000;
864 	} else
865 		return;
866 
867 	if (bankaddress >= memory.rom.cpu_m68k.size)
868 		bankaddress = 0x100000;
869 	cpu_68k_bankswitch(bankaddress);
870 }
871 
mem68k_store_bk_normal_byte(Uint32 addr,Uint8 data)872 void mem68k_store_bk_normal_byte(Uint32 addr, Uint8 data) {
873 	//if (addr<0x2FFFF0)
874 	//printf("bankswitch_b %x %x\n", addr, data);
875 	bankswitch(addr, data);
876 }
877 
mem68k_store_bk_normal_word(Uint32 addr,Uint16 data)878 void mem68k_store_bk_normal_word(Uint32 addr, Uint16 data) {
879 	//if (addr<0x2FFFF0)
880     //printf("bankswitch_w %x %x\n",addr,data);
881 	if (memory.bksw_unscramble && (addr & 0xFF) == memory.bksw_unscramble[0]) {
882 		/* unscramble bank number */
883 		data =
884             (((data >> memory.bksw_unscramble[1]) & 1) << 0) +
885             (((data	>> memory.bksw_unscramble[2]) & 1) << 1) +
886             (((data	>> memory.bksw_unscramble[3]) & 1) << 2) +
887             (((data	>> memory.bksw_unscramble[4]) & 1) << 3) +
888             (((data	>> memory.bksw_unscramble[5]) & 1) << 4) +
889             (((data	>> memory.bksw_unscramble[6]) & 1) << 5);
890 
891 		bankaddress = 0x100000 + memory.bksw_offset[data];
892 		cpu_68k_bankswitch(bankaddress);
893 	} else
894 		bankswitch(addr, data);
895 }
896 
897 LONG_STORE(mem68k_store_bk_normal)
898 ;
899