public void refresh() { for (int i = 0; i < MAX_CHIPS; i++) { DACData[i] = new dac_control(); } }
public void device_reset_daccontrol(byte ChipID) { dac_control chip = DACData[ChipID]; chip.DstChipType = 0x00; chip.DstChipID = 0x00; chip.DstCommand = 0x00; chip.CmdSize = 0x00; chip.Frequency = 0; chip.DataLen = 0x00; chip.Data = null; chip.DataStart = 0x00; chip.StepSize = 0x00; chip.StepBase = 0x00; chip.Running = 0x00; chip.Reverse = 0x00; chip.Step = 0x00; chip.Pos = 0x00; chip.RealPos = 0x00; chip.RemainCmds = 0x00; chip.DataStep = 0x00; return; }
public void set_data(byte ChipID, byte[] Data, uint DataLen, byte StepSize, byte StepBase) { dac_control chip = DACData[ChipID]; if ((chip.Running & 0x80) > 0) { return; } if (DataLen > 0 && Data != null) { chip.DataLen = DataLen; chip.Data = Data; } else { chip.DataLen = 0x00; chip.Data = null; } chip.StepSize = (byte)(StepSize > 0 ? StepSize : 1); chip.StepBase = StepBase; chip.DataStep = (byte)(chip.CmdSize * chip.StepSize); return; }
public void device_stop_daccontrol(byte ChipID) { dac_control chip = DACData[ChipID]; chip.Running = 0xFF; return; }
public void device_stop_daccontrol(byte ChipID) { lock (lockObj) { dac_control chip = DACData[ChipID]; chip.Running = 0xFF; } }
public void setup_chipZGM(byte StreamID, int ChipID, uint Command) { dac_control chip = DACData[StreamID]; byte ChType = 0x2; byte ChNum = 0x0; foreach (Driver.ZGM.ZgmChip.ZgmChip zchip in driver.chips) { if (zchip.defineInfo.commandNo != ChipID) { continue; } if (zchip is Driver.ZGM.ZgmChip.YM2612) { ChType = 0x2; } ChNum = (byte)zchip.Index; break; } chip.DstChipType = ChType; // TypeID (e.g. 0x02 for YM2612) chip.DstChipID = ChNum; // chip number (to send commands to 1st or 2nd chip) chip.DstCommand = Command; // Port and Command (would be 0x02A for YM2612) switch (chip.DstChipType) { case 0x00: // SN76496 if ((chip.DstCommand & 0x0010) > 0) { chip.CmdSize = 0x01; // Volume Write } else { chip.CmdSize = 0x02; // Frequency Write } break; case 0x02: // YM2612 chip.CmdSize = 0x01; break; case 0x11: // PWM case 0x1F: // QSound chip.CmdSize = 0x02; break; default: chip.CmdSize = 0x01; break; } chip.DataStep = (byte)(chip.CmdSize * chip.StepSize); return; }
public void stop(byte ChipID) { dac_control chip = DACData[ChipID]; if ((chip.Running & 0x80) > 0) { return; } chip.Running &= 0xfe;// ~0x01; // stop return; }
public void set_frequency(byte ChipID, uint Frequency) { //System.Console.WriteLine("ChipID{0} Frequency{1}", ChipID, Frequency); dac_control chip = DACData[ChipID]; if ((chip.Running & 0x80) > 0) { return; } chip.Frequency = Frequency; return; }
private void stop(byte ChipID) { lock (lockObj) { dac_control chip = DACData[ChipID]; if ((chip.Running & 0x80) != 0) { return; } chip.Running &= 0xfe;// ~0x01; // stop } }
private void setup_chip(byte ChipID, byte ChType, byte EmuType, byte ChipIndex, byte ChNum, uint Command) { lock (lockObj) { dac_control chip = DACData[ChipID]; chip.DstChipType = ChType; // TypeID (e.g. 0x02 for YM2612) chip.DstEmuType = EmuType; chip.DstChipIndex = ChipIndex; chip.DstChipID = ChNum; // chip number (to send commands to 1st or 2nd chip) chip.DstCommand = Command; // Port and Command (would be 0x02A for YM2612) switch (chip.DstChipType) { case 0x00: // SN76496 if ((chip.DstCommand & 0x0010) > 0) { chip.CmdSize = 0x01; // Volume Write } else { chip.CmdSize = 0x02; // Frequency Write } break; case 0x02: // YM2612 chip.CmdSize = 0x01; break; case 0x11: // PWM case 0x1F: // QSound chip.CmdSize = 0x02; break; default: chip.CmdSize = 0x01; break; } chip.DataStep = (byte)(chip.CmdSize * chip.StepSize); } }
private void set_frequency(byte ChipID, uint Frequency) { lock (lockObj) { //System.Console.WriteLine("ChipID{0} Frequency{1}", ChipID, Frequency); dac_control chip = DACData[ChipID]; if ((chip.Running & 0x80) != 0) { return; } if (Frequency != 0) { chip.Step = chip.Step * chip.Frequency / Frequency; } chip.Frequency = Frequency; return; } }
public void refresh_data(byte ChipID, byte[] Data, uint DataLen) { // Should be called to fix the data pointer. (e.g. after a realloc) dac_control chip = DACData[ChipID]; if ((chip.Running & 0x80) > 0) { return; } if (DataLen > 0 && Data != null) { chip.DataLen = DataLen; chip.Data = Data; } else { chip.DataLen = 0x00; chip.Data = null; } return; }
public void start(byte ChipID, uint DataPos, byte LenMode, uint Length, outDatum od) { dac_control chip = DACData[ChipID]; chip.od = od; uint CmdStepBase; if ((chip.Running & 0x80) > 0) { return; } CmdStepBase = (uint)(chip.CmdSize * chip.StepBase); if (DataPos != 0xFFFFFFFF) // skip setting DataStart, if Pos == -1 { chip.DataStart = DataPos + CmdStepBase; if (chip.DataStart > chip.DataLen) // catch bad value and force silence { chip.DataStart = chip.DataLen; } } switch (LenMode & 0x0F) { case DCTRL_LMODE_IGNORE: // Length is already set - ignore break; case DCTRL_LMODE_CMDS: // Length = number of commands chip.CmdsToSend = Length; break; case DCTRL_LMODE_MSEC: // Length = time in msec chip.CmdsToSend = 1000 * Length / chip.Frequency; break; case DCTRL_LMODE_TOEND: // play unti stop-command is received (or data-end is reached) chip.CmdsToSend = (chip.DataLen - (chip.DataStart - CmdStepBase)) / chip.DataStep; break; case DCTRL_LMODE_BYTES: // raw byte count chip.CmdsToSend = Length / chip.DataStep; break; default: chip.CmdsToSend = 0x00; break; } chip.Reverse = (byte)((LenMode & 0x10) >> 4); chip.RemainCmds = chip.CmdsToSend; chip.Step = 0x00; chip.Pos = 0x00; if (chip.Reverse == 0) { chip.RealPos = 0x00; } else { chip.RealPos = (chip.CmdsToSend - 0x01) * chip.DataStep; } chip.Running &= 0xfb; // ~0x04; chip.Running |= (byte)((LenMode & 0x80) > 0 ? 0x04 : 0x00); // set loop mode chip.Running |= 0x01; // start chip.Running &= 0xef; // ~0x10; // command isn't yet sent return; }
public void sendCommand(long Counter, dac_control chip) { byte Port; byte Command; byte Data; outDatum od; if ((chip.Running & 0x10) > 0) // command already sent { return; } if (chip.DataStart + chip.RealPos >= chip.DataLen) { return; } //if (! chip->Reverse) //ChipData00 = chip.Data[(chip.DataStart + chip.RealPos)]; //ChipData01 = chip.Data[(chip.DataStart + chip.RealPos+1)]; //else // ChipData = chip->Data + (chip->DataStart + chip->CmdsToSend - 1 - chip->Pos); switch (chip.DstChipType) { // Support for the important chips case 0x02: // YM2612 (16-bit Register (actually 9 Bit), 8-bit Data) Port = (byte)((chip.DstCommand & 0xFF00) >> 8); Command = (byte)((chip.DstCommand & 0x00FF) >> 0); Data = chip.Data[(chip.DataStart + chip.RealPos)]; od = null;// chip.od; //if (model == enmModel.RealModel) log.Write(string.Format("{0:x} {1:x}", Data, chip.RealPos)); chip_reg_write(Counter, chip.DstChipType, chip.DstChipID, Port, Command, Data, od); break; case 0x11: // PWM (4-bit Register, 12-bit Data) Port = (byte)((chip.DstCommand & 0x000F) >> 0); Command = (byte)(chip.Data[chip.DataStart + chip.RealPos + 1] & 0x0F); Data = chip.Data[chip.DataStart + chip.RealPos]; od = chip.od; chip_reg_write(Counter, chip.DstChipType, chip.DstChipID, Port, Command, Data, od); break; // Support for other chips (mainly for completeness) case 0x00: // SN76496 (4-bit Register, 4-bit/10-bit Data) Command = (byte)((chip.DstCommand & 0x00F0) >> 0); Data = (byte)(chip.Data[chip.DataStart + chip.RealPos] & 0x0F); od = chip.od; if ((Command & 0x10) > 0) { // Volume Change (4-Bit value) chip_reg_write(Counter, chip.DstChipType, chip.DstChipID, 0x00, 0x00, (byte)(Command | Data), od); } else { // Frequency Write (10-Bit value) Port = (byte)(((chip.Data[chip.DataStart + chip.RealPos + 1] & 0x03) << 4) | ((chip.Data[chip.DataStart + chip.RealPos] & 0xF0) >> 4)); chip_reg_write(Counter, chip.DstChipType, chip.DstChipID, 0x00, 0x00, (byte)(Command | Data), od); chip_reg_write(Counter, chip.DstChipType, chip.DstChipID, 0x00, 0x00, Port, od); } break; case 0x18: // OKIM6295 - TODO: verify Command = (byte)((chip.DstCommand & 0x00FF) >> 0); Data = chip.Data[chip.DataStart + chip.RealPos]; od = chip.od; if (Command == 0) { Port = (byte)((chip.DstCommand & 0x0F00) >> 8); if ((Data & 0x80) > 0) { // Sample Start // write sample ID chip_reg_write(Counter, chip.DstChipType, chip.DstChipID, 0x00, Command, Data, od); // write channel(s) that should play the sample chip_reg_write(Counter, chip.DstChipType, chip.DstChipID, 0x00, Command, (byte)(Port << 4), od); } else { // Sample Stop chip_reg_write(Counter, chip.DstChipType, chip.DstChipID, 0x00, Command, (byte)(Port << 3), od); } } else { chip_reg_write(Counter, chip.DstChipType, chip.DstChipID, 0x00, Command, Data, od); } break; // Generic support: 8-bit Register, 8-bit Data case 0x01: // YM2413 case 0x03: // YM2151 case 0x06: // YM2203 case 0x09: // YM3812 case 0x0A: // YM3526 case 0x0B: // Y8950 case 0x0F: // YMZ280B case 0x12: // AY8910 case 0x13: // GameBoy DMG case 0x14: // NES APU // case 0x15: // MultiPCM case 0x16: // UPD7759 case 0x17: // OKIM6258 case 0x1D: // K053260 - TODO: Verify case 0x1E: // Pokey - TODO: Verify Command = (byte)((chip.DstCommand & 0x00FF) >> 0); Data = chip.Data[chip.DataStart + chip.RealPos]; od = chip.od; chip_reg_write(Counter, chip.DstChipType, chip.DstChipID, 0x00, Command, Data, od); break; // Generic support: 16-bit Register, 8-bit Data case 0x07: // YM2608 case 0x08: // YM2610/B case 0x0C: // YMF262 case 0x0D: // YMF278B case 0x0E: // YMF271 case 0x19: // K051649 - TODO: Verify case 0x1A: // K054539 - TODO: Verify case 0x1C: // C140 - TODO: Verify Port = (byte)((chip.DstCommand & 0xFF00) >> 8); Command = (byte)((chip.DstCommand & 0x00FF) >> 0); Data = chip.Data[chip.DataStart + chip.RealPos]; od = chip.od; chip_reg_write(Counter, chip.DstChipType, chip.DstChipID, Port, Command, Data, od); break; // Generic support: 8-bit Register with Channel Select, 8-bit Data case 0x05: // RF5C68 case 0x10: // RF5C164 case 0x1B: // HuC6280 Port = (byte)((chip.DstCommand & 0xFF00) >> 8); Command = (byte)((chip.DstCommand & 0x00FF) >> 0); Data = chip.Data[chip.DataStart + chip.RealPos]; od = null; //chip.od; if (Port != 0xFF) // Send Channel Select { chip_reg_write(Counter, chip.DstChipType, chip.DstChipID, 0x00, (byte)(Command >> 4), Port, od); } // Send Data chip_reg_write(Counter, chip.DstChipType, chip.DstChipID, 0x00, (byte)(Command & 0x0F), Data, od); break; // Generic support: 8-bit Register, 16-bit Data case 0x1F: // QSound Command = (byte)((chip.DstCommand & 0x00FF) >> 0); od = chip.od; chip_reg_write(Counter, chip.DstChipType, chip.DstChipID, chip.Data[chip.DataStart + chip.RealPos], chip.Data[chip.DataStart + chip.RealPos + 1], Command, od); break; } chip.Running |= 0x10; return; }
public void update(long Counter, byte ChipID, uint samples) { dac_control chip = DACData[ChipID]; uint NewPos; int RealDataStp; //System.Console.WriteLine("DAC update ChipID{0} samples{1} chip.Running{2} ", ChipID, samples, chip.Running); if ((chip.Running & 0x80) != 0) // disabled { return; } if ((chip.Running & 0x01) == 0) // stopped { return; } if (chip.Reverse == 0) { RealDataStp = chip.DataStep; } else { RealDataStp = -chip.DataStep; } if (samples > 0x20) { // very effective Speed Hack for fast seeking NewPos = chip.Step + (samples - 0x10); NewPos = muldiv64round(NewPos * chip.DataStep, chip.Frequency, (UInt32)Common.SampleRate);// DAC_SMPL_RATE); while (chip.RemainCmds > 0 && chip.Pos < NewPos) { chip.Pos += chip.DataStep; chip.RealPos = (uint)((int)chip.RealPos + RealDataStp); chip.RemainCmds--; } } chip.Step += samples; // Formula: Step * Freq / SampleRate NewPos = muldiv64round(chip.Step * chip.DataStep, chip.Frequency, (UInt32)Common.SampleRate);// DAC_SMPL_RATE); //System.Console.Write("NewPos{0} chip.Step{1} chip.DataStep{2} chip.Frequency{3} DAC_SMPL_RATE{4} \n", NewPos, chip.Step, chip.DataStep, chip.Frequency, (UInt32)common.SampleRate); sendCommand(Counter, chip); while (chip.RemainCmds > 0 && chip.Pos < NewPos) { sendCommand(Counter, chip); chip.Pos += chip.DataStep; //if(model== enmModel.RealModel) log.Write(string.Format("datastep:{0}",chip.DataStep)); chip.RealPos = (uint)((int)chip.RealPos + RealDataStp); chip.Running &= 0xef;// ~0x10; chip.RemainCmds--; } if (chip.RemainCmds == 0 && ((chip.Running & 0x04) > 0)) { // loop back to start chip.RemainCmds = chip.CmdsToSend; chip.Step = 0x00; chip.Pos = 0x00; if (chip.Reverse == 0) { chip.RealPos = 0x00; } else { chip.RealPos = (chip.CmdsToSend - 0x01) * chip.DataStep; } } if (chip.RemainCmds == 0) { chip.Running &= 0xfe;// ~0x01; // stop } return; }
private void sendCommand(dac_control chip) { //注意!! chipはlock中です byte Port; byte Command; byte Data; if ((chip.Running & 0x10) != 0) // command already sent { return; } if (chip.DataStart + chip.RealPos >= chip.DataLen) { return; } //if (! chip->Reverse) //ChipData00 = chip.Data[(chip.DataStart + chip.RealPos)]; //ChipData01 = chip.Data[(chip.DataStart + chip.RealPos+1)]; //else // ChipData = chip->Data + (chip->DataStart + chip->CmdsToSend - 1 - chip->Pos); switch (chip.DstChipType) { // Support for the important chips case 0x02: // YM2612 (16-bit Register (actually 9 Bit), 8-bit Data) Port = (byte)((chip.DstCommand & 0xFF00) >> 8); Command = (byte)((chip.DstCommand & 0x00FF) >> 0); Data = chip.Data[(chip.DataStart + chip.RealPos)]; chip_reg_write(chip.DstChipType , chip.DstEmuType, chip.DstChipIndex, chip.DstChipID , Port, Command, Data); break; case 0x11: // PWM (4-bit Register, 12-bit Data) Port = (byte)((chip.DstCommand & 0x000F) >> 0); Command = (byte)(chip.Data[chip.DataStart + chip.RealPos + 1] & 0x0F); Data = chip.Data[chip.DataStart + chip.RealPos]; chip_reg_write(chip.DstChipType , chip.DstEmuType, chip.DstChipIndex, chip.DstChipID , Port, Command, Data); break; // Support for other chips (mainly for completeness) case 0x00: // SN76496 (4-bit Register, 4-bit/10-bit Data) Command = (byte)((chip.DstCommand & 0x00F0) >> 0); Data = (byte)(chip.Data[chip.DataStart + chip.RealPos] & 0x0F); if ((Command & 0x10) != 0) { // Volume Change (4-Bit value) chip_reg_write(chip.DstChipType , chip.DstEmuType, chip.DstChipIndex, chip.DstChipID , 0x00, 0x00, (byte)(Command | Data)); } else { // Frequency Write (10-Bit value) Port = (byte)(((chip.Data[chip.DataStart + chip.RealPos + 1] & 0x03) << 4) | ((chip.Data[chip.DataStart + chip.RealPos] & 0xF0) >> 4)); chip_reg_write(chip.DstChipType , chip.DstEmuType, chip.DstChipIndex, chip.DstChipID , 0x00, 0x00, (byte)(Command | Data)); chip_reg_write(chip.DstChipType , chip.DstEmuType, chip.DstChipIndex, chip.DstChipID , 0x00, 0x00, Port); } break; case 0x18: // OKIM6295 - TODO: verify Command = (byte)((chip.DstCommand & 0x00FF) >> 0); Data = chip.Data[chip.DataStart + chip.RealPos]; if (Command == 0) { Port = (byte)((chip.DstCommand & 0x0F00) >> 8); if ((Data & 0x80) > 0) { // Sample Start // write sample ID chip_reg_write(chip.DstChipType , chip.DstEmuType, chip.DstChipIndex, chip.DstChipID , 0x00, Command, Data); // write channel(s) that should play the sample chip_reg_write(chip.DstChipType , chip.DstEmuType, chip.DstChipIndex, chip.DstChipID , 0x00, Command, (byte)(Port << 4)); } else { // Sample Stop chip_reg_write(chip.DstChipType , chip.DstEmuType, chip.DstChipIndex, chip.DstChipID , 0x00, Command, (byte)(Port << 3)); } } else { chip_reg_write(chip.DstChipType , chip.DstEmuType, chip.DstChipIndex, chip.DstChipID , 0x00, Command, Data); } break; // Generic support: 8-bit Register, 8-bit Data case 0x01: // YM2413 case 0x03: // YM2151 case 0x06: // YM2203 case 0x09: // YM3812 case 0x0A: // YM3526 case 0x0B: // Y8950 case 0x0F: // YMZ280B case 0x12: // AY8910 case 0x13: // GameBoy DMG case 0x14: // NES APU // case 0x15: // MultiPCM case 0x16: // UPD7759 case 0x17: // OKIM6258 case 0x1D: // K053260 - TODO: Verify case 0x1E: // Pokey - TODO: Verify Command = (byte)((chip.DstCommand & 0x00FF) >> 0); Data = chip.Data[chip.DataStart + chip.RealPos]; chip_reg_write(chip.DstChipType , chip.DstEmuType, chip.DstChipIndex, chip.DstChipID , 0x00, Command, Data); break; // Generic support: 16-bit Register, 8-bit Data case 0x07: // YM2608 case 0x08: // YM2610/B case 0x0C: // YMF262 case 0x0D: // YMF278B case 0x0E: // YMF271 case 0x19: // K051649 - TODO: Verify case 0x1A: // K054539 - TODO: Verify case 0x1C: // C140 - TODO: Verify Port = (byte)((chip.DstCommand & 0xFF00) >> 8); Command = (byte)((chip.DstCommand & 0x00FF) >> 0); Data = chip.Data[chip.DataStart + chip.RealPos]; chip_reg_write(chip.DstChipType , chip.DstEmuType, chip.DstChipIndex, chip.DstChipID , Port, Command, Data); break; // Generic support: 8-bit Register with Channel Select, 8-bit Data case 0x05: // RF5C68 case 0x10: // RF5C164 case 0x1B: // HuC6280 Port = (byte)((chip.DstCommand & 0xFF00) >> 8); Command = (byte)((chip.DstCommand & 0x00FF) >> 0); Data = chip.Data[chip.DataStart + chip.RealPos]; if (Port == 0xFF) // Send Channel Select { chip_reg_write(chip.DstChipType , chip.DstEmuType, chip.DstChipIndex, chip.DstChipID , 0x00, (byte)(Command & 0x0f), Data); } else { byte prevChn; prevChn = Port; // by default don't restore channel // get current channel for supported chips if (chip.DstChipType == 0x05) { } // TODO else if (chip.DstChipType == 0x05) { } // TODO else if (chip.DstChipType == 0x1B) { prevChn = mds.ReadHuC6280(chip.DstChipIndex, chip.DstChipID, 0x00); } // Send Channel Select chip_reg_write(chip.DstChipType , chip.DstEmuType, chip.DstChipIndex, chip.DstChipID , 0x00, (byte)(Command >> 4), Port); // Send Data chip_reg_write(chip.DstChipType , chip.DstEmuType, chip.DstChipIndex, chip.DstChipID , 0x00, (byte)(Command & 0x0F), Data); // restore old channel if (prevChn != Port) { chip_reg_write(chip.DstChipType , chip.DstEmuType, chip.DstChipIndex, chip.DstChipID , 0x00, (byte)(Command >> 4), prevChn); } } break; // Generic support: 8-bit Register, 16-bit Data case 0x1F: // QSound Command = (byte)((chip.DstCommand & 0x00FF) >> 0); chip_reg_write(chip.DstChipType , chip.DstEmuType, chip.DstChipIndex, chip.DstChipID , chip.Data[chip.DataStart + chip.RealPos], chip.Data[chip.DataStart + chip.RealPos + 1], Command); break; } chip.Running |= 0x10; return; }