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