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