private U8CodeBlock BuildBlock(int Address) { bool complete = false; int offset = 0; List <U8Cmd> Cmds = new List <U8Cmd>(); var newBlock = new U8CodeBlock(null); while (!complete) { U8Cmd cmd = new U8Cmd(); offset += GetBlock(Address + offset, ref cmd, ref newBlock, ref complete); Cmds.Add(cmd); } // save block newBlock.Ops = Cmds.ToArray(); newBlock.Address = newBlock.Ops[0].Address; this.Blocks.Add(newBlock); return(newBlock); }
private bool GetBlocks() { this.Blocks.Clear(); // Split all blocks based on branch conditions and terminate by return // basically just check for anything thats capable of modifying the Instruction Pointer // ALL Conditional relative branch instructions: int ret = 2; int AddrBlockStart = 0; bool isEndOfBlock = false; List <U8Cmd> Cmds = new List <U8Cmd>(); var newBlock = new U8CodeBlock(null); // change to while;true loop? //for (int i = 0; i < this.Disasm.Buffer.Length-6; i+= ret) for (int i = 0x01000; i < this.Memory.Length - 6; i += ret) // dont kill the CPU { U8Cmd cmd = new U8Cmd(); ret = GetBlock(i, ref cmd, ref newBlock, ref isEndOfBlock); cmd.Address = i; Cmds.Add(cmd); if (isEndOfBlock) { // save block newBlock.Ops = Cmds.ToArray(); newBlock.Address = newBlock.Ops[0].Address; this.Blocks.Add(newBlock); Cmds.Clear(); newBlock = new U8CodeBlock(null); isEndOfBlock = false; } } // TODO: Replace with BuildBlock() return(true); }
// disassembles with block propertys private int GetBlock(int Address, ref U8Cmd Cmd, ref U8CodeBlock newBlock, ref bool isEndOfBlock) { // ALL Conditional relative branch instructions: int ret = -1; byte[] buf = new byte[6]; if (Address + 6 > this.Memory.Length) { isEndOfBlock = true; // wont come back again return(-1); // Cia Adios } // fill temp buff for (int b = 0; b < buf.Length; b++) { buf[b] = this.Memory[Address + b]; } // get opcode //u8_cmd opcode = new u8_cmd(); ret = U8Decoder.DecodeOpcode(buf, ref Cmd); Cmd.Address = Address;// dafuq??? //Cmds.Add(opcode); // check branches switch ((U8_OP)Cmd.Type) { case U8_OP.BGE_RAD: // conditional branch case U8_OP.BLT_RAD: case U8_OP.BGT_RAD: case U8_OP.BLE_RAD: case U8_OP.BGES_RAD: case U8_OP.BLTS_RAD: case U8_OP.BGTS_RAD: case U8_OP.BLES_RAD: case U8_OP.BNE_RAD: case U8_OP.BEQ_RAD: case U8_OP.BNV_RAD: case U8_OP.BOV_RAD: case U8_OP.BPS_RAD: case U8_OP.BNS_RAD: case U8_OP.BAL_RAD: // if cond ? radr : PC+=2 // if op1 < 0 then negative else positive; // conditions? dont care actually ;D newBlock.JumpsToBlock = Cmd.Address + Cmd.Op1; // takes jump newBlock.NextBlock = Cmd.Address + 2; // continue isEndOfBlock = true; break; case U8_OP.B_AD: // branch // PC = cadr[15:0] (op1) + second word newBlock.NextBlock = (Cmd.Op1 * 0x10000) + Cmd.sWord; // takes jump newBlock.JumpsToBlock = -1; // newBlock.JumpsToBlock; // dont set so we know its forced? isEndOfBlock = true; break; //// NOTE: Just ignore them? //case U8Decoder.U8_BL_AD: // caller address // newBlock.NextBlock = Cmd.Address + 4; // len 2 // newBlock.JumpsToBlock = -1; // isEndOfBlock = true; // break; //case U8Decoder.U8_BL_ER: // caller register ER // newBlock.NextBlock = Cmd.Address + 2; ; // len 1 // newBlock.JumpsToBlock = -1; // isEndOfBlock = true; // break; case U8_OP.B_ER: // this jumps to ER? whats in ER? newBlock.NextBlock = Cmd.Address += 2; // continue isEndOfBlock = true; break; case U8_OP.RT: // return from subroutine? isEndOfBlock = true; // there is no next ;D break; default: break; } return(ret); }