// this is same as above but, reads the same data from a binary format. this is for // performance reasons to try and stream the data live from BSNES public void ImportTraceLogLineBinary(byte[] bytes, bool abridgedFormat = true) { // extremely performance-intensive function. be really careful when adding stuff if (abridgedFormat) { Debug.Assert(bytes.Length == 8); } else { Debug.Assert(bytes.Length == 21); } var pointer = 0; // ----------------------------- var snesAddress = ByteUtil.ByteArrayToInt24(bytes, pointer); pointer += 3; var opcodeLen = bytes[pointer++]; var directPage = ByteUtil.ByteArrayToInt16(bytes, pointer); pointer += 2; var dataBank = bytes[pointer++]; // the flags register var flags = bytes[pointer++]; // n = flags & 0x80; // v = flags & 0x40; // m = flags & 0x20; // d = flags & 0x08; // i = flags & 0x04; // z = flags & 0x02; // c = flags & 0x01; // we only care about X and M flags var xflagSet = (flags & 0x10) != 0; var mflagSet = (flags & 0x20) != 0; if (!abridgedFormat) { // skip opcodes. NOTE: must read all 5 bytes but only use up to 'opcode_len' bytes //var op = bytes[pointer++]; //var op0 = bytes[pointer++]; //var op1 = bytes[pointer++]; //var op2 = bytes[pointer++]; pointer += 4; // skip A register pointer += 2; // skip X register pointer += 2; // skip Y register pointer += 2; // skip S register pointer += 2; // skip, flag 'e' for emulation mode or not // skip E(emu) flag <-- NOTE: we might... want this someday. pointer += 1; } Debug.Assert(pointer == bytes.Length); SetOpcodeAndOperandsFromTraceData(snesAddress, dataBank, directPage, xflagSet, mflagSet, opcodeLen); }
private static void ParseBinary(byte[] bytes, bool abridgedFormat, out byte opcodeLen, ModificationData modData) { // file format info from the BSNES side: // https://github.com/binary1230/bsnes-plus/blob/e30dfc784f3c40c0db0a09124db4ec83189c575c/bsnes/snes/cpu/core/disassembler/disassembler.cpp#L224 // extremely performance-intensive function. be really careful when adding stuff if (abridgedFormat) { if (bytes.Length != 8) { throw new InvalidDataException("Non-abridged trace data length must be 8 bytes"); } } else { if (bytes.Length != 21) { throw new InvalidDataException("Non-abridged trace data length must be 21 bytes"); } } var currentIndex = 0; // ----------------------------- modData.SnesAddress = ByteUtil.ByteArrayToInt24(bytes, currentIndex); currentIndex += 3; opcodeLen = bytes[currentIndex++]; modData.DirectPage = ByteUtil.ByteArrayToInt16(bytes, currentIndex); currentIndex += 2; modData.DataBank = bytes[currentIndex++]; // the flags register var flags = bytes[currentIndex++]; // n = flags & 0x80; // v = flags & 0x40; // m = flags & 0x20; // d = flags & 0x08; // i = flags & 0x04; // z = flags & 0x02; // c = flags & 0x01; // we only care about X and M flags modData.XFlagSet = (flags & 0x10) != 0; modData.MFlagSet = (flags & 0x20) != 0; if (!abridgedFormat) { // skip opcodes. NOTE: must read all 5 bytes but only use up to 'opcode_len' bytes //var op = bytes[currentIndex++]; //var op0 = bytes[currentIndex++]; //var op1 = bytes[currentIndex++]; //var op2 = bytes[currentIndex++]; currentIndex += 4; // skip A register currentIndex += 2; // skip X register currentIndex += 2; // skip Y register currentIndex += 2; // skip S register currentIndex += 2; // skip, flag 'e' for emulation mode or not // skip E(emu) flag <-- NOTE: we might... want this someday. currentIndex += 1; } Debug.Assert(currentIndex == bytes.Length); }