mirror of
https://github.com/libretro/FBNeo.git
synced 2024-11-24 01:19:46 +00:00
add driver for Qbert
This commit is contained in:
parent
fd0612393a
commit
88e0abdb84
@ -51,7 +51,7 @@ drvobj = d_dodonpachi.o d_donpachi.o d_esprade.o d_feversos.o d_gaia.o d_guwang
|
||||
d_higemaru.o d_ikki.o d_invaders.o d_jack.o d_kangaroo.o d_kncljoe.o d_kyugo.o d_ladybug.o d_lastduel.o d_lwings.o d_marineb.o \
|
||||
d_mario.o d_markham.o d_megasys1.o d_meijinsn.o d_millipede.o d_mirax.o d_mitchell.o d_mole.o d_momoko.o d_mouser.o d_mrdo.o d_mrflea.o \
|
||||
d_mustache.o d_mystston.o d_namcos86.o d_ninjakd2.o d_pacland.o d_pacman.o d_pac2650.o d_pkunwar.o d_popeye.o d_prehisle.o \
|
||||
d_psychic5.o d_punchout.o d_quizo.o d_rallyx.o d_renegade.o d_route16.o d_rpunch.o d_scregg.o d_sf.o d_sidearms.o d_skyarmy.o \
|
||||
d_psychic5.o d_punchout.o d_qbert.o d_quizo.o d_rallyx.o d_renegade.o d_route16.o d_rpunch.o d_scregg.o d_sf.o d_sidearms.o d_skyarmy.o \
|
||||
d_skyfox.o d_skykid.o d_snk68.o d_solomon.o d_sonson.o d_srumbler.o d_suna8.o d_tail2nose.o d_tbowl.o d_tecmo.o d_terracre.o \
|
||||
d_tigeroad.o d_timelimt.o d_toki.o d_tsamurai.o d_vastar.o d_vulgus.o d_wallc.o d_warpwarp.o d_wc90.o d_wc90b.o d_wiz.o d_wwfsstar.o \
|
||||
d_xain.o d_xxmissio.o \
|
||||
|
906
src/burn/drv/pre90s/d_qbert.cpp
Normal file
906
src/burn/drv/pre90s/d_qbert.cpp
Normal file
@ -0,0 +1,906 @@
|
||||
// Q-Bert emu-layer for FB Alpha by dink, based on the MAME driver by Fabrice Frances & Nicola Salmoria.
|
||||
// Notes:
|
||||
// Sometimes it plays the wrong sample at startup, hence QBERT_SOUND_DEBUG
|
||||
|
||||
#include "tiles_generic.h"
|
||||
#include "driver.h"
|
||||
#include "nec_intf.h"
|
||||
#include "m6502_intf.h"
|
||||
#include "bitswap.h"
|
||||
#include "dac.h"
|
||||
#include "samples.h"
|
||||
|
||||
//#define QBERT_SOUND_DEBUG
|
||||
|
||||
static UINT8 *AllMem;
|
||||
static UINT8 *MemEnd;
|
||||
static UINT8 *AllRam;
|
||||
static UINT8 *RamEnd;
|
||||
static UINT8 *DrvV20ROM;
|
||||
static UINT8 *Drv6502ROM;
|
||||
static UINT8 *DrvV20RAM;
|
||||
static UINT8 *Drv6502RAM;
|
||||
static UINT8 *DrvVideoRAM;
|
||||
static UINT8 *DrvCharRAM;
|
||||
static UINT8 *DrvSpriteRAM;
|
||||
static UINT8 *DrvPaletteRAM;
|
||||
static UINT8 *DrvCharGFX;
|
||||
static UINT8 *DrvSpriteGFX;
|
||||
static UINT8 *DrvNVRAM;
|
||||
static UINT8 *DrvDummyROM;
|
||||
|
||||
static UINT8 *riot_regs;
|
||||
static UINT8 *riot_ram;
|
||||
|
||||
static UINT8 *background_prio;
|
||||
static UINT8 *spritebank;
|
||||
static UINT8 *soundlatch;
|
||||
static UINT8 *soundcpu_do_nmi;
|
||||
|
||||
static char vtqueue[0x20];
|
||||
static UINT8 vtqueuepos;
|
||||
static UINT32 vtqueuetime;
|
||||
|
||||
static UINT32 *DrvPalette;
|
||||
static UINT8 DrvRecalc;
|
||||
|
||||
static UINT8 DrvJoy1[8];
|
||||
static UINT8 DrvJoy2[8];
|
||||
static UINT8 DrvDip[2] = { 0, 0 };
|
||||
static UINT8 DrvInput[5];
|
||||
static UINT8 DrvReset;
|
||||
|
||||
static struct BurnInputInfo QbertInputList[] = {
|
||||
{"P1 Coin", BIT_DIGITAL, DrvJoy1 + 2, "p1 coin" },
|
||||
{"P1 Start", BIT_DIGITAL, DrvJoy1 + 0, "p1 start" },
|
||||
{"P1 Up", BIT_DIGITAL, DrvJoy2 + 2, "p1 up" },
|
||||
{"P1 Down", BIT_DIGITAL, DrvJoy2 + 3, "p1 down" },
|
||||
{"P1 Left", BIT_DIGITAL, DrvJoy2 + 1, "p1 left" },
|
||||
{"P1 Right", BIT_DIGITAL, DrvJoy2 + 0, "p1 right" },
|
||||
|
||||
{"P2 Coin", BIT_DIGITAL, DrvJoy1 + 3, "p2 coin" },
|
||||
{"P2 Start", BIT_DIGITAL, DrvJoy1 + 1, "p2 start" },
|
||||
{"P2 Up", BIT_DIGITAL, DrvJoy2 + 6, "p2 up" },
|
||||
{"P2 Down", BIT_DIGITAL, DrvJoy2 + 7, "p2 down" },
|
||||
{"P2 Left", BIT_DIGITAL, DrvJoy2 + 5, "p2 left" },
|
||||
{"P2 Right", BIT_DIGITAL, DrvJoy2 + 4, "p2 right" },
|
||||
|
||||
{"Reset", BIT_DIGITAL, &DrvReset, "reset" },
|
||||
{"Select", BIT_DIGITAL, DrvJoy1 + 7, "select" },
|
||||
{"Dip A", BIT_DIPSWITCH, DrvDip + 0, "dip" },
|
||||
{"Dip B", BIT_DIPSWITCH, DrvDip + 1, "dip" },
|
||||
};
|
||||
|
||||
STDINPUTINFO(Qbert)
|
||||
|
||||
|
||||
static struct BurnDIPInfo QbertDIPList[]=
|
||||
{
|
||||
{0x0e, 0xff, 0xff, 0x02, NULL },
|
||||
{0x0f, 0xff, 0xff, 0x40, NULL },
|
||||
|
||||
{0 , 0xfe, 0 , 2, "Demo Sounds" },
|
||||
{0x0e, 0x01, 0x01, 0x01, "Off" },
|
||||
{0x0e, 0x01, 0x01, 0x00, "On" },
|
||||
|
||||
{0 , 0xfe, 0 , 2, "Kicker" },
|
||||
{0x0e, 0x01, 0x02, 0x00, "Off" },
|
||||
{0x0e, 0x01, 0x02, 0x02, "On" },
|
||||
|
||||
{0 , 0xfe, 0 , 2, "Cabinet" },
|
||||
{0x0e, 0x01, 0x04, 0x00, "Upright" },
|
||||
{0x0e, 0x01, 0x04, 0x04, "Cocktail" },
|
||||
|
||||
{0 , 0xfe, 0 , 2, "Auto Round Advance (Cheat)" },
|
||||
{0x0e, 0x01, 0x08, 0x00, "Off" },
|
||||
{0x0e, 0x01, 0x08, 0x08, "On" },
|
||||
|
||||
{0 , 0xfe, 0 , 2, "Free Play" },
|
||||
{0x0e, 0x01, 0x10, 0x00, "Off" },
|
||||
{0x0e, 0x01, 0x10, 0x10, "On" },
|
||||
|
||||
{0 , 0xfe, 0 , 2, "SW5" },
|
||||
{0x0e, 0x01, 0x20, 0x00, "Off" },
|
||||
{0x0e, 0x01, 0x20, 0x20, "On" },
|
||||
|
||||
{0 , 0xfe, 0 , 2, "SW7" },
|
||||
{0x0e, 0x01, 0x40, 0x00, "Off" },
|
||||
{0x0e, 0x01, 0x40, 0x40, "On" },
|
||||
|
||||
{0 , 0xfe, 0 , 2, "SW8" },
|
||||
{0x0e, 0x01, 0x80, 0x00, "Off" },
|
||||
{0x0e, 0x01, 0x80, 0x80, "On" },
|
||||
|
||||
{0 , 0xfe, 0 , 2, "Service" },
|
||||
{0x0f, 0x01, 0x40, 0x40, "Off" },
|
||||
{0x0f, 0x01, 0x40, 0x00, "On" },
|
||||
};
|
||||
|
||||
STDDIPINFO(Qbert)
|
||||
|
||||
static void gottlieb_paletteram_w(UINT16 offset, UINT8 data)
|
||||
{
|
||||
INT32 bit0, bit1, bit2, bit3;
|
||||
INT32 r, g, b, val;
|
||||
|
||||
DrvPaletteRAM[offset] = data;
|
||||
|
||||
/* red component */
|
||||
|
||||
val = DrvPaletteRAM[offset | 1];
|
||||
|
||||
bit0 = (val >> 0) & 0x01;
|
||||
bit1 = (val >> 1) & 0x01;
|
||||
bit2 = (val >> 2) & 0x01;
|
||||
bit3 = (val >> 3) & 0x01;
|
||||
|
||||
r = 0x10 * bit0 + 0x21 * bit1 + 0x46 * bit2 + 0x88 * bit3;
|
||||
|
||||
/* green component */
|
||||
|
||||
val = DrvPaletteRAM[offset & ~1];
|
||||
|
||||
bit0 = (val >> 4) & 0x01;
|
||||
bit1 = (val >> 5) & 0x01;
|
||||
bit2 = (val >> 6) & 0x01;
|
||||
bit3 = (val >> 7) & 0x01;
|
||||
|
||||
g = 0x10 * bit0 + 0x21 * bit1 + 0x46 * bit2 + 0x88 * bit3;
|
||||
|
||||
/* blue component */
|
||||
|
||||
val = DrvPaletteRAM[offset & ~1];
|
||||
|
||||
bit0 = (val >> 0) & 0x01;
|
||||
bit1 = (val >> 1) & 0x01;
|
||||
bit2 = (val >> 2) & 0x01;
|
||||
bit3 = (val >> 3) & 0x01;
|
||||
|
||||
b = 0x10 * bit0 + 0x21 * bit1 + 0x46 * bit2 + 0x88 * bit3;
|
||||
|
||||
DrvPalette[offset / 2] = BurnHighCol(r, g, b, 0);
|
||||
}
|
||||
|
||||
static void qbert_palette()
|
||||
{
|
||||
for (INT32 i = 0; i < 0x20; i++) {
|
||||
gottlieb_paletteram_w(i, DrvPaletteRAM[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void gottlieb_sh_w(UINT16 offset, UINT8 data); //forward!
|
||||
|
||||
static void __fastcall main_write(UINT32 address, UINT8 data)
|
||||
{
|
||||
address &= 0xffff;
|
||||
|
||||
if ((address & 0xff00) == 0x3700) address &= ~0x700; // mirror handling
|
||||
if ((address & 0xfc00) == 0x3c00) address &= ~0x400;
|
||||
if ((address & 0xffe0) == 0x57e0) address &= ~0x7e0;
|
||||
if ((address & 0xffff) == 0x5ff8) address &= ~0x7f8;
|
||||
|
||||
if (address >= 0x0000 && address <= 0x0fff) {
|
||||
DrvNVRAM[address - 0x0000] = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if (address >= 0x3000 && address <= 0x30ff) {
|
||||
DrvSpriteRAM[address - 0x3000] = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if (address >= 0x3800 && address <= 0x3bff) {
|
||||
DrvVideoRAM[address - 0x3800] = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if (address >= 0x4000 && address <= 0x4fff) {
|
||||
DrvCharRAM[address - 0x4000] = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if (address >= 0x5000 && address <= 0x501f) {
|
||||
gottlieb_paletteram_w(address - 0x5000, data);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (address)
|
||||
{
|
||||
case 0x5802: gottlieb_sh_w(address, data); return;
|
||||
case 0x5803: *background_prio = data & 0x01; return;
|
||||
}
|
||||
}
|
||||
|
||||
static UINT8 __fastcall main_read(UINT32 address)
|
||||
{
|
||||
address &= 0xffff;
|
||||
|
||||
if (address >= 0xa000 && address <= 0xffff) {
|
||||
return DrvV20ROM[address - 0xa000];
|
||||
}
|
||||
|
||||
if (address >= 0x0000 && address <= 0x0fff) {
|
||||
return DrvNVRAM[address - 0x0000];
|
||||
}
|
||||
|
||||
if ((address & 0xff00) == 0x3700) address &= ~0x700;
|
||||
if ((address & 0xfc00) == 0x3c00) address &= ~0x400;
|
||||
if ((address & 0xffe0) == 0x57e0) address &= ~0x7e0;
|
||||
if ((address & 0xffff) == 0x5ff8) address &= ~0x7f8;
|
||||
|
||||
if (address >= 0x3000 && address <= 0x30ff) {
|
||||
return DrvSpriteRAM[address - 0x3000];
|
||||
}
|
||||
|
||||
if (address >= 0x3800 && address <= 0x3bff) {
|
||||
return DrvVideoRAM[address - 0x3800];
|
||||
}
|
||||
|
||||
if (address >= 0x4000 && address <= 0x4fff) {
|
||||
return DrvCharRAM[address - 0x4000];
|
||||
}
|
||||
|
||||
if (address >= 0x5000 && address <= 0x501f) {
|
||||
return DrvPaletteRAM[address - 0x5000];
|
||||
}
|
||||
|
||||
|
||||
switch (address)
|
||||
{
|
||||
case 0x5800: return DrvDip[0];
|
||||
case 0x5801: return DrvInput[0] | DrvDip[1]; // DrvDip[1] for service mode.
|
||||
case 0x5804: return DrvInput[1];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gottlieb_sh_w(UINT16 offset, UINT8 data)
|
||||
{
|
||||
static INT32 random_offset=0;
|
||||
data &= 0x3f;
|
||||
|
||||
if ((data & 0x0f) != 0xf) {
|
||||
#ifdef QBERT_SOUND_DEBUG
|
||||
bprintf(0, _T("data %X.."), data ^ 0x3f);
|
||||
#endif
|
||||
switch (data ^ 0x3f) { // qbert sample player
|
||||
case 17:
|
||||
case 18:
|
||||
case 19:
|
||||
case 20:
|
||||
case 21:
|
||||
BurnSamplePlay(((data^0x3f)-17)*8+random_offset);
|
||||
random_offset = (random_offset+1)&7;
|
||||
break;
|
||||
case 22:
|
||||
BurnSamplePlay(40);
|
||||
break;
|
||||
case 23:
|
||||
BurnSamplePlay(41);
|
||||
break;
|
||||
case 28:
|
||||
BurnSamplePlay(42); // Hello, I'm turned on.
|
||||
break;
|
||||
case 36:
|
||||
BurnSamplePlay(43); // Bye-Bye
|
||||
break;
|
||||
}
|
||||
|
||||
*soundlatch = data;
|
||||
|
||||
M6502SetIRQLine(0, CPU_IRQSTATUS_ACK);
|
||||
M6502Run(10); //CPU_IRQSTATUS_AUTO no workie
|
||||
M6502SetIRQLine(0, CPU_IRQSTATUS_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
static UINT8 gottlieb_riot_r(UINT16 offset)
|
||||
{
|
||||
switch (offset & 0x1f) {
|
||||
case 0: /* port A */
|
||||
return *soundlatch ^ 0xff; /* invert command */
|
||||
case 2: /* port B */
|
||||
return 0x40; /* say that PB6 is 1 (test SW1 not pressed) */
|
||||
case 5: /* interrupt register */
|
||||
return 0x40; /* say that edge detected on PA7 */
|
||||
default:
|
||||
return riot_regs[offset & 0x1f];
|
||||
}
|
||||
}
|
||||
|
||||
static void blank_queue()
|
||||
{
|
||||
vtqueuepos = 0;
|
||||
memset(&vtqueue, 0, sizeof(vtqueue));
|
||||
vtqueuetime = GetCurrentFrame();
|
||||
}
|
||||
|
||||
static void add_to_queue(UINT8 data)
|
||||
{
|
||||
if (vtqueuepos > sizeof(vtqueue)-1 || GetCurrentFrame() > vtqueuetime+2)
|
||||
blank_queue();
|
||||
vtqueue[vtqueuepos++] = data;
|
||||
}
|
||||
|
||||
static UINT8 check_queue()
|
||||
{
|
||||
if (vtqueuepos == 24 && !strnicmp("\xC1\xE4\xFF\xE7\xE8\xD2\xFC\xFC\xFC\xFC\xFC\xEA\xFF\xF6\xD6\xF3\xD5\xC5\xF5\xF2\xE1\xDB\xF2\xC0", vtqueue, 24)) {
|
||||
blank_queue(); // "Hello, I'm turned on."
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void audio_write(UINT16 address, UINT8 data)
|
||||
{
|
||||
address &= 0x7fff; // 15bit addressing
|
||||
|
||||
if (address >= 0x7000 && address <= 0x7fff) {
|
||||
Drv6502ROM[address - 0x7000] = data;
|
||||
}
|
||||
|
||||
if (address >= 0x0000 && address <= 0x01ff) {
|
||||
riot_ram[address & 0x7f] = data;
|
||||
}
|
||||
|
||||
if (address >= 0x0200 && address <= 0x03ff) {
|
||||
riot_regs[address & 0x1f] = data;
|
||||
}
|
||||
|
||||
switch (address)
|
||||
{
|
||||
case 0x1fff:
|
||||
case 0x1000: {
|
||||
DACWrite(0, data);
|
||||
return;
|
||||
}
|
||||
case 0x2000: {
|
||||
add_to_queue(data);
|
||||
#ifdef QBERT_SOUND_DEBUG
|
||||
bprintf(0, _T("\\x%X"), data); //save
|
||||
#endif
|
||||
switch (check_queue()) {
|
||||
case 1: BurnSamplePlay(42); break; // Say Hello
|
||||
}
|
||||
*soundcpu_do_nmi = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static UINT8 audio_read(UINT16 address)
|
||||
{
|
||||
address &= 0x7fff; // 15bit addressing
|
||||
|
||||
if (address >= 0x7000 && address <= 0x7fff) {
|
||||
return Drv6502ROM[address - 0x7000];
|
||||
}
|
||||
|
||||
if (address >= 0x0000 && address <= 0x01ff) {
|
||||
return riot_ram[address&0x7f];
|
||||
}
|
||||
|
||||
if (address >= 0x0200 && address <= 0x03ff) {
|
||||
return gottlieb_riot_r(address - 0x200);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INT32 DrvSyncDAC()
|
||||
{
|
||||
return (INT32)(float)(nBurnSoundLen * (M6502TotalCycles() / ((3579545.0000/4) / (nBurnFPS / 100.0000))));
|
||||
}
|
||||
|
||||
static INT32 DrvDoReset()
|
||||
{
|
||||
memset (AllRam, 0, RamEnd - AllRam);
|
||||
|
||||
VezOpen(0);
|
||||
VezReset();
|
||||
VezClose();
|
||||
|
||||
M6502Open(0);
|
||||
M6502Reset();
|
||||
M6502Close();
|
||||
|
||||
DACReset();
|
||||
BurnSampleReset();
|
||||
// HiscoreReset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static INT32 MemIndex()
|
||||
{
|
||||
UINT8 *Next; Next = AllMem;
|
||||
|
||||
DrvV20ROM = Next; Next += 0x10000;
|
||||
Drv6502ROM = Next; Next += 0x10000;
|
||||
|
||||
DrvPalette = (UINT32*)Next; Next += 0x10 * sizeof(UINT32);
|
||||
DrvCharGFX = Next; Next += 0x40000;
|
||||
DrvSpriteGFX = Next; Next += 0x40000;
|
||||
DrvNVRAM = Next; Next += 0x01000;
|
||||
|
||||
AllRam = Next;
|
||||
|
||||
DrvV20RAM = Next; Next += 0x01000;
|
||||
Drv6502RAM = Next; Next += 0x01000;
|
||||
|
||||
DrvVideoRAM = Next; Next += 0x00400;
|
||||
DrvCharRAM = Next; Next += 0x01000;
|
||||
DrvSpriteRAM = Next; Next += 0x00100;
|
||||
DrvPaletteRAM = Next; Next += 0x00040;
|
||||
DrvDummyROM = Next; Next += 0x02000;
|
||||
|
||||
riot_regs = Next; Next += 0x00020;
|
||||
riot_ram = Next; Next += 0x001ff;
|
||||
|
||||
background_prio = Next; Next += 0x00001;
|
||||
spritebank = Next; Next += 0x00001;
|
||||
soundlatch = Next; Next += 0x00001;
|
||||
soundcpu_do_nmi = Next; Next += 0x00001;
|
||||
|
||||
RamEnd = Next;
|
||||
MemEnd = Next;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INT32 DrvInit()
|
||||
{
|
||||
INT32 c8PlaneOffsets[4] = { 0, 1, 2, 3 };
|
||||
INT32 c8XOffsets[8] = { 0, 4, 8, 12, 16, 20, 24, 28 };
|
||||
INT32 c8YOffsets[8] = { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 };
|
||||
|
||||
INT32 c16PlaneOffsets[4] = { RGN_FRAC(0x8000, 0, 4), RGN_FRAC(0x8000, 1, 4), RGN_FRAC(0x8000, 2, 4), RGN_FRAC(0x8000, 3, 4) };
|
||||
INT32 c16XOffsets[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
INT32 c16YOffsets[16] = { 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16, 8*16, 9*16, 10*16, 11*16, 12*16, 13*16, 14*16, 15*16 };
|
||||
|
||||
AllMem = NULL;
|
||||
MemIndex();
|
||||
INT32 nLen = MemEnd - (UINT8 *)0;
|
||||
if ((AllMem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
|
||||
memset(AllMem, 0, nLen);
|
||||
MemIndex();
|
||||
|
||||
{ // Load ROMS parse GFX
|
||||
UINT8 *DrvTempRom = (UINT8 *)BurnMalloc(0x40000);
|
||||
memset(DrvTempRom, 0, 0x40000);
|
||||
|
||||
{
|
||||
if (BurnLoadRom(DrvV20ROM + 0x0000, 0, 1)) return 1;
|
||||
if (BurnLoadRom(DrvV20ROM + 0x2000, 1, 1)) return 1;
|
||||
if (BurnLoadRom(DrvV20ROM + 0x4000, 2, 1)) return 1;
|
||||
|
||||
if (BurnLoadRom(Drv6502ROM + 0x0000, 3, 1)) return 1;
|
||||
if (BurnLoadRom(Drv6502ROM + 0x0800, 4, 1)) return 1;
|
||||
|
||||
// load & decode 8x8 tiles
|
||||
memset(DrvTempRom, 0, 0x40000);
|
||||
if (BurnLoadRom(DrvTempRom , 5, 1)) return 1;
|
||||
if (BurnLoadRom(DrvTempRom + 0x1000, 6, 1)) return 1;
|
||||
GfxDecode(0x100, 4, 8, 8, c8PlaneOffsets, c8XOffsets, c8YOffsets, 0x100, DrvTempRom, DrvCharGFX);
|
||||
|
||||
// load & decode 16x16 tiles
|
||||
memset(DrvTempRom, 0, 0x40000);
|
||||
if (BurnLoadRom(DrvTempRom + 0x0000, 7, 1)) return 1;
|
||||
if (BurnLoadRom(DrvTempRom + 0x2000, 8, 1)) return 1;
|
||||
if (BurnLoadRom(DrvTempRom + 0x4000, 9, 1)) return 1;
|
||||
if (BurnLoadRom(DrvTempRom + 0x6000, 10, 1)) return 1;
|
||||
GfxDecode(0x100 /*((0x18000*8)/3)/(16*16))*/, 4, 16, 16, c16PlaneOffsets, c16XOffsets, c16YOffsets, 0x100, DrvTempRom, DrvSpriteGFX);
|
||||
|
||||
}
|
||||
BurnFree(DrvTempRom);
|
||||
}
|
||||
|
||||
VezInit(0, V20_TYPE);
|
||||
VezOpen(0);
|
||||
|
||||
memset(DrvNVRAM, 0xff, 0x1000); // Init NVRAM
|
||||
|
||||
VezMapArea(0x01000, 0x02fff, 0, DrvDummyROM); // RAM/ROM (for reactor and 3stooges)
|
||||
VezMapArea(0x01000, 0x02fff, 1, DrvDummyROM); // not used in qbert, but something needs to be here
|
||||
VezMapArea(0x01000, 0x02fff, 2, DrvDummyROM);
|
||||
VezSetReadHandler(main_read);
|
||||
VezSetWriteHandler(main_write);
|
||||
|
||||
VezClose();
|
||||
|
||||
M6502Init(0, TYPE_M6502);
|
||||
M6502Open(0);
|
||||
M6502SetWriteHandler(audio_write);
|
||||
M6502SetReadHandler(audio_read);
|
||||
M6502SetWriteMemIndexHandler(audio_write);
|
||||
M6502SetReadMemIndexHandler(audio_read);
|
||||
M6502SetReadOpArgHandler(audio_read);
|
||||
M6502SetReadOpHandler(audio_read);
|
||||
M6502Close();
|
||||
|
||||
BurnSampleInit(0);
|
||||
BurnSampleSetAllRoutesAllSamples(0.30, BURN_SND_ROUTE_BOTH);
|
||||
|
||||
DACInit(0, 0, 1, DrvSyncDAC);
|
||||
DACSetRoute(0, 0.35, BURN_SND_ROUTE_BOTH);
|
||||
|
||||
GenericTilesInit();
|
||||
|
||||
DrvDoReset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static INT32 DrvExit()
|
||||
{
|
||||
GenericTilesExit();
|
||||
|
||||
VezExit();
|
||||
M6502Exit();
|
||||
DACExit();
|
||||
BurnSampleExit();
|
||||
|
||||
BurnFree(AllMem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void RenderTileCPMP(INT32 code, INT32 color, INT32 sx, INT32 sy, INT32 flipx, INT32 flipy, INT32 width, INT32 height, INT32 offset, INT32 mode, UINT8 *gfxrom)
|
||||
{
|
||||
UINT16 *dest = pTransDraw;
|
||||
UINT8 *gfx = gfxrom;
|
||||
|
||||
INT32 flip = 0;
|
||||
if (flipy) flip |= (height - 1) * width;
|
||||
if (flipx) flip |= width - 1;
|
||||
|
||||
gfx += code * width * height;
|
||||
|
||||
for (INT32 y = 0; y < height; y++, sy++) {
|
||||
if (sy < 0 || sy >= nScreenHeight) continue;
|
||||
|
||||
for (INT32 x = 0; x < width; x++, sx++) {
|
||||
if (sx < 0 || sx >= nScreenWidth) continue; // blank out the top and bottom 16 pixels for status
|
||||
|
||||
INT32 pxl = gfx[((y * width) + x) ^ flip];
|
||||
|
||||
if (!pxl) continue; // transparency
|
||||
|
||||
dest[sy * nScreenWidth + sx] = pxl | (color << 4) | offset;
|
||||
}
|
||||
sx -= width;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void draw_sprites()
|
||||
{
|
||||
for (INT32 offs = 0; offs < 0x100 - 8; offs += 4) {
|
||||
INT32 sx = (DrvSpriteRAM[offs + 1]) - 4;
|
||||
INT32 sy = (DrvSpriteRAM[offs]) - 13;
|
||||
INT32 code = (255 ^ DrvSpriteRAM[offs + 2]) + 256 * *spritebank;
|
||||
|
||||
//if (flip_screen_x) sx = 233 - sx;
|
||||
//if (flip_screen_y) sy = 244 - sy;
|
||||
|
||||
if (DrvSpriteRAM[offs] || DrvSpriteRAM[offs + 1]) /* needed to avoid garbage on screen */
|
||||
Render16x16Tile_Mask_Clip(pTransDraw, code, sx, sy, 0, 4, 0, 0x00, DrvSpriteGFX);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_bg()
|
||||
{
|
||||
INT32 hflip = 0, vflip = 0;
|
||||
for (INT32 offs = 0x3ff; offs >= 0; offs--)
|
||||
{
|
||||
INT32 sx = offs % 32;
|
||||
INT32 sy = offs / 32;
|
||||
|
||||
if (hflip) sx = 31 - sx;
|
||||
if (vflip) sy = 29 - sy;
|
||||
|
||||
INT32 code = DrvVideoRAM[offs];
|
||||
INT32 color = 0;
|
||||
|
||||
sx = 8 * sx;
|
||||
sy = 8 * sy;
|
||||
if (sx >= nScreenWidth) continue;
|
||||
if (sy >= nScreenHeight) continue;
|
||||
|
||||
RenderTileCPMP(code, color, sx, sy, hflip, vflip, 8, 8, 0, 0, DrvCharGFX);
|
||||
}
|
||||
}
|
||||
|
||||
static INT32 DrvDraw()
|
||||
{
|
||||
if (DrvRecalc) {
|
||||
qbert_palette();
|
||||
DrvRecalc = 0;
|
||||
}
|
||||
|
||||
BurnTransferClear();
|
||||
|
||||
if (nBurnLayer & 2 && !*background_prio) draw_bg();
|
||||
if (nBurnLayer & 4) draw_sprites();
|
||||
if (nBurnLayer & 2 && *background_prio) draw_bg();
|
||||
|
||||
BurnTransferCopy(DrvPalette);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void DrvMakeInputs()
|
||||
{
|
||||
// Reset Inputs (all active HIGH)
|
||||
DrvInput[0] = 0;
|
||||
DrvInput[1] = 0;
|
||||
|
||||
// Compile Digital Inputs
|
||||
for (INT32 i = 0; i < 8; i++) {
|
||||
DrvInput[0] |= (DrvJoy1[i] & 1) << i;
|
||||
DrvInput[1] |= (DrvJoy2[i] & 1) << i;
|
||||
}
|
||||
}
|
||||
|
||||
static INT32 DrvFrame()
|
||||
{
|
||||
if (DrvReset) {
|
||||
DrvDoReset();
|
||||
}
|
||||
|
||||
DrvMakeInputs();
|
||||
M6502NewFrame();
|
||||
|
||||
INT32 nInterleave = 256;
|
||||
INT32 nCyclesTotalVez = 5000000 / 60;
|
||||
INT32 nCyclesTotal6502 = (3579545 / 4) / 60;
|
||||
|
||||
VezOpen(0);
|
||||
M6502Open(0);
|
||||
for (INT32 i = 0; i < nInterleave; i++) {
|
||||
M6502Run(nCyclesTotal6502 / nInterleave);
|
||||
if (*soundcpu_do_nmi) {
|
||||
M6502SetIRQLine(M6502_INPUT_LINE_NMI, CPU_IRQSTATUS_AUTO);
|
||||
*soundcpu_do_nmi = 0;
|
||||
}
|
||||
|
||||
VezRun(nCyclesTotalVez / nInterleave);
|
||||
if (i == (nInterleave - 1))
|
||||
VezSetIRQLineAndVector(0x20, 0xff, CPU_IRQSTATUS_AUTO);
|
||||
}
|
||||
VezClose();
|
||||
M6502Close();
|
||||
|
||||
if (pBurnSoundOut) {
|
||||
BurnSampleRender(pBurnSoundOut, nBurnSoundLen);
|
||||
DACUpdate(pBurnSoundOut, nBurnSoundLen);
|
||||
}
|
||||
|
||||
if (pBurnDraw) {
|
||||
DrvDraw();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
|
||||
{
|
||||
struct BurnArea ba;
|
||||
|
||||
if (pnMin) {
|
||||
*pnMin = 0x029735;
|
||||
}
|
||||
|
||||
if (nAction & ACB_VOLATILE) {
|
||||
memset(&ba, 0, sizeof(ba));
|
||||
ba.Data = AllRam;
|
||||
ba.nLen = RamEnd - AllRam;
|
||||
ba.szName = "All Ram";
|
||||
BurnAcb(&ba);
|
||||
|
||||
VezScan(nAction);
|
||||
M6502Scan(nAction);
|
||||
|
||||
DACScan(nAction, pnMin);
|
||||
BurnSampleScan(nAction, pnMin);
|
||||
}
|
||||
|
||||
if (nAction & ACB_NVRAM) {
|
||||
memset(&ba, 0, sizeof(ba));
|
||||
ba.Data = DrvNVRAM;
|
||||
ba.nLen = 0x1000;
|
||||
ba.szName = "NV RAM";
|
||||
BurnAcb(&ba);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct BurnSampleInfo qbertSampleDesc[] = {
|
||||
{"fx_17a.wav", SAMPLE_NOLOOP },
|
||||
{"fx_17b.wav", SAMPLE_NOLOOP },
|
||||
{"fx_17c.wav", SAMPLE_NOLOOP },
|
||||
{"fx_17d.wav", SAMPLE_NOLOOP },
|
||||
{"fx_17e.wav", SAMPLE_NOLOOP },
|
||||
{"fx_17f.wav", SAMPLE_NOLOOP },
|
||||
{"fx_17g.wav", SAMPLE_NOLOOP },
|
||||
{"fx_17h.wav", SAMPLE_NOLOOP },
|
||||
{"fx_18a.wav", SAMPLE_NOLOOP },
|
||||
{"fx_18b.wav", SAMPLE_NOLOOP },
|
||||
{"fx_18c.wav", SAMPLE_NOLOOP },
|
||||
{"fx_18d.wav", SAMPLE_NOLOOP },
|
||||
{"fx_18e.wav", SAMPLE_NOLOOP },
|
||||
{"fx_18f.wav", SAMPLE_NOLOOP },
|
||||
{"fx_18g.wav", SAMPLE_NOLOOP },
|
||||
{"fx_18h.wav", SAMPLE_NOLOOP },
|
||||
{"fx_19a.wav", SAMPLE_NOLOOP },
|
||||
{"fx_19b.wav", SAMPLE_NOLOOP },
|
||||
{"fx_19c.wav", SAMPLE_NOLOOP },
|
||||
{"fx_19d.wav", SAMPLE_NOLOOP },
|
||||
{"fx_19e.wav", SAMPLE_NOLOOP },
|
||||
{"fx_19f.wav", SAMPLE_NOLOOP },
|
||||
{"fx_19g.wav", SAMPLE_NOLOOP },
|
||||
{"fx_19h.wav", SAMPLE_NOLOOP },
|
||||
{"fx_20a.wav", SAMPLE_NOLOOP },
|
||||
{"fx_20b.wav", SAMPLE_NOLOOP },
|
||||
{"fx_20c.wav", SAMPLE_NOLOOP },
|
||||
{"fx_20d.wav", SAMPLE_NOLOOP },
|
||||
{"fx_20e.wav", SAMPLE_NOLOOP },
|
||||
{"fx_20f.wav", SAMPLE_NOLOOP },
|
||||
{"fx_20g.wav", SAMPLE_NOLOOP },
|
||||
{"fx_20h.wav", SAMPLE_NOLOOP },
|
||||
{"fx_21a.wav", SAMPLE_NOLOOP },
|
||||
{"fx_21b.wav", SAMPLE_NOLOOP },
|
||||
{"fx_21c.wav", SAMPLE_NOLOOP },
|
||||
{"fx_21d.wav", SAMPLE_NOLOOP },
|
||||
{"fx_21e.wav", SAMPLE_NOLOOP },
|
||||
{"fx_21f.wav", SAMPLE_NOLOOP },
|
||||
{"fx_21g.wav", SAMPLE_NOLOOP },
|
||||
{"fx_21h.wav", SAMPLE_NOLOOP },
|
||||
{"fx_22.wav", SAMPLE_NOLOOP },
|
||||
{"fx_23.wav", SAMPLE_NOLOOP },
|
||||
{"fx_28.wav", SAMPLE_NOLOOP },
|
||||
{"fx_36.wav", SAMPLE_NOLOOP },
|
||||
{"knocker.wav", SAMPLE_NOLOOP },
|
||||
{"", 0 }
|
||||
};
|
||||
|
||||
STD_SAMPLE_PICK(qbert)
|
||||
STD_SAMPLE_FN(qbert)
|
||||
|
||||
// Q*bert (US set 1)
|
||||
|
||||
static struct BurnRomInfo qbertRomDesc[] = {
|
||||
{ "qb-rom2.bin", 0x2000, 0xfe434526, 1 }, // 0 maincpu
|
||||
{ "qb-rom1.bin", 0x2000, 0x55635447, 1 }, // 1
|
||||
{ "qb-rom0.bin", 0x2000, 0x8e318641, 1 }, // 2
|
||||
|
||||
{ "qb-snd1.bin", 0x0800, 0x15787c07, 2 }, // 3 audiocpu
|
||||
{ "qb-snd2.bin", 0x0800, 0x58437508, 2 }, // 4
|
||||
|
||||
{ "qb-bg0.bin", 0x1000, 0x7a9ba824, 3 }, // 5 bgtiles
|
||||
{ "qb-bg1.bin", 0x1000, 0x22e5b891, 3 }, // 6
|
||||
|
||||
{ "qb-fg3.bin", 0x2000, 0xdd436d3a, 4 }, // 7 sprites
|
||||
{ "qb-fg2.bin", 0x2000, 0xf69b9483, 4 }, // 8
|
||||
{ "qb-fg1.bin", 0x2000, 0x224e8356, 4 }, // 9
|
||||
{ "qb-fg0.bin", 0x2000, 0x2f695b85, 4 }, // 10
|
||||
};
|
||||
|
||||
STD_ROM_PICK(qbert)
|
||||
STD_ROM_FN(qbert)
|
||||
|
||||
struct BurnDriver BurnDrvQbert = {
|
||||
"qbert", NULL, NULL, "qbert", "1982",
|
||||
"Q*bert (US set 1)\0", NULL, "Gottlieb", "Miscellaneous",
|
||||
NULL, NULL, NULL, NULL,
|
||||
BDF_GAME_WORKING | BDF_ORIENTATION_VERTICAL | BDF_16BIT_ONLY, 2, HARDWARE_MISC_PRE90S, GBF_MISC, 0,
|
||||
NULL, qbertRomInfo, qbertRomName, qbertSampleInfo, qbertSampleName, QbertInputInfo, QbertDIPInfo,
|
||||
DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x10,
|
||||
240, 256, 3, 4
|
||||
};
|
||||
|
||||
|
||||
// Q*bert (US set 2)
|
||||
|
||||
static struct BurnRomInfo qbertaRomDesc[] = {
|
||||
{ "qrom_2.bin", 0x2000, 0xb54a8ffc, 1 }, // 0 maincpu
|
||||
{ "qrom_1.bin", 0x2000, 0x19d924e3, 1 }, // 1
|
||||
{ "qrom_0.bin", 0x2000, 0x2e7fad1b, 1 }, // 2
|
||||
|
||||
{ "qb-snd1.bin", 0x0800, 0x15787c07, 2 }, // 3 audiocpu
|
||||
{ "qb-snd2.bin", 0x0800, 0x58437508, 2 }, // 4
|
||||
|
||||
{ "qb-bg0.bin", 0x1000, 0x7a9ba824, 3 }, // 5 bgtiles
|
||||
{ "qb-bg1.bin", 0x1000, 0x22e5b891, 3 }, // 6
|
||||
|
||||
{ "qb-fg3.bin", 0x2000, 0xdd436d3a, 4 }, // 7 sprites
|
||||
{ "qb-fg2.bin", 0x2000, 0xf69b9483, 4 }, // 8
|
||||
{ "qb-fg1.bin", 0x2000, 0x224e8356, 4 }, // 9
|
||||
{ "qb-fg0.bin", 0x2000, 0x2f695b85, 4 }, // 10
|
||||
};
|
||||
|
||||
STD_ROM_PICK(qberta)
|
||||
STD_ROM_FN(qberta)
|
||||
|
||||
struct BurnDriver BurnDrvQberta = {
|
||||
"qberta", "qbert", NULL, "qbert", "1982",
|
||||
"Q*bert (US set 2)\0", NULL, "Gottlieb", "Miscellaneous",
|
||||
NULL, NULL, NULL, NULL,
|
||||
BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, GBF_MISC, 0,
|
||||
NULL, qbertaRomInfo, qbertaRomName, qbertSampleInfo, qbertSampleName, QbertInputInfo, QbertDIPInfo,
|
||||
DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x10,
|
||||
240, 256, 3, 4
|
||||
};
|
||||
|
||||
|
||||
// Q*bert (Japan)
|
||||
|
||||
static struct BurnRomInfo qbertjRomDesc[] = {
|
||||
{ "qbj-rom2.bin", 0x2000, 0x67bb1cb2, 1 }, // 0 maincpu
|
||||
{ "qbj-rom1.bin", 0x2000, 0xc61216e7, 1 }, // 1
|
||||
{ "qbj-rom0.bin", 0x2000, 0x69679d5c, 1 }, // 2
|
||||
|
||||
{ "qb-snd1.bin", 0x0800, 0x15787c07, 2 }, // 3 audiocpu
|
||||
{ "qb-snd2.bin", 0x0800, 0x58437508, 2 }, // 4
|
||||
|
||||
{ "qb-bg0.bin", 0x1000, 0x7a9ba824, 3 }, // 5 bgtiles
|
||||
{ "qb-bg1.bin", 0x1000, 0x22e5b891, 3 }, // 6
|
||||
|
||||
{ "qb-fg3.bin", 0x2000, 0xdd436d3a, 4 }, // 7 sprites
|
||||
{ "qb-fg2.bin", 0x2000, 0xf69b9483, 4 }, // 8
|
||||
{ "qb-fg1.bin", 0x2000, 0x224e8356, 4 }, // 9
|
||||
{ "qb-fg0.bin", 0x2000, 0x2f695b85, 4 }, // 10
|
||||
};
|
||||
|
||||
STD_ROM_PICK(qbertj)
|
||||
STD_ROM_FN(qbertj)
|
||||
|
||||
struct BurnDriver BurnDrvQbertj = {
|
||||
"qbertj", "qbert", NULL, "qbert", "1982",
|
||||
"Q*bert (Japan)\0", NULL, "Gottlieb (Konami license)", "Miscellaneous",
|
||||
NULL, NULL, NULL, NULL,
|
||||
BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, GBF_MISC, 0,
|
||||
NULL, qbertjRomInfo, qbertjRomName, qbertSampleInfo, qbertSampleName, QbertInputInfo, QbertDIPInfo,
|
||||
DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x10,
|
||||
240, 256, 3, 4
|
||||
};
|
||||
|
||||
|
||||
// Mello Yello Q*bert
|
||||
|
||||
static struct BurnRomInfo myqbertRomDesc[] = {
|
||||
{ "mqb-rom2.bin", 0x2000, 0x6860f957, 1 }, // 0 maincpu
|
||||
{ "mqb-rom1.bin", 0x2000, 0x11f0a4e4, 1 }, // 1
|
||||
{ "mqb-rom0.bin", 0x2000, 0x12a90cb2, 1 }, // 2
|
||||
|
||||
{ "mqb-snd1.bin", 0x0800, 0x495ffcd2, 2 }, // 3 audiocpu
|
||||
{ "mqb-snd2.bin", 0x0800, 0x9bbaa945, 2 }, // 4
|
||||
|
||||
{ "qb-bg0.bin", 0x1000, 0x7a9ba824, 3 }, // 5 bgtiles
|
||||
{ "qb-bg1.bin", 0x1000, 0x22e5b891, 3 }, // 6
|
||||
|
||||
{ "mqb-fg3.bin", 0x2000, 0x8b5d0852, 4 }, // 7 sprites
|
||||
{ "mqb-fg2.bin", 0x2000, 0x823f1e57, 4 }, // 8
|
||||
{ "mqb-fg1.bin", 0x2000, 0x05343ae6, 4 }, // 9
|
||||
{ "mqb-fg0.bin", 0x2000, 0xabc71bdd, 4 }, // 10
|
||||
};
|
||||
|
||||
STD_ROM_PICK(myqbert)
|
||||
STD_ROM_FN(myqbert)
|
||||
|
||||
struct BurnDriver BurnDrvMyqbert = {
|
||||
"myqbert", "qbert", NULL, "qbert", "1982",
|
||||
"Mello Yello Q*bert\0", NULL, "Gottlieb", "Miscellaneous",
|
||||
NULL, NULL, NULL, NULL,
|
||||
BDF_GAME_WORKING | BDF_CLONE | BDF_ORIENTATION_VERTICAL, 2, HARDWARE_MISC_PRE90S, GBF_MISC, 0,
|
||||
NULL, myqbertRomInfo, myqbertRomName, qbertSampleInfo, qbertSampleName, QbertInputInfo, QbertDIPInfo,
|
||||
DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x10,
|
||||
240, 256, 3, 4
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user