mirror of
https://github.com/t-edson/P65Utils.git
synced 2024-06-09 18:29:29 +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
|
maxUsed : dword; //Dirección mayor de la ROM usdas
|
||||||
hexLines : TStringList; //Uusado para crear archivo *.hex
|
hexLines : TStringList; //Uusado para crear archivo *.hex
|
||||||
public //Memories
|
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.
|
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
|
function DisassemblerAt(addr: word; out nBytesProc: byte; useVarName: boolean
|
||||||
): string; virtual; abstract; //Desensambla la instrucción actual
|
): string; virtual; abstract; //Desensambla la instrucción actual
|
||||||
public //RAM memory functions
|
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). Used too as flag.
|
||||||
dataAddr1: integer; //Start address for Data variables (-1 if not used)
|
dataAddr2: integer; //End address for Data variables (-1 if not used)
|
||||||
dataAddr2: integer;
|
|
||||||
procedure ClearMemRAM;
|
procedure ClearMemRAM;
|
||||||
procedure DisableAllRAM;
|
procedure DisableAllRAM;
|
||||||
procedure SetStatRAM(i1, i2: word; status0: TCPUCellState);
|
procedure SetStatRAM(i1, i2: word; status0: TCPUCellState);
|
||||||
|
@ -129,7 +128,7 @@ type
|
||||||
procedure Exec; virtual; abstract; //Ejecuta instrucción actual
|
procedure Exec; virtual; abstract; //Ejecuta instrucción actual
|
||||||
procedure ExecTo(endAdd: word); virtual; abstract; //Ejecuta hasta cierta dirección
|
procedure ExecTo(endAdd: word); virtual; abstract; //Ejecuta hasta cierta dirección
|
||||||
procedure ExecStep; virtual; abstract; //Execute one instruction considering CALL as one instruction
|
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;
|
procedure Reset(hard: boolean); virtual; abstract;
|
||||||
function ReadPC: dword; virtual; abstract; //Defined DWORD to cover the 18F PC register
|
function ReadPC: dword; virtual; abstract; //Defined DWORD to cover the 18F PC register
|
||||||
procedure WritePC(AValue: dword); virtual; abstract;
|
procedure WritePC(AValue: dword); virtual; abstract;
|
||||||
|
@ -312,7 +311,7 @@ begin
|
||||||
|
|
||||||
com := UpCase(trim(strDef));
|
com := UpCase(trim(strDef));
|
||||||
if com='' then begin
|
if com='' then begin
|
||||||
hasDataAdrr := -1; //Disable
|
dataAddr1 := -1; //Disable
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
//Find Address1
|
//Find Address1
|
||||||
|
@ -328,7 +327,6 @@ begin
|
||||||
exit(false);
|
exit(false);
|
||||||
end;
|
end;
|
||||||
//Ya se tienen los parámetros, para definir la memoria
|
//Ya se tienen los parámetros, para definir la memoria
|
||||||
hasDataAdrr := add1; //Set flag
|
|
||||||
dataAddr1 := add1; //Save
|
dataAddr1 := add1; //Save
|
||||||
dataAddr2 := add2; //Save end
|
dataAddr2 := add2; //Save end
|
||||||
end;
|
end;
|
||||||
|
@ -466,7 +464,7 @@ end;
|
||||||
//Initialization
|
//Initialization
|
||||||
constructor TCPUCore.Create;
|
constructor TCPUCore.Create;
|
||||||
begin
|
begin
|
||||||
hasDataAdrr := -1; //Disable
|
dataAddr1 := -1; //Disable
|
||||||
hexLines := TStringList.Create;
|
hexLines := TStringList.Create;
|
||||||
frequen := 1000000; //4MHz
|
frequen := 1000000; //4MHz
|
||||||
end;
|
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
|
0.2
|
||||||
===
|
===
|
||||||
Se cambian variables a tipo dword para evitar desborde en TP6502.GetFreeBytes().
|
Se cambian variables a tipo dword para evitar desborde en TP6502.GetFreeBytes().
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<WindowIndex Value="-1"/>
|
<WindowIndex Value="-1"/>
|
||||||
<TopLine Value="-1"/>
|
<TopLine Value="-1"/>
|
||||||
<CursorPos X="-1" Y="-1"/>
|
<CursorPos X="-1" Y="-1"/>
|
||||||
<UsageCount Value="61"/>
|
<UsageCount Value="74"/>
|
||||||
</Unit0>
|
</Unit0>
|
||||||
<Unit1>
|
<Unit1>
|
||||||
<Filename Value="unit1.pas"/>
|
<Filename Value="unit1.pas"/>
|
||||||
|
@ -21,19 +21,19 @@
|
||||||
<HasResources Value="True"/>
|
<HasResources Value="True"/>
|
||||||
<ResourceBaseClass Value="Form"/>
|
<ResourceBaseClass Value="Form"/>
|
||||||
<UnitName Value="Unit1"/>
|
<UnitName Value="Unit1"/>
|
||||||
<IsVisibleTab Value="True"/>
|
|
||||||
<TopLine Value="135"/>
|
<TopLine Value="135"/>
|
||||||
<CursorPos X="20" Y="154"/>
|
<CursorPos X="20" Y="154"/>
|
||||||
<UsageCount Value="61"/>
|
<UsageCount Value="74"/>
|
||||||
<Loaded Value="True"/>
|
<Loaded Value="True"/>
|
||||||
<LoadedDesigner Value="True"/>
|
<LoadedDesigner Value="True"/>
|
||||||
</Unit1>
|
</Unit1>
|
||||||
<Unit2>
|
<Unit2>
|
||||||
<Filename Value="..\P6502utils.pas"/>
|
<Filename Value="..\P6502utils.pas"/>
|
||||||
|
<IsVisibleTab Value="True"/>
|
||||||
<EditorIndex Value="1"/>
|
<EditorIndex Value="1"/>
|
||||||
<TopLine Value="178"/>
|
<TopLine Value="171"/>
|
||||||
<CursorPos X="15" Y="202"/>
|
<CursorPos Y="171"/>
|
||||||
<UsageCount Value="32"/>
|
<UsageCount Value="38"/>
|
||||||
<Bookmarks Count="1">
|
<Bookmarks Count="1">
|
||||||
<Item0 Y="1211" ID="1"/>
|
<Item0 Y="1211" ID="1"/>
|
||||||
</Bookmarks>
|
</Bookmarks>
|
||||||
|
@ -42,9 +42,9 @@
|
||||||
<Unit3>
|
<Unit3>
|
||||||
<Filename Value="..\CPUCore.pas"/>
|
<Filename Value="..\CPUCore.pas"/>
|
||||||
<EditorIndex Value="2"/>
|
<EditorIndex Value="2"/>
|
||||||
<TopLine Value="98"/>
|
<TopLine Value="124"/>
|
||||||
<CursorPos X="31" Y="121"/>
|
<CursorPos X="31" Y="121"/>
|
||||||
<UsageCount Value="25"/>
|
<UsageCount Value="31"/>
|
||||||
<Bookmarks Count="1">
|
<Bookmarks Count="1">
|
||||||
<Item0 Y="117" ID="3"/>
|
<Item0 Y="117" ID="3"/>
|
||||||
</Bookmarks>
|
</Bookmarks>
|
||||||
|
@ -55,123 +55,127 @@
|
||||||
<EditorIndex Value="-1"/>
|
<EditorIndex Value="-1"/>
|
||||||
<TopLine Value="2838"/>
|
<TopLine Value="2838"/>
|
||||||
<CursorPos Y="2861"/>
|
<CursorPos Y="2861"/>
|
||||||
<UsageCount Value="10"/>
|
<UsageCount Value="9"/>
|
||||||
</Unit4>
|
</Unit4>
|
||||||
</Units>
|
</Units>
|
||||||
<JumpHistory Count="29" HistoryIndex="28">
|
<JumpHistory Count="30" HistoryIndex="29">
|
||||||
<Position1>
|
<Position1>
|
||||||
<Filename Value="..\p6502utils.pas"/>
|
<Filename Value="..\p6502utils.pas"/>
|
||||||
<Caret Line="259" Column="21" TopLine="218"/>
|
<Caret Line="355" Column="65" TopLine="252"/>
|
||||||
</Position1>
|
</Position1>
|
||||||
<Position2>
|
<Position2>
|
||||||
<Filename Value="..\p6502utils.pas"/>
|
<Filename Value="..\p6502utils.pas"/>
|
||||||
<Caret Line="355" Column="65" TopLine="252"/>
|
<Caret Line="368" Column="5" TopLine="265"/>
|
||||||
</Position2>
|
</Position2>
|
||||||
<Position3>
|
<Position3>
|
||||||
<Filename Value="..\p6502utils.pas"/>
|
<Filename Value="..\p6502utils.pas"/>
|
||||||
<Caret Line="368" Column="5" TopLine="265"/>
|
<Caret Line="373" Column="32" TopLine="265"/>
|
||||||
</Position3>
|
</Position3>
|
||||||
<Position4>
|
<Position4>
|
||||||
<Filename Value="..\p6502utils.pas"/>
|
<Filename Value="..\p6502utils.pas"/>
|
||||||
<Caret Line="373" Column="32" TopLine="265"/>
|
<Caret Line="1060" Column="49" TopLine="963"/>
|
||||||
</Position4>
|
</Position4>
|
||||||
<Position5>
|
<Position5>
|
||||||
<Filename Value="..\p6502utils.pas"/>
|
<Filename Value="..\p6502utils.pas"/>
|
||||||
<Caret Line="1060" Column="49" TopLine="963"/>
|
<Caret Line="1085" Column="49" TopLine="1064"/>
|
||||||
</Position5>
|
</Position5>
|
||||||
<Position6>
|
<Position6>
|
||||||
<Filename Value="..\p6502utils.pas"/>
|
<Filename Value="..\p6502utils.pas"/>
|
||||||
<Caret Line="1085" Column="49" TopLine="1064"/>
|
|
||||||
</Position6>
|
</Position6>
|
||||||
<Position7>
|
<Position7>
|
||||||
<Filename Value="..\p6502utils.pas"/>
|
<Filename Value="..\p6502utils.pas"/>
|
||||||
|
<Caret Line="370" Column="8" TopLine="354"/>
|
||||||
</Position7>
|
</Position7>
|
||||||
<Position8>
|
<Position8>
|
||||||
<Filename Value="..\p6502utils.pas"/>
|
<Filename Value="..\p6502utils.pas"/>
|
||||||
<Caret Line="370" Column="8" TopLine="354"/>
|
<Caret Line="369" Column="28" TopLine="354"/>
|
||||||
</Position8>
|
</Position8>
|
||||||
<Position9>
|
<Position9>
|
||||||
<Filename Value="..\p6502utils.pas"/>
|
<Filename Value="..\p6502utils.pas"/>
|
||||||
<Caret Line="369" Column="28" TopLine="354"/>
|
<Caret Line="1148" TopLine="1141"/>
|
||||||
</Position9>
|
</Position9>
|
||||||
<Position10>
|
<Position10>
|
||||||
<Filename Value="..\p6502utils.pas"/>
|
<Filename Value="..\p6502utils.pas"/>
|
||||||
<Caret Line="1148" TopLine="1141"/>
|
<Caret Line="207" Column="33" TopLine="180"/>
|
||||||
</Position10>
|
</Position10>
|
||||||
<Position11>
|
<Position11>
|
||||||
<Filename Value="..\p6502utils.pas"/>
|
<Filename Value="..\p6502utils.pas"/>
|
||||||
<Caret Line="207" Column="33" TopLine="180"/>
|
|
||||||
</Position11>
|
</Position11>
|
||||||
<Position12>
|
<Position12>
|
||||||
<Filename Value="..\p6502utils.pas"/>
|
<Filename Value="..\p6502utils.pas"/>
|
||||||
|
<Caret Line="1077" Column="62" TopLine="957"/>
|
||||||
</Position12>
|
</Position12>
|
||||||
<Position13>
|
<Position13>
|
||||||
<Filename Value="..\p6502utils.pas"/>
|
<Filename Value="..\p6502utils.pas"/>
|
||||||
<Caret Line="1077" Column="62" TopLine="957"/>
|
<Caret Line="1446" Column="12" TopLine="1155"/>
|
||||||
</Position13>
|
</Position13>
|
||||||
<Position14>
|
<Position14>
|
||||||
<Filename Value="..\p6502utils.pas"/>
|
|
||||||
<Caret Line="1446" Column="12" TopLine="1155"/>
|
|
||||||
</Position14>
|
|
||||||
<Position15>
|
|
||||||
<Filename Value="..\CPUCore.pas"/>
|
<Filename Value="..\CPUCore.pas"/>
|
||||||
<Caret Line="155" Column="6" TopLine="121"/>
|
<Caret Line="155" Column="6" TopLine="121"/>
|
||||||
|
</Position14>
|
||||||
|
<Position15>
|
||||||
|
<Filename Value="..\P6502utils.pas"/>
|
||||||
|
<Caret Line="152" Column="18"/>
|
||||||
</Position15>
|
</Position15>
|
||||||
<Position16>
|
<Position16>
|
||||||
<Filename Value="..\P6502utils.pas"/>
|
<Filename Value="..\P6502utils.pas"/>
|
||||||
<Caret Line="152" Column="18"/>
|
<Caret Line="19" Column="38"/>
|
||||||
</Position16>
|
</Position16>
|
||||||
<Position17>
|
<Position17>
|
||||||
<Filename Value="..\P6502utils.pas"/>
|
<Filename Value="..\P6502utils.pas"/>
|
||||||
<Caret Line="19" Column="38"/>
|
<Caret Line="144" Column="26" TopLine="20"/>
|
||||||
</Position17>
|
</Position17>
|
||||||
<Position18>
|
<Position18>
|
||||||
<Filename Value="..\P6502utils.pas"/>
|
<Filename Value="..\P6502utils.pas"/>
|
||||||
<Caret Line="144" Column="26" TopLine="20"/>
|
<Caret Line="201" Column="42" TopLine="180"/>
|
||||||
</Position18>
|
</Position18>
|
||||||
<Position19>
|
<Position19>
|
||||||
<Filename Value="..\P6502utils.pas"/>
|
|
||||||
<Caret Line="201" Column="42" TopLine="180"/>
|
|
||||||
</Position19>
|
|
||||||
<Position20>
|
|
||||||
<Filename Value="..\CPUCore.pas"/>
|
<Filename Value="..\CPUCore.pas"/>
|
||||||
<Caret Line="88" Column="3" TopLine="71"/>
|
<Caret Line="88" Column="3" TopLine="71"/>
|
||||||
</Position20>
|
</Position19>
|
||||||
<Position21>
|
<Position20>
|
||||||
<Filename Value="..\P6502utils.pas"/>
|
<Filename Value="..\P6502utils.pas"/>
|
||||||
<Caret Line="1129" Column="48" TopLine="1113"/>
|
<Caret Line="1129" Column="48" TopLine="1113"/>
|
||||||
|
</Position20>
|
||||||
|
<Position21>
|
||||||
|
<Filename Value="..\CPUCore.pas"/>
|
||||||
|
<Caret Line="88" Column="16" TopLine="71"/>
|
||||||
</Position21>
|
</Position21>
|
||||||
<Position22>
|
<Position22>
|
||||||
<Filename Value="..\CPUCore.pas"/>
|
<Filename Value="..\CPUCore.pas"/>
|
||||||
<Caret Line="88" Column="16" TopLine="71"/>
|
|
||||||
</Position22>
|
</Position22>
|
||||||
<Position23>
|
<Position23>
|
||||||
<Filename Value="..\CPUCore.pas"/>
|
|
||||||
</Position23>
|
|
||||||
<Position24>
|
|
||||||
<Filename Value="..\P6502utils.pas"/>
|
<Filename Value="..\P6502utils.pas"/>
|
||||||
<Caret Line="1129" Column="48" TopLine="1113"/>
|
<Caret Line="1129" Column="48" TopLine="1113"/>
|
||||||
</Position24>
|
</Position23>
|
||||||
<Position25>
|
<Position24>
|
||||||
<Filename Value="..\CPUCore.pas"/>
|
<Filename Value="..\CPUCore.pas"/>
|
||||||
<Caret Line="88" Column="42" TopLine="37"/>
|
<Caret Line="88" Column="42" TopLine="37"/>
|
||||||
</Position25>
|
</Position24>
|
||||||
<Position26>
|
<Position25>
|
||||||
<Filename Value="..\P6502utils.pas"/>
|
<Filename Value="..\P6502utils.pas"/>
|
||||||
<Caret Line="1134" Column="7" TopLine="1115"/>
|
<Caret Line="1134" Column="7" TopLine="1115"/>
|
||||||
</Position26>
|
</Position25>
|
||||||
<Position27>
|
<Position26>
|
||||||
<Filename Value="..\CPUCore.pas"/>
|
<Filename Value="..\CPUCore.pas"/>
|
||||||
<Caret Line="64" Column="24" TopLine="37"/>
|
<Caret Line="64" Column="24" TopLine="37"/>
|
||||||
</Position27>
|
</Position26>
|
||||||
<Position28>
|
<Position27>
|
||||||
<Filename Value="..\P6502utils.pas"/>
|
<Filename Value="..\P6502utils.pas"/>
|
||||||
<Caret Line="1172" Column="12" TopLine="1150"/>
|
<Caret Line="1172" Column="12" TopLine="1150"/>
|
||||||
</Position28>
|
</Position27>
|
||||||
<Position29>
|
<Position28>
|
||||||
<Filename Value="unit1.pas"/>
|
<Filename Value="unit1.pas"/>
|
||||||
<Caret Line="131" Column="18" TopLine="113"/>
|
<Caret Line="131" Column="18" TopLine="113"/>
|
||||||
|
</Position28>
|
||||||
|
<Position29>
|
||||||
|
<Filename Value="..\P6502utils.pas"/>
|
||||||
|
<Caret Line="234" Column="30" TopLine="211"/>
|
||||||
</Position29>
|
</Position29>
|
||||||
|
<Position30>
|
||||||
|
<Filename Value="..\P6502utils.pas"/>
|
||||||
|
<Caret Line="1651" Column="5" TopLine="1620"/>
|
||||||
|
</Position30>
|
||||||
</JumpHistory>
|
</JumpHistory>
|
||||||
<RunParams>
|
<RunParams>
|
||||||
<FormatVersion Value="2"/>
|
<FormatVersion Value="2"/>
|
||||||
|
|
625
P6502utils.pas
625
P6502utils.pas
|
@ -539,7 +539,8 @@ Global variables used: "idIns", "modIns".
|
||||||
}
|
}
|
||||||
var
|
var
|
||||||
nemo: String;
|
nemo: String;
|
||||||
opCode, par1, par2: Byte;
|
opCode, par1: Byte;
|
||||||
|
par2: word;
|
||||||
begin
|
begin
|
||||||
if addr>CPUMAXRAM-1 then exit('');
|
if addr>CPUMAXRAM-1 then exit('');
|
||||||
opCode := ram[addr].value;
|
opCode := ram[addr].value;
|
||||||
|
@ -564,11 +565,19 @@ begin
|
||||||
aAbsolute: begin
|
aAbsolute: begin
|
||||||
nBytesProc := 3;
|
nBytesProc := 3;
|
||||||
if addr+2>CPUMAXRAM-1 then exit('');
|
if addr+2>CPUMAXRAM-1 then exit('');
|
||||||
par2 := ram[addr+2].value;
|
par2 := ram[addr+2].value<<8 + par1;
|
||||||
Result := nemo + '$'+IntToHex(par1 + par2*256, 4);
|
if useVarName and (ram[par2].name<>'') then begin
|
||||||
|
Result := nemo + ram[par2].name;
|
||||||
|
end else begin
|
||||||
|
Result := nemo + '$'+IntToHex(par2, 4);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
aZeroPage: begin
|
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;
|
nBytesProc := 2;
|
||||||
end;
|
end;
|
||||||
aRelative: begin
|
aRelative: begin
|
||||||
|
@ -633,8 +642,10 @@ Falta implementar las operaciones, cuando acceden al registro INDF, el Watchdog
|
||||||
los contadores, las interrupciones}
|
los contadores, las interrupciones}
|
||||||
var
|
var
|
||||||
opc: byte;
|
opc: byte;
|
||||||
nCycles, nBytes, tmp: byte;
|
nCycles, nBytes, tmp, off: byte;
|
||||||
target , addr: word;
|
target , addr: word;
|
||||||
|
C_tmp: Boolean;
|
||||||
|
tmpRes: integer;
|
||||||
begin
|
begin
|
||||||
//Decodifica instrucción
|
//Decodifica instrucción
|
||||||
aPC := PC.W;
|
aPC := PC.W;
|
||||||
|
@ -661,35 +672,233 @@ begin
|
||||||
end;
|
end;
|
||||||
//Execute
|
//Execute
|
||||||
case idIns of
|
case idIns of
|
||||||
i_ADC:; //add with carry
|
i_ADC: begin //add with carry
|
||||||
i_AND:; //and (with accumulator)
|
if STATUS_C then begin
|
||||||
i_ASL:; //arithmetic shift left
|
tmpRes := W + ram[addr].value + 1;
|
||||||
i_BCC:; //branch on carry clear
|
end else begin
|
||||||
i_BCS:; //branch on carry set
|
tmpRes := W + ram[addr].value;
|
||||||
i_BEQ:; //branch on equal (zero set)
|
end;
|
||||||
i_BIT:; //bit test
|
W := tmpRes and $FF;
|
||||||
i_BMI:; //branch on minus (negative set)
|
STATUS_Z := W = 0;
|
||||||
i_BNE: begin
|
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)
|
STATUS_C := (tmp and $80) <> 0; //Read bit 7
|
||||||
i_BPL:; //branch on plus (negative clear)
|
tmp := tmp << 1;
|
||||||
i_BRK:; //break / interrupt
|
STATUS_Z := tmp = 0;
|
||||||
i_BVC:; //branch on overflow clear
|
STATUS_N := tmp > 127;
|
||||||
i_BVS:; //branch on overflow set
|
|
||||||
i_CLC: STATUS_C := false; //clear carry
|
if modIns = aAcumulat then W := tmp
|
||||||
i_CLD: STATUS_D := false; //clear decimal
|
else ram[addr].value := tmp;
|
||||||
i_CLI: STATUS_I := false; //clear interrupt disable
|
end;
|
||||||
i_CLV: STATUS_V := false; //clear overflow
|
i_BCC: begin //branch on carry clear
|
||||||
i_CMP:; //compare (with accumulator)
|
if not STATUS_C then begin
|
||||||
i_CPX:; //compare with X
|
off := ram[aPC+1].value;
|
||||||
i_CPY:; //compare with Y
|
Inc(PC.W, nBytes); //Normal Increase PC
|
||||||
i_DEC:; //decrement
|
if off>127 then begin
|
||||||
i_DEX:; //decrement X
|
PC.W := (PC.W + off - 256) and $FFFF;
|
||||||
i_DEY:; //decrement Y
|
end else begin
|
||||||
i_EOR:; //exclusive or (with accumulator)
|
PC.W := (PC.W + off) and $FFFF;
|
||||||
i_INC:; //increment
|
end;
|
||||||
i_INX:; //increment X
|
//Inc(PC.W, nBytes); //No apply
|
||||||
i_INY:; //increment Y
|
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
|
i_JMP: begin //jump
|
||||||
case modIns of
|
case modIns of
|
||||||
aAbsolute : begin
|
aAbsolute : begin
|
||||||
|
@ -734,22 +943,81 @@ begin
|
||||||
STATUS_Z := Y = 0;
|
STATUS_Z := Y = 0;
|
||||||
STATUS_N := Y > 127;
|
STATUS_N := Y > 127;
|
||||||
end;
|
end;
|
||||||
i_LSR:; //logical shift right
|
i_LSR: begin
|
||||||
i_NOP:; //no operation
|
STATUS_N := false;
|
||||||
i_ORA:; //or with accumulator
|
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
|
i_PHA: begin //push accumulator
|
||||||
ram[$100 + SP].value := W;
|
ram[$100 + SP].value := W;
|
||||||
if SP = $00 then SP := $FF else dec(SP);
|
if SP = $00 then SP := $FF else dec(SP);
|
||||||
end;
|
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
|
i_PLA: begin //pull accumulator
|
||||||
if SP = $FF then SP := $00 else inc(SP);
|
if SP = $FF then SP := $00 else inc(SP);
|
||||||
W := ram[$100 + SP].value;
|
W := ram[$100 + SP].value;
|
||||||
end;
|
end;
|
||||||
i_PLP:; //pull processor status (SR)
|
i_PLP: begin //pull processor status (SR)
|
||||||
i_ROL:; //rotate left
|
if SP = $FF then SP := $00 else inc(SP);
|
||||||
i_ROR:; //rotate right
|
SR := ram[$100 + SP].value;
|
||||||
i_RTI:; //return from interrupt
|
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
|
i_RTS: begin //return from subroutine
|
||||||
if SP = $FF then SP := $00 else inc(SP);
|
if SP = $FF then SP := $00 else inc(SP);
|
||||||
PC.L := ram[$100 + SP].value;
|
PC.L := ram[$100 + SP].value;
|
||||||
|
@ -759,7 +1027,17 @@ begin
|
||||||
Inc(nClck, nCycles);
|
Inc(nClck, nCycles);
|
||||||
exit;
|
exit;
|
||||||
end;
|
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_SEC: STATUS_C := true; //set carry
|
||||||
i_SED: STATUS_D := true; //set decimal
|
i_SED: STATUS_D := true; //set decimal
|
||||||
i_SEI: STATUS_I := true; //set interrupt disable
|
i_SEI: STATUS_I := true; //set interrupt disable
|
||||||
|
@ -787,260 +1065,23 @@ begin
|
||||||
STATUS_Z := X = 0;
|
STATUS_Z := X = 0;
|
||||||
STATUS_N := X > 127;
|
STATUS_N := X > 127;
|
||||||
end;
|
end;
|
||||||
i_TXA:; //transfer X to accumulator
|
i_TXA: begin //transfer X to accumulator
|
||||||
i_TXS:; //transfer X to stack pointer
|
W := X;
|
||||||
i_TYA:; //transfer Y to accumulator
|
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
|
i_Inval: begin
|
||||||
MsjError := 'Invalid Opcode';
|
MsjError := 'Invalid Opcode';
|
||||||
end;
|
end;
|
||||||
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
|
//Increase counters
|
||||||
Inc(PC.W, nBytes);
|
Inc(PC.W, nBytes);
|
||||||
Inc(nClck, nCycles);
|
Inc(nClck, nCycles);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user