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