public void StoreString16(int offset, ushort data) { int addr = (ES << 4) + offset; DataRegister16 reg = new DataRegister16(data); _ram[addr + 1] = reg.HI; _ram[addr] = reg.LO; }
public void MoveString16(int src_offset, int dst_offset) { int dst_addr = (ES << 4) + dst_offset; DataRegister16 data = new DataRegister16(GetData16(src_offset)); _ram[dst_addr + 1] = data.HI; _ram[dst_addr] = data.LO; }
// save the 16 bit value to the requested offset public void SaveData16(int offset, ushort value) { int addr = (GetDataSegment() << 4) + offset; if (addr >= MAX_MEMORY) { throw new InvalidOperationException(String.Format("Memory bounds exceeded. DS={0:X4} offset={1:X4}", DS, offset)); } DataRegister16 data = new DataRegister16(value); _ram[addr + 1] = data.HI; _ram[addr] = data.LO; }
public void PushStack(int offset, ushort value) { int addr = (SS << 4) + offset; if (addr >= MAX_MEMORY) { throw new InvalidOperationException(String.Format("Memory bounds exceeded. SS={0:X4} offset={1:X4}", SS, offset)); } DataRegister16 reg = new DataRegister16(value); _ram[addr + 1] = reg.HI; _ram[addr] = reg.LO; }
public static uint DisassembleNext(byte[] buffer, uint pc, ushort startingAddress, out string output) { // formatting note: immediate data does not get brackets // data from memory or calculations get brackets // something went terribly wrong if (buffer.Length <= pc) throw new IndexOutOfRangeException("Index pc exceeds the bounds of the buffer"); uint bytes_read = 1; byte op = buffer[pc]; OpCodeDasmRecord op_table = OpCodeDasmTable.opCodes[op]; output = ""; // if there is no entry for this code in the op_table it is unused if (op_table.op_name == "") { output = "UNDEFINED OP CODE " + op.ToString("X2"); } // if there is no info for the 2nd byte then it is a one byte op code with a static string else if (op_table.addr_byte == "") { output = op_table.op_name; } // Otherwise use the addr_byte format to determine next steps // Possible values: A-LO, D-8, D-LO, IP-INC-8, IP-INC-LO, IP-LO, MRR // A-LO: 2nd & 3rd bytes point to data at a memory location else if (op_table.addr_byte == "A-LO") { DataRegister16 reg21 = new DataRegister16(buffer[pc + 2], buffer[pc + 1]); bytes_read += 2; if (op_table.op_fmt_1.StartsWith("M-")) { output = string.Format("{0} [{1}],{2}", op_table.op_name, reg21.ToString(), op_table.op_fmt_2); } else { output = string.Format("{0} {1},[{2}]", op_table.op_name, op_table.op_fmt_1, reg21.ToString()); } } // The 2nd byte is 8 bit immediate data else if (op_table.addr_byte == "D-8") { bytes_read++; // these are two byte instructions if (op_table.op_fmt_1 == "I-8") { if (op_table.op_fmt_2 == "") { output = string.Format("{0} {1}", op_table.op_name, buffer[pc + 1].ToString("X2")); } else { output = string.Format("{0} {1},{2}", op_table.op_name, buffer[pc + 1].ToString("X2"), op_table.op_fmt_2); } } else { output = string.Format("{0} {1},{2}", op_table.op_name, op_table.op_fmt_1, buffer[pc + 1].ToString("X2")); } } // D-LO: 2nd & 3rd bytes are 16 bit immediate data else if (op_table.addr_byte == "D-LO") { DataRegister16 reg21 = new DataRegister16(buffer[pc + 2], buffer[pc + 1]); bytes_read += 2; // these are three byte instructions if (op_table.op_fmt_1 == "I-16") { output = string.Format("{0} {1}", op_table.op_name, reg21.ToString()); } else if (op_table.op_fmt_1 == "FAR") { DataRegister16 reg43 = new DataRegister16(buffer[pc + 4], buffer[pc + 3]); output = string.Format("{0} {1}:{2}", op_table.op_name, reg43.ToString(), reg21.ToString()); bytes_read += 2; // two additional bytes } else { output = string.Format("{0} {1},{2}", op_table.op_name, op_table.op_fmt_1, reg21.ToString()); } } // IP-INC-8: Add the 8 bit number to the value of the program counter for the next instruction else if (op_table.addr_byte == "IP-INC-8") { uint immediate = (pc + 2) + buffer[pc + 1]; bytes_read++; // two byte instruction output = string.Format("{0} {1} {2}", op_table.op_name, op_table.op_fmt_1, immediate.ToString("X4")); } // IP-INC-LO: 2nd & 3rd bytes are 16 bites of immediate data to be added to the program counter of the // next instruction else if (op_table.addr_byte == "IP-INC-LO") { DataRegister16 reg21 = new DataRegister16(buffer[pc + 2], buffer[pc + 1]); uint immediate = (pc + 3) + reg21; bytes_read += 2; // three byte instruction output = string.Format("{0} {1}", op_table.op_name, immediate.ToString("X4")); } // IP-LO: next 4 bytes are IP-LO, IP-HI, CS-LO, CS-HI else if (op_table.addr_byte == "IP-LO") { bytes_read += 4; // five byte instruction DataRegister16 reg21 = new DataRegister16(buffer[pc + 2], buffer[pc + 1]); DataRegister16 reg43 = new DataRegister16(buffer[pc + 4], buffer[pc + 3]); output = string.Format("{0} {1}:{2}", op_table.op_name, reg43.ToString(), reg21.ToString()); } // MRR: the biggie else if (op_table.addr_byte == "MRR") { byte addr_mode = buffer[pc + 1]; bytes_read++; // possible formatting values: // M-8, M-16, I-8, I-16, R-8, R-16, RM-8, RM-16, SEG string oper1 = ""; string oper2 = ""; string oper1_fmt = GetFirstOper(buffer, pc); if (oper1_fmt == "RM-8" || oper1_fmt == "M-8") { bytes_read += DisassembleRM(buffer, pc, 1, GetMOD(addr_mode), GetRM(addr_mode), 0, out oper1); } else if (oper1_fmt == "RM-16" || oper1_fmt == "M-16") { bytes_read += DisassembleRM(buffer, pc, 1, GetMOD(addr_mode), GetRM(addr_mode), 1, out oper1); } else if (oper1_fmt == "R-8") { oper1 = RegField[GetREG(buffer, pc), 0]; } else if (oper1_fmt == "R-16") { oper1 = RegField[GetREG(buffer, pc), 1]; } else if (oper1_fmt == "SEG") { oper1 = SegRegTable[GetREG(buffer, pc)]; } else if (oper1_fmt == "I-8") { oper1 = buffer[pc + 2].ToString("X2"); bytes_read++; } else if (oper1_fmt == "I-16") { oper1 = buffer[pc + 3].ToString("X2") + buffer[pc + 2].ToString("X2"); bytes_read += 2; } else if (oper1_fmt != "") { oper1 = oper1_fmt; } uint immed_offset = bytes_read - 1; if (!SkipSecondOper(buffer, pc)) { if (op_table.op_fmt_2 == "RM-8" || op_table.op_fmt_2 == "M-8") { bytes_read += DisassembleRM(buffer, pc, immed_offset, GetMOD(addr_mode), GetRM(addr_mode), 0, out oper2); } else if (op_table.op_fmt_2 == "RM-16" || op_table.op_fmt_2 == "M-16") { bytes_read += DisassembleRM(buffer, pc, immed_offset, GetMOD(addr_mode), GetRM(addr_mode), 1, out oper2); } else if (op_table.op_fmt_2 == "R-8") { oper2 = RegField[GetREG(buffer, pc), 0]; } else if (op_table.op_fmt_2 == "R-16") { oper2 = RegField[GetREG(buffer, pc), 1]; } else if (op_table.op_fmt_2 == "SEG") { oper2 = SegRegTable[GetREG(buffer, pc)]; } else if (op_table.op_fmt_2 == "I-8") { oper2 = buffer[pc + immed_offset + 1].ToString("X2"); bytes_read++; } else if (op_table.op_fmt_2 == "I-16") { oper2 = buffer[pc + immed_offset + 2].ToString("X2") + buffer[pc + immed_offset + 1].ToString("X2"); bytes_read += 2; } else if (op_table.op_fmt_2 != "") { oper2 = op_table.op_fmt_2; } } if (oper2 == "") { output = string.Format("{0} {1}", GetOpName(op, GetREG(buffer,pc)), oper1); } else { output = string.Format("{0} {1},{2}", GetOpName(op, GetREG(buffer, pc)), oper1, oper2); } } output = output.ToLower(); return bytes_read; }
public i8253Timer(byte port) { _port = port; _counter = new DataRegister16(); _enabled = false; }
public static uint DisassembleNext(byte[] buffer, uint pc, ushort startingAddress, out string output) { // formatting note: immediate data does not get brackets // data from memory or calculations get brackets // something went terribly wrong if (buffer.Length <= pc) { throw new IndexOutOfRangeException("Index pc exceeds the bounds of the buffer"); } uint bytes_read = 1; byte op = buffer[pc]; OpCodeDasmRecord op_table = OpCodeDasmTable.opCodes[op]; output = ""; // if there is no entry for this code in the op_table it is unused if (op_table.op_name == "") { output = "UNDEFINED OP CODE " + op.ToString("X2"); } // if there is no info for the 2nd byte then it is a one byte op code with a static string else if (op_table.addr_byte == "") { output = op_table.op_name; } // Otherwise use the addr_byte format to determine next steps // Possible values: A-LO, D-8, D-LO, IP-INC-8, IP-INC-LO, IP-LO, MRR // A-LO: 2nd & 3rd bytes point to data at a memory location else if (op_table.addr_byte == "A-LO") { DataRegister16 reg21 = new DataRegister16(buffer[pc + 2], buffer[pc + 1]); bytes_read += 2; if (op_table.op_fmt_1.StartsWith("M-")) { output = string.Format("{0} [{1}],{2}", op_table.op_name, reg21.ToString(), op_table.op_fmt_2); } else { output = string.Format("{0} {1},[{2}]", op_table.op_name, op_table.op_fmt_1, reg21.ToString()); } } // The 2nd byte is 8 bit immediate data else if (op_table.addr_byte == "D-8") { bytes_read++; // these are two byte instructions if (op_table.op_fmt_1 == "I-8") { if (op_table.op_fmt_2 == "") { output = string.Format("{0} {1}", op_table.op_name, buffer[pc + 1].ToString("X2")); } else { output = string.Format("{0} {1},{2}", op_table.op_name, buffer[pc + 1].ToString("X2"), op_table.op_fmt_2); } } else { output = string.Format("{0} {1},{2}", op_table.op_name, op_table.op_fmt_1, buffer[pc + 1].ToString("X2")); } } // D-LO: 2nd & 3rd bytes are 16 bit immediate data else if (op_table.addr_byte == "D-LO") { DataRegister16 reg21 = new DataRegister16(buffer[pc + 2], buffer[pc + 1]); bytes_read += 2; // these are three byte instructions if (op_table.op_fmt_1 == "I-16") { output = string.Format("{0} {1}", op_table.op_name, reg21.ToString()); } else if (op_table.op_fmt_1 == "FAR") { DataRegister16 reg43 = new DataRegister16(buffer[pc + 4], buffer[pc + 3]); output = string.Format("{0} {1}:{2}", op_table.op_name, reg43.ToString(), reg21.ToString()); bytes_read += 2; // two additional bytes } else { output = string.Format("{0} {1},{2}", op_table.op_name, op_table.op_fmt_1, reg21.ToString()); } } // IP-INC-8: Add the 8 bit number to the value of the program counter for the next instruction else if (op_table.addr_byte == "IP-INC-8") { uint immediate = (pc + 2) + buffer[pc + 1]; bytes_read++; // two byte instruction output = string.Format("{0} {1} {2}", op_table.op_name, op_table.op_fmt_1, immediate.ToString("X4")); } // IP-INC-LO: 2nd & 3rd bytes are 16 bites of immediate data to be added to the program counter of the // next instruction else if (op_table.addr_byte == "IP-INC-LO") { DataRegister16 reg21 = new DataRegister16(buffer[pc + 2], buffer[pc + 1]); uint immediate = (pc + 3) + reg21; bytes_read += 2; // three byte instruction output = string.Format("{0} {1}", op_table.op_name, immediate.ToString("X4")); } // IP-LO: next 4 bytes are IP-LO, IP-HI, CS-LO, CS-HI else if (op_table.addr_byte == "IP-LO") { bytes_read += 4; // five byte instruction DataRegister16 reg21 = new DataRegister16(buffer[pc + 2], buffer[pc + 1]); DataRegister16 reg43 = new DataRegister16(buffer[pc + 4], buffer[pc + 3]); output = string.Format("{0} {1}:{2}", op_table.op_name, reg43.ToString(), reg21.ToString()); } // MRR: the biggie else if (op_table.addr_byte == "MRR") { byte addr_mode = buffer[pc + 1]; bytes_read++; // possible formatting values: // M-8, M-16, I-8, I-16, R-8, R-16, RM-8, RM-16, SEG string oper1 = ""; string oper2 = ""; string oper1_fmt = GetFirstOper(buffer, pc); if (oper1_fmt == "RM-8" || oper1_fmt == "M-8") { bytes_read += DisassembleRM(buffer, pc, 1, GetMOD(addr_mode), GetRM(addr_mode), 0, out oper1); } else if (oper1_fmt == "RM-16" || oper1_fmt == "M-16") { bytes_read += DisassembleRM(buffer, pc, 1, GetMOD(addr_mode), GetRM(addr_mode), 1, out oper1); } else if (oper1_fmt == "R-8") { oper1 = RegField[GetREG(buffer, pc), 0]; } else if (oper1_fmt == "R-16") { oper1 = RegField[GetREG(buffer, pc), 1]; } else if (oper1_fmt == "SEG") { oper1 = SegRegTable[GetREG(buffer, pc)]; } else if (oper1_fmt == "I-8") { oper1 = buffer[pc + 2].ToString("X2"); bytes_read++; } else if (oper1_fmt == "I-16") { oper1 = buffer[pc + 3].ToString("X2") + buffer[pc + 2].ToString("X2"); bytes_read += 2; } else if (oper1_fmt != "") { oper1 = oper1_fmt; } uint immed_offset = bytes_read - 1; if (!SkipSecondOper(buffer, pc)) { if (op_table.op_fmt_2 == "RM-8" || op_table.op_fmt_2 == "M-8") { bytes_read += DisassembleRM(buffer, pc, immed_offset, GetMOD(addr_mode), GetRM(addr_mode), 0, out oper2); } else if (op_table.op_fmt_2 == "RM-16" || op_table.op_fmt_2 == "M-16") { bytes_read += DisassembleRM(buffer, pc, immed_offset, GetMOD(addr_mode), GetRM(addr_mode), 1, out oper2); } else if (op_table.op_fmt_2 == "R-8") { oper2 = RegField[GetREG(buffer, pc), 0]; } else if (op_table.op_fmt_2 == "R-16") { oper2 = RegField[GetREG(buffer, pc), 1]; } else if (op_table.op_fmt_2 == "SEG") { oper2 = SegRegTable[GetREG(buffer, pc)]; } else if (op_table.op_fmt_2 == "I-8") { oper2 = buffer[pc + immed_offset + 1].ToString("X2"); bytes_read++; } else if (op_table.op_fmt_2 == "I-16") { oper2 = buffer[pc + immed_offset + 2].ToString("X2") + buffer[pc + immed_offset + 1].ToString("X2"); bytes_read += 2; } else if (op_table.op_fmt_2 != "") { oper2 = op_table.op_fmt_2; } } if (oper2 == "") { output = string.Format("{0} {1}", GetOpName(op, GetREG(buffer, pc)), oper1); } else { output = string.Format("{0} {1},{2}", GetOpName(op, GetREG(buffer, pc)), oper1, oper2); } } output = output.ToLower(); return(bytes_read); }