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