/***************************************************************************

	coco.c

	TRS-80 Radio Shack Color Computer Family

	Mathis Rosenhauer (original driver)
	Nate Woods (current maintainer)
	Tim Lindner (VHD and other work)

***************************************************************************/

#include "driver.h"
#include "inputx.h"
#include "machine/6821pia.h"
#include "video/m6847.h"
#include "machine/6883sam.h"
#include "includes/coco.h"
#include "devices/basicdsk.h"
#include "includes/6551.h"
#include "formats/coco_dsk.h"
#include "formats/coco_cas.h"
#include "devices/printer.h"
#include "devices/mflopimg.h"
#include "devices/cassette.h"
#include "devices/bitbngr.h"
#include "devices/snapquik.h"
#include "devices/cartslot.h"
#include "devices/coco_vhd.h"
#include "sound/ay8910.h"
#include "coco3.lh"

#define SHOW_FULL_AREA			0
#define JOYSTICK_DELTA			10
#define JOYSTICK_SENSITIVITY	100

static ADDRESS_MAP_START( coco_map, ADDRESS_SPACE_PROGRAM, 8 )
	AM_RANGE(0x0000, 0x0FFF) AM_RAMBANK(1)
	AM_RANGE(0x1000, 0x1FFF) AM_RAMBANK(2)
	AM_RANGE(0x2000, 0x2FFF) AM_RAMBANK(3)
	AM_RANGE(0x3000, 0x3FFF) AM_RAMBANK(4)
	AM_RANGE(0x4000, 0x4FFF) AM_RAMBANK(5)
	AM_RANGE(0x5000, 0x5FFF) AM_RAMBANK(6)
	AM_RANGE(0x6000, 0x6FFF) AM_RAMBANK(7)
	AM_RANGE(0x7000, 0x7FFF) AM_RAMBANK(8)
	AM_RANGE(0x8000, 0x8FFF) AM_RAMBANK(9)
	AM_RANGE(0x9000, 0x9FFF) AM_RAMBANK(10)
	AM_RANGE(0xA000, 0xAFFF) AM_RAMBANK(11)
	AM_RANGE(0xB000, 0xBFFF) AM_RAMBANK(12)
	AM_RANGE(0xC000, 0xCFFF) AM_RAMBANK(13)
	AM_RANGE(0xD000, 0xDFFF) AM_RAMBANK(14)
	AM_RANGE(0xE000, 0xEFFF) AM_RAMBANK(15)
	AM_RANGE(0xF000, 0xFEFF) AM_RAMBANK(16)
	AM_RANGE(0xff00, 0xff1f) AM_READWRITE(pia_0_r,			pia_0_w)
	AM_RANGE(0xff20, 0xff3f) AM_READWRITE(pia_1_r,			coco_pia_1_w)
	AM_RANGE(0xff40, 0xff8f) AM_READWRITE(coco_cartridge_r,	coco_cartridge_w)
	AM_RANGE(0xff90, 0xffbf) AM_NOP
	AM_RANGE(0xffc0, 0xffdf) AM_WRITE(sam_w)
	AM_RANGE(0xffe0, 0xffef) AM_NOP
	AM_RANGE(0xfff0, 0xffff) AM_ROM AM_REGION(REGION_CPU1, 0x3ff0)
ADDRESS_MAP_END



/* Note that the CoCo 3 doesn't use the SAM VDG mode registers
 *
 * Also, there might be other SAM registers that are ignored in the CoCo 3;
 * I am not sure which ones are...
 *
 * Tepolt implies that $FFD4-$FFD7 and $FFDA-$FFDD are ignored on the CoCo 3,
 * which would make sense, but I'm not sure.
 */
static ADDRESS_MAP_START( coco3_map, ADDRESS_SPACE_PROGRAM, 8 )
	AM_RANGE(0x0000, 0x1fff) AM_RAMBANK(1)
	AM_RANGE(0x2000, 0x3fff) AM_RAMBANK(2)
	AM_RANGE(0x4000, 0x5fff) AM_RAMBANK(3)
	AM_RANGE(0x6000, 0x7fff) AM_RAMBANK(4)
	AM_RANGE(0x8000, 0x9fff) AM_RAMBANK(5)
	AM_RANGE(0xa000, 0xbfff) AM_RAMBANK(6)
	AM_RANGE(0xc000, 0xdfff) AM_RAMBANK(7)
	AM_RANGE(0xe000, 0xfdff) AM_RAMBANK(8)
	AM_RANGE(0xfe00, 0xfeff) AM_RAMBANK(9)
	AM_RANGE(0xff00, 0xff1f) AM_READWRITE(pia_0_r,				pia_0_w)
	AM_RANGE(0xff20, 0xff3f) AM_READWRITE(pia_1_r,				coco_pia_1_w)
	AM_RANGE(0xff40, 0xff8f) AM_READWRITE(coco_cartridge_r,		coco_cartridge_w)
	AM_RANGE(0xff90, 0xff9f) AM_READWRITE(coco3_gime_r,			coco3_gime_w)
	AM_RANGE(0xffa0, 0xffaf) AM_READWRITE(coco3_mmu_r,			coco3_mmu_w)
	AM_RANGE(0xffb0, 0xffbf) AM_READWRITE(paletteram_r,			coco3_palette_w)
	AM_RANGE(0xffc0, 0xffdf) AM_WRITE(sam_w)
	AM_RANGE(0xffe0, 0xffef) AM_NOP
	AM_RANGE(0xfff0, 0xffff) AM_ROM AM_REGION(REGION_CPU1, 0x7ff0)
ADDRESS_MAP_END



static ADDRESS_MAP_START( d64_map, ADDRESS_SPACE_PROGRAM, 8 )
	AM_RANGE(0x0000, 0x0FFF) AM_RAMBANK(1)
	AM_RANGE(0x1000, 0x1FFF) AM_RAMBANK(2)
	AM_RANGE(0x2000, 0x2FFF) AM_RAMBANK(3)
	AM_RANGE(0x3000, 0x3FFF) AM_RAMBANK(4)
	AM_RANGE(0x4000, 0x4FFF) AM_RAMBANK(5)
	AM_RANGE(0x5000, 0x5FFF) AM_RAMBANK(6)
	AM_RANGE(0x6000, 0x6FFF) AM_RAMBANK(7)
	AM_RANGE(0x7000, 0x7FFF) AM_RAMBANK(8)
	AM_RANGE(0x8000, 0x8FFF) AM_RAMBANK(9)
	AM_RANGE(0x9000, 0x9FFF) AM_RAMBANK(10)
	AM_RANGE(0xA000, 0xAFFF) AM_RAMBANK(11)
	AM_RANGE(0xB000, 0xBFFF) AM_RAMBANK(12)
	AM_RANGE(0xC000, 0xCFFF) AM_RAMBANK(13)
	AM_RANGE(0xD000, 0xDFFF) AM_RAMBANK(14)
	AM_RANGE(0xE000, 0xEFFF) AM_RAMBANK(15)
	AM_RANGE(0xF000, 0xFEFF) AM_RAMBANK(16)
	AM_RANGE(0xff00, 0xff03) AM_READWRITE(pia_0_r,				pia_0_w)		AM_MIRROR(0x0018)
	AM_RANGE(0xff04, 0xff07) AM_READWRITE(acia_6551_r,			acia_6551_w)	AM_MIRROR(0x0018)
	AM_RANGE(0xff20, 0xff3f) AM_READWRITE(pia_1_r,				coco_pia_1_w)
	AM_RANGE(0xff40, 0xff8f) AM_READWRITE(coco_cartridge_r,		coco_cartridge_w)
	AM_RANGE(0xff90, 0xffbf) AM_NOP
	AM_RANGE(0xffc0, 0xffdf) AM_WRITE(sam_w)
	AM_RANGE(0xffe0, 0xffef) AM_NOP
	AM_RANGE(0xfff0, 0xffff) AM_ROM AM_REGION(REGION_CPU1, 0x3ff0)
ADDRESS_MAP_END

/*
	Dragon 64 with compusense Plus addon, this provided an extra 64K of memory
	and an 80x25 column text display, provided by a motorola 6845.

	Currently only the memory is emulated.
*/

static ADDRESS_MAP_START( d64_plus_map, ADDRESS_SPACE_PROGRAM, 8 )
	AM_RANGE(0x0000, 0x0FFF) AM_RAMBANK(1)
	AM_RANGE(0x1000, 0x1FFF) AM_RAMBANK(2)
	AM_RANGE(0x2000, 0x2FFF) AM_RAMBANK(3)
	AM_RANGE(0x3000, 0x3FFF) AM_RAMBANK(4)
	AM_RANGE(0x4000, 0x4FFF) AM_RAMBANK(5)
	AM_RANGE(0x5000, 0x5FFF) AM_RAMBANK(6)
	AM_RANGE(0x6000, 0x6FFF) AM_RAMBANK(7)
	AM_RANGE(0x7000, 0x7FFF) AM_RAMBANK(8)
	AM_RANGE(0x8000, 0x8FFF) AM_RAMBANK(9)
	AM_RANGE(0x9000, 0x9FFF) AM_RAMBANK(10)
	AM_RANGE(0xA000, 0xAFFF) AM_RAMBANK(11)
	AM_RANGE(0xB000, 0xBFFF) AM_RAMBANK(12)
	AM_RANGE(0xC000, 0xCFFF) AM_RAMBANK(13)
	AM_RANGE(0xD000, 0xDFFF) AM_RAMBANK(14)
	AM_RANGE(0xE000, 0xEFFF) AM_RAMBANK(15)
	AM_RANGE(0xF000, 0xFEFF) AM_RAMBANK(16)
	AM_RANGE(0xff00, 0xff03) AM_READWRITE(pia_0_r,pia_0_w)		AM_MIRROR(0x0018)
	AM_RANGE(0xff04, 0xff07) AM_READWRITE(acia_6551_r,acia_6551_w)	AM_MIRROR(0x0018)
	AM_RANGE(0xff20, 0xff3f) AM_READWRITE(pia_1_r,coco_pia_1_w)
	AM_RANGE(0xff40, 0xff8f) AM_READWRITE(coco_cartridge_r,	coco_cartridge_w)
	AM_RANGE(0xff90, 0xffbf) AM_NOP
	AM_RANGE(0xffc0, 0xffdf) AM_WRITE(sam_w)
	AM_RANGE(0xffe0, 0xffe1) AM_NOP
	AM_RANGE(0xffe2, 0xffe2) AM_READWRITE(plus_reg_r,plus_reg_w)	/* Dragon plus control / status reg */
	AM_RANGE(0xffe3, 0xffef) AM_NOP
	AM_RANGE(0xfff0, 0xffff) AM_ROM AM_REGION(REGION_CPU1,0x3ff0)
ADDRESS_MAP_END

/*
	The Dragon Alpha was a prototype in development when Dragon Data went bust,
	it is basically an enhanced Dragon 64, with built in modem, disk system, and
	graphical boot rom.

	It has the following extra hardware :-
	A third 6821 PIA mapped between FF24 and FF27
		An AY-8912, connected to the PIA.

	Port A of the PIA is connected as follows :-

		b0	BDIR of AY8912
		b1	BC1 of AY8912
		b2 	Rom select, High= boot rom, low=BASIC rom
		b3..7 not used.

	Port B
		b0..7 connected to D0..7 of the AY8912.

	CB1 DRQ of WD2797.

	/irqa
	/irqb	both connected to 6809 FIRQ.


	The analog outputs of the AY-8912 are connected to the standard sound multiplexer.
	The AY8912 output port is used as follows :-

		b0..b3	/DS0../DS3 for the drive interface (through an inverter first).
		b4		/motor for the drive interface (through an inverter first).
		b5..b7	not used as far as I can tell.

	A 6850 for the modem.

	A WD2797, used as an internal disk interface, this is however connected in a slightly strange
	way that I am yet to completely determine.
	19/10/2004, WD2797 is mapped between FF2C and FF2F, however the order of the registers is
	reversed so the command Register is at the highest address instead of the lowest. The Data
	request pin is connected to CB1(pin 18) of PIA2, to cause an firq, the INTRQ, is connected via
	an inverter to the 6809's NMI.

	All these are as yet un-emulated.

	29-Oct-2004, AY-8912 is now emulated.
	30-Oct-2004, Internal disk interface now emulated, Normal DragonDos rom replaced with a re-assembled
				version, that talks to the alpha hardware (verified on a clone of the real machine).
*/


static ADDRESS_MAP_START( dgnalpha_map, ADDRESS_SPACE_PROGRAM, 8 )
	AM_RANGE(0x0000, 0x0FFF) AM_RAMBANK(1)
	AM_RANGE(0x1000, 0x1FFF) AM_RAMBANK(2)
	AM_RANGE(0x2000, 0x2FFF) AM_RAMBANK(3)
	AM_RANGE(0x3000, 0x3FFF) AM_RAMBANK(4)
	AM_RANGE(0x4000, 0x4FFF) AM_RAMBANK(5)
	AM_RANGE(0x5000, 0x5FFF) AM_RAMBANK(6)
	AM_RANGE(0x6000, 0x6FFF) AM_RAMBANK(7)
	AM_RANGE(0x7000, 0x7FFF) AM_RAMBANK(8)
	AM_RANGE(0x8000, 0x8FFF) AM_RAMBANK(9)
	AM_RANGE(0x9000, 0x9FFF) AM_RAMBANK(10)
	AM_RANGE(0xA000, 0xAFFF) AM_RAMBANK(11)
	AM_RANGE(0xB000, 0xBFFF) AM_RAMBANK(12)
	AM_RANGE(0xC000, 0xCFFF) AM_RAMBANK(13)
	AM_RANGE(0xD000, 0xDFFF) AM_RAMBANK(14)
	AM_RANGE(0xE000, 0xEFFF) AM_RAMBANK(15)
	AM_RANGE(0xF000, 0xFEFF) AM_RAMBANK(16)
	AM_RANGE(0xff00, 0xff03) AM_READWRITE(pia_0_r,			pia_0_w)
	AM_RANGE(0xff04, 0xff07) AM_READWRITE(acia_6551_r,		acia_6551_w)
	AM_RANGE(0xff20, 0xff23) AM_READWRITE(pia_1_r,			coco_pia_1_w)
	AM_RANGE(0xff24, 0xff27) AM_READWRITE(pia_2_r,			pia_2_w) 	/* Third PIA on Dragon Alpha */
	AM_RANGE(0xff2c, 0xff2f) AM_READWRITE(wd2797_r,			wd2797_w)	/* Alpha onboard disk interface */
	AM_RANGE(0xff40, 0xff8f) AM_READWRITE(coco_cartridge_r,	coco_cartridge_w)
	AM_RANGE(0xff90, 0xffbf) AM_NOP
	AM_RANGE(0xffc0, 0xffdf) AM_WRITE(sam_w)
	AM_RANGE(0xffe0, 0xffef) AM_NOP
	AM_RANGE(0xfff0, 0xffff) AM_READ(dragon_alpha_mapped_irq_r)
ADDRESS_MAP_END


static INPUT_PORTS_START( coco_joystick )
	PORT_START_TAG("joystick_right_x")
	PORT_BIT( 0xff, 0x80,  IPT_AD_STICK_X) PORT_SENSITIVITY(JOYSTICK_SENSITIVITY) PORT_KEYDELTA(JOYSTICK_DELTA) PORT_MINMAX(0x00,0xFF) PORT_CODE_DEC(KEYCODE_4_PAD) PORT_CODE_INC(KEYCODE_6_PAD) PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH) PORT_PLAYER(1)
	PORT_START_TAG("joystick_right_y")
	PORT_BIT( 0xff, 0x80,  IPT_AD_STICK_Y) PORT_SENSITIVITY(JOYSTICK_SENSITIVITY) PORT_KEYDELTA(JOYSTICK_DELTA) PORT_MINMAX(0x00,0xFF) PORT_CODE_DEC(KEYCODE_8_PAD) PORT_CODE_INC(KEYCODE_2_PAD) PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH)   PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH)  PORT_PLAYER(1)
	PORT_START_TAG("joystick_left_x")
	PORT_BIT( 0xff, 0x80,  IPT_AD_STICK_X) PORT_SENSITIVITY(JOYSTICK_SENSITIVITY) PORT_KEYDELTA(JOYSTICK_DELTA) PORT_MINMAX(0x00,0xFF) PORT_CODE_DEC(KEYCODE_4_PAD) PORT_CODE_INC(KEYCODE_6_PAD) PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH) PORT_PLAYER(2)
	PORT_START_TAG("joystick_left_y")
	PORT_BIT( 0xff, 0x80,  IPT_AD_STICK_Y) PORT_SENSITIVITY(JOYSTICK_SENSITIVITY) PORT_KEYDELTA(JOYSTICK_DELTA) PORT_MINMAX(0x00,0xFF) PORT_CODE_DEC(KEYCODE_8_PAD) PORT_CODE_INC(KEYCODE_2_PAD) PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH)   PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH)  PORT_PLAYER(2)
INPUT_PORTS_END



static INPUT_PORTS_START( coco_joystick_buttons )
	PORT_START_TAG("joystick_buttons")
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Right Button") PORT_CODE(KEYCODE_0_PAD) PORT_CODE(JOYCODE_BUTTON1) PORT_CODE(MOUSECODE_BUTTON1) PORT_PLAYER(1)
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Left Button")  PORT_CODE(KEYCODE_0_PAD) PORT_CODE(JOYCODE_BUTTON1) PORT_CODE(MOUSECODE_BUTTON1) PORT_PLAYER(2)
INPUT_PORTS_END



static INPUT_PORTS_START( coco3_joystick_buttons )
	PORT_START_TAG("joystick_buttons")
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Right Button 1") PORT_CODE(KEYCODE_0_PAD)	PORT_CODE(JOYCODE_BUTTON1) PORT_CODE(MOUSECODE_BUTTON1) PORT_PLAYER(1)
	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_NAME("Right Button 2") PORT_CODE(KEYCODE_DEL_PAD) PORT_CODE(JOYCODE_BUTTON2) PORT_CODE(MOUSECODE_BUTTON2) PORT_PLAYER(1)
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Left Button 1")  PORT_CODE(KEYCODE_0_PAD)	PORT_CODE(JOYCODE_BUTTON1) PORT_CODE(MOUSECODE_BUTTON1) PORT_PLAYER(2)
	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_NAME("Left Button 2")  PORT_CODE(KEYCODE_DEL_PAD)	PORT_CODE(JOYCODE_BUTTON2) PORT_CODE(MOUSECODE_BUTTON2) PORT_PLAYER(2)
INPUT_PORTS_END

static INPUT_PORTS_START( cart_autostart )
	PORT_START_TAG("CARTAUTO")
	PORT_CONFNAME( 0x01, 0x01, "Cart Auto-Start" )
	PORT_CONFSETTING(0x00, DEF_STR( Off ))
	PORT_CONFSETTING(0x01, DEF_STR( On ))
INPUT_PORTS_END

/* Dragon keyboard

	   PB0 PB1 PB2 PB3 PB4 PB5 PB6 PB7
  PA6: Ent Clr Brk N/c N/c N/c N/c Shift
  PA5: X   Y   Z   Up  Dwn Lft Rgt Space
  PA4: P   Q   R   S   T   U   V   W
  PA3: H   I   J   K   L   M   N   O
  PA2: @   A   B   C   D   E   F   G
  PA1: 8   9   :   ;   ,   -   .   /
  PA0: 0   1   2   3   4   5   6   7
 */
static INPUT_PORTS_START( dragon32 )
	PORT_START /* KEY ROW 0 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('\"')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&')
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'')

	PORT_START /* KEY ROW 1 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(':') PORT_CHAR('*')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(';') PORT_CHAR('+')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=')
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')

	PORT_START /* KEY ROW 2 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('@')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E')
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F')
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G')

	PORT_START /* KEY ROW 3 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M')
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N')
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O')

	PORT_START /* KEY ROW 4 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U')
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V')
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W')

	PORT_START /* KEY ROW 5 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("UP") PORT_CODE(KEYCODE_UP) PORT_CHAR('^')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DOWN") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(10)
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LEFT") PORT_CODE(KEYCODE_LEFT) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RIGHT") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(9)
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')

	PORT_START /* KEY ROW 6 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ENTER") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CLEAR") PORT_CODE(KEYCODE_HOME) PORT_CHAR(12)
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BREAK") PORT_CODE(KEYCODE_END) PORT_CODE(KEYCODE_ESC) PORT_CHAR(27)
	PORT_BIT (0x78, IP_ACTIVE_LOW, IPT_UNUSED)
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L-SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R-SHIFT") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)

	PORT_INCLUDE( coco_joystick )
	PORT_INCLUDE( coco_joystick_buttons )
	PORT_INCLUDE( m6847_artifacting )

	PORT_INCLUDE( cart_autostart )
INPUT_PORTS_END

/* CoCo keyboard

	   PB0 PB1 PB2 PB3 PB4 PB5 PB6 PB7
  PA6: Ent Clr Brk N/c N/c N/c N/c Shift
  PA5: 8   9   :   ;   ,   -   .   /
  PA4: 0   1   2   3   4   5   6   7
  PA3: X   Y   Z   Up  Dwn Lft Rgt Space
  PA2: P   Q   R   S   T   U   V   W
  PA1: H   I   J   K   L   M   N   O
  PA0: @   A   B   C   D   E   F   G
 */
static INPUT_PORTS_START( coco )
	PORT_START /* KEY ROW 0 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('@')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E')
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F')
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G')

	PORT_START /* KEY ROW 1 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M')
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N')
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O')

	PORT_START /* KEY ROW 2 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U')
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V')
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W')

	PORT_START /* KEY ROW 3 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("UP") PORT_CODE(KEYCODE_UP) PORT_CHAR('^')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DOWN") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(10)
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LEFT") PORT_CODE(KEYCODE_LEFT) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RIGHT") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(9)
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')

	PORT_START /* KEY ROW 4 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('\"')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&')
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'')

	PORT_START /* KEY ROW 5 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(':') PORT_CHAR('*')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(';') PORT_CHAR('+')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=')
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')

	PORT_START /* KEY ROW 6 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ENTER") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CLEAR") PORT_CODE(KEYCODE_HOME) PORT_CHAR(12)
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BREAK") PORT_CODE(KEYCODE_END) PORT_CODE(KEYCODE_ESC) PORT_CHAR(27)
	PORT_BIT(0x78, IP_ACTIVE_LOW, IPT_UNUSED)
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L-SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R-SHIFT") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)

	PORT_INCLUDE( coco_joystick )
	PORT_INCLUDE( coco_joystick_buttons )
	PORT_INCLUDE( m6847_artifacting )

	PORT_START /* 13 */
	PORT_CONFNAME( 0x03, 0x00, "Real Time Clock" )
	PORT_CONFSETTING(    0x00, "Disto" )
	PORT_CONFSETTING(    0x01, "Cloud-9" )

	PORT_INCLUDE( cart_autostart )
INPUT_PORTS_END

/* CoCo 3 keyboard

	   PB0 PB1 PB2 PB3 PB4 PB5 PB6 PB7
  PA6: Ent Clr Brk Alt Ctr F1  F2 Shift
  PA5: 8   9   :   ;   ,   -   .   /
  PA4: 0   1   2   3   4   5   6   7
  PA3: X   Y   Z   Up  Dwn Lft Rgt Space
  PA2: P   Q   R   S   T   U   V   W
  PA1: H   I   J   K   L   M   N   O
  PA0: @   A   B   C   D   E   F   G
 */
static INPUT_PORTS_START( coco3 )
	PORT_START /* KEY ROW 0 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('@')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E')
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F')
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G')

	PORT_START /* KEY ROW 1 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M')
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N')
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O')

	PORT_START /* KEY ROW 2 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U')
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V')
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W')

	PORT_START /* KEY ROW 3 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("UP") PORT_CODE(KEYCODE_UP) PORT_CHAR('^')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DOWN") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(10)
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LEFT") PORT_CODE(KEYCODE_LEFT) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RIGHT") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(9)
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')

	PORT_START /* KEY ROW 4 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('\"')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&')
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'')

	PORT_START /* KEY ROW 5 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(':') PORT_CHAR('*')
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(';') PORT_CHAR('+')
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=') PORT_CHAR('_')
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')

	PORT_START /* KEY ROW 6 */
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ENTER") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CLEAR") PORT_CODE(KEYCODE_HOME) PORT_CHAR(12)
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BREAK") PORT_CODE(KEYCODE_END) PORT_CODE(KEYCODE_ESC) PORT_CHAR(27)
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ALT") PORT_CODE(KEYCODE_LALT)
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2)
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1))
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2))
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L-SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R-SHIFT") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)

	PORT_INCLUDE( coco_joystick )
	PORT_INCLUDE( coco3_joystick_buttons )
	PORT_INCLUDE( m6847_artifacting )

	PORT_START_TAG("joystick_mode")
	PORT_CONFNAME( 0x70, 0x00, "Joystick Type" )
	PORT_CONFSETTING(	0x00, DEF_STR( Normal ) )
	PORT_CONFSETTING(	0x10, "Hi-Res Interface" )
	PORT_CONFSETTING(	0x30, "Hi-Res Interface (CoCoMax 3 Style)" )
	PORT_CONFSETTING(	0x20, "The Rat Graphics Mouse" )
	PORT_CONFSETTING(	0x40, "Diecom Light Gun Adaptor" )

	PORT_START_TAG("real_time_clock")
	PORT_CONFNAME( 0x03, 0x00, "Real Time Clock" )
	PORT_CONFSETTING(    0x00, "Disto" )
	PORT_CONFSETTING(    0x01, "Cloud-9" )

	PORT_START_TAG("rat_mouse_x")
	PORT_BIT( 0x03, 0x00,  IPT_MOUSE_X) PORT_NAME("Rat Mouse X") PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_CODE_DEC(KEYCODE_LEFT) PORT_CODE_INC(KEYCODE_RIGHT) PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH) PORT_PLAYER(1)
	PORT_START_TAG("rat_mouse_y")
	PORT_BIT( 0x03, 0x00,  IPT_MOUSE_Y) PORT_NAME("Rat Mouse Y") PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_CODE_DEC(KEYCODE_UP) PORT_CODE_INC(KEYCODE_DOWN) PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH) PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH) PORT_PLAYER(1)

	PORT_START_TAG("dclg_x")
	PORT_BIT( 0x1ff, 266, IPT_LIGHTGUN_X ) PORT_NAME("Lightgun X") PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_MINMAX(116,416) PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_PLAYER(1)
	PORT_START_TAG("dclg_y")
	PORT_BIT( 0xff, 121, IPT_LIGHTGUN_Y ) PORT_NAME("Lightgun Y") PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_MINMAX(0,242) PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_PLAYER(1)

	PORT_INCLUDE( cart_autostart )
INPUT_PORTS_END

/* AY-8912 for Dragon Alpha, the AY-8912 simply an AY-8910 with only one io port. */
static const struct AY8910interface ay8912_interface =
{
	dgnalpha_psg_porta_read,	/* portA read */
	NULL,    					/* portB read */
	dgnalpha_psg_porta_write,	/* portA write */
	NULL						/* portB write */
};


static MACHINE_DRIVER_START( coco_sound )
	MDRV_SPEAKER_STANDARD_MONO("mono")
	MDRV_SOUND_ADD(DAC, 0)
	MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
	MDRV_SOUND_ADD(WAVE, 0)
	MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
MACHINE_DRIVER_END

static MACHINE_DRIVER_START( dragon32 )
	/* basic machine hardware */
	MDRV_CPU_ADD_TAG("main", M6809E, COCO_CPU_SPEED_HZ)        /* 0,894886 Mhz */
	MDRV_CPU_PROGRAM_MAP(coco_map, 0)
	MDRV_SCREEN_REFRESH_RATE(M6847_PAL_FRAMES_PER_SECOND)

	MDRV_MACHINE_START( dragon32 )

	/* video hardware */
	MDRV_VIDEO_START(dragon)
	MDRV_VIDEO_UPDATE(m6847)
	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
	MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
	MDRV_SCREEN_SIZE(320, 25+192+26)
	MDRV_SCREEN_VISIBLE_AREA(0, 319, 1, 239)

	/* sound hardware */
	MDRV_IMPORT_FROM( coco_sound )
MACHINE_DRIVER_END

static MACHINE_DRIVER_START( dragon64 )
	/* basic machine hardware */
	MDRV_CPU_ADD_TAG("main", M6809E, COCO_CPU_SPEED_HZ)        /* 0,894886 Mhz */
	MDRV_CPU_PROGRAM_MAP(d64_map, 0)
	MDRV_SCREEN_REFRESH_RATE(M6847_PAL_FRAMES_PER_SECOND)

	MDRV_MACHINE_START( dragon64 )

	/* video hardware */
	MDRV_VIDEO_START(dragon)
	MDRV_VIDEO_UPDATE(m6847)
	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
	MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
	MDRV_SCREEN_SIZE(320, 25+192+26)
	MDRV_SCREEN_VISIBLE_AREA(0, 319, 1, 239)

	/* sound hardware */
	MDRV_IMPORT_FROM( coco_sound )
MACHINE_DRIVER_END

static MACHINE_DRIVER_START( d64plus )
	/* basic machine hardware */
	MDRV_CPU_ADD_TAG("main", M6809E, COCO_CPU_SPEED_HZ)        /* 0,894886 Mhz */
	MDRV_CPU_PROGRAM_MAP(d64_plus_map, 0)
	MDRV_SCREEN_REFRESH_RATE(M6847_PAL_FRAMES_PER_SECOND)

	MDRV_MACHINE_START( dragon64 )

	/* video hardware */
	MDRV_VIDEO_START(dragon)
	MDRV_VIDEO_UPDATE(m6847)
	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
	MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
	MDRV_SCREEN_SIZE(320, 25+192+26)
	MDRV_SCREEN_VISIBLE_AREA(0, 319, 1, 239)

	/* sound hardware */
	MDRV_IMPORT_FROM( coco_sound )
MACHINE_DRIVER_END

static MACHINE_DRIVER_START( dgnalpha )
	/* basic machine hardware */
	MDRV_CPU_ADD_TAG("main", M6809E, COCO_CPU_SPEED_HZ)        /* 0,894886 Mhz */
	MDRV_CPU_PROGRAM_MAP(dgnalpha_map, 0)
	MDRV_SCREEN_REFRESH_RATE(M6847_PAL_FRAMES_PER_SECOND)

	MDRV_MACHINE_START( dgnalpha )

	/* video hardware */
	MDRV_VIDEO_START(dragon)
	MDRV_VIDEO_UPDATE(m6847)
	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
	MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
	MDRV_SCREEN_SIZE(320, 25+192+26)
	MDRV_SCREEN_VISIBLE_AREA(0, 319, 1, 239)

	/* sound hardware */
	MDRV_IMPORT_FROM( coco_sound )
	MDRV_SOUND_ADD(AY8910, 1000000)
	MDRV_SOUND_CONFIG(ay8912_interface)
	MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
MACHINE_DRIVER_END

static MACHINE_DRIVER_START( tanodr64 )
	/* basic machine hardware */
	MDRV_CPU_ADD_TAG("main", M6809E, COCO_CPU_SPEED_HZ)        /* 0,894886 Mhz */
	MDRV_CPU_PROGRAM_MAP(d64_map, 0)
	MDRV_SCREEN_REFRESH_RATE(COCO_FRAMES_PER_SECOND)			/* Tano Dragon 64 is NTSC */

	MDRV_MACHINE_START( tanodr64 )

	/* video hardware */
	MDRV_VIDEO_START(dragon)
	MDRV_VIDEO_UPDATE(m6847)
	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
	MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
	MDRV_SCREEN_SIZE(320, 25+192+26)
	MDRV_SCREEN_VISIBLE_AREA(0, 319, 1, 239)

	/* sound hardware */
	MDRV_IMPORT_FROM( coco_sound )
MACHINE_DRIVER_END

static MACHINE_DRIVER_START( coco )
	/* basic machine hardware */
	MDRV_CPU_ADD_TAG("main", M6809E, COCO_CPU_SPEED_HZ)        /* 0,894886 Mhz */
	MDRV_CPU_PROGRAM_MAP(coco_map, 0)
	MDRV_SCREEN_REFRESH_RATE(M6847_NTSC_FRAMES_PER_SECOND)

	MDRV_MACHINE_START( coco )

	/* video hardware */
	MDRV_VIDEO_START(coco)
	MDRV_VIDEO_UPDATE(m6847)
	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
	MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
	MDRV_SCREEN_SIZE(320, 25+192+26)
	MDRV_SCREEN_VISIBLE_AREA(0, 319, 1, 239)

	/* sound hardware */
	MDRV_IMPORT_FROM( coco_sound )
MACHINE_DRIVER_END

static MACHINE_DRIVER_START( coco2 )
	/* basic machine hardware */
	MDRV_CPU_ADD_TAG("main", M6809E, COCO_CPU_SPEED_HZ)        /* 0,894886 Mhz */
	MDRV_CPU_PROGRAM_MAP(coco_map, 0)
	MDRV_SCREEN_REFRESH_RATE(M6847_NTSC_FRAMES_PER_SECOND)

	MDRV_MACHINE_START( coco2 )

	/* video hardware */
	MDRV_VIDEO_START(coco)
	MDRV_VIDEO_UPDATE(m6847)
	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
	MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
	MDRV_SCREEN_SIZE(320, 25+192+26)
	MDRV_SCREEN_VISIBLE_AREA(0, 319, 1, 239)

	/* sound hardware */
	MDRV_IMPORT_FROM( coco_sound )
MACHINE_DRIVER_END

static MACHINE_DRIVER_START( coco2b )
	/* basic machine hardware */
	MDRV_CPU_ADD_TAG("main", M6809E, COCO_CPU_SPEED_HZ)        /* 0,894886 Mhz */
	MDRV_CPU_PROGRAM_MAP(coco_map, 0)
	MDRV_SCREEN_REFRESH_RATE(M6847_NTSC_FRAMES_PER_SECOND)

	MDRV_MACHINE_START( coco2 )

	/* video hardware */
	MDRV_VIDEO_START(coco2b)
	MDRV_VIDEO_UPDATE(m6847)
	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
	MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
	MDRV_SCREEN_SIZE(320, 25+192+26)
	MDRV_SCREEN_VISIBLE_AREA(0, 319, 1, 239)

	/* sound hardware */
	MDRV_IMPORT_FROM( coco_sound )
MACHINE_DRIVER_END

static MACHINE_DRIVER_START( coco3 )
	/* basic machine hardware */
	MDRV_CPU_ADD_TAG("main", M6809E, COCO_CPU_SPEED_HZ)        /* 0,894886 Mhz */
	MDRV_CPU_PROGRAM_MAP(coco3_map, 0)

	MDRV_MACHINE_START( coco3 )

	/* video hardware */
	MDRV_VIDEO_START(coco3)
	MDRV_VIDEO_UPDATE(coco3)
	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
	MDRV_DEFAULT_LAYOUT(layout_coco3)

	MDRV_SCREEN_ADD("composite", 0)
	MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
	MDRV_SCREEN_REFRESH_RATE(M6847_NTSC_FRAMES_PER_SECOND)
	MDRV_SCREEN_SIZE(640, 25+192+26)
	MDRV_SCREEN_VISIBLE_AREA(0, 639, 0, 239)

	MDRV_SCREEN_ADD("rgb", 0)
	MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
	MDRV_SCREEN_REFRESH_RATE(M6847_NTSC_FRAMES_PER_SECOND)
	MDRV_SCREEN_SIZE(640, 25+192+26)
	MDRV_SCREEN_VISIBLE_AREA(0, 639, 0, 239)

	/* sound hardware */
	MDRV_IMPORT_FROM( coco_sound )
MACHINE_DRIVER_END

static MACHINE_DRIVER_START( coco3p )
	MDRV_IMPORT_FROM( coco3 )
	MDRV_SCREEN_REFRESH_RATE(M6847_PAL_FRAMES_PER_SECOND)

	/* video hardware */
	MDRV_VIDEO_START(coco3p)
	MDRV_VIDEO_UPDATE(coco3)
	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
	MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
	MDRV_SCREEN_SIZE(640, 25+192+26)
	MDRV_SCREEN_VISIBLE_AREA(0, 639, 1, 239)
MACHINE_DRIVER_END

static MACHINE_DRIVER_START( coco3h )
	MDRV_IMPORT_FROM( coco3 )
	MDRV_CPU_REPLACE( "main", HD6309, COCO_CPU_SPEED_HZ)
MACHINE_DRIVER_END

/***************************************************************************

  Game driver(s)

***************************************************************************/

ROM_START(dragon32)
	ROM_REGION(0xC000,REGION_CPU1,0)
	ROM_LOAD(           "d32.rom",      0x0000,  0x4000, CRC(e3879310) SHA1(f2dab125673e653995a83bf6b793e3390ec7f65a))
	ROM_LOAD_OPTIONAL(  "ddos10.rom",   0x4000,  0x2000, CRC(b44536f6) SHA1(a8918c71d319237c1e3155bb38620acb114a80bc))
ROM_END

ROM_START(dragon64)
	ROM_REGION(0x10000,REGION_CPU1,0)
	ROM_LOAD(           "d64_1.rom",    0x0000,  0x4000, CRC(60a4634c) SHA1(f119506eaa3b4b70b9aa0dd83761e8cbe043d042))
	ROM_LOAD(           "d64_2.rom",    0x8000,  0x4000, CRC(17893a42) SHA1(e3c8986bb1d44269c4587b04f1ca27a70b0aaa2e))
	ROM_LOAD_OPTIONAL(  "ddos10.rom",   0x4000,  0x2000, CRC(b44536f6) SHA1(a8918c71d319237c1e3155bb38620acb114a80bc))
ROM_END

ROM_START(d64plus)
	ROM_REGION(0x10000,REGION_CPU1,0)
	ROM_LOAD(           "d64_1.rom",    0x0000,  0x4000, CRC(60a4634c) SHA1(f119506eaa3b4b70b9aa0dd83761e8cbe043d042))
	ROM_LOAD(           "d64_2.rom",    0x8000,  0x4000, CRC(17893a42) SHA1(e3c8986bb1d44269c4587b04f1ca27a70b0aaa2e))
	ROM_LOAD_OPTIONAL(  "ddos10.rom",   0x4000,  0x2000, CRC(b44536f6) SHA1(a8918c71d319237c1e3155bb38620acb114a80bc))
ROM_END

ROM_START(tanodr64)
	ROM_REGION(0x10000,REGION_CPU1,0)
	ROM_LOAD(           "d64_1.rom",    0x0000,  0x4000, CRC(60a4634c) SHA1(f119506eaa3b4b70b9aa0dd83761e8cbe043d042))
	ROM_LOAD(           "d64_2.rom",    0x8000,  0x4000, CRC(17893a42) SHA1(e3c8986bb1d44269c4587b04f1ca27a70b0aaa2e))
	ROM_LOAD_OPTIONAL(  "sdtandy.rom",   0x4000,  0x2000, CRC(5d7779b7) SHA1(ca03942118f2deab2f6c8a89b8a4f41f2d0b94f1))
ROM_END

ROM_START(dgnalpha)
	ROM_REGION(0x10000,REGION_CPU1,1)
	ROM_LOAD(           "alpha_bt.rom",    0x2000,  0x2000, CRC(c3dab585) SHA1(4a5851aa66eb426e9bb0bba196f1e02d48156068))
	ROM_LOAD(           "alpha_ba.rom",    0x8000,  0x4000, CRC(84f68bf9) SHA1(1983b4fb398e3dd9668d424c666c5a0b3f1e2b69))
ROM_END

ROM_START(coco)
     ROM_REGION(0x8000,REGION_CPU1,0)
     ROM_LOAD(			"bas10.rom",	0x2000, 0x2000, CRC(00b50aaa) SHA1(1f08455cd48ce6a06132aea15c4778f264e19539))
ROM_END

ROM_START(cocoe)
     ROM_REGION(0x8000,REGION_CPU1,0)
     ROM_LOAD(			"bas11.rom",	0x2000, 0x2000, CRC(6270955a) SHA1(cecb7c24ff1e0ab5836e4a7a8eb1b8e01f1fded3))
     ROM_LOAD(	        "extbas10.rom",	0x0000, 0x2000, CRC(6111a086) SHA1(8aa58f2eb3e8bcfd5470e3e35e2b359e9a72848e))
     ROM_LOAD_OPTIONAL(	"disk10.rom",	0x4000, 0x2000, CRC(b4f9968e) SHA1(04115be3f97952b9d9310b52f806d04f80b40d03))
ROM_END

ROM_START(coco2)
     ROM_REGION(0x8000,REGION_CPU1,0)
     ROM_LOAD(			"bas12.rom",	0x2000, 0x2000, CRC(54368805) SHA1(0f14dc46c647510eb0b7bd3f53e33da07907d04f))
     ROM_LOAD(      	"extbas11.rom",	0x0000, 0x2000, CRC(a82a6254) SHA1(ad927fb4f30746d820cb8b860ebb585e7f095dea))
     ROM_LOAD_OPTIONAL(	"disk11.rom",	0x4000, 0x2000, CRC(0b9c5415) SHA1(10bdc5aa2d7d7f205f67b47b19003a4bd89defd1))
ROM_END

ROM_START(coco2b)
     ROM_REGION(0x8000,REGION_CPU1,0)
     ROM_LOAD(			"bas13.rom",	0x2000, 0x2000, CRC(d8f4d15e) SHA1(28b92bebe35fa4f026a084416d6ea3b1552b63d3))
     ROM_LOAD(      	"extbas11.rom",	0x0000, 0x2000, CRC(a82a6254) SHA1(ad927fb4f30746d820cb8b860ebb585e7f095dea))
     ROM_LOAD_OPTIONAL(	"disk11.rom",	0x4000, 0x2000, CRC(0b9c5415) SHA1(10bdc5aa2d7d7f205f67b47b19003a4bd89defd1))
ROM_END

ROM_START(coco3)
     ROM_REGION(0x10000,REGION_CPU1,0)
	 ROM_LOAD(			"coco3.rom",	0x0000, 0x8000, CRC(b4c88d6c) SHA1(e0d82953fb6fd03768604933df1ce8bc51fc427d))
     ROM_LOAD_OPTIONAL(	"disk11.rom",	0xC000, 0x2000, CRC(0b9c5415) SHA1(10bdc5aa2d7d7f205f67b47b19003a4bd89defd1))
     ROM_LOAD_OPTIONAL(	"disk11.rom",	0xE000, 0x2000, CRC(0b9c5415) SHA1(10bdc5aa2d7d7f205f67b47b19003a4bd89defd1))
ROM_END

ROM_START(coco3p)
     ROM_REGION(0x10000,REGION_CPU1,0)
	 ROM_LOAD(			"coco3p.rom",	0x0000, 0x8000, CRC(ff050d80) SHA1(631e383068b1f52a8f419f4114b69501b21cf379))
     ROM_LOAD_OPTIONAL(	"disk11.rom",	0xC000, 0x2000, CRC(0b9c5415) SHA1(10bdc5aa2d7d7f205f67b47b19003a4bd89defd1))
     ROM_LOAD_OPTIONAL(	"disk11.rom",	0xE000, 0x2000, CRC(0b9c5415) SHA1(10bdc5aa2d7d7f205f67b47b19003a4bd89defd1))
ROM_END

ROM_START(cp400)
     ROM_REGION(0x8000,REGION_CPU1,0)
     ROM_LOAD("cp400bas.rom",  0x0000, 0x4000, CRC(878396a5) SHA1(292c545da3c77978e043b00a3dbc317201d18c3b))
     ROM_LOAD("cp400dsk.rom",  0x4000, 0x2000, CRC(e9ad60a0) SHA1(827697fa5b755f5dc1efb054cdbbeb04e405405b))
ROM_END

#define rom_coco3h	rom_coco3

/***************************************************************************
  Bitbanger port
***************************************************************************/

static int coco_bitbanger_filter(mess_image *img, const int *pulses, int total_pulses, int total_duration)
{
	int i;
	int result = 0;
	int word;
	int pos;
	int pulse_type;
	int c;

	if (total_duration >= 11)
	{
		word = 0;
		pos = 0;
		pulse_type = 0;
		result = 1;

		for (i = 0; i < total_pulses; i++)
		{
			if (pulse_type)
				word |= ((1 << pulses[i]) - 1) << pos;
			pulse_type ^= 1;
			pos += pulses[i];
		}

		c = (word >> 1) & 0xff;
		printer_output(img, c);
	}
	return result;
}

static const struct bitbanger_config coco_bitbanger_config =
{
	coco_bitbanger_filter,
	1.0 / 10.0,
	0.2,
	2,
	10,
	0,
	0
};

/* ----------------------------------------------------------------------- */

/*************************************
 *
 *	CoCo device getinfo functions
 *
 *************************************/

static void coco_bitbanger_getinfo(const device_class *devclass, UINT32 state, union devinfo *info)
{
	/* bitbanger port */
	switch(state)
	{
		/* --- the following bits of info are returned as 64-bit signed integers --- */
		case DEVINFO_INT_COUNT:							info->i = 1; break;

		/* --- the following bits of info are returned as pointers to data or functions --- */
		case DEVINFO_PTR_BITBANGER_CONFIG:				info->p = (void *) &coco_bitbanger_config; break;

		default:										bitbanger_device_getinfo(devclass, state, info); break;
	}
}



static void coco_cassette_getinfo(const device_class *devclass, UINT32 state, union devinfo *info)
{
	/* cassette */
	switch(state)
	{
		/* --- the following bits of info are returned as 64-bit signed integers --- */
		case DEVINFO_INT_COUNT:							info->i = 1; break;

		/* --- the following bits of info are returned as pointers to data or functions --- */
		case DEVINFO_PTR_CASSETTE_FORMATS:				info->p = (void *) coco_cassette_formats; break;

		/* --- the following bits of info are returned as 64-bit signed integers --- */
		case DEVINFO_INT_CASSETTE_DEFAULT_STATE:		info->i = CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_MUTED; break;

		default:										cassette_device_getinfo(devclass, state, info); break;
	}
}



static void coco_floppy_getinfo(const device_class *devclass, UINT32 state, union devinfo *info)
{
	/* floppy */
	switch(state)
	{
		/* --- the following bits of info are returned as 64-bit signed integers --- */
		case DEVINFO_INT_COUNT:							info->i = 4; break;

		/* --- the following bits of info are returned as pointers to data or functions --- */
		case DEVINFO_PTR_FLOPPY_OPTIONS:				info->p = (void *) floppyoptions_coco; break;

		/* --- the following bits of info are returned as NULL-terminated strings --- */
		case DEVINFO_STR_NAME+0:						strcpy(info->s = device_temp_str(), "floppydisk0"); break;
		case DEVINFO_STR_NAME+1:						strcpy(info->s = device_temp_str(), "floppydisk1"); break;
		case DEVINFO_STR_NAME+2:						strcpy(info->s = device_temp_str(), "floppydisk2"); break;
		case DEVINFO_STR_NAME+3:						strcpy(info->s = device_temp_str(), "floppydisk3"); break;
		case DEVINFO_STR_SHORT_NAME+0:					strcpy(info->s = device_temp_str(), "flop0"); break;
		case DEVINFO_STR_SHORT_NAME+1:					strcpy(info->s = device_temp_str(), "flop1"); break;
		case DEVINFO_STR_SHORT_NAME+2:					strcpy(info->s = device_temp_str(), "flop2"); break;
		case DEVINFO_STR_SHORT_NAME+3:					strcpy(info->s = device_temp_str(), "flop3"); break;
		case DEVINFO_STR_DESCRIPTION+0:					strcpy(info->s = device_temp_str(), "Floppy #0"); break;
		case DEVINFO_STR_DESCRIPTION+1:					strcpy(info->s = device_temp_str(), "Floppy #1"); break;
		case DEVINFO_STR_DESCRIPTION+2:					strcpy(info->s = device_temp_str(), "Floppy #2"); break;
		case DEVINFO_STR_DESCRIPTION+3:					strcpy(info->s = device_temp_str(), "Floppy #3"); break;

		default:										floppy_device_getinfo(devclass, state, info); break;
	}
}



static void coco_cartslot_getinfo(const device_class *devclass, UINT32 state, union devinfo *info)
{
	switch(state)
	{
		/* --- the following bits of info are returned as 64-bit signed integers --- */
		case DEVINFO_INT_COUNT:							info->i = 1; break;

		/* --- the following bits of info are returned as pointers to data or functions --- */
		case DEVINFO_PTR_LOAD:							info->load = device_load_coco_rom; break;
		case DEVINFO_PTR_UNLOAD:						info->unload = device_unload_coco_rom; break;

		/* --- the following bits of info are returned as NULL-terminated strings --- */
		case DEVINFO_STR_FILE_EXTENSIONS:				strcpy(info->s = device_temp_str(), "ccc,rom"); break;

		default:										cartslot_device_getinfo(devclass, state, info); break;
	}
}



static void coco3_cartslot_getinfo(const device_class *devclass, UINT32 state, union devinfo *info)
{
	switch(state)
	{
		/* --- the following bits of info are returned as 64-bit signed integers --- */
		case DEVINFO_INT_COUNT:							info->i = 1; break;

		/* --- the following bits of info are returned as pointers to data or functions --- */
		case DEVINFO_PTR_LOAD:							info->load = device_load_coco3_rom; break;
		case DEVINFO_PTR_UNLOAD:						info->unload = device_unload_coco3_rom; break;

		/* --- the following bits of info are returned as NULL-terminated strings --- */
		case DEVINFO_STR_FILE_EXTENSIONS:				strcpy(info->s = device_temp_str(), "ccc,rom"); break;

		default:										cartslot_device_getinfo(devclass, state, info); break;
	}
}



static void coco_snapshot_getinfo(const device_class *devclass, UINT32 state, union devinfo *info)
{
	switch(state)
	{
		/* --- the following bits of info are returned as NULL-terminated strings --- */
		case DEVINFO_STR_FILE_EXTENSIONS:				strcpy(info->s = device_temp_str(), "pak"); break;

		/* --- the following bits of info are returned as pointers to data or functions --- */
		case DEVINFO_PTR_SNAPSHOT_LOAD:					info->f = (genf *) snapshot_load_coco_pak; break;

		default:										snapshot_device_getinfo(devclass, state, info); break;
	}
}



static void coco3_snapshot_getinfo(const device_class *devclass, UINT32 state, union devinfo *info)
{
	switch(state)
	{
		/* --- the following bits of info are returned as NULL-terminated strings --- */
		case DEVINFO_STR_FILE_EXTENSIONS:				strcpy(info->s = device_temp_str(), "pak"); break;

		/* --- the following bits of info are returned as pointers to data or functions --- */
		case DEVINFO_PTR_SNAPSHOT_LOAD:					info->f = (genf *) snapshot_load_coco3_pak; break;

		default:										snapshot_device_getinfo(devclass, state, info); break;
	}
}

/*************************************
*
*	Dragon only devices
*
**************************************/

static void dragon_printer_getinfo(const device_class *devclass, UINT32 state, union devinfo *info)
{
	/* printer port */
	switch(state)
	{
		/* --- the following bits of info are returned as 64-bit signed integers --- */
		case DEVINFO_INT_COUNT:							info->i = 1; break;

		default:										printer_device_getinfo(devclass, state, info); break;
	}
}



/*************************************
 *
 *	CoCo sysconfig structures
 *
 *************************************/


SYSTEM_CONFIG_START( generic_coco )
	CONFIG_DEVICE( coco_bitbanger_getinfo )
	CONFIG_DEVICE( coco_cassette_getinfo )
	CONFIG_DEVICE( coco_floppy_getinfo )
SYSTEM_CONFIG_END

SYSTEM_CONFIG_START( generic_coco12 )
	CONFIG_IMPORT_FROM( generic_coco )
	CONFIG_DEVICE( coco_cartslot_getinfo )
	CONFIG_DEVICE( coco_snapshot_getinfo )
SYSTEM_CONFIG_END

/* These have to be split up, as the CoCo has a bitbanger */
/* where the Dragon has a paralell printer port */
SYSTEM_CONFIG_START( generic_dragon )
	CONFIG_DEVICE( coco_cassette_getinfo )
	CONFIG_DEVICE( coco_floppy_getinfo )
	CONFIG_DEVICE( coco_cartslot_getinfo )
	CONFIG_DEVICE( coco_snapshot_getinfo )
	CONFIG_DEVICE( dragon_printer_getinfo )
SYSTEM_CONFIG_END


/* ----------------------------------------------------------------------- */

/* I have split up coco and cocoe, as the basic rom in the coco, cannot    */
/* use 64K rams, and will boot with 4k, if this is selected, so I have     */
/* split these to avoid confusion -- PHS                                   */

SYSTEM_CONFIG_START( coco )
	CONFIG_IMPORT_FROM	( generic_coco12 )
	CONFIG_RAM		(4 * 1024)
	CONFIG_RAM_DEFAULT	(16 * 1024)
	CONFIG_RAM		(32 * 1024)
	CONFIG_RAM		(64 * 1024)
SYSTEM_CONFIG_END

SYSTEM_CONFIG_START( cocoe )
	CONFIG_IMPORT_FROM	( generic_coco12 )
	CONFIG_RAM		(4 * 1024)
	CONFIG_RAM		(16 * 1024)
	CONFIG_RAM		(32 * 1024)
	CONFIG_RAM_DEFAULT	(64 * 1024)
SYSTEM_CONFIG_END

SYSTEM_CONFIG_START(coco2)
	CONFIG_IMPORT_FROM	( generic_coco12 )
	CONFIG_RAM			(16 * 1024)
	CONFIG_RAM_DEFAULT	(64 * 1024)
SYSTEM_CONFIG_END

SYSTEM_CONFIG_START(coco3)
	CONFIG_IMPORT_FROM	( generic_coco )
	CONFIG_DEVICE( coco3_cartslot_getinfo )
	CONFIG_DEVICE( coco3_snapshot_getinfo )
	CONFIG_DEVICE( coco_vhd_device_getinfo )
	CONFIG_RAM			(128 * 1024)
	CONFIG_RAM_DEFAULT	(512 * 1024)
	CONFIG_RAM			(2048 * 1024)
	CONFIG_RAM			(8192 * 1024)
SYSTEM_CONFIG_END

SYSTEM_CONFIG_START(dragon32)
	CONFIG_IMPORT_FROM	( generic_dragon )
	CONFIG_RAM_DEFAULT	(32 * 1024)
	CONFIG_RAM		(64 * 1024)		// Since a fair number of users did this upgrade - phs
SYSTEM_CONFIG_END

SYSTEM_CONFIG_START(dragon64)
	CONFIG_IMPORT_FROM	( generic_dragon )
	CONFIG_RAM_DEFAULT	(64 * 1024)
SYSTEM_CONFIG_END

SYSTEM_CONFIG_START(d64plus)
	CONFIG_IMPORT_FROM	( generic_dragon )
	CONFIG_RAM_DEFAULT	(128 * 1024)		// 64K normal RAM + 64K on plus board.
SYSTEM_CONFIG_END

SYSTEM_CONFIG_START(tanodr64)
	CONFIG_IMPORT_FROM	( generic_dragon )
	CONFIG_RAM_DEFAULT	(64 * 1024)
SYSTEM_CONFIG_END

SYSTEM_CONFIG_START(dgnalpha)
	CONFIG_IMPORT_FROM	( generic_dragon )
	CONFIG_RAM_DEFAULT	(64 * 1024)
SYSTEM_CONFIG_END

/*     YEAR		NAME		PARENT	COMPAT	MACHINE    INPUT		INIT     CONFIG	COMPANY					FULLNAME */
COMP(  1980,	coco,		0,		0,		coco,		coco,		0,		coco,		"Tandy Radio Shack",	"Color Computer" , 0)
COMP(  1981,	cocoe,		coco,	0,		coco,		coco,		0,		cocoe,		"Tandy Radio Shack",	"Color Computer (Extended BASIC 1.0)" , 0)
COMP(  1983,	coco2,		coco,	0,		coco2,		coco,		0,		coco2,		"Tandy Radio Shack",	"Color Computer 2" , 0)
COMP(  1985?,	coco2b,		coco,	0,		coco2b,		coco,		0,		coco2,		"Tandy Radio Shack",	"Color Computer 2B" , 0)
COMP(  1986,	coco3,		coco,	0,	 	coco3,		coco3,		0,		coco3,		"Tandy Radio Shack",	"Color Computer 3 (NTSC)" , 0)
COMP(  1986,	coco3p,		coco, 	0,		coco3p,		coco3,		0,		coco3,		"Tandy Radio Shack",	"Color Computer 3 (PAL)" , 0)
COMP(  19??,	coco3h,		coco,	0,		coco3h,		coco3,		0,		coco3,		"Tandy Radio Shack",	"Color Computer 3 (NTSC; HD6309)", GAME_COMPUTER_MODIFIED)
COMP(  1982,	dragon32,	coco,	0,		dragon32,	dragon32,	0,		dragon32,	"Dragon Data Ltd",    "Dragon 32" , 0)
COMP(  1983,	dragon64,	coco,	0,		dragon64,	dragon32,	0,		dragon64,	"Dragon Data Ltd",    "Dragon 64" , 0)
COMP(  1983,	d64plus,	coco,	0,	d64plus,	dragon32,	0,	d64plus,	"Dragon Data Ltd",    "Dragon 64 Plus" , 0)
COMP(  1983,	tanodr64,	coco,	0,	tanodr64,	dragon32,	0,	tanodr64,	"Dragon Data Ltd/Tano Ltd","Tano Dragon 64 (NTSC)" , 0)
COMP(  1984,	dgnalpha,	coco,	0,		dgnalpha,	dragon32,	0,		dgnalpha,	"Dragon Data Ltd",    "Dragon Alpha Prototype" , 0)
COMP(  1984,	cp400,		coco, 	0,		coco,		coco,		0,		coco,		"Prologica",          "CP400" , 0)
