forte2, unkhorse: small cleanup

This commit is contained in:
hap 2023-08-09 15:03:41 +02:00
parent d94d4b338c
commit f70bc8ee7a
4 changed files with 209 additions and 162 deletions

View File

@ -2,12 +2,12 @@
// copyright-holders:hap, Tomasz Slanina // copyright-holders:hap, Tomasz Slanina
/******************************************************************************* /*******************************************************************************
unknown Japanese horse gambling game unknown Japanese horse gambling game
probably early 80s, manufacturer unknown probably early 80s, manufacturer unknown
from a broken PCB, labeled EFI TG-007 from a broken PCB, labeled EFI TG-007
8085A CPU + 8155 (for I/O and sound) M5L8085AP CPU + M5L8155P (for I/O and sound)
8KB RAM mainly for bitmap video, and 512x4 RAM for color map 8KB RAM mainly for bitmap video, and 512x4 RAM for color map
TODO: TODO:
- identify game! - identify game!
@ -38,37 +38,40 @@ public:
horse_state(const machine_config &mconfig, device_type type, const char *tag) : horse_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_speaker(*this, "speaker"), m_i8155(*this, "i8155"),
m_inputs(*this, "IN.%u", 0), m_screen(*this, "screen"),
m_vram(*this, "vram") m_vram(*this, "vram"),
m_colorram(*this, "colorram", 0x200, ENDIANNESS_LITTLE),
m_inputs(*this, "IN.%u", 0)
{ } { }
void horse(machine_config &config); void horse(machine_config &config);
protected:
virtual void machine_start() override;
private: private:
required_device<cpu_device> m_maincpu; required_device<cpu_device> m_maincpu;
required_device<speaker_sound_device> m_speaker; required_device<i8155_device> m_i8155;
required_device<screen_device> m_screen;
required_shared_ptr<u8> m_vram;
memory_share_creator<u8> m_colorram;
required_ioport_array<4> m_inputs; required_ioport_array<4> m_inputs;
required_shared_ptr<uint8_t> m_vram;
std::unique_ptr<uint8_t[]> m_colorram; u8 m_output = 0;
uint8_t m_output = 0;
uint8_t colorram_r(offs_t offset) { return m_colorram[(offset >> 2 & 0x1e0) | (offset & 0x1f)] | 0x0f; } u8 colorram_r(offs_t offset) { return m_colorram[(offset >> 2 & 0x1e0) | (offset & 0x1f)] | 0x0f; }
void colorram_w(offs_t offset, uint8_t data) { m_colorram[(offset >> 2 & 0x1e0) | (offset & 0x1f)] = data & 0xf0; } void colorram_w(offs_t offset, u8 data) { m_colorram[(offset >> 2 & 0x1e0) | (offset & 0x1f)] = data & 0xf0; }
uint8_t input_r(); u8 input_r();
void output_w(uint8_t data); void output_w(u8 data);
virtual void machine_start() override; u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void horse_io_map(address_map &map); void horse_io_map(address_map &map);
void horse_map(address_map &map); void horse_map(address_map &map);
}; };
void horse_state::machine_start() void horse_state::machine_start()
{ {
m_colorram = std::make_unique<uint8_t []>(0x200);
save_pointer(NAME(m_colorram), 0x200);
save_item(NAME(m_output)); save_item(NAME(m_output));
} }
@ -78,14 +81,14 @@ void horse_state::machine_start()
Video Video
*******************************************************************************/ *******************************************************************************/
uint32_t horse_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) u32 horse_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{ {
for (int y = cliprect.min_y; y <= cliprect.max_y; y++) for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
{ {
for (int x = 0; x < 32; x++) for (int x = 0; x < 32; x++)
{ {
uint8_t data = m_vram[y << 5 | x]; u8 data = m_vram[y << 5 | x];
uint8_t color = m_colorram[(y << 1 & 0x1e0) | x] >> 4; u8 color = m_colorram[(y << 1 & 0x1e0) | x] >> 4;
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
bitmap.pix(y, x << 3 | i) = (data >> i & 1) ? color : 0; bitmap.pix(y, x << 3 | i) = (data >> i & 1) ? color : 0;
@ -101,32 +104,36 @@ uint32_t horse_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap,
I/O I/O
*******************************************************************************/ *******************************************************************************/
u8 horse_state::input_r()
{
return m_inputs[m_output >> 6 & 3]->read();
}
void horse_state::output_w(u8 data)
{
// d4: payout related
// d6-d7: input mux
// other bits: ?
m_output = data;
}
/*******************************************************************************
Address Maps
*******************************************************************************/
void horse_state::horse_map(address_map &map) void horse_state::horse_map(address_map &map)
{ {
map(0x0000, 0x37ff).rom(); map(0x0000, 0x37ff).rom();
map(0x4000, 0x40ff).rw("i8155", FUNC(i8155_device::memory_r), FUNC(i8155_device::memory_w)); map(0x4000, 0x40ff).rw(m_i8155, FUNC(i8155_device::memory_r), FUNC(i8155_device::memory_w));
map(0x6000, 0x7fff).ram().share("vram"); map(0x6000, 0x7fff).ram().share("vram");
map(0x8000, 0x87ff).mirror(0x0800).rw(FUNC(horse_state::colorram_r), FUNC(horse_state::colorram_w)); map(0x8000, 0x87ff).mirror(0x0800).rw(FUNC(horse_state::colorram_r), FUNC(horse_state::colorram_w));
} }
void horse_state::horse_io_map(address_map &map) void horse_state::horse_io_map(address_map &map)
{ {
map(0x40, 0x47).rw("i8155", FUNC(i8155_device::io_r), FUNC(i8155_device::io_w)); map(0x40, 0x47).rw(m_i8155, FUNC(i8155_device::io_r), FUNC(i8155_device::io_w));
}
uint8_t horse_state::input_r()
{
return m_inputs[m_output >> 6 & 3]->read();
}
void horse_state::output_w(uint8_t data)
{
m_output = data;
// d4: payout related
// d6-d7: input mux
// other bits: ?
} }
@ -138,14 +145,14 @@ void horse_state::output_w(uint8_t data)
static INPUT_PORTS_START( horse ) static INPUT_PORTS_START( horse )
PORT_START("IN.0") PORT_START("IN.0")
PORT_DIPNAME( 0x07, 0x07, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW:1,2,3") PORT_DIPNAME( 0x07, 0x07, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW:1,2,3")
PORT_DIPSETTING( 0x01, DEF_STR( 1C_1C ) ) PORT_DIPSETTING( 0x01, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0x02, DEF_STR( 1C_2C ) ) PORT_DIPSETTING( 0x02, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x03, DEF_STR( 1C_3C ) ) PORT_DIPSETTING( 0x03, DEF_STR( 1C_3C ) )
PORT_DIPSETTING( 0x04, DEF_STR( 1C_4C ) ) PORT_DIPSETTING( 0x04, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0x05, DEF_STR( 1C_5C ) ) PORT_DIPSETTING( 0x05, DEF_STR( 1C_5C ) )
PORT_DIPSETTING( 0x06, DEF_STR( 1C_6C ) ) PORT_DIPSETTING( 0x06, DEF_STR( 1C_6C ) )
PORT_DIPSETTING( 0x07, DEF_STR( 1C_7C ) ) PORT_DIPSETTING( 0x07, DEF_STR( 1C_7C ) )
PORT_DIPSETTING( 0x00, "1 Coin/10 Credits" ) PORT_DIPSETTING( 0x00, "1 Coin/10 Credits" )
PORT_DIPNAME( 0x08, 0x08, "UNK04" ) PORT_DIPLOCATION("SW:4") PORT_DIPNAME( 0x08, 0x08, "UNK04" ) PORT_DIPLOCATION("SW:4")
PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) )
@ -190,30 +197,31 @@ INPUT_PORTS_END
void horse_state::horse(machine_config &config) void horse_state::horse(machine_config &config)
{ {
/* basic machine hardware */ // basic machine hardware
I8085A(config, m_maincpu, XTAL(12'000'000) / 2); I8085A(config, m_maincpu, 12_MHz_XTAL / 2);
m_maincpu->set_addrmap(AS_PROGRAM, &horse_state::horse_map); m_maincpu->set_addrmap(AS_PROGRAM, &horse_state::horse_map);
m_maincpu->set_addrmap(AS_IO, &horse_state::horse_io_map); m_maincpu->set_addrmap(AS_IO, &horse_state::horse_io_map);
i8155_device &i8155(I8155(config, "i8155", XTAL(12'000'000) / 4)); // port A input, B output, C output but unused I8155(config, m_i8155, 12_MHz_XTAL / 4); // port A input, B output, C output but unused
i8155.in_pa_callback().set(FUNC(horse_state::input_r)); m_i8155->in_pa_callback().set(FUNC(horse_state::input_r));
i8155.out_pb_callback().set(FUNC(horse_state::output_w)); m_i8155->out_pb_callback().set(FUNC(horse_state::output_w));
i8155.out_to_callback().set("speaker", FUNC(speaker_sound_device::level_w)); m_i8155->out_to_callback().set("speaker", FUNC(speaker_sound_device::level_w));
// video hardware
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(60);
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(0));
m_screen->set_size(32*8, 32*8);
m_screen->set_visarea(0*8, 32*8-1, 1*8, 31*8-1);
m_screen->set_screen_update(FUNC(horse_state::screen_update));
m_screen->screen_vblank().set_inputline(m_maincpu, I8085_RST75_LINE);
m_screen->set_palette("palette");
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
screen.set_size(32*8, 32*8);
screen.set_visarea(0*8, 32*8-1, 1*8, 31*8-1);
screen.set_screen_update(FUNC(horse_state::screen_update));
screen.screen_vblank().set_inputline(m_maincpu, I8085_RST75_LINE);
screen.set_palette("palette");
PALETTE(config, "palette", palette_device::BGR_3BIT); PALETTE(config, "palette", palette_device::BGR_3BIT);
/* sound hardware */ // sound hardware
SPEAKER(config, "mono").front_center(); SPEAKER(config, "mono").front_center();
SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25); SPEAKER_SOUND(config, "speaker").add_route(ALL_OUTPUTS, "mono", 0.25);
} }

View File

@ -105,7 +105,6 @@ private:
* Input Ports Demux & Common Routines * * Input Ports Demux & Common Routines *
****************************************/ ****************************************/
void big10_state::mux_w(uint8_t data) void big10_state::mux_w(uint8_t data)
{ {
m_mux_data = ~data; m_mux_data = ~data;
@ -138,7 +137,7 @@ void big10_state::main_map(address_map &map)
void big10_state::main_io(address_map &map) void big10_state::main_io(address_map &map)
{ {
map.global_mask(0xff); map.global_mask(0xff);
map(0x00, 0x00).r(FUNC(big10_state::mux_r)); // present in test mode map(0x00, 0x00).r(FUNC(big10_state::mux_r)); // present in test mode
map(0x02, 0x02).portr("SYSTEM"); // coins and service map(0x02, 0x02).portr("SYSTEM"); // coins and service
map(0x98, 0x9b).rw("v9938", FUNC(v9938_device::read), FUNC(v9938_device::write)); map(0x98, 0x9b).rw("v9938", FUNC(v9938_device::read), FUNC(v9938_device::write));
map(0xa0, 0xa1).w("aysnd", FUNC(ay8910_device::address_data_w)); map(0xa0, 0xa1).w("aysnd", FUNC(ay8910_device::address_data_w));
@ -157,8 +156,8 @@ static INPUT_PORTS_START( big10 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MEMORY_RESET ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MEMORY_RESET )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(2) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(2)
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) // in test mode, go to the game whilst keep pressed. PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) // in test mode, go to the game whilst keep pressed.
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) // in test mode, go to the game whilst keep pressed. PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) // "
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_IMPULSE(2) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_IMPULSE(2)
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN3 ) PORT_IMPULSE(2) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN3 ) PORT_IMPULSE(2)
@ -188,7 +187,7 @@ static INPUT_PORTS_START( big10 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big") PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small") PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
PORT_BIT( 0x70, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x70, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // in test mode triggers a sound and screen turns black, hanging the game. PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // in test mode triggers a sound and screen turns black, hanging the game.
PORT_START("IN4") PORT_START("IN4")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNKNOWN )
@ -234,12 +233,14 @@ INPUT_PORTS_END
void big10_state::big10(machine_config &config) void big10_state::big10(machine_config &config)
{ {
// basic machine hardware // basic machine hardware
Z80(config, m_maincpu, MASTER_CLOCK/6); // guess Z80(config, m_maincpu, MASTER_CLOCK/6); // guess
m_maincpu->set_addrmap(AS_PROGRAM, &big10_state::main_map); m_maincpu->set_addrmap(AS_PROGRAM, &big10_state::main_map);
m_maincpu->set_addrmap(AS_IO, &big10_state::main_io); m_maincpu->set_addrmap(AS_IO, &big10_state::main_io);
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
TICKET_DISPENSER(config, m_hopper, attotime::from_msec(HOPPER_PULSE), TICKET_MOTOR_ACTIVE_LOW, TICKET_STATUS_ACTIVE_LOW);
// video hardware // video hardware
v9938_device &v9938(V9938(config, "v9938", MASTER_CLOCK)); v9938_device &v9938(V9938(config, "v9938", MASTER_CLOCK));
v9938.set_screen_ntsc("screen"); v9938.set_screen_ntsc("screen");
@ -249,13 +250,11 @@ void big10_state::big10(machine_config &config)
// sound hardware // sound hardware
SPEAKER(config, "mono").front_center(); SPEAKER(config, "mono").front_center();
ym2149_device &aysnd(YM2149(config, "aysnd", MASTER_CLOCK/12)); // guess ym2149_device &aysnd(YM2149(config, "aysnd", MASTER_CLOCK/12)); // guess
aysnd.port_a_read_callback().set_ioport("DSW2"); aysnd.port_a_read_callback().set_ioport("DSW2");
aysnd.port_b_read_callback().set_ioport("DSW1"); aysnd.port_b_read_callback().set_ioport("DSW1");
aysnd.port_a_write_callback().set(FUNC(big10_state::mux_w)); aysnd.port_a_write_callback().set(FUNC(big10_state::mux_w));
aysnd.add_route(ALL_OUTPUTS, "mono", 0.30); aysnd.add_route(ALL_OUTPUTS, "mono", 0.30);
TICKET_DISPENSER(config, m_hopper, attotime::from_msec(HOPPER_PULSE), TICKET_MOTOR_ACTIVE_LOW, TICKET_STATUS_ACTIVE_LOW);
} }
@ -277,5 +276,5 @@ ROM_END
* Game Driver(s) * * Game Driver(s) *
**************************************/ **************************************/
/* YEAR NAME PARENT MACHINE INPUT STATE INIT ROT COMPANY FULLNAME FLAGS */ // YEAR NAME PARENT MACHINE INPUT STATE INIT ROT COMPANY FULLNAME FLAGS
GAME( 1985, big10, 0, big10, big10, big10_state, empty_init, ROT0, "Success", "Big 10", MACHINE_SUPPORTS_SAVE ) GAME( 1985, big10, 0, big10, big10, big10_state, empty_init, ROT0, "Success", "Big 10", MACHINE_SUPPORTS_SAVE )

View File

@ -1,45 +1,49 @@
// license:BSD-3-Clause // license:BSD-3-Clause
// copyright-holders:hap, Mariusz Wojcieszek // copyright-holders:hap, Mariusz Wojcieszek
/* Brazilian bootleg board from 1989. Forte II Games, Industria Brasileira. /*******************************************************************************
Brazilian bootleg board from 1989. Forte II Games, Industria Brasileira.
MAME driver by Mariusz Wojcieszek & hap, based on MAME driver by Mariusz Wojcieszek & hap, based on
information from Alexandre Souza (a.k.a. "Tabajara"). information from Alexandre Souza (a.k.a. "Tabajara").
Hardware is based on MSX1, excluding i8255 PPI: Hardware is based on MSX1, excluding i8255 PPI:
64KB RAM, largely unused - 64KB RAM, largely unused
64KB EPROM (2764-15, contains hacked BIOS and game ROM) - 64KB EPROM (2764-15, contains hacked BIOS and game ROM)
Z80 @ 3.58MHz - Z80 @ 3.58MHz
GI AY-3-8910 - GI AY-3-8910
TI TMS9928A - TI TMS9928A
(no dipswitches) - (no dipswitches)
Games:
Pesadelo (means 'nightmare' in Portuguese), 1989 bootleg of Knightmare (Majou Pesadelo (means 'nightmare' in Portuguese), 1989 bootleg of Knightmare (Majou
Densetsu in Japan) (C) 1986 Konami, originally released exclusively on MSX. Densetsu in Japan) (C) 1986 Konami, originally released exclusively on MSX.
This arcade conversion has been made a bit harder, eg. bonus power-ups deplete This arcade conversion has been made a bit harder, eg. bonus power-ups deplete
three times quicker, and the game starts at a later, more difficult level. three times quicker, and the game starts at a later, more difficult level.
A precise translation of the Brazilian Portuguese text displayed A precise translation of the Brazilian Portuguese text displayed upon
upon inserting a coin is: inserting a coin is:
NIGHTMARE DIFFICULTY-LEVEL 2 DOES NOT ACCUMULATE NIGHTMARE DIFFICULTY-LEVEL 2 DOES NOT ACCUMULATE
CREDITS , ONLY INSERT A NEW CREDITS , ONLY INSERT A NEW
COIN AFTER THE END OF THE GAME COIN AFTER THE END OF THE GAME
IN ORDER TO START THE GAME PRESS IN ORDER TO START THE GAME PRESS
THE FIRE BUTTON. THE FIRE BUTTON.
GOOD LUCK! GOOD LUCK!
If the coin detector is activated for a few seconds, an error message If the coin detector is activated for a few seconds, an error message
meaning STUCK COIN shows up blinking and beeping: FICHA PRESA (meaning STUCK COIN) shows up blinking and beeping.
FICHA PRESA
According to Alexandre, there are more games for this board, but not According to Alexandre, there are more games for this board, but not
found/dumped yet. */ found/dumped yet.
*******************************************************************************/
#include "emu.h" #include "emu.h"
#include "cpu/z80/z80.h" #include "cpu/z80/z80.h"
#include "video/tms9928a.h" #include "video/tms9928a.h"
#include "sound/ay8910.h" #include "sound/ay8910.h"
#include "screen.h" #include "screen.h"
#include "speaker.h" #include "speaker.h"
@ -49,9 +53,10 @@ namespace {
class forte2_state : public driver_device class forte2_state : public driver_device
{ {
public: public:
forte2_state(const machine_config &mconfig, device_type type, const char *tag) forte2_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_inputs(*this, "IN0")
{ } { }
void init_pesadelo(); void init_pesadelo();
@ -59,22 +64,74 @@ public:
protected: protected:
virtual void machine_start() override; virtual void machine_start() override;
virtual void machine_reset() override;
private: private:
required_device<cpu_device> m_maincpu;
required_ioport m_inputs;
u8 m_input_mask = 0xff;
u8 input_r();
void input_mask_w(u8 data);
void io_mem(address_map &map); void io_mem(address_map &map);
void program_mem(address_map &map); void program_mem(address_map &map);
uint8_t ay8910_read_input();
void ay8910_set_input_mask(uint8_t data);
required_device<cpu_device> m_maincpu;
uint8_t m_input_mask = 0;
}; };
/*******************************************************************************
Initialization
*******************************************************************************/
void forte2_state::init_pesadelo()
{
u8 *mem = memregion("maincpu")->base();
int memsize = memregion("maincpu")->bytes();
// data swap
for (int i = 0; i < memsize; i++)
{
mem[i] = bitswap<8>(mem[i],3,5,6,7,0,4,2,1);
}
// address line swap
std::vector<u8> buf(&mem[0], &mem[memsize]);
for (int i = 0; i < memsize; i++)
{
mem[bitswap<16>(i,11,9,8,13,14,15,12,7,6,5,4,3,2,1,0,10)] = buf[i];
}
}
void forte2_state::machine_start()
{
save_item(NAME(m_input_mask));
}
/*******************************************************************************
I/O
*******************************************************************************/
u8 forte2_state::input_r()
{
return m_inputs->read() | (m_input_mask & 0x7f);
}
void forte2_state::input_mask_w(u8 data)
{
// PSG reg 15, writes 0 at coin insert, 0xff at boot and game over
m_input_mask = data;
}
/*******************************************************************************
Address Maps
*******************************************************************************/
void forte2_state::program_mem(address_map &map) void forte2_state::program_mem(address_map &map)
{ {
map(0x0000, 0xbfff).rom(); map(0x0000, 0xbfff).rom();
@ -88,87 +145,62 @@ void forte2_state::io_mem(address_map &map)
map(0x98, 0x99).rw("tms9928a", FUNC(tms9928a_device::read), FUNC(tms9928a_device::write)); map(0x98, 0x99).rw("tms9928a", FUNC(tms9928a_device::read), FUNC(tms9928a_device::write));
map(0xa0, 0xa1).w("aysnd", FUNC(ay8910_device::address_data_w)); map(0xa0, 0xa1).w("aysnd", FUNC(ay8910_device::address_data_w));
map(0xa2, 0xa2).r("aysnd", FUNC(ay8910_device::data_r)); map(0xa2, 0xa2).r("aysnd", FUNC(ay8910_device::data_r));
// map(0xa8, 0xa8).ram(); // Ports a8-ab are originally for communicating with the i8255 PPI on MSX. map(0xa8, 0xab).noprw(); // no 8255
// map(0xa9, 0xab).noprw(); // Since this arcade board doesn't have one, those ports should be unmapped.
} }
/*******************************************************************************
Input Ports
*******************************************************************************/
static INPUT_PORTS_START( pesadelo ) static INPUT_PORTS_START( pesadelo )
PORT_START("IN0") PORT_START("IN0")
PORT_BIT (0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )
PORT_BIT (0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
PORT_BIT (0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
PORT_BIT (0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
PORT_BIT (0x10, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_BIT (0x20, IP_ACTIVE_LOW, IPT_START1) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT (0x40, IP_ACTIVE_LOW, IPT_UNUSED) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT (0x80, IP_ACTIVE_LOW, IPT_COIN1) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN1 )
INPUT_PORTS_END INPUT_PORTS_END
uint8_t forte2_state::ay8910_read_input()
{
return ioport("IN0")->read() | (m_input_mask & 0x3f);
}
void forte2_state::ay8910_set_input_mask(uint8_t data)
{
/* PSG reg 15, writes 0 at coin insert, 0xff at boot and game over */
m_input_mask = data;
}
void forte2_state::machine_reset()
{
m_input_mask = 0xff;
}
void forte2_state::machine_start()
{
/* register for save states */
save_item(NAME(m_input_mask));
}
/*******************************************************************************
Machine Configs
*******************************************************************************/
void forte2_state::pesadelo(machine_config &config) void forte2_state::pesadelo(machine_config &config)
{ {
/* basic machine hardware */ // basic machine hardware
Z80(config, m_maincpu, XTAL(3'579'545)); Z80(config, m_maincpu, 3.579545_MHz_XTAL);
m_maincpu->set_addrmap(AS_PROGRAM, &forte2_state::program_mem); m_maincpu->set_addrmap(AS_PROGRAM, &forte2_state::program_mem);
m_maincpu->set_addrmap(AS_IO, &forte2_state::io_mem); m_maincpu->set_addrmap(AS_IO, &forte2_state::io_mem);
/* video hardware */ // video hardware
tms9928a_device &vdp(TMS9928A(config, "tms9928a", XTAL(10'738'635))); tms9928a_device &vdp(TMS9928A(config, "tms9928a", 10.738635_MHz_XTAL));
vdp.set_screen("screen"); vdp.set_screen("screen");
vdp.set_vram_size(0x4000); vdp.set_vram_size(0x4000);
vdp.int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); vdp.int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
SCREEN(config, "screen", SCREEN_TYPE_RASTER); SCREEN(config, "screen", SCREEN_TYPE_RASTER);
/* sound hardware */ // sound hardware
SPEAKER(config, "mono").front_center(); SPEAKER(config, "mono").front_center();
ay8910_device &aysnd(AY8910(config, "aysnd", XTAL(3'579'545)/2));
aysnd.port_a_read_callback().set(FUNC(forte2_state::ay8910_read_input)); ay8910_device &aysnd(AY8910(config, "aysnd", 3.579545_MHz_XTAL/2));
aysnd.port_b_write_callback().set(FUNC(forte2_state::ay8910_set_input_mask)); aysnd.port_a_read_callback().set(FUNC(forte2_state::input_r));
aysnd.port_b_write_callback().set(FUNC(forte2_state::input_mask_w));
aysnd.add_route(ALL_OUTPUTS, "mono", 0.50); aysnd.add_route(ALL_OUTPUTS, "mono", 0.50);
} }
void forte2_state::init_pesadelo()
{
uint8_t *mem = memregion("maincpu")->base();
int memsize = memregion("maincpu")->bytes();
// data swap
for (int i = 0; i < memsize; i++)
{
mem[i] = bitswap<8>(mem[i],3,5,6,7,0,4,2,1);
}
// address line swap /*******************************************************************************
std::vector<uint8_t> buf(&mem[0], &mem[memsize]); ROM Definitions
*******************************************************************************/
for (int i = 0; i < memsize; i++)
{
mem[bitswap<16>(i,11,9,8,13,14,15,12,7,6,5,4,3,2,1,0,10)] = buf[i];
}
}
ROM_START( pesadelo ) ROM_START( pesadelo )
ROM_REGION( 0x10000, "maincpu", 0 ) ROM_REGION( 0x10000, "maincpu", 0 )
@ -178,4 +210,10 @@ ROM_END
} // anonymous namespace } // anonymous namespace
GAME( 1989, pesadelo, 0, pesadelo, pesadelo, forte2_state, init_pesadelo, ROT0, "bootleg (Forte II Games)", "Pesadelo (bootleg of Konami Knightmare)", MACHINE_SUPPORTS_SAVE )
/*******************************************************************************
Drivers
*******************************************************************************/
// YEAR NAME PARENT MACHINE INPUT CLASS INIT SCREEN COMPANY FULLNAME FLAGS
GAME( 1989, pesadelo, 0, pesadelo, pesadelo, forte2_state, init_pesadelo, ROT0, "bootleg (Forte II Games)", "Pesadelo (bootleg of Konami Knightmare)", MACHINE_SUPPORTS_SAVE )

View File

@ -219,6 +219,7 @@ static INPUT_PORTS_START( pengadvb2 ) // reads are scrambled
PORT_DIPUNKNOWN_DIPLOC(0x40, 0x40, "SW1:8") PORT_DIPUNKNOWN_DIPLOC(0x40, 0x40, "SW1:8")
INPUT_PORTS_END INPUT_PORTS_END
/*************************************************************************** /***************************************************************************
IC Interfaces IC Interfaces
@ -272,6 +273,7 @@ void pengadvb_state::ppi_port_c_w(uint8_t data)
m_kb_matrix_row = data & 0x0f; m_kb_matrix_row = data & 0x0f;
} }
/*************************************************************************** /***************************************************************************
Machine config(s) Machine config(s)