home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource3 / 149_01 / a68util.c < prev    next >
Text File  |  1989-01-13  |  17KB  |  588 lines

  1. /*
  2.     HEADER:        CUG149;
  3.     TITLE:        6801 Cross-Assembler (Portable);
  4.     FILENAME:    A68UTIL.C;
  5.     VERSION:    3.5;
  6.     DATE:        08/27/1988;
  7.  
  8.     DESCRIPTION:    "This program lets you use your computer to assemble
  9.             code for the Motorola 6800, 6801, 6802, 6803, 6808,
  10.             and 68701 microprocessors.  The program is written in
  11.             portable C rather than BDS C.  All assembler features
  12.             are supported except relocation, linkage, and macros.";
  13.  
  14.     KEYWORDS:    Software Development, Assemblers, Cross-Assemblers,
  15.             Motorola, MC6800, MC6801;
  16.  
  17.     SEE-ALSO:    CUG113, 6800 Cross-Assembler;
  18.  
  19.     SYSTEM:        CP/M-80, CP/M-86, HP-UX, MSDOS, PCDOS, QNIX;
  20.     COMPILERS:    Aztec C86, Aztec CII, CI-C86, Eco-C, Eco-C88, HP-UX,
  21.             Lattice C, Microsoft C,    QNIX C;
  22.  
  23.     WARNINGS:    "This program has compiled successfully on 2 UNIX
  24.             compilers, 5 MSDOS compilers, and 2 CP/M compilers.
  25.             A port to BDS C would be extremely difficult, but see
  26.             volume CUG113.  A port to Toolworks C is untried."
  27.  
  28.     AUTHORS:    William C. Colley III;
  29. */
  30.  
  31. /*
  32.               6801 Cross-Assembler in Portable C
  33.  
  34.            Copyright (c) 1985 William C. Colley, III
  35.  
  36. Revision History:
  37.  
  38. Ver    Date        Description
  39.  
  40. 3.0    APR 1985    Recoded from BDS C version 2.5.  WCC3.
  41.  
  42. 3.1    AUG 1985    Greatly shortened the routines find_symbol() and
  43.             new_symbol().  Fixed bugs in expression evaluator.
  44.             Added compilation instructions for Aztec C86,
  45.             Microsoft C, and QNIX C.  Added optional optimizations
  46.             for 16-bit machines.  Adjusted structure members for
  47.             fussy compilers.  WCC3.
  48.  
  49. 3.2    SEP 1985    Added the INCL pseudo-op and associated stuff.  WCC3.
  50.  
  51. 3.3    JUL 1986    Added compilation instructions and tweaks for CI-C86,
  52.             Eco-C88, and Lattice C.  WCC3.
  53.  
  54. 3.4    JAN 1987    Fixed bug that made "FCB 0," legal syntax.  WCC3.
  55.  
  56. 3.5    AUG 1988    Fixed a bug in the command line parser that puts it
  57.             into a VERY long loop if the user types a command line
  58.             like "A68 FILE.ASM -L".  WCC3 per Alex Cameron.
  59.  
  60. This module contains the following utility packages:
  61.  
  62.     1)  symbol table building and searching
  63.  
  64.     2)  opcode and operator table searching
  65.  
  66.     3)  listing file output
  67.  
  68.     4)  hex file output
  69.  
  70.     5)  error flagging
  71. */
  72.  
  73. /*  Get global goodies:  */
  74.  
  75. #include "a68.h"
  76.  
  77. /*  Make sure that MSDOS compilers using the large memory model know    */
  78. /*  that calloc() returns pointer to char as an MSDOS far pointer is    */
  79. /*  NOT compatible with the int type as is usually the case.        */
  80.  
  81. char *calloc();
  82.  
  83. /*  Get access to global mailboxes defined in A68.C:            */
  84.  
  85. extern char errcode, line[], title[];
  86. extern int eject, listhex;
  87. extern unsigned address, bytes, errors, listleft, obj[], pagelen;
  88.  
  89. /*  The symbol table is a binary tree of variable-length blocks drawn    */
  90. /*  from the heap with the calloc() function.  The root pointer lives    */
  91. /*  here:                                */
  92.  
  93. static SYMBOL *sroot = NULL;
  94.  
  95. /*  Add new symbol to symbol table.  Returns pointer to symbol even if    */
  96. /*  the symbol already exists.  If there's not enough memory to store    */
  97. /*  the new symbol, a fatal error occurs.                */
  98.  
  99. SYMBOL *new_symbol(nam)
  100. char *nam;
  101. {
  102.     SCRATCH int i;
  103.     SCRATCH SYMBOL **p, *q;
  104.     void fatal_error();
  105.  
  106.     for (p = &sroot; (q = *p) && (i = strcmp(nam,q -> sname)); )
  107.     p = i < 0 ? &(q -> left) : &(q -> right);
  108.     if (!q) {
  109.     if (!(*p = q = (SYMBOL *)calloc(1,sizeof(SYMBOL) + strlen(nam))))
  110.         fatal_error(SYMBOLS);
  111.     strcpy(q -> sname,nam);
  112.     }
  113.     return q;
  114. }
  115.  
  116. /*  Look up symbol in symbol table.  Returns pointer to symbol or NULL    */
  117. /*  if symbol not found.                        */
  118.  
  119. SYMBOL *find_symbol(nam)
  120. char *nam;
  121. {
  122.     SCRATCH int i;
  123.     SCRATCH SYMBOL *p;
  124.  
  125.     for (p = sroot; p && (i = strcmp(nam,p -> sname));
  126.     p = i < 0 ? p -> left : p -> right);
  127.     return p;
  128. }
  129.  
  130. /*  Opcode table search routine.  This routine pats down the opcode    */
  131. /*  table for a given opcode and returns either a pointer to it or    */
  132. /*  NULL if the opcode doesn't exist.                    */
  133.  
  134. OPCODE *find_code(nam)
  135. char *nam;
  136. {
  137.     OPCODE *bsearch();
  138.  
  139.     static OPCODE opctbl[] = {
  140.     { NULL,                    0x1b,    "ABA"    },
  141.     { IS6801,                0x3a,    "ABX"    },
  142.     { DIROK + INDEX + IMM8 + REGREQ,    0x89,    "ADC"    },
  143.     { DIROK + INDEX + IMM8,            0x89,    "ADCA"    },
  144.     { DIROK + INDEX + IMM8,            0xc9,    "ADCB"    },
  145.     { DIROK + INDEX + IMM8 + REGREQ,    0x8b,    "ADD"    },
  146.     { DIROK + INDEX + IMM8,            0x8b,    "ADDA"    },
  147.     { DIROK + INDEX + IMM8,            0xcb,    "ADDB"    },
  148.     { IS6801 + DIROK + INDEX + IMM16,    0xc3,    "ADDD"    },
  149.     { DIROK + INDEX + IMM8 + REGREQ,    0x84,    "AND"    },
  150.     { DIROK + INDEX + IMM8,            0x84,    "ANDA"    },
  151.     { DIROK + INDEX + IMM8,            0xc4,    "ANDB"    },
  152.     { INDEX + REGOPT,            0x48,    "ASL"    },
  153.     { NULL,                    0x48,    "ASLA"    },
  154.     { NULL,                    0x58,    "ASLB"    },
  155.     { IS6801,                0x05,    "ASLD"    },
  156.     { INDEX + REGOPT,            0x47,    "ASR"    },
  157.     { NULL,                    0x47,    "ASRA"    },
  158.     { NULL,                    0x57,    "ASRB"    },
  159.     { REL,                    0x24,    "BCC"    },
  160.     { REL,                    0x25,    "BCS"    },
  161.     { REL,                    0x27,    "BEQ"    },
  162.     { REL,                    0x2c,    "BGE"    },
  163.     { REL,                    0x2e,    "BGT"    },
  164.     { REL,                    0x22,    "BHI"    },
  165.     { REL,                    0x24,    "BHS"    },
  166.     { DIROK + INDEX + IMM8 + REGREQ,    0x85,    "BIT"    },
  167.     { DIROK + INDEX + IMM8,            0x85,    "BITA"    },
  168.     { DIROK + INDEX + IMM8,            0xc5,    "BITB"    },
  169.     { REL,                    0x2f,    "BLE"    },
  170.     { REL,                    0x25,    "BLO"    },
  171.     { REL,                    0x23,    "BLS"    },
  172.     { REL,                    0x2d,    "BLT"    },
  173.     { REL,                    0x2b,    "BMI"    },
  174.     { REL,                    0x26,    "BNE"    },
  175.     { REL,                    0x2A,    "BPL"    },
  176.     { REL,                    0x20,    "BRA"    },
  177.     { IS6801 + REL,                0x21,    "BRN"    },
  178.     { REL,                    0x8d,    "BSR"    },
  179.     { REL,                    0x28,    "BVC"    },
  180.     { REL,                    0x29,    "BVS"    },
  181.     { NULL,                    0x11,    "CBA"    },
  182.     { NULL,                    0x0c,    "CLC"    },
  183.     { NULL,                    0x0e,    "CLI"    },
  184.     { INDEX + REGOPT,            0x4f,    "CLR"    },
  185.     { NULL,                    0x4f,    "CLRA"    },
  186.     { NULL,                    0x5f,    "CLRB"    },
  187.     { NULL,                    0x0a,    "CLV"    },
  188.     { DIROK + INDEX + IMM8 + REGREQ,    0x81,    "CMP"    },
  189.     { DIROK + INDEX + IMM8,            0x81,    "CMPA"    },
  190.     { DIROK + INDEX + IMM8,            0xc1,    "CMPB"    },
  191.     { INDEX + REGOPT,            0x43,    "COM"    },
  192.     { NULL,                    0x43,    "COMA"    },
  193.     { NULL,                    0x53,    "COMB"    },
  194.     { PSEUDO,                CPU,    "CPU"    },
  195.     { DIROK + INDEX + IMM16,        0x8c,    "CPX"    },
  196.     { NULL,                    0x19,    "DAA"    },
  197.     { INDEX + REGOPT,            0x4a,    "DEC"    },
  198.     { NULL,                    0x4a,    "DECA"    },
  199.     { NULL,                    0x5a,    "DECB"    },
  200.     { NULL,                    0x34,    "DES"    },
  201.     { NULL,                    0x09,    "DEX"    },
  202.     { PSEUDO + ISIF,            ELSE,    "ELSE"    },
  203.     { PSEUDO,                END,    "END"    },
  204.     { PSEUDO + ISIF,            ENDI,    "ENDI"    },
  205.     { DIROK + INDEX + IMM8 + REGREQ,    0x88,    "EOR"    },
  206.     { DIROK + INDEX + IMM8,            0x88,    "EORA"    },
  207.     { DIROK + INDEX + IMM8,            0xc8,    "EORB"    },
  208.     { PSEUDO,                EQU,    "EQU"    },
  209.     { PSEUDO,                FCB,    "FCB"    },
  210.     { PSEUDO,                FCC,    "FCC"    },
  211.     { PSEUDO,                FDB,    "FDB"    },
  212.     { PSEUDO + ISIF,            IF,    "IF"    },
  213.     { INDEX + REGOPT,            0x4c,    "INC"    },
  214.     { NULL,                    0x4c,    "INCA"    },
  215.     { NULL,                    0x5c,    "INCB"    },
  216.     { PSEUDO,                INCL,    "INCL"    },
  217.     { NULL,                    0x31,    "INS"    },
  218.     { NULL,                    0x08,    "INX"    },
  219.     { INDEX,                0x4e,    "JMP"    },
  220.     { INDEX,                0x8d,    "JSR"    },
  221.     { DIROK + INDEX + IMM8 + REGREQ,    0x86,    "LDA"    },
  222.     { DIROK + INDEX + IMM8,            0x86,    "LDAA"    },
  223.     { DIROK + INDEX + IMM8,            0xc6,    "LDAB"    },
  224.     { IS6801 + DIROK + INDEX + IMM16,    0xcc,    "LDD"    },
  225.     { DIROK + INDEX + IMM16,        0x8e,    "LDS"    },
  226.     { DIROK + INDEX + IMM16,        0xce,    "LDX"    },
  227.     { INDEX + REGOPT,            0x48,    "LSL"    },
  228.     { NULL,                    0x48,    "LSLA"    },
  229.     { NULL,                    0x58,    "LSLB"    },
  230.     { IS6801,                0x05,    "LSLD"    },
  231.     { INDEX + REGOPT,            0x44,    "LSR"    },
  232.     { NULL,                    0x44,    "LSRA"    },
  233.     { NULL,                    0x54,    "LSRB"    },
  234.     { IS6801,                0x04,    "LSRD"    },
  235.     { IS6801,                0x3d,    "MUL"    },
  236.     { INDEX + REGOPT,            0x40,    "NEG"    },
  237.     { NULL,                    0x40,    "NEGA"    },
  238.     { NULL,                    0x50,    "NEGB"    },
  239.     { NULL,                    0x01,    "NOP"    },
  240.     { DIROK + INDEX + IMM8 + REGREQ,    0x8a,    "ORA"    },
  241.     { DIROK + INDEX + IMM8,            0x8a,    "ORAA"    },
  242.     { DIROK + INDEX + IMM8,            0xca,    "ORAB"    },
  243.     { PSEUDO,                ORG,    "ORG"    },
  244.     { PSEUDO,                PAGE,    "PAGE"    },
  245.     { REGREQ,                0x36,    "PSH"    },
  246.     { NULL,                    0x36,    "PSHA"    },
  247.     { NULL,                    0x37,    "PSHB"    },
  248.     { IS6801,                0x3c,    "PSHX"    },
  249.     { REGREQ,                0x32,    "PUL"    },
  250.     { NULL,                    0x32,    "PULA"    },
  251.     { NULL,                    0x33,    "PULB"    },
  252.     { IS6801,                0x38,    "PULX"    },
  253.     { PSEUDO,                RMB,    "RMB"    },
  254.     { INDEX + REGOPT,            0x49,    "ROL"    },
  255.     { NULL,                    0x49,    "ROLA"    },
  256.     { NULL,                    0x59,    "ROLB"    },
  257.     { INDEX + REGOPT,            0x46,    "ROR"    },
  258.     { NULL,                    0x46,    "RORA"    },
  259.     { NULL,                    0x56,    "RORB"    },
  260.     { NULL,                    0x3b,    "RTI"    },
  261.     { NULL,