void ay8910_write_ym(void *chip, int addr, int data) { struct AY8910 *PSG = chip; if (addr & 1) { /* Data port */ int r = PSG->register_latch; if (r > 15) return; if (r < 14) { if (r == AY_ESHAPE || PSG->Regs[r] != data) { /* update the output buffer before changing the register */ stream_update(PSG->Channel); } } _AYWriteReg(PSG,r,data); } else { /* Register port */ PSG->register_latch = data & 0x0f; } }
//////////////////////////////////////////////////////////////// // リセット //////////////////////////////////////////////////////////////// void cAY8910::Reset( void ) { PRINTD( PSG_LOG, "[PSG][Reset]\n" ); RegisterLatch = 0; RNG = 1; OutputA = 0; OutputB = 0; OutputC = 0; OutputN = 0xff; LastEnable = -1; for( int i=0; i<AY_PORTA; i++ ) _AYWriteReg( i, 0 ); }
/* write a register on AY8910 chip number 'n' */ static void AYWriteReg(INT32 chip, INT32 r, INT32 v) { if (r > 15) return; if (r < 14) { struct AY8910 *PSG = &AYPSG[chip]; if (r == AY_ESHAPE || PSG->Regs[r] != v) { // /* update the output buffer before changing the register */ // stream_update(PSG->Channel,0); AYStreamUpdate(); } } _AYWriteReg(chip,r,v); }
// レジスタ書込みメイン void cAY8910::AYWriteReg( BYTE addr, BYTE v ) { if( addr & 1 ) { // Data port PRINTD( PSG_LOG, "[PSG][AYWriteReg] Data -> %02X, %02X\n", RegisterLatch, v ); if( RegisterLatch > 15 ) return; if( RegisterLatch == AY_ESHAPE || Regs[RegisterLatch] != v ) { // レジスタを変更する前にストリームを更新する PreWriteReg(); } _AYWriteReg( RegisterLatch, v ); } else { // Register port PRINTD( PSG_LOG, "[PSG][AYWriteReg] Latch -> Reg:%02X\n", v ); RegisterLatch = v & 0x0f; } }
/* write a register on AY8910 chip number 'n' */ void AYWriteReg(int chip, int r, int v) { struct AY8910 *PSG = &AYPSG[chip]; if (r > 15) return; if (r < 14) { if (r == AY_ESHAPE || PSG->Regs[r] != v) { /* update the output buffer before changing the register */ stream_update(PSG->Channel,0); } } _AYWriteReg(chip,r,v); }
void AY8910_reset(int chip) { int i; struct AY8910 *PSG = &AYPSG[chip]; PSG->register_latch = 0; PSG->RNG = 1; PSG->OutputA = 0; PSG->OutputB = 0; PSG->OutputC = 0; PSG->OutputN = 0xff; PSG->lastEnable = -1; /* force a write */ for (i = 0;i < AY_PORTA;i++) _AYWriteReg(chip,i,0); /* AYWriteReg() uses the timer system; we cannot */ /* call it at this time because the timer system */ /* has not been initialized. */ }
void AY8910_reset(void) { int i; struct AY8910 *PSG = &AYPSG; PSG->register_latch = 0; PSG->RNG = 1; PSG->OutputA = 0; PSG->OutputB = 0; PSG->OutputC = 0; PSG->OutputN = 0xff; for (i = 0; i < AY_PORTA; i++) _AYWriteReg(i, 0); /* AYWriteReg() uses the timer system; we cannot */ /* call it at this time because the timer system */ /* has not been initialized. */ }
void ay8910_reset_ym(void *chip) { struct AY8910 *PSG = chip; int i; PSG->register_latch = 0; PSG->RNG = 1; PSG->OutputA = 0; PSG->OutputB = 0; PSG->OutputC = 0; PSG->OutputN = 0xff; PSG->lastEnable = -1; /* force a write */ for (i = 0;i < AY_PORTA;i++) _AYWriteReg(PSG,i,0); /* AYWriteReg() uses the timer system; we cannot */ /* call it at this time because the timer system */ /* has not been initialized. */ PSG->ready = 1; }
static void AY8910_Write(BYTE nDevice, BYTE nReg, BYTE nValue, BYTE nAYDevice) { g_bMB_RegAccessedFlag = true; SY6522_AY8910* pMB = &g_MB[nDevice]; if((nValue & 4) == 0) { // RESET: Reset AY8910 only AY8910_reset(nDevice+2*nAYDevice); } else { // Determine the AY8910 inputs int nBDIR = (nValue & 2) ? 1 : 0; const int nBC2 = 1; // Hardwired to +5V int nBC1 = nValue & 1; int nAYFunc = (nBDIR<<2) | (nBC2<<1) | nBC1; enum {AY_NOP0, AY_NOP1, AY_INACTIVE, AY_READ, AY_NOP4, AY_NOP5, AY_WRITE, AY_LATCH}; switch(nAYFunc) { case AY_INACTIVE: // 4: INACTIVE break; case AY_READ: // 5: READ FROM PSG (need to set DDRA to input) break; case AY_WRITE: // 6: WRITE TO PSG _AYWriteReg(nDevice+2*nAYDevice, pMB->nAYCurrentRegister, pMB->sy6522.ORA); break; case AY_LATCH: // 7: LATCH ADDRESS // http://www.worldofspectrum.org/forums/showthread.php?t=23327 // Selecting an unused register number above 0x0f puts the AY into a state where // any values written to the data/address bus are ignored, but can be read back // within a few tens of thousands of cycles before they decay to zero. if(pMB->sy6522.ORA <= 0x0F) pMB->nAYCurrentRegister = pMB->sy6522.ORA & 0x0F; // else Pro-Mockingboard (clone from HK) break; } } }
static void AY8910_Write(BYTE nDevice, BYTE nReg, BYTE nValue, BYTE nAYDevice) { SY6522_AY8910* pMB = &g_MB[nDevice]; if((nValue & 4) == 0) { // RESET: Reset AY8910 only AY8910_reset(nDevice+2*nAYDevice); } else { // Determine the AY8910 inputs int nBDIR = (nValue & 2) ? 1 : 0; const int nBC2 = 1; // Hardwired to +5V int nBC1 = nValue & 1; int nAYFunc = (nBDIR<<2) | (nBC2<<1) | nBC1; enum {AY_NOP0, AY_NOP1, AY_INACTIVE, AY_READ, AY_NOP4, AY_NOP5, AY_WRITE, AY_LATCH}; switch(nAYFunc) { case AY_INACTIVE: // 4: INACTIVE break; case AY_READ: // 5: READ FROM PSG (need to set DDRA to input) break; case AY_WRITE: // 6: WRITE TO PSG _AYWriteReg(nDevice+2*nAYDevice, pMB->nAYCurrentRegister, pMB->sy6522.ORA); break; case AY_LATCH: // 7: LATCH ADDRESS if(pMB->sy6522.ORA <= 0x0F) pMB->nAYCurrentRegister = pMB->sy6522.ORA & 0x0F; // else Pro-Mockingboard (clone from HK) break; } } }
void AY8910Reset(INT32 chip) { INT32 i; struct AY8910 *PSG = &AYPSG[chip]; #if defined FBA_DEBUG #ifdef __GNUC__ if (!DebugSnd_AY8910Initted) bprintf(PRINT_ERROR, _T("AY8910Reset called without init\n")); if (chip > num) bprintf(PRINT_ERROR, _T("AY8910Reset called with invalid chip number %x\n"), chip); #endif #endif PSG->register_latch = 0; PSG->RNG = 1; PSG->OutputA = 0; PSG->OutputB = 0; PSG->OutputC = 0; PSG->OutputN = 0xff; PSG->lastEnable = -1; /* force a write */ for (i = 0;i < AY_PORTA;i++) _AYWriteReg(chip,i,0); /* AYWriteReg() uses the timer system; we cannot */ /* call it at this time because the timer system */ /* has not been initialized. */ }
/* write a register on the AY8910 chip */ void AYWriteReg(int r, int v) { if (r > 15) return; _AYWriteReg(r, v); }