program uASM; // 2021.06.30. 6:24:22
uses sysutils; // <- strToInt
const
BASE = 64; // memoria merete, byte-ban
DATMAX = (BASE div 4)-2; // Adatszegmens kapacitasa
INITIP = BASE div 4; // Origin (10h)
var
Ch : Char; // bejovo karakter puffere
Token : string; // token puffere
DATCount: integer = 0; // Valtozok szamlaloja
NonDAT : boolean = false;
IP : byte = 1; // mem[0] foglalva a visszateresi cimnek
// igy az elso DATA cime a mem[1]!
MEM : array[0..(BASE-1)]of byte; // Memoria (64, 128 vagy 256 byte)
LBL : array[0..9] of byte; // labels addresses
Procedure Error(s: string); // hiba
begin
writeln(s); halt;
end;
function GetLblAddr(i: byte): byte; // Get
begin
if (i > 9) then Error(' Unknown label or >9? ')
else
GetLblAddr := LBL[i];
end;
procedure SetLblAddr(i: byte); // Set
begin
if (i > 9) or (LBL[i] > 0) then Error(' Duplicated Lbl or >9')
else
LBL[i] := IP;
end;
Procedure GetCh;
begin
Read(Ch);
end;
function AlphaBet(c : char) : boolean;
begin
AlphaBet := UpCase(c) in ['A'..'Z'];
end;
function Numeric(c : char) : boolean;
begin
Numeric := (c in ['0'..'9']);
end;
function Labels(c : char) : boolean;
begin
Labels := (c in ['#']);
end;
procedure DropWhite;
begin
while Ch in [' ',#09] do GetCh;
end;
// -----------------------------------------------
function GetKeyWord : string;
var
i : byte = 0;
begin
GetKeyWord := '';
while AlphaBet(Ch) do
begin
GetKeyWord := GetKeyWord + UpCase(Ch);
GetCh;
inc(i);
end;
if (i <> 3) then error(' Keyword error: '+GetKeyWord );
end;
function GetNumber : string;
var
i : byte = 0;
begin
GetNumber := '';
while Numeric(Ch) do
begin
GetNumber := GetNumber + Ch;
GetCh;
inc(i);
end;
if (i > 3) then error(' Error (number length?)');
end;
function GetLbl : string;
begin
GetLbl := Ch; GetCh;
Getlbl:= Getlbl+Ch; GetCh;
if Ch = ':' then GetLbl := GetLbl + Ch;
end;
function GetToken : string;
begin
DropWhite;
if AlphaBet(Ch) then GetToken := GetKeyWord
else
if Numeric(Ch) then GetToken := GetNumber
else
if Labels(Ch) then GetToken := GetLbl
else
begin
GetToken := Ch;
GetCh;
end;
DropWhite;
end;
procedure MemLoad(key: string);
begin
case Upcase(key) of
'SUB': MEM[IP]:= $AA;
'ADD': MEM[IP]:= $AD;
'CMP': MEM[IP]:= $C0;
'JMP': MEM[IP]:= $EA;
'JZR': MEM[IP]:= $E0;
'LDA': MEM[IP]:= $AB;
'STA': MEM[IP]:= $BA;
'RET': MEM[IP]:= $FF;
'DAT': if (DATCount < DATMAX) then inc(DATCount) else error(' Too much Vars?');
else error('Unknown keyword: '+key);
end; {case}
if UpCase(key) <> 'DAT' then inc(IP);
end;
procedure MemSaveToFile;
var i: byte;
f: file of byte;
begin
Assign(f,paramstr(1)); rewrite(f,1);
for i := 0 to BASE-1 do write(f,MEM[i]);
close(f);
end;
// -----------------
begin
GetCh;
repeat
Token := GetToken;
if (Token = ';') or (Ch = ':') then while (Ch <> #10) do GetCh; // comment szuro
if (Token <> #13) and (Token <> #10) and (token <> ';') then
begin
if Alphabet(Token[1]) then // ha kulcsszo
begin
if (Token[1] <> 'D') then NonDAT := true;
if (NonDAT = true) and (IP < INITIP) then IP := INITIP;
if (IP <= BASE-1) then MemLoad(Token) else error(' program is too big');
end
else
if Numeric(Token[1]) then // ha parameter
begin
if (StrToInt(Token) <= 255) then MEM[IP]:= StrToInt(Token) else error(' BIG integer? ');
inc(IP);
end
else
if Labels(Token[1]) then // ha label
begin
if length(Token) > 2 then SetLblAddr(StrToInt(Token[2]))
else
begin
MEM[IP] := GetLblAddr(StrToInt(Token[2]));
Inc(IP,1);
end;
end
else Error(' Unknown token: '+Token);
end; // if token <> CR
until EOF(input);
MemSaveToFile;
end.