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