Mercurial > hg > Members > kono > os9 > sbc09
comparison src/v09st.c @ 57:2088fd998865
sbc09 directry clean up
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 23 Jul 2018 16:07:12 +0900 |
parents | v09st.c@9a224bd9b45f |
children |
comparison
equal
deleted
inserted
replaced
56:4fa2bdb0c457 | 57:2088fd998865 |
---|---|
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 |