summaryrefslogtreecommitdiff
path: root/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpu.c')
-rw-r--r--cpu.c103
1 files changed, 78 insertions, 25 deletions
diff --git a/cpu.c b/cpu.c
index 87d68c8..8eaeff1 100644
--- a/cpu.c
+++ b/cpu.c
@@ -34,7 +34,6 @@ struct registers {
34struct registers regs; 34struct registers regs;
35 35
36enum addressing_mode { 36enum addressing_mode {
37 AM_ACC,
38 AM_IMM, 37 AM_IMM,
39 AM_ZP, 38 AM_ZP,
40 AM_ZP_X, 39 AM_ZP_X,
@@ -199,7 +198,7 @@ and(uint8_t arg)
199} 198}
200 199
201static void 200static void
202asl(uint8_t arg) 201asl_acc(void)
203{ 202{
204 uint16_t tmp; 203 uint16_t tmp;
205 204
@@ -212,6 +211,19 @@ asl(uint8_t arg)
212} 211}
213 212
214static void 213static void
214asl(uint16_t mem)
215{
216 uint16_t tmp;
217
218 tmp = peek(mem) << 1;
219 memwrite(mem, tmp & 0xFF);
220
221 regs.status.carry = tmp > 0xFF;
222 STATUS_UPDATE_ZERO(tmp);
223 STATUS_UPDATE_NEGATIVE(tmp);
224}
225
226static void
215bcc(uint8_t arg) 227bcc(uint8_t arg)
216{ 228{
217 if (regs.status.carry == 0) 229 if (regs.status.carry == 0)
@@ -398,7 +410,7 @@ inx(void)
398} 410}
399 411
400static void 412static void
401iny(uint8_t arg) 413iny(void)
402{ 414{
403 regs.y++; 415 regs.y++;
404 416
@@ -454,7 +466,7 @@ ldy(uint8_t arg)
454} 466}
455 467
456static void 468static void
457lsr(uint8_t arg) 469lsr_acc(void)
458{ 470{
459 regs.status.carry = regs.a & 1; // bit 0 in carry 471 regs.status.carry = regs.a & 1; // bit 0 in carry
460 regs.a >>= 1; 472 regs.a >>= 1;
@@ -465,7 +477,24 @@ lsr(uint8_t arg)
465} 477}
466 478
467static void 479static void
468nop(uint8_t arg) 480lsr(uint16_t mem)
481{
482 uint8_t tmp;
483
484 tmp = peek(mem);
485
486 regs.status.carry = tmp & 1; // bit 0 in carry
487 tmp >>= 1;
488 tmp &= ~(1 << 7); // bit 7 cleared
489
490 memwrite(mem, tmp);
491
492 STATUS_UPDATE_ZERO(tmp);
493 STATUS_UPDATE_NEGATIVE(tmp);
494}
495
496static void
497nop(void)
469{ 498{
470 return; 499 return;
471} 500}
@@ -525,35 +554,63 @@ plp(void)
525} 554}
526 555
527static void 556static void
528rol(uint8_t arg) 557rol_acc(void)
529{ 558{
530 uint8_t tmp; 559 uint8_t carry;
531 tmp = (regs.a & (1 << 7)) > 0; 560 carry = (regs.a & (1 << 7)) > 0;
532 561
533 regs.a <<= 1; 562 regs.a <<= 1;
534 regs.a |= regs.status.carry; 563 regs.a |= regs.status.carry;
535 564
536 regs.status.carry = tmp; 565 regs.status.carry = carry;
537 STATUS_UPDATE_ZERO(regs.a); 566 STATUS_UPDATE_ZERO(regs.a);
538 STATUS_UPDATE_NEGATIVE(regs.a); 567 STATUS_UPDATE_NEGATIVE(regs.a);
539} 568}
540 569
541static void 570static void
542ror(uint8_t arg) 571rol(uint16_t mem)
543{ 572{
544 uint8_t tmp; 573 uint8_t carry, tmp;
545 tmp = regs.a & 1; 574 carry = (peek(mem) & (1 << 7)) > 0;
575
576 tmp = (peek(mem) << 1) | regs.status.carry;
577 memwrite(mem, tmp);
578
579 regs.status.carry = carry;
580 STATUS_UPDATE_ZERO(tmp);
581 STATUS_UPDATE_NEGATIVE(tmp);
582}
583
584static void
585ror_acc(void)
586{
587 uint8_t carry;
588 carry = regs.a & 1;
546 589
547 regs.a >>= 1; 590 regs.a >>= 1;
548 regs.a |= regs.status.carry << 7; 591 regs.a |= regs.status.carry << 7;
549 592
550 regs.status.carry = tmp; 593 regs.status.carry = carry;
551 STATUS_UPDATE_ZERO(regs.a); 594 STATUS_UPDATE_ZERO(regs.a);
552 STATUS_UPDATE_NEGATIVE(regs.a); 595 STATUS_UPDATE_NEGATIVE(regs.a);
553} 596}
554 597
555static void 598static void
556rti(uint8_t arg) 599ror(uint16_t mem)
600{
601 uint8_t carry, tmp;
602 carry = peek(mem) & 1;
603
604 tmp = (peek(mem) >> 1) | (regs.status.carry << 7);
605 memwrite(mem, tmp);
606
607 regs.status.carry = carry;
608 STATUS_UPDATE_ZERO(tmp);
609 STATUS_UPDATE_NEGATIVE(tmp);
610}
611
612static void
613rti(void)
557{ 614{
558 plp(); 615 plp();
559 regs.pc = PULL(); 616 regs.pc = PULL();
@@ -743,7 +800,7 @@ interpret(void)
743 cycles += 5; 800 cycles += 5;
744 break; 801 break;
745 case 0x0a: 802 case 0x0a:
746 asl(opcode_arg(AM_ACC)); 803 asl_acc();
747 cycles += 2; 804 cycles += 2;
748 break; 805 break;
749 case 0x06: 806 case 0x06:
@@ -954,10 +1011,6 @@ interpret(void)
954 eor(opcode_arg(AM_IND_Y)); 1011 eor(opcode_arg(AM_IND_Y));
955 cycles += 5; 1012 cycles += 5;
956 break; 1013 break;
957 case 0x1a:
958 inc(opcode_arg(AM_ACC));
959 cycles += 2;
960 break;
961 case 0xe6: 1014 case 0xe6:
962 inc(opcode_arg(AM_ZP)); 1015 inc(opcode_arg(AM_ZP));
963 cycles += 5; 1016 cycles += 5;
@@ -979,7 +1032,7 @@ interpret(void)
979 cycles += 2; 1032 cycles += 2;
980 break; 1033 break;
981 case 0xc8: 1034 case 0xc8:
982 iny(opcode_arg(AM_ACC)); 1035 iny();
983 cycles += 2; 1036 cycles += 2;
984 break; 1037 break;
985 case 0x4c: 1038 case 0x4c:
@@ -1075,7 +1128,7 @@ interpret(void)
1075 cycles += 4; 1128 cycles += 4;
1076 break; 1129 break;
1077 case 0x4a: 1130 case 0x4a:
1078 lsr(opcode_arg(AM_ACC)); 1131 lsr_acc();
1079 cycles += 2; 1132 cycles += 2;
1080 break; 1133 break;
1081 case 0x46: 1134 case 0x46:
@@ -1095,7 +1148,7 @@ interpret(void)
1095 cycles += 6; 1148 cycles += 6;
1096 break; 1149 break;
1097 case 0xea: 1150 case 0xea:
1098 nop(opcode_arg(AM_ACC)); 1151 nop();
1099 cycles += 2; 1152 cycles += 2;
1100 break; 1153 break;
1101 case 0x09: 1154 case 0x09:
@@ -1151,7 +1204,7 @@ interpret(void)
1151 cycles += 4; 1204 cycles += 4;
1152 break; 1205 break;
1153 case 0x2a: 1206 case 0x2a:
1154 rol(opcode_arg(AM_ACC)); 1207 rol_acc();
1155 cycles += 2; 1208 cycles += 2;
1156 break; 1209 break;
1157 case 0x26: 1210 case 0x26:
@@ -1171,7 +1224,7 @@ interpret(void)
1171 cycles += 6; 1224 cycles += 6;
1172 break; 1225 break;
1173 case 0x6a: 1226 case 0x6a:
1174 ror(opcode_arg(AM_ACC)); 1227 ror_acc();
1175 cycles += 2; 1228 cycles += 2;
1176 break; 1229 break;
1177 case 0x66: 1230 case 0x66:
@@ -1191,7 +1244,7 @@ interpret(void)
1191 cycles += 6; 1244 cycles += 6;
1192 break; 1245 break;
1193 case 0x40: 1246 case 0x40:
1194 rti(opcode_arg(AM_ACC)); 1247 rti();
1195 cycles += 6; 1248 cycles += 6;
1196 break; 1249 break;
1197 case 0x60: 1250 case 0x60: