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