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