📄 cpumemory.pas
字号:
Result := Puint32(@(Palette[address and PALETTE_MASK]))^;
end;
//////////////////////////////////////////////////////////////////////
procedure WritePal_08(address, data: uint32);
begin
Dec(quota);
address := address and (PALETTE_MASK and not 1);
Puint16(@(Palette[address]))^ := data + data shl 8;
end;
//////////////////////////////////////////////////////////////////////
procedure WritePal_16(address, data: uint32);
begin
Dec(quota);
Puint16(@(Palette[address and PALETTE_MASK]))^ := data;
end;
//////////////////////////////////////////////////////////////////////
procedure WritePal_32(address, data: uint32);
begin
Dec(quota, 2);
Puint32(@(Palette[address and PALETTE_MASK]))^ := data;
end;
//////////////////////////////////////////////////////////////////////
function ReadVRAM_08(address: uint32): uint32;
begin
Dec(quota);
Result := VRAM[address and VRAM_MASK];
end;
//////////////////////////////////////////////////////////////////////
function ReadVRAM_16(address: uint32): uint32;
begin
Dec(quota);
Result := Puint16(@(VRAM[address and VRAM_MASK]))^;
end;
//////////////////////////////////////////////////////////////////////
function ReadVRAM_32(address: uint32): uint32;
begin
Dec(quota, 2);
Result := Puint32(@(VRAM[address and VRAM_MASK]))^;
end;
//////////////////////////////////////////////////////////////////////
procedure WriteVRAM_08(address, data: uint32);
begin
Dec(quota);
address := address and (VRAM_MASK and not 1);
Puint16(@(VRAM[address]))^ := data + data shl 8;
end;
//////////////////////////////////////////////////////////////////////
procedure WriteVRAM_16(address, data: uint32);
begin
Dec(quota);
Puint16(@(VRAM[address and VRAM_MASK]))^ := data;
end;
//////////////////////////////////////////////////////////////////////
procedure WriteVRAM_32(address, data: uint32);
begin
Dec(quota, 2);
Puint32(@(VRAM[address and VRAM_MASK]))^ := data;
end;
//////////////////////////////////////////////////////////////////////
function ReadOAM_08(address: uint32): uint32;
begin
Dec(quota);
Result := OAM[address and OAM_MASK];
end;
//////////////////////////////////////////////////////////////////////
function ReadOAM_16(address: uint32): uint32;
begin
Dec(quota);
Result := Puint16(@(OAM[address and OAM_MASK]))^;
end;
//////////////////////////////////////////////////////////////////////
function ReadOAM_32(address: uint32): uint32;
begin
Dec(quota, 2);
Result := Puint32(@(OAM[address and OAM_MASK]))^;
end;
//////////////////////////////////////////////////////////////////////
procedure WriteOAM_08(address, data: uint32);
begin
Dec(quota);
address := address and (OAM_MASK and not 1);
Puint16(@(OAM[address]))^ := data + data shl 8;
end;
//////////////////////////////////////////////////////////////////////
procedure WriteOAM_16(address, data: uint32);
begin
Dec(quota);
Puint16(@(OAM[address and OAM_MASK]))^ := data;
end;
//////////////////////////////////////////////////////////////////////
procedure WriteOAM_32(address, data: uint32);
begin
Dec(quota, 2);
Puint32(@(OAM[address and OAM_MASK]))^ := data;
end;
//////////////////////////////////////////////////////////////////////
function ReadROM1_08(address: uint32): uint32;
begin
if address-lastAddress <= 4 then Dec(quota, bankSTimes[curBank]) else Dec(quota, bankNTimes[curBank]);
Result := cartROM1^[address and cartMask1];
{ part of the e-Reader testing:
if address >= $08700000 then
logWriteLn(Format('%2.2x in ROM[%8.8x], at %8.8x', [Result, address, regs[R15]]));}
end;
//////////////////////////////////////////////////////////////////////
function ReadROM1_16(address: uint32): uint32;
begin
if address-lastAddress <= 4 then Dec(quota, bankSTimes[curBank]) else Dec(quota, bankNTimes[curBank]);
Result := Puint16(@(cartROM1^[address and cartMask1]))^;
{ part of the e-Reader testing:
if address >= $08700000 then
logWriteLn(Format('%4.4x in ROM[%8.8x], at %8.8x', [Result, address, regs[R15]]));}
end;
//////////////////////////////////////////////////////////////////////
function ReadROM1_32(address: uint32): uint32;
begin
if address-lastAddress <= 4 then
Dec(quota, bankSTimes[curBank]*2 + 1)
else
Dec(quota, bankNTimes[curBank] + bankSTimes[curBank] + 1);
Result := Puint32(@(cartROM1^[address and cartMask1]))^;
{ part of the e-Reader testing:
if address >= $08700000 then
logWriteLn(Format('%8.8x in ROM[%8.8x], at %8.8x', [Result, address, regs[R15]]));}
end;
//////////////////////////////////////////////////////////////////////
function ReadROM2_08(address: uint32): uint32;
begin
if address-lastAddress <= 4 then Dec(quota, bankSTimes[curBank]) else Dec(quota, bankNTimes[curBank]);
Result := cartROM2^[address and cartMask2];
end;
//////////////////////////////////////////////////////////////////////
function ReadROM2_16(address: uint32): uint32;
begin
if address-lastAddress <= 4 then Dec(quota, bankSTimes[curBank]) else Dec(quota, bankNTimes[curBank]);
Result := Puint16(@(cartROM2^[address and cartMask2]))^;
end;
//////////////////////////////////////////////////////////////////////
function ReadROM2_32(address: uint32): uint32;
begin
if address-lastAddress <= 4 then
Dec(quota, bankSTimes[curBank]*2 + 1)
else
Dec(quota, bankNTimes[curBank] + bankSTimes[curBank] + 1);
Result := Puint32(@(cartROM2^[address and cartMask2]))^;
end;
//////////////////////////////////////////////////////////////////////
// Thanks to Forgotten for his help with EEPROM support //////////////
//////////////////////////////////////////////////////////////////////
function ReadEEPROM_08(address: uint32): uint32;
begin
if address-lastAddress <= 4 then Dec(quota, bankSTimes[curBank]) else Dec(quota, bankNTimes[curBank]);
Result := 0;
case eepromMode of
emIdle, emReadAddress, emWriteData: Result := 1;
emReadData: begin
Inc(eepromIndex);
if eepromIndex = 4 then begin
eepromMode := emReadData2;
eepromIndex := 0;
eepromByte := 0;
end;
end;
emReadData2: begin
Result := (cartRAM[eepromAddress shl 3 + eepromByte] shr (7 - eepromIndex and 7)) and 1;
Inc(eepromIndex);
if eepromIndex and 7 = 0 then Inc(eepromByte);
if eepromIndex = 64 then eepromMode := emIdle;
end;
end;
end;
//////////////////////////////////////////////////////////////////////
function ReadEEPROM_16(address: uint32): uint32;
begin
Result := ReadEEPROM_08(address);
end;
//////////////////////////////////////////////////////////////////////
function ReadEEPROM_32(address: uint32): uint32;
begin
Result := ReadEEPROM_08(address);
Dec(quota, bankSTimes[curBank] + 1);
end;
//////////////////////////////////////////////////////////////////////
procedure WriteEEPROM_08(address, data: uint32);
var
i: uint32;
begin
if address-lastAddress <= 4 then Dec(quota, bankSTimes[curBank]) else Dec(quota, bankNTimes[curBank]);
cartRAMdirty := true;
data := data and 1;
case eepromMode of
emIdle: begin
eepromIndex := 1;
eepromByte := 0;
eepromBuffer[0] := data;
eepromMode := emReadAddress;
end;
emReadAddress: begin
eepromBuffer[eepromByte] := eepromBuffer[eepromByte] shl 1;
eepromBuffer[eepromByte] := eepromBuffer[eepromByte] or data;
Inc(eepromIndex);
if eepromIndex and 7 = 0 then Inc(eepromByte);
if eepromIndex = 9 then begin
eepromAddress := eepromBuffer[0] and $3F;
if eepromBuffer[0] and $40 = 0 then
eepromMode := emWriteData
else begin
eepromMode := emReadData;
eepromByte := 0;
eepromIndex := 0;
end;
end;
end;
emReadData, emReadData2: begin
eepromMode := emIdle;
end;
emWriteData: begin
eepromBuffer[eepromByte] := eepromBuffer[eepromByte] shl 1;
eepromBuffer[eepromByte] := eepromBuffer[eepromByte] or data;
Inc(eepromIndex);
if eepromIndex and 7 = 0 then Inc(eepromByte);
if eepromIndex = $49 then begin
// Write data
for i := 0 to 7 do
cartRAM[(eepromAddress shl 3 + i) and EEPROM_MASK] := eepromBuffer[1+i];
eepromMode := emIdle;
end;
end;
end;
end;
//////////////////////////////////////////////////////////////////////
procedure WriteEEPROM_16(address, data: uint32);
begin
WriteEEPROM_08(address, data);
end;
//////////////////////////////////////////////////////////////////////
procedure WriteEEPROM_32(address, data: uint32);
begin
WriteEEPROM_08(address, data);
Dec(quota, bankSTimes[curBank] + 1);
end;
//////////////////////////////////////////////////////////////////////
{
SRAM support is currently disabled
function ReadSRAM_08(address: uint32): uint32;
begin
logwriteln(format('SRAM read of %.4x',[address and $FFFF]));
if address-lastAddress <= 4 then Dec(quota, bankSTimes[curBank]) else Dec(quota, bankNTimes[curBank]);
Result := cartRAM[address and SRAM_MASK];
end;
//////////////////////////////////////////////////////////////////////
procedure WriteSRAM_08(address, data: uint32);
begin
logwriteln(format('SRAM write: [%.4x] = %.2x',[address and $FFFF, data]));
if address-lastAddress <= 4 then Dec(quota, bankSTimes[curBank]) else Dec(quota, bankNTimes[curBank]);
cartRAM[address and SRAM_MASK] := data;
cartRAMdirty := true;
end;
}
//////////////////////////////////////////////////////////////////////
var
bankId: longword = 0;
function ReadFlash_08(address: uint32): uint32;
begin
if address-lastAddress <= 4 then Dec(quota, bankSTimes[curBank]) else Dec(quota, bankNTimes[curBank]);
if flashMode = fmProductID then begin
// if address and 1 <> 0 then Result := $BC else Result := $1F;
if address and 1 <> 0 then Result := $09 else Result := $C2;
end else
Result := cartRAM[bankId + address and SRAM_MASK];
if address and $FFF < 5 then
logwriteln(format('FLASH read of %.4x (%.2x), i/m/b=%d/%d/%d, from %.8x', [address and $FFFF, Result, flashIndex, Ord(flashMode), bankId shr 16, regs[R15]]));
end;
//////////////////////////////////////////////////////////////////////
const
MX_FLASH_READ_ID = $90;
MX_FLASH_PROGRAM = $A0;
MX_FLASH_RESET = $F0;
MX_FLASH_SECTOR_ERASE_SUSPEND = $B0; // Not needed, since sector erase is currently instentanious
// MX_FLASH_SECTOR_ERASE_RESUME = $30; double strikeout, not needed as above, and same as erase command
MX_FLASH_EXTENDED = $80;
// Requires a MX_FLASH_EXTENDED first
MX_FLASH_CHIP_ERASE = $10;
MX_FLASH_SECTOR_ERASE = $30;
// MX_FLASH_SECTOR_UNLOCK = $20; not needed, since there are no lockable sectors
procedure WriteFlash_08(address, data: uint32);
begin
cartRAMdirty := true;
logwriteln(format('FLASH write: [%.4x] = %.2x, at %.8x', [address and $FFFF, data, regs[R15]]));
if address-lastAddress <= 4 then Dec(quota, bankSTimes[curBank]) else Dec(quota, bankNTimes[curBank]);
data := data and $FF;
if flashMode = fmWriteData then begin
cartRAM[bankID + address and SRAM_MASK] := {cartRAM[bankID + address and SRAM_MASK] and }data;
// cartRAM[address and SRAM_MASK] := data;
flashMode := fmIdle;
flashIndex := 0;
end else if flashMode = fmBankswitch then begin
flashMode := fmIdle;
flashIndex := 0;
bankID := (data and 1) shl 16;
logwriteln(format('Bankswitch: [%.4x] = %.2x, at %.8x', [address and $FFFF, data, regs[R15]]));
end else if data = MX_FLASH_RESET then begin
flashMode := fmIdle;
flashIndex := 0;
end else
case flashIndex of
0: if (address and $FFFF = $5555) and (data and $FF = $AA) then Inc(flashIndex);
1: if (address and $FFFF = $2AAA) and (data and $FF = $55) then Inc(flashIndex);
2: begin
if (data = MX_FLASH_SECTOR_ERASE) and (flashMode = fmExtended) then begin
// Do a sector erase
FillChar(cartRAM[bankID + (address and (2*SRAM_MASK+1)) and not $3FFF], $4000, $FF);
// FillChar(cartRAM[(address and SRAM_MASK) and not $1F], 32, $00);
flashMode := fmIdle;
end;
if (address and $FFFF = $5555) then
case data of
MX_FLASH_EXTENDED: flashMode := fmExtended;
MX_FLASH_READ_ID: flashMode := fmProductID;
MX_FLASH_PROGRAM: flashMode := fmWriteData;
MX_FLASH_SECTOR_ERASE: ; // done above
MX_FLASH_SECTOR_ERASE_SUSPEND: flashMode := fmBankswitch;
MX_FLASH_CHIP_ERASE: if flashMode = fmExtended then begin
// Erase the whole chip
FillChar(cartRAM, 2*SRAM_MASK+2, $FF);
// FillChar(cartRAM, SRAM_MASK+1, $FF);
flashMode := fmIdle;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -