mirror of
https://github.com/t-edson/P65Utils.git
synced 2025-03-28 05:34:02 +00:00
Add files via upload
This commit is contained in:
parent
729875617f
commit
4205b2147d
14
CPUCore.pas
14
CPUCore.pas
@ -99,14 +99,13 @@ type
|
||||
maxUsed : dword; //Dirección mayor de la ROM usdas
|
||||
hexLines : TStringList; //Uusado para crear archivo *.hex
|
||||
public //Memories
|
||||
ram : TCPURam; //memoria RAM
|
||||
ram : TCPURam; //RAM memory
|
||||
iRam : integer; //puntero a la memoria RAM, para escribir cuando se ensambla o compila código.
|
||||
function DisassemblerAt(addr: word; out nBytesProc: byte; useVarName: boolean
|
||||
): string; virtual; abstract; //Desensambla la instrucción actual
|
||||
public //RAM memory functions
|
||||
hasDataAdrr: integer; //Flag/index to indicate a Data block has defined.
|
||||
dataAddr1: integer; //Start address for Data variables (-1 if not used)
|
||||
dataAddr2: integer;
|
||||
dataAddr1: integer; //Start address for Data variables (-1 if not used). Used too as flag.
|
||||
dataAddr2: integer; //End address for Data variables (-1 if not used)
|
||||
procedure ClearMemRAM;
|
||||
procedure DisableAllRAM;
|
||||
procedure SetStatRAM(i1, i2: word; status0: TCPUCellState);
|
||||
@ -129,7 +128,7 @@ type
|
||||
procedure Exec; virtual; abstract; //Ejecuta instrucción actual
|
||||
procedure ExecTo(endAdd: word); virtual; abstract; //Ejecuta hasta cierta dirección
|
||||
procedure ExecStep; virtual; abstract; //Execute one instruction considering CALL as one instruction
|
||||
procedure ExecNCycles(nCyc: integer; out stopped: boolean); virtual; abstract; //Ejecuta hasta cierta dirección
|
||||
procedure ExecNCycles(nCyc: integer; out stopped: boolean); virtual; abstract; //Execute "n" cycles
|
||||
procedure Reset(hard: boolean); virtual; abstract;
|
||||
function ReadPC: dword; virtual; abstract; //Defined DWORD to cover the 18F PC register
|
||||
procedure WritePC(AValue: dword); virtual; abstract;
|
||||
@ -312,7 +311,7 @@ begin
|
||||
|
||||
com := UpCase(trim(strDef));
|
||||
if com='' then begin
|
||||
hasDataAdrr := -1; //Disable
|
||||
dataAddr1 := -1; //Disable
|
||||
exit;
|
||||
end;
|
||||
//Find Address1
|
||||
@ -328,7 +327,6 @@ begin
|
||||
exit(false);
|
||||
end;
|
||||
//Ya se tienen los parámetros, para definir la memoria
|
||||
hasDataAdrr := add1; //Set flag
|
||||
dataAddr1 := add1; //Save
|
||||
dataAddr2 := add2; //Save end
|
||||
end;
|
||||
@ -466,7 +464,7 @@ end;
|
||||
//Initialization
|
||||
constructor TCPUCore.Create;
|
||||
begin
|
||||
hasDataAdrr := -1; //Disable
|
||||
dataAddr1 := -1; //Disable
|
||||
hexLines := TStringList.Create;
|
||||
frequen := 1000000; //4MHz
|
||||
end;
|
||||
|
@ -1,3 +1,8 @@
|
||||
0.3
|
||||
===
|
||||
Se elimina la bandera hasDataAdrr y se pasa a usar dataAddr1, como bandera y dirección inicial.
|
||||
Se corrige un error en la ejecución de la instrucción ROL.
|
||||
|
||||
0.2
|
||||
===
|
||||
Se cambian variables a tipo dword para evitar desborde en TP6502.GetFreeBytes().
|
||||
|
@ -12,7 +12,7 @@
|
||||
<WindowIndex Value="-1"/>
|
||||
<TopLine Value="-1"/>
|
||||
<CursorPos X="-1" Y="-1"/>
|
||||
<UsageCount Value="61"/>
|
||||
<UsageCount Value="74"/>
|
||||
</Unit0>
|
||||
<Unit1>
|
||||
<Filename Value="unit1.pas"/>
|
||||
@ -21,19 +21,19 @@
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
<UnitName Value="Unit1"/>
|
||||
<IsVisibleTab Value="True"/>
|
||||
<TopLine Value="135"/>
|
||||
<CursorPos X="20" Y="154"/>
|
||||
<UsageCount Value="61"/>
|
||||
<UsageCount Value="74"/>
|
||||
<Loaded Value="True"/>
|
||||
<LoadedDesigner Value="True"/>
|
||||
</Unit1>
|
||||
<Unit2>
|
||||
<Filename Value="..\P6502utils.pas"/>
|
||||
<IsVisibleTab Value="True"/>
|
||||
<EditorIndex Value="1"/>
|
||||
<TopLine Value="178"/>
|
||||
<CursorPos X="15" Y="202"/>
|
||||
<UsageCount Value="32"/>
|
||||
<TopLine Value="171"/>
|
||||
<CursorPos Y="171"/>
|
||||
<UsageCount Value="38"/>
|
||||
<Bookmarks Count="1">
|
||||
<Item0 Y="1211" ID="1"/>
|
||||
</Bookmarks>
|
||||
@ -42,9 +42,9 @@
|
||||
<Unit3>
|
||||
<Filename Value="..\CPUCore.pas"/>
|
||||
<EditorIndex Value="2"/>
|
||||
<TopLine Value="98"/>
|
||||
<TopLine Value="124"/>
|
||||
<CursorPos X="31" Y="121"/>
|
||||
<UsageCount Value="25"/>
|
||||
<UsageCount Value="31"/>
|
||||
<Bookmarks Count="1">
|
||||
<Item0 Y="117" ID="3"/>
|
||||
</Bookmarks>
|
||||
@ -55,123 +55,127 @@
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="2838"/>
|
||||
<CursorPos Y="2861"/>
|
||||
<UsageCount Value="10"/>
|
||||
<UsageCount Value="9"/>
|
||||
</Unit4>
|
||||
</Units>
|
||||
<JumpHistory Count="29" HistoryIndex="28">
|
||||
<JumpHistory Count="30" HistoryIndex="29">
|
||||
<Position1>
|
||||
<Filename Value="..\p6502utils.pas"/>
|
||||
<Caret Line="259" Column="21" TopLine="218"/>
|
||||
<Caret Line="355" Column="65" TopLine="252"/>
|
||||
</Position1>
|
||||
<Position2>
|
||||
<Filename Value="..\p6502utils.pas"/>
|
||||
<Caret Line="355" Column="65" TopLine="252"/>
|
||||
<Caret Line="368" Column="5" TopLine="265"/>
|
||||
</Position2>
|
||||
<Position3>
|
||||
<Filename Value="..\p6502utils.pas"/>
|
||||
<Caret Line="368" Column="5" TopLine="265"/>
|
||||
<Caret Line="373" Column="32" TopLine="265"/>
|
||||
</Position3>
|
||||
<Position4>
|
||||
<Filename Value="..\p6502utils.pas"/>
|
||||
<Caret Line="373" Column="32" TopLine="265"/>
|
||||
<Caret Line="1060" Column="49" TopLine="963"/>
|
||||
</Position4>
|
||||
<Position5>
|
||||
<Filename Value="..\p6502utils.pas"/>
|
||||
<Caret Line="1060" Column="49" TopLine="963"/>
|
||||
<Caret Line="1085" Column="49" TopLine="1064"/>
|
||||
</Position5>
|
||||
<Position6>
|
||||
<Filename Value="..\p6502utils.pas"/>
|
||||
<Caret Line="1085" Column="49" TopLine="1064"/>
|
||||
</Position6>
|
||||
<Position7>
|
||||
<Filename Value="..\p6502utils.pas"/>
|
||||
<Caret Line="370" Column="8" TopLine="354"/>
|
||||
</Position7>
|
||||
<Position8>
|
||||
<Filename Value="..\p6502utils.pas"/>
|
||||
<Caret Line="370" Column="8" TopLine="354"/>
|
||||
<Caret Line="369" Column="28" TopLine="354"/>
|
||||
</Position8>
|
||||
<Position9>
|
||||
<Filename Value="..\p6502utils.pas"/>
|
||||
<Caret Line="369" Column="28" TopLine="354"/>
|
||||
<Caret Line="1148" TopLine="1141"/>
|
||||
</Position9>
|
||||
<Position10>
|
||||
<Filename Value="..\p6502utils.pas"/>
|
||||
<Caret Line="1148" TopLine="1141"/>
|
||||
<Caret Line="207" Column="33" TopLine="180"/>
|
||||
</Position10>
|
||||
<Position11>
|
||||
<Filename Value="..\p6502utils.pas"/>
|
||||
<Caret Line="207" Column="33" TopLine="180"/>
|
||||
</Position11>
|
||||
<Position12>
|
||||
<Filename Value="..\p6502utils.pas"/>
|
||||
<Caret Line="1077" Column="62" TopLine="957"/>
|
||||
</Position12>
|
||||
<Position13>
|
||||
<Filename Value="..\p6502utils.pas"/>
|
||||
<Caret Line="1077" Column="62" TopLine="957"/>
|
||||
<Caret Line="1446" Column="12" TopLine="1155"/>
|
||||
</Position13>
|
||||
<Position14>
|
||||
<Filename Value="..\p6502utils.pas"/>
|
||||
<Caret Line="1446" Column="12" TopLine="1155"/>
|
||||
</Position14>
|
||||
<Position15>
|
||||
<Filename Value="..\CPUCore.pas"/>
|
||||
<Caret Line="155" Column="6" TopLine="121"/>
|
||||
</Position14>
|
||||
<Position15>
|
||||
<Filename Value="..\P6502utils.pas"/>
|
||||
<Caret Line="152" Column="18"/>
|
||||
</Position15>
|
||||
<Position16>
|
||||
<Filename Value="..\P6502utils.pas"/>
|
||||
<Caret Line="152" Column="18"/>
|
||||
<Caret Line="19" Column="38"/>
|
||||
</Position16>
|
||||
<Position17>
|
||||
<Filename Value="..\P6502utils.pas"/>
|
||||
<Caret Line="19" Column="38"/>
|
||||
<Caret Line="144" Column="26" TopLine="20"/>
|
||||
</Position17>
|
||||
<Position18>
|
||||
<Filename Value="..\P6502utils.pas"/>
|
||||
<Caret Line="144" Column="26" TopLine="20"/>
|
||||
<Caret Line="201" Column="42" TopLine="180"/>
|
||||
</Position18>
|
||||
<Position19>
|
||||
<Filename Value="..\P6502utils.pas"/>
|
||||
<Caret Line="201" Column="42" TopLine="180"/>
|
||||
</Position19>
|
||||
<Position20>
|
||||
<Filename Value="..\CPUCore.pas"/>
|
||||
<Caret Line="88" Column="3" TopLine="71"/>
|
||||
</Position20>
|
||||
<Position21>
|
||||
</Position19>
|
||||
<Position20>
|
||||
<Filename Value="..\P6502utils.pas"/>
|
||||
<Caret Line="1129" Column="48" TopLine="1113"/>
|
||||
</Position20>
|
||||
<Position21>
|
||||
<Filename Value="..\CPUCore.pas"/>
|
||||
<Caret Line="88" Column="16" TopLine="71"/>
|
||||
</Position21>
|
||||
<Position22>
|
||||
<Filename Value="..\CPUCore.pas"/>
|
||||
<Caret Line="88" Column="16" TopLine="71"/>
|
||||
</Position22>
|
||||
<Position23>
|
||||
<Filename Value="..\CPUCore.pas"/>
|
||||
</Position23>
|
||||
<Position24>
|
||||
<Filename Value="..\P6502utils.pas"/>
|
||||
<Caret Line="1129" Column="48" TopLine="1113"/>
|
||||
</Position24>
|
||||
<Position25>
|
||||
</Position23>
|
||||
<Position24>
|
||||
<Filename Value="..\CPUCore.pas"/>
|
||||
<Caret Line="88" Column="42" TopLine="37"/>
|
||||
</Position25>
|
||||
<Position26>
|
||||
</Position24>
|
||||
<Position25>
|
||||
<Filename Value="..\P6502utils.pas"/>
|
||||
<Caret Line="1134" Column="7" TopLine="1115"/>
|
||||
</Position26>
|
||||
<Position27>
|
||||
</Position25>
|
||||
<Position26>
|
||||
<Filename Value="..\CPUCore.pas"/>
|
||||
<Caret Line="64" Column="24" TopLine="37"/>
|
||||
</Position27>
|
||||
<Position28>
|
||||
</Position26>
|
||||
<Position27>
|
||||
<Filename Value="..\P6502utils.pas"/>
|
||||
<Caret Line="1172" Column="12" TopLine="1150"/>
|
||||
</Position28>
|
||||
<Position29>
|
||||
</Position27>
|
||||
<Position28>
|
||||
<Filename Value="unit1.pas"/>
|
||||
<Caret Line="131" Column="18" TopLine="113"/>
|
||||
</Position28>
|
||||
<Position29>
|
||||
<Filename Value="..\P6502utils.pas"/>
|
||||
<Caret Line="234" Column="30" TopLine="211"/>
|
||||
</Position29>
|
||||
<Position30>
|
||||
<Filename Value="..\P6502utils.pas"/>
|
||||
<Caret Line="1651" Column="5" TopLine="1620"/>
|
||||
</Position30>
|
||||
</JumpHistory>
|
||||
<RunParams>
|
||||
<FormatVersion Value="2"/>
|
||||
|
625
P6502utils.pas
625
P6502utils.pas
@ -539,7 +539,8 @@ Global variables used: "idIns", "modIns".
|
||||
}
|
||||
var
|
||||
nemo: String;
|
||||
opCode, par1, par2: Byte;
|
||||
opCode, par1: Byte;
|
||||
par2: word;
|
||||
begin
|
||||
if addr>CPUMAXRAM-1 then exit('');
|
||||
opCode := ram[addr].value;
|
||||
@ -564,11 +565,19 @@ begin
|
||||
aAbsolute: begin
|
||||
nBytesProc := 3;
|
||||
if addr+2>CPUMAXRAM-1 then exit('');
|
||||
par2 := ram[addr+2].value;
|
||||
Result := nemo + '$'+IntToHex(par1 + par2*256, 4);
|
||||
par2 := ram[addr+2].value<<8 + par1;
|
||||
if useVarName and (ram[par2].name<>'') then begin
|
||||
Result := nemo + ram[par2].name;
|
||||
end else begin
|
||||
Result := nemo + '$'+IntToHex(par2, 4);
|
||||
end;
|
||||
end;
|
||||
aZeroPage: begin
|
||||
Result := nemo + '$'+IntToHex(par1, 2);
|
||||
if useVarName and (ram[par1].name<>'') then begin
|
||||
Result := nemo + ram[par1].name;
|
||||
end else begin
|
||||
Result := nemo + '$'+IntToHex(par1, 2);
|
||||
end;
|
||||
nBytesProc := 2;
|
||||
end;
|
||||
aRelative: begin
|
||||
@ -633,8 +642,10 @@ Falta implementar las operaciones, cuando acceden al registro INDF, el Watchdog
|
||||
los contadores, las interrupciones}
|
||||
var
|
||||
opc: byte;
|
||||
nCycles, nBytes, tmp: byte;
|
||||
nCycles, nBytes, tmp, off: byte;
|
||||
target , addr: word;
|
||||
C_tmp: Boolean;
|
||||
tmpRes: integer;
|
||||
begin
|
||||
//Decodifica instrucción
|
||||
aPC := PC.W;
|
||||
@ -661,35 +672,233 @@ begin
|
||||
end;
|
||||
//Execute
|
||||
case idIns of
|
||||
i_ADC:; //add with carry
|
||||
i_AND:; //and (with accumulator)
|
||||
i_ASL:; //arithmetic shift left
|
||||
i_BCC:; //branch on carry clear
|
||||
i_BCS:; //branch on carry set
|
||||
i_BEQ:; //branch on equal (zero set)
|
||||
i_BIT:; //bit test
|
||||
i_BMI:; //branch on minus (negative set)
|
||||
i_BNE: begin
|
||||
i_ADC: begin //add with carry
|
||||
if STATUS_C then begin
|
||||
tmpRes := W + ram[addr].value + 1;
|
||||
end else begin
|
||||
tmpRes := W + ram[addr].value;
|
||||
end;
|
||||
W := tmpRes and $FF;
|
||||
STATUS_Z := W = 0;
|
||||
STATUS_N := W > 127;
|
||||
STATUS_C := tmpRes>255;
|
||||
end;
|
||||
i_AND: begin //and (with accumulator)
|
||||
W := W and ram[addr].value;
|
||||
STATUS_Z := W = 0;
|
||||
STATUS_N := W > 127;
|
||||
end;
|
||||
i_ASL: begin //arithmetic shift left
|
||||
if modIns = aAcumulat then tmp := W
|
||||
else tmp := ram[addr].value;
|
||||
|
||||
end; //branch on not equal (zero clear)
|
||||
i_BPL:; //branch on plus (negative clear)
|
||||
i_BRK:; //break / interrupt
|
||||
i_BVC:; //branch on overflow clear
|
||||
i_BVS:; //branch on overflow set
|
||||
i_CLC: STATUS_C := false; //clear carry
|
||||
i_CLD: STATUS_D := false; //clear decimal
|
||||
i_CLI: STATUS_I := false; //clear interrupt disable
|
||||
i_CLV: STATUS_V := false; //clear overflow
|
||||
i_CMP:; //compare (with accumulator)
|
||||
i_CPX:; //compare with X
|
||||
i_CPY:; //compare with Y
|
||||
i_DEC:; //decrement
|
||||
i_DEX:; //decrement X
|
||||
i_DEY:; //decrement Y
|
||||
i_EOR:; //exclusive or (with accumulator)
|
||||
i_INC:; //increment
|
||||
i_INX:; //increment X
|
||||
i_INY:; //increment Y
|
||||
STATUS_C := (tmp and $80) <> 0; //Read bit 7
|
||||
tmp := tmp << 1;
|
||||
STATUS_Z := tmp = 0;
|
||||
STATUS_N := tmp > 127;
|
||||
|
||||
if modIns = aAcumulat then W := tmp
|
||||
else ram[addr].value := tmp;
|
||||
end;
|
||||
i_BCC: begin //branch on carry clear
|
||||
if not STATUS_C then begin
|
||||
off := ram[aPC+1].value;
|
||||
Inc(PC.W, nBytes); //Normal Increase PC
|
||||
if off>127 then begin
|
||||
PC.W := (PC.W + off - 256) and $FFFF;
|
||||
end else begin
|
||||
PC.W := (PC.W + off) and $FFFF;
|
||||
end;
|
||||
//Inc(PC.W, nBytes); //No apply
|
||||
Inc(nClck, nCycles);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
i_BCS: begin //branch on carry set
|
||||
if STATUS_C then begin
|
||||
off := ram[aPC+1].value;
|
||||
Inc(PC.W, nBytes); //Normal Increase PC
|
||||
if off>127 then begin
|
||||
PC.w := (PC.W + off - 256) and $FFFF;
|
||||
end else begin
|
||||
PC.W := (PC.W + off) and $FFFF;
|
||||
end;
|
||||
//Inc(PC.W, nBytes); //No apply
|
||||
Inc(nClck, nCycles);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
i_BNE: begin //branch on not equal (zero clear)
|
||||
if not STATUS_Z then begin
|
||||
off := ram[aPC+1].value;
|
||||
Inc(PC.W, nBytes); //Normal Increase PC
|
||||
if off>127 then begin
|
||||
PC.W := (PC.W + off - 256) and $FFFF;
|
||||
end else begin
|
||||
PC.W := (PC.W + off) and $FFFF;
|
||||
end;
|
||||
//Inc(PC.W, nBytes); //No apply
|
||||
Inc(nClck, nCycles);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
i_BEQ: begin //branch on equal (zero set)
|
||||
if STATUS_Z then begin
|
||||
off := ram[aPC+1].value;
|
||||
Inc(PC.W, nBytes); //Normal Increase PC
|
||||
if off>127 then begin
|
||||
PC.w := (PC.W + off - 256) and $FFFF;
|
||||
end else begin
|
||||
PC.W := (PC.W + off) and $FFFF;
|
||||
end;
|
||||
//Inc(PC.W, nBytes); //No apply
|
||||
Inc(nClck, nCycles);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
i_BIT: begin //bit test
|
||||
STATUS_N := (ram[addr].value AND $80) <> 0;
|
||||
STATUS_V := (ram[addr].value AND $40) <> 0;
|
||||
STATUS_Z := (W and ram[addr].value) <> 0;
|
||||
end;
|
||||
i_BPL: begin //branch on plus (negative clear)
|
||||
if not STATUS_N then begin
|
||||
off := ram[aPC+1].value;
|
||||
Inc(PC.W, nBytes); //Normal Increase PC
|
||||
if off>127 then begin
|
||||
PC.W := (PC.W + off - 256) and $FFFF;
|
||||
end else begin
|
||||
PC.W := (PC.W + off) and $FFFF;
|
||||
end;
|
||||
//Inc(PC.W, nBytes); //No apply
|
||||
Inc(nClck, nCycles);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
i_BMI: begin //branch on minus (negative set)
|
||||
if STATUS_N then begin
|
||||
off := ram[aPC+1].value;
|
||||
Inc(PC.W, nBytes); //Normal Increase PC
|
||||
if off>127 then begin
|
||||
PC.w := (PC.W + off - 256) and $FFFF;
|
||||
end else begin
|
||||
PC.W := (PC.W + off) and $FFFF;
|
||||
end;
|
||||
//Inc(PC.W, nBytes); //No apply
|
||||
Inc(nClck, nCycles);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
i_BRK: begin //break / interrupt
|
||||
ram[$100 + SP].value := PC.L;
|
||||
if SP = $00 then SP := $FF else dec(SP);
|
||||
ram[$100 + SP].value := PC.H;
|
||||
if SP = $00 then SP := $FF else dec(SP);
|
||||
STATUS_I := true;
|
||||
ram[$100 + SP].value := SR;
|
||||
if SP = $00 then SP := $FF else dec(SP);
|
||||
PC.L := ram[$FFFE].value;
|
||||
PC.H := ram[$FFFF].value;
|
||||
end;
|
||||
i_BVC: begin //branch on overflow clear
|
||||
if not STATUS_V then begin
|
||||
off := ram[aPC+1].value;
|
||||
Inc(PC.W, nBytes); //Normal Increase PC
|
||||
if off>127 then begin
|
||||
PC.W := (PC.W + off - 256) and $FFFF;
|
||||
end else begin
|
||||
PC.W := (PC.W + off) and $FFFF;
|
||||
end;
|
||||
//Inc(PC.W, nBytes); //No apply
|
||||
Inc(nClck, nCycles);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
i_BVS: begin //branch on overflow set
|
||||
if STATUS_V then begin
|
||||
off := ram[aPC+1].value;
|
||||
Inc(PC.W, nBytes); //Normal Increase PC
|
||||
if off>127 then begin
|
||||
PC.w := (PC.W + off - 256) and $FFFF;
|
||||
end else begin
|
||||
PC.W := (PC.W + off) and $FFFF;
|
||||
end;
|
||||
//Inc(PC.W, nBytes); //No apply
|
||||
Inc(nClck, nCycles);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
i_CLC: STATUS_C := false; //clear carry
|
||||
i_CLD: STATUS_D := false; //clear decimal
|
||||
i_CLI: STATUS_I := false; //clear interrupt disable
|
||||
i_CLV: STATUS_V := false; //clear overflow
|
||||
i_CMP: begin //Compare (with accumulator)
|
||||
tmp := ram[addr].value;
|
||||
STATUS_Z := W = tmp;
|
||||
STATUS_C := W >= tmp;
|
||||
if W = tmp then begin
|
||||
STATUS_N := false;
|
||||
end else begin
|
||||
STATUS_N := ((W-tmp) and $80) <> 0; //Copy bit 7
|
||||
end;
|
||||
end;
|
||||
i_CPX: begin; //compare with X
|
||||
tmp := ram[addr].value;
|
||||
STATUS_Z := X = tmp;
|
||||
STATUS_C := X >= tmp;
|
||||
if X = tmp then begin
|
||||
STATUS_N := false;
|
||||
end else begin
|
||||
STATUS_N := ((X-tmp) and $80) <> 0; //Copy bit 7
|
||||
end;
|
||||
end;
|
||||
i_CPY: begin //compare with Y
|
||||
tmp := ram[addr].value;
|
||||
STATUS_Z := Y = tmp;
|
||||
STATUS_C := Y >= tmp;
|
||||
if Y = tmp then begin
|
||||
STATUS_N := false;
|
||||
end else begin
|
||||
STATUS_N := ((Y-tmp) and $80) <> 0; //Copy bit 7
|
||||
end;
|
||||
end;
|
||||
i_DEC: begin //decrement
|
||||
tmp := (ram[addr].value - 1) and $FF;
|
||||
ram[addr].value := tmp;
|
||||
STATUS_Z := tmp = 0;
|
||||
STATUS_N := tmp > 127;
|
||||
end;
|
||||
i_DEX: begin //decrement X
|
||||
X := (X - 1) and $FF;
|
||||
STATUS_Z := X = 0;
|
||||
STATUS_N := X > 127;
|
||||
end;
|
||||
i_DEY: begin //decrement Y
|
||||
Y := (Y - 1) and $FF;
|
||||
STATUS_Z := Y = 0;
|
||||
STATUS_N := Y > 127;
|
||||
end;
|
||||
i_EOR: begin //exclusive or (with accumulator)
|
||||
W := W xor ram[addr].value;
|
||||
STATUS_Z := W = 0;
|
||||
STATUS_N := W > 127;
|
||||
end;
|
||||
i_INC: begin //increment
|
||||
tmp := (ram[addr].value + 1) and $FF;
|
||||
ram[addr].value := tmp;
|
||||
STATUS_Z := tmp = 0;
|
||||
STATUS_N := tmp > 127;
|
||||
end;
|
||||
i_INX: begin //increment X
|
||||
X := (X + 1) and $FF;
|
||||
STATUS_Z := X = 0;
|
||||
STATUS_N := X > 127;
|
||||
end;
|
||||
i_INY: begin //increment Y
|
||||
Y := (Y + 1) and $FF;
|
||||
STATUS_Z := Y = 0;
|
||||
STATUS_N := Y > 127;
|
||||
end;
|
||||
i_JMP: begin //jump
|
||||
case modIns of
|
||||
aAbsolute : begin
|
||||
@ -734,22 +943,81 @@ begin
|
||||
STATUS_Z := Y = 0;
|
||||
STATUS_N := Y > 127;
|
||||
end;
|
||||
i_LSR:; //logical shift right
|
||||
i_NOP:; //no operation
|
||||
i_ORA:; //or with accumulator
|
||||
i_LSR: begin
|
||||
STATUS_N := false;
|
||||
if modIns = aAcumulat then tmp := W
|
||||
else tmp := ram[addr].value;
|
||||
|
||||
STATUS_C := (tmp and $01) <> 0;
|
||||
tmp := tmp >> 1;
|
||||
STATUS_Z := tmp = 0;
|
||||
|
||||
if modIns = aAcumulat then W := tmp
|
||||
else ram[addr].value := tmp;
|
||||
end; //logical shift right
|
||||
i_NOP: ; //no operation
|
||||
i_ORA: begin //or with accumulator
|
||||
W := W or ram[addr].value;
|
||||
STATUS_Z := W = 0;
|
||||
STATUS_N := W > 127;
|
||||
end;
|
||||
i_PHA: begin //push accumulator
|
||||
ram[$100 + SP].value := W;
|
||||
if SP = $00 then SP := $FF else dec(SP);
|
||||
end;
|
||||
i_PHP:; //push processor status (SR)
|
||||
i_PHP: begin //push processor status (SR)
|
||||
ram[$100 + SP].value := STATUS;
|
||||
if SP = $00 then SP := $FF else dec(SP);
|
||||
end;
|
||||
i_PLA: begin //pull accumulator
|
||||
if SP = $FF then SP := $00 else inc(SP);
|
||||
W := ram[$100 + SP].value;
|
||||
end;
|
||||
i_PLP:; //pull processor status (SR)
|
||||
i_ROL:; //rotate left
|
||||
i_ROR:; //rotate right
|
||||
i_RTI:; //return from interrupt
|
||||
i_PLP: begin //pull processor status (SR)
|
||||
if SP = $FF then SP := $00 else inc(SP);
|
||||
SR := ram[$100 + SP].value;
|
||||
end;
|
||||
i_ROL: begin //rotate left
|
||||
STATUS_N := false;
|
||||
if modIns = aAcumulat then tmp := W
|
||||
else tmp := ram[addr].value;
|
||||
|
||||
C_tmp := STATUS_C;
|
||||
STATUS_C := (tmp and $07) <> 0; //Get bit 7
|
||||
tmp := byte(tmp << 1);
|
||||
if C_tmp then tmp := tmp or $01; //Insert bit 0
|
||||
STATUS_Z := tmp = 0;
|
||||
STATUS_N := tmp > 127;
|
||||
|
||||
if modIns = aAcumulat then W := tmp
|
||||
else ram[addr].value := tmp;
|
||||
end;
|
||||
i_ROR: begin //rotate right
|
||||
STATUS_N := false;
|
||||
if modIns = aAcumulat then tmp := W
|
||||
else tmp := ram[addr].value;
|
||||
|
||||
C_tmp := STATUS_C; //Save previos C
|
||||
STATUS_C := (tmp and $01) <> 0; //Get bit 0
|
||||
tmp := tmp >> 1;
|
||||
if C_tmp then tmp := tmp or $80; //Insert bit 7
|
||||
STATUS_Z := tmp = 0;
|
||||
STATUS_N := tmp > 127;
|
||||
|
||||
if modIns = aAcumulat then W := tmp
|
||||
else ram[addr].value := tmp;
|
||||
end;
|
||||
i_RTI: begin //return from interrupt
|
||||
if SP = $FF then SP := $00 else inc(SP);
|
||||
SR := ram[$100 + SP].value;
|
||||
if SP = $FF then SP := $00 else inc(SP);
|
||||
PC.L := ram[$100 + SP].value;
|
||||
if SP = $FF then SP := $00 else inc(SP);
|
||||
PC.H := ram[$100 + SP].value;
|
||||
//Inc(PC.W, nBytes); //No apply
|
||||
Inc(nClck, nCycles);
|
||||
exit;
|
||||
end;
|
||||
i_RTS: begin //return from subroutine
|
||||
if SP = $FF then SP := $00 else inc(SP);
|
||||
PC.L := ram[$100 + SP].value;
|
||||
@ -759,7 +1027,17 @@ begin
|
||||
Inc(nClck, nCycles);
|
||||
exit;
|
||||
end;
|
||||
i_SBC:; //subtract with carry
|
||||
i_SBC: begin //subtract with carry
|
||||
if STATUS_C then begin
|
||||
tmpRes := W - ram[addr].value - 1;
|
||||
end else begin
|
||||
tmpRes := W - ram[addr].value;
|
||||
end;
|
||||
W := tmpRes and $FF;
|
||||
STATUS_Z := W = 0;
|
||||
STATUS_N := W > 127;
|
||||
STATUS_C := tmpRes<0;
|
||||
end;
|
||||
i_SEC: STATUS_C := true; //set carry
|
||||
i_SED: STATUS_D := true; //set decimal
|
||||
i_SEI: STATUS_I := true; //set interrupt disable
|
||||
@ -787,260 +1065,23 @@ begin
|
||||
STATUS_Z := X = 0;
|
||||
STATUS_N := X > 127;
|
||||
end;
|
||||
i_TXA:; //transfer X to accumulator
|
||||
i_TXS:; //transfer X to stack pointer
|
||||
i_TYA:; //transfer Y to accumulator
|
||||
i_TXA: begin //transfer X to accumulator
|
||||
W := X;
|
||||
STATUS_Z := W = 0;
|
||||
STATUS_N := W > 127;
|
||||
end;
|
||||
i_TXS: begin //transfer X to stack pointer
|
||||
SP := X;
|
||||
end;
|
||||
i_TYA: begin //transfer Y to accumulator
|
||||
W := Y;
|
||||
STATUS_Z := W = 0;
|
||||
STATUS_N := W > 127;
|
||||
end;
|
||||
i_Inval: begin
|
||||
MsjError := 'Invalid Opcode';
|
||||
end;
|
||||
end;
|
||||
|
||||
{ i_ADDWF: begin
|
||||
resByte := FRAM;
|
||||
resWord := W + resByte;
|
||||
resNib := (W and $0F) + (resByte and $0F);
|
||||
if modIns = toF then begin
|
||||
FRAM := resWord and $FF;
|
||||
end else begin //toW
|
||||
w := resWord and $FF;
|
||||
end;
|
||||
STATUS_Z := (resWord and $ff) = 0;
|
||||
STATUS_C := (resWord > 255);
|
||||
STATUS_N := (resNib > 15);
|
||||
end;
|
||||
i_ANDWF: begin
|
||||
resByte := W and FRAM;
|
||||
if modIns = toF then begin
|
||||
FRAM := resByte;
|
||||
end else begin //toW
|
||||
w := resByte;
|
||||
end;
|
||||
STATUS_Z := resByte = 0;
|
||||
end;
|
||||
i_CLRF: begin
|
||||
FRAM := 0;
|
||||
STATUS_Z := true;
|
||||
end;
|
||||
i_CLRW: begin
|
||||
W := 0;
|
||||
STATUS_Z := true;
|
||||
end;
|
||||
i_COMF : begin
|
||||
resByte := not FRAM;
|
||||
if modIns = toF then begin
|
||||
FRAM := resByte;
|
||||
end else begin //toW
|
||||
w := resByte;
|
||||
end;
|
||||
STATUS_Z := resByte = 0;
|
||||
end;
|
||||
i_DECF : begin
|
||||
resByte := FRAM;
|
||||
if resByte = 0 then resByte := $FF else dec(resByte);
|
||||
if modIns = toF then begin
|
||||
FRAM := resByte;
|
||||
end else begin //toW
|
||||
w := resByte;
|
||||
end;
|
||||
STATUS_Z := resByte = 0;
|
||||
end;
|
||||
i_DECFSZ: begin
|
||||
resByte := FRAM;
|
||||
if resByte = 0 then resByte := $FF else dec(resByte);
|
||||
if modIns = toF then begin
|
||||
FRAM := resByte;
|
||||
end else begin //toW
|
||||
w := resByte;
|
||||
end;
|
||||
STATUS_Z := resByte = 0;
|
||||
if STATUS_Z then begin
|
||||
Inc(PC.W); //Jump one instrucción
|
||||
Inc(nClck); //In this case it takes one more cicle
|
||||
end;
|
||||
end;
|
||||
i_INCF: begin
|
||||
resByte := FRAM;
|
||||
if resByte = 255 then resByte := 0 else inc(resByte);
|
||||
if modIns = toF then begin
|
||||
FRAM := resByte;
|
||||
end else begin //toW
|
||||
w := resByte;
|
||||
end;
|
||||
STATUS_Z := resByte = 0;
|
||||
end;
|
||||
i_INCFSZ: begin
|
||||
resByte := FRAM;
|
||||
if resByte = 255 then resByte := 0 else inc(resByte);
|
||||
if modIns = toF then begin
|
||||
FRAM := resByte;
|
||||
end else begin //toW
|
||||
w := resByte;
|
||||
end;
|
||||
STATUS_Z := resByte = 0;
|
||||
if STATUS_Z then begin
|
||||
Inc(PC.W); //Jump one instrucción
|
||||
Inc(nClck); //In this case it takes one more cicle
|
||||
end;
|
||||
end;
|
||||
i_IORWF: begin
|
||||
resByte := W or FRAM;
|
||||
if modIns = toF then begin
|
||||
FRAM := resByte;
|
||||
end else begin //toW
|
||||
w := resByte;
|
||||
end;
|
||||
STATUS_Z := resByte <> 0;
|
||||
end;
|
||||
i_MOVF: begin
|
||||
resByte := FRAM;
|
||||
if modIns = toF then begin
|
||||
//no mueve, solo verifica
|
||||
STATUS_Z := (resByte = 0);
|
||||
end else begin //toW
|
||||
w := resByte;
|
||||
STATUS_Z := (resByte = 0);
|
||||
end;
|
||||
end;
|
||||
i_MOVWF: begin
|
||||
FRAM := W; //escribe a donde esté mapeado, (si está mapeado)
|
||||
if parIns = $02 then begin //Es el PCL
|
||||
PC.H := PCLATH; //Cuando se escribe en PCL, se carga PCH con PCLATH
|
||||
end;
|
||||
end;
|
||||
i_NOP: begin
|
||||
end;
|
||||
i_RLF: begin
|
||||
resByte := FRAM;
|
||||
bit7 := resByte and $80; //guarda bit 7
|
||||
resByte := (resByte << 1) and $ff; //desplaza
|
||||
//pone C en bit bajo
|
||||
if STATUS_C then begin //C era 1
|
||||
resByte := resByte or $01; //pone a 1 el bit 0
|
||||
end else begin //C era 0
|
||||
//no es necesario agregarlo, porque por defecto se agrega 0
|
||||
end;
|
||||
//Actualiza C
|
||||
if bit7 = 0 then STATUS_C := false
|
||||
else STATUS_C := true;
|
||||
if modIns = toF then begin
|
||||
FRAM := resByte;
|
||||
end else begin //toW
|
||||
w := resByte;
|
||||
end;
|
||||
end;
|
||||
i_RRF: begin
|
||||
resByte := FRAM;
|
||||
bit0 := resByte and $01; //guarda bit 0
|
||||
resByte := resByte >> 1; //desplaza
|
||||
//pone C en bit alto
|
||||
if STATUS_C then begin //C era 1
|
||||
resByte := resByte or $80; //pone a 1 el bit 0
|
||||
end else begin //C era 0
|
||||
//no es necesario agregarlo, porque por defecto se agrega 0
|
||||
end;
|
||||
//Actualiza C
|
||||
if bit0 = 0 then STATUS_C := false
|
||||
else STATUS_C := true;
|
||||
if modIns = toF then begin
|
||||
FRAM := resByte;
|
||||
end else begin //toW
|
||||
w := resByte;
|
||||
end;
|
||||
end;
|
||||
i_SUBWF: begin
|
||||
resByte := FRAM;
|
||||
resInt := resByte - W;
|
||||
if modIns = toF then begin
|
||||
FRAM := resInt and $FF;
|
||||
end else begin //toW
|
||||
w := resInt and $FF;
|
||||
end;
|
||||
STATUS_Z := (resInt = 0);
|
||||
if resInt < 0 then STATUS_C := false //negativo
|
||||
else STATUS_C := true;
|
||||
resInt := (resByte and $0F) - (W and $0F);
|
||||
if resInt < 0 then STATUS_N := false //negativo
|
||||
else STATUS_N := true;
|
||||
end;
|
||||
i_SWAPF: begin
|
||||
resByte := FRAM;
|
||||
FRAM := (resByte >> 4) or (resByte << 4);
|
||||
end;
|
||||
i_XORWF: begin
|
||||
resByte := W xor FRAM;
|
||||
if modIns = toF then begin
|
||||
FRAM := resByte;
|
||||
end else begin //toW
|
||||
w := resByte;
|
||||
end;
|
||||
STATUS_Z := resByte <> 0;
|
||||
end;
|
||||
//BIT-ORIENTED FILE REGISTER OPERATIONS
|
||||
i_BCF: begin
|
||||
msk := $1 << b_;
|
||||
msk := not msk;
|
||||
FRAM := FRAM and msk;
|
||||
end;
|
||||
i_BSF: begin
|
||||
msk := $1 << b_;
|
||||
FRAM := FRAM or msk;// b_
|
||||
end;
|
||||
i_BTFSC: begin
|
||||
msk := $1 << b_;
|
||||
if (FRAM and msk) = 0 then begin
|
||||
Inc(PC.W); //Jump one instrucción
|
||||
Inc(nClck); //In this case it takes one more cicle
|
||||
end;
|
||||
end;
|
||||
i_BTFSS: begin
|
||||
msk := $1 << b_;
|
||||
if (FRAM and msk) <> 0 then begin
|
||||
Inc(PC.W); //Jump one instrucción
|
||||
Inc(nClck); //In this case it takes one more cicle
|
||||
end;
|
||||
end;
|
||||
//LITERAL AND CONTROL OPERATIONS
|
||||
i_ADDLW: begin
|
||||
resWord := W + k_;
|
||||
resNib := (W and $0F) + (k_ and $0F);
|
||||
w := resWord and $FF;
|
||||
STATUS_Z := (resWord and $ff) = 0;
|
||||
STATUS_C := (resWord > 255);
|
||||
STATUS_N := (resNib > 15);
|
||||
end;
|
||||
i_ANDLW: begin
|
||||
resByte := W and K_;
|
||||
w := resByte;
|
||||
STATUS_Z := resByte = 0;
|
||||
end;
|
||||
i_IORLW: begin
|
||||
resByte := W or k_;
|
||||
w := resByte;
|
||||
STATUS_Z := resByte <> 0;
|
||||
end;
|
||||
i_MOVLW: begin
|
||||
W := k_;
|
||||
end;
|
||||
i_SUBLW: begin
|
||||
resInt := k_ - W;
|
||||
w := resInt and $FF;
|
||||
STATUS_Z := (resInt = 0);
|
||||
if resInt < 0 then STATUS_C := false //negativo
|
||||
else STATUS_C := true;
|
||||
resInt := (k_ and $0F) - (W and $0F);
|
||||
if resInt < 0 then STATUS_N := false //negativo
|
||||
else STATUS_N := true;
|
||||
end;
|
||||
i_XORLW: begin
|
||||
resByte := W xor k_;
|
||||
w := resByte;
|
||||
STATUS_Z := resByte <> 0;
|
||||
end;
|
||||
i_Inval: begin
|
||||
MsjError := 'Invalid Opcode';
|
||||
end;
|
||||
end;
|
||||
}
|
||||
//Increase counters
|
||||
Inc(PC.W, nBytes);
|
||||
Inc(nClck, nCycles);
|
||||
|
Loading…
x
Reference in New Issue
Block a user