diff options
Diffstat (limited to 'src/mess/machine/cbm.c')
-rw-r--r-- | src/mess/machine/cbm.c | 359 |
1 files changed, 359 insertions, 0 deletions
diff --git a/src/mess/machine/cbm.c b/src/mess/machine/cbm.c new file mode 100644 index 00000000000..a5f85443c2b --- /dev/null +++ b/src/mess/machine/cbm.c @@ -0,0 +1,359 @@ +#include "emu.h" +#include "imagedev/cassette.h" +#include "crsshair.h" +#include "includes/cbm.h" +#include "formats/cbm_tap.h" + + +/*********************************************** + + Input Reading - Common Components + +***********************************************/ + +/* These are needed by c64, c65 and c128, each machine has also additional specific +components in its INTERRUPT_GEN */ + +/* keyboard lines */ +UINT8 c64_keyline[10]; + +void cbm_common_init(void) +{ + int i; + + for (i = 0; i < ARRAY_LENGTH(c64_keyline); i++) + c64_keyline[i] = 0xff; +} + +static TIMER_CALLBACK( lightpen_tick ) +{ + if (((machine.root_device().ioport("CTRLSEL")->read() & 0x07) == 0x04) || ((machine.root_device().ioport("CTRLSEL")->read() & 0x07) == 0x06)) + { + /* enable lightpen crosshair */ + crosshair_set_screen(machine, 0, CROSSHAIR_SCREEN_ALL); + } + else + { + /* disable lightpen crosshair */ + crosshair_set_screen(machine, 0, CROSSHAIR_SCREEN_NONE); + } +} + +void cbm_common_interrupt( device_t *device ) +{ + int value, i; + int controller1 = device->machine().root_device().ioport("CTRLSEL")->read() & 0x07; + int controller2 = device->machine().root_device().ioport("CTRLSEL")->read() & 0x70; + static const char *const c64ports[] = { "ROW0", "ROW1", "ROW2", "ROW3", "ROW4", "ROW5", "ROW6", "ROW7" }; + + /* Lines 0-7 : common keyboard */ + for (i = 0; i < 8; i++) + { + value = 0xff; + value &= ~device->machine().root_device().ioport(c64ports[i])->read(); + + /* Shift Lock is mapped on Left Shift */ + if ((i == 1) && (device->machine().root_device().ioport("SPECIAL")->read() & 0x40)) + value &= ~0x80; + + c64_keyline[i] = value; + } + + + value = 0xff; + switch(controller1) + { + case 0x00: + value &= ~device->machine().root_device().ioport("JOY1_1B")->read(); /* Joy1 Directions + Button 1 */ + break; + + case 0x01: + if (device->machine().root_device().ioport("OTHER")->read() & 0x40) /* Paddle2 Button */ + value &= ~0x08; + if (device->machine().root_device().ioport("OTHER")->read() & 0x80) /* Paddle1 Button */ + value &= ~0x04; + break; + + case 0x02: + if (device->machine().root_device().ioport("OTHER")->read() & 0x02) /* Mouse Button Left */ + value &= ~0x10; + if (device->machine().root_device().ioport("OTHER")->read() & 0x01) /* Mouse Button Right */ + value &= ~0x01; + break; + + case 0x03: + value &= ~(device->machine().root_device().ioport("JOY1_2B")->read() & 0x1f); /* Joy1 Directions + Button 1 */ + break; + + case 0x04: +/* was there any input on the lightpen? where is it mapped? */ +// if (device->machine().root_device().ioport("OTHER")->read() & 0x04) /* Lightpen Signal */ +// value &= ?? ; + break; + + case 0x07: + break; + + default: + logerror("Invalid Controller 1 Setting %d\n", controller1); + break; + } + + c64_keyline[8] = value; + + + value = 0xff; + switch(controller2) + { + case 0x00: + value &= ~device->machine().root_device().ioport("JOY2_1B")->read(); /* Joy2 Directions + Button 1 */ + break; + + case 0x10: + if (device->machine().root_device().ioport("OTHER")->read() & 0x10) /* Paddle4 Button */ + value &= ~0x08; + if (device->machine().root_device().ioport("OTHER")->read() & 0x20) /* Paddle3 Button */ + value &= ~0x04; + break; + + case 0x20: + if (device->machine().root_device().ioport("OTHER")->read() & 0x02) /* Mouse Button Left */ + value &= ~0x10; + if (device->machine().root_device().ioport("OTHER")->read() & 0x01) /* Mouse Button Right */ + value &= ~0x01; + break; + + case 0x30: + value &= ~(device->machine().root_device().ioport("JOY2_2B")->read() & 0x1f); /* Joy2 Directions + Button 1 */ + break; + + case 0x40: +/* was there any input on the lightpen? where is it mapped? */ +// if (device->machine().root_device().ioport("OTHER")->read() & 0x04) /* Lightpen Signal */ +// value &= ?? ; + break; + + case 0x70: + break; + + default: + logerror("Invalid Controller 2 Setting %d\n", controller2); + break; + } + + c64_keyline[9] = value; + +// vic2_frame_interrupt does nothing so this is not necessary +// vic2_frame_interrupt (device); + + /* check if lightpen has been chosen as input: if so, enable crosshair */ + device->machine().scheduler().timer_set(attotime::zero, FUNC(lightpen_tick)); + + set_led_status (device->machine(), 1, device->machine().root_device().ioport("SPECIAL")->read() & 0x40 ? 1 : 0); /* Shift Lock */ + set_led_status (device->machine(), 0, device->machine().root_device().ioport("CTRLSEL")->read() & 0x80 ? 1 : 0); /* Joystick Swap */ +} + + +/*********************************************** + + CIA Common Handlers + +***********************************************/ + +/* These are shared by c64, c65 and c128. c65 and c128 also have additional specific +components (to select/read additional keyboard lines) */ + +/* + * CIA 0 - Port A + * bits 7-0 keyboard line select + * bits 7,6: paddle select( 01 port a, 10 port b) + * bit 4: joystick a fire button + * bits 3,2: Paddles port a fire button + * bits 3-0: joystick a direction + * + * CIA 0 - Port B + * bits 7-0: keyboard raw values + * bit 4: joystick b fire button, lightpen select + * bits 3,2: paddle b fire buttons (left,right) + * bits 3-0: joystick b direction + * + * flag cassette read input, serial request in + * irq to irq connected + */ + +UINT8 cbm_common_cia0_port_a_r( device_t *device, UINT8 output_b ) +{ + UINT8 value = 0xff; + + if (!(output_b & 0x80)) + { + UINT8 t = 0xff; + if (!(c64_keyline[7] & 0x80)) t &= ~0x80; + if (!(c64_keyline[6] & 0x80)) t &= ~0x40; + if (!(c64_keyline[5] & 0x80)) t &= ~0x20; + if (!(c64_keyline[4] & 0x80)) t &= ~0x10; + if (!(c64_keyline[3] & 0x80)) t &= ~0x08; + if (!(c64_keyline[2] & 0x80)) t &= ~0x04; + if (!(c64_keyline[1] & 0x80)) t &= ~0x02; + if (!(c64_keyline[0] & 0x80)) t &= ~0x01; + value &= t; + } + + if (!(output_b & 0x40)) + { + UINT8 t = 0xff; + if (!(c64_keyline[7] & 0x40)) t &= ~0x80; + if (!(c64_keyline[6] & 0x40)) t &= ~0x40; + if (!(c64_keyline[5] & 0x40)) t &= ~0x20; + if (!(c64_keyline[4] & 0x40)) t &= ~0x10; + if (!(c64_keyline[3] & 0x40)) t &= ~0x08; + if (!(c64_keyline[2] & 0x40)) t &= ~0x04; + if (!(c64_keyline[1] & 0x40)) t &= ~0x02; + if (!(c64_keyline[0] & 0x40)) t &= ~0x01; + value &= t; + } + + if (!(output_b & 0x20)) + { + UINT8 t = 0xff; + if (!(c64_keyline[7] & 0x20)) t &= ~0x80; + if (!(c64_keyline[6] & 0x20)) t &= ~0x40; + if (!(c64_keyline[5] & 0x20)) t &= ~0x20; + if (!(c64_keyline[4] & 0x20)) t &= ~0x10; + if (!(c64_keyline[3] & 0x20)) t &= ~0x08; + if (!(c64_keyline[2] & 0x20)) t &= ~0x04; + if (!(c64_keyline[1] & 0x20)) t &= ~0x02; + if (!(c64_keyline[0] & 0x20)) t &= ~0x01; + value &= t; + } + + if (!(output_b & 0x10)) + { + UINT8 t = 0xff; + if (!(c64_keyline[7] & 0x10)) t &= ~0x80; + if (!(c64_keyline[6] & 0x10)) t &= ~0x40; + if (!(c64_keyline[5] & 0x10)) t &= ~0x20; + if (!(c64_keyline[4] & 0x10)) t &= ~0x10; + if (!(c64_keyline[3] & 0x10)) t &= ~0x08; + if (!(c64_keyline[2] & 0x10)) t &= ~0x04; + if (!(c64_keyline[1] & 0x10)) t &= ~0x02; + if (!(c64_keyline[0] & 0x10)) t &= ~0x01; + value &= t; + } + + if (!(output_b & 0x08)) + { + UINT8 t = 0xff; + if (!(c64_keyline[7] & 0x08)) t &= ~0x80; + if (!(c64_keyline[6] & 0x08)) t &= ~0x40; + if (!(c64_keyline[5] & 0x08)) t &= ~0x20; + if (!(c64_keyline[4] & 0x08)) t &= ~0x10; + if (!(c64_keyline[3] & 0x08)) t &= ~0x08; + if (!(c64_keyline[2] & 0x08)) t &= ~0x04; + if (!(c64_keyline[1] & 0x08)) t &= ~0x02; + if (!(c64_keyline[0] & 0x08)) t &= ~0x01; + value &= t; + } + + if (!(output_b & 0x04)) + { + UINT8 t = 0xff; + if (!(c64_keyline[7] & 0x04)) t &= ~0x80; + if (!(c64_keyline[6] & 0x04)) t &= ~0x40; + if (!(c64_keyline[5] & 0x04)) t &= ~0x20; + if (!(c64_keyline[4] & 0x04)) t &= ~0x10; + if (!(c64_keyline[3] & 0x04)) t &= ~0x08; + if (!(c64_keyline[2] & 0x04)) t &= ~0x04; + if (!(c64_keyline[1] & 0x04)) t &= ~0x02; + if (!(c64_keyline[0] & 0x04)) t &= ~0x01; + value &= t; + } + + if (!(output_b & 0x02)) + { + UINT8 t = 0xff; + if (!(c64_keyline[7] & 0x02)) t &= ~0x80; + if (!(c64_keyline[6] & 0x02)) t &= ~0x40; + if (!(c64_keyline[5] & 0x02)) t &= ~0x20; + if (!(c64_keyline[4] & 0x02)) t &= ~0x10; + if (!(c64_keyline[3] & 0x02)) t &= ~0x08; + if (!(c64_keyline[2] & 0x02)) t &= ~0x04; + if (!(c64_keyline[1] & 0x02)) t &= ~0x02; + if (!(c64_keyline[0] & 0x02)) t &= ~0x01; + value &= t; + } + + if (!(output_b & 0x01)) + { + UINT8 t = 0xff; + if (!(c64_keyline[7] & 0x01)) t &= ~0x80; + if (!(c64_keyline[6] & 0x01)) t &= ~0x40; + if (!(c64_keyline[5] & 0x01)) t &= ~0x20; + if (!(c64_keyline[4] & 0x01)) t &= ~0x10; + if (!(c64_keyline[3] & 0x01)) t &= ~0x08; + if (!(c64_keyline[2] & 0x01)) t &= ~0x04; + if (!(c64_keyline[1] & 0x01)) t &= ~0x02; + if (!(c64_keyline[0] & 0x01)) t &= ~0x01; + value &= t; + } + + if ( device->machine().root_device().ioport("CTRLSEL")->read() & 0x80 ) + value &= c64_keyline[8]; + else + value &= c64_keyline[9]; + + return value; +} + +UINT8 cbm_common_cia0_port_b_r( device_t *device, UINT8 output_a ) +{ + UINT8 value = 0xff; + + if (!(output_a & 0x80)) value &= c64_keyline[7]; + if (!(output_a & 0x40)) value &= c64_keyline[6]; + if (!(output_a & 0x20)) value &= c64_keyline[5]; + if (!(output_a & 0x10)) value &= c64_keyline[4]; + if (!(output_a & 0x08)) value &= c64_keyline[3]; + if (!(output_a & 0x04)) value &= c64_keyline[2]; + if (!(output_a & 0x02)) value &= c64_keyline[1]; + if (!(output_a & 0x01)) value &= c64_keyline[0]; + + if ( device->machine().root_device().ioport("CTRLSEL")->read() & 0x80 ) + value &= c64_keyline[9]; + else + value &= c64_keyline[8]; + + return value; +} + + +/*********************************************** + + CBM Cartridges + +***********************************************/ + + +/* All the cartridge specific code has been moved + to machine/ drivers. Once more informations + surface about the cart expansions for systems + in c65.c, c128.c, cbmb.c and pet.c, the shared + code could be refactored to have here the + common functions */ + + + +/*********************************************** + + CBM Datasette Tapes + +***********************************************/ + +const cassette_interface cbm_cassette_interface = +{ + cbm_cassette_formats, + NULL, + (cassette_state) (CASSETTE_STOPPED | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED), + NULL, + NULL +}; |