Atmel Assembler version 001

In the other file I gave the EBNF code for the AVR Assembler I'm working on. As I told there I want to wet my appetite for making a code generator for the Plov compiler and this seems like an appropriate step to take. The source you see in the following section is in pre-alpha stage. The framework is active, yet not done. Lots of changes will be made, I guess.
Nonetheless, Fruttenboel is one of the few websites that do publish source code, AND, the evolution of the code is shown as well. So have a look at my current source, which bears the signs of the Plov, m4m and LiLi articles elsewhere on this website. Enjoy!

Some source

The source code for aa001.mod. Yesterday it compiled errorfree. It ran as well, but it didn't do anything yet. At this moment I'm adding features and functionality and I'm pretty sure nothing works...

MODULE aa001;

(*     This software is released under the rules of the GNU GPL. Please feel free to improve this software, 
       if needed. You may even port this source to a lesser language like C. This software comes without any
       warranty of any kind.
       *)

(* version   aaXXX is an assembler for Atmel AVR processors						*)
(*   0.01  : Try to get the framework running   	   	     			: , 2008	*)

IMPORT	ASCII, Arguments, InOut, MemPools, NumConv, Strings, SYSTEM, TextIO;


TYPE	Identifier		= ARRAY [0..31] OF CHAR;
	SymbolType		= (Label, Constant, Alias, Variable);
	Lstat			= (comment, label, space);

	SymbolPtr		= POINTER TO SymbolNode;
	PortPtr			= POINTER TO PortNode;
	BitNamesPtr		= POINTER TO BitNamesNode;
	OpcodePtr		= POINTER TO OpcodeNode;
	
	OpcodeNode		= RECORD
				    name	: Identifier;
				    minClass,
				    opcodeCode	: CARDINAL;
				    next	: OpcodePtr
				  END;

	SymbolNode		= RECORD
				    name	: Identifier;
				    type	: SymbolType;
				    next	: SymbolPtr;
				    value	: CARDINAL
				  END;

(*	type		value
	-------		--------
	Label 		Address in FLASH
	Constant	Value	
	Alias		Register number (may be ambiguous)
	Variable	Address in RAM
*)

	PortNode		= RECORD
				    number	: CARDINAL;
				    Name	: Identifier;
				    next	: PortPtr
				  END;

	BitNamesNode		= RECORD
				    RegName	: Identifier;
				    BitNr	: CARDINAL;
				    BitName	: Identifier;
				    next	: BitNamesPtr
				  END;


VAR	storage		 			: Arguments.ArgTable;
	listFile,
	lstFile, inFile, outFile		: TextIO.File;
	token, 
	Source, Target, path, option		: Identifier;
	PC, FlashRam, Eeprom, Sram, RAMstart,
	inRAM,
	cpuClass, line, column			: CARDINAL;
	DecodeNext, ok, BigFlash		: BOOLEAN;
	Symbols, Opcodes,
	PortNames, BitNames			: MemPools.MemPool;
	currentType				: SymbolType;
	firstOpcode, thisOpcode			: OpcodePtr;
	firstPort				: PortPtr;
	firstBitName				: BitNamesPtr;
	firstSymbol, thisSymbol			: SymbolPtr;


PROCEDURE UserMessage (nr    : CARDINAL);

BEGIN
   CASE  nr  OF
       0 : InOut.WriteCard (line, 5);	InOut.Write (':');     InOut.WriteCard (column, 5)
    |  1 : InOut.WriteString ("Syntax : aa infile [-t processortype] [-v]")
    |  2 : InOut.WriteString ("aa version 0.01, May 2008")
    |  3 : InOut.WriteString ("Could not open ");    InOut.WriteString (path)
    |  4 : InOut.WriteString ("Error in Configuration files. Aborting.")
    |  5 : InOut.WriteString ("Could not open source file. Aborting.")
    |  6 : InOut.WriteString ("No source file defined. Aborting.")
    |  7 : InOut.WriteString ("Could not create destination file.")
    |  8 : InOut.WriteString ("Premature end of file encountered. Aborting.")
    |  9 : InOut.WriteString ("Error in ");          
	   InOut.WriteString (path)
    | 10 : InOut.WriteString ("Illegal IO port number; ignoring.")
    | 11 : InOut.WriteString ("Duplicate opcode found: ");
	   InOut.WriteString (option);
	   InOut.WriteString (". Aborting.")
    | 12 : InOut.WriteString ("Error in number in ");
      	   UserMessage (0)
    | 13 : InOut.WriteString ("Duplicate symbol in ");
	   UserMessage (0)
    | 14 : InOut.WriteString ("Missing '=' token in ");
	   UserMessage (0)
    | 15 : InOut.WriteString ("Missing ':' token in ");
	   UserMessage (0)
    | 16 : InOut.WriteString ("")
    | 17 : InOut.WriteString ("")
    | 18 : InOut.WriteString ("")
    | 19 : InOut.WriteString ("")
   ELSE
      InOut.WriteString ("Something weird happened while processing line");
      UserMessage (0)
   END;
   InOut.WriteLn
END UserMessage;


PROCEDURE StoreOpcode (str	: Identifier; cat, opc	: CARDINAL) : BOOLEAN;

VAR	  thisOne, nextOne   : OpcodePtr;

BEGIN
   thisOne := firstOpcode;
   LOOP
      IF  Strings.StrEq (thisOne^.name, str)  THEN  RETURN FALSE  END;
      IF  thisOne^.next = NIL  THEN  EXIT  END;
      thisOne := thisOne^.next
   END;
   MemPools.PoolAllocate (Opcodes, nextOne, SYSTEM.TSIZE (OpcodeNode));
   thisOne^.next := nextOne;
   WITH  nextOne^  DO
      name 	 := str;
      minClass 	 := cat;
      opcodeCode := opc;
      next	 := NIL
   END;
   RETURN TRUE
END StoreOpcode;


PROCEDURE FindOpcode (str	: Identifier) : BOOLEAN;

VAR	  thisOne, nextOne   : OpcodePtr;

BEGIN
   thisOne := firstOpcode;
   LOOP
      IF  Strings.StrEq (thisOne^.name, str)  THEN
	 thisOpcode := thisOne;
	 RETURN TRUE
      END;
      IF  thisOne^.next = NIL  THEN  EXIT  END;
      thisOne := thisOne^.next
   END;
   RETURN  FALSE
END FindOpcode;


PROCEDURE StoreSymbol (str   : Identifier) : BOOLEAN;

VAR	  thisOne, nextOne   : SymbolPtr;

BEGIN
   thisOne := firstSymbol;
   LOOP
      IF  Strings.StrEq (thisOne^.name, str)  THEN  RETURN FALSE  END;
      IF  thisOne^.next = NIL  THEN  EXIT  END;
      thisOne := thisOne^.next
   END;
   MemPools.PoolAllocate (Symbols, nextOne, SYSTEM.TSIZE (SymbolNode));
   thisOne^.next := nextOne;
   WITH  nextOne^  DO
      name := str;
      type := currentType;
      next := NIL;
   END;
   thisSymbol := nextOne;
   RETURN TRUE
END StoreSymbol;


PROCEDURE FindSymbol (str  : Identifier) : BOOLEAN;

VAR	thisOne, nextOne : SymbolPtr;

BEGIN
   thisOne := firstSymbol;
   LOOP
      IF  Strings.StrEq (thisOne^.name, str)  THEN
	 thisSymbol := thisOne;
	 RETURN TRUE
      END;
      IF  thisOne^.next = NIL  THEN  EXIT  END;
      thisOne := thisOne^.next
   END;
   RETURN  FALSE
END FindSymbol;


PROCEDURE StorePort (str   : Identifier; nr   : CARDINAL) : BOOLEAN;

VAR	  this, prev, new	   : PortPtr;
	  result   	   	   : INTEGER;

BEGIN
   this := firstPort;
   prev := NIL;
   LOOP
      result := Strings.compare (this^.Name, str);
      IF  result = 0  THEN  RETURN FALSE  END;
      IF  result = 1  THEN  EXIT  END;
      prev := this;
      this := this^.next
   END;
   MemPools.PoolAllocate (PortNames, new, SYSTEM.TSIZE (PortNode));
   new^.Name := str;
   new^.number := nr;
   new^.next := this;
   IF  prev = NIL  THEN
      firstPort := new
   ELSE
      prev^.next := new
   END;
   RETURN TRUE
END StorePort;


PROCEDURE FindPort (n	   : CARDINAL; VAR str	  : Identifier);

VAR	  ThisOne    		: PortPtr;

BEGIN
   ThisOne := firstPort;
   LOOP
      IF  ThisOne^.number = n  THEN
         str := ThisOne^.Name;
	 EXIT
      ELSE
         ThisOne := ThisOne^.next
      END;
      IF  Strings.StrEq (ThisOne^.Name, "|")  THEN
         str := "Reserved";
      	 EXIT
      END;
   END
END FindPort;


PROCEDURE StoreBitName (port   : Identifier; bit   : CARDINAL; name   : Identifier);

VAR	  this, new, prev		: BitNamesPtr;

BEGIN
   this := firstBitName;
   prev := NIL;
   LOOP
      IF  Strings.compare (this^.RegName, port) >= 0  THEN  EXIT  END;
      prev := this;
      this := this^.next
   END;
   MemPools.PoolAllocate (BitNames, new, SYSTEM.TSIZE (BitNamesNode));
   WITH  new^  DO
      RegName := port;
      BitNr   := bit;
      BitName := name;
      next    := this
   END;
   IF  prev = NIL  THEN
      firstBitName := new
   ELSE
      prev^.next := new
   END
END StoreBitName;


PROCEDURE FindBitName (reg   : Identifier; bit   : CARDINAL; VAR  str    : Identifier);

VAR	  ThisOne 	   	: BitNamesPtr;
	  result		: INTEGER;

BEGIN
   ThisOne := firstBitName;
   LOOP
      result := Strings.compare (ThisOne^.RegName, reg);
      IF  result = 0  THEN
         LOOP
	    IF  bit = ThisOne^.BitNr  THEN
	       str := ThisOne^.BitName;
	       RETURN
	    ELSE
	       ThisOne := ThisOne^.next
	    END;
	    IF  Strings.StrEq (reg, ThisOne^.RegName) = FALSE  THEN  EXIT  END
	 END
      ELSIF  result = -1  THEN
         ThisOne := ThisOne^.next
      ELSE
         EXIT
      END
   END;
   str [0] := CHR (bit + ORD ('0'));
   str [1] := 0C
END FindBitName;


PROCEDURE ConfigureCPU () : BOOLEAN;

VAR  nr				: CARDINAL;
     PortName, BitName		: Identifier;

BEGIN
   InOut.WriteString ("Assembling source ");		InOut.WriteString (Source);
   InOut.WriteString (" for target processor ");	InOut.WriteString (Target);
   InOut.WriteLn;
   TextIO.OpenInput (inFile, Target);		(* Try to open it in current directory	*)
   IF  TextIO.Done () = FALSE  THEN
      path := "/usr/local/AVR/";
      Strings.Append (path, Target);
      TextIO.OpenInput (inFile, path);		(* Try to open it in /usr/local/AVR	*)
      IF  TextIO.Done () = FALSE  THEN
	 UserMessage (3);
	 InOut.WriteString ("Choosing ATmega8515 instead.");     		InOut.WriteLn;
	 InOut.WriteBf;
	 path := "/usr/local/AVR/ATmega8515";	(* Otherwise use the default CPU	*)
	 TextIO.OpenInput (inFile, path);
	 IF  TextIO.Done () = FALSE  THEN
	    UserMessage (3);
	    RETURN FALSE			(* If all fails, use your ejectionseat	*)
	 END
      END
   END;						(* The CFG file is now open		*)
   REPEAT
      TextIO.GetString (inFile, option);
      IF  TextIO.EOF (inFile) = TRUE  THEN  UserMessage (9);  RETURN FALSE  END
   UNTIL Strings.StrEq (option, 'BEGIN');
   LOOP
      IF  TextIO.EOF (inFile) = TRUE  THEN  UserMessage (9);  RETURN FALSE  END;
      TextIO.GetString (inFile, option);
      IF     Strings.StrEq (option, 'END')        = TRUE  THEN  EXIT
      ELSIF  Strings.StrEq (option, 'FLASH')      = TRUE  THEN  TextIO.GetCard (inFile, FlashRam)
      ELSIF  Strings.StrEq (option, 'EEPROM')     = TRUE  THEN  TextIO.GetCard (inFile, Eeprom)
      ELSIF  Strings.StrEq (option, 'SRAM') 	  = TRUE  THEN  TextIO.GetCard (inFile, Sram)
      ELSIF  Strings.StrEq (option, 'RAMSTART')	  = TRUE  THEN  TextIO.GetCard (inFile, RAMstart)
      ELSIF  Strings.StrEq (option, 'COMPILER')	  = TRUE  THEN
         REPEAT  TextIO.GetString (inFile, option)  UNTIL Strings.StrEq (option, 'END')
      ELSIF  Strings.StrEq (option, 'PORTS')	  = TRUE  THEN
         LOOP
	    TextIO.GetString (inFile, option);
	    IF  Strings.StrEq (option, 'END') = TRUE  THEN  EXIT  END;
	    NumConv.Str2Num (nr, 16, option, ok);
	    TextIO.GetString (inFile, PortName);
	    IF  NOT ok  THEN  
	       UserMessage (10)
	    ELSE
	       ok := StorePort (PortName, nr)
	    END
	 END
      ELSIF  Strings.StrEq (option, 'BITS')	  = TRUE  THEN
         LOOP
	    TextIO.GetString (inFile, PortName);
	    IF  Strings.StrEq (PortName, 'END') = TRUE  THEN  EXIT  END;
	    nr := 7;
	    LOOP
	       TextIO.GetString (inFile, BitName);
	       IF  BitName [0] # '-'  THEN  StoreBitName (PortName, nr, BitName)  END;
	       IF  nr = 0  THEN  EXIT  ELSE  DEC (nr)  END
	    END
	 END
      ELSE
         InOut.WriteString ('Invalid parameter in ');
	 InOut.WriteString (path);		  InOut.Write ('.');
	 InOut.WriteLn;
	 RETURN FALSE
      END
   END;
   TextIO.Close (inFile);
   IF  FlashRam > 4096  THEN  BigFlash := TRUE  ELSE  BigFlash := FALSE  END;
   RETURN TRUE
END ConfigureCPU;


PROCEDURE ConfigureOps () : BOOLEAN;

VAR	nr, cat, opc		: CARDINAL;

BEGIN
   path := "Opcodes";
   TextIO.OpenInput (inFile, path);		(* Try to open Opcodes file locally	*)
   IF  TextIO.Done () = FALSE  THEN
      path := "/usr/local/AVR/Opcodes";
      TextIO.OpenInput (inFile, path);		(* Or load systemwide version		*)
      IF  TextIO.Done () = FALSE  THEN
	 UserMessage (3);
	 RETURN FALSE
      END
   END;
   REPEAT
      TextIO.GetString (inFile, option);
      IF  TextIO.EOF (inFile) = TRUE  THEN  
	 UserMessage (9);
	 TextIO.Close (inFile);
	 RETURN FALSE
      END
   UNTIL Strings.StrEq (option, 'PROCESSORS');
   LOOP
      IF  TextIO.EOF (inFile) = TRUE  THEN  
	 UserMessage (9);
	 TextIO.Close (inFile);
	 RETURN FALSE
      END;
      TextIO.GetString (inFile, option);
      IF  Strings.StrEq (option, 'END') = TRUE  THEN  EXIT  END;
      IF  Strings.StrEq (option, Target) = TRUE  THEN  TextIO.GetCard (inFile, cpuClass)  END
   END;
   IF  cpuClass = 0  THEN
      InOut.WriteString ("Target CPU not found in Opcode list, assuming ATmega8515.");
      InOut.WriteLn;
      cpuClass := 3
   END;
   REPEAT
      TextIO.GetString (inFile, option);
      IF  TextIO.EOF (inFile) = TRUE  THEN  
	 UserMessage (9);
	 TextIO.Close (inFile);
	 RETURN FALSE
      END
   UNTIL Strings.StrEq (option, 'OPCODES');
   LOOP
      IF  TextIO.EOF (inFile) = TRUE  THEN
	 UserMessage (9);
	 TextIO.Close (inFile);
	 RETURN FALSE
      END;
      TextIO.GetString (inFile, option);
      IF  Strings.StrEq (option, 'END') = TRUE  THEN  EXIT  END;
      TextIO.GetCard (inFile, cat);
      TextIO.GetCard (inFile, opc);
      IF  StoreOpcode (option, cat, opc) = FALSE  THEN
         UserMessage (11);
	 TextIO.Close (inFile);
	 RETURN FALSE
      END
   END;
   TextIO.Close (inFile);
   RETURN TRUE
END ConfigureOps;


PROCEDURE GetChar (VAR ch	: CHAR);

BEGIN
   TextIO.GetChar (inFile, ch);
   IF  TextIO.EOF (inFile) = TRUE  THEN  
      UserMessage (8);
      HALT
   END;
   IF  ch = ASCII.LF  THEN
      column := 1;
      INC (line)
   ELSIF  ch = ASCII.TAB  THEN
      ch := ' '
   END
END GetChar;


PROCEDURE Sync;

VAR	chr	: CHAR;

BEGIN
   REPEAT  GetChar (chr)  UNTIL  chr = ASCII.LF
END Sync;


PROCEDURE GetToken;

VAR	chr		: CHAR;
	i		: CARDINAL;

BEGIN
   i := 0;
   REPEAT  GetChar (chr)  UNTIL  chr > ' ';
   REPEAT
      token [i] := chr;
      INC (i);
      GetChar (chr)
   UNTIL  (chr = ' ') OR (chr = ASCII.LF);
   IF   i <= HIGH (token)  THEN  token [i] := 0C  END
END GetToken;


PROCEDURE GetCard (VAR  nr  : CARDINAL) : BOOLEAN;

VAR	chr		: CHAR;
	Base, i		: CARDINAL;
	buff		: Identifier;

BEGIN
   i := 0;
   REPEAT  GetChar (chr)  UNTIL  chr > ' ';
   IF  chr = '$'  THEN
      Base := 16;
      GetChar (chr)
   ELSIF  chr = '#'  THEN
      Base := 2;
      GetChar (chr)
   ELSIF  chr = '%'  THEN
      Base := 8;
      GetChar (chr)
   ELSE
      Base := 10
   END;
   REPEAT
      buff [i] := chr;
      GetChar (chr);
      INC (i);
      IF  chr = '.'  THEN  GetChar (chr)  END
   UNTIL  chr = ' ';
   IF  i <=  HIGH (buff)  THEN  buff [i] := 0C  END;
   NumConv.Str2Num (nr, Base, buff, ok);
   IF  NOT ok  THEN  
      UserMessage (12);
      Sync
   END
END GetCard;


PROCEDURE doCONST;

VAR	done		: BOOLEAN;
	nr		: CARDINAL;

BEGIN
   currentType := Constant;
   REPEAT
      GetToken;
      IF  Strings.StrEq (token, 'END')  THEN  
	 done := TRUE
      ELSE
	 IF  StoreSymbol (token) = TRUE  THEN
	    GetToken;
	    IF  Strings.StrEq (token, '=')  THEN
	       GetCard (nr);
	       thisSymbol^.value := nr
	    ELSE
	       UserMessage (14)
	    END
	 ELSE
	    UserMessage (13)
	 END
      END;
      Sync
   UNTIL done
END doCONST;


PROCEDURE doMESS;

BEGIN
   
END doMESS;


PROCEDURE doDATA;

VAR	delta		: CARDINAL;

BEGIN
   currentType := Variable;
   REPEAT
      GetToken;
      IF  Strings.StrEq (token, 'END')  THEN  
	 done := TRUE
      ELSE
	 IF  StoreSymbol (token) = TRUE  THEN
	    GetToken;
	    IF  Strings.StrEq (token, ':')  THEN
	       thisSymbol^.value := inRAM;
	       GetCard (delta);
	       INC (inRAM, delta)
	    ELSE
	       UserMessage (15)
	    END
	 ELSE
	    UserMessage (13)
	 END
      END;
      Sync
   UNTIL done
END doDATA;


PROCEDURE doCOMMENT;

VAR	chr		: CHAR;
	endToken	: IDENTIFIER;

BEGIN
   GetToken;
   endToken := token;
   REPEAT
      GetToken;
      IF  Strings.StrEq (token, COMMENT)  THEN  doCOMMENT  END;
   UNTIL  token = endToken
END doCOMMENT;


PROCEDURE isPseudo (str		: IDENTIFIER) : BOOLEAN;

BEGIN
   IF     Strings.StrEq (str, 'ORIGIN')	    THEN
      GetCard (PC)
   ELSIF  Strings.StrEq (str, 'CONSTANTS')  THEN
      doCONST
   ELSIF  Strings.StrEq (str, 'COMMENT')    THEN
      doCOMMENT
   ELSIF  Strings.StrEq (str, 'DATA')	    THEN
      doDATA
   ELSIF  Strings.StrEq (str, 'MESSAGES')   THEN
      doMESS
   END
END isPseudo;


PROCEDURE GetLabel (VAR str	: Identifier) : Lstat;

VAR	ch	: CHAR;
	i	: CARDINAL;

BEGIN
   i := 0;
   GetChar (ch);
   IF  ch = ' ' THEN
      RETURN space
   ELSIF  ch = ';'  THEN  
      Sync;
      RETURN comment
   ELSE
      WHILE  ch > ' '  DO
         str [i] := ch;
	 INC (i);
	 GetChar (ch)
      END;
      str [i] := 0C
   END;
   RETURN label
END GetLabel;


PROCEDURE GetComment (VAR str	: Identifier);

BEGIN
END GetString;


PROCEDURE OpenFiles;

VAR	filename    	: Identifier;

BEGIN
   filename := Source;			Strings.Append (filename, '.asm');
   TextIO.OpenInput (inFile, filename);
   IF  NOT TextIO.Done ()  THEN
      UserMessage (5);
      HALT
   END;
   filename := Source;			Strings.Append (filename, '.lst');
   TextIO.OpenOutput (lstFile, filename);
   IF  NOT TextIO.Done ()  THEN
      UserMessage (7);
      HALT
   END;
   filename := Source;			Strings.Append (filename, '.out');
   TextIO.OpenOutput (outFile, filename);
   IF  NOT TextIO.Done ()  THEN
      UserMessage (7);
      HALT
   END;
   TextIO.PutString (lstFile, "Assembly listing");
   TextIO.PutLn (lstFile);    		   	     	TextIO.PutLn (lstFile);
   TextIO.PutString (lstFile, "Source : ");		TextIO.PutString (lstFile, Source);
   TextIO.PutString (lstFile, " assembling for target processor ");
   TextIO.PutString (lstFile, Target);
   TextIO.PutLn (lstFile);				TextIO.PutLn (lstFile);
   TextIO.PutLn (lstFile);
   TextIO.PutLn (lstFile)
END OpenFiles;


PROCEDURE ListOps;

VAR	thisOne		: OpcodePtr;

BEGIN
   TextIO.PutString (listFile, "Opcode list");		TextIO.PutLn (listFile);
   thisOne := firstOpcode;
   LOOP
      TextIO.PutString (listFile, thisOne^.name);	TextIO.PutLn (listFile);

      TextIO.PutChar (listFile, 11C);
      TextIO.PutString (listFile, "minClass    : ");	TextIO.PutCard (listFile, thisOne^.minClass, 4);
      TextIO.PutLn (listFile);

      TextIO.PutChar (listFile, 11C);
      TextIO.PutString (listFile, "opcodeCode  : ");	TextIO.PutCard (listFile, thisOne^.opcodeCode, 4);
      TextIO.PutLn (listFile);
      IF  thisOne^.next = NIL  THEN
         EXIT
      ELSE
         thisOne := thisOne^.next
      END
   END;
   TextIO.PutLn (listFile);
   TextIO.PutLn (listFile)
END ListOps;


PROCEDURE ListSyms;

VAR	thisOne		: SymbolPtr;

BEGIN
   TextIO.PutString (listFile, "Symboltable list");		TextIO.PutLn (listFile);
   thisOne := firstSymbol;
   LOOP
      TextIO.PutString (listFile, thisOne^.name);	TextIO.PutLn (listFile);

      TextIO.PutChar (listFile, 11C);
      TextIO.PutString (listFile, "Type  : ");
      CASE  thisOne^.type  OF
	 Label	   : option := "Label    "		|
	 Constant  : option := "Constant "		|
	 Alias	   : option := "Alias	 "		|
	 Variable  : option := "Variable "
      END;
      TextIO.PutString (listFile, option);
      TextIO.PutChar (listFile, 11C);
      TextIO.PutString (listFile, "Value : ");		TextIO.PutCard (listFile, thisOne^.value, 6);
      TextIO.PutLn (listFile);
      IF  thisOne^.next = NIL  THEN
         EXIT
      ELSE
         thisOne := thisOne^.next
      END
   END;
   TextIO.PutLn (listFile);
   TextIO.PutLn (listFile)
END ListSyms;


PROCEDURE ListPorts;

VAR	thisOne		: PortPtr;

BEGIN
   TextIO.PutString (listFile, "Portnames list");	TextIO.PutLn (listFile);
   thisOne := firstPort;
   LOOP
      TextIO.PutString (listFile, thisOne^.Name);	TextIO.PutLn (listFile);

      TextIO.PutChar (listFile, 11C);
      TextIO.PutString (listFile, "number : ");		TextIO.PutCard (listFile, thisOne^.number, 4);
      TextIO.PutLn (listFile);

      IF  thisOne^.next = NIL  THEN
         EXIT
      ELSE
         thisOne := thisOne^.next
      END
   END;
   TextIO.PutLn (listFile);
   TextIO.PutLn (listFile)
END ListPorts;


PROCEDURE ListNames;

VAR	thisOne		: BitNamesPtr;

BEGIN
   TextIO.PutString (listFile, "Bitnames list");	TextIO.PutLn (listFile);
   thisOne := firstBitName;
   LOOP
      TextIO.PutString (listFile, thisOne^.RegName);	TextIO.PutLn (listFile);

      TextIO.PutChar (listFile, 11C);
      TextIO.PutString (listFile, "Bit nr    : ");	TextIO.PutCard (listFile, thisOne^.BitNr, 4);

      TextIO.PutChar (listFile, 11C);
      TextIO.PutString (listFile, "Bit name  : ");	TextIO.PutString (listFile, thisOne^.BitName);
      TextIO.PutLn (listFile);
      IF  thisOne^.next = NIL  THEN
         EXIT
      ELSE
         thisOne := thisOne^.next
      END
   END;
   TextIO.PutLn (listFile);
   TextIO.PutLn (listFile)
END ListNames;


PROCEDURE ListLists;

VAR	filename	: Identifier;

BEGIN
   filename := Source;
   Strings.Append (filename, '.list');
   TextIO.OpenOutput (listFile, filename);
   ListOps;
   ListSyms;
   ListPorts;
   ListNames;
   TextIO.Close (listFile)
END ListLists;


PROCEDURE Assemble;

BEGIN
END Assemble;


PROCEDURE CloseFiles;

BEGIN
   TextIO.Close (inFile);
   TextIO.Close (lstFile);
   TextIO.Close (outFile);
   MemPools.KillPool (PortNames);
   MemPools.KillPool (BitNames);
   MemPools.KillPool (Opcodes);
   MemPools.KillPool (Symbols)
END CloseFiles;


PROCEDURE Init;

VAR   count, i    	: SHORTCARD;

BEGIN
   MemPools.NewPool (PortNames);
   MemPools.NewPool (BitNames);
   MemPools.NewPool (Symbols);
   MemPools.NewPool (Opcodes);
   MemPools.PoolAllocate (PortNames, firstPort, SYSTEM.TSIZE (PortNode));
   WITH  firstPort^  DO
      Name := "|";
      number := 5000;
      next := NIL
   END;
   MemPools.PoolAllocate (BitNames, firstBitName, SYSTEM.TSIZE (BitNamesNode));
   WITH  firstBitName^  DO
      RegName := "|";
      BitNr := 50000;
      BitName := "|";
      next := NIL
   END;
   MemPools.PoolAllocate (Symbols, firstSymbol, SYSTEM.TSIZE (SymbolNode));
   WITH  firstSymbol^  DO
      name := "|";
      value := MAX (CARDINAL);
      next := NIL
   END;
   MemPools.PoolAllocate (Opcodes, firstOpcode, SYSTEM.TSIZE (OpcodeNode));
   WITH  firstOpcode^  DO
      name := "|";
      minClass := 0;
      opcodeCode := 1024;
      next := NIL
   END;

   line := 1;				column := 1;			PC := 0;
   RAMstart := 96;
   Strings.EmptyString (Source);       	Target := "ATmega8515";
   Arguments.GetArgs (count, storage);
   IF  count = 1  THEN
      UserMessage (2);
      UserMessage (1);
      HALT
   END;
   i := 1;
   LOOP
      IF  i >= count  THEN  EXIT  END;
      Strings.Assign (option, storage^ [i]^);
      IF  Strings.StrEq (option, '-t')  THEN
         INC (i);
	 IF  i = count  THEN
	    UserMessage (11);		InOut.WriteLn;
	    UserMessage (1); 		UserMessage (2);
	    HALT
	 END;
         Strings.Assign (Target, storage^ [i]^)
      ELSIF  Strings.StrEq (option, '-v')  THEN
         UserMessage (2)
      ELSE
         Strings.Assign (Source, option)
      END;
      INC (i)
   END;
   IF  Source [0] = 0C  THEN
      UserMessage (6);
      HALT
   END;
   PC := 0;
   cpuClass := 0
END Init;


BEGIN
   Init;
   IF  (ConfigureCPU () = FALSE) OR (ConfigureOps () = FALSE)  THEN
      UserMessage (4);
      HALT
   END;
   UserMessage (2);
   OpenFiles;
   Assemble;
   CloseFiles;
   ListLists
END aa001.
   

Page created on 10 June 2008 and

Page equipped with FroogleBuster technology