protected override void writeAsm(EndianBinaryWriter stream, AddressMapper addressMapper, List <MapDescriptor> mapDescriptors) { var tableAddr = writeTable(mapDescriptors); PowerPcAsm.Pair16Bit v = PowerPcAsm.make16bitValuePair((UInt32)tableAddr); // --- Update Table Addr --- stream.Seek(addressMapper.toFileAddress((BSVAddr)0x801cca98), SeekOrigin.Begin); // mulli r0,r3,0x38 -> mulli r0,r3,0x04 stream.Write(PowerPcAsm.mulli(0, 3, 0x04)); // r3 <- 0x80428e50 -> r3 <- tableAddr stream.Write(PowerPcAsm.lis(3, v.upper16Bit)); stream.Write(PowerPcAsm.addi(3, 3, v.lower16Bit)); stream.Seek(0x4, SeekOrigin.Current); // lwz r3,0x10(r3) -> lwz r3,0x0(r3) stream.Write(PowerPcAsm.lwz(3, 0, 3)); // --- ASM hack: Use the rule set from map instead of from global setting --- var ruleSetFromMapRoutine = allocate(writeRuleSetFromMapRoutine(addressMapper, (VAVAddr)0), "writeRuleSetFromMapRoutine"); stream.Seek(addressMapper.toFileAddress(ruleSetFromMapRoutine), SeekOrigin.Begin); stream.Write(writeRuleSetFromMapRoutine(addressMapper, ruleSetFromMapRoutine)); // re-write the routine again since now we know where it is located in the main dol var virtualPos = addressMapper.toVersionAgnosticAddress((BSVAddr)0x8007e13c); stream.Seek(addressMapper.toFileAddress(virtualPos), SeekOrigin.Begin); // lha r3,0x3c(r30) -> bl ruleSetFromMapRoutine stream.Write(PowerPcAsm.bl(virtualPos, ruleSetFromMapRoutine)); // cmpwi r23,0x0 -> lha r3,0x3c(r30) stream.Write(PowerPcAsm.lha(3, 0x3c, 30)); // lha r0,0x28(r30) -> cmpwi r23,0x0 stream.Write(PowerPcAsm.cmpwi(23, 0x0)); // stw r25,0x53f4(r29) -> lha r0,0x28(r30) stream.Write(PowerPcAsm.lha(0, 0x28, 30)); }