gsword WIP:

* Split out gsword and josvolly functionalit from base driver class
* Hooked up josvolly MCUs for communication between CPUs
* Added DIP locations to josvolly based on test mode
* Named unknown DIP settings after the location they control in main RAM
* Hooked up josvolly MCUs for communication, still preliminary
* Marked josvolly NOT_WORKING, simulation still present for reference

(nw) The MCU code only makes sense if there are a pair of them hooked up
together.  There are effectively two programs, selected by whether P27
is tied high (master) or low (slave) at reset.  Master and slave have
all corresponding P1 lines connected, master P20 connects to slave
TEST0, and master P21 connects to slave TEST1.  You can see commands
and responses pass between the master and slave, it's very chatty.  Test
mode seems to work, but game mode fails a check after a couple of
seconds and dumps status codes on the screen.  There's still something
missing in the MCU hookup, and I'd guess there's something attached to
the AY output ports, too.
This commit is contained in:
Vas Crabb 2017-01-01 18:25:35 +11:00
parent 9d329bfc0c
commit 1b544b42a2
3 changed files with 474 additions and 278 deletions

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:Steve Ellenoff,Jarek Parchanski
// copyright-holders:Steve Ellenoff,Jarek Parchanski,Vas Crabb
/*
Great Swordsman (Taito) 1984
Joshi Volleyball (Taito) 1983
@ -9,9 +9,9 @@ TODO:
-joshi volleyball
-The incomplete graphic
-The implementation of DAC sound ?
-MCU code DUMP and emulation
-MCU hookup is incomplete
-The true interrupt circuit of SUB CPU
-unknown ROM (BANK ROM of sub-cpu ? )
-unknown ROM (BANK ROM of sub-cpu ?)
Credits:
- Steve Ellenoff: Original emulation and Mame driver
@ -146,6 +146,7 @@ reg: 0->1 (main->2nd) / : (1->0) 2nd->main :
#include "emu.h"
#include "includes/gsword.h"
#include "cpu/mcs48/mcs48.h"
#include "cpu/z80/z80.h"
#include "machine/i8255.h"
#include "machine/tait8741.h"
@ -166,20 +167,48 @@ int gsword_state::coins_in(void)
}
#endif
#include "cpu/z80/z80.h"
void gsword_state_base::machine_start()
{
save_item(NAME(m_fake8910_0));
save_item(NAME(m_fake8910_1));
}
void gsword_state_base::machine_reset()
{
}
WRITE8_MEMBER(gsword_state_base::ay8910_control_port_0_w)
{
m_ay0->address_w(space,offset,data);
m_fake8910_0 = data;
}
WRITE8_MEMBER(gsword_state_base::ay8910_control_port_1_w)
{
m_ay1->address_w(space,offset,data);
m_fake8910_1 = data;
}
READ8_MEMBER(gsword_state_base::fake_0_r)
{
return m_fake8910_0+1;
}
READ8_MEMBER(gsword_state_base::fake_1_r)
{
return m_fake8910_1+1;
}
/* CPU 2 memory hack */
/* (402E) timeout upcount must be under 0AH */
/* (4004,4005) clear down counter , if (4004,4005)==0 then (402E)=0 */
READ8_MEMBER(gsword_state::gsword_hack_r)
READ8_MEMBER(gsword_state::hack_r)
{
uint8_t data = m_cpu2_ram[offset + 4];
u8 const data = m_cpu2_ram[offset + 4];
/*if(offset==1)osd_printf_debug("CNT %02X%02X\n",m_cpu2_ram[5],m_cpu2_ram[4]); */
/* speedup timeout count down */
if(m_protect_hack)
if (m_protect_hack)
{
switch(offset)
{
@ -190,7 +219,55 @@ READ8_MEMBER(gsword_state::gsword_hack_r)
return data;
}
READ8_MEMBER(gsword_state::gsword_8741_2_r )
WRITE8_MEMBER(gsword_state::nmi_set_w)
{
/* osd_printf_debug("AY write %02X\n",data);*/
m_protect_hack = (data & 0x80) ? false : true;
#if 0
/* An actual circuit isn't known. */
/* write ff,02,ff,fe, 17 x 0d,0f */
m_nmi_enable = ((data>>7) & (data&1) &1) == 0;
#else
switch(data)
{
case 0xff:
m_nmi_enable = false; /* NMI must be disabled */
break;
case 0x02:
m_nmi_enable = false; /* ANY */
break;
case 0x0d:
m_nmi_enable = true;
break;
case 0x0f:
m_nmi_enable = true; /* NMI must be enabled */
break;
case 0xfe:
m_nmi_enable = true; /* NMI must be enabled */
break;
}
/* bit1= nmi disable , for ram check */
logerror("NMI control %02x\n",data);
#endif
}
WRITE8_MEMBER(gsword_state::sound_command_w)
{
m_soundlatch->write(space, 0, data);
m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
}
WRITE8_MEMBER(gsword_state::adpcm_data_w)
{
m_msm->data_w(data & 0x0f); // bit 0..3
m_msm->reset_w(BIT(data, 5)); // bit 5
m_msm->vclk_w(BIT(data, 4)); // bit 4
}
READ8_MEMBER(gsword_state::i8741_2_r )
{
switch (offset)
{
@ -207,7 +284,7 @@ READ8_MEMBER(gsword_state::gsword_8741_2_r )
return 0;
}
READ8_MEMBER(gsword_state::gsword_8741_3_r )
READ8_MEMBER(gsword_state::i8741_3_r )
{
switch (offset)
{
@ -223,99 +300,166 @@ READ8_MEMBER(gsword_state::gsword_8741_3_r )
return 0;
}
INTERRUPT_GEN_MEMBER(gsword_state::sound_interrupt)
{
if (m_nmi_enable)
device.execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE);
}
DRIVER_INIT_MEMBER(gsword_state, gsword)
{
#if 0
uint8_t *ROM2 = memregion("sub")->base();
ROM2[0x1da] = 0xc3; /* patch for rom self check */
ROM2[0x71e] = 0; /* patch for sound protection or time out function */
ROM2[0x71f] = 0;
#endif
#if 1
/* hack for sound protection or time out function */
m_subcpu->space(AS_PROGRAM).install_read_handler(0x4004, 0x4005, read8_delegate(FUNC(gsword_state::hack_r),this));
#endif
}
DRIVER_INIT_MEMBER(gsword_state, gsword2)
{
#if 0
uint8_t *ROM2 = memregion("sub")->base();
ROM2[0x1da] = 0xc3; /* patch for rom self check */
ROM2[0x726] = 0; /* patch for sound protection or time out function */
ROM2[0x727] = 0;
#endif
#if 1
/* hack for sound protection or time out function */
m_subcpu->space(AS_PROGRAM).install_read_handler(0x4004, 0x4005, read8_delegate(FUNC(gsword_state::hack_r),this));
#endif
}
void gsword_state::machine_start()
{
save_item(NAME(m_fake8910_0));
save_item(NAME(m_fake8910_1));
save_item(NAME(m_nmi_enable));
gsword_state_base::machine_start();
save_item(NAME(m_protect_hack));
save_item(NAME(m_nmi_enable));
}
void gsword_state::machine_reset()
{
m_coins = 0;
gsword_state_base::machine_reset();
/* snd CPU mask NMI during reset phase */
m_nmi_enable = 0;
m_protect_hack = 0;
m_protect_hack = false;
m_nmi_enable = false;
}
INTERRUPT_GEN_MEMBER(gsword_state::gsword_snd_interrupt)
READ8_MEMBER(josvolly_state::mcu1_p1_r)
{
if(m_nmi_enable)
device.execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE);
// the two MCUs appear to have port 1 tied together
return m_mcu1_p1 & m_mcu2_p1;
}
WRITE8_MEMBER(gsword_state::nmi_set_w)
READ8_MEMBER(josvolly_state::mcu1_p2_r)
{
/* osd_printf_debug("AY write %02X\n",data);*/
// p27 needs to float high for the MCU to start in the right mode
// p20 and p21 drive the test inputs of the other MCU
// if DIPSW1:8 is allowed to pull p27 low, the game won't even boot to test mode
// DIPSW1:1 and DIPSW1:2 are shown in test mode, but switching them on will break comms
return 0x80U | ioport("DSW1")->read();
}
m_protect_hack = (data&0x80) ? 0 : 1;
#if 0
/* An actual circuit isn't known. */
/* write ff,02,ff,fe, 17 x 0d,0f */
m_nmi_enable = ((data>>7) & (data&1) &1) == 0;
READ8_MEMBER(josvolly_state::mcu2_p1_r)
{
// the two MCUs appear to have port 1 tied together
return m_mcu1_p1 & m_mcu2_p1;
}
READ8_MEMBER(josvolly_state::mcu2_p2_r)
{
// p27 needs to be tied low for the MCU to start in the right mode
return 0x7fU & ioport("DSW2")->read();
}
#else
switch(data)
READ8_MEMBER(josvolly_state::mcu2_test_r)
{
// TEST0 and TEST1 are driven by P20 and P21 on the other MCU
return BIT(m_mcu1_p2, offset);
}
WRITE8_MEMBER(josvolly_state::cpu2_nmi_enable_w)
{
m_cpu2_nmi_enable = true;
}
WRITE8_MEMBER(josvolly_state::cpu2_irq_clear_w)
{
m_audiocpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE);
}
WRITE8_MEMBER(josvolly_state::mcu1_p1_w)
{
if (data != m_mcu1_p1)
{
case 0xff:
m_nmi_enable = 0; /* NMI must be disabled */
break;
case 0x02:
m_nmi_enable = 0; /* ANY */
break;
case 0x0d:
m_nmi_enable = 1;
break;
case 0x0f:
m_nmi_enable = 1; /* NMI must be enabled */
break;
case 0xfe:
m_nmi_enable = 1; /* NMI must be enabled */
break;
logerror("mcu1 p1 = 0x%02x\n", data);
m_mcu1_p1 = data;
}
/* bit1= nmi disable , for ram check */
logerror("NMI control %02x\n",data);
#endif
}
WRITE8_MEMBER(gsword_state::ay8910_control_port_0_w)
WRITE8_MEMBER(josvolly_state::mcu1_p2_w)
{
m_ay0->address_w(space,offset,data);
m_fake8910_0 = data;
}
WRITE8_MEMBER(gsword_state::ay8910_control_port_1_w)
{
m_ay1->address_w(space,offset,data);
m_fake8910_1 = data;
if (data != m_mcu1_p2)
{
logerror("mcu1 p2 = 0x%02x\n", data);
// the second CPU somehow gets an NMI when data is available
// it's probably implemented by the logic arrays somehow
// this is just a hacky guess at how it works
if (m_cpu2_nmi_enable && (data & (data ^ m_mcu1_p2) & 0x01))
{
m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
m_cpu2_nmi_enable = false;
}
m_mcu1_p2 = data;
}
}
READ8_MEMBER(gsword_state::fake_0_r)
WRITE8_MEMBER(josvolly_state::mcu2_p1_w)
{
return m_fake8910_0+1;
}
READ8_MEMBER(gsword_state::fake_1_r)
{
return m_fake8910_1+1;
if (data != m_mcu2_p1)
{
logerror("mcu2 p1 = 0x%02x\n", data);
m_mcu2_p1 = data;
}
}
WRITE8_MEMBER(gsword_state::gsword_adpcm_data_w)
WRITE8_MEMBER(josvolly_state::mcu2_p2_w)
{
m_msm->data_w (data & 0x0f); /* bit 0..3 */
m_msm->reset_w(BIT(data, 5)); /* bit 5 */
m_msm->vclk_w(BIT(data, 4)); /* bit 4 */
logerror("mcu2 p2 = 0x%02x\n", data);
}
WRITE8_MEMBER(gsword_state::adpcm_soundcommand_w)
void josvolly_state::machine_start()
{
m_soundlatch->write(space, 0, data);
m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
gsword_state_base::machine_start();
save_item(NAME(m_cpu2_nmi_enable));
save_item(NAME(m_mcu1_p1));
save_item(NAME(m_mcu1_p2));
save_item(NAME(m_mcu2_p1));
}
void josvolly_state::machine_reset()
{
gsword_state_base::machine_reset();
m_cpu2_nmi_enable = false;
m_mcu1_p1 = 0xffU;
m_mcu1_p2 = 0xffU;
m_mcu2_p1 = 0xffU;
}
static ADDRESS_MAP_START( cpu1_map, AS_PROGRAM , 8, gsword_state )
static ADDRESS_MAP_START( cpu1_map, AS_PROGRAM , 8, gsword_state_base )
AM_RANGE(0x0000, 0x8fff) AM_ROM
AM_RANGE(0x9000, 0x9fff) AM_RAM
AM_RANGE(0xa000, 0xa37f) AM_RAM
@ -329,21 +473,16 @@ static ADDRESS_MAP_START( cpu1_map, AS_PROGRAM , 8, gsword_state )
AM_RANGE(0xb000, 0xb7ff) AM_RAM_WRITE(videoram_w) AM_SHARE("videoram")
ADDRESS_MAP_END
static ADDRESS_MAP_START( cpu1_io_map, AS_IO, 8, gsword_state )
ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE(0x7e, 0x7f) AM_DEVREADWRITE("taito8741", taito8741_4pack_device, read_0, write_0)
ADDRESS_MAP_END
static ADDRESS_MAP_START( josvolly_cpu1_io_map, AS_IO, 8, gsword_state )
ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE(0x7e, 0x7f) AM_DEVREADWRITE("josvolly_8741", josvolly8741_4pack_device, read_0, write_0)
ADDRESS_MAP_END
//
static ADDRESS_MAP_START( cpu2_map, AS_PROGRAM, 8, gsword_state )
AM_RANGE(0x0000, 0x3fff) AM_ROM
AM_RANGE(0x4000, 0x43ff) AM_RAM AM_SHARE("cpu2_ram")
AM_RANGE(0x6000, 0x6000) AM_WRITE(adpcm_soundcommand_w)
AM_RANGE(0x6000, 0x6000) AM_WRITE(sound_command_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( cpu2_io_map, AS_IO, 8, gsword_state )
@ -355,44 +494,58 @@ static ADDRESS_MAP_START( cpu2_io_map, AS_IO, 8, gsword_state )
AM_RANGE(0x61, 0x61) AM_DEVREADWRITE("ay1", ay8910_device, data_r, data_w)
AM_RANGE(0x80, 0x80) AM_READWRITE(fake_1_r, ay8910_control_port_1_w)
AM_RANGE(0x81, 0x81) AM_DEVREADWRITE("ay2", ay8910_device, data_r, data_w)
//
AM_RANGE(0xe0, 0xe0) AM_READNOP /* ?? */
AM_RANGE(0xa0, 0xa0) AM_WRITENOP /* ?? */
AM_RANGE(0xe0, 0xe0) AM_WRITENOP /* watch dog ?*/
AM_RANGE(0xe0, 0xe0) AM_WRITENOP /* watchdog? */
ADDRESS_MAP_END
//
static ADDRESS_MAP_START( cpu3_map, AS_PROGRAM, 8, gsword_state )
AM_RANGE(0x0000, 0x7fff) AM_ROM
AM_RANGE(0x8000, 0x8000) AM_WRITE(gsword_adpcm_data_w)
AM_RANGE(0x8000, 0x8000) AM_WRITE(adpcm_data_w)
AM_RANGE(0xa000, 0xa000) AM_DEVREAD("soundlatch", generic_latch_8_device, read)
ADDRESS_MAP_END
static ADDRESS_MAP_START( josvolly_cpu2_map, AS_PROGRAM, 8, gsword_state )
static ADDRESS_MAP_START( josvolly_cpu1_io_map, AS_IO, 8, josvolly_state )
ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE(0x7e, 0x7f) AM_DEVREADWRITE("mcu1", upi41_cpu_device, upi41_master_r, upi41_master_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( josvolly_cpu2_map, AS_PROGRAM, 8, josvolly_state )
AM_RANGE(0x0000, 0x3fff) AM_ROM
AM_RANGE(0x4000, 0x43ff) AM_RAM AM_SHARE("cpu2_ram")
/* NEC D8255A with silkscreen removed and replaced with "AA 007" */
AM_RANGE(0x8000, 0x8003) AM_DEVREADWRITE("josvolly_aa_007", i8255_device, read, write)
AM_RANGE(0x8000, 0x8003) AM_DEVREADWRITE("aa_007", i8255_device, read, write)
// AM_RANGE(0x6000, 0x6000) AM_WRITE(adpcm_soundcommand_w)
AM_RANGE(0xA000, 0xA001) AM_DEVREADWRITE("josvolly_8741", josvolly8741_4pack_device, read_1, write_1)
AM_RANGE(0xA000, 0xA001) AM_DEVREADWRITE("mcu2", upi41_cpu_device, upi41_master_r, upi41_master_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( josvolly_cpu2_io_map, AS_IO, 8, gsword_state )
static ADDRESS_MAP_START( josvolly_cpu2_io_map, AS_IO, 8, josvolly_state )
ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE(0x00, 0x00) AM_READWRITE(fake_0_r, ay8910_control_port_0_w)
AM_RANGE(0x01, 0x01) AM_DEVREADWRITE("ay1", ay8910_device, data_r, data_w)
AM_RANGE(0x40, 0x40) AM_READWRITE(fake_1_r, ay8910_control_port_1_w)
AM_RANGE(0x41, 0x41) AM_DEVREADWRITE("ay2", ay8910_device, data_r, data_w)
AM_RANGE(0x81, 0x81) AM_DEVWRITE("josvolly_8741", josvolly8741_4pack_device, nmi_enable_w)
AM_RANGE(0xC1, 0xC1) AM_NOP // irq clear
AM_RANGE(0x81, 0x81) AM_WRITE(cpu2_nmi_enable_w);
AM_RANGE(0xC1, 0xC1) AM_WRITE(cpu2_irq_clear_w);
ADDRESS_MAP_END
static ADDRESS_MAP_START( josvolly_mcu1_io_map, AS_IO, 8, josvolly_state )
AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_READWRITE(mcu1_p1_r, mcu1_p1_w)
AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READWRITE(mcu1_p2_r, mcu1_p2_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( josvolly_mcu2_io_map, AS_IO, 8, josvolly_state )
AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_READWRITE(mcu2_p1_r, mcu2_p1_w)
AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READWRITE(mcu2_p2_r, mcu2_p2_w)
AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T1) AM_READ(mcu2_test_r)
ADDRESS_MAP_END
static INPUT_PORTS_START( gsword )
PORT_START("IN0") /* IN0 (8741-2 port1?) */
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START1 )
@ -539,44 +692,55 @@ static INPUT_PORTS_START( josvolly )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_START("DSW1") /* DSW1 */
PORT_DIPNAME( 0x0c, 0x00, "DIP1-0c(982E)" )
PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unused ) ) PORT_DIPLOCATION("DIPSW1:1")
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unused ) ) PORT_DIPLOCATION("DIPSW1:2")
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x0c, 0x0c, "982E" ) PORT_DIPLOCATION("DIPSW1:3,4")
PORT_DIPSETTING( 0x0c, "0" )
PORT_DIPSETTING( 0x08, "1" )
PORT_DIPSETTING( 0x00, "2" )
PORT_DIPSETTING( 0x0c, "3" )
PORT_DIPNAME( 0x30, 0x00, "DIP1-30(982A)" )
PORT_DIPSETTING( 0x30, "96H" )
PORT_DIPSETTING( 0x20, "78H" )
PORT_DIPSETTING( 0x10, "5AH" )
PORT_DIPSETTING( 0x00, "3CH" )
PORT_DIPNAME( 0x40, 0x40, "TEST_MODE" )
PORT_DIPSETTING( 0x04, "2" )
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPNAME( 0x30, 0x30, "982A" ) PORT_DIPLOCATION("DIPSW1:5,6")
PORT_DIPSETTING( 0x00, "60" )
PORT_DIPSETTING( 0x10, "90" )
PORT_DIPSETTING( 0x20, "120" )
PORT_DIPSETTING( 0x30, "150" )
PORT_DIPNAME( 0x40, 0x40, "TEST_MODE" ) PORT_DIPLOCATION("DIPSW1:7")
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, "DIP1-80(982C)" )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x80, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unused ) ) PORT_DIPLOCATION("DIPSW1:8")
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START("DSW2") /* DSW2 */
// PORT_DIPNAME( 0x01, 0x00, "DSW2-0" )
// PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
// PORT_DIPSETTING( 0x01, DEF_STR( On ) )
// PORT_DIPNAME( 0x02, 0x00, "DSW2-1($9831)" )
// PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
// PORT_DIPSETTING( 0x02, DEF_STR( On ) )
PORT_DIPNAME( 0x0C, 0x0C, DEF_STR( Coin_A ) )
PORT_DIPNAME( 0x01, 0x01, "982C" ) PORT_DIPLOCATION("DIPSW2:8")
PORT_DIPSETTING( 0x01, "0" )
PORT_DIPSETTING( 0x00, "1" )
PORT_DIPNAME( 0x02, 0x02, "9831" ) PORT_DIPLOCATION("DIPSW2:7")
PORT_DIPSETTING( 0x02, "0" )
PORT_DIPSETTING( 0x00, "1" )
PORT_DIPNAME( 0x0c, 0x0c, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("DIPSW2:6,5")
PORT_DIPSETTING( 0x00, DEF_STR( 5C_1C ) )
PORT_DIPSETTING( 0x08, DEF_STR( 4C_1C ) )
PORT_DIPSETTING( 0x04, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x0C, DEF_STR( 1C_1C ) )
PORT_DIPNAME( 0x30, 0x30, DEF_STR( Coin_B ) )
PORT_DIPSETTING( 0x0c, DEF_STR( 1C_1C ) )
PORT_DIPNAME( 0x30, 0x30, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("DIPSW2:4,3")
PORT_DIPSETTING( 0x30, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0x10, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x20, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0x00, DEF_STR( 1C_5C ) )
// PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
// PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_DIPNAME( 0x40, 0x40, "9827" ) PORT_DIPLOCATION("DIPSW2:2")
PORT_DIPSETTING( 0x40, "1" )
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unused ) ) PORT_DIPLOCATION("DIPSW2:1")
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
INPUT_PORTS_END
static const gfx_layout gsword_text =
{
8,8, /* 8x8 characters */
@ -636,7 +800,7 @@ static MACHINE_CONFIG_START( gsword, gsword_state )
MCFG_CPU_ADD("sub", Z80, XTAL_18MHz/6) /* verified on pcb */
MCFG_CPU_PROGRAM_MAP(cpu2_map)
MCFG_CPU_IO_MAP(cpu2_io_map)
MCFG_CPU_PERIODIC_INT_DRIVER(gsword_state, gsword_snd_interrupt, 4*60)
MCFG_CPU_PERIODIC_INT_DRIVER(gsword_state, sound_interrupt, 4*60)
MCFG_CPU_ADD("audiocpu", Z80, XTAL_18MHz/6) /* verified on pcb */
MCFG_CPU_PROGRAM_MAP(cpu3_map)
@ -646,7 +810,7 @@ static MACHINE_CONFIG_START( gsword, gsword_state )
MCFG_TAITO8741_ADD("taito8741")
MCFG_TAITO8741_MODES(TAITO8741_MASTER,TAITO8741_SLAVE,TAITO8741_PORT,TAITO8741_PORT)
MCFG_TAITO8741_CONNECT(1,0,0,0)
MCFG_TAITO8741_PORT_HANDLERS(IOPORT("DSW2"),IOPORT("DSW1"),READ8(gsword_state,gsword_8741_2_r),READ8(gsword_state,gsword_8741_3_r))
MCFG_TAITO8741_PORT_HANDLERS(IOPORT("DSW2"),IOPORT("DSW1"),READ8(gsword_state,i8741_2_r),READ8(gsword_state,i8741_3_r))
#if 1
/* to MCU timeout champbbj */
MCFG_QUANTUM_TIME(attotime::from_hz(6000))
@ -683,27 +847,32 @@ static MACHINE_CONFIG_START( gsword, gsword_state )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.60)
MACHINE_CONFIG_END
static MACHINE_CONFIG_START( josvolly, gsword_state )
static MACHINE_CONFIG_START( josvolly, josvolly_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", Z80, 18000000/6) /* ? */
MCFG_CPU_PROGRAM_MAP(cpu1_map)
MCFG_CPU_IO_MAP(josvolly_cpu1_io_map)
MCFG_CPU_PERIODIC_INT_DRIVER(gsword_state, irq0_line_hold, 2*60)
MCFG_CPU_PERIODIC_INT_DRIVER(josvolly_state, irq0_line_hold, 2*60)
MCFG_CPU_ADD("audiocpu", Z80, 12000000/4) /* ? */
MCFG_CPU_PROGRAM_MAP(josvolly_cpu2_map)
MCFG_CPU_IO_MAP(josvolly_cpu2_io_map)
MCFG_CPU_VBLANK_INT_DRIVER("screen", gsword_state, irq0_line_hold)
MCFG_CPU_VBLANK_INT_DRIVER("screen", josvolly_state, irq0_line_assert)
MCFG_DEVICE_ADD("josvolly_aa_007", I8255, 0)
MCFG_DEVICE_ADD("mcu1", I8741, 18000000/6) /* ? */
MCFG_CPU_IO_MAP(josvolly_mcu1_io_map)
MCFG_DEVICE_ADD("mcu2", I8741, 12000000/4) /* ? */
MCFG_CPU_IO_MAP(josvolly_mcu2_io_map)
MCFG_DEVICE_ADD("aa_007", I8255, 0)
MCFG_I8255_IN_PORTA_CB(IOPORT("IN1")) // 1PL
MCFG_I8255_IN_PORTB_CB(IOPORT("IN2")) // 2PL / ACK
MCFG_I8255_IN_PORTC_CB(IOPORT("IN0")) // START
MCFG_JOSVOLLY8741_ADD("josvolly_8741")
MCFG_JOSVOLLY8741_CONNECT(1,0,0,0)
MCFG_JOSVOLLY8741_PORT_HANDLERS(IOPORT("DSW1"),IOPORT("DSW2"),IOPORT("DSW1"),IOPORT("DSW2"))
// the second MCU polls the first MCU's outputs, so it needs tight sync
MCFG_QUANTUM_PERFECT_CPU("mcu2")
/* video hardware */
@ -712,13 +881,13 @@ static MACHINE_CONFIG_START( josvolly, gsword_state )
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)
MCFG_SCREEN_SIZE(32*8, 32*8)
MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 2*8, 30*8-1)
MCFG_SCREEN_UPDATE_DRIVER(gsword_state, screen_update_gsword)
MCFG_SCREEN_UPDATE_DRIVER(josvolly_state, screen_update_gsword)
MCFG_SCREEN_PALETTE("palette")
MCFG_GFXDECODE_ADD("gfxdecode", "palette", gsword)
MCFG_PALETTE_ADD("palette", 64*4+64*4)
MCFG_PALETTE_INDIRECT_ENTRIES(256)
MCFG_PALETTE_INIT_OWNER(gsword_state,josvolly)
MCFG_PALETTE_INIT_OWNER(josvolly_state, josvolly)
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
@ -727,7 +896,6 @@ static MACHINE_CONFIG_START( josvolly, gsword_state )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.30)
MCFG_SOUND_ADD("ay2", AY8910, 1500000)
MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(gsword_state, nmi_set_w)) /* portA write */
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.30)
#if 0
@ -851,11 +1019,12 @@ ROM_START( josvolly )
ROM_REGION( 0x04000, "user1", 0 ) /* music data and samples - not sure where it's mapped */
ROM_LOAD( "aa0-14.4j", 0x0000, 0x2000, CRC(436fe91f) SHA1(feb29501090c6db911e13ce6e9935ba004b0ce7e) )
// there are other undumped chips on this, not sure how many
// not hooked up yet
ROM_REGION( 0x400, "mcu", 0 )
ROM_REGION( 0x400, "mcu1", 0 )
ROM_LOAD( "aa003.bin", 0x0000, 0x400, CRC(68b399d9) SHA1(053482d12c2b714c23fc80ad0589a2afd258a5a6) )
ROM_REGION( 0x400, "mcu2", 0 )
ROM_LOAD( "aa008.bin", 0x0000, 0x400, CRC(68b399d9) SHA1(053482d12c2b714c23fc80ad0589a2afd258a5a6) BAD_DUMP )
ROM_REGION( 0x4000, "gfx1", 0 )
ROM_LOAD( "aa0-10.9n", 0x0000, 0x2000, CRC(207c4f42) SHA1(4cf2922d55cfc9e68cc07c3252ea3b5619b8aca5) ) /* tiles */
ROM_LOAD( "aa1-11.9p", 0x2000, 0x1000, CRC(c130464a) SHA1(9d23577b8aaaffeefff3d8f93668d1b2bd0ba3d9) )
@ -878,37 +1047,7 @@ ROM_START( josvolly )
ROM_LOAD( "005.3h", 0x0440, 0x0020, CRC(e8d6dec0) SHA1(d15cba9a4b24255d41046b15c2409391ab13ce95) ) /* address decoder? not used */
ROM_END
DRIVER_INIT_MEMBER(gsword_state,gsword)
{
#if 0
uint8_t *ROM2 = memregion("sub")->base();
ROM2[0x1da] = 0xc3; /* patch for rom self check */
ROM2[0x71e] = 0; /* patch for sound protection or time out function */
ROM2[0x71f] = 0;
#endif
#if 1
/* hack for sound protection or time out function */
m_subcpu->space(AS_PROGRAM).install_read_handler(0x4004, 0x4005, read8_delegate(FUNC(gsword_state::gsword_hack_r),this));
#endif
}
DRIVER_INIT_MEMBER(gsword_state,gsword2)
{
#if 0
uint8_t *ROM2 = memregion("sub")->base();
ROM2[0x1da] = 0xc3; /* patch for rom self check */
ROM2[0x726] = 0; /* patch for sound protection or time out function */
ROM2[0x727] = 0;
#endif
#if 1
/* hack for sound protection or time out function */
m_subcpu->space(AS_PROGRAM).install_read_handler(0x4004, 0x4005, read8_delegate(FUNC(gsword_state::gsword_hack_r),this));
#endif
}
GAME( 1983, josvolly, 0, josvolly, josvolly, driver_device, 0, ROT90, "Allumer / Taito Corporation", "Joshi Volleyball", MACHINE_UNEMULATED_PROTECTION | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1983, josvolly, 0, josvolly, josvolly, driver_device, 0, ROT90, "Allumer / Taito Corporation", "Joshi Volleyball", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1984, gsword, 0, gsword, gsword, gsword_state, gsword, ROT0, "Allumer / Taito Corporation", "Great Swordsman (World?)", MACHINE_SUPPORTS_SAVE )
GAME( 1984, gsword2, gsword, gsword, gsword, gsword_state, gsword2, ROT0, "Allumer / Taito Corporation", "Great Swordsman (Japan?)", MACHINE_SUPPORTS_SAVE )

View File

@ -5,35 +5,33 @@
#include "sound/ay8910.h"
#include "sound/msm5205.h"
class gsword_state : public driver_device
class gsword_state_base : public driver_device
{
public:
gsword_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
m_subcpu(*this, "sub"),
m_ay0(*this, "ay1"),
m_ay1(*this, "ay2"),
m_msm(*this, "msm"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
m_soundlatch(*this, "soundlatch"),
m_spritetile_ram(*this, "spritetile_ram"),
m_spritexy_ram(*this, "spritexy_ram"),
m_spriteattrib_ram(*this, "spriteattram"),
m_videoram(*this, "videoram"),
m_cpu2_ram(*this, "cpu2_ram") { }
gsword_state_base(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_audiocpu(*this, "audiocpu")
, m_subcpu(*this, "sub")
, m_ay0(*this, "ay1")
, m_ay1(*this, "ay2")
, m_gfxdecode(*this, "gfxdecode")
, m_palette(*this, "palette")
, m_spritetile_ram(*this, "spritetile_ram")
, m_spritexy_ram(*this, "spritexy_ram")
, m_spriteattrib_ram(*this, "spriteattram")
, m_videoram(*this, "videoram")
, m_cpu2_ram(*this, "cpu2_ram")
{
}
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
optional_device<cpu_device> m_subcpu;
required_device<ay8910_device> m_ay0;
required_device<ay8910_device> m_ay1;
optional_device<msm5205_device> m_msm;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
optional_device<generic_latch_8_device> m_soundlatch; // not josvolly
required_shared_ptr<uint8_t> m_spritetile_ram;
required_shared_ptr<uint8_t> m_spritexy_ram;
@ -41,11 +39,8 @@ public:
required_shared_ptr<uint8_t> m_videoram;
required_shared_ptr<uint8_t> m_cpu2_ram;
int m_coins; //currently initialized but not used
int m_fake8910_0;
int m_fake8910_1;
int m_nmi_enable;
int m_protect_hack;
int m_charbank;
int m_charpalbank;
int m_flipscreen;
@ -56,30 +51,93 @@ public:
DECLARE_WRITE8_MEMBER(charbank_w);
DECLARE_WRITE8_MEMBER(videoctrl_w);
DECLARE_WRITE8_MEMBER(scroll_w);
DECLARE_WRITE8_MEMBER(adpcm_soundcommand_w);
DECLARE_WRITE8_MEMBER(nmi_set_w);
DECLARE_WRITE8_MEMBER(ay8910_control_port_0_w);
DECLARE_WRITE8_MEMBER(ay8910_control_port_1_w);
DECLARE_READ8_MEMBER(fake_0_r);
DECLARE_READ8_MEMBER(fake_1_r);
// gsword specific
DECLARE_READ8_MEMBER(gsword_hack_r);
DECLARE_WRITE8_MEMBER(gsword_adpcm_data_w);
DECLARE_READ8_MEMBER(gsword_8741_2_r);
DECLARE_READ8_MEMBER(gsword_8741_3_r);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
DECLARE_DRIVER_INIT(gsword);
DECLARE_DRIVER_INIT(gsword2);
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;
DECLARE_PALETTE_INIT(gsword);
DECLARE_PALETTE_INIT(josvolly);
uint32_t screen_update_gsword(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(gsword_snd_interrupt);
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
};
class gsword_state : public gsword_state_base
{
public:
gsword_state(const machine_config &mconfig, device_type type, const char *tag)
: gsword_state_base(mconfig, type, tag)
, m_soundlatch(*this, "soundlatch")
, m_msm(*this, "msm")
, m_protect_hack(false)
, m_nmi_enable(false)
{
}
DECLARE_READ8_MEMBER(hack_r);
DECLARE_WRITE8_MEMBER(nmi_set_w);
DECLARE_WRITE8_MEMBER(sound_command_w);
DECLARE_WRITE8_MEMBER(adpcm_data_w);
DECLARE_READ8_MEMBER(i8741_2_r);
DECLARE_READ8_MEMBER(i8741_3_r);
INTERRUPT_GEN_MEMBER(sound_interrupt);
DECLARE_DRIVER_INIT(gsword);
DECLARE_DRIVER_INIT(gsword2);
DECLARE_PALETTE_INIT(gsword);
virtual void machine_start() override;
virtual void machine_reset() override;
private:
required_device<generic_latch_8_device> m_soundlatch;
required_device<msm5205_device> m_msm;
bool m_protect_hack;
bool m_nmi_enable;
};
class josvolly_state : public gsword_state_base
{
public:
josvolly_state(const machine_config &mconfig, device_type type, const char *tag)
: gsword_state_base(mconfig, type, tag)
, m_cpu2_nmi_enable(false)
, m_mcu1_p1(0xffU)
, m_mcu1_p2(0xffU)
, m_mcu2_p1(0xffU)
{
}
DECLARE_READ8_MEMBER(mcu1_p1_r);
DECLARE_READ8_MEMBER(mcu1_p2_r);
DECLARE_READ8_MEMBER(mcu2_p1_r);
DECLARE_READ8_MEMBER(mcu2_p2_r);
DECLARE_READ8_MEMBER(mcu2_test_r);
DECLARE_WRITE8_MEMBER(cpu2_nmi_enable_w);
DECLARE_WRITE8_MEMBER(cpu2_irq_clear_w);
DECLARE_WRITE8_MEMBER(mcu1_p1_w);
DECLARE_WRITE8_MEMBER(mcu1_p2_w);
DECLARE_WRITE8_MEMBER(mcu2_p1_w);
DECLARE_WRITE8_MEMBER(mcu2_p2_w);
DECLARE_PALETTE_INIT(josvolly);
virtual void machine_start() override;
virtual void machine_reset() override;
private:
bool m_cpu2_nmi_enable;
u8 m_mcu1_p1;
u8 m_mcu1_p2;
u8 m_mcu2_p1;
};

View File

@ -11,91 +11,13 @@
#include "includes/gsword.h"
PALETTE_INIT_MEMBER(gsword_state,josvolly)
{
const uint8_t *color_prom = memregion("proms")->base();
int i;
/* create a lookup table for the palette */
for (i = 0; i < 0x100; i++)
{
int r = pal4bit(color_prom[i + 0x000]);
int g = pal4bit(color_prom[i + 0x100]);
int b = pal4bit(color_prom[i + 0x200]);
palette.set_indirect_color(i, rgb_t(r, g, b));
}
/* color_prom now points to the beginning of the lookup table */
color_prom += 0x300;
/* characters */
for (i = 0; i < 0x100; i++)
palette.set_pen_indirect(i, i);
/* sprites */
for (i = 0x100; i < 0x200; i++)
{
uint8_t ctabentry = (BITSWAP8(color_prom[i - 0x100],7,6,5,4,0,1,2,3) & 0x0f) | 0x80;
palette.set_pen_indirect(i, ctabentry);
}
}
PALETTE_INIT_MEMBER(gsword_state,gsword)
{
const uint8_t *color_prom = memregion("proms")->base();
int i;
/* create a lookup table for the palette */
for (i = 0; i < 0x100; i++)
{
int bit0, bit1, bit2;
int r, g, b;
/* red component */
bit0 = (color_prom[i + 0x100] >> 0) & 1;
bit1 = (color_prom[i + 0x100] >> 1) & 1;
bit2 = (color_prom[i + 0x100] >> 2) & 1;
r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
/* green component */
bit0 = (color_prom[i + 0x100] >> 3) & 1;
bit1 = (color_prom[i + 0x000] >> 0) & 1;
bit2 = (color_prom[i + 0x000] >> 1) & 1;
g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
/* blue component */
bit0 = 0;
bit1 = (color_prom[i + 0x000] >> 2) & 1;
bit2 = (color_prom[i + 0x000] >> 3) & 1;
b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
palette.set_indirect_color(i, rgb_t(r, g, b));
}
/* color_prom now points to the beginning of the lookup table */
color_prom += 0x200;
/* characters */
for (i = 0; i < 0x100; i++)
palette.set_pen_indirect(i, i);
/* sprites */
for (i = 0x100; i < 0x200; i++)
{
uint8_t ctabentry = (BITSWAP8(color_prom[i - 0x100],7,6,5,4,0,1,2,3) & 0x0f) | 0x80;
palette.set_pen_indirect(i, ctabentry);
}
}
WRITE8_MEMBER(gsword_state::videoram_w)
WRITE8_MEMBER(gsword_state_base::videoram_w)
{
m_videoram[offset] = data;
m_bg_tilemap->mark_tile_dirty(offset);
}
WRITE8_MEMBER(gsword_state::charbank_w)
WRITE8_MEMBER(gsword_state_base::charbank_w)
{
if (m_charbank != data)
{
@ -104,7 +26,7 @@ WRITE8_MEMBER(gsword_state::charbank_w)
}
}
WRITE8_MEMBER(gsword_state::videoctrl_w)
WRITE8_MEMBER(gsword_state_base::videoctrl_w)
{
if (data & 0x8f)
{
@ -132,12 +54,12 @@ WRITE8_MEMBER(gsword_state::videoctrl_w)
/* other bits unused */
}
WRITE8_MEMBER(gsword_state::scroll_w)
WRITE8_MEMBER(gsword_state_base::scroll_w)
{
m_bg_tilemap->set_scrolly(0, data);
}
TILE_GET_INFO_MEMBER(gsword_state::get_bg_tile_info)
TILE_GET_INFO_MEMBER(gsword_state_base::get_bg_tile_info)
{
int code = m_videoram[tile_index] + ((m_charbank & 0x03) << 8);
int color = ((code & 0x3c0) >> 6) + 16 * m_charpalbank;
@ -146,9 +68,9 @@ TILE_GET_INFO_MEMBER(gsword_state::get_bg_tile_info)
SET_TILE_INFO_MEMBER(0, code, color, flags);
}
void gsword_state::video_start()
void gsword_state_base::video_start()
{
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(gsword_state::get_bg_tile_info),this), TILEMAP_SCAN_ROWS,
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(gsword_state_base::get_bg_tile_info),this), TILEMAP_SCAN_ROWS,
8, 8, 32, 64);
save_item(NAME(m_charbank));
@ -156,7 +78,7 @@ void gsword_state::video_start()
save_item(NAME(m_flipscreen));
}
void gsword_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
void gsword_state_base::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
for (int offs = 0; offs < m_spritexy_ram.bytes() - 1; offs+=2)
{
@ -197,9 +119,86 @@ void gsword_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
}
}
uint32_t gsword_state::screen_update_gsword(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
uint32_t gsword_state_base::screen_update_gsword(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
draw_sprites(bitmap, cliprect);
return 0;
}
PALETTE_INIT_MEMBER(gsword_state, gsword)
{
const uint8_t *color_prom = memregion("proms")->base();
/* create a lookup table for the palette */
for (unsigned i = 0; i < 0x100; i++)
{
int bit0, bit1, bit2;
int r, g, b;
/* red component */
bit0 = BIT(color_prom[i + 0x100], 0);
bit1 = BIT(color_prom[i + 0x100], 1);
bit2 = BIT(color_prom[i + 0x100], 2);
r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
/* green component */
bit0 = BIT(color_prom[i + 0x100], 3);
bit1 = BIT(color_prom[i + 0x000], 0);
bit2 = BIT(color_prom[i + 0x000], 1);
g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
/* blue component */
bit0 = 0;
bit1 = BIT(color_prom[i + 0x000], 2);
bit2 = BIT(color_prom[i + 0x000], 3);
b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
palette.set_indirect_color(i, rgb_t(r, g, b));
}
/* color_prom now points to the beginning of the lookup table */
color_prom += 0x200;
/* characters */
for (unsigned i = 0; i < 0x100; i++)
palette.set_pen_indirect(i, i);
/* sprites */
for (unsigned i = 0x100; i < 0x200; i++)
{
uint8_t ctabentry = (BITSWAP8(color_prom[i - 0x100],7,6,5,4,0,1,2,3) & 0x0f) | 0x80;
palette.set_pen_indirect(i, ctabentry);
}
}
PALETTE_INIT_MEMBER(josvolly_state, josvolly)
{
u8 const *color_prom = memregion("proms")->base();
// create a lookup table for the palette
for (unsigned i = 0; i < 0x100; i++)
{
u8 const r = pal4bit(color_prom[i + 0x000]);
u8 const g = pal4bit(color_prom[i + 0x100]);
u8 const b = pal4bit(color_prom[i + 0x200]);
palette.set_indirect_color(i, rgb_t(r, g, b));
// characters */
palette.set_pen_indirect(i, i);
}
/* color_prom now points to the beginning of the lookup table */
color_prom += 0x300;
/* sprites */
for (unsigned i = 0; i < 0x100; i++)
{
uint8_t ctabentry = (BITSWAP8(color_prom[i],7,6,5,4,0,1,2,3) & 0x0f) | 0x80;
palette.set_pen_indirect(i + 0x100, ctabentry);
}
}