| 1 | /* |
| 2 | * PicoDrive |
| 3 | * (C) notaz, 2008 |
| 4 | * |
| 5 | * This work is licensed under the terms of MAME license. |
| 6 | * See COPYING file in the top-level directory. |
| 7 | */ |
| 8 | #include "../pico_int.h" |
| 9 | #include "../memory.h" |
| 10 | #include "../sound/sn76496.h" |
| 11 | |
| 12 | /* |
| 13 | void dump(u16 w) |
| 14 | { |
| 15 | static FILE *f[0x10] = { NULL, }; |
| 16 | char fname[32]; |
| 17 | int num = PicoPicohw.r12 & 0xf; |
| 18 | |
| 19 | w = (w << 8) | (w >> 8); |
| 20 | sprintf(fname, "ldump%i.bin", num); |
| 21 | if (f[num] == NULL) |
| 22 | f[num] = fopen(fname, "wb"); |
| 23 | fwrite(&w, 1, 2, f[num]); |
| 24 | //fclose(f); |
| 25 | } |
| 26 | */ |
| 27 | |
| 28 | static u32 PicoRead8_pico(u32 a) |
| 29 | { |
| 30 | u32 d = 0; |
| 31 | |
| 32 | if ((a & 0xffffe0) == 0x800000) // Pico I/O |
| 33 | { |
| 34 | switch (a & 0x1f) |
| 35 | { |
| 36 | case 0x01: d = PicoPicohw.r1; break; |
| 37 | case 0x03: |
| 38 | d = PicoPad[0]&0x1f; // d-pad |
| 39 | d |= (PicoPad[0]&0x20) << 2; // pen push -> C |
| 40 | d = ~d; |
| 41 | break; |
| 42 | |
| 43 | case 0x05: d = (PicoPicohw.pen_pos[0] >> 8); break; // what is MS bit for? Games read it.. |
| 44 | case 0x07: d = PicoPicohw.pen_pos[0] & 0xff; break; |
| 45 | case 0x09: d = (PicoPicohw.pen_pos[1] >> 8); break; |
| 46 | case 0x0b: d = PicoPicohw.pen_pos[1] & 0xff; break; |
| 47 | case 0x0d: d = (1 << (PicoPicohw.page & 7)) - 1; break; |
| 48 | case 0x12: d = PicoPicohw.fifo_bytes == 0 ? 0x80 : 0; break; // guess |
| 49 | default: |
| 50 | goto unhandled; |
| 51 | } |
| 52 | return d; |
| 53 | } |
| 54 | |
| 55 | unhandled: |
| 56 | elprintf(EL_UIO, "m68k unmapped r8 [%06x] @%06x", a, SekPc); |
| 57 | return d; |
| 58 | } |
| 59 | |
| 60 | static u32 PicoRead16_pico(u32 a) |
| 61 | { |
| 62 | u32 d = 0; |
| 63 | |
| 64 | if (a == 0x800010) |
| 65 | d = (PicoPicohw.fifo_bytes > 0x3f) ? 0 : (0x3f - PicoPicohw.fifo_bytes); |
| 66 | else if (a == 0x800012) |
| 67 | d = PicoPicohw.fifo_bytes == 0 ? 0x8000 : 0; // guess |
| 68 | else |
| 69 | elprintf(EL_UIO, "m68k unmapped r16 [%06x] @%06x", a, SekPc); |
| 70 | |
| 71 | return d; |
| 72 | } |
| 73 | |
| 74 | static void PicoWrite8_pico(u32 a, u32 d) |
| 75 | { |
| 76 | switch (a & ~0x800000) { |
| 77 | case 0x19: case 0x1b: case 0x1d: case 0x1f: break; // 'S' 'E' 'G' 'A' |
| 78 | default: |
| 79 | elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x", a, d & 0xff, SekPc); |
| 80 | break; |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | static void PicoWrite16_pico(u32 a, u32 d) |
| 85 | { |
| 86 | //if (a == 0x800010) dump(d); |
| 87 | if (a == 0x800010) |
| 88 | { |
| 89 | PicoPicohw.fifo_bytes += 2; |
| 90 | |
| 91 | if (PicoPicohw.xpcm_ptr < PicoPicohw.xpcm_buffer + XPCM_BUFFER_SIZE) { |
| 92 | *PicoPicohw.xpcm_ptr++ = d >> 8; |
| 93 | *PicoPicohw.xpcm_ptr++ = d; |
| 94 | } |
| 95 | else if (PicoPicohw.xpcm_ptr == PicoPicohw.xpcm_buffer + XPCM_BUFFER_SIZE) { |
| 96 | elprintf(EL_ANOMALY|EL_PICOHW, "xpcm_buffer overflow!"); |
| 97 | PicoPicohw.xpcm_ptr++; |
| 98 | } |
| 99 | } |
| 100 | else if (a == 0x800012) { |
| 101 | int r12_old = PicoPicohw.r12; |
| 102 | PicoPicohw.r12 = d; |
| 103 | if (r12_old != d) |
| 104 | PicoReratePico(); |
| 105 | } |
| 106 | else |
| 107 | elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc); |
| 108 | } |
| 109 | |
| 110 | |
| 111 | PICO_INTERNAL void PicoMemSetupPico(void) |
| 112 | { |
| 113 | PicoMemSetup(); |
| 114 | |
| 115 | // no MD IO or Z80 on Pico |
| 116 | m68k_map_unmap(0x400000, 0xbfffff); |
| 117 | |
| 118 | // map Pico I/O |
| 119 | cpu68k_map_set(m68k_read8_map, 0x800000, 0x80ffff, PicoRead8_pico, 1); |
| 120 | cpu68k_map_set(m68k_read16_map, 0x800000, 0x80ffff, PicoRead16_pico, 1); |
| 121 | cpu68k_map_set(m68k_write8_map, 0x800000, 0x80ffff, PicoWrite8_pico, 1); |
| 122 | cpu68k_map_set(m68k_write16_map, 0x800000, 0x80ffff, PicoWrite16_pico, 1); |
| 123 | } |
| 124 | |