Пример #1
0
        private string NameOfRegGP(RegGeneral register)
        {
            switch (register)
            {
            case RegGeneral.R0:
                return("R0");

            case RegGeneral.R1:
                return("R1");

            case RegGeneral.R2:
                return("R2");

            case RegGeneral.R3:
                return("R3");

            case RegGeneral.R4:
                return("R4");

            case RegGeneral.R5:
                return("R5");

            case RegGeneral.R6:
                return("R6");

            case RegGeneral.R7:
                return("R7");

            default:
                return("??");
            }
        }
Пример #2
0
 private void BitPatternBTI(ushort operand, out ushort value, out RegGeneral destination)
 {
     destination = (RegGeneral)((operand & 0xE000) >> 13);
     RegGeneral source = (RegGeneral)((operand & 0x1C00) >> 10);
     bool asRegister = (operand & 0x0100) != 0;
     value = asRegister ?
         (ushort)(R[(int)source] & 0x000F) :
         (ushort)((operand & 0x1E00) >> 9);
 }
Пример #3
0
        private void BitPatternBTI(ushort operand, out ushort value, out RegGeneral destination)
        {
            destination = (RegGeneral)((operand & 0xE000) >> 13);
            RegGeneral source     = (RegGeneral)((operand & 0x1C00) >> 10);
            bool       asRegister = (operand & 0x0100) != 0;

            value = asRegister ?
                    (ushort)(R[(int)source] & 0x000F) :
                    (ushort)((operand & 0x1E00) >> 9);
        }
Пример #4
0
        /// <summary>
        /// Executes an ALU operation.
        /// </summary>
        /// <param name="operand">Input: machine code word</param>
        /// <param name="value">Output: result value of operation</param>
        /// <param name="destination">Output: index of general register result should be written to.</param>
        private void BitPatternALU(ushort operand, out ushort value, out RegGeneral destination)
        {
            ushort address;

            // Decode the operand word's constituent bits.             FEDC BA98 7654 3210
            //                                                         SAAA rrrE OOOO ORRR
            int        addressingMode = (operand & 0x7000) >> 12;
            RegGeneral source         = (RegGeneral)((operand & 0x0E00) >> 9);
            bool       eightBitMode   = (operand & 0x0100) != 0;

            destination = (RegGeneral)(operand & 0x0007); // R = destination register
            SegmentIndex dataSeg = (operand & 0x8000) != 0 ? SegmentIndex.ES : SegmentIndex.DS;

            switch (addressingMode) // will always be between 0x0 and 0x7
            {
            case 0:                 // Addressing mode: Immediate (r == 0), Absolute (r == 1), else Control Register.
                if (source == 0)    // Immediate
                {
                    value = eightBitMode ? ReadMemInt8(PC, SegmentIndex.CS) : ReadMemInt16(PC, SegmentIndex.CS);
                    PC   += 2;             // advance PC two bytes because we're reading an immediate value.
                }
                else if ((int)source == 1) // Absolute
                {
                    address = ReadMemInt16(PC, SegmentIndex.CS);
                    PC     += 2; // advance PC two bytes because we're reading an immediate value.
                    value   = eightBitMode ? ReadMemInt8(address, dataSeg) : ReadMemInt16(address, dataSeg);
                }
                else     // Control Register
                {
                    RegControl cr = (RegControl)((operand & 0x0700) >> 8);
                    value = ReadControlRegister(operand, cr);
                }
                break;

            case 1:     // Addressing mode: Register
                value = R[(int)source];
                break;

            case 2:     // Addressing mode: Indirect
                value = eightBitMode ? ReadMemInt8(R[(int)source], dataSeg) : ReadMemInt16(R[(int)source], dataSeg);
                break;

            case 3:          // Addressing mode: Absolute Offset AKA Indirect Offset
                address = (ushort)(R[(int)source] + ReadMemInt16(PC, SegmentIndex.CS));
                PC     += 2; // advance PC two bytes because we're reading an immediate value.
                value   = eightBitMode ? ReadMemInt8(address, dataSeg) : ReadMemInt16(address, dataSeg);
                break;

            default:                                // addressing of 0x4 ~ 0x7 is an Indirect Indexed operation.
                int indexRegister = addressingMode; // bit pattern is 1ii, where ii = r4 - r7.
                address = (ushort)(R[(int)source] + R[indexRegister]);
                value   = eightBitMode ? ReadMemInt8(address, dataSeg) : ReadMemInt16(address, dataSeg);
                break;
            }
        }
Пример #5
0
        /// <summary>
        /// Executes a STOre operation (same bit pattern as ALU, but writes a value from r0 to destination).
        /// </summary>
        /// <param name="operand">Input: machine code word</param>
        /// <param name="destAddress">Output: memory address that is the destination of the operation</param>
        /// <param name="source">Output: general register that is the source of the operation</param>
        private void BitPatternSTO(ushort operand, out ushort destAddress, out RegGeneral source)
        {
            // Decode the operand word's constituent bits.             FEDC BA98 7654 3210
            //                                                         SAAA rrrE OOOO ORRR
            int        addressingMode = (operand & 0x7000) >> 12;
            RegGeneral addrRegister   = (RegGeneral)((operand & 0x0E00) >> 9);

            source = (RegGeneral)(operand & 0x0007); // R = source register
            switch (addressingMode)                  // will always be between 0x0 and 0x7
            {
            case 0:                                  // Immediate (r == 0), Absolute (r == 1), else Control Register
                if (addrRegister == 0)
                {
                    // Immediate - no such addressing mode for STO.
                    source      = RegGeneral.None;
                    destAddress = 0;
                    Interrupt_UndefFault(operand);
                }
                else if ((int)addrRegister == 1)
                {
                    destAddress = ReadMemInt16(PC, SegmentIndex.CS);
                    PC         += 2; // advance PC two bytes because we're reading an immediate value.
                }
                else
                {
                    RegControl cr = (RegControl)((operand & 0x0700) >> 8);
                    WriteControlRegister(operand, cr, R[(int)source]);
                    // set source = none so calling function doesn't attempt to interpret this as well.
                    source      = RegGeneral.None;
                    destAddress = 0;
                }
                break;

            case 1:     // Register - no such addressing mode for STO.
                source      = RegGeneral.None;
                destAddress = 0;
                Interrupt_UndefFault(operand);
                break;

            case 2:     // Indirect
                destAddress = R[(int)addrRegister];
                break;

            case 3:              // Absolute Offset AKA Indirect Offset
                destAddress = (ushort)(R[(int)addrRegister] + ReadMemInt16(PC, SegmentIndex.CS));
                PC         += 2; // advance PC two bytes because we're reading an immediate value.
                break;

            default:                                // $8-$F are Indirect Indexed operations.
                int indexRegister = addressingMode; // bit pattern is 01ii, indicating r4 - r7.
                destAddress = (ushort)(R[(int)source] + R[indexRegister]);
                break;
            }
        }
Пример #6
0
 private void BitPatternSHF(ushort operand, out ushort value, out RegGeneral destination)
 {
     destination = (RegGeneral)((operand & 0xE000) >> 13);
     if ((operand & 0x1000) == 0)
     {
         value = (ushort)(((operand & 0x0F00) >> 8) + 1);
     }
     else
     {
         value = R[(operand & 0x0700) >> 8];
     }
 }
Пример #7
0
        private string DisassembleBTT(string name, ushort operand, ushort nextword, ushort address, bool showMemoryContents, out ushort instructionSize)
        {
            instructionSize = 2;
            RegGeneral destination = (RegGeneral)((operand & 0xE000) >> 13);
            bool       as_register = (operand & 0x1000) != 0;
            ushort     value       = as_register ?
                                     (ushort)((operand & 0x0700) >> 8) :
                                     (ushort)((operand & 0x0F00) >> 8);

            return
                ($"{name,-8}{NameOfRegGP(destination)}, {(as_register ? $"{NameOfRegGP((RegGeneral)value),-8}(${R[value]:X1})" : $"${value:X1}")}");
        }
Пример #8
0
        /// <summary>
        /// Executes an ALU operation.
        /// </summary>
        /// <param name="operand">Input: machine code word</param>
        /// <param name="value">Output: result value of operation</param>
        /// <param name="destination">Output: index of general register result should be written to.</param>
        private void BitPatternALU(ushort operand, out ushort value, out RegGeneral destination)
        {
            ushort address;

            // Decode the operand word's constituent bits.             FEDC BA98 7654 3210
            //                                                         SAAA rrrE OOOO ORRR
            int addressingMode = (operand & 0x7000) >> 12;
            RegGeneral source = (RegGeneral)((operand & 0x0E00) >> 9);
            bool eightBitMode = (operand & 0x0100) != 0;
            destination = (RegGeneral)(operand & 0x0007); // R = destination register
            SegmentIndex dataSeg = (operand & 0x8000) != 0 ? SegmentIndex.ES : SegmentIndex.DS;
            switch (addressingMode) // will always be between 0x0 and 0x7
            {
                case 0: // Addressing mode: Immediate (r == 0), Absolute (r == 1), else Control Register.
                    if (source == 0) // Immediate
                    {
                        value = eightBitMode ? ReadMemInt8(PC, SegmentIndex.CS) : ReadMemInt16(PC, SegmentIndex.CS);
                        PC += 2; // advance PC two bytes because we're reading an immediate value.
                    }
                    else if ((int)source == 1) // Absolute
                    {
                        address = ReadMemInt16(PC, SegmentIndex.CS);
                        PC += 2; // advance PC two bytes because we're reading an immediate value.
                        value = eightBitMode ? ReadMemInt8(address, dataSeg) : ReadMemInt16(address, dataSeg);
                    }
                    else // Control Register
                    {
                        RegControl cr = (RegControl)((operand & 0x0700) >> 8);
                        value = ReadControlRegister(operand, cr);
                    }
                    break;
                case 1: // Addressing mode: Register
                    value = R[(int)source];
                    break;
                case 2: // Addressing mode: Indirect
                    value = eightBitMode ? ReadMemInt8(R[(int)source], dataSeg) : ReadMemInt16(R[(int)source], dataSeg);
                    break;
                case 3: // Addressing mode: Absolute Offset AKA Indirect Offset
                    address = (ushort)(R[(int)source] + ReadMemInt16(PC, SegmentIndex.CS));
                    PC += 2; // advance PC two bytes because we're reading an immediate value.
                    value = eightBitMode ? ReadMemInt8(address, dataSeg) : ReadMemInt16(address, dataSeg);
                    break;
                default: // addressing of 0x4 ~ 0x7 is an Indirect Indexed operation.
                    int indexRegister = addressingMode; // bit pattern is 1ii, where ii = r4 - r7.
                    address = (ushort)(R[(int)source] + R[indexRegister]);
                    value = eightBitMode ? ReadMemInt8(address, dataSeg) : ReadMemInt16(address, dataSeg);
                    break;
            }
        }
Пример #9
0
 private void BitPatternSET(ushort operand, out ushort value, out RegGeneral destination)
 {
     destination = (RegGeneral)((operand & 0xE000) >> 13);
     value       = (ushort)((operand & 0x1F00) >> 8);
     if ((operand & 0x0001) == 1)
     {
         if (value <= 0x0A)
         {
             value = (ushort)(0x0001 << (value + 0x05));
         }
         else
         {
             value = (ushort)(0xFFE0 + value);
         }
     }
 }
Пример #10
0
        private string DisassembleSHF(string name, ushort operand, ushort nextword, ushort address, bool showMemoryContents, out ushort instructionSize)
        {
            instructionSize = 2;
            RegGeneral destination = (RegGeneral)((operand & 0xE000) >> 13);
            string     value;

            if ((operand & 0x1000) == 0)
            {
                int shiftby = ((operand & 0x0F00) >> 8) + 1;
                value = $"${(ushort)shiftby:X2}";
            }
            else
            {
                value = NameOfRegGP((RegGeneral)((operand & 0x0700) >> 8));
            }
            return($"{name,-8}{NameOfRegGP(destination)}, {value}");
        }
Пример #11
0
        private string DisassembleJMP(string name, ushort operand, ushort nextword, ushort address, bool showMemoryContents, out ushort instructionSize)
        {
            int          addressingmode = (operand & 0x7000) >> 12;
            RegGeneral   r_src          = (RegGeneral)((operand & 0x1C00) >> 10);
            int          index_bits     = (operand & 0x0300) >> 8;
            SegmentIndex segData        = (operand & 0x8000) != 0 ? SegmentIndex.ES : SegmentIndex.DS;
            bool         isFar          = (operand & 0x0100) != 0;

            if (isFar)
            {
                name += ".F";
            }
            switch (addressingmode)
            {
            case 0:     // Immediate or Absolute
                bool absolute = (operand & 0x0200) != 0;
                instructionSize = (ushort)(isFar && !absolute ? 8 : 4);
                if (absolute)
                {
                    return
                        ($"{name,-8}[${nextword:X4}]{string.Format($"         (${DebugReadMemory(nextword, SegmentIndex.CS):X4})", DebugReadMemory(nextword, SegmentIndex.CS))}");
                }
                return($"{name,-8}${nextword:X4}{(isFar ? ", $<SEGREG>" : string.Empty)}");

            case 1:     // Register
                instructionSize = 2;
                return($"{name,-8}{NameOfRegGP(r_src)}              (${R[(int)r_src]:X4})");

            case 2:     // Indirect
                instructionSize = 2;
                return
                    ($"{name,-8}[{NameOfRegGP(r_src)}]            (${DebugReadMemory(R[(int)r_src], segData):X4})");

            case 3:     // Indirect Offset (also Absolute Offset)
                instructionSize = 4;
                return
                    ($"{name,-8}[{NameOfRegGP(r_src)},${nextword:X4}]      (${DebugReadMemory((ushort)(R[(int)r_src] + nextword), segData):X4})");

            default:     // $8 - $f = Indirect Indexed
                instructionSize = 2;
                index_bits     += (operand & 0x4000) >> 12;
                return
                    ($"{name,-8}[{NameOfRegGP(r_src)},{NameOfRegGP((RegGeneral)index_bits)}]         (${DebugReadMemory((ushort)(R[(int)r_src] + R[index_bits]), segData):X4})");
            }
        }
Пример #12
0
        private string DisassembleSET(string name, ushort operand, ushort nextword, ushort address, bool showMemoryContents, out ushort instructionSize)
        {
            instructionSize = 2;
            RegGeneral destination = (RegGeneral)((operand & 0xE000) >> 13);
            int        value       = (operand & 0x1F00) >> 8;

            if ((operand & 0x0001) == 1)
            {
                if (value <= 0x0A)
                {
                    value = (ushort)(0x0001 << (value + 0x05));
                }
                else
                {
                    value = (ushort)(0xFFE0 + value);
                }
            }
            return($"{name,-8}{NameOfRegGP(destination)}, {string.Format($"${value:X2}", value)}");
        }
Пример #13
0
 private void BitPatternSHF(ushort operand, out ushort value, out RegGeneral destination)
 {
     destination = (RegGeneral)((operand & 0xE000) >> 13);
     if ((operand & 0x1000) == 0) {
         value = (ushort)(((operand & 0x0F00) >> 8) + 1);
     }
     else {
         value = R[(operand & 0x0700) >> 8];
     }
 }
Пример #14
0
 private void BitPatternSTK(ushort operand, out ushort value, out RegGeneral destination)
 {
     destination = RegGeneral.None; // unused
     value = (ushort)(operand & 0xFF01);
 }
Пример #15
0
 private void BitPatternBRA(ushort operand, out ushort value, out RegGeneral destination)
 {
     destination = RegGeneral.None;                   // not used
     value       = (ushort)((operand & 0xFF00) >> 7); // (shift 8 - 1) to multiply result by two, per spec.
 }
Пример #16
0
 /// <summary>
 /// Executes a STOre operation (same bit pattern as ALU, but writes a value from r0 to destination).
 /// </summary>
 /// <param name="operand">Input: machine code word</param>
 /// <param name="destAddress">Output: memory address that is the destination of the operation</param>
 /// <param name="source">Output: general register that is the source of the operation</param>
 private void BitPatternSTO(ushort operand, out ushort destAddress, out RegGeneral source)
 {
     // Decode the operand word's constituent bits.             FEDC BA98 7654 3210
     //                                                         SAAA rrrE OOOO ORRR
     int addressingMode = (operand & 0x7000) >> 12;
     RegGeneral addrRegister = (RegGeneral)((operand & 0x0E00) >> 9);
     source = (RegGeneral)(operand & 0x0007); // R = source register
     switch (addressingMode) // will always be between 0x0 and 0x7
     {
         case 0: // Immediate (r == 0), Absolute (r == 1), else Control Register
             if (addrRegister == 0) {
                 // Immediate - no such addressing mode for STO.
                 source = RegGeneral.None;
                 destAddress = 0;
                 Interrupt_UndefFault(operand);
             }
             else if ((int)addrRegister == 1) {
                 destAddress = ReadMemInt16(PC, SegmentIndex.CS);
                 PC += 2; // advance PC two bytes because we're reading an immediate value.
             }
             else {
                 RegControl cr = (RegControl)((operand & 0x0700) >> 8);
                 WriteControlRegister(operand, cr, R[(int)source]);
                 // set source = none so calling function doesn't attempt to interpret this as well.
                 source = RegGeneral.None;
                 destAddress = 0;
             }
             break;
         case 1: // Register - no such addressing mode for STO.
             source = RegGeneral.None;
             destAddress = 0;
             Interrupt_UndefFault(operand);
             break;
         case 2: // Indirect
             destAddress = R[(int)addrRegister];
             break;
         case 3: // Absolute Offset AKA Indirect Offset
             destAddress = (ushort)(R[(int)addrRegister] + ReadMemInt16(PC, SegmentIndex.CS));
             PC += 2; // advance PC two bytes because we're reading an immediate value.
             break;
         default: // $8-$F are Indirect Indexed operations.
             int indexRegister = addressingMode; // bit pattern is 01ii, indicating r4 - r7.
             destAddress = (ushort)(R[(int)source] + R[indexRegister]);
             break;
     }
 }
Пример #17
0
 private void BitPatternSTK(ushort operand, out ushort value, out RegGeneral destination)
 {
     destination = RegGeneral.None; // unused
     value       = (ushort)(operand & 0xFF01);
 }
Пример #18
0
 private void BitPatternIMM(ushort operand, out ushort value, out RegGeneral destination)
 {
     destination = (RegGeneral)((operand & 0xE000) >> 13);
     value = (ushort)(((operand & 0x1F00) >> 8) + 1);
 }
Пример #19
0
 private void BitPatternIMM(ushort operand, out ushort value, out RegGeneral destination)
 {
     destination = (RegGeneral)((operand & 0xE000) >> 13);
     value       = (ushort)(((operand & 0x1F00) >> 8) + 1);
 }
Пример #20
0
 private string NameOfRegGP(RegGeneral register)
 {
     switch (register) {
         case RegGeneral.R0:
             return "R0";
         case RegGeneral.R1:
             return "R1";
         case RegGeneral.R2:
             return "R2";
         case RegGeneral.R3:
             return "R3";
         case RegGeneral.R4:
             return "R4";
         case RegGeneral.R5:
             return "R5";
         case RegGeneral.R6:
             return "R6";
         case RegGeneral.R7:
             return "R7";
         default:
             return "??";
     }
 }
Пример #21
0
        private string DisassembleALU(string name, ushort operand, ushort nextword, ushort address, bool showMemoryContents, out ushort instructionSize)
        {
            int          addressingmode = (operand & 0x7000) >> 12;
            RegGeneral   regDest        = (RegGeneral)(operand & 0x0007);
            RegGeneral   regSrc         = (RegGeneral)((operand & 0x0E00) >> 9);
            bool         isEightBit     = (operand & 0x0100) != 0;
            SegmentIndex segData        = (operand & 0x8000) != 0 ? SegmentIndex.ES : SegmentIndex.DS;

            switch (addressingmode)
            {
            case 0:
                if (regSrc == 0)     // immediate
                {
                    if (name == "STO")
                    {
                        instructionSize = 2;
                        return("???");
                    }
                    instructionSize = 4;
                    string disasm =
                        $"{name + (isEightBit ? ".8" : string.Empty),-8}{NameOfRegGP(regDest)}, ${nextword:X4}";
                    if (showMemoryContents)
                    {
                        disasm = AppendMemoryContents(disasm, nextword);
                    }
                    return(disasm);
                }
                if ((int)regSrc == 1)     // absolute
                {
                    instructionSize = 4;
                    string disasm =
                        $"{name + (isEightBit ? ".8" : string.Empty),-8}{NameOfRegGP(regDest)}, [${nextword:X4}]";
                    if (showMemoryContents)
                    {
                        disasm = AppendMemoryContents(disasm, DebugReadMemory(nextword, segData));
                    }
                    return(disasm);
                }
                else     // control register
                {
                    instructionSize = 2;
                    RegControl cr     = (RegControl)((operand & 0x0700) >> 8);
                    string     disasm = $"{name,-8}{NameOfRegGP(regDest)}, {NameOfRegSP(cr)}";
                    if (showMemoryContents)
                    {
                        disasm = AppendMemoryContents(disasm, nextword);
                    }
                    return(disasm);
                }

            case 1:     // Register
                instructionSize = 2;
                return
                    ($"{name + (isEightBit ? ".8" : string.Empty),-8}{NameOfRegGP(regDest)}, {NameOfRegGP(regSrc),-12}(${R[(int)regSrc]:X4})");

            case 2:     // Indirect
                instructionSize = 2;
                return
                    ($"{name + (isEightBit ? ".8" : string.Empty),-8}{NameOfRegGP(regDest)}, [{NameOfRegGP(regSrc)}]        (${DebugReadMemory(R[(int)regSrc], segData):X4})");

            case 3:     // Indirect Offset (also Absolute Offset)
                instructionSize = 4;
                return
                    ($"{name + (isEightBit ? ".8" : string.Empty),-8}{NameOfRegGP(regDest)}, [{NameOfRegGP(regSrc)},${nextword:X4}]  (${DebugReadMemory((ushort)(R[(int)regSrc] + nextword), segData):X4})");

            default:     // $4 - $7 are Indirect Indexed
                instructionSize = 2;
                RegGeneral regIndex = (RegGeneral)((operand & 0x7000) >> 12);
                return
                    ($"{name + (isEightBit ? ".8" : string.Empty),-8}{NameOfRegGP(regDest)}, [{NameOfRegGP(regSrc)},{NameOfRegGP(regIndex)}]     (${DebugReadMemory((ushort)(R[(int)regSrc] + R[(int)regIndex]), segData):X4})");
            }
        }
Пример #22
0
 private void BitPatternSET(ushort operand, out ushort value, out RegGeneral destination)
 {
     destination = (RegGeneral)((operand & 0xE000) >> 13);
     value = (ushort)((operand & 0x1F00) >> 8);
     if ((operand & 0x0001) == 1) {
         if (value <= 0x0A)
             value = (ushort)(0x0001 << (value + 0x05));
         else
             value = (ushort)(0xFFE0 + value);
     }
 }
Пример #23
0
 private void BitPatternFLG(ushort operand, out ushort value, out RegGeneral destination)
 {
     destination = RegGeneral.None; // unused
     value = (ushort)(operand & 0xF000); // flags to set
 }
Пример #24
0
 private void BitPatternFLG(ushort operand, out ushort value, out RegGeneral destination)
 {
     destination = RegGeneral.None;            // unused
     value       = (ushort)(operand & 0xF000); // flags to set
 }
Пример #25
0
 private void BitPatternHWQ(ushort operand, out ushort value, out RegGeneral destination)
 {
     destination = RegGeneral.None; // Unused.
     value       = (ushort)((operand & 0xFF00) >> 8);
 }
Пример #26
0
 private void BitPatternBRA(ushort operand, out ushort value, out RegGeneral destination)
 {
     destination = RegGeneral.None; // not used
     value = (ushort)((operand & 0xFF00) >> 7); // (shift 8 - 1) to multiply result by two, per spec.
 }
Пример #27
0
        private void BitPatternJMI(ushort operand, out ushort address, out uint addressFar, out bool isFarJump)
        {
            ushort nextword;

            // Decode the operand word's constituent bits.             FEDC BA98 7654 3210
            //                                                         SAAA rrrF OOOO ORRR
            int          addressingMode = (operand & 0x7000) >> 12;
            RegGeneral   source         = (RegGeneral)((operand & 0x0E00) >> 9);
            SegmentIndex dataSeg        = (operand & 0x8000) != 0 ? SegmentIndex.ES : SegmentIndex.DS;

            addressFar = 0;
            isFarJump  = (operand & 0x0100) != 0; // F = far jump mode
            switch (addressingMode)               // will always be between 0x0 and 0xf
            {
            case 0:                               // Immediate (r == 0) or Absolute (r == 1)
                if (source == 0)
                {
                    address = ReadMemInt16(PC, SegmentIndex.CS);
                    PC     += 2; // advance PC two bytes because we're reading an immediate value.
                    if (isFarJump)
                    {
                        addressFar  = ReadMemInt16(PC, SegmentIndex.CS);
                        PC         += 2; // advance PC two bytes because we're reading an immediate value.
                        addressFar |= (uint)ReadMemInt16(PC, SegmentIndex.CS) << 16;
                        PC         += 2; // advance PC two bytes because we're reading an immediate value.
                    }
                }
                else
                {
                    nextword = ReadMemInt16(PC, SegmentIndex.CS);
                    PC      += 2; // advance PC two bytes because we're reading an immediate value.
                    address  = ReadMemInt16(nextword, dataSeg);
                    if (isFarJump)
                    {
                        addressFar  = ReadMemInt16((ushort)(nextword + 2), dataSeg);
                        addressFar |= (uint)ReadMemInt16((ushort)(nextword + 4), dataSeg) << 16;
                    }
                }
                break;

            case 1:     // Register
                address = R[(int)source];
                break;

            case 2:     // Indirect
                address = ReadMemInt16(R[(int)source], dataSeg);
                if (isFarJump)
                {
                    addressFar  = ReadMemInt16((ushort)(R[(int)source] + 2), dataSeg);
                    addressFar |= (uint)ReadMemInt16((ushort)(R[(int)source] + 4), dataSeg) << 16;
                }
                break;

            case 3:           // Indirect Offset AKA Absolute Offset
                nextword = ReadMemInt16(PC, SegmentIndex.CS);
                PC      += 2; // advance PC two bytes because we're reading an immediate value.
                address  = ReadMemInt16((ushort)(R[(int)source] + nextword), dataSeg);
                if (isFarJump)
                {
                    addressFar  = ReadMemInt16((ushort)(R[(int)source] + nextword + 2), dataSeg);
                    addressFar |= (uint)ReadMemInt16((ushort)(R[(int)source] + nextword + 4), dataSeg) << 16;
                }
                break;

            default:                                          // 0x04 - 0x07 are Indirect Indexed
                int indexRegister = (operand & 0x7000) >> 12; // bit pattern is 1ii, indicating R4 - R7
                address = ReadMemInt16((ushort)(R[(int)source] + R[indexRegister]), dataSeg);
                if (isFarJump)
                {
                    addressFar  = ReadMemInt16((ushort)(R[(int)source] + R[indexRegister] + 2), dataSeg);
                    addressFar |= (uint)ReadMemInt16((ushort)(R[(int)source] + R[indexRegister] + 4), dataSeg) << 16;
                }
                break;
            }
        }
Пример #28
0
 private void BitPatternHWQ(ushort operand, out ushort value, out RegGeneral destination)
 {
     destination = RegGeneral.None; // Unused.
     value = (ushort)((operand & 0xFF00) >> 8);
 }