mirror of
https://github.com/holub/mame
synced 2025-04-19 23:12:11 +03:00
(MESS) vic20: Emulated the Final Expansion 3 cartridge (only RAM/FlashROM supported). [Curt Coder]
This commit is contained in:
parent
d1b8b6739c
commit
1327a26a55
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1657,6 +1657,8 @@ src/emu/bus/vic20/4cga.c svneol=native#text/plain
|
||||
src/emu/bus/vic20/4cga.h svneol=native#text/plain
|
||||
src/emu/bus/vic20/exp.c svneol=native#text/plain
|
||||
src/emu/bus/vic20/exp.h svneol=native#text/plain
|
||||
src/emu/bus/vic20/fe3.c svneol=native#text/plain
|
||||
src/emu/bus/vic20/fe3.h svneol=native#text/plain
|
||||
src/emu/bus/vic20/megacart.c svneol=native#text/plain
|
||||
src/emu/bus/vic20/megacart.h svneol=native#text/plain
|
||||
src/emu/bus/vic20/std.c svneol=native#text/plain
|
||||
|
@ -735,6 +735,7 @@ endif
|
||||
ifneq ($(filter VIC20,$(BUSES)),)
|
||||
OBJDIRS += $(BUSOBJ)/vic20
|
||||
BUSOBJS += $(BUSOBJ)/vic20/exp.o
|
||||
BUSOBJS += $(BUSOBJ)/vic20/fe3.o
|
||||
BUSOBJS += $(BUSOBJ)/vic20/megacart.o
|
||||
BUSOBJS += $(BUSOBJ)/vic20/std.o
|
||||
BUSOBJS += $(BUSOBJ)/vic20/vic1010.o
|
||||
|
@ -209,6 +209,7 @@ void vic20_expansion_slot_device::cd_w(address_space &space, offs_t offset, UINT
|
||||
//-------------------------------------------------
|
||||
|
||||
// slot devices
|
||||
#include "fe3.h"
|
||||
#include "megacart.h"
|
||||
#include "std.h"
|
||||
#include "vic1010.h"
|
||||
@ -222,6 +223,7 @@ SLOT_INTERFACE_START( vic20_expansion_cards )
|
||||
SLOT_INTERFACE("3k", VIC1210)
|
||||
SLOT_INTERFACE("8k", VIC1110)
|
||||
SLOT_INTERFACE("16k", VIC1111)
|
||||
SLOT_INTERFACE("fe3", VIC20_FE3)
|
||||
|
||||
// the following need ROMs from the software list
|
||||
SLOT_INTERFACE_INTERNAL("standard", VIC20_STD)
|
||||
|
638
src/emu/bus/vic20/fe3.c
Normal file
638
src/emu/bus/vic20/fe3.c
Normal file
@ -0,0 +1,638 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Curt Coder
|
||||
/**********************************************************************
|
||||
|
||||
Final Expansion v3 cartridge emulation
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
TODO:
|
||||
|
||||
- fe3diag register error#2 hp=5592 (same error in VICE)
|
||||
- SD card
|
||||
- RTC
|
||||
|
||||
*/
|
||||
|
||||
#include "fe3.h"
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// MACROS/CONSTANTS
|
||||
//**************************************************************************
|
||||
|
||||
#define AM29F040_TAG "am29f040"
|
||||
|
||||
#define REG1_BANK \
|
||||
((m_reg1 & 0x7f) << 15)
|
||||
|
||||
#define REG2_BLK0_VISIBLE \
|
||||
(!(m_reg2 & REG2_BLK0))
|
||||
|
||||
#define REG2_BLK1_VISIBLE \
|
||||
(!(m_reg2 & REG2_BLK1))
|
||||
|
||||
#define REG2_BLK2_VISIBLE \
|
||||
(!(m_reg2 & REG2_BLK2))
|
||||
|
||||
#define REG2_BLK3_VISIBLE \
|
||||
(!(m_reg2 & REG2_BLK3))
|
||||
|
||||
#define REG2_BLK5_VISIBLE \
|
||||
(!(m_reg2 & REG2_BLK5))
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
const device_type VIC20_FE3 = &device_creator<vic20_final_expansion_3_t>;
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ROM( vic20_fe3 )
|
||||
//-------------------------------------------------
|
||||
|
||||
ROM_START( vic20_fe3 )
|
||||
ROM_REGION( 0x80000, AM29F040_TAG, 0 )
|
||||
ROM_LOAD( "fe3r022d.bin", 0x00000, 0x80000, CRC(f4ff4aee) SHA1(1a389120159dee09c0f03ecb8fcd51ea2a2d2306) )
|
||||
ROM_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// rom_region - device-specific ROM region
|
||||
//-------------------------------------------------
|
||||
|
||||
const rom_entry *vic20_final_expansion_3_t::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME( vic20_fe3 );
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// MACHINE_DRIVER( vic20_fe3 )
|
||||
//-------------------------------------------------
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( vic20_fe3 )
|
||||
MCFG_AMD_29F040_ADD(AM29F040_TAG)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// machine_config_additions - device-specific
|
||||
// machine configurations
|
||||
//-------------------------------------------------
|
||||
|
||||
machine_config_constructor vic20_final_expansion_3_t::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( vic20_fe3 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// vic20_final_expansion_3_t - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
vic20_final_expansion_3_t::vic20_final_expansion_3_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
device_t(mconfig, VIC20_FE3, "Final Expansion v3", tag, owner, clock, "vic20_fe3", __FILE__),
|
||||
device_vic20_expansion_card_interface(mconfig, *this),
|
||||
m_flash_rom(*this, AM29F040_TAG),
|
||||
m_ram(*this, "sram")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void vic20_final_expansion_3_t::device_start()
|
||||
{
|
||||
m_ram.allocate(0x80000);
|
||||
|
||||
// state saving
|
||||
save_item(NAME(m_reg1));
|
||||
save_item(NAME(m_reg2));
|
||||
save_item(NAME(m_lockbit));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void vic20_final_expansion_3_t::device_reset()
|
||||
{
|
||||
m_reg1 = 0;
|
||||
m_reg2 = 0;
|
||||
m_lockbit = true;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// vic20_cd_r - cartridge data read
|
||||
//-------------------------------------------------
|
||||
|
||||
UINT8 vic20_final_expansion_3_t::vic20_cd_r(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3)
|
||||
{
|
||||
switch (m_reg1 & REG1_MODE_MASK)
|
||||
{
|
||||
case REG1_START:
|
||||
// read from ROM
|
||||
if (!blk5)
|
||||
{
|
||||
data = m_flash_rom->read(get_address(0, 3, offset));
|
||||
|
||||
m_lockbit = true;
|
||||
}
|
||||
|
||||
// read from registers
|
||||
if (!io3 && !m_lockbit && ((offset & 0x1c02) == 0x1c02))
|
||||
{
|
||||
data = read_register(BIT(offset, 0));
|
||||
}
|
||||
break;
|
||||
|
||||
case REG1_SUPER_ROM:
|
||||
// read from RAM bank 0
|
||||
if ((!ram1 || !ram2 || !ram3) && REG2_BLK0_VISIBLE)
|
||||
{
|
||||
data = m_ram[get_address(0, 0, offset)];
|
||||
}
|
||||
|
||||
// read from ROM
|
||||
if (!blk1 && REG2_BLK1_VISIBLE)
|
||||
{
|
||||
data = m_flash_rom->read(get_address(REG1_BANK, 0, offset));
|
||||
}
|
||||
if (!blk2 && REG2_BLK2_VISIBLE)
|
||||
{
|
||||
data = m_flash_rom->read(get_address(REG1_BANK, 1, offset));
|
||||
}
|
||||
if (!blk3 && REG2_BLK3_VISIBLE)
|
||||
{
|
||||
data = m_flash_rom->read(get_address(REG1_BANK, 2, offset));
|
||||
}
|
||||
if (!blk5 && REG2_BLK5_VISIBLE)
|
||||
{
|
||||
data = m_flash_rom->read(get_address(REG1_BANK, 3, offset));
|
||||
}
|
||||
|
||||
// read from registers
|
||||
if (!io3 && !(m_reg2 & REG2_IO3) && ((offset & 0x1c02) == 0x1c02))
|
||||
{
|
||||
data = read_register(BIT(offset, 0));
|
||||
}
|
||||
break;
|
||||
|
||||
case REG1_RAM_1:
|
||||
// read from RAM bank 0
|
||||
if ((!ram1 || !ram2 || !ram3) && REG2_BLK0_VISIBLE)
|
||||
{
|
||||
data = m_ram[get_address(0, 0, offset)];
|
||||
}
|
||||
|
||||
// read from RAM bank 1
|
||||
if (!blk1 && REG2_BLK1_VISIBLE)
|
||||
{
|
||||
data = m_ram[get_address(1, 0, offset)];
|
||||
}
|
||||
if (!blk2 && REG2_BLK2_VISIBLE)
|
||||
{
|
||||
data = m_ram[get_address(1, 1, offset)];
|
||||
}
|
||||
if (!blk3 && REG2_BLK3_VISIBLE)
|
||||
{
|
||||
data = m_ram[get_address(1, 2, offset)];
|
||||
}
|
||||
if (!blk5 && REG2_BLK5_VISIBLE)
|
||||
{
|
||||
data = m_ram[get_address(1, 3, offset)];
|
||||
}
|
||||
|
||||
// read from registers
|
||||
if (!io3 && !(m_reg2 & REG2_IO3) && ((offset & 0x1c02) == 0x1c02))
|
||||
{
|
||||
data = read_register(BIT(offset, 0));
|
||||
}
|
||||
break;
|
||||
|
||||
case REG1_RAM_2:
|
||||
// read from RAM bank 0
|
||||
if ((!ram1 || !ram2 || !ram3) && REG2_BLK0_VISIBLE)
|
||||
{
|
||||
data = m_ram[get_address(0, 0, offset)];
|
||||
}
|
||||
|
||||
// read from RAM bank 1 or 2
|
||||
if (!blk1 && REG2_BLK1_VISIBLE)
|
||||
{
|
||||
data = m_ram[get_address((m_reg1 & REG1_BLK1) ? 2 : 1, 0, offset)];
|
||||
}
|
||||
if (!blk2 && REG2_BLK2_VISIBLE)
|
||||
{
|
||||
data = m_ram[get_address((m_reg1 & REG1_BLK2) ? 2 : 1, 1, offset)];
|
||||
}
|
||||
if (!blk3 && REG2_BLK3_VISIBLE)
|
||||
{
|
||||
data = m_ram[get_address((m_reg1 & REG1_BLK3) ? 2 : 1, 2, offset)];
|
||||
}
|
||||
if (!blk5 && REG2_BLK5_VISIBLE)
|
||||
{
|
||||
data = m_ram[get_address((m_reg1 & REG1_BLK5) ? 2 : 1, 3, offset)];
|
||||
}
|
||||
|
||||
// read from registers
|
||||
if (!io3 && !(m_reg2 & REG2_IO3) && ((offset & 0x1c02) == 0x1c02))
|
||||
{
|
||||
data = read_register(BIT(offset, 0));
|
||||
}
|
||||
break;
|
||||
|
||||
case REG1_SUPER_RAM:
|
||||
// read from RAM bank 0
|
||||
if ((!ram1 || !ram2 || !ram3) && REG2_BLK0_VISIBLE)
|
||||
{
|
||||
data = m_ram[get_address(0, 0, offset)];
|
||||
}
|
||||
|
||||
// read from any RAM bank
|
||||
if (!blk1 && REG2_BLK1_VISIBLE)
|
||||
{
|
||||
data = m_ram[get_address(REG1_BANK, 0, offset)];
|
||||
}
|
||||
if (!blk2 && REG2_BLK2_VISIBLE)
|
||||
{
|
||||
data = m_ram[get_address(REG1_BANK, 1, offset)];
|
||||
}
|
||||
if (!blk3 && REG2_BLK3_VISIBLE)
|
||||
{
|
||||
data = m_ram[get_address(REG1_BANK, 2, offset)];
|
||||
}
|
||||
if (!blk5 && REG2_BLK5_VISIBLE)
|
||||
{
|
||||
data = m_ram[get_address(REG1_BANK, 3, offset)];
|
||||
}
|
||||
|
||||
// read from registers
|
||||
if (!io3 && !(m_reg2 & REG2_IO3) && ((offset & 0x1c02) == 0x1c02))
|
||||
{
|
||||
data = read_register(BIT(offset, 0));
|
||||
}
|
||||
break;
|
||||
|
||||
case REG1_RAM_ROM:
|
||||
// read from RAM bank 0
|
||||
if ((!ram1 || !ram2 || !ram3) && REG2_BLK0_VISIBLE)
|
||||
{
|
||||
data = m_ram[get_address(0, 0, offset)];
|
||||
}
|
||||
|
||||
// read from ROM bank 0 or RAM bank 1
|
||||
if (!blk1 && REG2_BLK1_VISIBLE)
|
||||
{
|
||||
data = (m_reg1 & REG1_BLK1) ? m_flash_rom->read(get_address(0, 0, offset)) : m_ram[get_address(1, 0, offset)];
|
||||
}
|
||||
if (!blk2 && REG2_BLK2_VISIBLE)
|
||||
{
|
||||
data = (m_reg1 & REG1_BLK2) ? m_flash_rom->read(get_address(0, 1, offset)) : m_ram[get_address(1, 1, offset)];
|
||||
}
|
||||
if (!blk3 && REG2_BLK3_VISIBLE)
|
||||
{
|
||||
data = (m_reg1 & REG1_BLK3) ? m_flash_rom->read(get_address(0, 2, offset)) : m_ram[get_address(1, 2, offset)];
|
||||
}
|
||||
if (!blk5 && REG2_BLK5_VISIBLE)
|
||||
{
|
||||
data = (m_reg1 & REG1_BLK5) ? m_flash_rom->read(get_address(0, 3, offset)) : m_ram[get_address(1, 3, offset)];
|
||||
}
|
||||
|
||||
// read from registers
|
||||
if (!io3 && !(m_reg2 & REG2_IO3) && ((offset & 0x1c02) == 0x1c02))
|
||||
{
|
||||
data = read_register(BIT(offset, 0));
|
||||
}
|
||||
break;
|
||||
|
||||
case REG1_FLASH:
|
||||
// read from RAM bank 0
|
||||
if ((!ram1 || !ram2 || !ram3) && REG2_BLK0_VISIBLE)
|
||||
{
|
||||
data = m_ram[get_address(0, 0, offset)];
|
||||
}
|
||||
|
||||
// read from ROM
|
||||
if (!blk1 && REG2_BLK1_VISIBLE)
|
||||
{
|
||||
data = m_flash_rom->read(get_address(REG1_BANK, 0, offset));
|
||||
}
|
||||
if (!blk2 && REG2_BLK2_VISIBLE)
|
||||
{
|
||||
data = m_flash_rom->read(get_address(REG1_BANK, 1, offset));
|
||||
}
|
||||
if (!blk3 && REG2_BLK3_VISIBLE)
|
||||
{
|
||||
data = m_flash_rom->read(get_address(REG1_BANK, 2, offset));
|
||||
}
|
||||
if (!blk5 && REG2_BLK5_VISIBLE)
|
||||
{
|
||||
data = m_flash_rom->read(get_address(REG1_BANK, 3, offset));
|
||||
}
|
||||
|
||||
// read from registers
|
||||
if (!io3 && !(m_reg2 & REG2_IO3) && ((offset & 0x1c02) == 0x1c02))
|
||||
{
|
||||
data = read_register(BIT(offset, 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// vic20_cd_w - cartridge data write
|
||||
//-------------------------------------------------
|
||||
|
||||
void vic20_final_expansion_3_t::vic20_cd_w(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3)
|
||||
{
|
||||
offs_t addr = 0;
|
||||
|
||||
switch (m_reg1 & REG1_MODE_MASK)
|
||||
{
|
||||
case REG1_START:
|
||||
// write to RAM bank 1
|
||||
if (!blk5)
|
||||
{
|
||||
m_ram[get_address(1, 3, offset)] = data;
|
||||
|
||||
m_lockbit = false;
|
||||
}
|
||||
|
||||
// write to registers
|
||||
if (!io3 && !m_lockbit && ((offset & 0x1c02) == 0x1c02))
|
||||
{
|
||||
write_register(BIT(offset, 0), data);
|
||||
}
|
||||
break;
|
||||
|
||||
case REG1_SUPER_ROM:
|
||||
addr = 0x8000 | offset;
|
||||
|
||||
// write to RAM bank 0
|
||||
if ((!ram1 || !ram2 || !ram3) && REG2_BLK0_VISIBLE)
|
||||
{
|
||||
m_ram[get_address(0, 0, offset)] = data;
|
||||
}
|
||||
|
||||
// write to RAM bank 1
|
||||
if (!blk1 && REG2_BLK1_VISIBLE)
|
||||
{
|
||||
m_ram[get_address(1, 0, offset)] = data;
|
||||
}
|
||||
if (!blk2 && REG2_BLK2_VISIBLE)
|
||||
{
|
||||
m_ram[get_address(1, 1, offset)] = data;
|
||||
}
|
||||
if (!blk3 && REG2_BLK3_VISIBLE)
|
||||
{
|
||||
m_ram[get_address(1, 2, offset)] = data;
|
||||
}
|
||||
if (!blk5 && REG2_BLK5_VISIBLE)
|
||||
{
|
||||
m_ram[get_address(1, 3, offset)] = data;
|
||||
}
|
||||
|
||||
// write to registers
|
||||
if (!io3 && !(m_reg2 & REG2_IO3) && ((offset & 0x1c02) == 0x1c02))
|
||||
{
|
||||
write_register(BIT(offset, 0), data);
|
||||
}
|
||||
break;
|
||||
|
||||
case REG1_RAM_1:
|
||||
// write to RAM bank 0
|
||||
if ((!ram1 || !ram2 || !ram3) && REG2_BLK0_VISIBLE && REG1_BLK0)
|
||||
{
|
||||
m_ram[get_address(0, 0, offset)] = data;
|
||||
}
|
||||
|
||||
// write to RAM bank 1 or 2
|
||||
if (!blk1 && REG2_BLK1_VISIBLE)
|
||||
{
|
||||
m_ram[get_address((m_reg1 & REG1_BLK1) ? 2 : 1, 0, offset)] = data;
|
||||
}
|
||||
if (!blk2 && REG2_BLK2_VISIBLE)
|
||||
{
|
||||
m_ram[get_address((m_reg1 & REG1_BLK2) ? 2 : 1, 1, offset)] = data;
|
||||
}
|
||||
if (!blk3 && REG2_BLK3_VISIBLE)
|
||||
{
|
||||
m_ram[get_address((m_reg1 & REG1_BLK3) ? 2 : 1, 2, offset)] = data;
|
||||
}
|
||||
if (!blk5 && REG2_BLK5_VISIBLE)
|
||||
{
|
||||
m_ram[get_address((m_reg1 & REG1_BLK5) ? 2 : 1, 3, offset)] = data;
|
||||
}
|
||||
|
||||
// write to registers
|
||||
if (!io3 && !(m_reg2 & REG2_IO3) && ((offset & 0x1c02) == 0x1c02))
|
||||
{
|
||||
write_register(BIT(offset, 0), data);
|
||||
}
|
||||
break;
|
||||
|
||||
case REG1_RAM_2:
|
||||
// write to RAM bank 0
|
||||
if ((!ram1 || !ram2 || !ram3) && REG2_BLK0_VISIBLE && REG1_BLK0)
|
||||
{
|
||||
m_ram[get_address(0, 0, offset)] = data;
|
||||
}
|
||||
|
||||
// write to RAM bank 1
|
||||
if (!blk1 && REG2_BLK1_VISIBLE)
|
||||
{
|
||||
m_ram[get_address(1, 0, offset)] = data;
|
||||
}
|
||||
if (!blk2 && REG2_BLK2_VISIBLE)
|
||||
{
|
||||
m_ram[get_address(1, 1, offset)] = data;
|
||||
}
|
||||
if (!blk3 && REG2_BLK3_VISIBLE)
|
||||
{
|
||||
m_ram[get_address(1, 2, offset)] = data;
|
||||
}
|
||||
if (!blk5 && REG2_BLK5_VISIBLE)
|
||||
{
|
||||
m_ram[get_address(1, 3, offset)] = data;
|
||||
}
|
||||
|
||||
// write to registers
|
||||
if (!io3 && !(m_reg2 & REG2_IO3) && ((offset & 0x1c02) == 0x1c02))
|
||||
{
|
||||
write_register(BIT(offset, 0), data);
|
||||
}
|
||||
break;
|
||||
|
||||
case REG1_SUPER_RAM:
|
||||
// write to RAM bank 0
|
||||
if ((!ram1 || !ram2 || !ram3) && REG2_BLK0_VISIBLE)
|
||||
{
|
||||
m_ram[get_address(0, 0, offset)] = data;
|
||||
}
|
||||
|
||||
// write whole RAM
|
||||
if (!blk1 && REG2_BLK1_VISIBLE)
|
||||
{
|
||||
m_ram[get_address(REG1_BANK, 0, offset)] = data;
|
||||
}
|
||||
if (!blk2 && REG2_BLK2_VISIBLE)
|
||||
{
|
||||
m_ram[get_address(REG1_BANK, 1, offset)] = data;
|
||||
}
|
||||
if (!blk3 && REG2_BLK3_VISIBLE)
|
||||
{
|
||||
m_ram[get_address(REG1_BANK, 2, offset)] = data;
|
||||
}
|
||||
if (!blk5 && REG2_BLK5_VISIBLE)
|
||||
{
|
||||
m_ram[get_address(REG1_BANK, 3, offset)] = data;
|
||||
}
|
||||
|
||||
// write to registers
|
||||
if (!io3 && !(m_reg2 & REG2_IO3) && ((offset & 0x1c02) == 0x1c02))
|
||||
{
|
||||
write_register(BIT(offset, 0), data);
|
||||
}
|
||||
break;
|
||||
|
||||
case REG1_RAM_ROM:
|
||||
// write to RAM bank 0
|
||||
if ((!ram1 || !ram2 || !ram3) && REG2_BLK0_VISIBLE && REG1_BLK0)
|
||||
{
|
||||
m_ram[get_address(0, 0, offset)] = data;
|
||||
}
|
||||
|
||||
// write to RAM bank 1 or 2
|
||||
if (!blk1 && REG2_BLK1_VISIBLE)
|
||||
{
|
||||
m_ram[get_address((m_reg1 & REG1_BLK1) ? 2 : 1, 0, offset)] = data;
|
||||
}
|
||||
if (!blk2 && REG2_BLK2_VISIBLE)
|
||||
{
|
||||
m_ram[get_address((m_reg1 & REG1_BLK2) ? 2 : 1, 1, offset)] = data;
|
||||
}
|
||||
if (!blk3 && REG2_BLK3_VISIBLE)
|
||||
{
|
||||
m_ram[get_address((m_reg1 & REG1_BLK3) ? 2 : 1, 2, offset)] = data;
|
||||
}
|
||||
if (!blk5 && REG2_BLK5_VISIBLE)
|
||||
{
|
||||
m_ram[get_address((m_reg1 & REG1_BLK5) ? 2 : 1, 3, offset)] = data;
|
||||
}
|
||||
|
||||
// write to registers
|
||||
if (!io3 && !(m_reg2 & REG2_IO3) && ((offset & 0x1c02) == 0x1c02))
|
||||
{
|
||||
write_register(BIT(offset, 0), data);
|
||||
}
|
||||
break;
|
||||
|
||||
case REG1_FLASH:
|
||||
// write to RAM bank 0
|
||||
if ((!ram1 || !ram2 || !ram3) && REG2_BLK0_VISIBLE)
|
||||
{
|
||||
m_ram[get_address(0, 0, offset)] = data;
|
||||
}
|
||||
|
||||
// write to ROM
|
||||
if (!blk1 && REG2_BLK1_VISIBLE)
|
||||
{
|
||||
m_flash_rom->write(get_address(REG1_BANK, 0, offset), data);
|
||||
}
|
||||
if (!blk2 && REG2_BLK2_VISIBLE)
|
||||
{
|
||||
m_flash_rom->write(get_address(REG1_BANK, 1, offset), data);
|
||||
}
|
||||
if (!blk3 && REG2_BLK3_VISIBLE)
|
||||
{
|
||||
m_flash_rom->write(get_address(REG1_BANK, 2, offset), data);
|
||||
}
|
||||
if (!blk5 && REG2_BLK5_VISIBLE)
|
||||
{
|
||||
m_flash_rom->write(get_address(REG1_BANK, 3, offset), data);
|
||||
}
|
||||
|
||||
// write to registers
|
||||
if (!io3 && !(m_reg2 & REG2_IO3) && ((offset & 0x1c02) == 0x1c02))
|
||||
{
|
||||
write_register(BIT(offset, 0), data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// get_address -
|
||||
//-------------------------------------------------
|
||||
|
||||
offs_t vic20_final_expansion_3_t::get_address(int bank, int block, offs_t offset)
|
||||
{
|
||||
block ^= (m_reg2 >> 5) & 0x03;
|
||||
|
||||
return bank << 15 | block << 13 | offset;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// read_register -
|
||||
//-------------------------------------------------
|
||||
|
||||
UINT8 vic20_final_expansion_3_t::read_register(offs_t offset)
|
||||
{
|
||||
UINT8 data = 0;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
data = m_reg1;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
data = m_reg2;
|
||||
break;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// write_register -
|
||||
//-------------------------------------------------
|
||||
|
||||
void vic20_final_expansion_3_t::write_register(offs_t offset, UINT8 data)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
m_reg1 = data;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
m_reg2 = data;
|
||||
break;
|
||||
}
|
||||
}
|
97
src/emu/bus/vic20/fe3.h
Normal file
97
src/emu/bus/vic20/fe3.h
Normal file
@ -0,0 +1,97 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Curt Coder
|
||||
/**********************************************************************
|
||||
|
||||
Final Expansion v3 cartridge emulation
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __VIC20_FE3__
|
||||
#define __VIC20_FE3__
|
||||
|
||||
#include "emu.h"
|
||||
#include "exp.h"
|
||||
#include "machine/intelfsh.h"
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> vic20_final_expansion_3_t
|
||||
|
||||
class vic20_final_expansion_3_t : public device_t,
|
||||
public device_vic20_expansion_card_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
vic20_final_expansion_3_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// optional information overrides
|
||||
virtual const rom_entry *device_rom_region() const;
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
// device_vic20_expansion_card_interface overrides
|
||||
virtual UINT8 vic20_cd_r(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3);
|
||||
virtual void vic20_cd_w(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
REG1_BLK0 = 0x01,
|
||||
REG1_BLK1 = 0x02,
|
||||
REG1_BLK2 = 0x04,
|
||||
REG1_BLK3 = 0x08,
|
||||
REG1_BLK5 = 0x10,
|
||||
REG1_START = 0x00,
|
||||
REG1_SUPER_ROM = 0x40,
|
||||
REG1_RAM_1 = 0x80,
|
||||
REG1_RAM_2 = 0xc0,
|
||||
REG1_SUPER_RAM = 0xa0,
|
||||
REG1_RAM_ROM = 0x60,
|
||||
REG1_FLASH = 0x20,
|
||||
REG1_MODE_MASK = 0xe0
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
REG2_BLK0 = 0x01,
|
||||
REG2_BLK1 = 0x02,
|
||||
REG2_BLK2 = 0x04,
|
||||
REG2_BLK3 = 0x08,
|
||||
REG2_BLK5 = 0x10,
|
||||
REG2_A13 = 0x20,
|
||||
REG2_A14 = 0x40,
|
||||
REG2_IO3 = 0x80
|
||||
};
|
||||
|
||||
offs_t get_address(int bank, int block, offs_t offset);
|
||||
UINT8 read_register(offs_t offset);
|
||||
void write_register(offs_t offset, UINT8 data);
|
||||
|
||||
required_device<amd_29f040_device> m_flash_rom;
|
||||
optional_shared_ptr<UINT8> m_ram;
|
||||
|
||||
UINT8 m_reg1;
|
||||
UINT8 m_reg2;
|
||||
bool m_lockbit;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type VIC20_FE3;
|
||||
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user