OpenCores
URL https://opencores.org/ocsvn/thor/thor/trunk

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [software/] [AS64/] [source/] [main.cpp] - Diff between revs 54 and 55

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 54 Rev 55
// ============================================================================
// ============================================================================
//        __
//        __
//   \\__/ o\    (C) 2016-2018  Robert Finch, Waterloo
//   \\__/ o\    (C) 2016-2018  Robert Finch, Waterloo
//    \  __ /    All rights reserved.
//    \  __ /    All rights reserved.
//     \/_//     robfinch<remove>@finitron.ca
//     \/_//     robfinch<remove>@finitron.ca
//       ||
//       ||
//
//
// AS64 - Assembler
// AS64 - Assembler
//  - 64 bit CPU
//  - 64 bit CPU
//
//
// This source file is free software: you can redistribute it and/or modify 
// This source file is free software: you can redistribute it and/or modify 
// it under the terms of the GNU Lesser General Public License as published 
// it under the terms of the GNU Lesser General Public License as published 
// by the Free Software Foundation, either version 3 of the License, or     
// by the Free Software Foundation, either version 3 of the License, or     
// (at your option) any later version.                                      
// (at your option) any later version.                                      
//                                                                          
//                                                                          
// This source file is distributed in the hope that it will be useful,      
// This source file is distributed in the hope that it will be useful,      
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
// GNU General Public License for more details.                             
// GNU General Public License for more details.                             
//                                                                          
//                                                                          
// You should have received a copy of the GNU General Public License        
// You should have received a copy of the GNU General Public License        
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
//                                                                          
//                                                                          
// ============================================================================
// ============================================================================
//
//
#include "stdafx.h"
#include "stdafx.h"
 
 
#define MAX_PASS  6
#define MAX_PASS  6
 
 
FilenameStack fns;
FilenameStack fns;
 
 
int gCpu = 888;
int gCpu = 888;
int verbose = 1;
int verbose = 1;
int debug = 1;
int debug = 1;
int listing = 1;
int listing = 1;
int binary_out = 1;
int binary_out = 1;
int verilog_out = 1;
int verilog_out = 1;
int elf_out = 1;
int elf_out = 1;
int rel_out = 0;
int rel_out = 0;
int coe_out = 0;
int coe_out = 0;
int code_bits = 32;
int code_bits = 32;
int data_bits = 32;
int data_bits = 32;
int pass;
int pass;
int lineno;
int lineno;
char *inptr;
char *inptr;
char *stptr;
char *stptr;
char *pif1, *pif2;
char *pif1, *pif2;
int token;
int token;
int phasing_errors;
int phasing_errors;
int pe1, pe2, pe3;
int pe1, pe2, pe3;
int bGen = 0;
int bGen = 0;
bool bGenListing = false;
bool bGenListing = false;
char fSeg = 0;
char fSeg = 0;
int segment;
int segment;
int segprefix = -1;
int segprefix = -1;
int segmodel = 0;
int segmodel = 0;
int64_t program_address;
int64_t program_address;
int64_t code_address;
int64_t code_address;
int64_t data_address;
int64_t data_address;
int64_t bss_address;
int64_t bss_address;
int64_t start_address;
int64_t start_address;
FILE *ofp, *vfp;
FILE *ofp, *vfp;
std::ofstream mofs;
std::ofstream mofs;
 
 
int regno;
int regno;
char first_org = 1;
char first_org = 1;
char current_label[500];
char current_label[500];
 
 
std::string mname;
std::string mname;
char buf[10000];
char buf[10000];
int masterFileLength = 0;
int masterFileLength = 0;
char *masterFile;
char *masterFile;
char segmentFile[10000000];
char segmentFile[10000000];
int NumSections = 12;
int NumSections = 12;
clsElf64Section sections[12];
clsElf64Section sections[12];
NameTable nmTable;
NameTable nmTable;
char codebuf[10000000];
char codebuf[10000000];
char rodatabuf[10000000];
char rodatabuf[10000000];
char databuf[10000000];
char databuf[10000000];
char bssbuf[10000000];
char bssbuf[10000000];
char tlsbuf[10000000];
char tlsbuf[10000000];
uint8_t binfile[10000000];
uint8_t binfile[10000000];
uint64_t binfilex36[10000000];
uint64_t binfilex36[10000000];
int binndx;
int binndx;
int64_t binstart;
int64_t binstart;
int mfndx;
int mfndx;
int codendx;
int codendx;
int datandx;
int datandx;
int rodatandx;
int rodatandx;
int tlsndx;
int tlsndx;
int bssndx;
int bssndx;
SYM *lastsym;
SYM *lastsym;
int isInitializationData;
int isInitializationData;
float num_bytes;
float num_bytes;
int num_insns;
int num_insns;
int num_cinsns;
int num_cinsns;
HTBLE hTable[100000];
HTBLE hTable[100000];
int htblmax;
int htblmax;
int processOpt;
int processOpt;
int gCanCompress = 1;
int gCanCompress = 1;
int expandedBlock;
int expandedBlock;
int expand_flag;
int expand_flag;
int compress_flag;
int compress_flag;
int vebits = 128;
int vebits = 128;
void emitCode(int cd);
void emitCode(int cd);
void emitAlignedCode(int cd);
void emitAlignedCode(int cd);
void process_shifti(int oc,int fn);
void process_shifti(int oc,int fn);
void processFile(char *fname, int searchincl);
void processFile(char *fname, int searchincl);
void bump_address();
void bump_address();
extern void Table888_bump_address();
extern void Table888_bump_address();
extern void searchenv(char *filename, char *envname, char **pathname);
extern void searchenv(char *filename, char *envname, char **pathname);
extern void Table888mmu_processMaster();
extern void Table888mmu_processMaster();
extern void Friscv_processMaster();
extern void Friscv_processMaster();
extern void FISA64_processMaster();
extern void FISA64_processMaster();
extern void Thor_processMaster();
extern void Thor_processMaster();
extern void dsd6_processMaster();
extern void dsd6_processMaster();
extern void dsd7_processMaster();
extern void dsd7_processMaster();
extern void dsd9_processMaster();
extern void dsd9_processMaster();
extern void FT64_processMaster();
extern void FT64_processMaster();
extern void FT64x36_processMaster();
extern void FT64x36_processMaster();
extern void SymbolInit();
extern void SymbolInit();
extern void dsd9_VerilogOut(FILE *fp);
extern void dsd9_VerilogOut(FILE *fp);
 
 
Arg gArgs[12];
Arg gArgs[12];
int gArgCount;
int gArgCount;
Arglist gArglist;
Arglist gArglist;
 
 
FILE *mfp;      // master file pointer
FILE *mfp;      // master file pointer
 
 
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
 
 
void displayHelp()
void displayHelp()
{
{
     printf("a64 [options] file\r\n");
     printf("a64 [options] file\r\n");
     printf("    +v      = verbose output\r\n");
     printf("    +v      = verbose output\r\n");
     printf("    +r      = relocatable output\r\n");
     printf("    +r      = relocatable output\r\n");
     printf("    -s      = non-segmented\r\n");
     printf("    -s      = non-segmented\r\n");
     printf("    +g[n]   = cpu version 8=Table888, 9=Table888mmu V=RISCV 6=FISA64 T=Thor\r\n");
     printf("    +g[n]   = cpu version 8=Table888, 9=Table888mmu V=RISCV 6=FISA64 T=Thor\r\n");
     printf("                          D=DSD6 7=DSD7 A=DSD9 F=FT64 G=FT64x36\r\n");
     printf("                          D=DSD6 7=DSD7 A=DSD9 F=FT64 G=FT64x36\r\n");
     printf("    -o[bvlc] = suppress output file b=binary, v=verilog, l=listing, c=coe\r\n");
     printf("    -o[bvlc] = suppress output file b=binary, v=verilog, l=listing, c=coe\r\n");
}
}
 
 
int hcmp(const void *a1, const void *b1)
int hcmp(const void *a1, const void *b1)
{
{
    HTBLE *a = (HTBLE *)a1;
    HTBLE *a = (HTBLE *)a1;
    HTBLE *b = (HTBLE *)b1;
    HTBLE *b = (HTBLE *)b1;
    return (a->count < b->count) ? 1 : (a->count==b->count) ? 0 : -1;
    return (a->count < b->count) ? 1 : (a->count==b->count) ? 0 : -1;
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void DumphTable()
void DumphTable()
{
{
    int nn;
    int nn;
    HTBLE *pt;
    HTBLE *pt;
 
 
   pt = (HTBLE *)hTable;
   pt = (HTBLE *)hTable;
 
 
   // Sort the table (already sorted)
   // Sort the table (already sorted)
//   qsort(pt, htblmax, sizeof(HTBLE), hcmp);
//   qsort(pt, htblmax, sizeof(HTBLE), hcmp);
 
 
   if (gCpu=='F') {
   if (gCpu=='F') {
    fprintf(ofp, "%d compressable instructions\n", htblmax);
    fprintf(ofp, "%d compressable instructions\n", htblmax);
    fprintf(ofp, "The top 256 are:\n", htblmax);
    fprintf(ofp, "The top 256 are:\n", htblmax);
    fprintf(ofp, "Comp  Opcode  Count\n");
    fprintf(ofp, "Comp  Opcode  Count\n");
    for (nn = 0; nn < htblmax && nn < 256; nn++) {
    for (nn = 0; nn < htblmax && nn < 256; nn++) {
        fprintf(ofp, " %03X %08X %d\n", nn, hTable[nn].opcode, hTable[nn].count);
        fprintf(ofp, " %03X %012I64X %d\n", nn, hTable[nn].opcode, hTable[nn].count);
    }
    }
        return;
        return;
   }
   }
    fprintf(ofp, "%d compressable instructions\n", htblmax);
    fprintf(ofp, "%d compressable instructions\n", htblmax);
    fprintf(ofp, "The top 1024 are:\n", htblmax);
    fprintf(ofp, "The top 1024 are:\n", htblmax);
    fprintf(ofp, "Comp  Opcode  Count\n");
    fprintf(ofp, "Comp  Opcode  Count\n");
    for (nn = 0; nn < htblmax && nn < 1024; nn++) {
    for (nn = 0; nn < htblmax && nn < 1024; nn++) {
        fprintf(ofp, " %03X %08X %d\n", nn, hTable[nn].opcode, hTable[nn].count);
        fprintf(ofp, " %03X %08X %d\n", nn, hTable[nn].opcode, hTable[nn].count);
    }
    }
}
}
 
 
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
 
 
int processOptions(int argc, char **argv)
int processOptions(int argc, char **argv)
{
{
    int nn, mm;
    int nn, mm;
 
 
    segmodel = 0;
    segmodel = 0;
    nn = 1;
    nn = 1;
    do {
    do {
        if (nn >= argc-1)
        if (nn >= argc-1)
           break;
           break;
        if (argv[nn][0]=='-') {
        if (argv[nn][0]=='-') {
           if (argv[nn][1]=='o') {
           if (argv[nn][1]=='o') {
               mm = 2;
               mm = 2;
               while(argv[nn][mm] && !isspace(argv[nn][mm])) {
               while(argv[nn][mm] && !isspace(argv[nn][mm])) {
                   if (argv[nn][mm]=='b')
                   if (argv[nn][mm]=='b')
                       binary_out = 0;
                       binary_out = 0;
                   else if (argv[nn][mm]=='l')
                   else if (argv[nn][mm]=='l')
                       listing = 0;
                       listing = 0;
                   else if (argv[nn][mm]=='v')
                   else if (argv[nn][mm]=='v')
                       verilog_out = 0;
                       verilog_out = 0;
                   else if (argv[nn][mm]=='e')
                   else if (argv[nn][mm]=='e')
                       elf_out = 0;
                       elf_out = 0;
               }
               }
           }
           }
           if (argv[nn][1]=='s')
           if (argv[nn][1]=='s')
               fSeg = 0;
               fSeg = 0;
           nn++;
           nn++;
        }
        }
        else if (argv[nn][0]=='+') {
        else if (argv[nn][0]=='+') {
           mm = 2;
           mm = 2;
           if (argv[nn][1]=='r') {
           if (argv[nn][1]=='r') {
               rel_out = 1;
               rel_out = 1;
           }
           }
           if (argv[nn][1]=='s')
           if (argv[nn][1]=='s')
               fSeg = 1;
               fSeg = 1;
           if (argv[nn][1]=='g') {
           if (argv[nn][1]=='g') {
              if (argv[nn][2]=='9') {
              if (argv[nn][2]=='9') {
                 gCpu=889;
                 gCpu=889;
                 fSeg = 1;
                 fSeg = 1;
              }
              }
              if (argv[nn][2]=='V') {
              if (argv[nn][2]=='V') {
                 gCpu = 5;
                 gCpu = 5;
              }
              }
              if (argv[nn][2]=='6') {
              if (argv[nn][2]=='6') {
                 gCpu = 64;
                 gCpu = 64;
              }
              }
              if (argv[nn][2]=='7') {
              if (argv[nn][2]=='7') {
                 gCpu = 7;
                 gCpu = 7;
                                 if (argv[nn][3]=='c')
                                 if (argv[nn][3]=='c')
                                         gCanCompress = 1;
                                         gCanCompress = 1;
                                 else
                                 else
                                         gCanCompress = 0;
                                         gCanCompress = 0;
              }
              }
              if (argv[nn][2]=='T') {
              if (argv[nn][2]=='T') {
                 gCpu = 4;
                 gCpu = 4;
                 if (argv[nn][3]=='2') {
                 if (argv[nn][3]=='2') {
                   segmodel = 2;
                   segmodel = 2;
                 }
                 }
              }
              }
              if (argv[nn][2]=='D') {
              if (argv[nn][2]=='D') {
                 gCpu = 14;
                 gCpu = 14;
              }
              }
              if (argv[nn][2]=='A') {
              if (argv[nn][2]=='A') {
                 gCpu = 'A';
                 gCpu = 'A';
                                 if (argv[nn][3]=='c')
                                 if (argv[nn][3]=='c')
                                         gCanCompress = 1;
                                         gCanCompress = 1;
                                 else
                                 else
                                         gCanCompress = 0;
                                         gCanCompress = 0;
              }
              }
              if (argv[nn][2]=='F') {
              if (argv[nn][2]=='F') {
                 gCpu = 'F';
                 gCpu = 'F';
                                 mm = 3;
                                 mm = 3;
                                 gCanCompress = 0;
                                 gCanCompress = 0;
                                 while(argv[nn][mm]) {
                                 while(argv[nn][mm]) {
                                         if (argv[nn][mm]=='3')
                                         if (argv[nn][mm]=='3')
                                                 gCpu = 'H';
                                                 gCpu = 'H';
                                         else if (argv[nn][mm]=='c')
                                         else if (argv[nn][mm]=='c')
                                                 gCanCompress = 1;
                                                 gCanCompress = 1;
                                         else if (argv[nn][mm]=='n')
                                         else if (argv[nn][mm]=='n')
                                                 vebits = 64;
                                                 vebits = 64;
                                         mm++;
                                         mm++;
                                 }
                                 }
              }
              }
              if (argv[nn][2]=='G') {
              if (argv[nn][2]=='G') {
                 gCpu = 'G';
                 gCpu = 'G';
                                 if (argv[nn][3]=='n')
                                 if (argv[nn][3]=='n')
                                         vebits = 64;
                                         vebits = 64;
                                 else if (argv[nn][3]=='c')
                                 else if (argv[nn][3]=='c')
                                         gCanCompress = 1;
                                         gCanCompress = 1;
                                 else
                                 else
                                         gCanCompress = 0;
                                         gCanCompress = 0;
              }
              }
           }
           }
           nn++;
           nn++;
        }
        }
        else break;
        else break;
    } while (1);
    } while (1);
    return nn;
    return nn;
}
}
 
 
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// Emit a byte, for DSD7 a byte is 16 bits.
// Emit a byte, for DSD7 a byte is 16 bits.
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
 
 
void emitByte(int64_t cd)
void emitByte(int64_t cd)
{
{
     if (segment < 5) {
     if (segment < 5) {
                 if (gCpu==7)
                 if (gCpu==7)
                        sections[segment].AddChar(cd);
                        sections[segment].AddChar(cd);
                 else
                 else
                        sections[segment].AddByte(cd);
                        sections[segment].AddByte(cd);
         }
         }
    if (segment == codeseg || segment == rodataseg) {
    if (segment == codeseg || segment == rodataseg) {
                if (gCpu==7) {
                if (gCpu==7) {
                        binfile[binndx] = cd & 255LL;
                        binfile[binndx] = cd & 255LL;
                        binndx++;
                        binndx++;
                        binfile[binndx] = (cd >> 8) & 255LL;
                        binfile[binndx] = (cd >> 8) & 255LL;
                        binndx++;
                        binndx++;
                }
                }
                else {
                else {
                        binfile[binndx] = cd & 255LL;
                        binfile[binndx] = cd & 255LL;
                        binndx++;
                        binndx++;
                }
                }
    }
    }
    if (segment==bssseg) {
    if (segment==bssseg) {
       bss_address++;
       bss_address++;
    }
    }
    else if (segment==dataseg)
    else if (segment==dataseg)
         data_address++;
         data_address++;
    else
    else
        code_address++;
        code_address++;
}
}
 
 
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
 
 
void emitNybble(int64_t cd)
void emitNybble(int64_t cd)
{
{
        static int64_t ln;
        static int64_t ln;
        static bool evn = false;
        static bool evn = false;
        static int byt = 0;
        static int byt = 0;
 
 
        if (cd > 15)
        if (cd > 15)
                evn = cd >> 4;
                evn = cd >> 4;
        if (!evn) {
        if (!evn) {
                emitByte((cd << 4) | ln);
                emitByte((cd << 4) | ln);
        }
        }
        else
        else
                ln = cd;
                ln = cd;
        evn = !evn;
        evn = !evn;
}
}
 
 
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
 
 
void emitChar(int64_t cd)
void emitChar(int64_t cd)
{
{
     emitByte(cd & 255LL);
     emitByte(cd & 255LL);
     emitByte((cd >> 8) & 255LL);
     emitByte((cd >> 8) & 255LL);
}
}
 
 
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
 
 
void emitHalf(int64_t cd)
void emitHalf(int64_t cd)
{
{
        if (gCpu==7) {
        if (gCpu==7) {
                emitByte(cd & 65535LL);
                emitByte(cd & 65535LL);
                //emitByte((cd >> 16) & 65535LL);
                //emitByte((cd >> 16) & 65535LL);
        }
        }
  else if (gCpu==5) {
  else if (gCpu==5) {
     emitByte(cd & 255LL);
     emitByte(cd & 255LL);
     emitByte((cd >> 8) & 255LL);
     emitByte((cd >> 8) & 255LL);
  }
  }
  else {
  else {
     emitChar(cd & 65535LL);
     emitChar(cd & 65535LL);
     emitChar((cd >> 16) & 65535LL);
     emitChar((cd >> 16) & 65535LL);
  }
  }
}
}
 
 
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
 
 
void emitWord(int64_t cd)
void emitWord(int64_t cd)
{
{
  if (gCpu==5 || gCpu==7) {
  if (gCpu==5 || gCpu==7) {
     emitHalf(cd & 0xFFFFLL);
     emitHalf(cd & 0xFFFFLL);
     emitHalf((cd >> 16) & 0xFFFFLL);
     emitHalf((cd >> 16) & 0xFFFFLL);
  }
  }
  else {
  else {
     emitHalf(cd & 0xFFFFFFFFLL);
     emitHalf(cd & 0xFFFFFFFFLL);
     emitHalf((cd >> 32) & 0xFFFFFFFFLL);
     emitHalf((cd >> 32) & 0xFFFFFFFFLL);
  }
  }
}
}
 
 
void emitDecibyte(Int128 cd)
void emitDecibyte(Int128 cd)
{
{
        emitWord(cd.low);
        emitWord(cd.low);
        emitChar(cd.high & 0xFFFFLL);
        emitChar(cd.high & 0xFFFFLL);
}
}
 
 
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
 
 
void emitCode(int cd)
void emitCode(int cd)
{
{
     emitByte(cd);
     emitByte(cd);
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Process a public declaration.
// Process a public declaration.
//     public code myfn
//     public code myfn
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void process_public()
void process_public()
{
{
    SYM *sym;
    SYM *sym;
    int64_t ca;
    int64_t ca;
        int div = 1;
        int div = 1;
 
 
        if (gCpu==7)
        if (gCpu==7)
                div = 2;
                div = 2;
 
 
    NextToken();
    NextToken();
    if (token==tk_code) {
    if (token==tk_code) {
        segment = codeseg;
        segment = codeseg;
    }
    }
    else if (token==tk_rodata) {
    else if (token==tk_rodata) {
         segment = rodataseg;
         segment = rodataseg;
    }
    }
    else if (token==tk_data) {
    else if (token==tk_data) {
         if (isInitializationData)
         if (isInitializationData)
             segment = rodataseg;
             segment = rodataseg;
         else
         else
             segment = dataseg;
             segment = dataseg;
    }
    }
    else if (token==tk_bss) {
    else if (token==tk_bss) {
         segment = bssseg;
         segment = bssseg;
    }
    }
    else
    else
        prevToken();
        prevToken();
    bump_address();
    bump_address();
//    if (segment==bssseg)
//    if (segment==bssseg)
//        ca = bss_address;
//        ca = bss_address;
//    else
//    else
//        ca = code_address;
//        ca = code_address;
    switch(segment) {
    switch(segment) {
    case codeseg:
    case codeseg:
         ca = code_address/div;
         ca = code_address/div;
         ca = sections[0].address/div;
         ca = sections[0].address/div;
         break;
         break;
    case rodataseg:
    case rodataseg:
         ca = sections[1].address/div;
         ca = sections[1].address/div;
         break;
         break;
    case dataseg:
    case dataseg:
         ca = sections[2].address/div;
         ca = sections[2].address/div;
         break;
         break;
    case bssseg:
    case bssseg:
         ca = sections[3].address/div;
         ca = sections[3].address/div;
         break;
         break;
    case tlsseg:
    case tlsseg:
         ca = sections[4].address/div;
         ca = sections[4].address/div;
         break;
         break;
    }
    }
    NextToken();
    NextToken();
    if (token != tk_id) {
    if (token != tk_id) {
        printf("Identifier expected. Token %d\r\n", token);
        printf("Identifier expected. Token %d\r\n", token);
        printf("Line:%.60s", stptr);
        printf("Line:%.60s", stptr);
    }
    }
    else {
    else {
         if (isInitializationData) {
         if (isInitializationData) {
             ScanToEOL();
             ScanToEOL();
             inptr++;
             inptr++;
             return;
             return;
         }
         }
        sym = find_symbol(lastid);
        sym = find_symbol(lastid);
        if (pass == 4) {
        if (pass == 4) {
            if (sym) {
            if (sym) {
                if (sym->defined)
                if (sym->defined)
                    printf("Symbol (%s) already defined.\r\n", lastid);
                    printf("Symbol (%s) already defined.\r\n", lastid);
            }
            }
            else {
            else {
                sym = new_symbol(lastid);
                sym = new_symbol(lastid);
            }
            }
            if (sym) {
            if (sym) {
                sym->defined = 1;
                sym->defined = 1;
                                if (gCpu=='G')
                                if (gCpu=='G')
                                        sym->value.low = ca & -4LL;
                                        sym->value.low = ca & -4LL;
                                else
                                else
                                        sym->value.low = ca;
                                        sym->value.low = ca;
                                sym->value.high = 0;
                                sym->value.high = 0;
                sym->segment = segment;
                sym->segment = segment;
                sym->scope = 'P';
                sym->scope = 'P';
            }
            }
        }
        }
        else if (pass > 4) {
        else if (pass > 4) {
                        if (!sym)
                        if (!sym)
                            printf("Symbol (%s) not defined.\r\n", lastid);
                            printf("Symbol (%s) not defined.\r\n", lastid);
                        else {
                        else {
                    if (sym->value.low != ca) {
                    if (sym->value.low != ca) {
                        phasing_errors++;
                        phasing_errors++;
                        sym->phaserr = '*';
                        sym->phaserr = '*';
                         //if (bGen) printf("%s=%06I64x ca=%06I64x\r\n", nmTable.GetName(sym->name),  sym->value, code_address);
                         //if (bGen) printf("%s=%06I64x ca=%06I64x\r\n", nmTable.GetName(sym->name),  sym->value, code_address);
                    }
                    }
                    else
                    else
                         sym->phaserr = ' ';
                         sym->phaserr = ' ';
                                if (gCpu=='G')
                                if (gCpu=='G')
                                        sym->value.low = ca & -4LL;
                                        sym->value.low = ca & -4LL;
                                else
                                else
                                        sym->value.low = ca;
                                        sym->value.low = ca;
                                sym->value.high = 0;
                                sym->value.high = 0;
                }
                }
        }
        }
        strcpy_s(current_label, sizeof(current_label), lastid);
        strcpy_s(current_label, sizeof(current_label), lastid);
    }
    }
    ScanToEOL();
    ScanToEOL();
    inptr++;
    inptr++;
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// extern somefn
// extern somefn
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void process_extern()
void process_extern()
{
{
    SYM *sym;
    SYM *sym;
 
 
//    printf("<process_extern>");
//    printf("<process_extern>");
    NextToken();
    NextToken();
    if (token != tk_id)
    if (token != tk_id)
        printf("Expecting an identifier.\r\n");
        printf("Expecting an identifier.\r\n");
    else {
    else {
        sym = find_symbol(lastid);
        sym = find_symbol(lastid);
        if (pass == 4) {
        if (pass == 4) {
            if (sym) {
            if (sym) {
 
 
            }
            }
            else {
            else {
                sym = new_symbol(lastid);
                sym = new_symbol(lastid);
            }
            }
            if (sym) {
            if (sym) {
                sym->defined = 0;
                sym->defined = 0;
                sym->value.low = 0;
                sym->value.low = 0;
                                sym->value.high = 0;
                                sym->value.high = 0;
                sym->segment = segment;
                sym->segment = segment;
                sym->scope = 'P';
                sym->scope = 'P';
                sym->isExtern = 1;
                sym->isExtern = 1;
            }
            }
        }
        }
        else if (pass > 4) {
        else if (pass > 4) {
        }
        }
        NextToken();
        NextToken();
        if (token==':') {
        if (token==':') {
           NextToken();
           NextToken();
           if (sym)
           if (sym)
               sym->bits = (int)expr();
               sym->bits = (int)expr();
        }
        }
        else {
        else {
//    printf("J:sym=%p lastid=%s", sym, lastid);
//    printf("J:sym=%p lastid=%s", sym, lastid);
           prevToken();
           prevToken();
            if (sym)
            if (sym)
               sym->bits = 32;
               sym->bits = 32;
        }
        }
    }
    }
    ScanToEOL();
    ScanToEOL();
    inptr++;
    inptr++;
//    printf("</process_extern>\r\n");
//    printf("</process_extern>\r\n");
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// .org $23E200
// .org $23E200
// .org is ignored for relocatable files.
// .org is ignored for relocatable files.
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void process_org()
void process_org()
{
{
    int64_t new_address;
    int64_t new_address;
        int mul = 1;
        int mul = 1;
 
 
        if (gCpu==7)
        if (gCpu==7)
                mul = 2;
                mul = 2;
    NextToken();
    NextToken();
    new_address = expr();
    new_address = expr();
    if (!rel_out) {
    if (!rel_out) {
        if (segment==dataseg) {
        if (segment==dataseg) {
            data_address = new_address*mul;
            data_address = new_address*mul;
            sections[segment].address = new_address*mul;
            sections[segment].address = new_address*mul;
        }
        }
        else if (segment==bssseg || segment==tlsseg) {
        else if (segment==bssseg || segment==tlsseg) {
            bss_address = new_address*mul;
            bss_address = new_address*mul;
            sections[segment].address = new_address*mul;
            sections[segment].address = new_address*mul;
        }
        }
        else {
        else {
            if (first_org && segment==codeseg) {
            if (first_org && segment==codeseg) {
                                                        program_address = new_address;
                                                        program_address = new_address;
              code_address = new_address;
              code_address = new_address;
              start_address = new_address*mul;
              start_address = new_address*mul;
              sections[0].address = new_address*mul;
              sections[0].address = new_address*mul;
              first_org = 0;
              first_org = 0;
            }
            }
            else {
            else {
                                                        // Ignore the org directive in initialized data area of rodata
                                                        // Ignore the org directive in initialized data area of rodata
                                                        if (!isInitializationData)
                                                        if (!isInitializationData)
                                                                while(sections[0].address < new_address*mul)
                                                                while(sections[0].address < new_address*mul)
                                                                        emitByte(0x00);
                                                                        emitByte(0x00);
            }
            }
        }
        }
    }
    }
    ScanToEOL();
    ScanToEOL();
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void process_align()
void process_align()
{
{
        int64_t v;
        int64_t v;
 
 
        NextToken();
        NextToken();
        if (token == tk_code && gCpu=='F')
        if (token == tk_code && gCpu=='F')
                v = 5;
                v = 5;
        else
        else
                v = expr();
                v = expr();
        if (v == 0) {
        if (v == 0) {
                printf("Bad align directive. (%d)\r\n", lineno);
                printf("Bad align directive. (%d)\r\n", lineno);
                return;
                return;
        }
        }
    if (segment == codeseg || segment == rodataseg || segment == dataseg || segment==bssseg || segment==tlsseg) {
    if (segment == codeseg || segment == rodataseg || segment == dataseg || segment==bssseg || segment==tlsseg) {
        while (sections[segment].address % v)
        while (sections[segment].address % v)
            emitByte(0x00);
            emitByte(0x00);
    }
    }
//    if (segment==bssseg) {
//    if (segment==bssseg) {
//        while (bss_address % v)
//        while (bss_address % v)
//            emitByte(0x00);
//            emitByte(0x00);
//    }
//    }
//    else {
//    else {
//        while (code_address % v)
//        while (code_address % v)
//            emitByte(0x00);
//            emitByte(0x00);
//    }
//    }
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
//      hint #1
//      hint #1
//
//
// Process a compiler hint. Normally these instructions don't make it through
// Process a compiler hint. Normally these instructions don't make it through
// the compile stage, but in case one does... It is just ignored.
// the compile stage, but in case one does... It is just ignored.
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void process_hint()
void process_hint()
{
{
    int64_t v;
    int64_t v;
 
 
    NextToken();
    NextToken();
    v = expr();
    v = expr();
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// code 0x8000 to 0xFFFF
// code 0x8000 to 0xFFFF
// code 24 bits
// code 24 bits
// code
// code
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void process_code()
void process_code()
{
{
    int64_t st, nd;
    int64_t st, nd;
 
 
    segment = codeseg;
    segment = codeseg;
    NextToken();
    NextToken();
    if (token==tk_eol) {
    if (token==tk_eol) {
        prevToken();
        prevToken();
        return;
        return;
    }
    }
    st = expr();
    st = expr();
    if (token==tk_bits) {
    if (token==tk_bits) {
        code_bits = (int)st;
        code_bits = (int)st;
        return;
        return;
    }
    }
    if (token==tk_to) {
    if (token==tk_to) {
        NextToken();
        NextToken();
        nd = expr();
        nd = expr();
        code_bits = (int)log((double)nd+1)/log(2.0);    // +1 to round up a little bit
        code_bits = (int)log((double)nd+1)/log(2.0);    // +1 to round up a little bit
    }
    }
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// data 0x8000 to 0xFFFF
// data 0x8000 to 0xFFFF
// data 24 bits
// data 24 bits
// data
// data
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void process_data(int seg)
void process_data(int seg)
{
{
    int64_t st, nd;
    int64_t st, nd;
 
 
    segment = seg;
    segment = seg;
    NextToken();
    NextToken();
    if (token==tk_eol) {
    if (token==tk_eol) {
        prevToken();
        prevToken();
        return;
        return;
    }
    }
    st = expr();
    st = expr();
    if (token==tk_bits) {
    if (token==tk_bits) {
        data_bits = (int)st;
        data_bits = (int)st;
        return;
        return;
    }
    }
    if (token==tk_to) {
    if (token==tk_to) {
        NextToken();
        NextToken();
        nd = expr();
        nd = expr();
        data_bits = (int)log((double)nd+1)/log((double)2.0);    // +1 to round up a little bit
        data_bits = (int)log((double)nd+1)/log((double)2.0);    // +1 to round up a little bit
    }
    }
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void process_db()
void process_db()
{
{
    int64_t val;
    int64_t val;
 
 
    SkipSpaces();
    SkipSpaces();
    //NextToken();
    //NextToken();
    while(token!=tk_eol) {
    while(token!=tk_eol) {
        SkipSpaces();
        SkipSpaces();
        if (*inptr=='\n') break;
        if (*inptr=='\n') break;
        if (*inptr=='"') {
        if (*inptr=='"') {
            inptr++;
            inptr++;
            while (*inptr!='"') {
            while (*inptr!='"') {
                if (*inptr=='\\') {
                if (*inptr=='\\') {
                    inptr++;
                    inptr++;
                    switch(*inptr) {
                    switch(*inptr) {
                    case '\\': emitByte('\\'); inptr++; break;
                    case '\\': emitByte('\\'); inptr++; break;
                    case 'r': emitByte(0x0D); inptr++; break;
                    case 'r': emitByte(0x0D); inptr++; break;
                    case 'n': emitByte(0x0A); inptr++; break;
                    case 'n': emitByte(0x0A); inptr++; break;
                    case 'b': emitByte('\b'); inptr++; break;
                    case 'b': emitByte('\b'); inptr++; break;
                    case '"': emitByte('"'); inptr++; break;
                    case '"': emitByte('"'); inptr++; break;
                    default: inptr++; break;
                    default: inptr++; break;
                    }
                    }
                }
                }
                else {
                else {
                    emitByte(*inptr);
                    emitByte(*inptr);
                    inptr++;
                    inptr++;
                }
                }
            }
            }
            inptr++;
            inptr++;
        }
        }
/*
/*
        else if (*inptr=='\'') {
        else if (*inptr=='\'') {
            inptr++;
            inptr++;
            emitByte(*inptr);
            emitByte(*inptr);
            inptr++;
            inptr++;
            if (*inptr!='\'') {
            if (*inptr!='\'') {
                printf("Missing ' in character constant.\r\n");
                printf("Missing ' in character constant.\r\n");
            }
            }
        }
        }
*/
*/
        else {
        else {
            NextToken();
            NextToken();
            val = expr();
            val = expr();
            emitByte(val & 255);
            emitByte(val & 255);
            prevToken();
            prevToken();
        }
        }
        SkipSpaces();
        SkipSpaces();
        if (*inptr!=',')
        if (*inptr!=',')
            break;
            break;
        inptr++;
        inptr++;
    }
    }
    ScanToEOL();
    ScanToEOL();
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void process_dc()
void process_dc()
{
{
    int64_t val;
    int64_t val;
 
 
    SkipSpaces();
    SkipSpaces();
    while(token!=tk_eol) {
    while(token!=tk_eol) {
        SkipSpaces();
        SkipSpaces();
        if (*inptr=='"') {
        if (*inptr=='"') {
            inptr++;
            inptr++;
            while (*inptr!='"') {
            while (*inptr!='"') {
                if (*inptr=='\\') {
                if (*inptr=='\\') {
                    inptr++;
                    inptr++;
                    switch(*inptr) {
                    switch(*inptr) {
                    case '\\': emitChar('\\'); inptr++; break;
                    case '\\': emitChar('\\'); inptr++; break;
                    case 'r': emitChar(0x0D); inptr++; break;
                    case 'r': emitChar(0x0D); inptr++; break;
                    case 'n': emitChar(0x0A); inptr++; break;
                    case 'n': emitChar(0x0A); inptr++; break;
                    case 'b': emitChar('\b'); inptr++; break;
                    case 'b': emitChar('\b'); inptr++; break;
                    case '"': emitChar('"'); inptr++; break;
                    case '"': emitChar('"'); inptr++; break;
                    default: inptr++; break;
                    default: inptr++; break;
                    }
                    }
                }
                }
                else {
                else {
                    emitChar(*inptr);
                    emitChar(*inptr);
                    inptr++;
                    inptr++;
                }
                }
            }
            }
            inptr++;
            inptr++;
        }
        }
        else if (*inptr=='\'') {
        else if (*inptr=='\'') {
            inptr++;
            inptr++;
            emitChar(*inptr);
            emitChar(*inptr);
            inptr++;
            inptr++;
            if (*inptr!='\'') {
            if (*inptr!='\'') {
                printf("Missing ' in character constant.\r\n");
                printf("Missing ' in character constant.\r\n");
            }
            }
        }
        }
        else {
        else {
             NextToken();
             NextToken();
            val = expr();
            val = expr();
            emitChar(val);
            emitChar(val);
            prevToken();
            prevToken();
        }
        }
        SkipSpaces();
        SkipSpaces();
        if (*inptr!=',')
        if (*inptr!=',')
            break;
            break;
        inptr++;
        inptr++;
    }
    }
    ScanToEOL();
    ScanToEOL();
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void process_dh()
void process_dh()
{
{
    int64_t val;
    int64_t val;
 
 
    SkipSpaces();
    SkipSpaces();
    while(token!=tk_eol) {
    while(token!=tk_eol) {
        SkipSpaces();
        SkipSpaces();
        if (*inptr=='"') {
        if (*inptr=='"') {
            inptr++;
            inptr++;
            while (*inptr!='"') {
            while (*inptr!='"') {
                if (*inptr=='\\') {
                if (*inptr=='\\') {
                    inptr++;
                    inptr++;
                    switch(*inptr) {
                    switch(*inptr) {
                    case '\\': emitHalf('\\'); inptr++; break;
                    case '\\': emitHalf('\\'); inptr++; break;
                    case 'r': emitHalf(0x0D); inptr++; break;
                    case 'r': emitHalf(0x0D); inptr++; break;
                    case 'n': emitHalf(0x0A); inptr++; break;
                    case 'n': emitHalf(0x0A); inptr++; break;
                    case 'b': emitHalf('\b'); inptr++; break;
                    case 'b': emitHalf('\b'); inptr++; break;
                    case '"': emitHalf('"'); inptr++; break;
                    case '"': emitHalf('"'); inptr++; break;
                    default: inptr++; break;
                    default: inptr++; break;
                    }
                    }
                }
                }
                else {
                else {
                    emitHalf(*inptr);
                    emitHalf(*inptr);
                    inptr++;
                    inptr++;
                }
                }
            }
            }
            inptr++;
            inptr++;
        }
        }
        else if (*inptr=='\'') {
        else if (*inptr=='\'') {
            inptr++;
            inptr++;
            emitHalf(*inptr);
            emitHalf(*inptr);
            inptr++;
            inptr++;
            if (*inptr!='\'') {
            if (*inptr!='\'') {
                printf("Missing ' in character constant.\r\n");
                printf("Missing ' in character constant.\r\n");
            }
            }
        }
        }
        else {
        else {
             NextToken();
             NextToken();
            val = expr();
            val = expr();
            emitHalf(val);
            emitHalf(val);
            prevToken();
            prevToken();
        }
        }
        SkipSpaces();
        SkipSpaces();
        if (*inptr!=',')
        if (*inptr!=',')
            break;
            break;
        inptr++;
        inptr++;
    }
    }
    ScanToEOL();
    ScanToEOL();
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void process_dh_htbl()
void process_dh_htbl()
{
{
        int nn;
        int nn;
 
 
        if (gCpu=='F') {
        if (gCpu=='F') {
                emitHalf(htblmax > 1024 ? 1024 : htblmax);
                emitWord(htblmax > 1024 ? 1024 : htblmax);
                for (nn = 0; nn < htblmax && nn < 1024; nn++) {
                for (nn = 0; nn < htblmax && nn < 1024; nn++) {
                        emitHalf(hTable[nn].opcode);
                        emitWord(hTable[nn].opcode);
                }
                }
                return;
                return;
        }
        }
        else if (gCpu==7)
        else if (gCpu==7)
                emitByte(htblmax > 1024 ? 1024 : htblmax);
                emitByte(htblmax > 1024 ? 1024 : htblmax);
        else
        else
                emitHalf(htblmax > 1024 ? 1024 : htblmax);
                emitHalf(htblmax > 1024 ? 1024 : htblmax);
        for (nn = 0; nn < htblmax && nn < 1024; nn++) {
        for (nn = 0; nn < htblmax && nn < 1024; nn++) {
                emitWord(hTable[nn].opcode);
                emitWord(hTable[nn].opcode);
        }
        }
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void process_dw()
void process_dw()
{
{
    int64_t val;
    int64_t val;
 
 
    SkipSpaces();
    SkipSpaces();
    while(token!=tk_eol) {
    while(token!=tk_eol) {
        SkipSpaces();
        SkipSpaces();
        if (*inptr=='"') {
        if (*inptr=='"') {
            inptr++;
            inptr++;
            while (*inptr!='"') {
            while (*inptr!='"') {
                if (*inptr=='\\') {
                if (*inptr=='\\') {
                    inptr++;
                    inptr++;
                    switch(*inptr) {
                    switch(*inptr) {
                    case '\\': emitWord('\\'); inptr++; break;
                    case '\\': emitWord('\\'); inptr++; break;
                    case 'r': emitWord(0x0D); inptr++; break;
                    case 'r': emitWord(0x0D); inptr++; break;
                    case 'n': emitWord(0x0A); inptr++; break;
                    case 'n': emitWord(0x0A); inptr++; break;
                    case 'b': emitWord('\b'); inptr++; break;
                    case 'b': emitWord('\b'); inptr++; break;
                    case '"': emitWord('"'); inptr++; break;
                    case '"': emitWord('"'); inptr++; break;
                    default: inptr++; break;
                    default: inptr++; break;
                    }
                    }
                }
                }
                else {
                else {
                    emitWord(*inptr);
                    emitWord(*inptr);
                    inptr++;
                    inptr++;
                }
                }
            }
            }
            inptr++;
            inptr++;
        }
        }
        else if (*inptr=='\'') {
        else if (*inptr=='\'') {
            inptr++;
            inptr++;
            emitWord(*inptr);
            emitWord(*inptr);
            inptr++;
            inptr++;
            if (*inptr!='\'') {
            if (*inptr!='\'') {
                printf("Missing ' in character constant.\r\n");
                printf("Missing ' in character constant.\r\n");
            }
            }
        }
        }
        else {
        else {
             NextToken();
             NextToken();
            val = expr();
            val = expr();
    // A pointer to an object might be emitted as a data word.
    // A pointer to an object might be emitted as a data word.
    if (bGen && lastsym)
    if (bGen && lastsym)
    if( lastsym->segment < 5)
    if( lastsym->segment < 5)
    sections[segment+7].AddRel(sections[segment].index,((int64_t)(lastsym->ord+1) << 32) | 6 | (lastsym->isExtern ? 128 : 0));
    sections[segment+7].AddRel(sections[segment].index,((int64_t)(lastsym->ord+1) << 32) | 6 | (lastsym->isExtern ? 128 : 0));
            emitWord(val);
            emitWord(val);
            prevToken();
            prevToken();
        }
        }
        SkipSpaces();
        SkipSpaces();
        if (*inptr!=',')
        if (*inptr!=',')
            break;
            break;
        inptr++;
        inptr++;
    }
    }
    ScanToEOL();
    ScanToEOL();
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void process_dd()
void process_dd()
{
{
    Int128 val;
    Int128 val;
 
 
    SkipSpaces();
    SkipSpaces();
    while(token!=tk_eol) {
    while(token!=tk_eol) {
        SkipSpaces();
        SkipSpaces();
        if (*inptr=='"') {
        if (*inptr=='"') {
            inptr++;
            inptr++;
            while (*inptr!='"') {
            while (*inptr!='"') {
                if (*inptr=='\\') {
                if (*inptr=='\\') {
                    inptr++;
                    inptr++;
                    switch(*inptr) {
                    switch(*inptr) {
                    case '\\': emitWord('\\'); emitChar(0); inptr++; break;
                    case '\\': emitWord('\\'); emitChar(0); inptr++; break;
                    case 'r': emitWord(0x0D); emitChar(0); inptr++; break;
                    case 'r': emitWord(0x0D); emitChar(0); inptr++; break;
                    case 'n': emitWord(0x0A); emitChar(0); inptr++; break;
                    case 'n': emitWord(0x0A); emitChar(0); inptr++; break;
                    case 'b': emitWord('\b'); emitChar(0); inptr++; break;
                    case 'b': emitWord('\b'); emitChar(0); inptr++; break;
                    case '"': emitWord('"'); emitChar(0); inptr++; break;
                    case '"': emitWord('"'); emitChar(0); inptr++; break;
                    default: inptr++; break;
                    default: inptr++; break;
                    }
                    }
                }
                }
                else {
                else {
                    emitWord(*inptr);
                    emitWord(*inptr);
                                        emitChar(0);
                                        emitChar(0);
                    inptr++;
                    inptr++;
                }
                }
            }
            }
            inptr++;
            inptr++;
        }
        }
        else if (*inptr=='\'') {
        else if (*inptr=='\'') {
            inptr++;
            inptr++;
            emitWord(*inptr);
            emitWord(*inptr);
                        emitChar(0);
                        emitChar(0);
            inptr++;
            inptr++;
            if (*inptr!='\'') {
            if (*inptr!='\'') {
                printf("Missing ' in character constant.\r\n");
                printf("Missing ' in character constant.\r\n");
            }
            }
        }
        }
        else {
        else {
             NextToken();
             NextToken();
            val = expr128();
            val = expr128();
    // A pointer to an object might be emitted as a data word.
    // A pointer to an object might be emitted as a data word.
    if (bGen && lastsym)
    if (bGen && lastsym)
    if( lastsym->segment < 5)
    if( lastsym->segment < 5)
    sections[segment+7].AddRel(sections[segment].index,((int64_t)(lastsym->ord+1) << 32) | 6 | (lastsym->isExtern ? 128 : 0));
    sections[segment+7].AddRel(sections[segment].index,((int64_t)(lastsym->ord+1) << 32) | 6 | (lastsym->isExtern ? 128 : 0));
            emitDecibyte(val);
            emitDecibyte(val);
            prevToken();
            prevToken();
        }
        }
        SkipSpaces();
        SkipSpaces();
        if (*inptr!=',')
        if (*inptr!=',')
            break;
            break;
        inptr++;
        inptr++;
    }
    }
    ScanToEOL();
    ScanToEOL();
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// fill.b 252,0x00
// fill.b 252,0x00
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void process_fill()
void process_fill()
{
{
    char sz = 'b';
    char sz = 'b';
    int64_t count;
    int64_t count;
    int64_t val;
    int64_t val;
    int64_t nn;
    int64_t nn;
 
 
    if (*inptr=='.') {
    if (*inptr=='.') {
        inptr++;
        inptr++;
        if (strchr("bchwBCHW",*inptr)) {
        if (strchr("bchwBCHW",*inptr)) {
            sz = tolower(*inptr);
            sz = tolower(*inptr);
            inptr++;
            inptr++;
        }
        }
        else
        else
            printf("Illegal fill size.\r\n");
            printf("Illegal fill size.\r\n");
    }
    }
    SkipSpaces();
    SkipSpaces();
    NextToken();
    NextToken();
    count = expr();
    count = expr();
    prevToken();
    prevToken();
    need(',');
    need(',');
    NextToken();
    NextToken();
    val = expr();
    val = expr();
    prevToken();
    prevToken();
    for (nn = 0; nn < count; nn++)
    for (nn = 0; nn < count; nn++)
        switch(sz) {
        switch(sz) {
        case 'b': emitByte(val); break;
        case 'b': emitByte(val); break;
        case 'c': emitChar(val); break;
        case 'c': emitChar(val); break;
        case 'h': emitHalf(val); break;
        case 'h': emitHalf(val); break;
        case 'w': emitWord(val); break;
        case 'w': emitWord(val); break;
        }
        }
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Bump up the address to the next aligned code address.
// Bump up the address to the next aligned code address.
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void bump_address()
void bump_address()
{
{
     if (gCpu==888 || gCpu==889)
     if (gCpu==888 || gCpu==889)
        Table888_bump_address();
        Table888_bump_address();
}
}
 
 
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// macro <name> (<arg1, arg2, arg3, ...>)
// macro <name> (<arg1, arg2, arg3, ...>)
//      < macro body >
//      < macro body >
// endm
// endm
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
 
 
void process_macro()
void process_macro()
{
{
        SYM *sym;
        SYM *sym;
        Macro *macr;
        Macro *macr;
        bool alreadyDef = false;
        bool alreadyDef = false;
        char *p;
        char *p;
 
 
        if (pass == 3) {
        if (pass == 3) {
                macr = new Macro;
                macr = new Macro;
                SkipSpaces();
                SkipSpaces();
                getIdentifier();
                getIdentifier();
                sym = find_symbol(lastid);
                sym = find_symbol(lastid);
                if (sym != nullptr) {
                if (sym != nullptr) {
                        printf("Macro already defined %d.", lineno);
                        printf("Macro already defined %d.", lineno);
                        alreadyDef = true;
                        alreadyDef = true;
                }
                }
                else {
                else {
                        sym = new_symbol(lastid);
                        sym = new_symbol(lastid);
                        sym->defined = 1;
                        sym->defined = 1;
                        sym->isMacro = true;
                        sym->isMacro = true;
                        sym->macro = macr;
                        sym->macro = macr;
                }
                }
                NextToken();
                NextToken();
                if (token == '(') {
                if (token == '(') {
                        macr->GetParmList();
                        macr->GetParmList();
                        NextToken();
                        NextToken();
                        need(')');
                        need(')');
                }
                }
                p = inptr;
                p = inptr;
                macr->GetBody();
                macr->GetBody();
                if (alreadyDef)
                if (alreadyDef)
                        delete macr;
                        delete macr;
        }
        }
        else if (pass > 3) {
        else if (pass > 3) {
                Macro mthrowaway;
                Macro mthrowaway;
                SkipSpaces();
                SkipSpaces();
                getIdentifier();
                getIdentifier();
                NextToken();
                NextToken();
                if (token == '(') {
                if (token == '(') {
                        mthrowaway.GetParmList();
                        mthrowaway.GetParmList();
                        NextToken();
                        NextToken();
                        need(')');
                        need(')');
                }
                }
                mthrowaway.GetBody();
                mthrowaway.GetBody();
        }
        }
}
}
 
 
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
void process_message()
void process_message()
{
{
    char buf[200];
    char buf[200];
    int nn;
    int nn;
 
 
    while(*inptr != '"' && *inptr != '\n') inptr++;
    while(*inptr != '"' && *inptr != '\n') inptr++;
    if (*inptr=='\n') { NextToken(); return; }
    if (*inptr=='\n') { NextToken(); return; }
    nn = 0;
    nn = 0;
    inptr++;
    inptr++;
    while (*inptr != '"' && *inptr != '\n' && nn < 197) {
    while (*inptr != '"' && *inptr != '\n' && nn < 197) {
        buf[nn] = *inptr;
        buf[nn] = *inptr;
        inptr++;
        inptr++;
        nn++;
        nn++;
    }
    }
    buf[nn] = '\0';
    buf[nn] = '\0';
    strcat_s(buf, sizeof(buf), "\r\n");
    strcat_s(buf, sizeof(buf), "\r\n");
    printf(buf);
    printf(buf);
    ScanToEOL();
    ScanToEOL();
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// label:
// label:
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void process_label()
void process_label()
{
{
  SYM *sym;
  SYM *sym;
  static char nm[500];
  static char nm[500];
  int64_t ca;
  int64_t ca;
  Int128 val;
  Int128 val;
  int isEquate;
  int isEquate;
  int shft = 0;
  int shft = 0;
 
 
        val.low = 0;
        val.low = 0;
        val.high = 0;
        val.high = 0;
        if (gCpu==7)
        if (gCpu==7)
                shft = 1;
                shft = 1;
 
 
//    printf("<process_label>");
//    printf("<process_label>");
    isEquate = 0;
    isEquate = 0;
    // Bump up the address to align it with a valid code address if needed.
    // Bump up the address to align it with a valid code address if needed.
    bump_address();
    bump_address();
    switch(segment) {
    switch(segment) {
    case codeseg:
    case codeseg:
         ca = code_address >> shft;
         ca = code_address >> shft;
         ca = sections[0].address >> shft;
         ca = sections[0].address >> shft;
         break;
         break;
    case rodataseg:
    case rodataseg:
         ca = sections[1].address >> shft;
         ca = sections[1].address >> shft;
         break;
         break;
    case dataseg:
    case dataseg:
         ca = sections[2].address >> shft;
         ca = sections[2].address >> shft;
         break;
         break;
    case bssseg:
    case bssseg:
         ca = sections[3].address >> shft;
         ca = sections[3].address >> shft;
         break;
         break;
    case tlsseg:
    case tlsseg:
         ca = sections[4].address >> shft;
         ca = sections[4].address >> shft;
         break;
         break;
        default:
        default:
                 ca = code_address >> shft;
                 ca = code_address >> shft;
                 ca = sections[0].address >> shft;
                 ca = sections[0].address >> shft;
                 break;
                 break;
        }
        }
//    if (segment==bssseg)
//    if (segment==bssseg)
//       ca = bss_address;
//       ca = bss_address;
//    else
//    else
//        ca = code_address;
//        ca = code_address;
    if (lastid[0]=='.') {
    if (lastid[0]=='.') {
        sprintf_s(nm, sizeof(nm), "%s%s", current_label, lastid);
        sprintf_s(nm, sizeof(nm), "%s%s", current_label, lastid);
    }
    }
    else {
    else {
        strcpy_s(current_label, sizeof(current_label), lastid);
        strcpy_s(current_label, sizeof(current_label), lastid);
        strcpy_s(nm, sizeof(nm), lastid);
        strcpy_s(nm, sizeof(nm), lastid);
    }
    }
    if (strcmp("end_init_data", nm)==0)
    if (strcmp("end_init_data", nm)==0)
       isInitializationData = 0;
       isInitializationData = 0;
    NextToken();
    NextToken();
//    SkipSpaces();
//    SkipSpaces();
    if (token==tk_equ || token==tk_eq) {
    if (token==tk_equ || token==tk_eq) {
        NextToken();
        NextToken();
        val = expr128();
        val = expr128();
        isEquate = 1;
        isEquate = 1;
    }
    }
    else {
    else {
                prevToken();
                prevToken();
                val.low = ca;
                val.low = ca;
                val.high = 0;
                val.high = 0;
        }
        }
//    if (token==tk_eol)
//    if (token==tk_eol)
//       prevToken();
//       prevToken();
    //else if (token==':') inptr++;
    //else if (token==':') inptr++;
    // ignore the labels in initialization data
    // ignore the labels in initialization data
    if (isInitializationData)
    if (isInitializationData)
       return;
       return;
    sym = find_symbol(nm);
    sym = find_symbol(nm);
    if (pass==4 || pass==3) {
    if (pass==4 || pass==3) {
        if (sym) {
        if (sym) {
            if (sym->defined) {
            if (sym->defined) {
                //if (!Int128::IsEqual(&sym->value, &val)) {
                //if (!Int128::IsEqual(&sym->value, &val)) {
                //    printf("Label %s already defined %ld vs %ld.\r\n", nm, sym->value.low, val.low);
                //    printf("Label %s already defined %ld vs %ld.\r\n", nm, sym->value.low, val.low);
                //    printf("Line %d: %.60s\r\n", lineno, stptr);
                //    printf("Line %d: %.60s\r\n", lineno, stptr);
                //}
                //}
            }
            }
            sym->defined = 1;
            sym->defined = 1;
            if (isEquate) {
            if (isEquate) {
                sym->value = val;
                sym->value = val;
                sym->segment = constseg;
                sym->segment = constseg;
                sym->bits = (int)ceil(log(fabs((double)val.low)+1) / log(2.0))+1;
                sym->bits = (int)ceil(log(fabs((double)val.low)+1) / log(2.0))+1;
            }
            }
            else {
            else {
                                if (gCpu=='G')
                                if (gCpu=='G')
                                        sym->value.low = ca & -4LL;
                                        sym->value.low = ca & -4LL;
                                else
                                else
                                        sym->value.low = ca;
                                        sym->value.low = ca;
                                sym->value.high = 0;
                                sym->value.high = 0;
                sym->segment = segment;
                sym->segment = segment;
                if (segment==codeseg)
                if (segment==codeseg)
                   sym->bits = code_bits;
                   sym->bits = code_bits;
                else
                else
                    sym->bits = data_bits;
                    sym->bits = data_bits;
            }
            }
        }
        }
        else {
        else {
            sym = new_symbol(nm);
            sym = new_symbol(nm);
            sym->defined = 1;
            sym->defined = 1;
            if (isEquate) {
            if (isEquate) {
                sym->value = val;
                sym->value = val;
                sym->segment = constseg;
                sym->segment = constseg;
                sym->bits = (int)ceil(log(fabs((double)val.low)+1) / log(2.0))+1;
                sym->bits = (int)ceil(log(fabs((double)val.low)+1) / log(2.0))+1;
            }
            }
            else {
            else {
                                if (gCpu=='G')
                                if (gCpu=='G')
                                        sym->value.low = ca & -4LL;
                                        sym->value.low = ca & -4LL;
                                else
                                else
                                        sym->value.low = ca;
                                        sym->value.low = ca;
                                sym->value.high = 0;
                                sym->value.high = 0;
                                sym->segment = segment;
                                sym->segment = segment;
                if (segment==codeseg)
                if (segment==codeseg)
                   sym->bits = code_bits;
                   sym->bits = code_bits;
                else
                else
                    sym->bits = data_bits;
                    sym->bits = data_bits;
            }
            }
        }
        }
    }
    }
    else if (pass>4) {
    else if (pass>4) {
         if (!sym) {
         if (!sym) {
            printf("Internal error: SYM is NULL.\r\n");
            printf("Internal error: SYM is NULL.\r\n");
            printf("Couldn't find <%s>\r\n", nm);
            printf("Couldn't find <%s>\r\n", nm);
         }
         }
         else {
         else {
             if (isEquate) {
             if (isEquate) {
                 sym->value = val;
                 sym->value = val;
             }
             }
             else {
             else {
                                 if ((sym->value.low != ca && gCpu!='G') || (sym->value.low != (ca & -4LL) && gCpu=='G')) {
                                 if ((sym->value.low != ca && gCpu!='G') || (sym->value.low != (ca & -4LL) && gCpu=='G')) {
                     phasing_errors++;
                     phasing_errors++;
                     sym->phaserr = '*';
                     sym->phaserr = '*';
                     //if (bGen) printf("%s=%06llx ca=%06llx\r\n", nmTable.GetName(sym->name),  sym->value, code_address);
                     //if (bGen) printf("%s=%06llx ca=%06llx\r\n", nmTable.GetName(sym->name),  sym->value, code_address);
                 }
                 }
                 else
                 else
                     sym->phaserr = ' ';
                     sym->phaserr = ' ';
                                        if (gCpu=='G')
                                        if (gCpu=='G')
                                                sym->value.low = ca & -4LL;
                                                sym->value.low = ca & -4LL;
                                        else
                                        else
                                                sym->value.low = ca;
                                                sym->value.low = ca;
                                 sym->value.high = 0;
                                 sym->value.high = 0;
                         }
                         }
         }
         }
    }
    }
    if (strcmp("begin_init_data", nm)==0)
    if (strcmp("begin_init_data", nm)==0)
       isInitializationData = 1;
       isInitializationData = 1;
//    printf("</process_ label>\r\n");
//    printf("</process_ label>\r\n");
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Group and reorder the segments in the master file.
// Group and reorder the segments in the master file.
//     code          placed first
//     code          placed first
//     rodata        followed by
//     rodata        followed by
//     data
//     data
//     tls
//     tls
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void processSegments()
void processSegments()
{
{
  char *pinptr;
  char *pinptr;
  int segment = codeseg;
  int segment = codeseg;
  int inComment;
  int inComment;
        std::string fname;
        std::string fname;
        bool setname = false;
        bool setname = false;
 
 
  if (verbose)
  if (verbose)
    printf("Processing segments.\r\n");
    printf("Processing segments.\r\n");
  inptr = &masterFile[0];
  inptr = &masterFile[0];
  pinptr = inptr;
  pinptr = inptr;
  codendx = 0;
  codendx = 0;
  datandx = 0;
  datandx = 0;
  rodatandx = 0;
  rodatandx = 0;
  tlsndx = 0;
  tlsndx = 0;
  bssndx = 0;
  bssndx = 0;
  ZeroMemory(codebuf,sizeof(codebuf));
  ZeroMemory(codebuf,sizeof(codebuf));
  ZeroMemory(databuf,sizeof(databuf));
  ZeroMemory(databuf,sizeof(databuf));
  ZeroMemory(rodatabuf,sizeof(rodatabuf));
  ZeroMemory(rodatabuf,sizeof(rodatabuf));
  ZeroMemory(tlsbuf,sizeof(tlsbuf));
  ZeroMemory(tlsbuf,sizeof(tlsbuf));
  ZeroMemory(bssbuf,sizeof(bssbuf));
  ZeroMemory(bssbuf,sizeof(bssbuf));
  inComment = 0;
  inComment = 0;
 
 
        lineno = 1;
        lineno = 1;
        while (*inptr) {
        while (*inptr) {
                if (*inptr == '\n')
                if (*inptr == '\n')
                        lineno++;
                        lineno++;
                SkipSpaces();
                SkipSpaces();
                if (*inptr == ';')
                if (*inptr == ';')
                        goto j1;
                        goto j1;
                if (inptr[0] == '/' && inptr[1] == '/')
                if (inptr[0] == '/' && inptr[1] == '/')
                        goto j1;
                        goto j1;
                //        if (inptr[0]=='/' && inptr[1]=='*') {
                //        if (inptr[0]=='/' && inptr[1]=='*') {
                //              inComment = 1;
                //              inComment = 1;
                //              goto j1;
                //              goto j1;
                //              }
                //              }
                //              if (inComment && inptr[0]=='*' && inptr[1]=='/')
                //              if (inComment && inptr[0]=='*' && inptr[1]=='/')
                //                      inComment = 0;
                //                      inComment = 0;
                //              if (inComment)
                //              if (inComment)
                //                      goto j1;
                //                      goto j1;
                if (*inptr == '.') inptr++;
                if (*inptr == '.') inptr++;
                if ((_strnicmp(inptr, "file", 4)==0) && !isIdentChar(inptr[4])) {
                if ((_strnicmp(inptr, "file", 4)==0) && !isIdentChar(inptr[4])) {
                        inptr += 4;
                        inptr += 4;
                        NextToken();
                        NextToken();
                        if (token == tk_strconst)
                        if (token == tk_strconst)
                                fname = std::string(laststr);
                                fname = std::string(laststr);
                        else
                        else
                                fname = std::string("<unknown file>");
                                fname = std::string("<unknown file>");
                        NextToken();
                        NextToken();
                        lineno = expr();
                        lineno = expr();
                        setname = true;
                        setname = true;
                }
                }
    else if ((_strnicmp(inptr,"code",4)==0) && !isIdentChar(inptr[4])) {
    else if ((_strnicmp(inptr,"code",4)==0) && !isIdentChar(inptr[4])) {
      segment = codeseg;
      segment = codeseg;
                        setname = true;
                        setname = true;
    }
    }
    else if ((_strnicmp(inptr,"data",4)==0) && !isIdentChar(inptr[4])) {
    else if ((_strnicmp(inptr,"data",4)==0) && !isIdentChar(inptr[4])) {
        segment = dataseg;
        segment = dataseg;
    }
    }
    else if ((_strnicmp(inptr,"rodata",6)==0) && !isIdentChar(inptr[6])) {
    else if ((_strnicmp(inptr,"rodata",6)==0) && !isIdentChar(inptr[6])) {
        segment = rodataseg;
        segment = rodataseg;
    }
    }
    else if ((_strnicmp(inptr,"tls",3)==0) && !isIdentChar(inptr[3])) {
    else if ((_strnicmp(inptr,"tls",3)==0) && !isIdentChar(inptr[3])) {
        segment = tlsseg;
        segment = tlsseg;
    }
    }
    else if ((_strnicmp(inptr,"bss",3)==0) && !isIdentChar(inptr[3])) {
    else if ((_strnicmp(inptr,"bss",3)==0) && !isIdentChar(inptr[3])) {
        segment = bssseg;
        segment = bssseg;
    }
    }
j1:
j1:
        ScanToEOL();
        ScanToEOL();
        inptr++;
        inptr++;
        switch(segment) {
        switch(segment) {
        case codeseg:
        case codeseg:
                                        if (setname) {
                                        if (setname) {
                                                setname = false;
                                                setname = false;
                                                if (fname.length() > 0) {
                                                if (fname.length() > 0) {
                                                        sprintf(&codebuf[codendx], ".file \x22%s\x22,%d\n", fname.c_str(), lineno);
                                                        sprintf(&codebuf[codendx], ".file \x22%s\x22,%d\n", fname.c_str(), lineno);
                                                        codendx += strlen(&codebuf[codendx]);
                                                        codendx += strlen(&codebuf[codendx]);
                                                }
                                                }
                                        }
                                        }
          strncpy(&codebuf[codendx], pinptr, inptr-pinptr);
          strncpy(&codebuf[codendx], pinptr, inptr-pinptr);
          codendx += inptr-pinptr;
          codendx += inptr-pinptr;
          break;
          break;
              case dataseg:
              case dataseg:
             strncpy(&databuf[datandx], pinptr, inptr-pinptr);
             strncpy(&databuf[datandx], pinptr, inptr-pinptr);
             datandx += inptr-pinptr;
             datandx += inptr-pinptr;
             break;
             break;
        case rodataseg:
        case rodataseg:
             strncpy(&rodatabuf[rodatandx], pinptr, inptr-pinptr);
             strncpy(&rodatabuf[rodatandx], pinptr, inptr-pinptr);
             rodatandx += inptr-pinptr;
             rodatandx += inptr-pinptr;
             break;
             break;
        case tlsseg:
        case tlsseg:
             strncpy(&tlsbuf[tlsndx], pinptr, inptr-pinptr);
             strncpy(&tlsbuf[tlsndx], pinptr, inptr-pinptr);
             tlsndx += inptr-pinptr;
             tlsndx += inptr-pinptr;
             break;
             break;
        case bssseg:
        case bssseg:
             strncpy(&bssbuf[bssndx], pinptr, inptr-pinptr);
             strncpy(&bssbuf[bssndx], pinptr, inptr-pinptr);
             bssndx += inptr-pinptr;
             bssndx += inptr-pinptr;
             break;
             break;
        }
        }
        pinptr = inptr;
        pinptr = inptr;
    }
    }
    ZeroMemory(masterFile,sizeof(masterFile));
    ZeroMemory(masterFile,sizeof(masterFile));
    strcat(masterFile, codebuf);
    strcat(masterFile, codebuf);
    strcat(masterFile, rodatabuf);
    strcat(masterFile, rodatabuf);
    strcat(masterFile, "\r\n\trodata\r\n");
    strcat(masterFile, "\r\n\trodata\r\n");
    strcat(masterFile, "\talign 8\r\n");
    strcat(masterFile, "\talign 8\r\n");
    strcat(masterFile, "begin_init_data:\r\n");
    strcat(masterFile, "begin_init_data:\r\n");
    strcat(masterFile, databuf);
    strcat(masterFile, databuf);
    strcat(masterFile, "\r\n\trodata\r\n");
    strcat(masterFile, "\r\n\trodata\r\n");
    strcat(masterFile, "\talign 8\r\n");
    strcat(masterFile, "\talign 8\r\n");
    strcat(masterFile, "end_init_data:\r\n");
    strcat(masterFile, "end_init_data:\r\n");
    strcat(masterFile, databuf);
    strcat(masterFile, databuf);
    strcat(masterFile, bssbuf);
    strcat(masterFile, bssbuf);
    strcat(masterFile, tlsbuf);
    strcat(masterFile, tlsbuf);
    if (debug) {
    if (debug) {
        FILE *fp;
        FILE *fp;
        fp = fopen("a64-segments.asm", "w");
        fp = fopen("a64-segments.asm", "w");
        if (fp) {
        if (fp) {
                fwrite(masterFile, 1, strlen(masterFile), fp);
                fwrite(masterFile, 1, strlen(masterFile), fp);
                fclose(fp);
                fclose(fp);
        }
        }
    }
    }
}
}
 
 
void ProcessSegments2()
void ProcessSegments2()
{
{
        char buf[1000];
        char buf[1000];
        char *lptr;
        char *lptr;
        char fname[600];
        char fname[600];
        bool setname = false;
        bool setname = false;
 
 
        std::ifstream ifs("as64-master.asm");
        std::ifstream ifs("as64-master.asm");
        std::ofstream codeofs("as64-code.asm");
        std::ofstream codeofs("as64-code.asm");
        std::ofstream dataofs("as64-data.asm");
        std::ofstream dataofs("as64-data.asm");
        std::ofstream idataofs("as64-idata.asm");
        std::ofstream idataofs("as64-idata.asm");
        std::ofstream rodataofs("as64-rodata.asm");
        std::ofstream rodataofs("as64-rodata.asm");
        std::ofstream bssofs("as64-bss.asm");
        std::ofstream bssofs("as64-bss.asm");
        std::ofstream tlsofs("as64-tls.asm");
        std::ofstream tlsofs("as64-tls.asm");
 
 
        ZeroMemory(buf, sizeof(buf));
        ZeroMemory(buf, sizeof(buf));
        ZeroMemory(fname, sizeof(fname));
        ZeroMemory(fname, sizeof(fname));
        while (ifs.getline(buf, sizeof(buf))) {
        while (ifs.getline(buf, sizeof(buf))) {
                inptr = buf;
                inptr = buf;
                SkipSpaces();
                SkipSpaces();
                if (*inptr == ';')
                if (*inptr == ';')
                        goto j1;
                        goto j1;
                if (inptr[0] == '/' && inptr[1] == '/')
                if (inptr[0] == '/' && inptr[1] == '/')
                        goto j1;
                        goto j1;
                if (*inptr == '.') inptr++;
                if (*inptr == '.') inptr++;
                if ((_strnicmp(inptr, "file", 4)==0) && !isIdentChar(inptr[4])) {
                if ((_strnicmp(inptr, "file", 4)==0) && !isIdentChar(inptr[4])) {
                        inptr += 4;
                        inptr += 4;
                        if (inptr[0] == ':')
                        if (inptr[0] == ':')
                                inptr++;
                                inptr++;
                        getIdentifier();
                        getIdentifier();
                        strcpy_s(fname, sizeof(fname), lastid);
                        strcpy_s(fname, sizeof(fname), lastid);
                }
                }
                if ((_strnicmp(inptr, "code", 4) == 0) && !isIdentChar(inptr[4])) {
                if ((_strnicmp(inptr, "code", 4) == 0) && !isIdentChar(inptr[4])) {
                        segment = codeseg;
                        segment = codeseg;
                        setname = true;
                        setname = true;
                }
                }
                else if ((_strnicmp(inptr, "data", 4) == 0) && !isIdentChar(inptr[4])) {
                else if ((_strnicmp(inptr, "data", 4) == 0) && !isIdentChar(inptr[4])) {
                        segment = dataseg;
                        segment = dataseg;
                }
                }
                else if ((_strnicmp(inptr, "rodata", 6) == 0) && !isIdentChar(inptr[6])) {
                else if ((_strnicmp(inptr, "rodata", 6) == 0) && !isIdentChar(inptr[6])) {
                        segment = rodataseg;
                        segment = rodataseg;
                }
                }
                else if ((_strnicmp(inptr, "tls", 3) == 0) && !isIdentChar(inptr[3])) {
                else if ((_strnicmp(inptr, "tls", 3) == 0) && !isIdentChar(inptr[3])) {
                        segment = tlsseg;
                        segment = tlsseg;
                }
                }
                else if ((_strnicmp(inptr, "bss", 3) == 0) && !isIdentChar(inptr[3])) {
                else if ((_strnicmp(inptr, "bss", 3) == 0) && !isIdentChar(inptr[3])) {
                        segment = bssseg;
                        segment = bssseg;
                }
                }
                j1:
                j1:
                        switch (segment) {
                        switch (segment) {
                        case codeseg:
                        case codeseg:
                                if (setname) {
                                if (setname) {
                                        setname = false;
                                        setname = false;
                                        codeofs << ".file: ";
                                        codeofs << ".file: ";
                                        codeofs << fname;
                                        codeofs << fname;
                                }
                                }
                                codeofs << buf;
                                codeofs << buf;
                                break;
                                break;
                        case dataseg:
                        case dataseg:
                                dataofs << buf;
                                dataofs << buf;
                                break;
                                break;
                        case rodataseg:
                        case rodataseg:
                                rodataofs << buf;
                                rodataofs << buf;
                                break;
                                break;
                        case tlsseg:
                        case tlsseg:
                                tlsofs << buf;
                                tlsofs << buf;
                                break;
                                break;
                        case bssseg:
                        case bssseg:
                                bssofs << buf;
                                bssofs << buf;
                                break;
                                break;
                        }
                        }
        }
        }
        codeofs.close();
        codeofs.close();
        dataofs.close();
        dataofs.close();
        idataofs.close();
        idataofs.close();
        rodataofs.close();
        rodataofs.close();
        bssofs.close();
        bssofs.close();
        tlsofs.close();
        tlsofs.close();
        ifs.close();
        ifs.close();
        system("type as64-code.asm > as64-segments.asm");
        system("type as64-code.asm > as64-segments.asm");
        system("type as64-rodata.asm >> as64-segments.asm");
        system("type as64-rodata.asm >> as64-segments.asm");
        std::ofstream ofs("as64-segments.asm", std::ofstream::out | std::ofstream::app);
        std::ofstream ofs("as64-segments.asm", std::ofstream::out | std::ofstream::app);
        ofs << "\nrodata\n";
        ofs << "\nrodata\n";
        ofs << "\talign 8\n";
        ofs << "\talign 8\n";
        ofs << "begin_init_data:\n";
        ofs << "begin_init_data:\n";
        ofs.close();
        ofs.close();
        system("type as64-data.asm >> as64-segments.asm");
        system("type as64-data.asm >> as64-segments.asm");
        ofs.open("as64-segments.asm", std::ofstream::out | std::ofstream::app);
        ofs.open("as64-segments.asm", std::ofstream::out | std::ofstream::app);
        ofs << "\nrodata\n";
        ofs << "\nrodata\n";
        ofs << "\talign 8\n";
        ofs << "\talign 8\n";
        ofs << "end_init_data:\n";
        ofs << "end_init_data:\n";
        ofs.close();
        ofs.close();
        system("type as64-data.asm >> as64-segments.asm");
        system("type as64-data.asm >> as64-segments.asm");
        system("type as64-bss.asm >> as64-segments.asm");
        system("type as64-bss.asm >> as64-segments.asm");
        system("type as64-tls.asm >> as64-segments.asm");
        system("type as64-tls.asm >> as64-segments.asm");
}
}
 
 
void skipif(int64_t val)
void skipif(int64_t val)
{
{
        int iflevel = 1;
        int iflevel = 1;
        char *p1, *p2, *p3;
        char *p1, *p2, *p3;
        bool codecut = false;
        bool codecut = false;
 
 
        // Cut out the if statement
        // Cut out the if statement
        p1 = pif1;
        p1 = pif1;
        memmove(pif1,pif2,sizeof(masterFile)-(pif2-masterFile));
        memmove(pif1,pif2,sizeof(masterFile)-(pif2-masterFile));
 
 
        p1 = inptr = pif1;
        p1 = inptr = pif1;
        while(*inptr) {
        while(*inptr) {
                SkipSpaces();
                SkipSpaces();
                p2 = inptr;
                p2 = inptr;
                NextToken();
                NextToken();
                p3 = inptr;
                p3 = inptr;
                if (token==tk_if || token==tk_ifdef || token==tk_ifndef)
                if (token==tk_if || token==tk_ifdef || token==tk_ifndef)
                        iflevel++;
                        iflevel++;
                else if (token==tk_endif) {
                else if (token==tk_endif) {
                        iflevel--;
                        iflevel--;
                        if (iflevel==0) {
                        if (iflevel==0) {
                                // If the if was false cut out the code between
                                // If the if was false cut out the code between
                                // if and endif
                                // if and endif
                                if (val==0 && !codecut) {
                                if (val==0 && !codecut) {
                                        memmove(pif1,p3,sizeof(masterFile)-(p3-masterFile));
                                        memmove(pif1,p3,sizeof(masterFile)-(p3-masterFile));
                                        inptr = pif1;
                                        inptr = pif1;
                                        return;
                                        return;
                                }
                                }
                                else {
                                else {
                                        // remove endif but leave remaining text
                                        // remove endif but leave remaining text
                                        memmove(p2,inptr,sizeof(masterFile)-(inptr-masterFile));
                                        memmove(p2,inptr,sizeof(masterFile)-(inptr-masterFile));
                                        inptr = p2;
                                        inptr = p2;
                                }
                                }
                        }
                        }
                }
                }
                else if (token==tk_else) {
                else if (token==tk_else) {
                        if (iflevel==0) {
                        if (iflevel==0) {
                                // cut out code between if and else
                                // cut out code between if and else
                                // and keep going until endif
                                // and keep going until endif
                                if (val==0) {
                                if (val==0) {
                                        memmove(pif1,p2+4,sizeof(masterFile)-(p2+4-masterFile));
                                        memmove(pif1,p2+4,sizeof(masterFile)-(p2+4-masterFile));
                                        inptr = pif1;
                                        inptr = pif1;
                                        codecut = true;
                                        codecut = true;
                                }
                                }
                                else {
                                else {
                                        // remove the else from text
                                        // remove the else from text
                                        // and keep going until endif
                                        // and keep going until endif
                                        memmove(p2,inptr,sizeof(masterFile)-(inptr-masterFile));
                                        memmove(p2,inptr,sizeof(masterFile)-(inptr-masterFile));
                                        inptr = p2;
                                        inptr = p2;
                                }
                                }
                        }
                        }
                }
                }
                else
                else
                        ScanToEOL();
                        ScanToEOL();
                if (*inptr=='\n')
                if (*inptr=='\n')
                        inptr++;
                        inptr++;
        }
        }
}
}
 
 
void doif()
void doif()
{
{
        int64_t val;
        int64_t val;
 
 
        NextToken();
        NextToken();
        val = expr();
        val = expr();
        pif2 = inptr;
        pif2 = inptr;
        ScanToEOL();
        ScanToEOL();
        skipif(val);
        skipif(val);
}
}
 
 
void doifdef()
void doifdef()
{
{
        int64_t val;
        int64_t val;
 
 
        if (getIdentifier()==0)
        if (getIdentifier()==0)
                printf("Expecting an identifier %d.\n", lineno);
                printf("Expecting an identifier %d.\n", lineno);
    val = (find_symbol(lastid)!=nullptr);
    val = (find_symbol(lastid)!=nullptr);
        ScanToEOL();
        ScanToEOL();
        pif2 = inptr;
        pif2 = inptr;
        skipif(val);
        skipif(val);
}
}
 
 
void doifndef()
void doifndef()
{
{
        int64_t val;
        int64_t val;
 
 
        if (getIdentifier()==0)
        if (getIdentifier()==0)
                printf("Expecting an identifier %d.\n", lineno);
                printf("Expecting an identifier %d.\n", lineno);
    val = (find_symbol(lastid)==nullptr);
    val = (find_symbol(lastid)==nullptr);
        ScanToEOL();
        ScanToEOL();
        pif2 = inptr;
        pif2 = inptr;
        skipif(val);
        skipif(val);
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Look for .include directives and include the files.
// Look for .include directives and include the files.
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void processLine(char *line)
void processLine(char *line)
{
{
  char *p;
  char *p;
  int quoteType;
  int quoteType;
  static char fnm[300];
  static char fnm[300];
  char *fname;
  char *fname;
  int nn;
  int nn;
  int lb;
  int lb;
 
 
  p = line;
  p = line;
        fns.GetTos()->lineno = lineno;
        fns.GetTos()->lineno = lineno;
        while(isspace(*p)) p++;
        while(isspace(*p)) p++;
  if (!*p) goto addToMaster;
  if (!*p) goto addToMaster;
  // see if the first thing on the line is an include directive
  // see if the first thing on the line is an include directive
  if (*p=='.') p++;
  if (*p=='.') p++;
  if (strnicmp(p, "include", 7)==0 && !isIdentChar(p[7]))
  if (strnicmp(p, "include", 7)==0 && !isIdentChar(p[7]))
  {
  {
    p += 7;
    p += 7;
    // Capture the file name
    // Capture the file name
    while(isspace(*p)) p++;
    while(isspace(*p)) p++;
    if (*p=='"') { quoteType = '"'; p++; }
    if (*p=='"') { quoteType = '"'; p++; }
    else if (*p=='<') { quoteType = '>'; p++; }
    else if (*p=='<') { quoteType = '>'; p++; }
    else quoteType = ' ';
    else quoteType = ' ';
    nn = 0;
    nn = 0;
    do {
    do {
      fnm[nn] = *p;
      fnm[nn] = *p;
      p++; nn++;
      p++; nn++;
      if (quoteType==' ' && isspace(*p)) break;
      if (quoteType==' ' && isspace(*p)) break;
      else if (*p == quoteType) break;
      else if (*p == quoteType) break;
      else if (*p=='\n') break;
      else if (*p=='\n') break;
    } while(nn < sizeof(fnm)/sizeof(char));
    } while(nn < sizeof(fnm)/sizeof(char));
    fnm[nn] = '\0';
    fnm[nn] = '\0';
    fname = strdup(fnm);
    fname = strdup(fnm);
    lb = lineno;
    lb = lineno;
    lineno = 1;
    lineno = 1;
    processFile(fname,1);
    processFile(fname,1);
    lineno = lb;
    lineno = lb;
    free(fname);
    free(fname);
    return;
    return;
  }
  }
  // Not an include directive, then just copy the line to the master buffer.
  // Not an include directive, then just copy the line to the master buffer.
addToMaster:
addToMaster:
  //strcpy(&masterFile[mfndx], line);
  //strcpy(&masterFile[mfndx], line);
  //mfndx += strlen(line);
  //mfndx += strlen(line);
        mofs << line;
        mofs << line;
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Build a aggregate of all the included files into a single master buffer.
// Build a aggregate of all the included files into a single master buffer.
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void processFile(char *fname, int searchincl)
void processFile(char *fname, int searchincl)
{
{
  FILE *fp;
  FILE *fp;
        std::ifstream ifs;
        std::ifstream ifs;
  char *pathname;
  char *pathname;
        char buf[700];
        char buf[700];
 
 
        fns.Push(mname, lineno);
        fns.Push(mname, lineno);
        mname = std::string(fname);
        mname = std::string(fname);
        lineno = 1;
        lineno = 1;
        mofs << ".file \x22";
        mofs << ".file \x22";
        mofs << mname.c_str();
        mofs << mname.c_str();
        mofs << "\x22," << lineno << "\n";
        mofs << "\x22," << lineno << "\n";
        if (verbose)
        if (verbose)
    printf("Processing file:%s\n", fname);
    printf("Processing file:%s\n", fname);
  pathname = (char *)NULL;
  pathname = (char *)NULL;
        ifs.open(fname);
        ifs.open(fname);
  if (ifs.fail()) {
  if (ifs.fail()) {
    if (searchincl) {
    if (searchincl) {
      searchenv(fname, "INCLUDE", &pathname);
      searchenv(fname, "INCLUDE", &pathname);
      if (strlen(pathname)) {
      if (strlen(pathname)) {
        ifs.open(pathname);
        ifs.open(pathname);
        if (!ifs.fail()) goto j1;
        if (!ifs.fail()) goto j1;
      }
      }
    }
    }
    printf("Can't open file <%s>\n", fname);
    printf("Can't open file <%s>\n", fname);
    goto j2;
    goto j2;
  }
  }
j1:
j1:
        while (ifs.getline(buf, sizeof(buf))) {
        while (ifs.getline(buf, sizeof(buf))) {
                strcat(buf,"\n");
                strcat(buf,"\n");
                processLine(buf);
                processLine(buf);
        }
        }
        ifs.close();
        ifs.close();
j2:
j2:
  if (pathname)
  if (pathname)
      free(pathname);
      free(pathname);
        fns.Pop(&mname, &lineno);
        fns.Pop(&mname, &lineno);
        mofs << ".file \x22";
        mofs << ".file \x22";
        mofs << mname.c_str();
        mofs << mname.c_str();
        mofs << "\x22," << lineno << "\n";
        mofs << "\x22," << lineno << "\n";
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
int checksum(int32_t *val)
int checksum(int32_t *val)
{
{
    int nn;
    int nn;
    int cs;
    int cs;
 
 
    cs = 0;
    cs = 0;
    for (nn = 0; nn < 32; nn++)
    for (nn = 0; nn < 32; nn++)
        cs ^= (*val & (1 << nn))!=0;
        cs ^= (*val & (1 << nn))!=0;
    return cs;
    return cs;
}
}
 
 
 
 
int checksum64(int64_t *val)
int checksum64(int64_t *val)
{
{
    int nn;
    int nn;
    int cs;
    int cs;
 
 
    cs = 0;
    cs = 0;
    for (nn = 0; nn < 64; nn++)
    for (nn = 0; nn < 64; nn++)
        cs ^= (*val & (1LL << nn))!=0;
        cs ^= (*val & (1LL << nn))!=0;
    return cs;
    return cs;
}
}
 
 
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void processMaster()
void processMaster()
{
{
  expandedBlock = 0;
  expandedBlock = 0;
        switch(gCpu) {
        switch(gCpu) {
        case 888:       Table888_processMaster();       break;
        case 888:       Table888_processMaster();       break;
        case 889:       Table888mmu_processMaster();    break;
        case 889:       Table888mmu_processMaster();    break;
        case 64:        FISA64_processMaster(); break;
        case 64:        FISA64_processMaster(); break;
        case 5:         Friscv_processMaster(); break;
        case 5:         Friscv_processMaster(); break;
        case 4:         Thor_processMaster();   break;
        case 4:         Thor_processMaster();   break;
        case 14:        dsd6_processMaster();   break;
        case 14:        dsd6_processMaster();   break;
        case 7:         dsd7_processMaster();   break;
        case 7:         dsd7_processMaster();   break;
        case 'A':       dsd9_processMaster();   break;
        case 'A':       dsd9_processMaster();   break;
        case 'F':       FT64_processMaster();   break;
        case 'F':       FT64_processMaster();   break;
        case 'G':       FT64x36_processMaster();        break;
        case 'G':       FT64x36_processMaster();        break;
        default:        FT64_processMaster();
        default:        FT64_processMaster();
        }
        }
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
int64_t Round512(int64_t n)
int64_t Round512(int64_t n)
{
{
    return (n + 511LL) & 0xFFFFFFFFFFFFFE00LL;
    return (n + 511LL) & 0xFFFFFFFFFFFFFE00LL;
}
}
 
 
int64_t Round4096(int64_t n)
int64_t Round4096(int64_t n)
{
{
    return (n + 4095LL) & 0xFFFFFFFFFFFFF000LL;
    return (n + 4095LL) & 0xFFFFFFFFFFFFF000LL;
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
void WriteELFFile(FILE *fp)
void WriteELFFile(FILE *fp)
{
{
    int nn;
    int nn;
    Elf64Symbol elfsym;
    Elf64Symbol elfsym;
    clsElf64File elf;
    clsElf64File elf;
    SYM *sym,*syms;
    SYM *sym,*syms;
    int64_t start;
    int64_t start;
 
 
    sections[0].hdr.sh_name = nmTable.AddName(".text");
    sections[0].hdr.sh_name = nmTable.AddName(".text");
    sections[0].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
    sections[0].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
    sections[0].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_EXECINSTR;
    sections[0].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_EXECINSTR;
    sections[0].hdr.sh_addr = rel_out ? 0 : sections[0].start;
    sections[0].hdr.sh_addr = rel_out ? 0 : sections[0].start;
    sections[0].hdr.sh_offset = 512;  // offset in file
    sections[0].hdr.sh_offset = 512;  // offset in file
    sections[0].hdr.sh_size = sections[0].index;
    sections[0].hdr.sh_size = sections[0].index;
    sections[0].hdr.sh_link = 0;
    sections[0].hdr.sh_link = 0;
    sections[0].hdr.sh_info = 0;
    sections[0].hdr.sh_info = 0;
    sections[0].hdr.sh_addralign = 16;
    sections[0].hdr.sh_addralign = 16;
    sections[0].hdr.sh_entsize = 0;
    sections[0].hdr.sh_entsize = 0;
 
 
    sections[1].hdr.sh_name = nmTable.AddName(".rodata");
    sections[1].hdr.sh_name = nmTable.AddName(".rodata");
    sections[1].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
    sections[1].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
    sections[1].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC;
    sections[1].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC;
    sections[1].hdr.sh_addr = sections[0].hdr.sh_addr + sections[0].index;
    sections[1].hdr.sh_addr = sections[0].hdr.sh_addr + sections[0].index;
    sections[1].hdr.sh_offset = sections[0].hdr.sh_offset + sections[0].index; // offset in file
    sections[1].hdr.sh_offset = sections[0].hdr.sh_offset + sections[0].index; // offset in file
    sections[1].hdr.sh_size = sections[1].index;
    sections[1].hdr.sh_size = sections[1].index;
    sections[1].hdr.sh_link = 0;
    sections[1].hdr.sh_link = 0;
    sections[1].hdr.sh_info = 0;
    sections[1].hdr.sh_info = 0;
    sections[1].hdr.sh_addralign = 8;
    sections[1].hdr.sh_addralign = 8;
    sections[1].hdr.sh_entsize = 0;
    sections[1].hdr.sh_entsize = 0;
 
 
    sections[2].hdr.sh_name = nmTable.AddName(".data");
    sections[2].hdr.sh_name = nmTable.AddName(".data");
    sections[2].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
    sections[2].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
    sections[2].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_WRITE;
    sections[2].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_WRITE;
    sections[2].hdr.sh_addr = sections[1].hdr.sh_addr + sections[1].index;
    sections[2].hdr.sh_addr = sections[1].hdr.sh_addr + sections[1].index;
    sections[2].hdr.sh_offset = sections[1].hdr.sh_offset + sections[1].index; // offset in file
    sections[2].hdr.sh_offset = sections[1].hdr.sh_offset + sections[1].index; // offset in file
    sections[2].hdr.sh_size = sections[2].index;
    sections[2].hdr.sh_size = sections[2].index;
    sections[2].hdr.sh_link = 0;
    sections[2].hdr.sh_link = 0;
    sections[2].hdr.sh_info = 0;
    sections[2].hdr.sh_info = 0;
    sections[2].hdr.sh_addralign = 8;
    sections[2].hdr.sh_addralign = 8;
    sections[2].hdr.sh_entsize = 0;
    sections[2].hdr.sh_entsize = 0;
 
 
    sections[3].hdr.sh_name = nmTable.AddName(".bss");
    sections[3].hdr.sh_name = nmTable.AddName(".bss");
    sections[3].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
    sections[3].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
    sections[3].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_WRITE;
    sections[3].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_WRITE;
    sections[3].hdr.sh_addr = sections[2].hdr.sh_addr + sections[2].index;
    sections[3].hdr.sh_addr = sections[2].hdr.sh_addr + sections[2].index;
    sections[3].hdr.sh_offset = sections[2].hdr.sh_offset + sections[2].index; // offset in file
    sections[3].hdr.sh_offset = sections[2].hdr.sh_offset + sections[2].index; // offset in file
    sections[3].hdr.sh_size = 0;
    sections[3].hdr.sh_size = 0;
    sections[3].hdr.sh_link = 0;
    sections[3].hdr.sh_link = 0;
    sections[3].hdr.sh_info = 0;
    sections[3].hdr.sh_info = 0;
    sections[3].hdr.sh_addralign = 8;
    sections[3].hdr.sh_addralign = 8;
    sections[3].hdr.sh_entsize = 0;
    sections[3].hdr.sh_entsize = 0;
 
 
    sections[4].hdr.sh_name = nmTable.AddName(".tls");
    sections[4].hdr.sh_name = nmTable.AddName(".tls");
    sections[4].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
    sections[4].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
    sections[4].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_WRITE;
    sections[4].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_WRITE;
    sections[4].hdr.sh_addr = sections[3].hdr.sh_addr + sections[3].index;;
    sections[4].hdr.sh_addr = sections[3].hdr.sh_addr + sections[3].index;;
    sections[4].hdr.sh_offset = sections[2].hdr.sh_offset + sections[2].index; // offset in file
    sections[4].hdr.sh_offset = sections[2].hdr.sh_offset + sections[2].index; // offset in file
    sections[4].hdr.sh_size = 0;
    sections[4].hdr.sh_size = 0;
    sections[4].hdr.sh_link = 0;
    sections[4].hdr.sh_link = 0;
    sections[4].hdr.sh_info = 0;
    sections[4].hdr.sh_info = 0;
    sections[4].hdr.sh_addralign = 8;
    sections[4].hdr.sh_addralign = 8;
    sections[4].hdr.sh_entsize = 0;
    sections[4].hdr.sh_entsize = 0;
 
 
    sections[5].hdr.sh_name = nmTable.AddName(".strtab");
    sections[5].hdr.sh_name = nmTable.AddName(".strtab");
    // The following line must be before the name table is copied to the section.
    // The following line must be before the name table is copied to the section.
    sections[6].hdr.sh_name = nmTable.AddName(".symtab");
    sections[6].hdr.sh_name = nmTable.AddName(".symtab");
    sections[7].hdr.sh_name = nmTable.AddName(".reltext");
    sections[7].hdr.sh_name = nmTable.AddName(".reltext");
    sections[8].hdr.sh_name = nmTable.AddName(".relrodata");
    sections[8].hdr.sh_name = nmTable.AddName(".relrodata");
    sections[9].hdr.sh_name = nmTable.AddName(".reldata");
    sections[9].hdr.sh_name = nmTable.AddName(".reldata");
    sections[10].hdr.sh_name = nmTable.AddName(".relbss");
    sections[10].hdr.sh_name = nmTable.AddName(".relbss");
    sections[11].hdr.sh_name = nmTable.AddName(".reltls");
    sections[11].hdr.sh_name = nmTable.AddName(".reltls");
    sections[5].hdr.sh_type = clsElf64Shdr::SHT_STRTAB;
    sections[5].hdr.sh_type = clsElf64Shdr::SHT_STRTAB;
    sections[5].hdr.sh_flags = 0;
    sections[5].hdr.sh_flags = 0;
    sections[5].hdr.sh_addr = 0;
    sections[5].hdr.sh_addr = 0;
    sections[5].hdr.sh_offset = 512 + sections[0].index + sections[1].index + sections[2].index; // offset in file
    sections[5].hdr.sh_offset = 512 + sections[0].index + sections[1].index + sections[2].index; // offset in file
    sections[5].hdr.sh_size = nmTable.length;
    sections[5].hdr.sh_size = nmTable.length;
    sections[5].hdr.sh_link = 0;
    sections[5].hdr.sh_link = 0;
    sections[5].hdr.sh_info = 0;
    sections[5].hdr.sh_info = 0;
    sections[5].hdr.sh_addralign = 1;
    sections[5].hdr.sh_addralign = 1;
    sections[5].hdr.sh_entsize = 0;
    sections[5].hdr.sh_entsize = 0;
    memcpy(sections[5].bytes, nmTable.text, nmTable.length);
    memcpy(sections[5].bytes, nmTable.text, nmTable.length);
 
 
    sections[6].hdr.sh_type = clsElf64Shdr::SHT_SYMTAB;
    sections[6].hdr.sh_type = clsElf64Shdr::SHT_SYMTAB;
    sections[6].hdr.sh_flags = 0;
    sections[6].hdr.sh_flags = 0;
    sections[6].hdr.sh_addr = 0;
    sections[6].hdr.sh_addr = 0;
    sections[6].hdr.sh_offset = Round512(512 + sections[0].index + sections[1].index + sections[2].index) + nmTable.length; // offset in file
    sections[6].hdr.sh_offset = Round512(512 + sections[0].index + sections[1].index + sections[2].index) + nmTable.length; // offset in file
    sections[6].hdr.sh_size = (numsym + 1) * 24;
    sections[6].hdr.sh_size = (numsym + 1) * 24;
    sections[6].hdr.sh_link = 5;
    sections[6].hdr.sh_link = 5;
    sections[6].hdr.sh_info = 0;
    sections[6].hdr.sh_info = 0;
    sections[6].hdr.sh_addralign = 1;
    sections[6].hdr.sh_addralign = 1;
    sections[6].hdr.sh_entsize = 24;
    sections[6].hdr.sh_entsize = 24;
 
 
    for(nn = 7; nn < 12; nn++) {
    for(nn = 7; nn < 12; nn++) {
        sections[nn].hdr.sh_type = clsElf64Shdr::SHT_REL;
        sections[nn].hdr.sh_type = clsElf64Shdr::SHT_REL;
        sections[nn].hdr.sh_flags = 0;
        sections[nn].hdr.sh_flags = 0;
        sections[nn].hdr.sh_addr = 0;
        sections[nn].hdr.sh_addr = 0;
        sections[nn].hdr.sh_offset = sections[nn-1].hdr.sh_offset + sections[nn-1].hdr.sh_size; // offset in file
        sections[nn].hdr.sh_offset = sections[nn-1].hdr.sh_offset + sections[nn-1].hdr.sh_size; // offset in file
        sections[nn].hdr.sh_size = sections[nn].index;
        sections[nn].hdr.sh_size = sections[nn].index;
        sections[nn].hdr.sh_link = 6;
        sections[nn].hdr.sh_link = 6;
        sections[nn].hdr.sh_info = 0;
        sections[nn].hdr.sh_info = 0;
        sections[nn].hdr.sh_addralign = 1;
        sections[nn].hdr.sh_addralign = 1;
        sections[nn].hdr.sh_entsize = 16;
        sections[nn].hdr.sh_entsize = 16;
    }
    }
 
 
    nn = 1;
    nn = 1;
    // The first entry is an NULL symbol
    // The first entry is an NULL symbol
    elfsym.st_name = 0;
    elfsym.st_name = 0;
    elfsym.st_info = 0;
    elfsym.st_info = 0;
    elfsym.st_other = 0;
    elfsym.st_other = 0;
    elfsym.st_shndx = 0;
    elfsym.st_shndx = 0;
    elfsym.st_value = 0;
    elfsym.st_value = 0;
    elfsym.st_size = 0;
    elfsym.st_size = 0;
    sections[6].Add(&elfsym);
    sections[6].Add(&elfsym);
    syms = (SYM*)HashInfo.table;
    syms = (SYM*)HashInfo.table;
    for (nn = 0; nn < HashInfo.size; nn++) {
    for (nn = 0; nn < HashInfo.size; nn++) {
        // Don't output the constants
        // Don't output the constants
//        if (syms[nn].segment < 5) {
//        if (syms[nn].segment < 5) {
          if (syms[nn].name) {
          if (syms[nn].name) {
            elfsym.st_name = syms[nn].name;
            elfsym.st_name = syms[nn].name;
            elfsym.st_info = syms[nn].scope == 'P' ? STB_GLOBAL << 4 : 0;
            elfsym.st_info = syms[nn].scope == 'P' ? STB_GLOBAL << 4 : 0;
            elfsym.st_other = 0;
            elfsym.st_other = 0;
            elfsym.st_shndx = syms[nn].segment;
            elfsym.st_shndx = syms[nn].segment;
            elfsym.st_value = syms[nn].value.low;
            elfsym.st_value = syms[nn].value.low;
            elfsym.st_size = 8;
            elfsym.st_size = 8;
            sections[6].Add(&elfsym);
            sections[6].Add(&elfsym);
//        }
//        }
        }
        }
    }
    }
 
 
    elf.hdr.e_ident[0] = 127;
    elf.hdr.e_ident[0] = 127;
    elf.hdr.e_ident[1] = 'E';
    elf.hdr.e_ident[1] = 'E';
    elf.hdr.e_ident[2] = 'L';
    elf.hdr.e_ident[2] = 'L';
    elf.hdr.e_ident[3] = 'F';
    elf.hdr.e_ident[3] = 'F';
    elf.hdr.e_ident[4] = clsElf64Header::ELFCLASS64;   // 64 bit file format
    elf.hdr.e_ident[4] = clsElf64Header::ELFCLASS64;   // 64 bit file format
    elf.hdr.e_ident[5] = clsElf64Header::ELFDATA2LSB;  // little endian
    elf.hdr.e_ident[5] = clsElf64Header::ELFDATA2LSB;  // little endian
    elf.hdr.e_ident[6] = 1;        // header version always 1
    elf.hdr.e_ident[6] = 1;        // header version always 1
    elf.hdr.e_ident[7] = 255;      // OS/ABI indentification, 255 = standalone
    elf.hdr.e_ident[7] = 255;      // OS/ABI indentification, 255 = standalone
    elf.hdr.e_ident[8] = 255;      // ABI version
    elf.hdr.e_ident[8] = 255;      // ABI version
    elf.hdr.e_ident[9] = 0;
    elf.hdr.e_ident[9] = 0;
    elf.hdr.e_ident[10] = 0;
    elf.hdr.e_ident[10] = 0;
    elf.hdr.e_ident[11] = 0;
    elf.hdr.e_ident[11] = 0;
    elf.hdr.e_ident[12] = 0;
    elf.hdr.e_ident[12] = 0;
    elf.hdr.e_ident[13] = 0;
    elf.hdr.e_ident[13] = 0;
    elf.hdr.e_ident[14] = 0;
    elf.hdr.e_ident[14] = 0;
    elf.hdr.e_ident[15] = 0;
    elf.hdr.e_ident[15] = 0;
    elf.hdr.e_type = rel_out ? 1 : 2;
    elf.hdr.e_type = rel_out ? 1 : 2;
    elf.hdr.e_machine = 888;         // machine architecture
    elf.hdr.e_machine = 888;         // machine architecture
    elf.hdr.e_version = 1;
    elf.hdr.e_version = 1;
    sym = find_symbol("start");
    sym = find_symbol("start");
    if (sym)
    if (sym)
        start = sym->value.low;
        start = sym->value.low;
    else
    else
        start = 0xC00200;
        start = 0xC00200;
    elf.hdr.e_entry = start;
    elf.hdr.e_entry = start;
    elf.hdr.e_phoff = 0;
    elf.hdr.e_phoff = 0;
    elf.hdr.e_shoff = sections[11].hdr.sh_offset + sections[11].index;
    elf.hdr.e_shoff = sections[11].hdr.sh_offset + sections[11].index;
    elf.hdr.e_flags = 0;
    elf.hdr.e_flags = 0;
    elf.hdr.e_ehsize = Elf64HdrSz;
    elf.hdr.e_ehsize = Elf64HdrSz;
    elf.hdr.e_phentsize = 0;
    elf.hdr.e_phentsize = 0;
    elf.hdr.e_phnum = 0;
    elf.hdr.e_phnum = 0;
    elf.hdr.e_shentsize = Elf64ShdrSz;
    elf.hdr.e_shentsize = Elf64ShdrSz;
    elf.hdr.e_shnum = 0;              // This will be incremented by AddSection()
    elf.hdr.e_shnum = 0;              // This will be incremented by AddSection()
    elf.hdr.e_shstrndx = 5;           // index into section table of string table header
    elf.hdr.e_shstrndx = 5;           // index into section table of string table header
 
 
    for (nn = 0; nn < 12; nn++)
    for (nn = 0; nn < 12; nn++)
        elf.AddSection(&sections[nn]);
        elf.AddSection(&sections[nn]);
    elf.Write(fp);
    elf.Write(fp);
 
 
}
}
 
 
int IHChecksum(char *ibuf, int payloadCount)
int IHChecksum(char *ibuf, int payloadCount)
{
{
    char buf[20];
    char buf[20];
    int nn;
    int nn;
    int ii;
    int ii;
    int sum;
    int sum;
 
 
    sum = 0;
    sum = 0;
    for (nn = 0; nn < payloadCount +4; nn++) {
    for (nn = 0; nn < payloadCount +4; nn++) {
        buf[0] = ibuf[nn*2+1];
        buf[0] = ibuf[nn*2+1];
        buf[1] = ibuf[nn*2+2];
        buf[1] = ibuf[nn*2+2];
        buf[2] = '\0';
        buf[2] = '\0';
        ii = strtoul(buf,NULL,16);
        ii = strtoul(buf,NULL,16);
        sum = sum + ii;
        sum = sum + ii;
    }
    }
    sum = -sum;
    sum = -sum;
    sprintf(&ibuf[(payloadCount+4) * 2+1],"%02X\n", sum & 0xFF);
    sprintf(&ibuf[(payloadCount+4) * 2+1],"%02X\n", sum & 0xFF);
        return sum;
        return sum;
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
int64_t getbit(int n, int bit)
int64_t getbit(int n, int bit)
{
{
        return (n >> bit) & 1;
        return (n >> bit) & 1;
}
}
 
 
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Compute 38 bit ECC (32+6 bits EDC).
// Compute 38 bit ECC (32+6 bits EDC).
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
int checkbits(unsigned int i)
int checkbits(unsigned int i)
{
{
/*
/*
        unsigned int p0,p1,p2,p3,p4,p5,p;
        unsigned int p0,p1,p2,p3,p4,p5,p;
        unsigned int t1,t2,t3;
        unsigned int t1,t2,t3;
 
 
        p0 = u ^ (u >> 2);
        p0 = u ^ (u >> 2);
        p0 = p0 ^ (p0 >> 4);
        p0 = p0 ^ (p0 >> 4);
        p0 = p0 ^ (p0 >> 8);
        p0 = p0 ^ (p0 >> 8);
        p0 = p0 ^ (p0 >> 16);
        p0 = p0 ^ (p0 >> 16);
 
 
        t1 = u ^ (u >> 1);
        t1 = u ^ (u >> 1);
        p1 = t1 ^ (t1 >> 4);
        p1 = t1 ^ (t1 >> 4);
        p1 = p1 ^ (p1 >> 8);
        p1 = p1 ^ (p1 >> 8);
        p1 = p1 ^ (p1 >> 16);
        p1 = p1 ^ (p1 >> 16);
 
 
        t2 = t1 ^ (t1 >> 2);
        t2 = t1 ^ (t1 >> 2);
        p2 = t2 ^ (t2 >> 8);
        p2 = t2 ^ (t2 >> 8);
        p2 = p2 ^ (p2 >> 16);
        p2 = p2 ^ (p2 >> 16);
 
 
        t3 = t2 ^ (t2 >> 4);
        t3 = t2 ^ (t2 >> 4);
        p3 = t3 ^ (t3 >> 16);
        p3 = t3 ^ (t3 >> 16);
 
 
        p4 = t3 ^ (t3 >> 8);
        p4 = t3 ^ (t3 >> 8);
 
 
        p5 = p4 ^ (p4 >> 16);
        p5 = p4 ^ (p4 >> 16);
 
 
        p = ((p0 >> 1)&1) | ((p1 >> 1)&2) | ((p2>>2)&4) |
        p = ((p0 >> 1)&1) | ((p1 >> 1)&2) | ((p2>>2)&4) |
                ((p3 >> 5)&8) | ((p4 >> 12)&16) | ((p5 & 1)<<5);
                ((p3 >> 5)&8) | ((p4 >> 12)&16) | ((p5 & 1)<<5);
 
 
        p = p ^ (-(u & 1)&0x3f);        // now account for u[0]
        p = p ^ (-(u & 1)&0x3f);        // now account for u[0]
        return p;
        return p;
*/
*/
 
 
        static int8_t g1[18] = {0,1,3,4,6,8,10,11,13,15,17,19,21,23,25,26,28,30};
        static int8_t g1[18] = {0,1,3,4,6,8,10,11,13,15,17,19,21,23,25,26,28,30};
        static int8_t g2[18] = {0,2,3,5,6,9,10,12,13,16,17,20,21,24,25,27,28,31};
        static int8_t g2[18] = {0,2,3,5,6,9,10,12,13,16,17,20,21,24,25,27,28,31};
        static int8_t g4[18] = {1,2,3,7,8,9,10,14,15,16,17,22,23,24,25,29,30,31};
        static int8_t g4[18] = {1,2,3,7,8,9,10,14,15,16,17,22,23,24,25,29,30,31};
        static int8_t g8[15] = {4,5,6,7,8,9,10,18,19,20,21,22,23,24,25};
        static int8_t g8[15] = {4,5,6,7,8,9,10,18,19,20,21,22,23,24,25};
        static int8_t g16[15] = {11,12,13,14,15,16,17,18,19,20,21,22,23,24,25};
        static int8_t g16[15] = {11,12,13,14,15,16,17,18,19,20,21,22,23,24,25};
        static int8_t g32[6] = {26,27,28,29,30,31};
        static int8_t g32[6] = {26,27,28,29,30,31};
        unsigned int p1,p2,p4,p8,p16,p32,pg,b,o;
        unsigned int p1,p2,p4,p8,p16,p32,pg,b,o;
        int nn;
        int nn;
 
 
        p1 = 0;
        p1 = 0;
        for (nn = 0; nn < 18; nn++) {
        for (nn = 0; nn < 18; nn++) {
                b = getbit(i,g1[nn]);
                b = getbit(i,g1[nn]);
                p1 = p1 ^ b;
                p1 = p1 ^ b;
        }
        }
        p2 = 0;
        p2 = 0;
        for (nn = 0; nn < 18; nn++) {
        for (nn = 0; nn < 18; nn++) {
                b = getbit(i,g2[nn]);
                b = getbit(i,g2[nn]);
                p2 = p2 ^ b;
                p2 = p2 ^ b;
        }
        }
        p4 = 0;
        p4 = 0;
        for (nn = 0; nn < 18; nn++) {
        for (nn = 0; nn < 18; nn++) {
                b = getbit(i,g4[nn]);
                b = getbit(i,g4[nn]);
                p4 = p4 ^ b;
                p4 = p4 ^ b;
        }
        }
        p8 = 0;
        p8 = 0;
        for (nn = 0; nn < 15; nn++) {
        for (nn = 0; nn < 15; nn++) {
                b = getbit(i,g8[nn]);
                b = getbit(i,g8[nn]);
                p8 = p8 ^ b;
                p8 = p8 ^ b;
        }
        }
        p16 = 0;
        p16 = 0;
        for (nn = 0; nn < 15; nn++) {
        for (nn = 0; nn < 15; nn++) {
                b = getbit(i,g16[nn]);
                b = getbit(i,g16[nn]);
                p16 = p16 ^ b;
                p16 = p16 ^ b;
        }
        }
        p32 = 0;
        p32 = 0;
        for (nn = 0; nn < 6; nn++) {
        for (nn = 0; nn < 6; nn++) {
                b = getbit(i,g32[nn]);
                b = getbit(i,g32[nn]);
                p32 = p32 ^ b;
                p32 = p32 ^ b;
        }
        }
/*
/*
        o = p1|(p2<<1)|(getbit(i,0)<<2)|(p4<<3);
        o = p1|(p2<<1)|(getbit(i,0)<<2)|(p4<<3);
        o = o | (getbit(i,1)<<4)| (getbit(i,2)<<5)| (getbit(i,3)<<6)|(p8<<7);
        o = o | (getbit(i,1)<<4)| (getbit(i,2)<<5)| (getbit(i,3)<<6)|(p8<<7);
        for (nn = 4; nn <= 10; nn++)
        for (nn = 4; nn <= 10; nn++)
                o = o | (getbit(i,nn)<<(nn+4));
                o = o | (getbit(i,nn)<<(nn+4));
        o = o | (p16 << 15);
        o = o | (p16 << 15);
        for (nn = 11; nn <= 25; nn++)
        for (nn = 11; nn <= 25; nn++)
                o = o | (getbit(i,nn)<<(nn+5));
                o = o | (getbit(i,nn)<<(nn+5));
        o = o | (p32 << 31);
        o = o | (p32 << 31);
        for (nn = 26; nn <= 31; nn++)
        for (nn = 26; nn <= 31; nn++)
                o = o | (getbit(i,nn)<<(nn+6));
                o = o | (getbit(i,nn)<<(nn+6));
*/
*/
        pg = checksum((int32_t*)&i)^p1^p2^p4^p8^p16^p32;
        pg = checksum((int32_t*)&i)^p1^p2^p4^p8^p16^p32;
//      o = i | (p32<<37)|(p16<<36)|(p8<<35)|(p4<<34)|(p2<<33)|(p1<<32) | (pg << 38);
//      o = i | (p32<<37)|(p16<<36)|(p8<<35)|(p4<<34)|(p2<<33)|(p1<<32) | (pg << 38);
        o = (p32<<5)|(p16<<4)|(p8<<3)|(p4<<2)|(p2<<1)|p1|(pg<<6);
        o = (p32<<5)|(p16<<4)|(p8<<3)|(p4<<2)|(p2<<1)|p1|(pg<<6);
        return o;
        return o;
}
}
 
 
/*
/*
int PreProcessFile(char *nm)
int PreProcessFile(char *nm)
{
{
        static char outname[1000];
        static char outname[1000];
        static char sysbuf[500];
        static char sysbuf[500];
 
 
        strcpy_s(outname, sizeof(outname), nm);
        strcpy_s(outname, sizeof(outname), nm);
        strcat_s(outname,sizeof(outname),".app.asm");
        strcat_s(outname,sizeof(outname),".app.asm");
        sprintf_s(sysbuf, sizeof(sysbuf), "app -V %s %s", nm, outname);
        sprintf_s(sysbuf, sizeof(sysbuf), "app -V %s %s", nm, outname);
        return system(sysbuf);
        return system(sysbuf);
}
}
*/
*/
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
int main(int argc, char *argv[])
int main(int argc, char *argv[])
{
{
  int nn,qq,kk;
  int nn,qq,kk;
  static char fname[500];
  static char fname[500];
  static char hexbuf[500];
  static char hexbuf[500];
  char *p;
  char *p;
  uint64_t lsa;      // last start address
  uint64_t lsa;      // last start address
  double bpi;
  double bpi;
  int64_t i64;
  int64_t i64;
  uint32_t u32;
  uint32_t u32;
        float nc2;
        float nc2;
        std::ifstream ifs;
        std::ifstream ifs;
 
 
  processOpt = 1;
  processOpt = 1;
        sections[bssseg].storebyte = 0;
        sections[bssseg].storebyte = 0;
  ofp = stdout;
  ofp = stdout;
  nn = processOptions(argc, argv);
  nn = processOptions(argc, argv);
  if (nn > argc-1) {
  if (nn > argc-1) {
      displayHelp();
      displayHelp();
      return 0;
      return 0;
  }
  }
  SymbolInit();
  SymbolInit();
  strcpy_s(fname, sizeof(fname), argv[nn]);
  strcpy_s(fname, sizeof(fname), argv[nn]);
  mfndx = 0;
  mfndx = 0;
  start_address = 0;
  start_address = 0;
  code_address = 0;
  code_address = 0;
  bss_address = 0;
  bss_address = 0;
  data_address = 0;
  data_address = 0;
  isInitializationData = 0;
  isInitializationData = 0;
  for (qq = 0; qq < 12; qq++)
  for (qq = 0; qq < 12; qq++)
    sections[qq].Clear();
    sections[qq].Clear();
  nmTable.Clear();
  nmTable.Clear();
        mofs.open("as64-master.asm");
        mofs.open("as64-master.asm");
  if (verbose) printf("Pass 1 - collect all input files.\r\n");
  if (verbose) printf("Pass 1 - collect all input files.\r\n");
        //PreProcessFile(fname);
        //PreProcessFile(fname);
        //strcat_s(fname,sizeof(fname),".app.asm");
        //strcat_s(fname,sizeof(fname),".app.asm");
        mname = std::string(fname);
        mname = std::string(fname);
  processFile(fname,0);   // Pass 1, collect all include files
  processFile(fname,0);   // Pass 1, collect all include files
        masterFileLength = mofs.tellp();
        masterFileLength = mofs.tellp();
        mofs.close();
        mofs.close();
        masterFile = new char[masterFileLength + 10000];
        masterFile = new char[masterFileLength + 10000];
  //if (debug) {
  //if (debug) {
  //  FILE *fp;
  //  FILE *fp;
  //  fopen_s(&fp, "a64-master.asm", "w");
  //  fopen_s(&fp, "a64-master.asm", "w");
  //  if (fp) {
  //  if (fp) {
  //    fwrite(masterFile, 1, strlen(masterFile), fp);
  //    fwrite(masterFile, 1, strlen(masterFile), fp);
  //    fclose(fp);
  //    fclose(fp);
  //  }
  //  }
  //}
  //}
        ZeroMemory(masterFile, masterFileLength + 10000);
        ZeroMemory(masterFile, masterFileLength + 10000);
        ifs.open("as64-master.asm");
        ifs.open("as64-master.asm");
        ifs.read(masterFile, masterFileLength + 10000);
        ifs.read(masterFile, masterFileLength + 10000);
        ifs.close();
        ifs.close();
  if (verbose) printf("Pass 2 - group and reorder segments\r\n");
  if (verbose) printf("Pass 2 - group and reorder segments\r\n");
  first_org = 1;
  first_org = 1;
  processSegments();     // Pass 2, group and order segments
  processSegments();     // Pass 2, group and order segments
//      ProcessSegments2();
//      ProcessSegments2();
 
 
  pass = 3;
  pass = 3;
  processMaster();       // Pass 3 collect up opcodes
  processMaster();       // Pass 3 collect up opcodes
  printf("Qsorting\r\n");
  printf("Qsorting\r\n");
  qsort((HTBLE*)hTable, htblmax, sizeof(HTBLE), hcmp);
  qsort((HTBLE*)hTable, htblmax, sizeof(HTBLE), hcmp);
 
 
    pass = 4;
    pass = 4;
    if (verbose) printf("Pass 4 - get all symbols, set initial values.\r\n");
    if (verbose) printf("Pass 4 - get all symbols, set initial values.\r\n");
    first_org = 1;
    first_org = 1;
    processMaster();
    processMaster();
    pass = 5;
    pass = 5;
    phasing_errors = 0;
    phasing_errors = 0;
    if (verbose) printf("Pass 5 - assemble code.\r\n");
    if (verbose) printf("Pass 5 - assemble code.\r\n");
    first_org = 1;
    first_org = 1;
    processMaster();
    processMaster();
    if (verbose) printf("Pass 6: phase errors: %d\r\n", phasing_errors);
    if (verbose) printf("Pass 6: phase errors: %d\r\n", phasing_errors);
    pass = 6;
    pass = 6;
        pe3 = pe2 = pe1 = 0;
        pe3 = pe2 = pe1 = 0;
    while (phasing_errors && pass < 40) {
    while (phasing_errors && pass < 40) {
        phasing_errors = 0;
        phasing_errors = 0;
        num_bytes = 0;
        num_bytes = 0;
        num_insns = 0;
        num_insns = 0;
                num_cinsns = 0;
                num_cinsns = 0;
            first_org = 1;
            first_org = 1;
        processMaster();
        processMaster();
        if (verbose) printf("Pass %d: phase errors: %d\r\n", pass, phasing_errors);
        if (verbose) printf("Pass %d: phase errors: %d\r\n", pass, phasing_errors);
        pass++;
        pass++;
                pe3 = pe2;
                pe3 = pe2;
                pe2 = pe1;
                pe2 = pe1;
                pe1 = phasing_errors;
                pe1 = phasing_errors;
                if (pe1==pe2 && pe2==pe3 && pe1==pe3) {
                if (pe1==pe2 && pe2==pe3 && pe1==pe3) {
                        if (verbose)
                        if (verbose)
                                printf("Non converging phase errors\r\n");
                                printf("Non converging phase errors\r\n");
                        break;
                        break;
                }
                }
    }
    }
    //processMaster();
    //processMaster();
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Output listing file.
    // Output listing file.
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ofp = (FILE *)NULL;
    ofp = (FILE *)NULL;
    if (listing) {
    if (listing) {
        if (verbose) printf("Generating listing file %s.\r\n", argv[nn]);
        if (verbose) printf("Generating listing file %s.\r\n", argv[nn]);
        strcpy_s(fname, sizeof(fname), argv[nn]);
        strcpy_s(fname, sizeof(fname), argv[nn]);
        p = strrchr(fname,'.');
        p = strrchr(fname,'.');
        if (p) {
        if (p) {
            *p = '\0';
            *p = '\0';
        }
        }
        strcat_s(fname, sizeof(fname), ".lst");
        strcat_s(fname, sizeof(fname), ".lst");
        fopen_s(&ofp, fname,"w");
        fopen_s(&ofp, fname,"w");
        if (!ofp)
        if (!ofp)
           printf("Can't open output file <%s>\r\n", fname);
           printf("Can't open output file <%s>\r\n", fname);
        bGen = 1;
        bGen = 1;
    }
    }
    processOpt = 2;
    processOpt = 2;
        bGenListing = true;
        bGenListing = true;
    processMaster();
    processMaster();
        bGenListing = false;
        bGenListing = false;
    DumpSymbols();
    DumpSymbols();
    DumphTable();
    DumphTable();
    fprintf(ofp, "\nnumber of bytes: %f\n", num_bytes);
    fprintf(ofp, "\nnumber of bytes: %f\n", num_bytes);
    fprintf(ofp, "number of instructions: %d\n", num_insns);
    fprintf(ofp, "number of instructions: %d\n", num_insns);
        fprintf(ofp, "number of compressed instructions: %d\n", num_cinsns);
        fprintf(ofp, "number of compressed instructions: %d\n", num_cinsns);
        bpi = (double)num_bytes/(double)num_insns;
        bpi = (double)num_bytes/(double)num_insns;
    fprintf(ofp, "%0.6f bytes (%d bits) per instruction\n", bpi, (int)(bpi*8));
    fprintf(ofp, "%0.6f bytes (%d bits) per instruction\n", bpi, (int)(bpi*8));
        nc2 = (float)num_cinsns * 2.0;
        nc2 = (float)num_cinsns * 2.0;
        fprintf(ofp, "Compression ratio: %f%%", (nc2 / (num_bytes + nc2)) * 100.0);
        fprintf(ofp, "Compression ratio: %f%%", (nc2 / (num_bytes + nc2)) * 100.0);
 
 
/*
/*
    chksum = 0;
    chksum = 0;
    for (nn = 0; nn < binndx; nn+=4) {
    for (nn = 0; nn < binndx; nn+=4) {
        chksum += binfile[nn] +
        chksum += binfile[nn] +
                  (binfile[nn+1] << 8) +
                  (binfile[nn+1] << 8) +
                  (binfile[nn+2] << 16) +
                  (binfile[nn+2] << 16) +
                  (binfile[nn+3] << 24)
                  (binfile[nn+3] << 24)
                  ;
                  ;
    }
    }
 
 
    fprintf(ofp, "\r\nChecksum: %08X\r\n", chksum);
    fprintf(ofp, "\r\nChecksum: %08X\r\n", chksum);
*/
*/
    if (listing)
    if (listing)
        fclose(ofp);
        fclose(ofp);
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Output binary file.
    // Output binary file.
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    if (binary_out) {
    if (binary_out) {
        if (verbose) printf("Generating binary file.\r\n");
        if (verbose) printf("Generating binary file.\r\n");
        strcpy_s(fname, sizeof(fname), argv[nn]);
        strcpy_s(fname, sizeof(fname), argv[nn]);
        p = strrchr(fname,'.');
        p = strrchr(fname,'.');
        if (p) {
        if (p) {
            *p = '\0';
            *p = '\0';
        }
        }
        strcat_s(fname, sizeof(fname), ".bin");
        strcat_s(fname, sizeof(fname), ".bin");
        fopen_s(&ofp, fname,"wb");
        fopen_s(&ofp, fname,"wb");
        if (ofp) {
        if (ofp) {
            fwrite((void*)sections[0].bytes,sections[0].index,1,ofp);
            fwrite((void*)sections[0].bytes,sections[0].index,1,ofp);
            fwrite((void*)sections[1].bytes,sections[1].index,1,ofp);
            fwrite((void*)sections[1].bytes,sections[1].index,1,ofp);
            //fwrite((void*)sections[2].bytes,sections[2].index,1,ofp);
            //fwrite((void*)sections[2].bytes,sections[2].index,1,ofp);
            //fwrite(binfile,binndx,1,ofp);
            //fwrite(binfile,binndx,1,ofp);
            fclose(ofp);
            fclose(ofp);
        }
        }
        else
        else
            printf("Can't create .bin file.\r\n");
            printf("Can't create .bin file.\r\n");
    }
    }
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Output ELF file.
    // Output ELF file.
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    if (elf_out) {
    if (elf_out) {
        if (verbose) printf("Generating ELF file.\r\n");
        if (verbose) printf("Generating ELF file.\r\n");
        strcpy_s(fname, sizeof(fname), argv[nn]);
        strcpy_s(fname, sizeof(fname), argv[nn]);
        p = strrchr(fname,'.');
        p = strrchr(fname,'.');
        if (p) {
        if (p) {
            *p = '\0';
            *p = '\0';
        }
        }
        if (rel_out)
        if (rel_out)
            strcat_s(fname, sizeof(fname), ".rel");
            strcat_s(fname, sizeof(fname), ".rel");
        else
        else
            strcat_s(fname, sizeof(fname), ".elf");
            strcat_s(fname, sizeof(fname), ".elf");
        fopen_s(&ofp, fname,"wb");
        fopen_s(&ofp, fname,"wb");
        if (ofp) {
        if (ofp) {
            WriteELFFile(ofp);
            WriteELFFile(ofp);
            fclose(ofp);
            fclose(ofp);
        }
        }
        else
        else
            printf("Can't create .elf file.\r\n");
            printf("Can't create .elf file.\r\n");
    }
    }
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Output coe file
    // Output coe file
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    if (coe_out) {
    if (coe_out) {
            if (verbose) printf("Generating COE file.\r\n");
            if (verbose) printf("Generating COE file.\r\n");
            strcpy_s(fname, sizeof(fname), argv[nn]);
            strcpy_s(fname, sizeof(fname), argv[nn]);
            p = strrchr(fname,'.');
            p = strrchr(fname,'.');
            if (p) {
            if (p) {
                *p = '\0';
                *p = '\0';
            }
            }
            strcat_s(fname, sizeof(fname), ".coe");
            strcat_s(fname, sizeof(fname), ".coe");
            fopen_s(&vfp, fname, "w");
            fopen_s(&vfp, fname, "w");
            if (vfp) {
            if (vfp) {
                fprintf(vfp, "memory_initialization_radix=16;\r\n");
                fprintf(vfp, "memory_initialization_radix=16;\r\n");
                fprintf(vfp, "memory_initialization_vector=\r\n");
                fprintf(vfp, "memory_initialization_vector=\r\n");
                for (kk = 0;kk < binndx; kk+=4) {
                for (kk = 0;kk < binndx; kk+=4) {
                        u32 = (binfile[kk+3]<<24)|(binfile[kk+2]<<16)|(binfile[kk+1]<<8)|binfile[kk];
                        u32 = (binfile[kk+3]<<24)|(binfile[kk+2]<<16)|(binfile[kk+1]<<8)|binfile[kk];
                    i64 = ((uint64_t)checkbits(u32) << 32)|(uint64_t)u32;
                    i64 = ((uint64_t)checkbits(u32) << 32)|(uint64_t)u32;
                    fprintf(vfp, "%010I64X,\r\n", i64);
                    fprintf(vfp, "%010I64X,\r\n", i64);
                }
                }
                fprintf(vfp,"000000;\r\n");
                fprintf(vfp,"000000;\r\n");
                fclose(vfp);
                fclose(vfp);
                }
                }
        }
        }
 
 
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Output Verilog memory declaration
    // Output Verilog memory declaration
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    if (verilog_out) {
    if (verilog_out) {
        if (verbose) printf("Generating Verilog file.\r\n");
        if (verbose) printf("Generating Verilog file.\r\n");
        strcpy_s(fname, sizeof(fname), argv[nn]);
        strcpy_s(fname, sizeof(fname), argv[nn]);
        p = strrchr(fname,'.');
        p = strrchr(fname,'.');
        if (p) {
        if (p) {
            *p = '\0';
            *p = '\0';
        }
        }
        strcat_s(fname, sizeof(fname), ".ve0");
        strcat_s(fname, sizeof(fname), ".ve0");
        fopen_s(&vfp, fname, "w");
        fopen_s(&vfp, fname, "w");
        if (vfp) {
        if (vfp) {
                        /*
                        /*
                        if (gCpu=='A') {
                        if (gCpu=='A') {
                                dsd9_VerilogOut(vfp);
                                dsd9_VerilogOut(vfp);
                        }
                        }
            else
            else
                        */
                        */
                        if (gCpu=='F' || gCpu=='G') {
                        if (gCpu=='F' || gCpu=='G') {
                                if (vebits==128) {
                                if (vebits==128) {
                                        for (kk = 0; kk < binndx; kk+=16) {
                                        for (kk = 0; kk < binndx; kk+=16) {
                                                fprintf(vfp, "\trommem[%d] = 128'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
                                                fprintf(vfp, "\trommem[%d] = 128'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
                                                        ((((unsigned int)start_address+kk)/16)%16384), //checksum64((int64_t *)&binfile[kk]),
                                                        ((((unsigned int)start_address+kk)/16)%16384), //checksum64((int64_t *)&binfile[kk]),
                                                        binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
                                                        binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
                                                        binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
                                                        binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
                                                        binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
                                                        binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
                                                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
                                                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
                                        }
                                        }
                                }
                                }
                                else if (vebits==64) {
                                else if (vebits==64) {
                                        for (kk = 0; kk < binndx; kk+=8) {
                                        for (kk = 0; kk < binndx; kk+=8) {
                                                fprintf(vfp, "\trommem[%d] = 64'h%02X%02X%02X%02X%02X%02X%02X%02X;\n",
                                                fprintf(vfp, "\trommem[%d] = 64'h%02X%02X%02X%02X%02X%02X%02X%02X;\n",
                                                        ((((unsigned int)start_address+kk)/8)%16384), //checksum64((int64_t *)&binfile[kk]),
                                                        ((((unsigned int)start_address+kk)/8)%16384), //checksum64((int64_t *)&binfile[kk]),
                                                        binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
                                                        binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
                                                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
                                                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
                                        }
                                        }
                                }
                                }
            }
            }
                        /*
                        /*
                        else if (gCpu=='G') {
                        else if (gCpu=='G') {
                for (kk = 0; kk < binndx; kk+=32) {
                for (kk = 0; kk < binndx; kk+=32) {
                    fprintf(vfp, "\trommem[%d] = 256'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
                    fprintf(vfp, "\trommem[%d] = 256'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
                                                "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
                                                "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
                        ((((unsigned int)start_address+kk)/32)%16384), //checksum64((int64_t *)&binfile[kk]),
                        ((((unsigned int)start_address+kk)/32)%16384), //checksum64((int64_t *)&binfile[kk]),
                        binfile[kk+31], binfile[kk+30], binfile[kk+29], binfile[kk+28],
                        binfile[kk+31], binfile[kk+30], binfile[kk+29], binfile[kk+28],
                        binfile[kk+27], binfile[kk+26], binfile[kk+25], binfile[kk+24],
                        binfile[kk+27], binfile[kk+26], binfile[kk+25], binfile[kk+24],
                        binfile[kk+23], binfile[kk+22], binfile[kk+21], binfile[kk+20],
                        binfile[kk+23], binfile[kk+22], binfile[kk+21], binfile[kk+20],
                        binfile[kk+19], binfile[kk+18], binfile[kk+17], binfile[kk+16],
                        binfile[kk+19], binfile[kk+18], binfile[kk+17], binfile[kk+16],
                        binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
                        binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
                        binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
                        binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
                        binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
                        binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
                }
                }
            }
            }
                        */
                        */
                        else if (gCpu==64) {
                        else if (gCpu==64) {
                for (kk = 0; kk < binndx; kk+=8) {
                for (kk = 0; kk < binndx; kk+=8) {
                    fprintf(vfp, "\trommem0[%d] = 65'h%01d%02X%02X%02X%02X%02X%02X%02X%02X;\n",
                    fprintf(vfp, "\trommem0[%d] = 65'h%01d%02X%02X%02X%02X%02X%02X%02X%02X;\n",
                        (((0+kk)/8)%16384), checksum64((int64_t *)&binfile[kk]),
                        (((0+kk)/8)%16384), checksum64((int64_t *)&binfile[kk]),
                        binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
                        binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
                }
                }
            }
            }
            else if (gCpu==5) {
            else if (gCpu==5) {
                for (kk = 0;kk < binndx; kk+=4) {
                for (kk = 0;kk < binndx; kk+=4) {
                        u32 = (binfile[kk+3]<<24)|(binfile[kk+2]<<16)|(binfile[kk+1]<<8)|binfile[kk];
                        u32 = (binfile[kk+3]<<24)|(binfile[kk+2]<<16)|(binfile[kk+1]<<8)|binfile[kk];
                    i64 = (uint64_t)u32;
                    i64 = (uint64_t)u32;
                    fprintf(vfp, "\trommem[%d] = 32'h%08I64X;\n",
                    fprintf(vfp, "\trommem[%d] = 32'h%08I64X;\n",
                        (int)(((start_address+kk)/4)%32768), i64);
                        (int)(((start_address+kk)/4)%32768), i64);
                }
                }
            }
            }
                        else if (gCpu=='A') {
                        else if (gCpu=='A') {
                for (kk = 0; kk < binndx; kk+=16) {
                for (kk = 0; kk < binndx; kk+=16) {
                    fprintf(vfp, "\trommem[%d] = 128'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
                    fprintf(vfp, "\trommem[%d] = 128'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
                        (((0+kk)/16)%16384),
                        (((0+kk)/16)%16384),
                        binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
                        binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
                        binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
                        binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
                        binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
                        binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
                }
                }
                                if (kk != binndx)
                                if (kk != binndx)
                    fprintf(vfp, "\trommem[%d] = 128'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
                    fprintf(vfp, "\trommem[%d] = 128'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
                        (((0+kk)/16)%16384),
                        (((0+kk)/16)%16384),
                        binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
                        binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
                        binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
                        binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
                        binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
                        binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
            }
            }
            else {
            else {
                for (kk = 0;kk < binndx; kk+=4) {
                for (kk = 0;kk < binndx; kk+=4) {
                        u32 = (binfile[kk+3]<<24)|(binfile[kk+2]<<16)|(binfile[kk+1]<<8)|binfile[kk];
                        u32 = (binfile[kk+3]<<24)|(binfile[kk+2]<<16)|(binfile[kk+1]<<8)|binfile[kk];
                    i64 = ((uint64_t)checkbits(u32) << 32)|(uint64_t)u32;
                    i64 = ((uint64_t)checkbits(u32) << 32)|(uint64_t)u32;
                    fprintf(vfp, "\trommem0[%d] = 39'h%010I64X;\n",
                    fprintf(vfp, "\trommem0[%d] = 39'h%010I64X;\n",
                        (int)(((0+kk)/4)%32768), i64);
                        (int)(((0+kk)/4)%32768), i64);
                }
                }
            }
            }
            fclose(vfp);
            fclose(vfp);
        }
        }
        else
        else
            printf("Can't create .ver file.\r\n");
            printf("Can't create .ver file.\r\n");
        strcpy_s(fname, sizeof(fname), argv[nn]);
        strcpy_s(fname, sizeof(fname), argv[nn]);
        p = strrchr(fname,'.');
        p = strrchr(fname,'.');
        if (p) {
        if (p) {
            *p = '\0';
            *p = '\0';
        }
        }
        strcat_s(fname, sizeof(fname), ".ve1");
        strcat_s(fname, sizeof(fname), ".ve1");
        fopen_s(&vfp, fname, "w");
        fopen_s(&vfp, fname, "w");
        if (vfp) {
        if (vfp) {
            if (gCpu==64) {
            if (gCpu==64) {
                for (kk = 0; kk < binndx; kk+=8) {
                for (kk = 0; kk < binndx; kk+=8) {
                    fprintf(vfp, "\trommem1[%d] = 65'h%01d%02X%02X%02X%02X%02X%02X%02X%02X;\n",
                    fprintf(vfp, "\trommem1[%d] = 65'h%01d%02X%02X%02X%02X%02X%02X%02X%02X;\n",
                        (((0+kk)/8)%16384), checksum64((int64_t *)&binfile[kk]),
                        (((0+kk)/8)%16384), checksum64((int64_t *)&binfile[kk]),
                        binfile[kk+7]^0xAA, binfile[kk+6], binfile[kk+5], binfile[kk+4],
                        binfile[kk+7]^0xAA, binfile[kk+6], binfile[kk+5], binfile[kk+4],
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
                }
                }
            }
            }
            else {
            else {
                for (kk = 0;kk < binndx; kk+=4) {
                for (kk = 0;kk < binndx; kk+=4) {
                    fprintf(vfp, "\trommem1[%d] = 32'h%02X%02X%02X%02X;\n",
                    fprintf(vfp, "\trommem1[%d] = 32'h%02X%02X%02X%02X;\n",
                        (((start_address+kk)/4)%32768), binfile[kk+3]^0xAA, binfile[kk+2]^0xAA, binfile[kk+1]^0xAA, binfile[kk]^0xAA);
                        (((start_address+kk)/4)%32768), binfile[kk+3]^0xAA, binfile[kk+2]^0xAA, binfile[kk+1]^0xAA, binfile[kk]^0xAA);
                }
                }
            }
            }
            fclose(vfp);
            fclose(vfp);
        }
        }
        else
        else
            printf("Can't create .ver file.\r\n");
            printf("Can't create .ver file.\r\n");
        strcpy_s(fname, sizeof(fname), argv[nn]);
        strcpy_s(fname, sizeof(fname), argv[nn]);
        p = strrchr(fname,'.');
        p = strrchr(fname,'.');
        if (p) {
        if (p) {
            *p = '\0';
            *p = '\0';
        }
        }
        strcat_s(fname, sizeof(fname), ".ve2");
        strcat_s(fname, sizeof(fname), ".ve2");
        fopen_s(&vfp, fname, "w");
        fopen_s(&vfp, fname, "w");
        if (vfp) {
        if (vfp) {
            if (gCpu==64) {
            if (gCpu==64) {
                for (kk = 0; kk < binndx; kk+=8) {
                for (kk = 0; kk < binndx; kk+=8) {
                    fprintf(vfp, "\trommem2[%d] = 65'h%01d%02X%02X%02X%02X%02X%02X%02X%02X;\n",
                    fprintf(vfp, "\trommem2[%d] = 65'h%01d%02X%02X%02X%02X%02X%02X%02X%02X;\n",
                        (((0+kk)/8)%16384), checksum64((int64_t *)&binfile[kk]),
                        (((0+kk)/8)%16384), checksum64((int64_t *)&binfile[kk]),
                        binfile[kk+7]^0x55, binfile[kk+6], binfile[kk+5], binfile[kk+4],
                        binfile[kk+7]^0x55, binfile[kk+6], binfile[kk+5], binfile[kk+4],
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
                }
                }
            }
            }
            else {
            else {
                for (kk = 0;kk < binndx; kk+=4) {
                for (kk = 0;kk < binndx; kk+=4) {
                    fprintf(vfp, "\trommem2[%d] = 32'h%02X%02X%02X%02X;\n",
                    fprintf(vfp, "\trommem2[%d] = 32'h%02X%02X%02X%02X;\n",
                        (((start_address+kk)/4)%32768), binfile[kk+3]^0x55, binfile[kk+2]^0x55, binfile[kk+1]^0x55, binfile[kk]^0x55);
                        (((start_address+kk)/4)%32768), binfile[kk+3]^0x55, binfile[kk+2]^0x55, binfile[kk+1]^0x55, binfile[kk]^0x55);
                }
                }
            }
            }
            fclose(vfp);
            fclose(vfp);
        }
        }
        else
        else
            printf("Can't create .ver file.\r\n");
            printf("Can't create .ver file.\r\n");
    }
    }
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Output Verilog memory declaration
    // Output Verilog memory declaration
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        if (verbose) printf("Generating Text file.\r\n");
        if (verbose) printf("Generating Text file.\r\n");
        strcpy_s(fname, sizeof(fname), argv[nn]);
        strcpy_s(fname, sizeof(fname), argv[nn]);
        p = strrchr(fname,'.');
        p = strrchr(fname,'.');
        if (p) {
        if (p) {
            *p = '\0';
            *p = '\0';
        }
        }
        strcat_s(fname, sizeof(fname), ".txt");
        strcat_s(fname, sizeof(fname), ".txt");
        printf("fname:%s\r\n", fname);
        printf("fname:%s\r\n", fname);
        fopen_s(&vfp, fname, "w");
        fopen_s(&vfp, fname, "w");
        if (vfp) {
        if (vfp) {
            if (gCpu==64) {
            if (gCpu==64) {
                for (kk = 0; kk < binndx; kk+=4) {
                for (kk = 0; kk < binndx; kk+=4) {
                    fprintf(vfp, "%06X,%02X%02X%02X%02X\n",
                    fprintf(vfp, "%06X,%02X%02X%02X%02X\n",
                        (((start_address+kk))),
                        (((start_address+kk))),
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
                }
                }
            }
            }
            fclose(vfp);
            fclose(vfp);
        }
        }
        else
        else
            printf("Can't create .txt file.\r\n");
            printf("Can't create .txt file.\r\n");
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Output Intel hex file
    // Output Intel hex file
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        if (verbose) printf("Generating Hex file.\r\n");
        if (verbose) printf("Generating Hex file.\r\n");
        strcpy_s(fname, sizeof(fname), argv[nn]);
        strcpy_s(fname, sizeof(fname), argv[nn]);
        p = strrchr(fname,'.');
        p = strrchr(fname,'.');
        if (p) {
        if (p) {
            *p = '\0';
            *p = '\0';
        }
        }
        lsa = 0;
        lsa = 0;
        strcat_s(fname, sizeof(fname), ".hex");
        strcat_s(fname, sizeof(fname), ".hex");
        printf("fname:%s\r\n", fname);
        printf("fname:%s\r\n", fname);
        fopen_s(&vfp, fname, "w");
        fopen_s(&vfp, fname, "w");
        if (vfp) {
        if (vfp) {
            if (gCpu==64||gCpu=='F'||gCpu=='G') {
            if (gCpu==64||gCpu=='F'||gCpu=='G') {
                for (kk = 0; kk < binndx; kk+=4) {
                for (kk = 0; kk < binndx; kk+=4) {
                    if (lsa != (start_address + kk) >> 16) {
                    if (lsa != (start_address + kk) >> 16) {
                        sprintf_s(hexbuf, sizeof(hexbuf), ":02000004%04X00\n", (int)((start_address+kk) >> 16));
                        sprintf_s(hexbuf, sizeof(hexbuf), ":02000004%04X00\n", (int)((start_address+kk) >> 16));
                        IHChecksum(hexbuf, 2);
                        IHChecksum(hexbuf, 2);
                        fprintf(vfp, hexbuf);
                        fprintf(vfp, hexbuf);
                        lsa = (start_address+kk) >> 16;
                        lsa = (start_address+kk) >> 16;
                    }
                    }
                    sprintf_s(hexbuf, sizeof(hexbuf), ":%02X%04X00%02X%02X%02X%02X\n",
                    sprintf_s(hexbuf, sizeof(hexbuf), ":%02X%04X00%02X%02X%02X%02X\n",
                        4, (int)(start_address + kk) & 0xFFFF,
                        4, (int)(start_address + kk) & 0xFFFF,
                        binfile[kk], binfile[kk+1], binfile[kk+2], binfile[kk+3]
                        binfile[kk], binfile[kk+1], binfile[kk+2], binfile[kk+3]
                    );
                    );
                    IHChecksum(hexbuf, 4);
                    IHChecksum(hexbuf, 4);
                    fprintf(vfp, hexbuf);
                    fprintf(vfp, hexbuf);
                }
                }
            }
            }
            else if (gCpu==4) {
            else if (gCpu==4) {
                for (kk = 0; kk < binndx; kk+=8) {
                for (kk = 0; kk < binndx; kk+=8) {
                    if (lsa != (start_address + kk) >> 16) {
                    if (lsa != (start_address + kk) >> 16) {
                        sprintf_s(hexbuf, sizeof(hexbuf), ":02000004%04X00\n", (int)((start_address+kk) >> 16));
                        sprintf_s(hexbuf, sizeof(hexbuf), ":02000004%04X00\n", (int)((start_address+kk) >> 16));
                        IHChecksum(hexbuf, 2);
                        IHChecksum(hexbuf, 2);
                        fprintf(vfp, hexbuf);
                        fprintf(vfp, hexbuf);
                        lsa = (start_address+kk) >> 16;
                        lsa = (start_address+kk) >> 16;
                    }
                    }
                    sprintf_s(hexbuf, sizeof(hexbuf), ":%02X%04X00%02X%02X%02X%02X%02X%02X%02X%02X\n",
                    sprintf_s(hexbuf, sizeof(hexbuf), ":%02X%04X00%02X%02X%02X%02X%02X%02X%02X%02X\n",
                        8, (start_address + kk) & 0xFFFF,
                        8, (start_address + kk) & 0xFFFF,
                        binfile[kk], binfile[kk+1], binfile[kk+2],binfile[kk+3],
                        binfile[kk], binfile[kk+1], binfile[kk+2],binfile[kk+3],
                        binfile[kk+4],binfile[kk+5],binfile[kk+6],binfile[kk+7]
                        binfile[kk+4],binfile[kk+5],binfile[kk+6],binfile[kk+7]
                    );
                    );
                    IHChecksum(hexbuf, 8);
                    IHChecksum(hexbuf, 8);
                    fprintf(vfp, hexbuf);
                    fprintf(vfp, hexbuf);
                }
                }
            }
            }
            fprintf(vfp, ":00000001FF\n%c",26);        // end of file record
            fprintf(vfp, ":00000001FF\n%c",26);        // end of file record
            fclose(vfp);
            fclose(vfp);
        }
        }
        else
        else
            printf("Can't create .hex file.\r\n");
            printf("Can't create .hex file.\r\n");
        delete[] masterFile;
        delete[] masterFile;
  return (0);
  return (0);
}
}
 
 
bool IsNBit(int64_t val, int64_t n)
bool IsNBit(int64_t val, int64_t n)
{
{
        int64_t low, high;
        int64_t low, high;
 
 
        low = -(1LL << (n - 1LL));
        low = -(1LL << (n - 1LL));
        high = (1LL << (n - 1LL));
        high = (1LL << (n - 1LL));
        return (val >= low && val < high);
        return (val >= low && val < high);
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.