Nascom: Add support for the Advanced Video Card (AVC)

This commit is contained in:
Dirk Best 2015-05-18 12:57:09 +02:00
parent eaa3a955f7
commit 48aee7d615
8 changed files with 268 additions and 3 deletions

View File

@ -2426,6 +2426,8 @@ if (BUSES["NASBUS"]~=null) then
MAME_DIR .. "src/emu/bus/nasbus/nasbus.h",
MAME_DIR .. "src/emu/bus/nasbus/cards.c",
MAME_DIR .. "src/emu/bus/nasbus/cards.h",
MAME_DIR .. "src/emu/bus/nasbus/avc.c",
MAME_DIR .. "src/emu/bus/nasbus/avc.h",
MAME_DIR .. "src/emu/bus/nasbus/floppy.c",
MAME_DIR .. "src/emu/bus/nasbus/floppy.h",
}

173
src/emu/bus/nasbus/avc.c Normal file
View File

@ -0,0 +1,173 @@
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
Nascom Advanced Video Card
***************************************************************************/
#include "avc.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
const device_type NASCOM_AVC = &device_creator<nascom_avc_device>;
//-------------------------------------------------
// machine_config_additions - device-specific
// machine configurations
//-------------------------------------------------
static MACHINE_CONFIG_FRAGMENT( nascom_avc )
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_RAW_PARAMS(16250000, 1024, 0, 768, 320, 0, 256)
MCFG_SCREEN_UPDATE_DEVICE("mc6845", mc6845_device, screen_update)
MCFG_MC6845_ADD("mc6845", MC6845, "screen", XTAL_16MHz / 8)
MCFG_MC6845_SHOW_BORDER_AREA(false)
MCFG_MC6845_CHAR_WIDTH(6)
MCFG_MC6845_UPDATE_ROW_CB(nascom_avc_device, crtc_update_row)
MACHINE_CONFIG_END
machine_config_constructor nascom_avc_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME( nascom_avc );
}
const rgb_t nascom_avc_device::m_palette[] =
{
rgb_t::black,
rgb_t(0xff, 0x00, 0x00),
rgb_t(0x00, 0xff, 0x00),
rgb_t(0xff, 0xff, 0x00),
rgb_t(0x00, 0x00, 0xff),
rgb_t(0xff, 0x00, 0xff),
rgb_t(0x00, 0xff, 0xff),
rgb_t::white,
};
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// nascom_avc_device - constructor
//-------------------------------------------------
nascom_avc_device::nascom_avc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, NASCOM_AVC, "Nascom Advanced Video Card", tag, owner, clock, "nascom_avc", __FILE__),
device_nasbus_card_interface(mconfig, *this),
m_crtc(*this, "mc6845"),
m_control(0x80)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void nascom_avc_device::device_start()
{
// allocate memory
m_r_ram.resize(0x4000);
m_g_ram.resize(0x4000);
m_b_ram.resize(0x4000);
save_item(NAME(m_r_ram));
save_item(NAME(m_g_ram));
save_item(NAME(m_b_ram));
save_item(NAME(m_control));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void nascom_avc_device::device_reset()
{
m_nasbus->m_io->install_write_handler(0xb0, 0xb0, write8_delegate(FUNC(mc6845_device::address_w), m_crtc.target()));
m_nasbus->m_io->install_readwrite_handler(0xb1, 0xb1, read8_delegate(FUNC(mc6845_device::register_r), m_crtc.target()), write8_delegate(FUNC(mc6845_device::register_w), m_crtc.target()));
m_nasbus->m_io->install_write_handler(0xb2, 0xb2, write8_delegate(FUNC(nascom_avc_device::control_w), this));
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
MC6845_UPDATE_ROW( nascom_avc_device::crtc_update_row )
{
offs_t base_addr = (ma << 1 | ra << 6) + 2; // y * 64 + 2
for (int x = 0; x < x_count * 6; x++)
{
// addr of source byte
offs_t addr = base_addr + (x / 16);
// msb first
int bl = 7 - ((x / 2) & 7);
int bh = 7 - ((x / 1) & 7);
int r, g, b;
// double density)
if (BIT(m_control, 3))
{
// red disabled, blue low density, red/green combined to green
r = 0;
b = BIT(m_b_ram[addr], bl);
g = (x & 8) ? BIT(m_r_ram[addr], bh) : BIT(m_g_ram[addr], bh);
}
else
{
// rgb color
r = BIT(m_r_ram[addr], bl);
g = BIT(m_g_ram[addr], bl);
b = BIT(m_b_ram[addr], bl);
}
// plot the pixel
bitmap.pix32(y, x) = m_palette[(b << 2) | (g << 1) | (r << 0)];
}
}
WRITE8_MEMBER( nascom_avc_device::control_w )
{
logerror("nascom_avc_device::control_w: 0x%02x\n", data);
// page video ram in?
if (((m_control & 0x07) == 0) && (data & 0x07))
{
m_nasbus->ram_disable_w(0);
m_nasbus->m_program->install_readwrite_handler(0x8000, 0xbfff, read8_delegate(FUNC(nascom_avc_device::vram_r), this), write8_delegate(FUNC(nascom_avc_device::vram_w), this));
}
else if ((data & 0x07) == 0)
{
m_nasbus->m_program->unmap_readwrite(0x8000, 0xbfff);
m_nasbus->ram_disable_w(1);
}
m_control = data;
}
READ8_MEMBER( nascom_avc_device::vram_r )
{
// manual says only one plane can be read, i assume this is the order
if (BIT(m_control, 0)) return m_r_ram[offset];
if (BIT(m_control, 1)) return m_g_ram[offset];
if (BIT(m_control, 2)) return m_b_ram[offset];
// should never happen
return 0xff;
}
WRITE8_MEMBER( nascom_avc_device::vram_w )
{
// all planes can be written at the same time
if (BIT(m_control, 0)) m_r_ram[offset] = data;
if (BIT(m_control, 1)) m_g_ram[offset] = data;
if (BIT(m_control, 2)) m_b_ram[offset] = data;
}

57
src/emu/bus/nasbus/avc.h Normal file
View File

@ -0,0 +1,57 @@
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
Nascom Advanced Video Card
***************************************************************************/
#pragma once
#ifndef __NASBUS_AVC_H__
#define __NASBUS_AVC_H__
#include "emu.h"
#include "nasbus.h"
#include "video/mc6845.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> nascom_avc_device
class nascom_avc_device : public device_t, public device_nasbus_card_interface
{
public:
// construction/destruction
nascom_avc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
MC6845_UPDATE_ROW(crtc_update_row);
DECLARE_WRITE8_MEMBER(control_w);
READ8_MEMBER(vram_r);
WRITE8_MEMBER(vram_w);
protected:
virtual machine_config_constructor device_mconfig_additions() const;
virtual void device_start();
virtual void device_reset();
private:
required_device<mc6845_device> m_crtc;
std::vector<UINT8> m_r_ram;
std::vector<UINT8> m_g_ram;
std::vector<UINT8> m_b_ram;
UINT8 m_control;
static const rgb_t m_palette[];
};
// device type definition
extern const device_type NASCOM_AVC;
#endif // __NASBUS_AVC_H__

View File

@ -9,5 +9,6 @@
#include "cards.h"
SLOT_INTERFACE_START( nasbus_slot_cards )
SLOT_INTERFACE("avc", NASCOM_AVC)
SLOT_INTERFACE("floppy", NASCOM_FDC)
SLOT_INTERFACE_END

View File

@ -13,6 +13,7 @@
#include "emu.h"
#include "avc.h"
#include "floppy.h"
SLOT_INTERFACE_EXTERN( nasbus_slot_cards );

View File

@ -72,7 +72,8 @@ const device_type NASBUS = &device_creator<nasbus_device>;
nasbus_device::nasbus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, NASBUS_SLOT, "NASBUS Backplane", tag, owner, clock, "nasbus", __FILE__),
m_program(NULL),
m_io(NULL)
m_io(NULL),
m_ram_disable_handler(*this)
{
}
@ -91,6 +92,8 @@ nasbus_device::~nasbus_device()
void nasbus_device::device_start()
{
// resolve callbacks
m_ram_disable_handler.resolve_safe();
}
//-------------------------------------------------
@ -129,6 +132,9 @@ void nasbus_device::set_io_space(address_space *io)
m_io = io;
}
// callbacks from slot device to the host
WRITE_LINE_MEMBER( nasbus_device::ram_disable_w ) { m_ram_disable_handler(state); }
//**************************************************************************
// CARTRIDGE INTERFACE

View File

@ -114,6 +114,9 @@
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \
nasbus_slot_device::set_nasbus_slot(*device, owner, NASBUS_TAG);
#define MCFG_NASBUS_RAM_DISABLE_HANDLER(_devcb) \
devcb = &nasbus_device::set_ram_disable_handler(*device, DEVCB_##_devcb);
//**************************************************************************
// TYPE DEFINITIONS
@ -155,11 +158,17 @@ public:
nasbus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
virtual ~nasbus_device();
template<class _Object> static devcb_base &set_ram_disable_handler(device_t &device, _Object object)
{ return downcast<nasbus_device &>(device).m_ram_disable_handler.set_callback(object); }
void add_card(device_nasbus_card_interface *card);
void set_program_space(address_space *program);
void set_io_space(address_space *io);
// from cards
DECLARE_WRITE_LINE_MEMBER( ram_disable_w );
address_space *m_program;
address_space *m_io;
@ -170,6 +179,8 @@ protected:
private:
simple_list<device_nasbus_card_interface> m_dev;
devcb_write_line m_ram_disable_handler;
};
// device type definition

View File

@ -109,6 +109,8 @@ public:
m_socket2(*this, "socket2")
{}
DECLARE_WRITE_LINE_MEMBER(ram_disable_w);
virtual DECLARE_DRIVER_INIT(nascom);
UINT32 screen_update_nascom(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
@ -342,6 +344,17 @@ DRIVER_INIT_MEMBER( nascom2_state, nascom )
m_nasbus->set_io_space(&m_maincpu->space(AS_IO));
}
// since we don't know for which regions we should disable ram, we just let other devices
// overwrite the region they need, and re-install our ram when they are disabled
WRITE_LINE_MEMBER( nascom2_state::ram_disable_w )
{
if (state)
{
// enable ram again
m_maincpu->space(AS_PROGRAM).install_ram(0x1000, 0x1000 + m_ram->size() - 1, m_ram->pointer());
}
}
//**************************************************************************
// VIDEO
@ -574,8 +587,8 @@ static MACHINE_CONFIG_START( nascom1, nascom1_state )
// internal extra ram
MCFG_RAM_ADD(RAM_TAG)
MCFG_RAM_DEFAULT_SIZE("32K")
MCFG_RAM_EXTRA_OPTIONS("8K,16K")
MCFG_RAM_DEFAULT_SIZE("48K")
MCFG_RAM_EXTRA_OPTIONS("8K,16K,32K")
// devices
MCFG_SNAPSHOT_ADD("snapshot", nascom_state, nascom1, "nas", 0.5)
@ -606,6 +619,7 @@ static MACHINE_CONFIG_DERIVED_CLASS( nascom2, nascom1, nascom2_state )
// nasbus expansion bus
MCFG_NASBUS_ADD(NASBUS_TAG)
MCFG_NASBUS_RAM_DISABLE_HANDLER(WRITELINE(nascom2_state, ram_disable_w))
MCFG_NASBUS_SLOT_ADD("nasbus1", nasbus_slot_cards, NULL)
MCFG_NASBUS_SLOT_ADD("nasbus2", nasbus_slot_cards, NULL)
MCFG_NASBUS_SLOT_ADD("nasbus3", nasbus_slot_cards, NULL)