void OPL_WriteRegister(int reg, int value) { int i; OPL_WritePort(OPL_REGISTER_PORT, reg); // For timing, read the register port six times after writing the // register number to cause the appropriate delay for (i=0; i<6; ++i) { // An oddity of the Doom OPL code: at startup initialization, // the spacing here is performed by reading from the register // port; after initialization, the data port is read, instead. if (init_stage_reg_writes) { OPL_ReadPort(OPL_REGISTER_PORT); } else { OPL_ReadPort(OPL_DATA_PORT); } } OPL_WritePort(OPL_DATA_PORT, value); // Read the register port 24 times after writing the value to // cause the appropriate delay for (i=0; i<24; ++i) { OPL_ReadStatus(); } }
void WriteReg(unsigned int reg, unsigned int val) { int i; // This was recorded from an OPL2, but we are probably playing // back on an OPL3, so we need to enable the original OPL2 // channels. Doom does this already, but other games don't. if ((reg & 0xf0) == OPL_REGS_FEEDBACK) { val |= 0x30; } OPL_WritePort(OPL_REGISTER_PORT, reg); for (i=0; i<6; ++i) { OPL_ReadPort(OPL_REGISTER_PORT); } OPL_WritePort(OPL_DATA_PORT, val); for (i=0; i<35; ++i) { OPL_ReadPort(OPL_REGISTER_PORT); } }
unsigned int OPL_ReadStatus(void) { return OPL_ReadPort(OPL_REGISTER_PORT); }