6 * This work is licensed under the terms of MAME license.
7 * See COPYING file in the top-level directory.
9 #include "../pico_int.h"
10 #include "../memory.h"
11 #include <platform/common/input_pico.h>
17 static FILE *f[0x10] = { NULL, };
19 int num = PicoPicohw.r12 & 0xf;
21 w = (w << 8) | (w >> 8);
22 sprintf(fname, "ldump%i.bin", num);
24 f[num] = fopen(fname, "wb");
25 fwrite(&w, 1, 2, f[num]);
35 gettimeofday(&tv, NULL);
37 ret = (unsigned)tv.tv_sec * 1000;
38 /* approximate /= 1000 */
39 ret += ((unsigned)tv.tv_usec * 4195) >> 22;
44 static u32 PicoRead16_pico(u32 a)
50 case 0x00: d = PicoPicohw.r1; break;
51 case 0x02: d = PicoIn.pad[0]&0x1f; // d-pad
52 d |= (PicoIn.pad[0]&0x20) << 2; // pen push -> C
55 case 0x04: d = (PicoPicohw.pen_pos[0] >> 8); break;
56 case 0x06: d = PicoPicohw.pen_pos[0] & 0xff; break;
57 case 0x08: d = (PicoPicohw.pen_pos[1] >> 8); break;
58 case 0x0a: d = PicoPicohw.pen_pos[1] & 0xff; break;
59 case 0x0c: d = (1 << (PicoPicohw.page & 7)) - 1;
60 if (PicoPicohw.page == 7) d = 0x2a; // 0b00101010
62 case 0x10: d = (PicoPicohw.fifo_bytes > 0x3f) ? 0 : (0x3f - PicoPicohw.fifo_bytes); break;
63 case 0x12: d = (PicoPicohw.fifo_bytes | !PicoPicoPCMBusyN()) ? 0 : 0x8000;
64 d |= PicoPicohw.r12 & 0x7fff;
66 default: elprintf(EL_UIO, "m68k unmapped r16 [%06x] @%06x", a, SekPc); break;
71 static u32 PicoRead8_pico(u32 a)
75 if ((a & 0xffffe0) == 0x800000) // Pico I/O
77 d = PicoRead16_pico(a);
78 if (!(a & 1)) d >>= 8;
82 elprintf(EL_UIO, "m68k unmapped r8 [%06x] @%06x", a, SekPc);
86 static void PicoWrite8_pico(u32 a, u32 d)
88 switch (a & ~0x800000) {
89 case 0x19: case 0x1b: case 0x1d: case 0x1f: break; // 'S' 'E' 'G' 'A'
91 elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x", a, d & 0xff, SekPc);
96 static void PicoWrite16_pico(u32 a, u32 d)
98 //if (a == 0x800010) dump(d);
101 PicoPicohw.fifo_bytes += 2;
103 if (PicoPicohw.xpcm_ptr < PicoPicohw.xpcm_buffer + XPCM_BUFFER_SIZE) {
104 *PicoPicohw.xpcm_ptr++ = d >> 8;
105 *PicoPicohw.xpcm_ptr++ = d;
107 else if (PicoPicohw.xpcm_ptr == PicoPicohw.xpcm_buffer + XPCM_BUFFER_SIZE) {
108 elprintf(EL_ANOMALY|EL_PICOHW, "xpcm_buffer overflow!");
109 PicoPicohw.xpcm_ptr++;
112 else if (a == 0x800012) {
115 PicoPicoPCMGain(8 - (d & 0x0007)); // volume
116 PicoPicoPCMFilter((d & 0x00c0) >> 6); // low pass filter
117 PicoPicoPCMIrqEn(d & 0x4000); // PCM IRQ enable
119 if (d & 0x8000) { // PCM reset if 1 is written (dalmatians)?
120 PsndDoPCM(cycles_68k_to_z80(SekCyclesDone() - Pico.t.m68c_frame_start));
121 PicoPicoPCMResetN(0);
122 PicoPicohw.xpcm_ptr = PicoPicohw.xpcm_buffer;
123 PicoPicohw.fifo_bytes = 0;
124 PicoPicoPCMResetN(1);
126 // TODO: other bits used in software: 0x3f00.
129 elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
132 static u32 PicoRead8_pico_kb(u32 a)
135 if (!(PicoIn.opt & POPT_EN_KBD)) {
136 elprintf(EL_PICOHW, "kb: r @%06X %04X = %04X\n", SekPc, a, d);
140 PicoPicohw.kb.has_read = 1;
142 u32 key_shift = (PicoIn.kbd & 0xff00) >> 8;
143 u32 key = (PicoIn.kbd & 0x00ff);
145 // The Shift key requires 2 key up events to be registered:
146 // SHIFT_UP_HELD_DOWN to allow the game to register the key down event
147 // for the next held down key(s), and SHIFT_UP when the Shift key
148 // is no longer held down.
150 // For the second key up event, we need to
151 // override the parsed key code with PEVB_KBD_SHIFT,
152 // otherwise it will be zero and the game won't clear its Shift key state.
153 u32 key_code = (key_shift
155 && PicoPicohw.kb.key_state != PKEY_UP
156 && PicoPicohw.kb.shift_state != PSHIFT_UP_HELD_DOWN)
158 : PicoPicohw.kb.shift_state == PSHIFT_UP ? PEVB_KBD_LSHIFT : key;
159 u32 key_code_7654 = (key_code & 0xf0) >> 4;
160 u32 key_code_3210 = (key_code & 0x0f);
161 switch(PicoPicohw.kb.i) {
162 case 0x0: d = 1; // m5id
164 case 0x1: d = 3; // m6id
166 case 0x2: d = 4; // data size
168 case 0x3: d = 0; // pad1 rldu
170 case 0x4: d = 0; // pad2 sacb
172 case 0x5: d = 0; // pad3 rxyz
174 case 0x6: d = 0; // l&kbtype
176 case 0x7: // cap/num/scr
177 if (PicoPicohw.kb.active) {
178 if (key == PEVB_KBD_CAPSLOCK && PicoPicohw.kb.has_caps_lock == 1) {
179 PicoPicohw.kb.caps_lock = PicoPicohw.kb.caps_lock == 4 ? 0 : 4;
180 PicoPicohw.kb.has_caps_lock = 0;
182 d = PicoPicohw.kb.caps_lock;
187 if (PicoPicohw.kb.active) {
189 PicoPicohw.kb.key_state = PKEY_DOWN;
192 PicoPicohw.kb.key_state = !PicoPicohw.kb.key_state ? 0 : (PicoPicohw.kb.key_state + 1) % (PKEY_UP + 1);
193 PicoPicohw.kb.start_time_keydown = 0;
195 if (key_shift && !key) {
196 if (PicoPicohw.kb.shift_state < PSHIFT_RELEASED_HELD_DOWN) {
197 PicoPicohw.kb.shift_state++;
199 PicoPicohw.kb.start_time_keydown = 0;
202 PicoPicohw.kb.shift_state = !PicoPicohw.kb.shift_state ? 0 : (PicoPicohw.kb.shift_state + 1) % (PSHIFT_UP + 1);
205 if (PicoPicohw.kb.key_state == PKEY_DOWN || PicoPicohw.kb.shift_state == PSHIFT_DOWN) {
206 if (PicoPicohw.kb.start_time_keydown == 0) {
207 d |= 8; // Send key down a.k.a. make
208 PicoPicohw.kb.time_keydown = 0;
209 PicoPicohw.kb.start_time_keydown = get_ticks();
210 if (PicoPicohw.kb.key_state == PKEY_DOWN)
211 elprintf(EL_PICOHW, "PicoPicohw.kb.key_state: PKEY DOWN\n");
213 elprintf(EL_PICOHW, "PicoPicohw.kb.key_state: PSHIFT DOWN\n");
215 // Simulate key repeat while held down a.k.a. typematic
216 PicoPicohw.kb.time_keydown = get_ticks() - PicoPicohw.kb.start_time_keydown;
217 if (PicoPicohw.kb.time_keydown > 350
218 // Modifier keys don't have typematic
219 && key_code != PEVB_KBD_CAPSLOCK
220 && key_code != PEVB_KBD_LSHIFT) {
221 d |= 8; // Send key down a.k.a. make
222 if (PicoPicohw.kb.key_state == PKEY_DOWN)
223 elprintf(EL_PICOHW, "PicoPicohw.kb.key_state: PKEY DOWN\n");
225 elprintf(EL_PICOHW, "PicoPicohw.kb.key_state: PSHIFT DOWN\n");
227 // Must register key up while typematic not active (expected by Kibodeu Piko)
229 d |= 1; // Send key up a.k.a. break
232 if (PicoPicohw.kb.key_state == PKEY_UP
233 || PicoPicohw.kb.shift_state == PSHIFT_UP_HELD_DOWN
234 || PicoPicohw.kb.shift_state == PSHIFT_UP) {
235 d |= 1; // Send key up a.k.a. break
236 PicoPicohw.kb.start_time_keydown = 0;
237 if (PicoPicohw.kb.key_state == PKEY_UP)
238 elprintf(EL_PICOHW, "PicoPicohw.kb.key_state: PKEY UP\n");
240 elprintf(EL_PICOHW, "PicoPicohw.kb.key_state: PSHIFT UP\n");
244 case 0x9: d = key_code_7654; // data 7654
246 case 0xa: d = key_code_3210; // data 3210
248 case 0xb: d = 0; // ?
250 case 0xc: d = 0; // ?
257 if (PicoPicohw.kb.neg) {
261 elprintf(EL_PICOHW, "kb: r @%06X %04X = %04X\n", SekPc, a, d);
265 static u32 PicoRead16_pico_kb(u32 a)
267 u32 d = PicoPicohw.kb.mem;
269 elprintf(EL_PICOHW, "kb: r16 @%06X %04X = %04X\n", SekPc, a, d);
273 static void PicoWrite8_pico_kb(u32 a, u32 d)
275 elprintf(EL_PICOHW, "kb: w @%06X %04X = %04X\n", SekPc, a, d);
279 PicoPicohw.kb.neg = 0;
283 PicoPicohw.kb.neg = 1;
284 if (PicoPicohw.kb.has_read == 1) {
291 PicoPicohw.kb.mode = !PicoPicohw.kb.mode;
293 PicoPicohw.kb.has_read = 0;
299 PicoPicohw.kb.mem = (PicoPicohw.kb.mem & 0xff00) | d;
302 static void PicoWrite16_pico_kb(u32 a, u32 d)
304 elprintf(EL_PICOHW, "kb: w16 @%06X %04X = %04X\n", SekPc, a, d);
306 PicoPicohw.kb.mem = d;
309 PICO_INTERNAL void PicoMemSetupPico(void)
313 // no MD IO or Z80 on Pico
314 m68k_map_unmap(0x400000, 0xbfffff);
317 cpu68k_map_set(m68k_read8_map, 0x800000, 0x80ffff, PicoRead8_pico, 1);
318 cpu68k_map_set(m68k_read16_map, 0x800000, 0x80ffff, PicoRead16_pico, 1);
319 cpu68k_map_set(m68k_write8_map, 0x800000, 0x80ffff, PicoWrite8_pico, 1);
320 cpu68k_map_set(m68k_write16_map, 0x800000, 0x80ffff, PicoWrite16_pico, 1);
322 m68k_map_unmap(0x200000, 0x20ffff);
324 // map Pico PS/2 Peripheral I/O
325 cpu68k_map_set(m68k_read8_map, 0x200000, 0x20ffff, PicoRead8_pico_kb, 1);
326 cpu68k_map_set(m68k_read16_map, 0x200000, 0x20ffff, PicoRead16_pico_kb, 1);
327 cpu68k_map_set(m68k_write8_map, 0x200000, 0x20ffff, PicoWrite8_pico_kb, 1);
328 cpu68k_map_set(m68k_write16_map, 0x200000, 0x20ffff, PicoWrite16_pico_kb, 1);