various reorganization of radica and vtech stuff (#3108)

* various reorganization of radica and vtech stuff

* missed this (nw)

* correct file (nw)

* newlines and stuff (nw)

* less c_str (nw)

* worse (IMHO) filenames (nw)

* format got messed up (nw)

* some bits for golden tee (nw)

* get us renderng something in rad_gtg (nw)

* some basic inputs (nw)

* further improvements to the Golden Tee Home Edition (radica eu3a14)

added Radica Sensible Soccer [Sean Riddle]

* tilebase handling (nw)

* golden tee home video improvements (nw)
This commit is contained in:
David Haywood 2018-01-25 03:00:14 +00:00 committed by ajrhacker
parent 9f5c4c5ceb
commit c3709b0558
25 changed files with 1865 additions and 721 deletions

View File

@ -31246,30 +31246,6 @@ Notice that these are not working on real hardware due to bugged code with VDP i
</part>
</software>
<software name="radicav1">
<description>Radica: Volume 1 (USA)</description>
<year>2004</year>
<publisher>Radica Games ~ Sega</publisher>
<part name="cart" interface="megadriv_cart">
<feature name="slot" value="rom_radica"/>
<dataarea name="rom" width="16" endianness="big" size="4194304">
<rom name="radicav1.bin" size="4194304" crc="3b4c8438" sha1="5ed9c053f9ebc8d4bf571d57e562cf347585d158" offset="0x000000" loadflag="load16_word_swap"/>
</dataarea>
</part>
</software>
<software name="radicasf">
<description>Radica: Street Fighter Pack (Euro)</description>
<year>2004</year>
<publisher>Radica Games ~ Capcom</publisher>
<part name="cart" interface="megadriv_cart">
<feature name="slot" value="rom_radica"/>
<dataarea name="rom" width="16" endianness="big" size="4194304">
<rom name="radicasf.bin" size="4194304" crc="868afb44" sha1="f4339e36272c18b1d49aa4095127ed18e0961df6" offset="0x000000" loadflag="load16_word_swap"/>
</dataarea>
</part>
</software>
<software name="tomclown">
<description>Tom Clown (USA)</description>
<year>1993</year>
@ -32901,6 +32877,4 @@ This dump is either a bad dump or a wrongly patched one.
</dataarea>
</part>
</software>
</softwarelist>

View File

@ -3182,8 +3182,8 @@ files {
MAME_DIR .. "src/mame/machine/segabb.h",
MAME_DIR .. "src/mame/machine/megadriv.cpp",
MAME_DIR .. "src/mame/includes/megadriv.h",
MAME_DIR .. "src/mame/drivers/megadrvb.cpp",
MAME_DIR .. "src/mame/includes/megadrvb.h",
MAME_DIR .. "src/mame/drivers/megadriv_acbl.cpp",
MAME_DIR .. "src/mame/includes/megadriv_acbl.h",
MAME_DIR .. "src/mame/drivers/megaplay.cpp",
MAME_DIR .. "src/mame/drivers/megatech.cpp",
MAME_DIR .. "src/mame/drivers/calcune.cpp",

View File

@ -2836,6 +2836,8 @@ files {
MAME_DIR .. "src/mame/machine/gdrom.h",
MAME_DIR .. "src/mame/drivers/megadriv.cpp",
MAME_DIR .. "src/mame/includes/megadriv.h",
MAME_DIR .. "src/mame/drivers/megadriv_rad.cpp",
MAME_DIR .. "src/mame/includes/megadriv_rad.h",
MAME_DIR .. "src/mame/drivers/segapico.cpp",
MAME_DIR .. "src/mame/drivers/sega_sawatte.cpp",
MAME_DIR .. "src/mame/drivers/segapm.cpp",
@ -3367,6 +3369,10 @@ files {
MAME_DIR .. "src/mame/drivers/crvision.cpp",
MAME_DIR .. "src/mame/includes/crvision.h",
MAME_DIR .. "src/mame/drivers/geniusiq.cpp",
MAME_DIR .. "src/mame/drivers/vtech_unk1.cpp",
MAME_DIR .. "src/mame/drivers/vtech_unk2.cpp",
MAME_DIR .. "src/mame/drivers/vtech_eu3a12.cpp",
MAME_DIR .. "src/mame/drivers/iqunlim.cpp",
MAME_DIR .. "src/mame/drivers/laser3k.cpp",
MAME_DIR .. "src/mame/drivers/lcmate2.cpp",
MAME_DIR .. "src/mame/drivers/pc4.cpp",
@ -3614,7 +3620,12 @@ files {
MAME_DIR .. "src/mame/drivers/qvt201.cpp",
MAME_DIR .. "src/mame/drivers/qvt6800.cpp",
MAME_DIR .. "src/mame/drivers/rd100.cpp",
MAME_DIR .. "src/mame/drivers/radicasi.cpp",
MAME_DIR .. "src/mame/drivers/rad_eu3a14.cpp",
MAME_DIR .. "src/mame/drivers/rad_eu3a05.cpp",
MAME_DIR .. "src/mame/audio/rad_eu3a05.cpp",
MAME_DIR .. "src/mame/audio/rad_eu3a05.h",
MAME_DIR .. "src/mame/machine/rad_eu3a05gpio.cpp",
MAME_DIR .. "src/mame/machine/rad_eu3a05gpio.h",
MAME_DIR .. "src/mame/drivers/rvoice.cpp",
MAME_DIR .. "src/mame/drivers/sacstate.cpp",
MAME_DIR .. "src/mame/drivers/sartorius.cpp",

View File

@ -229,7 +229,7 @@ const double XTAL::known_xtals[] = {
21'052'600, /* NEC PC-98xx pixel clock */
21'060'000, /* HP 264x display clock (60 Hz configuration) */
21'254'400, /* TeleVideo 970 132-column display clock */
21'281'370, /* Radica Tetris */
21'281'370, /* Radica Tetris (PAL) */
21'300'000,
21'477'272, /* BMC bowling, some Data East 90's games, Vtech Socrates; (6x NTSC subcarrier) */
22'000'000,

View File

@ -694,7 +694,7 @@ mcr68.cpp
meadows.cpp
meadwttl.cpp
mediagx.cpp
megadrvb.cpp
megadriv_acbl.cpp
megaphx.cpp
megaplay.cpp
megasys1.cpp

View File

@ -0,0 +1,266 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
// Format not understood, it is not OKI ADPCM or IMA ADPCM, maybe something more basic?
#include "emu.h"
#include "rad_eu3a05.h"
DEFINE_DEVICE_TYPE(RADICA6502_SOUND, radica6502_sound_device, "radica6502sound", "Radica 6502 Sound")
radica6502_sound_device::radica6502_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, RADICA6502_SOUND, tag, owner, clock)
, device_sound_interface(mconfig, *this)
, m_stream(nullptr)
, m_space_read_cb(*this)
{
}
void radica6502_sound_device::device_start()
{
m_space_read_cb.resolve_safe(0);
m_stream = stream_alloc(0, 1, 8000);
}
void radica6502_sound_device::device_reset()
{
for (int i = 0; i < 6; i++)
{
m_sound_byte_address[i] = 0;
m_sound_byte_len[i] = 0;
m_sound_current_nib_pos[i] = 0;
}
m_isstopped = 0x3f;
}
//-------------------------------------------------
// sound_stream_update - handle a stream update
//-------------------------------------------------
void radica6502_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
// reset the output stream
memset(outputs[0], 0, samples * sizeof(*outputs[0]));
int outpos = 0;
// loop while we still have samples to generate
while (samples-- != 0)
{
for (int channel = 0; channel < 6; channel++)
{
if (!((m_isstopped >> channel) & 1))
{
//logerror("m_isstopped %02x channel %d is active %08x %06x\n", m_isstopped, channel, m_sound_byte_address[channel], m_sound_current_nib_pos[channel]);
int readoffset = m_sound_byte_address[channel] + (m_sound_current_nib_pos[channel] / 2);
int nibble = m_space_read_cb(readoffset);
nibble = nibble >> ((m_sound_current_nib_pos[channel] & 1) ? 0 : 4);
nibble &= 0x0f;
// it's actually some form of ADPCM? but apparently NOT the OKI ADPCM
if (nibble & 0x08)
nibble -= 0x10;
outputs[0][outpos] += nibble * 0x100;
m_sound_current_nib_pos[channel]++;
if (m_sound_current_nib_pos[channel] >= m_sound_byte_len[channel] * 2)
{
m_sound_current_nib_pos[channel] = 0;
m_isstopped |= (1 << channel);
// maybe should generate an interrupt with vector
// ffb8, ffbc, ffc0, ffc4, ffc8, or ffcc depending on which channel finished??
}
}
else
{
//logerror("m_isstopped %02x channel %d is NOT active %08x %06x\n", m_isstopped, channel, m_sound_byte_address[channel], m_sound_current_nib_pos[channel]);
}
}
outpos++;
}
}
void radica6502_sound_device::handle_sound_addr_w(int which, int offset, uint8_t data)
{
switch (offset)
{
case 0x00:
m_sound_byte_address[which] = (m_sound_byte_address[which] & 0xffff00) | (data<<0);
logerror("%s: sound_0 (%d) write lo address %02x (real address is now %08x)\n", machine().describe_context(), which, data, m_sound_byte_address[which]);
break;
case 0x01:
m_sound_byte_address[which] = (m_sound_byte_address[which] & 0xff00ff) | (data<<8);
logerror("%s: sound_0 (%d) write md address %02x (real address is now %08x)\n", machine().describe_context(), which, data, m_sound_byte_address[which]);
break;
case 0x02:
m_sound_byte_address[which] = (m_sound_byte_address[which] & 0x00ffff) | (data<<16);
logerror("%s: sound_0 (%d) write hi address %02x (real address is now %08x)\n", machine().describe_context(), which, data, m_sound_byte_address[which]);
break;
}
}
uint8_t radica6502_sound_device::handle_sound_addr_r(int which, int offset)
{
switch (offset)
{
case 0x00:
logerror("%s: sound_0 (%d) read lo address\n", machine().describe_context(), which);
return (m_sound_byte_address[which]>>0) & 0xff;
case 0x01:
logerror("%s: sound_0 (%d) read mid address\n", machine().describe_context(), which);
return (m_sound_byte_address[which]>>8) & 0xff;
case 0x02:
logerror("%s: sound_0 (%d) read hi address\n", machine().describe_context(), which);
return (m_sound_byte_address[which]>>16) & 0xff;
}
return 0x00;
}
WRITE8_MEMBER(radica6502_sound_device::radicasi_sound_addr_w)
{
m_stream->update();
handle_sound_addr_w(offset / 3, offset % 3, data);
}
READ8_MEMBER(radica6502_sound_device::radicasi_sound_addr_r)
{
m_stream->update();
return handle_sound_addr_r(offset / 3, offset % 3);
}
void radica6502_sound_device::handle_sound_size_w(int which, int offset, uint8_t data)
{
switch (offset)
{
case 0x00:
m_sound_byte_len[which] = (m_sound_byte_len[which] & 0xffff00) | (data<<0);
logerror("%s: sound_1 (%d) write lo size %02x (real size is now %08x)\n", machine().describe_context(), which, data, m_sound_byte_len[which]);
break;
case 0x01:
m_sound_byte_len[which] = (m_sound_byte_len[which] & 0xff00ff) | (data<<8);
logerror("%s: sound_1 (%d) write md size %02x (real size is now %08x)\n", machine().describe_context(), which, data, m_sound_byte_len[which]);
break;
case 0x02:
m_sound_byte_len[which] = (m_sound_byte_len[which] & 0x00ffff) | (data<<16);
logerror("%s: sound_1 (%d) write hi size %02x (real size is now %08x)\n", machine().describe_context(), which, data, m_sound_byte_len[which]);
break;
}
}
uint8_t radica6502_sound_device::handle_sound_size_r(int which, int offset)
{
switch (offset)
{
case 0x00:
logerror("%s: sound_1 (%d) read lo size\n", machine().describe_context(), which);
return (m_sound_byte_len[which]>>0) & 0xff;
case 0x01:
logerror("%s: sound_1 (%d) read mid size\n", machine().describe_context(), which);
return (m_sound_byte_len[which]>>8) & 0xff;
case 0x02:
logerror("%s: sound_1 (%d) read hi size\n", machine().describe_context(), which);
return (m_sound_byte_len[which]>>16) & 0xff;
}
return 0x00;
}
WRITE8_MEMBER(radica6502_sound_device::radicasi_sound_size_w)
{
m_stream->update();
handle_sound_size_w(offset / 3, offset % 3, data);
}
READ8_MEMBER(radica6502_sound_device::radicasi_sound_size_r)
{
m_stream->update();
return handle_sound_size_r(offset / 3, offset % 3);
}
READ8_MEMBER(radica6502_sound_device::radicasi_sound_trigger_r)
{
m_stream->update();
logerror("%s: sound read from trigger?\n", machine().describe_context());
return m_sound_trigger;
}
WRITE8_MEMBER(radica6502_sound_device::radicasi_sound_trigger_w)
{
m_stream->update();
logerror("%s: sound write to trigger? %02x\n", machine().describe_context(), data);
m_sound_trigger = data;
for (int i = 0; i < 6; i++)
{
int bit = (data >> i) & 1;
if (bit)
handle_sound_trigger(i);
}
if (data & 0xc0)
logerror(" UNEXPECTED BITS SET");
}
/* this is read/written with the same individual bits for each channel as the trigger
maybe related to interrupts? */
READ8_MEMBER(radica6502_sound_device::radicasi_sound_unk_r)
{
logerror("%s: radicasi_sound_unk_r\n", machine().describe_context());
// don't think this reads back what was written probably a status of something instead?
return 0x00; //m_sound_unk;
}
WRITE8_MEMBER(radica6502_sound_device::radicasi_sound_unk_w)
{
logerror("%s: radicasi_sound_unk_w %02x\n", machine().describe_context(), data);
for (int i = 0; i < 6; i++)
{
int bit = (data >> i) & 1;
if (bit)
logerror("(unknown operation on channel %d)\n", i);
}
m_sound_unk = data;
if (data & 0xc0)
logerror(" UNEXPECTED BITS SET");
}
void radica6502_sound_device::handle_sound_trigger(int which)
{
logerror("Triggering operation on channel (%d) with params %08x %08x\n", which, m_sound_byte_address[which], m_sound_byte_len[which]);
m_sound_current_nib_pos[which] = 0;
m_isstopped &= ~(1 << which);
}
READ8_MEMBER(radica6502_sound_device::radicasi_50a8_r)
{
m_stream->update();
logerror("%s: radicasi_50a8_r\n", machine().describe_context());
return m_isstopped;
}

View File

@ -0,0 +1,64 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
#ifndef MAME_AUDIO_RAD_EU3A05_H
#define MAME_AUDIO_RAD_EU3A05_H
#define MCFG_RADICA6502_SOUND_SPACE_READ_CB(_devcb) \
devcb = &radica6502_sound_device::set_space_read_callback(*device, DEVCB_##_devcb);
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> radica6502_sound_device
class radica6502_sound_device : public device_t, public device_sound_interface
{
public:
radica6502_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template <class Object> static devcb_base &set_space_read_callback(device_t &device, Object &&cb) { return downcast<radica6502_sound_device &>(device).m_space_read_cb.set_callback(std::forward<Object>(cb)); }
DECLARE_WRITE8_MEMBER(radicasi_sound_addr_w);
DECLARE_READ8_MEMBER(radicasi_sound_addr_r);
DECLARE_WRITE8_MEMBER(radicasi_sound_size_w);
DECLARE_READ8_MEMBER(radicasi_sound_size_r);
DECLARE_READ8_MEMBER(radicasi_sound_trigger_r);
DECLARE_WRITE8_MEMBER(radicasi_sound_trigger_w);
DECLARE_READ8_MEMBER(radicasi_sound_unk_r);
DECLARE_WRITE8_MEMBER(radicasi_sound_unk_w);
DECLARE_READ8_MEMBER(radicasi_50a8_r);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
private:
sound_stream *m_stream;
devcb_read8 m_space_read_cb;
uint32_t m_sound_byte_address[6];
uint32_t m_sound_byte_len[6];
uint32_t m_sound_current_nib_pos[6];
uint8_t m_sound_trigger;
uint8_t m_sound_unk;
uint8_t m_isstopped;
void handle_sound_trigger(int which);
void handle_sound_addr_w(int which, int offset, uint8_t data);
uint8_t handle_sound_addr_r(int which, int offset);
void handle_sound_size_w(int which, int offset, uint8_t data);
uint8_t handle_sound_size_r(int which, int offset);
};
DECLARE_DEVICE_TYPE(RADICA6502_SOUND, radica6502_sound_device)
#endif // MAME_AUDIO_RAD_EU3A05_H

View File

@ -148,87 +148,6 @@ PCB - German Version:
+------+ +--------------------------------------+ +-----------------------------------+ +----------+
IQ Unlimited - GERMAN:
+------------------------------------------------------------------------------+
| |
+-----+ |
| |
| |
| |
| +----+ +---+ |
| | A2 | +----+ | | |
| | | | A4 | |A1 | +-+ |
| +----+ +----+ | | | | |
| | | +-+ |
| | | |
| +---+ +--+
| |
| +-------+ |
+--+ |65C5L5K| +----+
| | HC374 | |
+--+ +----------+ +-------+ +--+
| |DragonBall| |
| C +----+ |EZ | +-------+ C |
| A | A3 | | | |65C5L5K| A |
| R +----+ |LSC414328P| | HC374 | R |
| T |U16 IJ75C| +-------+ T |
| R | HHAV984S | R |
| I +----------+ I |
| D CARD 1 +------------+ CARD 0 D |
| G | AM29F0400 | G |
| E | | +------+ +--------+ E |
| +------------+ | LGS | |LHMN5KR7| |
| S | | | | S |
| L |GM71C1| | 1998 | L |
| O GER |8163CJ| | | O |
| T 038 |6 | |27-06126| T |
| | | |-007 | |
+--+ | | | | +--+
| | | | VTECH | |
| +------+ +--------+ |
| 35-19600-200 703139-G|
+-------------------------------------------------------------------------+
A1 = 98AHCLT / 27-05992-0-0 / VTech
A2 = 9932 HBL / C807U-1442 / 35016B / Japan
A3 = ACT139
A4 = MAX232
Leader 8008 CX (German version)
+---+-----------+-----+-----------------------+-----+-----+-----+
| |SERIAL PORT| |PARALLEL PORT (PRINTER)| |MOUSE| |
| +-----------+ +-----------------------+ +-----+ |
| |
| |
| |
| |
| +----+ |
| | A0 | |
| +----+ |
| |
| |
| +--------+ |
| | | |
| CPU | VTECH | +------+ |
| |LHMV5GNS| | | |
| | | |GM76U8| |
| |1999 | |128CLF| |
| |27-6393-| |W85 | |
| +-----------+ |11 | | | |
| |27-6296-0-0| | | | | |
| |47C241M NH7| | | +------+ |
| +-----------+ +--------+ |
| |
| |
| |
| |
+---------------------------------------------------------------+
CPU = epoxy blob
GM76U8128CLFW85 = LGS / Hynix 131,072 WORDS x 8 BIT CMOS SRAM
TMP47C241MG = TCLS-47 series 4-bit CPU with 2048x8 internal ROM
****************************************************************************/
@ -312,19 +231,6 @@ private:
} m_keyboard;
};
class gl8008cx_state : public driver_device
{
public:
gl8008cx_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu")
{ }
required_device<cpu_device> m_maincpu;
virtual uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void gl8008cx(machine_config &config);
};
PALETTE_INIT_MEMBER(geniusiq_state, geniusiq)
{
@ -353,10 +259,6 @@ PALETTE_INIT_MEMBER(geniusiq_state, geniusiq)
palette.set_pen_color(i, palette_val[i*3], palette_val[i*3+1], palette_val[i*3+2]);
}
uint32_t gl8008cx_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
return 0;
}
uint32_t geniusiq_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
@ -511,10 +413,6 @@ INPUT_CHANGED_MEMBER( geniusiq_state::send_input )
queue_input(data);
}
static ADDRESS_MAP_START(gl8008cx_mem, AS_PROGRAM, 16, gl8008cx_state)
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x000000, 0x1FFFFF) AM_ROM
ADDRESS_MAP_END
static ADDRESS_MAP_START(geniusiq_mem, AS_PROGRAM, 16, geniusiq_state)
ADDRESS_MAP_UNMAP_HIGH
@ -743,8 +641,6 @@ static INPUT_PORTS_START( geniusiq_de )
PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_1 ) PORT_CHAR('1') PORT_CHAR('!') PORT_CHANGED_MEMBER( DEVICE_SELF, geniusiq_state, send_input, 0x66 )
INPUT_PORTS_END
static INPUT_PORTS_START( gl8008cx )
INPUT_PORTS_END
void geniusiq_state::machine_start()
{
@ -831,20 +727,6 @@ MACHINE_CONFIG_DERIVED(geniusiq_state::iqtv512, iq128)
MCFG_AMD_29F040_ADD("flash")
MACHINE_CONFIG_END
MACHINE_CONFIG_START(gl8008cx_state::gl8008cx)
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", M68000, XTAL(32'000'000)/2) // TODO wrong CPU and frequency
MCFG_CPU_PROGRAM_MAP(gl8008cx_mem)
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(50)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
MCFG_SCREEN_SIZE(512, 256)
MCFG_SCREEN_VISIBLE_AREA(0, 512-1, 0, 256-1)
MCFG_SCREEN_UPDATE_DRIVER( gl8008cx_state, screen_update )
MACHINE_CONFIG_END
/* ROM definition */
ROM_START( iq128 )
@ -862,45 +744,15 @@ ROM_START( iqtv512 )
ROM_LOAD( "27-06171-000.bin", 0x0000, 0x200000, CRC(2597af70) SHA1(9db8151a84517407d380424410b6fa0003ceb1eb) )
ROM_END
ROM_START( gl8008cx )
ROM_REGION(0x200000, "maincpu", 0)
ROM_LOAD( "27-6393-11.u1", 0x0000, 0x200000, CRC(fd49db46) SHA1(fc55bb31f42068f9d6cc8e2c2f419c3c4edb4fe6) )
ROM_REGION(0x800, "subcpu", 0)
ROM_LOAD( "27-6296-0-0.u3", 0x000, 0x800, NO_DUMP )
ROM_END
ROM_START( bs9009cx )
ROM_REGION(0x200000, "maincpu", 0)
ROM_LOAD( "27-6603-01.u1", 0x0000, 0x200000, CRC(2c299f65) SHA1(44b37007a7c4087d7c2bd8c24907402bfe445ba4) )
ROM_REGION(0x800, "subcpu", 0)
ROM_LOAD( "mcu.u5", 0x000, 0x800, NO_DUMP )
ROM_END
ROM_START( itunlim )
ROM_REGION(0x200000, "maincpu", 0)
ROM_LOAD( "27-06124-002.u3", 0x000000, 0x200000, CRC(0c0753ce) SHA1(d22504d583ca8d6a9d2f56fbaa3e1d52c442a1e9) )
ROM_END
ROM_START( iqunlim )
ROM_REGION(0x200000, "maincpu", 0)
ROM_LOAD16_WORD_SWAP( "27-06126-007.bin", 0x000000, 0x200000, CRC(af38c743) SHA1(5b91748536905812e6de7145638699acb375865a) )
ROM_END
ROM_START( glmmc )
ROM_REGION(0x200000, "maincpu", 0)
ROM_LOAD( "27-5889-00.bin", 0x000000, 0x080000, CRC(5e2c6359) SHA1(cc01c7bd5c87224b63dd1044db5a36a5cb7824f1) )
ROM_END
/* Driver */
// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS
COMP( 1997, iq128, 0, 0, iq128, geniusiq_de, geniusiq_state, 0, "Video Technology", "Genius IQ 128 (Germany)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 1997, iq128_fr, iq128, 0, iq128, geniusiq, geniusiq_state, 0, "Video Technology", "Genius IQ 128 (France)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 1998, iqtv512, 0, 0, iqtv512, geniusiq_de, geniusiq_state, 0, "Video Technology", "Genius IQ TV 512 (Germany)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 1999, gl8008cx, 0, 0, gl8008cx, gl8008cx, gl8008cx_state, 0, "Video Technology", "Genius Leader 8008 CX (Germany)", MACHINE_IS_SKELETON)
COMP( 1999, bs9009cx, 0, 0, gl8008cx, gl8008cx, gl8008cx_state, 0, "Video Technology", "BrainStation 9009 CXL (Germany)", MACHINE_IS_SKELETON)
COMP( 1998, itunlim, 0, 0, iq128, geniusiq_de, geniusiq_state, 0, "Video Technology", "VTech IT Unlimited (UK)", MACHINE_NO_SOUND)
COMP( 19??, iqunlim, 0, 0, iq128, geniusiq_de, geniusiq_state, 0, "Video Technology", "VTech IQ Unlimited (Germany)", MACHINE_IS_SKELETON)
COMP( 19??, glmmc, 0, 0, iq128, geniusiq_de, geniusiq_state, 0, "Video Technology", "Genius Leader Master Mega Color (Germany)", MACHINE_IS_SKELETON)

View File

@ -42,7 +42,7 @@ Unfortunately it's read protected.
#include "sound/2612intf.h"
#include "sound/sn76496.h"
#include "includes/megadriv.h"
#include "includes/megadrvb.h"
#include "includes/megadriv_acbl.h"
static INPUT_PORTS_START( hshavoc )
PORT_START("IN0") /* 16bit */

View File

@ -0,0 +1,105 @@
// license:BSD-3-Clause
// copyright-holders:Sandro Ronco
/*
IQ Unlimited - GERMAN:
+------------------------------------------------------------------------------+
| |
+-----+ |
| |
| |
| |
| +----+ +---+ |
| | A2 | +----+ | | |
| | | | A4 | |A1 | +-+ |
| +----+ +----+ | | | | |
| | | +-+ |
| | | |
| +---+ +--+
| |
| +-------+ |
+--+ |65C5L5K| +----+
| | HC374 | |
+--+ +----------+ +-------+ +--+
| |DragonBall| |
| C +----+ |EZ | +-------+ C |
| A | A3 | | | |65C5L5K| A |
| R +----+ |LSC414328P| | HC374 | R |
| T |U16 IJ75C| +-------+ T |
| R | HHAV984S | R |
| I +----------+ I |
| D CARD 1 +------------+ CARD 0 D |
| G | AM29F0400 | G |
| E | | +------+ +--------+ E |
| +------------+ | LGS | |LHMN5KR7| |
| S | | | | S |
| L |GM71C1| | 1998 | L |
| O GER |8163CJ| | | O |
| T 038 |6 | |27-06126| T |
| | | |-007 | |
+--+ | | | | +--+
| | | | VTECH | |
| +------+ +--------+ |
| 35-19600-200 703139-G|
+-------------------------------------------------------------------------+
A1 = 98AHCLT / 27-05992-0-0 / VTech
A2 = 9932 HBL / C807U-1442 / 35016B / Japan
A3 = ACT139
A4 = MAX232
*/
#include "emu.h"
#include "screen.h"
#include "cpu/m68000/m68000.h"
class iqunlim_state : public driver_device
{
public:
iqunlim_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu")
{ }
required_device<cpu_device> m_maincpu;
virtual uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void iqunlim(machine_config &config);
};
uint32_t iqunlim_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
return 0;
}
static ADDRESS_MAP_START(iqunlim_mem, AS_PROGRAM, 16, iqunlim_state)
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x000000, 0x1FFFFF) AM_ROM
ADDRESS_MAP_END
static INPUT_PORTS_START( iqunlim )
INPUT_PORTS_END
MACHINE_CONFIG_START(iqunlim_state::iqunlim)
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", M68000, XTAL(32'000'000)/2) // DragonBall EZ (MC68EZ328) (68k core) (is the xtal correct? this was from the other hardware)
MCFG_CPU_PROGRAM_MAP(iqunlim_mem)
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(50)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
MCFG_SCREEN_SIZE(512, 256)
MCFG_SCREEN_VISIBLE_AREA(0, 512-1, 0, 256-1)
MCFG_SCREEN_UPDATE_DRIVER( iqunlim_state, screen_update )
MACHINE_CONFIG_END
ROM_START( iqunlim )
ROM_REGION(0x200000, "maincpu", 0)
ROM_LOAD16_WORD_SWAP( "27-06126-007.bin", 0x000000, 0x200000, CRC(af38c743) SHA1(5b91748536905812e6de7145638699acb375865a) )
ROM_END
COMP( 19??, iqunlim, 0, 0, iqunlim, iqunlim, iqunlim_state, 0, "Video Technology", "VTech IQ Unlimited (Germany)", MACHINE_IS_SKELETON)

View File

@ -258,7 +258,7 @@ connector, but of course, I can be wrong.
#include "emu.h"
#include "includes/megadriv.h"
#include "includes/megadrvb.h"
#include "includes/megadriv_acbl.h"
/************************************ Megadrive Bootlegs *************************************/

View File

@ -0,0 +1,191 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
/*
Radica 'Mega Drive' and 'Genesis' clones
these were mini battery operated "TV Game" consoles with wired in controller and no cartslot
fully licensed by Sega
reproduction 'System on a Chip' hardware, not perfect, flaws will need emulating eventually.
not dumped
Genesis Volume 2
Genesis SF2 / GnG (PAL one is locked to PAL)
Outrun 2019 (probably identical ROM to MD version, just custom controller)
more?
*/
#include "emu.h"
#include "includes/megadriv.h"
#include "includes/megadriv_rad.h"
// todo, use actual MD map, easier once maps are part of base class.
static ADDRESS_MAP_START( megadriv_radica_map, AS_PROGRAM, 16, megadriv_radica_state )
AM_RANGE(0x000000, 0x3fffff) AM_READ(read) /* Cartridge Program Rom */
AM_RANGE(0xa00000, 0xa01fff) AM_READWRITE(megadriv_68k_read_z80_ram, megadriv_68k_write_z80_ram)
AM_RANGE(0xa02000, 0xa03fff) AM_WRITE(megadriv_68k_write_z80_ram)
AM_RANGE(0xa04000, 0xa04003) AM_READWRITE8(megadriv_68k_YM2612_read, megadriv_68k_YM2612_write, 0xffff)
AM_RANGE(0xa06000, 0xa06001) AM_WRITE(megadriv_68k_z80_bank_write)
AM_RANGE(0xa10000, 0xa1001f) AM_READWRITE(megadriv_68k_io_read, megadriv_68k_io_write)
AM_RANGE(0xa11100, 0xa11101) AM_READWRITE(megadriv_68k_check_z80_bus, megadriv_68k_req_z80_bus)
AM_RANGE(0xa11200, 0xa11201) AM_WRITE(megadriv_68k_req_z80_reset)
AM_RANGE(0xa13000, 0xa130ff) AM_READ(read_a13)
AM_RANGE(0xc00000, 0xc0001f) AM_DEVREADWRITE("gen_vdp", sega315_5313_device, vdp_r, vdp_w)
AM_RANGE(0xe00000, 0xe0ffff) AM_RAM AM_MIRROR(0x1f0000) AM_SHARE("megadrive_ram")
ADDRESS_MAP_END
READ16_MEMBER(megadriv_radica_state::read)
{
return m_rom[(((m_bank * 0x10000) + (offset << 1)) & (0x400000 - 1))/2];
}
READ16_MEMBER(megadriv_radica_state::read_a13)
{
if (offset < 0x80)
m_bank = offset & 0x3f;
// low bit gets set when selecting cannon fodder or mega lo mania in the rad_ssoc set, pointing to the wrong area, but rad_gen1 needs it for the menu
// as they're standalones it could just be different logic
if (m_bank != 0x3f)
m_bank &= 0x3e;
return 0;
}
// controller is wired directly into unit, no controller slots
static INPUT_PORTS_START( megadriv_radica_3button )
PORT_INCLUDE( md_common )
PORT_MODIFY("PAD1")
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START1 )
PORT_MODIFY("PAD2")
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START2 )
INPUT_PORTS_END
// the 6-in-1 and Sonic Gold units really only have a single wired controller, and no way to connect a 2nd one, despite having some 2 player games!
static INPUT_PORTS_START( megadriv_radica_3button_1player )
PORT_INCLUDE( megadriv_radica_3button )
PORT_MODIFY("PAD2")
PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )
INPUT_PORTS_END
static INPUT_PORTS_START( megadriv_radica_6button )
PORT_INCLUDE( megadriv_radica_3button )
PORT_START("EXTRA1") /* Extra buttons for Joypad 1 (6 button + start + mode) NOT READ DIRECTLY */
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(1)
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(1)
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1)
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("EXTRA2") /* Extra buttons for Joypad 2 (6 button + start + mode) NOT READ DIRECTLY */
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(2)
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(2)
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2)
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("IN0")
PORT_START("UNK")
INPUT_PORTS_END
MACHINE_START_MEMBER(megadriv_radica_state, megadriv_radica_6button)
{
MACHINE_START_CALL_MEMBER(megadriv);
m_vdp->stop_timers();
m_io_pad_6b[0] = ioport("EXTRA1");
m_io_pad_6b[1] = ioport("EXTRA2");
m_io_pad_6b[2] = ioport("IN0");
m_io_pad_6b[3] = ioport("UNK");
// setup timers for 6 button pads
for (int i = 0; i < 3; i++)
m_io_timeout[i] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(md_base_state::io_timeout_timer_callback),this), (void*)(uintptr_t)i);
save_item(NAME(m_bank));
}
MACHINE_START_MEMBER(megadriv_radica_state, megadriv_radica_3button)
{
MACHINE_START_CALL_MEMBER(megadriv);
m_vdp->stop_timers();
save_item(NAME(m_bank));
}
MACHINE_RESET_MEMBER(megadriv_radica_state, megadriv_radica)
{
m_bank = 0;
MACHINE_RESET_CALL_MEMBER(megadriv);
m_maincpu->reset();
}
MACHINE_CONFIG_START(megadriv_radica_state::megadriv_radica_3button_ntsc)
MCFG_FRAGMENT_ADD(md_ntsc)
MCFG_CPU_MODIFY("maincpu")
MCFG_CPU_PROGRAM_MAP(megadriv_radica_map)
MCFG_MACHINE_START_OVERRIDE(megadriv_radica_state, megadriv_radica_3button)
MCFG_MACHINE_RESET_OVERRIDE(megadriv_radica_state, megadriv_radica)
MACHINE_CONFIG_END
MACHINE_CONFIG_START(megadriv_radica_state::megadriv_radica_3button_pal)
MCFG_FRAGMENT_ADD(md_pal)
MCFG_CPU_MODIFY("maincpu")
MCFG_CPU_PROGRAM_MAP(megadriv_radica_map)
MCFG_MACHINE_START_OVERRIDE(megadriv_radica_state, megadriv_radica_3button)
MCFG_MACHINE_RESET_OVERRIDE(megadriv_radica_state, megadriv_radica)
MACHINE_CONFIG_END
MACHINE_CONFIG_START(megadriv_radica_state::megadriv_radica_6button_pal)
MCFG_FRAGMENT_ADD(md_pal)
MCFG_CPU_MODIFY("maincpu")
MCFG_CPU_PROGRAM_MAP(megadriv_radica_map)
MCFG_MACHINE_START_OVERRIDE(megadriv_radica_state, megadriv_radica_6button)
MCFG_MACHINE_RESET_OVERRIDE(megadriv_radica_state, megadriv_radica)
MACHINE_CONFIG_END
ROM_START( rad_sf )
ROM_REGION( 0x400000, "maincpu", 0 )
ROM_LOAD16_WORD_SWAP( "radicasf.bin", 0x000000, 0x400000, CRC(868afb44) SHA1(f4339e36272c18b1d49aa4095127ed18e0961df6) )
ROM_END
ROM_START( rad_gen1 )
ROM_REGION( 0x400000, "maincpu", 0 )
ROM_LOAD16_WORD_SWAP( "radicav1.bin", 0x000000, 0x400000, CRC(3b4c8438) SHA1(5ed9c053f9ebc8d4bf571d57e562cf347585d158) )
ROM_END
ROM_START( rad_ssoc )
ROM_REGION( 0x400000, "maincpu", 0 )
ROM_LOAD( "sensiblesoccer.bin", 0x000000, 0x400000, CRC(b8745ab3) SHA1(0ab3f26e5ffd288e5a3a5db676951b9095299eb0) ) // should be byteswapped?
ROM_END
DRIVER_INIT_MEMBER(megadriv_radica_state,megadriv_radica_6button_pal)
{
DRIVER_INIT_CALL(megadrie);
// 6 button game, so overwrite 3 button io handlers
m_megadrive_io_read_data_port_ptr = read8_delegate(FUNC(md_base_state::megadrive_io_read_data_port_6button),this);
m_megadrive_io_write_data_port_ptr = write16_delegate(FUNC(md_base_state::megadrive_io_write_data_port_6button),this);
}
// NTSC releases
CONS( 2004, rad_gen1,0, 0, megadriv_radica_3button_ntsc, megadriv_radica_3button_1player, megadriv_radica_state, megadriv, "Radica / Sega", "Genesis Collection Volume 1 (Radica, Arcade Legends) (USA)", 0)
// PAL releases
CONS( 2004, rad_sf, 0, 0, megadriv_radica_6button_pal, megadriv_radica_6button, megadriv_radica_state, megadriv_radica_6button_pal, "Radica / Capcom / Sega", "Street Fighter II: Special Champion Edition [Ghouls'n Ghosts] (Radica, Arcade Legends) (Europe)", 0) // SF2 game is region locked, US version ROM is definitely different
CONS( 2004, rad_ssoc,0, 0, megadriv_radica_3button_pal, megadriv_radica_3button, megadriv_radica_state, megadrie, "Radica / Sensible Software / Sega", "Sensible Soccer plus [Cannon Fodder, Mega lo Mania] (Radica, Arcade Legends) (Europe)", 0) // still branded as Arcade Legends even if none of these were ever arcade games

View File

@ -51,7 +51,7 @@ Notes:
#include "sound/2612intf.h"
#include "includes/megadriv.h"
#include "includes/megadrvb.h"
#include "includes/megadriv_acbl.h"
/* Puckman Pockimon Input Ports */
static INPUT_PORTS_START( puckpkmn )

View File

@ -23,7 +23,6 @@
---
Other games that might be on this hardware
Golden Tee Home Edition
Skateboarding
+ some of the earlier PlayTV games (not Soccer, that's XaviX, see xavix.cpp)
@ -159,11 +158,13 @@
#include "screen.h"
#include "speaker.h"
#include "machine/bankdev.h"
#include "audio/rad_eu3a05.h"
#include "machine/rad_eu3a05gpio.h"
class radica_6502_state : public driver_device
class radica_eu3a05_state : public driver_device
{
public:
radica_6502_state(const machine_config &mconfig, device_type type, const char *tag)
radica_eu3a05_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_ram(*this, "ram"),
@ -285,267 +286,7 @@ private:
void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
};
#define MCFG_RADICA6502_SOUND_SPACE_READ_CB(_devcb) \
devcb = &radica6502_sound_device::set_space_read_callback(*device, DEVCB_##_devcb);
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> radica6502_sound_device
class radica6502_sound_device : public device_t, public device_sound_interface
{
public:
radica6502_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template <class Object> static devcb_base &set_space_read_callback(device_t &device, Object &&cb) { return downcast<radica6502_sound_device &>(device).m_space_read_cb.set_callback(std::forward<Object>(cb)); }
DECLARE_WRITE8_MEMBER(radicasi_sound_addr_w);
DECLARE_READ8_MEMBER(radicasi_sound_addr_r);
DECLARE_WRITE8_MEMBER(radicasi_sound_size_w);
DECLARE_READ8_MEMBER(radicasi_sound_size_r);
DECLARE_READ8_MEMBER(radicasi_sound_trigger_r);
DECLARE_WRITE8_MEMBER(radicasi_sound_trigger_w);
DECLARE_READ8_MEMBER(radicasi_sound_unk_r);
DECLARE_WRITE8_MEMBER(radicasi_sound_unk_w);
DECLARE_READ8_MEMBER(radicasi_50a8_r);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
private:
sound_stream *m_stream;
devcb_read8 m_space_read_cb;
uint32_t m_sound_byte_address[6];
uint32_t m_sound_byte_len[6];
uint32_t m_sound_current_nib_pos[6];
uint8_t m_sound_trigger;
uint8_t m_sound_unk;
uint8_t m_isstopped;
void handle_sound_trigger(int which);
void handle_sound_addr_w(int which, int offset, uint8_t data);
uint8_t handle_sound_addr_r(int which, int offset);
void handle_sound_size_w(int which, int offset, uint8_t data);
uint8_t handle_sound_size_r(int which, int offset);
};
//DECLARE_DEVICE_TYPE(RADICA6502_SOUND, radica6502_sound_device)
DEFINE_DEVICE_TYPE(RADICA6502_SOUND, radica6502_sound_device, "radica6502sound", "Radica 6502 Sound")
radica6502_sound_device::radica6502_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, RADICA6502_SOUND, tag, owner, clock)
, device_sound_interface(mconfig, *this)
, m_stream(nullptr)
, m_space_read_cb(*this)
{
}
void radica6502_sound_device::device_start()
{
m_space_read_cb.resolve_safe(0);
m_stream = stream_alloc(0, 1, 8000);
}
void radica6502_sound_device::device_reset()
{
for (int i = 0; i < 6; i++)
{
m_sound_byte_address[i] = 0;
m_sound_byte_len[i] = 0;
m_sound_current_nib_pos[i] = 0;
}
m_isstopped = 0x3f;
}
//-------------------------------------------------
// sound_stream_update - handle a stream update
//-------------------------------------------------
void radica6502_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
// reset the output stream
memset(outputs[0], 0, samples * sizeof(*outputs[0]));
int outpos = 0;
// loop while we still have samples to generate
while (samples-- != 0)
{
for (int channel = 0; channel < 6; channel++)
{
if (!((m_isstopped >> channel) & 1))
{
//logerror("m_isstopped %02x channel %d is active %08x %06x\n", m_isstopped, channel, m_sound_byte_address[channel], m_sound_current_nib_pos[channel]);
int readoffset = m_sound_byte_address[channel] + (m_sound_current_nib_pos[channel] / 2);
int nibble = m_space_read_cb(readoffset);
nibble = nibble >> ((m_sound_current_nib_pos[channel] & 1) ? 0 : 4);
nibble &= 0x0f;
// it's actually some form of ADPCM? but apparently NOT the OKI ADPCM
if (nibble & 0x08)
nibble -= 0x10;
outputs[0][outpos] += nibble * 0x100;
m_sound_current_nib_pos[channel]++;
if (m_sound_current_nib_pos[channel] >= m_sound_byte_len[channel] * 2)
{
m_sound_current_nib_pos[channel] = 0;
m_isstopped |= (1 << channel);
// maybe should generate an interrupt with vector
// ffb8, ffbc, ffc0, ffc4, ffc8, or ffcc depending on which channel finished??
}
}
else
{
//logerror("m_isstopped %02x channel %d is NOT active %08x %06x\n", m_isstopped, channel, m_sound_byte_address[channel], m_sound_current_nib_pos[channel]);
}
}
outpos++;
}
}
#define MCFG_RADICA6502_GPIO_READ_PORT0_CB(_devcb) \
devcb = &radica6502_gpio_device::set_gpio_read_0_callback(*device, DEVCB_##_devcb);
#define MCFG_RADICA6502_GPIO_READ_PORT1_CB(_devcb) \
devcb = &radica6502_gpio_device::set_gpio_read_1_callback(*device, DEVCB_##_devcb);
#define MCFG_RADICA6502_GPIO_READ_PORT2_CB(_devcb) \
devcb = &radica6502_gpio_device::set_gpio_read_2_callback(*device, DEVCB_##_devcb);
class radica6502_gpio_device : public device_t
{
public:
radica6502_gpio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template <class Object> static devcb_base &set_gpio_read_0_callback(device_t &device, Object &&cb) { return downcast<radica6502_gpio_device &>(device).m_space_read0_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_gpio_read_1_callback(device_t &device, Object &&cb) { return downcast<radica6502_gpio_device &>(device).m_space_read1_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_gpio_read_2_callback(device_t &device, Object &&cb) { return downcast<radica6502_gpio_device &>(device).m_space_read2_cb.set_callback(std::forward<Object>(cb)); }
DECLARE_READ8_MEMBER(gpio_r);
DECLARE_WRITE8_MEMBER(gpio_w);
DECLARE_WRITE8_MEMBER(gpio_unk_w);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
private:
devcb_read8 m_space_read0_cb;
devcb_read8 m_space_read1_cb;
devcb_read8 m_space_read2_cb;
uint8_t read_port_data(int which);
uint8_t read_direction(int which);
void write_port_data(int which, uint8_t data);
void write_direction(int which, uint8_t data);
uint8_t m_ddr[3];
uint8_t m_unk[3];
};
//DECLARE_DEVICE_TYPE(RADICA6502_SOUND, radica6502_gpio_device)
DEFINE_DEVICE_TYPE(RADICA6502_GPIO, radica6502_gpio_device, "radica6502gpio", "Radica 6502 GPIO")
radica6502_gpio_device::radica6502_gpio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, RADICA6502_GPIO, tag, owner, clock)
, m_space_read0_cb(*this)
, m_space_read1_cb(*this)
, m_space_read2_cb(*this)
{
}
void radica6502_gpio_device::device_start()
{
m_space_read0_cb.resolve_safe(0xff);
m_space_read1_cb.resolve_safe(0xff);
m_space_read2_cb.resolve_safe(0xff);
}
void radica6502_gpio_device::device_reset()
{
for (int i = 0; i < 3; i++)
{
m_ddr[i] = 0;
m_unk[i] = 0;
}
}
uint8_t radica6502_gpio_device::read_port_data(int which)
{
//todo, actually use the direction registers
switch (which)
{
case 0: return m_space_read0_cb();
case 1: return m_space_read1_cb();
case 2: return m_space_read2_cb();
}
return 0xff;
}
uint8_t radica6502_gpio_device::read_direction(int which)
{
return m_ddr[which];
}
READ8_MEMBER(radica6502_gpio_device::gpio_r)
{
int port = offset/2;
if (!(offset&1)) return read_direction(port);
else return read_port_data(port);
}
void radica6502_gpio_device::write_port_data(int which, uint8_t data)
{
//todo, actually use the direction registers
logerror("%s: write_port_data (port %d) %02x (direction register %02x)\n", which, data, m_ddr[which]);
}
void radica6502_gpio_device::write_direction(int which, uint8_t data)
{
logerror("%s: write_direction (port %d) %02x\n", which, data);
m_ddr[which] = data;
}
WRITE8_MEMBER(radica6502_gpio_device::gpio_w)
{
int port = offset/2;
if (!(offset&1)) return write_direction(port, data);
else return write_port_data(port, data);
}
WRITE8_MEMBER(radica6502_gpio_device::gpio_unk_w)
{
logerror("%s: gpio_unk_w (port %d) %02x (direction register %02x)\n", offset, data, m_ddr[offset]);
}
void radica_6502_state::video_start()
void radica_eu3a05_state::video_start()
{
}
@ -555,7 +296,7 @@ void radica_6502_state::video_start()
that space (Tetris seems to rely on mirroring? as it sets all addresses up for the lower 1MB instead)
*/
void radica_6502_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
void radica_eu3a05_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
address_space& fullbankspace = m_bank->space(AS_PROGRAM);
@ -693,7 +434,7 @@ double hue2rgb(double p, double q, double t)
}
// a hacky mess for now
bool radica_6502_state::get_tile_data(int base, int drawpri, int& tile, int &attr, int &unk2)
bool radica_eu3a05_state::get_tile_data(int base, int drawpri, int& tile, int &attr, int &unk2)
{
tile = m_vram[base * 4] + (m_vram[(base * 4) + 1] << 8);
@ -716,7 +457,7 @@ bool radica_6502_state::get_tile_data(int base, int drawpri, int& tile, int &att
return true;
}
void radica_6502_state::draw_tilemaps(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int drawpri)
void radica_eu3a05_state::draw_tilemaps(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int drawpri)
{
/* this doesn't handle 8x8 4bpp, haven't seen it used
nor is there support for horizontal scrolling etc.
@ -844,7 +585,7 @@ void radica_6502_state::draw_tilemaps(screen_device &screen, bitmap_ind16 &bitma
}
}
uint32_t radica_6502_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
uint32_t radica_eu3a05_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
bitmap.fill(0, cliprect);
@ -893,36 +634,36 @@ uint32_t radica_6502_state::screen_update(screen_device &screen, bitmap_ind16 &b
// System control
WRITE8_MEMBER(radica_6502_state::radicasi_rombank_hi_w)
WRITE8_MEMBER(radica_eu3a05_state::radicasi_rombank_hi_w)
{
// written with the banking?
//logerror("%s: radicasi_rombank_hi_w (set ROM bank) %02x\n", machine().describe_context().c_str(), data);
//logerror("%s: radicasi_rombank_hi_w (set ROM bank) %02x\n", machine().describe_context(), data);
m_rombank_hi = data;
m_bank->set_bank(m_rombank_lo | (m_rombank_hi << 8));
}
WRITE8_MEMBER(radica_6502_state::radicasi_rombank_lo_w)
WRITE8_MEMBER(radica_eu3a05_state::radicasi_rombank_lo_w)
{
//logerror("%s: radicasi_rombank_lo_w (select ROM bank) %02x\n", machine().describe_context().c_str(), data);
//logerror("%s: radicasi_rombank_lo_w (select ROM bank) %02x\n", machine().describe_context(), data);
m_rombank_lo = data;
}
READ8_MEMBER(radica_6502_state::radicasi_rombank_lo_r)
READ8_MEMBER(radica_eu3a05_state::radicasi_rombank_lo_r)
{
return m_rombank_lo;
}
READ8_MEMBER(radica_6502_state::radicasi_pal_ntsc_r)
READ8_MEMBER(radica_eu3a05_state::radicasi_pal_ntsc_r)
{
// how best to handle this, we probably need to run the PAL machine at 50hz
// the text under the radica logo differs between regions
logerror("%s: radicasi_pal_ntsc_r (region + more?)\n", machine().describe_context().c_str());
logerror("%s: radicasi_pal_ntsc_r (region + more?)\n", machine().describe_context());
return 0xff; // NTSC
//return 0x00; // PAL
}
READ8_MEMBER(radica_6502_state::radicasi_5003_r)
READ8_MEMBER(radica_eu3a05_state::radicasi_5003_r)
{
/* masked with 0x0f, 0x01 or 0x03 depending on situation..
@ -934,7 +675,7 @@ READ8_MEMBER(radica_6502_state::radicasi_5003_r)
*/
logerror("%s: radicasi_5003_r (RNG?)\n", machine().describe_context().c_str());
logerror("%s: radicasi_5003_r (RNG?)\n", machine().describe_context());
return machine().rand();
}
@ -944,71 +685,71 @@ READ8_MEMBER(radica_6502_state::radicasi_5003_r)
// Tile bases
WRITE8_MEMBER(radica_6502_state::radicasi_tile_gfxbase_lo_w)
WRITE8_MEMBER(radica_eu3a05_state::radicasi_tile_gfxbase_lo_w)
{
//logerror("%s: radicasi_tile_gfxbase_lo_w (select GFX base lower) %02x\n", machine().describe_context().c_str(), data);
//logerror("%s: radicasi_tile_gfxbase_lo_w (select GFX base lower) %02x\n", machine().describe_context(), data);
m_tile_gfxbase_lo_data = data;
}
WRITE8_MEMBER(radica_6502_state::radicasi_tile_gfxbase_hi_w)
WRITE8_MEMBER(radica_eu3a05_state::radicasi_tile_gfxbase_hi_w)
{
//logerror("%s: radicasi_tile_gfxbase_hi_w (select GFX base upper) %02x\n", machine().describe_context().c_str(), data);
//logerror("%s: radicasi_tile_gfxbase_hi_w (select GFX base upper) %02x\n", machine().describe_context(), data);
m_tile_gfxbase_hi_data = data;
}
READ8_MEMBER(radica_6502_state::radicasi_tile_gfxbase_lo_r)
READ8_MEMBER(radica_eu3a05_state::radicasi_tile_gfxbase_lo_r)
{
//logerror("%s: radicasi_tile_gfxbase_lo_r (GFX base lower)\n", machine().describe_context().c_str());
//logerror("%s: radicasi_tile_gfxbase_lo_r (GFX base lower)\n", machine().describe_context());
return m_tile_gfxbase_lo_data;
}
READ8_MEMBER(radica_6502_state::radicasi_tile_gfxbase_hi_r)
READ8_MEMBER(radica_eu3a05_state::radicasi_tile_gfxbase_hi_r)
{
//logerror("%s: radicasi_tile_gfxbase_hi_r (GFX base upper)\n", machine().describe_context().c_str());
//logerror("%s: radicasi_tile_gfxbase_hi_r (GFX base upper)\n", machine().describe_context());
return m_tile_gfxbase_hi_data;
}
// Sprite Tile bases
WRITE8_MEMBER(radica_6502_state::radicasi_sprite_gfxbase_lo_w)
WRITE8_MEMBER(radica_eu3a05_state::radicasi_sprite_gfxbase_lo_w)
{
//logerror("%s: radicasi_sprite_gfxbase_lo_w (select Sprite GFX base lower) %02x\n", machine().describe_context().c_str(), data);
//logerror("%s: radicasi_sprite_gfxbase_lo_w (select Sprite GFX base lower) %02x\n", machine().describe_context(), data);
m_sprite_gfxbase_lo_data = data;
}
WRITE8_MEMBER(radica_6502_state::radicasi_sprite_gfxbase_hi_w)
WRITE8_MEMBER(radica_eu3a05_state::radicasi_sprite_gfxbase_hi_w)
{
//logerror("%s: radicasi_sprite_gfxbase_hi_w (select Sprite GFX base upper) %02x\n", machine().describe_context().c_str(), data);
//logerror("%s: radicasi_sprite_gfxbase_hi_w (select Sprite GFX base upper) %02x\n", machine().describe_context(), data);
m_sprite_gfxbase_hi_data = data;
}
READ8_MEMBER(radica_6502_state::radicasi_sprite_gfxbase_lo_r)
READ8_MEMBER(radica_eu3a05_state::radicasi_sprite_gfxbase_lo_r)
{
//logerror("%s: radicasi_sprite_gfxbase_lo_r (Sprite GFX base lower)\n", machine().describe_context().c_str());
//logerror("%s: radicasi_sprite_gfxbase_lo_r (Sprite GFX base lower)\n", machine().describe_context());
return m_sprite_gfxbase_lo_data;
}
READ8_MEMBER(radica_6502_state::radicasi_sprite_gfxbase_hi_r)
READ8_MEMBER(radica_eu3a05_state::radicasi_sprite_gfxbase_hi_r)
{
//logerror("%s: radicasi_sprite_gfxbase_hi_r (Sprite GFX base upper)\n", machine().describe_context().c_str());
//logerror("%s: radicasi_sprite_gfxbase_hi_r (Sprite GFX base upper)\n", machine().describe_context());
return m_sprite_gfxbase_hi_data;
}
READ8_MEMBER(radica_6502_state::radicasi_sprite_bg_scroll_r)
READ8_MEMBER(radica_eu3a05_state::radicasi_sprite_bg_scroll_r)
{
return m_bg_scroll[offset];
}
WRITE8_MEMBER(radica_6502_state::radicasi_sprite_bg_scroll_w)
WRITE8_MEMBER(radica_eu3a05_state::radicasi_sprite_bg_scroll_w)
{
m_bg_scroll[offset] = data;
}
WRITE8_MEMBER(radica_6502_state::radicasi_vidctrl_w)
WRITE8_MEMBER(radica_eu3a05_state::radicasi_vidctrl_w)
{
logerror("%s: radicasi_vidctrl_w %02x (video control?)\n", machine().describe_context().c_str(), data);
logerror("%s: radicasi_vidctrl_w %02x (video control?)\n", machine().describe_context(), data);
/*
c3 8bpp 16x16 1100 0011
e3 4bpp 16x16 1110 0011
@ -1020,103 +761,103 @@ WRITE8_MEMBER(radica_6502_state::radicasi_vidctrl_w)
// DMA device
WRITE8_MEMBER(radica_6502_state::radicasi_dmasrc_lo_w)
WRITE8_MEMBER(radica_eu3a05_state::radicasi_dmasrc_lo_w)
{
logerror("%s: radicasi_dmasrc_lo_w (select DMA source low) %02x\n", machine().describe_context().c_str(), data);
logerror("%s: radicasi_dmasrc_lo_w (select DMA source low) %02x\n", machine().describe_context(), data);
m_dmasrc_lo_data = data;
}
WRITE8_MEMBER(radica_6502_state::radicasi_dmasrc_md_w)
WRITE8_MEMBER(radica_eu3a05_state::radicasi_dmasrc_md_w)
{
logerror("%s: radicasi_dmasrc_md_w (select DMA source middle) %02x\n", machine().describe_context().c_str(), data);
logerror("%s: radicasi_dmasrc_md_w (select DMA source middle) %02x\n", machine().describe_context(), data);
m_dmasrc_md_data = data;
}
WRITE8_MEMBER(radica_6502_state::radicasi_dmasrc_hi_w)
WRITE8_MEMBER(radica_eu3a05_state::radicasi_dmasrc_hi_w)
{
logerror("%s: radicasi_dmasrc_hi_w (select DMA source upper) %02x\n", machine().describe_context().c_str(), data);
logerror("%s: radicasi_dmasrc_hi_w (select DMA source upper) %02x\n", machine().describe_context(), data);
m_dmasrc_hi_data = data;
}
READ8_MEMBER(radica_6502_state::radicasi_dmasrc_lo_r)
READ8_MEMBER(radica_eu3a05_state::radicasi_dmasrc_lo_r)
{
logerror("%s: radicasi_dmasrc_lo_r (DMA source low)\n", machine().describe_context().c_str());
logerror("%s: radicasi_dmasrc_lo_r (DMA source low)\n", machine().describe_context());
return m_dmasrc_lo_data;
}
READ8_MEMBER(radica_6502_state::radicasi_dmasrc_md_r)
READ8_MEMBER(radica_eu3a05_state::radicasi_dmasrc_md_r)
{
logerror("%s: radicasi_dmasrc_md_r (DMA source middle)\n", machine().describe_context().c_str());
logerror("%s: radicasi_dmasrc_md_r (DMA source middle)\n", machine().describe_context());
return m_dmasrc_md_data;
}
READ8_MEMBER(radica_6502_state::radicasi_dmasrc_hi_r)
READ8_MEMBER(radica_eu3a05_state::radicasi_dmasrc_hi_r)
{
logerror("%s: radicasi_dmasrc_hi_r (DMA source upper)\n", machine().describe_context().c_str());
logerror("%s: radicasi_dmasrc_hi_r (DMA source upper)\n", machine().describe_context());
return m_dmasrc_hi_data;
}
WRITE8_MEMBER(radica_6502_state::radicasi_dmadst_lo_w)
WRITE8_MEMBER(radica_eu3a05_state::radicasi_dmadst_lo_w)
{
logerror("%s: radicasi_dmadst_lo_w (select DMA Dest lower) %02x\n", machine().describe_context().c_str(), data);
logerror("%s: radicasi_dmadst_lo_w (select DMA Dest lower) %02x\n", machine().describe_context(), data);
m_dmadst_lo_data = data;
}
WRITE8_MEMBER(radica_6502_state::radicasi_dmadst_hi_w)
WRITE8_MEMBER(radica_eu3a05_state::radicasi_dmadst_hi_w)
{
logerror("%s: radicasi_dmadst_hi_w (select DMA Dest upper) %02x\n", machine().describe_context().c_str(), data);
logerror("%s: radicasi_dmadst_hi_w (select DMA Dest upper) %02x\n", machine().describe_context(), data);
m_dmadst_hi_data = data;
}
READ8_MEMBER(radica_6502_state::radicasi_dmadst_lo_r)
READ8_MEMBER(radica_eu3a05_state::radicasi_dmadst_lo_r)
{
logerror("%s: radicasi_dmadst_lo_r (DMA Dest lower)\n", machine().describe_context().c_str());
logerror("%s: radicasi_dmadst_lo_r (DMA Dest lower)\n", machine().describe_context());
return m_dmadst_lo_data;
}
READ8_MEMBER(radica_6502_state::radicasi_dmadst_hi_r)
READ8_MEMBER(radica_eu3a05_state::radicasi_dmadst_hi_r)
{
logerror("%s: radicasi_dmadst_hi_r (DMA Dest upper)\n", machine().describe_context().c_str());
logerror("%s: radicasi_dmadst_hi_r (DMA Dest upper)\n", machine().describe_context());
return m_dmadst_hi_data;
}
WRITE8_MEMBER(radica_6502_state::radicasi_dmasize_lo_w)
WRITE8_MEMBER(radica_eu3a05_state::radicasi_dmasize_lo_w)
{
logerror("%s: radicasi_dmasize_lo_w (select DMA Size lower) %02x\n", machine().describe_context().c_str(), data);
logerror("%s: radicasi_dmasize_lo_w (select DMA Size lower) %02x\n", machine().describe_context(), data);
m_dmasize_lo_data = data;
}
WRITE8_MEMBER(radica_6502_state::radicasi_dmasize_hi_w)
WRITE8_MEMBER(radica_eu3a05_state::radicasi_dmasize_hi_w)
{
logerror("%s: radicasi_dmasize_hi_w (select DMA Size upper) %02x\n", machine().describe_context().c_str(), data);
logerror("%s: radicasi_dmasize_hi_w (select DMA Size upper) %02x\n", machine().describe_context(), data);
m_dmasize_hi_data = data;
}
READ8_MEMBER(radica_6502_state::radicasi_dmasize_lo_r)
READ8_MEMBER(radica_eu3a05_state::radicasi_dmasize_lo_r)
{
logerror("%s: radicasi_dmasize_lo_r (DMA Size lower)\n", machine().describe_context().c_str());
logerror("%s: radicasi_dmasize_lo_r (DMA Size lower)\n", machine().describe_context());
return m_dmasize_lo_data;
}
READ8_MEMBER(radica_6502_state::radicasi_dmasize_hi_r)
READ8_MEMBER(radica_eu3a05_state::radicasi_dmasize_hi_r)
{
logerror("%s: radicasi_dmasize_hi_r (DMA Size upper)\n", machine().describe_context().c_str());
logerror("%s: radicasi_dmasize_hi_r (DMA Size upper)\n", machine().describe_context());
return m_dmasize_hi_data;
}
READ8_MEMBER(radica_6502_state::radicasi_dmatrg_r)
READ8_MEMBER(radica_eu3a05_state::radicasi_dmatrg_r)
{
logerror("%s: radicasi_dmatrg_r (DMA operation state?)\n", machine().describe_context().c_str());
logerror("%s: radicasi_dmatrg_r (DMA operation state?)\n", machine().describe_context());
return 0x00;//m_dmatrg_data;
}
WRITE8_MEMBER(radica_6502_state::radicasi_dmatrg_w)
WRITE8_MEMBER(radica_eu3a05_state::radicasi_dmatrg_w)
{
logerror("%s: radicasi_dmatrg_w (trigger DMA operation) %02x\n", machine().describe_context().c_str(), data);
logerror("%s: radicasi_dmatrg_w (trigger DMA operation) %02x\n", machine().describe_context(), data);
//m_dmatrg_data = data;
address_space& fullbankspace = m_bank->space(AS_PROGRAM);
@ -1140,205 +881,28 @@ WRITE8_MEMBER(radica_6502_state::radicasi_dmatrg_w)
void radica6502_sound_device::handle_sound_addr_w(int which, int offset, uint8_t data)
{
switch (offset)
{
case 0x00:
m_sound_byte_address[which] = (m_sound_byte_address[which] & 0xffff00) | (data<<0);
logerror("%s: sound_0 (%d) write lo address %02x (real address is now %08x)\n", machine().describe_context().c_str(), which, data, m_sound_byte_address[which]);
break;
case 0x01:
m_sound_byte_address[which] = (m_sound_byte_address[which] & 0xff00ff) | (data<<8);
logerror("%s: sound_0 (%d) write md address %02x (real address is now %08x)\n", machine().describe_context().c_str(), which, data, m_sound_byte_address[which]);
break;
case 0x02:
m_sound_byte_address[which] = (m_sound_byte_address[which] & 0x00ffff) | (data<<16);
logerror("%s: sound_0 (%d) write hi address %02x (real address is now %08x)\n", machine().describe_context().c_str(), which, data, m_sound_byte_address[which]);
break;
}
}
uint8_t radica6502_sound_device::handle_sound_addr_r(int which, int offset)
{
switch (offset)
{
case 0x00:
logerror("%s: sound_0 (%d) read lo address\n", machine().describe_context().c_str(), which);
return (m_sound_byte_address[which]>>0) & 0xff;
case 0x01:
logerror("%s: sound_0 (%d) read mid address\n", machine().describe_context().c_str(), which);
return (m_sound_byte_address[which]>>8) & 0xff;
case 0x02:
logerror("%s: sound_0 (%d) read hi address\n", machine().describe_context().c_str(), which);
return (m_sound_byte_address[which]>>16) & 0xff;
}
return 0x00;
}
WRITE8_MEMBER(radica6502_sound_device::radicasi_sound_addr_w)
{
m_stream->update();
handle_sound_addr_w(offset / 3, offset % 3, data);
}
READ8_MEMBER(radica6502_sound_device::radicasi_sound_addr_r)
{
m_stream->update();
return handle_sound_addr_r(offset / 3, offset % 3);
}
void radica6502_sound_device::handle_sound_size_w(int which, int offset, uint8_t data)
{
switch (offset)
{
case 0x00:
m_sound_byte_len[which] = (m_sound_byte_len[which] & 0xffff00) | (data<<0);
logerror("%s: sound_1 (%d) write lo size %02x (real size is now %08x)\n", machine().describe_context().c_str(), which, data, m_sound_byte_len[which]);
break;
case 0x01:
m_sound_byte_len[which] = (m_sound_byte_len[which] & 0xff00ff) | (data<<8);
logerror("%s: sound_1 (%d) write md size %02x (real size is now %08x)\n", machine().describe_context().c_str(), which, data, m_sound_byte_len[which]);
break;
case 0x02:
m_sound_byte_len[which] = (m_sound_byte_len[which] & 0x00ffff) | (data<<16);
logerror("%s: sound_1 (%d) write hi size %02x (real size is now %08x)\n", machine().describe_context().c_str(), which, data, m_sound_byte_len[which]);
break;
}
}
uint8_t radica6502_sound_device::handle_sound_size_r(int which, int offset)
{
switch (offset)
{
case 0x00:
logerror("%s: sound_1 (%d) read lo size\n", machine().describe_context().c_str(), which);
return (m_sound_byte_len[which]>>0) & 0xff;
case 0x01:
logerror("%s: sound_1 (%d) read mid size\n", machine().describe_context().c_str(), which);
return (m_sound_byte_len[which]>>8) & 0xff;
case 0x02:
logerror("%s: sound_1 (%d) read hi size\n", machine().describe_context().c_str(), which);
return (m_sound_byte_len[which]>>16) & 0xff;
}
return 0x00;
}
WRITE8_MEMBER(radica6502_sound_device::radicasi_sound_size_w)
{
m_stream->update();
handle_sound_size_w(offset / 3, offset % 3, data);
}
READ8_MEMBER(radica6502_sound_device::radicasi_sound_size_r)
{
m_stream->update();
return handle_sound_size_r(offset / 3, offset % 3);
}
READ8_MEMBER(radica6502_sound_device::radicasi_sound_trigger_r)
{
m_stream->update();
logerror("%s: sound read from trigger?\n", machine().describe_context().c_str());
return m_sound_trigger;
}
WRITE8_MEMBER(radica6502_sound_device::radicasi_sound_trigger_w)
{
m_stream->update();
logerror("%s: sound write to trigger? %02x\n", machine().describe_context().c_str(), data);
m_sound_trigger = data;
for (int i = 0; i < 6; i++)
{
int bit = (data >> i) & 1;
if (bit)
handle_sound_trigger(i);
}
if (data & 0xc0)
logerror(" UNEXPECTED BITS SET");
}
/* this is read/written with the same individual bits for each channel as the trigger
maybe related to interrupts? */
READ8_MEMBER(radica6502_sound_device::radicasi_sound_unk_r)
{
logerror("%s: radicasi_sound_unk_r\n", machine().describe_context().c_str());
// don't think this reads back what was written probably a status of something instead?
return 0x00; //m_sound_unk;
}
WRITE8_MEMBER(radica6502_sound_device::radicasi_sound_unk_w)
{
logerror("%s: radicasi_sound_unk_w %02x\n", machine().describe_context().c_str(), data);
for (int i = 0; i < 6; i++)
{
int bit = (data >> i) & 1;
if (bit)
logerror("(unknown operation on channel %d)\n", i);
}
m_sound_unk = data;
if (data & 0xc0)
logerror(" UNEXPECTED BITS SET");
}
void radica6502_sound_device::handle_sound_trigger(int which)
{
logerror("Triggering operation on channel (%d) with params %08x %08x\n", which, m_sound_byte_address[which], m_sound_byte_len[which]);
m_sound_current_nib_pos[which] = 0;
m_isstopped &= ~(1 << which);
}
READ8_MEMBER(radica6502_sound_device::radicasi_50a8_r)
{
m_stream->update();
logerror("%s: radicasi_50a8_r\n", machine().describe_context().c_str());
return m_isstopped;
}
// probably also sound device, maybe for forcing channels to stop?
READ8_MEMBER(radica_6502_state::radicasi_50a9_r)
READ8_MEMBER(radica_eu3a05_state::radicasi_50a9_r)
{
logerror("%s: radicasi_50a9_r\n", machine().describe_context().c_str());
logerror("%s: radicasi_50a9_r\n", machine().describe_context());
return m_50a9_data;
}
WRITE8_MEMBER(radica_6502_state::radicasi_50a9_w)
WRITE8_MEMBER(radica_eu3a05_state::radicasi_50a9_w)
{
logerror("%s: radicasi_50a9_w %02x\n", machine().describe_context().c_str(), data);
logerror("%s: radicasi_50a9_w %02x\n", machine().describe_context(), data);
m_50a9_data = data;
}
// sound callback
READ8_MEMBER(radica_6502_state::read_full_space)
READ8_MEMBER(radica_eu3a05_state::read_full_space)
{
address_space& fullbankspace = m_bank->space(AS_PROGRAM);
return fullbankspace.read_byte(offset);
}
static ADDRESS_MAP_START( radicasi_map, AS_PROGRAM, 8, radica_6502_state )
static ADDRESS_MAP_START( radicasi_map, AS_PROGRAM, 8, radica_eu3a05_state )
// can the addresses move around?
AM_RANGE(0x0000, 0x05ff) AM_RAM AM_SHARE("ram")
AM_RANGE(0x0600, 0x3dff) AM_RAM AM_SHARE("vram")
@ -1406,7 +970,7 @@ static ADDRESS_MAP_START( radicasi_map, AS_PROGRAM, 8, radica_6502_state )
ADDRESS_MAP_END
static ADDRESS_MAP_START( radicasi_bank_map, AS_PROGRAM, 8, radica_6502_state )
static ADDRESS_MAP_START( radicasi_bank_map, AS_PROGRAM, 8, radica_eu3a05_state )
AM_RANGE(0x000000, 0x3fffff) AM_ROM AM_REGION("maincpu", 0)
AM_RANGE(0x400000, 0x40ffff) AM_RAM // ?? only ever cleared maybe a mirror of below?
AM_RANGE(0x800000, 0x80ffff) AM_RAM AM_SHARE("pixram") // Qix writes here and sets the tile base here instead of ROM so it can have a pixel layer
@ -1450,7 +1014,7 @@ INPUT_PORTS_END
the others look like they might be timer service routines
*/
READ8_MEMBER(radica_6502_state::radicasi_nmi_vector_r)
READ8_MEMBER(radica_eu3a05_state::radicasi_nmi_vector_r)
{
if (m_custom_nmi)
{
@ -1463,7 +1027,7 @@ READ8_MEMBER(radica_6502_state::radicasi_nmi_vector_r)
}
}
READ8_MEMBER(radica_6502_state::radicasi_irq_vector_r)
READ8_MEMBER(radica_eu3a05_state::radicasi_irq_vector_r)
{
if (m_custom_irq)
{
@ -1476,7 +1040,7 @@ READ8_MEMBER(radica_6502_state::radicasi_irq_vector_r)
}
}
void radica_6502_state::machine_start()
void radica_eu3a05_state::machine_start()
{
m_custom_irq = 0;
m_custom_irq_vector = 0x0000;
@ -1487,7 +1051,7 @@ void radica_6502_state::machine_start()
m_bank->set_bank(0x7f);
}
void radica_6502_state::machine_reset()
void radica_eu3a05_state::machine_reset()
{
/* the 6502 core sets the default stack value to 0x01bd
and Tetris does not initialize it to anything else
@ -1567,7 +1131,7 @@ static GFXDECODE_START( radicasi_fake )
GFXDECODE_ENTRY( "maincpu", 0, texture_helper_8bpp_layout, 0x0, 1 )
GFXDECODE_END
INTERRUPT_GEN_MEMBER(radica_6502_state::interrupt)
INTERRUPT_GEN_MEMBER(radica_eu3a05_state::interrupt)
{
m_custom_irq = 1;
m_custom_irq_vector = 0xffd4;
@ -1581,12 +1145,12 @@ INTERRUPT_GEN_MEMBER(radica_6502_state::interrupt)
*/
}
MACHINE_CONFIG_START(radica_6502_state::radicasi)
MACHINE_CONFIG_START(radica_eu3a05_state::radicasi)
/* basic machine hardware */
MCFG_CPU_ADD("maincpu",M6502,XTAL(21'281'370)/2) // Tetris has a XTAL(21'281'370), not confirmed on Space Invaders, actual CPU clock unknown.
MCFG_CPU_PROGRAM_MAP(radicasi_map)
MCFG_CPU_VBLANK_INT_DRIVER("screen", radica_6502_state, interrupt)
MCFG_CPU_VBLANK_INT_DRIVER("screen", radica_eu3a05_state, interrupt)
MCFG_DEVICE_ADD("bank", ADDRESS_MAP_BANK, 0)
MCFG_DEVICE_PROGRAM_MAP(radicasi_bank_map)
@ -1599,7 +1163,7 @@ MACHINE_CONFIG_START(radica_6502_state::radicasi)
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))
MCFG_SCREEN_UPDATE_DRIVER(radica_6502_state, screen_update)
MCFG_SCREEN_UPDATE_DRIVER(radica_eu3a05_state, screen_update)
MCFG_SCREEN_SIZE(32*8, 32*8)
MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 28*8-1)
MCFG_SCREEN_PALETTE("palette")
@ -1614,7 +1178,7 @@ MACHINE_CONFIG_START(radica_6502_state::radicasi)
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_DEVICE_ADD("6ch_sound", RADICA6502_SOUND, 8000)
MCFG_RADICA6502_SOUND_SPACE_READ_CB(READ8(radica_6502_state, read_full_space))
MCFG_RADICA6502_SOUND_SPACE_READ_CB(READ8(radica_eu3a05_state, read_full_space))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MACHINE_CONFIG_END
@ -1635,5 +1199,5 @@ ROM_START( rad_sinv )
ROM_RELOAD(0x300000, 0x100000)
ROM_END
CONS( 2004, rad_sinv, 0, 0, radicasi, rad_sinv, radica_6502_state, 0, "Radica (licensed from Taito)", "Space Invaders [Lunar Rescue, Colony 5, Qix, Phoenix] (Radica, Arcade Legends TV Game)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) // "5 Taito games in 1"
CONS( 2004, rad_tetr, 0, 0, radicasi, rad_tetr, radica_6502_state, 0, "Radica (licensed from Elorg / The Tetris Company)", "Tetris (Radica, Arcade Legends TV Game)", MACHINE_NOT_WORKING ) // "5 Tetris games in 1"
CONS( 2004, rad_sinv, 0, 0, radicasi, rad_sinv, radica_eu3a05_state, 0, "Radica (licensed from Taito)", "Space Invaders [Lunar Rescue, Colony 7, Qix, Phoenix] (Radica, Arcade Legends TV Game)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) // "5 Taito games in 1"
CONS( 2004, rad_tetr, 0, 0, radicasi, rad_tetr, radica_eu3a05_state, 0, "Radica (licensed from Elorg / The Tetris Company)", "Tetris (Radica, Arcade Legends TV Game)", MACHINE_NOT_WORKING ) // "5 Tetris games in 1"

View File

@ -0,0 +1,722 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood, R.Belmont
/*
These use a 6502 derived CPU under a glob
The CPU die is marked 'ELAN EU3A14'
There is a second glob surrounded by TSOP48 pads
this contains the ROM
Known to be on this hardware
Golden Tee Golf Home Edition (developed by FarSight Studios)
Maybe on this hardware
PlayTV Real Swing Golf (also developed by FarSight, looks similar but with different controls)
In many ways this is similar to the rad_eu3a05.cpp hardware
but the video system has changed, here the sprites are more traditional non-tile based, rather
than coming from 'pages'
*/
#include "emu.h"
#include "cpu/m6502/m6502.h"
#include "screen.h"
#include "speaker.h"
#include "machine/bankdev.h"
#include "audio/rad_eu3a05.h"
#include "machine/timer.h"
/*
ffb0 rti
ffb4 rti
ffb8 rti
ffbc rti
ffc0 rti
ffc4 rti
ffc8 rti
ffcc rti
ffd0 rti
ffd4 main irq?
ffd8 rti
ffdc rti
ffe0 something with 5045 bit 0x08 and 9d in ram (increase or decrease) (ADC interrupt)
ffe4 something with 5045 bit 0x20 and 9c in ram (increase of decrease) (ADC interrupt)
ffe8 rti
ffec rti
regular NMI (e3f0 - jump to ($19e2) which seems to point to rti, but could move..)
regular IRQ (e3f3 - points to rti)
*/
class radica_eu3a14_state : public driver_device
{
public:
radica_eu3a14_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_palram(*this, "palram"),
m_scrollregs(*this, "scrollregs"),
m_tilebase(*this, "tilebase"),
m_mainram(*this, "mainram"),
m_dmaparams(*this, "dmaparams"),
m_bank(*this, "bank"),
m_palette(*this, "palette"),
m_gfxdecode(*this, "gfxdecode")
{ }
READ8_MEMBER(irq_vector_r);
// screen updates
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void radica_eu3a14(machine_config &config);
int m_custom_irq;
uint16_t m_custom_irq_vector;
INTERRUPT_GEN_MEMBER(interrupt);
DECLARE_READ8_MEMBER(radicasi_pal_ntsc_r);
DECLARE_READ8_MEMBER(dma_trigger_r);
DECLARE_WRITE8_MEMBER(dma_trigger_w);
DECLARE_READ8_MEMBER(radicasi_rombank_lo_r);
DECLARE_WRITE8_MEMBER(radicasi_rombank_lo_w);
DECLARE_WRITE8_MEMBER(radicasi_rombank_hi_w);
DECLARE_READ8_MEMBER(random_r) { return machine().rand(); };
TIMER_DEVICE_CALLBACK_MEMBER(scanline_cb);
// for callback
DECLARE_READ8_MEMBER(read_full_space);
protected:
// driver_device overrides
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;
private:
double hue2rgb(double p, double q, double t);
required_device<cpu_device> m_maincpu;
required_shared_ptr<uint8_t> m_palram;
required_shared_ptr<uint8_t> m_scrollregs;
required_shared_ptr<uint8_t> m_tilebase;
required_shared_ptr<uint8_t> m_mainram;
required_shared_ptr<uint8_t> m_dmaparams;
required_device<address_map_bank_device> m_bank;
required_device<palette_device> m_palette;
required_device<gfxdecode_device> m_gfxdecode;
uint8_t m_rombank_hi;
uint8_t m_rombank_lo;
void handle_palette(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void draw_page(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int which, int xbase, int ybase);
void draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
};
void radica_eu3a14_state::video_start()
{
}
double radica_eu3a14_state::hue2rgb(double p, double q, double t)
{
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6.0f) return p + (q - p) * 6 * t;
if (t < 1 / 2.0f) return q;
if (t < 2 / 3.0f) return p + (q - p) * (2 / 3.0f - t) * 6;
return p;
}
void radica_eu3a14_state::handle_palette(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// Palette
int offs = 0;
for (int index = 0; index < 512; index++)
{
uint16_t dat = m_palram[offs++] << 8;
dat |= m_palram[offs++];
// llll lsss ---h hhhh
int l_raw = (dat & 0xf800) >> 11;
int sl_raw = (dat & 0x0700) >> 8;
int h_raw = (dat & 0x001f) >> 0;
double l = (double)l_raw / 31.0f;
double s = (double)sl_raw / 7.0f;
double h = (double)h_raw / 24.0f;
double r, g, b;
if (s == 0) {
r = g = b = l; // greyscale
}
else {
double q = l < 0.5f ? l * (1 + s) : l + s - l * s;
double p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3.0f);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3.0f);
}
int r_real = r * 255.0f;
int g_real = g * 255.0f;
int b_real = b * 255.0f;
m_palette->set_pen_color(index, r_real, g_real, b_real);
}
}
void radica_eu3a14_state::draw_page(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int which, int xbase, int ybase)
{
gfx_element *gfx = m_gfxdecode->gfx(3);
int base = (m_tilebase[1] << 8) | m_tilebase[0];
int xdraw = xbase;
int ydraw = ybase;
int count = 0;
for (int i = 0x800+0x1c0*which; i < 0x800+0x1c0*(which+1); i+=2)
{
int tile = m_mainram[i+0] | (m_mainram[i+1] << 8);
gfx->transpen(bitmap, cliprect, tile+base, 0, 0, 0, xdraw, ydraw, 0);
xdraw+=16;
count++;
if (((count % 16) == 0))
{
xdraw -= 256;
ydraw += 16;
}
}
}
void radica_eu3a14_state::draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int xscroll = m_scrollregs[0] | (m_scrollregs[1] << 8);
int yscroll = m_scrollregs[2] | (m_scrollregs[3] << 8);
draw_page(screen,bitmap,cliprect,0, 0-xscroll, 0-yscroll);
draw_page(screen,bitmap,cliprect,1, 256-xscroll, 0-yscroll);
draw_page(screen,bitmap,cliprect,2, 0-xscroll, 224-yscroll);
draw_page(screen,bitmap,cliprect,3, 256-xscroll, 224-yscroll);
draw_page(screen,bitmap,cliprect,0, 512+0-xscroll, 0-yscroll);
draw_page(screen,bitmap,cliprect,1, 512+256-xscroll, 0-yscroll);
draw_page(screen,bitmap,cliprect,2, 512+0-xscroll, 224-yscroll);
draw_page(screen,bitmap,cliprect,3, 512+256-xscroll, 224-yscroll);
draw_page(screen,bitmap,cliprect,0, 0-xscroll, 448+0-yscroll);
draw_page(screen,bitmap,cliprect,1, 256-xscroll, 448+0-yscroll);
draw_page(screen,bitmap,cliprect,2, 0-xscroll, 448+224-yscroll);
draw_page(screen,bitmap,cliprect,3, 256-xscroll, 448+224-yscroll);
draw_page(screen,bitmap,cliprect,0, 512+0-xscroll, 448+0-yscroll);
draw_page(screen,bitmap,cliprect,1, 512+256-xscroll, 448+0-yscroll);
draw_page(screen,bitmap,cliprect,2, 512+0-xscroll, 448+224-yscroll);
draw_page(screen,bitmap,cliprect,3, 512+256-xscroll, 448+224-yscroll);
}
void radica_eu3a14_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// first 4 sprite entries seem to be garbage sprites, so we start at 0x20
// likely we're just interpreting them wrong and they're used for blanking things or clipping?
for (int i = 0x20; i < 0x800; i += 8)
{
/*
+0 e--f hhww flip, enable, height, width
+1 yyyy yyyy ypos
+2 xxxx xxxx xpos
+3 pppp ---- palette
+4 tttt tttt tile bits
+5 tttt tttt
+6 ---- ---- (more tile bits)
+7 ---- ----
*/
int attr = m_mainram[i + 0];
int y = m_mainram[i + 1];
int x = m_mainram[i + 2];
int attr2 = m_mainram[i + 3];
int h = attr & 0x0c;
int w = attr & 0x03;
int flipx = (attr & 0x10) >> 4;
int height = 0;
int width = 0;
int pal = attr2 >> 4;
// no idea
if (attr2 & 0x08)
pal += 0x10;
switch (h)
{
case 0x0:height = 2; break;
case 0x4:height = 4; break;
case 0x8:height = 8; break;
case 0xc:height = 16; break;
}
switch (w)
{
case 0x0:width = 1; break;
case 0x1:width = 2; break;
case 0x2:width = 4; break;
case 0x3:width = 8; break;
}
y -= ((height * 2) - 4);
x -= ((width * 4) - 4);
height *= 4;
x -= 8;
y -= 4;
// int base = 0x18000;
int offset = ((m_mainram[i + 5] << 8) + (m_mainram[i + 4] << 0));
int extra = m_mainram[i + 6];
gfx_element *gfx;
gfx = m_gfxdecode->gfx(1);
#if 0
static int test = 0x0000;
if (machine().input().code_pressed_once(KEYCODE_W))
{
test += 0x2000;
popmessage("%02x", test);
}
if (machine().input().code_pressed_once(KEYCODE_Q))
{
test -= 0x2000;
popmessage("%02x", test);
}
#endif
// this probably comes from somewhere else, base register
offset += 0x8000;
// these additions are odd, because 0x8000 should already be coming
// from the tile bits above
// 2bpp modes, always have bit --- --x- set?
if (extra == 0x02)
{
offset <<= 1;
gfx = m_gfxdecode->gfx(0);
pal = 0;
}
if (extra == 0x0a) // bits ---- x-x-
{
offset += 0x10000;
offset <<= 1;
gfx = m_gfxdecode->gfx(0);
pal = 0;
}
// 4bpp modes, always have bit --- -x-- set?
if (extra == 0x04) // bits ---- -x--
{
//
}
if (extra == 0x0c) // bits ---- xx--
offset += 0x10000;
if (extra == 0x14) // bits ---x -x--
offset += 0x20000;
offset = offset >> 1;
if (attr & 0x80)
{
int count = 0;
for (int yy = 0; yy < height; yy++)
{
for (int xx = 0; xx < width; xx++)
{
gfx->transpen(bitmap, cliprect, offset + count, pal, flipx, 0, x + xx * 8, y + yy, 0);
count++;
}
}
}
}
}
uint32_t radica_eu3a14_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
bitmap.fill(0, cliprect);
handle_palette(screen, bitmap, cliprect);
draw_background(screen, bitmap, cliprect);
draw_sprites(screen, bitmap, cliprect);
return 0;
}
// sound callback
READ8_MEMBER(radica_eu3a14_state::read_full_space)
{
address_space& fullbankspace = m_bank->space(AS_PROGRAM);
return fullbankspace.read_byte(offset);
}
// irq controller seems to be like the Radica Space Invaders
READ8_MEMBER(radica_eu3a14_state::irq_vector_r)
{
if (m_custom_irq)
{
return m_custom_irq_vector >> (offset*8);
}
else
{
uint8_t *rom = memregion("maincpu")->base();
return rom[0x001ffe + offset];
}
}
/*
code at 0000 maps to e000
code at 1000 maps to f000
data at 2000
data at 3000
data at 4000
blank 5000
blank 6000
code at 7000 maps to 3000
code at 8000 maps to 6000
9000 maps to 7000
a000 maps to 8000
b000 maps to 9000
c000 maps to a000
d000 maps to b000
e000 maps to c000
*/
WRITE8_MEMBER(radica_eu3a14_state::radicasi_rombank_hi_w)
{
// written with the banking?
//logerror("%s: radicasi_rombank_hi_w (set ROM bank) %02x\n", machine().describe_context(), data);
m_rombank_hi = data;
m_bank->set_bank(m_rombank_lo | (m_rombank_hi << 8));
}
WRITE8_MEMBER(radica_eu3a14_state::radicasi_rombank_lo_w)
{
//logerror("%s: radicasi_rombank_lo_w (select ROM bank) %02x\n", machine().describe_context(), data);
m_rombank_lo = data;
}
READ8_MEMBER(radica_eu3a14_state::radicasi_rombank_lo_r)
{
return m_rombank_lo;
}
READ8_MEMBER(radica_eu3a14_state::radicasi_pal_ntsc_r)
{
// how best to handle this, we probably need to run the PAL machine at 50hz
// the text under the radica logo differs between regions
logerror("%s: radicasi_pal_ntsc_r (region + more?)\n", machine().describe_context());
return 0xff; // NTSC
//return 0x00; // PAL
}
static ADDRESS_MAP_START( bank_map, AS_PROGRAM, 8, radica_eu3a14_state )
AM_RANGE(0x000000, 0x3fffff) AM_ROM AM_REGION("maincpu", 0)
ADDRESS_MAP_END
static ADDRESS_MAP_START( radica_eu3a14_map, AS_PROGRAM, 8, radica_eu3a14_state )
AM_RANGE(0x0000, 0x01ff) AM_RAM
AM_RANGE(0x0200, 0x1fff) AM_RAM AM_SHARE("mainram") // 200-9ff is sprites? a00 - ??? is tilemap?
AM_RANGE(0x3000, 0x3fff) AM_RAM // runs code from here
AM_RANGE(0x4800, 0x4bff) AM_RAM AM_SHARE("palram")
// similar to eu3a05, at least for pal flags and rom banking
AM_RANGE(0x5007, 0x5007) AM_NOP
AM_RANGE(0x5008, 0x5008) AM_WRITENOP // startup
AM_RANGE(0x5009, 0x5009) AM_NOP
AM_RANGE(0x500a, 0x500a) AM_WRITENOP // startup
AM_RANGE(0x500b, 0x500b) AM_READ(radicasi_pal_ntsc_r) AM_WRITENOP // PAL / NTSC flag at least
AM_RANGE(0x500c, 0x500c) AM_WRITE(radicasi_rombank_hi_w)
AM_RANGE(0x500d, 0x500d) AM_READWRITE(radicasi_rombank_lo_r, radicasi_rombank_lo_w)
// DMA is similar to, but not the same as eu3a05
AM_RANGE(0x500f, 0x5017) AM_RAM AM_SHARE("dmaparams")
AM_RANGE(0x5018, 0x5018) AM_READWRITE(dma_trigger_r, dma_trigger_w)
// probably GPIO like eu3a05, although it access 47/48 as unknown instead of 48/49/4a
AM_RANGE(0x5040, 0x5040) AM_WRITENOP
AM_RANGE(0x5041, 0x5041) AM_READ_PORT("IN0")
AM_RANGE(0x5042, 0x5042) AM_WRITENOP
AM_RANGE(0x5043, 0x5043) AM_NOP
AM_RANGE(0x5044, 0x5044) AM_WRITENOP
AM_RANGE(0x5045, 0x5045) AM_READ_PORT("IN1") AM_WRITENOP
AM_RANGE(0x5046, 0x5046) AM_WRITENOP
AM_RANGE(0x5047, 0x5047) AM_WRITENOP
AM_RANGE(0x5048, 0x5048) AM_WRITENOP
// sound appears to be the same as eu3a05
AM_RANGE(0x5080, 0x5091) AM_DEVREADWRITE("6ch_sound", radica6502_sound_device, radicasi_sound_addr_r, radicasi_sound_addr_w)
AM_RANGE(0x5092, 0x50a3) AM_DEVREADWRITE("6ch_sound", radica6502_sound_device, radicasi_sound_size_r, radicasi_sound_size_w)
AM_RANGE(0x50a4, 0x50a4) AM_DEVREADWRITE("6ch_sound", radica6502_sound_device, radicasi_sound_unk_r, radicasi_sound_unk_w) // read frequently on this
AM_RANGE(0x50a5, 0x50a5) AM_DEVREADWRITE("6ch_sound", radica6502_sound_device, radicasi_sound_trigger_r, radicasi_sound_trigger_w)
AM_RANGE(0x50a6, 0x50a6) AM_WRITENOP // startup
AM_RANGE(0x50a7, 0x50a7) AM_WRITENOP // startup
AM_RANGE(0x50a8, 0x50a8) AM_DEVREAD("6ch_sound", radica6502_sound_device, radicasi_50a8_r)
AM_RANGE(0x50a9, 0x50a9) AM_WRITENOP // startup
// video regs are here this time
AM_RANGE(0x5100, 0x5100) AM_RAM
AM_RANGE(0x5103, 0x5106) AM_RAM
AM_RANGE(0x5107, 0x5107) AM_RAM // on transitions, maybe layer disables?
AM_RANGE(0x5110, 0x5112) AM_RAM // startup
AM_RANGE(0x5113, 0x5113) AM_RAM // written with tilebase?
AM_RANGE(0x5114, 0x5115) AM_RAM AM_SHARE("tilebase")
AM_RANGE(0x5116, 0x5117) AM_RAM
AM_RANGE(0x5121, 0x5124) AM_RAM AM_SHARE("scrollregs")
AM_RANGE(0x5150, 0x5150) AM_RAM // startup
AM_RANGE(0x5151, 0x5153) AM_RAM // startup
AM_RANGE(0x6000, 0xdfff) AM_DEVICE("bank", address_map_bank_device, amap8)
AM_RANGE(0xfffe, 0xffff) AM_READ(irq_vector_r)
AM_RANGE(0xe000, 0xffff) AM_ROM AM_REGION("maincpu", 0x0000)
ADDRESS_MAP_END
READ8_MEMBER(radica_eu3a14_state::dma_trigger_r)
{
logerror("%s: dma_trigger_r\n", machine().describe_context());
return 0;
}
WRITE8_MEMBER(radica_eu3a14_state::dma_trigger_w)
{
uint32_t dmasrc = (m_dmaparams[2] << 16) | (m_dmaparams[1] << 8) | (m_dmaparams[0] << 0);
uint32_t dmadst = (m_dmaparams[5] << 16) | (m_dmaparams[4] << 8) | (m_dmaparams[3] << 0);
uint32_t dmalen = (m_dmaparams[8] << 16) | (m_dmaparams[7] << 8) | (m_dmaparams[6] << 0);
//logerror("%s: dma_trigger_w %02x (src %08x dst %08x size %08x)\n", machine().describe_context(), data, dmasrc, dmadst, dmalen);
address_space& fullbankspace = m_bank->space(AS_PROGRAM);
address_space& destspace = m_maincpu->space(AS_PROGRAM);
if (data == 0x08)
{
for (int i = 0; i < dmalen; i++)
{
uint8_t dat = fullbankspace.read_byte(dmasrc + i);
destspace.write_byte(dmadst + i, dat);
}
}
else
{
logerror("UNKNOWN DMA TRIGGER VALUE\n");
}
}
static INPUT_PORTS_START( radica_eu3a14 )
PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 ) // back / backspin
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) // up and down in the menus should be the trackball?!
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
PORT_START("IN1")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_DIPNAME( 0x08, 0x08, "Track Y test" ) // trackball up/down direction bit? (read in interrupt, increases / decreases a counter)
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_DIPNAME( 0x20, 0x20, "Track X test" ) // trackball left / right direction bit? (read in interrupt, increases / decreases a counter)
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
INPUT_PORTS_END
void radica_eu3a14_state::machine_start()
{
}
void radica_eu3a14_state::machine_reset()
{
// rather be safe
m_maincpu->set_state_int(M6502_S, 0x1ff);
m_bank->set_bank(0x01);
}
TIMER_DEVICE_CALLBACK_MEMBER(radica_eu3a14_state::scanline_cb)
{
// these interrupts need to occur based on how fast the trackball is
// being moved, the direction is read in a port.
int scanline = param;
if (scanline == 20)
{
// vertical trackball
m_custom_irq_vector = 0xffe0;
m_maincpu->set_input_line(INPUT_LINE_IRQ0,HOLD_LINE);
}
if (scanline == 40)
{
// horizontal trackball
m_custom_irq_vector = 0xffe4;
m_maincpu->set_input_line(INPUT_LINE_IRQ0,HOLD_LINE);
}
}
INTERRUPT_GEN_MEMBER(radica_eu3a14_state::interrupt)
{
m_custom_irq = 1;
m_custom_irq_vector = 0xffd4;
m_maincpu->set_input_line(INPUT_LINE_IRQ0,HOLD_LINE);
}
static const gfx_layout helper8x1x2_layout =
{
8,1,
RGN_FRAC(1,1),
2,
{ STEP2(0,1) },
{ STEP8(0,2) },
{ 0 },
8 * 2
};
static const gfx_layout helper8x1x4_layout =
{
8,1,
RGN_FRAC(1,1),
4,
{ STEP4(0,1) },
{ STEP8(0,4) },
{ 0 },
8 * 4
};
static const gfx_layout helper8x1x8_layout =
{
8,1,
RGN_FRAC(1,1),
8,
{ STEP8(0,1) },
{ STEP8(0,8) },
{ 0 },
8 * 8
};
// background
static const gfx_layout helper16x16x8_layout =
{
16,16,
RGN_FRAC(1,1),
8,
{ STEP8(0,1) },
{ STEP16(0,8) },
{ STEP16(0,16*8) },
16 * 16 * 8
};
static GFXDECODE_START( helper )
GFXDECODE_ENTRY( "maincpu", 0, helper8x1x2_layout, 0x0, 128 )
GFXDECODE_ENTRY( "maincpu", 0, helper8x1x4_layout, 0x0, 32 )
GFXDECODE_ENTRY( "maincpu", 0, helper8x1x8_layout, 0x0, 2 )
GFXDECODE_ENTRY( "maincpu", 0, helper16x16x8_layout, 0x0, 2 )
GFXDECODE_END
MACHINE_CONFIG_START(radica_eu3a14_state::radica_eu3a14)
/* basic machine hardware */
MCFG_CPU_ADD("maincpu",M6502,XTAL(21'477'272)/2) // marked as 21'477'270
MCFG_CPU_PROGRAM_MAP(radica_eu3a14_map)
MCFG_CPU_VBLANK_INT_DRIVER("screen", radica_eu3a14_state, interrupt)
MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", radica_eu3a14_state, scanline_cb, "screen", 0, 1)
MCFG_DEVICE_ADD("bank", ADDRESS_MAP_BANK, 0)
MCFG_DEVICE_PROGRAM_MAP(bank_map)
MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE)
MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8)
MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(24)
MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000)
MCFG_GFXDECODE_ADD("gfxdecode", "palette", helper)
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))
MCFG_SCREEN_UPDATE_DRIVER(radica_eu3a14_state, screen_update)
MCFG_SCREEN_SIZE(32*8, 32*8)
MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 28*8-1)
MCFG_SCREEN_PALETTE("palette")
MCFG_PALETTE_ADD("palette", 512)
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_DEVICE_ADD("6ch_sound", RADICA6502_SOUND, 8000)
MCFG_RADICA6502_SOUND_SPACE_READ_CB(READ8(radica_eu3a14_state, read_full_space))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MACHINE_CONFIG_END
ROM_START( rad_gtg )
ROM_REGION( 0x400000, "maincpu", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "goldentee.bin", 0x000000, 0x400000, CRC(b1985c63) SHA1(c42a59fcb665eb801d9ca5312b90e39333e52de4) )
ROM_END
CONS( 2006, rad_gtg, 0, 0, radica_eu3a14, radica_eu3a14, radica_eu3a14_state, 0, "Radica (licensed from Incredible Technologies)", "Golden Tee Golf: Home Edition", MACHINE_NOT_WORKING )

View File

@ -1342,12 +1342,18 @@ ROM_START( wirels60 )
ROM_END
// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS
CONS( 2004, batmantv, vii, 0, batman, batman, vii_state, batman, "JAKKS Pacific Inc / HotGen Ltd", "The Batman", MACHINE_NO_SOUND )
// VTech systems
CONS( 2005, vsmile, 0, 0, vsmile, vsmile, vii_state, vsmile, "VTech", "V.Smile (US)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
CONS( 2005, vsmileg, vsmile, 0, vsmile, vsmile, vii_state, vsmile, "VTech", "V.Smile (Germany)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
CONS( 2005, vsmilef, vsmile, 0, vsmile, vsmile, vii_state, vsmile, "VTech", "V.Smile (France)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
CONS( 2005, vsmileb, 0, 0, vsmile, vsmile, vii_state, vsmile, "VTech", "V.Smile Baby (US)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
CONS( 2007, vii, 0, 0, vii, vii, vii_state, vii, "Jungle Soft / KenSingTon / Chintendo / Siatronics", "Vii", MACHINE_NO_SOUND )
CONS( 2008, walle, vii, 0, batman, walle, vii_state, walle, "JAKKS Pacific Inc", "Wall-E", MACHINE_NO_SOUND )
// Jungle Soft TV games
CONS( 2007, vii, 0, 0, vii, vii, vii_state, vii, "Jungle Soft / KenSingTon / Chintendo / Siatronics", "Vii", MACHINE_NO_SOUND | MACHINE_NOT_WORKING ) // some games run, others crash
CONS( 2010, zone60, 0, 0, wirels60, wirels60, vii_state, wirels60, "Jungle Soft / Ultimate Products (HK) Ltd", "Zone 60", MACHINE_NO_SOUND )
CONS( 2010, wirels60, 0, 0, wirels60, wirels60, vii_state, wirels60, "Jungle Soft / Kids Station Toys Inc", "Wireless 60", MACHINE_NO_SOUND )
// JAKKS Pacific Inc TV games
CONS( 2004, batmantv, 0, 0, batman, batman, vii_state, batman, "JAKKS Pacific Inc / HotGen Ltd", "The Batman", MACHINE_NO_SOUND )
CONS( 2008, walle, 0, 0, batman, walle, vii_state, walle, "JAKKS Pacific Inc", "Wall-E", MACHINE_NO_SOUND )

View File

@ -0,0 +1,46 @@
// license:BSD-3-Clause
// copyright-holders:Sandro Ronco
// CPU die is an Elan EU3A12, it isn't clear what it is compatible with (16-bit?)
#include "emu.h"
#include "screen.h"
class vreadere_state : public driver_device
{
public:
vreadere_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
{ }
virtual uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void vreadere(machine_config &config);
};
uint32_t vreadere_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
return 0;
}
static INPUT_PORTS_START( vreadere )
INPUT_PORTS_END
MACHINE_CONFIG_START(vreadere_state::vreadere)
/* basic machine hardware */
// MCFG_CPU_ADD("maincpu", unknown, unknown) // CPU type is unknown, epoxy blob
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(50)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
MCFG_SCREEN_SIZE(512, 256)
MCFG_SCREEN_VISIBLE_AREA(0, 512-1, 0, 256-1)
MCFG_SCREEN_UPDATE_DRIVER( vreadere_state, screen_update )
MACHINE_CONFIG_END
ROM_START( vreadere )
ROM_REGION(0x400000, "maincpu", 0)
ROM_LOAD( "27-08291.U2", 0x000000, 0x400000, CRC(f2eb801f) SHA1(33e2d28ab2f04b17f66880898832265d50de54d4) )
ROM_END
COMP( 2004, vreadere, 0, 0, vreadere, vreadere, vreadere_state, 0, "Video Technology", "Reader Laptop E (Germany)", MACHINE_IS_SKELETON )

View File

@ -0,0 +1,98 @@
// license:BSD-3-Clause
// copyright-holders:Sandro Ronco
// Unknown CPU type
/*
Leader 8008 CX (German version)
+---+-----------+-----+-----------------------+-----+-----+-----+
| |SERIAL PORT| |PARALLEL PORT (PRINTER)| |MOUSE| |
| +-----------+ +-----------------------+ +-----+ |
| |
| |
| |
| |
| +----+ |
| | A0 | |
| +----+ |
| |
| |
| +--------+ |
| | | |
| CPU | VTECH | +------+ |
| |LHMV5GNS| | | |
| | | |GM76U8| |
| |1999 | |128CLF| |
| |27-6393-| |W85 | |
| +-----------+ |11 | | | |
| |27-6296-0-0| | | | | |
| |47C241M NH7| | | +------+ |
| +-----------+ +--------+ |
| |
| |
| |
| |
+---------------------------------------------------------------+
CPU = epoxy blob
GM76U8128CLFW85 = LGS / Hynix 131,072 WORDS x 8 BIT CMOS SRAM
TMP47C241MG = TCLS-47 series 4-bit CPU with 2048x8 internal ROM
*/
#include "emu.h"
#include "screen.h"
class gl8008cx_state : public driver_device
{
public:
gl8008cx_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
{ }
virtual uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void gl8008cx(machine_config &config);
};
uint32_t gl8008cx_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
return 0;
}
static INPUT_PORTS_START( gl8008cx )
INPUT_PORTS_END
MACHINE_CONFIG_START(gl8008cx_state::gl8008cx)
/* basic machine hardware */
// MCFG_CPU_ADD("maincpu", unknown, unknown) // CPU type is unknown, epoxy blob
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(50)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
MCFG_SCREEN_SIZE(512, 256)
MCFG_SCREEN_VISIBLE_AREA(0, 512-1, 0, 256-1)
MCFG_SCREEN_UPDATE_DRIVER( gl8008cx_state, screen_update )
MACHINE_CONFIG_END
ROM_START( gl8008cx )
ROM_REGION(0x200000, "maincpu", 0)
ROM_LOAD( "27-6393-11.u1", 0x0000, 0x200000, CRC(fd49db46) SHA1(fc55bb31f42068f9d6cc8e2c2f419c3c4edb4fe6) )
ROM_REGION(0x800, "subcpu", 0)
ROM_LOAD( "27-6296-0-0.u3", 0x000, 0x800, NO_DUMP )
ROM_END
ROM_START( bs9009cx )
ROM_REGION(0x200000, "maincpu", 0)
ROM_LOAD( "27-6603-01.u1", 0x0000, 0x200000, CRC(2c299f65) SHA1(44b37007a7c4087d7c2bd8c24907402bfe445ba4) )
ROM_REGION(0x800, "subcpu", 0)
ROM_LOAD( "mcu.u5", 0x000, 0x800, NO_DUMP )
ROM_END
COMP( 1999, gl8008cx, 0, 0, gl8008cx, gl8008cx, gl8008cx_state, 0, "Video Technology", "Genius Leader 8008 CX (Germany)", MACHINE_IS_SKELETON)
COMP( 1999, bs9009cx, 0, 0, gl8008cx, gl8008cx, gl8008cx_state, 0, "Video Technology", "BrainStation 9009 CXL (Germany)", MACHINE_IS_SKELETON)

View File

@ -0,0 +1,46 @@
// license:BSD-3-Clause
// copyright-holders:Sandro Ronco
// Unknown CPU type
#include "emu.h"
#include "screen.h"
class glmmc_state : public driver_device
{
public:
glmmc_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
{ }
virtual uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void glmmc(machine_config &config);
};
uint32_t glmmc_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
return 0;
}
static INPUT_PORTS_START( glmmc )
INPUT_PORTS_END
MACHINE_CONFIG_START(glmmc_state::glmmc)
/* basic machine hardware */
// MCFG_CPU_ADD("maincpu", unknown, unknown) // CPU type is unknown, epoxy blob
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(50)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
MCFG_SCREEN_SIZE(512, 256)
MCFG_SCREEN_VISIBLE_AREA(0, 512-1, 0, 256-1)
MCFG_SCREEN_UPDATE_DRIVER( glmmc_state, screen_update )
MACHINE_CONFIG_END
ROM_START( glmmc )
ROM_REGION(0x200000, "maincpu", 0)
ROM_LOAD( "27-5889-00.bin", 0x000000, 0x080000, CRC(5e2c6359) SHA1(cc01c7bd5c87224b63dd1044db5a36a5cb7824f1) )
ROM_END
COMP( 19??, glmmc, 0, 0, glmmc, glmmc, glmmc_state, 0, "Video Technology", "Genius Leader Master Mega Color (Germany)", MACHINE_IS_SKELETON)

View File

@ -1,17 +1,15 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
#ifndef MAME_INCLUDES_MEGADRIV_ACBL_H
#define MAME_INCLUDES_MEGADRIV_ACBL_H
class md_boot_state : public md_base_state
{
public:
md_boot_state(const machine_config &mconfig, device_type type, const char *tag)
: md_base_state(mconfig, type, tag) { m_protcount = 0;}
// bootleg specific
int m_aladmdb_mcu_port;
int m_protcount;
DECLARE_DRIVER_INIT(aladmdb);
DECLARE_DRIVER_INIT(mk3mdb);
DECLARE_DRIVER_INIT(ssf2mdb);
@ -38,4 +36,12 @@ public:
void puckpkmn(machine_config &config);
void jzth(machine_config &config);
void puckpkmna(machine_config &config);
private:
// bootleg specific
int m_aladmdb_mcu_port;
int m_protcount;
};
#endif // MAME_INCLUDES_MEGADRIV_ACBL_H

View File

@ -0,0 +1,34 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
#ifndef MAME_INCLUDES_MEGADRIV_RAD_H
#define MAME_INCLUDES_MEGADRIV_RAD_H
class megadriv_radica_state : public md_base_state
{
public:
megadriv_radica_state(const machine_config &mconfig, device_type type, const char *tag)
: md_base_state(mconfig, type, tag),
m_bank(0),
m_rom(*this, "maincpu")
{}
DECLARE_DRIVER_INIT(megadriv_radica_6button_pal);
DECLARE_MACHINE_START(megadriv_radica_6button);
DECLARE_MACHINE_START(megadriv_radica_3button);
DECLARE_MACHINE_RESET(megadriv_radica);
DECLARE_READ16_MEMBER(read);
DECLARE_READ16_MEMBER(read_a13);
void megadriv_radica_6button_pal(machine_config &config);
void megadriv_radica_3button_ntsc(machine_config &config);
void megadriv_radica_3button_pal(machine_config &config);
private:
int m_bank;
required_region_ptr<uint16_t> m_rom;
};
#endif // MAME_INCLUDES_MEGADRIV_RAD_H

View File

@ -0,0 +1,84 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
#include "emu.h"
#include "rad_eu3a05gpio.h"
DEFINE_DEVICE_TYPE(RADICA6502_GPIO, radica6502_gpio_device, "radica6502gpio", "Radica 6502 GPIO")
radica6502_gpio_device::radica6502_gpio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, RADICA6502_GPIO, tag, owner, clock)
, m_space_read0_cb(*this)
, m_space_read1_cb(*this)
, m_space_read2_cb(*this)
{
}
void radica6502_gpio_device::device_start()
{
m_space_read0_cb.resolve_safe(0xff);
m_space_read1_cb.resolve_safe(0xff);
m_space_read2_cb.resolve_safe(0xff);
}
void radica6502_gpio_device::device_reset()
{
for (int i = 0; i < 3; i++)
{
m_ddr[i] = 0;
m_unk[i] = 0;
}
}
uint8_t radica6502_gpio_device::read_port_data(int which)
{
//todo, actually use the direction registers
switch (which)
{
case 0: return m_space_read0_cb();
case 1: return m_space_read1_cb();
case 2: return m_space_read2_cb();
}
return 0xff;
}
uint8_t radica6502_gpio_device::read_direction(int which)
{
return m_ddr[which];
}
READ8_MEMBER(radica6502_gpio_device::gpio_r)
{
int port = offset/2;
if (!(offset&1)) return read_direction(port);
else return read_port_data(port);
}
void radica6502_gpio_device::write_port_data(int which, uint8_t data)
{
//todo, actually use the direction registers
logerror("%s: write_port_data (port %d) %02x (direction register %02x)\n", machine().describe_context(), which, data, m_ddr[which]);
}
void radica6502_gpio_device::write_direction(int which, uint8_t data)
{
logerror("%s: write_direction (port %d) %02x\n", machine().describe_context(), which, data);
m_ddr[which] = data;
}
WRITE8_MEMBER(radica6502_gpio_device::gpio_w)
{
int port = offset/2;
if (!(offset&1)) return write_direction(port, data);
else return write_port_data(port, data);
}
WRITE8_MEMBER(radica6502_gpio_device::gpio_unk_w)
{
logerror("%s: gpio_unk_w (port %d) %02x (direction register %02x)\n", machine().describe_context(), offset, data, m_ddr[offset]);
}

View File

@ -0,0 +1,52 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
#ifndef MAME_AUDIO_RAD_EU3A05GPIO_H
#define MAME_AUDIO_RAD_EU3A05GPIO_H
#define MCFG_RADICA6502_GPIO_READ_PORT0_CB(_devcb) \
devcb = &radica6502_gpio_device::set_gpio_read_0_callback(*device, DEVCB_##_devcb);
#define MCFG_RADICA6502_GPIO_READ_PORT1_CB(_devcb) \
devcb = &radica6502_gpio_device::set_gpio_read_1_callback(*device, DEVCB_##_devcb);
#define MCFG_RADICA6502_GPIO_READ_PORT2_CB(_devcb) \
devcb = &radica6502_gpio_device::set_gpio_read_2_callback(*device, DEVCB_##_devcb);
class radica6502_gpio_device : public device_t
{
public:
radica6502_gpio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template <class Object> static devcb_base &set_gpio_read_0_callback(device_t &device, Object &&cb) { return downcast<radica6502_gpio_device &>(device).m_space_read0_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_gpio_read_1_callback(device_t &device, Object &&cb) { return downcast<radica6502_gpio_device &>(device).m_space_read1_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_gpio_read_2_callback(device_t &device, Object &&cb) { return downcast<radica6502_gpio_device &>(device).m_space_read2_cb.set_callback(std::forward<Object>(cb)); }
DECLARE_READ8_MEMBER(gpio_r);
DECLARE_WRITE8_MEMBER(gpio_w);
DECLARE_WRITE8_MEMBER(gpio_unk_w);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
private:
devcb_read8 m_space_read0_cb;
devcb_read8 m_space_read1_cb;
devcb_read8 m_space_read2_cb;
uint8_t read_port_data(int which);
uint8_t read_direction(int which);
void write_port_data(int which, uint8_t data);
void write_direction(int which, uint8_t data);
uint8_t m_ddr[3];
uint8_t m_unk[3];
};
DECLARE_DEVICE_TYPE(RADICA6502_GPIO, radica6502_gpio_device)
#endif // MAME_AUDIO_RAD_EU3A05GPIO_H

View File

@ -13742,13 +13742,9 @@ suprpokrb // (c) 1986 Grayhound Electronics
geneve // 1987? Myarc Geneve 9640
@source:geniusiq.cpp
bs9009cx // 1999 BrainStation 9009 CXL (Germany)
gl8008cx // 1999 Genius Leader 8008 CX (Germany)
glmmc // 199? Genius Master Mega Color
iq128 // 1997 Genius IQ 128 (Germany)
iq128_fr // 1997 Genius PC (France)
iqtv512 // IQ TV512 (Germany)
iqunlim // 199? IQ Unlimited (680x0)
itunlim // 199? IT Unlimited
@source:genpc.cpp
@ -15388,6 +15384,9 @@ iq151 //
grndtour // (c) 1993
iqblock // (c) 1993
@source:iqunlim.cpp
iqunlim // 199? IQ Unlimited (680x0)
@source:iris3130.cpp
sgi_ip2 // IP2: IRIS 3xx0, 68020, 16MHz
@ -20499,7 +20498,7 @@ wmegam2 // 1993 Victor Wondermega M2 (Japan)
xeye // 1993 JVC X'eye (USA)
dcat16 //
@source:megadrvb.cpp
@source:megadriv_acbl.cpp
aladmdb // MegaDrive-based hack
mk3mdb // MegaDrive-based hack
sonic2mb // MegaDrive-based hack
@ -20507,6 +20506,11 @@ srmdb // MegaDrive-based hack
ssf2mdb // MegaDrive-based hack
topshoot // (c) 1995 Sun Mixing
@source:megadriv_rad.cpp
rad_sf // (c)2004 Radica
rad_gen1 // (c)2004 Radica
rad_ssoc // (c)2004 Radica
@source:megaphx.cpp
megaphx // (c) 1991 Dinamic / Inder
@ -32429,7 +32433,10 @@ r9751 // ROLM 9751 phone system
@source:rabbit.cpp
rabbit // (c) 1997 Electronic Arts
@source:radicasi.cpp
@source:rad_eu3a14.cpp
rad_gtg
@source:rad_eu3a05.cpp
rad_sinv
rad_tetr
@ -37991,6 +37998,16 @@ laser350 // 1984? Laser 350
laser500 // 1984? Laser 500
laser700 // 1984? Laser 700
@source:vtech_eu3a12.cpp
vreadere
@source:vtech_unk1.cpp
bs9009cx // 1999 BrainStation 9009 CXL (Germany)
gl8008cx // 1999 Genius Leader 8008 CX (Germany)
@source:vtech_unk2.cpp
glmmc // 199? Genius Master Mega Color
@source:vulgus.cpp
mach9 // bootleg (ITISA)
vulgus // 5/1984 (c) 1984

View File

@ -309,6 +309,7 @@ intv.cpp
ipc.cpp
ipds.cpp
iq151.cpp
iqunlim.cpp
iris3130.cpp
irisha.cpp
isbc.cpp
@ -374,6 +375,7 @@ mc8030.cpp
mcb216.cpp
mccpm.cpp
megadriv.cpp
megadriv_rad.cpp
mekd2.cpp
mephisto.cpp
mephisto_montec.cpp
@ -566,7 +568,8 @@ qvt201.cpp
qvt6800.cpp
qx10.cpp
r9751.cpp
radicasi.cpp
rad_eu3a05.cpp
rad_eu3a14.cpp
radio86.cpp
rainbow.cpp
rambo.cpp
@ -765,6 +768,9 @@ vt520.cpp
vta2000.cpp
vtech1.cpp
vtech2.cpp
vtech_eu3a12.cpp
vtech_unk1.cpp
vtech_unk2.cpp
wangpc.cpp
wicat.cpp
wswan.cpp