| 451 | } |
| 452 | |
| 453 | std::vector<unsigned char> CCompiler::LoadDriver(const driver_t &Driver, unsigned short Origin) const { // // // |
| 454 | // Copy embedded driver |
| 455 | std::vector<unsigned char> Data(Driver.driver.begin(), Driver.driver.end()); |
| 456 | |
| 457 | // // // Custom pitch tables |
| 458 | CPeriodTables PeriodTables = m_pModule->MakePeriodTables(); // // // |
| 459 | for (size_t i = 0; i < Driver.freq_table.size(); i += 2) { // // // |
| 460 | int Table = Driver.freq_table[i + 1]; |
| 461 | switch (Table) { |
| 462 | case CDetuneTable::DETUNE_NTSC: |
| 463 | case CDetuneTable::DETUNE_PAL: |
| 464 | case CDetuneTable::DETUNE_SAW: |
| 465 | case CDetuneTable::DETUNE_FDS: |
| 466 | case CDetuneTable::DETUNE_N163: |
| 467 | for (int j = 0; j < NOTE_COUNT; ++j) { |
| 468 | int Reg = PeriodTables.ReadTable(j, Table); |
| 469 | Data[Driver.freq_table[i] + 2 * j ] = Reg & 0xFF; |
| 470 | Data[Driver.freq_table[i] + 2 * j + 1] = Reg >> 8; |
| 471 | } break; |
| 472 | case CDetuneTable::DETUNE_VRC7: |
| 473 | for (int j = 0; j <= NOTE_RANGE; ++j) { // one extra item |
| 474 | int Reg = PeriodTables.ReadTable(j % NOTE_RANGE, Table) * 4; |
| 475 | if (j == NOTE_RANGE) Reg <<= 1; |
| 476 | Data[Driver.freq_table[i] + j ] = Reg & 0xFF; |
| 477 | Data[Driver.freq_table[i] + j + NOTE_RANGE + 1] = Reg >> 8; |
| 478 | } break; |
| 479 | default: |
| 480 | DEBUG_BREAK(); |
| 481 | } |
| 482 | } |
| 483 | |
| 484 | // Relocate driver |
| 485 | for (size_t i = 0; i < Driver.word_reloc.size(); ++i) { |
| 486 | // Words |
| 487 | unsigned short value = Data[Driver.word_reloc[i]] + (Data[Driver.word_reloc[i] + 1] << 8); |
| 488 | value += Origin; |
| 489 | Data[Driver.word_reloc[i]] = value & 0xFF; |
| 490 | Data[Driver.word_reloc[i] + 1] = value >> 8; |
| 491 | } |
| 492 | |
| 493 | for (size_t i = 0; i < Driver.adr_reloc.size(); i += 2) { // // // |
| 494 | unsigned short value = Data[Driver.adr_reloc[i]] + (Data[Driver.adr_reloc[i + 1]] << 8); |
| 495 | value += Origin; |
| 496 | Data[Driver.adr_reloc[i]] = value & 0xFF; |
| 497 | Data[Driver.adr_reloc[i + 1]] = value >> 8; |
| 498 | } |
| 499 | |
| 500 | if (m_pModule->HasExpansionChip(sound_chip_t::N163)) { |
| 501 | Data[m_iDriverSize - 2 - 0x100 - 0xC0 * 2 - 8 - 1 - MAX_CHANNELS_N163 + m_pModule->GetNamcoChannels()] = 3; |
| 502 | } |
| 503 | |
| 504 | if (m_pModule->GetSoundChipSet().IsMultiChip()) { // // // special processing for multichip |
| 505 | int ptr = FT_UPDATE_EXT_ADR; |
| 506 | FTEnv.GetSoundChipService()->ForeachType([&] (sound_chip_t chip) { |
| 507 | if (chip != sound_chip_t::APU) { |
| 508 | Assert(Data[ptr] == 0x20); // jsr |
| 509 | if (!m_pModule->HasExpansionChip(chip)) { |
| 510 | Data[ptr++] = 0xEA; // nop |
nothing calls this directly
no test coverage detected