public void install(ref sidmemory mem, byte video) { mem.fillRam(0, (byte)(0), 0x3ff); if (m_tuneInfo.compatibility() >= sidplayfp.SidTuneInfo.compatibility_t.COMPATIBILITY_R64) { copyPoweronPattern(ref mem); } // Set PAL/NTSC switch mem.writeMemByte(0x02a6, video); mem.installResetHook(sidendian.endian_little16(reloc_driver)); // If not a basic tune then the psiddrv must install // interrupt hooks and trap programs trying to restart basic if (m_tuneInfo.compatibility() == sidplayfp.SidTuneInfo.compatibility_t.COMPATIBILITY_BASIC) { // Install hook to set subtune number for basic mem.setBasicSubtune((byte)(m_tuneInfo.currentSong() - 1)); mem.installBasicTrap(0xbf53); } else { // Only install irq handle for RSID tunes mem.fillRam(0x0314, new Ptr <byte>(reloc_driver, 2), (UInt32)(m_tuneInfo.compatibility() == sidplayfp.SidTuneInfo.compatibility_t.COMPATIBILITY_R64 ? 2 : 6)); // Experimental restart basic trap UInt16 addr = sidendian.endian_little16(new Ptr <byte>(reloc_driver, 8)); mem.installBasicTrap(0xffe1); mem.writeMemWord(0x0328, addr); } Int32 pos = m_driverAddr; // Install driver to ram mem.fillRam((UInt16)pos, new Ptr <byte>(reloc_driver, 10), (UInt32)reloc_size); // Set song number mem.writeMemByte((UInt16)pos, (byte)(m_tuneInfo.currentSong() - 1)); pos++; // Set tunes speed (VIC/CIA) mem.writeMemByte((UInt16)pos, (byte)(m_tuneInfo.songSpeed() == sidplayfp.SidTuneInfo.SPEED_VBI ? 0 : 1)); pos++; // Set init address mem.writeMemWord((UInt16)pos, (UInt16)(m_tuneInfo.compatibility() == sidplayfp.SidTuneInfo.compatibility_t.COMPATIBILITY_BASIC ? 0xbf55 : m_tuneInfo.initAddr())); pos += 2; // Set play address mem.writeMemWord((UInt16)pos, m_tuneInfo.playAddr()); pos += 2; // Set init address io bank value mem.writeMemByte((UInt16)pos, iomap(m_tuneInfo.initAddr())); pos++; // Set play address io bank value mem.writeMemByte((UInt16)pos, iomap(m_tuneInfo.playAddr())); pos++; // Set PAL/NTSC flag mem.writeMemByte((UInt16)pos, video); pos++; // Set the required tune clock speed byte clockSpeed; switch (m_tuneInfo.clockSpeed()) { case sidplayfp.SidTuneInfo.clock_t.CLOCK_PAL: clockSpeed = 1; break; case sidplayfp.SidTuneInfo.clock_t.CLOCK_NTSC: clockSpeed = 0; break; default: // UNKNOWN or ANY clockSpeed = video; break; } mem.writeMemByte((UInt16)pos, clockSpeed); pos++; // Set default processor register flags on calling init mem.writeMemByte((UInt16)pos, (byte)(m_tuneInfo.compatibility() >= sidplayfp.SidTuneInfo.compatibility_t.COMPATIBILITY_R64 ? 0 : 1 << c64.CPU.MOS6510.SR_INTERRUPT)); //Console.WriteLine("{0}",mem.readMemByte(0x17e3)); }
// Clock speed changes due to loading a new song private c64.c64.model_t c64model(sidplayfp.SidConfig.c64_model_t defaultModel, bool forced) { sidplayfp.SidTuneInfo tuneInfo = m_tune.getInfo(); sidplayfp.SidTuneInfo.clock_t clockSpeed = tuneInfo.clockSpeed(); c64.c64.model_t model = c64.c64.model_t.PAL_B; // Use preferred speed if forced or if song speed is unknown if (forced || clockSpeed == sidplayfp.SidTuneInfo.clock_t.CLOCK_UNKNOWN || clockSpeed == sidplayfp.SidTuneInfo.clock_t.CLOCK_ANY) { switch (defaultModel) { case sidplayfp.SidConfig.c64_model_t.PAL: clockSpeed = sidplayfp.SidTuneInfo.clock_t.CLOCK_PAL; model = c64.c64.model_t.PAL_B; videoSwitch = 1; break; case sidplayfp.SidConfig.c64_model_t.DREAN: clockSpeed = sidplayfp.SidTuneInfo.clock_t.CLOCK_PAL; model = c64.c64.model_t.PAL_N; videoSwitch = 1; // TODO verify break; case sidplayfp.SidConfig.c64_model_t.NTSC: clockSpeed = sidplayfp.SidTuneInfo.clock_t.CLOCK_NTSC; model = c64.c64.model_t.NTSC_M; videoSwitch = 0; break; case sidplayfp.SidConfig.c64_model_t.OLD_NTSC: clockSpeed = sidplayfp.SidTuneInfo.clock_t.CLOCK_NTSC; model = c64.c64.model_t.OLD_NTSC_M; videoSwitch = 0; break; } } else { switch (clockSpeed) { default: case sidplayfp.SidTuneInfo.clock_t.CLOCK_PAL: model = c64.c64.model_t.PAL_B; videoSwitch = 1; break; case sidplayfp.SidTuneInfo.clock_t.CLOCK_NTSC: model = c64.c64.model_t.NTSC_M; videoSwitch = 0; break; } } switch (clockSpeed) { case sidplayfp.SidTuneInfo.clock_t.CLOCK_PAL: if (tuneInfo.songSpeed() == sidplayfp.SidTuneInfo.SPEED_CIA_1A) { m_info.m_speedString = TXT_PAL_CIA; } else if (tuneInfo.clockSpeed() == sidplayfp.SidTuneInfo.clock_t.CLOCK_NTSC) { m_info.m_speedString = TXT_PAL_VBI_FIXED; } else { m_info.m_speedString = TXT_PAL_VBI; } break; case sidplayfp.SidTuneInfo.clock_t.CLOCK_NTSC: if (tuneInfo.songSpeed() == sidplayfp.SidTuneInfo.SPEED_CIA_1A) { m_info.m_speedString = TXT_NTSC_CIA; } else if (tuneInfo.clockSpeed() == sidplayfp.SidTuneInfo.clock_t.CLOCK_PAL) { m_info.m_speedString = TXT_NTSC_VBI_FIXED; } else { m_info.m_speedString = TXT_NTSC_VBI; } break; default: break; } return(model); }