From acdaf11b7380ead229d3d7f52c2b9e8bdfbb8c84 Mon Sep 17 00:00:00 2001 From: Nigel Barnes Date: Thu, 15 Jun 2017 18:20:27 +0100 Subject: d64plus: Implemented banking of extra 64K, and 6845 with chargen. Machine promoted to WORKING. dragon32: Added JCB Sound Extension cartridge. dragon200e: Added correct keyboard. --- scripts/src/bus.lua | 3 +- src/devices/bus/coco/cococart.h | 9 +-- src/devices/bus/coco/dragon_jcbsnd.cpp | 96 +++++++++++++++++++++++++++++ src/devices/bus/coco/dragon_jcbsnd.h | 44 ++++++++++++++ src/mame/drivers/dragon.cpp | 99 +++++++++++++++++------------- src/mame/includes/dragon.h | 20 +++++-- src/mame/machine/dragon.cpp | 106 ++++++++++++++++++++++++++++++++- 7 files changed, 325 insertions(+), 52 deletions(-) create mode 100644 src/devices/bus/coco/dragon_jcbsnd.cpp create mode 100644 src/devices/bus/coco/dragon_jcbsnd.h 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(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 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 m_hd6845; - required_memory_region m_videoram; + required_device m_crtc; + required_device m_palette; + optional_shared_ptr m_plus_ram; + optional_shared_ptr 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(); +} -- cgit v1.2.3