Add files via upload

This commit is contained in:
Tito Hinostroza 2019-07-22 00:54:54 -05:00 committed by GitHub
parent 1d05a351f9
commit 729875617f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 180 additions and 69 deletions

View File

@ -52,7 +52,8 @@ type //Models for RAM memory
state : TCPUCellState; //Status of the cell
property value: byte read Getvalue write Setvalue;
property dvalue: byte read Fvalue write Fvalue; //Direct access to "Fvalue".
function Avail: boolean;
function Avail: boolean; //RAM implemented to use in programs
function Free: boolean; //RAM implemented and unused
public //Campos para deputación
breakPnt : boolean; //Indicates if this cell have a Breakpoint
{Be careful on the size of this record, because it's going to be multiplied by 64K}
@ -76,8 +77,10 @@ type //Models for RAM memory
type
{ TCPUCore }
{Abcestor of all 8 bits PIC cores}
{Abcestor of all 8 bits CPU cores}
TCPUCore = class
private
function GetTokAddress(var str: string; delimiter: char): word;
public //Limits
{This variables are set just one time. So they work as constant.}
CPUMAXRAM: dword; //Max virtual RAM used by the CPU
@ -91,7 +94,7 @@ type
nClck : Int64; //Contador de ciclos de reloj
CommStop: boolean; //Bandera para detener la ejecución
OnExecutionMsg: procedure(message: string) of object; //Genera mensaje en ejecución
protected //Generation of HEX files
protected //Generation of PRG files
minUsed : dword; //Dirección menor de la ROM usada
maxUsed : dword; //Dirección mayor de la ROM usdas
hexLines : TStringList; //Uusado para crear archivo *.hex
@ -101,6 +104,9 @@ type
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;
procedure ClearMemRAM;
procedure DisableAllRAM;
procedure SetStatRAM(i1, i2: word; status0: TCPUCellState);
@ -110,7 +116,7 @@ type
procedure UseConsecRAM(const i, n: word); //Ocupa "n" bytes en la posición "i"
procedure SetSharedUnused;
procedure SetSharedUsed;
public //ram memory functions
public //RAM memory functions
function UsedMemRAM: word; //devuelve el total de memoria ram usada
public //RAM name managment
function NameRAM(const addr: word): string;
@ -128,6 +134,7 @@ type
function ReadPC: dword; virtual; abstract; //Defined DWORD to cover the 18F PC register
procedure WritePC(AValue: dword); virtual; abstract;
public //Others
procedure addTopLabel(lbl: string); //Add a comment to the ASM code
procedure addTopComm(comm: string; replace: boolean = true); //Add a comment to the ASM code
procedure addSideComm(comm: string; before: boolean); //Add lateral comment to the ASM code
@ -149,29 +156,70 @@ begin
Fvalue := AValue;
end;
function TCPURamCell.Avail: boolean;
{Indica si el registro es una dirección disponible en la memoria RAM.}
{Indicates if the RAM cell is available for programmer.}
begin
Result := (state = cs_impleGPR);
end;
function TCPURamCell.Free: boolean;
begin
Result := (state = cs_impleGPR) and (used = ruUnused);
end;
function TCPUCore.GetTokAddress(var str: string; delimiter: char): word;
{Extract a number (address) from a string and delete until de delimiter.
If delimiter is #0, it's consider all the text.
If fail update the variable "MsjError".}
var
p: SizeInt;
n: Longint;
begin
if delimiter=#0 then begin
//Until the end of line
p := length(str) + 1;
end else begin
//Until delimiter
p := pos(delimiter, str);
if p = 0 then begin
MsjError := 'Expected "'+delimiter+'".';
exit(0);
end;
end;
//Have delimiter. Get number
if not TryStrToInt('$'+copy(str,1,p-1), n) then begin
MsjError := 'Wrong address.';
exit(0);
end;
delete(str, 1, p); //delete number and delimiter
if n<0 then begin
MsjError := 'Address cannot be negative.';
exit(0);
end;
if n>$FFFF then begin
MsjError := 'Address cannot be greater than $FFFF.';
exit(0);
end;
exit(n);
end;
{ TCPUCore }
//RAM memory functions
procedure TCPUCore.ClearMemRAM;
{Limpia el contenido de la memoria}
{Clear content of RAM. Doesn't change the state.}
var
i: Integer;
begin
for i:=0 to high(ram) do begin
ram[i].dvalue := $00;
ram[i].used := ruUnused;
ram[i].name:='';
ram[i].shared := false;
ram[i].breakPnt := false;
ram[i].topLabel := '';
ram[i].dvalue := $00;
ram[i].used := ruUnused;
ram[i].name :='';
ram[i].shared := false;
ram[i].breakPnt := false;
ram[i].topLabel := '';
ram[i].sideComment:= '';
ram[i].topComment := '';
ram[i].idFile := -1; //Indica no inicializado
// ram[i].state := cs_unimplem; //por defecto se considera no implementado
ram[i].topComment:= '';
ram[i].idFile := -1; //Not initialized.
{Don't change the implementation. Because "state" must be defined just once at the
First Pass when processing $CLEAR_STATE_RAM and $SET_STATE_RAM }
// ram[i].state := cs_impleGPR;
end;
end;
procedure TCPUCore.DisableAllRAM;
@ -196,20 +244,20 @@ begin
end;
end;
function TCPUCore.SetStatRAMCom(strDef: string): boolean;
{Define el estado de la memoria RAM, usando una cadena de definición.
La cadena de definición, tiene el formato:
<comando 1>, <comando 2>, ...
Cada comando, tiene el formato:
<dirIni>-<dirFin>:<estado de memoria>
Un ejemplo de cadena de definición, es:
'000-01F:IMP, 020-07F:NIM'
Si hay error, devuelve FALSE, y el mensaje de error en MsjError.
{Define the RAM state using a Definitions string.
Definitions string have the format:
<command 1>, <command 2>, ...
Each command have the format:
<addStart>-<addEnd>:<memory state>
One example for Definitions string, is:
'0000-01FF:SFR, 8000-FFFF:NIM'
If error ocurrs, return FALSE, and the error messaje in MsjError.
}
var
coms: TStringList;
add1, add2: longint;
state: TCPUCellState;
staMem, com, str: String;
com, str: String;
begin
Result := true;
coms:= TStringList.Create;
@ -219,33 +267,24 @@ begin
for str in coms do begin
com := UpCase(trim(str));
if com='' then continue;
if length(com)<>11 then begin
MsjError := 'Memory definition syntax error: Bad string size.';
//Find Address1
add1 := GetTokAddress(com, '-');
if MsjError<>'' then begin
MsjError := 'Memory definition syntax error: ' + MsjError;
exit(false);
end;
if com[4] <> '-' then begin
MsjError := 'Memory definition syntax error: Expected "-".';
//Find Address1
add2 := GetTokAddress(com, ':');
if MsjError<>'' then begin
MsjError := 'Memory definition syntax error: ' + MsjError;
exit(false);
end;
if com[8] <> ':' then begin
MsjError := 'Memory definition syntax error: Expected ":".';
exit(false);
end;
//Debe tener el formato pedido
if not TryStrToInt('$'+copy(com,1,3), add1) then begin
MsjError := 'Memory definition syntax error: Wrong address.';
exit(false);
end;
if not TryStrToInt('$'+copy(com,5,3), add2) then begin
MsjError := 'Memory definition syntax error: Wrong address.';
exit(false);
end;
staMem := copy(com, 9, 3);
case staMem of
'IMP': state := cs_impleGPR;
case copy(com,1,3) of
'SFR': state := cs_impleSFR;
'GPR': state := cs_impleGPR;
'NIM': state := cs_unimplem;
else
MsjError := 'Memory definition syntax error: Expected IMP or NIM';
MsjError := 'Memory definition syntax error: Expected SFR, GPR or NIM';
exit(false);
end;
//Ya se tienen los parámetros, para definir la memoria
@ -256,8 +295,42 @@ begin
end;
end;
function TCPUCore.SetDataAddr(strDef: string): boolean;
{Define primary address to be used for allocating variables.
Definitions string have the format:
<command 1>, <command 2>, ...
Each command have the format:
<addStart>-<addEnd>:<memory state>
One example for Definitions string, is:
'00F0-00FF'
If error ocurrs, return FALSE, and the error message in MsjError.
}
var
add1, add2: longint;
com: String;
begin
Result := true;
com := UpCase(trim(strDef));
if com='' then begin
hasDataAdrr := -1; //Disable
exit;
end;
//Find Address1
add1 := GetTokAddress(com, '-');
if MsjError<>'' then begin
MsjError := 'Memory definition syntax error: ' + MsjError;
exit(false);
end;
//Find Address1
add2 := GetTokAddress(com, #0);
if MsjError<>'' then begin
MsjError := 'Memory definition syntax error: ' + MsjError;
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;
function TCPUCore.HaveConsecRAM(const i, n: word; maxRam: dword): boolean;
{Indica si hay "n" bytes consecutivos libres en la posicióm "i", en RAM.
@ -270,7 +343,7 @@ begin
c := 0;
j := i;
while (j<=maxRam) and (c<n) do begin
if (ram[j].state <> cs_impleGPR) or (ram[j].used<>ruUnused) then exit;
if not ram[j].Free then exit;
inc(c); //verifica siguiente
inc(j);
end;
@ -393,6 +466,7 @@ end;
//Initialization
constructor TCPUCore.Create;
begin
hasDataAdrr := -1; //Disable
hexLines := TStringList.Create;
frequen := 1000000; //4MHz
end;

View File

@ -190,6 +190,7 @@ type
function DisassemblerAt(addr: word; out nBytesProc: byte; useVarName: boolean
): string; override;
public //RAM memory functions
freeStart: word; //Start address where Free RAM will be searched.
function GetFreeByte(out addr: word): boolean;
function GetFreeBytes(const size: integer; out addr: word): boolean; //obtiene una dirección libre
function TotalMemRAM: integer; //devuelve el total de memoria RAM
@ -206,7 +207,7 @@ type
public //Aditional methods
function FindOpcode(Op: string): TP6502Inst; //Find Opcode
function IsRelJump(idInst: TP6502Inst): boolean; //Idnetify realtive jumps Opcodes
procedure GenHex(hexFile: string); //genera un archivo hex
procedure GenHex(hexFile: string; startAddr: integer = - 1); //genera un archivo hex
procedure DumpCodeAsm(lOut: TStrings; incAdrr, incValues, incCom,
incVarNam: boolean);
public //Initialization
@ -1151,18 +1152,28 @@ var
begin
Result := false; //valor inicial
maxRam := CPUMAXRAM; //posición máxima
//Realmente debería explorar solo hasta la dirección implementada, por eficiencia
for i:=iRam to maxRam-1 do begin
//Verifica si hay zona de varaibles
if dataAddr1<>-1 then begin
//Busca en zona especial
for i:=dataAddr1 to dataAddr2 do begin
if (ram[i].state = cs_impleGPR) and (ram[i].used = ruUnused) then begin
//Esta dirección está libre
addr := i;
//Notar que la posición de memoria puede estar mapeada.
exit(true); //indica que encontró espacio
end;
end;
//No found. No more space available.
dataAddr1 := -1; //Deactivate
//Continue in the normal RAM
end;
//Busca en la zona normal
for i:=freeStart to maxRam-1 do begin
if (ram[i].state = cs_impleGPR) and (ram[i].used = ruUnused) then begin
//Esta dirección está libre
// ram[i].used := ruData; //marca como usado para variable
// if shared then begin
// ram[i].shared := true; //Marca como compartido
// end;
addr := i;
//Notar que la posición de memoria puede estar mapeada.
Result := true; //indica que encontró espacio
exit;
exit(true); //indica que encontró espacio
end;
end;
end;
@ -1179,10 +1190,24 @@ begin
exit(true);
end;
maxRam := CPUMAXRAM;
for i:=iRam to maxRam-1 do begin //verifica 1 a 1, por seguridad
//Verifica si hay zona de varaibles
if dataAddr1<>-1 then begin
//Busca en zona especial
for i:=dataAddr1 to dataAddr2 do begin
if HaveConsecRAM(i, size, maxRam) then begin
//Encontró del tamaño buscado
addr := i;
exit(true);
end;
end;
//No found. No more space available.
dataAddr1 := -1; //Deactivate
//Continue in the normal RAM
end;
//Busca en la zona normal
for i:=freeStart to maxRam-1 do begin //verifica 1 a 1, por seguridad
if HaveConsecRAM(i, size, maxRam) then begin
//encontró del tamaño buscado
//UseConsecRAM(i, size); //marca como usado
//Encontró del tamaño buscado
addr := i;
exit(true);
end;
@ -1304,22 +1329,34 @@ begin
i := i + nBytes; //Incrementa a siguiente instrucción
end;
end;
procedure TP6502.GenHex(hexFile: string);
procedure TP6502.GenHex(hexFile: string; startAddr: integer = -1);
{Genera el archivo *.hex, a partir de los datos almacenados en la memoria RAM.
Actualiza los campos, minUsed y maxUsed.}
var
i: Integer;
f: file of byte;
begin
hexLines.Clear; //Se usará la lista hexLines
//Prepara extracción de datos
minUsed := CPUMAXRAM;
maxUsed := 0;
//Busca dirección de inicio usada
for i := 0 to CPUMAXRAM-1 do begin
if ram[i].used in [ruCode, ruData] then begin
if i<minUsed then minUsed := i;
if i>maxUsed then maxUsed := i;
hexLines.Clear; //Clear list
if startAddr = -1 then begin
//Find first and last byte used
minUsed := CPUMAXRAM;
maxUsed := 0;
for i := 0 to CPUMAXRAM-1 do begin
//if ram[i].used in [ruCode, ruData] then begin //Changed in versión 0.7.1
if ram[i].used in [ruCode] then begin
if i<minUsed then minUsed := i;
if i>maxUsed then maxUsed := i;
end;
end;
end else begin
//Find only last byte used
minUsed := startAddr;
maxUsed := 0;
for i := minUsed to CPUMAXRAM-1 do begin
//if ram[i].used in [ruCode, ruData] then begin //Changed in versión 0.7.1
if ram[i].used in [ruCode] then begin
if i>maxUsed then maxUsed := i;
end;
end;
end;
//Genera archivo PRG
@ -1341,7 +1378,7 @@ begin
SetLength(ram, CPUMAXRAM);
//inicia una configuración común
ClearMemRAM;
SetStatRAM($020, $04F, cs_impleGPR);
SetStatRAM($0000, $FFFF, cs_impleGPR);
//Estado inicial
iRam := 0; //posición de inicio