1 //////////////////////////////////////////////////
2 //                                              //
3 // Emu64                                        //
4 // von Thorsten Kattanek                        //
5 //                                              //
6 // #file: mos6510_class.cpp                     //
7 //                                              //
8 // Dieser Sourcecode ist Copyright geschützt!   //
9 // Geistiges Eigentum von Th.Kattanek           //
10 //                                              //
11 // Letzte Änderung am 18.09.2019                //
12 // www.emu64.de                                 //
13 //                                              //
14 //////////////////////////////////////////////////
15 
16 #include "mos6510_class.h"
17 #include "micro_code_tbl_6510.h"
18 
19 #define CHK_RDY	if(!*RDY && !CpuWait){CpuWait=true;MCT--;break;}
20 #define OLD_IRQHandling
21 
MOS6510(void)22 MOS6510::MOS6510(void)
23 {
24     ReadProcTbl = 0;
25     WriteProcTbl = 0;
26 
27     MCT = ((unsigned char*)MicroCodeTable6510 + (0x100*MCTItemSize));
28     Pointer = 0;
29     Adresse = 0x0000;
30     BranchAdresse = 0x0000;
31     AktOpcodePC = 0x0100;
32     JAMFlag = false;
33     TMPByte = 0;
34     CpuWait = false;
35 
36     PC = 0;
37     AC = 0;
38     XR = 0;
39     YR = 0;
40     SP = 0;
41     SR = 32;
42 
43     EnableExtInterrupts = false;
44 
45     irq_state = 0;
46     irq_is_low_pegel = false;
47     irq_is_active = false;
48 
49     irq_delay = false;
50     irq_delay_sr_value = 0;
51 
52     nmi_state = false;
53     nmi_state_old = false;
54     nmi_fall_edge = false;
55     nmi_is_active = false;
56 
57     EnableDebugCart = false;
58     WRITE_DEBUG_CART = false;
59 }
60 
~MOS6510(void)61 MOS6510::~MOS6510(void)
62 {
63 }
64 
TriggerInterrupt(int typ)65 void MOS6510::TriggerInterrupt(int typ)
66 {
67     if(EnableExtInterrupts)
68     {
69         switch(typ)
70         {
71         case EXT_IRQ:
72             typ = CIA_IRQ;
73             break;
74         case EXT_NMI:
75             typ = CIA_NMI;
76             break;
77         default:
78             typ = NOP_INT;
79             break;
80         }
81     }
82 
83     switch (typ)
84     {
85     case CIA_IRQ:
86             //Interrupts[CIA_IRQ] = true;
87             irq_state |= 0x01;
88             break;
89     case CIA_NMI:
90             if(Interrupts[CIA_NMI] == true) return;
91             Interrupts[CIA_NMI] = true;
92             if((Interrupts[CRT_NMI] == false) && (Interrupts[RESTORE_NMI] == false)) nmi_state = true;
93             break;
94     case VIC_IRQ:
95             //Interrupts[VIC_IRQ] = true;
96             irq_state |= 0x02;
97             break;
98     case REU_IRQ:
99             //Interrupts[REU_IRQ] = true;
100             irq_state |= 0x04;
101             break;
102     case CRT_NMI:
103             if(Interrupts[CRT_NMI] == true) return;
104             Interrupts[CRT_NMI] = true;
105             if((Interrupts[CIA_NMI] == false) && (Interrupts[RESTORE_NMI] == false)) nmi_state = true;
106             break;
107     case RESTORE_NMI:
108             if(Interrupts[RESTORE_NMI] == true) return;
109             Interrupts[RESTORE_NMI] = true;
110             if((Interrupts[CIA_NMI] == false) && (Interrupts[CRT_NMI] == false)) nmi_state = true;
111             break;
112     default:
113             break;
114     }
115 }
116 
ClearInterrupt(int typ)117 void MOS6510::ClearInterrupt(int typ)
118 {
119     if(EnableExtInterrupts)
120     {
121         switch(typ)
122         {
123         case EXT_IRQ:
124             typ = CIA_IRQ;
125             break;
126         case EXT_NMI:
127             typ = CIA_NMI;
128             break;
129         default:
130             typ = NOP_INT;
131             break;
132         }
133     }
134 
135     switch (typ)
136     {
137     case CIA_IRQ:
138             //Interrupts[CIA_IRQ] = false;
139             irq_state &= 0xFE;
140             break;
141     case CIA_NMI:
142             Interrupts[CIA_NMI] = false;
143             if(Interrupts[CRT_NMI] == false) nmi_state = false;
144             break;
145     case VIC_IRQ:
146             //Interrupts[VIC_IRQ] = false;
147             irq_state &= 0xFD;
148             break;
149     case REU_IRQ:
150             //Interrupts[REU_IRQ] = false;
151             irq_state &= 0xFB;
152             break;
153     case CRT_NMI:
154             Interrupts[CRT_NMI] = false;
155             if(Interrupts[CIA_NMI] == false) nmi_state = false;
156             break;
157     case RESTORE_NMI:
158             Interrupts[RESTORE_NMI] = false;
159             if((Interrupts[CIA_NMI] == false) && (Interrupts[CRT_NMI] == false)) nmi_state = false;
160             break;
161     default:
162             break;
163     }
164 }
165 
ClearJAMFlag(void)166 void MOS6510::ClearJAMFlag(void)
167 {
168     JAMFlag = false;
169 }
170 
SetRegister(REG_STRUCT * reg)171 void MOS6510::SetRegister(REG_STRUCT *reg)
172 {
173     if(reg == 0) return;
174 
175     unsigned char mask = reg->reg_mask;
176     if((mask&1) == 1)
177     {
178         PC = reg->pc;
179         MCT = ((unsigned char*)MicroCodeTable6510 + 6);
180     }
181     mask>>=1;
182     if((mask&1) == 1) AC = (unsigned char)reg->ac;
183     mask>>=1;
184     if((mask&1) == 1) XR = (unsigned char)reg->xr;
185     mask>>=1;
186     if((mask&1) == 1) YR = (unsigned char)reg->yr;
187     mask>>=1;
188     if((mask&1) == 1) SP = (unsigned char)reg->sp;
189     mask>>=1;
190     if((mask&1) == 1) SR = (unsigned char)reg->sr | 32;
191 }
192 
GetInterrupts(int typ)193 bool MOS6510::GetInterrupts(int typ)
194 {
195     return Interrupts[typ];
196 }
197 
GetRegister(REG_STRUCT * reg)198 void MOS6510::GetRegister(REG_STRUCT *reg)
199 {
200     if(reg == 0) return;
201 
202     unsigned char mask = reg->reg_mask;
203     if((mask&1) == 1) reg->pc = PC;
204     mask>>=1;
205     if((mask&1) == 1) reg->ac = AC;
206     mask>>=1;
207     if((mask&1) == 1) reg->xr = XR;
208     mask>>=1;
209     if((mask&1) == 1) reg->yr = YR;
210     mask>>=1;
211     if((mask&1) == 1) reg->sp = SP;
212     mask>>=1;
213     if((mask&1) == 1) reg->sr = SR;
214     mask>>=1;
215     if((mask&1) == 1)
216     {
217         reg->irq = Read(0xFFFE);
218         reg->irq |= Read(0xFFFF)<<8;
219     }
220     mask>>=1;
221     if((mask&1) == 1)
222     {
223         reg->nmi = Read(0xFFFA);
224         reg->nmi |= Read(0xFFFB)<<8;
225     }
226     reg->_0314 = Read(0x314);
227     reg->_0314 |= Read(0x315)<<8;
228     reg->_0318 = Read(0x318);
229     reg->_0318 |= Read(0x319)<<8;
230 }
231 
GetInterneRegister(IREG_STRUCT * ireg)232 void MOS6510::GetInterneRegister(IREG_STRUCT* ireg)
233 {
234     if(ireg == 0) return;
235     ireg->current_opcode_pc = AktOpcodePC;
236     ireg->current_opcode = AktOpcode;
237     ireg->current_micro_code = *MCT;
238     ireg->cpu_wait = CpuWait;
239     ireg->jam_flag = JAMFlag;
240     ireg->pointer = Pointer;
241     ireg->address = Adresse;
242     ireg->branch_address = BranchAdresse;
243     ireg->tmp_byte = TMPByte;
244     ireg->irq = irq_state;
245     ireg->nmi = Interrupts[CIA_NMI] | Interrupts[CRT_NMI] | Interrupts[RESTORE_NMI];
246     ireg->rdy = *RDY;
247     ireg->reset = *RESET;
248 }
249 
SetEnableDebugCart(bool enabled)250 void MOS6510::SetEnableDebugCart(bool enabled)
251 {
252     EnableDebugCart = enabled;
253     WRITE_DEBUG_CART = false;
254 }
255 
GetDebugCartValue()256 unsigned char MOS6510::GetDebugCartValue()
257 {
258     return DebugCartValue;
259 }
260 
261 /*
262 bool MOS6510::SaveFreez(FILE *File)
263 {
264     unsigned short MCTOffset = MCT-(unsigned char*)MicroCodeTable6510;
265     fwrite(&MCTOffset,1,sizeof(MCTOffset),File);
266     fwrite(&Pointer,1,sizeof(Pointer),File);
267     fwrite(&Adresse,1,sizeof(Adresse),File);
268     fwrite(&BranchAdresse,1,sizeof(BranchAdresse),File);
269     fwrite(&AktOpcodePC,1,sizeof(AktOpcodePC),File);
270     fwrite(&CpuWait,1,sizeof(CpuWait),File);
271     fwrite(&JAMFlag,1,sizeof(JAMFlag),File);
272     fwrite(&TMPByte,1,sizeof(TMPByte),File);
273     fwrite(Interrupts,1,sizeof(Interrupts),File);
274     fwrite(&NMIState,1,sizeof(NMIState),File);
275     fwrite(&PC,1,sizeof(PC),File);
276     fwrite(&AC,1,sizeof(AC),File);
277     fwrite(&XR,1,sizeof(XR),File);
278     fwrite(&YR,1,sizeof(YR),File);
279     fwrite(&SP,1,sizeof(SP),File);
280     fwrite(&SR,1,sizeof(SR),File);
281     return true;
282 }
283 
284 bool MOS6510::LoadFreez(FILE *File,unsigned short Version)
285 {
286     unsigned short MCTOffset;
287 
288     switch(Version)
289     {
290     case 0x0100:
291     case 0x0101:
292         fread(&MCTOffset,1,sizeof(MCTOffset),File);
293         MCT = MCTOffset + (unsigned char*)MicroCodeTable6510;
294         fread(&Pointer,1,sizeof(Pointer),File);
295         fread(&Adresse,1,sizeof(Adresse),File);
296         fread(&BranchAdresse,1,sizeof(BranchAdresse),File);
297         fread(&AktOpcodePC,1,sizeof(AktOpcodePC),File);
298         fread(&CpuWait,1,sizeof(CpuWait),File);
299         fread(&JAMFlag,1,sizeof(JAMFlag),File);
300         fread(&TMPByte,1,sizeof(TMPByte),File);
301         fread(Interrupts,1,sizeof(Interrupts),File);
302         fread(&NMIState,1,sizeof(NMIState),File);
303         fread(&PC,1,sizeof(PC),File);
304         fread(&AC,1,sizeof(AC),File);
305         fread(&XR,1,sizeof(XR),File);
306         fread(&YR,1,sizeof(YR),File);
307         fread(&SP,1,sizeof(SP),File);
308         fread(&SR,1,sizeof(SR),File);
309         break;
310     }
311     return true;
312 }
313 */
314 
SET_SR_NZ(unsigned char wert)315 inline void MOS6510::SET_SR_NZ(unsigned char wert)
316 {
317     SR = (SR&0x7D)|(wert&0x80);
318     if (wert==0) SR|=2;
319 }
320 
SET_SIGN(unsigned char wert)321 inline void MOS6510::SET_SIGN(unsigned char wert)
322 {
323     SR = (SR&127)|(wert&0x80);
324 }
325 
SET_ZERO(unsigned char wert)326 inline void MOS6510::SET_ZERO(unsigned char wert)
327 {
328     if(wert==0) SR|=2;
329     else SR&=0xFD;
330 }
331 
SET_CARRY(unsigned char status)332 inline void MOS6510::SET_CARRY(unsigned char status)
333 {
334     if (status!=0) SR|=1;
335     else SR&=0xFE;
336 }
337 
IF_CARRY(void)338 inline bool MOS6510::IF_CARRY(void)
339 {
340     if(SR&1) return true;
341     return false;
342 }
343 
IF_DECIMAL(void)344 inline bool MOS6510::IF_DECIMAL(void)
345 {
346     if(SR&8) return true;
347     return false;
348 }
349 
SET_OVERFLOW(bool status)350 inline void MOS6510::SET_OVERFLOW(bool status)
351 {
352     if (status!=0) SR|=64;
353     else SR&=0xBF;
354 }
355 
Read(unsigned short adresse)356 inline unsigned char MOS6510::Read(unsigned short adresse)
357 {
358     unsigned char wert = ReadProcTbl[(adresse)>>8](adresse);
359 
360     if(Breakpoints[adresse] & 16)
361     {
362         *BreakStatus |=16;
363         BreakWerte[4] = adresse;
364     }
365 
366     if(Breakpoints[wert] & 64)
367     {
368         *BreakStatus |=64;
369         BreakWerte[6] = wert;
370     }
371     return wert;
372 }
373 
Write(unsigned short adresse,unsigned char wert)374 inline void MOS6510::Write(unsigned short adresse, unsigned char wert)
375 {
376     if((EnableDebugCart == true) && (adresse == DEBUG_CART_ADRESS))
377     {
378         DebugCartValue = wert;
379         WRITE_DEBUG_CART = true;
380     }
381 
382     if(adresse == 0xFF00) WRITE_FF00 = true;
383     if(Breakpoints[adresse] & 32)
384     {
385         *BreakStatus |=32;
386         BreakWerte[5] = adresse;
387     }
388 
389     if(Breakpoints[wert] & 128)
390     {
391         *BreakStatus |=128;
392         BreakWerte[7] = wert;
393     }
394     WriteProcTbl[(adresse)>>8](adresse,wert);
395 }
396 
397 // Phi2
OneZyklus(void)398 bool MOS6510::OneZyklus(void)
399 {
400     static bool RESET_OLD = false;
401     static unsigned char   idxReg = 0;
402 
403     unsigned int    tmp;
404     unsigned int    tmp1;
405     unsigned short  tmp2;
406     unsigned short  src;
407     bool            carry_tmp;
408 
409     if(*RDY) CpuWait = false;
410 
411     if(!*RESET)
412     {
413         CpuWait=true;
414     }
415 
416     if((*RESET == true) && (RESET_OLD == false))
417     {
418         CpuWait=false;
419         Interrupts[CIA_NMI] = false;
420         Interrupts[CRT_NMI] = false;
421         Interrupts[RESTORE_NMI] = false;
422 
423         JAMFlag = false;
424         SR = 0x04;
425         MCT = ((unsigned char*)MicroCodeTable6510 + (0x100*MCTItemSize));
426         AktOpcode = 0x100;
427     }
428     RESET_OLD = *RESET;
429 
430     // IRQ auf low Pegel prüfen
431     if(irq_state > 0)
432         irq_is_low_pegel = true;
433     else
434         irq_is_low_pegel = false;
435 
436     // NMI auf fallende Flanke überprüfen
437     if(nmi_state == true && nmi_state_old == false)
438         nmi_fall_edge = true;
439     else
440         nmi_fall_edge = false;
441     nmi_state_old = nmi_state;
442 
443     if(!CpuWait)
444     {
445         switch(*MCT)
446         {
447         //R // Feetch Opcode
448         case 0:
449             if(JAMFlag) return false;
450 
451             CHK_RDY
452 
453             if((nmi_is_active == true)) // NMIStatePuffer[CYCLES] --> 2 CYCLES Sagt zwei Zyklen vorher muss der NMI schon angelegen haben also vor dem letzten Zyklus des vorigen Befehls
454             {
455                 nmi_is_active = false;
456                 MCT = ((unsigned char*)MicroCodeTable6510 + (0x102*MCTItemSize));
457                 AktOpcode = 0x102;
458 
459                 irq_delay = false;
460                 return false;
461             }
462             else
463             {
464                 if((irq_is_active == true) && (irq_delay ? ((irq_delay_sr_value&4)==0) : ((SR&4)==0))) // IRQLinePuffer[CYCLES] --> 2 CYCLES Sagt zwei Zyklen vorher muss der IRQ schon anliegen also vor dem letzten Zyklus des vorigen Befehls
465                 {
466                     MCT = ((unsigned char*)MicroCodeTable6510 + (0x101*MCTItemSize));
467                     AktOpcode = 0x101;
468 
469                     irq_delay = false;
470                     return false;
471                 }
472             }
473 
474             irq_delay = false;
475 
476             MCT = ((unsigned char*)MicroCodeTable6510 + (Read(PC)*MCTItemSize));
477             AktOpcode = ReadProcTbl[(AktOpcodePC)>>8](AktOpcodePC);
478 
479             *HistoryPointer = *HistoryPointer+1;
480             History[*HistoryPointer] = AktOpcodePC;
481 
482             PC++;
483 
484             return false;
485         break;
486 
487         //R // Lesen von PC-Adresse und verwerfen // PC++
488         case 1:
489             CHK_RDY
490             Read(PC);
491             PC++;
492             break;
493         //W // PC Hi -> Stack // SR|16 // SP--
494         case 2:
495             Write(0x0100+(SP),GetPCHi);
496             SR|=16;
497             SP--;
498             break;
499         //W // PC Lo -> Stack // SP--
500         case 3:
501             Write(0x0100+(SP),GetPCLo);
502             SP--;
503             break;
504         //W // SR -> Stack // SR|4 // SP--
505         case 4:
506             Write(0x0100+(SP),SR);
507             SR|=4;
508             SP--;
509             break;
510         //R // PC Lo von 0xFFFE holen
511         case 5:
512             CHK_RDY
513             SetPCLo(Read(0xFFFE));
514             break;
515         //R // PC Hi von 0xFFFF holen
516         case 6:
517             CHK_RDY
518             SetPCHi(Read(0xFFFF));
519             break;
520         //R // Pointer von PC-Adresse holen // PC++
521         case 7:
522             CHK_RDY
523             Pointer = Read(PC);
524             PC++;
525             break;
526         //R // Lesen von Pointer und verwerfen // Pointer+XR
527         case 8:
528             CHK_RDY
529             Read((unsigned short)Pointer);
530             Pointer += XR;
531             break;
532         //R // Adresse Lo von Pointer-Adresse holen // Pointer++
533         case 9:
534                 CHK_RDY
535                 SetAdresseLo(Read((unsigned short)Pointer));
536                 Pointer++;
537                 break;
538         //R // Adresse Hi von Pointer-Adresse holen //
539         case 10:
540                 CHK_RDY
541                 SetAdresseHi(Read((unsigned short)Pointer));
542                 break;
543         //R // TMPByte von Adresse holen // AC or TMPByte // Set SR(NZ)
544         case 11:
545                 CHK_RDY
546                 TMPByte = Read(Adresse);
547                 AC |= TMPByte;
548                 SET_SR_NZ(AC);
549                 break;
550         //R // JAM
551         case 12:
552                 CHK_RDY
553                 CpuWait=false;
554                 SR = 0x04;
555                 MCT = ((unsigned char*)MicroCodeTable6510 + (0x100*MCTItemSize));
556                 return 0;
557         break;
558         //R // TMPByte von Adresse holen
559         case 13:
560                 CHK_RDY
561                 TMPByte = Read(Adresse);
562                 break;
563         //W // TMPByte nach Adresse schreiben // ASL MEMORY // ORA
564         case 14:
565             Write(Adresse,TMPByte);
566 
567             SET_CARRY(TMPByte&0x80);	// ASL MEMORY
568             TMPByte <<= 1;
569             TMPByte &= 0xFF;
570 
571             AC|=TMPByte;				// ORA
572             SET_SR_NZ(AC);
573 
574             break;
575         //W // TMPByte nach Adresse schreiben
576         case 15:
577                 Write(Adresse,TMPByte);
578                 break;
579         //R // Adresse Hi = 0 // Adresse Lo von PC-Adresse holen // PC++
580         case 16:
581                 CHK_RDY
582                 Adresse = Read(PC);
583                 PC++;
584                 break;
585         //R // TMPByte von Adresse lesen // Adresse Lo + YR
586         case 17:
587                 CHK_RDY
588                 TMPByte = Read(Adresse);
589                 Adresse += YR;
590                 Adresse &= 0xFF;
591                 break;
592         //W // TMPByte nach Adresse schreiben // TMPByte<<1 // Set SR(NZC)
593         case 18:
594                 Write(Adresse,TMPByte);
595                 SET_CARRY(TMPByte&0x80);
596                 TMPByte <<= 1;
597                 TMPByte &= 0xFF;
598                 SET_SIGN(TMPByte);
599                 SET_ZERO(TMPByte);
600                 break;
601         //R // TMPByte von PC-Adresse holen
602         case 19:
603                 CHK_RDY
604                 TMPByte = Read(PC);
605                 break;
606         //W // SR nach SP+0x0100 schreiben // SP-1
607         case 20:
608                 Write(SP+0x0100,SR|16);
609                 SP--;
610                 break;
611         //R // TMPByte von PC-Adresse holen // AC or TMPByte // PC+1
612         case 21:
613                 CHK_RDY
614                 TMPByte = Read(PC);
615                 AC|=TMPByte;
616                 SET_SR_NZ(AC);
617                 PC++;
618                 break;
619         //R // TMPByte von PC-Adresse holen // AC<<1 // Set SR(NZC)
620         case 22:
621                 CHK_RDY
622                 TMPByte = Read(PC);
623                 SET_CARRY(AC&0x80);
624                 AC <<= 1;
625                 AC &= 0xFF;
626                 SET_SIGN(AC);
627                 SET_ZERO(AC);
628                 break;
629         //R // TMPByte von PC-Adresse holen // AC and TMPByte // Set SR(NZC) // PC+1
630         case 23:
631                 CHK_RDY
632                 TMPByte = Read(PC);
633                 AC&=TMPByte;
634                 SET_SR_NZ(AC);
635                 SR&=0xFE;
636                 SR|=AC>>7;
637                 PC++;
638                 break;
639         //R // Adresse Lo von PC-Adresse holen // PC+1
640         case 24:
641                 CHK_RDY
642                 SetAdresseLo(Read(PC));
643                 PC++;
644                 break;
645         //R // Adresse Hi von PC-Adresse holen // PC+1
646         case 25:
647                 CHK_RDY
648                 SetAdresseHi(Read(PC));
649                 PC++;
650                 break;
651         //R // TMPByte von PC-Adresse holen // PC+1 // SR(N) auf FALSE prÃŒfen (BPL)
652         case 26:
653                 CHK_RDY
654                 TMPByte = Read(PC);
655                 PC++;
656                 if((SR&0x80)!=0x00) MCT+=2;
657                 break;
658         //R // TMPByte von PC-Adresse holen // PC+1 // SR(N) auf TRUE prÃŒfen (BMI)
659         case 27:
660                 CHK_RDY
661                 TMPByte = Read(PC);
662                 PC++;
663                 if((SR&0x80)!=0x80) MCT+=2;
664                 break;
665         //R // TMPByte von PC-Adresse holen // PC+1 // SR(V) auf FALSE prÃŒfen (BVC)
666         case 28:
667                 CHK_RDY
668                 TMPByte = Read(PC);
669                 PC++;
670                 if((SR&0x40)!=0x00) MCT+=2;
671                 break;
672         //R // TMPByte von PC-Adresse holen // PC+1 // SR(V) auf TRUE prÃŒfen (BVS)
673         case 29:
674                 CHK_RDY
675                 TMPByte = Read(PC);
676                 PC++;
677                 if((SR&0x40)!=0x40) MCT+=2;
678                 break;
679         //R // TMPByte von PC-Adresse holen // PC+1 // SR(C) auf FALSE prÃŒfen (BCC)
680         case 30:
681                 CHK_RDY
682                 TMPByte = Read(PC);
683                 PC++;
684                 if((SR&0x01)!=0x00) MCT+=2;
685                 break;
686         //R // TMPByte von PC-Adresse holen // PC+1 // SR(C) auf TRUE prÃŒfen (BCS)
687         case 31:
688                 CHK_RDY
689                 TMPByte = Read(PC);
690                 PC++;
691                 if((SR&0x01)!=0x01) MCT+=2;
692                 break;
693         //R // TMPByte von PC-Adresse holen // PC+1 // SR(Z) auf FALSE prÃŒfen (BNE)
694         case 32:
695                 CHK_RDY
696                 TMPByte = Read(PC);
697                 PC++;
698                 if((SR&0x02)!=0x00) MCT+=2;
699                 break;
700         //R // TMPByte von PC-Adresse holen // PC+1 // SR(Z) auf TRUE prÃŒfen (BEQ)
701         case 33:
702                 CHK_RDY
703                 TMPByte = Read(PC);
704                 PC++;
705                 if((SR&0x02)!=0x02) MCT+=2;
706                 break;
707         //R // Lesen von PC-Adresse und verwerfen // BranchAdresse=PC+TMPByte
708         case 34:
709                 CHK_RDY
710                 Read(PC);
711                 BranchAdresse = PC + (signed char)(TMPByte);
712                 if ((PC ^ BranchAdresse) & 0xFF00)
713                 {
714                         PC = (PC&0xFF00)|(BranchAdresse&0xFF);
715                 }
716                 else
717                 {
718                         PC = BranchAdresse;
719                         MCT+=1;
720                 }
721                 break;
722         //R // FIX PC Hi Adresse (Im Branchbefehl)
723         case 35:
724                 CHK_RDY
725                 Read(PC);
726                 PC = BranchAdresse;
727                 break;
728         //R // Adresse Hi von Pointer-Adresse holen // Adresse+YR
729         case 36:
730                 CHK_RDY
731                 SetAdresseHi(Read((unsigned short)Pointer));
732                 Adresse += YR;
733                 idxReg = YR;
734                 break;
735         //R // TMPByte von Adresse holen // Fix Adresse Hi MCT+1 // AC or TMPByte //
736         case 37:
737                 CHK_RDY
738                 if((Adresse&0xFF) >= idxReg)
739                 {
740                         TMPByte = Read(Adresse);
741                         AC|=TMPByte;
742                         SET_SR_NZ(AC);
743                         MCT++;
744                 }
745                 break;
746         //R // Adresse Hi von PC-Adresse holen // PC=Adresse
747         case 38:
748                 CHK_RDY
749                 SetAdresseHi(Read(PC));
750                 PC = Adresse;
751                 break;
752         //R // Lesen von PC-Adresse und verwerfen // XR=AC // Set SR(NZ)
753         case 39:
754                 CHK_RDY
755                 Read(PC);
756                 XR = AC;
757                 SET_SR_NZ(XR);
758                 break;
759         //R // Lesen von PC-Adresse und verwerfen // YR=AC // Set SR(NZ)
760         case 40:
761                 CHK_RDY
762                 Read(PC);
763                 YR = AC;
764                 SET_SR_NZ(YR);
765                 break;
766         //R // Lesen von PC-Adresse und verwerfen // XR=SP // Set SR(NZ)
767         case 41:
768                 CHK_RDY
769                 Read(PC);
770                 XR = SP;
771                 SET_SR_NZ(XR);
772                 break;
773         //R // Lesen von PC-Adresse und verwerfen // AC=XR // Set SR(NZ)
774         case 42:
775                 CHK_RDY
776                 Read(PC);
777                 AC = XR;
778                 SET_SR_NZ(AC);
779                 break;
780         //R // Lesen von PC-Adresse und verwerfen // SP=XR
781         case 43:
782                 CHK_RDY
783                 Read(PC);
784                 SP = XR;
785                 break;
786         //R // Lesen von PC-Adresse und verwerfen // AC=YR // Set SR(NZ)
787         case 44:
788                 CHK_RDY
789                 Read(PC);
790                 AC = YR;
791                 SET_SR_NZ(AC);
792                 break;
793         //W // AC nach SP+0x0100 schreiben // SP-1
794         case 45:
795                 Write(SP+0x0100,AC);
796                 SP--;
797                 break;
798         //R // AC von SP+0x0100 lesen // SP+1
799         case 46:
800                 CHK_RDY
801                 AC = Read(SP+0x0100);
802                 SP++;
803                 break;
804         //R // AC von SP+0x0100 lesen // Set SR(NZ)
805         case 47:
806                 CHK_RDY
807                 AC = Read(SP+0x0100);
808                 SET_SR_NZ(AC);
809                 break;
810         //R // SR von SP+0x0100 lesen // SP+1
811         case 48:
812                 CHK_RDY
813                 SR = Read(SP+0x0100)|32;
814                 SP++;
815                 break;
816         //R // SR von SP+0x0100 lesen
817         case 49:
818                 CHK_RDY
819                 SR = Read(SP+0x0100)|32;
820                 break;
821         //R // TMPByte von PC-Adresse lesen // AC + TMPByte + Carry // PC+1
822         case 50:
823                 CHK_RDY
824                 tmp1 = Read(PC);
825 
826                 if (IF_DECIMAL())
827                 {
828                         tmp = (AC & 0xF) + (tmp1 & 0xF) + (SR & 0x1);
829                         if (tmp > 0x9) tmp += 0x6;
830                         if (tmp <= 0x0F) tmp = (tmp & 0xF) + (AC & 0xF0) + (tmp1 & 0xF0);
831                         else tmp = (tmp & 0xF) + (AC & 0xF0) + (tmp1 & 0xF0) + 0x10;
832                         SET_ZERO(((AC + tmp1 + (SR & 0x1)) & 0xFF));
833                         SET_SIGN(tmp & 0x80);
834                         SET_OVERFLOW(((AC ^ tmp) & 0x80) && !((AC ^ tmp1) & 0x80));
835                         if ((tmp & 0x1F0) > 0x90) tmp += 0x60;
836                         SET_CARRY((tmp & 0xFF0) > 0xF0);
837                 }
838                 else
839                 {
840                         tmp = tmp1 + AC + (SR & 0x01);
841                         SET_SR_NZ(tmp & 0xff);
842                         SET_OVERFLOW(!((AC ^ tmp1) & 0x80) && ((AC ^ tmp) & 0x80));
843                         SET_CARRY(tmp > 0xFF);
844                 }
845                 AC = (unsigned char)tmp;
846                 PC++;
847                 break;
848 
849         //R // TMPByte von Adresse lesen // AC + TMPByte + Carry
850         case 51:
851                 CHK_RDY
852                 tmp1 = Read(Adresse);
853 
854                 if (IF_DECIMAL())
855                 {
856                         tmp = (AC & 0xF) + (tmp1 & 0xF) + (SR & 0x1);
857                         if (tmp > 0x9) tmp += 0x6;
858                         if (tmp <= 0x0F) tmp = (tmp & 0xF) + (AC & 0xF0) + (tmp1 & 0xF0);
859                         else tmp = (tmp & 0xF) + (AC & 0xF0) + (tmp1 & 0xF0) + 0x10;
860                         SET_ZERO(((AC + tmp1 + (SR & 0x1)) & 0xFF));
861                         SET_SIGN(tmp & 0x80);
862                         SET_OVERFLOW(((AC ^ tmp) & 0x80) && !((AC ^ tmp1) & 0x80));
863                         if ((tmp & 0x1F0) > 0x90) tmp += 0x60;
864                         SET_CARRY((tmp & 0xFF0) > 0xF0);
865                 }
866                 else
867                 {
868                         tmp = tmp1 + AC + (SR & 0x01);
869                         SET_SR_NZ(tmp & 0xff);
870                         SET_OVERFLOW(!((AC ^ tmp1) & 0x80) && ((AC ^ tmp) & 0x80));
871                         SET_CARRY(tmp > 0xFF);
872                 }
873                 AC = (unsigned char)tmp;
874                 break;
875 
876         //R // TMPByte von Adresse lesen // Adresse Lo + XR
877         case 52:
878                 CHK_RDY
879                 TMPByte = Read(Adresse);
880                 Adresse += XR;
881                 Adresse &= 0xFF;
882                 break;
883         //R // Adresse Hi von PC-Adresse holen // Adresse+XR  // PC+1 //
884         case 53:
885                 CHK_RDY
886                 SetAdresseHi(Read(PC));
887                 Adresse += XR;
888                 idxReg = XR;
889                 PC++;
890                 break;
891         //R // Adresse Hi von PC-Adresse holen // Adresse+YR  // PC+1 //
892         case 54:
893                 CHK_RDY
894                 SetAdresseHi(Read(PC));
895                 Adresse += YR;
896                 idxReg = YR;
897                 PC++;
898                 break;
899         //R // TMPByte von Adresse lesen // AC + TMPByte + Carry // if(idxReg<Adresse Lo) MCT++
900         case 55:
901                 CHK_RDY
902                 if((Adresse&0xFF)>=(idxReg))
903                 {
904                         tmp1 = Read(Adresse);
905                         if (IF_DECIMAL())
906                         {
907                                 tmp = (AC & 0xF) + (tmp1 & 0xF) + (SR & 0x1);
908                                 if (tmp > 0x9) tmp += 0x6;
909                                 if (tmp <= 0x0F) tmp = (tmp & 0xF) + (AC & 0xF0) + (tmp1 & 0xF0);
910                                 else tmp = (tmp & 0xF) + (AC & 0xF0) + (tmp1 & 0xF0) + 0x10;
911                                 SET_ZERO(((AC + tmp1 + (SR & 0x1)) & 0xFF));
912                                 SET_SIGN(tmp & 0x80);
913                                 SET_OVERFLOW(((AC ^ tmp) & 0x80) && !((AC ^ tmp1) & 0x80));
914                                 if ((tmp & 0x1F0) > 0x90) tmp += 0x60;
915                                 SET_CARRY((tmp & 0xFF0) > 0xF0);
916                         }
917                         else
918                         {
919                                 tmp = tmp1 + AC + (SR & 0x01);
920                                 SET_SR_NZ(tmp & 0xff);
921                                 SET_OVERFLOW(!((AC ^ tmp1) & 0x80) && ((AC ^ tmp) & 0x80));
922                                 SET_CARRY(tmp > 0xFF);
923                         }
924                         AC = (unsigned char)tmp;
925                         MCT++;
926                 }
927                 break;
928         //R // TMPByte von PC-Adresse lesen // AC - TMPByte - Carry // PC+1
929         case 56:
930                 CHK_RDY
931                 src=Read(PC);
932                 tmp2 = AC - src - ((SR & 0x01) ? 0 : 1);
933                 if (IF_DECIMAL())
934                 {
935                         tmp = (AC & 0xF) - (src & 0xF) - ((SR & 0x1) ? 0 : 1);
936                         if (tmp & 0x10) tmp = ((tmp - 6) & 0xF)| ((AC & 0xF0) - (src & 0xF0) - 0x10);
937                         else tmp = (tmp & 0xF) | ((AC & 0xF0) - (src & 0xF0));
938                         if (tmp & 0x100) tmp -= 0x60;
939                         SET_CARRY(tmp2 < 0x100);
940                         SET_SR_NZ(tmp2 & 0xFF);
941                         SET_OVERFLOW(((AC ^ tmp2) & 0x80) && ((AC ^ src) & 0x80));
942                         AC = (unsigned char) tmp;
943                 }
944                 else
945                 {
946                         SET_SR_NZ(tmp2 & 0xff);
947                         SET_CARRY(tmp2 < 0x100);
948                         SET_OVERFLOW(((AC ^ tmp2) & 0x80)
949                                                          && ((AC ^ src) & 0x80));
950                         AC = (unsigned char) tmp2;
951                 }
952                 PC++;
953                 break;
954         //R // TMPByte von Adresse lesen // AC - TMPByte - Carry
955         case 57:
956                 CHK_RDY
957                 src=Read(Adresse);
958                 tmp2 = AC - src - ((SR & 0x01) ? 0 : 1);
959                 if (IF_DECIMAL())
960                 {
961                         tmp = (AC & 0xF) - (src & 0xF) - ((SR & 0x1) ? 0 : 1);
962                         if (tmp & 0x10) tmp = ((tmp - 6) & 0xF)| ((AC & 0xF0) - (src & 0xF0) - 0x10);
963                         else tmp = (tmp & 0xF) | ((AC & 0xF0) - (src & 0xF0));
964                         if (tmp & 0x100) tmp -= 0x60;
965                         SET_CARRY(tmp2 < 0x100);
966                         SET_SR_NZ(tmp2 & 0xFF);
967                         SET_OVERFLOW(((AC ^ tmp2) & 0x80) && ((AC ^ src) & 0x80));
968                         AC = (unsigned char) tmp;
969                 }
970                 else
971                 {
972                         SET_SR_NZ(tmp2 & 0xff);
973                         SET_CARRY(tmp2 < 0x100);
974                         SET_OVERFLOW(((AC ^ tmp2) & 0x80)
975                                                          && ((AC ^ src) & 0x80));
976                         AC = (unsigned char) tmp2;
977                 }
978                 break;
979         //R // TMPByte von Adresse lesen // AC - TMPByte - Carry // if(idxReg<Adresse Lo) MCT++
980         case 58:
981                 CHK_RDY
982                 if((Adresse&0xFF)>=(idxReg))
983                 {
984                         src=Read(Adresse);
985                         tmp2 = AC - src - ((SR & 0x01) ? 0 : 1);
986                         if (IF_DECIMAL())
987                         {
988                                 tmp = (AC & 0xF) - (src & 0xF) - ((SR & 0x1) ? 0 : 1);
989                                 if (tmp & 0x10) tmp = ((tmp - 6) & 0xF)| ((AC & 0xF0) - (src & 0xF0) - 0x10);
990                                 else tmp = (tmp & 0xF) | ((AC & 0xF0) - (src & 0xF0));
991                                 if (tmp & 0x100) tmp -= 0x60;
992                                 SET_CARRY(tmp2 < 0x100);
993                                 SET_SR_NZ(tmp2 & 0xFF);
994                                 SET_OVERFLOW(((AC ^ tmp2) & 0x80) && ((AC ^ src) & 0x80));
995                                 AC = (unsigned char) tmp;
996                         }
997                         else
998                         {
999                                 SET_SR_NZ(tmp2 & 0xff);
1000                                 SET_CARRY(tmp2 < 0x100);
1001                                 SET_OVERFLOW(((AC ^ tmp2) & 0x80)
1002                                                                  && ((AC ^ src) & 0x80));
1003                                 AC = (unsigned char) tmp2;
1004                         }
1005                         MCT++;
1006                 }
1007                 break;
1008         //R // TMPByte von SP+0x0100 holen
1009         case 59:
1010                 CHK_RDY
1011                 TMPByte=Read(SP + 0x0100);
1012                 break;
1013         //W // PC-Adresse Hi nach SP+0x0100 schreiben // SP-1
1014         case 60:
1015                 Write(SP+0x0100,GetPCHi);
1016                 SP--;
1017                 break;
1018         //W // PC-Adresse Lo nach SP+0x0100 schreiben // SP-1
1019         case 61:
1020                 Write(SP+0x0100,GetPCLo);
1021                 SP--;
1022                 break;
1023         //R // TMPByte von SP+0x0100 holen // SP+1
1024         case 62:
1025                 CHK_RDY
1026                 TMPByte = Read(SP+0x0100);
1027                 SP++;
1028                 break;
1029         //R // PC-Adresse Lo von SP+0x0100 holen // SP+1
1030         case 63:
1031                 CHK_RDY
1032                 SetPCLo(Read(SP+0x0100));
1033                 SP++;
1034                 break;
1035         //R // PC-Adresse Hi von SP+0x0100 holen
1036         case 64:
1037                 CHK_RDY
1038                 SetPCHi(Read(SP+0x0100));
1039                 break;
1040         //R // TMPByte von PC-Adresse laden // PC+1
1041         case 65:
1042                 CHK_RDY
1043                 TMPByte = Read(PC);
1044                 PC++;
1045                 break;
1046         //R // TMPByte von PC-Adresse lesen // AC and TMPByte // Set SR(NZ) // PC+1
1047         case 66:
1048                 CHK_RDY
1049                 TMPByte=Read(PC);
1050                 AC &= TMPByte;
1051                 SET_SR_NZ(AC);
1052                 PC++;
1053                 break;
1054         //R // TMPByte von Adresse lesen // AC and TMPByte // Set SR(NZ)
1055         case 67:
1056                 CHK_RDY
1057                 TMPByte=Read(Adresse);
1058                 AC &= TMPByte;
1059                 SET_SR_NZ(AC);
1060                 break;
1061         //R // TMPByte von Adresse lesen // AC and TMPByte // Set SR(NZ) // if(idxReg<Adresse Lo) MCT++
1062         case 68:
1063                 CHK_RDY
1064                 if((Adresse&0xFF)>=(idxReg))
1065                 {
1066                         TMPByte=Read(Adresse);
1067                         AC &= TMPByte;
1068                         SET_SR_NZ(AC);
1069                         MCT++;
1070                 }
1071                 break;
1072         //R // TMPByte von Adresse lesen // CarrayFalg=0
1073         case 69:
1074                 CHK_RDY
1075                 TMPByte = Read(PC);
1076                 SR &= 0xFE;
1077                 break;
1078         //R // TMPByte von Adresse lesen // DezimalFalg=0
1079         case 70:
1080                 CHK_RDY
1081                 TMPByte = Read(PC);
1082                 SR &= 0xF7;
1083                 break;
1084         //R // TMPByte von Adresse lesen // InterruptFalg=0
1085         case 71:
1086                 CHK_RDY
1087                 TMPByte = Read(PC);
1088                 irq_delay_sr_value = SR;
1089                 SR &= 0xFB;
1090                 irq_delay = true;
1091                 break;
1092         //R // TMPByte von Adresse lesen // OverflowFalg=0
1093         case 72:
1094                 CHK_RDY
1095                 TMPByte = Read(PC);
1096                 SR &= 0xBF;
1097                 break;
1098         //R // TMPByte von Adresse lesen // CarrayFalg=1
1099         case 73:
1100                 CHK_RDY
1101                 TMPByte = Read(PC);
1102                 SR |= 0x01;
1103                 break;
1104         //R // TMPByte von Adresse lesen // DezimalFalg=1
1105         case 74:
1106                 CHK_RDY
1107                 TMPByte = Read(PC);
1108                 SR |= 0x08;
1109                 break;
1110         //R // TMPByte von Adresse lesen // InterruptFalg=1
1111         case 75:
1112                 CHK_RDY
1113                 TMPByte = Read(PC);
1114                 irq_delay_sr_value = SR;
1115                 SR |= 0x04;
1116                 irq_delay = true;
1117                 break;
1118         //R // TMPByte von Adresse lesen // BIT Operation
1119         case 76:
1120                 CHK_RDY
1121                 TMPByte = Read(Adresse);
1122                 SET_ZERO(AC & TMPByte);
1123                 SR = (TMPByte & 0xC0) | (SR & 0x3F);
1124                 break;
1125         //W // AC nach Adresse schreiben
1126         case 77:
1127                 Write(Adresse,AC);
1128                 break;
1129         //W // XR nach Adresse schreiben
1130         case 78:
1131                 Write(Adresse,XR);
1132                 break;
1133         //W // YR nach Adresse schreiben
1134         case 79:
1135                 Write(Adresse,YR);
1136                 break;
1137         //R // AC von PC-Adresse lesen // Set SR(NZ) // PC+1
1138         case 80:
1139                 CHK_RDY
1140                 AC = Read(PC);
1141                 SET_SR_NZ(AC);
1142                 PC++;
1143                 break;
1144         //R // AC von Adresse lesen // Set SR(NZ)
1145         case 81:
1146                 CHK_RDY
1147                 AC = Read(Adresse);
1148                 SET_SR_NZ(AC);
1149                 break;
1150         //R // AC von Adresse lesen // Set SR(NZ) // if(idxReg<Adresse Lo) MCT++
1151         case 82:
1152                 CHK_RDY
1153                 if((Adresse&0xFF)>=(idxReg))
1154                 {
1155                         TMPByte=Read(Adresse);
1156                         AC = TMPByte;
1157                         SET_SR_NZ(AC);
1158                         MCT++;
1159                 }
1160                 break;
1161         //R // XR von PC-Adresse lesen // Set SR(NZ) // PC+1
1162         case 83:
1163                 CHK_RDY
1164                 XR = Read(PC);
1165                 SET_SR_NZ(XR);
1166                 PC++;
1167                 break;
1168         //R // XR von Adresse lesen // Set SR(NZ)
1169         case 84:
1170                 CHK_RDY
1171                 XR = Read(Adresse);
1172                 SET_SR_NZ(XR);
1173                 break;
1174         //R // XR von Adresse lesen // Set SR(NZ) // if(idxReg<Adresse Lo) MCT++
1175         case 85:
1176                 CHK_RDY
1177                 if((Adresse&0xFF)>=(idxReg))
1178                 {
1179                         TMPByte=Read(Adresse);
1180                         XR = TMPByte;
1181                         SET_SR_NZ(XR);
1182                         MCT++;
1183                 }
1184                 break;
1185         //R // YR von PC-Adresse lesen // Set SR(NZ) // PC+1
1186         case 86:
1187                 CHK_RDY
1188                 YR = Read(PC);
1189                 SET_SR_NZ(YR);
1190                 PC++;
1191                 break;
1192         //R // YR von Adresse lesen // Set SR(NZ)
1193         case 87:
1194                 CHK_RDY
1195                 YR = Read(Adresse);
1196                 SET_SR_NZ(YR);
1197                 break;
1198         //R // YR von Adresse lesen // Set SR(NZ) // if(idxReg<Adresse Lo) MCT++
1199         case 88:
1200                 CHK_RDY
1201                 if((Adresse&0xFF)>=(idxReg))
1202                 {
1203                         TMPByte=Read(Adresse);
1204                         YR = TMPByte;
1205                         SET_SR_NZ(YR);
1206                         MCT++;
1207                 }
1208                 break;
1209         //R // TMPByte von Adresse lesen // XR+1 // Set SR(NZ)
1210         case 89:
1211                 CHK_RDY
1212                 TMPByte = Read(PC);
1213                 XR ++;
1214                 SET_SR_NZ(XR);
1215                 break;
1216         //R // TMPByte von Adresse lesen // YR+1 // Set SR(NZ)
1217         case 90:
1218                 CHK_RDY
1219                 TMPByte = Read(PC);
1220                 YR ++;
1221                 SET_SR_NZ(YR);
1222                 break;
1223         //R // TMPByte von Adresse lesen // XR-1 // Set SR(NZ)
1224         case 91:
1225                 CHK_RDY
1226                 TMPByte = Read(PC);
1227                 XR --;
1228                 SET_SR_NZ(XR);
1229                 break;
1230         //R // TMPByte von Adresse lesen // YR-1 // Set SR(NZ)
1231         case 92:
1232                 CHK_RDY
1233                 TMPByte = Read(PC);
1234                 YR --;
1235                 SET_SR_NZ(YR);
1236                 break;
1237         //R // Illegale Opcode //
1238         case 93:
1239                 //// Wird nie angesprungen !!! ////
1240                 break;
1241         //R // PC LO von Adresse lesen // AdresseLo+1
1242         case 94:
1243                 CHK_RDY
1244                 SetPCLo(Read(Adresse));
1245                 Adresse = (Adresse&0xFF00)|((Adresse+1)&0x00FF);
1246                 break;
1247         //R // PC HI von Adresse lesen
1248         case 95:
1249                 CHK_RDY
1250                 SetPCHi(Read(Adresse));
1251                 break;
1252         //R // PC LO von $FFFC lesen
1253         case 96:
1254                 CHK_RDY
1255                 SetPCLo(Read(0xFFFC));
1256                 break;
1257         //R // PC HI von $FFFD lesen
1258         case 97:
1259                 CHK_RDY
1260                 SetPCHi(Read(0xFFFD));
1261                 break;
1262         //R // TMPByte von PC-Adresse lesen // AC - TMPByte (AC wird nicht verÀndert) // Set SR(NZC) // PC+1
1263         case 98:
1264                 CHK_RDY
1265                 TMPByte=Read(PC);
1266                 tmp = AC - TMPByte;
1267                 SET_CARRY(tmp < 0x100);
1268                 SET_SIGN(tmp);
1269                 SET_ZERO(tmp &= 0xFF);
1270                 PC++;
1271                 break;
1272         //R // TMPByte von Adresse lesen // AC - TMPByte (AC wird nicht verÀndert) // Set SR(NZC)
1273         case 99:
1274                 CHK_RDY
1275                 TMPByte=Read(Adresse);
1276                 tmp = AC - TMPByte;
1277                 SET_CARRY(tmp < 0x100);
1278                 SET_SIGN(tmp);
1279                 SET_ZERO(tmp &= 0xFF);
1280                 break;
1281         //R // TMPByte von Adresse lesen // AC - TMPByte (AC wird nicht verÀndert) // if(idxReg<Adresse Lo) MCT++
1282         case 100:
1283                 CHK_RDY
1284                 if((Adresse&0xFF)>=(idxReg))
1285                 {
1286                         TMPByte=Read(Adresse);
1287                         tmp = AC - TMPByte;
1288                         SET_CARRY(tmp < 0x100);
1289                         SET_SIGN(tmp);
1290                         SET_ZERO(tmp &= 0xFF);
1291                         MCT++;
1292                 }
1293                 break;
1294         //R // TMPByte von PC-Adresse lesen // XR - TMPByte (XR wird nicht verÀndert) // Set SR(NZC) // PC+1
1295         case 101:
1296                 CHK_RDY
1297                 TMPByte=Read(PC);
1298                 tmp = XR - TMPByte;
1299                 SET_CARRY(tmp < 0x100);
1300                 SET_SIGN(tmp);
1301                 SET_ZERO(tmp &= 0xFF);
1302                 PC++;
1303                 break;
1304         //R // TMPByte von Adresse lesen // XR - TMPByte (XR wird nicht verÀndert) // Set SR(NZC)
1305         case 102:
1306                 CHK_RDY
1307                 TMPByte=Read(Adresse);
1308                 tmp = XR - TMPByte;
1309                 SET_CARRY(tmp < 0x100);
1310                 SET_SIGN(tmp);
1311                 SET_ZERO(tmp &= 0xFF);
1312                 break;
1313         //R // TMPByte von PC-Adresse lesen // YR - TMPByte (XR wird nicht verÀndert) // Set SR(NZC) // PC+1
1314         case 103:
1315                 CHK_RDY
1316                 TMPByte=Read(PC);
1317                 tmp = YR - TMPByte;
1318                 SET_CARRY(tmp < 0x100);
1319                 SET_SIGN(tmp);
1320                 SET_ZERO(tmp &= 0xFF);
1321                 PC++;
1322                 break;
1323         //R // TMPByte von Adresse lesen // YR - TMPByte (XR wird nicht verÀndert) // Set SR(NZC)
1324         case 104:
1325                 CHK_RDY
1326                 TMPByte=Read(Adresse);
1327                 tmp = YR - TMPByte;
1328                 SET_CARRY(tmp < 0x100);
1329                 SET_SIGN(tmp);
1330                 SET_ZERO(tmp &= 0xFF);
1331                 break;
1332         //R // TMPByte von PC-Adresse lesen // AC XOR TMPByte // Set SR(NZC) // PC+1
1333         case 105:
1334                 CHK_RDY
1335                 TMPByte=Read(PC);
1336                 AC^=TMPByte;
1337                 SET_SR_NZ(AC);
1338                 PC++;
1339                 break;
1340         //R // TMPByte von Adresse lesen // AC XOR TMPByte // Set SR(NZC)
1341         case 106:
1342                 CHK_RDY
1343                 TMPByte=Read(Adresse);
1344                 AC^=TMPByte;
1345                 SET_SR_NZ(AC);
1346                 break;
1347         //R // TMPByte von Adresse lesen // AC XOR TMPByte // if(idxReg<Adresse Lo) MCT++
1348         case 107:
1349                 CHK_RDY
1350                 if((Adresse&0xFF)>=(idxReg))
1351                 {
1352                         TMPByte=Read(Adresse);
1353                         AC^=TMPByte;
1354                         SET_SR_NZ(AC);
1355                         MCT++;
1356                 }
1357                 break;
1358         //R // TMPByte von PC-Adresse holen // AC>>1 // Set SR(NZC)
1359         case 108:
1360                 CHK_RDY
1361                 TMPByte = Read(PC);
1362                 SET_CARRY(AC&0x01);
1363                 AC >>= 1;
1364                 SET_SIGN(0);
1365                 SET_ZERO(AC);
1366                 break;
1367         //W // TMPByte nach Adresse schreiben // TMPByte>>1 // Set SR(NZC)
1368         case 109:
1369                 Write(Adresse,TMPByte);
1370                 SET_CARRY(TMPByte&0x01);
1371                 TMPByte >>= 1;
1372                 SET_SIGN(0);
1373                 SET_ZERO(TMPByte);
1374                 break;
1375         //R // TMPByte von PC-Adresse holen // C<-AC<<1<-C // Set SR(NZC)
1376         case 110:
1377                 CHK_RDY
1378                 TMPByte = Read(PC);
1379                 tmp = AC;
1380                 tmp <<= 1;
1381                 if (IF_CARRY()) tmp |= 0x1;
1382                 SET_CARRY(tmp > 0xff);
1383                 tmp &= 0xff;
1384                 SET_SIGN(tmp);
1385                 SET_ZERO(tmp);
1386                 AC = tmp;
1387                 break;
1388         //W // TMPByte nach Adresse schreiben // C<-TMPByte<<1<-C // Set SR(NZC)
1389         case 111:
1390                 Write(Adresse,TMPByte);
1391                 tmp = TMPByte;
1392                 tmp <<= 1;
1393                 if (IF_CARRY()) tmp |= 0x1;
1394                 SET_CARRY(tmp > 0xff);
1395                 tmp &= 0xff;
1396                 SET_SIGN(tmp);
1397                 SET_ZERO(tmp);
1398                 TMPByte = tmp;
1399                 break;
1400         //R // TMPByte von PC-Adresse holen // C->AC>>1->C // Set SR(NZC)
1401         case 112:
1402                 CHK_RDY
1403                 TMPByte = Read(PC);
1404                 carry_tmp=IF_CARRY();
1405                 SET_CARRY(AC & 0x01);
1406                 AC >>= 1;
1407                 if(carry_tmp) AC |= 0x80;
1408                 SET_SIGN(AC);
1409                 SET_ZERO(AC);
1410                 break;
1411         //W // TMPByte nach Adresse schreiben // C->TMPByte>>1->C // Set SR(NZC)
1412         case 113:
1413                 Write(Adresse,TMPByte);
1414                 carry_tmp=IF_CARRY();
1415                 SET_CARRY(TMPByte & 0x01);
1416                 TMPByte >>= 1;
1417                 if(carry_tmp) TMPByte |= 0x80;
1418                 SET_SIGN(TMPByte);
1419                 SET_ZERO(TMPByte);
1420                 break;
1421         //W // TMPByte nach Adresse schreiben // TMPByte+1 // Set SR(NZ)
1422         case 114:
1423                 Write(Adresse,TMPByte);
1424                 TMPByte++;
1425                 SET_SR_NZ(TMPByte);
1426                 break;
1427         //W // TMPByte nach Adresse schreiben // TMPByte-1 // Set SR(NZ)
1428         case 115:
1429                 Write(Adresse,TMPByte);
1430                 TMPByte--;
1431                 SET_SR_NZ(TMPByte);
1432                 break;
1433         //W // SR nach 0x100+SP schreiben // SP-- // IFlag setzen // BFlag löschen
1434         case 116:
1435                 SR&=239;
1436                 Write(0x0100+SP,SR);
1437                 SP--;
1438                 SR|=4;
1439                 break;
1440         //R // PC Lo von 0xFFFA holen
1441         case 117:
1442                 CHK_RDY
1443                 SetPCLo(Read(0xFFFA));
1444                 break;
1445         //R // PC Hi von 0xFFFB holen
1446         case 118:
1447                 CHK_RDY
1448                 SetPCHi(Read(0xFFFB));
1449                 break;
1450         //R // TMPByte von Adresse holen // Fix Adresse Hi MCT+1
1451         case 119:
1452                 CHK_RDY
1453                 if((Adresse&0xFF)>=(idxReg))
1454                 {
1455                         TMPByte = Read(Adresse);
1456                         MCT++;
1457                 }
1458                 break;
1459         //W // TMPByte nach Adresse schreiben // Illegal [SLO]
1460         case 120:
1461                 Write(Adresse,TMPByte);
1462                 SET_CARRY(TMPByte&0x80);	// ASL MEMORY
1463                 TMPByte <<= 1;
1464                 AC |= TMPByte;				// ORA
1465                 SET_SR_NZ(AC);
1466                 break;
1467         //W // TMPByte nach Adresse schreiben // Illegal [RLA]
1468         case 121:
1469                 Write(Adresse,TMPByte);
1470                 tmp = TMPByte;
1471                 tmp <<= 1;					// ROL
1472                 if (IF_CARRY()) tmp |= 0x1;
1473                 SET_CARRY(tmp > 0xFF);
1474                 tmp &= 0xFF;
1475                 TMPByte = tmp;
1476                 AC &= TMPByte;				// AND
1477                 SET_SR_NZ(AC);
1478                 break;
1479         //W // TMPByte nach Adresse schreiben // Illegal [SRE]
1480         case 122:
1481                 Write(Adresse,TMPByte);
1482                 SET_CARRY(TMPByte & 0x01);	// LSR
1483                 TMPByte >>= 1;
1484                 AC ^= TMPByte;				// EOR
1485                 SET_SR_NZ(AC);
1486                 break;
1487         //W // TMPByte nach Adresse schreiben // Illegal [RRA]
1488         case 123:
1489                 Write(Adresse,TMPByte);
1490 
1491                 carry_tmp = IF_CARRY();		// ROR
1492                 SET_CARRY(TMPByte & 0x01);
1493                 TMPByte >>= 1;
1494                 if(carry_tmp) TMPByte |= 0x80;
1495 
1496                 tmp1 = TMPByte;				// ADC
1497                 if (IF_DECIMAL())
1498                 {
1499                         tmp = (AC & 0xF) + (tmp1 & 0xF) + (SR & 0x1);
1500                         if (tmp > 0x9) tmp += 0x6;
1501                         if (tmp <= 0x0F) tmp = (tmp & 0xF) + (AC & 0xF0) + (tmp1 & 0xF0);
1502                         else tmp = (tmp & 0xF) + (AC & 0xF0) + (tmp1 & 0xF0) + 0x10;
1503                         SET_ZERO(((AC + tmp1 + (SR & 0x1)) & 0xFF));
1504                         SET_SIGN(tmp & 0x80);
1505                         SET_OVERFLOW(((AC ^ tmp) & 0x80) && !((AC ^ tmp1) & 0x80));
1506                         if ((tmp & 0x1F0) > 0x90) tmp += 0x60;
1507                         SET_CARRY((tmp & 0xFF0) > 0xF0);
1508                 }
1509                 else
1510                 {
1511                         tmp = tmp1 + AC + (SR & 0x01);
1512                         SET_SR_NZ(tmp & 0xff);
1513                         SET_OVERFLOW(!((AC ^ tmp1) & 0x80) && ((AC ^ tmp) & 0x80));
1514                         SET_CARRY(tmp > 0xFF);
1515                 }
1516                 AC = (unsigned char)tmp;
1517                 break;
1518         //W // TMPByte nach Adresse schreiben // Illegal [DCP]
1519         case 124:
1520                 Write(Adresse,TMPByte);
1521                 TMPByte--;					//DEC
1522 
1523                 tmp = AC - TMPByte;			//CMP
1524                 SET_CARRY(tmp < 0x100);
1525                 SET_SIGN(tmp);
1526                 SET_ZERO(tmp &= 0xFF);
1527                 break;
1528         //W // TMPByte nach Adresse schreiben // Illegal [ISB]
1529         case 125:
1530                 Write(Adresse,TMPByte);
1531                 TMPByte++;					//INC
1532 
1533                 src=TMPByte;				//SBC
1534                 tmp2 = AC - src - ((SR & 0x01) ? 0 : 1);
1535                 if (IF_DECIMAL())
1536                 {
1537                         tmp = (AC & 0xF) - (src & 0xF) - ((SR & 0x1) ? 0 : 1);
1538                         if (tmp & 0x10) tmp = ((tmp - 6) & 0xF)| ((AC & 0xF0) - (src & 0xF0) - 0x10);
1539                         else tmp = (tmp & 0xF) | ((AC & 0xF0) - (src & 0xF0));
1540                         if (tmp & 0x100) tmp -= 0x60;
1541                         SET_CARRY(tmp2 < 0x100);
1542                         SET_SR_NZ(tmp2 & 0xFF);
1543                         SET_OVERFLOW(((AC ^ tmp2) & 0x80) && ((AC ^ src) & 0x80));
1544                         AC = (unsigned char) tmp;
1545                 }
1546                 else
1547                 {
1548                         SET_SR_NZ(tmp2 & 0xff);
1549                         SET_CARRY(tmp2 < 0x100);
1550                         SET_OVERFLOW(((AC ^ tmp2) & 0x80)
1551                                                          && ((AC ^ src) & 0x80));
1552                         AC = (unsigned char) tmp2;
1553                 }
1554                 break;
1555         //R // AC von Adresse lesen // AC -> XR // Set SR(NZ) // Illegal [LAX]
1556         case 126:
1557                 CHK_RDY
1558                 AC = Read(Adresse);
1559                 XR = AC;
1560                 SET_SR_NZ(AC);
1561                 break;
1562         //R // AC von Adresse lesen // AC -> XR // Set SR(NZ) // if(idxReg<Adresse Lo) MCT++ // Illegal [LAX]
1563         case 127:
1564                 CHK_RDY
1565                 if((Adresse&0xFF)>=(idxReg))
1566                 {
1567                         TMPByte=Read(Adresse);
1568                         AC = TMPByte;
1569                         XR = AC;
1570                         SET_SR_NZ(AC);
1571                         MCT++;
1572                 }
1573                 break;
1574         //W // TMPByte = AC & XR // TMPByte nach Adresse schreiben // Set SR(NZ) // Illegal [SAX]
1575         case 128:
1576                 TMPByte = AC & XR;
1577                 Write(Adresse,TMPByte);
1578                 break;
1579         //R // Illegal [ASR]
1580         case 129:
1581                 CHK_RDY
1582                 AC &= Read(PC);				// AND
1583 
1584                 SET_CARRY(AC & 0x01);		// LSR
1585                 AC >>= 1;
1586                 SET_SIGN(0);
1587                 SET_ZERO(AC);
1588                 PC++;
1589                 break;
1590         //R // Illegal [ARR]
1591         case 130:
1592                 CHK_RDY
1593                 tmp2 = Read(PC) & AC;
1594                 AC = ((SR & 0x01) ? (tmp2 >> 1) | 0x80 : tmp2 >> 1);
1595                 if (!IF_DECIMAL())
1596                 {
1597                         SET_SR_NZ(AC);
1598                         SET_CARRY(AC & 0x40);
1599                         SET_OVERFLOW(!!((AC & 0x40) ^ ((AC & 0x20) << 1)));
1600                 }
1601                 else
1602                 {
1603                         SET_SIGN((SR & 0x01) ? 0x80 : 0);
1604                         SET_ZERO(AC);
1605                         SET_OVERFLOW(!!((tmp2 ^ AC) & 0x40));
1606                         if ((tmp2 & 0x0F) + (tmp2 & 0x01) > 5) AC = (AC & 0xF0) | ((AC + 6) & 0x0F);
1607                         SET_CARRY(((tmp2 + (tmp2 & 0x10)) & 0x1F0)>0x50);
1608                         if(IF_CARRY()) AC += 0x60;
1609                 }
1610                 PC++;
1611                 break;
1612         //R // Illegal [ANE]
1613         case 131:
1614                 CHK_RDY
1615                 TMPByte = Read(PC);
1616                 AC = (AC | 0xEE) & XR & TMPByte;
1617                 SET_SR_NZ(AC);
1618                 PC++;
1619                 break;
1620         //R // Illegal [LXA]
1621         case 132:
1622                 CHK_RDY
1623                 TMPByte = Read(PC);
1624                 AC = XR = ((AC | 0xEE) & TMPByte);
1625                 SET_SR_NZ(AC);
1626                 PC++;
1627                 break;
1628         //R // Illegal [SBX]
1629         case 133:
1630                 CHK_RDY
1631                 tmp = Read(PC);
1632                 tmp = (AC & XR) - tmp;
1633                 SET_CARRY(tmp < 0x100);
1634                 XR = tmp & 0xFF;
1635                 SET_SR_NZ(XR);
1636                 PC++;
1637                 break;
1638         //W // Illegal [SHY]
1639         case 134:
1640                 Write(Adresse,YR & ((((Adresse) + XR) >> 8)));
1641                 break;
1642         //W // Illegal [SHX]
1643         case 135:
1644                 Write(Adresse,XR & ((((Adresse) + YR) >> 8)));
1645                 break;
1646         //W // Illegal [SHA]
1647         case 136:
1648                 Write(Adresse,AC & XR & ((((Adresse) + YR) >> 8)));
1649                 break;
1650         //W // Illegal [SHS]
1651         case 137:
1652                 Write(Adresse,AC & XR & ((((Adresse) + YR) >> 8)));
1653                 SP = AC & XR;
1654                 break;
1655         //R // Illegal [ANC]
1656         case 138:
1657                 CHK_RDY
1658                 AC &= Read(PC);
1659                 SET_SR_NZ(AC);
1660                 SET_CARRY(SR&0x80);
1661                 PC++;
1662                 break;
1663         //R // Illegal [LAE]
1664         case 139:
1665                 CHK_RDY
1666                 TMPByte = Read(Adresse);
1667                 AC = XR = SP = SP & (TMPByte);
1668                 SET_SR_NZ(AC);
1669                 break;
1670         //R // Illegal [LAE]
1671         case 140:
1672                 CHK_RDY
1673                 if((Adresse&0xFF)>=(idxReg))
1674                 {
1675                         TMPByte=Read(Adresse);
1676                         AC = XR = SP = SP & (TMPByte);
1677                         SET_SR_NZ(AC);
1678                         MCT++;
1679                 }
1680                 break;
1681         }
1682         MCT++;
1683 
1684         if(*MCT == 0)
1685         {
1686             /*
1687             if(NMIState == true)
1688             {
1689                 isNMI = true;
1690                 return false;
1691             }
1692             else if((Interrupts[VIC_IRQ] || Interrupts[CIA_IRQ] || Interrupts[REU_IRQ]) && ((SR&4)==0))
1693             {
1694                 isIRQ = true;
1695                 return false;
1696             }
1697             */
1698 
1699             AktOpcodePC = PC;
1700             if(Breakpoints[PC] & 1)
1701             {
1702                     *BreakStatus |=1;
1703                     BreakWerte[0] = PC;
1704             }
1705             if(Breakpoints[AC] & 2)
1706             {
1707                     *BreakStatus |=2;
1708                     BreakWerte[1] = AC;
1709             }
1710             if(Breakpoints[XR] & 4)
1711             {
1712                     *BreakStatus |=4;
1713                     BreakWerte[2] = XR;
1714             }
1715             if(Breakpoints[YR] & 8)
1716             {
1717                     *BreakStatus |=8;
1718                     BreakWerte[3] = YR;
1719             }
1720 
1721             if(ResetReadyAdr == PC)
1722             {
1723                 *ResetReady = true;
1724             }
1725             return true;
1726         }
1727         else return false;
1728     }
1729     return false;
1730 }
1731 
Phi1()1732 void MOS6510::Phi1()
1733 {
1734     if(irq_is_low_pegel)
1735     {
1736         irq_is_active = true;
1737     }
1738     else irq_is_active = false;
1739 
1740     if(nmi_fall_edge)
1741         nmi_is_active = true;
1742 }
1743 
MOS6510_PORT(void)1744 MOS6510_PORT::MOS6510_PORT(void)
1745 {
1746 	Reset();
1747 }
1748 
~MOS6510_PORT(void)1749 MOS6510_PORT::~MOS6510_PORT(void)
1750 {
1751 }
1752 
Reset(void)1753 void MOS6510_PORT::Reset(void)
1754 {
1755     DATA = 0x3f;
1756     DATA_OUT = 0x3f;
1757     DATA_READ = 0x3f;
1758     DIR = 0;
1759     DIR_READ = 0;
1760     DATA_SET_BIT6 = 0;
1761     DATA_SET_BIT7 = 0;
1762     DATA_FALLOFF_BIT6 = 0;
1763     DATA_FALLOFF_BIT7 = 0;
1764 }
1765 
ConfigChanged(int tape_sense,int caps_sense,unsigned char pullup)1766 void MOS6510_PORT::ConfigChanged(int tape_sense, int caps_sense,unsigned char pullup)
1767 {
1768 	TAPE_SENSE = !!(tape_sense);
1769 	/* Tape Motor Status.  */
1770 	static unsigned char OLD_DATA_OUT = 0xFF;
1771 	/* Tape Write Line Status */
1772 	static unsigned char OLD_WRITE_BIT = 0xFF;
1773 
1774     DATA_OUT = (DATA_OUT & ~DIR)|(DATA & DIR);
1775     DATA_READ = (DATA | ~DIR) & (DATA_OUT | pullup);
1776 
1777     if ((pullup & 0x40) && !caps_sense) DATA_READ &= 0xBF;
1778 	if (!(DIR & 0x20)) DATA_READ &= 0xDF;
1779     if (tape_sense && !(DIR & 0x10))DATA_READ &= 0xEF;
1780     if (((DIR & DATA) & 0x20) != OLD_DATA_OUT)
1781 	{
1782         OLD_DATA_OUT = (DIR & DATA) & 0x20;
1783         DATASETTE_MOTOR = !OLD_DATA_OUT;
1784     }
1785 
1786     if (((~DIR | DATA) & 0x8) != OLD_WRITE_BIT)
1787 	{
1788         OLD_WRITE_BIT = (~DIR | DATA) & 0x8;
1789         //datasette_toggle_write_bit((~pport.dir | pport.data) & 0x8);
1790     }
1791     DIR_READ = DIR;
1792 }
1793 /*
1794 bool MOS6510_PORT::SaveFreez(FILE* File)
1795 {
1796 	fwrite(&DIR,1,sizeof(DIR),File);
1797 	fwrite(&DATA,1,sizeof(DATA),File);
1798 	fwrite(&DIR_READ,1,sizeof(DIR_READ),File);
1799 	fwrite(&DATA_READ,1,sizeof(DATA_READ),File);
1800 	fwrite(&DATA_OUT,1,sizeof(DATA_OUT),File);
1801 	fwrite(&DATA_SET_CLK_BIT6,1,sizeof(DATA_SET_CLK_BIT6),File);
1802 	fwrite(&DATA_SET_CLK_BIT7,1,sizeof(DATA_SET_CLK_BIT7),File);
1803 	fwrite(&DATA_SET_BIT6,1,sizeof(DATA_SET_BIT6),File);
1804 	fwrite(&DATA_SET_BIT7,1,sizeof(DATA_SET_BIT7),File);
1805 	fwrite(&DATA_FALLOFF_BIT6,1,sizeof(DATA_FALLOFF_BIT6),File);
1806 	fwrite(&DATA_FALLOFF_BIT7,1,sizeof(DATA_FALLOFF_BIT7),File);
1807 	return true;
1808 }
1809 
1810 bool MOS6510_PORT::LoadFreez(FILE* File,unsigned short Version)
1811 {
1812 	switch(Version)
1813 	{
1814 	case 0x0100:
1815 	case 0x0101:
1816 		fread(&DIR,1,sizeof(DIR),File);
1817 		fread(&DATA,1,sizeof(DATA),File);
1818 		fread(&DIR_READ,1,sizeof(DIR_READ),File);
1819 		fread(&DATA_READ,1,sizeof(DATA_READ),File);
1820 		fread(&DATA_OUT,1,sizeof(DATA_OUT),File);
1821 		fread(&DATA_SET_CLK_BIT6,1,sizeof(DATA_SET_CLK_BIT6),File);
1822 		fread(&DATA_SET_CLK_BIT7,1,sizeof(DATA_SET_CLK_BIT7),File);
1823 		fread(&DATA_SET_BIT6,1,sizeof(DATA_SET_BIT6),File);
1824 		fread(&DATA_SET_BIT7,1,sizeof(DATA_SET_BIT7),File);
1825 		fread(&DATA_FALLOFF_BIT6,1,sizeof(DATA_FALLOFF_BIT6),File);
1826 		fread(&DATA_FALLOFF_BIT7,1,sizeof(DATA_FALLOFF_BIT7),File);
1827 		break;
1828 	}
1829 	return true;
1830 }
1831 */
1832