pinkerton5

Why Not Assembler 1.1

Jun 30th, 2021 (edited)
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 6.31 KB | None | 0 0
  1.  program wnASSEMBLER; // 2021.07.03. 23:06:53
  2.                       // Fresh News: LABELS, 3 New Instruct, ORIGIN & a FLAG  
  3.                       // wn means: Why Not?  
  4.                       // ++ > Hex input. Format: $00 - $FF
  5.   uses sysutils;                        // <- strToInt
  6.   const
  7.    BASE    =  96;  
  8.    PAGES   =  6;                        // oszto
  9.    DATMAX  = (BASE div PAGES)-2;        // Adatszegmens kapacitasa
  10.    INITIP  =  BASE div PAGES;           // Origin (10h)
  11.    PREHEX  = '$';                       // Hex num. prefixe. Csak '$' lehet!!!
  12.                                         // igy nem kell konverzios fuggv.-t irni.  
  13.   var
  14.    Ch      : Char;                      // bejovo karakter puffere
  15.    Token   : string;                    // token  puffere
  16.    DATCount: integer = 0;               // Valtozok szamlaloja
  17.    NonDAT  : boolean = false;
  18.    IP      : byte    = 1;               // mem[00] foglalva a visszateresi cimnek
  19.                                         // igy az elso DATA cime a mem[01]!                                        
  20.    ORIGIP  : byte    = 0;               // foprogram cime
  21.    MEM     : array[0..(BASE-1)]of byte; // Memoria (64, 96, 128 vagy 256 byte)
  22.    LBL     : array[0..9] of byte;       // labelek cimei
  23.    
  24.  Procedure Error(s: string);            // hiba
  25.  begin
  26.    writeln(s);  
  27.    halt;
  28.  end;
  29.  
  30.  function GetLabelAddr(i: byte): byte;  // az i altal indexelt helyrol kiolvassaa az i label cimet.
  31.  begin
  32.    if (i > 9) then Error(' Unknown label or >9')  // ha i kisebb v egyenlo 9
  33.     else            
  34.    GetLabelAddr := LBL[i];
  35.  end;  
  36.  
  37.  procedure SetLabelAddr(i: byte);       // az i altal indexelt helyre beirja i azonosítoju label cimet
  38.  begin
  39.    if (i > 9) or (LBL[i] > 0) then Error(' Duplicated Label or >9')
  40.     else
  41.    LBL[i] := IP;
  42.  end;  
  43.                  
  44.  Procedure GetCh;                       // Egy karaktert olvas a STD bemenetrol
  45.  begin
  46.    Read(Ch);                            // a Ch nevu Char tip. valtozoba  
  47.  end;
  48.  
  49.  function AlphaBet(c : char) : boolean; // true-val ter vissza, ha a c eleme A..Z halmaznak
  50.  begin
  51.    AlphaBet := UpCase(c) in ['A'..'Z'];
  52.  end;
  53.  
  54.  function Numeric(c : char) : boolean;  // true-val ter vissza, ha c eleme a 0..9 halmaznak
  55.  begin
  56.    Numeric := (Upcase(c) in ['0'..'9','A'..'F',PREHEX]);
  57.  end;
  58.  
  59.  function Labels(c : char) : boolean;   // true-val ter vissza, ha a c egy label prefix karaktere
  60.  begin
  61.    Labels := (c = '#');
  62.  end;
  63.  
  64.  procedure DropWhite;                   // kiejti a feldolgozasbol a space es TAB karaktereket
  65.  begin
  66.    while  Ch in [' ',#09] do GetCh;
  67.  end;
  68.    
  69.  function GetKeyWord : string;          // ha token elso Ch key akkor ez kiegesziti
  70.  var
  71.    i  : byte = 0;
  72.  begin
  73.    GetKeyWord := '';
  74.    while AlphaBet(Ch) do
  75.    begin  
  76.     GetKeyWord := GetKeyWord + UpCase(Ch);
  77.     GetCh;
  78.     inc(i);
  79.    end;
  80.    if (i <> 3) then error(' Keyword error: '+GetKeyWord );
  81.  end;
  82.  
  83.  function GetNumber : string;           // ha token elso Ch NUM akkor ez kiegesziti
  84.  var
  85.    i  : byte = 0;
  86.  begin
  87.    GetNumber := '';
  88.    while Numeric(Ch) do
  89.    begin
  90.     GetNumber := GetNumber + Ch;
  91.     GetCh;
  92.     inc(i);
  93.    end;
  94.    if (i > 3) then error(' Error (number length?)');
  95.  end;
  96.  
  97.  function GetLabel : string;         // ha token elso Ch Label akkor ez kiegesziti
  98.  begin
  99.   GetLabel := Ch;
  100.   GetCh;
  101.   if (numeric(Ch) <> true) then Error(' Label error: #'+Ch);  
  102.   Getlabel:= Getlabel+Ch;  
  103.   GetCh;
  104.   if Ch = ':' then GetLabel := GetLabel+Ch;  
  105.  end;
  106.  
  107.  function GetToken : string;                    // a Token tipusanak szelektora  
  108.  begin
  109.    DropWhite;
  110.    if AlphaBet(Ch) then GetToken := GetKeyWord
  111.      else
  112.    if Numeric(Ch)  then GetToken := GetNumber
  113.      else
  114.    if Labels(Ch)   then GetToken := GetLabel
  115.      else  
  116.      begin GetToken := Ch; GetCh; end;
  117.    DropWhite;
  118.  end;
  119.  
  120.  procedure MemLoad(key: string);
  121.  begin
  122.    case key of
  123.     'INC': MEM[IP]:= $F1;
  124.     'DEC': MEM[IP]:= $F0;
  125.     'SWP': MEM[IP]:= $CD;
  126.     'ORG': begin ORIGIP := IP; dec(IP); end;
  127.      //----------------------- orig. instructions:
  128.     'SUB': MEM[IP]:= $AA;  
  129.     'ADD': MEM[IP]:= $AD;  
  130.     'CMP': MEM[IP]:= $C0;  
  131.     'JMP': MEM[IP]:= $EA;  
  132.     'JZR': MEM[IP]:= $E0;  
  133.     'LDA': MEM[IP]:= $AB;  
  134.     'STA': MEM[IP]:= $BA;  
  135.     'RET': MEM[IP]:= $FF;  
  136.     'DAT': if (DATCount < DATMAX) then inc(DATCount) else  error(' Too much Vars?');
  137.      else error('Unknown keyword: '+key);
  138.    end; {case}    
  139.    if (key <> 'DAT') then inc(IP);
  140.  end;
  141.  
  142.   procedure CheckDAT;
  143.  begin
  144.    if (Token[1] <> 'D') then NonDAT := true;          
  145.    if (NonDAT = true) and (IP < INITIP) then IP := INITIP;
  146.  end;
  147.  
  148.  procedure MemSaveToFile;  // binary file borning. This is the GENESIS!
  149.  var i: byte;
  150.      f: file of byte;
  151.  begin
  152.    Assign(f,paramstr(1));
  153.    rewrite(f,1);
  154.    MEM[00] := ORIGIP;
  155.    for i := 0 to BASE-1 do write(f,MEM[i]);
  156.    close(f);
  157.  end;  
  158.   // -----------------  Please, fasten Your safety Belt!  
  159.  begin
  160.    GetCh;             //  The first step        
  161.    repeat
  162.      Token := GetToken;
  163.      
  164.      if (Token = ';') or (Ch = ':') then while (Ch <> #10) do GetCh; // decommenter      
  165.      if (Token <> #13) and (Token <> #10) and (token <> ';') then
  166.      begin          
  167.        if Alphabet(Token[1]) then                               // if keyWord
  168.        begin
  169.         CheckDAT;
  170.         if (IP <= BASE-1) then MemLoad(Upcase(Token))  else error(' program is too big');
  171.        end      
  172.        else            
  173.        if Numeric(Token[1]) then                                // if ADDR or param
  174.        begin
  175.        if (Token[2] = PREHEX) or (Token[3] = PREHEX) then  error(' Invalid HEX');
  176.         if (StrToInt(Token) < 256) then MEM[IP]:= StrToInt(Token) else  error(' BIG int?');
  177.         inc(IP);
  178.        end              
  179.        else      
  180.        if Labels(Token[1]) then                                 // if Label
  181.        begin
  182.         CheckDAT;
  183.          if (length(Token) > 2) then SetLabelAddr(StrToInt(Token[2]))
  184.          else
  185.          begin
  186.           MEM[IP] := GetLabelAddr(StrToInt(Token[2]));  
  187.           Inc(IP);
  188.          end;
  189.        end              
  190.        else Error(' Hurray, its a BRAVE NEW token: '+Token);    
  191.      end;   //  if (token <> #13)
  192.    until EOF(input);
  193.          
  194.    MemSaveToFile;  
  195.  end.
  196.  
Add Comment
Please, Sign In to add comment