mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00
(MESS) msx.c: [Wilbert Pol]
- Reimplemented the cartridge slots as slot devices. - Moved the msx slot layouts to inline machine configuration. - Started adding support for a few more firmware types. - Add turbo support to Panasonic FS-A1FX/FS-A1WX/FS-A1WSX.
This commit is contained in:
parent
8ab3ccb194
commit
c74226bb26
44
.gitattributes
vendored
44
.gitattributes
vendored
@ -970,6 +970,48 @@ src/emu/bus/midi/midiinport.c svneol=native#text/plain
|
||||
src/emu/bus/midi/midiinport.h svneol=native#text/plain
|
||||
src/emu/bus/midi/midioutport.c svneol=native#text/plain
|
||||
src/emu/bus/midi/midioutport.h svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/ascii.c svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/ascii.h svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/cartridge.c svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/cartridge.h svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/crossblaim.c svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/crossblaim.h svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/fmpac.c svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/fmpac.h svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/konami.c svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/konami.h svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/korean.c svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/korean.h svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/majutsushi.c svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/majutsushi.h svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/msxdos2.c svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/msxdos2.h svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/nomapper.c svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/nomapper.h svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/rtype.c svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/rtype.h svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/superloderunner.c svneol=native#text/plain
|
||||
src/emu/bus/msx_cart/superloderunner.h svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/bunsetsu.c svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/bunsetsu.h svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/cartridge.c svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/cartridge.h svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/disk.c svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/disk.h svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/fs4600.c svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/fs4600.h svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/music.c svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/music.h svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/panasonic08.c svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/panasonic08.h svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/ram.c svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/ram.h svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/ram_mm.c svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/ram_mm.h svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/rom.c svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/rom.h svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/slot.c svneol=native#text/plain
|
||||
src/emu/bus/msx_slot/slot.h svneol=native#text/plain
|
||||
src/emu/bus/nes/2a03pur.c svneol=native#text/plain
|
||||
src/emu/bus/nes/2a03pur.h svneol=native#text/plain
|
||||
src/emu/bus/nes/act53.c svneol=native#text/plain
|
||||
@ -8290,7 +8332,6 @@ src/mess/includes/mpf1.h svneol=native#text/plain
|
||||
src/mess/includes/mpz80.h svneol=native#text/plain
|
||||
src/mess/includes/msbc1.h svneol=native#text/plain
|
||||
src/mess/includes/msx.h svneol=native#text/plain
|
||||
src/mess/includes/msx_slot.h svneol=native#text/plain
|
||||
src/mess/includes/mtx.h svneol=native#text/plain
|
||||
src/mess/includes/mz700.h svneol=native#text/plain
|
||||
src/mess/includes/mz80.h svneol=native#text/plain
|
||||
@ -8642,7 +8683,6 @@ src/mess/machine/mikro80.c svneol=native#text/plain
|
||||
src/mess/machine/mm1kb.c svneol=native#text/plain
|
||||
src/mess/machine/mm1kb.h svneol=native#text/plain
|
||||
src/mess/machine/msx.c svneol=native#text/plain
|
||||
src/mess/machine/msx_slot.c svneol=native#text/plain
|
||||
src/mess/machine/mtx.c svneol=native#text/plain
|
||||
src/mess/machine/mz700.c svneol=native#text/plain
|
||||
src/mess/machine/mz80.c svneol=native#text/plain
|
||||
|
@ -387,6 +387,38 @@ BUSOBJS += $(BUSOBJ)/isbx/isbc_218a.o
|
||||
endif
|
||||
|
||||
|
||||
#-------------------------------------------------
|
||||
#
|
||||
#@src/emu/bus/msx_slot/slot.h,BUSES += MSX_SLOT
|
||||
#-------------------------------------------------
|
||||
|
||||
ifneq ($(filter MSX_SLOT,$(BUSES)),)
|
||||
OBJDIRS += $(BUSOBJ)/msx_slot
|
||||
BUSOBJS += $(BUSOBJ)/msx_slot/bunsetsu.o
|
||||
BUSOBJS += $(BUSOBJ)/msx_slot/cartridge.o
|
||||
BUSOBJS += $(BUSOBJ)/msx_slot/disk.o
|
||||
BUSOBJS += $(BUSOBJ)/msx_slot/fs4600.o
|
||||
BUSOBJS += $(BUSOBJ)/msx_slot/music.o
|
||||
BUSOBJS += $(BUSOBJ)/msx_slot/panasonic08.o
|
||||
BUSOBJS += $(BUSOBJ)/msx_slot/rom.o
|
||||
BUSOBJS += $(BUSOBJ)/msx_slot/ram.o
|
||||
BUSOBJS += $(BUSOBJ)/msx_slot/ram_mm.o
|
||||
BUSOBJS += $(BUSOBJ)/msx_slot/slot.o
|
||||
OBJDIRS += $(BUSOBJ)/msx_cart
|
||||
BUSOBJS += $(BUSOBJ)/msx_cart/ascii.o
|
||||
BUSOBJS += $(BUSOBJ)/msx_cart/cartridge.o
|
||||
BUSOBJS += $(BUSOBJ)/msx_cart/crossblaim.o
|
||||
BUSOBJS += $(BUSOBJ)/msx_cart/fmpac.o
|
||||
BUSOBJS += $(BUSOBJ)/msx_cart/konami.o
|
||||
BUSOBJS += $(BUSOBJ)/msx_cart/korean.o
|
||||
BUSOBJS += $(BUSOBJ)/msx_cart/majutsushi.o
|
||||
BUSOBJS += $(BUSOBJ)/msx_cart/msxdos2.o
|
||||
BUSOBJS += $(BUSOBJ)/msx_cart/nomapper.o
|
||||
BUSOBJS += $(BUSOBJ)/msx_cart/rtype.o
|
||||
BUSOBJS += $(BUSOBJ)/msx_cart/superloderunner.o
|
||||
endif
|
||||
|
||||
|
||||
#-------------------------------------------------
|
||||
#
|
||||
#@src/emu/bus/kc/kc.h,BUSES += KC
|
||||
|
442
src/emu/bus/msx_cart/ascii.c
Normal file
442
src/emu/bus/msx_cart/ascii.c
Normal file
@ -0,0 +1,442 @@
|
||||
#include "emu.h"
|
||||
#include "ascii.h"
|
||||
|
||||
|
||||
const device_type MSX_CART_ASCII8 = &device_creator<msx_cart_ascii8>;
|
||||
const device_type MSX_CART_ASCII16 = &device_creator<msx_cart_ascii16>;
|
||||
const device_type MSX_CART_ASCII8_SRAM = &device_creator<msx_cart_ascii8_sram>;
|
||||
const device_type MSX_CART_ASCII16_SRAM = &device_creator<msx_cart_ascii16_sram>;
|
||||
|
||||
|
||||
msx_cart_ascii8::msx_cart_ascii8(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_CART_ASCII8, "MSX Cartridge - ASCII8", tag, owner, clock, "msx_cart_ascii8", __FILE__)
|
||||
, msx_cart_interface(mconfig, *this)
|
||||
, m_bank_mask(0)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_selected_bank[i] = 0;
|
||||
m_bank_base[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_ascii8::device_start()
|
||||
{
|
||||
save_item(NAME(m_selected_bank));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_cart_ascii8::restore_banks), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_ascii8::restore_banks()
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_bank_base[i] = get_rom_base() + (m_selected_bank[i] & m_bank_mask ) * 0x2000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_ascii8::device_reset()
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_selected_bank[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_ascii8::initialize_cartridge()
|
||||
{
|
||||
UINT32 size = get_rom_size();
|
||||
|
||||
if ( size > 256 * 0x2000 )
|
||||
{
|
||||
fatalerror("ascii8: ROM is too big\n");
|
||||
}
|
||||
|
||||
UINT16 banks = size / 0x2000;
|
||||
|
||||
if (size != banks * 0x2000 || (~(banks - 1) % banks))
|
||||
{
|
||||
fatalerror("ascii8: Invalid ROM size\n");
|
||||
}
|
||||
|
||||
m_bank_mask = banks - 1;
|
||||
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_cart_ascii8::read_cart)
|
||||
{
|
||||
if ( offset >= 0x4000 && offset < 0xC000 )
|
||||
{
|
||||
return m_bank_base[(offset - 0x4000) >> 13][offset & 0x1fff];
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_cart_ascii8::write_cart)
|
||||
{
|
||||
if (offset >= 0x6000 && offset < 0x8000)
|
||||
{
|
||||
UINT8 bank = (offset / 0x800) & 0x03;
|
||||
|
||||
m_selected_bank[bank] = data;
|
||||
m_bank_base[bank] = get_rom_base() + (m_selected_bank[bank] & m_bank_mask ) * 0x2000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
msx_cart_ascii16::msx_cart_ascii16(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_CART_ASCII16, "MSX Cartridge - ASCII16", tag, owner, clock, "msx_cart_ascii16", __FILE__)
|
||||
, msx_cart_interface(mconfig, *this)
|
||||
, m_bank_mask(0)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
m_selected_bank[i] = 0;
|
||||
m_bank_base[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_ascii16::device_start()
|
||||
{
|
||||
save_item(NAME(m_selected_bank));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_cart_ascii16::restore_banks), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_ascii16::restore_banks()
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
m_bank_base[i] = get_rom_base() + (m_selected_bank[i] & m_bank_mask) * 0x4000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_ascii16::device_reset()
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
m_selected_bank[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_ascii16::initialize_cartridge()
|
||||
{
|
||||
UINT32 size = get_rom_size();
|
||||
|
||||
if ( size > 256 * 0x4000 )
|
||||
{
|
||||
fatalerror("ascii16: ROM is too big\n");
|
||||
}
|
||||
|
||||
UINT16 banks = size / 0x4000;
|
||||
|
||||
if (size != banks * 0x4000 || (~(banks - 1) % banks))
|
||||
{
|
||||
fatalerror("ascii16: Invalid ROM size\n");
|
||||
}
|
||||
|
||||
m_bank_mask = banks - 1;
|
||||
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_cart_ascii16::read_cart)
|
||||
{
|
||||
if ( offset >= 0x4000 && offset < 0xC000 )
|
||||
{
|
||||
return m_bank_base[offset >> 15][offset & 0x3fff];
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_cart_ascii16::write_cart)
|
||||
{
|
||||
if (offset >= 0x6000 && offset < 0x6800)
|
||||
{
|
||||
m_selected_bank[0] = data;
|
||||
m_bank_base[0] = get_rom_base() + (m_selected_bank[0] & m_bank_mask) * 0x4000;
|
||||
}
|
||||
|
||||
if (offset >= 0x7000 && offset < 0x7800)
|
||||
{
|
||||
m_selected_bank[1] = data;
|
||||
m_bank_base[1] = get_rom_base() + (m_selected_bank[1] & m_bank_mask) * 0x4000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
msx_cart_ascii8_sram::msx_cart_ascii8_sram(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_CART_ASCII8_SRAM, "MSX Cartridge - ASCII8 w/SRAM", tag, owner, clock, "msx_cart_ascii8_sram", __FILE__)
|
||||
, msx_cart_interface(mconfig, *this)
|
||||
, m_bank_mask(0)
|
||||
, m_sram_select_mask(0)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_selected_bank[i] = 0;
|
||||
m_bank_base[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_ascii8_sram::device_start()
|
||||
{
|
||||
save_item(NAME(m_selected_bank));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_cart_ascii8_sram::restore_banks), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_ascii8_sram::setup_bank(UINT8 bank)
|
||||
{
|
||||
if (m_selected_bank[bank] & ~(m_sram_select_mask | m_bank_mask))
|
||||
{
|
||||
// Nothing is mapped
|
||||
m_bank_base[bank] = NULL;
|
||||
}
|
||||
else if (m_selected_bank[bank] & m_sram_select_mask)
|
||||
{
|
||||
// SRAM is selected
|
||||
m_bank_base[bank] = get_sram_base();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bank_base[bank] = get_rom_base() + (m_selected_bank[bank] & m_bank_mask ) * 0x2000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_ascii8_sram::restore_banks()
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
setup_bank(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_ascii8_sram::device_reset()
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_selected_bank[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_ascii8_sram::initialize_cartridge()
|
||||
{
|
||||
UINT32 size = get_rom_size();
|
||||
|
||||
if ( size > 128 * 0x2000 )
|
||||
{
|
||||
fatalerror("ascii8_sram: ROM is too big\n");
|
||||
}
|
||||
|
||||
UINT16 banks = size / 0x2000;
|
||||
|
||||
if (size != banks * 0x2000 || (~(banks - 1) % banks))
|
||||
{
|
||||
fatalerror("ascii8_sram: Invalid ROM size\n");
|
||||
}
|
||||
|
||||
if (get_sram_size() != 0x2000)
|
||||
{
|
||||
fatalerror("ascii8_sram: Unsupported SRAM size\n");
|
||||
}
|
||||
|
||||
m_bank_mask = banks - 1;
|
||||
m_sram_select_mask = banks;
|
||||
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_cart_ascii8_sram::read_cart)
|
||||
{
|
||||
if ( offset >= 0x4000 && offset < 0xC000 )
|
||||
{
|
||||
UINT8 *bank_base = m_bank_base[(offset - 0x4000) >> 13];
|
||||
|
||||
if (bank_base != NULL)
|
||||
{
|
||||
return bank_base[offset & 0x1fff];
|
||||
}
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_cart_ascii8_sram::write_cart)
|
||||
{
|
||||
if (offset >= 0x6000 && offset < 0x8000)
|
||||
{
|
||||
UINT8 bank = (offset / 0x800) & 0x03;
|
||||
|
||||
m_selected_bank[bank] = data;
|
||||
setup_bank(bank);
|
||||
}
|
||||
else if (offset >= 0x8000 && offset < 0xc000)
|
||||
{
|
||||
UINT8 bank = (offset & 0x2000) ? 3 : 2;
|
||||
|
||||
if ((m_selected_bank[bank] & m_sram_select_mask) && !(m_selected_bank[bank] & ~(m_sram_select_mask | m_bank_mask)))
|
||||
{
|
||||
// Write to SRAM
|
||||
m_bank_base[bank][offset & 0x1fff] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
msx_cart_ascii16_sram::msx_cart_ascii16_sram(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_CART_ASCII16_SRAM, "MSX Cartridge - ASCII16 w/SRAM", tag, owner, clock, "msx_cart_ascii16_sram", __FILE__)
|
||||
, msx_cart_interface(mconfig, *this)
|
||||
, m_bank_mask(0)
|
||||
, m_sram_select_mask(0)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
m_selected_bank[i] = 0;
|
||||
m_bank_base[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_ascii16_sram::device_start()
|
||||
{
|
||||
save_item(NAME(m_selected_bank));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_cart_ascii16_sram::restore_banks), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_ascii16_sram::setup_bank(UINT8 bank)
|
||||
{
|
||||
if (m_selected_bank[bank] & ~(m_sram_select_mask | m_bank_mask))
|
||||
{
|
||||
// Nothing is mapped
|
||||
m_bank_base[bank] = NULL;
|
||||
}
|
||||
else if (m_selected_bank[bank] & m_sram_select_mask)
|
||||
{
|
||||
// SRAM is selected
|
||||
m_bank_base[bank] = get_sram_base();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bank_base[bank] = get_rom_base() + (m_selected_bank[bank] & m_bank_mask) * 0x4000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_ascii16_sram::restore_banks()
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
setup_bank(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_ascii16_sram::device_reset()
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
m_selected_bank[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_ascii16_sram::initialize_cartridge()
|
||||
{
|
||||
UINT32 size = get_rom_size();
|
||||
|
||||
if ( size > 128 * 0x4000 )
|
||||
{
|
||||
fatalerror("ascii16_sram: ROM is too big\n");
|
||||
}
|
||||
|
||||
UINT16 banks = size / 0x4000;
|
||||
|
||||
if (size != banks * 0x4000 || (~(banks - 1) % banks))
|
||||
{
|
||||
fatalerror("ascii16_sram: Invalid ROM size\n");
|
||||
}
|
||||
|
||||
if (get_sram_size() != 0x800)
|
||||
{
|
||||
fatalerror("ascii16_sram: Unsupported SRAM size\n");
|
||||
}
|
||||
|
||||
m_bank_mask = banks - 1;
|
||||
m_sram_select_mask = banks;
|
||||
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_cart_ascii16_sram::read_cart)
|
||||
{
|
||||
if ( offset >= 0x4000 && offset < 0xC000 )
|
||||
{
|
||||
UINT8 bank = offset >> 15;
|
||||
|
||||
if (m_bank_base[bank] != NULL)
|
||||
{
|
||||
if (m_selected_bank[bank] & m_sram_select_mask)
|
||||
{
|
||||
return m_bank_base[bank][offset & 0x7ff];
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_bank_base[bank][offset & 0x3fff];
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_cart_ascii16_sram::write_cart)
|
||||
{
|
||||
if (offset >= 0x6000 && offset < 0x6800)
|
||||
{
|
||||
m_selected_bank[0] = data;
|
||||
setup_bank(0);
|
||||
}
|
||||
|
||||
if (offset >= 0x7000 && offset < 0x7800)
|
||||
{
|
||||
m_selected_bank[1] = data;
|
||||
setup_bank(1);
|
||||
}
|
||||
|
||||
if (offset >= 0x8000 && offset < 0xc000)
|
||||
{
|
||||
if ((m_selected_bank[1] & m_sram_select_mask) && !(m_selected_bank[1] & ~(m_sram_select_mask | m_bank_mask)))
|
||||
{
|
||||
// Write to SRAM
|
||||
m_bank_base[1][offset & 0x7ff] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
116
src/emu/bus/msx_cart/ascii.h
Normal file
116
src/emu/bus/msx_cart/ascii.h
Normal file
@ -0,0 +1,116 @@
|
||||
#ifndef __MSX_CART_ASCII_H
|
||||
#define __MSX_CART_ASCII_H
|
||||
|
||||
#include "bus/msx_cart/cartridge.h"
|
||||
|
||||
|
||||
extern const device_type MSX_CART_ASCII8;
|
||||
extern const device_type MSX_CART_ASCII16;
|
||||
extern const device_type MSX_CART_ASCII8_SRAM;
|
||||
extern const device_type MSX_CART_ASCII16_SRAM;
|
||||
|
||||
|
||||
class msx_cart_ascii8 : public device_t
|
||||
, public msx_cart_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_ascii8(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
private:
|
||||
UINT8 m_bank_mask;
|
||||
UINT8 m_selected_bank[4];
|
||||
UINT8 *m_bank_base[4];
|
||||
};
|
||||
|
||||
|
||||
class msx_cart_ascii16 : public device_t
|
||||
, public msx_cart_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_ascii16(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
private:
|
||||
UINT8 m_bank_mask;
|
||||
UINT8 m_selected_bank[2];
|
||||
UINT8 *m_bank_base[2];
|
||||
};
|
||||
|
||||
|
||||
class msx_cart_ascii8_sram : public device_t
|
||||
, public msx_cart_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_ascii8_sram(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
private:
|
||||
UINT8 m_bank_mask;
|
||||
UINT8 m_selected_bank[4];
|
||||
UINT8 *m_bank_base[4];
|
||||
UINT8 m_sram_select_mask;
|
||||
|
||||
void setup_bank(UINT8 bank);
|
||||
};
|
||||
|
||||
|
||||
class msx_cart_ascii16_sram : public device_t
|
||||
, public msx_cart_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_ascii16_sram(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
private:
|
||||
UINT8 m_bank_mask;
|
||||
UINT8 m_selected_bank[2];
|
||||
UINT8 *m_bank_base[2];
|
||||
UINT8 m_sram_select_mask;
|
||||
|
||||
void setup_bank(UINT8 bank);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
59
src/emu/bus/msx_cart/cartridge.c
Normal file
59
src/emu/bus/msx_cart/cartridge.c
Normal file
@ -0,0 +1,59 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "cartridge.h"
|
||||
#include "ascii.h"
|
||||
#include "crossblaim.h"
|
||||
#include "fmpac.h"
|
||||
#include "konami.h"
|
||||
#include "korean.h"
|
||||
#include "majutsushi.h"
|
||||
#include "msxdos2.h"
|
||||
#include "nomapper.h"
|
||||
#include "rtype.h"
|
||||
#include "superloderunner.h"
|
||||
|
||||
|
||||
SLOT_INTERFACE_START(msx_cart)
|
||||
SLOT_INTERFACE_INTERNAL("nomapper", MSX_CART_NOMAPPER)
|
||||
SLOT_INTERFACE_INTERNAL("msxdos2", MSX_CART_MSXDOS2)
|
||||
SLOT_INTERFACE_INTERNAL("konami_scc", MSX_CART_KONAMI_SCC)
|
||||
SLOT_INTERFACE_INTERNAL("konami", MSX_CART_KONAMI)
|
||||
SLOT_INTERFACE_INTERNAL("ascii8", MSX_CART_ASCII8)
|
||||
SLOT_INTERFACE_INTERNAL("ascii16", MSX_CART_ASCII16)
|
||||
SLOT_INTERFACE_INTERNAL("gamemaster2", MSX_CART_GAMEMASTER2)
|
||||
SLOT_INTERFACE_INTERNAL("ascii8_sram", MSX_CART_ASCII8_SRAM)
|
||||
SLOT_INTERFACE_INTERNAL("ascii16_sram", MSX_CART_ASCII16_SRAM)
|
||||
SLOT_INTERFACE_INTERNAL("rtype", MSX_CART_RTYPE)
|
||||
SLOT_INTERFACE_INTERNAL("majutsushi", MSX_CART_MAJUTSUSHI)
|
||||
SLOT_INTERFACE_INTERNAL("fmpac", MSX_CART_FMPAC)
|
||||
SLOT_INTERFACE_INTERNAL("superloderunner", MSX_CART_SUPERLODERUNNER)
|
||||
SLOT_INTERFACE_INTERNAL("synthesizer", MSX_CART_SYNTHESIZER)
|
||||
SLOT_INTERFACE_INTERNAL("cross_blaim", MSX_CART_CROSSBLAIM)
|
||||
// SLOT_INTERFACE_INTERNAL("disk_rom", MSX_CART_DISK_ROM)
|
||||
SLOT_INTERFACE_INTERNAL("korean_80in1", MSX_CART_KOREAN_80IN1)
|
||||
SLOT_INTERFACE_INTERNAL("korean_90in1", MSX_CART_KOREAN_90IN1)
|
||||
SLOT_INTERFACE_INTERNAL("korean_126in1", MSX_CART_KOREAN_126IN1)
|
||||
SLOT_INTERFACE_INTERNAL("sound_snatcher", MSX_CART_SOUND_SNATCHER)
|
||||
SLOT_INTERFACE_INTERNAL("sound_sdsnatch", MSX_CART_SOUND_SDSNATCHER)
|
||||
SLOT_INTERFACE_END
|
||||
|
||||
|
||||
msx_cart_interface::msx_cart_interface(const machine_config &mconfig, device_t &device)
|
||||
: device_slot_card_interface(mconfig, device)
|
||||
{
|
||||
}
|
||||
|
||||
void msx_cart_interface::rom_alloc(UINT32 size)
|
||||
{
|
||||
m_rom.resize(size);
|
||||
}
|
||||
|
||||
void msx_cart_interface::ram_alloc(UINT32 size)
|
||||
{
|
||||
m_ram.resize(size);
|
||||
}
|
||||
|
||||
void msx_cart_interface::sram_alloc(UINT32 size)
|
||||
{
|
||||
m_sram.resize(size);
|
||||
}
|
42
src/emu/bus/msx_cart/cartridge.h
Normal file
42
src/emu/bus/msx_cart/cartridge.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef __MSX_CART_CARTRIDGE_H
|
||||
#define __MSX_CART_CARTRIDGE_H
|
||||
|
||||
|
||||
SLOT_INTERFACE_EXTERN(msx_cart);
|
||||
|
||||
|
||||
class msx_cart_interface : public device_slot_card_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_interface(const machine_config &mconfig, device_t &device);
|
||||
|
||||
// This is called after loading cartridge contents and allows the cartridge
|
||||
// implementation to perform some additional initialization based on the
|
||||
// cartridge contents.
|
||||
virtual void initialize_cartridge() {}
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_cart) { return 0xff; }
|
||||
virtual DECLARE_WRITE8_MEMBER(write_cart) {}
|
||||
|
||||
// ROM/RAM/SRAM management
|
||||
// Mainly used by the cartridge slot when loading images
|
||||
void rom_alloc(UINT32 size);
|
||||
void ram_alloc(UINT32 size);
|
||||
void sram_alloc(UINT32 size);
|
||||
|
||||
UINT8* get_rom_base() { return m_rom; }
|
||||
UINT8* get_ram_base() { return m_ram; }
|
||||
UINT8* get_sram_base() { return m_sram; }
|
||||
UINT32 get_rom_size() { return m_rom.count(); }
|
||||
UINT32 get_ram_size() { return m_ram.count(); }
|
||||
UINT32 get_sram_size() { return m_sram.count(); }
|
||||
|
||||
protected:
|
||||
dynamic_buffer m_rom;
|
||||
dynamic_buffer m_ram;
|
||||
dynamic_buffer m_sram;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
81
src/emu/bus/msx_cart/crossblaim.c
Normal file
81
src/emu/bus/msx_cart/crossblaim.c
Normal file
@ -0,0 +1,81 @@
|
||||
#include "emu.h"
|
||||
#include "crossblaim.h"
|
||||
|
||||
const device_type MSX_CART_CROSSBLAIM = &device_creator<msx_cart_crossblaim>;
|
||||
|
||||
|
||||
msx_cart_crossblaim::msx_cart_crossblaim(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_CART_CROSSBLAIM, "MSX Cartridge - Cross Blaim", tag, owner, clock, "msx_cart_crossblaim", __FILE__)
|
||||
, msx_cart_interface(mconfig, *this)
|
||||
, m_selected_bank(1)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_bank_base[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_crossblaim::device_start()
|
||||
{
|
||||
save_item(NAME(m_selected_bank));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_cart_crossblaim::restore_banks), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_crossblaim::setup_bank()
|
||||
{
|
||||
m_bank_base[0] = ( m_selected_bank & 2 ) ? NULL : get_rom_base() + ( m_selected_bank & 0x03 ) * 0x4000;
|
||||
m_bank_base[2] = get_rom_base() + ( m_selected_bank & 0x03 ) * 0x4000;
|
||||
m_bank_base[3] = ( m_selected_bank & 2 ) ? NULL : get_rom_base() + ( m_selected_bank & 0x03 ) * 0x4000;
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_crossblaim::restore_banks()
|
||||
{
|
||||
m_bank_base[1] = get_rom_base();
|
||||
setup_bank();
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_crossblaim::device_reset()
|
||||
{
|
||||
m_selected_bank = 1;
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_crossblaim::initialize_cartridge()
|
||||
{
|
||||
if (get_rom_size() != 0x10000)
|
||||
{
|
||||
fatalerror("crossblaim: Invalid ROM size\n");
|
||||
}
|
||||
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_cart_crossblaim::read_cart)
|
||||
{
|
||||
UINT8 *bank_base = m_bank_base[offset >> 14];
|
||||
|
||||
if (bank_base != NULL)
|
||||
{
|
||||
return bank_base[offset & 0x3fff];
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_cart_crossblaim::write_cart)
|
||||
{
|
||||
m_selected_bank = data & 3;
|
||||
if (m_selected_bank == 0)
|
||||
{
|
||||
m_selected_bank = 1;
|
||||
}
|
||||
setup_bank();
|
||||
}
|
||||
|
35
src/emu/bus/msx_cart/crossblaim.h
Normal file
35
src/emu/bus/msx_cart/crossblaim.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef __MSX_CART_CROSSBLAIM_H
|
||||
#define __MSX_CART_CROSSBLAIM_H
|
||||
|
||||
#include "bus/msx_cart/cartridge.h"
|
||||
|
||||
|
||||
extern const device_type MSX_CART_CROSSBLAIM;
|
||||
|
||||
|
||||
class msx_cart_crossblaim : public device_t
|
||||
, public msx_cart_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_crossblaim(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
private:
|
||||
UINT8 m_selected_bank;
|
||||
UINT8 *m_bank_base[4];
|
||||
|
||||
void setup_bank();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
172
src/emu/bus/msx_cart/fmpac.c
Normal file
172
src/emu/bus/msx_cart/fmpac.c
Normal file
@ -0,0 +1,172 @@
|
||||
/**********************************************************************************
|
||||
|
||||
When backing up the SRAM from an FM-PAC the file seems to be prefixed
|
||||
with: PAC2 BACKUP DATA. We only store the raw sram contents.
|
||||
|
||||
**********************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "fmpac.h"
|
||||
|
||||
const device_type MSX_CART_FMPAC = &device_creator<msx_cart_fmpac>;
|
||||
|
||||
|
||||
msx_cart_fmpac::msx_cart_fmpac(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_CART_FMPAC, "MSX Cartridge - FM-PAC", tag, owner, clock, "msx_cart_fmpac", __FILE__)
|
||||
, msx_cart_interface(mconfig, *this)
|
||||
, m_ym2413(*this, "ym2413")
|
||||
, m_selected_bank(0)
|
||||
, m_bank_base(NULL)
|
||||
, m_sram_active(false)
|
||||
, m_opll_active(false)
|
||||
, m_1ffe(0)
|
||||
, m_1fff(0)
|
||||
, m_7ff6(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( fmpac )
|
||||
// This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'.
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_SOUND_ADD("ym2413", YM2413, XTAL_10_738635MHz/3)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.40)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
machine_config_constructor msx_cart_fmpac::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( fmpac );
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_fmpac::device_start()
|
||||
{
|
||||
save_item(NAME(m_selected_bank));
|
||||
save_item(NAME(m_sram_active));
|
||||
save_item(NAME(m_opll_active));
|
||||
save_item(NAME(m_1ffe));
|
||||
save_item(NAME(m_1fff));
|
||||
save_item(NAME(m_7ff6));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_cart_fmpac::restore_banks), this));
|
||||
|
||||
// Install IO read/write handlers
|
||||
address_space &space = machine().device<cpu_device>("maincpu")->space(AS_IO);
|
||||
space.install_write_handler(0x7c, 0x7d, write8_delegate(FUNC(msx_cart_fmpac::write_ym2413), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_fmpac::restore_banks()
|
||||
{
|
||||
m_bank_base = get_rom_base() + ( m_selected_bank & 0x03 ) * 0x4000;
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_fmpac::device_reset()
|
||||
{
|
||||
m_selected_bank = 0;
|
||||
m_sram_active = false;
|
||||
m_opll_active = false;
|
||||
m_1ffe = 0;
|
||||
m_1fff = 0;
|
||||
m_7ff6 = 0;
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_fmpac::initialize_cartridge()
|
||||
{
|
||||
if ( get_rom_size() != 0x10000 )
|
||||
{
|
||||
fatalerror("fmpac: Invalid ROM size\n");
|
||||
}
|
||||
|
||||
if ( get_sram_size() != 0x2000 )
|
||||
{
|
||||
fatalerror("fmpac: Invalid SRAM size\n");
|
||||
}
|
||||
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_cart_fmpac::read_cart)
|
||||
{
|
||||
if (offset >= 0x4000 && offset < 0x8000)
|
||||
{
|
||||
if (offset == 0x7ff6)
|
||||
{
|
||||
return m_7ff6;
|
||||
}
|
||||
if (offset == 0x7ff7)
|
||||
{
|
||||
return m_selected_bank & 0x03;
|
||||
}
|
||||
if (m_sram_active)
|
||||
{
|
||||
if (offset & 0x2000)
|
||||
{
|
||||
return 0xff;
|
||||
}
|
||||
return get_sram_base()[offset & 0x1fff];
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_bank_base[offset & 0x3fff];
|
||||
}
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_cart_fmpac::write_cart)
|
||||
{
|
||||
if (offset >= 0x4000 && offset < 0x6000)
|
||||
{
|
||||
if (m_sram_active)
|
||||
{
|
||||
get_sram_base()[offset & 0x1fff] = data;
|
||||
}
|
||||
if (offset == 0x5ffe)
|
||||
{
|
||||
m_1ffe = data;
|
||||
}
|
||||
if (offset == 0x5fff)
|
||||
{
|
||||
m_1fff = data;
|
||||
}
|
||||
m_sram_active = (m_1ffe == 0x4d) && (m_1fff == 0x69);
|
||||
}
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x7ff4:
|
||||
case 0x7ff5:
|
||||
if (m_opll_active)
|
||||
{
|
||||
m_ym2413->write(space, offset & 1, data);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x7ff6:
|
||||
m_7ff6 = data & 0x11;
|
||||
m_opll_active = (m_7ff6 & 0x01);
|
||||
break;
|
||||
|
||||
case 0x7ff7:
|
||||
m_selected_bank = data;
|
||||
restore_banks();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_cart_fmpac::write_ym2413)
|
||||
{
|
||||
if (m_opll_active)
|
||||
{
|
||||
m_ym2413->write(space, offset & 1, data);
|
||||
}
|
||||
}
|
||||
|
44
src/emu/bus/msx_cart/fmpac.h
Normal file
44
src/emu/bus/msx_cart/fmpac.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef __MSX_CART_FMPAC_H
|
||||
#define __MSX_CART_FMPAC_H
|
||||
|
||||
#include "bus/msx_cart/cartridge.h"
|
||||
#include "sound/2413intf.h"
|
||||
|
||||
|
||||
extern const device_type MSX_CART_FMPAC;
|
||||
|
||||
|
||||
class msx_cart_fmpac : public device_t
|
||||
, public msx_cart_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_fmpac(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
DECLARE_WRITE8_MEMBER(write_ym2413);
|
||||
|
||||
private:
|
||||
required_device<ym2413_device> m_ym2413;
|
||||
|
||||
UINT8 m_selected_bank;
|
||||
UINT8 *m_bank_base;
|
||||
bool m_sram_active;
|
||||
bool m_opll_active;
|
||||
UINT8 m_1ffe;
|
||||
UINT8 m_1fff;
|
||||
UINT8 m_7ff6;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
862
src/emu/bus/msx_cart/konami.c
Normal file
862
src/emu/bus/msx_cart/konami.c
Normal file
@ -0,0 +1,862 @@
|
||||
#include "emu.h"
|
||||
#include "konami.h"
|
||||
|
||||
const device_type MSX_CART_KONAMI = &device_creator<msx_cart_konami>;
|
||||
const device_type MSX_CART_KONAMI_SCC = &device_creator<msx_cart_konami_scc>;
|
||||
const device_type MSX_CART_GAMEMASTER2 = &device_creator<msx_cart_gamemaster2>;
|
||||
const device_type MSX_CART_SYNTHESIZER = &device_creator<msx_cart_synthesizer>;
|
||||
const device_type MSX_CART_SOUND_SNATCHER = &device_creator<msx_cart_konami_sound_snatcher>;
|
||||
const device_type MSX_CART_SOUND_SDSNATCHER = &device_creator<msx_cart_konami_sound_sdsnatcher>;
|
||||
|
||||
|
||||
msx_cart_konami::msx_cart_konami(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_CART_KONAMI, "MSX Cartridge - KONAMI", tag, owner, clock, "msx_cart_konami", __FILE__)
|
||||
, msx_cart_interface(mconfig, *this)
|
||||
, m_bank_mask(0)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
m_selected_bank[i] = 0;
|
||||
}
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
m_bank_base[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_konami::device_start()
|
||||
{
|
||||
save_item(NAME(m_selected_bank));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_cart_konami::restore_banks), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_konami::restore_banks()
|
||||
{
|
||||
m_bank_base[0] = get_rom_base();
|
||||
m_bank_base[1] = get_rom_base() + ( m_selected_bank[0] & m_bank_mask ) * 0x2000;
|
||||
m_bank_base[2] = get_rom_base();
|
||||
m_bank_base[3] = get_rom_base() + ( m_selected_bank[0] & m_bank_mask ) * 0x2000;
|
||||
m_bank_base[4] = get_rom_base() + ( m_selected_bank[1] & m_bank_mask ) * 0x2000;
|
||||
m_bank_base[5] = get_rom_base() + ( m_selected_bank[2] & m_bank_mask ) * 0x2000;
|
||||
m_bank_base[6] = get_rom_base() + ( m_selected_bank[1] & m_bank_mask ) * 0x2000;
|
||||
m_bank_base[7] = get_rom_base() + ( m_selected_bank[2] & m_bank_mask ) * 0x2000;
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_konami::device_reset()
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
m_selected_bank[i] = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_konami::initialize_cartridge()
|
||||
{
|
||||
UINT32 size = get_rom_size();
|
||||
|
||||
if ( get_rom_size() > 256 * 0x2000 )
|
||||
{
|
||||
fatalerror("konami: ROM is too big\n");
|
||||
}
|
||||
|
||||
UINT16 banks = size / 0x2000;
|
||||
|
||||
if (size != banks * 0x2000 || (~(banks - 1) % banks))
|
||||
{
|
||||
fatalerror("konami: Invalid ROM size\n");
|
||||
}
|
||||
|
||||
m_bank_mask = banks - 1;
|
||||
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_cart_konami::read_cart)
|
||||
{
|
||||
return m_bank_base[offset >> 13][offset & 0x1fff];
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_cart_konami::write_cart)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x6000:
|
||||
m_selected_bank[0] = data;
|
||||
m_bank_base[1] = get_rom_base() + ( m_selected_bank[0] & m_bank_mask ) * 0x2000;
|
||||
m_bank_base[3] = get_rom_base() + ( m_selected_bank[0] & m_bank_mask ) * 0x2000;
|
||||
break;
|
||||
|
||||
case 0x8000:
|
||||
m_selected_bank[1] = data;
|
||||
m_bank_base[4] = get_rom_base() + ( m_selected_bank[1] & m_bank_mask ) * 0x2000;
|
||||
m_bank_base[6] = get_rom_base() + ( m_selected_bank[1] & m_bank_mask ) * 0x2000;
|
||||
break;
|
||||
|
||||
case 0xa000:
|
||||
m_selected_bank[2] = data;
|
||||
m_bank_base[5] = get_rom_base() + ( m_selected_bank[2] & m_bank_mask ) * 0x2000;
|
||||
m_bank_base[7] = get_rom_base() + ( m_selected_bank[2] & m_bank_mask ) * 0x2000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
msx_cart_konami_scc::msx_cart_konami_scc(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_CART_KONAMI_SCC, "MSX Cartridge - KONAMI+SCC", tag, owner, clock, "msx_cart_konami_scc", __FILE__)
|
||||
, msx_cart_interface(mconfig, *this)
|
||||
, m_k051649(*this, "k051649")
|
||||
, m_bank_mask(0)
|
||||
, m_scc_active(false)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_selected_bank[i] = 0;
|
||||
}
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
m_bank_base[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( konami_scc )
|
||||
// This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'.
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_SOUND_ADD("k051649", K051649, XTAL_10_738635MHz/3/2)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.15)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
machine_config_constructor msx_cart_konami_scc::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( konami_scc );
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_konami_scc::device_start()
|
||||
{
|
||||
save_item(NAME(m_selected_bank));
|
||||
save_item(NAME(m_scc_active));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_cart_konami_scc::restore_banks), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_konami_scc::restore_banks()
|
||||
{
|
||||
m_bank_base[0] = get_rom_base() + ( m_selected_bank[2] & m_bank_mask ) * 0x2000;
|
||||
m_bank_base[1] = get_rom_base() + ( m_selected_bank[3] & m_bank_mask ) * 0x2000;
|
||||
m_bank_base[2] = get_rom_base() + ( m_selected_bank[0] & m_bank_mask ) * 0x2000;
|
||||
m_bank_base[3] = get_rom_base() + ( m_selected_bank[1] & m_bank_mask ) * 0x2000;
|
||||
m_bank_base[4] = get_rom_base() + ( m_selected_bank[2] & m_bank_mask ) * 0x2000;
|
||||
m_bank_base[5] = get_rom_base() + ( m_selected_bank[3] & m_bank_mask ) * 0x2000;
|
||||
m_bank_base[6] = get_rom_base() + ( m_selected_bank[0] & m_bank_mask ) * 0x2000;
|
||||
m_bank_base[7] = get_rom_base() + ( m_selected_bank[1] & m_bank_mask ) * 0x2000;
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_konami_scc::device_reset()
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_selected_bank[i] = i;
|
||||
}
|
||||
m_scc_active = false;
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_konami_scc::initialize_cartridge()
|
||||
{
|
||||
UINT32 size = get_rom_size();
|
||||
|
||||
if ( get_rom_size() > 256 * 0x2000 )
|
||||
{
|
||||
fatalerror("konami_scc: ROM is too big\n");
|
||||
}
|
||||
|
||||
UINT16 banks = size / 0x2000;
|
||||
|
||||
if (size != banks * 0x2000 || (~(banks - 1) % banks))
|
||||
{
|
||||
fatalerror("konami_scc: Invalid ROM size\n");
|
||||
}
|
||||
|
||||
m_bank_mask = banks - 1;
|
||||
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_cart_konami_scc::read_cart)
|
||||
{
|
||||
if ( m_scc_active && offset >= 0x9800 && offset < 0xa000 )
|
||||
{
|
||||
if (offset & 0x80)
|
||||
{
|
||||
if ((offset & 0xff) >= 0xe0)
|
||||
{
|
||||
return m_k051649->k051649_test_r(space, offset & 0xff);
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_k051649->k051649_waveform_r(space, offset & 0x7f);
|
||||
}
|
||||
}
|
||||
|
||||
return m_bank_base[offset >> 13][offset & 0x1fff];
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_cart_konami_scc::write_cart)
|
||||
{
|
||||
switch (offset & 0xf800)
|
||||
{
|
||||
case 0x5000:
|
||||
m_selected_bank[0] = data;
|
||||
m_bank_base[2] = get_rom_base() + ( m_selected_bank[0] & m_bank_mask ) * 0x2000;
|
||||
m_bank_base[6] = get_rom_base() + ( m_selected_bank[0] & m_bank_mask ) * 0x2000;
|
||||
break;
|
||||
|
||||
case 0x7000:
|
||||
m_selected_bank[1] = data;
|
||||
m_bank_base[3] = get_rom_base() + ( m_selected_bank[1] & m_bank_mask ) * 0x2000;
|
||||
m_bank_base[7] = get_rom_base() + ( m_selected_bank[1] & m_bank_mask ) * 0x2000;
|
||||
break;
|
||||
|
||||
case 0x9000:
|
||||
m_selected_bank[2] = data;
|
||||
m_scc_active = ( ( data & 0x3f ) == 0x3f );
|
||||
m_bank_base[0] = get_rom_base() + ( m_selected_bank[2] & m_bank_mask ) * 0x2000;
|
||||
m_bank_base[4] = get_rom_base() + ( m_selected_bank[2] & m_bank_mask ) * 0x2000;
|
||||
break;
|
||||
|
||||
case 0x9800:
|
||||
if ( m_scc_active )
|
||||
{
|
||||
offset &= 0xff;
|
||||
|
||||
if (offset < 0x80)
|
||||
{
|
||||
m_k051649->k051649_waveform_w(space, offset, data);
|
||||
}
|
||||
else if (offset < 0xa0)
|
||||
{
|
||||
offset &= 0x0f;
|
||||
if (offset < 0x0a)
|
||||
{
|
||||
m_k051649->k051649_frequency_w(space, offset, data);
|
||||
}
|
||||
else if (offset < 0x0f)
|
||||
{
|
||||
m_k051649->k051649_volume_w(space, offset - 0xa, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_k051649->k051649_keyonoff_w(space, 0, data);
|
||||
}
|
||||
}
|
||||
else if (offset >= 0xe0)
|
||||
{
|
||||
m_k051649->k051649_test_w(space, offset, data);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xb000:
|
||||
m_selected_bank[3] = data;
|
||||
m_bank_base[1] = get_rom_base() + ( m_selected_bank[3] & m_bank_mask ) * 0x2000;
|
||||
m_bank_base[5] = get_rom_base() + ( m_selected_bank[3] & m_bank_mask ) * 0x2000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
msx_cart_gamemaster2::msx_cart_gamemaster2(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_CART_GAMEMASTER2, "MSX Cartridge - GAMEMASTER2", tag, owner, clock, "msx_cart_gamemaster2", __FILE__)
|
||||
, msx_cart_interface(mconfig, *this)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
m_selected_bank[i] = 0;
|
||||
}
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
m_bank_base[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_gamemaster2::device_start()
|
||||
{
|
||||
save_item(NAME(m_selected_bank));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_cart_gamemaster2::restore_banks), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_gamemaster2::setup_bank(UINT8 bank)
|
||||
{
|
||||
switch (bank)
|
||||
{
|
||||
case 0:
|
||||
if (m_selected_bank[0] & 0x10)
|
||||
{
|
||||
m_bank_base[1] = get_sram_base() + ((m_selected_bank[0] & 0x20) ? 0x1000 : 0);
|
||||
m_bank_base[3] = get_sram_base() + ((m_selected_bank[0] & 0x20) ? 0x1000 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bank_base[1] = get_rom_base() + ( m_selected_bank[0] & 0x0f ) * 0x2000;
|
||||
m_bank_base[3] = get_rom_base() + ( m_selected_bank[0] & 0x0f ) * 0x2000;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (m_selected_bank[1] & 0x10)
|
||||
{
|
||||
m_bank_base[4] = get_sram_base() + ((m_selected_bank[1] & 0x20) ? 0x1000 : 0);
|
||||
m_bank_base[6] = get_sram_base() + ((m_selected_bank[1] & 0x20) ? 0x1000 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bank_base[4] = get_rom_base() + ( m_selected_bank[1] & 0x0f ) * 0x2000;
|
||||
m_bank_base[6] = get_rom_base() + ( m_selected_bank[1] & 0x0f ) * 0x2000;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (m_selected_bank[2] & 0x10)
|
||||
{
|
||||
m_bank_base[5] = get_sram_base() + ((m_selected_bank[2] & 0x20) ? 0x1000 : 0);
|
||||
m_bank_base[7] = get_sram_base() + ((m_selected_bank[2] & 0x20) ? 0x1000 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bank_base[5] = get_rom_base() + ( m_selected_bank[2] & 0x0f ) * 0x2000;
|
||||
m_bank_base[7] = get_rom_base() + ( m_selected_bank[2] & 0x0f ) * 0x2000;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_gamemaster2::restore_banks()
|
||||
{
|
||||
m_bank_base[0] = get_rom_base();
|
||||
m_bank_base[2] = get_rom_base();
|
||||
setup_bank(0);
|
||||
setup_bank(1);
|
||||
setup_bank(2);
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_gamemaster2::device_reset()
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
m_selected_bank[i] = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_gamemaster2::initialize_cartridge()
|
||||
{
|
||||
if ( get_rom_size() != 0x20000 )
|
||||
{
|
||||
fatalerror("gamemaster2: Invalid ROM size\n");
|
||||
}
|
||||
|
||||
if (get_sram_size() != 0x2000)
|
||||
{
|
||||
fatalerror("gamemaster2: Invalid SRAM size\n");
|
||||
}
|
||||
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_cart_gamemaster2::read_cart)
|
||||
{
|
||||
UINT8 bank = offset >> 13;
|
||||
|
||||
switch (bank)
|
||||
{
|
||||
case 1:
|
||||
case 3:
|
||||
if (m_selected_bank[0] & 0x10)
|
||||
{
|
||||
return m_bank_base[bank][offset & 0x0fff];
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 6:
|
||||
if (m_selected_bank[1] & 0x10)
|
||||
{
|
||||
return m_bank_base[bank][offset & 0x0fff];
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
case 7:
|
||||
if (m_selected_bank[2] & 0x10)
|
||||
{
|
||||
return m_bank_base[bank][offset & 0x0fff];
|
||||
}
|
||||
break;
|
||||
}
|
||||
return m_bank_base[bank][offset & 0x1fff];
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_cart_gamemaster2::write_cart)
|
||||
{
|
||||
switch (offset & 0xf000)
|
||||
{
|
||||
case 0x6000:
|
||||
m_selected_bank[0] = data;
|
||||
setup_bank(0);
|
||||
break;
|
||||
|
||||
case 0x8000:
|
||||
m_selected_bank[1] = data;
|
||||
setup_bank(1);
|
||||
break;
|
||||
|
||||
case 0xa000:
|
||||
m_selected_bank[2] = data;
|
||||
setup_bank(2);
|
||||
break;
|
||||
|
||||
case 0xb000:
|
||||
if (m_selected_bank[2] & 0x10)
|
||||
{
|
||||
m_bank_base[5][offset & 0x0fff] = data;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
msx_cart_synthesizer::msx_cart_synthesizer(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_CART_SYNTHESIZER, "MSX Cartridge - Synthesizer", tag, owner, clock, "msx_cart_synthesizer", __FILE__)
|
||||
, msx_cart_interface(mconfig, *this)
|
||||
, m_bank_base(NULL)
|
||||
, m_dac(*this, "dac")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( synthesizer )
|
||||
// This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'.
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_SOUND_ADD("dac", DAC, 0)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.20)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
machine_config_constructor msx_cart_synthesizer::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( synthesizer );
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_synthesizer::device_start()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_synthesizer::initialize_cartridge()
|
||||
{
|
||||
if ( get_rom_size() != 0x8000 )
|
||||
{
|
||||
fatalerror("synthesizer: Invalid ROM size\n");
|
||||
}
|
||||
|
||||
m_bank_base = get_rom_base();
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_cart_synthesizer::read_cart)
|
||||
{
|
||||
if (offset >= 0x4000 && offset < 0xc000 )
|
||||
{
|
||||
return m_bank_base[offset - 0x4000];
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_cart_synthesizer::write_cart)
|
||||
{
|
||||
if ((offset & 0xc010) == 0x4000)
|
||||
{
|
||||
m_dac->write_unsigned8(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
msx_cart_konami_sound::msx_cart_konami_sound(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)
|
||||
, msx_cart_interface(mconfig, *this)
|
||||
, m_k052539(*this, "k052539")
|
||||
, m_scc_active(false)
|
||||
, m_sccplus_active(false)
|
||||
, m_scc_mode(0)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_selected_bank[i] = 0;
|
||||
}
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
m_bank_base[i] = NULL;
|
||||
}
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
m_ram_bank[i] = NULL;
|
||||
}
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_ram_enabled[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( konami_sound )
|
||||
// This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'.
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_SOUND_ADD("k052539", K051649, XTAL_10_738635MHz/3/2)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.15)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
machine_config_constructor msx_cart_konami_sound::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( konami_sound );
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_konami_sound::device_start()
|
||||
{
|
||||
save_item(NAME(m_selected_bank));
|
||||
save_item(NAME(m_scc_active));
|
||||
save_item(NAME(m_sccplus_active));
|
||||
save_item(NAME(m_ram_enabled));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_cart_konami_sound::restore_banks), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_konami_sound::restore_banks()
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
setup_bank(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_konami_sound::setup_bank(UINT8 bank)
|
||||
{
|
||||
switch (bank)
|
||||
{
|
||||
case 0:
|
||||
m_bank_base[2] = m_ram_bank[m_selected_bank[0] & 0x0f];
|
||||
m_bank_base[6] = m_ram_bank[m_selected_bank[0] & 0x0f];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
m_bank_base[3] = m_ram_bank[m_selected_bank[1] & 0x0f];
|
||||
m_bank_base[7] = m_ram_bank[m_selected_bank[1] & 0x0f];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_bank_base[0] = m_ram_bank[m_selected_bank[2] & 0x0f];
|
||||
m_bank_base[4] = m_ram_bank[m_selected_bank[2] & 0x0f];
|
||||
break;
|
||||
|
||||
case 3:
|
||||
m_bank_base[1] = m_ram_bank[m_selected_bank[3] & 0x0f];
|
||||
m_bank_base[5] = m_ram_bank[m_selected_bank[3] & 0x0f];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_konami_sound::device_reset()
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_selected_bank[i] = i;
|
||||
m_ram_enabled[i] = false;
|
||||
}
|
||||
m_scc_active = false;
|
||||
m_sccplus_active = false;
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_konami_sound::initialize_cartridge()
|
||||
{
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_cart_konami_sound::read_cart)
|
||||
{
|
||||
if ( m_scc_active && offset >= 0x9800 && offset < 0x9fe0 )
|
||||
{
|
||||
offset &= 0xff;
|
||||
if (offset < 0x80)
|
||||
{
|
||||
return m_k052539->k051649_waveform_r(space, offset);
|
||||
}
|
||||
if (offset < 0xa0)
|
||||
{
|
||||
return 0xff;
|
||||
}
|
||||
if (offset < 0xc0)
|
||||
{
|
||||
return m_k052539->k051649_waveform_r(space, offset & 0x9f);
|
||||
}
|
||||
if (offset < 0xe0)
|
||||
{
|
||||
return m_k052539->k051649_test_r(space, offset & 0xff);
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
else if ( m_sccplus_active && offset >= 0xb800 && offset < 0xbfe0)
|
||||
{
|
||||
offset &= 0xff;
|
||||
|
||||
if (offset < 0xa0)
|
||||
{
|
||||
return m_k052539->k052539_waveform_r(space, offset);
|
||||
}
|
||||
if (offset >= 0xc0 && offset < 0xe0)
|
||||
{
|
||||
return m_k052539->k051649_test_r(space, offset);
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
UINT8 *base = m_bank_base[offset >> 13];
|
||||
|
||||
if (base != NULL)
|
||||
{
|
||||
return base[offset & 0x1fff];
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_cart_konami_sound::write_cart)
|
||||
{
|
||||
switch (offset & 0xe000)
|
||||
{
|
||||
case 0x4000:
|
||||
if (m_ram_enabled[0] && m_bank_base[2] != NULL)
|
||||
{
|
||||
m_bank_base[2][offset & 0x1fff] = data;
|
||||
}
|
||||
if ((offset & 0x1800) == 0x1000)
|
||||
{
|
||||
m_selected_bank[0] = data;
|
||||
setup_bank(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x6000:
|
||||
if (m_ram_enabled[1] && m_bank_base[3] != NULL)
|
||||
{
|
||||
m_bank_base[3][offset & 0x1fff] = data;
|
||||
}
|
||||
if ((offset & 0x1800) == 0x1000)
|
||||
{
|
||||
m_selected_bank[1] = data;
|
||||
setup_bank(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8000:
|
||||
if (m_ram_enabled[2] && m_bank_base[0] != NULL)
|
||||
{
|
||||
m_bank_base[0][offset & 0x1fff] = data;
|
||||
}
|
||||
switch (offset & 0x1800)
|
||||
{
|
||||
case 0x1000: // 0x9000-0x97ff
|
||||
m_selected_bank[2] = data;
|
||||
m_scc_active = ( ( data & 0x3f ) == 0x3f );
|
||||
setup_bank(2);
|
||||
break;
|
||||
|
||||
case 0x1800: // 0x9800-0x9fff
|
||||
if ( m_scc_active )
|
||||
{
|
||||
offset &= 0xff;
|
||||
|
||||
if (offset < 0x80)
|
||||
{
|
||||
m_k052539->k051649_waveform_w(space, offset, data);
|
||||
}
|
||||
else if (offset < 0xa0)
|
||||
{
|
||||
offset &= 0x0f;
|
||||
if (offset < 0x0a)
|
||||
{
|
||||
m_k052539->k051649_frequency_w(space, offset, data);
|
||||
}
|
||||
else if (offset < 0x0f)
|
||||
{
|
||||
m_k052539->k051649_volume_w(space, offset - 0xa, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_k052539->k051649_keyonoff_w(space, 0, data);
|
||||
}
|
||||
}
|
||||
else if (offset >= 0xe0)
|
||||
{
|
||||
m_k052539->k051649_test_w(space, offset, data);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xa000:
|
||||
if (m_ram_enabled[3] && m_bank_base[1] != NULL)
|
||||
{
|
||||
m_bank_base[1][offset & 0x1fff] = data;
|
||||
}
|
||||
switch (offset & 0x1800)
|
||||
{
|
||||
// 0xb000-0xb7ff
|
||||
case 0x1000:
|
||||
m_selected_bank[3] = data;
|
||||
setup_bank(3);
|
||||
break;
|
||||
|
||||
// 0xb800-0xbfff
|
||||
case 0x1800:
|
||||
if ((offset & 0x7fe) == 0x7fe)
|
||||
{
|
||||
// 0xbffe-0xbfff
|
||||
/* write to mode register */
|
||||
m_scc_mode = data;
|
||||
|
||||
m_ram_enabled[0] = ((m_scc_mode & 0x10) || (m_scc_mode & 0x01));
|
||||
m_ram_enabled[1] = ((m_scc_mode & 0x10) || (m_scc_mode & 0x02));
|
||||
m_ram_enabled[2] = ((m_scc_mode & 0x10) || ((m_scc_mode & 0x04) && (m_scc_mode & 0x20)));
|
||||
m_ram_enabled[3] = (m_scc_mode & 0x10);
|
||||
|
||||
m_scc_active = ((m_selected_bank[2] & 0x3f) == 0x3f) && !(m_scc_mode & 0x20);
|
||||
m_sccplus_active = (m_selected_bank[3] & 0x80) && (m_scc_mode & 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_sccplus_active)
|
||||
{
|
||||
offset &= 0xff;
|
||||
if (offset < 0xa0)
|
||||
{
|
||||
m_k052539->k052539_waveform_w(space, offset, data);
|
||||
}
|
||||
else if (offset < 0xc0)
|
||||
{
|
||||
offset &= 0x0f;
|
||||
if (offset < 0x0a)
|
||||
{
|
||||
m_k052539->k051649_frequency_w(space, offset, data);
|
||||
}
|
||||
else if (offset < 0x0f)
|
||||
{
|
||||
m_k052539->k051649_volume_w(space, offset - 0x0a, data);
|
||||
}
|
||||
else if (offset == 0x0f)
|
||||
{
|
||||
m_k052539->k051649_keyonoff_w(space, 0, data);
|
||||
}
|
||||
}
|
||||
else if (offset < 0xe0)
|
||||
{
|
||||
m_k052539->k051649_test_w(space, offset, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
msx_cart_konami_sound_snatcher::msx_cart_konami_sound_snatcher(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: msx_cart_konami_sound(mconfig, MSX_CART_SOUND_SNATCHER, "MSX Cartridge - Sound Snatcher", tag, owner, clock, "msx_cart_sound_snatcher", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_konami_sound_snatcher::initialize_cartridge()
|
||||
{
|
||||
msx_cart_konami_sound::initialize_cartridge();
|
||||
|
||||
if (get_ram_size() != 0x10000)
|
||||
{
|
||||
fatalerror("sound_snatcher: Invalid RAM size\n");
|
||||
}
|
||||
|
||||
// The Snatcher Sound cartridge has 64KB RAM available by selecting ram banks 0-7
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
m_ram_bank[i] = get_ram_base() + i * 0x2000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
msx_cart_konami_sound_sdsnatcher::msx_cart_konami_sound_sdsnatcher(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: msx_cart_konami_sound(mconfig, MSX_CART_SOUND_SDSNATCHER, "MSX Cartridge - Sound SD Snatcher", tag, owner, clock, "msx_cart_sound_sdsnatcher", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_konami_sound_sdsnatcher::initialize_cartridge()
|
||||
{
|
||||
msx_cart_konami_sound::initialize_cartridge();
|
||||
|
||||
if (get_ram_size() != 0x10000)
|
||||
{
|
||||
fatalerror("sound_sdsnatcher: Invalid RAM size\n");
|
||||
}
|
||||
|
||||
// The SD Snatcher Sound cartrdige has 64KB RAM available by selecting ram banks 8-15
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
m_ram_bank[8+i] = get_ram_base() + i * 0x2000;
|
||||
}
|
||||
|
||||
}
|
||||
|
169
src/emu/bus/msx_cart/konami.h
Normal file
169
src/emu/bus/msx_cart/konami.h
Normal file
@ -0,0 +1,169 @@
|
||||
#ifndef __MSX_CART_KONAMI_H
|
||||
#define __MSX_CART_KONAMI_H
|
||||
|
||||
#include "bus/msx_cart/cartridge.h"
|
||||
#include "sound/k051649.h"
|
||||
#include "sound/dac.h"
|
||||
|
||||
|
||||
extern const device_type MSX_CART_KONAMI;
|
||||
extern const device_type MSX_CART_KONAMI_SCC;
|
||||
extern const device_type MSX_CART_GAMEMASTER2;
|
||||
extern const device_type MSX_CART_SYNTHESIZER;
|
||||
extern const device_type MSX_CART_SOUND_SNATCHER;
|
||||
extern const device_type MSX_CART_SOUND_SDSNATCHER;
|
||||
|
||||
|
||||
class msx_cart_konami : public device_t
|
||||
, public msx_cart_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_konami(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
private:
|
||||
UINT8 m_bank_mask;
|
||||
UINT8 m_selected_bank[3];
|
||||
UINT8 *m_bank_base[8];
|
||||
};
|
||||
|
||||
|
||||
class msx_cart_konami_scc : public device_t
|
||||
, public msx_cart_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_konami_scc(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
private:
|
||||
required_device<k051649_device> m_k051649;
|
||||
|
||||
UINT8 m_bank_mask;
|
||||
UINT8 m_selected_bank[4];
|
||||
UINT8 *m_bank_base[8];
|
||||
bool m_scc_active;
|
||||
};
|
||||
|
||||
|
||||
class msx_cart_gamemaster2 : public device_t
|
||||
, public msx_cart_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_gamemaster2(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
private:
|
||||
UINT8 m_selected_bank[3];
|
||||
UINT8 *m_bank_base[8];
|
||||
|
||||
void setup_bank(UINT8 bank);
|
||||
};
|
||||
|
||||
|
||||
class msx_cart_synthesizer : public device_t
|
||||
, public msx_cart_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_synthesizer(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||
|
||||
private:
|
||||
UINT8 *m_bank_base;
|
||||
required_device<dac_device> m_dac;
|
||||
};
|
||||
|
||||
|
||||
class msx_cart_konami_sound : public device_t
|
||||
, public msx_cart_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_konami_sound(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-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
protected:
|
||||
UINT8 *m_ram_bank[16];
|
||||
|
||||
private:
|
||||
// This is actually a K052539
|
||||
required_device<k051649_device> m_k052539;
|
||||
|
||||
UINT8 m_selected_bank[4];
|
||||
UINT8 *m_bank_base[8];
|
||||
bool m_scc_active;
|
||||
bool m_sccplus_active;
|
||||
bool m_ram_enabled[4];
|
||||
UINT8 m_scc_mode;
|
||||
|
||||
void setup_bank(UINT8 bank);
|
||||
};
|
||||
|
||||
|
||||
class msx_cart_konami_sound_snatcher : public msx_cart_konami_sound
|
||||
{
|
||||
public:
|
||||
msx_cart_konami_sound_snatcher(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
};
|
||||
|
||||
|
||||
class msx_cart_konami_sound_sdsnatcher : public msx_cart_konami_sound
|
||||
{
|
||||
public:
|
||||
msx_cart_konami_sound_sdsnatcher(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
297
src/emu/bus/msx_cart/korean.c
Normal file
297
src/emu/bus/msx_cart/korean.c
Normal file
@ -0,0 +1,297 @@
|
||||
#include "emu.h"
|
||||
#include "korean.h"
|
||||
|
||||
const device_type MSX_CART_KOREAN_80IN1 = &device_creator<msx_cart_korean_80in1>;
|
||||
const device_type MSX_CART_KOREAN_90IN1 = &device_creator<msx_cart_korean_90in1>;
|
||||
const device_type MSX_CART_KOREAN_126IN1 = &device_creator<msx_cart_korean_126in1>;
|
||||
|
||||
|
||||
msx_cart_korean_80in1::msx_cart_korean_80in1(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_CART_KOREAN_80IN1, "MSX Cartridge - Korean 80-in-1", tag, owner, clock, "msx_cart_korean_80in1", __FILE__)
|
||||
, msx_cart_interface(mconfig, *this)
|
||||
, m_bank_mask(0)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_selected_bank[i] = i;
|
||||
m_bank_base[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_korean_80in1::device_start()
|
||||
{
|
||||
save_item(NAME(m_selected_bank));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_cart_korean_80in1::restore_banks), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_korean_80in1::setup_bank(UINT8 bank)
|
||||
{
|
||||
m_bank_base[bank] = get_rom_base() + ( m_selected_bank[bank] & m_bank_mask ) * 0x2000;
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_korean_80in1::restore_banks()
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
setup_bank(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_korean_80in1::device_reset()
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_selected_bank[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_korean_80in1::initialize_cartridge()
|
||||
{
|
||||
UINT32 size = get_rom_size();
|
||||
|
||||
if ( size > 256 * 0x2000 )
|
||||
{
|
||||
fatalerror("korean_80in1: ROM is too big\n");
|
||||
}
|
||||
|
||||
UINT16 banks = size / 0x2000;
|
||||
|
||||
if (size != banks * 0x2000 || (~(banks - 1) % banks))
|
||||
{
|
||||
fatalerror("korean_80in1: Invalid ROM size\n");
|
||||
}
|
||||
|
||||
m_bank_mask = banks - 1;
|
||||
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_cart_korean_80in1::read_cart)
|
||||
{
|
||||
if (offset >= 0x4000 && offset < 0xc000)
|
||||
{
|
||||
return m_bank_base[(offset - 0x4000) >> 13][offset & 0x1fff];
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_cart_korean_80in1::write_cart)
|
||||
{
|
||||
if (offset >= 0x4000 && offset < 0x4004)
|
||||
{
|
||||
UINT8 bank = offset & 3;
|
||||
|
||||
m_selected_bank[bank] = data;
|
||||
setup_bank(bank);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
msx_cart_korean_90in1::msx_cart_korean_90in1(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_CART_KOREAN_90IN1, "MSX Cartridge - Korean 90-in-1", tag, owner, clock, "msx_cart_korean_90in1", __FILE__)
|
||||
, msx_cart_interface(mconfig, *this)
|
||||
, m_bank_mask(0)
|
||||
, m_selected_bank(0)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_bank_base[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_korean_90in1::device_start()
|
||||
{
|
||||
save_item(NAME(m_selected_bank));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_cart_korean_90in1::restore_banks), this));
|
||||
|
||||
// Install IO read/write handlers
|
||||
address_space &space = machine().device<cpu_device>("maincpu")->space(AS_IO);
|
||||
space.install_write_handler(0x77, 0x77, write8_delegate(FUNC(msx_cart_korean_90in1::banking), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_korean_90in1::restore_banks()
|
||||
{
|
||||
UINT8 *base = get_rom_base();
|
||||
|
||||
switch (m_selected_bank & 0xc0)
|
||||
{
|
||||
case 0x80:
|
||||
base += (m_selected_bank & 0x3e & m_bank_mask) * 0x4000;
|
||||
m_bank_base[0] = base;
|
||||
m_bank_base[1] = base + 0x2000;
|
||||
m_bank_base[2] = base + 0x4000;
|
||||
m_bank_base[3] = base + 0x6000;
|
||||
break;
|
||||
|
||||
case 0xc0:
|
||||
base += (m_selected_bank & m_bank_mask) * 0x4000;
|
||||
m_bank_base[0] = base;
|
||||
m_bank_base[1] = base + 0x2000;
|
||||
m_bank_base[2] = base + 0x2000;
|
||||
m_bank_base[3] = base;
|
||||
break;
|
||||
|
||||
default:
|
||||
base += (m_selected_bank & m_bank_mask) * 0x4000;
|
||||
m_bank_base[0] = base;
|
||||
m_bank_base[1] = base + 0x2000;
|
||||
m_bank_base[2] = base;
|
||||
m_bank_base[3] = base + 0x2000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_korean_90in1::device_reset()
|
||||
{
|
||||
m_selected_bank = 0;
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_korean_90in1::initialize_cartridge()
|
||||
{
|
||||
UINT32 size = get_rom_size();
|
||||
|
||||
if ( size > 64 * 0x4000 )
|
||||
{
|
||||
fatalerror("korean_90in1: ROM is too big\n");
|
||||
}
|
||||
|
||||
UINT16 banks = size / 0x4000;
|
||||
|
||||
if (size != banks * 0x4000 || (~(banks - 1) % banks))
|
||||
{
|
||||
fatalerror("korean_90in1: Invalid ROM size\n");
|
||||
}
|
||||
|
||||
m_bank_mask = banks - 1;
|
||||
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_cart_korean_90in1::read_cart)
|
||||
{
|
||||
if (offset >= 0x4000 && offset < 0xc000)
|
||||
{
|
||||
return m_bank_base[(offset - 0x4000) >> 13][offset & 0x1fff];
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_cart_korean_90in1::banking)
|
||||
{
|
||||
m_selected_bank = data;
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
msx_cart_korean_126in1::msx_cart_korean_126in1(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_CART_KOREAN_126IN1, "MSX Cartridge - Korean 126-in-1", tag, owner, clock, "msx_cart_korean_126in1", __FILE__)
|
||||
, msx_cart_interface(mconfig, *this)
|
||||
, m_bank_mask(0)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
m_selected_bank[i] = i;
|
||||
m_bank_base[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_korean_126in1::device_start()
|
||||
{
|
||||
save_item(NAME(m_selected_bank));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_cart_korean_126in1::restore_banks), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_korean_126in1::setup_bank(UINT8 bank)
|
||||
{
|
||||
m_bank_base[bank] = get_rom_base() + ( m_selected_bank[bank] & m_bank_mask ) * 0x4000;
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_korean_126in1::restore_banks()
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
setup_bank(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_korean_126in1::device_reset()
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
m_selected_bank[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_korean_126in1::initialize_cartridge()
|
||||
{
|
||||
UINT32 size = get_rom_size();
|
||||
|
||||
if ( size > 256 * 0x4000 )
|
||||
{
|
||||
fatalerror("korean_126in1: ROM is too big\n");
|
||||
}
|
||||
|
||||
UINT16 banks = size / 0x4000;
|
||||
|
||||
if (size != banks * 0x4000 || (~(banks - 1) % banks))
|
||||
{
|
||||
fatalerror("korean_126in1: Invalid ROM size\n");
|
||||
}
|
||||
|
||||
m_bank_mask = banks - 1;
|
||||
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_cart_korean_126in1::read_cart)
|
||||
{
|
||||
if (offset >= 0x4000 && offset < 0xc000)
|
||||
{
|
||||
return m_bank_base[offset >> 15][offset & 0x3fff];
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_cart_korean_126in1::write_cart)
|
||||
{
|
||||
if (offset >= 0x4000 && offset < 0x4002)
|
||||
{
|
||||
UINT8 bank = offset & 1;
|
||||
|
||||
m_selected_bank[bank] = data;
|
||||
setup_bank(bank);
|
||||
}
|
||||
}
|
||||
|
89
src/emu/bus/msx_cart/korean.h
Normal file
89
src/emu/bus/msx_cart/korean.h
Normal file
@ -0,0 +1,89 @@
|
||||
#ifndef __MSX_CART_KOREAN_H
|
||||
#define __MSX_CART_KOREAN_H
|
||||
|
||||
#include "bus/msx_cart/cartridge.h"
|
||||
|
||||
|
||||
extern const device_type MSX_CART_KOREAN_80IN1;
|
||||
extern const device_type MSX_CART_KOREAN_90IN1;
|
||||
extern const device_type MSX_CART_KOREAN_126IN1;
|
||||
|
||||
|
||||
class msx_cart_korean_80in1 : public device_t
|
||||
, public msx_cart_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_korean_80in1(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
private:
|
||||
UINT8 m_bank_mask;
|
||||
UINT8 m_selected_bank[4];
|
||||
UINT8 *m_bank_base[4];
|
||||
|
||||
void setup_bank(UINT8 bank);
|
||||
};
|
||||
|
||||
|
||||
class msx_cart_korean_90in1 : public device_t
|
||||
, public msx_cart_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_korean_90in1(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||
|
||||
DECLARE_WRITE8_MEMBER(banking);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
private:
|
||||
UINT8 m_bank_mask;
|
||||
UINT8 m_selected_bank;
|
||||
UINT8 *m_bank_base[4];
|
||||
};
|
||||
|
||||
|
||||
class msx_cart_korean_126in1 : public device_t
|
||||
, public msx_cart_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_korean_126in1(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
private:
|
||||
UINT8 m_bank_mask;
|
||||
UINT8 m_selected_bank[2];
|
||||
UINT8 *m_bank_base[2];
|
||||
|
||||
void setup_bank(UINT8 bank);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
114
src/emu/bus/msx_cart/majutsushi.c
Normal file
114
src/emu/bus/msx_cart/majutsushi.c
Normal file
@ -0,0 +1,114 @@
|
||||
#include "emu.h"
|
||||
#include "majutsushi.h"
|
||||
|
||||
const device_type MSX_CART_MAJUTSUSHI = &device_creator<msx_cart_majutsushi>;
|
||||
|
||||
|
||||
msx_cart_majutsushi::msx_cart_majutsushi(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_CART_MAJUTSUSHI, "MSX Cartridge - Majutsushi", tag, owner, clock, "msx_cart_majutsushi", __FILE__)
|
||||
, msx_cart_interface(mconfig, *this)
|
||||
, m_dac(*this, "dac")
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_selected_bank[i] = 0;
|
||||
}
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
m_bank_base[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( majutsushi )
|
||||
// This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'.
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_SOUND_ADD("dac", DAC, 0)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.10)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
machine_config_constructor msx_cart_majutsushi::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( majutsushi );
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_majutsushi::device_start()
|
||||
{
|
||||
save_item(NAME(m_selected_bank));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_cart_majutsushi::restore_banks), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_majutsushi::restore_banks()
|
||||
{
|
||||
m_bank_base[0] = get_rom_base() + ( m_selected_bank[0] & 0x0f ) * 0x2000;
|
||||
m_bank_base[1] = get_rom_base() + ( m_selected_bank[1] & 0x0f ) * 0x2000;
|
||||
m_bank_base[2] = get_rom_base() + ( m_selected_bank[0] & 0x0f ) * 0x2000;
|
||||
m_bank_base[3] = get_rom_base() + ( m_selected_bank[1] & 0x0f ) * 0x2000;
|
||||
m_bank_base[4] = get_rom_base() + ( m_selected_bank[2] & 0x0f ) * 0x2000;
|
||||
m_bank_base[5] = get_rom_base() + ( m_selected_bank[3] & 0x0f ) * 0x2000;
|
||||
m_bank_base[6] = get_rom_base() + ( m_selected_bank[2] & 0x0f ) * 0x2000;
|
||||
m_bank_base[7] = get_rom_base() + ( m_selected_bank[3] & 0x0f ) * 0x2000;
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_majutsushi::device_reset()
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_selected_bank[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_majutsushi::initialize_cartridge()
|
||||
{
|
||||
if ( get_rom_size() != 0x20000 )
|
||||
{
|
||||
fatalerror("majutsushi: Invalid ROM size\n");
|
||||
}
|
||||
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_cart_majutsushi::read_cart)
|
||||
{
|
||||
return m_bank_base[offset >> 13][offset & 0x1fff];
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_cart_majutsushi::write_cart)
|
||||
{
|
||||
switch (offset & 0xe000)
|
||||
{
|
||||
case 0x4000:
|
||||
if (offset & 0x1000)
|
||||
{
|
||||
m_dac->write_unsigned8(data);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x6000:
|
||||
m_selected_bank[1] = data & 0x0f;
|
||||
m_bank_base[1] = get_rom_base() + m_selected_bank[1] * 0x2000;
|
||||
m_bank_base[3] = get_rom_base() + m_selected_bank[1] * 0x2000;
|
||||
break;
|
||||
|
||||
case 0x8000:
|
||||
m_selected_bank[2] = data & 0x0f;
|
||||
m_bank_base[4] = get_rom_base() + m_selected_bank[2] * 0x2000;
|
||||
m_bank_base[6] = get_rom_base() + m_selected_bank[2] * 0x2000;
|
||||
break;
|
||||
|
||||
case 0xa000:
|
||||
m_selected_bank[3] = data & 0x0f;
|
||||
m_bank_base[5] = get_rom_base() + m_selected_bank[3] * 0x2000;
|
||||
m_bank_base[7] = get_rom_base() + m_selected_bank[3] * 0x2000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
37
src/emu/bus/msx_cart/majutsushi.h
Normal file
37
src/emu/bus/msx_cart/majutsushi.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef __MSX_CART_MAJUTSUSHI_H
|
||||
#define __MSX_CART_MAJUTSUSHI_H
|
||||
|
||||
#include "bus/msx_cart/cartridge.h"
|
||||
#include "sound/dac.h"
|
||||
|
||||
|
||||
extern const device_type MSX_CART_MAJUTSUSHI;
|
||||
|
||||
|
||||
class msx_cart_majutsushi : public device_t
|
||||
, public msx_cart_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_majutsushi(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
private:
|
||||
required_device<dac_device> m_dac;
|
||||
|
||||
UINT8 m_selected_bank[4];
|
||||
UINT8 *m_bank_base[8];
|
||||
};
|
||||
|
||||
|
||||
#endif
|
66
src/emu/bus/msx_cart/msxdos2.c
Normal file
66
src/emu/bus/msx_cart/msxdos2.c
Normal file
@ -0,0 +1,66 @@
|
||||
#include "emu.h"
|
||||
#include "msxdos2.h"
|
||||
|
||||
const device_type MSX_CART_MSXDOS2 = &device_creator<msx_cart_msxdos2>;
|
||||
|
||||
|
||||
msx_cart_msxdos2::msx_cart_msxdos2(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_CART_MSXDOS2, "MSX Cartridge - MSXDOS2", tag, owner, clock, "msx_cart_msxdos2", __FILE__)
|
||||
, msx_cart_interface(mconfig, *this)
|
||||
, m_selected_bank(0)
|
||||
, m_bank_base(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_msxdos2::device_start()
|
||||
{
|
||||
save_item(NAME(m_selected_bank));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_cart_msxdos2::restore_banks), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_msxdos2::restore_banks()
|
||||
{
|
||||
m_bank_base = get_rom_base() + ( m_selected_bank & 0x03 ) * 0x4000;
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_msxdos2::device_reset()
|
||||
{
|
||||
m_selected_bank = 0;
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_msxdos2::initialize_cartridge()
|
||||
{
|
||||
if (get_rom_size() != 0x10000)
|
||||
{
|
||||
fatalerror("msxdos2: Invalid ROM size\n");
|
||||
}
|
||||
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_cart_msxdos2::read_cart)
|
||||
{
|
||||
if (offset >= 0x4000 && offset < 0x8000)
|
||||
{
|
||||
return m_bank_base[offset & 0x3fff];
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_cart_msxdos2::write_cart)
|
||||
{
|
||||
if (offset == 0x6000)
|
||||
{
|
||||
m_selected_bank = data;
|
||||
restore_banks();
|
||||
}
|
||||
}
|
||||
|
33
src/emu/bus/msx_cart/msxdos2.h
Normal file
33
src/emu/bus/msx_cart/msxdos2.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef __MSX_CART_MSXDOS2_H
|
||||
#define __MSX_CART_MSXDOS2_H
|
||||
|
||||
#include "bus/msx_cart/cartridge.h"
|
||||
|
||||
|
||||
extern const device_type MSX_CART_MSXDOS2;
|
||||
|
||||
|
||||
class msx_cart_msxdos2 : public device_t
|
||||
, public msx_cart_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_msxdos2(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
private:
|
||||
UINT8 m_selected_bank;
|
||||
UINT8 *m_bank_base;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
49
src/emu/bus/msx_cart/nomapper.c
Normal file
49
src/emu/bus/msx_cart/nomapper.c
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "nomapper.h"
|
||||
|
||||
const device_type MSX_CART_NOMAPPER = &device_creator<msx_cart_nomapper>;
|
||||
|
||||
|
||||
msx_cart_nomapper::msx_cart_nomapper(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_CART_NOMAPPER, "MSX Cartridge - ROM", tag, owner, clock, "msx_cart_nomapper", __FILE__)
|
||||
, msx_cart_interface(mconfig, *this)
|
||||
, m_start_address(0)
|
||||
, m_end_address(0)
|
||||
{
|
||||
}
|
||||
|
||||
void msx_cart_nomapper::device_start()
|
||||
{
|
||||
}
|
||||
|
||||
void msx_cart_nomapper::initialize_cartridge()
|
||||
{
|
||||
UINT32 size = get_rom_size();
|
||||
|
||||
m_start_address = 0x4000;
|
||||
|
||||
if (size <= 0x4000)
|
||||
{
|
||||
// Check if this ROM should be in page 2
|
||||
|
||||
UINT8 *rom = get_rom_base();
|
||||
|
||||
if (rom[0] == 'A' && rom[1] == 'B' && (rom[3] & 0x80))
|
||||
{
|
||||
m_start_address = 0x8000;
|
||||
}
|
||||
}
|
||||
|
||||
m_end_address = MIN(m_start_address + size, 0x10000);
|
||||
}
|
||||
|
||||
READ8_MEMBER(msx_cart_nomapper::read_cart)
|
||||
{
|
||||
if ( offset >= m_start_address && offset < m_end_address )
|
||||
{
|
||||
return get_rom_base()[offset - m_start_address];
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
28
src/emu/bus/msx_cart/nomapper.h
Normal file
28
src/emu/bus/msx_cart/nomapper.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef __MSX_CART_NOMAPPER_H
|
||||
#define __MSX_CART_NOMAPPER_H
|
||||
|
||||
#include "bus/msx_cart/cartridge.h"
|
||||
|
||||
|
||||
extern const device_type MSX_CART_NOMAPPER;
|
||||
|
||||
|
||||
class msx_cart_nomapper : public device_t
|
||||
, public msx_cart_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_nomapper(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||
|
||||
private:
|
||||
UINT32 m_start_address;
|
||||
UINT32 m_end_address;
|
||||
};
|
||||
|
||||
#endif
|
77
src/emu/bus/msx_cart/rtype.c
Normal file
77
src/emu/bus/msx_cart/rtype.c
Normal file
@ -0,0 +1,77 @@
|
||||
#include "emu.h"
|
||||
#include "rtype.h"
|
||||
|
||||
const device_type MSX_CART_RTYPE = &device_creator<msx_cart_rtype>;
|
||||
|
||||
|
||||
msx_cart_rtype::msx_cart_rtype(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_CART_RTYPE, "MSX Cartridge - R-Type", tag, owner, clock, "msx_cart_rtype", __FILE__)
|
||||
, msx_cart_interface(mconfig, *this)
|
||||
, m_selected_bank(0)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
m_bank_base[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_rtype::device_start()
|
||||
{
|
||||
save_item(NAME(m_selected_bank));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_cart_rtype::restore_banks), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_rtype::restore_banks()
|
||||
{
|
||||
m_bank_base[0] = get_rom_base() + 15 * 0x4000;
|
||||
if (m_selected_bank & 0x10)
|
||||
{
|
||||
m_selected_bank &= 0x17;
|
||||
}
|
||||
m_bank_base[1] = get_rom_base() + m_selected_bank * 0x4000;
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_rtype::device_reset()
|
||||
{
|
||||
m_selected_bank = 15;
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_rtype::initialize_cartridge()
|
||||
{
|
||||
if ( get_rom_size() != 0x80000 && get_rom_size() != 0x60000 )
|
||||
{
|
||||
fatalerror("rtype: Invalid ROM size\n");
|
||||
}
|
||||
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_cart_rtype::read_cart)
|
||||
{
|
||||
if (offset >= 0x4000 && offset < 0xc000)
|
||||
{
|
||||
return m_bank_base[offset >> 15][offset & 0x3fff];
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_cart_rtype::write_cart)
|
||||
{
|
||||
if (offset >= 0x7000 && offset < 0x8000)
|
||||
{
|
||||
m_selected_bank = data & 0x1f;
|
||||
if (m_selected_bank & 0x10)
|
||||
{
|
||||
m_selected_bank &= 0x17;
|
||||
}
|
||||
m_bank_base[1] = get_rom_base() + m_selected_bank * 0x4000;
|
||||
}
|
||||
}
|
||||
|
33
src/emu/bus/msx_cart/rtype.h
Normal file
33
src/emu/bus/msx_cart/rtype.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef __MSX_CART_RTYPE_H
|
||||
#define __MSX_CART_RTYPE_H
|
||||
|
||||
#include "bus/msx_cart/cartridge.h"
|
||||
|
||||
|
||||
extern const device_type MSX_CART_RTYPE;
|
||||
|
||||
|
||||
class msx_cart_rtype : public device_t
|
||||
, public msx_cart_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_rtype(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
private:
|
||||
UINT8 m_selected_bank;
|
||||
UINT8 *m_bank_base[2];
|
||||
};
|
||||
|
||||
|
||||
#endif
|
61
src/emu/bus/msx_cart/superloderunner.c
Normal file
61
src/emu/bus/msx_cart/superloderunner.c
Normal file
@ -0,0 +1,61 @@
|
||||
#include "emu.h"
|
||||
#include "superloderunner.h"
|
||||
|
||||
const device_type MSX_CART_SUPERLODERUNNER = &device_creator<msx_cart_superloderunner>;
|
||||
|
||||
|
||||
msx_cart_superloderunner::msx_cart_superloderunner(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_CART_SUPERLODERUNNER, "MSX Cartridge - Super Lode Runner", tag, owner, clock, "msx_cart_superloderunner", __FILE__)
|
||||
, msx_cart_interface(mconfig, *this)
|
||||
, m_selected_bank(0)
|
||||
, m_bank_base(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_superloderunner::device_start()
|
||||
{
|
||||
save_item(NAME(m_selected_bank));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_cart_superloderunner::restore_banks), this));
|
||||
|
||||
// Install evil memory write handler
|
||||
address_space &space = machine().device<cpu_device>("maincpu")->space(AS_PROGRAM);
|
||||
space.install_write_handler(0x0000, 0x0000, write8_delegate(FUNC(msx_cart_superloderunner::banking), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_superloderunner::restore_banks()
|
||||
{
|
||||
m_bank_base = get_rom_base() + (m_selected_bank & 0x0f) * 0x4000;
|
||||
}
|
||||
|
||||
|
||||
void msx_cart_superloderunner::initialize_cartridge()
|
||||
{
|
||||
if (get_rom_size() != 0x20000)
|
||||
{
|
||||
fatalerror("crossblaim: Invalid ROM size\n");
|
||||
}
|
||||
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_cart_superloderunner::read_cart)
|
||||
{
|
||||
if (offset >= 0x8000 && offset < 0xc000)
|
||||
{
|
||||
return m_bank_base[offset & 0x3fff];
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_cart_superloderunner::banking)
|
||||
{
|
||||
m_selected_bank = data;
|
||||
restore_banks();
|
||||
}
|
||||
|
33
src/emu/bus/msx_cart/superloderunner.h
Normal file
33
src/emu/bus/msx_cart/superloderunner.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef __MSX_CART_SUPERLODERUNNER_H
|
||||
#define __MSX_CART_SUPERLODERUNNER_H
|
||||
|
||||
#include "bus/msx_cart/cartridge.h"
|
||||
|
||||
|
||||
extern const device_type MSX_CART_SUPERLODERUNNER;
|
||||
|
||||
|
||||
class msx_cart_superloderunner : public device_t
|
||||
, public msx_cart_interface
|
||||
{
|
||||
public:
|
||||
msx_cart_superloderunner(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
|
||||
virtual void initialize_cartridge();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||
|
||||
DECLARE_WRITE8_MEMBER(banking);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
private:
|
||||
UINT8 m_selected_bank;
|
||||
UINT8 *m_bank_base;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
77
src/emu/bus/msx_slot/bunsetsu.c
Normal file
77
src/emu/bus/msx_slot/bunsetsu.c
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
Emulation for the bunsetsu internal firmware mapper found in a number of MSX machines
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "bunsetsu.h"
|
||||
|
||||
|
||||
const device_type MSX_SLOT_BUNSETSU = &device_creator<msx_slot_bunsetsu_device>;
|
||||
|
||||
|
||||
msx_slot_bunsetsu_device::msx_slot_bunsetsu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: msx_slot_rom_device(mconfig, MSX_SLOT_BUNSETSU, "MSX Internal BUNSETSU", tag, owner, clock, "msx_slot_bunsetsu", __FILE__)
|
||||
, m_bunsetsu_region(NULL)
|
||||
, m_bunsetsu_region_tag(NULL)
|
||||
, m_bunsetsu_address(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_bunsetsu_device::device_start()
|
||||
{
|
||||
msx_slot_rom_device::device_start();
|
||||
|
||||
if (m_bunsetsu_region_tag == NULL)
|
||||
{
|
||||
fatalerror("msx_slot_bunsetsu_device: no bunsetsu region tag specified\n");
|
||||
}
|
||||
|
||||
m_bunsetsu_region = owner()->memregion(m_bunsetsu_region_tag);
|
||||
|
||||
if (m_bunsetsu_region == NULL)
|
||||
{
|
||||
fatalerror("msx_slot_bunsetsu_device: Unable to find region with tag '%s'\n", m_bunsetsu_region_tag);
|
||||
}
|
||||
|
||||
if (m_bunsetsu_region->bytes() != 0x20000)
|
||||
{
|
||||
fatalerror("msx_slot_bunsetsu_device: Bunsetsu region must be 0x20000 bytes.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_bunsetsu_device::device_reset()
|
||||
{
|
||||
m_bunsetsu_address = 0;
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_slot_bunsetsu_device::read)
|
||||
{
|
||||
if (offset == 0xbfff)
|
||||
{
|
||||
return m_bunsetsu_region->u8(m_bunsetsu_address++ & 0x1ffff);
|
||||
}
|
||||
return msx_slot_rom_device::read(space, offset);
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_slot_bunsetsu_device::write)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0xbffc:
|
||||
m_bunsetsu_address = (m_bunsetsu_address & 0xffff00) | data;
|
||||
break;
|
||||
|
||||
case 0xbffd:
|
||||
m_bunsetsu_address = (m_bunsetsu_address & 0xff00ff) | (data << 8);
|
||||
break;
|
||||
|
||||
case 0xbffe:
|
||||
m_bunsetsu_address = (m_bunsetsu_address & 0x00ffff) | (data << 16);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
38
src/emu/bus/msx_slot/bunsetsu.h
Normal file
38
src/emu/bus/msx_slot/bunsetsu.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef __MSX_SLOT_BUNSETSU_H
|
||||
#define __MSX_SLOT_BUNSETSU_H
|
||||
|
||||
#include "bus/msx_slot/slot.h"
|
||||
#include "bus/msx_slot/rom.h"
|
||||
|
||||
|
||||
extern const device_type MSX_SLOT_BUNSETSU;
|
||||
|
||||
|
||||
#define MCFG_MSX_SLOT_BUNSETSU_ADD(_tag, _startpage, _numpages, _region, _offset, _bunsetsu_region_tag) \
|
||||
MCFG_MSX_INTERNAL_SLOT_ADD(_tag, MSX_SLOT_BUNSETSU, _startpage, _numpages) \
|
||||
msx_slot_rom_device::set_rom_start(*device, _region, _offset); \
|
||||
msx_slot_bunsetsu_device::set_bunsetsu_region_tag(*device, _bunsetsu_region_tag); \
|
||||
|
||||
class msx_slot_bunsetsu_device : public msx_slot_rom_device
|
||||
{
|
||||
public:
|
||||
msx_slot_bunsetsu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// static configuration helpers
|
||||
static void set_bunsetsu_region_tag(device_t &device, const char *tag) { dynamic_cast<msx_slot_bunsetsu_device &>(device).m_bunsetsu_region_tag = tag; }
|
||||
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read);
|
||||
virtual DECLARE_WRITE8_MEMBER(write);
|
||||
|
||||
private:
|
||||
memory_region *m_bunsetsu_region;
|
||||
const char *m_bunsetsu_region_tag;
|
||||
UINT32 m_bunsetsu_address;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
317
src/emu/bus/msx_slot/cartridge.c
Normal file
317
src/emu/bus/msx_slot/cartridge.c
Normal file
@ -0,0 +1,317 @@
|
||||
#include "emu.h"
|
||||
#include "bus/msx_slot/cartridge.h"
|
||||
#include "hashfile.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
NOMAPPER = 0,
|
||||
ASCII8,
|
||||
ASCII8_SRAM,
|
||||
ASCII16,
|
||||
ASCII16_SRAM,
|
||||
CROSSBLAIM,
|
||||
GAMEMASTER2,
|
||||
KOREAN_80IN1,
|
||||
KOREAN_90IN1,
|
||||
KOREAN_126IN1,
|
||||
FMPAC,
|
||||
RTYPE,
|
||||
KONAMI,
|
||||
KONAMI_SCC,
|
||||
SUPERLODERUNNER,
|
||||
MAJUTSUSHI,
|
||||
DISK_ROM,
|
||||
SYNTHESIZER,
|
||||
MSXDOS2
|
||||
};
|
||||
|
||||
|
||||
const device_type MSX_SLOT_CARTRIDGE = &device_creator<msx_slot_cartridge_device>;
|
||||
|
||||
|
||||
msx_slot_cartridge_device::msx_slot_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_SLOT_CARTRIDGE, "MSX Cartridge slot", tag, owner, clock, "msx_slot_cartridge", __FILE__)
|
||||
, device_image_interface(mconfig, *this)
|
||||
, device_slot_interface(mconfig, *this)
|
||||
, msx_internal_slot_interface()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static const struct
|
||||
{
|
||||
int pcb_id;
|
||||
const char *slot_option;
|
||||
} slot_list[] =
|
||||
{
|
||||
{ NOMAPPER, "nomapper" },
|
||||
{ ASCII8, "ascii8" },
|
||||
{ ASCII8_SRAM, "ascii8_sram" },
|
||||
{ ASCII16, "ascii16" },
|
||||
{ ASCII16_SRAM, "ascii16_sram" },
|
||||
{ CROSSBLAIM, "cross_blaim" },
|
||||
{ GAMEMASTER2, "gamemaster2" },
|
||||
{ KOREAN_80IN1, "korean_80in1" },
|
||||
{ KOREAN_90IN1, "korean_90in1" },
|
||||
{ KOREAN_126IN1, "korean_126in1" },
|
||||
{ FMPAC, "fmpac" },
|
||||
{ RTYPE, "rtype" },
|
||||
{ KONAMI, "konami" },
|
||||
{ KONAMI_SCC, "konami_scc" },
|
||||
{ SUPERLODERUNNER, "superloderunner" },
|
||||
{ MAJUTSUSHI, "majutsushi" },
|
||||
{ DISK_ROM, "disk_rom" },
|
||||
{ SYNTHESIZER, "synthesizer" },
|
||||
{ MSXDOS2, "msxdos2" }
|
||||
};
|
||||
|
||||
|
||||
static const char *msx_cart_get_slot_option(int type)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_LENGTH(slot_list); i++)
|
||||
{
|
||||
if (slot_list[i].pcb_id == type)
|
||||
return slot_list[i].slot_option;
|
||||
}
|
||||
|
||||
return slot_list[0].slot_option;
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_cartridge_device::device_start()
|
||||
{
|
||||
m_cartridge = dynamic_cast<msx_cart_interface *>(get_card_device());
|
||||
}
|
||||
|
||||
|
||||
bool msx_slot_cartridge_device::call_load()
|
||||
{
|
||||
if ( m_cartridge )
|
||||
{
|
||||
if ( software_entry() )
|
||||
{
|
||||
// Allocate and copy rom contents
|
||||
UINT32 length = get_software_region_length("rom");
|
||||
|
||||
m_cartridge->rom_alloc( length );
|
||||
UINT8 *rom_base = m_cartridge->get_rom_base();
|
||||
memcpy(rom_base, get_software_region("rom"), length);
|
||||
|
||||
// Allocate ram
|
||||
length = get_software_region_length("ram");
|
||||
m_cartridge->ram_alloc( length );
|
||||
|
||||
// Allocate sram
|
||||
length = get_software_region_length("sram");
|
||||
m_cartridge->sram_alloc( length );
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT32 length = this->length();
|
||||
|
||||
UINT32 length_aligned = 0x4000;
|
||||
while (length_aligned < length )
|
||||
{
|
||||
length_aligned *= 2;
|
||||
}
|
||||
|
||||
m_cartridge->rom_alloc(length_aligned);
|
||||
m_cartridge->ram_alloc(0);
|
||||
m_cartridge->sram_alloc(0);
|
||||
|
||||
if (fread(m_cartridge->get_rom_base(), length) != length)
|
||||
{
|
||||
seterror(IMAGE_ERROR_UNSPECIFIED, "Unable to fully read file");
|
||||
return IMAGE_INIT_FAIL;
|
||||
}
|
||||
|
||||
// Check if there's some mapper related
|
||||
astring extrainfo;
|
||||
if (hashfile_extrainfo(*this, extrainfo))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
m_cartridge->initialize_cartridge();
|
||||
|
||||
if (m_cartridge->get_sram_size() > 0)
|
||||
{
|
||||
battery_load(m_cartridge->get_sram_base(), m_cartridge->get_sram_size(), 0x00);
|
||||
}
|
||||
}
|
||||
return IMAGE_INIT_PASS;
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_cartridge_device::call_unload()
|
||||
{
|
||||
if (m_cartridge)
|
||||
{
|
||||
if (m_cartridge->get_sram_size() > 0)
|
||||
{
|
||||
battery_save(m_cartridge->get_sram_base(), m_cartridge->get_sram_size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool msx_slot_cartridge_device::call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry)
|
||||
{
|
||||
load_software_part_region(*this, swlist, swname, start_entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int msx_slot_cartridge_device::get_cart_type(UINT8 *rom, UINT32 length)
|
||||
{
|
||||
if (length < 0x2000)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (length < 0x10000)
|
||||
{
|
||||
return NOMAPPER;
|
||||
}
|
||||
|
||||
if ( (rom[0x10] == 'Y') && (rom[0x11] == 'Z') && (length > 0x18000) )
|
||||
{
|
||||
return GAMEMASTER2;
|
||||
}
|
||||
|
||||
int kon4 = 0, kon5 = 0, asc8 = 0, asc16 = 0;
|
||||
|
||||
for (int i=0; i < length-3; i++)
|
||||
{
|
||||
if (rom[i] == 0x32 && rom[i+1] == 0)
|
||||
{
|
||||
switch (rom[i+2])
|
||||
{
|
||||
case 0x60:
|
||||
case 0x70:
|
||||
asc16++;
|
||||
asc8++;
|
||||
break;
|
||||
|
||||
case 0x68:
|
||||
case 0x78:
|
||||
asc8++;
|
||||
asc16--;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (rom[i+2])
|
||||
{
|
||||
case 0x60:
|
||||
case 0x80:
|
||||
case 0xa0:
|
||||
kon4++;
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
case 0x70:
|
||||
case 0x90:
|
||||
case 0xb0:
|
||||
kon5++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (MAX (kon4, kon5) > MAX (asc8, asc16) )
|
||||
{
|
||||
return (kon5 > kon4) ? KONAMI_SCC : KONAMI;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (asc8 > asc16) ? ASCII8 : ASCII16;
|
||||
}
|
||||
|
||||
return NOMAPPER;
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_cartridge_device::get_default_card_software(astring &result)
|
||||
{
|
||||
if (open_image_file(mconfig().options()))
|
||||
{
|
||||
const char *slot_string = "nomapper";
|
||||
UINT32 length = core_fsize(m_file);
|
||||
dynamic_buffer rom(length);
|
||||
int type = NOMAPPER;
|
||||
|
||||
// Check if there's some mapper related information in the hashfiles
|
||||
astring extrainfo;
|
||||
if (hashfile_extrainfo(*this, extrainfo))
|
||||
{
|
||||
int extrainfo_type = -1;
|
||||
if (1 == sscanf(extrainfo.cstr(), "%d", &extrainfo_type))
|
||||
{
|
||||
static const struct { int extrainfo; int mapper; } extrainfo_map[] = {
|
||||
//{ 0, NOMAPPER },
|
||||
{ 1, MSXDOS2 },
|
||||
{ 2, KONAMI_SCC },
|
||||
{ 3, KONAMI },
|
||||
{ 4, ASCII8 },
|
||||
{ 5, ASCII16 },
|
||||
{ 6, GAMEMASTER2 },
|
||||
{ 7, ASCII8_SRAM },
|
||||
{ 8, ASCII16_SRAM },
|
||||
{ 9, RTYPE },
|
||||
{ 10, MAJUTSUSHI },
|
||||
{ 11, FMPAC },
|
||||
{ 12, SUPERLODERUNNER },
|
||||
{ 13, SYNTHESIZER },
|
||||
{ 14, CROSSBLAIM },
|
||||
{ 15, DISK_ROM },
|
||||
{ 16, KOREAN_80IN1 },
|
||||
{ 17, KOREAN_126IN1 }
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAY_LENGTH(extrainfo_map); i++)
|
||||
{
|
||||
if (extrainfo_map[i].extrainfo == extrainfo_type)
|
||||
{
|
||||
type = extrainfo_map[i].mapper;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type == NOMAPPER)
|
||||
{
|
||||
// Not identified through hashfile, try automatic detection
|
||||
type = get_cart_type(rom, length);
|
||||
}
|
||||
|
||||
if (type > NOMAPPER)
|
||||
{
|
||||
slot_string = msx_cart_get_slot_option(type);
|
||||
}
|
||||
|
||||
result.cpy(slot_string);
|
||||
return;
|
||||
}
|
||||
software_get_default_slot(result, "nomapper");
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_slot_cartridge_device::read)
|
||||
{
|
||||
if ( m_cartridge )
|
||||
{
|
||||
return m_cartridge->read_cart(space, offset);
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_slot_cartridge_device::write)
|
||||
{
|
||||
if ( m_cartridge )
|
||||
{
|
||||
m_cartridge->write_cart(space, offset, data);
|
||||
}
|
||||
}
|
||||
|
57
src/emu/bus/msx_slot/cartridge.h
Normal file
57
src/emu/bus/msx_slot/cartridge.h
Normal file
@ -0,0 +1,57 @@
|
||||
#ifndef __MSX_SLOT_CARTRIDGE_H
|
||||
#define __MSX_SLOT_CARTRIDGE_H
|
||||
|
||||
#include "slot.h"
|
||||
#include "bus/msx_cart/cartridge.h"
|
||||
|
||||
|
||||
extern const device_type MSX_SLOT_CARTRIDGE;
|
||||
|
||||
|
||||
#define MCFG_MSX_SLOT_CARTRIDGE_ADD(_tag) \
|
||||
MCFG_DEVICE_ADD(_tag, MSX_SLOT_CARTRIDGE, 0) \
|
||||
MCFG_DEVICE_SLOT_INTERFACE(msx_cart, NULL, false)
|
||||
|
||||
|
||||
class msx_slot_cartridge_device : public device_t
|
||||
, public device_image_interface
|
||||
, public device_slot_interface
|
||||
, public msx_internal_slot_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
msx_slot_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_config_complete() { update_names(MSX_SLOT_CARTRIDGE, "cartridge", "cart"); }
|
||||
|
||||
// image-level overrides
|
||||
virtual bool call_load();
|
||||
virtual void call_unload();
|
||||
virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry);
|
||||
virtual iodevice_t image_type() const { return IO_CARTSLOT; }
|
||||
virtual bool is_readable() const { return true; }
|
||||
virtual bool is_writeable() const { return false; }
|
||||
virtual bool is_creatable() const { return false; }
|
||||
virtual bool must_be_loaded() const { return false; }
|
||||
virtual bool is_reset_on_load() const { return true; }
|
||||
virtual const option_guide *create_option_guide() const { return NULL; }
|
||||
virtual const char *image_interface() const { return "msx_cart"; }
|
||||
virtual const char *file_extensions() const { return "mx1,bin,rom"; }
|
||||
|
||||
// slot interface overrides
|
||||
virtual void get_default_card_software(astring &result);
|
||||
|
||||
// msx_internal_slot-level overrides
|
||||
virtual DECLARE_READ8_MEMBER(read);
|
||||
virtual DECLARE_WRITE8_MEMBER(write);
|
||||
|
||||
private:
|
||||
msx_cart_interface *m_cartridge;
|
||||
|
||||
int get_cart_type(UINT8 *rom, UINT32 length);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
369
src/emu/bus/msx_slot/disk.c
Normal file
369
src/emu/bus/msx_slot/disk.c
Normal file
@ -0,0 +1,369 @@
|
||||
/*
|
||||
From: erbo@xs4all.nl (erik de boer)
|
||||
|
||||
sony and philips have used (almost) the same design
|
||||
and this is the memory layout
|
||||
but it is not a msx standard !
|
||||
|
||||
WD1793 or wd2793 registers
|
||||
|
||||
address
|
||||
|
||||
7FF8H read status register
|
||||
write command register
|
||||
7FF9H r/w track register (r/o on NMS 8245 and Sony)
|
||||
7FFAH r/w sector register (r/o on NMS 8245 and Sony)
|
||||
7FFBH r/w data register
|
||||
|
||||
|
||||
hardware registers
|
||||
|
||||
address
|
||||
|
||||
7FFCH r/w bit 0 side select
|
||||
7FFDH r/w b7>M-on , b6>in-use , b1>ds1 , b0>ds0 (all neg. logic)
|
||||
7FFEH not used
|
||||
7FFFH read b7>drq , b6>intrq
|
||||
|
||||
set on 7FFDH bit 2 always to 0 (some use it as disk change reset)
|
||||
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "disk.h"
|
||||
|
||||
|
||||
const device_type MSX_SLOT_DISK1 = &device_creator<msx_slot_disk1_device>;
|
||||
const device_type MSX_SLOT_DISK2 = &device_creator<msx_slot_disk2_device>;
|
||||
|
||||
|
||||
msx_slot_disk_device::msx_slot_disk_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)
|
||||
: msx_slot_rom_device(mconfig, type, name, tag, owner, clock, shortname, source)
|
||||
, m_fdc(NULL)
|
||||
, m_floppy0(NULL)
|
||||
, m_floppy1(NULL)
|
||||
, m_floppy(NULL)
|
||||
, m_fdc_tag(NULL)
|
||||
, m_floppy0_tag(NULL)
|
||||
, m_floppy1_tag(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_disk_device::device_start()
|
||||
{
|
||||
msx_slot_rom_device::device_start();
|
||||
|
||||
if (m_fdc_tag == NULL)
|
||||
{
|
||||
fatalerror("msx_slot_disk_device: no FDC tag specified\n");
|
||||
}
|
||||
|
||||
m_fdc = owner()->subdevice<wd_fdc_analog_t>(m_fdc_tag);
|
||||
m_floppy0 = owner()->subdevice<floppy_connector>(m_floppy0_tag);
|
||||
m_floppy1 = owner()->subdevice<floppy_connector>(m_floppy1_tag);
|
||||
|
||||
if (m_fdc == NULL)
|
||||
{
|
||||
fatalerror("msx_slot_disk_device: Unable to find FDC with tag '%s'\n", m_fdc_tag);
|
||||
}
|
||||
|
||||
if (m_floppy0 == NULL && m_floppy1 == NULL)
|
||||
{
|
||||
logerror("msx_slot_disk_device: Warning: both floppy0 and floppy1 were not found\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
msx_slot_disk1_device::msx_slot_disk1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: msx_slot_disk_device(mconfig, MSX_SLOT_DISK1, "MSX Internal floppy type 1", tag, owner, clock, "msx_slot_disk1", __FILE__)
|
||||
, m_side_control(0)
|
||||
, m_control(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_disk1_device::device_start()
|
||||
{
|
||||
msx_slot_disk_device::device_start();
|
||||
|
||||
save_item(NAME(m_side_control));
|
||||
save_item(NAME(m_control));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_slot_disk1_device::post_load), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_disk1_device::device_reset()
|
||||
{
|
||||
m_fdc->dden_w(false);
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_disk1_device::post_load()
|
||||
{
|
||||
UINT8 data = m_control;
|
||||
|
||||
// To make sure the FDD busy led status gets set correctly
|
||||
m_control ^= 0x40;
|
||||
|
||||
set_control(data);
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_disk1_device::set_side_control(UINT8 data)
|
||||
{
|
||||
m_side_control = data;
|
||||
|
||||
if (m_floppy)
|
||||
{
|
||||
m_floppy->ss_w(m_side_control & 0x01);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_disk1_device::set_control(UINT8 data)
|
||||
{
|
||||
UINT8 old_m_control = m_control;
|
||||
|
||||
m_control = data;
|
||||
|
||||
switch (m_control & 0x03)
|
||||
{
|
||||
case 0:
|
||||
case 2:
|
||||
m_floppy = m_floppy0 ? m_floppy0->get_device() : NULL;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
m_floppy = m_floppy1 ? m_floppy1->get_device() : NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
m_floppy = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_floppy)
|
||||
{
|
||||
m_floppy->mon_w((m_control & 0x80) ? 0 : 1);
|
||||
m_floppy->ss_w(m_side_control & 0x01);
|
||||
}
|
||||
|
||||
m_fdc->set_floppy(m_floppy);
|
||||
|
||||
if ((old_m_control ^ m_control) & 0x40)
|
||||
{
|
||||
set_led_status(machine(), 0, !(m_control & 0x40));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_slot_disk1_device::read)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x7ff8:
|
||||
case 0xbff8:
|
||||
return m_fdc->status_r();
|
||||
|
||||
case 0x7ff9:
|
||||
case 0xbff9:
|
||||
return m_fdc->track_r();
|
||||
|
||||
case 0x7ffa:
|
||||
case 0xbffa:
|
||||
return m_fdc->sector_r();
|
||||
|
||||
case 0x7ffb:
|
||||
case 0xbffb:
|
||||
return m_fdc->data_r();
|
||||
|
||||
case 0x7ffc:
|
||||
case 0xbffc:
|
||||
return 0xfe | (m_side_control & 0x01);
|
||||
|
||||
case 0x7ffd:
|
||||
case 0xbffd:
|
||||
return ( m_control & 0x83 ) | 0x78;
|
||||
|
||||
case 0x7fff:
|
||||
case 0xbfff:
|
||||
return 0x3f | (m_fdc->intrq_r() ? 0 : 0x40) | (m_fdc->drq_r() ? 0 : 0x80);
|
||||
}
|
||||
|
||||
return msx_slot_rom_device::read(space, offset);
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_slot_disk1_device::write)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x7ff8:
|
||||
case 0xbff8:
|
||||
m_fdc->cmd_w(data);
|
||||
break;
|
||||
|
||||
case 0x7ff9:
|
||||
case 0xbff9:
|
||||
m_fdc->track_w(data);
|
||||
break;
|
||||
|
||||
case 0x7ffa:
|
||||
case 0xbffa:
|
||||
m_fdc->sector_w(data);
|
||||
break;
|
||||
|
||||
case 0x7ffb:
|
||||
case 0xbffb:
|
||||
m_fdc->data_w(data);
|
||||
break;
|
||||
|
||||
case 0x7ffc:
|
||||
case 0xbffc:
|
||||
set_side_control(data);
|
||||
break;
|
||||
|
||||
case 0x7ffd:
|
||||
case 0xbffd:
|
||||
set_control(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
msx_slot_disk2_device::msx_slot_disk2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: msx_slot_disk_device(mconfig, MSX_SLOT_DISK2, "MSX Internal floppy type 2", tag, owner, clock, "msx_slot_disk2", __FILE__)
|
||||
, m_control(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_disk2_device::device_start()
|
||||
{
|
||||
msx_slot_disk_device::device_start();
|
||||
|
||||
save_item(NAME(m_control));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_slot_disk2_device::post_load), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_disk2_device::device_reset()
|
||||
{
|
||||
m_fdc->dden_w(false);
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_disk2_device::post_load()
|
||||
{
|
||||
UINT8 data = m_control;
|
||||
|
||||
// To make sure the FDD busy led status gets set correctly
|
||||
m_control ^= 0x40;
|
||||
|
||||
set_control(data);
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_disk2_device::set_control(UINT8 data)
|
||||
{
|
||||
UINT8 old_m_control = m_control;
|
||||
|
||||
m_control = data;
|
||||
|
||||
switch (m_control & 3)
|
||||
{
|
||||
case 1:
|
||||
m_floppy = m_floppy0 ? m_floppy0->get_device() : NULL;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_floppy = m_floppy1 ? m_floppy1->get_device() : NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
m_floppy = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_floppy)
|
||||
{
|
||||
m_floppy->mon_w((m_control & 0x08) ? 0 : 1);
|
||||
m_floppy->ss_w((m_control & 0x04) ? 0 : 1);
|
||||
}
|
||||
|
||||
m_fdc->set_floppy(m_floppy);
|
||||
|
||||
if ((old_m_control ^ m_control) & 0x40)
|
||||
{
|
||||
set_led_status(machine(), 0, !(m_control & 0x40));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_slot_disk2_device::read)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x7fb8:
|
||||
case 0xbfb8:
|
||||
return m_fdc->status_r();
|
||||
|
||||
case 0x7fb9:
|
||||
case 0xbfb9:
|
||||
return m_fdc->track_r();
|
||||
|
||||
case 0x7fba:
|
||||
case 0xbfba:
|
||||
return m_fdc->sector_r();
|
||||
|
||||
case 0x7fbb:
|
||||
case 0xbfbb:
|
||||
return m_fdc->data_r();
|
||||
|
||||
case 0x7fbc:
|
||||
case 0xbfbc:
|
||||
return 0x3f | (m_fdc->drq_r() ? 0 : 0x40) | (m_fdc->intrq_r() ? 0x80 : 0);
|
||||
}
|
||||
|
||||
return msx_slot_rom_device::read(space, offset);
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_slot_disk2_device::write)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x7fb8:
|
||||
case 0xbfb8:
|
||||
m_fdc->cmd_w(data);
|
||||
break;
|
||||
|
||||
case 0x7fb9:
|
||||
case 0xbfb9:
|
||||
m_fdc->track_w(data);
|
||||
break;
|
||||
|
||||
case 0x7fba:
|
||||
case 0xbfba:
|
||||
m_fdc->sector_w(data);
|
||||
break;
|
||||
|
||||
case 0x7fbb:
|
||||
case 0xbfbb:
|
||||
m_fdc->data_w(data);
|
||||
break;
|
||||
|
||||
case 0x7fbc:
|
||||
case 0xbfbc:
|
||||
set_control(data);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unmapped write writing %02x to %04x\n", data, offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
97
src/emu/bus/msx_slot/disk.h
Normal file
97
src/emu/bus/msx_slot/disk.h
Normal file
@ -0,0 +1,97 @@
|
||||
#ifndef __MSX_SLOT_DISK_H
|
||||
#define __MSX_SLOT_DISK_H
|
||||
|
||||
#include "bus/msx_slot/slot.h"
|
||||
#include "bus/msx_slot/rom.h"
|
||||
#include "machine/wd_fdc.h"
|
||||
#include "imagedev/flopdrv.h"
|
||||
#include "imagedev/floppy.h"
|
||||
|
||||
|
||||
extern const device_type MSX_SLOT_DISK1;
|
||||
extern const device_type MSX_SLOT_DISK2;
|
||||
|
||||
|
||||
#define MCFG_MSX_SLOT_DISK1_ADD(_tag, _startpage, _numpages, _region, _offset, _fdc_tag, _floppy0_tag, _floppy1_tag) \
|
||||
MCFG_MSX_INTERNAL_SLOT_ADD(_tag, MSX_SLOT_DISK1, _startpage, _numpages) \
|
||||
msx_slot_rom_device::set_rom_start(*device, _region, _offset); \
|
||||
msx_slot_disk_device::set_fdc_tag(*device, _fdc_tag); \
|
||||
msx_slot_disk_device::set_floppy0_tag(*device, _floppy0_tag); \
|
||||
msx_slot_disk_device::set_floppy1_tag(*device, _floppy1_tag);
|
||||
|
||||
#define MCFG_MSX_SLOT_DISK2_ADD(_tag, _startpage, _numpages, _region, _offset, _fdc_tag, _floppy0_tag, _floppy1_tag) \
|
||||
MCFG_MSX_INTERNAL_SLOT_ADD(_tag, MSX_SLOT_DISK2, _startpage, _numpages) \
|
||||
msx_slot_rom_device::set_rom_start(*device, _region, _offset); \
|
||||
msx_slot_disk_device::set_fdc_tag(*device, _fdc_tag); \
|
||||
msx_slot_disk_device::set_floppy0_tag(*device, _floppy0_tag); \
|
||||
msx_slot_disk_device::set_floppy1_tag(*device, _floppy1_tag);
|
||||
|
||||
|
||||
class msx_slot_disk_device : public msx_slot_rom_device
|
||||
{
|
||||
public:
|
||||
msx_slot_disk_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);
|
||||
|
||||
virtual void device_start();
|
||||
|
||||
// static configuration helpers
|
||||
static void set_fdc_tag(device_t &device, const char *tag) { dynamic_cast<msx_slot_disk_device &>(device).m_fdc_tag = tag; }
|
||||
static void set_floppy0_tag(device_t &device, const char *tag) { dynamic_cast<msx_slot_disk_device &>(device).m_floppy0_tag = tag; }
|
||||
static void set_floppy1_tag(device_t &device, const char *tag) { dynamic_cast<msx_slot_disk_device &>(device).m_floppy1_tag = tag; }
|
||||
|
||||
protected:
|
||||
wd_fdc_analog_t *m_fdc;
|
||||
floppy_connector *m_floppy0;
|
||||
floppy_connector *m_floppy1;
|
||||
floppy_image_device *m_floppy;
|
||||
|
||||
private:
|
||||
const char *m_fdc_tag;
|
||||
const char *m_floppy0_tag;
|
||||
const char *m_floppy1_tag;
|
||||
};
|
||||
|
||||
|
||||
class msx_slot_disk1_device : public msx_slot_disk_device
|
||||
{
|
||||
public:
|
||||
msx_slot_disk1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read);
|
||||
virtual DECLARE_WRITE8_MEMBER(write);
|
||||
|
||||
void post_load();
|
||||
|
||||
private:
|
||||
UINT8 m_side_control;
|
||||
UINT8 m_control;
|
||||
|
||||
void set_control(UINT8 data);
|
||||
void set_side_control(UINT8 data);
|
||||
};
|
||||
|
||||
|
||||
class msx_slot_disk2_device : public msx_slot_disk_device
|
||||
{
|
||||
public:
|
||||
msx_slot_disk2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read);
|
||||
virtual DECLARE_WRITE8_MEMBER(write);
|
||||
|
||||
void post_load();
|
||||
|
||||
private:
|
||||
UINT8 m_control;
|
||||
|
||||
void set_control(UINT8 data);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
162
src/emu/bus/msx_slot/fs4600.c
Normal file
162
src/emu/bus/msx_slot/fs4600.c
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
Emulation for the internal firmware mapper in the National FS-4600.
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "fs4600.h"
|
||||
|
||||
|
||||
const device_type MSX_SLOT_FS4600 = &device_creator<msx_slot_fs4600_device>;
|
||||
|
||||
|
||||
msx_slot_fs4600_device::msx_slot_fs4600_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_SLOT_FS4600, "MSX Internal FS4600 Firmware", tag, owner, clock, "msx_slot_fs4600", __FILE__)
|
||||
, msx_internal_slot_interface()
|
||||
, m_nvram(*this, "nvram")
|
||||
, m_region(NULL)
|
||||
, m_region_offset(0)
|
||||
, m_rom(NULL)
|
||||
, m_sram_address(0)
|
||||
, m_control(0)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_selected_bank[i] = 0;
|
||||
m_bank_base[i] = 0;
|
||||
}
|
||||
memset(m_sram, 0, sizeof(m_sram));
|
||||
}
|
||||
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( fs4600 )
|
||||
MCFG_NVRAM_ADD_0FILL("nvram")
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
machine_config_constructor msx_slot_fs4600_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( fs4600 );
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_fs4600_device::set_rom_start(device_t &device, const char *region, UINT32 offset)
|
||||
{
|
||||
msx_slot_fs4600_device &dev = downcast<msx_slot_fs4600_device &>(device);
|
||||
|
||||
dev.m_region = region;
|
||||
dev.m_region_offset = offset;
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_fs4600_device::device_start()
|
||||
{
|
||||
assert(m_region != NULL );
|
||||
|
||||
memory_region *m_rom_region = owner()->memregion(m_region);
|
||||
|
||||
// Sanity checks
|
||||
if (m_rom_region == NULL )
|
||||
{
|
||||
fatalerror("Rom slot '%s': Unable to find memory region '%s'\n", tag(), m_region);
|
||||
}
|
||||
if (m_rom_region->bytes() < m_region_offset + 0x100000)
|
||||
{
|
||||
fatalerror("Memory region '%s' is too small for the FS4600 firmware\n", m_region);
|
||||
}
|
||||
|
||||
m_rom = m_rom_region->base() + m_region_offset;
|
||||
m_nvram->set_base(m_sram, 0x1000);
|
||||
|
||||
save_item(NAME(m_selected_bank));
|
||||
save_item(NAME(m_sram_address));
|
||||
save_item(NAME(m_control));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_slot_fs4600_device::restore_banks), this));
|
||||
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_fs4600_device::restore_banks()
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_bank_base[i] = m_rom + ( ( m_selected_bank[i] * 0x4000 ) & 0x0fffff );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_slot_fs4600_device::read)
|
||||
{
|
||||
if ((m_control & 0x02) && ((offset & 0x3fff) == 0x3ffd))
|
||||
{
|
||||
return m_sram[m_sram_address++ & 0xfff];
|
||||
}
|
||||
if ((m_control & 0x04) && (offset& 0x7ff8) == 0x7ff0)
|
||||
{
|
||||
return m_selected_bank[(offset >> 1) & 0x03];
|
||||
}
|
||||
return m_bank_base[offset >> 14][offset & 0x3fff];
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_slot_fs4600_device::write)
|
||||
{
|
||||
if (offset == 0x7ff9)
|
||||
{
|
||||
m_control = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_control & 0x02)
|
||||
{
|
||||
switch (offset & 0x3fff)
|
||||
{
|
||||
case 0x3ffa:
|
||||
m_sram_address = (m_sram_address & 0x00ffff) | (data << 16);
|
||||
break;
|
||||
|
||||
case 0x3ffb:
|
||||
m_sram_address = (m_sram_address & 0xff00ff) | (data << 8);
|
||||
break;
|
||||
|
||||
case 0x3ffc:
|
||||
m_sram_address = (m_sram_address & 0xffff00) | data;
|
||||
break;
|
||||
|
||||
case 0x3ffd:
|
||||
m_sram[m_sram_address++ & 0xfff] = data;
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror("Unhandled write %02x to %04x\n", data, offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x6000:
|
||||
m_selected_bank[1] = data;
|
||||
m_bank_base[1] = m_rom + ( ( m_selected_bank[1] * 0x4000 ) & 0x0fffff );
|
||||
break;
|
||||
|
||||
case 0x6400:
|
||||
m_selected_bank[0] = data;
|
||||
m_bank_base[0] = m_rom + ( ( m_selected_bank[0] * 0x4000 ) & 0x0fffff );
|
||||
break;
|
||||
|
||||
case 0x7000:
|
||||
m_selected_bank[2] = data;
|
||||
m_bank_base[2] = m_rom + ( ( m_selected_bank[2] * 0x4000 ) & 0x0fffff );
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror("Unhandled write %02x to %04x\n", data, offset);;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
45
src/emu/bus/msx_slot/fs4600.h
Normal file
45
src/emu/bus/msx_slot/fs4600.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef __MSX_SLOT_FS4600_H
|
||||
#define __MSX_SLOT_FS4600_H
|
||||
|
||||
#include "slot.h"
|
||||
#include "machine/nvram.h"
|
||||
|
||||
|
||||
extern const device_type MSX_SLOT_FS4600;
|
||||
|
||||
|
||||
#define MCFG_MSX_SLOT_FS4600_ADD(_tag, _startpage, _numpages, _region, _offset) \
|
||||
MCFG_MSX_INTERNAL_SLOT_ADD(_tag, MSX_SLOT_FS4600, _startpage, _numpages) \
|
||||
msx_slot_fs4600_device::set_rom_start(*device, _region, _offset);
|
||||
|
||||
class msx_slot_fs4600_device : public device_t,
|
||||
public msx_internal_slot_interface
|
||||
{
|
||||
public:
|
||||
msx_slot_fs4600_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// static configuration helpers
|
||||
static void set_rom_start(device_t &device, const char *region, UINT32 offset);
|
||||
|
||||
virtual void device_start();
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read);
|
||||
virtual DECLARE_WRITE8_MEMBER(write);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
private:
|
||||
required_device<nvram_device> m_nvram;
|
||||
const char *m_region;
|
||||
UINT32 m_region_offset;
|
||||
const UINT8 *m_rom;
|
||||
UINT8 m_selected_bank[4];
|
||||
const UINT8 *m_bank_base[4];
|
||||
UINT32 m_sram_address;
|
||||
UINT8 m_sram[0x1000];
|
||||
UINT8 m_control;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
69
src/emu/bus/msx_slot/music.c
Normal file
69
src/emu/bus/msx_slot/music.c
Normal file
@ -0,0 +1,69 @@
|
||||
#include "emu.h"
|
||||
#include "music.h"
|
||||
|
||||
|
||||
const device_type MSX_SLOT_MUSIC = &device_creator<msx_slot_music_device>;
|
||||
|
||||
|
||||
msx_slot_music_device::msx_slot_music_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: msx_slot_rom_device(mconfig, MSX_SLOT_MUSIC, "MSX Internal MSX-MUSIC", tag, owner, clock, "msx_slot_music", __FILE__)
|
||||
, m_ym2413(NULL)
|
||||
, m_ym2413_tag(NULL)
|
||||
, m_opll_active(false)
|
||||
, m_unlock(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_music_device::device_start()
|
||||
{
|
||||
msx_slot_rom_device::device_start();
|
||||
|
||||
if (m_ym2413_tag == NULL)
|
||||
{
|
||||
fatalerror("msx_slot_music_device: no YM2413 tag specified\n");
|
||||
}
|
||||
|
||||
m_ym2413 = owner()->subdevice<ym2413_device>(m_ym2413_tag);
|
||||
|
||||
if (m_ym2413 == NULL)
|
||||
{
|
||||
fatalerror("msx_slot_ym2413_device: Unable to find YM2413 with tag '%s'\n", m_ym2413_tag);
|
||||
}
|
||||
|
||||
// Install IO read/write handlers
|
||||
address_space &space = machine().device<cpu_device>("maincpu")->space(AS_IO);
|
||||
space.install_write_handler(0x7c, 0x7d, write8_delegate(FUNC(msx_slot_music_device::write_ym2413), this));
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_music_device::device_reset()
|
||||
{
|
||||
m_opll_active = false;
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_slot_music_device::read)
|
||||
{
|
||||
return msx_slot_rom_device::read(space, offset);
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_slot_music_device::write)
|
||||
{
|
||||
if (m_unlock == 0xbe && data == 0x41)
|
||||
{
|
||||
m_opll_active = true;
|
||||
}
|
||||
m_unlock = data;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_slot_music_device::write_ym2413)
|
||||
{
|
||||
if (m_opll_active)
|
||||
{
|
||||
m_ym2413->write(space, offset & 1, data);
|
||||
}
|
||||
}
|
||||
|
43
src/emu/bus/msx_slot/music.h
Normal file
43
src/emu/bus/msx_slot/music.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef __MSX_SLOT_MUSIC_H
|
||||
#define __MSX_SLOT_MUSIC_H
|
||||
|
||||
|
||||
#include "bus/msx_slot/slot.h"
|
||||
#include "bus/msx_slot/rom.h"
|
||||
#include "sound/2413intf.h"
|
||||
|
||||
|
||||
extern const device_type MSX_SLOT_MUSIC;
|
||||
|
||||
|
||||
#define MCFG_MSX_SLOT_MUSIC_ADD(_tag, _startpage, _numpages, _region, _offset, _ym2413_tag) \
|
||||
MCFG_MSX_INTERNAL_SLOT_ADD(_tag, MSX_SLOT_MUSIC, _startpage, _numpages) \
|
||||
msx_slot_rom_device::set_rom_start(*device, _region, _offset); \
|
||||
msx_slot_music_device::set_ym2413_tag(*device, _ym2413_tag); \
|
||||
|
||||
class msx_slot_music_device : public msx_slot_rom_device
|
||||
{
|
||||
public:
|
||||
msx_slot_music_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// static configuration helpers
|
||||
static void set_ym2413_tag(device_t &device, const char *tag) { dynamic_cast<msx_slot_music_device &>(device).m_ym2413_tag = tag; }
|
||||
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read);
|
||||
virtual DECLARE_WRITE8_MEMBER(write);
|
||||
|
||||
DECLARE_WRITE8_MEMBER(write_ym2413);
|
||||
|
||||
private:
|
||||
ym2413_device *m_ym2413;
|
||||
const char *m_ym2413_tag;
|
||||
bool m_opll_active;
|
||||
UINT8 m_unlock;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
176
src/emu/bus/msx_slot/panasonic08.c
Normal file
176
src/emu/bus/msx_slot/panasonic08.c
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
|
||||
Emulation of the firmware mapper as found in Panasonic FS-A1WX andFS-A1WSX machines.
|
||||
|
||||
Todo:
|
||||
- Anything besides the basic mapping
|
||||
- SRAM?
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "panasonic08.h"
|
||||
|
||||
|
||||
const device_type MSX_SLOT_PANASONIC08 = &device_creator<msx_slot_panasonic08_device>;
|
||||
|
||||
|
||||
msx_slot_panasonic08_device::msx_slot_panasonic08_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_SLOT_PANASONIC08, "MSX Internal Panasonic08", tag, owner, clock, "msx_slot_panasonic08", __FILE__)
|
||||
, msx_internal_slot_interface()
|
||||
, m_region(NULL)
|
||||
, m_region_offset(0)
|
||||
, m_rom(NULL)
|
||||
, m_control(0)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
m_selected_bank[i] = 0;
|
||||
m_bank_base[i] = 0;
|
||||
}
|
||||
memset(m_sram, 0, sizeof(m_sram));
|
||||
}
|
||||
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( panasonic08 )
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
machine_config_constructor msx_slot_panasonic08_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( panasonic08 );
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_panasonic08_device::set_rom_start(device_t &device, const char *region, UINT32 offset)
|
||||
{
|
||||
msx_slot_panasonic08_device &dev = downcast<msx_slot_panasonic08_device &>(device);
|
||||
|
||||
dev.m_region = region;
|
||||
dev.m_region_offset = offset;
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_panasonic08_device::device_start()
|
||||
{
|
||||
assert(m_region != NULL );
|
||||
|
||||
memory_region *m_rom_region = owner()->memregion(m_region);
|
||||
|
||||
// Sanity checks
|
||||
if (m_rom_region == NULL )
|
||||
{
|
||||
fatalerror("Rom slot '%s': Unable to find memory region '%s'\n", tag(), m_region);
|
||||
}
|
||||
if (m_rom_region->bytes() < m_region_offset + 0x200000)
|
||||
{
|
||||
fatalerror("Memory region '%s' is too small for the FS4600 firmware\n", m_region);
|
||||
}
|
||||
|
||||
m_rom = m_rom_region->base() + m_region_offset;
|
||||
|
||||
save_item(NAME(m_selected_bank));
|
||||
save_item(NAME(m_control));
|
||||
save_item(NAME(m_sram));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_slot_panasonic08_device::restore_banks), this));
|
||||
|
||||
restore_banks();
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_panasonic08_device::map_bank(int bank)
|
||||
{
|
||||
if (m_selected_bank[bank] >= 0x80 && m_selected_bank[bank] < 0x84) // Are these banks were sram is present? Mirroring?
|
||||
{
|
||||
logerror("panasonic08: mapping bank %d to sram\n", bank);
|
||||
m_bank_base[bank] = m_sram;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bank_base[bank] = m_rom + ( ( m_selected_bank[bank] * 0x2000 ) & 0x1fffff );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_panasonic08_device::restore_banks()
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
map_bank(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_slot_panasonic08_device::read)
|
||||
{
|
||||
if (m_control & 0x04)
|
||||
{
|
||||
// 7ff0 - 6000
|
||||
// 7ff1 - 6400
|
||||
// 7ff2 - 6800
|
||||
// 7ff3 - 6c00
|
||||
// 7ff4 - 7000
|
||||
// 7ff5 - 7800
|
||||
if (offset >= 0x7ff0 && offset < 0x7ff6) // maybe 7ff8 would make more sense here??
|
||||
{
|
||||
return m_selected_bank[offset - 0x7ff0];
|
||||
}
|
||||
}
|
||||
return m_bank_base[offset >> 13][offset & 0x1fff];
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(msx_slot_panasonic08_device::write)
|
||||
{
|
||||
if ((offset & 0xc000) == 0x8000)
|
||||
{
|
||||
UINT8 bank = m_selected_bank[offset >> 13];
|
||||
if (bank >= 0x80 && bank < 0x84) // Are these banks were sram is present? Mirroring?
|
||||
{
|
||||
logerror("panasonic08: writing %02x to sram %04x\n", data, offset & 0x1fff);
|
||||
m_sram[offset & 0x1fff] = data;
|
||||
}
|
||||
}
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x6000: /* Switched 0x0000-0x1FFF */
|
||||
m_selected_bank[0] = data;
|
||||
map_bank(0);
|
||||
break;
|
||||
|
||||
case 0x6400: /* Switches 0x2000-0x3FFF */
|
||||
m_selected_bank[1] = data;
|
||||
map_bank(1);
|
||||
break;
|
||||
|
||||
case 0x6800: /* Switches 0x4000-0x5FFF */
|
||||
m_selected_bank[2] = data;
|
||||
map_bank(2);
|
||||
break;
|
||||
|
||||
case 0x6c00:
|
||||
m_selected_bank[3] = data;
|
||||
map_bank(3);
|
||||
break;
|
||||
|
||||
case 0x7000: /* Switches 0x8000-0x9FFF */
|
||||
m_selected_bank[4] = data;
|
||||
map_bank(4);
|
||||
break;
|
||||
|
||||
case 0x7800:
|
||||
m_selected_bank[5] = data;
|
||||
map_bank(5);
|
||||
break;
|
||||
|
||||
case 0x7ff9:
|
||||
m_control = data;
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror("Unhandled write %02x to %04x\n", data, offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
44
src/emu/bus/msx_slot/panasonic08.h
Normal file
44
src/emu/bus/msx_slot/panasonic08.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef __MSX_SLOT_PANASONIC08_H
|
||||
#define __MSX_SLOT_PANASONIC08_H
|
||||
|
||||
#include "slot.h"
|
||||
|
||||
|
||||
extern const device_type MSX_SLOT_PANASONIC08;
|
||||
|
||||
|
||||
#define MCFG_MSX_SLOT_PANASONIC08_ADD(_tag, _startpage, _numpages, _region, _offset) \
|
||||
MCFG_MSX_INTERNAL_SLOT_ADD(_tag, MSX_SLOT_PANASONIC08, _startpage, _numpages) \
|
||||
msx_slot_panasonic08_device::set_rom_start(*device, _region, _offset);
|
||||
|
||||
class msx_slot_panasonic08_device : public device_t,
|
||||
public msx_internal_slot_interface
|
||||
{
|
||||
public:
|
||||
msx_slot_panasonic08_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// static configuration helpers
|
||||
static void set_rom_start(device_t &device, const char *region, UINT32 offset);
|
||||
|
||||
virtual void device_start();
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read);
|
||||
virtual DECLARE_WRITE8_MEMBER(write);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
private:
|
||||
const char *m_region;
|
||||
UINT32 m_region_offset;
|
||||
const UINT8 *m_rom;
|
||||
UINT8 m_selected_bank[8];
|
||||
const UINT8 *m_bank_base[8];
|
||||
UINT8 m_control;
|
||||
UINT8 m_sram[0x2000];
|
||||
|
||||
void map_bank(int bank);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
36
src/emu/bus/msx_slot/ram.c
Normal file
36
src/emu/bus/msx_slot/ram.c
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "ram.h"
|
||||
|
||||
const device_type MSX_SLOT_RAM = &device_creator<msx_slot_ram_device>;
|
||||
|
||||
msx_slot_ram_device::msx_slot_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_SLOT_RAM, "MSX Internal RAM", tag, owner, clock, "msx_slot_ram", __FILE__)
|
||||
, msx_internal_slot_interface()
|
||||
{
|
||||
}
|
||||
|
||||
void msx_slot_ram_device::device_start()
|
||||
{
|
||||
m_ram.resize(m_size);
|
||||
save_item(NAME(m_ram));
|
||||
}
|
||||
|
||||
READ8_MEMBER(msx_slot_ram_device::read)
|
||||
{
|
||||
if ( offset >= m_start_address && offset < m_end_address )
|
||||
{
|
||||
return m_ram[ offset - m_start_address ];
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(msx_slot_ram_device::write)
|
||||
{
|
||||
if ( offset >= m_start_address && offset < m_end_address )
|
||||
{
|
||||
m_ram[offset - m_start_address] = data;
|
||||
}
|
||||
}
|
||||
|
26
src/emu/bus/msx_slot/ram.h
Normal file
26
src/emu/bus/msx_slot/ram.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef __MSX_SLOT_RAM_H
|
||||
#define __MSX_SLOT_RAM_H
|
||||
|
||||
#include "slot.h"
|
||||
|
||||
#define MCFG_MSX_SLOT_RAM_ADD(_tag, _startpage, _numpages) \
|
||||
MCFG_MSX_INTERNAL_SLOT_ADD(_tag, MSX_SLOT_RAM, _startpage, _numpages) \
|
||||
|
||||
class msx_slot_ram_device : public device_t,
|
||||
public msx_internal_slot_interface
|
||||
{
|
||||
public:
|
||||
msx_slot_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
virtual void device_start();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read);
|
||||
virtual DECLARE_WRITE8_MEMBER(write);
|
||||
|
||||
private:
|
||||
dynamic_array<UINT8> m_ram;
|
||||
};
|
||||
|
||||
extern const device_type MSX_SLOT_RAM;
|
||||
|
||||
#endif
|
79
src/emu/bus/msx_slot/ram_mm.c
Normal file
79
src/emu/bus/msx_slot/ram_mm.c
Normal file
@ -0,0 +1,79 @@
|
||||
#include "emu.h"
|
||||
#include "ram_mm.h"
|
||||
|
||||
const device_type MSX_SLOT_RAM_MM = &device_creator<msx_slot_ram_mm_device>;
|
||||
|
||||
msx_slot_ram_mm_device::msx_slot_ram_mm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_SLOT_RAM_MM, "MSX Internal Memory Mapped RAM", tag, owner, clock, "msx_slot_ram_mm", __FILE__)
|
||||
, msx_internal_slot_interface()
|
||||
, m_total_size(0)
|
||||
, m_bank_mask(0)
|
||||
, m_ramio_set_bits(0)
|
||||
{
|
||||
}
|
||||
|
||||
void msx_slot_ram_mm_device::device_start()
|
||||
{
|
||||
// Valid mapper sizes are 64KB, 128KB, 256KB, 512KB, 1MB, 2MB, and 4MB */
|
||||
switch (m_total_size)
|
||||
{
|
||||
case 64*1024: m_bank_mask = 0x03; break;
|
||||
case 128*1024: m_bank_mask = 0x07; break;
|
||||
case 256*1024: m_bank_mask = 0x0F; break;
|
||||
case 512*1024: m_bank_mask = 0x1F; break;
|
||||
case 1024*1024: m_bank_mask = 0x3F; break;
|
||||
case 2048*1024: m_bank_mask = 0x7F; break;
|
||||
case 4096*1024: m_bank_mask = 0xFF; break;
|
||||
default: fatalerror("Invalid memory mapper size specified\n");
|
||||
}
|
||||
|
||||
m_ram.resize(m_total_size);
|
||||
|
||||
for ( int i = 0; i < 4; i++ )
|
||||
{
|
||||
m_bank_selected[i] = 3 -i;
|
||||
m_bank_base[i] = m_ram + 0x4000 * m_bank_selected[i];
|
||||
}
|
||||
|
||||
save_item(NAME(m_ram));
|
||||
save_item(NAME(m_bank_selected));
|
||||
|
||||
machine().save().register_postload(save_prepost_delegate(FUNC(msx_slot_ram_mm_device::restore_banks), this));
|
||||
|
||||
// Install IO read/write handlers
|
||||
address_space &space = machine().device<cpu_device>("maincpu")->space(AS_IO);
|
||||
space.install_read_handler(0xFC, 0xFF, read8_delegate(FUNC(msx_slot_ram_mm_device::read_mapper_bank), this));
|
||||
space.install_write_handler(0xFC, 0xFF, write8_delegate(FUNC(msx_slot_ram_mm_device::write_mapper_bank), this));
|
||||
}
|
||||
|
||||
void msx_slot_ram_mm_device::restore_banks()
|
||||
{
|
||||
for ( int i = 0; i < 3; i++ )
|
||||
{
|
||||
m_bank_base[i] = m_ram + 0x4000 * ( m_bank_selected[i] & m_bank_mask );
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER(msx_slot_ram_mm_device::read)
|
||||
{
|
||||
return m_bank_base[offset >> 14][offset & 0x3fff];
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(msx_slot_ram_mm_device::write)
|
||||
{
|
||||
m_bank_base[offset >> 14][offset & 0x3fff] = data;
|
||||
}
|
||||
|
||||
READ8_MEMBER(msx_slot_ram_mm_device::read_mapper_bank)
|
||||
{
|
||||
return m_bank_selected[offset & 3] | m_ramio_set_bits;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(msx_slot_ram_mm_device::write_mapper_bank)
|
||||
{
|
||||
offset &= 3;
|
||||
|
||||
m_bank_selected[offset] = data;
|
||||
m_bank_base[offset] = m_ram + 0x4000 * ( m_bank_selected[offset] & m_bank_mask );
|
||||
}
|
||||
|
44
src/emu/bus/msx_slot/ram_mm.h
Normal file
44
src/emu/bus/msx_slot/ram_mm.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef __MSX_SLOT_RAM_MM_H
|
||||
#define __MSX_SLOT_RAM_MM_H
|
||||
|
||||
#include "slot.h"
|
||||
|
||||
#define MCFG_MSX_SLOT_RAM_MM_ADD(_tag, _total_size) \
|
||||
MCFG_MSX_INTERNAL_SLOT_ADD(_tag, MSX_SLOT_RAM_MM, 0, 4) \
|
||||
msx_slot_ram_mm_device::set_total_size(*device, _total_size);
|
||||
|
||||
#define MCFG_MSX_SLOT_RAMM_SET_RAMIO_BITS(_ramio_set_bits) \
|
||||
msx_slot_ram_mm_device::set_ramio_set_bits(*device, _ramio_set_bits);
|
||||
|
||||
class msx_slot_ram_mm_device : public device_t
|
||||
, public msx_internal_slot_interface
|
||||
{
|
||||
public:
|
||||
msx_slot_ram_mm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
static void set_total_size(device_t &device, UINT32 total_size) { dynamic_cast<msx_slot_ram_mm_device &>(device).m_total_size = total_size; }
|
||||
static void set_ramio_set_bits(device_t &device, UINT8 ramio_set_bits) { dynamic_cast<msx_slot_ram_mm_device &>(device).m_ramio_set_bits = ramio_set_bits; }
|
||||
|
||||
virtual void device_start();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read);
|
||||
virtual DECLARE_WRITE8_MEMBER(write);
|
||||
|
||||
DECLARE_READ8_MEMBER(read_mapper_bank);
|
||||
DECLARE_WRITE8_MEMBER(write_mapper_bank);
|
||||
|
||||
void restore_banks();
|
||||
|
||||
private:
|
||||
dynamic_array<UINT8> m_ram;
|
||||
UINT32 m_total_size;
|
||||
UINT8 m_bank_mask;
|
||||
UINT8 m_bank_selected[4];
|
||||
UINT8 *m_bank_base[4];
|
||||
UINT8 m_ramio_set_bits;
|
||||
};
|
||||
|
||||
extern const device_type MSX_SLOT_RAM_MM;
|
||||
|
||||
#endif
|
||||
|
66
src/emu/bus/msx_slot/rom.c
Normal file
66
src/emu/bus/msx_slot/rom.c
Normal file
@ -0,0 +1,66 @@
|
||||
#include "emu.h"
|
||||
#include "rom.h"
|
||||
|
||||
|
||||
const device_type MSX_SLOT_ROM = &device_creator<msx_slot_rom_device>;
|
||||
|
||||
|
||||
msx_slot_rom_device::msx_slot_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MSX_SLOT_ROM, "MSX Internal ROM", tag, owner, clock, "msx_slot_rom", __FILE__)
|
||||
, msx_internal_slot_interface()
|
||||
, m_region(NULL)
|
||||
, m_region_offset(0)
|
||||
, m_rom(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
msx_slot_rom_device::msx_slot_rom_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)
|
||||
, msx_internal_slot_interface()
|
||||
, m_region(NULL)
|
||||
, m_region_offset(0)
|
||||
, m_rom(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_rom_device::set_rom_start(device_t &device, const char *region, UINT32 offset)
|
||||
{
|
||||
msx_slot_rom_device &dev = downcast<msx_slot_rom_device &>(device);
|
||||
|
||||
dev.m_region = region;
|
||||
dev.m_region_offset = offset;
|
||||
}
|
||||
|
||||
|
||||
void msx_slot_rom_device::device_start()
|
||||
{
|
||||
assert(m_region != NULL );
|
||||
|
||||
memory_region *m_rom_region = owner()->memregion(m_region);
|
||||
|
||||
// Sanity checks
|
||||
if (m_rom_region == NULL )
|
||||
{
|
||||
fatalerror("Rom slot '%s': Unable to find memory region '%s'\n", tag(), m_region);
|
||||
}
|
||||
if (m_rom_region->bytes() < m_region_offset + m_size)
|
||||
{
|
||||
fatalerror("Memory region '%s' is too small for rom slot '%s'\n", m_region, tag());
|
||||
}
|
||||
|
||||
m_rom = m_rom_region->base() + m_region_offset;
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(msx_slot_rom_device::read)
|
||||
{
|
||||
if ( offset >= m_start_address && offset < m_end_address )
|
||||
{
|
||||
return m_rom[ offset - m_start_address ];
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
|
32
src/emu/bus/msx_slot/rom.h
Normal file
32
src/emu/bus/msx_slot/rom.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef __MSX_SLOT_ROM_H
|
||||
#define __MSX_SLOT_ROM_H
|
||||
|
||||
#include "slot.h"
|
||||
|
||||
#define MCFG_MSX_SLOT_ROM_ADD(_tag, _startpage, _numpages, _region, _offset) \
|
||||
MCFG_MSX_INTERNAL_SLOT_ADD(_tag, MSX_SLOT_ROM, _startpage, _numpages) \
|
||||
msx_slot_rom_device::set_rom_start(*device, _region, _offset);
|
||||
|
||||
class msx_slot_rom_device : public device_t,
|
||||
public msx_internal_slot_interface
|
||||
{
|
||||
public:
|
||||
msx_slot_rom_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);
|
||||
msx_slot_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// static configuration helpers
|
||||
static void set_rom_start(device_t &device, const char *region, UINT32 offset);
|
||||
|
||||
virtual void device_start();
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read);
|
||||
|
||||
private:
|
||||
const char *m_region;
|
||||
UINT32 m_region_offset;
|
||||
const UINT8 *m_rom;
|
||||
};
|
||||
|
||||
extern const device_type MSX_SLOT_ROM;
|
||||
|
||||
#endif
|
35
src/emu/bus/msx_slot/slot.c
Normal file
35
src/emu/bus/msx_slot/slot.c
Normal file
@ -0,0 +1,35 @@
|
||||
/***********************************************************************************************************
|
||||
|
||||
MSX (logical) internal slot interfacing
|
||||
|
||||
The MSX standard uses logically defined slots, subslots, and pages to access rom and optional components
|
||||
in a system. There are no physical slots inside the system. A piece of rom/component can occur in multiple
|
||||
pages; and multiple pieces of rom/ram/components can occur in a single slot.
|
||||
|
||||
***********************************************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "slot.h"
|
||||
|
||||
msx_internal_slot_interface::msx_internal_slot_interface()
|
||||
: m_start_address(0)
|
||||
, m_size(0)
|
||||
, m_end_address(0)
|
||||
{
|
||||
}
|
||||
|
||||
void msx_internal_slot_interface::set_start_address(device_t &device, UINT32 start_address)
|
||||
{
|
||||
msx_internal_slot_interface &dev = dynamic_cast<msx_internal_slot_interface &>(device);
|
||||
dev.m_start_address = start_address;
|
||||
dev.m_end_address = dev.m_start_address + dev.m_size;
|
||||
}
|
||||
|
||||
void msx_internal_slot_interface::set_size(device_t &device, UINT32 size)
|
||||
{
|
||||
msx_internal_slot_interface &dev = dynamic_cast<msx_internal_slot_interface &>(device);
|
||||
|
||||
dev.m_size = size;
|
||||
dev.m_end_address = dev.m_start_address + dev.m_size;
|
||||
}
|
||||
|
37
src/emu/bus/msx_slot/slot.h
Normal file
37
src/emu/bus/msx_slot/slot.h
Normal file
@ -0,0 +1,37 @@
|
||||
/***********************************************************************************************************
|
||||
|
||||
MSX (logical) internal slot/page interfacing
|
||||
|
||||
The MSX standard uses logically defined slots, subslots, and pages to access rom and optional components
|
||||
in a system. There are no physical slots inside the system. A piece of rom/component can occur in multiple
|
||||
pages; and multiple pieces of rom/ram/components can occur in a single slot.
|
||||
|
||||
***********************************************************************************************************/
|
||||
|
||||
#ifndef __MSX_SLOT_SLOT_H
|
||||
#define __MSX_SLOT_SLOT_H
|
||||
|
||||
#define MCFG_MSX_INTERNAL_SLOT_ADD(_tag, _type, _startpage, _numpages) \
|
||||
MCFG_DEVICE_ADD(_tag, _type, 0) \
|
||||
msx_internal_slot_interface::set_start_address(*device, _startpage * 0x4000); \
|
||||
msx_internal_slot_interface::set_size(*device, _numpages * 0x4000);
|
||||
|
||||
class msx_internal_slot_interface
|
||||
{
|
||||
public:
|
||||
msx_internal_slot_interface();
|
||||
|
||||
// static configuration helpers
|
||||
static void set_start_address(device_t &device, UINT32 start_address);
|
||||
static void set_size(device_t &device, UINT32 size);
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(read) { return 0xFF; }
|
||||
virtual DECLARE_WRITE8_MEMBER(write) { }
|
||||
|
||||
protected:
|
||||
UINT32 m_start_address;
|
||||
UINT32 m_size;
|
||||
UINT32 m_end_address;
|
||||
};
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -16,7 +16,6 @@
|
||||
#include "sound/ay8910.h"
|
||||
#include "sound/dac.h"
|
||||
#include "sound/wave.h"
|
||||
#include "sound/k051649.h"
|
||||
#include "sound/2413intf.h"
|
||||
#include "video/v9938.h"
|
||||
#include "video/tms9928a.h"
|
||||
@ -28,124 +27,155 @@
|
||||
#include "formats/msx_dsk.h"
|
||||
//#include "osdepend.h"
|
||||
#include "hashfile.h"
|
||||
#include "includes/msx_slot.h"
|
||||
#include "machine/wd_fdc.h"
|
||||
#include "imagedev/floppy.h"
|
||||
#include "bus/msx_slot/slot.h"
|
||||
#include "bus/msx_slot/rom.h"
|
||||
#include "bus/msx_slot/ram.h"
|
||||
#include "bus/msx_slot/cartridge.h"
|
||||
#include "bus/msx_slot/ram_mm.h"
|
||||
#include "bus/msx_slot/disk.h"
|
||||
#include "bus/msx_slot/music.h"
|
||||
#include "bus/msx_slot/bunsetsu.h"
|
||||
#include "bus/msx_slot/fs4600.h"
|
||||
#include "bus/msx_slot/panasonic08.h"
|
||||
|
||||
#define MSX_MAX_CARTS (2)
|
||||
|
||||
#define TC8521_TAG "rtc"
|
||||
|
||||
#define MCFG_MSX_LAYOUT(_layout) \
|
||||
msx_state::set_layout(*owner, msx_slot_layout_##_layout);
|
||||
#define MCFG_MSX_LAYOUT_ROM(_tag, _prim, _sec, _page, _numpages, _region, _offset) \
|
||||
MCFG_MSX_SLOT_ROM_ADD(_tag, _page, _numpages, _region, _offset) \
|
||||
msx_state::install_slot_pages(*owner, _prim, _sec, _page, _numpages, device);
|
||||
|
||||
#define MCFG_MSX_LAYOUT_RAM(_tag, _prim, _sec, _page, _numpages) \
|
||||
MCFG_MSX_SLOT_RAM_ADD(_tag, _page, _numpages) \
|
||||
msx_state::install_slot_pages(*owner, _prim, _sec, _page, _numpages, device);
|
||||
|
||||
#define MCFG_MSX_LAYOUT_CARTRIDGE(_tag, _prim, _sec) \
|
||||
MCFG_MSX_SLOT_CARTRIDGE_ADD(_tag) \
|
||||
msx_state::install_slot_pages(*owner, _prim, _sec, 0, 4, device);
|
||||
|
||||
#define MCFG_MSX_LAYOUT_RAM_MM(_tag, _prim, _sec, _total_size) \
|
||||
MCFG_MSX_SLOT_RAM_MM_ADD(_tag, _total_size) \
|
||||
msx_state::install_slot_pages(*owner, _prim, _sec, 0, 4, device);
|
||||
|
||||
#define MCFG_MSX_RAMIO_SET_BITS(_ramio_set_bits) \
|
||||
msx_state::set_ramio_set_bits(*owner, _ramio_set_bits);
|
||||
MCFG_MSX_SLOT_RAMM_SET_RAMIO_BITS(_ramio_set_bits)
|
||||
|
||||
#define MCFG_MSX_LAYOUT_DISK1(_tag, _prim, _sec, _page, _numpages, _region, _offset) \
|
||||
MCFG_MSX_SLOT_DISK1_ADD(_tag, _page, _numpages, _region, _offset, "fdc", "fdc:0", "fdc:1") \
|
||||
msx_state::install_slot_pages(*owner, _prim, _sec, _page, _numpages, device);
|
||||
|
||||
#define MCFG_MSX_LAYOUT_DISK2(_tag, _prim, _sec, _page, _numpages, _region, _offset) \
|
||||
MCFG_MSX_SLOT_DISK2_ADD(_tag, _page, _numpages, _region, _offset, "fdc", "fdc:0", "fdc:1") \
|
||||
msx_state::install_slot_pages(*owner, _prim, _sec, _page, _numpages, device);
|
||||
|
||||
#define MCFG_MSX_LAYOUT_MUSIC(_tag, _prim, _sec, _page, _numpages, _region, _offset) \
|
||||
MCFG_MSX_SLOT_MUSIC_ADD(_tag, _page, _numpages, _region, _offset, "ym2413" ) \
|
||||
msx_state::install_slot_pages(*owner, _prim, _sec, _page, _numpages, device);
|
||||
|
||||
#define MCFG_MSX_LAYOUT_BUNSETSU(_tag, _prim, _sec, _page, _numpages, _region, _offset, _bunsetsu_tag) \
|
||||
MCFG_MSX_SLOT_BUNSETSU_ADD(_tag, _page, _numpages, _region, _offset, _bunsetsu_tag) \
|
||||
msx_state::install_slot_pages(*owner, _prim, _sec, _page, _numpages, device);
|
||||
|
||||
#define MCFG_MSX_LAYOUT_FS4600(_tag, _prim, _sec, _page, _numpages, _region, _offset) \
|
||||
MCFG_MSX_SLOT_FS4600_ADD(_tag, _page, _numpages, _region, _offset) \
|
||||
msx_state::install_slot_pages(*owner, _prim, _sec, _page, _numpages, device);
|
||||
|
||||
#define MCFG_MSX_LAYOUT_PANASONIC08(_tag, _prim, _sec, _page, _numpages, _region, _offset) \
|
||||
MCFG_MSX_SLOT_PANASONIC08_ADD(_tag, _page, _numpages, _region, _offset) \
|
||||
msx_state::install_slot_pages(*owner, _prim, _sec, _page, _numpages, device);
|
||||
|
||||
|
||||
class msx_state : public driver_device
|
||||
{
|
||||
public:
|
||||
msx_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag),
|
||||
m_layout(NULL),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_v9938(*this, "v9938"),
|
||||
m_v9958(*this, "v9958"),
|
||||
m_cassette(*this, "cassette"),
|
||||
m_ay8910(*this, "ay8910"),
|
||||
m_ym(*this, "ym2413"),
|
||||
m_k051649(*this, "k051649"),
|
||||
m_dac(*this, "dac"),
|
||||
m_rtc(*this, TC8521_TAG),
|
||||
m_fdc(*this, "fdc"),
|
||||
m_floppy0(*this, "fdc:0"),
|
||||
m_floppy1(*this, "fdc:1"),
|
||||
m_floppy(NULL),
|
||||
m_bank1(*this, "bank1"),
|
||||
m_bank2(*this, "bank2"),
|
||||
m_bank3(*this, "bank3"),
|
||||
m_bank4(*this, "bank4"),
|
||||
m_bank5(*this, "bank5"),
|
||||
m_bank6(*this, "bank6"),
|
||||
m_bank7(*this, "bank7"),
|
||||
m_bank8(*this, "bank8"),
|
||||
m_bank9(*this, "bank9"),
|
||||
m_bank10(*this, "bank10"),
|
||||
m_bank11(*this, "bank11"),
|
||||
m_region_maincpu(*this, "maincpu"),
|
||||
m_region_kanji(*this, "kanji"),
|
||||
m_io_joy0(*this, "JOY0"),
|
||||
m_io_joy1(*this, "JOY1"),
|
||||
m_io_dsw(*this, "DSW"),
|
||||
m_io_mouse0(*this, "MOUSE0"),
|
||||
m_io_mouse1(*this, "MOUSE1"),
|
||||
m_io_key0(*this, "KEY0"),
|
||||
m_io_key1(*this, "KEY1"),
|
||||
m_io_key2(*this, "KEY2"),
|
||||
m_io_key3(*this, "KEY3"),
|
||||
m_io_key4(*this, "KEY4"),
|
||||
m_io_key5(*this, "KEY5") { }
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_psg_b(0)
|
||||
, m_rtc_latch(0)
|
||||
, m_kanji_latch(0)
|
||||
, m_primary_slot(0)
|
||||
, m_port_c_old(0)
|
||||
, m_keylatch(0)
|
||||
, m_current_switched_device(0)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_v9938(*this, "v9938")
|
||||
, m_v9958(*this, "v9958")
|
||||
, m_cassette(*this, "cassette")
|
||||
, m_ay8910(*this, "ay8910")
|
||||
, m_dac(*this, "dac")
|
||||
, m_rtc(*this, TC8521_TAG)
|
||||
, m_switched_device_as_config("switched_device", ENDIANNESS_LITTLE, 8, 16, 0, address_map_delegate(FUNC(msx_state::switched_device_map), this))
|
||||
, m_region_maincpu(*this, "maincpu")
|
||||
, m_region_kanji(*this, "kanji")
|
||||
, m_io_joy0(*this, "JOY0")
|
||||
, m_io_joy1(*this, "JOY1")
|
||||
, m_io_dsw(*this, "DSW")
|
||||
, m_io_mouse0(*this, "MOUSE0")
|
||||
, m_io_mouse1(*this, "MOUSE1")
|
||||
, m_io_key0(*this, "KEY0")
|
||||
, m_io_key1(*this, "KEY1")
|
||||
, m_io_key2(*this, "KEY2")
|
||||
, m_io_key3(*this, "KEY3")
|
||||
, m_io_key4(*this, "KEY4")
|
||||
, m_io_key5(*this, "KEY5")
|
||||
{
|
||||
for (int prim = 0; prim < 4; prim++ )
|
||||
{
|
||||
m_slot_expanded[prim] = false;
|
||||
m_secondary_slot[prim] = 0;
|
||||
for (int sec = 0; sec < 4; sec++ )
|
||||
{
|
||||
for (int page = 0; page < 4; page++ )
|
||||
{
|
||||
m_all_slots[prim][sec][page] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_mouse[0] = m_mouse[1] = 0;
|
||||
m_mouse_stat[0] = m_mouse_stat[1] = 0;
|
||||
}
|
||||
|
||||
// static configuration helpers
|
||||
static void set_layout(device_t &device, const msx_slot_layout *layout) { downcast<msx_state &>(device).m_layout = layout; }
|
||||
static void set_ramio_set_bits(device_t &device, UINT8 ramio_set_bits) { downcast<msx_state &>(device).m_ramio_set_bits = ramio_set_bits; }
|
||||
static void install_slot_pages(device_t &owner, UINT8 prim, UINT8 sec, UINT8 page, UINT8 numpages, device_t *device);
|
||||
|
||||
DECLARE_WRITE8_MEMBER(msx_page0_w);
|
||||
DECLARE_WRITE8_MEMBER(msx_page0_1_w);
|
||||
DECLARE_WRITE8_MEMBER(msx_page1_w);
|
||||
DECLARE_WRITE8_MEMBER(msx_page1_1_w);
|
||||
DECLARE_WRITE8_MEMBER(msx_page1_2_w);
|
||||
DECLARE_WRITE8_MEMBER(msx_page2_w);
|
||||
DECLARE_WRITE8_MEMBER(msx_page2_1_w);
|
||||
DECLARE_WRITE8_MEMBER(msx_page2_2_w);
|
||||
DECLARE_WRITE8_MEMBER(msx_page2_3_w);
|
||||
DECLARE_WRITE8_MEMBER(msx_page3_w);
|
||||
DECLARE_WRITE8_MEMBER(msx_page3_1_w);
|
||||
DECLARE_ADDRESS_MAP(switched_device_map, 8);
|
||||
DECLARE_WRITE8_MEMBER(msx_sec_slot_w);
|
||||
DECLARE_READ8_MEMBER(msx_sec_slot_r);
|
||||
DECLARE_WRITE8_MEMBER(msx_ram_mapper_w);
|
||||
DECLARE_READ8_MEMBER(msx_ram_mapper_r);
|
||||
DECLARE_READ8_MEMBER(msx_kanji_r);
|
||||
DECLARE_WRITE8_MEMBER(msx_kanji_w);
|
||||
DECLARE_WRITE8_MEMBER(msx_90in1_w);
|
||||
DECLARE_WRITE8_MEMBER(msx_ppi_port_a_w);
|
||||
DECLARE_WRITE8_MEMBER(msx_ppi_port_c_w);
|
||||
DECLARE_READ8_MEMBER(msx_ppi_port_b_r);
|
||||
DECLARE_WRITE8_MEMBER(msx_fmpac_w);
|
||||
DECLARE_READ8_MEMBER(msx_rtc_reg_r);
|
||||
DECLARE_WRITE8_MEMBER(msx_rtc_reg_w);
|
||||
DECLARE_WRITE8_MEMBER(msx_rtc_latch_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(msx_wd179x_intrq_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(msx_wd179x_drq_w);
|
||||
DECLARE_READ8_MEMBER(msx_mem_read);
|
||||
DECLARE_WRITE8_MEMBER(msx_mem_write);
|
||||
DECLARE_READ8_MEMBER(msx_switched_r);
|
||||
DECLARE_WRITE8_MEMBER(msx_switched_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(turbo_w);
|
||||
|
||||
/* PSG */
|
||||
int m_psg_b;
|
||||
int m_opll_active;
|
||||
/* mouse */
|
||||
UINT16 m_mouse[2];
|
||||
int m_mouse_stat[2];
|
||||
/* rtc */
|
||||
int m_rtc_latch;
|
||||
/* disk */
|
||||
UINT8 m_dsk_stat;
|
||||
/* kanji */
|
||||
int m_kanji_latch;
|
||||
/* memory */
|
||||
const msx_slot_layout *m_layout;
|
||||
slot_state *m_cart_state[MSX_MAX_CARTS];
|
||||
slot_state *m_state[4];
|
||||
const msx_slot *m_slot[4];
|
||||
UINT8 *m_ram_pages[4];
|
||||
UINT8 *m_empty, m_ram_mapper[4];
|
||||
UINT8 m_ramio_set_bits;
|
||||
slot_state *m_all_state[4][4][4];
|
||||
int m_slot_expanded[4];
|
||||
msx_internal_slot_interface m_empty_slot;
|
||||
msx_internal_slot_interface *m_all_slots[4][4][4];
|
||||
msx_internal_slot_interface *m_current_page[4];
|
||||
bool m_slot_expanded[4];
|
||||
UINT8 m_primary_slot;
|
||||
UINT8 m_secondary_slot[4];
|
||||
UINT8 m_superloderunner_bank;
|
||||
UINT8 m_korean90in1_bank;
|
||||
UINT8 *m_top_page;
|
||||
int m_port_c_old;
|
||||
int keylatch;
|
||||
int m_keylatch;
|
||||
UINT8 m_current_switched_device;
|
||||
void msx_memory_map_all ();
|
||||
void msx_memory_map_page (UINT8 page);
|
||||
void msx_ch_reset_core ();
|
||||
@ -156,14 +186,8 @@ public:
|
||||
optional_device<v9958_device> m_v9958;
|
||||
required_device<cassette_image_device> m_cassette;
|
||||
required_device<ay8910_device> m_ay8910;
|
||||
required_device<ym2413_device> m_ym;
|
||||
optional_device<k051649_device> m_k051649;
|
||||
required_device<dac_device> m_dac;
|
||||
optional_device<rp5c01_device> m_rtc;
|
||||
optional_device<wd_fdc_analog_t> m_fdc;
|
||||
optional_device<floppy_connector> m_floppy0;
|
||||
optional_device<floppy_connector> m_floppy1;
|
||||
floppy_image_device *m_floppy;
|
||||
DECLARE_FLOPPY_FORMATS(floppy_formats);
|
||||
|
||||
DECLARE_READ8_MEMBER(msx_psg_port_a_r);
|
||||
@ -180,34 +204,13 @@ public:
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(msx2p_interrupt);
|
||||
DECLARE_WRITE8_MEMBER(msx_ay8910_w);
|
||||
void msx_memory_init();
|
||||
void msx_memory_set_carts();
|
||||
|
||||
DECLARE_DEVICE_IMAGE_LOAD_MEMBER( msx_cart );
|
||||
DECLARE_DEVICE_IMAGE_UNLOAD_MEMBER( msx_cart );
|
||||
DECLARE_WRITE_LINE_MEMBER(msx_vdp_interrupt);
|
||||
|
||||
// from msx_slot
|
||||
DECLARE_READ8_MEMBER(konami_scc_bank5);
|
||||
DECLARE_READ8_MEMBER(msx_diskrom_page1_r);
|
||||
DECLARE_READ8_MEMBER(msx_diskrom_page2_r);
|
||||
DECLARE_READ8_MEMBER(msx_diskrom2_page1_r);
|
||||
DECLARE_READ8_MEMBER(msx_diskrom2_page2_r);
|
||||
DECLARE_READ8_MEMBER(soundcartridge_scc);
|
||||
DECLARE_READ8_MEMBER(soundcartridge_sccp);
|
||||
|
||||
required_memory_bank m_bank1;
|
||||
required_memory_bank m_bank2;
|
||||
required_memory_bank m_bank3;
|
||||
required_memory_bank m_bank4;
|
||||
required_memory_bank m_bank5;
|
||||
required_memory_bank m_bank6;
|
||||
required_memory_bank m_bank7;
|
||||
required_memory_bank m_bank8;
|
||||
required_memory_bank m_bank9;
|
||||
required_memory_bank m_bank10;
|
||||
required_memory_bank m_bank11;
|
||||
|
||||
protected:
|
||||
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == 0) ? &m_switched_device_as_config : NULL; }
|
||||
|
||||
address_space_config m_switched_device_as_config;
|
||||
required_memory_region m_region_maincpu;
|
||||
optional_memory_region m_region_kanji;
|
||||
required_ioport m_io_joy0;
|
||||
|
@ -1,215 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* includes/msx_slot.h
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MSX_SLOT_H_
|
||||
#define MSX_SLOT_H_
|
||||
|
||||
|
||||
enum {
|
||||
MSX_LAYOUT_SLOT_ENTRY,
|
||||
MSX_LAYOUT_LAST
|
||||
};
|
||||
|
||||
struct msx_slot_layout {
|
||||
int entry;
|
||||
int type;
|
||||
int slot_primary, slot_secondary, slot_page, page_extent;
|
||||
int size, option;
|
||||
};
|
||||
|
||||
#define MSX_LAYOUT_INIT(msx) \
|
||||
static const msx_slot_layout msx_slot_layout_##msx[] = {
|
||||
#define MSX_LAYOUT_SLOT(prim, sec, page, extend, type, size, option) \
|
||||
{ \
|
||||
MSX_LAYOUT_SLOT_ENTRY, \
|
||||
SLOT_##type, \
|
||||
prim, \
|
||||
sec, \
|
||||
page, \
|
||||
extend, \
|
||||
size, \
|
||||
option \
|
||||
},
|
||||
|
||||
#define MSX_LAYOUT_END \
|
||||
{ \
|
||||
MSX_LAYOUT_LAST, \
|
||||
SLOT_END, \
|
||||
0, \
|
||||
0, \
|
||||
0, \
|
||||
0, \
|
||||
0, \
|
||||
0 \
|
||||
} \
|
||||
};
|
||||
|
||||
|
||||
enum msx_slot_type {
|
||||
SLOT_EMPTY = 0,
|
||||
SLOT_MSXDOS2,
|
||||
SLOT_KONAMI_SCC,
|
||||
SLOT_KONAMI,
|
||||
SLOT_ASCII8,
|
||||
SLOT_ASCII16,
|
||||
SLOT_GAMEMASTER2,
|
||||
SLOT_ASCII8_SRAM,
|
||||
SLOT_ASCII16_SRAM,
|
||||
SLOT_RTYPE,
|
||||
SLOT_MAJUTSUSHI,
|
||||
SLOT_FMPAC,
|
||||
SLOT_SUPERLODERUNNER,
|
||||
SLOT_SYNTHESIZER,
|
||||
SLOT_CROSS_BLAIM,
|
||||
SLOT_DISK_ROM,
|
||||
SLOT_KOREAN_80IN1,
|
||||
SLOT_KOREAN_126IN1,
|
||||
SLOT_KOREAN_90IN1,
|
||||
SLOT_LAST_CARTRIDGE_TYPE = SLOT_KOREAN_90IN1,
|
||||
SLOT_SOUNDCARTRIDGE,
|
||||
SLOT_ROM,
|
||||
SLOT_RAM,
|
||||
SLOT_RAM_MM,
|
||||
SLOT_CARTRIDGE1,
|
||||
SLOT_CARTRIDGE2,
|
||||
SLOT_DISK_ROM2,
|
||||
SLOT_END
|
||||
};
|
||||
|
||||
enum msx_mem_type {
|
||||
MSX_MEM_ROM,
|
||||
MSX_MEM_RAM,
|
||||
MSX_MEM_HANDLER
|
||||
};
|
||||
|
||||
struct slot_state {
|
||||
int m_type;
|
||||
int m_start_page;
|
||||
int m_bank_mask;
|
||||
int m_banks[4];
|
||||
int m_size;
|
||||
UINT8 *m_mem;
|
||||
const char *m_sramfile;
|
||||
union {
|
||||
struct {
|
||||
UINT8 *mem;
|
||||
int sram_support;
|
||||
int sram_active;
|
||||
int opll_active;
|
||||
} fmpac;
|
||||
struct {
|
||||
int active;
|
||||
} scc;
|
||||
struct {
|
||||
UINT8 *mem;
|
||||
int sram_mask;
|
||||
int empty_mask;
|
||||
} sram;
|
||||
struct {
|
||||
int scc_active;
|
||||
int sccp_active;
|
||||
int ram_mode[4];
|
||||
int banks_saved[4];
|
||||
int mode;
|
||||
} sccp;
|
||||
} m_cart;
|
||||
};
|
||||
|
||||
struct msx_slot {
|
||||
int slot_type;
|
||||
int mem_type;
|
||||
char name[32];
|
||||
int (*init)(running_machine &machine, slot_state*, int page, UINT8 *mem, int size);
|
||||
void (*reset)(running_machine &machine, slot_state*);
|
||||
void (*map)(running_machine &machine, slot_state*, int page);
|
||||
void (*write)(running_machine &machine, slot_state*, UINT16, UINT8);
|
||||
int (*loadsram)(running_machine &machine, slot_state*);
|
||||
int (*savesram)(running_machine &machine, slot_state*);
|
||||
};
|
||||
|
||||
extern const msx_slot msx_slot_list[];
|
||||
|
||||
#define MSX_SLOT_START \
|
||||
const msx_slot msx_slot_list[] = {
|
||||
#define MSX_SLOT_ROM(type, ent) { \
|
||||
type, \
|
||||
MSX_MEM_ROM, \
|
||||
#type, \
|
||||
slot_##ent##_init, \
|
||||
slot_##ent##_reset, \
|
||||
slot_##ent##_map, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
NULL \
|
||||
},
|
||||
|
||||
#define MSX_SLOT_RAM(type, ent) { \
|
||||
type, \
|
||||
MSX_MEM_RAM, \
|
||||
#type, \
|
||||
slot_##ent##_init, \
|
||||
slot_##ent##_reset, \
|
||||
slot_##ent##_map, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
NULL \
|
||||
},
|
||||
|
||||
#define MSX_SLOT(type, ent) { \
|
||||
type, \
|
||||
MSX_MEM_HANDLER, \
|
||||
#type, \
|
||||
slot_##ent##_init, \
|
||||
slot_##ent##_reset, \
|
||||
slot_##ent##_map, \
|
||||
slot_##ent##_write, \
|
||||
NULL, \
|
||||
NULL \
|
||||
},
|
||||
|
||||
#define MSX_SLOT_SRAM(type, ent) { \
|
||||
type, \
|
||||
MSX_MEM_HANDLER, \
|
||||
#type, \
|
||||
slot_##ent##_init, \
|
||||
slot_##ent##_reset, \
|
||||
slot_##ent##_map, \
|
||||
slot_##ent##_write, \
|
||||
slot_##ent##_loadsram, \
|
||||
slot_##ent##_savesram \
|
||||
},
|
||||
|
||||
#define MSX_SLOT_NULL(type) { \
|
||||
type, \
|
||||
MSX_MEM_ROM, \
|
||||
#type, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
NULL \
|
||||
},
|
||||
|
||||
#define MSX_SLOT_END \
|
||||
{ SLOT_END, 0, "", NULL, NULL, NULL, NULL, NULL } \
|
||||
};
|
||||
|
||||
#define MSX_SLOT_INIT(nm) static int \
|
||||
slot_##nm##_init (running_machine &machine, slot_state *state, int page, UINT8 *mem, int size)
|
||||
#define MSX_SLOT_MAP(nm) \
|
||||
static void slot_##nm##_map (running_machine &machine, slot_state *state, int page)
|
||||
#define MSX_SLOT_WRITE(nm) \
|
||||
static void slot_##nm##_write (running_machine &machine, slot_state *state, UINT16 addr, UINT8 val)
|
||||
#define MSX_SLOT_RESET(nm) \
|
||||
static void slot_##nm##_reset (running_machine &machine, slot_state *state)
|
||||
#define MSX_SLOT_LOADSRAM(nm) \
|
||||
static int slot_##nm##_loadsram (running_machine &machine, slot_state *state)
|
||||
#define MSX_SLOT_SAVESRAM(nm) \
|
||||
static int slot_##nm##_savesram (running_machine &machine, slot_state *state)
|
||||
|
||||
|
||||
#endif /* MSX_SLOT_H_ */
|
@ -16,347 +16,9 @@
|
||||
#define VERBOSE 0
|
||||
|
||||
|
||||
static int msx_probe_type (UINT8* pmem, int size)
|
||||
{
|
||||
int kon4, kon5, asc8, asc16, i;
|
||||
|
||||
if (size <= 0x10000) return 0;
|
||||
|
||||
if ( (pmem[0x10] == 'Y') && (pmem[0x11] == 'Z') && (size > 0x18000) )
|
||||
return 6;
|
||||
|
||||
kon4 = kon5 = asc8 = asc16 = 0;
|
||||
|
||||
for (i=0;i<size-3;i++)
|
||||
{
|
||||
if (pmem[i] == 0x32 && pmem[i+1] == 0)
|
||||
{
|
||||
switch (pmem[i+2])
|
||||
{
|
||||
case 0x60:
|
||||
case 0x70:
|
||||
asc16++;
|
||||
asc8++;
|
||||
break;
|
||||
case 0x68:
|
||||
case 0x78:
|
||||
asc8++;
|
||||
asc16--;
|
||||
}
|
||||
|
||||
switch (pmem[i+2])
|
||||
{
|
||||
case 0x60:
|
||||
case 0x80:
|
||||
case 0xa0:
|
||||
kon4++;
|
||||
break;
|
||||
case 0x50:
|
||||
case 0x70:
|
||||
case 0x90:
|
||||
case 0xb0:
|
||||
kon5++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (MAX (kon4, kon5) > MAX (asc8, asc16) )
|
||||
return (kon5 > kon4) ? 2 : 3;
|
||||
else
|
||||
return (asc8 > asc16) ? 4 : 5;
|
||||
}
|
||||
|
||||
DEVICE_IMAGE_LOAD_MEMBER(msx_state,msx_cart)
|
||||
{
|
||||
int size;
|
||||
int size_aligned;
|
||||
UINT8 *mem;
|
||||
int type = -1;
|
||||
astring extra;
|
||||
char *sramfile;
|
||||
slot_state *st;
|
||||
int id = -1;
|
||||
|
||||
if (strcmp(image.device().tag(),":cart1")==0)
|
||||
id = 0;
|
||||
|
||||
if (strcmp(image.device().tag(),":cart2")==0)
|
||||
id = 1;
|
||||
|
||||
if( id == -1 )
|
||||
{
|
||||
//logerror ("error: invalid cart tag '%s'\n", image->tag);
|
||||
return IMAGE_INIT_FAIL;
|
||||
}
|
||||
|
||||
if ( image.software_entry() != NULL )
|
||||
{
|
||||
/* Load software from software list */
|
||||
/* TODO: Add proper SRAM (size) handling */
|
||||
|
||||
const char *mapper = image.get_feature("mapper");
|
||||
if (mapper != NULL)
|
||||
{
|
||||
static const struct { const char *mapper_name; int mapper_type; } mapper_types[] =
|
||||
{
|
||||
{ "NOMAPPER", SLOT_EMPTY },
|
||||
{ "M60002-0125SP", SLOT_ASCII8 },
|
||||
{ "LZ93A13", SLOT_ASCII8 },
|
||||
{ "NEOS MR6401", SLOT_ASCII8 },
|
||||
{ "BS6202", SLOT_ASCII8 },
|
||||
{ "BS6101", SLOT_ASCII8 },
|
||||
{ "M60002-0125SP-16", SLOT_ASCII16 },
|
||||
{ "LZ93A13-16", SLOT_ASCII16 },
|
||||
{ "BS6101-16", SLOT_ASCII16 },
|
||||
{ "MR6401", SLOT_ASCII16 },
|
||||
{ "CROSS-BLAIM", SLOT_CROSS_BLAIM },
|
||||
{ "GMASTER2", SLOT_GAMEMASTER2 },
|
||||
{ "80IN1", SLOT_KOREAN_80IN1 },
|
||||
{ "90IN1", SLOT_KOREAN_90IN1 },
|
||||
{ "126IN1", SLOT_KOREAN_126IN1 },
|
||||
{ "FM-PAC", SLOT_FMPAC },
|
||||
{ "IREM TAM-S1", SLOT_RTYPE },
|
||||
{ "KONAMI", SLOT_KONAMI },
|
||||
{ "KONAMI-SCC", SLOT_KONAMI_SCC },
|
||||
{ "SUPERLODE", SLOT_SUPERLODERUNNER },
|
||||
{ "MAJUTSUSHI", SLOT_MAJUTSUSHI },
|
||||
{ "DISK_ROM", SLOT_DISK_ROM },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAY_LENGTH(mapper_types) && type < 0; i++)
|
||||
{
|
||||
if (!core_stricmp(mapper, mapper_types[i].mapper_name))
|
||||
type = mapper_types[i].mapper_type;
|
||||
}
|
||||
|
||||
if (-1 == type)
|
||||
logerror("Mapper '%s' not recognized!\n", mapper);
|
||||
}
|
||||
|
||||
UINT8 *tmp_sram = image.get_software_region("sram");
|
||||
if (tmp_sram)
|
||||
{
|
||||
if (type == SLOT_ASCII8) type = SLOT_ASCII8_SRAM;
|
||||
if (type == SLOT_ASCII16) type = SLOT_ASCII16_SRAM;
|
||||
}
|
||||
|
||||
UINT8 *rom_region = image.get_software_region("rom");
|
||||
size = size_aligned = image.get_software_region_length("rom");
|
||||
|
||||
mem = auto_alloc_array(machine(), UINT8, size_aligned);
|
||||
memcpy(mem, rom_region, size_aligned);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Old style image loading */
|
||||
|
||||
size = image.length ();
|
||||
if (size < 0x2000)
|
||||
{
|
||||
logerror ("cart #%d: error: file is smaller than 2kb, too small to be true!\n", id);
|
||||
return IMAGE_INIT_FAIL;
|
||||
}
|
||||
|
||||
/* allocate memory and load */
|
||||
size_aligned = 0x2000;
|
||||
while (size_aligned < size)
|
||||
size_aligned *= 2;
|
||||
|
||||
mem = auto_alloc_array(machine(),UINT8,size_aligned);
|
||||
if (!mem)
|
||||
{
|
||||
logerror ("cart #%d: error: failed to allocate memory for cartridge\n", id);
|
||||
return IMAGE_INIT_FAIL;
|
||||
}
|
||||
|
||||
if (size < size_aligned)
|
||||
memset (mem, 0xff, size_aligned);
|
||||
|
||||
if (image.fread(mem, size) != size)
|
||||
{
|
||||
logerror ("cart #%d: %s: can't read full %d bytes\n", id, image.filename (), size);
|
||||
return IMAGE_INIT_FAIL;
|
||||
}
|
||||
|
||||
/* see if msx.crc will tell us more */
|
||||
if (!hashfile_extrainfo(image, extra))
|
||||
{
|
||||
logerror("cart #%d: warning: no information in crc file\n", id);
|
||||
type = -1;
|
||||
}
|
||||
else
|
||||
if ((1 != sscanf(extra.cstr(), "%d", &type) ) || type < 0 || type > SLOT_LAST_CARTRIDGE_TYPE)
|
||||
{
|
||||
logerror("cart #%d: warning: information in crc file not valid\n", id);
|
||||
type = -1;
|
||||
}
|
||||
else
|
||||
logerror ("cart #%d: info: cart extra info: '%s' = %s\n", id, extra.cstr(), msx_slot_list[type].name);
|
||||
|
||||
/* if not, attempt autodetection */
|
||||
if (type < 0)
|
||||
{
|
||||
type = msx_probe_type (mem, size);
|
||||
|
||||
if (mem[0] != 'A' || mem[1] != 'B')
|
||||
logerror("cart #%d: %s: May not be a valid ROM file\n", id, image.filename ());
|
||||
|
||||
logerror("cart #%d: Probed cartridge mapper %d/%s\n", id, type, msx_slot_list[type].name);
|
||||
}
|
||||
}
|
||||
|
||||
/* mapper type 0 always needs 64kB */
|
||||
if (!type && size_aligned != 0x10000)
|
||||
{
|
||||
UINT8 *old_mem = mem;
|
||||
int old_size_aligned = size_aligned;
|
||||
|
||||
size_aligned = 0x10000;
|
||||
mem = auto_alloc_array(machine(),UINT8, 0x10000);
|
||||
if (!mem)
|
||||
{
|
||||
auto_free(machine(),old_mem);
|
||||
logerror ("cart #%d: error: cannot allocate memory\n", id);
|
||||
return IMAGE_INIT_FAIL;
|
||||
}
|
||||
|
||||
if (size < 0x10000)
|
||||
memset (mem + size, 0xff, 0x10000 - size);
|
||||
|
||||
if (size > 0x10000)
|
||||
{
|
||||
logerror ("cart #%d: warning: rom truncated to 64kb due to mapperless type (possibly detected)\n", id);
|
||||
|
||||
size = 0x10000;
|
||||
}
|
||||
|
||||
/* Copy old contents to newly claimed memory */
|
||||
memcpy(mem,old_mem,old_size_aligned);
|
||||
auto_free(machine(),old_mem);
|
||||
}
|
||||
|
||||
/* mapper type 0 (ROM) might need moving around a bit */
|
||||
if (!type)
|
||||
{
|
||||
int i, page = 1;
|
||||
|
||||
/* find the correct page */
|
||||
if (mem[0] == 'A' && mem[1] == 'B')
|
||||
{
|
||||
for (i=2; i<=8; i += 2)
|
||||
{
|
||||
if (mem[i] || mem[i+1])
|
||||
{
|
||||
page = mem[i+1] / 0x40;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (size <= 0x4000)
|
||||
{
|
||||
if (page == 1 || page == 2)
|
||||
{
|
||||
/* copy to the respective page */
|
||||
memcpy (mem + (page * 0x4000), mem, 0x4000);
|
||||
memset (mem, 0xff, 0x4000);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* memory is repeated 4 times */
|
||||
page = -1;
|
||||
memcpy (mem + 0x4000, mem, 0x4000);
|
||||
memcpy (mem + 0x8000, mem, 0x4000);
|
||||
memcpy (mem + 0xc000, mem, 0x4000);
|
||||
}
|
||||
}
|
||||
else /*if (size <= 0xc000) */
|
||||
{
|
||||
if (page)
|
||||
{
|
||||
/* shift up 16kB; custom memcpy so overlapping memory isn't corrupted. ROM starts in page 1 (0x4000) */
|
||||
UINT8 *m;
|
||||
|
||||
page = 1;
|
||||
i = 0xc000; m = mem + 0xffff;
|
||||
while (i--)
|
||||
{
|
||||
*m = *(m - 0x4000);
|
||||
m--;
|
||||
}
|
||||
memset (mem, 0xff, 0x4000);
|
||||
}
|
||||
}
|
||||
|
||||
if (page)
|
||||
logerror ("cart #%d: info: rom in page %d\n", id, page);
|
||||
else
|
||||
logerror ("cart #%d: info: rom duplicted in all pages\n", id);
|
||||
}
|
||||
|
||||
/* kludge */
|
||||
if (type == 0)
|
||||
type = SLOT_ROM;
|
||||
|
||||
/* allocate and set slot_state for this cartridge */
|
||||
st = auto_alloc(machine(),slot_state);
|
||||
if (!st)
|
||||
{
|
||||
logerror ("cart #%d: error: cannot allocate memory for cartridge state\n", id);
|
||||
return IMAGE_INIT_FAIL;
|
||||
}
|
||||
memset (st, 0, sizeof (slot_state));
|
||||
|
||||
st->m_type = type;
|
||||
sramfile = auto_alloc_array(machine(), char, strlen (image.filename ()) + 1);
|
||||
|
||||
if (sramfile)
|
||||
{
|
||||
char *ext;
|
||||
|
||||
strcpy (sramfile, image.basename ());
|
||||
ext = strrchr (sramfile, '.');
|
||||
if (ext)
|
||||
*ext = 0;
|
||||
|
||||
st->m_sramfile = sramfile;
|
||||
}
|
||||
|
||||
if (msx_slot_list[type].init (machine(), st, 0, mem, size_aligned))
|
||||
return IMAGE_INIT_FAIL;
|
||||
|
||||
if (msx_slot_list[type].loadsram)
|
||||
msx_slot_list[type].loadsram (machine(), st);
|
||||
|
||||
m_cart_state[id] = st;
|
||||
msx_memory_set_carts();
|
||||
|
||||
return IMAGE_INIT_PASS;
|
||||
}
|
||||
|
||||
DEVICE_IMAGE_UNLOAD_MEMBER(msx_state, msx_cart)
|
||||
{
|
||||
int id = -1;
|
||||
|
||||
if (strcmp(image.device().tag(),":cart1")==0)
|
||||
id = 0;
|
||||
|
||||
if (strcmp(image.device().tag(),":cart2")==0)
|
||||
id = 1;
|
||||
|
||||
if( id == -1 )
|
||||
{
|
||||
//logerror ("error: invalid cart tag '%s'\n", image->tag);
|
||||
return;
|
||||
}
|
||||
|
||||
if (msx_slot_list[m_cart_state[id]->m_type].savesram)
|
||||
msx_slot_list[m_cart_state[id]->m_type].savesram (machine(), m_cart_state[id]);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(msx_state::msx_vdp_interrupt)
|
||||
{
|
||||
m_maincpu->set_input_line(0, (state ? HOLD_LINE : CLEAR_LINE));
|
||||
m_maincpu->set_input_line(0, (state ? ASSERT_LINE : CLEAR_LINE));
|
||||
}
|
||||
|
||||
void msx_state::msx_ch_reset_core ()
|
||||
@ -373,7 +35,6 @@ MACHINE_START_MEMBER(msx_state,msx)
|
||||
MACHINE_START_MEMBER(msx_state,msx2)
|
||||
{
|
||||
m_port_c_old = 0xff;
|
||||
m_dsk_stat = 0x3f;
|
||||
}
|
||||
|
||||
MACHINE_RESET_MEMBER(msx_state,msx)
|
||||
@ -612,16 +273,6 @@ WRITE8_MEMBER(msx_state::msx_psg_port_b_w)
|
||||
m_psg_b = data;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( msx_state::msx_fmpac_w )
|
||||
{
|
||||
if (m_opll_active)
|
||||
{
|
||||
if (offset == 1)
|
||||
m_ym->write(space, 1, data);
|
||||
else
|
||||
m_ym->write(space, 0, data);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RTC functions
|
||||
@ -642,53 +293,6 @@ READ8_MEMBER( msx_state::msx_rtc_reg_r )
|
||||
return m_rtc->read(space, m_rtc_latch);
|
||||
}
|
||||
|
||||
/*
|
||||
From: erbo@xs4all.nl (erik de boer)
|
||||
|
||||
sony and philips have used (almost) the same design
|
||||
and this is the memory layout
|
||||
but it is not a msx standard !
|
||||
|
||||
WD1793 or wd2793 registers
|
||||
|
||||
address
|
||||
|
||||
7FF8H read status register
|
||||
write command register
|
||||
7FF9H r/w track register (r/o on NMS 8245 and Sony)
|
||||
7FFAH r/w sector register (r/o on NMS 8245 and Sony)
|
||||
7FFBH r/w data register
|
||||
|
||||
|
||||
hardware registers
|
||||
|
||||
address
|
||||
|
||||
7FFCH r/w bit 0 side select
|
||||
7FFDH r/w b7>M-on , b6>in-use , b1>ds1 , b0>ds0 (all neg. logic)
|
||||
7FFEH not used
|
||||
7FFFH read b7>drq , b6>intrq
|
||||
|
||||
set on 7FFDH bit 2 always to 0 (some use it as disk change reset)
|
||||
|
||||
*/
|
||||
|
||||
WRITE_LINE_MEMBER( msx_state::msx_wd179x_intrq_w )
|
||||
{
|
||||
if (state)
|
||||
m_dsk_stat &= ~0x40;
|
||||
else
|
||||
m_dsk_stat |= 0x40;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( msx_state::msx_wd179x_drq_w )
|
||||
{
|
||||
if (state)
|
||||
m_dsk_stat &= ~0x80;
|
||||
else
|
||||
m_dsk_stat |= 0x80;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** The PPI functions
|
||||
@ -705,7 +309,7 @@ WRITE8_MEMBER( msx_state::msx_ppi_port_a_w )
|
||||
|
||||
WRITE8_MEMBER( msx_state::msx_ppi_port_c_w )
|
||||
{
|
||||
keylatch = data & 0x0f;
|
||||
m_keylatch = data & 0x0f;
|
||||
|
||||
/* caps lock */
|
||||
if ( BIT(m_port_c_old ^ data, 6) )
|
||||
@ -732,7 +336,7 @@ READ8_MEMBER( msx_state::msx_ppi_port_b_r )
|
||||
int row, data;
|
||||
ioport_port *keynames[] = { m_io_key0, m_io_key1, m_io_key2, m_io_key3, m_io_key4, m_io_key5 };
|
||||
|
||||
row = keylatch;
|
||||
row = m_keylatch;
|
||||
if (row <= 10)
|
||||
{
|
||||
data = keynames[row / 2]->read();
|
||||
@ -750,198 +354,65 @@ READ8_MEMBER( msx_state::msx_ppi_port_b_r )
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
void msx_state::install_slot_pages(device_t &owner, UINT8 prim, UINT8 sec, UINT8 page, UINT8 numpages, device_t *device)
|
||||
{
|
||||
msx_state &msx = downcast<msx_state &>(owner);
|
||||
msx_internal_slot_interface *internal_slot = dynamic_cast<msx_internal_slot_interface *>(device);
|
||||
|
||||
for ( int i = page; i < MIN(page + numpages, 4); i++ )
|
||||
{
|
||||
msx.m_all_slots[prim][sec][i] = internal_slot;
|
||||
}
|
||||
if ( sec )
|
||||
{
|
||||
msx.m_slot_expanded[prim] = true;
|
||||
}
|
||||
}
|
||||
|
||||
void msx_state::msx_memory_init()
|
||||
{
|
||||
int prim, sec, page, extent, option;
|
||||
int size = 0;
|
||||
const msx_slot_layout *layout= (msx_slot_layout*)NULL;
|
||||
const msx_slot *slot;
|
||||
slot_state *st;
|
||||
UINT8 *mem = NULL;
|
||||
int count_populated_pages = 0;
|
||||
|
||||
if ( m_layout == NULL ) {
|
||||
fatalerror("No msx slot layout defined for this system!\n");
|
||||
}
|
||||
|
||||
m_empty = auto_alloc_array(machine(), UINT8, 0x4000);
|
||||
memset (m_empty, 0xff, 0x4000);
|
||||
|
||||
for (prim=0; prim<4; prim++) {
|
||||
for (sec=0; sec<4; sec++) {
|
||||
for (page=0; page<4; page++) {
|
||||
m_all_state[prim][sec][page]= (slot_state*)NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (layout = m_layout; layout->entry != MSX_LAYOUT_LAST; layout++) {
|
||||
switch (layout->entry) {
|
||||
case MSX_LAYOUT_SLOT_ENTRY:
|
||||
prim = layout->slot_primary;
|
||||
sec = layout->slot_secondary;
|
||||
page = layout->slot_page;
|
||||
extent = layout->page_extent;
|
||||
|
||||
if (layout->slot_secondary) {
|
||||
m_slot_expanded[layout->slot_primary]= TRUE;
|
||||
}
|
||||
|
||||
slot = &msx_slot_list[layout->type];
|
||||
if (slot->slot_type != layout->type) {
|
||||
logerror ("internal error: msx_slot_list[%d].type != %d\n",
|
||||
slot->slot_type, slot->slot_type);
|
||||
}
|
||||
|
||||
size = layout->size;
|
||||
option = layout->option;
|
||||
|
||||
if (layout->type != SLOT_CARTRIDGE1 && layout->type != SLOT_CARTRIDGE2)
|
||||
// Populate all unpopulated slots with the dummy interface
|
||||
for ( int prim = 0; prim < 4; prim++ )
|
||||
{
|
||||
for ( int sec = 0; sec < 4; sec++ )
|
||||
{
|
||||
for ( int page = 0; page < 4; page++ )
|
||||
{
|
||||
int size_tmp = 0;
|
||||
if (size < 0x4000)
|
||||
size_tmp = 0x4000;
|
||||
else if (size > 0x10000)
|
||||
size_tmp = 0x10000;
|
||||
if ( m_all_slots[prim][sec][page] == NULL )
|
||||
{
|
||||
m_all_slots[prim][sec][page] = &m_empty_slot;
|
||||
}
|
||||
else
|
||||
size_tmp = size;
|
||||
int extent_tmp = size_tmp / 0x4000;
|
||||
if (extent_tmp != extent)
|
||||
fatalerror("incorrect MSX_LAYOUT_SLOT configuration - expected extent %d but found %d\n", extent, extent_tmp);
|
||||
}
|
||||
|
||||
if (VERBOSE)
|
||||
{
|
||||
logerror ("slot %d/%d/%d-%d: type %s, size 0x%x\n",
|
||||
prim, sec, page, page + extent - 1, slot->name, size);
|
||||
}
|
||||
|
||||
st = (slot_state*)NULL;
|
||||
if (layout->type == SLOT_CARTRIDGE1) {
|
||||
st = m_cart_state[0];
|
||||
if (!st) {
|
||||
slot = &msx_slot_list[SLOT_SOUNDCARTRIDGE];
|
||||
size = 0x20000;
|
||||
{
|
||||
count_populated_pages++;
|
||||
}
|
||||
}
|
||||
if (layout->type == SLOT_CARTRIDGE2) {
|
||||
st = m_cart_state[1];
|
||||
if (!st) {
|
||||
/* Check whether the optional FM-PAC rom is present */
|
||||
option = 0x10000;
|
||||
size = 0x10000;
|
||||
mem = m_region_maincpu->base() + option;
|
||||
if (m_region_maincpu->bytes() >= size + option && mem[0] == 'A' && mem[1] == 'B') {
|
||||
slot = &msx_slot_list[SLOT_FMPAC];
|
||||
}
|
||||
else {
|
||||
slot = &msx_slot_list[SLOT_EMPTY];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!st) {
|
||||
switch (slot->mem_type) {
|
||||
case MSX_MEM_HANDLER:
|
||||
case MSX_MEM_ROM:
|
||||
mem = m_region_maincpu->base() + option;
|
||||
break;
|
||||
case MSX_MEM_RAM:
|
||||
mem = NULL;
|
||||
break;
|
||||
}
|
||||
st = auto_alloc_clear (machine(), slot_state);
|
||||
memset (st, 0, sizeof (slot_state));
|
||||
|
||||
if (slot->init (machine(), st, layout->slot_page, mem, size)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
while (extent--) {
|
||||
if (page > 3) {
|
||||
logerror ("internal error: msx_slot_layout wrong, "
|
||||
"page + extent > 3\n");
|
||||
break;
|
||||
}
|
||||
m_all_state[prim][sec][page] = st;
|
||||
page++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( count_populated_pages == 0 ) {
|
||||
fatalerror("No msx slot layout defined for this system!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void msx_state::msx_memory_reset ()
|
||||
{
|
||||
slot_state *st, *last_st = (slot_state*)NULL;
|
||||
int prim, sec, page;
|
||||
|
||||
m_primary_slot = 0;
|
||||
|
||||
for (prim=0; prim<4; prim++)
|
||||
for (int prim=0; prim<4; prim++)
|
||||
{
|
||||
m_secondary_slot[prim] = 0;
|
||||
for (sec=0; sec<4; sec++)
|
||||
{
|
||||
for (page=0; page<4; page++)
|
||||
{
|
||||
st = m_all_state[prim][sec][page];
|
||||
if (st && st != last_st)
|
||||
msx_slot_list[st->m_type].reset (machine(), st);
|
||||
last_st = st;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void msx_state::msx_memory_set_carts()
|
||||
{
|
||||
const msx_slot_layout *layout;
|
||||
int page;
|
||||
|
||||
if (!m_layout)
|
||||
return;
|
||||
|
||||
for (layout = m_layout; layout->entry != MSX_LAYOUT_LAST; layout++)
|
||||
{
|
||||
if (layout->entry == MSX_LAYOUT_SLOT_ENTRY)
|
||||
{
|
||||
switch (layout->type)
|
||||
{
|
||||
case SLOT_CARTRIDGE1:
|
||||
for (page=0; page<4; page++)
|
||||
m_all_state[layout->slot_primary][layout->slot_secondary][page]
|
||||
= m_cart_state[0];
|
||||
break;
|
||||
case SLOT_CARTRIDGE2:
|
||||
for (page=0; page<4; page++)
|
||||
m_all_state[layout->slot_primary][layout->slot_secondary][page]
|
||||
= m_cart_state[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void msx_state::msx_memory_map_page (UINT8 page)
|
||||
{
|
||||
int slot_primary;
|
||||
int slot_secondary;
|
||||
slot_state *st;
|
||||
const msx_slot *slot;
|
||||
int slot_primary = (m_primary_slot >> (page * 2)) & 3;
|
||||
int slot_secondary = (m_secondary_slot[slot_primary] >> (page * 2)) & 3;
|
||||
|
||||
slot_primary = (m_primary_slot >> (page * 2)) & 3;
|
||||
slot_secondary = (m_secondary_slot[slot_primary] >> (page * 2)) & 3;
|
||||
|
||||
st = m_all_state[slot_primary][slot_secondary][page];
|
||||
slot = st ? &msx_slot_list[st->m_type] : &msx_slot_list[SLOT_EMPTY];
|
||||
m_state[page] = st;
|
||||
m_slot[page] = slot;
|
||||
|
||||
if (VERBOSE)
|
||||
logerror ("mapping %s in %d/%d/%d\n", slot->name, slot_primary, slot_secondary, page);
|
||||
|
||||
slot->map (machine(), st, page);
|
||||
m_current_page[page] = m_all_slots[slot_primary][slot_secondary][page];
|
||||
}
|
||||
|
||||
void msx_state::msx_memory_map_all ()
|
||||
@ -950,94 +421,14 @@ void msx_state::msx_memory_map_all ()
|
||||
msx_memory_map_page (i);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( msx_state::msx_page0_w )
|
||||
READ8_MEMBER( msx_state::msx_mem_read )
|
||||
{
|
||||
if ( offset == 0 )
|
||||
{
|
||||
m_superloderunner_bank = data;
|
||||
if (m_slot[2]->slot_type == SLOT_SUPERLODERUNNER)
|
||||
m_slot[2]->map (machine(), m_state[2], 2);
|
||||
}
|
||||
|
||||
switch (m_slot[0]->mem_type)
|
||||
{
|
||||
case MSX_MEM_RAM:
|
||||
m_ram_pages[0][offset] = data;
|
||||
break;
|
||||
case MSX_MEM_HANDLER:
|
||||
m_slot[0]->write (machine(), m_state[0], offset, data);
|
||||
}
|
||||
return m_current_page[offset >> 14]->read(space, offset);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( msx_state::msx_page0_1_w )
|
||||
WRITE8_MEMBER( msx_state::msx_mem_write )
|
||||
{
|
||||
msx_page0_w( space, 0x2000 + offset, data );
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( msx_state::msx_page1_w )
|
||||
{
|
||||
switch (m_slot[1]->mem_type)
|
||||
{
|
||||
case MSX_MEM_RAM:
|
||||
m_ram_pages[1][offset] = data;
|
||||
break;
|
||||
case MSX_MEM_HANDLER:
|
||||
m_slot[1]->write (machine(), m_state[1], 0x4000 + offset, data);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( msx_state::msx_page1_1_w )
|
||||
{
|
||||
msx_page1_w( space, 0x2000 + offset, data );
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( msx_state::msx_page1_2_w )
|
||||
{
|
||||
msx_page1_w( space, 0x3ff8 + offset, data );
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( msx_state::msx_page2_w )
|
||||
{
|
||||
switch (m_slot[2]->mem_type)
|
||||
{
|
||||
case MSX_MEM_RAM:
|
||||
m_ram_pages[2][offset] = data;
|
||||
break;
|
||||
case MSX_MEM_HANDLER:
|
||||
m_slot[2]->write (machine(), m_state[2], 0x8000 + offset, data);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( msx_state::msx_page2_1_w )
|
||||
{
|
||||
msx_page2_w( space, 0x1800 + offset, data );
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( msx_state::msx_page2_2_w )
|
||||
{
|
||||
msx_page2_w( space, 0x2000 + offset, data );
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( msx_state::msx_page2_3_w )
|
||||
{
|
||||
msx_page2_w( space, 0x3800 + offset, data );
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( msx_state::msx_page3_w )
|
||||
{
|
||||
switch (m_slot[3]->mem_type)
|
||||
{
|
||||
case MSX_MEM_RAM:
|
||||
m_ram_pages[3][offset] = data;
|
||||
break;
|
||||
case MSX_MEM_HANDLER:
|
||||
m_slot[3]->write (machine(), m_state[3], 0xc000 + offset, data);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( msx_state::msx_page3_1_w )
|
||||
{
|
||||
msx_page3_w( space, 0x2000 + offset, data );
|
||||
m_current_page[offset >> 14]->write(space, offset, data);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( msx_state::msx_sec_slot_w )
|
||||
@ -1052,42 +443,21 @@ WRITE8_MEMBER( msx_state::msx_sec_slot_w )
|
||||
msx_memory_map_all ();
|
||||
}
|
||||
else
|
||||
msx_page3_w(space, 0x3fff, data);
|
||||
m_current_page[3]->write(space, 0xffff, data);
|
||||
}
|
||||
|
||||
READ8_MEMBER( msx_state::msx_sec_slot_r )
|
||||
{
|
||||
UINT8 result;
|
||||
int slot = m_primary_slot >> 6;
|
||||
|
||||
if (m_slot_expanded[slot])
|
||||
result = ~m_secondary_slot[slot];
|
||||
{
|
||||
return ~m_secondary_slot[slot];
|
||||
}
|
||||
else
|
||||
result = m_top_page[0x1fff];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( msx_state::msx_ram_mapper_w )
|
||||
{
|
||||
m_ram_mapper[offset] = data;
|
||||
if (m_slot[offset]->slot_type == SLOT_RAM_MM)
|
||||
m_slot[offset]->map (machine(), m_state[offset], offset);
|
||||
}
|
||||
|
||||
READ8_MEMBER( msx_state::msx_ram_mapper_r )
|
||||
{
|
||||
return m_ram_mapper[offset] | m_ramio_set_bits;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( msx_state::msx_90in1_w )
|
||||
{
|
||||
m_korean90in1_bank = data;
|
||||
if (m_slot[1]->slot_type == SLOT_KOREAN_90IN1)
|
||||
m_slot[1]->map (machine(), m_state[1], 1);
|
||||
|
||||
if (m_slot[2]->slot_type == SLOT_KOREAN_90IN1)
|
||||
m_slot[2]->map (machine(), m_state[2], 2);
|
||||
{
|
||||
return m_current_page[3]->read(space, 0xffff);
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER( msx_state::msx_kanji_r )
|
||||
@ -1112,3 +482,24 @@ WRITE8_MEMBER( msx_state::msx_kanji_w )
|
||||
else
|
||||
m_kanji_latch = (m_kanji_latch & 0x1f800) | ((data & 0x3f) << 5);
|
||||
}
|
||||
|
||||
READ8_MEMBER( msx_state::msx_switched_r )
|
||||
{
|
||||
// Read from selected switched device
|
||||
return this->space().read_byte( (m_current_switched_device << 8) | offset );
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( msx_state::msx_switched_w )
|
||||
{
|
||||
if (offset == 0)
|
||||
{
|
||||
// Select switched device
|
||||
m_current_switched_device = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write to selected switched device
|
||||
this->space().write_byte( (m_current_switched_device << 8) | offset, data );
|
||||
}
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -589,6 +589,7 @@ BUSES += KC
|
||||
BUSES += MACPDS
|
||||
BUSES += MIDI
|
||||
BUSES += MEGADRIVE
|
||||
BUSES += MSX_SLOT
|
||||
BUSES += NES
|
||||
BUSES += NUBUS
|
||||
BUSES += ORICEXT
|
||||
@ -1002,7 +1003,9 @@ $(MESSOBJ)/arcadia.a: \
|
||||
$(MESSOBJ)/ascii.a: \
|
||||
$(MESS_DRIVERS)/msx.o \
|
||||
$(MESS_MACHINE)/msx.o \
|
||||
$(MESS_MACHINE)/msx_slot.o \
|
||||
$(MESS_MACHINE)/msx_switched.o \
|
||||
$(MESS_MACHINE)/msx_matsushita.o \
|
||||
$(MESS_MACHINE)/msx_s1985.o \
|
||||
|
||||
$(MESSOBJ)/at.a: \
|
||||
$(MESS_MACHINE)/at.o \
|
||||
|
Loading…
Reference in New Issue
Block a user