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