⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 d_superman.cpp

📁 motorola ezx 平台下的fba模拟器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
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 + -