|
|
1.1 root 1: /*****************************************************************************/
2: /* Generator - Sega Genesis emulation - (c) James Ponder 1997-1998 */
3: /*****************************************************************************/
4: /* */
5: /* mem68k.c */
6: /* */
7: /*****************************************************************************/
8:
9: #include <stdio.h>
10:
11: #include "generator.h"
12: #include "cpu68k.h"
13: #include "mem68k.h"
14: #include "vdp.h"
15: #include "cpuz80.h"
16: #include "gensound.h"
17: #include "ui.h"
18:
19: #undef DEBUG_BUS
20: #undef DEBUG_SRAM
21: #undef DEBUG_RAM
22: #undef DEBUG_BANK
23:
24: /*** forward references ***/
25:
26: uint8 *mem68k_memptr_bad(uint32 addr);
27: uint8 *mem68k_memptr_rom(uint32 addr);
28: uint8 *mem68k_memptr_ram(uint32 addr);
29:
30: uint8 mem68k_fetch_bad_byte(uint32 addr);
31: uint16 mem68k_fetch_bad_word(uint32 addr);
32: uint32 mem68k_fetch_bad_long(uint32 addr);
33: uint8 mem68k_fetch_rom_byte(uint32 addr);
34: uint16 mem68k_fetch_rom_word(uint32 addr);
35: uint32 mem68k_fetch_rom_long(uint32 addr);
36: uint8 mem68k_fetch_sram_byte(uint32 addr);
37: uint16 mem68k_fetch_sram_word(uint32 addr);
38: uint32 mem68k_fetch_sram_long(uint32 addr);
39: uint8 mem68k_fetch_yam_byte(uint32 addr);
40: uint16 mem68k_fetch_yam_word(uint32 addr);
41: uint32 mem68k_fetch_yam_long(uint32 addr);
42: uint8 mem68k_fetch_bank_byte(uint32 addr);
43: uint16 mem68k_fetch_bank_word(uint32 addr);
44: uint32 mem68k_fetch_bank_long(uint32 addr);
45: uint8 mem68k_fetch_io_byte(uint32 addr);
46: uint16 mem68k_fetch_io_word(uint32 addr);
47: uint32 mem68k_fetch_io_long(uint32 addr);
48: uint8 mem68k_fetch_ctrl_byte(uint32 addr);
49: uint16 mem68k_fetch_ctrl_word(uint32 addr);
50: uint32 mem68k_fetch_ctrl_long(uint32 addr);
51: uint8 mem68k_fetch_vdp_byte(uint32 addr);
52: uint16 mem68k_fetch_vdp_word(uint32 addr);
53: uint32 mem68k_fetch_vdp_long(uint32 addr);
54: uint8 mem68k_fetch_ram_byte(uint32 addr);
55: uint16 mem68k_fetch_ram_word(uint32 addr);
56: uint32 mem68k_fetch_ram_long(uint32 addr);
57:
58: void mem68k_store_bad_byte(uint32 addr, uint8 data);
59: void mem68k_store_bad_word(uint32 addr, uint16 data);
60: void mem68k_store_bad_long(uint32 addr, uint32 data);
61: void mem68k_store_rom_byte(uint32 addr, uint8 data);
62: void mem68k_store_rom_word(uint32 addr, uint16 data);
63: void mem68k_store_rom_long(uint32 addr, uint32 data);
64: void mem68k_store_sram_byte(uint32 addr, uint8 data);
65: void mem68k_store_sram_word(uint32 addr, uint16 data);
66: void mem68k_store_sram_long(uint32 addr, uint32 data);
67: void mem68k_store_yam_byte(uint32 addr, uint8 data);
68: void mem68k_store_yam_word(uint32 addr, uint16 data);
69: void mem68k_store_yam_long(uint32 addr, uint32 data);
70: void mem68k_store_bank_byte(uint32 addr, uint8 data);
71: void mem68k_store_bank_word(uint32 addr, uint16 data);
72: void mem68k_store_bank_long(uint32 addr, uint32 data);
73: void mem68k_store_io_byte(uint32 addr, uint8 data);
74: void mem68k_store_io_word(uint32 addr, uint16 data);
75: void mem68k_store_io_long(uint32 addr, uint32 data);
76: void mem68k_store_ctrl_byte(uint32 addr, uint8 data);
77: void mem68k_store_ctrl_word(uint32 addr, uint16 data);
78: void mem68k_store_ctrl_long(uint32 addr, uint32 data);
79: void mem68k_store_vdp_byte(uint32 addr, uint8 data);
80: void mem68k_store_vdp_word(uint32 addr, uint16 data);
81: void mem68k_store_vdp_long(uint32 addr, uint32 data);
82: void mem68k_store_ram_byte(uint32 addr, uint8 data);
83: void mem68k_store_ram_word(uint32 addr, uint16 data);
84: void mem68k_store_ram_long(uint32 addr, uint32 data);
85:
86: unsigned int mem68k_cont1_a = 0;
87: unsigned int mem68k_cont1_b = 0;
88: unsigned int mem68k_cont1_c = 0;
89: unsigned int mem68k_cont1_up = 0;
90: unsigned int mem68k_cont1_down = 0;
91: unsigned int mem68k_cont1_left = 0;
92: unsigned int mem68k_cont1_right = 0;
93: unsigned int mem68k_cont1_start = 0;
94:
95: unsigned int mem68k_cont2_a = 0;
96: unsigned int mem68k_cont2_b = 0;
97: unsigned int mem68k_cont2_c = 0;
98: unsigned int mem68k_cont2_up = 0;
99: unsigned int mem68k_cont2_down = 0;
100: unsigned int mem68k_cont2_left = 0;
101: unsigned int mem68k_cont2_right = 0;
102: unsigned int mem68k_cont2_start = 0;
103:
104: static unsigned int mem68k_cont1store;
105: static unsigned int mem68k_cont2store;
106:
107: /*** memory map ***/
108:
109: t_mem68k_def mem68k_def[] = {
110:
111: { 0x000, 0x400, mem68k_memptr_rom,
112: mem68k_fetch_rom_byte, mem68k_fetch_rom_word, mem68k_fetch_rom_long,
113: mem68k_store_rom_byte, mem68k_store_rom_word, mem68k_store_rom_long },
114:
115: { 0x400, 0x1000, mem68k_memptr_bad,
116: mem68k_fetch_bad_byte, mem68k_fetch_bad_word, mem68k_fetch_bad_long,
117: mem68k_store_bad_byte, mem68k_store_bad_word, mem68k_store_bad_long },
118:
119: { 0xA00, 0xA02, mem68k_memptr_bad,
120: mem68k_fetch_sram_byte, mem68k_fetch_sram_word, mem68k_fetch_sram_long,
121: mem68k_store_sram_byte, mem68k_store_sram_word, mem68k_store_sram_long },
122:
123: { 0xA04, 0xA05, mem68k_memptr_bad,
124: mem68k_fetch_yam_byte, mem68k_fetch_yam_word, mem68k_fetch_yam_long,
125: mem68k_store_yam_byte, mem68k_store_yam_word, mem68k_store_yam_long },
126:
127: { 0xA06, 0xA07, mem68k_memptr_bad,
128: mem68k_fetch_bank_byte, mem68k_fetch_bank_word, mem68k_fetch_bank_long,
129: mem68k_store_bank_byte, mem68k_store_bank_word, mem68k_store_bank_long },
130:
131: { 0xA10, 0xA11, mem68k_memptr_bad,
132: mem68k_fetch_io_byte, mem68k_fetch_io_word, mem68k_fetch_io_long,
133: mem68k_store_io_byte, mem68k_store_io_word, mem68k_store_io_long },
134:
135: { 0xA11, 0xA12, mem68k_memptr_bad,
136: mem68k_fetch_ctrl_byte, mem68k_fetch_ctrl_word, mem68k_fetch_ctrl_long,
137: mem68k_store_ctrl_byte, mem68k_store_ctrl_word, mem68k_store_ctrl_long },
138:
139: { 0xC00, 0xC01, mem68k_memptr_bad,
140: mem68k_fetch_vdp_byte, mem68k_fetch_vdp_word, mem68k_fetch_vdp_long,
141: mem68k_store_vdp_byte, mem68k_store_vdp_word, mem68k_store_vdp_long },
142:
143: { 0xFF0, 0x1000, mem68k_memptr_ram,
144: mem68k_fetch_ram_byte, mem68k_fetch_ram_word, mem68k_fetch_ram_long,
145: mem68k_store_ram_byte, mem68k_store_ram_word, mem68k_store_ram_long },
146:
147: { 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
148:
149: };
150:
151: uint8 *(*mem68k_memptr[0x1000])(uint32 addr);
152: uint8 (*mem68k_fetch_byte[0x1000])(uint32 addr);
153: uint16 (*mem68k_fetch_word[0x1000])(uint32 addr);
154: uint32 (*mem68k_fetch_long[0x1000])(uint32 addr);
155: void (*mem68k_store_byte[0x1000])(uint32 addr, uint8 data);
156: void (*mem68k_store_word[0x1000])(uint32 addr, uint16 data);
157: void (*mem68k_store_long[0x1000])(uint32 addr, uint32 data);
158:
159: /*** initialise memory tables ***/
160:
161: int mem68k_init(void)
162: {
163: int i = 0;
164: int j;
165:
166: do {
167: for (j = mem68k_def[i].start; j < mem68k_def[i].end; j++) {
168: mem68k_memptr[j] = mem68k_def[i].memptr;
169: mem68k_fetch_byte[j] = mem68k_def[i].fetch_byte;
170: mem68k_fetch_word[j] = mem68k_def[i].fetch_word;
171: mem68k_fetch_long[j] = mem68k_def[i].fetch_long;
172: mem68k_store_byte[j] = mem68k_def[i].store_byte;
173: mem68k_store_word[j] = mem68k_def[i].store_word;
174: mem68k_store_long[j] = mem68k_def[i].store_long;
175: }
176: i++;
177: } while ((mem68k_def[i].start != 0) || (mem68k_def[i].end != 0));
178: return 0;
179: }
180:
181:
182: /*** memptr routines - called for IPC generation so speed is not vital ***/
183:
184: uint8 *mem68k_memptr_bad(uint32 addr)
185: {
186: LOG_CRITICAL(("%08X [MEM] Invalid memory access 0x%X", regs.pc, addr));
187: return cpu68k_rom;
188: }
189:
190: uint8 *mem68k_memptr_rom(uint32 addr)
191: {
192: if (addr < cpu68k_romlen) {
193: return(cpu68k_rom+addr);
194: }
195: LOG_CRITICAL(("%08X [MEM] Invalid memory access to ROM 0x%X", regs.pc,
196: addr));
197: return cpu68k_rom;
198: }
199:
200: uint8 *mem68k_memptr_ram(uint32 addr)
201: {
202: /* LOG_USER(("%08X [MEM] Executing code from RAM 0x%X\n", regs.pc, addr)); */
203: addr-= 0xFF0000;
204: return(cpu68k_ram+addr);
205: }
206:
207:
208: /*** BAD fetch/store ***/
209:
210: uint8 mem68k_fetch_bad_byte(uint32 addr)
211: {
212: LOG_CRITICAL(("%08X [MEM] Invalid memory fetch (byte) 0x%X", regs.pc, addr));
213: return 0;
214: }
215:
216: uint16 mem68k_fetch_bad_word(uint32 addr)
217: {
218: LOG_CRITICAL(("%08X [MEM] Invalid memory fetch (word) 0x%X", regs.pc, addr));
219: return 0;
220: }
221:
222: uint32 mem68k_fetch_bad_long(uint32 addr)
223: {
224: LOG_CRITICAL(("%08X [MEM] Invalid memory fetch (long) 0x%X", regs.pc, addr));
225: return 0;
226: }
227:
228: void mem68k_store_bad_byte(uint32 addr, uint8 data)
229: {
230: LOG_CRITICAL(("%08X [MEM] Invalid memory store (byte) 0x%X", regs.pc, addr));
231: }
232:
233: void mem68k_store_bad_word(uint32 addr, uint16 data)
234: {
235: LOG_CRITICAL(("%08X [MEM] Invalid memory store (word) 0x%X", regs.pc, addr));
236: }
237:
238: void mem68k_store_bad_long(uint32 addr, uint32 data)
239: {
240: LOG_CRITICAL(("%08X [MEM] Invalid memory store (long) 0x%X", regs.pc, addr));
241: }
242:
243:
244: /*** ROM fetch/store ***/
245:
246: uint8 mem68k_fetch_rom_byte(uint32 addr)
247: {
248: if (addr < cpu68k_romlen) {
249: return (*(uint8 *)(cpu68k_rom+addr));
250: }
251: LOG_CRITICAL(("%08X [ROM] Invalid memory fetch (byte) 0x%X", regs.pc, addr));
252: return 0;
253: }
254:
255: uint16 mem68k_fetch_rom_word(uint32 addr)
256: {
257: #ifdef DEBUG_BUS
258: if (addr & 1) {
259: LOG_CRITICAL(("%08X [ROM] Bus error 0x%X", regs.pc, addr));
260: return 0;
261: }
262: #endif
263: if (addr < cpu68k_romlen) {
264: return LOCENDIAN16(*(uint16 *)(cpu68k_rom+addr));
265: }
266: LOG_CRITICAL(("%08X [ROM] Invalid memory fetch (word) 0x%X", regs.pc, addr));
267: return 0;
268: }
269:
270: uint32 mem68k_fetch_rom_long(uint32 addr)
271: {
272: #ifdef DEBUG_BUS
273: if (addr & 1) {
274: LOG_CRITICAL(("%08X [ROM] Bus error 0x%X", regs.pc, addr));
275: return 0;
276: }
277: #endif
278: if (addr < cpu68k_romlen) {
279: #ifdef ALIGNLONGS
280: return (LOCENDIAN16(*(uint16 *)(cpu68k_rom+addr))<<16) |
281: LOCENDIAN16(*(uint16 *)(cpu68k_rom+addr+2));
282: #else
283: return LOCENDIAN32(*(uint32 *)(cpu68k_rom+addr));
284: #endif
285: }
286: LOG_CRITICAL(("%08X [ROM] Invalid memory fetch (long) 0x%X", regs.pc, addr));
287: return 0;
288: }
289:
290: void mem68k_store_rom_byte(uint32 addr, uint8 data)
291: {
292: LOG_CRITICAL(("%08X [ROM] Invalid memory store (byte) 0x%X", regs.pc, addr));
293: }
294:
295: void mem68k_store_rom_word(uint32 addr, uint16 data)
296: {
297: LOG_CRITICAL(("%08X [ROM] Invalid memory store (word) 0x%X", regs.pc, addr));
298: }
299:
300: void mem68k_store_rom_long(uint32 addr, uint32 data)
301: {
302: LOG_CRITICAL(("%08X [ROM] Invalid memory store (long) 0x%X", regs.pc, addr));
303: }
304:
305:
306: /*** SRAM fetch/store ***/
307:
308: uint8 mem68k_fetch_sram_byte(uint32 addr)
309: {
310: #ifdef DEBUG_SRAM
311: LOG_VERBOSE(("%08X [SRAM] Fetch byte from %X", regs.pc, addr));
312: #endif
313: addr-= 0xA00000;
314: return (*(uint8 *)(cpuz80_ram+addr));
315: }
316:
317: uint16 mem68k_fetch_sram_word(uint32 addr)
318: {
319: #ifdef DEBUG_BUS
320: if (addr & 1) {
321: LOG_CRITICAL(("%08X [SRAM] Bus error 0x%X", regs.pc, addr));
322: return 0;
323: }
324: #endif
325: #ifdef DEBUG_SRAM
326: LOG_VERBOSE(("%08X [SRAM] Fetch word from %X", regs.pc, addr));
327: #endif
328: addr-= 0xA00000;
329: return LOCENDIAN16(*(uint16 *)(cpuz80_ram+addr));
330: }
331:
332: uint32 mem68k_fetch_sram_long(uint32 addr)
333: {
334: #ifdef DEBUG_BUS
335: if (addr & 1) {
336: LOG_CRITICAL(("%08X [SRAM] Bus error 0x%X", regs.pc, addr));
337: return 0;
338: }
339: #endif
340: #ifdef DEBUG_SRAM
341: LOG_VERBOSE(("%08X [SRAM] Fetch long from %X", regs.pc, addr));
342: #endif
343: addr-= 0xA00000;
344: #ifdef ALIGNLONGS
345: return (LOCENDIAN16(*(uint16 *)(cpuz80_ram+addr))<<16) |
346: LOCENDIAN16(*(uint16 *)(cpuz80_ram+addr+2));
347: #else
348: return LOCENDIAN32(*(uint32 *)(cpuz80_ram+addr));
349: #endif
350: }
351:
352: void mem68k_store_sram_byte(uint32 addr, uint8 data)
353: {
354: #ifdef DEBUG_SRAM
355: LOG_VERBOSE(("%08X [SRAM] Store byte to %X", regs.pc, addr));
356: #endif
357: addr-= 0xA00000;
358: *(uint8 *)(cpuz80_ram+addr) = data;
359: return;
360: }
361:
362: void mem68k_store_sram_word(uint32 addr, uint16 data)
363: {
364: #ifdef DEBUG_BUS
365: if (addr & 1) {
366: LOG_CRITICAL(("%08X [SRAM] Bus error 0x%X", regs.pc, addr));
367: return;
368: }
369: #endif
370: #ifdef DEBUG_SRAM
371: LOG_VERBOSE(("%08X [SRAM] Store word to %X", regs.pc, addr));
372: #endif
373: addr-= 0xA00000;
374: *(uint16 *)(cpuz80_ram+addr) = LOCENDIAN16(data);
375: return;
376: }
377:
378: void mem68k_store_sram_long(uint32 addr, uint32 data)
379: {
380: #ifdef DEBUG_BUS
381: if (addr & 1) {
382: LOG_CRITICAL(("%08X [SRAM] Bus error 0x%X", regs.pc, addr));
383: return;
384: }
385: #endif
386: #ifdef DEBUG_SRAM
387: LOG_VERBOSE(("%08X [SRAM] Store byte to %X", regs.pc, addr));
388: #endif
389: addr-= 0xA00000;
390: #ifdef ALIGNLONGS
391: *(uint16 *)(cpuz80_ram+addr) = LOCENDIAN16((uint16)(data>>16));
392: *(uint16 *)(cpuz80_ram+addr+2) = LOCENDIAN16((uint16)(data));
393: #else
394: *(uint32 *)(cpuz80_ram+addr) = LOCENDIAN32(data);
395: #endif
396: return;
397: }
398:
399:
400: /*** YAM fetch/store ***/
401:
402: uint8 mem68k_fetch_yam_byte(uint32 addr)
403: {
404: addr-= 0xA04000;
405: /* LOG_USER(("%08X [YAM] fetch (byte) 0x%X", regs.pc, addr)); */
406: if (addr < 4) {
407: return sound_ym2612fetch(addr);
408: } else {
409: LOG_CRITICAL(("%08X [YAM] Invalid YAM fetch (byte) 0x%X", regs.pc, addr));
410: return 0;
411: }
412: }
413:
414: uint16 mem68k_fetch_yam_word(uint32 addr)
415: {
416: #ifdef DEBUG_BUS
417: if (addr & 1) {
418: LOG_CRITICAL(("%08X [YAM] Bus error 0x%X", regs.pc, addr));
419: return 0;
420: }
421: #endif
422: addr-= 0xA04000;
423: LOG_CRITICAL(("%08X [YAM] Invalid memory fetch (word) 0x%X", regs.pc, addr));
424: return 0;
425: }
426:
427: uint32 mem68k_fetch_yam_long(uint32 addr)
428: {
429: #ifdef DEBUG_BUS
430: if (addr & 1) {
431: LOG_CRITICAL(("%08X [YAM] Bus error 0x%X", regs.pc, addr));
432: return 0;
433: }
434: #endif
435: addr-= 0xA04000;
436: /* no longs please */
437: LOG_CRITICAL(("%08X [YAM] Invalid memory fetch (long) 0x%X", regs.pc, addr));
438: return 0;
439: }
440:
441: void mem68k_store_yam_byte(uint32 addr, uint8 data)
442: {
443: addr-= 0xA04000;
444: /* LOG_USER(("%08X [YAM] (68k) store (byte) 0x%X (%d)", regs.pc, addr,
445: data)); */
446: if (addr < 4)
447: sound_ym2612store(addr, data);
448: else
449: LOG_CRITICAL(("%08X [YAM] Invalid YAM store (byte) 0x%X", regs.pc, addr));
450: }
451:
452: void mem68k_store_yam_word(uint32 addr, uint16 data)
453: {
454: #ifdef DEBUG_BUS
455: if (addr & 1) {
456: LOG_CRITICAL(("%08X [YAM] Bus error 0x%X", regs.pc, addr));
457: return;
458: }
459: #endif
460: addr-= 0xA04000;
461: LOG_CRITICAL(("%08X [YAM] Invalid memory store (word) 0x%X", regs.pc, addr));
462: }
463:
464: void mem68k_store_yam_long(uint32 addr, uint32 data)
465: {
466: #ifdef DEBUG_BUS
467: if (addr & 1) {
468: LOG_CRITICAL(("%08X [YAM] Bus error 0x%X", regs.pc, addr));
469: return;
470: }
471: #endif
472: addr-= 0xA04000;
473: /* no longs please */
474: LOG_CRITICAL(("%08X [YAM] Invalid memory store (long) 0x%X", regs.pc, addr));
475: }
476:
477:
478: /*** BANK fetch/store ***/
479:
480: uint8 mem68k_fetch_bank_byte(uint32 addr)
481: {
482: /* write only */
483: LOG_CRITICAL(("%08X [BANK] Invalid memory fetch (byte) 0x%X", regs.pc,
484: addr));
485: return 0;
486: }
487:
488: uint16 mem68k_fetch_bank_word(uint32 addr)
489: {
490: /* write only */
491: LOG_CRITICAL(("%08X [BANK] Invalid memory fetch (word) 0x%X", regs.pc,
492: addr));
493: return 0;
494: }
495:
496: uint32 mem68k_fetch_bank_long(uint32 addr)
497: {
498: /* write only */
499: LOG_CRITICAL(("%08X [BANK] Invalid memory fetch (long) 0x%X", regs.pc,
500: addr));
501: return 0;
502: }
503:
504: void mem68k_store_bank_byte(uint32 addr, uint8 data)
505: {
506: addr-= 0xA06000;
507: if (addr == 0x000) {
508: #ifdef DEBUG_SRAM
509: LOG_VERBOSE(("%08X [BANK] Store byte to %X", regs.pc, addr));
510: #endif
511: cpuz80_bankwrite(data);
512: } else {
513: LOG_CRITICAL(("%08X [BANK] Invalid memory store (byte) 0x%X", regs.pc,
514: addr));
515: }
516: }
517:
518: void mem68k_store_bank_word(uint32 addr, uint16 data)
519: {
520: addr-= 0xA06000;
521: if (addr == 0x000) {
522: #ifdef DEBUG_SRAM
523: LOG_VERBOSE(("%08X [BANK] Store word to %X", regs.pc, addr));
524: #endif
525: cpuz80_bankwrite(data>>8);
526: } else {
527: LOG_CRITICAL(("%08X [BANK] Invalid memory store (word) 0x%X", regs.pc,
528: addr));
529: }
530: }
531:
532: void mem68k_store_bank_long(uint32 addr, uint32 data)
533: {
534: addr-= 0xA06000;
535: /* no longs please */
536: LOG_CRITICAL(("%08X [BANK] Invalid memory store (long) 0x%X", regs.pc,
537: addr));
538: }
539:
540:
541: /*** I/O fetch/store ***/
542:
543: uint8 mem68k_fetch_io_byte(uint32 addr)
544: {
545: /* LOG_USER(("%08X [IO] Memory fetch (byte) 0x%X", regs.pc, addr)); */
546: addr-= 0xA10000;
547: switch (addr) {
548: case 0:
549: LOG_CRITICAL(("%08X [IO] Invalid memory fetch (byte) 0x%X",
550: regs.pc, addr));
551: return 0;
552: case 0x1:
553: /* version */
554: return (1<<5 | vdp_pal<<6 | vdp_overseas<<7);
555: case 0x3:
556: LOG_USER(("%08X [IO] getting controller 1 state - %02X store",
557: regs.pc, mem68k_cont1store));
558: if (mem68k_cont1store & 1<<6) {
559: return (1<<6 | (1-mem68k_cont1_up) | (1-mem68k_cont1_down)<<1 |
560: (1-mem68k_cont1_left)<<2 | (1-mem68k_cont1_right)<<3 |
561: (1-mem68k_cont1_b)<<4 | (1-mem68k_cont1_c)<<5);
562: } else {
563: return ((1-mem68k_cont1_up) | (1-mem68k_cont1_down)<<1 |
564: (1-mem68k_cont1_a)<<4 | (1-mem68k_cont1_start)<<5);
565: }
566: case 0x5:
567: LOG_USER(("%08X [IO] getting controller 2 state - %02X store",
568: regs.pc, mem68k_cont2store));
569: if (mem68k_cont2store & 1<<6) {
570: return (1<<6 | (1-mem68k_cont2_up) | (1-mem68k_cont2_down)<<1 |
571: (1-mem68k_cont2_left)<<2 | (1-mem68k_cont2_right)<<3 |
572: (1-mem68k_cont2_b)<<4 | (1-mem68k_cont2_c)<<5);
573: } else {
574: return ((1-mem68k_cont2_up) | (1-mem68k_cont2_down)<<1 |
575: (1-mem68k_cont2_a)<<4 | (1-mem68k_cont2_start)<<5);
576: }
577: case 0x9:
578: case 0xB:
579: return 0;
580: default:
581: LOG_CRITICAL(("%08X [IO] Invalid memory fetch (byte) 0x%X",
582: regs.pc, addr));
583: return 0;
584: }
585: }
586:
587: uint16 mem68k_fetch_io_word(uint32 addr)
588: {
589: /* LOG_USER(("%08X [IO] Memory fetch (word) 0x%X", regs.pc, addr)); */
590: #ifdef DEBUG_BUS
591: if (addr & 1) {
592: LOG_CRITICAL(("%08X [ROM] Bus error 0x%X", regs.pc, addr));
593: return 0;
594: }
595: #endif
596: addr-= 0xA10000;
597: switch (addr>>1) {
598: case 0: /* version */
599: return (1<<5 | vdp_pal<<6 | vdp_overseas<<7);
600: case 1: /* data 1 */
601: return 0;
602: case 2: /* data 2 */
603: return 0;
604: case 3: /* data E */
605: return 0;
606: case 4: /* ctrl 1 */
607: case 5: /* ctrl 2 */
608: case 6: /* ctrl E */
609: case 7: /* TxData 1 */
610: case 8: /* RxData 1 */
611: case 9: /* S-Mode 1 */
612: case 10: /* TxData 2 */
613: case 11: /* RxData 2 */
614: case 12: /* S-Mode 2 */
615: case 13: /* TxData E */
616: case 14: /* RxData E */
617: case 15: /* S-Mode E */
618: LOG_CRITICAL(("%08X [IO] Invalid memory fetch (word) 0x%X",
619: regs.pc, addr));
620: return 0;
621: default:
622: LOG_CRITICAL(("%08X [IO] Invalid memory fetch (word) 0x%X",
623: regs.pc, addr));
624: return 0;
625: }
626: }
627:
628: uint32 mem68k_fetch_io_long(uint32 addr)
629: {
630: #ifdef DEBUG_BUS
631: if (addr & 1) {
632: LOG_CRITICAL(("%08X [ROM] Bus error 0x%X", regs.pc, addr));
633: return 0;
634: }
635: #endif
636: if (addr >= 0xA1001E) {
637: LOG_CRITICAL(("%08X [IO] Invalid memory fetch (long) 0x%X",
638: regs.pc, addr));
639: return 0;
640: }
641: return (mem68k_fetch_io_word(addr)<<16) | mem68k_fetch_io_word(addr+2);
642: }
643:
644: void mem68k_store_io_byte(uint32 addr, uint8 data)
645: {
646: /* LOG_USER(("%08X [IO] Memory store (byte) 0x%X", regs.pc, addr)); */
647: addr-= 0xA10000;
648: switch (addr) {
649: case 0x3:
650: mem68k_cont1store = data;
651: return;
652: case 0x5:
653: mem68k_cont2store = data;
654: return;
655: case 0x9:
656: if (data != 0x40) {
657: LOG_CRITICAL(("%08X [IO] Invalid controller 1 setting (0x%X)",
658: regs.pc, data));
659: }
660: return;
661: case 0xB:
662: if (data != 0x40) {
663: LOG_CRITICAL(("%08X [IO] Invalid controller 2 setting (0x%X)",
664: regs.pc, data));
665: }
666: return;
667: case 0xD:
668: case 0xF:
669: case 0x11:
670: case 0x13:
671: case 0x15:
672: case 0x17:
673: case 0x19:
674: case 0x1B:
675: case 0x1D:
676: case 0x1F:
677: return;
678: default:
679: LOG_CRITICAL(("%08X [IO] Invalid memory store (byte) 0x%X",
680: regs.pc, addr));
681: return;
682: }
683: }
684:
685: void mem68k_store_io_word(uint32 addr, uint16 data)
686: {
687: /* LOG_USER(("%08X [IO] Memory store (word) 0x%X", regs.pc, addr)); */
688: #ifdef DEBUG_BUS
689: if (addr & 1) {
690: LOG_CRITICAL(("%08X [ROM] Bus error 0x%X", regs.pc, addr));
691: return;
692: }
693: #endif
694: addr-= 0xA10000;
695: switch (addr>>1) {
696: case 1: /* data 1 */
697: case 2: /* data 2 */
698: case 3: /* data E */
699: LOG_CRITICAL(("%08X [IO] Word store to DATA 0x%X", regs.pc, addr));
700: return;
701: case 4: /* ctrl 1 */
702: case 5: /* ctrl 2 */
703: case 6: /* ctrl E */
704: LOG_CRITICAL(("%08X [IO] Word store to CTRL 0x%X", regs.pc, addr));
705: return;
706: case 7: /* TxData 1 */
707: case 8: /* RxData 1 */
708: case 9: /* S-Mode 1 */
709: case 10: /* TxData 2 */
710: case 11: /* RxData 2 */
711: case 12: /* S-Mode 2 */
712: case 13: /* TxData E */
713: case 14: /* RxData E */
714: case 15: /* S-Mode E */
715: LOG_CRITICAL(("%08X [IO] Invalid memory store (word) 0x%X",
716: regs.pc, addr));
717: return;
718: default:
719: LOG_CRITICAL(("%08X [IO] Invalid memory store (word) 0x%X",
720: regs.pc, addr));
721: }
722: }
723:
724: void mem68k_store_io_long(uint32 addr, uint32 data)
725: {
726: addr-= 0xA10000;
727: if (addr >= 0x1E) {
728: LOG_CRITICAL(("%08X [IO] Invalid memory store (long) 0x%X",
729: regs.pc, addr));
730: return;
731: }
732: mem68k_store_io_word(addr, (uint16)(data<<16));
733: mem68k_store_io_word(addr+2, (uint16)data);
734: return;
735: }
736:
737:
738: /*** CTRL fetch/store ***/
739:
740: uint8 mem68k_fetch_ctrl_byte(uint32 addr)
741: {
742: addr-= 0xA11000;
743: /* 0x000 mode (write only), 0x100 z80 busreq, 0x200 z80 reset (write only) */
744: if (addr == 0x100) {
745: return cpuz80_active ? 1 : 0;
746: }
747: LOG_CRITICAL(("%08X [CTRL] Invalid memory fetch (byte) 0x%X",
748: regs.pc, addr));
749: return 0;
750: }
751:
752: uint16 mem68k_fetch_ctrl_word(uint32 addr)
753: {
754: addr-= 0xA11000;
755: /* 0x000 mode (write only), 0x100 z80 busreq, 0x200 z80 reset (write only) */
756: if (addr == 0x100) {
757: return cpuz80_active ? 0x100 : 0;
758: }
759: LOG_CRITICAL(("%08X [CTRL] Invalid memory fetch (word) 0x%X",
760: regs.pc, addr));
761: return 0;
762: }
763:
764: uint32 mem68k_fetch_ctrl_long(uint32 addr)
765: {
766: addr-= 0xA11000;
767: /* no long access allowed */
768: LOG_CRITICAL(("%08X [CTRL] Invalid memory fetch (long) 0x%X",
769: regs.pc, addr));
770: return 0;
771: }
772:
773: void mem68k_store_ctrl_byte(uint32 addr, uint8 data)
774: {
775: addr-= 0xA11000;
776: if (addr == 0x000 || addr == 0x001) {
777: /* z80 memory mode - not applicable for production carts */
778: return;
779: } else if (addr == 0x100) {
780: /* bus request */
781: if (data & 1) {
782: cpuz80_stop();
783: LOG_DEBUG1(("%08X Z80 stopped", regs.pc));
784: } else {
785: cpuz80_start();
786: LOG_DEBUG1(("%08X Z80 started", regs.pc));
787: }
788: } else if (addr == 0x101) {
789: return; /* ignore low byte */
790: } else if (addr == 0x200) {
791: /* z80 reset request */
792: if (!(data & 1)) {
793: /* cpuz80_stop(); */
794: cpuz80_resetcpu();
795: sound_genreset();
796: LOG_DEBUG1(("%08X Z80 reset", regs.pc));
797: } else {
798: cpuz80_unresetcpu();
799: LOG_DEBUG1(("%08X Z80 un-reset", regs.pc));
800: }
801: } else if (addr == 0x201) {
802: return; /* ignore low byte */
803: } else {
804: LOG_CRITICAL(("%08X [CTRL] Invalid memory store (byte) 0x%X",
805: regs.pc, addr));
806: }
807: }
808:
809: void mem68k_store_ctrl_word(uint32 addr, uint16 data)
810: {
811: addr-= 0xA11000;
812: if (addr == 0x000) {
813: /* z80 memory mode - not applicable for production carts */
814: return;
815: } else if (addr == 0x100) {
816: /* bus request */
817: if (data == 0x100) {
818: cpuz80_stop();
819: LOG_DEBUG1(("%08X Z80 stopped", regs.pc));
820: } else {
821: cpuz80_start();
822: LOG_DEBUG1(("%08X Z80 started", regs.pc));
823: }
824: } else if (addr == 0x200) {
825: /* z80 reset request */
826: if (!(data & 0x100)) {
827: /* cpuz80_stop(); */
828: cpuz80_resetcpu();
829: sound_genreset();
830: LOG_DEBUG1(("%08X Z80 reset", regs.pc));
831: } else {
832: cpuz80_unresetcpu();
833: LOG_DEBUG1(("%08X Z80 un-reset", regs.pc));
834: }
835: } else {
836: LOG_CRITICAL(("%08X [CTRL] Invalid memory store (word) 0x%X",
837: regs.pc, addr));
838: }
839: }
840:
841: void mem68k_store_ctrl_long(uint32 addr, uint32 data)
842: {
843: addr-= 0xA11000;
844: /* no long access allowed */
845: LOG_CRITICAL(("%08X [CTRL] Invalid memory store (long) 0x%X",
846: regs.pc, addr));
847: }
848:
849:
850: /*** VDP fetch/store ***/
851:
852: uint8 mem68k_fetch_vdp_byte(uint32 addr)
853: {
854: addr-= 0xC00000;
855: switch(addr) {
856: case 0:
857: case 1:
858: case 2:
859: case 3:
860: /* data port */
861: LOG_CRITICAL(("%08X [VDP] Byte fetch from data port 0x%X",
862: regs.pc, addr));
863: return 0;
864: case 4:
865: /* control port */
866: return vdp_status()>>8; /* upper 8 bits */
867: case 5:
868: /* control port */
869: return vdp_status(); /* lower 8 bits */
870: case 6:
871: case 7:
872: /* unknown control port */
873: LOG_CRITICAL(("%08X [VDP] Byte fetch from control port 0x%X",
874: regs.pc, addr));
875: return 0;
876: case 8:
877: /* hv counter */
878: return mem68k_fetch_vdp_word(0xc00008)>>8; /* upper 8 bits */
879: case 9:
880: /* hv counter */
881: return mem68k_fetch_vdp_word(0xc00008); /* lower 8 bits */
882: case 17:
883: LOG_CRITICAL(("%08X [VDP] PSG byte fetch.", regs.pc));
884: return 0;
885: default:
886: LOG_CRITICAL(("%08X [VDP] Invalid memory fetch (byte) 0x%X",
887: regs.pc, addr));
888: return 0;
889: }
890: }
891:
892: uint16 mem68k_fetch_vdp_word(uint32 addr)
893: {
894: #ifdef DEBUG_BUS
895: if (addr & 1) {
896: LOG_CRITICAL(("%08X [VDP] Bus error 0x%X", regs.pc, addr));
897: return 0;
898: }
899: #endif
900: addr-= 0xC00000;
901: switch(addr>>1) {
902: case 0:
903: case 1:
904: /* data port */
905: #ifdef DEBUG_VDP
906: LOG_VERBOSE(("%08X [VDP] Word fetch from data port 0x%X",
907: regs.pc, addr));
908: #endif
909: return vdp_fetchdata_word();
910: case 2:
911: case 3:
912: /* control port */
913: #ifdef DEBUG_VDP
914: LOG_VERBOSE(("%08X [VDP] Word fetch from control port "
915: "(status) 0x%X", regs.pc, addr));
916: #endif
917: return vdp_status();
918: case 4:
919: /* hv counter */
920: #ifdef DEBUG_VDP
921: LOG_VERBOSE(("%08X [VDP] Word fetch from hv counter 0x%X",
922: regs.pc, addr));
923: #endif
924: /* we always return 0 for the horizontal position */
925: if (vdp_interlace) {
926: /* interlace mode - replace lowest bit with highest bit */
927: LOG_CRITICAL(("Interlace mode HV read - check this"));
928: return ((((vdp_line & ~1)<<8) | (vdp_line & 0x100)) & 0xff00) |
929: vdp_gethpos();
930: } else {
931: /* non-interlace mode */
932: LOG_VERBOSE(("%02X", vdp_gethpos()));
933: return (vdp_line<<8) | vdp_gethpos();
934: }
935: case 8:
936: LOG_CRITICAL(("%08X [VDP] PSG/prohibited word fetch.", regs.pc));
937: return 0;
938: default:
939: LOG_CRITICAL(("%08X [VDP] Invalid memory fetch (word) 0x%X",
940: regs.pc, addr));
941: return 0;
942: }
943: }
944:
945: uint32 mem68k_fetch_vdp_long(uint32 addr)
946: {
947: #ifdef DEBUG_BUS
948: if (addr & 1) {
949: LOG_CRITICAL(("%08X [VDP] Bus error 0x%X", regs.pc, addr));
950: return 0;
951: }
952: #endif
953: addr-= 0xC00000;
954: switch(addr>>1) {
955: case 0:
956: /* data port */
957: #ifdef DEBUG_VDP
958: LOG_VERBOSE(("%08X [VDP] Long fetch from data port 0x%X",
959: regs.pc, addr));
960: #endif
961: return (vdp_fetchdata_word()<<16) | vdp_fetchdata_word();
962: case 2:
963: /* control port */
964: #ifdef DEBUG_VDP
965: LOG_VERBOSE(("%08X [VDP] Long fetch from control port 0x%X",
966: regs.pc, addr));
967: #endif
968: return 0;
969: case 4:
970: /* hv counter ish */
971: LOG_CRITICAL(("%08X [VDP] Long fetch from hv/prohibited 0x%X",
972: regs.pc, addr));
973: return 0;
974: default:
975: LOG_CRITICAL(("%08X [VDP] Invalid memory fetch (word) 0x%X",
976: regs.pc, addr));
977: return 0;
978: }
979: }
980:
981: void mem68k_store_vdp_byte(uint32 addr, uint8 data)
982: {
983: addr-= 0xC00000;
984: switch(addr) {
985: case 0:
986: case 1:
987: case 2:
988: case 3:
989: /* data port */
990: #ifdef DEBUG_VDP
991: LOG_VERBOSE(("%08X [VDP] Byte store to data port 0x%X\n", regs.pc, addr));
992: #endif
993: vdp_storedata_byte(data);
994: return;
995: case 4:
996: case 5:
997: case 6:
998: case 7:
999: /* control port */
1000: LOG_CRITICAL(("%08X [VDP] Byte store to control port 0x%X", regs.pc,
1001: addr));
1002: return;
1003: case 8:
1004: case 9:
1005: /* hv counter */
1006: LOG_CRITICAL(("%08X [VDP] Byte store to hv counter 0x%X", regs.pc, addr));
1007: return;
1008: case 17:
1009: sound_psgwrite(data);
1010: return;
1011: default:
1012: LOG_CRITICAL(("%08X [VDP] Invalid memory store (byte) 0x%X",
1013: regs.pc, addr));
1014: return;
1015: }
1016: }
1017:
1018: void mem68k_store_vdp_word(uint32 addr, uint16 data)
1019: {
1020: #ifdef DEBUG_BUS
1021: if (addr & 1) {
1022: LOG_CRITICAL(("%08X [VDP] Bus error 0x%X", regs.pc, addr));
1023: return;
1024: }
1025: #endif
1026: addr-= 0xC00000;
1027: switch(addr>>1) {
1028: case 0:
1029: case 1:
1030: /* data port */
1031: #ifdef DEBUG_VDP
1032: LOG_CRITICAL(("%08X [VDP] Word store to data port 0x%X", regs.pc, addr));
1033: #endif
1034: vdp_storedata_word(data);
1035: return;
1036: case 2:
1037: case 3:
1038: #ifdef DEBUG_VDP
1039: LOG_VERBOSE(("%08X [VDP] Word store to control port 0x%X", regs.pc, addr));
1040: #endif
1041: /* control port */
1042: vdp_storectrl(data);
1043: return;
1044: case 4:
1045: /* hv counter */
1046: LOG_CRITICAL(("%08X [VDP] Word store to hv counter 0x%X", regs.pc, addr));
1047: return;
1048: case 8:
1049: LOG_CRITICAL(("%08X [VDP] PSG/prohibited word store.", regs.pc));
1050: return;
1051: default:
1052: LOG_CRITICAL(("%08X [VDP] Invalid memory store (word) 0x%X", regs.pc,
1053: addr));
1054: return;
1055: }
1056: }
1057:
1058: void mem68k_store_vdp_long(uint32 addr, uint32 data)
1059: {
1060: #ifdef DEBUG_BUS
1061: if (addr & 1) {
1062: LOG_CRITICAL(("%08X [VDP] Bus error 0x%X", regs.pc, addr));
1063: return;
1064: }
1065: #endif
1066: addr-= 0xC00000;
1067: switch(addr>>1) {
1068: case 0:
1069: /* data port */
1070: #ifdef DEBUG_VDP
1071: LOG_VERBOSE(("%08X [VDP] Long store to data port 0x%X\n", regs.pc, addr));
1072: #endif
1073: vdp_storedata_word((uint16)(data>>16));
1074: vdp_storedata_word((uint16)(data));
1075: return;
1076: case 2:
1077: /* control port */
1078: #ifdef DEBUG_VDP
1079: LOG_VERBOSE(("%08X [VDP] Long store to control port 0x%X", regs.pc, addr));
1080: #endif
1081: vdp_storectrl((uint16)(data>>16));
1082: vdp_storectrl((uint16)(data));
1083: return;
1084: case 4:
1085: /* hv counter */
1086: LOG_CRITICAL(("%08X [VDP] Long store to hv/prohibited 0x%X", regs.pc,
1087: addr));
1088: return;
1089: default:
1090: LOG_CRITICAL(("%08X [VDP] Invalid memory store (long) 0x%X", regs.pc,
1091: addr));
1092: return;
1093: }
1094: }
1095:
1096:
1097: /*** RAM fetch/store ***/
1098:
1099: uint8 mem68k_fetch_ram_byte(uint32 addr)
1100: {
1101: addr-= 0xFF0000;
1102: return (*(uint8 *)(cpu68k_ram+addr));
1103: }
1104:
1105: uint16 mem68k_fetch_ram_word(uint32 addr)
1106: {
1107: addr-= 0xFF0000;
1108: return LOCENDIAN16(*(uint16 *)(cpu68k_ram+addr));
1109: }
1110:
1111: uint32 mem68k_fetch_ram_long(uint32 addr)
1112: {
1113: addr-= 0xFF0000;
1114: #ifdef ALIGNLONGS
1115: return (LOCENDIAN16(*(uint16 *)(cpu68k_ram+addr))<<16) |
1116: LOCENDIAN16(*(uint16 *)(cpu68k_ram+addr+2));
1117: #else
1118: return LOCENDIAN32(*(uint32 *)(cpu68k_ram+addr));
1119: #endif
1120: }
1121:
1122: void mem68k_store_ram_byte(uint32 addr, uint8 data)
1123: {
1124: addr-= 0xFF0000;
1125: *(uint8 *)(cpu68k_ram+addr) = data;
1126: return;
1127: }
1128:
1129: void mem68k_store_ram_word(uint32 addr, uint16 data)
1130: {
1131: addr-= 0xFF0000;
1132: *(uint16 *)(cpu68k_ram+addr) = LOCENDIAN16(data);
1133: return;
1134: }
1135:
1136: void mem68k_store_ram_long(uint32 addr, uint32 data)
1137: {
1138: addr-= 0xFF0000;
1139: #ifdef ALIGNLONGS
1140: *(uint16 *)(cpu68k_ram+addr) = LOCENDIAN16((uint16)(data>>16));
1141: *(uint16 *)(cpu68k_ram+addr+2) = LOCENDIAN16((uint16)(data));
1142: #else
1143: *(uint32 *)(cpu68k_ram+addr) = LOCENDIAN32(data);
1144: #endif
1145: return;
1146: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.