mirror of
https://github.com/holub/mame
synced 2025-04-24 09:20:02 +03:00
(MESS) astrocade: converted the expansion bus to be a slot
device, and converted RAM expansions to be slot cards. As a result you now specify the expansion you want by using e.g. mess astrocde -exp blue_ram_32k or the Slot Devices menu of the internal UI, instead of using the DipSwitches menu. Check the -lslot output for a list of available expansions. [Fabio Priuli]
This commit is contained in:
parent
8f941b83d1
commit
c4e136859d
82
src/emu/bus/astrocde/exp.c
Normal file
82
src/emu/bus/astrocde/exp.c
Normal file
@ -0,0 +1,82 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:etabeta
|
||||
/***********************************************************************************************************
|
||||
|
||||
Bally Astrocade Expansion port
|
||||
|
||||
***********************************************************************************************************/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "exp.h"
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
const device_type ASTROCADE_EXP_SLOT = &device_creator<astrocade_exp_device>;
|
||||
|
||||
|
||||
device_astrocade_card_interface::device_astrocade_card_interface(const machine_config &mconfig, device_t &device)
|
||||
: device_slot_card_interface(mconfig, device)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
device_astrocade_card_interface::~device_astrocade_card_interface()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// astrocade_exp_device - constructor
|
||||
//-------------------------------------------------
|
||||
astrocade_exp_device::astrocade_exp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
device_t(mconfig, ASTROCADE_EXP_SLOT, "Bally Astrocade expansion", tag, owner, clock, "astrocde_exp", __FILE__),
|
||||
device_slot_interface(mconfig, *this)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// astrocade_exp_device - destructor
|
||||
//-------------------------------------------------
|
||||
|
||||
astrocade_exp_device::~astrocade_exp_device()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void astrocade_exp_device::device_start()
|
||||
{
|
||||
m_card = dynamic_cast<device_astrocade_card_interface *>(get_card_device());
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
read
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER(astrocade_exp_device::read)
|
||||
{
|
||||
if (m_card)
|
||||
return m_card->read(space, offset);
|
||||
else
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
write
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE8_MEMBER(astrocade_exp_device::write)
|
||||
{
|
||||
if (m_card)
|
||||
m_card->write(space, offset, data);
|
||||
}
|
55
src/emu/bus/astrocde/exp.h
Normal file
55
src/emu/bus/astrocde/exp.h
Normal file
@ -0,0 +1,55 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:etabeta
|
||||
#ifndef __ASTROCADE_EXP_H
|
||||
#define __ASTROCADE_EXP_H
|
||||
|
||||
// ======================> device_astrocade_card_interface
|
||||
|
||||
class device_astrocade_card_interface : public device_slot_card_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
device_astrocade_card_interface(const machine_config &mconfig, device_t &device);
|
||||
virtual ~device_astrocade_card_interface();
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read) { return 0; }
|
||||
virtual DECLARE_WRITE8_MEMBER(write) {}
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
|
||||
// ======================> astrocade_exp_device
|
||||
|
||||
class astrocade_exp_device : public device_t,
|
||||
public device_slot_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
astrocade_exp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
virtual ~astrocade_exp_device();
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read);
|
||||
virtual DECLARE_WRITE8_MEMBER(write);
|
||||
|
||||
protected:
|
||||
|
||||
device_astrocade_card_interface* m_card;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type ASTROCADE_EXP_SLOT;
|
||||
|
||||
|
||||
#define MCFG_ASTROCADE_EXPANSION_SLOT_ADD(_tag, _slot_intf, _def_slot) \
|
||||
MCFG_DEVICE_ADD(_tag, ASTROCADE_EXP_SLOT, 0) \
|
||||
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
|
||||
|
||||
#endif
|
213
src/emu/bus/astrocde/ram.c
Normal file
213
src/emu/bus/astrocde/ram.c
Normal file
@ -0,0 +1,213 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:etabeta
|
||||
/***********************************************************************************************************
|
||||
|
||||
|
||||
Bally Astrocade RAM expansion emulation
|
||||
|
||||
RAM Expansions (info below courtesy of Paul Thacker)
|
||||
|
||||
Several third party RAM expansions have been made for the Astrocade. These
|
||||
allow access to various ranges of the expansion memory ($5000 to $FFFF).
|
||||
A RAM expansion is required to use extended BASIC programs like Blue RAM BASIC
|
||||
and VIPERSoft BASIC. All of the expansions also have a RAM protect switch, which
|
||||
can be flipped at any time to make the RAM act like ROM. Extended BASIC
|
||||
programs need access to the RAM and won't work with RAM protect enabled, but
|
||||
this can be useful with Bally and Astrocade BASIC. They also have a range switch
|
||||
(not implemented). The default position is 6K, but it can be switched to
|
||||
2K. This means that the expanded memory starting at $6000 will instead be
|
||||
mapped to the cartridge memory starting at $2000. So it would be possible to
|
||||
load a cartridge program from tape into the expansion memory, then flip the range
|
||||
switch and run it as a cartridge. This is useful for cartridge development.
|
||||
|
||||
Blue RAM -- available in 4K, 16K, and 32K. These also use an INS8154 chip,
|
||||
(not yet implemented) which has an additional $80 bytes of RAM mapped
|
||||
immediately after the end of the expansion address space. This memory
|
||||
can't be write protected. The INS8154 has I/O features needed for loading
|
||||
tape programs into Blue RAM BASIC, as well as running the Blue RAM Utility cart.
|
||||
4K: $6000 to $6FFF (can't run VIPERSoft BASIC, because this program needs memory
|
||||
past this range)
|
||||
16K: $6000 to $9FFF
|
||||
32K: $6000 to $DFFF
|
||||
|
||||
VIPER System 1 -- This is available in 16K only. It also includes a keyboard (not implemented).
|
||||
16K: $6000 to $9FFF
|
||||
|
||||
Lil' WHITE RAM -- This is available in 32K only. Attempts to read and write
|
||||
to memory outside of its address range ($D000 to $FFFF) are mapped to the expansion
|
||||
memory $5000 to $7FFF. The current implementation won't allow the shadow RAM area
|
||||
to be accessed when RAM protect is on, but there is no known software that will
|
||||
access the upper range of the expansion RAM when RAM protect is enabled.
|
||||
32K: $5000 to $CFFF
|
||||
|
||||
R&L 64K RAM Board -- This is a highly configurable kit. RAM can be installed in
|
||||
2K increments. So, the entire 44K expansion memory can be filled. It is also
|
||||
possible to override the rest of the memory map with RAM (not implemented).
|
||||
There are 32 switches allowing users to activate and deactivate each 2K block (not implemented).
|
||||
RAM write protection can be implemented in three ranges through jumpers or by
|
||||
installing switches. The ranges are $0000 to $0FFF (first 4K), $0000 to $3FFF (first 16K),
|
||||
and $0000 to $FFFF (all 64K). The current implementation is for 44K expansion memory mapped from
|
||||
$5000 to $FFFF, with only a single write protect covering this entire range.
|
||||
|
||||
***********************************************************************************************************/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "ram.h"
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// astrocade_rom_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
const device_type ASTROCADE_BLUERAM_4K = &device_creator<astrocade_blueram_4k_device>;
|
||||
const device_type ASTROCADE_BLUERAM_16K = &device_creator<astrocade_blueram_16k_device>;
|
||||
const device_type ASTROCADE_BLUERAM_32K = &device_creator<astrocade_blueram_32k_device>;
|
||||
const device_type ASTROCADE_VIPER_SYS1 = &device_creator<astrocade_viper_sys1_device>;
|
||||
const device_type ASTROCADE_WHITERAM = &device_creator<astrocade_whiteram_device>;
|
||||
const device_type ASTROCADE_RL64RAM = &device_creator<astrocade_rl64ram_device>;
|
||||
|
||||
|
||||
astrocade_blueram_4k_device::astrocade_blueram_4k_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
|
||||
: device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||
device_astrocade_card_interface(mconfig, *this),
|
||||
m_write_prot(*this, "RAM_PROTECT")
|
||||
{
|
||||
}
|
||||
|
||||
astrocade_blueram_4k_device::astrocade_blueram_4k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, ASTROCADE_BLUERAM_4K, "Bally Astrocade Blue RAM 4K", tag, owner, clock, "astrocade_br4", __FILE__),
|
||||
device_astrocade_card_interface(mconfig, *this),
|
||||
m_write_prot(*this, "RAM_PROTECT")
|
||||
{
|
||||
}
|
||||
|
||||
astrocade_blueram_16k_device::astrocade_blueram_16k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: astrocade_blueram_4k_device(mconfig, ASTROCADE_BLUERAM_16K, "Bally Astrocade Blue RAM 16K", tag, owner, clock, "astrocade_br16", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
astrocade_blueram_32k_device::astrocade_blueram_32k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: astrocade_blueram_4k_device(mconfig, ASTROCADE_BLUERAM_32K, "Bally Astrocade Blue RAM 32K", tag, owner, clock, "astrocade_br32", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
astrocade_viper_sys1_device::astrocade_viper_sys1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, ASTROCADE_VIPER_SYS1, "Bally Astrocade Viper System 1", tag, owner, clock, "astrocade_vs1", __FILE__),
|
||||
device_astrocade_card_interface(mconfig, *this),
|
||||
m_write_prot(*this, "RAM_PROTECT")
|
||||
{
|
||||
}
|
||||
|
||||
astrocade_whiteram_device::astrocade_whiteram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, ASTROCADE_WHITERAM, "Bally Astrocade Lil' White RAM 32K", tag, owner, clock, "astrocade_lwr", __FILE__),
|
||||
device_astrocade_card_interface(mconfig, *this),
|
||||
m_write_prot(*this, "RAM_PROTECT")
|
||||
{
|
||||
}
|
||||
|
||||
astrocade_rl64ram_device::astrocade_rl64ram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, ASTROCADE_RL64RAM, "Bally Astrocade R&L RAM 64K", tag, owner, clock, "astrocade_rl64", __FILE__),
|
||||
device_astrocade_card_interface(mconfig, *this),
|
||||
m_write_prot(*this, "RAM_PROTECT")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// RAM Write protect switch
|
||||
//-------------------------------------------------
|
||||
|
||||
static INPUT_PORTS_START( exp_switches )
|
||||
PORT_START("RAM_PROTECT")
|
||||
PORT_CONFNAME( 0x01, 0x00, "Write Protect RAM")
|
||||
PORT_CONFSETTING( 0x00, DEF_STR(Off))
|
||||
PORT_CONFSETTING( 0x01, DEF_STR(On))
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
ioport_constructor astrocade_blueram_4k_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME( exp_switches );
|
||||
}
|
||||
|
||||
ioport_constructor astrocade_viper_sys1_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME( exp_switches );
|
||||
}
|
||||
|
||||
ioport_constructor astrocade_whiteram_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME( exp_switches );
|
||||
}
|
||||
|
||||
ioport_constructor astrocade_rl64ram_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME( exp_switches );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
specific handlers
|
||||
-------------------------------------------------*/
|
||||
|
||||
// Blue RAM expansions have RAM starting at 0x6000, up to the RAM size
|
||||
READ8_MEMBER(astrocade_blueram_4k_device::read)
|
||||
{
|
||||
if (offset >= 0x1000 && offset < 0x1000 + m_ram.bytes())
|
||||
return m_ram[offset - 0x1000];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(astrocade_blueram_4k_device::write)
|
||||
{
|
||||
if (offset >= 0x1000 && offset < 0x1000 + m_ram.bytes() && !m_write_prot->read())
|
||||
m_ram[offset - 0x1000] = data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Viper System 1 expansion has RAM in 0x6000-0x9fff
|
||||
READ8_MEMBER(astrocade_viper_sys1_device::read)
|
||||
{
|
||||
if (offset >= 0x1000 && offset < 0xa000)
|
||||
return m_ram[offset - 0x1000];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(astrocade_viper_sys1_device::write)
|
||||
{
|
||||
if (offset >= 0x1000 && offset < 0xa000 && !m_write_prot->read())
|
||||
m_ram[offset - 0x1000] = data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Lil' WHITE RAM expansion has RAM in 0x5000-0xcfff + a mirror of the first 0x3000 bytes up to 0xffff
|
||||
READ8_MEMBER(astrocade_whiteram_device::read)
|
||||
{
|
||||
return m_ram[offset % 0x8000];
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(astrocade_whiteram_device::write)
|
||||
{
|
||||
if (!m_write_prot->read())
|
||||
m_ram[offset % 0x8000] = data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// R&L 64K RAM Board (44KB installed) has RAM in 0x5000-0xffff
|
||||
READ8_MEMBER(astrocade_rl64ram_device::read)
|
||||
{
|
||||
return m_ram[offset];
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(astrocade_rl64ram_device::write)
|
||||
{
|
||||
if (!m_write_prot->read())
|
||||
m_ram[offset] = data;
|
||||
}
|
||||
|
||||
|
135
src/emu/bus/astrocde/ram.h
Normal file
135
src/emu/bus/astrocde/ram.h
Normal file
@ -0,0 +1,135 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:etabeta
|
||||
#ifndef __ASTROCADE_RAM_H
|
||||
#define __ASTROCADE_RAM_H
|
||||
|
||||
#include "exp.h"
|
||||
|
||||
|
||||
// ======================> astrocade_blueram_4k_device
|
||||
|
||||
class astrocade_blueram_4k_device : public device_t,
|
||||
public device_astrocade_card_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
astrocade_blueram_4k_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
|
||||
astrocade_blueram_4k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start() { m_ram.resize(0x1000); save_item(NAME(m_ram)); }
|
||||
virtual void device_reset() {}
|
||||
virtual ioport_constructor device_input_ports() const;
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read);
|
||||
virtual DECLARE_WRITE8_MEMBER(write);
|
||||
|
||||
protected:
|
||||
dynamic_buffer m_ram;
|
||||
required_ioport m_write_prot;
|
||||
};
|
||||
|
||||
// ======================> astrocade_blueram_16k_device
|
||||
|
||||
class astrocade_blueram_16k_device : public astrocade_blueram_4k_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
astrocade_blueram_16k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
virtual void device_start() { m_ram.resize(0x4000); save_item(NAME(m_ram)); }
|
||||
};
|
||||
|
||||
// ======================> astrocade_blueram_32k_device
|
||||
|
||||
class astrocade_blueram_32k_device : public astrocade_blueram_4k_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
astrocade_blueram_32k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
virtual void device_start() { m_ram.resize(0x8000); save_item(NAME(m_ram)); }
|
||||
};
|
||||
|
||||
// ======================> astrocade_viper_sys1_device
|
||||
|
||||
class astrocade_viper_sys1_device : public device_t,
|
||||
public device_astrocade_card_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
astrocade_viper_sys1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start() { m_ram.resize(0x4000); save_item(NAME(m_ram)); }
|
||||
virtual void device_reset() {}
|
||||
virtual ioport_constructor device_input_ports() const;
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read);
|
||||
virtual DECLARE_WRITE8_MEMBER(write);
|
||||
|
||||
private:
|
||||
dynamic_buffer m_ram;
|
||||
required_ioport m_write_prot;
|
||||
};
|
||||
|
||||
// ======================> astrocade_whiteram_device
|
||||
|
||||
class astrocade_whiteram_device : public device_t,
|
||||
public device_astrocade_card_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
astrocade_whiteram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start() { m_ram.resize(0x8000); save_item(NAME(m_ram)); }
|
||||
virtual void device_reset() {}
|
||||
virtual ioport_constructor device_input_ports() const;
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read);
|
||||
virtual DECLARE_WRITE8_MEMBER(write);
|
||||
|
||||
private:
|
||||
dynamic_buffer m_ram;
|
||||
required_ioport m_write_prot;
|
||||
};
|
||||
|
||||
// ======================> astrocade_rl64ram_device
|
||||
|
||||
class astrocade_rl64ram_device : public device_t,
|
||||
public device_astrocade_card_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
astrocade_rl64ram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start() { m_ram.resize(0xb000); save_item(NAME(m_ram)); }
|
||||
virtual void device_reset() {}
|
||||
virtual ioport_constructor device_input_ports() const;
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read);
|
||||
virtual DECLARE_WRITE8_MEMBER(write);
|
||||
|
||||
private:
|
||||
dynamic_buffer m_ram;
|
||||
required_ioport m_write_prot;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type ASTROCADE_BLUERAM_4K;
|
||||
extern const device_type ASTROCADE_BLUERAM_16K;
|
||||
extern const device_type ASTROCADE_BLUERAM_32K;
|
||||
extern const device_type ASTROCADE_VIPER_SYS1;
|
||||
extern const device_type ASTROCADE_WHITERAM;
|
||||
extern const device_type ASTROCADE_RL64RAM;
|
||||
|
||||
|
||||
#endif
|
@ -129,6 +129,8 @@ ifneq ($(filter ASTROCADE,$(BUSES)),)
|
||||
OBJDIRS += $(BUSOBJ)/astrocde
|
||||
BUSOBJS += $(BUSOBJ)/astrocde/slot.o
|
||||
BUSOBJS += $(BUSOBJ)/astrocde/rom.o
|
||||
BUSOBJS += $(BUSOBJ)/astrocde/exp.o
|
||||
BUSOBJS += $(BUSOBJ)/astrocde/ram.o
|
||||
endif
|
||||
|
||||
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include "sound/astrocde.h"
|
||||
#include "bus/astrocde/slot.h"
|
||||
#include "bus/astrocde/rom.h"
|
||||
#include "bus/astrocde/exp.h"
|
||||
#include "bus/astrocde/ram.h"
|
||||
|
||||
class astrocde_mess_state : public astrocde_state
|
||||
{
|
||||
@ -24,13 +26,10 @@ public:
|
||||
{ }
|
||||
|
||||
required_device<astrocade_cart_slot_device> m_cart;
|
||||
void get_ram_expansion_settings(int &ram_expansion_installed, int &write_protect_on, int &expansion_ram_start, int &expansion_ram_end, int &shadow_ram_end);
|
||||
DECLARE_MACHINE_START(astrocde);
|
||||
DECLARE_MACHINE_RESET(astrocde);
|
||||
DECLARE_INPUT_CHANGED_MEMBER(set_write_protect);
|
||||
};
|
||||
|
||||
/*************************************
|
||||
/*********************************************************************************
|
||||
*
|
||||
* Memory maps
|
||||
*
|
||||
@ -42,58 +41,13 @@ public:
|
||||
* by an extended BASIC program. Bally and Astrocade BASIC can access from
|
||||
* $5000 to $7FFF if available.
|
||||
*
|
||||
* RAM Expansions
|
||||
*
|
||||
* Several third party RAM expansions have been made for the Astrocade. These
|
||||
* allow access to various ranges of the expansion memory ($5000 to $FFFF).
|
||||
* A RAM expansion is required to use extended BASIC programs like Blue RAM BASIC
|
||||
* and VIPERSoft BASIC. All of the expansions also have a RAM protect switch, which
|
||||
* can be flipped at any time to make the RAM act like ROM. Extended BASIC
|
||||
* programs need access to the RAM and won't work with RAM protect enabled, but
|
||||
* this can be useful with Bally and Astrocade BASIC. They also have a range switch
|
||||
* (not implemented). The default position is 6K, but it can be switched to
|
||||
* 2K. This means that the expanded memory starting at $6000 will instead be
|
||||
* mapped to the cartridge memory starting at $2000. So it would be possible to
|
||||
* load a cartridge program from tape into the expansion memory, then flip the range
|
||||
* switch and run it as a cartridge. This is useful for cartridge development.
|
||||
*
|
||||
* NOTE: If you have any trouble running cartridges with a RAM expansion installed, hit reset.
|
||||
*
|
||||
* Blue RAM -- available in 4K, 16K, and 32K. These also use an INS8154 chip,
|
||||
* (not yet implemented) which has an additional $80 bytes of RAM mapped
|
||||
* immediately after the end of the expansion address space. This memory
|
||||
* can't be write protected. The INS8154 has I/O features needed for loading
|
||||
* tape programs into Blue RAM BASIC, as well as running the Blue RAM Utility cart.
|
||||
* 4K: $6000 to $6FFF (can't run VIPERSoft BASIC, because this program needs memory
|
||||
* past this range)
|
||||
* 16K: $6000 to $9FFF
|
||||
* 32K: $6000 to $DFFF
|
||||
*
|
||||
* VIPER System 1 -- This is available in 16K only. It also includes a keyboard (not implemented).
|
||||
* 16K: $6000 to $9FFF
|
||||
*
|
||||
* Lil' WHITE RAM -- This is available in 32K only. Attempts to read and write
|
||||
* to memory outside of its address range ($D000 to $FFFF) are mapped to the expansion
|
||||
* memory $5000 to $7FFF. The current implementation won't allow the shadow RAM area
|
||||
* to be accessed when RAM protect is on, but there is no known software that will
|
||||
* access the upper range of the expansion RAM when RAM protect is enabled.
|
||||
* 32K: $5000 to $CFFF
|
||||
*
|
||||
* R&L 64K RAM Board -- This is a highly configurable kit. RAM can be installed in
|
||||
* 2K increments. So, the entire 44K expansion memory can be filled. It is also
|
||||
* possible to override the rest of the memory map with RAM (not implemented).
|
||||
* There are 32 switches allowing users to activate and deactivate each 2K block (not implemented).
|
||||
* RAM write protection can be implemented in three ranges through jumpers or by
|
||||
* installing switches. The ranges are $0000 to $0FFF (first 4K), $0000 to $3FFF (first 16K),
|
||||
* and $0000 to $FFFF (all 64K). The current implementation is for 44K expansion memory mapped from
|
||||
* $5000 to $FFFF, with only a single write protect covering this entire range.
|
||||
*
|
||||
*************************************/
|
||||
*********************************************************************************/
|
||||
|
||||
static ADDRESS_MAP_START( astrocade_mem, AS_PROGRAM, 8, astrocde_mess_state )
|
||||
AM_RANGE(0x0000, 0x0fff) AM_ROM AM_WRITE(astrocade_funcgen_w)
|
||||
AM_RANGE(0x1000, 0x3fff) AM_ROM /* Star Fortress writes in here?? */
|
||||
AM_RANGE(0x4000, 0x4fff) AM_RAM AM_SHARE("videoram") /* ASG */
|
||||
AM_RANGE(0x5000, 0xffff) AM_DEVREADWRITE("exp", astrocade_exp_device, read, write)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
@ -101,29 +55,6 @@ static ADDRESS_MAP_START( astrocade_io, AS_IO, 8, astrocde_mess_state )
|
||||
AM_RANGE(0x00, 0x1f) AM_MIRROR(0xff00) AM_MASK(0xffff) AM_READWRITE(astrocade_data_chip_register_r, astrocade_data_chip_register_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
INPUT_CHANGED_MEMBER(astrocde_mess_state::set_write_protect) // run when RAM expansion write protect switch is changed
|
||||
{
|
||||
int ram_expansion_installed = 0, write_protect_on = 0, expansion_ram_start = 0, expansion_ram_end = 0, shadow_ram_end = 0;
|
||||
address_space &space = m_maincpu->space(AS_PROGRAM);
|
||||
UINT8 *expram = machine().device<ram_device>("ram_tag")->pointer();
|
||||
|
||||
get_ram_expansion_settings(ram_expansion_installed, write_protect_on, expansion_ram_start, expansion_ram_end, shadow_ram_end); // passing by reference
|
||||
|
||||
if (ram_expansion_installed == 1)
|
||||
{
|
||||
if (write_protect_on == 0) // write protect off, so install memory normally
|
||||
{
|
||||
space.install_ram(expansion_ram_start, expansion_ram_end, expram);
|
||||
if (shadow_ram_end > expansion_ram_end)
|
||||
space.install_ram(expansion_ram_end + 1, shadow_ram_end, expram);
|
||||
}
|
||||
else // write protect on, so make memory read only
|
||||
{
|
||||
space.nop_write(expansion_ram_start, expansion_ram_end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Input ports
|
||||
@ -227,21 +158,6 @@ static INPUT_PORTS_START( astrocde )
|
||||
|
||||
PORT_START("P4_KNOB")
|
||||
PORT_BIT(0xff, 0x00, IPT_PADDLE) PORT_INVERT PORT_SENSITIVITY(85) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) PORT_MINMAX(0,255) PORT_CODE_DEC(KEYCODE_Y) PORT_CODE_INC(KEYCODE_U) PORT_PLAYER(4)
|
||||
|
||||
PORT_START("CFG") /* machine config */
|
||||
PORT_DIPNAME( 0x3f, 0x00, "RAM Expansion")
|
||||
PORT_DIPSETTING( 0x00, "No RAM Expansion")
|
||||
PORT_DIPSETTING( 0x01, "16KB Viper System 1 RAM Expansion")
|
||||
PORT_DIPSETTING( 0x02, "32KB Lil' WHITE RAM Expansion")
|
||||
PORT_DIPSETTING( 0x04, "R&L 64K RAM Board (44K installed)")
|
||||
PORT_DIPSETTING( 0x08, "4KB Blue RAM Expansion")
|
||||
PORT_DIPSETTING( 0x10, "16KB Blue RAM Expansion")
|
||||
PORT_DIPSETTING( 0x20, "32KB Blue RAM Expansion")
|
||||
|
||||
PORT_START("PROTECT") /* Write protect RAM */
|
||||
PORT_DIPNAME( 0x01, 0x00, "Write Protect RAM") PORT_CHANGED_MEMBER(DEVICE_SELF, astrocde_mess_state, set_write_protect, 0)
|
||||
PORT_DIPSETTING( 0x00, "Write Protect Off")
|
||||
PORT_DIPSETTING( 0x01, "Write Protect On")
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
@ -257,6 +173,15 @@ static SLOT_INTERFACE_START(astrocade_cart)
|
||||
SLOT_INTERFACE_INTERNAL("rom_512k", ASTROCADE_ROM_512K)
|
||||
SLOT_INTERFACE_END
|
||||
|
||||
static SLOT_INTERFACE_START(astrocade_exp)
|
||||
SLOT_INTERFACE("blue_ram_4k", ASTROCADE_BLUERAM_4K)
|
||||
SLOT_INTERFACE("blue_ram_16k", ASTROCADE_BLUERAM_16K)
|
||||
SLOT_INTERFACE("blue_ram_32k", ASTROCADE_BLUERAM_32K)
|
||||
SLOT_INTERFACE("viper_sys1", ASTROCADE_VIPER_SYS1)
|
||||
SLOT_INTERFACE("lil_white_ram", ASTROCADE_WHITERAM)
|
||||
SLOT_INTERFACE("rl64_ram", ASTROCADE_RL64RAM)
|
||||
SLOT_INTERFACE_END
|
||||
|
||||
|
||||
static MACHINE_CONFIG_START( astrocde, astrocde_mess_state )
|
||||
/* basic machine hardware */
|
||||
@ -265,7 +190,6 @@ static MACHINE_CONFIG_START( astrocde, astrocde_mess_state )
|
||||
MCFG_CPU_IO_MAP(astrocade_io)
|
||||
|
||||
MCFG_MACHINE_START_OVERRIDE(astrocde_mess_state, astrocde)
|
||||
MCFG_MACHINE_RESET_OVERRIDE(astrocde_mess_state, astrocde)
|
||||
|
||||
/* video hardware */
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
@ -281,9 +205,8 @@ static MACHINE_CONFIG_START( astrocde, astrocde_mess_state )
|
||||
MCFG_SOUND_ADD("astrocade1", ASTROCADE, ASTROCADE_CLOCK/4)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
|
||||
|
||||
/* optional expansion ram (installed in machine_reset)*/
|
||||
MCFG_RAM_ADD("ram_tag")
|
||||
MCFG_RAM_DEFAULT_SIZE("32k")
|
||||
/* expansion port */
|
||||
MCFG_ASTROCADE_EXPANSION_SLOT_ADD("exp", astrocade_exp, NULL)
|
||||
|
||||
/* cartridge */
|
||||
MCFG_ASTROCADE_CARTRIDGE_ADD("cartslot", astrocade_cart, NULL)
|
||||
@ -331,80 +254,6 @@ MACHINE_START_MEMBER(astrocde_mess_state, astrocde)
|
||||
m_maincpu->space(AS_PROGRAM).install_read_handler(0x2000, 0x3fff, read8_delegate(FUNC(astrocade_cart_slot_device::read_rom),(astrocade_cart_slot_device*)m_cart));
|
||||
}
|
||||
|
||||
MACHINE_RESET_MEMBER(astrocde_mess_state, astrocde)
|
||||
{
|
||||
int ram_expansion_installed = 0, write_protect_on = 0, expansion_ram_start = 0, expansion_ram_end = 0, shadow_ram_end = 0;
|
||||
address_space &space = m_maincpu->space(AS_PROGRAM);
|
||||
UINT8 *expram = machine().device<ram_device>("ram_tag")->pointer();
|
||||
space.unmap_readwrite(0x5000, 0xffff); // unmap any previously installed expansion RAM
|
||||
|
||||
get_ram_expansion_settings(ram_expansion_installed, write_protect_on, expansion_ram_start, expansion_ram_end, shadow_ram_end); // passing by reference
|
||||
|
||||
if (ram_expansion_installed == 1)
|
||||
{
|
||||
if (write_protect_on == 0) // write protect off, so install memory normally
|
||||
{
|
||||
space.install_ram(expansion_ram_start, expansion_ram_end, expram);
|
||||
if (shadow_ram_end > expansion_ram_end)
|
||||
space.install_ram(expansion_ram_end + 1, shadow_ram_end, expram);
|
||||
}
|
||||
else // write protect on, so make memory read only
|
||||
{
|
||||
space.nop_write(expansion_ram_start, expansion_ram_end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void astrocde_mess_state::get_ram_expansion_settings(int &ram_expansion_installed, int &write_protect_on, int &expansion_ram_start, int &expansion_ram_end, int &shadow_ram_end)
|
||||
{
|
||||
if (ioport("PROTECT")->read() == 0x01)
|
||||
write_protect_on = 1;
|
||||
else
|
||||
write_protect_on = 0;
|
||||
|
||||
ram_expansion_installed = 1;
|
||||
|
||||
switch(ioport("CFG")->read()) // check RAM expansion configuration and set address ranges
|
||||
{
|
||||
case 0x00: // No RAM Expansion
|
||||
ram_expansion_installed = 0;
|
||||
break;
|
||||
case 0x01: // 16KB Viper System 1 RAM Expansion
|
||||
expansion_ram_start = 0x6000;
|
||||
expansion_ram_end = 0x9fff;
|
||||
shadow_ram_end = 0;
|
||||
break;
|
||||
case 0x02: // "32KB Lil' WHITE RAM Expansion
|
||||
expansion_ram_start = 0x5000;
|
||||
expansion_ram_end = 0xcfff;
|
||||
shadow_ram_end = 0xffff;
|
||||
break;
|
||||
case 0x04: // R&L 64K RAM Board (44KB installed)
|
||||
expansion_ram_start = 0x5000;
|
||||
expansion_ram_end = 0xffff;
|
||||
shadow_ram_end = 0;
|
||||
break;
|
||||
case 0x08: // 4KB Blue RAM Expansion
|
||||
expansion_ram_start = 0x6000;
|
||||
expansion_ram_end = 0x6fff;
|
||||
shadow_ram_end = 0;
|
||||
break;
|
||||
case 0x10: // 16KB Blue RAM Expansion
|
||||
expansion_ram_start = 0x6000;
|
||||
expansion_ram_end = 0x9fff;
|
||||
shadow_ram_end = 0;
|
||||
break;
|
||||
case 0x20: // 32KB Blue RAM Expansion
|
||||
expansion_ram_start = 0x6000;
|
||||
expansion_ram_end = 0xdfff;
|
||||
shadow_ram_end = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Driver definitions
|
||||
|
Loading…
Reference in New Issue
Block a user