Add M52 (Moon Patrol) and an Irem Sound device. Hook it up to M62.

This commit is contained in:
iq_132 2018-08-15 23:36:20 +00:00
parent f55e6c679c
commit 823e9de53e
5 changed files with 1317 additions and 37 deletions

View File

@ -19,7 +19,7 @@ drvsrc = d_dodonpachi.o d_donpachi.o d_esprade.o d_feversos.o d_gaia.o d_guwang
\
d_galaxian.o \
\
d_m62.o d_m63.o d_m72.o d_m90.o d_m92.o d_m107.o d_vigilant.o \
d_m52.o d_m62.o d_m63.o d_m72.o d_m90.o d_m92.o d_m107.o d_vigilant.o \
\
d_88games.o d_ajax.o d_aliens.o d_asterix.o d_battlex.o d_battlnts.o d_bishi.o d_bladestl.o d_blockhl.o d_bottom9.o d_chqflag.o d_circusc.o d_combatsc.o d_contra.o \
d_crimfght.o d_dbz.o d_ddribble.o d_fastlane.o d_finalzr.o d_flkatck.o d_gberet.o d_gijoe.o d_gbusters.o d_gradius3.o d_gyruss.o d_hcastle.o d_hexion.o d_hyperspt.o \
@ -118,7 +118,7 @@ depobj = burn.o burn_gun.o burn_led.o burn_shift.o burn_memory.o burn_pal.o bur
\
gal_gfx.o gal_run.o gal_sound.o gal_stars.o \
\
irem_cpu.o \
irem_cpu.o irem_sound.o \
\
k007121.o k007342_k007420.o k051316.o k051733.o k051960.o k052109.o k053245.o k053247.o k053250.o k053251.o k053936.o k054000.o \
k054338.o k055555.o k056832.o konamigx.o konamiic.o timeplt_snd.o \

867
src/burn/drv/irem/d_m52.cpp Normal file
View File

@ -0,0 +1,867 @@
// FB Alpha M52 (Moon Patrol) driver module
// Based on MAME driver by Nicola Salmoria
#include "tiles_generic.h"
#include "z80_intf.h"
#include "irem_sound.h"
#include "bitswap.h"
static UINT8 *AllMem;
static UINT8 *AllRam;
static UINT8 *RamEnd;
static UINT8 *MemEnd;
static UINT8 *DrvZ80ROM;
static UINT8 *DrvM6803ROM;
static UINT8 *DrvGfxROM0;
static UINT8 *DrvGfxROM1;
static UINT8 *DrvGfxROM2;
static UINT8 *DrvGfxROM3;
static UINT8 *DrvGfxROM4;
static UINT8 *DrvColPROM;
static UINT8 *DrvZ80RAM;
static UINT8 *DrvVidRAM;
static UINT8 *DrvColRAM;
static UINT8 *DrvSprRAM;
static UINT32 *DrvPalette;
static UINT8 DrvRecalc;
static UINT8 scrollx = 0;
static UINT8 bgcontrol = 0;
static UINT8 bg1xpos = 0;
static UINT8 bg1ypos = 0;
static UINT8 bg2xpos = 0;
static UINT8 bg2ypos = 0;
static UINT8 flipscreen = 0;
static UINT8 DrvJoy1[8];
static UINT8 DrvJoy2[8];
static UINT8 DrvJoy3[8];
static UINT8 DrvDips[2];
static UINT8 DrvInputs[3];
static UINT8 DrvReset;
static struct BurnInputInfo MpatrolInputList[] = {
{"P1 Coin", BIT_DIGITAL, DrvJoy1 + 3, "p1 coin" },
{"P1 Start", BIT_DIGITAL, DrvJoy1 + 0, "p1 start" },
{"P1 Left", BIT_DIGITAL, DrvJoy2 + 1, "p1 left" },
{"P1 Right", BIT_DIGITAL, DrvJoy2 + 0, "p1 right" },
{"P1 Button 1", BIT_DIGITAL, DrvJoy2 + 7, "p1 fire 1" },
{"P1 Button 2", BIT_DIGITAL, DrvJoy2 + 5, "p1 fire 2" },
{"P2 Coin", BIT_DIGITAL, DrvJoy3 + 4, "p2 coin" },
{"P2 Start", BIT_DIGITAL, DrvJoy1 + 1, "p2 start" },
{"P2 Left", BIT_DIGITAL, DrvJoy3 + 1, "p2 left" },
{"P2 Right", BIT_DIGITAL, DrvJoy3 + 0, "p2 right" },
{"P2 Button 1", BIT_DIGITAL, DrvJoy3 + 7, "p2 fire 1" },
{"P2 Button 2", BIT_DIGITAL, DrvJoy3 + 5, "p2 fire 2" },
{"Reset", BIT_DIGITAL, &DrvReset, "reset" },
{"Service", BIT_DIGITAL, DrvJoy1 + 2, "service" },
{"Dip A", BIT_DIPSWITCH, DrvDips + 0, "dip" },
{"Dip B", BIT_DIPSWITCH, DrvDips + 1, "dip" },
};
STDINPUTINFO(Mpatrol)
static struct BurnDIPInfo MpatrolDIPList[]=
{
{0x0e, 0xff, 0xff, 0xfe, NULL },
{0x0f, 0xff, 0xff, 0xfd, NULL },
{0 , 0xfe, 0 , 4, "Lives" },
{0x0e, 0x01, 0x03, 0x00, "1" },
{0x0e, 0x01, 0x03, 0x01, "2" },
{0x0e, 0x01, 0x03, 0x02, "3" },
{0x0e, 0x01, 0x03, 0x03, "5" },
{0 , 0xfe, 0 , 4, "Bonus Life" },
{0x0e, 0x01, 0x0c, 0x0c, "10000 30000 50000" },
{0x0e, 0x01, 0x0c, 0x08, "20000 40000 60000" },
{0x0e, 0x01, 0x0c, 0x04, "10000" },
{0x0e, 0x01, 0x0c, 0x00, "None" },
{0 , 0xfe, 0 , 15, "Coinage" },
{0x0e, 0x01, 0xf0, 0x90, "7 Coins 1 Credits" },
{0x0e, 0x01, 0xf0, 0xa0, "6 Coins 1 Credits" },
{0x0e, 0x01, 0xf0, 0xb0, "5 Coins 1 Credits" },
{0x0e, 0x01, 0xf0, 0xc0, "4 Coins 1 Credits" },
{0x0e, 0x01, 0xf0, 0xd0, "3 Coins 1 Credits" },
{0x0e, 0x01, 0xf0, 0xe0, "2 Coins 1 Credits" },
{0x0e, 0x01, 0xf0, 0xf0, "1 Coin 1 Credits" },
{0x0e, 0x01, 0xf0, 0x70, "1 Coin 2 Credits" },
{0x0e, 0x01, 0xf0, 0x60, "1 Coin 3 Credits" },
{0x0e, 0x01, 0xf0, 0x50, "1 Coin 4 Credits" },
{0x0e, 0x01, 0xf0, 0x40, "1 Coin 5 Credits" },
{0x0e, 0x01, 0xf0, 0x30, "1 Coin 6 Credits" },
{0x0e, 0x01, 0xf0, 0x20, "1 Coin 7 Credits" },
{0x0e, 0x01, 0xf0, 0x10, "1 Coin 8 Credits" },
{0x0e, 0x01, 0xf0, 0x00, "Free Play" },
{0 , 0xfe, 0 , 2, "Flip Screen" },
{0x0f, 0x01, 0x01, 0x01, "Off" },
{0x0f, 0x01, 0x01, 0x00, "On" },
{0 , 0xfe, 0 , 2, "Cabinet" },
{0x0f, 0x01, 0x02, 0x00, "Upright" },
{0x0f, 0x01, 0x02, 0x02, "Cocktail" },
{0 , 0xfe, 0 , 2, "Coin Mode" },
{0x0f, 0x01, 0x04, 0x04, "Mode 1" },
{0x0f, 0x01, 0x04, 0x00, "Mode 2" },
{0 , 0xfe, 0 , 2, "Stop Mode (Cheat)" },
{0x0f, 0x01, 0x10, 0x10, "Off" },
{0x0f, 0x01, 0x10, 0x00, "On" },
{0 , 0xfe, 0 , 2, "Sector Selection (Cheat)" },
{0x0f, 0x01, 0x20, 0x20, "Off" },
{0x0f, 0x01, 0x20, 0x00, "On" },
{0 , 0xfe, 0 , 2, "Invulnerability (Cheat)" },
{0x0f, 0x01, 0x40, 0x40, "Off" },
{0x0f, 0x01, 0x40, 0x00, "On" },
{0 , 0xfe, 0 , 2, "Service Mode" },
{0x0f, 0x01, 0x80, 0x80, "Off" },
{0x0f, 0x01, 0x80, 0x00, "On" },
};
STDDIPINFO(Mpatrol)
static struct BurnDIPInfo MpatrolwDIPList[]=
{
{0x0e, 0xff, 0xff, 0xfe, NULL },
{0x0f, 0xff, 0xff, 0xfd, NULL },
{0 , 0xfe, 0 , 4, "Lives" },
{0x0e, 0x01, 0x03, 0x00, "2" },
{0x0e, 0x01, 0x03, 0x01, "3" },
{0x0e, 0x01, 0x03, 0x02, "4" },
{0x0e, 0x01, 0x03, 0x03, "5" },
{0 , 0xfe, 0 , 4, "Bonus Life" },
{0x0e, 0x01, 0x0c, 0x0c, "10000 30000 50000" },
{0x0e, 0x01, 0x0c, 0x08, "20000 40000 60000" },
{0x0e, 0x01, 0x0c, 0x04, "10000" },
{0x0e, 0x01, 0x0c, 0x00, "None" },
{0 , 0xfe, 0 , 15, "Coinage" },
{0x0e, 0x01, 0xf0, 0x90, "7 Coins 1 Credits" },
{0x0e, 0x01, 0xf0, 0xa0, "6 Coins 1 Credits" },
{0x0e, 0x01, 0xf0, 0xb0, "5 Coins 1 Credits" },
{0x0e, 0x01, 0xf0, 0xc0, "4 Coins 1 Credits" },
{0x0e, 0x01, 0xf0, 0xd0, "3 Coins 1 Credits" },
{0x0e, 0x01, 0xf0, 0xe0, "2 Coins 1 Credits" },
{0x0e, 0x01, 0xf0, 0xf0, "1 Coin 1 Credits" },
{0x0e, 0x01, 0xf0, 0x70, "1 Coin 2 Credits" },
{0x0e, 0x01, 0xf0, 0x60, "1 Coin 3 Credits" },
{0x0e, 0x01, 0xf0, 0x50, "1 Coin 4 Credits" },
{0x0e, 0x01, 0xf0, 0x40, "1 Coin 5 Credits" },
{0x0e, 0x01, 0xf0, 0x30, "1 Coin 6 Credits" },
{0x0e, 0x01, 0xf0, 0x20, "1 Coin 7 Credits" },
{0x0e, 0x01, 0xf0, 0x10, "1 Coin 8 Credits" },
{0x0e, 0x01, 0xf0, 0x00, "Free Play" },
{0 , 0xfe, 0 , 2, "Flip Screen" },
{0x0f, 0x01, 0x01, 0x01, "Off" },
{0x0f, 0x01, 0x01, 0x00, "On" },
{0 , 0xfe, 0 , 2, "Cabinet" },
{0x0f, 0x01, 0x02, 0x00, "Upright" },
{0x0f, 0x01, 0x02, 0x02, "Cocktail" },
{0 , 0xfe, 0 , 2, "Coin Mode" },
{0x0f, 0x01, 0x04, 0x04, "Mode 1" },
{0x0f, 0x01, 0x04, 0x00, "Mode 2" },
{0 , 0xfe, 0 , 2, "Stop Mode (Cheat)" },
{0x0f, 0x01, 0x10, 0x10, "Off" },
{0x0f, 0x01, 0x10, 0x00, "On" },
{0 , 0xfe, 0 , 2, "Sector Selection (Cheat)" },
{0x0f, 0x01, 0x20, 0x20, "Off" },
{0x0f, 0x01, 0x20, 0x00, "On" },
{0 , 0xfe, 0 , 2, "Invulnerability (Cheat)" },
{0x0f, 0x01, 0x40, 0x40, "Off" },
{0x0f, 0x01, 0x40, 0x00, "On" },
{0 , 0xfe, 0 , 2, "Service Mode" },
{0x0f, 0x01, 0x80, 0x80, "Off" },
{0x0f, 0x01, 0x80, 0x00, "On" },
};
STDDIPINFO(Mpatrolw)
static void __fastcall m52_main_write(UINT16 address, UINT8 data)
{
switch (address & ~0x7fc)
{
case 0xd000:
IremSoundWrite(data);
return;
case 0xd001:
flipscreen = (data & 1) ^ (~DrvDips[1] & 0x01);
return;
}
}
static UINT8 __fastcall m52_main_read(UINT16 address)
{
if ((address & 0xf800) == 0x8800) {
INT32 count = 0;
for (INT32 i = bg1xpos & 0x7f; i != 0; i >>= 1) {
count += i & 1;
}
return count ^ (bg1xpos >> 7);
}
switch (address & ~0x07f8)
{
case 0xd000:
case 0xd001:
case 0xd002:
return DrvInputs[address & 3];
case 0xd003:
case 0xd004:
return DrvDips[address - 0xd003];
}
return 0;
}
static void __fastcall m52_main_write_port(UINT16 port, UINT8 data)
{
switch (port & 0xe0)
{
case 0x00:
scrollx = data;
return;
case 0x40:
bg1xpos = data;
return;
case 0x60:
bg1ypos = data;
return;
case 0x80:
bg2xpos = data;
return;
case 0xa0:
bg2ypos = data;
return;
case 0xc0:
bgcontrol = data;
return;
}
}
static tilemap_callback( bg )
{
INT32 color = DrvColRAM[offs];
INT32 code = DrvVidRAM[offs] | ((color & 0x80) << 1);
TILE_SET_INFO(0, code, color, ((offs/0x20) < 7) ? TILE_OPAQUE : 0);
}
static INT32 DrvDoReset()
{
memset (AllRam, 0, RamEnd - AllRam);
ZetOpen(0);
ZetReset();
ZetClose();
IremSoundReset();
bgcontrol = 0;
bg1xpos = 0;
bg1ypos = 0;
bg2xpos = 0;
bg2ypos = 0;
flipscreen = 0;
scrollx = 0;
return 0;
}
static INT32 MemIndex()
{
UINT8 *Next; Next = AllMem;
DrvZ80ROM = Next; Next += 0x0070000;
DrvM6803ROM = Next; Next += 0x0100000;
DrvGfxROM0 = Next; Next += 0x0080000;
DrvGfxROM1 = Next; Next += 0x0080000;
DrvGfxROM2 = Next; Next += 0x0040000;
DrvGfxROM3 = Next; Next += 0x0040000;
DrvGfxROM4 = Next; Next += 0x0040000;
DrvColPROM = Next; Next += 0x0003400;
DrvPalette = (UINT32*)Next; Next += 0x034c0 * sizeof(UINT32);
AllRam = Next;
DrvZ80RAM = Next; Next += 0x0010000;
DrvVidRAM = Next; Next += 0x0004000;
DrvColRAM = Next; Next += 0x0004000;
DrvSprRAM = Next; Next += 0x0004000;
RamEnd = Next;
MemEnd = Next;
return 0;
}
static INT32 DrvGfxDecode()
{
INT32 Plane0[2] = { 0, 0x1000*8 };
INT32 XOffs0[16] = { STEP8(0,1), STEP8(16*8,1) };
INT32 YOffs0[16] = { STEP16(0,8) };
INT32 Plane1[2] = { 4, 0 };
INT32 XOffs1[256];
INT32 YOffs1[64] = { STEP32(0x0000,0x200), STEP32(0x4000,0x200) };
for (INT32 i = 0; i < 0x100; i++) XOffs1[i] = ((i & 0xfc) << 1) | (i & 3);
UINT8 *tmp = (UINT8*)BurnMalloc(0x2000);
if (tmp == NULL) {
return 1;
}
memcpy (tmp, DrvGfxROM0, 0x2000);
GfxDecode(0x0200, 2, 8, 8, Plane0, XOffs0, YOffs0, 0x0040, tmp, DrvGfxROM0);
memcpy (tmp, DrvGfxROM1, 0x2000);
GfxDecode(0x0080, 2, 16, 16, Plane0, XOffs0, YOffs0, 0x0100, tmp, DrvGfxROM1);
memcpy (tmp, DrvGfxROM2, 0x1000);
GfxDecode(0x0001, 2, 256, 64, Plane1, XOffs1, YOffs1, 0x8000, tmp, DrvGfxROM2);
memcpy (tmp, DrvGfxROM3, 0x1000);
GfxDecode(0x0001, 2, 256, 64, Plane1, XOffs1, YOffs1, 0x8000, tmp, DrvGfxROM3);
memcpy (tmp, DrvGfxROM4, 0x1000);
GfxDecode(0x0001, 2, 256, 64, Plane1, XOffs1, YOffs1, 0x8000, tmp, DrvGfxROM4);
BurnFree(tmp);
return 0;
}
static INT32 DrvInit()
{
AllMem = NULL;
MemIndex();
INT32 nLen = MemEnd - (UINT8 *)0;
if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
memset(AllMem, 0, nLen);
MemIndex();
{
if (BurnLoadRom(DrvZ80ROM + 0x0000, 0, 1)) return 1;
if (BurnLoadRom(DrvZ80ROM + 0x1000, 1, 1)) return 1;
if (BurnLoadRom(DrvZ80ROM + 0x2000, 2, 1)) return 1;
if (BurnLoadRom(DrvZ80ROM + 0x3000, 3, 1)) return 1;
if (BurnLoadRom(DrvM6803ROM+ 0x7000, 4, 1)) return 1;
if (BurnLoadRom(DrvGfxROM0 + 0x0000, 5, 1)) return 1;
if (BurnLoadRom(DrvGfxROM0 + 0x1000, 6, 1)) return 1;
if (BurnLoadRom(DrvGfxROM1 + 0x0000, 7, 1)) return 1;
if (BurnLoadRom(DrvGfxROM1 + 0x1000, 8, 1)) return 1;
if (BurnLoadRom(DrvGfxROM2 + 0x0000, 9, 1)) return 1;
if (BurnLoadRom(DrvGfxROM3 + 0x0000, 10, 1)) return 1;
if (BurnLoadRom(DrvGfxROM4 + 0x0000, 11, 1)) return 1;
if (BurnLoadRom(DrvColPROM + 0x0000, 12, 1)) return 1;
if (BurnLoadRom(DrvColPROM + 0x0200, 13, 1)) return 1;
if (BurnLoadRom(DrvColPROM + 0x0220, 14, 1)) return 1;
if (BurnLoadRom(DrvColPROM + 0x0240, 15, 1)) return 1;
DrvGfxDecode();
}
ZetInit(0);
ZetOpen(0);
ZetMapMemory(DrvZ80ROM, 0x0000, 0x6fff, MAP_ROM);
ZetMapMemory(DrvVidRAM, 0x8000, 0x83ff, MAP_RAM);
ZetMapMemory(DrvColRAM, 0x8400, 0x87ff, MAP_RAM);
ZetMapMemory(DrvSprRAM, 0xc800, 0xcbff, MAP_WRITE);
ZetMapMemory(DrvSprRAM, 0xcc00, 0xcfff, MAP_WRITE);
ZetMapMemory(DrvZ80RAM, 0xe000, 0xefff, MAP_RAM);
ZetSetWriteHandler(m52_main_write);
ZetSetReadHandler(m52_main_read);
ZetSetOutHandler(m52_main_write_port);
ZetClose();
IremSoundInit(DrvM6803ROM, 0, 3072000);
GenericTilesInit();
GenericTilemapInit(0, TILEMAP_SCAN_ROWS, bg_map_callback, 8, 8, 32, 32);
GenericTilemapSetGfx(0, DrvGfxROM0, 2, 8, 8, 0x08000, 0, 0x3f);
GenericTilemapSetTransparent(0, 0);
GenericTilemapSetScrollRows(0, 4);
GenericTilemapSetOffsets(0, -8, -8);
DrvDoReset();
return 0;
}
static INT32 DrvExit()
{
GenericTilesExit();
ZetExit();
IremSoundExit();
BurnFree(AllMem);
return 0;
}
static void DrvPaletteInit()
{
#define combine_3_weights(w, b0, b1, b2) ((((b0 * w[2]) + (b1 * w[1]) + (b2 * w[0])) * 255) / (w[0]+w[1]+w[2]))
#define combine_2_weights(w, b0, b1) ((((b0 * w[1]) + (b1 * w[0])) * 255) / (w[0]+w[1]))
UINT32 tmp[64];
static const INT32 resistances_3[3] = { 1000, 470, 220 };
static const INT32 resistances_2[2] = { 470, 220 };
for (INT32 i = 0; i < 512; i++)
{
UINT8 promval = DrvColPROM[0x000 + i];
INT32 r = combine_3_weights(resistances_3, BIT(promval,0), BIT(promval,1), BIT(promval,2));
INT32 g = combine_3_weights(resistances_3, BIT(promval,3), BIT(promval,4), BIT(promval,5));
INT32 b = combine_2_weights(resistances_2, BIT(promval,6), BIT(promval,7));
DrvPalette[i] = BurnHighCol(r,g,b,0);
}
for (INT32 i = 0; i < 32; i++)
{
UINT8 promval = DrvColPROM[0x200 + i];
INT32 r = combine_3_weights(resistances_3, BIT(promval,0), BIT(promval,1), BIT(promval,2));
INT32 g = combine_3_weights(resistances_3, BIT(promval,3), BIT(promval,4), BIT(promval,5));
INT32 b = combine_2_weights(resistances_2, BIT(promval,6), BIT(promval,7));
tmp[i] = BurnHighCol(r,g,b,0);
promval = DrvColPROM[0x220 + i];
r = combine_2_weights(resistances_2, BIT(promval,6), BIT(promval,7));
g = combine_3_weights(resistances_3, BIT(promval,3), BIT(promval,4), BIT(promval,5));
b = combine_3_weights(resistances_3, BIT(promval,0), BIT(promval,1), BIT(promval,2));
tmp[32 + i] = BurnHighCol(r,g,b,0);
}
for (INT32 i = 0; i < 64; i++)
{
UINT8 promval = DrvColPROM[0x240 + ((i & 3) | ((i & ~3) << 1))];
DrvPalette[0x200+i] = tmp[32 + promval];
}
DrvPalette[512+16*4+0*4+0] = tmp[0];
DrvPalette[512+16*4+0*4+1] = tmp[4];
DrvPalette[512+16*4+0*4+2] = tmp[8];
DrvPalette[512+16*4+0*4+3] = tmp[12];
DrvPalette[512+16*4+1*4+0] = tmp[0];
DrvPalette[512+16*4+1*4+1] = tmp[1];
DrvPalette[512+16*4+1*4+2] = tmp[2];
DrvPalette[512+16*4+1*4+3] = tmp[3];
DrvPalette[512+16*4+2*4+0] = tmp[0];
DrvPalette[512+16*4+2*4+1] = tmp[16+1];
DrvPalette[512+16*4+2*4+2] = tmp[16+2];
DrvPalette[512+16*4+2*4+3] = tmp[16+3];
}
static void draw_background(int xpos, int ypos, UINT8 *gfx, int color_offset)
{
if (flipscreen)
{
xpos = 127 - xpos;
ypos = 255 - ypos - 64;
}
ypos = ypos + (22 - 16);
DrawCustomMaskTile(pTransDraw, 256, 64, 0, xpos - 8, ypos, flipscreen, flipscreen, 0, 2, 0, color_offset, gfx);
DrawCustomMaskTile(pTransDraw, 256, 64, 0, xpos - (256 + 8), ypos, flipscreen, flipscreen, 0, 2, 0, color_offset, gfx);
INT32 min_y, max_y;
if (flipscreen)
{
min_y = ypos - 64;
max_y = ypos - 1;
}
else
{
min_y = ypos + 64;
max_y = ypos + 2 * 64 - 1;
}
// fill in all the stuff below the image with a solid color
for (INT32 y = min_y; y < nScreenHeight && y < max_y; y++)
{
UINT16 *dst = pTransDraw + y * nScreenWidth;
for (INT32 x = 0; x < nScreenWidth; x++)
{
dst[x] = color_offset + 3;
}
}
}
static void draw_sprites()
{
for (INT32 offs = 0xfc; offs >= 0; offs -= 4)
{
INT32 sy = 257 - DrvSprRAM[offs];
INT32 color = DrvSprRAM[offs + 1] & 0x3f;
INT32 flipx = DrvSprRAM[offs + 1] & 0x40;
INT32 flipy = DrvSprRAM[offs + 1] & 0x80;
INT32 code = DrvSprRAM[offs + 2];
INT32 sx = DrvSprRAM[offs + 3];
if (flipscreen)
{
if ((offs & 0x80) != 0)
GenericTilesSetClip(-1, -1, 0, 127-8);
else
GenericTilesSetClip(-1, -1, 128-8, 240);
flipx = !flipx;
flipy = !flipy;
sx = 112 - sx;
sy = 257 + 11 - sy;
}
else
{
if (!(offs & 0x80))
GenericTilesSetClip(-1, -1, 0, 127-8);
else
GenericTilesSetClip(-1, -1, 128-8, 240);
}
// m_palette->transpen_mask(*m_gfxdecode->gfx(1), color, 512 + 32)); !! transtab
Draw16x16MaskTile(pTransDraw, code, sx - 8, sy - 24, flipx, flipy, color, 2, 0, 0x200, DrvGfxROM1);
}
GenericTilesClearClip();
}
static INT32 DrvDraw()
{
if (DrvRecalc) {
DrvPaletteInit();
DrvRecalc = 0;
}
BurnTransferClear();
if (!(bgcontrol & 0x20))
{
if (!(bgcontrol & 0x10) && (nBurnLayer & 1))
draw_background(bg2xpos, bg2ypos, DrvGfxROM2, 512+64+0);
if (!(bgcontrol & 0x02) && (nBurnLayer & 2))
draw_background(bg1xpos, bg1ypos, DrvGfxROM3, 512+64+4);
if (!(bgcontrol & 0x04) && (nBurnLayer & 4))
draw_background(bg1xpos, bg1ypos, DrvGfxROM4, 512+64+8);
}
GenericTilemapSetScrollRow(0, 3, -scrollx);
if (nBurnLayer & 8) GenericTilemapDraw(0, pTransDraw, 0);
if (nSpriteEnable & 1) draw_sprites();
BurnTransferCopy(DrvPalette);
return 0;
}
static INT32 DrvFrame()
{
if (DrvReset) {
DrvDoReset();
}
M6803NewFrame();
ZetNewFrame();
{
DrvInputs[0] = 0xff;
DrvInputs[1] = 0xff;
DrvInputs[2] = 0xff;
for (INT32 i = 0; i < 8; i++) {
DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
DrvInputs[2] ^= (DrvJoy3[i] & 1) << i;
}
}
INT32 nInterleave = MSM5205CalcInterleave(0, 3072000);
INT32 nCyclesTotal[2] = { 3072000 / 60, 894886 / 60 };
INT32 nCyclesDone[2] = { 0, 0 };
ZetOpen(0);
M6803Open(0);
for (INT32 i = 0; i < nInterleave; i++)
{
nCyclesDone[0] += ZetRun(nCyclesTotal[0] / nInterleave);
if (i == (nInterleave - 1)) ZetSetIRQLine(0, CPU_IRQSTATUS_HOLD);
nCyclesDone[1] += M6803Run(nCyclesTotal[1] / nInterleave);
MSM5205Update();
}
if (pBurnSoundOut) {
AY8910Render(pBurnSoundOut, nBurnSoundLen);
MSM5205Render(0, pBurnSoundOut, nBurnSoundLen);
}
M6803Close();
ZetClose();
if (pBurnDraw) {
BurnDrvRedraw();
}
return 0;
}
static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
{
struct BurnArea ba;
if (pnMin) {
*pnMin = 0x029702;
}
if (nAction & ACB_VOLATILE) {
memset(&ba, 0, sizeof(ba));
ba.Data = AllRam;
ba.nLen = RamEnd - AllRam;
ba.szName = "All Ram";
BurnAcb(&ba);
ZetScan(nAction);
IremScan(nAction, pnMin);
SCAN_VAR(bgcontrol);
SCAN_VAR(bg1xpos);
SCAN_VAR(bg1ypos);
SCAN_VAR(bg2xpos);
SCAN_VAR(bg2ypos);
SCAN_VAR(flipscreen);
SCAN_VAR(scrollx);
}
return 0;
}
// Moon Patrol
static struct BurnRomInfo mpatrolRomDesc[] = {
{ "mpa-1.3m", 0x1000, 0x5873a860, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code
{ "mpa-2.3l", 0x1000, 0xf4b85974, 1 | BRF_PRG | BRF_ESS }, // 1
{ "mpa-3.3k", 0x1000, 0x2e1a598c, 1 | BRF_PRG | BRF_ESS }, // 2
{ "mpa-4.3j", 0x1000, 0xdd05b587, 1 | BRF_PRG | BRF_ESS }, // 3
{ "mp-s1.1a", 0x1000, 0x561d3108, 2 | BRF_GRA }, // 4 M6803 Code
{ "mpe-5.3e", 0x1000, 0xe3ee7f75, 3 | BRF_GRA }, // 5 Characters
{ "mpe-4.3f", 0x1000, 0xcca6d023, 3 | BRF_GRA }, // 6
{ "mpb-2.3m", 0x1000, 0x707ace5e, 4 | BRF_GRA }, // 7 Sprites
{ "mpb-1.3n", 0x1000, 0x9b72133a, 4 | BRF_GRA }, // 8
{ "mpe-1.3l", 0x1000, 0xc46a7f72, 5 | BRF_GRA }, // 9 Mountain Layer
{ "mpe-2.3k", 0x1000, 0xc7aa1fb0, 6 | BRF_GRA }, // 10 Hill Layer
{ "mpe-3.3h", 0x1000, 0xa0919392, 7 | BRF_GRA }, // 11 Cityscape Layer
{ "mpc-4.2a", 0x0200, 0x07f99284, 8 | BRF_GRA }, // 12 Color Data
{ "mpc-3.1m", 0x0020, 0x6a57eff2, 8 | BRF_GRA }, // 13
{ "mpc-1.1f", 0x0020, 0x26979b13, 8 | BRF_GRA }, // 14
{ "mpc-2.2h", 0x0100, 0x7ae4cd97, 8 | BRF_GRA }, // 15
};
STD_ROM_PICK(mpatrol)
STD_ROM_FN(mpatrol)
struct BurnDriver BurnDrvMpatrol = {
"mpatrol", NULL, NULL, NULL, "1982",
"Moon Patrol\0", NULL, "Irem", "Miscellaneous",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING, 2, HARDWARE_IREM_M62, GBF_HORSHOOT, 0,
NULL, mpatrolRomInfo, mpatrolRomName, NULL, NULL, MpatrolInputInfo, MpatrolDIPInfo,
DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x42c,
240, 240, 4, 3
};
// Moon Patrol (Williams)
static struct BurnRomInfo mpatrolwRomDesc[] = {
{ "mpa-1w.3m", 0x1000, 0xbaa1a1d4, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code
{ "mpa-2w.3l", 0x1000, 0x52459e51, 1 | BRF_PRG | BRF_ESS }, // 1
{ "mpa-3w.3k", 0x1000, 0x9b249fe5, 1 | BRF_PRG | BRF_ESS }, // 2
{ "mpa-4w.3j", 0x1000, 0xfee76972, 1 | BRF_PRG | BRF_ESS }, // 3
{ "mp-s1.1a", 0x1000, 0x561d3108, 2 | BRF_GRA }, // 4 M6803 Code
{ "mpe-5w.3e", 0x1000, 0xf56e01fe, 3 | BRF_GRA }, // 5 Characters
{ "mpe-4w.3f", 0x1000, 0xcaaba2d9, 3 | BRF_GRA }, // 6
{ "mpb-2.3m", 0x1000, 0x707ace5e, 4 | BRF_GRA }, // 7 Sprites
{ "mpb-1.3n", 0x1000, 0x9b72133a, 4 | BRF_GRA }, // 8
{ "mpe-1.3l", 0x1000, 0xc46a7f72, 5 | BRF_GRA }, // 9 Mountain Layer
{ "mpe-2.3k", 0x1000, 0xc7aa1fb0, 6 | BRF_GRA }, // 10 Hill Layer
{ "mpe-3.3h", 0x1000, 0xa0919392, 7 | BRF_GRA }, // 11 Cityscape Layer
{ "mpc-4a.2a", 0x0200, 0xcb0a5ff3, 8 | BRF_GRA }, // 12 Color Data
{ "mpc-3.1m", 0x0020, 0x6a57eff2, 8 | BRF_GRA }, // 13
{ "mpc-1.1f", 0x0020, 0x26979b13, 8 | BRF_GRA }, // 14
{ "mpc-2.2h", 0x0100, 0x7ae4cd97, 8 | BRF_GRA }, // 15
};
STD_ROM_PICK(mpatrolw)
STD_ROM_FN(mpatrolw)
struct BurnDriver BurnDrvMpatrolw = {
"mpatrolw", "mpatrol", NULL, NULL, "1982",
"Moon Patrol (Williams)\0", NULL, "Irem (Williams license)", "Miscellaneous",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_IREM_M62, GBF_HORSHOOT, 0,
NULL, mpatrolwRomInfo, mpatrolwRomName, NULL, NULL, MpatrolInputInfo, MpatrolwDIPInfo,
DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x42c,
240, 240, 4, 3
};
// Moon Ranger (bootleg of Moon Patrol)
static struct BurnRomInfo mrangerRomDesc[] = {
{ "mpa-1.3m", 0x1000, 0x5873a860, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code
{ "mra-2.3l", 0x1000, 0x217dd431, 1 | BRF_PRG | BRF_ESS }, // 1
{ "mra-3.3k", 0x1000, 0x9f0af7b2, 1 | BRF_PRG | BRF_ESS }, // 2
{ "mra-4.3j", 0x1000, 0x7fe8e2cd, 1 | BRF_PRG | BRF_ESS }, // 3
{ "mp-s1.1a", 0x1000, 0x561d3108, 2 | BRF_GRA }, // 4 M6803 Code
{ "mpe-5.3e", 0x1000, 0xe3ee7f75, 3 | BRF_GRA }, // 5 Characters
{ "mpe-4.3f", 0x1000, 0xcca6d023, 3 | BRF_GRA }, // 6
{ "mpb-2.3m", 0x1000, 0x707ace5e, 4 | BRF_GRA }, // 7 Sprites
{ "mpb-1.3n", 0x1000, 0x9b72133a, 4 | BRF_GRA }, // 8
{ "mpe-1.3l", 0x1000, 0xc46a7f72, 5 | BRF_GRA }, // 9 Mountain Layer
{ "mpe-2.3k", 0x1000, 0xc7aa1fb0, 6 | BRF_GRA }, // 10 Hill Layer
{ "mpe-3.3h", 0x1000, 0xa0919392, 7 | BRF_GRA }, // 11 Cityscape Layer
{ "mpc-4.2a", 0x0200, 0x07f99284, 8 | BRF_GRA }, // 12 Color Data
{ "mpc-3.1m", 0x0020, 0x6a57eff2, 8 | BRF_GRA }, // 13
{ "mpc-1.1f", 0x0020, 0x26979b13, 8 | BRF_GRA }, // 14
{ "mpc-2.2h", 0x0100, 0x7ae4cd97, 8 | BRF_GRA }, // 15
};
STD_ROM_PICK(mranger)
STD_ROM_FN(mranger)
struct BurnDriver BurnDrvMranger = {
"mranger", "mpatrol", NULL, NULL, "1982",
"Moon Ranger (bootleg of Moon Patrol)\0", NULL, "bootleg", "Miscellaneous",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 2, HARDWARE_IREM_M62, GBF_HORSHOOT, 0,
NULL, mrangerRomInfo, mrangerRomName, NULL, NULL, MpatrolInputInfo, MpatrolDIPInfo,
DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x42c,
240, 240, 4, 3
};
/*
// Alpha One (Vision Electronics)
static struct BurnRomInfo alpha1vRomDesc[] = {
{ "2-m3", 0x1000, 0x3a679d34, 1 | BRF_PRG | BRF_ESS }, // 0 Z80 Code
{ "3-l3", 0x1000, 0x2f09df64, 1 | BRF_PRG | BRF_ESS }, // 1
{ "4-k3", 0x1000, 0x64fb9c8a, 1 | BRF_PRG | BRF_ESS }, // 2
{ "5-j3", 0x1000, 0xd1643d18, 1 | BRF_PRG | BRF_ESS }, // 3
{ "6-h3", 0x1000, 0xcf34ab51, 1 | BRF_PRG | BRF_ESS }, // 4
{ "7-f3", 0x1000, 0x99db9781, 1 | BRF_PRG | BRF_ESS }, // 5
{ "7a e3", 0x1000, 0x3b0b4b0d, 1 | BRF_PRG | BRF_ESS }, // 6
{ "1-a1", 0x1000, 0x9e07fdd5, 2 | BRF_GRA }, // 7 M6803 Code
{ "14-e3", 0x1000, 0xcf00c737, 3 | BRF_GRA }, // 8 Characters
{ "13-f3", 0x1000, 0x4b799229, 3 | BRF_GRA }, // 9
{ "15-n3", 0x1000, 0xdc26df76, 4 | BRF_GRA }, // 10 Sprites
{ "16-l3", 0x1000, 0x39b9863b, 4 | BRF_GRA }, // 11
{ "17-k3", 0x1000, 0xcfd90773, 4 | BRF_GRA }, // 12
{ "11-k3", 0x1000, 0x7659440a, 5 | BRF_GRA }, // 13 gfx3
{ "12-jh3", 0x1000, 0x7659440a, 5 | BRF_GRA }, // 14
{ "9-n3", 0x1000, 0x0fdb7d13, 6 | BRF_GRA }, // 15 gfx4
{ "10-lm3", 0x1000, 0x9dde3a75, 7 | BRF_GRA }, // 16 gfx5
{ "63s481-a2", 0x0200, 0x58678ea8, 8 | BRF_GRA }, // 17 Color Data
{ "18s030-m1", 0x0020, 0x6a57eff2, 8 | BRF_GRA }, // 18
{ "mb7051-f1", 0x0020, 0xd8bdd0df, 8 | BRF_GRA }, // 19
{ "mb7052-h2", 0x0100, 0xce9f0ef9, 8 | BRF_GRA }, // 20
};
STD_ROM_PICK(alpha1v)
STD_ROM_FN(alpha1v)
struct BurnDriver BurnDrvAlpha1v = {
"alpha1v", NULL, NULL, NULL, "1988",
"Alpha One (Vision Electronics)\0", NULL, "Vision Electronics", "Miscellaneous",
NULL, NULL, NULL, NULL,
0, 2, HARDWARE_IREM_M62, GBF_MISC, 0,
NULL, alpha1vRomInfo, alpha1vRomName, NULL, NULL, Alpha1vInputInfo, Alpha1vDIPInfo,
DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x42c,
240, 240, 4, 3
};
*/

View File

@ -3,9 +3,16 @@
#include "tiles_generic.h"
#include "z80_intf.h"
#define USE_SOUND_DEVICE
#ifdef USE_SOUND_DEVICE
#include "irem_sound.h"
#else
#include "m6800_intf.h"
#include "msm5205.h"
#include "ay8910.h"
#endif
#define USE_SAMPLE_HACK // allow use of sampled drumkit on Kid Niki, Spelunker 1 & 2, Battle-Road, Horizon
#ifdef USE_SAMPLE_HACK
@ -42,7 +49,10 @@ static UINT8 *M62SpriteRam = NULL;
static UINT8 *M62CharRam = NULL;
static UINT8 *M62ScrollRam = NULL;
static UINT8 *M62Z80Ram = NULL;
#ifndef USE_SOUND_DEVICE
static UINT8 *M62M6803Ram = NULL;
#endif
static UINT8 *M62Tiles = NULL;
static UINT8 *M62Sprites = NULL;
static UINT8 *M62Chars = NULL;
@ -56,10 +66,12 @@ static INT32 M62CharHScroll;
static INT32 M62CharVScroll;
static INT32 M62FlipScreen;
static INT32 M62SpriteHeightPromOffset;
#ifndef USE_SOUND_DEVICE
static UINT8 M62SoundLatch;
static UINT8 M62Port1;
static UINT8 M62Port2;
static UINT8 M62SlaveMSM5205VClckReset;
#endif
static UINT32 M62PaletteEntries;
static INT32 M62Z80Clock;
static INT32 M62M6803Clock;
@ -1787,7 +1799,7 @@ static INT32 M62MemIndex()
if (!M62SpriteRamSize) M62SpriteRamSize = 0x100;
M62Z80Rom = Next; Next += M62Z80RomSize;
M62M6803Rom = Next; Next += 0x0c000;
M62M6803Rom = Next; Next += 0x10000;
RamStart = Next;
@ -1796,7 +1808,10 @@ static INT32 M62MemIndex()
if (M62CharRamSize) { M62CharRam = Next; Next += M62CharRamSize; }
if (M62ScrollRamSize) { M62ScrollRam = Next; Next += M62ScrollRamSize; }
M62Z80Ram = Next; Next += 0x01000;
#ifndef USE_SOUND_DEVICE
M62M6803Ram = Next; Next += 0x00080;
#endif
RamEnd = Next;
@ -1817,6 +1832,9 @@ static INT32 M62DoReset()
ZetReset();
ZetClose();
#ifdef USE_SOUND_DEVICE
IremSoundReset();
#else
M6803Open(0);
M6803Reset();
M6803Close();
@ -1825,6 +1843,8 @@ static INT32 M62DoReset()
AY8910Reset(1);
MSM5205Reset();
#endif
#ifdef USE_SAMPLE_HACK
BurnSampleReset();
#endif
@ -1836,10 +1856,13 @@ static INT32 M62DoReset()
M62CharHScroll = 0;
M62CharVScroll = 0;
M62FlipScreen = 0;
#ifndef USE_SOUND_DEVICE
M62SoundLatch = 0;
M62Port1 = 0;
M62Port2 = 0;
M62SlaveMSM5205VClckReset = 0;
#endif
M62BankControl[0] = M62BankControl[1] = 0;
Ldrun2BankSwap = 0;
Ldrun3TopBottomMask = 0;
@ -2064,11 +2087,15 @@ void __fastcall M62Z80PortWrite(UINT16 a, UINT8 d)
switch (a) {
case 0x00: {
#ifdef USE_SOUND_DEVICE
IremSoundWrite(d);
#else
if ((d & 0x80) == 0) {
M62SoundLatch = d & 0x7f;
} else {
M6803SetIRQLine(M6803_IRQ_LINE, CPU_IRQSTATUS_ACK);
}
#endif
return;
}
@ -2345,6 +2372,7 @@ void __fastcall YoujyudnZ80PortWrite(UINT16 a, UINT8 d)
}
}
#ifndef USE_SOUND_DEVICE
UINT8 M62M6803ReadByte(UINT16 a)
{
if (a <= 0x001f) {
@ -2445,6 +2473,7 @@ void M62M6803WritePort(UINT16 a, UINT8 d)
bprintf(PRINT_NORMAL, _T("M6803 Write Port -> %04X, %02X\n"), a, d);
}
#endif
static INT32 Tile1024PlaneOffsets[3] = { 0x20000, 0x10000, 0 };
static INT32 Tile2048PlaneOffsets[3] = { 0x40000, 0x20000, 0 };
@ -2471,6 +2500,26 @@ static INT32 YoujyudnTilePlaneOffsets[3] = { 0x40000, 0x20000, 0 };
static INT32 YoujyudnTileXOffsets[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
static INT32 YoujyudnTileYOffsets[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120 };
#ifdef USE_SOUND_DEVICE
static void AY8910_1PortAWrite(UINT8 data)
{
if (data == 0xff) {
//bprintf(0, _T("M62 Analog drumkit init.\n"));
return;
}
if (data > 0) {
if (data & 0x01) // bass drum
BurnSamplePlay(2);
if (data & 0x02) // snare drum
BurnSamplePlay(1);
if (data & 0x04) // open hat
BurnSamplePlay(3);
if (data & 0x08) // closed hat
BurnSamplePlay(0);
}
}
#else
UINT8 M62SoundLatchRead(UINT32)
{
return M62SoundLatch;
@ -2514,6 +2563,7 @@ static void M62MSM5205Vck0()
M6803SetIRQLine(M6803_INPUT_LINE_NMI, CPU_IRQSTATUS_AUTO);
M62SlaveMSM5205VClckReset = 1;
}
#endif
static INT32 M62MemInit()
{
@ -2542,9 +2592,9 @@ static INT32 KungfumLoadRoms()
nRet = BurnLoadRom(M62Z80Rom + 0x04000, 1, 1); if (nRet != 0) return 1;
// Load M6803 Program Roms
nRet = BurnLoadRom(M62M6803Rom + 0x06000, 2, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 3, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0a000, 4, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0a000, 2, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0c000, 3, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0e000, 4, 1); if (nRet != 0) return 1;
// Load and decode the tiles
memset(M62TempRom, 0, 0x18000);
@ -2595,8 +2645,8 @@ static INT32 KungfumdLoadRoms()
nRet = BurnLoadRom(M62Z80Rom + 0x04000, 1, 1); if (nRet != 0) return 1;
// Load M6803 Program Roms
nRet = BurnLoadRom(M62M6803Rom + 0x04000, 2, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 3, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 2, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0c000, 3, 1); if (nRet != 0) return 1;
// Load and decode the tiles
memset(M62TempRom, 0, 0x18000);
@ -2641,9 +2691,9 @@ static INT32 Kungfub3LoadRoms()
nRet = BurnLoadRom(M62Z80Rom + 0x04000, 1, 1); if (nRet != 0) return 1;
// Load M6803 Program Roms
nRet = BurnLoadRom(M62M6803Rom + 0x06000, 2, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 3, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0a000, 4, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0a000, 2, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0a000, 3, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0e000, 4, 1); if (nRet != 0) return 1;
// Load and decode the tiles
memset(M62TempRom, 0, 0x18000);
@ -2696,9 +2746,9 @@ static INT32 BattroadLoadRoms()
nRet = BurnLoadRom(M62Z80Rom + 0x14000, 9, 1); if (nRet != 0) return 1;
// Load M6803 Program Roms
nRet = BurnLoadRom(M62M6803Rom + 0x06000, 10, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 11, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0a000, 12, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0a000, 10, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0c000, 11, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0e000, 12, 1); if (nRet != 0) return 1;
// Load and decode the tiles
memset(M62TempRom, 0, 0x0c000);
@ -2752,8 +2802,8 @@ static INT32 LdrunLoadRoms()
nRet = BurnLoadRom(M62Z80Rom + 0x06000, 3, 1); if (nRet != 0) return 1;
// Load M6803 Program Roms
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 4, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0a000, 5, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0c000, 4, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0e000, 5, 1); if (nRet != 0) return 1;
// Load and decode the tiles
memset(M62TempRom, 0, 0x06000);
@ -2799,9 +2849,9 @@ static INT32 Ldrun2LoadRoms()
nRet = BurnLoadRom(M62Z80Rom + 0x0a000, 5, 1); if (nRet != 0) return 1;
// Load M6803 Program Roms
nRet = BurnLoadRom(M62M6803Rom + 0x06000, 6, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 7, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0a000, 8, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0a000, 6, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0c000, 7, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0e000, 8, 1); if (nRet != 0) return 1;
// Load and decode the tiles
memset(M62TempRom, 0, 0x0c000);
@ -2847,8 +2897,8 @@ static INT32 Ldrun3LoadRoms()
nRet = BurnLoadRom(M62Z80Rom + 0x08000, 2, 1); if (nRet != 0) return 1;
// Load M6803 Program Roms
nRet = BurnLoadRom(M62M6803Rom + 0x04000, 3, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 4, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 3, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0c000, 4, 1); if (nRet != 0) return 1;
// Load and decode the tiles
memset(M62TempRom, 0, 0x18000);
@ -2894,8 +2944,8 @@ static INT32 Ldrun3jLoadRoms()
nRet = BurnLoadRom(M62Z80Rom + 0x08000, 2, 1); if (nRet != 0) return 1;
// Load M6803 Program Roms
nRet = BurnLoadRom(M62M6803Rom + 0x04000, 3, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 4, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 3, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0c000, 4, 1); if (nRet != 0) return 1;
// Load and decode the tiles
memset(M62TempRom, 0, 0x0c000);
@ -2937,7 +2987,7 @@ static INT32 LotlotLoadRoms()
nRet = BurnLoadRom(M62Z80Rom + 0x04000, 1, 1); if (nRet != 0) return 1;
// Load M6803 Program Roms
nRet = BurnLoadRom(M62M6803Rom + 0x0a000, 2, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0e000, 2, 1); if (nRet != 0) return 1;
// Load and decode the tiles
memset(M62TempRom, 0, 0x06000);
@ -2992,9 +3042,9 @@ static INT32 KidnikiLoadRoms()
memcpy(M62Z80Rom + 0x20000, M62Z80Rom + 0x18000, 0x8000);
// Load M6803 Program Roms
nRet = BurnLoadRom(M62M6803Rom + 0x00000, 4, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x04000, 5, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 6, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x04000, 4, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 5, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0c000, 6, 1); if (nRet != 0) return 1;
// Load and decode the tiles
memset(M62TempRom, 0, 0x30000);
@ -3053,9 +3103,9 @@ static INT32 LitheroLoadRoms()
nRet = BurnLoadRom(M62Z80Rom + 0x10000, 2, 1); if (nRet != 0) return 1;
// Load M6803 Program Roms
nRet = BurnLoadRom(M62M6803Rom + 0x00000, 3, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x04000, 4, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 5, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x04000, 3, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 4, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0c000, 5, 1); if (nRet != 0) return 1;
// Load and decode the tiles
memset(M62TempRom, 0, 0x30000);
@ -3109,8 +3159,8 @@ static INT32 SpelunkrLoadRoms()
nRet = BurnLoadRom(M62Z80Rom + 0x0c000, 3, 1); if (nRet != 0) return 1;
// Load M6803 Program Roms
nRet = BurnLoadRom(M62M6803Rom + 0x04000, 4, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 5, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 4, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0c000, 5, 1); if (nRet != 0) return 1;
// Load and decode the tiles
memset(M62TempRom, 0, 0x18000);
@ -3194,8 +3244,8 @@ static INT32 Spelunk2LoadRoms()
nRet = BurnLoadRom(M62Z80Rom + 0x18000, 4, 1); if (nRet != 0) return 1;
// Load M6803 Program Roms
nRet = BurnLoadRom(M62M6803Rom + 0x04000, 5, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 6, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 5, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0c000, 6, 1); if (nRet != 0) return 1;
// Load and decode the tiles
memset(M62TempRom, 0, 0x18000);
@ -3275,7 +3325,7 @@ static INT32 YoujyudnLoadRoms()
nRet = BurnLoadRom(M62Z80Rom + 0x0c000, 3, 1); if (nRet != 0) return 1;
// Load M6803 Program Roms
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 4, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0c000, 4, 1); if (nRet != 0) return 1;
// Load and decode the tiles
memset(M62TempRom, 0, 0x18000);
@ -3333,7 +3383,7 @@ static INT32 HorizonLoadRoms()
nRet = BurnLoadRom(M62Z80Rom + 0x08000, 2, 1); if (nRet != 0) return 1;
// Load M6803 Program Roms
nRet = BurnLoadRom(M62M6803Rom + 0x08000, 3, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(M62M6803Rom + 0x0c000, 3, 1); if (nRet != 0) return 1;
// Load and decode the tiles
memset(M62TempRom, 0, 0x18000);
@ -3390,6 +3440,13 @@ static void M62MachineInit()
ZetMapArea(0xe000, 0xefff, 2, M62Z80Ram );
ZetClose();
#ifdef USE_SOUND_DEVICE
IremSoundInit(M62M6803Rom, 1, 4000000, AY8910_1PortAWrite);
MSM5205SetRoute(0, 0.20, BURN_SND_ROUTE_BOTH);
MSM5205SetRoute(1, 0.20, BURN_SND_ROUTE_BOTH);
AY8910SetAllRoutes(0, 0.15, BURN_SND_ROUTE_BOTH);
AY8910SetAllRoutes(1, 0.15, BURN_SND_ROUTE_BOTH);
#else
M6803Init(0);
M6803Open(0);
M6803MapMemory(M62M6803Rom, 0x4000, 0xffff, MAP_ROM);
@ -3410,6 +3467,8 @@ static void M62MachineInit()
AY8910SetPorts(1, NULL, NULL, &AY8910_1PortAWrite, NULL);
AY8910SetAllRoutes(0, 0.15, BURN_SND_ROUTE_BOTH);
AY8910SetAllRoutes(1, 0.15, BURN_SND_ROUTE_BOTH);
#endif
#ifdef USE_SAMPLE_HACK
BurnUpdateProgress(0.0, _T("Loading samples..."), 0);
bBurnSampleTrimSampleEnd = 1;
@ -3965,10 +4024,15 @@ static INT32 HorizonInit()
static INT32 M62Exit()
{
ZetExit();
#ifdef USE_SOUND_DEVICE
IremSoundExit();
#else
M6800Exit();
AY8910Exit(0);
AY8910Exit(1);
MSM5205Exit();
#endif
#ifdef USE_SAMPLE_HACK
BurnSampleExit();
#endif
@ -3991,10 +4055,12 @@ static INT32 M62Exit()
M62CharHScroll = 0;
M62CharVScroll = 0;
M62FlipScreen = 0;
#ifndef USE_SOUND_DEVICE
M62SoundLatch = 0;
M62Port1 = 0;
M62Port2 = 0;
M62SlaveMSM5205VClckReset = 0;
#endif
M62PaletteEntries = 0;
M62Z80Clock = 0;
M62M6803Clock = 0;
@ -4792,11 +4858,19 @@ static INT32 M62Frame()
}
MSM5205Update();
#ifdef USE_SOUND_DEVICE
if (IremSlaveMSM5205VClckReset) {
MSM5205VCLKWrite(1, 1);
MSM5205VCLKWrite(1, 0);
IremSlaveMSM5205VClckReset = 0;
}
#else
if (M62SlaveMSM5205VClckReset) {
MSM5205VCLKWrite(1, 1);
MSM5205VCLKWrite(1, 0);
M62SlaveMSM5205VClckReset = 0;
}
#endif
}
if (pBurnSoundOut) {
@ -4841,10 +4915,16 @@ static INT32 M62Scan(INT32 nAction, INT32 *pnMin)
}
if (nAction & ACB_DRIVER_DATA) {
M6803Scan(nAction);
ZetScan(nAction);
#ifdef USE_SOUND_DEVICE
IremScan(nAction, pnMin);
#else
M6803Scan(nAction);
AY8910Scan(nAction, pnMin);
MSM5205Scan(nAction, pnMin);
#endif
#ifdef USE_SAMPLE_HACK
BurnSampleScan(nAction, pnMin);
#endif
@ -4853,10 +4933,12 @@ static INT32 M62Scan(INT32 nAction, INT32 *pnMin)
SCAN_VAR(M62CharHScroll);
SCAN_VAR(M62CharVScroll);
SCAN_VAR(M62FlipScreen);
#ifndef USE_SOUND_DEVICE
SCAN_VAR(M62SoundLatch);
SCAN_VAR(M62Port1);
SCAN_VAR(M62Port2);
SCAN_VAR(M62SlaveMSM5205VClckReset);
#endif
SCAN_VAR(M62BankControl);
SCAN_VAR(Ldrun2BankSwap);
SCAN_VAR(Ldrun3TopBottomMask);

View File

@ -0,0 +1,319 @@
// FB Alpha Irem Sound system device
// Based on MAME sources by Couriersud and FBA port by Barry Harris (Treble Winner)
#include "burnint.h"
#include "z80_intf.h"
#include "m6800_intf.h"
#include "msm5205.h"
#include "ay8910.h"
static UINT8 *IremM6803Rom;
static UINT8 IremM6803Ram[0x80];
static UINT8 IremSoundLatch;
static UINT8 IremPort1;
static UINT8 IremPort2;
UINT8 IremSlaveMSM5205VClckReset;
static INT32 IremM6803Clock;
static INT32 IremZ80Clock;
static INT32 bHasMSM5205_1 = 0;
static INT32 nSoundType = 0;
static void (*pAY8910P1ACb)(UINT8 data) = NULL;
void IremSoundWrite(UINT8 d)
{
IremSoundLatch = d;
if ((d & 0x80) == 0) {
M6803SetIRQLine(M6803_IRQ_LINE, CPU_IRQSTATUS_ACK);
}
}
INT32 IremSoundReset()
{
memset (IremM6803Ram, 0, 0x80);
M6803Open(0);
M6803Reset();
M6803SetIRQLine(M6803_IRQ_LINE, CPU_IRQSTATUS_ACK);
M6803Close();
AY8910Reset(0);
AY8910Reset(1);
MSM5205Reset();
IremSoundLatch = 0;
IremPort1 = 0;
IremPort2 = 0;
IremSlaveMSM5205VClckReset = 0;
return 0;
}
static UINT8 IremM6803ReadByte(UINT16 a)
{
if (a <= 0x001f) {
return m6803_internal_registers_r(a);
}
if (a >= 0x0080 && a <= 0x00ff) {
return IremM6803Ram[a - 0x0080];
}
bprintf(PRINT_NORMAL, _T("M6803 Read Byte -> %04X\n"), a);
return 0;
}
static void IremM6803WriteByte(UINT16 a, UINT8 d)
{
int subhit = 0;
if (a <= 0x001f) {
m6803_internal_registers_w(a, d);
return;
}
if (a >= 0x0080 && a <= 0x00ff) {
IremM6803Ram[a - 0x0080] = d;
return;
}
if (nSoundType == 0)
{
a &= 0x7fff;
if (a < 0x1000) {
if (a & 1) MSM5205DataWrite(0, d);
if ((a & 2) && bHasMSM5205_1) MSM5205DataWrite(0, d);
return;
}
if (a < 0x2000) {
M6803SetIRQLine(M6803_IRQ_LINE, CPU_IRQSTATUS_NONE);
return;
}
}
else if (nSoundType == 1)
{
a &= 0x0803;
subhit = 1;
if (a == 0x0800) {
M6803SetIRQLine(M6803_IRQ_LINE, CPU_IRQSTATUS_NONE);
return;
}
if (a == 0x0801) {
MSM5205DataWrite(0, d);
return;
}
if (a == 0x0802) {
if (bHasMSM5205_1) MSM5205DataWrite(1, d);
return;
}
if (a == 0x0803) {
return; // nop?
}
if (a < 0x800) {
IremM6803WriteByte(a, d);
return;
}
}
else if (nSoundType == 2)
{
if (a < 0x2000) {
if (a & 1) MSM5205DataWrite(0, d);
if ((a & 2) && bHasMSM5205_1) MSM5205DataWrite(0, d);
return;
}
if (a < 0x4000) {
M6803SetIRQLine(M6803_IRQ_LINE, CPU_IRQSTATUS_NONE);
return;
}
}
bprintf(PRINT_NORMAL, _T("M6803 Write Byte -> %04X, %02X Type-> %d, %d\n"), a, d, nSoundType, subhit);
}
static UINT8 IremM6803ReadPort(UINT16 a)
{
switch (a) {
case M6803_PORT1: {
if (IremPort2 & 0x08) return AY8910Read(0);
if (IremPort2 & 0x10) return AY8910Read(1);
return 0xff;
}
case M6803_PORT2: {
return 0;
}
}
bprintf(PRINT_NORMAL, _T("M6803 Read Port -> %04X\n"), a);
return 0;
}
static void IremM6803WritePort(UINT16 a, UINT8 d)
{
switch (a) {
case M6803_PORT1: {
IremPort1 = d;
return;
}
case M6803_PORT2: {
if ((IremPort2 & 0x01) && !(d & 0x01)) {
if (IremPort2 & 0x04) {
if (IremPort2 & 0x08) {
AY8910Write(0, 0, IremPort1);
}
if (IremPort2 & 0x10) {
AY8910Write(1, 0, IremPort1);
}
} else {
if (IremPort2 & 0x08) {
AY8910Write(0, 1, IremPort1);
}
if (IremPort2 & 0x10) {
AY8910Write(1, 1, IremPort1);
}
}
}
IremPort2 = d;
return;
}
}
bprintf(PRINT_NORMAL, _T("M6803 Write Port -> %04X, %02X\n"), a, d);
}
static UINT8 IremSoundLatchRead(UINT32)
{
return IremSoundLatch;
}
static void AY8910_0PortBWrite(UINT32, UINT32 d)
{
MSM5205PlaymodeWrite(0, (d >> 2) & 0x07);
MSM5205ResetWrite(0, d & 0x01);
if (bHasMSM5205_1) {
MSM5205PlaymodeWrite(1, ((d >> 2) & 0x04) | 0x03);
MSM5205ResetWrite(1, d & 0x02);
}
}
static void AY8910_1PortAWrite(UINT32, UINT32 data)
{
if (pAY8910P1ACb) {
pAY8910P1ACb(data);
}
}
inline static INT32 IremSynchroniseStream(INT32 nSoundRate)
{
return (INT64)((double)ZetTotalCycles() * nSoundRate / IremZ80Clock);
}
static void IremMSM5205Vck0()
{
M6803SetIRQLine(M6803_INPUT_LINE_NMI, CPU_IRQSTATUS_AUTO);
IremSlaveMSM5205VClckReset = 1;
}
void IremSoundInit(UINT8 *pZ80ROM, INT32 nType, INT32 nZ80Clock)
{
IremM6803Rom = pZ80ROM;
M6803Init(0);
M6803Open(0);
if (nType == 0) {
M6803MapMemory(IremM6803Rom + 0x2000, 0x2000, 0x7fff, MAP_ROM);
M6803MapMemory(IremM6803Rom + 0x2000, 0xa000, 0xffff, MAP_ROM);
} else {
M6803MapMemory(IremM6803Rom + 0x4000, 0x4000, 0xffff, MAP_ROM);
}
M6803SetReadHandler(IremM6803ReadByte);
M6803SetWriteHandler(IremM6803WriteByte);
M6803SetReadPortHandler(IremM6803ReadPort);
M6803SetWritePortHandler(IremM6803WritePort);
M6803Close();
AY8910Init(0, 894886, 0);
AY8910Init(1, 894886, 1);
AY8910SetPorts(0, &IremSoundLatchRead, NULL, NULL, &AY8910_0PortBWrite);
AY8910SetPorts(1, NULL, NULL, &AY8910_1PortAWrite, NULL);
AY8910SetAllRoutes(0, 0.15, BURN_SND_ROUTE_BOTH);
AY8910SetAllRoutes(1, 0.15, BURN_SND_ROUTE_BOTH);
MSM5205Init(0, IremSynchroniseStream, 384000, IremMSM5205Vck0, MSM5205_S96_4B, 1);
MSM5205Init(1, IremSynchroniseStream, 384000, NULL, MSM5205_SEX_4B, 1);
MSM5205SetRoute(0, 0.20, BURN_SND_ROUTE_BOTH);
MSM5205SetRoute(1, 0.20, BURN_SND_ROUTE_BOTH);
IremZ80Clock = nZ80Clock;
IremM6803Clock = 894886;
bHasMSM5205_1 = (nType != 0) ? 1 : 0;
nSoundType = nType;
}
void IremSoundInit(UINT8 *pZ80ROM, INT32 nType, INT32 nZ80Clock, void (*ay8910cb)(UINT8))
{
pAY8910P1ACb = ay8910cb;
IremSoundInit(pZ80ROM, nType, nZ80Clock);
}
INT32 IremSoundExit()
{
M6800Exit();
AY8910Exit(0);
AY8910Exit(1);
MSM5205Exit();
IremSoundLatch = 0;
IremPort1 = 0;
IremPort2 = 0;
IremSlaveMSM5205VClckReset = 0;
IremM6803Clock = 0;
bHasMSM5205_1 = 0;
nSoundType = 0;
pAY8910P1ACb = NULL;
return 0;
}
INT32 IremScan(INT32 nAction, INT32 *pnMin)
{
struct BurnArea ba;
if (nAction & ACB_MEMORY_RAM) {
memset(&ba, 0, sizeof(ba));
ba.Data = IremM6803Ram;
ba.nLen = 0x80;
ba.szName = "Irem Sound RAM";
BurnAcb(&ba);
}
if (nAction & ACB_DRIVER_DATA) {
M6803Scan(nAction);
AY8910Scan(nAction, pnMin);
MSM5205Scan(nAction, pnMin);
SCAN_VAR(IremSoundLatch);
SCAN_VAR(IremPort1);
SCAN_VAR(IremPort2);
SCAN_VAR(IremSlaveMSM5205VClckReset);
}
return 0;
}

View File

@ -0,0 +1,12 @@
#include "m6800_intf.h"
#include "msm5205.h"
#include "ay8910.h"
void IremSoundWrite(UINT8 d);
extern UINT8 IremSlaveMSM5205VClckReset;
INT32 IremSoundReset();
void IremSoundInit(UINT8 *pZ80ROM, INT32 nType, INT32 nZ80Clock);
void IremSoundInit(UINT8 *pZ80ROM, INT32 nType, INT32 nZ80Clock, void (*ay8910cb)(UINT8));
INT32 IremSoundExit();
INT32 IremScan(INT32 nAction, INT32 *pnMin);