1 %{
2 /* Clang doesn't like the unreachable code in Bison's generated output. */
3 #ifdef __clang__
4 #pragma clang diagnostic ignored "-Wunreachable-code"
5 #endif
6
7 #if 0
8 # define YYDEBUG 1
9 # define YYERROR_VERBOSE 1
10 # define YYTOKEN_TABLE 1
11 int yydebug = 1;
12 #endif
13
14 /* NOTICE: This code is based on the Public Domain AS2650.Y that comes
15 * with the Frankenstein Assembler, by Mark Zenier. The changes
16 * that I, Joseph Zbiciak, have made are being placed under GPL.
17 * See GPL notice immediately below.
18 */
19
20 /* ======================================================================== */
21 /* This program is free software; you can redistribute it and/or modify */
22 /* it under the terms of the GNU General Public License as published by */
23 /* the Free Software Foundation; either version 2 of the License, or */
24 /* (at your option) any later version. */
25 /* */
26 /* This program is distributed in the hope that it will be useful, */
27 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
28 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
29 /* General Public License for more details. */
30 /* */
31 /* You should have received a copy of the GNU General Public License along */
32 /* with this program; if not, write to the Free Software Foundation, Inc., */
33 /* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
34 /* ======================================================================== */
35 /* Copyright (c) 1998-1999, Joseph Zbiciak */
36 /* ======================================================================== */
37
38
39 /*
40 HEADER: ;
41 TITLE: Frankenstein Cross Assemblers;
42 VERSION: 2.0;
43 DESCRIPTION: " Reconfigurable Cross-assembler producing Intel (TM)
44 Hex format object records. ";
45 KEYWORDS: cross-assemblers, 1600, 1805, 2650, 6301, 6502, 6805, 6809,
46 6811, tms7000, 8048, 8051, 8096, z8, z80;
47 SYSTEM: UNIX, MS-Dos ;
48 FILENAME: as1600.y;
49 WARNINGS: "This software is in the public domain.
50 Any prior copyright claims are relinquished.
51
52 This software is distributed with no warranty whatever.
53 The author takes no responsibility for the consequences
54 of its use.
55
56 Yacc (or Bison) required to compile." ;
57 SEE-ALSO: as1600.ps, frasmain.c;
58 AUTHORS: Mark Zenier; Joe Zbiciak
59 COMPILERS: GCC
60 */
61
62 /* 1600 instruction generation file, GI standard syntax */
63 /* September 25, 1999 */
64
65 /*
66 description frame work parser description for framework cross assemblers
67 history February 2, 1988
68 September 11, 1990 - merge table definition
69 September 12, 1990 - short file names
70 September 14, 1990 - short variable names
71 September 17, 1990 - use yylex as external
72 */
73
74 /* ======================================================================== *\
75
76 The CP-1610 supports the following basic opcode formats:
77
78 --------------------------------------- ------- --------------------------
79 Format Words Description
80 --------------------------------------- ------- --------------------------
81 0000 000 0oo 1 Implied 1-op insns
82 0000 000 100 bbppppppii pppppppppp 3 Jump insns
83 0000 000 1oo 1 Implied 1-op insns
84 0000 ooo ddd 1 1-op insns, comb src/dst
85 0000 110 0dd 1 GSWD
86 0000 110 1om 1 NOP(2), SIN(2)
87 0001 ooo mrr 1 Rotate/Shift insns
88 0ooo sss ddd 1 2-op arith, reg->reg
89 1000 zxc ccc pppppppppp 2 Branch insns
90 1ooo 000 ddd pppppppppp 2 2-op arith, direct, reg
91 1ooo mmm ddd 1* 2-op arith, ind., reg
92 1ooo 111 ddd iiiiiiiiii 2* 2-op arith, immed., reg
93 --------------------------------------- ------- --------------------------
94
95
96 -----
97 Key
98 -----
99
100 oo -- Opcode field (dependent on format)
101 sss -- Source register, R0 ... R7 (binary encoding)
102 ddd -- Destination register, R0 ... R7 (binary encoding)
103 0dd -- Destination register, R0 ... R3
104 cccc -- Condition codes (branches)
105 x -- External branch condition (0 == internal, 1 == examine BEXT)
106 z -- Branch displacement direction (1 == negative)
107 m -- Shift amount (0 == shift by 1, 1 == shift by 2)
108 bb -- Branch return register
109 ii -- Branch interrupt flag mode
110
111 --------------------------------
112 Branch Condition Codes (cccc)
113 --------------------------------
114 n == 0 n == 1
115 n000 -- Always Never
116 n001 -- Carry set/Greater than Carry clear/Less than or equal
117 n010 -- Overflow set Overflow clear
118 n011 -- Positive Negative
119 n100 -- Equal Not equal
120 n101 -- Less than Greater than or equal
121 n110 -- Less than or equal Greater than
122 n111 -- Unequal sign and carry Equal sign and carry
123
124
125 -------------------------------
126 Branch Return Registers (bb)
127 -------------------------------
128
129 00 -- R4
130 01 -- R5
131 10 -- R6
132 11 -- none (do not save return address)
133
134 -------------------------------
135 Branch Interrupt Modes (ii)
136 -------------------------------
137
138 00 -- Do not change interrupt enable state
139 01 -- Enable interrupts
140 10 -- Disable interrupts
141 11 -- Undefined/Reserved ?
142
143 ------------
144 SDBD notes
145 ------------
146
147 -- SDBD is supported on "immediate" and "indirect" modes only.
148
149 -- An SDBD prefix on an immediate instruction sets the immediate constant
150 to be 16 bits, stored in two adjacent 8-bit words. The ordering is
151 little-endian.
152
153 -- An SDBD prefix on an indirect instruction causes memory to be
154 accessed twice, bringing in (or out) two 8-bit words, again in
155 little-endian order. If a non-incrementing data counter is used,
156 both accesses are to the same address. Otherwise, the counter
157 is post-incremented with each access. Indirect through R6
158 (stack addressing) is not allowed, although I suspect it works
159 as expected (performing two accesses through R6).
160
161 ------------------------
162 General encoding notes
163 ------------------------
164
165 -- "Immediate" mode is encoded the same as "Indirect" mode, except that
166 R7 is given as the indirect register. I'm guessing R7 is implemented
167 the same as R4 and R5, especially since MVOI does what you'd
168 expect -- it (attempts to) write over its immediate operand!!!
169
170 -- The PC value (in R7) used for arithmetic always points to the first
171 byte after the instruction for purposes of arithmetic. This is
172 consistent with the observation that immediate mode is really
173 indirect mode in disguise, with the instruction being only one word
174 long initially.
175
176 -- Several instructions are just special cases of other instructions,
177 and therefore do not need special decoder treatment:
178
179 -- TSTR Rx --> MOVR Rx, Rx
180 -- JR Rx --> MOVR Rx, R7
181 -- CLRR Rx --> XORR Rx, Rx
182 -- B --> Branch with condition code 0000 ("Always")
183 -- NOPP --> Branch with condition code 1000 ("Never")
184 -- PSHR Rx --> MVO@ Rx, R6
185 -- PULR Rx --> MVI@ R6, Rx
186
187 -- "Direct" mode is encoded the same as "Indirect" mode, except 000
188 (which corresponds to R0) is encoded in the indirect register field.
189 This is why R0 cannot be used as a data counter, and why it has no
190 "special use."
191
192 -- Relative branches encode their sign bit in the opcode word, rather
193 than relying on a sign-extended relative offset in their second word.
194 This allows +/- 10-bit range in a 10-bit wide memory, or +/-
195 16-bit range in a 16-bit memory. To avoid redundant encoding, the
196 offset is calculated slightly differently for negative vs. positive
197 offset:
198
199 -- Negative: address_of_branch + 1 - offset
200 -- Positive: address_of_branch + 2 + offset
201
202 I'm guessing it is implemented about like so in hardware:
203
204 -- offset == pc + (offset ^ (sign ? -1 : 0))
205
206 ---------------
207 Opcode Spaces
208 ---------------
209
210 I've divided the CP-1610 opcode map into 12 different opcode
211 spaces. (I really should merge the two separate Implied 1-op
212 spaces into one space. Oh well...) In the descriptions below,
213 "n/i" means "not interruptible". Defined flags: Sign, Zero, Carry,
214 Overflow, Interrupt-enable, Double-byte-data. Interrupt-enable and
215 Double-byte-data are not user visible.
216
217 -- Implied 1-op instructions, part A: 0000 000 0oo
218 Each has a single, implied operand, if any.
219
220 opcode mnemonic n/i SZCOID description
221 -- 00 HLT Halts the CPU (until next interrupt?)
222 -- 01 SDBD * 1 Set Double Byte Data
223 -- 10 EIS * 1 Enable Interrupt System
224 -- 11 DIS * 1 Disable Interrupt System
225
226 -- Implied 1-op instructions, part B: 0000 000 1oo
227 Each has a single, implied operand, if any.
228
229 opcode mnemonic n/i SZCOID description
230 -- 00 n/a Aliases the "Jump" opcode space
231 -- 01 TCI * Terminate Current Interrupt.
232 -- 10 CLRC * Clear carry flag
233 -- 11 SETC * Set carry flag
234
235 -- Jump Instructions: 0000 000 100 bbppppppii pppppppppp
236 Unconditional jumps with optional return-address save and
237 interrupt enable/disable.
238
239 bb ii mnemonic n/i SZCOID description
240 -- 11 00 J Jump.
241 -- xx 00 JSR Jump. Save return address in R4..R6
242 -- 11 01 JE 1 Jump and enable ints.
243 -- xx 01 JSRE 1 Jump and enable ints. Save ret addr.
244 -- 11 10 JD 0 Jump and disable ints
245 -- xx 10 JSRD 0 Jump and disable ints. Save ret addr.
246 -- xx 11 n/a Invalid opcode.
247
248 -- Register 1-op instructions 0000 ooo rrr
249 Each has one register operand, encoded as 000 through 111.
250
251 opcode mnemonic n/i SZCOID description
252 -- 000 n/a Aliases "Implied", "Jump" opcode space
253 -- 001 INCR XX INCrement register
254 -- 010 DECR XX DECrement register
255 -- 011 COMR XX COMplement register (1s complement)
256 -- 100 NEGR XXXX NEGate register (2s complement)
257 -- 101 ADCR XXXX ADd Carry to Register
258 -- 110 n/a Aliases "GSWD", "NOP/SIN" opcode space
259 -- 111 RSWD XXXX Restore Status Word from Register
260
261
262 -- Get Status WorD 0000 110 0rr
263 This was given its own opcode space due to limited encoding on its
264 destination register and complication with the NOP/SIN encodings.
265
266 -- NOP/SIN 0000 110 1om
267 I don't know what the "m" bit is for. I don't know what to do with SIN.
268
269 opcode mnemonic n/i SZCOID description
270 -- 0 NOP No operation
271 -- 1 SIN Software Interrupt (pulse PCIT pin) ?
272
273 -- Shift/Rotate 1-op instructions 0001 ooo mrr
274 These can operate only on R0...R3. The "m" bit specifies whether the
275 operation is performed once or twice. The overflow bit is used for
276 catching the second bit on the rotates/shifts that use the carry.
277
278 opcode mnemonic n/i SZCOID description
279 -- 000 SWAP * XX Swaps bytes in word once or twice.
280 -- 001 SLL * XX Shift Logical Left
281 -- 010 RLC * XXX2 Rotate Left through Carry/overflow
282 -- 011 SLLC * XXX2 Shift Logical Left thru Carry/overflow
283 -- 100 SLR * XX Shift Logical Right
284 -- 101 SAR * XX Shift Arithmetic Right
285 -- 110 RRC * XXX2 Rotate Left through Carry/overflow
286 -- 111 SARC * XXX2 Shift Arithmetic Right thru Carry/over
287
288 -- Register/Register 2-op instructions 0ooo sss ddd
289 Register to register arithmetic. Second operand acts as src2 and dest.
290
291 opcode mnemonic n/i SZCOID description
292 -- 00x n/a Aliases other opcode spaces
293 -- 010 MOVR XX Move register to register
294 -- 011 ADDR XXXX Add src1 to src2->dst
295 -- 100 SUBR XXXX Sub src1 from src2->dst
296 -- 101 CMPR XXXX Sub src1 from src2, don't store
297 -- 110 ANDR XX AND src1 with src2->dst
298 -- 111 XORR XX XOR src1 with src2->dst
299
300 -- Conditional Branch instructions 1000 zxn ccc pppppppppppppppp
301 The "z" bit specifies the direction for the offset. The "x" bit
302 specifies using an external branch condition instead of using flag
303 bits. Conditional brances are interruptible. The "n" bit specifies
304 branching on the opposite condition from 'ccc'.
305
306 cond n=0 Condition n=1 Condition
307 -- n000 B always NOPP never
308 -- n001 BC C = 1 BNC C = 0
309 -- n010 BOV O = 1 BNOV O = 0
310 -- n011 BPL S = 0 BMI S = 1
311 -- n100 BZE/BEQ Z = 1 BNZE/BNEQ Z = 0
312 -- n101 BLT/BNGE S^O = 1 BGE/BNLT S^O = 0
313 -- n110 BLE/BNGT Z|(S^O) = 1 BGT/BNLE Z|(S^O) = 0
314 -- n111 BUSC S^C = 1 BESC S^C = 0
315
316 -- Direct/Register 2-op instructions 1ooo 000 rrr pppppppppppppppp
317 Direct memory to register arithmetic. MVO uses direct address as
318 a destination, all other operations use it as a source, with
319 the register as the destination.
320
321 opcode mnemonic n/i SZCOID description
322 -- 000 n/a Aliases conditional branch opcodes
323 -- 001 MVO * Move register to direct address
324 -- 010 MVI Move direct address to register
325 -- 011 ADD XXXX Add src1 to src2->dst
326 -- 100 SUB XXXX Sub src1 from src2->dst
327 -- 101 CMP XXXX Sub src1 from src2, don't store
328 -- 110 AND XX AND src1 with src2->dst
329 -- 111 XOR XX XOR src1 with src2->dst
330
331
332 -- Indirect/Register 2-op instructions 1ooo sss ddd
333 A source of "000" is actually a Direct/Register opcode.
334 A source of "111" is actually a Immediate/Register opcode.
335 R4, R5 increment after each access. If the D bit is set, two
336 accesses are made through the indirect register, updating the
337 address if R4 or R5. R6 increments after writes, decrements
338 before reads.
339
340 opcode mnemonic n/i SZCOID description
341 -- 000 n/a Aliases conditional branch opcodes
342 -- 001 MVO@ * Move register to indirect address
343 -- 010 MVI@ Move indirect address to register
344 -- 011 ADD@ XXXX Add src1 to src2->dst
345 -- 100 SUB@ XXXX Sub src1 from src2->dst
346 -- 101 CMP@ XXXX Sub src1 from src2, don't store
347 -- 110 AND@ XX AND src1 with src2->dst
348 -- 111 XOR@ XX XOR src1 with src2->dst
349
350 -- Immediate/Register 2-op instructions 1ooo 111 ddd pppp
351 If DBD is set, the immediate value spans two adjacent bytes, little
352 endian order. Otherwise the immediate value spans one word. This
353 instruction really looks like indirect through R7, and I suspect
354 that's how the silicon implements it.
355
356 opcode mnemonic n/i SZCOID description
357 -- 000 n/a Aliases conditional branch opcodes
358 -- 001 MVOI * Move register to immediate field!
359 -- 010 MVII Move immediate field to register
360 -- 011 ADDI XXXX Add src1 to src2->dst
361 -- 100 SUBI XXXX Sub src1 from src2->dst
362 -- 101 CMPI XXXX Sub src1 from src2, don't store
363 -- 110 ANDI XX AND src1 with src2->dst
364 -- 111 XORI XX XOR src1 with src2->dst
365
366 \* ======================================================================== */
367
368 #include <stdio.h>
369 #include <string.h>
370 #include "config.h"
371 #include "as1600_types.h"
372 #include "intermed.h"
373 #include "lzoe/lzoe.h"
374 #include "file/file.h"
375 #include "asm/frasmdat.h"
376 #include "asm/fragcon.h"
377 #include "asm/intvec.h"
378 #include "asm/protos.h"
379 #include "asm/as1600.tab.h"
380 #include "asm/memo_string.h"
381
382 #define yylex lexintercept
383
384 #define JSR_RG 0x0001
385 #define SHF_RG 0x0002
386 #define IND_RG 0x0004
387 #define SDBD 0x0008
388
389 #define ST_REGREG 0x0001
390 #define ST_REGEXP 0x0002
391 #define ST_EXPREG 0x0004
392 #define ST_REGCEX 0x0008
393 #define ST_CEXREG 0x0010
394 #define ST_REG 0x0020
395 #define ST_EXP 0x0040
396 #define ST_IMP 0x0080
397 #define ST_EXPEXP 0x0100
398
399 /* ======================================================================== */
400 /* R0 .. R7 can be used as general-purpose registers. */
401 /* R0 .. R3 can be used for shifts and GSWD. */
402 /* R1 .. R6 can be used for indirect addressing. */
403 /* R4 .. R6 can be used for JSR. */
404 /* ======================================================================== */
405 static int reg_type[8] =
406 {
407 SHF_RG,
408 SHF_RG | IND_RG,
409 SHF_RG | IND_RG,
410 SHF_RG | IND_RG,
411 JSR_RG | IND_RG,
412 JSR_RG | IND_RG,
413 JSR_RG | IND_RG,
414 0
415 };
416
417 /* ======================================================================== */
418 /* BDEF outputs a number as a ROMW width word directly. Allowed width is */
419 /* determined by argument #2 to the expression. */
420 /* WDEF outputs a 16-bit word as a Double Byte Data. */
421 /* ======================================================================== */
422 static char genbdef[] = "[1=].[2#]I$[1=]x";
423 static char genwdef[] = "[1=].10I$[1=].FF&x[1=].8}.FF&x";
424
425 /*static char gensdbd[] = "0001x";*/
426
427 char ignosyn[] = "[Xinvalid syntax for instruction";
428 char ignosel[] = "[Xinvalid operands";
429
430 /* ======================================================================== */
431 /* Truth table: */
432 /* */
433 /* ifskip rptskip expmac | Expand macros Parse line */
434 /* FALSE FALSE any | TRUE TRUE */
435 /* TRUE any FALSE | FALSE FALSE */
436 /* TRUE any TRUE | TRUE FALSE */
437 /* any TRUE FALSE | FALSE FALSE */
438 /* any TRUE TRUE | TRUE FALSE */
439 /* */
440 /* Only IF/ENDI modify expmac. RPT 0 does not modify expmac, and the */
441 /* default state of expmac is TRUE. Therefore, by default, macros will */
442 /* get expanded in RPT 0 / ENDR blocks. If you need RPT 0 to terminate */
443 /* macro recursion, include an IF / ENDI around it. Sorry. */
444 /* ======================================================================== */
445 int fraifskip = FALSE, frarptskip = FALSE, fraexpmac = TRUE;
446
447 int labelloc;
448 static int satsub;
449 int ifstkpt = 0;
450 int frarptact = 0, frarptcnt = -1;
451 int struct_locctr = -1;
452
453 #define MAX_PROC_STK (64)
454
455 static char *proc_stk[MAX_PROC_STK];
456 static int proc_stk_depth = 0;
457
458 extern char *proc;
459 extern int proc_len;
460 static const char *currmode = "";
461
462
463 static int sdbd = 0, is_sdbd = 0;
464 static int romw = 16;
465 static unsigned romm = 0xFFFF;
466 static int first = 1;
467
468 static int fwd_sdbd = 0;
469
470 struct symel * endsymbol = SYMNULL;
471
472
473 #define SDBD_CHK \
474 if (sdbd) { sdbd = 0; frawarn("SDBD not allowed with this instruction."); }
475
do_set_equ_(int isequ,int flags,struct symel * sym,int value,const char * equerr)476 LOCAL void do_set_equ_(int isequ, int flags,
477 struct symel *sym, int value,
478 const char *equerr)
479 {
480 if (sym->seg == SSG_UNDEF
481 || (sym->seg == SSG_SET && isequ == FALSE))
482 {
483 sym->seg = isequ ? SSG_EQU : SSG_SET;
484 sym->value = value;
485 sym->flags |= flags;
486 emit_set_equ(value);
487 } else
488 {
489 fraerror(equerr);
490 }
491 }
492
do_set_equ_list(int isslice,int isequ,int flags,struct symel * const RESTRICT sym,const intvec_t * const RESTRICT exprs,int firstidx,int lastidx,const char * const RESTRICT ncerr,const char * const RESTRICT equerr)493 LOCAL void do_set_equ_list(int isslice,
494 int isequ,
495 int flags,
496 struct symel *const RESTRICT sym,
497 const intvec_t *const RESTRICT exprs,
498 int firstidx,
499 int lastidx,
500 const char *const RESTRICT ncerr,
501 const char *const RESTRICT equerr)
502 {
503 static long *exprvals = NULL;
504 static int exprvals_size = 0;
505 struct symel *newsym;
506 int i, idx, stp;
507
508 if (exprvals_size < exprs->len)
509 {
510 exprvals = REALLOC(exprvals, long, exprs->alloc);
511 exprvals_size = exprs->alloc;
512 }
513
514 for (i = 0; i < exprs->len; i++)
515 {
516 pevalexpr(0, exprs->data[i]);
517
518 exprvals[i] = evalr[0].value;
519
520 if (evalr[0].seg != SSG_ABS)
521 fraerror(ncerr);
522 }
523
524 if (exprs->len == 1 && !isslice)
525 {
526 do_set_equ_(isequ, flags, sym, exprvals[0], equerr);
527 }
528 else if (abs(lastidx - firstidx) + 1 != exprs->len)
529 {
530 fraerror("Array slice length doesn't match expression list length");
531 }
532 else if (sym->seg == SSG_UNDEF || sym->seg == SSG_SET)
533 {
534 if (sym->value < firstidx)
535 sym->value = firstidx;
536
537 if (sym->value < lastidx)
538 sym->value = lastidx;
539
540 stp = firstidx > lastidx ? -1 : 1;
541 sym->seg = SSG_SET;
542 sym->flags |= SFLAG_QUIET;
543
544 for (i = 0, idx = firstidx; i < exprs->len; i++, idx += stp)
545 {
546 newsym = symbentryidx(sym->symstr, LABEL, 1, idx);
547 newsym->flags |= SFLAG_QUIET | SFLAG_ARRAY;
548
549 do_set_equ_(isequ, flags, newsym, exprvals[i], equerr);
550 }
551 } else
552 {
553 fraerror("Cannot convert symbol to array");
554 }
555 }
556
557 typedef enum { USRERR, USRWARN, USRSTAT, USRCMT } usrmsg;
558
usr_message(usrmsg type,const char * msg)559 LOCAL void usr_message(usrmsg type, const char *msg)
560 {
561 char *copy = strdup((msg && *msg) ? msg : " "), *s, *ss;
562
563 /* force all characters to be printing characters */
564 for (s = copy; *s; s++)
565 if (!(isprint(*s) || isspace(*s)))
566 *s = '?';
567
568 /* Print all the lines of the message, breaking at newlines */
569 for (s = copy; s && *s; s = ss)
570 {
571 ss = strpbrk(s, "\n\r");
572
573 if (ss)
574 *ss++ = 0;
575
576 switch (type)
577 {
578 case USRERR: fraerror(s); break;
579 case USRWARN: frawarn (s); break;
580 case USRSTAT: puts(s); FALLTHROUGH_INTENDED;
581 case USRCMT: emit_comment(1, "%s", s); break;
582 default: fraerror("internal error in usr_message");
583 }
584 }
585
586 free(copy);
587 }
588
chardef(char * sourcestr,const intvec_t * const RESTRICT defs)589 LOCAL void chardef(char *sourcestr,
590 const intvec_t *const RESTRICT defs)
591 {
592 int findrv, numret, *charaddr;
593 char *before;
594
595 if(chtnpoint != (int *)NULL)
596 {
597 for(satsub = 0; satsub < defs->len; satsub++)
598 {
599 before = sourcestr;
600
601 pevalexpr(0, defs->data[satsub]);
602 findrv = chtcfind(chtnpoint, &sourcestr, &charaddr, &numret);
603
604 if(findrv == CF_END)
605 {
606 fraerror("more expressions than characters");
607 break;
608 }
609
610 if(evalr[0].seg == SSG_ABS)
611 {
612 switch(findrv)
613 {
614 case CF_UNDEF:
615 {
616 if(evalr[0].value < 0 || evalr[0].value > 255)
617 frawarn("character translation value truncated");
618
619 *charaddr = evalr[0].value & 0xff;
620 emit_set_equ(evalr[0].value);
621 }
622 break;
623
624 case CF_INVALID:
625 case CF_NUMBER:
626 fracherror("invalid character to define",
627 before, sourcestr);
628 break;
629
630 case CF_CHAR:
631 fracherror("character already defined",
632 before, sourcestr);
633 break;
634 }
635 }
636 else
637 fraerror("noncomputable expression");
638 }
639
640 if( *sourcestr != '\0')
641 fraerror("more characters than expressions");
642 }
643 else
644 fraerror("no CHARSET statement active");
645 }
646
chkover(int value,int bias)647 LOCAL int chkover(int value, int bias)
648 {
649 if (value > 0xFFFF + bias || value < 0)
650 fraerror("Address overflow");
651
652 return value;
653 }
654
655 #define MAXTEMPSTR (65536)
656 static char tempstr[MAXTEMPSTR];
657 static int tempstrlen = 0;
658
659
660 %}
661 %union {
662 int intv;
663 int longv;
664 char *strng;
665 struct symel *symb;
666 struct slidx slidx;
667 intvec_t *intvec;
668 }
669
670 %token <intv> CP1600_REG
671 %token <intv> KOC_BDEF
672 %token <intv> KOC_ELSE
673 %token <intv> KOC_END
674 %token <intv> KOC_ENDI
675 %token <intv> KOC_EQU
676 %token <intv> KOC_IF
677 %token <intv> KOC_INCLUDE
678 %token <intv> KOC_ORG
679 %token <intv> KOC_RESM
680 %token <intv> KOC_SDEF
681 %token <intv> KOC_SET
682 %token <intv> KOC_WDEF
683 %token <intv> KOC_CHSET
684 %token <intv> KOC_CHDEF
685 %token <intv> KOC_CHUSE
686 %token <intv> KOC_opcode
687 %token <intv> KOC_opcode_i
688 %token <intv> KOC_relbr
689 %token <intv> KOC_relbr_x
690 %token <intv> KOC_SDBD
691 %token <intv> KOC_ROMW
692 %token <intv> KOC_PROC
693 %token <intv> KOC_ENDP
694 %token <intv> KOC_STRUCT
695 %token <intv> KOC_ENDS
696 %token <intv> KOC_MEMATTR
697 %token <intv> KOC_DDEF
698 %token <intv> KOC_RPT
699 %token <intv> KOC_ENDR
700 %token <intv> KOC_USRERR
701 %token <intv> KOC_LIST
702 %token <intv> KOC_QEQU
703 %token <intv> KOC_QSET
704 %token <intv> KOC_MACERR /* macro error */
705 %token <intv> KOC_BRKIF
706 %token <intv> KOC_CMSG /* Comment message inserted into listing */
707 %token <intv> KOC_SMSG /* Status message printed to stdout + listing */
708 %token <intv> KOC_WMSG /* User warning */
709 %token <intv> KOC_CFGVAR /* Set a .CFG variable */
710 %token <intv> KOC_SRCFILE /* Set the current source file and line # */
711 %token <intv> KOC_LISTCOL /* Control formatting of the listing file. */
712 %token <intv> KOC_ERR_IF_OVERWRITTEN
713 %token <intv> KOC_FORCE_OVERWRITE
714
715 %token <longv> CONSTANT
716 %token EOL
717 %token KEOP_AND
718 %token KEOP_DEFINED
719 %token KEOP_EQ
720 %token KEOP_GE
721 %token KEOP_GT
722 %token KEOP_HIGH
723 %token KEOP_LE
724 %token KEOP_LOW
725 %token KEOP_LT
726 %token KEOP_MOD
727 %token KEOP_MUN
728 %token KEOP_NE
729 %token KEOP_NOT
730 %token KEOP_OR
731 %token KEOP_SHL
732 %token KEOP_SHR
733 %token KEOP_SHRU
734 %token <intv> KEOP_ROTL
735 %token <intv> KEOP_ROTR
736 %token KEOP_XOR
737 %token KEOP_locctr
738 %token <longv> KEOP_TODAY_STR
739 %token <longv> KEOP_TODAY_VAL
740 %token <longv> KEOP_STRLEN
741 %token <longv> KEOP_ASC
742 %token <longv> KEOP_CLASSIFY
743 %token <symb> LABEL
744 %token <strng> STRING
745 %token <longv> QCHAR
746 %token <symb> SYMBOL
747 %token <longv> FEATURE
748 %token KEOP_EXPMAC /* _EXPMAC modifier for IF/ENDI. */
749
750 %token KTK_invalid
751
752 %nonassoc EXPRLIST
753 %right KEOP_HIGH KEOP_LOW
754 %left KEOP_OR KEOP_XOR
755 %nonassoc FEATURE SYMBOL
756 %left KEOP_AND
757 %right KEOP_NOT
758 %nonassoc KEOP_GT KEOP_GE KEOP_LE KEOP_LT KEOP_NE KEOP_EQ
759 %left '+' '-'
760 %left '*' '/' KEOP_MOD KEOP_SHL KEOP_SHR KEOP_SHRU KEOP_ROTL KEOP_ROTR
761 %right KEOP_MUN
762 %nonassoc ')'
763 %right KEOP_CLASSIFY
764
765
766 %type <intv> expr maybe_expmac
767 %type <intvec> exprlist symslice
768 %type <symb> labelcolon symbol label
769 %type <slidx> labelslice labelslicecolon
770 %type <strng> string
771
772 %start file
773
774 %%
775
776 file : file allline
777 | allline
778 ;
779
780 allline : line EOL
781 {
782 clrexpr();
783 tempstrlen = 0;
784 }
785 | EOL
786 | error EOL
787 {
788 clrexpr();
789 tempstrlen = 0;
790 yyerrok;
791 }
792 ;
793
794 line : labelcolon KOC_END
795 {
796 endsymbol = $1;
797 nextreadact = Nra_end;
798 }
799 | KOC_USRERR string
800 {
801 usr_message(USRERR, $2);
802 }
803 | KOC_WMSG string
804 {
805 usr_message(USRWARN, $2);
806 }
807 | KOC_SMSG string
808 {
809 usr_message(USRSTAT, $2);
810 }
811 | KOC_CMSG string
812 {
813 usr_message(USRCMT, $2);
814 }
815 | KOC_MACERR
816 {
817 fraerror("Unexpected MACRO or ENDM directive");
818 }
819 | KOC_END
820 {
821 nextreadact = Nra_end;
822 }
823 | KOC_INCLUDE STRING
824 {
825 if(frarptact)
826 {
827 fraerror("INCLUDE not permitted inside REPEAT");
828 } else if(nextfstk >= FILESTKDPTH)
829 {
830 fraerror("include file nesting limit exceeded");
831 }
832 else
833 {
834 infilestk[nextfstk].line = 0;
835 infilestk[nextfstk].fnm = memoize_string($2);
836 if( (infilestk[nextfstk].fpt =
837 path_fopen(as1600_search_path,$2,"r")) ==(LZFILE*)NULL)
838 {
839 static char *incl_file = NULL;
840 static int incl_file_size = 0;
841 int incl_file_len = strlen($2) + 80;
842 if (incl_file_size < incl_file_len)
843 {
844 incl_file_size = incl_file_len << 1;
845 if (incl_file) free(incl_file);
846 incl_file = (char *)malloc(incl_file_size);
847 if (!incl_file)
848 incl_file_size = 0;
849 }
850 if (incl_file_size == 0)
851 fraerror("cannot open include file");
852 else
853 {
854 sprintf(incl_file, "cannot open include file "
855 "\"%s\"", $2);
856
857 fraerror(incl_file);
858 }
859 }
860 else
861 {
862 nextreadact = Nra_new;
863 }
864 }
865 }
866 | labelcolon KOC_EQU exprlist
867 {
868 do_set_equ_list(FALSE, TRUE, 0, $1, $3, 0, $3->len - 1,
869 "noncomputable expression for EQU",
870 "cannot change symbol value with EQU");
871 intvec_delete($3);
872 }
873 | labelcolon KOC_QEQU exprlist
874 {
875 do_set_equ_list(FALSE, TRUE, SFLAG_QUIET, $1, $3, 0,
876 $3->len - 1,
877 "noncomputable expression for QEQU",
878 "cannot change symbol value with QEQU");
879 intvec_delete($3);
880 }
881 | labelcolon KOC_SET exprlist
882 {
883 do_set_equ_list(FALSE, FALSE, 0, $1, $3, 0,
884 $3->len - 1,
885 "noncomputable expression for SET",
886 "cannot change symbol value with SET");
887 intvec_delete($3);
888 }
889 | labelcolon KOC_QSET exprlist
890 {
891 do_set_equ_list(FALSE, FALSE, SFLAG_QUIET, $1, $3, 0,
892 $3->len - 1,
893 "noncomputable expression for QSET",
894 "cannot change symbol value with QSET");
895 intvec_delete($3);
896 }
897 | labelslicecolon KOC_EQU exprlist
898 {
899 do_set_equ_list(TRUE, TRUE, 0,
900 $1.sym, $3, $1.first, $1.last,
901 "noncomputable expression for EQU",
902 "cannot change symbol value with EQU");
903 intvec_delete($3);
904 }
905 | labelslicecolon KOC_QEQU exprlist
906 {
907 do_set_equ_list(TRUE, TRUE, SFLAG_QUIET,
908 $1.sym, $3, $1.first, $1.last,
909 "noncomputable expression for QEQU",
910 "cannot change symbol value with QEQU");
911 intvec_delete($3);
912 }
913 | labelslicecolon KOC_SET exprlist
914 {
915 do_set_equ_list(TRUE, FALSE, 0,
916 $1.sym, $3, $1.first, $1.last,
917 "noncomputable expression for SET",
918 "cannot change symbol value with SET");
919 intvec_delete($3);
920 }
921 | labelslicecolon KOC_QSET exprlist
922 {
923 do_set_equ_list(TRUE, FALSE, SFLAG_QUIET,
924 $1.sym, $3, $1.first, $1.last,
925 "noncomputable expression for QSET",
926 "cannot change symbol value with QSET");
927 intvec_delete($3);
928 }
929 | KOC_RPT expr
930 {
931 pevalexpr(0, $2);
932 if (evalr[0].seg == SSG_ABS)
933 {
934 if (evalr[0].value < 0)
935 {
936 fraerror("REPEAT count must be >= 0");
937 frarptpush(0); /* treat it as a 0 count. */
938 } else
939 {
940 frarptpush(frarptskip ? 0 : evalr[0].value);
941 }
942 } else
943 {
944 fraerror("Computable expression required for REPEAT block");
945 frarptpush(0); /* treat it as a 0 count. */
946 }
947 }
948 | KOC_ENDR
949 {
950 if (frarptact == 0)
951 {
952 fraerror("ENDR without REPEAT");
953 frarptreset(); /* make sure repeat stack is reset. */
954 } else
955 {
956 frarptendr(); /* loop back to most recent REPEAT */
957 }
958 }
959 | KOC_BRKIF expr
960 {
961 if (frarptcnt < 0)
962 fraerror("BRKIF without REPEAT");
963
964 pevalexpr(0, $2);
965 if (evalr[0].seg == SSG_ABS)
966 {
967 if (evalr[0].value != 0)
968 frarptbreak(); /* skip rest of repeat block */
969 } else
970 {
971 fraerror("Computable expression required for BRKIF");
972 }
973 }
974 | KOC_LIST STRING
975 {
976 if (stricmp($2, "ON" )==0) emit_listing_mode(LIST_ON);
977 else if (stricmp($2, "OFF" )==0) emit_listing_mode(LIST_OFF);
978 else if (stricmp($2, "CODE")==0) emit_listing_mode(LIST_CODE);
979 else if (stricmp($2, "PREV")==0) emit_listing_mode(LIST_PREV);
980 else
981 {
982 fraerror("LISTING must be followed by \"ON\", \"OFF\" "
983 "or \"CODE\"");
984 }
985 }
986 | labelcolon KOC_LIST STRING
987 {
988 if (stricmp($3, "ON" )==0) emit_listing_mode(LIST_ON);
989 else if (stricmp($3, "OFF" )==0) emit_listing_mode(LIST_OFF);
990 else if (stricmp($3, "CODE")==0) emit_listing_mode(LIST_CODE);
991 else if (stricmp($3, "PREV")==0) emit_listing_mode(LIST_PREV);
992 else
993 {
994 fraerror("LISTING must be followed by \"ON\", \"OFF\" "
995 "or \"CODE\"");
996 }
997
998 if($1->seg == SSG_UNDEF)
999 {
1000 $1->seg = SSG_ABS;
1001 $1->value = labelloc;
1002 }
1003 else
1004 fraerror( "multiple definition of label");
1005 }
1006 | KOC_IF maybe_expmac expr
1007 {
1008 if((++ifstkpt) < IFSTKDEPTH)
1009 {
1010 pevalexpr(0, $3);
1011 if(evalr[0].seg == SSG_ABS)
1012 {
1013 if(evalr[0].value != 0)
1014 {
1015 elseifstk[ifstkpt] = If_Skip;
1016 endifstk[ifstkpt] = If_Active;
1017 }
1018 else
1019 {
1020 fraifskip = TRUE;
1021 elseifstk[ifstkpt] = If_Active;
1022 endifstk[ifstkpt] = If_Active;
1023 }
1024 }
1025 else
1026 {
1027 fraifskip = TRUE;
1028 elseifstk[ifstkpt] = If_Active;
1029 endifstk[ifstkpt] = If_Active;
1030 }
1031 expmacstk[ifstkpt] = fraexpmac;
1032 fraexpmac = $2;
1033 }
1034 else
1035 {
1036 fraerror("IF stack overflow");
1037 }
1038 }
1039
1040 | KOC_IF maybe_expmac
1041 {
1042 if(fraifskip)
1043 {
1044 if((++ifstkpt) < IFSTKDEPTH)
1045 {
1046 elseifstk[ifstkpt] = If_Skip;
1047 endifstk[ifstkpt] = If_Skip;
1048 expmacstk[ifstkpt] = fraexpmac;
1049 fraexpmac = $2;
1050 }
1051 else
1052 {
1053 fraerror("IF stack overflow");
1054 }
1055 }
1056 else
1057 {
1058 yyerror("syntax error");
1059 YYERROR;
1060 }
1061 }
1062
1063 | KOC_ELSE
1064 {
1065 switch(elseifstk[ifstkpt])
1066 {
1067 case If_Active:
1068 fraifskip = FALSE;
1069 break;
1070
1071 case If_Skip:
1072 fraifskip = TRUE;
1073 break;
1074
1075 case If_Err:
1076 fraerror("ELSE with no matching if");
1077 break;
1078 }
1079 }
1080
1081 | KOC_ENDI
1082 {
1083 fraexpmac = expmacstk[ifstkpt];
1084 switch(endifstk[ifstkpt])
1085 {
1086 case If_Active:
1087 fraifskip = FALSE;
1088 ifstkpt--;
1089 break;
1090
1091 case If_Skip:
1092 fraifskip = TRUE;
1093 ifstkpt--;
1094 break;
1095
1096 case If_Err:
1097 fraerror("ENDI with no matching if");
1098 break;
1099 }
1100 }
1101 | labelcolon KOC_ORG expr
1102 {
1103 pevalexpr(0, $3);
1104 if(evalr[0].seg == SSG_ABS)
1105 {
1106 locctr = 2 * chkover(labelloc = evalr[0].value, 0);
1107 currseg = 0;
1108 currpag = -1;
1109 currmode = memoize_string("+R");
1110 if($1->seg == SSG_UNDEF)
1111 {
1112 $1->seg = SSG_ABS;
1113 $1->value = labelloc;
1114 }
1115 else
1116 fraerror( "multiple definition of label");
1117
1118 emit_set_equ(evalr[0].value);
1119 }
1120 else
1121 {
1122 fraerror( "noncomputable expression for ORG");
1123 }
1124 }
1125 | KOC_ORG expr
1126 {
1127 pevalexpr(0, $2);
1128 if(evalr[0].seg == SSG_ABS)
1129 {
1130 locctr = 2 * chkover(labelloc = evalr[0].value, 0);
1131 currseg = 0;
1132 currpag = -1;
1133 currmode = memoize_string("+R");
1134 emit_set_equ(evalr[0].value);
1135 }
1136 else
1137 {
1138 fraerror(
1139 "noncomputable expression for ORG");
1140 }
1141 }
1142 | labelcolon KOC_ORG expr ',' expr
1143 {
1144 pevalexpr(0, $3);
1145 pevalexpr(1, $5);
1146 if(evalr[0].seg == SSG_ABS && evalr[1].seg == SSG_ABS)
1147 {
1148 locctr = 2 * chkover(labelloc = evalr[0].value, 0);
1149 currseg = chkover(evalr[1].value, 0) - labelloc;
1150 currpag = -1;
1151 currmode = memoize_string(currseg ? "" : "+R");
1152 if($1->seg == SSG_UNDEF)
1153 {
1154 $1->seg = SSG_ABS;
1155 $1->value = labelloc;
1156 }
1157 else
1158 fraerror( "multiple definition of label");
1159
1160 emit_set_equ(evalr[0].value);
1161 }
1162 else
1163 {
1164 fraerror( "noncomputable expression for ORG");
1165 }
1166 }
1167 | KOC_ORG expr ',' expr
1168 {
1169 pevalexpr(0, $2);
1170 pevalexpr(1, $4);
1171 if(evalr[0].seg == SSG_ABS && evalr[1].seg == SSG_ABS)
1172 {
1173 locctr = 2 * chkover(labelloc = evalr[0].value, 0);
1174 currseg = chkover(evalr[1].value, 0) - labelloc;
1175 currpag = -1;
1176 currmode = memoize_string(currseg ? "" : "+R");
1177 emit_set_equ(evalr[0].value);
1178 }
1179 else
1180 {
1181 fraerror(
1182 "noncomputable expression for ORG");
1183 }
1184 }
1185 | labelcolon KOC_ORG expr ',' expr ',' STRING
1186 {
1187 pevalexpr(0, $3);
1188 pevalexpr(1, $5);
1189 if(evalr[0].seg == SSG_ABS && evalr[1].seg == SSG_ABS)
1190 {
1191 char *s = $7;
1192
1193 locctr = 2 * chkover(labelloc = evalr[0].value, 0);
1194 currseg = chkover(evalr[1].value, 0) - labelloc;
1195 currpag = -1;
1196 currmode = memoize_string(s);
1197
1198 if($1->seg == SSG_UNDEF)
1199 {
1200 $1->seg = SSG_ABS;
1201 $1->value = labelloc;
1202 }
1203 else
1204 fraerror( "multiple definition of label");
1205
1206 emit_set_equ(evalr[0].value);
1207 }
1208 else
1209 {
1210 fraerror( "noncomputable expression for ORG");
1211 }
1212 }
1213 | KOC_ORG expr ',' expr ',' STRING
1214 {
1215 pevalexpr(0, $2);
1216 pevalexpr(1, $4);
1217 if(evalr[0].seg == SSG_ABS && evalr[1].seg == SSG_ABS)
1218 {
1219 char *s = $6;
1220
1221 locctr = 2 * chkover(labelloc = evalr[0].value, 0);
1222 currseg = chkover(evalr[1].value, 0) - labelloc;
1223 currpag = -1;
1224 currmode = memoize_string(s);
1225 emit_set_equ(evalr[0].value);
1226 }
1227 else
1228 {
1229 fraerror("noncomputable expression for ORG");
1230 }
1231 }
1232 | labelcolon KOC_ORG expr ':' expr
1233 {
1234 pevalexpr(0, $3);
1235 pevalexpr(1, $5);
1236 if(evalr[0].seg == SSG_ABS && evalr[1].seg == SSG_ABS)
1237 {
1238 locctr = 2 * chkover(labelloc = evalr[0].value, 0);
1239 currseg = 0;
1240 currpag = evalr[1].value;
1241 currmode = memoize_string("=R");
1242 if($1->seg == SSG_UNDEF)
1243 {
1244 $1->seg = SSG_ABS;
1245 $1->value = labelloc;
1246 }
1247 else
1248 fraerror( "multiple definition of label");
1249
1250 emit_set_equ(evalr[0].value);
1251 }
1252 else
1253 {
1254 fraerror( "noncomputable expression for ORG");
1255 }
1256 }
1257 | KOC_ORG expr ':' expr
1258 {
1259 pevalexpr(0, $2);
1260 pevalexpr(1, $4);
1261 if(evalr[0].seg == SSG_ABS && evalr[1].seg == SSG_ABS)
1262 {
1263 locctr = 2 * chkover(labelloc = evalr[0].value, 0);
1264 currseg = 0;
1265 currpag = evalr[1].value;
1266 currmode = memoize_string("=R");
1267 emit_set_equ(evalr[0].value);
1268 }
1269 else
1270 {
1271 fraerror("noncomputable expression for ORG");
1272 }
1273 }
1274 | labelcolon KOC_ORG expr ':' expr ',' STRING
1275 {
1276 pevalexpr(0, $3);
1277 pevalexpr(1, $5);
1278 if(evalr[0].seg == SSG_ABS && evalr[1].seg == SSG_ABS)
1279 {
1280 locctr = 2 * chkover(labelloc = evalr[0].value, 0);
1281 currseg = 0;
1282 currpag = evalr[1].value;
1283 currmode = memoize_string($7);
1284 if($1->seg == SSG_UNDEF)
1285 {
1286 $1->seg = SSG_ABS;
1287 $1->value = labelloc;
1288 }
1289 else
1290 fraerror( "multiple definition of label");
1291
1292 emit_set_equ(evalr[0].value);
1293 }
1294 else
1295 {
1296 fraerror( "noncomputable expression for ORG");
1297 }
1298 }
1299 | KOC_ORG expr ':' expr ',' STRING
1300 {
1301 pevalexpr(0, $2);
1302 pevalexpr(1, $4);
1303 if(evalr[0].seg == SSG_ABS && evalr[1].seg == SSG_ABS)
1304 {
1305 locctr = 2 * chkover(labelloc = evalr[0].value, 0);
1306 currseg = 0;
1307 currpag = evalr[1].value;
1308 currmode = memoize_string($6);
1309 emit_set_equ(evalr[0].value);
1310 }
1311 else
1312 {
1313 fraerror("noncomputable expression for ORG");
1314 }
1315 }
1316 | KOC_MEMATTR expr ',' expr ',' STRING
1317 {
1318 pevalexpr(0, $2);
1319 pevalexpr(1, $4);
1320 if(evalr[0].seg == SSG_ABS && evalr[1].seg == SSG_ABS)
1321 {
1322 const char *s = memoize_string($6);
1323 chkover(evalr[0].value, 0);
1324 chkover(evalr[1].value, 0);
1325 emit_location(0, -1, labelloc, TYPE_HOLE, s);
1326 emit_mark_with_mode(evalr[0].value, evalr[1].value, s);
1327 emit_location(currseg, currpag, labelloc, TYPE_HOLE,
1328 currmode);
1329 }
1330 else
1331 {
1332 fraerror("noncomputable expression for MEMATTR");
1333 }
1334 }
1335 | KOC_CFGVAR string KEOP_EQ string
1336 {
1337 const char *var = memoize_string($2);
1338 const char *value = memoize_string($4);
1339 emit_cfgvar_str(var, value);
1340 }
1341 | KOC_CFGVAR string KEOP_EQ expr
1342 {
1343 pevalexpr(0, $4);
1344 if(evalr[0].seg == SSG_ABS)
1345 {
1346 const char *var = memoize_string($2);
1347 emit_cfgvar_int(var, evalr[0].value);
1348 }
1349 else
1350 {
1351 fraerror("noncomputable expression for CFGVAR");
1352 }
1353 }
1354 | KOC_SRCFILE string ',' expr
1355 {
1356 /* set the current source file override and line number */
1357 pevalexpr(0, $4);
1358 if ( evalr[0].seg == SSG_ABS )
1359 {
1360 if ( strlen( $2 ) == 0 || evalr[0].value < 1 )
1361 {
1362 emit_srcfile_override( NULL, 0 );
1363 } else
1364 {
1365 emit_srcfile_override( memoize_string( $2 ),
1366 evalr[0].value );
1367 }
1368 }
1369 else
1370 {
1371 fraerror("noncomputable expression for SRCFILE");
1372 }
1373 }
1374 | KOC_LISTCOL expr ',' expr ',' expr
1375 {
1376 pevalexpr(0, $2); /* Hex per line w/ source */
1377 pevalexpr(1, $4); /* Hex per line w/out source */
1378 pevalexpr(2, $6); /* Starting column of source */
1379 if ( evalr[0].seg != SSG_ABS || evalr[1].seg != SSG_ABS ||
1380 evalr[2].seg != SSG_ABS )
1381 {
1382 fraerror("noncomputable expression for LISTCOL");
1383 } else
1384 {
1385 const int new_hex_source = evalr[0].value;
1386 const int new_hex_no_src = evalr[1].value;
1387 const int new_source_ofs = evalr[2].value;
1388 const int new_source_ofs_min = 7 + 5*new_hex_source;
1389
1390 if (new_hex_source < 1 || new_hex_source > 256 ||
1391 new_hex_no_src < 1 || new_hex_no_src > 256 ||
1392 new_source_ofs < 1 || new_source_ofs > 2048)
1393 {
1394 fraerror("value out of range value for LISTCOL");
1395 } else
1396 {
1397 if (new_source_ofs < new_source_ofs_min)
1398 {
1399 fraerror("source column too small compared to "
1400 "hex-per-source-line for LISTCOL");
1401 } else
1402 {
1403 emit_listing_column(new_hex_source,
1404 new_hex_no_src,
1405 new_source_ofs);
1406 }
1407 }
1408 }
1409 }
1410 | KOC_ERR_IF_OVERWRITTEN expr
1411 {
1412 pevalexpr(0, $2);
1413 if ( evalr[0].seg != SSG_ABS )
1414 {
1415 fraerror("noncomputable expression for ERR_IF_OVERWITTEN");
1416 } else
1417 {
1418 emit_err_if_overwritten(evalr[0].value != 0);
1419 }
1420 }
1421 | KOC_FORCE_OVERWRITE expr
1422 {
1423 pevalexpr(0, $2);
1424 if ( evalr[0].seg != SSG_ABS )
1425 {
1426 fraerror("noncomputable expression for FORCE_OVERWRITE");
1427 } else
1428 {
1429 emit_force_overwrite(evalr[0].value != 0);
1430 }
1431 }
1432 | labelcolon KOC_CHSET
1433 {
1434 if($1->seg == SSG_UNDEF)
1435 {
1436 $1->seg = SSG_EQU;
1437 if( ($1->value = chtcreate()) <= 0)
1438 {
1439 fraerror("cannot create character translation table");
1440 }
1441 emit_set_equ($1->value);
1442 }
1443 else
1444 {
1445 fraerror("multiple definition of label");
1446 }
1447 }
1448 | KOC_CHUSE
1449 {
1450 chtcpoint = (int *) NULL;
1451 emit_set_equ(0L);
1452 }
1453 | KOC_CHUSE expr
1454 {
1455 pevalexpr(0, $2);
1456 if( evalr[0].seg == SSG_ABS)
1457 {
1458 if( evalr[0].value == 0)
1459 {
1460 chtcpoint = (int *)NULL;
1461 emit_set_equ(0L);
1462 }
1463 else if(evalr[0].value < chtnxalph)
1464 {
1465 chtcpoint = chtatab[evalr[0].value];
1466 emit_set_equ(evalr[0].value);
1467 }
1468 else
1469 {
1470 fraerror("nonexistent character translation table");
1471 }
1472 }
1473 else
1474 {
1475 fraerror("noncomputable expression");
1476 }
1477 }
1478 | KOC_CHDEF string ',' exprlist
1479 {
1480 chardef($2, $4);
1481 intvec_delete($4);
1482 }
1483 | KOC_CHDEF QCHAR ',' exprlist
1484 {
1485 char st[2] = { $2, 0 };
1486 chardef(st, $4);
1487 intvec_delete($4);
1488 }
1489 | labelcolon
1490 {
1491 if($1->seg == SSG_UNDEF)
1492 {
1493 $1->seg = SSG_ABS;
1494 $1->value = chkover(labelloc, 0);
1495 emit_set_equ(labelloc);
1496
1497 }
1498 else
1499 fraerror("multiple definition of label");
1500 }
1501 | labeledline
1502 ;
1503
1504 maybe_expmac: KEOP_EXPMAC { $$ = 1; }
1505 | { $$ = 0; }
1506 ;
1507
1508 labeledline : labelcolon genline
1509 {
1510 if (sdbd)
1511 frawarn("label between SDBD and instruction");
1512
1513 if($1->seg == SSG_UNDEF)
1514 {
1515 $1->seg = SSG_ABS;
1516 $1->value = chkover(labelloc, 0);
1517 }
1518 else
1519 fraerror("multiple definition of label");
1520
1521 if (locctr & 1) fraerror("internal error: PC misaligned.");
1522
1523 labelloc = locctr >> 1;
1524
1525 sdbd = is_sdbd;
1526 is_sdbd = 0;
1527 first = 0;
1528 }
1529 | genline
1530 {
1531 if (locctr & 1) fraerror("internal error: PC misaligned.");
1532 labelloc = locctr >> 1;
1533
1534 sdbd = is_sdbd;
1535 is_sdbd = 0;
1536 first = 0;
1537 }
1538 ;
1539
1540 genline : KOC_BDEF exprlist
1541 {
1542 emit_location(currseg, currpag, labelloc, TYPE_DATA, currmode);
1543 evalr[2].seg = SSG_ABS;
1544 evalr[2].value = 8;
1545 for( satsub = 0; satsub < $2->len; satsub++)
1546 {
1547 pevalexpr(1, $2->data[satsub]);
1548 locctr += geninstr(genbdef);
1549 }
1550 chkover( locctr >> 1 , 1);
1551 intvec_delete($2);
1552 }
1553 | KOC_DDEF exprlist
1554 {
1555 emit_location(currseg, currpag, labelloc, TYPE_DATA, currmode);
1556 evalr[2].seg = SSG_ABS;
1557 evalr[2].value = romw;
1558 for( satsub = 0; satsub < $2->len; satsub++)
1559 {
1560 pevalexpr(1, $2->data[satsub]);
1561 locctr += geninstr(genbdef);
1562 }
1563 chkover( locctr >> 1 , 1);
1564 intvec_delete($2);
1565 }
1566
1567 | KOC_SDEF exprlist
1568 {
1569 emit_location(currseg, currpag, labelloc, TYPE_STRING, currmode);
1570 evalr[2].seg = SSG_ABS;
1571 evalr[2].value = romw;
1572 for( satsub = 0; satsub < $2->len; satsub++)
1573 {
1574 pevalexpr(1, $2->data[satsub]);
1575 locctr += geninstr(genbdef);
1576 }
1577 chkover( locctr >> 1 , 1);
1578 intvec_delete($2);
1579 }
1580 | KOC_WDEF exprlist
1581 {
1582 emit_location(currseg, currpag, labelloc,
1583 TYPE_DBDATA|TYPE_DATA, currmode);
1584 for( satsub = 0; satsub < $2->len; satsub++)
1585 {
1586 pevalexpr(1, $2->data[satsub]);
1587 locctr += geninstr(genwdef);
1588 }
1589 chkover( locctr >> 1 , 1);
1590 intvec_delete($2);
1591 }
1592 | KOC_RESM expr
1593 {
1594 pevalexpr(0, $2);
1595 if(evalr[0].seg == SSG_ABS)
1596 {
1597 locctr = 2 * chkover(labelloc + evalr[0].value, 1);
1598 emit_set_equ(labelloc);
1599 emit_location(currseg, currpag, labelloc, TYPE_HOLE,
1600 currmode);
1601 emit_reserve(labelloc + evalr[0].value - 1);
1602 }
1603 else
1604 {
1605 fraerror("noncomputable expression for RMB");
1606 }
1607 }
1608 ;
1609
1610 labelcolon: label
1611 | label ':'
1612 ;
1613
1614 labelslicecolon: labelslice
1615 | labelslice ':'
1616 ;
1617
1618 exprlist : exprlist ',' expr
1619 {
1620 intvec_push($1, $3);
1621 $$ = $1;
1622 }
1623 | exprlist ',' string
1624 {
1625 char *s = $3;
1626 int accval = 0;
1627
1628 while (*s)
1629 {
1630 accval = chtran(&s);
1631 intvec_push($1,
1632 exprnode(PCCASE_CONS,0,IGP_CONSTANT,0,accval,SYMNULL));
1633 }
1634 $$ = $1;
1635 }
1636 | expr %prec EXPRLIST
1637 {
1638 intvec_t *const RESTRICT iv = intvec_new();
1639 intvec_push(iv, $1);
1640 $$ = iv;
1641 }
1642 | string
1643 {
1644 intvec_t *const RESTRICT iv = intvec_new();
1645 char *s = $1;
1646 int accval = 0;
1647
1648 while (*s)
1649 {
1650 accval = chtran(&s);
1651 intvec_push(iv,
1652 exprnode(PCCASE_CONS,0,IGP_CONSTANT,0,accval,SYMNULL));
1653 }
1654 $$ = iv;
1655 }
1656 | KEOP_TODAY_VAL '(' string ')'
1657 {
1658 const struct tm *t = $1 ? &asm_time_gmt : &asm_time_local;
1659 $$ = unpack_time_exprs(t, &asm_time_gmt, $3);
1660 }
1661 | exprlist ',' symslice
1662 {
1663 intvec_concat($1, $3);
1664 intvec_delete($3);
1665 $$ = $1;
1666 }
1667 | symslice
1668 {
1669 $$ = $1;
1670 }
1671 ;
1672
1673 string : STRING
1674 | '$' '(' exprlist ')'
1675 {
1676 char *s = &tempstr[tempstrlen];
1677
1678 if (chtcpoint != NULL)
1679 {
1680 frawarn("Stringifying expression list while character "
1681 "translation active");
1682 }
1683
1684 tempstrlen += $3->len + 1;
1685
1686 if (tempstrlen > MAXTEMPSTR)
1687 {
1688 fraerror("Temporary string buffer overflow");
1689 $$ = "";
1690 } else
1691 {
1692 int i;
1693 $$ = s;
1694 for (i = 0; i < $3->len; i++)
1695 {
1696 pevalexpr(0, $3->data[i]);
1697
1698 if (evalr[0].seg == SSG_ABS)
1699 *s++ = evalr[0].value;
1700 else
1701 *s++ = '?';
1702 }
1703 *s = 0;
1704 }
1705 intvec_delete($3);
1706 }
1707 | '$' '#' '(' expr ')'
1708 {
1709 char *s = &tempstr[tempstrlen];
1710
1711 if (tempstrlen + 32 > MAXTEMPSTR)
1712 {
1713 fraerror("Temporary string buffer overflow");
1714 $$ = "";
1715 } else
1716 {
1717 $$ = s;
1718 pevalexpr(0, $4);
1719
1720 if (evalr[0].seg == SSG_ABS)
1721 sprintf(s, "%d", (int)evalr[0].value);
1722 else
1723 {
1724 s[0] = '?';
1725 s[1] = 0;
1726 }
1727 tempstrlen += strlen(s) + 1;
1728 }
1729 }
1730 | '$' '$' '(' expr ')'
1731 {
1732 char *s = &tempstr[tempstrlen];
1733
1734 if (tempstrlen + 5 > MAXTEMPSTR)
1735 {
1736 fraerror("Temporary string buffer overflow");
1737 $$ = "";
1738 } else
1739 {
1740 $$ = s;
1741 pevalexpr(0, $4);
1742
1743 if (evalr[0].seg == SSG_ABS)
1744 sprintf(s, "%4.4X",
1745 (unsigned int)(0xFFFF & evalr[0].value));
1746 else
1747 {
1748 s[0] = '?';
1749 s[1] = '?';
1750 s[2] = '?';
1751 s[3] = '?';
1752 s[4] = 0;
1753 }
1754 tempstrlen += 5;
1755 }
1756 }
1757 | '$' '%' '(' expr ')'
1758 {
1759 char *s = &tempstr[tempstrlen];
1760
1761 if (tempstrlen + 5 > MAXTEMPSTR)
1762 {
1763 fraerror("Temporary string buffer overflow");
1764 $$ = "";
1765 } else
1766 {
1767 $$ = s;
1768 pevalexpr(0, $4);
1769
1770 if (evalr[0].seg == SSG_ABS)
1771 sprintf(s, "%8.8X",
1772 (unsigned int)(0xFFFFFFFF & evalr[0].value));
1773 else
1774 {
1775 s[0] = '?';
1776 s[1] = '?';
1777 s[2] = '?';
1778 s[3] = '?';
1779 s[4] = '?';
1780 s[5] = '?';
1781 s[6] = '?';
1782 s[7] = '?';
1783 s[8] = 0;
1784 }
1785 tempstrlen += 5;
1786 }
1787 }
1788 | KEOP_TODAY_STR '(' string ')'
1789 {
1790 const struct tm *t = $1 ? &asm_time_gmt : &asm_time_local;
1791 char *const bufbeg = &tempstr[tempstrlen];
1792 const int avail = MAXTEMPSTR - tempstrlen;
1793 const int len = format_time_string(t, &asm_time_gmt,
1794 $3, bufbeg, avail);
1795 tempstrlen += len;
1796 $$ = bufbeg;
1797 }
1798 ;
1799
1800 /* ======================================================================== */
1801 /* PROC/ENDP pseudo-ops */
1802 /* ======================================================================== */
1803 genline : labelcolon KOC_PROC
1804 {
1805 if (proc && struct_locctr != -1)
1806 fraerror("PROC cannot nest inside STRUCT.");
1807 else if (proc && proc_stk_depth == MAX_PROC_STK)
1808 fraerror("PROC nesting limit reached.");
1809 else if (($1->flags & SFLAG_ARRAY) != 0)
1810 fraerror("array element can not be defined by PROC");
1811 else if ($1->seg != SSG_UNDEF)
1812 fraerror("multiple definition of label");
1813 else
1814 {
1815 if (proc)
1816 {
1817 char *old_proc = proc;
1818 int old_proc_len = proc_len;
1819 proc_stk[proc_stk_depth++] = proc;
1820 proc_len = strlen(proc) + strlen($1->symstr) + 1;
1821 proc = (char *)malloc(proc_len + 1);
1822 strcpy(proc, old_proc);
1823 proc[old_proc_len] = '.';
1824 strcpy(proc + old_proc_len + 1, $1->symstr);
1825 } else
1826 {
1827 proc = strdup($1->symstr);
1828 proc_len = strlen(proc);
1829 }
1830
1831 $1->seg = SSG_ABS;
1832 $1->value = labelloc;
1833 emit_set_equ(labelloc);
1834 }
1835 }
1836 ;
1837 genline : KOC_ENDP
1838 {
1839 if (!proc || struct_locctr != -1)
1840 fraerror("ENDP w/out PROC.");
1841
1842 free(proc);
1843
1844 if (proc_stk_depth > 0)
1845 {
1846 proc = proc_stk[--proc_stk_depth];
1847 proc_len = strlen(proc);
1848 } else
1849 {
1850 proc = NULL;
1851 proc_len = 0;
1852 }
1853 }
1854 ;
1855 /* ======================================================================== */
1856 /* STRUCT/ENDS pseudo-ops */
1857 /* ======================================================================== */
1858 genline : labelcolon KOC_STRUCT expr
1859 {
1860 pevalexpr(0, $3);
1861
1862 if (proc)
1863 fraerror("STRUCT can not nest inside other STRUCTs or PROCs.");
1864 else if (($1->flags & SFLAG_ARRAY) != 0)
1865 fraerror("array element can not be defined by STRUCT");
1866 else if (evalr[0].seg != SSG_ABS)
1867 fraerror( "noncomputable expression for ORG");
1868 else if ($1->seg != SSG_UNDEF)
1869 fraerror( "multiple definition of label");
1870 else
1871 {
1872 proc = strdup($1->symstr);
1873 proc_len = strlen(proc);
1874 struct_locctr = locctr;
1875
1876 locctr = 2 * chkover(labelloc = evalr[0].value, 0);
1877
1878 $1->seg = SSG_ABS;
1879 $1->value = labelloc;
1880
1881 emit_set_equ(evalr[0].value);
1882 }
1883 }
1884 ;
1885 genline : KOC_ENDS
1886 {
1887 if (!proc || struct_locctr == -1)
1888 fraerror("ENDS w/out STRUCT.");
1889 else
1890 {
1891 free(proc);
1892 proc = NULL;
1893 proc_len = 0;
1894 locctr = struct_locctr;
1895 struct_locctr = -1;
1896 }
1897 }
1898 ;
1899 /* ======================================================================== */
1900 /* ROMWIDTH pseudo-op */
1901 /* ======================================================================== */
1902 genline : KOC_ROMW expr
1903 {
1904 emit_location(currseg, currpag, labelloc, TYPE_HOLE, currmode);
1905 pevalexpr(0, $2);
1906 if(evalr[0].seg == SSG_ABS)
1907 {
1908 romw = evalr[0].value;
1909
1910 if (romw < 8 || romw > 16)
1911 fraerror("ROMWIDTH out of range");
1912
1913 romm = 0xFFFFU >> (16 - romw);
1914 }
1915 else
1916 {
1917 fraerror("noncomputable expression for ROMWIDTH");
1918 }
1919
1920 if (!first)
1921 {
1922 frawarn("Code appears before ROMW directive.");
1923 }
1924
1925 fwd_sdbd = 0;
1926 }
1927 | KOC_ROMW expr ',' expr
1928 {
1929 emit_location(currseg, currpag, labelloc, TYPE_HOLE, currmode);
1930 pevalexpr(0, $2);
1931 pevalexpr(1, $4);
1932 if(evalr[0].seg == SSG_ABS)
1933 {
1934 romw = evalr[0].value;
1935
1936 if (romw < 8 || romw > 16)
1937 fraerror("ROMWIDTH out of range");
1938
1939 romm = 0xFFFFU >> (16 - romw);
1940 }
1941 else
1942 fraerror("noncomputable expression for ROMWIDTH");
1943
1944 if (!first)
1945 {
1946 frawarn("Code appears before ROMW directive.");
1947 }
1948
1949 if (evalr[1].seg == SSG_ABS)
1950 {
1951 fwd_sdbd = evalr[1].value;
1952
1953 if (fwd_sdbd > 1 || fwd_sdbd < 0)
1954 fraerror("SDBD mode flag must be 0 or 1.");
1955 } else
1956 fraerror("noncomputable expression for ROMWIDTH");
1957
1958 }
1959 ;
1960
1961 /* ======================================================================== */
1962 /* SDBD instruction. */
1963 /* ======================================================================== */
1964 genline : KOC_SDBD
1965 {
1966 if (sdbd)
1967 frawarn("Two SDBDs in a row.");
1968
1969 emit_location(currseg, currpag, labelloc, TYPE_CODE, currmode);
1970 locctr += geninstr(findgen($1, ST_IMP, 0));
1971 chkover(locctr >> 1, 1);
1972 is_sdbd = SDBD;
1973 }
1974 ;
1975
1976 /* ======================================================================== */
1977 /* Relative Branch instructions. */
1978 /* ======================================================================== */
1979 genline : KOC_relbr expr
1980 {
1981 /*unsigned rel_addr = labelloc + 2;*/
1982 /*int dir;*/
1983
1984 SDBD_CHK
1985
1986 emit_location(currseg, currpag, labelloc, TYPE_CODE, currmode);
1987 pevalexpr(1, $2);
1988
1989 evalr[3].seg = SSG_ABS;
1990 evalr[3].value = romw;
1991
1992 locctr += geninstr(findgen($1, ST_EXP, sdbd));
1993 chkover(locctr >> 1, 1);
1994 }
1995 ;
1996 genline : KOC_relbr_x expr ',' expr
1997 {
1998 /*unsigned rel_addr = labelloc + 2;*/
1999 /*int dir;*/
2000
2001 SDBD_CHK
2002
2003 emit_location(currseg, currpag, labelloc, TYPE_CODE, currmode);
2004 pevalexpr(1, $2);
2005 pevalexpr(4, $4);
2006
2007 if (evalr[4].seg != SSG_ABS)
2008 fraerror("Must have constant expr for BEXT condition");
2009
2010 evalr[3].seg = SSG_ABS;
2011 evalr[3].value = romw;
2012
2013 locctr += geninstr(findgen($1, ST_EXPEXP, sdbd));
2014 chkover(locctr >> 1, 1);
2015 }
2016 ;
2017
2018
2019 /* ======================================================================== */
2020 /* Implied Operand instructions. */
2021 /* ======================================================================== */
2022 genline : KOC_opcode
2023 {
2024 SDBD_CHK
2025 emit_location(currseg, currpag, labelloc, TYPE_CODE, currmode);
2026 locctr += geninstr(findgen($1, ST_IMP, sdbd));
2027 chkover(locctr >> 1, 1);
2028 }
2029 ;
2030
2031 /* ======================================================================== */
2032 /* Constant Operand instructions. */
2033 /* ======================================================================== */
2034 genline : KOC_opcode expr
2035 {
2036 SDBD_CHK
2037 emit_location(currseg, currpag, labelloc, TYPE_CODE, currmode);
2038 pevalexpr(1, $2);
2039 locctr += geninstr(findgen($1, ST_EXP, sdbd));
2040 chkover(locctr >> 1, 1);
2041 }
2042 ;
2043
2044 /* ======================================================================== */
2045 /* Register, Direct instructions (MVO) */
2046 /* Register, 2 instructions (shifts) */
2047 /* ======================================================================== */
2048 genline : KOC_opcode CP1600_REG ',' expr
2049 {
2050 SDBD_CHK
2051 emit_location(currseg, currpag, labelloc, TYPE_CODE, currmode);
2052 evalr[1].value = $2;
2053 pevalexpr(2, $4);
2054 evalr[3].seg = SSG_ABS;
2055 evalr[3].value = romw;
2056 locctr += geninstr(findgen($1, ST_REGEXP, reg_type[$2]|sdbd));
2057 chkover(locctr >> 1, 1);
2058 }
2059 ;
2060
2061 /* ======================================================================== */
2062 /* Register, Immediate --> MVOI */
2063 /* ======================================================================== */
2064 genline : KOC_opcode CP1600_REG ',' '#' expr
2065 {
2066 SDBD_CHK
2067 emit_location(currseg, currpag, labelloc, TYPE_CODE, currmode);
2068 evalr[1].value = $2;
2069 evalr[3].seg = SSG_ABS;
2070 evalr[3].value = romw;
2071 pevalexpr(2, $5);
2072 locctr += geninstr(findgen($1, ST_REGCEX, reg_type[$2]|sdbd));
2073 chkover(locctr >> 1, 1);
2074 }
2075 ;
2076
2077 /* ======================================================================== */
2078 /* Direct, Register instructions */
2079 /* ======================================================================== */
2080 genline : KOC_opcode expr ',' CP1600_REG
2081 {
2082 SDBD_CHK
2083 emit_location(currseg, currpag, labelloc, TYPE_CODE, currmode);
2084 pevalexpr(1, $2);
2085 evalr[2].value = $4;
2086 evalr[3].seg = SSG_ABS;
2087 evalr[3].value = romw;
2088 locctr += geninstr(findgen($1, ST_EXPREG, reg_type[$4]|sdbd));
2089 chkover(locctr >> 1, 1);
2090 }
2091 ;
2092
2093 /* ======================================================================== */
2094 /* Immediate, Register instructions */
2095 /* ======================================================================== */
2096 genline : KOC_opcode '#' expr ',' CP1600_REG
2097 {
2098 emit_location(currseg, currpag, labelloc, TYPE_CODE, currmode);
2099 pevalexpr(1, $3);
2100 evalr[2].value = $5;
2101
2102 evalr[3].seg = SSG_ABS;
2103 evalr[3].value = romw;
2104
2105 if (sdbd == 0 && romw != 16)
2106 {
2107 if (evalr[1].seg == SSG_ABS &&
2108 (0xFFFF & evalr[1].value & ~romm) != 0)
2109 {
2110 /*frawarn("Constant is wider than ROM width. "
2111 "Inserting SDBD.");*/
2112 locctr += geninstr("0001x");
2113 sdbd = SDBD;
2114 }
2115
2116 if (evalr[1].seg != SSG_ABS && fwd_sdbd)
2117 {
2118 frawarn("Inserting SDBD due to forward reference.");
2119 locctr += geninstr("0001x");
2120 sdbd = SDBD;
2121 }
2122 }
2123
2124 locctr += geninstr(findgen($1, ST_CEXREG, reg_type[$5]|sdbd));
2125 chkover(locctr >> 1, 1);
2126 }
2127 ;
2128
2129 /* ======================================================================== */
2130 /* Single-register instructions. */
2131 /* ======================================================================== */
2132 genline : KOC_opcode CP1600_REG
2133 {
2134 SDBD_CHK
2135 emit_location(currseg, currpag, labelloc, TYPE_CODE, currmode);
2136 evalr[1].value = $2;
2137 locctr += geninstr(findgen($1, ST_REG, reg_type[$2]|sdbd));
2138 chkover(locctr >> 1, 1);
2139 }
2140 ;
2141
2142 /* ======================================================================== */
2143 /* Register, Register instructions. */
2144 /* ======================================================================== */
2145 genline : KOC_opcode CP1600_REG ',' CP1600_REG
2146 {
2147 SDBD_CHK
2148 emit_location(currseg, currpag, labelloc, TYPE_CODE, currmode);
2149 evalr[1].value = $2;
2150 evalr[2].value = $4;
2151 locctr += geninstr(findgen($1, ST_REGREG, reg_type[$2]|sdbd));
2152 chkover(locctr >> 1, 1);
2153 }
2154 ;
2155
2156 /* ======================================================================== */
2157 /* Register, Register instructions, indirect via first register. */
2158 /* ======================================================================== */
2159 genline : KOC_opcode_i CP1600_REG ',' CP1600_REG
2160 {
2161 emit_location(currseg, currpag, labelloc, TYPE_CODE, currmode);
2162 evalr[1].value = $2;
2163 evalr[2].value = $4;
2164 locctr += geninstr(findgen($1, ST_REGREG, reg_type[$2]|sdbd));
2165 chkover(locctr >> 1, 1);
2166 }
2167 ;
2168
2169
2170 /* ======================================================================== */
2171 /* Expression definition. */
2172 /* ======================================================================== */
2173 expr : '+' expr %prec KEOP_MUN
2174 {
2175 $$ = $2;
2176 }
2177 | '-' expr %prec KEOP_MUN
2178 {
2179 $$ = exprnode(PCCASE_UN,$2,IFC_NEG,0,0L, SYMNULL);
2180 }
2181 | KEOP_NOT expr
2182 {
2183 $$ = exprnode(PCCASE_UN,$2,IFC_NOT,0,0L, SYMNULL);
2184 }
2185 | KEOP_HIGH expr
2186 {
2187 $$ = exprnode(PCCASE_UN,$2,IFC_HIGH,0,0L, SYMNULL);
2188 }
2189 | KEOP_LOW expr
2190 {
2191 $$ = exprnode(PCCASE_UN,$2,IFC_LOW,0,0L, SYMNULL);
2192 }
2193 | expr '*' expr
2194 {
2195 $$ = exprnode(PCCASE_BIN,$1,IFC_MUL,$3,0L, SYMNULL);
2196 }
2197 | expr '/' expr
2198 {
2199 $$ = exprnode(PCCASE_BIN,$1,IFC_DIV,$3,0L, SYMNULL);
2200 }
2201 | expr '+' expr
2202 {
2203 $$ = exprnode(PCCASE_BIN,$1,IFC_ADD,$3,0L, SYMNULL);
2204 }
2205 | expr '-' expr
2206 {
2207 $$ = exprnode(PCCASE_BIN,$1,IFC_SUB,$3,0L, SYMNULL);
2208 }
2209 | expr KEOP_MOD expr
2210 {
2211 $$ = exprnode(PCCASE_BIN,$1,IFC_MOD,$3,0L, SYMNULL);
2212 }
2213 | expr KEOP_SHL expr
2214 {
2215 $$ = exprnode(PCCASE_BIN,$1,IFC_SHL,$3,0L, SYMNULL);
2216 }
2217 | expr KEOP_SHR expr
2218 {
2219 $$ = exprnode(PCCASE_BIN,$1,IFC_SHR,$3,0L, SYMNULL);
2220 }
2221 | expr KEOP_SHRU expr
2222 {
2223 $$ = exprnode(PCCASE_BIN,$1,IFC_SHRU,$3,0L, SYMNULL);
2224 }
2225 | expr KEOP_ROTL expr
2226 {
2227 const int ifc = $2 == 16 ? IFC_ROTL16 : IFC_ROTL32;
2228 $$ = exprnode(PCCASE_BIN,$1,ifc,$3,0L, SYMNULL);
2229 }
2230 | expr KEOP_ROTR expr
2231 {
2232 const int ifc = $2 == 16 ? IFC_ROTL16 : IFC_ROTL32;
2233 const int neg = exprnode(PCCASE_UN,$3,IFC_NEG,0,0L, SYMNULL);
2234 $$ = exprnode(PCCASE_BIN,$1,ifc,neg,0L, SYMNULL);
2235 }
2236 | expr KEOP_GT expr
2237 {
2238 $$ = exprnode(PCCASE_BIN,$1,IFC_GT,$3,0L, SYMNULL);
2239 }
2240 | expr KEOP_GE expr
2241 {
2242 $$ = exprnode(PCCASE_BIN,$1,IFC_GE,$3,0L, SYMNULL);
2243 }
2244 | expr KEOP_LT expr
2245 {
2246 $$ = exprnode(PCCASE_BIN,$1,IFC_LT,$3,0L, SYMNULL);
2247 }
2248 | expr KEOP_LE expr
2249 {
2250 $$ = exprnode(PCCASE_BIN,$1,IFC_LE,$3,0L, SYMNULL);
2251 }
2252 | expr KEOP_NE expr
2253 {
2254 $$ = exprnode(PCCASE_BIN,$1,IFC_NE,$3,0L, SYMNULL);
2255 }
2256 | expr KEOP_EQ expr
2257 {
2258 $$ = exprnode(PCCASE_BIN,$1,IFC_EQ,$3,0L, SYMNULL);
2259 }
2260 | expr KEOP_AND expr
2261 {
2262 $$ = exprnode(PCCASE_BIN,$1,IFC_AND,$3,0L, SYMNULL);
2263 }
2264 | expr KEOP_OR expr
2265 {
2266 $$ = exprnode(PCCASE_BIN,$1,IFC_OR,$3,0L, SYMNULL);
2267 }
2268 | expr KEOP_XOR expr
2269 {
2270 $$ = exprnode(PCCASE_BIN,$1,IFC_XOR,$3,0L, SYMNULL);
2271 }
2272 | KEOP_DEFINED symbol
2273 {
2274 $$ = exprnode(PCCASE_DEF,0,IGP_DEFINED,0,0L,$2);
2275 }
2276 | symbol %prec SYMBOL
2277 {
2278 $$ = exprnode(PCCASE_SYMB,0,IFC_SYMB,0,0L,$1);
2279 }
2280 | KEOP_DEFINED FEATURE
2281 {
2282 $$ = exprnode(PCCASE_CONS,0,IGP_CONSTANT,0,$2, SYMNULL);
2283 }
2284 | FEATURE
2285 {
2286 $$ = exprnode(PCCASE_CONS,0,IGP_CONSTANT,0,$1, SYMNULL);
2287 }
2288 | '$'
2289 {
2290 $$ = exprnode(PCCASE_PROGC,0,IFC_PROGCTR,0,labelloc,SYMNULL);
2291 }
2292 | CONSTANT
2293 {
2294 $$ = exprnode(PCCASE_CONS,0,IGP_CONSTANT,0,$1, SYMNULL);
2295 }
2296 | QCHAR
2297 {
2298 char st[2] = { $1, 0 }, *s = st;
2299 int accval = chtran(&s);
2300 $$ = exprnode(PCCASE_CONS,0,IGP_CONSTANT,0,accval,SYMNULL);
2301 }
2302 | KEOP_CLASSIFY '(' ')' %prec KEOP_CLASSIFY
2303 {
2304 $$ = exprnode(PCCASE_CONS,0,IGP_CONSTANT,0,CLASS_EMPTY,SYMNULL);
2305 }
2306 | KEOP_CLASSIFY '(' CP1600_REG ')' %prec KEOP_CLASSIFY
2307 {
2308 $$ = exprnode(PCCASE_CONS,0,IGP_CONSTANT,0, $3, SYMNULL);
2309 }
2310 | KEOP_CLASSIFY '(' FEATURE ')' %prec KEOP_CLASSIFY
2311 {
2312 $$ = exprnode(PCCASE_CONS,0,IGP_CONSTANT,0,CLASS_FEATURE,
2313 SYMNULL);
2314 }
2315 | KEOP_CLASSIFY '(' keyword ')' %prec KEOP_CLASSIFY
2316 {
2317 $$ = exprnode(PCCASE_CONS,0,IGP_CONSTANT,0,CLASS_RESV,SYMNULL);
2318 }
2319 | KEOP_CLASSIFY '(' string ')' %prec KEOP_CLASSIFY
2320 {
2321 $$ = exprnode(PCCASE_CONS,0,IGP_CONSTANT,0,CLASS_STRING,
2322 SYMNULL);
2323 }
2324 | KEOP_CLASSIFY '(' symbol ')' %prec KEOP_CLASSIFY
2325 {
2326 $$ = exprnode(PCCASE_CLASSSYM,0,IFC_CLASSIFY,0,0L,$3);
2327 }
2328 | KEOP_CLASSIFY '(' expr ')' %prec KEOP_CLASSIFY
2329 {
2330 $$ = exprnode(PCCASE_UN,$3,IFC_CLASSIFY,0,0L, SYMNULL);
2331 }
2332 | KEOP_STRLEN '(' string ')'
2333 {
2334 char *s = $3;
2335 int accval = 0;
2336 int length = 0;
2337
2338 while (*s)
2339 {
2340 accval = chtran(&s);
2341 length++;
2342 }
2343 (void)accval;
2344 $$ = exprnode(PCCASE_CONS,0,IGP_CONSTANT,0,length++,SYMNULL);
2345 }
2346 | KEOP_STRLEN '(' QCHAR ')'
2347 {
2348 $$ = exprnode(PCCASE_CONS,0,IGP_CONSTANT,0,1,SYMNULL);
2349 }
2350 | KEOP_ASC '(' string ',' expr ')'
2351 {
2352 char *s = $3;
2353 int accval = 0;
2354 int sindex = 0;
2355
2356 pevalexpr(0, $5);
2357 if(evalr[0].seg == SSG_ABS)
2358 {
2359 sindex = evalr[0].value;
2360 while (*s && sindex >= 0)
2361 {
2362 accval = chtran(&s);
2363 sindex--;
2364 }
2365 if (sindex >= 0)
2366 accval = 0;
2367
2368 $$ = exprnode(PCCASE_CONS,0,IGP_CONSTANT,0,accval,SYMNULL);
2369 }
2370 else
2371 {
2372 fraerror("noncomputable expression for index to ASC");
2373 }
2374 }
2375 | KEOP_ASC '(' QCHAR ',' expr ')'
2376 {
2377 char st[2] = { $3, 0 }, *s = st;
2378 int accval = 0;
2379
2380 pevalexpr(0, $5);
2381 if(evalr[0].seg == SSG_ABS)
2382 {
2383 accval = evalr[0].value == 0 ? chtran(&s) : 0;
2384 $$ = exprnode(PCCASE_CONS,0,IGP_CONSTANT,0,accval,SYMNULL);
2385 }
2386 else
2387 {
2388 fraerror("noncomputable expression for index to ASC");
2389 }
2390 }
2391 | '(' expr ')' { $$ = $2; }
2392 | '(' exprlist ')' '[' expr ']' %prec '('
2393 {
2394 pevalexpr(0, $5);
2395 if (evalr[0].seg == SSG_ABS)
2396 {
2397 const int idx = evalr[0].value;
2398 if (idx < $2->len)
2399 $$ = $2->data[idx];
2400 else
2401 $$ = exprnode(PCCASE_CONS,0,IGP_CONSTANT,0,0,SYMNULL);
2402 }
2403 else
2404 {
2405 fraerror("noncomputable expression for expr-list index");
2406 }
2407 intvec_delete($2);
2408 }
2409 ;
2410
2411 /* ======================================================================== */
2412 /* Array-indexed labels and symbols */
2413 /* ======================================================================== */
2414 label: LABEL
2415 | label '[' expr ']'
2416 {
2417 pevalexpr(0, $3);
2418 if (evalr[0].seg == SSG_ABS)
2419 {
2420 $$ = symbentryidx($1->symstr, LABEL, 1, evalr[0].value);
2421 $$->flags |= SFLAG_QUIET | SFLAG_ARRAY;
2422
2423 /* track "high water mark" in LABEL's own value */
2424 $1->seg = SSG_SET;
2425 $1->flags |= SFLAG_QUIET;
2426 if ($1->value < evalr[0].value)
2427 $1->value = evalr[0].value;
2428 } else
2429 {
2430 fraerror("noncomputable expression for label array index");
2431 }
2432 }
2433 ;
2434
2435 symbol: SYMBOL
2436 | symbol '[' expr ']'
2437 {
2438 pevalexpr(0, $3);
2439 if (evalr[0].seg == SSG_ABS)
2440 {
2441 $$ = symbentryidx($1->symstr, LABEL, 1, evalr[0].value);
2442 $$->flags |= SFLAG_QUIET | SFLAG_ARRAY;
2443
2444 /* track "high water mark" in LABEL's own value */
2445 $1->seg = SSG_SET;
2446 $1->flags |= SFLAG_QUIET;
2447 if ($1->value < evalr[0].value)
2448 $1->value = evalr[0].value;
2449 } else
2450 {
2451 fraerror("noncomputable expression for symbol array index");
2452 }
2453 }
2454 ;
2455
2456
2457 symslice: symbol '[' expr ',' expr ']'
2458 {
2459 intvec_t *const RESTRICT iv = intvec_new();
2460 pevalexpr(0, $3);
2461 pevalexpr(1, $5);
2462
2463 if (evalr[0].seg != SSG_ABS || evalr[1].seg != SSG_ABS)
2464 {
2465 fraerror("noncomputable expression for symbol slice index");
2466 $$ = iv;
2467 } else
2468 {
2469 int i, s;
2470
2471 s = evalr[0].value > evalr[1].value ? -1 : 1;
2472
2473 for (i = evalr[0].value; i != evalr[1].value + s; i += s)
2474 {
2475 struct symel *sym;
2476 intvec_push(iv,
2477 exprnode(PCCASE_SYMB,0,IFC_SYMB,0,0L,
2478 sym = symbentryidx($1->symstr, LABEL, 1, i)));
2479
2480 sym->flags |= SFLAG_ARRAY | SFLAG_QUIET;
2481 }
2482 $$ = iv;
2483 }
2484 }
2485 | '(' exprlist ')' '[' expr ',' expr ']' %prec '('
2486 {
2487 pevalexpr(0, $5);
2488 pevalexpr(1, $7);
2489 if (evalr[0].seg != SSG_ABS || evalr[1].seg != SSG_ABS)
2490 {
2491 fraerror(
2492 "noncomputable expression for expr-list slice index");
2493 intvec_resize($2, 0);
2494 $$ = $2;
2495 } else if (evalr[0].value >= $2->len ||
2496 evalr[1].value >= $2->len)
2497 {
2498 fraerror("out of range index for expr-list slice");
2499 intvec_resize($2, 0);
2500 $$ = $2;
2501 } else
2502 {
2503 const int rev = evalr[0].value > evalr[1].value;
2504 const int lo = rev ? evalr[1].value : evalr[0].value;
2505 const int hi = rev ? evalr[0].value : evalr[1].value;
2506 const int cnt = hi - lo + 1;
2507 int *const data = $2->data;
2508
2509 memmove(&data[0], &data[lo], sizeof(data[0]) * cnt);
2510
2511 if (rev)
2512 {
2513 int i, j;
2514 for (i = 0, j = cnt - 1; i < j; i++, j--)
2515 {
2516 const int tmp = $2->data[i];
2517 $2->data[i] = $2->data[j];
2518 $2->data[j] = tmp;
2519 }
2520 }
2521 $2->len = cnt;
2522 $$ = $2;
2523 }
2524 }
2525 | symslice '[' expr ']'
2526 {
2527 fraerror("array slice allowed on last index only");
2528 $$ = intvec_new();
2529 }
2530 | symslice '[' expr ',' expr ']'
2531 {
2532 fraerror("array slice allowed on last index only");
2533 $$ = intvec_new();
2534 }
2535 ;
2536
2537
2538 labelslice: label '[' expr ',' expr ']'
2539 {
2540 pevalexpr(0, $3);
2541 pevalexpr(1, $5);
2542
2543 if (evalr[0].seg != SSG_ABS || evalr[1].seg != SSG_ABS)
2544 {
2545 fraerror("noncomputable expression for label slice index");
2546 } else
2547 {
2548 $$.first = evalr[0].value;
2549 $$.last = evalr[1].value;
2550 $$.sym = $1;
2551 }
2552 }
2553 | labelslice '[' expr ']'
2554 {
2555 fraerror("array slice allowed on last index only");
2556 }
2557 | labelslice '[' expr ',' expr ']'
2558 {
2559 fraerror("array slice allowed on last index only");
2560 }
2561 ;
2562
2563 /* Keyword catch-all for CLASSIFY operator */
2564 keyword : KEOP_AND
2565 | KEOP_DEFINED
2566 | KEOP_EQ
2567 | KEOP_GE
2568 | KEOP_GT
2569 | KEOP_HIGH
2570 | KEOP_LE
2571 | KEOP_LOW
2572 | KEOP_LT
2573 | KEOP_MOD
2574 | KEOP_MUN
2575 | KEOP_NE
2576 | KEOP_NOT
2577 | KEOP_OR
2578 | KEOP_SHL
2579 | KEOP_SHR
2580 | KEOP_SHRU
2581 | KEOP_XOR
2582 | KEOP_locctr
2583 | KEOP_STRLEN
2584 | KEOP_ASC
2585 | KEOP_CLASSIFY
2586 ;
2587 %%
2588
2589 int lexintercept(void)
2590 /*
2591 description intercept the call to yylex (the lexical analyzer)
2592 and filter out all unnecessary tokens when skipping
2593 the input between a failed IF and its matching ENDI or
2594 ELSE
2595 globals fraifskip the enable flag
2596 */
2597 {
2598 #undef yylex
2599 int rv;
2600
2601 if (!(frarptskip | fraifskip))
2602 {
2603 int token = yylex();
2604 return token;
2605 }
2606
2607 if(frarptskip)
2608 {
2609 for(;;)
2610 {
2611
2612 switch(rv = yylex())
2613 {
2614 case 0:
2615 case KOC_END:
2616 case KOC_ENDR:
2617 case EOL:
2618 return rv;
2619 case KOC_RPT:
2620 frarptpush(0); /* push a dummy loop */
2621 default:
2622 break;
2623 }
2624 }
2625 } else if(fraifskip)
2626 {
2627 for(;;)
2628 {
2629
2630 switch(rv = yylex())
2631 {
2632 case 0:
2633 case KOC_END:
2634 case KOC_IF:
2635 case KOC_ELSE:
2636 case KOC_ENDI:
2637 case KEOP_EXPMAC:
2638 case EOL:
2639 return rv;
2640 default:
2641 break;
2642 }
2643 }
2644 } else
2645 {
2646 int token = yylex();
2647 return token;
2648 }
2649
2650 #define yylex lexintercept
2651 }
2652
2653
2654
setreserved(void)2655 void setreserved(void)
2656 {
2657 reservedsym("and", KEOP_AND, 0);
2658 reservedsym("defined", KEOP_DEFINED, 0);
2659 reservedsym("ge", KEOP_GE, 0);
2660 reservedsym("high", KEOP_HIGH, 0);
2661 reservedsym("le", KEOP_LE, 0);
2662 reservedsym("low", KEOP_LOW, 0);
2663 reservedsym("mod", KEOP_MOD, 0);
2664 reservedsym("ne", KEOP_NE, 0);
2665 reservedsym("not", KEOP_NOT, 0);
2666 reservedsym("or", KEOP_OR, 0);
2667 reservedsym("shl", KEOP_SHL, 0);
2668 reservedsym("shr", KEOP_SHR, 0);
2669 reservedsym("shru", KEOP_SHRU, 0);
2670 reservedsym("xor", KEOP_XOR, 0);
2671 reservedsym("AND", KEOP_AND, 0);
2672 reservedsym("DEFINED", KEOP_DEFINED, 0);
2673 reservedsym("GE", KEOP_GE, 0);
2674 reservedsym("HIGH", KEOP_HIGH, 0);
2675 reservedsym("LE", KEOP_LE, 0);
2676 reservedsym("LOW", KEOP_LOW, 0);
2677 reservedsym("MOD", KEOP_MOD, 0);
2678 reservedsym("NE", KEOP_NE, 0);
2679 reservedsym("NOT", KEOP_NOT, 0);
2680 reservedsym("OR", KEOP_OR, 0);
2681 reservedsym("SHL", KEOP_SHL, 0);
2682 reservedsym("SHR", KEOP_SHR, 0);
2683 reservedsym("SHRU", KEOP_SHRU, 0);
2684 reservedsym("_ROTL16", KEOP_ROTL, 16);
2685 reservedsym("_ROTL32", KEOP_ROTL, 32);
2686 reservedsym("_ROTR16", KEOP_ROTR, 16);
2687 reservedsym("_ROTR32", KEOP_ROTR, 32);
2688 reservedsym("XOR", KEOP_XOR, 0);
2689 reservedsym("STRLEN", KEOP_STRLEN, 0);
2690 reservedsym("ASC", KEOP_ASC, 0);
2691 reservedsym("CLASSIFY", KEOP_CLASSIFY, 0);
2692 reservedsym("TODAY_STR_LOC", KEOP_TODAY_STR, 0);
2693 reservedsym("TODAY_STR_GMT", KEOP_TODAY_STR, 1);
2694 reservedsym("TODAY_VAL_LOC", KEOP_TODAY_VAL, 0);
2695 reservedsym("TODAY_VAL_GMT", KEOP_TODAY_VAL, 1);
2696 reservedsym("_EXPMAC", KEOP_EXPMAC, 1);
2697
2698 /* machine specific token definitions */
2699 reservedsym("r0", CP1600_REG, 0);
2700 reservedsym("r1", CP1600_REG, 1);
2701 reservedsym("r2", CP1600_REG, 2);
2702 reservedsym("r3", CP1600_REG, 3);
2703 reservedsym("r4", CP1600_REG, 4);
2704 reservedsym("r5", CP1600_REG, 5);
2705 reservedsym("r6", CP1600_REG, 6);
2706 reservedsym("r7", CP1600_REG, 7);
2707 reservedsym("sp", CP1600_REG, 6);
2708 reservedsym("pc", CP1600_REG, 7);
2709 reservedsym("R0", CP1600_REG, 0);
2710 reservedsym("R1", CP1600_REG, 1);
2711 reservedsym("R2", CP1600_REG, 2);
2712 reservedsym("R3", CP1600_REG, 3);
2713 reservedsym("R4", CP1600_REG, 4);
2714 reservedsym("R5", CP1600_REG, 5);
2715 reservedsym("R6", CP1600_REG, 6);
2716 reservedsym("R7", CP1600_REG, 7);
2717 reservedsym("SP", CP1600_REG, 6);
2718 reservedsym("PC", CP1600_REG, 7);
2719
2720 reservedsym("__FEATURE.MACRO", FEATURE, 99);
2721 reservedsym("__FEATURE.CFGVAR", FEATURE, 99);
2722 reservedsym("__FEATURE.SRCFILE", FEATURE, 99);
2723 reservedsym("__FEATURE.CLASSIFY", FEATURE, 99);
2724 reservedsym("__FEATURE.TODAY", FEATURE, 99);
2725 reservedsym("__FEATURE.ROTATE", FEATURE, 99);
2726 reservedsym("__FEATURE.EXPMAC", FEATURE, 99);
2727 reservedsym("__FEATURE.LISTCOL", FEATURE, 99);
2728 reservedsym("__FEATURE.OVERWRITE", FEATURE, 99);
2729 reservedsym("MACRO", FEATURE, 99);
2730 reservedsym("ENDM", FEATURE, 99);
2731 }
2732
cpumatch(char * str)2733 int cpumatch(char *str)
2734 {
2735 (void)str;
2736 return TRUE;
2737 }
2738
2739
2740 /* ======================================================================== */
2741 /* Opcode and Instruction Generation Tables */
2742 /* */
2743 /* These tables are used by the assembler framework to generate */
2744 /* instructions from the parsed input. */
2745 /* */
2746 /* OPTAB -- OPcode TABle. Contains the set of supported mnemonics. */
2747 /* OSTAB -- Opcode Syntax TABle. Syntax definition sets for instrs. */
2748 /* IGTAB -- Instruction Generation TABle. Contains RPN code for */
2749 /* generating the instructions. */
2750 /* ======================================================================== */
2751
2752
2753
2754 /* ======================================================================== */
2755 /* OPTAB -- OPcode TABle. Contains the set of supported mnemonics. */
2756 /* ======================================================================== */
2757 struct opsym optab[] =
2758 {
2759 { "invalid", KOC_opcode, 2, 0 },
2760
2761 { "MVO", KOC_opcode, 1, 2 },
2762 { "MVI", KOC_opcode, 1, 3 },
2763 { "ADD", KOC_opcode, 1, 4 },
2764 { "SUB", KOC_opcode, 1, 5 },
2765 { "CMP", KOC_opcode, 1, 6 },
2766 { "AND", KOC_opcode, 1, 7 },
2767 { "XOR", KOC_opcode, 1, 8 },
2768
2769 { "MVO@", KOC_opcode, 1, 9 },
2770 { "MVI@", KOC_opcode_i, 1, 10 },
2771 { "ADD@", KOC_opcode_i, 1, 11 },
2772 { "SUB@", KOC_opcode_i, 1, 12 },
2773 { "CMP@", KOC_opcode_i, 1, 13 },
2774 { "AND@", KOC_opcode_i, 1, 14 },
2775 { "XOR@", KOC_opcode_i, 1, 15 },
2776
2777 { "MVOI", KOC_opcode, 1, 16 },
2778 { "MVII", KOC_opcode, 1, 17 },
2779 { "ADDI", KOC_opcode, 1, 18 },
2780 { "SUBI", KOC_opcode, 1, 19 },
2781 { "CMPI", KOC_opcode, 1, 20 },
2782 { "ANDI", KOC_opcode, 1, 21 },
2783 { "XORI", KOC_opcode, 1, 22 },
2784
2785 { "MOVR", KOC_opcode, 1, 24 },
2786 { "ADDR", KOC_opcode, 1, 25 },
2787 { "SUBR", KOC_opcode, 1, 26 },
2788 { "CMPR", KOC_opcode, 1, 27 },
2789 { "ANDR", KOC_opcode, 1, 28 },
2790 { "XORR", KOC_opcode, 1, 29 },
2791
2792 { "B", KOC_relbr, 1, 30 },
2793 { "BC", KOC_relbr, 1, 31 },
2794 { "BOV", KOC_relbr, 1, 32 },
2795 { "BPL", KOC_relbr, 1, 33 },
2796 { "BZE", KOC_relbr, 1, 34 },
2797 { "BEQ", KOC_relbr, 1, 34 },
2798 { "BLT", KOC_relbr, 1, 35 },
2799 { "BNGE", KOC_relbr, 1, 35 },
2800 { "BLE", KOC_relbr, 1, 36 },
2801 { "BNGT", KOC_relbr, 1, 36 },
2802 { "BUSC", KOC_relbr, 1, 37 },
2803
2804 { "NOPP", KOC_opcode, 2, 92 },
2805 { "BNC", KOC_relbr, 1, 39 },
2806 { "BNOV", KOC_relbr, 1, 40 },
2807 { "BMI", KOC_relbr, 1, 41 },
2808 { "BNZE", KOC_relbr, 1, 42 },
2809 { "BNZ", KOC_relbr, 1, 42 },
2810 { "BNEQ", KOC_relbr, 1, 42 },
2811 { "BNE", KOC_relbr, 1, 42 },
2812 { "BGE", KOC_relbr, 1, 43 },
2813 { "BNLT", KOC_relbr, 1, 43 },
2814 { "BGT", KOC_relbr, 1, 44 },
2815 { "BNLE", KOC_relbr, 1, 44 },
2816 { "BESC", KOC_relbr, 1, 45 },
2817
2818 { "BEXT", KOC_relbr_x, 1, 96 },
2819
2820 { "SWAP", KOC_opcode, 2, 46 },
2821 { "SLL", KOC_opcode, 2, 48 },
2822 { "RLC", KOC_opcode, 2, 50 },
2823 { "SLLC", KOC_opcode, 2, 52 },
2824 { "SLR", KOC_opcode, 2, 54 },
2825 { "SAR", KOC_opcode, 2, 56 },
2826 { "RRC", KOC_opcode, 2, 58 },
2827 { "SARC", KOC_opcode, 2, 60 },
2828
2829 { "NOP", KOC_opcode, 1, 62 },
2830 { "NOP2", KOC_opcode, 1, 94 },
2831 { "SIN", KOC_opcode, 1, 63 },
2832 { "SIN2", KOC_opcode, 1, 95 },
2833
2834 { "J", KOC_opcode, 1, 64 },
2835 { "JE", KOC_opcode, 1, 65 },
2836 { "JD", KOC_opcode, 1, 66 },
2837 { "JSR", KOC_opcode, 1, 67 },
2838 { "JSRE", KOC_opcode, 1, 68 },
2839 { "JSRD", KOC_opcode, 1, 69 },
2840
2841 { "INCR", KOC_opcode, 1, 70 },
2842 { "DECR", KOC_opcode, 1, 71 },
2843 { "COMR", KOC_opcode, 1, 72 },
2844 { "NEGR", KOC_opcode, 1, 73 },
2845 { "ADCR", KOC_opcode, 1, 74 },
2846 { "GSWD", KOC_opcode, 1, 75 },
2847 { "RSWD", KOC_opcode, 1, 76 },
2848
2849 { "HLT", KOC_opcode, 1, 77 },
2850 { "SDBD", KOC_SDBD, 1, 78 },
2851 { "EIS", KOC_opcode, 1, 79 },
2852 { "DIS", KOC_opcode, 1, 80 },
2853 { "TCI", KOC_opcode, 1, 81 },
2854 { "CLRC", KOC_opcode, 1, 82 },
2855 { "SETC", KOC_opcode, 1, 83 },
2856
2857 { "TSTR", KOC_opcode, 1, 84 }, /* MOVR Rx, Rx */
2858 { "CLRR", KOC_opcode, 1, 85 }, /* XORR Rx, Rx */
2859 { "PSHR", KOC_opcode, 1, 86 }, /* MVO@ Rx, SP */
2860 { "PULR", KOC_opcode, 1, 87 }, /* MVI@ SP, Rx */
2861 { "JR", KOC_opcode, 1, 88 }, /* MOVR Rx, PC */
2862 { "CALL", KOC_opcode, 1, 89 }, /* JSR R5, addr */
2863 { "BEGIN", KOC_opcode, 1, 90 }, /* MVO@ R5, SP */
2864 { "RETURN", KOC_opcode, 1, 91 }, /* MVI@ SP, PC */
2865
2866 { "DECLE", KOC_DDEF, 0, 0 }, /* Generates ROMW values */
2867 { "DCW", KOC_DDEF, 0, 0 }, /* Generates ROMW values */
2868 { "BIDECLE", KOC_WDEF, 0, 0 }, /* Generates SDBD values */
2869 { "ROMWIDTH", KOC_ROMW, 0, 0 },
2870 { "ROMW", KOC_ROMW, 0, 0 },
2871 { "PROC", KOC_PROC, 0, 0 },
2872 { "ENDP", KOC_ENDP, 0, 0 },
2873
2874 { "BYTE", KOC_BDEF, 0, 0 }, /* Generates 8-bit values */
2875 { "CHARDEF", KOC_CHDEF, 0, 0 },
2876 { "CHARSET", KOC_CHSET, 0, 0 },
2877 { "CHARUSE", KOC_CHUSE, 0, 0 },
2878 { "CHD", KOC_CHDEF, 0, 0 },
2879 { "DATA", KOC_DDEF, 0, 0 }, /* Generates ROMW values */
2880 { "DB", KOC_BDEF, 0, 0 }, /* Generates 8-bit values */
2881 { "DW", KOC_WDEF, 0, 0 }, /* Generates SDBD values */
2882 { "ELSE", KOC_ELSE, 0, 0 },
2883 { "END", KOC_END, 0, 0 },
2884 { "ENDI", KOC_ENDI, 0, 0 },
2885 { "EQU", KOC_EQU, 0, 0 },
2886 { "FCB", KOC_BDEF, 0, 0 }, /* Generates 8-bit values */
2887 { "FCC", KOC_SDEF, 0, 0 },
2888 { "FDB", KOC_WDEF, 0, 0 }, /* Generates SDBD values */
2889 { "IF", KOC_IF, 0, 0 },
2890 { "INCL", KOC_INCLUDE, 0, 0 },
2891 { "INCLUDE", KOC_INCLUDE, 0, 0 },
2892 { "ORG", KOC_ORG, 0, 0 },
2893 { "RES", KOC_RESM, 0, 0 },
2894 { "RESERVE", KOC_RESM, 0, 0 },
2895 { "RMB", KOC_RESM, 0, 0 },
2896 { "SET", KOC_SET, 0, 0 },
2897 { "STRING", KOC_SDEF, 0, 0 },
2898 { "WORD", KOC_WDEF, 0, 0 }, /* Generates SDBD values */
2899
2900 { "STRUCT", KOC_STRUCT, 0, 0 }, /* Opens a struct def'n */
2901 { "ENDS", KOC_ENDS, 0, 0 }, /* Closes a struct def'n */
2902
2903 { "MEMATTR", KOC_MEMATTR, 0, 0 }, /* Set memory attributes */
2904
2905 { "RPT", KOC_RPT, 0, 0 }, /* Repeat a block of code */
2906 { "REPEAT", KOC_RPT, 0, 0 }, /* Repeat a block of code */
2907 { "ENDR", KOC_ENDR, 0, 0 }, /* End repeated block */
2908
2909 { "ERR", KOC_USRERR, 0, 0 }, /* User-designated error */
2910
2911 { "STRLEN", KEOP_STRLEN, 0, 0 }, /* Returns length of string */
2912 { "ASC", KEOP_ASC, 0, 0 }, /* ASCII val of char in str */
2913
2914 { "LISTING", KOC_LIST, 0, 0 }, /* Assembler listing control */
2915 { "QEQU", KOC_QEQU, 0, 0 }, /* EQU and mark as "quiet" */
2916 { "QSET", KOC_QSET, 0, 0 }, /* SET and mark as "quiet" */
2917
2918 { "MACRO", KOC_MACERR, 0, 0 }, /* We shouldn't see MACRO */
2919 { "ENDM", KOC_MACERR, 0, 0 }, /* We shouldn't see ENDM */
2920
2921 { "BRKIF", KOC_BRKIF, 0, 0 }, /* Break out of RPT if true */
2922
2923 { "CMSG", KOC_CMSG, 0, 0 }, /* Comment message in listing */
2924 { "SMSG", KOC_SMSG, 0, 0 }, /* Status message to stdout */
2925 { "WMSG", KOC_WMSG, 0, 0 }, /* Warning message */
2926
2927 { "CFGVAR", KOC_CFGVAR, 0, 0 }, /* Configuration variable */
2928
2929 { "SRCFILE", KOC_SRCFILE, 0, 0 }, /* HLL source file / line */
2930 { "LISTCOL", KOC_LISTCOL, 0, 0 }, /* Listing formatting */
2931 { "ERR_IF_OVERWRITTEN",
2932 KOC_ERR_IF_OVERWRITTEN, 0, 0 }, /* ROM overwrite control */
2933 { "FORCE_OVERWRITE",
2934 KOC_FORCE_OVERWRITE, 0, 0 }, /* ROM overwrite control */
2935 { "", 0, 0, 0 }
2936 };
2937
2938
2939 /* ======================================================================== */
2940 /* OSTAB -- Opcode Syntax TABle. Syntax definition sets for instrs. */
2941 /* */
2942 /* Legend: */
2943 /* REG Register. */
2944 /* EXP EXPression */
2945 /* CEX Constant EXpression (eg. exp. prefixed w/ #). */
2946 /* IMP Implied operand. */
2947 /* ======================================================================== */
2948 struct opsynt ostab[] =
2949 {
2950 /* invalid 0 */ { 0, 1, 0 },
2951 /* invalid 1 */ { 0xFFFF, 1, 1 },
2952
2953 /* MVO 2 */ { ST_REGEXP, 1, 2 },
2954 /* MVI 3 */ { ST_EXPREG, 1, 3 },
2955 /* ADD 4 */ { ST_EXPREG, 1, 4 },
2956 /* SUB 5 */ { ST_EXPREG, 1, 5 },
2957 /* CMP 6 */ { ST_EXPREG, 1, 6 },
2958 /* AND 7 */ { ST_EXPREG, 1, 7 },
2959 /* XOR 8 */ { ST_EXPREG, 1, 8 },
2960
2961 /* MVO@ 9 */ { ST_REGREG, 1, 9 },
2962 /* MVI@ 10 */ { ST_REGREG, 1, 10 },
2963 /* ADD@ 11 */ { ST_REGREG, 1, 11 },
2964 /* SUB@ 12 */ { ST_REGREG, 1, 12 },
2965 /* CMP@ 13 */ { ST_REGREG, 1, 13 },
2966 /* AND@ 14 */ { ST_REGREG, 1, 14 },
2967 /* XOR@ 15 */ { ST_REGREG, 1, 15 },
2968
2969 /* MVOI 16 */ { ST_REGCEX, 1, 16 },
2970 /* MVII 17 */ { ST_CEXREG, 2, 17 },
2971 /* ADDI 18 */ { ST_CEXREG, 2, 19 },
2972 /* SUBI 19 */ { ST_CEXREG, 2, 21 },
2973 /* CMPI 20 */ { ST_CEXREG, 2, 23 },
2974 /* ANDI 21 */ { ST_CEXREG, 2, 25 },
2975 /* XORI 22 */ { ST_CEXREG, 2, 27 },
2976
2977 /* unused 23 */ { 0, 1, 0 }, /* oops */
2978 /* MOVR 24 */ { ST_REGREG, 1, 29 },
2979 /* ADDR 25 */ { ST_REGREG, 1, 30 },
2980 /* SUBR 26 */ { ST_REGREG, 1, 31 },
2981 /* CMPR 27 */ { ST_REGREG, 1, 32 },
2982 /* ANDR 28 */ { ST_REGREG, 1, 33 },
2983 /* XORR 29 */ { ST_REGREG, 1, 34 },
2984
2985 /* B 30 */ { ST_EXP, 1, 35 },
2986 /* BC 31 */ { ST_EXP, 1, 36 },
2987 /* BOV 32 */ { ST_EXP, 1, 37 },
2988 /* BPL 33 */ { ST_EXP, 1, 38 },
2989 /* BEQ 34 */ { ST_EXP, 1, 39 },
2990 /* BLT 35 */ { ST_EXP, 1, 40 },
2991 /* BLE 36 */ { ST_EXP, 1, 41 },
2992 /* BUSC 37 */ { ST_EXP, 1, 42 },
2993
2994 /* unused 38 */ { 0, 1, 0 }, /* oops */
2995 /* BNC 39 */ { ST_EXP, 1, 44 },
2996 /* BNOV 40 */ { ST_EXP, 1, 45 },
2997 /* BMI 41 */ { ST_EXP, 1, 46 },
2998 /* BNEQ 42 */ { ST_EXP, 1, 47 },
2999 /* BGE 43 */ { ST_EXP, 1, 48 },
3000 /* BGT 44 */ { ST_EXP, 1, 49 },
3001 /* BESC 45 */ { ST_EXP, 1, 50 },
3002
3003 /* SWAP 46 */ { ST_REG, 1, 51 },
3004 /* SWAP 47 */ { ST_REGEXP, 1, 52 },
3005 /* SLL 48 */ { ST_REG, 1, 53 },
3006 /* SLL 49 */ { ST_REGEXP, 1, 54 },
3007 /* RLC 50 */ { ST_REG, 1, 55 },
3008 /* RLC 51 */ { ST_REGEXP, 1, 56 },
3009 /* SLLC 52 */ { ST_REG, 1, 57 },
3010 /* SLLC 53 */ { ST_REGEXP, 1, 58 },
3011 /* SLR 54 */ { ST_REG, 1, 59 },
3012 /* SLR 55 */ { ST_REGEXP, 1, 60 },
3013 /* SAR 56 */ { ST_REG, 1, 61 },
3014 /* SAR 57 */ { ST_REGEXP, 1, 62 },
3015 /* RRC 58 */ { ST_REG, 1, 63 },
3016 /* RRC 59 */ { ST_REGEXP, 1, 64 },
3017 /* SARC 60 */ { ST_REG, 1, 65 },
3018 /* SARC 61 */ { ST_REGEXP, 1, 66 },
3019
3020 /* NOP 62 */ { ST_IMP, 1, 67 },
3021 /* SIN 63 */ { ST_IMP, 1, 68 },
3022
3023 /* J 64 */ { ST_EXP, 1, 69 },
3024 /* JE 65 */ { ST_EXP, 1, 70 },
3025 /* JD 66 */ { ST_EXP, 1, 71 },
3026 /* JSR 67 */ { ST_REGEXP, 1, 72 },
3027 /* JSRE 68 */ { ST_REGEXP, 1, 73 },
3028 /* JSRD 69 */ { ST_REGEXP, 1, 74 },
3029
3030 /* INCR 70 */ { ST_REG, 1, 75 },
3031 /* DECR 71 */ { ST_REG, 1, 76 },
3032 /* COMR 72 */ { ST_REG, 1, 77 },
3033 /* NEGR 73 */ { ST_REG, 1, 78 },
3034 /* ADCR 74 */ { ST_REG, 1, 79 },
3035 /* GSWD 75 */ { ST_REG, 1, 80 },
3036 /* RSWD 76 */ { ST_REG, 1, 81 },
3037
3038 /* HLT 77 */ { ST_IMP, 1, 82 },
3039 /* SDBD 78 */ { ST_IMP, 1, 83 },
3040 /* EIS 79 */ { ST_IMP, 1, 84 },
3041 /* DIS 80 */ { ST_IMP, 1, 85 },
3042 /* TCI 81 */ { ST_IMP, 1, 86 },
3043 /* CLRC 82 */ { ST_IMP, 1, 87 },
3044 /* SETC 83 */ { ST_IMP, 1, 88 },
3045
3046 /* TSTR 84 */ { ST_REG, 1, 89 },
3047 /* CLRR 85 */ { ST_REG, 1, 90 },
3048 /* PSHR 86 */ { ST_REG, 1, 91 },
3049 /* PULR 87 */ { ST_REG, 1, 92 },
3050 /* JR 88 */ { ST_REG, 1, 93 },
3051 /* CALL 89 */ { ST_EXP, 1, 94 },
3052 /* BEGIN 90 */ { ST_IMP, 1, 95 },
3053 /* RETURN 91 */ { ST_IMP, 1, 96 },
3054
3055 /* NOPP 92 */ { ST_EXP, 1, 43 },
3056 /* NOPP 93 */ { ST_IMP, 1, 97 },
3057
3058 /* NOP2 94 */ { ST_IMP, 1, 98 },
3059 /* SIN2 95 */ { ST_IMP, 1, 99 },
3060
3061 /* BEXT 95 */ { ST_EXPEXP, 1, 100 },
3062
3063 /* end */ { 0, 0, 0 }
3064 };
3065
3066
3067 /* ======================================================================== */
3068 /* Helper macros. */
3069 /* MVO_OK Tests arg 2 to make sure it's R1 .. R6. */
3070 /* SH_OK Tests if shift amount is ok. */
3071 /* CST_OK Tests if constant is ok (within field width). */
3072 /* DBD Generate double-byte-data. */
3073 /* RR Register/Register generator. Reused for Direct, Immediate. */
3074 /* BR Branch Relative generator. */
3075 /* SH Shift generator. */
3076 /* SR Single-register generator */
3077 /* JSR Jump/JSR generator */
3078 /* CST Constant arg generator (eg. immediate argument) */
3079 /* ======================================================================== */
3080 #define MVO_OK "[2#].0=.[2#].7=+T$"
3081 #define SH_OK(n) #n ".1>T$" #n ".<0T$"
3082 #define CST_OK(w,c) #c "." #w"I$"
3083 #define DBD(x) #x ".FF&x" #x ".8}.FF&x"
3084 #define RR(o,x,y) #o "." #x ".3{|." #y "|x"
3085 #define BRDIR(a) "P.2+." #a ">."
3086 #define BROFS(a) #a ".P.2+-." BRDIR(a) "!_^"
3087 #define BR(c,a,w) "0200." #c "|." BRDIR(a) "5{|x" BROFS(a) "~x" #w "I$"
3088 #define BX(c,a,w) #c ".4I$" \
3089 "0210." #c "|." BRDIR(a) "5{|x" BROFS(a) "~x" #w "I$"
3090 /*#define BR(c,a,m) "0200." #c "|." BRDIR(a) "5{|x" #a "x"*/
3091 #define CST(c,m) CST_OK(m,c) #c "x"
3092 #define SH(o,n,r) SH_OK(n) "0040." #o ".3{|." #n ".1&.2{|." #r "|x"
3093 #define SR(o,r) "0000." #o ".3{|." #r "|x"
3094 #define JSR(r,e,a) "0004x" #r ".3&.8{." #a ".8}.FC&|." #e "|x" #a ".3FF&x"
3095
3096
3097 /* ======================================================================== */
3098 /* IGTAB -- Instruction Generator Table. */
3099 /* ======================================================================== */
3100 struct igel igtab[] =
3101 {
3102 /* inv 0 */ { SDBD, 0, "[Xnullentry" },
3103 /* inv 1 */ { SDBD, 0, "[Xinvalid opcode" },
3104
3105 /* MVO 2 */ { SDBD, 0, RR(0240,0,[1#]) CST([2=],[3#]) },
3106 /* MVI 3 */ { SDBD, 0, RR(0280,0,[2#]) CST([1=],[3#]) },
3107 /* ADD 4 */ { SDBD, 0, RR(02C0,0,[2#]) CST([1=],[3#]) },
3108 /* SUB 5 */ { SDBD, 0, RR(0300,0,[2#]) CST([1=],[3#]) },
3109 /* CMP 6 */ { SDBD, 0, RR(0340,0,[2#]) CST([1=],[3#]) },
3110 /* AND 7 */ { SDBD, 0, RR(0380,0,[2#]) CST([1=],[3#]) },
3111 /* XOR 8 */ { SDBD, 0, RR(03C0,0,[2#]) CST([1=],[3#]) },
3112
3113 /* MVO@ 9 */ { SDBD, 0, MVO_OK
3114 RR(0240,[2#],[1#]) },
3115 /* MVI@ 10 */ { IND_RG, IND_RG, RR(0280,[1#],[2#]) },
3116 /* ADD@ 11 */ { IND_RG, IND_RG, RR(02C0,[1#],[2#]) },
3117 /* SUB@ 12 */ { IND_RG, IND_RG, RR(0300,[1#],[2#]) },
3118 /* CMP@ 13 */ { IND_RG, IND_RG, RR(0340,[1#],[2#]) },
3119 /* AND@ 14 */ { IND_RG, IND_RG, RR(0380,[1#],[2#]) },
3120 /* XOR@ 15 */ { IND_RG, IND_RG, RR(03C0,[1#],[2#]) },
3121
3122 /* MVOI 16 */ { SDBD, 0, RR(0240,7,[1#]) CST([2=],[3#]) },
3123 /* MVII 17 */ { SDBD, 0, RR(0280,7,[2#]) CST([1=],[3#]) },
3124 /* MVII 18 */ { SDBD, SDBD, RR(0280,7,[2#]) DBD([1=]) },
3125 /* ADDI 19 */ { SDBD, 0, RR(02C0,7,[2#]) CST([1=],[3#]) },
3126 /* ADDI 20 */ { SDBD, SDBD, RR(02C0,7,[2#]) DBD([1=]) },
3127 /* SUBI 21 */ { SDBD, 0, RR(0300,7,[2#]) CST([1=],[3#]) },
3128 /* SUBI 22 */ { SDBD, SDBD, RR(0300,7,[2#]) DBD([1=]) },
3129 /* CMPI 23 */ { SDBD, 0, RR(0340,7,[2#]) CST([1=],[3#]) },
3130 /* CMPI 24 */ { SDBD, SDBD, RR(0340,7,[2#]) DBD([1=]) },
3131 /* ANDI 25 */ { SDBD, 0, RR(0380,7,[2#]) CST([1=],[3#]) },
3132 /* ANDI 26 */ { SDBD, SDBD, RR(0380,7,[2#]) DBD([1=]) },
3133 /* XORI 27 */ { SDBD, 0, RR(03C0,7,[2#]) CST([1=],[3#]) },
3134 /* XORI 28 */ { SDBD, SDBD, RR(03C0,7,[2#]) DBD([1=]) },
3135
3136 /* MOVR 29 */ { SDBD, 0, RR(0080,[1#],[2#]) },
3137 /* ADDR 30 */ { SDBD, 0, RR(00C0,[1#],[2#]) },
3138 /* SUBR 31 */ { SDBD, 0, RR(0100,[1#],[2#]) },
3139 /* CMPR 32 */ { SDBD, 0, RR(0140,[1#],[2#]) },
3140 /* ANDR 33 */ { SDBD, 0, RR(0180,[1#],[2#]) },
3141 /* XORR 34 */ { SDBD, 0, RR(01C0,[1#],[2#]) },
3142
3143 /* B 35 */ { SDBD, 0, BR(0,[1=],[3#]) },
3144 /* BC 36 */ { SDBD, 0, BR(1,[1=],[3#]) },
3145 /* BOV 37 */ { SDBD, 0, BR(2,[1=],[3#]) },
3146 /* BPL 38 */ { SDBD, 0, BR(3,[1=],[3#]) },
3147 /* BEQ 39 */ { SDBD, 0, BR(4,[1=],[3#]) },
3148 /* BLT 40 */ { SDBD, 0, BR(5,[1=],[3#]) },
3149 /* BLE 41 */ { SDBD, 0, BR(6,[1=],[3#]) },
3150 /* BUSC 42 */ { SDBD, 0, BR(7,[1=],[3#]) },
3151 /* NOPP 43 */ { SDBD, 0, BR(8,[1=],[3#]) },
3152 /* BNC 44 */ { SDBD, 0, BR(9,[1=],[3#]) },
3153 /* BNOV 45 */ { SDBD, 0, BR(A,[1=],[3#]) },
3154 /* BMI 46 */ { SDBD, 0, BR(B,[1=],[3#]) },
3155 /* BNEQ 47 */ { SDBD, 0, BR(C,[1=],[3#]) },
3156 /* BGE 48 */ { SDBD, 0, BR(D,[1=],[3#]) },
3157 /* BGT 49 */ { SDBD, 0, BR(E,[1=],[3#]) },
3158 /* BESC 50 */ { SDBD, 0, BR(F,[1=],[3#]) },
3159
3160 /* SWAP 51 */ { SDBD|SHF_RG,SHF_RG, SH(0,0,[1#]) },
3161 /* SWAP 52 */ { SDBD|SHF_RG,SHF_RG, SH(0,[2=].1-,[1#]) },
3162 /* SLL 53 */ { SDBD|SHF_RG,SHF_RG, SH(1,0,[1#]) },
3163 /* SLL 54 */ { SDBD|SHF_RG,SHF_RG, SH(1,[2=].1-,[1#]) },
3164 /* RLC 55 */ { SDBD|SHF_RG,SHF_RG, SH(2,0,[1#]) },
3165 /* RLC 56 */ { SDBD|SHF_RG,SHF_RG, SH(2,[2=].1-,[1#]) },
3166 /* SLLC 57 */ { SDBD|SHF_RG,SHF_RG, SH(3,0,[1#]) },
3167 /* SLLC 58 */ { SDBD|SHF_RG,SHF_RG, SH(3,[2=].1-,[1#]) },
3168 /* SLR 59 */ { SDBD|SHF_RG,SHF_RG, SH(4,0,[1#]) },
3169 /* SLR 60 */ { SDBD|SHF_RG,SHF_RG, SH(4,[2=].1-,[1#]) },
3170 /* SAR 61 */ { SDBD|SHF_RG,SHF_RG, SH(5,0,[1#]) },
3171 /* SAR 62 */ { SDBD|SHF_RG,SHF_RG, SH(5,[2=].1-,[1#]) },
3172 /* RRC 63 */ { SDBD|SHF_RG,SHF_RG, SH(6,0,[1#]) },
3173 /* RRC 64 */ { SDBD|SHF_RG,SHF_RG, SH(6,[2=].1-,[1#]) },
3174 /* SARC 65 */ { SDBD|SHF_RG,SHF_RG, SH(7,0,[1#]) },
3175 /* SARC 66 */ { SDBD|SHF_RG,SHF_RG, SH(7,[2=].1-,[1#]) },
3176
3177 /* NOP 67 */ { SDBD, 0, "0034x" },
3178 /* SIN 68 */ { SDBD, 0, "0036x" },
3179
3180 /* J 69 */ { SDBD, 0, JSR(3,0,[1=]) },
3181 /* JE 70 */ { SDBD, 0, JSR(3,1,[1=]) },
3182 /* JD 71 */ { SDBD, 0, JSR(3,2,[1=]) },
3183 /* JSR 72 */ { SDBD|JSR_RG,JSR_RG, JSR([1#],0,[2=]) },
3184 /* JSRE 73 */ { SDBD|JSR_RG,JSR_RG, JSR([1#],1,[2=]) },
3185 /* JSRD 74 */ { SDBD|JSR_RG,JSR_RG, JSR([1#],2,[2=]) },
3186
3187 /* INCR 75 */ { SDBD, 0, SR(1,[1#]) },
3188 /* DECR 76 */ { SDBD, 0, SR(2,[1#]) },
3189 /* COMR 77 */ { SDBD, 0, SR(3,[1#]) },
3190 /* NEGR 78 */ { SDBD, 0, SR(4,[1#]) },
3191 /* ADCR 79 */ { SDBD, 0, SR(5,[1#]) },
3192 /* GSWD 80 */ { SDBD|SHF_RG,SHF_RG, SR(6,[1#]) },
3193 /* RSWD 81 */ { SDBD, 0, SR(7,[1#]) },
3194
3195 /* HLT 82 */ { SDBD, 0, "0000x" },
3196 /* SDBD 83 */ { SDBD, 0, "0001x" },
3197 /* EIS 84 */ { SDBD, 0, "0002x" },
3198 /* DIS 85 */ { SDBD, 0, "0003x" },
3199 /* TCI 86 */ { SDBD, 0, "0005x" },
3200 /* CLRC 87 */ { SDBD, 0, "0006x" },
3201 /* SETC 88 */ { SDBD, 0, "0007x" },
3202
3203 /* TSTR 89 */ { SDBD, 0, RR(0080,[1#],[1#]) },
3204 /* CLRR 90 */ { SDBD, 0, RR(01C0,[1#],[1#]) },
3205 /* PSHR 91 */ { SDBD, 0, RR(0240,6,[1#]) },
3206 /* PULR 92 */ { 0, 0, RR(0280,6,[1#]) },
3207 /* JR 93 */ { SDBD, 0, RR(0080,[1#],7) },
3208 /* CALL 94 */ { SDBD, 0, JSR(5,0,[1=]) },
3209 /* BEGIN 95 */ { SDBD, 0, RR(0240,6,5) },
3210 /* RETURN 96*/ { SDBD, 0, RR(0280,6,7) },
3211
3212 /* NOPP 97 */ { SDBD, 0, "0208x0000x" },
3213 /* NOP2 98 */ { SDBD, 0, "0035x" },
3214 /* SIN2 99 */ { SDBD, 0, "0037x" },
3215
3216 /* BESC 100 */ { SDBD, 0, BX([4#],[1=],[3#]) },
3217
3218 /* end */ { 0, 0, "[Xinvalid opcode" },
3219 };
3220
3221 #define NUMOPCODE (sizeof(optab)/sizeof(struct opsym))
3222
3223 int gnumopcode = NUMOPCODE;
3224 int ophashlnk[NUMOPCODE];
3225
3226 /* ======================================================================== */
3227 /* End of file: fraptabdef.c */
3228 /* ======================================================================== */
3229