(nw) get rid of some MACHINE_(START|RESET)_MEMBER, get rid of static state in atarisy4

This commit is contained in:
Vas Crabb 2018-05-16 22:46:01 +10:00
parent 166638ce80
commit c54c83ca94
3 changed files with 422 additions and 361 deletions

View File

@ -113,11 +113,9 @@ public:
required_device<ram_device> m_ram; required_device<ram_device> m_ram;
void init_at(); void init_at();
void init_atpci(); void init_atpci();
void init_megapcpla();
DECLARE_READ16_MEMBER(ps1_unk_r); DECLARE_READ16_MEMBER(ps1_unk_r);
DECLARE_WRITE16_MEMBER(ps1_unk_w); DECLARE_WRITE16_MEMBER(ps1_unk_w);
DECLARE_READ8_MEMBER(ps1_portb_r); DECLARE_READ8_MEMBER(ps1_portb_r);
DECLARE_MACHINE_START(vrom_fix);
void init_at_common(int xmsbase); void init_at_common(int xmsbase);
uint16_t m_ps1_reg[2]; uint16_t m_ps1_reg[2];
@ -127,7 +125,6 @@ public:
void ct386sx(machine_config &config); void ct386sx(machine_config &config);
void xb42639(machine_config &config); void xb42639(machine_config &config);
void at486l(machine_config &config); void at486l(machine_config &config);
void megapcpla(machine_config &config);
void comportii(machine_config &config); void comportii(machine_config &config);
void comportiii(machine_config &config); void comportiii(machine_config &config);
void ibm5162(machine_config &config); void ibm5162(machine_config &config);
@ -140,7 +137,6 @@ public:
void at386sx(machine_config &config); void at386sx(machine_config &config);
void pc40iii(machine_config &config); void pc40iii(machine_config &config);
void atvga(machine_config &config); void atvga(machine_config &config);
void ibmps1(machine_config &config);
void at386(machine_config &config); void at386(machine_config &config);
void ews286(machine_config &config); void ews286(machine_config &config);
@ -158,11 +154,25 @@ public:
void ps1_16_io(address_map &map); void ps1_16_io(address_map &map);
}; };
class at_vrom_fix_state : public at_state
{
public:
using at_state::at_state;
void init_megapcpla();
void ibmps1(machine_config &config);
void megapcpla(machine_config &config);
protected:
virtual void machine_start() override;
};
class megapc_state : public driver_device class megapc_state : public driver_device
{ {
public: public:
megapc_state(const machine_config &mconfig, device_type type, const char *tag) megapc_state(const machine_config &mconfig, device_type type, const char *tag) :
: driver_device(mconfig, type, tag), driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"), m_maincpu(*this, "maincpu"),
m_wd7600(*this, "wd7600"), m_wd7600(*this, "wd7600"),
m_isabus(*this, "isabus"), m_isabus(*this, "isabus"),
@ -309,7 +319,7 @@ void megapc_state::init_megapcpl()
ROM[0x1fea0] = 0x20; // to correct checksum ROM[0x1fea0] = 0x20; // to correct checksum
} }
void at_state::init_megapcpla() void at_vrom_fix_state::init_megapcpla()
{ {
uint8_t* ROM = memregion("bios")->base(); uint8_t* ROM = memregion("bios")->base();
@ -397,8 +407,10 @@ void at_state::init_atpci()
init_at_common(0x100000); init_at_common(0x100000);
} }
MACHINE_START_MEMBER(at_state,vrom_fix) void at_vrom_fix_state::machine_start()
{ {
at_state::machine_start();
address_space& space = m_maincpu->space(AS_PROGRAM); address_space& space = m_maincpu->space(AS_PROGRAM);
space.install_read_bank(0xc0000, 0xcffff, "vrom_bank"); space.install_read_bank(0xc0000, 0xcffff, "vrom_bank");
membank("vrom_bank")->set_base(machine().root_device().memregion("bios")->base()); membank("vrom_bank")->set_base(machine().root_device().memregion("bios")->base());
@ -480,9 +492,8 @@ MACHINE_CONFIG_START(at_state::ibm5162)
MCFG_DEVICE_SLOT_INTERFACE(pc_isa16_cards, "cga", false) MCFG_DEVICE_SLOT_INTERFACE(pc_isa16_cards, "cga", false)
MACHINE_CONFIG_END MACHINE_CONFIG_END
MACHINE_CONFIG_START(at_state::ibmps1) MACHINE_CONFIG_START(at_vrom_fix_state::ibmps1)
ibm5170(config); ibm5170(config);
MCFG_MACHINE_START_OVERRIDE(at_state, vrom_fix)
MCFG_DEVICE_MODIFY("maincpu") MCFG_DEVICE_MODIFY("maincpu")
MCFG_DEVICE_CLOCK(XTAL(10'000'000)) MCFG_DEVICE_CLOCK(XTAL(10'000'000))
MCFG_DEVICE_PROGRAM_MAP(at16l_map) MCFG_DEVICE_PROGRAM_MAP(at16l_map)
@ -699,12 +710,11 @@ MACHINE_CONFIG_START(megapc_state::megapcpl)
MCFG_DEVICE_IRQ_ACKNOWLEDGE_DEVICE("wd7600", wd7600_device, intack_cb) MCFG_DEVICE_IRQ_ACKNOWLEDGE_DEVICE("wd7600", wd7600_device, intack_cb)
MACHINE_CONFIG_END MACHINE_CONFIG_END
MACHINE_CONFIG_START(at_state::megapcpla) MACHINE_CONFIG_START(at_vrom_fix_state::megapcpla)
MCFG_DEVICE_ADD("maincpu", I486, 66000000 / 2) // 486SLC MCFG_DEVICE_ADD("maincpu", I486, 66000000 / 2) // 486SLC
MCFG_DEVICE_PROGRAM_MAP(at32l_map) MCFG_DEVICE_PROGRAM_MAP(at32l_map)
MCFG_DEVICE_IO_MAP(at32_io) MCFG_DEVICE_IO_MAP(at32_io)
MCFG_DEVICE_IRQ_ACKNOWLEDGE_DEVICE("mb:pic8259_master", pic8259_device, inta_cb) MCFG_DEVICE_IRQ_ACKNOWLEDGE_DEVICE("mb:pic8259_master", pic8259_device, inta_cb)
MCFG_MACHINE_START_OVERRIDE(at_state, vrom_fix)
MCFG_DEVICE_ADD("mb", AT_MB, 0) MCFG_DEVICE_ADD("mb", AT_MB, 0)
MCFG_QUANTUM_TIME(attotime::from_hz(60)) MCFG_QUANTUM_TIME(attotime::from_hz(60))
@ -1426,7 +1436,7 @@ ROM_END
COMP( 1984, ibm5170, 0, ibm5150, ibm5170, 0, at_state, init_at, "International Business Machines", "IBM PC/AT 5170", MACHINE_NOT_WORKING ) COMP( 1984, ibm5170, 0, ibm5150, ibm5170, 0, at_state, init_at, "International Business Machines", "IBM PC/AT 5170", MACHINE_NOT_WORKING )
COMP( 1985, ibm5170a, ibm5170, 0, ibm5170a, 0, at_state, init_at, "International Business Machines", "IBM PC/AT 5170 8MHz", MACHINE_NOT_WORKING ) COMP( 1985, ibm5170a, ibm5170, 0, ibm5170a, 0, at_state, init_at, "International Business Machines", "IBM PC/AT 5170 8MHz", MACHINE_NOT_WORKING )
COMP( 1985, ibm5162, ibm5170, 0, ibm5162, 0, at_state, init_at, "International Business Machines", "IBM PC/XT-286 5162", MACHINE_NOT_WORKING ) COMP( 1985, ibm5162, ibm5170, 0, ibm5162, 0, at_state, init_at, "International Business Machines", "IBM PC/XT-286 5162", MACHINE_NOT_WORKING )
COMP( 1989, ibmps1es, ibm5170, 0, ibmps1, 0, at_state, init_at, "International Business Machines", "IBM PS/1 (Spanish)", MACHINE_NOT_WORKING ) COMP( 1989, ibmps1es, ibm5170, 0, ibmps1, 0, at_vrom_fix_state, init_at, "International Business Machines", "IBM PS/1 (Spanish)", MACHINE_NOT_WORKING )
COMP( 1987, at, ibm5170, 0, ibm5162, 0, at_state, init_at, "<generic>", "PC/AT (CGA, MF2 Keyboard)", MACHINE_NOT_WORKING ) COMP( 1987, at, ibm5170, 0, ibm5162, 0, at_state, init_at, "<generic>", "PC/AT (CGA, MF2 Keyboard)", MACHINE_NOT_WORKING )
COMP( 1987, atvga, ibm5170, 0, atvga, 0, at_state, init_at, "<generic>", "PC/AT (VGA, MF2 Keyboard)" , MACHINE_NOT_WORKING ) COMP( 1987, atvga, ibm5170, 0, atvga, 0, at_state, init_at, "<generic>", "PC/AT (VGA, MF2 Keyboard)" , MACHINE_NOT_WORKING )
COMP( 1988, at386, ibm5170, 0, at386, 0, at_state, init_at, "<generic>", "PC/AT 386 (VGA, MF2 Keyboard)", MACHINE_NOT_WORKING ) COMP( 1988, at386, ibm5170, 0, at386, 0, at_state, init_at, "<generic>", "PC/AT 386 (VGA, MF2 Keyboard)", MACHINE_NOT_WORKING )
@ -1438,7 +1448,7 @@ COMP( 1989, ec1842, ibm5150, 0, ec1842, 0, at_state, init_at
COMP( 1993, ec1849, ibm5170, 0, ec1842, 0, at_state, init_at, "<unknown>", "EC-1849", MACHINE_NOT_WORKING ) COMP( 1993, ec1849, ibm5170, 0, ec1842, 0, at_state, init_at, "<unknown>", "EC-1849", MACHINE_NOT_WORKING )
COMP( 1993, megapc, 0, 0, megapc, 0, megapc_state, init_megapc, "Amstrad plc", "MegaPC", MACHINE_NOT_WORKING ) COMP( 1993, megapc, 0, 0, megapc, 0, megapc_state, init_megapc, "Amstrad plc", "MegaPC", MACHINE_NOT_WORKING )
COMP( 199?, megapcpl, megapc, 0, megapcpl, 0, megapc_state, init_megapcpl, "Amstrad plc", "MegaPC Plus", MACHINE_NOT_WORKING ) COMP( 199?, megapcpl, megapc, 0, megapcpl, 0, megapc_state, init_megapcpl, "Amstrad plc", "MegaPC Plus", MACHINE_NOT_WORKING )
COMP( 199?, megapcpla, megapc, 0, megapcpla, 0, at_state, init_megapcpla, "Amstrad plc", "MegaPC Plus (WINBUS chipset)", MACHINE_NOT_WORKING ) COMP( 199?, megapcpla, megapc, 0, megapcpla, 0, at_vrom_fix_state, init_megapcpla, "Amstrad plc", "MegaPC Plus (WINBUS chipset)", MACHINE_NOT_WORKING )
COMP( 1989, pc2386, ibm5170, 0, at386l, 0, at_state, init_at, "Amstrad plc", "Amstrad PC2386", MACHINE_NOT_WORKING ) COMP( 1989, pc2386, ibm5170, 0, at386l, 0, at_state, init_at, "Amstrad plc", "Amstrad PC2386", MACHINE_NOT_WORKING )
COMP( 1991, aprfte, ibm5170, 0, at486, 0, at_state, init_at, "Apricot", "Apricot FT//ex 486 (J3 Motherboard)", MACHINE_NOT_WORKING ) COMP( 1991, aprfte, ibm5170, 0, at486, 0, at_state, init_at, "Apricot", "Apricot FT//ex 486 (J3 Motherboard)", MACHINE_NOT_WORKING )
COMP( 1991, ftsserv, ibm5170, 0, at486, 0, at_state, init_at, "Apricot", "Apricot FTs (Scorpion)", MACHINE_NOT_WORKING ) COMP( 1991, ftsserv, ibm5170, 0, at486, 0, at_state, init_at, "Apricot", "Apricot FTs (Scorpion)", MACHINE_NOT_WORKING )

View File

@ -23,61 +23,97 @@
#include "screen.h" #include "screen.h"
struct atarisy4_polydata
{
uint16_t color;
uint16_t *screen_ram;
};
class atarisy4_state;
class atarisy4_renderer : public poly_manager<float, atarisy4_polydata, 2, 8192>
{
public:
atarisy4_renderer(atarisy4_state &state, screen_device &screen);
~atarisy4_renderer() {}
void draw_scanline(int32_t scanline, const extent_t &extent, const atarisy4_polydata &extradata, int threadid);
void draw_polygon(uint16_t color);
atarisy4_state &m_state;
};
class atarisy4_state : public driver_device class atarisy4_state : public driver_device
{ {
public: public:
atarisy4_state(const machine_config &mconfig, device_type type, const char *tag) atarisy4_state(const machine_config &mconfig, device_type type, const char *tag) :
: driver_device(mconfig, type, tag), driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"), m_maincpu(*this, "maincpu"),
m_dsp0(*this, "dsp0"), m_dsp0(*this, "dsp0"),
m_dsp1(*this, "dsp1"), m_dsp0_bank1(*this, "dsp0_bank1"),
m_palette(*this, "palette"), m_palette(*this, "palette"),
m_screen(*this, "screen"), m_screen(*this, "screen"),
m_m68k_ram(*this, "m68k_ram"), m_m68k_ram(*this, "m68k_ram"),
m_screen_ram(*this, "screen_ram"), m_screen_ram(*this, "screen_ram"),
m_dsp0_bank1(*this, "dsp0_bank1"), m_stick(*this, "STICK%c", 'X')
m_dsp1_bank1(*this, "dsp1_bank1") { } {
}
required_device<cpu_device> m_maincpu; void init_laststar();
required_device<cpu_device> m_dsp0;
optional_device<cpu_device> m_dsp1;
required_device<palette_device> m_palette;
required_device<screen_device> m_screen;
required_shared_ptr<uint16_t> m_m68k_ram; void atarisy4(machine_config &config);
required_shared_ptr<uint16_t> m_screen_ram;
required_memory_bank m_dsp0_bank1; protected:
optional_memory_bank m_dsp1_bank1; struct atarisy4_polydata
{
uint16_t color;
uint16_t *screen_ram;
};
std::unique_ptr<atarisy4_renderer> m_renderer; class atarisy4_renderer : public poly_manager<float, atarisy4_polydata, 2, 8192>
{
public:
atarisy4_renderer(atarisy4_state &state, screen_device &screen);
~atarisy4_renderer() {}
uint8_t m_r_color_table[256]; void draw_scanline(int32_t scanline, const extent_t &extent, const atarisy4_polydata &extradata, int threadid);
uint8_t m_g_color_table[256]; void draw_polygon(uint16_t color);
uint8_t m_b_color_table[256];
uint16_t m_dsp_bank[2]; protected:
uint8_t m_csr[2]; atarisy4_state &m_state;
std::unique_ptr<uint16_t[]> m_shared_ram[2]; };
struct gpu
{
uint32_t xy_to_screen_addr(uint32_t x, uint32_t y) const;
/* Memory-mapped registers */
uint16_t gr[8]; /* Command parameters */
uint16_t bcrw; /* Screen buffer W control */
uint16_t bcrx; /* Screen buffer X control */
uint16_t bcry; /* Screen buffer Y control */
uint16_t bcrz; /* Screen buffer Z control */
uint16_t psrw;
uint16_t psrx;
uint16_t psry;
uint16_t psrz;
uint16_t dpr;
uint16_t ctr;
uint16_t lfr;
uint16_t ifr;
uint16_t ecr; /* Execute command register */
uint16_t far;
uint16_t mcr; /* Interrupt control */
uint16_t qlr;
uint16_t qar;
uint16_t dhr; /* Scanline counter */
uint16_t dlr;
/* Others */
uint16_t idr;
uint16_t icd;
uint8_t transpose;
uint8_t vblank_wait;
/* Polygon points */
struct
{
int16_t x;
int16_t y;
} points[16];
uint16_t pt_idx;
bool poly_open;
uint16_t clip_min_x;
uint16_t clip_max_x;
uint16_t clip_min_y;
uint16_t clip_max_y;
};
DECLARE_WRITE16_MEMBER(gpu_w); DECLARE_WRITE16_MEMBER(gpu_w);
DECLARE_READ16_MEMBER(gpu_r); DECLARE_READ16_MEMBER(gpu_r);
@ -89,90 +125,85 @@ public:
DECLARE_WRITE16_MEMBER(dsp0_control_w); DECLARE_WRITE16_MEMBER(dsp0_control_w);
DECLARE_READ_LINE_MEMBER(dsp0_bio_r); DECLARE_READ_LINE_MEMBER(dsp0_bio_r);
DECLARE_WRITE16_MEMBER(dsp0_bank_w); DECLARE_WRITE16_MEMBER(dsp0_bank_w);
DECLARE_READ16_MEMBER(dsp1_status_r);
DECLARE_WRITE16_MEMBER(dsp1_control_w);
DECLARE_READ_LINE_MEMBER(dsp1_bio_r);
DECLARE_WRITE16_MEMBER(dsp1_bank_w);
DECLARE_READ16_MEMBER(analog_r); DECLARE_READ16_MEMBER(analog_r);
void init_airrace();
void init_laststar();
virtual void machine_reset() override; virtual void machine_reset() override;
virtual void video_start() override; virtual void video_start() override;
virtual void video_reset() override; virtual void video_reset() override;
DECLARE_MACHINE_RESET(airrace);
uint32_t screen_update_atarisy4(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); uint32_t screen_update_atarisy4(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(vblank_int); INTERRUPT_GEN_MEMBER(vblank_int);
void image_mem_to_screen( bool clip); void image_mem_to_screen( bool clip);
void execute_gpu_command(); void execute_gpu_command();
inline uint8_t hex_to_ascii(uint8_t in); inline uint8_t hex_to_ascii(uint8_t in);
void load_ldafile(address_space &space, const uint8_t *file); void load_ldafile(address_space &space, const uint8_t *file);
void load_hexfile(address_space &space, const uint8_t *file); void load_hexfile(address_space &space, const uint8_t *file);
void airrace(machine_config &config);
void atarisy4(machine_config &config);
void dsp0_io_map(address_map &map);
void dsp0_map(address_map &map);
void dsp1_io_map(address_map &map);
void dsp1_map(address_map &map);
void main_map(address_map &map); void main_map(address_map &map);
void dsp0_map(address_map &map);
void dsp0_io_map(address_map &map);
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_dsp0;
required_memory_bank m_dsp0_bank1;
uint16_t m_dsp_bank[2];
uint8_t m_csr[2];
std::unique_ptr<uint16_t[]> m_shared_ram[2];
private:
required_device<palette_device> m_palette;
required_device<screen_device> m_screen;
required_shared_ptr<uint16_t> m_m68k_ram;
required_shared_ptr<uint16_t> m_screen_ram;
required_ioport_array<2> m_stick;
std::unique_ptr<atarisy4_renderer> m_renderer;
gpu m_gpu;
uint8_t m_r_color_table[256];
uint8_t m_g_color_table[256];
uint8_t m_b_color_table[256];
}; };
class airrace_state : public atarisy4_state
/*************************************
*
* State
*
*************************************/
struct gpu_
{ {
/* Memory-mapped registers */ public:
uint16_t gr[8]; /* Command parameters */ airrace_state(const machine_config &mconfig, device_type type, const char *tag) :
atarisy4_state(mconfig, type, tag),
uint16_t bcrw; /* Screen buffer W control */ m_dsp1(*this, "dsp1"),
uint16_t bcrx; /* Screen buffer X control */ m_dsp1_bank1(*this, "dsp1_bank1")
uint16_t bcry; /* Screen buffer Y control */
uint16_t bcrz; /* Screen buffer Z control */
uint16_t psrw;
uint16_t psrx;
uint16_t psry;
uint16_t psrz;
uint16_t dpr;
uint16_t ctr;
uint16_t lfr;
uint16_t ifr;
uint16_t ecr; /* Execute command register */
uint16_t far;
uint16_t mcr; /* Interrupt control */
uint16_t qlr;
uint16_t qar;
uint16_t dhr; /* Scanline counter */
uint16_t dlr;
/* Others */
uint16_t idr;
uint16_t icd;
uint8_t transpose;
uint8_t vblank_wait;
/* Polygon points */
struct
{ {
int16_t x; }
int16_t y;
} points[16];
uint16_t pt_idx; void init_airrace();
bool poly_open;
void airrace(machine_config &config);
protected:
DECLARE_READ16_MEMBER(dsp1_status_r);
DECLARE_WRITE16_MEMBER(dsp1_control_w);
DECLARE_READ_LINE_MEMBER(dsp1_bio_r);
DECLARE_WRITE16_MEMBER(dsp1_bank_w);
virtual void machine_reset() override;
void airrace_map(address_map &map);
void dsp1_map(address_map &map);
void dsp1_io_map(address_map &map);
private:
required_device<cpu_device> m_dsp1;
required_memory_bank m_dsp1_bank1;
};
uint16_t clip_min_x;
uint16_t clip_max_x;
uint16_t clip_min_y;
uint16_t clip_max_y;
} gpu;
/************************************* /*************************************
@ -181,9 +212,9 @@ struct gpu_
* *
*************************************/ *************************************/
atarisy4_renderer::atarisy4_renderer(atarisy4_state &state, screen_device &screen) atarisy4_state::atarisy4_renderer::atarisy4_renderer(atarisy4_state &state, screen_device &screen) :
: poly_manager<float, atarisy4_polydata, 2, 8192>(screen, FLAG_NO_WORK_QUEUE), poly_manager<float, atarisy4_polydata, 2, 8192>(screen, FLAG_NO_WORK_QUEUE),
m_state(state) m_state(state)
{ {
} }
@ -194,7 +225,7 @@ void atarisy4_state::video_start()
void atarisy4_state::video_reset() void atarisy4_state::video_reset()
{ {
gpu.vblank_wait = 0; m_gpu.vblank_wait = 0;
} }
uint32_t atarisy4_state::screen_update_atarisy4(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) uint32_t atarisy4_state::screen_update_atarisy4(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
@ -202,16 +233,16 @@ uint32_t atarisy4_state::screen_update_atarisy4(screen_device &screen, bitmap_rg
int y; int y;
uint32_t offset = 0; uint32_t offset = 0;
if (gpu.bcrw & 0x80) if (m_gpu.bcrw & 0x80)
{ {
offset = 0; offset = 0;
} }
else if (gpu.bcrx & 0x80) else if (m_gpu.bcrx & 0x80)
{ {
offset = 0x10 << 5; offset = 0x10 << 5;
} }
//uint32_t offset = gpu.dpr << 5; //uint32_t offset = m_gpu.dpr << 5;
for (y = cliprect.min_y; y <= cliprect.max_y; ++y) for (y = cliprect.min_y; y <= cliprect.max_y; ++y)
{ {
@ -230,16 +261,16 @@ uint32_t atarisy4_state::screen_update_atarisy4(screen_device &screen, bitmap_rg
return 0; return 0;
} }
static inline uint32_t xy_to_screen_addr(uint32_t x, uint32_t y) inline uint32_t atarisy4_state::gpu::xy_to_screen_addr(uint32_t x, uint32_t y) const
{ {
// uint32_t offset = ((gpu.mcr >> 4) & 3) << 9; // uint32_t offset = ((mcr >> 4) & 3) << 9;
uint32_t offset = 0; uint32_t offset = 0;
if (~gpu.bcrw & 0x80) if (~bcrw & 0x80)
{ {
offset = 0; offset = 0;
} }
else if (~gpu.bcrx & 0x80) else if (~bcrx & 0x80)
{ {
offset = 0x10 << 5; offset = 0x10 << 5;
} }
@ -249,8 +280,8 @@ static inline uint32_t xy_to_screen_addr(uint32_t x, uint32_t y)
void atarisy4_state::image_mem_to_screen(bool clip) void atarisy4_state::image_mem_to_screen(bool clip)
{ {
int16_t y = gpu.gr[1] - 0x200; int16_t y = m_gpu.gr[1] - 0x200;
uint16_t h = gpu.gr[3]; uint16_t h = m_gpu.gr[3];
if (h & 0x8000) if (h & 0x8000)
h = -h; h = -h;
@ -258,8 +289,8 @@ void atarisy4_state::image_mem_to_screen(bool clip)
/* Not 100% sure of this */ /* Not 100% sure of this */
while (h--) while (h--)
{ {
uint16_t w = gpu.gr[2]; uint16_t w = m_gpu.gr[2];
int16_t x = gpu.gr[0] - 0x400; int16_t x = m_gpu.gr[0] - 0x400;
if (w & 0x8000) if (w & 0x8000)
w = -w; w = -w;
@ -270,14 +301,14 @@ void atarisy4_state::image_mem_to_screen(bool clip)
{ {
if (x >= 0 && x <= 511) if (x >= 0 && x <= 511)
{ {
uint16_t pix = m_screen_ram[xy_to_screen_addr(x,y) >> 1]; uint16_t pix = m_screen_ram[m_gpu.xy_to_screen_addr(x,y) >> 1];
if (x & 1) if (x & 1)
pix = (pix & (0x00ff)) | gpu.idr << 8; pix = (pix & (0x00ff)) | m_gpu.idr << 8;
else else
pix = (pix & (0xff00)) | gpu.idr; pix = (pix & (0xff00)) | m_gpu.idr;
m_screen_ram[xy_to_screen_addr(x,y) >> 1] = pix; m_screen_ram[m_gpu.xy_to_screen_addr(x,y) >> 1] = pix;
} }
++x; ++x;
} }
@ -286,14 +317,14 @@ void atarisy4_state::image_mem_to_screen(bool clip)
} }
} }
void atarisy4_renderer::draw_scanline(int32_t scanline, const extent_t &extent, const atarisy4_polydata &extradata, int threadid) void atarisy4_state::atarisy4_renderer::draw_scanline(int32_t scanline, const extent_t &extent, const atarisy4_polydata &extradata, int threadid)
{ {
uint16_t color = extradata.color; uint16_t color = extradata.color;
int x; int x;
for (x = extent.startx; x < extent.stopx; ++x) for (x = extent.startx; x < extent.stopx; ++x)
{ {
uint32_t addr = xy_to_screen_addr(x, scanline); uint32_t addr = m_state.m_gpu.xy_to_screen_addr(x, scanline);
uint16_t pix = extradata.screen_ram[addr >> 1]; uint16_t pix = extradata.screen_ram[addr >> 1];
if (x & 1) if (x & 1)
@ -305,7 +336,7 @@ void atarisy4_renderer::draw_scanline(int32_t scanline, const extent_t &extent,
} }
} }
void atarisy4_renderer::draw_polygon(uint16_t color) void atarisy4_state::atarisy4_renderer::draw_polygon(uint16_t color)
{ {
rectangle clip; rectangle clip;
vertex_t v1, v2, v3; vertex_t v1, v2, v3;
@ -317,17 +348,17 @@ void atarisy4_renderer::draw_polygon(uint16_t color)
extradata.color = color; extradata.color = color;
extradata.screen_ram = m_state.m_screen_ram; extradata.screen_ram = m_state.m_screen_ram;
v1.x = gpu.points[0].x; v1.x = m_state.m_gpu.points[0].x;
v1.y = gpu.points[0].y; v1.y = m_state.m_gpu.points[0].y;
v2.x = gpu.points[1].x; v2.x = m_state.m_gpu.points[1].x;
v2.y = gpu.points[1].y; v2.y = m_state.m_gpu.points[1].y;
/* Draw a triangle fan */ /* Draw a triangle fan */
for (int i = 2; i <= gpu.pt_idx; ++i) for (int i = 2; i <= m_state.m_gpu.pt_idx; ++i)
{ {
v3.x = gpu.points[i].x; v3.x = m_state.m_gpu.points[i].x;
v3.y = gpu.points[i].y; v3.y = m_state.m_gpu.points[i].y;
render_triangle(clip, rd_scan, 1, v1, v2, v3); render_triangle(clip, rd_scan, 1, v1, v2, v3);
v2 = v3; v2 = v3;
@ -364,40 +395,40 @@ void atarisy4_renderer::draw_polygon(uint16_t color)
*/ */
void atarisy4_state::execute_gpu_command() void atarisy4_state::execute_gpu_command()
{ {
switch (gpu.ecr) switch (m_gpu.ecr)
{ {
case 0x04: case 0x04:
{ {
gpu.transpose = 0; m_gpu.transpose = 0;
break; break;
} }
case 0x05: case 0x05:
{ {
gpu.transpose = 1; m_gpu.transpose = 1;
break; break;
} }
case 0x06: case 0x06:
{ {
gpu.idr = gpu.gr[0]; m_gpu.idr = m_gpu.gr[0];
break; break;
} }
case 0x07: case 0x07:
{ {
gpu.icd = gpu.gr[0]; m_gpu.icd = m_gpu.gr[0];
break; break;
} }
case 0x09: case 0x09:
{ {
gpu.clip_max_x = gpu.gr[0]; m_gpu.clip_max_x = m_gpu.gr[0];
gpu.clip_min_x = gpu.gr[1]; m_gpu.clip_min_x = m_gpu.gr[1];
gpu.clip_max_y = gpu.gr[2]; m_gpu.clip_max_y = m_gpu.gr[2];
gpu.clip_min_y = gpu.gr[3]; m_gpu.clip_min_y = m_gpu.gr[3];
break; break;
} }
case 0x0b: case 0x0b:
{ {
// Wait for VBLANK and swap buffers? // Wait for VBLANK and swap buffers?
gpu.vblank_wait = 1; m_gpu.vblank_wait = 1;
break; break;
} }
case 0x16: case 0x16:
@ -411,19 +442,19 @@ void atarisy4_state::execute_gpu_command()
GR4 : Channels to set (R: 0x10, G: 0x20, B: 0x40) GR4 : Channels to set (R: 0x10, G: 0x20, B: 0x40)
*/ */
int i; int i;
int offset = xy_to_screen_addr(gpu.gr[0] - 0x400, gpu.gr[1] - 0x200); int offset = m_gpu.xy_to_screen_addr(m_gpu.gr[0] - 0x400, m_gpu.gr[1] - 0x200);
int table_offs = gpu.gr[2]; int table_offs = m_gpu.gr[2];
for (i = 0; i < gpu.gr[3]; ++i) for (i = 0; i < m_gpu.gr[3]; ++i)
{ {
uint16_t val = m_screen_ram[offset >> 1]; uint16_t val = m_screen_ram[offset >> 1];
val >>= (~offset & 1) << 3; val >>= (~offset & 1) << 3;
if (gpu.gr[4] & 0x10) if (m_gpu.gr[4] & 0x10)
m_r_color_table[table_offs] = val; m_r_color_table[table_offs] = val;
if (gpu.gr[4] & 0x20) if (m_gpu.gr[4] & 0x20)
m_g_color_table[table_offs] = val; m_g_color_table[table_offs] = val;
if (gpu.gr[4] & 0x40) if (m_gpu.gr[4] & 0x40)
m_b_color_table[table_offs] = val; m_b_color_table[table_offs] = val;
/* Update */ /* Update */
@ -447,42 +478,42 @@ void atarisy4_state::execute_gpu_command()
} }
case 0x28: case 0x28:
{ {
gpu.points[0].x = gpu.gr[0] - 0x400; m_gpu.points[0].x = m_gpu.gr[0] - 0x400;
gpu.points[0].y = gpu.gr[1] - 0x200; m_gpu.points[0].y = m_gpu.gr[1] - 0x200;
gpu.pt_idx = 0; m_gpu.pt_idx = 0;
break; break;
} }
case 0x29: case 0x29:
{ {
gpu.points[0].x = gpu.points[gpu.pt_idx].x + gpu.gr[0]; m_gpu.points[0].x = m_gpu.points[m_gpu.pt_idx].x + m_gpu.gr[0];
gpu.points[0].y = gpu.points[gpu.pt_idx].y + gpu.gr[1]; m_gpu.points[0].y = m_gpu.points[m_gpu.pt_idx].y + m_gpu.gr[1];
gpu.pt_idx = 0; m_gpu.pt_idx = 0;
break; break;
} }
case 0x2a: case 0x2a:
{ {
++gpu.pt_idx; ++m_gpu.pt_idx;
gpu.points[gpu.pt_idx].x = gpu.gr[0] - 0x400; m_gpu.points[m_gpu.pt_idx].x = m_gpu.gr[0] - 0x400;
gpu.points[gpu.pt_idx].y = gpu.gr[1] - 0x200; m_gpu.points[m_gpu.pt_idx].y = m_gpu.gr[1] - 0x200;
break; break;
} }
case 0x2b: case 0x2b:
{ {
uint16_t x = gpu.points[gpu.pt_idx].x + gpu.gr[0]; uint16_t x = m_gpu.points[m_gpu.pt_idx].x + m_gpu.gr[0];
uint16_t y = gpu.points[gpu.pt_idx].y + gpu.gr[1]; uint16_t y = m_gpu.points[m_gpu.pt_idx].y + m_gpu.gr[1];
++gpu.pt_idx; ++m_gpu.pt_idx;
gpu.points[gpu.pt_idx].x = x; m_gpu.points[m_gpu.pt_idx].x = x;
gpu.points[gpu.pt_idx].y = y; m_gpu.points[m_gpu.pt_idx].y = y;
break; break;
} }
case 0x2c: case 0x2c:
{ {
m_renderer->draw_polygon(gpu.gr[2]); m_renderer->draw_polygon(m_gpu.gr[2]);
m_renderer->wait(); m_renderer->wait();
break; break;
} }
default: default:
logerror("GPU COMMAND: %x\n", gpu.ecr); logerror("GPU COMMAND: %x\n", m_gpu.ecr);
} }
} }
@ -490,37 +521,37 @@ WRITE16_MEMBER(atarisy4_state::gpu_w)
{ {
switch (offset) switch (offset)
{ {
case 0x00: gpu.gr[0] = data; break; case 0x00: m_gpu.gr[0] = data; break;
case 0x01: gpu.gr[1] = data; break; case 0x01: m_gpu.gr[1] = data; break;
case 0x02: gpu.gr[2] = data; break; case 0x02: m_gpu.gr[2] = data; break;
case 0x03: gpu.gr[3] = data; break; case 0x03: m_gpu.gr[3] = data; break;
case 0x04: gpu.gr[4] = data; break; case 0x04: m_gpu.gr[4] = data; break;
case 0x05: gpu.gr[5] = data; break; case 0x05: m_gpu.gr[5] = data; break;
case 0x06: gpu.gr[6] = data; break; case 0x06: m_gpu.gr[6] = data; break;
case 0x07: gpu.gr[7] = data; break; case 0x07: m_gpu.gr[7] = data; break;
case 0x08: gpu.bcrw = data; break; case 0x08: m_gpu.bcrw = data; break;
case 0x09: gpu.bcrx = data; break; case 0x09: m_gpu.bcrx = data; break;
case 0x0a: gpu.bcry = data; break; case 0x0a: m_gpu.bcry = data; break;
case 0x0b: gpu.bcrz = data; break; case 0x0b: m_gpu.bcrz = data; break;
case 0x0c: gpu.psrw = data; break; case 0x0c: m_gpu.psrw = data; break;
case 0x0d: gpu.psrx = data; break; case 0x0d: m_gpu.psrx = data; break;
case 0x0e: gpu.psry = data; break; case 0x0e: m_gpu.psry = data; break;
case 0x0f: gpu.psrz = data; break; case 0x0f: m_gpu.psrz = data; break;
case 0x14: gpu.dpr = data; break; case 0x14: m_gpu.dpr = data; break;
case 0x15: gpu.ctr = data; break; case 0x15: m_gpu.ctr = data; break;
case 0x16: gpu.ifr = data; break; case 0x16: m_gpu.ifr = data; break;
case 0x17: case 0x17:
{ {
gpu.ecr = data; m_gpu.ecr = data;
execute_gpu_command(); execute_gpu_command();
break; break;
} }
case 0x1a: gpu.far = data; break; case 0x1a: m_gpu.far = data; break;
case 0x20: case 0x20:
{ {
gpu.mcr = data; m_gpu.mcr = data;
if (~data & 0x08) if (~data & 0x08)
m_maincpu->set_input_line(6, CLEAR_LINE); m_maincpu->set_input_line(6, CLEAR_LINE);
@ -528,8 +559,8 @@ WRITE16_MEMBER(atarisy4_state::gpu_w)
break; break;
} }
case 0x21: gpu.qlr = data; break; case 0x21: m_gpu.qlr = data; break;
case 0x22: gpu.qar = data; break; case 0x22: m_gpu.qar = data; break;
} }
} }
@ -539,12 +570,12 @@ READ16_MEMBER(atarisy4_state::gpu_r)
switch (offset) switch (offset)
{ {
case 0x08: res = gpu.bcrw; break; case 0x08: res = m_gpu.bcrw; break;
case 0x09: res = gpu.bcrx; break; case 0x09: res = m_gpu.bcrx; break;
case 0x0a: res = gpu.bcry; break; case 0x0a: res = m_gpu.bcry; break;
case 0x0b: res = gpu.bcrz; break; case 0x0b: res = m_gpu.bcrz; break;
case 0x20: res = gpu.mcr; break; case 0x20: res = m_gpu.mcr; break;
case 0x400: res = 5; break; // TODO! case 0x400: res = 5; break; // TODO!
case 0x420: res = 5; break; case 0x420: res = 5; break;
@ -557,7 +588,7 @@ READ16_MEMBER(atarisy4_state::gpu_r)
INTERRUPT_GEN_MEMBER(atarisy4_state::vblank_int) INTERRUPT_GEN_MEMBER(atarisy4_state::vblank_int)
{ {
if (gpu.mcr & 0x08) if (m_gpu.mcr & 0x08)
m_maincpu->set_input_line(6, ASSERT_LINE); m_maincpu->set_input_line(6, ASSERT_LINE);
} }
@ -630,12 +661,12 @@ WRITE16_MEMBER(atarisy4_state::dsp0_bank_w)
m_dsp_bank[0] = data; m_dsp_bank[0] = data;
} }
READ16_MEMBER(atarisy4_state::dsp1_status_r) READ16_MEMBER(airrace_state::dsp1_status_r)
{ {
return m_csr[1]; return m_csr[1];
} }
WRITE16_MEMBER(atarisy4_state::dsp1_control_w) WRITE16_MEMBER(airrace_state::dsp1_control_w)
{ {
m_dsp1->set_input_line(INPUT_LINE_RESET, data & 0x01 ? CLEAR_LINE : ASSERT_LINE); m_dsp1->set_input_line(INPUT_LINE_RESET, data & 0x01 ? CLEAR_LINE : ASSERT_LINE);
m_dsp1->set_input_line(0, data & 0x02 ? ASSERT_LINE : CLEAR_LINE); m_dsp1->set_input_line(0, data & 0x02 ? ASSERT_LINE : CLEAR_LINE);
@ -643,12 +674,12 @@ WRITE16_MEMBER(atarisy4_state::dsp1_control_w)
m_csr[1] = data; m_csr[1] = data;
} }
READ_LINE_MEMBER(atarisy4_state::dsp1_bio_r) READ_LINE_MEMBER(airrace_state::dsp1_bio_r)
{ {
return BIT(m_csr[1], 2); return BIT(m_csr[1], 2);
} }
WRITE16_MEMBER(atarisy4_state::dsp1_bank_w) WRITE16_MEMBER(airrace_state::dsp1_bank_w)
{ {
if (data & 0x4000) if (data & 0x4000)
{ {
@ -679,13 +710,19 @@ void atarisy4_state::main_map(address_map &map)
map(0x588000, 0x588001).r(this, FUNC(atarisy4_state::analog_r)); map(0x588000, 0x588001).r(this, FUNC(atarisy4_state::analog_r));
map(0x598000, 0x598001).noprw(); /* Sound board */ map(0x598000, 0x598001).noprw(); /* Sound board */
map(0x7c0000, 0x7c4fff).rw(this, FUNC(atarisy4_state::m68k_shared_1_r), FUNC(atarisy4_state::m68k_shared_1_w)); map(0x7c0000, 0x7c4fff).rw(this, FUNC(atarisy4_state::m68k_shared_1_r), FUNC(atarisy4_state::m68k_shared_1_w));
map(0x7c6000, 0x7c6001).rw(this, FUNC(atarisy4_state::dsp1_status_r), FUNC(atarisy4_state::dsp1_control_w));
map(0x7f0000, 0x7f4fff).rw(this, FUNC(atarisy4_state::m68k_shared_0_r), FUNC(atarisy4_state::m68k_shared_0_w)); map(0x7f0000, 0x7f4fff).rw(this, FUNC(atarisy4_state::m68k_shared_0_r), FUNC(atarisy4_state::m68k_shared_0_w));
map(0x7f6000, 0x7f6001).rw(this, FUNC(atarisy4_state::dsp0_status_r), FUNC(atarisy4_state::dsp0_control_w)); map(0x7f6000, 0x7f6001).rw(this, FUNC(atarisy4_state::dsp0_status_r), FUNC(atarisy4_state::dsp0_control_w));
map(0xa00400, 0xbfffff).ram().share("screen_ram"); map(0xa00400, 0xbfffff).ram().share("screen_ram");
map(0xff8000, 0xff8fff).rw(this, FUNC(atarisy4_state::gpu_r), FUNC(atarisy4_state::gpu_w)); map(0xff8000, 0xff8fff).rw(this, FUNC(atarisy4_state::gpu_r), FUNC(atarisy4_state::gpu_w));
} }
void airrace_state::airrace_map(address_map &map)
{
main_map(map);
map(0x7c6000, 0x7c6001).rw(this, FUNC(airrace_state::dsp1_status_r), FUNC(airrace_state::dsp1_control_w));
}
/************************************* /*************************************
* *
@ -712,16 +749,16 @@ void atarisy4_state::dsp0_io_map(address_map &map)
* *
*************************************/ *************************************/
void atarisy4_state::dsp1_map(address_map &map) void airrace_state::dsp1_map(address_map &map)
{ {
map.global_mask(0xfff); map.global_mask(0xfff);
map(0x0000, 0x07ff).bankrw("dsp1_bank0"); map(0x0000, 0x07ff).bankrw("dsp1_bank0");
map(0x0800, 0x0fff).bankrw("dsp1_bank1"); map(0x0800, 0x0fff).bankrw("dsp1_bank1");
} }
void atarisy4_state::dsp1_io_map(address_map &map) void airrace_state::dsp1_io_map(address_map &map)
{ {
map(0x00, 0x01).w(this, FUNC(atarisy4_state::dsp1_bank_w)); map(0x00, 0x01).w(this, FUNC(airrace_state::dsp1_bank_w));
} }
@ -733,7 +770,7 @@ void atarisy4_state::dsp1_io_map(address_map &map)
READ16_MEMBER(atarisy4_state::analog_r) READ16_MEMBER(atarisy4_state::analog_r)
{ {
return (ioport("STICKX")->read() << 8) | ioport("STICKY")->read(); return (m_stick[0]->read() << 8) | m_stick[1]->read();
} }
static INPUT_PORTS_START( atarisy4 ) static INPUT_PORTS_START( atarisy4 )
@ -770,11 +807,11 @@ INPUT_PORTS_END
*************************************/ *************************************/
MACHINE_CONFIG_START(atarisy4_state::atarisy4) MACHINE_CONFIG_START(atarisy4_state::atarisy4)
MCFG_DEVICE_ADD("maincpu", M68000, 8000000) MCFG_DEVICE_ADD(m_maincpu, M68000, 8000000)
MCFG_DEVICE_PROGRAM_MAP(main_map) MCFG_DEVICE_PROGRAM_MAP(main_map)
MCFG_DEVICE_VBLANK_INT_DRIVER("screen", atarisy4_state, vblank_int) MCFG_DEVICE_VBLANK_INT_DRIVER("screen", atarisy4_state, vblank_int)
MCFG_DEVICE_ADD("dsp0", TMS32010, 16000000) MCFG_DEVICE_ADD(m_dsp0, TMS32010, 16000000)
MCFG_DEVICE_PROGRAM_MAP(dsp0_map) MCFG_DEVICE_PROGRAM_MAP(dsp0_map)
MCFG_DEVICE_IO_MAP(dsp0_io_map) MCFG_DEVICE_IO_MAP(dsp0_io_map)
MCFG_TMS32010_BIO_IN_CB(READLINE(*this, atarisy4_state, dsp0_bio_r)) MCFG_TMS32010_BIO_IN_CB(READLINE(*this, atarisy4_state, dsp0_bio_r))
@ -788,15 +825,16 @@ MACHINE_CONFIG_START(atarisy4_state::atarisy4)
MACHINE_CONFIG_END MACHINE_CONFIG_END
MACHINE_CONFIG_START(atarisy4_state::airrace) MACHINE_CONFIG_START(airrace_state::airrace)
atarisy4(config); atarisy4(config);
MCFG_DEVICE_ADD("dsp1", TMS32010, 16000000) MCFG_DEVICE_MODIFY("maincpu")
MCFG_DEVICE_PROGRAM_MAP(airrace_map)
MCFG_DEVICE_ADD(m_dsp1, TMS32010, 16000000)
MCFG_DEVICE_PROGRAM_MAP(dsp1_map) MCFG_DEVICE_PROGRAM_MAP(dsp1_map)
MCFG_DEVICE_IO_MAP(dsp1_io_map) MCFG_DEVICE_IO_MAP(dsp1_io_map)
MCFG_TMS32010_BIO_IN_CB(READLINE(*this, atarisy4_state, dsp1_bio_r)) MCFG_TMS32010_BIO_IN_CB(READLINE(*this, airrace_state, dsp1_bio_r))
MCFG_MACHINE_RESET_OVERRIDE(atarisy4_state,airrace)
MACHINE_CONFIG_END MACHINE_CONFIG_END
@ -1028,7 +1066,7 @@ void atarisy4_state::init_laststar()
load_ldafile(m_dsp0->space(AS_PROGRAM), memregion("dsp")->base()); load_ldafile(m_dsp0->space(AS_PROGRAM), memregion("dsp")->base());
} }
void atarisy4_state::init_airrace() void airrace_state::init_airrace()
{ {
/* Allocate two sets of 32kB shared RAM */ /* Allocate two sets of 32kB shared RAM */
m_shared_ram[0] = make_unique_clear<uint16_t[]>(0x4000); m_shared_ram[0] = make_unique_clear<uint16_t[]>(0x4000);
@ -1053,9 +1091,10 @@ void atarisy4_state::machine_reset()
m_dsp0->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); m_dsp0->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
} }
MACHINE_RESET_MEMBER(atarisy4_state,airrace) void airrace_state::machine_reset()
{ {
m_dsp0->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); atarisy4_state::machine_reset();
m_dsp1->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); m_dsp1->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
} }
@ -1067,4 +1106,4 @@ MACHINE_RESET_MEMBER(atarisy4_state,airrace)
*************************************/ *************************************/
GAME( 1984, laststar, 0, atarisy4, atarisy4, atarisy4_state, init_laststar, ROT0, "Atari Games", "The Last Starfighter (prototype)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND_HW ) GAME( 1984, laststar, 0, atarisy4, atarisy4, atarisy4_state, init_laststar, ROT0, "Atari Games", "The Last Starfighter (prototype)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND_HW )
GAME( 1985, airrace, 0, airrace, atarisy4, atarisy4_state, init_airrace, ROT0, "Atari Games", "Air Race (prototype)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND_HW ) GAME( 1985, airrace, 0, airrace, atarisy4, airrace_state, init_airrace, ROT0, "Atari Games", "Air Race (prototype)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND_HW )

View File

@ -61,50 +61,67 @@ public:
, m_v9958(*this, "v9958") , m_v9958(*this, "v9958")
, m_maincpu(*this, "maincpu") , m_maincpu(*this, "maincpu")
, m_region_user1(*this, "user1") , m_region_user1(*this, "user1")
, m_bank1(*this, "bank1") , m_banks(*this, "bank%u", 1U)
, m_bank2(*this, "bank2")
, m_bank3(*this, "bank3")
, m_bank4(*this, "bank4")
, m_bank5(*this, "bank5")
, m_bank6(*this, "bank6")
, m_bank7(*this, "bank7")
, m_bank8(*this, "bank8")
{ } { }
protected:
virtual void machine_start() override;
void sangho_map(address_map &map);
std::unique_ptr<uint8_t[]> m_ram; std::unique_ptr<uint8_t[]> m_ram;
uint8_t m_sexyboom_bank[8];
uint8_t m_pzlestar_mem_bank;
uint8_t m_pzlestar_rom_bank;
required_device<v9958_device> m_v9958; required_device<v9958_device> m_v9958;
required_device<cpu_device> m_maincpu; required_device<cpu_device> m_maincpu;
required_memory_region m_region_user1; required_memory_region m_region_user1;
required_memory_bank m_bank1; required_memory_bank_array<8> m_banks;
required_memory_bank m_bank2; };
required_memory_bank m_bank3;
required_memory_bank m_bank4;
required_memory_bank m_bank5;
required_memory_bank m_bank6;
required_memory_bank m_bank7;
required_memory_bank m_bank8;
uint8_t m_sec_slot[4];
class pzlestar_state : public sangho_state
{
public:
using sangho_state::sangho_state;
void init_pzlestar();
void pzlestar(machine_config &config);
protected:
DECLARE_WRITE8_MEMBER(pzlestar_bank_w); DECLARE_WRITE8_MEMBER(pzlestar_bank_w);
DECLARE_WRITE8_MEMBER(pzlestar_mem_bank_w); DECLARE_WRITE8_MEMBER(pzlestar_mem_bank_w);
DECLARE_READ8_MEMBER(pzlestar_mem_bank_r); DECLARE_READ8_MEMBER(pzlestar_mem_bank_r);
DECLARE_WRITE8_MEMBER(sexyboom_bank_w);
void init_pzlestar();
virtual void machine_start() override;
DECLARE_MACHINE_RESET(pzlestar);
DECLARE_MACHINE_RESET(sexyboom);
void pzlestar_map_banks();
void sexyboom_map_bank(int bank);
DECLARE_READ8_MEMBER(sec_slot_r); DECLARE_READ8_MEMBER(sec_slot_r);
DECLARE_WRITE8_MEMBER(sec_slot_w); DECLARE_WRITE8_MEMBER(sec_slot_w);
void pzlestar(machine_config &config);
void sexyboom(machine_config &config); virtual void machine_reset() override;
void pzlestar_map_banks();
void pzlestar_io_map(address_map &map); void pzlestar_io_map(address_map &map);
void sangho_map(address_map &map);
private:
uint8_t m_pzlestar_mem_bank;
uint8_t m_pzlestar_rom_bank;
uint8_t m_sec_slot[4];
};
class sexyboom_state : public sangho_state
{
public:
using sangho_state::sangho_state;
void sexyboom(machine_config &config);
protected:
DECLARE_WRITE8_MEMBER(sexyboom_bank_w);
virtual void machine_reset() override;
void sexyboom_map_bank(int bank);
void sexyboom_io_map(address_map &map); void sexyboom_io_map(address_map &map);
private:
uint8_t m_sexyboom_bank[8];
}; };
/* /*
@ -113,7 +130,7 @@ public:
slot 2 selects code ROMs slot 2 selects code ROMs
slot 3 selects data ROMs slot 3 selects data ROMs
*/ */
void sangho_state::pzlestar_map_banks() void pzlestar_state::pzlestar_map_banks()
{ {
int slot_select; int slot_select;
@ -121,117 +138,114 @@ void sangho_state::pzlestar_map_banks()
slot_select = (m_pzlestar_mem_bank >> 0) & 0x03; slot_select = (m_pzlestar_mem_bank >> 0) & 0x03;
switch(slot_select) switch(slot_select)
{ {
case 0: case 0:
m_maincpu->space(AS_PROGRAM).install_read_bank(0x0000, 0x3fff, m_bank1); m_maincpu->space(AS_PROGRAM).install_read_bank(0x0000, 0x3fff, m_banks[0]);
m_maincpu->space(AS_PROGRAM).install_write_bank(0x0000, 0x3fff, m_bank5); m_maincpu->space(AS_PROGRAM).install_write_bank(0x0000, 0x3fff, m_banks[4]);
m_bank1->set_base(m_ram.get()); m_banks[0]->set_base(m_ram.get());
m_bank5->set_base(m_ram.get()); m_banks[4]->set_base(m_ram.get());
break; break;
case 2: case 2:
m_maincpu->space(AS_PROGRAM).install_read_bank(0x0000, 0x3fff, m_bank1); m_maincpu->space(AS_PROGRAM).install_read_bank(0x0000, 0x3fff, m_banks[0]);
m_maincpu->space(AS_PROGRAM).unmap_write(0x0000, 0x3fff); m_maincpu->space(AS_PROGRAM).unmap_write(0x0000, 0x3fff);
m_bank1->set_base(m_region_user1->base()+ 0x10000); m_banks[0]->set_base(m_region_user1->base()+ 0x10000);
break; break;
case 1: case 1:
case 3: case 3:
m_maincpu->space(AS_PROGRAM).unmap_read(0x0000, 0x3fff); m_maincpu->space(AS_PROGRAM).unmap_read(0x0000, 0x3fff);
m_maincpu->space(AS_PROGRAM).unmap_write(0x0000, 0x3fff); m_maincpu->space(AS_PROGRAM).unmap_write(0x0000, 0x3fff);
break; break;
} }
// page 1 // page 1
slot_select = (m_pzlestar_mem_bank >> 2) & 0x03; slot_select = (m_pzlestar_mem_bank >> 2) & 0x03;
switch(slot_select) switch(slot_select)
{ {
case 0: case 0:
m_maincpu->space(AS_PROGRAM).install_read_bank(0x4000, 0x7fff, m_bank2); m_maincpu->space(AS_PROGRAM).install_read_bank(0x4000, 0x7fff, m_banks[1]);
m_maincpu->space(AS_PROGRAM).install_write_bank(0x4000, 0x7fff, m_bank6); m_maincpu->space(AS_PROGRAM).install_write_bank(0x4000, 0x7fff, m_banks[5]);
m_bank2->set_base(m_ram.get() + 0x4000); m_banks[1]->set_base(m_ram.get() + 0x4000);
m_bank6->set_base(m_ram.get() + 0x4000); m_banks[5]->set_base(m_ram.get() + 0x4000);
break; break;
case 2: case 2:
m_maincpu->space(AS_PROGRAM).install_read_bank(0x4000, 0x7fff, m_bank2); m_maincpu->space(AS_PROGRAM).install_read_bank(0x4000, 0x7fff, m_banks[1]);
m_maincpu->space(AS_PROGRAM).unmap_write(0x4000, 0x7fff); m_maincpu->space(AS_PROGRAM).unmap_write(0x4000, 0x7fff);
m_bank2->set_base(m_region_user1->base()+ 0x18000); m_banks[1]->set_base(m_region_user1->base()+ 0x18000);
break; break;
case 3: case 3:
m_maincpu->space(AS_PROGRAM).install_read_bank(0x4000, 0x7fff, m_bank2); m_maincpu->space(AS_PROGRAM).install_read_bank(0x4000, 0x7fff, m_banks[1]);
m_maincpu->space(AS_PROGRAM).unmap_write(0x4000, 0x7fff); m_maincpu->space(AS_PROGRAM).unmap_write(0x4000, 0x7fff);
m_bank2->set_base(m_region_user1->base()+ 0x20000 + (m_pzlestar_rom_bank*0x8000) + 0x4000); m_banks[1]->set_base(m_region_user1->base()+ 0x20000 + (m_pzlestar_rom_bank*0x8000) + 0x4000);
break; break;
case 1: case 1:
m_maincpu->space(AS_PROGRAM).unmap_read(0x4000, 0x7fff); m_maincpu->space(AS_PROGRAM).unmap_read(0x4000, 0x7fff);
m_maincpu->space(AS_PROGRAM).unmap_write(0x4000, 0x7fff); m_maincpu->space(AS_PROGRAM).unmap_write(0x4000, 0x7fff);
break; break;
} }
// page 2 // page 2
slot_select = (m_pzlestar_mem_bank >> 4) & 0x03; slot_select = (m_pzlestar_mem_bank >> 4) & 0x03;
switch(slot_select) switch(slot_select)
{ {
case 0: case 0:
m_maincpu->space(AS_PROGRAM).install_read_bank(0x8000, 0xbfff, m_bank3); m_maincpu->space(AS_PROGRAM).install_read_bank(0x8000, 0xbfff, m_banks[2]);
m_maincpu->space(AS_PROGRAM).install_write_bank(0x8000, 0xbfff, m_bank7); m_maincpu->space(AS_PROGRAM).install_write_bank(0x8000, 0xbfff, m_banks[6]);
m_bank3->set_base(m_ram.get() + 0x8000); m_banks[2]->set_base(m_ram.get() + 0x8000);
m_bank7->set_base(m_ram.get() + 0x8000); m_banks[6]->set_base(m_ram.get() + 0x8000);
break; break;
case 3: case 3:
m_maincpu->space(AS_PROGRAM).install_read_bank(0x8000, 0xbfff, m_bank3); m_maincpu->space(AS_PROGRAM).install_read_bank(0x8000, 0xbfff, m_banks[2]);
m_maincpu->space(AS_PROGRAM).unmap_write(0x8000, 0xbfff); m_maincpu->space(AS_PROGRAM).unmap_write(0x8000, 0xbfff);
m_bank3->set_base(m_region_user1->base()+ 0x20000 + (m_pzlestar_rom_bank*0x8000)); m_banks[2]->set_base(m_region_user1->base()+ 0x20000 + (m_pzlestar_rom_bank*0x8000));
break; break;
case 1: case 1:
case 2: case 2:
m_maincpu->space(AS_PROGRAM).unmap_read(0x8000, 0xbfff); m_maincpu->space(AS_PROGRAM).unmap_read(0x8000, 0xbfff);
m_maincpu->space(AS_PROGRAM).unmap_write(0x8000, 0xbfff); m_maincpu->space(AS_PROGRAM).unmap_write(0x8000, 0xbfff);
break; break;
} }
// page 3 // page 3
slot_select = (m_pzlestar_mem_bank >> 6) & 0x03; slot_select = (m_pzlestar_mem_bank >> 6) & 0x03;
switch(slot_select) switch(slot_select)
{ {
case 0: case 0:
m_maincpu->space(AS_PROGRAM).install_read_bank(0xc000, 0xffff, m_bank4); m_maincpu->space(AS_PROGRAM).install_read_bank(0xc000, 0xffff, m_banks[3]);
m_maincpu->space(AS_PROGRAM).install_write_bank(0xc000, 0xffff, m_bank8); m_maincpu->space(AS_PROGRAM).install_write_bank(0xc000, 0xffff, m_banks[7]);
m_bank4->set_base(m_ram.get() + 0xc000); m_banks[3]->set_base(m_ram.get() + 0xc000);
m_bank8->set_base(m_ram.get() + 0xc000); m_banks[7]->set_base(m_ram.get() + 0xc000);
break; break;
case 1: case 1:
case 2: case 2:
case 3: case 3:
m_maincpu->space(AS_PROGRAM).unmap_read(0xc000, 0xffff); m_maincpu->space(AS_PROGRAM).unmap_read(0xc000, 0xffff);
m_maincpu->space(AS_PROGRAM).unmap_write(0xc000, 0xffff); m_maincpu->space(AS_PROGRAM).unmap_write(0xc000, 0xffff);
break; break;
} }
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xffff, 0xffff, read8_delegate(FUNC(sangho_state::sec_slot_r),this), write8_delegate(FUNC(sangho_state::sec_slot_w),this)); m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xffff, 0xffff, read8_delegate(FUNC(pzlestar_state::sec_slot_r),this), write8_delegate(FUNC(pzlestar_state::sec_slot_w),this));
} }
WRITE8_MEMBER(sangho_state::pzlestar_bank_w) WRITE8_MEMBER(pzlestar_state::pzlestar_bank_w)
{ {
logerror("rom bank %02x\n", data); logerror("rom bank %02x\n", data);
m_pzlestar_rom_bank = data; m_pzlestar_rom_bank = data;
pzlestar_map_banks(); pzlestar_map_banks();
} }
WRITE8_MEMBER(sangho_state::pzlestar_mem_bank_w) WRITE8_MEMBER(pzlestar_state::pzlestar_mem_bank_w)
{ {
logerror("mem bank %02x\n", data); logerror("mem bank %02x\n", data);
m_pzlestar_mem_bank = data; m_pzlestar_mem_bank = data;
pzlestar_map_banks(); pzlestar_map_banks();
} }
READ8_MEMBER(sangho_state::pzlestar_mem_bank_r) READ8_MEMBER(pzlestar_state::pzlestar_mem_bank_r)
{ {
return m_pzlestar_mem_bank; return m_pzlestar_mem_bank;
} }
void sangho_state::sexyboom_map_bank(int bank) void sexyboom_state::sexyboom_map_bank(int bank)
{ {
memory_bank *read_bank[4] = { m_bank1, m_bank2, m_bank3, m_bank4 };
memory_bank *write_bank[4] = { m_bank5, m_bank6, m_bank7, m_bank8 };
uint8_t banknum = m_sexyboom_bank[bank*2]; uint8_t banknum = m_sexyboom_bank[bank*2];
uint8_t banktype = m_sexyboom_bank[bank*2 + 1]; uint8_t banktype = m_sexyboom_bank[bank*2 + 1];
@ -240,25 +254,25 @@ void sangho_state::sexyboom_map_bank(int bank)
if (banknum & 0x80) if (banknum & 0x80)
{ {
// ram // ram
read_bank[bank]->set_base(&m_ram[(banknum & 0x7f) * 0x4000]); m_banks[bank]->set_base(&m_ram[(banknum & 0x7f) * 0x4000]);
m_maincpu->space(AS_PROGRAM).install_write_bank(bank*0x4000, (bank+1)*0x4000 - 1, write_bank[bank] ); m_maincpu->space(AS_PROGRAM).install_write_bank(bank*0x4000, (bank+1)*0x4000 - 1, m_banks[4 + bank] );
write_bank[bank]->set_base(&m_ram[(banknum & 0x7f) * 0x4000]); m_banks[4 + bank]->set_base(&m_ram[(banknum & 0x7f) * 0x4000]);
} }
else else
{ {
// rom 0 // rom 0
read_bank[bank]->set_base(m_region_user1->base()+0x4000*banknum); m_banks[bank]->set_base(m_region_user1->base()+0x4000*banknum);
m_maincpu->space(AS_PROGRAM).unmap_write(bank*0x4000, (bank+1)*0x4000 - 1); m_maincpu->space(AS_PROGRAM).unmap_write(bank*0x4000, (bank+1)*0x4000 - 1);
} }
} }
else if (banktype == 0x82) else if (banktype == 0x82)
{ {
read_bank[bank]->set_base(m_region_user1->base()+0x20000+banknum*0x4000); m_banks[bank]->set_base(m_region_user1->base()+0x20000+banknum*0x4000);
m_maincpu->space(AS_PROGRAM).unmap_write(bank*0x4000, (bank+1)*0x4000 - 1); m_maincpu->space(AS_PROGRAM).unmap_write(bank*0x4000, (bank+1)*0x4000 - 1);
} }
else if (banktype == 0x80) else if (banktype == 0x80)
{ {
read_bank[bank]->set_base(m_region_user1->base()+0x120000+banknum*0x4000); m_banks[bank]->set_base(m_region_user1->base()+0x120000+banknum*0x4000);
m_maincpu->space(AS_PROGRAM).unmap_write(bank*0x4000, (bank+1)*0x4000 - 1); m_maincpu->space(AS_PROGRAM).unmap_write(bank*0x4000, (bank+1)*0x4000 - 1);
} }
else else
@ -267,19 +281,19 @@ void sangho_state::sexyboom_map_bank(int bank)
} }
} }
WRITE8_MEMBER(sangho_state::sexyboom_bank_w) WRITE8_MEMBER(sexyboom_state::sexyboom_bank_w)
{ {
m_sexyboom_bank[offset] = data; m_sexyboom_bank[offset] = data;
sexyboom_map_bank(offset>>1); sexyboom_map_bank(offset>>1);
} }
/* secondary slot R/Ws from current primary slot number (see also mess/machine/msx.c) */ /* secondary slot R/Ws from current primary slot number (see also mess/machine/msx.c) */
READ8_MEMBER(sangho_state::sec_slot_r) READ8_MEMBER(pzlestar_state::sec_slot_r)
{ {
return m_sec_slot[m_pzlestar_mem_bank >> 6] ^ 0xff; return m_sec_slot[m_pzlestar_mem_bank >> 6] ^ 0xff;
} }
WRITE8_MEMBER(sangho_state::sec_slot_w) WRITE8_MEMBER(pzlestar_state::sec_slot_w)
{ {
m_sec_slot[m_pzlestar_mem_bank >> 6] = data; m_sec_slot[m_pzlestar_mem_bank >> 6] = data;
} }
@ -295,21 +309,21 @@ void sangho_state::sangho_map(address_map &map)
/* Puzzle Star Ports */ /* Puzzle Star Ports */
void sangho_state::pzlestar_io_map(address_map &map) void pzlestar_state::pzlestar_io_map(address_map &map)
{ {
map.global_mask(0xff); map.global_mask(0xff);
map(0x7c, 0x7d).w("ymsnd", FUNC(ym2413_device::write)); map(0x7c, 0x7d).w("ymsnd", FUNC(ym2413_device::write));
map(0x91, 0x91).w(this, FUNC(sangho_state::pzlestar_bank_w)); map(0x91, 0x91).w(this, FUNC(pzlestar_state::pzlestar_bank_w));
map(0x98, 0x9b).rw(m_v9958, FUNC(v9958_device::read), FUNC(v9958_device::write)); map(0x98, 0x9b).rw(m_v9958, FUNC(v9958_device::read), FUNC(v9958_device::write));
map(0xa0, 0xa0).portr("P1"); map(0xa0, 0xa0).portr("P1");
map(0xa1, 0xa1).portr("P2"); map(0xa1, 0xa1).portr("P2");
map(0xa8, 0xa8).rw(this, FUNC(sangho_state::pzlestar_mem_bank_r), FUNC(sangho_state::pzlestar_mem_bank_w)); map(0xa8, 0xa8).rw(this, FUNC(pzlestar_state::pzlestar_mem_bank_r), FUNC(pzlestar_state::pzlestar_mem_bank_w));
map(0xf7, 0xf7).portr("DSW"); map(0xf7, 0xf7).portr("DSW");
} }
/* Sexy Boom Ports */ /* Sexy Boom Ports */
void sangho_state::sexyboom_io_map(address_map &map) void sexyboom_state::sexyboom_io_map(address_map &map)
{ {
map.global_mask(0xff); map.global_mask(0xff);
map(0x7c, 0x7d).w("ymsnd", FUNC(ym2413_device::write)); map(0x7c, 0x7d).w("ymsnd", FUNC(ym2413_device::write));
@ -317,7 +331,7 @@ void sangho_state::sexyboom_io_map(address_map &map)
map(0xa1, 0xa1).portr("P2"); map(0xa1, 0xa1).portr("P2");
map(0xf0, 0xf3).rw(m_v9958, FUNC(v9958_device::read), FUNC(v9958_device::write)); map(0xf0, 0xf3).rw(m_v9958, FUNC(v9958_device::read), FUNC(v9958_device::write));
map(0xf7, 0xf7).portr("DSW"); map(0xf7, 0xf7).portr("DSW");
map(0xf8, 0xff).w(this, FUNC(sangho_state::sexyboom_bank_w)); map(0xf8, 0xff).w(this, FUNC(sexyboom_state::sexyboom_bank_w));
} }
static INPUT_PORTS_START( sexyboom ) static INPUT_PORTS_START( sexyboom )
@ -437,14 +451,18 @@ void sangho_state::machine_start()
m_ram = std::make_unique<uint8_t[]>(0x20000); // TODO: define how much RAM these ones have (MSX2+ can potentially go up to 4MB) m_ram = std::make_unique<uint8_t[]>(0x20000); // TODO: define how much RAM these ones have (MSX2+ can potentially go up to 4MB)
} }
MACHINE_RESET_MEMBER(sangho_state,pzlestar) void pzlestar_state::machine_reset()
{ {
sangho_state::machine_reset();
m_pzlestar_mem_bank = 2; m_pzlestar_mem_bank = 2;
pzlestar_map_banks(); pzlestar_map_banks();
} }
MACHINE_RESET_MEMBER(sangho_state,sexyboom) void sexyboom_state::machine_reset()
{ {
sangho_state::machine_reset();
m_sexyboom_bank[0] = 0x00; m_sexyboom_bank[0] = 0x00;
m_sexyboom_bank[1] = 0x00; m_sexyboom_bank[1] = 0x00;
m_sexyboom_bank[2] = 0x01; m_sexyboom_bank[2] = 0x01;
@ -460,8 +478,7 @@ MACHINE_RESET_MEMBER(sangho_state,sexyboom)
} }
MACHINE_CONFIG_START(sangho_state::pzlestar) MACHINE_CONFIG_START(pzlestar_state::pzlestar)
MCFG_DEVICE_ADD("maincpu", Z80, XTAL(21'477'272)/6) // ? MCFG_DEVICE_ADD("maincpu", Z80, XTAL(21'477'272)/6) // ?
MCFG_DEVICE_PROGRAM_MAP(sangho_map) MCFG_DEVICE_PROGRAM_MAP(sangho_map)
MCFG_DEVICE_IO_MAP(pzlestar_io_map) MCFG_DEVICE_IO_MAP(pzlestar_io_map)
@ -470,8 +487,6 @@ MACHINE_CONFIG_START(sangho_state::pzlestar)
MCFG_V99X8_INTERRUPT_CALLBACK(INPUTLINE("maincpu", 0)) MCFG_V99X8_INTERRUPT_CALLBACK(INPUTLINE("maincpu", 0))
MCFG_V99X8_SCREEN_ADD_NTSC("screen", "v9958", XTAL(21'477'272)) MCFG_V99X8_SCREEN_ADD_NTSC("screen", "v9958", XTAL(21'477'272))
MCFG_MACHINE_RESET_OVERRIDE(sangho_state,pzlestar)
SPEAKER(config, "mono").front_center(); SPEAKER(config, "mono").front_center();
MCFG_DEVICE_ADD("ymsnd", YM2413, XTAL(21'477'272)/6) MCFG_DEVICE_ADD("ymsnd", YM2413, XTAL(21'477'272)/6)
@ -479,8 +494,7 @@ MACHINE_CONFIG_START(sangho_state::pzlestar)
MACHINE_CONFIG_END MACHINE_CONFIG_END
MACHINE_CONFIG_START(sangho_state::sexyboom) MACHINE_CONFIG_START(sexyboom_state::sexyboom)
MCFG_DEVICE_ADD("maincpu", Z80, XTAL(21'477'272)/6) MCFG_DEVICE_ADD("maincpu", Z80, XTAL(21'477'272)/6)
MCFG_DEVICE_PROGRAM_MAP(sangho_map) MCFG_DEVICE_PROGRAM_MAP(sangho_map)
MCFG_DEVICE_IO_MAP(sexyboom_io_map) MCFG_DEVICE_IO_MAP(sexyboom_io_map)
@ -489,8 +503,6 @@ MACHINE_CONFIG_START(sangho_state::sexyboom)
MCFG_V99X8_INTERRUPT_CALLBACK(INPUTLINE("maincpu", 0)) MCFG_V99X8_INTERRUPT_CALLBACK(INPUTLINE("maincpu", 0))
MCFG_V99X8_SCREEN_ADD_NTSC("screen", "v9958", XTAL(21'477'272)) MCFG_V99X8_SCREEN_ADD_NTSC("screen", "v9958", XTAL(21'477'272))
MCFG_MACHINE_RESET_OVERRIDE(sangho_state,sexyboom)
MCFG_PALETTE_ADD("palette", 19780) MCFG_PALETTE_ADD("palette", 19780)
SPEAKER(config, "mono").front_center(); SPEAKER(config, "mono").front_center();
@ -537,7 +549,7 @@ ROM_START( sexyboom )
/* 15 empty */ /* 15 empty */
ROM_END ROM_END
void sangho_state::init_pzlestar() void pzlestar_state::init_pzlestar()
{ {
uint8_t *ROM = m_region_user1->base(); uint8_t *ROM = m_region_user1->base();
@ -546,5 +558,5 @@ void sangho_state::init_pzlestar()
ROM[0x12ca8] = 0x00; ROM[0x12ca8] = 0x00;
} }
GAME( 1991, pzlestar, 0, pzlestar, pzlestar, sangho_state, init_pzlestar, ROT270, "Sang Ho Soft", "Puzzle Star (Sang Ho Soft)", MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_SOUND ) GAME( 1991, pzlestar, 0, pzlestar, pzlestar, pzlestar_state, init_pzlestar, ROT270, "Sang Ho Soft", "Puzzle Star (Sang Ho Soft)", MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_SOUND )
GAME( 1992, sexyboom, 0, sexyboom, sexyboom, sangho_state, empty_init, ROT270, "Sang Ho Soft", "Sexy Boom", 0 ) GAME( 1992, sexyboom, 0, sexyboom, sexyboom, sexyboom_state, empty_init, ROT270, "Sang Ho Soft", "Sexy Boom", 0 )