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

Subversion Repositories c16

[/] [c16/] [trunk/] [asm/] [assembler.bison] - Blame information for rev 26

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

Line No. Rev Author Line
1 2 jsauermann
 
2
%{
3
 
4
#include 
5
#include 
6
 
7
extern int yylex();
8
extern int yyparse();
9
extern int yyerror(const char *);
10
extern FILE * out;
11
extern FILE * list;
12
extern FILE * sym;
13
extern FILE * ihx;
14
static void write_intel_hex(FILE * out);
15
 
16
int PC          = 0;
17
int reloc_start = 0;   // first PC
18
int reloc_last  = 0;   // last PC
19
int reloc_end   = 0;   // end of reloc
20
 
21
char memory[0x10000];
22
unsigned int mem_idx = 0;
23
 
24
enum ExHow { EX_NAME, EX_NUMBER,
25
             EX_ADD, EX_SUB, EX_MULT, EX_DIV, EX_MOD };
26
 
27
class Expression
28
{
29
 
30
public:
31
   Expression(const char * n)
32
   : how(EX_NAME),
33
     ex(0),
34
     name(n),
35
     number(0)
36
     {};
37
 
38
   Expression(int n)
39
   : how(EX_NUMBER),
40
     ex(0),
41
     name(0),
42
     number(n)
43
     {};
44
 
45
   Expression(Expression * e, ExHow h, const char * n)
46
   : how(h),
47
     ex(e),
48
     name(n),
49
     number(0)
50
     {};
51
 
52
   Expression(Expression * e, ExHow h, int n)
53
   : how(h),
54
     ex(e),
55
     name(0),
56
     number(n)
57
     {};
58
 
59
   int GetValue() const;
60
   int ListBase() const;
61
   bool UsesName() const
62
      {
63
        if (how == EX_NAME)     return true;
64
        if (how == EX_NUMBER)   return false;
65
        assert(ex);
66
        return ex->UsesName();
67
      }
68
 
69
 
70
private:
71
   const ExHow  how;
72
   Expression * ex;
73
   const char * name;
74
   int          number;
75
};
76
 
77
enum OP_BASE
78
{
79
   EXPR,
80
   REG_RR, REG_RU, REG_RS, REG_R,
81
   REG_LL, REG_LU, REG_LS, REG_L,
82
   REG_SP,
83
   COND_Z,
84
   COND_NZ
85
};
86
 
87
enum OP_ATTR
88
{
89
   ATT_NONE,
90
   ATT_POSTINC,
91
   ATT_PREDEC,
92
   ATT_OFFSET,
93
   ATT_CONTENT,
94
   ATT_PORT,
95
   ATT_ADDR,
96
   ATT_IMM,
97
};
98
 
99
enum OP_HOW
100
{
101
   H_NONE     = 0, // unique opcode
102
   H_BYTE     = 1,
103
   H_PORT     = 2, //                       #byte
104
   H_WORD     = 3, //                                      #word
105
   H_sBW      = 4, // signed                #byte (01X) or #word (10X)
106
   H_uBW      = 5, // unsigned              #byte (01X) or #word (10X)
107
   H_sQBW     = 6, // signed quick       or #byte (01X) or #word (10X)
108
   H_uQBW     = 7, // unsigned quick     or #byte (01X) or #word (10X)
109
};
110
 
111
class Operand
112
{
113
public:
114
   Operand(OP_BASE b, const char * txt)
115
   : base(b), attr(ATT_NONE), expr(0), op_text(txt), offset(0) {};
116
 
117
   Operand(Expression * ex)
118
   : base(EXPR), attr(ATT_NONE), expr(ex), op_text(0), offset(0) {};
119
 
120
   Operand * PostInc()
121
      {
122
        assert(attr == ATT_NONE);
123
        attr = ATT_POSTINC;
124
        return this;
125
      };
126
 
127
   Operand * PreDec()
128
      {
129
        assert(attr == ATT_NONE);
130
        attr = ATT_PREDEC;
131
        return this;
132
      };
133
 
134
   Operand * Content()
135
      {
136
        assert(base == REG_RR || base == REG_LL);
137
        assert(attr == ATT_NONE);
138
        attr = ATT_CONTENT;
139
        return this;
140
      };
141
 
142
   Operand * Offset(Operand * offs)
143
      {
144
        assert(base != EXPR);
145
        assert(attr == ATT_NONE);
146
        attr = ATT_OFFSET;
147
 
148
        assert(offs->base == EXPR);
149
        assert(offs->attr == ATT_NONE);
150
        assert(offset == 0);
151
        offset = offs;
152
        return this;
153
      };
154
 
155
   Operand * Port()
156
      {
157
        assert(base == EXPR);
158
        assert(attr == ATT_NONE);
159
        attr = ATT_PORT;
160
        return this;
161
      };
162
 
163
   Operand * AbsAddr()
164
      {
165
        assert(base == EXPR);
166
        assert(attr == ATT_NONE);
167
        attr = ATT_ADDR;
168
        return this;
169
      };
170
 
171
   Operand * Immediate()
172
     {
173
        assert(base == EXPR);
174
        assert(attr == ATT_NONE);
175
        attr = ATT_IMM;
176
        return this;
177
     };
178
 
179
   int  GetLength(OP_HOW how);
180
   int  GetValue();
181
   int  ListHex(OP_HOW how);
182
   int  List(OP_HOW how);
183
   int  ListBase(OP_HOW how);
184
 
185
private:
186
   OP_BASE      base;
187
   OP_ATTR      attr;
188
   Operand    * offset;
189
   const char * op_text;   // scanned text
190
   Expression * expr;
191
};
192
 
193
class Opcode
194
{
195
public:
196
   Opcode(OP_HOW how, unsigned int opc, const char * txt,
197
          Operand * op1 = 0, Operand * op2 = 0)
198
   : op_how(how),
199
     op_code(opc),
200
     op_text(txt),
201
     op_1(op1),
202
     op_2(op2),
203
     reloc(reloc_end) {};
204
 
205
   int GetLength() const;
206
   int GetOpcode(int & len) const;
207
   int List(int pc);
208
   void Error() const;
209
 
210
private:
211
   OP_HOW        op_how;
212
   unsigned char op_code;
213
   const char  * op_text;   // opcode text
214
   Operand     * op_1;    // oerand 1
215
   Operand     * op_2;    // oerand 2
216
   bool          reloc;   // true if relocated
217
};
218
 
219
int Reloc(bool rloc, int value)
220
{
221
  if (!rloc)   return value;
222
   return value + reloc_end - reloc_last;
223
}
224
 
225
class Symbol
226
{
227
public:
228
   static void Add(const char * id, Expression * ex, bool lab, bool reloc);
229
   static void ListNonlabels();
230
   static int GetValue(const char * id);
231
   static void Reset()   { current = symbols; };
232
   static void PrintSymbols();
233
   static void Advance(int pc);
234
 
235
private:
236
   Symbol(const char * id, Expression * ex, bool lab, bool rloc)
237
   : identifier(id),
238
     expr(ex),
239
     label(lab),
240
     reloc(rloc),
241
     tail(0) {};
242
 
243
   const char * identifier;
244
   Expression * expr;
245
   Symbol     * tail;
246
   bool         label;   // true if label
247
   bool         reloc;   // true if relocated
248
 
249
   static Symbol * symbols;
250
   static Symbol * current;
251
};
252
 
253
class Line
254
{
255
public:
256
   static void Add(Opcode * opc);
257
   static void List();
258
 
259
private:
260
   Line(Opcode * opc)
261
   : opcode(opc),
262
     pc(PC),
263
     tail(0)
264
     {};
265
 
266
   int      pc;
267
   Opcode * opcode;
268
   Line   * tail;
269
 
270
   static Line * first;
271
   static Line * last;
272
};
273
 
274
%}
275
 
276
%token  _BYTE   _WORD   _OFFSET INT     IDENT   EOL     EOFILE  ERROR
277
        _LL     _L      _LS     _LU     _RR     _R      _RS     _RU
278
        _RRZ    _RRNZ   _SP     _EXTERN _STATIC
279
 
280
        ADD     AND     ASR     CALL    CLRB    CLRW    DI      DIV_IS
281
        DIV_IU  EI      HALT    IN      JMP     LNOT    LEA     LSL
282
        LSR     MOVE    MD_STP  MD_FIN  MOD_FIN MUL_IS  MUL_IU  NEG
283
        NOP     NOT     OUT     OR      RET     RETI    SEQ     SGE
284
        SGT     SLE     SLT     SNE     SHS     SHI     SLS     SLO
285
        SUB     XOR
286
 
287
%start  all
288
 
289
%union  {       int          _num;
290
                const char * _txt;
291
                Opcode     * _opcode;
292
                Operand    * _operand;
293
                Expression * _expression;
294
        }
295
 
296
%type   <_num>        INT
297
%type   <_txt>
298
        IDENT   _BYTE   _WORD
299
        _LL     _LU     _LS     _L      _RR     _RU     _RS     _R
300
        _RRZ    _RRNZ   _SP
301
 
302
        ADD     AND     ASR     CALL    CLRB    CLRW    DI      DIV_IS
303
        DIV_IU  EI      HALT    IN      JMP     LNOT    LEA     LSL
304
        LSR     MOVE    MD_STP  MD_FIN  MOD_FIN MUL_IS  MUL_IU  NEG
305
        NOP     NOT     OUT     OR      RET     RETI    SEQ     SGE
306
        SGT     SLE     SLT     SNE     SHS     SHI     SLS     SLO
307
        SUB     XOR
308
 
309
%type   <_opcode>        opcode  rest    line
310
%type   <_expression>        expr
311
%type   <_operand>
312
        value
313
        imm
314
        cRR RR RU RS R dRR RRi
315
        cLL LL LU LS L dLL LLi
316
        SP dSP SPi oSP
317
        RRZ RRNZ
318
        port addr
319
 
320
%%
321
 
322
all     : lines EOFILE
323
          {
324
            reloc_last = PC;
325
            Symbol::ListNonlabels();
326
            Line::List();
327
            Symbol::PrintSymbols();
328
            fwrite(memory, 1, mem_idx, out);
329
            write_intel_hex(ihx);
330
            return 0;
331
          }
332
        ;
333
 
334
lines
335
        : line                  { if ($1)   Line::Add($1); }
336
        | lines line            { if ($2)   Line::Add($2); }
337
        ;
338
 
339
line
340
        :            EOL        { $$ =  0; }
341
        | label      EOL        { $$ =  0; }
342
        |       rest EOL        { $$ = $1; }
343
        | label rest EOL        { $$ = $2; }
344
        ;
345
 
346
label   : IDENT ':'
347
          { Symbol::Add($1, new Expression(PC), true, reloc_end); }
348
        ;
349
 
350
rest
351
        : IDENT '='  expr       { $$ = 0;   Symbol::Add($1, $3, false, false); }
352
        | _EXTERN IDENT         { $$ = 0;   }
353
        | _STATIC IDENT         { $$ = 0;   }
354
        | _OFFSET    expr       { $$ = 0;   reloc_end = $2->GetValue();
355
                                  reloc_start = PC;  }
356
        | opcode                { $$ = $1 }
357
        ;
358
 
359
expr
360
        : INT                   { $$ = new Expression($1);               }
361
        | IDENT                 { $$ = new Expression($1);               }
362
        | expr '+' INT          { $$ = new Expression($1, EX_ADD,  $3);  }
363
        | expr '-' INT          { $$ = new Expression($1, EX_SUB,  $3);  }
364
        | expr '*' INT          { $$ = new Expression($1, EX_MULT, $3);  }
365
        | expr '/' INT          { $$ = new Expression($1, EX_DIV,  $3);  }
366
        | expr '%' INT          { $$ = new Expression($1, EX_MOD,  $3);  }
367
        | expr '+' IDENT        { $$ = new Expression($1, EX_ADD,  $3);  }
368
        | expr '-' IDENT        { $$ = new Expression($1, EX_SUB,  $3);  }
369
        | expr '*' IDENT        { $$ = new Expression($1, EX_MULT, $3); }
370
        | expr '/' IDENT        { $$ = new Expression($1, EX_DIV,  $3);  }
371
        | expr '%' IDENT        { $$ = new Expression($1, EX_MOD,  $3);  }
372
        ;
373
 
374
value
375
        : expr                  { $$ = new Operand($1); }
376
        ;
377
 
378
imm
379
        :  '#' value            { $$ = $2->Immediate(); }
380
        ;
381
 
382
RR      : _RR                   { $$ = new Operand(REG_RR, $1); }       ;
383
RU      : _RU                   { $$ = new Operand(REG_RU, $1); }       ;
384
RS      : _RS                   { $$ = new Operand(REG_RS, $1); }       ;
385
R       : _R                    { $$ = new Operand(REG_R,  $1); }       ;
386
cRR     : '(' RR ')'            { $$ = $2->Content();           }       ;
387
RRZ     : _RRZ                  { $$ = new Operand(COND_Z, $1); }       ;
388
RRNZ    : _RRNZ                 { $$ = new Operand(COND_NZ, $1); }      ;
389
 
390
LL      : _LL                   { $$ = new Operand(REG_LL, $1); }       ;
391
LU      : _LU                   { $$ = new Operand(REG_LU, $1); }       ;
392
LS      : _LS                   { $$ = new Operand(REG_LS, $1); }       ;
393
L       : _L                    { $$ = new Operand(REG_L,  $1); }       ;
394
cLL     : '(' LL ')'            { $$ = $2->Content();           }       ;
395
 
396
SP      : _SP                   { $$ = new Operand(REG_SP,  $1); }      ;
397
 
398
dRR     : '-' '(' RR ')'        { $$ = $3->PreDec();             }      ;
399
dLL     : '-' '(' LL ')'        { $$ = $3->PreDec();             }      ;
400
dSP     : '-' '(' SP ')'        { $$ = $3->PreDec();             }      ;
401
RRi     : '(' RR ')' '+'        { $$ = $2->PostInc();            }      ;
402
LLi     : '(' LL ')' '+'        { $$ = $2->PostInc();            }      ;
403
SPi     : '(' SP ')' '+'        { $$ = $2->PostInc();            }      ;
404
oSP     : value '(' SP ')'      { $$ = $3->Offset($1);           }      ;
405
port    : '(' value ')'         { $$ = $2->Port();               }      ;
406
addr    : '(' value ')'         { $$ = $2->AbsAddr();            }      ;
407
 
408
/////////////////////////////////////////////////////////////////////////
409
 
410
opcode
411
: _BYTE value           { $$ = new Opcode(H_BYTE, 0x00, $1, $2);       }
412
| _WORD value           { $$ = new Opcode(H_WORD, 0x00, $1, $2);       }
413
 
414
| HALT                  { $$ = new Opcode(H_NONE,   0x00, $1);         }
415
| NOP                   { $$ = new Opcode(H_NONE,   0x01, $1);         }
416
| JMP  value            { $$ = new Opcode(H_WORD,   0x02, $1, $2);     }
417
| JMP  RRNZ ',' value   { $$ = new Opcode(H_WORD,   0x03, $1, $2, $4); }
418
| JMP  RRZ  ',' value   { $$ = new Opcode(H_WORD,   0x04, $1, $2, $4); }
419
| CALL value            { $$ = new Opcode(H_WORD,   0x05, $1, $2);     }
420
| CALL '(' RR ')'       { $$ = new Opcode(H_NONE,   0x06, $1, $3);     }
421
| RET                   { $$ = new Opcode(H_NONE,   0x07, $1);         }
422
| MOVE SPi  ',' RR      { $$ = new Opcode(H_NONE,   0x08, $1, $2, $4); }
423
| MOVE SPi  ',' RS      { $$ = new Opcode(H_NONE,   0x09, $1, $2, $4); }
424
| MOVE SPi  ',' RU      { $$ = new Opcode(H_NONE,   0x0A, $1, $2, $4); }
425
| MOVE SPi  ',' LL      { $$ = new Opcode(H_NONE,   0x0B, $1, $2, $4); }
426
| MOVE SPi  ',' LS      { $$ = new Opcode(H_NONE,   0x0C, $1, $2, $4); }
427
| MOVE SPi  ',' LU      { $$ = new Opcode(H_NONE,   0x0D, $1, $2, $4); }
428
| MOVE RR   ',' dSP     { $$ = new Opcode(H_NONE,   0x0E, $1, $2, $4); }
429
| MOVE R    ',' dSP     { $$ = new Opcode(H_NONE,   0x0F, $1, $2, $4); }
430
 
431
| AND  RR   ',' imm     { $$ = new Opcode(H_uBW,    0x10, $1, $2, $4); }
432
| OR   RR   ',' imm     { $$ = new Opcode(H_uBW,    0x12, $1, $2, $4); }
433
| XOR  RR   ',' imm     { $$ = new Opcode(H_uBW,    0x14, $1, $2, $4); }
434
| SEQ  RR   ',' imm     { $$ = new Opcode(H_sBW,    0x16, $1, $2, $4); }
435
| SNE  RR   ',' imm     { $$ = new Opcode(H_sBW,    0x18, $1, $2, $4); }
436
| SGE  RR   ',' imm     { $$ = new Opcode(H_sBW,    0x1A, $1, $2, $4); }
437
| SGT  RR   ',' imm     { $$ = new Opcode(H_sBW,    0x1C, $1, $2, $4); }
438
| SLE  RR   ',' imm     { $$ = new Opcode(H_sBW,    0x1E, $1, $2, $4); }
439
| SLT  RR   ',' imm     { $$ = new Opcode(H_sBW,    0x20, $1, $2, $4); }
440
| SHS  RR   ',' imm     { $$ = new Opcode(H_uBW,    0x22, $1, $2, $4); }
441
| SHI  RR   ',' imm     { $$ = new Opcode(H_uBW,    0x24, $1, $2, $4); }
442
| SLS  RR   ',' imm     { $$ = new Opcode(H_uBW,    0x26, $1, $2, $4); }
443
| SLO  RR   ',' imm     { $$ = new Opcode(H_uBW,    0x28, $1, $2, $4); }
444
| ADD  SP   ',' imm     { $$ = new Opcode(H_uBW,    0x2A, $1, $2, $4); }
445
| CLRW dSP              { $$ = new Opcode(H_NONE,   0x2C, $1, $2);     }
446
| CLRB dSP              { $$ = new Opcode(H_NONE,   0x2D, $1, $2);     }
447
| IN   port ',' RU      { $$ = new Opcode(H_PORT,   0x2E, $1, $2, $4); }
448
| OUT  R    ',' port    { $$ = new Opcode(H_PORT,   0x2F, $1, $2, $4); }
449
 
450
| AND  LL   ',' RR      { $$ = new Opcode(H_NONE,   0x30, $1, $2, $4); }
451
| OR   LL   ',' RR      { $$ = new Opcode(H_NONE,   0x31, $1, $2, $4); }
452
| XOR  LL   ',' RR      { $$ = new Opcode(H_NONE,   0x32, $1, $2, $4); }
453
| SEQ  LL   ',' RR      { $$ = new Opcode(H_NONE,   0x33, $1, $2, $4); }
454
| SNE  LL   ',' RR      { $$ = new Opcode(H_NONE,   0x34, $1, $2, $4); }
455
| SGE  LL   ',' RR      { $$ = new Opcode(H_NONE,   0x35, $1, $2, $4); }
456
| SGT  LL   ',' RR      { $$ = new Opcode(H_NONE,   0x36, $1, $2, $4); }
457
| SLE  LL   ',' RR      { $$ = new Opcode(H_NONE,   0x37, $1, $2, $4); }
458
| SLT  LL   ',' RR      { $$ = new Opcode(H_NONE,   0x38, $1, $2, $4); }
459
| SHS  LL   ',' RR      { $$ = new Opcode(H_NONE,   0x39, $1, $2, $4); }
460
| SHI  LL   ',' RR      { $$ = new Opcode(H_NONE,   0x3A, $1, $2, $4); }
461
| SLS  LL   ',' RR      { $$ = new Opcode(H_NONE,   0x3B, $1, $2, $4); }
462
| SLO  LL   ',' RR      { $$ = new Opcode(H_NONE,   0x3C, $1, $2, $4); }
463
| LNOT RR               { $$ = new Opcode(H_NONE,   0x3D, $1, $2);     }
464
| NEG  RR               { $$ = new Opcode(H_NONE,   0x3E, $1, $2);     }
465
| NOT  RR               { $$ = new Opcode(H_NONE,   0x3F, $1, $2);     }
466
 
467
| MOVE LL   ',' RR      { $$ = new Opcode(H_NONE,   0x40, $1, $2, $4); }
468
| MOVE LL   ',' cRR     { $$ = new Opcode(H_NONE,   0x41, $1, $2, $4); }
469
| MOVE L    ',' cRR     { $$ = new Opcode(H_NONE,   0x42, $1, $2, $4); }
470
| MOVE RR   ',' LL      { $$ = new Opcode(H_NONE,   0x43, $1, $2, $4); }
471
| MOVE RR   ',' cLL     { $$ = new Opcode(H_NONE,   0x44, $1, $2, $4); }
472
| MOVE R    ',' cLL     { $$ = new Opcode(H_NONE,   0x45, $1, $2, $4); }
473
| MOVE cRR  ',' RR      { $$ = new Opcode(H_NONE,   0x46, $1, $2, $4); }
474
| MOVE cRR  ',' RS      { $$ = new Opcode(H_NONE,   0x47, $1, $2, $4); }
475
| MOVE cRR  ',' RU      { $$ = new Opcode(H_NONE,   0x48, $1, $2, $4); }
476
| MOVE addr ',' RR      { $$ = new Opcode(H_WORD,   0x49, $1, $2, $4); }
477
| MOVE addr ',' RS      { $$ = new Opcode(H_WORD,   0x4A, $1, $2, $4); }
478
| MOVE addr ',' RU      { $$ = new Opcode(H_WORD,   0x4B, $1, $2, $4); }
479
| MOVE addr ',' LL      { $$ = new Opcode(H_WORD,   0x4C, $1, $2, $4); }
480
| MOVE addr ',' LS      { $$ = new Opcode(H_WORD,   0x4D, $1, $2, $4); }
481
| MOVE addr ',' LU      { $$ = new Opcode(H_WORD,   0x4E, $1, $2, $4); }
482
| MOVE RR   ',' SP      { $$ = new Opcode(H_NONE,   0x4F, $1, $2, $4); }
483
 
484
| LSL  RR   ',' imm     { $$ = new Opcode(H_BYTE,   0x52, $1, $2, $4); }
485
| ASR  RR   ',' imm     { $$ = new Opcode(H_BYTE,   0x53, $1, $2, $4); }
486
| LSR  RR   ',' imm     { $$ = new Opcode(H_BYTE,   0x54, $1, $2, $4); }
487
| LSL  LL   ',' RR      { $$ = new Opcode(H_NONE,   0x55, $1, $2, $4); }
488
| ASR  LL   ',' RR      { $$ = new Opcode(H_NONE,   0x56, $1, $2, $4); }
489
| LSR  LL   ',' RR      { $$ = new Opcode(H_NONE,   0x57, $1, $2, $4); }
490
| ADD  LL   ',' RR      { $$ = new Opcode(H_NONE,   0x58, $1, $2, $4); }
491
| SUB  LL   ',' RR      { $$ = new Opcode(H_NONE,   0x59, $1, $2, $4); }
492
| MOVE RR   ',' addr    { $$ = new Opcode(H_WORD,   0x5A, $1, $2, $4); }
493
| MOVE R    ',' addr    { $$ = new Opcode(H_WORD,   0x5B, $1, $2, $4); }
494
| MOVE RR   ',' oSP     { $$ = new Opcode(H_uBW,    0x5C, $1, $2, $4); }
495
| MOVE R    ',' oSP     { $$ = new Opcode(H_uBW,    0x5E, $1, $2, $4); }
496
 
497
| MOVE oSP  ',' RR      { $$ = new Opcode(H_uBW,    0x60, $1, $2, $4); }
498
| MOVE oSP  ',' RS      { $$ = new Opcode(H_uBW,    0x62, $1, $2, $4); }
499
| MOVE oSP  ',' RU      { $$ = new Opcode(H_uBW,    0x64, $1, $2, $4); }
500
| MOVE oSP  ',' LL      { $$ = new Opcode(H_uBW,    0x66, $1, $2, $4); }
501
| MOVE oSP  ',' LS      { $$ = new Opcode(H_uBW,    0x68, $1, $2, $4); }
502
| MOVE oSP  ',' LU      { $$ = new Opcode(H_uBW,    0x6A, $1, $2, $4); }
503
| LEA  oSP  ',' RR      { $$ = new Opcode(H_uBW,    0x6C, $1, $2, $4); }
504
| MOVE dRR  ',' dLL     { $$ = new Opcode(H_NONE,   0x6E, $1, $2, $4); }
505
| MOVE RRi  ',' LLi     { $$ = new Opcode(H_NONE,   0x6F, $1, $2, $4); }
506
 
507
| MUL_IS                { $$ = new Opcode(H_NONE,   0x70, $1);         }
508
| MUL_IU                { $$ = new Opcode(H_NONE,   0x71, $1);         }
509
| DIV_IS                { $$ = new Opcode(H_NONE,   0x72, $1);         }
510
| DIV_IU                { $$ = new Opcode(H_NONE,   0x73, $1);         }
511
| MD_STP                { $$ = new Opcode(H_NONE,   0x74, $1);         }
512
| MD_FIN                { $$ = new Opcode(H_NONE,   0x75, $1);         }
513
| MOD_FIN               { $$ = new Opcode(H_NONE,   0x76, $1);         }
514
| EI                    { $$ = new Opcode(H_NONE,   0x77, $1);         }
515
| RETI                  { $$ = new Opcode(H_NONE,   0x78, $1);         }
516
| DI                    { $$ = new Opcode(H_NONE,   0x79, $1);         }
517
 
518
| ADD  RR   ',' imm     { $$ = new Opcode(H_uQBW,   0xA0, $1, $2, $4); }
519
| SUB  RR   ',' imm     { $$ = new Opcode(H_uQBW,   0xB0, $1, $2, $4); }
520
| MOVE imm  ',' RR      { $$ = new Opcode(H_sQBW,   0xC0, $1, $2, $4); }
521
| SEQ  LL   ',' imm     { $$ = new Opcode(H_sQBW,   0xD0, $1, $2, $4); }
522
| MOVE imm  ',' LL      { $$ = new Opcode(H_sQBW,   0xE0, $1, $2, $4); }
523
;
524
 
525
// Fx mapped from 8X..EX
526
%%
527
 
528
//-----------------------------------------------------------------------------
529
void Line::Add(Opcode * opc)
530
{
531
   assert(opc);
532
Line * l = new Line(opc);
533
   if (first == 0)
534
      {
535
        assert(last == 0);
536
        first = last = l;
537
      }
538
   else
539
      {
540
        assert(last->tail == 0);
541
        last->tail = l;
542
        last = l;
543
      }
544
   PC += opc->GetLength();
545
}
546
//-----------------------------------------------------------------------------
547
Symbol * Symbol::symbols = 0;
548
Symbol * Symbol::current = 0;
549
 
550
Line * Line::first = 0;
551
Line * Line::last  = 0;
552
 
553
void Symbol::Add(const char * id, Expression * expr, bool lab, bool reloc)
554
{
555
   for (Symbol * s = symbols; s; s = s->tail)
556
       {
557
         if (!strcmp(id, s->identifier))
558
            {
559
              fprintf(stderr, "Error: Symbol %s already defined\n", id);
560
              return;
561
            }
562
 
563
         if (s->tail == 0)
564
            {
565
              s->tail = new Symbol(id, expr, lab, reloc);
566
              return;
567
            }
568
       }
569
 
570
   symbols = new Symbol(id, expr, lab, reloc);
571
}
572
 
573
//-----------------------------------------------------------------------------
574
int Operand::GetLength(OP_HOW how)
575
{
576
   // how may apply to this or the other argument!
577
   //
578
   if (offset)   return offset->GetLength(how);
579
 
580
   if (base != EXPR)    return 0;
581
   assert(expr);
582
 
583
   switch(how)
584
      {
585
        case H_BYTE:
586
        case H_PORT: return 1;
587
        case H_WORD: return 2;
588
      }
589
 
590
   if (expr->UsesName())   return 2;   // not yet known
591
 
592
   if (GetValue() < 0)    switch(how)
593
      {
594
        case H_uBW:
595
        case H_uQBW:   return 2;
596
 
597
        case H_sBW:    if (GetValue() >= -128)   return 1;
598
                       return 2;
599
 
600
        case H_sQBW:   if (GetValue() >= -8)     return 0;
601
                       if (GetValue() >= -128)   return 1;
602
                       return 2;
603
 
604
        default:        fprintf(stderr, "HOW = %d\n", how);
605
                        assert(0 && "Bad how");
606
      }
607
 
608
   // here GetValue() >= 0
609
   switch(how)
610
      {
611
        case H_uBW:    if (GetValue() <= 255)   return 1;
612
                       return 2;
613
 
614
        case H_sBW:    if (GetValue() <= 127)   return 1;
615
                       return 2;
616
 
617
        case H_uQBW:   if (GetValue() <= 15)    return 0;
618
                       if (GetValue() <= 255)   return 1;
619
                       return 2;
620
 
621
        case H_sQBW:   if (GetValue() <= 7)     return 0;
622
                       if (GetValue() <= 127)   return 1;
623
                       return 2;
624
 
625
        default:        fprintf(stderr, "HOW = %d\n", how);
626
                        assert(0 && "Bad how");
627
      }
628
}
629
//-----------------------------------------------------------------------------
630
int Opcode::GetLength() const
631
{
632
int base_len = 1;
633
 
634
   assert(op_text);
635
   if (*op_text == '.')   base_len = 0;
636
 
637
int op1_len  = 0;
638
   if (op_1)   op1_len = op_1->GetLength(op_how);
639
 
640
int op2_len  = 0;
641
   if (op_2)   op2_len = op_2->GetLength(op_how);
642
 
643
   assert(!op1_len || !op2_len);
644
   return base_len + op1_len + op2_len;
645
}
646
//-----------------------------------------------------------------------------
647
void Line::List()
648
{
649
   PC = 0;
650
   Symbol::Reset();
651
 
652
   for (Line * l = first; l; l = l->tail)
653
       {
654
         Symbol::Advance(PC);
655
         assert(l->opcode);
656
         assert(l->pc == PC);
657
         PC += l->opcode->List(PC);
658
       }
659
   Symbol::Advance(PC);
660
   fprintf(stderr, "Bytes = %d (0x%X)\n", PC, PC);
661
}
662
//-----------------------------------------------------------------------------
663
void Symbol::ListNonlabels()
664
{
665
   for (Symbol * s = symbols; s; s = s->tail)
666
       {
667
         if (s->label)   continue;
668
 
669
         assert(s->identifier);
670
         fprintf(list, "%s\t= %d\n",
671
                 s->identifier, s->expr->GetValue() & 0xFFFF);
672
       }
673
   fprintf(list, "\n");
674
}
675
//-----------------------------------------------------------------------------
676
void Symbol::PrintSymbols()
677
{
678
   for (Symbol * s = symbols; s; s = s->tail)
679
       {
680
         if (!s->label)   continue;
681
 
682
         assert(s->identifier);
683
         fprintf(sym, "%4.4X %s\n",
684
                 s->expr->GetValue() & 0xFFFF, s->identifier);
685
       }
686
}
687
//-----------------------------------------------------------------------------
688
int Symbol::GetValue(const char * id)
689
{
690
   for (Symbol * s = symbols; s; s = s->tail)
691
       {
692
         assert(s->identifier);
693
         assert(s->expr);
694
         if (strcmp(id, s->identifier))   continue;
695
         return 0xFFFF & Reloc(s->reloc, s->expr->GetValue());
696
       }
697
 
698
   fprintf(stderr, "Symbol %s not defined\n", id);
699
   assert(0 && "Symbol Not Defined");
700
   return 0;
701
}
702
//-----------------------------------------------------------------------------
703
int Operand::GetValue()
704
{
705
   assert(expr);
706
   return expr->GetValue();
707
}
708
//-----------------------------------------------------------------------------
709
int Expression::ListBase() const
710
{
711
int ret = 0;
712
 
713
   if (ex)   ret += ex->ListBase();
714
 
715
   switch(how)
716
      {
717
        case EX_NAME:
718
             assert(name);
719
             assert(!ex);
720
             return fprintf(list, "%s", name);
721
 
722
        case EX_NUMBER:
723
             assert(!name);
724
             assert(!ex);
725
             return fprintf(list, "%d", 0xFFFF & number);
726
 
727
        case EX_ADD:
728
             assert(ex);
729
             ret += fprintf(list, " + ");
730
             break;
731
 
732
        case EX_SUB:
733
             assert(ex);
734
             ret += fprintf(list, " - ");
735
             break;
736
 
737
        case EX_MULT:
738
             assert(ex);
739
             ret += fprintf(list, " * ");
740
             break;
741
 
742
        case EX_DIV:
743
             assert(ex);
744
             ret += fprintf(list, " / ");
745
             break;
746
 
747
        case EX_MOD:
748
             assert(ex);
749
             ret += fprintf(list, " / ");
750
             break;
751
 
752
        default: assert(0);
753
      }
754
 
755
   if (name)   ret += fprintf(list, "%s", name);
756
   else        ret += fprintf(list, "%d", number);
757
 
758
   return ret;
759
}
760
//-----------------------------------------------------------------------------
761
int Expression::GetValue() const
762
{
763
int ret;
764
 
765
int my_val = number;
766
   if (name)   my_val = Symbol::GetValue(name);
767
 
768
   switch(how)
769
      {
770
        case EX_NAME:
771
             assert(name);
772
             assert(!ex);
773
             ret = 0xFFFF & my_val;
774
             break;
775
 
776
        case EX_NUMBER:
777
             assert(!name);
778
             assert(!ex);
779
             ret = 0xFFFF & my_val;
780
             break;
781
 
782
        case EX_ADD:
783
             assert(ex);
784
             ret = 0xFFFF & (ex->GetValue() + my_val);
785
             break;
786
 
787
        case EX_SUB:
788
             assert(ex);
789
             ret = 0xFFFF & (ex->GetValue() - my_val);
790
             break;
791
 
792
        case EX_MULT:
793
             assert(ex);
794
             ret = 0xFFFF & (ex->GetValue() * my_val);
795
             break;
796
 
797
        case EX_DIV:
798
             assert(ex);
799
             assert(0xFFFF & my_val);
800
             ret = 0xFFFF & (ex->GetValue() / my_val);
801
             break;
802
 
803
        case EX_MOD:
804
             assert(ex);
805
             assert(0xFFFF & my_val);
806
             ret = 0xFFFF & (ex->GetValue() % my_val);
807
             break;
808
 
809
        default: assert(0);
810
      }
811
 
812
   return ret;
813
}
814
//-----------------------------------------------------------------------------
815
void Symbol::Advance(int pc)
816
{
817
   for (; current; current = current->tail)
818
      {
819
        if (!current->label)   continue;
820
 
821
        assert(current->expr);
822
        int nxt = current->expr->GetValue();
823
        if (nxt > pc)   return;
824
 
825
 
826
        if (nxt == pc)
827
           {
828
             assert(current->identifier);
829
             fprintf(list, "%s:\n", current->identifier);
830
             continue;
831
           }
832
 
833
        assert(0);
834
      }
835
}
836
//-----------------------------------------------------------------------------
837
int Opcode::List(int pc)
838
{
839
int len = 0;
840
int ret = 0;
841
int real_opcode = GetOpcode(ret);
842
 
843
   len += fprintf(list, "   %4.4X: ", 0xFFFF & Reloc(reloc, pc));
844
 
845
   assert(op_text);
846
   if (*op_text != '.')
847
      {
848
       len += fprintf(list, "%2.2X ", real_opcode);
849
       memory[mem_idx++] = real_opcode;
850
      }
851
 
852
   if (op_1)   len += op_1->ListHex(op_how);
853
   if (op_2)   len += op_2->ListHex(op_how);
854
 
855
   while (len < 20)   len += fprintf(list, " ");
856
 
857
   len += fprintf(list, "%s ", op_text);
858
 
859
   while (len < 22)   len += fprintf(list, " ");
860
 
861
   if (op_1)   len += op_1->List(op_how);
862
   if (op_2)
863
      {
864
        len += fprintf(list, ", ");
865
        len += op_2->List(op_how);
866
      }
867
 
868
   fprintf(list, "\n");
869
   return ret;
870
}
871
//-----------------------------------------------------------------------------
872
int Operand::ListHex(OP_HOW how)
873
{
874
   if (offset)   return offset->ListHex(how);
875
 
876
   switch(GetLength(how))
877
      {
878
        case 0:   return 0;
879
 
880
        case 1:   memory[mem_idx++] = GetValue();
881
                  return fprintf(list, "%2.2X ", GetValue() & 0xFF);
882
 
883
        case 2:   memory[mem_idx++] = GetValue();
884
                  memory[mem_idx++] = GetValue() >> 8;
885
                  return fprintf(list, "%4.4X ", GetValue() & 0xFFFF);
886
 
887
        default:  assert(0);
888
      }
889
}
890
//-----------------------------------------------------------------------------
891
int Operand::List(OP_HOW how)
892
{
893
int len = 0;
894
 
895
   if (offset)   len += offset->List(how);
896
 
897
   switch(attr)
898
      {
899
        case ATT_NONE:
900
             return len + ListBase(how);
901
 
902
        case ATT_OFFSET:
903
             len += fprintf(list, "(");
904
             len += ListBase(how);
905
             return len + fprintf(list, ")");
906
 
907
        case ATT_POSTINC:
908
             len += fprintf(list, "(");
909
             len += ListBase(how);
910
             return len + fprintf(list, ")+");
911
 
912
        case ATT_PREDEC:
913
             len += fprintf(list, "-(");
914
             len += ListBase(how);
915
             return len + fprintf(list, ")");
916
 
917
        case ATT_CONTENT:
918
        case ATT_PORT:
919
        case ATT_ADDR:
920
             len += fprintf(list, "(");
921
             len += ListBase(how);
922
             return len + fprintf(list, ")");
923
 
924
        case ATT_IMM:
925
             len += fprintf(list, "#");
926
             return len + ListBase(how);
927
 
928
        default: assert(0);
929
      }
930
}
931
//-----------------------------------------------------------------------------
932
int Operand::ListBase(OP_HOW how)
933
{
934
   if (base != EXPR)
935
      {
936
        assert(op_text);
937
        return fprintf(list, op_text);
938
     }
939
 
940
   if (expr)   return expr->ListBase();
941
 
942
   switch(GetLength(how))
943
      {
944
        case 0:  // quick
945
        case 1:  return fprintf(list, "%2.2X", GetValue() & 0x0FF);
946
        case 2:  return fprintf(list, "%4.4X", GetValue() & 0x0FFFF);
947
      }
948
 
949
   assert(0);
950
}
951
//-----------------------------------------------------------------------------
952
int Opcode::GetOpcode(int & len) const
953
{
954
   len = GetLength();
955
 
956
   switch(op_how)
957
      {
958
        case H_BYTE:
959
        case H_WORD: return op_code;
960
        case H_NONE: if (len == 1)    return op_code;
961
                     if (len == 2)
962
                        {
963
                          assert(op_code & 0x0F1 == 0x61);
964
                          return op_code | 0x01;
965
                        }
966
                     if (len == 3)
967
                        {
968
                          assert(op_code & 0x0F1 == 0x60);
969
                          return op_code;
970
                        }
971
 
972
                     assert(0);
973
        case H_PORT: if (len == 2)    return op_code;
974
                     assert(0);
975
 
976
        case H_sBW:
977
        case H_uBW:  assert((op_code & 0x01) == 0);
978
                     if (len == 2)   return op_code | 0x01;
979
                     if (len == 3)   return op_code;
980
                     Error();
981
                     assert(0);
982
 
983
        case H_uQBW:
984
        case H_sQBW: assert(op_1);
985
                     assert(op_2);
986
                     assert((op_code & 0x0F) == 0);
987
                     if (len == 3)   return 0xF0 | op_code >> 3;
988
                     if (len == 2)   return 0xF1 | op_code >> 3;
989
 
990
                     assert(len == 1);
991
                     if (op_code == 0xC0)   // MOVE #, RR
992
                        return op_code | op_1->GetValue() & 0x0F;
993
                     if (op_code == 0xE0)   // MOVE #, LL
994
                        return op_code | op_1->GetValue() & 0x0F;
995
 
996
                     return op_code | op_2->GetValue() & 0x0F;
997
 
998
      }
999
   assert(0);
1000
}
1001
//-----------------------------------------------------------------------------
1002
void Opcode::Error() const
1003
{
1004
   fprintf(stderr, "Error: ");
1005
   if (op_text) fprintf(stderr, "%s ", op_text);
1006
   fprintf(stderr, "%X", op_code);
1007
   fprintf(stderr, "\n");
1008
}
1009
//-----------------------------------------------------------------------------
1010
void write_intel_record(FILE * out, int adr, int len)
1011
{
1012
char checksum = 0;
1013
 
1014
   fprintf(out, ":");
1015
 
1016
   fprintf(out, "%2.2X", len & 0xFF);
1017
   checksum += len;
1018
 
1019
   fprintf(out, "%4.4X", adr & 0xFFFF);
1020
   checksum += adr >> 8;
1021
   checksum += adr;
1022
 
1023
   if (len == 0)   { fprintf(out, "01");   checksum ++; }   // end of file
1024
   else            { fprintf(out, "00");                }   // data
1025
 
1026
   for (int i = adr; i < adr + len; i++)
1027
       {
1028
         fprintf(out, "%2.2X", memory[i] & 0xFF);
1029
         checksum += memory[i];
1030
       }
1031
 
1032
   fprintf(out, "%2.2X", (-checksum) & 0xFF);
1033
   fprintf(out, "\n");
1034
}
1035
//-----------------------------------------------------------------------------
1036
void write_intel_hex(FILE * out)
1037
{
1038
   for (int i = 0; i < mem_idx; i += 16)
1039
       {
1040
         int len = mem_idx - i;
1041
         if (len > 16)   len = 16;
1042
         write_intel_record(out, i, len);
1043
       }
1044
   write_intel_record(out, 0, 0);
1045
}
1046
//-----------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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