📄 d_superman.cpp
字号:
/*
Part of FBAs Taito 68k hardware drivers
Credits: Mame team, Raine team
Driver by Treble Winner
*/
//#include "taito.h"
#include "burnint.h"
#include "taito_gfx.h"
#include "snd_tc0140.h"
#include "burn_ym2610.h"
static unsigned char *Mem = NULL, *MemEnd = NULL;
static unsigned char *RamStart =NULL, *RamEnd = NULL;
static unsigned char *Rom = NULL;
static unsigned char *Superman_ram = NULL, *Superman_src_pal = NULL;
static unsigned char SupermanReset = 0;
static unsigned char *z80_rom = NULL, *z80_ram = NULL;
static unsigned char *SupermanYM2610Rom = NULL;
static unsigned int *Superman_pal = NULL;
// Z80 ROM bank
static int Z80Bank = 0;
static int nCurrentBank = 0;
static int nCyclesTotal[2];
static int nCyclesDone[2];
static int nCycles68KSync;
static unsigned char SupermanInputPort0[8], SupermanInputPort1[8], SupermanInputPort2[8];
unsigned char SupermanInput[3] = {0, 0, 0};
static unsigned char SupermanDip[2] = {0, 0};
static struct BurnInputInfo SupermanInputList[] =
{
{"P1 Coin" , 0, SupermanInputPort2 + 0, "p1 coin" },
{"P1 Start" , 0, SupermanInputPort0 + 7, "p1 start" },
{"P1 Up" , 0, SupermanInputPort0 + 0, "p1 up" },
{"P1 Down" , 0, SupermanInputPort0 + 1, "p1 down" },
{"P1 Left" , 0, SupermanInputPort0 + 2, "p1 left" },
{"P1 Right" , 0, SupermanInputPort0 + 3, "p1 right" },
{"P1 Button 1" , 0, SupermanInputPort0 + 4, "p1 fire 1" },
{"P1 Button 2" , 0, SupermanInputPort0 + 5, "p1 fire 2" },
{"P2 Coin" , 0, SupermanInputPort2 + 1, "p2 coin" },
{"P2 Start" , 0, SupermanInputPort1 + 7, "p2 start" },
{"P2 Up" , 0, SupermanInputPort1 + 0, "p2 up" },
{"P2 Down" , 0, SupermanInputPort1 + 1, "p2 down" },
{"P2 Left" , 0, SupermanInputPort1 + 2, "p2 left" },
{"P2 Right" , 0, SupermanInputPort1 + 3, "p2 right" },
{"P2 Button 1" , 0, SupermanInputPort1 + 4, "p2 fire 1" },
{"P2 Button 2" , 0, SupermanInputPort1 + 5, "p2 fire 2" },
{"Reset" , 0, &SupermanReset , "reset" },
{"Service" , 0, SupermanInputPort2 + 2, "service" },
{"Tilt" , 0, SupermanInputPort2 + 3, "tilt" },
{"Dip 1" , 2, SupermanDip + 0 , "dip" },
{"Dip 2" , 2, SupermanDip + 1 , "dip" },
};
STDINPUTINFO(Superman);
static struct BurnDIPInfo SupermanDIPList[]=
{
// Default Values
{0x13, 0xff, 0xff, 0x00, NULL },
{0x14, 0xff, 0xff, 0x00, NULL },
// Dip 1
{0 , 0xfe, 0 , 2 , "Flip Screen" },
{0x13, 0x01, 0x02, 0x00, "Off" },
{0x13, 0x01, 0x02, 0x02, "On" },
{0 , 0xfe, 0 , 2 , "Service Mode" },
{0x13, 0x01, 0x04, 0x00, "Off" },
{0x13, 0x01, 0x04, 0x04, "On" },
{0 , 0xfe, 0 , 4 , "Coin A" },
{0x13, 0x01, 0x30, 0x30, "4 Coins 1 Credit" },
{0x13, 0x01, 0x30, 0x20, "3 Coins 1 Credit" },
{0x13, 0x01, 0x30, 0x10, "2 Coins 1 Credit" },
{0x13, 0x01, 0x30, 0x00, "1 Coin 1 Credit" },
{0 , 0xfe, 0 , 4 , "Coin B" },
{0x13, 0x01, 0xc0, 0xc0, "1 Coin 6 Credits" },
{0x13, 0x01, 0xc0, 0x80, "1 Coin 4 Credits" },
{0x13, 0x01, 0xc0, 0x40, "1 Coin 3 Credits" },
{0x13, 0x01, 0xc0, 0x00, "1 Coin 2 Credits" },
// {0 , 0xfe, 0 , 2 , "Demo Sounds" }, // No Effect?
// {0x13, 0x01, 0x08, 0x00, "Off" },
// {0x13, 0x01, 0x08, 0x08, "On" },
// Dip 2
{0 , 0xfe, 0 , 4 , "Lives" },
{0x14, 0x01, 0x30, 0x10, "2" },
{0x14, 0x01, 0x30, 0x00, "3" },
{0x14, 0x01, 0x30, 0x20, "4" },
{0x14, 0x01, 0x30, 0x30, "5" },
};
STDDIPINFO(Superman);
void SupermanBankSwitch(unsigned int data)
{
Z80Bank = (data - 1) & 0x03;
unsigned char* nStartAddress = z80_rom + 0x4000 + (Z80Bank * 0x4000);
nCurrentBank = Z80Bank;
ZetMapArea(0x4000, 0x7fff, 0, nStartAddress);
ZetMapArea(0x4000, 0x7fff, 2, nStartAddress);
}
int SupermanInpMake()
{
SupermanInput[0] = SupermanInput[1] = SupermanInput[2] = 0xff;
for (int i = 0; i < 8; i++) {
SupermanInput[0] -= (SupermanInputPort0[i] & 1) << i;
SupermanInput[1] -= (SupermanInputPort1[i] & 1) << i;
SupermanInput[2] -= (SupermanInputPort2[i] & 1) << i;
}
return 0;
}
// ----------------------------------------------------------------------------
// CPU synchronisation
static inline void SupermanSynchroniseZ80(int nExtraCycles)
{
int nCycles = ((long long)SekTotalCycles() * nCyclesTotal[1] / nCyclesTotal[0]) + nExtraCycles;
if (nCycles <= ZetTotalCycles()) {
return;
}
nCycles68KSync = nCycles - nExtraCycles;
BurnTimerUpdate(nCycles);
}
// Callbacks for the FM chip
static void SupermanFMIRQHandler(int, int nStatus)
{
if (nStatus) {
ZetSetIRQLine(0xFF, ZET_IRQSTATUS_ACK);
} else {
ZetSetIRQLine(0, ZET_IRQSTATUS_NONE);
}
}
static int SupermanSynchroniseStream(int nSoundRate)
{
return (long long)ZetTotalCycles() * nSoundRate / 4000000;
}
static double SupermanGetTime()
{
return (double)ZetTotalCycles() / 4000000.0;
}
// ----------------------------------------------------------------------------
inline static unsigned int CalcCol(unsigned short nColour)
{
int r, g, b;
r = (nColour & 0x001f) << 3; // Red
r |= r >> 5;
g = (nColour & 0x03e0) >> 2; // Green
g |= g >> 5;
b = (nColour & 0x7c00) >> 7; // Blue
b |= b >> 5;
return BurnHighCol(b, g, r, 0);
}
int SupermanPalUpdate()
{
int i;
unsigned short* ps;
unsigned int* pd;
for (i = 0, ps = (unsigned short*)Superman_src_pal, pd = Superman_pal; i < 0x400; i++, ps++, pd++) {
*pd = CalcCol(*ps);
}
return 0;
}
// This routine is called first to determine how much memory is needed (MemEnd-(unsigned char *)0),
// and then to set up all the pointers
static int MemIndex()
{
unsigned char *Next; Next=Mem;
Rom = Next; Next += 0x80000; // 68000 program
z80_rom = Next; Next += 0x1c000;
SupermanYM2610Rom= Next; Next += 0x80000;
RamStart = Next;
Superman_ram = Next; Next += 0x4000;
sysbvidattr = Next; Next += 0x1000;
sysbvidram = Next; Next += 0x4000;
Superman_src_pal = Next; Next += 0x1000;
Superman_pal = (unsigned int*)Next; Next += 0x800 * sizeof(unsigned int);
z80_ram = Next; Next += 0x2000;
RamEnd = Next;
MemEnd = Next;
return 0;
}
static int LoadRoms()
{
int nRet=0;
// Load program roms and byteswap
nRet = BurnLoadRom(Rom + 0x00001, 0, 2); if (nRet != 0) return 1;
nRet = BurnLoadRom(Rom + 0x00000, 1, 2); if (nRet != 0) return 1;
nRet = BurnLoadRom(Rom + 0x40001, 2, 2); if (nRet != 0) return 1;
nRet = BurnLoadRom(Rom + 0x40000, 3, 2); if (nRet != 0) return 1;
nRet = BurnLoadRom(z80_rom, 4, 1); // load z80 code rom
ttiles = (unsigned char *)malloc(0x400000);
memset(ttiles, 0, 16384 * 256);
SysxTempGfx = (unsigned char *)malloc(0x200000);
nRet = BurnLoadRom(SysxTempGfx + 0x000000, 5, 1);
nRet = BurnLoadRom(SysxTempGfx + 0x080000, 6, 1);
nRet = BurnLoadRom(SysxTempGfx + 0x100000, 7, 1);
nRet = BurnLoadRom(SysxTempGfx + 0x180000, 8, 1);
nRet = BurnLoadRom(SupermanYM2610Rom, 9, 1);
return nRet;
}
// C-Chip Stuff (Taken from MAME)
static int CChip_CurrentBank = 0;
static int CChip_Port = 0;
static int superman_code[40] =
{
0x48, 0xe7, 0x80, 0x80, /* MOVEM.L D0/A0,-(A7) ( Preserve Regs ) */
0x20, 0x6d, 0x1c, 0x40, /* MOVEA.L ($1C40,A5),A0 ( Load sound pointer in A0 ) */
0x30, 0x2f, 0x00, 0x0c, /* MOVE.W ($0C,A7),D0 ( Fetch sound number ) */
0x10, 0x80, /* MOVE.B D0,(A0) ( Store it on sound pointer ) */
0x52, 0x88, /* ADDQ.W #1,A0 ( Increment sound pointer ) */
0x20, 0x3c, 0x00, 0xf0, 0x1c, 0x40, /* MOVE.L #$F01C40,D0 ( Load top of buffer in D0 ) */
0xb1, 0xc0, /* CMPA.L D0,A0 ( Are we there yet? ) */
0x66, 0x04, /* BNE.S *+$6 ( No, we arent, skip next line ) */
0x41, 0xed, 0x1c, 0x20, /* LEA ($1C20,A5),A0 ( Point to the start of the buffer ) */
0x2b, 0x48, 0x1c, 0x40, /* MOVE.L A0,($1C40,A5) ( Store new sound pointer ) */
0x4c, 0xdf, 0x01, 0x01, /* MOVEM.L (A7)+, D0/A0 ( Restore Regs ) */
0x4e, 0x75 /* RTS ( Return ) */
};
static unsigned char CChip_Read(int Offset)
{
if (Offset == 0x401) {
// C-Chip ID
return 0x01;
}
if (CChip_CurrentBank == 0) {
switch (Offset) {
case 0x000: return SupermanInput[0]; // input port 1
case 0x001: return SupermanInput[1]; // input port 2
case 0x002: return SupermanInput[2]; // input port 3
case 0x003: return CChip_Port;
}
}
if (CChip_CurrentBank == 1 && Offset <= 0xff) {
// bprintf(PRINT_NORMAL, "C-Chip: Attempt to read sound commands\n");
if (Offset < 40) {
return superman_code[Offset];
} else {
return 0x00;
}
}
if (CChip_CurrentBank == 2) {
switch (Offset) {
case 0x000: return 0x47;
case 0x001: return 0x57;
case 0x002: return 0x4b;
}
}
return 0;
}
static void CChip_Write(int Offset, unsigned short Data)
{
if (Offset == 0x600) {
CChip_CurrentBank = Data;
return;
}
if (CChip_CurrentBank == 0 && Offset == 0x003) {
CChip_Port = Data;
return;
}
}
unsigned char __fastcall SupermanZ80Read(unsigned short a)
{
switch (a) {
case (0xe000):
return BurnYM2610Read(0);;
case (0xe001):
return BurnYM2610Read(1);
case (0xe002):
return BurnYM2610Read(2);
case (0xe201):
return tc0140_slave_comm_r();
}
return 0;
}
void __fastcall SupermanZ80Write(unsigned short a, unsigned char d)
{
switch (a) {
case 0xe000:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -