vic20: Emulated the Data 20 Display Manager 40/80 column video cartridge. [Curt Coder]

This commit is contained in:
Curt Coder 2017-02-06 12:34:31 +02:00
parent 07f104af68
commit f419eba57e
6 changed files with 438 additions and 0 deletions

View file

@ -3908,4 +3908,18 @@
</dataarea>
</part>
</software>
<software name="data20dm">
<description>Data 20 Display Manager</description>
<year>1982</year>
<publisher>Data 20 Corporation</publisher>
<info name="usage" value="SYS 40969 for 40 column mode, SYS 40972 for 80 column mode, SYS 40975 for VIC mode, SYS 40978 to restart 40/80 column mode" />
<sharedfeat name="compatibility" value="NTSC,PAL"/>
<part name="cart" interface="vic1001_cart">
<feature name="slot" value="videopak" />
<dataarea name="blk5" size="0x800">
<rom name="data20.bin" size="0x800" crc="b7b1899f" sha1="aac8388d16d789126a917958282e9bc6da1038c6" offset="0" />
</dataarea>
</part>
</software>
</softwarelist>

View file

@ -71,4 +71,17 @@
</part>
</software>
<software name="data20dm">
<description>Data 20 Display Manager</description>
<year>1982</year>
<publisher>Data 20 Corporation</publisher>
<sharedfeat name="compatibility" value="NTSC,PAL"/>
<sharedfeat name="requirement" value="vic1001_cart:data20dm"/>
<part name="flop1" interface="floppy_5_25">
<dataarea name="flop" size="174848">
<rom name="data20.d64" size="174848" crc="06664680" sha1="1586afa380272d333801992c829707e26f81c455" offset="0" />
</dataarea>
</part>
</software>
</softwarelist>

View file

@ -1427,6 +1427,8 @@ if (BUSES["VIC20"]~=null) then
MAME_DIR .. "src/devices/bus/vic20/vic1112.h",
MAME_DIR .. "src/devices/bus/vic20/vic1210.cpp",
MAME_DIR .. "src/devices/bus/vic20/vic1210.h",
MAME_DIR .. "src/devices/bus/vic20/videopak.cpp",
MAME_DIR .. "src/devices/bus/vic20/videopak.h",
MAME_DIR .. "src/devices/bus/vic20/speakeasy.cpp",
MAME_DIR .. "src/devices/bus/vic20/speakeasy.h",
MAME_DIR .. "src/devices/bus/vic20/user.cpp",

View file

@ -202,6 +202,7 @@ void vic20_expansion_slot_device::cd_w(address_space &space, offs_t offset, uint
#include "vic1111.h"
#include "vic1112.h"
#include "vic1210.h"
#include "videopak.h"
#include "speakeasy.h"
SLOT_INTERFACE_START( vic20_expansion_cards )
@ -211,6 +212,7 @@ SLOT_INTERFACE_START( vic20_expansion_cards )
SLOT_INTERFACE("16k", VIC1111)
SLOT_INTERFACE("fe3", VIC20_FE3)
SLOT_INTERFACE("speakez", VIC20_SPEAKEASY)
SLOT_INTERFACE("videopak", VIC20_VIDEO_PAK)
// the following need ROMs from the software list
SLOT_INTERFACE_INTERNAL("standard", VIC20_STD)

View file

@ -0,0 +1,336 @@
// license:BSD-3-Clause
// copyright-holders:Curt Coder
/**********************************************************************
Data 20 Corporation Video Pak cartridge emulation
aka Data 20 Display Manager aka Protecto 40/80
**********************************************************************/
#include "videopak.h"
//**************************************************************************
// MACROS/CONSTANTS
//**************************************************************************
#define VIDEORAM_SIZE 0x800
#define RAM_SIZE 0x10000
#define MC6845_TAG "mc6845"
#define MC6845_SCREEN_TAG "screen80"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
const device_type VIC20_VIDEO_PAK = &device_creator<vic20_video_pak_t>;
//-------------------------------------------------
// ROM( videopak )
//-------------------------------------------------
ROM_START( videopak )
ROM_REGION( 0x800, MC6845_TAG, 0 )
// ROM has been borrowed from the C64 XL80 cartridge
ROM_LOAD( "chargen", 0x000, 0x800, BAD_DUMP CRC(9edf5e58) SHA1(4b244e6d94a7653a2e52c351589f0b469119fb04) )
ROM_END
//-------------------------------------------------
// rom_region - device-specific ROM region
//-------------------------------------------------
const tiny_rom_entry *vic20_video_pak_t::device_rom_region() const
{
return ROM_NAME( videopak );
}
//-------------------------------------------------
// mc6845
//-------------------------------------------------
MC6845_UPDATE_ROW( vic20_video_pak_t::crtc_update_row )
{
const pen_t *pen = m_palette->pens();
for (int column = 0; column < x_count; column++)
{
uint8_t code = m_videoram[((ma + column) & 0x7ff)];
uint16_t addr = (code << 3) | (ra & 0x07);
uint8_t data = m_char_rom->base()[addr & 0x7ff];
if (column == cursor_x)
{
data = 0xff;
}
for (int bit = 0; bit < 8; bit++)
{
int x = (column * 8) + bit;
int color = BIT(data, 7) && de;
bitmap.pix32(vbp + y, hbp + x) = pen[color];
data <<= 1;
}
}
}
//-------------------------------------------------
// GFXDECODE( vic20_video_pak )
//-------------------------------------------------
static GFXDECODE_START( vic20_video_pak )
GFXDECODE_ENTRY(MC6845_TAG, 0x0000, gfx_8x8x1, 0, 1)
GFXDECODE_END
//-------------------------------------------------
// MACHINE_CONFIG_FRAGMENT( vic20_video_pak )
//-------------------------------------------------
static MACHINE_CONFIG_FRAGMENT( vic20_video_pak )
MCFG_SCREEN_ADD_MONOCHROME(MC6845_SCREEN_TAG, RASTER, rgb_t::white())
MCFG_SCREEN_UPDATE_DEVICE(MC6845_TAG, h46505_device, screen_update)
MCFG_SCREEN_SIZE(80*8, 24*8)
MCFG_SCREEN_VISIBLE_AREA(0, 80*8-1, 0, 24*8-1)
MCFG_SCREEN_REFRESH_RATE(50)
MCFG_GFXDECODE_ADD("gfxdecode", "palette", vic20_video_pak)
MCFG_PALETTE_ADD_MONOCHROME("palette")
MCFG_MC6845_ADD(MC6845_TAG, H46505, MC6845_SCREEN_TAG, XTAL_14_31818MHz / 8)
MCFG_MC6845_SHOW_BORDER_AREA(true)
MCFG_MC6845_CHAR_WIDTH(8)
MCFG_MC6845_UPDATE_ROW_CB(vic20_video_pak_t, crtc_update_row)
MACHINE_CONFIG_END
//-------------------------------------------------
// machine_config_additions - device-specific
// machine configurations
//-------------------------------------------------
machine_config_constructor vic20_video_pak_t::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME( vic20_video_pak );
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// vic20_video_pak_t - constructor
//-------------------------------------------------
vic20_video_pak_t::vic20_video_pak_t(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, VIC20_VIDEO_PAK, "Data 20 Video Pak", tag, owner, clock, "videopak", __FILE__),
device_vic20_expansion_card_interface(mconfig, *this),
m_crtc(*this, MC6845_TAG),
m_palette(*this, "palette"),
m_char_rom(*this, MC6845_TAG),
m_videoram(*this, "videoram"),
m_ram(*this, "ram")
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void vic20_video_pak_t::device_start()
{
// allocate memory
m_videoram.allocate(VIDEORAM_SIZE);
m_ram.allocate(RAM_SIZE);
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void vic20_video_pak_t::device_reset()
{
}
//-------------------------------------------------
// vic20_cd_r - cartridge data read
//-------------------------------------------------
uint8_t vic20_video_pak_t::vic20_cd_r(address_space &space, offs_t offset, uint8_t data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3)
{
if (!m_ram_enable)
{
if (m_bank_size)
{
if (!blk1)
{
offs_t addr = m_bank_msb << 15 | m_bank_lsb << 14 | offset;
data = m_ram[addr];
}
if (!blk2)
{
offs_t addr = m_bank_msb << 15 | m_bank_lsb << 14 | 0x2000 | offset;
data = m_ram[addr];
}
}
else
{
if (!blk1)
{
offs_t addr = m_bank_msb << 15 | offset;
data = m_ram[addr];
}
if (!blk2)
{
offs_t addr = m_bank_msb << 15 | 0x2000 | offset;
data = m_ram[addr];
}
if (!blk3)
{
offs_t addr = m_bank_msb << 15 | 0x4000 | offset;
data = m_ram[addr];
}
}
}
if (!blk5)
{
switch ((offset >> 11) & 0x03)
{
case 0:
data = m_blk5[offset & 0x7ff];
break;
case 3:
data = m_videoram[offset & 0x7ff];
break;
}
}
if (!io2)
{
if (offset == 0x1bf9)
{
data = m_crtc->register_r(space, 0);
}
}
return data;
}
//-------------------------------------------------
// vic20_cd_w - cartridge data write
//-------------------------------------------------
void vic20_video_pak_t::vic20_cd_w(address_space &space, offs_t offset, uint8_t data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3)
{
if (!m_ram_enable)
{
if (m_bank_size)
{
if (!blk1)
{
offs_t addr = m_bank_msb << 15 | m_bank_lsb << 14 | offset;
m_ram[addr] = data;
}
if (!blk2)
{
offs_t addr = m_bank_msb << 15 | m_bank_lsb << 14 | 0x2000 | offset;
m_ram[addr] = data;
}
}
else
{
if (!blk1)
{
offs_t addr = m_bank_msb << 15 | offset;
m_ram[addr] = data;
}
if (!blk2)
{
offs_t addr = m_bank_msb << 15 | 0x2000 | offset;
m_ram[addr] = data;
}
if (!blk3)
{
offs_t addr = m_bank_msb << 15 | 0x4000 | offset;
m_ram[addr] = data;
}
}
}
if (!blk5)
{
switch ((offset >> 11) & 0x03)
{
case 3:
m_videoram[offset & 0x7ff] = data;
break;
}
}
if (!io2)
{
switch (offset)
{
case 0x1bf8:
m_crtc->address_w(space, 0, data);
break;
case 0x1bf9:
m_crtc->register_w(space, 0, data);
break;
case 0x1bfc:
/*
bit description
0 0 = upper case, 1 = lower case
1 bank size: 0 = 2x24KB, 1 = 4x16KB
2 16KB mode address LSB
3 memory address MSB
4 0 = enable RAM, 1 = disable RAM
5 0 = 40 columns, 1 = 80 columns (Data 20 Video Manager)
*/
m_case = BIT(data, 0);
m_bank_size = BIT(data, 1);
m_bank_lsb = BIT(data, 2);
m_bank_msb = BIT(data, 3);
m_ram_enable = BIT(data, 4);
m_columns = BIT(data, 5);
break;
}
}
}

View file

@ -0,0 +1,71 @@
// license:BSD-3-Clause
// copyright-holders:Curt Coder
/**********************************************************************
Data 20 Corporation Video Pak cartridge emulation
aka Data 20 Display Manager aka Protecto 40/80
**********************************************************************/
#pragma once
#ifndef __VIC20_VIDEO_PAK__
#define __VIC20_VIDEO_PAK__
#include "emu.h"
#include "exp.h"
#include "video/mc6845.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> vic20_video_pak_t
class vic20_video_pak_t : public device_t,
public device_vic20_expansion_card_interface
{
public:
// construction/destruction
vic20_video_pak_t(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// optional information overrides
virtual const tiny_rom_entry *device_rom_region() const override;
virtual machine_config_constructor device_mconfig_additions() const override;
// not really public
MC6845_UPDATE_ROW( crtc_update_row );
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
// device_vic20_expansion_card_interface overrides
virtual uint8_t vic20_cd_r(address_space &space, offs_t offset, uint8_t data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3) override;
virtual void vic20_cd_w(address_space &space, offs_t offset, uint8_t data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3) override;
private:
required_device<h46505_device> m_crtc;
required_device<palette_device> m_palette;
required_memory_region m_char_rom;
optional_shared_ptr<uint8_t> m_videoram;
optional_shared_ptr<uint8_t> m_ram;
bool m_case;
bool m_bank_size;
bool m_bank_lsb;
bool m_bank_msb;
bool m_ram_enable;
bool m_columns;
};
// device type definition
extern const device_type VIC20_VIDEO_PAK;
#endif