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

Subversion Repositories c16

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

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

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

powered by: WebSVN 2.1.0

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