mirror of
https://github.com/holub/mame
synced 2025-04-24 09:20:02 +03:00
not yet correct (nw)
This commit is contained in:
parent
bd1f4df87c
commit
96bbc15ff8
@ -151,7 +151,43 @@ WRITE16_MEMBER(sshangha_state::paletteram16_xbgr_word_be_tilehigh_w)
|
||||
sshangha_set_color_888((offset/2)+0x300, 0, 8, 16, m_tile_paletteram2[(offset) | 1] | (m_tile_paletteram2[(offset) & ~1] << 16) );
|
||||
}
|
||||
|
||||
READ16_MEMBER( sshangha_state::sshangha_protection_region_d_146_r )
|
||||
{
|
||||
int real_address = 0x3f4000 + (offset *2);
|
||||
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8, 7,6,5,4, 3,2,1,0) & 0x7fff;
|
||||
UINT8 cs = 0;
|
||||
UINT16 data = m_deco146->read_data( deco146_addr, mem_mask, cs );
|
||||
return data;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER( sshangha_state::sshangha_protection_region_d_146_w )
|
||||
{
|
||||
int real_address = 0x3f4000 + (offset *2);
|
||||
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8, 7,6,5,4, 3,2,1,0) & 0x7fff;
|
||||
UINT8 cs = 0;
|
||||
m_deco146->write_data( deco146_addr, data, mem_mask, cs );
|
||||
}
|
||||
|
||||
READ16_MEMBER( sshangha_state::sshangha_protection_region_8_146_r )
|
||||
{
|
||||
int real_address = 0x3e0000 + (offset *2);
|
||||
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8, 7,6,5,4, 3,2,1,0) & 0x7fff;
|
||||
UINT8 cs = 0;
|
||||
UINT16 data = m_deco146->read_data( deco146_addr, mem_mask, cs );
|
||||
return data;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER( sshangha_state::sshangha_protection_region_8_146_w )
|
||||
{
|
||||
int real_address = 0x3e0000 + (offset *2);
|
||||
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8, 7,6,5,4, 3,2,1,0) & 0x7fff;
|
||||
UINT8 cs = 0;
|
||||
m_deco146->write_data( deco146_addr, data, mem_mask, cs );
|
||||
}
|
||||
|
||||
|
||||
static ADDRESS_MAP_START( sshangha_map, AS_PROGRAM, 16, sshangha_state )
|
||||
ADDRESS_MAP_GLOBAL_MASK(0x3fffff)
|
||||
AM_RANGE(0x000000, 0x03ffff) AM_ROM
|
||||
AM_RANGE(0x100000, 0x10000f) AM_RAM AM_SHARE("sound_shared")
|
||||
|
||||
@ -177,9 +213,9 @@ static ADDRESS_MAP_START( sshangha_map, AS_PROGRAM, 16, sshangha_state )
|
||||
AM_RANGE(0x380800, 0x380bff) AM_RAM_WRITE(paletteram16_xbgr_word_be_sprites2_w) AM_SHARE("sprite_palram2")
|
||||
AM_RANGE(0x380c00, 0x380fff) AM_RAM_WRITE(paletteram16_xbgr_word_be_tilelow_w) AM_SHARE("tile_palram1")
|
||||
AM_RANGE(0x381000, 0x383fff) AM_RAM // unused palette area
|
||||
|
||||
AM_RANGE(0xfec000, 0xff3fff) AM_RAM
|
||||
AM_RANGE(0xff4000, 0xff47ff) AM_READWRITE(sshangha_protection16_r,sshangha_protection16_w) AM_SHARE("prot_data")
|
||||
AM_RANGE(0x3e0000, 0x3e3fff) AM_READWRITE(sshangha_protection_region_8_146_r,sshangha_protection_region_8_146_w)
|
||||
AM_RANGE(0x3ec000, 0x3f3fff) AM_RAM
|
||||
AM_RANGE(0x3f4000, 0x3f7fff) AM_READWRITE(sshangha_protection_region_d_146_r,sshangha_protection_region_d_146_w) AM_SHARE("prot_data")
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( sshanghb_map, AS_PROGRAM, 16, sshangha_state )
|
||||
|
@ -1,11 +1,13 @@
|
||||
#include "video/deco16ic.h"
|
||||
#include "video/decospr.h"
|
||||
#include "machine/deco146.h"
|
||||
|
||||
class sshangha_state : public driver_device
|
||||
{
|
||||
public:
|
||||
sshangha_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag),
|
||||
: driver_device(mconfig, type, tag),
|
||||
m_deco146(*this, "ioprot"),
|
||||
m_deco_tilegen1(*this, "tilegen1"),
|
||||
m_spriteram(*this, "spriteram"),
|
||||
m_spriteram2(*this, "spriteram2"),
|
||||
@ -22,6 +24,7 @@ public:
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_audiocpu(*this, "audiocpu") { }
|
||||
|
||||
optional_device<deco146_device> m_deco146;
|
||||
required_device<deco16ic_device> m_deco_tilegen1;
|
||||
required_shared_ptr<UINT16> m_spriteram;
|
||||
optional_shared_ptr<UINT16> m_spriteram2;
|
||||
@ -42,6 +45,10 @@ public:
|
||||
|
||||
int m_video_control;
|
||||
|
||||
DECLARE_READ16_MEMBER( sshangha_protection_region_8_146_r );
|
||||
DECLARE_WRITE16_MEMBER( sshangha_protection_region_8_146_w );
|
||||
DECLARE_READ16_MEMBER( sshangha_protection_region_d_146_r );
|
||||
DECLARE_WRITE16_MEMBER( sshangha_protection_region_d_146_w );
|
||||
|
||||
|
||||
DECLARE_WRITE16_MEMBER(sshangha_protection16_w);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Data East 146 protection chip & I/O interface */
|
||||
/* Data East 146 protection chip / memory-mapper & I/O interface */
|
||||
|
||||
#include "emu.h"
|
||||
#include "deco146.h"
|
||||
@ -25,7 +25,7 @@ struct nibselect
|
||||
struct deco146port
|
||||
{
|
||||
UINT16 read_offset;
|
||||
UINT16 write_offset;
|
||||
int write_offset;
|
||||
// char bit_mapping[16];
|
||||
UINT16 nibble_rotate;
|
||||
// UINT16 blank_mask;
|
||||
@ -1082,33 +1082,280 @@ struct deco146port
|
||||
{ 0x7FE, 0x4C/*, "FEDC3210BA987654"*/, 0/*, 0xFFFF*/, { 3,0,2,1 }, 2}, // .N.
|
||||
};
|
||||
|
||||
static ADDRESS_MAP_START( deco146_map, AS_0, 16, deco146_device )
|
||||
AM_RANGE(0x0000, 0x07ff) AM_RAM
|
||||
AM_RANGE(0x0800, 0x0fff) AM_RAM
|
||||
AM_RANGE(0x1000, 0x17ff) AM_RAM
|
||||
AM_RANGE(0x1800, 0x1fff) AM_RAM
|
||||
AM_RANGE(0x2000, 0x27ff) AM_RAM
|
||||
AM_RANGE(0x2800, 0x2fff) AM_RAM
|
||||
AM_RANGE(0x3000, 0x37ff) AM_RAM
|
||||
AM_RANGE(0x3800, 0x3fff) AM_RAM
|
||||
AM_RANGE(0x4000, 0x47ff) AM_RAM
|
||||
AM_RANGE(0x4800, 0x4fff) AM_RAM
|
||||
AM_RANGE(0x5000, 0x57ff) AM_RAM
|
||||
AM_RANGE(0x5800, 0x5fff) AM_RAM
|
||||
AM_RANGE(0x6000, 0x67ff) AM_RAM
|
||||
AM_RANGE(0x6800, 0x6fff) AM_RAM
|
||||
AM_RANGE(0x7000, 0x77ff) AM_RAM
|
||||
AM_RANGE(0x7800, 0x7fff) AM_RAM
|
||||
ADDRESS_MAP_END
|
||||
/* there are probably less dumb ways of doing the CS logic, it could be hooked up
|
||||
more like the system16 mapper chips */
|
||||
|
||||
void deco146_device::write_data(UINT16 address, UINT16 data, UINT16 mem_mask, UINT8 &csflags)
|
||||
{
|
||||
csflags = 0;
|
||||
int upper_addr_bits = (address & 0x7800) >> 11;
|
||||
|
||||
if (upper_addr_bits == 0x8) // configuration registers are hardcoded to this area
|
||||
{
|
||||
int real_address = address & 0xf;
|
||||
printf("write to config regs %04x %04x %04x\n", real_address, data, mem_mask);
|
||||
|
||||
if ((real_address>=0x2) && (real_address<=0x0c))
|
||||
{
|
||||
region_selects[(real_address-2)/2] = data &0xf;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// unknown
|
||||
}
|
||||
|
||||
return; // or fall through?
|
||||
}
|
||||
|
||||
for (int i=0;i<6;i++)
|
||||
{
|
||||
int cs = region_selects[i];
|
||||
|
||||
if (cs==upper_addr_bits)
|
||||
{
|
||||
int real_address = address & 0x7ff;
|
||||
csflags |= (1 << i);
|
||||
|
||||
if (i==0) // the first cs is our internal protection area
|
||||
{
|
||||
printf("write matches cs table (protection) %01x %04x %04x %04x\n", i, real_address, data, mem_mask);
|
||||
write_protport(real_address, data, mem_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("write matches cs table (external connection) %01x %04x %04x %04x\n", i, real_address, data, mem_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (csflags==0)
|
||||
{
|
||||
printf("write not in cs table\n");
|
||||
}
|
||||
}
|
||||
|
||||
UINT16 deco146_device::read_input_a_callback(void)
|
||||
{
|
||||
return ioport(":INPUTS")->read();
|
||||
}
|
||||
|
||||
UINT16 deco146_device::read_input_b_callback(void)
|
||||
{
|
||||
return ioport(":SYSTEM")->read();
|
||||
}
|
||||
|
||||
UINT16 deco146_device::read_input_c_callback(void)
|
||||
{
|
||||
return ioport(":DSW")->read();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
UINT16 deco146_device::read_protport(UINT16 address, UINT16 mem_mask)
|
||||
{
|
||||
UINT16 retdata = 0;
|
||||
|
||||
// if we read the last written address immediately after then ignore all other logic and just return what was written unmodified
|
||||
if ((address==m_latchaddr) && (m_latchflag==1))
|
||||
{
|
||||
printf("returning latched data %04x\n", m_latchdata);
|
||||
m_latchflag = 0;
|
||||
return m_latchdata;
|
||||
}
|
||||
|
||||
m_latchflag = 0;
|
||||
|
||||
// otherwise process the data..
|
||||
|
||||
int location = port_info[address>>1].write_offset;
|
||||
|
||||
if (location==INPUT_PORT_A)
|
||||
{
|
||||
retdata = read_input_a_callback();
|
||||
}
|
||||
else if (location==INPUT_PORT_B)
|
||||
{
|
||||
retdata = read_input_b_callback();
|
||||
}
|
||||
else if (location==INPUT_PORT_C)
|
||||
{
|
||||
retdata = read_input_c_callback();
|
||||
}
|
||||
else
|
||||
{
|
||||
retdata = m_current_rambank[location>>1];
|
||||
}
|
||||
|
||||
int flags = (port_info[address>>1].flags);
|
||||
|
||||
if (location>=0)
|
||||
{
|
||||
printf("read_protport (real ram addres %02x) | %04x %04x | ", location, address, mem_mask);
|
||||
|
||||
printf("nibble order %d %d %d %d | ", (port_info[address>>1].nibbles.nib0), (port_info[address>>1].nibbles.nib1),(port_info[address>>1].nibbles.nib2),(port_info[address>>1].nibbles.nib3) );
|
||||
printf("lowest nibble rotate %d | ",(port_info[address>>1].nibble_rotate) );
|
||||
|
||||
if (flags&1) printf("read is affected by XOR | ");
|
||||
if (flags&2) printf("read is affected by NAND | ");
|
||||
//if (flags&4) printf("read has nibbles blanked out\n");
|
||||
|
||||
|
||||
printf("would return %04x | ", retdata);
|
||||
|
||||
}
|
||||
|
||||
int nib;
|
||||
|
||||
|
||||
UINT16 realret = 0;
|
||||
|
||||
nib = port_info[address>>1].nibbles.nib0;
|
||||
if (nib==0) realret |= ((retdata & 0x000f)<<12);
|
||||
if (nib==1) realret |= ((retdata & 0x00f0)<<8);
|
||||
if (nib==2) realret |= ((retdata & 0x0f00)<<4);
|
||||
if (nib==3) realret |= ((retdata & 0xf000)<<0);
|
||||
|
||||
nib = port_info[address>>1].nibbles.nib1;
|
||||
if (nib==0) realret |= ((retdata & 0x000f)<<8);
|
||||
if (nib==1) realret |= ((retdata & 0x00f0)<<4);
|
||||
if (nib==2) realret |= ((retdata & 0x0f00)<<0);
|
||||
if (nib==3) realret |= ((retdata & 0xf000)>>4);
|
||||
|
||||
nib = port_info[address>>1].nibbles.nib2;
|
||||
if (nib==0) realret |= ((retdata & 0x000f)<<4);
|
||||
if (nib==1) realret |= ((retdata & 0x00f0)<<0);
|
||||
if (nib==2) realret |= ((retdata & 0x0f00)>>4);
|
||||
if (nib==3) realret |= ((retdata & 0xf000)>>8);
|
||||
|
||||
nib = port_info[address>>1].nibbles.nib3;
|
||||
UINT16 lownib = 0;
|
||||
if (nib==0) lownib = ((retdata & 0x000f)<<0);
|
||||
if (nib==1) lownib = ((retdata & 0x00f0)>>4);
|
||||
if (nib==2) lownib = ((retdata & 0x0f00)>>8);
|
||||
if (nib==3) lownib = ((retdata & 0xf000)>>12);
|
||||
|
||||
int rotate = (port_info[address>>1].nibble_rotate);
|
||||
|
||||
if (rotate==0)
|
||||
{
|
||||
}
|
||||
else if (rotate==1)
|
||||
{
|
||||
lownib = ((lownib&0x7) << 1) | ((lownib&0x8) >> 3);
|
||||
}
|
||||
else if (rotate==2)
|
||||
{
|
||||
lownib = ((lownib&0x3) << 2) | ((lownib&0xc) >> 2);
|
||||
}
|
||||
else if (rotate==3)
|
||||
{
|
||||
lownib = ((lownib&0x1) << 3) | ((lownib&0xe) >> 1);
|
||||
}
|
||||
|
||||
realret |= lownib;
|
||||
|
||||
if (flags&1) realret ^= m_xor;
|
||||
if (flags&2) realret = (realret & m_nand)^0xffff;
|
||||
|
||||
if (location>=0)
|
||||
{
|
||||
printf("actual return %04x \n", realret);
|
||||
}
|
||||
|
||||
if (location == 0x78) // this has a special meaning
|
||||
{
|
||||
printf("(bankswitch) %04x %04x\n", address, mem_mask);
|
||||
|
||||
if (m_current_rambank==m_rambank0)
|
||||
m_current_rambank = m_rambank1;
|
||||
else
|
||||
m_current_rambank = m_rambank0;
|
||||
}
|
||||
|
||||
|
||||
return realret;
|
||||
}
|
||||
|
||||
void deco146_device::write_protport(UINT16 address, UINT16 data, UINT16 mem_mask)
|
||||
{
|
||||
m_latchaddr = address;
|
||||
m_latchdata = data;
|
||||
m_latchflag = 1;
|
||||
|
||||
if ((address&0xff) == 0x2c)
|
||||
{
|
||||
printf("LOAD XOR REGISTER %04x %04x\n", data, mem_mask);
|
||||
COMBINE_DATA(&m_xor);
|
||||
}
|
||||
else if ((address&0xff) == 0x36)
|
||||
{
|
||||
printf("LOAD NAND REGISTER %04x %04x\n", data, mem_mask);
|
||||
COMBINE_DATA(&m_nand);
|
||||
}
|
||||
else if ((address&0xff) == 0x64)
|
||||
{
|
||||
printf("LOAD SOUND LATCH %04x %04x\n", data, mem_mask);
|
||||
COMBINE_DATA(&m_soundlatch);
|
||||
}
|
||||
|
||||
// always store
|
||||
COMBINE_DATA(&m_current_rambank[address>>1]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
UINT16 deco146_device::read_data(UINT16 address, UINT16 mem_mask, UINT8 &csflags)
|
||||
{
|
||||
UINT16 retdata = 0;
|
||||
csflags = 0;
|
||||
int upper_addr_bits = (address & 0x7800) >> 11;
|
||||
|
||||
if (upper_addr_bits == 0x8) // configuration registers are hardcoded to this area
|
||||
{
|
||||
int real_address = address & 0xf;
|
||||
printf("read config regs? %04x %04x\n", real_address, mem_mask);
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
// what gets priority?
|
||||
for (int i=0;i<6;i++)
|
||||
{
|
||||
int cs = region_selects[i];
|
||||
|
||||
if (cs==upper_addr_bits)
|
||||
{
|
||||
int real_address = address & 0x7ff;
|
||||
csflags |= (1 << i);
|
||||
|
||||
if (i==0) // the first cs is our internal protection area
|
||||
{
|
||||
//printf("read matches cs table (protection) %01x %04x %04x\n", i, real_address, mem_mask);
|
||||
retdata = read_protport( real_address, mem_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("read matches cs table (external connection) %01x %04x %04x\n", i, real_address, mem_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (csflags==0)
|
||||
{
|
||||
printf("read not in cs table\n");
|
||||
}
|
||||
|
||||
return retdata;
|
||||
}
|
||||
|
||||
|
||||
const device_type DECO146PROT = &device_creator<deco146_device>;
|
||||
|
||||
|
||||
|
||||
deco146_device::deco146_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, DECO146PROT, "DECO146PROT", tag, owner, clock, "deco146", __FILE__),
|
||||
device_memory_interface(mconfig, *this),
|
||||
m_space_config("deco146_space", ENDIANNESS_BIG, 16,15, 0, NULL, *ADDRESS_MAP_NAME(deco146_map))
|
||||
: device_t(mconfig, DECO146PROT, "DECO146PROT", tag, owner, clock, "deco146", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1127,13 +1374,32 @@ void deco146_device::device_start()
|
||||
if (read_address != i*2)
|
||||
printf("%04x %02x\n", port_info[i].read_offset, port_info[i].write_offset);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void deco146_device::device_reset()
|
||||
{
|
||||
region_selects[0] = 0;
|
||||
region_selects[1] = 0;
|
||||
region_selects[2] = 0;
|
||||
region_selects[3] = 0;
|
||||
region_selects[4] = 0;
|
||||
region_selects[5] = 0;
|
||||
|
||||
for (int i=0;i<0x80;i++)
|
||||
{
|
||||
m_rambank0[i] = 0x0000;
|
||||
m_rambank1[i] = 0xffff;
|
||||
}
|
||||
|
||||
m_current_rambank = m_rambank0;
|
||||
|
||||
m_nand = 0x0000;
|
||||
m_xor = 0x0000;
|
||||
m_soundlatch = 0x0000;
|
||||
|
||||
m_latchaddr = 0xffff;
|
||||
m_latchdata = 0x0000;
|
||||
m_latchflag = 0;
|
||||
}
|
||||
|
||||
const address_space_config *deco146_device::memory_space_config(address_spacenum spacenum) const
|
||||
{
|
||||
return (spacenum == 0) ? &m_space_config : NULL;
|
||||
}
|
||||
|
@ -1,16 +1,46 @@
|
||||
#pragma once
|
||||
#ifndef __DECO146_H__
|
||||
#define __DECO146_H__
|
||||
|
||||
|
||||
/* Data East 146 protection chip */
|
||||
|
||||
class deco146_device : public device_t,
|
||||
public device_memory_interface
|
||||
class deco146_device : public device_t
|
||||
{
|
||||
public:
|
||||
deco146_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
void write_data(UINT16 address, UINT16 data, UINT16 mem_mask, UINT8 &csflags);
|
||||
UINT16 read_data(UINT16 address, UINT16 mem_mask, UINT8 &csflags);
|
||||
|
||||
protected:
|
||||
virtual void device_config_complete();
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
|
||||
address_space_config m_space_config;
|
||||
|
||||
UINT16 read_protport(UINT16 address, UINT16 mem_mask);
|
||||
void write_protport(UINT16 address, UINT16 data, UINT16 mem_mask);
|
||||
|
||||
UINT16 m_rambank0[0x80];
|
||||
UINT16 m_rambank1[0x80];
|
||||
|
||||
UINT16* m_current_rambank;
|
||||
|
||||
UINT16 read_input_a_callback(void);
|
||||
UINT16 read_input_b_callback(void);
|
||||
UINT16 read_input_c_callback(void);
|
||||
|
||||
UINT16 m_nand;
|
||||
UINT16 m_xor;
|
||||
UINT16 m_soundlatch;
|
||||
|
||||
UINT16 m_latchaddr;
|
||||
UINT16 m_latchdata;
|
||||
int m_latchflag;
|
||||
|
||||
|
||||
private:
|
||||
UINT8 region_selects[6];
|
||||
|
||||
};
|
||||
|
||||
@ -22,4 +52,4 @@ extern const device_type DECO146PROT;
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user