public void qsound_write_rom(byte ChipID, Int32 ROMSize, Int32 DataStart, Int32 DataLength, byte[] ROMData, Int32 srcStartAddress) { qsound_state info = QSoundData[ChipID]; if (info.sample_rom_length != ROMSize) { info.sample_rom = new sbyte[ROMSize];// (sbyte*)realloc(info.sample_rom, ROMSize); info.sample_rom_length = (UInt32)ROMSize; for (Int32 i = 0; i < ROMSize; i++) { info.sample_rom[i] = (sbyte)(-1); // 0xff; } //memset(info.sample_rom, 0xFF, ROMSize); } if (DataStart > ROMSize) { return; } if (DataStart + DataLength > ROMSize) { DataLength = ROMSize - DataStart; } for (Int32 i = 0; i < DataLength; i++) { info.sample_rom[i + DataStart] = (sbyte)ROMData[i + srcStartAddress]; } //memcpy(info.sample_rom + DataStart, ROMData, DataLength); return; }
//WRITE8_DEVICE_HANDLER( qsound_w ) public void qsound_w(byte ChipID, Int32 offset, byte data) { //qsound_state *chip = get_safe_token(device); qsound_state chip = QSoundData[ChipID]; switch (offset) { case 0: chip.data = (UInt16)((chip.data & 0xff) | (data << 8)); break; case 1: chip.data = (UInt16)((chip.data & 0xff00) | data); break; case 2: qsound_set_command(chip, data, chip.data); break; default: //logerror("%s: unexpected qsound write to offset %d == %02X\n", device->machine().describe_context(), offset, data); //logerror("QSound: unexpected qsound write to offset %d == %02X\n", offset, data); break; } }
public void qsound_set_mute_mask(byte ChipID, UInt32 MuteMask) { qsound_state info = QSoundData[ChipID]; byte CurChn; for (CurChn = 0; CurChn < QSOUND_CHANNELS; CurChn++) { info.channel[CurChn].Muted = (byte)((MuteMask >> CurChn) & 0x01); } return; }
//static DEVICE_STOP( qsound ) public void device_stop_qsound(byte ChipID) { //qsound_state *chip = get_safe_token(device); qsound_state chip = QSoundData[ChipID]; /*if (chip.fpRawDataR) * { * fclose(chip.fpRawDataR); * } * chip.fpRawDataR = NULL; * if (chip.fpRawDataL) * { * fclose(chip.fpRawDataL); * } * chip.fpRawDataL = NULL;*/ //free(chip.sample_rom); chip.sample_rom = null; }
public void device_reset_qsound(byte ChipID) { qsound_state chip = QSoundData[ChipID]; Int32 adr; // init sound regs for (Int32 i = 0; i < chip.channel.Length; i++) { chip.channel[i] = new QSOUND_CHANNEL(); } //memset(chip.channel, 0, sizeof(chip.channel)); for (adr = 0x7f; adr >= 0; adr--) { qsound_set_command(chip, (byte)adr, 0); } for (adr = 0x80; adr < 0x90; adr++) { qsound_set_command(chip, (byte)adr, 0x120); } return; }
//static STREAM_UPDATE( qsound_update ) public void qsound_update(byte ChipID, Int32[][] outputs, Int32 samples) { //qsound_state *chip = (qsound_state *)param; qsound_state chip = QSoundData[ChipID]; Int32 i, j; UInt32 offset; UInt32 advance; sbyte sample; QSOUND_CHANNEL pC = chip.channel[0]; for (i = 0; i < samples; i++) { outputs[0][i] = 0x00; outputs[1][i] = 0x00; } //memset(outputs[0], 0x00, samples * sizeof(* outputs[0]) ); //memset(outputs[1], 0x00, samples * sizeof(* outputs[1]) ); if (chip.sample_rom_length == 0) { return; } for (i = 0; i < QSOUND_CHANNELS; i++)//, pC++) { pC = chip.channel[i]; if (pC.enabled != 0 && pC.Muted == 0) { Int32[] pOutL = outputs[0]; Int32[] pOutR = outputs[1]; Int32 ptr = 0; for (j = samples - 1; j >= 0; j--) { advance = (pC.step_ptr >> 12); pC.step_ptr &= 0xfff; pC.step_ptr += pC.freq; if (advance != 0) { pC.address += advance; if (pC.freq != 0 && pC.address >= pC.end) { if (pC.loop != 0) { // Reached the end, restart the loop pC.address -= pC.loop; // Make sure we don't overflow (what does the real chip do in this case?) if (pC.address >= pC.end) { pC.address = (UInt32)(pC.end - pC.loop); } pC.address &= 0xffff; } else { // Reached the end of a non-looped sample //pC->enabled = 0; pC.address--; // ensure that old ripped VGMs still work pC.step_ptr += 0x1000; break; } } } offset = (pC.bank | pC.address) % chip.sample_rom_length; sample = chip.sample_rom[offset]; pOutL[ptr] += ((sample * pC.lvol * pC.vol) >> 14); pOutR[ptr] += ((sample * pC.rvol * pC.vol) >> 14); ptr++; } } } /*if (chip.fpRawDataL) * fwrite(outputs[0], samples*sizeof(Int32), 1, chip.fpRawDataL); * if (chip.fpRawDataR) * fwrite(outputs[1], samples*sizeof(Int32), 1, chip.fpRawDataR);*/ }
public void qsound_set_command(qsound_state chip, byte address, UInt16 data) { Int32 ch = 0, reg = 0; // direct sound reg if (address < 0x80) { ch = address >> 3; reg = address & 0x07; } // >= 0x80 is probably for the dsp? else if (address < 0x90) { ch = address & 0x0F; reg = 8; } else if (address >= 0xba && address < 0xca) { ch = address - 0xba; reg = 9; } else { /* Unknown registers */ ch = 99; reg = 99; } switch (reg) { case 0: // bank, high bits unknown ch = (ch + 1) & 0x0f; /* strange ... */ chip.channel[ch].bank = (UInt32)((data & 0x7f) << 16); // Note: The most recent MAME doesn't do "& 0x7F" //# ifdef _DEBUG //if (data && !(data & 0x8000)) //fprintf(stderr, "QSound Ch %u: Bank = %04x\n", ch, data); //#endif break; case 1: // start/cur address chip.channel[ch].address = data; break; case 2: // frequency chip.channel[ch].freq = data; // This was working with the old code, but breaks the songs with the new one. // And I'm pretty sure the hardware won't do this. -Valley Bell /*if (!data) * { * // key off * chip.channel[ch].enabled = 0; * }*/ break; case 3: //# ifdef _DEBUG // if (chip.channel[ch].enabled && data != 0x8000) // fprintf(stderr, "QSound Ch %u: KeyOn = %04x\n", ch, data); //#endif // key on (does the value matter? it always writes 0x8000) //chip.channel[ch].enabled = 1; chip.channel[ch].enabled = (byte)((data & 0x8000) >> 15); chip.channel[ch].step_ptr = 0; break; case 4: // loop address chip.channel[ch].loop = data; break; case 5: // end address chip.channel[ch].end = data; break; case 6: // master volume //# ifdef _DEBUG // if (!chip.channel[ch].enabled && data) // fprintf(stderr, "QSound update warning - please report!\n"); //#endif chip.channel[ch].vol = data; break; case 7: // unused? //# ifdef MAME_DEBUG // popmessage("UNUSED QSOUND REG 7=%04x", data); //#endif break; case 8: { // panning (left=0x0110, centre=0x0120, right=0x0130) // looks like it doesn't write other values than that int pan = (data & 0x3f) - 0x10; if (pan > 0x20) { pan = 0x20; } if (pan < 0) { pan = 0; } chip.channel[ch].rvol = chip.pan_table[pan]; chip.channel[ch].lvol = chip.pan_table[0x20 - pan]; } break; case 9: // unknown /* #ifdef MAME_DEBUG * popmessage("QSOUND REG 9=%04x",data); #endif */ break; default: //logerror("%s: write_data %02x = %04x\n", machine().describe_context(), address, data); break; } //LOG(("QSOUND WRITE %02x CH%02d-R%02d =%04x\n", address, ch, reg, data)); }