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

Subversion Repositories System09

[/] [System09/] [trunk/] [Tools/] [as09/] [do09.c] - Blame information for rev 83

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 83 davidgb
/*
2
 *      MC6809 specific processing
3
 */
4
 
5
#define PAGE2 0x10
6
#define PAGE3 0x11
7
#define IPBYTE 0x9F /* extended indirect postbyte */
8
#define SWI     0x3F
9
 
10
/* register names */
11
 
12
#define RD 0
13
#define RX 1
14
#define RY 2
15
#define RU 3
16
#define RS 4
17
#define RPC 5
18
#define RA 8
19
#define RB 9
20
#define RCC 10
21
#define RDP 11
22
#define RPCR 12
23
 
24
/* convert tfr/exg reg number into psh/pul format */
25
int     regs[] = { 6,16,32,64,64,128,0,0,2,4,1,8,0};
26
int     rcycl[]= { 2,2, 2, 2, 2, 2,  0,0,1,1,1,1,0};
27
 
28
/* addressing modes */
29
#define IMMED   0       /* immediate */
30
#define IND     1       /* indexed */
31
#define INDIR   2       /* indirect */
32
#define OTHER   3       /* NOTA */
33
 
34
/*
35
 *      localinit --- machine specific initialization
36
 */
37
localinit()
38
{
39
}
40
 
41
/*
42
 *      do_op --- process mnemonic
43
 *
44
 * Called with the base opcode and it's class. Optr points to
45
 * the beginning of the operand field.
46
 */
47
void do_op(int opcode,int class)
48
{
49
 int     dist;   /* relative branch distance */
50
 int     src,dst;/* source and destination registers */
51
 int     pbyte;  /* postbyte value */
52
 int     amode;  /* indicated addressing mode */
53
 int j;
54
 
55
 amode = set_mode();     /* pickup indicated addressing mode */
56
 
57
 switch(class){
58
  case INH:                       /* inherent addressing */
59
   emit(opcode);
60
   return;
61
  case GEN:                       /* general addressing */
62
   do_gen(opcode,amode);
63
   return;
64
  case IMM:                       /* immediate addressing */
65
   if( amode != IMMED ){
66
    error("Immediate Operand Required");
67
    return;
68
    }
69
   Optr++;
70
   eval();
71
   emit(opcode);
72
   emit(lobyte(Result));
73
   return;
74
  case REL:                       /* short relative branches */
75
   eval();
76
   dist = Result - (Pc+2);
77
   emit(opcode);
78
   if( (dist >127 || dist <-128) && Pass==2){
79
    error("Branch out of Range");
80
    emit(lobyte(-2));
81
    return;
82
    }
83
   emit(lobyte(dist));
84
   return;
85
  case P2REL:                     /* long relative branches */
86
   eval();
87
   dist = Result - (Pc+4);
88
   emit(PAGE2);
89
   emit(opcode);
90
   eword(dist);
91
   return;
92
  case P1REL:                     /* lbra and lbsr */
93
   if( amode == IMMED)
94
    Optr++; /* kludge for C compiler */
95
   eval();
96
   dist = Result - (Pc+3);
97
   emit(opcode);
98
   eword(dist);
99
   return;
100
  case NOIMM:
101
   if( amode == IMMED ){
102
    error("Immediate Addressing Illegal");
103
    return;
104
    }
105
   do_gen(opcode,amode);
106
   return;
107
  case P2GEN:
108
   emit(PAGE2);
109
   if( amode == IMMED ){
110
    emit(opcode);
111
    Optr++;
112
    eval();
113
    eword(Result);
114
    return;
115
    }
116
   do_gen(opcode,amode);
117
   return;
118
  case P3GEN:
119
   emit(PAGE3);
120
   if( amode == IMMED ){
121
    emit(opcode);
122
    Optr++;
123
    eval();
124
    eword(Result);
125
    return;
126
    }
127
   do_gen(opcode,amode);
128
   return;
129
  case RTOR:                      /* tfr and exg */
130
   emit(opcode);
131
   src = regnum();
132
   while(alpha(*Optr))Optr++;
133
   if(src==ERR){
134
    error("Register Name Required");
135
    emit(0);
136
    return;
137
    }
138
   if(*Optr++ != ','){
139
    error("Missing ,");
140
    emit(0);
141
    return;
142
    }
143
   dst = regnum();
144
   while(alpha(*Optr))Optr++;
145
   if(dst==ERR){
146
    error("Register Name Required");
147
    emit(0);
148
    return;
149
    }
150
   if( src==RPCR || dst==RPCR){
151
    error("PCR illegal here");
152
    emit(0);
153
    return;
154
    }
155
   if( (src <=5 && dst >=8) ||
156
       (src >=8 && dst <=5)){
157
    error("Register Size Mismatch");
158
    emit(0);
159
    return;
160
    }
161
   emit( (src<<4)+dst );
162
   return;
163
  case INDEXED:                   /* indexed addressing only */
164
   if( *Optr == '#'){
165
    Optr++;         /* kludge city */
166
    amode = IND;
167
    }
168
   if( amode != IND ){
169
    error("Indexed Addressing Required");
170
    return;
171
    }
172
   do_indexed(opcode);
173
   return;
174
  case RLIST:                     /* pushes and pulls */
175
   if(*Operand == EOS){
176
    error("Register List Required");
177
    return;
178
    }
179
   emit(opcode);
180
   pbyte = 0;
181
   do{
182
    j = regnum();
183
    if( j == ERR || j==RPCR)
184
     error("Illegal Register Name");
185
    else if(j==RS && (opcode==52))
186
     error("Can't Push S on S");
187
    else if(j==RU && (opcode==54))
188
     error("Can't Push U on U");
189
    else if(j==RS && (opcode==53))
190
     error("Can't Pull S from S");
191
    else if(j==RU && (opcode==55))
192
     error("Can't Pull U from U");
193
    else{
194
     pbyte |= regs[j];
195
     Cycles += rcycl[j];
196
     }
197
    while(*Optr != EOS && alpha(*Optr))Optr++;
198
   }while( *Optr++ == ',' );
199
   emit(lobyte(pbyte));
200
   return;
201
  case P2NOIMM:
202
   if( amode == IMMED )
203
    error("Immediate Addressing Illegal");
204
   else{
205
    emit(PAGE2);
206
    do_gen(opcode,amode);
207
    }
208
   return;
209
  case P2INH:                     /* Page 2 inherent */
210
   emit(PAGE2);
211
   emit(opcode);
212
   return;
213
  case P3INH:                     /* Page 3 inherent */
214
   emit(PAGE3);
215
   emit(opcode);
216
   return;
217
  case LONGIMM:
218
   if( amode == IMMED ){
219
    emit(opcode);
220
    Optr++;
221
    eval();
222
    eword(Result);
223
    }
224
   else
225
    do_gen(opcode,amode);
226
   return;
227
  case GRP2:
228
   if( amode == IND ){
229
    do_indexed(opcode+0x60);
230
    return;
231
    }
232
   else if( amode == INDIR){
233
    Optr++;
234
    emit(opcode + 0x60);
235
    emit(IPBYTE);
236
    eval();
237
    eword(Result);
238
    Cycles += 7;
239
    if(*Optr == ']'){
240
     Optr++;
241
     return;
242
     }
243
    error("Missing ']'");
244
    return;
245
    }
246
   eval();
247
   if(Force_word){
248
    emit(opcode+0x70);
249
    eword(Result);
250
    Cycles += 3;
251
    return;
252
    }
253
   if(Force_byte){
254
    emit(opcode);
255
    emit(lobyte(Result));
256
    Cycles += 2;
257
    return;
258
    }
259
   if(Result>=0 && Result <=0xFF){
260
    emit(opcode);
261
    emit(lobyte(Result));
262
    Cycles += 2;
263
    return;
264
    }
265
   else {
266
    emit(opcode+0x70);
267
    eword(Result);
268
    Cycles += 3;
269
    return;
270
    }
271
  case SYS:                       /* system call */
272
   emit(SWI);
273
   eval();
274
   emit(lobyte(Result));
275
   return;
276
  default:
277
   fatal("Error in Mnemonic table");
278
  }
279
}
280
 
281
 
282
/*
283
 *      do_gen --- process general addressing mode stuff
284
 */
285
do_gen(op,mode)
286
int     op;
287
int     mode;
288
{
289
 if( mode == IMMED){
290
  Optr++;
291
  emit(op);
292
  eval();
293
  emit(lobyte(Result));
294
        return(0);
295
  }
296
 else if( mode == IND ){
297
  do_indexed(op+0x20);
298
        return(0);
299
  }
300
 else if( mode == INDIR){
301
  Optr++;
302
  emit(op+0x20);
303
  emit(IPBYTE);
304
  eval();
305
  eword(Result);
306
  Cycles += 7;
307
  if(*Optr == ']'){
308
   Optr++;
309
         return(0);
310
   }
311
  error("Missing ']'");
312
        return(0);
313
  }
314
 else if( mode == OTHER){
315
  eval();
316
  if(Force_word){
317
   emit(op+0x30);
318
   eword(Result);
319
   Cycles += 3;
320
         return(0);
321
   }
322
  if(Force_byte){
323
   emit(op+0x10);
324
   emit(lobyte(Result));
325
   Cycles += 2;
326
         return(0);
327
   }
328
  if(Result>=0 && Result <=0xFF){
329
   emit(op+0x10);
330
   emit(lobyte(Result));
331
   Cycles += 2;
332
         return(0);
333
   }
334
  else {
335
   emit(op+0x30);
336
   eword(Result);
337
   Cycles += 3;
338
         return(0);
339
   }
340
  }
341
 else {
342
  error("Unknown Addressing Mode");
343
        return(0);
344
  }
345
}
346
 
347
/*
348
 *      do_indexed --- handle all wierd stuff for indexed addressing
349
 */
350
do_indexed(op)
351
int op;
352
{
353
 int     pbyte;
354
 int     j,k;
355
 int     predec,pstinc;
356
 
357
 Cycles += 2;    /* indexed is always 2+ base cycle count */
358
 predec=0;
359
 pstinc=0;
360
 pbyte=128;
361
 emit(op);
362
 if(*Optr=='['){
363
  pbyte |= 0x10;    /* set indirect bit */
364
  Optr++;
365
  if( !any((char)']',Optr))
366
   error("Missing ']'");
367
  Cycles += 3;    /* indirection takes this much longer */
368
  }
369
 j=regnum();
370
 if(j==RA){
371
  Cycles++;
372
  abd_index(pbyte+6);
373
        return(0);
374
  }
375
 if(j==RB){
376
  Cycles++;
377
  abd_index(pbyte+5);
378
        return(0);
379
  }
380
 if(j==RD){
381
  Cycles += 4;
382
  abd_index(pbyte+11);
383
        return(0);
384
  }
385
 eval();
386
 Optr++;
387
 while(*Optr=='-'){
388
  predec++;
389
  Optr++;
390
  }
391
 j=regnum();
392
 while( alpha(*Optr) )Optr++;
393
 while(*Optr=='+'){
394
  pstinc++;
395
  Optr++;
396
  }
397
 if(j==RPC || j==RPCR){
398
  if( pstinc || predec ){
399
   error("Auto Inc/Dec Illegal on PC");
400
         return(0);
401
   }
402
  if(j==RPC){
403
   if(Force_word){
404
    emit(pbyte+13);
405
    eword(Result);
406
    Cycles += 5;
407
                return(0);
408
    }
409
   if(Force_byte){
410
    emit(pbyte+12);
411
    emit(lobyte(Result));
412
    Cycles++;
413
                return(0);
414
    }
415
   if(Result>=-128 && Result <=127){
416
    emit(pbyte+12);
417
    emit(lobyte(Result));
418
    Cycles++;
419
                return(0);
420
    }
421
   else {
422
    emit(pbyte+13);
423
    eword(Result);
424
    Cycles += 5;
425
                return(0);
426
    }
427
   }
428
  /* PCR addressing */
429
  if(Force_word){
430
   emit(pbyte+13);
431
   eword(Result-(Pc+2));
432
   Cycles += 5;
433
         return(0);
434
   }
435
  if(Force_byte){
436
   emit(pbyte+12);
437
   emit(lobyte(Result-(Pc+1)));
438
   Cycles++;
439
         return(0);
440
   }
441
  k=Result-(Pc+2);
442
  if( k >= -128 && k <= 127){
443
   emit(pbyte+12);
444
   emit(lobyte(Result-(Pc+1)));
445
   Cycles++;
446
         return(0);
447
   }
448
  else{
449
   emit(pbyte+13);
450
   eword(Result-(Pc+2));
451
   Cycles += 5;
452
         return(0);
453
   }
454
  }
455
 if(predec || pstinc){
456
  if(Result != 0){
457
   error("Offset must be Zero");
458
         return(0);
459
   }
460
  if(predec>2 || pstinc>2){
461
   error("Auto Inc/Dec by 1 or 2 only");
462
         return(0);
463
   }
464
  if((predec==1 && (pbyte&0x10) != 0) ||
465
     (pstinc==1 && (pbyte&0x10) != 0)){
466
   error("No Auto Inc/Dec by 1 for Indirect");
467
         return(0);
468
   }
469
  if(predec && pstinc){
470
   error("Can't do both!");
471
         return(0);
472
   }
473
  if(predec)
474
   pbyte += predec+1;
475
  if(pstinc)
476
   pbyte += pstinc-1;
477
  pbyte += rtype(j);
478
  emit(pbyte);
479
  Cycles += 1 + predec + pstinc;
480
        return(0);
481
  }
482
 pbyte += rtype(j);
483
 if(Force_word){
484
  emit(pbyte+0x09);
485
  eword(Result);
486
  Cycles += 4;
487
        return(0);
488
  }
489
 if(Force_byte){
490
  emit(pbyte+0x08);
491
  emit(lobyte(Result));
492
  Cycles++;
493
        return(0);
494
  }
495
 if(Result==0){
496
  emit(pbyte+0x04);
497
        return(0);
498
  }
499
 if((Result >= -16) && (Result <= 15) && ((pbyte&16)==0)){
500
  pbyte &= 127;
501
  pbyte += Result&31;
502
  emit(pbyte);
503
  Cycles++;
504
        return(0);
505
  }
506
 if(Result >= -128 && Result <= 127){
507
  emit(pbyte+0x08);
508
  emit(lobyte(Result));
509
  Cycles++;
510
        return(0);
511
  }
512
 emit(pbyte+0x09);
513
 eword(Result);
514
 Cycles += 4;
515
 return(0);
516
}
517
 
518
 
519
/*
520
 *      abd_index --- a,b or d indexed
521
 */
522
 
523
abd_index(pbyte)
524
int pbyte;
525
{
526
 int     k;
527
 
528
 Optr += 2;
529
 k=regnum();
530
 pbyte += rtype(k);
531
 emit(pbyte);
532
 return(0);
533
}
534
 
535
/*
536
 *      rtype --- return register type in post-byte format
537
 */
538
rtype(r)
539
int r;
540
{
541
 switch(r){
542
 case RX:        return(0x00);
543
 case RY:        return(0x20);
544
 case RU:        return(0x40);
545
 case RS:        return(0x60);
546
  }
547
 error("Illegal Register for Indexed");
548
 return(0);
549
}
550
 
551
/*
552
 *      set_mode --- determine addressing mode from operand field
553
 */
554
set_mode()
555
{
556
 register char *p;
557
 
558
 if( *Operand == '#' )
559
  return(IMMED);          /* immediate addressing */
560
 p = Operand;
561
 while( *p != EOS && *p != BLANK && *p != TAB){/* any , before break */
562
  if( *p == ',')
563
   return(IND);    /* indexed addressing */
564
  p++;
565
  }
566
 if( *Operand == '[')
567
  return(INDIR);          /* indirect addressing */
568
 return(OTHER);                  /* NOTA */
569
}
570
 
571
/*
572
 *      regnum --- return register number of *Optr
573
 */
574
regnum()
575
{
576
 if( head(Optr,"D" ))return(RD);
577
 if( head(Optr,"d" ))return(RD);
578
 if( head(Optr,"X" ))return(RX);
579
 if( head(Optr,"x" ))return(RX);
580
 if( head(Optr,"Y" ))return(RY);
581
 if( head(Optr,"y" ))return(RY);
582
 if( head(Optr,"U" ))return(RU);
583
 if( head(Optr,"u" ))return(RU);
584
 if( head(Optr,"S" ))return(RS);
585
 if( head(Optr,"s" ))return(RS);
586
 if( head(Optr,"PC" ))return(RPC);
587
 if( head(Optr,"pc" ))return(RPC);
588
 if( head(Optr,"PCR" ))return(RPCR);
589
 if( head(Optr,"pcr" ))return(RPCR);
590
 if( head(Optr,"A" ))return(RA);
591
 if( head(Optr,"a" ))return(RA);
592
 if( head(Optr,"B" ))return(RB);
593
 if( head(Optr,"b" ))return(RB);
594
 if( head(Optr,"CC" ))return(RCC);
595
 if( head(Optr,"cc" ))return(RCC);
596
 if( head(Optr,"DP" ))return(RDP);
597
 if( head(Optr,"dp" ))return(RDP);
598
 return(ERR);
599
}
600
 
601
 

powered by: WebSVN 2.1.0

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