⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cputhumbcore.pas

📁 一个不出名的GBA模拟器
💻 PAS
📖 第 1 页 / 共 2 页
字号:
            //  4 in all other cases.
            test := regs[(t shr 3) and 7];
            if test shr 31 <> 0 then test := not test;
            if test and $FFFFFF00 = 0 then
              c := 1
            else if test and $FFFF0000 = 0 then
              c := 2
            else if test and $FF000000 = 0 then
              c := 3
            else
              c := 4;
            Dec(quota, c*cycI);

            // Do the actual multiply
            test := regs[(t shr 3) and 7] * regs[t and 7];
            regs[t and 7] := test;

            // Test flags
            negative := test shr 31 <> 0;
            zero := test = 0;
          end;
          $E: begin
            // bic Rd, Rs
            test := regs[t and 7] and not regs[(t shr 3) and 7];
            regs[t and 7] := test;
          end;
          $F: begin
            // mvn Rd, Rs
            test := not regs[(t shr 3) and 7];
            regs[t and 7] := test;
          end;
        else
          test := 0; // shaddup
        end;

        negative := test shr 31 <> 0;
        zero := test = 0;
      end;

      $44: begin
        // Format 5: Hi register add, [add Rd/Hd, Hs/Rs]  (both low is undefined)
        case (t shr 6) and 3 of
          1: begin
            operand1 := t and 7;
            regs[operand1] := regs[operand1] + regs[(t shr 3) and 7 + 8];
          end;
          2: begin
            operand1 := t and 7 + 8;
            regs[operand1] := regs[operand1] + regs[(t shr 3) and 7];
            if operand1 = 15 then FlushPipeThumb;
          end;
          3: begin
            operand1 := t and 7 + 8;
            regs[operand1] := regs[operand1] + regs[(t shr 3) and 7 + 8];
            if operand1 = 15 then FlushPipeThumb;
          end;
        end;
      end;

      $45: begin
        // Format 5: Hi register compare, [cmp Rd/Hd, Hs/Rs]  (both low is undefined)
        case (t shr 6) and 3 of
          1: begin
            operand1 := regs[t and 7];
            operand2 := regs[(t shr 3) and 7 + 8];
          end;
          2: begin
            operand1 := regs[t and 7 + 8];
            operand2 := regs[(t shr 3) and 7];
          end;
          3: begin
            operand1 := regs[t and 7 + 8];
            operand2 := regs[(t shr 3) and 7 + 8];
          end;
        else
          UndefinedState('Thumb format 5: H1 and H2 = 0');
          operand1 := 0;
          operand2 := 0;
        end;

        test := operand1 - operand2;
        neg1 := operand1 shr 31 <> 0;
        neg2 := operand2 shr 31 <> 0;
        negative := test shr 31 <> 0;
        carry := (neg1 and not neg2) or (neg1 and not negative) or (not neg2 and not negative);
        overflow := (neg1 and not neg2 and not negative) or (not neg1 and neg2 and negative);
        zero := test = 0;
      end;

      $46: begin
        // Format 5: Hi register move, [mov Rd/Hd, Hs/Rs]  (both low is undefined)
        case (t shr 6) and 3 of
          1: regs[t and 7] := regs[(t shr 3) and 7 + 8];
          2: begin
            Rd := t and 7 + 8;
            regs[Rd] := regs[(t shr 3) and 7];
            if Rd = 15 then begin
              regs[R15] := regs[R15] and not 1;
              FlushPipeThumb;
            end;
          end;
          3: begin
            Rd := t and 7 + 8;
            regs[Rd] := regs[(t shr 3) and 7 + 8];
            if Rd = 15 then begin
              regs[R15] := regs[R15] and not 1;
              FlushPipeThumb;
            end;
          end;
        end;
      end;

      $47: begin
        // Format 5: Branch and exchange, [bx Rs/Hs]  (H1=1 is undefined)
        case (t shr 6) and 3 of
          0: Rd := (t shr 3) and 7;
          1: Rd := (t shr 3) and 7 + 8;
        else
          Rd := 0;
        end;

        // Using R15 as an operand
        thumbMode := regs[Rd] and 1 <> 0;
        regs[R15] := regs[Rd] and not 1;
        if thumbMode then FlushPipeThumb else FlushPipeARM;
      end;

      $48..$4F: begin
        // Format 6: PC-relative load, [ldr Rd, [PC, #Imm]]
        regs[c and 7] := memReadWord((regs[R15] and $FFFFFFFC) + (t and $FF) shl 2);
        Dec(quota, cycI);
      end;

      $50..$51: begin
        // Format 7: Store with register offset, [str Rd, [Rb, Ro]]
        memWriteWord(regs[(t shr 3) and 7] + regs[(t shr 6) and 7], regs[t and 7]);
      end;

      $52..$53: begin
        // Format 8: Store halfword, [strh Rd, [Rb, Ro]]
        memWriteHalfWord(regs[(t shr 3) and 7] + regs[(t shr 6) and 7], regs[t and 7]);
      end;

      $54..$55: begin
        // Format 7: Store byte with register offset, [strb Rd, [Rb, Ro]]
        memWriteByte(regs[(t shr 3) and 7] + regs[(t shr 6) and 7], regs[t and 7]);
      end;

      $56..$57: begin
        // Format 8: Load signed byte, [ldrsb Rd, [Rb, Ro]]
        test := memReadByte(regs[(t shr 3) and 7] + regs[(t shr 6) and 7]);
        if test shr 7 <> 0 then test := test or $FFFFFF00;
        regs[t and 7] := test;
        Dec(quota, cycI);
      end;

      $58..$59: begin
        // Format 7: Load with register offset, [ldr Rd, [Rb, Ro]]
        regs[t and 7] := memReadWord(regs[(t shr 3) and 7] + regs[(t shr 6) and 7]);
        Dec(quota, cycI);
      end;

      $5A..$5B: begin
        // Format 8: Load halfword, [ldrh Rd, [Rb, Ro]]
        regs[t and 7] := memReadHalfWord(regs[(t shr 3) and 7] + regs[(t shr 6) and 7]);
        Dec(quota, cycI);
      end;

      $5C..$5D: begin
        // Format 7: Load byte with register offset, [ldrb Rd, [Rb, Ro]]
        regs[t and 7] := memReadByte(regs[(t shr 3) and 7] + regs[(t shr 6) and 7]);
        Dec(quota, cycI);
      end;

      $5E..$5F: begin
        // Format 8: Load signed halfword, [ldrsh Rd, [Rb, Ro]]
        test := memReadHalfWord(regs[(t shr 3) and 7] + regs[(t shr 6) and 7]);
        if test shr 15 <> 0 then test := test or $FFFF0000;
        regs[t and 7] := test;
        Dec(quota, cycI);
      end;

      $60..$67: begin
        // Format 9: Store with immediate offset, [str Rd, [Rb, #Imm]]
        memWriteWord(regs[(t shr 3) and 7] + ((t shr 6) and $1F) shl 2, regs[t and 7]);
      end;

      $68..$6F: begin
        // Format 9: Load with immediate offset, [ldr Rd, [Rb, #Imm]]
        regs[t and 7] := memReadWord(regs[(t shr 3) and 7] + ((t shr 6) and $1F) shl 2);
        Dec(quota, cycI);
      end;

      $70..$77: begin
        // Format 9: Store byte with immediate offset, [strb Rd, [Rb, #Imm]]
        memWriteByte(regs[(t shr 3) and 7] + ((t shr 6) and $1F), regs[t and 7]);
      end;

      $78..$7F: begin
        // Format 9: Load byte with immediate offset, [ldrb Rd, [Rb, #Imm]]
        regs[t and 7] := memReadByte(regs[(t shr 3) and 7] + ((t shr 6) and $1F));
        Dec(quota, cycI);
      end;

      $80..$87: begin
        // Format 10: Store halfword, [strh Rd, [Rb, #Imm]]
        memWriteHalfWord(regs[(t shr 3) and 7] + ((t shr 6) and $1F) shl 1, regs[t and 7]);
      end;

      $88..$8F: begin
        // Format 10: Load halfword, [ldrh Rd, [Rb, #Imm]]
        regs[t and 7] := memReadHalfWord(regs[(t shr 3) and 7] + ((t shr 6) and $1F) shl 1);
        Dec(quota, cycI);
      end;

      $90..$97: begin
        // Format 11: SP-relative store, [str Rd, [SP, #Imm]]
        memWriteWord(regs[R13] + (t and $FF) shl 2, regs[c and 7]);
      end;

      $98..$9F: begin
        // Format 11: SP-relative load, [ldr Rd, [SP, #Imm]]
        regs[c and 7] := memReadWord(regs[R13] + (t and $FF) shl 2);
        Dec(quota, cycI);
      end;

      $A0..$A7: begin
        // Format 12: Load address, [add Rd, PC, #Imm]
        regs[c and 7] := (regs[R15] and $FFFFFFFC) + (t and $FF) shl 2;
      end;

      $A8..$AF: begin
        // Format 12: Load address, [add Rd, SP, #Imm]
        regs[c and 7] := regs[R13] + (t and $FF) shl 2;
      end;

      $B0: begin
        // Format 13: Add offset to stack pointer [add SP, #+/-Imm]
        test := (t and $7F) shl 2;
        if t and (1 shl 7) <> 0 then Dec(regs[R13], test) else Inc(regs[R13], test);
      end;

      $B1..$B3, $B6..$BB, $BE..$BF, $E8..$EF: begin
        // Undefined Opcode
        UndefinedOpcode;
      end;

      $B4: begin
        // Format 14: push {rlist}
        for i := 7 downto 0 do
          if t and (1 shl i) <> 0 then begin
            Dec(regs[R13], 4);
            memWriteWord(regs[R13], regs[i]);
          end;
      end;

      $B5: begin
        // Format 14: push {rlist,LR}
        Dec(regs[R13], 4);
        memWriteWord(regs[R13], regs[R14]);
        for i := 7 downto 0 do
          if t and (1 shl i) <> 0 then begin
            Dec(regs[R13], 4);
            memWriteWord(regs[R13], regs[i]);
          end;
      end;

      $BC: begin
        // Format 14: pop {rlist}
        for i := 0 to 7 do
          if t and (1 shl i) <> 0 then begin
            regs[i] := memReadWord(regs[R13]);
            Inc(regs[R13], 4);
          end;

        Dec(quota, cycI);
      end;

      $BD: begin
        // Format 14: pop {rlist, PC}
        for i := 0 to 7 do
          if t and (1 shl i) <> 0 then begin
            regs[i] := memReadWord(regs[R13]);
            Inc(regs[R13], 4);
          end;

        regs[R15] := memReadWord(regs[R13]);
        Inc(regs[R13], 4);

        FlushPipeThumb;
        Dec(quota, cycI);
      end;

      $C0..$C7: begin
        // Format 15: stmia Rb!, {rlist}
        for i := 0 to 7 do
          if t and (1 shl i) <> 0 then begin
            memWriteWord(regs[c and 7], regs[i]);
            Inc(regs[c and 7], 4);
          end;
      end;

      $C8..$CF: begin
        // Format 15: ldmia Rb!, {rlist}
        for i := 0 to 7 do
          if t and (1 shl i) <> 0 then begin
            regs[i] := memReadWord(regs[c and 7]);
            Inc(regs[c and 7], 4);
          end;

        Dec(quota, cycI);
      end;

      $D0..$DE: begin
        // Format 16: Conditionial branch, [bXX label]
        rs := c and $F;
        {$I incTestCond.pas}
        if cond then begin
          test := t and $FF;
          if test shr 7 <> 0 then test := test or $FFFFFF00;
          Inc(regs[R15], test shl 1);
          FlushPipeThumb;
        end;
      end;

      $DF: begin
        // Format 17: Software Interrupt, [swi value8]
        cpuCurrentOpcode := t;
        SoftwareInterrupt;
      end;

      $E0..$E7: begin
        // Format 18: Unconditional branch, [b label]
        test := t and $7FF;
        if test shr 10 <> 0 then test := test or $FFFFF800;
        Inc(regs[R15], test shl 1);
        FlushPipeThumb;
      end;

      $F0..$F7: begin
        // Format 19: Long branch with link (hw1), [part one of bl label]
        test := t and $7FF;
        if test shr 10 <> 0 then test := test or $FFFFF800;
        regs[R14] := regs[R15] + test shl 12;
      end;

      $F8..$FF: begin
        // Format 19: Long branch with link (hw2), [part two of bl label]
        test := t and $7FF;

        operand1 := regs[R15] - 2;
        regs[R15] := regs[R14] + test shl 1;
        regs[R14] := operand1 or 1;

        FlushPipeThumb;
      end;
    end;

    // Check for a breakpoint
    if memStopAtAddy(regs[R15] - 2) then begin
      hitBreakpoint := true;
      Exit;
    end;
  until (quota <= 0) or not thumbMode;

  // Check for a breakpoint on the next opcode
  if (not thumbMode) and not haveFlippedThumb then
    hitBreakpoint := memStopAtAddy(regs[R15] - 4);
end;

//////////////////////////////////////////////////////////////////////

end.

//////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -