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