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
        }
2818
      else
2819
        error |= ERR_ILLEGAL_ADDR;
2820
      }
2821
    else                                /* ,W and [,W]                       */
2822
      postbyte = (mode == ADRMODE_IND) ? 0x900 : 0x80F;
2823
    }
2824
  else                                  /* normal index register addressing  */
2825
    {
2826
    if (!scanindexreg())
2827
      error |= ERR_ILLEGAL_ADDR;
2828
    else
2829
      srcptr++;
2830
    if (*srcptr == '+')
2831
      {
2832
      srcptr++;
2833
      if (*srcptr == '+')
2834
        {
2835
        srcptr++;
2836
        postbyte += 1;
2837
        }
2838
      }
2839
    else
2840
      postbyte += 4;
2841
    }
2842
  }
2843
}
2844
 
2845
/*****************************************************************************/
2846
/* scanindexed :                                                             */
2847
/*****************************************************************************/
2848
 
2849
void scanindexed()
2850
{
2851
set3();
2852
postbyte = 0;
2853
if ((dwOptions & OPTION_H63) &&         /* special for W as index register   */
2854
    (toupper(*srcptr) == 'W'))
2855
  {
2856
  srcptr++;
2857
  postbyte = (mode == ADRMODE_IND) ? 0xb00 : 0xa0f;
2858
  opsize = 3;
2859
  }
2860
else if (scanindexreg())
2861
  {
2862
  srcptr++;
2863
  if (opsize == 0)
2864
    {
2865
    if (unknown || !certain)
2866
      opsize = 3;
2867
    else if (operand >= -256 && operand < 256 && mode == ADRMODE_POST)
2868
      opsize = 1;
2869
    else if (operand >= -2048 && operand < 2048)
2870
      opsize = 2;
2871
    else if (operand >=-8388608 && operand < 8388608)
2872
                opsize = 3;
2873
        else
2874
      opsize = 4;
2875
    }
2876
  switch (opsize)
2877
    {
2878
    case 1:
2879 12 robfinch
      postbyte |= (operand & 511);
2880 4 robfinch
      opsize = 0;
2881
      break;
2882
    case 2:
2883 12 robfinch
      postbyte |= 0x808;
2884 4 robfinch
      break;
2885
    case 3:
2886 12 robfinch
      postbyte |= 0x809;
2887 4 robfinch
      break;
2888
        case 4:
2889 12 robfinch
          postbyte |= 0x80A;
2890 4 robfinch
          break;
2891
    }
2892
  }
2893
else
2894
  { /*pc relative*/
2895
  if (toupper(*srcptr) != 'P')
2896
    error |= ERR_ILLEGAL_ADDR;
2897
  else
2898
    {
2899
    srcptr++;
2900
    if (toupper(*srcptr) != 'C')
2901
      error |= ERR_ILLEGAL_ADDR;
2902
    else
2903
      {
2904
      srcptr++;
2905
      if (toupper(*srcptr) == 'R')
2906
        srcptr++;
2907
      }
2908
    }
2909
  mode++;
2910 12 robfinch
  postbyte |= 0x80c;
2911 4 robfinch
  if (opsize == 1)
2912
    opsize = 2;
2913
  }
2914
}
2915
 
2916
/*****************************************************************************/
2917
/* scanoperands :                                                            */
2918
/*****************************************************************************/
2919
 
2920
#define RESTORE { srcptr = oldsrcptr; c = *srcptr; goto dodefault; }
2921
 
2922
void scanoperands09(struct relocrecord *pp)
2923
{
2924
char c, *oldsrcptr, *ptr;
2925
unsigned short accpost, h63 = 0;
2926
unsigned short isIndexed = 0;
2927 12 robfinch
unsigned short indirect_byte = 0;
2928 4 robfinch
isFar = 0;
2929
isPostIndexed = 0;
2930
unknown = 0;
2931
opsize = 0;
2932
certain = 1;
2933
scano1:
2934
skipspace();
2935
c = *srcptr;
2936
mode = ADRMODE_IMM;
2937
if (c == '[')
2938
  {
2939
  c = *++srcptr;
2940
  if (c=='[') {
2941
          c = *++srcptr;
2942
          mode = ADRMODE_DBL_IND;
2943
          postbyte = 0x80F;
2944
  }
2945
  else
2946
          mode = ADRMODE_IND;
2947 12 robfinch
    indirect_byte = 0x100;
2948 4 robfinch
  }
2949
switch (toupper(c))
2950
  {
2951
  case 'D':
2952
    accpost = 0x80b;
2953
  accoffset:
2954
    oldsrcptr = srcptr;
2955
    srcptr++;
2956
    if (!(dwOptions & OPTION_TSC))
2957
      skipspace();
2958
    if (*srcptr != ',')
2959
      RESTORE
2960
    else
2961
      {
2962
                  isIndexed = 1;
2963
      if ((h63) && (!(dwOptions & OPTION_H63)))
2964
        error |= ERR_ILLEGAL_ADDR;
2965 12 robfinch
      postbyte |= accpost;
2966 4 robfinch
      srcptr++;
2967
      if (!scanindexreg())
2968
        RESTORE
2969
      else
2970
        {
2971
        srcptr++;
2972
        set3();
2973
        }
2974
      }
2975
    break;
2976
  case 'A':
2977
    accpost = 0x806;
2978
    goto accoffset;
2979
  case 'B':
2980
    accpost = 0x805;
2981
    goto accoffset;
2982
  case 'E':
2983
    accpost = 0x807;
2984
    h63 = 1;
2985
    goto accoffset;
2986
  case 'F':
2987
          if (toupper(srcptr[1])=='A' && toupper(srcptr[2])=='R' && (srcptr[3]==' '||srcptr[3]=='\t')) {
2988
                  isFar = 1;
2989
                  isFarkw = 1;
2990
                  srcptr += 3;
2991
                  goto scano1;
2992
          }
2993
    accpost = 0x80a;
2994
    h63 = 1;
2995
    goto accoffset;
2996
  case 'W' :
2997
    accpost = 0x80e;
2998
    h63 = 1;
2999
    goto accoffset;
3000
  case ',':
3001
    srcptr++;
3002
    scanspecial();
3003
    break;
3004
  case '#':
3005
    if (mode == ADRMODE_IND)
3006
      error |= ERR_ILLEGAL_ADDR;
3007
    else
3008
      mode = ADRMODE_IMM;
3009
    srcptr++;
3010
        if (*srcptr=='>') {
3011
                srcptr++;
3012
            operand = (scanexpr(0, pp) >> 24LL) & 0xffffffLL;
3013
                isFar = 0;
3014
                opsize = 3;
3015
        }
3016
        else if (*srcptr=='<') {
3017
                srcptr++;
3018
            operand = scanexpr(0, pp) & 0xffffffLL;
3019
                isFar = 0;
3020
                opsize = 3;
3021
        }
3022
        else
3023
                operand = scanexpr(0, pp);
3024
    break;
3025
  case '<':
3026
    srcptr++;
3027
    if (*srcptr == '<')
3028
      {
3029
      srcptr++;
3030
      opsize = 1;
3031
      }
3032
    else
3033
      opsize = 2;
3034
    goto dodefault;
3035
  case '>':
3036
    srcptr++;
3037
    opsize = 3;
3038
    /* fall thru on purpose */
3039
  default:
3040
  dodefault:
3041
    operand = scanexpr(0, pp);
3042
    if (!(dwOptions & OPTION_TSC))
3043
      skipspace();
3044
    if (*srcptr == ',')
3045
      {
3046
                  isIndexed = 1;
3047
      srcptr++;
3048
      if (!(dwOptions & OPTION_TSC))
3049
        skipspace();
3050
      if ((operand == 0) &&             /* special for "0,-[-]indexreg       */
3051
          (!unknown) && (certain) &&    /*         and "0,indexreg[+[+]]     */
3052
          (opsize < 3) &&               /* but NOT for ">0,indexreg"!        */
3053
          ((*srcptr == '-') ||
3054
           (scanindexreg() /* && (srcptr[1] == '+') */ )))
3055
        scanspecial();
3056
      else
3057
        scanindexed();
3058
      }
3059
    else
3060
      {
3061
      if (opsize == 0)
3062
        {
3063
        if ((unsigned)operand >= 16777216)
3064
                      opsize = 4;
3065
              else
3066
        if (unknown || !certain || dpsetting == -1 ||
3067 12 robfinch
          (signed)(operand - dpsetting * 4096) >= 2048 ||
3068
          (signed)(operand - dpsetting * 4096) < -2048)
3069 4 robfinch
          opsize = 3;
3070
        else
3071
          opsize = 2;
3072
        }
3073
      /*
3074
      if (opsize == 4) {
3075
        if ((operand & 0xff800000) == 0xff800000)
3076
          opsize = 3;
3077
        else if ((operand & 0xff800000) == 0x0)
3078
          opsize = 3;
3079
      }
3080
      */
3081
      if (opsize == 1)
3082
        opsize = 2;
3083
      if (mode == ADRMODE_IND)
3084
        {
3085
        postbyte = 0x80f;
3086
                // Why is the following set ?
3087
//        opsize = 3;
3088
        }
3089
          else if (mode == ADRMODE_DBL_IND)
3090
                  ;
3091
          else {
3092
                  switch(opsize) {
3093
                case 2: mode = ADRMODE_DIR; break;
3094
                case 3: mode = ADRMODE_EXT; break;
3095
//              case 4:
3096
                case 4: mode = ADRMODE_EXT; isFar = 1; break;
3097
                default: mode = opsize - 1;
3098
                  }
3099
          }
3100
      }
3101
  }
3102
 
3103
if (mode >= ADRMODE_IND)
3104
  {
3105
  if (!(dwOptions & OPTION_TSC))
3106
    skipspace();
3107
  if (mode != ADRMODE_DBL_IND)
3108
        postbyte |= 0x100;
3109
  if (*srcptr != ']')
3110
    error |= ERR_ILLEGAL_ADDR;
3111
  srcptr++;
3112
  if (mode==ADRMODE_DBL_IND) {
3113
          if (*srcptr != ']')
3114
                error |= ERR_ILLEGAL_ADDR;
3115
          srcptr++;
3116
  }
3117
  }
3118
  skipspace();
3119
  if (*srcptr==',') {
3120
          srcptr++;
3121
          isPostIndexed = 1;
3122 12 robfinch
    scanindexed();      // scanindexed will reset the postbyte
3123
          postbyte |= indirect_byte | 0x80;
3124 4 robfinch
  }
3125
  else {
3126
          if (postbyte==0x90F || postbyte==0x80F)
3127
                  opsize = 3;
3128
      if (mode == ADRMODE_IND || mode==ADRMODE_DBL_IND)
3129
        {
3130
/*
3131
                        if ((postbyte & 0xF)==4)        // 0 offset
3132
                                opsize = 0;
3133
                //      else if ((postbyte & 0xf)==8 || (postbyte & 0xF)==
3134
                        else
3135
                                opsize = 3;
3136
*/
3137
        }
3138
  }
3139
if (pass > 1 && unknown)
3140
  error |= ERR_LABEL_UNDEF;
3141
}
3142
 
3143
void scanoperands00(struct relocrecord *pp)
3144
{
3145
char c, *s = srcptr;
3146
 
3147
unknown = 0;
3148
opsize = 0;
3149
certain = 1;
3150
operand = 0;
3151
skipspace();
3152
c = *srcptr;
3153
mode = ADRMODE_IMM;
3154
switch (toupper(c))
3155
  {
3156
  case 'X' :                            /* "X"?                              */
3157
    scanname();
3158
    if (!strcmp(unamebuf, "X"))         /* if it's "X" alone,                */
3159
      goto XWithout;                    /* assume it means "0,X"             */
3160
    srcptr = s;                         /* else restore current offset       */
3161
    goto dodefault;                     /* and treat as label starting with X*/
3162
  case ',':                             /* ","?                              */
3163
  Indexed :
3164
    srcptr++;                           /* must be followed by "X"           */
3165
    if (!(dwOptions & OPTION_TSC))
3166
      skipspace();
3167
    scanname();
3168
    if (strcmp(unamebuf, "X"))          /* if it's NOT "X" alone,            */
3169
      {
3170
      error |= ERR_ILLEGAL_ADDR;
3171
      break;
3172
      }
3173
  XWithout :
3174
    if ((unsigned)operand < 256)
3175
      mode = ADRMODE_IDX;
3176
    else
3177
      error |= ERR_ILLEGAL_ADDR;
3178
    break;
3179
  case '#':
3180
    srcptr++;
3181
    operand = scanexpr(0, pp);
3182
    break;
3183
  case '<':
3184
    srcptr++;
3185
    if (*srcptr == '<')
3186
      {
3187
      srcptr++;
3188
      opsize = 1;
3189
      }
3190
    else
3191
      opsize = 2;
3192
    goto dodefault;
3193
  case '>':
3194
    srcptr++;
3195
    opsize = 3;
3196
    /* fall thru on purpose */
3197
  default:
3198
  dodefault:
3199
    operand = scanexpr(0, pp);
3200
    if (!(dwOptions & OPTION_TSC))
3201
      skipspace();
3202
    if (*srcptr == ',')
3203
      goto Indexed;
3204
    else
3205
      {
3206
      if (opsize == 0)
3207
        {
3208
        if (unknown || !certain ||
3209
          (unsigned short)(operand) >= 256)
3210
          opsize = 3;
3211
        else
3212
          opsize = 2;
3213
        }
3214
      if (opsize == 1)
3215
        opsize = 2;
3216
      mode = opsize - 1;
3217
      }
3218
  }
3219
 
3220
if (pass > 1 && unknown)
3221
  error |= ERR_LABEL_UNDEF;
3222
}
3223
 
3224
/*****************************************************************************/
3225
/* writerelhdr : writes a FLEX Relocatable Format header                     */
3226
/*****************************************************************************/
3227
 
3228
void writerelhdr(char wcommon)
3229
{
3230
int i;
3231
 
3232
#if 0
3233
struct                                  /* Header Layout                     */
3234
  {
3235
  unsigned char Signature;              /* Signature (always $03)            */
3236
  unsigned char flags1;                 /* Flags 1                           */
3237
  unsigned datasize;              /* size of binary data               */
3238
  unsigned char unknown1[4];            /* unknown data                      */
3239
  unsigned short extsize;               /* size of External table            */
3240
  unsigned startaddr;             /* program start address             */
3241
  unsigned char unknown2[2];            /* unknown data                      */
3242
  unsigned short globalsize;            /* size of global table              */
3243
  unsigned char unknown3[2];            /* unknown data                      */
3244
  unsigned short namesize;              /* length of module name             */
3245
  unsigned char flags2;                 /* Flags 2                           */
3246
  unsigned char unknown4[3];            /* unknown data; filler?             */
3247
  } hdr;
3248
memset(&hdr, 0, sizeof(hdr));
3249
#endif
3250
 
3251
fputc(0x04, objfile);                   /* write signature                   */
3252
 
3253
if (wcommon)                            /* if writing common data,           */
3254
  fputc(0x18, objfile);                 /* Flags1 = $18                      */
3255
else if (!absmode)                      /* if writing Relative data,         */
3256
  fputc(0x10, objfile);                 /* Flags1 = $10                      */
3257
else                                    /* if writing Absolute data,         */
3258
  fputc(0x12, objfile);                 /* Flags1 = $12                      */
3259
 
3260
if (wcommon)                            /* if writing common data            */
3261
  {                                     /* write size of data                */
3262
//  fputc((unsigned char)((commonsym->value >> 24) & 0xff), objfile);
3263
  fputc((unsigned char)((commonsym->value >> 16) & 0xff), objfile);
3264
  fputc((unsigned char)((commonsym->value >> 8) & 0xff), objfile);
3265
  fputc((unsigned char)(commonsym->value & 0xFF), objfile);
3266
  }
3267
else                                    /* otherwise                         */
3268
  {                                     /* write size of binary data         */
3269
//  fputc((unsigned char)((loccounter >> 24) & 0xff), objfile);
3270
  fputc((unsigned char)((loccounter >> 16) & 0xff), objfile);
3271
  fputc((unsigned char)((loccounter >> 8) & 0xff), objfile);
3272
  fputc((unsigned char)(loccounter & 0xFF), objfile);
3273
  }
3274
 
3275
//fputc(0, objfile);                      /* unknown data                      */
3276
fputc(0, objfile);
3277
fputc(0, objfile);
3278
fputc(0, objfile);
3279
 
3280
if (wcommon)                            /* if writing common data            */
3281
  {                                     /* external table is empty           */
3282
  fputc(0, objfile);
3283
  fputc(0, objfile);
3284
  }
3285
else
3286
  {
3287
  int extrel = 0;                       /* # external relocation records     */
3288
 
3289
  for (i = 0; i < relcounter; i++)      /* calc # external symbols           */
3290
    if ((reltable[i].sym->cat == SYMCAT_EXTERN) ||
3291
        (reltable[i].sym->cat == SYMCAT_COMMON))
3292
      extrel++;
3293
                                        /* then calculate table size         */
3294
  extrel = (extrel * 8) + (relcounter * 3);
3295
                                        /* and write it out                  */
3296
  fputc((unsigned char)(extrel >> 8), objfile);
3297
  fputc((unsigned char)(extrel & 0xFF), objfile);
3298
  }
3299
 
3300
if (wcommon ||                          /* if writing common data            */
3301
    (!tfradrset))                       /* or no transfer address given      */
3302
  {                                     /* start address is empty            */
3303
//  fputc(0, objfile);
3304
  fputc(0, objfile);
3305
  fputc(0, objfile);
3306
  fputc(0, objfile);
3307
  }
3308
else                                    /* write transfer address            */
3309
  {
3310
//  fputc((unsigned char)((tfradr >> 24) & 0xff), objfile);
3311
  fputc((unsigned char)((tfradr >> 16) & 0xff), objfile);
3312
  fputc((unsigned char)((tfradr >> 8) & 0xff), objfile);
3313
  fputc((unsigned char)(tfradr & 0xFF), objfile);
3314
  }
3315
 
3316
fputc(0, objfile);                      /* unknown data                      */
3317
fputc(0, objfile);
3318
 
3319
if (wcommon)
3320
  {                                     /* always 1 Global - the LABEL       */
3321
  fputc(0, objfile);
3322
  fputc(12, objfile);
3323
  }
3324
else                                    /* calculate & write out global size */
3325
  {
3326
  int globals = 0;
3327
  for (i = 0; i < symcounter; i++)
3328
    if (symtable[i].cat == SYMCAT_PUBLIC)
3329
      globals++;
3330
  globals *= 12;
3331
  fputc((unsigned char)(globals >> 8), objfile);
3332
  fputc((unsigned char)(globals & 0xFF), objfile);
3333
  }
3334
 
3335
fputc(0, objfile);                      /* unknown data                      */
3336
fputc(0, objfile);
3337
 
3338
if (wcommon)
3339
  {                                     /* no name size yet ...              */
3340
  size_t len;
3341
  char name[9] = "";
3342
  sprintf(name, "%-.8s", commonsym->name);
3343
  strupr(name);
3344
  len = strlen(name);
3345
  if (len)                              /* if there,                         */
3346
    len++;                              /* append a $04                      */
3347
  fputc((unsigned char)(len >> 8), objfile);
3348
  fputc((unsigned char)(len & 0xFF), objfile);
3349
  }
3350
else                                    /* write out module name size        */
3351
  {
3352
  size_t len = strlen(modulename);
3353
  if (len)                              /* if there,                         */
3354
    len++;                              /* append a $04                      */
3355
  fputc((unsigned char)(len >> 8), objfile);
3356
  fputc((unsigned char)(len & 0xFF), objfile);
3357
  }
3358
 
3359
if ((!wcommon) && (tfradrset))          /* if transfer address set           */
3360
  fputc(0x80, objfile);                 /* write $80 flag                    */
3361
else
3362
  fputc(0, objfile);
3363
 
3364
fputc(0, objfile);                      /* unknown data                      */
3365
fputc(0, objfile);
3366
fputc(0, objfile);
3367
}
3368
 
3369
/*****************************************************************************/
3370
/* writerelcommon : writes out all common blocks                             */
3371
/*****************************************************************************/
3372
 
3373
void writerelcommon()
3374
{
3375
int i, j;
3376
char name[9];
3377
                                        /* work through symbol list          */
3378
for (i = 0; i < symcounter; i++)
3379
  {
3380
  if (symtable[i].cat == SYMCAT_COMMON) /* if that is a common block         */
3381
    {
3382
    commonsym = symtable + i;           /* write it out                      */
3383
    writerelhdr(1);
3384
                                        /* then write the global definition  */
3385
    sprintf(name, "%-8.8s", symtable[i].name);
3386
    strupr(name);
3387
    fwrite(name, 1, 8, objfile);
3388
        if (symtable[i].value >= 65536)
3389
                fputc(2, objfile);                  /* unknown data                      */
3390
        else
3391
                fputc(1, objfile);                  /* unknown data                      */
3392
//    fputc((unsigned char)(symtable[i].value >> 24), objfile);
3393
    fputc((unsigned char)(symtable[i].value >> 16), objfile);
3394
    fputc((unsigned char)(symtable[i].value >> 8), objfile);
3395
    fputc((unsigned char)(symtable[i].value & 0xFF), objfile);
3396
    fputc(0x13, objfile);               /* unknown flag                      */
3397
 
3398
                                        /* then write the Common name        */
3399
    sprintf(name, "%-.8s", symtable[i].name);
3400
    strupr(name);
3401
    for (j = 0; name[j]; j++)
3402
      fputc(name[j], objfile);
3403
    fputc(0x04, objfile);
3404
 
3405
    j = (int)ftell(objfile);            /* fill last sector with zeroes      */
3406
    while (j % 252)
3407
      {
3408
      fputc(0, objfile);
3409
      j++;
3410
      }
3411
    }
3412
  }
3413
}
3414
 
3415
/*****************************************************************************/
3416
/* writerelext : writes out a FLEX Relocatable External table                */
3417
/*****************************************************************************/
3418
 
3419
void writerelext()
3420
{
3421
int i;
3422
char name[9];
3423
unsigned char flags;
3424
 
3425
for (i = 0; i < relcounter; i++)        /* write out the external data       */
3426
  {
3427
//  fputc((unsigned char)(reltable[i].addr >> 24), objfile);
3428
  fputc((unsigned char)(reltable[i].addr >> 16), objfile);
3429
  fputc((unsigned char)(reltable[i].addr >> 8), objfile);
3430
  fputc((unsigned char)(reltable[i].addr & 0xFF), objfile);
3431
 
3432
  flags = 0x00;                         /* reset flags                       */
3433
  if (reltable[i].exprcat & EXPRCAT_NEGATIVE)
3434
    flags |= 0x20;                      /* eventually add subtraction flag   */
3435
  if ((reltable[i].sym->cat == SYMCAT_EXTERN) ||
3436
      (reltable[i].sym->cat == SYMCAT_COMMON))
3437
    flags |= 0x80;                      /* eventually add External flag      */
3438
  fputc(flags, objfile);                /* write the flag bytes              */
3439
  if (flags & 0x80)                     /* eventually write external symbol  */
3440
    {
3441
    sprintf(name, "%-8.8s", reltable[i].sym->name);
3442
    strupr(name);
3443
    fwrite(name, 1, 8, objfile);
3444
    }
3445
  }
3446
}
3447
 
3448
/*****************************************************************************/
3449
/* writerelglobal : writes out FLEX Relocatable Global table                 */
3450
/*****************************************************************************/
3451
 
3452
void writerelglobal()
3453
{
3454
int i;
3455
char name[9];
3456
 
3457
for (i = 0; i < symcounter; i++)        /* write out the global data         */
3458
  {
3459
  if (symtable[i].cat == SYMCAT_PUBLIC)
3460
    {
3461
    sprintf(name, "%-8.8s", symtable[i].name);
3462
    strupr(name);
3463
    fwrite(name, 1, 8, objfile);
3464
 
3465
    fputc(0, objfile);                  /* unknown data                      */
3466
 
3467
//    fputc((unsigned char)(symtable[i].value >> 24), objfile);
3468
    fputc((unsigned char)(symtable[i].value >> 16), objfile);
3469
    fputc((unsigned char)(symtable[i].value >> 8), objfile);
3470
    fputc((unsigned char)(symtable[i].value & 0xFF), objfile);
3471
 
3472
    fputc(0x02, objfile);               /* unknown flag                      */
3473
    }
3474
  }
3475
}
3476
 
3477
/*****************************************************************************/
3478
/* writerelmodname : writes out FLEX Relocatable Module Name                 */
3479
/*****************************************************************************/
3480
 
3481
void writerelmodname()
3482
{
3483
int i;
3484
 
3485
if (!modulename[0])
3486
  return;
3487
strupr(modulename);
3488
for (i = 0; modulename[i]; i++)
3489
  fputc(modulename[i], objfile);
3490
fputc(0x04, objfile);
3491
}
3492
 
3493
/*****************************************************************************/
3494
/* flushver : write verilog                                       */
3495
/*****************************************************************************/
3496
 
3497
int calcParity(unsigned wd)
3498
{
3499
        int nn;
3500
        int bit;
3501
        int par;
3502
 
3503
        par = 0;
3504
        for (nn = 0; nn < 32; nn++) {
3505
                bit = (wd >> nn) & 1;
3506
                par = par ^ bit;
3507
        }
3508
        return par;
3509
}
3510
 
3511
void flushver()
3512
{
3513
int i;
3514
int chk;
3515
 
3516
if (hexcount)
3517
 {
3518
  if (objfile)
3519
    {
3520
                 for (i = 0; i < hexcount; i++)
3521
        fprintf(objfile, "rommem[%5d] <= 12'h%03X;\r\n", (hexaddr+i) & 0x3fff, hexbuffer[i] & 0xfff);
3522
  hexaddr += hexcount;
3523
  hexcount = 0;
3524
  chksum = 0;
3525
        vercount++;
3526
        }
3527
  }
3528
}
3529
 
3530
/*****************************************************************************/
3531
/* flushhex : write Motorola s-records  */
3532
/* Flushes using 12-bit bytes */
3533
/*****************************************************************************/
3534
 
3535
void flushhex()
3536
{
3537
int i;
3538
 
3539
if (hexcount)
3540
  {
3541
  if (objfile)
3542
    {
3543
    fprintf(objfile, "S1%03X%06X", (hexcount + 3) & 0xfff, hexaddr & 0xffffff);
3544
    for (i = 0; i < hexcount; i++)
3545
      fprintf(objfile, "%03X", hexbuffer[i] & 0xfff);
3546
    chksum += (hexaddr & 0xfff) + ((hexaddr >> 12) & 0xfff) + hexcount + 3;
3547
    fprintf(objfile, "%03X\n", 0xfff - (chksum & 0xfff));
3548
    }
3549
  hexaddr += hexcount;
3550
  hexcount = 0;
3551
  chksum = 0;
3552
  }
3553
}
3554
 
3555
/*****************************************************************************/
3556
/* flushihex : write Intel hex record                                        */
3557
/*****************************************************************************/
3558
 
3559
void flushihex()
3560
{
3561
int i;
3562
unsigned char  *j;
3563
 
3564
if (hexcount)
3565
  {
3566
  if (objfile)
3567
    {
3568
    j = &hexbuffer[0];
3569
    fprintf(objfile, ":%03X%06X00", hexcount, hexaddr & 0xffffff);
3570
    chksum = hexcount + ((hexaddr >> 12) & 0xfff) + (hexaddr & 0xfff);
3571
    for (i = 0; i < hexcount; i++, j++)
3572
      {
3573
      chksum += (*j) & 0xfff;
3574
      fprintf(objfile, "%03X", (*j) & 0xfff);
3575
      }
3576
    fprintf(objfile, "%03X\n", (-(signed)chksum) & 0xfff);
3577
    }
3578
  hexaddr += hexcount;
3579
  hexcount = 0;
3580
  chksum = 0;
3581
  }
3582
}
3583
 
3584
/*****************************************************************************/
3585
/* flushflex : write FLEX binary record                                      */
3586
/*****************************************************************************/
3587
 
3588
void flushflex()
3589
{
3590
int i;
3591
unsigned short *j;
3592
 
3593
if (hexcount)
3594
  {
3595
  j = &hexbuffer[0];
3596
  if (objfile)
3597
    {
3598
    fputc(0x02, objfile);               /* start of record indicator         */
3599
    fputc((hexaddr >> 32) & 0xf,        /* load address high part            */
3600
      objfile);
3601
    fputc((hexaddr >> 24) & 0xff,        /* load address high part            */
3602
          objfile);
3603
    fputc((hexaddr >> 20) & 0xf,        /* load address high part            */
3604
      objfile);
3605
    fputc((hexaddr >> 12) & 0xff,        /* load address high part            */
3606
          objfile);
3607
    fputc((hexaddr >> 8) & 0xf, objfile);     /* load address low part             */
3608
    fputc(hexaddr & 0xff, objfile);     /* load address low part             */
3609
    fputc((hexcount >> 8) & 0xf, objfile);    /* # following data bytes            */
3610
    fputc(hexcount & 0xff, objfile);    /* # following data bytes            */
3611
    for (i = 0; i < hexcount; i++, j++) { /* then put all data bytes           */
3612
      fputc(((*j)>>8)&0xff, objfile);
3613
      fputc(*j, objfile);
3614
    }
3615
    }
3616
  hexaddr += hexcount;                  /* set new address                   */
3617
  hexcount = 0;                         /* reset counter                     */
3618
  }
3619
}
3620
 
3621
/*****************************************************************************/
3622
/* outver : add a byte to verilog output                           */
3623
/*****************************************************************************/
3624
 
3625
void outver (unsigned short x)
3626
{
3627
        if (hexcount==4)
3628
                flushver();
3629
        hexbuffer[hexcount] = x;
3630
        hexcount++;
3631
chksum += x;
3632
}
3633
 
3634
/*****************************************************************************/
3635
/* outhex : add a byte to motorola s-record output                           */
3636
/*****************************************************************************/
3637
 
3638
void outhex (unsigned short x)
3639
{
3640
if (hexcount == 16)
3641
  flushhex();
3642
hexbuffer[hexcount++] = x;
3643
chksum += x;
3644
}
3645
 
3646
/*****************************************************************************/
3647
/* outihex : add a byte to intel hex output                                  */
3648
/*****************************************************************************/
3649
 
3650
void outihex (unsigned short x)
3651
{
3652
if (hexcount == 32)
3653
  flushihex();
3654
hexbuffer[hexcount++] = x;
3655
chksum += x;
3656
}
3657
 
3658
/*****************************************************************************/
3659
/* outflex : adds a byte to FLEX output                                      */
3660
/*****************************************************************************/
3661
 
3662
void outflex(unsigned short x)
3663
{
3664
if (hexcount == 255)                    /* if buffer full                    */
3665
  flushflex();                          /* flush it                          */
3666
hexbuffer[hexcount++] = x;              /* then put byte into buffer         */
3667
}
3668
 
3669
/*****************************************************************************/
3670
/* outbyte : writes one byte to the output in the selected format            */
3671
/*****************************************************************************/
3672
 
3673
void outbyte(unsigned short uc, int off)
3674
{
3675
int nByte = (loccounter + off) / 8;
3676
unsigned short nBitMask = (unsigned short) (1 << ((loccounter + off) % 12));
3677
 
3678
//if (bUsedBytes[nByte] & nBitMask)       /* if address already used           */
3679
//  warning |= WRN_AREA;                  /* set warning code                  */
3680
//else                                    /* otherwise                         */
3681
//  bUsedBytes[nByte] |= nBitMask;        /* mark it as used                   */
3682
 
3683
switch (outmode)
3684
  {
3685
  case OUT_BIN :                        /* binary file                       */
3686
    fputc((uc >> 8) & 0xf, objfile);
3687
    fputc(uc, objfile);
3688
    break;
3689
  case OUT_REL :                        /* FLEX Relocatable                  */
3690
    fputc((uc >> 8) & 0xf, objfile);
3691
    fputc(uc, objfile);
3692
    break;
3693
  case OUT_SREC :                       /* Motorola S-records                */
3694
    outhex(uc);
3695
    break;
3696
  case OUT_IHEX :                       /* Intel Hex                         */
3697
    outihex(uc);
3698
    break;
3699
  case OUT_FLEX :                       /* FLEX                              */
3700
    outflex(uc);
3701
    break;
3702
  case OUT_VER:
3703
          outver(uc);
3704
          break;
3705
  }
3706
}
3707
 
3708
/*****************************************************************************/
3709
/* outbuffer : writes the output to a file in the selected format            */
3710
/*****************************************************************************/
3711
 
3712
void outbuffer()
3713
{
3714
int i;
3715
for (i = 0; i < codeptr; i++)
3716
  outbyte(codebuf[i], i);
3717
}
3718
 
3719
/*****************************************************************************/
3720
/* report : reports an error                                                 */
3721
/*****************************************************************************/
3722
 
3723
void report()
3724
{
3725
int i;
3726
 
3727
for (i = 0; i < 16; i++)
3728
  {
3729
  if (error & 1)
3730
    {
3731
    printf("%s(%ld) : error %d: %s in \"%s\"\n",
3732
           expandfn(curline->fn), curline->ln, i + 1,
3733
           errormsg[i], curline->txt);
3734
    if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
3735
      putlist( "*** Error %d: %s\n", i + 1, errormsg[i]);
3736
    errors++;
3737
    }
3738
  error >>= 1;
3739
  }
3740
 
3741
if ((dwOptions & OPTION_TSC))           /* suppress warning 1 in TSC mode    */
3742
  warning &= ~WRN_OPT;
3743
 
3744
if (!(dwOptions & OPTION_WAR))          /* reset warnings if not wanted      */
3745
  warning = WRN_OK;
3746
 
3747
for (i = 0; i < 16; i++)
3748
  {
3749
  if (warning & 1)
3750
    {
3751
    printf("%s(%ld) : warning %d: %s in \"%s\"\n",
3752
           expandfn(curline->fn), curline->ln, i + 1, warningmsg[i], curline->txt);
3753
    if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
3754
      putlist( "*** warning %d: %s\n", i + 1, warningmsg[i]);
3755
    warnings++;
3756
    }
3757
  warning >>= 1;
3758
  }
3759
}
3760
 
3761
/*****************************************************************************/
3762
/* outlist : lists the code bytes for an instruction                         */
3763
/*****************************************************************************/
3764
 
3765
void outlist(struct oprecord *op)
3766
{
3767
int i;
3768
 
3769
if ((curline->lvl & LINCAT_INVISIBLE) &&/* don't list invisible lines       */
3770
    !(dwOptions & OPTION_INV))
3771
  return;
3772
 
3773
if ((curline->lvl & LINCAT_MACEXP) &&   /* don't list macro expansions if   */
3774
    !(dwOptions & OPTION_EXP))          /* not explicitly requested         */
3775
  return;
3776
 
3777
if ((curline->lvl & LINCAT_LVLMASK) &&  /* if level 1..31                    */
3778
    !(dwOptions & OPTION_LLL))          /* and this is not to be listed      */
3779
  return;
3780
 
3781
if ((suppress || nSkipCount) &&         /* if this is conditionally skipped  */
3782
    !(dwOptions & OPTION_CON))          /* and this is not to be listed      */
3783
  return;
3784
if ((condline) &&                       /* if this is a condition line       */
3785
    !(dwOptions & OPTION_CON))          /* and this is not to be listed      */
3786
  return;
3787
 
3788
if (dwOptions & OPTION_NUM)             /* if number output                  */
3789
  putlist("%4d ", curline->ln);         /* print out the line number         */
3790
 
3791
if (!absmode)                           /* if in relocating assembler mode   */
3792
  putlist("%c", curline->rel);          /* output relocation information     */
3793
 
3794
if (dwOptions & OPTION_LPA)             /* if in patch mode                  */
3795
  {
3796
  if ((op) && (op->cat == OPCAT_PSEUDO))
3797
    {
3798
    switch (op->code)
3799
      {
3800
      case PSEUDO_SETDP :
3801
        if (dpsetting >= 0)
3802
          putlist("setdp %02X\n", dpsetting);
3803
        break;
3804
      case PSEUDO_ORG :
3805
        putlist("insert %08X \\        ORG $%08X\n", loccounter, loccounter);
3806
        break;
3807
      case PSEUDO_FCB :
3808
      case PSEUDO_FCC :
3809
        putlist("data %04X", oldlc);
3810
        if (codeptr > 1)
3811
          putlist("-%04X", oldlc + codeptr - 1);
3812
        putlist("\n");
3813
        break;
3814
      case PSEUDO_FCW :
3815
        putlist("word %04x", oldlc);
3816
        if (codeptr > 2)
3817
          putlist("-%04X", oldlc + codeptr - 1);
3818
        putlist("\n");
3819
        break;
3820
      case PSEUDO_FCDW :
3821
        putlist("dword %08x", oldlc);
3822
        if (codeptr > 2)
3823
          putlist("-%08X", oldlc + codeptr - 1);
3824
        putlist("\n");
3825
        break;
3826
      }
3827
    }
3828
  if (codeptr > 0)                      /* if there are code bytes           */
3829
    {
3830
    char *name = findsymat(oldlc);
3831
    if (name)
3832
      putlist("label %04X %s\n", oldlc, name);
3833
    putlist("patch ");                  /* write "patch"                     */
3834
    }
3835
  else if (*curline->txt)
3836
    putlist("      ");
3837
  else
3838
    putlist("comment %04X", oldlc);
3839
  }
3840
else if ((warning & WRN_OPT) &&         /* excessive branch, TSC style       */
3841
    (dwOptions & OPTION_TSC) &&
3842
    (dwOptions & OPTION_WAR))
3843
  putlist(">");
3844
else if (curline->lvl & LINCAT_MACDEF)  /* if in macro definition            */
3845
  putlist("#");                         /* prefix line with #                */
3846
else if (curline->lvl & LINCAT_MACEXP)  /* if in macro expansion             */
3847
  putlist("+");                         /* prefix line with +                */
3848
else if (curline->lvl & LINCAT_INVISIBLE)
3849
  putlist("-");
3850
else if (curline->txt)                  /* otherwise                         */
3851
  putlist(" ");                         /* prefix line with blank            */
3852
 
3853
if (codeptr > 0)
3854
  putlist("%08X ", oldlc);
3855
else if (*curline->txt)
3856
  putlist("     ");
3857
else
3858
  {
3859
  putlist( "\n");
3860
  return;
3861
  }
3862
 
3863
for (i = 0; i < codeptr && i < MAXLISTBYTES; i++)
3864
  {
3865
  if (dwOptions & OPTION_LPA)
3866
    putlist("%03X ", codebuf[i]&0xfff);
3867
  else
3868
    putlist("%03X", codebuf[i]&0xfff);
3869
  }
3870
for (; i <= MAXLISTBYTES; i++)
3871
  {
3872
  if (dwOptions & OPTION_LPA)
3873
    putlist("    ");
3874
  else
3875
    putlist("   ");
3876
  }
3877
 
3878
if ((dwOptions & OPTION_LPA) &&
3879
    (*curline->txt))
3880
  putlist("* ");
3881
 
3882
if (strcmp(curline->txt, srcline) &&    /* if text inserted                  */
3883
    (dwOptions & OPTION_EXP))           /* and expansion activated           */
3884
  putlist("%s", curline->txt);          /* just print out the source line    */
3885
else                                    /* otherwise                         */
3886
  putlist("%s", srcline);               /* print possibly expanded line      */
3887
 
3888
putlist("\n");                          /* send newline                      */
3889
 
3890
if (codeptr > MAXLISTBYTES &&           /* if there are additional bytes,    */
3891
    (dwOptions & OPTION_MUL))
3892
  {                                     /* print them.                       */
3893
  if (dwOptions & OPTION_LPA)           /* if in patch mode                  */
3894
    putlist("patch");                   /* write "patch"                     */
3895
  for (i = MAXLISTBYTES; i < codeptr; i++)
3896
    {
3897
    if (!(i % MAXLISTBYTES))
3898
      {
3899
      if (i != MAXLISTBYTES)
3900
        putlist("\n");
3901
      if (dwOptions & OPTION_NUM)       /* if number output                  */
3902
        putlist("     ");
3903
      if (!absmode)
3904
        putlist(" ");
3905
      putlist(" %08X ", oldlc + i);
3906
      }
3907
    if (dwOptions & OPTION_LPA)         /* if in patch mode                  */
3908
      putlist("%03X ", codebuf[i]&0xfff);
3909
    else
3910
      putlist("%03X", codebuf[i]&0xfff);
3911
    }
3912
  putlist("\n");
3913
  }
3914
 
3915
if (strcmp(curline->txt, srcline) &&    /* if text inserted                  */
3916
    (dwOptions & OPTION_EXP))           /* and expansion activated           */
3917
  {
3918
  if (dwOptions & OPTION_NUM)
3919
    putlist("%4d ", curline->ln);
3920
  if (!absmode)
3921
    putlist(" ");
3922
  putlist("+                   ( %s )\n", srcline);
3923
  }
3924
}
3925
 
3926
/*****************************************************************************/
3927
/* setlabel : sets a label                                                   */
3928
/*****************************************************************************/
3929
 
3930
void setlabel(struct symrecord * lp)
3931
{
3932
if (lp)
3933
  {
3934
          lp->isFar = isFar;
3935
          lp->isFarkw = isFarkw;
3936
  if (lp->cat == SYMCAT_PUBLICUNDEF)
3937
    {
3938
    lp->cat = SYMCAT_PUBLIC;
3939
    lp->value = loccounter;
3940
    }
3941
  else if (lp->cat == SYMCAT_EMPTYLOCAL)
3942
    {
3943
    lp->cat = SYMCAT_LOCALLABEL;
3944
    }
3945
  else if (lp->cat == SYMCAT_LOCALLABEL)
3946
    ;
3947
  else if (lp->cat != SYMCAT_EMPTY && lp->cat != SYMCAT_UNRESOLVED)
3948
    {
3949
    if ((lp->cat != SYMCAT_LABEL && lp->cat != SYMCAT_PUBLIC) ||
3950
                lp->value != loccounter) {
3951
                lp->value = loccounter;
3952
                if (pass==MAX_PASSNO)
3953
                        error |= ERR_LABEL_MULT;
3954
                }
3955
    }
3956
  else
3957
    {
3958
    lp->cat = (global) ? SYMCAT_PUBLIC : SYMCAT_LABEL;
3959
    lp->value = loccounter;
3960
    }
3961
  }
3962
}
3963
 
3964
/*****************************************************************************/
3965
/* putbyte : adds a byte to the instruction code buffer                      */
3966
/*****************************************************************************/
3967
 
3968
void putbyte(unsigned short b)
3969
{
3970
codebuf[codeptr++] = b;                 /* and finally put the byte there.   */
3971
}
3972
 
3973
/*****************************************************************************/
3974
/* putword : adds a word to the instruction code buffer                      */
3975
/*****************************************************************************/
3976
 
3977
void putword(unsigned w)
3978
{
3979
putbyte((unsigned short)((w >> 12L) & 0xfffL));
3980
putbyte((unsigned short)(w & 0xfff));
3981
}
3982
 
3983
/*****************************************************************************/
3984
/* putdword : adds a doubleword to the instruction code buffer               */
3985
/*****************************************************************************/
3986
 
3987
void putdword(unsigned __int64 d)
3988
{
3989
putbyte((unsigned short)((d >> 36LL) & 0xfffLL));
3990
putbyte((unsigned short)((d >> 24LL) & 0xfffLL));
3991
putbyte((unsigned short)((d >> 12LL) & 0xfffLL));
3992
putbyte((unsigned short)(d & 0xfffLL));
3993
}
3994
 
3995
/*****************************************************************************/
3996
/* doaddress : assemble the right addressing bytes for an instruction        */
3997
/*****************************************************************************/
3998
 
3999
void doaddress(struct relocrecord *p)
4000
{
4001
int offs;
4002
int addrelocation = 0;
4003
int isNear = 0;
4004
if (p)                                  /* create relocation record          */
4005
  p->addr = (unsigned)(loccounter + codeptr);
4006
 
4007
switch (mode)
4008
  {
4009
  case ADRMODE_IMM :
4010
    if (opsize == 2)
4011
      putbyte((unsigned short)operand);
4012
    else if (opsize == 5)               /* LDQ special                       */
4013
      putdword(operand);
4014
    else
4015
      {
4016
      putword((unsigned)operand);
4017
      addrelocation = 1;
4018
      }
4019
    break;
4020
  case ADRMODE_DIR :
4021
    putbyte((unsigned short)operand);
4022
    break;
4023
  case ADRMODE_EXT :
4024
    if (((codebuf[0] == 0x07e) ||        /* special for JMP                   */
4025
         (codebuf[0] == 0x0bd) ||
4026
                 (codebuf[0] == 0x015 && (codebuf[1]==0x07E || codebuf[1]==0x0bd))
4027
                 ) &&       /* and JSR                           */
4028
        pass > 1)
4029
      {
4030
      int nDiff = (int)operand - (int)loccounter - 3;
4031
          isNear = (operand & 0xFF0000L) == (loccounter & 0xff0000L);
4032
      if (((nDiff & 0xff80) == 0x0000) ||
4033
           ((nDiff & 0xff80) == 0xff80))
4034
           warning |= (certain) ? WRN_OPT : 0;
4035
      }
4036
          if (codebuf[0]==0x015 && codebuf[1]==0x0bd && isFar) {
4037
                  if (isNear && !isFarkw) {
4038
                          codebuf[0]=0x0bd;
4039
                          isFar = 0;
4040
                  }
4041
                  else
4042
                          codebuf[0]=0x0cf;
4043
                  codeptr--;
4044
          }
4045
          if (codebuf[0]==0x015 && codebuf[1]==0x07E && isFar) {
4046
                  if (isNear && !isFarkw) {
4047
                        codebuf[0]=0x07E;
4048
                        isFar = 0;
4049
                  }
4050
                  else
4051
                        codebuf[0]=0x08f;
4052
                  codeptr--;
4053
          }
4054
          if (isFar) {
4055
                  putbyte((unsigned short)(operand >> 24));
4056
          }
4057
    putword((unsigned)operand);
4058
    addrelocation = 1;
4059
    break;
4060
  case ADRMODE_IDX :
4061
    putbyte((unsigned short)operand);
4062
    break;
4063
  case ADRMODE_POST :
4064
  case ADRMODE_IND :
4065
  case ADRMODE_DBL_IND:
4066
    putbyte(postbyte);
4067
    switch (opsize)
4068
      {
4069
      case 2:
4070
        putbyte((unsigned short)operand);
4071
        break;
4072
      case 3:
4073
        putword((unsigned)operand);
4074
        addrelocation = 1;
4075
                break;
4076
      case 4:
4077
        putbyte((unsigned short)(operand>>24));
4078
        putword((unsigned)operand);
4079
        addrelocation = 1;
4080
                break;
4081
      case 5:
4082
        putword((unsigned short)(operand>>24));
4083
        putword((unsigned)operand);
4084
        addrelocation = 1;
4085
                break;
4086
      }
4087
    break;
4088
  case ADRMODE_PCR :
4089
  case ADRMODE_PIN :
4090
    offs = (unsigned)operand - loccounter - codeptr - 2;
4091
    if (offs < -2048 || offs >= 2048 || opsize == 3 || unknown || !certain)
4092
      {
4093
      if ((!unknown) && opsize == 2)
4094
        error |= ERR_RANGE;
4095
      offs--;
4096
      opsize = 3;
4097
      postbyte++;
4098
      }
4099
    putbyte(postbyte);
4100
    if (opsize == 3)
4101
      {
4102
      putword((unsigned)offs);
4103
      addrelocation = 1;
4104
      }
4105
    else
4106
      putbyte((unsigned short)offs);
4107
  }
4108
 
4109
if (addrelocation)
4110
  addreloc(p);
4111
}
4112
 
4113
/*****************************************************************************/
4114
/* onebyte : saves integer as one instruction byte                           */
4115
/*****************************************************************************/
4116
 
4117
void onebyte(int co)
4118
{
4119
putbyte((unsigned short)co);
4120
}
4121
 
4122
/*****************************************************************************/
4123
/* twobyte : saves integer as two instruction bytes                          */
4124
/*****************************************************************************/
4125
 
4126
void twobyte(int co)
4127
{
4128
putword((unsigned)co);
4129
}
4130
 
4131
/*****************************************************************************/
4132
/* threebyte : saves long integer as three instruction bytes                 */
4133
/*****************************************************************************/
4134
 
4135
void threebyte(unsigned __int64 co)
4136
{
4137
putbyte((unsigned short)((co >> 24LL) & 0xfffLL));
4138
putbyte((unsigned short)((co >> 12LL) & 0xfffLL));
4139
putbyte((unsigned short)(co & 0xfffL));
4140
}
4141
 
4142
/*****************************************************************************/
4143
/* fourbyte : saves long integer as four instruction bytes                   */
4144
/*****************************************************************************/
4145
 
4146
void fourbyte(unsigned __int64 co)
4147
{
4148
  putbyte((unsigned short)((co >> 36LL) & 0xfffLL));
4149
  putbyte((unsigned short)((co >> 24LL) & 0xfffLL));
4150
  putbyte((unsigned short)((co >> 12LL) & 0xfffLL));
4151
  putbyte((unsigned short)(co & 0xfffL));
4152
}
4153
 
4154
/*****************************************************************************/
4155
/* oneimm : saves one immediate value                                        */
4156
/*****************************************************************************/
4157
 
4158
void oneimm(int co)
4159
{
4160
struct relocrecord p = {0};
4161
 
4162
scanoperands(&p);
4163
if (mode >= ADRMODE_POST)
4164
  error |= ERR_ILLEGAL_ADDR;
4165
putbyte((unsigned short)co);
4166
 
4167
/* addreloc(0, 2, p); */                /* no relocation for immediate op's  */
4168
 
4169
putbyte((unsigned short)operand);
4170
}
4171
 
4172
/*****************************************************************************/
4173
/* lea :                                                                     */
4174
/*****************************************************************************/
4175
 
4176
void lea(int co)
4177
{
4178
struct relocrecord p = {0};
4179
 
4180
scanoperands(&p);
4181
if (isFar)
4182
        onebyte(0x015);
4183
onebyte((unsigned short)co);
4184
if (mode == ADRMODE_IMM)
4185
  error |= ERR_ILLEGAL_ADDR;
4186
if (mode < ADRMODE_POST)
4187
  {
4188
          if (isFar)
4189
                  opsize = 4;
4190
          else
4191
                opsize = 3;
4192
  postbyte = 0x80f;
4193
  mode = ADRMODE_POST;
4194
  }
4195
doaddress(&p);
4196
}
4197
 
4198
/*****************************************************************************/
4199
/* sbranch : processes a short branch                                        */
4200
/*****************************************************************************/
4201
 
4202
void sbranch(int co)
4203
{
4204
struct relocrecord p = {0};
4205
int offs;
4206
 
4207
scanoperands(&p);
4208
if (mode != ADRMODE_DIR && mode != ADRMODE_EXT)
4209
  error |= ERR_ILLEGAL_ADDR;
4210
offs = operand - loccounter - 2;
4211
if (!unknown && (offs < -2048 || offs >= 2048))
4212
  error |= ERR_RANGE;
4213
if (pass > 1 && unknown)
4214
  error |= ERR_LABEL_UNDEF;
4215
putbyte((unsigned short)co);
4216
putbyte((unsigned short)offs);
4217
}
4218
 
4219
/*****************************************************************************/
4220
/* lbra : does a long branch                                                 */
4221
/*****************************************************************************/
4222
 
4223
void lbra(int co)
4224
{
4225
struct relocrecord p = {0};
4226
int nDiff;
4227
 
4228
scanoperands(&p);
4229
if (mode != ADRMODE_DIR && mode != ADRMODE_EXT)
4230
  error |= ERR_ILLEGAL_ADDR;
4231
putbyte((unsigned short)co);
4232
 
4233
nDiff = operand - loccounter - 3;
4234
putword((unsigned)nDiff);
4235
if (((nDiff & 0xff8000) == 0x000000) ||
4236
    ((nDiff & 0xff8000) == 0xff8000))
4237
  warning |= (certain) ? WRN_OPT : 0;
4238
}
4239
 
4240
/*****************************************************************************/
4241
/* lbranch : does a long branch                                              */
4242
/*****************************************************************************/
4243
 
4244
void lbranch(int co)
4245
{
4246
struct relocrecord p = {0};
4247
int nDiff;
4248
 
4249
scanoperands(&p);
4250
if (mode != ADRMODE_DIR && mode != ADRMODE_EXT)
4251
  error |= ERR_ILLEGAL_ADDR;
4252
putword((unsigned)co);
4253
nDiff = operand - loccounter - 4;
4254
putword((unsigned)nDiff);
4255
if (((nDiff & 0xff8000) == 0x000000) ||
4256
    ((nDiff & 0xff8000) == 0xff8000))
4257
  warning |= (certain) ? WRN_OPT : 0;
4258
}
4259
 
4260
/*****************************************************************************/
4261
/* arith : process arithmetic operation                                      */
4262
/*****************************************************************************/
4263
 
4264
void arith(int co, char noimm)
4265
{
4266
struct relocrecord p = {0};
4267
 
4268
scanoperands(&p);
4269
switch (mode)
4270
  {
4271
  case ADRMODE_IMM :
4272
    if (noimm)
4273
      error |= ERR_ILLEGAL_ADDR;
4274
    opsize = 2;
4275
    putbyte((unsigned short)co);
4276
    break;
4277
  case ADRMODE_DIR :
4278
    putbyte((unsigned short)(co + 0x010));
4279
    break;
4280
  case ADRMODE_EXT :
4281
          if (isFar)
4282
                  putbyte(0x015);
4283
    putbyte((unsigned short)(co + 0x030));
4284
    break;
4285
  default:
4286
          if (isFar)
4287
                  putbyte(0x015);
4288 12 robfinch
    if (isPostIndexed) {
4289
      //putbyte(0x01B);
4290
      postbyte |= 0x80;
4291
    }
4292 4 robfinch
    putbyte((unsigned short)(co + 0x020));
4293
  }
4294
doaddress(&p);
4295
}
4296
 
4297
/*****************************************************************************/
4298
/* accarith : process arithmetic operation with explicit accumulator         */
4299
/*****************************************************************************/
4300
 
4301
void accarith(int co, char noimm, char ignore)
4302
{
4303
char *s = srcptr;                       /* remember current offset           */
4304
char correct = 1;                       /* flag whether correct              */
4305
 
4306
skipspace();                            /* skip space                        */
4307
scanname();                             /* get following name                */
4308
 
4309
if (strcmp(unamebuf, "A") &&            /* has to be followed by A or B      */
4310
    strcmp(unamebuf, "B"))
4311
  correct = 0;
4312
 
4313
#if 1
4314
if (*srcptr == ',')                     /* if directly followed by a comma   */
4315
  srcptr++;                             /* skip it                           */
4316
#else
4317
if (!(dwOptions & OPTION_TSC))
4318
  skipspace();
4319
if (*srcptr++ != ',')                   /* and a comma                       */
4320
  correct = 0;
4321
#endif
4322
 
4323
if (!correct)                           /* if NOT followed by "A," or "B,"   */
4324
  {
4325
  if (ignore)                           /* if ignoring that,                 */
4326
    srcptr = s;                         /* go back to parm start             */
4327
  else                                  /* otherwise                         */
4328
    error |= ERR_EXPR;                  /* flag as an error                  */
4329
  }
4330
else if (unamebuf[0] == 'B')            /* eventually transform to acc.B     */
4331
  co |= 0x40;
4332
arith(co, noimm);                       /* then process as arithmetic        */
4333
}
4334
 
4335
/*****************************************************************************/
4336
/* idxextarith : indexed / extended arithmetic, 6800 style                   */
4337
/*****************************************************************************/
4338
 
4339
void idxextarith(int co)
4340
{
4341
struct relocrecord p = {0};
4342
 
4343
scanoperands(&p);
4344
switch (mode)
4345
  {
4346
  case ADRMODE_IMM :
4347
    error |= ERR_ILLEGAL_ADDR;
4348
    opsize = 3;
4349
    putbyte((unsigned short)co);
4350
    break;
4351
  case ADRMODE_DIR :
4352
    mode = ADRMODE_EXT;                 /* implicitly convert to extended    */
4353
    putbyte((unsigned short)(co + 0x030));
4354
    break;
4355
  case ADRMODE_EXT :
4356
        if (isFar)
4357
                putbyte(0x015);
4358
    putbyte((unsigned short)(co + 0x030));
4359
    break;
4360
  default:
4361
        if (isFar)
4362
                putbyte(0x015);
4363
        if (isPostIndexed)
4364 12 robfinch
                //putbyte(0x01B);
4365 4 robfinch
    putbyte((unsigned short)(co + 0x020));
4366
    break;
4367
 }
4368
doaddress(&p);
4369
}
4370
 
4371
/*****************************************************************************/
4372
/* darith : process direct arithmetic                                        */
4373
/*****************************************************************************/
4374
 
4375
void darith(int co, char noimm, char tgt)
4376
{
4377
struct relocrecord p = {0};
4378
 
4379
scanoperands(&p);
4380
switch (mode)
4381
  {
4382
  case ADRMODE_IMM :
4383
    if (noimm)
4384
      error |= ERR_ILLEGAL_ADDR;
4385
        if (isX32 && tgt)
4386
                opsize = 5;
4387
        else
4388
                opsize = 3;
4389
    putbyte((unsigned short)co);
4390
    break;
4391
  case ADRMODE_DIR :
4392
    putbyte((unsigned short)(co + 0x010));
4393
    break;
4394
  case ADRMODE_EXT :
4395
          if (isFar)
4396
                  putbyte(0x015);
4397
    putbyte((unsigned short)(co + 0x030));
4398
    break;
4399
  default:
4400
          if (isFar)
4401
                  putbyte(0x015);
4402 12 robfinch
    if (isPostIndexed) {
4403
      //putbyte(0x01B);
4404
      postbyte |= 0x80;
4405
    }
4406 4 robfinch
    putbyte((unsigned short)(co + 0x020));
4407
    break;
4408
 }
4409
doaddress(&p);
4410
}
4411
 
4412
/*****************************************************************************/
4413
/* d2arith : process direct word arithmetic                                  */
4414
/*****************************************************************************/
4415
 
4416
void d2arith(int co, char noimm, char tgt)
4417
{
4418
struct relocrecord p = {0};
4419
 
4420
scanoperands(&p);
4421
switch (mode)
4422
  {
4423
  case ADRMODE_IMM :
4424
    if (noimm)
4425
      error |= ERR_ILLEGAL_ADDR;
4426
        if (isX32 && tgt)
4427
                opsize = 5;
4428
        else
4429
                opsize = 3;
4430
    putword((unsigned)co);
4431
    break;
4432
  case ADRMODE_DIR :
4433
    putword((unsigned)(co + 0x010));
4434
    break;
4435
  case ADRMODE_EXT :
4436
          if (isFar) {
4437
                  putbyte(0x015);
4438
          }
4439
    putword((unsigned)(co + 0x030));
4440
    break;
4441
  default:
4442
          if (isFar)
4443
                  putbyte(0x015);
4444 12 robfinch
    if (isPostIndexed) {
4445
      //putbyte(0x01B);
4446
      postbyte |= 0x80;
4447
    }
4448 4 robfinch
    putword((unsigned)(co + 0x020));
4449
 }
4450
doaddress(&p);
4451
}
4452
 
4453
/*****************************************************************************/
4454
/* qarith : process direct doubleword arithmetic                             */
4455
/*****************************************************************************/
4456
 
4457
void qarith(int co, char noimm)
4458
{
4459
struct relocrecord p = {0};
4460
 
4461
scanoperands(&p);
4462
switch (mode)
4463
  {
4464
  case ADRMODE_IMM :
4465
    if (noimm)
4466
      error |= ERR_ILLEGAL_ADDR;
4467
    opsize = 5;
4468
    putbyte((unsigned short)0xcd);       /* this can ONLY be LDQ!             */
4469
    break;
4470
  case ADRMODE_DIR :
4471
    putword((unsigned)(co + 0x010));
4472
    break;
4473
  case ADRMODE_EXT :
4474
    putword((unsigned)(co + 0x030));
4475
    break;
4476
  default:
4477
    putword((unsigned)(co + 0x020));
4478
    break;
4479
 }
4480
doaddress(&p);
4481
}
4482
 
4483
/*****************************************************************************/
4484
/* oneaddr :                                                                 */
4485
/*****************************************************************************/
4486
 
4487
void oneaddr(int co)
4488
{
4489
struct relocrecord p = {0};
4490
char *s;
4491
 
4492
skipspace();
4493
if ((dwOptions & OPTION_TSC) &&         /* if TSC mode, check for 6800       */
4494
    (co != 0x0e))                       /* convenience things                */
4495
  {
4496
  s = srcptr;
4497
  scanname();                           /* look whether followed by A or B   */
4498
  if (((!strcmp(unamebuf, "A")) ||
4499
       (!strcmp(unamebuf, "B"))) &&
4500
      (*srcptr != ','))                 /* and NO comma                      */
4501
    {                                   /* if so, replace by 6809 mnemonic   */
4502
    warning |= WRN_AMBIG;               /* ... but not without a warning     */
4503
    onebyte(co | ((unamebuf[0] == 'A') ? 0x40 : 0x50));
4504
    return;
4505
    }
4506
  srcptr = s;
4507
  }
4508
 
4509
scanoperands(&p);
4510
switch (mode)
4511
  {
4512
  case ADRMODE_IMM :
4513
    error |= ERR_ILLEGAL_ADDR;
4514
    break;
4515
  case ADRMODE_DIR :
4516
    if ((dwOptions & OPTION_M00) &&     /* on MC6800, a DIRect JMP is not OK */
4517
        (co == 0x0e))
4518
      error |= ERR_ILLEGAL_ADDR;
4519
    else
4520
      putbyte((unsigned short)co);
4521
    break;
4522
  case ADRMODE_EXT :
4523
          if (isFar)
4524
                  putbyte(0x015);
4525
    putbyte((unsigned short)(co + 0x70));
4526
    break;
4527
  default:
4528
          if (isFar)
4529
                  putbyte(0x015);
4530 12 robfinch
    if (isPostIndexed) {
4531
      //putbyte(0x01B);
4532
      postbyte |= 0x80;
4533
    }
4534 4 robfinch
    putbyte((unsigned short)(co + 0x60));
4535
    break;
4536
  }
4537
doaddress(&p);
4538
}
4539
 
4540
/*****************************************************************************/
4541
/* accaddr :                                                                 */
4542
/*****************************************************************************/
4543
 
4544
void accaddr(int co)
4545
{
4546
struct relocrecord p = {0};
4547
char *s;
4548
 
4549
skipspace();
4550
if (dwOptions & OPTION_TSC)             /* if TSC mode, check for 6800       */
4551
  {
4552
  s = srcptr;
4553
  scanname();                           /* look whether followed by A or B   */
4554
  if (((!strcmp(unamebuf, "A")) ||
4555
       (!strcmp(unamebuf, "B"))) &&
4556
      (*srcptr != ','))                 /* and NO comma                      */
4557
    {                                   /* if so, replace                    */
4558
    onebyte(co | ((unamebuf[0] == 'A') ? 0x40 : 0x50));
4559
    return;
4560
    }
4561
  srcptr = s;
4562
  }
4563
 
4564
scanoperands(&p);
4565
switch (mode)
4566
  {
4567
  case ADRMODE_IMM :
4568
    error |= ERR_ILLEGAL_ADDR;
4569
    break;
4570
  case ADRMODE_DIR :
4571
    mode = ADRMODE_EXT;                 /* silently convert to extended      */
4572
    putbyte((unsigned short)(co + 0x70));
4573
    break;
4574
  case ADRMODE_EXT :
4575
          if (isFar)
4576
                  putbyte(0x15);
4577
    putbyte((unsigned short)(co + 0x70));
4578
    break;
4579
  default:
4580
          if (isFar)
4581
                  putbyte(0x15);
4582 12 robfinch
    if (isPostIndexed) {
4583
      //putbyte(0x1B);
4584
      postbyte |= 0x80;
4585
    }
4586 4 robfinch
    putbyte((unsigned short)(co + 0x60));
4587
    break;
4588
  }
4589
doaddress(&p);
4590
}
4591
 
4592
/*****************************************************************************/
4593
/* tfrexg :                                                                  */
4594
/*****************************************************************************/
4595
 
4596
void tfrexg(int co)
4597
{
4598
struct regrecord * p;
4599
 
4600
putbyte((unsigned char)co);
4601
skipspace();
4602
scanname();
4603
 
4604
if (dwOptions & OPTION_H63)
4605
  p = findreg63(unamebuf);
4606
else
4607
  p = findreg(unamebuf);
4608
if (!p)
4609
  error |= ERR_ILLEGAL_ADDR;
4610
else
4611
 postbyte = (p->tfr) << 4;
4612
skipspace();
4613
if (*srcptr == ',')
4614
  srcptr++;
4615
else
4616
 error |= ERR_ILLEGAL_ADDR;
4617
skipspace();
4618
scanname();
4619
if ((p = findreg(unamebuf)) == 0)
4620
  error |= ERR_ILLEGAL_ADDR;
4621
else
4622
 postbyte |= p->tfr;
4623
putbyte(postbyte);
4624
}
4625
 
4626
/*****************************************************************************/
4627
/* pshpul : operates on PSH / PUL mnemonics                                  */
4628
/*****************************************************************************/
4629
 
4630
void pshpul(int co)
4631
{
4632
struct regrecord *p;
4633
struct relocrecord sp = {0};
4634
 
4635
postbyte = 0;
4636
 
4637
skipspace();
4638
if (*srcptr == '#')
4639
  {
4640
  srcptr++;
4641
  if (!(dwOptions & OPTION_TSC))
4642
    skipspace();
4643
  postbyte = (unsigned short)scanexpr(0, &sp);
4644
  }
4645
else do
4646
  {
4647
  if (*srcptr=='f' || *srcptr=='F') {
4648
          if (srcptr[1]=='a' || srcptr[1]=='A') {
4649
                  if (srcptr[2]=='r' || srcptr[2]=='R') {
4650
                          if (srcptr[3]==' ' || srcptr[3]=='\t') {
4651
                                  isFar = 1;
4652
                                  srcptr += 4;
4653
                          }
4654
                  }
4655
          }
4656
  }
4657
  if (*srcptr == ',')
4658
    srcptr++;
4659
  if (!(dwOptions & OPTION_TSC))
4660
    skipspace();
4661
  scanname();
4662
  if ((p = findreg(unamebuf)) == 0)
4663
    error |= ERR_ILLEGAL_ADDR;
4664
  else
4665
    postbyte |= p->psh;
4666
  if (!(dwOptions & OPTION_TSC))
4667
    skipspace();
4668
  } while (*srcptr == ',');
4669
if (isFar)
4670
        putbyte((unsigned short)0x15);
4671
putbyte((unsigned short)co);
4672
putbyte(postbyte);
4673
}
4674
 
4675
/*****************************************************************************/
4676
/* bitdirect :                                                               */
4677
/*****************************************************************************/
4678
 
4679
void bitdirect(int co)
4680
{
4681
struct relocrecord p = {0};
4682
unsigned short dir;
4683
 
4684
skipspace();
4685
if (*srcptr++ != '#')
4686
  error |= ERR_EXPR;
4687
dir = (unsigned)scanexpr(0, &p);
4688
if (dir & 0xfff000)
4689
  error |= ERR_EXPR;
4690
if (!(dwOptions & OPTION_TSC))
4691
  skipspace();
4692
if (*srcptr++ != ',')
4693
  error |= ERR_EXPR;
4694
scanoperands(&p);
4695
switch (mode)
4696
  {
4697
  case ADRMODE_IMM :
4698
    error |= ERR_ILLEGAL_ADDR;
4699
    break;
4700
  case ADRMODE_DIR :
4701
    putbyte((unsigned short)co);
4702
    break;
4703
  case ADRMODE_EXT :
4704
          if (isFar)
4705
                  putbyte(0x15);
4706
    putbyte((unsigned short)(co + 0x70));
4707
    break;
4708
  default:
4709
          if (isFar)
4710
                  putbyte(0x15);
4711
    putbyte((unsigned short)(co + 0x60));
4712
    break;
4713
  }
4714
putbyte((unsigned short)dir);
4715
doaddress(&p);
4716
}
4717
 
4718
/*****************************************************************************/
4719
/* bittrans :                                                                */
4720
/*****************************************************************************/
4721
 
4722
void bittrans(int co)
4723
{
4724
struct regrecord *p;
4725
struct relocrecord rp = {0};
4726
long t;
4727
 
4728
putword((unsigned)co);
4729
 
4730
skipspace();
4731
scanname();
4732
if ((p = findbitreg(unamebuf)) == 0)
4733
  error |= ERR_ILLEGAL_ADDR;
4734
else
4735
  postbyte = (p->tfr) << 6;
4736
if (!(dwOptions & OPTION_TSC))
4737
  skipspace();
4738
if (*srcptr == ',')
4739
  srcptr++;
4740
else
4741
 error |= ERR_ILLEGAL_ADDR;
4742
if (!(dwOptions & OPTION_TSC))
4743
  skipspace();
4744
t = scanfactor(&rp);
4745
if (t & 0xfffff8)
4746
  error |= ERR_ILLEGAL_ADDR;
4747
else
4748
  postbyte |= (t << 3);
4749
if (!(dwOptions & OPTION_TSC))
4750
  skipspace();
4751
if (*srcptr == ',')
4752
  srcptr++;
4753
else
4754
 error |= ERR_ILLEGAL_ADDR;
4755
t = scanfactor(&rp);
4756
if (t & 0xfffff8)
4757
  error |= ERR_ILLEGAL_ADDR;
4758
else
4759
  postbyte |= t;
4760
putbyte((unsigned short)postbyte);
4761
if (!(dwOptions & OPTION_TSC))
4762
  skipspace();
4763
if (*srcptr == ',')
4764
  srcptr++;
4765
else
4766
 error |= ERR_ILLEGAL_ADDR;
4767
scanoperands(&rp);
4768
switch (mode)
4769
  {
4770
  case ADRMODE_DIR :
4771
    putbyte((unsigned short)operand);
4772
    break;
4773
  default:
4774
    error |= ERR_ILLEGAL_ADDR;
4775
  }
4776
}
4777
 
4778
/*****************************************************************************/
4779
/* blocktrans :                                                              */
4780
/*****************************************************************************/
4781
 
4782
void blocktrans(int co)
4783
{
4784
char reg1,reg2;
4785
char mode[3] = "";
4786
static char regnames[] = "DXYUS";
4787
static char *modes[] =
4788
  {
4789
  "++",
4790
  "--",
4791
  "+",
4792
  ",+"
4793
  };
4794
int i;
4795
 
4796
skipspace();
4797
reg1 = toupper(*srcptr);
4798
for (i = 0; regnames[i]; i++)
4799
  if (reg1 == regnames[i])
4800
    break;
4801
if (!regnames[i])
4802
  error |= ERR_ILLEGAL_ADDR;
4803
else
4804
  reg1 = i;
4805
mode[0] = *++srcptr;
4806
if ((mode[0] != '+') && (mode[0] != '-'))
4807
  {
4808
  if (!(dwOptions & OPTION_TSC))
4809
    skipspace();
4810
  mode[0] = *srcptr;
4811
  }
4812
else
4813
  srcptr++;
4814
if (!(dwOptions & OPTION_TSC))
4815
  skipspace();
4816
if (*srcptr != ',')
4817
  error |= ERR_ILLEGAL_ADDR;
4818
srcptr++;
4819
reg2 = toupper(*srcptr);
4820
for (i = 0; regnames[i]; i++)
4821
  if (reg2 == regnames[i])
4822
    break;
4823
if (!regnames[i])
4824
  error |= ERR_ILLEGAL_ADDR;
4825
else
4826
  reg2 = i;
4827
mode[1] = *++srcptr;
4828
if ((mode[1] != '+') && (mode[1] != '-'))
4829
  {
4830
  if (!(dwOptions & OPTION_TSC))
4831
    skipspace();
4832
  mode[1] = *srcptr;
4833
  }
4834
else
4835
  srcptr++;
4836
if ((mode[1] == ';') || (mode[1] == '*') ||
4837
    (mode[1] == ' ') || (mode[1] == '\t'))
4838
  mode[1] = '\0';
4839
for (i = 0; i < (sizeof(modes) / sizeof(modes[0])); i++)
4840
  if (!strcmp(mode, modes[i]))
4841
    break;
4842
if (i >= (sizeof(modes) / sizeof(modes[0])))
4843
  error |= ERR_ILLEGAL_ADDR;
4844
else
4845
  co |= i;
4846
 
4847
putword((unsigned)co);
4848
putbyte((unsigned short)((reg1 << 4) | reg2));
4849
}
4850
 
4851
/*****************************************************************************/
4852
/* expandline : un-tabify current line                                       */
4853
/*****************************************************************************/
4854
 
4855
void expandline()
4856
{
4857
int i, j = 0, k, j1;
4858
 
4859
for (i = 0; i < LINELEN && j < LINELEN; i++)
4860
  {
4861
  if (inpline[i] == '\n')
4862
    {
4863
    srcline[j] = 0;
4864
    break;
4865
    }
4866
  else if (inpline[i] == '\t')
4867
    {
4868
    j1 = j;
4869
    for (k = 0; k < 8 - j1 % 8 && j < LINELEN; k++)
4870
      srcline[j++] = ' ';
4871
    }
4872
  else if (inpline[i] == '\r')
4873
    {
4874
    continue;
4875
    }
4876
  else
4877
    srcline[j++] = inpline[i];
4878
 }
4879
srcline[LINELEN - 1] = 0;
4880
}
4881
 
4882
/*****************************************************************************/
4883
/* expandtext : expands all texts in a line                                  */
4884
/*****************************************************************************/
4885
 
4886
void expandtext()
4887
{
4888
char *p;
4889
int i, j = 0;
4890
int doit = 1;
4891
 
4892
for (p = curline->txt; (*p) && (j < LINELEN); )
4893
  {
4894
  if (*p == '\"')
4895
    doit = !doit;
4896
 
4897
  if (*p == '\\' && p[1] == '&')
4898
    srcline[j++] = *(++p);
4899
  else if (*p == '&' &&
4900
           (p[1] < '0' || p[1] > '9') &&
4901
           doit)
4902
    {
4903
    struct symrecord *lp;
4904
    srcptr = p + 1;
4905
    scanname();
4906
    lp = findsym(namebuf, 0);
4907
    if ((lp) && (*namebuf) &&           /* if symbol IS a text constant,     */
4908
        (lp->cat == SYMCAT_TEXT))
4909
      {                                 /* insert its content                */
4910
      p = srcptr;
4911
      for (i = 0; j < LINELEN && texts[lp->value][i]; i++)
4912
        srcline[j++] = texts[lp->value][i];
4913
      }
4914
    else                                /* otherwise                         */
4915
      srcline[j++] = *p++;              /* simply use the '&' and go on.     */
4916
    }
4917
  else
4918
    srcline[j++] = *p++;
4919
  }
4920
srcline[j >= LINELEN ? LINELEN - 1 : j] = '\0';
4921
}
4922
 
4923
/*****************************************************************************/
4924
/* readfile : reads in a file and recurses through includes                  */
4925
/*****************************************************************************/
4926
 
4927
struct linebuf *readfile(char *name, unsigned char lvl, struct linebuf *after)
4928
{
4929
FILE *srcfile;
4930
struct linebuf *pNew;
4931
int lineno = 0;
4932
int i;
4933
int nfnidx = -1;
4934
 
4935
for (i = 0; i < nfnms; i++)             /* prohibit recursion                */
4936
  if (!strcmp(name, fnms[i]))
4937
    {
4938
    nfnidx = i;
4939
    break;
4940
    }
4941
if (nfnidx < 0)
4942
  {
4943
  if (nfnms >= (sizeof(fnms) / sizeof(fnms[0])))
4944
    {
4945
    printf("%s(0) : error 21: nesting level too deep\n", name);
4946
    if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
4947
      putlist( "*** Error 21: nesting level too deep\n");
4948
    exit(4);
4949
    }
4950
  nfnidx = nfnms++;
4951
  }
4952
 
4953
if ((srcfile = fopen(name, "r")) == 0)
4954
  {
4955
  printf("%s(0) : error 17: cannot open source file\n", name);
4956
  if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
4957
    putlist( "*** Error 17: cannot open source file\n");
4958
  exit(4);
4959
  }
4960
if (!fnms[nfnidx])                      /* if not yet done,                  */
4961
  fnms[nfnidx] = strdup(name);          /* remember the file name            */
4962
while (fgets(inpline, LINELEN, srcfile))
4963
  {
4964
  expandline();
4965
  pNew = allocline(after, fnms[nfnidx], ++lineno, lvl, srcline);
4966
  if (!pNew)
4967
    {
4968
    printf("%s(%d) : error 22: memory allocation error\n", name, lineno);
4969
    if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
4970
      putlist( "*** Error 22: memory allocation error\n");
4971
    exit(4);
4972
    }
4973
  if (!after)                           /* if 1st line                       */
4974
    rootline = pNew;                    /* remember it as root               */
4975
  after = pNew;                         /* insert behind the new line        */
4976
  }
4977
fclose(srcfile);                        /* then close the file               */
4978
return after;                           /* pass back last line inserted      */
4979
}
4980
 
4981
/*****************************************************************************/
4982
/* readbinary: reads in a binary file and converts to fcw / fcb lines        */
4983
/*****************************************************************************/
4984
 
4985
struct linebuf *readbinary
4986
    (
4987
    char *name,
4988
    unsigned char lvl,
4989
    struct linebuf *after,
4990
    struct symrecord *lp
4991
    )
4992
{
4993
FILE *srcfile;
4994
struct linebuf *pNew;
4995
int lineno = 0;
4996
int i;
4997
int nfnidx = -1;
4998
unsigned char binlin[16];
4999
int binlen;
5000
int fcbstart;
5001
 
5002
for (i = 0; i < nfnms; i++)             /* prohibit recursion                */
5003
  if (!strcmp(name, fnms[i]))
5004
    {
5005
    nfnidx = i;
5006
    break;
5007
    }
5008
if (nfnidx < 0)
5009
  {
5010
  if (nfnms >= (sizeof(fnms) / sizeof(fnms[0])))
5011
    {
5012
    printf("%s(0) : error 21: nesting level too deep\n", name);
5013
    if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
5014
      putlist( "*** Error 21: nesting level too deep\n");
5015
    exit(4);
5016
    }
5017
  nfnidx = nfnms++;
5018
  }
5019
 
5020
if ((srcfile = fopen(name, "rb")) == 0)
5021
  {
5022
  printf("%s(0) : error 17: cannot open source file\n", name);
5023
  if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
5024
    putlist( "*** Error 17: cannot open source file\n");
5025
  exit(4);
5026
  }
5027
if (!fnms[nfnidx])                      /* if not yet done,                  */
5028
  fnms[nfnidx] = strdup(name);          /* remember the file name            */
5029
while ((binlen = (int)fread(binlin, 1, sizeof(binlin), srcfile)) > 0)
5030
  {
5031
  sprintf(inpline, "%s", (lineno || (!lp)) ? "" : lp->name);
5032
  i = 0;
5033
  if ((binlen & (~1)) && (binlen > 7))
5034
    {
5035
    sprintf(inpline + strlen(inpline), "\tFCW\t" /* , (binlen & 1) ? 'B' : 'W' */);
5036
    for (; i < (binlen & ~1); i += 2)
5037
      sprintf(inpline + strlen(inpline), "%s$%02X%02X", (i) ? "," : "",
5038
              binlin[i], binlin[i + 1]);
5039
    expandline();
5040
    pNew = allocline(after, fnms[nfnidx], ++lineno, lvl, srcline);
5041
    if (!pNew)
5042
      {
5043
      printf("%s(%d) : error 22: memory allocation error\n", name, lineno);
5044
      if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
5045
        putlist( "*** Error 22: memory allocation error\n");
5046
      exit(4);
5047
      }
5048
    if (!after)                         /* if 1st line                       */
5049
      rootline = pNew;                  /* remember it as root               */
5050
    after = pNew;                       /* insert behind the new line        */
5051
    inpline[0] = '\0';                  /* reset input line                  */
5052
    }
5053
  if ((binlen & 1) || (binlen <= 7))
5054
    {
5055
    fcbstart = i;
5056
    sprintf(inpline + strlen(inpline), "\tFCB\t");
5057
    for (; i < binlen; i++)
5058
      sprintf(inpline + strlen(inpline), "%s$%02X", (i > fcbstart) ? "," : "",
5059
              binlin[i]);
5060
 
5061
    expandline();
5062
    pNew = allocline(after, fnms[nfnidx], ++lineno, lvl, srcline);
5063
    if (!pNew)
5064
      {
5065
      printf("%s(%d) : error 22: memory allocation error\n", name, lineno);
5066
      if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
5067
        putlist( "*** Error 22: memory allocation error\n");
5068
      exit(4);
5069
      }
5070
    if (!after)                         /* if 1st line                       */
5071
      rootline = pNew;                  /* remember it as root               */
5072
    after = pNew;                       /* insert behind the new line        */
5073
    }
5074
  }
5075
fclose(srcfile);                        /* then close the file               */
5076
return after;                           /* pass back last line inserted      */
5077
}
5078
 
5079
/*****************************************************************************/
5080
/* setoptiontexts : sets up the option text variables                        */
5081
/*****************************************************************************/
5082
 
5083
void setoptiontexts()
5084
{
5085
int i;
5086
                                        /* walk option list                  */
5087
for (i = 0; i < (sizeof(Options) / sizeof(Options[0])); i++)
5088
  {
5089
  if ((dwOptions & Options[i].dwAdd) ||
5090
      (!(dwOptions & ~Options[i].dwRem)))
5091
    settext(Options[i].Name, "1");
5092
  else
5093
    settext(Options[i].Name, "0");
5094
  }
5095
}
5096
 
5097
/*****************************************************************************/
5098
/* setoption : processes an option string                                    */
5099
/*****************************************************************************/
5100
 
5101
int setoption ( char *szOpt )
5102
{
5103
char iopt[4];
5104
int i;
5105
 
5106
for (i = 0; szOpt[i] && i < sizeof(iopt); i++)
5107
  iopt[i] = toupper(szOpt[i]);
5108
if (i >= sizeof(iopt))
5109
  i--;
5110
iopt[i] = '\0';
5111
                                        /* search option list                */
5112
for (i = 0; i < (sizeof(Options) / sizeof(Options[0])); i++)
5113
  {
5114
  if (!strcmp(iopt, Options[i].Name))   /* if option found                   */
5115
    {
5116
    dwOptions |= Options[i].dwAdd;      /* add flags                         */
5117
    dwOptions &= ~Options[i].dwRem;     /* and remove flags                  */
5118
 
5119
    switch (Options[i].dwAdd)           /* afterprocessing for specials:     */
5120
      {
5121
      case OPTION_M09 :                 /* switch to MC6809 processor        */
5122
        optable = optable09;
5123
        optablesize = sizeof(optable09) / sizeof(optable09[0]);
5124
        regtable = regtable09;
5125
        bitregtable = bitregtable09;
5126
        scanoperands = scanoperands09;
5127
        break;
5128
      case OPTION_H63 :                 /* switch to HD6309 processor        */
5129
        optable = optable09;
5130
        optablesize = sizeof(optable09) / sizeof(optable09[0]);
5131
        regtable = regtable63;
5132
        bitregtable = bitregtable09;
5133
        scanoperands = scanoperands09;
5134
        break;
5135
      case OPTION_M00 :                 /* switch to MC6800 processor        */
5136
        optable = optable00;
5137
        optablesize = sizeof(optable00) / sizeof(optable00[0]);
5138
        regtable = regtable00;
5139
        bitregtable = bitregtable00;
5140
        scanoperands = scanoperands00;
5141
        break;
5142
      }
5143
 
5144
    setoptiontexts();
5145
    return 0;                           /* then return OK                    */
5146
    }
5147
  }
5148
 
5149
return 1;                               /* unknown option                    */
5150
}
5151
 
5152
/*****************************************************************************/
5153
/* pseudoop : processes all known pseudo-ops                                 */
5154
/*****************************************************************************/
5155
 
5156
void pseudoop(int co, struct symrecord * lp)
5157
{
5158
int i, j;
5159
char c;
5160
struct relocrecord p = {0};
5161
 
5162
if (common &&                           /* if in COMMON definition mode      */
5163
    (co != PSEUDO_ENDCOM) &&            /* and this is neither ENDCOM        */
5164
    (co != PSEUDO_RMB))                 /* nor RMB                           */
5165
  error |= ERR_EXPR;                    /* this is an error.                 */
5166
 
5167
switch (co)
5168
  {
5169
  case PSEUDO_ABS :                     /* ABS                               */
5170
    absmode = 1;                        /* reset mode to absolute            */
5171
    break;
5172
  case PSEUDO_DEF :                     /* DEFINE                            */
5173
    global++;                           /* all labels from now on are global */
5174
    break;
5175
  case PSEUDO_ENDDEF :                  /* ENDDEF                            */
5176
    if (global)                         /* all labels from now on are local  */
5177
      global--;
5178
    else
5179
      error |= ERR_EXPR;                /* must be paired                    */
5180
    break;
5181
  case PSEUDO_COMMON :                  /* label COMMON                      */
5182
    if (absmode)                        /* if in absolute assembler mode     */
5183
      error |= ERR_RELOCATING;
5184
    if (!lp)
5185
      error |= ERR_LABEL_MISSING;
5186
    else
5187
      lp->cat = SYMCAT_COMMON;
5188
    common++;                           /* go into common mode               */
5189
    commonsym = lp;                     /* remember common symbol            */
5190
    break;
5191
  case PSEUDO_ENDCOM :                  /* ENDCOM                            */
5192
    if (absmode)                        /* if in absolute assembler mode     */
5193
      error |= ERR_RELOCATING;
5194
    if (common)                         /* terminate common mode             */
5195
      common--;
5196
    else
5197
      error |= ERR_EXPR;                /* must be paired                    */
5198
    break;
5199
  case PSEUDO_RMB :                     /* [label] RMB <absolute expression> */
5200
  case PSEUDO_RZB :                     /* [label] RZB <absolute expression> */
5201
    operand = scanexpr(0, &p);
5202
    if (unknown)
5203
      error |= ERR_LABEL_UNDEF;
5204
 
5205
    if (common)                         /* if in common mode                 */
5206
      {
5207
      if ((lp->cat != SYMCAT_EMPTY) &&
5208
          (lp->cat != SYMCAT_UNRESOLVED) &&
5209
          (lp->cat != SYMCAT_COMMONDATA))
5210
        error |= ERR_LABEL_MULT;
5211
      if (lp->cat != SYMCAT_COMMONDATA) /* if not yet done,                  */
5212
        {
5213
        lp->cat = SYMCAT_COMMONDATA;    /* set tymbol type                   */
5214
        lp->u.parent = commonsym;       /* remember COMMON symbol            */
5215
        lp->value = commonsym->value;   /* remember offset from COMMON symbol*/
5216
        commonsym->value +=             /* append # bytes to reserve to -"-  */
5217
            (unsigned short)operand;
5218
        }
5219
      break;
5220
      }
5221
 
5222
    setlabel(lp);
5223
    if (generating && pass == MAX_PASSNO)
5224
      {
5225
      if (co != 0 || outmode == OUT_BIN)
5226
        for (i = 0; i < operand; i++)
5227
          outbyte(0, i);
5228
      else switch (outmode)
5229
        {
5230
        case OUT_SREC :                 /* Motorola S51-09 ?                 */
5231
          flushhex();
5232
          break;
5233
        case OUT_IHEX :                 /* Intel Hex ?                       */
5234
          flushihex();
5235
          break;
5236
        case OUT_FLEX :                 /* FLEX binary ?                     */
5237
          flushflex();
5238
          break;
5239
        }
5240
      }
5241
    loccounter += operand;
5242
    hexaddr = loccounter;
5243
    break;
5244
  case PSEUDO_EQU :                     /* label EQU x                       */
5245
    nRepNext = 0;                       /* reset eventual repeat             */
5246
    operand = scanexpr(0, &p);
5247
    if (!lp)
5248
      error |= ERR_LABEL_MISSING;
5249
    else
5250
      {
5251
      if (lp->cat == SYMCAT_EMPTY ||
5252
          lp->cat == SYMCAT_UNRESOLVED ||
5253
          (lp->value == (unsigned)operand &&
5254
           pass > 1))
5255
        {
5256
        if (exprcat == EXPRCAT_INTADDR)
5257
          lp->cat = SYMCAT_LABEL;
5258
        else
5259
          lp->cat = SYMCAT_CONSTANT;
5260
        lp->value = (unsigned)operand;
5261
        }
5262
      else
5263
        error |= ERR_LABEL_MULT;
5264
      }
5265
    break;
5266
  case PSEUDO_PUB :                     /* PUBLIC a[,b[,c...]]               */
5267
  case PSEUDO_EXT :                     /* EXTERN a[,b[,c...]]               */
5268
    nRepNext = 0;                       /* reset eventual repeat             */
5269
    skipspace();
5270
    while (isalnum(*srcptr))
5271
      {
5272
      scanname();                       /* parse option                      */
5273
      lp = findsym(namebuf, 1);         /* look up the symbol                */
5274
      switch (co)
5275
        {
5276
        case PSEUDO_PUB :               /* PUBLIC a[,b[,c...]]               */
5277
          if (lp->cat == SYMCAT_EMPTY ||
5278
              lp->cat == SYMCAT_UNRESOLVED)
5279
            lp->cat = SYMCAT_PUBLICUNDEF;
5280
          else if (lp->cat == SYMCAT_LABEL)
5281
            lp->cat = SYMCAT_PUBLIC;
5282
          else if (lp->cat == SYMCAT_PUBLICUNDEF)
5283
            error |= ERR_LABEL_UNDEF;
5284
          else if (lp->cat != SYMCAT_PUBLIC)
5285
            error |= ERR_LABEL_MULT;
5286
          break;
5287
        case PSEUDO_EXT :               /* EXTERN a[,b[,c...]]               */
5288
          if (absmode)                  /* if not in relocating asm mode,    */
5289
            error |= ERR_RELOCATING;    /* set error                         */
5290
          if (lp->cat == SYMCAT_EMPTY ||
5291
              lp->cat == SYMCAT_UNRESOLVED)
5292
            lp->cat = SYMCAT_EXTERN;
5293
          else if (lp->cat != SYMCAT_EXTERN)
5294
            error |= ERR_LABEL_MULT;
5295
          break;
5296
        }
5297
      if (*srcptr == ',')
5298
        {
5299
        srcptr++;
5300
        if (!(dwOptions & OPTION_TSC))
5301
          skipspace();
5302
        }
5303
      }
5304
    break;
5305
  case PSEUDO_FCB :                     /* [label] FCB expr[,expr...]        */
5306
    setlabel(lp);
5307
    generating = 1;
5308
    do
5309
      {
5310
      if (*srcptr == ',')
5311
        srcptr++;
5312
      if (!(dwOptions & OPTION_TSC))
5313
        skipspace();
5314
      if (*srcptr == '\"')
5315
        {
5316
        srcptr++;
5317
        while (*srcptr != '\"' && *srcptr)
5318
          putbyte(*srcptr++);
5319
        if (*srcptr == '\"')
5320
          srcptr++;
5321
        }
5322
      else
5323
        {
5324
        putbyte((unsigned short)scanexpr(0, &p));
5325
        if (unknown && pass == MAX_PASSNO)
5326
          error |= ERR_LABEL_UNDEF;
5327
        }
5328
      if (!(dwOptions & OPTION_TSC))
5329
        skipspace();
5330
      } while (*srcptr == ',');
5331
    break;
5332
  case PSEUDO_FCC :                     /* [label] FCC expr[,expr...]        */
5333
    setlabel(lp);
5334
    if (!(dwOptions & OPTION_TSC))
5335
      skipspace();
5336
    if (!(dwOptions & OPTION_TSC))      /* if standard                       */
5337
      {                                 /* accept ONE sequence with an       */
5338
      c = *srcptr++;                    /* arbitrary delimiter character     */
5339
      while (*srcptr != c && *srcptr)
5340
        putbyte(*srcptr++);
5341
      if (*srcptr == c)
5342
        srcptr++;
5343
      }
5344
    else                                /* if TSC extended format            */
5345
      {                                 /* accept MORE sequences             */
5346
      do
5347
        {
5348
        if (*srcptr == ',')
5349
          srcptr++;
5350
        if (!(dwOptions & OPTION_TSC))
5351
          skipspace();
5352
        c = *srcptr;
5353
        if ((c == '$') || isalnum(c))
5354
          {
5355
          putbyte((unsigned short)scanexpr(0, &p));
5356
          if (unknown && pass == MAX_PASSNO)
5357
            error |= ERR_LABEL_UNDEF;
5358
          }
5359
        else
5360
          {
5361
          srcptr++;
5362
          while (*srcptr != c && *srcptr)
5363
            putbyte(*srcptr++);
5364
          if (*srcptr == c)
5365
            srcptr++;
5366
          }
5367
        if (!(dwOptions & OPTION_TSC))
5368
          skipspace();
5369
        } while (*srcptr == ',');
5370
      }
5371
    break;
5372
  case PSEUDO_FCW :                     /* [label] FCW,FDB  expr[,expr...]   */
5373
    setlabel(lp);
5374
    generating = 1;
5375
    do
5376
      {
5377
      if (*srcptr == ',')
5378
        srcptr++;
5379
      if (!(dwOptions & OPTION_TSC))
5380
        skipspace();
5381
      putword((unsigned)scanexpr(0, &p));
5382
      if (unknown && pass == MAX_PASSNO)
5383
        error |= ERR_LABEL_UNDEF;
5384
      if (!(dwOptions & OPTION_TSC))
5385
        skipspace();
5386
      } while (*srcptr == ',');
5387
    break;
5388
  case PSEUDO_FCDW:                     /* [label] FCDW,FDB  expr[,expr...]   */
5389
    setlabel(lp);
5390
    generating = 1;
5391
    do
5392
      {
5393
      if (*srcptr == ',')
5394
        srcptr++;
5395
      if (!(dwOptions & OPTION_TSC))
5396
        skipspace();
5397
      putdword((unsigned __int64)scanexpr(0, &p));
5398
      if (unknown && pass == MAX_PASSNO)
5399
        error |= ERR_LABEL_UNDEF;
5400
      if (!(dwOptions & OPTION_TSC))
5401
        skipspace();
5402
      } while (*srcptr == ',');
5403
    break;
5404
  case PSEUDO_ELSE :                    /* ELSE                              */
5405
    if (inMacro)                        /* don't process if in MACRO def.    */
5406
      break;
5407
    nRepNext = 0;                       /* reset eventual repeat             */
5408
    suppress = 1;
5409
    condline = 1;                       /* this is a conditional line        */
5410
    break;
5411
  case PSEUDO_ENDIF :                   /* ENDIF                             */
5412
    if (inMacro)                        /* don't process if in MACRO def.    */
5413
      break;
5414
    nRepNext = 0;                       /* reset eventual repeat             */
5415
    condline = 1;                       /* this is a conditional line        */
5416
    break;
5417
  case PSEUDO_IF :                      /* IF  <expression>[,<skip>]         */
5418
  case PSEUDO_IFN :                     /* IFN <expression>[,<skip>]         */
5419
    if (inMacro)                        /* don't process if in MACRO def.    */
5420
      break;
5421
    condline = 1;                       /* this is a conditional line        */
5422
    nRepNext = 0;                       /* reset eventual repeat             */
5423
    operand = scanexpr(0, &p);
5424
    if (unknown)
5425
      error |= ERR_LABEL_UNDEF;
5426
    if (co == PSEUDO_IFN)               /* if IFN                            */
5427
      operand = !operand;               /* reverse operand                   */
5428
    if (!(dwOptions & OPTION_TSC))
5429
      skipspace();
5430
    if (*srcptr == ',')                 /* skip count?                       */
5431
      {
5432
      srcptr++;
5433
      if (!(dwOptions & OPTION_TSC))
5434
        skipspace();
5435
      nSkipCount = scanexpr(0, &p);
5436
      if (!operand)
5437
        nSkipCount = 0;
5438
      }
5439
    else if (!operand)
5440
      suppress = 2;
5441
    break;
5442
  case PSEUDO_IFC :                     /* IFC  <string1>,<string2>[,<skip>] */
5443
  case PSEUDO_IFNC :                    /* IFNC <string1>,<string2>[,<skip>] */
5444
    if (inMacro)                        /* don't process if in MACRO def.    */
5445
      break;
5446
    condline = 1;                       /* this is a conditional line        */
5447
    if (!(dwOptions & OPTION_TSC))
5448
      skipspace();
5449
    scanstring(szBuf1, sizeof(szBuf1));
5450
    if (!(dwOptions & OPTION_TSC))
5451
      skipspace();
5452
    if (*srcptr != ',')                 /* if not on comma                   */
5453
      {
5454
      *szBuf2 = '\0';                   /* reset 2nd string                  */
5455
      error |= ERR_EXPR;                /* set error                         */
5456
      }
5457
    else
5458
      {
5459
      srcptr++;
5460
      if (!(dwOptions & OPTION_TSC))
5461
        skipspace();
5462
      scanstring(szBuf2, sizeof(szBuf2));
5463
      if (!(dwOptions & OPTION_TSC))
5464
        skipspace();
5465
      }
5466
    operand = !strcmp(szBuf1, szBuf2);
5467
    if (co == PSEUDO_IFNC)
5468
      operand = !operand;
5469
    if (*srcptr == ',')                 /* if skip count                     */
5470
      {
5471
      srcptr++;
5472
      if (!(dwOptions & OPTION_TSC))
5473
        skipspace();
5474
      nSkipCount = scanexpr(0, &p);
5475
      if (!operand)
5476
        nSkipCount = 0;
5477
      }
5478
    else if (!operand)
5479
      suppress = 2;
5480
    break;
5481
 
5482
  case PSEUDO_IFD :                     /* IFD <symbol>[,skipcount]          */
5483
  case PSEUDO_IFND :                    /* IFND <symbol>[,skipcount]         */
5484
    /* ATTENTION: it is easy to produce phasing errors with these 2,         */
5485
    /*            since symbols are NOT reset when starting pass 2!          */
5486
    if (inMacro)                        /* don't process if in MACRO def.    */
5487
      break;
5488
    skipspace();
5489
    scanname();                         /* parse symbol name                 */
5490
    lp = findsym(namebuf, 0);           /* look up the symbol                */
5491
    if (!(dwOptions & OPTION_TSC))
5492
      skipspace();
5493
    if (*srcptr == ',')                 /* if skip count                     */
5494
      {
5495
      srcptr++;
5496
      if (!(dwOptions & OPTION_TSC))
5497
        skipspace();
5498
      nSkipCount = scanexpr(0, &p);
5499
      if (!lp != (co == PSEUDO_IFND))
5500
        nSkipCount = 0;
5501
      }
5502
                                        /* if no skip count and NOT matched  */
5503
    else if (!lp != (co == PSEUDO_IFND))
5504
      suppress = 2;                     /* suppress until ELSE or ENDIF      */
5505
    condline = 1;                       /* this is a conditional line        */
5506
    break;
5507
 
5508
  case PSEUDO_ORG :                     /* ORG <expression>                  */
5509
    nRepNext = 0;                       /* reset eventual repeat             */
5510
    operand = scanexpr(0, &p);
5511
    if (unknown)
5512
      error |= ERR_LABEL_UNDEF;
5513
    if (relocatable &&                  /* if in relocating assembler mode   */
5514
        (!absmode))
5515
      {
5516
      error |= ERR_RELOCATING;          /* set error                         */
5517
      break;                            /* and ignore                        */
5518
      }
5519
    if (generating && pass == MAX_PASSNO)
5520
      {
5521
      switch (outmode)
5522
        {
5523
        case OUT_BIN :                  /* binary output file                */
5524
          j = (int)(unsigned)operand - (int)loccounter;
5525
          if (j > 0)                    /* if forward gap                    */
5526
            {
5527
            for (i = 0; i < j; i++)     /* seek forward that many bytes      */
5528
              fseek(objfile, 1, SEEK_CUR);
5529
            }
5530
          else                          /* if backward gap                   */
5531
            {
5532
            j = -j;
5533
            for (i = 0; i < j; i++)     /* seek back that many bytes         */
5534
              fseek(objfile, -1, SEEK_CUR);
5535
            }
5536
          break;
5537
                case OUT_VER:
5538
                        flushver();
5539
                        break;
5540
        case OUT_SREC :                 /* motorola s51-09                   */
5541
          flushhex();
5542
          break;
5543
        case OUT_IHEX :                 /* intel hex format                  */
5544
          flushihex();
5545
          break;
5546
        case OUT_FLEX :                 /* FLEX binary                       */
5547
          flushflex();
5548
          break;
5549
        }
5550
      }
5551
    loccounter = operand;
5552
    hexaddr = loccounter;
5553
    break;
5554
  case PSEUDO_SETDP :                   /* SETDP [<abs page value>]          */
5555
    nRepNext = 0;                       /* reset eventual repeat             */
5556
    skipspace();
5557
    if ((!*srcptr) || (*srcptr == '*') || (*srcptr == ';'))
5558
      operand = -1;
5559
    else
5560
      operand = scanexpr(0, &p);
5561
    if (unknown)
5562
      error |= ERR_LABEL_UNDEF;
5563
    if (!(operand & 4095))
5564
      operand = (unsigned)operand >> 12;
5565
    if ((unsigned)operand > 4095)
5566
      operand = -1;
5567
    if (absmode)
5568
      dpsetting = operand;
5569
    else
5570
      error |= ERR_RELOCATING;
5571
    break;
5572
  case PSEUDO_SET :                     /* label SET <non external expr>     */
5573
    nRepNext = 0;                       /* reset eventual repeat             */
5574
    operand = scanexpr(0, &p);
5575
    if (!lp)
5576
      error |= ERR_LABEL_MISSING;
5577
    else
5578
      {
5579
      if (lp->cat & SYMCAT_VARIABLE ||
5580
          lp->cat == SYMCAT_UNRESOLVED)
5581
        {
5582
        if (exprcat == EXPRCAT_INTADDR)
5583
          lp->cat = SYMCAT_VARADDR;
5584
        else
5585
          lp->cat = SYMCAT_VARIABLE;
5586
        lp->value = (unsigned)operand;
5587
        }
5588
      else
5589
        error |= ERR_LABEL_MULT;
5590
      }
5591
    break;
5592
  case PSEUDO_END :                     /* END [loadaddr]                    */
5593
    nRepNext = 0;                       /* reset eventual repeat             */
5594
    if ((curline->lvl & 0x0f) == 0)     /* only in outermost level!          */
5595
      {
5596
      skipspace();                      /* skip blanks                       */
5597
      if (isfactorstart(*srcptr))       /* if possible transfer address      */
5598
        {
5599
        tfradr = (unsigned)       /* get transfer address              */
5600
            scanexpr(0, &p);
5601
        if (error)                      /* if error in here                  */
5602
          tfradr = 0;                   /* reset to zero                     */
5603
        else                            /* otherwise                         */
5604
          tfradrset = 1;                /* remember transfer addr. is set    */
5605
        }
5606
      terminate = 1;
5607
      }
5608
    break;
5609
  case PSEUDO_INCLUDE :                 /* INCLUDE <filename>                */
5610
    nRepNext = 0;                       /* reset eventual repeat             */
5611
    if (inMacro ||                      /* if in macro definition            */
5612
        (curline->lvl & LINCAT_MACEXP)) /* or macro expansion                */
5613
      error |= ERR_EXPR;                /* this is an error.                 */
5614
    else if (pass == 1)                 /* otherwise expand if in pass 1     */
5615
      {
5616
      char fname[FNLEN + 1];
5617
      int instring = 0;
5618
      char *osrc = srcptr;
5619
 
5620
      if ((curline->lvl & 0x0f) == 0x0f)/* if impossible                     */
5621
        {
5622
#if 0
5623
        allocline(curline, "NULL", -1, 0x0f,
5624
                  "Error including file - nesting level too deep");
5625
#endif
5626
        error |= ERR_MALLOC;            /* set OUT OF MEMORY error           */
5627
        break;
5628
        }
5629
      if (!(dwOptions & OPTION_TSC))
5630
        skipspace();
5631
      if (*srcptr == '\"')
5632
        {
5633
        srcptr++;
5634
        instring = 1;
5635
        }
5636
      for (i = 0; i < FNLEN; i++)
5637
        {
5638
        if (*srcptr == 0 ||
5639
            (!instring && *srcptr == ' ') ||
5640
            *srcptr == '"')
5641
          break;
5642
        fname[i] = *srcptr++;
5643
        }
5644
      fname[i] = 0;
5645
      curline->lvl |= LINCAT_INVISIBLE; /* preclude listing of INCLUDE line  */
5646
 
5647
      readfile(fname,                   /* append include after current line */
5648
               (unsigned char)((curline->lvl & 0x0f) + 1),
5649
               curline);
5650
      expandtext();                     /* re-expand current line            */
5651
      srcptr = osrc;
5652
      }
5653
    break;
5654
  case PSEUDO_OPT :                     /* OPT,OPTION  option[,option...]    */
5655
    nRepNext = 0;                       /* reset eventual repeat             */
5656
    skipspace();
5657
    while (isalnum(*srcptr))
5658
      {
5659
      scanname();                       /* parse option                      */
5660
      if (setoption(unamebuf))
5661
        error |= ERR_OPTION_UNK;
5662
      if (*srcptr == ',')
5663
        {
5664
        srcptr++;
5665
        if (!(dwOptions & OPTION_TSC))
5666
          skipspace();
5667
        }
5668
      }
5669
    break;
5670
  case PSEUDO_NAM :                     /* NAM,TTL <text>                    */
5671
  case PSEUDO_STTL :                    /* STTL <text>                       */
5672
    nRepNext = 0;                       /* reset eventual repeat             */
5673
    if (!(dwOptions & OPTION_TSC))
5674
      skipspace();
5675
    if (isalnum(*srcptr))
5676
      {
5677
      char *tgt = (co == PSEUDO_NAM) ? szTitle : szSubtitle;
5678
      char *lnblnk = tgt;
5679
      int nBytes = 0;
5680
      while (*srcptr && nBytes < (sizeof(szTitle) - 1))
5681
        {
5682
        if (*srcptr != ' ')
5683
          lnblnk = tgt;
5684
        *tgt++ = *srcptr++;
5685
        nBytes++;
5686
        }
5687
      lnblnk[1] = '\0';                 /* terminate after last nonblank     */
5688
      while (*srcptr)                   /* skip rest if too long             */
5689
        srcptr++;
5690
      }
5691
    break;
5692
  case PSEUDO_PAG :                     /* PAG [<abs expression>]            */
5693
    if (!(dwOptions & OPTION_TSC))
5694
      skipspace();
5695
    if (isfactorstart(*srcptr))         /* if possible new page number       */
5696
      {
5697
      int nPage = scanexpr(0, &p);      /* get new page #                    */
5698
      if (!error && listfile)           /* if valid and writing listfile     */
5699
        nCurPage = nPage - 1;
5700
      else
5701
        break;
5702
      }
5703
    curline->lvl |= LINCAT_INVISIBLE;
5704
    if ((listing & LIST_ON) && listfile &&
5705
        (dwOptions & OPTION_PAG) &&
5706
        (!(curline->lvl & LINCAT_LVLMASK) || (dwOptions & OPTION_LLL)) &&
5707
        (pass > 1 || (dwOptions & OPTION_LP1)))
5708
      PageFeed();
5709
    break;
5710
  case PSEUDO_SPC :                     /* SPC <n[,keep]>                    */
5711
    {
5712
    int nSpc = 1, nKeep = 0;
5713
    if (!(dwOptions & OPTION_TSC))
5714
      skipspace();
5715
    if (isfactorstart(*srcptr))         /* if possible new page number       */
5716
      {
5717
      nSpc = scanexpr(0, &p);           /* get # space lines                 */
5718
      if (!(dwOptions & OPTION_TSC))
5719
        skipspace();
5720
      if (*srcptr == ',')               /* if followed by ,                  */
5721
        {
5722
        srcptr++;
5723
        if (!(dwOptions & OPTION_TSC))
5724
          skipspace();
5725
        nKeep = scanexpr(0, &p);        /* get # keep lines                  */
5726
        }
5727
      if (error)
5728
        break;
5729
      }
5730
    curline->lvl |= LINCAT_INVISIBLE;
5731
    if (listing & LIST_ON)
5732
      {
5733
      if (nSpc > 0)                     /* if spaces needed                  */
5734
        {
5735
        if ((dwOptions & OPTION_PAG) &&
5736
            (nCurLine + nSpc + nKeep >= nLinesPerPage))
5737
          PageFeed();
5738
        else for (; nSpc; nSpc--)
5739
          putlist("\n");
5740
        }
5741
      else if (nKeep &&
5742
          (dwOptions & OPTION_PAG) &&
5743
          (nCurLine + nKeep >= nLinesPerPage))
5744
        PageFeed();
5745
      }
5746
    }
5747
    break;
5748
  case PSEUDO_REP :                     /* REP n                             */
5749
    if (!(dwOptions & OPTION_TSC))
5750
      skipspace();
5751
    nRepNext = scanexpr(0, &p);         /* get # repetitions                 */
5752
    curline->lvl |= LINCAT_INVISIBLE;
5753
    break;
5754
  case PSEUDO_SETPG :                   /* SETPG pagelen                     */
5755
    if (!(dwOptions & OPTION_TSC))
5756
      skipspace();
5757
    nLinesPerPage = scanexpr(0, &p);    /* get # lines per page              */
5758
    if (nLinesPerPage < 10)             /* adjust to boundary values         */
5759
      nLinesPerPage = 10;
5760
    else if (nLinesPerPage > 1000)
5761
      nLinesPerPage = 1000;
5762
    curline->lvl |= LINCAT_INVISIBLE;
5763
    break;
5764
  case PSEUDO_SETLI :                   /* SETLI linelen                     */
5765
    if (!(dwOptions & OPTION_TSC))
5766
      skipspace();
5767
    nColsPerLine = scanexpr(0, &p);     /* get # columns per line            */
5768
    if (nColsPerLine < 40)              /* adjust to boundary values         */
5769
      nColsPerLine = 40;
5770
    else if (nColsPerLine > 2000)
5771
      nColsPerLine = 2000;
5772
    curline->lvl |= LINCAT_INVISIBLE;
5773
    break;
5774
  case PSEUDO_SYMLEN :                  /* SYMLEN symbollength               */
5775
    if (!(dwOptions & OPTION_TSC))
5776
      skipspace();
5777
    maxidlen = scanexpr(0, &p);         /* get # significant ID places       */
5778
    if (maxidlen < 6)                   /* adjust to boundary values         */
5779
      maxidlen = 6;
5780
    else if ((outmode == OUT_REL) &&
5781
             (maxidlen > 8))
5782
      maxidlen = 8;
5783
    else if (maxidlen > MAXIDLEN)
5784
      maxidlen = MAXIDLEN;
5785
    curline->lvl |= LINCAT_INVISIBLE;
5786
    break;
5787
  case PSEUDO_MACRO :                   /* label MACRO                       */
5788
    if (!lp)                            /* a macro NEEDS a label!            */
5789
      error |= ERR_LABEL_MISSING;
5790
    if (lp->cat == SYMCAT_EMPTY)
5791
      {
5792
      if (nMacros < MAXMACROS)          /* if space for another macro defin. */
5793
        {
5794
        lp->cat = SYMCAT_MACRO;         /* remember it's a macro             */
5795
        macros[nMacros] = curline;      /* remember pointer to start line    */
5796
        lp->value = nMacros++;          /* and remember the macro            */
5797
        }
5798
      else
5799
        error |= ERR_MALLOC;
5800
      }
5801
    else if (lp->cat != SYMCAT_MACRO ||
5802
             macros[lp->value] != curline)
5803
      error |= ERR_LABEL_MULT;
5804
    inMacro++;
5805
    curline->lvl |= LINCAT_MACDEF;
5806
    if (inMacro > 1)
5807
      error |= ERR_NESTING;
5808
    break;
5809
  case PSEUDO_ENDM :                    /* ENDM                              */
5810
    if (!inMacro)
5811
      error |= ERR_EXPR;
5812
    else
5813
      inMacro--;
5814
    break;
5815
  case PSEUDO_EXITM :                   /* EXITM                             */
5816
    if (!inMacro &&                     /* only allowed inside macros        */
5817
         !(curline->lvl & LINCAT_MACEXP))
5818
      error |= ERR_EXPR;
5819
    break;
5820
  case PSEUDO_REG :                     /* label REG <register list>         */
5821
    if (!lp)                            /* label is mandatory!               */
5822
      error |= ERR_LABEL_MISSING;
5823
    {
5824
    struct regrecord *p;
5825
    postbyte = 0;
5826
    do
5827
      {
5828
      if (*srcptr == ',')
5829
        srcptr++;
5830
      if (!(dwOptions & OPTION_TSC))
5831
        skipspace();
5832
      scanname();
5833
      if ((p = findreg(unamebuf)) == 0)
5834
        error |= ERR_ILLEGAL_ADDR;
5835
      else
5836
        postbyte |= p->psh;
5837
      if (!(dwOptions & OPTION_TSC))
5838
        skipspace();
5839
      } while (*srcptr == ',');
5840
    if (lp->cat == SYMCAT_EMPTY)
5841
      {
5842
      lp->cat = SYMCAT_REG;
5843
      lp->value = postbyte;
5844
      }
5845
    else if (lp->cat != SYMCAT_REG ||
5846
             lp->value != postbyte)
5847
      error |= ERR_LABEL_MULT;
5848
    }
5849
    break;
5850
  case PSEUDO_ERR :                     /* ERR text?                         */
5851
    if (!(dwOptions & OPTION_TSC))
5852
      skipspace();
5853
    if (pass != 1)                      /* ignore in pass 1                  */
5854
      {
5855
      errormsg[14] = srcptr;
5856
      error |= ERR_ERRTXT;
5857
      }
5858
    break;
5859
  case PSEUDO_TEXT :                    /* TEXT text ?                       */
5860
    if (!(dwOptions & OPTION_TSC))
5861
      skipspace();
5862
    if (!lp)                            /* label is mandatory!               */
5863
      error |= ERR_LABEL_MISSING;
5864
    else if (lp->cat != SYMCAT_EMPTY && /* and must be text, if there        */
5865
             lp->cat != SYMCAT_TEXT)
5866
      error |= ERR_LABEL_MULT;
5867
    else                                /* if all OK, (re)define text        */
5868
      settext(lp->name, srcptr);
5869
    break;
5870
  case PSEUDO_NAME :                    /* NAME <modulename> ?               */
5871
    if (!(dwOptions & OPTION_TSC))
5872
      skipspace();
5873
    scanname();
5874
    if (!namebuf[0])                    /* name must be given                */
5875
      error |= ERR_EXPR;
5876
    strncpy(modulename, namebuf, 8);
5877
    break;
5878
  case PSEUDO_BINARY :                  /* BIN[ARY] <filename> ?             */
5879
    nRepNext = 0;                       /* reset eventual repeat             */
5880
    if (pass == 1)                      /* expand if in pass 1               */
5881
      {
5882
      char fname[FNLEN + 1];
5883
      int instring = 0;
5884
      char *osrc = srcptr;
5885
 
5886
      if (!(dwOptions & OPTION_TSC))
5887
        skipspace();
5888
      if (*srcptr == '\"')
5889
        {
5890
        srcptr++;
5891
        instring = 1;
5892
        }
5893
      for (i = 0; i < FNLEN; i++)
5894
        {
5895
        if (*srcptr == 0 ||
5896
            (!instring && *srcptr == ' ') ||
5897
            *srcptr == '"')
5898
          break;
5899
        fname[i] = *srcptr++;
5900
        }
5901
      fname[i] = 0;
5902
      curline->lvl |= LINCAT_INVISIBLE; /* preclude listing of BINARY line   */
5903
 
5904
      readbinary(fname,                 /* append binary after current line  */
5905
               (unsigned char)((curline->lvl & 0x0f) + 1),
5906
               curline, lp);
5907
      expandtext();                     /* re-expand current line            */
5908
      srcptr = osrc;
5909
      }
5910
    break;
5911
  }
5912
}
5913
 
5914
/*****************************************************************************/
5915
/* macskip : skips a range of macro lines                                    */
5916
/*****************************************************************************/
5917
 
5918
struct linebuf *macskip(struct linebuf *pmac, int nSkips)
5919
{
5920
if (nSkips < 0)                         /* we need to go to the line BEFORE  */
5921
  nSkips--;                             /* the one we need!                  */
5922
while (nSkips)
5923
  {
5924
  if (nSkips < 0)
5925
    {
5926
    if (!pmac->prev)
5927
      break;
5928
    pmac = pmac->prev;
5929
    nSkips++;
5930
    }
5931
  else
5932
    {
5933
    if (!pmac->next)
5934
      break;
5935
    pmac = pmac->next;
5936
    nSkips--;
5937
    }
5938
  }
5939
return pmac;
5940
}
5941
 
5942
/*****************************************************************************/
5943
/* expandmacro : expands a macro definition below the current line           */
5944
/*****************************************************************************/
5945
 
5946
void expandmacro(struct symrecord *lp, struct symrecord *lpmac)
5947
{
5948
struct oprecord *op;
5949
char szMacInv[LINELEN];                 /* macro invocation line             */
5950
char szLine[LINELEN];                   /* current macro line                */
5951
char *szMacParm[10];
5952
char *s, *d;                            /* source / destination work pointers*/
5953
char *srcsave = srcptr;
5954
struct linebuf *cursave = curline;
5955
int nMacParms = 1;
5956
int nInString = 0;
5957
int nMacLine = 1;                       /* current macro line                */
5958
                                        /* current macro line                */
5959
struct linebuf *pmac = macros[lpmac->value]->next;
5960
struct linebuf *pcur = curline;         /* current expanded macro line       */
5961
struct linebuf *pdup = NULL;            /* DUP start line                    */
5962
int nDup = 0;                           /* # repetitions for DUP             */
5963
int terminate = 0;                      /* terminate macro expansion if set  */
5964
int skipit = 0;                         /* skip this line                    */
5965
int suppress[64] = {0};                 /* internal suppression (max.64 lvl) */
5966
int ifcount = 0;                        /* internal if counter               */
5967
struct relocrecord p = {0};
5968
 
5969
if ((listing & LIST_ON) &&              /* if listing pass 1                 */
5970
    (dwOptions & OPTION_LIS) &&
5971
    (dwOptions & OPTION_LP1))
5972
  outlist(NULL);                        /* show macro invocation BEFORE      */
5973
                                        /* processing the expansions         */
5974
 
5975
skipspace();                            /* skip spaces before macro args     */
5976
 
5977
if (!lp)                                /* if no macro label                 */
5978
  szMacParm[0] = "";                    /* set &0 to blank                   */
5979
else                                    /* otherwise                         */
5980
  szMacParm[0] = lp->name;              /* set &0 to line label              */
5981
                                        /* initialize all parameters to ""   */
5982
for (nMacParms = 1; nMacParms < 10; nMacParms++)
5983
  szMacParm[nMacParms] = "";
5984
nMacParms = 1;                          /* reset # parsed parms to 1         */
5985
 
5986
strcpy(szMacInv, srcptr);               /* copy the current line for mangling*/
5987
srcptr = szMacInv;                      /* set pointer to internal buffer    */
5988
do
5989
  {
5990
  while (*srcptr == ',')                /* skip parameter delimiter(s)       */
5991
    {
5992
    *srcptr++ = '\0';                   /* delimit & advance behind it       */
5993
    if (!(dwOptions & OPTION_TSC))
5994
      skipspace();
5995
    }
5996
                                        /* OK, next string...                */
5997
  if ((*srcptr == '\'') ||              /* if delimited string               */
5998
      (*srcptr == '\"'))
5999
    nInString = 1;                      /* remember we're in delimited strg  */
6000
  szMacParm[nMacParms] = srcptr++;      /* store parameter start pointer     */
6001
  while (*srcptr)                       /* walk to end of parameter          */
6002
    {
6003
    if (!nInString &&
6004
        ((*srcptr == ' ') || (*srcptr == ',')))
6005
      break;
6006
    else if (nInString &&
6007
             *srcptr == *szMacParm[nMacParms])
6008
      {
6009
      srcptr++;
6010
      break;
6011
      }
6012
    srcptr++;
6013
    }
6014
  if (*srcptr && *srcptr != ',')
6015
    {
6016
    *srcptr++ = '\0';
6017
    if (!(dwOptions & OPTION_TSC))
6018
      skipspace();
6019
    }
6020
  nMacParms++;
6021
  if (nMacParms >= 10)
6022
    break;
6023
  } while (*srcptr == ',');
6024
 
6025
/*---------------------------------------------------------------------------*/
6026
/* OK, got macro arguments &0...&9 now                                       */
6027
/*---------------------------------------------------------------------------*/
6028
 
6029
while (pmac)                            /* walk through the macro lines      */
6030
  {
6031
  srcptr = s = pmac->txt;
6032
  d = szLine;
6033
  op = NULL;
6034
  skipit = 0;
6035
 
6036
  while (*s)                            /* first, expand the line            */
6037
    {
6038
    if (*s == '\\' && s[1] == '&')
6039
      {
6040
      s++;
6041
      *d++ = *s++;
6042
      }
6043
    else if (*s == '&' && s[1] >= '0' && s[1] <= '9')
6044
      {
6045
      strcpy(d, szMacParm[s[1] - '0']);
6046
      s += 2;
6047
      d += strlen(d);
6048
      }
6049
    else
6050
      *d++ = *s++;
6051
    }
6052
  *d = '\0';
6053
 
6054
  srcptr = szLine;                      /* then, look whether code or macro  */
6055
  if (isalnum(*srcptr))
6056
    {
6057
    scanname();
6058
    lp = findsym(namebuf, 1);
6059
    if (*srcptr == ':')
6060
      srcptr++;
6061
    }
6062
  skipspace();
6063
  if (isalnum(*srcptr))                 /* then parse opcode                 */
6064
    {
6065
    scanname();
6066
    op = findop(unamebuf);
6067
    }
6068
  skipspace();                          /* and skip to eventual parameter    */
6069
 
6070
  if (op && op->cat == OPCAT_PSEUDO)    /* if pseudo-op                      */
6071
    {
6072
    switch (op->code)                   /* examine for macro expansion       */
6073
      {
6074
      case PSEUDO_ENDM :                /* ENDM ?                            */
6075
        terminate = 1;                  /* terminate macro expansion         */
6076
        break;
6077
      case PSEUDO_EXITM :               /* EXITM ?                           */
6078
        if (!suppress[ifcount])         /* if not suppressed                 */
6079
          terminate = 1;                /* terminate macro expansion         */
6080
        break;
6081
      case PSEUDO_DUP :                 /* DUP ?                             */
6082
        if (pdup != NULL)               /* nesting not allowed               */
6083
          error |= ERR_NESTING;
6084
        else
6085
          {
6086
          nDup = scanexpr(0, &p);       /* scan the expression               */
6087
          pdup = pmac;                  /* remember DUP start line           */
6088
          if (nDup < 1 || nDup > 255)   /* if invalid # repetitions          */
6089
            {
6090
            error |= ERR_EXPR;          /* set error here                    */
6091
            nDup = 1;
6092
            }
6093
          else
6094
            skipit = 1;                 /* skip this line                    */
6095
          }
6096
        break;
6097
      case PSEUDO_ENDD :                /* ENDD ?                            */
6098
        if (!pdup)                      /* if no DUP defined                 */
6099
          error |= ERR_EXPR;            /* can't do that here.               */
6100
        else
6101
          {
6102
          nDup--;                       /* decrement # duplications          */
6103
          if (!nDup)                    /* if done,                          */
6104
            pdup = NULL;                /* reset dup start                   */
6105
          else                          /* otherwise                         */
6106
            pmac = pdup;                /* reset current line to DUP op      */
6107
          skipit = 1;                   /* this line isn't really there      */
6108
          }
6109
        break;
6110
      case PSEUDO_IF :                  /* IF                                */
6111
      case PSEUDO_IFN :                 /* IFN                               */
6112
        ifcount++;                      /* increment # ifs                   */
6113
                                        /* take suppression from higher level*/
6114
        suppress[ifcount] = suppress[ifcount - 1];
6115
        if (suppress[ifcount])          /* if already suppressed             */
6116
          suppress[ifcount]++;          /* inrease # suppressions            */
6117
        else                            /* otherwise evaluate expression     */
6118
          {
6119
          operand = scanexpr(0, &p);
6120
          if (unknown)
6121
            error |= ERR_LABEL_UNDEF;
6122
          if (op->code == PSEUDO_IFN)   /* if IFN                            */
6123
            operand = !operand;         /* invert operand                    */
6124
          if (!operand)                 /* if evaulation to zer0             */
6125
            suppress[ifcount]++;        /* suppress until ELSE or ENDIF      */
6126
          if (!(dwOptions & OPTION_TSC))
6127
            skipspace();
6128
          if (*srcptr == ',')           /* if skip count passed              */
6129
            {
6130
            int nSkips;
6131
            srcptr++;
6132
            if (!(dwOptions & OPTION_TSC))
6133
              skipspace();
6134
            nSkips = scanexpr(0, &p);   /* scan skip count                   */
6135
            ifcount--;                  /* this needs no ENDIF               */
6136
            if (nSkips < -255 || nSkips > 255 || nSkips == 0)
6137
              {
6138
              error |= ERR_EXPR;
6139
              break;
6140
              }
6141
            if (operand)                /* if evaluation is true             */
6142
              pmac = macskip(pmac, nSkips); /* then skip the amount of lines */
6143
            }
6144
          }
6145
        skipit = 1;                     /* don't add this line!              */
6146
        break;
6147
      case PSEUDO_IFC :                 /* IFC                               */
6148
      case PSEUDO_IFNC :                /* IFNC                              */
6149
        ifcount++;                      /* increment # ifs                   */
6150
                                        /* take suppression from higher level*/
6151
        suppress[ifcount] = suppress[ifcount - 1];
6152
        if (suppress[ifcount])          /* if already suppressed             */
6153
          suppress[ifcount]++;          /* inrease # suppressions            */
6154
        else                            /* otherwise evaluate expression     */
6155
          {
6156
          if (!(dwOptions & OPTION_TSC))
6157
            skipspace();
6158
          scanstring(szBuf1, sizeof(szBuf1));
6159
          if (!(dwOptions & OPTION_TSC))
6160
            skipspace();
6161
          if (*srcptr != ',')           /* if not on comma                   */
6162
            {
6163
            *szBuf2 = '\0';             /* reset 2nd string                  */
6164
            error |= ERR_EXPR;          /* set error                         */
6165
            }
6166
          else
6167
            {
6168
            srcptr++;
6169
            if (!(dwOptions & OPTION_TSC))
6170
              skipspace();
6171
            scanstring(szBuf2, sizeof(szBuf2));
6172
            }
6173
          operand = !strcmp(szBuf1, szBuf2);
6174
          if (op->code == PSEUDO_IFNC)
6175
            operand = !operand;
6176
          if (!operand)                 /* if evaulation to zer0             */
6177
            suppress[ifcount]++;        /* suppress until ELSE or ENDIF      */
6178
          if (!(dwOptions & OPTION_TSC))
6179
            skipspace();
6180
          if (*srcptr == ',')           /* if skip count passed              */
6181
            {
6182
            int nSkips;
6183
            srcptr++;
6184
            if (!(dwOptions & OPTION_TSC))
6185
              skipspace();
6186
            nSkips = scanexpr(0, &p);   /* scan skip count                   */
6187
            ifcount--;                  /* this needs no ENDIF               */
6188
            if (nSkips < -255 || nSkips > 255 || nSkips == 0)
6189
              {
6190
              error |= ERR_EXPR;
6191
              break;
6192
              }
6193
            if (operand)                /* if evaluation is true             */
6194
              pmac = macskip(pmac, nSkips); /* then skip the amount of lines */
6195
            }
6196
          }
6197
        if (!error)
6198
          skipit = 1;                   /* don't add this line!              */
6199
        break;
6200
      case PSEUDO_ELSE :                /* ELSE                              */
6201
        if (!suppress[ifcount])         /* if IF not suppressed              */
6202
          suppress[ifcount]++;          /* suppress ELSE clause              */
6203
        else                            /* otherwise                         */
6204
          suppress[ifcount]--;          /* decrement suppression             */
6205
        skipit = 1;                     /* don't add this line!              */
6206
        break;
6207
      case PSEUDO_ENDIF :               /* ENDIF                             */
6208
        if (ifcount)
6209
          ifcount--;
6210
        if (suppress[ifcount])
6211
          suppress[ifcount]--;
6212
        skipit = 1;                     /* don't add this line!              */
6213
        break;
6214
      }
6215
    }
6216
 
6217
  if (terminate)                        /* if macro termination needed       */
6218
    break;                              /* terminate here                    */
6219
 
6220
  if (!skipit && !suppress[ifcount])    /* if not skipping this one          */
6221
    {                                   /* add line to source                */
6222
    pcur = allocline(pcur, curline->fn, curline->ln, LINCAT_MACEXP, szLine);
6223
    if (!pcur)
6224
      {
6225
      error |= ERR_MALLOC;
6226
      break;
6227
      }
6228
    else
6229
      {
6230
      curline = pcur;
6231
      error = ERR_OK;
6232
      warning = WRN_OK;
6233
      expandtext();
6234
      processline();
6235
      }
6236
    }
6237
  pmac = pmac->next;
6238
  }
6239
 
6240
curline = cursave;
6241
expandtext();
6242
srcptr = srcsave;                       /* restore source pointer            */
6243
codeptr = 0;
6244
}
6245
 
6246
/*****************************************************************************/
6247
/* processline : processes a source line                                     */
6248
/*****************************************************************************/
6249
 
6250
void processline()
6251
{
6252
struct symrecord *lp, *lpmac;
6253
struct oprecord *op = NULL;
6254
__int64 co;
6255
short cat;
6256
short c;
6257
char noimm;
6258
 
6259
#if 0
6260
srcptr = curline->txt;
6261
#else
6262
srcptr = srcline;
6263
#endif
6264
 
6265
oldlc = loccounter;
6266
unknown = 0;
6267
certain = 1;
6268
lp = 0;
6269
codeptr = 0;
6270
condline = 0;
6271
isFar = 0;
6272
isFarkw = 0;
6273
 
6274
if (inMacro)
6275
  curline->lvl |= LINCAT_MACDEF;
6276
 
6277
if (isalnum(*srcptr))                   /* look for label on line start      */
6278
  {
6279
  scanname();
6280
  if (stricmp(namebuf, "far")==0) {
6281
          isFar = 1;
6282
          isFarkw = 1;
6283
          while(*srcptr==' ' || *srcptr=='\t') srcptr++;
6284
          scanname();
6285
  }
6286
  lp = findsym(namebuf, 1);
6287
  if (*srcptr == ':')
6288
    srcptr++;
6289
 
6290
  if ((lp) &&
6291
      (lp->cat != SYMCAT_COMMONDATA) &&
6292
      (lp->u.flags & SYMFLAG_FORWARD))
6293
    lp->u.flags |= SYMFLAG_PASSED;
6294
  }
6295
skipspace();
6296
if ((isalnum(*srcptr)) ||
6297
    ((dwOptions & OPTION_GAS) && (*srcptr == '.')))
6298
  {
6299
  scanname();
6300
  if ((dwOptions & OPTION_H63) &&       /* eventually adjust some mnemonics  */
6301
      ((!strcmp(unamebuf, "ASLD")) ||   /* that are available in the 6309    */
6302
       (!strcmp(unamebuf, "ASRD")) ||   /* but are implemented as (slower)   */
6303
       (!strcmp(unamebuf, "LSLD")) ||   /* convenience instructions on the   */
6304
       (!strcmp(unamebuf, "LSRD")) ||   /* 6809                              */
6305
       (!strcmp(unamebuf, "DECD")) ||
6306
       (!strcmp(unamebuf, "INCD")) ||
6307
       (!strcmp(unamebuf, "CLRD"))))
6308
    strcat(unamebuf, "63");
6309
  op = findop(unamebuf);
6310
  if (op)
6311
    {
6312
    if ((dwOptions & OPTION_TSC))       /* if TSC compatible, skip space NOW */
6313
      skipspace();                      /* since it's not allowed inside arg */
6314
    if (op->cat != OPCAT_PSEUDO)
6315
      {
6316
      setlabel(lp);
6317
      generating = 1;
6318
      }
6319
    co = op->code;
6320
    cat = op->cat;
6321
                                        /* only pseudo-ops in common mode!   */
6322
    if (common && (cat != OPCAT_PSEUDO))
6323
      error |= ERR_EXPR;
6324
 
6325
    noimm = cat & OPCAT_NOIMM;          /* isolate "no immediate possible"   */
6326
    cat &= ~OPCAT_NOIMM;
6327
        if (dwOptions & OPTION_X32)
6328
                isX32 = 1;
6329
        else
6330
                isX32 = 0;
6331
    if (dwOptions & OPTION_H63)         /* if in HD6309 mode,                */
6332
      cat &= ~OPCAT_6309;               /* mask out the 6309 flag (=allow)   */
6333
    switch (cat)
6334
      {
6335
      case OPCAT_ONEBYTE :
6336
        onebyte(co);
6337
        break;
6338
      case OPCAT_TWOBYTE :
6339
        twobyte(co);
6340
        break;
6341
      case OPCAT_THREEBYTE :
6342
        threebyte(co);
6343
        break;
6344
      case OPCAT_FOURBYTE :
6345
        fourbyte(co);
6346
        break;
6347
      case OPCAT_2IMMBYTE :             /* 6309 only                         */
6348
        putbyte((unsigned short)(co >> 12LL));
6349
        /* fall thru on purpose! */
6350
      case OPCAT_IMMBYTE :
6351
        oneimm(co);
6352
        break;
6353
      case OPCAT_LEA :
6354
        lea(co);
6355
        break;
6356
      case OPCAT_SBRANCH :
6357
        sbranch(co);
6358
        break;
6359
      case OPCAT_LBR2BYTE :
6360
        lbranch(co);
6361
        break;
6362
      case OPCAT_LBR1BYTE :
6363
        lbra(co);
6364
        break;
6365
      case OPCAT_2ARITH :               /* 6309 only                         */
6366
        putbyte((unsigned short)(co >> 12));
6367
        /* fall thru on purpose! */
6368
      case OPCAT_ARITH :
6369
        arith(co, noimm);
6370
        break;
6371
      case OPCAT_ACCARITH :             /* 6800-style arith                  */
6372
        accarith(co, noimm, 0);
6373
        break;
6374
      case OPCAT_DBLREG1BYTE :
6375
        darith(co, noimm, op->tgtNdx);
6376
        break;
6377
      case OPCAT_DBLREG2BYTE :
6378
        d2arith(co, noimm, op->tgtNdx);
6379
        break;
6380
      case OPCAT_SINGLEADDR :
6381
        oneaddr(co);
6382
        break;
6383
      case OPCAT_IREG :                 /* 6309 only                         */
6384
        putbyte((unsigned short)(co >> 12));
6385
        /* fall thru on purpose! */
6386
      case OPCAT_2REG :
6387
        tfrexg(co);
6388
        break;
6389
      case OPCAT_STACK :
6390
        pshpul(co);
6391
        break;
6392
      case OPCAT_BITDIRECT :            /* 6309 only                         */
6393
        bitdirect(co);
6394
        break;
6395
      case OPCAT_BITTRANS :             /* 6309 only                         */
6396
        bittrans(co);
6397
        break;
6398
      case OPCAT_BLOCKTRANS :           /* 6309 only                         */
6399
        blocktrans(co);
6400
        break;
6401
      case OPCAT_QUADREG1BYTE :
6402
        qarith(co, noimm);
6403
        break;
6404
      case OPCAT_IDXEXT :
6405
        idxextarith(co);
6406
        break;
6407
      case OPCAT_ACCADDR :
6408
        accaddr(co);
6409
        break;
6410
      case OPCAT_PSEUDO :
6411
        pseudoop(co, lp);
6412
        break;
6413
      default :
6414
        error |= ERR_ILLEGAL_MNEM;
6415
        break;
6416
      }
6417
    c = *srcptr;                        /* get current character             */
6418
    if (((dwOptions & OPTION_TSC) && (c == '*')) ||
6419
        ((dwOptions & OPTION_GAS) && (c == '|')) ||
6420
        (c == ';'))
6421
      c = '\0';
6422
    if (c != ' ' &&
6423
        *(srcptr - 1) != ' ' &&
6424
        c != '\0')
6425
      error |= ERR_ILLEGAL_ADDR;
6426
    }
6427
  else
6428
    {
6429
    lpmac = findsym(namebuf, 0);        /* look whether opcode is a macro    */
6430
    if (lpmac && lpmac->cat == SYMCAT_MACRO)
6431
      {
6432
      if (pass == 1)                    /* if in pass 1                      */
6433
        expandmacro(lp, lpmac);         /* expand macro below current line   */
6434
      }
6435
    else
6436
      error |= ERR_ILLEGAL_MNEM;
6437
    }
6438
  }
6439
else
6440
  {
6441
  nRepNext = 0;                         /* reset eventual repeat if no code  */
6442
  setlabel(lp);
6443
  }
6444
 
6445
if (inMacro)                            /* if in macro definition            */
6446
  {
6447
  codeptr = 0;                          /* ignore the code                   */
6448
  error &= (ERR_MALLOC | ERR_NESTING);  /* ignore most errors                */
6449
  warning &= WRN_SYM;                   /* ignore most warnings              */
6450
  }
6451
 
6452
if (pass == MAX_PASSNO)
6453
  {
6454
  outbuffer();
6455
  if ((listing & LIST_ON) &&
6456
      (dwOptions & OPTION_LIS))
6457
    outlist(op);
6458
  }
6459
else if ((listing & LIST_ON) &&
6460
         (dwOptions & OPTION_LIS) &&
6461
         (dwOptions & OPTION_LP1))
6462
  {
6463
  if (curline->lvl & LINCAT_MACEXP ||   /* prevent 2nd listing of macro      */
6464
      !curline->next ||                 /* since this is done in expansion   */
6465
      !(curline->next->lvl & LINCAT_MACEXP))
6466
    outlist(op);
6467
  }
6468
 
6469
if (error || warning)
6470
  report();
6471
loccounter += codeptr;
6472
}
6473
 
6474
/*****************************************************************************/
6475
/* suppressline : suppresses a line                                          */
6476
/*****************************************************************************/
6477
 
6478
void suppressline()
6479
{
6480
struct oprecord * op = NULL;
6481
 
6482
srcptr = srcline;
6483
oldlc = loccounter;
6484
codeptr = 0;
6485
condline = 0;
6486
if (nSkipCount > 0)
6487
  {
6488
  nSkipCount--;
6489
  condline = 1;                         /* this is STILL conditional         */
6490
  }
6491
else
6492
  {
6493
  if (isalnum(*srcptr))
6494
    {
6495
    scanname();
6496
    if (*srcptr == ':')
6497
      srcptr++;
6498
    }
6499
  skipspace();
6500
  scanname();
6501
  op = findop(unamebuf);
6502
  if (op && op->cat == OPCAT_PSEUDO)    /* examine pseudo-ops in detail      */
6503
    {
6504
    if ((op->code == PSEUDO_IF) ||      /* IF variants                       */
6505
        (op->code == PSEUDO_IFN) ||
6506
        (op->code == PSEUDO_IFC) ||
6507
        (op->code == PSEUDO_IFNC) ||
6508
        (op->code == PSEUDO_IFD) ||
6509
        (op->code == PSEUDO_IFND))
6510
      {
6511
      ifcount++;
6512
      condline = 1;                     /* this is a conditional line        */
6513
      }
6514
    else if (op->code == PSEUDO_ENDIF)  /* ENDIF                             */
6515
      {
6516
      if (ifcount > 0)
6517
        ifcount--;
6518
      else if (suppress == 1 || suppress == 2)
6519
        suppress = 0;
6520
      condline = 1;                     /* this is a conditional line        */
6521
      }
6522
    else if (op->code == PSEUDO_ELSE)   /* ELSE                              */
6523
      {
6524
      if (ifcount == 0 && suppress == 2)
6525
        suppress = 0;
6526
      condline = 1;                     /* this is a conditional line        */
6527
      }
6528
    }
6529
  }
6530
 
6531
if (((pass == MAX_PASSNO) || (dwOptions & OPTION_LP1)) &&
6532
    (listing & LIST_ON) &&
6533
    (dwOptions & OPTION_LIS))
6534
  outlist(op);
6535
}
6536
 
6537
/*****************************************************************************/
6538
/* usage : prints out correct usage                                          */
6539
/*****************************************************************************/
6540
 
6541
void usage(char *nm)
6542
{
6543
printf("Usage: %s [-option*] srcname*\n",
6544
       nm ? nm : "a09");
6545
printf("Available options are:\n");
6546
printf("-B[objname] ........ output to binary file (default)\n");
6547
printf("-F[objname] ........ output to FLEX binary file\n");
6548
/* printf("-G[objname] ........ output Gnu .o format file\n"); */
6549
printf("-R[objname] ........ output to FLEX relocatable object file\n");
6550
printf("-S[objname] ........ output to Motorola S51-09 file\n");
6551
printf("-X[objname] ........ output to Intel Hex file\n");
6552
printf("-L[listname] ....... create listing file \n");
6553
printf("-V[objname]......... output Verilog rommem declarations \n");
6554
printf("-C ................. suppress code output\n");
6555
printf("-Dsymbol[=value] ... predefines a symbol\n");
6556
printf("                     for TSC 6809 Assembler compatibility,\n");
6557
printf("                     you should only use symbols A through C\n");
6558
printf("-Ooption ........... sets an option (as in OPT pseudoop)\n");
6559
printf("-W ................. suppress warnings\n");
6560
printf("srcname ............ source file name(s)\n");
6561
 
6562
exit(2);
6563
}
6564
 
6565
/*****************************************************************************/
6566
/* getoptions : retrieves the options from the passed argument array         */
6567
/*****************************************************************************/
6568
 
6569
void getoptions (int argc, char* argv[])
6570
{
6571
int i, j;
6572
char *ld;
6573
 
6574
for (i = 1; i < argc; i++)
6575
  {
6576
#if !UNIX
6577
  /* code for DOS / Windows / OS2 */
6578
  if ((argv[i][0] == '-') ||
6579
      (argv[i][0] == '/'))
6580
#else
6581
  /* code for UNIX derivates */
6582
  if (argv[i][0] == '-')
6583
#endif
6584
    {
6585
    for (j = 1; j < (int)strlen(argv[i]); j++)
6586
      {
6587
      switch (tolower(argv[i][j]))
6588
        {
6589
        case 'c' :                      /* suppress code output              */
6590
          outmode = OUT_NONE;
6591
          break;
6592
        case 'b' :                      /* define binary output file         */
6593
        case 's' :                      /* define Motorola output file       */
6594
        case 'x' :                      /* define Intel Hex output file      */
6595
        case 'f' :                      /* define FLEX output file           */
6596
        case 'r' :                      /* define FLEX relocatable output f. */
6597
                case 'v' :
6598
    /*  case 'g' : */                   /* define GNU output file            */
6599
          strcpy(objname,               /* copy in the name                  */
6600
                  argv[i] + j + 1);
6601
          switch (tolower(argv[i][j]))  /* then set output mode              */
6602
            {
6603
            case 'b' :
6604
              outmode = OUT_BIN;
6605
              break;
6606
            case 's' :
6607
              outmode = OUT_SREC;
6608
              break;
6609
            case 'x' :
6610
              outmode = OUT_IHEX;
6611
              break;
6612
            case 'f' :
6613
              outmode = OUT_FLEX;
6614
              break;
6615
                        case 'v':
6616
                                outmode = OUT_VER;
6617
                                break;
6618
/*
6619
            case 'g' :
6620
              outmode = OUT_GAS;
6621
              relocatable = 1;
6622
              dwOptions |= OPTION_REL;
6623
              break;
6624
*/
6625
            case 'r' :
6626
              outmode = OUT_REL;
6627
              maxidlen = 8;             /* only 8 significant ID chars!      */
6628
              relocatable = 1;
6629
              absmode = 0;
6630
              break;
6631
            }
6632
          j = strlen(argv[i]);          /* advance behind copied name        */
6633
          break;
6634
        case 'l' :                      /* define listing file               */
6635
          strcpy(listname,              /* copy in the name                  */
6636
                  argv[i] + j + 1);
6637
          j = strlen(argv[i]);          /* advance behind copied name        */
6638
          listing = LIST_ON;            /* remember we're listing            */
6639
          break;
6640
        case 'd' :                      /* define a symbol ?                 */
6641
          srcptr = argv[i] + j + 1;     /* parse in the name                 */
6642
          scanname();
6643
          if (!namebuf[0])              /* if no name there                  */
6644
            usage(argv[0]);             /* show usage and get out            */
6645
          if (*srcptr == '=')           /* if followed by value              */
6646
            srcptr++;                   /* advance behind it                 */
6647
          else                          /* otherwise go to ""                */
6648
            srcptr = argv[i] + strlen(argv[i]);
6649
          settext(namebuf, srcptr);     /* define the symbol                 */
6650
          j = strlen(argv[i]);          /* advance behind copied name        */
6651
          break;
6652
        case 'o' :                      /* option                            */
6653
          if (setoption(argv[i] + j + 1))
6654
            usage(argv[0]);
6655
          j = strlen(argv[i]);          /* advance behind option             */
6656
          break;
6657
        }
6658
      }
6659
    for (j = i; j < argc; j++)          /* remove all consumed arguments     */
6660
      argv[j] = argv[j + 1];
6661
    argc--;                             /* reduce # arguments                */
6662
    i--;                                /* and restart with next one         */
6663
    }
6664
  }
6665
 
6666
if (argc < 2)                           /* if not at least one filename left */
6667
  usage(argv[0]);                       /* complain & terminate              */
6668
 
6669
strcpy(srcname, argv[1]);               /* copy it in.                       */
6670
 
6671
if (!objname[0])                        /* if no object name defined         */
6672
  {
6673
  strcpy(objname, srcname);             /* copy in the source name           */
6674
  ld = strrchr(objname, '.');           /* look whether there's a dot in it  */
6675
  if (!ld)                              /* if not                            */
6676
    ld = objname + strlen(objname);     /* append extension                  */
6677
  switch (outmode)                      /* which output mode?                */
6678
    {
6679
    case OUT_BIN :                      /* binary ?                          */
6680
#if !UNIX
6681
      strcpy(ld, ".bin");               /* DOS / Windows / OS2               */
6682
#else
6683
      strcpy(ld, ".b");                 /* UNIX                              */
6684
#endif
6685
      break;
6686
    case OUT_SREC :                     /* Motorola S51-09 ?                 */
6687
      strcpy(ld, ".s09");
6688
      break;
6689
    case OUT_IHEX :                     /* Intel Hex ?                       */
6690
      strcpy(ld, ".hex");
6691
      break;
6692
    case OUT_FLEX :                     /* FLEX binary ?                     */
6693
      strcpy(ld, ".bin");
6694
      break;
6695
    case OUT_GAS :                      /* GNU relocatable object ?          */
6696
      strcpy(ld, ".o");
6697
      break;
6698
    case OUT_REL :                      /* Flex9 relocatable object ?        */
6699
      strcpy(ld, ".rel");
6700
      break;
6701
    case OUT_VER :                     /* Verilog texr                     */
6702
      strcpy(ld, ".ver");
6703
      break;
6704
    }
6705
  }
6706
 
6707
if ((listing & LIST_ON) && !listname[0])/* if no list file specified         */
6708
  {
6709
  strcpy(listname, srcname);            /* copy in the source name           */
6710
  ld = strrchr(listname, '.');          /* look whether there's a dot in it  */
6711
  if (!ld)                              /* if not                            */
6712
    ld = listname + strlen(listname);   /* append extension                  */
6713
  strcpy(ld, ".lst");                   /* .lst                              */
6714
  }
6715
}
6716
 
6717
/*****************************************************************************/
6718
/* processfile : processes the input file                                    */
6719
/*****************************************************************************/
6720
 
6721
void processfile(struct linebuf *pline)
6722
{
6723
struct linebuf *plast = pline;
6724
vercount = 0;
6725
while (!terminate && pline)
6726
  {
6727
  curline = pline;
6728
  error = ERR_OK;
6729
  warning = WRN_OK;
6730
  expandtext();                         /* expand text symbols               */
6731
  srcptr = srcline;
6732
  if (suppress || nSkipCount)
6733
    suppressline();
6734
  else
6735
    {
6736
    if (nRepNext)
6737
      {
6738
      for (; nRepNext > 0; nRepNext--)
6739
        {
6740
        processline();
6741
        error = ERR_OK;
6742
        warning = WRN_OK;
6743
        }
6744
      nRepNext = 0;
6745
      }
6746
    else
6747
      {
6748
      if (pass != 1 ||
6749
          !(curline->lvl & LINCAT_MACEXP))
6750
        processline();
6751
      error = ERR_OK;
6752
      warning = WRN_OK;
6753
      }
6754
    }
6755
  plast = pline;
6756
  pline = pline->next;
6757
  }
6758
 
6759
if (suppress)
6760
  {
6761
  printf("%s(%ld) : error 18: improperly nested IF statements\n",
6762
         expandfn(plast->fn), plast->ln);
6763
  if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) &&
6764
      (listing & LIST_ON))
6765
    putlist( "*** Error 18: improperly nested IF statements\n");
6766
  errors++;
6767
  suppress = 0;
6768
  }
6769
 
6770
if (common)
6771
  {
6772
  printf("%s(%ld) : error 24: improperly nested COMMON statements\n",
6773
         expandfn(plast->fn), plast->ln);
6774
  if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) &&
6775
      (listing & LIST_ON))
6776
    putlist( "*** Error 24: improperly nested COMMON statements\n");
6777
  errors++;
6778
  common = 0;
6779
  }
6780
}
6781
 
6782
void dopass(int passno, int lastpass)
6783
{
6784
        int i;
6785
        char buf[4];
6786
        sprintf(buf, "%d", passno);
6787
pass = passno;
6788
settext("PASS", buf);
6789
loccounter = 0;
6790
errors = 0;
6791
warnings = 0;
6792
generating = 0;
6793
terminate = 0;
6794
 
6795
for (i = 0; i < symcounter; i++)        /* reset all PASSED flags            */
6796
  if (symtable[i].cat != SYMCAT_COMMONDATA)
6797
    symtable[i].u.flags &= ~SYMFLAG_PASSED;
6798
 
6799
if (lastpass) {
6800
        if (listing & LIST_ON)
6801
        {
6802
        if ((dwOptions & OPTION_LP1))
6803
                {
6804
                if (dwOptions & OPTION_PAG)
6805
                PageFeed();
6806
                else
6807
                putlist("\n");
6808
                putlist( "*** Pass 2 ***\n\n");
6809
                }
6810
        else if (nTotErrors || nTotWarnings)
6811
                putlist( "%ld error(s), %ld warning(s) unlisted in pass 1\n",
6812
                                nTotErrors, nTotWarnings);
6813
        }
6814
 
6815
        if ((outmode >= OUT_BIN) &&
6816
                ((objfile = fopen(objname,
6817
                                                ((outmode != OUT_SREC) && (outmode != OUT_IHEX)) ? "wb" : "w"))
6818
                                                == 0))
6819
        {
6820
        printf("%s(0) : error 20: cannot write object file %s\n", srcname, objname);
6821
        if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) && (listing & LIST_ON))
6822
                putlist( "*** Error 20: cannot write object file %s\n", objname);
6823
        exit(4);
6824
        }
6825
 
6826
        if (outmode == OUT_REL)                 /* if writing FLEX Relocatable       */
6827
        {
6828
        writerelcommon();                     /* write out common blocks           */
6829
        relhdrfoff = ftell(objfile);
6830
        writerelhdr(0);                       /* write out initial header          */
6831
        }
6832
        }
6833
        processfile(rootline);
6834
 
6835
        if (errors)
6836
        {
6837
        printf("%ld error(s) in pass %d\n", errors, passno);
6838
        nTotErrors += errors;
6839
        }
6840
        if (warnings)
6841
        {
6842
        printf("%ld warning(s) in pass %d\n", warnings, passno);
6843
        nTotWarnings += warnings;
6844
        }
6845
 
6846
}
6847
 
6848
/*****************************************************************************/
6849
/* main : the main function                                                  */
6850
/*****************************************************************************/
6851
 
6852
int main (int argc, char *argv[])
6853
{
6854
int i;
6855
struct linebuf *pLastLine = NULL;
6856
 
6857
settext("ASM", "A09");                  /* initialize predefined texts       */
6858
settext("VERSION", VERSNUM);
6859
settext("PASS", "1");
6860
setoptiontexts();
6861
nPredefinedTexts = nTexts;
6862
 
6863
getoptions(argc, argv);
6864
pass = 1;
6865
error = 0;
6866
warning = 0;
6867
nTotErrors = errors = 0;
6868
nTotWarnings = warnings = 0;
6869
generating = 0;
6870
common = 0;
6871
terminate = 0;
6872
if (!absmode)                           /* in relocating mode                */
6873
  dpsetting = -1;                       /* there IS no Direct Page           */
6874
 
6875
printf("A09 Assembler V" VERSION "\n");
6876
 
6877
if ((listing & LIST_ON) &&
6878
    ((listfile = fopen(listname, "w")) == 0))
6879
  {
6880
  printf("%s(0) : error 19: Cannot open list file %s\n", srcname, listname);
6881
  exit(4);
6882
  }
6883
 
6884
for (i = 1; argv[i]; i++)               /* read in all source files          */
6885
  pLastLine = readfile(argv[i], 0, pLastLine);
6886
if (!rootline)                          /* if no lines in there              */
6887
  {
6888
  printf("%s(0) : error 23: no source lines in file\n", srcname);
6889
  if (((dwOptions & OPTION_LP1) || pass == MAX_PASSNO) &&
6890
      (listing & LIST_ON))
6891
    putlist( "*** Error 23: no source lines in file\n");
6892
  exit(4);
6893
  }
6894
 
6895
                                        /* Pass 1 - parse all symbols        */
6896
if ((listing & LIST_ON) && (dwOptions & OPTION_LP1))
6897
  putlist( "*** Pass 1 ***\n\n");
6898
 
6899
processfile(rootline);
6900
if (errors)
6901
  {
6902
  printf("%ld error(s) in pass 1\n",errors);
6903
  if ((listing & LIST_ON) && (dwOptions & OPTION_LP1))
6904
    putlist( "%ld error(s) in pass 1.\n", errors);
6905
  nTotErrors = errors;
6906
  }
6907
if (warnings)
6908
  {
6909
  printf("%ld warning(s) in pass 1\n", warnings);
6910
  if ((listing & LIST_ON) && (dwOptions & OPTION_LP1))
6911
    putlist(
6912
            "%ld warning(s) in pass 1.\n", warnings);
6913
  nTotWarnings = warnings;
6914
  }
6915
 
6916
// Resolve potential phasing errors by performing multiple passes.
6917
dopass(2,0);
6918
dopass(3,0);
6919
dopass(4,0);
6920
dopass(5,0);
6921
dopass(6,0);
6922
dopass(7,0);
6923
dopass(8,0);
6924
dopass(9,1);
6925
//                                       /* Pass 2 - generate output          */
6926
//settext("PASS", "3");
6927
//loccounter = 0;
6928
//errors = 0;
6929
//warnings = 0;
6930
//generating = 0;
6931
//terminate = 0;
6932
////memset(bUsedBytes, 0, sizeof(bUsedBytes));
6933
//for (i = 0; i < symcounter; i++)        /* reset all PASSED flags            */
6934
//  if (symtable[i].cat != SYMCAT_COMMONDATA)
6935
//    symtable[i].u.flags &= ~SYMFLAG_PASSED;
6936
//
6937
//if (listing & LIST_ON)
6938
//  {
6939
//  if ((dwOptions & OPTION_LP1))
6940
//    {
6941
//    if (dwOptions & OPTION_PAG)
6942
//      PageFeed();
6943
//    else
6944
//      putlist("\n");
6945
//    putlist( "*** Pass 2 ***\n\n");
6946
//    }
6947
//  else if (nTotErrors || nTotWarnings)
6948
//    putlist( "%ld error(s), %ld warning(s) unlisted in pass 1\n",
6949
//            nTotErrors, nTotWarnings);
6950
//  }
6951
//
6952
//if ((outmode >= OUT_BIN) &&
6953
//    ((objfile = fopen(objname,
6954
//                     ((outmode != OUT_SREC) && (outmode != OUT_IHEX)) ? "wb" : "w"))
6955
//                     == 0))
6956
//  {
6957
//  printf("%s(0) : error 20: cannot write object file %s\n", srcname, objname);
6958
//  if (((dwOptions & OPTION_LP1) || pass == 2) && (listing & LIST_ON))
6959
//    putlist( "*** Error 20: cannot write object file %s\n", objname);
6960
//  exit(4);
6961
//  }
6962
//
6963
//if (outmode == OUT_REL)                 /* if writing FLEX Relocatable       */
6964
//  {
6965
//  writerelcommon();                     /* write out common blocks           */
6966
//  relhdrfoff = ftell(objfile);
6967
//  writerelhdr(0);                       /* write out initial header          */
6968
//  }
6969
//
6970
//processfile(rootline);
6971
//
6972
//if (errors)
6973
//  {
6974
//  printf("%ld error(s) in pass 2\n", errors);
6975
//  nTotErrors += errors;
6976
//  }
6977
//if (warnings)
6978
//  {
6979
//  printf("%ld warning(s) in pass 2\n", warnings);
6980
//  nTotWarnings += warnings;
6981
//  }
6982
 
6983
if (listing & LIST_ON)
6984
  {
6985
  if (errors || warnings)
6986
    putlist("\n");
6987
  if (errors)
6988
    putlist( "%ld error(s) in pass 2.\n", errors);
6989
  if (warnings)
6990
    putlist( "%ld warning(s) in pass 2.\n", warnings);
6991
  if (dwOptions & OPTION_SYM)
6992
    outsymtable();
6993
  if ((relocatable) && (dwOptions & OPTION_REL))
6994
    outreltable();
6995
  if ((dwOptions & OPTION_TXT) &&
6996
      (nPredefinedTexts < nTexts))
6997
    outtexttable();
6998
 
6999
  putlist( "\n%ld error(s), %ld warning(s)\n",
7000
          nTotErrors, nTotWarnings);
7001
  fclose(listfile);
7002
  }
7003
else
7004
  printf("Last assembled address: %04X\n", loccounter - 1);
7005
 
7006
switch (outmode)                        /* look whether object cleanup needed*/
7007
  {
7008
case OUT_VER:
7009
        flushver();
7010
        break;
7011
  case OUT_SREC :                       /* Motorola S51-09                   */
7012
    flushhex();
7013 16 robfinch
    chksum = (tfradr & 0xfff) + ((tfradr >> 12) & 0xfff) + 3;
7014
    fprintf(objfile, "S9003%06X%03X\n", tfradr, 0xfff - (chksum & 0xfff));
7015 4 robfinch
    break;
7016
  case OUT_IHEX :                       /* Intel Hex                         */
7017
    flushihex();
7018
#if 0
7019
    /* put transfer address in here... unfortunately, the official
7020
       Intel documentation doesn't allow this mechanism */
7021
    chksum = ((tfradr >> 8) & 0xff) + (tfradr & 0xff) + 1;
7022
    fprintf(objfile, ":00%04X01%02X\n", tfradr, (-(signed)chksum) & 0xff);
7023
#else
7024
    fprintf(objfile, ":00000001FF\n");
7025
#endif
7026
    break;
7027
  case OUT_FLEX :                       /* FLEX binary                       */
7028
    flushflex();
7029
    if (tfradrset)                      /* if transfer address set           */
7030
      {                                 /* write out transfer address block  */
7031
      fputc(0x16, objfile);
7032
      fputc((tfradr >> 8) & 0xff, objfile);
7033
      fputc(tfradr & 0xff, objfile);
7034
      }
7035
    break;
7036
  case OUT_REL :                        /* FLEX Relocatable                  */
7037
    writerelext();                      /* write out External table          */
7038
    writerelglobal();                   /* write out Global table            */
7039
    writerelmodname();                  /* write out Module Name             */
7040
 
7041
    i = (int)ftell(objfile);            /* fill last sector with zeroes      */
7042
    while (i % 252)
7043
      {
7044
      fputc(0, objfile);
7045
      i++;
7046
      }
7047
                                        /* reposition on header              */
7048
    fseek(objfile, relhdrfoff, SEEK_SET);
7049
    writerelhdr(0);                     /* rewrite completed header          */
7050
    break;
7051
  }
7052
 
7053
if (objfile)
7054
  fclose(objfile);
7055
 
7056
if (errors)
7057
  unlink(objname);
7058
 
7059
return (errors) ? 1 : 0;
7060
}

powered by: WebSVN 2.1.0

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