1 /*
2 * Module d'�mulation des micro-circuits Motorola MC68xx:
3 * - microprocesseur MC6809E
4 * - PIA MC6846
5 * - PIA MC6821
6 *
7 * Copyright (C) 1996 Sylvain Huet, 1999 Eric Botcazou, 2011 Gilles F�tis
8 * 2012 Fran�ois Mouret, 2012 Samuel Devulder.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25 /*
26 * Module : mc68xx/mc6809.c
27 * Version : 2.8.1
28 * Cr�� par : Sylvain Huet 1996
29 * Modifi� par: Eric Botcazou 30/11/2000
30 * Fran�ois Mouret 27/09/2006 26/01/2010 04/02/2012 12/04/2014
31 * Gilles F�tis 27/07/2011
32 * Samuel Devulder 04/02/2012
33 *
34 * Emulateur du microprocesseur Motorola MC6809E.
35 *
36 * version 1.0: �mulation fonctionnelle
37 * version 2.0: horloge interne, interface
38 * version 2.1: interruption du timer
39 * version 2.2: nouvelles valeurs de retour des fonctions d'�x�cution
40 * version 2.3: encapsulation compl�te du module
41 * version 2.4: ajout d'un masque d'�criture des registres
42 * version 2.5: ajout d'une fonction trace (mode DEBUG)
43 * version 2.6: nouvelles commandes externes (RESET, NMI, FIRQ)
44 * correction mineure du mode index� 5-bit
45 * Fetch devient FetchInstr et utilise des unsigned char
46 * suppression d'un inline inutile
47 * version 2.7: nouvelle interface de manipulation de l'�tat du MC6809E
48 * 2.7.1: pr�-incr�ment de cpu_clock pour puls et pulu.
49 * 2.7.2: am�nagement pour le debugger.
50 * version 2.8: ex�cution cycle par cycle des instructions
51 * �mulation des instructions non standard
52 * �mulation des postcodes non standard pour TFR/EXG
53 * �mulation des postcodes non standard pour index�
54 * �mulation du postcode 0x00 pour PSHS/PSHU/PULS/PULU
55 * 2.8.1: Correction du risque de freeze pour synm(), cwai()
56 * et hcfm()
57 * 2.8.2: correction du temps CPU pour CWAI et SYNC
58 * r�initialisation des horloges au reset
59 * mc6809_FlushExec() ex�cute un code machine entier
60 */
61
62
63 #ifndef SCAN_DEPEND
64 #include <stdio.h>
65 #include <string.h>
66 #endif
67
68 #include "defs.h"
69 #include "mc68xx/mc6809.h"
70 #include "teo.h"
71
72 extern struct MOTHERBOARD mb;
73
74 /* broche de demande d'interruption ordinaire */
75 int mc6809_irq;
76
77 #ifdef DEBUG
78 FILE *mc6809_ftrace=NULL;
79 #endif
80
81 /* 6809 interface */
82 struct MC6809_INTERFACE mc6809_interface;
83 static void (*FetchInstr)(int, unsigned char []);
84 static int (*LoadByte)(int);
85 static int (*LoadWord)(int);
86 static void (*StoreByte)(int, int);
87 static void (*StoreWord)(int, int);
88
89 static int (*TrapCallback)(struct MC6809_REGS *);
90 static void (*TimerCallback)(void *);
91 static void *timer_data;
92
93 static struct MC6809_REGS reg_list;
94
95 static void (*addr[])(void);
96
97 /* le caract�re 8-bit du MC6809 impose l'utilisation de char
98 pour la manipulation des opcodes qui sont des octets sign�s */
99 static char byte;
100 static int *regist[4], *exreg[16];
101
102 /* variables d'�tat du MC6809 */
103 static int page=0,opcode,postcode,address,value;
104 static int *reg;
105 static int step=1;
106 static mc6809_clock_t cpu_clock, cpu_timer, cpu_limit;
107 static int pc,xr,yr,ur,sr,ar,br,dp,dr;
108 static int res,m1,m2,sign,ovfl,h1,h2,ccrest;
109 static int bus;
110 static int irq_start,irq_run;
111
112 static void (*compute_address)(void);
113 static const int swi_vector[] = { 0xFFFA, 0xFFF4, 0xFFF2 };
114
115 /*************************************************/
116 /*** gestion du registre d'�tat (CC) du MC6809 ***/
117 /*************************************************/
118
getcc(void)119 static int getcc(void) {
120 return ((((h1&15)+(h2&15))&16)<<1) /* ..x..... H */
121 |((sign&0x80)>>4) /* ....x... N */
122 |((((res&0xff)==0)&1)<<2) /* .....x.. Z */
123 |(( ((~(m1^m2))&(m1^ovfl))&0x80)>>6) /* ......x. V */
124 |((res&0x100)>>8) /* .......x C */
125 |ccrest; /* xx.x.... EFI */
126 }
127
setcc(int i)128 static void setcc(int i) {
129 m1=m2=0;
130 res=((i&1)<<8)|(4-(i&4)); /* .....x.x ZC */
131 ovfl=(i&2)<<6; /* ......x. V */
132 sign=(i&8)<<4; /* ....x... N */
133 h1=h2=(i&32)>>2; /* ..x..... H */
134 ccrest=i&0xd0; /* xx.x.... EFI */
135 }
136
137 /* ========================================================== */
138 /* Adressing modes */
139 /* ========================================================== */
140
indxp(void)141 static void indxp(void) { /* ,r+ */
142 switch (step) {
143 /* [Don't Care] */
144 case 5 : reg=regist[(postcode&0x60)>>5];
145 address=*reg;
146 *reg=((*reg)+1)&0xffff;
147 step=0x20-(postcode&0x10);
148 break;
149 /* Cases 3,4 = [Don't Care] */
150 default: break;
151 }
152 }
153
indxpp(void)154 static void indxpp (void) { /* ,r++ */
155 switch (step) {
156 /* [Don't Care] */
157 case 3 : reg=regist[(postcode&0x60)>>5];
158 address=*reg;
159 *reg=((*reg)+2)&0xffff;
160 break;
161 /* [Don't Care] */
162 case 6 : step=0x20-(postcode&0x10);
163 break;
164 /* Cases 4,5 = [Don't Care] */
165 default: break;
166 }
167 }
168
indmx(void)169 static void indmx(void) { /* ,-r */
170 switch (step) {
171 /* [Don't Care] */
172 case 5 : reg=regist[(postcode&0x60)>>5];
173 *reg=((*reg)-1)&0xffff;
174 address=*reg;
175 step=0x20-(postcode&0x10);
176 break;
177 /* Cases 3,4 = [Don't Care] */
178 default: break;
179 }
180 }
181
indmmx(void)182 static void indmmx(void) { /* ,--r */
183 switch (step) {
184 /* [Don't Care] */
185 case 6 : reg=regist[(postcode&0x60)>>5];
186 *reg=((*reg)-2)&0xffff;
187 address=*reg;
188 step=0x20-(postcode&0x10);
189 break;
190 /* Cases 3,4,5 = [Don't Care] */
191 default: break;
192 }
193 }
194
indx0(void)195 static void indx0(void) { /* ,r */
196 /* [Don't Care] */
197 address=*(regist[(postcode&0x60)>>5]);
198 step=0x20-(postcode&0x10);
199 }
200
indbx(void)201 static void indbx(void) { /* B,r */
202 switch (step) {
203 /* [Don't Care] */
204 case 4 : byte=br;
205 address=((*(regist[(postcode&0x60)>>5]))+byte)&0xffff;
206 step=0x20-(postcode&0x10);
207 break;
208 /* Case 3 = [Don't Care] */
209 default: break;
210 }
211 }
212
indax(void)213 static void indax(void) { /* A,r */
214 switch (step) {
215 /* [Don't Care] */
216 case 4 : byte=ar;
217 address=((*(regist[(postcode&0x60)>>5]))+byte)&0xffff;
218 step=0x20-(postcode&0x10);
219 break;
220 /* Case 3 = [Don't Care] */
221 default: break;
222 }
223 }
224
ind07(void)225 static void ind07(void) { /* ,r (not standard) */
226 switch (step) {
227 /* [Don't Care] */
228 case 4 : address=*(regist[(postcode&0x60)>>5]);
229 step=0x20-(postcode&0x10);
230 break;
231 /* Case 3 = [Don't Care] */
232 default: break;
233 }
234 }
235
ind1x(void)236 static void ind1x(void) { /* n8,r */
237 switch (step) {
238 /* [Offset : NNNN+2(3)] */
239 case 3 : byte=LoadByte(pc);
240 pc=(pc+1)&0xffff;
241 break;
242 /* [Don't Care] */
243 case 4 : address=((*(regist[(postcode&0x60)>>5]))+byte)&0xffff;
244 step=0x20-(postcode&0x10);
245 break;
246 }
247 }
248
ind2x(void)249 static void ind2x(void) { /* n16,r */
250 switch (step) {
251 /* [Offset High : NNNN+2(3)] */
252 case 3 : value=LoadByte(pc)<<8;
253 pc=(pc+1)&0xffff;
254 break;
255 /* [Offset Low : NNNN+3(4)] */
256 case 4 : value|=LoadByte(pc);
257 pc=(pc+1)&0xffff;
258 break;
259 /* [Don't Care] */
260 case 7 : address=((*(regist[(postcode&0x60)>>5]))+value)&0xffff;
261 step=0x20-(postcode&0x10);
262 break;
263 /* Cases 5,6 = [Don't Care] */
264 default: break;
265 }
266 }
267
ind0A(void)268 static void ind0A(void) { /* pc|$ff (not standard) */
269 switch (step) {
270 /* [Don't Care] */
271 case 7 : address=pc|0xff;
272 ar&=LoadByte(pc);
273 step=0x20-(postcode&0x10);
274 break;
275 /* Cases 3,4,5,6 = [Don't Care] */
276 default: break;
277 }
278 }
279
inddx(void)280 static void inddx(void) { /* D,r */
281 switch (step) {
282 /* [Don't Care] */
283 case 7 : address=((*(regist[(postcode&0x60)>>5]))+((ar<<8)+br))&0xffff;
284 step=0x20-(postcode&0x10);
285 break;
286 /* Cases 3,4,5,6 = [Don't Care] */
287 default: break;
288 }
289 }
290
ind1p(void)291 static void ind1p(void) { /* n8,PCR */
292 switch (step) {
293 /* [Offset : NNNN+2(3)] */
294 case 3 : byte=LoadByte(pc);
295 pc=(pc+1)&0xffff;
296 break;
297 /* [Don't Care] */
298 case 4 : address=(pc+byte)&0xffff;
299 step=0x20-(postcode&0x10);
300 break;
301 }
302 }
303
ind2p(void)304 static void ind2p(void) { /* n16,PCR */
305 switch (step) {
306 /* [Offset High : NNNN+2(3)] */
307 case 3 : value=LoadByte(pc)<<8;
308 pc=(pc+1)&0xffff;
309 break;
310 /* [Offset Low : NNNN+3(4)] */
311 case 4 : value|=LoadByte(pc);
312 pc=(pc+1)&0xffff;
313 break;
314 /* [Don't Care] */
315 case 8 : address=(pc+value)&0xffff;
316 step=0x20-(postcode&0x10);
317 break;
318 /* Cases 5,6,7 = [Don't Care] */
319 default: break;
320 }
321 }
322
ind0E(void)323 static void ind0E(void) { /* $ffff (not standard) */
324 switch (step) {
325 /* [Address High] */
326 case 3 : address=0xff00;
327 break;
328 /* [Address Low] */
329 case 4 : address=0xffff;
330 break;
331 /* [Don't Care] */
332 case 8 : step=0x20-(postcode&0x10);
333 break;
334 /* Cases 5,6,7 = [Don't Care] */
335 default: break;
336 }
337 }
338
indad(void)339 static void indad(void) { /* n16 */
340 switch (step) {
341 /* [Address High : NNNN+2(3)] */
342 case 3 : address=LoadByte(pc)<<8;
343 pc=(pc+1)&0xffff;
344 break;
345 /* [Address Low : NNNN+3(4)] */
346 case 4 : address|=LoadByte(pc);
347 pc=(pc+1)&0xffff;
348 break;
349 /* [Don't Care] */
350 case 5 : step=0x20-(postcode&0x10);
351 break;
352 }
353 }
354
355 static void (*indmod[])(void)= {
356 indxp , /* 0 ,r+ */
357 indxpp, /* 1 ,r++ */
358 indmx , /* 2 ,-r */
359 indmmx, /* 3 ,--r */
360 indx0 , /* 4 ,r */
361 indbx , /* 5 B,r */
362 indax , /* 6 A,r */
363 ind07 , /* 7 ,r (not standard) */
364 ind1x , /* 8 n8,r */
365 ind2x , /* 9 n16,r */
366 ind0A , /* A pc|$ff (not standard) */
367 inddx , /* B D,r */
368 ind1p , /* C n8,PCR */
369 ind2p , /* D n16,PCR */
370 ind0E , /* E $ffff (not standard) */
371 indad /* F n16 */
372 };
373
indx(void)374 static void indx(void) {
375 switch (step) {
376 /* [Post Byte : NNNN+1(2)] */
377 case 0x02 : postcode=LoadByte(pc);
378 pc=(pc+1)&0xffff;
379 if ((postcode&0x80)==0) step=0x17;
380 break;
381 /* ----- 5 bits offset from register addressing ------ */
382 /* [Don't Care] */
383 case 0x18 : break;
384 /* [Don't Care] */
385 case 0x19 : address=*(regist[(postcode&0x60)>>5])+(postcode&0x0f)-(postcode&0x10);
386 step=0x20; /* address computed */
387 break;
388 /* ----- indirect addressing ------ */
389 /* [Indirect High : XXXX] */
390 case 0x11 : value=address;
391 address=LoadByte(value)<<8;
392 break;
393 /* [Indirect Low : XXXX+1] */
394 case 0x12 : address|=LoadByte(value+1);
395 break;
396 /* [Don't Care] */
397 case 0x13 : step=0x20; /* address computed */
398 break;
399 /* compute address */
400 default : (*indmod[postcode&0xf])();
401 break;
402 }
403 }
404
extn(void)405 static void extn(void) {
406 switch (step) {
407 /*[Address High : NNNN+1(2)]*/
408 case 2 : address=LoadByte(pc)<<8;
409 pc=(pc+1)&0xffff;
410 break;
411 /*[Address Low : NNNN+2(3)]*/
412 case 3 : address|=LoadByte(pc);
413 pc=(pc+1)&0xffff;
414 break;
415 /* [Don't Care] */
416 case 4 : step=0x20; /* address computed */
417 break;
418 }
419 }
420
drct(void)421 static void drct(void) {
422 switch (step) {
423 /*[Address High : NNNN+1(2)]*/
424 case 2 : address=(dp<<8)|LoadByte(pc);
425 pc=(pc+1)&0xffff;
426 break;
427 /* [Don't Care] */
428 case 3 : step=0x20; /* address computed */
429 break;
430 }
431 }
432
rela(void)433 static void rela(void) {
434 }
435
impl(void)436 static void impl(void) {
437 }
438
imm1(void)439 static void imm1(void) {
440 address=pc;
441 pc=(pc+1)&0xffff;
442 step=0x21; /* address computed */
443 }
444
imm2(void)445 static void imm2(void) {
446 address=pc;
447 pc=(pc+2)&0xffff;
448 step=0x21; /* address computed */
449 }
450
451 /******************************/
452 /*** instructions du MC6809 ***/
453 /******************************/
454
455 /* ========================================================== */
456 /* ASL ASR CLR COM DEC INC LSL LSR NEG ROL ROR TST */
457 /* ========================================================== */
458
aslm(void)459 static void aslm(void) { /* H?NxZxVxCx */
460 switch (step) {
461 /* [Data : EA] */
462 case 0x21 : value=LoadByte(address);
463 break;
464 /* [Don't Care] */
465 case 0x22 : break;
466 /* [Data (write) : EA] */
467 case 0x23 : m1=m2=value;
468 value<<=1;
469 ovfl=sign=res=value;
470 StoreByte(address,value);
471 step=0; /* reset fetch */
472 break;
473 /* compute address */
474 default : compute_address();
475 break;
476 }
477 }
478
asrm(void)479 static void asrm(void) { /* H?NxZxCx */
480 switch (step) {
481 /* [Data : EA] */
482 case 0x21 : value=LoadByte(address);
483 break;
484 /* [Don't Care] */
485 case 0x22 : break;
486 /* [Data (write) : EA] */
487 case 0x23 : res=(value&1)<<8;
488 value=(value>>1)|(value&0x80);
489 sign=value;
490 res|=sign;
491 StoreByte(address,value);
492 step=0; /* reset fetch */
493 break;
494 /* compute address */
495 default : compute_address();
496 break;
497 }
498 }
499
clrm(void)500 static void clrm(void) { /* N0Z1V0C0 */
501 switch (step) {
502 /* [Data : EA] */
503 case 0x21 : value=LoadByte(address);
504 break;
505 /* [Don't Care] */
506 case 0x22 : break;
507 /* [Data (write) : EA] */
508 case 0x23 : m1=~m2;
509 sign=res=value=0;
510 StoreByte(address,value);
511 step=0; /* reset fetch */
512 break;
513 /* compute address */
514 default : compute_address();
515 break;
516 }
517 }
518
comm(void)519 static void comm(void) { /* NxZxV0C1 */
520 switch (step) {
521 /* [Data : EA] */
522 case 0x21 : value=LoadByte(address);
523 break;
524 /* [Don't Care] */
525 case 0x22 : break;
526 /* [Data (write) : EA] */
527 case 0x23 : m1=~m2;
528 value=(~value)&0xff;
529 sign=value;
530 res=sign|0x100; /* bit C a 1 */
531 StoreByte(address,value);
532 step=0; /* reset fetch */
533 break;
534 /* compute address */
535 default : compute_address();
536 break;
537 }
538 }
539
decm(void)540 static void decm(void) { /* NxZxVx */
541 switch (step) {
542 /* [Data : EA] */
543 case 0x21 : value=LoadByte(address);
544 break;
545 /* [Don't Care] */
546 case 0x22 : break;
547 /* [Data (write) : EA] */
548 case 0x23 : m1=value; m2=0x80;
549 ovfl=sign=(--value)&0xff;
550 res=(res&0x100)|sign;
551 StoreByte(address,value);
552 step=0; /* reset fetch */
553 break;
554 /* compute address */
555 default : compute_address();
556 break;
557 }
558 }
559
incm(void)560 static void incm(void) { /* NxZxVx */
561 switch (step) {
562 /* [Data : EA] */
563 case 0x21 : value=LoadByte(address);
564 break;
565 /* [Don't Care] */
566 case 0x22 : break;
567 /* [Data (write) : EA] */
568 case 0x23 : m1=value; m2=0;
569 ovfl=sign=(++value)&0xff;
570 res=(res&0x100)|sign;
571 StoreByte(address,value);
572 step=0; /* reset fetch */
573 break;
574 /* compute address */
575 default : compute_address();
576 break;
577 }
578 }
579
lsrm(void)580 static void lsrm(void) { /* N0ZxCx */
581 switch (step) {
582 /* [Data : EA] */
583 case 0x21 : value=LoadByte(address);
584 break;
585 /* [Don't Care] */
586 case 0x22 : break;
587 /* [Data (write) : EA] */
588 case 0x23 : res=(value&1)<<8; /* bit C */
589 value>>=1;
590 sign=0;
591 res|=value;
592 StoreByte(address,value);
593 step=0; /* reset fetch */
594 break;
595 /* compute address */
596 default : compute_address();
597 break;
598 }
599 }
600
negm(void)601 static void negm(void) { /* H?NxZxVxCx */
602 switch (step) {
603 /* [Data : EA] */
604 case 0x21 : value=LoadByte(address);
605 break;
606 /* [Don't Care] */
607 case 0x22 : break;
608 /* [Data (write) : EA] */
609 case 0x23 : m1=value; m2=-value; /* bit V */
610 value=(-value)&0xff;
611 ovfl=res=sign=value;
612 StoreByte(address,value);
613 step=0; /* reset fetch */
614 break;
615 /* compute address */
616 default : compute_address();
617 break;
618 }
619 }
620
rolm(void)621 static void rolm(void) { /* NxZxVxCx */
622 switch (step) {
623 /* [Data : EA] */
624 case 0x21 : value=LoadByte(address);
625 break;
626 /* [Don't Care] */
627 case 0x22 : break;
628 /* [Data (write) : EA] */
629 case 0x23 : m1=m2=value;
630 value=(value<<1)|((res&0x100)>>8);
631 ovfl=sign=res=value;
632 StoreByte(address,value);
633 step=0; /* reset fetch */
634 break;
635 /* compute address */
636 default : compute_address();
637 break;
638 }
639 }
640
rorm(void)641 static void rorm(void) { /* NxZxCx */
642 switch (step) {
643 /* [Data : EA] */
644 case 0x21 : value=LoadByte(address);
645 break;
646 /* [Don't Care] */
647 case 0x22 : break;
648 /* [Data (write) : EA] */
649 case 0x23 : sign=(value|(res&0x100))>>1;
650 res=((value&1)<<8)|sign;
651 StoreByte(address,sign);
652 step=0; /* reset fetch */
653 break;
654 /* compute address */
655 default : compute_address();
656 break;
657 }
658 }
659
tstm(void)660 static void tstm(void) { /* NxZxV0 */
661 switch (step) {
662 /* [Data : EA] */
663 case 0x21 : value=LoadByte(address);
664 break;
665 /* [Don't Care] */
666 case 0x22 : break;
667 /* [Don't Care] */
668 case 0x23 : m1=~m2;
669 sign=value;
670 res=(res&0x100)|sign;
671 step=0; /* reset fetch */
672 break;
673 /* compute address */
674 default : compute_address();
675 break;
676 }
677 }
678
679 /* ========================================================== */
680 /* JMP JSR */
681 /* ========================================================== */
682
jmpm(void)683 static void jmpm(void) {
684 compute_address();
685 if (step==0x20) {
686 pc=address;
687 step=0; /* reset fetch */
688 }
689 }
690
jsrm(void)691 static void jsrm(void) { /* NxZxV0 */
692 switch (step) {
693 /* [Don't Care : Sub Address] */
694 case 0x21 : break;
695 /* [Don't Care] */
696 case 0x22 : break;
697 /* [PC Low (write) : Stack] */
698 case 0x23 : sr=(sr-1)&0xffff;
699 StoreByte(sr,pc);
700 break;
701 /* [PC High (write) : Stack] */
702 case 0x24 : sr=(sr-1)&0xffff;
703 StoreByte(sr,pc>>8);
704 pc=address;
705 step=0; /* reset fetch */
706 break;
707 /* compute address */
708 default : compute_address();
709 break;
710 }
711 }
712
713 /* ========================================================== */
714 /* TFR EXG */
715 /* ========================================================== */
716
tfrm(void)717 static void tfrm(void) {
718 int r1,r2,v1;
719 switch (step) {
720 /* [Post Byte : NNNN+1] */
721 case 2 : postcode=LoadByte(pc);
722 pc=(pc+1)&0xffff;
723 break;
724 /* [Don't Care] */
725 case 6 : bus=0xffff;
726 r1=postcode>>4;
727 r2=postcode&0xf;
728 v1=(r1&8)?((r1==0xa)?getcc()|0xff00:*exreg[r1]|0xff00)
729 :((r1)?*exreg[r1]:(ar<<8)+br);
730 if (!r2) { ar=v1>>8; br=v1&0xff; }
731 else if (r2==0xa) setcc(v1);
732 else *exreg[r2]=(r2&8)?v1&0xff:v1;
733 step=0; /* reset fetch */
734 break;
735 /* Cases 3,4,5 = [Don't Care] */
736 default: break;
737 }
738 }
739
exgm(void)740 static void exgm(void) {
741 int r1,r2,v1,v2;
742 switch (step) {
743 /* [Post Byte : NNNN+1] */
744 case 2 : postcode=LoadByte(pc);
745 pc=(pc+1)&0xffff;
746 break;
747 /* [Don't Care] */
748 case 8 : bus=0xffff;
749 r1=postcode>>4;
750 r2=postcode&0xf;
751 v1=(r1&8)?((r1==0xa)?getcc()|0xff00:*exreg[r1]|0xff00)
752 :((r1)?*exreg[r1]:(ar<<8)+br);
753 v2=(r2&8)?((r2==0xa)?getcc()|0xff00:*exreg[r2]|0xff00)
754 :((r2)?*exreg[r2]:(ar<<8)+br);
755 if (!r1) { ar=v2>>8; br=v2&0xff; }
756 else if (r1==0xa) setcc(v2);
757 else *exreg[r1]=(r1&8)?v2&0xff:v2;
758 if (!r2) { ar=v1>>8; br=v1&0xff; }
759 else if (r2==0xa) setcc(v1);
760 else *exreg[r2]=(r2&8)?v1&0xff:v1;
761 step=0; /* reset fetch */
762 break;
763 /* Cases 3,4,5,6,7 = [Don't Care] */
764 default: break;
765 }
766 }
767
768 /* ========================================================== */
769 /* BCC BCS BEQ BGE BGT BHI BHS BLE BLO BLS BLT BMI BNE BPL */
770 /* BRA BRN BVC BVS */
771 /* ========================================================== */
772
bras(void)773 static void bras(void) { /* branch always */
774 switch (step) {
775 /* [Offset : NNNN+1] */
776 case 2 : byte=LoadByte(pc);
777 pc=(pc+1)&0xffff;
778 break;
779 /* [Don't Care] */
780 case 3 : pc=(pc+byte)&0xffff;
781 step=0; /* reset fetch */
782 break;
783 }
784 }
785
brns(void)786 static void brns(void) { /* branch never */
787 switch (step) {
788 /* [Offset : NNNN+1] */
789 case 2 : pc=(pc+1)&0xffff;
790 break;
791 /* [Don't Care] */
792 case 3 : step=0; /* reset fetch */
793 break;
794 }
795 }
796
bhis(void)797 static void bhis(void) { /* branch if C|Z=0 */
798 switch (step) {
799 /* [Offset : NNNN+1] */
800 case 2 : byte=LoadByte(pc);
801 pc=(pc+1)&0xffff;
802 break;
803 /* [Don't Care] */
804 case 3 : if ((!(res&0x100))&&(res&0xff))
805 pc=(pc+byte)&0xffff;
806 step=0; /* reset fetch */
807 break;
808 }
809 }
810
blss(void)811 static void blss(void) { /* branch if C|Z=1 */
812 switch (step) {
813 /* [Offset : NNNN+1] */
814 case 2 : byte=LoadByte(pc);
815 pc=(pc+1)&0xffff;
816 break;
817 /* [Don't Care] */
818 case 3 : if ((res&0x100)||(!(res&0xff)))
819 pc=(pc+byte)&0xffff;
820 step=0; /* reset fetch */
821 break;
822 }
823 }
824
bccs(void)825 static void bccs(void) { /* branch if C=0 */
826 switch (step) {
827 /* [Offset : NNNN+1] */
828 case 2 : byte=LoadByte(pc);
829 pc=(pc+1)&0xffff;
830 break;
831 /* [Don't Care] */
832 case 3 : if (!(res&0x100)) pc=(pc+byte)&0xffff;
833 step=0; /* reset fetch */
834 break;
835 }
836 }
837
blos(void)838 static void blos(void) { /* branch if C=1 */
839 switch (step) {
840 /* [Offset : NNNN+1] */
841 case 2 : byte=LoadByte(pc);
842 pc=(pc+1)&0xffff;
843 break;
844 /* [Don't Care] */
845 case 3 : if (res&0x100) pc=(pc+byte)&0xffff;
846 step=0; /* reset fetch */
847 break;
848 }
849 }
850
bnes(void)851 static void bnes(void) { /* branch if Z=0 */
852 switch (step) {
853 /* [Offset : NNNN+1] */
854 case 2 : byte=LoadByte(pc);
855 pc=(pc+1)&0xffff;
856 break;
857 /* [Don't Care] */
858 case 3 : if (res&0xff) pc=(pc+byte)&0xffff;
859 step=0; /* reset fetch */
860 break;
861 }
862 }
863
beqs(void)864 static void beqs(void) { /* branch if Z=1 */
865 switch (step) {
866 /* [Offset : NNNN+1] */
867 case 2 : byte=LoadByte(pc);
868 pc=(pc+1)&0xffff;
869 break;
870 /* [Don't Care] */
871 case 3 : if (!(res&0xff)) pc=(pc+byte)&0xffff;
872 step=0; /* reset fetch */
873 break;
874 }
875 }
876
bvcs(void)877 static void bvcs(void) { /* branch if V=0 */
878 switch (step) {
879 /* [Offset : NNNN+1] */
880 case 2 : byte=LoadByte(pc);
881 pc=(pc+1)&0xffff;
882 break;
883 /* [Don't Care] */
884 case 3 : if (((m1^m2)&0x80)||(!((m1^ovfl)&0x80)))
885 pc=(pc+byte)&0xffff;
886 step=0; /* reset fetch */
887 break;
888 }
889 }
890
bvss(void)891 static void bvss(void) { /* branch if V=1 */
892 switch (step) {
893 /* [Offset : NNNN+1] */
894 case 2 : byte=LoadByte(pc);
895 pc=(pc+1)&0xffff;
896 break;
897 /* [Don't Care] */
898 case 3 : if ((!((m1^m2)&0x80))&&((m1^ovfl)&0x80))
899 pc=(pc+byte)&0xffff;
900 step=0; /* reset fetch */
901 break;
902 }
903 }
904
bpls(void)905 static void bpls(void) { /* branch if N=0 */
906 switch (step) {
907 /* [Offset : NNNN+1] */
908 case 2 : byte=LoadByte(pc);
909 pc=(pc+1)&0xffff;
910 break;
911 /* [Don't Care] */
912 case 3 : if (!(sign&0x80)) pc=(pc+byte)&0xffff;
913 step=0; /* reset fetch */
914 break;
915 }
916 }
917
bmis(void)918 static void bmis(void) { /* branch if N=1 */
919 switch (step) {
920 /* [Offset : NNNN+1] */
921 case 2 : byte=LoadByte(pc);
922 pc=(pc+1)&0xffff;
923 break;
924 /* [Don't Care] */
925 case 3 : if (sign&0x80) pc=(pc+byte)&0xffff;
926 step=0; /* reset fetch */
927 break;
928 }
929 }
930
bges(void)931 static void bges(void) { /* branch if N^V=0 */
932 switch (step) {
933 /* [Offset : NNNN+1] */
934 case 2 : byte=LoadByte(pc);
935 pc=(pc+1)&0xffff;
936 break;
937 /* [Don't Care] */
938 case 3 : if (!((sign^((~(m1^m2))&(m1^ovfl)))&0x80))
939 pc=(pc+byte)&0xffff;
940 step=0; /* reset fetch */
941 break;
942 }
943 }
944
blts(void)945 static void blts(void) { /* branch if N^V=1 */
946 switch (step) {
947 /* [Offset : NNNN+1] */
948 case 2 : byte=LoadByte(pc);
949 pc=(pc+1)&0xffff;
950 break;
951 /* [Don't Care] */
952 case 3 : if ((sign^((~(m1^m2))&(m1^ovfl)))&0x80)
953 pc=(pc+byte)&0xffff;
954 step=0; /* reset fetch */
955 break;
956 }
957 }
958
bgts(void)959 static void bgts(void) { /* branch if Z|(N^V)=0 */
960 switch (step) {
961 /* [Offset : NNNN+1] */
962 case 2 : byte=LoadByte(pc);
963 pc=(pc+1)&0xffff;
964 break;
965 /* [Don't Care] */
966 case 3 : if ((res&0xff)&&(!((sign^((~(m1^m2))&(m1^ovfl)))&0x80)))
967 pc=(pc+byte)&0xffff;
968 step=0; /* reset fetch */
969 break;
970 }
971 }
972
bles(void)973 static void bles(void) { /* branch if Z|(N^V)=1 */
974 switch (step) {
975 /* [Offset : NNNN+1] */
976 case 2 : byte=LoadByte(pc);
977 pc=(pc+1)&0xffff;
978 break;
979 /* [Don't Care] */
980 case 3 : if ((!(res&0xff))||((sign^((~(m1^m2))&(m1^ovfl)))&0x80))
981 pc=(pc+byte)&0xffff;
982 step=0; /* reset fetch */
983 break;
984 }
985 }
986
987 /* ========================================================== */
988 /* LBCC LBCS LBGE LBGT LBHI LBHS LBLE LBLS LBLT LBMI LBNE */
989 /* LBPL LBRA LBRN LBVC LBVS */
990 /* ========================================================== */
991
lbra(void)992 static void lbra(void) { /* branch always */
993 switch (step) {
994 /* [Offset High : NNNN+2] */
995 case 2 : value=LoadByte(pc)<<8;
996 pc=(pc+1)&0xffff;
997 break;
998 /* [Offset Low : NNNN+3] */
999 case 3 : value|=LoadByte(pc);
1000 pc=(pc+1)&0xffff;
1001 break;
1002 /* [Don't Care] */
1003 case 5 : pc=(pc+value)&0xffff;
1004 step=0; /* reset fetch */
1005 break;
1006 /* Case 4 = [Don't Care] */
1007 default: break;
1008 }
1009 }
1010
lbrn(void)1011 static void lbrn(void) { /* branch never */
1012 switch (step) {
1013 /* [Offset High : NNNN+2] */
1014 case 2 : value=LoadByte(pc)<<8;
1015 pc=(pc+1)&0xffff;
1016 break;
1017 /* [Offset Low : NNNN+3] */
1018 case 3 : value|=LoadByte(pc);
1019 pc=(pc+1)&0xffff;
1020 break;
1021 /* Case 4 = [Don't Care] */
1022 default: step=0; /* reset fetch */
1023 break;
1024 }
1025 }
1026
lbhi(void)1027 static void lbhi(void) { /* branch if c|z=0 */
1028 switch (step) {
1029 /* [Offset High : NNNN+2] */
1030 case 2 : value=LoadByte(pc)<<8;
1031 pc=(pc+1)&0xffff;
1032 break;
1033 /* [Offset Low : NNNN+3] */
1034 case 3 : value|=LoadByte(pc);
1035 pc=(pc+1)&0xffff;
1036 break;
1037 /* [Don't Care] */
1038 case 4 : if ((res&0x100)||(!(res&0xff)))
1039 step=0; /* reset fetch */
1040 break;
1041 /* Case 5 = [Don't Care] */
1042 default: pc=(pc+value)&0xffff;
1043 step=0; /* reset fetch */
1044 break;
1045 }
1046 }
1047
lbls(void)1048 static void lbls(void) { /* c|z=1 */
1049 switch (step) {
1050 /* [Offset High : NNNN+2] */
1051 case 2 : value=LoadByte(pc)<<8;
1052 pc=(pc+1)&0xffff;
1053 break;
1054 /* [Offset Low : NNNN+3] */
1055 case 3 : value|=LoadByte(pc);
1056 pc=(pc+1)&0xffff;
1057 break;
1058 /* [Don't Care] */
1059 case 4 : if ((!(res&0x100))&&(res&0xff))
1060 step=0; /* reset fetch */
1061 break;
1062 /* Case 5 = [Don't Care] */
1063 default: pc=(pc+value)&0xffff;
1064 step=0; /* reset fetch */
1065 break;
1066 }
1067 }
1068
lbcc(void)1069 static void lbcc(void) { /* c=0 */
1070 switch (step) {
1071 /* [Offset High : NNNN+2] */
1072 case 2 : value=LoadByte(pc)<<8;
1073 pc=(pc+1)&0xffff;
1074 break;
1075 /* [Offset Low : NNNN+3] */
1076 case 3 : value|=LoadByte(pc);
1077 pc=(pc+1)&0xffff;
1078 break;
1079 /* [Don't Care] */
1080 case 4 : if (res&0x100)
1081 step=0; /* reset fetch */
1082 break;
1083 /* Case 5 = [Don't Care] */
1084 default: pc=(pc+value)&0xffff;
1085 step=0; /* reset fetch */
1086 break;
1087 }
1088 }
1089
lblo(void)1090 static void lblo(void) { /* c=1 */
1091 switch (step) {
1092 /* [Offset High : NNNN+2] */
1093 case 2 : value=LoadByte(pc)<<8;
1094 pc=(pc+1)&0xffff;
1095 break;
1096 /* [Offset Low : NNNN+3] */
1097 case 3 : value|=LoadByte(pc);
1098 pc=(pc+1)&0xffff;
1099 break;
1100 /* [Don't Care] */
1101 case 4 : if (!(res&0x100))
1102 step=0; /* reset fetch */
1103 break;
1104 /* Case 5 = [Don't Care] */
1105 default: pc=(pc+value)&0xffff;
1106 step=0; /* reset fetch */
1107 break;
1108 }
1109 }
1110
lbne(void)1111 static void lbne(void) { /* z=0 */
1112 switch (step) {
1113 /* [Offset High : NNNN+2] */
1114 case 2 : value=LoadByte(pc)<<8;
1115 pc=(pc+1)&0xffff;
1116 break;
1117 /* [Offset Low : NNNN+3] */
1118 case 3 : value|=LoadByte(pc);
1119 pc=(pc+1)&0xffff;
1120 break;
1121 /* [Don't Care] */
1122 case 4 : if (!(res&0xff))
1123 step=0; /* reset fetch */
1124 break;
1125 /* Case 5 = [Don't Care] */
1126 default: pc=(pc+value)&0xffff;
1127 step=0; /* reset fetch */
1128 break;
1129 }
1130 }
1131
lbeq(void)1132 static void lbeq(void) { /* z=1 */
1133 switch (step) {
1134 /* [Offset High : NNNN+2] */
1135 case 2 : value=LoadByte(pc)<<8;
1136 pc=(pc+1)&0xffff;
1137 break;
1138 /* [Offset Low : NNNN+3] */
1139 case 3 : value|=LoadByte(pc);
1140 pc=(pc+1)&0xffff;
1141 break;
1142 /* [Don't Care] */
1143 case 4 : if (res&0xff)
1144 step=0; /* reset fetch */
1145 break;
1146 /* Case 5 = [Don't Care] */
1147 default: pc=(pc+value)&0xffff;
1148 step=0; /* reset fetch */
1149 break;
1150 }
1151 }
1152
lbvc(void)1153 static void lbvc(void) { /* v=0 */
1154 switch (step) {
1155 /* [Offset High : NNNN+2] */
1156 case 2 : value=LoadByte(pc)<<8;
1157 pc=(pc+1)&0xffff;
1158 break;
1159 /* [Offset Low : NNNN+3] */
1160 case 3 : value|=LoadByte(pc);
1161 pc=(pc+1)&0xffff;
1162 break;
1163 /* [Don't Care] */
1164 case 4 : if ((!((m1^m2)&0x80))&&((m1^ovfl)&0x80))
1165 step=0; /* reset fetch */
1166 break;
1167 /* Case 5 = [Don't Care] */
1168 default: pc=(pc+value)&0xffff;
1169 step=0; /* reset fetch */
1170 break;
1171 }
1172 }
1173
lbvs(void)1174 static void lbvs(void) { /* v=1 */
1175 switch (step) {
1176 /* [Offset High : NNNN+2] */
1177 case 2 : value=LoadByte(pc)<<8;
1178 pc=(pc+1)&0xffff;
1179 break;
1180 /* [Offset Low : NNNN+3] */
1181 case 3 : value|=LoadByte(pc);
1182 pc=(pc+1)&0xffff;
1183 break;
1184 /* [Don't Care] */
1185 case 4 : if (((m1^m2)&0x80)||(!((m1^ovfl)&0x80)))
1186 step=0; /* reset fetch */
1187 break;
1188 /* Case 5 = [Don't Care] */
1189 default: pc=(pc+value)&0xffff;
1190 step=0; /* reset fetch */
1191 break;
1192 }
1193 }
1194
lbpl(void)1195 static void lbpl(void) { /* n=0 */
1196 switch (step) {
1197 /* [Offset High : NNNN+2] */
1198 case 2 : value=LoadByte(pc)<<8;
1199 pc=(pc+1)&0xffff;
1200 break;
1201 /* [Offset Low : NNNN+3] */
1202 case 3 : value|=LoadByte(pc);
1203 pc=(pc+1)&0xffff;
1204 break;
1205 /* [Don't Care] */
1206 case 4 : if (sign&0x80)
1207 step=0; /* reset fetch */
1208 break;
1209 /* Case 5 = [Don't Care] */
1210 default: pc=(pc+value)&0xffff;
1211 step=0; /* reset fetch */
1212 break;
1213 }
1214 }
1215
lbmi(void)1216 static void lbmi(void) { /* n=1 */
1217 switch (step) {
1218 /* [Offset High : NNNN+2] */
1219 case 2 : value=LoadByte(pc)<<8;
1220 pc=(pc+1)&0xffff;
1221 break;
1222 /* [Offset Low : NNNN+3] */
1223 case 3 : value|=LoadByte(pc);
1224 pc=(pc+1)&0xffff;
1225 break;
1226 /* [Don't Care] */
1227 case 4 : if (!(sign&0x80))
1228 step=0; /* reset fetch */
1229 break;
1230 /* Case 5 = [Don't Care] */
1231 default: pc=(pc+value)&0xffff;
1232 step=0; /* reset fetch */
1233 break;
1234 }
1235 }
1236
lbge(void)1237 static void lbge(void) { /* n^v=0 */
1238 switch (step) {
1239 /* [Offset High : NNNN+2] */
1240 case 2 : value=LoadByte(pc)<<8;
1241 pc=(pc+1)&0xffff;
1242 break;
1243 /* [Offset Low : NNNN+3] */
1244 case 3 : value|=LoadByte(pc);
1245 pc=(pc+1)&0xffff;
1246 break;
1247 /* [Don't Care] */
1248 case 4 : if ((sign^((~(m1^m2))&(m1^ovfl)))&0x80)
1249 step=0; /* reset fetch */
1250 break;
1251 /* Case 5 = [Don't Care] */
1252 default: pc=(pc+value)&0xffff;
1253 step=0; /* reset fetch */
1254 break;
1255 }
1256 }
1257
lblt(void)1258 static void lblt(void) { /* n^v=1 */
1259 switch (step) {
1260 /* [Offset High : NNNN+2] */
1261 case 2 : value=LoadByte(pc)<<8;
1262 pc=(pc+1)&0xffff;
1263 break;
1264 /* [Offset Low : NNNN+3] */
1265 case 3 : value|=LoadByte(pc);
1266 pc=(pc+1)&0xffff;
1267 break;
1268 /* [Don't Care] */
1269 case 4 : if (!((sign^((~(m1^m2))&(m1^ovfl)))&0x80))
1270 step=0; /* reset fetch */
1271 break;
1272 /* Case 5 = [Don't Care] */
1273 default: pc=(pc+value)&0xffff;
1274 step=0; /* reset fetch */
1275 break;
1276 }
1277 }
1278
lbgt(void)1279 static void lbgt(void) { /* z|(n^v)=0 */
1280 switch (step) {
1281 /* [Offset High : NNNN+2] */
1282 case 2 : value=LoadByte(pc)<<8;
1283 pc=(pc+1)&0xffff;
1284 break;
1285 /* [Offset Low : NNNN+3] */
1286 case 3 : value|=LoadByte(pc);
1287 pc=(pc+1)&0xffff;
1288 break;
1289 /* [Don't Care] */
1290 case 4 : if ((!(res&0xff))||((sign^((~(m1^m2))&(m1^ovfl)))&0x80))
1291 step=0; /* reset fetch */
1292 break;
1293 /* Case 5 = [Don't Care] */
1294 default: pc=(pc+value)&0xffff;
1295 step=0; /* reset fetch */
1296 break;
1297 }
1298 }
1299
lble(void)1300 static void lble(void) { /* z|(n^v)=1 */
1301 switch (step) {
1302 /* [Offset High : NNNN+2] */
1303 case 2 : value=LoadByte(pc)<<8;
1304 pc=(pc+1)&0xffff;
1305 break;
1306 /* [Offset Low : NNNN+3] */
1307 case 3 : value|=LoadByte(pc);
1308 pc=(pc+1)&0xffff;
1309 break;
1310 /* [Don't Care] */
1311 case 4 : if ((res&0xff)&&(!((sign^((~(m1^m2))&(m1^ovfl)))&0x80)))
1312 step=0; /* reset fetch */
1313 break;
1314 /* Case 5 = [Don't Care] */
1315 default: pc=(pc+value)&0xffff;
1316 step=0; /* reset fetch */
1317 break;
1318 }
1319 }
1320
1321 /* ========================================================== */
1322 /* BSR LBSR */
1323 /* ========================================================== */
1324
bsrm(void)1325 static void bsrm(void) {
1326 switch (step) {
1327 /* [Offset : NNNN+1] */
1328 case 2 : byte=LoadByte(pc);
1329 pc=(pc+1)&0xffff;
1330 break;
1331 /* Return Address Low : Stack */
1332 case 6 : sr=(sr-1)&0xffff;
1333 StoreByte(sr,pc);
1334 break;
1335 /* Return Address High : Stack */
1336 case 7 : sr=(sr-1)&0xffff;
1337 StoreByte(sr,pc>>8);
1338 pc=(pc+byte)&0xffff;
1339 step=0; /* reset fetch */
1340 break;
1341 /* Cases 3,4,5 = [Don't Care] */
1342 default: break;
1343 }
1344 }
1345
lbsr(void)1346 static void lbsr(void) {
1347 switch (step) {
1348 /* [Offset : NNNN+1] */
1349 case 2 : value=LoadByte(pc)<<8;
1350 pc=(pc+1)&0xffff;
1351 break;
1352 /* [Offset : NNNN+2] */
1353 case 3 : value|=LoadByte(pc);
1354 pc=(pc+1)&0xffff;
1355 break;
1356 /* Return Address Low : Stack */
1357 case 8 : sr=(sr-1)&0xffff;
1358 StoreByte(sr,pc);
1359 break;
1360 /* Return Address High : Stack */
1361 case 9 : sr=(sr-1)&0xffff;
1362 StoreByte(sr,pc>>8);
1363 pc=(pc+value)&0xffff;
1364 step=0; /* reset fetch */
1365 break;
1366 /* Cases 4,5,6,7 = [Don't Care] */
1367 default: break;
1368 }
1369 }
1370
1371 /* ========================================================== */
1372 /* LEAX/Y/U/S */
1373 /* ========================================================== */
1374
leax(void)1375 static void leax(void) { /* Zx */
1376 switch (step) {
1377 /* [Don't Care] */
1378 case 0x21: xr=address;
1379 res=(res&0x100)|((xr|(xr>>8))&0xff);
1380 step=0; /* reset fetch */
1381 break;
1382 /* Compute Address */
1383 default : compute_address();
1384 break;
1385 }
1386 }
1387
leay(void)1388 static void leay(void) { /* Zx */
1389 switch (step) {
1390 /* [Don't Care] */
1391 case 0x21: yr=address;
1392 res=(res&0x100)|((yr|(yr>>8))&0xff);
1393 step=0; /* reset fetch */
1394 break;
1395 /* Compute Address */
1396 default : compute_address();
1397 break;
1398 }
1399 }
1400
leas(void)1401 static void leas(void) {
1402 switch (step) {
1403 /* [Don't Care] */
1404 case 0x21: sr=address;
1405 step=0; /* reset fetch */
1406 break;
1407 /* Compute Address */
1408 default : compute_address();
1409 break;
1410 }
1411 }
1412
leau(void)1413 static void leau(void) {
1414 switch (step) {
1415 /* [Don't Care] */
1416 case 0x21: ur=address;
1417 step=0; /* reset fetch */
1418 break;
1419 /* Compute Address */
1420 default : compute_address();
1421 break;
1422 }
1423 }
1424
1425 /* ========================================================== */
1426 /* PSHS/U PULS/U */
1427 /* ========================================================== */
1428
pshsr(void)1429 static void pshsr(void) {
1430 sr=(sr-1)&0xffff; /* stack-1 */
1431 if (value&0x100) {
1432 if (value&0x80) { StoreByte(sr,pc>>8); value^=0x180; } /* [PC High] */
1433 else if (value&0x40) { StoreByte(sr,ur>>8); value^=0x140; } /* [U High] */
1434 else if (value&0x20) { StoreByte(sr,yr>>8); value^=0x120; } /* [Y High] */
1435 else { StoreByte(sr,xr>>8); value^=0x110; } /* [X High] */
1436 }
1437 else if (value&0x80) { StoreByte(sr,pc); value|=0x100; } /* [PC Low] */
1438 else if (value&0x40) { StoreByte(sr,ur); value|=0x100; } /* [U Low] */
1439 else if (value&0x20) { StoreByte(sr,yr); value|=0x100; } /* [Y Low] */
1440 else if (value&0x10) { StoreByte(sr,xr); value|=0x100; } /* [X Low] */
1441 else if (value&0x08) { StoreByte(sr,dp); value^=0x08; } /* [DP] */
1442 else if (value&0x04) { StoreByte(sr,br); value^=0x04; } /* [B] */
1443 else if (value&0x02) { StoreByte(sr,ar); value^=0x02; } /* [A] */
1444 else { StoreByte(sr,getcc()); value^=0x01; } /* [CC] */
1445 }
1446
pshs(void)1447 static void pshs(void) {
1448 switch (step) {
1449 /* Post Byte : NNNN+1] */
1450 case 2 : value=LoadByte(pc);
1451 pc=(pc+1)&0xffff;
1452 break;
1453 /* [Don't Care] */
1454 case 3 :
1455 case 4 : break;
1456 /* [Don't Care] */
1457 case 5 : if (value==0) step=0; /* reset fetch if nothing to push */
1458 break;
1459 /* push registers */
1460 default: pshsr();
1461 if (value==0) step=0; /* reset fetch if nothing left to push */
1462 break;
1463 }
1464 }
1465
pulsr(void)1466 static void pulsr(void) {
1467 if (value&0x100) {
1468 if (value&0x10) { xr|=LoadByte(sr); value^=0x110; } /* [X Low] */
1469 else if (value&0x20) { yr|=LoadByte(sr); value^=0x120; } /* [Y Low] */
1470 else if (value&0x40) { ur|=LoadByte(sr); value^=0x140; } /* [U Low] */
1471 else { pc|=LoadByte(sr); value^=0x180; } /* [PC Low] */
1472 }
1473 else if (value&0x01) { setcc(LoadByte(sr)); value^=0x01; } /* [CC] */
1474 else if (value&0x02) { ar=LoadByte(sr); value^=0x02; } /* [A] */
1475 else if (value&0x04) { br=LoadByte(sr); value^=0x04; } /* [B] */
1476 else if (value&0x08) { dp=LoadByte(sr); value^=0x08; } /* [DP] */
1477 else if (value&0x10) { xr=LoadByte(sr)<<8; value|=0x100; } /* [X High] */
1478 else if (value&0x20) { yr=LoadByte(sr)<<8; value|=0x100; } /* [Y High] */
1479 else if (value&0x40) { ur=LoadByte(sr)<<8; value|=0x100; } /* [U High] */
1480 else { pc=LoadByte(sr)<<8; value|=0x100; } /* [PC High] */
1481 sr=(sr+1)&0xffff; /* stack+1 */
1482 }
1483
puls(void)1484 static void puls(void) {
1485 switch (step) {
1486 /* Post Byte : NNNN+1] */
1487 case 2 : value=LoadByte(pc);
1488 pc=(pc+1)&0xffff;
1489 break;
1490 /* [Don't Care] */
1491 case 3 : break;
1492 /* [Don't Care] */
1493 case 4 : if (value==0) step=0x20; /* skip if nothing to pull */
1494 break;
1495 /* [Don't Care] */
1496 case 0x21 : step=0; /* reset fetch */
1497 break;
1498 /* pull registers */
1499 default: pulsr();
1500 if (value==0) step=0x20; /* skip if nothing left to pull */
1501 break;
1502 }
1503 }
1504
pshu(void)1505 static void pshu(void) {
1506 switch (step) {
1507 /* Post Byte : NNNN+1] */
1508 case 2 : value=LoadByte(pc);
1509 pc=(pc+1)&0xffff;
1510 break;
1511 /* [Don't Care] */
1512 case 3 :
1513 case 4 : break;
1514 /* [Don't Care] */
1515 case 5 : if (value==0) step=0; /* reset fetch if nothing to push */
1516 break;
1517 /* push registers */
1518 default:
1519 ur=(ur-1)&0xffff; /* stack-1 */
1520 if (value&0x100) {
1521 if (value&0x80) { StoreByte(ur,pc>>8); value^=0x180; } /* [PC High] */
1522 else if (value&0x40) { StoreByte(ur,sr>>8); value^=0x140; } /* [S High] */
1523 else if (value&0x20) { StoreByte(ur,yr>>8); value^=0x120; } /* [Y High] */
1524 else { StoreByte(ur,xr>>8); value^=0x110; } /* [X High] */
1525 }
1526 else if (value&0x80) { StoreByte(ur,pc); value|=0x100; } /* [PC Low] */
1527 else if (value&0x40) { StoreByte(ur,sr); value|=0x100; } /* [S Low] */
1528 else if (value&0x20) { StoreByte(ur,yr); value|=0x100; } /* [Y Low] */
1529 else if (value&0x10) { StoreByte(ur,xr); value|=0x100; } /* [X Low] */
1530 else if (value&0x08) { StoreByte(ur,dp); value^=0x08; } /* [DP] */
1531 else if (value&0x04) { StoreByte(ur,br); value^=0x04; } /* [B] */
1532 else if (value&0x02) { StoreByte(ur,ar); value^=0x02; } /* [A] */
1533 else { StoreByte(ur,getcc()); value^=0x01; } /* [CC] */
1534 if (value==0) step=0; /* reset fetch if nothing left to push */
1535 break;
1536 }
1537 }
1538
pulu(void)1539 static void pulu(void) {
1540 switch (step) {
1541 /* [Post Byte : NNNN+1] */
1542 case 2 : postcode=LoadByte(pc);
1543 pc=(pc+1)&0xffff;
1544 value=postcode;
1545 break;
1546 /* [Don't Care] */
1547 case 3 : break;
1548 /* [Don't Care] */
1549 case 4 : if (value==0) step=0x21; /* skip if nothing to pull */
1550 break;
1551 /* [Don't Care] */
1552 case 0x21 : step=0; /* reset fetch */
1553 break;
1554 /* pull registers */
1555 default:
1556 if (value&0x100) {
1557 if (value&0x10) { xr|=LoadByte(ur); value^=0x110; } /* [X Low] */
1558 else if (value&0x20) { yr|=LoadByte(ur); value^=0x120; } /* [Y Low] */
1559 else if (value&0x40) { sr|=LoadByte(ur); value^=0x140; } /* [S Low] */
1560 else { pc|=LoadByte(ur); value^=0x180; } /* [PC Low] */
1561 }
1562 else if (value&0x01) { setcc(LoadByte(ur)); value^=0x01; } /* [CC] */
1563 else if (value&0x02) { ar=LoadByte(ur); value^=0x02; } /* [A] */
1564 else if (value&0x04) { br=LoadByte(ur); value^=0x04; } /* [B] */
1565 else if (value&0x08) { dp=LoadByte(ur); value^=0x08; } /* [DP] */
1566 else if (value&0x10) { xr=LoadByte(ur)<<8; value|=0x100; } /* [X High] */
1567 else if (value&0x20) { yr=LoadByte(ur)<<8; value|=0x100; } /* [Y High] */
1568 else if (value&0x40) { sr=LoadByte(ur)<<8; value|=0x100; } /* [S High] */
1569 else { pc=LoadByte(ur)<<8; value|=0x100; } /* [PC High] */
1570 ur=(ur+1)&0xffff; /* stack+1 */
1571 if (value==0) step=0x20; /* skip if nothing left to pull */
1572 break;
1573 }
1574 }
1575
1576 /* ========================================================== */
1577 /* RTI */
1578 /* ========================================================== */
1579
rtim(void)1580 static void rtim(void) {
1581 switch (step) {
1582 /* [Don't Care : NNNN+1] */
1583 case 2 : break;
1584 /* CCR : Stack] */
1585 case 3 : value=0x01;
1586 pulsr();
1587 value=(ccrest&0x80)?0xfe:0x80;
1588 break;
1589 /* [Don't Care : Stack] */
1590 case 0x21 : irq_run=0;
1591 step=0; /* reset fetch */
1592 break;
1593 /* pull registers */
1594 default: pulsr();
1595 if (value==0) step=0x20; /* skip if nothing left to pull */
1596 break;
1597 }
1598 }
1599
1600 /* ========================================================== */
1601 /* NOP DAA SEX */
1602 /* ========================================================== */
1603
nopm(void)1604 static void nopm(void) {
1605 /* [Don't Care : NNNN+1] */
1606 step=0; /* reset fetch */
1607 }
1608
daam(void)1609 static void daam(void) { /* NxZxV?Cx */
1610 int i=ar+(res&0x100);
1611 /* [Don't Care : NNNN+1] */
1612 if (((ar&15)>9)||((h1&15)+(h2&15)>15)) i+=6;
1613 if (i>0x99) i+=0x60;
1614 res=sign=i;
1615 ar=i&0xff;
1616 step=0; /* reset fetch */
1617 }
1618
sexm(void)1619 static void sexm(void) { /* NxZx */
1620 /* [Don't Care : NNNN+1] */
1621 ar=(br&0x80)?0xff:0;
1622 sign=br;
1623 res=(res&0x100)|sign;
1624 step=0; /* reset fetch */
1625 }
1626
1627 /* ========================================================== */
1628 /* ASLA/B ASRA/B CLRA/B COMA/B DECA/B INCA/B LSRA/B NEGA/B */
1629 /* ROLA/B RORA/B TSTA/B */
1630 /* ========================================================== */
1631
asla(void)1632 static void asla(void) { /* H?NxZxVxCx */
1633 /* [Don't Care : NNNN+1] */
1634 m1=m2=ar;
1635 ar<<=1;
1636 ovfl=sign=res=ar;
1637 ar&=0xff;
1638 step=0; /* reset fetch */
1639 }
1640
aslb(void)1641 static void aslb(void) { /* H?NxZxVxCx */
1642 /* [Don't Care : NNNN+1] */
1643 m1=m2=br;
1644 br<<=1;
1645 ovfl=sign=res=br;
1646 br&=0xff;
1647 step=0; /* reset fetch */
1648 }
1649
asra(void)1650 static void asra(void) { /* H?NxZxCx */
1651 /* [Don't Care : NNNN+1] */
1652 res=(ar&1)<<8;
1653 ar=(ar>>1)|(ar&0x80);
1654 sign=ar;
1655 res|=sign;
1656 step=0; /* reset fetch */
1657 }
1658
asrb(void)1659 static void asrb(void) { /* H?NxZxCx */
1660 /* [Don't Care : NNNN+1] */
1661 res=(br&1)<<8;
1662 br=(br>>1)|(br&0x80);
1663 sign=br;
1664 res|=sign;
1665 step=0; /* reset fetch */
1666 }
1667
clra(void)1668 static void clra(void) { /* N0Z1V0C0 */
1669 /* [Don't Care : NNNN+1] */
1670 ar=0;
1671 m1=ovfl;
1672 sign=res=0;
1673 step=0; /* reset fetch */
1674 }
1675
clrb(void)1676 static void clrb(void) { /* N0Z1V0C0 */
1677 /* [Don't Care : NNNN+1] */
1678 br=0;
1679 m1=ovfl;
1680 sign=res=0;
1681 step=0; /* reset fetch */
1682 }
1683
coma(void)1684 static void coma(void) { /* NxZxV0C1 */
1685 /* [Don't Care : NNNN+1] */
1686 m1=ovfl;
1687 ar^=0xff;
1688 sign=ar;
1689 res=sign|0x100; /* bit C a 1 */
1690 step=0; /* reset fetch */
1691 }
1692
comb(void)1693 static void comb(void) { /* NxZxV0C1 */
1694 /* [Don't Care : NNNN+1] */
1695 m1=ovfl;
1696 br^=0xff;
1697 sign=br;
1698 res=sign|0x100; /* bit C a 1 */
1699 step=0; /* reset fetch */
1700 }
1701
deca(void)1702 static void deca(void) { /* NxZxVx */
1703 /* [Don't Care : NNNN+1] */
1704 m1=ar; m2=0x80;
1705 ar=(ar-1)&0xff;
1706 ovfl=sign=ar;
1707 res=(res&0x100)|sign;
1708 step=0; /* reset fetch */
1709 }
1710
decb(void)1711 static void decb(void) { /* NxZxVx */
1712 /* [Don't Care : NNNN+1] */
1713 m1=br; m2=0x80;
1714 br=(br-1)&0xff;
1715 ovfl=sign=br;
1716 res=(res&0x100)|sign;
1717 step=0; /* reset fetch */
1718 }
1719
inca(void)1720 static void inca(void) { /* NxZxVx */
1721 /* [Don't Care : NNNN+1] */
1722 m1=ar; m2=0;
1723 ar=(ar+1)&0xff;
1724 ovfl=sign=ar;
1725 res=(res&0x100)|sign;
1726 step=0; /* reset fetch */
1727 }
1728
incb(void)1729 static void incb(void) { /* NxZxVx */
1730 /* [Don't Care : NNNN+1] */
1731 m1=br; m2=0;
1732 br=(br+1)&0xff;
1733 ovfl=sign=br;
1734 res=(res&0x100)|sign;
1735 step=0; /* reset fetch */
1736 }
1737
lsra(void)1738 static void lsra(void) { /* N0ZxCx */
1739 /* [Don't Care : NNNN+1] */
1740 res=(ar&1)<<8; /* bit C */
1741 ar>>=1;
1742 sign=0;
1743 res|=ar;
1744 step=0; /* reset fetch */
1745 }
1746
lsrb(void)1747 static void lsrb(void) { /* N0ZxCx */
1748 /* [Don't Care : NNNN+1] */
1749 res=(br&1)<<8; /* bit C */
1750 br>>=1;
1751 sign=0;
1752 res|=br;
1753 step=0; /* reset fetch */
1754 }
1755
nega(void)1756 static void nega(void) { /* H?NxZxVxCx */
1757 /* [Don't Care : NNNN+1] */
1758 m1=ar; m2=-ar; /* bit V */
1759 ar=-ar;
1760 ovfl=res=sign=ar;
1761 ar&=0xff;
1762 step=0; /* reset fetch */
1763 }
1764
negb(void)1765 static void negb(void) { /* H?NxZxVxCx */
1766 /* [Don't Care : NNNN+1] */
1767 m1=br; m2=-br; /* bit V */
1768 br=-br;
1769 ovfl=res=sign=br;
1770 br&=0xff;
1771 step=0; /* reset fetch */
1772 }
1773
rola(void)1774 static void rola(void) { /* NxZxVxCx */
1775 /* [Don't Care : NNNN+1] */
1776 m1=m2=ar;
1777 ar=(ar<<1)|((res&0x100)>>8);
1778 ovfl=sign=res=ar;
1779 ar&=0xff;
1780 step=0; /* reset fetch */
1781 }
1782
rolb(void)1783 static void rolb(void) { /* NxZxVxCx */
1784 /* [Don't Care : NNNN+1] */
1785 m1=m2=br;
1786 br=(br<<1)|((res&0x100)>>8);
1787 ovfl=sign=res=br;
1788 br&=0xff;
1789 step=0; /* reset fetch */
1790 }
1791
rora(void)1792 static void rora(void) { /* NxZxCx */
1793 /* [Don't Care : NNNN+1] */
1794 sign=(ar|(res&0x100))>>1;
1795 res=((ar&1)<<8)|sign;
1796 ar=sign;
1797 step=0; /* reset fetch */
1798 }
1799
rorb(void)1800 static void rorb(void) { /* NxZxCx */
1801 /* [Don't Care : NNNN+1] */
1802 sign=(br|(res&0x100))>>1;
1803 res=((br&1)<<8)|sign;
1804 br=sign;
1805 step=0; /* reset fetch */
1806 }
1807
tsta(void)1808 static void tsta(void) { /* NxZxV0 */
1809 /* [Don't Care : NNNN+1] */
1810 m1=ovfl;
1811 sign=ar;
1812 res=(res&0x100)|sign;
1813 step=0; /* reset fetch */
1814 }
1815
tstb(void)1816 static void tstb(void) { /* NxZxV0 */
1817 /* [Don't Care : NNNN+1] */
1818 m1=ovfl;
1819 sign=br;
1820 res=(res&0x100)|sign;
1821 step=0; /* reset fetch */
1822 }
1823
1824 /* ========================================================== */
1825 /* ORCC ANDCC */
1826 /* ========================================================== */
1827
orcc(void)1828 static void orcc(void) {
1829 switch (step) {
1830 /* [data : NNNN+1] */
1831 case 2 : value=LoadByte(pc);
1832 pc=(pc+1)&0xffff;
1833 break;
1834 /* [Don't Care] */
1835 case 3 : setcc(getcc()|value);
1836 step=0; /* reset fetch */
1837 break;
1838 }
1839 }
1840
andc(void)1841 static void andc(void) {
1842 switch (step) {
1843 /* [data : NNNN+1] */
1844 case 2 : value=LoadByte(pc);
1845 pc=(pc+1)&0xffff;
1846 break;
1847 /* [Don't Care] */
1848 case 3 : setcc(getcc()&value);
1849 step=0; /* reset fetch */
1850 break;
1851 }
1852 }
1853
1854 /* ========================================================== */
1855 /* ABX */
1856 /* ========================================================== */
1857
abxm(void)1858 static void abxm(void) {
1859 switch (step) {
1860 /* [Don't Care] */
1861 case 3 : xr=(xr+br)&0xffff;
1862 step=0; /* reset fetch */
1863 break;
1864 /* Case 2 = [Don't Care] */
1865 default: break;
1866 }
1867 }
1868
1869 /* ========================================================== */
1870 /* RTS */
1871 /* ========================================================== */
1872
rtsm(void)1873 static void rtsm(void) {
1874 switch (step) {
1875 /* PC High : Stack */
1876 case 3 : pc=LoadByte(sr)<<8;
1877 sr=(sr+1)&0xffff;
1878 break;
1879 /* PC Low : Stack */
1880 case 4 : pc|=LoadByte(sr);
1881 sr=(sr+1)&0xffff;
1882 break;
1883 /* Cases 5 = [Don't Care] */
1884 case 5 : step=0; /* reset fetch */
1885 break;
1886 /* Case 2 = [Don't Care] */
1887 default: break;
1888 }
1889 }
1890
1891 /* ========================================================== */
1892 /* MUL */
1893 /* ========================================================== */
1894
mulm(void)1895 static void mulm(void) { /* ZxCx */
1896 switch (step) {
1897 /* [Don't Care] */
1898 case 11 : value=ar*br;
1899 ar=(value>>8)&0xff;
1900 br=value&0xff;
1901 res=((br&0x80)<<1)|ar|br; /* c=bit7 de br */
1902 step=0; /* reset fetch */
1903 break;
1904 /* Case 2->10 = [Don't Care] */
1905 default : break;
1906 }
1907 }
1908
1909 /* ========================================================== */
1910 /* Software interrupts */
1911 /* SWI SWI2 SWI3 */
1912 /* ========================================================== */
1913
swim(void)1914 static void swim(void) {
1915 switch (step) {
1916 /* [Don't Care] */
1917 case 2 : ccrest|=0x80;
1918 value=0xff; /* push all registers */
1919 break;
1920 /* [Don't Care] */
1921 case 3 : break;
1922 /* [Don't Care] */
1923 case 16 : ccrest|=0x50; /* F,I masked */
1924 break;
1925 /* [Interrupt Vector High : FFFX] */
1926 case 17 : pc=LoadByte(swi_vector[page>>8])<<8;
1927 break;
1928 /* [Interrupt Vector Low : FFFX+1] */
1929 case 18 : pc|=LoadByte(swi_vector[page>>8]+1);
1930 break;
1931 /* [Don't Care] */
1932 case 19 : step=0; /* reset fetch */
1933 break;
1934 /* case 4->15 = push registers */
1935 default : pshsr();
1936 break;
1937 }
1938 }
1939
1940 /* ========================================================== */
1941 /* ADCA/B ADDA/B ANDA/B BITA/B CMPA/B EORA/B LDA/B ORA/B */
1942 /* SBCA/B SUBA/B */
1943 /* ========================================================== */
1944 /* Code is written without 'switch' or 'else' because of */
1945 /* immediate addressing mode : all must be done in 2 cycles. */
1946
adca(void)1947 static void adca(void) { /* HxNxZxVxCx */
1948 /* compute address */
1949 if (step<0x21) compute_address();
1950 /* [Data : EA] */
1951 if (step==0x21) {
1952 value=LoadByte(address);
1953 m1=h1=ar; m2=value;
1954 h2=value+((res&0x100)>>8);
1955 ar+=h2;
1956 ovfl=res=sign=ar;
1957 ar&=0xff;
1958 step=0; /* reset fetch */
1959 }
1960 }
1961
adcb(void)1962 static void adcb(void) { /* HxNxZxVxCx */
1963 /* compute address */
1964 if (step<0x21) compute_address();
1965 /* [Data : EA] */
1966 if (step==0x21) {
1967 value=LoadByte(address);
1968 m1=h1=br; m2=value;
1969 h2=value+((res&0x100)>>8);
1970 br+=h2;
1971 ovfl=res=sign=br;
1972 br&=0xff;
1973 step=0; /* reset fetch */
1974 }
1975 }
1976
adda(void)1977 static void adda(void) { /* HxNxZxVxCx */
1978 /* compute address */
1979 if (step<0x21) compute_address();
1980 /* [Data : EA] */
1981 if (step==0x21) {
1982 value=LoadByte(address);
1983 m1=h1=ar; m2=h2=value;
1984 ar+=value;
1985 ovfl=res=sign=ar;
1986 ar&=0xff;
1987 step=0; /* reset fetch */
1988 }
1989 }
1990
addb(void)1991 static void addb(void) { /* HxNxZxVxCx */
1992 /* compute address */
1993 if (step<0x21) compute_address();
1994 /* [Data : EA] */
1995 if (step==0x21) {
1996 value=LoadByte(address);
1997 m1=h1=br; m2=h2=value;
1998 br+=value;
1999 ovfl=res=sign=br;
2000 br&=0xff;
2001 step=0; /* reset fetch */
2002 }
2003 }
2004
anda(void)2005 static void anda(void) { /* NxZxV0 */
2006 /* compute address */
2007 if (step<0x21) compute_address();
2008 /* [Data : EA] */
2009 if (step==0x21) {
2010 value=LoadByte(address);
2011 m1=ovfl;
2012 ar&=value;
2013 sign=ar;
2014 res=(res&0x100)|sign;
2015 step=0; /* reset fetch */
2016 }
2017 }
2018
andb(void)2019 static void andb(void) { /* NxZxV0 */
2020 /* compute address */
2021 if (step<0x21) compute_address();
2022 /* [Data : EA] */
2023 if (step==0x21) {
2024 value=LoadByte(address);
2025 m1=ovfl;
2026 br&=value;
2027 sign=br;
2028 res=(res&0x100)|sign;
2029 step=0; /* reset fetch */
2030 }
2031 }
2032
bita(void)2033 static void bita(void) { /* NxZxV0 */
2034 /* compute address */
2035 if (step<0x21) compute_address();
2036 /* [Data : EA] */
2037 if (step==0x21) {
2038 value=LoadByte(address);
2039 m1=ovfl;
2040 sign=ar&value;
2041 res=(res&0x100)|sign;
2042 step=0; /* reset fetch */
2043 }
2044 }
2045
bitb(void)2046 static void bitb(void) { /* NxZxV0 */
2047 /* compute address */
2048 if (step<0x21) compute_address();
2049 /* [Data : EA] */
2050 if (step==0x21) {
2051 value=LoadByte(address);
2052 m1=ovfl;
2053 sign=br&value;
2054 res=(res&0x100)|sign;
2055 step=0; /* reset fetch */
2056 }
2057 }
2058
cmpa(void)2059 static void cmpa(void) { /* H?NxZxVxCx */
2060 /* compute address */
2061 if (step<0x21) compute_address();
2062 /* [Data : EA] */
2063 if (step==0x21) {
2064 value=LoadByte(address);
2065 m1=ar; m2=-value;
2066 ovfl=res=sign=ar-value;
2067 step=0; /* reset fetch */
2068 }
2069 }
2070
cmpb(void)2071 static void cmpb(void) { /* H?NxZxVxCx */
2072 /* compute address */
2073 if (step<0x21) compute_address();
2074 /* [Data : EA] */
2075 if (step==0x21) {
2076 value=LoadByte(address);
2077 m1=br; m2=-value;
2078 ovfl=res=sign=br-value;
2079 step=0; /* reset fetch */
2080 }
2081 }
2082
eora(void)2083 static void eora(void) { /* NxZxV0 */
2084 /* compute address */
2085 if (step<0x21) compute_address();
2086 /* [Data : EA] */
2087 if (step==0x21) {
2088 value=LoadByte(address);
2089 m1=ovfl;
2090 ar^=value;
2091 sign=ar;
2092 res=(res&0x100)|sign;
2093 step=0; /* reset fetch */
2094 }
2095 }
2096
eorb(void)2097 static void eorb(void) { /* NxZxV0 */
2098 /* compute address */
2099 if (step<0x21) compute_address();
2100 /* [Data : EA] */
2101 if (step==0x21) {
2102 value=LoadByte(address);
2103 m1=ovfl;
2104 br^=value;
2105 sign=br;
2106 res=(res&0x100)|sign;
2107 step=0; /* reset fetch */
2108 }
2109 }
2110
ldam(void)2111 static void ldam(void) { /* NxZxV0 */
2112 /* compute address */
2113 if (step<0x21) compute_address();
2114 /* [Data : EA] */
2115 if (step==0x21) {
2116 sign=ar=LoadByte(address);
2117 m1=ovfl;
2118 res=(res&0x100)|sign;
2119 step=0; /* reset fetch */
2120 }
2121 }
2122
ldbm(void)2123 static void ldbm(void) { /* NxZxV0 */
2124 /* compute address */
2125 if (step<0x21) compute_address();
2126 /* [Data : EA] */
2127 if (step==0x21) {
2128 sign=br=LoadByte(address);
2129 m1=ovfl;
2130 res=(res&0x100)|sign;
2131 step=0; /* reset fetch */
2132 }
2133 }
2134
oram(void)2135 static void oram(void) { /* NxZxV0 */
2136 /* compute address */
2137 if (step<0x21) compute_address();
2138 /* [Data : EA] */
2139 if (step==0x21) {
2140 value=LoadByte(address);
2141 m1=ovfl;
2142 ar|=value;
2143 sign=ar;
2144 res=(res&0x100)|sign;
2145 step=0; /* reset fetch */
2146 }
2147 }
2148
orbm(void)2149 static void orbm(void) { /* NxZxV0 */
2150 /* compute address */
2151 if (step<0x21) compute_address();
2152 /* [Data : EA] */
2153 if (step==0x21) {
2154 value=LoadByte(address);
2155 m1=ovfl;
2156 br|=value;
2157 sign=br;
2158 res=(res&0x100)|sign;
2159 step=0; /* reset fetch */
2160 }
2161 }
2162
sbca(void)2163 static void sbca(void) { /* H?NxZxVxCx */
2164 /* compute address */
2165 if (step<0x21) compute_address();
2166 /* [Data : EA] */
2167 if (step==0x21) {
2168 value=LoadByte(address);
2169 m1=ar; m2=-value;
2170 ar-=value+((res&0x100)>>8);
2171 ovfl=res=sign=ar;
2172 ar&=0xff;
2173 step=0; /* reset fetch */
2174 }
2175 }
2176
sbcb(void)2177 static void sbcb(void) { /* H?NxZxVxCx */
2178 /* compute address */
2179 if (step<0x21) compute_address();
2180 /* [Data : EA] */
2181 if (step==0x21) {
2182 value=LoadByte(address);
2183 m1=br; m2=-value;
2184 br-=value+((res&0x100)>>8);
2185 ovfl=res=sign=br;
2186 br&=0xff;
2187 step=0; /* reset fetch */
2188 }
2189 }
2190
suba(void)2191 static void suba(void) { /* H?NxZxVxCx */
2192 /* compute address */
2193 if (step<0x21) compute_address();
2194 /* [Data : EA] */
2195 if (step==0x21) {
2196 value=LoadByte(address);
2197 m1=ar; m2=-value;
2198 ar-=value;
2199 ovfl=res=sign=ar;
2200 ar&=0xff;
2201 step=0; /* reset fetch */
2202 }
2203 }
2204
subb(void)2205 static void subb(void) { /* H?NxZxVxCx */
2206 /* compute address */
2207 if (step<0x21) compute_address();
2208 /* [Data : EA] */
2209 if (step==0x21) {
2210 value=LoadByte(address);
2211 m1=br; m2=-value;
2212 br-=value;
2213 ovfl=res=sign=br;
2214 br&=0xff;
2215 step=0; /* reset fetch */
2216 }
2217 }
2218
2219 /* ========================================================== */
2220 /* STA STB STD STX STY STU STS */
2221 /* ========================================================== */
2222
stam(void)2223 static void stam(void) { /* NxZxV0 */
2224 switch (step) {
2225 /* [Register (Write) : EA] */
2226 case 0x21 : StoreByte(address,ar);
2227 sign=ar;
2228 m1=ovfl;
2229 res=(res&0x100)|sign;
2230 step=0; /* reset fetch */
2231 break;
2232 /* compute address */
2233 default : compute_address();
2234 break;
2235 }
2236 }
2237
stbm(void)2238 static void stbm(void) { /* NxZxV0 */
2239 switch (step) {
2240 /* [Register (Write) : EA] */
2241 case 0x21 : StoreByte(address,br);
2242 sign=br;
2243 m1=ovfl;
2244 res=(res&0x100)|sign;
2245 step=0; /* reset fetch */
2246 break;
2247 /* compute address */
2248 default : compute_address();
2249 break;
2250 }
2251 }
2252
stdm(void)2253 static void stdm(void) { /* NxZxV0 */
2254 switch (step) {
2255 /* [Register High (Write) : EA] */
2256 case 0x21 : StoreByte(address,ar);
2257 break;
2258 /* [Register Low (Write) : EA] */
2259 case 0x22 : StoreByte(address+1,br);
2260 m1=ovfl;
2261 sign=ar;
2262 res=(res&0x100)|ar|br;
2263 step=0; /* reset fetch */
2264 break;
2265 /* compute address */
2266 default : compute_address();
2267 break;
2268 }
2269 }
2270
stxm(void)2271 static void stxm(void) { /* NxZxV0 */
2272 switch (step) {
2273 /* [Register High (Write) : EA] */
2274 case 0x21 : StoreByte(address,xr>>8);
2275 break;
2276 /* [Register Low (Write) : EA] */
2277 case 0x22 : StoreByte(address+1,xr);
2278 m1=0; m2=0x80;
2279 sign=xr>>8;
2280 res=(res&0x100)|((sign|xr)&0xff);
2281 step=0; /* reset fetch */
2282 break;
2283 /* compute address */
2284 default : compute_address();
2285 break;
2286 }
2287 }
2288
stum(void)2289 static void stum(void) { /* NxZxV0 */
2290 switch (step) {
2291 /* [Register High (Write) : EA] */
2292 case 0x21 : StoreByte(address,ur>>8);
2293 break;
2294 /* [Register Low (Write) : EA] */
2295 case 0x22 : StoreByte(address+1,ur);
2296 m1=ovfl;
2297 sign=ur>>8;
2298 res=(res&0x100)|((sign|ur)&0xff);
2299 step=0; /* reset fetch */
2300 break;
2301 /* compute address */
2302 default : compute_address();
2303 break;
2304 }
2305 }
2306
stym(void)2307 static void stym(void) { /* NxZxV0 */
2308 switch (step) {
2309 /* [Register High (Write) : EA] */
2310 case 0x21 : StoreByte(address,yr>>8);
2311 break;
2312 /* [Register Low (Write) : EA] */
2313 case 0x22 : StoreByte(address+1,yr);
2314 m1=ovfl;
2315 sign=yr>>8;
2316 res=(res&0x100)|((sign|yr)&0xff);
2317 step=0; /* reset fetch */
2318 break;
2319 /* compute address */
2320 default : compute_address();
2321 break;
2322 }
2323 }
2324
stsm(void)2325 static void stsm(void) { /* NxZxV0 */
2326 switch (step) {
2327 /* [Register High (Write) : EA] */
2328 case 0x21 : StoreByte(address,sr>>8);
2329 break;
2330 /* [Register Low (Write) : EA] */
2331 case 0x22 : StoreByte(address+1,sr);
2332 m1=ovfl;
2333 sign=sr>>8;
2334 res=(res&0x100)|((sign|sr)&0xff);
2335 step=0; /* reset fetch */
2336 break;
2337 /* compute address */
2338 default : compute_address();
2339 break;
2340 }
2341 }
2342
2343 /* ========================================================== */
2344 /* LDD/X/Y/U/S */
2345 /* ========================================================== */
2346
lddm(void)2347 static void lddm(void) { /* NxZxV0 */
2348 /* compute address */
2349 if (step<0x21) compute_address();
2350 switch (step) {
2351 /* [Register High : EA] */
2352 case 0x21 : ar=LoadByte(address);
2353 break;
2354 /* [Register Low : EA] */
2355 case 0x22 : br=LoadByte(address+1);
2356 m1=ovfl;
2357 sign=ar;
2358 res=(res&0x100)|br|ar;
2359 step=0; /* reset fetch */
2360 break;
2361 }
2362 }
2363
ldxm(void)2364 static void ldxm(void) { /* NxZxV0 */
2365 /* compute address */
2366 if (step<0x21) compute_address();
2367 switch (step) {
2368 /* [Register High : EA] */
2369 case 0x21 : xr=LoadByte(address)<<8;
2370 break;
2371 /* [Register Low : EA] */
2372 case 0x22 : xr|=LoadByte(address+1);
2373 m1=ovfl;
2374 sign=xr>>8;
2375 res=(res&0x100)|((sign|xr)&0xff);
2376 step=0; /* reset fetch */
2377 break;
2378 }
2379 }
2380
ldym(void)2381 static void ldym(void) { /* NxZxV0 */
2382 /* compute address */
2383 if (step<0x21) compute_address();
2384 switch (step) {
2385 /* [Register High : EA] */
2386 case 0x21 : yr=LoadByte(address)<<8;
2387 break;
2388 /* [Register Low : EA] */
2389 case 0x22 : yr|=LoadByte(address+1);
2390 m1=ovfl;
2391 sign=yr>>8;
2392 res=(res&0x100)|((sign|yr)&0xff);
2393 step=0; /* reset fetch */
2394 break;
2395 }
2396 }
2397
ldum(void)2398 static void ldum(void) { /* NxZxV0 */
2399 /* compute address */
2400 if (step<0x21) compute_address();
2401 switch (step) {
2402 /* [Register High : EA] */
2403 case 0x21 : ur=LoadByte(address)<<8;
2404 break;
2405 /* [Register Low : EA] */
2406 case 0x22 : ur|=LoadByte(address+1);
2407 m1=ovfl;
2408 sign=ur>>8;
2409 res=(res&0x100)|((sign|ur)&0xff);
2410 step=0; /* reset fetch */
2411 break;
2412 }
2413 }
2414
ldsm(void)2415 static void ldsm(void) { /* NxZxV0 */
2416 /* compute address */
2417 if (step<0x21) compute_address();
2418 switch (step) {
2419 /* [Register High : EA] */
2420 case 0x21 : sr=LoadByte(address)<<8;
2421 break;
2422 /* [Register Low : EA] */
2423 case 0x22 : sr|=LoadByte(address+1);
2424 m1=ovfl;
2425 sign=sr>>8;
2426 res=(res&0x100)|((sign|sr)&0xff);
2427 step=0; /* reset fetch */
2428 break;
2429 }
2430 }
2431
2432 /* ========================================================== */
2433 /* CMPD/X/Y/U/S */
2434 /* ========================================================== */
2435
cmpd(void)2436 static void cmpd(void) { /* NxZxVxCx */
2437 /* compute address */
2438 if (step<0x21) compute_address();
2439 switch (step) {
2440 /* [Data High : EA] */
2441 case 0x21 : value=LoadByte(address)<<8;
2442 break;
2443 /* [Register Low : EA] */
2444 case 0x22 : value|=LoadByte(address+1);
2445 break;
2446 /* [Don't Care] */
2447 case 0x23 : dr=(ar<<8)+br-value;
2448 m1=ar; m2=(-value)>>8;
2449 ovfl=res=sign=dr>>8;
2450 res|=(dr&0xff);
2451 step=0; /* reset fetch */
2452 break;
2453 }
2454 }
2455
cmpx(void)2456 static void cmpx(void) { /* NxZxVxCx */
2457 /* compute address */
2458 if (step<0x21) compute_address();
2459 switch (step) {
2460 /* [Data High : EA] */
2461 case 0x21 : value=LoadByte(address)<<8;
2462 break;
2463 /* [Register Low : EA] */
2464 case 0x22 : value|=LoadByte(address+1);
2465 break;
2466 /* [Don't Care] */
2467 case 0x23 : m1=xr>>8; m2=(-value)>>8;
2468 ovfl=res=sign=(xr-value)>>8;
2469 res|=(xr-value)&0xff;
2470 step=0; /* reset fetch */
2471 break;
2472 }
2473 }
2474
cmpy(void)2475 static void cmpy(void) { /* NxZxVxCx */
2476 /* compute address */
2477 if (step<0x21) compute_address();
2478 switch (step) {
2479 /* [Data High : EA] */
2480 case 0x21 : value=LoadByte(address)<<8;
2481 break;
2482 /* [Register Low : EA] */
2483 case 0x22 : value|=LoadByte(address+1);
2484 break;
2485 /* [Don't Care] */
2486 case 0x23 : m1=yr>>8; m2=(-value)>>8;
2487 ovfl=res=sign=(yr-value)>>8;
2488 res|=(yr-value)&0xff;
2489 step=0; /* reset fetch */
2490 break;
2491 }
2492 }
2493
cmpu(void)2494 static void cmpu(void) { /* NxZxVxCx */
2495 /* compute address */
2496 if (step<0x21) compute_address();
2497 switch (step) {
2498 /* [Data High : EA] */
2499 case 0x21 : value=LoadByte(address)<<8;
2500 break;
2501 /* [Register Low : EA] */
2502 case 0x22 : value|=LoadByte(address+1);
2503 break;
2504 /* [Don't Care] */
2505 case 0x23 : m1=ur>>8; m2=(-value)>>8;
2506 ovfl=res=sign=(ur-value)>>8;
2507 res|=(ur-value)&0xff;
2508 step=0; /* reset fetch */
2509 break;
2510 }
2511 }
2512
cmps(void)2513 static void cmps(void) { /* NxZxVxCx */
2514 /* compute address */
2515 if (step<0x21) compute_address();
2516 switch (step) {
2517 /* [Data High : EA] */
2518 case 0x21 : value=LoadByte(address)<<8;
2519 break;
2520 /* [Register Low : EA] */
2521 case 0x22 : value|=LoadByte(address+1);
2522 break;
2523 /* [Don't Care] */
2524 case 0x23 : m1=sr>>8; m2=(-value)>>8;
2525 ovfl=res=sign=(sr-value)>>8;
2526 res|=(sr-value)&0xff;
2527 step=0; /* reset fetch */
2528 break;
2529 }
2530 }
2531
addd(void)2532 static void addd(void) { /* NxZxVxCx */
2533 /* compute address */
2534 if (step<0x21) compute_address();
2535 switch (step) {
2536 /* [Data High : EA] */
2537 case 0x21 : value=LoadByte(address)<<8;
2538 break;
2539 /* [Register Low : EA] */
2540 case 0x22 : value|=LoadByte(address+1);
2541 break;
2542 /* [Don't Care] */
2543 case 0x23 : dr=(ar<<8)+br+value;
2544 m1=ar; m2=value>>8;
2545 ar=dr>>8;
2546 br=dr&0xff;
2547 ovfl=res=sign=ar;
2548 res|=br;
2549 ar&=0xff;
2550 step=0; /* reset fetch */
2551 break;
2552 }
2553 }
2554
subd(void)2555 static void subd(void) { /* NxZxVxCx */
2556 /* compute address */
2557 if (step<0x21) compute_address();
2558 switch (step) {
2559 /* [Data High : EA] */
2560 case 0x21 : value=LoadByte(address)<<8;
2561 break;
2562 /* [Register Low : EA] */
2563 case 0x22 : value|=LoadByte(address+1);
2564 break;
2565 /* [Don't Care] */
2566 case 0x23 : dr=(ar<<8)+br-value;
2567 m1=ar; m2=(-value)>>8;
2568 ar=dr>>8;
2569 br=dr&0xff;
2570 ovfl=res=sign=ar;
2571 res|=br;
2572 ar&=0xff;
2573 step=0; /* reset fetch */
2574 break;
2575 }
2576 }
2577
synm(void)2578 static void synm(void) {
2579 /* not supported */
2580 switch (step) {
2581 case 4 : step=0; /* reset fetch */
2582 break;
2583 /* Case 2->3 = [Don't Care] */
2584 default : break;
2585 }
2586 }
2587
cwai(void)2588 static void cwai(void) {
2589 /* not supported */
2590 switch (step) {
2591 case 2 : value=LoadByte(pc);
2592 pc=(pc+1)&0xffff;
2593 break;
2594 /* Case 20 = [Don't Care] */
2595 case 20 : step=0; /* reset fetch */
2596 break;
2597 /* Case 3->19 = [Don't Care] */
2598 default : break;
2599 }
2600 }
2601
2602 /**********************************************/
2603 /*** instructions non document�es du MC6809 ***/
2604 /**********************************************/
2605
cd02(void)2606 static void cd02(void) { /* NEG if Carry=0, COM otherwise */
2607 if (res&0x100)
2608 comm();
2609 else
2610 negm();
2611 }
2612
cd10(void)2613 static void cd10(void) {
2614 };
cd11(void)2615 static void cd11(void) { };
2616
hcfm(void)2617 static void hcfm(void) { /* Halt and Catch Fire */
2618 /* not supported */
2619 step=0; /* reset fetch */
2620 }
2621
rset(void)2622 static void rset(void) { /* Reset */
2623 irq_start = 0;
2624 irq_run = 0;
2625 cpu_clock = 0;
2626 cpu_limit = 0;
2627 mb.exact_clock = 0;
2628 cpu_timer = MC6809_TIMER_DISABLED;
2629
2630 dp=0;
2631 mc6809_irq=0;
2632 ccrest|=0x50;
2633 step=0; /* reset fetch */
2634 pc=LoadWord(0xFFFE);
2635 }
2636
cd18(void)2637 static void cd18(void) {
2638 switch (step) {
2639 /* [Don't Care] */
2640 case 3 : res=1-((((~(m1^m2))&(m1^ovfl))&0x80)>>7); /* V -> Z */
2641 h1=h2=((ccrest&0x10)>>4)*15; /* I -> H */
2642 ccrest=sign=m1=m2=ovfl=0; /* others bits of CC to 0 */
2643 step=0; /* reset fetch */
2644 break;
2645 /* Case 2 = [Don't Care] */
2646 default: break;
2647 }
2648 }
2649
cd38(void)2650 static void cd38(void) { /* ANDCC 4 cycles */
2651 switch (step) {
2652 /* [data : NNNN+1] */
2653 case 2 : value=LoadByte(pc);
2654 pc=(pc+1)&0xffff;
2655 break;
2656 /* [Don't Care] */
2657 case 4 : setcc(getcc()&value);
2658 step=0; /* reset fetch */
2659 break;
2660 /* Case 3 = [Don't Care] */
2661 default: break;
2662 }
2663 }
2664
cd42(void)2665 static void cd42(void) { /* NEGA if Carry=0, COMA otherwise */
2666 if (res&0x100)
2667 coma();
2668 else
2669 nega();
2670 }
2671
cd52(void)2672 static void cd52(void) { /* NEGB if Carry=0, COMB otherwise */
2673 if (res&0x100)
2674 comb();
2675 else
2676 negb();
2677 }
2678
cd87(void)2679 static void cd87(void) {
2680 /* [Don't Care] */
2681 m1=m2=ovfl=0; /* V=0 */
2682 res&=0xff00; /* Z=0 */
2683 sign|=0x80; /* N=1 */
2684 step=0; /* reset fetch */
2685 }
2686
cd8f(void)2687 static void cd8f(void) {
2688 switch (step) {
2689 /* [Don't Care : NNNN+1] */
2690 case 2 : pc=(pc+1)&0xffff;
2691 break;
2692 /* [Register Low (write) : NNNN+2] */
2693 case 3 : StoreByte(pc,xr);
2694 pc=(pc+1)&0xffff;
2695 m1=m2=ovfl=0; /* V=0 */
2696 res&=0xff00; /* Z=0 */
2697 sign|=0x80; /* N=1 */
2698 step=0; /* reset fetch */
2699 break;
2700 /* Case 1 = [Don't Care] */
2701 default: break;
2702 }
2703 }
2704
cdcf(void)2705 static void cdcf(void) {
2706 switch (step) {
2707 /* [Don't Care : NNNN+1] */
2708 case 2 : pc=(pc+1)&0xffff;
2709 break;
2710 /* [Register Low (write) : NNNN+2] */
2711 case 3 : StoreByte(pc,ur);
2712 pc=(pc+1)&0xffff;
2713 m1=m2=ovfl=0; /* V=0 */
2714 res&=0xff00; /* Z=0 */
2715 sign|=0x80; /* N=1 */
2716 step=0; /* reset fetch */
2717 break;
2718 /* Case 1 = [Don't Care] */
2719 default: break;
2720 }
2721 }
2722
2723 /*******************************/
2724 /*** syst�mes d'interruption ***/
2725 /*******************************/
2726
do_nmi(void)2727 static void do_nmi(void) {
2728 switch (step) {
2729 /* [Don't Care] */
2730 case 1 : ccrest|=0x80;
2731 value=0xff; /* push all registers */
2732 break;
2733 /* [Don't Care] */
2734 case 2 :
2735 case 3 : break;
2736 /* [Don't Care] */
2737 case 0x21 : ccrest|=0x50;
2738 break;
2739 /* [PC High : FFFX] */
2740 case 0x22 : pc=LoadByte(0xFFFC)<<8;
2741 break;
2742 /* [PC Low : FFFX+1] */
2743 case 0x23 : pc|=LoadByte(0xFFFD);
2744 break;
2745 /* [Don't Care] */
2746 case 0x24 : step=0; /* reset fetch */
2747 break;
2748 /* push all registers */
2749 default : pshsr();
2750 if (value==0) step=0x20;
2751 break;
2752 }
2753 }
2754
do_irq(void)2755 static void do_irq(void) {
2756 switch (step) {
2757 /* [Don't Care] */
2758 case 1 : ccrest|=0x80;
2759 value=0xff; /* push all registers */
2760 break;
2761 /* [Don't Care] */
2762 case 2 :
2763 case 3 : break;
2764 /* [Don't Care] */
2765 case 0x21 : ccrest|=0x10;
2766 break;
2767 /* [PC High : FFFX] */
2768 case 0x22 : pc=LoadByte(0xFFF8)<<8;
2769 break;
2770 /* [PC Low : FFFX+1] */
2771 case 0x23 : pc|=LoadByte(0xFFF9);
2772 break;
2773 /* [Don't Care] */
2774 case 0x24 : irq_start=0;
2775 step=0; /* reset fetch */
2776 break;
2777 /* push all registers */
2778 default : pshsr();
2779 if (value==0) step=0x20;
2780 break;
2781 }
2782 }
2783
do_firq(void)2784 static void do_firq(void) {
2785 switch (step) {
2786 /* [Don't Care] */
2787 case 1 : ccrest&=0x7f;
2788 value=0x81;
2789 break;
2790 /* push PC,CC */
2791 case 4 :
2792 case 5 :
2793 case 6 : pshsr();
2794 break;
2795 /* [Don't Care] */
2796 case 7 : ccrest|=0x50;
2797 break;
2798 /* [PC High : FFFX] */
2799 case 8 : pc=LoadByte(0xFFF6)<<8;
2800 break;
2801 /* [PC Low : FFFX+1] */
2802 case 9 : pc|=LoadByte(0xFFF7);
2803 break;
2804 /* [Don't Care] */
2805 case 10: step=0; /* reset fetch */
2806 break;
2807 /* Cases 2,3 = [Don't Care] */
2808 default: break;
2809 }
2810 }
2811
2812
2813 static void (*code[])(void)=
2814 {negm,negm,cd02,comm,lsrm,lsrm,rorm,asrm,aslm,rolm,decm,decm,incm,tstm,jmpm,clrm
2815 ,cd10,cd11,nopm,synm,hcfm,hcfm,lbra,lbsr,cd18,daam,orcc,nopm,andc,sexm,exgm,tfrm
2816 ,bras,brns,bhis,blss,bccs,blos,bnes,beqs,bvcs,bvss,bpls,bmis,bges,blts,bgts,bles
2817 ,leax,leay,leas,leau,pshs,puls,pshu,pulu,cd38,rtsm,abxm,rtim,cwai,mulm,rset,swim
2818 ,nega,nega,cd42,coma,lsra,lsra,rora,asra,asla,rola,deca,deca,inca,tsta,clra,clra
2819 ,negb,negb,cd52,comb,lsrb,lsrb,rorb,asrb,aslb,rolb,decb,decb,incb,tstb,clrb,clrb
2820 ,negm,negm,cd02,comm,lsrm,lsrm,rorm,asrm,aslm,rolm,decm,decm,incm,tstm,jmpm,clrm
2821 ,negm,negm,cd02,comm,lsrm,lsrm,rorm,asrm,aslm,rolm,decm,decm,incm,tstm,jmpm,clrm
2822 ,suba,cmpa,sbca,subd,anda,bita,ldam,cd87,eora,adca,oram,adda,cmpx,bsrm,ldxm,cd8f
2823 ,suba,cmpa,sbca,subd,anda,bita,ldam,stam,eora,adca,oram,adda,cmpx,jsrm,ldxm,stxm
2824 ,suba,cmpa,sbca,subd,anda,bita,ldam,stam,eora,adca,oram,adda,cmpx,jsrm,ldxm,stxm
2825 ,suba,cmpa,sbca,subd,anda,bita,ldam,stam,eora,adca,oram,adda,cmpx,jsrm,ldxm,stxm
2826 ,subb,cmpb,sbcb,addd,andb,bitb,ldbm,cd87,eorb,adcb,orbm,addb,lddm,hcfm,ldum,cdcf
2827 ,subb,cmpb,sbcb,addd,andb,bitb,ldbm,stbm,eorb,adcb,orbm,addb,lddm,stdm,ldum,stum
2828 ,subb,cmpb,sbcb,addd,andb,bitb,ldbm,stbm,eorb,adcb,orbm,addb,lddm,stdm,ldum,stum
2829 ,subb,cmpb,sbcb,addd,andb,bitb,ldbm,stbm,eorb,adcb,orbm,addb,lddm,stdm,ldum,stum
2830 /* page 2 */
2831 ,negm,negm,cd02,comm,lsrm,lsrm,rorm,asrm,aslm,rolm,decm,decm,incm,tstm,jmpm,clrm
2832 ,cd10,cd11,nopm,synm,hcfm,hcfm,lbra,lbsr,cd18,daam,orcc,nopm,andc,sexm,exgm,tfrm
2833 ,lbra,lbrn,lbhi,lbls,lbcc,lblo,lbne,lbeq,lbvc,lbvs,lbpl,lbmi,lbge,lblt,lbgt,lble
2834 ,leax,leay,leas,leau,pshs,puls,pshu,pulu,cd38,rtsm,abxm,rtim,cwai,mulm,rset,swim
2835 ,nega,nega,cd42,coma,lsra,lsra,rora,asra,asla,rola,deca,deca,inca,tsta,clra,clra
2836 ,negb,negb,cd52,comb,lsrb,lsrb,rorb,asrb,aslb,rolb,decb,decb,incb,tstb,clrb,clrb
2837 ,negm,negm,cd02,comm,lsrm,lsrm,rorm,asrm,aslm,rolm,decm,decm,incm,tstm,jmpm,clrm
2838 ,negm,negm,cd02,comm,lsrm,lsrm,rorm,asrm,aslm,rolm,decm,decm,incm,tstm,jmpm,clrm
2839 ,suba,cmpa,sbca,cmpd,anda,bita,ldam,cd87,eora,adca,oram,adda,cmpy,bsrm,ldym,cd8f
2840 ,suba,cmpa,sbca,cmpd,anda,bita,ldam,stam,eora,adca,oram,adda,cmpy,jsrm,ldym,stym
2841 ,suba,cmpa,sbca,cmpd,anda,bita,ldam,stam,eora,adca,oram,adda,cmpy,jsrm,ldym,stym
2842 ,suba,cmpa,sbca,cmpd,anda,bita,ldam,stam,eora,adca,oram,adda,cmpy,jsrm,ldym,stym
2843 ,subb,cmpb,sbcb,addd,andb,bitb,ldbm,cd87,eorb,adcb,orbm,addb,lddm,hcfm,ldsm,cdcf
2844 ,subb,cmpb,sbcb,addd,andb,bitb,ldbm,stbm,eorb,adcb,orbm,addb,lddm,stdm,ldsm,stsm
2845 ,subb,cmpb,sbcb,addd,andb,bitb,ldbm,stbm,eorb,adcb,orbm,addb,lddm,stdm,ldsm,stsm
2846 ,subb,cmpb,sbcb,addd,andb,bitb,ldbm,stbm,eorb,adcb,orbm,addb,lddm,stdm,ldsm,stsm
2847 /* page 3 */
2848 ,negm,negm,cd02,comm,lsrm,lsrm,rorm,asrm,aslm,rolm,decm,decm,incm,tstm,jmpm,clrm
2849 ,cd10,cd11,nopm,synm,hcfm,hcfm,lbra,lbsr,cd18,daam,orcc,nopm,andc,sexm,exgm,tfrm
2850 ,bras,brns,bhis,blss,bccs,blos,bnes,beqs,bvcs,bvss,bpls,bmis,bges,blts,bgts,bles
2851 ,leax,leay,leas,leau,pshs,puls,pshu,pulu,cd38,rtsm,abxm,rtim,cwai,mulm,rset,swim
2852 ,nega,nega,cd42,coma,lsra,lsra,rora,asra,asla,rola,deca,deca,inca,tsta,clra,clra
2853 ,negb,negb,cd52,comb,lsrb,lsrb,rorb,asrb,aslb,rolb,decb,decb,incb,tstb,clrb,clrb
2854 ,negm,negm,cd02,comm,lsrm,lsrm,rorm,asrm,aslm,rolm,decm,decm,incm,tstm,jmpm,clrm
2855 ,negm,negm,cd02,comm,lsrm,lsrm,rorm,asrm,aslm,rolm,decm,decm,incm,tstm,jmpm,clrm
2856 ,suba,cmpa,sbca,cmpu,anda,bita,ldam,cd87,eora,adca,oram,adda,cmps,bsrm,ldxm,cd8f
2857 ,suba,cmpa,sbca,cmpu,anda,bita,ldam,stam,eora,adca,oram,adda,cmps,jsrm,ldxm,stxm
2858 ,suba,cmpa,sbca,cmpu,anda,bita,ldam,stam,eora,adca,oram,adda,cmps,jsrm,ldxm,stxm
2859 ,suba,cmpa,sbca,cmpu,anda,bita,ldam,stam,eora,adca,oram,adda,cmps,jsrm,ldxm,stxm
2860 ,subb,cmpb,sbcb,addd,andb,bitb,ldbm,cd87,eorb,adcb,orbm,addb,lddm,hcfm,ldum,cdcf
2861 ,subb,cmpb,sbcb,addd,andb,bitb,ldbm,stbm,eorb,adcb,orbm,addb,lddm,stdm,ldum,stum
2862 ,subb,cmpb,sbcb,addd,andb,bitb,ldbm,stbm,eorb,adcb,orbm,addb,lddm,stdm,ldum,stum
2863 ,subb,cmpb,sbcb,addd,andb,bitb,ldbm,stbm,eorb,adcb,orbm,addb,lddm,stdm,ldum,stum
2864 /* interrupts */
2865 ,do_irq,do_firq,do_nmi
2866 };
2867
2868 static void (*addr[])(void)=
2869 {drct,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct
2870 ,impl,impl,impl,impl,impl,impl,rela,rela,impl,impl,imm1,imm1,imm1,impl,impl,impl
2871 ,rela,rela,rela,rela,rela,rela,rela,rela,rela,rela,rela,rela,rela,rela,rela,rela
2872 ,indx,indx,indx,indx,impl,impl,impl,impl,impl,impl,impl,impl,impl,impl,impl,impl
2873 ,impl,impl,impl,impl,impl,impl,impl,impl,impl,impl,impl,impl,impl,impl,impl,impl
2874 ,impl,impl,impl,impl,impl,impl,impl,impl,impl,impl,impl,impl,impl,impl,impl,impl
2875 ,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx
2876 ,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn
2877 ,imm1,imm1,imm1,imm2,imm1,imm1,imm1,imm1,imm1,imm1,imm1,imm1,imm2,rela,imm2,imm2
2878 ,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct
2879 ,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx
2880 ,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn
2881 ,imm1,imm1,imm1,imm2,imm1,imm1,imm1,imm1,imm1,imm1,imm1,imm1,imm2,rela,imm2,imm2
2882 ,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct,drct
2883 ,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx,indx
2884 ,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn,extn
2885 };
2886
2887
mc6809_Step(void)2888 static void mc6809_Step(void) {
2889 if (step == 1) /* [Fetch OpCode] */
2890 {
2891 if (page == 0)
2892 {
2893 #ifdef DEBUG
2894 if (mc6809_ftrace)
2895 fprintf(mc6809_ftrace, "pc: %04X\n", pc);
2896 #endif
2897 if (cpu_clock>=cpu_timer)
2898 TimerCallback(timer_data);
2899
2900 if ((mc6809_irq!=0)&&((ccrest&0x10)==0))
2901 {
2902 irq_start=irq_run=1;
2903 opcode=0x300;
2904 do_irq();
2905 }
2906 }
2907 if (irq_start == 0)
2908 {
2909 opcode=LoadByte(pc);
2910 pc=(pc+1)&0xffff;
2911 if(opcode==TEO_TRAP_CODE)
2912 {
2913 mc6809_GetRegs(®_list);
2914 opcode=TrapCallback(®_list);
2915 mc6809_SetRegs(®_list, MC6809_REGS_ALL_FLAG);
2916 }
2917 }
2918 switch(opcode)
2919 {
2920 case 0x10 : page=0x100; step=0; break;
2921 case 0x11 : page=0x200; step=0; break;
2922 default : compute_address=addr[opcode&0xff]; break;
2923 }
2924 }
2925 else
2926 {
2927 (*(code[opcode+page]))();
2928 if (step==0) /* fetch reset */
2929 page=0;
2930 }
2931 }
2932
2933
2934 /************************************************/
2935 /*** Interface publique de l'�mulateur MC6809 ***/
2936 /************************************************/
2937
2938 /* clock:
2939 * Retourne la valeur de l'horloge du CPU.
2940 */
mc6809_clock(void)2941 mc6809_clock_t mc6809_clock(void)
2942 {
2943 return cpu_clock;
2944 }
2945
2946
2947
2948 /* GetRegs:
2949 * Retourne le contenu des registres du CPU.
2950 */
mc6809_GetRegs(struct MC6809_REGS * regs)2951 void mc6809_GetRegs(struct MC6809_REGS *regs)
2952 {
2953 regs->cc = getcc();
2954 regs->dp = dp;
2955 regs->ar = ar;
2956 regs->br = br;
2957 regs->xr = xr;
2958 regs->yr = yr;
2959 regs->ur = ur;
2960 regs->sr = sr;
2961 regs->pc = pc;
2962 regs->cpu_clock = cpu_clock;
2963 regs->cpu_timer = cpu_timer;
2964 }
2965
2966
2967 /* SetRegs:
2968 * Modifie le contenu des registres du CPU.
2969 */
mc6809_SetRegs(const struct MC6809_REGS * regs,int flags)2970 void mc6809_SetRegs(const struct MC6809_REGS *regs, int flags)
2971 {
2972 if (flags&MC6809_REGS_CC_FLAG)
2973 setcc(regs->cc);
2974
2975 if (flags&MC6809_REGS_DP_FLAG)
2976 dp=regs->dp;
2977
2978 if (flags&MC6809_REGS_AR_FLAG)
2979 ar=regs->ar;
2980
2981 if (flags&MC6809_REGS_BR_FLAG)
2982 br=regs->br;
2983
2984 if (flags&MC6809_REGS_XR_FLAG)
2985 xr=regs->xr;
2986
2987 if (flags&MC6809_REGS_YR_FLAG)
2988 yr=regs->yr;
2989
2990 if (flags&MC6809_REGS_UR_FLAG)
2991 ur=regs->ur;
2992
2993 if (flags&MC6809_REGS_SR_FLAG)
2994 sr=regs->sr;
2995
2996 if (flags&MC6809_REGS_PC_FLAG)
2997 pc=regs->pc;
2998
2999 if (flags&MC6809_REGS_CPUCLOCK_FLAG)
3000 cpu_clock=regs->cpu_clock;
3001
3002 if (flags&MC6809_REGS_CPUTIMER_FLAG)
3003 cpu_timer=regs->cpu_timer;
3004 }
3005
3006
3007 /* SetTimer:
3008 * Installe un callback appel� par le CPU � expiration de la p�riode sp�cifi�e.
3009 */
mc6809_SetTimer(mc6809_clock_t time,void (* func)(void *),void * data)3010 void mc6809_SetTimer(mc6809_clock_t time, void (*func)(void *), void *data)
3011 {
3012 cpu_timer = time;
3013 TimerCallback = func;
3014 timer_data = data;
3015 }
3016
3017
3018 /* Init:
3019 * Initialise l'�mulation du MC6809.
3020 */
mc6809_Init(void)3021 void mc6809_Init(void)
3022 {
3023 int i;
3024
3025 regist[0] = &xr;
3026 regist[1] = &yr;
3027 regist[2] = &ur;
3028 regist[3] = &sr;
3029
3030 for(i=0; i<16; i++)
3031 exreg[i] = &bus;
3032
3033 exreg[1] = &xr;
3034 exreg[2] = &yr;
3035 exreg[3] = &ur;
3036 exreg[4] = &sr;
3037 exreg[5] = &pc;
3038 exreg[8] = &ar;
3039 exreg[9] = &br;
3040 exreg[11] = &dp;
3041
3042 page = 0;
3043 step = 1;
3044 irq_start = 0;
3045 irq_run = 0;
3046 cpu_clock = 0;
3047 cpu_limit = 0;
3048 cpu_timer = MC6809_TIMER_DISABLED;
3049
3050 FetchInstr = mc6809_interface.FetchInstr;
3051 LoadByte = mc6809_interface.LoadByte;
3052 LoadWord = mc6809_interface.LoadWord;
3053 StoreByte = mc6809_interface.StoreByte;
3054 StoreWord = mc6809_interface.StoreWord;
3055 TrapCallback = mc6809_interface.TrapCallback;
3056 }
3057
3058
3059 /* mc6809_Reset:
3060 * Remet � z�ro le CPU (envoie un signal sur la broche RESET du MC6809).
3061 */
mc6809_Reset(void)3062 void mc6809_Reset(void)
3063 {
3064 rset();
3065 step=1;
3066 }
3067
3068
3069 /* FlushExec:
3070 * Ach�ve l'ex�cution d'une instruction et/ou
3071 * d'une interruption
3072 */
mc6809_FlushExec(void)3073 void mc6809_FlushExec(void)
3074 {
3075 while ((step!=1) || (irq_start!=0) || (page!=0))
3076 {
3077 mc6809_Step();
3078 step++;
3079 cpu_clock++;
3080 }
3081 }
3082
3083
3084 /* mc6809_StepExec:
3085 * Ex�cute une instruction et retourne le
3086 * nombre de cycles n�cessaires � son �x�cution.
3087 */
mc6809_StepExec(void)3088 int mc6809_StepExec(void)
3089 {
3090 mc6809_clock_t start_clock=cpu_clock;
3091
3092 do
3093 {
3094 mc6809_Step();
3095 step++;
3096 cpu_clock++;
3097 }
3098 while ((step!=1) || (irq_start!=0) || (page!=0));
3099
3100 return (int)(cpu_clock-start_clock);
3101 }
3102
3103
3104 /* mc6809_TimeExec:
3105 * Fait tourner le MC6809 jusqu'� un instant donn�
3106 */
mc6809_TimeExec(mc6809_clock_t time_limit)3107 int mc6809_TimeExec(mc6809_clock_t time_limit)
3108 {
3109 cpu_limit = time_limit;
3110 while (cpu_clock<cpu_limit)
3111 {
3112 mc6809_Step();
3113 step++;
3114 cpu_clock++;
3115 if ((teo_DebugBreakPoint) && (step == 1) && (page == 0))
3116 if (teo_DebugBreakPoint(pc&0xFFFF))
3117 return -1;
3118 }
3119 return 0;
3120 }
3121
3122