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(); }
static void drvYM2151IRQHandler(int nStatus) { if (nStatus) { ZetSetIRQLine(0xFF, ZET_IRQSTATUS_ACK); ZetRun(0x0800); } else { ZetSetIRQLine(0, ZET_IRQSTATUS_NONE); } }
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; }
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; } }
int PsndZRun(int nWant) { int nDid; if (nWant<=0) { return 0; } nDid=ZetRun(nWant); nNextTimer-=nDid; return nDid; }
void HangonPPI0WritePortC(UINT8 data) { System16ColScroll = ~data & 0x04; System16RowScroll = ~data & 0x02; if (!(data & 0x80)) { ZetNmi(); ZetRun(100); nSystem16CyclesDone[2] += 100; } }
static int drvDoReset() { SekOpen(0); SekReset(); SekClose(); ZetOpen(0); ZetReset(); ZetClose(); ZetRun(4000000/60); BurnYM2151Reset(); return 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); }
static int DrvFrame() { if (DrvReset) { DrvDoReset(); } ZetOpen(0); ZetRun(4000000 / 60); ZetRaiseIrq(0); ZetClose(); if (pBurnDraw) { DrvDraw(); } return 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; } }
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; }
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); } }
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); } }
// 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); }
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); } }
/* 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); } } }
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; }
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); } }
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; }
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; }