mirror of
https://github.com/holub/mame
synced 2025-04-19 23:12:11 +03:00
(MESS) snes.c: several updates to cart handling [Fabio Priuli]
- moved Sufami Turbo and BSX carts to separate lists - added two new drivers snesnew and snespnew, using slot devices for carts - added emulation for DSP1/4, ST-010/011, S-DD1, SPC7110, SuperFX, BS-X and Sufami Turbo as slot devices - added emulation for the protection device used in some pirate carts out of whatsnew. there are one or two (possibly stupid) bugs in the new drivers causing glitches in several games (e.g. SameGame, or F1 ROC 2) which prevent us from removing the fake driver clones with add-on CPUs. if anyone is willing to help to trace them, you're all welcome.
This commit is contained in:
parent
66f93718fc
commit
969074c41e
20
.gitattributes
vendored
20
.gitattributes
vendored
@ -222,6 +222,8 @@ hash/sgx.xml svneol=native#text/xml
|
||||
hash/smc777.xml svneol=native#text/xml
|
||||
hash/sms.xml svneol=native#text/xml
|
||||
hash/snes.xml svneol=native#text/xml
|
||||
hash/snes_bspack.xml svneol=native#text/xml
|
||||
hash/snes_strom.xml svneol=native#text/xml
|
||||
hash/socrates.xml svneol=native#text/xml
|
||||
hash/softwarelist.dtd svneol=native#text/plain
|
||||
hash/sorcerer_cart.xml svneol=native#text/xml
|
||||
@ -7475,6 +7477,24 @@ src/mess/machine/smc92x4.h svneol=native#text/plain
|
||||
src/mess/machine/sms.c svneol=native#text/plain
|
||||
src/mess/machine/snescart.c svneol=native#text/plain
|
||||
src/mess/machine/snescart.h svneol=native#text/plain
|
||||
src/mess/machine/sns_bsx.c svneol=native#text/plain
|
||||
src/mess/machine/sns_bsx.h svneol=native#text/plain
|
||||
src/mess/machine/sns_rom.c svneol=native#text/plain
|
||||
src/mess/machine/sns_rom.h svneol=native#text/plain
|
||||
src/mess/machine/sns_rom21.c svneol=native#text/plain
|
||||
src/mess/machine/sns_rom21.h svneol=native#text/plain
|
||||
src/mess/machine/sns_sdd1.c svneol=native#text/plain
|
||||
src/mess/machine/sns_sdd1.h svneol=native#text/plain
|
||||
src/mess/machine/sns_sfx.c svneol=native#text/plain
|
||||
src/mess/machine/sns_sfx.h svneol=native#text/plain
|
||||
src/mess/machine/sns_slot.c svneol=native#text/plain
|
||||
src/mess/machine/sns_slot.h svneol=native#text/plain
|
||||
src/mess/machine/sns_spc7110.c svneol=native#text/plain
|
||||
src/mess/machine/sns_spc7110.h svneol=native#text/plain
|
||||
src/mess/machine/sns_sufami.c svneol=native#text/plain
|
||||
src/mess/machine/sns_sufami.h svneol=native#text/plain
|
||||
src/mess/machine/sns_upd.c svneol=native#text/plain
|
||||
src/mess/machine/sns_upd.h svneol=native#text/plain
|
||||
src/mess/machine/softbox.c svneol=native#text/plain
|
||||
src/mess/machine/softbox.h svneol=native#text/plain
|
||||
src/mess/machine/sonydriv.c svneol=native#text/plain
|
||||
|
10332
hash/snes.xml
10332
hash/snes.xml
File diff suppressed because it is too large
Load Diff
3185
hash/snes_bspack.xml
Normal file
3185
hash/snes_bspack.xml
Normal file
File diff suppressed because it is too large
Load Diff
214
hash/snes_strom.xml
Normal file
214
hash/snes_strom.xml
Normal file
@ -0,0 +1,214 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE softwarelist SYSTEM "softwarelist.dtd">
|
||||
|
||||
<softwarelist name="snes_strom" description="Nintendo SNES - Sufami Turbo cartridges">
|
||||
|
||||
<software name="stbattlu" supported="no">
|
||||
<description>SD Ultra Battle - Ultraman Densetsu (Jpn)</description>
|
||||
<year>1996</year>
|
||||
<publisher>Bandai</publisher>
|
||||
<info name="serial" value="SFT-0101-JPN" />
|
||||
<info name="release" value="19960628" />
|
||||
<info name="alt_title" value="SDウルトラバトル ウルトラマン伝 説" />
|
||||
<part name="cart" interface="st_cart">
|
||||
|
||||
<feature name="slot" value="strom" />
|
||||
<dataarea name="rom" size="524288">
|
||||
<rom name="sd ultra battle - ultraman densetsu (japan).st" size="524288" crc="04939d14" sha1="5527fcc136ff0c0ef53a1c9c2756d4a27afa1526" offset="0x000000" />
|
||||
</dataarea>
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<software name="stbattl7" supported="no">
|
||||
<description>SD Ultra Battle - Seven Densetsu (Jpn)</description>
|
||||
<year>1996</year>
|
||||
<publisher>Bandai</publisher>
|
||||
<info name="serial" value="SFT-0102-JPN" />
|
||||
<info name="release" value="19960628" />
|
||||
<info name="alt_title" value="SDウルトラバトル セブン伝説" />
|
||||
<part name="cart" interface="st_cart">
|
||||
|
||||
<feature name="slot" value="strom" />
|
||||
<dataarea name="rom" size="524288">
|
||||
<rom name="sd ultra battle - seven densetsu (japan).st" size="524288" crc="43ad5a45" sha1="bfe85a6e6e8c24584ed5983dbf56048c4c8f2287" offset="0x000000" />
|
||||
</dataarea>
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<software name="stpoipoi" supported="no">
|
||||
<description>Poi Poi Ninja World (Jpn)</description>
|
||||
<year>1996</year>
|
||||
<publisher>Bandai</publisher>
|
||||
<info name="serial" value="SFT-0103-JPN" />
|
||||
<info name="release" value="19960628" />
|
||||
<info name="alt_title" value="ぽいぽい忍者ワールト" />
|
||||
<part name="cart" interface="st_cart">
|
||||
|
||||
<feature name="slot" value="strom" />
|
||||
<dataarea name="rom" size="524288">
|
||||
<rom name="poi poi ninja world (japan).st" size="524288" crc="32b2b3dd" sha1="ae7421b87a9f4cc7c189680dfbb39453905aa5e6" offset="0x000000" />
|
||||
</dataarea>
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<software name="stsdguni" supported="no">
|
||||
<description>SD Gundam Generation - Ichinen Sensouki (Jpn)</description>
|
||||
<year>1996</year>
|
||||
<publisher>Bandai</publisher>
|
||||
<info name="serial" value="SFT-0104-JPN" />
|
||||
<info name="release" value="19960726" />
|
||||
<info name="alt_title" value="SDガンダムジェネレーション一年戦争記" />
|
||||
<part name="cart" interface="st_cart">
|
||||
|
||||
<feature name="slot" value="strom" />
|
||||
<dataarea name="rom" size="524288">
|
||||
<rom name="sd gundam generation - ichinen sensouki (japan).st" size="524288" crc="afd74dcb" sha1="adc7716a4b081aba5cde3525881c51ee6d600396" offset="0x000000" />
|
||||
</dataarea>
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<software name="stsdgung" supported="no">
|
||||
<description>SD Gundam Generation - Gryps Senki (Jpn)</description>
|
||||
<year>1996</year>
|
||||
<publisher>Bandai</publisher>
|
||||
<info name="serial" value="SFT-0105-JPN" />
|
||||
<info name="release" value="19960726" />
|
||||
<info name="alt_title" value="SDガンダムジェネレーション グリプス戦記" />
|
||||
<part name="cart" interface="st_cart">
|
||||
|
||||
<feature name="slot" value="strom" />
|
||||
<dataarea name="rom" size="524288">
|
||||
<rom name="sd gundam generation - gryps senki (japan).st" size="524288" crc="48ecae44" sha1="f280004dd92b70b1bf4518e054b4181a9bbba245" offset="0x000000" />
|
||||
</dataarea>
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<software name="stgegege" supported="no">
|
||||
<description>GeGeGe no Kitarou - Youkai Donjara (Jpn)</description>
|
||||
<year>1996</year>
|
||||
<publisher>Bandai</publisher>
|
||||
<info name="serial" value="SFT-0106-JPN" />
|
||||
<info name="release" value="19960719" />
|
||||
<info name="alt_title" value="ゲゲゲの鬼太郎 妖怪ドンジャラ" />
|
||||
<part name="cart" interface="st_cart">
|
||||
|
||||
<feature name="slot" value="strom" />
|
||||
<dataarea name="rom" size="524288">
|
||||
<rom name="gegege no kitarou - youkai donjara (japan).st" size="524288" crc="4296500d" sha1="965b2582b13ee361eca93937b1b093049bc8d958" offset="0x000000" />
|
||||
</dataarea>
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<software name="stsdguna" supported="no">
|
||||
<description>SD Gundam Generation - Axis Senki (Jpn)</description>
|
||||
<year>1996</year>
|
||||
<publisher>Bandai</publisher>
|
||||
<info name="serial" value="SFT-0107-JPN" />
|
||||
<info name="release" value="19960823" />
|
||||
<info name="alt_title" value="SDガンダムジェネレーション アクシズ戦記" />
|
||||
<part name="cart" interface="st_cart">
|
||||
|
||||
<feature name="slot" value="strom" />
|
||||
<dataarea name="rom" size="524288">
|
||||
<rom name="sd gundam generation - axis senki (japan).st" size="524288" crc="72b4235f" sha1="6f5be110a606f34bb797a30c1f07b84b2ff38425" offset="0x000000" />
|
||||
</dataarea>
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<software name="stsdgunb" supported="no">
|
||||
<description>SD Gundam Generation - Babylonia Kenkoku Senki (Jpn)</description>
|
||||
<year>1996</year>
|
||||
<publisher>Bandai</publisher>
|
||||
<info name="serial" value="SFT-0108-JPN" />
|
||||
<info name="release" value="19960823" />
|
||||
<info name="alt_title" value="SDガンダムジェネレーション バヒロニア建国戦記" />
|
||||
<part name="cart" interface="st_cart">
|
||||
|
||||
<feature name="slot" value="strom" />
|
||||
<dataarea name="rom" size="524288">
|
||||
<rom name="sd gundam generation - babylonia kenkoku senki (japan).st" size="524288" crc="792d884c" sha1="f18f680b981077cfa025161cfe6c9594b6d18078" offset="0x000000" />
|
||||
</dataarea>
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<software name="stcarrng" supported="no">
|
||||
<description>Gekisou Sentai Carranger - Zenkai! Racer Senshi (Jpn)</description>
|
||||
<year>1996</year>
|
||||
<publisher>Bandai</publisher>
|
||||
<info name="serial" value="SFT-0109-JPN" />
|
||||
<info name="release" value="19960823" />
|
||||
<info name="alt_title" value="激走戦隊カーレンジャー 全開!レー サー戦士" />
|
||||
<part name="cart" interface="st_cart">
|
||||
|
||||
<feature name="slot" value="strom" />
|
||||
<dataarea name="rom" size="524288">
|
||||
<rom name="gekisou sentai carranger - zenkai! racer senshi (japan).st" size="524288" crc="14c66fca" sha1="50b9d6ebf0e3f4b9dad5d0660d6c834820cbe391" offset="0x000000" />
|
||||
</dataarea>
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<software name="stsdgunz" supported="no">
|
||||
<description>SD Gundam Generation - Zanscare Senki (Jpn)</description>
|
||||
<year>1996</year>
|
||||
<publisher>Bandai</publisher>
|
||||
<info name="serial" value="SFT-0110-JPN" />
|
||||
<info name="release" value="19960927" />
|
||||
<info name="alt_title" value="SDガンダムジェネレーション ザン スカール戦記" />
|
||||
<part name="cart" interface="st_cart">
|
||||
|
||||
<feature name="slot" value="strom" />
|
||||
<dataarea name="rom" size="524288">
|
||||
<rom name="sd gundam generation - zanscare senki (japan).st" size="524288" crc="efd3a865" sha1="d0ebe3cfcc76ec275151c3b9392fc2ff5d3b50da" offset="0x000000" />
|
||||
</dataarea>
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<software name="stsdgunc" supported="no">
|
||||
<description>SD Gundam Generation - Colony Kakutouki (Jpn)</description>
|
||||
<year>1996</year>
|
||||
<publisher>Bandai</publisher>
|
||||
<info name="serial" value="SFT-0111-JPN" />
|
||||
<info name="release" value="19960927" />
|
||||
<info name="alt_title" value="SDガンダムジェネレーション コロ ニー格闘記" />
|
||||
<part name="cart" interface="st_cart">
|
||||
|
||||
<feature name="slot" value="strom" />
|
||||
<dataarea name="rom" size="524288">
|
||||
<rom name="sd gundam generation - colony kakutouki (japan).st" size="524288" crc="c5dfa8fd" sha1="0a335ef645d058c2da5389ad622c62d0bffce944" offset="0x000000" />
|
||||
</dataarea>
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<software name="sailrfp2" supported="no">
|
||||
<description>Bishoujo Senshi Sailormoon Sailorstars - Fuwafuwa Panic 2 (Jpn)</description>
|
||||
<year>1996</year>
|
||||
<publisher>Bandai</publisher>
|
||||
<info name="serial" value="SFT-0112-JPN" />
|
||||
<info name="release" value="19960927" />
|
||||
<info name="alt_title" value="美少女戦士セーラームーン セー ラースターズ ~ふわふわパニック2" />
|
||||
<part name="cart" interface="st_cart">
|
||||
|
||||
<feature name="slot" value="strom" />
|
||||
<dataarea name="rom" size="1048576">
|
||||
<rom name="bishoujo senshi sailormoon sailorstars - fuwafuwa panic 2 (japan).st" size="1048576" crc="bb5c4238" sha1="f72ea67468cf34360042bdd7974fd588a2407566" offset="0x000000" />
|
||||
</dataarea>
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<software name="stcrayon" supported="no">
|
||||
<description>Crayon Shin-chan - Nagagutsu Dobon!! (Jpn)</description>
|
||||
<year>1996</year>
|
||||
<publisher>Bandai</publisher>
|
||||
<info name="serial" value="SFT-0113-JPN" />
|
||||
<info name="release" value="19960927" />
|
||||
<info name="alt_title" value="クレヨンしんちゃん 長ぐつどぼ ん!!" />
|
||||
<part name="cart" interface="st_cart">
|
||||
|
||||
<feature name="slot" value="strom" />
|
||||
<dataarea name="rom" size="524288">
|
||||
<rom name="crayon shin-chan - nagagutsu dobon!! (japan).st" size="524288" crc="8eb753f3" sha1="98a99807a958c1175a2b257166d7b08b2be6d442" offset="0x000000" />
|
||||
</dataarea>
|
||||
</part>
|
||||
</software>
|
||||
|
||||
</softwarelist>
|
@ -35,10 +35,12 @@
|
||||
#include "cpu/upd7725/upd7725.h"
|
||||
#include "includes/snes.h"
|
||||
#include "machine/snescart.h"
|
||||
|
||||
#include "crsshair.h"
|
||||
|
||||
#define MAX_SNES_CART_SIZE 0x600000
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Memory handlers
|
||||
@ -55,6 +57,8 @@ static WRITE8_DEVICE_HANDLER( spc_ram_100_w )
|
||||
spc_ram_w(device, space, offset + 0x100, data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Address maps
|
||||
@ -733,6 +737,7 @@ static MACHINE_CONFIG_DERIVED( snes, snes_base )
|
||||
MCFG_FRAGMENT_ADD(snes_cartslot)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
static SUPERFX_CONFIG( snes_superfx_config )
|
||||
{
|
||||
DEVCB_DRIVER_LINE_MEMBER(snes_state,snes_extern_irq_w) /* IRQ line from cart */
|
||||
@ -988,3 +993,961 @@ CONS( 1989, snesst11, snes, 0, snesst11, snes, snes_state, snes_mess,
|
||||
// These would require cartslot to be added/removed depending on the cart which is loaded
|
||||
CONS( 1989, snesst, snes, 0, snesst, snes, snes_state, snesst, "Nintendo", "Super Nintendo Entertainment System / Super Famicom (NTSC, w/Sufami Turbo)", GAME_NOT_WORKING )
|
||||
CONS( 1989, snesbsx, snes, 0, snesbsx, snes, snes_state, snes_mess, "Nintendo", "Super Nintendo Entertainment System / Super Famicom (NTSC, w/BS-X Satellaview slotted cart)", GAME_NOT_WORKING )
|
||||
|
||||
|
||||
|
||||
// WIP for slot-ified cart devices
|
||||
|
||||
#include "machine/sns_slot.h"
|
||||
#include "machine/sns_rom.h"
|
||||
#include "machine/sns_rom21.h"
|
||||
#include "machine/sns_bsx.h"
|
||||
#include "machine/sns_sdd1.h"
|
||||
#include "machine/sns_sfx.h"
|
||||
#include "machine/sns_spc7110.h"
|
||||
#include "machine/sns_sufami.h"
|
||||
#include "machine/sns_upd.h"
|
||||
|
||||
class snsnew_state : public snes_state
|
||||
{
|
||||
public:
|
||||
snsnew_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: snes_state(mconfig, type, tag),
|
||||
m_slotcart(*this, "snsslot")
|
||||
{ }
|
||||
|
||||
optional_device<sns_cart_slot_device> m_slotcart;
|
||||
int m_type;
|
||||
};
|
||||
|
||||
|
||||
// FIXME: merge these add-on specific maps into something more sane!
|
||||
|
||||
// In general LoROM games have perfect mirror between 0x00-0x7d and 0x80-0xff
|
||||
// But BSX+LoROM games use different read handlers (to access ROM beyond 2MB)
|
||||
// so we use two different set of handlers...
|
||||
|
||||
// LoROM
|
||||
|
||||
static READ8_HANDLER( snes20_hi_r )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
return space.read_byte(0x7e0000 + address);
|
||||
if (address >= 0x2000 && address < 0x6000)
|
||||
return snes_r_io(space, address);
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
return snes_open_bus_r(space, 0);
|
||||
if (address >= 0x8000)
|
||||
return state->m_slotcart->m_cart->read_h(space, offset);
|
||||
}
|
||||
else if (offset < 0x700000)
|
||||
{
|
||||
if (address < 0x8000)
|
||||
return snes_open_bus_r(space, 0);
|
||||
else
|
||||
return state->m_slotcart->m_cart->read_h(space, offset);
|
||||
}
|
||||
|
||||
// ROM & NVRAM access
|
||||
return state->m_slotcart->m_cart->read_h(space, offset);
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( snes20_hi_w )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
UINT16 address = offset & 0xffff;
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
space.write_byte(0x7e0000 + address, data);
|
||||
if (address >= 0x2000 && address < 0x6000)
|
||||
snes_w_io(space, address, data);
|
||||
}
|
||||
else if (offset >= 0x700000) // NVRAM access
|
||||
{
|
||||
state->m_slotcart->m_cart->write_h(space, offset, data);
|
||||
}
|
||||
}
|
||||
|
||||
static READ8_HANDLER( snes20_lo_r )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
return space.read_byte(0x7e0000 + address);
|
||||
if (address >= 0x2000 && address < 0x6000)
|
||||
return snes_r_io(space, address);
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
return snes_open_bus_r(space, 0);
|
||||
if (address >= 0x8000)
|
||||
return state->m_slotcart->m_cart->read_l(space, offset);
|
||||
}
|
||||
else if (offset < 0x700000)
|
||||
{
|
||||
if (address < 0x8000)
|
||||
return snes_open_bus_r(space, 0);
|
||||
else
|
||||
return state->m_slotcart->m_cart->read_l(space, offset);
|
||||
}
|
||||
|
||||
// ROM & NVRAM access
|
||||
return state->m_slotcart->m_cart->read_l(space, offset);
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( snes20_lo_w )
|
||||
{
|
||||
snes20_hi_w(space, offset, data, 0xff);
|
||||
}
|
||||
|
||||
|
||||
// HiROM
|
||||
|
||||
static READ8_HANDLER( snes21_lo_r )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
return space.read_byte(0x7e0000 + address);
|
||||
if (address >= 0x2000 && address < 0x6000)
|
||||
return snes_r_io(space, address);
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
{
|
||||
if (state->m_slotcart->m_cart->get_nvram_size())
|
||||
{
|
||||
// read NVRAM, instead
|
||||
if (offset >= 0x300000)
|
||||
return state->m_slotcart->m_cart->read_l(space, offset);
|
||||
}
|
||||
return snes_open_bus_r(space, 0);
|
||||
}
|
||||
if (address >= 0x8000)
|
||||
return state->m_slotcart->m_cart->read_l(space, offset);
|
||||
}
|
||||
|
||||
// ROM & NVRAM access
|
||||
return state->m_slotcart->m_cart->read_l(space, offset);
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( snes21_lo_w )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
UINT16 address = offset & 0xffff;
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
space.write_byte(0x7e0000 + address, data);
|
||||
if (address >= 0x2000 && address < 0x6000)
|
||||
snes_w_io(space, address, data);
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
{
|
||||
if (state->m_slotcart->m_cart->get_nvram_size())
|
||||
{
|
||||
// write to NVRAM, in this case
|
||||
if (offset >= 0x300000)
|
||||
state->m_slotcart->m_cart->write_l(space, offset, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (offset >= 0x700000) // NVRAM access
|
||||
state->m_slotcart->m_cart->write_l(space, offset, data);
|
||||
}
|
||||
|
||||
static READ8_HANDLER( snes21_hi_r )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
return space.read_byte(0x7e0000 + address);
|
||||
if (address >= 0x2000 && address < 0x6000)
|
||||
return snes_r_io(space, address);
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
{
|
||||
if (state->m_slotcart->m_cart->get_nvram_size())
|
||||
{
|
||||
// read NVRAM, instead
|
||||
if (offset >= 0x300000)
|
||||
return state->m_slotcart->m_cart->read_h(space, offset);
|
||||
}
|
||||
return snes_open_bus_r(space, 0);
|
||||
}
|
||||
if (address >= 0x8000)
|
||||
return state->m_slotcart->m_cart->read_h(space, offset);
|
||||
}
|
||||
|
||||
// ROM & NVRAM access
|
||||
return state->m_slotcart->m_cart->read_h(space, offset);
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( snes21_hi_w )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
UINT16 address = offset & 0xffff;
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
space.write_byte(0x7e0000 + address, data);
|
||||
if (address >= 0x2000 && address < 0x6000)
|
||||
snes_w_io(space, address, data);
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
{
|
||||
if (state->m_slotcart->m_cart->get_nvram_size())
|
||||
{
|
||||
// write to NVRAM, in this case
|
||||
if (offset >= 0x300000)
|
||||
state->m_slotcart->m_cart->write_h(space, offset, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (offset >= 0x700000) // NVRAM access
|
||||
state->m_slotcart->m_cart->write_h(space, offset, data);
|
||||
}
|
||||
|
||||
// SuperFX / GSU
|
||||
|
||||
static READ8_HANDLER( snesfx_hi_r )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
return space.read_byte(0x7e0000 + address);
|
||||
if (address >= 0x2000 && address < 0x6000)
|
||||
{
|
||||
if (address >= 0x3000 && address < 0x3300)
|
||||
return state->m_slotcart->m_cart->chip_read(space, offset);
|
||||
else
|
||||
return snes_r_io(space, address);
|
||||
}
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
{
|
||||
return state->m_slotcart->m_cart->read_h(space, offset); //RAM
|
||||
}
|
||||
if (address >= 0x8000)
|
||||
return state->m_slotcart->m_cart->read_h(space, offset); //ROM
|
||||
}
|
||||
if (offset < 0x600000)
|
||||
return state->m_slotcart->m_cart->read_h(space, offset); //ROM
|
||||
|
||||
return state->m_slotcart->m_cart->read_h(space, offset); //RAM
|
||||
}
|
||||
|
||||
static READ8_HANDLER( snesfx_lo_r )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
return space.read_byte(0x7e0000 + address);
|
||||
if (address >= 0x2000 && address < 0x6000)
|
||||
{
|
||||
if (address >= 0x3000 && address < 0x3300)
|
||||
return state->m_slotcart->m_cart->chip_read(space, offset);
|
||||
else
|
||||
return snes_r_io(space, address);
|
||||
}
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
{
|
||||
return state->m_slotcart->m_cart->read_l(space, offset); //RAM
|
||||
}
|
||||
if (address >= 0x8000)
|
||||
return state->m_slotcart->m_cart->read_l(space, offset); //ROM
|
||||
}
|
||||
if (offset < 0x600000)
|
||||
return state->m_slotcart->m_cart->read_l(space, offset); //ROM
|
||||
|
||||
return state->m_slotcart->m_cart->read_l(space, offset); //RAM
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( snesfx_hi_w )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
UINT16 address = offset & 0xffff;
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
space.write_byte(0x7e0000 + address, data);
|
||||
if (address >= 0x2000 && address < 0x6000)
|
||||
{
|
||||
if (address >= 0x3000 && address < 0x3300)
|
||||
state->m_slotcart->m_cart->chip_write(space, offset, data);
|
||||
else
|
||||
snes_w_io(space, address, data);
|
||||
}
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
state->m_slotcart->m_cart->write_h(space, offset, data);
|
||||
}
|
||||
else
|
||||
state->m_slotcart->m_cart->write_h(space, offset, data);
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( snesfx_lo_w )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
UINT16 address = offset & 0xffff;
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
space.write_byte(0x7e0000 + address, data);
|
||||
if (address >= 0x2000 && address < 0x6000)
|
||||
{
|
||||
if (address >= 0x3000 && address < 0x3300)
|
||||
state->m_slotcart->m_cart->chip_write(space, offset, data);
|
||||
else
|
||||
snes_w_io(space, address, data);
|
||||
}
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
state->m_slotcart->m_cart->write_l(space, offset, data);
|
||||
}
|
||||
else
|
||||
state->m_slotcart->m_cart->write_l(space, offset, data);
|
||||
}
|
||||
|
||||
// SPC-7110
|
||||
|
||||
static READ8_HANDLER( snespc7110_hi_r )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
return space.read_byte(0x7e0000 + address);
|
||||
if (address >= 0x2000 && address < 0x6000)
|
||||
{
|
||||
UINT16 limit = (state->m_slotcart->get_type() == SNES_SPC7110_RTC) ? 0x4843 : 0x4840;
|
||||
if (address >= 0x4800 && address < limit)
|
||||
return state->m_slotcart->m_cart->chip_read(space, address);
|
||||
|
||||
return snes_r_io(space, address);
|
||||
}
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
{
|
||||
if (offset < 0x10000)
|
||||
return state->m_slotcart->m_cart->read_h(space, offset);
|
||||
if (offset >= 0x300000 && offset < 0x310000)
|
||||
return state->m_slotcart->m_cart->read_h(space, offset);
|
||||
}
|
||||
if (address >= 0x8000)
|
||||
return state->m_slotcart->m_cart->read_h(space, offset);
|
||||
}
|
||||
return state->m_slotcart->m_cart->read_h(space, offset);
|
||||
}
|
||||
|
||||
static READ8_HANDLER( snespc7110_lo_r )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
return space.read_byte(0x7e0000 + address);
|
||||
if (address >= 0x2000 && address < 0x6000)
|
||||
{
|
||||
UINT16 limit = (state->m_slotcart->get_type() == SNES_SPC7110_RTC) ? 0x4843 : 0x4840;
|
||||
if (address >= 0x4800 && address < limit)
|
||||
return state->m_slotcart->m_cart->chip_read(space, address);
|
||||
|
||||
return snes_r_io(space, address);
|
||||
}
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
{
|
||||
if (offset < 0x10000)
|
||||
return state->m_slotcart->m_cart->read_l(space, offset);
|
||||
if (offset >= 0x300000 && offset < 0x310000)
|
||||
return state->m_slotcart->m_cart->read_l(space, offset);
|
||||
}
|
||||
if (address >= 0x8000)
|
||||
return state->m_slotcart->m_cart->read_l(space, offset);
|
||||
}
|
||||
if (offset >= 0x500000 && offset < 0x510000)
|
||||
return state->m_slotcart->m_cart->chip_read(space, 0x4800);
|
||||
|
||||
return snes_open_bus_r(space, 0);
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( snespc7110_hi_w )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
UINT16 address = offset & 0xffff;
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
space.write_byte(0x7e0000 + address, data);
|
||||
if (address >= 0x2000 && address < 0x6000)
|
||||
{
|
||||
UINT16 limit = (state->m_slotcart->get_type() == SNES_SPC7110_RTC) ? 0x4843 : 0x4840;
|
||||
if (address >= 0x4800 && address < limit)
|
||||
{
|
||||
state->m_slotcart->m_cart->chip_write(space, address, data);
|
||||
return;
|
||||
}
|
||||
snes_w_io(space, address, data);
|
||||
}
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
{
|
||||
if (offset < 0x10000)
|
||||
state->m_slotcart->m_cart->write_l(space, offset, data);
|
||||
if (offset >= 0x300000 && offset < 0x310000)
|
||||
state->m_slotcart->m_cart->write_l(space, offset, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( snespc7110_lo_w )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
UINT16 address = offset & 0xffff;
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
space.write_byte(0x7e0000 + address, data);
|
||||
if (address >= 0x2000 && address < 0x6000)
|
||||
{
|
||||
UINT16 limit = (state->m_slotcart->get_type() == SNES_SPC7110_RTC) ? 0x4843 : 0x4840;
|
||||
if (address >= 0x4800 && address < limit)
|
||||
{
|
||||
state->m_slotcart->m_cart->chip_write(space, address, data);
|
||||
return;
|
||||
}
|
||||
snes_w_io(space, address, data);
|
||||
}
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
{
|
||||
if (offset < 0x10000)
|
||||
state->m_slotcart->m_cart->write_l(space, offset, data);
|
||||
if (offset >= 0x300000 && offset < 0x310000)
|
||||
state->m_slotcart->m_cart->write_l(space, offset, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// S-DD1
|
||||
|
||||
static READ8_HANDLER( snesdd1_lo_r )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
return space.read_byte(0x7e0000 + address);
|
||||
if (address >= 0x2000 && address < 0x6000)
|
||||
{
|
||||
if (address >= 0x4800 && address < 0x4808)
|
||||
return state->m_slotcart->m_cart->chip_read(space, address);
|
||||
|
||||
return snes_r_io(space, address);
|
||||
}
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
return snes_open_bus_r(space, 0);
|
||||
if (address >= 0x8000)
|
||||
return state->m_slotcart->m_cart->read_l(space, offset);
|
||||
}
|
||||
|
||||
// ROM & NVRAM access
|
||||
return state->m_slotcart->m_cart->read_l(space, offset);
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( snesdd1_lo_w )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
UINT16 address = offset & 0xffff;
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
space.write_byte(0x7e0000 + address, data);
|
||||
if (address >= 0x2000 && address < 0x6000)
|
||||
{
|
||||
if (address >= 0x4300 && address < 0x4380)
|
||||
{
|
||||
state->m_slotcart->m_cart->chip_write(space, address, data);
|
||||
// here we don't return, but we let the w_io happen...
|
||||
}
|
||||
if (address >= 0x4800 && address < 0x4808)
|
||||
{
|
||||
state->m_slotcart->m_cart->chip_write(space, address, data);
|
||||
return;
|
||||
}
|
||||
snes_w_io(space, address, data);
|
||||
}
|
||||
}
|
||||
if (offset >= 0x700000 && address < 0x8000 && state->m_slotcart->m_cart->get_nvram_size())
|
||||
return state->m_slotcart->m_cart->write_l(space, offset, data);
|
||||
}
|
||||
|
||||
static READ8_HANDLER( snesdd1_hi_r )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
|
||||
if (offset >= 0x400000)
|
||||
return state->m_slotcart->m_cart->read_h(space, offset);
|
||||
else
|
||||
return snesdd1_lo_r(space, offset, 0xff);
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( snesdd1_hi_w )
|
||||
{
|
||||
snesdd1_lo_w(space, offset, data, 0xff);
|
||||
}
|
||||
|
||||
|
||||
// BS-X
|
||||
|
||||
static READ8_HANDLER( snesbsx_hi_r )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
return space.read_byte(0x7e0000 + address);
|
||||
if (address >= 0x2000 && address < 0x6000)
|
||||
{
|
||||
if (address >= 0x2188 && address < 0x21a0)
|
||||
return state->m_slotcart->m_cart->chip_read(space, offset);
|
||||
if (address >= 0x5000)
|
||||
return state->m_slotcart->m_cart->chip_read(space, offset);
|
||||
return snes_r_io(space, address);
|
||||
}
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
{
|
||||
if (offset >= 0x200000)
|
||||
return state->m_slotcart->m_cart->read_l(space, offset);
|
||||
else
|
||||
return snes_open_bus_r(space, 0);
|
||||
}
|
||||
if (address >= 0x8000)
|
||||
return state->m_slotcart->m_cart->read_l(space, offset);
|
||||
}
|
||||
return state->m_slotcart->m_cart->read_l(space, offset);
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( snesbsx_hi_w )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
UINT16 address = offset & 0xffff;
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
space.write_byte(0x7e0000 + address, data);
|
||||
if (address >= 0x2000 && address < 0x6000)
|
||||
{
|
||||
if (address >= 0x2188 && address < 0x21a0)
|
||||
{
|
||||
state->m_slotcart->m_cart->chip_write(space, offset, data);
|
||||
return;
|
||||
}
|
||||
if (address >= 0x5000)
|
||||
{
|
||||
state->m_slotcart->m_cart->chip_write(space, offset, data);
|
||||
return;
|
||||
}
|
||||
snes_w_io(space, address, data);
|
||||
}
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
{
|
||||
if (offset >= 0x200000)
|
||||
return state->m_slotcart->m_cart->write_l(space, offset, data);
|
||||
}
|
||||
if (address >= 0x8000)
|
||||
return state->m_slotcart->m_cart->write_l(space, offset, data);
|
||||
}
|
||||
return state->m_slotcart->m_cart->write_l(space, offset, data);
|
||||
}
|
||||
|
||||
static READ8_HANDLER( snesbsx_lo_r )
|
||||
{
|
||||
return snesbsx_hi_r(space, offset, 0xff);
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( snesbsx_lo_w )
|
||||
{
|
||||
snesbsx_hi_w(space, offset, data, 0xff);
|
||||
}
|
||||
|
||||
|
||||
static READ8_HANDLER( snesnew_lo_r )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
|
||||
// take care of add-on IO
|
||||
if (state->m_slotcart->get_type() == SNES_DSP
|
||||
&& (offset >= 0x200000 && offset < 0x400000 && (offset & 0x8000) == 0x8000))
|
||||
return state->m_slotcart->m_cart->chip_read(space, offset & 0x7fff);
|
||||
else if (state->m_slotcart->get_type() == SNES_DSP_MODE21
|
||||
&& (offset < 0x200000 && (offset & 0xffff) >= 0x6000 && (offset & 0xffff) < 0x8000))
|
||||
return state->m_slotcart->m_cart->chip_read(space, offset & 0x1fff);
|
||||
else if (state->m_slotcart->get_type() == SNES_DSP4
|
||||
&& (offset >= 0x300000 && offset < 0x400000 && (offset & 0x8000) == 0x8000))
|
||||
return state->m_slotcart->m_cart->chip_read(space, offset & 0x7fff);
|
||||
else if (state->m_slotcart->get_type() == SNES_OBC1
|
||||
&& (offset < 0x400000 && (offset & 0xffff) >= 0x6000 && (offset & 0xffff) < 0x8000))
|
||||
return state->m_slotcart->m_cart->chip_read(space, offset);
|
||||
else if ((state->m_slotcart->get_type() == SNES_ST010 || state->m_slotcart->get_type() == SNES_ST011)
|
||||
&& (offset >= 0x680000 && offset < 0x700000 && (offset & 0xffff) < 0x1000))
|
||||
return state->m_slotcart->m_cart->chip_read(space, offset);
|
||||
else if (state->m_slotcart->get_type() == SNES_SRTC
|
||||
&& (offset < 0x400000 && (offset & 0xffff) == 0x2800))
|
||||
return state->m_slotcart->m_cart->chip_read(space, offset & 0xffff);
|
||||
else
|
||||
{
|
||||
switch (state->m_type)
|
||||
{
|
||||
case SNES_MODE20:
|
||||
case SNES_ST010:
|
||||
case SNES_ST011:
|
||||
case SNES_DSP:
|
||||
case SNES_DSP4:
|
||||
case SNES_OBC1:
|
||||
case SNES_SUFAMITURBO:
|
||||
case SNES_STROM:
|
||||
case SNES_BSXLO:
|
||||
case SNES_POKEMON:
|
||||
case SNES_BANANA:
|
||||
return snes20_lo_r(space, offset, 0xff);
|
||||
|
||||
case SNES_MODE21:
|
||||
case SNES_DSP_MODE21:
|
||||
case SNES_SRTC:
|
||||
case SNES_BSXHI:
|
||||
return snes21_lo_r(space, offset, 0xff);
|
||||
|
||||
case SNES_SFX:
|
||||
return snesfx_lo_r(space, offset, 0xff);
|
||||
|
||||
case SNES_SPC7110:
|
||||
case SNES_SPC7110_RTC:
|
||||
return snespc7110_lo_r(space, offset, 0xff);
|
||||
|
||||
case SNES_SDD1:
|
||||
return snesdd1_lo_r(space, offset, 0xff);
|
||||
|
||||
case SNES_BSX:
|
||||
return snesbsx_lo_r(space, offset, 0xff);
|
||||
}
|
||||
}
|
||||
return snes_open_bus_r(space, 0);
|
||||
}
|
||||
|
||||
static READ8_HANDLER( snesnew_hi_r )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
|
||||
// take care of add-on IO
|
||||
if (state->m_slotcart->get_type() == SNES_DSP
|
||||
&& (offset >= 0x200000 && offset < 0x400000 && (offset & 0x8000) == 0x8000))
|
||||
return state->m_slotcart->m_cart->chip_read(space, offset & 0x7fff);
|
||||
else if (state->m_slotcart->get_type() == SNES_DSP_MODE21
|
||||
&& (offset < 0x200000 && (offset & 0xffff) >= 0x6000 && (offset & 0xffff) < 0x8000))
|
||||
return state->m_slotcart->m_cart->chip_read(space, offset & 0x1fff);
|
||||
else if (state->m_slotcart->get_type() == SNES_DSP4
|
||||
&& (offset >= 0x300000 && offset < 0x400000 && (offset & 0x8000) == 0x8000))
|
||||
return state->m_slotcart->m_cart->chip_read(space, offset & 0x7fff);
|
||||
else if (state->m_slotcart->get_type() == SNES_OBC1
|
||||
&& (offset < 0x400000 && (offset & 0xffff) >= 0x6000 && (offset & 0xffff) < 0x8000))
|
||||
return state->m_slotcart->m_cart->chip_read(space, offset);
|
||||
else if ((state->m_slotcart->get_type() == SNES_ST010 || state->m_slotcart->get_type() == SNES_ST011)
|
||||
&& (offset >= 0x680000 && offset < 0x700000 && (offset & 0xffff) < 0x1000))
|
||||
return state->m_slotcart->m_cart->chip_read(space, offset);
|
||||
else if (state->m_slotcart->get_type() == SNES_SRTC
|
||||
&& (offset < 0x400000 && (offset & 0xffff) == 0x2800))
|
||||
return state->m_slotcart->m_cart->chip_read(space, offset & 0xffff);
|
||||
else if ((state->m_slotcart->get_type() == SNES_POKEMON || state->m_slotcart->get_type() == SNES_BANANA)
|
||||
&& (offset & 0x70000) == 0x0000)
|
||||
{
|
||||
// printf("hi read %x\n", offset);
|
||||
return state->m_slotcart->m_cart->chip_read(space, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (state->m_type)
|
||||
{
|
||||
case SNES_MODE20:
|
||||
case SNES_ST010:
|
||||
case SNES_ST011:
|
||||
case SNES_DSP:
|
||||
case SNES_DSP4:
|
||||
case SNES_OBC1:
|
||||
case SNES_SUFAMITURBO:
|
||||
case SNES_STROM:
|
||||
case SNES_BSXLO:
|
||||
case SNES_POKEMON:
|
||||
case SNES_BANANA:
|
||||
return snes20_hi_r(space, offset, 0xff);
|
||||
|
||||
case SNES_MODE21:
|
||||
case SNES_DSP_MODE21:
|
||||
case SNES_SRTC:
|
||||
case SNES_BSXHI:
|
||||
return snes21_hi_r(space, offset, 0xff);
|
||||
|
||||
case SNES_SFX:
|
||||
return snesfx_hi_r(space, offset, 0xff);
|
||||
|
||||
case SNES_SPC7110:
|
||||
case SNES_SPC7110_RTC:
|
||||
return snespc7110_hi_r(space, offset, 0xff);
|
||||
|
||||
case SNES_SDD1:
|
||||
return snesdd1_hi_r(space, offset, 0xff);
|
||||
|
||||
case SNES_BSX:
|
||||
return snesbsx_hi_r(space, offset, 0xff);
|
||||
}
|
||||
}
|
||||
return snes_open_bus_r(space, 0);
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( snesnew_lo_w )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
|
||||
// take care of add-on IO
|
||||
if (state->m_slotcart->get_type() == SNES_DSP
|
||||
&& (offset >= 0x200000 && offset < 0x400000 && (offset & 0x8000) == 0x8000))
|
||||
state->m_slotcart->m_cart->chip_write(space, offset & 0x7fff, data);
|
||||
else if (state->m_slotcart->get_type() == SNES_DSP_MODE21
|
||||
&& (offset < 0x200000 && (offset & 0xffff) >= 0x6000 && (offset & 0xffff) < 0x8000))
|
||||
state->m_slotcart->m_cart->chip_write(space, offset & 0x1fff, data);
|
||||
else if (state->m_slotcart->get_type() == SNES_DSP4
|
||||
&& (offset >= 0x300000 && offset < 0x400000 && (offset & 0x8000) == 0x8000))
|
||||
state->m_slotcart->m_cart->chip_write(space, offset & 0x7fff, data);
|
||||
else if (state->m_slotcart->get_type() == SNES_OBC1
|
||||
&& (offset < 0x400000 && (offset & 0xffff) >= 0x6000 && (offset & 0xffff) < 0x8000))
|
||||
state->m_slotcart->m_cart->chip_write(space, offset, data);
|
||||
else if ((state->m_slotcart->get_type() == SNES_ST010 || state->m_slotcart->get_type() == SNES_ST011)
|
||||
&& (offset >= 0x680000 && offset < 0x700000 && (offset & 0xffff) < 0x1000))
|
||||
state->m_slotcart->m_cart->chip_write(space, offset, data);
|
||||
else if (state->m_slotcart->get_type() == SNES_SRTC
|
||||
&& (offset < 0x400000 && (offset & 0xffff) == 0x2801))
|
||||
state->m_slotcart->m_cart->chip_write(space, offset & 0xffff, data);
|
||||
else if (state->m_slotcart->get_type() == SNES_BANANA
|
||||
&& (offset & 0x78000) == 0x8000)
|
||||
{
|
||||
// printf("lo write %x\n", offset);
|
||||
state->m_slotcart->m_cart->chip_write(space, offset, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (state->m_type)
|
||||
{
|
||||
case SNES_MODE20:
|
||||
case SNES_ST010:
|
||||
case SNES_ST011:
|
||||
case SNES_DSP:
|
||||
case SNES_DSP4:
|
||||
case SNES_OBC1:
|
||||
case SNES_SUFAMITURBO:
|
||||
case SNES_STROM:
|
||||
case SNES_BSXLO:
|
||||
case SNES_POKEMON:
|
||||
case SNES_BANANA:
|
||||
snes20_lo_w(space, offset, data, 0xff);
|
||||
break;
|
||||
|
||||
case SNES_MODE21:
|
||||
case SNES_DSP_MODE21:
|
||||
case SNES_SRTC:
|
||||
case SNES_BSXHI:
|
||||
snes21_lo_w(space, offset, data, 0xff);
|
||||
break;
|
||||
|
||||
case SNES_SFX:
|
||||
snesfx_lo_w(space, offset, data, 0xff);
|
||||
break;
|
||||
|
||||
case SNES_SPC7110:
|
||||
case SNES_SPC7110_RTC:
|
||||
snespc7110_lo_w(space, offset, data, 0xff);
|
||||
break;
|
||||
|
||||
case SNES_SDD1:
|
||||
snesdd1_lo_w(space, offset, data, 0xff);
|
||||
break;
|
||||
|
||||
case SNES_BSX:
|
||||
snesbsx_lo_w(space, offset, data, 0xff);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( snesnew_hi_w )
|
||||
{
|
||||
snsnew_state *state = space.machine().driver_data<snsnew_state>();
|
||||
|
||||
// take care of add-on IO
|
||||
if (state->m_slotcart->get_type() == SNES_DSP
|
||||
&& (offset >= 0x200000 && offset < 0x400000 && (offset & 0x8000) == 0x8000))
|
||||
state->m_slotcart->m_cart->chip_write(space, offset & 0x7fff, data);
|
||||
else if (state->m_slotcart->get_type() == SNES_DSP_MODE21
|
||||
&& (offset < 0x200000 && (offset & 0xffff) >= 0x6000 && (offset & 0xffff) < 0x8000))
|
||||
state->m_slotcart->m_cart->chip_write(space, offset & 0x1fff, data);
|
||||
else if (state->m_slotcart->get_type() == SNES_DSP4
|
||||
&& (offset >= 0x300000 && offset < 0x400000 && (offset & 0x8000) == 0x8000))
|
||||
state->m_slotcart->m_cart->chip_write(space, offset & 0x7fff, data);
|
||||
else if (state->m_slotcart->get_type() == SNES_OBC1
|
||||
&& (offset < 0x400000 && (offset & 0xffff) >= 0x6000 && (offset & 0xffff) < 0x8000))
|
||||
return state->m_slotcart->m_cart->chip_write(space, offset, data);
|
||||
else if ((state->m_slotcart->get_type() == SNES_ST010 || state->m_slotcart->get_type() == SNES_ST011)
|
||||
&& (offset >= 0x680000 && offset < 0x700000 && (offset & 0xffff) < 0x1000))
|
||||
state->m_slotcart->m_cart->chip_write(space, offset, data);
|
||||
else if (state->m_slotcart->get_type() == SNES_SRTC
|
||||
&& (offset < 0x400000 && (offset & 0xffff) == 0x2801))
|
||||
state->m_slotcart->m_cart->chip_write(space, offset & 0xffff, data);
|
||||
else if ((state->m_slotcart->get_type() == SNES_POKEMON)
|
||||
&& (offset & 0x70000) == 0x0000)
|
||||
{
|
||||
// printf("hi write %x\n", offset);
|
||||
state->m_slotcart->m_cart->chip_write(space, offset, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (state->m_type)
|
||||
{
|
||||
case SNES_MODE20:
|
||||
case SNES_ST010:
|
||||
case SNES_ST011:
|
||||
case SNES_DSP:
|
||||
case SNES_DSP4:
|
||||
case SNES_OBC1:
|
||||
case SNES_SUFAMITURBO:
|
||||
case SNES_STROM:
|
||||
case SNES_BSXLO:
|
||||
case SNES_POKEMON:
|
||||
case SNES_BANANA:
|
||||
snes20_hi_w(space, offset, data, 0xff);
|
||||
break;
|
||||
|
||||
case SNES_MODE21:
|
||||
case SNES_DSP_MODE21:
|
||||
case SNES_SRTC:
|
||||
case SNES_BSXHI:
|
||||
snes21_hi_w(space, offset, data, 0xff);
|
||||
break;
|
||||
|
||||
case SNES_SFX:
|
||||
snesfx_hi_w(space, offset, data, 0xff);
|
||||
break;
|
||||
|
||||
case SNES_SPC7110:
|
||||
case SNES_SPC7110_RTC:
|
||||
snespc7110_hi_w(space, offset, data, 0xff);
|
||||
break;
|
||||
|
||||
case SNES_SDD1:
|
||||
snesdd1_hi_w(space, offset, data, 0xff);
|
||||
break;
|
||||
|
||||
case SNES_BSX:
|
||||
snesbsx_hi_w(space, offset, data, 0xff);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static ADDRESS_MAP_START( snesnew_map, AS_PROGRAM, 8, snsnew_state )
|
||||
AM_RANGE(0x000000, 0x7dffff) AM_READWRITE_LEGACY(snesnew_lo_r, snesnew_lo_w)
|
||||
AM_RANGE(0x7e0000, 0x7fffff) AM_RAM /* 8KB Low RAM, 24KB High RAM, 96KB Expanded RAM */
|
||||
AM_RANGE(0x800000, 0xffffff) AM_READWRITE_LEGACY(snesnew_hi_r, snesnew_hi_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static SLOT_INTERFACE_START(snes_cart)
|
||||
SLOT_INTERFACE_INTERNAL("lorom", SNS_LOROM)
|
||||
SLOT_INTERFACE_INTERNAL("lorom_bsx", SNS_LOROM_BSX) // LoROM + BS-X slot - unsupported
|
||||
SLOT_INTERFACE_INTERNAL("lorom_cx4", SNS_LOROM) // Cart + CX4 - unsupported
|
||||
SLOT_INTERFACE_INTERNAL("lorom_dsp", SNS_LOROM_NECDSP)
|
||||
SLOT_INTERFACE_INTERNAL("lorom_dsp4", SNS_LOROM_NECDSP)
|
||||
SLOT_INTERFACE_INTERNAL("lorom_obc1", SNS_LOROM_OBC1)
|
||||
SLOT_INTERFACE_INTERNAL("lorom_sa1", SNS_LOROM) // Cart + SA1 - unsupported
|
||||
SLOT_INTERFACE_INTERNAL("lorom_sdd1", SNS_LOROM_SDD1)
|
||||
SLOT_INTERFACE_INTERNAL("lorom_sfx", SNS_LOROM_SUPERFX)
|
||||
SLOT_INTERFACE_INTERNAL("lorom_sgb", SNS_LOROM) // SuperGB base cart - unsupported
|
||||
SLOT_INTERFACE_INTERNAL("lorom_st010", SNS_LOROM_SETA10)
|
||||
SLOT_INTERFACE_INTERNAL("lorom_st011", SNS_LOROM_SETA11)
|
||||
SLOT_INTERFACE_INTERNAL("lorom_st018", SNS_LOROM) // Cart + ST018 - unsupported
|
||||
SLOT_INTERFACE_INTERNAL("lorom_sufami", SNS_LOROM_SUFAMI) // Sufami Turbo base cart
|
||||
SLOT_INTERFACE_INTERNAL("hirom", SNS_HIROM)
|
||||
SLOT_INTERFACE_INTERNAL("hirom_bsx", SNS_HIROM_BSX) // HiROM + BS-X slot - unsupported
|
||||
SLOT_INTERFACE_INTERNAL("hirom_dsp", SNS_HIROM_NECDSP)
|
||||
SLOT_INTERFACE_INTERNAL("hirom_spc7110", SNS_HIROM_SPC7110)
|
||||
SLOT_INTERFACE_INTERNAL("hirom_spcrtc", SNS_HIROM_SPC7110_RTC)
|
||||
SLOT_INTERFACE_INTERNAL("hirom_srtc", SNS_HIROM_SRTC)
|
||||
SLOT_INTERFACE_INTERNAL("bsxrom", SNS_ROM_BSX) // BS-X base cart - partial support only
|
||||
// pirate carts
|
||||
SLOT_INTERFACE_INTERNAL("lorom_poke", SNS_LOROM_POKEMON)
|
||||
SLOT_INTERFACE_END
|
||||
|
||||
|
||||
static MACHINE_START( snesnew )
|
||||
{
|
||||
snsnew_state *state = machine.driver_data<snsnew_state>();
|
||||
|
||||
state->m_type = state->m_slotcart->get_type();
|
||||
|
||||
MACHINE_START_CALL(snes);
|
||||
|
||||
// FIXME: why installing handlers here does not work? it would allow to clean up handlers above...
|
||||
switch (state->m_type)
|
||||
{
|
||||
case SNES_MODE21:
|
||||
case SNES_MODE25:
|
||||
case SNES_DSP_MODE21:
|
||||
// machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(0x000000, 0x7dffff, FUNC(snes21_lo_r), FUNC(snes21_lo_w));
|
||||
// machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(0x800000, 0xffffff, FUNC(snes21_hi_r), FUNC(snes21_hi_w));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static MACHINE_CONFIG_START( snesnew, snsnew_state )
|
||||
MCFG_FRAGMENT_ADD( snes_base )
|
||||
|
||||
MCFG_CPU_MODIFY("maincpu")
|
||||
MCFG_CPU_PROGRAM_MAP(snesnew_map)
|
||||
|
||||
MCFG_MACHINE_START(snesnew)
|
||||
|
||||
MCFG_SNS_CARTRIDGE_ADD("snsslot", snes_cart, NULL, NULL)
|
||||
MCFG_SOFTWARE_LIST_ADD("cart_list","snes")
|
||||
MCFG_SOFTWARE_LIST_ADD("bsx_list","snes_bspack")
|
||||
MCFG_SOFTWARE_LIST_ADD("st_list","snes_strom")
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
static MACHINE_CONFIG_DERIVED( snespnew, snesnew )
|
||||
MCFG_CPU_MODIFY( "maincpu" )
|
||||
MCFG_CPU_CLOCK( MCLK_PAL )
|
||||
|
||||
MCFG_SCREEN_MODIFY("screen")
|
||||
MCFG_SCREEN_RAW_PARAMS(DOTCLK_PAL, SNES_HTOTAL, 0, SNES_SCR_WIDTH, SNES_VTOTAL_PAL, 0, SNES_SCR_HEIGHT_PAL)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
#define rom_snesnew rom_snes
|
||||
#define rom_snespnew rom_snespal
|
||||
|
||||
CONS( 1989, snesnew, snes, 0, snesnew, snes, snes_state, snes_mess, "Nintendo", "Super Nintendo Entertainment System / Super Famicom (NTSC, Test)", GAME_NOT_WORKING )
|
||||
CONS( 1989, snespnew, snes, 0, snespnew, snes, snes_state, snes_mess, "Nintendo", "Super Nintendo Entertainment System (PAL, Test)", GAME_NOT_WORKING )
|
||||
|
@ -303,7 +303,7 @@ MACHINE_START( snesst )
|
||||
|
||||
/* This function assign a 'score' to data immediately after 'offset' to measure how valid they are
|
||||
as information block (to decide if the image is HiRom, LoRom, ExLoRom or ExHiRom) */
|
||||
/* Code from bsnes, courtesy of byuu - http://byuu.cinnamonpirate.com/ */
|
||||
/* Code from bsnes, courtesy of byuu - http://byuu.org/ , based on previous code by Cowering */
|
||||
static int snes_validate_infoblock( UINT8 *infoblock, UINT32 offset )
|
||||
{
|
||||
int score = 0;
|
||||
|
586
src/mess/machine/sns_bsx.c
Normal file
586
src/mess/machine/sns_bsx.c
Normal file
@ -0,0 +1,586 @@
|
||||
/***********************************************************************************************************
|
||||
|
||||
BS-X Satellaview cartridge emulation (for SNES/SFC)
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
***********************************************************************************************************/
|
||||
|
||||
|
||||
// TODO: Emulate FLASH memory... (possibly using flash device?)
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "machine/sns_bsx.h"
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// sns_rom_bsx_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
const device_type SNS_ROM_BSX = &device_creator<sns_rom_bsx_device>;
|
||||
const device_type SNS_LOROM_BSX = &device_creator<sns_rom_bsxlo_device>;
|
||||
const device_type SNS_HIROM_BSX = &device_creator<sns_rom_bsxhi_device>;
|
||||
const device_type SNS_BSMEMPAK = &device_creator<sns_rom_bsmempak_device>;
|
||||
|
||||
|
||||
sns_rom_bsx_device::sns_rom_bsx_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sns_rom_device(mconfig, type, name, tag, owner, clock),
|
||||
m_slot(*this, "bs_slot")
|
||||
{
|
||||
}
|
||||
|
||||
sns_rom_bsx_device::sns_rom_bsx_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sns_rom_device(mconfig, SNS_ROM_BSX, "SNES BS-X Cart", tag, owner, clock),
|
||||
m_slot(*this, "bs_slot")
|
||||
{
|
||||
}
|
||||
|
||||
sns_rom_bsxlo_device::sns_rom_bsxlo_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sns_rom_device(mconfig, SNS_LOROM_BSX, "SNES Cart (LoROM) + BS-X slot", tag, owner, clock),
|
||||
m_slot(*this, "bs_slot")
|
||||
{
|
||||
}
|
||||
|
||||
sns_rom_bsxhi_device::sns_rom_bsxhi_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sns_rom21_device(mconfig, SNS_HIROM_BSX, "SNES Cart (HiROM) + BS-X slot", tag, owner, clock),
|
||||
m_slot(*this, "bs_slot")
|
||||
{
|
||||
}
|
||||
|
||||
sns_rom_bsmempak_device::sns_rom_bsmempak_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sns_rom_device(mconfig, SNS_BSMEMPAK, "SNES BS-X Memory packs", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void sns_rom_bsx_device::device_start()
|
||||
{
|
||||
m_base_unit = auto_alloc(machine(), BSX_base(machine()));
|
||||
memset(m_cart_regs, 0x00, sizeof(m_cart_regs));
|
||||
m_cart_regs[7] = 0x80;
|
||||
m_cart_regs[8] = 0x80;
|
||||
access_update();
|
||||
|
||||
memset(m_pram, 0xff, sizeof(m_pram));
|
||||
|
||||
save_item(NAME(m_cart_regs));
|
||||
save_item(NAME(access_00_1f));
|
||||
save_item(NAME(access_80_9f));
|
||||
save_item(NAME(access_40_4f));
|
||||
save_item(NAME(access_50_5f));
|
||||
save_item(NAME(access_60_6f));
|
||||
save_item(NAME(rom_access));
|
||||
save_item(NAME(m_pram));
|
||||
// TODO: save unit-related items and fix their restore...
|
||||
}
|
||||
|
||||
void sns_rom_bsxlo_device::device_start()
|
||||
{
|
||||
}
|
||||
|
||||
void sns_rom_bsxhi_device::device_start()
|
||||
{
|
||||
}
|
||||
|
||||
void sns_rom_bsmempak_device::device_start()
|
||||
{
|
||||
m_command = 0;
|
||||
m_write_old = 0;
|
||||
m_write_new = 0;
|
||||
|
||||
m_flash_enable = 0;
|
||||
m_read_enable = 0;
|
||||
m_write_enable = 0;
|
||||
|
||||
save_item(NAME(m_command));
|
||||
save_item(NAME(m_write_old));
|
||||
save_item(NAME(m_write_new));
|
||||
save_item(NAME(m_flash_enable));
|
||||
save_item(NAME(m_read_enable));
|
||||
save_item(NAME(m_write_enable));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// BS-X Base Unit emulation, to be device-fied ?
|
||||
|
||||
BSX_base::BSX_base(running_machine &machine)
|
||||
: m_machine(machine)
|
||||
{
|
||||
}
|
||||
|
||||
void BSX_base::init()
|
||||
{
|
||||
memset(regs, 0x00, sizeof(regs));
|
||||
r2192_counter = 0;
|
||||
r2192_hour = 0;
|
||||
r2192_minute = 0;
|
||||
r2192_second = 0;
|
||||
}
|
||||
|
||||
|
||||
UINT8 BSX_base::read(UINT32 offset)
|
||||
{
|
||||
offset &= 0xffff;
|
||||
if (offset < 0x2188 || offset >= 0x21a0)
|
||||
{
|
||||
mame_printf_debug("BS-X Base Unit reg read outside correct range!\n");
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
// no 218b? no 218d? no 2191? no 2195? no 219a-219f?
|
||||
case 0x2192:
|
||||
{
|
||||
UINT8 counter = r2192_counter++;
|
||||
if (r2192_counter >= 18)
|
||||
r2192_counter = 0;
|
||||
|
||||
if (counter == 0)
|
||||
{
|
||||
system_time curtime, *systime = &curtime;
|
||||
m_machine.current_datetime(curtime);
|
||||
r2192_hour = systime->local_time.hour;
|
||||
r2192_minute = systime->local_time.minute;
|
||||
r2192_second = systime->local_time.second;
|
||||
}
|
||||
|
||||
switch (counter)
|
||||
{
|
||||
case 0: return 0x00; //???
|
||||
case 1: return 0x00; //???
|
||||
case 2: return 0x00; //???
|
||||
case 3: return 0x00; //???
|
||||
case 4: return 0x00; //???
|
||||
case 5: return 0x01;
|
||||
case 6: return 0x01;
|
||||
case 7: return 0x00;
|
||||
case 8: return 0x00;
|
||||
case 9: return 0x00;
|
||||
case 10: return r2192_second;
|
||||
case 11: return r2192_minute;
|
||||
case 12: return r2192_hour;
|
||||
case 13: return 0x00; //???
|
||||
case 14: return 0x00; //???
|
||||
case 15: return 0x00; //???
|
||||
case 16: return 0x00; //???
|
||||
case 17: return 0x00; //???
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2193:
|
||||
return regs[offset - 0x2188] & ~0x0c;
|
||||
|
||||
default:
|
||||
return regs[offset - 0x2188];
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
|
||||
void BSX_base::write(UINT32 offset, UINT8 data)
|
||||
{
|
||||
offset &= 0xffff;
|
||||
if (offset < 0x2188 || offset >= 0x21a0)
|
||||
{
|
||||
mame_printf_debug("BS-X Base Unit reg write outside correct range!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch(offset)
|
||||
{
|
||||
// no 218d? no 2190? no 2195? no 2196? no 2198? no 219a-219f?
|
||||
case 0x218f:
|
||||
regs[6] >>= 1; // 0x218e
|
||||
regs[6] = regs[7] - regs[6]; // 0x218f - 0x218e
|
||||
regs[7] >>= 1; // 0x218f
|
||||
break;
|
||||
|
||||
case 0x2191:
|
||||
regs[offset - 0x2188] = data;
|
||||
r2192_counter = 0;
|
||||
break;
|
||||
|
||||
case 0x2192:
|
||||
regs[8] = data; // sets 0x2190
|
||||
break;
|
||||
|
||||
default:
|
||||
regs[offset - 0x2188] = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// MACHINE_CONFIG_FRAGMENT( bs_slot )
|
||||
//-------------------------------------------------
|
||||
|
||||
static SLOT_INTERFACE_START(bsx_cart)
|
||||
SLOT_INTERFACE_INTERNAL("bsmempak", SNS_BSMEMPAK)
|
||||
SLOT_INTERFACE_END
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( bs_slot )
|
||||
MCFG_SNS_BSX_CARTRIDGE_ADD("bs_slot", bsx_cart, NULL, NULL)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// machine_config_additions - device-specific
|
||||
// machine configurations
|
||||
//-------------------------------------------------
|
||||
|
||||
machine_config_constructor sns_rom_bsx_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( bs_slot );
|
||||
}
|
||||
|
||||
machine_config_constructor sns_rom_bsxlo_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( bs_slot );
|
||||
}
|
||||
|
||||
machine_config_constructor sns_rom_bsxhi_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( bs_slot );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
mapper specific handlers
|
||||
-------------------------------------------------*/
|
||||
|
||||
// BS-X base + cart
|
||||
|
||||
void sns_rom_bsx_device::access_update()
|
||||
{
|
||||
access_00_1f = BIT(m_cart_regs[0x07], 7);
|
||||
access_40_4f = !BIT(m_cart_regs[0x05], 7);
|
||||
access_50_5f = !BIT(m_cart_regs[0x06], 7);
|
||||
access_60_6f = BIT(m_cart_regs[0x03], 7);
|
||||
access_80_9f = BIT(m_cart_regs[0x08], 7);
|
||||
if (BIT(m_cart_regs[0x01], 7))
|
||||
rom_access = 0;
|
||||
else
|
||||
{
|
||||
// rom_access = BIT(m_cart_regs[0x02], 7) + 1;
|
||||
rom_access = 1; // for whatever reason bsxsore changes access mode here and then fails to read the ROM properly!
|
||||
printf("rom_access %s\n", !BIT(m_cart_regs[0x02], 7) ? "Lo" : "Hi");
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER(sns_rom_bsx_device::read_l)
|
||||
{
|
||||
if (offset < 0x200000 && access_00_1f)
|
||||
{
|
||||
// 0x00-0x1f:0x8000-0xffff -> CART
|
||||
if (m_slot->m_cart && m_slot->m_cart->get_rom_size())
|
||||
return m_slot->m_cart->read_l(space, offset);
|
||||
}
|
||||
if (offset >= 0x200000 && offset < 0x400000)
|
||||
{
|
||||
// 0x20-0x3f:0x6000-0x7fff -> PRAM
|
||||
if ((offset & 0xffff) >= 0x6000 && (offset & 0xffff) < 0x8000)
|
||||
return m_pram[offset & 0xffff];
|
||||
}
|
||||
if (offset >= 0x400000 && offset < 0x500000 && access_40_4f)
|
||||
{
|
||||
// 0x40-0x4f:0x0000-0xffff -> PRAM
|
||||
return m_pram[offset & 0x7ffff];
|
||||
}
|
||||
if (offset >= 0x500000 && offset < 0x600000 && access_50_5f)
|
||||
{
|
||||
// 0x50-0x5f:0x0000-0xffff -> PRAM
|
||||
return m_pram[offset & 0x7ffff];
|
||||
}
|
||||
if (offset >= 0x600000 && offset < 0x700000 && access_60_6f)
|
||||
{
|
||||
// 0x60-0x6f:0x0000-0xffff -> PRAM
|
||||
return m_pram[offset & 0x7ffff];
|
||||
}
|
||||
if (offset >= 0x700000 && offset < 0x780000)
|
||||
{
|
||||
// 0x70-0x77:0x0000-0xffff -> PRAM
|
||||
return m_pram[offset & 0x7ffff];
|
||||
}
|
||||
|
||||
// if not in any of the cases above...
|
||||
//$00-3f|80-bf:8000-ffff
|
||||
//$40-7f|c0-ff:0000-ffff
|
||||
if (!rom_access)
|
||||
return m_pram[offset & 0x7ffff];
|
||||
else
|
||||
{
|
||||
int bank = (rom_access == 1) ? (offset / 0x10000) : (offset / 0x8000);
|
||||
return m_rom[rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(sns_rom_bsx_device::read_h)
|
||||
{
|
||||
if (offset < 0x200000 && access_80_9f)
|
||||
{
|
||||
// 0x80-0x9f:0x8000-0xffff -> CART
|
||||
if (m_slot->m_cart && m_slot->m_cart->get_rom_size())
|
||||
return m_slot->m_cart->read_l(space, offset);
|
||||
}
|
||||
|
||||
// if not in any of the cases above...
|
||||
//$00-3f|80-bf:8000-ffff
|
||||
//$40-7f|c0-ff:0000-ffff
|
||||
if (!rom_access)
|
||||
return m_pram[offset & 0x7ffff];
|
||||
else
|
||||
{
|
||||
int bank = (rom_access == 1) ? (offset / 0x10000) : (offset / 0x8000);
|
||||
return m_rom[rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(sns_rom_bsx_device::write_l)
|
||||
{
|
||||
if (offset < 0x200000 && access_00_1f)
|
||||
{
|
||||
// write to cart...
|
||||
return;
|
||||
}
|
||||
if (offset >= 0x200000 && offset < 0x400000)
|
||||
{
|
||||
// 0x20-0x3f:0x6000-0x7fff -> PRAM
|
||||
if ((offset & 0xffff) >= 0x6000 && (offset & 0xffff) < 0x8000)
|
||||
m_pram[offset & 0xffff] = data;
|
||||
}
|
||||
if (offset >= 0x400000 && offset < 0x500000 && access_40_4f)
|
||||
{
|
||||
// 0x40-0x4f:0x0000-0xffff -> PRAM
|
||||
m_pram[offset & 0x7ffff] = data;
|
||||
}
|
||||
if (offset >= 0x500000 && offset < 0x600000 && access_50_5f)
|
||||
{
|
||||
// 0x50-0x5f:0x0000-0xffff -> PRAM
|
||||
m_pram[offset & 0x7ffff] = data;
|
||||
}
|
||||
if (offset >= 0x600000 && offset < 0x700000 && access_60_6f)
|
||||
{
|
||||
// 0x60-0x6f:0x0000-0xffff -> PRAM
|
||||
m_pram[offset & 0x7ffff] = data;
|
||||
}
|
||||
if (offset >= 0x700000 && offset < 0x780000)
|
||||
{
|
||||
// 0x70-0x77:0x0000-0xffff -> PRAM
|
||||
m_pram[offset & 0x7ffff] = data;
|
||||
}
|
||||
|
||||
// if not in any of the cases above...
|
||||
//$00-3f|80-bf:8000-ffff
|
||||
//$40-7f|c0-ff:0000-ffff
|
||||
if (!rom_access)
|
||||
m_pram[offset & 0x7ffff] = data;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(sns_rom_bsx_device::write_h)
|
||||
{
|
||||
if (offset < 0x200000 && access_80_9f)
|
||||
{
|
||||
// write to cart...
|
||||
return;
|
||||
}
|
||||
|
||||
// if not in any of the cases above...
|
||||
//$00-3f|80-bf:8000-ffff
|
||||
//$40-7f|c0-ff:0000-ffff
|
||||
if (!rom_access)
|
||||
m_pram[offset & 0x7ffff] = data;
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(sns_rom_bsx_device::chip_read)
|
||||
{
|
||||
if ((offset & 0xffff) >= 0x2188 && (offset & 0xffff) < 0x21a0)
|
||||
return m_base_unit->read(offset & 0xffff);
|
||||
|
||||
if ((offset & 0xf0ffff) == 0x005000) //$[00-0f]:5000 reg access
|
||||
{
|
||||
UINT8 n = (offset >> 16) & 0x0f;
|
||||
return m_cart_regs[n];
|
||||
}
|
||||
|
||||
if ((offset & 0xf8f000) == 0x105000) //$[10-17]:[5000-5fff] SRAM access
|
||||
{
|
||||
return m_nvram[((offset >> 16) & 7) * 0x1000 + (offset & 0xfff)];
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(sns_rom_bsx_device::chip_write)
|
||||
{
|
||||
if ((offset & 0xffff) >= 0x2188 && (offset & 0xffff) < 0x21a0)
|
||||
m_base_unit->write(offset & 0xffff, data);
|
||||
|
||||
if ((offset & 0xf0ffff) == 0x005000) //$[00-0f]:5000 reg access
|
||||
{
|
||||
UINT8 n = (offset >> 16) & 0x0f;
|
||||
m_cart_regs[n] = data;
|
||||
if (n == 0x0e && data & 0x80)
|
||||
access_update();
|
||||
}
|
||||
|
||||
if ((offset & 0xf8f000) == 0x105000) //$[10-17]:[5000-5fff] SRAM access
|
||||
{
|
||||
m_nvram[((offset >> 16) & 7) * 0x1000 + (offset & 0xfff)] = data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// LoROM cart w/BS-X slot
|
||||
|
||||
READ8_MEMBER(sns_rom_bsxlo_device::read_l)
|
||||
{
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
int bank = offset / 0x10000;
|
||||
return m_rom[rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
if (offset >= 0x700000 && (offset & 0xffff) < 0x8000)
|
||||
{
|
||||
if (m_nvram_size > 0x8000)
|
||||
{
|
||||
// In this case, SRAM is mapped in 0x8000 chunks at diff offsets: 0x700000-0x707fff, 0x710000-0x717fff, etc.
|
||||
int mask = (m_nvram_size << 1) - 1;
|
||||
mask &= ~0x8000;
|
||||
return m_nvram[offset & mask];
|
||||
}
|
||||
else if (m_nvram_size > 0)
|
||||
{
|
||||
int mask = m_nvram_size - 1; /* Limit SRAM size to what's actually present */
|
||||
return m_nvram[offset & mask];
|
||||
}
|
||||
}
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
READ8_MEMBER(sns_rom_bsxlo_device::read_h)
|
||||
{
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
int bank = offset / 0x10000;
|
||||
if (offset < 0x200000)
|
||||
bank += 64;
|
||||
return m_rom[rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
else if (offset < 0x700000)
|
||||
{
|
||||
if (m_slot->m_cart && m_slot->m_cart->get_rom_size())
|
||||
return m_slot->m_cart->read_h(space, offset);
|
||||
}
|
||||
|
||||
if (offset >= 0x700000 && (offset & 0xffff) < 0x8000)
|
||||
{
|
||||
if (m_nvram_size > 0x8000)
|
||||
{
|
||||
// In this case, SRAM is mapped in 0x8000 chunks at diff offsets: 0x700000-0x707fff, 0x710000-0x717fff, etc.
|
||||
int mask = (m_nvram_size << 1) - 1;
|
||||
mask &= ~0x8000;
|
||||
return m_nvram[offset & mask];
|
||||
}
|
||||
else if (m_nvram_size > 0)
|
||||
{
|
||||
int mask = m_nvram_size - 1; /* Limit SRAM size to what's actually present */
|
||||
return m_nvram[offset & mask];
|
||||
}
|
||||
}
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
|
||||
// HiROM cart w/BS-X slot
|
||||
|
||||
READ8_MEMBER(sns_rom_bsxhi_device::read_l)
|
||||
{
|
||||
return read_h(space, offset);
|
||||
}
|
||||
|
||||
READ8_MEMBER(sns_rom_bsxhi_device::read_h)
|
||||
{
|
||||
if (offset < 0x200000 && (offset & 0xffff) >= 0x8000)
|
||||
{
|
||||
int bank = offset / 0x8000;
|
||||
return m_rom[rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
if (offset >= 0x200000 && offset < 0x400000)
|
||||
{
|
||||
if ((offset & 0xffff) >= 0x6000 && (offset & 0xffff) < 0x8000 && m_nvram_size > 0)
|
||||
{
|
||||
int mask = (m_nvram_size - 1) & 0x7fff;
|
||||
return m_nvram[(offset - 0x6000) & mask];
|
||||
}
|
||||
if ((offset & 0xffff) >= 0x8000 && m_slot->m_cart && m_slot->m_cart->get_rom_size())
|
||||
return m_slot->m_cart->read_h(space, offset);
|
||||
}
|
||||
if (offset >= 0x400000 && offset < 0x600000)
|
||||
{
|
||||
// TODO: Ongaku Tsukuru Kanadeeru does not like accesses in 0x0000-0x8000 here... investigate...
|
||||
int bank = offset / 0x8000;
|
||||
return m_rom[rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
if (offset >= 0x600000)
|
||||
{
|
||||
if (m_slot->m_cart && m_slot->m_cart->get_rom_size())
|
||||
return m_slot->m_cart->read_h(space, offset);
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(sns_rom_bsxhi_device::write_l)
|
||||
{
|
||||
write_h(space, offset, data);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(sns_rom_bsxhi_device::write_h)
|
||||
{
|
||||
if (offset >= 0x200000 && offset < 0x400000)
|
||||
{
|
||||
if ((offset & 0xffff) >= 0x6000 && (offset & 0xffff) < 0x8000 && m_nvram_size > 0)
|
||||
{
|
||||
int mask = (m_nvram_size - 1) & 0x7fff;
|
||||
m_nvram[(offset - 0x6000) & mask] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
BS-X Memory Packs
|
||||
-------------------------------------------------*/
|
||||
|
||||
// Here we're cheating a bit, for the moment, to avoid the need of BSX mempacks as a completely different device
|
||||
// which would require separate loading routines
|
||||
// Hence, we use low read handler for ROM access in the 0x8000-0xffff range (i.e. mempack mapped as LoROM) and
|
||||
// hi read handler for ROM access in the 0x0000-0xffff range (i.e. mempack mapped as HiROM)...
|
||||
|
||||
READ8_MEMBER(sns_rom_bsmempak_device::read_l)
|
||||
{
|
||||
int bank = offset / 0x10000;
|
||||
return m_rom[rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
|
||||
READ8_MEMBER(sns_rom_bsmempak_device::read_h)
|
||||
{
|
||||
int bank = offset / 0x8000;
|
||||
return m_rom[rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(sns_rom_bsmempak_device::write_l)
|
||||
{
|
||||
}
|
||||
|
159
src/mess/machine/sns_bsx.h
Normal file
159
src/mess/machine/sns_bsx.h
Normal file
@ -0,0 +1,159 @@
|
||||
#ifndef __SNS_BSX_H
|
||||
#define __SNS_BSX_H
|
||||
|
||||
#include "machine/sns_slot.h"
|
||||
#include "machine/sns_rom.h"
|
||||
#include "machine/sns_rom21.h"
|
||||
|
||||
class BSX_base
|
||||
{
|
||||
public:
|
||||
BSX_base(running_machine &machine);
|
||||
running_machine &machine() const { return m_machine; }
|
||||
|
||||
void init();
|
||||
UINT8 read(UINT32 offset);
|
||||
void write(UINT32 offset, UINT8 data);
|
||||
|
||||
private:
|
||||
// regs
|
||||
UINT8 regs[0x18]; // 0x2188-0x219f
|
||||
|
||||
// counter + clock
|
||||
UINT8 r2192_counter;
|
||||
UINT8 r2192_hour, r2192_minute, r2192_second;
|
||||
|
||||
running_machine& m_machine;
|
||||
};
|
||||
|
||||
// ======================> sns_rom_bsx_device
|
||||
|
||||
class sns_rom_bsx_device : public sns_rom_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom_bsx_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
|
||||
sns_rom_bsx_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() { m_shortname = "sns_rom_bsx"; }
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
// additional reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_l);
|
||||
virtual DECLARE_READ8_MEMBER(read_h);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_l);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_h);
|
||||
virtual DECLARE_READ8_MEMBER(chip_read);
|
||||
virtual DECLARE_WRITE8_MEMBER(chip_write);
|
||||
|
||||
// base regs
|
||||
BSX_base *m_base_unit;
|
||||
|
||||
// cart regs
|
||||
UINT8 m_cart_regs[16];
|
||||
UINT8 access_00_1f; // 1 = CART, 0 = NOTHING
|
||||
UINT8 access_80_9f; // 1 = CART, 0 = NOTHING
|
||||
UINT8 access_40_4f; // 1 = NOTHING, 0 = PRAM
|
||||
UINT8 access_50_5f; // 1 = NOTHING, 0 = PRAM
|
||||
UINT8 access_60_6f; // 1 = PRAM, 0 = NOTHING
|
||||
UINT8 rom_access; // 2 = HiROM, 1 = LoROM, 0 = PRAM
|
||||
void access_update();
|
||||
|
||||
|
||||
UINT8 m_pram[0x80000];
|
||||
|
||||
private:
|
||||
required_device<sns_bsx_cart_slot_device> m_slot;
|
||||
};
|
||||
|
||||
// ======================> sns_rom_bsxlo_device
|
||||
|
||||
class sns_rom_bsxlo_device : public sns_rom_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom_bsxlo_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() { m_shortname = "sns_rom_bsxlo"; }
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
// additional reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_l);
|
||||
virtual DECLARE_READ8_MEMBER(read_h);
|
||||
// virtual DECLARE_WRITE8_MEMBER(write_l);
|
||||
// virtual DECLARE_WRITE8_MEMBER(write_h);
|
||||
// virtual DECLARE_READ8_MEMBER(chip_read);
|
||||
// virtual DECLARE_WRITE8_MEMBER(chip_write);
|
||||
|
||||
private:
|
||||
required_device<sns_bsx_cart_slot_device> m_slot;
|
||||
};
|
||||
|
||||
// ======================> sns_rom_bsxhi_device
|
||||
|
||||
class sns_rom_bsxhi_device : public sns_rom21_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom_bsxhi_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() { m_shortname = "sns_rom_bsxhi"; }
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
// additional reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_l);
|
||||
virtual DECLARE_READ8_MEMBER(read_h);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_l);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_h);
|
||||
// virtual DECLARE_READ8_MEMBER(chip_read);
|
||||
// virtual DECLARE_WRITE8_MEMBER(chip_write);
|
||||
|
||||
private:
|
||||
required_device<sns_bsx_cart_slot_device> m_slot;
|
||||
};
|
||||
|
||||
|
||||
// ======================> sns_rom_bsmempak_device
|
||||
|
||||
class sns_rom_bsmempak_device : public sns_rom_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom_bsmempak_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() { m_shortname = "sns_bsmempak"; }
|
||||
|
||||
// additional reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_l);
|
||||
virtual DECLARE_READ8_MEMBER(read_h);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_l);
|
||||
// virtual DECLARE_WRITE8_MEMBER(write_h);
|
||||
// virtual DECLARE_READ8_MEMBER(chip_read);
|
||||
// virtual DECLARE_WRITE8_MEMBER(chip_write);
|
||||
|
||||
// flash regs
|
||||
UINT32 m_command;
|
||||
UINT8 m_write_old;
|
||||
UINT8 m_write_new;
|
||||
|
||||
int m_flash_enable;
|
||||
int m_read_enable;
|
||||
int m_write_enable;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type SNS_ROM_BSX;
|
||||
extern const device_type SNS_LOROM_BSX;
|
||||
extern const device_type SNS_HIROM_BSX;
|
||||
extern const device_type SNS_BSMEMPAK;
|
||||
|
||||
#endif
|
260
src/mess/machine/sns_rom.c
Normal file
260
src/mess/machine/sns_rom.c
Normal file
@ -0,0 +1,260 @@
|
||||
/***********************************************************************************************************
|
||||
|
||||
Super NES/Famicom (LoROM) cartridge emulation (for SNES/SFC)
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
***********************************************************************************************************/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "machine/sns_rom.h"
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// sns_rom_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
const device_type SNS_LOROM = &device_creator<sns_rom_device>;
|
||||
const device_type SNS_LOROM_OBC1 = &device_creator<sns_rom_obc1_device>;
|
||||
// LoROM pirate carts with protection
|
||||
const device_type SNS_LOROM_POKEMON = &device_creator<sns_rom_pokemon_device>;
|
||||
|
||||
|
||||
sns_rom_device::sns_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, type, name, tag, owner, clock),
|
||||
device_sns_cart_interface( mconfig, *this )
|
||||
{
|
||||
}
|
||||
|
||||
sns_rom_device::sns_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, SNS_LOROM, "SNES Cart (LoROM)", tag, owner, clock),
|
||||
device_sns_cart_interface( mconfig, *this )
|
||||
{
|
||||
}
|
||||
|
||||
sns_rom_pokemon_device::sns_rom_pokemon_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sns_rom_device(mconfig, SNS_LOROM_POKEMON, "SNES Pirate Carts with Protection", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
sns_rom_obc1_device::sns_rom_obc1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sns_rom_device(mconfig, SNS_LOROM_OBC1, "SNES Cart (LoROM) + OBC-1", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void sns_rom_device::device_start()
|
||||
{
|
||||
memset(rom_bank_map, 0, sizeof(rom_bank_map));
|
||||
}
|
||||
|
||||
void sns_rom_pokemon_device::device_start()
|
||||
{
|
||||
m_latch = 0;
|
||||
save_item(NAME(m_latch));
|
||||
}
|
||||
|
||||
void sns_rom_obc1_device::device_start()
|
||||
{
|
||||
memset(m_ram, 0xff, sizeof(m_ram));
|
||||
// or from rom?
|
||||
m_offset = (m_ram[0x1ff5] & 0x01) ? 0x1800 : 0x1c00;
|
||||
m_address = (m_ram[0x1ff6] & 0x7f);
|
||||
m_shift = (m_ram[0x1ff6] & 0x03) << 1;
|
||||
|
||||
save_item(NAME(m_ram));
|
||||
save_item(NAME(m_address));
|
||||
save_item(NAME(m_offset));
|
||||
save_item(NAME(m_shift));
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
mapper specific handlers
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER(sns_rom_device::read_l)
|
||||
{
|
||||
return read_h(space, offset);
|
||||
}
|
||||
|
||||
READ8_MEMBER(sns_rom_device::read_h)
|
||||
{
|
||||
UINT8 value = 0xff;
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset < 0x700000)
|
||||
{
|
||||
int bank = offset / 0x10000;
|
||||
value = m_rom[rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (address < 0x8000)
|
||||
{
|
||||
if (m_nvram_size > 0x8000)
|
||||
{
|
||||
// In this case, SRAM is mapped in 0x8000 chunks at diff offsets: 0x700000-0x707fff, 0x710000-0x717fff, etc.
|
||||
int mask = m_nvram_size - 1;
|
||||
offset = ((offset - 0x700000) / 0x10000) * 0x8000 + (offset & 0x7fff);
|
||||
value = m_nvram[offset & mask];
|
||||
}
|
||||
else if (m_nvram_size > 0)
|
||||
{
|
||||
int mask = m_nvram_size - 1; /* Limit SRAM size to what's actually present */
|
||||
value = m_nvram[offset & mask];
|
||||
}
|
||||
else
|
||||
value = 0xff; // this should never happened...
|
||||
}
|
||||
else
|
||||
{
|
||||
int bank = offset / 0x10000;
|
||||
value = m_rom[rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(sns_rom_device::write_l)
|
||||
{
|
||||
write_h(space, offset, data);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(sns_rom_device::write_h)
|
||||
{
|
||||
if (offset >= 0x700000) // SRAM
|
||||
{
|
||||
if (m_nvram_size > 0x8000)
|
||||
{
|
||||
// In this case, SRAM is mapped in 0x8000 chunks at diff offsets: 0x700000-0x707fff, 0x710000-0x717fff, etc.
|
||||
int mask = m_nvram_size - 1;
|
||||
offset = ((offset - 0x700000) / 0x10000) * 0x8000 + (offset & 0x7fff);
|
||||
m_nvram[offset & mask] = data;
|
||||
}
|
||||
else if (m_nvram_size > 0)
|
||||
{
|
||||
int mask = m_nvram_size - 1; /* Limit SRAM size to what's actually present */
|
||||
m_nvram[offset & mask] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Lo-ROM + Protection device
|
||||
|
||||
READ8_MEMBER( sns_rom_pokemon_device::chip_read )
|
||||
{
|
||||
return BITSWAP8(m_latch,0,6,7,1,2,3,4,5);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( sns_rom_pokemon_device::chip_write )
|
||||
{
|
||||
m_latch = data;
|
||||
}
|
||||
|
||||
|
||||
// Lo-ROM + OBC-1 (used by Metal Combat - Falcon's Revenge)
|
||||
// same as above but additional read/write handling for the add-on chip
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Based on C++ implementation by Byuu in BSNES.
|
||||
|
||||
Byuu's code is released under GNU General Public License
|
||||
version 2 as published by the Free Software Foundation.
|
||||
|
||||
The implementation below is released under the MAME license
|
||||
for use in MAME, MESS and derivatives by permission of Byuu
|
||||
|
||||
Copyright (for the implementation below) MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
***********************************************************************************************************/
|
||||
|
||||
|
||||
READ8_MEMBER( sns_rom_obc1_device::chip_read )
|
||||
{
|
||||
UINT16 address = offset & 0x1fff;
|
||||
UINT8 value;
|
||||
|
||||
switch (address)
|
||||
{
|
||||
case 0x1ff0:
|
||||
value = m_ram[m_offset + (m_address << 2) + 0];
|
||||
break;
|
||||
|
||||
case 0x1ff1:
|
||||
value = m_ram[m_offset + (m_address << 2) + 1];
|
||||
break;
|
||||
|
||||
case 0x1ff2:
|
||||
value = m_ram[m_offset + (m_address << 2) + 2];
|
||||
break;
|
||||
|
||||
case 0x1ff3:
|
||||
value = m_ram[m_offset + (m_address << 2) + 3];
|
||||
break;
|
||||
|
||||
case 0x1ff4:
|
||||
value = m_ram[m_offset + (m_address >> 2) + 0x200];
|
||||
break;
|
||||
|
||||
default:
|
||||
value = m_ram[address];
|
||||
break;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER( sns_rom_obc1_device::chip_write )
|
||||
{
|
||||
UINT16 address = offset & 0x1fff;
|
||||
UINT8 temp;
|
||||
|
||||
switch(address)
|
||||
{
|
||||
case 0x1ff0:
|
||||
m_ram[m_offset + (m_address << 2) + 0] = data;
|
||||
break;
|
||||
|
||||
case 0x1ff1:
|
||||
m_ram[m_offset + (m_address << 2) + 1] = data;
|
||||
break;
|
||||
|
||||
case 0x1ff2:
|
||||
m_ram[m_offset + (m_address << 2) + 2] = data;
|
||||
break;
|
||||
|
||||
case 0x1ff3:
|
||||
m_ram[m_offset + (m_address << 2) + 3] = data;
|
||||
break;
|
||||
|
||||
case 0x1ff4:
|
||||
temp = m_ram[m_offset + (m_address >> 2) + 0x200];
|
||||
temp = (temp & ~(3 << m_shift)) | ((data & 0x03) << m_shift);
|
||||
m_ram[m_offset + (m_address >> 2) + 0x200] = temp;
|
||||
break;
|
||||
|
||||
case 0x1ff5:
|
||||
m_offset = (data & 0x01) ? 0x1800 : 0x1c00;
|
||||
m_ram[address & 0x1fff] = data;
|
||||
break;
|
||||
|
||||
case 0x1ff6:
|
||||
m_address = data & 0x7f;
|
||||
m_shift = (data & 0x03) << 1;
|
||||
m_ram[address & 0x1fff] = data;
|
||||
break;
|
||||
|
||||
default:
|
||||
m_ram[address & 0x1fff] = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
74
src/mess/machine/sns_rom.h
Normal file
74
src/mess/machine/sns_rom.h
Normal file
@ -0,0 +1,74 @@
|
||||
#ifndef __SNS_ROM_H
|
||||
#define __SNS_ROM_H
|
||||
|
||||
#include "machine/sns_slot.h"
|
||||
|
||||
|
||||
// ======================> sns_rom_device
|
||||
|
||||
class sns_rom_device : public device_t,
|
||||
public device_sns_cart_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
|
||||
sns_rom_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() { m_shortname = "sns_rom"; }
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_l);
|
||||
virtual DECLARE_READ8_MEMBER(read_h);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_l);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_h);
|
||||
};
|
||||
|
||||
// ======================> sns_rom_pokemon_device
|
||||
|
||||
class sns_rom_pokemon_device : public sns_rom_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom_pokemon_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() { m_shortname = "sns_rom_pokemon"; }
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(chip_read); // protection device
|
||||
virtual DECLARE_WRITE8_MEMBER(chip_write); // protection device
|
||||
UINT8 m_latch;
|
||||
};
|
||||
|
||||
// ======================> sns_rom_obc1_device
|
||||
|
||||
class sns_rom_obc1_device : public sns_rom_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom_obc1_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() { m_shortname = "sns_rom_obc1"; }
|
||||
|
||||
// additional reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(chip_read);
|
||||
virtual DECLARE_WRITE8_MEMBER(chip_write);
|
||||
|
||||
int m_address;
|
||||
int m_offset;
|
||||
int m_shift;
|
||||
UINT8 m_ram[0x2000];
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type SNS_LOROM;
|
||||
extern const device_type SNS_LOROM_OBC1;
|
||||
extern const device_type SNS_LOROM_POKEMON;
|
||||
|
||||
#endif
|
306
src/mess/machine/sns_rom21.c
Normal file
306
src/mess/machine/sns_rom21.c
Normal file
@ -0,0 +1,306 @@
|
||||
/***********************************************************************************************************
|
||||
|
||||
Super NES/Famicom (HiROM) cartridge emulation (for SNES/SFC)
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
***********************************************************************************************************/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "machine/sns_rom21.h"
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// sns_rom_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
const device_type SNS_HIROM = &device_creator<sns_rom21_device>;
|
||||
const device_type SNS_HIROM_SRTC = &device_creator<sns_rom21_srtc_device>;
|
||||
|
||||
|
||||
sns_rom21_device::sns_rom21_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, type, name, tag, owner, clock),
|
||||
device_sns_cart_interface( mconfig, *this )
|
||||
{
|
||||
}
|
||||
|
||||
sns_rom21_device::sns_rom21_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, SNS_HIROM, "SNES Cart (HiROM)", tag, owner, clock),
|
||||
device_sns_cart_interface( mconfig, *this )
|
||||
{
|
||||
}
|
||||
|
||||
sns_rom21_srtc_device::sns_rom21_srtc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sns_rom21_device(mconfig, SNS_HIROM_SRTC, "SNES Cart (HiROM) + S-RTC", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void sns_rom21_device::device_start()
|
||||
{
|
||||
memset(rom_bank_map, 0, sizeof(rom_bank_map));
|
||||
}
|
||||
|
||||
void sns_rom21_srtc_device::device_start()
|
||||
{
|
||||
memset(rom_bank_map, 0, sizeof(rom_bank_map));
|
||||
|
||||
m_mode = RTCM_Read;
|
||||
m_index = -1;
|
||||
|
||||
// at this stage, rtc_ram is not yet allocated. this will be fixed when converting RTC to be a separate device.
|
||||
// update_time();
|
||||
|
||||
save_item(NAME(m_mode));
|
||||
save_item(NAME(m_index));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
mapper specific handlers
|
||||
-------------------------------------------------*/
|
||||
|
||||
// low and hi reads are not the same! (different ROM banks are accessed)
|
||||
|
||||
READ8_MEMBER(sns_rom21_device::read_l)
|
||||
{
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset >= 0x300000 && offset < 0x400000 && address < 0x8000)
|
||||
{
|
||||
if (m_nvram_size > 0)
|
||||
{
|
||||
/* Donkey Kong Country checks this and detects a copier if 0x800 is not masked out due to sram size */
|
||||
/* OTOH Secret of Mana does not work properly if sram is not mirrored on later banks */
|
||||
int mask = (m_nvram_size - 1) & 0x7fff; /* Limit SRAM size to what's actually present */
|
||||
return m_nvram[(offset - 0x6000) & mask];
|
||||
}
|
||||
}
|
||||
|
||||
// here ROM banks from 128 to 255, mirrored twice
|
||||
int bank = (offset & 0x3fffff) / 0x8000;
|
||||
return m_rom[rom_bank_map[bank + 0x80] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
|
||||
READ8_MEMBER(sns_rom21_device::read_h)
|
||||
{
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset >= 0x300000 && offset < 0x400000 && address < 0x8000)
|
||||
{
|
||||
if (m_nvram_size > 0)
|
||||
{
|
||||
/* Donkey Kong Country checks this and detects a copier if 0x800 is not masked out due to sram size */
|
||||
/* OTOH Secret of Mana does not work properly if sram is not mirrored on later banks */
|
||||
int mask = (m_nvram_size - 1) & 0x7fff; /* Limit SRAM size to what's actually present */
|
||||
return m_nvram[(offset - 0x6000) & mask];
|
||||
}
|
||||
}
|
||||
|
||||
// here ROM banks from 0 to 127, mirrored twice
|
||||
int bank = (offset & 0x3fffff) / 0x8000;
|
||||
return m_rom[rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(sns_rom21_device::write_l)
|
||||
{
|
||||
write_h(space, offset, data);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(sns_rom21_device::write_h)
|
||||
{
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset >= 0x300000 && offset < 0x400000 && address < 0x8000)
|
||||
{
|
||||
if (m_nvram_size > 0)
|
||||
{
|
||||
/* Donkey Kong Country checks this and detects a copier if 0x800 is not masked out due to sram size */
|
||||
/* OTOH Secret of Mana does not work properly if sram is not mirrored on later banks */
|
||||
int mask = (m_nvram_size - 1) & 0x7fff; /* Limit SRAM size to what's actually present */
|
||||
m_nvram[(offset - 0x6000) & mask] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hi-ROM + S-RTC (used by Daikaijuu Monogatari II)
|
||||
// same as above but additional read/write handling for the RTC
|
||||
/***************************************************************************
|
||||
|
||||
Based on C++ implementation by Byuu in BSNES.
|
||||
|
||||
Byuu's code is released under GNU General Public License
|
||||
version 2 as published by the Free Software Foundation.
|
||||
|
||||
The implementation below is released under the MAME license
|
||||
for use in MAME, MESS and derivatives by permission of Byuu
|
||||
|
||||
Copyright (for the implementation below) MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
static const UINT8 srtc_months[12] =
|
||||
{
|
||||
31, 28, 31,
|
||||
30, 31, 30,
|
||||
31, 31, 30,
|
||||
31, 30, 31
|
||||
};
|
||||
|
||||
void sns_rom21_srtc_device::update_time()
|
||||
{
|
||||
system_time curtime, *systime = &curtime;
|
||||
machine().current_datetime(curtime);
|
||||
m_rtc_ram[0] = systime->local_time.second % 10;
|
||||
m_rtc_ram[1] = systime->local_time.second / 10;
|
||||
m_rtc_ram[2] = systime->local_time.minute % 10;
|
||||
m_rtc_ram[3] = systime->local_time.minute / 10;
|
||||
m_rtc_ram[4] = systime->local_time.hour % 10;
|
||||
m_rtc_ram[5] = systime->local_time.hour / 10;
|
||||
m_rtc_ram[6] = systime->local_time.mday % 10;
|
||||
m_rtc_ram[7] = systime->local_time.mday / 10;
|
||||
m_rtc_ram[8] = systime->local_time.month;
|
||||
m_rtc_ram[9] = (systime->local_time.year - 1000) % 10;
|
||||
m_rtc_ram[10] = ((systime->local_time.year - 1000) / 10) % 10;
|
||||
m_rtc_ram[11] = (systime->local_time.year - 1000) / 100;
|
||||
m_rtc_ram[12] = systime->local_time.weekday % 7;
|
||||
}
|
||||
|
||||
// Returns day-of-week for specified date
|
||||
// e.g. 0 = Sunday, 1 = Monday, ... 6 = Saturday
|
||||
// Usage: weekday(2008, 1, 1) returns the weekday of January 1st, 2008
|
||||
UINT8 sns_rom21_srtc_device::srtc_weekday( UINT32 year, UINT32 month, UINT32 day )
|
||||
{
|
||||
UINT32 y = 1900, m = 1; // Epoch is 1900-01-01
|
||||
UINT32 sum = 0; // Number of days passed since epoch
|
||||
|
||||
year = MAX(1900, year);
|
||||
month = MAX(1, MIN(12, month));
|
||||
day = MAX(1, MIN(31, day));
|
||||
|
||||
while (y < year)
|
||||
{
|
||||
UINT8 leapyear = 0;
|
||||
if ((y % 4) == 0)
|
||||
{
|
||||
leapyear = 1;
|
||||
if ((y % 100) == 0 && (y % 400) != 0)
|
||||
{
|
||||
leapyear = 0;
|
||||
}
|
||||
}
|
||||
sum += leapyear ? 366 : 365;
|
||||
y++;
|
||||
}
|
||||
|
||||
while (m < month)
|
||||
{
|
||||
UINT32 days = srtc_months[m - 1];
|
||||
if (days == 28)
|
||||
{
|
||||
UINT8 leapyear = 0;
|
||||
if ((y % 4) == 0)
|
||||
{
|
||||
leapyear = 1;
|
||||
if ((y % 100) == 0 && (y % 400) != 0)
|
||||
{
|
||||
leapyear = 0;
|
||||
}
|
||||
}
|
||||
days += leapyear ? 1 : 0;
|
||||
}
|
||||
sum += days;
|
||||
m++;
|
||||
}
|
||||
|
||||
sum += day - 1;
|
||||
return (sum + 1) % 7; // 1900-01-01 was a Monday
|
||||
}
|
||||
|
||||
|
||||
// this gets called only for accesses at 0x2800,
|
||||
// because for 0x2801 open bus gets returned...
|
||||
READ8_MEMBER(sns_rom21_srtc_device::chip_read)
|
||||
{
|
||||
if (m_mode != RTCM_Read)
|
||||
return 0x00;
|
||||
|
||||
if (m_index < 0)
|
||||
{
|
||||
update_time();
|
||||
m_index++;
|
||||
return 0x0f;
|
||||
}
|
||||
else if (m_index > 12)
|
||||
{
|
||||
m_index = -1;
|
||||
return 0x0f;
|
||||
}
|
||||
else
|
||||
return m_rtc_ram[m_index++];
|
||||
}
|
||||
|
||||
// this gets called only for accesses at 0x2801
|
||||
WRITE8_MEMBER(sns_rom21_srtc_device::chip_write)
|
||||
{
|
||||
data &= 0x0f; // Only the low four bits are used
|
||||
|
||||
if (data == 0x0d)
|
||||
{
|
||||
m_mode = RTCM_Read;
|
||||
m_index = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (data == 0x0e)
|
||||
{
|
||||
m_mode = RTCM_Command;
|
||||
return;
|
||||
}
|
||||
|
||||
if (data == 0x0f)
|
||||
return; // Unknown behaviour
|
||||
|
||||
if (m_mode == RTCM_Write)
|
||||
{
|
||||
if (m_index >= 0 && m_index < 12)
|
||||
{
|
||||
m_rtc_ram[m_index++] = data;
|
||||
|
||||
if (m_index == 12)
|
||||
{
|
||||
// Day of week is automatically calculated and written
|
||||
UINT32 day = m_rtc_ram[6] + m_rtc_ram[7] * 10;
|
||||
UINT32 month = m_rtc_ram[8];
|
||||
UINT32 year = m_rtc_ram[9] + m_rtc_ram[10] * 10 + m_rtc_ram[11] * 100;
|
||||
year += 1000;
|
||||
|
||||
m_rtc_ram[m_index++] = srtc_weekday(year, month, day);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_mode == RTCM_Command)
|
||||
{
|
||||
if (data == 0)
|
||||
{
|
||||
m_mode = RTCM_Write;
|
||||
m_index = 0;
|
||||
}
|
||||
else if (data == 4)
|
||||
{
|
||||
UINT8 i;
|
||||
m_mode = RTCM_Ready;
|
||||
m_index = -1;
|
||||
for(i = 0; i < 13; i++)
|
||||
m_rtc_ram[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown behaviour
|
||||
m_mode = RTCM_Ready;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
67
src/mess/machine/sns_rom21.h
Normal file
67
src/mess/machine/sns_rom21.h
Normal file
@ -0,0 +1,67 @@
|
||||
#ifndef __SNS_ROM21_H
|
||||
#define __SNS_ROM21_H
|
||||
|
||||
#include "machine/sns_slot.h"
|
||||
|
||||
|
||||
// ======================> sns_rom21_device
|
||||
|
||||
class sns_rom21_device : public device_t,
|
||||
public device_sns_cart_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom21_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
|
||||
sns_rom21_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() { m_shortname = "sns_rom21"; }
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_l);
|
||||
virtual DECLARE_READ8_MEMBER(read_h);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_l);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_h);
|
||||
};
|
||||
|
||||
// ======================> sns_rom21_srtc_device
|
||||
|
||||
class sns_rom21_srtc_device : public sns_rom21_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom21_srtc_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() { m_shortname = "sns_rom21_srtc"; }
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(chip_read);
|
||||
virtual DECLARE_WRITE8_MEMBER(chip_write);
|
||||
|
||||
// S-RTC specific variables
|
||||
enum
|
||||
{
|
||||
RTCM_Ready = 0,
|
||||
RTCM_Command,
|
||||
RTCM_Read,
|
||||
RTCM_Write
|
||||
};
|
||||
|
||||
void update_time();
|
||||
UINT8 srtc_weekday(UINT32 year, UINT32 month, UINT32 day);
|
||||
|
||||
//this is now allocated in the main snes cart class, to allow saving to nvram
|
||||
//UINT8 m_rtc_ram[13];
|
||||
INT32 m_mode;
|
||||
INT8 m_index;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type SNS_HIROM;
|
||||
extern const device_type SNS_HIROM_SRTC;
|
||||
|
||||
#endif
|
602
src/mess/machine/sns_sdd1.c
Normal file
602
src/mess/machine/sns_sdd1.c
Normal file
@ -0,0 +1,602 @@
|
||||
/***********************************************************************************************************
|
||||
|
||||
S-DD1 add-on chip emulation (for SNES/SFC)
|
||||
|
||||
Based on Andreas Naive Public Domain code.
|
||||
Code ported by MooglyGuy and updated to slots by Fabio Priuli.
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
***********************************************************************************************************/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "machine/sns_sdd1.h"
|
||||
|
||||
|
||||
#define SSD1_ADD(addr)\
|
||||
mmc[(addr >> 20) & 3] + (addr & 0x0fffff)
|
||||
|
||||
|
||||
// Input Manager
|
||||
|
||||
void SDD1__IM::IM_prepareDecomp(UINT32 in_buf)
|
||||
{
|
||||
m_byte_ptr = in_buf;
|
||||
m_bit_count = 4;
|
||||
}
|
||||
|
||||
UINT8 SDD1__IM::IM_getCodeword(UINT8 *ROM, UINT32 *mmc, const UINT8 code_len)
|
||||
{
|
||||
UINT8 codeword = ROM[SSD1_ADD(m_byte_ptr)] << m_bit_count;
|
||||
|
||||
++m_bit_count;
|
||||
|
||||
if (codeword & 0x80)
|
||||
{
|
||||
codeword |= ROM[SSD1_ADD((m_byte_ptr + 1))] >> (9 - m_bit_count);
|
||||
m_bit_count += code_len;
|
||||
}
|
||||
|
||||
if (m_bit_count & 0x08)
|
||||
{
|
||||
m_byte_ptr++;
|
||||
m_bit_count &= 0x07;
|
||||
}
|
||||
|
||||
return codeword;
|
||||
}
|
||||
|
||||
// GCD
|
||||
|
||||
void SDD1__GCD::GCD_getRunCount(UINT8 *ROM, UINT32 *mmc, UINT8 code_num, UINT8* MPScount, UINT8* LPSind)
|
||||
{
|
||||
const UINT8 run_count[] =
|
||||
{
|
||||
0x00, 0x00, 0x01, 0x00, 0x03, 0x01, 0x02, 0x00,
|
||||
0x07, 0x03, 0x05, 0x01, 0x06, 0x02, 0x04, 0x00,
|
||||
0x0f, 0x07, 0x0b, 0x03, 0x0d, 0x05, 0x09, 0x01,
|
||||
0x0e, 0x06, 0x0a, 0x02, 0x0c, 0x04, 0x08, 0x00,
|
||||
0x1f, 0x0f, 0x17, 0x07, 0x1b, 0x0b, 0x13, 0x03,
|
||||
0x1d, 0x0d, 0x15, 0x05, 0x19, 0x09, 0x11, 0x01,
|
||||
0x1e, 0x0e, 0x16, 0x06, 0x1a, 0x0a, 0x12, 0x02,
|
||||
0x1c, 0x0c, 0x14, 0x04, 0x18, 0x08, 0x10, 0x00,
|
||||
0x3f, 0x1f, 0x2f, 0x0f, 0x37, 0x17, 0x27, 0x07,
|
||||
0x3b, 0x1b, 0x2b, 0x0b, 0x33, 0x13, 0x23, 0x03,
|
||||
0x3d, 0x1d, 0x2d, 0x0d, 0x35, 0x15, 0x25, 0x05,
|
||||
0x39, 0x19, 0x29, 0x09, 0x31, 0x11, 0x21, 0x01,
|
||||
0x3e, 0x1e, 0x2e, 0x0e, 0x36, 0x16, 0x26, 0x06,
|
||||
0x3a, 0x1a, 0x2a, 0x0a, 0x32, 0x12, 0x22, 0x02,
|
||||
0x3c, 0x1c, 0x2c, 0x0c, 0x34, 0x14, 0x24, 0x04,
|
||||
0x38, 0x18, 0x28, 0x08, 0x30, 0x10, 0x20, 0x00,
|
||||
0x7f, 0x3f, 0x5f, 0x1f, 0x6f, 0x2f, 0x4f, 0x0f,
|
||||
0x77, 0x37, 0x57, 0x17, 0x67, 0x27, 0x47, 0x07,
|
||||
0x7b, 0x3b, 0x5b, 0x1b, 0x6b, 0x2b, 0x4b, 0x0b,
|
||||
0x73, 0x33, 0x53, 0x13, 0x63, 0x23, 0x43, 0x03,
|
||||
0x7d, 0x3d, 0x5d, 0x1d, 0x6d, 0x2d, 0x4d, 0x0d,
|
||||
0x75, 0x35, 0x55, 0x15, 0x65, 0x25, 0x45, 0x05,
|
||||
0x79, 0x39, 0x59, 0x19, 0x69, 0x29, 0x49, 0x09,
|
||||
0x71, 0x31, 0x51, 0x11, 0x61, 0x21, 0x41, 0x01,
|
||||
0x7e, 0x3e, 0x5e, 0x1e, 0x6e, 0x2e, 0x4e, 0x0e,
|
||||
0x76, 0x36, 0x56, 0x16, 0x66, 0x26, 0x46, 0x06,
|
||||
0x7a, 0x3a, 0x5a, 0x1a, 0x6a, 0x2a, 0x4a, 0x0a,
|
||||
0x72, 0x32, 0x52, 0x12, 0x62, 0x22, 0x42, 0x02,
|
||||
0x7c, 0x3c, 0x5c, 0x1c, 0x6c, 0x2c, 0x4c, 0x0c,
|
||||
0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04,
|
||||
0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08,
|
||||
0x70, 0x30, 0x50, 0x10, 0x60, 0x20, 0x40, 0x00,
|
||||
};
|
||||
|
||||
UINT8 codeword = m_IM->IM_getCodeword(ROM, mmc, code_num);
|
||||
|
||||
if (codeword & 0x80)
|
||||
{
|
||||
*LPSind = 1;
|
||||
*MPScount = run_count[codeword >> (code_num ^ 0x07)];
|
||||
}
|
||||
else
|
||||
{
|
||||
*MPScount = (1 << code_num);
|
||||
}
|
||||
}
|
||||
|
||||
// BG
|
||||
|
||||
void SDD1__BG::BG_prepareDecomp()
|
||||
{
|
||||
m_MPScount = 0;
|
||||
m_LPSind = 0;
|
||||
}
|
||||
|
||||
UINT8 SDD1__BG::BG_getBit(UINT8 *ROM, UINT32 *mmc, UINT8* endOfRun)
|
||||
{
|
||||
UINT8 bit;
|
||||
|
||||
if (!(m_MPScount || m_LPSind))
|
||||
{
|
||||
m_GCD->GCD_getRunCount(ROM, mmc, m_code_num, &(m_MPScount), &(m_LPSind));
|
||||
}
|
||||
|
||||
if (m_MPScount)
|
||||
{
|
||||
bit = 0;
|
||||
m_MPScount--;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit = 1;
|
||||
m_LPSind = 0;
|
||||
}
|
||||
|
||||
if (m_MPScount || m_LPSind)
|
||||
{
|
||||
(*endOfRun) = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*endOfRun) = 1;
|
||||
}
|
||||
|
||||
return bit;
|
||||
}
|
||||
|
||||
// PEM
|
||||
|
||||
struct SDD1__PEM_state
|
||||
{
|
||||
UINT8 code_num;
|
||||
UINT8 nextIfMPS;
|
||||
UINT8 nextIfLPS;
|
||||
};
|
||||
|
||||
static const SDD1__PEM_state PEM_evolution_table[33] =
|
||||
{
|
||||
{ 0,25,25},
|
||||
{ 0, 2, 1},
|
||||
{ 0, 3, 1},
|
||||
{ 0, 4, 2},
|
||||
{ 0, 5, 3},
|
||||
{ 1, 6, 4},
|
||||
{ 1, 7, 5},
|
||||
{ 1, 8, 6},
|
||||
{ 1, 9, 7},
|
||||
{ 2,10, 8},
|
||||
{ 2,11, 9},
|
||||
{ 2,12,10},
|
||||
{ 2,13,11},
|
||||
{ 3,14,12},
|
||||
{ 3,15,13},
|
||||
{ 3,16,14},
|
||||
{ 3,17,15},
|
||||
{ 4,18,16},
|
||||
{ 4,19,17},
|
||||
{ 5,20,18},
|
||||
{ 5,21,19},
|
||||
{ 6,22,20},
|
||||
{ 6,23,21},
|
||||
{ 7,24,22},
|
||||
{ 7,24,23},
|
||||
{ 0,26, 1},
|
||||
{ 1,27, 2},
|
||||
{ 2,28, 4},
|
||||
{ 3,29, 8},
|
||||
{ 4,30,12},
|
||||
{ 5,31,16},
|
||||
{ 6,32,18},
|
||||
{ 7,24,22}
|
||||
};
|
||||
|
||||
void SDD1__PEM::PEM_prepareDecomp()
|
||||
{
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
m_contextInfo[i].status = 0;
|
||||
m_contextInfo[i].MPS = 0;
|
||||
}
|
||||
}
|
||||
|
||||
UINT8 SDD1__PEM::PEM_getBit(UINT8 *ROM, UINT32 *mmc, UINT8 context)
|
||||
{
|
||||
UINT8 endOfRun;
|
||||
UINT8 bit;
|
||||
|
||||
SDD1__PEM_ContextInfo *pContInfo = &(m_contextInfo)[context];
|
||||
UINT8 currStatus = pContInfo->status;
|
||||
const SDD1__PEM_state* pState = &(PEM_evolution_table[currStatus]);
|
||||
UINT8 currentMPS = pContInfo->MPS;
|
||||
|
||||
bit = m_BG[pState->code_num]->BG_getBit(ROM, mmc, &endOfRun);
|
||||
|
||||
if (endOfRun)
|
||||
{
|
||||
if (bit)
|
||||
{
|
||||
if (!(currStatus & 0xfe))
|
||||
{
|
||||
(pContInfo->MPS) ^= 0x01;
|
||||
}
|
||||
pContInfo->status = pState->nextIfLPS;
|
||||
}
|
||||
else
|
||||
{
|
||||
pContInfo->status = pState->nextIfMPS;
|
||||
}
|
||||
}
|
||||
|
||||
return bit ^ currentMPS;
|
||||
}
|
||||
|
||||
// CM
|
||||
|
||||
void SDD1__CM::CM_prepareDecomp(UINT8 *ROM, UINT32 *mmc, UINT32 first_byte)
|
||||
{
|
||||
INT32 i = 0;
|
||||
m_bitplanesInfo = ROM[SSD1_ADD(first_byte)] & 0xc0;
|
||||
m_contextBitsInfo = ROM[SSD1_ADD(first_byte)] & 0x30;
|
||||
m_bit_number = 0;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
m_prevBitplaneBits[i] = 0;
|
||||
}
|
||||
switch (m_bitplanesInfo)
|
||||
{
|
||||
case 0x00:
|
||||
m_currBitplane = 1;
|
||||
break;
|
||||
case 0x40:
|
||||
m_currBitplane = 7;
|
||||
break;
|
||||
case 0x80:
|
||||
m_currBitplane = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UINT8 SDD1__CM::CM_getBit(UINT8 *ROM, UINT32 *mmc)
|
||||
{
|
||||
UINT8 currContext;
|
||||
UINT16 *context_bits;
|
||||
UINT8 bit = 0;
|
||||
|
||||
switch (m_bitplanesInfo)
|
||||
{
|
||||
case 0x00:
|
||||
m_currBitplane ^= 0x01;
|
||||
break;
|
||||
case 0x40:
|
||||
m_currBitplane ^= 0x01;
|
||||
if (!(m_bit_number & 0x7f))
|
||||
m_currBitplane = ((m_currBitplane + 2) & 0x07);
|
||||
break;
|
||||
case 0x80:
|
||||
m_currBitplane ^= 0x01;
|
||||
if (!(m_bit_number & 0x7f))
|
||||
m_currBitplane ^= 0x02;
|
||||
break;
|
||||
case 0xc0:
|
||||
m_currBitplane = m_bit_number & 0x07;
|
||||
break;
|
||||
}
|
||||
|
||||
context_bits = &(m_prevBitplaneBits)[m_currBitplane];
|
||||
|
||||
currContext = (m_currBitplane & 0x01) << 4;
|
||||
switch (m_contextBitsInfo)
|
||||
{
|
||||
case 0x00:
|
||||
currContext |= ((*context_bits & 0x01c0) >> 5) | (*context_bits & 0x0001);
|
||||
break;
|
||||
case 0x10:
|
||||
currContext |= ((*context_bits & 0x0180) >> 5) | (*context_bits & 0x0001);
|
||||
break;
|
||||
case 0x20:
|
||||
currContext |= ((*context_bits & 0x00c0) >> 5) | (*context_bits & 0x0001);
|
||||
break;
|
||||
case 0x30:
|
||||
currContext |= ((*context_bits & 0x0180) >> 5) | (*context_bits & 0x0003);
|
||||
break;
|
||||
}
|
||||
|
||||
bit = m_PEM->PEM_getBit(ROM, mmc, currContext);
|
||||
|
||||
*context_bits <<= 1;
|
||||
*context_bits |= bit;
|
||||
|
||||
m_bit_number++;
|
||||
|
||||
return bit;
|
||||
}
|
||||
|
||||
// OL
|
||||
|
||||
void SDD1__OL::OL_prepareDecomp(UINT8 *ROM, UINT32 *mmc, UINT32 first_byte, UINT16 out_len, UINT8 *out_buf)
|
||||
{
|
||||
m_bitplanesInfo = ROM[SSD1_ADD(first_byte)] & 0xc0;
|
||||
m_length = out_len;
|
||||
m_buffer = out_buf;
|
||||
}
|
||||
|
||||
void SDD1__OL::OL_launch(UINT8 *ROM, UINT32 *mmc)
|
||||
{
|
||||
UINT8 i;
|
||||
UINT8 register1 = 0, register2 = 0;
|
||||
|
||||
switch (m_bitplanesInfo)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x40:
|
||||
case 0x80:
|
||||
i = 1;
|
||||
do
|
||||
{ // if length == 0, we output 2^16 bytes
|
||||
if (!i)
|
||||
{
|
||||
*(m_buffer++) = register2;
|
||||
i = ~i;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (register1 = register2 = 0, i = 0x80; i; i >>= 1)
|
||||
{
|
||||
if (m_CM->CM_getBit(ROM, mmc))
|
||||
register1 |= i;
|
||||
|
||||
if (m_CM->CM_getBit(ROM, mmc))
|
||||
register2 |= i;
|
||||
}
|
||||
*(m_buffer++) = register1;
|
||||
}
|
||||
} while (--(m_length));
|
||||
break;
|
||||
case 0xc0:
|
||||
do
|
||||
{
|
||||
for (register1 = 0, i = 0x01; i; i <<= 1)
|
||||
{
|
||||
if (m_CM->CM_getBit(ROM, mmc))
|
||||
{
|
||||
register1 |= i;
|
||||
}
|
||||
}
|
||||
*(m_buffer++) = register1;
|
||||
} while (--(m_length));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// S-DD1
|
||||
|
||||
SDD1__emu::SDD1__emu(running_machine &machine)
|
||||
: m_machine(machine)
|
||||
{
|
||||
m_IM = auto_alloc(machine, SDD1__IM());
|
||||
m_GCD = auto_alloc(machine, SDD1__GCD(m_IM));
|
||||
m_BG0 = auto_alloc(machine, SDD1__BG(m_GCD, 0));
|
||||
m_BG1 = auto_alloc(machine, SDD1__BG(m_GCD, 1));
|
||||
m_BG2 = auto_alloc(machine, SDD1__BG(m_GCD, 2));
|
||||
m_BG3 = auto_alloc(machine, SDD1__BG(m_GCD, 3));
|
||||
m_BG4 = auto_alloc(machine, SDD1__BG(m_GCD, 4));
|
||||
m_BG5 = auto_alloc(machine, SDD1__BG(m_GCD, 5));
|
||||
m_BG6 = auto_alloc(machine, SDD1__BG(m_GCD, 6));
|
||||
m_BG7 = auto_alloc(machine, SDD1__BG(m_GCD, 7));
|
||||
m_PEM = auto_alloc(machine, SDD1__PEM(m_BG0, m_BG1, m_BG2, m_BG3,
|
||||
m_BG4, m_BG5, m_BG6, m_BG7));
|
||||
m_CM = auto_alloc(machine, SDD1__CM(m_PEM));
|
||||
m_OL = auto_alloc(machine, SDD1__OL(m_CM));
|
||||
}
|
||||
|
||||
void SDD1__emu::SDD1emu_decompress(UINT8 *ROM, UINT32 *mmc, UINT32 in_buf, UINT16 out_len, UINT8 *out_buf)
|
||||
{
|
||||
m_IM->IM_prepareDecomp(in_buf);
|
||||
m_BG0->BG_prepareDecomp();
|
||||
m_BG1->BG_prepareDecomp();
|
||||
m_BG2->BG_prepareDecomp();
|
||||
m_BG3->BG_prepareDecomp();
|
||||
m_BG4->BG_prepareDecomp();
|
||||
m_BG5->BG_prepareDecomp();
|
||||
m_BG6->BG_prepareDecomp();
|
||||
m_BG7->BG_prepareDecomp();
|
||||
m_PEM->PEM_prepareDecomp();
|
||||
m_CM->CM_prepareDecomp(ROM, mmc, in_buf);
|
||||
m_OL->OL_prepareDecomp(ROM, mmc, in_buf, out_len, out_buf);
|
||||
|
||||
m_OL->OL_launch(ROM, mmc);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// sns_rom_sdd1_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
const device_type SNS_LOROM_SDD1 = &device_creator<sns_rom_sdd1_device>;
|
||||
|
||||
|
||||
sns_rom_sdd1_device::sns_rom_sdd1_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, type, name, tag, owner, clock),
|
||||
device_sns_cart_interface( mconfig, *this )
|
||||
{
|
||||
}
|
||||
|
||||
sns_rom_sdd1_device::sns_rom_sdd1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, SNS_LOROM_SDD1, "SNES Cart + S-DD1", tag, owner, clock),
|
||||
device_sns_cart_interface( mconfig, *this )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void sns_rom_sdd1_device::device_start()
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
m_sdd1_enable = 0x00;
|
||||
m_xfer_enable = 0x00;
|
||||
|
||||
m_mmc[0] = 0 << 20;
|
||||
m_mmc[1] = 1 << 20;
|
||||
m_mmc[2] = 2 << 20;
|
||||
m_mmc[3] = 3 << 20;
|
||||
|
||||
for(i = 0; i < 8; i++)
|
||||
{
|
||||
m_dma[i].addr = 0;
|
||||
m_dma[i].size = 0;
|
||||
}
|
||||
|
||||
m_sdd1emu = auto_alloc(machine(), SDD1__emu(machine()));
|
||||
|
||||
m_buffer.data = (UINT8*)auto_alloc_array(machine(), UINT8, 0x10000);
|
||||
m_buffer.ready = 0;
|
||||
|
||||
save_item(NAME(m_sdd1_enable));
|
||||
save_item(NAME(m_xfer_enable));
|
||||
save_item(NAME(m_mmc));
|
||||
// TODO: save decomp-related and dma-related items and fix their restore...
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
mapper specific handlers
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER( sns_rom_sdd1_device::chip_read )
|
||||
{
|
||||
UINT16 addr = offset & 0xffff;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x4804:
|
||||
return (m_mmc[0] >> 20) & 7;
|
||||
case 0x4805:
|
||||
return (m_mmc[1] >> 20) & 7;
|
||||
case 0x4806:
|
||||
return (m_mmc[2] >> 20) & 7;
|
||||
case 0x4807:
|
||||
return (m_mmc[3] >> 20) & 7;
|
||||
}
|
||||
|
||||
// we should never get here, but...
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER( sns_rom_sdd1_device::chip_write )
|
||||
{
|
||||
UINT16 addr = offset & 0xffff;
|
||||
|
||||
if ((addr & 0x4380) == 0x4300)
|
||||
{
|
||||
UINT8 channel = (addr >> 4) & 7;
|
||||
switch(addr & 0xf)
|
||||
{
|
||||
case 2:
|
||||
m_dma[channel].addr = (m_dma[channel].addr & 0xffff00) + (data << 0);
|
||||
break;
|
||||
case 3:
|
||||
m_dma[channel].addr = (m_dma[channel].addr & 0xff00ff) + (data << 8);
|
||||
break;
|
||||
case 4:
|
||||
m_dma[channel].addr = (m_dma[channel].addr & 0x00ffff) + (data << 16);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
m_dma[channel].size = (m_dma[channel].size & 0xff00) + (data << 0);
|
||||
break;
|
||||
case 6:
|
||||
m_dma[channel].size = (m_dma[channel].size & 0x00ff) + (data << 8);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch(addr)
|
||||
{
|
||||
case 0x4800:
|
||||
m_sdd1_enable = data;
|
||||
break;
|
||||
case 0x4801:
|
||||
m_xfer_enable = data;
|
||||
break;
|
||||
|
||||
case 0x4804:
|
||||
m_mmc[0] = (data & 7) << 20;
|
||||
break;
|
||||
case 0x4805:
|
||||
m_mmc[1] = (data & 7) << 20;
|
||||
break;
|
||||
case 0x4806:
|
||||
m_mmc[2] = (data & 7) << 20;
|
||||
break;
|
||||
case 0x4807:
|
||||
m_mmc[3] = (data & 7) << 20;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
UINT8 sns_rom_sdd1_device::read_helper(UINT32 addr)
|
||||
{
|
||||
if (m_sdd1_enable & m_xfer_enable)
|
||||
{
|
||||
// at least one channel has S-DD1 decompression enabled...
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (m_sdd1_enable & m_xfer_enable & (1 << i))
|
||||
{
|
||||
// S-DD1 always uses fixed transfer mode, so address will not change during transfer
|
||||
if ((addr + 0xc00000) == m_dma[i].addr)
|
||||
{
|
||||
UINT8 data;
|
||||
if (!m_buffer.ready)
|
||||
{
|
||||
// first byte read for channel performs full decompression.
|
||||
// this really should stream byte-by-byte, but it's not necessary since the size is known
|
||||
m_buffer.offset = 0;
|
||||
m_buffer.size = m_dma[i].size ? m_dma[i].size : 65536;
|
||||
|
||||
// SDD1_emu calls this function; it needs to access uncompressed data;
|
||||
// so temporarily disable decompression mode for decompress() call.
|
||||
m_sdd1emu->SDD1emu_decompress(m_rom, m_mmc, addr, m_buffer.size, m_buffer.data);
|
||||
|
||||
m_buffer.ready = 1;
|
||||
}
|
||||
|
||||
// fetch a decompressed byte; once buffer is depleted, disable channel and invalidate buffer
|
||||
data = m_buffer.data[(UINT16)m_buffer.offset++];
|
||||
if (m_buffer.offset >= m_buffer.size)
|
||||
{
|
||||
m_buffer.ready = 0;
|
||||
m_xfer_enable &= ~(1 << i);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return m_rom[m_mmc[(addr >> 20) & 3] + (addr & 0x0fffff)];
|
||||
}
|
||||
|
||||
READ8_MEMBER(sns_rom_sdd1_device::read_l)
|
||||
{
|
||||
if (offset < 0x400000)
|
||||
return m_rom[rom_bank_map[offset / 0x10000] * 0x8000 + (offset & 0x7fff)];
|
||||
else if (offset >= 0x700000 && (offset & 0xffff) < 0x8000 && m_nvram_size > 0)
|
||||
return m_nvram[offset & 0x1fff];
|
||||
else
|
||||
return m_rom[rom_bank_map[(offset - 0x400000) / 0x8000] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
|
||||
READ8_MEMBER(sns_rom_sdd1_device::read_h)
|
||||
{
|
||||
if (offset >= 0x400000)
|
||||
return read_helper(offset - 0x400000);
|
||||
else
|
||||
return read_l(space, offset);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(sns_rom_sdd1_device::write_l)
|
||||
{
|
||||
if (offset >= 0x700000 && (offset & 0xffff) < 0x8000 && m_nvram_size > 0) // SRAM
|
||||
m_nvram[offset & 0x1fff] = data;
|
||||
}
|
184
src/mess/machine/sns_sdd1.h
Normal file
184
src/mess/machine/sns_sdd1.h
Normal file
@ -0,0 +1,184 @@
|
||||
#ifndef __SNS_SDD1_H
|
||||
#define __SNS_SDD1_H
|
||||
|
||||
#include "machine/sns_slot.h"
|
||||
|
||||
// misc classes for the S-DD1
|
||||
|
||||
class SDD1__IM //Input Manager
|
||||
{
|
||||
public:
|
||||
SDD1__IM() {}
|
||||
|
||||
UINT32 m_byte_ptr;
|
||||
UINT8 m_bit_count;
|
||||
|
||||
void IM_prepareDecomp(UINT32 in_buf);
|
||||
UINT8 IM_getCodeword(UINT8 *ROM, UINT32 *mmc, const UINT8 code_len);
|
||||
};
|
||||
|
||||
class SDD1__GCD //Golomb-Code Decoder
|
||||
{
|
||||
public:
|
||||
SDD1__GCD(SDD1__IM* associatedIM)
|
||||
: m_IM(associatedIM) { }
|
||||
|
||||
SDD1__IM* m_IM;
|
||||
|
||||
void GCD_getRunCount(UINT8 *ROM, UINT32 *mmc, UINT8 code_num, UINT8* MPScount, UINT8* LPSind);
|
||||
};
|
||||
|
||||
class SDD1__BG // Bits Generator
|
||||
{
|
||||
public:
|
||||
SDD1__BG(SDD1__GCD* associatedGCD, UINT8 code)
|
||||
: m_code_num(code),
|
||||
m_GCD(associatedGCD) { }
|
||||
|
||||
UINT8 m_code_num;
|
||||
UINT8 m_MPScount;
|
||||
UINT8 m_LPSind;
|
||||
SDD1__GCD* m_GCD;
|
||||
|
||||
void BG_prepareDecomp();
|
||||
UINT8 BG_getBit(UINT8 *ROM, UINT32 *mmc, UINT8* endOfRun);
|
||||
} ;
|
||||
|
||||
struct SDD1__PEM_ContextInfo
|
||||
{
|
||||
UINT8 status;
|
||||
UINT8 MPS;
|
||||
};
|
||||
|
||||
class SDD1__PEM //Probability Estimation Module
|
||||
{
|
||||
public:
|
||||
SDD1__PEM(
|
||||
SDD1__BG* associatedBG0, SDD1__BG* associatedBG1,
|
||||
SDD1__BG* associatedBG2, SDD1__BG* associatedBG3,
|
||||
SDD1__BG* associatedBG4, SDD1__BG* associatedBG5,
|
||||
SDD1__BG* associatedBG6, SDD1__BG* associatedBG7)
|
||||
{
|
||||
m_BG[0] = associatedBG0;
|
||||
m_BG[1] = associatedBG1;
|
||||
m_BG[2] = associatedBG2;
|
||||
m_BG[3] = associatedBG3;
|
||||
m_BG[4] = associatedBG4;
|
||||
m_BG[5] = associatedBG5;
|
||||
m_BG[6] = associatedBG6;
|
||||
m_BG[7] = associatedBG7;
|
||||
}
|
||||
|
||||
SDD1__PEM_ContextInfo m_contextInfo[32];
|
||||
SDD1__BG* m_BG[8];
|
||||
|
||||
void PEM_prepareDecomp();
|
||||
UINT8 PEM_getBit(UINT8 *ROM, UINT32 *mmc, UINT8 context);
|
||||
} ;
|
||||
|
||||
|
||||
class SDD1__CM
|
||||
{
|
||||
public:
|
||||
SDD1__CM(SDD1__PEM* associatedPEM)
|
||||
: m_PEM(associatedPEM) { }
|
||||
|
||||
UINT8 m_bitplanesInfo;
|
||||
UINT8 m_contextBitsInfo;
|
||||
UINT8 m_bit_number;
|
||||
UINT8 m_currBitplane;
|
||||
UINT16 m_prevBitplaneBits[8];
|
||||
SDD1__PEM* m_PEM;
|
||||
|
||||
void CM_prepareDecomp(UINT8 *ROM, UINT32 *mmc, UINT32 first_byte);
|
||||
UINT8 CM_getBit(UINT8 *ROM, UINT32 *mmc);
|
||||
} ;
|
||||
|
||||
|
||||
class SDD1__OL
|
||||
{
|
||||
public:
|
||||
SDD1__OL(SDD1__CM* associatedCM)
|
||||
: m_CM(associatedCM) { }
|
||||
|
||||
UINT8 m_bitplanesInfo;
|
||||
UINT16 m_length;
|
||||
UINT8* m_buffer;
|
||||
SDD1__CM* m_CM;
|
||||
|
||||
void OL_prepareDecomp(UINT8 *ROM, UINT32 *mmc, UINT32 first_byte, UINT16 out_len, UINT8 *out_buf);
|
||||
void OL_launch(UINT8 *ROM, UINT32 *mmc);
|
||||
} ;
|
||||
|
||||
class SDD1__emu
|
||||
{
|
||||
public:
|
||||
SDD1__emu(running_machine &machine);
|
||||
|
||||
running_machine &machine() const { return m_machine; }
|
||||
|
||||
SDD1__IM* m_IM;
|
||||
SDD1__GCD* m_GCD;
|
||||
SDD1__BG* m_BG0; SDD1__BG* m_BG1; SDD1__BG* m_BG2; SDD1__BG* m_BG3;
|
||||
SDD1__BG* m_BG4; SDD1__BG* m_BG5; SDD1__BG* m_BG6; SDD1__BG* m_BG7;
|
||||
SDD1__PEM* m_PEM;
|
||||
SDD1__CM* m_CM;
|
||||
SDD1__OL* m_OL;
|
||||
|
||||
void SDD1emu_decompress(UINT8 *ROM, UINT32 *mmc, UINT32 in_buf, UINT16 out_len, UINT8 *out_buf);
|
||||
|
||||
private:
|
||||
running_machine& m_machine;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// ======================> sns_rom_sdd1_device
|
||||
|
||||
class sns_rom_sdd1_device : public device_t,
|
||||
public device_sns_cart_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom_sdd1_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
|
||||
sns_rom_sdd1_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() { m_shortname = "sns_rom_sdd1"; }
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_l);
|
||||
virtual DECLARE_READ8_MEMBER(read_h);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_l);
|
||||
virtual DECLARE_READ8_MEMBER(chip_read);
|
||||
virtual DECLARE_WRITE8_MEMBER(chip_write);
|
||||
|
||||
UINT8 read_helper(UINT32 offset);
|
||||
|
||||
UINT8 m_sdd1_enable; // channel bit-mask
|
||||
UINT8 m_xfer_enable; // channel bit-mask
|
||||
UINT32 m_mmc[4]; // memory map controller ROM indices
|
||||
|
||||
struct
|
||||
{
|
||||
UINT32 addr; // $43x2-$43x4 -- DMA transfer address
|
||||
UINT16 size; // $43x5-$43x6 -- DMA transfer size
|
||||
} m_dma[8];
|
||||
|
||||
SDD1__emu* m_sdd1emu;
|
||||
|
||||
struct
|
||||
{
|
||||
UINT8 *data; // pointer to decompressed S-DD1 data (65536 bytes)
|
||||
UINT16 offset; // read index into S-DD1 decompression buffer
|
||||
UINT32 size; // length of data buffer; reads decrement counter, set ready to false at 0
|
||||
UINT8 ready; // 1 when data[] is valid; 0 to invoke sdd1emu.decompress()
|
||||
} m_buffer;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type SNS_LOROM_SDD1;
|
||||
|
||||
#endif
|
222
src/mess/machine/sns_sfx.c
Normal file
222
src/mess/machine/sns_sfx.c
Normal file
@ -0,0 +1,222 @@
|
||||
/***********************************************************************************************************
|
||||
|
||||
SuperFX add-on chip emulation (for SNES/SFC)
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
***********************************************************************************************************/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "machine/sns_sfx.h"
|
||||
#include "cpu/g65816/g65816.h"
|
||||
|
||||
//-------------------------------------------------
|
||||
// sns_rom_superfx_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
const device_type SNS_LOROM_SUPERFX = &device_creator<sns_rom_superfx_device>;
|
||||
|
||||
|
||||
sns_rom_superfx_device::sns_rom_superfx_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sns_rom_device(mconfig, SNS_LOROM_SUPERFX, "SNES Cart (LoROM) + SuperFX", tag, owner, clock),
|
||||
m_superfx(*this, "superfx")
|
||||
{
|
||||
}
|
||||
|
||||
void sns_rom_superfx_device::device_start()
|
||||
{
|
||||
save_item(NAME(sfx_ram));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
mapper specific handlers
|
||||
-------------------------------------------------*/
|
||||
|
||||
// LoROM + SuperFX (GSU-1,2)
|
||||
// TODO: mask sfx_ram based on the actual RAM...
|
||||
|
||||
READ8_MEMBER( sns_rom_superfx_device::superfx_r_bank1 )
|
||||
{
|
||||
return m_rom[rom_bank_map[offset / 0x10000] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
|
||||
READ8_MEMBER( sns_rom_superfx_device::superfx_r_bank2 )
|
||||
{
|
||||
return m_rom[rom_bank_map[offset / 0x8000] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
|
||||
READ8_MEMBER( sns_rom_superfx_device::superfx_r_bank3 )
|
||||
{
|
||||
return sfx_ram[offset & 0xfffff];
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( sns_rom_superfx_device::superfx_w_bank1 )
|
||||
{
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( sns_rom_superfx_device::superfx_w_bank2 )
|
||||
{
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( sns_rom_superfx_device::superfx_w_bank3 )
|
||||
{
|
||||
sfx_ram[offset & 0xfffff] = data;
|
||||
}
|
||||
|
||||
static ADDRESS_MAP_START( sfx_map, AS_PROGRAM, 8, sns_rom_superfx_device )
|
||||
AM_RANGE(0x000000, 0x3fffff) AM_READWRITE(superfx_r_bank1, superfx_w_bank1)
|
||||
AM_RANGE(0x400000, 0x5fffff) AM_READWRITE(superfx_r_bank2, superfx_w_bank2)
|
||||
AM_RANGE(0x600000, 0x7dffff) AM_READWRITE(superfx_r_bank3, superfx_w_bank3)
|
||||
AM_RANGE(0x800000, 0xbfffff) AM_READWRITE(superfx_r_bank1, superfx_w_bank1)
|
||||
AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE(superfx_r_bank2, superfx_w_bank2)
|
||||
AM_RANGE(0xe00000, 0xffffff) AM_READWRITE(superfx_r_bank3, superfx_w_bank3)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(sns_rom_superfx_device::snes_extern_irq_w)
|
||||
{
|
||||
machine().device("maincpu")->execute().set_input_line(G65816_LINE_IRQ, state);
|
||||
}
|
||||
|
||||
static SUPERFX_CONFIG( snes_sfx_config )
|
||||
{
|
||||
DEVCB_LINE_MEMBER(sns_rom_superfx_device,snes_extern_irq_w) /* IRQ line from cart */
|
||||
};
|
||||
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( snes_sfx )
|
||||
MCFG_CPU_ADD("superfx", SUPERFX, 21480000) /* 21.48MHz */
|
||||
MCFG_CPU_PROGRAM_MAP(sfx_map)
|
||||
MCFG_CPU_CONFIG(snes_sfx_config)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
machine_config_constructor sns_rom_superfx_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( snes_sfx );
|
||||
}
|
||||
|
||||
READ8_MEMBER( sns_rom_superfx_device::chip_read )
|
||||
{
|
||||
return superfx_mmio_read(m_superfx, offset);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( sns_rom_superfx_device::chip_write )
|
||||
{
|
||||
superfx_mmio_write(m_superfx, offset, data);
|
||||
}
|
||||
|
||||
READ8_MEMBER( sns_rom_superfx_device::read_l )
|
||||
{
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
{
|
||||
if (superfx_access_ram(m_superfx))
|
||||
return sfx_ram[offset & 0x1fff];
|
||||
}
|
||||
if (address >= 0x8000)
|
||||
return m_rom[rom_bank_map[offset / 0x10000] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
else if (offset < 0x600000)
|
||||
{
|
||||
if (superfx_access_rom(m_superfx))
|
||||
{
|
||||
return m_rom[rom_bank_map[(offset - 0x400000) / 0x8000] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
else
|
||||
{
|
||||
static const UINT8 sfx_data[16] = {
|
||||
0x00, 0x01, 0x00, 0x01, 0x04, 0x01, 0x00, 0x01,
|
||||
0x00, 0x01, 0x08, 0x01, 0x00, 0x01, 0x0c, 0x01,
|
||||
};
|
||||
return sfx_data[offset & 0x0f];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (superfx_access_ram(m_superfx))
|
||||
return sfx_ram[offset & 0xfffff];
|
||||
}
|
||||
|
||||
return 0xff; // should be open bus...
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER( sns_rom_superfx_device::write_l )
|
||||
{
|
||||
UINT16 address = offset & 0xffff;
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
{
|
||||
if (superfx_access_ram(m_superfx))
|
||||
sfx_ram[offset & 0x1fff] = data;
|
||||
}
|
||||
}
|
||||
else if (offset >= 0x600000)
|
||||
{
|
||||
if (superfx_access_ram(m_superfx))
|
||||
sfx_ram[offset & 0xfffff] = data;
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER(sns_rom_superfx_device::read_h)
|
||||
{
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
{
|
||||
if (superfx_access_ram(m_superfx))
|
||||
return sfx_ram[offset & 0x1fff];
|
||||
}
|
||||
if (address >= 0x8000)
|
||||
return m_rom[rom_bank_map[offset / 0x10000] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
else if (offset < 0x600000)
|
||||
{
|
||||
if (superfx_access_rom(m_superfx))
|
||||
{
|
||||
return m_rom[rom_bank_map[(offset - 0x400000) / 0x8000] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
else
|
||||
{
|
||||
static const UINT8 sfx_data[16] = {
|
||||
0x00, 0x01, 0x00, 0x01, 0x04, 0x01, 0x00, 0x01,
|
||||
0x00, 0x01, 0x08, 0x01, 0x00, 0x01, 0x0c, 0x01,
|
||||
};
|
||||
return sfx_data[offset & 0x0f];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (superfx_access_ram(m_superfx))
|
||||
return sfx_ram[offset & 0xfffff];
|
||||
}
|
||||
|
||||
return 0xff; // should be open bus...
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( sns_rom_superfx_device::write_h )
|
||||
{
|
||||
UINT16 address = offset & 0xffff;
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
{
|
||||
if (superfx_access_ram(m_superfx))
|
||||
sfx_ram[offset & 0x1fff] = data;
|
||||
}
|
||||
}
|
||||
else if (offset >= 0x600000)
|
||||
{
|
||||
if (superfx_access_ram(m_superfx))
|
||||
sfx_ram[offset & 0xfffff] = data;
|
||||
}
|
||||
}
|
||||
|
48
src/mess/machine/sns_sfx.h
Normal file
48
src/mess/machine/sns_sfx.h
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef __SNS_SFX_H
|
||||
#define __SNS_SFX_H
|
||||
|
||||
#include "machine/sns_slot.h"
|
||||
#include "machine/sns_rom.h"
|
||||
#include "cpu/superfx/superfx.h"
|
||||
|
||||
|
||||
// ======================> sns_rom_superfx_device
|
||||
|
||||
class sns_rom_superfx_device : public sns_rom_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom_superfx_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() { m_shortname = "sns_rom_superfx"; }
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
required_device<device_t> m_superfx;
|
||||
|
||||
// additional reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_l);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_l);
|
||||
virtual DECLARE_READ8_MEMBER(read_h);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_h);
|
||||
virtual DECLARE_READ8_MEMBER(chip_read);
|
||||
virtual DECLARE_WRITE8_MEMBER(chip_write);
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(superfx_r_bank1);
|
||||
virtual DECLARE_READ8_MEMBER(superfx_r_bank2);
|
||||
virtual DECLARE_READ8_MEMBER(superfx_r_bank3);
|
||||
virtual DECLARE_WRITE8_MEMBER(superfx_w_bank1);
|
||||
virtual DECLARE_WRITE8_MEMBER(superfx_w_bank2);
|
||||
virtual DECLARE_WRITE8_MEMBER(superfx_w_bank3);
|
||||
virtual DECLARE_WRITE_LINE_MEMBER(snes_extern_irq_w);
|
||||
|
||||
|
||||
UINT8 sfx_ram[0x200000];
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type SNS_LOROM_SUPERFX;
|
||||
|
||||
#endif
|
1108
src/mess/machine/sns_slot.c
Normal file
1108
src/mess/machine/sns_slot.c
Normal file
File diff suppressed because it is too large
Load Diff
215
src/mess/machine/sns_slot.h
Normal file
215
src/mess/machine/sns_slot.h
Normal file
@ -0,0 +1,215 @@
|
||||
#ifndef __SNS_SLOT_H
|
||||
#define __SNS_SLOT_H
|
||||
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
/* PCB */
|
||||
enum
|
||||
{
|
||||
SNES_MODE20 = 0,
|
||||
SNES_MODE21,
|
||||
SNES_MODE22, // ExLoROM - not used anymore in emulation (only to log info), will be removed
|
||||
SNES_MODE25, // ExHiROM - not used anymore in emulation (only to log info), will be removed
|
||||
SNES_CX4,
|
||||
SNES_DSP,
|
||||
SNES_DSP_MODE21,
|
||||
SNES_DSP4,
|
||||
SNES_OBC1,
|
||||
SNES_SA1,
|
||||
SNES_SDD1,
|
||||
SNES_SFX,
|
||||
SNES_SPC7110,
|
||||
SNES_SPC7110_RTC,
|
||||
SNES_SRTC,
|
||||
SNES_ST010,
|
||||
SNES_ST011,
|
||||
SNES_ST018,
|
||||
SNES_Z80GB,
|
||||
SNES_BSX,
|
||||
SNES_BSXLO,
|
||||
SNES_BSXHI,
|
||||
SNES_BSMEMPAK,
|
||||
SNES_SUFAMITURBO,
|
||||
SNES_STROM,
|
||||
// pirate carts
|
||||
SNES_POKEMON,
|
||||
SNES_BANANA, // wip
|
||||
SNES_SOULBLAD // wip
|
||||
};
|
||||
|
||||
|
||||
// ======================> sns_cart_interface
|
||||
|
||||
struct sns_cart_interface
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
// ======================> device_sns_cart_interface
|
||||
|
||||
class device_sns_cart_interface : public device_slot_card_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
device_sns_cart_interface(const machine_config &mconfig, device_t &device);
|
||||
virtual ~device_sns_cart_interface();
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_l) { return 0xff; }
|
||||
virtual DECLARE_READ8_MEMBER(read_h) { return 0xff; }
|
||||
virtual DECLARE_WRITE8_MEMBER(write_l) {}
|
||||
virtual DECLARE_WRITE8_MEMBER(write_h) {}
|
||||
virtual DECLARE_READ8_MEMBER(chip_read) { return 0xff; }
|
||||
virtual DECLARE_WRITE8_MEMBER(chip_write) {}
|
||||
|
||||
virtual void rom_alloc(running_machine &machine, UINT32 size);
|
||||
virtual void nvram_alloc(running_machine &machine, UINT32 size);
|
||||
virtual void rtc_ram_alloc(running_machine &machine, UINT32 size);
|
||||
virtual void addon_bios_alloc(running_machine &machine, UINT32 size);
|
||||
virtual UINT8* get_rom_base() { return m_rom; };
|
||||
virtual UINT8* get_nvram_base() { return m_nvram; };
|
||||
virtual UINT8* get_addon_bios_base() { return m_bios; };
|
||||
virtual UINT8* get_rtc_ram_base() { return m_rtc_ram; };
|
||||
virtual UINT32 get_rom_size() { return m_rom_size; };
|
||||
virtual UINT32 get_nvram_size() { return m_nvram_size; };
|
||||
virtual UINT32 get_addon_bios_size() { return m_bios_size; };
|
||||
virtual UINT32 get_rtc_ram_size() { return m_rtc_ram_size; };
|
||||
|
||||
virtual void rom_map_setup(UINT32 size);
|
||||
|
||||
// internal state
|
||||
UINT8 *m_rom;
|
||||
UINT8 *m_nvram;
|
||||
UINT8 *m_bios;
|
||||
UINT8 *m_rtc_ram; // temp pointer to save RTC ram to nvram (will disappear when RTCs become devices)
|
||||
UINT32 m_rom_size;
|
||||
UINT32 m_nvram_size;
|
||||
UINT32 m_bios_size;
|
||||
UINT32 m_rtc_ram_size; // temp
|
||||
|
||||
UINT8 rom_bank_map[256]; // 32K chunks of rom
|
||||
};
|
||||
|
||||
|
||||
// ======================> base_sns_cart_slot_device
|
||||
|
||||
class base_sns_cart_slot_device : public device_t,
|
||||
public sns_cart_interface,
|
||||
public device_image_interface,
|
||||
public device_slot_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
base_sns_cart_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
|
||||
virtual ~base_sns_cart_slot_device();
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_config_complete();
|
||||
|
||||
// image-level overrides
|
||||
virtual bool call_load();
|
||||
virtual void call_unload();
|
||||
virtual bool call_softlist_load(char *swlist, char *swname, rom_entry *start_entry);
|
||||
|
||||
virtual int get_cart_type(UINT8 *ROM, UINT32 len);
|
||||
virtual UINT32 snes_skip_header(UINT8 *ROM, UINT32 snes_rom_size);
|
||||
virtual int get_type() { return m_type; }
|
||||
|
||||
virtual void setup_custom_mappers();
|
||||
virtual void setup_nvram();
|
||||
|
||||
virtual iodevice_t image_type() const { return IO_CARTSLOT; }
|
||||
virtual bool is_readable() const { return 1; }
|
||||
virtual bool is_writeable() const { return 0; }
|
||||
virtual bool is_creatable() const { return 0; }
|
||||
virtual bool must_be_loaded() const { return 1; }
|
||||
virtual bool is_reset_on_load() const { return 1; }
|
||||
virtual const option_guide *create_option_guide() const { return NULL; }
|
||||
|
||||
// slot interface overrides
|
||||
virtual const char * get_default_card_software(const machine_config &config, emu_options &options);
|
||||
virtual void internal_header_logging(UINT8 *ROM, UINT32 len);
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_l);
|
||||
virtual DECLARE_READ8_MEMBER(read_h);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_l);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_h);
|
||||
virtual DECLARE_READ8_MEMBER(chip_read);
|
||||
virtual DECLARE_WRITE8_MEMBER(chip_write);
|
||||
|
||||
// FIXME:
|
||||
// this should be private, but then there is some problem installing delegates in the driver...
|
||||
//private:
|
||||
|
||||
device_sns_cart_interface* m_cart;
|
||||
|
||||
int m_type;
|
||||
};
|
||||
|
||||
// ======================> sns_cart_slot_device
|
||||
|
||||
class sns_cart_slot_device : public base_sns_cart_slot_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
virtual const char *image_interface() const { return "snes_cart"; }
|
||||
virtual const char *file_extensions() const { return "sfc"; }
|
||||
};
|
||||
|
||||
// ======================> sns_sufami_cart_slot_device
|
||||
|
||||
class sns_sufami_cart_slot_device : public base_sns_cart_slot_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_sufami_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
virtual const char *image_interface() const { return "st_cart"; }
|
||||
virtual const char *file_extensions() const { return "st"; }
|
||||
virtual bool must_be_loaded() const { return 0; }
|
||||
};
|
||||
|
||||
// ======================> sns_sufami_cart_slot_device
|
||||
|
||||
class sns_bsx_cart_slot_device : public base_sns_cart_slot_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_bsx_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
virtual const char *image_interface() const { return "bspack"; }
|
||||
virtual const char *file_extensions() const { return "bs"; }
|
||||
virtual bool must_be_loaded() const { return 0; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type SNS_CART_SLOT;
|
||||
extern const device_type SNS_SUFAMI_CART_SLOT;
|
||||
extern const device_type SNS_BSX_CART_SLOT;
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
DEVICE CONFIGURATION MACROS
|
||||
***************************************************************************/
|
||||
|
||||
#define MCFG_SNS_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot,_def_inp) \
|
||||
MCFG_DEVICE_ADD(_tag, SNS_CART_SLOT, 0) \
|
||||
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _def_inp, false)
|
||||
|
||||
#define MCFG_SNS_SUFAMI_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot,_def_inp) \
|
||||
MCFG_DEVICE_ADD(_tag, SNS_SUFAMI_CART_SLOT, 0) \
|
||||
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _def_inp, false)
|
||||
|
||||
#define MCFG_SNS_BSX_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot,_def_inp) \
|
||||
MCFG_DEVICE_ADD(_tag, SNS_BSX_CART_SLOT, 0) \
|
||||
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _def_inp, false)
|
||||
|
||||
|
||||
#endif
|
1643
src/mess/machine/sns_spc7110.c
Normal file
1643
src/mess/machine/sns_spc7110.c
Normal file
File diff suppressed because it is too large
Load Diff
211
src/mess/machine/sns_spc7110.h
Normal file
211
src/mess/machine/sns_spc7110.h
Normal file
@ -0,0 +1,211 @@
|
||||
#ifndef __SNS_SPC7110_H
|
||||
#define __SNS_SPC7110_H
|
||||
|
||||
#include "machine/sns_slot.h"
|
||||
#include "machine/sns_rom21.h"
|
||||
|
||||
|
||||
enum RTC_State
|
||||
{
|
||||
RTCS_Inactive,
|
||||
RTCS_ModeSelect,
|
||||
RTCS_IndexSelect,
|
||||
RTCS_Write
|
||||
};
|
||||
|
||||
enum RTC_Mode
|
||||
{
|
||||
RTCM_Linear = 0x03,
|
||||
RTCM_Indexed = 0x0c
|
||||
};
|
||||
|
||||
class SPC7110_Decomp
|
||||
{
|
||||
public:
|
||||
SPC7110_Decomp(running_machine &machine);
|
||||
|
||||
running_machine &machine() const { return m_machine; }
|
||||
|
||||
void init(running_machine &machine, UINT8 *ROM, UINT32 len, UINT32 mode, UINT32 offset, UINT32 index);
|
||||
void reset();
|
||||
|
||||
UINT8 read(UINT8 *ROM, UINT32 len);
|
||||
void write(UINT8 data);
|
||||
void mode0(UINT8 init, UINT8 *ROM, UINT32 len);
|
||||
void mode1(UINT8 init, UINT8 *ROM, UINT32 len);
|
||||
void mode2(UINT8 init, UINT8 *ROM, UINT32 len);
|
||||
|
||||
UINT8 dataread(UINT8 *ROM, UINT32 len);
|
||||
UINT8 probability(UINT32 n);
|
||||
UINT8 next_lps(UINT32 n);
|
||||
UINT8 next_mps(UINT32 n);
|
||||
UINT8 toggle_invert(UINT32 n);
|
||||
UINT32 morton_2x8(UINT32 data);
|
||||
UINT32 morton_4x8(UINT32 data);
|
||||
|
||||
UINT32 m_decomp_mode;
|
||||
UINT32 m_decomp_offset;
|
||||
|
||||
UINT8 *m_decomp_buffer;
|
||||
UINT32 m_decomp_buffer_rdoffset;
|
||||
UINT32 m_decomp_buffer_wroffset;
|
||||
UINT32 m_decomp_buffer_length;
|
||||
|
||||
struct ContextState
|
||||
{
|
||||
UINT8 index;
|
||||
UINT8 invert;
|
||||
} m_context[32];
|
||||
|
||||
UINT32 m_morton16[2][256];
|
||||
UINT32 m_morton32[4][256];
|
||||
|
||||
|
||||
private:
|
||||
running_machine& m_machine;
|
||||
UINT32 m_rom_size;
|
||||
};
|
||||
|
||||
// ======================> sns_rom_spc7110_device
|
||||
|
||||
class sns_rom_spc7110_device : public sns_rom21_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom_spc7110_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
|
||||
sns_rom_spc7110_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() { m_shortname = "sns_rom_spc7110"; }
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_l);
|
||||
virtual DECLARE_READ8_MEMBER(read_h);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_l);
|
||||
|
||||
virtual DECLARE_READ8_MEMBER(chip_read);
|
||||
virtual DECLARE_WRITE8_MEMBER(chip_write);
|
||||
|
||||
void spc7110_start();
|
||||
UINT32 spc7110_datarom_addr(UINT32 addr, UINT32 len);
|
||||
UINT32 spc7110_data_pointer();
|
||||
UINT32 spc7110_data_adjust();
|
||||
UINT32 spc7110_data_increment();
|
||||
void spc7110_set_data_pointer(UINT32 addr);
|
||||
void spc7110_set_data_adjust(UINT32 addr);
|
||||
void spc7110_update_time(UINT8 offset);
|
||||
|
||||
|
||||
//==================
|
||||
//decompression unit
|
||||
//==================
|
||||
UINT8 m_r4801; // compression table low
|
||||
UINT8 m_r4802; // compression table high
|
||||
UINT8 m_r4803; // compression table bank
|
||||
UINT8 m_r4804; // compression table index
|
||||
UINT8 m_r4805; // decompression buffer index low
|
||||
UINT8 m_r4806; // decompression buffer index high
|
||||
UINT8 m_r4807; // ???
|
||||
UINT8 m_r4808; // ???
|
||||
UINT8 m_r4809; // compression length low
|
||||
UINT8 m_r480a; // compression length high
|
||||
UINT8 m_r480b; // decompression control register
|
||||
UINT8 m_r480c; // decompression status
|
||||
|
||||
SPC7110_Decomp* m_decomp;
|
||||
|
||||
UINT8 m_r4811; // data pointer low
|
||||
UINT8 m_r4812; // data pointer high
|
||||
UINT8 m_r4813; // data pointer bank
|
||||
UINT8 m_r4814; // data adjust low
|
||||
UINT8 m_r4815; // data adjust high
|
||||
UINT8 m_r4816; // data increment low
|
||||
UINT8 m_r4817; // data increment high
|
||||
UINT8 m_r4818; // data port control register
|
||||
|
||||
UINT8 m_r481x;
|
||||
|
||||
UINT8 m_r4814_latch;
|
||||
UINT8 m_r4815_latch;
|
||||
|
||||
//=========
|
||||
//math unit
|
||||
//=========
|
||||
UINT8 m_r4820; // 16-bit multiplicand B0, 32-bit dividend B0
|
||||
UINT8 m_r4821; // 16-bit multiplicand B1, 32-bit dividend B1
|
||||
UINT8 m_r4822; // 32-bit dividend B2
|
||||
UINT8 m_r4823; // 32-bit dividend B3
|
||||
UINT8 m_r4824; // 16-bit multiplier B0
|
||||
UINT8 m_r4825; // 16-bit multiplier B1
|
||||
UINT8 m_r4826; // 16-bit divisor B0
|
||||
UINT8 m_r4827; // 16-bit divisor B1
|
||||
UINT8 m_r4828; // 32-bit product B0, 32-bit quotient B0
|
||||
UINT8 m_r4829; // 32-bit product B1, 32-bit quotient B1
|
||||
UINT8 m_r482a; // 32-bit product B2, 32-bit quotient B2
|
||||
UINT8 m_r482b; // 32-bit product B3, 32-bit quotient B3
|
||||
UINT8 m_r482c; // 16-bit remainder B0
|
||||
UINT8 m_r482d; // 16-bit remainder B1
|
||||
UINT8 m_r482e; // math control register
|
||||
UINT8 m_r482f; // math status
|
||||
|
||||
//===================
|
||||
//memory mapping unit
|
||||
//===================
|
||||
UINT8 m_r4830; // SRAM write enable
|
||||
UINT8 m_r4831; // $[d0-df]:[0000-ffff] mapping
|
||||
UINT8 m_r4832; // $[e0-ef]:[0000-ffff] mapping
|
||||
UINT8 m_r4833; // $[f0-ff]:[0000-ffff] mapping
|
||||
UINT8 m_r4834; // ???
|
||||
|
||||
UINT32 m_dx_offset;
|
||||
UINT32 m_ex_offset;
|
||||
UINT32 m_fx_offset;
|
||||
|
||||
//====================
|
||||
//real-time clock unit
|
||||
//====================
|
||||
UINT8 m_r4840; // RTC latch
|
||||
UINT8 m_r4841; // RTC index/data port
|
||||
UINT8 m_r4842; // RTC status
|
||||
|
||||
UINT32 m_rtc_state;
|
||||
UINT32 m_rtc_mode;
|
||||
UINT32 m_rtc_index;
|
||||
|
||||
UINT64 m_rtc_offset;
|
||||
|
||||
//this is now allocated in the main snes cart class, to allow saving to nvram
|
||||
//UINT8 m_rtc_ram[16]; // 0-12 secs, min, hrs, etc.; 13-14-15 control registers
|
||||
|
||||
UINT8 m_ram[0x2000];
|
||||
};
|
||||
|
||||
// ======================> sns_rom_spc7110_device
|
||||
|
||||
class sns_rom_spc7110rtc_device : public sns_rom_spc7110_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom_spc7110rtc_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() { m_shortname = "sns_rom_spc7110rtc"; }
|
||||
|
||||
// reading and writing
|
||||
|
||||
// we just use the spc7110 ones for the moment, pending the split of regs 0x4840-0x4842 (RTC) from the base add-on
|
||||
// virtual DECLARE_READ8_MEMBER(read_l);
|
||||
// virtual DECLARE_READ8_MEMBER(read_h);
|
||||
// virtual DECLARE_WRITE8_MEMBER(write_l);
|
||||
|
||||
// virtual DECLARE_READ8_MEMBER(chip_read);
|
||||
// virtual DECLARE_WRITE8_MEMBER(chip_write);
|
||||
};
|
||||
|
||||
// device type definition
|
||||
extern const device_type SNS_HIROM_SPC7110;
|
||||
extern const device_type SNS_HIROM_SPC7110_RTC;
|
||||
|
||||
#endif
|
176
src/mess/machine/sns_sufami.c
Normal file
176
src/mess/machine/sns_sufami.c
Normal file
@ -0,0 +1,176 @@
|
||||
/***********************************************************************************************************
|
||||
|
||||
Bandai Sufami Turbo cartridge emulation (for SNES/SFC)
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
This is basically a standard LoROM cart with two slots for ST minicarts
|
||||
The content of each slot (with ROM and RAM) is mapped to a separate memory range
|
||||
Slot 1: ROM [20-3f][8000-ffff], RAM [60-63][8000-ffff]
|
||||
Slot 2: ROM [40-5f][8000-ffff], RAM [70-73][8000-ffff]
|
||||
|
||||
***********************************************************************************************************/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "machine/sns_sufami.h"
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// sns_rom_sufami_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
const device_type SNS_LOROM_SUFAMI = &device_creator<sns_rom_sufami_device>;
|
||||
const device_type SNS_STROM = &device_creator<sns_rom_strom_device>;
|
||||
|
||||
|
||||
sns_rom_sufami_device::sns_rom_sufami_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sns_rom_device(mconfig, SNS_LOROM_SUFAMI, "SNES Sufami Turbo Cart", tag, owner, clock),
|
||||
m_slot1(*this, "st_slot1"),
|
||||
m_slot2(*this, "st_slot2")
|
||||
{
|
||||
}
|
||||
|
||||
sns_rom_strom_device::sns_rom_strom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sns_rom_device(mconfig, SNS_STROM, "SNES Sufami Turbo Minicart", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void sns_rom_sufami_device::device_start()
|
||||
{
|
||||
}
|
||||
|
||||
void sns_rom_strom_device::device_start()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// MACHINE_CONFIG_FRAGMENT( st_slot )
|
||||
//-------------------------------------------------
|
||||
|
||||
static SLOT_INTERFACE_START(sufamiturbo_cart)
|
||||
SLOT_INTERFACE_INTERNAL("strom", SNS_STROM)
|
||||
SLOT_INTERFACE_END
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( st_slot )
|
||||
MCFG_SNS_SUFAMI_CARTRIDGE_ADD("st_slot1", sufamiturbo_cart, NULL, NULL)
|
||||
MCFG_SNS_SUFAMI_CARTRIDGE_ADD("st_slot2", sufamiturbo_cart, NULL, NULL)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// machine_config_additions - device-specific
|
||||
// machine configurations
|
||||
//-------------------------------------------------
|
||||
|
||||
machine_config_constructor sns_rom_sufami_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( st_slot );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
mapper specific handlers
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER(sns_rom_sufami_device::read_l)
|
||||
{
|
||||
return read_h(space, offset);
|
||||
}
|
||||
|
||||
READ8_MEMBER(sns_rom_sufami_device::read_h)
|
||||
{
|
||||
if (offset < 0x200000) // SUFAMI TURBO ROM
|
||||
{
|
||||
int bank = offset / 0x10000;
|
||||
return m_rom[rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
if (offset >= 0x200000 && offset < 0x400000) // SLOT1 STROM
|
||||
{
|
||||
if (m_slot1->m_cart)
|
||||
return m_slot1->m_cart->read_l(space, offset - 0x200000);
|
||||
}
|
||||
if (offset >= 0x400000 && offset < 0x600000) // SLOT2 STROM
|
||||
{
|
||||
if (m_slot2->m_cart)
|
||||
return m_slot2->m_cart->read_l(space, offset - 0x400000);
|
||||
}
|
||||
if (offset >= 0x600000 && offset < 0x640000) // SLOT1 RAM
|
||||
{
|
||||
if (m_slot1->m_cart && (offset & 0xffff) > 0x8000)
|
||||
return m_slot1->m_cart->read_h(space, offset - 0x600000);
|
||||
}
|
||||
if (offset >= 0x700000 && offset < 0x740000) // SLOT2 RAM
|
||||
{
|
||||
if (m_slot2->m_cart && (offset & 0xffff) > 0x8000)
|
||||
return m_slot2->m_cart->read_h(space, offset - 0x700000);
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(sns_rom_sufami_device::write_l)
|
||||
{
|
||||
write_h(space, offset, data);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(sns_rom_sufami_device::write_h)
|
||||
{
|
||||
if (offset >= 0x600000 && offset < 0x640000) // SLOT1 RAM
|
||||
{
|
||||
if (m_slot1->m_cart && (offset & 0xffff) > 0x8000)
|
||||
return m_slot1->m_cart->write_h(space, offset - 0x600000, data);
|
||||
}
|
||||
|
||||
if (offset >= 0x700000 && offset < 0x740000) // SLOT2 RAM
|
||||
{
|
||||
if (m_slot2->m_cart && (offset & 0xffff) > 0x8000)
|
||||
return m_slot2->m_cart->write_h(space, offset - 0x700000, data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
Sufami Turbo 'minicart' emulation
|
||||
-------------------------------------------------*/
|
||||
|
||||
// Here we're cheating a bit, for the moment, to avoid the need of ST carts as a completely different device
|
||||
// which would require separate loading routines
|
||||
// Hence, we use low r/w handlers for ROM access and hi r/w handlers for RAM access...
|
||||
// Eventually, it might be better to create a separate device for these, with rom_r and ram_r/ram_w handlers
|
||||
|
||||
READ8_MEMBER(sns_rom_strom_device::read_l)
|
||||
{
|
||||
if (offset < 0x200000)
|
||||
{
|
||||
int bank = offset / 0x10000;
|
||||
return m_rom[rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
READ8_MEMBER(sns_rom_strom_device::read_h)
|
||||
{
|
||||
if (offset < 0x40000)
|
||||
{
|
||||
int bank = offset / 0x10000;
|
||||
return m_nvram[bank * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(sns_rom_strom_device::write_l)
|
||||
{
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(sns_rom_strom_device::write_h)
|
||||
{
|
||||
if (offset < 0x40000)
|
||||
{
|
||||
int bank = offset / 0x10000;
|
||||
m_nvram[bank * 0x8000 + (offset & 0x7fff)] = data;
|
||||
}
|
||||
}
|
||||
|
||||
|
56
src/mess/machine/sns_sufami.h
Normal file
56
src/mess/machine/sns_sufami.h
Normal file
@ -0,0 +1,56 @@
|
||||
#ifndef __SNS_SUFAMI_H
|
||||
#define __SNS_SUFAMI_H
|
||||
|
||||
#include "machine/sns_slot.h"
|
||||
#include "machine/sns_rom.h"
|
||||
|
||||
|
||||
// ======================> sns_rom_sufami_device
|
||||
|
||||
class sns_rom_sufami_device : public sns_rom_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom_sufami_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() { m_shortname = "sns_rom_sufami"; }
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
// additional reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_l);
|
||||
virtual DECLARE_READ8_MEMBER(read_h);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_l);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_h);
|
||||
|
||||
private:
|
||||
required_device<sns_sufami_cart_slot_device> m_slot1;
|
||||
required_device<sns_sufami_cart_slot_device> m_slot2;
|
||||
};
|
||||
|
||||
// ======================> sns_rom_strom_device
|
||||
|
||||
class sns_rom_strom_device : public sns_rom_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom_strom_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() { m_shortname = "sns_strom"; }
|
||||
|
||||
// additional reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_l); // used for ROM
|
||||
virtual DECLARE_READ8_MEMBER(read_h); // used for ROM
|
||||
virtual DECLARE_WRITE8_MEMBER(write_l); // used for RAM
|
||||
virtual DECLARE_WRITE8_MEMBER(write_h); // used for RAM
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type SNS_LOROM_SUFAMI;
|
||||
extern const device_type SNS_STROM;
|
||||
|
||||
#endif
|
319
src/mess/machine/sns_upd.c
Normal file
319
src/mess/machine/sns_upd.c
Normal file
@ -0,0 +1,319 @@
|
||||
/***********************************************************************************************************
|
||||
|
||||
UPD7725 / UPD96050 add-on chip emulation (for SNES/SFC)
|
||||
used in carts with DSP-1, DSP-1A, DSP-1B, DSP-2, DSP-3, DSP-4, ST-010 & ST-011 add-on chips
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
***********************************************************************************************************/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "machine/sns_upd.h"
|
||||
|
||||
//-------------------------------------------------
|
||||
// constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
const device_type SNS_LOROM_NECDSP = &device_creator<sns_rom20_necdsp_device>;
|
||||
const device_type SNS_HIROM_NECDSP = &device_creator<sns_rom21_necdsp_device>;
|
||||
const device_type SNS_LOROM_SETA10 = &device_creator<sns_rom_seta10dsp_device>;
|
||||
const device_type SNS_LOROM_SETA11 = &device_creator<sns_rom_seta11dsp_device>;
|
||||
|
||||
|
||||
sns_rom20_necdsp_device::sns_rom20_necdsp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sns_rom_device(mconfig, SNS_LOROM_NECDSP, "SNES Cart (LoROM) + NEC DSP", tag, owner, clock),
|
||||
m_upd7725(*this, "dsp")
|
||||
{
|
||||
}
|
||||
|
||||
sns_rom21_necdsp_device::sns_rom21_necdsp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sns_rom21_device(mconfig, SNS_HIROM_NECDSP, "SNES Cart (HiROM) + NEC DSP", tag, owner, clock),
|
||||
m_upd7725(*this, "dsp")
|
||||
{
|
||||
}
|
||||
|
||||
sns_rom_setadsp_device::sns_rom_setadsp_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sns_rom_device(mconfig, type, name, tag, owner, clock),
|
||||
m_upd96050(*this, "dsp")
|
||||
{
|
||||
}
|
||||
|
||||
sns_rom_seta10dsp_device::sns_rom_seta10dsp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sns_rom_setadsp_device(mconfig, SNS_LOROM_SETA10, "SNES Cart (LoROM) + Seta ST010 DSP", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
sns_rom_seta11dsp_device::sns_rom_seta11dsp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sns_rom_setadsp_device(mconfig, SNS_LOROM_SETA11, "SNES Cart (LoROM) + Seta ST011 DSP", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void sns_rom20_necdsp_device::device_start()
|
||||
{
|
||||
}
|
||||
|
||||
void sns_rom21_necdsp_device::device_start()
|
||||
{
|
||||
}
|
||||
|
||||
void sns_rom_setadsp_device::device_start()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
mapper specific handlers
|
||||
-------------------------------------------------*/
|
||||
|
||||
//-------------------------------------------------
|
||||
// NEC DSP
|
||||
//-------------------------------------------------
|
||||
|
||||
// Lo-ROM
|
||||
|
||||
// DSP dump contains prg at offset 0 and data at offset 0x2000
|
||||
READ32_MEMBER( sns_rom20_necdsp_device::necdsp_prg_r )
|
||||
{
|
||||
return (m_bios[offset * 4] << 24) | (m_bios[offset * 4 + 1] << 16) |
|
||||
(m_bios[offset * 4 + 2] << 8) | 0x00;
|
||||
}
|
||||
|
||||
READ16_MEMBER( sns_rom20_necdsp_device::necdsp_data_r )
|
||||
{
|
||||
return (m_bios[0x2000 + offset * 2] << 8) | m_bios[0x2000 + offset * 2 + 1];
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ADDRESS_MAP( dsp_prg_map )
|
||||
//-------------------------------------------------
|
||||
|
||||
static ADDRESS_MAP_START( dsp_prg_map_lorom, AS_PROGRAM, 32, sns_rom20_necdsp_device )
|
||||
AM_RANGE(0x0000, 0x07ff) AM_READ(necdsp_prg_r)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ADDRESS_MAP( dsp_data_map )
|
||||
//-------------------------------------------------
|
||||
|
||||
static ADDRESS_MAP_START( dsp_data_map_lorom, AS_DATA, 16, sns_rom20_necdsp_device )
|
||||
AM_RANGE(0x0000, 0x03ff) AM_READ(necdsp_data_r)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// MACHINE_DRIVER( snes_dsp )
|
||||
//-------------------------------------------------
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( snes_dsp_lorom )
|
||||
MCFG_CPU_ADD("dsp", UPD7725, 8000000)
|
||||
MCFG_CPU_PROGRAM_MAP(dsp_prg_map_lorom)
|
||||
MCFG_CPU_DATA_MAP(dsp_data_map_lorom)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
//-------------------------------------------------
|
||||
// machine_config_additions - device-specific
|
||||
// machine configurations
|
||||
//-------------------------------------------------
|
||||
|
||||
machine_config_constructor sns_rom20_necdsp_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( snes_dsp_lorom );
|
||||
}
|
||||
|
||||
READ8_MEMBER( sns_rom20_necdsp_device::chip_read )
|
||||
{
|
||||
offset &= 0x7fff;
|
||||
return m_upd7725->snesdsp_read(offset < 0x4000);
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER( sns_rom20_necdsp_device::chip_write )
|
||||
{
|
||||
offset &= 0x7fff;
|
||||
m_upd7725->snesdsp_write(offset < 0x4000, data);
|
||||
}
|
||||
|
||||
|
||||
// Hi-ROM
|
||||
|
||||
// DSP dump contains prg at offset 0 and data at offset 0x2000
|
||||
READ32_MEMBER( sns_rom21_necdsp_device::necdsp_prg_r )
|
||||
{
|
||||
return (m_bios[offset * 4] << 24) | (m_bios[offset * 4 + 1] << 16) |
|
||||
(m_bios[offset * 4 + 2] << 8) | 0x00;
|
||||
}
|
||||
|
||||
READ16_MEMBER( sns_rom21_necdsp_device::necdsp_data_r )
|
||||
{
|
||||
return (m_bios[0x2000 + offset * 2] << 8) | m_bios[0x2000 + offset * 2 + 1];
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ADDRESS_MAP( dsp_prg_map )
|
||||
//-------------------------------------------------
|
||||
|
||||
static ADDRESS_MAP_START( dsp_prg_map_hirom, AS_PROGRAM, 32, sns_rom21_necdsp_device )
|
||||
AM_RANGE(0x0000, 0x07ff) AM_READ(necdsp_prg_r)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ADDRESS_MAP( dsp_data_map )
|
||||
//-------------------------------------------------
|
||||
|
||||
static ADDRESS_MAP_START( dsp_data_map_hirom, AS_DATA, 16, sns_rom21_necdsp_device )
|
||||
AM_RANGE(0x0000, 0x03ff) AM_READ(necdsp_data_r)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// MACHINE_DRIVER( snes_dsp )
|
||||
//-------------------------------------------------
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( snes_dsp_hirom )
|
||||
MCFG_CPU_ADD("dsp", UPD7725, 8000000)
|
||||
MCFG_CPU_PROGRAM_MAP(dsp_prg_map_hirom)
|
||||
MCFG_CPU_DATA_MAP(dsp_data_map_hirom)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
//-------------------------------------------------
|
||||
// machine_config_additions - device-specific
|
||||
// machine configurations
|
||||
//-------------------------------------------------
|
||||
|
||||
machine_config_constructor sns_rom21_necdsp_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( snes_dsp_hirom );
|
||||
}
|
||||
|
||||
READ8_MEMBER( sns_rom21_necdsp_device::chip_read )
|
||||
{
|
||||
offset &= 0x1fff;
|
||||
return m_upd7725->snesdsp_read(offset < 0x1000);
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER( sns_rom21_necdsp_device::chip_write )
|
||||
{
|
||||
offset &= 0x1fff;
|
||||
m_upd7725->snesdsp_write(offset < 0x1000, data);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// Seta DSP
|
||||
//-------------------------------------------------
|
||||
|
||||
// same as above but additional read/write handling for the add-on chip
|
||||
|
||||
READ8_MEMBER( sns_rom_setadsp_device::chip_read )
|
||||
{
|
||||
if (offset >= 0x680000 && offset < 0x700000 && (offset & 0xffff) < 0x1000)
|
||||
{
|
||||
UINT16 address = offset & 0xffff;
|
||||
UINT16 temp = m_upd96050->dataram_r(address/2);
|
||||
if (offset & 1)
|
||||
return temp >> 8;
|
||||
else
|
||||
return temp & 0xff;
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER( sns_rom_setadsp_device::chip_write )
|
||||
{
|
||||
if (offset >= 0x680000 && offset < 0x700000 && (offset & 0xffff) < 0x1000)
|
||||
{
|
||||
UINT16 address = offset & 0xffff;
|
||||
UINT16 temp = m_upd96050->dataram_r(address/2);
|
||||
|
||||
if (offset & 1)
|
||||
{
|
||||
temp &= 0xff;
|
||||
temp |= data << 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp &= 0xff00;
|
||||
temp |= data;
|
||||
}
|
||||
|
||||
m_upd96050->dataram_w(address/2, temp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// DSP dump contains prg at offset 0 and data at offset 0x10000
|
||||
READ32_MEMBER( sns_rom_setadsp_device::setadsp_prg_r )
|
||||
{
|
||||
return (m_bios[offset * 4] << 24) | (m_bios[offset * 4 + 1] << 16) |
|
||||
(m_bios[offset * 4 + 2] << 8) | 0x00;
|
||||
}
|
||||
|
||||
READ16_MEMBER( sns_rom_setadsp_device::setadsp_data_r )
|
||||
{
|
||||
return (m_bios[0x10000 + offset * 2] << 8) | m_bios[0x10000 + offset * 2 + 1];
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ADDRESS_MAP( st01x_prg_map )
|
||||
//-------------------------------------------------
|
||||
|
||||
static ADDRESS_MAP_START( st01x_prg_map, AS_PROGRAM, 32, sns_rom_setadsp_device )
|
||||
AM_RANGE(0x0000, 0x3fff) AM_READ(setadsp_prg_r)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ADDRESS_MAP( st01x_data_map )
|
||||
//-------------------------------------------------
|
||||
|
||||
static ADDRESS_MAP_START( st01x_data_map, AS_DATA, 16, sns_rom_setadsp_device )
|
||||
AM_RANGE(0x0000, 0x07ff) AM_READ(setadsp_data_r)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// MACHINE_DRIVER( snes_st010 )
|
||||
//-------------------------------------------------
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( snes_st010 )
|
||||
MCFG_CPU_ADD("dsp", UPD96050, 10000000)
|
||||
MCFG_CPU_PROGRAM_MAP(st01x_prg_map)
|
||||
MCFG_CPU_DATA_MAP(st01x_data_map)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
//-------------------------------------------------
|
||||
// MACHINE_DRIVER( snes_st011 )
|
||||
//-------------------------------------------------
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( snes_st011 )
|
||||
MCFG_CPU_ADD("dsp", UPD96050, 15000000)
|
||||
MCFG_CPU_PROGRAM_MAP(st01x_prg_map)
|
||||
MCFG_CPU_DATA_MAP(st01x_data_map)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
//-------------------------------------------------
|
||||
// machine_config_additions - device-specific
|
||||
// machine configurations
|
||||
//-------------------------------------------------
|
||||
|
||||
machine_config_constructor sns_rom_seta10dsp_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( snes_st010 );
|
||||
}
|
||||
|
||||
machine_config_constructor sns_rom_seta11dsp_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( snes_st011 );
|
||||
}
|
||||
|
110
src/mess/machine/sns_upd.h
Normal file
110
src/mess/machine/sns_upd.h
Normal file
@ -0,0 +1,110 @@
|
||||
#ifndef __SNS_UPD_H
|
||||
#define __SNS_UPD_H
|
||||
|
||||
#include "machine/sns_slot.h"
|
||||
#include "machine/sns_rom.h"
|
||||
#include "machine/sns_rom21.h"
|
||||
#include "cpu/upd7725/upd7725.h"
|
||||
|
||||
// ======================> sns_rom_necdsp_device
|
||||
|
||||
class sns_rom20_necdsp_device : public sns_rom_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom20_necdsp_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() { m_shortname = "sns_rom_necdsp"; }
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
required_device<upd7725_device> m_upd7725;
|
||||
|
||||
// additional reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(chip_read);
|
||||
virtual DECLARE_WRITE8_MEMBER(chip_write);
|
||||
|
||||
virtual DECLARE_READ32_MEMBER(necdsp_prg_r);
|
||||
virtual DECLARE_READ16_MEMBER(necdsp_data_r);
|
||||
};
|
||||
|
||||
// ======================> sns_rom21_necdsp_device
|
||||
|
||||
class sns_rom21_necdsp_device : public sns_rom21_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom21_necdsp_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() { m_shortname = "sns_rom21_necdsp"; }
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
required_device<upd7725_device> m_upd7725;
|
||||
|
||||
// additional reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(chip_read);
|
||||
virtual DECLARE_WRITE8_MEMBER(chip_write);
|
||||
|
||||
virtual DECLARE_READ32_MEMBER(necdsp_prg_r);
|
||||
virtual DECLARE_READ16_MEMBER(necdsp_data_r);
|
||||
};
|
||||
|
||||
// ======================> sns_rom_setadsp_device
|
||||
|
||||
class sns_rom_setadsp_device : public sns_rom_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom_setadsp_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_config_complete() { m_shortname = "sns_rom_setadsp"; }
|
||||
|
||||
required_device<upd96050_device> m_upd96050;
|
||||
|
||||
// additional reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(chip_read);
|
||||
virtual DECLARE_WRITE8_MEMBER(chip_write);
|
||||
|
||||
virtual DECLARE_READ32_MEMBER(setadsp_prg_r);
|
||||
virtual DECLARE_READ16_MEMBER(setadsp_data_r);
|
||||
};
|
||||
|
||||
// ======================> sns_rom_seta10_device
|
||||
|
||||
class sns_rom_seta10dsp_device : public sns_rom_setadsp_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom_seta10dsp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_config_complete() { m_shortname = "sns_rom_seta10"; }
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
};
|
||||
|
||||
// ======================> sns_rom_seta11_device [Faster CPU than ST010]
|
||||
|
||||
class sns_rom_seta11dsp_device : public sns_rom_setadsp_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_rom_seta11dsp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_config_complete() { m_shortname = "sns_rom_seta11"; }
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type SNS_LOROM_NECDSP;
|
||||
extern const device_type SNS_HIROM_NECDSP;
|
||||
extern const device_type SNS_LOROM_SETA10;
|
||||
extern const device_type SNS_LOROM_SETA11;
|
||||
|
||||
#endif
|
@ -68,6 +68,8 @@ gbpocket // Nintendo Game Boy Pocket Handheld
|
||||
gblight // Nintendo Game Boy Light Handheld
|
||||
gbcolor // Nintendo Game Boy Color Handheld
|
||||
gba // Nintendo Game Boy Advance Handheld
|
||||
snesnew // Nintendo Super Nintendo NTSC (test driver with slots)
|
||||
snespnew // Nintendo Super Nintendo PAL (test driver with slots)
|
||||
snes // Nintendo Super Nintendo NTSC
|
||||
snespal // Nintendo Super Nintendo PAL
|
||||
snessfx // Nintendo Super Nintendo NTSC w/SuperFX CPU
|
||||
|
@ -1422,6 +1422,15 @@ $(MESSOBJ)/nintendo.a: \
|
||||
$(MESS_MACHINE)/nes.o \
|
||||
$(MESS_DRIVERS)/nes.o \
|
||||
$(MESS_MACHINE)/snescart.o \
|
||||
$(MESS_MACHINE)/sns_slot.o \
|
||||
$(MESS_MACHINE)/sns_rom.o \
|
||||
$(MESS_MACHINE)/sns_rom21.o \
|
||||
$(MESS_MACHINE)/sns_bsx.o \
|
||||
$(MESS_MACHINE)/sns_sdd1.o \
|
||||
$(MESS_MACHINE)/sns_sfx.o \
|
||||
$(MESS_MACHINE)/sns_spc7110.o \
|
||||
$(MESS_MACHINE)/sns_sufami.o \
|
||||
$(MESS_MACHINE)/sns_upd.o \
|
||||
$(MESS_DRIVERS)/snes.o \
|
||||
$(MESS_DRIVERS)/n64.o \
|
||||
$(MESS_AUDIO)/gb.o \
|
||||
|
Loading…
Reference in New Issue
Block a user