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