mirror of
https://github.com/holub/mame
synced 2025-06-06 04:43:45 +03:00
Initial implementation of "Dona Barata" driver (brazilian whack-a-mole style game).
This commit is contained in:
parent
adfefa9f34
commit
e573926847
332
src/mame/drivers/barata.c
Normal file
332
src/mame/drivers/barata.c
Normal file
@ -0,0 +1,332 @@
|
||||
// license:MAME|GPL-2.0+
|
||||
// copyright-holders:FelipeSanches
|
||||
/*************************************************************************
|
||||
|
||||
barata.c
|
||||
|
||||
"Dona Barata"
|
||||
|
||||
Brazilian "whack-a-mole"-style game themed after stepping on cockroaches.
|
||||
The name "Dona Barata" means "Lady Cockroach" in brazilian portuguese.
|
||||
|
||||
Manufactured by Matic: http://maticplay.com.br/
|
||||
This driver still only emulates an early prototype of the game.
|
||||
Propper dumps of the actual released game is still lacking.
|
||||
Photos on the web make us believe that there are at least 2 official
|
||||
releases of this game.
|
||||
|
||||
http://www.maticplay.com.br/equipamentos.php?equipamento=dona-barata
|
||||
http://www.valedosduendes.com.br/site/wp-content/uploads/2012/02/barata_1.jpg
|
||||
|
||||
Driver by Felipe Sanches <juca@members.fsf.org>
|
||||
|
||||
**************************************************************************
|
||||
|
||||
TO-DO:
|
||||
|
||||
* at the moment, the portbits for the rows are still a guess
|
||||
* as we don't have access to actual PCBs, the CPU clock frequency is a guess
|
||||
(but maybe it can be infered by analysing the 1ms delay routine used)
|
||||
* we don't have sound samples or background music dumps
|
||||
(i.e. we lack dumps of all of the sound memory)
|
||||
* we don't have ROM dumps of the official releases of the game
|
||||
* it would be nice to add photographic artwork to improve the layout
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
#define CPU_CLOCK (XTAL_6MHz) /* main cpu clock */
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/mcs51/mcs51.h"
|
||||
#include "sound/dac.h"
|
||||
#include "barata.lh"
|
||||
#include "rendlay.h"
|
||||
|
||||
class barata_state : public driver_device
|
||||
{
|
||||
public:
|
||||
barata_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_dac(*this, "dac") { }
|
||||
DECLARE_WRITE8_MEMBER(fpga_w);
|
||||
DECLARE_WRITE8_MEMBER(port0_w);
|
||||
DECLARE_WRITE8_MEMBER(port2_w);
|
||||
DECLARE_READ8_MEMBER(port2_r);
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<dac_device> m_dac;
|
||||
private:
|
||||
unsigned char row_selection;
|
||||
};
|
||||
|
||||
/************************
|
||||
* Input Ports *
|
||||
************************/
|
||||
|
||||
static INPUT_PORTS_START( barata )
|
||||
PORT_START("PORT1")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
/* these portbits for the cockroach button rows are still a guess */
|
||||
PORT_START("PLAYER1_ROW1")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("P1_0") PORT_CODE(KEYCODE_Q)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("P1_1") PORT_CODE(KEYCODE_W)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("P1_2") PORT_CODE(KEYCODE_E)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("P1_3") PORT_CODE(KEYCODE_R)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PLAYER1_ROW2")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("P1_4") PORT_CODE(KEYCODE_T)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("P1_5") PORT_CODE(KEYCODE_Y)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("P1_6") PORT_CODE(KEYCODE_U)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("P1_7") PORT_CODE(KEYCODE_I)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PLAYER2_ROW1")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("P2_0") PORT_CODE(KEYCODE_A)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("P2_1") PORT_CODE(KEYCODE_S)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("P2_2") PORT_CODE(KEYCODE_D)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("P2_3") PORT_CODE(KEYCODE_F)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PLAYER2_ROW2")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("P2_4") PORT_CODE(KEYCODE_G)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("P2_5") PORT_CODE(KEYCODE_H)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("P2_6") PORT_CODE(KEYCODE_J)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("P2_7") PORT_CODE(KEYCODE_K)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
INPUT_PORTS_END
|
||||
|
||||
/* BCD to Seven Segment Decoder */
|
||||
static UINT8 dec_7seg(int data)
|
||||
{
|
||||
UINT8 segment;
|
||||
switch (data)
|
||||
{
|
||||
case 0: segment = 0x3f; break;
|
||||
case 1: segment = 0x06; break;
|
||||
case 2: segment = 0x5b; break;
|
||||
case 3: segment = 0x4f; break;
|
||||
case 4: segment = 0x66; break;
|
||||
case 5: segment = 0x6d; break;
|
||||
case 6: segment = 0x7d; break;
|
||||
case 7: segment = 0x07; break;
|
||||
case 8: segment = 0x7f; break;
|
||||
case 9: segment = 0x6f; break;
|
||||
default: segment = 0x79;
|
||||
}
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
||||
#define FPGA_PLAY_BGM 0
|
||||
#define FPGA_STOP_BGM 1
|
||||
#define FPGA_PLAY_SAMPLE 2
|
||||
#define FPGA_LAMP 3
|
||||
#define FPGA_COUNTER 4
|
||||
#define FPGA_WAITING_FOR_NEW_CMD 5
|
||||
|
||||
const char* mode_strings[] = {
|
||||
"Play background music",
|
||||
"Stop background music",
|
||||
"Play sound sample",
|
||||
"Set lamp states",
|
||||
"Set counter values"
|
||||
};
|
||||
|
||||
static void fpga_send(unsigned char cmd){
|
||||
static unsigned char byte = 0;
|
||||
static unsigned char mode = FPGA_WAITING_FOR_NEW_CMD;
|
||||
static unsigned char lamp_data = 0;
|
||||
|
||||
logerror("FPGA CMD: %d\n", cmd);
|
||||
|
||||
if (mode == FPGA_WAITING_FOR_NEW_CMD){
|
||||
if (cmd < FPGA_WAITING_FOR_NEW_CMD){
|
||||
mode = cmd;
|
||||
byte=1;
|
||||
logerror("SET FPGA MODE: %s\n", mode_strings[mode]);
|
||||
|
||||
if (mode == FPGA_PLAY_BGM){
|
||||
logerror("PLAY_BGM.\n");
|
||||
mode = FPGA_WAITING_FOR_NEW_CMD;
|
||||
}
|
||||
|
||||
if (mode == FPGA_STOP_BGM){
|
||||
logerror("STOP_BGM.\n");
|
||||
mode = FPGA_WAITING_FOR_NEW_CMD;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool state, erase_all;
|
||||
char lamp_index;
|
||||
if (mode == FPGA_LAMP){
|
||||
switch (byte){
|
||||
case 1:
|
||||
lamp_data = cmd;
|
||||
break;
|
||||
case 2:
|
||||
lamp_data = (lamp_data << 3) | cmd;
|
||||
state = BIT(lamp_data,5);
|
||||
erase_all = BIT(lamp_data,4);
|
||||
lamp_index = lamp_data & 0x0F;
|
||||
|
||||
if (erase_all){
|
||||
// logerror("LED: ERASE ALL\n");
|
||||
for (int i=0; i<16; i++){
|
||||
output_set_led_value(i, 1);
|
||||
}
|
||||
} else {
|
||||
output_set_led_value(lamp_index, state ? 0 : 1);
|
||||
}
|
||||
default:
|
||||
mode = FPGA_WAITING_FOR_NEW_CMD;
|
||||
break;
|
||||
}
|
||||
byte++;
|
||||
return;
|
||||
}
|
||||
|
||||
static unsigned char counter_bank = 0;
|
||||
static unsigned char counter_data = 0;
|
||||
static bool counter_state = false;
|
||||
if (mode == FPGA_COUNTER){
|
||||
//logerror("FPGA_COUNTER byte:%d cmd:%d\n", byte, cmd);
|
||||
switch (byte){
|
||||
case 1:
|
||||
counter_bank = BIT(cmd,2);
|
||||
counter_state = BIT(cmd,1);
|
||||
counter_data = (cmd & 1);
|
||||
break;
|
||||
case 2:
|
||||
counter_data = (counter_data << 3) | cmd;
|
||||
break;
|
||||
case 3:
|
||||
counter_data = (counter_data << 3) | cmd;
|
||||
|
||||
if (counter_state){
|
||||
output_set_digit_value(2*counter_bank, 0);
|
||||
output_set_digit_value(2*counter_bank+1, 0);
|
||||
} else {
|
||||
output_set_digit_value(2*counter_bank, dec_7seg(counter_data/10));
|
||||
output_set_digit_value(2*counter_bank+1, dec_7seg(counter_data%10));
|
||||
}
|
||||
default:
|
||||
mode = FPGA_WAITING_FOR_NEW_CMD;
|
||||
break;
|
||||
}
|
||||
byte++;
|
||||
return;
|
||||
}
|
||||
|
||||
static unsigned char sample_index = 0;
|
||||
if (mode == FPGA_PLAY_SAMPLE){
|
||||
switch (byte){
|
||||
case 1:
|
||||
sample_index = cmd;
|
||||
break;
|
||||
case 2:
|
||||
sample_index = (sample_index << 3) | cmd;
|
||||
logerror("PLAY_SAMPLE #%d.\n", sample_index);
|
||||
default:
|
||||
mode = FPGA_WAITING_FOR_NEW_CMD;
|
||||
break;
|
||||
}
|
||||
byte++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(barata_state::fpga_w)
|
||||
{
|
||||
static unsigned char old_data = 0;
|
||||
if (!BIT(old_data, 5) and BIT(data, 5)){
|
||||
//process the command sent to the FPGA
|
||||
fpga_send((data >> 2) & 7);
|
||||
}
|
||||
old_data = data;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(barata_state::port0_w)
|
||||
{
|
||||
row_selection = data;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(barata_state::port2_w)
|
||||
{
|
||||
/* why does it write to PORT2 ? */
|
||||
}
|
||||
|
||||
READ8_MEMBER(barata_state::port2_r)
|
||||
{
|
||||
if (!BIT(row_selection, 0)) return ioport("PLAYER1_ROW1")->read();
|
||||
if (!BIT(row_selection, 1)) return ioport("PLAYER1_ROW2")->read();
|
||||
if (!BIT(row_selection, 2)) return ioport("PLAYER2_ROW1")->read();
|
||||
if (!BIT(row_selection, 3)) return ioport("PLAYER2_ROW2")->read();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************
|
||||
* Memory Map Information *
|
||||
*************************/
|
||||
|
||||
static ADDRESS_MAP_START( i8051_io_port, AS_IO, 8, barata_state )
|
||||
AM_RANGE(MCS51_PORT_P0, MCS51_PORT_P0 ) AM_WRITE(port0_w)
|
||||
AM_RANGE(MCS51_PORT_P1, MCS51_PORT_P1 ) AM_READ_PORT("PORT1")
|
||||
AM_RANGE(MCS51_PORT_P2, MCS51_PORT_P2 ) AM_READWRITE(port2_r, port2_w)
|
||||
AM_RANGE(MCS51_PORT_P3, MCS51_PORT_P3 ) AM_WRITE(fpga_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
/************************
|
||||
* Machine Drivers *
|
||||
************************/
|
||||
|
||||
static MACHINE_CONFIG_START( barata, barata_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD("maincpu", I8051, CPU_CLOCK)
|
||||
MCFG_CPU_IO_MAP(i8051_io_port)
|
||||
|
||||
MCFG_DEFAULT_LAYOUT( layout_barata )
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_DAC_ADD("dac")
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.55)
|
||||
|
||||
/* TODO: add sound samples */
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
/*************************
|
||||
* Rom Load *
|
||||
*************************/
|
||||
|
||||
ROM_START( barata )
|
||||
ROM_REGION( 0x1000, "maincpu", 0 )
|
||||
ROM_LOAD( "barata.bin", 0x0000, 0x06a8, CRC(a5b68617) SHA1(4c7cd7c494d20236732c8d1f2b2904bfe99f5252) )
|
||||
ROM_END
|
||||
|
||||
/*************************
|
||||
* Game Drivers *
|
||||
*************************/
|
||||
GAME( 2002, barata, 0, barata, barata, driver_device, 0, ROT0, "Eletro Matic Equipamentos Eletromecânicos", "Dona Barata (early prototype)", GAME_IMPERFECT_GRAPHICS )
|
71
src/mame/layout/barata.lay
Normal file
71
src/mame/layout/barata.lay
Normal file
@ -0,0 +1,71 @@
|
||||
<?xml version="1.0"?>
|
||||
<mamelayout version="2">
|
||||
<element name="digit" defstate="0">
|
||||
<led7seg>
|
||||
<color red="0.75" green="0.0" blue="0.0" />
|
||||
</led7seg>
|
||||
</element>
|
||||
<element name="red_led">
|
||||
<disk><color red="1.0" green="0.0" blue="0.0" /></disk>
|
||||
</element>
|
||||
<element name="background">
|
||||
<rect>
|
||||
<bounds left="0" top="0" right="1" bottom="1" />
|
||||
<color red="0.0" green="0.0" blue="0.0" />
|
||||
</rect>
|
||||
</element>
|
||||
|
||||
<view name="Default Layout">
|
||||
<!-- Black background -->
|
||||
<bezel element="background">
|
||||
<bounds left="97" top="95" right="428" bottom="250" />
|
||||
</bezel>
|
||||
<bezel name="digit0" element="digit">
|
||||
<bounds left="107" top="105" right="155" bottom="185" />
|
||||
</bezel>
|
||||
<bezel name="digit1" element="digit">
|
||||
<bounds left="155" top="105" right="203" bottom="185" />
|
||||
</bezel>
|
||||
<bezel name="digit2" element="digit">
|
||||
<bounds left="323" top="105" right="370" bottom="185" />
|
||||
</bezel>
|
||||
<bezel name="digit3" element="digit">
|
||||
<bounds left="371" top="105" right="418" bottom="185" />
|
||||
</bezel>
|
||||
|
||||
<bezel name="led0" element="red_led">
|
||||
<bounds left="124" right="129" top="205" bottom="210" /></bezel>
|
||||
<bezel name="led1" element="red_led">
|
||||
<bounds left="134" right="139" top="205" bottom="210" /></bezel>
|
||||
<bezel name="led2" element="red_led">
|
||||
<bounds left="144" right="149" top="205" bottom="210" /></bezel>
|
||||
<bezel name="led3" element="red_led">
|
||||
<bounds left="154" right="159" top="205" bottom="210" /></bezel>
|
||||
<bezel name="led4" element="red_led">
|
||||
<bounds left="164" right="169" top="205" bottom="210" /></bezel>
|
||||
<bezel name="led5" element="red_led">
|
||||
<bounds left="174" right="179" top="205" bottom="210" /></bezel>
|
||||
<bezel name="led6" element="red_led">
|
||||
<bounds left="184" right="189" top="205" bottom="210" /></bezel>
|
||||
<bezel name="led7" element="red_led">
|
||||
<bounds left="194" right="199" top="205" bottom="210" /></bezel>
|
||||
|
||||
<bezel name="led8" element="red_led">
|
||||
<bounds left="324" right="329" top="205" bottom="210" /></bezel>
|
||||
<bezel name="led9" element="red_led">
|
||||
<bounds left="334" right="339" top="205" bottom="210" /></bezel>
|
||||
<bezel name="led10" element="red_led">
|
||||
<bounds left="344" right="349" top="205" bottom="210" /></bezel>
|
||||
<bezel name="led11" element="red_led">
|
||||
<bounds left="354" right="359" top="205" bottom="210" /></bezel>
|
||||
<bezel name="led12" element="red_led">
|
||||
<bounds left="364" right="369" top="205" bottom="210" /></bezel>
|
||||
<bezel name="led13" element="red_led">
|
||||
<bounds left="374" right="379" top="205" bottom="210" /></bezel>
|
||||
<bezel name="led14" element="red_led">
|
||||
<bounds left="384" right="389" top="205" bottom="210" /></bezel>
|
||||
<bezel name="led15" element="red_led">
|
||||
<bounds left="394" right="399" top="205" bottom="210" /></bezel>
|
||||
|
||||
</view>
|
||||
</mamelayout>
|
@ -31845,6 +31845,8 @@ strike
|
||||
|
||||
/* Below are misc lazy adds, or yet to be sorted out... */
|
||||
|
||||
barata
|
||||
|
||||
cspin2
|
||||
caprcyc
|
||||
|
||||
|
@ -706,6 +706,7 @@ DRVLIBS += \
|
||||
$(MAMEOBJ)/jpm.a \
|
||||
$(MAMEOBJ)/kaneko.a \
|
||||
$(MAMEOBJ)/konami.a \
|
||||
$(MAMEOBJ)/matic.a \
|
||||
$(MAMEOBJ)/maygay.a \
|
||||
$(MAMEOBJ)/meadows.a \
|
||||
$(MAMEOBJ)/merit.a \
|
||||
@ -1430,6 +1431,8 @@ $(MAMEOBJ)/konami.a: \
|
||||
$(VIDEO)/k001005.o \
|
||||
$(VIDEO)/k001604.o \
|
||||
|
||||
$(MAMEOBJ)/matic.a: \
|
||||
$(DRIVERS)/barata.o
|
||||
|
||||
$(MAMEOBJ)/maygay.a: \
|
||||
$(DRIVERS)/maygay1b.o \
|
||||
@ -2527,6 +2530,8 @@ $(DRIVERS)/avalnche.o: $(LAYOUT)/avalnche.lh
|
||||
|
||||
$(DRIVERS)/balsente.o: $(LAYOUT)/stocker.lh
|
||||
|
||||
$(DRIVERS)/barata.o: $(LAYOUT)/barata.lh
|
||||
|
||||
$(DRIVERS)/beaminv.o: $(LAYOUT)/beaminv.lh
|
||||
|
||||
$(DRIVERS)/bfm_sc1.o: $(LAYOUT)/sc1_vfd.lh \
|
||||
|
Loading…
Reference in New Issue
Block a user