summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/machine/cbm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/machine/cbm.c')
-rw-r--r--src/mess/machine/cbm.c359
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
+};