cff531af |
1 | /* |
2 | * PicoDrive |
3 | * (C) notaz, 2008 |
f1b425e3 |
4 | * (C) irixxxx, 2024 |
cff531af |
5 | * |
6 | * This work is licensed under the terms of MAME license. |
7 | * See COPYING file in the top-level directory. |
8 | */ |
efcba75f |
9 | #include "../pico_int.h" |
45f2f245 |
10 | #include "../memory.h" |
9037e45d |
11 | |
45f2f245 |
12 | /* |
13 | void dump(u16 w) |
9037e45d |
14 | { |
45f2f245 |
15 | static FILE *f[0x10] = { NULL, }; |
16 | char fname[32]; |
17 | int num = PicoPicohw.r12 & 0xf; |
9037e45d |
18 | |
45f2f245 |
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 | */ |
9037e45d |
27 | |
f1b425e3 |
28 | static u32 PicoRead16_pico(u32 a) |
45f2f245 |
29 | { |
30 | u32 d = 0; |
9037e45d |
31 | |
f1b425e3 |
32 | switch (a & 0x1e) |
406c96c5 |
33 | { |
f1b425e3 |
34 | case 0x00: d = PicoPicohw.r1; break; |
35 | case 0x02: d = PicoIn.pad[0]&0x1f; // d-pad |
36 | d |= (PicoIn.pad[0]&0x20) << 2; // pen push -> C |
37 | d = ~d; |
38 | break; |
39 | case 0x04: d = (PicoPicohw.pen_pos[0] >> 8); break; // what is MS bit for? Games read it.. |
40 | case 0x06: d = PicoPicohw.pen_pos[0] & 0xff; break; |
41 | case 0x08: d = (PicoPicohw.pen_pos[1] >> 8); break; |
42 | case 0x0a: d = PicoPicohw.pen_pos[1] & 0xff; break; |
43 | case 0x0c: d = (1 << (PicoPicohw.page & 7)) - 1; break; |
44 | case 0x10: d = (PicoPicohw.fifo_bytes > 0x3f) ? 0 : (0x3f - PicoPicohw.fifo_bytes); break; |
45 | case 0x12: d = (PicoPicohw.fifo_bytes | !PicoPicoPCMBusyN()) ? 0 : 0x8000; |
46 | d |= PicoPicohw.r12 & 0x7fff; |
47 | break; |
48 | default: elprintf(EL_UIO, "m68k unmapped r16 [%06x] @%06x", a, SekPc); break; |
406c96c5 |
49 | } |
9037e45d |
50 | return d; |
51 | } |
52 | |
f1b425e3 |
53 | static u32 PicoRead8_pico(u32 a) |
9037e45d |
54 | { |
45f2f245 |
55 | u32 d = 0; |
9037e45d |
56 | |
f1b425e3 |
57 | if ((a & 0xffffe0) == 0x800000) // Pico I/O |
58 | { |
59 | d = PicoRead16_pico(a); |
60 | if (!(a & 1)) d >>= 8; |
61 | return d & 0xff; |
62 | } |
9037e45d |
63 | |
f1b425e3 |
64 | elprintf(EL_UIO, "m68k unmapped r8 [%06x] @%06x", a, SekPc); |
9037e45d |
65 | return d; |
66 | } |
67 | |
45f2f245 |
68 | static void PicoWrite8_pico(u32 a, u32 d) |
9037e45d |
69 | { |
45f2f245 |
70 | switch (a & ~0x800000) { |
fa22af4c |
71 | case 0x19: case 0x1b: case 0x1d: case 0x1f: break; // 'S' 'E' 'G' 'A' |
72 | default: |
45f2f245 |
73 | elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x", a, d & 0xff, SekPc); |
fa22af4c |
74 | break; |
75 | } |
9037e45d |
76 | } |
77 | |
45f2f245 |
78 | static void PicoWrite16_pico(u32 a, u32 d) |
9037e45d |
79 | { |
582890c0 |
80 | //if (a == 0x800010) dump(d); |
ef4eb506 |
81 | if (a == 0x800010) |
82 | { |
83 | PicoPicohw.fifo_bytes += 2; |
84 | |
85 | if (PicoPicohw.xpcm_ptr < PicoPicohw.xpcm_buffer + XPCM_BUFFER_SIZE) { |
86 | *PicoPicohw.xpcm_ptr++ = d >> 8; |
87 | *PicoPicohw.xpcm_ptr++ = d; |
88 | } |
89 | else if (PicoPicohw.xpcm_ptr == PicoPicohw.xpcm_buffer + XPCM_BUFFER_SIZE) { |
fa22af4c |
90 | elprintf(EL_ANOMALY|EL_PICOHW, "xpcm_buffer overflow!"); |
ef4eb506 |
91 | PicoPicohw.xpcm_ptr++; |
92 | } |
93 | } |
213c16ad |
94 | else if (a == 0x800012) { |
213c16ad |
95 | PicoPicohw.r12 = d; |
f1b425e3 |
96 | |
97 | PicoPicoPCMGain(8 - (d & 0x0007)); // volume |
98 | PicoPicoPCMFilter((d & 0x00c0) >> 6); // low pass filter |
99 | PicoPicoPCMIrqEn(d & 0x4000); // PCM IRQ enable |
100 | |
101 | if (d & 0x8000) { // PCM reset if 1 is written (dalmatians)? |
102 | PsndDoPCM(cycles_68k_to_z80(SekCyclesDone() - Pico.t.m68c_frame_start)); |
103 | PicoPicoPCMResetN(0); |
104 | PicoPicohw.xpcm_ptr = PicoPicohw.xpcm_buffer; |
105 | PicoPicohw.fifo_bytes = 0; |
106 | PicoPicoPCMResetN(1); |
107 | } |
108 | // other bits used in software: 0x3f00. |
213c16ad |
109 | } |
fa22af4c |
110 | else |
45f2f245 |
111 | elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc); |
9037e45d |
112 | } |
113 | |
9037e45d |
114 | |
115 | PICO_INTERNAL void PicoMemSetupPico(void) |
116 | { |
67c81ee2 |
117 | PicoMemSetup(); |
45f2f245 |
118 | |
119 | // no MD IO or Z80 on Pico |
120 | m68k_map_unmap(0x400000, 0xbfffff); |
121 | |
122 | // map Pico I/O |
123 | cpu68k_map_set(m68k_read8_map, 0x800000, 0x80ffff, PicoRead8_pico, 1); |
124 | cpu68k_map_set(m68k_read16_map, 0x800000, 0x80ffff, PicoRead16_pico, 1); |
125 | cpu68k_map_set(m68k_write8_map, 0x800000, 0x80ffff, PicoWrite8_pico, 1); |
126 | cpu68k_map_set(m68k_write16_map, 0x800000, 0x80ffff, PicoWrite16_pico, 1); |
9037e45d |
127 | } |
128 | |