示例#1
0
void Sf2mdtSoundFrameEnd()
{
	for (INT32 i = Sf2mdtSoundPos; i < Sf2mdtMSM5205Interleave; i++) {
		ZetRun(Sf2mdtCyclesPerSegment);
		MSM5205Update();
		Sf2mdtSoundPos = i;
	}
	ZetRun(nCpsZ80Cycles - ZetTotalCycles());
	
	if (pBurnSoundOut) {
		BurnYM2151Render(pBurnSoundOut, nBurnSoundLen);
		MSM5205Render(0, pBurnSoundOut, nBurnSoundLen);
		MSM5205Render(1, pBurnSoundOut, nBurnSoundLen);
	}
	ZetClose();
}
示例#2
0
文件: ps.cpp 项目: SiN13/pifba
static void drvYM2151IRQHandler(int nStatus)
{
	if (nStatus) {
		ZetSetIRQLine(0xFF, ZET_IRQSTATUS_ACK);
		ZetRun(0x0800);
	} else {
		ZetSetIRQLine(0,    ZET_IRQSTATUS_NONE);
	}
}
示例#3
0
static INT32 DrvFrame()
{
	if (DrvReset) {
		DrvDoReset();
	}

	{
		memset (DrvInputs, 0xff, 3);
		for (INT32 i = 0; i < 8; i++) {
			DrvInputs[0] ^= DrvJoy1[i] << i;
			DrvInputs[1] ^= DrvJoy2[i] << i;
			DrvInputs[2] ^= DrvJoy3[i] << i;
		}
	}

	INT32 nInterleave = 10;
	INT32 nCyclesTotal[2] = { 6000000 / 60, 6000000 / 60 };
	INT32 nCyclesDone[2] = { 0, 0 };

	for (INT32 i = 0; i < nInterleave; i++) {
		INT32 nSegment;

		ZetOpen(0);
		nSegment = nCyclesTotal[0] / nInterleave;
		nCyclesDone[0] += ZetRun(nSegment);
		if (i == (nInterleave - 1)) ZetSetIRQLine(0, CPU_IRQSTATUS_AUTO);
		ZetClose();

		ZetOpen(1);
		nCyclesDone[1] += ZetRun(nSegment);
		ZetClose();
	}

	if (pBurnSoundOut) {
		MSM6295Render(0,pBurnSoundOut, nBurnSoundLen);
	}

	if (pBurnDraw) {
		DrvDraw();
	}

	return 0;
}
示例#4
0
void hcastle_write(UINT16 address, UINT8 data)
{
	if ((address & 0xfff8) == 0x0000) {
		playfield_write(address, data, DrvPf1Ctrl, DrvSprRAM1, DrvSprBuf1);
		return;
	}

	if ((address & 0xfff8) == 0x0200) {
		playfield_write(address, data, DrvPf2Ctrl, DrvSprRAM2, DrvSprBuf2);
		return;
	}

	if ((address & 0xff00) == 0x0000) {
		DrvKonRAM0[address & 0xff] = data;
		return;
	}

	if ((address & 0xff00) == 0x0200) {
		DrvKonRAM1[address & 0xff] = data;
		return;
	}

	switch (address)
	{
		case 0x0400:
			bankswitch(data);
		return;

		case 0x0404:
			*soundlatch = data;
		return;

		case 0x0408:
		{
			float t = konamiTotalCycles() * 1.19318167;
			t -= ZetTotalCycles();
			if (t > 1) ZetRun((INT32)t);

			ZetSetIRQLine(0, ZET_IRQSTATUS_ACK);
		}
		return;

		case 0x040c:
			watchdog = 0;
		return;

		case 0x0410:

		return;

		case 0x0418:
			*gfxbank = data;
		return;
	}
}
示例#5
0
int PsndZRun(int nWant)
{
	int nDid;
	if (nWant<=0)
	{
		return 0;
	}
	nDid=ZetRun(nWant);
	nNextTimer-=nDid;
	return nDid;
}
示例#6
0
void HangonPPI0WritePortC(UINT8 data)
{
	System16ColScroll = ~data & 0x04;
	System16RowScroll = ~data & 0x02;
	
	if (!(data & 0x80)) {
		ZetNmi();
		ZetRun(100);
		nSystem16CyclesDone[2] += 100;
	}
}
示例#7
0
static int drvDoReset()
{
	SekOpen(0);
	SekReset();
	SekClose();
	ZetOpen(0);
	ZetReset();
	ZetClose();
	ZetRun(4000000/60);
	BurnYM2151Reset();
	return 0;
}
示例#8
0
void Sf2mdtSoundCommand(UINT16 d)
{
	INT32 nCyclesToDo = ((INT64)SekTotalCycles() * nCpsZ80Cycles / nCpsCycles) - ZetTotalCycles();
	INT32 nEnd = Sf2mdtSoundPos + (INT64)Sf2mdtMSM5205Interleave * nCyclesToDo / nCpsZ80Cycles;
	
	for (INT32 i = Sf2mdtSoundPos; i < nEnd; i++) {
		ZetRun(Sf2mdtCyclesPerSegment);
		MSM5205Update();
		Sf2mdtSoundPos = i;
	}
	
	Sf2mdtSoundLatch = d & 0xff;
	ZetSetIRQLine(0, ZET_IRQSTATUS_ACK);
}
示例#9
0
static int DrvFrame()
{
	if (DrvReset) {
		DrvDoReset();
	}

	ZetOpen(0);
	ZetRun(4000000 / 60);
	ZetRaiseIrq(0);
	ZetClose();

	if (pBurnDraw) {
		DrvDraw();
	}

	return 0;
}
示例#10
0
void __fastcall rollerg_sound_write(unsigned short address, unsigned char data)
{
	switch (address)
	{
		case 0xc000:
		case 0xc001:
			BurnYM3812Write(address & 1, data);
		return;

		case 0xfc00:
			ZetRun(100);
			ZetNmi();
		return;
	}

	if (address >= 0xa000 && address <= 0xa02f) {
		K053260Write(0, address & 0x3f, data);
		return;
	}
}
示例#11
0
int QsndSectRun(int nStart,int nEnd)
{
	int nTo;
	// See if an irq occurs before the end
	while (nStart+nIrqNext<nEnd)
	{
		nTo=nStart+nIrqNext;
		SectRun(nStart,nTo);
		ZetRaiseIrq(0xff);
		ZetRun(0);
		ZetLowerIrq();

		nIrqNext=nIrqPeriod; // Next irq happens after period
		nStart=nTo; // Done this part now
	}

	nTo=nEnd;
	SectRun(nStart,nTo);
	nIrqNext-=nTo-nStart; // Next irq happens sooner
	return 0;
}
示例#12
0
void __fastcall parodius_sound_write(UINT16 address, UINT8 data)
{
	switch (address)
	{
		case 0xf800:
			BurnYM2151SelectRegister(data);
		return;

		case 0xf801:
			BurnYM2151WriteRegister(data);
		return;

		case 0xfa00:
			nCyclesDone[1] += ZetRun(100);
			ZetNmi();
		return;
	}

	if (address >= 0xfc00 && address <= 0xfc2f) {
		K053260Write(0, address & 0x3f, data);
	}
}
示例#13
0
void __fastcall battlegWriteByte(UINT32 sekAddress, UINT8 byteValue)
{
	switch (sekAddress) {

		case 0x218021:								// The 68K has access to the Z80 RAM
			RamZ80[0x10] = byteValue;				// Only these addresses are used, however
			break;

		case 0x21C01D:								// Coin control
			break;

		case 0x600001:
			nSoundCommand = byteValue;

			// Trigger Z80 interrupt, and allow the Z80 to process it
			ZetSetIRQLine(0xff, CPU_IRQSTATUS_AUTO);
			nCyclesDone[1] += ZetRun(0x0200);
			break;

//		default:
//			printf("Attempt to write byte value %x to location %x\n", byteValue, sekAddress);
	}
}
示例#14
0
// Run a section of one frame,
// e.g. 0x200 to 0x400 for second half
static INLINE void SectRun(int nStart,int nEnd)
{
	int nAtEnd,nAtStart,nWant,nDid=0;

	if (nEnd<=nStart)
	{
		return;
	}

	nAtStart=(nZTotal*nStart)>>10;
	nAtEnd  =(nZTotal*nEnd  )>>10;

	// Cycles would we like to do this time to get to end point
	nWant=nAtEnd-nAtStart-nZExtra;

	if (nWant>0)
	{
		nDid=ZetRun(nWant);
	}
	nZExtra=nDid-nWant;

	SectSound(nStart,nEnd);
}
示例#15
0
void __fastcall batriderWriteWord(UINT32 sekAddress, UINT16 wordValue)
{
	switch (sekAddress) {
		case 0x500020: {
			RamShared[0] = wordValue;
            
			// The 68K program normally writes 0x500020/0x500022 as a single longword,
			// except during the communications test.
			if (wordValue == 0x55) {
				ZetNmi();
				nCyclesDone[1] += ZetRun(0x1800);
			}
			break;
		}
		case 0x500022:
			RamShared[1] = wordValue;
            
			// Sound commands are processed by the Z80 using an NMI
			// So, trigger a Z80 NMI and execute it
			ZetNmi();
			nCyclesDone[1] += ZetRun(0x1800);
			break;
            
		case 0x500024:
			// Writes to this address only occur in situations where the program sets
			// 0x20FA19 (Ram02[0x7A18]) to 0xFF, and then sits in a loop waiting for it to become 0x00
			// Interrupt 4 does this (the same code is also conditionally called from interrupt 2)
            
			nIRQPending = 1;
			SekSetIRQLine(4, SEK_IRQSTATUS_ACK);
			break;
            
		case 0x500060:
			// Bit 0 of the value written to this location must be echod at 0x50000C
			nData = wordValue;
			break;
            
		case 0x500080:
			Map68KTextROM(false);
			break;
            
		case 0x500082:								// Acknowledge interrupt
			SekSetIRQLine(0, SEK_IRQSTATUS_NONE);
			nIRQPending = 0;
			break;
            
		case 0x5000C0:
		case 0x5000C1:
		case 0x5000C2:
		case 0x5000C3:
		case 0x5000C4:
		case 0x5000C5:
		case 0x5000C6:
		case 0x5000C7:
		case 0x5000C8:
		case 0x5000C9:
		case 0x5000CA:
		case 0x5000CB:
		case 0x5000CC:
		case 0x5000CD:
		case 0x5000CE:
			GP9001TileBank[(sekAddress & 0x0F) >> 1] = ((wordValue & 0x0F) << 15);
			break;
            
            //		default:
            //			printf("Attempt to write %06X (word) -> %04X.\n", sekAddress, wordValue);
	}
}
示例#16
0
/* Run the virtual console emulation for one frame */
void system_frame(int skip_render)
{
    static int iline_table[] = {0xC0, 0xE0, 0xF0};
    int lpf = (sms.display == DISPLAY_NTSC) ? 262 : 313;
    int iline, z80cnt = 0;;
	INT32 nSoundBufferPos = 0;

    /* Debounce pause key */
    if(input.system & INPUT_PAUSE)
    {
        if(!sms.paused)
        {
            sms.paused = 1;

			ZetNmi();
        }
    }
    else
    {
         sms.paused = 0;
    }

	ZetNewFrame();

    text_counter = 0;

    /* End of frame, parse sprites for line 0 on line 261 (VCount=$FF) */
    if(vdp.mode <= 7)
        parse_line(0);

    for(vdp.line = 0; vdp.line < lpf;)
    {
        iline = iline_table[vdp.extended];
		z80cnt = 0;

        if(!skip_render)
        {
            render_line(vdp.line);
        }

        if(vdp.line <= iline)
        {
            vdp.left -= 1;
            if(vdp.left == -1)
            {
                vdp.left = vdp.reg[0x0A];
                vdp.hint_pending = 1;

                if(vdp.reg[0x00] & 0x10)
				{
					if (!(ZetTotalCycles() % CYCLES_PER_LINE)) {
						ZetRun(1);
						z80cnt++;
					}
					ZetSetIRQLine(0, CPU_IRQSTATUS_ACK);
                }
            }
        }
        else
        {
            vdp.left = vdp.reg[0x0A];
        }

		ZetRun(228 - z80cnt);

        if(vdp.line == iline)
        {
            vdp.status |= 0x80;
            vdp.vint_pending = 1;

            if(vdp.reg[0x01] & 0x20)
            {
                ZetSetIRQLine(0, CPU_IRQSTATUS_ACK);
            }
        }

		// Render Sound Segment
		if (pBurnSoundOut) {
			INT32 nSegmentLength = nBurnSoundLen / lpf;
			INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
			SN76496Update(0, pSoundBuf, nSegmentLength);
			nSoundBufferPos += nSegmentLength;
		}

        ++vdp.line;

        if(vdp.mode <= 7)
            parse_line(vdp.line);
    }

	// Make sure the buffer is entirely filled.
	if (pBurnSoundOut) {
		INT32 nSegmentLength = nBurnSoundLen - nSoundBufferPos;
		INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
		if (nSegmentLength) {
			SN76496Update(0, pSoundBuf, nSegmentLength);
		}
	}
}
示例#17
0
int TmntFrame()
{
	int nInterleave = 16;
	if (DrvReset)
	{
		TmntReset();
	}
	TmntInpMake();

	nCyclesTotal[0] = 8000000/60;							
	nCyclesTotal[1] = 3579545/60;
	nCyclesDone[0] = nCyclesDone[1] = 0;
	int nSoundBufferPos = 0;

	SekOpen(0);
	ZetOpen(0);
	if (bInt5)
	{
		SekSetIRQLine(5, SEK_IRQSTATUS_AUTO);
	}
	for (int i = 0; i < nInterleave; i++) {
    	int nCurrentCPU;
		int nNext;
		// Run 68000
		nCurrentCPU = 0;
		nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave;

		nCyclesSegment = nNext - nCyclesDone[nCurrentCPU];
		if (!CheckSleep(nCurrentCPU)) {					// See if this CPU is busywaiting
			nCyclesDone[nCurrentCPU] += SekRun(nCyclesSegment);
		} else {
			nCyclesDone[nCurrentCPU] += nCyclesSegment;
		}
		// Run Z80
		nCurrentCPU = 1;
		nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave;
		nCyclesSegment = nNext - nCyclesDone[nCurrentCPU];
		nCyclesSegment = ZetRun(nCyclesSegment);
		nCyclesDone[nCurrentCPU] += nCyclesSegment;

		{
			// Render sound segment
			if (pBurnSoundOut) {
				int nSegmentLength = nBurnSoundLen / nInterleave;
				short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
				BurnYM2151Render(pSoundBuf, nSegmentLength);
				UPD7759Update(pSoundBuf, nSegmentLength);
				nSoundBufferPos += nSegmentLength;
			}
		}
	}

	{
		// Make sure the buffer is entirely filled.
		if (pBurnSoundOut) {
			int nSegmentLength = nBurnSoundLen - nSoundBufferPos;
			short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
			if (nSegmentLength) {
				BurnYM2151Render(pSoundBuf, nSegmentLength);
				UPD7759Update(pSoundBuf, nSegmentLength);
			}
		}
	}
//	
	ZetClose();
	SekClose();
	
//	UPD7759Update(pBurnSoundOut, nBurnSoundLen);

	if (pBurnDraw) {
		TmntDraw();														// Draw screen if needed
	}

	return 0;
}
示例#18
0
void __fastcall metmqstrWriteWord(UINT32 sekAddress, UINT16 wordValue)
{
	if (sekAddress >= 0xa8000a && sekAddress <= 0xa80068) return;
	if (sekAddress >= 0xa8006a && sekAddress <= 0xa8006c) return;
	if (sekAddress >= 0xa80004 && sekAddress <= 0xa80006) return;
	
	switch (sekAddress) {
		case 0xa80000:
			nCaveXOffset = wordValue;
			return;
		case 0xa80002:
			nCaveYOffset = wordValue;
			return;
			
		case 0xa80008:
			CaveSpriteBuffer();
			nCaveSpriteBank = wordValue;
			return;
			
		case 0xa8006E:
			SoundLatch = wordValue;
			SoundLatchStatus |= 0x0C;

			ZetNmi();
			nCyclesDone[1] += ZetRun(0x0400);
			return;
			
		case 0xb00000:
			CaveTileReg[2][0] = wordValue;
			break;
		case 0xb00002:
			CaveTileReg[2][1] = wordValue;
			break;
		case 0xb00004:
			CaveTileReg[2][2] = wordValue;
			break;
			
		case 0xb80000:
			CaveTileReg[1][0] = wordValue;
			break;
		case 0xb80002:
			CaveTileReg[1][1] = wordValue;
			break;
		case 0xb80004:
			CaveTileReg[1][2] = wordValue;
			break;
			
		case 0xc00000:
			CaveTileReg[0][0] = wordValue;
			break;
		case 0xc00002:
			CaveTileReg[0][1] = wordValue;
			break;
		case 0xc00004:
			CaveTileReg[0][2] = wordValue;
			break;
		
		case 0xd00000:
			if (~wordValue & 0x0100) {
			wordValue >>= 8;
			EEPROMWrite(wordValue & 0x04, wordValue & 0x02, wordValue & 0x08);
			break;
			}
		default: {
			bprintf(PRINT_NORMAL, _T("Attempt to write word value %x to location %x\n"), wordValue, sekAddress);

		}
	}
示例#19
0
int twinhawkFrame()
{
	if (drvReset) {	// Reset machine
		drvDoReset();
	}

	twinhawkInpMake();

	int nInterleave =10;

	SekNewFrame();

	SekOpen(0);
	ZetOpen(0);
	nCyclesTotal[0] = 8000000/60;
	nCyclesTotal[1] = 4000000/60;
	rCyclesDone[0] = rCyclesDone[1] = 0;

	int nSoundBufferPos = 0;

	for (int i = 0; i < nInterleave; i++) {
    	int nCurrentCPU;
		int nNext;
		// Run 68000
		nCurrentCPU = 0;
		nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave;

		nCyclesSegment = nNext - rCyclesDone[nCurrentCPU];
		rCyclesDone[nCurrentCPU] += SekRun(nCyclesSegment);
		// Run Z80
		nCurrentCPU = 1;

		nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave;
		nCyclesSegment = nNext - rCyclesDone[nCurrentCPU];

		nCyclesSegment = ZetRun(nCyclesSegment);
		rCyclesDone[nCurrentCPU] += nCyclesSegment;
		{
			// Render sound segment
			if (pBurnSoundOut) {
				int nSegmentLength = nBurnSoundLen / nInterleave;
				short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
				BurnYM2151Render(pSoundBuf, nSegmentLength);
				nSoundBufferPos += nSegmentLength;
			}
		}
	}

	{
		// Make sure the buffer is entirely filled.
		if (pBurnSoundOut) {
			int nSegmentLength = nBurnSoundLen - nSoundBufferPos;
			short* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
			if (nSegmentLength) {
				BurnYM2151Render(pSoundBuf, nSegmentLength);
			}
		}
	}
	SekSetIRQLine(2, SEK_IRQSTATUS_AUTO);
	ZetClose();
	SekClose();

	if (pBurnDraw) {
		twinhawkDraw();														// Draw screen if needed
	}

	return 0;
}
示例#20
0
static INT32 DrvFrame()
{
	INT32 nInterleave = 8;

	if (DrvReset) {														// Reset machine
		DrvDoReset();
	}

	// Compile digital inputs
	DrvInput[0] = 0x00;													// Buttons
	DrvInput[1] = 0x00;													// Player 1
	DrvInput[2] = 0x00;													// Player 2
	for (INT32 i = 0; i < 8; i++) {
		DrvInput[0] |= (DrvJoy1[i] & 1) << i;
		DrvInput[1] |= (DrvJoy2[i] & 1) << i;
		DrvInput[2] |= (DrvButton[i] & 1) << i;
	}
	ToaClearOpposites(&DrvInput[0]);
	ToaClearOpposites(&DrvInput[1]);

	SekNewFrame();

	nCyclesTotal[0] = (INT32)((INT64)16000000 * nBurnCPUSpeedAdjust / (0x0100 * 60));
	nCyclesTotal[1] = TOA_Z80_SPEED / 60;
	nCyclesDone[0] = nCyclesDone[1] = 0;

	SekOpen(0);
	
	SekSetCyclesScanline(nCyclesTotal[0] / 262);
	nToaCyclesDisplayStart = nCyclesTotal[0] - ((nCyclesTotal[0] * (TOA_VBLANK_LINES + 240)) / 262);
	nToaCyclesVBlankStart = nCyclesTotal[0] - ((nCyclesTotal[0] * TOA_VBLANK_LINES) / 262);
	bVBlank = false;

	INT32 nSoundBufferPos = 0;

	ZetOpen(0);
	for (INT32 i = 1; i <= nInterleave; i++) {
    	INT32 nCurrentCPU;
		INT32 nNext;

		// Run 68000

		nCurrentCPU = 0;
		nNext = i * nCyclesTotal[nCurrentCPU] / nInterleave;

		// Trigger VBlank interrupt
		if (!bVBlank && nNext > nToaCyclesVBlankStart) {
			if (nCyclesDone[nCurrentCPU] < nToaCyclesVBlankStart) {
				nCyclesSegment = nToaCyclesVBlankStart - nCyclesDone[nCurrentCPU];
				if (!CheckSleep(nCurrentCPU)) {
					nCyclesDone[nCurrentCPU] += SekRun(nCyclesSegment);
				} else {
					nCyclesDone[nCurrentCPU] += SekIdle(nCyclesSegment);
				}
			}

			nIRQPending = 1;
			SekSetIRQLine(4, CPU_IRQSTATUS_AUTO);

			ToaBufferGP9001Sprites();

			if (pBurnDraw) {
				DrvDraw();												// Draw screen if needed
			}

			bVBlank = true;
		}

		nCyclesSegment = nNext - nCyclesDone[nCurrentCPU];
		if (!CheckSleep(nCurrentCPU)) {									// See if this CPU is busywaiting
			nCyclesDone[nCurrentCPU] += SekRun(nCyclesSegment);
			nIRQPending = 0;
		} else {
			nCyclesDone[nCurrentCPU] += SekIdle(nCyclesSegment);
		}

		if ((i & 1) == 0) {
			// Run Z80
			nCurrentCPU = 1;
			nNext = i * nCyclesTotal[nCurrentCPU] / nInterleave;
			nCyclesSegment = nNext - nCyclesDone[nCurrentCPU];
			nCyclesDone[nCurrentCPU] += ZetRun(nCyclesSegment);

			// Render sound segment
			if (pBurnSoundOut) {
				INT32 nSegmentLength = (nBurnSoundLen * i / nInterleave) - nSoundBufferPos;
				INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
				BurnYM2151Render(pSoundBuf, nSegmentLength);
				MSM6295Render(0, pSoundBuf, nSegmentLength);
				nSoundBufferPos += nSegmentLength;
			}
		}
	}

	SekClose();
	
	{
		// Make sure the buffer is entirely filled.
		if (pBurnSoundOut) {
			INT32 nSegmentLength = nBurnSoundLen - nSoundBufferPos;
			INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
			if (nSegmentLength) {
				BurnYM2151Render(pSoundBuf, nSegmentLength);
				MSM6295Render(0, pSoundBuf, nSegmentLength);
			}
		}
	}
	
	ZetClose();

	return 0;
}