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