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

📄 cpumemory.pas

📁 一个不出名的GBA模拟器
💻 PAS
📖 第 1 页 / 共 5 页
字号:
  Dec(quota, 6);
  Result := Puint32(@(exWRAM[address and EX_WRAM_MASK]))^;
end;

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

procedure WriteExWRAM_08(address, data: uint32);
begin
  Dec(quota, 3);
  exWRAM[address and EX_WRAM_MASK] := data;
end;

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

procedure WriteExWRAM_16(address, data: uint32);
begin
  Dec(quota, 3);
  Puint16(@(exWRAM[address and EX_WRAM_MASK]))^ := data;
end;

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

procedure WriteExWRAM_32(address, data: uint32);
begin
  Dec(quota, 6);
  Puint32(@(exWRAM[address and EX_WRAM_MASK]))^ := data;
end;

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

function ReadWRAM_08(address: uint32): uint32;
begin
  Dec(quota);
  Result := WRAM[address and WRAM_MASK];
end;

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

function ReadWRAM_16(address: uint32): uint32;
begin
  Dec(quota);
  Result := Puint16(@(WRAM[address and WRAM_MASK]))^;
end;

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

function ReadWRAM_32(address: uint32): uint32;
begin
  Dec(quota);
  Result := Puint32(@(WRAM[address and WRAM_MASK]))^;
end;

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

procedure WriteWRAM_08(address, data: uint32);
begin
  Dec(quota);
  WRAM[address and WRAM_MASK] := data;
end;

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

procedure WriteWRAM_16(address, data: uint32);
begin
  Dec(quota);
  Puint16(@(WRAM[address and WRAM_MASK]))^ := data;
end;

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

procedure WriteWRAM_32(address, data: uint32);
begin
  Dec(quota);
  Puint32(@(WRAM[address and WRAM_MASK]))^ := data;
end;

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

function ReadIO_08(address: uint32): uint32;
begin
  Dec(quota);
  address := address and REGISTERS_MASK;
  case address of
    // DMA source and dests always read $91009100 (test 3)
    $0B0, $0B2, $0B4, $0B6, $0BC, $0BE, $0C0, $0C2,
    $0C8, $0CA, $0CC, $0CE, $0D4, $0D6, $0D8, $0DA: Result := $00;
    $0B1, $0B3, $0B5, $0B7, $0BD, $0BF, $0C1, $0C3,
    $0C9, $0CB, $0CD, $0CF, $0D5, $0D7, $0D9, $0DB: Result := $91;

    // DMA count registers always read 0
    $0B8, $0B9, $0C4, $0C5, $0D0, $0D1, $0DC, $0DD: Result := $00;

    // BLEND_CR bits 14-15 are fixed at 0
    $051: Result := registers[$051] and $3F;

    // BLEND_A bits 5-7 are fixed at 0
    $052: Result := registers[$052] and $1F;

    // BLEND_B bits 5-7 are fixed at 0
    $053: Result := registers[$053] and $1F;

    // BLEND_Y appears to return $881B when I write $FFFF
    $054: Result := registers[$054] and $1B;
    $055: Result := registers[$055] and $88;

    // Timer CR high order regs are fixed at 0
    $103, $107, $10B, $10F: Result := 0;

    // Timer CR bits 3-5 are fixed at 0
    $102, $106, $10A, $10E: Result := registers[address] and $C7;

    // Write-only registers that are still untested
    $010..$047, $04C..$04D, $056..$05F, $0A0..$0AF: Result := 0;

    // Timer counter reads require flushing the timer values
    TIMER0: begin
      flushTimers;
      Result := Puint16(@(registers[TIMER0]))^ and $FF;
    end;
    TIMER0+1: begin
      flushTimers;
      Result := Puint16(@(registers[TIMER0]))^ shr 8;
    end;
    TIMER1: begin
      flushTimers;
      Result := Puint16(@(registers[TIMER1]))^ and $FF;
    end;
    TIMER1+1: begin
      flushTimers;
      Result := Puint16(@(registers[TIMER1]))^ shr 8;
    end;
    TIMER2: begin
      flushTimers;
      Result := Puint16(@(registers[TIMER2]))^ and $FF;
    end;
    TIMER2+1: begin
      flushTimers;
      Result := Puint16(@(registers[TIMER2]))^ shr 8;
    end;
    TIMER3: begin
      flushTimers;
      Result := Puint16(@(registers[TIMER3]))^ and $FF;
    end;
    TIMER3+1: begin
      flushTimers;
      Result := Puint16(@(registers[TIMER3]))^ shr 8;
    end;

    KEYS: Result := downkeys and $FF;
    KEYS+1: Result := (downkeys shr 8) and $3;

    SOUND_ENABLED: begin
      Result := registers[SOUND_ENABLED] and 128;
      if sound1.enabled then Result := Result or 1;
      if sound2.enabled then Result := Result or 2;
      if sound3.enabled then Result := Result or 4;
      if sound4.enabled then Result := Result or 8;
    end;
  else
    Result := registers[address];
  end;
end;

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

function ReadIO_16(address: uint32): uint32;
begin
  Dec(quota);
  address := address and REGISTERS_MASK;
  case address of
    // DMA source and dests always read $91009100 (test 3)
    $0B0, $0B2, $0B4, $0B6, $0BC, $0BE, $0C0, $0C2,
    $0C8, $0CA, $0CC, $0CE, $0D4, $0D6, $0D8, $0DA: Result := $9100;

    // DMA count registers always read 0
    $0B8, $0C4, $0D0, $0DC: Result := $00;

    // BLEND_CR bits 14-15 are fixed at 0
    $050: Result := Puint16(@(registers[$050]))^ and $3FFF;

    // BLEND_A bits 5-7 are fixed at 0, BLEND_B bits 5-7 are fixed at 0
    $052: Result := Puint16(@(registers[$052]))^ and $1F1F;

    // BLEND_Y appears to return $881B when I write $FFFF
    $054: Result := Puint16(@(registers[$054]))^ and $881B;

    // Timer CR bits 3-5,8-15 are fixed at 0
    $102, $106, $10A, $10E: Result := registers[address] and $C7;

    // Write-only registers that are still untested
    $010..$046, $04C, $056..$05E, $0A0..$0AE: Result := 0;

    // Timer counter reads require flushing the timer values
    TIMER0: begin
      flushTimers;
      Result := Puint16(@(registers[TIMER0]))^;
    end;
    TIMER1: begin
      flushTimers;
      Result := Puint16(@(registers[TIMER1]))^;
    end;
    TIMER2: begin
      flushTimers;
      Result := Puint16(@(registers[TIMER2]))^;
    end;
    TIMER3: begin
      flushTimers;
      Result := Puint16(@(registers[TIMER3]))^;
    end;

    KEYS: Result := downkeys and $3FF;
    SOUND_ENABLED: begin
      Result := Puint16(@(registers[SOUND_ENABLED]))^ and 128;
      if sound1.enabled then Result := Result or 1;
      if sound2.enabled then Result := Result or 2;
      if sound3.enabled then Result := Result or 4;
      if sound4.enabled then Result := Result or 8;
    end;
  else
    Result := Puint16(@(registers[address]))^;
  end;
end;

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

function ReadIO_32(address: uint32): uint32;
begin
  Dec(quota);
  address := address and REGISTERS_MASK;

  case address of
    // DMA source and dests always read $91009100 (test 3)
    $0B0, $0B4, $0BC, $0C0, $0C8, $0CC, $0D4, $0D8: Result := $91009100;

    // BLEND_CR bits 14-15 are fixed at 0, BLEND_A bits 5-7 are fixed at 0, BLEND_B bits 5-7 are fixed at 0
    $050: Result := Puint32(@(registers[$050]))^ and $1F1F3FFF;

    // BLEND_Y appears to return $881B when I write $FFFF, and I'll guess the rest of the bits are 0
    $054: Result := Puint16(@(registers[$054]))^ and $881B;

    // Write-only registers that are still untested, but are adjacent to valid regs
    $010..$040, $0A0..$0AC: Result := 0;

    $044, $04C: Result := Puint32(@(registers[address]))^ and $FFFF0000;

    // Half of this is the CR and half the count, the cr is valid, but count reads 0
    $0B8, $0C4, $0D0, $0DC: Result := Puint32(@(registers[address]))^ and $FFFF0000;

    // Timer counter reads require flushing the timer values, and timer CR bits 3-5,8-15 are fixed at 0
    TIMER0: begin
      flushTimers;
      Result := Puint32(@(registers[address]))^ and $00C7FFFF;
    end;
    TIMER1: begin
      flushTimers;
      Result := Puint32(@(registers[address]))^ and $00C7FFFF;
    end;
    TIMER2: begin
      flushTimers;
      Result := Puint32(@(registers[address]))^ and $00C7FFFF;
    end;
    TIMER3: begin
      flushTimers;
      Result := Puint32(@(registers[address]))^ and $00C7FFFF;
    end;
    KEYS: Result := downkeys and $3FF;
    SOUND_ENABLED: begin
      Result := Puint32(@(registers[SOUND_ENABLED]))^ and ($FFFF0000+128);
      if sound1.enabled then Result := Result or 1;
      if sound2.enabled then Result := Result or 2;
      if sound3.enabled then Result := Result or 4;
      if sound4.enabled then Result := Result or 8;
    end;
  else
    Result := Puint32(@(registers[address]))^;
  end;
end;

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

procedure WriteIO_08(address, data: uint32);
begin
  Dec(quota);
  address := address and REGISTERS_MASK;

  // Log it if we want to
  if logIORegisters then
    LogWriteLn(Format(' u8[$%3.3x]=$%2.2x', [address, data]));

  case address of
    BG2_X..BG2_X+3: begin
      registers[address] := data;
      registers[BG2_X_DIRTY] := 1;
      if (Puint32(@(registers[BG2_X]))^ shr 27) and 1 <> 0 then
        Puint32(@(registers[BG2_X]))^ := Puint32(@(registers[BG2_X]))^ or $F0000000;
      Puint32(@(registers[BG2_X_LATCH]))^ := Puint32(@(registers[BG2_X]))^;
    end;
    BG2_Y..BG2_Y+3: begin
      registers[address] := data;
      registers[BG2_Y_DIRTY] := 1;
      if (Puint32(@(registers[BG2_Y]))^ shr 27) and 1 <> 0 then
        Puint32(@(registers[BG2_Y]))^ := Puint32(@(registers[BG2_Y]))^ or $F0000000;
      Puint32(@(registers[BG2_Y_LATCH]))^ := Puint32(@(registers[BG2_Y]))^;
    end;
    BG3_X..BG3_X+3: begin
      registers[address] := data;
      registers[BG3_X_DIRTY] := 1;
      if (Puint32(@(registers[BG3_X]))^ shr 27) and 1 <> 0 then
        Puint32(@(registers[BG3_X]))^ := Puint32(@(registers[BG3_X]))^ or $F0000000;
      Puint32(@(registers[BG3_X_LATCH]))^ := Puint32(@(registers[BG3_X]))^;
    end;
    BG3_Y..BG3_Y+3: begin
      registers[address] := data;
      registers[BG3_Y_DIRTY] := 1;
      if (Puint32(@(registers[BG3_Y]))^ shr 27) and 1 <> 0 then
        Puint32(@(registers[BG3_Y]))^ := Puint32(@(registers[BG3_Y]))^ or $F0000000;
      Puint32(@(registers[BG3_X_LATCH]))^ := Puint32(@(registers[BG3_Y]))^;
    end;

    TIMER0, TIMER0+1, TIMER1, TIMER1+1, TIMER2, TIMER2+1, TIMER3, TIMER3+1: registers[address+$400] := data;

    TIMER0_CR: begin
      registers[address] := data;
      WriteTimerCR(0);
    end;
    TIMER1_CR: begin
      registers[address] := data;
      WriteTimerCR(1);
    end;
    TIMER2_CR: begin
      registers[address] := data;
      WriteTimerCR(2);
    end;
    TIMER3_CR: begin
      registers[address] := data;
      WriteTimerCR(3);
    end;
    KEYS..KEYS+1: ;
    DMA0_CR+1: begin
      registers[address] := data;
      if Puint16(@(registers[DMA0_CR]))^ and (1 shl 15) <> 0 then InitiateDMATransfer(0);
    end;
    DMA1_CR: begin
      registers[address] := data;
      if Puint16(@(registers[DMA1_CR]))^ and (1 shl 15) <> 0 then InitiateDMATransfer(1);
    end;
    DMA2_CR: begin
      registers[address] := data;
      if Puint16(@(registers[DMA2_CR]))^ and (1 shl 15) <> 0 then InitiateDMATransfer(2);
    end;
    DMA3_CR: begin
      registers[address] := data;
      if Puint16(@(registers[DMA3_CR]))^ and (1 shl 15) <> 0 then InitiateDMATransfer(3);
    end;
    IRQ_FLAGS: Puint16(@(registers[IRQ_FLAGS]))^ := Puint16(@(registers[IRQ_FLAGS]))^ and not data;
    IRQ_FLAGS+1: Puint16(@(registers[IRQ_FLAGS]))^ := Puint16(@(registers[IRQ_FLAGS]))^ and not (data shl 8);
    WAIT_STATE_CR: begin
      registers[address] := data;
      SetWaitStates;
    end;
    WAIT_STATE_CR+1: begin
      registers[address] := data and $3F;
      SetWaitStates;
    end;

    SOUND1_SWEEP: begin
      soundChanging;
      registers[address] := data;
      soundSetSound1Sweep;
    end;
    SOUND1_LENGTH..SOUND1_LENGTH+1: begin
      soundChanging;
      registers[address] := data;
      soundSetSound1Length;
    end;
    SOUND1_FREQUENCY..SOUND1_FREQUENCY+1: begin
      soundChanging;
      registers[address] := data;
      soundSetSound1Freq;
    end;

    SOUND2_LENGTH..SOUND2_LENGTH+1: begin
      soundChanging;
      registers[address] := data;
      soundSetSound2Length;
    end;
    SOUND2_FREQUENCY..SOUND2_FREQUENCY+1: begin
      soundChanging;
      registers[address] := data;
      soundSetSound2Freq;
    end;

    SOUND3_CR: begin
      soundChanging;
      registers[address] := data;
      soundSetSound3CR;
    end;
    SOUND3_LENGTH..SOUND3_VOLUME: begin
      soundChanging;
      registers[address] := data;
      soundSetSound3Length;
    end;
    SOUND3_FREQUENCY: begin

⌨️ 快捷键说明

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