· 7 years ago · Feb 19, 2019, 02:12 PM
1#include "stdafx.h"
2#include <winsock2.h>
3
4#pragma comment(lib, "wsock32.lib")
5
6
7#define STUDENT_NUMBER "18018842"
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(); //COME BACK TO THIS
1418 if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 2)) {
1419 LB = Memory[StackPointer];
1420 StackPointer++;
1421 HB = Memory[StackPointer];
1422 StackPointer++;
1423 ProgramCounter = ((WORD)HB << 8) + (WORD)LB;
1424 }
1425 break;
1426
1427 case 0x39: // JCC Jump on carry clear
1428
1429 if (Flags = Flags & (0xFF - FLAG_C))
1430 {
1431 LB = fetch();
1432 HB = fetch();
1433 address = ((WORD)HB << 8) + (WORD)LB;
1434 ProgramCounter = address;
1435 }
1436 break;
1437 case 0x3A: // JCS Jump on carry set
1438
1439 if (Flags = Flags | FLAG_C)
1440 {
1441 LB = fetch();
1442 HB = fetch();
1443 address = ((WORD)HB << 8) + (WORD)LB;
1444 ProgramCounter = address;
1445
1446
1447 }
1448 break;
1449 case 0x3B: // JNE jump on carry not zero // Originally if ((Flags = Flags | FLAG_C) && (Flags != 0)).
1450 if ((Flags & FLAG_C) != 0)
1451 {
1452 LB = fetch();
1453 HB = fetch();
1454 address = ((WORD)HB << 8) + (WORD)LB;
1455 ProgramCounter = address;
1456 }
1457 break;
1458 case 0x3C: // JEQ jump on carry equal to 0
1459 if ((Flags & FLAG_C) == 0)
1460 {
1461 LB = fetch();
1462 HB = fetch();
1463 address = ((WORD)HB << 8) + (WORD)LB;
1464 ProgramCounter = address;
1465 }
1466 break;
1467 case 0x3D: // JMI
1468 if ((Flags & FLAG_C) == 10) {
1469 LB = fetch();
1470 HB = fetch();
1471 address = ((WORD)HB << 8) + (WORD)LB;
1472 ProgramCounter = address;
1473 }
1474 break;
1475 case 0x3E: // JPL
1476 if ((Flags & FLAG_C) == 00 || (Flags & FLAG_C) == 01) {
1477 LB = fetch();
1478 HB = fetch();
1479 address = ((WORD)HB << 8) + (WORD)LB;
1480 ProgramCounter = address;
1481 }
1482 break;
1483 /// pushes current instruction pointer on to the stack.
1484 /// jump
1485 case 0x08: // CCC call on carry clear
1486 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) { /// pushes current instruction pointer on to the stack.
1487 StackPointer--;
1488 Memory[StackPointer] = Registers[REGISTER_A];
1489 if (Flags = Flags & (0xFF - FLAG_C))
1490 {
1491 /// jump
1492 LB = fetch();
1493 HB = fetch();
1494 address = ((WORD)HB << 8) + (WORD)LB;
1495 ProgramCounter = address;
1496 }
1497 }
1498 break;
1499 case 0x0A: //CNE
1500 if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
1501 StackPointer--;
1502 Memory[StackPointer] = Registers[REGISTER_A];
1503 if ((Flags & FLAG_C) != 0) /// jne
1504 {
1505 LB = fetch();
1506 HB = fetch();
1507 address = ((WORD)HB << 8) + (WORD)LB;
1508 ProgramCounter = address;
1509 }
1510 }
1511 break;
1512 /// COME BACK TO WORK ON WEEK 3
1513 case 0x95: // INCA
1514 ++Registers[REGISTER_A];
1515 set_flag_n(Registers[REGISTER_A]);
1516 set_flag_z(Registers[REGISTER_A]);
1517 break;
1518 case 0x4B: // INX
1519 ++Index_Registers[REGISTER_X];
1520 set_flag_z(Registers[REGISTER_X]);
1521 break;
1522 //case 0xBC: // AND
1523 // copy for add op code
1524
1525
1526 case 0xBC:
1527 param1 = Registers[REGISTER_A];
1528 param2 = Registers[REGISTER_B];
1529 temp_word = (WORD)param1 & (WORD)param2;
1530
1531
1532
1533 // Clear carry flag
1534 Flags = Flags & (0xFF - FLAG_C);
1535
1536 set_flag_n((BYTE)temp_word);
1537 set_flag_z((BYTE)temp_word);
1538 Registers[REGISTER_A] = (BYTE)temp_word;
1539 break;
1540
1541 case 0xCC:
1542 param1 = Registers[REGISTER_A];
1543 param2 = Registers[REGISTER_C];
1544 temp_word = (WORD)param1 & (WORD)param2;
1545
1546
1547 // Clear carry flag
1548 Flags = Flags & (0xFF - FLAG_C);
1549
1550 set_flag_n((BYTE)temp_word);
1551 set_flag_z((BYTE)temp_word);
1552 Registers[REGISTER_A] = (BYTE)temp_word;
1553 break;
1554
1555 case 0xDC:
1556 param1 = Registers[REGISTER_A];
1557 param2 = Registers[REGISTER_L];
1558 temp_word = (WORD)param1 & (WORD)param2;
1559
1560
1561 // Clear carry flag
1562 Flags = Flags & (0xFF - FLAG_C);
1563
1564 set_flag_n((BYTE)temp_word);
1565 set_flag_z((BYTE)temp_word);
1566 Registers[REGISTER_A] = (BYTE)temp_word;
1567 break;
1568
1569 case 0xEC:
1570 param1 = Registers[REGISTER_A];
1571 param2 = Registers[REGISTER_H];
1572 temp_word = (WORD)param1 & (WORD)param2;
1573
1574
1575 // Clear carry flag
1576 Flags = Flags & (0xFF - FLAG_C);
1577
1578 set_flag_n((BYTE)temp_word);
1579 set_flag_z((BYTE)temp_word);
1580 Registers[REGISTER_A] = (BYTE)temp_word;
1581 break;
1582
1583 case 0xFC:
1584 param1 = Registers[REGISTER_A];
1585 param2 = Registers[REGISTER_M];
1586 temp_word = (WORD)param1 & (WORD)param2;
1587
1588
1589 // Clear carry flag
1590 Flags = Flags & (0xFF - FLAG_C);
1591
1592 set_flag_n((BYTE)temp_word);
1593 set_flag_z((BYTE)temp_word);
1594 Registers[REGISTER_A] = (BYTE)temp_word;
1595 break;
1596 case 0x9F: // CLRA
1597 Registers[REGISTER_A] = 0;
1598 Flags = Flags | FLAG_Z; // set carry flag
1599 Flags = Flags & (0xFF - FLAG_C); // clear carry flag
1600 Flags = Flags & (0xFF - FLAG_N);// clear carry flag
1601 break;
1602 case 0x55: // INC absolute
1603 LB = fetch();
1604 HB = fetch();
1605 address += (WORD)((WORD)HB << 8) + LB;
1606 if (address >= 0 && address < MEMORY_SIZE) {
1607 Registers[REGISTER_A] = ++Memory[address];
1608 }
1609
1610 set_flag_n(Registers[REGISTER_A]);
1611 set_flag_z(Registers[REGISTER_A]);
1612 break;
1613 case 0x65:
1614 address += Index_Registers[REGISTER_X];
1615 LB = fetch();
1616 HB = fetch();
1617 address += (WORD)((WORD)HB << 8) + LB;
1618
1619 if (address >= 0 && address < MEMORY_SIZE) {
1620 Registers[REGISTER_A] = ++Memory[address];
1621 }
1622 set_flag_n(Registers[REGISTER_A]);
1623 set_flag_z(Registers[REGISTER_A]);
1624 break;
1625
1626 case 0x75:
1627 address += Index_Registers[REGISTER_Y];
1628 LB = fetch();
1629 HB = fetch();
1630 address += (WORD)((WORD)HB << 8) + LB;
1631
1632 if (address >= 0 && address < MEMORY_SIZE) {
1633 Registers[REGISTER_A] = ++Memory[address];
1634 }
1635 set_flag_n(Registers[REGISTER_A]);
1636 set_flag_z(Registers[REGISTER_A]);
1637 break;
1638
1639 case 0x85:
1640 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8)
1641 + Index_Registers[REGISTER_X];
1642 LB = fetch();
1643 HB = fetch();
1644 address += (WORD)((WORD)HB << 8) + LB;
1645
1646 if (address >= 0 && address < MEMORY_SIZE) {
1647 Registers[REGISTER_A] = ++Memory[address];
1648 }
1649 set_flag_n(Registers[REGISTER_A]);
1650 set_flag_z(Registers[REGISTER_A]);
1651 break;
1652
1653
1654 case 0x4A: // DEX
1655 --Index_Registers[REGISTER_X];
1656 set_flag_z(Registers[REGISTER_X]);
1657 break;
1658
1659 case 0x4D: //INY
1660 ++Index_Registers[REGISTER_Y];
1661 set_flag_z(Registers[REGISTER_Y]);
1662 break;
1663 case 0x4C: // DEY
1664 --Index_Registers[REGISTER_Y];
1665 set_flag_z(Registers[REGISTER_Y]);
1666 break;
1667 case 0xB7: // SBC
1668 param1 = Registers[REGISTER_A];
1669 param2 = Registers[REGISTER_B];
1670 temp_word = (WORD)param1 - (WORD)param2;
1671
1672 if ((Flags & FLAG_C) != 0) {
1673 temp_word++;
1674 }
1675 if (temp_word >= 0x100) {
1676 // Set carry flag
1677 Flags = Flags | FLAG_C;
1678 }
1679 else {
1680 // Clear carry flag
1681 Flags = Flags & (0xFF - FLAG_C);
1682 }
1683 set_flag_n((BYTE)temp_word);
1684 set_flag_z((BYTE)temp_word);
1685 Registers[REGISTER_A] = (BYTE)temp_word;
1686 break;
1687
1688 case 0xC7:
1689 param1 = Registers[REGISTER_A];
1690 param2 = Registers[REGISTER_C];
1691 temp_word = (WORD)param1 - (WORD)param2;
1692
1693 if ((Flags & FLAG_C) != 0) {
1694 temp_word++;
1695 }
1696 if (temp_word >= 0x100) {
1697 // Set carry flag
1698 Flags = Flags | FLAG_C;
1699 }
1700 else {
1701 // Clear carry flag
1702 Flags = Flags & (0xFF - FLAG_C);
1703 }
1704 set_flag_n((BYTE)temp_word);
1705 set_flag_z((BYTE)temp_word);
1706 Registers[REGISTER_A] = (BYTE)temp_word;
1707 break;
1708
1709 case 0xD7:
1710 param1 = Registers[REGISTER_A];
1711 param2 = Registers[REGISTER_L];
1712 temp_word = (WORD)param1 - (WORD)param2;
1713
1714 if ((Flags & FLAG_C) != 0) {
1715 temp_word++;
1716 }
1717 if (temp_word >= 0x100) {
1718 // Set carry flag
1719 Flags = Flags | FLAG_C;
1720 }
1721 else {
1722 // Clear carry flag
1723 Flags = Flags & (0xFF - FLAG_C);
1724 }
1725 set_flag_n((BYTE)temp_word);
1726 set_flag_z((BYTE)temp_word);
1727 Registers[REGISTER_A] = (BYTE)temp_word;
1728 break;
1729
1730 case 0xE7:
1731 param1 = Registers[REGISTER_A];
1732 param2 = Registers[REGISTER_H];
1733 temp_word = (WORD)param1 - (WORD)param2;
1734
1735 if ((Flags & FLAG_C) != 0) {
1736 temp_word++;
1737 }
1738 if (temp_word >= 0x100) {
1739 // Set carry flag
1740 Flags = Flags | FLAG_C;
1741 }
1742 else {
1743 // Clear carry flag
1744 Flags = Flags & (0xFF - FLAG_C);
1745 }
1746 set_flag_n((BYTE)temp_word);
1747 set_flag_z((BYTE)temp_word);
1748 Registers[REGISTER_A] = (BYTE)temp_word;
1749 break;
1750
1751 case 0xF7:
1752 param1 = Registers[REGISTER_A];
1753 param2 = Registers[REGISTER_M];
1754 temp_word = (WORD)param1 - (WORD)param2;
1755
1756 if ((Flags & FLAG_C) != 0) {
1757 temp_word++;
1758 }
1759 if (temp_word >= 0x100) {
1760 // Set carry flag
1761 Flags = Flags | FLAG_C;
1762 }
1763 else {
1764 // Clear carry flag
1765 Flags = Flags & (0xFF - FLAG_C);
1766 }
1767 set_flag_n((BYTE)temp_word);
1768 set_flag_z((BYTE)temp_word);
1769 Registers[REGISTER_A] = (BYTE)temp_word;
1770 break;
1771 case 0xBB:
1772 param1 = Registers[REGISTER_A];
1773 param2 = Registers[REGISTER_B];
1774 temp_word = (WORD)param1 | (WORD)param2;
1775
1776
1777
1778 // Clear carry flag
1779 Flags = Flags & (0xFF - FLAG_C);
1780
1781 set_flag_n((BYTE)temp_word);
1782 set_flag_z((BYTE)temp_word);
1783 Registers[REGISTER_A] = (BYTE)temp_word;
1784 break;
1785
1786 case 0xCB:
1787 param1 = Registers[REGISTER_A];
1788 param2 = Registers[REGISTER_C];
1789 temp_word = (WORD)param1 | (WORD)param2;
1790
1791
1792 // Clear carry flag
1793 Flags = Flags & (0xFF - FLAG_C);
1794
1795 set_flag_n((BYTE)temp_word);
1796 set_flag_z((BYTE)temp_word);
1797 Registers[REGISTER_A] = (BYTE)temp_word;
1798 break;
1799
1800 case 0xDB:
1801 param1 = Registers[REGISTER_A];
1802 param2 = Registers[REGISTER_L];
1803 temp_word = (WORD)param1 | (WORD)param2;
1804
1805
1806 // Clear carry flag
1807 Flags = Flags & (0xFF - FLAG_C);
1808
1809 set_flag_n((BYTE)temp_word);
1810 set_flag_z((BYTE)temp_word);
1811 Registers[REGISTER_A] = (BYTE)temp_word;
1812 break;
1813
1814 case 0xEB:
1815 param1 = Registers[REGISTER_A];
1816 param2 = Registers[REGISTER_H];
1817 temp_word = (WORD)param1 | (WORD)param2;
1818
1819
1820 // Clear carry flag
1821 Flags = Flags & (0xFF - FLAG_C);
1822
1823 set_flag_n((BYTE)temp_word);
1824 set_flag_z((BYTE)temp_word);
1825 Registers[REGISTER_A] = (BYTE)temp_word;
1826 break;
1827
1828 case 0xFB:
1829 param1 = Registers[REGISTER_A];
1830 param2 = Registers[REGISTER_M];
1831 temp_word = (WORD)param1 | (WORD)param2;
1832
1833
1834 // Clear carry flag
1835 Flags = Flags & (0xFF - FLAG_C);
1836
1837 set_flag_n((BYTE)temp_word);
1838 set_flag_z((BYTE)temp_word);
1839 Registers[REGISTER_A] = (BYTE)temp_word;
1840 break;
1841 case 0x9B: // COMA
1842 // negate memory or accumulator ^
1843 Registers[REGISTER_A] ^ 0xFF;
1844
1845 Flags = Flags | FLAG_C;
1846 Flags = Flags & (0xFF - FLAG_C);
1847
1848 // Clear carry flag
1849 Flags = Flags & (0xFF - FLAG_C);
1850 set_flag_n((BYTE)temp_word);
1851 set_flag_z((BYTE)temp_word);
1852 break;
1853 // SUB
1854 case 0xB9:
1855 param1 = Registers[REGISTER_A];
1856 param2 = Registers[REGISTER_B];
1857 temp_word = (WORD)param1 - (WORD)param2;
1858
1859 if (temp_word >= 0x100) {
1860 // Set carry flag
1861 Flags = Flags | FLAG_C;
1862 }
1863 else {
1864 // Clear carry flag
1865 Flags = Flags & (0xFF - FLAG_C);
1866 }
1867 set_flag_n((BYTE)temp_word);
1868 set_flag_z((BYTE)temp_word);
1869 Registers[REGISTER_A] = (BYTE)temp_word;
1870 break;
1871
1872 case 0xC9:
1873 param1 = Registers[REGISTER_A];
1874 param2 = Registers[REGISTER_C];
1875 temp_word = (WORD)param1 - (WORD)param2;
1876
1877 if (temp_word >= 0x100) {
1878 // Set carry flag
1879 Flags = Flags | FLAG_C;
1880 }
1881 else {
1882 // Clear carry flag
1883 Flags = Flags & (0xFF - FLAG_C);
1884 }
1885 set_flag_n((BYTE)temp_word);
1886 set_flag_z((BYTE)temp_word);
1887 Registers[REGISTER_A] = (BYTE)temp_word;
1888 break;
1889
1890 case 0xD9:
1891 param1 = Registers[REGISTER_A];
1892 param2 = Registers[REGISTER_L];
1893 temp_word = (WORD)param1 - (WORD)param2;
1894
1895 if (temp_word >= 0x100) {
1896 // Set carry flag
1897 Flags = Flags | FLAG_C;
1898 }
1899 else {
1900 // Clear carry flag
1901 Flags = Flags & (0xFF - FLAG_C);
1902 }
1903 set_flag_n((BYTE)temp_word);
1904 set_flag_z((BYTE)temp_word);
1905 Registers[REGISTER_A] = (BYTE)temp_word;
1906 break;
1907
1908 case 0xE9:
1909 param1 = Registers[REGISTER_A];
1910 param2 = Registers[REGISTER_H];
1911 temp_word = (WORD)param1 - (WORD)param2;
1912
1913 if (temp_word >= 0x100) {
1914 // Set carry flag
1915 Flags = Flags | FLAG_C;
1916 }
1917 else {
1918 // Clear carry flag
1919 Flags = Flags & (0xFF - FLAG_C);
1920 }
1921 set_flag_n((BYTE)temp_word);
1922 set_flag_z((BYTE)temp_word);
1923 Registers[REGISTER_A] = (BYTE)temp_word;
1924 break;
1925
1926 case 0xF9:
1927 param1 = Registers[REGISTER_A];
1928 param2 = Registers[REGISTER_M];
1929 temp_word = (WORD)param1 - (WORD)param2;
1930
1931 if (temp_word >= 0x100) {
1932 // Set carry flag
1933 Flags = Flags | FLAG_C;
1934 }
1935 else {
1936 // Clear carry flag
1937 Flags = Flags & (0xFF - FLAG_C);
1938 }
1939 set_flag_n((BYTE)temp_word);
1940 set_flag_z((BYTE)temp_word);
1941 Registers[REGISTER_A] = (BYTE)temp_word;
1942 break;
1943 case 0xBD:
1944 param1 = Registers[REGISTER_A];
1945 param2 = Registers[REGISTER_B];
1946 temp_word = (WORD)param1 ^ (WORD)param2;
1947
1948 if (temp_word >= 0x100) {
1949 // Set carry flag
1950 Flags = Flags | FLAG_C;
1951 }
1952 else {
1953 // Clear carry flag
1954 Flags = Flags & (0xFF - FLAG_C);
1955 }
1956 set_flag_n((BYTE)temp_word);
1957 set_flag_z((BYTE)temp_word);
1958 Registers[REGISTER_A] = (BYTE)temp_word;
1959 break;
1960
1961 case 0xCD:
1962 param1 = Registers[REGISTER_A];
1963 param2 = Registers[REGISTER_C];
1964 temp_word = (WORD)param1 ^ (WORD)param2;
1965
1966 if (temp_word >= 0x100) {
1967 // Set carry flag
1968 Flags = Flags | FLAG_C;
1969 }
1970 else {
1971 // Clear carry flag
1972 Flags = Flags & (0xFF - FLAG_C);
1973 }
1974 set_flag_n((BYTE)temp_word);
1975 set_flag_z((BYTE)temp_word);
1976 Registers[REGISTER_A] = (BYTE)temp_word;
1977 break;
1978
1979 case 0xDD:
1980 param1 = Registers[REGISTER_A];
1981 param2 = Registers[REGISTER_L];
1982 temp_word = (WORD)param1 ^ (WORD)param2;
1983
1984 if (temp_word >= 0x100) {
1985 // Set carry flag
1986 Flags = Flags | FLAG_C;
1987 }
1988 else {
1989 // Clear carry flag
1990 Flags = Flags & (0xFF - FLAG_C);
1991 }
1992 set_flag_n((BYTE)temp_word);
1993 set_flag_z((BYTE)temp_word);
1994 Registers[REGISTER_A] = (BYTE)temp_word;
1995 break;
1996
1997 case 0xED:
1998 param1 = Registers[REGISTER_A];
1999 param2 = Registers[REGISTER_H];
2000 temp_word = (WORD)param1 ^ (WORD)param2;
2001
2002 if (temp_word >= 0x100) {
2003 // Set carry flag
2004 Flags = Flags | FLAG_C;
2005 }
2006 else {
2007 // Clear carry flag
2008 Flags = Flags & (0xFF - FLAG_C);
2009 }
2010 set_flag_n((BYTE)temp_word);
2011 set_flag_z((BYTE)temp_word);
2012 Registers[REGISTER_A] = (BYTE)temp_word;
2013 break;
2014
2015 case 0xFD:
2016 param1 = Registers[REGISTER_A];
2017 param2 = Registers[REGISTER_M];
2018 temp_word = (WORD)param1 ^ (WORD)param2;
2019
2020 if (temp_word >= 0x100) {
2021 // Set carry flag
2022 Flags = Flags | FLAG_C;
2023 }
2024 else {
2025 // Clear carry flag
2026 Flags = Flags & (0xFF - FLAG_C);
2027 }
2028 set_flag_n((BYTE)temp_word);
2029 set_flag_z((BYTE)temp_word);
2030 Registers[REGISTER_A] = (BYTE)temp_word;
2031 break;
2032 case 0x54: // TEST
2033 LB = fetch();
2034 HB = fetch();
2035 address += (WORD)((WORD)HB << 8) + LB;
2036 if (address >= 0 && address < MEMORY_SIZE) {
2037 Registers[REGISTER_A] = Memory[address];
2038 Registers[REGISTER_A] = (Registers[REGISTER_A] & ~0xF);
2039 }
2040 set_flag_n(Registers[REGISTER_A]);
2041 set_flag_z(Registers[REGISTER_A]);
2042 break;
2043 case 0x64:
2044 address += Index_Registers[REGISTER_X];
2045 LB = fetch();
2046 HB = fetch();
2047 address += (WORD)((WORD)HB << 8) + LB;
2048
2049 if (address >= 0 && address < MEMORY_SIZE) {
2050 Registers[REGISTER_A] = Memory[address];
2051 Registers[REGISTER_A] = (Registers[REGISTER_A] & ~0xF);
2052 }
2053 set_flag_n(Registers[REGISTER_A]);
2054 set_flag_z(Registers[REGISTER_A]);
2055 break;
2056
2057 case 0x74:
2058 address += Index_Registers[REGISTER_Y];
2059 LB = fetch();
2060 HB = fetch();
2061 address += (WORD)((WORD)HB << 8) + LB;
2062
2063 if (address >= 0 && address < MEMORY_SIZE) {
2064 Registers[REGISTER_A] = Memory[address];
2065 Registers[REGISTER_A] = (Registers[REGISTER_A] & ~0xF);
2066 }
2067 set_flag_n(Registers[REGISTER_A]);
2068 set_flag_z(Registers[REGISTER_A]);
2069 break;
2070
2071 case 0x84:
2072 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8)
2073 + Index_Registers[REGISTER_X];
2074 LB = fetch();
2075 HB = fetch();
2076 address += (WORD)((WORD)HB << 8) + LB;
2077
2078 if (address >= 0 && address < MEMORY_SIZE) {
2079 Registers[REGISTER_A] = Memory[address];
2080 Registers[REGISTER_A] = (Registers[REGISTER_A] & ~0xF);
2081 }
2082 set_flag_n(Registers[REGISTER_A]);
2083 set_flag_z(Registers[REGISTER_A]);
2084 break;
2085 case 0x56: // INC absolute
2086 LB = fetch();
2087 HB = fetch();
2088 address += (WORD)((WORD)HB << 8) + LB;
2089 if (address >= 0 && address < MEMORY_SIZE) {
2090 Registers[REGISTER_A] = --Memory[address];
2091 }
2092
2093 set_flag_n(Registers[REGISTER_A]);
2094 set_flag_z(Registers[REGISTER_A]);
2095 break;
2096 case 0x66:
2097 address += Index_Registers[REGISTER_X];
2098 LB = fetch();
2099 HB = fetch();
2100 address += (WORD)((WORD)HB << 8) + LB;
2101
2102 if (address >= 0 && address < MEMORY_SIZE) {
2103 Registers[REGISTER_A] = --Memory[address];
2104 }
2105 set_flag_n(Registers[REGISTER_A]);
2106 set_flag_z(Registers[REGISTER_A]);
2107 break;
2108
2109 case 0x76:
2110 address += Index_Registers[REGISTER_Y];
2111 LB = fetch();
2112 HB = fetch();
2113 address += (WORD)((WORD)HB << 8) + LB;
2114
2115 if (address >= 0 && address < MEMORY_SIZE) {
2116 Registers[REGISTER_A] = --Memory[address];
2117 }
2118 set_flag_n(Registers[REGISTER_A]);
2119 set_flag_z(Registers[REGISTER_A]);
2120 break;
2121
2122 case 0x86:
2123 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8)
2124 + Index_Registers[REGISTER_X];
2125 LB = fetch();
2126 HB = fetch();
2127 address += (WORD)((WORD)HB << 8) + LB;
2128
2129 if (address >= 0 && address < MEMORY_SIZE) {
2130 Registers[REGISTER_A] = --Memory[address];
2131
2132 }
2133 set_flag_n(Registers[REGISTER_A]);
2134 set_flag_z(Registers[REGISTER_A]);
2135 break;
2136 case 0x59: // SAL
2137 LB = fetch();
2138 HB = fetch();
2139 address += (WORD)((WORD)HB << 8) + LB;
2140 if (address >= 0 && address < MEMORY_SIZE) {
2141
2142 Registers[REGISTER_A] = Memory[address];
2143 Registers[REGISTER_A] = (Registers[REGISTER_A] << 8);
2144
2145
2146
2147 }
2148 Flags = Flags | FLAG_C; // set carry flag
2149 Flags = Flags & (0xFF - FLAG_C); // clear carry flag
2150
2151 set_flag_n(Registers[REGISTER_A]);
2152 set_flag_z(Registers[REGISTER_A]);
2153 break;
2154 case 0x69:
2155 address += Index_Registers[REGISTER_X];
2156 LB = fetch();
2157 HB = fetch();
2158 address += (WORD)((WORD)HB << 8) + LB;
2159
2160 if (address >= 0 && address < MEMORY_SIZE) {
2161
2162 Registers[REGISTER_A] = Memory[address];
2163 Registers[REGISTER_A] = (Registers[REGISTER_A] << 8);
2164
2165
2166 }
2167 Flags = Flags | FLAG_C; // set carry flag
2168 Flags = Flags & (0xFF - FLAG_C); // clear carry flag
2169
2170 set_flag_n(Registers[REGISTER_A]);
2171 set_flag_z(Registers[REGISTER_A]);
2172 break;
2173
2174 case 0x79:
2175 address += Index_Registers[REGISTER_Y];
2176 LB = fetch();
2177 HB = fetch();
2178 address += (WORD)((WORD)HB << 8) + LB;
2179
2180 if (address >= 0 && address < MEMORY_SIZE) {
2181
2182 Registers[REGISTER_A] = Memory[address];
2183 Registers[REGISTER_A] = (Registers[REGISTER_A] << 8);
2184
2185
2186 }
2187 Flags = Flags | FLAG_C; // set carry flag
2188 Flags = Flags & (0xFF - FLAG_C); // clear carry flag
2189
2190 set_flag_n(Registers[REGISTER_A]);
2191 set_flag_z(Registers[REGISTER_A]);
2192 break;
2193
2194 case 0x89:
2195 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8)
2196 + Index_Registers[REGISTER_X];
2197 LB = fetch();
2198 HB = fetch();
2199 address += (WORD)((WORD)HB << 8) + LB;
2200
2201 if (address >= 0 && address < MEMORY_SIZE) {
2202
2203 Registers[REGISTER_A] = Memory[address];
2204 Registers[REGISTER_A] = (Registers[REGISTER_A] << 8);
2205
2206
2207 }
2208 Flags = Flags | FLAG_C; // set carry flag
2209 Flags = Flags & (0xFF - FLAG_C); // clear carry flag
2210
2211 set_flag_n(Registers[REGISTER_A]);
2212 set_flag_z(Registers[REGISTER_A]);
2213 break;
2214 case 0x5A: // SAL
2215 LB = fetch();
2216 HB = fetch();
2217 address += (WORD)((WORD)HB << 8) + LB;
2218 if (address >= 0 && address < MEMORY_SIZE) {
2219
2220 Registers[REGISTER_A] = Memory[address];
2221 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 8);
2222
2223
2224 }
2225 Flags = Flags | FLAG_C; // set carry flag
2226 Flags = Flags & (0xFF - FLAG_C); // clear carry flag
2227
2228 set_flag_n(Registers[REGISTER_A]);
2229 set_flag_z(Registers[REGISTER_A]);
2230 break;
2231 case 0x6A:
2232 address += Index_Registers[REGISTER_X];
2233 LB = fetch();
2234 HB = fetch();
2235 address += (WORD)((WORD)HB << 8) + LB;
2236
2237 if (address >= 0 && address < MEMORY_SIZE) {
2238
2239 Registers[REGISTER_A] = Memory[address];
2240 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 8);
2241
2242
2243 }
2244 Flags = Flags | FLAG_C; // set carry flag
2245 Flags = Flags & (0xFF - FLAG_C); // clear carry flag
2246
2247 set_flag_n(Registers[REGISTER_A]);
2248 set_flag_z(Registers[REGISTER_A]);
2249 break;
2250
2251 case 0x7A:
2252 address += Index_Registers[REGISTER_Y];
2253 LB = fetch();
2254 HB = fetch();
2255 address += (WORD)((WORD)HB << 8) + LB;
2256
2257 if (address >= 0 && address < MEMORY_SIZE) {
2258
2259 Registers[REGISTER_A] = Memory[address];
2260 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 8);
2261
2262
2263 }
2264 Flags = Flags | FLAG_C; // set carry flag
2265 Flags = Flags & (0xFF - FLAG_C); // clear carry flag
2266
2267 set_flag_n(Registers[REGISTER_A]);
2268 set_flag_z(Registers[REGISTER_A]);
2269 break;
2270
2271 case 0x8A:
2272 address += (WORD)((WORD)Index_Registers[REGISTER_Y] << 8)
2273 + Index_Registers[REGISTER_X];
2274 LB = fetch();
2275 HB = fetch();
2276 address += (WORD)((WORD)HB << 8) + LB;
2277
2278 if (address >= 0 && address < MEMORY_SIZE) {
2279
2280 Registers[REGISTER_A] = Memory[address];
2281 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 8);
2282
2283
2284 }
2285 Flags = Flags | FLAG_C; // set carry flag
2286 Flags = Flags & (0xFF - FLAG_C); // clear carry flag
2287
2288 set_flag_n(Registers[REGISTER_A]);
2289 set_flag_z(Registers[REGISTER_A]);
2290 break;
2291 case 0x98: // RCLA
2292 data = Flags;
2293 if ((Registers[REGISTER_A] & 0x80) == 0x80) {
2294 Flags = Flags | FLAG_C;
2295 }
2296 else {
2297 Flags = Flags & (0xFF - FLAG_C);
2298 }
2299 Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
2300 if ((data & FLAG_C) == FLAG_C) {
2301 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
2302 }
2303 set_flag_n(Registers[REGISTER_A]);
2304 set_flag_z(Registers[REGISTER_A]);
2305 break;
2306
2307 case 0x99: // SALA
2308 data = Flags;
2309 if ((Registers[REGISTER_A] & 0x80) == 0x80) {
2310 Flags = Flags | FLAG_C;
2311 }
2312 else {
2313 Flags = Flags & (0xFF - FLAG_C);
2314 }
2315 Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
2316 if ((data & FLAG_C) == FLAG_C) {
2317 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
2318 }
2319 set_flag_n(Registers[REGISTER_A]);
2320 set_flag_z(Registers[REGISTER_A]);
2321 break;
2322
2323 case 0x9A: //SHRA
2324 data = Flags;
2325 if ((Registers[REGISTER_A] & 0x40) == 0x40) {
2326 Flags = Flags | FLAG_C;
2327 }
2328 else {
2329 Flags = Flags & (0xFF - FLAG_C);
2330 }
2331 Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7f;
2332 if ((Flags & FLAG_N) == FLAG_N) {
2333 Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
2334 }
2335 set_flag_n(Registers[REGISTER_A]);
2336 set_flag_z(Registers[REGISTER_A]);
2337 break;
2338
2339
2340
2341
2342
2343
2344 // week 6
2345
2346
2347
2348
2349
2350
2351 }
2352
2353
2354}
2355
2356
2357//-----------------------------------------------------------------------------
2358void Group_2_Move(BYTE opcode) {
2359
2360 BYTE source = opcode >> 4;
2361 BYTE destination = opcode & 0x0F;
2362 int destReg;
2363 int sourceReg;
2364 WORD address = 0;
2365
2366 switch (destination) {
2367
2368 case 0x00:
2369 destReg = REGISTER_A;
2370 break;
2371
2372 case 0x01:
2373 destReg = REGISTER_B;
2374 break;
2375
2376 case 0x02:
2377 destReg = REGISTER_C;
2378 break;
2379
2380 case 0x03:
2381 destReg = REGISTER_L;
2382 break;
2383
2384 case 0x04:
2385 destReg = REGISTER_H;
2386 break;
2387
2388 case 0x05:
2389 destReg = REGISTER_M;
2390 break;
2391
2392 }
2393
2394 switch (source) {
2395
2396 case 0x0A:
2397 sourceReg = REGISTER_A;
2398 break;
2399
2400 case 0x0B:
2401 sourceReg = REGISTER_B;
2402 break;
2403
2404 case 0x0C:
2405 sourceReg = REGISTER_C;
2406 break;
2407
2408 case 0x0D:
2409 sourceReg = REGISTER_L;
2410 break;
2411
2412 case 0x0E:
2413 sourceReg = REGISTER_H;
2414 break;
2415
2416 case 0x0F:
2417 sourceReg = REGISTER_M;
2418 break;
2419
2420 }
2421
2422 if (sourceReg == REGISTER_M) {
2423
2424 address = Registers[REGISTER_L];
2425 address += (WORD)Registers[REGISTER_H] << 8;
2426
2427 if (address >= 0 && address <= MEMORY_SIZE) {
2428
2429 Registers[REGISTER_M] = Memory[address];
2430
2431 }
2432
2433 }
2434
2435 if (destReg == REGISTER_M) {
2436
2437 address = Registers[REGISTER_L];
2438
2439 address += (WORD)Registers[REGISTER_H] << 8;
2440
2441 if (address >= 0 && address <= MEMORY_SIZE) {
2442
2443 Memory[address] = Registers[sourceReg];
2444
2445 }
2446
2447 }
2448
2449 else {
2450
2451 Registers[destReg] = Registers[sourceReg];
2452
2453 }
2454
2455}
2456
2457
2458
2459
2460
2461void execute(BYTE opcode) {
2462
2463 BYTE source = opcode >> 4;
2464
2465 BYTE destination = opcode & 0x0F;
2466
2467 if (((source >= 0x0A) && (source <= 0x0F)) && ((destination >= 0x00) && (destination <= 0x05))) {
2468
2469 Group_2_Move(opcode);
2470
2471 }
2472
2473 else {
2474
2475 Group_1(opcode);
2476 }
2477
2478}
2479
2480void emulate()
2481{
2482 BYTE opcode;
2483 int sanity;
2484
2485 ProgramCounter = 0;
2486 halt = false;
2487 memory_in_range = true;
2488 sanity = 0;
2489
2490 printf(" A B C L H X Y SP\n");
2491
2492 while ((!halt) && (memory_in_range)) {
2493
2494 sanity++;
2495 if (sanity > 200) halt = true;
2496
2497 printf("%04X ", ProgramCounter); // Print current address
2498 opcode = fetch();
2499 execute(opcode);
2500
2501 printf("%s ", opcode_mneumonics[opcode]); // Print current opcode
2502
2503 printf("%02X ", Registers[REGISTER_A]);
2504 printf("%02X ", Registers[REGISTER_B]);
2505 printf("%02X ", Registers[REGISTER_C]);
2506 printf("%02X ", Registers[REGISTER_L]);
2507 printf("%02X ", Registers[REGISTER_H]);
2508 printf("%02X ", Index_Registers[REGISTER_X]);
2509 printf("%02X ", Index_Registers[REGISTER_Y]);
2510 printf("%04X ", StackPointer); // Print Stack Pointer
2511
2512 if ((Flags & FLAG_Z) == FLAG_Z)
2513 {
2514 printf("Z=1 ");
2515 }
2516 else
2517 {
2518 printf("Z=0 ");
2519 }
2520 if ((Flags & FLAG_I) == FLAG_I)
2521 {
2522 printf("I=1 ");
2523 }
2524 else
2525 {
2526 printf("I=0 ");
2527 }
2528 if ((Flags & FLAG_N) == FLAG_N)
2529 {
2530 printf("N=1 ");
2531 }
2532 else
2533 {
2534 printf("N=0 ");
2535 }
2536 if ((Flags & FLAG_C) == FLAG_C)
2537 {
2538 printf("C=1 ");
2539 }
2540 else
2541 {
2542 printf("C=0 ");
2543 }
2544
2545 printf("\n"); // New line
2546 sanity++;
2547 }
2548
2549 printf("\n"); // New line
2550}
2551
2552
2553////////////////////////////////////////////////////////////////////////////////
2554// Simulator/Emulator (End) //
2555////////////////////////////////////////////////////////////////////////////////
2556
2557
2558void initialise_filenames() {
2559 int i;
2560
2561 for (i = 0; i < MAX_FILENAME_SIZE; i++) {
2562 hex_file[i] = '\0';
2563 trc_file[i] = '\0';
2564 }
2565}
2566
2567
2568
2569
2570int find_dot_position(char *filename) {
2571 int dot_position;
2572 int i;
2573 char chr;
2574
2575 dot_position = 0;
2576 i = 0;
2577 chr = filename[i];
2578
2579 while (chr != '\0') {
2580 if (chr == '.') {
2581 dot_position = i;
2582 }
2583 i++;
2584 chr = filename[i];
2585 }
2586
2587 return (dot_position);
2588}
2589
2590
2591int find_end_position(char *filename) {
2592 int end_position;
2593 int i;
2594 char chr;
2595
2596 end_position = 0;
2597 i = 0;
2598 chr = filename[i];
2599
2600 while (chr != '\0') {
2601 end_position = i;
2602 i++;
2603 chr = filename[i];
2604 }
2605
2606 return (end_position);
2607}
2608
2609
2610bool file_exists(char *filename) {
2611 bool exists;
2612 FILE *ifp;
2613
2614 exists = false;
2615
2616 if ((ifp = fopen(filename, "r")) != NULL) {
2617 exists = true;
2618
2619 fclose(ifp);
2620 }
2621
2622 return (exists);
2623}
2624
2625
2626
2627void create_file(char *filename) {
2628 FILE *ofp;
2629
2630 if ((ofp = fopen(filename, "w")) != NULL) {
2631 fclose(ofp);
2632 }
2633}
2634
2635
2636
2637bool getline(FILE *fp, char *buffer) {
2638 bool rc;
2639 bool collect;
2640 char c;
2641 int i;
2642
2643 rc = false;
2644 collect = true;
2645
2646 i = 0;
2647 while (collect) {
2648 c = getc(fp);
2649
2650 switch (c) {
2651 case EOF:
2652 if (i > 0) {
2653 rc = true;
2654 }
2655 collect = false;
2656 break;
2657
2658 case '\n':
2659 if (i > 0) {
2660 rc = true;
2661 collect = false;
2662 buffer[i] = '\0';
2663 }
2664 break;
2665
2666 default:
2667 buffer[i] = c;
2668 i++;
2669 break;
2670 }
2671 }
2672
2673 return (rc);
2674}
2675
2676
2677
2678
2679
2680
2681void load_and_run(int args, _TCHAR** argv) {
2682 char chr;
2683 int ln;
2684 int dot_position;
2685 int end_position;
2686 long i;
2687 FILE *ifp;
2688 long address;
2689 long load_at;
2690 int code;
2691
2692 // Prompt for the .hex file
2693
2694 printf("\n");
2695 printf("Enter the hex filename (.hex): ");
2696
2697 if (args == 2) {
2698 ln = 0;
2699 chr = argv[1][ln];
2700 while (chr != '\0')
2701 {
2702 if (ln < MAX_FILENAME_SIZE)
2703 {
2704 hex_file[ln] = chr;
2705 trc_file[ln] = chr;
2706 ln++;
2707 }
2708 chr = argv[1][ln];
2709 }
2710 }
2711 else {
2712 ln = 0;
2713 chr = '\0';
2714 while (chr != '\n') {
2715 chr = getchar();
2716
2717 switch (chr) {
2718 case '\n':
2719 break;
2720 default:
2721 if (ln < MAX_FILENAME_SIZE) {
2722 hex_file[ln] = chr;
2723 trc_file[ln] = chr;
2724 ln++;
2725 }
2726 break;
2727 }
2728 }
2729
2730 }
2731 // Tidy up the file names
2732
2733 dot_position = find_dot_position(hex_file);
2734 if (dot_position == 0) {
2735 end_position = find_end_position(hex_file);
2736
2737 hex_file[end_position + 1] = '.';
2738 hex_file[end_position + 2] = 'h';
2739 hex_file[end_position + 3] = 'e';
2740 hex_file[end_position + 4] = 'x';
2741 hex_file[end_position + 5] = '\0';
2742 }
2743 else {
2744 hex_file[dot_position + 0] = '.';
2745 hex_file[dot_position + 1] = 'h';
2746 hex_file[dot_position + 2] = 'e';
2747 hex_file[dot_position + 3] = 'x';
2748 hex_file[dot_position + 4] = '\0';
2749 }
2750
2751 dot_position = find_dot_position(trc_file);
2752 if (dot_position == 0) {
2753 end_position = find_end_position(trc_file);
2754
2755 trc_file[end_position + 1] = '.';
2756 trc_file[end_position + 2] = 't';
2757 trc_file[end_position + 3] = 'r';
2758 trc_file[end_position + 4] = 'c';
2759 trc_file[end_position + 5] = '\0';
2760 }
2761 else {
2762 trc_file[dot_position + 0] = '.';
2763 trc_file[dot_position + 1] = 't';
2764 trc_file[dot_position + 2] = 'r';
2765 trc_file[dot_position + 3] = 'c';
2766 trc_file[dot_position + 4] = '\0';
2767 }
2768
2769 if (file_exists(hex_file)) {
2770 // Clear Registers and Memory
2771
2772 Registers[REGISTER_A] = 0;
2773 Registers[REGISTER_B] = 0;
2774 Registers[REGISTER_C] = 0;
2775 Registers[REGISTER_L] = 0;
2776 Registers[REGISTER_H] = 0;
2777 Index_Registers[REGISTER_X] = 0;
2778 Index_Registers[REGISTER_Y] = 0;
2779 Flags = 0;
2780 ProgramCounter = 0;
2781 StackPointer = 0;
2782
2783 for (i = 0; i < MEMORY_SIZE; i++) {
2784 Memory[i] = 0x00;
2785 }
2786
2787 // Load hex file
2788
2789 if ((ifp = fopen(hex_file, "r")) != NULL) {
2790 printf("Loading file...\n\n");
2791
2792 load_at = 0;
2793
2794 while (getline(ifp, InputBuffer)) {
2795 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
2796 load_at = address;
2797 }
2798 else if (sscanf(InputBuffer, "%x", &code) == 1) {
2799 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
2800 Memory[load_at] = (BYTE)code;
2801 }
2802 load_at++;
2803 }
2804 else {
2805 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
2806 }
2807 }
2808
2809 fclose(ifp);
2810 }
2811
2812 // Emulate
2813
2814 emulate();
2815 }
2816 else {
2817 printf("\n");
2818 printf("ERROR> Input file %s does not exist!\n", hex_file);
2819 printf("\n");
2820 }
2821}
2822
2823void building(int args, _TCHAR** argv) {
2824 char buffer[1024];
2825 load_and_run(args, argv);
2826 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",
2827 Memory[TEST_ADDRESS_1],
2828 Memory[TEST_ADDRESS_2],
2829 Memory[TEST_ADDRESS_3],
2830 Memory[TEST_ADDRESS_4],
2831 Memory[TEST_ADDRESS_5],
2832 Memory[TEST_ADDRESS_6],
2833 Memory[TEST_ADDRESS_7],
2834 Memory[TEST_ADDRESS_8],
2835 Memory[TEST_ADDRESS_9],
2836 Memory[TEST_ADDRESS_10],
2837 Memory[TEST_ADDRESS_11],
2838 Memory[TEST_ADDRESS_12]
2839 );
2840 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
2841}
2842
2843
2844
2845void test_and_mark() {
2846 char buffer[1024];
2847 bool testing_complete;
2848 int len = sizeof(SOCKADDR);
2849 char chr;
2850 int i;
2851 int j;
2852 bool end_of_program;
2853 long address;
2854 long load_at;
2855 int code;
2856 int mark;
2857 int passed;
2858
2859 printf("\n");
2860 printf("Automatic Testing and Marking\n");
2861 printf("\n");
2862
2863 testing_complete = false;
2864
2865 sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
2866 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
2867
2868 while (!testing_complete) {
2869 memset(buffer, '\0', sizeof(buffer));
2870
2871 if (recvfrom(sock, buffer, sizeof(buffer) - 1, 0, (SOCKADDR *)&client_addr, &len) != SOCKET_ERROR) {
2872 printf("Incoming Data: %s \n", buffer);
2873
2874 //if (strcmp(buffer, "Testing complete") == 1)
2875 if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
2876 testing_complete = true;
2877 printf("Current mark = %d\n", mark);
2878
2879 }
2880 else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
2881 //testing_complete = true;
2882 printf("Passed = %d\n", passed);
2883
2884 }
2885 else if (strcmp(buffer, "Error") == 0) {
2886 printf("ERROR> Testing abnormally terminated\n");
2887 testing_complete = true;
2888 }
2889 else {
2890 // Clear Registers and Memory
2891
2892 Registers[REGISTER_A] = 0;
2893 Registers[REGISTER_B] = 0;
2894 Registers[REGISTER_C] = 0;
2895 Registers[REGISTER_L] = 0;
2896 Registers[REGISTER_H] = 0;
2897 Index_Registers[REGISTER_X] = 0;
2898 Index_Registers[REGISTER_Y] = 0;
2899 Flags = 0;
2900 ProgramCounter = 0;
2901 StackPointer = 0;
2902 for (i = 0; i < MEMORY_SIZE; i++) {
2903 Memory[i] = 0;
2904 }
2905
2906 // Load hex file
2907
2908 i = 0;
2909 j = 0;
2910 load_at = 0;
2911 end_of_program = false;
2912 FILE *ofp;
2913 fopen_s(&ofp, "branch.txt", "a");
2914
2915 while (!end_of_program) {
2916 chr = buffer[i];
2917 switch (chr) {
2918 case '\0':
2919 end_of_program = true;
2920
2921 case ',':
2922 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
2923 load_at = address;
2924 }
2925 else if (sscanf(InputBuffer, "%x", &code) == 1) {
2926 if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
2927 Memory[load_at] = (BYTE)code;
2928 fprintf(ofp, "%02X\n", (BYTE)code);
2929 }
2930 load_at++;
2931 }
2932 else {
2933 printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
2934 }
2935 j = 0;
2936 break;
2937
2938 default:
2939 InputBuffer[j] = chr;
2940 j++;
2941 break;
2942 }
2943 i++;
2944 }
2945 fclose(ofp);
2946 // Emulate
2947
2948 if (load_at > 1) {
2949 emulate();
2950 // Send and store results
2951 sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
2952 Memory[TEST_ADDRESS_1],
2953 Memory[TEST_ADDRESS_2],
2954 Memory[TEST_ADDRESS_3],
2955 Memory[TEST_ADDRESS_4],
2956 Memory[TEST_ADDRESS_5],
2957 Memory[TEST_ADDRESS_6],
2958 Memory[TEST_ADDRESS_7],
2959 Memory[TEST_ADDRESS_8],
2960 Memory[TEST_ADDRESS_9],
2961 Memory[TEST_ADDRESS_10],
2962 Memory[TEST_ADDRESS_11],
2963 Memory[TEST_ADDRESS_12]
2964 );
2965 sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
2966 }
2967 }
2968 }
2969 }
2970}
2971
2972
2973
2974int _tmain(int argc, _TCHAR* argv[])
2975{
2976 char chr;
2977 char dummy;
2978
2979 printf("\n");
2980 printf("Microprocessor Emulator\n");
2981 printf("UWE Computer and Network Systems Assignment 1\n");
2982 printf("\n");
2983
2984 initialise_filenames();
2985
2986 if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return(0);
2987
2988 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
2989 if (!sock) {
2990 // Creation failed!
2991 }
2992
2993 memset(&server_addr, 0, sizeof(SOCKADDR_IN));
2994 server_addr.sin_family = AF_INET;
2995 server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
2996 server_addr.sin_port = htons(PORT_SERVER);
2997
2998 memset(&client_addr, 0, sizeof(SOCKADDR_IN));
2999 client_addr.sin_family = AF_INET;
3000 client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
3001 client_addr.sin_port = htons(PORT_CLIENT);
3002
3003 chr = '\0';
3004 while ((chr != 'e') && (chr != 'E'))
3005 {
3006 printf("\n");
3007 printf("Please select option\n");
3008 printf("L - Load and run a hex file\n");
3009 printf("T - Have the server test and mark your emulator\n");
3010 printf("E - Exit\n");
3011 if (argc == 2) { building(argc, argv); exit(0); }
3012 printf("Enter option: ");
3013 chr = getchar();
3014 if (chr != 0x0A)
3015 {
3016 dummy = getchar(); // read in the <CR>
3017 }
3018 printf("\n");
3019
3020 switch (chr)
3021 {
3022 case 'L':
3023 case 'l':
3024 load_and_run(argc, argv);
3025 break;
3026
3027 case 'T':
3028 case 't':
3029 test_and_mark();
3030 break;
3031
3032 default:
3033 break;
3034 }
3035 }
3036
3037 closesocket(sock);
3038 WSACleanup();
3039
3040
3041 return 0;
3042}