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