summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Nigel Barnes <Pernod70@users.noreply.github.com>2017-06-15 18:20:27 +0100
committer Nigel Barnes <Pernod70@users.noreply.github.com>2017-06-15 18:43:33 +0100
commitacdaf11b7380ead229d3d7f52c2b9e8bdfbb8c84 (patch)
treeea700a5e116ae3840698c169cdd25e086733c5e2
parent1a77f08161b61c3b892f0a3edabbcd60aa0e0524 (diff)
d64plus: Implemented banking of extra 64K, and 6845 with chargen. Machine promoted to WORKING.
dragon32: Added JCB Sound Extension cartridge. dragon200e: Added correct keyboard.
-rw-r--r--scripts/src/bus.lua3
-rw-r--r--src/devices/bus/coco/cococart.h9
-rw-r--r--src/devices/bus/coco/dragon_jcbsnd.cpp96
-rw-r--r--src/devices/bus/coco/dragon_jcbsnd.h44
-rw-r--r--src/mame/drivers/dragon.cpp99
-rw-r--r--src/mame/includes/dragon.h20
-rw-r--r--src/mame/machine/dragon.cpp106
7 files changed, 325 insertions, 52 deletions
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index 3f7e1d1a341..1c7a5cb5046 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -2518,8 +2518,9 @@ if (BUSES["COCO"]~=null) then
MAME_DIR .. "src/devices/bus/coco/coco_multi.cpp",
MAME_DIR .. "src/devices/bus/coco/coco_dwsock.cpp",
MAME_DIR .. "src/devices/bus/coco/coco_dwsock.h",
- MAME_DIR .. "src/devices/bus/coco/dragon_fdc.cpp",
MAME_DIR .. "src/devices/bus/coco/coco_t4426.cpp",
+ MAME_DIR .. "src/devices/bus/coco/dragon_fdc.cpp",
+ MAME_DIR .. "src/devices/bus/coco/dragon_jcbsnd.cpp",
}
end
diff --git a/src/devices/bus/coco/cococart.h b/src/devices/bus/coco/cococart.h
index 12ce93f8357..82cc9f8a323 100644
--- a/src/devices/bus/coco/cococart.h
+++ b/src/devices/bus/coco/cococart.h
@@ -121,7 +121,7 @@ public:
// cart base
uint8_t* get_cart_base();
void set_cart_base_update(cococart_base_update_delegate update);
-
+
private:
// TIMER_POOL: Must be power of two
static constexpr int TIMER_POOL = 2;
@@ -214,9 +214,9 @@ protected:
typedef cococart_slot_device::line_value line_value;
private:
- cococart_base_update_delegate m_update;
- cococart_slot_device * m_owning_slot;
- device_cococart_host_interface * m_host;
+ cococart_base_update_delegate m_update;
+ cococart_slot_device * m_owning_slot;
+ device_cococart_host_interface * m_host;
};
@@ -256,5 +256,6 @@ extern const device_type COCO_PAK;
extern const device_type COCO_PAK_BANKED;
extern const device_type COCO_PAK_GMC;
extern const device_type COCO_T4426;
+extern const device_type DRAGON_JCBSND;
#endif // MAME_BUS_COCO_COCOCART_H
diff --git a/src/devices/bus/coco/dragon_jcbsnd.cpp b/src/devices/bus/coco/dragon_jcbsnd.cpp
new file mode 100644
index 00000000000..8bc858d26e8
--- /dev/null
+++ b/src/devices/bus/coco/dragon_jcbsnd.cpp
@@ -0,0 +1,96 @@
+// license:BSD-3-Clause
+// copyright-holders:Nigel Barnes
+/***************************************************************************
+
+ JCB Sound Extension Module
+
+ The Dragon 32 Sound Extension Module is a cartridge by J.C.B. (Microsystems),
+ that contains a General Instruments AY-3-8910 sound chip. This allows the
+ Dragon to play interesting sound effects and complex chiptunes without
+ taking all processor time.
+ The cartridge also adds two 8-bit I/O ports (provided also by the AY-3-8910).
+ The sound chip can be operated via the new commands in BASIC provided in
+ the cartridge ROM, or via the 0xFEFE and 0xFEFF addresses.
+
+***************************************************************************/
+
+#include "emu.h"
+#include "dragon_jcbsnd.h"
+#include "speaker.h"
+
+
+ROM_START( dragon_jcbsnd )
+ ROM_REGION(0x8000, "eprom", ROMREGION_ERASE00)
+ ROM_LOAD("D32SEM.ROM", 0x0000, 0x1000, CRC(4cd0f30b) SHA1(d07bb9272e3d3928059853730ff656905a80b68e))
+ROM_END
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(DRAGON_JCBSND, dragon_jcbsnd_device, "dragon_jcbsnd", "Dragon Sound Extension Module")
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// dragon_jcbsnd_device - constructor
+//-------------------------------------------------
+
+dragon_jcbsnd_device::dragon_jcbsnd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, DRAGON_JCBSND, tag, owner, clock)
+ , device_cococart_interface(mconfig, *this )
+ , m_ay8910(*this, "ay8910")
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void dragon_jcbsnd_device::device_start()
+{
+ m_cart = dynamic_cast<cococart_slot_device *>(owner());
+}
+
+//-------------------------------------------------
+// device_reset - device-specific startup
+//-------------------------------------------------
+
+void dragon_jcbsnd_device::device_reset()
+{
+ set_line_value(line::CART, line_value::Q);
+
+ address_space& space = machine().device("maincpu")->memory().space(AS_PROGRAM);
+ space.install_write_handler(0xfefe, 0xfefe, WRITE8_DEVICE_DELEGATE(m_ay8910, ay8910_device, address_w));
+ space.install_readwrite_handler(0xfeff, 0xfeff, READ8_DEVICE_DELEGATE(m_ay8910, ay8910_device, data_r), WRITE8_DEVICE_DELEGATE(m_ay8910, ay8910_device, data_w));
+}
+
+//-------------------------------------------------
+// dragon_jcbsnd_device::get_cart_base
+//-------------------------------------------------
+
+uint8_t* dragon_jcbsnd_device::get_cart_base()
+{
+ return memregion("eprom")->base();
+}
+
+//-------------------------------------------------
+// device_add_mconfig - add device configuration
+//-------------------------------------------------
+
+MACHINE_CONFIG_MEMBER( dragon_jcbsnd_device::device_add_mconfig )
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+ MCFG_SOUND_ADD("ay8910", AY8910, DERIVED_CLOCK(1, 4)) /* AY-3-8910 - clock not verified */
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
+MACHINE_CONFIG_END
+
+//-------------------------------------------------
+// rom_region - device-specific ROM region
+//-------------------------------------------------
+
+const tiny_rom_entry *dragon_jcbsnd_device::device_rom_region() const
+{
+ return ROM_NAME( dragon_jcbsnd );
+}
diff --git a/src/devices/bus/coco/dragon_jcbsnd.h b/src/devices/bus/coco/dragon_jcbsnd.h
new file mode 100644
index 00000000000..5f4015d434f
--- /dev/null
+++ b/src/devices/bus/coco/dragon_jcbsnd.h
@@ -0,0 +1,44 @@
+// license:BSD-3-Clause
+// copyright-holders:Nigel Barnes
+#ifndef MAME_BUS_COCO_DRAGON_JCBSND_H
+#define MAME_BUS_COCO_DRAGON_JCBSND_H
+
+#pragma once
+
+#include "cococart.h"
+#include "sound/ay8910.h"
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> dragon_jcbsnd_device
+
+class dragon_jcbsnd_device :
+ public device_t,
+ public device_cococart_interface
+{
+public:
+ // construction/destruction
+ dragon_jcbsnd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ // optional information overrides
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual const tiny_rom_entry *device_rom_region() const override;
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual uint8_t* get_cart_base() override;
+
+ // internal state
+ device_image_interface *m_cart;
+private:
+ required_device<ay8910_device> m_ay8910;
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(DRAGON_JCBSND, dragon_jcbsnd_device)
+
+#endif // MAME_BUS_COCO_DRAGON_JCBSND_H
diff --git a/src/mame/drivers/dragon.cpp b/src/mame/drivers/dragon.cpp
index c080bbf921b..36fdf3ba88b 100644
--- a/src/mame/drivers/dragon.cpp
+++ b/src/mame/drivers/dragon.cpp
@@ -38,14 +38,14 @@ ADDRESS_MAP_END
/* Dragon keyboard
- PB0 PB1 PB2 PB3 PB4 PB5 PB6 PB7
- PA6: Ent Clr Brk N/c N/c N/c N/c Shift
- PA5: X Y Z Up Dwn Lft Rgt Space
- PA4: P Q R S T U V W
- PA3: H I J K L M N O
- PA2: @ A B C D E F G
- PA1: 8 9 : ; , - . /
- PA0: 0 1 2 3 4 5 6 7
+ PB0 PB1 PB2 PB3 PB4 PB5 PB6 PB7
+ PA6: Ent Clr Brk N/c N/c N/c N/c Shift
+ PA5: X Y Z Up Dwn Lft Rgt Space
+ PA4: P Q R S T U V W
+ PA3: H I J K L M N O
+ PA2: @ A B C D E F G
+ PA1: 8 9 : ; , - . /
+ PA0: 0 1 2 3 4 5 6 7
*/
static INPUT_PORTS_START( dragon_keyboard )
PORT_START("row0")
@@ -61,15 +61,15 @@ static INPUT_PORTS_START( dragon_keyboard )
PORT_START("row1")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
- PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_CODE(KEYCODE_COLON) PORT_CHAR(':') PORT_CHAR('*')
- PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(';') PORT_CHAR('+')
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_CODE(KEYCODE_MINUS) PORT_CHAR(':') PORT_CHAR('*')
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+')
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
- PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=')
+ PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('-') PORT_CHAR('=')
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
PORT_START("row2")
- PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('@')
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@')
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_CODE(KEYCODE_A) PORT_CHAR('A')
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_CODE(KEYCODE_B) PORT_CHAR('B')
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_CODE(KEYCODE_C) PORT_CHAR('C')
@@ -116,12 +116,40 @@ static INPUT_PORTS_START( dragon_keyboard )
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
INPUT_PORTS_END
+static INPUT_PORTS_START( dragon200e_keyboard )
+ PORT_INCLUDE(dragon_keyboard)
+
+ PORT_MODIFY("row0")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_NAME("0 \xC3\x87") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR('\xC7')
+
+ PORT_MODIFY("row1")
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_NAME("\xC3\x91") PORT_CODE(KEYCODE_COLON) PORT_CHAR('\xD1')
+
+ PORT_MODIFY("row2")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR(';') PORT_CHAR('+')
+
+ PORT_MODIFY("row5")
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_NAME("DOWN \xC2\xA1") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(10) PORT_CHAR('\xA1')
+ PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_NAME("RIGHT \xC2\xBF") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(9) PORT_CHAR('\xBF')
+ PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_CHAR('\xA7')
+
+ PORT_MODIFY("row6")
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_NAME("CLEAR @") PORT_CODE(KEYCODE_HOME) PORT_CHAR(12) PORT_CHAR('@')
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, dragon_state, keyboard_changed, nullptr) PORT_NAME("BREAK \xC3\xBC") PORT_CODE(KEYCODE_END) PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) PORT_CHAR('\xFC')
+INPUT_PORTS_END
+
static INPUT_PORTS_START( dragon )
PORT_INCLUDE(dragon_keyboard)
PORT_INCLUDE(coco_joystick)
PORT_INCLUDE(coco_analog_control)
INPUT_PORTS_END
+static INPUT_PORTS_START( dragon200e )
+ PORT_INCLUDE(dragon200e_keyboard)
+ PORT_INCLUDE(coco_joystick)
+ PORT_INCLUDE(coco_analog_control)
+INPUT_PORTS_END
+
MC6847_GET_CHARROM_MEMBER( dragon200e_state::char_rom_r )
{
return m_char_rom->base()[(ch * 12 + line) & 0xfff];
@@ -130,6 +158,8 @@ MC6847_GET_CHARROM_MEMBER( dragon200e_state::char_rom_r )
SLOT_INTERFACE_START( dragon_cart )
SLOT_INTERFACE("dragon_fdc", DRAGON_FDC)
SLOT_INTERFACE("sdtandy_fdc", SDTANDY_FDC)
+ SLOT_INTERFACE("jcbsnd", DRAGON_JCBSND) MCFG_SLOT_OPTION_CLOCK("jcbsnd", DERIVED_CLOCK(1, 1))
+ SLOT_INTERFACE("ssc", COCO_SSC) MCFG_SLOT_OPTION_CLOCK("ssc", DERIVED_CLOCK(1, 1))
SLOT_INTERFACE("pak", COCO_PAK)
SLOT_INTERFACE_END
@@ -240,33 +270,20 @@ static MACHINE_CONFIG_DERIVED( dragon200e, dragon64 )
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( d64plus, dragon64 )
- // internal ram
- MCFG_RAM_MODIFY(RAM_TAG)
- MCFG_RAM_DEFAULT_SIZE("128K")
-
// video hardware
MCFG_SCREEN_ADD("plus_screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(50)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
- MCFG_SCREEN_SIZE(640, 240)
- MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 240-1)
- MCFG_SCREEN_UPDATE_DEVICE("hd6845", hd6845_device, screen_update)
+ MCFG_SCREEN_SIZE(640, 264)
+ MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 264-1)
+ MCFG_SCREEN_UPDATE_DEVICE("crtc", hd6845_device, screen_update)
+ MCFG_PALETTE_ADD_MONOCHROME("palette")
// crtc
- MCFG_MC6845_ADD("hd6845", HD6845, "plus_screen", 1000000)
+ MCFG_MC6845_ADD("crtc", HD6845, "plus_screen", 14218000 / 8) /* unknown clock, hand tuned to get ~50 fps */
MCFG_MC6845_SHOW_BORDER_AREA(false)
MCFG_MC6845_CHAR_WIDTH(8)
-
- // TODO:
- // $FFE0 6845 control register
- // $FFE1 6845 data register
- // $FFE2 memory bank register - swaps lower memory banks between the standard dragon memory and the
- // three additional memory banks (A, B, C):
- // 0x00 standard Dragon 32 bank
- // 0x01 Bank C - 2k RAM (videoram)
- // 0x02 Bank A - 32k RAM (ram offset 0x10000)
- // 0x06 Bank B - 32k RAM (ram offset 0x18000)
- //
+ MCFG_MC6845_UPDATE_ROW_CB(d64plus_state, crtc_update_row)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( dgnalpha, dragon_base )
@@ -317,6 +334,9 @@ static MACHINE_CONFIG_DERIVED( dgnalpha, dragon_base )
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( tanodr64, dragon64 )
+ MCFG_DEVICE_MODIFY(":")
+ MCFG_DEVICE_CLOCK(XTAL_14_31818MHz / 4)
+
// video hardware
MCFG_SCREEN_MODIFY(SCREEN_TAG)
MCFG_SCREEN_REFRESH_RATE(60)
@@ -367,7 +387,6 @@ ROM_START(d64plus)
ROM_LOAD("n82s147an.ic12", 0x0000, 0x0200, CRC(92b6728d) SHA1(bcf7c60c4e5608a58587044458d9cacaca4568aa))
ROM_REGION(0x2000, "chargen", 0)
ROM_LOAD("chargen.ic22", 0x0000, 0x2000, CRC(514f1450) SHA1(956c99fcca1b52e79bb5d91dbafc817c992e324a))
- ROM_REGION(0x0800, "videoram", ROMREGION_ERASE)
ROM_END
ROM_START(tanodr64)
@@ -386,11 +405,11 @@ ROM_START(dgnalpha)
ROM_LOAD("alpha_ba.rom", 0x8000, 0x4000, CRC(84f68bf9) SHA1(1983b4fb398e3dd9668d424c666c5a0b3f1e2b69))
ROM_END
-// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
-COMP( 1982, dragon32, 0, 0, dragon32, dragon, dragon_state, 0, "Dragon Data Ltd", "Dragon 32", 0 )
-COMP( 1983, dragon64, dragon32, 0, dragon64, dragon, dragon64_state, 0, "Dragon Data Ltd", "Dragon 64", 0 )
-COMP( 1985, dragon200, dragon32, 0, dragon64, dragon, dragon64_state, 0, "Eurohard S.A.", "Dragon 200", 0 )
-COMP( 1985, dragon200e, dragon32, 0, dragon200e, dragon, dragon200e_state, 0, "Eurohard S.A.", "Dragon 200-E", MACHINE_NOT_WORKING )
-COMP( 1985, d64plus, dragon32, 0, d64plus, dragon, d64plus_state, 0, "Dragon Data Ltd / Compusense", "Dragon 64 Plus", MACHINE_NOT_WORKING )
-COMP( 1983, tanodr64, dragon32, 0, tanodr64, dragon, dragon64_state, 0, "Dragon Data Ltd / Tano Ltd", "Tano Dragon 64 (NTSC)", 0 )
-COMP( 1984, dgnalpha, dragon32, 0, dgnalpha, dragon, dragon_alpha_state, 0, "Dragon Data Ltd", "Dragon Professional (Alpha)", 0 )
+// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
+COMP( 1982, dragon32, 0, 0, dragon32, dragon, dragon_state, 0, "Dragon Data Ltd", "Dragon 32", 0 )
+COMP( 1983, dragon64, dragon32, 0, dragon64, dragon, dragon64_state, 0, "Dragon Data Ltd", "Dragon 64", 0 )
+COMP( 1985, dragon200, dragon32, 0, dragon64, dragon, dragon64_state, 0, "Eurohard S.A.", "Dragon 200", 0 )
+COMP( 1985, dragon200e, dragon32, 0, dragon200e, dragon200e, dragon200e_state, 0, "Eurohard S.A.", "Dragon 200-E", MACHINE_NOT_WORKING )
+COMP( 1985, d64plus, dragon32, 0, d64plus, dragon, d64plus_state, 0, "Dragon Data Ltd / Compusense", "Dragon 64 Plus", 0 )
+COMP( 1983, tanodr64, dragon32, 0, tanodr64, dragon, dragon64_state, 0, "Dragon Data Ltd / Tano Ltd", "Tano Dragon 64 (NTSC)", 0 )
+COMP( 1984, dgnalpha, dragon32, 0, dgnalpha, dragon, dragon_alpha_state, 0, "Dragon Data Ltd", "Dragon Professional (Alpha)", 0 )
diff --git a/src/mame/includes/dragon.h b/src/mame/includes/dragon.h
index 61c42719147..77fe00b8c93 100644
--- a/src/mame/includes/dragon.h
+++ b/src/mame/includes/dragon.h
@@ -95,17 +95,27 @@ class d64plus_state : public dragon64_state
public:
d64plus_state(const machine_config &mconfig, device_type type, const char *tag)
: dragon64_state(mconfig, type, tag)
- , m_hd6845(*this, "hd6845")
- , m_videoram(*this, "videoram")
+ , m_crtc(*this, "crtc")
+ , m_palette(*this, "palette")
+ , m_plus_ram(*this, "plus_ram")
+ , m_video_ram(*this, "video_ram")
, m_char_rom(*this, "chargen")
{
}
- MC6847_GET_CHARROM_MEMBER(char_rom_r);
+ DECLARE_READ8_MEMBER(d64plus_6845_disp_r);
+ DECLARE_WRITE8_MEMBER(d64plus_bank_w);
+ MC6845_UPDATE_ROW(crtc_update_row);
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
private:
- required_device<hd6845_device> m_hd6845;
- required_memory_region m_videoram;
+ required_device<hd6845_device> m_crtc;
+ required_device<palette_device> m_palette;
+ optional_shared_ptr<uint8_t> m_plus_ram;
+ optional_shared_ptr<uint8_t> m_video_ram;
required_memory_region m_char_rom;
};
diff --git a/src/mame/machine/dragon.cpp b/src/mame/machine/dragon.cpp
index 2c800a2280c..2ef1851d7d5 100644
--- a/src/mame/machine/dragon.cpp
+++ b/src/mame/machine/dragon.cpp
@@ -28,9 +28,9 @@ cartline, but is so slow in real terms that it should have very little
impact on the emulation speed.
Re-factored the code common to all machines, and separated the code different,
-into callbacks/functions unique to the machines, in preperation for splitting
+into callbacks/functions unique to the machines, in preparation for splitting
the code for individual machine types into separate files, I have preposed, that
-the CoCo 1/2 should stay in coco.c, and that the coco3 and dragon specifc code
+the CoCo 1/2 should stay in coco.c, and that the coco3 and dragon specific code
should go into coco3.c and dragon.c which should (hopefully) make the code
easier to manage.
P.Harvey-Smith, Dec 2006-Feb 2007
@@ -152,3 +152,105 @@ void dragon64_state::page_rom(bool romswitch)
sam().set_bank_offset(1, offset); // 0x8000-0x9FFF
sam().set_bank_offset(2, offset); // 0xA000-0xBFFF
}
+
+
+/***************************************************************************
+ DRAGON64 PLUS
+***************************************************************************/
+
+//-------------------------------------------------
+// d64plus_6845_disp_r
+//
+// The status of the 6845 display is determined by bit 0 of the $FFE2
+// register as follows:-
+// 1 Video display busy, ie. not blanking
+// 0 Video display available, ie. blanking
+// The display is blanking during a horizontal or vertical retrace period.
+//-------------------------------------------------
+
+READ8_MEMBER(d64plus_state::d64plus_6845_disp_r)
+{
+ return m_crtc->de_r() ? 0xff : 0xfe;
+}
+
+
+//-------------------------------------------------
+// d64plus_bank_w
+//-------------------------------------------------
+
+WRITE8_MEMBER(d64plus_state::d64plus_bank_w)
+{
+ switch (data & 0x06)
+ {
+ case 0: // Standard Dragon 32 Dynamic bank
+ space.install_write_bank(0x0000, 0x7fff, "bank0000_w");
+ space.install_read_bank(0x0000, 0x7fff, "bank0000_r");
+ sam().set_bank_offset(0, 0x0000);
+ break;
+ case 2: // First extra 32K bank (A)
+ space.install_ram(0x0000, 0x7fff, m_plus_ram + 0x0000);
+ break;
+ case 6: // Second extra 32K bank (B)
+ space.install_ram(0x0000, 0x7fff, m_plus_ram + 0x8000);
+ break;
+ default:
+ logerror("unknown bank register $FFE2 = %02x\n", data);
+ break;
+ }
+ if (data & 0x01)
+ {
+ space.install_ram(0x0000, 0x07ff, m_video_ram); // Video RAM bank (C)
+ }
+}
+
+
+MC6845_UPDATE_ROW(d64plus_state::crtc_update_row)
+{
+ for (int column = 0; column < x_count; column++)
+ {
+ uint8_t code = m_video_ram[((ma + column) & 0x7ff)];
+ uint16_t addr = (code << 4) | (ra & 0x0f);
+ uint8_t data = m_char_rom->base()[addr & 0xfff];
+
+ if (column == cursor_x)
+ {
+ data = 0xff;
+ }
+
+ for (int bit = 0; bit < 8; bit++)
+ {
+ int x = (column * 8) + bit;
+ bitmap.pix32(y, x) = m_palette->pen(BIT(data, 7) && de);
+ data <<= 1;
+ }
+ }
+}
+
+
+//-------------------------------------------------
+// device_start
+//-------------------------------------------------
+
+void d64plus_state::device_start()
+{
+ dragon_state::device_start();
+
+ address_space& space = machine().device("maincpu")->memory().space(AS_PROGRAM);
+ space.install_readwrite_handler(0xffe0, 0xffe0, READ8_DEVICE_DELEGATE(m_crtc, mc6845_device, status_r), WRITE8_DEVICE_DELEGATE(m_crtc, mc6845_device, address_w));
+ space.install_readwrite_handler(0xffe1, 0xffe1, READ8_DEVICE_DELEGATE(m_crtc, mc6845_device, register_r), WRITE8_DEVICE_DELEGATE(m_crtc, mc6845_device, register_w));
+ space.install_readwrite_handler(0xffe2, 0xffe2, READ8_DELEGATE(d64plus_state, d64plus_6845_disp_r), WRITE8_DELEGATE(d64plus_state, d64plus_bank_w));
+
+ // allocate memory
+ m_plus_ram.allocate(0x10000);
+ m_video_ram.allocate(0x800);
+}
+
+
+//-------------------------------------------------
+// device_reset
+//-------------------------------------------------
+
+void d64plus_state::device_reset()
+{
+ dragon_state::device_reset();
+}