Esempio n. 1
0
 public void refresh()
 {
     for (int i = 0; i < MAX_CHIPS; i++)
     {
         DACData[i] = new dac_control();
     }
 }
Esempio n. 2
0
        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;
        }
Esempio n. 3
0
        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;
        }
Esempio n. 4
0
        public void device_stop_daccontrol(byte ChipID)
        {
            dac_control chip = DACData[ChipID];

            chip.Running = 0xFF;

            return;
        }
Esempio n. 5
0
 public void device_stop_daccontrol(byte ChipID)
 {
     lock (lockObj)
     {
         dac_control chip = DACData[ChipID];
         chip.Running = 0xFF;
     }
 }
Esempio n. 6
0
        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;
        }
Esempio n. 7
0
        public void stop(byte ChipID)
        {
            dac_control chip = DACData[ChipID];

            if ((chip.Running & 0x80) > 0)
            {
                return;
            }

            chip.Running &= 0xfe;// ~0x01; // stop

            return;
        }
Esempio n. 8
0
        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;
        }
Esempio n. 9
0
        private void stop(byte ChipID)
        {
            lock (lockObj)
            {
                dac_control chip = DACData[ChipID];

                if ((chip.Running & 0x80) != 0)
                {
                    return;
                }

                chip.Running &= 0xfe;// ~0x01; // stop
            }
        }
Esempio n. 10
0
        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);
            }
        }
Esempio n. 11
0
        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;
            }
        }
Esempio n. 12
0
        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;
        }
Esempio n. 13
0
        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;
        }
Esempio n. 14
0
        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;
        }
Esempio n. 15
0
        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;
        }
Esempio n. 16
0
        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;
        }