cgenie: Rewrote driver and removed lots of cruft.

- Remove custom 6845 emulation and use our standard core
- Use the slot system for the parallel interface, fix and implement the
joystick as a slot device and create a printer slot device
- Add support for the RS-232 port
- Add support for the Break key (causes NMI)
This commit is contained in:
Dirk Best 2015-05-24 18:11:48 +02:00
parent 434da1bdf4
commit b3b2768cc9
20 changed files with 1165 additions and 1475 deletions

View File

@ -2440,11 +2440,29 @@ end
if (BUSES["CGENIE_EXPANSION"]~=null) then
files {
MAME_DIR .. "src/emu/bus/cgenie/expansion.c",
MAME_DIR .. "src/emu/bus/cgenie/expansion.h",
MAME_DIR .. "src/emu/bus/cgenie/carts.c",
MAME_DIR .. "src/emu/bus/cgenie/carts.h",
MAME_DIR .. "src/emu/bus/cgenie/floppy.c",
MAME_DIR .. "src/emu/bus/cgenie/floppy.h",
MAME_DIR .. "src/emu/bus/cgenie/expansion/expansion.c",
MAME_DIR .. "src/emu/bus/cgenie/expansion/expansion.h",
MAME_DIR .. "src/emu/bus/cgenie/expansion/carts.c",
MAME_DIR .. "src/emu/bus/cgenie/expansion/carts.h",
MAME_DIR .. "src/emu/bus/cgenie/expansion/floppy.c",
MAME_DIR .. "src/emu/bus/cgenie/expansion/floppy.h",
}
end
---------------------------------------------------
--
--@src/emu/bus/cgenie/parallel.h,BUSES += CGENIE_PARALLEL
---------------------------------------------------
if (BUSES["CGENIE_PARALLEL"]~=null) then
files {
MAME_DIR .. "src/emu/bus/cgenie/parallel/parallel.c",
MAME_DIR .. "src/emu/bus/cgenie/parallel/parallel.h",
MAME_DIR .. "src/emu/bus/cgenie/parallel/carts.c",
MAME_DIR .. "src/emu/bus/cgenie/parallel/carts.h",
MAME_DIR .. "src/emu/bus/cgenie/parallel/joystick.c",
MAME_DIR .. "src/emu/bus/cgenie/parallel/joystick.h",
MAME_DIR .. "src/emu/bus/cgenie/parallel/printer.c",
MAME_DIR .. "src/emu/bus/cgenie/parallel/printer.h",
}
end

View File

@ -580,6 +580,7 @@ BUSES["CBM2"] = true
BUSES["CBMIEC"] = true
BUSES["CENTRONICS"] = true
BUSES["CGENIE_EXPANSION"] = true
BUSES["CGENIE_PARALLEL"] = true
BUSES["CHANNELF"] = true
BUSES["COCO"] = true
BUSES["COLECO"] = true
@ -1405,8 +1406,6 @@ files {
createMESSProjects(_target, _subtarget, "eaca")
files {
MAME_DIR .. "src/mess/drivers/cgenie.c",
MAME_DIR .. "src/mess/machine/cgenie.c",
MAME_DIR .. "src/mess/video/cgenie.c",
}
createMESSProjects(_target, _subtarget, "einis")

View File

@ -8,8 +8,8 @@
#pragma once
#ifndef __CGENIE_CARTS_H__
#define __CGENIE_CARTS_H__
#ifndef __CGENIE_EXPANSION_CARTS_H__
#define __CGENIE_EXPANSION_CARTS_H__
#include "emu.h"
@ -17,4 +17,4 @@
SLOT_INTERFACE_EXTERN( expansion_slot_carts );
#endif // __CGENIE_CARTS_H__
#endif // __CGENIE_EXPANSION_CARTS_H__

View File

@ -5,9 +5,11 @@
EACA Colour Genie Floppy Disc Controller
TODO:
- Only native MESS .mfi files load
- What's the exact FD1793 model?
- How does it turn off the motor?
- How does it switch between FM/MFM?
- What's the source of the timer and the exact timings?
***************************************************************************/
@ -65,7 +67,9 @@ const rom_entry *cgenie_fdc_device::device_rom_region() const
//-------------------------------------------------
static MACHINE_CONFIG_FRAGMENT( cgenie_fdc )
MCFG_FD1793x_ADD("fd1793", XTAL_16MHz / 4 / 4)
MCFG_TIMER_DRIVER_ADD_PERIODIC("timer", cgenie_fdc_device, timer_callback, attotime::from_msec(25))
MCFG_FD1793x_ADD("fd1793", XTAL_1MHz)
MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(cgenie_fdc_device, intrq_w))
MCFG_FLOPPY_DRIVE_ADD("fd1793:0", cgenie_floppies, "ssdd", cgenie_fdc_device::floppy_formats)
@ -97,7 +101,7 @@ machine_config_constructor cgenie_fdc_device::device_mconfig_additions() const
//-------------------------------------------------
cgenie_fdc_device::cgenie_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, CGENIE_FDC, "Colour Genie Floppy Disc Controller", tag, owner, clock, "cgenie_fdc", __FILE__),
device_t(mconfig, CGENIE_FDC, "Floppy Disc Controller", tag, owner, clock, "cgenie_fdc", __FILE__),
device_expansion_interface(mconfig, *this),
m_fdc(*this, "fd1793"),
m_floppy0(*this, "fd1793:0"),
@ -105,7 +109,9 @@ cgenie_fdc_device::cgenie_fdc_device(const machine_config &mconfig, const char *
m_floppy2(*this, "fd1793:2"),
m_floppy3(*this, "fd1793:3"),
m_socket(*this, "socket"),
m_floppy(NULL)
m_floppy(NULL),
m_timer_irq_off(NULL),
m_irq_status(0)
{
}
@ -115,6 +121,7 @@ cgenie_fdc_device::cgenie_fdc_device(const machine_config &mconfig, const char *
void cgenie_fdc_device::device_start()
{
m_timer_irq_off = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(cgenie_fdc_device::irq_off_callback), this));
}
//-------------------------------------------------
@ -127,6 +134,7 @@ void cgenie_fdc_device::device_reset()
m_slot->m_program->install_rom(0xc000, 0xdfff, memregion("software")->base());
// memory mapped i/o
m_slot->m_program->install_read_handler(0xffe0, 0xffe3, 0, 0x10, read8_delegate(FUNC(cgenie_fdc_device::irq_r), this));
m_slot->m_program->install_write_handler(0xffe0, 0xffe3, 0, 0x10, write8_delegate(FUNC(cgenie_fdc_device::select_w), this));
m_slot->m_program->install_read_handler(0xffec, 0xffef, 0, 0x10, read8_delegate(FUNC(fd1793_t::read), m_fdc.target()));
m_slot->m_program->install_write_handler(0xffec, 0xffef, 0, 0x10, write8_delegate(FUNC(fd1793_t::write), m_fdc.target()));
@ -143,6 +151,31 @@ void cgenie_fdc_device::device_reset()
// IMPLEMENTATION
//**************************************************************************
READ8_MEMBER( cgenie_fdc_device::irq_r )
{
return m_irq_status;
}
void cgenie_fdc_device::update_irq()
{
m_slot->int_w(m_irq_status ? 1 : 0);
}
TIMER_DEVICE_CALLBACK_MEMBER( cgenie_fdc_device::timer_callback )
{
m_irq_status |= IRQ_TIMER;
update_irq();
// timer to turn it off again
m_timer_irq_off->adjust(attotime::from_usec(250));
}
TIMER_CALLBACK_MEMBER( cgenie_fdc_device::irq_off_callback )
{
m_irq_status &= ~IRQ_TIMER;
update_irq();
}
DEVICE_IMAGE_LOAD_MEMBER( cgenie_fdc_device, socket_load )
{
UINT32 size = m_socket->common_get_size("rom");
@ -164,8 +197,12 @@ WRITE_LINE_MEMBER( cgenie_fdc_device::intrq_w )
if (VERBOSE)
logerror("cgenie_fdc_device::intrq_w: %d\n", state);
// forward to host
m_slot->int_w(state);
if (state)
m_irq_status |= IRQ_WDC;
else
m_irq_status &= ~IRQ_WDC;
update_irq();
}
WRITE8_MEMBER( cgenie_fdc_device::select_w )

View File

@ -29,12 +29,17 @@ public:
// construction/destruction
cgenie_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
TIMER_DEVICE_CALLBACK_MEMBER(timer_callback);
TIMER_CALLBACK_MEMBER( irq_off_callback );
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(socket_load);
DECLARE_WRITE_LINE_MEMBER(intrq_w);
DECLARE_READ8_MEMBER(irq_r);
DECLARE_WRITE8_MEMBER(select_w);
DECLARE_FLOPPY_FORMATS(floppy_formats);
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(socket_load);
protected:
virtual const rom_entry *device_rom_region() const;
@ -43,6 +48,8 @@ protected:
virtual void device_reset();
private:
void update_irq();
required_device<fd1793_t> m_fdc;
required_device<floppy_connector> m_floppy0;
required_device<floppy_connector> m_floppy1;
@ -50,7 +57,16 @@ private:
required_device<floppy_connector> m_floppy3;
required_device<generic_slot_device> m_socket;
enum
{
IRQ_WDC = 0x40,
IRQ_TIMER = 0x80
};
floppy_image_device *m_floppy;
emu_timer *m_timer_irq_off;
UINT8 m_irq_status;
};
// device type definition

View File

@ -0,0 +1,14 @@
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
EACA Colour Genie Parallel Carts
***************************************************************************/
#include "carts.h"
SLOT_INTERFACE_START( parallel_slot_carts )
SLOT_INTERFACE("joystick", CGENIE_JOYSTICK)
SLOT_INTERFACE("printer", CGENIE_PRINTER)
SLOT_INTERFACE_END

View File

@ -0,0 +1,21 @@
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
EACA Colour Genie Parallel Carts
***************************************************************************/
#pragma once
#ifndef __CGENIE_PARALLEL_CARTS_H__
#define __CGENIE_PARALLEL_CARTS_H__
#include "emu.h"
#include "joystick.h"
#include "printer.h"
SLOT_INTERFACE_EXTERN( parallel_slot_carts );
#endif // __CGENIE_PARALLEL_CARTS_H__

View File

@ -0,0 +1,153 @@
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
EACA Colour Genie Joystick Interface EG2013
Keypads are organized as 3x4 matrix.
***************************************************************************/
#include "joystick.h"
//**************************************************************************
// CONSTANTS/MACROS
//**************************************************************************
#define VERBOSE 0
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
const device_type CGENIE_JOYSTICK = &device_creator<cgenie_joystick_device>;
//-------------------------------------------------
// input_ports - device-specific input ports
//-------------------------------------------------
static INPUT_PORTS_START( cgenie_joystick )
PORT_START("JOY.0")
PORT_BIT(0x3f, 0x00, IPT_AD_STICK_X) PORT_SENSITIVITY(100) PORT_PLAYER(1)
PORT_START("JOY.1")
PORT_BIT(0x3f, 0x00, IPT_AD_STICK_Y) PORT_SENSITIVITY(100) PORT_PLAYER(1) PORT_REVERSE
PORT_START("JOY.2")
PORT_BIT(0x3f, 0x00, IPT_AD_STICK_X) PORT_SENSITIVITY(100) PORT_PLAYER(2)
PORT_START("JOY.3")
PORT_BIT(0x3f, 0x00, IPT_AD_STICK_Y) PORT_SENSITIVITY(100) PORT_PLAYER(2) PORT_REVERSE
PORT_START("KEYPAD.0")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Keypad 1 Button 3") PORT_PLAYER(1) PORT_CODE(KEYCODE_3_PAD)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("Keypad 1 Button 6") PORT_PLAYER(1) PORT_CODE(KEYCODE_6_PAD)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_NAME("Keypad 1 Button 9") PORT_PLAYER(1) PORT_CODE(KEYCODE_9_PAD)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_BUTTON4) PORT_NAME("Keypad 1 Button #") PORT_PLAYER(1) PORT_CODE(KEYCODE_SLASH_PAD)
PORT_START("KEYPAD.1")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON5) PORT_NAME("Keypad 1 Button 2") PORT_PLAYER(1) PORT_CODE(KEYCODE_2_PAD)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON6) PORT_NAME("Keypad 1 Button 5") PORT_PLAYER(1) PORT_CODE(KEYCODE_5_PAD)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON7) PORT_NAME("Keypad 1 Button 8") PORT_PLAYER(1) PORT_CODE(KEYCODE_8_PAD)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_BUTTON8) PORT_NAME("Keypad 1 Button 0") PORT_PLAYER(1) PORT_CODE(KEYCODE_0_PAD)
PORT_START("KEYPAD.2")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON9) PORT_NAME("Keypad 1 Button 1") PORT_PLAYER(1) PORT_CODE(KEYCODE_1_PAD)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON10) PORT_NAME("Keypad 1 Button 4") PORT_PLAYER(1) PORT_CODE(KEYCODE_4_PAD)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON11) PORT_NAME("Keypad 1 Button 7") PORT_PLAYER(1) PORT_CODE(KEYCODE_7_PAD)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_BUTTON12) PORT_NAME("Keypad 1 Button *") PORT_PLAYER(1) PORT_CODE(KEYCODE_ASTERISK)
PORT_START("KEYPAD.3")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Keypad 2 Button 3") PORT_PLAYER(2) PORT_CODE(JOYCODE_BUTTON2)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("Keypad 2 Button 6") PORT_PLAYER(2) PORT_CODE(JOYCODE_BUTTON5)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_NAME("Keypad 2 Button 9") PORT_PLAYER(2)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_BUTTON4) PORT_NAME("Keypad 2 Button #") PORT_PLAYER(2) PORT_CODE(JOYCODE_BUTTON1)
PORT_START("KEYPAD.4")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON5) PORT_NAME("Keypad 2 Button 2") PORT_PLAYER(2) PORT_CODE(JOYCODE_BUTTON2)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON6) PORT_NAME("Keypad 2 Button 5") PORT_PLAYER(2) PORT_CODE(JOYCODE_BUTTON5)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON7) PORT_NAME("Keypad 2 Button 8") PORT_PLAYER(2)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_BUTTON8) PORT_NAME("Keypad 2 Button 0") PORT_PLAYER(2)
PORT_START("KEYPAD.5")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON9) PORT_NAME("Keypad 2 Button 1") PORT_PLAYER(2) PORT_CODE(JOYCODE_BUTTON1)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON10) PORT_NAME("Keypad 2 Button 4") PORT_PLAYER(2) PORT_CODE(JOYCODE_BUTTON4)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON11) PORT_NAME("Keypad 2 Button 7") PORT_PLAYER(2)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_BUTTON12) PORT_NAME("Keypad 2 Button *") PORT_PLAYER(2) PORT_CODE(JOYCODE_BUTTON1)
INPUT_PORTS_END
ioport_constructor cgenie_joystick_device::device_input_ports() const
{
return INPUT_PORTS_NAME( cgenie_joystick );
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// cgenie_joystick_device - constructor
//-------------------------------------------------
cgenie_joystick_device::cgenie_joystick_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, CGENIE_JOYSTICK, "Joystick Interface EG2013", tag, owner, clock, "cgenie_joystick", __FILE__),
device_parallel_interface(mconfig, *this),
m_joy(*this, "JOY"),
m_keypad(*this, "KEYPAD"),
m_select(0)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void cgenie_joystick_device::device_start()
{
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void cgenie_joystick_device::device_reset()
{
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
void cgenie_joystick_device::pa_w(UINT8 data)
{
if (VERBOSE)
logerror("%s: pa_w %02x\n", tag(), data);
// d0 to d5 connected
m_select = data & 0x3f;
}
UINT8 cgenie_joystick_device::pb_r()
{
UINT8 data = 0x0f;
// read button state
for (int i = 0; i < 4; i++)
if (!BIT(m_select, i))
data &= m_keypad[i]->read();
// and joystick state
data |= m_joy[3]->read() > m_select ? 0x10 : 0x00;
data |= m_joy[2]->read() > m_select ? 0x20 : 0x00;
data |= m_joy[1]->read() > m_select ? 0x40 : 0x00;
data |= m_joy[0]->read() > m_select ? 0x80 : 0x00;
if (VERBOSE)
logerror("%s: pb_r %02x\n", tag(), data);
return data;
}

View File

@ -0,0 +1,48 @@
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
EACA Colour Genie Joystick Interface EG2013
***************************************************************************/
#pragma once
#ifndef __CGENIE_PARALLEL_JOYSTICK_H__
#define __CGENIE_PARALLEL_JOYSTICK_H__
#include "emu.h"
#include "parallel.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> cgenie_joystick_device
class cgenie_joystick_device : public device_t, public device_parallel_interface
{
public:
// construction/destruction
cgenie_joystick_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
protected:
virtual void device_start();
virtual void device_reset();
virtual ioport_constructor device_input_ports() const;
virtual void pa_w(UINT8 data);
virtual UINT8 pb_r();
private:
required_ioport_array<4> m_joy;
required_ioport_array<6> m_keypad;
UINT8 m_select;
};
// device type definition
extern const device_type CGENIE_JOYSTICK;
#endif // __CGENIE_PARALLEL_JOYSTICK_H__

View File

@ -0,0 +1,115 @@
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
EACA Colour Genie Parallel Slot
20-pin slot
***************************************************************************/
#include "parallel.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
const device_type PARALLEL_SLOT = &device_creator<parallel_slot_device>;
//**************************************************************************
// SLOT DEVICE
//**************************************************************************
//-------------------------------------------------
// parallel_slot_device - constructor
//-------------------------------------------------
parallel_slot_device::parallel_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, PARALLEL_SLOT, "Parallel Slot", tag, owner, clock, "parallel_slot", __FILE__),
device_slot_interface(mconfig, *this),
m_cart(NULL)
{
}
//-------------------------------------------------
// parallel_slot_device - destructor
//-------------------------------------------------
parallel_slot_device::~parallel_slot_device()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void parallel_slot_device::device_start()
{
m_cart = dynamic_cast<device_parallel_interface *>(get_card_device());
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void parallel_slot_device::device_reset()
{
}
//**************************************************************************
// I/O PORTS
//**************************************************************************
READ8_MEMBER( parallel_slot_device::pa_r )
{
if (m_cart)
return m_cart->pa_r();
else
return 0xff;
}
WRITE8_MEMBER( parallel_slot_device::pa_w )
{
if (m_cart)
m_cart->pa_w(data);
}
READ8_MEMBER( parallel_slot_device::pb_r )
{
if (m_cart)
return m_cart->pb_r();
else
return 0xff;
}
WRITE8_MEMBER( parallel_slot_device::pb_w )
{
if (m_cart)
m_cart->pb_w(data);
}
//**************************************************************************
// CARTRIDGE INTERFACE
//**************************************************************************
//-------------------------------------------------
// device_parallel_interface - constructor
//-------------------------------------------------
device_parallel_interface::device_parallel_interface(const machine_config &mconfig, device_t &device) :
device_slot_card_interface(mconfig, device)
{
m_slot = dynamic_cast<parallel_slot_device *>(device.owner());
}
//-------------------------------------------------
// ~device_parallel_interface - destructor
//-------------------------------------------------
device_parallel_interface::~device_parallel_interface()
{
}

View File

@ -0,0 +1,94 @@
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
EACA Colour Genie Parallel Slot
20-pin slot
1 GND 11 IOB2
2 +12V 12 IOB1
3 IOA3 13 IOB0
4 IOA4 14 IOB3
5 IOA0 15 IOB4
6 IOA5 16 IOB5
7 IOA1 17 IOB7
8 IOA2 18 IOB6
9 IOA7 19 +5V
10 IOA6 20 -12V
***************************************************************************/
#pragma once
#ifndef __CGENIE_PARALLEL_H__
#define __CGENIE_PARALLEL_H__
#include "emu.h"
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
#define MCFG_PARALLEL_SLOT_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, PARALLEL_SLOT, 0) \
MCFG_DEVICE_SLOT_INTERFACE(parallel_slot_carts, NULL, false)
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class device_parallel_interface;
class parallel_slot_device : public device_t, public device_slot_interface
{
public:
// construction/destruction
parallel_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
virtual ~parallel_slot_device();
// IOA
DECLARE_READ8_MEMBER(pa_r);
DECLARE_WRITE8_MEMBER(pa_w);
// IOB
DECLARE_READ8_MEMBER(pb_r);
DECLARE_WRITE8_MEMBER(pb_w);
protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
device_parallel_interface *m_cart;
private:
};
// class representing interface-specific live parallel device
class device_parallel_interface : public device_slot_card_interface
{
public:
// construction/destruction
device_parallel_interface(const machine_config &mconfig, device_t &device);
virtual ~device_parallel_interface();
virtual UINT8 pa_r() { return 0xff; };
virtual void pa_w(UINT8 data) {};
virtual UINT8 pb_r() { return 0xff; };
virtual void pb_w(UINT8 data) {};
protected:
parallel_slot_device *m_slot;
};
// device type definition
extern const device_type PARALLEL_SLOT;
// include here so drivers don't need to
#include "carts.h"
#endif // __CGENIE_PARALLEL_H__

View File

@ -0,0 +1,132 @@
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
EACA Colour Genie Printer Interface EG2012
***************************************************************************/
#include "printer.h"
//**************************************************************************
// CONSTANTS/MACROS
//**************************************************************************
#define VERBOSE 0
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
const device_type CGENIE_PRINTER = &device_creator<cgenie_printer_device>;
//-------------------------------------------------
// machine_config_additions - device-specific
// machine configurations
//-------------------------------------------------
static MACHINE_CONFIG_FRAGMENT( cgenie_printer )
MCFG_CENTRONICS_ADD("centronics", centronics_devices, "printer")
MCFG_CENTRONICS_BUSY_HANDLER(WRITELINE(cgenie_printer_device, busy_w))
MCFG_CENTRONICS_PERROR_HANDLER(WRITELINE(cgenie_printer_device, perror_w))
MCFG_CENTRONICS_SELECT_HANDLER(WRITELINE(cgenie_printer_device, select_w))
MCFG_CENTRONICS_FAULT_HANDLER(WRITELINE(cgenie_printer_device, fault_w))
MCFG_CENTRONICS_OUTPUT_LATCH_ADD("latch", "centronics")
MACHINE_CONFIG_END
machine_config_constructor cgenie_printer_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME( cgenie_printer );
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// cgenie_printer_device - constructor
//-------------------------------------------------
cgenie_printer_device::cgenie_printer_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, CGENIE_PRINTER, "Printer Interface EG2012", tag, owner, clock, "cgenie_printer", __FILE__),
device_parallel_interface(mconfig, *this),
m_centronics(*this, "centronics"),
m_latch(*this, "latch"),
m_centronics_busy(0),
m_centronics_out_of_paper(0),
m_centronics_unit_sel(1),
m_centronics_ready(1)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void cgenie_printer_device::device_start()
{
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void cgenie_printer_device::device_reset()
{
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
WRITE_LINE_MEMBER( cgenie_printer_device::busy_w )
{
m_centronics_busy = state;
}
WRITE_LINE_MEMBER( cgenie_printer_device::perror_w )
{
m_centronics_out_of_paper = state;
}
WRITE_LINE_MEMBER( cgenie_printer_device::select_w )
{
m_centronics_unit_sel = state;
}
WRITE_LINE_MEMBER( cgenie_printer_device::fault_w )
{
m_centronics_ready = state;
}
void cgenie_printer_device::pa_w(UINT8 data)
{
if (VERBOSE)
logerror("%s: pa_w %02x\n", tag(), data);
m_latch->write(data);
}
UINT8 cgenie_printer_device::pb_r()
{
UINT8 data = 0x0f;
data |= m_centronics_ready << 4;
data |= m_centronics_unit_sel << 5;
data |= m_centronics_out_of_paper << 6;
data |= m_centronics_busy << 7;
return data;
}
void cgenie_printer_device::pb_w(UINT8 data)
{
if (VERBOSE)
logerror("%s: pa_w %02x\n", tag(), data);
m_centronics->write_strobe(BIT(data, 0));
}

View File

@ -0,0 +1,58 @@
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
EACA Colour Genie Printer Interface EG2012
***************************************************************************/
#pragma once
#ifndef __CGENIE_PARALLEL_PRINTER_H__
#define __CGENIE_PARALLEL_PRINTER_H__
#include "emu.h"
#include "parallel.h"
#include "bus/centronics/ctronics.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> cgenie_printer_device
class cgenie_printer_device : public device_t, public device_parallel_interface
{
public:
// construction/destruction
cgenie_printer_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
DECLARE_WRITE_LINE_MEMBER(busy_w);
DECLARE_WRITE_LINE_MEMBER(perror_w);
DECLARE_WRITE_LINE_MEMBER(select_w);
DECLARE_WRITE_LINE_MEMBER(fault_w);
protected:
virtual machine_config_constructor device_mconfig_additions() const;
virtual void device_start();
virtual void device_reset();
virtual void pa_w(UINT8 data);
virtual UINT8 pb_r();
virtual void pb_w(UINT8 data);
private:
required_device<centronics_device> m_centronics;
required_device<output_latch_device> m_latch;
int m_centronics_busy;
int m_centronics_out_of_paper;
int m_centronics_unit_sel;
int m_centronics_ready;
};
// device type definition
extern const device_type CGENIE_PRINTER;
#endif // __CGENIE_PARALLEL_PRINTER_H__

View File

@ -1,494 +1,460 @@
// license:BSD-3-Clause
// copyright-holders:Nathan Woods
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
HAD to change the PORT_ANALOG defs in this file... please check ;-)
Colour Genie memory map
EACA Colour Genie EG2000
CPU #1:
0000-3fff ROM basic & bios R D0-D7
TODO:
- System is too fast, there should be one wait cycle every five cycles?
- What's the exact MC6845 type? It can't be H46505
- Adjust visible area so that the borders aren't that large (needs
MC6845 changes)
- Verify BASIC and character set versions
4000-bfff RAM
c000-dfff ROM dos R D0-D7
e000-efff ROM extra R D0-D7
f000-f3ff color ram W/R D0-D3
f400-f7ff font ram W/R D0-D7
f800-f8ff keyboard matrix R D0-D7
ffe0-ffe3 floppy motor W D0-D2
floppy head select W D3
ffec-ffef FDC WD179x R/W D0-D7
ffec command W
ffec status R
ffed track R/W
ffee sector R/W
ffef data R/W
Interrupts:
IRQ mode 1
NMI
***************************************************************************/
#include "emu.h"
#include "cpu/z80/z80.h"
#include "includes/cgenie.h"
#include "imagedev/flopdrv.h"
#include "formats/basicdsk.h"
#include "imagedev/cassette.h"
#include "sound/ay8910.h"
#include "sound/dac.h"
#include "formats/cgen_cas.h"
#include "machine/ram.h"
#include "bus/cgenie/expansion.h"
#include "video/mc6845.h"
#include "sound/ay8910.h"
#include "imagedev/cassette.h"
#include "formats/cgen_cas.h"
#include "bus/rs232/rs232.h"
#include "bus/cgenie/expansion/expansion.h"
#include "bus/cgenie/parallel/parallel.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class cgenie_state : public driver_device
{
public:
cgenie_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_cassette(*this, "cassette"),
m_ram(*this, RAM_TAG),
m_crtc(*this, "crtc"),
m_rs232(*this, "rs232"),
m_exp(*this, "exp"),
m_char_rom(*this, "gfx1"),
m_color_ram(*this, "colorram"),
m_font_ram(*this, "fontram"),
m_keyboard(*this, "KEY"),
m_palette(NULL),
m_control(0xff),
m_rs232_rx(1),
m_rs232_dcd(1)
{}
DECLARE_DRIVER_INIT(cgenie_eu);
DECLARE_DRIVER_INIT(cgenie_nz);
MC6845_BEGIN_UPDATE(crtc_begin_update);
MC6845_UPDATE_ROW(crtc_update_row);
// 4-bit color ram
DECLARE_READ8_MEMBER(colorram_r);
DECLARE_WRITE8_MEMBER(colorram_w);
// control port
DECLARE_WRITE8_MEMBER(control_w);
DECLARE_READ8_MEMBER(control_r);
DECLARE_READ8_MEMBER(keyboard_r);
DECLARE_INPUT_CHANGED_MEMBER(rst_callback);
DECLARE_WRITE_LINE_MEMBER(rs232_rx_w);
DECLARE_WRITE_LINE_MEMBER(rs232_dcd_w);
protected:
virtual void machine_start();
private:
required_device<cpu_device> m_maincpu;
required_device<cassette_image_device> m_cassette;
required_device<ram_device> m_ram;
required_device<mc6845_1_device> m_crtc;
required_device<rs232_port_device> m_rs232;
required_device<expansion_slot_device> m_exp;
required_memory_region m_char_rom;
required_shared_ptr<UINT8> m_color_ram;
required_shared_ptr<UINT8> m_font_ram;
required_ioport_array<8> m_keyboard;
static const rgb_t m_palette_bg[];
static const rgb_t m_palette_eu[];
static const rgb_t m_palette_nz[];
const rgb_t *m_palette;
rgb_t m_background_color;
UINT8 m_control;
int m_rs232_rx;
int m_rs232_dcd;
};
//**************************************************************************
// ADDRESS MAPS
//**************************************************************************
static ADDRESS_MAP_START( cgenie_mem, AS_PROGRAM, 8, cgenie_state )
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x0000, 0x3fff) AM_ROM
// AM_RANGE(0x4000, 0xbfff) AM_RAM // set up in MACHINE_START
AM_RANGE(0xf000, 0xf3ff) AM_READWRITE(cgenie_colorram_r, cgenie_colorram_w ) AM_SHARE("colorram")
AM_RANGE(0xf400, 0xf7ff) AM_READWRITE(cgenie_fontram_r, cgenie_fontram_w) AM_SHARE("fontram")
AM_RANGE(0xf800, 0xf8ff) AM_READ(cgenie_keyboard_r )
AM_RANGE(0xffe0, 0xffe3) AM_READ(cgenie_irq_status_r)
// AM_RANGE(0x4000, 0xbfff) AM_RAM // set up in machine_start
AM_RANGE(0xc000, 0xefff) AM_NOP // cartridge space
AM_RANGE(0xf000, 0xf3ff) AM_READWRITE(colorram_r, colorram_w ) AM_SHARE("colorram")
AM_RANGE(0xf400, 0xf7ff) AM_RAM AM_SHARE("fontram")
AM_RANGE(0xf800, 0xf8ff) AM_MIRROR(0x300) AM_READ(keyboard_r)
AM_RANGE(0xfc00, 0xffff) AM_NOP // cartridge space
ADDRESS_MAP_END
static ADDRESS_MAP_START( cgenie_io, AS_IO, 8, cgenie_state )
ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE(0xf8, 0xf8) AM_READWRITE(cgenie_sh_control_port_r, cgenie_sh_control_port_w )
AM_RANGE(0xf8, 0xf8) AM_DEVWRITE("ay8910", ay8910_device, address_w)
AM_RANGE(0xf9, 0xf9) AM_DEVREADWRITE("ay8910", ay8910_device, data_r, data_w)
AM_RANGE(0xfa, 0xfa) AM_READWRITE(cgenie_index_r, cgenie_index_w )
AM_RANGE(0xfb, 0xfb) AM_READWRITE(cgenie_register_r, cgenie_register_w )
AM_RANGE(0xff, 0xff) AM_READWRITE(cgenie_port_ff_r, cgenie_port_ff_w )
AM_RANGE(0xfa, 0xfa) AM_DEVWRITE("crtc", mc6845_1_device, address_w)
AM_RANGE(0xfb, 0xfb) AM_DEVREADWRITE("crtc", mc6845_1_device, register_r, register_w)
AM_RANGE(0xff, 0xff) AM_READWRITE(control_r, control_w)
ADDRESS_MAP_END
//**************************************************************************
// INPUTS
//**************************************************************************
static INPUT_PORTS_START( cgenie )
PORT_START("DSW0")
PORT_DIPNAME( 0x10, 0x10, "Video Display accuracy") PORT_CODE(KEYCODE_F5) PORT_TOGGLE
PORT_DIPSETTING( 0x10, "TV set" )
PORT_DIPSETTING( 0x00, "RGB monitor" )
PORT_BIT(0xef, 0xef, IPT_UNUSED)
PORT_START("KEY.0")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@') PORT_CHAR('`')
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A')
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B')
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C')
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E')
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F')
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G')
/**************************************************************************
+-------------------------------+ +-------------------------------+
| 0 1 2 3 4 5 6 7 | | 0 1 2 3 4 5 6 7 |
+--+---+---+---+---+---+---+---+---+ +--+---+---+---+---+---+---+---+---+
|0 | @ | A | B | C | D | E | F | G | |0 | ` | a | b | c | d | e | f | g |
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+
|1 | H | I | J | K | L | M | N | O | |1 | h | i | j | k | l | m | n | o |
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+
|2 | P | Q | R | S | T | U | V | W | |2 | p | q | r | s | t | u | v | w |
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+
|3 | X | Y | Z | [ |F-1|F-2|F-3|F-4| |3 | x | y | z | { |F-5|F-6|F-7|F-8|
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+
|4 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |4 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+
|5 | 8 | 9 | : | ; | , | - | . | / | |5 | 8 | 9 | * | + | < | = | > | ? |
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+
|6 |ENT|CLR|BRK|UP |DN |LFT|RGT|SPC| |6 |ENT|CLR|BRK|UP |DN |LFT|RGT|SPC|
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+
|7 |SHF|ALT|PUP|PDN|INS|DEL|CTL|END| |7 |SHF|ALT|PUP|PDN|INS|DEL|CTL|END|
+--+---+---+---+---+---+---+---+---+ +--+---+---+---+---+---+---+---+---+
***************************************************************************/
PORT_START("KEY.1")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H')
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I')
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J')
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K')
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L')
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M')
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N')
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O')
PORT_START("ROW0")
PORT_BIT(0x01, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@') PORT_CHAR('`')
PORT_BIT(0x02, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A')
PORT_BIT(0x04, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B')
PORT_BIT(0x08, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C')
PORT_BIT(0x10, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')
PORT_BIT(0x20, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E')
PORT_BIT(0x40, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F')
PORT_BIT(0x80, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G')
PORT_START("KEY.2")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P')
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q')
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R')
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T')
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U')
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V')
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W')
PORT_START("ROW1")
PORT_BIT(0x01, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H')
PORT_BIT(0x02, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I')
PORT_BIT(0x04, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J')
PORT_BIT(0x08, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K')
PORT_BIT(0x10, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L')
PORT_BIT(0x20, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M')
PORT_BIT(0x40, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N')
PORT_BIT(0x80, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O')
PORT_START("KEY.3")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X')
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y')
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z')
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_UNUSED) // produces [ and { when pressed, not on keyboard
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_CHAR(UCHAR_MAMEKEY(F5))
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CHAR(UCHAR_MAMEKEY(F6))
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_CHAR(UCHAR_MAMEKEY(F7))
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_CHAR(UCHAR_MAMEKEY(F8))
PORT_START("ROW2")
PORT_BIT(0x01, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P')
PORT_BIT(0x02, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q')
PORT_BIT(0x04, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R')
PORT_BIT(0x08, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')
PORT_BIT(0x10, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T')
PORT_BIT(0x20, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U')
PORT_BIT(0x40, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V')
PORT_BIT(0x80, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W')
PORT_START("KEY.4")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0')
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"')
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&')
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'')
PORT_START("ROW3")
PORT_BIT(0x01, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X')
PORT_BIT(0x02, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y')
PORT_BIT(0x04, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z')
PORT_BIT(0x08, 0x00, IPT_KEYBOARD) PORT_NAME("[ { (Not Connected)") PORT_CHAR('[') PORT_CHAR('{')
PORT_BIT(0x10, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_CHAR(UCHAR_MAMEKEY(F5))
PORT_BIT(0x20, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CHAR(UCHAR_MAMEKEY(F6))
PORT_BIT(0x40, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_CHAR(UCHAR_MAMEKEY(F7))
PORT_BIT(0x80, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_CHAR(UCHAR_MAMEKEY(F8))
PORT_START("KEY.5")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR(':') PORT_CHAR('*')
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+')
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('-') PORT_CHAR('=')
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
PORT_START("ROW4")
PORT_BIT(0x01, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0')
PORT_BIT(0x02, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
PORT_BIT(0x04, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"')
PORT_BIT(0x08, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
PORT_BIT(0x10, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
PORT_BIT(0x20, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
PORT_BIT(0x40, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&')
PORT_BIT(0x80, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'')
PORT_START("KEY.6")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Clear") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR(UCHAR_MAMEKEY(F10))
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Break") PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR(UCHAR_MAMEKEY(ESC))
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP))
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN))
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
PORT_START("ROW5")
PORT_BIT(0x01, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
PORT_BIT(0x02, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
PORT_BIT(0x04, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR(':') PORT_CHAR('*')
PORT_BIT(0x08, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+')
PORT_BIT(0x10, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
PORT_BIT(0x20, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('-') PORT_CHAR('=')
PORT_BIT(0x40, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
PORT_BIT(0x80, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
PORT_START("KEY.7")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Mod Sel") PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(F9))
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Rpt") PORT_CODE(KEYCODE_PGDN) PORT_CHAR(UCHAR_MAMEKEY(F11))
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(F12))
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("L.P.") // marked as "L.P." in the manual, lightpen?
PORT_START("ROW6")
PORT_BIT(0x01, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
PORT_BIT(0x02, 0x00, IPT_KEYBOARD) PORT_NAME("Clear") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR(UCHAR_MAMEKEY(F10))
PORT_BIT(0x04, 0x00, IPT_KEYBOARD) PORT_NAME("Break") PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR(UCHAR_MAMEKEY(ESC))
PORT_BIT(0x08, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP))
PORT_BIT(0x10, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN))
PORT_BIT(0x20, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
PORT_BIT(0x40, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
PORT_BIT(0x80, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
/* 2008-05 FP: Below we still miss a 'Lock' key, two 'Rst' keys (used in pair, they should restart the
system) and, I guess, two unused inputs (according to the user manual, there are no other keys on the
keyboard) */
PORT_START("ROW7")
PORT_BIT(0x01, 0x00, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
PORT_BIT(0x02, 0x00, IPT_KEYBOARD) PORT_NAME("Mod Sel") PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(F9))
PORT_BIT(0x04, 0x00, IPT_KEYBOARD) PORT_NAME("Unknown 1")
PORT_BIT(0x08, 0x00, IPT_KEYBOARD) PORT_NAME("Rpt") PORT_CODE(KEYCODE_PGDN) PORT_CHAR(UCHAR_MAMEKEY(F11))
PORT_BIT(0x10, 0x00, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(F12))
PORT_BIT(0x20, 0x00, IPT_KEYBOARD) PORT_NAME("Unknown 2")
PORT_BIT(0x40, 0x00, IPT_KEYBOARD) PORT_NAME("Unknown 3")
PORT_BIT(0x80, 0x00, IPT_KEYBOARD) PORT_NAME("Unknown 4")
PORT_START("JOY0")
PORT_BIT( 0xff, 0x60, IPT_AD_STICK_X) PORT_SENSITIVITY(40) PORT_KEYDELTA(0) PORT_MINMAX(0x00,0xcf ) PORT_PLAYER(1)
PORT_START("JOY1")
PORT_BIT( 0xff, 0x60, IPT_AD_STICK_Y) PORT_SENSITIVITY(40) PORT_KEYDELTA(0) PORT_MINMAX(0x00,0xcf ) PORT_PLAYER(1) PORT_REVERSE
PORT_START("JOY2")
PORT_BIT( 0xff, 0x60, IPT_AD_STICK_X) PORT_SENSITIVITY(40) PORT_KEYDELTA(0) PORT_MINMAX(0x00,0xcf ) PORT_PLAYER(2)
PORT_START("JOY3")
PORT_BIT( 0xff, 0x60, IPT_AD_STICK_Y) PORT_SENSITIVITY(40) PORT_KEYDELTA(0) PORT_MINMAX(0x00,0xcf ) PORT_PLAYER(2) PORT_REVERSE
/* Joystick Keypad */
/* keypads were organized a 3 x 4 matrix and it looked */
/* exactly like a our northern telephone numerical pads */
/* The addressing was done with a single clear bit 0..6 */
/* on i/o port A, while all other bits were set. */
/* (e.g. 0xFE addresses keypad1 row 0, 0xEF keypad2 row 1) */
/* bit 0 1 2 3 */
/* FE/F7 0 [3] [6] [9] [#] */
/* FD/EF 1 [2] [5] [8] [0] */
/* FB/DF 2 [1] [4] [7] [*] */
/* 2008-05 FP: temporarily I mapped these as follows:
- Joy 1 at Keypad
- Joy 2 at a Joystick buttons
A better mapping would be needed...
*/
PORT_START("KP0")
PORT_BIT(0x01, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 1 [3]") PORT_CODE(KEYCODE_3_PAD)
PORT_BIT(0x02, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 1 [6]") PORT_CODE(KEYCODE_6_PAD)
PORT_BIT(0x04, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 1 [9]") PORT_CODE(KEYCODE_9_PAD)
PORT_BIT(0x08, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 1 [#]") PORT_CODE(KEYCODE_SLASH_PAD)
PORT_START("KP1")
PORT_BIT(0x01, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 1 [2]") PORT_CODE(KEYCODE_2_PAD)
PORT_BIT(0x02, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 1 [5]") PORT_CODE(KEYCODE_5_PAD)
PORT_BIT(0x04, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 1 [8]") PORT_CODE(KEYCODE_8_PAD)
PORT_BIT(0x08, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 1 [0]") PORT_CODE(KEYCODE_0_PAD)
PORT_START("KP2")
PORT_BIT(0x01, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 1 [1]") PORT_CODE(KEYCODE_1_PAD)
PORT_BIT(0x02, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 1 [4]") PORT_CODE(KEYCODE_4_PAD)
PORT_BIT(0x04, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 1 [7]") PORT_CODE(KEYCODE_7_PAD)
PORT_BIT(0x08, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 1 [*]") PORT_CODE(KEYCODE_ASTERISK)
PORT_START("KP3")
PORT_BIT(0x01, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 2 [3]") PORT_CODE(JOYCODE_BUTTON2)
PORT_BIT(0x02, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 2 [6]") PORT_CODE(JOYCODE_BUTTON5)
PORT_BIT(0x04, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 2 [9]")
PORT_BIT(0x08, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 2 [#]") PORT_CODE(JOYCODE_BUTTON1)
PORT_START("KP4")
PORT_BIT(0x01, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 2 [2]") PORT_CODE(JOYCODE_BUTTON2)
PORT_BIT(0x02, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 2 [5]") PORT_CODE(JOYCODE_BUTTON5)
PORT_BIT(0x04, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 2 [8]")
PORT_BIT(0x08, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 2 [0]")
PORT_START("KP5")
PORT_BIT(0x01, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 2 [1]") PORT_CODE(JOYCODE_BUTTON1)
PORT_BIT(0x02, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 2 [4]") PORT_CODE(JOYCODE_BUTTON4)
PORT_BIT(0x04, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 2 [7]")
PORT_BIT(0x08, 0x00, IPT_KEYBOARD) PORT_NAME("Joy 2 [*]") PORT_CODE(JOYCODE_BUTTON1)
PORT_START("RST")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_TAB) PORT_NAME("Rst") PORT_CHAR(9) PORT_CHANGED_MEMBER(DEVICE_SELF, cgenie_state, rst_callback, NULL)
INPUT_PORTS_END
static const gfx_layout cgenie_charlayout =
//**************************************************************************
// KEYBOARD
//**************************************************************************
READ8_MEMBER( cgenie_state::keyboard_r )
{
8,8, /* 8*8 characters */
384, /* 256 fixed + 128 defineable characters */
1, /* 1 bits per pixel */
{ 0 }, /* no bitplanes; 1 bit per pixel */
{ 0, 1, 2, 3, 4, 5, 6, 7 }, /* x offsets */
{ 0*8,1*8,2*8,3*8,4*8,5*8,6*8,7*8 },
8*8 /* every char takes 8 bytes */
};
int data = 0;
static const gfx_layout cgenie_gfxlayout =
{
8,8, /* 4*8 characters */
256, /* 256 graphics patterns */
2, /* 2 bits per pixel */
{ 0, 1 }, /* two bitplanes; 2 bit per pixel */
{ 0, 0, 2, 2, 4, 4, 6, 6}, /* x offsets */
{ 0*8,1*8,2*8,3*8,4*8,5*8,6*8,7*8 },
8*8 /* every char takes 8 bytes */
};
for (int i = 0; i < 8; i++)
if (BIT(offset, i))
data |= m_keyboard[i]->read();
static GFXDECODE_START( cgenie )
GFXDECODE_ENTRY( "gfx1", 0, cgenie_charlayout, 0, 3*16 )
GFXDECODE_ENTRY( "gfx2", 0, cgenie_gfxlayout, 3*16*2, 3*4 )
GFXDECODE_END
static const unsigned char cgenie_colors[] = {
0x00,0x00,0x00, /* background */
0x5e,0x5e,0x5e, /* gray */
0x11,0xff,0xea, /* cyan */
0xff,0x00,0x5e, /* red */
0xea,0xea,0xea, /* white */
0xff,0xf9,0x00, /* yellow */
0x6e,0xff,0x00, /* green */
0xff,0x52,0x00, /* orange */
0xea,0xff,0x00, /* light yellow */
0x02,0x48,0xff, /* blue */
0x8e,0xd4,0xff, /* light blue */
0xff,0x12,0xff, /* pink */
0x88,0x43,0xff, /* purple */
0x8c,0x8c,0x8c, /* light gray */
0x00,0xfb,0x8c, /* turquoise */
0xd2,0x00,0xff, /* magenta */
0xff,0xff,0xff, /* bright white */
#if 0
0*4, 0*4, 0*4, /* background */
/* this is the 'RGB monitor' version, strong and clean */
15*4, 15*4, 15*4, /* gray */
0*4, 48*4, 48*4, /* cyan */
60*4, 0*4, 0*4, /* red */
47*4, 47*4, 47*4, /* white */
55*4, 55*4, 0*4, /* yellow */
0*4, 56*4, 0*4, /* green */
42*4, 32*4, 0*4, /* orange */
63*4, 63*4, 0*4, /* light yellow */
0*4, 0*4, 48*4, /* blue */
0*4, 24*4, 63*4, /* light blue */
60*4, 0*4, 38*4, /* pink */
38*4, 0*4, 60*4, /* purple */
31*4, 31*4, 31*4, /* light gray */
0*4, 63*4, 63*4, /* light cyan */
58*4, 0*4, 58*4, /* magenta */
63*4, 63*4, 63*4, /* bright white */
#endif
/* this is the 'TV screen' version, weak and blurred by repeating pixels */
15*2+80, 15*2+80, 15*2+80, /* gray */
0*2+80, 48*2+80, 48*2+80, /* cyan */
60*2+80, 0*2+80, 0*2+80, /* red */
47*2+80, 47*2+80, 47*2+80, /* white */
55*2+80, 55*2+80, 0*2+80, /* yellow */
0*2+80, 56*2+80, 0*2+80, /* green */
42*2+80, 32*2+80, 0*2+80, /* orange */
63*2+80, 63*2+80, 0*2+80, /* light yellow */
0*2+80, 0*2+80, 48*2+80, /* blue */
0*2+80, 24*2+80, 63*2+80, /* light blue */
60*2+80, 0*2+80, 38*2+80, /* pink */
38*2+80, 0*2+80, 60*2+80, /* purple */
31*2+80, 31*2+80, 31*2+80, /* light gray */
0*2+80, 63*2+80, 63*2+80, /* light cyan */
58*2+80, 0*2+80, 58*2+80, /* magenta */
63*2+80, 63*2+80, 63*2+80, /* bright white */
15*2+96, 15*2+96, 15*2+96, /* gray */
0*2+96, 48*2+96, 48*2+96, /* cyan */
60*2+96, 0*2+96, 0*2+96, /* red */
47*2+96, 47*2+96, 47*2+96, /* white */
55*2+96, 55*2+96, 0*2+96, /* yellow */
0*2+96, 56*2+96, 0*2+96, /* green */
42*2+96, 32*2+96, 0*2+96, /* orange */
63*2+96, 63*2+96, 0*2+96, /* light yellow */
0*2+96, 0*2+96, 48*2+96, /* blue */
0*2+96, 24*2+96, 63*2+96, /* light blue */
60*2+96, 0*2+96, 38*2+96, /* pink */
38*2+96, 0*2+96, 60*2+96, /* purple */
31*2+96, 31*2+96, 31*2+96, /* light gray */
0*2+96, 63*2+96, 63*2+96, /* light cyan */
58*2+96, 0*2+96, 58*2+96, /* magenta */
63*2+96, 63*2+96, 63*2+96, /* bright white */
};
static const unsigned char cgenienz_colors[] = {
0x00,0x00,0x00, /* background */
0xff,0xff,0xff, /* gray */
0x12,0xff,0xff, /* cyan */
0xff,0x6f,0xff, /* red */
0x31,0x77,0xff, /* white */
0xff,0xcb,0x00, /* yellow */
0x6e,0xff,0x00, /* green */
0xff,0x52,0x00, /* orange */
0x5e,0x5e,0x5e, /* light yellow */
0xea,0xea,0xea, /* blue */
0x00,0xff,0xdd, /* light blue */
0xd2,0x00,0xff, /* pink */
0x02,0x48,0xff, /* purple */
0xff,0xf9,0x00, /* light gray */
0x00,0xda,0x00, /* light cyan */
0xff,0x22,0x00, /* magenta */
0x00,0x00,0x00, /* bright white */
/* this is the 'TV screen' version, weak and blurred by repeating pixels */
15*2+80, 15*2+80, 15*2+80, /* gray */
0*2+80, 48*2+80, 48*2+80, /* cyan */
60*2+80, 0*2+80, 0*2+80, /* red */
47*2+80, 47*2+80, 47*2+80, /* white */
55*2+80, 55*2+80, 0*2+80, /* yellow */
0*2+80, 56*2+80, 0*2+80, /* green */
42*2+80, 32*2+80, 0*2+80, /* orange */
63*2+80, 63*2+80, 0*2+80, /* light yellow */
0*2+80, 0*2+80, 48*2+80, /* blue */
0*2+80, 24*2+80, 63*2+80, /* light blue */
60*2+80, 0*2+80, 38*2+80, /* pink */
38*2+80, 0*2+80, 60*2+80, /* purple */
31*2+80, 31*2+80, 31*2+80, /* light gray */
0*2+80, 63*2+80, 63*2+80, /* light cyan */
58*2+80, 0*2+80, 58*2+80, /* magenta */
63*2+80, 63*2+80, 63*2+80, /* bright white */
15*2+96, 15*2+96, 15*2+96, /* gray */
0*2+96, 48*2+96, 48*2+96, /* cyan */
60*2+96, 0*2+96, 0*2+96, /* red */
47*2+96, 47*2+96, 47*2+96, /* white */
55*2+96, 55*2+96, 0*2+96, /* yellow */
0*2+96, 56*2+96, 0*2+96, /* green */
42*2+96, 32*2+96, 0*2+96, /* orange */
63*2+96, 63*2+96, 0*2+96, /* light yellow */
0*2+96, 0*2+96, 48*2+96, /* blue */
0*2+96, 24*2+96, 63*2+96, /* light blue */
60*2+96, 0*2+96, 38*2+96, /* pink */
38*2+96, 0*2+96, 60*2+96, /* purple */
31*2+96, 31*2+96, 31*2+96, /* light gray */
0*2+96, 63*2+96, 63*2+96, /* light cyan */
58*2+96, 0*2+96, 58*2+96, /* magenta */
63*2+96, 63*2+96, 63*2+96, /* bright white */
};
static const unsigned short cgenie_palette[] =
{
0, 1, 0, 2, 0, 3, 0, 4, /* RGB monitor set of text colors */
0, 5, 0, 6, 0, 7, 0, 8,
0, 9, 0,10, 0,11, 0,12,
0,13, 0,14, 0,15, 0,16,
0,17, 0,18, 0,19, 0,20, /* TV set text colors: darker */
0,21, 0,22, 0,23, 0,24,
0,25, 0,26, 0,27, 0,28,
0,29, 0,30, 0,31, 0,32,
0,33, 0,34, 0,35, 0,36, /* TV set text colors: a bit brighter */
0,37, 0,38, 0,39, 0,40,
0,41, 0,42, 0,43, 0,44,
0,45, 0,46, 0,47, 0,48,
0, 9, 7, 6, /* RGB monitor graphics colors */
0, 25, 23, 22, /* TV set graphics colors: darker */
0, 41, 39, 38, /* TV set graphics colors: a bit brighter */
};
/* Initialize the palette */
PALETTE_INIT_MEMBER(cgenie_state,cgenie)
{
UINT8 i, r, g, b;
for ( i = 0; i < 49; i++ )
{
r = cgenie_colors[i*3]; g = cgenie_colors[i*3+1]; b = cgenie_colors[i*3+2];
palette.set_indirect_color(i, rgb_t(r, g, b));
return data;
}
for(i=0; i<108; i++)
palette.set_pen_indirect(i, cgenie_palette[i]);
}
PALETTE_INIT_MEMBER(cgenie_state,cgenienz)
INPUT_CHANGED_MEMBER( cgenie_state::rst_callback )
{
UINT8 i, r, g, b;
for ( i = 0; i < 49; i++ )
{
r = cgenienz_colors[i*3]; g = cgenienz_colors[i*3+1]; b = cgenienz_colors[i*3+2];
palette.set_indirect_color(i, rgb_t(r, g, b));
}
for(i=0; i<108; i++)
palette.set_pen_indirect(i, cgenie_palette[i]);
m_maincpu->set_input_line(INPUT_LINE_NMI, newval);
}
static MACHINE_CONFIG_START( cgenie_common, cgenie_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", Z80, XTAL_17_73447MHz/8) /* 2,2168 MHz */
//**************************************************************************
// CONTROL PORT & RS232
//**************************************************************************
WRITE8_MEMBER( cgenie_state::control_w )
{
// cassette output
m_cassette->output(BIT(data, 0) ? -1.0 : 1.0);
// serial output
m_rs232->write_txd(BIT(data, 1));
// background color selection
if (BIT(data, 2))
m_background_color = m_palette_bg[4];
else
m_background_color = m_palette_bg[data >> 6 & 0x03];
// graphics/text mode switch
m_crtc->set_hpixels_per_column(BIT(data, 5) ? 4 : 8);
m_control = data;
}
READ8_MEMBER( cgenie_state::control_r )
{
UINT8 data = 0;
data |= m_cassette->input() > 0 ? 1 : 0;
data |= m_rs232_rx << 1;
data |= m_rs232_dcd << 2;
return data;
}
WRITE_LINE_MEMBER( cgenie_state::rs232_rx_w )
{
m_rs232_rx = state;
}
WRITE_LINE_MEMBER( cgenie_state::rs232_dcd_w )
{
m_rs232_dcd = state;
}
//**************************************************************************
// DRIVER INIT
//**************************************************************************
DRIVER_INIT_MEMBER( cgenie_state, cgenie_eu )
{
m_palette = &m_palette_eu[0];
}
DRIVER_INIT_MEMBER( cgenie_state, cgenie_nz )
{
m_palette = &m_palette_nz[0];
}
void cgenie_state::machine_start()
{
// setup ram
m_maincpu->space(AS_PROGRAM).install_ram(0x4000, 0x4000 + m_ram->size() - 1, m_ram->pointer());
// setup expansion bus
m_exp->set_program_space(&m_maincpu->space(AS_PROGRAM));
m_exp->set_io_space(&m_maincpu->space(AS_IO));
}
//**************************************************************************
// VIDEO EMULATION
//**************************************************************************
READ8_MEMBER( cgenie_state::colorram_r )
{
return m_color_ram[offset] | 0xf0;
}
WRITE8_MEMBER( cgenie_state::colorram_w )
{
m_color_ram[offset] = data & 0x0f;
}
MC6845_BEGIN_UPDATE( cgenie_state::crtc_begin_update )
{
bitmap.fill(m_background_color, cliprect);
}
MC6845_UPDATE_ROW( cgenie_state::crtc_update_row )
{
// don't need to do anything in vblank
if (!de)
return;
for (int column = 0; column < x_count; column++)
{
UINT8 code = m_ram->pointer()[ma + column];
UINT8 color = m_color_ram[(ma & 0xbff) + column];
// gfx mode?
if (BIT(m_control, 5))
{
const rgb_t map[] = { m_background_color, m_palette[8], m_palette[6], m_palette[5] };
bitmap.pix32(y + vbp, column * 4 + hbp + 0) = map[code >> 6 & 0x03];
bitmap.pix32(y + vbp, column * 4 + hbp + 1) = map[code >> 4 & 0x03];
bitmap.pix32(y + vbp, column * 4 + hbp + 2) = map[code >> 2 & 0x03];
bitmap.pix32(y + vbp, column * 4 + hbp + 3) = map[code >> 0 & 0x03];
}
else
{
UINT8 gfx = 0;
// cursor visible?
if (cursor_x == column)
gfx = 0xff;
// or use character rom?
else if ((code < 128) || (code < 192 && BIT(m_control, 4)) || (code > 192 && BIT(m_control, 3)))
gfx = m_char_rom->base()[(code << 3) | ra];
// or the programmable characters?
else
gfx = m_font_ram[((code << 3) | ra) & 0x3ff];
// 8 pixel chars
for (int p = 0; p < 8; p++)
bitmap.pix32(y + vbp, column * 8 + hbp + p) = BIT(gfx, 7 - p) ? m_palette[color] : m_background_color;
}
}
}
//**************************************************************************
// PALETTE
//**************************************************************************
// how accurate are these colors?
const rgb_t cgenie_state::m_palette_bg[] =
{
rgb_t::black,
rgb_t(0x70, 0x28, 0x20), // dark orange
rgb_t(0x28, 0x70, 0x20), // dark green
rgb_t(0x48, 0x48, 0x48), // dark gray
rgb_t(0x70, 0x00, 0x70) // dark purple
};
// european palette
const rgb_t cgenie_state::m_palette_eu[] =
{
rgb_t(0x5e, 0x5e, 0x5e), // gray
rgb_t(0x11, 0xff, 0xea), // cyan
rgb_t(0xff, 0x00, 0x5e), // red
rgb_t(0xea, 0xea, 0xea), // white
rgb_t(0xff, 0xf9, 0x00), // yellow
rgb_t(0x6e, 0xff, 0x00), // green
rgb_t(0xff, 0x52, 0x00), // orange
rgb_t(0xea, 0xff, 0x00), // light yellow
rgb_t(0x02, 0x48, 0xff), // blue
rgb_t(0x8e, 0xd4, 0xff), // light blue
rgb_t(0xff, 0x12, 0xff), // pink
rgb_t(0x88, 0x43, 0xff), // purple
rgb_t(0x8c, 0x8c, 0x8c), // light gray
rgb_t(0x00, 0xfb, 0x8c), // turquoise
rgb_t(0xd2, 0x00, 0xff), // magenta
rgb_t::white // bright white
};
// new zealand palette
const rgb_t cgenie_state::m_palette_nz[] =
{
rgb_t::white,
rgb_t(0x12, 0xff, 0xff),
rgb_t(0xff, 0x6f, 0xff),
rgb_t(0x31, 0x77, 0xff),
rgb_t(0xff, 0xcb, 0x00),
rgb_t(0x6e, 0xff, 0x00),
rgb_t(0xff, 0x52, 0x00),
rgb_t(0x5e, 0x5e, 0x5e),
rgb_t(0xea, 0xea, 0xea),
rgb_t(0x00, 0xff, 0xdd),
rgb_t(0xd2, 0x00, 0xff),
rgb_t(0x02, 0x48, 0xff),
rgb_t(0xff, 0xf9, 0x00),
rgb_t(0x00, 0xda, 0x00),
rgb_t(0xff, 0x22, 0x00),
rgb_t::black
};
//**************************************************************************
// MACHINE DEFINTIONS
//**************************************************************************
static MACHINE_CONFIG_START( cgenie, cgenie_state )
// basic machine hardware
MCFG_CPU_ADD("maincpu", Z80, XTAL_17_73447MHz / 8) // 2.2168 MHz
MCFG_CPU_PROGRAM_MAP(cgenie_mem)
MCFG_CPU_IO_MAP(cgenie_io)
MCFG_CPU_VBLANK_INT_DRIVER("screen", cgenie_state, cgenie_frame_interrupt)
MCFG_CPU_PERIODIC_INT_DRIVER(cgenie_state, cgenie_timer_interrupt, 40)
MCFG_QUANTUM_TIME(attotime::from_hz(240))
/* video hardware */
// video hardware
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(50)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
MCFG_SCREEN_SIZE(48*8, 32*8)
MCFG_SCREEN_VISIBLE_AREA(0*8, 48*8-1,0*8,32*8-1)
MCFG_SCREEN_UPDATE_DRIVER(cgenie_state, screen_update_cgenie)
MCFG_SCREEN_PALETTE("palette")
MCFG_SCREEN_RAW_PARAMS(XTAL_17_73447MHz / 2, 568, 32, 416, 312, 28, 284)
MCFG_SCREEN_UPDATE_DEVICE("crtc", mc6845_device, screen_update)
MCFG_GFXDECODE_ADD("gfxdecode", "palette", cgenie )
MCFG_PALETTE_ADD("palette", 108)
MCFG_PALETTE_INDIRECT_ENTRIES(49)
MCFG_MC6845_ADD("crtc", MC6845_1, "screen", XTAL_17_73447MHz / 16)
MCFG_MC6845_SHOW_BORDER_AREA(true)
MCFG_MC6845_CHAR_WIDTH(8)
MCFG_MC6845_BEGIN_UPDATE_CB(cgenie_state, crtc_begin_update)
MCFG_MC6845_UPDATE_ROW_CB(cgenie_state, crtc_update_row)
// Actually the video is driven by an HD46505 clocked at XTAL_17_73447MHz/16
/* sound hardware */
// sound hardware
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("dac", DAC, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
MCFG_SOUND_ADD("ay8910", AY8910, XTAL_17_73447MHz / 8)
MCFG_AY8910_PORT_A_READ_CB(READ8(cgenie_state, cgenie_psg_port_a_r))
MCFG_AY8910_PORT_B_READ_CB(READ8(cgenie_state, cgenie_psg_port_b_r))
MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(cgenie_state, cgenie_psg_port_a_w))
MCFG_AY8910_PORT_B_WRITE_CB(WRITE8(cgenie_state, cgenie_psg_port_b_w))
MCFG_AY8910_PORT_A_READ_CB(DEVREAD8("par", parallel_slot_device, pa_r))
MCFG_AY8910_PORT_A_WRITE_CB(DEVWRITE8("par", parallel_slot_device, pa_w))
MCFG_AY8910_PORT_B_READ_CB(DEVREAD8("par", parallel_slot_device, pb_r))
MCFG_AY8910_PORT_B_WRITE_CB(DEVWRITE8("par", parallel_slot_device, pb_w))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
MCFG_CASSETTE_ADD("cassette")
@ -498,8 +464,17 @@ static MACHINE_CONFIG_START( cgenie_common, cgenie_state )
MCFG_SOFTWARE_LIST_ADD("cass_list", "cgenie_cass")
// serial port
MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, NULL)
MCFG_RS232_RXD_HANDLER(WRITELINE(cgenie_state, rs232_rx_w))
MCFG_RS232_DCD_HANDLER(WRITELINE(cgenie_state, rs232_dcd_w))
// cartridge expansion slot
MCFG_EXPANSION_SLOT_ADD("exp")
MCFG_EXPANSION_SLOT_INT_HANDLER(WRITELINE(cgenie_state, exp_intrq_w))
MCFG_EXPANSION_SLOT_INT_HANDLER(INPUTLINE("maincpu", INPUT_LINE_IRQ0))
// parallel slot
MCFG_PARALLEL_SLOT_ADD("par")
// internal ram
MCFG_RAM_ADD(RAM_TAG)
@ -507,31 +482,23 @@ static MACHINE_CONFIG_START( cgenie_common, cgenie_state )
MCFG_RAM_EXTRA_OPTIONS("32K")
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( cgenie, cgenie_common )
MCFG_PALETTE_MODIFY("palette")
MCFG_PALETTE_INIT_OWNER(cgenie_state, cgenie )
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( cgenienz, cgenie_common )
MCFG_PALETTE_MODIFY("palette")
MCFG_PALETTE_INIT_OWNER(cgenie_state, cgenienz )
MACHINE_CONFIG_END
/***************************************************************************
Game driver(s)
***************************************************************************/
//**************************************************************************
// ROM DEFINITIONS
//**************************************************************************
ROM_START( cgenie )
ROM_REGION(0x4000, "maincpu", 0)
ROM_LOAD("cgenie.rom", 0x0000, 0x4000, CRC(d359ead7) SHA1(d8c2fc389ad38c45fba0ed556a7d91abac5463f4))
ROM_LOAD("cg_rom1.z1", 0x0000, 0x1000, CRC(d3369420) SHA1(fe7f06f8e2b648d695d4787d00a374d3e4ac5d39))
ROM_LOAD("cg_rom2.z2", 0x1000, 0x1000, CRC(73d2c9ea) SHA1(343d595b4eeaea627f9c36d5cef3827c79593425))
ROM_LOAD("cg_rom3.z3", 0x2000, 0x1000, CRC(3f358811) SHA1(6ba151759fd8fd367806cf2dd5f1dfc33ee9521f))
ROM_LOAD("cg_rom4.z4", 0x3000, 0x1000, CRC(be235782) SHA1(d7d61208a9855ffd09ecb051618f5ed6a8816f3f))
ROM_REGION(0x0c00, "gfx1", 0)
ROM_REGION(0x0800, "gfx1", 0)
// this is a "german" character set with umlauts, is this official?
ROM_LOAD("cgenieg.fnt", 0x0000, 0x0800, CRC(c3e60d57) SHA1(fb96f608fdb47391145fdcd614a9c7a79756e6a4))
// default character set
ROM_LOAD("cgenie1.fnt", 0x0000, 0x0800, CRC(4fed774a) SHA1(d53df8212b521892cc56be690db0bb474627d2ff))
/* Empty memory region for the character generator */
ROM_REGION(0x0800, "gfx2", ROMREGION_ERASEFF)
ROM_END
ROM_START( cgenienz )
@ -541,14 +508,15 @@ ROM_START( cgenienz )
ROM_SYSTEM_BIOS(1, "new", "New ROM")
ROMX_LOAD("cgromv2.rom", 0x0000, 0x4000, CRC(cfb84e09) SHA1(e199e4429bab6f9fca2bb05e71324538928a693a), ROM_BIOS(2))
ROM_REGION(0x0c00, "gfx1", 0)
ROM_REGION(0x0800, "gfx1", 0)
ROM_LOAD("cgenie1.fnt", 0x0000, 0x0800, CRC(4fed774a) SHA1(d53df8212b521892cc56be690db0bb474627d2ff))
/* Empty memory region for the character generator */
ROM_REGION(0x0800, "gfx2", ROMREGION_ERASEFF)
ROM_END
/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME */
COMP( 1982, cgenie, 0, 0, cgenie, cgenie, driver_device, 0, "EACA Computers Ltd", "Colour Genie EG2000" , 0)
COMP( 1982, cgenienz, cgenie, 0, cgenienz, cgenie, driver_device, 0, "EACA Computers Ltd", "Colour Genie EG2000 (New Zealand)" , 0)
//**************************************************************************
// SYSTEM DRIVERS
//**************************************************************************
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
COMP( 1982, cgenie, 0, 0, cgenie, cgenie, cgenie_state, cgenie_eu, "EACA", "Colour Genie EG2000", 0)
COMP( 1982, cgenienz, cgenie, 0, cgenie, cgenie, cgenie_state, cgenie_nz, "EACA", "Colour Genie EG2000 (New Zealand)", 0)

View File

@ -1,139 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Nathan Woods
/*****************************************************************************
*
* includes/cgenie.h
*
****************************************************************************/
#ifndef CGENIE_H_
#define CGENIE_H_
#include "imagedev/cassette.h"
#include "machine/ram.h"
#include "sound/ay8910.h"
#include "bus/cgenie/expansion.h"
// CRTC 6845
struct CRTC6845
{
UINT8 cursor_address_lo;
UINT8 cursor_address_hi;
UINT8 screen_address_lo;
UINT8 screen_address_hi;
UINT8 cursor_bottom;
UINT8 cursor_top;
UINT8 scan_lines;
UINT8 crt_mode;
UINT8 vertical_sync_pos;
UINT8 vertical_displayed;
UINT8 vertical_adjust;
UINT8 vertical_total;
UINT8 horizontal_length;
UINT8 horizontal_sync_pos;
UINT8 horizontal_displayed;
UINT8 horizontal_total;
UINT8 idx;
UINT8 cursor_visible;
UINT8 cursor_phase;
};
class cgenie_state : public driver_device
{
public:
cgenie_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_colorram(*this, "colorram"),
m_fontram(*this, "fontram"),
m_maincpu(*this, "maincpu"),
m_cassette(*this, "cassette"),
m_ram(*this, RAM_TAG),
m_ay8910(*this, "ay8910"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
m_screen(*this, "screen"),
m_exp(*this, "exp")
{
}
required_shared_ptr<UINT8> m_colorram;
required_shared_ptr<UINT8> m_fontram;
UINT8 *m_videoram;
int m_tv_mode;
int m_font_offset[4];
int m_port_ff;
UINT8 m_irq_status;
UINT8 m_cass_level;
UINT8 m_cass_bit;
UINT8 m_psg_a_out;
UINT8 m_psg_b_out;
UINT8 m_psg_a_inp;
UINT8 m_psg_b_inp;
UINT8 m_control_port;
CRTC6845 m_crt;
int m_graphics;
bitmap_ind16 m_bitmap;
bitmap_ind16 m_dlybitmap;
int m_off_x;
int m_off_y;
virtual void machine_start();
virtual void machine_reset();
virtual void video_start();
DECLARE_PALETTE_INIT(cgenie);
DECLARE_PALETTE_INIT(cgenienz);
UINT32 screen_update_cgenie(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(cgenie_timer_interrupt);
INTERRUPT_GEN_MEMBER(cgenie_frame_interrupt);
TIMER_CALLBACK_MEMBER(handle_cassette_input);
DECLARE_WRITE_LINE_MEMBER(exp_intrq_w);
DECLARE_READ8_MEMBER(cgenie_sh_control_port_r);
DECLARE_WRITE8_MEMBER(cgenie_sh_control_port_w);
required_device<cpu_device> m_maincpu;
required_device<cassette_image_device> m_cassette;
required_device<ram_device> m_ram;
required_device<ay8910_device> m_ay8910;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<screen_device> m_screen;
required_device<expansion_slot_device> m_exp;
void cgenie_offset_xy();
int cgenie_get_register(int indx);
void cgenie_mode_select(int mode);
void cgenie_refresh_monitor(bitmap_ind16 &bitmap, const rectangle &cliprect);
void cgenie_refresh_tv_set(bitmap_ind16 &bitmap, const rectangle &cliprect);
int cgenie_port_xx_r( int offset );
int cgenie_videoram_r( int offset );
DECLARE_READ8_MEMBER( cgenie_psg_port_a_r );
DECLARE_READ8_MEMBER( cgenie_psg_port_b_r );
DECLARE_WRITE8_MEMBER( cgenie_psg_port_a_w );
DECLARE_WRITE8_MEMBER( cgenie_psg_port_b_w );
DECLARE_READ8_MEMBER( cgenie_colorram_r );
DECLARE_READ8_MEMBER( cgenie_fontram_r );
DECLARE_WRITE8_MEMBER( cgenie_colorram_w );
DECLARE_WRITE8_MEMBER( cgenie_fontram_w );
DECLARE_WRITE8_MEMBER( cgenie_port_ff_w );
DECLARE_READ8_MEMBER( cgenie_port_ff_r );
DECLARE_READ8_MEMBER( cgenie_irq_status_r );
DECLARE_READ8_MEMBER( cgenie_keyboard_r );
DECLARE_WRITE8_MEMBER( cgenie_videoram_w );
DECLARE_READ8_MEMBER( cgenie_index_r );
DECLARE_READ8_MEMBER( cgenie_register_r );
DECLARE_WRITE8_MEMBER( cgenie_index_w );
DECLARE_WRITE8_MEMBER( cgenie_register_w );
};
#endif /* CGENIE_H_ */

View File

@ -1,432 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Nathan Woods
/***************************************************************************
machine.c
Functions to emulate general aspects of the machine
(RAM, ROM, interrupts, I/O ports)
***************************************************************************/
#include "emu.h"
#include "cpu/z80/z80.h"
#include "includes/cgenie.h"
#include "imagedev/cassette.h"
#include "sound/dac.h"
#include "machine/ram.h"
#define AYWriteReg(chip,port,value) \
m_ay8910->address_w(space, 0,port); \
m_ay8910->data_w(space, 0,value)
#define TAPE_HEADER "Colour Genie - Virtual Tape File"
#define IRQ_TIMER 0x80
#define IRQ_FDC 0x40
TIMER_CALLBACK_MEMBER(cgenie_state::handle_cassette_input)
{
UINT8 new_level = ( (m_cassette->input()) > 0.0 ) ? 1 : 0;
if ( new_level != m_cass_level )
{
m_cass_level = new_level;
m_cass_bit ^= 1;
}
}
void cgenie_state::machine_reset()
{
address_space &space = m_maincpu->space(AS_PROGRAM);
UINT8 *ROM = memregion("maincpu")->base();
/* reset the AY8910 to be quiet, since the cgenie BIOS doesn't */
AYWriteReg(0, 0, 0);
AYWriteReg(0, 1, 0);
AYWriteReg(0, 2, 0);
AYWriteReg(0, 3, 0);
AYWriteReg(0, 4, 0);
AYWriteReg(0, 5, 0);
AYWriteReg(0, 6, 0);
AYWriteReg(0, 7, 0x3f);
AYWriteReg(0, 8, 0);
AYWriteReg(0, 9, 0);
AYWriteReg(0, 10, 0);
/* wipe out color RAM */
memset(&ROM[0x0f000], 0x00, 0x0400);
/* wipe out font RAM */
memset(&ROM[0x0f400], 0xff, 0x0400);
m_cass_level = 0;
m_cass_bit = 1;
}
void cgenie_state::machine_start()
{
address_space &space = m_maincpu->space(AS_PROGRAM);
UINT8 *gfx = memregion("gfx2")->base();
int i;
/* initialize static variables */
m_irq_status = 0;
m_tv_mode = -1;
m_port_ff = 0xff;
/*
* Every fifth cycle is a wait cycle, so I reduced
* the overlocking by one fitfth
* Underclocking causes the tape loading to not work.
*/
// cpunum_set_clockscale(machine(), 0, 0.80);
/* Initialize some patterns to be displayed in graphics mode */
for( i = 0; i < 256; i++ )
memset(gfx + i * 8, i, 8);
/* set up RAM */
space.install_read_bank(0x4000, 0x4000 + m_ram->size() - 1, "bank1");
space.install_write_handler(0x4000, 0x4000 + m_ram->size() - 1, write8_delegate(FUNC(cgenie_state::cgenie_videoram_w),this));
m_videoram = m_ram->pointer();
membank("bank1")->set_base(m_ram->pointer());
machine().scheduler().timer_pulse(attotime::from_hz(11025), timer_expired_delegate(FUNC(cgenie_state::handle_cassette_input),this));
// setup expansion bus
m_exp->set_program_space(&m_maincpu->space(AS_PROGRAM));
m_exp->set_io_space(&m_maincpu->space(AS_IO));
}
/*************************************
*
* Port handlers.
*
*************************************/
/* used bits on port FF */
#define FF_CAS 0x01 /* tape output signal */
#define FF_BGD0 0x04 /* background color enable */
#define FF_CHR1 0x08 /* charset 0xc0 - 0xff 1:fixed 0:defined */
#define FF_CHR0 0x10 /* charset 0x80 - 0xbf 1:fixed 0:defined */
#define FF_CHR (FF_CHR0 | FF_CHR1)
#define FF_FGR 0x20 /* 1: "hi" resolution graphics, 0: text mode */
#define FF_BGD1 0x40 /* background color select 1 */
#define FF_BGD2 0x80 /* background color select 2 */
#define FF_BGD (FF_BGD0 | FF_BGD1 | FF_BGD2)
WRITE8_MEMBER( cgenie_state::cgenie_port_ff_w )
{
int port_ff_changed = m_port_ff ^ data;
m_cassette->output(data & 0x01 ? -1.0 : 1.0 );
/* background bits changed ? */
if( port_ff_changed & FF_BGD )
{
unsigned char r, g, b;
if( data & FF_BGD0 )
{
r = 112;
g = 0;
b = 112;
}
else
{
if( m_tv_mode == 0 )
{
switch( data & (FF_BGD1 + FF_BGD2) )
{
case FF_BGD1:
r = 112;
g = 40;
b = 32;
break;
case FF_BGD2:
r = 40;
g = 112;
b = 32;
break;
case FF_BGD1 + FF_BGD2:
r = 72;
g = 72;
b = 72;
break;
default:
r = 0;
g = 0;
b = 0;
break;
}
}
else
{
r = 15;
g = 15;
b = 15;
}
}
m_palette->set_pen_color(0, r, g, b);
}
/* character mode changed ? */
if( port_ff_changed & FF_CHR )
{
m_font_offset[2] = (data & FF_CHR0) ? 0x00 : 0x80;
m_font_offset[3] = (data & FF_CHR1) ? 0x00 : 0x80;
}
/* graphics mode changed ? */
if( port_ff_changed & FF_FGR )
{
cgenie_mode_select(data & FF_FGR);
}
m_port_ff = data;
}
READ8_MEMBER( cgenie_state::cgenie_port_ff_r )
{
UINT8 data = m_port_ff & ~0x01;
data |= m_cass_bit;
return data;
}
int cgenie_state::cgenie_port_xx_r( int offset )
{
return 0xff;
}
/*************************************
* *
* Memory handlers *
* *
*************************************/
READ8_MEMBER( cgenie_state::cgenie_psg_port_a_r )
{
return m_psg_a_inp;
}
READ8_MEMBER( cgenie_state::cgenie_psg_port_b_r )
{
if( m_psg_a_out < 0xd0 )
{
/* comparator value */
m_psg_b_inp = 0x00;
if( ioport("JOY0")->read() > m_psg_a_out )
m_psg_b_inp |= 0x80;
if( ioport("JOY1")->read() > m_psg_a_out )
m_psg_b_inp |= 0x40;
if( ioport("JOY2")->read() > m_psg_a_out )
m_psg_b_inp |= 0x20;
if( ioport("JOY3")->read() > m_psg_a_out )
m_psg_b_inp |= 0x10;
}
else
{
/* read keypad matrix */
m_psg_b_inp = 0xFF;
if( !(m_psg_a_out & 0x01) )
m_psg_b_inp &= ~ioport("KP0")->read();
if( !(m_psg_a_out & 0x02) )
m_psg_b_inp &= ~ioport("KP1")->read();
if( !(m_psg_a_out & 0x04) )
m_psg_b_inp &= ~ioport("KP2")->read();
if( !(m_psg_a_out & 0x08) )
m_psg_b_inp &= ~ioport("KP3")->read();
if( !(m_psg_a_out & 0x10) )
m_psg_b_inp &= ~ioport("KP4")->read();
if( !(m_psg_a_out & 0x20) )
m_psg_b_inp &= ~ioport("KP5")->read();
}
return m_psg_b_inp;
}
WRITE8_MEMBER( cgenie_state::cgenie_psg_port_a_w )
{
m_psg_a_out = data;
}
WRITE8_MEMBER( cgenie_state::cgenie_psg_port_b_w )
{
m_psg_b_out = data;
}
READ8_MEMBER( cgenie_state::cgenie_irq_status_r )
{
int result = m_irq_status;
m_irq_status &= ~(IRQ_TIMER);
return result;
}
INTERRUPT_GEN_MEMBER(cgenie_state::cgenie_timer_interrupt)
{
if( (m_irq_status & IRQ_TIMER) == 0 )
{
m_irq_status |= IRQ_TIMER;
m_maincpu->set_input_line(0, HOLD_LINE);
}
}
WRITE_LINE_MEMBER( cgenie_state::exp_intrq_w )
{
m_irq_status &= ~IRQ_FDC;
m_irq_status |= state << 6;
if (m_irq_status)
m_maincpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE);
else
m_maincpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE);
}
/*************************************
* Keyboard *
*************************************/
READ8_MEMBER( cgenie_state::cgenie_keyboard_r )
{
int result = 0;
if( offset & 0x01 )
result |= ioport("ROW0")->read();
if( offset & 0x02 )
result |= ioport("ROW1")->read();
if( offset & 0x04 )
result |= ioport("ROW2")->read();
if( offset & 0x08 )
result |= ioport("ROW3")->read();
if( offset & 0x10 )
result |= ioport("ROW4")->read();
if( offset & 0x20 )
result |= ioport("ROW5")->read();
if( offset & 0x40 )
result |= ioport("ROW6")->read();
if( offset & 0x80 )
result |= ioport("ROW7")->read();
return result;
}
/*************************************
* Video RAM *
*************************************/
int cgenie_state::cgenie_videoram_r( int offset )
{
UINT8 *videoram = m_videoram;
return videoram[offset];
}
WRITE8_MEMBER( cgenie_state::cgenie_videoram_w )
{
UINT8 *videoram = m_videoram;
/* write to video RAM */
if( data == videoram[offset] )
return; /* no change */
videoram[offset] = data;
}
READ8_MEMBER( cgenie_state::cgenie_colorram_r )
{
return m_colorram[offset] | 0xf0;
}
WRITE8_MEMBER( cgenie_state::cgenie_colorram_w )
{
/* only bits 0 to 3 */
data &= 15;
/* nothing changed ? */
if( data == m_colorram[offset] )
return;
/* set new value */
m_colorram[offset] = data;
/* make offset relative to video frame buffer offset */
offset = (offset + (cgenie_get_register(12) << 8) + cgenie_get_register(13)) & 0x3ff;
}
READ8_MEMBER( cgenie_state::cgenie_fontram_r )
{
return m_fontram[offset];
}
WRITE8_MEMBER( cgenie_state::cgenie_fontram_w )
{
UINT8 *dp;
if( data == m_fontram[offset] )
return; /* no change */
/* store data */
m_fontram[offset] = data;
/* convert eight pixels */
dp = const_cast<UINT8 *>(m_gfxdecode->gfx(0)->get_data(256 + offset/8) + (offset % 8) * m_gfxdecode->gfx(0)->width());
dp[0] = (data & 0x80) ? 1 : 0;
dp[1] = (data & 0x40) ? 1 : 0;
dp[2] = (data & 0x20) ? 1 : 0;
dp[3] = (data & 0x10) ? 1 : 0;
dp[4] = (data & 0x08) ? 1 : 0;
dp[5] = (data & 0x04) ? 1 : 0;
dp[6] = (data & 0x02) ? 1 : 0;
dp[7] = (data & 0x01) ? 1 : 0;
}
/*************************************
*
* Interrupt handlers.
*
*************************************/
INTERRUPT_GEN_MEMBER(cgenie_state::cgenie_frame_interrupt)
{
if( m_tv_mode != (ioport("DSW0")->read() & 0x10) )
{
m_tv_mode = ioport("DSW0")->read() & 0x10;
/* force setting of background color */
m_port_ff ^= FF_BGD0;
cgenie_port_ff_w(m_maincpu->space(AS_PROGRAM), 0, m_port_ff ^ FF_BGD0);
}
}
READ8_MEMBER(cgenie_state::cgenie_sh_control_port_r)
{
return m_control_port;
}
WRITE8_MEMBER(cgenie_state::cgenie_sh_control_port_w)
{
m_control_port = data;
m_ay8910->address_w(space, offset, data);
}

View File

@ -1,412 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Nathan Woods
/***************************************************************************
cgenie.c
Functions to emulate the video controller 6845.
***************************************************************************/
#include "emu.h"
#include "includes/cgenie.h"
/***************************************************************************
Start the video hardware emulation.
***************************************************************************/
void cgenie_state::video_start()
{
m_screen->register_screen_bitmap(m_dlybitmap);
m_screen->register_screen_bitmap(m_bitmap);
}
/***************************************************************************
Calculate the horizontal and vertical offset for the
current register settings of the 6845 CRTC
***************************************************************************/
void cgenie_state::cgenie_offset_xy()
{
if( m_crt.horizontal_sync_pos )
m_off_x = m_crt.horizontal_total - m_crt.horizontal_sync_pos - 14;
else
m_off_x = -15;
m_off_y = (m_crt.vertical_total - m_crt.vertical_sync_pos) *
(m_crt.scan_lines + 1) + m_crt.vertical_adjust
- 32;
if( m_off_y < 0 )
m_off_y = 0;
if( m_off_y > 128 )
m_off_y = 128;
// logerror("cgenie offset x:%d y:%d\n", m_off_x, m_off_y);
}
/***************************************************************************
Write to an indexed register of the 6845 CRTC
***************************************************************************/
WRITE8_MEMBER( cgenie_state::cgenie_register_w )
{
//int addr;
switch (m_crt.idx)
{
case 0:
if( m_crt.horizontal_total == data )
break;
m_crt.horizontal_total = data;
cgenie_offset_xy();
break;
case 1:
if( m_crt.horizontal_displayed == data )
break;
m_crt.horizontal_displayed = data;
break;
case 2:
if( m_crt.horizontal_sync_pos == data )
break;
m_crt.horizontal_sync_pos = data;
cgenie_offset_xy();
break;
case 3:
m_crt.horizontal_length = data;
break;
case 4:
if( m_crt.vertical_total == data )
break;
m_crt.vertical_total = data;
cgenie_offset_xy();
break;
case 5:
if( m_crt.vertical_adjust == data )
break;
m_crt.vertical_adjust = data;
cgenie_offset_xy();
break;
case 6:
if( m_crt.vertical_displayed == data )
break;
m_crt.vertical_displayed = data;
break;
case 7:
if( m_crt.vertical_sync_pos == data )
break;
m_crt.vertical_sync_pos = data;
cgenie_offset_xy();
break;
case 8:
m_crt.crt_mode = data;
break;
case 9:
data &= 15;
if( m_crt.scan_lines == data )
break;
m_crt.scan_lines = data;
cgenie_offset_xy();
break;
case 10:
if( m_crt.cursor_top == data )
break;
m_crt.cursor_top = data;
//addr = 256 * m_crt.cursor_address_hi + m_crt.cursor_address_lo;
break;
case 11:
if( m_crt.cursor_bottom == data )
break;
m_crt.cursor_bottom = data;
//addr = 256 * m_crt.cursor_address_hi + m_crt.cursor_address_lo;
break;
case 12:
data &= 63;
if( m_crt.screen_address_hi == data )
break;
m_crt.screen_address_hi = data;
break;
case 13:
if( m_crt.screen_address_lo == data )
break;
m_crt.screen_address_lo = data;
break;
case 14:
data &= 63;
if( m_crt.cursor_address_hi == data )
break;
m_crt.cursor_address_hi = data;
//addr = 256 * m_crt.cursor_address_hi + m_crt.cursor_address_lo;
break;
case 15:
if( m_crt.cursor_address_lo == data )
break;
m_crt.cursor_address_lo = data;
//addr = 256 * m_crt.cursor_address_hi + m_crt.cursor_address_lo;
break;
}
}
/***************************************************************************
Write to the index register of the 6845 CRTC
***************************************************************************/
WRITE8_MEMBER( cgenie_state::cgenie_index_w )
{
m_crt.idx = data & 15;
}
/***************************************************************************
Read from an indexed register of the 6845 CRTC
***************************************************************************/
READ8_MEMBER( cgenie_state::cgenie_register_r )
{
return cgenie_get_register(m_crt.idx);
}
/***************************************************************************
Read from a register of the 6845 CRTC
***************************************************************************/
int cgenie_state::cgenie_get_register(int indx)
{
switch (indx)
{
case 0:
return m_crt.horizontal_total;
case 1:
return m_crt.horizontal_displayed;
case 2:
return m_crt.horizontal_sync_pos;
case 3:
return m_crt.horizontal_length;
case 4:
return m_crt.vertical_total;
case 5:
return m_crt.vertical_adjust;
case 6:
return m_crt.vertical_displayed;
case 7:
return m_crt.vertical_sync_pos;
case 8:
return m_crt.crt_mode;
case 9:
return m_crt.scan_lines;
case 10:
return m_crt.cursor_top;
case 11:
return m_crt.cursor_bottom;
case 12:
return m_crt.screen_address_hi;
case 13:
return m_crt.screen_address_lo;
case 14:
return m_crt.cursor_address_hi;
case 15:
return m_crt.cursor_address_lo;
}
return 0;
}
/***************************************************************************
Read the index register of the 6845 CRTC
***************************************************************************/
READ8_MEMBER( cgenie_state::cgenie_index_r )
{
return m_crt.idx;
}
/***************************************************************************
Switch mode between character generator and graphics
***************************************************************************/
void cgenie_state::cgenie_mode_select(int mode)
{
m_graphics = (mode) ? 1 : 0;
}
void cgenie_state::cgenie_refresh_monitor(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
UINT8 *videoram = m_videoram;
int i, address, offset, cursor, size, code, x, y;
rectangle r;
bitmap.fill(m_palette->black_pen(), cliprect);
if(m_crt.vertical_displayed || m_crt.horizontal_displayed)
{
offset = 256 * m_crt.screen_address_hi + m_crt.screen_address_lo;
size = m_crt.horizontal_displayed * m_crt.vertical_displayed;
cursor = 256 * m_crt.cursor_address_hi + m_crt.cursor_address_lo;
/*
* for every character in the Video RAM, check if it has been modified since
* last time and update it accordingly.
*/
for( address = 0; address < size; address++ )
{
i = (offset + address) & 0x3fff;
x = address % m_crt.horizontal_displayed + m_off_x;
y = address / m_crt.horizontal_displayed;
r.min_x = x * 8;
r.max_x = r.min_x + 7;
r.min_y = y * (m_crt.scan_lines + 1) + m_off_y;
r.max_y = r.min_y + m_crt.scan_lines;
if( m_graphics )
{
/* get graphics code */
code = videoram[i];
m_gfxdecode->gfx(1)->opaque(bitmap,r, code, 0,
0, 0, r.min_x, r.min_y);
}
else
{
/* get character code */
code = videoram[i];
/* translate defined character sets */
code += m_font_offset[(code >> 6) & 3];
m_gfxdecode->gfx(0)->opaque(bitmap,r, code, m_colorram[i&0x3ff],
0, 0, r.min_x, r.min_y);
}
if( i == cursor )
{
rectangle rc;
/* check if cursor turned off */
if( (m_crt.cursor_top & 0x60) == 0x20 )
continue;
if( (m_crt.cursor_top & 0x60) == 0x60 )
{
m_crt.cursor_visible = 1;
}
else
{
m_crt.cursor_phase++;
m_crt.cursor_visible = (m_crt.cursor_phase >> 3) & 1;
}
if( !m_crt.cursor_visible )
continue;
rc.min_x = r.min_x;
rc.max_x = r.max_x;
rc.min_y = r.min_y + (m_crt.cursor_top & 15);
rc.max_y = r.min_y + (m_crt.cursor_bottom & 15);
m_gfxdecode->gfx(0)->opaque(bitmap,rc, 0x7f, m_colorram[i&0x3ff],
0, 0, rc.min_x, rc.min_y);
}
}
}
}
void cgenie_state::cgenie_refresh_tv_set(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
UINT8 *videoram = m_videoram;
int i, address, offset, cursor, size, code, x, y;
rectangle r;
m_bitmap.fill(m_palette->black_pen(), cliprect);
m_dlybitmap.fill(m_palette->black_pen(), cliprect);
if(m_crt.vertical_displayed || m_crt.horizontal_displayed)
{
offset = 256 * m_crt.screen_address_hi + m_crt.screen_address_lo;
size = m_crt.horizontal_displayed * m_crt.vertical_displayed;
cursor = 256 * m_crt.cursor_address_hi + m_crt.cursor_address_lo;
/*
* for every character in the Video RAM, check if it has been modified since
* last time and update it accordingly.
*/
for( address = 0; address < size; address++ )
{
i = (offset + address) & 0x3fff;
x = address % m_crt.horizontal_displayed + m_off_x;
y = address / m_crt.horizontal_displayed;
r.min_x = x * 8;
r.max_x = r.min_x + 7;
r.min_y = y * (m_crt.scan_lines + 1) + m_off_y;
r.max_y = r.min_y + m_crt.scan_lines;
if( m_graphics )
{
/* get graphics code */
code = videoram[i];
m_gfxdecode->gfx(1)->opaque(m_bitmap,r, code, 1,
0, 0, r.min_x, r.min_y);
m_gfxdecode->gfx(1)->opaque(m_dlybitmap,r, code, 2,
0, 0, r.min_x, r.min_y);
}
else
{
/* get character code */
code = videoram[i];
/* translate defined character sets */
code += m_font_offset[(code >> 6) & 3];
m_gfxdecode->gfx(0)->opaque(m_bitmap,r, code, m_colorram[i&0x3ff] + 16,
0, 0, r.min_x, r.min_y);
m_gfxdecode->gfx(0)->opaque(m_dlybitmap,r, code, m_colorram[i&0x3ff] + 32,
0, 0, r.min_x, r.min_y);
}
if( i == cursor )
{
rectangle rc;
/* check if cursor turned off */
if( (m_crt.cursor_top & 0x60) == 0x20 )
continue;
if( (m_crt.cursor_top & 0x60) == 0x60 )
{
m_crt.cursor_visible = 1;
}
else
{
m_crt.cursor_phase++;
m_crt.cursor_visible = (m_crt.cursor_phase >> 3) & 1;
}
if( !m_crt.cursor_visible )
continue;
rc.min_x = r.min_x;
rc.max_x = r.max_x;
rc.min_y = r.min_y + (m_crt.cursor_top & 15);
rc.max_y = r.min_y + (m_crt.cursor_bottom & 15);
m_gfxdecode->gfx(0)->opaque(m_bitmap,rc, 0x7f, m_colorram[i&0x3ff] + 16,
0, 0, rc.min_x, rc.min_y);
m_gfxdecode->gfx(0)->opaque(m_dlybitmap,rc, 0x7f, m_colorram[i&0x3ff] + 32,
0, 0, rc.min_x, rc.min_y);
}
}
}
copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect);
copybitmap_trans(bitmap, m_dlybitmap, 0, 0, 1, 0, cliprect, 0);
}
/***************************************************************************
Draw the game screen in the given bitmap_ind16.
***************************************************************************/
UINT32 cgenie_state::screen_update_cgenie(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
if( m_tv_mode )
cgenie_refresh_tv_set(bitmap, cliprect);
else
cgenie_refresh_monitor(bitmap, cliprect);
return 0;
}