diff options
Diffstat (limited to 'src/devices/bus/coco/coco_wpk.cpp')
-rw-r--r-- | src/devices/bus/coco/coco_wpk.cpp | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/src/devices/bus/coco/coco_wpk.cpp b/src/devices/bus/coco/coco_wpk.cpp new file mode 100644 index 00000000000..e2750428227 --- /dev/null +++ b/src/devices/bus/coco/coco_wpk.cpp @@ -0,0 +1,200 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + PBJ Word-Pak/Word-Pak II - 80 Column Video Cartridge + + TODO: + - the R6545 Transparent Mode used to update video RAM needs some attention. + - original PBJ WorkPak (not II or RS) had an optional Basic Driver ROM (undumped). + - does WordPak II use different character ROM? + +***************************************************************************/ + +#include "emu.h" +#include "coco_wpk.h" +#include "render.h" +#include "screen.h" + + +//------------------------------------------------- +// ROM( coco_wpk ) +//------------------------------------------------- + +ROM_START(coco_wpk) + ROM_REGION(0x0800, "chargen", 0) + ROM_LOAD("chr_gen_4.0.rom", 0x0000, 0x0800, CRC(6e9a671a) SHA1(0ff5fae512c7f1abe138504d51492404dd86be03)) // from PBJ WordPak RS +ROM_END + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(COCO_WPK, coco_wpk_device, "coco_wpk", "CoCo WordPak") +DEFINE_DEVICE_TYPE(COCO_WPK2, coco_wpk2_device, "coco_wpk2", "CoCo WordPak II") +DEFINE_DEVICE_TYPE(COCO_WPKRS, coco_wpkrs_device, "coco_wpkrs", "CoCo WordPak RS") + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// coco_wpk_device - constructor +//------------------------------------------------- + +coco_wpk_device::coco_wpk_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, type, tag, owner, clock) + , device_cococart_interface(mconfig, *this ) + , m_crtc(*this, "crtc") + , m_palette(*this, "palette") + , m_chargen(*this, "chargen") + , m_video_addr(0) +{ +} + +coco_wpk_device::coco_wpk_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : coco_wpk_device(mconfig, COCO_WPK, tag, owner, clock) +{ +} + +coco_wpk2_device::coco_wpk2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : coco_wpk_device(mconfig, COCO_WPK2, tag, owner, clock) +{ +} + +coco_wpkrs_device::coco_wpkrs_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : coco_wpk_device(mconfig, COCO_WPKRS, tag, owner, clock) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void coco_wpk_device::device_start() +{ + m_video_ram = std::make_unique<u8[]>(0x800); + + save_pointer(NAME(m_video_ram), 0x800); + save_item(NAME(m_video_addr)); +} + +void coco_wpk2_device::device_start() +{ + coco_wpk_device::device_start(); +} + +void coco_wpkrs_device::device_start() +{ + coco_wpk_device::device_start(); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void coco_wpk_device::device_reset() +{ + install_readwrite_handler(0xff98, 0xff98, read8smo_delegate(*m_crtc, FUNC(r6545_1_device::status_r)), write8smo_delegate(*m_crtc, FUNC(r6545_1_device::address_w))); + install_readwrite_handler(0xff99, 0xff99, read8smo_delegate(*m_crtc, FUNC(r6545_1_device::register_r)), write8smo_delegate(*m_crtc, FUNC(r6545_1_device::register_w))); + install_write_handler(0xff9b, 0xff9b, write8smo_delegate(*this, FUNC(coco_wpkrs_device::crtc_display_w))); +} + +void coco_wpk2_device::device_reset() +{ + coco_wpk_device::device_reset(); + + install_write_handler(0xff9c, 0xff9c, write8smo_delegate(*this, FUNC(coco_wpk2_device::video_select_w))); + + machine().render().first_target()->set_view(0); +} + +void coco_wpkrs_device::device_reset() +{ + install_readwrite_handler(0xff76, 0xff76, read8smo_delegate(*m_crtc, FUNC(r6545_1_device::status_r)), write8smo_delegate(*m_crtc, FUNC(r6545_1_device::address_w))); + install_readwrite_handler(0xff77, 0xff77, read8smo_delegate(*m_crtc, FUNC(r6545_1_device::register_r)), write8smo_delegate(*m_crtc, FUNC(r6545_1_device::register_w))); + install_write_handler(0xff79, 0xff79, write8smo_delegate(*this, FUNC(coco_wpkrs_device::crtc_display_w))); +} + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void coco_wpk_device::device_add_mconfig(machine_config &config) +{ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_raw(14.318181_MHz_XTAL, 896, 0, 640, 290, 0, 240); + screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update)); + + PALETTE(config, m_palette, palette_device::MONOCHROME); + + R6545_1(config, m_crtc, 14.318181_MHz_XTAL / 8); + m_crtc->set_screen("screen"); + m_crtc->set_show_border_area(false); + m_crtc->set_char_width(8); + m_crtc->set_on_update_addr_change_callback(FUNC(coco_wpkrs_device::crtc_addr)); + m_crtc->set_update_row_callback(FUNC(coco_wpkrs_device::crtc_update_row)); +} + + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const tiny_rom_entry *coco_wpk_device::device_rom_region() const +{ + return ROM_NAME( coco_wpk ); +} + + +void coco_wpk_device::crtc_display_w(u8 data) +{ + //logerror("crtc_display_w: %02x\n", data); + m_video_ram[m_video_addr] = data; + + m_crtc->register_r(); +} + + +MC6845_ON_UPDATE_ADDR_CHANGED(coco_wpk_device::crtc_addr) +{ + //logerror("crtc_addr: %04x %d\n", address, strobe); + m_video_addr = address; +} + + +MC6845_UPDATE_ROW(coco_wpk_device::crtc_update_row) +{ + u32 *p = &bitmap.pix(y); + + for (int column = 0; column < x_count; column++) + { + u8 code = m_video_ram[(ma + column) & 0x7ff]; + u16 addr = (code << 4) | (ra & 0x0f); + u8 data = m_chargen->base()[addr & 0x7ff]; + + if (column == cursor_x) + { + data = 0xff; + } + + for (int bit = 0; bit < 8; bit++) + { + *p++ = m_palette->pen(BIT(data, 0) && de); + + data >>= 1; + } + } +} + + +void coco_wpk2_device::video_select_w(u8 data) +{ + // software video switch (Word-Pak II only) + machine().render().first_target()->set_view(BIT(data, 6)); +} |