📄 cpumemory.pas
字号:
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 + -