From 7f12847c282f432171bc92abeeb1d1bd93ce3533 Mon Sep 17 00:00:00 2001 From: Sergey Svishchev Date: Tue, 14 Mar 2017 03:03:25 +0300 Subject: agat: split from apple2, implement basic agat7 hardware (take 2). --- scripts/src/bus.lua | 4 + scripts/target/mame/mess.lua | 9 + src/devices/bus/a2bus/a2diskii.cpp | 16 + src/devices/bus/a2bus/a2diskii.h | 9 + src/devices/bus/a2bus/agat7langcard.cpp | 156 +++++ src/devices/bus/a2bus/agat7langcard.h | 57 ++ src/devices/bus/a2bus/agat7ram.cpp | 140 ++++ src/devices/bus/a2bus/agat7ram.h | 55 ++ src/emu/drivers/xtal.h | 2 + src/mame/drivers/agat.cpp | 1115 +++++++++++++++++++++++++++++++ src/mame/drivers/apple2.cpp | 31 - src/mame/mame.lst | 6 +- src/mame/mess.flt | 1 + src/mame/video/agat7.cpp | 375 +++++++++++ src/mame/video/agat7.h | 75 +++ 15 files changed, 2018 insertions(+), 33 deletions(-) create mode 100644 src/devices/bus/a2bus/agat7langcard.cpp create mode 100644 src/devices/bus/a2bus/agat7langcard.h create mode 100644 src/devices/bus/a2bus/agat7ram.cpp create mode 100644 src/devices/bus/a2bus/agat7ram.h create mode 100644 src/mame/drivers/agat.cpp create mode 100644 src/mame/video/agat7.cpp create mode 100644 src/mame/video/agat7.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index df699c95229..299133ef55e 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -1649,6 +1649,10 @@ if (BUSES["A2BUS"]~=null) then MAME_DIR .. "src/devices/bus/a2bus/ezcgi.h", MAME_DIR .. "src/devices/bus/a2bus/pc_xporter.cpp", MAME_DIR .. "src/devices/bus/a2bus/pc_xporter.h", + MAME_DIR .. "src/devices/bus/a2bus/agat7langcard.cpp", + MAME_DIR .. "src/devices/bus/a2bus/agat7langcard.h", + MAME_DIR .. "src/devices/bus/a2bus/agat7ram.cpp", + MAME_DIR .. "src/devices/bus/a2bus/agat7ram.h", } end diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index f91d4edd87c..62c4ab78c12 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -880,6 +880,7 @@ function linkProjects_mame_mess(_target, _subtarget) "acorn", "act", "adc", + "agat", "alesis", "altos", "ami", @@ -1323,6 +1324,14 @@ files { MAME_DIR .. "src/mame/includes/superslave.h", } +createMESSProjects(_target, _subtarget, "agat") +files { + MAME_DIR .. "src/mame/drivers/agat.cpp", + MAME_DIR .. "src/mame/includes/apple2.h", + MAME_DIR .. "src/mame/video/agat7.cpp", + MAME_DIR .. "src/mame/video/agat7.h", +} + createMESSProjects(_target, _subtarget, "alesis") files { MAME_DIR .. "src/mame/drivers/alesis.cpp", diff --git a/src/devices/bus/a2bus/a2diskii.cpp b/src/devices/bus/a2bus/a2diskii.cpp index a32ec42430b..a28cc19076b 100644 --- a/src/devices/bus/a2bus/a2diskii.cpp +++ b/src/devices/bus/a2bus/a2diskii.cpp @@ -25,6 +25,7 @@ const device_type A2BUS_DISKII = device_creator; const device_type A2BUS_IWM_FDC = device_creator; +const device_type A2BUS_AGAT7_FDC = device_creator; #define DISKII_ROM_REGION "diskii_rom" #define FDC_TAG "diskii_fdc" @@ -61,6 +62,11 @@ ROM_START( diskii ) ROM_LOAD( "341-0027-a.p5", 0x000000, 0x000100, CRC(ce7144f6) SHA1(d4181c9f046aafc3fb326b381baac809d9e38d16) ) ROM_END +ROM_START( agat7 ) + ROM_REGION(0x100, DISKII_ROM_REGION, 0) + ROM_LOAD( "shugart7.rom", 0x0000, 0x0100, CRC(c6e4850c) SHA1(71626d3d2d4bbeeac2b77585b45a5566d20b8d34) ) +ROM_END + //------------------------------------------------- // machine_config_additions - device-specific // machine configurations @@ -85,6 +91,11 @@ const tiny_rom_entry *a2bus_floppy_device::device_rom_region() const return ROM_NAME( diskii ); } +const tiny_rom_entry *a2bus_agat7flop_device::device_rom_region() const +{ + return ROM_NAME( agat7 ); +} + //************************************************************************** // LIVE DEVICE //************************************************************************** @@ -106,6 +117,11 @@ a2bus_iwmflop_device::a2bus_iwmflop_device(const machine_config &mconfig, const { } +a2bus_agat7flop_device::a2bus_agat7flop_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + a2bus_floppy_device(mconfig, A2BUS_AGAT7_FDC, "Agat-7 140K floppy card", tag, owner, clock, "agat7_flop", __FILE__) +{ +} + //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- diff --git a/src/devices/bus/a2bus/a2diskii.h b/src/devices/bus/a2bus/a2diskii.h index 56b4c5dd1f5..9d17757a144 100644 --- a/src/devices/bus/a2bus/a2diskii.h +++ b/src/devices/bus/a2bus/a2diskii.h @@ -59,8 +59,17 @@ public: virtual machine_config_constructor device_mconfig_additions() const override; }; +class a2bus_agat7flop_device: public a2bus_floppy_device +{ +public: + a2bus_agat7flop_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual const tiny_rom_entry *device_rom_region() const override; +}; + // device type definition extern const device_type A2BUS_DISKII; extern const device_type A2BUS_IWM_FDC; +extern const device_type A2BUS_AGAT7_FDC; #endif /* __A2BUS_DISKII__ */ diff --git a/src/devices/bus/a2bus/agat7langcard.cpp b/src/devices/bus/a2bus/agat7langcard.cpp new file mode 100644 index 00000000000..fba82f8dcd2 --- /dev/null +++ b/src/devices/bus/a2bus/agat7langcard.cpp @@ -0,0 +1,156 @@ +// license:BSD-3-Clause +// copyright-holders:Sergey Svishchev +/********************************************************************* + + agat7langcard.c + + Implemention of the Agat-7 language card + +*********************************************************************/ + +#include "agat7langcard.h" + +/*************************************************************************** + PARAMETERS +***************************************************************************/ + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type A2BUS_AGAT7LANGCARD = device_creator; + +/*************************************************************************** + FUNCTION PROTOTYPES +***************************************************************************/ + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +a2bus_agat7langcard_device::a2bus_agat7langcard_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source) : + device_t(mconfig, type, name, tag, owner, clock, shortname, source), + device_a2bus_card_interface(mconfig, *this), m_inh_state(0), m_last_offset(0), m_dxxx_bank(0), m_main_bank(0) +{ +} + +a2bus_agat7langcard_device::a2bus_agat7langcard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, A2BUS_AGAT7LANGCARD, "Agat-7 32K Language Card", tag, owner, clock, "a7lang", __FILE__), + device_a2bus_card_interface(mconfig, *this), m_inh_state(0), m_last_offset(0), m_dxxx_bank(0), m_main_bank(0) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void a2bus_agat7langcard_device::device_start() +{ + // set_a2bus_device makes m_slot valid + set_a2bus_device(); + + memset(m_ram, 0, 32*1024); + + save_item(NAME(m_inh_state)); + save_item(NAME(m_ram)); + save_item(NAME(m_dxxx_bank)); + save_item(NAME(m_main_bank)); + save_item(NAME(m_last_offset)); +} + +void a2bus_agat7langcard_device::device_reset() +{ + m_inh_state = INH_NONE; + m_dxxx_bank = 0; + m_main_bank = 0; + m_last_offset = -1; + m_mode = 0; +} + +void a2bus_agat7langcard_device::do_io(int offset) +{ + int old_inh_state = m_inh_state; + + m_last_offset = offset; + + m_inh_state = INH_WRITE; + m_dxxx_bank = 0; + m_main_bank = (offset & 1) * 0x4000; + + if (offset & 0x20) + { + m_inh_state = INH_READ; + } + + if (offset & 0x40) + { + m_dxxx_bank = 0x1000; + } + + if (m_inh_state != old_inh_state) + { + recalc_slot_inh(); + } + +#if 1 + logerror("LC: (ofs %02x) new state %c%c dxxx=%04x main=%05x\n", + offset, + (m_inh_state & INH_READ) ? 'R' : 'x', + (m_inh_state & INH_WRITE) ? 'W' : 'x', + m_dxxx_bank, m_main_bank); +#endif +} + + +/*------------------------------------------------- + read_cnxx - called for reads from this card's cnxx space +-------------------------------------------------*/ + +uint8_t a2bus_agat7langcard_device::read_cnxx(address_space &space, uint8_t offset) +{ + return m_last_offset < 0 ? 0x80 : (0x80 | m_last_offset); +} + + +/*------------------------------------------------- + write_cnxx - called for writes to this card's cnxx space +-------------------------------------------------*/ + +void a2bus_agat7langcard_device::write_cnxx(address_space &space, uint8_t offset, uint8_t data) +{ + do_io(offset); +} + +uint8_t a2bus_agat7langcard_device::read_inh_rom(address_space &space, uint16_t offset) +{ + assert(m_inh_state & INH_READ); // this should never happen + + if (offset < 0xe000) + { + return m_ram[(offset & 0xfff) + m_dxxx_bank + m_main_bank]; + } + + return m_ram[(offset & 0x1fff) + 0x2000 + m_main_bank]; +} + +void a2bus_agat7langcard_device::write_inh_rom(address_space &space, uint16_t offset, uint8_t data) +{ + // are writes enabled? + if (!(m_inh_state & INH_WRITE)) + { + return; + } + + if (offset < 0xe000) + { + m_ram[(offset & 0xfff) + m_dxxx_bank + m_main_bank] = data; + return; + } + + m_ram[(offset & 0x1fff) + 0x2000 + m_main_bank] = data; +} + +int a2bus_agat7langcard_device::inh_type() +{ + return m_inh_state; +} diff --git a/src/devices/bus/a2bus/agat7langcard.h b/src/devices/bus/a2bus/agat7langcard.h new file mode 100644 index 00000000000..ea7b80e5075 --- /dev/null +++ b/src/devices/bus/a2bus/agat7langcard.h @@ -0,0 +1,57 @@ +// license:BSD-3-Clause +// copyright-holders:Sergey Svishchev +/********************************************************************* + + agat7langcard.h + + Implemention of the Agat-7 language card + +*********************************************************************/ + +#ifndef __A2BUS_AGAT7LANGCARD__ +#define __A2BUS_AGAT7LANGCARD__ + +#include "emu.h" +#include "a2bus.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class a2bus_agat7langcard_device: + public device_t, + public device_a2bus_card_interface +{ +public: + // construction/destruction + a2bus_agat7langcard_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source); + a2bus_agat7langcard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + // overrides of standard a2bus slot functions + virtual uint8_t read_cnxx(address_space &space, uint8_t offset) override; + virtual void write_cnxx(address_space &space, uint8_t offset, uint8_t data) override; + virtual uint8_t read_inh_rom(address_space &space, uint16_t offset) override; + virtual void write_inh_rom(address_space &space, uint16_t offset, uint8_t data) override; + virtual uint16_t inh_start() override { return 0xd000; } + virtual uint16_t inh_end() override { return 0xffff; } + virtual int inh_type() override; + +private: + void do_io(int offset); + + int m_inh_state; + int m_last_offset; + int m_dxxx_bank; + int m_main_bank; + uint8_t m_ram[32*1024]; + uint8_t m_mode; +}; + +// device type definition +extern const device_type A2BUS_AGAT7LANGCARD; + +#endif /* __A2BUS_AGAT7LANGCARD__ */ diff --git a/src/devices/bus/a2bus/agat7ram.cpp b/src/devices/bus/a2bus/agat7ram.cpp new file mode 100644 index 00000000000..694d6c65daa --- /dev/null +++ b/src/devices/bus/a2bus/agat7ram.cpp @@ -0,0 +1,140 @@ +// license:BSD-3-Clause +// copyright-holders:Sergey Svishchev +/********************************************************************* + + agat7ram.c + + Implemention of the Agat-7 RAM card + +*********************************************************************/ + +#include "agat7ram.h" + +/*************************************************************************** + PARAMETERS +***************************************************************************/ + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type A2BUS_AGAT7RAM = device_creator; + +/*************************************************************************** + FUNCTION PROTOTYPES +***************************************************************************/ + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +a2bus_agat7ram_device::a2bus_agat7ram_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source) : + device_t(mconfig, type, name, tag, owner, clock, shortname, source), + device_a2bus_card_interface(mconfig, *this), m_inh_state(0), m_last_offset(0), m_main_bank(0) +{ +} + +a2bus_agat7ram_device::a2bus_agat7ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, A2BUS_AGAT7RAM, "Agat-7 32K RAM Card", tag, owner, clock, "a7ram", __FILE__), + device_a2bus_card_interface(mconfig, *this), m_inh_state(0), m_last_offset(0), m_main_bank(0) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void a2bus_agat7ram_device::device_start() +{ + // set_a2bus_device makes m_slot valid + set_a2bus_device(); + + memset(m_ram, 0, 32*1024); + + save_item(NAME(m_inh_state)); + save_item(NAME(m_ram)); + save_item(NAME(m_main_bank)); + save_item(NAME(m_last_offset)); +} + +void a2bus_agat7ram_device::device_reset() +{ + m_inh_state = INH_NONE; + m_main_bank = 0; + m_last_offset = -1; +} + +void a2bus_agat7ram_device::do_io(int offset) +{ + int old_inh_state = m_inh_state; + + m_last_offset = offset; + m_inh_state = INH_NONE; + m_main_bank = 0; + + if (offset & 0x8) + { + m_inh_state = INH_READ|INH_WRITE; + } + + if (offset & 0x1) + { + m_main_bank = 0x4000; + } + + if (m_inh_state != old_inh_state) + { + recalc_slot_inh(); + } + +#if 1 + logerror("RAM: (ofs %02x) new state %c%c main=%05x\n", + offset, + (m_inh_state & INH_READ) ? 'R' : 'x', + (m_inh_state & INH_WRITE) ? 'W' : 'x', + m_main_bank); +#endif +} + + +/*------------------------------------------------- + read_cnxx - called for reads from this card's cnxx space +-------------------------------------------------*/ + +uint8_t a2bus_agat7ram_device::read_cnxx(address_space &space, uint8_t offset) +{ + return m_last_offset < 0 ? 0 : (m_last_offset & 0x7f); +} + + +/*------------------------------------------------- + write_cnxx - called for writes to this card's cnxx space +-------------------------------------------------*/ + +void a2bus_agat7ram_device::write_cnxx(address_space &space, uint8_t offset, uint8_t data) +{ + do_io(offset); +} + +uint8_t a2bus_agat7ram_device::read_inh_rom(address_space &space, uint16_t offset) +{ + assert(m_inh_state & INH_READ); // this should never happen + + return m_ram[(offset & 0x3fff) + m_main_bank]; +} + +void a2bus_agat7ram_device::write_inh_rom(address_space &space, uint16_t offset, uint8_t data) +{ + // are writes enabled? + if (!(m_inh_state & INH_WRITE)) + { + return; + } + + m_ram[(offset & 0x3fff) + m_main_bank] = data; +} + +int a2bus_agat7ram_device::inh_type() +{ + return m_inh_state; +} diff --git a/src/devices/bus/a2bus/agat7ram.h b/src/devices/bus/a2bus/agat7ram.h new file mode 100644 index 00000000000..451efb08e3e --- /dev/null +++ b/src/devices/bus/a2bus/agat7ram.h @@ -0,0 +1,55 @@ +// license:BSD-3-Clause +// copyright-holders:Sergey Svishchev +/********************************************************************* + + agat7ram.h + + Implemention of the Agat-7 RAM card + +*********************************************************************/ + +#ifndef __A2BUS_AGAT7RAM__ +#define __A2BUS_AGAT7RAM__ + +#include "emu.h" +#include "a2bus.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class a2bus_agat7ram_device: + public device_t, + public device_a2bus_card_interface +{ +public: + // construction/destruction + a2bus_agat7ram_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source); + a2bus_agat7ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + // overrides of standard a2bus slot functions + virtual uint8_t read_cnxx(address_space &space, uint8_t offset) override; + virtual void write_cnxx(address_space &space, uint8_t offset, uint8_t data) override; + virtual uint8_t read_inh_rom(address_space &space, uint16_t offset) override; + virtual void write_inh_rom(address_space &space, uint16_t offset, uint8_t data) override; + virtual uint16_t inh_start() override { return 0x8000; } + virtual uint16_t inh_end() override { return 0xbfff; } + virtual int inh_type() override; + +private: + void do_io(int offset); + + int m_inh_state; + int m_last_offset; + int m_main_bank; + uint8_t m_ram[32*1024]; +}; + +// device type definition +extern const device_type A2BUS_AGAT7RAM; + +#endif /* __A2BUS_AGAT7RAM__ */ diff --git a/src/emu/drivers/xtal.h b/src/emu/drivers/xtal.h index 7e9e809aed2..464e3d2a7ac 100644 --- a/src/emu/drivers/xtal.h +++ b/src/emu/drivers/xtal.h @@ -111,6 +111,7 @@ enum XTAL_9_987MHz = 9987000, /* Crazy Balloon */ XTAL_10MHz = 10000000, XTAL_10_245MHz = 10245000, /* PES Speech box */ + XTAL_10_5MHz = 10500000, /* Agat-7 */ XTAL_10_595MHz = 10595000, /* Mad Alien */ XTAL_10_6875MHz = 10687500, /* BBC Bridge Companion */ XTAL_10_69425MHz = 10694250, /* Xerox 820 */ @@ -141,6 +142,7 @@ enum XTAL_13_4952MHz = 13495200, /* Used on Shadow Force pcb and maybe other Technos pcbs? */ XTAL_14MHz = 14000000, XTAL_14_112MHz = 14112000, /* Timex/Sinclair TS2068 */ + XTAL_14_3MHz = 14300000, /* Agat-7 */ XTAL_14_314MHz = 14314000, /* Taito TTL Board */ XTAL_14_31818MHz = 14318181, /* Extremely common, used on 100's of PCBs (4x NTSC subcarrier) */ XTAL_14_705882MHz = 14705882, /* Aleck64 */ diff --git a/src/mame/drivers/agat.cpp b/src/mame/drivers/agat.cpp new file mode 100644 index 00000000000..f025a2818bd --- /dev/null +++ b/src/mame/drivers/agat.cpp @@ -0,0 +1,1115 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont, Sergey Svishchev +/*************************************************************************** + + agat.c + Skeleton driver for Agat series of Soviet Apple II non-clones + + These are similar to Apple II (same bus architecture, keyboard and + floppy interface), but video controller is completely different. + + To do: + - native keyboards (at least two variants) + - 840K floppy controller (MFM encoding, but track layout is unique) + - agat7: 64K and 128K onboard memory configurations + - agat9 + - 3rd party slot devices + +************************************************************************/ + +#include "emu.h" +#include "includes/apple2.h" +#include "video/agat7.h" + +#include "machine/bankdev.h" +#include "imagedev/flopdrv.h" + +#include "bus/a2bus/a2diskii.h" +#include "bus/a2bus/agat7langcard.h" +#include "bus/a2bus/agat7ram.h" + +#include "screen.h" +#include "softlist.h" +#include "speaker.h" + +#include "formats/ap2_dsk.h" + + +#define A7_CPU_TAG "maincpu" +#define A7_KBDC_TAG "ay3600" +#define A7_BUS_TAG "a2bus" +#define A7_SPEAKER_TAG "speaker" +#define A7_CASSETTE_TAG "tape" +#define A7_UPPERBANK_TAG "inhbank" +#define A7_VIDEO_TAG "a7video" + +class agat7_state : public driver_device +{ +public: + agat7_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, A7_CPU_TAG) + , m_ram(*this, RAM_TAG) + , m_ay3600(*this, A7_KBDC_TAG) + , m_video(*this, A7_VIDEO_TAG) + , m_a2bus(*this, A7_BUS_TAG) + , m_joy1x(*this, "joystick_1_x") + , m_joy1y(*this, "joystick_1_y") + , m_joy2x(*this, "joystick_2_x") + , m_joy2y(*this, "joystick_2_y") + , m_joybuttons(*this, "joystick_buttons") + , m_kbspecial(*this, "keyb_special") + , m_kbrepeat(*this, "keyb_repeat") + , m_speaker(*this, A7_SPEAKER_TAG) + , m_cassette(*this, A7_CASSETTE_TAG) + , m_upperbank(*this, A7_UPPERBANK_TAG) + { } + + required_device m_maincpu; + required_device m_ram; + required_device m_ay3600; + required_device m_video; + required_device m_a2bus; + required_ioport m_joy1x, m_joy1y, m_joy2x, m_joy2y, m_joybuttons; + required_ioport m_kbspecial; + required_ioport m_kbrepeat; + required_device m_speaker; + required_device m_cassette; + required_device m_upperbank; + + TIMER_DEVICE_CALLBACK_MEMBER(ay3600_repeat); + TIMER_DEVICE_CALLBACK_MEMBER(agat_timer); + TIMER_DEVICE_CALLBACK_MEMBER(agat_vblank); + + virtual void machine_start() override; + virtual void machine_reset() override; + + DECLARE_READ8_MEMBER(c000_r); + DECLARE_WRITE8_MEMBER(c000_w); + DECLARE_READ8_MEMBER(c080_r); + DECLARE_WRITE8_MEMBER(c080_w); + DECLARE_READ8_MEMBER(c100_r); + DECLARE_WRITE8_MEMBER(c100_w); + DECLARE_READ8_MEMBER(c800_r); + DECLARE_WRITE8_MEMBER(c800_w); + DECLARE_READ8_MEMBER(inh_r); + DECLARE_WRITE8_MEMBER(inh_w); + DECLARE_WRITE_LINE_MEMBER(a2bus_irq_w); + DECLARE_WRITE_LINE_MEMBER(a2bus_nmi_w); + DECLARE_WRITE_LINE_MEMBER(a2bus_inh_w); + DECLARE_READ_LINE_MEMBER(ay3600_shift_r); + DECLARE_READ_LINE_MEMBER(ay3600_control_r); + DECLARE_WRITE_LINE_MEMBER(ay3600_data_ready_w); + DECLARE_WRITE_LINE_MEMBER(ay3600_ako_w); + + DECLARE_READ8_MEMBER(agat7_membank_r); + DECLARE_WRITE8_MEMBER(agat7_membank_w); + DECLARE_READ8_MEMBER(agat7_ram_r); + DECLARE_WRITE8_MEMBER(agat7_ram_w); + +private: + int m_speaker_state; + int m_cassette_state; + + double m_joystick_x1_time; + double m_joystick_y1_time; + double m_joystick_x2_time; + double m_joystick_y2_time; + + uint16_t m_lastchar, m_strobe; + uint8_t m_transchar; + bool m_anykeydown; + + int m_inh_slot; + int m_cnxx_slot; + + bool m_page2; + bool m_an0, m_an1, m_an2, m_an3; + + uint8_t *m_ram_ptr; + int m_ram_size; + + int m_inh_bank; + + double m_x_calibration, m_y_calibration; + + device_a2bus_card_interface *m_slotdevice[8]; + + bool m_agat7_interrupts; + int m_agat7_membank; + int m_agat7_ram_slot; + + void do_io(address_space &space, int offset); + uint8_t read_floatingbus(); +}; + +/*************************************************************************** + PARAMETERS +***************************************************************************/ + +#define JOYSTICK_DELTA 80 +#define JOYSTICK_SENSITIVITY 50 +#define JOYSTICK_AUTOCENTER 80 + +WRITE_LINE_MEMBER(agat7_state::a2bus_irq_w) +{ + m_maincpu->set_input_line(M6502_IRQ_LINE, state); +} + +WRITE_LINE_MEMBER(agat7_state::a2bus_nmi_w) +{ + m_maincpu->set_input_line(INPUT_LINE_NMI, state); +} + +// This code makes a ton of assumptions because we can guarantee a pre-IIe machine! +WRITE_LINE_MEMBER(agat7_state::a2bus_inh_w) +{ + if (state == ASSERT_LINE) + { + // assume no cards are pulling /INH + m_inh_slot = -1; + m_agat7_ram_slot = -1; + + // scan the slots to figure out which card(s) are INHibiting stuff + for (int i = 0; i <= 7; i++) + { + if (m_slotdevice[i]) + { + // this driver only can inhibit from 0xd000-0xffff + if ((m_slotdevice[i]->inh_start() == 0xd000) && + (m_slotdevice[i]->inh_end() == 0xffff)) + { + if ((m_slotdevice[i]->inh_type() & INH_READ) == INH_READ) + { + if (m_inh_bank != 1) + { + m_upperbank->set_bank(1); + m_inh_bank = 1; + } + } + else + { + if (m_inh_bank != 0) + { + m_upperbank->set_bank(0); + m_inh_bank = 0; + } + } + + m_inh_slot = i; + // break; + } + + if ((m_slotdevice[i]->inh_start() == 0x8000) && + (m_slotdevice[i]->inh_end() == 0xbfff)) + { + if ((m_slotdevice[i]->inh_type() & INH_READ) == INH_READ) + { + m_agat7_ram_slot = i; + } + } + } + } + + // if no slots are inhibiting, make sure ROM is fully switched in + if ((m_inh_slot == -1) && (m_inh_bank != 0)) + { + m_upperbank->set_bank(0); + m_inh_bank = 0; + } + } +} + +/*************************************************************************** + START/RESET +***************************************************************************/ + +void agat7_state::machine_start() +{ + m_ram_ptr = m_ram->pointer(); + m_ram_size = m_ram->size(); + m_speaker_state = 0; + m_speaker->level_w(m_speaker_state); + m_cassette_state = 0; + m_cassette->output(-1.0f); + m_upperbank->set_bank(0); + m_inh_bank = 0; + + // precalculate joystick time constants + m_x_calibration = attotime::from_usec(12).as_double(); + m_y_calibration = attotime::from_usec(13).as_double(); + + // cache slot devices + for (int i = 0; i <= 7; i++) + { + m_slotdevice[i] = m_a2bus->get_a2bus_card(i); + } + + // setup save states + save_item(NAME(m_speaker_state)); + save_item(NAME(m_cassette_state)); + save_item(NAME(m_joystick_x1_time)); + save_item(NAME(m_joystick_y1_time)); + save_item(NAME(m_joystick_x2_time)); + save_item(NAME(m_joystick_y2_time)); + save_item(NAME(m_lastchar)); + save_item(NAME(m_strobe)); + save_item(NAME(m_transchar)); + save_item(NAME(m_inh_slot)); + save_item(NAME(m_inh_bank)); + save_item(NAME(m_cnxx_slot)); + save_item(NAME(m_page2)); + save_item(NAME(m_an0)); + save_item(NAME(m_an1)); + save_item(NAME(m_an2)); + save_item(NAME(m_an3)); + save_item(NAME(m_anykeydown)); + + // setup video pointers + m_video->m_ram_dev = machine().device(RAM_TAG); + m_video->m_char_ptr = memregion("gfx1")->base(); + m_video->m_char_size = memregion("gfx1")->bytes(); +} + +void agat7_state::machine_reset() +{ + m_inh_slot = -1; + m_cnxx_slot = -1; + m_page2 = false; + m_an0 = m_an1 = m_an2 = m_an3 = false; + m_anykeydown = false; + m_upperbank->set_bank(0); + m_agat7_interrupts = false; + m_agat7_membank = 0; + m_agat7_ram_slot = -1; +} + +/*************************************************************************** + VIDEO +***************************************************************************/ + +/*************************************************************************** + I/O +***************************************************************************/ +// most softswitches don't care about read vs write, so handle them here +void agat7_state::do_io(address_space &space, int offset) +{ + if (machine().side_effect_disabled()) + { + return; + } + + switch (offset & 0xf0) + { + case 0x20: + m_cassette_state ^= 1; + m_cassette->output(m_cassette_state ? 1.0f : -1.0f); + break; + + case 0x30: + m_speaker_state ^= 1; + m_speaker->level_w(m_speaker_state); + break; + + // XXX agat7: 0x4N -- enable timer interrupts, 0x5N -- disable (or vice versa depending on hw rev) + case 0x40: + m_agat7_interrupts = true; + break; + + case 0x50: + m_agat7_interrupts = false; + + case 0x70: + m_joystick_x1_time = machine().time().as_double() + m_x_calibration * m_joy1x->read(); + m_joystick_y1_time = machine().time().as_double() + m_y_calibration * m_joy1y->read(); + m_joystick_x2_time = machine().time().as_double() + m_x_calibration * m_joy2x->read(); + m_joystick_y2_time = machine().time().as_double() + m_y_calibration * m_joy2y->read(); + break; + } +} + +READ8_MEMBER(agat7_state::c000_r) +{ + if (offset) + logerror("%s: c000_r %04X == %02X\n", machine().describe_context(), offset+0xc000, 0); + else if (m_strobe) + logerror("%s: c000_r %04X == %02X\n", machine().describe_context(), offset+0xc000, m_transchar | m_strobe); + + switch (offset) + { + // keyboard latch. NB: agat7 returns 0 if latch is clear, agat9 returns char code. + case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: + case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: + return m_strobe ? (m_transchar | m_strobe) : 0; + + case 0x10: // reads any key down, clears strobe + { + uint8_t rv = m_transchar | (m_anykeydown ? 0x80 : 0x00); + m_strobe = 0; + return rv; + } + + case 0x60: // cassette in + case 0x68: + return m_cassette->input() > 0.0 ? 0x80 : 0; + + case 0x61: // button 0 + case 0x69: + return (m_joybuttons->read() & 0x10) ? 0x80 : 0; + + case 0x62: // button 1 + case 0x6a: + return (m_joybuttons->read() & 0x20) ? 0x80 : 0; + + case 0x63: // button 2 + case 0x6b: + return ((m_joybuttons->read() & 0x40) || (m_kbspecial->read() & 0x06)) ? 0 : 0x80; + + case 0x64: // joy 1 X axis + case 0x6c: + return (space.machine().time().as_double() < m_joystick_x1_time) ? 0x80 : 0; + + case 0x65: // joy 1 Y axis + case 0x6d: + return (space.machine().time().as_double() < m_joystick_y1_time) ? 0x80 : 0; + + case 0x66: // joy 2 X axis + case 0x6e: + return (space.machine().time().as_double() < m_joystick_x2_time) ? 0x80 : 0; + + case 0x67: // joy 2 Y axis + case 0x6f: + return (space.machine().time().as_double() < m_joystick_y2_time) ? 0x80 : 0; + + default: + do_io(space, offset); + break; + } + + return read_floatingbus(); +} + +WRITE8_MEMBER(agat7_state::c000_w) +{ + logerror("%s: c000_w %04X <- %02X\n", machine().describe_context(), offset + 0xc000, data); + + switch (offset) + { + // clear keyboard latch + case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: + case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: + m_strobe = 0; + break; + + default: + do_io(space, offset); + break; + } +} + +READ8_MEMBER(agat7_state::c080_r) +{ + if (!machine().side_effect_disabled()) + { + int slot; + + offset &= 0x7F; + slot = offset / 0x10; + + logerror("%s: c080_r %04X (slot %d) == %02X\n", machine().describe_context(), offset + 0xc080, slot, 0); + + if (m_slotdevice[slot] != nullptr) + { + return m_slotdevice[slot]->read_c0nx(space, offset % 0x10); + } + } + + return read_floatingbus(); +} + +WRITE8_MEMBER(agat7_state::c080_w) +{ + int slot; + + offset &= 0x7F; + slot = offset / 0x10; + + logerror("%s: c080_w %04X (slot %d) <- %02X\n", machine().describe_context(), offset + 0xc080, slot, data); + + if (m_slotdevice[slot] != nullptr) + { + m_slotdevice[slot]->write_c0nx(space, offset % 0x10, data); + } +} + +READ8_MEMBER(agat7_state::c100_r) +{ + int slotnum; + uint8_t data = 0; + + slotnum = ((offset >> 8) & 0xf) + 1; + + if (m_slotdevice[slotnum] != nullptr) + { + if ((m_slotdevice[slotnum]->take_c800()) && (!machine().side_effect_disabled())) + { + m_cnxx_slot = slotnum; + } + + logerror("%s: c100_r %04X (slot %d) == %02X\n", machine().describe_context(), offset+0xc100, slotnum, data); + + return m_slotdevice[slotnum]->read_cnxx(space, offset & 0xff); + } + + return read_floatingbus(); +} + +WRITE8_MEMBER(agat7_state::c100_w) +{ + int slotnum; + + slotnum = ((offset >> 8) & 0xf) + 1; + + logerror("%s: c100_w %04X (slot %d) <- %02X\n", machine().describe_context(), offset + 0xc100, slotnum, data); + + if (m_slotdevice[slotnum] != nullptr) + { + if ((m_slotdevice[slotnum]->take_c800()) && (!machine().side_effect_disabled())) + { + m_cnxx_slot = slotnum; + } + + m_slotdevice[slotnum]->write_cnxx(space, offset&0xff, data); + } +} + +READ8_MEMBER(agat7_state::c800_r) +{ +// logerror("%s: c800_r %04X (slot %d) == %02X\n", machine().describe_context(), offset+0xc800, m_cnxx_slot, 0); + + if (offset == 0x7ff) + { + if (!machine().side_effect_disabled()) + { + m_cnxx_slot = -1; + } + + return 0xff; + } + + if ((m_cnxx_slot != -1) && (m_slotdevice[m_cnxx_slot] != nullptr)) + { + return m_slotdevice[m_cnxx_slot]->read_c800(space, offset & 0xfff); + } + + return read_floatingbus(); +} + +WRITE8_MEMBER(agat7_state::c800_w) +{ +// logerror("%s: c800_w %04X <- %02X\n", machine().describe_context(), offset+0xc800, data); + + if (offset == 0x7ff) + { + if (!machine().side_effect_disabled()) + { + m_cnxx_slot = -1; + } + + return; + } + + if ((m_cnxx_slot != -1) && (m_slotdevice[m_cnxx_slot] != nullptr)) + { + m_slotdevice[m_cnxx_slot]->write_c800(space, offset & 0xfff, data); + } +} + +READ8_MEMBER(agat7_state::inh_r) +{ + if (m_inh_slot != -1) + { + return m_slotdevice[m_inh_slot]->read_inh_rom(space, offset + 0xd000); + } + + assert(0); // hitting inh_r with invalid m_inh_slot should not be possible + return read_floatingbus(); +} + +WRITE8_MEMBER(agat7_state::inh_w) +{ + if (m_inh_slot != -1) + { + m_slotdevice[m_inh_slot]->write_inh_rom(space, offset + 0xd000, data); + } +} + +// XXX what does Agat do here? +uint8_t agat7_state::read_floatingbus() +{ + return 0xff; +} + +/*************************************************************************** + ADDRESS MAP +***************************************************************************/ + +/* onboard memory banking on Agat-7 */ + +READ8_MEMBER(agat7_state::agat7_membank_r) +{ + logerror("%s: c0f0_r %04X == %02X\n", machine().describe_context(), offset + 0xc0f0, 0xff); + + m_agat7_membank = offset; + + return 0xff; +} + +WRITE8_MEMBER(agat7_state::agat7_membank_w) +{ + logerror("%s: c0f0_w %04X <- %02X\n", machine().describe_context(), offset + 0xc0f0, data); + + m_agat7_membank = offset; +} + +READ8_MEMBER(agat7_state::agat7_ram_r) +{ + if (offset < 32768) + { + if (offset < m_ram_size) + { + return m_ram_ptr[offset]; + } + } + else + { + if (m_agat7_ram_slot != -1) + return m_slotdevice[m_agat7_ram_slot]->read_inh_rom(space, offset + 0x8000); + if (offset < m_ram_size) + { + if (m_agat7_membank == 0) + return m_ram_ptr[offset]; + else if (m_agat7_membank == 1) + return m_ram_ptr[offset + 16384]; + } + } + + return 0xff; +} + +WRITE8_MEMBER(agat7_state::agat7_ram_w) +{ +// if (offset > 0x7fff) +// logerror("%s: ram %04X (bank %d slot %d) <- %02X\n", machine().describe_context(), offset, m_agat7_membank, m_agat7_ram_slot, data); + + if (offset < 32768) + { + if (offset < m_ram_size) + { + m_ram_ptr[offset] = data; + } + } + else + { + if (m_agat7_ram_slot != -1) + m_slotdevice[m_agat7_ram_slot]->write_inh_rom(space, offset + 0x8000, data); + else if (offset < m_ram_size) + { + if (m_agat7_membank == 0) + m_ram_ptr[offset] = data; + else if (m_agat7_membank == 1) + m_ram_ptr[offset + 16384] = data; + } + } +} + +/* + * onboard RAM is at least 32K, up to 128K. + * first 32K of onboard RAM are always mapped at 0. + * standard add-on RAM cards hold 32K (possibly up to 128K?) + * and are supported only on motherboards with 32K onboard. + * all extra RAM (onboard or addon) is accessible via 16K window at 0x8000. + */ +static ADDRESS_MAP_START( agat7_map, AS_PROGRAM, 8, agat7_state ) + ADDRESS_MAP_UNMAP_HIGH + AM_RANGE(0x0000, 0xbfff) AM_READWRITE(agat7_ram_r, agat7_ram_w) + AM_RANGE(0xc000, 0xc07f) AM_READWRITE(c000_r, c000_w) + AM_RANGE(0xc080, 0xc0ef) AM_READWRITE(c080_r, c080_w) + AM_RANGE(0xc0f0, 0xc0ff) AM_READWRITE(agat7_membank_r, agat7_membank_w) + AM_RANGE(0xc100, 0xc6ff) AM_READWRITE(c100_r, c100_w) + AM_RANGE(0xc700, 0xc7ff) AM_DEVREADWRITE("a7video", agat7video_device, read, write) + AM_RANGE(0xc800, 0xcfff) AM_READWRITE(c800_r, c800_w) + AM_RANGE(0xd000, 0xffff) AM_DEVICE(A7_UPPERBANK_TAG, address_map_bank_device, amap8) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( inhbank_map, AS_PROGRAM, 8, agat7_state ) + AM_RANGE(0x0000, 0x2fff) AM_ROM AM_REGION("maincpu", 0x1000) AM_WRITE(inh_w) + AM_RANGE(0x3000, 0x5fff) AM_READWRITE(inh_r, inh_w) +ADDRESS_MAP_END + +/*************************************************************************** + KEYBOARD +***************************************************************************/ + +READ_LINE_MEMBER(agat7_state::ay3600_shift_r) +{ + // either shift key + if (m_kbspecial->read() & 0x06) + { + return ASSERT_LINE; + } + + return CLEAR_LINE; +} + +READ_LINE_MEMBER(agat7_state::ay3600_control_r) +{ + if (m_kbspecial->read() & 0x08) + { + return ASSERT_LINE; + } + + return CLEAR_LINE; +} + +static const uint8_t a2_key_remap[0x40][4] = +{ +/* norm shft ctrl both */ + { 0x33,0x23,0x33,0x23 }, /* 3 # 00 */ + { 0x34,0x24,0x34,0x24 }, /* 4 $ 01 */ + { 0x35,0x25,0x35,0x25 }, /* 5 % 02 */ + { 0x36,'&', 0x35,'&' }, /* 6 & 03 */ + { 0x37,0x27,0x37,0x27 }, /* 7 ' 04 */ + { 0x38,0x28,0x38,0x28 }, /* 8 ( 05 */ + { 0x39,0x29,0x39,0x29 }, /* 9 ) 06 */ + { 0x30,0x30,0x30,0x30 }, /* 0 07 */ + { 0x3a,0x2a,0x3b,0x2a }, /* : * 08 */ + { 0x2d,0x3d,0x2d,0x3d }, /* - = 09 */ + { 0x51,0x51,0x11,0x11 }, /* q Q 0a */ + { 0x57,0x57,0x17,0x17 }, /* w W 0b */ + { 0x45,0x45,0x05,0x05 }, /* e E 0c */ + { 0x52,0x52,0x12,0x12 }, /* r R 0d */ + { 0x54,0x54,0x14,0x14 }, /* t T 0e */ + { 0x59,0x59,0x19,0x19 }, /* y Y 0f */ + { 0x55,0x55,0x15,0x15 }, /* u U 10 */ + { 0x49,0x49,0x09,0x09 }, /* i I 11 */ + { 0x4f,0x4f,0x0f,0x0f }, /* o O 12 */ + { 0x50,0x50,0x10,0x10 }, /* p P 13 */ + { 0x44,0x44,0x04,0x04 }, /* d D 14 */ + { 0x46,0x46,0x06,0x06 }, /* f F 15 */ + { 0x47,0x47,0x07,0x07 }, /* g G 16 */ + { 0x48,0x48,0x08,0x08 }, /* h H 17 */ + { 0x4a,0x4a,0x0a,0x0a }, /* j J 18 */ + { 0x4b,0x4b,0x0b,0x0b }, /* k K 19 */ + { 0x4c,0x4c,0x0c,0x0c }, /* l L 1a */ + { ';' ,0x2b,';' ,0x2b }, /* ; + 1b */ + { 0x08,0x08,0x08,0x08 }, /* Left 1c */ + { 0x15,0x15,0x15,0x15 }, /* Right 1d */ + { 0x5a,0x5a,0x1a,0x1a }, /* z Z 1e */ + { 0x58,0x58,0x18,0x18 }, /* x X 1f */ + { 0x43,0x43,0x03,0x03 }, /* c C 20 */ + { 0x56,0x56,0x16,0x16 }, /* v V 21 */ + { 0x42,0x42,0x02,0x02 }, /* b B 22 */ + { 0x4e,0x4e,0x0e,0x0e }, /* n N 23 */ + { 0x4d,0x4d,0x0d,0x0d }, /* m M 24 */ + { 0x2c,0x3c,0x2c,0x3c }, /* , < 25 */ + { 0x2e,0x3e,0x2e,0x3e }, /* . > 26 */ + { 0x2f,0x3f,0x2f,0x3f }, /* / ? 27 */ + { 0x53,0x53,0x13,0x13 }, /* s S 28 */ + { 0x32,0x22,0x32,0x00 }, /* 2 " 29 */ + { 0x31,0x21,0x31,0x31 }, /* 1 ! 2a */ + { 0x1b,0x1b,0x1b,0x1b }, /* Escape 2b */ + { 0x41,0x41,0x01,0x01 }, /* a A 2c */ + { 0x20,0x20,0x20,0x20 }, /* Space 2d */ + { 0x19,0x19,0x19,0x19 }, /* Up */ + { 0x1a,0x1a,0x1a,0x1a }, /* Down */ + { 0x10,0x10,0x10,0x10 }, /* KP1 */ + { 0x0d,0x0d,0x0d,0x0d }, /* Enter 31 */ + { 0x11,0x11,0x11,0x11 }, + { 0x12,0x12,0x12,0x12 }, + { 0x13,0x13,0x13,0x13 }, + { 0x14,0x14,0x14,0x14 }, + { 0x1c,0x1c,0x1c,0x1c }, + { 0x1d,0x1d,0x1d,0x1d }, + { 0x1e,0x1e,0x1e,0x1e }, + { 0x1f,0x1f,0x1f,0x1f }, + { 0x01,0x01,0x01,0x01 }, + { 0x02,0x02,0x02,0x02 }, + { 0x03,0x03,0x03,0x03 }, + { 0x04,0x04,0x04,0x04 }, + { 0x05,0x05,0x05,0x05 }, + { 0x06,0x06,0x06,0x06 }, +}; + +WRITE_LINE_MEMBER(agat7_state::ay3600_data_ready_w) +{ + if (state == ASSERT_LINE) + { + int mod = 0; + m_lastchar = m_ay3600->b_r(); + + mod = (m_kbspecial->read() & 0x06) ? 0x01 : 0x00; + mod |= (m_kbspecial->read() & 0x08) ? 0x02 : 0x00; + + m_transchar = a2_key_remap[m_lastchar & 0x3f][mod]; + + if (m_transchar != 0) + { + m_strobe = 0x80; + } + } +} + +WRITE_LINE_MEMBER(agat7_state::ay3600_ako_w) +{ + m_anykeydown = (state == ASSERT_LINE) ? true : false; +} + +TIMER_DEVICE_CALLBACK_MEMBER(agat7_state::ay3600_repeat) +{ + // is the key still down? + if (m_anykeydown) + { + if (m_kbrepeat->read() & 1) + { + m_strobe = 0x80; + } + } +} + +TIMER_DEVICE_CALLBACK_MEMBER(agat7_state::agat_timer) +{ + if (m_agat7_interrupts) + { + m_maincpu->set_input_line(M6502_IRQ_LINE, ASSERT_LINE); + } +} + +TIMER_DEVICE_CALLBACK_MEMBER(agat7_state::agat_vblank) +{ + if (m_agat7_interrupts) + { + m_maincpu->set_input_line(M6502_NMI_LINE, ASSERT_LINE); + } +} + +/*************************************************************************** + INPUT PORTS +***************************************************************************/ + +static INPUT_PORTS_START( agat7_joystick ) + PORT_START("joystick_1_x") /* Joystick 1 X Axis */ + PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X) PORT_NAME("P1 Joystick X") + PORT_SENSITIVITY(JOYSTICK_SENSITIVITY) + PORT_KEYDELTA(JOYSTICK_DELTA) + PORT_CENTERDELTA(JOYSTICK_AUTOCENTER) + PORT_MINMAX(0,0xff) PORT_PLAYER(1) + 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_START("joystick_1_y") /* Joystick 1 Y Axis */ + PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y) PORT_NAME("P1 Joystick Y") + PORT_SENSITIVITY(JOYSTICK_SENSITIVITY) + PORT_KEYDELTA(JOYSTICK_DELTA) + PORT_CENTERDELTA(JOYSTICK_AUTOCENTER) + PORT_MINMAX(0,0xff) PORT_PLAYER(1) + 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_START("joystick_2_x") /* Joystick 2 X Axis */ + PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X) PORT_NAME("P2 Joystick X") + PORT_SENSITIVITY(JOYSTICK_SENSITIVITY) + PORT_KEYDELTA(JOYSTICK_DELTA) + PORT_CENTERDELTA(JOYSTICK_AUTOCENTER) + PORT_MINMAX(0,0xff) PORT_PLAYER(2) + PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH) + + PORT_START("joystick_2_y") /* Joystick 2 Y Axis */ + PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y) PORT_NAME("P2 Joystick Y") + PORT_SENSITIVITY(JOYSTICK_SENSITIVITY) + PORT_KEYDELTA(JOYSTICK_DELTA) + PORT_CENTERDELTA(JOYSTICK_AUTOCENTER) + PORT_MINMAX(0,0xff) PORT_PLAYER(2) + PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH) PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH) + + PORT_START("joystick_buttons") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_PLAYER(1) PORT_CODE(KEYCODE_0_PAD) PORT_CODE(JOYCODE_BUTTON1) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_PLAYER(1) PORT_CODE(KEYCODE_ENTER_PAD)PORT_CODE(JOYCODE_BUTTON2) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_PLAYER(2) PORT_CODE(JOYCODE_BUTTON1) +INPUT_PORTS_END + + /* + Apple II / II Plus key matrix (from "The Apple II Circuit Description") + + | Y0 | Y1 | Y2 | Y3 | Y4 | Y5 | Y6 | Y7 | Y8 | Y9 | + | | | | | | | | | | | + ----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----| + X0 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | :* | - | + ----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----| + X1 | Q | W | E | R | T | Y | U | I | O | P | + ----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----| + X2 | D | F | G | H | J | K | L | ;+ |LEFT |RIGHT| + ----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----| + X3 | Z | X | C | V | B | N | M | ,< | .> | /? | + ----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----| + X4 | S | 2 | 1 | ESC | A |SPACE| | | |ENTER| + ----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----| + */ + +static INPUT_PORTS_START( agat7_common ) + PORT_START("X0") + PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR(':') PORT_CHAR('*') + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('-') PORT_CHAR('=') + + PORT_START("X1") + PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHAR('q') + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHAR('w') + PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHAR('e') + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHAR('r') + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHAR('t') + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHAR('y') + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHAR('u') + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHAR('i') + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHAR('o') + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('@') + + PORT_START("X2") + PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('d') + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHAR('f') + PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHAR('g') + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CHAR('h') + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHAR('j') + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHAR('k') + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHAR('l') + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+') + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT) + + PORT_START("X3") + PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHAR('z') + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHAR('x') + PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHAR('c') + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHAR('v') + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHAR('b') + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHAR('n') + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CHAR('m') + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + + PORT_START("X4") + PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHAR('s') + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('\"') + PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHAR('a') + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Num 1") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + + PORT_START("X5") + PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 2") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 3") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) + PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 4") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 5") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 6") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 7") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 8") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 9") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 0") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num .") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) + + PORT_START("X6") + PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num =") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF1") PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHAR(UCHAR_MAMEKEY(SLASH_PAD)) + PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF2") PORT_CODE(KEYCODE_ASTERISK) + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF3") PORT_CODE(KEYCODE_MINUS_PAD) + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_UNUSED) + + PORT_START("X7") + PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_UNUSED) + + PORT_START("X8") + PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_UNUSED) + + PORT_START("keyb_special") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Left Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Right Shift") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Control") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RESET") PORT_CODE(KEYCODE_F12) +INPUT_PORTS_END + +static INPUT_PORTS_START(agat7) + PORT_INCLUDE(agat7_common) + + PORT_START("keyb_repeat") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("REPT") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') + + /* other devices */ + PORT_INCLUDE(agat7_joystick) +INPUT_PORTS_END + +static SLOT_INTERFACE_START(agat7_cards) + // Standard cards + + SLOT_INTERFACE("a7lang", A2BUS_AGAT7LANGCARD) // Agat-7 RAM Language Card -- decimal 3.089.119 + SLOT_INTERFACE("a7ram", A2BUS_AGAT7RAM) // Agat-7 32K RAM Card -- decimal 3.089.119-01, KR565RU6D chips + SLOT_INTERFACE("a7fdc", A2BUS_AGAT7_FDC) // Disk II clone -- decimal 3.089.105 + // 840K floppy controller -- decimal 7.104.351 + // Serial-parallel card -- decimal 3.089.106 + // Printer card (agat9) -- decimal 3.089.174 + + // 3rd party cards + + // Programmable i/o (8035 + 8251 + 8253 + 8255) + // Card-93 floppy controller (KR1818VG93-based) + // Nippel ADC (digital oscilloscope) + // Nippel Clock (mc146818) + // Nippel Co-processor (R65C02 clone + dual-ported RAM) +SLOT_INTERFACE_END + +static MACHINE_CONFIG_START( agat7, agat7_state ) + MCFG_CPU_ADD("maincpu", M6502, XTAL_14_3MHz / 14) + MCFG_CPU_PROGRAM_MAP(agat7_map) + + MCFG_TIMER_DRIVER_ADD_PERIODIC("agat7irq", agat7_state, agat_timer, attotime::from_hz(500)) + + MCFG_DEVICE_ADD(A7_VIDEO_TAG, AGAT7VIDEO, 0) + + MCFG_RAM_ADD(RAM_TAG) + MCFG_RAM_DEFAULT_SIZE("32K") +// MCFG_RAM_EXTRA_OPTIONS("64K,128K") + MCFG_RAM_DEFAULT_VALUE(0x00) + + /* sound hardware */ + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_ADD(A7_SPEAKER_TAG, SPEAKER_SOUND, 0) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) + + /* /INH banking */ + MCFG_DEVICE_ADD(A7_UPPERBANK_TAG, ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(inhbank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x3000) + + /* keyboard controller -- XXX must be replaced */ + MCFG_DEVICE_ADD(A7_KBDC_TAG, AY3600, 0) + MCFG_AY3600_MATRIX_X0(IOPORT("X0")) + MCFG_AY3600_MATRIX_X1(IOPORT("X1")) + MCFG_AY3600_MATRIX_X2(IOPORT("X2")) + MCFG_AY3600_MATRIX_X3(IOPORT("X3")) + MCFG_AY3600_MATRIX_X4(IOPORT("X4")) + MCFG_AY3600_MATRIX_X5(IOPORT("X5")) + MCFG_AY3600_MATRIX_X6(IOPORT("X6")) + MCFG_AY3600_MATRIX_X7(IOPORT("X7")) + MCFG_AY3600_MATRIX_X8(IOPORT("X8")) + MCFG_AY3600_SHIFT_CB(READLINE(agat7_state, ay3600_shift_r)) + MCFG_AY3600_CONTROL_CB(READLINE(agat7_state, ay3600_control_r)) + MCFG_AY3600_DATA_READY_CB(WRITELINE(agat7_state, ay3600_data_ready_w)) + MCFG_AY3600_AKO_CB(WRITELINE(agat7_state, ay3600_ako_w)) + + /* repeat timer. 10 Hz per Mymrin's book */ + MCFG_TIMER_DRIVER_ADD_PERIODIC("repttmr", agat7_state, ay3600_repeat, attotime::from_hz(10)) + + /* + * slot 0 is reserved for SECAM encoder or Apple II compat card. + * slot 1 always holds the CPU card. + */ + MCFG_DEVICE_ADD(A7_BUS_TAG, A2BUS, 0) + MCFG_A2BUS_CPU(A7_CPU_TAG) + MCFG_A2BUS_OUT_IRQ_CB(WRITELINE(agat7_state, a2bus_irq_w)) + MCFG_A2BUS_OUT_NMI_CB(WRITELINE(agat7_state, a2bus_nmi_w)) + MCFG_A2BUS_OUT_INH_CB(WRITELINE(agat7_state, a2bus_inh_w)) + MCFG_A2BUS_SLOT_ADD(A7_BUS_TAG, "sl2", agat7_cards, "a7lang") + MCFG_A2BUS_SLOT_ADD(A7_BUS_TAG, "sl3", agat7_cards, "a7fdc") + MCFG_A2BUS_SLOT_ADD(A7_BUS_TAG, "sl4", agat7_cards, nullptr) + MCFG_A2BUS_SLOT_ADD(A7_BUS_TAG, "sl5", agat7_cards, nullptr) + MCFG_A2BUS_SLOT_ADD(A7_BUS_TAG, "sl6", agat7_cards, "a7ram") + + MCFG_CASSETTE_ADD(A7_CASSETTE_TAG) + MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED) +MACHINE_CONFIG_END + + +/*************************************************************************** + + Game driver(s) + +***************************************************************************/ + +ROM_START( agat7 ) + ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) + ROM_DEFAULT_BIOS("v1") + + ROM_SYSTEM_BIOS( 0, "v1", "Version 1" ) // original? + ROMX_LOAD( "monitor7.rom", 0x3800, 0x0800, CRC(071fda0b) SHA1(6089d46b7addc4e2ae096b2cf81124681bd2b27a), ROM_BIOS(1)) + ROM_SYSTEM_BIOS( 1, "v2", "Version 2" ) // modded by author of agatcomp.ru + ROMX_LOAD( "agat_pzu.bin", 0x3800, 0x0800, CRC(c605163d) SHA1(b30fd1b264a347a9de69bb9e3105483254994d06), ROM_BIOS(2)) + ROM_SYSTEM_BIOS( 2, "debug", "Debug" ) // written by author of agatcomp.ru + ROMX_LOAD( "debug-sysmon7.bin", 0x3800, 0x0800, CRC(d26f18a4) SHA1(2862c13a82e2f4dfc757aa2eeab11fe71c570c12), ROM_BIOS(3)) + + // 140KB floppy controller + ROM_LOAD( "shugart7.rom", 0x4500, 0x0100, CRC(c6e4850c) SHA1(71626d3d2d4bbeeac2b77585b45a5566d20b8d34)) + // 840KB floppy controller + ROM_LOAD( "teac.rom", 0x4500, 0x0100, CRC(94266928) SHA1(5d369bad6cdd6a70b0bb16480eba69640de87a2e)) + + ROM_REGION(0x0800,"gfx1",0) + ROM_LOAD( "agathe7.fnt", 0x0000, 0x0800, CRC(fcffb490) SHA1(0bda26ae7ad75f74da835c0cf6d9928f9508844c)) +ROM_END + +ROM_START( agat9 ) + ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) + ROM_SYSTEM_BIOS( 0, "v1", "Version 1" ) + ROMX_LOAD( "monitor9.rom", 0x3800, 0x0800, CRC(b90bb66a) SHA1(02217f0785913b41fc25eabcff70fa814799c69a), ROM_BIOS(1)) + ROM_SYSTEM_BIOS( 1, "v2", "Version 2" ) + ROMX_LOAD( "monitor91.rom", 0x3800, 0x0800, CRC(89b10fc1) SHA1(7fe1ede32b5525255f82597ca9c3c2034c5996fa), ROM_BIOS(2)) + // Floppy controllers + ROM_LOAD( "shugart9.rom", 0x4500, 0x0100, CRC(964a0ce2) SHA1(bf955189ebffe874c20ef649a3db8177dc16af61)) + ROM_LOAD( "teac.rom", 0x4500, 0x0100, CRC(94266928) SHA1(5d369bad6cdd6a70b0bb16480eba69640de87a2e)) + // Printer card + ROM_LOAD( "cm6337.rom", 0x8000, 0x0100, CRC(73be16ec) SHA1(ead1abbef5b86f1def0b956147d5b267f0d544b5)) + ROM_LOAD( "cm6337p.rom", 0x8100, 0x0800, CRC(9120f11f) SHA1(78107653491e88d5ea12e07367c4c028771a4aca)) + ROM_REGION(0x0800,"gfx1",0) + ROM_LOAD( "agathe9.fnt", 0x0000, 0x0800, CRC(8c55c984) SHA1(5a5a202000576b88b4ae2e180dd2d1b9b337b594)) +ROM_END + +/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME */ +COMP( 1983, agat7, apple2, 0, agat7, agat7, driver_device, 0, "Agat", "Agat-7", MACHINE_NOT_WORKING) +COMP( 1984, agat9, apple2, 0, agat7, agat7, driver_device, 0, "Agat", "Agat-9", MACHINE_NOT_WORKING) diff --git a/src/mame/drivers/apple2.cpp b/src/mame/drivers/apple2.cpp index 8cd77a1d54a..363a8ee5c1b 100644 --- a/src/mame/drivers/apple2.cpp +++ b/src/mame/drivers/apple2.cpp @@ -1605,35 +1605,6 @@ ROM_START(am64) ROM_LOAD( "tk10.bin", 0x0800, 0x0800, CRC(a06c5b78) SHA1(27c5160b913e0f62120f384026d24b9f1acb6970) ) ROM_END -ROM_START( agat7 ) - ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) - ROM_SYSTEM_BIOS( 0, "v1", "Version 1" ) - ROMX_LOAD( "monitor7.rom", 0x3800, 0x0800, CRC(071fda0b) SHA1(6089d46b7addc4e2ae096b2cf81124681bd2b27a), ROM_BIOS(1)) - ROM_SYSTEM_BIOS( 1, "v2", "Version 2" ) - ROMX_LOAD( "agat_pzu.bin", 0x3800, 0x0800, CRC(c605163d) SHA1(b30fd1b264a347a9de69bb9e3105483254994d06), ROM_BIOS(2)) - // Floppy controllers - ROM_LOAD( "shugart7.rom", 0x4500, 0x0100, CRC(c6e4850c) SHA1(71626d3d2d4bbeeac2b77585b45a5566d20b8d34)) - ROM_LOAD( "teac.rom", 0x4500, 0x0100, CRC(94266928) SHA1(5d369bad6cdd6a70b0bb16480eba69640de87a2e)) - ROM_REGION(0x0800,"gfx1",0) - ROM_LOAD( "agathe7.fnt", 0x0000, 0x0800, CRC(fcffb490) SHA1(0bda26ae7ad75f74da835c0cf6d9928f9508844c)) -ROM_END - -ROM_START( agat9 ) - ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) - ROM_SYSTEM_BIOS( 0, "v1", "Version 1" ) - ROMX_LOAD( "monitor9.rom", 0x3800, 0x0800, CRC(b90bb66a) SHA1(02217f0785913b41fc25eabcff70fa814799c69a), ROM_BIOS(1)) - ROM_SYSTEM_BIOS( 1, "v2", "Version 2" ) - ROMX_LOAD( "monitor91.rom", 0x3800, 0x0800, CRC(89b10fc1) SHA1(7fe1ede32b5525255f82597ca9c3c2034c5996fa), ROM_BIOS(2)) - // Floppy controllers - ROM_LOAD( "shugart9.rom", 0x4500, 0x0100, CRC(964a0ce2) SHA1(bf955189ebffe874c20ef649a3db8177dc16af61)) - ROM_LOAD( "teac.rom", 0x4500, 0x0100, CRC(94266928) SHA1(5d369bad6cdd6a70b0bb16480eba69640de87a2e)) - // Printer card - ROM_LOAD( "cm6337.rom", 0x8000, 0x0100, CRC(73be16ec) SHA1(ead1abbef5b86f1def0b956147d5b267f0d544b5)) - ROM_LOAD( "cm6337p.rom", 0x8100, 0x0800, CRC(9120f11f) SHA1(78107653491e88d5ea12e07367c4c028771a4aca)) - ROM_REGION(0x0800,"gfx1",0) - ROM_LOAD( "agathe9.fnt", 0x0000, 0x0800, CRC(8c55c984) SHA1(5a5a202000576b88b4ae2e180dd2d1b9b337b594)) -ROM_END - ROM_START(ivelultr) ROM_REGION(0x2000,"gfx1",0) ROM_LOAD( "ultra.chr", 0x0000, 0x1000,CRC(fed62c85) SHA1(479fb3f38a3f7332cef2e8c4856871afe8dc6017)) @@ -1683,10 +1654,8 @@ COMP( 1982, ace100, apple2, 0, apple2, apple2p, driver_device, COMP( 1982, uniap2en, apple2, 0, apple2p, apple2p, driver_device, 0, "Unitron Eletronica", "Unitron AP II (in English)", MACHINE_SUPPORTS_SAVE ) COMP( 1982, uniap2pt, apple2, 0, apple2p, apple2p, driver_device, 0, "Unitron Eletronica", "Unitron AP II (in Brazilian Portuguese)", MACHINE_SUPPORTS_SAVE ) COMP( 1984, uniap2ti, apple2, 0, apple2p, apple2p, driver_device, 0, "Unitron Eletronica", "Unitron AP II+ (Teclado Inteligente)", MACHINE_SUPPORTS_SAVE ) -COMP( 1983, agat7, apple2, 0, apple2p, apple2p, driver_device, 0, "Agat", "Agat-7", MACHINE_NOT_WORKING) // disk controller ROM JSRs to $FCA8 which is a delay on apple II, illegal instruction crash here :( // reverse font direction -\/ COMP( 1984, ivelultr, apple2, 0, apple2p, apple2p, driver_device, 0, "Ivasim", "Ivel Ultra", MACHINE_SUPPORTS_SAVE ) -COMP( 1984, agat9, apple2, 0, apple2p, apple2p, driver_device, 0, "Agat", "Agat-9", MACHINE_NOT_WORKING) COMP( 1985, prav8m, apple2, 0, apple2p, apple2p, driver_device, 0, "Pravetz", "Pravetz 8M", MACHINE_SUPPORTS_SAVE ) COMP( 1985, space84, apple2, 0, space84, apple2p, driver_device, 0, "ComputerTechnik/IBS", "Space 84", MACHINE_NOT_WORKING ) COMP( 1985, am64, apple2, 0, space84, apple2p, driver_device, 0, "ASEM", "AM 64", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index d39fabff950..eec59aec47f 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -910,6 +910,10 @@ wbbc97 // (c) 1997 Comad @source:age_candy.cpp age_cand // AGE Candy Crane +@source:agat.cpp +agat7 // Agat-7 +agat9 // Agat-9 + @source:aim65.cpp aim65 // Rockwell AIM65 @@ -1216,8 +1220,6 @@ apple1 // Jul 1976 Apple 1 @source:apple2.cpp ace100 // ??? 1982 Franklin Ace 100 -agat7 // Agat-7 -agat9 // Agat-9 am64 // 1985 ASEM AM 64 (motherboard is marked AM-100 but it boots as "AM 64") apple2 // Apr 1977 Apple ][ apple2jp // ??? ???? Apple ][j+ diff --git a/src/mame/mess.flt b/src/mame/mess.flt index cff14552aef..399174a18c5 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -17,6 +17,7 @@ aceex.cpp acrnsys1.cpp adam.cpp advision.cpp +agat.cpp aim65.cpp aim65_40.cpp akaiax80.cpp diff --git a/src/mame/video/agat7.cpp b/src/mame/video/agat7.cpp new file mode 100644 index 00000000000..10ff9800a40 --- /dev/null +++ b/src/mame/video/agat7.cpp @@ -0,0 +1,375 @@ +// license:BSD-3-Clause +// copyright-holders:Sergey Svishchev +/********************************************************************* + + agat7video.cpp + + Implementation of Agat-7 onboard video. + + 5 video modes: + - 32x32 color text + - 64x32 mono text with reverse video + - 64x64 color graphics + - 128x128 color graphics + - 256x256 mono graphics + + Character generator ROM could have 128 or 256 chars. + + C7xx: video mode select + +*********************************************************************/ + +#include "video/agat7.h" + +#include "screen.h" + + +/*************************************************************************** + PARAMETERS +***************************************************************************/ + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type AGAT7VIDEO = device_creator; + +MACHINE_CONFIG_FRAGMENT(agat7video) + MCFG_SCREEN_ADD("a7screen", RASTER) + MCFG_SCREEN_RAW_PARAMS(XTAL_10_5MHz, 672, 0, 512, 312, 0, 256) + MCFG_SCREEN_UPDATE_DRIVER(agat7video_device, screen_update) + MCFG_SCREEN_PALETTE("a7palette") + + MCFG_PALETTE_ADD("a7palette", 16) + MCFG_PALETTE_INIT_OWNER(agat7video_device, agat7) +MACHINE_CONFIG_END + +/*************************************************************************** + FUNCTION PROTOTYPES +***************************************************************************/ + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor agat7video_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( agat7video ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +agat7video_device::agat7video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, AGAT7VIDEO, "Agat-7 video", tag, owner, clock, "agat7video", __FILE__), + m_palette(*this, "a7palette") +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void agat7video_device::device_start() +{ +// save_item(NAME(m_video_mode)); + save_item(NAME(m_start_address)); +} + +void agat7video_device::device_reset() +{ + // XXX to be confirmed + m_video_mode = TEXT_LORES; + m_start_address = 0x7800; +} + + +READ8_MEMBER(agat7video_device::read) +{ + do_io(offset); + return 0; +} + +WRITE8_MEMBER(agat7video_device::write) +{ + do_io(offset); +} + + +void agat7video_device::do_io(int offset) +{ + switch (offset & 3) + { + case 0: + m_video_mode = GRAPHICS_LORES; + m_start_address = (offset) << 9; + logerror("offset %04X, video mode 0 (GRAPHICS_LORES)\n", m_start_address); + break; + + case 1: + m_video_mode = GRAPHICS_HIRES; + m_start_address = ((offset & 0x3f) - 0x01) << 9; + logerror("offset %04X, video mode 1 (GRAPHICS_HIRES)\n", m_start_address); + break; + + case 2: + if (offset > 0x80) { + m_video_mode = TEXT_HIRES; + m_start_address = (offset - 0x82) << 9; + logerror("offset %04X, video mode 2 (TEXT_HIRES)\n", m_start_address); + } else { + m_video_mode = TEXT_LORES; + m_start_address = (offset - 0x02) << 9; + logerror("offset %04X, video mode 2 (TEXT_LORES)\n", m_start_address); + } + break; + + case 3: + m_video_mode = GRAPHICS_MONO; + m_start_address = ((offset & 0x3f) - 0x03) << 9; + logerror("offset %04X, video mode 3 (GRAPHICS_MONO)\n", m_start_address); + break; + } +} + + +void agat7video_device::plot_text_character(bitmap_ind16 &bitmap, int xpos, int ypos, int xscale, uint32_t code, + const uint8_t *textgfx_data, uint32_t textgfx_datalen, int fg, int bg) +{ + int x, y, i; + const uint8_t *chardata; + uint16_t color; + + /* look up the character data */ + chardata = &textgfx_data[(code * 8)]; + + for (y = 0; y < 8; y++) + { + for (x = 0; x < 8; x++) + { + color = (chardata[y] & (1 << (7-x))) ? fg : bg; + + for (i = 0; i < xscale; i++) + { + bitmap.pix16(ypos + y, xpos + (x * xscale) + i) = color; + } + } + } +} + +void agat7video_device::text_update_lores(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow) +{ + int row, col; + uint32_t address; + uint8_t ch, attr; + int fg = 0; + int bg = 0; + + beginrow = std::max(beginrow, cliprect.min_y - (cliprect.min_y % 8)); + endrow = std::min(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7); + + for (row = beginrow; row <= endrow; row += 8) + { + for (col = 0; col < 32; col++) + { + /* calculate address */ + address = m_start_address + (col * 2) + (row * 8); + ch = m_ram_dev->read(address); + attr = m_ram_dev->read(address + 1); + if (BIT(attr, 5)) { + fg = BITSWAP8(attr,7,6,5,3,4,2,1,0) & 15; + bg = 0; + } else { + fg = 0; + bg = BITSWAP8(attr,7,6,5,3,4,2,1,0) & 15; + } + plot_text_character(bitmap, col * 16, row, 2, ch, m_char_ptr, m_char_size, fg, bg); + } + } +} + +void agat7video_device::text_update_hires(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow) +{ + int row, col; + uint32_t address; + uint8_t ch; + int fg, bg; + + beginrow = std::max(beginrow, cliprect.min_y - (cliprect.min_y % 8)); + endrow = std::min(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7); + + if (m_start_address & 0x800) { + fg = 7; bg = 0; + } else { + fg = 0; bg = 7; + } + + for (row = beginrow; row <= endrow; row += 8) + { + for (col = 0; col < 64; col++) + { + /* calculate address */ + address = m_start_address + col + (row * 8); + ch = m_ram_dev->read(address); + plot_text_character(bitmap, col * 8, row, 1, ch, m_char_ptr, m_char_size, fg, bg); + } + } +} + +void agat7video_device::graph_update_mono(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow) +{ + int row, col, b; + uint32_t address; + uint16_t *p; + uint8_t gfx, v; + int fg = 7, bg = 0; + + beginrow = std::max(beginrow, cliprect.min_y - (cliprect.min_y % 8)); + endrow = std::min(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7); + + for (row = beginrow; row <= endrow; row++) + { + p = &bitmap.pix16(row); + for (col = 0; col < 32; col++) + { + address = m_start_address + col + (row * 0x20); + gfx = m_ram_dev->read(address); + + for (b = 0; b < 8; b++) + { + v = (gfx & 0x80); + gfx <<= 1; + *(p++) = v ? fg : bg; + *(p++) = v ? fg : bg; + } + } + } +} + +void agat7video_device::graph_update_hires(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow) +{ + int row, col, b; + uint32_t address; + uint16_t *p; + uint8_t gfx, v; + + beginrow = std::max(beginrow, cliprect.min_y - (cliprect.min_y % 8)); + endrow = std::min(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7); + + for (row = beginrow; row <= endrow; row++) + { + p = &bitmap.pix16(row); + for (col = 0; col < 0x40; col++) + { + address = m_start_address + col + ((row/2) * 0x40); + gfx = m_ram_dev->read(address); + + for (b = 0; b < 2; b++) + { + v = (gfx & 0xf0) >> 4; + gfx <<= 4; + *(p++) = v; + *(p++) = v; + *(p++) = v; + *(p++) = v; + } + } + } +} + +void agat7video_device::graph_update_lores(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow) +{ + int row, col, b; + uint32_t address; + uint16_t *p; + uint8_t gfx, v; + + beginrow = std::max(beginrow, cliprect.min_y - (cliprect.min_y % 8)); + endrow = std::min(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7); + + for (row = beginrow; row <= endrow; row++) + { + p = &bitmap.pix16(row); + for (col = 0; col < 0x20; col++) + { + address = m_start_address + col + ((row/4) * 0x20); + gfx = m_ram_dev->read(address); + + for (b = 0; b < 2; b++) + { + v = (gfx & 0xf0) >> 4; + gfx <<= 4; + *(p++) = v; + *(p++) = v; + *(p++) = v; + *(p++) = v; + *(p++) = v; + *(p++) = v; + *(p++) = v; + *(p++) = v; + } + } + } +} + + +uint32_t agat7video_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + switch (m_video_mode) + { + case TEXT_LORES: + text_update_lores(screen, bitmap, cliprect, 0, 255); + break; + + case TEXT_HIRES: + text_update_hires(screen, bitmap, cliprect, 0, 255); + break; + + case GRAPHICS_MONO: + graph_update_mono(screen, bitmap, cliprect, 0, 255); + break; + + case GRAPHICS_LORES: + graph_update_lores(screen, bitmap, cliprect, 0, 255); + break; + + case GRAPHICS_HIRES: + graph_update_hires(screen, bitmap, cliprect, 0, 255); + break; + + default: + graph_update_mono(screen, bitmap, cliprect, 0, 255); + break; + } + + return 0; +} + +// per http://agatcomp.ru/Reading/IiO/87-2-077.djvu +static const rgb_t agat7_palette[] = +{ + rgb_t::black(), + rgb_t(0xFF, 0x00, 0x00), /* White */ + rgb_t(0x00, 0xFF, 0x00), /* White */ + rgb_t(0xFF, 0xFF, 0x00), /* White */ + rgb_t(0x00, 0x00, 0xFF), /* White */ + rgb_t(0xFF, 0x00, 0xFF), /* White */ + rgb_t(0xFF, 0xFF, 0x00), /* White */ + rgb_t(0xFF, 0xFF, 0xFF), /* White */ + rgb_t::black(), + rgb_t(0x7F, 0x00, 0x00), /* White */ + rgb_t(0x00, 0x7F, 0x00), /* White */ + rgb_t(0x7F, 0x7F, 0x00), /* White */ + rgb_t(0x00, 0x00, 0x7F), /* White */ + rgb_t(0x7F, 0x00, 0x7F), /* White */ + rgb_t(0x7F, 0x7F, 0x00), /* White */ + rgb_t(0x7F, 0x7F, 0x7F) /* White */ +}; + +PALETTE_INIT_MEMBER(agat7video_device, agat7) +{ + palette.set_pen_colors(0, agat7_palette, ARRAY_LENGTH(agat7_palette)); +} diff --git a/src/mame/video/agat7.h b/src/mame/video/agat7.h new file mode 100644 index 00000000000..510e55e23c5 --- /dev/null +++ b/src/mame/video/agat7.h @@ -0,0 +1,75 @@ +// license:BSD-3-Clause +// copyright-holders:Sergey Svishchev +/********************************************************************* + + agat7video.h + + Implementation of Agat-7 onboard video. + +*********************************************************************/ + +#ifndef __AGAT7VIDEO__ +#define __AGAT7VIDEO__ + +#include "emu.h" + +#include "machine/ram.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class agat7video_device: + public device_t +{ +public: + // construction/destruction + agat7video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const override; + + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + + DECLARE_PALETTE_INIT(agat7); + + DECLARE_READ8_MEMBER(read); + DECLARE_WRITE8_MEMBER(write); + + ram_device *m_ram_dev; + uint8_t *m_char_ptr; + int m_char_size; + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + void text_update_lores(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow); + void text_update_hires(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow); + void graph_update_mono(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow); + void graph_update_lores(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow); + void graph_update_hires(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow); + +private: + void do_io(int offset); + + uint32_t m_start_address; + enum { + TEXT_LORES = 0, + TEXT_HIRES, + GRAPHICS_LORES, + GRAPHICS_HIRES, + GRAPHICS_MONO + } m_video_mode; + + void plot_text_character(bitmap_ind16 &bitmap, int xpos, int ypos, int xscale, uint32_t code, const uint8_t *textgfx_data, uint32_t textgfx_datalen, int fg, int bg); + +public: + required_device m_palette; +}; + +// device type definition +extern const device_type AGAT7VIDEO; + +#endif /* __AGAT7VIDEO__ */ -- cgit v1.2.3