mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
magicard.cpp: map RAM at $008***** on several entries, tie vblank irqs to int2_w, update QA
* This allows puzzleme to enter into attract mode;
This commit is contained in:
parent
26fd98c3c8
commit
2c6fb6d831
@ -7,6 +7,23 @@
|
||||
|
||||
Preliminary driver by Roberto Fresca, David Haywood & Angelo Salese
|
||||
|
||||
TODO:
|
||||
- driver based off raw guesses (we don't have relevant key docs);
|
||||
- Device-ize 66470
|
||||
Handles video and CRTC, has annoying blitter ops (magicard text on
|
||||
playfield at very least, most likely service mode too);
|
||||
- Verify RAM config on PCBs;
|
||||
- I/Os;
|
||||
- UART;
|
||||
- magicardj & magicle: hook-up PIC;
|
||||
- magicardj: expects GFX pitch width to be 320 rather than 336 for
|
||||
title screen to draw correctly;
|
||||
- hotslots, quingo: sets up 68070 timer chs 1 & 2, currently unsupported;
|
||||
- magicardj: keeps reading timer 0 low byte, expects a live change?
|
||||
- bigdeal0: punts with an address error PC=0x60ea3a A2=$c71c38e3;
|
||||
- lucky7i, unkte06, magicardw: loops on i2c accesses;
|
||||
- Is int1_w unconnected? Doesn't seem to be enabled by games so far;
|
||||
- puzzleme: confirm it has a ssg (mapping matches hotslots);
|
||||
|
||||
Games running on this hardware:
|
||||
|
||||
@ -381,27 +398,11 @@
|
||||
F = 74HCU04D
|
||||
G = 74HC74D
|
||||
|
||||
*******************************************************************************
|
||||
|
||||
TODO:
|
||||
|
||||
- Proper handling of the 68070 (68k with 32 address lines instead of 24)
|
||||
& handle the extra features properly (UART, DMA, timers, etc.)
|
||||
|
||||
- Proper emulation of the 66470 Video Chip (still many unhandled features)
|
||||
|
||||
- Inputs;
|
||||
|
||||
- Many unknown memory maps;
|
||||
|
||||
- Proper memory map and machine driver for magicardj & magicle.
|
||||
(different sound chip, extra undumped rom and PIC controller)
|
||||
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "machine/scc68070.h"
|
||||
#include "machine/timer.h"
|
||||
#include "sound/ay8910.h"
|
||||
#include "sound/saa1099.h"
|
||||
#include "video/ramdac.h"
|
||||
@ -419,13 +420,14 @@ class magicard_state : public driver_device
|
||||
{
|
||||
public:
|
||||
magicard_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag),
|
||||
m_magicram(*this, "magicram"),
|
||||
m_magicramb(*this, "magicramb"),
|
||||
m_pcab_vregs(*this, "pcab_vregs"),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_screen(*this, "screen"),
|
||||
m_palette(*this, "palette") { }
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_magicram(*this, "magicram")
|
||||
, m_magicramb(*this, "magicramb")
|
||||
, m_pcab_vregs(*this, "pcab_vregs")
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_screen(*this, "screen")
|
||||
, m_palette(*this, "palette")
|
||||
{ }
|
||||
|
||||
void magicard(machine_config &config);
|
||||
void hotslots(machine_config &config);
|
||||
@ -443,12 +445,12 @@ private:
|
||||
virtual void machine_reset() override;
|
||||
virtual void video_start() override;
|
||||
uint32_t screen_update_magicard(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
INTERRUPT_GEN_MEMBER(magicard_irq);
|
||||
required_device<cpu_device> m_maincpu;
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(magicard_scanline_cb);
|
||||
required_device<scc68070_device> m_maincpu;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
void hotslots_mem(address_map &map);
|
||||
void magicard_mem(address_map &map);
|
||||
void hotslots_map(address_map &map);
|
||||
void magicard_map(address_map &map);
|
||||
void ramdac_map(address_map &map);
|
||||
};
|
||||
|
||||
@ -646,9 +648,11 @@ void magicard_state::video_start()
|
||||
|
||||
uint32_t magicard_state::screen_update_magicard(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
bitmap.fill(m_palette->black_pen(), cliprect); //TODO
|
||||
// TODO: border & genlock
|
||||
bitmap.fill(m_palette->black_pen(), cliprect);
|
||||
|
||||
if(!(SCC_DE_VREG)) //display enable
|
||||
// punt if display enable is off
|
||||
if(!(SCC_DE_VREG))
|
||||
return 0;
|
||||
|
||||
uint32_t count = ((SCC_VSR_VREG) / 2);
|
||||
@ -730,13 +734,11 @@ uint16_t magicard_state::philips_66470_r(offs_t offset)
|
||||
uint8_t vdisp;
|
||||
vdisp = m_screen->vpos() < 256;
|
||||
|
||||
return (m_pcab_vregs[offset] & 0xff7f) | vdisp << 7; //TODO
|
||||
// TODO: other bits
|
||||
return (m_pcab_vregs[offset] & 0xff7f) | vdisp << 7;
|
||||
}
|
||||
}
|
||||
|
||||
//printf("[%04x]\n",offset*2);
|
||||
|
||||
|
||||
return m_pcab_vregs[offset];
|
||||
}
|
||||
|
||||
@ -756,31 +758,38 @@ void magicard_state::philips_66470_w(offs_t offset, uint16_t data, uint16_t mem_
|
||||
* Memory Maps *
|
||||
*************************/
|
||||
|
||||
void magicard_state::magicard_mem(address_map &map)
|
||||
void magicard_state::magicard_map(address_map &map)
|
||||
{
|
||||
// map.global_mask(0x1fffff);
|
||||
map(0x00000000, 0x001ffbff).mirror(0x00200000).ram().share("magicram");
|
||||
map(0x00600000, 0x007ffbff).ram().share("magicramb");
|
||||
/* 001ffc00-001ffdff System I/O */
|
||||
map(0x001ffc00, 0x001ffc01).mirror(0x7fe00000).r(FUNC(magicard_state::test_r));
|
||||
map(0x001ffc00, 0x001ffc01).mirror(0x7fe00000).portr("SYSTEM");
|
||||
map(0x001ffc40, 0x001ffc41).mirror(0x7fe00000).r(FUNC(magicard_state::test_r));
|
||||
map(0x001ffd01, 0x001ffd01).mirror(0x7fe00000).w("ramdac", FUNC(ramdac_device::index_w));
|
||||
map(0x001ffd03, 0x001ffd03).mirror(0x7fe00000).w("ramdac", FUNC(ramdac_device::pal_w));
|
||||
map(0x001ffd05, 0x001ffd05).mirror(0x7fe00000).w("ramdac", FUNC(ramdac_device::mask_w));
|
||||
map(0x001ffd40, 0x001ffd43).mirror(0x7fe00000).w("saa", FUNC(saa1099_device::write)).umask16(0x00ff);
|
||||
map(0x001ffd80, 0x001ffd81).mirror(0x7fe00000).r(FUNC(magicard_state::test_r));
|
||||
map(0x001ffd80, 0x001ffd81).mirror(0x7fe00000).nopw(); //?
|
||||
map(0x001ffd80, 0x001ffd81).mirror(0x7fe00000).nopw();
|
||||
map(0x001fff80, 0x001fffbf).mirror(0x7fe00000).ram(); //DRAM I/O, not accessed by this game, CD buffer?
|
||||
map(0x001fffe0, 0x001fffff).mirror(0x7fe00000).rw(FUNC(magicard_state::philips_66470_r), FUNC(magicard_state::philips_66470_w)).share("pcab_vregs"); //video registers
|
||||
map(0x001fffe0, 0x001fffff).mirror(0x7fe00000).rw(FUNC(magicard_state::philips_66470_r), FUNC(magicard_state::philips_66470_w)).share("pcab_vregs");
|
||||
}
|
||||
|
||||
void magicard_state::hotslots_mem(address_map &map)
|
||||
// Different PAL mapping?
|
||||
void magicard_state::hotslots_map(address_map &map)
|
||||
{
|
||||
// map.global_mask(0x1fffff);
|
||||
// puzzleme sets $0080000a as default reset vector, magicardf sets $00800078
|
||||
// latter also will address error if we mirror with bank A by logic (i.e. .mirror(0x00a00000))
|
||||
// we currently map it to B bank for now
|
||||
map(0x00000000, 0x001ffbff).mirror(0x00200000).ram().share("magicram");
|
||||
map(0x00600000, 0x007ffbff).ram().share("magicramb");
|
||||
map(0x00800000, 0x009ffbff).ram().share("magicramb");
|
||||
map(0x001fff80, 0x001fffbf).mirror(0x7fe00000).ram(); //DRAM I/O, not accessed by this game, CD buffer?
|
||||
map(0x001fffe0, 0x001fffff).mirror(0x7fe00000).rw(FUNC(magicard_state::philips_66470_r), FUNC(magicard_state::philips_66470_w)).share("pcab_vregs"); //video registers
|
||||
map(0x001fffe0, 0x001fffff).mirror(0x7fe00000).rw(FUNC(magicard_state::philips_66470_r), FUNC(magicard_state::philips_66470_w)).share("pcab_vregs");
|
||||
map(0x00400000, 0x00403fff).ram(); // ? bigdeal0, magicardj accesses this as scratchram
|
||||
map(0x00411000, 0x00411001).portr("SYSTEM");
|
||||
map(0x00414001, 0x00414001).w("ramdac", FUNC(ramdac_device::index_w));
|
||||
map(0x00414003, 0x00414003).w("ramdac", FUNC(ramdac_device::pal_w));
|
||||
map(0x00414005, 0x00414005).w("ramdac", FUNC(ramdac_device::mask_w));
|
||||
@ -795,12 +804,64 @@ void magicard_state::hotslots_mem(address_map &map)
|
||||
*************************/
|
||||
|
||||
static INPUT_PORTS_START( magicard )
|
||||
PORT_START("SYSTEM")
|
||||
PORT_DIPNAME( 0x01, 0x01, "SYSTEM0" )
|
||||
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
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_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x0100, 0x0100, "SYSTEM1" )
|
||||
PORT_DIPSETTING( 0x0100, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
|
||||
// Used by magicard to enter into gameplay
|
||||
PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x0200, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x0400, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x0800, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x1000, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x2000, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
|
||||
// coin sound in magicard (but no GFX is updated?)
|
||||
PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x8000, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
void magicard_state::machine_reset()
|
||||
{
|
||||
uint16_t *src = (uint16_t*)memregion("maincpu" )->base();
|
||||
// TODO: confirm reset state
|
||||
uint16_t *src = (uint16_t*)memregion("maincpu")->base();
|
||||
uint16_t *dst = m_magicram;
|
||||
memcpy (dst, src, 0x80000);
|
||||
memcpy (dst + 0x40000 * 1, src, 0x80000);
|
||||
@ -818,20 +879,17 @@ void magicard_state::machine_reset()
|
||||
* Machine Drivers *
|
||||
*************************/
|
||||
|
||||
|
||||
/*Probably there's a mask somewhere if it REALLY uses irqs at all...irq vectors dynamically changes after some time.*/
|
||||
INTERRUPT_GEN_MEMBER(magicard_state::magicard_irq)
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(magicard_state::magicard_scanline_cb)
|
||||
{
|
||||
#if 0
|
||||
if(machine().input().code_pressed(KEYCODE_Z)) { //vblank?
|
||||
m_vector = 0xe4;
|
||||
device.execute().set_input_line(1, HOLD_LINE);
|
||||
int scanline = param;
|
||||
|
||||
// hotslots and quingo definitely wants two irqs per frame,
|
||||
// reading vdisp as branch dispatch and setting a specific flag in RAM
|
||||
if (scanline == 256 || scanline == 0)
|
||||
{
|
||||
m_maincpu->int2_w(1);
|
||||
m_maincpu->int2_w(0);
|
||||
}
|
||||
if(machine().input().code_pressed(KEYCODE_X)) { //uart irq
|
||||
m_vector = 0xf0;
|
||||
device.execute().set_input_line(1, HOLD_LINE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void magicard_state::ramdac_map(address_map &map)
|
||||
@ -842,15 +900,17 @@ void magicard_state::ramdac_map(address_map &map)
|
||||
|
||||
void magicard_state::magicard(machine_config &config)
|
||||
{
|
||||
SCC68070(config, m_maincpu, CLOCK_A); /* SCC-68070 CCA84 datasheet */
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &magicard_state::magicard_mem);
|
||||
m_maincpu->set_vblank_int("screen", FUNC(magicard_state::magicard_irq)); /* no interrupts? (it erases the vectors..) */
|
||||
SCC68070(config, m_maincpu, CLOCK_A); /* SCC-68070 CCA84 */
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &magicard_state::magicard_map);
|
||||
TIMER(config, "scantimer").configure_scanline(FUNC(magicard_state::magicard_scanline_cb), "screen", 0, 1);
|
||||
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
// TODO: has dynamic resolution, fill defaults and convert to set_raw
|
||||
m_screen->set_refresh_hz(50);
|
||||
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(0));
|
||||
m_screen->set_size(400, 300);
|
||||
m_screen->set_visarea(0, 320-1, 0, 256-1); //dynamic resolution,TODO
|
||||
m_screen->set_visarea(0, 320-1, 0, 256-1);
|
||||
// m_screen->screen_vblank().set(m_maincpu, FUNC(scc68070_device::int2_w));
|
||||
m_screen->set_screen_update(FUNC(magicard_state::screen_update_magicard));
|
||||
|
||||
PALETTE(config, m_palette).set_entries(0x100);
|
||||
@ -864,7 +924,7 @@ void magicard_state::magicard(machine_config &config)
|
||||
void magicard_state::hotslots(machine_config &config)
|
||||
{
|
||||
magicard(config);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &magicard_state::hotslots_mem);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &magicard_state::hotslots_map);
|
||||
|
||||
config.device_remove("saa");
|
||||
YMZ284(config, "ssg", 4000000).add_route(ALL_OUTPUTS, "mono", 1.0);
|
||||
@ -1134,7 +1194,7 @@ ROM_END
|
||||
Puzzle Me!
|
||||
Impera.
|
||||
|
||||
vectors are wrong.
|
||||
TODO: PCB
|
||||
*/
|
||||
ROM_START( puzzleme )
|
||||
ROM_REGION( 0x80000, "maincpu", 0 ) /* 68070 Code & GFX */
|
||||
@ -1192,15 +1252,15 @@ void magicard_state::init_magicard()
|
||||
GAME( 199?, magicard, 0, magicard, magicard, magicard_state, init_magicard, ROT0, "Impera", "Magic Card (set 1)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
|
||||
GAME( 199?, magicarda, magicard, magicard, magicard, magicard_state, init_magicard, ROT0, "Impera", "Magic Card (set 2)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
|
||||
GAME( 199?, magicardb, magicard, magicard, magicard, magicard_state, init_magicard, ROT0, "Impera", "Magic Card (set 3)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
|
||||
GAME( 1994, magicarde, magicard, magicard, magicard, magicard_state, init_magicard, ROT0, "Impera", "Magic Card Export 94", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
|
||||
GAME( 1994, magicardf, magicard, magicard, magicard, magicard_state, init_magicard, ROT0, "Impera", "Magic Export (V.211A)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
|
||||
GAME( 1998, magicardj, magicard, magicard, magicard, magicard_state, init_magicard, ROT0, "Impera", "Magic Card Jackpot (4.01)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
|
||||
GAME( 1994, magicarde, magicard, hotslots, magicard, magicard_state, init_magicard, ROT0, "Impera", "Magic Card Export 94", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
|
||||
GAME( 1994, magicardf, magicard, hotslots, magicard, magicard_state, init_magicard, ROT0, "Impera", "Magic Export (V.211A)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
|
||||
GAME( 1998, magicardj, 0, hotslots, magicard, magicard_state, init_magicard, ROT0, "Impera", "Magic Card III Jackpot (4.01)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
|
||||
GAME( 1993, magicardw, magicard, magicard, magicard, magicard_state, init_magicard, ROT0, "Impera", "Magic Card - Wien (Sicherheitsversion 1.2)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
|
||||
GAME( 2001, magicle, 0, magicard, magicard, magicard_state, init_magicard, ROT0, "Impera", "Magic Lotto Export (5.03)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
|
||||
GAME( 2002, hotslots, 0, hotslots, magicard, magicard_state, init_magicard, ROT0, "Impera", "Hot Slots (6.00)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
|
||||
GAME( 1999, quingo, 0, hotslots, magicard, magicard_state, init_magicard, ROT0, "Impera", "Quingo Export (5.00)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
|
||||
GAME( 1999, belslots, 0, hotslots, magicard, magicard_state, init_magicard, ROT0, "Impera", "Bel Slots Export (5.01)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
|
||||
GAME( 2001, bigdeal0, 0, hotslots, magicard, magicard_state, init_magicard, ROT0, "Impera", "Big Deal Belgien (5.04)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
|
||||
GAME( 199?, puzzleme, 0, magicard, magicard, magicard_state, init_magicard, ROT0, "Impera", "Puzzle Me!", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
|
||||
GAME( 199?, unkte06, 0, magicard, magicard, magicard_state, init_magicard, ROT0, "Impera", "unknown 'TE06'", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
|
||||
GAME( 199?, puzzleme, 0, hotslots, magicard, magicard_state, init_magicard, ROT0, "Impera", "Puzzle Me!", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
|
||||
GAME( 199?, unkte06, 0, magicard, magicard, magicard_state, init_magicard, ROT0, "Impera", "unknown Poker 'TE06'", MACHINE_NO_SOUND | MACHINE_NOT_WORKING ) // strings in ROM
|
||||
GAME( 199?, lucky7i, 0, magicard, magicard, magicard_state, init_magicard, ROT0, "Impera", "Lucky 7 (Impera)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
|
||||
|
Loading…
Reference in New Issue
Block a user