1 /***********************************************************************
2
3 DECO Cassette System machine
4
5 ***********************************************************************/
6
7 #include "driver.h"
8 #include "cpu/m6502/m6502.h"
9 #include "cpu/i8x41/i8x41.h"
10 #include "machine/decocass.h"
11 #include "state.h"
12
13 /* tape direction, speed and timing (used also in vidhrdw/decocass.c) */
14 int tape_dir;
15 int tape_speed;
16 double tape_time0;
17 void *tape_timer;
18
19 static int firsttime = 1;
20 static int tape_present;
21 static int tape_blocks;
22 static int tape_length;
23 static int tape_bot_eot;
24 static UINT8 crc16_lsb;
25 static UINT8 crc16_msb;
26
27 /* pre-calculated crc16 of the tape blocks */
28 static UINT8 tape_crc16_lsb[256];
29 static UINT8 tape_crc16_msb[256];
30
31 static data8_t (*decocass_dongle_r)(offs_t offset);
32 static void (*decocass_dongle_w)(offs_t offset, data8_t data);
33
34 static data8_t decocass_reset;
35 static data8_t i8041_p1;
36 static data8_t i8041_p2;
37
38 /* dongle type #1: jumpers C and D assignments */
39 #define MAKE_MAP(m0,m1,m2,m3,m4,m5,m6,m7) \
40 ((m0)<<0)|((m1)<<4)|((m2)<<8)|((m3)<<12)| \
41 ((m4)<<16)|((m5)<<20)|((m6)<<24)|((m7)<<28)
42 #define MAP0(m) ((m>>0)&15)
43 #define MAP1(m) ((m>>4)&15)
44 #define MAP2(m) ((m>>8)&15)
45 #define MAP3(m) ((m>>12)&15)
46 #define MAP4(m) ((m>>16)&15)
47 #define MAP5(m) ((m>>20)&15)
48 #define MAP6(m) ((m>>24)&15)
49 #define MAP7(m) ((m>>28)&15)
50 static UINT32 type1_inmap;
51 static UINT32 type1_outmap;
52
53 /* dongle type #2: status of the latches */
54 static int type2_d2_latch; /* latched 8041-STATUS D2 value */
55 static int type2_xx_latch; /* latched value (D7-4 == 0xc0) ? 1 : 0 */
56 static int type2_promaddr; /* latched PROM address A0-A7 */
57
58 /* dongle type #3: status and patches */
59 static int type3_ctrs; /* 12 bit counter stage */
60 static int type3_d0_latch; /* latched 8041-D0 value */
61 static int type3_pal_19; /* latched 1 for PAL input pin-19 */
62 static int type3_swap;
63 enum {
64 TYPE3_SWAP_01,
65 TYPE3_SWAP_12,
66 TYPE3_SWAP_13,
67 TYPE3_SWAP_24,
68 TYPE3_SWAP_25,
69 TYPE3_SWAP_34_0,
70 TYPE3_SWAP_34_7,
71 TYPE3_SWAP_56,
72 TYPE3_SWAP_67
73 };
74
75 /* dongle type #4: status */
76 static int type4_ctrs; /* latched PROM address (E5x0 LSB, E5x1 MSB) */
77 static int type4_latch; /* latched enable PROM (1100xxxx written to E5x1) */
78
79 /* dongle type #5: status */
80 static int type5_latch; /* latched enable PROM (1100xxxx written to E5x1) */
81
82 /* four inputs from the quadrature decoder (H1, V1, H2, V2) */
83 static data8_t decocass_quadrature_decoder[4];
84
85 /* sound latches, ACK status bits and NMI timer */
86 static data8_t decocass_sound_ack;
87 static void *decocass_sound_timer;
88
WRITE_HANDLER(decocass_coin_counter_w)89 WRITE_HANDLER( decocass_coin_counter_w )
90 {
91 }
92
WRITE_HANDLER(decocass_sound_command_w)93 WRITE_HANDLER( decocass_sound_command_w )
94 {
95 LOG(2,("CPU #%d sound command -> $%02x\n", cpu_getactivecpu(), data));
96 soundlatch_w(0,data);
97 decocass_sound_ack |= 0x80;
98 /* remove snd cpu data ack bit. i don't see it in the schems, but... */
99 decocass_sound_ack &= ~0x40;
100 cpu_set_irq_line(1, M6502_IRQ_LINE, ASSERT_LINE);
101 }
102
READ_HANDLER(decocass_sound_data_r)103 READ_HANDLER( decocass_sound_data_r )
104 {
105 data8_t data = soundlatch2_r(0);
106 LOG(2,("CPU #%d sound data <- $%02x\n", cpu_getactivecpu(), data));
107 return data;
108 }
109
READ_HANDLER(decocass_sound_ack_r)110 READ_HANDLER( decocass_sound_ack_r )
111 {
112 data8_t data = decocass_sound_ack; /* D6+D7 */
113 LOG(2,("CPU #%d sound ack <- $%02x\n", cpu_getactivecpu(), data));
114 return data;
115 }
116
WRITE_HANDLER(decocass_sound_data_w)117 WRITE_HANDLER( decocass_sound_data_w )
118 {
119 LOG(2,("CPU #%d sound data -> $%02x\n", cpu_getactivecpu(), data));
120 soundlatch2_w(0, data);
121 decocass_sound_ack |= 0x40;
122 }
123
READ_HANDLER(decocass_sound_command_r)124 READ_HANDLER( decocass_sound_command_r )
125 {
126 data8_t data = soundlatch_r(0);
127 LOG(2,("CPU #%d sound command <- $%02x\n", cpu_getactivecpu(), data));
128 cpu_set_irq_line(1, M6502_IRQ_LINE, CLEAR_LINE);
129 decocass_sound_ack &= ~0x80;
130 return data;
131 }
132
decocass_sound_nmi_pulse(int param)133 static void decocass_sound_nmi_pulse( int param )
134 {
135 cpu_set_nmi_line(1, PULSE_LINE);
136 }
137
WRITE_HANDLER(decocass_sound_nmi_enable_w)138 WRITE_HANDLER( decocass_sound_nmi_enable_w )
139 {
140 LOG(2,("CPU #%d sound NMI enb -> $%02x\n", cpu_getactivecpu(), data));
141 timer_adjust(decocass_sound_timer, TIME_IN_HZ(256 * 57 / 8 / 2), 0, TIME_IN_HZ(256 * 57 / 8 / 2));
142 }
143
READ_HANDLER(decocass_sound_nmi_enable_r)144 READ_HANDLER( decocass_sound_nmi_enable_r )
145 {
146 data8_t data = 0xff;
147 LOG(2,("CPU #%d sound NMI enb <- $%02x\n", cpu_getactivecpu(), data));
148 timer_adjust(decocass_sound_timer, TIME_IN_HZ(256 * 57 / 8 / 2), 0, TIME_IN_HZ(256 * 57 / 8 / 2));
149 return data;
150 }
151
READ_HANDLER(decocass_sound_data_ack_reset_r)152 READ_HANDLER( decocass_sound_data_ack_reset_r )
153 {
154 data8_t data = 0xff;
155 LOG(2,("CPU #%d sound ack rst <- $%02x\n", cpu_getactivecpu(), data));
156 decocass_sound_ack &= ~0x40;
157 return data;
158 }
159
WRITE_HANDLER(decocass_sound_data_ack_reset_w)160 WRITE_HANDLER( decocass_sound_data_ack_reset_w )
161 {
162 LOG(2,("CPU #%d sound ack rst -> $%02x\n", cpu_getactivecpu(), data));
163 decocass_sound_ack &= ~0x40;
164 }
165
WRITE_HANDLER(decocass_nmi_reset_w)166 WRITE_HANDLER( decocass_nmi_reset_w )
167 {
168 cpu_set_nmi_line( 0, CLEAR_LINE );
169 }
170
WRITE_HANDLER(decocass_quadrature_decoder_reset_w)171 WRITE_HANDLER( decocass_quadrature_decoder_reset_w )
172 {
173 /* just latch the analog controls here */
174 decocass_quadrature_decoder[0] = input_port_3_r(0);
175 decocass_quadrature_decoder[1] = input_port_4_r(0);
176 decocass_quadrature_decoder[2] = input_port_5_r(0);
177 decocass_quadrature_decoder[3] = input_port_6_r(0);
178 }
179
WRITE_HANDLER(decocass_adc_w)180 WRITE_HANDLER( decocass_adc_w )
181 {
182 }
183
184 /*
185 * E6x0 inputs
186 * E6x1 inputs
187 * E6x2 coin inp
188 * E6x3 quadrature decoder read
189 * E6x4 ""
190 * E6x5 ""
191 * E6x6 ""
192 * E6x7 a/d converter read
193 */
READ_HANDLER(decocass_input_r)194 READ_HANDLER( decocass_input_r )
195 {
196 data8_t data = 0xff;
197 switch (offset & 7)
198 {
199 case 0: case 1: case 2:
200 data = readinputport(offset & 7);
201 break;
202 case 3: case 4: case 5: case 6:
203 data = decocass_quadrature_decoder[(offset & 7) - 3];
204 break;
205 default:
206 break;
207 }
208
209 return data;
210 }
211
212 /*
213 * D0 - REQ/ data request (8041 pin 34 port 1.7)
214 * D1 - FNO/ function number (8041 pin 21 port 2.0)
215 * D2 - EOT/ end-of-tape (8041 pin 22 port 2.1)
216 * D3 - ERR/ error condition (8041 pin 23 port 2.2)
217 * D4 - BOT-EOT from tape
218 * D5 -
219 * D6 -
220 * D7 - cassette present
221 */
222 /* Note on a tapes leader-BOT-data-EOT-trailer format:
223 * A cassette has a transparent piece of tape on both ends,
224 * leader and trailer. And data tapes also have BOT and EOT
225 * holes, shortly before the the leader and trailer.
226 * The holes and clear tape are detected using a photo-resitor.
227 * When rewinding, the BOT/EOT signal will show a short
228 * pulse and if rewind continues a constant high signal later.
229 * The specs say the holes are "> 2ms" in length.
230 */
231
232 #define TAPE_CLOCKRATE 4800 /* clock pulses per second */
233
234 /* duration of the clear LEADER (and trailer) of the tape */
235 #define TAPE_LEADER TAPE_CLOCKRATE /* 1s */
236 /* duration of the GAP between leader and BOT/EOT */
237 #define TAPE_GAP TAPE_CLOCKRATE*3/2 /* 1.5s */
238 /* duration of BOT/EOT holes */
239 #define TAPE_HOLE TAPE_CLOCKRATE/400 /* 0.0025s */
240
241 /* byte offset of the tape chunks (8 clocks per byte = 16 samples) */
242 /* 300 ms GAP between BOT and first data block (doesn't work.. thus /2) */
243 #define TAPE_PRE_GAP 34
244 #define TAPE_LEADIN (TAPE_PRE_GAP + 1)
245 #define TAPE_HEADER (TAPE_LEADIN + 1)
246 #define TAPE_BLOCK (TAPE_HEADER + 256)
247 #define TAPE_CRC16_MSB (TAPE_BLOCK + 1)
248 #define TAPE_CRC16_LSB (TAPE_CRC16_MSB + 1)
249 #define TAPE_TRAILER (TAPE_CRC16_LSB + 1)
250 #define TAPE_LEADOUT (TAPE_TRAILER + 1)
251 #define TAPE_LONGCLOCK (TAPE_LEADOUT + 1)
252 #define TAPE_POST_GAP (TAPE_LONGCLOCK + 34)
253
254 /* size of a tape chunk (block) including gaps */
255 #define TAPE_CHUNK TAPE_POST_GAP
256
257 #define E5XX_MASK 0x02 /* use 0x0e for old style board */
258
259 #define BIT0(x) ((x)&1)
260 #define BIT1(x) (((x)>>1)&1)
261 #define BIT2(x) (((x)>>2)&1)
262 #define BIT3(x) (((x)>>3)&1)
263 #define BIT4(x) (((x)>>4)&1)
264 #define BIT5(x) (((x)>>5)&1)
265 #define BIT6(x) (((x)>>6)&1)
266 #define BIT7(x) (((x)>>7)&1)
267
WRITE_HANDLER(decocass_reset_w)268 WRITE_HANDLER( decocass_reset_w )
269 {
270 LOG(1,("%9.7f 6502-PC: %04x decocass_reset_w(%02x): $%02x\n", timer_get_time(), activecpu_get_previouspc(), offset, data));
271 decocass_reset = data;
272
273 /* CPU #1 active hight reset */
274 cpu_set_reset_line( 1, data & 0x01 );
275
276 /* on reset also remove the sound timer */
277 if (data & 1)
278 timer_adjust(decocass_sound_timer, TIME_NEVER, 0, 0);
279
280 /* 8041 active low reset */
281 cpu_set_reset_line( 2, (data & 0x08) ^ 0x08 );
282 }
283
284 #ifdef MAME_DEBUG
dirnm(int speed)285 static const char *dirnm(int speed)
286 {
287 if (speed < -1) return "fast rewind";
288 if (speed == -1) return "rewind";
289 if (speed == 0) return "stop";
290 if (speed == 1) return "forward";
291 return "fast forward";
292 }
293 #endif
294
tape_crc16(UINT8 data)295 static void tape_crc16(UINT8 data)
296 {
297 UINT8 c0, c1;
298 UINT8 old_lsb = crc16_lsb;
299 UINT8 old_msb = crc16_msb;
300 UINT8 feedback;
301
302 feedback = ((data >> 7) ^ crc16_msb) & 1;
303
304 /* rotate 16 bits */
305 c0 = crc16_lsb & 1;
306 c1 = crc16_msb & 1;
307 crc16_msb = (crc16_msb >> 1) | (c0 << 7);
308 crc16_lsb = (crc16_lsb >> 1) | (c1 << 7);
309
310 /* feedback into bit 7 */
311 if (feedback)
312 crc16_lsb |= 0x80;
313 else
314 crc16_lsb &= ~0x80;
315
316 /* feedback to bit 6 into bit 5 */
317 if (((old_lsb >> 6) ^ feedback) & 1)
318 crc16_lsb |= 0x20;
319 else
320 crc16_lsb &= ~0x20;
321
322 /* feedback to bit 1 into bit 0 */
323 if (((old_msb >> 1) ^ feedback) & 1)
324 crc16_msb |= 0x01;
325 else
326 crc16_msb &= ~0x01;
327 }
328
tape_update(void)329 static void tape_update(void)
330 {
331 static int last_byte;
332 double tape_time = tape_time0;
333 int offset, rclk, rdata, tape_bit, tape_byte, tape_block;
334
335 if (tape_timer)
336 tape_time += tape_dir * timer_timeelapsed(tape_timer);
337
338 if (tape_time < 0.0)
339 tape_time = 0.0;
340 else if (tape_time > 999.9)
341 tape_time = 999.9;
342
343 offset = (int)(tape_time * TAPE_CLOCKRATE + 0.499995);
344
345 /* reset RCLK and RDATA inputs */
346 rclk = 0;
347 rdata = 0;
348
349 if (offset < TAPE_LEADER)
350 {
351 if (offset < 0)
352 offset = 0;
353 /* LEADER area */
354 if (0 == tape_bot_eot)
355 {
356 tape_bot_eot = 1;
357 set_led_status(1, 1);
358 LOG(5,("tape %5.4fs: %s found LEADER\n", tape_time, dirnm(tape_dir)));
359 }
360 }
361 else
362 if (offset < TAPE_LEADER + TAPE_GAP)
363 {
364 /* GAP between LEADER and BOT hole */
365 if (1 == tape_bot_eot)
366 {
367 tape_bot_eot = 0;
368 set_led_status(1, 0);
369 LOG(5,("tape %5.4fs: %s between BOT + LEADER\n", tape_time, dirnm(tape_dir)));
370 }
371 }
372 else
373 if (offset < TAPE_LEADER + TAPE_GAP + TAPE_HOLE)
374 {
375 /* during BOT hole */
376 if (0 == tape_bot_eot)
377 {
378 tape_bot_eot = 1;
379 set_led_status(1, 1);
380 LOG(5,("tape %5.4fs: %s found BOT\n", tape_time, dirnm(tape_dir)));
381 }
382 }
383 else
384 if (offset < tape_length - TAPE_LEADER - TAPE_GAP - TAPE_HOLE)
385 {
386 offset -= TAPE_LEADER + TAPE_GAP + TAPE_HOLE;
387
388 /* data area */
389 if (1 == tape_bot_eot)
390 {
391 tape_bot_eot = 0;
392 set_led_status(1, 0);
393 LOG(5,("tape %5.4fs: %s data area\n", tape_time, dirnm(tape_dir)));
394 }
395 rclk = (offset ^ 1) & 1;
396 tape_bit = (offset / 2) % 8;
397 tape_byte = (offset / 16) % TAPE_CHUNK;
398 tape_block = offset / 16 / TAPE_CHUNK;
399
400 if (tape_byte < TAPE_PRE_GAP)
401 {
402 rclk = 0;
403 rdata = 0;
404 }
405 else
406 if (tape_byte < TAPE_LEADIN)
407 {
408 rdata = (0x00 >> tape_bit) & 1;
409 if (tape_byte != last_byte)
410 {
411 LOG(5,("tape %5.4fs: LEADIN $00\n", tape_time));
412 set_led_status(2, 1);
413 }
414 }
415 else
416 if (tape_byte < TAPE_HEADER)
417 {
418 rdata = (0xaa >> tape_bit) & 1;
419 if (tape_byte != last_byte)
420 LOG(5,("tape %5.4fs: HEADER $aa\n", tape_time));
421 }
422 else
423 if (tape_byte < TAPE_BLOCK)
424 {
425 data8_t *ptr = memory_region(REGION_USER2) + tape_block * 256 + tape_byte - TAPE_HEADER;
426 rdata = (*ptr >> tape_bit) & 1;
427 if (tape_byte != last_byte)
428 LOG(4,("tape %5.4fs: DATA(%02x) $%02x\n", tape_time, tape_byte - TAPE_HEADER, *ptr));
429 }
430 else
431 if (tape_byte < TAPE_CRC16_MSB)
432 {
433 rdata = (tape_crc16_msb[tape_block] >> tape_bit) & 1;
434 if (tape_byte != last_byte)
435 LOG(4,("tape %5.4fs: CRC16 MSB $%02x\n", tape_time, tape_crc16_msb[tape_block]));
436 }
437 else
438 if (tape_byte < TAPE_CRC16_LSB)
439 {
440 rdata = (tape_crc16_lsb[tape_block] >> tape_bit) & 1;
441 if (tape_byte != last_byte)
442 LOG(4,("tape %5.4fs: CRC16 LSB $%02x\n", tape_time, tape_crc16_lsb[tape_block]));
443 }
444 else
445 if (tape_byte < TAPE_TRAILER)
446 {
447 rdata = (0xaa >> tape_bit) & 1;
448 if (tape_byte != last_byte)
449 LOG(4,("tape %5.4fs: TRAILER $aa\n", tape_time));
450 }
451 else
452 if (tape_byte < TAPE_LEADOUT)
453 {
454 rdata = (0x00 >> tape_bit) & 1;
455 if (tape_byte != last_byte)
456 LOG(4,("tape %5.4fs: LEADOUT $00\n", tape_time));
457 }
458 else
459 if (tape_byte < TAPE_LONGCLOCK)
460 {
461 if (tape_byte != last_byte)
462 {
463 LOG(4,("tape %5.4fs: LONG CLOCK\n", tape_time));
464 set_led_status(2, 0);
465 }
466 rclk = 1;
467 rdata = 0;
468 }
469 last_byte = tape_byte;
470 }
471 else
472 if (offset < tape_length - TAPE_LEADER - TAPE_GAP)
473 {
474 /* during EOT hole */
475 if (0 == tape_bot_eot)
476 {
477 tape_bot_eot = 1;
478 set_led_status(1, 1);
479 LOG(5,("tape %5.4fs: %s found EOT\n", tape_time, dirnm(tape_dir)));
480 }
481 }
482 else
483 if (offset < tape_length - TAPE_LEADER)
484 {
485 /* GAP between EOT and trailer */
486 if (1 == tape_bot_eot)
487 {
488 tape_bot_eot = 0;
489 set_led_status(1, 0);
490 LOG(5,("tape %5.4fs: %s EOT and TRAILER\n", tape_time, dirnm(tape_dir)));
491 }
492 }
493 else
494 {
495 /* TRAILER area */
496 if (0 == tape_bot_eot)
497 {
498 tape_bot_eot = 1;
499 set_led_status(1, 1);
500 LOG(5,("tape %5.4fs: %s found TRAILER\n", tape_time, dirnm(tape_dir)));
501 }
502 offset = tape_length - 1;
503 }
504
505 i8041_p2 = (i8041_p2 & ~0xe0) | (tape_bot_eot << 5) | (rclk << 6) | (rdata << 7);
506 }
507
508 #ifdef MAME_DEBUG
decocass_fno(offs_t offset,data8_t data)509 static void decocass_fno(offs_t offset, data8_t data)
510 {
511 /* 8041ENA/ and is this a FNO write (function number)? */
512 if (0 == (i8041_p2 & 0x01))
513 {
514 switch (data)
515 {
516 case 0x25: logerror("8041 FNO 25: write_block\n"); break;
517 case 0x26: logerror("8041 FNO 26: rewind_block\n"); break;
518 case 0x27: logerror("8041 FNO 27: read_block_a\n"); break;
519 case 0x28: logerror("8041 FNO 28: read_block_b\n"); break;
520 case 0x29: logerror("8041 FNO 29: tape_rewind_fast\n"); break;
521 case 0x2a: logerror("8041 FNO 2a: tape_forward\n"); break;
522 case 0x2b: logerror("8041 FNO 2b: tape_rewind\n"); break;
523 case 0x2c: logerror("8041 FNO 2c: force_abort\n"); break;
524 case 0x2d: logerror("8041 FNO 2d: tape_erase\n"); break;
525 case 0x2e: logerror("8041 FNO 2e: search_tape_mark\n"); break;
526 case 0x2f: logerror("8041 FNO 2f: search_eot\n"); break;
527 case 0x30: logerror("8041 FNO 30: advance_block\n"); break;
528 case 0x31: logerror("8041 FNO 31: write_tape_mark\n"); break;
529 case 0x32: logerror("8041 FNO 32: reset_error\n"); break;
530 case 0x33: logerror("8041 FNO 33: flag_status_report\n"); break;
531 case 0x34: logerror("8041 FNO 34: report_status_to_main\n"); break;
532 default: logerror("8041 FNO %02x: invalid\n", data);
533 }
534 }
535 }
536 #endif
537
538 /***************************************************************************
539 *
540 * TYPE1 DONGLE (DE-0061)
541 * - Test Tape
542 * - Lock 'n Chase
543 * - Treasure Island
544 * - Super Astro Fighter
545 * - Lucky Poker
546 * - Terranian
547 * - Explorer
548 * - Pro Golf
549 *
550 ***************************************************************************/
551
READ_HANDLER(decocass_type1_r)552 READ_HANDLER( decocass_type1_r )
553 {
554 static data8_t latch1;
555 data8_t data;
556
557 if (1 == (offset & 1))
558 {
559 if (0 == (offset & E5XX_MASK))
560 data = cpunum_get_reg(2, I8X41_STAT);
561 else
562 data = 0xff;
563
564 data =
565 (BIT0(data) << 0) |
566 (BIT1(data) << 1) |
567 (1 << 2) |
568 (1 << 3) |
569 (1 << 4) |
570 (1 << 5) |
571 (1 << 6) |
572 (0 << 7);
573 LOG(4,("%9.7f 6502-PC: %04x decocass_type1_r(%02x): $%02x <- (%s %s)\n",
574 timer_get_time(), activecpu_get_previouspc(), offset, data,
575 (data & 1) ? "OBF" : "-",
576 (data & 2) ? "IBF" : "-"));
577 }
578 else
579 {
580 offs_t promaddr;
581 data8_t save;
582 UINT8 *prom = memory_region(REGION_USER1);
583
584 if (firsttime)
585 {
586 LOG(4,("prom data:\n"));
587 for (promaddr = 0; promaddr < 32; promaddr++)
588 {
589 if (promaddr % 8 == 0)
590 LOG(4,("%04x:", promaddr));
591 LOG(4,(" %02x%s", prom[promaddr], (promaddr % 8) == 7 ? "\n" : ""));
592 }
593 firsttime = 0;
594 latch1 = 0; /* reset latch (??) */
595 }
596
597 if (0 == (offset & E5XX_MASK))
598 data = cpunum_get_reg(2, I8X41_DATA);
599 else
600 data = 0xff;
601
602 save = data; /* save the unmodifed data for the latch */
603
604 promaddr =
605 (((data >> MAP0(type1_inmap)) & 1) << 0) |
606 (((data >> MAP1(type1_inmap)) & 1) << 1) |
607 (((data >> MAP4(type1_inmap)) & 1) << 2) |
608 (((data >> MAP5(type1_inmap)) & 1) << 3) |
609 (((data >> MAP7(type1_inmap)) & 1) << 4);
610
611 data =
612 (((prom[promaddr] >> 0) & 1) << MAP0(type1_outmap)) |
613 (((prom[promaddr] >> 1) & 1) << MAP1(type1_outmap)) |
614 ((1 - ((latch1 >> MAP2(type1_inmap)) & 1)) << MAP2(type1_outmap)) |
615 (((data >> MAP3(type1_inmap)) & 1) << MAP3(type1_outmap)) |
616 (((prom[promaddr] >> 2) & 1) << MAP4(type1_outmap)) |
617 (((prom[promaddr] >> 3) & 1) << MAP5(type1_outmap)) |
618 (((latch1 >> MAP6(type1_inmap)) & 1) << MAP6(type1_outmap)) |
619 (((prom[promaddr] >> 4) & 1) << MAP7(type1_outmap));
620
621 LOG(3,("%9.7f 6502-PC: %04x decocass_type1_r(%02x): $%02x <- (%s $%02x mangled with PROM[$%02x])\n", timer_get_time(), activecpu_get_previouspc(), offset, data, 0 == (offset & E5XX_MASK) ? "8041-DATA" : "open bus", save, promaddr));
622
623 latch1 = save; /* latch the data for the next A0 == 0 read */
624 }
625 return data;
626 }
627
628 /*
629 * special handler for the test tape, because we cannot
630 * look inside the dongle :-/
631 * There seem to be lines 1, 3 and 6 straight through.
632 * The rest could be translated with the standard Type1 dongle
633 * PROM, but I don't know. For now we have found this lookup
634 * table by applying data to the dongle and logging the outputs.
635 */
636
READ_HANDLER(decocass_type1_map1_r)637 READ_HANDLER( decocass_type1_map1_r )
638 {
639 static data8_t map[] = {
640 0x01,0x34,0x03,0x36,0xa4,0x15,0xa6,0x17,
641 0x09,0x3c,0x0b,0x3e,0xac,0x1d,0xae,0x1f,
642 0x90,0x14,0x92,0x16,0x85,0x00,0x87,0x02,
643 0x98,0x1c,0x9a,0x1e,0x8d,0x08,0x8f,0x0a,
644 0x31,0x30,0x33,0x32,0xa1,0x11,0xa3,0x13,
645 0x39,0x38,0x3b,0x3a,0xa9,0x19,0xab,0x1b,
646 0x84,0xb5,0x86,0xb7,0x81,0xb4,0x83,0xb6,
647 0x8c,0xbd,0x8e,0xbf,0x89,0xbc,0x8b,0xbe,
648 0x41,0x74,0x43,0x76,0xe4,0x55,0xe6,0x57,
649 0x49,0x7c,0x4b,0x7e,0xec,0x5d,0xee,0x5f,
650 0xd0,0x54,0xd2,0x56,0xc5,0x40,0xc7,0x42,
651 0xd8,0x5c,0xda,0x5e,0xcd,0x48,0xcf,0x4a,
652 0x71,0x70,0x73,0x72,0xe1,0x51,0xe3,0x53,
653 0x79,0x78,0x7b,0x7a,0xe9,0x59,0xeb,0x5b,
654 0xc4,0xf5,0xc6,0xf7,0xc1,0xf4,0xc3,0xf6,
655 0xcc,0xfd,0xce,0xff,0xc9,0xfc,0xcb,0xfe,
656 0x25,0xa0,0x27,0xa2,0x95,0x10,0x97,0x12,
657 0x2d,0xa8,0x2f,0xaa,0x9d,0x18,0x9f,0x1a,
658 0x80,0xb1,0x82,0xb3,0x24,0xb0,0x26,0xb2,
659 0x88,0xb9,0x8a,0xbb,0x2c,0xb8,0x2e,0xba,
660 0x21,0x94,0x23,0x96,0x05,0x04,0x07,0x06,
661 0x29,0x9c,0x2b,0x9e,0x0d,0x0c,0x0f,0x0e,
662 0x35,0xa5,0x37,0xa7,0x20,0x91,0x22,0x93,
663 0x3d,0xad,0x3f,0xaf,0x28,0x99,0x2a,0x9b,
664 0x65,0xe0,0x67,0xe2,0xd5,0x50,0xd7,0x52,
665 0x6d,0xe8,0x6f,0xea,0xdd,0x58,0xdf,0x5a,
666 0xc0,0xf1,0xc2,0xf3,0x64,0xf0,0x66,0xf2,
667 0xc8,0xf9,0xca,0xfb,0x6c,0xf8,0x6e,0xfa,
668 0x61,0xd4,0x63,0xd6,0x45,0x44,0x47,0x46,
669 0x69,0xdc,0x6b,0xde,0x4d,0x4c,0x4f,0x4e,
670 0x75,0xe5,0x77,0xe7,0x60,0xd1,0x62,0xd3,
671 0x7d,0xed,0x7f,0xef,0x68,0xd9,0x6a,0xdb
672 };
673 data8_t save, data;
674
675 if (1 == (offset & 1))
676 {
677 if (0 == (offset & E5XX_MASK))
678 data = cpunum_get_reg(2, I8X41_STAT);
679 else
680 data = 0xff;
681
682 data =
683 (BIT0(data) << 0) |
684 (BIT1(data) << 1) |
685 (1 << 2) |
686 (1 << 3) |
687 (1 << 4) |
688 (1 << 5) |
689 (1 << 6) |
690 (0 << 7);
691 LOG(4,("%9.7f 6502-PC: %04x decocass_type1_r(%02x): $%02x <- (%s %s)\n",
692 timer_get_time(), activecpu_get_previouspc(), offset, data,
693 (data & 1) ? "OBF" : "-",
694 (data & 2) ? "IBF" : "-"));
695 }
696 else
697 {
698 if (0 == (offset & E5XX_MASK))
699 save = cpunum_get_reg(2, I8X41_DATA);
700 else
701 save = 0xff;
702
703 data = map[save];
704
705 LOG(3,("%9.7f 6502-PC: %04x decocass_type1_r(%02x): $%02x '%c' <- map[%02x] (%s)\n", timer_get_time(), activecpu_get_previouspc(), offset, data, (data >= 32) ? data : '.', save, 0 == (offset & E5XX_MASK) ? "8041-DATA" : "open bus"));
706 }
707 return data;
708 }
709
READ_HANDLER(decocass_type1_map2_r)710 READ_HANDLER( decocass_type1_map2_r )
711 {
712 static data8_t map[] = {
713 /* 00 */0x06,0x1f,0x8f,0x0c,0x02,0x1b,0x8b,0x08,
714 0x1e,0x1d,0x8e,0x16,0x1a,0x19,0x8a,0x12,
715 0x95,0x17,0x94,0x05,0x91,0x13,0x90,0x01,
716 0x87,0x04,0x86,0x9f,0x83,0x00,0x82,0x9b,
717 /* 20 */0x26,0x3f,0xaf,0x2c,0x22,0x3b,0xab,0x28,
718 0x3e,0x3d,0xae,0x36,0x3a,0x39,0xaa,0x32,
719 0xb5,0x37,0xb4,0x25,0xb1,0x33,0xb0,0x21,
720 0xa7,0x24,0xa6,0xbf,0xa3,0x20,0xa2,0xbb,
721 /* 40 */0x46,0x5f,0xcf,0x4c,0x42,0x5b,0xcb,0x48,
722 0x5e,0x5d,0xce,0x56,0x5a,0x59,0xca,0x52,
723 0xd5,0x57,0xd4,0x45,0xd1,0x53,0xd0,0x41,
724 0xc7,0x44,0xc6,0xdf,0xc3,0x40,0xc2,0xdb,
725 /* 60 */0x66,0x7f,0xef,0x6c,0x62,0x7b,0xeb,0x68,
726 0x7e,0x7d,0xee,0x76,0x7a,0x79,0xea,0x72,
727 0xf5,0x77,0xf4,0x65,0xf1,0x73,0xf0,0x61,
728 0xe7,0x64,0xe6,0xff,0xe3,0x60,0xe2,0xfb,
729 /* 80 */0x1c,0x8d,0x8c,0x15,0x18,0x89,0x88,0x11,
730 0x0e,0x97,0x14,0x07,0x0a,0x93,0x10,0x03,
731 0x85,0x9e,0x0f,0x9d,0x81,0x9a,0x0b,0x99,
732 0x84,0x9c,0x0d,0x96,0x80,0x98,0x09,0x92,
733 /* a0 */0x3c,0xad,0xac,0x35,0x38,0xa9,0xa8,0x31,
734 0x2e,0xb7,0x34,0x27,0x2a,0xb3,0x30,0x23,
735 0xa5,0xbe,0x2f,0xbd,0xa1,0xba,0x2b,0xb9,
736 0xa4,0xbc,0x2d,0xb6,0xa0,0xb8,0x29,0xb2,
737 /* c0 */0x5c,0xcd,0xcc,0x55,0x58,0xc9,0xc8,0x51,
738 0x4e,0xd7,0x54,0x47,0x4a,0xd3,0x50,0x43,
739 0xc5,0xde,0x4f,0xdd,0xc1,0xda,0x4b,0xd9,
740 0xc4,0xdc,0x4d,0xd6,0xc0,0xd8,0x49,0xd2,
741 /* e0 */0x7c,0xed,0xec,0x75,0x78,0xe9,0xe8,0x71,
742 0x6e,0xf7,0x74,0x67,0x6a,0xf3,0x70,0x63,
743 0xe5,0xfe,0x6f,0xfd,0xe1,0xfa,0x6b,0xf9,
744 0xe4,0xfc,0x6d,0xf6,0xe0,0xf8,0x69,0xf2
745 };
746 static data8_t latch2;
747 data8_t save, addr, data;
748
749 /* read from tape:
750 * 7d 43 5d 4f 04 ae e3 59 57 cb d6 55 4d 15
751 * should become:
752 * ?? 48 44 52 42 30 31 44 45 43 4f 53 59 53
753 * lookup entries with above values:
754 * ?? 47 59 4f 44 ae a7 59 53 cf d2 55 4d 55
755 * difference:
756 * 04 04 00 40 00 44 00 04 04 04 00 00 40
757 */
758
759 if (1 == (offset & 1))
760 {
761 if (0 == (offset & E5XX_MASK))
762 data = cpunum_get_reg(2, I8X41_STAT);
763 else
764 data = 0xff;
765
766 data =
767 (BIT0(data) << 0) |
768 (BIT1(data) << 1) |
769 (1 << 2) |
770 (1 << 3) |
771 (1 << 4) |
772 (1 << 5) |
773 (1 << 6) |
774 (0 << 7);
775 LOG(4,("%9.7f 6502-PC: %04x decocass_type1_r(%02x): $%02x <- (%s %s)\n",
776 timer_get_time(), activecpu_get_previouspc(), offset, data,
777 (data & 1) ? "OBF" : "-",
778 (data & 2) ? "IBF" : "-"));
779 }
780 else
781 {
782 if (0 == (offset & E5XX_MASK))
783 save = cpunum_get_reg(2, I8X41_DATA);
784 else
785 save = 0xff;
786
787 addr = (save & ~0x44) | (latch2 & 0x44);
788 data = map[addr];
789
790 LOG(3,("%9.7f 6502-PC: %04x decocass_type1_r(%02x): $%02x '%c' <- map[%02x = %02x^((%02x^%02x)&%02x)] (%s)\n", timer_get_time(), activecpu_get_previouspc(), offset, data, (data >= 32) ? data : '.', addr, save, latch2, save, 0x44, 0 == (offset & E5XX_MASK) ? "8041-DATA" : "open bus"));
791 latch2 = save;
792 }
793 return data;
794 }
795
READ_HANDLER(decocass_type1_map3_r)796 READ_HANDLER( decocass_type1_map3_r )
797 {
798 static data8_t map[] = {
799 /* 00 */0x03,0x36,0x01,0x34,0xa6,0x17,0xa4,0x15,
800 0x0b,0x3e,0x09,0x3c,0xae,0x1f,0xac,0x1d,
801 0x92,0x16,0x90,0x14,0x87,0x02,0x85,0x00,
802 0x9a,0x1e,0x98,0x1c,0x8f,0x0a,0x8d,0x08,
803 /* 20 */0x33,0x32,0x31,0x30,0xa3,0x13,0xa1,0x11,
804 0x3b,0x3a,0x39,0x38,0xab,0x1b,0xa9,0x19,
805 0x86,0xb7,0x84,0xb5,0x83,0xb6,0x81,0xb4,
806 0x8e,0xbf,0x8c,0xbd,0x8b,0xbe,0x89,0xbc,
807 /* 40 */0x43,0x76,0x41,0x74,0xe6,0x57,0xe4,0x55,
808 0x4b,0x7e,0x49,0x7c,0xee,0x5f,0xec,0x5d,
809 0xd2,0x56,0xd0,0x54,0xc7,0x42,0xc5,0x40,
810 0xda,0x5e,0xd8,0x5c,0xcf,0x4a,0xcd,0x48,
811 /* 60 */0x73,0x72,0x71,0x70,0xe3,0x53,0xe1,0x51,
812 0x7b,0x7a,0x79,0x78,0xeb,0x5b,0xe9,0x59,
813 0xc6,0xf7,0xc4,0xf5,0xc3,0xf6,0xc1,0xf4,
814 0xce,0xff,0xcc,0xfd,0xcb,0xfe,0xc9,0xfc,
815 /* 80 */0x27,0xa2,0x25,0xa0,0x97,0x12,0x95,0x10,
816 0x2f,0xaa,0x2d,0xa8,0x9f,0x1a,0x9d,0x18,
817 0x82,0xb3,0x80,0xb1,0x26,0xb2,0x24,0xb0,
818 0x8a,0xbb,0x88,0xb9,0x2e,0xba,0x2c,0xb8,
819 /* a0 */0x23,0x96,0x21,0x94,0x07,0x06,0x05,0x04,
820 0x2b,0x9e,0x29,0x9c,0x0f,0x0e,0x0d,0x0c,
821 0x37,0xa7,0x35,0xa5,0x22,0x93,0x20,0x91,
822 0x3f,0xaf,0x3d,0xad,0x2a,0x9b,0x28,0x99,
823 /* c0 */0x67,0xe2,0x65,0xe0,0xd7,0x52,0xd5,0x50,
824 0x6f,0xea,0x6d,0xe8,0xdf,0x5a,0xdd,0x58,
825 0xc2,0xf3,0xc0,0xf1,0x66,0xf2,0x64,0xf0,
826 0xca,0xfb,0xc8,0xf9,0x6e,0xfa,0x6c,0xf8,
827 /* e0 */0x63,0xd6,0x61,0xd4,0x47,0x46,0x45,0x44,
828 0x6b,0xde,0x69,0xdc,0x4f,0x4e,0x4d,0x4c,
829 0x77,0xe7,0x75,0xe5,0x62,0xd3,0x60,0xd1,
830 0x7f,0xef,0x7d,0xed,0x6a,0xdb,0x68,0xd9
831 };
832 static data8_t latch3;
833 data8_t save, addr, data;
834
835 /* read from tape:
836 * f6 5f e5 c5 17 23 62 40 67 51 c5 ee 85 23
837 * should become:
838 * 20 48 44 52 42 30 31 41 53 54 52 4f 50 32
839 * lookup entries with above values:
840 * b6 5f e7 c5 55 23 22 42 65 53 c5 ec c7 21
841 * difference:
842 * 40 00 02 00 40 00 40 02 02 02 00 02 42 02
843 */
844
845 if (1 == (offset & 1))
846 {
847 if (0 == (offset & E5XX_MASK))
848 data = cpunum_get_reg(2, I8X41_STAT);
849 else
850 data = 0xff;
851
852 data =
853 (BIT0(data) << 0) |
854 (BIT1(data) << 1) |
855 (1 << 2) |
856 (1 << 3) |
857 (1 << 4) |
858 (1 << 5) |
859 (1 << 6) |
860 (0 << 7);
861 LOG(4,("%9.7f 6502-PC: %04x decocass_type1_r(%02x): $%02x <- (%s %s)\n",
862 timer_get_time(), activecpu_get_previouspc(), offset, data,
863 (data & 1) ? "OBF" : "-",
864 (data & 2) ? "IBF" : "-"));
865 }
866 else
867 {
868
869 if (0 == (offset & E5XX_MASK))
870 save = cpunum_get_reg(2, I8X41_DATA);
871 else
872 save = 0xff;
873
874 addr = (save & ~0x42) | (latch3 & 0x42);
875 data = map[addr];
876
877 LOG(3,("%9.7f 6502-PC: %04x decocass_type1_r(%02x): $%02x '%c' <- map[%02x = %02x^((%02x^%02x)&%02x)] (%s)\n", timer_get_time(), activecpu_get_previouspc(), offset, data, data >= 0x20 ? data : '.', addr, save, latch3, save, 0x42, 0 == (offset & E5XX_MASK) ? "8041-DATA" : "open bus"));
878 latch3 = save;
879 }
880 return data;
881 }
882
883 /***************************************************************************
884 *
885 * TYPE2 DONGLE (CS82-007)
886 * - Mission X
887 * - Disco No 1
888 * - Pro Tennis
889 * - Tornado
890 *
891 ***************************************************************************/
READ_HANDLER(decocass_type2_r)892 READ_HANDLER( decocass_type2_r )
893 {
894 data8_t data;
895
896 if (1 == type2_xx_latch)
897 {
898 if (1 == (offset & 1))
899 {
900 data8_t *prom = memory_region(REGION_USER1);
901 data = prom[256 * type2_d2_latch + type2_promaddr];
902 LOG(3,("%9.7f 6502-PC: %04x decocass_type2_r(%02x): $%02x <- prom[%03x]\n", timer_get_time(), activecpu_get_previouspc(), offset, data, 256 * type2_d2_latch + type2_promaddr));
903 }
904 else
905 {
906 data = 0xff; /* floating input? */
907 }
908 }
909 else
910 {
911 if (0 == (offset & E5XX_MASK))
912 data = cpunum_get_reg(2, offset & 1 ? I8X41_STAT : I8X41_DATA);
913 else
914 data = offset & 0xff;
915
916 LOG(3,("%9.7f 6502-PC: %04x decocass_type2_r(%02x): $%02x <- 8041-%s\n", timer_get_time(), activecpu_get_previouspc(), offset, data, offset & 1 ? "STATUS" : "DATA"));
917 }
918 return data;
919 }
920
WRITE_HANDLER(decocass_type2_w)921 WRITE_HANDLER( decocass_type2_w )
922 {
923 if (1 == type2_xx_latch)
924 {
925 if (1 == (offset & 1))
926 {
927 LOG(4,("%9.7f 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> set PROM+D2 latch", timer_get_time(), activecpu_get_previouspc(), offset, data));
928 }
929 else
930 {
931 type2_promaddr = data;
932 LOG(3,("%9.7f 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> set PROM addr $%02x\n", timer_get_time(), activecpu_get_previouspc(), offset, data, type2_promaddr));
933 return;
934 }
935 }
936 else
937 {
938 LOG(3,("%9.7f 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> %s ", timer_get_time(), activecpu_get_previouspc(), offset, data, offset & 1 ? "8041-CMND" : "8041 DATA"));
939 }
940 if (1 == (offset & 1))
941 {
942 if (0xc0 == (data & 0xf0))
943 {
944 type2_xx_latch = 1;
945 type2_d2_latch = (data & 0x04) ? 1 : 0;
946 LOG(3,("PROM:%s D2:%d", type2_xx_latch ? "on" : "off", type2_d2_latch));
947 }
948 }
949 cpunum_set_reg(2, offset & 1 ? I8X41_CMND : I8X41_DATA, data);
950
951 #ifdef MAME_DEBUG
952 decocass_fno(offset, data);
953 #endif
954 }
955
956 /***************************************************************************
957 *
958 * TYPE3 DONGLE
959 * - Bump 'n Jump
960 * - Burnin' Rubber
961 * - Burger Time
962 * - Graplop
963 * - Cluster Buster
964 * - LaPaPa
965 * - Fighting Ice Hockey
966 * - Pro Bowling
967 * - Night Star
968 * - Pro Soccer
969 * - Peter Pepper's Ice Cream Factory
970 *
971 ***************************************************************************/
READ_HANDLER(decocass_type3_r)972 READ_HANDLER( decocass_type3_r )
973 {
974 data8_t data, save;
975
976 if (1 == (offset & 1))
977 {
978 if (1 == type3_pal_19)
979 {
980 data8_t *prom = memory_region(REGION_USER1);
981 data = prom[type3_ctrs];
982 LOG(3,("%9.7f 6502-PC: %04x decocass_type3_r(%02x): $%02x <- prom[$%03x]\n", timer_get_time(), activecpu_get_previouspc(), offset, data, type3_ctrs));
983 if (++type3_ctrs == 4096)
984 type3_ctrs = 0;
985 }
986 else
987 {
988 if (0 == (offset & E5XX_MASK))
989 {
990 data = cpunum_get_reg(2, I8X41_STAT);
991 LOG(4,("%9.7f 6502-PC: %04x decocass_type3_r(%02x): $%02x <- 8041 STATUS\n", timer_get_time(), activecpu_get_previouspc(), offset, data));
992 }
993 else
994 {
995 data = 0xff; /* open data bus? */
996 LOG(4,("%9.7f 6502-PC: %04x decocass_type3_r(%02x): $%02x <- open bus\n", timer_get_time(), activecpu_get_previouspc(), offset, data));
997 }
998 }
999 }
1000 else
1001 {
1002 if (1 == type3_pal_19)
1003 {
1004 save = data = 0xff; /* open data bus? */
1005 LOG(3,("%9.7f 6502-PC: %04x decocass_type3_r(%02x): $%02x <- open bus", timer_get_time(), activecpu_get_previouspc(), offset, data));
1006 }
1007 else
1008 {
1009 if (0 == (offset & E5XX_MASK))
1010 {
1011 save = cpunum_get_reg(2, I8X41_DATA);
1012 if (type3_swap == TYPE3_SWAP_01)
1013 {
1014 data =
1015 (BIT1(save) << 0) |
1016 (type3_d0_latch << 1) |
1017 (BIT2(save) << 2) |
1018 (BIT3(save) << 3) |
1019 (BIT4(save) << 4) |
1020 (BIT5(save) << 5) |
1021 (BIT6(save) << 6) |
1022 (BIT7(save) << 7);
1023 type3_d0_latch = save & 1;
1024 }
1025 else
1026 if (type3_swap == TYPE3_SWAP_12)
1027 {
1028 data =
1029 (type3_d0_latch << 0) |
1030 (BIT2(save) << 1) |
1031 (BIT1(save) << 2) |
1032 (BIT3(save) << 3) |
1033 (BIT4(save) << 4) |
1034 (BIT5(save) << 5) |
1035 (BIT6(save) << 6) |
1036 (BIT7(save) << 7);
1037 type3_d0_latch = save & 1;
1038 }
1039 else
1040 if (type3_swap == TYPE3_SWAP_13)
1041 {
1042 data =
1043 (type3_d0_latch << 0) |
1044 (BIT3(save) << 1) |
1045 (BIT2(save) << 2) |
1046 (BIT1(save) << 3) |
1047 (BIT4(save) << 4) |
1048 (BIT5(save) << 5) |
1049 (BIT6(save) << 6) |
1050 (BIT7(save) << 7);
1051 type3_d0_latch = save & 1;
1052 }
1053 else
1054 if (type3_swap == TYPE3_SWAP_24)
1055 {
1056 data =
1057 (type3_d0_latch << 0) |
1058 (BIT1(save) << 1) |
1059 (BIT4(save) << 2) |
1060 (BIT3(save) << 3) |
1061 (BIT2(save) << 4) |
1062 (BIT5(save) << 5) |
1063 (BIT6(save) << 6) |
1064 (BIT7(save) << 7);
1065 type3_d0_latch = save & 1;
1066 }
1067 else
1068 if (type3_swap == TYPE3_SWAP_25)
1069 {
1070 data =
1071 (type3_d0_latch << 0) |
1072 (BIT1(save) << 1) |
1073 (BIT5(save) << 2) |
1074 (BIT3(save) << 3) |
1075 (BIT4(save) << 4) |
1076 (BIT2(save) << 5) |
1077 (BIT6(save) << 6) |
1078 (BIT7(save) << 7);
1079 type3_d0_latch = save & 1;
1080 }
1081 else
1082 if (type3_swap == TYPE3_SWAP_34_0)
1083 {
1084 data =
1085 (type3_d0_latch << 0) |
1086 (BIT1(save) << 1) |
1087 (BIT2(save) << 2) |
1088 (BIT3(save) << 4) |
1089 (BIT4(save) << 3) |
1090 (BIT5(save) << 5) |
1091 (BIT6(save) << 6) |
1092 (BIT7(save) << 7);
1093 type3_d0_latch = save & 1;
1094 }
1095 else
1096 if (type3_swap == TYPE3_SWAP_34_7)
1097 {
1098 data =
1099 (BIT7(save) << 0) |
1100 (BIT1(save) << 1) |
1101 (BIT2(save) << 2) |
1102 (BIT4(save) << 3) |
1103 (BIT3(save) << 4) |
1104 (BIT5(save) << 5) |
1105 (BIT6(save) << 6) |
1106 (type3_d0_latch << 7);
1107 type3_d0_latch = save & 1;
1108 }
1109 else
1110 if (type3_swap == TYPE3_SWAP_56)
1111 {
1112 data =
1113 type3_d0_latch |
1114 (BIT1(save) << 1) |
1115 (BIT2(save) << 2) |
1116 (BIT3(save) << 3) |
1117 (BIT4(save) << 4) |
1118 (BIT6(save) << 5) |
1119 (BIT5(save) << 6) |
1120 (BIT7(save) << 7);
1121 type3_d0_latch = save & 1;
1122 }
1123 else
1124 if (type3_swap == TYPE3_SWAP_67)
1125 {
1126 data =
1127 type3_d0_latch |
1128 (BIT1(save) << 1) |
1129 (BIT2(save) << 2) |
1130 (BIT3(save) << 3) |
1131 (BIT4(save) << 4) |
1132 (BIT5(save) << 5) |
1133 (BIT7(save) << 6) |
1134 (BIT6(save) << 7);
1135 type3_d0_latch = save & 1;
1136 }
1137 else
1138 {
1139 data =
1140 type3_d0_latch |
1141 (BIT1(save) << 1) |
1142 (BIT2(save) << 2) |
1143 (BIT3(save) << 3) |
1144 (BIT4(save) << 4) |
1145 (BIT5(save) << 5) |
1146 (BIT6(save) << 6) |
1147 (BIT7(save) << 7);
1148 type3_d0_latch = save & 1;
1149 }
1150 LOG(3,("%9.7f 6502-PC: %04x decocass_type3_r(%02x): $%02x '%c' <- 8041-DATA\n", timer_get_time(), activecpu_get_previouspc(), offset, data, (data >= 32) ? data : '.'));
1151 }
1152 else
1153 {
1154 save = 0xff; /* open data bus? */
1155 data =
1156 type3_d0_latch |
1157 (BIT1(save) << 1) |
1158 (BIT2(save) << 2) |
1159 (BIT3(save) << 3) |
1160 (BIT4(save) << 4) |
1161 (BIT5(save) << 5) |
1162 (BIT6(save) << 7) |
1163 (BIT7(save) << 6);
1164 LOG(3,("%9.7f 6502-PC: %04x decocass_type3_r(%02x): $%02x '%c' <- open bus (D0 replaced with latch)\n", timer_get_time(), activecpu_get_previouspc(), offset, data, (data >= 32) ? data : '.'));
1165 type3_d0_latch = save & 1;
1166 }
1167 }
1168 }
1169
1170 return data;
1171 }
1172
WRITE_HANDLER(decocass_type3_w)1173 WRITE_HANDLER( decocass_type3_w )
1174 {
1175 if (1 == (offset & 1))
1176 {
1177 if (1 == type3_pal_19)
1178 {
1179 type3_ctrs = data << 4;
1180 LOG(3,("%9.7f 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> %s\n", timer_get_time(), activecpu_get_previouspc(), offset, data, "LDCTRS"));
1181 return;
1182 }
1183 else
1184 if (0xc0 == (data & 0xf0))
1185 type3_pal_19 = 1;
1186 }
1187 else
1188 {
1189 if (1 == type3_pal_19)
1190 {
1191 /* write nowhere?? */
1192 LOG(3,("%9.7f 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> %s\n", timer_get_time(), activecpu_get_previouspc(), offset, data, "nowhere?"));
1193 return;
1194 }
1195 }
1196 LOG(3,("%9.7f 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> %s\n", timer_get_time(), activecpu_get_previouspc(), offset, data, offset & 1 ? "8041-CMND" : "8041-DATA"));
1197 cpunum_set_reg(2, offset & 1 ? I8X41_CMND : I8X41_DATA, data);
1198 }
1199
1200 /***************************************************************************
1201 *
1202 * TYPE4 DONGLE
1203 * - Scrum Try
1204 * Contains a 32K (EP)ROM that can be read from any byte
1205 * boundary sequentially. The EPROM is enable after writing
1206 * 1100xxxx to E5x1 once. Then an address is written LSB
1207 * to E5x0 MSB to E5x1 and every read from E5x1 returns the
1208 * next byte of the contents.
1209 *
1210 ***************************************************************************/
1211
READ_HANDLER(decocass_type4_r)1212 READ_HANDLER( decocass_type4_r )
1213 {
1214 data8_t data;
1215
1216 if (1 == (offset & 1))
1217 {
1218 if (0 == (offset & E5XX_MASK))
1219 {
1220 data = cpunum_get_reg(2, I8X41_STAT);
1221 LOG(4,("%9.7f 6502-PC: %04x decocass_type4_r(%02x): $%02x <- 8041 STATUS\n", timer_get_time(), activecpu_get_previouspc(), offset, data));
1222 }
1223 else
1224 {
1225 data = 0xff; /* open data bus? */
1226 LOG(4,("%9.7f 6502-PC: %04x decocass_type4_r(%02x): $%02x <- open bus\n", timer_get_time(), activecpu_get_previouspc(), offset, data));
1227 }
1228 }
1229 else
1230 {
1231 if (type4_latch)
1232 {
1233 UINT8 *prom = memory_region(REGION_USER1);
1234
1235 data = prom[type4_ctrs];
1236 LOG(3,("%9.7f 6502-PC: %04x decocass_type5_r(%02x): $%02x '%c' <- PROM[%04x]\n", timer_get_time(), activecpu_get_previouspc(), offset, data, (data >= 32) ? data : '.', type4_ctrs));
1237 type4_ctrs = (type4_ctrs+1) & 0x7fff;
1238 }
1239 else
1240 {
1241 if (0 == (offset & E5XX_MASK))
1242 {
1243 data = cpunum_get_reg(2, I8X41_DATA);
1244 LOG(3,("%9.7f 6502-PC: %04x decocass_type4_r(%02x): $%02x '%c' <- open bus (D0 replaced with latch)\n", timer_get_time(), activecpu_get_previouspc(), offset, data, (data >= 32) ? data : '.'));
1245 }
1246 else
1247 {
1248 data = 0xff; /* open data bus? */
1249 LOG(4,("%9.7f 6502-PC: %04x decocass_type4_r(%02x): $%02x <- open bus\n", timer_get_time(), activecpu_get_previouspc(), offset, data));
1250 }
1251 }
1252 }
1253
1254 return data;
1255 }
1256
WRITE_HANDLER(decocass_type4_w)1257 WRITE_HANDLER( decocass_type4_w )
1258 {
1259 if (1 == (offset & 1))
1260 {
1261 if (1 == type4_latch)
1262 {
1263 type4_ctrs = (type4_ctrs & 0x00ff) | ((data & 0x7f) << 8);
1264 LOG(3,("%9.7f 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> CTRS MSB (%04x)\n", timer_get_time(), activecpu_get_previouspc(), offset, data, type4_ctrs));
1265 return;
1266 }
1267 else
1268 if (0xc0 == (data & 0xf0))
1269 {
1270 type4_latch = 1;
1271 }
1272 }
1273 else
1274 {
1275 if (type4_latch)
1276 {
1277 type4_ctrs = (type4_ctrs & 0xff00) | data;
1278 LOG(3,("%9.7f 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> CTRS LSB (%04x)\n", timer_get_time(), activecpu_get_previouspc(), offset, data, type4_ctrs));
1279 return;
1280 }
1281 }
1282 LOG(3,("%9.7f 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> %s\n", timer_get_time(), activecpu_get_previouspc(), offset, data, offset & 1 ? "8041-CMND" : "8041-DATA"));
1283 cpunum_set_reg(2, offset & 1 ? I8X41_CMND : I8X41_DATA, data);
1284 }
1285
1286 /***************************************************************************
1287 *
1288 * TYPE5 DONGLE
1289 * - Boulder Dash
1290 * Actually a NOP dongle returning 0x55 after triggering a latch
1291 * by writing 1100xxxx to E5x1
1292 *
1293 ***************************************************************************/
1294
READ_HANDLER(decocass_type5_r)1295 READ_HANDLER( decocass_type5_r )
1296 {
1297 data8_t data;
1298
1299 if (1 == (offset & 1))
1300 {
1301 if (0 == (offset & E5XX_MASK))
1302 {
1303 data = cpunum_get_reg(2, I8X41_STAT);
1304 LOG(4,("%9.7f 6502-PC: %04x decocass_type5_r(%02x): $%02x <- 8041 STATUS\n", timer_get_time(), activecpu_get_previouspc(), offset, data));
1305 }
1306 else
1307 {
1308 data = 0xff; /* open data bus? */
1309 LOG(4,("%9.7f 6502-PC: %04x decocass_type5_r(%02x): $%02x <- open bus\n", timer_get_time(), activecpu_get_previouspc(), offset, data));
1310 }
1311 }
1312 else
1313 {
1314 if (type5_latch)
1315 {
1316 data = 0x55; /* Only a fixed value? It looks like this is all we need to do */
1317 LOG(3,("%9.7f 6502-PC: %04x decocass_type5_r(%02x): $%02x '%c' <- fixed value???\n", timer_get_time(), activecpu_get_previouspc(), offset, data, (data >= 32) ? data : '.'));
1318 }
1319 else
1320 {
1321 if (0 == (offset & E5XX_MASK))
1322 {
1323 data = cpunum_get_reg(2, I8X41_DATA);
1324 LOG(3,("%9.7f 6502-PC: %04x decocass_type5_r(%02x): $%02x '%c' <- open bus (D0 replaced with latch)\n", timer_get_time(), activecpu_get_previouspc(), offset, data, (data >= 32) ? data : '.'));
1325 }
1326 else
1327 {
1328 data = 0xff; /* open data bus? */
1329 LOG(4,("%9.7f 6502-PC: %04x decocass_type5_r(%02x): $%02x <- open bus\n", timer_get_time(), activecpu_get_previouspc(), offset, data));
1330 }
1331 }
1332 }
1333
1334 return data;
1335 }
1336
WRITE_HANDLER(decocass_type5_w)1337 WRITE_HANDLER( decocass_type5_w )
1338 {
1339 if (1 == (offset & 1))
1340 {
1341 if (1 == type5_latch)
1342 {
1343 LOG(3,("%9.7f 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> %s\n", timer_get_time(), activecpu_get_previouspc(), offset, data, "latch #2??"));
1344 return;
1345 }
1346 else
1347 if (0xc0 == (data & 0xf0))
1348 type5_latch = 1;
1349 }
1350 else
1351 {
1352 if (type5_latch)
1353 {
1354 /* write nowhere?? */
1355 LOG(3,("%9.7f 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> %s\n", timer_get_time(), activecpu_get_previouspc(), offset, data, "nowhere?"));
1356 return;
1357 }
1358 }
1359 LOG(3,("%9.7f 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> %s\n", timer_get_time(), activecpu_get_previouspc(), offset, data, offset & 1 ? "8041-CMND" : "8041-DATA"));
1360 cpunum_set_reg(2, offset & 1 ? I8X41_CMND : I8X41_DATA, data);
1361 }
1362
1363 /***************************************************************************
1364 *
1365 * Main dongle and 8041 interface
1366 *
1367 ***************************************************************************/
1368
READ_HANDLER(decocass_e5xx_r)1369 READ_HANDLER( decocass_e5xx_r )
1370 {
1371 data8_t data;
1372
1373 /* E5x2-E5x3 and mirrors */
1374 if (2 == (offset & E5XX_MASK))
1375 {
1376 data =
1377 (BIT7(i8041_p1) << 0) | /* D0 = P17 - REQ/ */
1378 (BIT0(i8041_p2) << 1) | /* D1 = P20 - FNO/ */
1379 (BIT1(i8041_p2) << 2) | /* D2 = P21 - EOT/ */
1380 (BIT2(i8041_p2) << 3) | /* D3 = P22 - ERR/ */
1381 ((tape_bot_eot) << 4) | /* D4 = BOT/EOT (direct from drive) */
1382 (1 << 5) | /* D5 floating input */
1383 (1 << 6) | /* D6 floating input */
1384 ((1 - tape_present) << 7); /* D7 = cassette present */
1385
1386 LOG(4,("%9.7f 6502-PC: %04x decocass_e5xx_r(%02x): $%02x <- STATUS (%s%s%s%s%s%s%s%s)\n",
1387 timer_get_time(),
1388 activecpu_get_previouspc(),
1389 offset, data,
1390 data & 0x01 ? "" : "REQ/",
1391 data & 0x02 ? "" : " FNO/",
1392 data & 0x04 ? "" : " EOT/",
1393 data & 0x08 ? "" : " ERR/",
1394 data & 0x10 ? " [BOT-EOT]" : "",
1395 data & 0x20 ? " [BIT5?]" : "",
1396 data & 0x40 ? " [BIT6?]" : "",
1397 data & 0x80 ? "" : " [CASS-PRESENT/]"));
1398 }
1399 else
1400 {
1401 if (decocass_dongle_r)
1402 data = (*decocass_dongle_r)(offset);
1403 else
1404 data = 0xff;
1405 }
1406 return data;
1407 }
1408
WRITE_HANDLER(decocass_e5xx_w)1409 WRITE_HANDLER( decocass_e5xx_w )
1410 {
1411 if (decocass_dongle_w)
1412 {
1413 (*decocass_dongle_w)(offset, data);
1414 return;
1415 }
1416
1417 if (0 == (offset & E5XX_MASK))
1418 {
1419 LOG(3,("%9.7f 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> %s\n", timer_get_time(), activecpu_get_previouspc(), offset, data, offset & 1 ? "8041-CMND" : "8041-DATA"));
1420 cpunum_set_reg(2, offset & 1 ? I8X41_CMND : I8X41_DATA, data);
1421 #ifdef MAME_DEBUG
1422 decocass_fno(offset, data);
1423 #endif
1424 }
1425 else
1426 {
1427 LOG(3,("%9.7f 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> dongle\n", timer_get_time(), activecpu_get_previouspc(), offset, data));
1428 }
1429 }
1430
1431 /***************************************************************************
1432 *
1433 * init machine functions (select dongle and determine tape image size)
1434 *
1435 ***************************************************************************/
decocass_state_save_postload(void)1436 static void decocass_state_save_postload(void)
1437 {
1438 int A;
1439 unsigned char *mem = memory_region(REGION_CPU1);
1440 int diff = memory_region_length(REGION_CPU1) / 2;
1441
1442 memory_set_opcode_base(0, mem + diff);
1443
1444 for (A = 0;A < 0x10000; A++)
1445 decocass_w(A, mem[A]);
1446 /* restart the timer if the tape was playing */
1447 if (0 != tape_dir)
1448 timer_adjust(tape_timer, TIME_NEVER, 0, 0);
1449 }
1450
decocass_init_common(void)1451 void decocass_init_common(void)
1452 {
1453 UINT8 *image = memory_region(REGION_USER2);
1454 int i, offs;
1455
1456 tape_dir = 0;
1457 tape_speed = 0;
1458 tape_timer = timer_alloc(NULL);
1459
1460 firsttime = 1;
1461 tape_present = 1;
1462 tape_blocks = 0;
1463 for (i = memory_region_length(REGION_USER2) / 256 - 1; !tape_blocks && i > 0; i--)
1464 for (offs = 256 * i; !tape_blocks && offs < 256 * i + 256; offs++)
1465 if (image[offs])
1466 tape_blocks = i+1;
1467 for (i = 0; i < tape_blocks; i++)
1468 {
1469 crc16_lsb = 0;
1470 crc16_msb = 0;
1471 for (offs = 256 * i; offs < 256 * i + 256; offs++)
1472 {
1473 tape_crc16(image[offs] << 7);
1474 tape_crc16(image[offs] << 6);
1475 tape_crc16(image[offs] << 5);
1476 tape_crc16(image[offs] << 4);
1477 tape_crc16(image[offs] << 3);
1478 tape_crc16(image[offs] << 2);
1479 tape_crc16(image[offs] << 1);
1480 tape_crc16(image[offs] << 0);
1481 }
1482 tape_crc16_lsb[i] = crc16_lsb;
1483 tape_crc16_msb[i] = crc16_msb;
1484 }
1485
1486 tape_length = tape_blocks * TAPE_CHUNK * 8 * 2 + 2 * (TAPE_LEADER + TAPE_GAP + TAPE_HOLE);
1487 tape_time0 = (double)(TAPE_LEADER + TAPE_GAP - TAPE_HOLE) / TAPE_CLOCKRATE;
1488 LOG(0,("tape: %d blocks\n", tape_blocks));
1489 tape_bot_eot = 0;
1490
1491 decocass_dongle_r = NULL;
1492 decocass_dongle_w = NULL;
1493
1494 decocass_reset = 0;
1495 i8041_p1 = 0xff;
1496 i8041_p2 = 0xff;
1497
1498 type1_inmap = MAKE_MAP(0,1,2,3,4,5,6,7);
1499 type1_outmap = MAKE_MAP(0,1,2,3,4,5,6,7);
1500
1501 type2_d2_latch = 0;
1502 type2_xx_latch = 0;
1503 type2_promaddr = 0;
1504
1505 type3_ctrs = 0;
1506 type3_d0_latch = 0;
1507 type3_pal_19 = 0;
1508 type3_swap = 0;
1509
1510 memset(decocass_quadrature_decoder, 0, sizeof(decocass_quadrature_decoder));
1511 decocass_sound_ack = 0;
1512 decocass_sound_timer = timer_alloc(decocass_sound_nmi_pulse);
1513
1514 /* state saving code */
1515 state_save_register_func_postload(decocass_state_save_postload);
1516 state_save_register_int ("decocass", 0, "tape_dir", &tape_dir);
1517 state_save_register_int ("decocass", 0, "tape_speed", &tape_speed);
1518 state_save_register_double ("decocass", 0, "tape_time0", &tape_time0, 1);
1519 state_save_register_int ("decocass", 0, "firsttime", &firsttime);
1520 state_save_register_int ("decocass", 0, "tape_present", &tape_present);
1521 state_save_register_int ("decocass", 0, "tape_blocks", &tape_blocks);
1522 state_save_register_int ("decocass", 0, "tape_length", &tape_length);
1523 state_save_register_int ("decocass", 0, "tape_bot_eot", &tape_bot_eot);
1524 state_save_register_UINT8 ("decocass", 0, "crc16_lsb", &crc16_lsb, 1);
1525 state_save_register_UINT8 ("decocass", 0, "crc16_msb", &crc16_msb, 1);
1526 state_save_register_UINT8 ("decocass", 0, "tape_crc16_lsb", tape_crc16_lsb, 256);
1527 state_save_register_UINT8 ("decocass", 0, "tape_crc16_msb", tape_crc16_msb, 256);
1528 state_save_register_UINT8 ("decocass", 0, "decocass_reset", &decocass_reset, 1);
1529 state_save_register_UINT8 ("decocass", 0, "i8041_p1", &i8041_p1, 1);
1530 state_save_register_UINT8 ("decocass", 0, "i8041_p2", &i8041_p2, 1);
1531 state_save_register_UINT32 ("decocass", 0, "type1_inmap", &type1_inmap, 1);
1532 state_save_register_UINT32 ("decocass", 0, "type1_outmap", &type1_outmap, 1);
1533 state_save_register_int ("decocass", 0, "type2_d2_latch", &type2_d2_latch);
1534 state_save_register_int ("decocass", 0, "type2_xx_latch", &type2_xx_latch);
1535 state_save_register_int ("decocass", 0, "type2_promaddr", &type2_promaddr);
1536 state_save_register_int ("decocass", 0, "type3_ctrs", &type3_ctrs);
1537 state_save_register_int ("decocass", 0, "type3_d0_latch", &type3_d0_latch);
1538 state_save_register_int ("decocass", 0, "type3_pal_19", &type3_pal_19);
1539 state_save_register_int ("decocass", 0, "type3_swap", &type3_swap);
1540 state_save_register_int ("decocass", 0, "type4_ctrs", &type4_ctrs);
1541 state_save_register_int ("decocass", 0, "type4_latch", &type4_latch);
1542 state_save_register_int ("decocass", 0, "type5_latch", &type5_latch);
1543 state_save_register_UINT8 ("decocass", 0, "decocass_sound_ack", &decocass_sound_ack, 1);
1544 }
1545
MACHINE_INIT(decocass)1546 MACHINE_INIT( decocass )
1547 {
1548 decocass_init_common();
1549 }
1550
MACHINE_INIT(ctsttape)1551 MACHINE_INIT( ctsttape )
1552 {
1553 decocass_init_common();
1554 LOG(0,("dongle type #1 (DE-0061)\n"));
1555 decocass_dongle_r = decocass_type1_map1_r;
1556 }
1557
MACHINE_INIT(clocknch)1558 MACHINE_INIT( clocknch )
1559 {
1560 decocass_init_common();
1561 LOG(0,("dongle type #1 (DE-0061 flip 2-3)\n"));
1562 decocass_dongle_r = decocass_type1_r;
1563 type1_inmap = MAKE_MAP(0,1,3,2,4,5,6,7);
1564 type1_outmap = MAKE_MAP(0,1,3,2,4,5,6,7);
1565 }
1566
MACHINE_INIT(ctisland)1567 MACHINE_INIT( ctisland )
1568 {
1569 decocass_init_common();
1570 LOG(0,("dongle type #1 (DE-0061 flip 0-2)\n"));
1571 decocass_dongle_r = decocass_type1_r;
1572 type1_inmap = MAKE_MAP(2,1,0,3,4,5,6,7);
1573 type1_outmap = MAKE_MAP(2,1,0,3,4,5,6,7);
1574 }
1575
MACHINE_INIT(csuperas)1576 MACHINE_INIT( csuperas )
1577 {
1578 decocass_init_common();
1579 LOG(0,("dongle type #1 (DE-0061 flip 4-5)\n"));
1580 decocass_dongle_r = decocass_type1_r;
1581 type1_inmap = MAKE_MAP(0,1,2,3,5,4,6,7);
1582 type1_outmap = MAKE_MAP(0,1,2,3,5,4,6,7);
1583 }
1584
MACHINE_INIT(castfant)1585 MACHINE_INIT( castfant )
1586 {
1587 decocass_init_common();
1588 LOG(0,("dongle type #1 (DE-0061 flip 1-2)\n"));
1589 decocass_dongle_r = decocass_type1_map3_r;
1590 }
1591
MACHINE_INIT(cluckypo)1592 MACHINE_INIT( cluckypo )
1593 {
1594 decocass_init_common();
1595 LOG(0,("dongle type #1 (DE-0061 flip 1-3)\n"));
1596 decocass_dongle_r = decocass_type1_r;
1597 type1_inmap = MAKE_MAP(0,3,2,1,4,5,6,7);
1598 type1_outmap = MAKE_MAP(0,3,2,1,4,5,6,7);
1599 }
1600
MACHINE_INIT(cterrani)1601 MACHINE_INIT( cterrani )
1602 {
1603 decocass_init_common();
1604 LOG(0,("dongle type #1 (DE-0061 straight)\n"));
1605 decocass_dongle_r = decocass_type1_r;
1606 type1_inmap = MAKE_MAP(0,1,2,3,4,5,6,7);
1607 type1_outmap = MAKE_MAP(0,1,2,3,4,5,6,7);
1608 }
1609
MACHINE_INIT(cexplore)1610 MACHINE_INIT( cexplore )
1611 {
1612 decocass_init_common();
1613 LOG(0,("dongle type #1 (DE-0061)\n"));
1614 decocass_dongle_r = decocass_type1_map2_r;
1615 }
1616
MACHINE_INIT(cprogolf)1617 MACHINE_INIT( cprogolf )
1618 {
1619 decocass_init_common();
1620 LOG(0,("dongle type #1 (DE-0061 flip 0-1)\n"));
1621 decocass_dongle_r = decocass_type1_r;
1622 type1_inmap = MAKE_MAP(1,0,2,3,4,5,6,7);
1623 type1_outmap = MAKE_MAP(1,0,2,3,4,5,6,7);
1624 }
1625
MACHINE_INIT(cmissnx)1626 MACHINE_INIT( cmissnx )
1627 {
1628 decocass_init_common();
1629 LOG(0,("dongle type #2 (CS82-007)\n"));
1630 decocass_dongle_r = decocass_type2_r;
1631 decocass_dongle_w = decocass_type2_w;
1632 }
1633
MACHINE_INIT(cdiscon1)1634 MACHINE_INIT( cdiscon1 )
1635 {
1636 decocass_init_common();
1637 LOG(0,("dongle type #2 (CS82-007)\n"));
1638 decocass_dongle_r = decocass_type2_r;
1639 decocass_dongle_w = decocass_type2_w;
1640 }
1641
MACHINE_INIT(cptennis)1642 MACHINE_INIT( cptennis )
1643 {
1644 decocass_init_common();
1645 LOG(0,("dongle type #2 (CS82-007)\n"));
1646 decocass_dongle_r = decocass_type2_r;
1647 decocass_dongle_w = decocass_type2_w;
1648 }
1649
MACHINE_INIT(ctornado)1650 MACHINE_INIT( ctornado )
1651 {
1652 decocass_init_common();
1653 LOG(0,("dongle type #2 (CS82-007)\n"));
1654 decocass_dongle_r = decocass_type2_r;
1655 decocass_dongle_w = decocass_type2_w;
1656 }
1657
MACHINE_INIT(cbnj)1658 MACHINE_INIT( cbnj )
1659 {
1660 decocass_init_common();
1661 LOG(0,("dongle type #3 (PAL)\n"));
1662 decocass_dongle_r = decocass_type3_r;
1663 decocass_dongle_w = decocass_type3_w;
1664 type3_swap = TYPE3_SWAP_67;
1665 }
1666
MACHINE_INIT(cburnrub)1667 MACHINE_INIT( cburnrub )
1668 {
1669 decocass_init_common();
1670 LOG(0,("dongle type #3 (PAL)\n"));
1671 decocass_dongle_r = decocass_type3_r;
1672 decocass_dongle_w = decocass_type3_w;
1673 type3_swap = TYPE3_SWAP_67;
1674 }
1675
MACHINE_INIT(cbtime)1676 MACHINE_INIT( cbtime )
1677 {
1678 decocass_init_common();
1679 LOG(0,("dongle type #3 (PAL)\n"));
1680 decocass_dongle_r = decocass_type3_r;
1681 decocass_dongle_w = decocass_type3_w;
1682 type3_swap = TYPE3_SWAP_12;
1683 }
1684
MACHINE_INIT(cgraplop)1685 MACHINE_INIT( cgraplop )
1686 {
1687 decocass_init_common();
1688 LOG(0,("dongle type #3 (PAL)\n"));
1689 decocass_dongle_r = decocass_type3_r;
1690 decocass_dongle_w = decocass_type3_w;
1691 type3_swap = TYPE3_SWAP_56;
1692 }
1693
MACHINE_INIT(clapapa)1694 MACHINE_INIT( clapapa )
1695 {
1696 decocass_init_common();
1697 LOG(0,("dongle type #3 (PAL)\n"));
1698 decocass_dongle_r = decocass_type3_r;
1699 decocass_dongle_w = decocass_type3_w;
1700 type3_swap = TYPE3_SWAP_34_7;
1701 }
1702
MACHINE_INIT(cfghtice)1703 MACHINE_INIT( cfghtice )
1704 {
1705 decocass_init_common();
1706 LOG(0,("dongle type #3 (PAL)\n"));
1707 decocass_dongle_r = decocass_type3_r;
1708 decocass_dongle_w = decocass_type3_w;
1709 type3_swap = TYPE3_SWAP_25;
1710 }
1711
MACHINE_INIT(cprobowl)1712 MACHINE_INIT( cprobowl )
1713 {
1714 decocass_init_common();
1715 LOG(0,("dongle type #3 (PAL)\n"));
1716 decocass_dongle_r = decocass_type3_r;
1717 decocass_dongle_w = decocass_type3_w;
1718 type3_swap = TYPE3_SWAP_34_0;
1719 }
1720
MACHINE_INIT(cnightst)1721 MACHINE_INIT( cnightst )
1722 {
1723 decocass_init_common();
1724 LOG(0,("dongle type #3 (PAL)\n"));
1725 decocass_dongle_r = decocass_type3_r;
1726 decocass_dongle_w = decocass_type3_w;
1727 type3_swap = TYPE3_SWAP_13;
1728 }
1729
MACHINE_INIT(cprosocc)1730 MACHINE_INIT( cprosocc )
1731 {
1732 decocass_init_common();
1733 LOG(0,("dongle type #3 (PAL)\n"));
1734 decocass_dongle_r = decocass_type3_r;
1735 decocass_dongle_w = decocass_type3_w;
1736 type3_swap = TYPE3_SWAP_24;
1737 }
1738
MACHINE_INIT(cppicf)1739 MACHINE_INIT( cppicf )
1740 {
1741 decocass_init_common();
1742 LOG(0,("dongle type #3 (PAL)\n"));
1743 decocass_dongle_r = decocass_type3_r;
1744 decocass_dongle_w = decocass_type3_w;
1745 type3_swap = TYPE3_SWAP_01;
1746 }
1747
MACHINE_INIT(cscrtry)1748 MACHINE_INIT( cscrtry )
1749 {
1750 decocass_init_common();
1751 LOG(0,("dongle type #4 (32K ROM)\n"));
1752 decocass_dongle_r = decocass_type4_r;
1753 decocass_dongle_w = decocass_type4_w;
1754 }
1755
MACHINE_INIT(cbdash)1756 MACHINE_INIT( cbdash )
1757 {
1758 decocass_init_common();
1759 LOG(0,("dongle type #5 (NOP)\n"));
1760 decocass_dongle_r = decocass_type5_r;
1761 decocass_dongle_w = decocass_type5_w;
1762 }
1763
1764 /***************************************************************************
1765 *
1766 * 8041 port handlers
1767 *
1768 ***************************************************************************/
1769
tape_stop(void)1770 static void tape_stop(void)
1771 {
1772 /* remember time */
1773 tape_time0 += tape_dir * timer_timeelapsed(tape_timer);
1774 timer_adjust(tape_timer, TIME_NEVER, 0, 0);
1775 }
1776
1777
WRITE_HANDLER(i8041_p1_w)1778 WRITE_HANDLER( i8041_p1_w )
1779 {
1780 static int i8041_p1_old;
1781
1782 if (data != i8041_p1_old)
1783 {
1784 LOG(4,("%9.7f 8041-PC: %03x i8041_p1_w: $%02x (%s%s%s%s%s%s%s%s)\n",
1785 timer_get_time(),
1786 activecpu_get_previouspc(),
1787 data,
1788 data & 0x01 ? "" : "DATA-WRT",
1789 data & 0x02 ? "" : " DATA-CLK",
1790 data & 0x04 ? "" : " FAST",
1791 data & 0x08 ? "" : " BIT3",
1792 data & 0x10 ? "" : " REW",
1793 data & 0x20 ? "" : " FWD",
1794 data & 0x40 ? "" : " WREN",
1795 data & 0x80 ? "" : " REQ"));
1796 i8041_p1_old = data;
1797 }
1798
1799 /* change in REW signal ? */
1800 if ((data ^ i8041_p1) & 0x10)
1801 {
1802 tape_stop();
1803 if (0 == (data & 0x10))
1804 {
1805 LOG(2,("tape %5.4fs: rewind\n", tape_time0));
1806 tape_dir = -1;
1807 timer_adjust(tape_timer, TIME_NEVER, 0, 0);
1808 set_led_status(0, 1);
1809 }
1810 else
1811 {
1812 tape_dir = 0;
1813 tape_speed = 0;
1814 LOG(2,("tape %5.4fs: stopped\n", tape_time0));
1815 #if TAPE_UI_DISPLAY
1816 usrintf_showmessage(" [%05.1fs] ", tape_time0);
1817 #endif
1818 set_led_status(0, 0);
1819 }
1820 }
1821
1822 /* change in FWD signal ? */
1823 if ((data ^ i8041_p1) & 0x20)
1824 {
1825 tape_stop();
1826 if (0 == (data & 0x20))
1827 {
1828 LOG(2,("tape %5.4fs: forward\n", tape_time0));
1829 tape_dir = +1;
1830 timer_adjust(tape_timer, TIME_NEVER, 0, 0);
1831 set_led_status(0, 1);
1832 }
1833 else
1834 {
1835 tape_dir = 0;
1836 tape_speed = 0;
1837 LOG(2,("tape %5.4fs: stopped\n", tape_time0));
1838 #if TAPE_UI_DISPLAY
1839 usrintf_showmessage(" [%05.1fs] ", tape_time0);
1840 #endif
1841 set_led_status(0, 0);
1842 }
1843 }
1844
1845 /* change in FAST signal ? */
1846 if (tape_timer && (data ^ i8041_p1) & 0x04)
1847 {
1848 tape_stop();
1849 tape_speed = (0 == (data & 0x04)) ? 1 : 0;
1850
1851 if (tape_dir < 0)
1852 {
1853 LOG(2,("tape: fast rewind %s\n", (0 == (data & 0x04)) ? "on" : "off"));
1854 tape_dir = (tape_speed) ? -7 : -1;
1855 timer_adjust(tape_timer, TIME_NEVER, 0, 0);
1856 }
1857 else
1858 if (tape_dir > 0)
1859 {
1860 LOG(2,("tape: fast forward %s\n", (0 == (data & 0x04)) ? "on" : "off"));
1861 tape_dir = (tape_speed) ? +7 : +1;
1862 timer_adjust(tape_timer, TIME_NEVER, 0, 0);
1863 }
1864 }
1865
1866 i8041_p1 = data;
1867 }
1868
READ_HANDLER(i8041_p1_r)1869 READ_HANDLER( i8041_p1_r )
1870 {
1871 data8_t data = i8041_p1;
1872 static int i8041_p1_old;
1873
1874 if (data != i8041_p1_old)
1875 {
1876 LOG(4,("%9.7f 8041-PC: %03x i8041_p1_r: $%02x (%s%s%s%s%s%s%s%s)\n",
1877 timer_get_time(),
1878 activecpu_get_previouspc(),
1879 data,
1880 data & 0x01 ? "" : "DATA-WRT",
1881 data & 0x02 ? "" : " DATA-CLK",
1882 data & 0x04 ? "" : " FAST",
1883 data & 0x08 ? "" : " BIT3",
1884 data & 0x10 ? "" : " REW",
1885 data & 0x20 ? "" : " FWD",
1886 data & 0x40 ? "" : " WREN",
1887 data & 0x80 ? "" : " REQ"));
1888 i8041_p1_old = data;
1889 }
1890 return data;
1891 }
1892
WRITE_HANDLER(i8041_p2_w)1893 WRITE_HANDLER( i8041_p2_w )
1894 {
1895 static int i8041_p2_old;
1896
1897 if (data != i8041_p2_old)
1898 {
1899 LOG(4,("%9.7f 8041-PC: %03x i8041_p2_w: $%02x (%s%s%s%s%s%s%s%s)\n",
1900 timer_get_time(),
1901 activecpu_get_previouspc(),
1902 data,
1903 data & 0x01 ? "" : "FNO/",
1904 data & 0x02 ? "" : " EOT/",
1905 data & 0x04 ? "" : " ERR/",
1906 data & 0x08 ? "" : " OUT3?/",
1907 data & 0x10 ? " [IN4]" : "",
1908 data & 0x20 ? " [BOT-EOT]" : "",
1909 data & 0x40 ? " [RCLK]" : "",
1910 data & 0x80 ? " [RDATA]" : ""));
1911 i8041_p2_old = data;
1912 }
1913 i8041_p2 = data;
1914 }
1915
READ_HANDLER(i8041_p2_r)1916 READ_HANDLER( i8041_p2_r )
1917 {
1918 data8_t data;
1919 static int i8041_p2_old;
1920
1921 tape_update();
1922
1923 data = i8041_p2;
1924
1925 if (data != i8041_p2_old)
1926 {
1927 LOG(4,("%9.7f 8041-PC: %03x i8041_p2_r: $%02x (%s%s%s%s%s%s%s%s)\n",
1928 timer_get_time(),
1929 activecpu_get_previouspc(),
1930 data,
1931 data & 0x01 ? "" : "FNO/",
1932 data & 0x02 ? "" : " EOT/",
1933 data & 0x04 ? "" : " ERR/",
1934 data & 0x08 ? "" : " OUT3?/",
1935 data & 0x10 ? " [IN4]" : "",
1936 data & 0x20 ? " [BOT-EOT]" : "",
1937 data & 0x40 ? " [RCLK]" : "",
1938 data & 0x80 ? " [RDATA]" : ""));
1939 i8041_p2_old = data;
1940 }
1941 return data;
1942 }
1943
1944
1945