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(&reg_list);
2914                 opcode=TrapCallback(&reg_list);
2915                 mc6809_SetRegs(&reg_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