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

Subversion Repositories rf6809

[/] [rf6809/] [trunk/] [software/] [a09/] [a09.c] - Blame information for rev 16

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 robfinch
/* A09, 6809 Assembler.
2
 
3
   (C) Copyright 1993,1994 L.C. Benschop.
4
   Parts (C) Copyright 2001-2010 H. Seib.
5
   Mods for 12-bit FPGA core 6809 by R. Finch
6
 
7
   This version of the program is distributed under the terms and conditions
8
   of the GNU General Public License version 2. See file the COPYING for details.
9
   THERE IS NO WARRANTY ON THIS PROGRAM.
10
 
11
   Generates binary image file from the lowest to
12
   the highest address with actually assembled data.
13
 
14
   Machine dependencies:
15
                  char is 8 bits.
16
                  short is 16 bits.
17
                  integer arithmetic is twos complement.
18
 
19
   syntax:
20
     a09 [-{b|r|s|x|f}filename]|[-c] [-lfilename] [-ooption] [-dsym=value]* sourcefile.
21
 
22
   Options
23
   -Vfilename    Verilog rommem declaration output
24
   -c suppresses code output
25
   -bfilename    binary output file name (default name minus a09 suffix plus .bin)
26
   -rfilename    Flex9 RELASMB-compatible output file name (relocatable)
27
   -sfilename    s-record output file name (default its a binary file)
28
   -xfilename    intel hex output file name (-"-)
29
   -ffilename    Flex9 output file name (-"-)
30
   -lfilename    list file name (default no listing)
31
   -dsym[=value] define a symbol
32
   -oopt defines an option
33
 
34
   recognized pseudoops:
35
    ext        defines an external symbol (relocating mode only)
36
    extern     -"-
37
    public     defines a public symbol (effective in relocating mode only)
38
    macro      defines a macro
39
    exitm      terminates a macro expansion
40
    endm       ends a macro definition
41
    if
42
    ifn
43
    ifc
44
    ifnc
45
    else
46
    endif
47
    dup
48
    endd
49
    org
50
    equ
51
    set
52
    setdp      sets direct page in 6809 / 6309 mode
53
    text
54
    fcb
55
    fcw
56
    fdb
57
    fcc
58
    rmb
59
    reg
60
    end
61
    include
62
    title
63
    nam
64
    ttl
65
    sttl
66
    setpg
67
    pag
68
    spc
69
    rep
70
    rpt
71
    repeat
72
    opt        define an option (see below for possible options)
73
    err
74
    abs        force absolute mode
75
    common
76
    endcom
77
    def
78
    define
79
    enddef
80
    name
81
    symlen
82
    bin, binary includes a binary file at the current position
83
 
84
   recognized options:
85
     On | Off         Meaning
86
    ------------------------------------------------------------
87
    PAG | NOP*        Page Formatting
88
    CON | NOC*        Print skipped conditional code
89
    MAC*| NOM         Print macro calling line
90
    EXP | NOE*        Print macro expansion lines
91
    SYM*| NOS         Print symbol table
92
    MUL*| NMU         Print multiple object code lines
93
    LIS*| NOL         Print assembler listing
94
    LP1 | NO1*        Print Pass 1 Listing
95
    DAT*| NOD         Print date in listing
96
    NUM | NON*        Print line numbers
97
    INV | NOI*        Print invisible lines
98
    TSC | NOT*        Strict TSC Compatibility
99
    WAR*| NOW         Print warnings
100
    CLL*| NCL         Check line length
101
    LFN | NLF*        Print long file names
102
    LLL*| NLL         List library lines
103
    GAS | NOG*        Gnu AS source style compatibility
104
    REL*| NOR         Print Relocation table in Relocating mode
105
    M68*| H63 | M00   MC6809 / HD6309 / MC6800 mode
106
    TXT | NTX*        Print text table
107
    LPA | LNP*        Listing in f9dasm patch format
108
    * denotes default value
109
 
110
 
111
   v0.1 93/11/03 Initial version.
112
 
113
   v0.2 94/03/21 Fixed PC relative addressing bug
114
                 Added SET, SETDP, INCLUDE. IF/ELSE/ENDIF
115
                 No macros yet, and no separate linkable modules.
116
 
117
   v0.1.X 99/12/20 added Intel hex option (SLB)
118
 
119
-- H.Seib Additions: --
120
 
121
   v0.2.S 01/10/13 converted to readable format
122
   v0.3   01/10/15 added transfer address processing
123
                   increased max. #symbols and other constants
124
                     (hey, this isn't CP/M anymore :-)
125
                   added a bit of intelligence to command line processing
126
                   loads file(s) into internal storage prior to processing
127
                     (this aids a lot in preventing recursive invocations)
128
                   added LIB,LIBRARY pseudoop (same as INCLUDE)
129
                   added OPT,OPTION pseudoop
130
   v0.4   01/10/22 added -t switch to increase compatibility with the
131
                   TSC FLEX Assembler line, which uses a slightly more
132
                   rigid source file format
133
   v0.5   01/10/23 added SETPG, SETLI, PAG, SPC, NAM(TTL,TITLE), STTL, REP(RPT,REPEAT)
134
   v0.6   01/10/23 added EXITM, IFN, IFC, IFNC, DUP, ENDD
135
   v0.7   01/10/29 added REG, ERR, TEXT
136
   v0.8   01/10/30 converted command line handling to -O switch for options
137
                   and added a bunch of options
138
                   RZB pseudoop added
139
   v0.9   01/11/05 clean-ups, increased TSC FLEX Assembler compatibility
140
   v0.10  01/11/15 ASM and VERSION texts predefined
141
   v0.11  01/11/27 increased TSC FLEX Assembler compatibility (labels made case sensitive)
142
   v0.12  01/11/28 added some convenience mnemonics and simulated 6800 instructions to
143
                   increase TSC FLEX Assembler compatibility
144
   v1.02  01/04/11 check for address range overlaps implemented
145
   v1.03  02/09/24 macro parser had an error; corrected
146
   v1.04  02/12/10 error message output adjusted for Visual C++ 6.0 IDE compatibility
147
                   added OPT LFN/NLF for that purpose
148
   v1.05  02/12/23 crude form of backwards ORG added to binary output
149
   v1.06  03/06/10 added OPT LLL/NLL to include/suppress listing of LIB lines
150
   v1.07  03/06/23 outsymtable() only starts with a page feed if current line
151
                   is is NOT the first line on a page
152
   v1.08  03/07/01 SKIP count for the IF(N) and IF(N)C statements added to
153
                   normal statements (i.e., outside macro definitions)
154
   v1.09  05/06/02 some cleanups
155
                   added -r format for FLEX9 RELASMB compatible output
156
                   added ABS, GLOBAL, EXT, DEFINE, ENDDEF, COMMON, ENDCOM
157
                   REL|NOR option added
158
                   GAS|NOG option added (rudimentary)
159
                   M68|H63 option added
160
   v1.10  05/06/03 made options available as numeric strings
161
                   added local label support
162
                   added SYMLEN
163
                   TXT|NTX option added
164
   v1.11  05/06/06 IFD/IFND directives added
165
                   added special checks for "0,-[-]indexreg" and "0,indexreg+[+]"
166
                   when determining the postbyte for indexed addressing modes
167
   v1.12  05/06/20 OPT CON|NOC correctly implemented
168
   v1.13           skipped for users that might have an uneasy feeling about
169
                   the number "13" >:-)
170
   v1.14  05/08/01 text symbol replacement enhanced; it was a bit TOO general.
171
                   Now, &xxx is only treated as a text variable when xxx REALLY
172
                   is a text symbol; in all other cases, it's not preprocessed.
173
                   Let the assembler engine handle eventual errors.
174
                   Thanks to Peter from Australia for pointing this out!
175
   v1.15  05/08/02 only 1 local label was allowed per address; now, as many as
176
                   possible can be at the same location.
177
                   Thanks to Peter from Australia for pointing this out!
178
   v1.16  05/08/05 SETDP is illegal in relocating mode!
179
                   SETDP without any parameter DISABLES Direct mode entirely.
180
                   Cured an interesting bug... the following sequence:
181
                              ORG 1
182
                              LDA TEST
183
                       SHIT   NOP
184
                              ORG 1
185
                       TEST   RMB 1
186
                   caused a phase error; this was caused by the invalid
187
                   assumption in scanlabel() that forward references have
188
                   a higher memory location than the current address.
189
                   Thanks to Peter from Australia for pointing this out!
190
   v1.17  08/08/05 made tests for above problem more rigorous; now ANY forward
191
                   reference to a label that's not yet defined is treated as
192
                   uncertain.
193
                   Removed a nasty bug that caused the following code to produce
194
                   incorrect values:
195
                            org $8000  (anything >= $8000 will do)
196
                         lbl rmb 8
197
                         SizeBad equ (*-lbl)/2
198
                   OPT NOL changed to OPT NO1 to allow implementing OPT LIS|NOL.
199
                   OPT LIS*|NOL added
200
                   Thanks to Peter from Australia for pointing these out!
201
   v1.18  09/08/05 backward search for local labels now searches for "<= local
202
                   address" instead of "< local address"
203
                   Thanks to Peter from Australia for pointing this out!
204
                   Added INCD / DECD convenience mnemonics
205
                   (realized as ADDD/SUBD 1)
206
   v1.19  10/08/05 Added a bunch of 6800-style mnemonics; if they conflict
207
                   with 6809 mnemonics ("INC A" for example), they are only
208
                   active in TSC mode
209
   v1.20  16/08/05 changed special checks for
210
                     "0,-[-]indexreg" and "0,indexreg+[+]"
211
                   to include all known labels and changed the scope to
212
                     ",[-[-]]indexreg[+[+]]"
213
   v1.21  21/02/06 Bug in "xxx  >0,reg" found by Margus Kliimask
214
   v1.22  03/09/08 Addded BIN(ARY) pseudo-op to include binary files
215
   v1.23  13/02/09 6800 code generation added
216
                   accept multiple input files (first one defines default
217
                     output and listing file names)
218
   v1.24  13/02/09 made compilable with gcc
219
   v1.25  05/03/09 6800 alternate mnemonics work better now
220
   v1.26  14/03/09 assembling DOS format files in Loonix works better now
221
   v1.27  20/01/10 LPA/NLP options added
222
   v1.28  21/04/10 INCD/DECD produced invalid code
223
 
224
*/
225
 
226
#include <stdio.h>
227
#include <string.h>
228
#include <ctype.h>
229
#include <malloc.h>
230
#include <stdarg.h>
231
#include <stdlib.h>
232
#include <time.h>
233
 
234
/*****************************************************************************/
235
/* Definitions                                                               */
236
/*****************************************************************************/
237
 
238
#define VERSION      "1.30"
239
#define VERSNUM      "$011D"            /* can be queried as &VERSION        */
240
 
241
#define UNIX 0                          /* set to != 0 for UNIX specials     */
242
 
243
#define MAX_PASSNO      9
244
#define MAXLABELS    8192
245
#define MAXMACROS    1024
246
#define MAXTEXTS     1024
247
#define MAXRELOCS    32768
248
#define MAXIDLEN     32
249
#define MAXLISTBYTES 7
250
#define FNLEN        256
251
#define LINELEN      1024
252
 
253
/*****************************************************************************/
254
/* Line buffer definitions                                                   */
255
/*****************************************************************************/
256
 
257
struct linebuf
258
  {
259
  struct linebuf * next;                /* pointer to next line              */
260
  struct linebuf * prev;                /* pointer to previous line          */
261
  char *fn;                             /* pointer to original file name     */
262
  long ln;                              /* line number therein               */
263
  unsigned char lvl;                    /* line level                        */
264
  unsigned char rel;                    /* relocation mode                   */
265
  char txt[1];                          /* text buffer                       */
266
  };
267
 
268
char *fnms[128] = {0};                  /* we process up to 128 different fls*/
269
short nfnms;                            /* # loaded files                    */
270
 
271
                                        /* special bits in lvl :             */
272
#define LINCAT_MACDEF       0x20        /* macro definition                  */
273
#define LINCAT_MACEXP       0x40        /* macro expansion                   */
274
#define LINCAT_INVISIBLE    0x80        /* does not appear in listing        */
275
#define LINCAT_LVLMASK      0x1F        /* mask for line levels (0..31)      */
276
 
277
struct linebuf *rootline = NULL;        /* pointer to 1st line of the file   */
278
struct linebuf *curline = NULL;         /* pointer to currently processed ln */
279
 
280
/*****************************************************************************/
281
/* Opcode definitions                                                        */
282
/*****************************************************************************/
283
 
284
struct oprecord
285
  {
286
  char * name;                          /* opcode mnemonic                   */
287
  unsigned char cat;                    /* opcode category                   */
288
  unsigned __int64 code;                /* category-dependent additional code*/
289
  unsigned char tgtNdx;
290
  };
291
 
292
                                        /* Instruction categories :          */
293
#define OPCAT_ONEBYTE        0x00       /* one byte opcodes             NOP  */
294
#define OPCAT_TWOBYTE        0x01       /* two byte opcodes             SWI2 */
295
#define OPCAT_THREEBYTE      0x02       /* three byte opcodes            TAB */
296
#define OPCAT_FOURBYTE       0x03       /* four byte opcodes             ABA */
297
#define OPCAT_IMMBYTE        0x04       /* opcodes w. imm byte         ANDCC */
298
#define OPCAT_LEA            0x05       /* load effective address       LEAX */
299
#define OPCAT_SBRANCH        0x06       /* short branches               BGE  */
300
#define OPCAT_LBR2BYTE       0x07       /* long branches 2 byte opc     LBGE */
301
#define OPCAT_LBR1BYTE       0x08       /* long branches 2 byte opc     LBRA */
302
#define OPCAT_ARITH          0x09       /* accumulator instr.           ADDA */
303
#define OPCAT_DBLREG1BYTE    0x0a       /* double reg instr 1 byte opc  LDX  */
304
#define OPCAT_DBLREG2BYTE    0x0b       /* double reg instr 2 byte opc  LDY  */
305
#define OPCAT_SINGLEADDR     0x0c       /* single address instrs        NEG  */
306
#define OPCAT_2REG           0x0d       /* 2 register instr         TFR,EXG  */
307
#define OPCAT_STACK          0x0e       /* stack instr             PSHx,PULx */
308
#define OPCAT_BITDIRECT      0x0f       /* direct bitmanipulation       AIM  */
309
#define OPCAT_BITTRANS       0x10       /* direct bit transfer         BAND  */
310
#define OPCAT_BLOCKTRANS     0x11       /* block transfer               TFM  */
311
#define OPCAT_IREG           0x12       /* inter-register operations   ADCR  */
312
#define OPCAT_QUADREG1BYTE   0x13       /* quad reg instr 1 byte opc    LDQ  */
313
#define OPCAT_2IMMBYTE       0x14       /* 2byte opcode w. imm byte    BITMD */
314
#define OPCAT_2ARITH         0x15       /* 2byte opcode accum. instr.   SUBE */
315
#define OPCAT_ACCARITH       0x16       /* acc. instr. w.explicit acc   ADD  */
316
#define OPCAT_IDXEXT         0x17       /* indexed/extended, 6800-style JMP  */
317
#define OPCAT_ACCADDR        0x18       /* single address instrs, 6800  NEG  */
318
#define OPCAT_PSEUDO         0x3f       /* pseudo-ops                        */
319
#define OPCAT_6309           0x40       /* valid for 6309 only!              */
320
#define OPCAT_NOIMM          0x80       /* immediate not allowed!       STD  */
321
 
322
                                        /* the various Pseudo-Ops            */
323
#define PSEUDO_RMB            0
324
#define PSEUDO_ELSE           1
325
#define PSEUDO_END            2
326
#define PSEUDO_ENDIF          3
327
#define PSEUDO_ENDM           4
328
#define PSEUDO_EQU            5
329
#define PSEUDO_EXT            6
330
#define PSEUDO_FCB            7
331
#define PSEUDO_FCC            8
332
#define PSEUDO_FCW            9
333
#define PSEUDO_IF            10
334
#define PSEUDO_MACRO         11
335
#define PSEUDO_ORG           12
336
#define PSEUDO_PUB           13
337
#define PSEUDO_SETDP         14
338
#define PSEUDO_SET           15
339
#define PSEUDO_INCLUDE       16
340
#define PSEUDO_OPT           17
341
#define PSEUDO_NAM           18
342
#define PSEUDO_STTL          19
343
#define PSEUDO_PAG           20
344
#define PSEUDO_SPC           21
345
#define PSEUDO_REP           22
346
#define PSEUDO_SETPG         23
347
#define PSEUDO_SETLI         24
348
#define PSEUDO_EXITM         25
349
#define PSEUDO_IFN           26
350
#define PSEUDO_IFC           27
351
#define PSEUDO_IFNC          28
352
#define PSEUDO_DUP           29
353
#define PSEUDO_ENDD          30
354
#define PSEUDO_REG           31
355
#define PSEUDO_ERR           32
356
#define PSEUDO_TEXT          33
357
#define PSEUDO_RZB           34
358
#define PSEUDO_ABS           35
359
#define PSEUDO_DEF           36
360
#define PSEUDO_ENDDEF        37
361
#define PSEUDO_COMMON        38
362
#define PSEUDO_ENDCOM        39
363
#define PSEUDO_NAME          40
364
#define PSEUDO_SYMLEN        41
365
#define PSEUDO_IFD           42
366
#define PSEUDO_IFND          43
367
#define PSEUDO_BINARY        44
368
#define PSEUDO_FCDW          45
369
 
370
struct oprecord optable09[]=
371
  {
372
  { "ABA",     OPCAT_FOURBYTE,    0x0340040ab0e0LL, 0 },
373
  { "ABS",     OPCAT_PSEUDO,      PSEUDO_ABS, 0 },
374
  { "ABX",     OPCAT_ONEBYTE,     0x3a, 0 },
375
  { "ABY",     OPCAT_TWOBYTE,     0x0310a5, 0 },
376
  { "ADC",     OPCAT_ACCARITH,    0x89, 0 },
377
  { "ADCA",    OPCAT_ARITH,       0x89, 0 },
378
  { "ADCB",    OPCAT_ARITH,       0xc9, 0 },
379
  { "ADCD",    OPCAT_6309 |
380
               OPCAT_DBLREG1BYTE, 0x189, 0 },
381
  { "ADCR",    OPCAT_6309 |
382
               OPCAT_IREG,        0x1031, 0 },
383
  { "ADD",     OPCAT_ACCARITH,    0x8b, 0 },
384
  { "ADDA",    OPCAT_ARITH,       0x8b, 0 },
385
  { "ADDB",    OPCAT_ARITH,       0xcb, 0 },
386
  { "ADDD",    OPCAT_DBLREG1BYTE, 0xc3, 0 },
387
  { "ADDE",    OPCAT_6309 |
388
               OPCAT_2ARITH,      0x118b, 0 },
389
  { "ADDF",    OPCAT_6309 |
390
               OPCAT_2ARITH,      0x11cb, 0 },
391
  { "ADDR",    OPCAT_6309 |
392
               OPCAT_IREG,        0x1030, 0 },
393
  { "ADDW",    OPCAT_6309 |
394
               OPCAT_DBLREG2BYTE, 0x108b, 0 },
395
  { "AIM",     OPCAT_6309 |
396
               OPCAT_BITDIRECT,   0x02, 0 },
397
  { "AND",     OPCAT_ACCARITH,    0x84, 0 },
398
  { "ANDA",    OPCAT_ARITH,       0x84, 0 },
399
  { "ANDB",    OPCAT_ARITH,       0xc4, 0 },
400
  { "ANDCC",   OPCAT_IMMBYTE,     0x1c, 0 },
401
  { "ANDD",    OPCAT_6309 |
402
               OPCAT_DBLREG1BYTE, 0x184, 0 },
403
  { "ANDR",    OPCAT_6309 |
404
               OPCAT_IREG,        0x1034, 0 },
405
  { "ASL",     OPCAT_SINGLEADDR,  0x08, 0 },
406
  { "ASLA",    OPCAT_ONEBYTE,     0x48, 0 },
407
  { "ASLB",    OPCAT_ONEBYTE,     0x58, 0 },
408
  { "ASLD",    OPCAT_TWOBYTE,     0x058049, 0 },
409
  { "ASLD63",  OPCAT_6309 |
410
               OPCAT_TWOBYTE,     0x1048, 0 },
411
  { "ASR",     OPCAT_SINGLEADDR,  0x07, 0 },
412
  { "ASRA",    OPCAT_ONEBYTE,     0x47, 0 },
413
  { "ASRB",    OPCAT_ONEBYTE,     0x57, 0 },
414
  { "ASRD",    OPCAT_TWOBYTE,     0x047056, 0 },
415
  { "ASRD63",  OPCAT_6309 |
416
               OPCAT_TWOBYTE,     0x1047, 0 },
417
  { "BAND",    OPCAT_6309 |
418
               OPCAT_BITTRANS,    0x1130, 0 },
419
  { "BCC",     OPCAT_SBRANCH,     0x24, 0 },
420
  { "BCS",     OPCAT_SBRANCH,     0x25, 0 },
421
  { "BEC",     OPCAT_SBRANCH,     0x24, 0 },
422
  { "BEOR",    OPCAT_6309 |
423
               OPCAT_BITTRANS,    0x1134, 0 },
424
  { "BEQ",     OPCAT_SBRANCH,     0x27, 0 },
425
  { "BES",     OPCAT_SBRANCH,     0x25, 0 },
426
  { "BGE",     OPCAT_SBRANCH,     0x2c, 0 },
427
  { "BGT",     OPCAT_SBRANCH,     0x2e, 0 },
428
  { "BHI",     OPCAT_SBRANCH,     0x22, 0 },
429
  { "BHS",     OPCAT_SBRANCH,     0x24, 0 },
430
  { "BIAND",   OPCAT_6309 |
431
               OPCAT_BITTRANS,    0x1131, 0 },
432
  { "BIEOR",   OPCAT_6309 |
433
               OPCAT_BITTRANS,    0x1135, 0 },
434
  { "BIN",     OPCAT_PSEUDO,      PSEUDO_BINARY, 0 },
435
  { "BINARY",  OPCAT_PSEUDO,      PSEUDO_BINARY, 0 },
436
  { "BIOR",    OPCAT_6309 |
437
               OPCAT_BITTRANS,    0x1133, 0 },
438
  { "BIT",     OPCAT_ACCARITH,    0x85, 0 },
439
  { "BITA",    OPCAT_ARITH,       0x85, 0 },
440
  { "BITB",    OPCAT_ARITH,       0xc5, 0 },
441
  { "BITD",    OPCAT_6309 |
442
               OPCAT_DBLREG1BYTE, 0x185, 0 },
443
  { "BITMD",   OPCAT_6309 |
444
               OPCAT_2IMMBYTE,    0x113c, 0 },
445
  { "BLE",     OPCAT_SBRANCH,     0x2f, 0 },
446
  { "BLO",     OPCAT_SBRANCH,     0x25, 0 },
447
  { "BLS",     OPCAT_SBRANCH,     0x23, 0 },
448
  { "BLT",     OPCAT_SBRANCH,     0x2d, 0 },
449
  { "BMI",     OPCAT_SBRANCH,     0x2b, 0 },
450
  { "BNE",     OPCAT_SBRANCH,     0x26, 0 },
451
  { "BOR",     OPCAT_6309 |
452
               OPCAT_BITTRANS,    0x1132, 0 },
453
  { "BPL",     OPCAT_SBRANCH,     0x2a, 0 },
454
  { "BRA",     OPCAT_SBRANCH,     0x20, 0 },
455
  { "BRN",     OPCAT_SBRANCH,     0x21, 0 },
456
  { "BSR",     OPCAT_SBRANCH,     0x8d, 0 },
457
  { "BVC",     OPCAT_SBRANCH,     0x28, 0 },
458
  { "BVS",     OPCAT_SBRANCH,     0x29, 0 },
459
  { "CBA",     OPCAT_FOURBYTE,    0x0340040a10e0LL, 0 },
460
  { "CLC",     OPCAT_TWOBYTE,     0x1c0fe, 0 },
461
  { "CLF",     OPCAT_TWOBYTE,     0x1c0bf, 0 },
462
  { "CLI",     OPCAT_TWOBYTE,     0x1c0ef, 0 },
463
  { "CLIF",    OPCAT_TWOBYTE,     0x1c0af, 0 },
464
  { "CLR",     OPCAT_SINGLEADDR,  0x0f, 0 },
465
  { "CLRA",    OPCAT_ONEBYTE,     0x4f, 0 },
466
  { "CLRB",    OPCAT_ONEBYTE,     0x5f, 0 },
467
  { "CLRD",    OPCAT_TWOBYTE,     0x4f05f, 0 },
468
  { "CLRD63",  OPCAT_6309 |
469
               OPCAT_TWOBYTE,     0x104f, 0 },
470
  { "CLRE",    OPCAT_6309 |
471
               OPCAT_TWOBYTE,     0x114f, 0 },
472
  { "CLRF",    OPCAT_6309 |
473
               OPCAT_TWOBYTE,     0x115f, 0 },
474
  { "CLRW",    OPCAT_6309 |
475
               OPCAT_TWOBYTE,     0x105f, 0 },
476
  { "CLV",     OPCAT_TWOBYTE,     0x1c0fd, 0 },
477
  { "CLZ",     OPCAT_TWOBYTE,     0x1c0fb, 0 },
478
  { "CMP",     OPCAT_ACCARITH,    0x81, 0 },
479
  { "CMPA",    OPCAT_ARITH,       0x81, 0 },
480
  { "CMPB",    OPCAT_ARITH,       0xc1, 0 },
481
  { "CMPD",    OPCAT_DBLREG1BYTE, 0x183, 0 },
482
  { "CMPE",    OPCAT_6309 |
483
               OPCAT_2ARITH,      0x1181, 0 },
484
  { "CMPF",    OPCAT_6309 |
485
               OPCAT_2ARITH,      0x11c1, 0 },
486
  { "CMPR",    OPCAT_6309 |
487
               OPCAT_IREG,        0x1037, 0 },
488
  { "CMPS",    OPCAT_DBLREG1BYTE, 0x28c, 4 },
489
  { "CMPU",    OPCAT_DBLREG1BYTE, 0x283, 3 },
490
  { "CMPW",    OPCAT_6309 |
491
               OPCAT_DBLREG2BYTE, 0x1081, 0 },
492
  { "CMPX",    OPCAT_DBLREG1BYTE, 0x8c, 1 },
493
  { "CMPY",    OPCAT_DBLREG1BYTE, 0x18c, 2 },
494
  { "COM",     OPCAT_SINGLEADDR,  0x03, 0 },
495
  { "COMA",    OPCAT_ONEBYTE,     0x43, 0 },
496
  { "COMB",    OPCAT_ONEBYTE,     0x53, 0 },
497
  { "COMD",    OPCAT_6309 |
498
               OPCAT_ONEBYTE,     0x143, 0 },
499
  { "COME",    OPCAT_6309 |
500
               OPCAT_TWOBYTE,     0x1143, 0  },
501
  { "COMF",    OPCAT_6309 |
502
               OPCAT_TWOBYTE,     0x1153, 0 },
503
  { "COMW",    OPCAT_6309 |
504
               OPCAT_TWOBYTE,     0x1053, 0 },
505
  { "COMMON",  OPCAT_PSEUDO,      PSEUDO_COMMON, 0 },
506
  { "CPD",     OPCAT_DBLREG1BYTE, 0x183, 0 },
507
  { "CPX",     OPCAT_DBLREG1BYTE, 0x8c, 1 },
508
  { "CPY",     OPCAT_DBLREG1BYTE, 0x18c, 2 },
509
  { "CWAI",    OPCAT_IMMBYTE,     0x3c, 0 },
510
  { "DAA",     OPCAT_ONEBYTE,     0x19, 0 },
511
  { "DEC",     OPCAT_SINGLEADDR,  0x0a, 0 },
512
  { "DECA",    OPCAT_ONEBYTE,     0x4a, 0 },
513
  { "DECB",    OPCAT_ONEBYTE,     0x5a, 0 },
514
  { "DECD",    OPCAT_THREEBYTE,   0x083000001LL, 0 },
515
  { "DECD63",  OPCAT_6309 |
516
               OPCAT_TWOBYTE,     0x104a, 0 },
517
  { "DECE",    OPCAT_6309 |
518
               OPCAT_TWOBYTE,     0x114a, 0 },
519
  { "DECF",    OPCAT_6309 |
520
               OPCAT_TWOBYTE,     0x115a, 0 },
521
  { "DECW",    OPCAT_6309 |
522
               OPCAT_TWOBYTE,     0x105a, 0 },
523
  { "DEF",     OPCAT_PSEUDO,      PSEUDO_DEF, 0 },
524
  { "DEFINE",  OPCAT_PSEUDO,      PSEUDO_DEF, 0 },
525
  { "DES",     OPCAT_TWOBYTE,     0x327ff, 4 },
526
  { "DEU",     OPCAT_TWOBYTE,     0x335ff, 3 },
527
  { "DEX",     OPCAT_TWOBYTE,     0x301ff, 1 },
528
  { "DEY",     OPCAT_TWOBYTE,     0x313ff, 2 },
529
  { "DIVD",    OPCAT_6309 |
530
               OPCAT_2ARITH,      0x118d, 0 },
531
  { "DIVQ",    OPCAT_6309 |
532
               OPCAT_DBLREG2BYTE, 0x118e, 0 },
533
  { "DUP",     OPCAT_PSEUDO,      PSEUDO_DUP, 0 },
534
  { "EIM",     OPCAT_6309 |
535
               OPCAT_BITDIRECT,   0x05, 0 },
536
  { "ELSE",    OPCAT_PSEUDO,      PSEUDO_ELSE, 0 },
537
  { "END",     OPCAT_PSEUDO,      PSEUDO_END, 0 },
538
  { "ENDCOM",  OPCAT_PSEUDO,      PSEUDO_ENDCOM, 0 },
539
  { "ENDD",    OPCAT_PSEUDO,      PSEUDO_ENDD, 0 },
540
  { "ENDDEF",  OPCAT_PSEUDO,      PSEUDO_ENDDEF, 0 },
541
  { "ENDIF",   OPCAT_PSEUDO,      PSEUDO_ENDIF, 0 },
542
  { "ENDM",    OPCAT_PSEUDO,      PSEUDO_ENDM, 0 },
543
  { "EOR",     OPCAT_ACCARITH,    0x88, 0 },
544
  { "EORA",    OPCAT_ARITH,       0x88, 0 },
545
  { "EORB",    OPCAT_ARITH,       0xc8, 0 },
546
  { "EORD",    OPCAT_6309 |
547
               OPCAT_DBLREG1BYTE, 0x188, 0 },
548
  { "EORR",    OPCAT_6309 |
549
               OPCAT_IREG,        0x1036, 0 },
550
  { "EQU",     OPCAT_PSEUDO,      PSEUDO_EQU, 0 },
551
  { "ERR",     OPCAT_PSEUDO,      PSEUDO_ERR, 0 },
552
  { "EXG",     OPCAT_2REG,        0x1e, 0 },
553
  { "EXITM",   OPCAT_PSEUDO,      PSEUDO_EXITM, 0 },
554
  { "EXT",     OPCAT_PSEUDO,      PSEUDO_EXT, 0 },
555
  { "EXTERN",  OPCAT_PSEUDO,      PSEUDO_EXT, 0 },
556
  { "FCB",     OPCAT_PSEUDO,      PSEUDO_FCB, 0 },
557
  { "FCC",     OPCAT_PSEUDO,      PSEUDO_FCC, 0 },
558
  { "FCDW",    OPCAT_PSEUDO,      PSEUDO_FCDW, 0 },
559
  { "FCW",     OPCAT_PSEUDO,      PSEUDO_FCW, 0 },
560
  { "FDB",     OPCAT_PSEUDO,      PSEUDO_FCW, 0 },
561
  { "GLOBAL",  OPCAT_PSEUDO,      PSEUDO_PUB, 0 },
562
  { "IF",      OPCAT_PSEUDO,      PSEUDO_IF, 0 },
563
  { "IFC",     OPCAT_PSEUDO,      PSEUDO_IFC, 0 },
564
  { "IFD",     OPCAT_PSEUDO,      PSEUDO_IFD, 0 },
565
  { "IFN",     OPCAT_PSEUDO,      PSEUDO_IFN, 0 },
566
  { "IFNC",    OPCAT_PSEUDO,      PSEUDO_IFNC, 0 },
567
  { "IFND",    OPCAT_PSEUDO,      PSEUDO_IFND, 0 },
568
  { "INC",     OPCAT_SINGLEADDR,  0x0c, 0 },
569
  { "INCA",    OPCAT_ONEBYTE,     0x4c, 0 },
570
  { "INCB",    OPCAT_ONEBYTE,     0x5c, 0 },
571
  { "INCD",    OPCAT_THREEBYTE,   0x0c3000001LL, 0 },
572
  { "INCD63",  OPCAT_6309 |
573
               OPCAT_TWOBYTE,     0x104c, 0 },
574
  { "INCE",    OPCAT_6309 |
575
               OPCAT_TWOBYTE,     0x114c, 0 },
576
  { "INCF",    OPCAT_6309 |
577
               OPCAT_TWOBYTE,     0x115c, 0 },
578
  { "INCLUDE", OPCAT_PSEUDO,      PSEUDO_INCLUDE, 0 },
579
  { "INCW",    OPCAT_6309 |
580
               OPCAT_TWOBYTE,     0x105c, 0 },
581
  { "INS",     OPCAT_TWOBYTE,     0x32601, 4 },
582
  { "INU",     OPCAT_TWOBYTE,     0x33401, 3 },
583
  { "INX",     OPCAT_TWOBYTE,     0x30001, 1 },
584
  { "INY",     OPCAT_TWOBYTE,     0x31201, 2 },
585
  { "JMP",     OPCAT_SINGLEADDR,  0x0e, 0 },
586
  { "JSR",     OPCAT_DBLREG1BYTE, 0x8d, 0 },
587
  { "LBCC",    OPCAT_LBR1BYTE,    0x124, 0 },
588
  { "LBCS",    OPCAT_LBR1BYTE,    0x125, 0 },
589
  { "LBEC",    OPCAT_LBR1BYTE,    0x124, 0 },
590
  { "LBEQ",    OPCAT_LBR1BYTE,    0x127, 0 },
591
  { "LBES",    OPCAT_LBR1BYTE,    0x125, 0 },
592
  { "LBGE",    OPCAT_LBR1BYTE,    0x12c, 0 },
593
  { "LBGT",    OPCAT_LBR1BYTE,    0x12e, 0 },
594
  { "LBHI",    OPCAT_LBR1BYTE,    0x122, 0 },
595
  { "LBHS",    OPCAT_LBR1BYTE,    0x124, 0 },
596
  { "LBLE",    OPCAT_LBR1BYTE,    0x12f, 0 },
597
  { "LBLO",    OPCAT_LBR1BYTE,    0x125, 0 },
598
  { "LBLS",    OPCAT_LBR1BYTE,    0x123, 0 },
599
  { "LBLT",    OPCAT_LBR1BYTE,    0x12d, 0 },
600
  { "LBMI",    OPCAT_LBR1BYTE,    0x12b, 0 },
601
  { "LBNE",    OPCAT_LBR1BYTE,    0x126, 0 },
602
  { "LBPL",    OPCAT_LBR1BYTE,    0x12a, 0 },
603
  { "LBRA",    OPCAT_LBR1BYTE,    0x16, 0 },
604
  { "LBRN",    OPCAT_LBR1BYTE,    0x121, 0 },
605
  { "LBSR",    OPCAT_LBR1BYTE,    0x17, 0 },
606
  { "LBVC",    OPCAT_LBR1BYTE,    0x128, 0 },
607
  { "LBVS",    OPCAT_LBR1BYTE,    0x129, 0 },
608
  { "LD",      OPCAT_ACCARITH,    0x86, 0 },
609
  { "LDA",     OPCAT_ARITH,       0x86, 0 },
610
  { "LDAA",    OPCAT_ARITH,       0x86, 0 },
611
  { "LDAB",    OPCAT_ARITH,       0xc6, 0 },
612
  { "LDAD",    OPCAT_DBLREG1BYTE, 0xcc, 0 },
613
  { "LDB",     OPCAT_ARITH,       0xc6, 0 },
614
  { "LDBT",    OPCAT_6309 |
615
               OPCAT_BITTRANS,    0x1136, 0 },
616
  { "LDD",     OPCAT_DBLREG1BYTE, 0xcc, 0 },
617
  { "LDE",     OPCAT_6309 |
618
               OPCAT_2ARITH,      0x1186, 0 },
619
  { "LDF",     OPCAT_6309 |
620
               OPCAT_2ARITH,      0x11c6, 0 },
621
  { "LDMD",    OPCAT_6309 |
622
               OPCAT_2IMMBYTE,    0x113d, 0 },
623
  { "LDQ",     OPCAT_6309 |
624
               OPCAT_QUADREG1BYTE,0x10cc, 0 },
625
  { "LDS",     OPCAT_DBLREG1BYTE, 0x1ce, 4 },
626
  { "LDU",     OPCAT_DBLREG1BYTE, 0xce, 3 },
627
  { "LDW",     OPCAT_6309 |
628
               OPCAT_DBLREG2BYTE, 0x1086, 0 },
629
  { "LDX",     OPCAT_DBLREG1BYTE, 0x8e, 1 },
630
  { "LDY",     OPCAT_DBLREG1BYTE, 0x18e, 2 },
631
  { "LEAS",    OPCAT_LEA,         0x32, 4 },
632
  { "LEAU",    OPCAT_LEA,         0x33, 3 },
633
  { "LEAX",    OPCAT_LEA,         0x30, 1 },
634
  { "LEAY",    OPCAT_LEA,         0x31, 2 },
635
  { "LIB",     OPCAT_PSEUDO,      PSEUDO_INCLUDE, 0 },
636
  { "LIBRARY", OPCAT_PSEUDO,      PSEUDO_INCLUDE, 0 },
637
  { "LSL",     OPCAT_SINGLEADDR,  0x08, 0 },
638
  { "LSLA",    OPCAT_ONEBYTE,     0x48, 0 },
639
  { "LSLB",    OPCAT_ONEBYTE,     0x58, 0 },
640
  { "LSLD",    OPCAT_TWOBYTE,     0x58049, 0 },
641
  { "LSLD63",  OPCAT_6309 |
642
               OPCAT_TWOBYTE,     0x1048, 0 },
643
  { "LSR",     OPCAT_SINGLEADDR,  0x04, 0 },
644
  { "LSRA",    OPCAT_ONEBYTE,     0x44, 0 },
645
  { "LSRB",    OPCAT_ONEBYTE,     0x54, 0 },
646
  { "LSRD",    OPCAT_TWOBYTE,     0x44056, 0 },
647
  { "LSRD63",  OPCAT_6309 |
648
               OPCAT_TWOBYTE,     0x1044, 0 },
649
  { "LSRW",    OPCAT_6309 |
650
               OPCAT_TWOBYTE,     0x1054, 0 },
651
  { "MACRO",   OPCAT_PSEUDO,      PSEUDO_MACRO, 0 },
652
  { "MUL",     OPCAT_ONEBYTE,     0x3d, 0 },
653
  { "MULD",    OPCAT_6309 |
654
               OPCAT_DBLREG2BYTE, 0x118f, 0 },
655
  { "NAM",     OPCAT_PSEUDO,      PSEUDO_NAM, 0 },
656
  { "NAME",    OPCAT_PSEUDO,      PSEUDO_NAME, 0 },
657
  { "NEG",     OPCAT_SINGLEADDR,  0x00, 0 },
658
  { "NEGA",    OPCAT_ONEBYTE,     0x40, 0 },
659
  { "NEGB",    OPCAT_ONEBYTE,     0x50, 0 },
660
  { "NEGD",    OPCAT_6309 |
661
               OPCAT_ONEBYTE,     0x140, 0 },
662
  { "NOP",     OPCAT_ONEBYTE,     0x12, 0 },
663
  { "OIM",     OPCAT_6309 |
664
               OPCAT_BITDIRECT,   0x01, 0 },
665
  { "OPT",     OPCAT_PSEUDO,      PSEUDO_OPT, 0 },
666
  { "OPTION",  OPCAT_PSEUDO,      PSEUDO_OPT, 0 },
667
  { "ORA",     OPCAT_ARITH,       0x8a, 0 },
668
  { "ORAA",    OPCAT_ARITH,       0x8a, 0 },
669
  { "ORAB",    OPCAT_ARITH,       0xca, 0 },
670
  { "ORB",     OPCAT_ARITH,       0xca, 0 },
671
  { "ORCC",    OPCAT_IMMBYTE,     0x1a, 0 },
672
  { "ORD",     OPCAT_6309 |
673
               OPCAT_DBLREG1BYTE, 0x18a, 0 },
674
  { "ORG",     OPCAT_PSEUDO,      PSEUDO_ORG, 0 },
675
  { "ORR",     OPCAT_6309 |
676
               OPCAT_IREG,        0x1035, 0 },
677
  { "PAG",     OPCAT_PSEUDO,      PSEUDO_PAG, 0 },
678
  { "PAGE",    OPCAT_PSEUDO,      PSEUDO_PAG, 0 },
679
  { "PSH",     OPCAT_STACK,       0x34, 0 },
680
  { "PSHA",    OPCAT_TWOBYTE,     0x34002, 0 },
681
  { "PSHB",    OPCAT_TWOBYTE,     0x34004, 0 },
682
  { "PSHD",    OPCAT_TWOBYTE,     0x34006, 0 },
683
  { "PSHS",    OPCAT_STACK,       0x34, 4 },
684
  { "PSHSW",   OPCAT_6309 |
685
               OPCAT_TWOBYTE,     0x1038, 0 },
686
  { "PSHU",    OPCAT_STACK,       0x36, 3 },
687
  { "PSHUW",   OPCAT_6309 |
688
               OPCAT_TWOBYTE,     0x103a, 0 },
689
  { "PSHX",    OPCAT_TWOBYTE,     0x34010, 1 },
690
  { "PSHY",    OPCAT_TWOBYTE,     0x34020, 2 },
691
  { "PUB",     OPCAT_PSEUDO,      PSEUDO_PUB, 0 },
692
  { "PUBLIC",  OPCAT_PSEUDO,      PSEUDO_PUB, 0 },
693
  { "PUL",     OPCAT_STACK,       0x35, 0 },
694
  { "PULA",    OPCAT_TWOBYTE,     0x35002, 0 },
695
  { "PULB",    OPCAT_TWOBYTE,     0x35004, 0 },
696
  { "PULD",    OPCAT_TWOBYTE,     0x35006, 0 },
697
  { "PULS",    OPCAT_STACK,       0x35, 4 },
698
  { "PULSW",   OPCAT_6309 |
699
               OPCAT_TWOBYTE,     0x1039, 0 },
700
  { "PULU",    OPCAT_STACK,       0x37, 3 },
701
  { "PULUW",   OPCAT_6309 |
702
               OPCAT_TWOBYTE,     0x103b, 0 },
703
  { "PULX",    OPCAT_TWOBYTE,     0x35010, 1 },
704
  { "PULY",    OPCAT_TWOBYTE,     0x35020, 2 },
705
  { "REG",     OPCAT_PSEUDO,      PSEUDO_REG, 0 },
706
  { "REP",     OPCAT_PSEUDO,      PSEUDO_REP, 0 },
707
  { "REPEAT",  OPCAT_PSEUDO,      PSEUDO_REP, 0 },
708
  { "RESET",   OPCAT_ONEBYTE,     0x3e, 0 },
709
  { "RMB",     OPCAT_PSEUDO,      PSEUDO_RMB, 0 },
710
  { "ROL",     OPCAT_SINGLEADDR,  0x09, 0 },
711
  { "ROLA",    OPCAT_ONEBYTE,     0x49, 0 },
712
  { "ROLB",    OPCAT_ONEBYTE,     0x59, 0 },
713
  { "ROLD",    OPCAT_6309 |
714
               OPCAT_ONEBYTE,     0x149, 0 },
715
  { "ROLW",    OPCAT_6309 |
716
               OPCAT_TWOBYTE,     0x1059, 0 },
717
  { "ROR",     OPCAT_SINGLEADDR,  0x06, 0 },
718
  { "RORA",    OPCAT_ONEBYTE,     0x46, 0 },
719
  { "RORB",    OPCAT_ONEBYTE,     0x56, 0 },
720
  { "RORD",    OPCAT_6309 |
721
               OPCAT_ONEBYTE,     0x146, 0 },
722
  { "RORW",    OPCAT_6309 |
723
               OPCAT_TWOBYTE,     0x1056, 0 },
724
  { "RPT",     OPCAT_PSEUDO,      PSEUDO_REP, 0 },
725
  { "RTF",     OPCAT_ONEBYTE,     0x38, 0 },
726
  { "RTI",     OPCAT_ONEBYTE,     0x3b, 0 },
727
  { "RTS",     OPCAT_ONEBYTE,     0x39, 0 },
728
  { "RZB",     OPCAT_PSEUDO,      PSEUDO_RZB, 0 },
729
  { "SBA",     OPCAT_FOURBYTE,    0x0340040a00e0LL, 0 },
730
  { "SBC",     OPCAT_ACCARITH,    0x82, 0 },
731
  { "SBCA",    OPCAT_ARITH,       0x82, 0 },
732
  { "SBCB",    OPCAT_ARITH,       0xc2, 0 },
733
  { "SBCD",    OPCAT_6309 |
734
               OPCAT_DBLREG1BYTE, 0x182, 0 },
735
  { "SBCR",    OPCAT_6309 |
736
               OPCAT_IREG,        0x1033, 0 },
737
  { "SEC",     OPCAT_TWOBYTE,     0x1a001, 0 },
738
  { "SEF",     OPCAT_TWOBYTE,     0x1a040, 0 },
739
  { "SEI",     OPCAT_TWOBYTE,     0x1a010, 0 },
740
  { "SEIF",    OPCAT_TWOBYTE,     0x1a050, 0 },
741
  { "SET",     OPCAT_PSEUDO,      PSEUDO_SET, 0 },
742
  { "SETDP",   OPCAT_PSEUDO,      PSEUDO_SETDP, 0 },
743
  { "SETLI",   OPCAT_PSEUDO,      PSEUDO_SETLI, 0 },
744
  { "SETPG",   OPCAT_PSEUDO,      PSEUDO_SETPG, 0 },
745
  { "SEV",     OPCAT_TWOBYTE,     0x1a002, 0 },
746
  { "SEX",     OPCAT_ONEBYTE,     0x1d, 0 },
747
  { "SEXW",    OPCAT_6309 |
748
               OPCAT_ONEBYTE,     0x14, 0 },
749
  { "SEZ",     OPCAT_TWOBYTE,     0x1a004, 0 },
750
  { "SPC",     OPCAT_PSEUDO,      PSEUDO_SPC, 0 },
751
  { "STA",     OPCAT_NOIMM |
752
               OPCAT_ARITH,       0x87, 0 },
753
  { "STAA",    OPCAT_NOIMM |
754
               OPCAT_ARITH,       0x87, 0 },
755
  { "STAB",    OPCAT_NOIMM |
756
               OPCAT_ARITH,       0xc7, 0 },
757
  { "STAD",    OPCAT_NOIMM |
758
               OPCAT_DBLREG1BYTE, 0xcd, 0 },
759
  { "STB",     OPCAT_NOIMM |
760
               OPCAT_ARITH,       0xc7, 0 },
761
  { "STBT",    OPCAT_6309 |
762
               OPCAT_BITTRANS,    0x1137, 0 },
763
  { "STD",     OPCAT_NOIMM |
764
               OPCAT_DBLREG1BYTE, 0xcd, 0 },
765
  { "STE",     OPCAT_NOIMM |
766
               OPCAT_6309 |
767
               OPCAT_2ARITH,      0x1187, 0 },
768
  { "STF",     OPCAT_NOIMM |
769
               OPCAT_6309 |
770
               OPCAT_2ARITH,      0x11c7, 0 },
771
  { "STQ",     OPCAT_NOIMM |
772
               OPCAT_6309 |
773
               OPCAT_QUADREG1BYTE,0x10cd, 0 },
774
  { "STS",     OPCAT_NOIMM |
775
               OPCAT_DBLREG1BYTE, 0x1cf, 4 },
776
  { "STTL",    OPCAT_PSEUDO,      PSEUDO_STTL, 0 },
777
  { "STU",     OPCAT_NOIMM |
778
               OPCAT_DBLREG1BYTE, 0xcf, 3 },
779
  { "STW",     OPCAT_NOIMM |
780
               OPCAT_6309 |
781
               OPCAT_DBLREG2BYTE, 0x1087, 0 },
782
  { "STX",     OPCAT_NOIMM |
783
               OPCAT_DBLREG1BYTE, 0x8f, 1 },
784
  { "STY",     OPCAT_NOIMM |
785
               OPCAT_DBLREG1BYTE, 0x18f, 2 },
786
  { "SUB",     OPCAT_ACCARITH,    0x80, 0 },
787
  { "SUBA",    OPCAT_ARITH,       0x80, 0 },
788
  { "SUBB",    OPCAT_ARITH,       0xc0, 0 },
789
  { "SUBD",    OPCAT_DBLREG1BYTE, 0x83, 0 },
790
  { "SUBE",    OPCAT_6309 |
791
               OPCAT_2ARITH,      0x1180, 0 },
792
  { "SUBF",    OPCAT_6309 |
793
               OPCAT_2ARITH,      0x11c0, 0 },
794
  { "SUBW",    OPCAT_6309 |
795
               OPCAT_DBLREG2BYTE, 0x1080, 0 },
796
  { "SUBR",    OPCAT_6309 |
797
               OPCAT_IREG,        0x1032, 0 },
798
  { "SWI",     OPCAT_ONEBYTE,     0x3f, 0 },
799
  { "SWI2",    OPCAT_ONEBYTE,     0x13f, 0 },
800
  { "SWI3",    OPCAT_ONEBYTE,     0x23f, 0 },
801
  { "SYMLEN",  OPCAT_PSEUDO,      PSEUDO_SYMLEN, 0 },
802
  { "SYNC",    OPCAT_ONEBYTE,     0x13, 0 },
803
  { "TAB",     OPCAT_THREEBYTE,   0x1f08904d, 0 },
804
  { "TAP",     OPCAT_TWOBYTE,     0x1f08a, 0 },
805
  { "TBA",     OPCAT_THREEBYTE,   0x1f09804dLL, 0 },
806
  { "TEXT",    OPCAT_PSEUDO,      PSEUDO_TEXT, 0 },
807
  { "TFM",     OPCAT_6309 |
808
               OPCAT_BLOCKTRANS,  0x1138, 0 },
809
  { "TFR",     OPCAT_2REG,        0x1f, 0 },
810
  { "TIM",     OPCAT_6309 |
811
               OPCAT_BITDIRECT,   0x0b, 0 },
812
  { "TITLE",   OPCAT_PSEUDO,      PSEUDO_NAM, 0 },
813
  { "TPA",     OPCAT_TWOBYTE,     0x1f0a8, 0 },
814
  { "TST",     OPCAT_SINGLEADDR,  0x0d, 0 },
815
  { "TSTA",    OPCAT_ONEBYTE,     0x4d, 0 },
816
  { "TSTB",    OPCAT_ONEBYTE,     0x5d, 0 },
817
  { "TSTD",    OPCAT_6309 |
818
               OPCAT_ONEBYTE,     0x14d, 0 },
819
  { "TSTE",    OPCAT_6309 |
820
               OPCAT_TWOBYTE,     0x114d, 0 },
821
  { "TSTF",    OPCAT_6309 |
822
               OPCAT_TWOBYTE,     0x115d, 0 },
823
  { "TSTW",    OPCAT_6309 |
824
               OPCAT_TWOBYTE,     0x105d, 0 },
825
  { "TSX",     OPCAT_TWOBYTE,     0x1f041, 1 },
826
  { "TSY",     OPCAT_FOURBYTE,    0x034040035020LL, 2 },  /* PSHS S/PULS Y */
827
  { "TTL",     OPCAT_PSEUDO,      PSEUDO_NAM, 0 },
828
  { "TXS",     OPCAT_TWOBYTE,     0x1f014, 4 },
829
  { "TYS",     OPCAT_FOURBYTE,    0x034020035040LL, 4 },  /* PSHS Y/PULS S */
830
  { "WAI",     OPCAT_TWOBYTE,     0x3c0ff, 0 },
831
  { "WORD",    OPCAT_PSEUDO,      PSEUDO_FCW, 0 },
832
};
833
 
834
struct oprecord optable00[]=
835
  {
836
  { "ABA",     OPCAT_ONEBYTE,     0x1b },
837
  { "ABS",     OPCAT_PSEUDO,      PSEUDO_ABS },
838
  { "ADC",     OPCAT_ACCARITH,    0x89 },
839
  { "ADCA",    OPCAT_ARITH,       0x89 },
840
  { "ADCB",    OPCAT_ARITH,       0xc9 },
841
  { "ADD",     OPCAT_ACCARITH,    0x8b },
842
  { "ADDA",    OPCAT_ARITH,       0x8b },
843
  { "ADDB",    OPCAT_ARITH,       0xcb },
844
  { "AND",     OPCAT_ACCARITH,    0x84 },
845
  { "ANDA",    OPCAT_ARITH,       0x84 },
846
  { "ANDB",    OPCAT_ARITH,       0xc4 },
847
  { "ASL",     OPCAT_ACCADDR,     0x08 },
848
  { "ASLA",    OPCAT_ONEBYTE,     0x48 },
849
  { "ASLB",    OPCAT_ONEBYTE,     0x58 },
850
  { "ASR",     OPCAT_ACCADDR,     0x07 },
851
  { "ASRA",    OPCAT_ONEBYTE,     0x47 },
852
  { "ASRB",    OPCAT_ONEBYTE,     0x57 },
853
  { "BCC",     OPCAT_SBRANCH,     0x24 },
854
  { "BCS",     OPCAT_SBRANCH,     0x25 },
855
  { "BEC",     OPCAT_SBRANCH,     0x24 },
856
  { "BEQ",     OPCAT_SBRANCH,     0x27 },
857
  { "BES",     OPCAT_SBRANCH,     0x25 },
858
  { "BGE",     OPCAT_SBRANCH,     0x2c },
859
  { "BGT",     OPCAT_SBRANCH,     0x2e },
860
  { "BHI",     OPCAT_SBRANCH,     0x22 },
861
  { "BHS",     OPCAT_SBRANCH,     0x24 },
862
  { "BIN",     OPCAT_PSEUDO,      PSEUDO_BINARY },
863
  { "BINARY",  OPCAT_PSEUDO,      PSEUDO_BINARY },
864
  { "BIT",     OPCAT_ACCARITH,    0x85 },
865
  { "BITA",    OPCAT_ARITH,       0x85 },
866
  { "BITB",    OPCAT_ARITH,       0xc5 },
867
  { "BLE",     OPCAT_SBRANCH,     0x2f },
868
  { "BLO",     OPCAT_SBRANCH,     0x25 },
869
  { "BLS",     OPCAT_SBRANCH,     0x23 },
870
  { "BLT",     OPCAT_SBRANCH,     0x2d },
871
  { "BMI",     OPCAT_SBRANCH,     0x2b },
872
  { "BNE",     OPCAT_SBRANCH,     0x26 },
873
  { "BPL",     OPCAT_SBRANCH,     0x2a },
874
  { "BRA",     OPCAT_SBRANCH,     0x20 },
875
  { "BSR",     OPCAT_SBRANCH,     0x8d },
876
  { "BVC",     OPCAT_SBRANCH,     0x28 },
877
  { "BVS",     OPCAT_SBRANCH,     0x29 },
878
  { "CBA",     OPCAT_ONEBYTE,     0x11 },
879
  { "CLC",     OPCAT_ONEBYTE,     0x0c },
880
  { "CLI",     OPCAT_ONEBYTE,     0x0e },
881
  { "CLR",     OPCAT_ACCADDR,     0x0f },
882
  { "CLRA",    OPCAT_ONEBYTE,     0x4f },
883
  { "CLRB",    OPCAT_ONEBYTE,     0x5f },
884
  { "CLV",     OPCAT_ONEBYTE,     0x0a },
885
  { "CMP",     OPCAT_ACCARITH,    0x81 },
886
  { "CMPA",    OPCAT_ARITH,       0x81 },
887
  { "CMPB",    OPCAT_ARITH,       0xc1 },
888
  { "COM",     OPCAT_ACCADDR,     0x03 },
889
  { "COMA",    OPCAT_ONEBYTE,     0x43 },
890
  { "COMB",    OPCAT_ONEBYTE,     0x53 },
891
  { "CPX",     OPCAT_DBLREG1BYTE, 0x8c },
892
  { "DAA",     OPCAT_ONEBYTE,     0x19 },
893
  { "DEC",     OPCAT_ACCADDR,     0x0a },
894
  { "DECA",    OPCAT_ONEBYTE,     0x4a },
895
  { "DECB",    OPCAT_ONEBYTE,     0x5a },
896
  { "DEF",     OPCAT_PSEUDO,      PSEUDO_DEF },
897
  { "DEFINE",  OPCAT_PSEUDO,      PSEUDO_DEF },
898
  { "DES",     OPCAT_ONEBYTE,     0x34 },
899
  { "DEX",     OPCAT_ONEBYTE,     0x09 },
900
  { "DUP",     OPCAT_PSEUDO,      PSEUDO_DUP },
901
  { "ELSE",    OPCAT_PSEUDO,      PSEUDO_ELSE },
902
  { "END",     OPCAT_PSEUDO,      PSEUDO_END },
903
  { "ENDCOM",  OPCAT_PSEUDO,      PSEUDO_ENDCOM },
904
  { "ENDD",    OPCAT_PSEUDO,      PSEUDO_ENDD },
905
  { "ENDDEF",  OPCAT_PSEUDO,      PSEUDO_ENDDEF },
906
  { "ENDIF",   OPCAT_PSEUDO,      PSEUDO_ENDIF },
907
  { "ENDM",    OPCAT_PSEUDO,      PSEUDO_ENDM },
908
  { "EOR",     OPCAT_ACCARITH,    0x88 },
909
  { "EORA",    OPCAT_ARITH,       0x88 },
910
  { "EORB",    OPCAT_ARITH,       0xc8 },
911
  { "EQU",     OPCAT_PSEUDO,      PSEUDO_EQU },
912
  { "ERR",     OPCAT_PSEUDO,      PSEUDO_ERR },
913
  { "EXITM",   OPCAT_PSEUDO,      PSEUDO_EXITM },
914
  { "EXT",     OPCAT_PSEUDO,      PSEUDO_EXT },
915
  { "EXTERN",  OPCAT_PSEUDO,      PSEUDO_EXT },
916
  { "FCB",     OPCAT_PSEUDO,      PSEUDO_FCB },
917
  { "FCC",     OPCAT_PSEUDO,      PSEUDO_FCC },
918
  { "FCW",     OPCAT_PSEUDO,      PSEUDO_FCW },
919
  { "FDB",     OPCAT_PSEUDO,      PSEUDO_FCW },
920
  { "GLOBAL",  OPCAT_PSEUDO,      PSEUDO_PUB },
921
  { "IF",      OPCAT_PSEUDO,      PSEUDO_IF },
922
  { "IFC",     OPCAT_PSEUDO,      PSEUDO_IFC },
923
  { "IFD",     OPCAT_PSEUDO,      PSEUDO_IFD },
924
  { "IFN",     OPCAT_PSEUDO,      PSEUDO_IFN },
925
  { "IFNC",    OPCAT_PSEUDO,      PSEUDO_IFNC },
926
  { "IFND",    OPCAT_PSEUDO,      PSEUDO_IFND },
927
  { "INC",     OPCAT_ACCADDR,     0x0c },
928
  { "INCA",    OPCAT_ONEBYTE,     0x4c },
929
  { "INCB",    OPCAT_ONEBYTE,     0x5c },
930
  { "INCLUDE", OPCAT_PSEUDO,      PSEUDO_INCLUDE },
931
  { "INS",     OPCAT_ONEBYTE,     0x31 },
932
  { "INX",     OPCAT_ONEBYTE,     0x08 },
933
  { "JMP",     OPCAT_IDXEXT,      0x4e },
934
  { "JSR",     OPCAT_IDXEXT,      0x8d },
935
  { "LDA",     OPCAT_ACCARITH,    0x86 },
936
  { "LDAA",    OPCAT_ARITH,       0x86 },
937
  { "LDAB",    OPCAT_ARITH,       0xc6 },
938
  { "LDB",     OPCAT_ARITH,       0xc6 },
939
  { "LDS",     OPCAT_DBLREG1BYTE, 0x8e },
940
  { "LDX",     OPCAT_DBLREG1BYTE, 0xce },
941
  { "LIB",     OPCAT_PSEUDO,      PSEUDO_INCLUDE },
942
  { "LIBRARY", OPCAT_PSEUDO,      PSEUDO_INCLUDE },
943
  { "LSL",     OPCAT_ACCADDR,     0x08 },
944
  { "LSLA",    OPCAT_ONEBYTE,     0x48 },
945
  { "LSLB",    OPCAT_ONEBYTE,     0x58 },
946
  { "LSR",     OPCAT_ACCADDR,     0x04 },
947
  { "LSRA",    OPCAT_ONEBYTE,     0x44 },
948
  { "LSRB",    OPCAT_ONEBYTE,     0x54 },
949
  { "MACRO",   OPCAT_PSEUDO,      PSEUDO_MACRO },
950
  { "NAM",     OPCAT_PSEUDO,      PSEUDO_NAM },
951
  { "NAME",    OPCAT_PSEUDO,      PSEUDO_NAME },
952
  { "NEG",     OPCAT_ACCADDR,     0x00 },
953
  { "NEGA",    OPCAT_ONEBYTE,     0x40 },
954
  { "NEGB",    OPCAT_ONEBYTE,     0x50 },
955
  { "NOP",     OPCAT_ONEBYTE,     0x01 },
956
  { "OPT",     OPCAT_PSEUDO,      PSEUDO_OPT },
957
  { "OPTION",  OPCAT_PSEUDO,      PSEUDO_OPT },
958
  { "ORA",     OPCAT_ARITH,       0x8a },
959
  { "ORAA",    OPCAT_ARITH,       0x8a },
960
  { "ORAB",    OPCAT_ARITH,       0xca },
961
  { "ORB",     OPCAT_ARITH,       0xca },
962
  { "ORG",     OPCAT_PSEUDO,      PSEUDO_ORG },
963
  { "PAG",     OPCAT_PSEUDO,      PSEUDO_PAG },
964
  { "PAGE",    OPCAT_PSEUDO,      PSEUDO_PAG },
965
  { "PSHA",    OPCAT_ONEBYTE,     0x36 },
966
  { "PSHB",    OPCAT_ONEBYTE,     0x37 },
967
  { "PUB",     OPCAT_PSEUDO,      PSEUDO_PUB },
968
  { "PUBLIC",  OPCAT_PSEUDO,      PSEUDO_PUB },
969
  { "PULA",    OPCAT_ONEBYTE,     0x32 },
970
  { "PULB",    OPCAT_ONEBYTE,     0x33 },
971
  { "REG",     OPCAT_PSEUDO,      PSEUDO_REG },
972
  { "REP",     OPCAT_PSEUDO,      PSEUDO_REP },
973
  { "REPEAT",  OPCAT_PSEUDO,      PSEUDO_REP },
974
  { "RMB",     OPCAT_PSEUDO,      PSEUDO_RMB },
975
  { "ROL",     OPCAT_ACCADDR,     0x09 },
976
  { "ROLA",    OPCAT_ONEBYTE,     0x49 },
977
  { "ROLB",    OPCAT_ONEBYTE,     0x59 },
978
  { "ROR",     OPCAT_ACCADDR,     0x06 },
979
  { "RORA",    OPCAT_ONEBYTE,     0x46 },
980
  { "RORB",    OPCAT_ONEBYTE,     0x56 },
981
  { "RPT",     OPCAT_PSEUDO,      PSEUDO_REP },
982
  { "RTI",     OPCAT_ONEBYTE,     0x3b },
983
  { "RTS",     OPCAT_ONEBYTE,     0x39 },
984
  { "RZB",     OPCAT_PSEUDO,      PSEUDO_RZB },
985
  { "SBA",     OPCAT_ONEBYTE,     0x10 },
986
  { "SBC",     OPCAT_ACCARITH,    0x82 },
987
  { "SBCA",    OPCAT_ARITH,       0x82 },
988
  { "SBCB",    OPCAT_ARITH,       0xc2 },
989
  { "SEC",     OPCAT_ONEBYTE,     0x0d },
990
  { "SEI",     OPCAT_ONEBYTE,     0x0f },
991
  { "SET",     OPCAT_PSEUDO,      PSEUDO_SET },
992
//{ "SETDP",   OPCAT_PSEUDO,      PSEUDO_SETDP },
993
  { "SETLI",   OPCAT_PSEUDO,      PSEUDO_SETLI },
994
  { "SETPG",   OPCAT_PSEUDO,      PSEUDO_SETPG },
995
  { "SEV",     OPCAT_ONEBYTE,     0x0b },
996
  { "SPC",     OPCAT_PSEUDO,      PSEUDO_SPC },
997
  { "STA",     OPCAT_NOIMM |
998
               OPCAT_ACCARITH,    0x87 },
999
  { "STAA",    OPCAT_NOIMM |
1000
               OPCAT_ARITH,       0x87 },
1001
  { "STAB",    OPCAT_NOIMM |
1002
               OPCAT_ARITH,       0xc7 },
1003
  { "STS",     OPCAT_NOIMM |
1004
               OPCAT_DBLREG1BYTE, 0x8f },
1005
  { "STTL",    OPCAT_PSEUDO,      PSEUDO_STTL },
1006
  { "STX",     OPCAT_NOIMM |
1007
               OPCAT_DBLREG1BYTE, 0xcf },
1008
  { "SUB",     OPCAT_ACCARITH,    0x80 },
1009
  { "SUBA",    OPCAT_ARITH,       0x80 },
1010
  { "SUBB",    OPCAT_ARITH,       0xc0 },
1011
  { "SWI",     OPCAT_ONEBYTE,     0x3f },
1012
  { "SYMLEN",  OPCAT_PSEUDO,      PSEUDO_SYMLEN },
1013
  { "TAB",     OPCAT_ONEBYTE,     0x16 },
1014
  { "TAP",     OPCAT_ONEBYTE,     0x06 },
1015
  { "TBA",     OPCAT_ONEBYTE,     0x17 },
1016
  { "TEXT",    OPCAT_PSEUDO,      PSEUDO_TEXT },
1017
  { "TITLE",   OPCAT_PSEUDO,      PSEUDO_NAM },
1018
  { "TPA",     OPCAT_ONEBYTE,     0x07 },
1019
  { "TST",     OPCAT_ACCADDR,     0x0d },
1020
  { "TSTA",    OPCAT_ONEBYTE,     0x4d },
1021
  { "TSTB",    OPCAT_ONEBYTE,     0x5d },
1022
  { "TSX",     OPCAT_ONEBYTE,     0x30 },
1023
  { "TTL",     OPCAT_PSEUDO,      PSEUDO_NAM },
1024
  { "TXS",     OPCAT_ONEBYTE,     0x35 },
1025
  { "WAI",     OPCAT_ONEBYTE,     0x3e },
1026
  };
1027
 
1028
/* expression categories...
1029
   all zeros is ordinary constant.
1030
   bit 1 indicates address within module.
1031
   bit 2 indicates external address.
1032
   bit 4 indicates this can't be relocated if it's an address.
1033
   bit 5 indicates address (if any) is negative.
1034
*/
1035
 
1036
#define EXPRCAT_INTADDR       0x02
1037
#define EXPRCAT_EXTADDR       0x04
1038
#define EXPRCAT_PUBLIC        0x08
1039
#define EXPRCAT_FIXED         0x10
1040
#define EXPRCAT_NEGATIVE      0x20
1041
 
1042
/*****************************************************************************/
1043
/* Symbol definitions                                                        */
1044
/*****************************************************************************/
1045
 
1046
struct symrecord
1047
  {
1048
  char name[MAXIDLEN + 1];              /* symbol name                       */
1049
  char cat;                             /* symbol category                   */
1050
  char isFar;                                           /* far assumed */
1051
  char isFarkw;                                         /* FAR keyword used in symbol definiton */
1052
  unsigned value;                 /* symbol value                      */
1053
  union
1054
    {
1055
    struct symrecord *parent;           /* parent symbol (for COMMON)        */
1056
    long flags;                         /* forward reference flag (otherwise)*/
1057
    } u;
1058
  };
1059
 
1060
                                        /* symbol categories :               */
1061
#define SYMCAT_CONSTANT       0x00      /* constant value (from equ)         */
1062
#define SYMCAT_VARIABLE       0x01      /* variable value (from set)         */
1063
#define SYMCAT_LABEL          0x02      /* address within module (label)     */
1064
#define SYMCAT_VARADDR        0x03      /* variable containing address       */
1065
#define SYMCAT_EXTERN         0x04      /* address in other module (extern)  */
1066
#define SYMCAT_VAREXTERN      0x05      /* variable containing extern addr.  */
1067
#define SYMCAT_UNRESOLVED     0x06      /* unresolved address                */
1068
#define SYMCAT_VARUNRESOLVED  0x07      /* var. containing unresolved addr   */
1069
#define SYMCAT_PUBLIC         0x08      /* public label                      */
1070
#define SYMCAT_MACRO          0x09      /* macro definition                  */
1071
#define SYMCAT_PUBLICUNDEF    0x0A      /* public label (yet undefined)      */
1072
#define SYMCAT_PARMNAME       0x0B      /* parameter name                    */
1073
#define SYMCAT_EMPTY          0x0D      /* empty                             */
1074
#define SYMCAT_REG            0x0E      /* REG directive                     */
1075
#define SYMCAT_TEXT           0x0F      /* /Dsymbol or TEXT label            */
1076
#define SYMCAT_COMMONDATA     0x12      /* COMMON Data                       */
1077
#define SYMCAT_COMMON         0x14      /* COMMON block                      */
1078
#define SYMCAT_LOCALLABEL     0x22      /* local label                       */
1079
#define SYMCAT_EMPTYLOCAL     0x26      /* empty local label                 */
1080
 
1081
                                        /* symbol flags:                     */
1082
#define SYMFLAG_FORWARD       0x01      /* forward reference                 */
1083
#define SYMFLAG_PASSED        0x02      /* passed forward reference          */
1084
 
1085
long symcounter = 0;                    /* # currently loaded symbols        */
1086
struct symrecord symtable[MAXLABELS];   /* symbol table (fixed size)         */
1087
long lclcounter = 0;                    /* # currently loaded local symbols  */
1088
struct symrecord lcltable[MAXLABELS];   /* local symbol table (fixed size)   */
1089
 
1090
/*****************************************************************************/
1091
/* regrecord structure definition                                            */
1092
/*****************************************************************************/
1093
 
1094
struct regrecord
1095
  {
1096
  char *name;                           /* name of the register              */
1097
  unsigned char tfr, psh;               /* bit value for tfr and psh/pul     */
1098
  };
1099
 
1100
/*****************************************************************************/
1101
/* regtable : table of all registers                                         */
1102
/*****************************************************************************/
1103
 
1104
struct regrecord regtable09[]=
1105
  {
1106
  { "D",   0x00, 0x06 },
1107
  { "X",   0x01, 0x10 },
1108
  { "Y",   0x02, 0x20 },
1109
  { "U",   0x03, 0x40 },
1110
  { "S",   0x04, 0x40 },
1111
  { "PC",  0x05, 0x80 },
1112
  { "A",   0x08, 0x02 },
1113
  { "B",   0x09, 0x04 },
1114
  { "CC",  0x0a, 0x01 },
1115
  { "CCR", 0x0a, 0x01 },
1116
  { "DP",  0x0b, 0x08 },
1117
  { "DPR", 0x0b, 0x08 },
1118
  { 0,     0,    0    }
1119
  };
1120
 
1121
struct regrecord regtable63[]=          /* same for HD6309                   */
1122
  {
1123
  { "D",   0x00, 0x06 },
1124
  { "X",   0x01, 0x10 },
1125
  { "Y",   0x02, 0x20 },
1126
  { "U",   0x03, 0x40 },
1127
  { "S",   0x04, 0x40 },
1128
  { "PC",  0x05, 0x80 },
1129
  { "W",   0x06, 0x00 },
1130
  { "V",   0x07, 0x00 },
1131
  { "A",   0x08, 0x02 },
1132
  { "B",   0x09, 0x04 },
1133
  { "CC",  0x0a, 0x01 },
1134
  { "CCR", 0x0a, 0x01 },
1135
  { "DP",  0x0b, 0x08 },
1136
  { "DPR", 0x0b, 0x08 },
1137
  { "0",   0x0c, 0x00 },
1138
  { "E",   0x0e, 0x00 },
1139
  { "F",   0x0f, 0x00 },
1140
  { 0,     0,    0    }
1141
  };
1142
 
1143
struct regrecord regtable00[]=
1144
  {
1145
  { "X",   0x01, 0x10 },
1146
  { "S",   0x04, 0x40 },
1147
  { "PC",  0x05, 0x80 },
1148
  { "A",   0x08, 0x02 },
1149
  { "B",   0x09, 0x04 },
1150
  { "CC",  0x0a, 0x01 },
1151
  { "CCR", 0x0a, 0x01 },
1152
  { 0,     0,    0    }
1153
  };
1154
 
1155
/*****************************************************************************/
1156
/* bitregtable : table of all bit transfer registers                         */
1157
/*****************************************************************************/
1158
 
1159
struct regrecord bitregtable09[] =
1160
  {
1161
  { "CC",  0x00, 0x00 },
1162
  { "A",   0x01, 0x01 },
1163
  { "B",   0x02, 0x02 },
1164
  };
1165
 
1166
struct regrecord bitregtable00[] =
1167
  {
1168
  { "CC",  0x00, 0x00 },
1169
  { "A",   0x01, 0x01 },
1170
  { "B",   0x02, 0x02 },
1171
  };
1172
 
1173
/*****************************************************************************/
1174
/* relocrecord structure definition                                          */
1175
/*****************************************************************************/
1176
 
1177
struct relocrecord
1178
  {
1179
  unsigned addr;                  /* address that needs relocation     */
1180
  char exprcat;                         /* expression category               */
1181
  struct symrecord *sym;                /* symbol for relocation             */
1182
  };
1183
 
1184
long relcounter = 0;                    /* # currently defined relocations   */
1185
struct relocrecord reltable[MAXRELOCS]; /* relocation table (fixed size)     */
1186
long relhdrfoff;                        /* FLEX Relocatable Global Hdr Offset*/
1187
 
1188
/*****************************************************************************/
1189
/* Options definitions                                                       */
1190
/*****************************************************************************/
1191
 
1192
#define OPTION_M09    0x00000001L       /* MC6809 mode                       */
1193
#define OPTION_H63    0x00000002L       /* HD6309 mode                       */
1194
#define OPTION_M00    0x00000004L       /* MC6800 mode                       */
1195
#define OPTION_PAG    0x00000008L       /* page formatting ON                */
1196
#define OPTION_CON    0x00000010L       /* print cond. skipped code          */
1197
#define OPTION_MAC    0x00000020L       /* print macro calling line (default)*/
1198
#define OPTION_EXP    0x00000040L       /* print macro expansion lines       */
1199
#define OPTION_SYM    0x00000080L       /* print symbol table (default)      */
1200
#define OPTION_MUL    0x00000100L       /* print multiple oc lines (default) */
1201
#define OPTION_LP1    0x00000200L       /* print pass 1 listing              */
1202
#define OPTION_DAT    0x00000400L       /* print date in listing (default)   */
1203
#define OPTION_NUM    0x00000800L       /* print line numbers                */
1204
#define OPTION_INV    0x00001000L       /* print invisible lines             */
1205
#define OPTION_TSC    0x00002000L       /* TSC-compatible source format      */
1206
#define OPTION_WAR    0x00004000L       /* print warnings                    */
1207
#define OPTION_CLL    0x00008000L       /* check line length (default)       */
1208
#define OPTION_LFN    0x00010000L       /* print long file names             */
1209
#define OPTION_LLL    0x00020000L       /* list library lines                */
1210
#define OPTION_GAS    0x00040000L       /* Gnu AS compatibility              */
1211
#define OPTION_REL    0x00080000L       /* print relocation table            */
1212
#define OPTION_TXT    0x00100000L       /* print text table                  */
1213
#define OPTION_LIS    0x00200000L       /* print assembler output listing    */
1214
#define OPTION_LPA    0x00400000L       /* listing in f9dasm patch format    */
1215
#define OPTION_RTF        0x00800000L
1216
#define OPTION_X32        0x01000000L           /* 32 bit index registers            */
1217
#define OPTION_X16        0x02000000L           /* 32 bit index registers            */
1218
 
1219
struct
1220
  {
1221
  char *Name;
1222
  unsigned long dwAdd;
1223
  unsigned long dwRem;
1224
  } Options[] =
1225
  {/*Name          Add      Remove */
1226
  { "PAG",  OPTION_PAG,          0 },
1227
  { "NOP",           0, OPTION_PAG },
1228
  { "CON",  OPTION_CON,          0 },
1229
  { "NOC",           0, OPTION_CON },
1230
  { "MAC",  OPTION_MAC,          0 },
1231
  { "NOM",           0, OPTION_MAC },
1232
  { "EXP",  OPTION_EXP,          0 },
1233
  { "NOE",           0, OPTION_EXP },
1234
  { "SYM",  OPTION_SYM,          0 },
1235
  { "NOS",           0, OPTION_SYM },
1236
  { "MUL",  OPTION_MUL,          0 },
1237
  { "NMU",           0, OPTION_MUL },
1238
  { "LP1",  OPTION_LP1,          0 },
1239
  { "NO1",           0, OPTION_LP1 },
1240
  { "DAT",  OPTION_DAT,          0 },
1241
  { "NOD",           0, OPTION_DAT },
1242
  { "NUM",  OPTION_NUM,          0 },
1243
  { "NON",           0, OPTION_NUM },
1244
  { "INV",  OPTION_INV,          0 },
1245
  { "NOI",           0, OPTION_INV },
1246
  { "TSC",  OPTION_TSC,          0 },
1247
  { "NOT",           0, OPTION_TSC },
1248
  { "WAR",  OPTION_WAR,          0 },
1249
  { "NOW",           0, OPTION_WAR },
1250
  { "CLL",  OPTION_CLL,          0 },
1251
  { "NCL",           0, OPTION_CLL },
1252
  { "LFN",  OPTION_LFN,          0 },
1253
  { "NLF",           0, OPTION_LFN },
1254
  { "LLL",  OPTION_LLL,          0 },
1255
  { "NLL",           0, OPTION_LLL },
1256
  { "GAS",  OPTION_GAS,          0 },
1257
  { "NOG",           0, OPTION_GAS },
1258
  { "REL",  OPTION_REL,          0 },
1259
  { "NOR",           0, OPTION_REL },
1260
  { "H63",  OPTION_H63, OPTION_M09 | OPTION_M00 },
1261
  { "M68",  OPTION_M09, OPTION_H63 | OPTION_M00 },
1262
  { "M09",  OPTION_M09, OPTION_H63 | OPTION_M00 },
1263
  { "M00",  OPTION_M00, OPTION_H63 | OPTION_M09 },
1264
  { "TXT",  OPTION_TXT,          0 },
1265
  { "NTX",           0, OPTION_TXT },
1266
  { "LIS",  OPTION_LIS,          0 },
1267
  { "NOL",           0, OPTION_LIS },
1268
  { "LPA",  OPTION_LPA, OPTION_NUM | OPTION_CLL }, // LPA inhibits NUM / CLL!
1269
  { "NLP",           0, OPTION_LPA },
1270
  { "X32",  OPTION_X32, OPTION_X16 },
1271
  { "X16",  OPTION_X16, OPTION_X32 }
1272
  };
1273
 
1274
unsigned long dwOptions =               /* options flags, init to default    */
1275
    OPTION_M09 |
1276
    OPTION_MAC |
1277
    OPTION_SYM |
1278
    OPTION_MUL |
1279
    OPTION_DAT |
1280
    OPTION_WAR |
1281
    OPTION_CLL |
1282
    OPTION_LLL |
1283
    OPTION_REL |
1284
    OPTION_LIS;
1285
 
1286
/*****************************************************************************/
1287
/* arrays of error/warning messages                                          */
1288
/*****************************************************************************/
1289
                                        /* defined error flags               */
1290
#define ERR_OK            0x0000        /* all is well                       */
1291
#define ERR_EXPR          0x0001        /* Error in expression               */
1292
#define ERR_ILLEGAL_ADDR  0x0002        /* Illegal adressing mode            */
1293
#define ERR_LABEL_UNDEF   0x0004        /* Undefined label                   */
1294
#define ERR_LABEL_MULT    0x0008        /* Label multiply defined            */
1295
#define ERR_RANGE         0x0010        /* Relative branch out of range      */
1296
#define ERR_LABEL_MISSING 0x0020        /* Missing label                     */
1297
#define ERR_OPTION_UNK    0x0040        /* Option unknown                    */
1298
#define ERR_MALLOC        0x0080        /* Out of memory                     */
1299
#define ERR_NESTING       0x0100        /* Nesting not allowed               */
1300
#define ERR_RELOCATING    0x0200        /* Statement not valid for reloc mode*/
1301
#define ERR_ERRTXT        0x4000        /* ERR text output                   */
1302
#define ERR_ILLEGAL_MNEM  0x8000        /* Illegal mnemonic                  */
1303
 
1304
char *errormsg[]=
1305
  {
1306
  "Error in expression",                /* 1     ERR_EXPR                    */
1307
  "Illegal addressing mode",            /* 2     ERR_ILLEGAL_ADDR            */
1308
  "Undefined label",                    /* 4     ERR_LABEL_UNDEF             */
1309
  "Multiple definitions of label",      /* 8     ERR_LABEL_MULT              */
1310
  "Relative branch out of range",       /* 16    ERR_RANGE                   */
1311
  "Missing label",                      /* 32    ERR_LABEL_MISSING           */
1312
  "Unknown option specified",           /* 64    ERR_OPTION_UNK              */
1313
  "Out of memory",                      /* 128   ERR_MALLOC                  */
1314
  "Nesting not allowed",                /* 256   ERR_NESTING                 */
1315
  "Illegal for current relocation mode",/* 512   ERR_RELOCATING              */
1316
  "",                                   /* 1024                              */
1317
  "",                                   /* 2048                              */
1318
  "",                                   /* 4096                              */
1319
  "",                                   /* 8192                              */
1320
  NULL,                                 /* 16384 ERR_ERRTXT (ERR output)     */
1321
  "Illegal mnemonic"                    /* 32768 ERR_ILLEGAL_MNEM            */
1322
  };
1323
 
1324
                                        /* defined warning flags             */
1325
#define WRN_OK            0x0000        /* All OK                            */
1326
#define WRN_OPT           0x0001        /* Long branch in short range        */
1327
#define WRN_SYM           0x0002        /* Symbolic text undefined           */
1328
#define WRN_AREA          0x0004        /* Area already in use               */
1329
#define WRN_AMBIG         0x0008        /* Ambiguous 6800 opcode             */
1330
 
1331
char *warningmsg[] =
1332
  {
1333
  "Long branch within short branch "    /* 1     WRN_OPT                     */
1334
      "range could be optimized",
1335
  "Symbolic text undefined",            /* 2     WRN_SYM                     */
1336
  "Area already in use",                /* 4     WRN_AREA                    */
1337
  "Ambiguous 6800 alternate notation",  /* 8     WRN_AMBIG                   */
1338
  "",                                   /* 16                                */
1339
  "",                                   /* 32                                */
1340
  "",                                   /* 64                                */
1341
  "",                                   /* 128                               */
1342
  "",                                   /* 256                               */
1343
  "",                                   /* 512                               */
1344
  "",                                   /* 1024                              */
1345
  "",                                   /* 2048                              */
1346
  "",                                   /* 4096                              */
1347
  "",                                   /* 8192                              */
1348
  "",                                   /* 18384                             */
1349
  ""                                    /* 32768                             */
1350
  };
1351
 
1352
/*****************************************************************************/
1353
/* Listing Definitions                                                       */
1354
/*****************************************************************************/
1355
 
1356
#define LIST_OFF  0x00                  /* listing is generally off          */
1357
#define LIST_ON   0x01                  /* listing is generally on           */
1358
 
1359
char listing = LIST_OFF;                /* listing flag                      */
1360
 
1361
/*****************************************************************************/
1362
/* Global variables                                                          */
1363
/*****************************************************************************/
1364
 
1365
FILE *listfile = NULL;                  /* list file                         */
1366
FILE *objfile = NULL;                   /* object file                       */
1367
char listname[FNLEN + 1];               /* list file name                    */
1368
char objname[FNLEN + 1];                /* object file name                  */
1369
char srcname[FNLEN + 1];                /* source file name                  */
1370
 
1371
                                        /* assembler mode specifics:         */
1372
struct oprecord *optable = optable09;   /* used op table                     */
1373
                                        /* size of this table                */
1374
int optablesize = sizeof(optable09) / sizeof(optable09[0]);
1375
struct regrecord *regtable = regtable09;/* used register table               */
1376
                                        /* used bit register table           */
1377
struct regrecord *bitregtable = bitregtable09;
1378
void scanoperands09(struct relocrecord *pp);
1379
void (*scanoperands)(struct relocrecord *) = scanoperands09;
1380
 
1381
char pass;                              /* Assembler pass = 1 or 2           */
1382
char relocatable = 0;                   /* relocatable object flag           */
1383
char absmode = 1;                       /* absolute mode                     */
1384
long global = 0;                        /* all labels global flag            */
1385
long common = 0;                        /* common definition flag            */
1386
struct symrecord * commonsym = NULL;    /* current common main symbol        */
1387
char terminate;                         /* termination flag                  */
1388
char generating;                        /* code generation flag              */
1389
unsigned loccounter,oldlc;        /* Location counter                  */
1390
 
1391
char inpline[LINELEN];                  /* Current input line (not expanded) */
1392
char srcline[LINELEN];                  /* Current source line               */
1393
char * srcptr;                          /* Pointer to line being parsed      */
1394
 
1395
char unknown;          /* flag to indicate value unknown */
1396
char certain;          /* flag to indicate value is certain at pass 1*/
1397
long error;            /* flags indicating errors in current line. */
1398
long errors;           /* number of errors in current pass */
1399
long warning;          /* flags indicating warnings in current line */
1400
long warnings;         /* number of warnings in current pass */
1401
long nTotErrors;                        /* total # of errors                 */
1402
long nTotWarnings;                      /* total # warnings                  */
1403
char exprcat;          /* category of expression being parsed, eg.
1404
                          label or constant, this is important when
1405
                          generating relocatable object code. */
1406
 
1407
int maxidlen = MAXIDLEN;                /* maximum ID length                 */
1408
 
1409
char modulename[MAXIDLEN + 1] = "";     /* module name buffer                */
1410
char namebuf[MAXIDLEN + 1];             /* name buffer for parsing           */
1411
char unamebuf[MAXIDLEN + 1];            /* name buffer in uppercase          */
1412
 
1413
char isFar,isFarkw;
1414
int vercount;
1415
char mode;
1416
char isX32;
1417
char isPostIndexed;
1418
 
1419
/* adressing mode:                   */
1420
#define ADRMODE_IMM  0                  /* 0 = immediate                     */
1421
#define ADRMODE_DIR  1                  /* 1 = direct                        */
1422
#define ADRMODE_EXT  2                  /* 2 = extended                      */
1423
#define ADRMODE_IDX  3                  /* 3 = indexed                       */
1424
#define ADRMODE_POST 4                  /* 4 = postbyte                      */
1425
#define ADRMODE_PCR  5                  /* 5 = PC relative (with postbyte)   */
1426
#define ADRMODE_IND  6                  /* 6 = indirect                      */
1427
#define ADRMODE_PIN  7                  /* 7 = PC relative & indirect        */
1428
#define ADRMODE_DBL_IND 8
1429
 
1430
char opsize;                            /* desired operand size :            */
1431
                                        /* 0=dunno,1=5, 2=8, 3=16, 4=32      */
1432
long operand;
1433
unsigned short postbyte;
1434
 
1435
long dpsetting = 0;                     /* Direct Page Default = 0           */
1436
 
1437
unsigned short codebuf[256];
1438
int codeptr;                            /* byte offset within instruction    */
1439
int suppress;                           /* 0=no suppress                     */
1440
                                        /* 1=until ENDIF                     */
1441
                                        /* 2=until ELSE                      */
1442
                                        /* 3=until ENDM                      */
1443
char condline = 0;                      /* flag whether on conditional line  */
1444
int ifcount;                            /* count of nested IFs within        */
1445
                                        /* suppressed text                   */
1446
 
1447
#define OUT_NONE  -1                    /* no output                         */
1448
#define OUT_BIN   0                     /* binary output                     */
1449
#define OUT_SREC  1                     /* Motorola S-Records                */
1450
#define OUT_IHEX  2                     /* Intel Hex Records                 */
1451
#define OUT_FLEX  3                     /* Flex9 ASMB-compatible output      */
1452
#define OUT_GAS   4                     /* GNU relocation output             */
1453
#define OUT_REL   5                     /* Flex9 RELASMB output              */
1454
#define OUT_VER   6
1455
int outmode = OUT_BIN;                  /* default to binary output          */
1456
 
1457
unsigned hexaddr;
1458
int hexcount;
1459
unsigned short hexbuffer[256];
1460
unsigned int chksum;
1461
unsigned vslide;
1462
 
1463
int nRepNext = 0;                       /* # repetitions for REP pseudo-op   */
1464
int nSkipCount = 0;                     /* # lines to skip                   */
1465
 
1466 16 robfinch
unsigned tfradr = 0;
1467 4 robfinch
int tfradrset = 0;
1468
 
1469
int nCurLine = 0;                       /* current output line on page       */
1470
int nCurCol = 0;                        /* current output column on line     */
1471
int nCurPage = 0;                       /* current page #                    */
1472
int nLinesPerPage = 66;                 /* # lines on a page                 */
1473
int nColsPerLine = 200;                  /* # columns per line                */
1474
char szTitle[128] = "";                 /* title for listings                */
1475
char szSubtitle[128] = "";              /* subtitle for listings             */
1476
 
1477
char szBuf1[LINELEN];                   /* general-purpose buffers for parse */
1478
char szBuf2[LINELEN];
1479
 
1480
struct linebuf *macros[MAXMACROS];      /* pointers to the macros            */
1481
int nMacros = 0;                        /* # parsed macros                   */
1482
int inMacro = 0;                        /* flag whether in macro definition  */
1483
 
1484
char *texts[MAXTEXTS];                  /* pointers to the texts             */
1485
int nPredefinedTexts = 0;               /* # predefined texts                */
1486
int nTexts = 0;                         /* # currently defined texts         */
1487
 
1488
//unsigned char bUsedBytes[8192] = {0};   /* 1 bit per byte of the address spc */
1489
 
1490
/*****************************************************************************/
1491
/* Necessary forward declarations                                            */
1492
/*****************************************************************************/
1493
 
1494
void processline();
1495
struct linebuf *readfile(char *name, unsigned char lvl, struct linebuf *after);
1496
struct linebuf *readbinary(char *name, unsigned char lvl, struct linebuf *after, struct symrecord *lp);
1497
 
1498
/*****************************************************************************/
1499
/* allocline : allocates a line of text                                      */
1500
/*****************************************************************************/
1501
 
1502
struct linebuf * allocline
1503
    (
1504
    struct linebuf *prev,
1505
    char *fn,
1506
    int line,
1507
    unsigned char lvl,
1508
    char *text
1509
    )
1510
{
1511
struct linebuf *pNew = malloc(sizeof(struct linebuf) + strlen(text));
1512
if (!pNew)
1513
  return NULL;
1514
pNew->next = (prev) ? prev->next : NULL;
1515
pNew->prev = prev;
1516
if (prev)
1517
  prev->next = pNew;
1518
if (pNew->next)
1519
  pNew->next->prev = pNew;
1520
pNew->lvl = lvl;
1521
pNew->fn = fn;
1522
pNew->ln = line;
1523
pNew->rel = ' ';
1524
strcpy(pNew->txt, text);
1525
return pNew;
1526
}
1527
 
1528
/*****************************************************************************/
1529
/* expandfn : eventually expands a file name to full-blown path              */
1530
/*****************************************************************************/
1531
 
1532
char const *expandfn(char const *fn)
1533
{
1534
#ifdef WIN32
1535
static char szBuf[_MAX_PATH];           /* allocate big buffer               */
1536
 
1537
if (dwOptions & OPTION_LFN)             /* if long file names wanted         */
1538
  return _fullpath(szBuf, fn, sizeof(szBuf));
1539
#endif
1540
 
1541
return fn;                              /* can't do that yet                 */
1542
}
1543
 
1544
/*****************************************************************************/
1545
/* PageFeed : advances the list file                                         */
1546
/*****************************************************************************/
1547
 
1548
void PageFeed()
1549
{
1550
time_t tim;
1551
struct tm *ltm;
1552
 
1553
time(&tim);
1554
ltm = localtime(&tim);
1555
 
1556
fputc('\x0c', listfile);                /* print header                      */
1557
nCurPage++;                             /* advance to next page              */
1558
fprintf(listfile, "\n\n%-32.32s ", szTitle);
1559
if (dwOptions & OPTION_DAT)
1560
  fprintf(listfile,
1561
          "%04d-%02d-%02d ",
1562
          ltm->tm_year + 1900,
1563
          ltm->tm_mon + 1,
1564
          ltm->tm_mday);
1565
fprintf(listfile,
1566
        "A09 %d Assembler V" VERSION " Page %d\n",
1567
        (dwOptions & OPTION_H63) ? 6309 :
1568
            (dwOptions & OPTION_M00) ? 6800 :
1569
            6809,
1570
        nCurPage);
1571
fprintf(listfile, "%-.79s\n\n", szSubtitle);
1572
 
1573
nCurLine = 5;                           /* remember current line             */
1574
nCurCol = 0;                            /* and reset current column          */
1575
}
1576
 
1577
/*****************************************************************************/
1578
/* putlist : puts something to the list file                                 */
1579
/*****************************************************************************/
1580
 
1581
void putlist(char *szFmt, ...)
1582
{
1583
char szList[1024];                      /* buffer for 1k list output         */
1584
char *p;
1585
 
1586
va_list al;
1587
va_start(al, szFmt);
1588
vsprintf(szList, szFmt, al);            /* generate formatted output buffer  */
1589
va_end(al);
1590
 
1591
for (p = szList; *p; p++)               /* then walk through the buffer      */
1592
  {
1593
  fputc(*p, listfile);                  /* print out each character          */
1594
  if (*p == '\n')                       /* if newline sent                   */
1595
    {
1596
    nCurLine++;
1597
    nCurCol = 0;
1598
    if ((nCurLine >= nLinesPerPage) &&  /* if beyond # lines per page        */
1599
        (dwOptions & OPTION_PAG))       /* if pagination activated           */
1600
      PageFeed();                       /* do a page feed                    */
1601
    }
1602
  else                                  /* if another character              */
1603
    {
1604
    nCurCol++;                          /* advance to next column            */
1605
    if (dwOptions & OPTION_CLL)         /* if line length checked            */
1606
      {
1607
                                        /* check if word would go too far    */
1608
      if ((nCurCol >= nColsPerLine * 3 / 4) &&
1609
          (*p == ' '))
1610
        {
1611
        int i;                          /* look whether more delimiters      */
1612
        char c;
1613
        for (i = nCurCol + 1; i < nColsPerLine; i++)
1614
          {
1615
          c = p[i - nCurCol];
1616
          if ((c == '\t') || (c == ' ') || (!c))
1617
            break;
1618
          }
1619
        if (i >= nColsPerLine)          /* if no more delimiters,            */
1620
          nCurCol = nColsPerLine;       /* make sure to advance to new line  */
1621
        }
1622
 
1623
      if (nCurCol >= nColsPerLine)      /* if it IS too far                  */
1624
        {
1625
        putlist("\n");                  /* recurse with a newline            */
1626
        nCurCol = 0;
1627
        }
1628
      }
1629
    }
1630
  }
1631
}
1632
 
1633
/*****************************************************************************/
1634
/* findop : finds a mnemonic in table using binary search                    */
1635
/*****************************************************************************/
1636
 
1637
struct oprecord * findop(char * nm)
1638
{
1639
int lo,hi,i,s;
1640
 
1641
lo = 0;
1642
hi = optablesize - 1;
1643
do
1644
  {
1645
  i = (lo + hi) / 2;
1646
  s = strcmp(optable[i].name, nm);
1647
  if (s < 0)
1648
    lo = i + 1;
1649
  else if (s > 0)
1650
    hi = i - 1;
1651
  else
1652
    break;
1653
  } while (hi >= lo);
1654
if (s)
1655
  return NULL;
1656
return optable + i;
1657
}
1658
 
1659
/*****************************************************************************/
1660
/* findlocal : finds a local symbol table record                             */
1661
/*****************************************************************************/
1662
 
1663
struct symrecord * findlocal(struct symrecord *sym, char forward, int insert)
1664
{
1665
static struct symrecord empty = {"", SYMCAT_EMPTYLOCAL, 0, {0}};
1666
int lo,hi,i,j,s;
1667
 
1668
if ((!sym) ||                           /* if no main symbol for that        */
1669
    ((!insert) &&                       /* or not inserting, but             */
1670
     (sym->cat == SYMCAT_EMPTYLOCAL)))  /*    yet undefined label            */
1671
  return sym;                           /* pass back main symbol             */
1672
 
1673
lo = 0;                                 /* do binary search for the thing    */
1674
hi = lclcounter - 1;
1675
s = 1;
1676
i = 0;
1677
while (hi >= lo)
1678
  {
1679
  i = (lo + hi) / 2;
1680
  s = lcltable[i].value - loccounter;   /* binary search for current address */
1681
  if (s < 0)
1682
    lo = i + 1;
1683
  else if (s > 0)
1684
    hi = i - 1;
1685
  else                                  /* if found,                         */
1686
    {                                   /* go to 1st of this value           */
1687
    while ((i) && (lcltable[i - 1].value == loccounter))
1688
      i--;
1689
    while ((i < lclcounter) &&          /* search for the NAME now           */
1690
           (lcltable[i].value == loccounter))
1691
      {
1692
      s = strcmp(sym->name, lcltable[i].name);
1693
      if (s <= 0)
1694
        {
1695
        if (s)
1696
          i--;
1697
        break;
1698
        }
1699
      i++;
1700
      }
1701
    if (s)                              /* if not found, re-set              */
1702
      {
1703
      if (i >= lclcounter)
1704
        s = 1;
1705
      else
1706
        s = lcltable[i].value - loccounter;
1707
      }
1708
    break;
1709
    }
1710
  }
1711
 
1712
if (insert)                             /* if inserting,                     */
1713
  {
1714
  if (!s)                               /* if address is already in use      */
1715
    {                                   /* but not the correct label         */
1716
    if (strcmp(sym->name, lcltable[i].name))
1717
      error |= ERR_LABEL_MULT;          /* set error                         */
1718
    return lcltable + i;                /* return the local symbol           */
1719
    }
1720
  i = (s < 0 ? i + 1 : i);
1721
  if (lclcounter == MAXLABELS)
1722
    {
1723
    printf("%s(%ld): error 25: out of local symbol storage\n",
1724
           expandfn(curline->fn), curline->ln);
1725
    if (((dwOptions & OPTION_LP1) || pass ==  MAX_PASSNO) && (listing & LIST_ON))
1726
      putlist( "*** Error 25: out of local symbol storage\n");
1727
    exit(4);
1728
    }
1729
  sym->cat = SYMCAT_LOCALLABEL;
1730
  for (j = lclcounter; j > i; j--)
1731
    lcltable[j] = lcltable[j - 1];
1732
  lclcounter++;
1733
  strcpy(lcltable[i].name, sym->name);
1734
  lcltable[i].cat = SYMCAT_LOCALLABEL;
1735
  lcltable[i].value = loccounter;
1736
  lcltable[i].u.parent = NULL;
1737
  return lcltable + i;                  /* pass back this symbol             */
1738
  }
1739
 
1740
if (forward)                            /* if forward search                 */
1741
  {
1742
  i = (s < 0 ? i - 1 : i);
1743
  for (; i < lclcounter; i++)
1744
    {
1745
    if ((!strcmp(lcltable[i].name, sym->name)) &&
1746
        (lcltable[i].value > loccounter))
1747
      return lcltable + i;
1748
    }
1749
  }
1750
else                                    /* if backward search                */
1751
  {
1752
  i = (s > 0 ? i + 1 : i);
1753
  for (; i >= 0; i--)
1754
    {
1755
    if ((!strcmp(lcltable[i].name, sym->name)) &&
1756
        (lcltable[i].value <= loccounter))
1757
      return lcltable + i;
1758
    }
1759
  }
1760
 
1761
return &empty;                          /* if not found, return empty label  */
1762
}
1763
 
1764
/*****************************************************************************/
1765
/* findsym : finds symbol table record; inserts if not found                 */
1766
/*           uses binary search, maintains sorted table                      */
1767
/*****************************************************************************/
1768
 
1769
struct symrecord * findsym (char * nm, int insert)
1770
{
1771
int lo,hi,i,j,s;
1772
char islocal = 0, forward = 0;
1773
char name[MAXIDLEN + 1] = "";
1774
                                        /* copy name to internal buffer      */
1775
strncpy(name, (nm) ? nm : "", sizeof(name) - 1);
1776
for (i = 0; name[i]; i++)               /* determine whether local label     */
1777
  if ((name[i] < '0') || (name[i] > '9'))
1778
    break;
1779
if (i)                                  /* if starting with number           */
1780
  {
1781
  if (!name[i])                         /* if ONLY numeric                   */
1782
    islocal = 1;                        /* this is a local label             */
1783
  else                                  /* otherwise check direction         */
1784
    {
1785
    switch(toupper(name[i]))
1786
      {
1787
      case 'B' :                        /* backward reference ?              */
1788
        islocal = 2;                    /* this is a local label reference   */
1789
        forward = 0;
1790
        break;
1791
      case 'F' :                        /* forward reference ?               */
1792
        islocal = 2;                    /* this is a local label reference   */
1793
        forward = 1;
1794
        break;
1795
      }
1796
    if (islocal && name[i + 1])         /* if followed by anything else      */
1797
      islocal = 0;                      /* reset flag for local label        */
1798
    else                                /* otherwise                         */
1799
      name[i] = 0;                      /* remove the direction              */
1800
    }
1801
  }
1802
 
1803
lo = 0;                                 /* do binary search for the thing    */
1804
hi = symcounter - 1;
1805
s = 1;
1806
i = 0;
1807
while (hi >= lo)
1808
  {
1809
  i = (lo + hi) / 2;
1810
  s = strcmp(symtable[i].name, name);
1811
  if (s < 0)
1812
    lo = i + 1;
1813
  else if (s > 0)
1814
    hi = i - 1;
1815
  else
1816
    break;
1817
  }
1818
 
1819
if (s)                                  /* if symbol not found               */
1820
  {
1821
  if (!insert)                          /* if inserting prohibited,          */
1822
    return NULL;                        /* return without pointer            */
1823
 
1824
  i = (s < 0 ? i + 1 : i);
1825
  if (symcounter == MAXLABELS)
1826
    {
1827
    printf("%s(%ld): error 23: out of symbol storage\n",
1828
           expandfn(curline->fn), curline->ln);
1829
    if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
1830
      putlist( "*** Error 23: out of symbol storage\n");
1831
    exit(4);
1832
    }
1833
  if (commonsym >= symtable + i)
1834
    commonsym++;
1835
  for (j = 0; j < symcounter; j++)
1836
    if (symtable[j].u.parent >= symtable + i)
1837
      symtable[j].u.parent++;
1838
  for (j = symcounter; j > i; j--)
1839
    symtable[j] = symtable[j-1];
1840
  symcounter++;
1841
  strcpy(symtable[i].name, name);
1842
  symtable[i].cat = (islocal) ? SYMCAT_EMPTYLOCAL : SYMCAT_EMPTY;
1843
  symtable[i].value = 0;
1844
  symtable[i].u.flags = 0;
1845
  }
1846
 
1847
if (islocal)                            /* if searching for a local label    */
1848
  return findlocal(symtable + i,        /* search for the local label        */
1849
                   forward, (islocal < 2));
1850
 
1851
return symtable + i;                    /* return the found or inserted sym  */
1852
}
1853
 
1854
/*****************************************************************************/
1855
/* findsymat : finds 1st symbol fo a given address                           */
1856
/*****************************************************************************/
1857
 
1858
char *findsymat(unsigned addr)
1859
{
1860
/* since the symbol table is sorted by name, this needs a sequential search  */
1861
int i;
1862
for (i = 0; i < symcounter; i++)
1863
  if (symtable[i].cat != SYMCAT_EMPTY)
1864
    {
1865
    if (symtable[i].cat == SYMCAT_TEXT)
1866
      continue;
1867
    if (symtable[i].value == addr)
1868
      return symtable[i].name;
1869
    }
1870
return NULL;
1871
}
1872
 
1873
/*****************************************************************************/
1874
/* settext : sets a text symbol                                              */
1875
/*****************************************************************************/
1876
 
1877
int settext(char *namebuf, char *text)
1878
{
1879
struct symrecord *lp = findsym(namebuf, 1);
1880
int len;
1881
int special = 0;
1882
 
1883
if (!lp)
1884
  {
1885
  error |= ERR_LABEL_UNDEF;
1886
  return -1;
1887
  }
1888
if (lp->cat != SYMCAT_EMPTY &&
1889
    lp->cat != SYMCAT_TEXT)
1890
  {
1891
  error |= ERR_LABEL_MULT;
1892
  return -1;
1893
  }
1894
 
1895
if (lp->cat != SYMCAT_EMPTY)
1896
  free(texts[lp->value]);
1897
else if (nTexts >= MAXTEXTS)
1898
  {
1899
  error |= ERR_MALLOC;
1900
  return -1;
1901
  }
1902
else
1903
  {
1904
  lp->cat = SYMCAT_TEXT;
1905
  lp->value = nTexts++;
1906
  }
1907
 
1908
if (!text)                              /* if NULL input                     */
1909
  text = "";                            /* assume empty string               */
1910
 
1911
for (len = 0; text[len]; len++)
1912
  if ((isspace(text[len])) ||
1913
      (text[len] == ','))
1914
    special = 1;
1915
if (!len)                               /* empty string?                     */
1916
  special = 1;                          /* that's special anyway.            */
1917
if (special && len &&                   /* if delimited special string       */
1918
    (text[0] == '\'' || text[0] == '\"') &&
1919
    (text[len - 1] == text[0]))
1920
  special = 0;                          /* forget that "special" flag        */
1921
 
1922
len += (special) ? 3 : 1;
1923
texts[lp->value] = malloc(len);
1924
if (texts[lp->value])
1925
  {
1926
  if (special)
1927
    texts[lp->value][0] = '\"';
1928
  strcpy(texts[lp->value] + special, text);
1929
  if (special)
1930
    strcat(texts[lp->value], "\"");
1931
  }
1932
 
1933
return lp->value;
1934
}
1935
 
1936
/*****************************************************************************/
1937
/* outsymtable : prints the symbol table                                     */
1938
/*****************************************************************************/
1939
 
1940
void outsymtable()
1941
{
1942
int i,j = 0;
1943
 
1944
if (dwOptions & OPTION_PAG)             /* if pagination active,             */
1945
  {
1946
  if (nCurLine > 5)                     /* if not on 1st line,               */
1947
    PageFeed();                         /* shift to next page                */
1948
  }
1949
else
1950
  putlist("\n");
1951
 
1952
putlist("SYMBOL TABLE");
1953
for (i = 0; i < symcounter; i++)
1954
  if (symtable[i].cat != SYMCAT_EMPTY)
1955
    {
1956
                                        /* suppress listing of predef texts  */
1957
    if ((symtable[i].cat == SYMCAT_TEXT) &&
1958
        (symtable[i].value < nPredefinedTexts))
1959
      continue;
1960
                                        /* if local label                    */
1961
    if (symtable[i].cat == SYMCAT_LOCALLABEL)
1962
      {
1963
      int k;                            /* walk local label list             */
1964
      for (k = 0; k < lclcounter; k++)
1965
        if (!strcmp(lcltable[k].name, symtable[i].name))
1966
          {
1967
          if (j % 4 == 0)
1968
            putlist("\n");
1969
          putlist( " %9s %02d %08X", lcltable[k].name, lcltable[k].cat,
1970
                                     lcltable[k].value);
1971
          j++;
1972
          }
1973
      }
1974
    else                                /* if normal label                   */
1975
      {
1976
      if (j % 4 == 0)
1977
        putlist("\n");
1978
      putlist( " %9s %02d %08X", symtable[i].name,symtable[i].cat,
1979
                                 symtable[i].value);
1980
      j++;
1981
      }
1982
    }
1983
putlist("\n%d SYMBOLS\n", j);
1984
}
1985
 
1986
/*****************************************************************************/
1987
/* outreltable : prints the relocation table                                 */
1988
/*****************************************************************************/
1989
 
1990
void outreltable()
1991
{
1992
int i,j = 0;
1993
 
1994
if (dwOptions & OPTION_PAG)             /* if pagination active,             */
1995
  {
1996
  if (nCurLine > 5)                     /* if not on 1st line,               */
1997
    PageFeed();                         /* shift to next page                */
1998
  }
1999
else
2000
  putlist("\n");
2001
 
2002
putlist("RELOCATION TABLE");
2003
for (i = 0; i < relcounter; i++)
2004
  {
2005
  char name[10];
2006
  sprintf(name, "%c%-.8s",
2007
          (reltable[i].exprcat & EXPRCAT_NEGATIVE) ? '-' : ' ',
2008
          reltable[i].sym->name);
2009
  if (j % 4 == 0)
2010
    putlist("\n");
2011
  putlist( " %9s %02d %04X",
2012
           name,
2013
           reltable[i].sym->cat,
2014
           reltable[i].addr);
2015
  j++;
2016
  }
2017
putlist("\n%d RELOCATIONS\n", j);
2018
}
2019
 
2020
/*****************************************************************************/
2021
/* outtexttable : prints the text table                                      */
2022
/*****************************************************************************/
2023
 
2024
void outtexttable()
2025
{
2026
int i,j = 0;
2027
 
2028
if (dwOptions & OPTION_PAG)             /* if pagination active,             */
2029
  {
2030
  if (nCurLine > 5)                     /* if not on 1st line,               */
2031
    PageFeed();                         /* shift to next page                */
2032
  }
2033
else
2034
  putlist("\n");
2035
 
2036
putlist("TEXT TABLE");
2037
for (i = 0; i < symcounter; i++)
2038
  if (symtable[i].cat == SYMCAT_TEXT)
2039
    {
2040
                                        /* suppress listing of predef texts  */
2041
    if (symtable[i].value < nPredefinedTexts)
2042
      continue;
2043
    putlist("\n %9s %s", symtable[i].name, texts[symtable[i].value]);
2044
    j++;
2045
    }
2046
putlist("\n%d TEXTS\n", j);
2047
}
2048
 
2049
/*****************************************************************************/
2050
/* findreg : finds a register per name                                       */
2051
/*****************************************************************************/
2052
 
2053
struct regrecord * findreg(char *nm)
2054
{
2055
int i;
2056
for (i = 0; regtable[i].name != NULL; i++)
2057
  {
2058
  if (strcmp(regtable[i].name,nm) == 0)
2059
    return regtable + i;
2060
  }
2061
return 0;
2062
}
2063
 
2064
/*****************************************************************************/
2065
/* findreg63 : finds a register per name for HD63 operations                 */
2066
/*****************************************************************************/
2067
 
2068
struct regrecord * findreg63(char *nm)
2069
{
2070
int i;
2071
for (i = 0; i < (sizeof(regtable63) / sizeof(regtable63[0])); i++)
2072
  {
2073
  if (strcmp(regtable63[i].name,nm) == 0)
2074
    return regtable63 + i;
2075
  }
2076
return 0;
2077
}
2078
 
2079
/*****************************************************************************/
2080
/* findbitreg : finds a bit transfer register per name (6309 only)           */
2081
/*****************************************************************************/
2082
 
2083
struct regrecord * findbitreg(char *nm)
2084
{
2085
int i;
2086
for (i = 0; i < (sizeof(bitregtable) / sizeof(bitregtable[0])); i++)
2087
  {
2088
  if (strcmp(bitregtable[i].name,nm) == 0)
2089
    return bitregtable + i;
2090
  }
2091
return 0;
2092
}
2093
 
2094
/*****************************************************************************/
2095
/* strupr : converts a string to uppercase (crude)                           */
2096
/*****************************************************************************/
2097
 
2098
char *strupr(char *name)
2099
{
2100
int i;
2101
if (!name)
2102
  return name;
2103
for (i = 0; name[i]; i++)
2104
  if ((name[i] >= 'a') && (name[i] <= 'z'))
2105
    name[i] -= ('a' - 'A');
2106
return name;
2107
}
2108
 
2109
/*****************************************************************************/
2110
/* addreloc : adds a relocation record to the list                           */
2111
/*****************************************************************************/
2112
 
2113
void addreloc(struct relocrecord *p)
2114
{
2115
struct relocrecord rel = {0};           /* internal copy                     */
2116
 
2117
if (p)                                  /* if there's a record,              */
2118
  rel = *p;                             /* copy to internal                  */
2119
 
2120
if ((!relocatable) ||                   /* if generating unrelocatable binary*/
2121
    (!rel.sym) ||                       /* or no symbol                      */
2122
    (pass == 1))                        /* or in pass 1                      */
2123
  return;                               /* do nothing here                   */
2124
 
2125
switch (rel.sym->cat)                   /* check symbol category             */
2126
  {
2127
  case SYMCAT_PUBLIC :                  /* public label ?                    */
2128
  case SYMCAT_LABEL :                   /* normal label ?                    */
2129
  case SYMCAT_EXTERN :                  /* external symbol ?                 */
2130
    break;                              /* these are allowed                 */
2131
  case SYMCAT_COMMONDATA :              /* Common data ?                     */
2132
    rel.sym = rel.sym->u.parent;        /* switch to COMMON block            */
2133
    break;                              /* and allow it.                     */
2134
  default :                             /* anything else                     */
2135
    return;                             /* isn't                             */
2136
  }
2137
 
2138
if (relcounter >= MAXRELOCS)            /* if no more space                  */
2139
  {                                     /* should NEVER happen... but then...*/
2140
  error |= ERR_MALLOC;                  /* set mem alloc err                 */
2141
  return;                               /* and get out of here               */
2142
  }
2143
 
2144
reltable[relcounter++] = rel;           /* add relocation record             */
2145
 
2146
switch (p->sym->cat)                    /* do specials...                    */
2147
  {
2148
  case SYMCAT_PUBLIC :                  /* public label ?                    */
2149
  case SYMCAT_LABEL :                   /* normal label ?                    */
2150
  case SYMCAT_COMMONDATA :              /* common data ?                     */
2151
    curline->rel =                      /* remember there's a relocation     */
2152
      (p->exprcat & EXPRCAT_NEGATIVE) ? '-' : '+';
2153
    break;
2154
  case SYMCAT_EXTERN :                  /* external symbol ?                 */
2155
    curline->rel =
2156
      (p->exprcat & EXPRCAT_NEGATIVE) ? 'x' : 'X';
2157
    break;
2158
  }
2159
 
2160
}
2161
 
2162
/*****************************************************************************/
2163
/* scanname : scans a name from the input buffer                             */
2164
/*****************************************************************************/
2165
 
2166
void scanname()
2167
{
2168
int i = 0;
2169
char c;
2170
char cValid;
2171
 
2172
while (1)
2173
  {
2174
  c = *srcptr++;
2175
  if ((!(dwOptions & OPTION_TSC)) &&    /* TSC Assembler is case-sensitive   */
2176
      (!(dwOptions & OPTION_GAS)) &&    /* GNU Assembler is case-sensitive   */
2177
      (c >= 'a' && c <= 'z'))
2178
    c -= 32;
2179
  cValid = 0;                           /* check for validity                */
2180
  if ((c >= '0' && c <= '9') ||         /* normally, labels may consist of   */
2181
      (c >= 'A' && c <= 'Z') ||         /* the characters A..Z,a..z,_        */
2182
      (c >= 'a' && c <= 'z') ||
2183
      (c == '_'))
2184
    cValid = 1;
2185
  if (dwOptions & OPTION_GAS)           /* for GNU AS compatibility,         */
2186
    {                                   /* the following rules apply:        */
2187
    if ((c == '.') ||                   /* .$ are valid symbol characters    */
2188
        (c == '$'))
2189
     cValid = 1;
2190
    }
2191
  if (!cValid)                          /* if invalid character encountered  */
2192
    break;                              /* stop here                         */
2193
 
2194
  if (i < maxidlen)
2195
    {
2196
    namebuf[i] = c;
2197
    unamebuf[i] = toupper(c);
2198
    i++;
2199
    }
2200
  }
2201
namebuf[i] = '\0';
2202
unamebuf[i] = '\0';
2203
srcptr--;
2204
}
2205
 
2206
/*****************************************************************************/
2207
/* skipspace : skips whitespace characters                                   */
2208
/*****************************************************************************/
2209
 
2210
void skipspace()
2211
{
2212
char c;
2213
do
2214
  {
2215
  c = *srcptr++;
2216
  } while (c == ' ' || c == '\t');
2217
srcptr--;
2218
}
2219
 
2220
long scanexpr(int, struct relocrecord *);
2221
 
2222
/*****************************************************************************/
2223
/* scandecimal : scans a decimal number                                      */
2224
/*****************************************************************************/
2225
 
2226
long scandecimal()
2227
{
2228
char c;
2229
long t = 0;
2230
c = *srcptr++;
2231
while (isdigit(c))
2232
  {
2233
  t = t * 10 + c - '0';
2234
  c = *srcptr++;
2235
  }
2236
srcptr--;
2237
return t;
2238
}
2239
 
2240
/*****************************************************************************/
2241
/* scanhex : scans hex number                                                */
2242
/*****************************************************************************/
2243
 
2244
long scanhex()
2245
{
2246
long t = 0, i = 0;
2247
 
2248
srcptr++;
2249
scanname();
2250
while (unamebuf[i] >= '0' && unamebuf[i] <= 'F')
2251
  {
2252
  t = t * 16 + unamebuf[i] - '0';
2253
  if (unamebuf[i] > '9')
2254
    t -= 7;
2255
  i++;
2256
  }
2257
if (i==0)
2258
  error |= ERR_EXPR;
2259
return t;
2260
}
2261
 
2262
/*****************************************************************************/
2263
/* scanchar : scan a character                                               */
2264
/*****************************************************************************/
2265
 
2266
long scanchar()
2267
{
2268
long  t;
2269
 
2270
srcptr++;
2271
t = *srcptr;
2272
if (t)
2273
  srcptr++;
2274
if (*srcptr == '\'')
2275
  srcptr++;
2276
return t;
2277
}
2278
 
2279
/*****************************************************************************/
2280
/* scanbin : scans a binary value                                            */
2281
/*****************************************************************************/
2282
 
2283
long scanbin()
2284
{
2285
char c;
2286
short t = 0;
2287
 
2288
srcptr++;
2289
c = *srcptr++;
2290
while (c == '0' || c == '1')
2291
  {
2292
  t = t * 2 + c - '0';
2293
  c = *srcptr++;
2294
  }
2295
srcptr--;
2296
return t;
2297
}
2298
 
2299
/*****************************************************************************/
2300
/* scanoct : scans an octal value                                            */
2301
/*****************************************************************************/
2302
 
2303
long scanoct()
2304
{
2305
char c;
2306
long t = 0;
2307
 
2308
srcptr++;
2309
c = *srcptr++;
2310
while (c >= '0' && c <= '7')
2311
  {
2312
  t = t * 8 + c - '0';
2313
  c = *srcptr++;
2314
  }
2315
srcptr--;
2316
return t;
2317
}
2318
 
2319
/*****************************************************************************/
2320
/* scanstring : scans a string into a buffer                                 */
2321
/*****************************************************************************/
2322
 
2323
char * scanstring(char *dest, int nlen)
2324
{
2325
char *s = srcptr;
2326
char *d = dest;
2327
int nInString = 0;
2328
char c;
2329
 
2330
if (*srcptr == '\'' || *srcptr == '\"')
2331
  {
2332
  nInString = 1;
2333
  srcptr++;
2334
  }
2335
 
2336
while (*srcptr)
2337
  {
2338
  if (!nInString &&
2339
      (*srcptr == ' ' || *srcptr == ','))
2340
    break;
2341
  else if (nInString && *s == *srcptr)
2342
    {
2343
    srcptr++;
2344
    break;
2345
    }
2346
  c = *srcptr++;
2347
  if (!nInString && c >= 'a' && c <= 'z')
2348
    c -= 32;
2349
  *d++ = c;
2350
  }
2351
*d = '\0';
2352
 
2353
return dest;
2354
}
2355
 
2356
 
2357
/*****************************************************************************/
2358
/* scanlabel : scans a label                                                 */
2359
/*****************************************************************************/
2360
 
2361
unsigned scanlabel(struct relocrecord *pp)
2362
{
2363
struct symrecord * p;
2364
 
2365
scanname();
2366
p = findsym(namebuf, 1);
2367
if (p->cat == SYMCAT_EMPTY)
2368
  {
2369
  p->cat = SYMCAT_UNRESOLVED;
2370
  p->value = 0;
2371
  p->u.flags |= SYMFLAG_FORWARD;
2372
  }
2373
 
2374
if (p->cat == SYMCAT_MACRO ||
2375
    p->cat == SYMCAT_PARMNAME ||
2376
    p->cat == SYMCAT_TEXT)
2377
  error |= ERR_EXPR;
2378
exprcat = p->cat & (EXPRCAT_PUBLIC | EXPRCAT_EXTADDR | EXPRCAT_INTADDR);
2379
if (exprcat == (EXPRCAT_EXTADDR | EXPRCAT_INTADDR) ||
2380
    exprcat == (EXPRCAT_PUBLIC | EXPRCAT_INTADDR))
2381
  unknown = 1;
2382
 
2383
#if 1
2384
/* anything that's not yet defined is uncertain in pass 2! */
2385
if ((p->u.flags & (SYMFLAG_FORWARD | SYMFLAG_PASSED)) == SYMFLAG_FORWARD)
2386
  certain = 0;
2387
#else
2388
if (((exprcat == EXPRCAT_INTADDR ||
2389
      exprcat == EXPRCAT_PUBLIC) &&
2390
//    (unsigned short)(p->value) > (unsigned short)loccounter) ||
2391
//    (p->u.flags & SYMFLAG_FORWARD)) ||
2392
    ((p->u.flags & (SYMFLAG_FORWARD | SYMFLAG_PASSED)) == SYMFLAG_FORWARD)) ||
2393
    exprcat == EXPRCAT_EXTADDR)
2394
  certain = 0;
2395
#endif
2396
if ((!absmode) &&                       /* if in relocating mode             */
2397
    (exprcat))                          /* and this is not a constant        */
2398
  certain = 0;                          /* this is NOT certain               */
2399
if (exprcat == EXPRCAT_PUBLIC ||
2400
    exprcat == (EXPRCAT_EXTADDR | EXPRCAT_INTADDR) ||
2401
    exprcat == (EXPRCAT_PUBLIC | EXPRCAT_INTADDR))
2402
  exprcat = EXPRCAT_INTADDR;
2403
if (pp)
2404
  {
2405
  pp->exprcat = exprcat;
2406
  pp->sym = p;
2407
  }
2408
  if (p->isFar)
2409
          isFar = 1;
2410
  if (p->isFarkw)
2411
          isFarkw = 1;
2412
return p->value;
2413
}
2414
 
2415
/*****************************************************************************/
2416
/* isfactorstart : returns whether passed character possibly starts a factor */
2417
/*****************************************************************************/
2418
 
2419
int isfactorstart(char c)
2420
{
2421
if (isalpha(c))
2422
  return 1;
2423
else if (isdigit(c))
2424
  return 1;
2425
else switch (c)
2426
  {
2427
  case '*' :
2428
  case '$' :
2429
  case '%' :
2430
  case '@' :
2431
  case '\'' :
2432
  case '(' :
2433
  case '-' :
2434
  case '+' :
2435
  case '!' :
2436
  case '~' :
2437
    return 1;
2438
  }
2439
return 0;
2440
}
2441
 
2442
/*****************************************************************************/
2443
/* scanfactor : scans an expression factor                                   */
2444
/*****************************************************************************/
2445
 
2446
long scanfactor(struct relocrecord *p)
2447
{
2448
char c;
2449
long t;
2450
 
2451
if (!(dwOptions & OPTION_TSC))
2452
  skipspace();
2453
c = *srcptr;
2454
if (isalpha(c))
2455
  return (unsigned)scanlabel(p);
2456
else if (isdigit(c))
2457
  {
2458
  char *locptr = srcptr;                /* watch out for local labels        */
2459
  char caft;
2460
  while ((*locptr >= '0') &&            /* advance to next nonnumeric        */
2461
         (*locptr <= '9'))
2462
    locptr++;
2463
  caft = toupper(*locptr);              /* get next character in uppercase   */
2464
  if ((caft == 'B') || (caft == 'F'))   /* if this might be a local reference*/
2465
    return scanlabel(p);         /* look it up.                       */
2466
  switch (c)
2467
    {
2468
    case '0' :                          /* GNU AS bin/oct/hex?               */
2469
      if (dwOptions & OPTION_GAS)       /* if GNU AS extensions,             */
2470
        {
2471
        if (srcptr[1] == 'b')           /* if binary value,                  */
2472
          {
2473
          srcptr++;                     /* advance behind 0                  */
2474
          return scanbin();             /* and treat rest as binary value    */
2475
          }
2476
        else if (srcptr[1] == 'x')      /* if hex value,                     */
2477
          {
2478
          srcptr++;                     /* advance behind 0                  */
2479
          return scanhex();             /* and treat rest as hex value       */
2480
          }
2481
        return scanoct();               /* otherwise treat as octal          */
2482
        }
2483
      /* else fall thru on purpose */
2484
    default :                           /* decimal in any case ?             */
2485
      return scandecimal();
2486
    }
2487
  }
2488
else switch (c)
2489
  {
2490
  case '*' :
2491
    srcptr++;
2492
    exprcat |= EXPRCAT_INTADDR;
2493
    return loccounter;
2494
  case '$' :
2495
    return scanhex();
2496
  case '%' :
2497
    return scanbin();
2498
  case '@' :
2499
    return scanoct();
2500
  case '\'' :
2501
    return scanchar();
2502
  case '(' :
2503
    srcptr++;
2504
    t = scanexpr(0, p);
2505
    if (!(dwOptions & OPTION_TSC))
2506
      skipspace();
2507
    if (*srcptr == ')')
2508
      srcptr++;
2509
    else
2510
      error |= ERR_EXPR;
2511
    return t;
2512
  case '-' :
2513
    srcptr++;
2514
    t = scanfactor(p);
2515
    exprcat ^= EXPRCAT_NEGATIVE;
2516
    if (p)
2517
      p->exprcat ^= EXPRCAT_NEGATIVE;
2518
    return -t;
2519
  case '+' :
2520
    srcptr++;
2521
    return scanfactor(p);
2522
  case '!' :
2523
    srcptr++;
2524
    exprcat |= EXPRCAT_FIXED;
2525
    return !scanfactor(p);
2526
  case '~' :
2527
    srcptr++;
2528
    exprcat |= EXPRCAT_FIXED;
2529
    return ~scanfactor(p);
2530
  }
2531
error |= ERR_EXPR;
2532
return 0;
2533
}
2534
 
2535
/*****************************************************************************/
2536
/* some nice macros                                                          */
2537
/*****************************************************************************/
2538
 
2539
/*define EXITEVAL { srcptr--; return t; } */
2540
#define EXITEVAL { srcptr--; parsing = 0; break; }
2541
 
2542
#define RESOLVECAT if((oldcat & 15) == 0) oldcat = 0;               \
2543
           if ((exprcat & 15) == 0)exprcat = 0;                     \
2544
           if ((exprcat == EXPRCAT_INTADDR &&                       \
2545
                oldcat == (EXPRCAT_INTADDR | EXPRCAT_NEGATIVE)) ||  \
2546
               (exprcat == (EXPRCAT_INTADDR | EXPRCAT_NEGATIVE)&&   \
2547
               oldcat == EXPRCAT_INTADDR))                          \
2548
             {                                                      \
2549
             exprcat = 0;                                           \
2550
             oldcat = 0;                                            \
2551
             }                                                      \
2552
           exprcat |= oldcat;
2553
/* resolve such cases as constant added to address or difference between
2554
   two addresses in same module */
2555
 
2556
/*****************************************************************************/
2557
/* scanexpr : scan expression                                                */
2558
/*****************************************************************************/
2559
 
2560
long scanexpr(int level, struct relocrecord *pp) /* This is what you call _recursive_ descent!!!*/
2561
{
2562
long t, u;
2563
char oldcat,c,parsing=1;
2564
struct relocrecord ip = {0}, p = {0};
2565
 
2566
exprcat = 0;
2567
if (level == 10)
2568
  return scanfactor(pp);
2569
t = scanexpr(level + 1, &ip);
2570
/* ip.exprcat = exprcat; */
2571
while (parsing)
2572
  {
2573
  p.sym = NULL;
2574
  if (!(dwOptions & OPTION_TSC))
2575
    skipspace();
2576
  c = *srcptr++;
2577
  switch(c)
2578
    {
2579
    case '*':
2580
      oldcat = exprcat;
2581
      t *= scanexpr(10, &p);
2582
      exprcat |= oldcat | EXPRCAT_FIXED;
2583
      break;
2584
    case '/':
2585
      oldcat = exprcat;
2586
      u = scanexpr(10, &p);
2587
      if (u)
2588
        t /= u;
2589
      else
2590
        error |= ERR_EXPR;
2591
      exprcat |= oldcat | EXPRCAT_FIXED;
2592
      break;
2593
    case '%':
2594
      oldcat = exprcat;
2595
      u = scanexpr(10, &p);
2596
      if (u)
2597
        t %= u;
2598
      else
2599
        error |= ERR_EXPR;
2600
      exprcat |= oldcat | EXPRCAT_FIXED;
2601
      break;
2602
    case '+':
2603
      if (level == 9)
2604
        EXITEVAL
2605
      oldcat = exprcat;
2606
      t += scanexpr(9, &p);
2607
      RESOLVECAT
2608
      break;
2609
    case '-':
2610
      if (level == 9)
2611
        EXITEVAL
2612
      oldcat = exprcat;
2613
      t -= scanexpr(9, &p);
2614
      exprcat ^= EXPRCAT_NEGATIVE;
2615
      RESOLVECAT
2616
      break;
2617
    case '<':
2618
      if (*(srcptr) == '<')
2619
        {
2620
        if (level >= 8)
2621
          EXITEVAL
2622
        srcptr++;
2623
        oldcat = exprcat;
2624
        t <<= scanexpr(8, &p);
2625
        exprcat |= oldcat | EXPRCAT_FIXED;
2626
        }
2627
      else if (*(srcptr) == '=')
2628
        {
2629
        if (level >= 7)
2630
          EXITEVAL
2631
        srcptr++;
2632
        oldcat = exprcat;
2633
        t = t <= scanexpr(7, &p);
2634
        exprcat |= oldcat | EXPRCAT_FIXED;
2635
        }
2636
      else
2637
        {
2638
        if (level >= 7)
2639
          EXITEVAL
2640
        oldcat = exprcat;
2641
        t = t < scanexpr(7, &p);
2642
        exprcat |= oldcat | EXPRCAT_FIXED;
2643
        }
2644
      break;
2645
    case '>':
2646
      if (*(srcptr) == '>')
2647
        {
2648
        if (level >= 8)
2649
          EXITEVAL
2650
        srcptr++;
2651
        oldcat = exprcat;
2652
        t >>= scanexpr(8, &p);
2653
        exprcat |= oldcat | EXPRCAT_FIXED;
2654
        }
2655
      else if (*(srcptr) == '=')
2656
        {
2657
        if (level>=7)
2658
          EXITEVAL
2659
        srcptr++;
2660
        oldcat = exprcat;
2661
        t = t >= scanexpr(7, &p);
2662
        exprcat |= oldcat | EXPRCAT_FIXED;
2663
        }
2664
      else
2665
        {
2666
        if (level >= 7)
2667
          EXITEVAL
2668
        oldcat = exprcat;
2669
        t = t > scanexpr(7, &p);
2670
        exprcat |= oldcat | EXPRCAT_FIXED;
2671
        }
2672
      break;
2673
    case '!':
2674
      if (level >= 6 || *srcptr != '=')
2675
        EXITEVAL
2676
      srcptr++;
2677
      oldcat = exprcat;
2678
      t = t != scanexpr(6, &p);
2679
      exprcat |= oldcat | EXPRCAT_FIXED;
2680
      break;
2681
    case '=':
2682
      if (level >= 6)
2683
        EXITEVAL
2684
      if (*srcptr == '=')
2685
        srcptr++;
2686
      oldcat = exprcat;
2687
      t = (t == scanexpr(6, &p));
2688
      exprcat |= oldcat | EXPRCAT_FIXED;
2689
      break;
2690
    case '&':
2691
      if (level >= 5)
2692
        EXITEVAL
2693
      oldcat = exprcat;
2694
      t &= scanexpr(5, &p);
2695
      exprcat |= oldcat | EXPRCAT_FIXED;
2696
      break;
2697
    case '^':
2698
      if (level >= 4)
2699
        EXITEVAL
2700
      oldcat = exprcat;
2701
      t ^= scanexpr(4, &p);
2702
      exprcat |= oldcat | EXPRCAT_FIXED;
2703
      break;
2704
    case '|':
2705
      if (level >= 3)
2706
        EXITEVAL
2707
      oldcat = exprcat;
2708
      t |= scanexpr(3, &p);
2709
      exprcat |= oldcat | EXPRCAT_FIXED;
2710
      break;
2711
    default:
2712
      EXITEVAL
2713
    }
2714
  p.exprcat = exprcat;
2715
  if (p.sym)
2716
    {
2717
    if (ip.sym)                         /* if 2 symbols, cancel 'em          */
2718
      {
2719
      /* a simple safeguard against cancelling local vs. external symbols
2720
         or operations between 2 external symbols.
2721
         This means that an external symbol has to be the last one in an
2722
         expression, or the others have to be paired so that they cancel
2723
         each other's effect AND their subexpression has to be parenthesized.*/
2724
      if ((ip.sym->cat == SYMCAT_EXTERN) || (p.sym->cat == SYMCAT_EXTERN))
2725
        error |= ERR_EXPR;
2726
      else
2727
        ip.sym = NULL;                  /* this might be TOO crude...        */
2728
      }
2729
    else                                /* if new symbol                     */
2730
      ip = p;                           /* use this one                      */
2731
    }
2732
  }
2733
 
2734
*pp = ip;
2735
return t;
2736
}
2737
 
2738
/*****************************************************************************/
2739
/* scanindexreg : scans an index register                                    */
2740
/*****************************************************************************/
2741
 
2742
int scanindexreg()
2743
{
2744
switch (toupper(*srcptr))
2745
  {
2746
  case 'X':
2747
    return 1;
2748
  case 'Y':
2749
    postbyte |= 0x200;
2750
    return 1;
2751
  case 'U':
2752
    postbyte |= 0x400;
2753
    return 1;
2754
  case 'S':
2755
    postbyte |= 0x600;
2756
    return 1;
2757
  }
2758
return 0;
2759
}
2760
 
2761
/*****************************************************************************/
2762
/* set3 : sets mode to at least ADRMODE_POST                                 */
2763
/*****************************************************************************/
2764
 
2765
void set3()
2766
{
2767
if (mode < ADRMODE_POST)
2768
  mode = ADRMODE_POST;
2769
}
2770
 
2771
/*****************************************************************************/
2772
/* scanspecial : scans for increments                                        */
2773
/*****************************************************************************/
2774
 
2775
void scanspecial()
2776
{
2777
set3();
2778
if (!(dwOptions & OPTION_TSC))
2779
  skipspace();
2780
if (*srcptr == '-')
2781
  {
2782
  srcptr++;
2783
  if (*srcptr == '-')
2784
    {
2785
    srcptr++;
2786
    postbyte = 0x803;
2787
    }
2788
  else
2789
    postbyte = 0x802;
2790
 
2791
  if ((dwOptions & OPTION_H63) &&       /* special for ,--W and [,--W]       */
2792
      (postbyte == 0x803) &&
2793
      (toupper(*srcptr) == 'W'))
2794
    {
2795
    postbyte = (mode == ADRMODE_IND) ? 0x900 : 0x80f;
2796
    srcptr++;
2797
    }
2798
  else if (!scanindexreg())
2799
    error |= ERR_ILLEGAL_ADDR;
2800
  else
2801
    srcptr++;
2802
  }
2803
else
2804
  {
2805
  postbyte = 0x800;
2806
  if ((dwOptions & OPTION_H63) &&       /* special for ,W, [,W], ,W++, [,W++]*/
2807
      (toupper(*srcptr) == 'W'))
2808
    {
2809
    srcptr++;                           /* advance behind W                  */
2810
    if (*srcptr == '+')
2811
      {
2812
      srcptr++;
2813
      if (*srcptr == '+')               /* ,W++ and [,W++]                   */
2814
        {
2815
        postbyte = (mode == ADRMODE_IND) ? 0xB00 : 0xA0F;
2816
        srcptr++;
2817