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

📄 cpumemory.pas

📁 一个不出名的GBA模拟器
💻 PAS
📖 第 1 页 / 共 5 页
字号:
      soundChanging;
      registers[address] := data;
      soundSetSound3Freq;
    end;

    SOUND4_LENGTH..SOUND4_LENGTH+1: begin
      soundChanging;
      registers[address] := data;
      soundSetSound4Length;
    end;
    SOUND4_CR..SOUND4_CR+1: begin
      soundChanging;
      registers[address] := data;
      soundSetSound4CR;
    end;

    SOUNDA_FIFO..SOUNDA_FIFO+3: begin
      registers[address] := data;
      soundIncrementFifoA;
    end;
    SOUNDB_FIFO..SOUNDB_FIFO+3: begin
      registers[address] := data;
      soundIncrementFifoB;
    end;

    SOUND_DSOUND_CR, SOUND_DSOUND_CR+1: begin
      soundChanging;
      registers[address] := data;
      soundWriteDSoundCR;
    end;

    $301: begin
      if data and $80 <> 0 then begin
        // Halt
        cpuStopped := true;
        cpuHalted := true;
        quota := 0;
      end else begin
        // Stop
        cpuStopped := true;
        quota := 0;
      end;
    end;
  else
    registers[address] := data;
  end;
end;

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

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

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

  case address of
    BG2_X, BG2_X+2: begin
      Puint16(@(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+2: begin
      Puint16(@(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+2: begin
      Puint16(@(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+2: begin
      Puint16(@(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_Y_LATCH]))^ := Puint32(@(registers[BG3_Y]))^;
    end;

    TIMER0: Puint16(@(registers[TIMER0_LATCH]))^ := data;
    TIMER1: Puint16(@(registers[TIMER1_LATCH]))^ := data;
    TIMER2: Puint16(@(registers[TIMER2_LATCH]))^ := data;
    TIMER3: Puint16(@(registers[TIMER3_LATCH]))^ := data;

    TIMER0_CR: begin
      Puint16(@(registers[address]))^ := data;
      WriteTimerCR(0);
    end;
    TIMER1_CR: begin
      Puint16(@(registers[address]))^ := data;
      WriteTimerCR(1);
    end;
    TIMER2_CR: begin
      Puint16(@(registers[address]))^ := data;
      WriteTimerCR(2);
    end;
    TIMER3_CR: begin
      Puint16(@(registers[address]))^ := data;
      WriteTimerCR(3);
    end;
    KEYS: ;
    DMA0_CR: begin
      Puint16(@(registers[address]))^ := data;
      if Puint16(@(registers[DMA0_CR]))^ and (1 shl 15) <> 0 then InitiateDMATransfer(0);
    end;
    DMA1_CR: begin
      Puint16(@(registers[address]))^ := data;
      if Puint16(@(registers[DMA1_CR]))^ and (1 shl 15) <> 0 then InitiateDMATransfer(1);
    end;
    DMA2_CR: begin
      Puint16(@(registers[address]))^ := data;
      if Puint16(@(registers[DMA2_CR]))^ and (1 shl 15) <> 0 then InitiateDMATransfer(2);
    end;
    DMA3_CR: begin
      Puint16(@(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;

    WAIT_STATE_CR: begin
      Puint16(@(registers[address]))^ := data and $3FFF;
      SetWaitStates;
    end;

    SOUND1_SWEEP: begin
      soundChanging;
      Puint16(@(registers[address]))^ := data;
      soundSetSound1Sweep;
    end;
    SOUND1_LENGTH: begin
      soundChanging;
      Puint16(@(registers[address]))^ := data;
      soundSetSound1Length;
    end;
    SOUND1_FREQUENCY: begin
      soundChanging;
      Puint16(@(registers[address]))^ := data;
      soundSetSound1Freq;
    end;

    SOUND2_LENGTH: begin
      soundChanging;
      Puint16(@(registers[address]))^ := data;
      soundSetSound2Length;
    end;
    SOUND2_FREQUENCY: begin
      soundChanging;
      Puint16(@(registers[address]))^ := data;
      soundSetSound2Freq;
    end;

    SOUND3_CR: begin
      soundChanging;
      Puint16(@(registers[address]))^ := data;
      soundSetSound3CR;
    end;
    SOUND3_LENGTH: begin
      soundChanging;
      Puint16(@(registers[address]))^ := data;
      soundSetSound3Length;
    end;
    SOUND3_FREQUENCY: begin
      soundChanging;
      Puint16(@(registers[address]))^ := data;
      soundSetSound3Freq;
    end;

    SOUND4_LENGTH: begin
      soundChanging;
      Puint16(@(registers[address]))^ := data;
      soundSetSound4Length;
    end;
    SOUND4_CR: begin
      soundChanging;
      Puint16(@(registers[address]))^ := data;
      soundSetSound4CR;
    end;

    SOUNDA_FIFO, SOUNDA_FIFO+2: begin
      Puint16(@(registers[address]))^ := data;
      soundIncrementFifoA;
    end;
    SOUNDB_FIFO, SOUNDB_FIFO+2: begin
      Puint16(@(registers[address]))^ := data;
      soundIncrementFifoB;
    end;

    SOUND_DSOUND_CR: begin
      soundChanging;
      Puint16(@(registers[address]))^ := data;
      soundWriteDSoundCR;
    end;

    $300: begin
      if data and $8000 <> 0 then begin
        // Halt
        cpuStopped := true;
        cpuHalted := true;
        quota := 0;
      end else begin
        // Stop
        cpuStopped := true;
        quota := 0;
      end;
    end;
  else
    Puint16(@(registers[address]))^ := data;
  end;
end;

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

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

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

  case address of
    BG2_X: begin
      Puint32(@(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: begin
      Puint32(@(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: begin
      Puint32(@(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: begin
      Puint32(@(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_Y_LATCH]))^ := Puint32(@(registers[BG3_Y]))^;
    end;                                                  

    KEYS: ;

    TIMER0: begin
      Puint16(@(registers[TIMER0_LATCH]))^ := data and $FFFF;
      Puint16(@(registers[TIMER0_CR]))^ := data shr 16;
      WriteTimerCR(0);
    end;
    TIMER1: begin
      Puint16(@(registers[TIMER1_LATCH]))^ := data and $FFFF;
      Puint16(@(registers[TIMER1_CR]))^ := data shr 16;
      WriteTimerCR(1);
    end;
    TIMER2: begin
      Puint16(@(registers[TIMER2_LATCH]))^ := data and $FFFF;
      Puint16(@(registers[TIMER2_CR]))^ := data shr 16;
      WriteTimerCR(2);
    end;
    TIMER3: begin
      Puint16(@(registers[TIMER3_LATCH]))^ := data and $FFFF;
      Puint16(@(registers[TIMER3_CR]))^ := data shr 16;
      WriteTimerCR(3);
    end;

    DMA0_COUNT: begin
      Puint32(@(registers[address]))^ := data;
      if Puint16(@(registers[DMA0_CR]))^ and (1 shl 15) <> 0 then InitiateDMATransfer(0);
    end;
    DMA1_COUNT: begin
      Puint32(@(registers[address]))^ := data;
      if Puint16(@(registers[DMA1_CR]))^ and (1 shl 15) <> 0 then InitiateDMATransfer(1);
    end;
    DMA2_COUNT: begin
      Puint32(@(registers[address]))^ := data;
      if Puint16(@(registers[DMA2_CR]))^ and (1 shl 15) <> 0 then InitiateDMATransfer(2);
    end;
    DMA3_COUNT: begin
      Puint32(@(registers[address]))^ := data;
      if Puint16(@(registers[DMA3_CR]))^ and (1 shl 15) <> 0 then InitiateDMATransfer(3);
    end;

    IRQ_ENABLED: begin
      Puint16(@(registers[address]))^ := data and $FFFF;
      Puint16(@(registers[IRQ_FLAGS]))^ := Puint16(@(registers[IRQ_FLAGS]))^ and not (data shr 16);
    end;

    WAIT_STATE_CR: begin
      Puint32(@(registers[address]))^ := data;
      Puint16(@(registers[WAIT_STATE_CR]))^ := Puint16(@(registers[WAIT_STATE_CR]))^ and $3FFF;
      SetWaitStates;
    end;

    SOUND1_SWEEP: begin
      soundChanging;
      Puint32(@(registers[address]))^ := data;
      soundSetSound1Sweep;
      soundSetSound1Length;
    end;
    SOUND1_FREQUENCY: begin
      soundChanging;
      Puint32(@(registers[address]))^ := data;
      soundSetSound1Freq;
    end;

    SOUND2_LENGTH: begin
      soundChanging;
      Puint32(@(registers[address]))^ := data;
      soundSetSound2Length;
      soundSetSound2Freq;
    end;

    SOUND3_CR: begin
      soundChanging;
      Puint32(@(registers[address]))^ := data;
      soundSetSound3CR;
      soundSetSound3Length;
    end;
    SOUND3_FREQUENCY: begin
      soundChanging;
      Puint32(@(registers[address]))^ := data;
      soundSetSound3Freq;
    end;

    SOUND4_LENGTH: begin
      soundChanging;
      Puint32(@(registers[address]))^ := data;
      soundSetSound4Length;
      soundSetSound4CR;
    end;

    SOUNDA_FIFO: begin
      Puint32(@(registers[address]))^ := data;
      soundIncrementFifoA;
    end;
    SOUNDB_FIFO: begin
      Puint32(@(registers[address]))^ := data;
      soundIncrementFifoB;
    end;

    $080: begin
      soundChanging;
      Puint32(@(registers[address]))^ := data;
      soundWriteDSoundCR;
    end;

    $300: begin
      if data and $8000 <> 0 then begin
        // Halt
        cpuStopped := true;
        cpuHalted := true;
        quota := 0;
      end else begin
        // Stop
        cpuStopped := true;
        quota := 0;
      end;
    end;
  else
    Puint32(@(registers[address]))^ := data;
  end;
end;

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

function ReadPal_08(address: uint32): uint32;
begin
  Dec(quota);
  Result := Palette[address and PALETTE_MASK];
end;

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

function ReadPal_16(address: uint32): uint32;
begin
  Dec(quota);
  Result := Puint16(@(Palette[address and PALETTE_MASK]))^;
end;

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

function ReadPal_32(address: uint32): uint32;
begin
  Dec(quota, 2);

⌨️ 快捷键说明

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