/* (S)Chip-48 Assembler V2.11 by Christian Egeberg 2/11-'90 .. 20/8-'91 */
//{{2004/04/02 Naoyuki Sawa
// (S)Chip-48 Assembler V2.11A Changed by Naoyuki Sawa 2/4-'04
// - "jp v0,Addr"命令が正しくコンパイルできなかったのを修正しました。
// - "INCLUDE"擬似命令の後で、命令配置アドレスが元に戻ってしまうのを修正しました。
//}}2004/04/02 Naoyuki Sawa

//{{2004/04/02 Naoyuki Sawa
//#define CopyRight "(S)Chip-48 Assembler V2.11 by Christian Egeberg 20/8-\'91"
//↓バージョン番号を変更しました。
#define CopyRight "(S)Chip-48 Assembler V2.11 by Christian Egeberg 20/8-\'91\n" \
                  "(S)Chip-48 Assembler V2.11A Changed by Naoyuki Sawa 2/4-'04"
//}}2004/04/02 Naoyuki Sawa

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

/* Modify macro below to force Ansi or Kernighan-Ritchie prototypes */
#define ANSI ( defined( c_plusplus ) || defined( __cplusplus ) || __STDC__ )
/* Modify macro below to change procedure storage class */
#define PROC

#define False     ( char )0
#define True      ( char )~0
#define UnDefined 0L
#define Defined   ~0L

#define StartAddress 0x200L
#define StopAddress  0xfffL
#define CheckMagic   0x1081L
#define WordMask     0xffffL
#define AddrMask     0xfffL
#define ByteMask     0xffL
#define NibbleMask   0xfL

#define SpaceLength     32768 
#define LineLength      255
#define ParamLength     127
#define SymbolLength    32
#define ListLength      32
#define StackLength     32  
#define MaxBaseLength   16
#define BinHpHeadLength 13
#define FailExitCode    1
#define SuccessExitCode 0

#define NullChar      '\0'
#define BellChar      '\7'
#define SpaceChar     ' '
#define SeparatorChar ','
#define RemarkChar    ';'
#define SymbolChar    '_'
#define LabelChar     ':'
#define EqualChar     '='
#define TextChar      '\''
#define AddressChar   '\77'
#define HexChar       '#'
#define BinChar       '$'
#define OctChar       '@'
#define AscChar       '\"'
#define StartChar     '('
#define StopChar      ')'
#define PlusChar      '+'
#define MinusChar     '-'
#define NotChar       '~'
#define PowerChar     '!'
#define ShlChar       '<'
#define ShrChar       '>'
#define MulChar       '*'
#define FracChar      '/'
#define AndChar       '&'
#define OrChar        '|'
#define XorChar       '^'
#define DivChar       '\\'
#define ModChar       '%'

#define WrongToken    0
#define EqualToken    1
#define AddToken      2
#define AlignToken    3
#define AndToken      4
#define CallToken     5
#define ClsToken      6
#define DaToken       7
#define DbToken       8
#define DefineToken   9
#define DrwToken     10
#define DsToken      11
#define DwToken      12
#define ElseToken    13
#define EndToken     14
#define EndifToken   15
#define EquToken     16
#define ExitToken    17
#define HighToken    18
#define IfdefToken   19
#define IfundToken   20
#define IncludeToken 21
#define JpToken      22
#define LdToken      23
#define LowToken     24
#define OptionToken  25
#define OrToken      26
#define OrgToken     27
#define RetToken     28
#define RndToken     29
#define ScdToken     30
#define SclToken     31
#define ScrToken     32
#define SeToken      33
#define ShlToken     34
#define ShrToken     35
#define SknpToken    36
#define SkpToken     37
#define SneToken     38
#define SubToken     39
#define SubnToken    40
#define SysToken     41
#define UndefToken   42
#define UsedToken    43
#define XorToken     44
#define XrefToken    45
#define LastToken    46

#define BadReg   0
#define BReg     1
#define DtReg    2
#define FReg     3
#define HfReg    4
#define IReg     5
#define KReg     6
#define LfReg    7
#define RReg     8
#define StReg    9
#define V0Reg   10
#define V1Reg   11
#define V2Reg   12
#define V3Reg   13
#define V4Reg   14
#define V5Reg   15
#define V6Reg   16
#define V7Reg   17
#define V8Reg   18
#define V9Reg   19
#define VaReg   20
#define VbReg   21
#define VcReg   22
#define VdReg   23
#define VeReg   24
#define VfReg   25
#define IiReg   26
#define LastReg 27

#define AlignOnDefault  Defined
#define Chip8Default    UnDefined
#define Chip48Default   Defined
#define Super10Default  UnDefined
#define Super11Default  UnDefined
#define UsedYesDefault  UnDefined
#define UsedOnDefault   UnDefined
#define XrefYesDefault  Defined
#define XrefOnDefault   Defined
#define HpHeadDefault   Defined
#define HpAscDefault    UnDefined

typedef char CharSet[ 0x100 ];
typedef char LineString[ LineLength + 1 ];
typedef char ParamString[ ParamLength + 1 ];
typedef char SymbolString[ SymbolLength + 1 ];
typedef struct SpaceRecord {
  unsigned int Size;
  char *Start;
  char *Point;
  char *Index;
  unsigned int Request;
} SpaceRecord;
typedef struct LocRecord *LocPointer;
typedef struct LocRecord {
  unsigned int Line; 
  char *Name;
  char *Text;
  char Xref;
  long int Addr;
} LocRecord;
typedef struct ReferRecord *ReferPointer;
typedef struct ReferRecord {
  LocRecord Loc;
  ReferPointer Next;
} ReferRecord;
typedef struct ParamRecord *ParamPointer;
typedef struct ParamRecord {
  char *Param;
  ParamPointer Next;
} ParamRecord;
typedef struct SymbolRecord *SymbolPointer;
typedef struct SymbolRecord {
  LocRecord Loc;
  long int Value;
  char *Symbol;
  char *Expr;
  ReferPointer Refer;
  SymbolPointer Left;
  SymbolPointer Right;
} SymbolRecord;
typedef struct InstRecord *InstPointer;
typedef struct InstRecord { 
  LocRecord Loc;
  unsigned int Token;
  unsigned int Count;
  ParamPointer Params;
  InstPointer Next;
} InstRecord;

static char InExtDefault[] = ".chp";
static char ListExtDefault[] = ".lst";
static char DefFileName[] = ".";
static char StdFileName[] = "-";
static char StdInFileName[] = "stdin";
static char StdOutFileName[] = "stdout";
static char BinHpHeadText[] = "HPHP48-C";
static char AscHpHeadText[] = "%%HP: T(3)A(R)F(.);\n";

static char RunErrorMessage[] = "Fatal error: ";
static char RunWarningMessage[] = "Warning: ";
static char WarningNumMessage[] = "Total number of warnings: ";
static char EndOfFileMessage[] = "; End of file";
static char NoTargetError[] = "Usage is.. chipper Target [Source] [List]";
static char NoSourceError[] = "No source file found";
static char FileAccessError[] = "Unable to open file";
static char FileWriteError[] = "File or pipe output failed";
static char AllocationError[] = "Unable to allocate more memory";
static char SpaceAssertError[] = "Internal memory allocation mismatch";
static char NestedIfdefError[] = "Too many nested conditions";
static char BoundsError[] = "Outside legal address range";
static char ParamCountWarning[] = "Incorrect number of parameters";
static char DualSymbolWarning[] = "No directive recognized";
static char NoOptionWarning[] = "Option not recognized";
static char MissingSymbolWarning[] = "No symbol name specified";
static char NoSymbolWarning[] = "Not a defined symbol";
static char UnusedSymbolWarning[] = "Unused symbol detected";
static char CopySymbolWarning[] = "Existing symbol redefined";
static char UndefinedWarning[] = "Unable to evaluate parameter";
static char RangeWarning[] = "Parameter out of range";
static char NoRegisterWarning[] = "No register recognized";
static char BadRegisterWarning[] = "Illegal register specified";
static char NeedsChip8Warning[] = "Chip-8 spesific directive";
static char NeedsChip48Warning[] = "Chip-48 spesific directive";
static char NeedsSuper10Warning[] = "Super Chip-48 V1.0.. spesific directive";
static char NeedsSuper11Warning[] = "Super Chip-48 V1.1.. spesific directive";
static char MissingIfdefWarning[] = "No previous condition found";
static char CountDefineWarning[] = "Unbalanced condition matching in file";
static char InternalWarning[] = "Internal data structure mismatch";

static char AlignOnName[] = "ALIGNON";
static char Chip8Name[] = "CHIP8";
static char Chip48Name[] = "CHIP48";
static char Super10Name[] = "SCHIP10";
static char Super11Name[] = "SCHIP11";
static char UsedYesName[] = "USEDYES";
static char UsedOnName[] = "USEDON";
static char XrefYesName[] = "XREFYES";
static char XrefOnName[] = "XREFON";
static char HpHeadName[] = "HPHEAD";
static char HpAscName[] = "HPASC";
static char HpBinName[] = "HPBIN";
static char BinaryName[] = "BINARY";
static char StringName[] = "STRING";

static char OptionYesName[] = "YES";
static char OptionNoName[] = "NO";
static char OptionOnName[] = "ON";
static char OptionOffName[] = "OFF";

static SymbolString TokenText[ LastToken ] = 
  { ",,,,,",   "=",       "ADD",     "ALIGN",   "AND",
    "CALL",    "CLS",     "DA",      "DB",      "DEFINE",
    "DRW",     "DS",      "DW",      "ELSE",    "END",     
    "ENDIF",   "EQU",     "EXIT",    "HIGH",    "IFDEF",   
    "IFUND",   "INCLUDE", "JP",      "LD",      "LOW",     
    "OPTION",  "OR",      "ORG",     "RET",     "RND",     
    "SCD",     "SCL",     "SCR",     "SE",      "SHL",     
    "SHR",     "SKNP",    "SKP",     "SNE",     "SUB",     
    "SUBN",    "SYS",     "UNDEF",   "USED",    "XOR",     
    "XREF"                                                };

static SymbolString RegisterText[ LastReg ] =
  { ",,,", "B",   "DT",  "F",   "HF",  "I",   "K",   "LF",
    "R",   "ST",  "V0",  "V1",  "V2",  "V3",  "V4",  "V5",
    "V6",  "V7",  "V8",  "V9",  "VA",  "VB",  "VC",  "VD",
    "VE",  "VF",  "[I]"                                    };

static SpaceRecord Space = { SpaceLength, NULL, NULL, NULL, 0 };

static char StackStart[ StackLength + 1 ];
static char *StackPoint = StackStart;

static CharSet Operators;
static char StartOperator[] = { StartChar, NullChar };
static char StopOperator[] = { StopChar, NullChar };
static char UnaryOperator[] = { PlusChar, MinusChar, NotChar, NullChar };
static char PowerOperator[] = { PowerChar, ShlChar, ShrChar, NullChar };
static char MulDivOperator[] = { MulChar, FracChar, NullChar };
static char PlusMinusOperator[] = { PlusChar, MinusChar, NullChar };
static char BitWiseOperator[] = { AndChar, OrChar, XorChar, NullChar };
static char DivModOperator[] = { DivChar, ModChar, NullChar };
static ParamString DigitText = "0123456789ABCDEF.";
static char NullString[] = "\0";
static LineString Separator = "";

static long int DefinedValue = Defined;
static long int DummyValue = UnDefined;
static long int *AlignOnCond = &DummyValue;
static long int *Chip8Cond = &DummyValue;
static long int *Chip48Cond = &DummyValue;
static long int *Super10Cond = &DummyValue;
static long int *Super11Cond = &DummyValue;
static long int *UsedYesCond = &DummyValue;
static long int *UsedOnCond = &DummyValue;
static long int *XrefYesCond = &DummyValue;
static long int *XrefOnCond = &DummyValue;
static long int *HpHeadCond = &DummyValue;
static long int *HpAscCond = &DummyValue;

static InstPointer Instructions = NULL;
static SymbolPointer Directives = NULL;
static SymbolPointer Registers = NULL;
static SymbolPointer Symbols= NULL;
static SymbolPointer Conditions= NULL;
static InstPointer InstPoint = NULL;
static SymbolPointer SymbPoint = NULL;
static SymbolPointer CurrentSymbol = NULL;

static long int FinalAddress = StartAddress;
static LocRecord NullLocation = { 0, NullString, NullString, False, 0L };
static LocRecord UsedLocation = { 0, NullString, NullString, True, 0L };
static LocRecord Location = { 0, NullString, NullString, False, StartAddress };
static unsigned int WarningCount = 0;

static FILE *InFile = NULL;
static FILE *OutFile = NULL;
static FILE *ListFile = NULL;
static LineString InFileName = "";
static LineString OutFileName = "";
static LineString ListFileName = "";

static unsigned char Memory[ StopAddress - StartAddress + 1 ];

#if ANSI
  static PROC char ResolveDivMod( char *Symbol, char **Param,
    long int *Value, SymbolPointer Head, LocPointer Loc );
  //{{2004/04/02 Naoyuki Sawa
  //static PROC void DecodeFile( char *FileName, InstPointer *Head,
  //  SymbolPointer Dir, SymbolPointer *Symb, SymbolPointer *Cond );
  //↓次の命令配置アドレスを返すように変更しました。
  static PROC long DecodeFile( char *FileName, InstPointer *Head,
    SymbolPointer Dir, SymbolPointer *Symb, SymbolPointer *Cond );
  //}}2004/04/02 Naoyuki Sawa
#else
  static PROC char ResolveDivMod();
  //{{2004/04/02 Naoyuki Sawa
  //static PROC void DecodeFile();
  //↓次の命令配置アドレスを返すように変更しました。
  static PROC long DecodeFile();
  //}}2004/04/02 Naoyuki Sawa
#endif

#if ANSI
  static PROC void RunError( char AbortFlag, char *Message )
#else
  static PROC void RunError( AbortFlag, Message )
  char AbortFlag;
  char *Message;
#endif
{
  if( AbortFlag ) {
    fprintf( stderr, "%c%s\n%s%s\n", BellChar, Separator, RunErrorMessage,
      Message );
    if( ListFile )
      fprintf( ListFile, "%s\n%s%s\n", Separator, RunErrorMessage, Message );
  } else {
    fprintf( stderr, "%s\n%s%s\n", Separator, RunWarningMessage, Message );
    if( ListFile )
      fprintf( ListFile, "%s\n%s%s\n", Separator, RunWarningMessage, Message );
  }
  if( Location.Line ) {
    fprintf( stderr, "Current file %s line %u\n%s\n", Location.Name,
      Location.Line, Location.Text );
    if( ListFile ) 
      fprintf( ListFile, "Current file %s line %u\n%s\n", Location.Name,
        Location.Line, Location.Text );
  }
  if( InstPoint ) {
    fprintf( stderr, "Associated file %s line %u\n%s\n",
      InstPoint->Loc.Name, InstPoint->Loc.Line, InstPoint->Loc.Text );
    if( ListFile ) 
      fprintf( ListFile, "Associated file %s line %u\n%s\n",
        InstPoint->Loc.Name, InstPoint->Loc.Line, InstPoint->Loc.Text );
  }
  if( SymbPoint ) {
    fprintf( stderr, "Symbol %s file %s line %u\n%s\n", SymbPoint->Symbol,
      SymbPoint->Loc.Name, SymbPoint->Loc.Line, SymbPoint->Loc.Text );
    if( ListFile ) 
      fprintf( ListFile, "Symbol %s file %s line %u\n%s\n", SymbPoint->Symbol,
        SymbPoint->Loc.Name, SymbPoint->Loc.Line, SymbPoint->Loc.Text );
  }
  fprintf( stderr, "%s\n", Separator );
  if( ListFile )
    fprintf( ListFile, "%s\n", Separator );
  if( AbortFlag ) 
    exit( FailExitCode );
    /* exit function should close all files */
  else
    WarningCount++;
}

#if ANSI
  static PROC char *NumberString( char *Result, long int Value,
    unsigned int Base, unsigned int Count )
#else
  static PROC char *NumberString( Result, Value, Base, Count )
  char *Result;
  long int Value;
  unsigned int Base;
  unsigned int Count;
#endif
{
  char *Digit;

  Digit = Result + Count;
  *( Digit-- ) = NullChar;
  while(( Digit >= Result ) && ( Value > 0L )) {
    *( Digit-- ) = DigitText[ Value % Base ];
    Value /= Base;
  }
  while( Digit >= Result ) 
    *( Digit-- ) = '0';
  return( Result );
}

#if ANSI
  static PROC void ListInstruction( long int Address, unsigned int Count,
    InstPointer Inst )
#else
  static PROC void ListInstruction( Address, Count, Inst )
  long int Address;
  unsigned int Count;
  InstPointer Inst;
#endif
{
  unsigned int This;
  SymbolString HexText;

  if( fprintf( ListFile, "%s\n%s(%u).. %s: ", Inst->Loc.Text, Inst->Loc.Name,
    Inst->Loc.Line, NumberString( HexText, Address, 16, 3 )) <= 0 )
      RunError( True, FileWriteError );
  for( This = 0; This < Count; This++ )
    if( fprintf( ListFile, NumberString( HexText, ( long int )
      Memory[ Address + This - StartAddress ], 16, 2 )) <= 0 )
        RunError( True, FileWriteError );
  fprintf( ListFile, "\n" );
}

#if ANSI
  static PROC void ListReference( ReferPointer Head )
#else
  static PROC void ListReference( Head )
  ReferPointer Head;
#endif
{
  for( ; Head; Head = Head->Next )
    if( Head->Loc.Line && Head->Loc.Xref )
      if( fprintf( ListFile, "  %s(%u)\n", Head->Loc.Name,
        Head->Loc.Line ) <= 0 )
          RunError( True, FileWriteError );
}

#if ANSI
  static PROC void ListSymbols( SymbolPointer Head )
#else
  static PROC void ListSymbols( Head )
  SymbolPointer Head;
#endif
{
  SymbolString HexText;

  if( Head ) {
    if( Head->Left )
      ListSymbols( Head->Left );
    SymbPoint = Head;
    if( !( *UsedYesCond ) && Head->Loc.Line && !( Head->Refer ))
      RunError( False, UnusedSymbolWarning );
    if( Head->Expr )
      strcpy( HexText, "UND" );
    else
      NumberString( HexText, Head->Value, 16, 3 );
    if( fprintf( ListFile, "%s %s %s(%u)\n", HexText, Head->Symbol,
      Head->Loc.Name, Head->Loc.Line ) <= 0 )
        RunError( True, FileWriteError );
    if( *XrefYesCond )
      ListReference( Head->Refer );
    SymbPoint = NULL;
    if( Head->Right )
      ListSymbols( Head->Right );
  }
}

#if ANSI
  static PROC void ListDefines( SymbolPointer Head )
#else
  static PROC void ListDefines( Head )
  SymbolPointer Head;
#endif
{
  if( Head ) {
    if( Head->Left )
      ListDefines( Head->Left );
    if( Head->Value ) {
      if( fprintf( ListFile, "DEF %s\n", Head->Symbol ) <= 0 )
        RunError( True, FileWriteError );
    } else 
      if( fprintf( ListFile, "UND %s\n", Head->Symbol ) <= 0 )
        RunError( True, FileWriteError );
    if( Head->Right )
      ListDefines( Head->Right );
  }
}

#if ANSI
  static PROC void ListWarnings( void )
#else
  static PROC void ListWarnings()
#endif
{
  if( fprintf( stderr, "%s%u\n", WarningNumMessage, WarningCount ) <= 0 )
    RunError( True, FileWriteError );
  if( fprintf( ListFile, "%s%u\n", WarningNumMessage, WarningCount ) <= 0 )
    RunError( True, FileWriteError );
}

#if ANSI
  static PROC char *AssertSpace( SpaceRecord *Chain, unsigned int Size )
#else
  static PROC char *AssertSpace( Chain, Size )
  SpaceRecord *Chain;
  unsigned int Size;
#endif
{
  if( Chain ) {
    if( Chain->Request )
      RunError( True, SpaceAssertError );
    if( Size + sizeof( char * ) > Chain->Size )
      RunError( True, SpaceAssertError );
    if( !( Chain->Start )) {
      Chain->Start = ( char * )malloc( Chain->Size );
      if( !( Chain->Start ))
        RunError( True, AllocationError );
      Chain->Point = NULL;
    }
    if( !( Chain->Point )) {
      Chain->Point = Chain->Start;
      Chain->Index = NULL;
    }
    if( !( Chain->Index )) {
      *( char ** )Chain->Point = NULL;
      Chain->Index = Chain->Point + sizeof( char * );
    }
    if( Chain->Index + Size > Chain->Point + Chain->Size ) {
      char *This;

      This = ( char * )malloc( Chain->Size );
      if( !This )
        RunError( True, AllocationError );
      *( char ** )Chain->Point = This;
      Chain->Point = This;
      *( char ** )This = NULL;
      Chain->Index = This + sizeof( char * );
    }
  } else
    RunError( True, SpaceAssertError );
  Chain->Request = Size;
  return( Chain->Index );
}

#if ANSI
  static PROC void ClaimSpace( SpaceRecord *Chain, unsigned int Size )
#else
  static PROC void ClaimSpace( Chain, Size )
  SpaceRecord *Chain;
  unsigned int Size;
#endif
{
  if( Chain ) {
    if( !( Chain->Request ))
      RunError( True, SpaceAssertError );
    if( Size > Chain->Request )
      RunError( True, SpaceAssertError );
    Chain->Index += Size;
    Chain->Request = 0;
  } else
    RunError( True, SpaceAssertError );
}

#if ANSI
  static PROC void ReleaseSpace( SpaceRecord *Chain )
#else
  static PROC void ReleaseSpace( Chain )
  SpaceRecord *Chain;
#endif
{
  char *This;
  char *Next;

  if( Chain ) {
    if( Chain->Request )
      RunError( True, SpaceAssertError );
    for( This = Chain->Start; This; ) {
      Next = *( char ** )This;
      free( This );
      This = Next;
    }
    Chain->Start = NULL;
    Chain->Point = NULL;
    Chain->Index = NULL;
    Chain->Request = 0;
  } else
    RunError( True, SpaceAssertError );
}

#if ANSI
  static PROC char OpenFiles( int argc, char *argv[] )
#else
  static PROC char OpenFiles( argc, argv )
  int argc;
  char *argv[]; 
#endif
{
  if( argc >= 2 ) {
    strcpy( OutFileName, argv[ 1 ]);
    if( argc >= 3 )
      strcpy( InFileName, argv[ 2 ]);
    else {
      strcpy( InFileName, OutFileName );
      strcat( InFileName, InExtDefault );
    }
    if( !strcmp( InFileName, DefFileName )) {
      strcpy( InFileName, OutFileName );
      strcat( InFileName, InExtDefault );
    }
    if( !strcmp( InFileName, StdFileName )) 
      strcpy( InFileName, StdInFileName );
    if( argc >= 4 ) 
      strcpy( ListFileName, argv[ 3 ]);
    else {
      strcpy( ListFileName, OutFileName );
      strcat( ListFileName, ListExtDefault );
    }
    if( !strcmp( ListFileName, DefFileName )) {
      strcpy( ListFileName, OutFileName );
      strcat( ListFileName, ListExtDefault );
    }
    if( !strcmp( ListFileName, StdFileName )) 
      strcpy( ListFileName, StdOutFileName );
  } else
    RunError( True, NoTargetError );
  if( fprintf( stderr, "TargetFile: %s\n", OutFileName ) <= 0 )
    RunError( True, FileWriteError );
  OutFile = fopen( OutFileName, "w+b" );
  if( !OutFile )
    RunError( True, FileAccessError );
  if( fprintf( stderr, "SourceFile: %s\n", InFileName ) <= 0 )
    RunError( True, FileWriteError );
  if( strcmp( InFileName, StdInFileName ))
    InFile = fopen( InFileName, "r" );
  else 
    InFile = stdin;
  if( !InFile )
    RunError( True, NoSourceError );
  if( fprintf( stderr, "ListFile: %s\n", ListFileName ) <= 0 )
    RunError( True, FileWriteError );
  if( strcmp( ListFileName, StdOutFileName )) 
    ListFile = fopen( ListFileName, "w" );
  else
    ListFile = stdout;
  if( !ListFile )
    RunError( True, FileAccessError );
  fprintf( stderr, "\n" );
  if( fprintf( ListFile,
    "%s\n\nTargetFile: %s\nSourceFile: %s\nListFile: %s\n\n", CopyRight,
    OutFileName, InFileName, ListFileName ) <= 0 )
      RunError( True, FileWriteError );
  return( True );
}

#if ANSI
  static PROC void DefineReference( LocPointer Loc, ReferPointer *Head )
#else
  static PROC void DefineReference( Loc, Head )
  LocPointer Loc;
  ReferPointer *Head;
#endif
{
  ReferPointer This;
  ReferPointer Ref;
  ReferPointer Last;
  int Compare;

  if( Loc ) {
    This = ( ReferPointer )AssertSpace( &Space, sizeof( ReferRecord ));
    ClaimSpace( &Space, sizeof( ReferRecord ));
    This->Loc = *Loc;
    This->Next = NULL;
    for( Last = NULL, Ref = *Head; Ref; ) {
      Compare = strcmp( Loc->Name, Ref->Loc.Name );
      if( !Compare ) {
        if( Loc->Line < Ref->Loc.Line ) {
          This->Next = Ref;
          Ref = NULL;
        } else {
          Last = Ref;
          Ref = Ref->Next;
        }
      } else 
        if( Compare < 0 ) {
          This->Next = Ref;
          Ref = NULL;
        } else {
          Last = Ref;
          Ref = Ref->Next;
        }
    }
    if( !Last ) 
      *Head = This;
    else  
      if(( Loc->Line != Last->Loc.Line ) || ( Loc->Name != Last->Loc.Name )) 
        Last->Next = This;
  }
}

#if ANSI
  static PROC char *StripSymbol( char *Result, char *Symbol )
#else
  static PROC char *StripSymbol( Result, Symbol )
  char *Result;
  char *Symbol;
#endif
{
  if( *Symbol == SymbolChar ) 
    Symbol++;
  strncpy( Result, Symbol, SymbolLength );
  Result[ SymbolLength ] = NullChar;
  Symbol = Result + strlen( Result ) - 1;
  if( *Symbol == LabelChar )
    *Symbol = NullChar;
  return( Result );
}

#if ANSI
  static PROC char DefineSymbol( char *RawSymbol, long int Value,
    SymbolPointer *Head, LocPointer Loc )
#else
  static PROC char DefineSymbol( RawSymbol, Value, Head, Loc )
  char *RawSymbol;
  long int Value;
  SymbolPointer *Head;
  LocPointer Loc;
#endif
{
  SymbolString Symbol;
  SymbolPointer Symb;
  SymbolPointer Last;
  int Compare;

  StripSymbol( Symbol, RawSymbol );
  Compare = 0;
  Last = NULL;
  Symb = *Head;
  while( Symb ) {
    Compare = strcmp( Symbol, Symb->Symbol );
    if( !Compare ) {
      Symb->Value = Value;
      Symb->Expr = NULL;
      if( Loc ) 
        Symb->Loc = *Loc;
      else
        Symb->Loc = NullLocation; 
      if( Symb->Loc.Xref )
        DefineReference( &( Symb->Loc ), &( Symb->Refer ));
      CurrentSymbol = Symb;
      return( False );
    }
    Last = Symb;
    if( Compare <= 0 )
      Symb = Symb->Left;
    else
      Symb = Symb->Right;
  }
  Symb = ( SymbolPointer )AssertSpace( &Space, sizeof( SymbolRecord ));
  ClaimSpace( &Space, sizeof( SymbolRecord ));
  Symb->Symbol = ( char * )AssertSpace( &Space, sizeof( SymbolString ));
  strcpy( Symb->Symbol, Symbol );
  ClaimSpace( &Space, ( unsigned int )( strlen( Symb->Symbol ) + 1 ));
  Symb->Value = Value;
  Symb->Expr = NULL;
  if( Loc )
    Symb->Loc = *Loc;
  else
    Symb->Loc = NullLocation; 
  Symb->Refer = NULL;
  if( *UsedOnCond )
    DefineReference( &NullLocation, &( Symb->Refer ));
  Symb->Left = NULL;
  Symb->Right = NULL;
  if( !Last )
    *Head = Symb;
  else 
    if( Compare <= 0 )
      Last->Left = Symb;
    else
      Last->Right = Symb;
  CurrentSymbol = Symb;
  return( True );
}

#if ANSI
  static PROC char ResolveOption( char *Option, long int *YesNoPoint,
    long int *OnOffPoint )
#else
  static PROC char ResolveOption( Option, YesNoPoint, OnOffPoint )
  char *Option;
  long int *YesNoPoint;
  long int *OnOffPoint;
#endif
{
  char Result;

  Result = True;
  if( !strcmp( Option, OptionYesName )) {
    *YesNoPoint = Defined;
    Result = False;
  }
  if( !strcmp( Option, OptionNoName )) {
    *YesNoPoint = UnDefined;
    Result = False;
  }
  if( !strcmp( Option, OptionOnName )) {
    *OnOffPoint = Defined;
    Result = False;
  }
  if( !strcmp( Option, OptionOffName )) {
    *OnOffPoint = UnDefined;
    Result = False;
  }
  return( Result );
}

#if ANSI
  static PROC char ResolveSymbol( char *RawSymbol, long int *Value,
    SymbolPointer Head, LocPointer Loc )
#else
  static PROC char ResolveSymbol( RawSymbol, Value, Head, Loc )
  char *RawSymbol;
  long int *Value;
  SymbolPointer Head;
  LocPointer Loc;
#endif
{
  SymbolString Symbol;
  int Compare;
  char Result;

  Result = False;
  *Value = 0L;
  StripSymbol( Symbol, RawSymbol );
  while( Head ) {
    Compare = strcmp( Symbol, Head->Symbol );
    if( !Compare ) {
      *Value = Head->Value;
      if( Loc )
        if( Loc->Xref )
          DefineReference( Loc, &( Head->Refer ));
      if( !( Head->Expr ))
        Result = True;
      Head = NULL;
    } else {
      if( Compare <= 0 )
        Head = Head->Left;
      else
        Head = Head->Right;
    }
  }
  return( Result );
}

#if ANSI
  static PROC char ResolveNumber( char *Symbol, int Base, long int *Value )
#else
  static PROC char ResolveNumber( Symbol, Base, Value )
  char *Symbol;
  int Base;
  long int *Value;
#endif
{
  char *Digit;
  char Result;
  unsigned int Count;
  unsigned int Length;

  Result = True;
  if( !( *Symbol ))
    Result = False;
  *Value = 0L;
  Length = strlen( Symbol );
  for( Count = 1; Count <= Length; Count++ ) {
    Digit = strchr( DigitText, Symbol[ Count - 1 ]);
    if( !Digit ) {
      Result = False;
      Count = Length;
    } else {
      if(( Digit - DigitText ) >= MaxBaseLength ) 
        Digit = DigitText;
      if(( Digit - DigitText ) > Base ) {
        Result = False;
        Count = Length;
      } else
        *Value = Base * ( *Value ) + ( Digit - DigitText );
    }
  }
  return( Result );
}

#if ANSI
  static PROC char ResolveValue( char *Symbol, long int *Value,
    SymbolPointer Head, LocPointer Loc )
#else
  static PROC char ResolveValue( Symbol, Value, Head, Loc )
  char *Symbol;
  long int *Value;
  SymbolPointer Head;
  LocPointer Loc;
#endif
{
  char Result;

  Result = False;
  *Value = 0L;
  if(( Symbol[ 0 ] == AddressChar ) && !( Symbol[ 1 ]) && Loc ) {
    *Value = Loc->Addr;
    return( True );
  }
  switch( Symbol[ 0 ]) {
    case HexChar:
      Result = ResolveNumber( Symbol + 1, 16, Value );
      break;
    case BinChar:
      Result = ResolveNumber( Symbol + 1, 2, Value );
      break;
    case OctChar:
      Result = ResolveNumber( Symbol + 1, 8, Value );
      break;
    case AscChar:
      if( Symbol[ 1 ]) {
        *Value = Symbol[ 1 ];
        if( !( Symbol[ 2 ]))
        Result = True;
      }
      break;
    default:
      if( isdigit( Symbol[ 0 ]))
        Result = ResolveNumber( Symbol, 10, Value );
      else
        Result = ResolveSymbol( Symbol, Value, Head, Loc );
      break;
  }
  return( Result );
}

#if ANSI
  static PROC char *SplitParam( char *Result, char **Param )
#else
  static PROC char *SplitParam( Result, Param )
  char *Result;
  char **Param;
#endif
{
  char *Start;
  char *Count;
  char *Store;
  char Reading;

  Store = Result;
  *Store = NullChar;
  Reading = True;
  for( Start = NULL, Count = *Param; *Count; Count++ ) 
    if( isgraph( *Count )) {
      Start = Count;
      Count = NullString;
    }
  if( Start ) {
    Count = Start;
    if( Operators[ *Count ]) {
      *( Store++ ) = *Count;
      *( Store++ ) = NullChar; 
      *Param = Count + 1;
      Reading = False;
    } else 
      for( ; *Count; Count++ ) 
        if(( !isgraph( *Count )) || Operators[ *Count ]) {
          *Param = Count;
          Count = NullString;
          Reading = False;
        } else 
          *( Store++ ) = *Count;
  }
  if( Reading )
    *Param = NullString;
  *( Store++ ) = NullChar;
  return( Result );
}

#if ANSI
  static PROC char ResolveOperator( char *Symbol, char *Token, char *Legal )
#else
  static PROC char ResolveOperator( Symbol, Token, Legal )
  char *Symbol;
  char *Token;
  char *Legal;
#endif
{
  *Token = *Symbol;
  if(( *Token ) && strchr( Legal, *Token ))
    return( True ); 
  else
    return( False ); 
}

#if ANSI
  static PROC char ResolveSingle( char Token, long int *Value )
#else
  static PROC char ResolveSingle( Token, Value )
  char Token;
  long int *Value;
#endif
{
  char Result;

  Result = True;
  switch( Token ) {
    case PlusChar:
      /* Nothing to be done */
      break;
    case MinusChar:
      *Value = -( *Value );
      break;
    case NotChar:
      *Value = ~( *Value );
      break;
    default:
      Result = False;
      break;
  }
  return( Result );
}

#if ANSI
  static PROC char ResolveDouble( char Token, long int *Value,
    long int Operand )
#else
  static PROC char ResolveDouble( Token, Value, Operand )
  char Token;
  long int *Value;
  long int Operand;
#endif
{
  long int Count;
  long int This;
  char Result;

  Result = True;
  switch( Token ) {
    case PowerChar:
      This = 1;
      for( Count = 1; Count <= Operand; Count++ )
        This *= *Value;
      *Value = This;
      break;
    case ShlChar:
      *Value <<= Operand;
      break;
    case ShrChar:
      *Value >>= Operand;
      break;
    case MulChar:
      *Value *= Operand;
      break;
    case FracChar:
    case DivChar:
      *Value /= Operand;
      break;
    case PlusChar:
      *Value += Operand;
      break;
    case MinusChar:
      *Value -= Operand;
      break;
    case AndChar:
      *Value &= Operand;
      break;
    case OrChar:
      *Value |= Operand;
      break;
    case XorChar:
      *Value ^= Operand;
      break;
    case ModChar:
      *Value %= Operand;
      break;
    default:
      Result = False;
      break;
  }
  return( Result );
}

#if ANSI
  static PROC char ResolveParent( char *Symbol, char **Param, long int *Value,
    SymbolPointer Head, LocPointer Loc )
#else
  static PROC char ResolveParent( Symbol, Param, Value, Head, Loc )
  char *Symbol;
  char **Param;
  long int *Value;
  SymbolPointer Head;
  LocPointer Loc;
#endif
{
  char Token;
  char Status;

  if( ResolveOperator( Symbol, &Token, StartOperator )) {
    SplitParam( Symbol, Param );
    Status = ResolveDivMod( Symbol, Param, Value, Head, Loc );
    if( !ResolveOperator( Symbol, &Token, StopOperator ))
      Status = False;
    SplitParam( Symbol, Param );
  } else {
    Status = ResolveValue( Symbol, Value, Head, Loc );
    SplitParam( Symbol, Param );
  }
  return( Status );
}

#if ANSI
  static PROC char ResolveUnary( char *Symbol, char **Param, long int *Value,
    SymbolPointer Head, LocPointer Loc )
#else
  static PROC char ResolveUnary( Symbol, Param, Value, Head, Loc )
  char *Symbol;
  char **Param;
  long int *Value;
  SymbolPointer Head;
  LocPointer Loc;
#endif
{
  char Token;
  char Status;

  if( ResolveOperator( Symbol, &Token, UnaryOperator )) {
    SplitParam( Symbol, Param );
    Status = ResolveParent( Symbol, Param, Value, Head, Loc );
    Status = Status & ResolveSingle( Token, Value );
  } else
    Status = ResolveParent( Symbol, Param, Value, Head, Loc );
  return( Status );
}

#if ANSI
  static PROC char ResolvePower( char *Symbol, char **Param, long int *Value,
    SymbolPointer Head, LocPointer Loc )
#else
  static PROC char ResolvePower( Symbol, Param, Value, Head, Loc )
  char *Symbol;
  char **Param;
  long int *Value;
  SymbolPointer Head;
  LocPointer Loc;
#endif
{
  long int Operand;
  char Token;
  char Status;

  Operand = 0L;
  Status = ResolveUnary( Symbol, Param, Value, Head, Loc );
  while( ResolveOperator( Symbol, &Token, PowerOperator )) {
    SplitParam( Symbol, Param );
    Status = Status & ResolveUnary( Symbol, Param, &Operand, Head, Loc );
    Status = Status & ResolveDouble( Token, Value, Operand );
  }
  return( Status );
}

#if ANSI
  static PROC char ResolveMulDiv( char *Symbol, char **Param, long int *Value,
    SymbolPointer Head, LocPointer Loc )
#else
  static PROC char ResolveMulDiv( Symbol, Param, Value, Head, Loc )
  char *Symbol;
  char **Param;
  long int *Value;
  SymbolPointer Head;
  LocPointer Loc;
#endif
{
  long int Operand;
  char Token;
  char Status;

  Operand = 0L;
  Status = ResolvePower( Symbol, Param, Value, Head, Loc );
  while( ResolveOperator( Symbol, &Token, MulDivOperator )) {
    SplitParam( Symbol, Param );
    Status = Status & ResolvePower( Symbol, Param, &Operand, Head, Loc );
    Status = Status & ResolveDouble( Token, Value, Operand );
  }
  return( Status );
}

#if ANSI
  static PROC char ResolvePlusMinus( char *Symbol, char **Param,
    long int *Value, SymbolPointer Head, LocPointer Loc )
#else
  static PROC char ResolvePlusMinus( Symbol, Param, Value, Head, Loc )
  char *Symbol;
  char **Param;
  long int *Value;
  SymbolPointer Head;
  LocPointer Loc;
#endif
{
  long int Operand;
  char Token;
  char Status;

  Operand = 0L;
  Status = ResolveMulDiv( Symbol, Param, Value, Head, Loc );
  while( ResolveOperator( Symbol, &Token, PlusMinusOperator )) {
    SplitParam( Symbol, Param );
    Status = Status & ResolveMulDiv( Symbol, Param, &Operand, Head, Loc );
    Status = Status & ResolveDouble( Token, Value, Operand );
  }
  return( Status );
}

#if ANSI
  static PROC char ResolveBitWise( char *Symbol, char **Param, long int *Value,
    SymbolPointer Head, LocPointer Loc )
#else
  static PROC char ResolveBitWise( Symbol, Param, Value, Head, Loc )
  char *Symbol;
  char **Param;
  long int *Value;
  SymbolPointer Head;
  LocPointer Loc;
#endif
{
  long int Operand;
  char Token;
  char Status;

  Operand = 0L;
  Status = ResolvePlusMinus( Symbol, Param, Value, Head, Loc );
  while( ResolveOperator( Symbol, &Token, BitWiseOperator )) {
    SplitParam( Symbol, Param );
    Status = Status & ResolvePlusMinus( Symbol, Param, &Operand, Head, Loc );
    Status = Status & ResolveDouble( Token, Value, Operand );
  }
  return( Status );
}

#if ANSI
  static PROC char ResolveDivMod( char *Symbol, char **Param, long int *Value,
    SymbolPointer Head, LocPointer Loc )
#else
  static PROC char ResolveDivMod( Symbol, Param, Value, Head, Loc )
  char *Symbol;
  char **Param;
  long int *Value;
  SymbolPointer Head;
  LocPointer Loc;
#endif
{
  long int Operand;
  char Token;
  char Status;

  Operand = 0L;
  Status = ResolveBitWise( Symbol, Param, Value, Head, Loc );
  while( ResolveOperator( Symbol, &Token, DivModOperator )) {
    SplitParam( Symbol, Param );
    Status = Status & ResolveBitWise( Symbol, Param, &Operand, Head, Loc );
    Status = Status & ResolveDouble( Token, Value, Operand );
  }
  return( Status );
}

#if ANSI
  static PROC char ResolveExpression( char **Param, long int *Value,
    SymbolPointer Head, LocPointer Loc )
#else
  static PROC char ResolveExpression( Param, Value, Head, Loc )
  char **Param;
  long int *Value;
  SymbolPointer Head;
  LocPointer Loc;
#endif
{
  SymbolString Symbol;
  char Result;

  Result = False;
  *Value = 0L;
  SplitParam( Symbol, Param );
  if( *Symbol )
    Result = ResolveDivMod( Symbol, Param, Value, Head, Loc );
  if( *Symbol )
    return( False );
  else
    return( Result );
}

#if ANSI
  static PROC void MissingEquations( SymbolPointer Head )
#else
  static PROC void MissingEquations( Head )
  SymbolPointer Head;
#endif
{
  if( Head ) {
    MissingEquations( Head->Left );
    if( Head->Expr ) {
      SymbPoint = Head;
      RunError( False, UndefinedWarning );
      SymbPoint = NULL;
    }
    MissingEquations( Head->Right ); 
  }
}

#if ANSI
  static PROC unsigned int ResolveTraversal( SymbolPointer Symb,
    SymbolPointer Head )
#else
  static PROC unsigned int ResolveTraversal( Symb, Head )
  SymbolPointer Symb;
  SymbolPointer Head;
#endif
{
  char *Expression;
  long int Value;
  unsigned int Count;

  Count = 0;
  if( Symb ) {
    if( Symb->Expr ) {
      Expression = Symb->Expr;
      if( ResolveExpression( &Expression, &Value, Head, &( Symb->Loc ))) {
        Symb->Value = Value;
        Symb->Expr = NULL; 
      } else
        Count++;
    }
    Count += ResolveTraversal( Symb->Left, Head );
    Count += ResolveTraversal( Symb->Right, Head ); 
  }
  return( Count );
}

#if ANSI
  static PROC void ResolveEquations( SymbolPointer Head )
#else
  static PROC void ResolveEquations( Head )
  SymbolPointer Head;
#endif
{
  unsigned int Count;
  unsigned int Remains;

  Count = 0;
  do {
    Remains = Count;
    Count = ResolveTraversal( Head, Head );
  } while( Count && ( Count != Remains ));
  if( Count ) 
    MissingEquations( Head );
}

#if ANSI
  static PROC void StoreSymbolList( SymbolString SymbolText[],
    unsigned int Min, unsigned int Max, SymbolPointer *DirHead )
#else
  static PROC void StoreSymbolList( SymbolText, Min, Max, DirHead )
  SymbolString SymbolText[];
  unsigned int Min;
  unsigned int Max;
  SymbolPointer *DirHead;
#endif
{
  unsigned int This;

  This = Min + (( Max - Min ) >> 1 );
  if( !DefineSymbol( SymbolText[ This ], ( long int )This, DirHead,
    &NullLocation ))
      RunError( False, CopySymbolWarning );
  if( This != Min )
    StoreSymbolList( SymbolText, Min, This - 1, DirHead );
  if( This != Max )
    StoreSymbolList( SymbolText, This + 1, Max, DirHead );
}

#if ANSI
  static PROC char *SplitLine( char *Result, char **Line, char AbortFlag )
#else
  static PROC char *SplitLine( Result, Line, AbortFlag )
  char *Result;
  char **Line;
  char AbortFlag;
#endif
{
  char *Start;
  char *Count;
  char *Store;
  int Level;
  char TextFlag;
  char Reading;

  Store = Result;
  *Store = NullChar;
  Level = 0;
  TextFlag = False;
  Reading = True;
  for( Start = NULL, Count = *Line; *Count; Count++ ) 
    if( *Count == RemarkChar )
      Count = NullString;
    else 
      if( isgraph( *Count ) && ( *Count != SeparatorChar )) {
        Start = Count;
        Count = NullString;
      }
  if( Start ) 
    for( Count = Start; *Count && ( Count < Start + ParamLength ); Count++ ) 
      if( *Count == TextChar ) {
        if( Count != Start )
          if( *( Count - 1 ) == TextChar ) 
            *( Store++ ) = TextChar;
        TextFlag = ( char )~TextFlag;
      } else
        if( TextFlag ) 
          *( Store++ ) = *Count;
        else
          switch( *Count ) {
            case SeparatorChar:
              if( !Level ) {
                *Line = Count;
                Reading = False;
                Count = NullString;
              } else 
                *( Store++ ) = *Count;
              break;
            case RemarkChar:
              *Line = NullString;
              Reading = False;
              Count = NullString;
              break;
            case StartChar:
              Level++;
              *( Store++ ) = *Count;
              break;
            case StopChar:
              Level--;
              *( Store++ ) = *Count;
              break;
            default:
              if( isgraph( *Count )) 
                *( Store++ ) = ( char )toupper(( int )( *Count ));
              else
                if( AbortFlag && ( !Level )) {
                  *Line = Count;
                  Reading = False;
                  Count = NullString;
                } else
                  if( Store != Result )
                   if( *( Store - 1 ) != SpaceChar )
                     *( Store++ ) = SpaceChar; 
              break;
          }
  if( Reading )
    *Line = NullString;
  if( Store != Result )
    *( Store-- ) = NullChar;
  while( *Store == SpaceChar ) 
    if( Store > Result )
      *( Store-- ) = NullChar;
    else
      *Store = NullChar;
  return( Result );
}

#if ANSI
  static PROC void AlignWordBounds( void )
#else
  static PROC void AlignWordBounds()
#endif
{
  if( *AlignOnCond )
    Location.Addr = (( Location.Addr + 1 ) >> 1 ) << 1;
  if( Location.Addr > FinalAddress )
    FinalAddress = Location.Addr;
  if(( Location.Addr < StartAddress ) || ( Location.Addr > StopAddress ))
    RunError( True, BoundsError );
}

#if ANSI
  static PROC char ParamCheck( unsigned int Count, unsigned int Min,
    unsigned int Max )
#else
  static PROC char ParamCheck( Count, Min, Max )
  unsigned int Count;
  unsigned int Min;
  unsigned int Max;
#endif
{
  if(( Count < Min ) || ( Count > Max ))
    RunError( False, ParamCountWarning );
  if( Count >= Min )
    return( True );
  else
    return( False );
}

#if ANSI
  static PROC char RangeCheck( long int Value, long int Min, long int Max,
    char *Message )
#else
  static PROC char RangeCheck( Value, Min, Max, Message )
  long int Value;
  long int Min;
  long int Max;
  char *Message;
#endif
{
  if(( Value < Min ) || ( Value > Max )) {
    RunError( False, Message );
    return( True );
  } else
    return( False );
}

#if ANSI
  static PROC char DecodeOption( char *Option )
#else
  static PROC char DecodeOption( Option )
  char *Option;
#endif
{
  char Result;

  Result = True;
  if( !strcmp( Option, Chip8Name )) {
    *Chip8Cond = Defined;
    *Chip48Cond = Defined;
    *Super10Cond = UnDefined;
    *Super11Cond = UnDefined;
    *HpHeadCond = UnDefined;
    *HpAscCond = UnDefined;
    Result = False;
  }
  if( !strcmp( Option, Chip48Name )) {
    *Chip8Cond = UnDefined;
    *Chip48Cond = Defined;
    *Super10Cond = UnDefined;
    *Super11Cond = UnDefined;
    *HpHeadCond = Defined;
    Result = False;
  }
  if( !strcmp( Option, Super10Name )) {
    *Chip8Cond = UnDefined;
    *Chip48Cond = UnDefined;
    *Super10Cond = Defined;
    *Super11Cond = UnDefined;
    *HpHeadCond = Defined;
    Result = False;
  }
  if( !strcmp( Option, Super11Name )) {
    *Chip8Cond = UnDefined;
    *Chip48Cond = UnDefined;
    *Super10Cond = Defined;
    *Super11Cond = Defined;
    *HpHeadCond = Defined;
    Result = False;
  }
  if( !strcmp( Option, HpBinName )) {
    *HpHeadCond = Defined;
    *HpAscCond = UnDefined;
    Result = False;
  }
  if( !strcmp( Option, HpAscName )) {
    *HpHeadCond = Defined;
    *HpAscCond = Defined;
    Result = False;
  }
  if( !strcmp( Option, BinaryName )) {
    *HpHeadCond = UnDefined;
    *HpAscCond = UnDefined;
    Result = False;
  }
  if( !strcmp( Option, StringName )) {
    *HpHeadCond = UnDefined;
    *HpAscCond = Defined;
    Result = False;
  }
  return( Result );
}

#if ANSI
  static PROC unsigned int DecodeParameters( char **Line, ParamPointer *Head )
#else
  static PROC unsigned int DecodeParameters( Line, Head )
  char **Line;
  ParamPointer *Head;
#endif
{
  ParamString FoundWord;
  ParamPointer Param;
  ParamPointer Last;
  unsigned int Count;

  *Head = NULL;
  Count = 0;
  for( Last = NULL; **Line; )
    if( *SplitLine( FoundWord, Line, False )) {
      Param = ( ParamPointer )AssertSpace( &Space, sizeof( ParamRecord ));
      ClaimSpace( &Space, sizeof( ParamRecord ));
      Param->Param = ( char * )AssertSpace( &Space, sizeof( ParamString ));
      strcpy( Param->Param, FoundWord );
      ClaimSpace( &Space, ( unsigned int )( strlen( Param->Param ) + 1 ));
      Param->Next = NULL;
      if( Last )
        Last->Next = Param;
      else
        *Head = Param;
      Last = Param;
      Count++;
    }
  return( Count );
}

#if ANSI
  static PROC void DecodeDirective( unsigned int Token, char **Line,
    InstPointer *Head, SymbolPointer Dir, SymbolPointer *Symb,
    SymbolPointer *Cond )
#else
  static PROC void DecodeDirective( Token, Line, Head, Dir, Symb, Cond )
  unsigned int Token;
  char **Line;
  InstPointer *Head;
  SymbolPointer Dir;
  SymbolPointer *Symb;
  SymbolPointer *Cond;
#endif
{
  ParamPointer Params;
  InstPointer Inst;
  unsigned int Count;

  Count = DecodeParameters( Line, &Params );
  switch( Token ) {
    case ElseToken:
      ParamCheck( Count, 0, 0 );
      if( StackPoint == StackStart ) 
        RunError( False, MissingIfdefWarning );
      else 
        *StackPoint = ( char )~( *StackPoint );
      break;
    case EndifToken:
      ParamCheck( Count, 0, 0 );
      if( StackPoint <= StackStart ) 
        RunError( False, MissingIfdefWarning );
      else 
        StackPoint--;
      break;
    case IfdefToken:
    case IfundToken:
      if( ParamCheck( Count, 1, 1 )) {
        long int Value;

        if( !ResolveSymbol( Params->Param, &Value, *Cond, &NullLocation ))
          Value = 0L;
        if( Token == IfundToken )
          Value = ~Value;
        if( StackPoint >= StackStart + StackLength ) 
          RunError( True, NestedIfdefError );
        else 
          if( Value ) 
            *( ++StackPoint ) = True;
          else
            *( ++StackPoint ) = False;
      }
      break;
    default:
      if( *StackPoint ) {
        switch( Token ) {
          case WrongToken:
            RunError( False, InternalWarning );
            break;
          case AlignToken:
            if( ParamCheck( Count, 1, 1 )) 
              if( ResolveOption( Params->Param, AlignOnCond, AlignOnCond ))
                RunError( False, NoOptionWarning );
            break;
          case DefineToken:
          case UndefToken:
            if( ParamCheck( Count, 1, 1 )) 
              if( Token == DefineToken )
                DefineSymbol( Params->Param, Defined, Cond, &NullLocation );
              else
                DefineSymbol( Params->Param, UnDefined, Cond,
                  &NullLocation );
            break;
          case EqualToken:
          case EquToken:
            if( !CurrentSymbol )
              RunError( False, MissingSymbolWarning );
            else 
              if( ParamCheck( Count, 1, 1 )) {
                char *Expression;

                Expression = ( char * )AssertSpace( &Space,
                  sizeof( ParamString ));
                CurrentSymbol->Expr = strcpy( Expression, Params->Param );
                ClaimSpace( &Space, ( unsigned int )
                  ( strlen( Expression ) + 1 ));
              }
            break;
          case DsToken:
            if( ParamCheck( Count, 1, 1 )) {
              char *FirstParam;
              long int Value;

              FirstParam = Params->Param;
              if( !ResolveExpression( &FirstParam, &Value, *Symb, &Location ))
                RunError( False, UndefinedWarning );
              Location.Addr += Value;
            }
            break;
          case OptionToken:
            if( ParamCheck( Count, 1, 1 )) 
              if( DecodeOption( Params->Param ))
                RunError( False, NoOptionWarning );
            break;
          case OrgToken:
            if( ParamCheck( Count, 1, 1 )) {
              char *FirstParam;
              long int Value;

              FirstParam = Params->Param;
              if( ResolveExpression( &FirstParam, &Value, *Symb, &Location ))
                Location.Addr = Value;
              else
                RunError( False, UndefinedWarning );
            }
            break;
          case IncludeToken:
            if( ParamCheck( Count, 1, 1 )) {
              FILE *StoreFile;
              LocRecord StoreLoc;
              char *IncludeName;

              StoreFile = InFile; 
              StoreLoc = Location;
              for( IncludeName = Params->Param; *IncludeName; IncludeName++ )
                *IncludeName = ( char )tolower(( int )( *IncludeName ));
              IncludeName = ( char * )AssertSpace( &Space,
                sizeof( LineString ));
              strcpy( IncludeName, Params->Param );
              ClaimSpace( &Space, ( unsigned int )
                ( strlen( IncludeName ) + 1 ));
              InFile = fopen( IncludeName, "r" );
              if( !InFile )
                RunError( True, NoSourceError );
              //{{2004/04/02 Naoyuki Sawa
              //DecodeFile( IncludeName, Head, Dir, Symb, Cond );
              //↓命令配置アドレスは元に戻さず、継続するように変更しました。
              StoreLoc.Addr = DecodeFile( IncludeName, Head, Dir, Symb, Cond );
              //}}2004/04/02 Naoyuki Sawa
              InFile = StoreFile;
              Location = StoreLoc;
              if( fprintf( stderr, "Reading: %s\n\n", Location.Name ) <= 0 )
                RunError( True, FileWriteError );
              if( fprintf( ListFile, "Reading: %s\n\n", Location.Name ) <= 0 )
                RunError( True, FileWriteError );
            }
            break;
          case EndToken:
            ParamCheck( Count, 0, 0 );
            /* The END directive is ignored */
            break;
          case UsedToken:
            if( ParamCheck( Count, 1, ListLength )) 
              if( ResolveOption( Params->Param, UsedYesCond, UsedOnCond )) {
                ParamPointer Point;
                long int Value;
      
                for( Point = Params; Point; Point = Point->Next ) 
                  if( *XrefOnCond ) {
                    if( !ResolveSymbol( Point->Param, &Value, *Symb,
                      &Location ))
                        if( !Value )
                          RunError( False, NoSymbolWarning );
                  } else
                    if( !ResolveSymbol( Point->Param, &Value, *Symb,
                      &UsedLocation ))
                        if( !Value )
                          RunError( False, NoSymbolWarning );
              } else
                if( Count > 1 )
                  RunError( False, ParamCountWarning );
            break;
          case XrefToken:
            if( ParamCheck( Count, 1, 1 )) 
              if( ResolveOption( Params->Param, XrefYesCond, XrefOnCond ))
                RunError( False, NoOptionWarning );
            break;
          default:
            Inst = ( InstPointer )AssertSpace( &Space, sizeof( InstRecord ));
            ClaimSpace( &Space, sizeof( InstRecord ));
            Inst->Loc = Location;
            Inst->Token = Token;
            Inst->Count = Count;
            Inst->Params = Params;
            Inst->Next = NULL;
            if( *Head ) 
              ( *Head )->Next = Inst;
            else
              Instructions = Inst;
            *Head = Inst;
            switch( Token ) {
              case DbToken:
                if( ParamCheck( Count, 1, ListLength ))
                  Location.Addr += Count;
                break;
              case DwToken:
                if( ParamCheck( Count, 1, ListLength ))
                  Location.Addr += Count * 2;
                break;
              case DaToken:
                if( ParamCheck( Count, 1, 1 ))
                  Location.Addr += strlen( Params->Param );
                break;
              default:
                Location.Addr += 2;
                break;
            }
          break;
        }
      }
      break;
  }
}

#if ANSI
  static PROC void DecodeLine( char **Line, InstPointer *Head,
    SymbolPointer Dir, SymbolPointer *Symb, SymbolPointer *Cond )
#else
  static PROC void DecodeLine( Line, Head, Dir, Symb, Cond )
  char **Line;
  InstPointer *Head;
  SymbolPointer Dir;
  SymbolPointer *Symb;
  SymbolPointer *Cond;
#endif
{
  ParamString Split;
  long int Value;

  CurrentSymbol = NULL;
  while( **Line ) 
    if( *SplitLine( Split, Line, True )) 
      if( !ResolveSymbol( Split, &Value, Dir, &NullLocation )) {
        if( *StackPoint )
          if( CurrentSymbol ) {
            RunError( False, DualSymbolWarning );
            *Line = NullString;
          } else 
            if( !DefineSymbol( Split, Location.Addr, Symb, &Location ))
              RunError( False, CopySymbolWarning );
      } else {
        DecodeDirective(( unsigned int )Value, Line, Head, Dir, Symb, Cond );
        AlignWordBounds();
        *Line = NullString;
      }
  CurrentSymbol = NULL;
}

#if ANSI
  //{{2004/04/02 Naoyuki Sawa
  //static PROC void DecodeFile( char *FileName, InstPointer *Head,
  //  SymbolPointer Dir, SymbolPointer *Symb, SymbolPointer *Cond )
  //↓次の命令配置アドレスを返すように変更しました。
  static PROC long DecodeFile( char *FileName, InstPointer *Head,
    SymbolPointer Dir, SymbolPointer *Symb, SymbolPointer *Cond )
  //}}2004/04/02 Naoyuki Sawa
#else
  //{{2004/04/02 Naoyuki Sawa
  //static PROC void DecodeFile( FileName, Head, Dir, Symb, Cond )
  //↓次の命令配置アドレスを返すように変更しました。
  static PROC long DecodeFile( FileName, Head, Dir, Symb, Cond )
  //}}2004/04/02 Naoyuki Sawa
  char *FileName;
  InstPointer *Head;
  SymbolPointer Dir;
  SymbolPointer *Symb;
  SymbolPointer *Cond;
#endif
{
  char *StoreStack;
  char *Line;
  //{{2004/04/02 Naoyuki Sawa
  long NextAddr; /* 次の命令配置アドレスを記憶しておくための変数です */
  //}}2004/04/02 Naoyuki Sawa

  StoreStack = StackPoint;
  if( fprintf( stderr, "Reading: %s\n\n", FileName ) <= 0 )
    RunError( True, FileWriteError );
  if( fprintf( ListFile, "Reading: %s\n\n", FileName ) <= 0 )
    RunError( True, FileWriteError );
  Location.Text = ( char * )AssertSpace( &Space, sizeof( LineString ));
  *( Location.Text ) = NullChar;
  Location.Name = FileName;
  Location.Line = 1;
  while( fgets( Location.Text, LineLength + 1, InFile )) {
    ClaimSpace( &Space, ( unsigned int )( strlen( Location.Text ) + 1 ));
    if( *XrefOnCond )
      Location.Xref = True;
    else
      Location.Xref = False;
    for( Line = Location.Text; *Line; Line++ )
      if( iscntrl( *Line ))
        *Line = SpaceChar;
    Line = Location.Text;
    DecodeLine( &Line, Head, Dir, Symb, Cond );
    Location.Text = ( char * )AssertSpace( &Space, sizeof( LineString ));
    *( Location.Text ) = NullChar;
    Location.Line++;
  }
  strcpy( Location.Text, EndOfFileMessage );
  ClaimSpace( &Space, ( unsigned int )( strlen( Location.Text ) + 1 ));
  if( StoreStack != StackPoint )
    RunError( False, CountDefineWarning );
  if( InFile )
    if( InFile != stdin )
      fclose( InFile );
  InFile = NULL;
  //{{2004/04/02 Naoyuki Sawa
  NextAddr = Location.Addr; /* Locationをクリアする前に、次の命令配置アドレスを記憶します */
  //}}2004/04/02 Naoyuki Sawa
  Location = NullLocation;
  //{{2004/04/02 Naoyuki Sawa
  return NextAddr; /* 次の命令配置アドレスを返します */
  //}}2004/04/02 Naoyuki Sawa
}

#if ANSI
  static PROC void EncodeNoneToken( InstPointer Inst, long int OpCode,
    long int *Ver10, long int *Ver11 )
#else
  static PROC void EncodeNoneToken( Inst, OpCode, Ver10, Ver11 )
  InstPointer Inst;
  long int OpCode;
  long int *Ver10;
  long int *Ver11;
#endif
{
  ParamCheck( Inst->Count, 0, 0 );
  /* Generate instruction anyway */
  if( !( *Ver11 ))
    RunError( False, NeedsSuper11Warning );
  if( !( *Ver10 ))
    RunError( False, NeedsSuper10Warning );
  Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
    (( OpCode & 0xff00L ) >> 8 );
  Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
    ( OpCode & 0xffL );
  ListInstruction( Inst->Loc.Addr, 2, Inst );
}

#if ANSI
  static PROC void EncodeValToken( InstPointer Inst, long int OpCode,
    long int Limit, SymbolPointer Symb, long int *Ver8, long int *Ver11 )
#else
  static PROC void EncodeValToken( Inst, OpCode, Limit, Symb, Ver8, Ver11 )
  InstPointer Inst;
  long int OpCode;
  long int Limit;
  SymbolPointer Symb;
  long int *Ver8; 
  long int *Ver11;
#endif
{
  long int Value;

  Value = 0L;
  if( ParamCheck( Inst->Count, 1, 1 )) {
    char *FirstParam;

    FirstParam = Inst->Params->Param;
    if( !ResolveExpression( &FirstParam, &Value, Symb, &( Inst->Loc )))
      RunError( False, UndefinedWarning );
  }
  if( RangeCheck( Value, 0L, Limit, RangeWarning ))
    Value &= Limit;
  if( !( *Ver11 ))
    RunError( False, NeedsSuper11Warning );
  if( !( *Ver8 ))
    RunError( False, NeedsChip8Warning );
  Value |= OpCode;
  Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
    (( Value & 0xff00L ) >> 8 );
  Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
    ( Value & 0xffL );
  ListInstruction( Inst->Loc.Addr, 2, Inst );
}

#if ANSI
  static PROC void EncodeRegToken( InstPointer Inst, long int OpCode,
    SymbolPointer Reg )
#else
  static PROC void EncodeRegToken( Inst, OpCode, Reg )
  InstPointer Inst;
  long int OpCode;
  SymbolPointer Reg;
#endif
{
  long int RegX;

  RegX = ( long int )V0Reg;
  if( ParamCheck( Inst->Count, 1, 1 )) {
    if( ResolveSymbol( Inst->Params->Param, &RegX, Reg, &NullLocation ))
      RegX -= V0Reg;
    else
      RunError( False, NoRegisterWarning );
  }
  if( RangeCheck( RegX, 0L, NibbleMask, BadRegisterWarning ))
    RegX = 0L;
  RegX = OpCode | ( RegX << 8 );
  Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
    (( RegX & 0xff00L ) >> 8 );
  Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
    ( RegX & 0xffL );
  ListInstruction( Inst->Loc.Addr, 2, Inst );
}

#if ANSI
  static PROC void EncodeRegValToken( InstPointer Inst, long int OpCode,
    SymbolPointer Reg, SymbolPointer Symb )
#else
  static PROC void EncodeRegValToken( Inst, OpCode, Reg, Symb )
  InstPointer Inst;
  long int OpCode;
  SymbolPointer Reg;
  SymbolPointer Symb;
#endif
{
  long int RegX;
  long int Value;

  RegX = ( long int )V0Reg;
  Value = 0L;
  if( Inst->Count >= 1 ) 
    if( ResolveSymbol( Inst->Params->Param, &RegX, Reg, &NullLocation ))
      RegX -= V0Reg;
    else
      RunError( False, NoRegisterWarning );
  if( RangeCheck( RegX, 0L, NibbleMask, BadRegisterWarning ))
    RegX = 0L;
  if( ParamCheck( Inst->Count, 2, 2 )) {
    char *SecondParam;

    SecondParam = Inst->Params->Next->Param;
    if( !ResolveExpression( &SecondParam, &Value, Symb, &( Inst->Loc )))
      RunError( False, UndefinedWarning );
  }
  if( RangeCheck( Value, 0L, ByteMask, RangeWarning ))
    Value &= ByteMask;
  Value |= OpCode | ( RegX << 8 );
  Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
    (( Value & 0xff00L ) >> 8 );
  Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
    ( Value & 0xffL );
  ListInstruction( Inst->Loc.Addr, 2, Inst );
}

#if ANSI
  static PROC void EncodeRegRegToken( InstPointer Inst, long int OpCode,
    unsigned int Min, SymbolPointer Reg )
#else
  static PROC void EncodeRegRegToken( Inst, OpCode, Min, Reg )
  InstPointer Inst;
  long int OpCode;
  unsigned int Min;
  SymbolPointer Reg;
#endif
{
  long int RegX;
  long int RegY;

  RegX = ( long int )V0Reg;
  RegY = 0L;
  if( ParamCheck( Inst->Count, Min, 2 )) 
    if( ResolveSymbol( Inst->Params->Param, &RegX, Reg, &NullLocation ))
      RegX -= V0Reg;
    else
      RunError( False, NoRegisterWarning );
  if( RangeCheck( RegX, 0L, NibbleMask, BadRegisterWarning ))
    RegX = 0L;
  if( Inst->Count >= 2 ) 
    if( ResolveSymbol( Inst->Params->Next->Param, &RegY, Reg, &NullLocation ))
      RegY -= V0Reg;
    else
      RunError( False, NoRegisterWarning );
  if( RangeCheck( RegY, 0L, NibbleMask, BadRegisterWarning ))
    RegY = 0L;
  RegX = OpCode | ( RegX << 8 ) | ( RegY << 4 );
  Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
    (( RegX & 0xff00L ) >> 8 );
  Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
    ( RegX & 0xffL );
  ListInstruction( Inst->Loc.Addr, 2, Inst );
}

#if ANSI
  static PROC void EncodeRegRegOrValToken( InstPointer Inst, long int OpCode1,
    long int OpCode2, SymbolPointer Reg, SymbolPointer Symb )
#else
  static PROC void EncodeRegRegOrValToken( Inst, OpCode1, OpCode2, Reg, Symb )
  InstPointer Inst;
  long int OpCode1;
  long int OpCode2;
  SymbolPointer Reg;
  SymbolPointer Symb;
#endif
{
  long int RegX;
  long int RegY;
  long int Value;

  RegX = ( long int )V0Reg;
  RegY = ( long int )V0Reg;
  Value = 0L;
  if( Inst->Count >= 1 ) 
    if( ResolveSymbol( Inst->Params->Param, &RegX, Reg, &NullLocation ))
      RegX -= V0Reg;
    else
      RunError( False, NoRegisterWarning );
  if( RangeCheck( RegX, 0L, NibbleMask, BadRegisterWarning ))
    RegX = 0L;
  if( ParamCheck( Inst->Count, 2, 2 ))
    if( ResolveSymbol( Inst->Params->Next->Param, &RegY, Reg,
      &NullLocation )) {
        RegY -= V0Reg;
        if( RangeCheck( RegY, 0L, NibbleMask, BadRegisterWarning ))
          RegY = 0L;
        Value = OpCode1 | ( RegX << 8 ) | ( RegY << 4 );
        Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
          (( Value & 0xff00L ) >> 8 );
        Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
          ( Value & 0xffL );
        ListInstruction( Inst->Loc.Addr, 2, Inst );
      } else {
        char *SecondParam;

        SecondParam = Inst->Params->Next->Param; 
        if( !ResolveExpression( &SecondParam, &Value, Symb, &( Inst->Loc )))
          RunError( False, UndefinedWarning );
        if( RangeCheck( Value, 0L, ByteMask, RangeWarning ))
          Value &= ByteMask;
        Value |= OpCode2 | ( RegX << 8 );
        Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
          (( Value & 0xff00L ) >> 8 );
        Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
          ( Value & 0xffL );
        ListInstruction( Inst->Loc.Addr, 2, Inst );
      }
}

#if ANSI
  static PROC void EncodeDrwToken( InstPointer Inst, long int OpCode,
    SymbolPointer Reg, SymbolPointer Symb )
#else
  static PROC void EncodeDrwToken( Inst, OpCode, Reg, Symb )
  InstPointer Inst;
  long int OpCode;
  SymbolPointer Reg;
  SymbolPointer Symb;
#endif
{
  long int RegX;
  long int RegY;
  long int Value;

  RegX = ( long int )V0Reg;
  RegY = ( long int )V0Reg;
  Value = 0L;
  if( Inst->Count >= 1 ) 
    if( ResolveSymbol( Inst->Params->Param, &RegX, Reg, &NullLocation ))
      RegX -= V0Reg;
    else
      RunError( False, NoRegisterWarning );
  if( RangeCheck( RegX, 0L, NibbleMask, BadRegisterWarning ))
    RegX = 0L;
  if( Inst->Count >= 2 ) 
    if( ResolveSymbol( Inst->Params->Next->Param, &RegY, Reg, &NullLocation ))
      RegY -= V0Reg;
    else
      RunError( False, NoRegisterWarning );
  if( RangeCheck( RegY, 0L, NibbleMask, BadRegisterWarning ))
    RegY = 0L;
  if( ParamCheck( Inst->Count, 3, 3 )) {
    char *ThirdParam;

    ThirdParam = Inst->Params->Next->Next->Param;
    if( !ResolveExpression( &ThirdParam, &Value, Symb, &( Inst->Loc )))
      RunError( False, UndefinedWarning );
  }
  if( RangeCheck( Value, 0L, NibbleMask, RangeWarning ))
    Value &= NibbleMask;
  if(( Value == 0L ) && !( *Super10Cond ))
    RunError( False, NeedsSuper10Warning );
  Value |= OpCode | ( RegX << 8 ) | ( RegY << 4 );
  Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
    (( Value & 0xff00L ) >> 8 );
  Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
    ( Value & 0xffL );
  ListInstruction( Inst->Loc.Addr, 2, Inst );
}

#if ANSI
  static PROC void EncodeAddToken( InstPointer Inst, SymbolPointer Reg,
    SymbolPointer Symb )
#else
  static PROC void EncodeAddToken( Inst, Reg, Symb )
  InstPointer Inst;
  SymbolPointer Reg;
  SymbolPointer Symb;
#endif
{
  long int RegX;
  long int RegY;
  long int Value;

  RegX = ( long int )V0Reg;
  RegY = ( long int )V0Reg;
  Value = 0L;
  if( Inst->Count >= 1 ) 
    if( !ResolveSymbol( Inst->Params->Param, &RegX, Reg, &NullLocation )) {
      RegX = ( long int )V0Reg;
      RunError( False, NoRegisterWarning );
    }
  if( RegX == ( long int )IReg ) {
    if( ParamCheck( Inst->Count, 2, 2 )) 
      if( ResolveSymbol( Inst->Params->Next->Param, &RegX, Reg,
        &NullLocation ))
          RegX -= V0Reg;
      else
        RunError( False, NoRegisterWarning );
    if( RangeCheck( RegX, 0L, NibbleMask, BadRegisterWarning ))
      RegX = 0L;
    Value = 0xf01eL | ( RegX << 8 );
    Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
      (( Value & 0xff00L ) >> 8 );
    Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
      ( Value & 0xffL );
    ListInstruction( Inst->Loc.Addr, 2, Inst );
  } else {
    RegX -= V0Reg;
    if( RangeCheck( RegX, 0L, NibbleMask, BadRegisterWarning ))
      RegX = 0L;
    if( ParamCheck( Inst->Count, 2, 2 ))
      if( ResolveSymbol( Inst->Params->Next->Param, &RegY, Reg,
        &NullLocation )) {
          RegY -= V0Reg;
          if( RangeCheck( RegY, 0L, NibbleMask, BadRegisterWarning ))
            RegY = 0L;
          Value = 0x8004L | ( RegX << 8 ) | ( RegY << 4 );
          Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
            (( Value & 0xff00L ) >> 8 );
          Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
            ( Value & 0xffL );
          ListInstruction( Inst->Loc.Addr, 2, Inst );
        } else {
          char *SecondParam;

          SecondParam = Inst->Params->Next->Param;
          if( !ResolveExpression( &SecondParam, &Value, Symb, &( Inst->Loc )))
            RunError( False, UndefinedWarning );
          if( RangeCheck( Value, 0L, ByteMask, RangeWarning ))
            Value &= ByteMask;
          Value |= 0x7000L | ( RegX << 8 );
          Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
            (( Value & 0xff00L ) >> 8 );
          Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
            ( Value & 0xffL );
          ListInstruction( Inst->Loc.Addr, 2, Inst );
        }
  }
}

#if ANSI
  static PROC void EncodeJpToken( InstPointer Inst, SymbolPointer Reg,
    SymbolPointer Symb )
#else
  static PROC void EncodeJpToken( Inst, Reg, Symb )
  InstPointer Inst;
  SymbolPointer Reg;
  SymbolPointer Symb;
#endif
{
  long int RegX;
  long int Addr;

  RegX = ( long int )V0Reg;
  Addr = ( long int )V0Reg;
  if( ParamCheck( Inst->Count, 1, 2 ))
    if( ResolveSymbol( Inst->Params->Param, &RegX, Reg, &NullLocation )) {
      if( RegX != V0Reg )
        RunError( False, BadRegisterWarning );
      if( Inst->Count == 1 )
        RunError( False, ParamCountWarning );
      else {
        char *SecondParam;

        SecondParam = Inst->Params->Next->Param;
        //{{2004/04/02 Naoyuki Sawa
        //if( ResolveExpression( &SecondParam , &Addr, Symb, &( Inst->Loc )))
        //↓式が“正しいとき(!=0)にエラー”ではなく“不正なとき(=0)にエラー”に修正しました。
        if( !ResolveExpression( &SecondParam , &Addr, Symb, &( Inst->Loc )))
        //}}2004/04/02 Naoyuki Sawa
          RunError( False, UndefinedWarning );
      }
      if( RangeCheck( Addr, 0L, AddrMask, RangeWarning ))
        Addr &= AddrMask;
      Addr |= 0xb000L;
      Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
        (( Addr & 0xff00L ) >> 8 );
      Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
        ( Addr & 0xffL );
      ListInstruction( Inst->Loc.Addr, 2, Inst );
    } else {
      char *FirstParam;

      FirstParam = Inst->Params->Param;
      if( !ResolveExpression( &FirstParam, &Addr, Symb, &( Inst->Loc )))
        RunError( False, UndefinedWarning );
      if( Inst->Count == 2 )
        RunError( False, ParamCountWarning );
      if( RangeCheck( Addr, 0L, AddrMask, RangeWarning ))
        Addr &= AddrMask;
      Addr |= 0x1000L;
      Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
        (( Addr & 0xff00L ) >> 8 );
      Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
        ( Addr & 0xffL );
      ListInstruction( Inst->Loc.Addr, 2, Inst );
    }
}

#if ANSI
  static PROC void EncodeLdToken( InstPointer Inst, SymbolPointer Reg,
    SymbolPointer Symb )
#else
  static PROC void EncodeLdToken( Inst, Reg, Symb )
  InstPointer Inst;
  SymbolPointer Reg;
  SymbolPointer Symb;
#endif
{
  long int RegX;
  long int RegY;
  long int Value;
  char RegFlag;

  RegX = ( long int )V0Reg;
  RegY = ( long int )V0Reg;
  Value = 0L;
  RegFlag = True;
  if( Inst->Count >= 1 ) 
    if( !ResolveSymbol( Inst->Params->Param, &RegX, Reg, &NullLocation )) {
      RegX = ( long int )V0Reg;
      RunError( False, NoRegisterWarning );
    }
  switch( RegX ) {
    case BReg:
    case DtReg:
    case FReg:
    case HfReg:
    case LfReg:
    case RReg:
    case StReg:
    case IiReg:
      RegY = RegX;
      RegX = ( long int )V0Reg;
      if( ParamCheck( Inst->Count, 2, 2 )) 
        if( ResolveSymbol( Inst->Params->Next->Param, &RegX, Reg,
          &NullLocation ))
            RegX -= V0Reg;
        else
          RunError( False, NoRegisterWarning );
      if( RangeCheck( RegX, 0L, NibbleMask, BadRegisterWarning ))
        RegX = 0L;
      switch( RegY ) {
        case BReg:
          Value = 0xf033L | ( RegX << 8 );
          break;
        case DtReg:
          Value = 0xf015L | ( RegX << 8 );
          break;
        case FReg:
          if( !( *Chip48Cond ))
            RunError( False, NeedsChip48Warning );
          Value = 0xf029L | ( RegX << 8 );
          break;
        case HfReg:
          if( !( *Super10Cond ))
            RunError( False, NeedsSuper10Warning );
          Value = 0xf030L | ( RegX << 8 );
          break;
        case LfReg:
          if( !( *Super10Cond ))
            RunError( False, NeedsSuper10Warning );
          Value = 0xf029L | ( RegX << 8 );
          break;
        case RReg:
          if( RangeCheck( RegX, 0L, 7L, BadRegisterWarning ))
            RegX = 0L;
          if( !( *Super10Cond ))
            RunError( False, NeedsSuper10Warning );
          Value = 0xf075L | ( RegX << 8 );
          break;
        case StReg:
          Value = 0xf018L | ( RegX << 8 );
          break;
        case IiReg:
          Value = 0xf055L | ( RegX << 8 );
          break;
        default:
          RunError( False, InternalWarning );
          break;
      }
      Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
        (( Value & 0xff00L ) >> 8 );
      Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
        ( Value & 0xffL );
      ListInstruction( Inst->Loc.Addr, 2, Inst );
      break;
    case IReg:
      if( ParamCheck( Inst->Count, 2, 2 )) {
        char *SecondParam;

        SecondParam = Inst->Params->Next->Param;
        if( !ResolveExpression( &SecondParam, &Value, Symb, &( Inst->Loc )))
          RunError( False, UndefinedWarning );
      }
      if( RangeCheck( Value, 0L, AddrMask, RangeWarning ))
        Value &= AddrMask;
      Value |= 0xa000L;
      Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
        (( Value & 0xff00L ) >> 8 );
      Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
        ( Value & 0xffL );
      ListInstruction( Inst->Loc.Addr, 2, Inst );
      break;
    default:
      RegX -= V0Reg;
      if( RangeCheck( RegX, 0L, NibbleMask, BadRegisterWarning ))
        RegX = 0L;
      if( ParamCheck( Inst->Count, 2, 2 ))
        RegFlag = ResolveSymbol( Inst->Params->Next->Param, &RegY, Reg,
          &NullLocation );
      if( RegFlag ) 
        switch( RegY ) {
          case DtReg:
            Value = 0xf007L | ( RegX << 8 );
            Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
              (( Value & 0xff00L ) >> 8 );
            Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
              ( Value & 0xffL );
            ListInstruction( Inst->Loc.Addr, 2, Inst );
            break;
          case KReg:
            Value = 0xf00aL | ( RegX << 8 );
            Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
              (( Value & 0xff00L ) >> 8 );
            Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
              ( Value & 0xffL );
            ListInstruction( Inst->Loc.Addr, 2, Inst );
            break;
          case RReg:
            if( RangeCheck( RegX, 0L, 7L, BadRegisterWarning ))
              RegX = 0L;
            if( !( *Super10Cond ))
              RunError( False, NeedsSuper10Warning );
            Value = 0xf085L | ( RegX << 8 );
            Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
              (( Value & 0xff00L ) >> 8 );
            Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
              ( Value & 0xffL );
            ListInstruction( Inst->Loc.Addr, 2, Inst );
            break;
          case IiReg:
            Value = 0xf065L | ( RegX << 8 );
            Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
              (( Value & 0xff00L ) >> 8 );
            Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
              ( Value & 0xffL );
            ListInstruction( Inst->Loc.Addr, 2, Inst );
            break;
          default:
            RegY -= V0Reg;
            if( RangeCheck( RegY, 0L, NibbleMask, BadRegisterWarning ))
              RegY = 0L;
            Value = 0x8000L | ( RegX << 8 ) | ( RegY << 4 );
            Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
              (( Value & 0xff00L ) >> 8 );
            Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
              ( Value & 0xffL );
            ListInstruction( Inst->Loc.Addr, 2, Inst );
            break;
        }
      else {
        if( Inst->Count >= 2 ) {
          char *SecondParam;

          SecondParam = Inst->Params->Next->Param;
          if( !ResolveExpression( &SecondParam, &Value, Symb, &( Inst->Loc )))
            RunError( False, UndefinedWarning );
        }
        if( RangeCheck( Value, 0L, ByteMask, RangeWarning ))
          Value &= ByteMask;
        Value |= 0x6000L | ( RegX << 8 );
        Memory[ Inst->Loc.Addr - StartAddress ] = ( unsigned char )
          (( Value & 0xff00L ) >> 8 );
        Memory[ Inst->Loc.Addr - StartAddress + 1 ] = ( unsigned char )
          ( Value & 0xffL );
        ListInstruction( Inst->Loc.Addr, 2, Inst );
      }
      break;
  }
}

#if ANSI
  static PROC void EncodeDaToken( InstPointer Inst )
#else
  static PROC void EncodeDaToken( Inst )
  InstPointer Inst;
#endif
{
  char *Param;
  char *This;
  long int Store;

  Param = NullString;
  if( Inst->Count >= 1 )
    Param = Inst->Params->Param;
  Store = Inst->Loc.Addr - StartAddress;
  for( This = Param ; *This; This++ )
    Memory[ Store++ ] = *This;
  ListInstruction( Inst->Loc.Addr, ( unsigned int )strlen( Param ), Inst );
}

#if ANSI
  static PROC void EncodeDbToken( InstPointer Inst, SymbolPointer Symb )
#else
  static PROC void EncodeDbToken( Inst, Symb )
  InstPointer Inst;
  SymbolPointer Symb;
#endif
{
  ParamPointer Param;
  char *LoopParam;
  long int Value;
  unsigned int This;

  This = 0;
  Value = 0L;
  for( Param = Inst->Params; Param; Param = Param->Next ) {
    LoopParam = Param->Param; 
    if( !ResolveExpression( &LoopParam, &Value, Symb, &( Inst->Loc )))
      RunError( False, UndefinedWarning );
    if( RangeCheck( Value, 0L, ByteMask, RangeWarning ))
      Value &= ByteMask;
    Memory[ Inst->Loc.Addr + ( This++ ) - StartAddress ] = ( unsigned char )
      Value;
  }
  ListInstruction( Inst->Loc.Addr, Inst->Count, Inst );
}

#if ANSI
  static PROC void EncodeDwToken( InstPointer Inst, SymbolPointer Symb )
#else
  static PROC void EncodeDwToken( Inst, Symb )
  InstPointer Inst;
  SymbolPointer Symb;
#endif
{
  ParamPointer Param;
  char *LoopParam;
  long int Value;
  unsigned int This;

  This = 0;
  Value = 0L;
  for( Param = Inst->Params; Param; Param = Param->Next ) {
    LoopParam = Param->Param;
    if( !ResolveExpression( &LoopParam, &Value, Symb, &( Inst->Loc )))
      RunError( False, UndefinedWarning );
    if( RangeCheck( Value, 0L, WordMask, RangeWarning ))
      Value &= WordMask;
    Memory[ Inst->Loc.Addr + ( This++ ) - StartAddress ] = ( unsigned char )
      (( Value & 0xff00L ) >> 8 );
    Memory[ Inst->Loc.Addr + ( This++ ) - StartAddress ] = ( unsigned char )
      ( Value & 0xffL );
  }
  ListInstruction( Inst->Loc.Addr, Inst->Count * 2, Inst );
}

#if ANSI
  static PROC void EncodeInstruction( InstPointer Inst, SymbolPointer Reg,
    SymbolPointer Symb )
#else
  static PROC void EncodeInstruction( Inst, Reg, Symb )
  InstPointer Inst;
  SymbolPointer Reg;
  SymbolPointer Symb;
#endif
{
  switch( Inst->Token ) {
    case AddToken:
      EncodeAddToken( Inst, Reg, Symb );
      break;
    case AndToken:
      EncodeRegRegToken( Inst, 0x8002L, 2, Reg );
      break;
    case CallToken:
      EncodeValToken( Inst, 0x2000L, AddrMask, Symb, &DefinedValue,
        &DefinedValue );
      break;
    case ClsToken:
      EncodeNoneToken( Inst, 0x00e0L, &DefinedValue, &DefinedValue );
      break;
    case DaToken:
      EncodeDaToken( Inst );
      break;
    case DbToken:
      EncodeDbToken( Inst, Symb );
      break;
    case DrwToken:
      EncodeDrwToken( Inst, 0xd000L, Reg, Symb );
      break;
    case DwToken:
      EncodeDwToken( Inst, Symb );
      break;
    case ExitToken:
      EncodeNoneToken( Inst, 0x00fdL, Super10Cond, &DefinedValue );
      break;
    case HighToken:
      EncodeNoneToken( Inst, 0x00ffL, Super10Cond, &DefinedValue );
      break;
    case JpToken:
      EncodeJpToken( Inst, Reg, Symb );
      break;
    case LdToken:
      EncodeLdToken( Inst, Reg, Symb );
      break;
    case LowToken:
      EncodeNoneToken( Inst, 0x00feL, Super10Cond, &DefinedValue );
      break;
    case OrToken:
      EncodeRegRegToken( Inst, 0x8001L, 2, Reg );
      break;
    case RetToken:
      EncodeNoneToken( Inst, 0x00eeL, &DefinedValue, &DefinedValue );
      break;
    case RndToken:
      EncodeRegValToken( Inst, 0xc000L, Reg, Symb );
      break;
    case ScdToken:
      EncodeValToken( Inst, 0x00c0L, NibbleMask, Symb, &DefinedValue,
        Super11Cond );
      break;
    case SclToken:
      EncodeNoneToken( Inst, 0x00fcL, &DefinedValue, Super11Cond );
      break;
    case ScrToken:
      EncodeNoneToken( Inst, 0x00fbL, &DefinedValue, Super11Cond );
      break;
    case SeToken:
      EncodeRegRegOrValToken( Inst, 0x5000L, 0x3000L, Reg, Symb );
      break;
    case ShlToken:
      EncodeRegRegToken( Inst, 0x800eL, 1, Reg );
      break;
    case ShrToken:
      EncodeRegRegToken( Inst, 0x8006L, 1, Reg );
      break;
    case SknpToken:
      EncodeRegToken( Inst, 0xe0a1L, Reg );
      break;
    case SkpToken:
      EncodeRegToken( Inst, 0xe09eL, Reg );
      break;
    case SneToken:
      EncodeRegRegOrValToken( Inst, 0x9000L, 0x4000L, Reg, Symb );
      break;
    case SubToken:
      EncodeRegRegToken( Inst, 0x8005L, 2, Reg );
      break;
    case SubnToken:
      EncodeRegRegToken( Inst, 0x8007L, 2, Reg );
      break;
    case SysToken:
      EncodeValToken( Inst, 0x2000L, AddrMask, Symb, Chip8Cond,
        &DefinedValue );
      break;
    case XorToken:
      EncodeRegRegToken( Inst, 0x8003L, 2, Reg );
      break;
    default:
      RunError( False, InternalWarning );
      break;
  }
}

#if ANSI
  static PROC void EncodeMemory( InstPointer Inst, SymbolPointer Reg,
    SymbolPointer Symb, SymbolPointer Cond )
#else
  static PROC void EncodeMemory( Inst, Reg, Symb, Cond )
  InstPointer Inst;
  SymbolPointer Reg;
  SymbolPointer Symb;
  SymbolPointer Cond;
#endif
{
  long int Count;

  if( fprintf( ListFile, "-----   *INSTRUCTIONS*   -----\n\n" ) <= 0 )
    RunError( True, FileWriteError );
  for( Count = StartAddress; Count <= StopAddress; Count++ )
    Memory[ Count - StartAddress ] = 0;
  while( Inst ) {
    InstPoint = Inst;
    EncodeInstruction( Inst, Reg, Symb );
    Inst = Inst->Next;
  }
  InstPoint = NULL;
  if( fprintf( ListFile, "\n-----   *SYMBOLS*   -----\n\n" ) <= 0 )
    RunError( True, FileWriteError );
  ListSymbols( Symb );
  if( fprintf( ListFile, "\n-----   *CONDITIONS*   -----\n\n" ) <= 0 )
    RunError( True, FileWriteError );
  ListDefines( Cond );
  fprintf( ListFile, "\n" );
  ListWarnings();
}

#if ANSI
  static PROC void WriteCheckByte( long int *Check, unsigned char Value )
#else
  static PROC void WriteCheckByte( Check, Value )
  long int *Check;
  unsigned char Value;
#endif
{
  SymbolString MsbText;
  SymbolString LsbText;

  if( *HpHeadCond ) {
    if( fprintf( OutFile, "%s%s", NumberString( LsbText,
      ( long int )( Value & NibbleMask ), 16, 1 ), NumberString( MsbText,
      ( long int )(( Value >> 4 ) & NibbleMask ), 16, 1 )) <= 0 )
        RunError( True, FileWriteError );
  } else
    if( fprintf( OutFile, "%s", NumberString( MsbText, ( long int )Value,
      16, 2 )) <= 0 )
        RunError( True, FileWriteError );
  *Check = ((( *Check ) >> 4 ) ^ ((( Value ^ ( *Check )) & NibbleMask ) *
    CheckMagic ) & WordMask );
  *Check = ((( *Check ) >> 4 ) ^ (((( Value >> 4 ) ^ ( *Check )) &
    NibbleMask ) * CheckMagic ) & WordMask );
}

#if ANSI
  static PROC void WriteMemory( long int Start, long int Stop )
#else
  static PROC void WriteMemory( Start, Stop )
  long int Start;
  long int Stop;
#endif
{
  if( *HpAscCond ) {
    OutFile = freopen( OutFileName, "w+", OutFile );
    if( !OutFile )
      RunError( True, FileAccessError );
  }
  if( *HpHeadCond )
    if( *HpAscCond ) {
      if( fprintf( OutFile, "%s", AscHpHeadText ) <= 0 )
        RunError( True, FileWriteError );
    } else {
      unsigned char HpHeading[ BinHpHeadLength ];
      long int Size;

      Size = (( Stop - Start ) << 1 ) + 5;
      strcpy(( char * )HpHeading, BinHpHeadText );
      HpHeading[ BinHpHeadLength - 5 ] = 0x2c;
      HpHeading[ BinHpHeadLength - 4 ] = 0x2a;
      HpHeading[ BinHpHeadLength - 3 ] = ( unsigned char )( 0 | (( Size &
        0xfL ) << 4 ));
      HpHeading[ BinHpHeadLength - 2 ] = ( unsigned char )(( Size &
        0xff0L ) >> 4 );
      HpHeading[ BinHpHeadLength - 1 ] = ( unsigned char )(( Size &
        0xff000L ) >> 12 );
      if( fwrite(( char * )HpHeading, 1, BinHpHeadLength, OutFile ) !=
        BinHpHeadLength ) 
          RunError( True, FileWriteError );
    }
  if( *HpAscCond ) {
    SymbolString HexText;
    long int Count;
    long int Check;

    Check = 0L;
    if( *HpHeadCond ) {
      long int Size;

      Size = (( Stop - Start ) << 1 ) + 5;
      if( fprintf( OutFile, "\"" ) <= 0 )
        RunError( True, FileWriteError );
      WriteCheckByte( &Check, 0x2c );
      WriteCheckByte( &Check, 0x2a );
      WriteCheckByte( &Check, ( unsigned char )( 0 | (( Size & 0xfL ) << 4 )));
      WriteCheckByte( &Check, ( unsigned char )(( Size & 0xff0L ) >> 4 ));
      WriteCheckByte( &Check, ( unsigned char )(( Size & 0xff000L ) >> 12 ));
    }
    for( Count = Start; Count < Stop; Count++ ) {
      WriteCheckByte( &Check, Memory[ Count - StartAddress ]);
      if( !(( Count - Start + 6 ) % 32 ) && ( *HpHeadCond ))
        if( fprintf( OutFile, "\n" ) <= 0 )
          RunError( True, FileWriteError );
    }
    if( *HpHeadCond ) {
      for( Count = 0; Count < 4; Count++ ) 
        if( fprintf( OutFile, "%s", NumberString( HexText,
          ( Check >> ( 4 * Count )) & NibbleMask, 16, 1 )) <= 0 )
            RunError( True, FileWriteError );
      if( fprintf( OutFile, "\"" ) <= 0 )
        RunError( True, FileWriteError );
    }
  } else {
    unsigned int Size;

    if(( Stop - Start ) > 0L ) {
      Size = ( unsigned int )( Stop - Start );
      if( fwrite(( char * )&Memory[ Start - StartAddress ], 1, Size,
        OutFile ) != Size )
          RunError( True, FileWriteError );
    }
  }
}

#if ANSI
  PROC int main( int argc, char *argv[] )
#else
  PROC int main( argc, argv )
  int argc;
  char *argv[];
#endif
{
  InstPointer Inst; 
  unsigned int Count;
  
  if( fprintf( stderr, "%s\n\n", CopyRight ) <= 0 )
    RunError( True, FileWriteError );
  strcpy( Separator, "---------------------------------------" );
  strcat( Separator, "---------------------------------------" );
  for( Count = 0x0; Count < 0x100; Count++ )
    Operators[ Count ] = False;
  Operators[ StartChar ] = True;
  Operators[ StopChar ] = True;
  Operators[ PlusChar ] = True;
  Operators[ MinusChar ] = True;
  Operators[ NotChar ] = True;
  Operators[ PowerChar ] = True;
  Operators[ ShlChar ] = True;
  Operators[ ShrChar ] = True;
  Operators[ MulChar ] = True;
  Operators[ FracChar ] = True;
  Operators[ AndChar ] = True;
  Operators[ OrChar ] = True;
  Operators[ XorChar ] = True;
  Operators[ DivChar ] = True;
  Operators[ ModChar ] = True;
  if( OpenFiles( argc, argv )) {
    *StackPoint = True;
    StoreSymbolList( TokenText, 0, LastToken - 1, &Directives );
    StoreSymbolList( RegisterText, 0, LastReg - 1, &Registers );
    DefineSymbol( Super10Name, Super10Default, &Conditions, &NullLocation );
    Super10Cond = &( CurrentSymbol->Value );
    DefineSymbol( Chip48Name, Chip48Default, &Conditions, &NullLocation );
    Chip48Cond = &( CurrentSymbol->Value );
    DefineSymbol( UsedYesName, UsedYesDefault, &Conditions, &NullLocation );
    UsedYesCond = &( CurrentSymbol->Value );
    DefineSymbol( AlignOnName, AlignOnDefault, &Conditions, &NullLocation );
    AlignOnCond = &( CurrentSymbol->Value );
    DefineSymbol( HpAscName, HpAscDefault, &Conditions, &NullLocation );
    HpAscCond = &( CurrentSymbol->Value );
    DefineSymbol( Super11Name, Super11Default, &Conditions, &NullLocation );
    Super11Cond = &( CurrentSymbol->Value );
    DefineSymbol( XrefOnName, XrefOnDefault, &Conditions, &NullLocation );
    XrefOnCond = &( CurrentSymbol->Value );
    DefineSymbol( Chip8Name, Chip8Default, &Conditions, &NullLocation );
    Chip8Cond = &( CurrentSymbol->Value );
    DefineSymbol( HpHeadName, HpHeadDefault, &Conditions, &NullLocation );
    HpHeadCond = &( CurrentSymbol->Value );
    DefineSymbol( UsedOnName, UsedOnDefault, &Conditions, &NullLocation );
    UsedOnCond = &( CurrentSymbol->Value );
    DefineSymbol( XrefYesName, XrefYesDefault, &Conditions, &NullLocation );
    XrefYesCond = &( CurrentSymbol->Value );
    CurrentSymbol = NULL;
    Inst = NULL;
    DecodeFile( InFileName, &Inst, Directives, &Symbols, &Conditions );
    if( fprintf( stderr, "Done reading\n\n" ) <= 0 )
      RunError( True, FileWriteError );
    if( fprintf( ListFile, "Done reading\n\n" ) <= 0 )
      RunError( True, FileWriteError );
    ResolveEquations( Symbols );
    EncodeMemory( Instructions, Registers, Symbols, Conditions );
    WriteMemory( StartAddress, FinalAddress );
    if( OutFile )
      fclose( OutFile );
    OutFile = NULL;
    if( ListFile )
      if( ListFile != stdout )
        fclose( ListFile );
    ListFile = NULL;
    ReleaseSpace( &Space );
  }
  return( SuccessExitCode );
}
