Merge pull request #106 from dinkc64/master
[picodrive.git] / pico / pico / memory.c
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  =  PicoIn.pad[0]&0x1f; // d-pad
39         d |= (PicoIn.pad[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