diff options
| -rw-r--r-- | cpu.c | 103 |
1 files changed, 78 insertions, 25 deletions
| @@ -34,7 +34,6 @@ struct registers { | |||
| 34 | struct registers regs; | 34 | struct registers regs; |
| 35 | 35 | ||
| 36 | enum addressing_mode { | 36 | enum 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 | ||
| 201 | static void | 200 | static void |
| 202 | asl(uint8_t arg) | 201 | asl_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 | ||
| 214 | static void | 213 | static void |
| 214 | asl(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 | |||
| 226 | static void | ||
| 215 | bcc(uint8_t arg) | 227 | bcc(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 | ||
| 400 | static void | 412 | static void |
| 401 | iny(uint8_t arg) | 413 | iny(void) |
| 402 | { | 414 | { |
| 403 | regs.y++; | 415 | regs.y++; |
| 404 | 416 | ||
| @@ -454,7 +466,7 @@ ldy(uint8_t arg) | |||
| 454 | } | 466 | } |
| 455 | 467 | ||
| 456 | static void | 468 | static void |
| 457 | lsr(uint8_t arg) | 469 | lsr_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 | ||
| 467 | static void | 479 | static void |
| 468 | nop(uint8_t arg) | 480 | lsr(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 | |||
| 496 | static void | ||
| 497 | nop(void) | ||
| 469 | { | 498 | { |
| 470 | return; | 499 | return; |
| 471 | } | 500 | } |
| @@ -525,35 +554,63 @@ plp(void) | |||
| 525 | } | 554 | } |
| 526 | 555 | ||
| 527 | static void | 556 | static void |
| 528 | rol(uint8_t arg) | 557 | rol_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 | ||
| 541 | static void | 570 | static void |
| 542 | ror(uint8_t arg) | 571 | rol(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 | |||
| 584 | static void | ||
| 585 | ror_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 | ||
| 555 | static void | 598 | static void |
| 556 | rti(uint8_t arg) | 599 | ror(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 | |||
| 612 | static void | ||
| 613 | rti(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: |
