summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvin <git@vineetk.net>2024-06-28 09:51:55 -0400
committervin <git@vineetk.net>2024-06-28 10:17:37 -0400
commit3ebdeab784d8ecd6d6d3a531693ad285577f32e0 (patch)
treea86d77ac3b2782e12c113ea36791063a51e44ffb
parent6a5b0b728e522cd4e90a2ae775666ad6c36d3c5a (diff)
start logging instructions as nestest.log has done
-rw-r--r--.gitignore1
-rw-r--r--Makefile8
-rw-r--r--cpu.c223
3 files changed, 201 insertions, 31 deletions
diff --git a/.gitignore b/.gitignore
index 4d0dfab..567a3fd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
1a.out 1a.out
2nes
2*.core 3*.core
3*~ 4*~
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..a7f070a
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,8 @@
1nes:
2 ${CC} -o nes cpu.c rom.c
3
4test: nes
5 ./nes ${HOME}/src/other/nes-test-roms/other/nestest.nes
6
7clean:
8 rm -f *.o nes
diff --git a/cpu.c b/cpu.c
index 594c462..862ba67 100644
--- a/cpu.c
+++ b/cpu.c
@@ -12,6 +12,11 @@
12 (regs.status.zero = r == 0) 12 (regs.status.zero = r == 0)
13#define STATUS_UPDATE_NEGATIVE(r) \ 13#define STATUS_UPDATE_NEGATIVE(r) \
14 (regs.status.negative = ((r & (1 << 7)) != 0)) 14 (regs.status.negative = ((r & (1 << 7)) != 0))
15#define STATUS_TO_INT() \
16 ((regs.status.carry << 7) | (regs.status.zero << 6) \
17 | (regs.status.interrupt_disable << 5) | (regs.status.decimal_mode << 4) \
18 | (regs.status.brk << 3) | (regs.status.unused << 2) \
19 | (regs.status.overflow << 1) | regs.status.negative)
15 20
16#define MEMORY_MIRROR(addr) \ 21#define MEMORY_MIRROR(addr) \
17 if (addr < 0x2000) \ 22 if (addr < 0x2000) \
@@ -108,10 +113,14 @@ opcode_arg(enum addressing_mode mode)
108{ 113{
109 uint16_t arg, val; 114 uint16_t arg, val;
110 115
111 if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y) 116 if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y) {
112 arg = peek(regs.pc++); 117 arg = peek(regs.pc++);
113 else 118 printf(" %02X\t", arg);
114 arg = peek16(regs.pc), regs.pc += 2; 119 } else {
120 arg = peek16(regs.pc);
121 printf(" %02X %02X\t", peek(regs.pc), peek(regs.pc + 1));
122 regs.pc += 2;
123 }
115 124
116 switch (mode) { 125 switch (mode) {
117 case AM_IMM: 126 case AM_IMM:
@@ -129,12 +138,15 @@ opcode_arg(enum addressing_mode mode)
129 break; 138 break;
130 case AM_ABS: 139 case AM_ABS:
131 val = peek16(arg); 140 val = peek16(arg);
141 printf("$%04X", arg);
132 break; 142 break;
133 case AM_ABS_X: 143 case AM_ABS_X:
134 val = peek16(arg + regs.x); 144 val = peek16(arg + regs.x);
145 printf("$%04X", arg);
135 break; 146 break;
136 case AM_ABS_Y: 147 case AM_ABS_Y:
137 val = peek16(arg + regs.y); 148 val = peek16(arg + regs.y);
149 printf("$%04X", arg);
138 break; 150 break;
139 case AM_IND_X: 151 case AM_IND_X:
140 val = peek(peek((arg + regs.x) % 256) + peek((arg + regs.x + 1) % 256) * 256); 152 val = peek(peek((arg + regs.x) % 256) + peek((arg + regs.x + 1) % 256) * 256);
@@ -147,8 +159,6 @@ opcode_arg(enum addressing_mode mode)
147 abort(); 159 abort();
148 } 160 }
149 161
150 printf("arg: $%04X $%04X\n", arg, val);
151
152 return val; 162 return val;
153} 163}
154 164
@@ -157,10 +167,14 @@ opcode_mem(enum addressing_mode mode)
157{ 167{
158 uint16_t arg, val; 168 uint16_t arg, val;
159 169
160 if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y) 170 if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y) {
161 arg = peek(regs.pc++); 171 arg = peek(regs.pc++);
162 else 172 printf(" %02X\t", arg);
163 arg = peek16(regs.pc), regs.pc += 2; 173 } else {
174 arg = peek16(regs.pc);
175 printf(" %02X %02X\t", peek(regs.pc), peek(regs.pc + 1));
176 regs.pc += 2;
177 }
164 178
165 switch (mode) { 179 switch (mode) {
166 case AM_ZP: 180 case AM_ZP:
@@ -301,6 +315,7 @@ brk(void)
301{ 315{
302 /* TODO: push regs.pc and regs.status to stack and load IRQ vector */ 316 /* TODO: push regs.pc and regs.status to stack and load IRQ vector */
303 regs.status.brk = 1; 317 regs.status.brk = 1;
318 putchar('\n');
304 exit(0); 319 exit(0);
305} 320}
306 321
@@ -542,10 +557,7 @@ php(void)
542{ 557{
543 uint8_t status; 558 uint8_t status;
544 559
545 status = (regs.status.carry << 7) | (regs.status.zero << 6) 560 status = STATUS_TO_INT();
546 | (regs.status.interrupt_disable << 5) | (regs.status.decimal_mode << 4)
547 | (regs.status.brk << 3) | (regs.status.unused << 2)
548 | (regs.status.overflow << 1) | regs.status.negative;
549 561
550 PUSH(status); 562 PUSH(status);
551} 563}
@@ -742,678 +754,837 @@ tya(void)
742static void 754static void
743interpret(void) 755interpret(void)
744{ 756{
745 uint8_t opcode; 757 uint8_t opcode, cycles_;
746 758
747 for (;;) { 759 for (;;) {
748 opcode = peek(regs.pc++); 760 opcode = peek(regs.pc++);
761 cycles_ = cycles;
749 762
750 printf("opcode: $%02X @ $%04X\n", opcode, regs.pc - 1); 763 printf("%04X %02X", regs.pc - 1, opcode);
751 764
752 switch (opcode) { 765 switch (opcode) {
753 case 0x69: 766 case 0x69:
754 adc(opcode_arg(AM_IMM)); 767 adc(opcode_arg(AM_IMM));
755 cycles += 2; 768 cycles += 2;
769 printf("ADC");
756 break; 770 break;
757 case 0x65: 771 case 0x65:
758 adc(opcode_arg(AM_ZP)); 772 adc(opcode_arg(AM_ZP));
759 cycles += 3; 773 cycles += 3;
774 printf("ADC");
760 break; 775 break;
761 case 0x75: 776 case 0x75:
762 adc(opcode_arg(AM_ZP_X)); 777 adc(opcode_arg(AM_ZP_X));
763 cycles += 4; 778 cycles += 4;
779 printf("ADC");
764 break; 780 break;
765 case 0x6d: 781 case 0x6d:
766 adc(opcode_arg(AM_ABS)); 782 adc(opcode_arg(AM_ABS));
767 cycles += 4; 783 cycles += 4;
784 printf("ADC");
768 break; 785 break;
769 case 0x7d: 786 case 0x7d:
770 adc(opcode_arg(AM_ABS_X)); 787 adc(opcode_arg(AM_ABS_X));
771 cycles += 4; 788 cycles += 4;
789 printf("ADC");
772 break; 790 break;
773 case 0x79: 791 case 0x79:
774 adc(opcode_arg(AM_ABS_Y)); 792 adc(opcode_arg(AM_ABS_Y));
775 cycles += 4; 793 cycles += 4;
794 printf("ADC");
776 break; 795 break;
777 case 0x72: 796 case 0x72:
778 adc(opcode_arg(AM_IND)); 797 adc(opcode_arg(AM_IND));
779 cycles += 5; 798 cycles += 5;
799 printf("ADC");
780 break; 800 break;
781 case 0x61: 801 case 0x61:
782 adc(opcode_arg(AM_IND_X)); 802 adc(opcode_arg(AM_IND_X));
783 cycles += 6; 803 cycles += 6;
804 printf("ADC");
784 break; 805 break;
785 case 0x71: 806 case 0x71:
786 adc(opcode_arg(AM_IND_Y)); 807 adc(opcode_arg(AM_IND_Y));
787 cycles += 5; 808 cycles += 5;
809 printf("ADC");
788 break; 810 break;
789 case 0x29: 811 case 0x29:
790 and(opcode_arg(AM_IMM)); 812 and(opcode_arg(AM_IMM));
791 cycles += 2; 813 cycles += 2;
814 printf("AND");
792 break; 815 break;
793 case 0x25: 816 case 0x25:
794 and(opcode_arg(AM_ZP)); 817 and(opcode_arg(AM_ZP));
795 cycles += 3; 818 cycles += 3;
819 printf("AND");
796 break; 820 break;
797 case 0x35: 821 case 0x35:
798 and(opcode_arg(AM_ZP_X)); 822 and(opcode_arg(AM_ZP_X));
799 cycles += 4; 823 cycles += 4;
824 printf("AND");
800 break; 825 break;
801 case 0x2d: 826 case 0x2d:
802 and(opcode_arg(AM_ABS)); 827 and(opcode_arg(AM_ABS));
803 cycles += 4; 828 cycles += 4;
829 printf("AND");
804 break; 830 break;
805 case 0x3d: 831 case 0x3d:
806 and(opcode_arg(AM_ABS_X)); 832 and(opcode_arg(AM_ABS_X));
807 cycles += 4; 833 cycles += 4;
834 printf("AND");
808 break; 835 break;
809 case 0x39: 836 case 0x39:
810 and(opcode_arg(AM_ABS_Y)); 837 and(opcode_arg(AM_ABS_Y));
811 cycles += 4; 838 cycles += 4;
839 printf("AND");
812 break; 840 break;
813 case 0x32: 841 case 0x32:
814 and(opcode_arg(AM_IND)); 842 and(opcode_arg(AM_IND));
815 cycles += 5; 843 cycles += 5;
844 printf("AND");
816 break; 845 break;
817 case 0x21: 846 case 0x21:
818 and(opcode_arg(AM_IND_X)); 847 and(opcode_arg(AM_IND_X));
819 cycles += 6; 848 cycles += 6;
849 printf("AND");
820 break; 850 break;
821 case 0x31: 851 case 0x31:
822 and(opcode_arg(AM_IND_Y)); 852 and(opcode_arg(AM_IND_Y));
823 cycles += 5; 853 cycles += 5;
854 printf("AND");
824 break; 855 break;
825 case 0x0a: 856 case 0x0a:
826 asl_acc(); 857 asl_acc();
827 cycles += 2; 858 cycles += 2;
859 printf("\tASL");
828 break; 860 break;
829 case 0x06: 861 case 0x06:
830 asl(opcode_arg(AM_ZP)); 862 asl(opcode_arg(AM_ZP));
831 cycles += 5; 863 cycles += 5;
864 printf("ASL");
832 break; 865 break;
833 case 0x16: 866 case 0x16:
834 asl(opcode_arg(AM_ZP_X)); 867 asl(opcode_arg(AM_ZP_X));
835 cycles += 6; 868 cycles += 6;
869 printf("ASL");
836 break; 870 break;
837 case 0x0e: 871 case 0x0e:
838 asl(opcode_arg(AM_ABS)); 872 asl(opcode_arg(AM_ABS));
839 cycles += 6; 873 cycles += 6;
874 printf("ASL");
840 break; 875 break;
841 case 0x1e: 876 case 0x1e:
842 asl(opcode_arg(AM_ABS_X)); 877 asl(opcode_arg(AM_ABS_X));
843 cycles += 6; 878 cycles += 6;
879 printf("ASL");
844 break; 880 break;
845 case 0x90: 881 case 0x90:
846 bcc(opcode_arg(AM_IMM)); 882 bcc(opcode_arg(AM_IMM));
847 cycles += 2; 883 cycles += 2;
884 printf("BCC");
848 break; 885 break;
849 case 0xb0: 886 case 0xb0:
850 bcs(opcode_arg(AM_IMM)); 887 bcs(opcode_arg(AM_IMM));
851 cycles += 2; 888 cycles += 2;
889 printf("BCS");
852 break; 890 break;
853 case 0xf0: 891 case 0xf0:
854 beq(opcode_arg(AM_IMM)); 892 beq(opcode_arg(AM_IMM));
855 cycles += 2; 893 cycles += 2;
894 printf("BEQ");
856 break; 895 break;
857 case 0x89: 896 case 0x89:
858 bit(opcode_arg(AM_IMM)); 897 bit(opcode_arg(AM_IMM));
859 cycles += 2; 898 cycles += 2;
899 printf("BIT");
860 break; 900 break;
861 case 0x24: 901 case 0x24:
862 bit(opcode_arg(AM_ZP)); 902 bit(opcode_arg(AM_ZP));
863 cycles += 3; 903 cycles += 3;
904 printf("BIT");
864 break; 905 break;
865 case 0x34: 906 case 0x34:
866 bit(opcode_arg(AM_ZP_X)); 907 bit(opcode_arg(AM_ZP_X));
867 cycles += 4; 908 cycles += 4;
909 printf("BIT");
868 break; 910 break;
869 case 0x2c: 911 case 0x2c:
870 bit(opcode_arg(AM_ABS)); 912 bit(opcode_arg(AM_ABS));
871 cycles += 4; 913 cycles += 4;
914 printf("BIT");
872 break; 915 break;
873 case 0x3c: 916 case 0x3c:
874 bit(opcode_arg(AM_ABS_X)); 917 bit(opcode_arg(AM_ABS_X));
875 cycles += 4; 918 cycles += 4;
919 printf("BIT");
876 break; 920 break;
877 case 0x30: 921 case 0x30:
878 bmi(opcode_arg(AM_IMM)); 922 bmi(opcode_arg(AM_IMM));
879 cycles += 2; 923 cycles += 2;
924 printf("BMI");
880 break; 925 break;
881 case 0xd0: 926 case 0xd0:
882 bne(opcode_arg(AM_IMM)); 927 bne(opcode_arg(AM_IMM));
883 cycles += 2; 928 cycles += 2;
929 printf("BNE");
884 break; 930 break;
885 case 0x10: 931 case 0x10:
886 bpl(opcode_arg(AM_IMM)); 932 bpl(opcode_arg(AM_IMM));
887 cycles += 2; 933 cycles += 2;
934 printf("BPL");
888 break; 935 break;
889 case 0x00: 936 case 0x00:
890 brk(); 937 brk();
891 cycles += 7; 938 cycles += 7;
939 printf("\tBRK");
892 break; 940 break;
893 case 0x50: 941 case 0x50:
894 bvc(opcode_arg(AM_IMM)); 942 bvc(opcode_arg(AM_IMM));
895 cycles += 2; 943 cycles += 2;
944 printf("BVC");
896 break; 945 break;
897 case 0x70: 946 case 0x70:
898 bvs(opcode_arg(AM_IMM)); 947 bvs(opcode_arg(AM_IMM));
899 cycles += 2; 948 cycles += 2;
949 printf("BVS");
900 break; 950 break;
901 case 0x18: 951 case 0x18:
902 clc(); 952 clc();
903 cycles += 2; 953 cycles += 2;
954 printf("\tCLC");
904 break; 955 break;
905 case 0xd8: 956 case 0xd8:
906 cld(); 957 cld();
907 cycles += 2; 958 cycles += 2;
959 printf("\tCLD");
908 break; 960 break;
909 case 0x58: 961 case 0x58:
910 cli(); 962 cli();
911 cycles += 2; 963 cycles += 2;
964 printf("\tCLI");
912 break; 965 break;
913 case 0xb8: 966 case 0xb8:
914 clv(); 967 clv();
915 cycles += 2; 968 cycles += 2;
969 printf("\tCLV");
916 break; 970 break;
917 case 0xc9: 971 case 0xc9:
918 cmp(opcode_arg(AM_IMM)); 972 cmp(opcode_arg(AM_IMM));
919 cycles += 2; 973 cycles += 2;
974 printf("CMP");
920 break; 975 break;
921 case 0xc5: 976 case 0xc5:
922 cmp(opcode_arg(AM_ZP)); 977 cmp(opcode_arg(AM_ZP));
923 cycles += 3; 978 cycles += 3;
979 printf("CMP");
924 break; 980 break;
925 case 0xd5: 981 case 0xd5:
926 cmp(opcode_arg(AM_ZP_X)); 982 cmp(opcode_arg(AM_ZP_X));
927 cycles += 4; 983 cycles += 4;
984 printf("CMP");
928 break; 985 break;
929 case 0xcd: 986 case 0xcd:
930 cmp(opcode_arg(AM_ABS)); 987 cmp(opcode_arg(AM_ABS));
931 cycles += 4; 988 cycles += 4;
989 printf("CMP");
932 break; 990 break;
933 case 0xdd: 991 case 0xdd:
934 cmp(opcode_arg(AM_ABS_X)); 992 cmp(opcode_arg(AM_ABS_X));
935 cycles += 4; 993 cycles += 4;
994 printf("CMP");
936 break; 995 break;
937 case 0xd9: 996 case 0xd9:
938 cmp(opcode_arg(AM_ABS_Y)); 997 cmp(opcode_arg(AM_ABS_Y));
939 cycles += 4; 998 cycles += 4;
999 printf("CMP");
940 break; 1000 break;
941 case 0xd2: 1001 case 0xd2:
942 cmp(opcode_arg(AM_IND)); 1002 cmp(opcode_arg(AM_IND));
943 cycles += 5; 1003 cycles += 5;
1004 printf("CMP");
944 break; 1005 break;
945 case 0xc1: 1006 case 0xc1:
946 cmp(opcode_arg(AM_IND_X)); 1007 cmp(opcode_arg(AM_IND_X));
947 cycles += 6; 1008 cycles += 6;
1009 printf("CMP");
948 break; 1010 break;
949 case 0xd1: 1011 case 0xd1:
950 cmp(opcode_arg(AM_IND_Y)); 1012 cmp(opcode_arg(AM_IND_Y));
951 cycles += 5; 1013 cycles += 5;
1014 printf("CMP");
952 break; 1015 break;
953 case 0xe0: 1016 case 0xe0:
954 cpx(opcode_arg(AM_IMM)); 1017 cpx(opcode_arg(AM_IMM));
955 cycles += 2; 1018 cycles += 2;
1019 printf("CPX");
956 break; 1020 break;
957 case 0xe4: 1021 case 0xe4:
958 cpx(opcode_arg(AM_ZP)); 1022 cpx(opcode_arg(AM_ZP));
959 cycles += 3; 1023 cycles += 3;
1024 printf("CPX");
960 break; 1025 break;
961 case 0xec: 1026 case 0xec:
962 cpx(opcode_arg(AM_ABS)); 1027 cpx(opcode_arg(AM_ABS));
963 cycles += 4; 1028 cycles += 4;
1029 printf("CPX");
964 break; 1030 break;
965 case 0xc0: 1031 case 0xc0:
966 cpy(opcode_arg(AM_IMM)); 1032 cpy(opcode_arg(AM_IMM));
967 cycles += 2; 1033 cycles += 2;
1034 printf("CPY");
968 break; 1035 break;
969 case 0xc4: 1036 case 0xc4:
970 cpy(opcode_arg(AM_ZP)); 1037 cpy(opcode_arg(AM_ZP));
971 cycles += 3; 1038 cycles += 3;
1039 printf("CPY");
972 break; 1040 break;
973 case 0xcc: 1041 case 0xcc:
974 cpy(opcode_arg(AM_ABS)); 1042 cpy(opcode_arg(AM_ABS));
975 cycles += 4; 1043 cycles += 4;
1044 printf("CPY");
976 break; 1045 break;
977 case 0xc6: 1046 case 0xc6:
978 dec(opcode_mem(AM_ZP)); 1047 dec(opcode_mem(AM_ZP));
979 cycles += 5; 1048 cycles += 5;
1049 printf("DEC");
980 break; 1050 break;
981 case 0xd6: 1051 case 0xd6:
982 dec(opcode_mem(AM_ZP_X)); 1052 dec(opcode_mem(AM_ZP_X));
983 cycles += 6; 1053 cycles += 6;
1054 printf("DEC");
984 break; 1055 break;
985 case 0xce: 1056 case 0xce:
986 dec(opcode_mem(AM_ABS)); 1057 dec(opcode_mem(AM_ABS));
987 cycles += 6; 1058 cycles += 6;
1059 printf("DEC");
988 break; 1060 break;
989 case 0xde: 1061 case 0xde:
990 dec(opcode_mem(AM_ABS_X)); 1062 dec(opcode_mem(AM_ABS_X));
991 cycles += 7; 1063 cycles += 7;
1064 printf("DEC");
992 break; 1065 break;
993 case 0xca: 1066 case 0xca:
994 dex(); 1067 dex();
995 cycles += 2; 1068 cycles += 2;
1069 printf("\tDEX");
996 break; 1070 break;
997 case 0x88: 1071 case 0x88:
998 dey(); 1072 dey();
999 cycles += 2; 1073 cycles += 2;
1074 printf("\tDEY");
1000 break; 1075 break;
1001 case 0x49: 1076 case 0x49:
1002 eor(opcode_arg(AM_IMM)); 1077 eor(opcode_arg(AM_IMM));
1003 cycles += 2; 1078 cycles += 2;
1079 printf("EOR");
1004 break; 1080 break;
1005 case 0x45: 1081 case 0x45:
1006 eor(opcode_arg(AM_ZP)); 1082 eor(opcode_arg(AM_ZP));
1007 cycles += 3; 1083 cycles += 3;
1084 printf("EOR");
1008 break; 1085 break;
1009 case 0x55: 1086 case 0x55:
1010 eor(opcode_arg(AM_ZP_X)); 1087 eor(opcode_arg(AM_ZP_X));
1011 cycles += 4; 1088 cycles += 4;
1089 printf("EOR");
1012 break; 1090 break;
1013 case 0x4d: 1091 case 0x4d:
1014 eor(opcode_arg(AM_ABS)); 1092 eor(opcode_arg(AM_ABS));
1015 cycles += 4; 1093 cycles += 4;
1094 printf("EOR");
1016 break; 1095 break;
1017 case 0x5d: 1096 case 0x5d:
1018 eor(opcode_arg(AM_ABS_X)); 1097 eor(opcode_arg(AM_ABS_X));
1019 cycles += 4; 1098 cycles += 4;
1099 printf("EOR");
1020 break; 1100 break;
1021 case 0x59: 1101 case 0x59:
1022 eor(opcode_arg(AM_ABS_Y)); 1102 eor(opcode_arg(AM_ABS_Y));
1023 cycles += 4; 1103 cycles += 4;
1104 printf("EOR");
1024 break; 1105 break;
1025 case 0x52: 1106 case 0x52:
1026 eor(opcode_arg(AM_IND)); 1107 eor(opcode_arg(AM_IND));
1027 cycles += 5; 1108 cycles += 5;
1109 printf("EOR");
1028 break; 1110 break;
1029 case 0x41: 1111 case 0x41:
1030 eor(opcode_arg(AM_IND_X)); 1112 eor(opcode_arg(AM_IND_X));
1031 cycles += 6; 1113 cycles += 6;
1114 printf("EOR");
1032 break; 1115 break;
1033 case 0x51: 1116 case 0x51:
1034 eor(opcode_arg(AM_IND_Y)); 1117 eor(opcode_arg(AM_IND_Y));
1035 cycles += 5; 1118 cycles += 5;
1119 printf("EOR");
1036 break; 1120 break;
1037 case 0xe6: 1121 case 0xe6:
1038 inc(opcode_arg(AM_ZP)); 1122 inc(opcode_arg(AM_ZP));
1039 cycles += 5; 1123 cycles += 5;
1124 printf("INC");
1040 break; 1125 break;
1041 case 0xf6: 1126 case 0xf6:
1042 inc(opcode_arg(AM_ZP_X)); 1127 inc(opcode_arg(AM_ZP_X));
1043 cycles += 6; 1128 cycles += 6;
1129 printf("INC");
1044 break; 1130 break;
1045 case 0xee: 1131 case 0xee:
1046 inc(opcode_arg(AM_ABS)); 1132 inc(opcode_arg(AM_ABS));
1047 cycles += 6; 1133 cycles += 6;
1134 printf("INC");
1048 break; 1135 break;
1049 case 0xfe: 1136 case 0xfe:
1050 inc(opcode_arg(AM_ABS_X)); 1137 inc(opcode_arg(AM_ABS_X));
1051 cycles += 7; 1138 cycles += 7;
1139 printf("INC");
1052 break; 1140 break;
1053 case 0xe8: 1141 case 0xe8:
1054 inx(); 1142 inx();
1055 cycles += 2; 1143 cycles += 2;
1144 printf("\tINX");
1056 break; 1145 break;
1057 case 0xc8: 1146 case 0xc8:
1058 iny(); 1147 iny();
1059 cycles += 2; 1148 cycles += 2;
1149 printf("\tINY");
1060 break; 1150 break;
1061 case 0x4c: 1151 case 0x4c:
1062 jmp(opcode_mem(AM_ABS)); 1152 jmp(opcode_mem(AM_ABS));
1063 cycles += 3; 1153 cycles += 3;
1154 printf("JMP");
1064 break; 1155 break;
1065 case 0x6c: 1156 case 0x6c:
1066 jmp(opcode_arg(AM_IND)); 1157 jmp(opcode_arg(AM_IND));
1067 cycles += 6; 1158 cycles += 6;
1159 printf("JMP");
1068 break; 1160 break;
1069 case 0x7c: 1161 case 0x7c:
1070 jmp(opcode_arg(AM_ABS_X)); 1162 jmp(opcode_arg(AM_ABS_X));
1071 cycles += 6; 1163 cycles += 6;
1164 printf("JMP");
1072 break; 1165 break;
1073 case 0x20: 1166 case 0x20:
1074 jsr(opcode_arg(AM_ABS)); 1167 jsr(opcode_arg(AM_ABS));
1075 cycles += 6; 1168 cycles += 6;
1169 printf("JSR");
1076 break; 1170 break;
1077 case 0xa9: 1171 case 0xa9:
1078 lda(opcode_arg(AM_IMM)); 1172 lda(opcode_arg(AM_IMM));
1079 cycles += 2; 1173 cycles += 2;
1174 printf("LDA");
1080 break; 1175 break;
1081 case 0xa5: 1176 case 0xa5:
1082 lda(opcode_arg(AM_ZP)); 1177 lda(opcode_arg(AM_ZP));
1083 cycles += 3; 1178 cycles += 3;
1179 printf("LDA");
1084 break; 1180 break;
1085 case 0xb5: 1181 case 0xb5:
1086 lda(opcode_arg(AM_ZP_X)); 1182 lda(opcode_arg(AM_ZP_X));
1087 cycles += 4; 1183 cycles += 4;
1184 printf("LDA");
1088 break; 1185 break;
1089 case 0xad: 1186 case 0xad:
1090 lda(opcode_arg(AM_ABS)); 1187 lda(opcode_arg(AM_ABS));
1091 cycles += 4; 1188 cycles += 4;
1189 printf("LDA");
1092 break; 1190 break;
1093 case 0xbd: 1191 case 0xbd:
1094 lda(opcode_arg(AM_ABS_X)); 1192 lda(opcode_arg(AM_ABS_X));
1095 cycles += 4; 1193 cycles += 4;
1194 printf("LDA");
1096 break; 1195 break;
1097 case 0xb9: 1196 case 0xb9:
1098 lda(opcode_arg(AM_ABS_Y)); 1197 lda(opcode_arg(AM_ABS_Y));
1099 cycles += 4; 1198 cycles += 4;
1199 printf("LDA");
1100 break; 1200 break;
1101 case 0xb2: 1201 case 0xb2:
1102 lda(opcode_arg(AM_IND)); 1202 lda(opcode_arg(AM_IND));
1103 cycles += 5; 1203 cycles += 5;
1204 printf("LDA");
1104 break; 1205 break;
1105 case 0xa1: 1206 case 0xa1:
1106 lda(opcode_arg(AM_IND_X)); 1207 lda(opcode_arg(AM_IND_X));
1107 cycles += 6; 1208 cycles += 6;
1209 printf("LDA");
1108 break; 1210 break;
1109 case 0xb1: 1211 case 0xb1:
1110 lda(opcode_arg(AM_IND_Y)); 1212 lda(opcode_arg(AM_IND_Y));
1111 cycles += 5; 1213 cycles += 5;
1214 printf("LDA");
1112 break; 1215 break;
1113 case 0xa2: 1216 case 0xa2:
1114 ldx(opcode_mem(AM_IMM)); 1217 ldx(opcode_mem(AM_IMM));
1115 cycles += 2; 1218 cycles += 2;
1219 printf("LDX");
1116 break; 1220 break;
1117 case 0xa6: 1221 case 0xa6:
1118 ldx(opcode_arg(AM_ZP)); 1222 ldx(opcode_arg(AM_ZP));
1119 cycles += 3; 1223 cycles += 3;
1224 printf("LDX");
1120 break; 1225 break;
1121 case 0xb6: 1226 case 0xb6:
1122 ldx(opcode_arg(AM_ZP_Y)); 1227 ldx(opcode_arg(AM_ZP_Y));
1123 cycles += 4; 1228 cycles += 4;
1229 printf("LDX");
1124 break; 1230 break;
1125 case 0xae: 1231 case 0xae:
1126 ldx(opcode_arg(AM_ABS)); 1232 ldx(opcode_arg(AM_ABS));
1127 cycles += 4; 1233 cycles += 4;
1234 printf("LDX");
1128 break; 1235 break;
1129 case 0xbe: 1236 case 0xbe:
1130 ldx(opcode_arg(AM_ABS_Y)); 1237 ldx(opcode_arg(AM_ABS_Y));
1131 cycles += 4; 1238 cycles += 4;
1239 printf("LDX");
1132 break; 1240 break;
1133 case 0xa0: 1241 case 0xa0:
1134 ldy(opcode_arg(AM_IMM)); 1242 ldy(opcode_arg(AM_IMM));
1135 cycles += 2; 1243 cycles += 2;
1244 printf("LDY");
1136 break; 1245 break;
1137 case 0xa4: 1246 case 0xa4:
1138 ldy(opcode_arg(AM_ZP)); 1247 ldy(opcode_arg(AM_ZP));
1139 cycles += 3; 1248 cycles += 3;
1249 printf("LDY");
1140 break; 1250 break;
1141 case 0xb4: 1251 case 0xb4:
1142 ldy(opcode_arg(AM_ZP_X)); 1252 ldy(opcode_arg(AM_ZP_X));
1143 cycles += 4; 1253 cycles += 4;
1254 printf("LDY");
1144 break; 1255 break;
1145 case 0xac: 1256 case 0xac:
1146 ldy(opcode_arg(AM_ABS)); 1257 ldy(opcode_arg(AM_ABS));
1147 cycles += 4; 1258 cycles += 4;
1259 printf("LDY");
1148 break; 1260 break;
1149 case 0xbc: 1261 case 0xbc:
1150 ldy(opcode_arg(AM_ABS_X)); 1262 ldy(opcode_arg(AM_ABS_X));
1151 cycles += 4; 1263 cycles += 4;
1264 printf("LDY");
1152 break; 1265 break;
1153 case 0x4a: 1266 case 0x4a:
1154 lsr_acc(); 1267 lsr_acc();
1155 cycles += 2; 1268 cycles += 2;
1269 printf("\tLSR");
1156 break; 1270 break;
1157 case 0x46: 1271 case 0x46:
1158 lsr(opcode_arg(AM_ZP)); 1272 lsr(opcode_arg(AM_ZP));
1159 cycles += 5; 1273 cycles += 5;
1274 printf("LSR");
1160 break; 1275 break;
1161 case 0x56: 1276 case 0x56:
1162 lsr(opcode_arg(AM_ZP_X)); 1277 lsr(opcode_arg(AM_ZP_X));
1163 cycles += 6; 1278 cycles += 6;
1279 printf("LSR");
1164 break; 1280 break;
1165 case 0x4e: 1281 case 0x4e:
1166 lsr(opcode_arg(AM_ABS)); 1282 lsr(opcode_arg(AM_ABS));
1167 cycles += 6; 1283 cycles += 6;
1284 printf("LSR");
1168 break; 1285 break;
1169 case 0x5e: 1286 case 0x5e:
1170 lsr(opcode_arg(AM_ABS_X)); 1287 lsr(opcode_arg(AM_ABS_X));
1171 cycles += 6; 1288 cycles += 6;
1289 printf("LSR");
1172 break; 1290 break;
1173 case 0xea: 1291 case 0xea:
1174 nop(); 1292 nop();
1175 cycles += 2; 1293 cycles += 2;
1294 printf("\tNOP");
1176 break; 1295 break;
1177 case 0x09: 1296 case 0x09:
1178 ora(opcode_arg(AM_IMM)); 1297 ora(opcode_arg(AM_IMM));
1179 cycles += 2; 1298 cycles += 2;
1299 printf("ORA");
1180 break; 1300 break;
1181 case 0x05: 1301 case 0x05:
1182 ora(opcode_arg(AM_ZP)); 1302 ora(opcode_arg(AM_ZP));
1183 cycles += 3; 1303 cycles += 3;
1304 printf("ORA");
1184 break; 1305 break;
1185 case 0x15: 1306 case 0x15:
1186 ora(opcode_arg(AM_ZP_X)); 1307 ora(opcode_arg(AM_ZP_X));
1187 cycles += 4; 1308 cycles += 4;
1309 printf("ORA");
1188 break; 1310 break;
1189 case 0x0d: 1311 case 0x0d:
1190 ora(opcode_arg(AM_ABS)); 1312 ora(opcode_arg(AM_ABS));
1191 cycles += 4; 1313 cycles += 4;
1314 printf("ORA");
1192 break; 1315 break;
1193 case 0x1d: 1316 case 0x1d:
1194 ora(opcode_arg(AM_ABS_X)); 1317 ora(opcode_arg(AM_ABS_X));
1195 cycles += 4; 1318 cycles += 4;
1319 printf("ORA");
1196 break; 1320 break;
1197 case 0x19: 1321 case 0x19:
1198 ora(opcode_arg(AM_ABS_Y)); 1322 ora(opcode_arg(AM_ABS_Y));
1199 cycles += 4; 1323 cycles += 4;
1324 printf("ORA");
1200 break; 1325 break;
1201 case 0x12: 1326 case 0x12:
1202 ora(opcode_arg(AM_IND)); 1327 ora(opcode_arg(AM_IND));
1203 cycles += 5; 1328 cycles += 5;
1329 printf("ORA");
1204 break; 1330 break;
1205 case 0x01: 1331 case 0x01:
1206 ora(opcode_arg(AM_IND_X)); 1332 ora(opcode_arg(AM_IND_X));
1207 cycles += 6; 1333 cycles += 6;
1334 printf("ORA");
1208 break; 1335 break;
1209 case 0x11: 1336 case 0x11:
1210 ora(opcode_arg(AM_IND_Y)); 1337 ora(opcode_arg(AM_IND_Y));
1211 cycles += 5; 1338 cycles += 5;
1339 printf("ORA");
1212 break; 1340 break;
1213 case 0x48: 1341 case 0x48:
1214 pha(); 1342 pha();
1215 cycles += 3; 1343 cycles += 3;
1344 printf("\tPHA");
1216 break; 1345 break;
1217 case 0x08: 1346 case 0x08:
1218 php(); 1347 php();
1219 cycles += 3; 1348 cycles += 3;
1349 printf("\tPHP");
1220 break; 1350 break;
1221 case 0x68: 1351 case 0x68:
1222 pla(); 1352 pla();
1223 cycles += 4; 1353 cycles += 4;
1354 printf("\tPLA");
1224 break; 1355 break;
1225 case 0x28: 1356 case 0x28:
1226 plp(); 1357 plp();
1227 cycles += 4; 1358 cycles += 4;
1359 printf("\tPLP");
1228 break; 1360 break;
1229 case 0x2a: 1361 case 0x2a:
1230 rol_acc(); 1362 rol_acc();
1231 cycles += 2; 1363 cycles += 2;
1364 printf("\tROL");
1232 break; 1365 break;
1233 case 0x26: 1366 case 0x26:
1234 rol(opcode_arg(AM_ZP)); 1367 rol(opcode_arg(AM_ZP));
1235 cycles += 5; 1368 cycles += 5;
1369 printf("ROL");
1236 break; 1370 break;
1237 case 0x36: 1371 case 0x36:
1238 rol(opcode_arg(AM_ZP_X)); 1372 rol(opcode_arg(AM_ZP_X));
1239 cycles += 6; 1373 cycles += 6;
1374 printf("ROL");
1240 break; 1375 break;
1241 case 0x2e: 1376 case 0x2e:
1242 rol(opcode_arg(AM_ABS)); 1377 rol(opcode_arg(AM_ABS));
1243 cycles += 6; 1378 cycles += 6;
1379 printf("ROL");
1244 break; 1380 break;
1245 case 0x3e: 1381 case 0x3e:
1246 rol(opcode_arg(AM_ABS_X)); 1382 rol(opcode_arg(AM_ABS_X));
1247 cycles += 6; 1383 cycles += 6;
1384 printf("ROL");
1248 break; 1385 break;
1249 case 0x6a: 1386 case 0x6a:
1250 ror_acc(); 1387 ror_acc();
1251 cycles += 2; 1388 cycles += 2;
1389 printf("\tROR");
1252 break; 1390 break;
1253 case 0x66: 1391 case 0x66:
1254 ror(opcode_arg(AM_ZP)); 1392 ror(opcode_arg(AM_ZP));
1255 cycles += 5; 1393 cycles += 5;
1394 printf("ROR");
1256 break; 1395 break;
1257 case 0x76: 1396 case 0x76:
1258 ror(opcode_arg(AM_ZP_X)); 1397 ror(opcode_arg(AM_ZP_X));
1259 cycles += 6; 1398 cycles += 6;
1399 printf("ROR");
1260 break; 1400 break;
1261 case 0x6e: 1401 case 0x6e:
1262 ror(opcode_arg(AM_ABS)); 1402 ror(opcode_arg(AM_ABS));
1263 cycles += 6; 1403 cycles += 6;
1404 printf("ROR");
1264 break; 1405 break;
1265 case 0x7e: 1406 case 0x7e:
1266 ror(opcode_arg(AM_ABS_X)); 1407 ror(opcode_arg(AM_ABS_X));
1267 cycles += 6; 1408 cycles += 6;
1409 printf("ROR");
1268 break; 1410 break;
1269 case 0x40: 1411 case 0x40:
1270 rti(); 1412 rti();
1271 cycles += 6; 1413 cycles += 6;
1414 printf("\tRTI");
1272 break; 1415 break;
1273 case 0x60: 1416 case 0x60:
1274 rts(); 1417 rts();
1275 cycles += 6; 1418 cycles += 6;
1419 printf("\tRTS");
1276 break; 1420 break;
1277 case 0xe9: 1421 case 0xe9:
1278 sbc(opcode_arg(AM_IMM)); 1422 sbc(opcode_arg(AM_IMM));
1279 cycles += 2; 1423 cycles += 2;
1424 printf("SBC");
1280 break; 1425 break;
1281 case 0xe5: 1426 case 0xe5:
1282 sbc(opcode_arg(AM_ZP)); 1427 sbc(opcode_arg(AM_ZP));
1283 cycles += 3; 1428 cycles += 3;
1429 printf("SBC");
1284 break; 1430 break;
1285 case 0xf5: 1431 case 0xf5:
1286 sbc(opcode_arg(AM_ZP_X)); 1432 sbc(opcode_arg(AM_ZP_X));
1287 cycles += 4; 1433 cycles += 4;
1434 printf("SBC");
1288 break; 1435 break;
1289 case 0xed: 1436 case 0xed:
1290 sbc(opcode_arg(AM_ABS)); 1437 sbc(opcode_arg(AM_ABS));
1291 cycles += 4; 1438 cycles += 4;
1439 printf("SBC");
1292 break; 1440 break;
1293 case 0xfd: 1441 case 0xfd:
1294 sbc(opcode_arg(AM_ABS_X)); 1442 sbc(opcode_arg(AM_ABS_X));
1295 cycles += 4; 1443 cycles += 4;
1444 printf("SBC");
1296 break; 1445 break;
1297 case 0xf9: 1446 case 0xf9:
1298 sbc(opcode_arg(AM_ABS_Y)); 1447 sbc(opcode_arg(AM_ABS_Y));
1299 cycles += 4; 1448 cycles += 4;
1449 printf("SBC");
1300 break; 1450 break;
1301 case 0xf2: 1451 case 0xf2:
1302 sbc(opcode_arg(AM_IND)); 1452 sbc(opcode_arg(AM_IND));
1303 cycles += 5; 1453 cycles += 5;
1454 printf("SBC");
1304 break; 1455 break;
1305 case 0xe1: 1456 case 0xe1:
1306 sbc(opcode_arg(AM_IND_X)); 1457 sbc(opcode_arg(AM_IND_X));
1307 cycles += 6; 1458 cycles += 6;
1459 printf("SBC");
1308 break; 1460 break;
1309 case 0xf1: 1461 case 0xf1:
1310 sbc(opcode_arg(AM_IND_Y)); 1462 sbc(opcode_arg(AM_IND_Y));
1311 cycles += 5; 1463 cycles += 5;
1464 printf("SBC");
1312 break; 1465 break;
1313 case 0x38: 1466 case 0x38:
1314 sec(); 1467 sec();
1315 cycles += 2; 1468 cycles += 2;
1469 printf("\tSEC");
1316 break; 1470 break;
1317 case 0xf8: 1471 case 0xf8:
1318 sed(); 1472 sed();
1319 cycles += 2; 1473 cycles += 2;
1474 printf("\tSED");
1320 break; 1475 break;
1321 case 0x78: 1476 case 0x78:
1322 sei(); 1477 sei();
1323 cycles += 2; 1478 cycles += 2;
1479 printf("\tSEI");
1324 break; 1480 break;
1325 case 0x85: 1481 case 0x85:
1326 sta(opcode_mem(AM_ZP)); 1482 sta(opcode_mem(AM_ZP));
1327 cycles += 4; 1483 cycles += 4;
1484 printf("STA");
1328 break; 1485 break;
1329 case 0x95: 1486 case 0x95:
1330 sta(opcode_mem(AM_ZP_X)); 1487 sta(opcode_mem(AM_ZP_X));
1331 cycles += 5; 1488 cycles += 5;
1489 printf("STA");
1332 break; 1490 break;
1333 case 0x8d: 1491 case 0x8d:
1334 sta(opcode_mem(AM_ABS)); 1492 sta(opcode_mem(AM_ABS));
1335 cycles += 5; 1493 cycles += 5;
1494 printf("STA");
1336 break; 1495 break;
1337 case 0x9d: 1496 case 0x9d:
1338 sta(opcode_mem(AM_ABS_X)); 1497 sta(opcode_mem(AM_ABS_X));
1339 cycles += 6; 1498 cycles += 6;
1499 printf("STA");
1340 break; 1500 break;
1341 case 0x99: 1501 case 0x99:
1342 sta(opcode_mem(AM_ABS_Y)); 1502 sta(opcode_mem(AM_ABS_Y));
1343 cycles += 6; 1503 cycles += 6;
1504 printf("STA");
1344 break; 1505 break;
1345 case 0x92: 1506 case 0x92:
1346 sta(opcode_mem(AM_IND)); 1507 sta(opcode_mem(AM_IND));
1347 cycles += 6; 1508 cycles += 6;
1509 printf("STA");
1348 break; 1510 break;
1349 case 0x81: 1511 case 0x81:
1350 sta(opcode_mem(AM_IND_X)); 1512 sta(opcode_mem(AM_IND_X));
1351 cycles += 7; 1513 cycles += 7;
1514 printf("STA");
1352 break; 1515 break;
1353 case 0x91: 1516 case 0x91:
1354 sta(opcode_mem(AM_IND_Y)); 1517 sta(opcode_mem(AM_IND_Y));
1355 cycles += 7; 1518 cycles += 7;
1519 printf("STA");
1356 break; 1520 break;
1357 case 0x86: 1521 case 0x86:
1358 stx(opcode_mem(AM_ZP)); 1522 stx(opcode_mem(AM_ZP));
1359 cycles += 4; 1523 cycles += 4;
1524 printf("STX");
1360 break; 1525 break;
1361 case 0x96: 1526 case 0x96:
1362 stx(opcode_mem(AM_ZP_Y)); 1527 stx(opcode_mem(AM_ZP_Y));
1363 cycles += 5; 1528 cycles += 5;
1529 printf("STX");
1364 break; 1530 break;
1365 case 0x8e: 1531 case 0x8e:
1366 stx(opcode_mem(AM_ABS)); 1532 stx(opcode_mem(AM_ABS));
1367 cycles += 5; 1533 cycles += 5;
1534 printf("STX");
1368 break; 1535 break;
1369 case 0x84: 1536 case 0x84:
1370 sty(opcode_mem(AM_ZP)); 1537 sty(opcode_mem(AM_ZP));
1371 cycles += 4; 1538 cycles += 4;
1539 printf("STY");
1372 break; 1540 break;
1373 case 0x94: 1541 case 0x94:
1374 sty(opcode_mem(AM_ZP_X)); 1542 sty(opcode_mem(AM_ZP_X));
1375 cycles += 5; 1543 cycles += 5;
1544 printf("STY");
1376 break; 1545 break;
1377 case 0x8c: 1546 case 0x8c:
1378 sty(opcode_mem(AM_ABS)); 1547 sty(opcode_mem(AM_ABS));
1379 cycles += 5; 1548 cycles += 5;
1549 printf("STY");
1380 break; 1550 break;
1381 case 0xaa: 1551 case 0xaa:
1382 tax(); 1552 tax();
1383 cycles += 2; 1553 cycles += 2;
1554 printf("\tTAX");
1384 break; 1555 break;
1385 case 0xa8: 1556 case 0xa8:
1386 tay(); 1557 tay();
1387 cycles += 2; 1558 cycles += 2;
1559 printf("\tTAY");
1388 break; 1560 break;
1389 case 0xba: 1561 case 0xba:
1390 tsx(); 1562 tsx();
1391 cycles += 2; 1563 cycles += 2;
1564 printf("\tTSX");
1392 break; 1565 break;
1393 case 0x8a: 1566 case 0x8a:
1394 txa(); 1567 txa();
1395 cycles += 2; 1568 cycles += 2;
1569 printf("\tTXA");
1396 break; 1570 break;
1397 case 0x9a: 1571 case 0x9a:
1398 txs(); 1572 txs();
1399 cycles += 2; 1573 cycles += 2;
1574 printf("\tTXS");
1400 break; 1575 break;
1401 case 0x98: 1576 case 0x98:
1402 tya(); 1577 tya();
1403 cycles += 2; 1578 cycles += 2;
1579 printf("\tTYA");
1404 break; 1580 break;
1405 default: 1581 default:
1406 printf("opcode $%02X not implemented\n", opcode); 1582 printf("opcode $%02X not implemented\n", opcode);
1407 break; 1583 break;
1408 } 1584 }
1409 1585
1410 printf("status: %i%i%i%i%i%i%i%i\n", regs.status.carry, 1586 printf("%50c:%02X X:%02X Y:%02X P:%02X SP:%02X CYC:%d\n", 'A',
1411 regs.status.zero, regs.status.interrupt_disable, 1587 regs.a, regs.x, regs.y, STATUS_TO_INT(), regs.sp, cycles_);
1412 regs.status.decimal_mode, regs.status.brk,
1413 regs.status.unused, regs.status.overflow,
1414 regs.status.negative);
1415 printf("A: $%02X, X: $%02X, Y: $%02X, SP: $%02X, PC: $%04X\n",
1416 regs.a, regs.x, regs.y, regs.sp, regs.pc);
1417 } 1588 }
1418} 1589}
1419 1590
@@ -1470,16 +1641,6 @@ main(int argc, char *argv[])
1470 memwrite16(0xFFFC, 0xC000); 1641 memwrite16(0xFFFC, 0xC000);
1471 regs.pc = 0xC000; 1642 regs.pc = 0xC000;
1472 1643
1473 printf("status: %i%i%i%i%i%i%i%i\n", regs.status.carry,
1474 regs.status.zero, regs.status.interrupt_disable,
1475 regs.status.decimal_mode, regs.status.brk,
1476 regs.status.unused, regs.status.overflow,
1477 regs.status.negative);
1478 printf("A: $%02X, X: $%02X, Y: $%02X, SP: $%02X, PC: $%02X\n",
1479 regs.a, regs.x, regs.y, regs.sp, regs.pc);
1480
1481 putchar('\n');
1482
1483 interpret(); 1644 interpret();
1484 1645
1485 free_rom(&rom); 1646 free_rom(&rom);