0
|
1 /* 6809 Simulator V09,
|
|
2 By L.C. Benschop, Eidnhoven The Netherlands.
|
|
3 This program is in the public domain.
|
|
4
|
|
5 *** TURBO C VERSION ****
|
|
6
|
|
7 This program simulates a 6809 processor.
|
|
8
|
|
9 System dependencies: short must be 16 bits.
|
|
10 char must be 8 bits.
|
|
11 long must be more than 16 bits.
|
|
12 arrays up to 65536 bytes must be supported.
|
|
13 machine must be twos complement.
|
|
14 Most Unix machines will work. For MSODS you need long pointers
|
|
15 and you may have to malloc() the mem array of 65536 bytes.
|
|
16
|
|
17 Define BIG_ENDIAN if you have a big-endian machine (680x0 etc)
|
|
18
|
|
19 Define TRACE if you want an instruction trace on stderr.
|
|
20 Define TERM_CONTROL for raw, nonblocking IO.
|
|
21
|
|
22 Special instructions:
|
|
23 SWI2 writes char to stdout from register B.
|
|
24 SWI3 reads char from stdout to register B, sets carry at EOF.
|
|
25 (or when no key available when using TERM Control).
|
|
26 SWI retains its normal function.
|
|
27 CWAI and SYNC stop simulator.
|
|
28
|
|
29 The program reads a binary image file at $100 and runs it from there.
|
|
30 The file name must be given on the command line.
|
|
31 */
|
|
32
|
|
33 #include <stdio.h>
|
|
34 #include <alloc.h>
|
|
35 #ifdef TERM_CONTROL
|
|
36 #include <conio.h>
|
|
37 #endif
|
|
38
|
|
39 typedef unsigned char Byte;
|
|
40 typedef unsigned short Word;
|
|
41
|
|
42 /* 6809 registers */
|
|
43 Byte ccreg,dpreg;
|
|
44 Word xreg,yreg,ureg,sreg,ureg,pcreg;
|
|
45
|
|
46 Byte d_reg[2];
|
|
47 Word *dreg=(Word *)d_reg;
|
|
48 #ifdef BIG_ENDIAN /* This is a dirty aliasing trick, but fast! */
|
|
49 Byte *areg=d_reg;
|
|
50 Byte *breg=d_reg+1;
|
|
51 #else
|
|
52 Byte *breg=d_reg;
|
|
53 Byte *areg=d_reg+1;
|
|
54 #endif
|
|
55
|
|
56 /* 6809 memory space */
|
|
57 Byte *mem;
|
|
58
|
|
59 #define GETWORD(a) (mem[a]<<8|mem[(a)+1])
|
|
60 #define SETWORD(a,n) {mem[a]=(n)>>8;mem[(a)+1]=n;}
|
|
61 /* Two bytes of a word are fetched separately because of
|
|
62 the possible wrap-around at address $ffff and alignment
|
|
63 */
|
|
64
|
|
65
|
|
66 int iflag; /* flag to indicate prebyte $10 or $11 */
|
|
67 Byte ireg; /* Instruction register */
|
|
68
|
|
69 #define IMMBYTE(b) b=mem[pcreg++];
|
|
70 #define IMMWORD(w) {w=GETWORD(pcreg);pcreg+=2;}
|
|
71
|
|
72 #define PUSHBYTE(b) mem[--sreg]=b;
|
|
73 #define PUSHWORD(w) {sreg-=2;SETWORD(sreg,w)}
|
|
74 #define PULLBYTE(b) b=mem[sreg++];
|
|
75 #define PULLWORD(w) {w=GETWORD(sreg);sreg+=2;}
|
|
76
|
|
77 #define SIGNED(b) ((Word)(b&0x80?b|0xff00:b))
|
|
78
|
|
79 Word *ixregs[]={&xreg,&yreg,&ureg,&sreg};
|
|
80
|
|
81 int index;
|
|
82
|
|
83 /* Now follow the posbyte addressing modes. */
|
|
84
|
|
85 Word illaddr() /* illegal addressing mode, defaults to zero */
|
|
86 {
|
|
87 return 0;
|
|
88 }
|
|
89
|
|
90 Word ainc()
|
|
91 {
|
|
92 return (*ixregs[index])++;
|
|
93 }
|
|
94
|
|
95 Word ainc2()
|
|
96 {
|
|
97 Word temp;
|
|
98 temp=(*ixregs[index]);
|
|
99 (*ixregs[index])+=2;
|
|
100 return(temp);
|
|
101 }
|
|
102
|
|
103 Word adec()
|
|
104 {
|
|
105 return --(*ixregs[index]);
|
|
106 }
|
|
107
|
|
108 Word adec2()
|
|
109 {
|
|
110 Word temp;
|
|
111 (*ixregs[index])-=2;
|
|
112 temp=(*ixregs[index]);
|
|
113 return(temp);
|
|
114 }
|
|
115
|
|
116 Word plus0()
|
|
117 {
|
|
118 return(*ixregs[index]);
|
|
119 }
|
|
120
|
|
121 Word plusa()
|
|
122 {
|
|
123 return(*ixregs[index])+SIGNED(*areg);
|
|
124 }
|
|
125
|
|
126 Word plusb()
|
|
127 {
|
|
128 return(*ixregs[index])+SIGNED(*breg);
|
|
129 }
|
|
130
|
|
131 Word plusn()
|
|
132 {
|
|
133 Byte b;
|
|
134 IMMBYTE(b)
|
|
135 return(*ixregs[index])+SIGNED(b);
|
|
136 }
|
|
137
|
|
138 Word plusnn()
|
|
139 {
|
|
140 Word w;
|
|
141 IMMWORD(w)
|
|
142 return(*ixregs[index])+w;
|
|
143 }
|
|
144
|
|
145 Word plusd()
|
|
146 {
|
|
147 return(*ixregs[index])+*dreg;
|
|
148 }
|
|
149
|
|
150
|
|
151 Word npcr()
|
|
152 {
|
|
153 Byte b;
|
|
154 IMMBYTE(b)
|
|
155 return pcreg+SIGNED(b);
|
|
156 }
|
|
157
|
|
158 Word nnpcr()
|
|
159 {
|
|
160 Word w;
|
|
161 IMMWORD(w)
|
|
162 return pcreg+w;
|
|
163 }
|
|
164
|
|
165 Word direct()
|
|
166 {
|
|
167 Word(w);
|
|
168 IMMWORD(w)
|
|
169 return w;
|
|
170 }
|
|
171
|
|
172 Word zeropage()
|
|
173 {
|
|
174 Byte b;
|
|
175 IMMBYTE(b)
|
|
176 return dpreg<<8|b;
|
|
177 }
|
|
178
|
|
179
|
|
180 Word immediate()
|
|
181 {
|
|
182 return pcreg++;
|
|
183 }
|
|
184
|
|
185 Word immediate2()
|
|
186 {
|
|
187 Word temp;
|
|
188 temp=pcreg;
|
|
189 pcreg+=2;
|
|
190 return temp;
|
|
191 }
|
|
192
|
|
193 Word (*pbtable[])()={ ainc, ainc2, adec, adec2,
|
|
194 plus0, plusb, plusa, illaddr,
|
|
195 plusn, plusnn, illaddr, plusd,
|
|
196 npcr, nnpcr, illaddr, direct, };
|
|
197
|
|
198 Word postbyte()
|
|
199 {
|
|
200 Byte pb;
|
|
201 Word temp;
|
|
202 IMMBYTE(pb)
|
|
203 index=(pb & 0x60) >> 5;
|
|
204 if(pb & 0x80) {
|
|
205 temp=(*pbtable[pb & 0x0f])();
|
|
206 if( pb & 0x10) temp=GETWORD(temp);
|
|
207 return temp;
|
|
208 } else {
|
|
209 temp=pb & 0x1f;
|
|
210 if(temp & 0x10) temp|=0xfff0;
|
|
211 return (*ixregs[index])+temp;
|
|
212 }
|
|
213 }
|
|
214
|
|
215 Byte * eaddr0() /* effective address for NEG..JMP as byte poitner */
|
|
216 {
|
|
217 switch( (ireg & 0x70) >> 4)
|
|
218 {
|
|
219 case 0: return mem+zeropage();
|
|
220 case 1:case 2:case 3: return 0; /*canthappen*/
|
|
221 case 4: return areg;
|
|
222 case 5: return breg;
|
|
223 case 6: return mem+postbyte();
|
|
224 case 7: return mem+direct();
|
|
225 }
|
|
226 }
|
|
227
|
|
228 Word eaddr8() /* effective address for 8-bits ops. */
|
|
229 {
|
|
230 switch( (ireg & 0x30) >> 4)
|
|
231 {
|
|
232 case 0: return immediate();
|
|
233 case 1: return zeropage();
|
|
234 case 2: return postbyte();
|
|
235 case 3: return direct();
|
|
236 }
|
|
237 }
|
|
238
|
|
239 Word eaddr16() /* effective address for 16-bits ops. */
|
|
240 {
|
|
241 switch( (ireg & 0x30) >> 4)
|
|
242 {
|
|
243 case 0: return immediate2();
|
|
244 case 1: return zeropage();
|
|
245 case 2: return postbyte();
|
|
246 case 3: return direct();
|
|
247 }
|
|
248 }
|
|
249
|
|
250 ill() /* illegal opcode==noop */
|
|
251 {
|
|
252 }
|
|
253
|
|
254 /* macros to set status flags */
|
|
255 #define SEC ccreg|=0x01;
|
|
256 #define CLC ccreg&=0xfe;
|
|
257 #define SEZ ccreg|=0x04;
|
|
258 #define CLZ ccreg&=0xfb;
|
|
259 #define SEN ccreg|=0x08;
|
|
260 #define CLN ccreg&=0xf7;
|
|
261 #define SEV ccreg|=0x02;
|
|
262 #define CLV ccreg&=0xfd;
|
|
263 #define SEH ccreg|=0x20;
|
|
264 #define CLH ccreg&=0xdf;
|
|
265
|
|
266 /* set N and Z flags depending on 8 or 16 bit result */
|
|
267 #define SETNZ8(b) {if(b)CLZ else SEZ if(b&0x80)SEN else CLN}
|
|
268 #define SETNZ16(b) {if(b)CLZ else SEZ if(b&0x8000)SEN else CLN}
|
|
269
|
|
270 #define SETSTATUS(a,b,res) if((a^b^res)&0x10) SEH else CLH \
|
|
271 if((a^b^res^(res>>1))&0x80)SEV else CLV \
|
|
272 if(res&0x100)SEC else CLC SETNZ8((Byte)res)
|
|
273
|
|
274 add()
|
|
275 {
|
|
276 Word aop,bop,res;
|
|
277 Byte* aaop;
|
|
278 aaop=(ireg&0x40)?breg:areg;
|
|
279 aop=*aaop;
|
|
280 bop=mem[eaddr8()];
|
|
281 res=aop+bop;
|
|
282 SETSTATUS(aop,bop,res)
|
|
283 *aaop=res;
|
|
284 }
|
|
285
|
|
286 sbc()
|
|
287 {
|
|
288 Word aop,bop,res;
|
|
289 Byte* aaop;
|
|
290 aaop=(ireg&0x40)?breg:areg;
|
|
291 aop=*aaop;
|
|
292 bop=mem[eaddr8()];
|
|
293 res=aop-bop-(ccreg&0x01);
|
|
294 SETSTATUS(aop,bop,res)
|
|
295 *aaop=res;
|
|
296 }
|
|
297
|
|
298 sub()
|
|
299 {
|
|
300 Word aop,bop,res;
|
|
301 Byte* aaop;
|
|
302 aaop=(ireg&0x40)?breg:areg;
|
|
303 aop=*aaop;
|
|
304 bop=mem[eaddr8()];
|
|
305 res=aop-bop;
|
|
306 SETSTATUS(aop,bop,res)
|
|
307 *aaop=res;
|
|
308 }
|
|
309
|
|
310 adc()
|
|
311 {
|
|
312 Word aop,bop,res;
|
|
313 Byte* aaop;
|
|
314 aaop=(ireg&0x40)?breg:areg;
|
|
315 aop=*aaop;
|
|
316 bop=mem[eaddr8()];
|
|
317 res=aop+bop+(ccreg&0x01);
|
|
318 SETSTATUS(aop,bop,res)
|
|
319 *aaop=res;
|
|
320 }
|
|
321
|
|
322 cmp()
|
|
323 {
|
|
324 Word aop,bop,res;
|
|
325 Byte* aaop;
|
|
326 aaop=(ireg&0x40)?breg:areg;
|
|
327 aop=*aaop;
|
|
328 bop=mem[eaddr8()];
|
|
329 res=aop-bop;
|
|
330 SETSTATUS(aop,bop,res)
|
|
331 }
|
|
332
|
|
333 and()
|
|
334 {
|
|
335 Byte aop,bop,res;
|
|
336 Byte* aaop;
|
|
337 aaop=(ireg&0x40)?breg:areg;
|
|
338 aop=*aaop;
|
|
339 bop=mem[eaddr8()];
|
|
340 res=aop&bop;
|
|
341 SETNZ8(res)
|
|
342 CLV
|
|
343 *aaop=res;
|
|
344 }
|
|
345
|
|
346 or()
|
|
347 {
|
|
348 Byte aop,bop,res;
|
|
349 Byte* aaop;
|
|
350 aaop=(ireg&0x40)?breg:areg;
|
|
351 aop=*aaop;
|
|
352 bop=mem[eaddr8()];
|
|
353 res=aop|bop;
|
|
354 SETNZ8(res)
|
|
355 CLV
|
|
356 *aaop=res;
|
|
357 }
|
|
358
|
|
359 eor()
|
|
360 {
|
|
361 Byte aop,bop,res;
|
|
362 Byte* aaop;
|
|
363 aaop=(ireg&0x40)?breg:areg;
|
|
364 aop=*aaop;
|
|
365 bop=mem[eaddr8()];
|
|
366 res=aop^bop;
|
|
367 SETNZ8(res)
|
|
368 CLV
|
|
369 *aaop=res;
|
|
370 }
|
|
371
|
|
372 bit()
|
|
373 {
|
|
374 Byte aop,bop,res;
|
|
375 Byte* aaop;
|
|
376 aaop=(ireg&0x40)?breg:areg;
|
|
377 aop=*aaop;
|
|
378 bop=mem[eaddr8()];
|
|
379 res=aop&bop;
|
|
380 SETNZ8(res)
|
|
381 CLV
|
|
382 }
|
|
383
|
|
384 ld()
|
|
385 {
|
|
386 Byte res;
|
|
387 Byte* aaop;
|
|
388 aaop=(ireg&0x40)?breg:areg;
|
|
389 res=mem[eaddr8()];
|
|
390 SETNZ8(res)
|
|
391 CLV
|
|
392 *aaop=res;
|
|
393 }
|
|
394
|
|
395 st()
|
|
396 {
|
|
397 Byte res;
|
|
398 Byte* aaop;
|
|
399 aaop=(ireg&0x40)?breg:areg;
|
|
400 res=*aaop;
|
|
401 mem[eaddr8()]=res;
|
|
402 SETNZ8(res)
|
|
403 CLV
|
|
404 }
|
|
405
|
|
406 jsr()
|
|
407 {
|
|
408 Word w;
|
|
409 w=eaddr8();
|
|
410 PUSHWORD(pcreg)
|
|
411 pcreg=w;
|
|
412 }
|
|
413
|
|
414 bsr()
|
|
415 {
|
|
416 Byte b;
|
|
417 IMMBYTE(b)
|
|
418 PUSHWORD(pcreg)
|
|
419 pcreg+=SIGNED(b);
|
|
420 }
|
|
421
|
|
422 neg()
|
|
423 {
|
|
424 Byte *ea;
|
|
425 Word a,r;
|
|
426 a=0;
|
|
427 ea=eaddr0();
|
|
428 a=*ea;
|
|
429 r=-a;
|
|
430 SETSTATUS(0,a,r)
|
|
431 *ea=r;
|
|
432 }
|
|
433
|
|
434 com()
|
|
435 {
|
|
436 Byte *ea;
|
|
437 Byte r;
|
|
438 ea=eaddr0();
|
|
439 r=0^*ea;
|
|
440 SETNZ8(r)
|
|
441 SEC CLV
|
|
442 *ea=r;
|
|
443 }
|
|
444
|
|
445 lsr()
|
|
446 {
|
|
447 Byte *ea;
|
|
448 Byte r;
|
|
449 ea=eaddr0();
|
|
450 r=*ea;
|
|
451 if(r&0x01)SEC else CLC
|
|
452 r>>=1;
|
|
453 SETNZ8(r)
|
|
454 *ea=r;
|
|
455 }
|
|
456
|
|
457 ror()
|
|
458 {
|
|
459 Byte *ea;
|
|
460 Byte r,c;
|
|
461 c=(ccreg&0x01)<<7;
|
|
462 ea=eaddr0();
|
|
463 r=*ea;
|
|
464 if(r&0x01)SEC else CLC
|
|
465 r=(r>>1)+c;
|
|
466 SETNZ8(r)
|
|
467 *ea=r;
|
|
468 }
|
|
469
|
|
470 asr()
|
|
471 {
|
|
472 Byte *ea;
|
|
473 Byte r;
|
|
474 ea=eaddr0();
|
|
475 r=*ea;
|
|
476 if(r&0x01)SEC else CLC
|
|
477 r>>=1;
|
|
478 if(r&0x40)r|=0x80;
|
|
479 SETNZ8(r)
|
|
480 *ea=r;
|
|
481 }
|
|
482
|
|
483 asl()
|
|
484 {
|
|
485 Byte *ea;
|
|
486 Word a,r;
|
|
487 ea=eaddr0();
|
|
488 a=*ea;
|
|
489 r=a<<1;
|
|
490 SETSTATUS(a,a,r)
|
|
491 *ea=r;
|
|
492 }
|
|
493
|
|
494 rol()
|
|
495 {
|
|
496 Byte *ea;
|
|
497 Byte r,c;
|
|
498 c=(ccreg&0x01);
|
|
499 ea=eaddr0();
|
|
500 r=*ea;
|
|
501 if(r&0x80)SEC else CLC
|
|
502 r=(r<<1)+c;
|
|
503 SETNZ8(r)
|
|
504 *ea=r;
|
|
505 }
|
|
506
|
|
507 inc()
|
|
508 {
|
|
509 Byte *ea;
|
|
510 Byte r;
|
|
511 ea=eaddr0();
|
|
512 r=*ea;
|
|
513 r++;
|
|
514 if(r==0x80)SEV else CLV
|
|
515 SETNZ8(r)
|
|
516 *ea=r;
|
|
517 }
|
|
518
|
|
519 dec()
|
|
520 {
|
|
521 Byte *ea;
|
|
522 Byte r;
|
|
523 ea=eaddr0();
|
|
524 r=*ea;
|
|
525 r--;
|
|
526 if(r==0x7f)SEV else CLV
|
|
527 SETNZ8(r)
|
|
528 *ea=r;
|
|
529 }
|
|
530
|
|
531 tst()
|
|
532 {
|
|
533 Byte r;
|
|
534 r=*eaddr0();
|
|
535 SETNZ8(r)
|
|
536 CLV
|
|
537 }
|
|
538
|
|
539 jmp()
|
|
540 {
|
|
541 Byte *ea;
|
|
542 ea=eaddr0();
|
|
543 pcreg=ea-mem;
|
|
544 }
|
|
545
|
|
546 clr()
|
|
547 {
|
|
548 Byte *ea;
|
|
549 ea=eaddr0();
|
|
550 *ea=0;CLN CLV SEZ CLC
|
|
551 }
|
|
552
|
|
553 extern (*instrtable[])();
|
|
554
|
|
555 flag0()
|
|
556 {
|
|
557 if(iflag) /* in case flag already set by previous flag instr don't recurse */
|
|
558 {
|
|
559 pcreg--;
|
|
560 return;
|
|
561 }
|
|
562 iflag=1;
|
|
563 ireg=mem[pcreg++];
|
|
564 (*instrtable[ireg])();
|
|
565 iflag=0;
|
|
566 }
|
|
567
|
|
568 flag1()
|
|
569 {
|
|
570 if(iflag) /* in case flag already set by previous flag instr don't recurse */
|
|
571 {
|
|
572 pcreg--;
|
|
573 return;
|
|
574 }
|
|
575 iflag=2;
|
|
576 ireg=mem[pcreg++];
|
|
577 (*instrtable[ireg])();
|
|
578 iflag=0;
|
|
579 }
|
|
580
|
|
581 nop()
|
|
582 {
|
|
583 }
|
|
584
|
|
585 sync()
|
|
586 {
|
|
587 exit(0);
|
|
588 }
|
|
589
|
|
590 cwai()
|
|
591 {
|
|
592 sync();
|
|
593 }
|
|
594
|
|
595 lbra()
|
|
596 {
|
|
597 Word w;
|
|
598 IMMWORD(w)
|
|
599 pcreg+=w;
|
|
600 }
|
|
601
|
|
602 lbsr()
|
|
603 {
|
|
604 Word w;
|
|
605 IMMWORD(w)
|
|
606 PUSHWORD(pcreg)
|
|
607 pcreg+=w;
|
|
608 }
|
|
609
|
|
610 daa()
|
|
611 {
|
|
612 Word a;
|
|
613 a=*areg;
|
|
614 if(ccreg&0x20)a+=6;
|
|
615 if((a&0x0f)>9)a+=6;
|
|
616 if(ccreg&0x01)a+=0x60;
|
|
617 if((a&0xf0)>0x90)a+=0x60;
|
|
618 if(a&0x100)SEC else CLC
|
|
619 *areg=a;
|
|
620 }
|
|
621
|
|
622 orcc()
|
|
623 {
|
|
624 Byte b;
|
|
625 IMMBYTE(b)
|
|
626 ccreg|=b;
|
|
627 }
|
|
628
|
|
629 andcc()
|
|
630 {
|
|
631 Byte b;
|
|
632 IMMBYTE(b)
|
|
633 ccreg&=b;
|
|
634 }
|
|
635
|
|
636 mul()
|
|
637 {
|
|
638 Word w;
|
|
639 w=*areg * *breg;
|
|
640 if(w)CLZ else SEZ
|
|
641 if(w&0xff00) SEC else CLC
|
|
642 *dreg=w;
|
|
643 }
|
|
644
|
|
645 sex()
|
|
646 {
|
|
647 Word w;
|
|
648 w=SIGNED(*breg);
|
|
649 SETNZ16(w)
|
|
650 *dreg=w;
|
|
651 }
|
|
652
|
|
653 abx()
|
|
654 {
|
|
655 xreg += *breg;
|
|
656 }
|
|
657
|
|
658 rts()
|
|
659 {
|
|
660 PULLWORD(pcreg)
|
|
661 }
|
|
662
|
|
663 rti()
|
|
664 {
|
|
665 Byte x;
|
|
666 x=ccreg&0x80;
|
|
667 PULLBYTE(ccreg)
|
|
668 if(x)
|
|
669 {
|
|
670 PULLBYTE(*areg)
|
|
671 PULLBYTE(*breg)
|
|
672 PULLBYTE(dpreg)
|
|
673 PULLWORD(xreg)
|
|
674 PULLWORD(yreg)
|
|
675 PULLWORD(ureg)
|
|
676 }
|
|
677 PULLWORD(pcreg)
|
|
678 }
|
|
679
|
|
680 swi()
|
|
681 {
|
|
682 int w;
|
|
683 switch(iflag)
|
|
684 {
|
|
685 case 0:
|
|
686 PUSHWORD(pcreg)
|
|
687 PUSHWORD(ureg)
|
|
688 PUSHWORD(yreg)
|
|
689 PUSHWORD(xreg)
|
|
690 PUSHBYTE(dpreg)
|
|
691 PUSHBYTE(*breg)
|
|
692 PUSHBYTE(*areg)
|
|
693 PUSHBYTE(ccreg)
|
|
694 ccreg|=0xd0;
|
|
695 pcreg=GETWORD(0xfffa);
|
|
696 break;
|
|
697 case 1:
|
|
698 putchar(*breg);
|
|
699 fflush(stdout);
|
|
700 break;
|
|
701 case 2:
|
|
702 #ifndef TERM_CONTROL
|
|
703 w=getchar();
|
|
704 if(w==EOF)SEC else CLC
|
|
705 #else
|
|
706 if(kbhit()) {
|
|
707 w=getch();
|
|
708 CLC
|
|
709 } else {
|
|
710 w=255;
|
|
711 SEC
|
|
712 }
|
|
713 #endif
|
|
714 *breg=w;
|
|
715 }
|
|
716 }
|
|
717
|
|
718 Word *wordregs[]={(Word*)d_reg,&xreg,&yreg,&ureg,&sreg,&pcreg,&sreg,&pcreg};
|
|
719 #ifdef BIG_ENDIAN
|
|
720 Byte *byteregs[]={d_reg,d_reg+1,&ccreg,&dpreg};
|
|
721 #else
|
|
722 Byte *byteregs[]={d_reg+1,d_reg,&ccreg,&dpreg};
|
|
723 #endif
|
|
724
|
|
725 tfr()
|
|
726 {
|
|
727 Byte b;
|
|
728 IMMBYTE(b)
|
|
729 if(b&0x80) {
|
|
730 *byteregs[b&0x03]=*byteregs[(b&0x30)>>4];
|
|
731 } else {
|
|
732 *wordregs[b&0x07]=*wordregs[(b&0x70)>>4];
|
|
733 }
|
|
734 }
|
|
735
|
|
736 exg()
|
|
737 {
|
|
738 Byte b;
|
|
739 Word w;
|
|
740 IMMBYTE(b)
|
|
741 if(b&0x80) {
|
|
742 w=*byteregs[b&0x03];
|
|
743 *byteregs[b&0x03]=*byteregs[(b&0x30)>>4];
|
|
744 *byteregs[(b&0x30)>>4]=w;
|
|
745 } else {
|
|
746 w=*wordregs[b&0x07];
|
|
747 *wordregs[b&0x07]=*wordregs[(b&0x70)>>4];
|
|
748 *wordregs[(b&0x70)>>4]=w;
|
|
749 }
|
|
750 }
|
|
751
|
|
752 br(int f)
|
|
753 {
|
|
754 Byte b;
|
|
755 Word w;
|
|
756 if(!iflag) {
|
|
757 IMMBYTE(b)
|
|
758 if(f) pcreg+=SIGNED(b);
|
|
759 } else {
|
|
760 IMMWORD(w)
|
|
761 if(f) pcreg+=w;
|
|
762 }
|
|
763 }
|
|
764
|
|
765 #define NXORV ((ccreg&0x08)^(ccreg&0x02))
|
|
766
|
|
767 bra()
|
|
768 {
|
|
769 br(1);
|
|
770 }
|
|
771
|
|
772 brn()
|
|
773 {
|
|
774 br(0);
|
|
775 }
|
|
776
|
|
777 bhi()
|
|
778 {
|
|
779 br(!(ccreg&0x05));
|
|
780 }
|
|
781
|
|
782 bls()
|
|
783 {
|
|
784 br(ccreg&0x05);
|
|
785 }
|
|
786
|
|
787 bcc()
|
|
788 {
|
|
789 br(!(ccreg&0x01));
|
|
790 }
|
|
791
|
|
792 bcs()
|
|
793 {
|
|
794 br(ccreg&0x01);
|
|
795 }
|
|
796
|
|
797 bne()
|
|
798 {
|
|
799 br(!(ccreg&0x04));
|
|
800 }
|
|
801
|
|
802 beq()
|
|
803 {
|
|
804 br(ccreg&0x04);
|
|
805 }
|
|
806
|
|
807 bvc()
|
|
808 {
|
|
809 br(!(ccreg&0x02));
|
|
810 }
|
|
811
|
|
812 bvs()
|
|
813 {
|
|
814 br(ccreg&0x02);
|
|
815 }
|
|
816
|
|
817 bpl()
|
|
818 {
|
|
819 br(!(ccreg&0x08));
|
|
820 }
|
|
821
|
|
822 bmi()
|
|
823 {
|
|
824 br(ccreg&0x08);
|
|
825 }
|
|
826
|
|
827 bge()
|
|
828 {
|
|
829 br(!NXORV);
|
|
830 }
|
|
831
|
|
832 blt()
|
|
833 {
|
|
834 br(NXORV);
|
|
835 }
|
|
836
|
|
837 bgt()
|
|
838 {
|
|
839 br(!(NXORV||ccreg&0x04));
|
|
840 }
|
|
841
|
|
842 ble()
|
|
843 {
|
|
844 br(NXORV||ccreg&0x04);
|
|
845 }
|
|
846
|
|
847 leax()
|
|
848 {
|
|
849 Word w;
|
|
850 w=postbyte();
|
|
851 if(w) CLZ else SEZ
|
|
852 xreg=w;
|
|
853 }
|
|
854
|
|
855 leay()
|
|
856 {
|
|
857 Word w;
|
|
858 w=postbyte();
|
|
859 if(w) CLZ else SEZ
|
|
860 yreg=w;
|
|
861 }
|
|
862
|
|
863 leau()
|
|
864 {
|
|
865 ureg=postbyte();
|
|
866 }
|
|
867
|
|
868 leas()
|
|
869 {
|
|
870 sreg=postbyte();
|
|
871 }
|
|
872
|
|
873 #define SWAPUS {temp=sreg;sreg=ureg;ureg=temp;}
|
|
874
|
|
875 pshs()
|
|
876 {
|
|
877 Byte b;
|
|
878 IMMBYTE(b)
|
|
879 if(b&0x80)PUSHWORD(pcreg)
|
|
880 if(b&0x40)PUSHWORD(ureg)
|
|
881 if(b&0x20)PUSHWORD(yreg)
|
|
882 if(b&0x10)PUSHWORD(xreg)
|
|
883 if(b&0x08)PUSHBYTE(dpreg)
|
|
884 if(b&0x04)PUSHBYTE(*breg)
|
|
885 if(b&0x02)PUSHBYTE(*areg)
|
|
886 if(b&0x01)PUSHBYTE(ccreg)
|
|
887 }
|
|
888
|
|
889 puls()
|
|
890 {
|
|
891 Byte b;
|
|
892 IMMBYTE(b)
|
|
893 if(b&0x01)PULLBYTE(ccreg)
|
|
894 if(b&0x02)PULLBYTE(*areg)
|
|
895 if(b&0x04)PULLBYTE(*breg)
|
|
896 if(b&0x08)PULLBYTE(dpreg)
|
|
897 if(b&0x10)PULLWORD(xreg)
|
|
898 if(b&0x20)PULLWORD(yreg)
|
|
899 if(b&0x40)PULLWORD(ureg)
|
|
900 if(b&0x80)PULLWORD(pcreg)
|
|
901 }
|
|
902
|
|
903 pshu()
|
|
904 {
|
|
905 Word temp;
|
|
906 SWAPUS
|
|
907 pshs();
|
|
908 SWAPUS
|
|
909 }
|
|
910
|
|
911 pulu()
|
|
912 {
|
|
913 Word temp;
|
|
914 SWAPUS
|
|
915 puls();
|
|
916 SWAPUS
|
|
917 }
|
|
918
|
|
919 #define SETSTATUSD(a,b,res) {if((res&0x10000l)!=0) SEC else CLC \
|
|
920 if((((res>>1)^a^b^res)&0x8000l)!=0) SEV else CLV \
|
|
921 SETNZ16((Word)res)}
|
|
922
|
|
923 addd()
|
|
924 {
|
|
925 unsigned long aop,bop,res;
|
|
926 Word ea;
|
|
927 aop=*dreg&0xffff;
|
|
928 ea=eaddr16();
|
|
929 bop=GETWORD(ea)&0xffff;
|
|
930 res=aop+bop;
|
|
931 SETSTATUSD(aop,bop,res)
|
|
932 *dreg=res;
|
|
933 }
|
|
934
|
|
935 subd()
|
|
936 {
|
|
937 unsigned long aop,bop,res;
|
|
938 Word ea;
|
|
939 if(iflag==2)aop=ureg; else aop=*dreg;
|
|
940 aop&=0xffff;
|
|
941 ea=eaddr16();
|
|
942 bop=GETWORD(ea)&0xffff;
|
|
943 res=aop-bop;
|
|
944 SETSTATUSD(aop,bop,res)
|
|
945 if(iflag==0) *dreg=res;
|
|
946 }
|
|
947
|
|
948 cmpx()
|
|
949 {
|
|
950 unsigned long aop,bop,res;
|
|
951 Word ea;
|
|
952 switch(iflag) {
|
|
953 case 0: aop=xreg;break;
|
|
954 case 1: aop=yreg;break;
|
|
955 case 2: aop=sreg;
|
|
956 }
|
|
957 aop&=0xffff;
|
|
958 ea=eaddr16();
|
|
959 bop=GETWORD(ea)&0xffff;
|
|
960 res=aop-bop;
|
|
961 SETSTATUSD(aop,bop,res)
|
|
962 }
|
|
963
|
|
964 ldd()
|
|
965 {
|
|
966 Word ea,w;
|
|
967 ea=eaddr16();
|
|
968 w=GETWORD(ea);
|
|
969 SETNZ16(w)
|
|
970 *dreg=w;
|
|
971 }
|
|
972
|
|
973 ldx()
|
|
974 {
|
|
975 Word ea,w;
|
|
976 ea=eaddr16();
|
|
977 w=GETWORD(ea);
|
|
978 SETNZ16(w)
|
|
979 if (iflag==0) xreg=w; else yreg=w;
|
|
980 }
|
|
981
|
|
982 ldu()
|
|
983 {
|
|
984 Word ea,w;
|
|
985 ea=eaddr16();
|
|
986 w=GETWORD(ea);
|
|
987 SETNZ16(w)
|
|
988 if (iflag==0) ureg=w; else sreg=w;
|
|
989 }
|
|
990
|
|
991 std()
|
|
992 {
|
|
993 Word ea,w;
|
|
994 ea=eaddr16();
|
|
995 w=*dreg;
|
|
996 SETNZ16(w)
|
|
997 SETWORD(ea,w)
|
|
998 }
|
|
999
|
|
1000 stx()
|
|
1001 {
|
|
1002 Word ea,w;
|
|
1003 ea=eaddr16();
|
|
1004 if (iflag==0) w=xreg; else w=yreg;
|
|
1005 SETNZ16(w)
|
|
1006 SETWORD(ea,w)
|
|
1007 }
|
|
1008
|
|
1009 stu()
|
|
1010 {
|
|
1011 Word ea,w;
|
|
1012 ea=eaddr16();
|
|
1013 if (iflag==0) w=ureg; else w=sreg;
|
|
1014 SETNZ16(w)
|
|
1015 SETWORD(ea,w)
|
|
1016 }
|
|
1017
|
|
1018 int (*instrtable[])() = {
|
|
1019 neg , ill , ill , com , lsr , ill , ror , asr ,
|
|
1020 asl , rol , dec , ill , inc , tst , jmp , clr ,
|
|
1021 flag0 , flag1 , nop , sync , ill , ill , lbra , lbsr ,
|
|
1022 ill , daa , orcc , ill , andcc , sex , exg , tfr ,
|
|
1023 bra , brn , bhi , bls , bcc , bcs , bne , beq ,
|
|
1024 bvc , bvs , bpl , bmi , bge , blt , bgt , ble ,
|
|
1025 leax , leay , leas , leau , pshs , puls , pshu , pulu ,
|
|
1026 ill , rts , abx , rti , cwai , mul , ill , swi ,
|
|
1027 neg , ill , ill , com , lsr , ill , ror , asr ,
|
|
1028 asl , rol , dec , ill , inc , tst , ill , clr ,
|
|
1029 neg , ill , ill , com , lsr , ill , ror , asr ,
|
|
1030 asl , rol , dec , ill , inc , tst , ill , clr ,
|
|
1031 neg , ill , ill , com , lsr , ill , ror , asr ,
|
|
1032 asl , rol , dec , ill , inc , tst , jmp , clr ,
|
|
1033 neg , ill , ill , com , lsr , ill , ror , asr ,
|
|
1034 asl , rol , dec , ill , inc , tst , jmp , clr ,
|
|
1035 sub , cmp , sbc , subd , and , bit , ld , st ,
|
|
1036 eor , adc , or , add , cmpx , bsr , ldx , stx ,
|
|
1037 sub , cmp , sbc , subd , and , bit , ld , st ,
|
|
1038 eor , adc , or , add , cmpx , jsr , ldx , stx ,
|
|
1039 sub , cmp , sbc , subd , and , bit , ld , st ,
|
|
1040 eor , adc , or , add , cmpx , jsr , ldx , stx ,
|
|
1041 sub , cmp , sbc , subd , and , bit , ld , st ,
|
|
1042 eor , adc , or , add , cmpx , jsr , ldx , stx ,
|
|
1043 sub , cmp , sbc , addd , and , bit , ld , st ,
|
|
1044 eor , adc , or , add , ldd , std , ldu , stu ,
|
|
1045 sub , cmp , sbc , addd , and , bit , ld , st ,
|
|
1046 eor , adc , or , add , ldd , std , ldu , stu ,
|
|
1047 sub , cmp , sbc , addd , and , bit , ld , st ,
|
|
1048 eor , adc , or , add , ldd , std , ldu , stu ,
|
|
1049 sub , cmp , sbc , addd , and , bit , ld , st ,
|
|
1050 eor , adc , or , add , ldd , std , ldu , stu ,
|
|
1051 };
|
|
1052
|
|
1053 read_image(char* name)
|
|
1054 {
|
|
1055 FILE *image;
|
|
1056 if((image=fopen(name,"rb"))!=NULL) {
|
|
1057 fread(mem+0x100,0xff00,1,image);
|
|
1058 fclose(image);
|
|
1059 }
|
|
1060 }
|
|
1061
|
|
1062 main(int argc,char *argv[])
|
|
1063 {
|
|
1064 mem=farmalloc(65536);
|
|
1065 read_image(argv[1]);
|
|
1066 pcreg=0x100;
|
|
1067 sreg=0;
|
|
1068 dpreg=0;
|
|
1069 iflag=0;
|
|
1070 for(;;){
|
|
1071 #ifdef TRACE
|
|
1072 fprintf(stderr,"pc=%04x ",pcreg);
|
|
1073 #endif
|
|
1074 ireg=mem[pcreg++];
|
|
1075 #ifdef TRACE
|
|
1076 fprintf(stderr,"i=%02x ",ireg);
|
|
1077 if((ireg&0xfe)==0x10)
|
|
1078 fprintf(stderr,"%02x ",mem[pcreg]);else fprintf(stderr," ");
|
|
1079 fprintf(stderr,"x=%04x y=%04x u=%04x s=%04x a=%02x b=%02x cc=%02x\n",
|
|
1080 xreg,yreg,ureg,sreg,*areg,*breg,ccreg);
|
|
1081 #endif
|
|
1082 (*instrtable[ireg])();
|
|
1083 }
|
|
1084 }
|
|
1085
|