int wd2793GetDataRequest(WD2793* wd) { sync(wd); if (((wd->regCommand & 0xF0) == 0xF0) && ((wd->regStatus & ST_BUSY) || wd->dataReady)) { UInt32 pulses = (boardSystemTime() - wd->dataRequsetTime) / (boardFrequency() / 5); if (wd->dataReady) { wd->dataRequest = 1; } if (pulses > 0) { wd->dataReady = 1; } if (pulses > 1) { wd->dataAvailable = 0; wd->sectorOffset = 0; wd->dataRequest = 0; wd->intRequest = 1; wd->regStatus &= ~ST_BUSY; } } if ((wd->regCommand & 0xe0) == 0x80 && (wd->regStatus & ST_BUSY)) { UInt32 pulses = (boardSystemTime() - wd->dataRequsetTime) / (boardFrequency() / 25); if (wd->dataReady) { wd->dataRequest = 1; } if (pulses > 0) { wd->dataReady = 1; } } return wd->dataRequest; }
UInt8 coinDeviceRead(CoinDevice* coinDev) { if(coinDev->time == 0 && inputEventGetState(EC_C)) { coinDev->time = boardSystemTime(); } if (coinDev->time != 0) { if ((boardSystemTime() - coinDev->time) < boardFrequency() * 2 / 10) { return 0; } coinDev->time = 0; } return 1; }
UInt8 moonsoundPeek(Moonsound* moonsound, UInt16 ioPort) { UInt8 result = 0xff; UInt32 systemTime = boardSystemTime(); if (moonsound == NULL) { return 0xff; } if (ioPort < 0xC0) { switch (ioPort & 0x01) { case 1: // read wave register result = moonsound->ymf278->peekRegOPL4(moonsound->opl4latch, systemTime); break; } } else { switch (ioPort & 0x03) { case 0: // read status case 2: result = moonsound->ymf262->peekStatus() | moonsound->ymf278->peekStatus(systemTime); break; case 1: case 3: // read fm register result = moonsound->ymf262->peekReg(moonsound->opl3latch); break; } } return result; }
void wd2793SetDataReg(WD2793* wd, UInt8 value) { sync(wd); wd->regData = value; if ((wd->regCommand & 0xE0) == 0xA0) { wd->sectorBuf[wd->sectorOffset] = value; wd->sectorOffset++; if (wd->dataAvailable) { wd->dataAvailable--; } if (wd->dataAvailable == 0) { int rv = 0; if (wd->drive >= 0) { wd->dataRequsetTime = boardSystemTime(); rv = diskWriteSector(wd->drive, wd->sectorBuf, wd->regSector, wd->diskSide, wd->diskTrack, wd->diskDensity); fdcAudioSetReadWrite(wd->fdcAudio); boardSetFdcActive(); } wd->sectorOffset = 0; wd->dataAvailable = diskGetSectorSize(wd->drive, wd->diskSide, wd->diskTrack, wd->diskDensity); if (!rv || wd->diskTrack != wd->regTrack) { wd->regStatus |= ST_RECORD_NOT_FOUND; wd->intRequest = 1; wd->regStatus &= ~ST_BUSY; return; } wd->regStatus &= ~(ST_BUSY | ST_DATA_REQUEST); if (!(wd->regCommand & FLAG_DDM)) { wd->intRequest = 1; wd->dataRequest = 0; } } } }
void moonsoundWrite(Moonsound* moonsound, UInt16 ioPort, UInt8 value) { UInt32 systemTime = boardSystemTime(); if (ioPort < 0xC0) { switch (ioPort & 0x01) { case 0: // select register moonsound->opl4latch = value; break; case 1: mixerSync(moonsound->mixer); moonsound->ymf278->writeRegOPL4(moonsound->opl4latch, value, systemTime); break; } } else { switch (ioPort & 0x03) { case 0: moonsound->opl3latch = value; break; case 2: // select register bank 1 moonsound->opl3latch = value | 0x100; break; case 1: case 3: // write fm register mixerSync(moonsound->mixer); moonsound->ymf262->writeReg(moonsound->opl3latch, value, systemTime); break; } } }
UInt8 moonsoundRead(Moonsound* moonsound, UInt16 ioPort) { UInt8 result = 0xff; UInt32 systemTime = boardSystemTime(); if (ioPort < 0xC0) { switch (ioPort & 0x01) { case 1: // read wave register mixerSync(moonsound->mixer); result = moonsound->ymf278->readRegOPL4(moonsound->opl4latch, systemTime); break; } } else { switch (ioPort & 0x03) { case 0: // read status case 2: mixerSync(moonsound->mixer); result = moonsound->ymf262->readStatus() | moonsound->ymf278->readStatus(systemTime); break; case 1: case 3: // read fm register mixerSync(moonsound->mixer); result = moonsound->ymf262->readReg(moonsound->opl3latch); break; } } return result; }
static void wd2793ReadSector(WD2793* wd) { DSKE rv = 0; int sectorSize = 0; if (wd->drive >= 0) { rv = diskReadSector(wd->drive, wd->sectorBuf, wd->regSector, wd->diskSide, wd->diskTrack, wd->diskDensity, §orSize); fdcAudioSetReadWrite(wd->fdcAudio); boardSetFdcActive(); } if (rv == DSKE_NO_DATA || wd->diskTrack != wd->regTrack) { wd->regStatus |= ST_RECORD_NOT_FOUND; wd->intRequest = 1; wd->regStatus &= ~ST_BUSY; } else { if (rv == DSKE_CRC_ERROR) { wd->regStatus |= ST_CRC_ERROR; } wd->sectorOffset = 0; wd->dataRequest = 0; wd->dataReady = 0; wd->dataRequsetTime = boardSystemTime(); wd->dataAvailable = sectorSize; } }
void boardCaptureInit() { cap.timer = boardTimerCreate(boardTimerCb, NULL); if (cap.state == CAPTURE_REC) { boardTimerAdd(cap.timer, boardSystemTime() + 1); } }
static void onRecv(YM2148* midi, UInt32 time) { midi->timeRecv = 0; if (midi->status & STAT_RXRDY) { midi->status |= STAT_OE; if (midi->command & CMD_RSTER) { ym2148Reset(midi); return; } } if (midi->rxPending != 0) { archSemaphoreWait(midi->semaphore, -1); midi->rxData = midi->rxQueue[(midi->rxHead - midi->rxPending) & (RX_QUEUE_SIZE - 1)]; midi->rxPending--; archSemaphoreSignal(midi->semaphore); midi->status |= STAT_RXRDY; if (midi->command & CMD_RDINT) { boardSetDataBus(midi->vector, 0, 0); boardSetInt(0x800); midi->status |= ST_INT; } } midi->timeRecv = boardSystemTime() + midi->charTime; boardTimerAdd(midi->timerRecv, midi->timeRecv); }
void moonsoundGetDebugInfo(Moonsound* moonsound, DbgDevice* dbgDevice) { UInt32 systemTime = boardSystemTime(); DbgRegisterBank* regBank; int r; // Add YMF262 registers int c = 1; for (r = 0; r < sizeof(regsAvailYMF262); r++) { c += regsAvailYMF262[r]; } regBank = dbgDeviceAddRegisterBank(dbgDevice, langDbgRegsYmf262(), c); c = 0; dbgRegisterBankAddRegister(regBank, c++, "SR", 8, moonsound->ymf262->peekStatus()); for (r = 0; r < sizeof(regsAvailYMF262); r++) { if (regsAvailYMF262[r]) { if (r <= 8) { dbgRegisterBankAddRegister(regBank, c++, regText(r), 8, moonsound->ymf262->peekReg(r|0x100)); } else { dbgRegisterBankAddRegister(regBank, c++, regText(r), 8, moonsound->ymf262->peekReg(r)); } } } // Add YMF278 registers c = 1 + 7 + 2 + 10 * 10; regBank = dbgDeviceAddRegisterBank(dbgDevice, langDbgRegsYmf278(), c); c = 0; dbgRegisterBankAddRegister(regBank, c++, "SR", 8, moonsound->ymf278->peekStatus(systemTime)); r=0x00; dbgRegisterBankAddRegister(regBank, c++, regText(r), 8, moonsound->ymf278->peekRegOPL4(r, systemTime)); r=0x01; dbgRegisterBankAddRegister(regBank, c++, regText(r), 8, moonsound->ymf278->peekRegOPL4(r, systemTime)); r=0x02; dbgRegisterBankAddRegister(regBank, c++, regText(r), 8, moonsound->ymf278->peekRegOPL4(r, systemTime)); r=0x03; dbgRegisterBankAddRegister(regBank, c++, regText(r), 8, moonsound->ymf278->peekRegOPL4(r, systemTime)); r=0x04; dbgRegisterBankAddRegister(regBank, c++, regText(r), 8, moonsound->ymf278->peekRegOPL4(r, systemTime)); r=0x05; dbgRegisterBankAddRegister(regBank, c++, regText(r), 8, moonsound->ymf278->peekRegOPL4(r, systemTime)); r=0x06; dbgRegisterBankAddRegister(regBank, c++, regText(r), 8, moonsound->ymf278->peekRegOPL4(r, systemTime)); r=0xf8; dbgRegisterBankAddRegister(regBank, c++, regText(r), 8, moonsound->ymf278->peekRegOPL4(r, systemTime)); r=0xf9; dbgRegisterBankAddRegister(regBank, c++, regText(r), 8, moonsound->ymf278->peekRegOPL4(r, systemTime)); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { int r = 8 + i * 24 + j; dbgRegisterBankAddRegister(regBank, c++, slotRegText(i,j), 8, moonsound->ymf278->peekRegOPL4(r, systemTime)); } } dbgDeviceAddMemoryBlock(dbgDevice, langDbgMemYmf278(), 0, 0, moonsound->ymf278->getRamSize(), (UInt8*)moonsound->ymf278->getRam()); }
Y8950Adpcm::Y8950Adpcm(Y8950& y8950_, const string& name_, int sampleRam) : y8950(y8950_), name(name_ + " RAM"), ramSize(sampleRam), volume(0) { ramBank = new byte[ramSize]; memset(ramBank, 0xFF, ramSize); sysTime = oldTime = boardSystemTime(); unschedule(oldTime); // Debugger::instance().registerDebuggable(name, *this); }
void moonsoundReset(Moonsound* moonsound) { UInt32 systemTime = boardSystemTime(); moonsound->timerStarted1 = (UInt32)-1; moonsound->timerStarted2 = (UInt32)-1; moonsound->ymf262->reset(systemTime); moonsound->ymf278->reset(systemTime); moonsoundTimerStart(moonsound, 1, 0, moonsound->timerRef1); moonsoundTimerStart(moonsound, 4, 0, moonsound->timerRef2); }
static UInt8 getTimerCounter(RomMapperTurboRPcm* rm) { UInt64 elapsed; UInt32 systemTime = boardSystemTime(); elapsed = 15750 * (UInt64)(systemTime - rm->refTime) + rm->refFrag; rm->refTime = systemTime; rm->refFrag = (UInt32)(elapsed % boardFrequency()); rm->time += (UInt8)(elapsed / boardFrequency()); return rm->time & 0x03; }
void ym2151TimerStart(void* ptr, int timer, int start) { YM2151* ym2151 = (YM2151*)ptr; if (timer == 0) { if (start != 0) { if (!ym2151->timerRunning1) { UInt32 systemTime = boardSystemTime(); UInt32 adjust = systemTime % TIMER_FREQUENCY; ym2151->timeout1 = systemTime + TIMER_FREQUENCY * ym2151->timerValue1 - adjust; boardTimerAdd(ym2151->timer1, ym2151->timeout1); ym2151->timerRunning1 = 1; } } else { if (ym2151->timerRunning1) { boardTimerRemove(ym2151->timer1); ym2151->timerRunning1 = 0; } } } else { if (start != 0) { if (!ym2151->timerRunning2) { UInt32 systemTime = boardSystemTime(); UInt32 adjust = systemTime % (16 * TIMER_FREQUENCY); ym2151->timeout2 = systemTime + TIMER_FREQUENCY * ym2151->timerValue2 - adjust; boardTimerAdd(ym2151->timer2, ym2151->timeout2); ym2151->timerRunning2 = 1; } } else { if (ym2151->timerRunning2) { boardTimerRemove(ym2151->timer2); ym2151->timerRunning2 = 0; } } } }
static UInt16 counterGetElapsedTime(Counter* counter) { UInt64 elapsed; UInt32 elapsedTime; UInt32 systemTime = boardSystemTime(); elapsed = counter->frequency * (UInt64)(systemTime - counter->refTime) + counter->refFrag; counter->refTime = systemTime; counter->refFrag = (UInt32)(elapsed % boardFrequency()); elapsedTime = (UInt32)(elapsed / boardFrequency()); return (UInt16)elapsedTime; }
static YM2148* ym2148Create() { YM2148* midi = (YM2148*)calloc(1, sizeof(YM2148)); midi->midiIo = midiIoCreate(midiInCallback, midi); midi->semaphore = archSemaphoreCreate(1); midi->timerRecv = boardTimerCreate(onRecv, midi); midi->timerTrans = boardTimerCreate(onTrans, midi); midi->timeRecv = boardSystemTime() + midi->charTime; boardTimerAdd(midi->timerRecv, midi->timeRecv); return midi; }
void philipsMidiReset(PhilipsMidi* midi) { midi->status = STAT_TXEMPTY; midi->txPending = 0; midi->rxPending = 0; midi->command = 0; midi->timeRecv = 0; midi->timeTrans = 0; midi->charTime = 10 * boardFrequency() / 31250; boardTimerRemove(midi->timerRecv); boardTimerRemove(midi->timerTrans); midi->timeRecv = boardSystemTime() + midi->charTime; boardTimerAdd(midi->timerRecv, midi->timeRecv); }
void philipsMidiWriteData(PhilipsMidi* midi, UInt8 value) { if (!(midi->status & STAT_TXEMPTY)) { return; } if (midi->txPending == 0) { midiIoTransmit(midi->midiIo, value); midi->timeTrans = boardSystemTime() + midi->charTime; boardTimerAdd(midi->timerTrans, midi->timeTrans); midi->txPending = 1; } else { midi->status &= ~STAT_TXEMPTY; midi->txBuffer = value; } }
static void ym2148WriteData(YM2148* midi, UInt8 value) { if (!(midi->command & CMD_TXEN)) { return; } if (midi->status & STAT_TXEMPTY) { midi->status &= ~STAT_TXEMPTY; midi->sendByte = value; midi->timeTrans = boardSystemTime() + midi->charTime; boardTimerAdd(midi->timerTrans, midi->timeTrans); } else { midi->sendBuffer = value; midi->status &= ~STAT_TXRDY; } }
UInt8 wd2793PeekStatusReg(WD2793* wd) { UInt8 regStatus; sync(wd); regStatus = wd->regStatus; if (((wd->regCommand & 0x80) == 0) || ((wd->regCommand & 0xf0) == 0xd0)) { regStatus &= ~(ST_INDEX | ST_TRACK00 | ST_HEAD_LOADED | ST_WRITE_PROTECTED); if (diskEnabled(wd->drive)) { if (diskPresent(wd->drive)) { if ((UInt64)160 * boardSystemTime() / boardFrequency() & 0x1e) { regStatus |= ST_INDEX; } } if (wd->diskTrack == 0) { regStatus |= ST_TRACK00; } if (wd->headLoaded) { regStatus |= ST_HEAD_LOADED; } } else { regStatus |= ST_WRITE_PROTECTED; } } else { if (wd2793PeekDataRequest(wd)) { regStatus |= ST_DATA_REQUEST; } else { regStatus &= ~ST_DATA_REQUEST; } } if (diskPresent(wd->drive)) { regStatus &= ~ST_NOT_READY; } else { regStatus |= ST_NOT_READY; } return regStatus; }
static void reset() { UInt32 systemTime = boardSystemTime(); slotManagerReset(); if (r800 != NULL) { r800Reset(r800, systemTime); } if (sn76489 != NULL) { sn76489Reset(sn76489); } ledSetCapslock(0); deviceManagerReset(); }
void rtcLoadState(RTC* rtc) { SaveState* state = saveStateOpenForRead("rtc"); rtc->refTime = saveStateGet(state, "refTime", boardSystemTime()); rtc->refFrag = saveStateGet(state, "refFrag", 0); rtc->fraction = saveStateGet(state, "fraction", 0); rtc->seconds = saveStateGet(state, "seconds", 0); rtc->minutes = saveStateGet(state, "minutes", 0); rtc->hours = saveStateGet(state, "hours", 0); rtc->dayWeek = saveStateGet(state, "dayWeek", 0); rtc->days = saveStateGet(state, "days", 0); rtc->months = saveStateGet(state, "months", 0); rtc->years = saveStateGet(state, "years", 0); rtc->leapYear = saveStateGet(state, "leapYear", 0); rtc->latch = (UInt8) saveStateGet(state, "latch", 0); saveStateClose(state); }
static void onTrans(PhilipsMidi* midi, UInt32 time) { midi->timeTrans = 0; if (midi->status & STAT_TXEMPTY) { midi->txPending = 0; } else { midiIoTransmit(midi->midiIo, midi->txBuffer); midi->timeTrans = boardSystemTime() + midi->charTime; boardTimerAdd(midi->timerTrans, midi->timeTrans); midi->status |= STAT_TXEMPTY; if (midi->command & CMD_WRINT) { boardSetInt(0x400); midi->status |= ST_INT; } } }
static void reset() { UInt32 systemTime = boardSystemTime(); slotManagerReset(); if (r800 != NULL) { r800Reset(r800, systemTime); } if (ay8910 != NULL) { ay8910Reset(ay8910); } sviMemSetBank(0xDF); ledSetCapslock(0); deviceManagerReset(); }
static void commandType1(WD2793* wd) { wd->regStatus &= ~(ST_SEEK_ERROR | ST_CRC_ERROR); wd->headLoaded = wd->regCommand & FLAG_HLD; wd->regStatus |= ST_BUSY; wd->dataRequest = 0; switch (wd->regCommand >> 4) { case CMD_RESTORE: wd->regTrack = 0xff; wd->regData = 0x00; wd->stepDirection = -1; break; case CMD_SEEK: if (wd->regTrack == wd->regData) { wd->intRequest = 1; wd->regStatus &= ~ST_BUSY; return; } wd->stepDirection = wd->regTrack > wd->regData ? -1 : 1; break; case CMD_STEP1: case CMD_STEP2: break; case CMD_STEP_IN1: case CMD_STEP_IN2: wd->stepDirection = 1; break; case CMD_STEP_OUT1: case CMD_STEP_OUT2: wd->stepDirection = -1; break; } wd->step = 1; wd->curStep = 0; wd->stepTime = boardSystemTime(); }
static void sync(WD2793* wd) { if (wd->step) { const UInt64 timePerStep[4] = { 200, 100, 66, 50 }; UInt32 steps = (UInt32)(timePerStep[wd->regCommand & 3] * (boardSystemTime() - wd->stepTime) / boardFrequency()); while (wd->curStep < steps) { wd->curStep++; if ((wd->regCommand & 0x10) || ((wd->regCommand & 0xe0) == 0x00)) { wd->regTrack += wd->stepDirection; } if (diskEnabled(wd->drive) && ((wd->stepDirection == -1 && wd->diskTrack > 0) || wd->stepDirection == 1)) { wd->diskTrack += wd->stepDirection; } if (wd->regCommand & 0xe0) { wd->intRequest = 1; wd->regStatus &= ~ST_BUSY; wd->step = 0; break; } if (wd->stepDirection == -1 && diskEnabled(wd->drive) && wd->diskTrack == 0) { wd->regTrack = 0; wd->intRequest = 1; wd->regStatus &= ~ST_BUSY; wd->step = 0; break; } if (wd->regTrack == wd->regData) { wd->intRequest = 1; wd->regStatus &= ~ST_BUSY; wd->step = 0; break; } } } }
static void onRecv(PhilipsMidi* midi, UInt32 time) { midi->timeRecv = 0; if (midi->status & STAT_RXRDY) { midi->status |= STAT_OE; } else if (midi->rxPending != 0) { archSemaphoreWait(midi->semaphore, -1); midi->rxData = midi->rxQueue[(midi->rxHead - midi->rxPending) & (RX_QUEUE_SIZE - 1)]; midi->rxPending--; archSemaphoreSignal(midi->semaphore); midi->status |= STAT_RXRDY; if (midi->command & CMD_RDINT) { boardSetInt(0x400); midi->status |= ST_INT; } } midi->timeRecv = boardSystemTime() + midi->charTime; boardTimerAdd(midi->timerRecv, midi->timeRecv); }
static void onTrans(YM2148* midi, UInt32 time) { midi->timeTrans = 0; midiIoTransmit(midi->midiIo, midi->sendByte); if (midi->status & STAT_TXRDY) { midi->status |= STAT_TXEMPTY; if (midi->command & CMD_TXINT) { boardSetDataBus(midi->vector, 0, 0); boardSetInt(0x800); midi->status |= ST_INT; } } else { midi->status |= STAT_TXRDY; midi->status &= ~STAT_TXEMPTY; midi->sendByte = midi->sendBuffer; midi->timeTrans = boardSystemTime() + midi->charTime; boardTimerAdd(midi->timerTrans, midi->timeTrans); } }
static void counterSetTimeout(Counter* counter) { int nextTimeout = 0; int mode = counter->mode; // If counter is disabled, just return if (mode != 1 && mode != 5 && counter->gate == 0) { return; } if (counter->outPhase == 1) { nextTimeout = counter->countingElement - counter->endOutPhase1; } else if (counter->outPhase == 2) { nextTimeout = counter->countingElement - counter->endOutPhase2; } if (nextTimeout != 0) { counter->time = boardSystemTime() + (UInt64)boardFrequency() * nextTimeout / counter->frequency; boardTimerAdd(counter->timer, counter->time); } }
int wd2793PeekDataRequest(WD2793* wd) { int dataRequest = wd->dataRequest; if (((wd->regCommand & 0xF0) == 0xF0) && ((wd->regStatus & ST_BUSY) || wd->dataReady)) { UInt32 pulses = (boardSystemTime() - wd->dataRequsetTime) / (boardFrequency() / 5); if (wd->dataReady) { dataRequest = 1; } if (pulses > 1) { dataRequest = 0; } } if ((wd->regCommand & 0xe0) == 0x80 && (wd->regStatus & ST_BUSY)) { // UInt32 pulses = (boardSystemTime() - wd->dataRequsetTime) / (boardFrequency() / 25); if (wd->dataReady) { dataRequest = 1; } } return dataRequest; }