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