· 7 years ago · Feb 20, 2019, 08:40 PM
1/*
2* Author: Raul-Andrei Ginj-Groszhart (18007497)
3* Created: 05/02/2019
4* Revised: 20/02/2019 - added comments
5* Description: Program that emulates the Chimera-2016-I Processor
6* User advice: none
7*/
8
9#include "stdafx.h"
10#include <winsock2.h>
11
12#pragma comment(lib, "wsock32.lib")
13
14
15#define STUDENT_NUMBER "18007497"
16
17#define IP_ADDRESS_SERVER "127.0.0.1"
18
19#define PORT_SERVER 0x1984 // We define a port that we are going to use.
20#define PORT_CLIENT 0x1985 // We define a port that we are going to use.
21
22#define WORD unsigned short
23#define DWORD unsigned long
24#define BYTE unsigned char
25
26#define MAX_FILENAME_SIZE 500
27#define MAX_BUFFER_SIZE 500
28
29SOCKADDR_IN server_addr;
30SOCKADDR_IN client_addr;
31
32SOCKET sock; // This is our socket, it is the handle to the IO address to read/write packets
33
34WSADATA data;
35
36char InputBuffer [MAX_BUFFER_SIZE];
37
38char hex_file [MAX_BUFFER_SIZE];
39char trc_file [MAX_BUFFER_SIZE];
40
41//////////////////////////
42// Registers //
43//////////////////////////
44
45#define FLAG_Z 0x80
46#define FLAG_I 0x20
47#define FLAG_N 0x08
48#define FLAG_C 0x01
49#define REGISTER_M 5
50#define REGISTER_A 4
51#define REGISTER_H 3
52#define REGISTER_L 2
53#define REGISTER_C 1
54#define REGISTER_B 0
55#define REGISTER_X 0
56#define REGISTER_Y 1
57BYTE Index_Registers[2];
58
59BYTE Registers[6];
60BYTE Flags;
61WORD ProgramCounter;
62WORD StackPointer;
63
64
65////////////
66// Memory //
67////////////
68
69#define MEMORY_SIZE 65536
70
71BYTE Memory[MEMORY_SIZE];
72
73#define TEST_ADDRESS_1 0x01FA
74#define TEST_ADDRESS_2 0x01FB
75#define TEST_ADDRESS_3 0x01FC
76#define TEST_ADDRESS_4 0x01FD
77#define TEST_ADDRESS_5 0x01FE
78#define TEST_ADDRESS_6 0x01FF
79#define TEST_ADDRESS_7 0x0200
80#define TEST_ADDRESS_8 0x0201
81#define TEST_ADDRESS_9 0x0202
82#define TEST_ADDRESS_10 0x0203
83#define TEST_ADDRESS_11 0x0204
84#define TEST_ADDRESS_12 0x0205
85
86
87///////////////////////
88// Control variables //
89///////////////////////
90
91bool memory_in_range = true;
92bool halt = false;
93
94
95///////////////////////
96// Disassembly table //
97///////////////////////
98
99char opcode_mneumonics[][14] =
100{
101"ILLEGAL ",
102"ILLEGAL ",
103"SWI impl ",
104"RTI impl ",
105"STO abs ",
106"STOX abs ",
107"STOY abs ",
108"JMPR abs ",
109"CCC abs ",
110"CCS abs ",
111"CNE abs ",
112"CEQ abs ",
113"CMI abs ",
114"CPL abs ",
115"ILLEGAL ",
116"STOS abs ",
117
118"ILLEGAL ",
119"ILLEGAL ",
120"ILLEGAL ",
121"ILLEGAL ",
122"STO abs,X ",
123"STOX abs,X ",
124"STOY abs,X ",
125"NOP impl ",
126"WAI impl ",
127"ILLEGAL ",
128"ILLEGAL ",
129"ILLEGAL ",
130"ADI # ",
131"CPI # ",
132"ANI # ",
133"STOS abs,X ",
134
135"LODS # ",
136"LDX # ",
137"LODY # ",
138"RT impl ",
139"STO abs,Y ",
140"STOX abs,Y ",
141"STOY abs,Y ",
142"MVR #,B ",
143"MVR #,C ",
144"MVR #,L ",
145"MVR #,H ",
146"TAY impl ",
147"TYA impl ",
148"MSA impl ",
149"ILLEGAL ",
150"STOS abs,Y ",
151
152"LODS abs ",
153"LDX abs ",
154"LODY abs ",
155"ILLEGAL ",
156"STO abs,XY ",
157"STOX abs,XY ",
158"STOY abs,XY ",
159"ILLEGAL ",
160"JUMP abs ",
161"JCC abs ",
162"JCS abs ",
163"JNE abs ",
164"JEQ abs ",
165"JMI abs ",
166"JPL abs ",
167"STOS abs,XY ",
168
169"LODS abs,X ",
170"LDX abs,X ",
171"LODY abs,X ",
172"LD # ",
173"STO zpg ",
174"STOX zpg ",
175"STOY zpg ",
176"ILLEGAL ",
177"ILLEGAL ",
178"ILLEGAL ",
179"DEX impl ",
180"INX impl ",
181"DEY impl ",
182"INY impl ",
183"ILLEGAL ",
184"STOS zpg ",
185
186"LODS abs,Y ",
187"LDX abs,Y ",
188"LODY abs,Y ",
189"LD abs ",
190"TEST abs ",
191"INC abs ",
192"DEC abs ",
193"RR abs ",
194"RCL abs ",
195"SAL abs ",
196"SHR abs ",
197"COM abs ",
198"NEG abs ",
199"RAL abs ",
200"ROR abs ",
201"CLR abs ",
202
203"LODS abs,XY ",
204"LDX abs,XY ",
205"LODY abs,XY ",
206"LD abs,X ",
207"TEST abs,X ",
208"INC abs,X ",
209"DEC abs,X ",
210"RR abs,X ",
211"RCL abs,X ",
212"SAL abs,X ",
213"SHR abs,X ",
214"COM abs,X ",
215"NEG abs,X ",
216"RAL abs,X ",
217"ROR abs,X ",
218"CLR abs,X ",
219
220"LODS zpg ",
221"LDX zpg ",
222"LODY zpg ",
223"LD abs,Y ",
224"TEST abs,Y ",
225"INC abs,Y ",
226"DEC abs,Y ",
227"RR abs,Y ",
228"RCL abs,Y ",
229"SAL abs,Y ",
230"SHR abs,Y ",
231"COM abs,Y ",
232"NEG abs,Y ",
233"RAL abs,Y ",
234"ROR abs,Y ",
235"CLR abs,Y ",
236
237"ILLEGAL ",
238"ILLEGAL ",
239"ILLEGAL ",
240"LD abs,XY ",
241"TEST abs,XY ",
242"INC abs,XY ",
243"DEC abs,XY ",
244"RR abs,XY ",
245"RCL abs,XY ",
246"SAL abs,XY ",
247"SHR abs,XY ",
248"COM abs,XY ",
249"NEG abs,XY ",
250"RAL abs,XY ",
251"ROR abs,XY ",
252"CLR abs,XY ",
253
254"ILLEGAL ",
255"ILLEGAL ",
256"ILLEGAL ",
257"LD zpg ",
258"TESTA A,A ",
259"INCA A,A ",
260"DECA A,A ",
261"RRA A,A ",
262"RCLA A,A ",
263"SALA A,A ",
264"SHRA A,A ",
265"COMA A,A ",
266"NEGA A,0 ",
267"RALA A,A ",
268"RORA A,A ",
269"CLRA A,0 ",
270
271"MV A,A ",
272"MV B,A ",
273"MV C,A ",
274"MV L,A ",
275"MV H,A ",
276"MV M,A ",
277"CLC impl ",
278"SEC impl ",
279"CLI impl ",
280"SEI impl ",
281"CMC impl ",
282"ILLEGAL ",
283"ILLEGAL ",
284"ILLEGAL ",
285"PUSH ,A ",
286"POP A, ",
287
288"MV A,B ",
289"MV B,B ",
290"MV C,B ",
291"MV L,B ",
292"MV H,B ",
293"MV M,B ",
294"ADC A,B ",
295"SBC A,B ",
296"ADD A,B ",
297"SUB A,B ",
298"CMP A,B ",
299"OR A,B ",
300"AND A,B ",
301"XOR A,B ",
302"PUSH ,s ",
303"POP s, ",
304
305"MV A,C ",
306"MV B,C ",
307"MV C,C ",
308"MV L,C ",
309"MV H,C ",
310"MV M,C ",
311"ADC A,C ",
312"SBC A,C ",
313"ADD A,C ",
314"SUB A,C ",
315"CMP A,C ",
316"OR A,C ",
317"AND A,C ",
318"XOR A,C ",
319"PUSH ,B ",
320"POP B, ",
321
322"MV A,L ",
323"MV B,L ",
324"MV C,L ",
325"MV L,L ",
326"MV H,L ",
327"MV M,L ",
328"ADC A,L ",
329"SBC A,L ",
330"ADD A,L ",
331"SUB A,L ",
332"CMP A,L ",
333"OR A,L ",
334"AND A,L ",
335"XOR A,L ",
336"PUSH ,C ",
337"POP C, ",
338
339"MV A,H ",
340"MV B,H ",
341"MV C,H ",
342"MV L,H ",
343"MV H,H ",
344"MV M,H ",
345"ADC A,H ",
346"SBC A,H ",
347"ADD A,H ",
348"SUB A,H ",
349"CMP A,H ",
350"OR A,H ",
351"AND A,H ",
352"XOR A,H ",
353"PUSH ,L ",
354"POP L, ",
355
356"MV A,M ",
357"MV B,M ",
358"MV C,M ",
359"MV L,M ",
360"MV H,M ",
361"MV -,- ",
362"ADC A,M ",
363"SBC A,M ",
364"ADD A,M ",
365"SUB A,M ",
366"CMP A,M ",
367"OR A,M ",
368"AND A,M ",
369"XOR A,M ",
370"PUSH ,H ",
371"POP H, ",
372
373};
374
375////////////////////////////////////////////////////////////////////////////////
376// Simulator/Emulator (Start) //
377////////////////////////////////////////////////////////////////////////////////
378BYTE fetch()
379{
380 BYTE byte = 0;
381
382 if ((ProgramCounter >= 0) && (ProgramCounter <= MEMORY_SIZE))
383 {
384 memory_in_range = true;
385 byte = Memory[ProgramCounter];
386 ProgramCounter++;
387 }
388 else
389 {
390 memory_in_range = false;
391 }
392 return byte;
393}
394
395/*
396* Function: set_flag_n
397* Description: Set n flag depending on the value in a given register
398* Parameters inReg(BYTE) - the register that will be used to set the flags
399* Returns: none (void)
400* Warnings: none
401*/
402void set_flag_n(BYTE inReg) {
403 BYTE reg;
404 reg = inReg;
405
406 if ((reg & 0x80) != 0) // msbit set
407 {
408 Flags = Flags | FLAG_N;
409 }
410 else
411 {
412 Flags = Flags & (0xFF - FLAG_N);
413 }
414}
415
416/*
417* Function: set_flag_z
418* Description: Set z flag depending on the value in a given register
419* Parameters inReg(BYTE) - the register that will be used to set the flags
420* Returns: none (void)
421* Warnings: none
422*/
423void set_flag_z(BYTE inReg) {
424
425 BYTE reg;
426 reg = inReg;
427
428 if (reg == 0) // msbit set
429 {
430 Flags = Flags | FLAG_Z;
431 }
432 else
433 {
434 Flags = Flags & (0xFF - FLAG_Z);
435 }
436}
437
438void Group_1(BYTE opcode){
439 BYTE LB = 0;
440 BYTE HB = 0;
441 BYTE saved_flags = 0;
442 WORD address = 0;
443 WORD data = 0;
444 WORD temp_word = 0;
445 WORD param1 = 0;
446 WORD param2 = 0;
447
448 switch (opcode) {
449 case 0x43: //LD Immediate
450 data = fetch();
451 Registers[REGISTER_A] = data;
452 set_flag_n((BYTE)Registers[REGISTER_A]);
453 set_flag_z((BYTE)Registers[REGISTER_A]);
454 break;
455
456 case 0x53: //LD Absoulute
457 LB = fetch();
458 HB = fetch();
459 address += (WORD)((WORD)HB << 8) + LB;
460 if (address >= 0 && address <MEMORY_SIZE) {
461 Registers[REGISTER_A] = Memory[address];
462 }
463 set_flag_n((BYTE)Registers[REGISTER_A]);
464 set_flag_z((BYTE)Registers[REGISTER_A]);
465 break;
466
467 case 0x63://LD Absoulte X
468 address += Index_Registers[REGISTER_X];
469 LB = fetch();
470 HB = fetch();
471 address += (WORD)((WORD)HB << 8) + LB;
472 if (address >= 0 && address < MEMORY_SIZE) {
473 Registers[REGISTER_A] = Memory[address];
474 }
475 set_flag_n((BYTE)Registers[REGISTER_A]);
476 set_flag_z((BYTE)Registers[REGISTER_A]);
477 break;
478
479 case 0x73://LD Absoulte Y
480 address += Index_Registers[REGISTER_Y];
481 LB = fetch();
482 HB = fetch();
483 address += (WORD)((WORD)HB << 8) + LB;
484 if (address >= 0 && address < MEMORY_SIZE) {
485 Registers[REGISTER_A] = Memory[address];
486 }
487 set_flag_n((BYTE)Registers[REGISTER_A]);
488 set_flag_z((BYTE)Registers[REGISTER_A]);
489 break;
490
491 case 0x83://LD Absoulte XY
492 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
493 LB = fetch();
494 HB = fetch();
495 address += (WORD)((WORD)HB << 8) + LB;
496 if (address >= 0 && address < MEMORY_SIZE) {
497 Registers[REGISTER_A] = Memory[address];
498 }
499 set_flag_n((BYTE)Registers[REGISTER_A]);
500 set_flag_z((BYTE)Registers[REGISTER_A]);
501 break;
502
503 case 0x93://LD zpg
504 address += 0x0000 | (WORD)fetch();
505 if (address >= 0 && address < MEMORY_SIZE) {
506 Registers[REGISTER_A] = Memory[address];
507 }
508 set_flag_n((BYTE)Registers[REGISTER_A]);
509 set_flag_z((BYTE)Registers[REGISTER_A]);
510 break;
511
512 case 0x21://LDX Immediate
513 data = fetch();
514 Index_Registers[REGISTER_X] = data;
515 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
516 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
517 break;
518
519 case 0x31: //LDX Absoulute
520 LB = fetch();
521 HB = fetch();
522 address += (WORD)((WORD)HB << 8) + LB;
523 if (address >= 0 && address < MEMORY_SIZE) {
524 Index_Registers[REGISTER_X] = Memory[address];
525 }
526 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
527 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
528 break;
529
530 case 0x41://LDX Absoulte X
531 address += Index_Registers[REGISTER_X];
532 LB = fetch();
533 HB = fetch();
534 address += (WORD)((WORD)HB << 8) + LB;
535 if (address >= 0 && address < MEMORY_SIZE) {
536 Index_Registers[REGISTER_X] = Memory[address];
537 }
538 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
539 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
540 break;
541
542 case 0x51://LDX Absoulte Y
543 address += Index_Registers[REGISTER_Y];
544 LB = fetch();
545 HB = fetch();
546 address += (WORD)((WORD)HB << 8) + LB;
547 if (address >= 0 && address < MEMORY_SIZE) {
548 Index_Registers[REGISTER_X] = Memory[address];
549 }
550 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
551 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
552 break;
553
554 case 0x61://LDX Absoulte XY
555 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
556 LB = fetch();
557 HB = fetch();
558 address += (WORD)((WORD)HB << 8) + LB;
559 if (address >= 0 && address < MEMORY_SIZE) {
560 Index_Registers[REGISTER_X] = Memory[address];
561 }
562 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
563 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
564 break;
565
566 case 0x71://LDX zpg
567 address += 0x0000 | (WORD)fetch();
568 if (address >= 0 && address < MEMORY_SIZE) {
569 Index_Registers[REGISTER_X] = Memory[address];
570 }
571 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
572 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
573 break;
574
575 case 0x22://LODY Immediate
576 data = fetch();
577 Index_Registers[REGISTER_Y] = data;
578 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
579 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
580 break;
581
582 case 0x32: //LODY Absoulute
583 LB = fetch();
584 HB = fetch();
585 address += (WORD)((WORD)HB << 8) + LB;
586 if (address >= 0 && address < MEMORY_SIZE) {
587 Index_Registers[REGISTER_Y] = Memory[address];
588 }
589 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
590 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
591 break;
592
593 case 0x42://LODY Absoulte X
594 address += Index_Registers[REGISTER_X];
595 LB = fetch();
596 HB = fetch();
597 address += (WORD)((WORD)HB << 8) + LB;
598 if (address >= 0 && address < MEMORY_SIZE) {
599 Index_Registers[REGISTER_Y] = Memory[address];
600 }
601 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
602 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
603 break;
604
605 case 0x52://LODY Absoulte Y
606 address += Index_Registers[REGISTER_Y];
607 LB = fetch();
608 HB = fetch();
609 address += (WORD)((WORD)HB << 8) + LB;
610 if (address >= 0 && address < MEMORY_SIZE) {
611 Index_Registers[REGISTER_Y] = Memory[address];
612 }
613 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
614 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
615 break;
616
617 case 0x62://LODY Absoulte XY
618 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
619 LB = fetch();
620 HB = fetch();
621 address += (WORD)((WORD)HB << 8) + LB;
622 if (address >= 0 && address < MEMORY_SIZE) {
623 Index_Registers[REGISTER_Y] = Memory[address];
624 }
625 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
626 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
627 break;
628
629 case 0x72://LODY zpg
630 address += 0x0000 | (WORD)fetch();
631 if (address >= 0 && address < MEMORY_SIZE) {
632 Index_Registers[REGISTER_Y] = Memory[address];
633 }
634 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
635 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
636 break;
637
638 case 0x20://LODS Immediate
639 data = fetch();
640 StackPointer = data;
641 StackPointer += (WORD)fetch() << 8;
642 set_flag_n((BYTE)StackPointer);
643 set_flag_z((BYTE)StackPointer);
644 break;
645
646 case 0x30://LODS Absoulte
647 LB = fetch();
648 HB = fetch();
649 address += (WORD)((WORD)HB << 8) + LB;
650 if (address >= 0 && address < MEMORY_SIZE - 1) {
651 StackPointer = Memory[address];
652 StackPointer += (WORD)Memory[address + 1] << 8;
653 }
654 set_flag_n((BYTE)StackPointer);
655 set_flag_z((BYTE)StackPointer);
656 break;
657
658 case 0x40://LODS Absoulte X
659 address += Index_Registers[REGISTER_X];
660 LB = fetch();
661 HB = fetch();
662 address += (WORD)((WORD)HB << 8) + LB;
663 if (address >= 0 && address < MEMORY_SIZE - 1) {
664 StackPointer = Memory[address];
665 StackPointer += (WORD)Memory[address + 1] << 8;
666 }
667 set_flag_n((BYTE)StackPointer);
668 set_flag_z((BYTE)StackPointer);
669 break;
670
671 case 0x50://LODS Absoulte Y
672 address += Index_Registers[REGISTER_Y];
673 LB = fetch();
674 HB = fetch();
675 address += (WORD)((WORD)HB << 8) + LB;
676 if (address >= 0 && address < MEMORY_SIZE - 1) {
677 StackPointer = Memory[address];
678 StackPointer += (WORD)Memory[address + 1] << 8;
679 }
680 set_flag_n((BYTE)StackPointer);
681 set_flag_z((BYTE)StackPointer);
682 break;
683
684 case 0x60://LODS Absolute XY
685 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
686 LB = fetch();
687 HB = fetch();
688 address += (WORD)((WORD)HB << 8) + LB;
689 if (address >= 0 && address < MEMORY_SIZE - 1) {
690 StackPointer = Memory[address];
691 StackPointer += (WORD)Memory[address + 1] << 8;
692 }
693 set_flag_n((BYTE)StackPointer);
694 set_flag_z((BYTE)StackPointer);
695 break;
696
697 case 0x70://LODS zpg
698 address += 0x0000 | (WORD)fetch();
699 if (address >= 0 && address < MEMORY_SIZE - 1) {
700 StackPointer = Memory[address];
701 StackPointer += (WORD)Memory[address + 1] << 8;
702 }
703 set_flag_n((BYTE)StackPointer);
704 set_flag_z((BYTE)StackPointer);
705 break;
706
707 case 0x04://STO Absolute
708 LB = fetch();
709 HB = fetch();
710 address += (WORD)((WORD)HB << 8) + LB;
711 if (address >= 0 && address < MEMORY_SIZE) {
712 Memory[address] = Registers[REGISTER_A];
713 }
714 set_flag_n((BYTE)Memory[address]);
715 set_flag_z((BYTE)Memory[address]);
716 break;
717
718 case 0x14://STO Absolute X
719 address += Index_Registers[REGISTER_X];
720 LB = fetch();
721 HB = fetch();
722 address += (WORD)((WORD)HB << 8) + LB;
723 if (address >= 0 && address < MEMORY_SIZE) {
724 Memory[address] = Registers[REGISTER_A];
725 }
726 set_flag_n((BYTE)Memory[address]);
727 set_flag_z((BYTE)Memory[address]);
728 break;
729
730 case 0x24: //STO Absolute Y
731 address += Index_Registers[REGISTER_Y];
732 LB = fetch();
733 HB = fetch();
734 address += (WORD)((WORD)HB << 8) + LB;
735 if (address >= 0 && address < MEMORY_SIZE) {
736 Memory[address] = Registers[REGISTER_A];
737 }
738 set_flag_n((BYTE)Memory[address]);
739 set_flag_z((BYTE)Memory[address]);
740 break;
741
742 case 0x34://STO Absolute XY
743 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
744 LB = fetch();
745 HB = fetch();
746 address += (WORD)((WORD)HB << 8) + LB;
747 if (address >= 0 && address < MEMORY_SIZE) {
748 Memory[address] = Registers[REGISTER_A];
749 }
750 set_flag_n((BYTE)Memory[address]);
751 set_flag_z((BYTE)Memory[address]);
752 break;
753
754 case 0x44://STO zpg
755 address += 0x0000 | (WORD)fetch();
756 if (address >= 0 && address < MEMORY_SIZE) {
757 Memory[address] = Registers[REGISTER_A];
758 }
759 set_flag_n((BYTE)Memory[address]);
760 set_flag_z((BYTE)Memory[address]);
761 break;
762
763 case 0x0F://STOS Absoulte
764 LB = fetch();
765 HB = fetch();
766 address += (WORD)((WORD)HB << 8) + LB;
767 if (address >= 0 && address < MEMORY_SIZE - 1) {
768 HB = (BYTE)(StackPointer >> 8);
769 LB = (BYTE)StackPointer;
770 Memory[address] = LB;
771 Memory[address + 1] = HB;
772 }
773 set_flag_n((BYTE)StackPointer);
774 set_flag_z((BYTE)StackPointer);
775 break;
776
777 case 0x1F://STOS Absoulte X
778 address += Index_Registers[REGISTER_X];
779 LB = fetch();
780 HB = fetch();
781 address += (WORD)((WORD)HB << 8) + LB;
782 if (address >= 0 && address < MEMORY_SIZE - 1) {
783 HB = (BYTE)(StackPointer >> 8);
784 LB = (BYTE)StackPointer;
785 Memory[address] = LB;
786 Memory[address + 1] = HB;
787
788 }
789 set_flag_n((BYTE)StackPointer);
790 set_flag_z((BYTE)StackPointer);
791 break;
792
793 case 0x2F://STOS Absoulte Y
794 address += Index_Registers[REGISTER_Y];
795 LB = fetch();
796 HB = fetch();
797 address += (WORD)((WORD)HB << 8) + LB;
798 if (address >= 0 && address < MEMORY_SIZE - 1) {
799 HB = (BYTE)(StackPointer >> 8);
800 LB = (BYTE)StackPointer;
801 Memory[address] = LB;
802 Memory[address + 1] = HB;
803 }
804 set_flag_n((BYTE)StackPointer);
805 set_flag_z((BYTE)StackPointer);
806 break;
807
808 case 0x3F://STOS Absolute XY
809 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
810 LB = fetch();
811 HB = fetch();
812 address += (WORD)((WORD)HB << 8) + LB;
813 if (address >= 0 && address < MEMORY_SIZE - 1) {
814 HB = (BYTE)(StackPointer >> 8);
815 LB = (BYTE)StackPointer;
816 Memory[address] = LB;
817 Memory[address + 1] = HB;
818 }
819 set_flag_n((BYTE)StackPointer);
820 set_flag_z((BYTE)StackPointer);
821 break;
822
823 case 0x4F://STOS zpg
824 address += 0x0000 | (WORD)fetch();
825 if (address >= 0 && address < MEMORY_SIZE - 1) {
826 HB = (BYTE)(StackPointer >> 8);
827 LB = (BYTE)StackPointer;
828 Memory[address] = LB;
829 Memory[address + 1] = HB;
830 }
831 set_flag_n((BYTE)StackPointer);
832 set_flag_z((BYTE)StackPointer);
833 break;
834
835 case 0x05://STOX Absolute
836 LB = fetch();
837 HB = fetch();
838 address += (WORD)((WORD)HB << 8) + LB;
839 if (address >= 0 && address < MEMORY_SIZE) {
840 Memory[address] = Index_Registers[REGISTER_X];
841 }
842 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
843 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
844 break;
845
846 case 0x15://STOX Absolute X
847 address += Index_Registers[REGISTER_X];
848 LB = fetch();
849 HB = fetch();
850 address += (WORD)((WORD)HB << 8) + LB;
851 if (address >= 0 && address < MEMORY_SIZE) {
852 Memory[address] = Index_Registers[REGISTER_X];
853 }
854 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
855 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
856 break;
857
858 case 0x25: //STOX Absolute Y
859 address += Index_Registers[REGISTER_Y];
860 LB = fetch();
861 HB = fetch();
862 address += (WORD)((WORD)HB << 8) + LB;
863 if (address >= 0 && address < MEMORY_SIZE) {
864 Memory[address] = Index_Registers[REGISTER_X];
865 }
866 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
867 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
868 break;
869
870 case 0x35://STOX Absolute XY
871 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
872 LB = fetch();
873 HB = fetch();
874 address += (WORD)((WORD)HB << 8) + LB;
875 if (address >= 0 && address < MEMORY_SIZE) {
876 Memory[address] = Index_Registers[REGISTER_X];
877 }
878 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
879 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
880 break;
881
882 case 0x45://STOX zpg
883 address += 0x0000 | (WORD)fetch();
884 if (address >= 0 && address < MEMORY_SIZE) {
885 Memory[address] = Index_Registers[REGISTER_X];
886 }
887 set_flag_n((BYTE)Index_Registers[REGISTER_X]);
888 set_flag_z((BYTE)Index_Registers[REGISTER_X]);
889 break;
890
891 case 0x06://STOY Absolute
892 LB = fetch();
893 HB = fetch();
894 address += (WORD)((WORD)HB << 8) + LB;
895 if (address >= 0 && address < MEMORY_SIZE) {
896 Memory[address] = Index_Registers[REGISTER_Y];
897 }
898 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
899 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
900 break;
901
902 case 0x16://STOY Absolute X
903 address += Index_Registers[REGISTER_X];
904 LB = fetch();
905 HB = fetch();
906 address += (WORD)((WORD)HB << 8) + LB;
907 if (address >= 0 && address < MEMORY_SIZE) {
908 Memory[address] = Index_Registers[REGISTER_Y];
909 }
910 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
911 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
912 break;
913
914 case 0x26: //STOY Absolute Y
915 address += Index_Registers[REGISTER_Y];
916 LB = fetch();
917 HB = fetch();
918 address += (WORD)((WORD)HB << 8) + LB;
919 if (address >= 0 && address < MEMORY_SIZE) {
920 Memory[address] = Index_Registers[REGISTER_Y];
921 }
922 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
923 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
924 break;
925
926 case 0x36://STOY Absolute XY
927 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
928 LB = fetch();
929 HB = fetch();
930 address += (WORD)((WORD)HB << 8) + LB;
931 if (address >= 0 && address < MEMORY_SIZE) {
932 Memory[address] = Index_Registers[REGISTER_Y];
933 }
934 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
935 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
936 break;
937
938 case 0x46://STOY zpg
939 address += 0x0000 | (WORD)fetch();
940 if (address >= 0 && address < MEMORY_SIZE) {
941 Memory[address] = Index_Registers[REGISTER_Y];
942 }
943 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
944 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
945 break;
946
947 case 0x27://Register B MVR Intermediate
948 data = fetch();
949 Registers[REGISTER_B] = data;
950 set_flag_n((BYTE)Registers[REGISTER_B]);
951 set_flag_z((BYTE)Registers[REGISTER_B]);
952 break;
953
954 case 0x28://Register C MVR Intermediate
955 data = fetch();
956 Registers[REGISTER_C] = data;
957 set_flag_n((BYTE)Registers[REGISTER_C]);
958 set_flag_z((BYTE)Registers[REGISTER_C]);
959 break;
960
961 case 0x29://Register L MVR Intermediate
962 data = fetch();
963 Registers[REGISTER_L] = data;
964 set_flag_n((BYTE)Registers[REGISTER_L]);
965 set_flag_z((BYTE)Registers[REGISTER_L]);
966 break;
967
968 case 0x2A://Register H MVR Intermediate
969 data = fetch();
970 Registers[REGISTER_H] = data;
971 set_flag_n((BYTE)Registers[REGISTER_H]);
972 set_flag_z((BYTE)Registers[REGISTER_H]);
973 break;
974
975 case 0xB6://ADC A,B
976 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_B];
977 if ((Flags & FLAG_C) != 0)
978 {
979 temp_word++;
980 }
981 if (temp_word >= 0x100)
982 {
983 Flags = Flags | FLAG_C;
984 }
985 else
986 {
987 Flags = Flags & (0xFF - FLAG_C);
988 }
989 Registers[REGISTER_A] = (BYTE)temp_word;
990 set_flag_n((BYTE)temp_word);
991 set_flag_z((BYTE)temp_word);
992 break;
993
994 case 0xC6://ADC A,C
995 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_C];
996 if ((Flags & FLAG_C) != 0)
997 {
998 temp_word++;
999 }
1000 if (temp_word >= 0x100)
1001 {
1002 Flags = Flags | FLAG_C;
1003 }
1004 else
1005 {
1006 Flags = Flags & (0xFF - FLAG_C);
1007 }
1008 Registers[REGISTER_A] = (BYTE)temp_word;
1009 set_flag_n((BYTE)temp_word);
1010 set_flag_z((BYTE)temp_word);
1011 break;
1012
1013 case 0xD6://ADC A,L
1014 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_L];
1015 if ((Flags & FLAG_C) != 0)
1016 {
1017 temp_word++;
1018 }
1019 if (temp_word >= 0x100)
1020 {
1021 Flags = Flags | FLAG_C;
1022 }
1023 else
1024 {
1025 Flags = Flags & (0xFF - FLAG_C);
1026 }
1027 Registers[REGISTER_A] = (BYTE)temp_word;
1028 set_flag_n((BYTE)temp_word);
1029 set_flag_z((BYTE)temp_word);
1030 break;
1031
1032 case 0xE6://ADC A,H
1033 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_H];
1034 if ((Flags & FLAG_C) != 0)
1035 {
1036 temp_word++;
1037 }
1038 if (temp_word >= 0x100)
1039 {
1040 Flags = Flags | FLAG_C;
1041 }
1042 else
1043 {
1044 Flags = Flags & (0xFF - FLAG_C);
1045 }
1046 Registers[REGISTER_A] = (BYTE)temp_word;
1047 set_flag_n((BYTE)temp_word);
1048 set_flag_z((BYTE)temp_word);
1049 break;
1050
1051 case 0xF6://ADC A,M
1052 HB = Registers[REGISTER_H];
1053 LB = Registers[REGISTER_L];
1054 address = ((WORD)HB << 8) + LB;
1055 param1 = Registers[REGISTER_A];
1056 param2 = Memory[address];
1057 temp_word = (WORD)param1 + (WORD)param2;
1058 if ((Flags & FLAG_C) != 0)
1059 {
1060 temp_word++;
1061 }
1062 if (temp_word >= 0x100)
1063 {
1064 Flags = Flags | FLAG_C;
1065 }
1066 else
1067 {
1068 Flags = Flags & (0xFF - FLAG_C);
1069 }
1070 set_flag_n((BYTE)temp_word);
1071 set_flag_z((BYTE)temp_word);
1072 Registers[REGISTER_A] = (BYTE)temp_word;
1073 break;
1074
1075 case 0xB8://ADD A,B
1076 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_B];
1077 if (temp_word >= 0x100)
1078 {
1079 Flags = Flags | FLAG_C;
1080 }
1081 else
1082 {
1083 Flags = Flags & (0xFF - FLAG_C);
1084 }
1085 set_flag_n((BYTE)temp_word);
1086 set_flag_z((BYTE)temp_word);
1087 Registers[REGISTER_A] = (BYTE)temp_word;
1088 break;
1089
1090 case 0xC8://ADD A,C
1091 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_C];
1092 if (temp_word >= 0x100)
1093 {
1094 Flags = Flags | FLAG_C;
1095 }
1096 else
1097 {
1098 Flags = Flags & (0xFF - FLAG_C);
1099 }
1100 set_flag_n((BYTE)temp_word);
1101 set_flag_z((BYTE)temp_word);
1102 Registers[REGISTER_A] = (BYTE)temp_word;
1103 break;
1104
1105 case 0xD8://ADD A,L
1106 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_L];
1107 if (temp_word >= 0x100)
1108 {
1109 Flags = Flags | FLAG_C;
1110 }
1111 else
1112 {
1113 Flags = Flags & (0xFF - FLAG_C);
1114 }
1115 set_flag_n((BYTE)temp_word);
1116 set_flag_z((BYTE)temp_word);
1117 Registers[REGISTER_A] = (BYTE)temp_word;
1118 break;
1119
1120 case 0xE8://ADD A,H
1121 temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_H];
1122 if (temp_word >= 0x100)
1123 {
1124 Flags = Flags | FLAG_C;
1125 }
1126 else
1127 {
1128 Flags = Flags & (0xFF - FLAG_C);
1129 }
1130 set_flag_n((BYTE)temp_word);
1131 set_flag_z((BYTE)temp_word);
1132 Registers[REGISTER_A] = (BYTE)temp_word;
1133 break;
1134
1135 case 0xF8://ADD A,M
1136 HB = Registers[REGISTER_H];
1137 LB = Registers[REGISTER_L];
1138 address = ((WORD)HB << 8) + LB;
1139 param1 = Registers[REGISTER_A];
1140 param2 = Memory[address];
1141 temp_word = (WORD)param1 + (WORD)param2;
1142 if (temp_word >= 0x100)
1143 {
1144 Flags = Flags | FLAG_C;
1145 }
1146 else
1147 {
1148 Flags = Flags & (0xFF - FLAG_C);
1149 }
1150 set_flag_n((BYTE)temp_word);
1151 set_flag_z((BYTE)temp_word);
1152 Registers[REGISTER_A] = (BYTE)temp_word;
1153 break;
1154
1155 case 0xB7: //SBC A,B
1156 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
1157 if ((Flags & FLAG_C) != 0)
1158 {
1159 temp_word--;
1160 }
1161 if (temp_word >= 0x100)
1162 {
1163 Flags = Flags | FLAG_C;
1164 }
1165 else
1166 {
1167 Flags = Flags & (0xFF - FLAG_C);
1168 }
1169 set_flag_n((BYTE)temp_word);
1170 set_flag_z((BYTE)temp_word);
1171 Registers[REGISTER_A] = (BYTE)temp_word;
1172 break;
1173
1174 case 0xC7: //SBC A,C
1175 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
1176 if ((Flags & FLAG_C) != 0)
1177 {
1178 temp_word--;
1179 }
1180 if (temp_word >= 0x100)
1181 {
1182 Flags = Flags | FLAG_C;
1183 }
1184 else
1185 {
1186 Flags = Flags & (0xFF - FLAG_C);
1187 }
1188 set_flag_n((BYTE)temp_word);
1189 set_flag_z((BYTE)temp_word);
1190 Registers[REGISTER_A] = (BYTE)temp_word;
1191 break;
1192
1193 case 0xD7: //SBC A,L
1194 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
1195 if ((Flags & FLAG_C) != 0)
1196 {
1197 temp_word--;
1198 }
1199 if (temp_word >= 0x100)
1200 {
1201 Flags = Flags | FLAG_C;
1202 }
1203 else
1204 {
1205 Flags = Flags & (0xFF - FLAG_C);
1206 }
1207 set_flag_n((BYTE)temp_word);
1208 set_flag_z((BYTE)temp_word);
1209 Registers[REGISTER_A] = (BYTE)temp_word;
1210 break;
1211
1212 case 0xE7: //SBC A,H
1213 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
1214 if ((Flags & FLAG_C) != 0)
1215 {
1216 temp_word--;
1217 }
1218 if (temp_word >= 0x100)
1219 {
1220 Flags = Flags | FLAG_C;
1221 }
1222 else
1223 {
1224 Flags = Flags & (0xFF - FLAG_C);
1225 }
1226 set_flag_n((BYTE)temp_word);
1227 set_flag_z((BYTE)temp_word);
1228 Registers[REGISTER_A] = (BYTE)temp_word;
1229 break;
1230
1231 case 0xF7: //SBC A,M
1232 HB = Registers[REGISTER_H];
1233 LB = Registers[REGISTER_L];
1234 address = ((WORD)HB << 8) + LB;
1235 temp_word = (WORD)Registers[REGISTER_A] - Memory[address];
1236 if ((Flags & FLAG_C) != 0)
1237 {
1238 temp_word--;
1239 }
1240 if (temp_word >= 0x100)
1241 {
1242 Flags = Flags | FLAG_C; //Set carry flag
1243 }
1244 else
1245 {
1246 Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
1247 }
1248 set_flag_n((BYTE)temp_word);
1249 set_flag_z((BYTE)temp_word);
1250 Registers[REGISTER_A] = (BYTE)temp_word;
1251 break;
1252
1253 case 0xB9: //SUB A,B
1254 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
1255 if (temp_word >= 0x100)
1256 {
1257 Flags = Flags | FLAG_C;
1258 }
1259 else
1260 {
1261 Flags = Flags & (0xFF - FLAG_C);
1262 }
1263 set_flag_n((BYTE)temp_word);
1264 set_flag_z((BYTE)temp_word);
1265 Registers[REGISTER_A] = (BYTE)temp_word;
1266 break;
1267
1268 case 0xC9: //SUB A,C
1269 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
1270 if (temp_word >= 0x100)
1271 {
1272 Flags = Flags | FLAG_C;
1273 }
1274 else
1275 {
1276 Flags = Flags & (0xFF - FLAG_C);
1277 }
1278 set_flag_n((BYTE)temp_word);
1279 set_flag_z((BYTE)temp_word);
1280 Registers[REGISTER_A] = (BYTE)temp_word;
1281 break;
1282
1283 case 0xD9: //SUB A,L
1284 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
1285 if (temp_word >= 0x100)
1286 {
1287 Flags = Flags | FLAG_C;
1288 }
1289 else
1290 {
1291 Flags = Flags & (0xFF - FLAG_C);
1292 }
1293 set_flag_n((BYTE)temp_word);
1294 set_flag_z((BYTE)temp_word);
1295 Registers[REGISTER_A] = (BYTE)temp_word;
1296 break;
1297
1298 case 0xE9: //SUB A,H
1299 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
1300 if (temp_word >= 0x100)
1301 {
1302 Flags = Flags | FLAG_C;
1303 }
1304 else
1305 {
1306 Flags = Flags & (0xFF - FLAG_C);
1307 }
1308 set_flag_n((BYTE)temp_word);
1309 set_flag_z((BYTE)temp_word);
1310 Registers[REGISTER_A] = (BYTE)temp_word;
1311 break;
1312
1313 case 0xF9: //SUB A,M
1314 HB = Registers[REGISTER_H];
1315 LB = Registers[REGISTER_L];
1316 address = ((WORD)HB << 8) + LB;
1317 temp_word = (WORD)Registers[REGISTER_A] - Memory[address];
1318 if (temp_word >= 0x100)
1319 {
1320 Flags = Flags | FLAG_C; //Set carry flag
1321 }
1322 else
1323 {
1324 Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
1325 }
1326 set_flag_n((BYTE)temp_word);
1327 set_flag_z((BYTE)temp_word);
1328 Registers[REGISTER_A] = (BYTE)temp_word;
1329 break;
1330
1331 case 0xBA://CMP A,B
1332 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
1333 if (temp_word >= 0x100) {
1334 Flags = Flags | FLAG_C; // Set carry flag
1335 }
1336 else {
1337 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1338 }
1339 set_flag_n((BYTE)temp_word);
1340 set_flag_z((BYTE)temp_word);
1341 break;
1342
1343 case 0xCA://CMP A,C
1344 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
1345 if (temp_word >= 0x100) {
1346 Flags = Flags | FLAG_C; // Set carry flag
1347 }
1348 else {
1349 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1350 }
1351 set_flag_n((BYTE)temp_word);
1352 set_flag_z((BYTE)temp_word);
1353 break;
1354
1355 case 0xDA://CMP A,L
1356 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
1357 if (temp_word >= 0x100) {
1358 Flags = Flags | FLAG_C; // Set carry flag
1359 }
1360 else {
1361 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1362 }
1363 set_flag_n((BYTE)temp_word);
1364 set_flag_z((BYTE)temp_word);
1365 break;
1366
1367 case 0xEA://CMP A,H
1368 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
1369 if (temp_word >= 0x100)
1370 {
1371 Flags = Flags | FLAG_C; // Set carry flag
1372 }
1373 else
1374 {
1375 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1376 }
1377 set_flag_n((BYTE)temp_word);
1378 set_flag_z((BYTE)temp_word);
1379 break;
1380
1381 case 0xFA://CMP A,M
1382 temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_M];
1383 if (temp_word >= 0x100)
1384 {
1385 Flags = Flags | FLAG_C; // Set carry flag
1386 }
1387 else
1388 {
1389 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
1390 }
1391 set_flag_n((BYTE)temp_word);
1392 set_flag_z((BYTE)temp_word);
1393 break;
1394
1395 case 0x2D://MSA
1396 Registers[REGISTER_A] = Flags;
1397 break;
1398
1399 case 0x2B://TAY
1400 Index_Registers[REGISTER_Y] = Registers[REGISTER_A];
1401 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
1402 break;
1403
1404 case 0x2C://TYA
1405 Registers[REGISTER_A] = Index_Registers[REGISTER_Y];
1406 set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
1407 set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
1408 break;
1409
1410 case 0xA6://CLC
1411 Flags = Flags & (0xFF - FLAG_C);
1412 break;
1413
1414 case 0xA7://SEC
1415 Flags = Flags | FLAG_C;
1416 break;
1417
1418 case 0xA8://CLI
1419 Flags = Flags & (0xFF - FLAG_I);
1420 break;
1421
1422 case 0xA9://SEI
1423 Flags = Flags | FLAG_I;
1424 break;
1425
1426 case 0xAA://CMC
1427 Flags = Flags ^ FLAG_C;
1428 break;
1429
1430 case 0xAE://PUSH REGISTER A
1431 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1432 StackPointer--;
1433 Memory[StackPointer] = Registers[REGISTER_A];
1434 }
1435 break;
1436
1437 case 0xBE://PUSH FLAGS
1438 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1439 StackPointer--;
1440 Memory[StackPointer] = Flags;
1441 }
1442 break;
1443
1444 case 0xCE://PUSH REGISTER B
1445 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1446 StackPointer--;
1447 Memory[StackPointer] = Registers[REGISTER_B];
1448 }
1449 break;
1450
1451 case 0xDE://PUSH REGISTER C
1452 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1453 StackPointer--;
1454 Memory[StackPointer] = Registers[REGISTER_C];
1455 }
1456 break;
1457
1458 case 0xEE://PUSH REGISTER L
1459 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1460 StackPointer--;
1461 Memory[StackPointer] = Registers[REGISTER_L];
1462 }
1463 break;
1464
1465 case 0xFE://PUSH REGISTER H
1466 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1467 StackPointer--;
1468 Memory[StackPointer] = Registers[REGISTER_H];
1469 }
1470 break;
1471
1472 case 0xAF://POP REGISTER A
1473 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1474 Registers[REGISTER_A] = Memory[StackPointer];
1475 StackPointer++;
1476 }
1477 break;
1478
1479 case 0xBF://POP FLAGS
1480 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1481 Flags = Memory[StackPointer];
1482 StackPointer++;
1483 }
1484 break;
1485
1486 case 0xCF://POP REGISTER B
1487 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1488 Registers[REGISTER_B] = Memory[StackPointer];
1489 StackPointer++;
1490 }
1491 break;
1492
1493 case 0xDF://POP REGISTER C
1494 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1495 Registers[REGISTER_C] = Memory[StackPointer];
1496 StackPointer++;
1497 }
1498 break;
1499
1500 case 0xEF://POP REGISTER L
1501 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1502 Registers[REGISTER_L] = Memory[StackPointer];
1503 StackPointer++;
1504 }
1505 break;
1506
1507 case 0xFF://POP REGISTER M
1508 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
1509 Registers[REGISTER_H] = Memory[StackPointer];
1510 StackPointer++;
1511 }
1512 break;
1513
1514 case 0x38: //JUMP
1515 LB = fetch();
1516 HB = fetch();
1517 address = ((WORD)HB << 8) + (WORD)LB;
1518 ProgramCounter = address;
1519 break;
1520
1521 case 0x07://JMPR
1522 HB = fetch();
1523 LB = fetch();
1524 if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
1525 StackPointer--;
1526 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
1527 StackPointer--;
1528 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
1529
1530 }
1531 ProgramCounter = address;
1532 break;
1533
1534 case 0x23: //RT
1535 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 2)) {
1536 LB = Memory[StackPointer];
1537 StackPointer++;
1538 HB = Memory[StackPointer];
1539 StackPointer++;
1540 ProgramCounter = ((WORD)HB << 8) + (WORD)LB;
1541 }
1542 break;
1543
1544 case 0x39://JCC
1545 LB = fetch();
1546 HB = fetch();
1547 address = ((WORD)HB << 8) + (WORD)LB;
1548 if ((Flags & FLAG_C) == 0)
1549 {
1550 ProgramCounter = address;
1551 }
1552 break;
1553
1554 case 0x3A://JCS
1555 LB = fetch();
1556 HB = fetch();
1557 address = ((WORD)HB << 8) + (WORD)LB;
1558 if ((Flags & FLAG_C) == FLAG_C)
1559 {
1560 ProgramCounter = address;
1561 }
1562 break;
1563
1564 case 0x3B://JNE
1565 LB = fetch();
1566 HB = fetch();
1567 address = ((WORD)HB << 8) + (WORD)LB;
1568 if ((Flags & FLAG_Z) == 0)
1569 {
1570 ProgramCounter = address;
1571 }
1572 break;
1573
1574 case 0x3C://JEQ
1575 LB = fetch();
1576 HB = fetch();
1577 address = ((WORD)HB << 8) + (WORD)LB;
1578 if ((Flags & FLAG_Z) == FLAG_Z)
1579 {
1580 ProgramCounter = address;
1581 }
1582 break;
1583
1584 case 0x3D://JMI
1585 LB = fetch();
1586 HB = fetch();
1587 address = ((WORD)HB << 8) + (WORD)LB;
1588 if ((Flags & FLAG_N) == FLAG_N)
1589 {
1590 ProgramCounter = address;
1591 }
1592 break;
1593
1594 case 0x3E://JPL
1595 LB = fetch();
1596 HB = fetch();
1597 address = ((WORD)HB << 8) + (WORD)LB;
1598 if ((Flags & FLAG_N) == 0)
1599 {
1600 ProgramCounter = address;
1601 }
1602 break;
1603
1604 case 0x08: //CCC
1605 LB = fetch();
1606 HB = fetch();
1607 address = ((WORD)HB << 8) + (WORD)LB;
1608 if ((Flags & FLAG_C) == 0) {
1609 Memory[StackPointer] = ProgramCounter;
1610 StackPointer--;
1611 ProgramCounter = address;
1612 }
1613 break;
1614
1615 case 0x09: //CCS
1616 LB = fetch();
1617 HB = fetch();
1618 address = ((WORD)HB << 8) + (WORD)LB;
1619
1620 if ((Flags & FLAG_C) != 0) {
1621 Memory[StackPointer] = ProgramCounter;
1622 StackPointer--;
1623 ProgramCounter = address;
1624 }
1625 break;
1626
1627 case 0x0A: //CNE
1628 LB = fetch();
1629 HB = fetch();
1630 address = ((WORD)HB << 8) + (WORD)LB;
1631
1632 if ((Flags & FLAG_Z) == 0) {
1633 Memory[StackPointer] = ProgramCounter;
1634 StackPointer--;
1635 ProgramCounter = address;
1636 }
1637 break;
1638
1639 case 0x0B: //CEQ
1640 LB = fetch();
1641 HB = fetch();
1642 address = ((WORD)HB << 8) + (WORD)LB;
1643
1644 if ((Flags & FLAG_Z) != 0) {
1645 Memory[StackPointer] = ProgramCounter;
1646 StackPointer--;
1647 ProgramCounter = address;
1648 }
1649 break;
1650
1651 case 0x0C: //CMI
1652 LB = fetch();
1653 HB = fetch();
1654 address = ((WORD)HB << 8) + (WORD)LB;
1655
1656 if ((Flags & FLAG_N) != 0) {
1657 Memory[StackPointer] = ProgramCounter;
1658 StackPointer--;
1659 ProgramCounter = address;
1660 }
1661 break;
1662
1663 case 0x0D: //CPL
1664 LB = fetch();
1665 HB = fetch();
1666 address = ((WORD)HB << 8) + (WORD)LB;
1667
1668 if ((Flags & FLAG_N) == 0) {
1669 Memory[StackPointer] = ProgramCounter;
1670 StackPointer--;
1671 ProgramCounter = address;
1672 }
1673 break;
1674
1675 case 0x95: //INCA
1676 ++Registers[REGISTER_A];
1677 set_flag_n(Registers[REGISTER_A]);
1678 set_flag_z(Registers[REGISTER_A]);
1679 break;
1680
1681 case 0x96: //DECA
1682 Registers[REGISTER_A]--;
1683 set_flag_n(Registers[REGISTER_A]);
1684 set_flag_z(Registers[REGISTER_A]);
1685 break;
1686
1687 case 0x9F: //CLRA
1688 Registers[REGISTER_A] = 0;
1689 Flags = Flags | FLAG_Z;
1690 Flags = Flags & (0xFF - FLAG_N);
1691 Flags = Flags & (0xFF - FLAG_C);
1692 break;
1693
1694 case 0x55: // INC Absolute
1695 LB = fetch();
1696 HB = fetch();
1697 address += (WORD)((WORD)HB << 8) + LB;
1698 ++Memory[address];
1699 set_flag_n(Memory[address]);
1700 set_flag_z(Memory[address]);
1701 break;
1702
1703 case 0x65: // INC Absolute X
1704 address += Index_Registers[REGISTER_X];
1705 LB = fetch();
1706 HB = fetch();
1707 address += (WORD)((WORD)HB << 8) + LB;
1708 if (address >= 0 && address < MEMORY_SIZE)
1709 {
1710 ++Memory[address];
1711 }
1712 set_flag_n(Memory[address]);
1713 set_flag_z(Memory[address]);
1714 break;
1715
1716 case 0x75: // INC Absolute Y
1717 address += Index_Registers[REGISTER_Y];
1718 LB = fetch();
1719 HB = fetch();
1720 address += (WORD)((WORD)HB << 8) + LB;
1721 if (address >= 0 && address < MEMORY_SIZE)
1722 {
1723 ++Memory[address];
1724 }
1725 set_flag_n(Memory[address]);
1726 set_flag_z(Memory[address]);
1727 break;
1728
1729 case 0x85: // INC Absolute X,Y
1730 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1731 LB = fetch();
1732 HB = fetch();
1733 address += (WORD)((WORD)HB << 8) + LB;
1734 if (address >= 0 && address < MEMORY_SIZE)
1735 {
1736 ++Memory[address];
1737 }
1738 set_flag_n(Memory[address]);
1739 set_flag_z(Memory[address]);
1740 break;
1741
1742 case 0x5F: // CLR Absolute
1743 LB = fetch();
1744 HB = fetch();
1745 address += (WORD)((WORD)HB << 8) + LB;
1746 Memory[address] = 0;
1747 Flags = Flags | FLAG_Z;
1748 Flags = Flags & (0xFF - FLAG_N);
1749 Flags = Flags & (0xFF - FLAG_C);
1750 break;
1751
1752 case 0x6F: // CLR Absolute X
1753 address += Index_Registers[REGISTER_X];
1754 LB = fetch();
1755 HB = fetch();
1756 address += (WORD)((WORD)HB << 8) + LB;
1757 Memory[address] = 0;
1758 Flags = Flags | FLAG_Z;
1759 Flags = Flags & (0xFF - FLAG_N);
1760 Flags = Flags & (0xFF - FLAG_C);
1761 break;
1762
1763 case 0x7F: // CLR Absolute Y
1764 address += Index_Registers[REGISTER_Y];
1765 LB = fetch();
1766 HB = fetch();
1767 address += (WORD)((WORD)HB << 8) + LB;
1768 Memory[address] = 0;
1769 Flags = Flags | FLAG_Z;
1770 Flags = Flags & (0xFF - FLAG_N);
1771 Flags = Flags & (0xFF - FLAG_C);
1772 break;
1773
1774 case 0x8F: // CLR Absolute XY
1775 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1776 LB = fetch();
1777 HB = fetch();
1778 address += (WORD)((WORD)HB << 8) + LB;
1779 Memory[address] = 0;
1780 Flags = Flags | FLAG_Z;
1781 Flags = Flags & (0xFF - FLAG_N);
1782 Flags = Flags & (0xFF - FLAG_C);
1783 break;
1784
1785 case 0x4A: // DEX
1786 Index_Registers[REGISTER_X]--;
1787 set_flag_z(Index_Registers[REGISTER_X]);
1788 break;
1789
1790 case 0x4B: //INX
1791 ++Index_Registers[REGISTER_X];
1792 set_flag_z(Index_Registers[REGISTER_X]);
1793 break;
1794
1795 case 0x4C: //DEY
1796 Index_Registers[REGISTER_Y]--;
1797 set_flag_z(Index_Registers[REGISTER_Y]);
1798 break;
1799
1800 case 0x4D: //INY
1801 ++Index_Registers[REGISTER_Y];
1802 set_flag_z(Index_Registers[REGISTER_Y]);
1803 break;
1804
1805 case 0xBC: // AND Register A,B
1806 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_B];
1807 set_flag_n((BYTE)temp_word);
1808 set_flag_z((BYTE)temp_word);
1809 Registers[REGISTER_A] = (BYTE)temp_word;
1810 break;
1811
1812 case 0xCC: // AND Register A,C
1813 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_C];
1814 set_flag_n((BYTE)temp_word);
1815 set_flag_z((BYTE)temp_word);
1816 Registers[REGISTER_A] = (BYTE)temp_word;
1817 break;
1818
1819 case 0xDC: // AND Register A,L
1820 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_L];
1821 set_flag_n((BYTE)temp_word);
1822 set_flag_z((BYTE)temp_word);
1823 Registers[REGISTER_A] = (BYTE)temp_word;
1824 break;
1825
1826 case 0xEC: // AND Register A,H
1827 temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_H];
1828 set_flag_n((BYTE)temp_word);
1829 set_flag_z((BYTE)temp_word);
1830 Registers[REGISTER_A] = (BYTE)temp_word;
1831 break;
1832
1833 case 0xFC: // AND Register A,M
1834 HB = Registers[REGISTER_H];
1835 LB = Registers[REGISTER_L];
1836 address = ((WORD)HB << 8) + LB;
1837 param1 = Registers[REGISTER_A];
1838 param2 = Memory[address];
1839 temp_word = (WORD)param1 & (WORD)param2;
1840 set_flag_n((BYTE)temp_word);
1841 set_flag_z((BYTE)temp_word);
1842 Registers[REGISTER_A] = (BYTE)temp_word;
1843 break;
1844
1845 case 0xBB: //OR A,B
1846 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_B];
1847 set_flag_n((BYTE)temp_word);
1848 set_flag_z((BYTE)temp_word);
1849 Registers[REGISTER_A] = (BYTE)temp_word;
1850 break;
1851
1852 case 0xCB: //OR A,C
1853 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_C];
1854 set_flag_n((BYTE)temp_word);
1855 set_flag_z((BYTE)temp_word);
1856 Registers[REGISTER_A] = (BYTE)temp_word;
1857 break;
1858
1859 case 0xDB: //OR A,L
1860 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_L];
1861 set_flag_n((BYTE)temp_word);
1862 set_flag_z((BYTE)temp_word);
1863 Registers[REGISTER_A] = (BYTE)temp_word;
1864 break;
1865
1866 case 0xEB: //OR A,H
1867 temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_H];
1868 set_flag_n((BYTE)temp_word);
1869 set_flag_z((BYTE)temp_word);
1870 Registers[REGISTER_A] = (BYTE)temp_word;
1871 break;
1872
1873 case 0xFB: //OR A,M
1874 HB = Registers[REGISTER_H];
1875 LB = Registers[REGISTER_L];
1876 address = ((WORD)HB << 8) + LB;
1877 param1 = Registers[REGISTER_A];
1878 param2 = Memory[address];
1879 temp_word = (WORD)param1 | (WORD)param2;
1880 set_flag_n((BYTE)temp_word);
1881 set_flag_z((BYTE)temp_word);
1882 Registers[REGISTER_A] = (BYTE)temp_word;
1883 break;
1884
1885 case 0xBD: //XOR A,B
1886 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_B];
1887 set_flag_n((BYTE)temp_word);
1888 set_flag_z((BYTE)temp_word);
1889 Registers[REGISTER_A] = (BYTE)temp_word;
1890 break;
1891
1892 case 0xCD: //XOR A,C
1893 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_C];
1894 set_flag_n((BYTE)temp_word);
1895 set_flag_z((BYTE)temp_word);
1896 Registers[REGISTER_A] = (BYTE)temp_word;
1897 break;
1898
1899 case 0xDD: //XOR A,L
1900 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_L];
1901 set_flag_n((BYTE)temp_word);
1902 set_flag_z((BYTE)temp_word);
1903 Registers[REGISTER_A] = (BYTE)temp_word;
1904 break;
1905
1906 case 0xED: //XOR A,H
1907 temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_H];
1908 set_flag_n((BYTE)temp_word);
1909 set_flag_z((BYTE)temp_word);
1910 Registers[REGISTER_A] = (BYTE)temp_word;
1911 break;
1912
1913 case 0xFD: //XOR A,M
1914 HB = Registers[REGISTER_H];
1915 LB = Registers[REGISTER_L];
1916 address = ((WORD)HB << 8) + LB;
1917 param1 = Registers[REGISTER_A];
1918 param2 = Memory[address];
1919 temp_word = (WORD)param1 ^ (WORD)param2;
1920 set_flag_n((BYTE)temp_word);
1921 set_flag_z((BYTE)temp_word);
1922 Registers[REGISTER_A] = (BYTE)temp_word;
1923 break;
1924
1925 case 0x56: //DEC Absolute
1926 LB = fetch();
1927 HB = fetch();
1928 address += (WORD)((WORD)HB << 8) + LB;
1929 Memory[address]--;
1930 set_flag_n(Memory[address]);
1931 set_flag_z(Memory[address]);
1932 break;
1933
1934 case 0x66: //DEC Absolute X
1935 address += Index_Registers[REGISTER_X];
1936 LB = fetch();
1937 HB = fetch();
1938 address += (WORD)((WORD)HB << 8) + LB;
1939 if (address >= 0 && address < MEMORY_SIZE)
1940 {
1941 Memory[address]--;
1942 }
1943 set_flag_n(Memory[address]);
1944 set_flag_z(Memory[address]);
1945 break;
1946
1947 case 0x76: //DEC Absolute Y
1948 address += Index_Registers[REGISTER_Y];
1949 LB = fetch();
1950 HB = fetch();
1951 address += (WORD)((WORD)HB << 8) + LB;
1952 if (address >= 0 && address < MEMORY_SIZE)
1953 {
1954 Memory[address]--;
1955 }
1956 set_flag_n(Memory[address]);
1957 set_flag_z(Memory[address]);
1958 break;
1959
1960 case 0x86: //DEC Absolute X,Y
1961 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
1962 LB = fetch();
1963 HB = fetch();
1964 address += (WORD)((WORD)HB << 8) + LB;
1965 if (address >= 0 && address < MEMORY_SIZE)
1966 {
1967 Memory[address]--;
1968 }
1969 set_flag_n(Memory[address]);
1970 set_flag_z(Memory[address]);
1971 break;
1972
1973 case 0x59: //SAL Absolute
1974 LB = fetch();
1975 HB = fetch();
1976 address = (WORD)((WORD)HB << 8) + LB;
1977 saved_flags = Flags;
1978 if ((Memory[address] & 0x80) == 0x80)
1979 {
1980 Flags = Flags | FLAG_C;
1981 } else {
1982 Flags = Flags & (0xFF - FLAG_C);
1983 }
1984 Memory[address] = (Memory[address] << 1) & 0xFE;
1985 set_flag_n(Memory[address]);
1986 set_flag_z(Memory[address]);
1987 break;
1988
1989 case 0x69: //SAL Absolute X
1990 address += Index_Registers[REGISTER_X];
1991 LB = fetch();
1992 HB = fetch();
1993 address = (WORD)((WORD)HB << 8) + LB;
1994 saved_flags = Flags;
1995 if ((Memory[address] & 0x80) == 0x80)
1996 {
1997 Flags = Flags | FLAG_C;
1998 }
1999 else {
2000 Flags = Flags & (0xFF - FLAG_C);
2001 }
2002 Memory[address] = (Memory[address] << 1) & 0xFE;
2003 set_flag_n(Memory[address]);
2004 set_flag_z(Memory[address]);
2005 break;
2006
2007 case 0x79: //SAL Absolute Y
2008 address += Index_Registers[REGISTER_Y];
2009 LB = fetch();
2010 HB = fetch();
2011 address = (WORD)((WORD)HB << 8) + LB;
2012 saved_flags = Flags;
2013 if ((Memory[address] & 0x80) == 0x80)
2014 {
2015 Flags = Flags | FLAG_C;
2016 }
2017 else {
2018 Flags = Flags & (0xFF - FLAG_C);
2019 }
2020 Memory[address] = (Memory[address] << 1) & 0xFE;
2021 set_flag_n(Memory[address]);
2022 set_flag_z(Memory[address]);
2023 break;
2024
2025 case 0x89: //SAL Absolute X,Y
2026 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2027 LB = fetch();
2028 HB = fetch();
2029 address = (WORD)((WORD)HB << 8) + LB;
2030 saved_flags = Flags;
2031 if ((Memory[address] & 0x80) == 0x80)
2032 {
2033 Flags = Flags | FLAG_C;
2034 }
2035 else {
2036 Flags = Flags & (0xFF - FLAG_C);
2037 }
2038 Memory[address] = (Memory[address] << 1) & 0xFE;
2039 set_flag_n(Memory[address]);
2040 set_flag_z(Memory[address]);
2041 break;
2042
2043 case 0x5A: //SHR Absolute
2044 LB = fetch();
2045 HB = fetch();
2046 address = (WORD)((WORD)HB << 8) + LB;
2047 if ((Memory[address] & 0x01) == 0x01) {
2048 Flags = Flags | FLAG_C;
2049 } else {
2050 Flags = Flags & (0xFF - FLAG_C);
2051 }
2052 HB = Memory[address];
2053 Memory[address] = (Memory[address] >> 1) & 0x7F;
2054 if ((HB & 0x80) == 0x80) {
2055 Memory[address] = Memory[address] | 0x80;
2056 }
2057 set_flag_n(Memory[address]);
2058 set_flag_z(Memory[address]);
2059 break;
2060
2061 case 0x6A: //SHR Absolute X
2062 address += Index_Registers[REGISTER_X];
2063 LB = fetch();
2064 HB = fetch();
2065 address = (WORD)((WORD)HB << 8) + LB;
2066 if ((Memory[address] & 0x01) == 0x01) {
2067 Flags = Flags | FLAG_C;
2068 } else {
2069 Flags = Flags & (0xFF - FLAG_C);
2070 }
2071 HB = Memory[address];
2072 Memory[address] = (Memory[address] >> 1) & 0x7F;
2073 if ((HB & 0x80) == 0x80) {
2074 Memory[address] = Memory[address] | 0x80;
2075 }
2076 set_flag_n(Memory[address]);
2077 set_flag_z(Memory[address]);
2078 break;
2079
2080 case 0x7A: //SHR Absolute Y
2081 address += Index_Registers[REGISTER_Y];
2082 LB = fetch();
2083 HB = fetch();
2084 address = (WORD)((WORD)HB << 8) + LB;
2085 if ((Memory[address] & 0x01) == 0x01) {
2086 Flags = Flags | FLAG_C;
2087 } else {
2088 Flags = Flags & (0xFF - FLAG_C);
2089 }
2090 HB = Memory[address];
2091 Memory[address] = (Memory[address] >> 1) & 0x7F;
2092 if ((HB & 0x80) == 0x80) {
2093 Memory[address] = Memory[address] | 0x80;
2094 }
2095 set_flag_n(Memory[address]);
2096 set_flag_z(Memory[address]);
2097
2098 break;
2099
2100 case 0x8A: //SHR Absolute X,Y
2101 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2102 LB = fetch();
2103 HB = fetch();
2104 address = (WORD)((WORD)HB << 8) + LB;
2105 if ((Memory[address] & 0x01) == 0x01) {
2106 Flags = Flags | FLAG_C;
2107 } else {
2108 Flags = Flags & (0xFF - FLAG_C);
2109 }
2110 HB = Memory[address];
2111 Memory[address] = (Memory[address] >> 1) & 0x7F;
2112 if ((HB & 0x80) == 0x80) {
2113 Memory[address] = Memory[address] | 0x80;
2114 }
2115 set_flag_n(Memory[address]);
2116 set_flag_z(Memory[address]);
2117 break;
2118
2119 case 0x02: //SWI
2120 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2121 StackPointer--;
2122 Memory[StackPointer] = Registers[REGISTER_A];
2123 }
2124 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2125 StackPointer--;
2126 Memory[StackPointer] = (BYTE)ProgramCounter;
2127 }
2128 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2129 StackPointer--;
2130 Memory[StackPointer] = (BYTE)(ProgramCounter >> 8);
2131 }
2132 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2133 StackPointer--;
2134 Memory[StackPointer] = Flags;
2135 }
2136 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2137 StackPointer--;
2138 Memory[StackPointer] = Registers[REGISTER_B];
2139 }
2140 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2141 StackPointer--;
2142 Memory[StackPointer] = Registers[REGISTER_C];
2143 }
2144 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2145 StackPointer--;
2146 Memory[StackPointer] = Registers[REGISTER_L];
2147 }
2148 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
2149 StackPointer--;
2150 Memory[StackPointer] = Registers[REGISTER_H];
2151 }
2152 break;
2153
2154 case 0x03: //RTI
2155 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2156 Registers[REGISTER_H] = Memory[StackPointer];
2157 StackPointer++;
2158 }
2159 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2160 Registers[REGISTER_L] = Memory[StackPointer];
2161 StackPointer++;
2162 }
2163 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2164 Registers[REGISTER_C] = Memory[StackPointer];
2165 StackPointer++;
2166 }
2167 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2168 Registers[REGISTER_B] = Memory[StackPointer];
2169 StackPointer++;
2170 }
2171 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2172 Flags = Memory[StackPointer];
2173 StackPointer++;
2174 }
2175 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2176 ProgramCounter = (WORD)(Memory[StackPointer] << 8);
2177 StackPointer++;
2178 }
2179 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2180 ProgramCounter += Memory[StackPointer];
2181 StackPointer++;
2182 }
2183 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
2184 Registers[REGISTER_A] = Memory[StackPointer];
2185 StackPointer++;
2186 }
2187 break;
2188
2189 case 0x98: //RCLA
2190 saved_flags = Flags;
2191 if ((Registers[REGISTER_A] & 0x80) == 0x80) {
2192 Flags = Flags | FLAG_C;
2193 }
2194 else {
2195 Flags = Flags & (0xFF - FLAG_C);
2196 }
2197 Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
2198 if ((saved_flags & FLAG_C) == FLAG_C) {
2199 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
2200 }
2201 set_flag_n(Registers[REGISTER_A]);
2202 set_flag_z(Registers[REGISTER_A]);
2203 break;
2204
2205 case 0x1C: //ADI
2206 data = fetch();
2207 temp_word = (WORD)Registers[REGISTER_A] + data;
2208 if ((Flags & FLAG_C) != 0)
2209 {
2210 temp_word++;
2211 }
2212 if (temp_word >= 0x100)
2213 {
2214 Flags = Flags | FLAG_C;
2215 }
2216 else
2217 {
2218 Flags = Flags & (0xFF - FLAG_C);
2219 }
2220 set_flag_n((BYTE)temp_word);
2221 set_flag_z((BYTE)temp_word);
2222 Registers[REGISTER_A] = (BYTE)temp_word;
2223 break;
2224
2225 case 0x1D: //CPI
2226 data = fetch();
2227 temp_word = (WORD)data - (WORD)Registers[REGISTER_A];
2228 if (temp_word >= 0x100) {
2229 Flags = Flags | FLAG_C; // Set carry flag
2230 }
2231 else {
2232 Flags = Flags & (0xFF - FLAG_C); // Clear carry flag
2233 }
2234 set_flag_z((BYTE)temp_word);
2235 set_flag_n((BYTE)temp_word);
2236 break;
2237
2238 case 0x1E: //ANI
2239 data = fetch();
2240 temp_word = (WORD)Registers[REGISTER_A] & data;
2241 if (temp_word >= 0x100)
2242 {
2243 Flags = Flags | FLAG_C;
2244 }
2245 else
2246 {
2247 Flags = Flags & (0xFF - FLAG_C);
2248 }
2249 Registers[REGISTER_A] = (BYTE)temp_word;
2250 set_flag_n((BYTE)temp_word);
2251 set_flag_z((BYTE)temp_word);
2252 break;
2253
2254 case 0x54: //TEST Absolute
2255 LB = fetch();
2256 HB = fetch();
2257 address += (WORD)((WORD)HB << 8) + LB;
2258 data = Memory[address];
2259 set_flag_n(data);
2260 set_flag_z(data);
2261 break;
2262
2263 case 0x64: //TEST Absolute X
2264 address += Index_Registers[REGISTER_X];
2265 LB = fetch();
2266 HB = fetch();
2267 address += (WORD)((WORD)HB << 8) + LB;
2268 data = Memory[address];
2269 set_flag_n(data);
2270 set_flag_z(data);
2271 break;
2272
2273 case 0x74: //TEST Absolute Y
2274 address += Index_Registers[REGISTER_Y];
2275 LB = fetch();
2276 HB = fetch();
2277 address += (WORD)((WORD)HB << 8) + LB;
2278 data = Memory[address];
2279 set_flag_n(data);
2280 set_flag_z(data);
2281 break;
2282
2283 case 0x84: //TEST Absolute X,Y
2284 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2285 LB = fetch();
2286 HB = fetch();
2287 address += (WORD)((WORD)HB << 8) + LB;
2288 data = Memory[address];
2289 set_flag_n(data);
2290 set_flag_z(data);
2291 break;
2292
2293 case 0x94: //TESTA
2294 set_flag_n(Registers[REGISTER_A]);
2295 set_flag_z(Registers[REGISTER_A]);
2296 break;
2297
2298 case 0x57: //RR Absolute
2299 LB = fetch();
2300 HB = fetch();
2301 address += (WORD)((WORD)HB << 8) + LB;
2302 saved_flags = Flags;
2303
2304 if ((Memory[address] & 0x01) == 0x01) {
2305 Flags = Flags | FLAG_C;
2306 }
2307 else {
2308 Flags = Flags & (0xFF - FLAG_C);
2309 }
2310 Memory[address] = (Memory[address] >> 1) & 0x7F;
2311
2312 if ((saved_flags & FLAG_C) == FLAG_C) {
2313 Memory[address] = Memory[address] | 0x80;
2314 }
2315 set_flag_n((BYTE)Memory[address]);
2316 set_flag_z((BYTE)Memory[address]);
2317 break;
2318
2319 case 0x67: //RR Absolute X
2320 address += Index_Registers[REGISTER_X];
2321 LB = fetch();
2322 HB = fetch();
2323 address += (WORD)((WORD)HB << 8) + LB;
2324 saved_flags = Flags;
2325
2326 if ((Memory[address] & 0x01) == 0x01) {
2327 Flags = Flags | FLAG_C;
2328 }
2329 else {
2330 Flags = Flags & (0xFF - FLAG_C);
2331 }
2332 Memory[address] = (Memory[address] >> 1) & 0x7F;
2333
2334 if ((saved_flags & FLAG_C) == FLAG_C) {
2335 Memory[address] = Memory[address] | 0x80;
2336 }
2337 set_flag_n((BYTE)Memory[address]);
2338 set_flag_z((BYTE)Memory[address]);
2339 break;
2340
2341 case 0x77: //RR Absolute Y
2342 address += Index_Registers[REGISTER_Y];
2343 LB = fetch();
2344 HB = fetch();
2345 address += (WORD)((WORD)HB << 8) + LB;
2346 saved_flags = Flags;
2347
2348 if ((Memory[address] & 0x01) == 0x01) {
2349 Flags = Flags | FLAG_C;
2350 }
2351 else {
2352 Flags = Flags & (0xFF - FLAG_C);
2353 }
2354 Memory[address] = (Memory[address] >> 1) & 0x7F;
2355
2356 if ((saved_flags & FLAG_C) == FLAG_C) {
2357 Memory[address] = Memory[address] | 0x80;
2358 }
2359 set_flag_n((BYTE)Memory[address]);
2360 set_flag_z((BYTE)Memory[address]);
2361 break;
2362
2363 case 0x87: //RR Absolute X,Y
2364 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2365 LB = fetch();
2366 HB = fetch();
2367 address += (WORD)((WORD)HB << 8) + LB;
2368 saved_flags = Flags;
2369 if ((Memory[address] & 0x01) == 0x01) {
2370 Flags = Flags | FLAG_C;
2371 }
2372 else {
2373 Flags = Flags & (0xFF - FLAG_C);
2374 }
2375 Memory[address] = (Memory[address] >> 1) & 0x7F;
2376 if ((saved_flags & FLAG_C) == FLAG_C) {
2377 Memory[address] = Memory[address] | 0x80;
2378 }
2379 set_flag_n((BYTE)Memory[address]);
2380 set_flag_z((BYTE)Memory[address]);
2381 break;
2382
2383 case 0x97: //RRA
2384 saved_flags = Flags;
2385 if ((Registers[REGISTER_A] & 0x01) == 0x01) {
2386 Flags = Flags | FLAG_C;
2387 } else {
2388 Flags = Flags & (0xFF - FLAG_C);
2389 }
2390 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
2391 if ((saved_flags & FLAG_C) == FLAG_C) {
2392 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
2393 }
2394 set_flag_n((BYTE)Registers[REGISTER_A]);
2395 set_flag_z((BYTE)Registers[REGISTER_A]);
2396 break;
2397
2398 case 0x58: //RCL Absolute
2399 LB = fetch();
2400 HB = fetch();
2401 address += (WORD)((WORD)HB << 8) + LB;
2402 saved_flags = Flags;
2403 if ((Memory[address] & 0x80) == 0x80) {
2404 Flags = Flags | FLAG_C;
2405 } else {
2406 Flags = Flags & (0xFF - FLAG_C);
2407 }
2408 Memory[address] = (Memory[address] << 1) & 0xFE;
2409 if ((saved_flags & FLAG_C) == FLAG_C) {
2410 Memory[address] = Memory[address] | 0x01;
2411 }
2412 set_flag_n((BYTE)Memory[address]);
2413 set_flag_z((BYTE)Memory[address]);
2414 break;
2415
2416 case 0x68: //RCL Absolute X
2417 address += Index_Registers[REGISTER_X];
2418 LB = fetch();
2419 HB = fetch();
2420 address += (WORD)((WORD)HB << 8) + LB;
2421 saved_flags = Flags;
2422 if ((Memory[address] & 0x80) == 0x80) {
2423 Flags = Flags | FLAG_C;
2424 } else {
2425 Flags = Flags & (0xFF - FLAG_C);
2426 }
2427 Memory[address] = (Memory[address] << 1) & 0xFE;
2428 if ((saved_flags & FLAG_C) == FLAG_C) {
2429 Memory[address] = Memory[address] | 0x01;
2430 }
2431 set_flag_n((BYTE)Memory[address]);
2432 set_flag_z((BYTE)Memory[address]);
2433 break;
2434
2435 case 0x78: //RCL Absolute Y
2436 address += Index_Registers[REGISTER_Y];
2437 LB = fetch();
2438 HB = fetch();
2439 address += (WORD)((WORD)HB << 8) + LB;
2440 saved_flags = Flags;
2441 if ((Memory[address] & 0x80) == 0x80) {
2442 Flags = Flags | FLAG_C;
2443 } else {
2444 Flags = Flags & (0xFF - FLAG_C);
2445 }
2446 Memory[address] = (Memory[address] << 1) & 0xFE;
2447 if ((saved_flags & FLAG_C) == FLAG_C) {
2448 Memory[address] = Memory[address] | 0x01;
2449 }
2450 set_flag_n((BYTE)Memory[address]);
2451 set_flag_z((BYTE)Memory[address]);
2452 break;
2453
2454 case 0x88: //RCL Absolute X,Y
2455 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2456 LB = fetch();
2457 HB = fetch();
2458 address += (WORD)((WORD)HB << 8) + LB;
2459 saved_flags = Flags;
2460 if ((Memory[address] & 0x80) == 0x80) {
2461 Flags = Flags | FLAG_C;
2462 } else {
2463 Flags = Flags & (0xFF - FLAG_C);
2464 }
2465 Memory[address] = (Memory[address] << 1) & 0xFE;
2466 if ((saved_flags & FLAG_C) == FLAG_C) {
2467 Memory[address] = Memory[address] | 0x01;
2468 }
2469 set_flag_n((BYTE)Memory[address]);
2470 set_flag_z((BYTE)Memory[address]);
2471 break;
2472
2473 case 0x99: //SALA
2474 saved_flags = Flags;
2475 if ((Registers[REGISTER_A] & 0x80) == 0x80) {
2476 Flags = Flags | FLAG_C;
2477 }
2478 else {
2479 Flags = Flags & (0xFF - FLAG_C);
2480 }
2481 Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
2482 set_flag_n(Registers[REGISTER_A]);
2483 set_flag_z(Registers[REGISTER_A]);
2484 break;
2485
2486 case 0x9A: //SHRA
2487 if ((Registers[REGISTER_A] & 0x01) == 0x01) {
2488 Flags = Flags | FLAG_C;
2489 }
2490 else {
2491 Flags = Flags & (0xFF - FLAG_C);
2492 }
2493 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
2494 if ((Flags & FLAG_N) == FLAG_N) {
2495 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
2496 }
2497 set_flag_n(Registers[REGISTER_A]);
2498 set_flag_z(Registers[REGISTER_A]);
2499 break;
2500
2501 case 0x5B: //COM Absolute
2502 LB = fetch();
2503 HB = fetch();
2504 address += (WORD)((WORD)HB << 8) + LB;
2505 Memory[address] = Memory[address] ^ 0xFFFF;
2506 Flags = Flags | FLAG_C;
2507 set_flag_n(Memory[address]);
2508 set_flag_z(Memory[address]);
2509 break;
2510
2511 case 0x6B: //COM Absolute X
2512 address += Index_Registers[REGISTER_X];
2513 LB = fetch();
2514 HB = fetch();
2515 address += (WORD)((WORD)HB << 8) + LB;
2516 Memory[address] = Memory[address] ^ 0xFFFF;
2517 Flags = Flags | FLAG_C;
2518 set_flag_n(Memory[address]);
2519 set_flag_z(Memory[address]);
2520 break;
2521
2522 case 0x7B: //COM Absolute Y
2523 address += Index_Registers[REGISTER_Y];
2524 LB = fetch();
2525 HB = fetch();
2526 address += (WORD)((WORD)HB << 8) + LB;
2527 Memory[address] = Memory[address] ^ 0xFFFF;
2528 Flags = Flags | FLAG_C;
2529 set_flag_n(Memory[address]);
2530 set_flag_z(Memory[address]);
2531 break;
2532
2533 case 0x8B: //COM Absolute X,Y
2534 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2535 LB = fetch();
2536 HB = fetch();
2537 address += (WORD)((WORD)HB << 8) + LB;
2538 Memory[address] = Memory[address] ^ 0xFFFF;
2539 Flags = Flags | FLAG_C;
2540 set_flag_n(Memory[address]);
2541 set_flag_z(Memory[address]);
2542 break;
2543
2544 case 0x9B: //COMA
2545 temp_word = (WORD)Registers[REGISTER_A] ^ 0xFFFF;
2546 if (temp_word >= 0x100)
2547 {
2548 Flags = Flags | FLAG_C;
2549 }
2550 else
2551 {
2552 Flags = Flags & (0xFF - FLAG_C);
2553 }
2554 set_flag_n((BYTE)temp_word);
2555 set_flag_z((BYTE)temp_word);
2556 Registers[REGISTER_A] = (BYTE)temp_word;
2557 break;
2558
2559 case 0x5C: //NEG Absolute
2560 LB = fetch();
2561 HB = fetch();
2562 address += (WORD)((WORD)HB << 8) + LB;
2563 Memory[address] = 0 - Memory[address];
2564 set_flag_n(Memory[address]);
2565 set_flag_z(Memory[address]);
2566 break;
2567
2568 case 0x6C: //NEG Absolute X
2569 address += Index_Registers[REGISTER_X];
2570 LB = fetch();
2571 HB = fetch();
2572 address += (WORD)((WORD)HB << 8) + LB;
2573 Memory[address] = 0 - Memory[address];
2574 set_flag_n(Memory[address]);
2575 set_flag_z(Memory[address]);
2576 break;
2577
2578 case 0x7C: //NEG Absolute Y
2579 address += Index_Registers[REGISTER_Y];
2580 LB = fetch();
2581 HB = fetch();
2582 address += (WORD)((WORD)HB << 8) + LB;
2583 Memory[address] = 0 - Memory[address];
2584 set_flag_n(Memory[address]);
2585 set_flag_z(Memory[address]);
2586 break;
2587
2588 case 0x8C: //NEG Absolute X,Y
2589 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2590 LB = fetch();
2591 HB = fetch();
2592 address += (WORD)((WORD)HB << 8) + LB;
2593 Memory[address] = 0 - Memory[address];
2594 set_flag_n(Memory[address]);
2595 set_flag_z(Memory[address]);
2596 break;
2597
2598 case 0x9C: //NEGA
2599 Registers[REGISTER_A] = Registers[REGISTER_A] ^ 0xFF;
2600 Registers[REGISTER_A]++;
2601 set_flag_n(Registers[REGISTER_A]);
2602 set_flag_z(Registers[REGISTER_A]);
2603 break;
2604
2605 case 0x5D: //RAL Absolute
2606 LB = fetch();
2607 HB = fetch();
2608 address += (WORD)((WORD)HB << 8) + LB;
2609 saved_flags = Flags;
2610 if ((Memory[address] & 0x80) == 0x80) {
2611 Flags = Flags | FLAG_C;
2612 } else {
2613 Flags = Flags & (0xFF - FLAG_C);
2614 }
2615 Memory[address] = (Memory[address] << 1) & 0xFE;
2616 if ((Flags & FLAG_C) == FLAG_C) {
2617 Memory[address] = Memory[address] | 0x01;
2618 }
2619 Flags = saved_flags;
2620 set_flag_n((BYTE)Memory[address]);
2621 set_flag_z((BYTE)Memory[address]);
2622 break;
2623
2624 case 0x6D: //RAL Absolute X
2625 address += Index_Registers[REGISTER_X];
2626 LB = fetch();
2627 HB = fetch();
2628 address += (WORD)((WORD)HB << 8) + LB;
2629 saved_flags = Flags;
2630 if ((Memory[address] & 0x80) == 0x80) {
2631 Flags = Flags | FLAG_C;
2632 } else {
2633 Flags = Flags & (0xFF - FLAG_C);
2634 }
2635 Memory[address] = (Memory[address] << 1) & 0xFE;
2636 if ((Flags & FLAG_C) == FLAG_C) {
2637 Memory[address] = Memory[address] | 0x01;
2638 }
2639 Flags = saved_flags;
2640 set_flag_n((BYTE)Memory[address]);
2641 set_flag_z((BYTE)Memory[address]);
2642 break;
2643
2644 case 0x7D: //RAL Absolute Y
2645 address += Index_Registers[REGISTER_Y];
2646 LB = fetch();
2647 HB = fetch();
2648 address += (WORD)((WORD)HB << 8) + LB;
2649 saved_flags = Flags;
2650 if ((Memory[address] & 0x80) == 0x80) {
2651 Flags = Flags | FLAG_C;
2652 } else {
2653 Flags = Flags & (0xFF - FLAG_C);
2654 }
2655 Memory[address] = (Memory[address] << 1) & 0xFE;
2656 if ((Flags & FLAG_C) == FLAG_C) {
2657 Memory[address] = Memory[address] | 0x01;
2658 }
2659 Flags = saved_flags;
2660 set_flag_n((BYTE)Memory[address]);
2661 set_flag_z((BYTE)Memory[address]);
2662 break;
2663
2664 case 0x8D: //RAL Absolute X,Y
2665 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2666 LB = fetch();
2667 HB = fetch();
2668 address += (WORD)((WORD)HB << 8) + LB;
2669 saved_flags = Flags;
2670 if ((Memory[address] & 0x80) == 0x80) {
2671 Flags = Flags | FLAG_C;
2672 } else {
2673 Flags = Flags & (0xFF - FLAG_C);
2674 }
2675 Memory[address] = (Memory[address] << 1) & 0xFE;
2676 if ((Flags & FLAG_C) == FLAG_C) {
2677 Memory[address] = Memory[address] | 0x01;
2678 }
2679 Flags = saved_flags;
2680 set_flag_n((BYTE)Memory[address]);
2681 set_flag_z((BYTE)Memory[address]);
2682 break;
2683
2684 case 0x9D: //RALA
2685 saved_flags = Flags;
2686 if ((Registers[REGISTER_A] & 0x80) == 0x80) {
2687 Flags = Flags | FLAG_C;
2688 } else {
2689 Flags = Flags & (0xFF - FLAG_C);
2690 }
2691 Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
2692 if ((Flags & FLAG_C) == FLAG_C) {
2693 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
2694 }
2695 Flags = saved_flags;
2696 set_flag_n((BYTE)Registers[REGISTER_A]);
2697 set_flag_z((BYTE)Registers[REGISTER_A]);
2698 break;
2699
2700 case 0x5E: //ROR Absolute
2701 LB = fetch();
2702 HB = fetch();
2703 address += (WORD)((WORD)HB << 8) + LB;
2704 saved_flags = Flags;
2705 if ((Memory[address] & 0x01) == 0x01) {
2706 Flags = Flags | FLAG_C;
2707 } else {
2708 Flags = Flags & (0xFF - FLAG_C);
2709 }
2710 Memory[address] = (Memory[address] >> 1) & 0x7F;
2711 if ((Flags & FLAG_C) == FLAG_C) {
2712 Memory[address] = Memory[address] | 0x80;
2713 }
2714 Flags = saved_flags;
2715 set_flag_n((BYTE)Memory[address]);
2716 set_flag_z((BYTE)Memory[address]);
2717 break;
2718
2719 case 0x6E: //ROR Absolute X
2720 address += Index_Registers[REGISTER_X];
2721 LB = fetch();
2722 HB = fetch();
2723 address += (WORD)((WORD)HB << 8) + LB;
2724 saved_flags = Flags;
2725 if ((Memory[address] & 0x01) == 0x01) {
2726 Flags = Flags | FLAG_C;
2727 } else {
2728 Flags = Flags & (0xFF - FLAG_C);
2729 }
2730 Memory[address] = (Memory[address] >> 1) & 0x7F;
2731 if ((Flags & FLAG_C) == FLAG_C) {
2732 Memory[address] = Memory[address] | 0x80;
2733 }
2734 Flags = saved_flags;
2735 set_flag_n((BYTE)Memory[address]);
2736 set_flag_z((BYTE)Memory[address]);
2737 break;
2738
2739 case 0x7E: //ROR Absolute Y
2740 address += Index_Registers[REGISTER_Y];
2741 LB = fetch();
2742 HB = fetch();
2743 address += (WORD)((WORD)HB << 8) + LB;
2744 saved_flags = Flags;
2745 if ((Memory[address] & 0x01) == 0x01) {
2746 Flags = Flags | FLAG_C;
2747 } else {
2748 Flags = Flags & (0xFF - FLAG_C);
2749 }
2750 Memory[address] = (Memory[address] >> 1) & 0x7F;
2751
2752 if ((Flags & FLAG_C) == FLAG_C) {
2753 Memory[address] = Memory[address] | 0x80;
2754 }
2755 Flags = saved_flags;
2756 set_flag_n((BYTE)Memory[address]);
2757 set_flag_z((BYTE)Memory[address]);
2758 break;
2759
2760 case 0x8E: //ROR Absolute X,Y
2761 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
2762 LB = fetch();
2763 HB = fetch();
2764 address += (WORD)((WORD)HB << 8) + LB;
2765 saved_flags = Flags;
2766 if ((Memory[address] & 0x01) == 0x01) {
2767 Flags = Flags | FLAG_C;
2768 } else {
2769 Flags = Flags & (0xFF - FLAG_C);
2770 }
2771 Memory[address] = (Memory[address] >> 1) & 0x7F;
2772 if ((Flags & FLAG_C) == FLAG_C) {
2773 Memory[address] = Memory[address] | 0x80;
2774 }
2775 Flags = saved_flags;
2776 set_flag_n((BYTE)Memory[address]);
2777 set_flag_z((BYTE)Memory[address]);
2778 break;
2779
2780 case 0x9E: //RORA
2781 saved_flags = Flags;
2782 if ((Registers[REGISTER_A] & 0x01) == 0x01) {
2783 Flags = Flags | FLAG_C;
2784 } else {
2785 Flags = Flags & (0xFF - FLAG_C);
2786 }
2787 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
2788 if ((Flags & FLAG_C) == FLAG_C) {
2789 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
2790 }
2791 Flags = saved_flags;
2792 set_flag_n((BYTE)Registers[REGISTER_A]);
2793 set_flag_z((BYTE)Registers[REGISTER_A]);
2794 break;
2795
2796 //No Operation
2797 case 0x17: //NOP
2798 break;
2799
2800 case 0x18: //WAI
2801 halt = true;
2802 break;
2803 }
2804}
2805
2806void Group_2_Move(BYTE opcode)
2807{
2808 BYTE source = opcode >> 4;
2809 BYTE destination = opcode & 0x0F;
2810 int destReg;
2811 int sourceReg;
2812 WORD address = 0;
2813 switch (destination) {
2814 case 0x00:
2815 destReg = REGISTER_A;
2816 break;
2817
2818 case 0x01:
2819 destReg = REGISTER_B;
2820 break;
2821
2822 case 0x02:
2823 destReg = REGISTER_C;
2824 break;
2825
2826 case 0x03:
2827 destReg = REGISTER_L;
2828 break;
2829
2830 case 0x04:
2831 destReg = REGISTER_H;
2832 break;
2833
2834 case 0x05:
2835 destReg = REGISTER_M;
2836 break;
2837 }
2838
2839 switch (source) {
2840
2841 case 0x0A:
2842 sourceReg = REGISTER_A;
2843 break;
2844
2845 case 0x0B:
2846 sourceReg = REGISTER_B;
2847 break;
2848
2849 case 0x0C:
2850 sourceReg = REGISTER_C;
2851 break;
2852
2853 case 0x0D:
2854 sourceReg = REGISTER_L;
2855 break;
2856
2857 case 0x0E:
2858 sourceReg = REGISTER_H;
2859 break;
2860
2861 case 0x0F:
2862 sourceReg = REGISTER_M;
2863 break;
2864 }
2865
2866 if (sourceReg == REGISTER_M) {
2867
2868 address = Registers[REGISTER_L];
2869 address += (WORD)Registers[REGISTER_H] << 8;
2870
2871 if (address >= 0 && address <= MEMORY_SIZE) {
2872 Registers[REGISTER_M] = Memory[address];
2873 }
2874 }
2875
2876 if (destReg == REGISTER_M) {
2877 address = Registers[REGISTER_L];
2878 address += (WORD)Registers[REGISTER_H] << 8;
2879 if (address >= 0 && address <= MEMORY_SIZE) {
2880 Memory[address] = Registers[sourceReg];
2881 }
2882 } else {
2883 Registers[destReg] = Registers[sourceReg];
2884 }
2885}
2886
2887
2888
2889
2890
2891void execute(BYTE opcode)
2892
2893
2894{
2895
2896
2897 BYTE source = opcode >> 4;
2898
2899
2900 BYTE destination = opcode & 0x0F;
2901
2902
2903
2904
2905
2906 if (((source >= 0x0A) && (source <= 0x0F)) && ((destination >= 0x00) && (destination <= 0x05)))
2907
2908
2909 {
2910
2911
2912 Group_2_Move(opcode);
2913
2914
2915 }
2916
2917
2918 else
2919
2920
2921 {
2922
2923
2924 Group_1(opcode);
2925
2926
2927 }
2928
2929
2930}
2931
2932void emulate()
2933{
2934 BYTE opcode;
2935 int sanity;
2936
2937 ProgramCounter = 0;
2938 halt = false;
2939 memory_in_range = true;
2940 sanity = 0;
2941
2942 printf(" A B C L H X Y SP\n");
2943
2944 while ((!halt) && (memory_in_range)) {
2945 printf("%04X ", ProgramCounter); // Print current address
2946 opcode = fetch();
2947 execute(opcode);
2948
2949 printf("%s ", opcode_mneumonics[opcode]); // Print current opcode
2950
2951 printf("%02X ", Registers[REGISTER_A]);
2952 printf("%02X ", Registers[REGISTER_B]);
2953 printf("%02X ", Registers[REGISTER_C]);
2954 printf("%02X ", Registers[REGISTER_L]);
2955 printf("%02X ", Registers[REGISTER_H]);
2956 printf("%02X ", Index_Registers[REGISTER_X]);
2957 printf("%02X ", Index_Registers[REGISTER_Y]);
2958 printf("%04X ", StackPointer); // Print Stack Pointer
2959
2960 if ((Flags & FLAG_Z) == FLAG_Z)
2961 {
2962 printf("Z=1 ");
2963 }
2964 else
2965 {
2966 printf("Z=0 ");
2967 }
2968 if ((Flags & FLAG_I) == FLAG_I)
2969 {
2970 printf("I=1 ");
2971 }
2972 else
2973 {
2974 printf("I=0 ");
2975 }
2976 if ((Flags & FLAG_N) == FLAG_N)
2977 {
2978 printf("N=1 ");
2979 }
2980 else
2981 {
2982 printf("N=0 ");
2983 }
2984 if ((Flags & FLAG_C) == FLAG_C)
2985 {
2986 printf("C=1 ");
2987 }
2988 else
2989 {
2990 printf("C=0 ");
2991 }
2992
2993 printf("\n"); // New line
2994 sanity++;
2995 if (sanity > 200) halt = true;
2996
2997 }
2998
2999 printf("\n"); // New line
3000}
3001
3002
3003////////////////////////////////////////////////////////////////////////////////
3004// Simulator/Emulator (End) //
3005////////////////////////////////////////////////////////////////////////////////
3006
3007
3008void initialise_filenames() {
3009 int i;
3010
3011 for (i=0; i<MAX_FILENAME_SIZE; i++) {
3012 hex_file [i] = '\0';
3013 trc_file [i] = '\0';
3014 }
3015}
3016
3017
3018
3019
3020int find_dot_position(char *filename) {
3021 int dot_position;
3022 int i;
3023 char chr;
3024
3025 dot_position = 0;
3026 i = 0;
3027 chr = filename[i];
3028
3029 while (chr != '\0') {
3030 if (chr == '.') {
3031 dot_position = i;
3032 }
3033 i++;
3034 chr = filename[i];
3035 }
3036
3037 return (dot_position);
3038}
3039
3040
3041int find_end_position(char *filename) {
3042 int end_position;
3043 int i;
3044 char chr;
3045
3046 end_position = 0;
3047 i = 0;
3048 chr = filename[i];
3049
3050 while (chr != '\0') {
3051 end_position = i;
3052 i++;
3053 chr = filename[i];
3054 }
3055
3056 return (end_position);
3057}
3058
3059
3060bool file_exists(char *filename) {
3061 bool exists;
3062 FILE *ifp;
3063
3064 exists = false;
3065
3066 if ( ( ifp = fopen( filename, "r" ) ) != NULL ) {
3067 exists = true;
3068
3069 fclose(ifp);
3070 }
3071
3072 return (exists);
3073}
3074
3075
3076
3077void create_file(char *filename) {
3078 FILE *ofp;
3079
3080 if ( ( ofp = fopen( filename, "w" ) ) != NULL ) {
3081 fclose(ofp);
3082 }
3083}
3084
3085
3086
3087bool getline(FILE *fp, char *buffer) {
3088 bool rc;
3089 bool collect;
3090 char c;
3091 int i;
3092
3093 rc = false;
3094 collect = true;
3095
3096 i = 0;
3097 while (collect) {
3098 c = getc(fp);
3099
3100 switch (c) {
3101 case EOF:
3102 if (i > 0) {
3103 rc = true;
3104 }
3105 collect = false;
3106 break;
3107
3108 case '\n':
3109 if (i > 0) {
3110 rc = true;
3111 collect = false;
3112 buffer[i] = '\0';
3113 }
3114 break;
3115
3116 default:
3117 buffer[i] = c;
3118 i++;
3119 break;
3120 }
3121 }
3122
3123 return (rc);
3124}
3125
3126
3127
3128
3129
3130
3131void load_and_run(int args,_TCHAR** argv) {
3132 char chr;
3133 int ln;
3134 int dot_position;
3135 int end_position;
3136 long i;
3137 FILE *ifp;
3138 long address;
3139 long load_at;
3140 int code;
3141
3142 // Prompt for the .hex file
3143
3144 printf("\n");
3145 printf("Enter the hex filename (.hex): ");
3146
3147 if(args == 2){
3148 ln = 0;
3149 chr = argv[1][ln];
3150 while (chr != '\0')
3151 {
3152 if (ln < MAX_FILENAME_SIZE)
3153 {
3154 hex_file [ln] = chr;
3155 trc_file [ln] = chr;
3156 ln++;
3157 }
3158 chr = argv[1][ln];
3159 }
3160 } else {
3161 ln = 0;
3162 chr = '\0';
3163 while (chr != '\n') {
3164 chr = getchar();
3165
3166 switch(chr) {
3167 case '\n':
3168 break;
3169 default:
3170 if (ln < MAX_FILENAME_SIZE) {
3171 hex_file [ln] = chr;
3172 trc_file [ln] = chr;
3173 ln++;
3174 }
3175 break;
3176 }
3177 }
3178
3179 }
3180 // Tidy up the file names
3181
3182 dot_position = find_dot_position(hex_file);
3183 if (dot_position == 0) {
3184 end_position = find_end_position(hex_file);
3185
3186 hex_file[end_position + 1] = '.';
3187 hex_file[end_position + 2] = 'h';
3188 hex_file[end_position + 3] = 'e';
3189 hex_file[end_position + 4] = 'x';
3190 hex_file[end_position + 5] = '\0';
3191 } else {
3192 hex_file[dot_position + 0] = '.';
3193 hex_file[dot_position + 1] = 'h';
3194 hex_file[dot_position + 2] = 'e';
3195 hex_file[dot_position + 3] = 'x';
3196 hex_file[dot_position + 4] = '\0';
3197 }
3198
3199 dot_position = find_dot_position(trc_file);
3200 if (dot_position == 0) {
3201 end_position = find_end_position(trc_file);
3202
3203 trc_file[end_position + 1] = '.';
3204 trc_file[end_position + 2] = 't';
3205 trc_file[end_position + 3] = 'r';
3206 trc_file[end_position + 4] = 'c';
3207 trc_file[end_position + 5] = '\0';
3208 } else {
3209 trc_file[dot_position + 0] = '.';
3210 trc_file[dot_position + 1] = 't';
3211 trc_file[dot_position + 2] = 'r';
3212 trc_file[dot_position + 3] = 'c';
3213 trc_file[dot_position + 4] = '\0';
3214 }
3215
3216 if (file_exists(hex_file)) {
3217 // Clear Registers and Memory
3218
3219 Registers[REGISTER_A] = 0;
3220 Registers[REGISTER_B] = 0;
3221 Registers[REGISTER_C] = 0;
3222 Registers[REGISTER_L] = 0;
3223 Registers[REGISTER_H] = 0;
3224 Index_Registers[REGISTER_X] = 0;
3225 Index_Registers[REGISTER_Y] = 0;
3226 Flags = 0;
3227 ProgramCounter = 0;
3228 StackPointer = 0;
3229
3230 for (i=0; i<MEMORY_SIZE; i++) {
3231 Memory[i] = 0x00;
3232 }
3233
3234 // Load hex file
3235
3236 if ( ( ifp = fopen( hex_file, "r" ) ) != NULL ) {
3237 printf("Loading file...\n\n");
3238
3239 load_at = 0;
3240
3241 while (getline(ifp, InputBuffer)) {
3242 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
3243 load_at = address;
3244 } else if (sscanf(InputBuffer, "%x", &code) == 1) {
3245 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
3246 Memory[load_at] = (BYTE)code;
3247 }
3248 load_at++;
3249 } else {
3250 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
3251 }
3252 }
3253
3254 fclose(ifp);
3255 }
3256
3257 // Emulate
3258
3259 emulate();
3260 } else {
3261 printf("\n");
3262 printf("ERROR> Input file %s does not exist!\n", hex_file);
3263 printf("\n");
3264 }
3265}
3266
3267void building(int args,_TCHAR** argv){
3268 char buffer[1024];
3269 load_and_run(args,argv);
3270 sprintf(buffer, "0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X",
3271 Memory[TEST_ADDRESS_1],
3272 Memory[TEST_ADDRESS_2],
3273 Memory[TEST_ADDRESS_3],
3274 Memory[TEST_ADDRESS_4],
3275 Memory[TEST_ADDRESS_5],
3276 Memory[TEST_ADDRESS_6],
3277 Memory[TEST_ADDRESS_7],
3278 Memory[TEST_ADDRESS_8],
3279 Memory[TEST_ADDRESS_9],
3280 Memory[TEST_ADDRESS_10],
3281 Memory[TEST_ADDRESS_11],
3282 Memory[TEST_ADDRESS_12]
3283 );
3284 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
3285}
3286
3287
3288
3289void test_and_mark() {
3290 char buffer[1024];
3291 bool testing_complete;
3292 int len = sizeof(SOCKADDR);
3293 char chr;
3294 int i;
3295 int j;
3296 bool end_of_program;
3297 long address;
3298 long load_at;
3299 int code;
3300 int mark;
3301 int passed;
3302
3303 printf("\n");
3304 printf("Automatic Testing and Marking\n");
3305 printf("\n");
3306
3307 testing_complete = false;
3308
3309 sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
3310 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
3311
3312 while (!testing_complete) {
3313 memset(buffer, '\0', sizeof(buffer));
3314
3315 if (recvfrom(sock, buffer, sizeof(buffer)-1, 0, (SOCKADDR *)&client_addr, &len) != SOCKET_ERROR) {
3316 printf("Incoming Data: %s \n", buffer);
3317
3318 //if (strcmp(buffer, "Testing complete") == 1)
3319 if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
3320 testing_complete = true;
3321 printf("Current mark = %d\n", mark);
3322
3323 }else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
3324 //testing_complete = true;
3325 printf("Passed = %d\n", passed);
3326
3327 } else if (strcmp(buffer, "Error") == 0) {
3328 printf("ERROR> Testing abnormally terminated\n");
3329 testing_complete = true;
3330 } else {
3331 // Clear Registers and Memory
3332
3333 Registers[REGISTER_A] = 0;
3334 Registers[REGISTER_B] = 0;
3335 Registers[REGISTER_C] = 0;
3336 Registers[REGISTER_L] = 0;
3337 Registers[REGISTER_H] = 0;
3338 Index_Registers[REGISTER_X] = 0;
3339 Index_Registers[REGISTER_Y] = 0;
3340 Flags = 0;
3341 ProgramCounter = 0;
3342 StackPointer = 0;
3343 for (i=0; i<MEMORY_SIZE; i++) {
3344 Memory[i] = 0;
3345 }
3346
3347 // Load hex file
3348
3349 i = 0;
3350 j = 0;
3351 load_at = 0;
3352 end_of_program = false;
3353 FILE *ofp;
3354 fopen_s(&ofp ,"branch.txt", "a");
3355
3356 while (!end_of_program) {
3357 chr = buffer[i];
3358 switch (chr) {
3359 case '\0':
3360 end_of_program = true;
3361
3362 case ',':
3363 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
3364 load_at = address;
3365 } else if (sscanf(InputBuffer, "%x", &code) == 1) {
3366 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
3367 Memory[load_at] = (BYTE)code;
3368 fprintf(ofp, "%02X\n", (BYTE)code);
3369 }
3370 load_at++;
3371 } else {
3372 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
3373 }
3374 j = 0;
3375 break;
3376
3377 default:
3378 InputBuffer[j] = chr;
3379 j++;
3380 break;
3381 }
3382 i++;
3383 }
3384 fclose(ofp);
3385 // Emulate
3386
3387 if (load_at > 1) {
3388 emulate();
3389 // Send and store results
3390 sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
3391 Memory[TEST_ADDRESS_1],
3392 Memory[TEST_ADDRESS_2],
3393 Memory[TEST_ADDRESS_3],
3394 Memory[TEST_ADDRESS_4],
3395 Memory[TEST_ADDRESS_5],
3396 Memory[TEST_ADDRESS_6],
3397 Memory[TEST_ADDRESS_7],
3398 Memory[TEST_ADDRESS_8],
3399 Memory[TEST_ADDRESS_9],
3400 Memory[TEST_ADDRESS_10],
3401 Memory[TEST_ADDRESS_11],
3402 Memory[TEST_ADDRESS_12]
3403 );
3404 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
3405 }
3406 }
3407 }
3408 }
3409}
3410
3411
3412
3413int _tmain(int argc, _TCHAR* argv[])
3414{
3415 char chr;
3416 char dummy;
3417
3418 printf("\n");
3419 printf("Microprocessor Emulator\n");
3420 printf("UWE Computer and Network Systems Assignment 1\n");
3421 printf("\n");
3422
3423 initialise_filenames();
3424
3425 if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return(0);
3426
3427 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
3428 if (!sock) {
3429 // Creation failed!
3430 }
3431
3432 memset(&server_addr, 0, sizeof(SOCKADDR_IN));
3433 server_addr.sin_family = AF_INET;
3434 server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
3435 server_addr.sin_port = htons(PORT_SERVER);
3436
3437 memset(&client_addr, 0, sizeof(SOCKADDR_IN));
3438 client_addr.sin_family = AF_INET;
3439 client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
3440 client_addr.sin_port = htons(PORT_CLIENT);
3441
3442 chr = '\0';
3443 while ((chr != 'e') && (chr != 'E'))
3444 {
3445 printf("\n");
3446 printf("Please select option\n");
3447 printf("L - Load and run a hex file\n");
3448 printf("T - Have the server test and mark your emulator\n");
3449 printf("E - Exit\n");
3450 if(argc == 2){ building(argc,argv); exit(0);}
3451 printf("Enter option: ");
3452 chr = getchar();
3453 if (chr != 0x0A)
3454 {
3455 dummy = getchar(); // read in the <CR>
3456 }
3457 printf("\n");
3458
3459 switch (chr)
3460 {
3461 case 'L':
3462 case 'l':
3463 load_and_run(argc,argv);
3464 break;
3465
3466 case 'T':
3467 case 't':
3468 test_and_mark();
3469 break;
3470
3471 default:
3472 break;
3473 }
3474 }
3475
3476 closesocket(sock);
3477 WSACleanup();
3478
3479
3480 return 0;
3481}