diff --git a/CPUCore.pas b/CPUCore.pas index 34af9e5..30c1b6f 100644 --- a/CPUCore.pas +++ b/CPUCore.pas @@ -21,9 +21,14 @@ type end; TCPUCellState = ( - cs_impleGPR, //Implemented. Can be used. + cs_implemen, //Implemented. Can be used. cs_unimplem //Not implemented. ); + TCPURamUsed = ( + ruUnused, + ruCode, //Used for code + ruVar //Used for variable + ); type //Models for RAM memory @@ -39,9 +44,9 @@ type //Models for RAM memory function Getvalue: byte; procedure Setvalue(AValue: byte); public - name : string; //Name of the register (for variables) - used : boolean; //Indicates if have been written - shared : boolean; //Used to share this register + name : string; //Name of the register (for variables) + used : TCPURamUsed; //Indicates if have been written + shared : boolean; //Used to share this register state : TCPUCellState; //Status of the cell property value: byte read Getvalue write Setvalue; property dvalue: byte read Fvalue write Fvalue; //Direct access to "Fvalue". @@ -98,7 +103,7 @@ type procedure DisableAllRAM; procedure SetStatRAM(i1, i2: word; status0: TCPUCellState); function SetStatRAMCom(strDef: string): boolean; - function HaveConsecRAM(const i, n: word; maxRam: word): boolean; //Indica si hay "n" bytes libres + function HaveConsecRAM(const i, n: word; maxRam: dword): boolean; //Indica si hay "n" bytes libres procedure UseConsecRAM(const i, n: word); //Ocupa "n" bytes en la posición "i" procedure SetSharedUnused; procedure SetSharedUsed; @@ -143,7 +148,7 @@ end; function TCPURamCell.Avail: boolean; {Indica si el registro es una dirección disponible en la memoria RAM.} begin - Result := (state = cs_impleGPR); + Result := (state = cs_implemen); end; { TCPUCore } @@ -155,7 +160,7 @@ var begin for i:=0 to high(ram) do begin ram[i].dvalue := $00; - ram[i].used := false; + ram[i].used := ruUnused; ram[i].name:=''; ram[i].shared := false; ram[i].breakPnt := false; @@ -234,7 +239,7 @@ begin end; staMem := copy(com, 9, 3); case staMem of - 'IMP': state := cs_impleGPR; + 'IMP': state := cs_implemen; 'NIM': state := cs_unimplem; else MsjError := 'Memory definition syntax error: Expected SFR or GPR'; @@ -247,18 +252,18 @@ begin coms.Destroy; end; end; -function TCPUCore.HaveConsecRAM(const i, n: word; maxRam: word): boolean; +function TCPUCore.HaveConsecRAM(const i, n: word; maxRam: dword): boolean; {Indica si hay "n" bytes consecutivos libres en la posicióm "i", en RAM. La búsqueda se hace solo hasta la posición "maxRam"} var c: Integer; - j: word; + j: dword; begin Result := false; c := 0; j := i; while (j<=maxRam) and (c cs_impleGPR) or (ram[j].used) then exit; + if (ram[j].state <> cs_implemen) or (ram[j].used<>ruUnused) then exit; inc(c); //verifica siguiente inc(j); end; @@ -273,30 +278,28 @@ procedure TCPUCore.UseConsecRAM(const i, n: word); var j: word; begin for j:=i to i+n-1 do begin - ram[j].used := true; //todos los bits + ram[j].used := ruVar; //todos los bits end; end; procedure TCPUCore.SetSharedUnused; -{Marca las posiciones que estén en "shared", como no usadas, para que se puedan -usar nuevamente.} +{Set positions marked as "shared", as unused for to be used again.} var i: Integer; begin for i:=0 to high(ram) do begin - if (ram[i].state = cs_impleGPR) and (ram[i].shared) then begin - ram[i].used := false; //pone en cero + if (ram[i].state = cs_implemen) and (ram[i].shared) then begin + ram[i].used := ruUnused; end; end; end; procedure TCPUCore.SetSharedUsed; -{Marca las posiciones que estén en "shared", como usadas, para que no se puedan -usar nuevamente.} +{Set positions marked as "shared", as used, for NOT to be used again.} var i: Integer; begin for i:=0 to high(ram) do begin - if (ram[i].state = cs_impleGPR) and (ram[i].shared) then begin - ram[i].used := true; //pone en uno + if (ram[i].state = cs_implemen) and (ram[i].shared) then begin + ram[i].used := ruVar; //Set as used for variables end; end; end; @@ -306,7 +309,7 @@ var begin Result := 0; for i:=$0000 to CPUMAXRAM-1 do begin - if ram[i].used then inc(Result); + if ram[i].used<>ruUnused then inc(Result); end; end; //RAM name managment diff --git a/Cambios.txt b/Cambios.txt index c3e20ac..e3026d9 100644 --- a/Cambios.txt +++ b/Cambios.txt @@ -1,3 +1,9 @@ +0.2 +=== +Se cambian variables a tipo dword para evitar desborde en TP6502.GetFreeBytes(). +Se cambia el tipo del campo TCPURamCell.used al enumerado TCPURamUsed, para dar más libertad +para definir a la RAM. + 0.1 === Se eliminan algunos campos no usados, porque esta librería se ha creado a partir de la librería diff --git a/P6502utils.pas b/P6502utils.pas index 5988ce5..366cd0b 100644 --- a/P6502utils.pas +++ b/P6502utils.pas @@ -197,7 +197,7 @@ type procedure ExploreUsed(rutExplorRAM: TCPURutExplorRAM); //devuelve un reporte del uso de la RAM function ValidRAMaddr(addr: word): boolean; //indica si una posición de memoria es válida public //Métthods to code instructions according to syntax - procedure useRAM; + procedure useRAMCode; procedure codByte(const value: byte; isData: boolean); procedure codAsm(const inst: TP6502Inst; addMode: TP6502AddMode; param: word); procedure cod_JMP_at(iRam0: integer; const k: word); @@ -249,11 +249,11 @@ begin end; { TP6502 } -procedure TP6502.useRAM; +procedure TP6502.useRAMCode; {Marca la posición actual, como usada, e incrementa el puntero iRam. Si hay error, actualiza el campo "MsjError"} begin - ram[iRam].used := true; //marca como usado + ram[iRam].used := ruCode; //marca como usado inc(iRam); end; procedure TP6502.codByte(const value: byte; isData: boolean); @@ -265,7 +265,8 @@ begin end; ram[iRam].value := value; if isData then ram[iRam].name := 'data'; - useRAM; //marca como usado e incrementa puntero. + ram[iRam].used := ruVar; //marca como usado + inc(iRam); end; procedure TP6502.codAsm(const inst: TP6502Inst; addMode: TP6502AddMode; param: word); {General routine to codify assembler instructions.} @@ -284,7 +285,7 @@ begin exit; end; ram[iRam].value := rInst.instrInform[addMode].Opcode; - useRAM; //marca como usado e incrementa puntero. + useRAMCode; //marca como usado e incrementa puntero. //Codifica parámetros case addMode of aImplicit: begin @@ -310,55 +311,55 @@ begin MsjError:= 'Invalid Address Mode (Immediate)'; end; ram[iRam].value := lo(param); //escribe parámetro - useRAM; + useRAMCode; end; aAbsolute:begin ram[iRam].value := lo(param); - useRAM; + useRAMCode; ram[iRam].value := hi(param); - useRAM; + useRAMCode; end; aZeroPage:begin ram[iRam].value := lo(param); - useRAM; + useRAMCode; end; aRelative:begin ram[iRam].value := lo(param); - useRAM; + useRAMCode; end; aIndirect:begin ram[iRam].value := lo(param); - useRAM; + useRAMCode; ram[iRam].value := hi(param); - useRAM; + useRAMCode; end; aAbsolutX:begin ram[iRam].value := lo(param); - useRAM; + useRAMCode; ram[iRam].value := hi(param); - useRAM; + useRAMCode; end; aAbsolutY:begin ram[iRam].value := lo(param); - useRAM; + useRAMCode; ram[iRam].value := hi(param); - useRAM; + useRAMCode; end; aZeroPagX:begin ram[iRam].value := lo(param); - useRAM; + useRAMCode; end; aZeroPagY:begin ram[iRam].value := lo(param); - useRAM; + useRAMCode; end; aIndirecX:begin ram[iRam].value := lo(param); - useRAM; + useRAMCode; end; aIndirecY:begin ram[iRam].value := lo(param); - useRAM; + useRAMCode; end; else raise Exception.Create('Implementation Error.'); @@ -1093,7 +1094,7 @@ begin stopped := true; exit; end; - if not ram[_pc].used then begin + if ram[_pc].used = ruUnused then begin //Encontró un BreakPoint, sale sin ejecutar esa instrucción if OnExecutionMsg<>nil then OnExecutionMsg('Stopped for executing unused code.'); stopped := true; @@ -1150,9 +1151,9 @@ begin 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 - if (ram[i].state = cs_impleGPR) and (not ram[i].used) then begin + if (ram[i].state = cs_implemen) and (ram[i].used = ruUnused) then begin //Esta dirección está libre - ram[i].used := true; //marca como usado + ram[i].used := ruVar; //marca como usado para variable if shared then begin ram[i].shared := true; //Marca como compartido end; @@ -1168,8 +1169,8 @@ function TP6502.GetFreeBytes(const size: integer; var addr: word): boolean; del tamaño indicado. Si encuentra espacio, devuelve TRUE. El tamaño se da en bytes, pero si el valor es negativo, se entiende que es en bits.} var - i: word; - maxRam: Word; + i: dword; + maxRam: dWord; begin Result := false; //valor por defecto if size=0 then exit; @@ -1203,7 +1204,7 @@ var begin Result := 0; for i := 0 to CPUMAXRAM - 1 do begin - if ram[i].Avail and (ram[i].used) then begin + if ram[i].Avail and (ram[i].used<>ruUnused) then begin //Notar que "AvailGPR" asegura que no se consideran registros maepados Result := Result + 1; end; @@ -1215,7 +1216,7 @@ var i: Integer; begin for i := 0 to CPUMAXRAM - 1 do begin - if ram[i].Avail and (ram[i].used) then begin + if ram[i].Avail and (ram[i].used<>ruUnused) then begin rutExplorRAM(i, @ram[i]); end; end; @@ -1245,21 +1246,25 @@ begin end; i := minUsed; while i <= maxUsed do begin - //Verifica si es variable - if ram[i].name <> '' then begin - //Escribe en forma de variable - if incAdrr then begin - lOut.Add( PadRight(ram[i].name, Length(SPACEPAD)) + '$'+IntToHex(i,4) + ' DB ??'); - end else begin - lOut.Add( PadRight(ram[i].name, Length(SPACEPAD)) + 'DB ??'); - end; - i := i + 1; - continue; - end; //Lee comentarios y etiqueta lblLin := ram[i].topLabel; comLat := ram[i].sideComment; comLin := ram[i].topComment; + //Verifica si es variable + if ram[i].used = ruVar then begin + //Escribe en forma de variable + if incAdrr then begin + if comLin<>'' then lOut.add(comLin); + //lOut.Add( PadRight(ram[i].name, Length(SPACEPAD)) + '$'+IntToHex(i,4) + ' DB ??'); + lOut.Add( PadRight(ram[i].name, Length(SPACEPAD)) + '$'+IntToHex(i,4) + ' DB ' + + IntToHEx(ram[i].value,2) ); + end else begin + //lOut.Add( PadRight(ram[i].name, Length(SPACEPAD)) + 'DB ??'); + lOut.Add( PadRight(ram[i].name, Length(SPACEPAD)) + 'DB ' + IntToHEx(ram[i].value,2) ); + end; + i := i + 1; + continue; + end; //Escribe etiqueta al inicio de línea if lblLin<>'' then lOut.Add(lblLin+':'); //Escribe comentario al inicio de línea @@ -1309,7 +1314,7 @@ begin maxUsed := 0; //Busca dirección de inicio usada for i := 0 to CPUMAXRAM-1 do begin - if ram[i].used then begin + if ram[i].used<>ruUnused then begin if imaxUsed then maxUsed := i; end; @@ -1333,7 +1338,7 @@ begin SetLength(ram, CPUMAXRAM); //inicia una configuración común ClearMemRAM; - SetStatRAM($020, $04F, cs_impleGPR); + SetStatRAM($020, $04F, cs_implemen); //Estado inicial iRam := 0; //posición de inicio