Пример #1
0
        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;
        }
Пример #2
0
        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;
        }
Пример #3
0
        // 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;
        }
Пример #4
0
        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;
        }
Пример #5
0
        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;
        }
Пример #6
0
 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;
 }
Пример #7
0
 // 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;
 }
Пример #8
0
        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;
        }
Пример #9
0
        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;
        }
Пример #10
0
 public i8253Timer(byte port)
 {
     _port    = port;
     _counter = new DataRegister16();
     _enabled = false;
 }
Пример #11
0
        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);
        }