diff options
| author | vin <git@vineetk.net> | 2024-06-10 22:56:06 +0530 |
|---|---|---|
| committer | vin <git@vineetk.net> | 2024-06-10 23:27:11 +0530 |
| commit | 3412a03a5ec20e1d3fb5dbd38888cf0c0eae09fc (patch) | |
| tree | 4b2a01e16a25a1887d4a4c64039e25c975c4e38a /cpu.c | |
| parent | dbb952a52b1b7168b4d1e98e9819d632ad16e087 (diff) | |
implement untested most of stack-related opcodes
Diffstat (limited to 'cpu.c')
| -rw-r--r-- | cpu.c | 123 |
1 files changed, 57 insertions, 66 deletions
| @@ -10,6 +10,11 @@ | |||
| 10 | #define STATUS_UPDATE_NEGATIVE(r) \ | 10 | #define STATUS_UPDATE_NEGATIVE(r) \ |
| 11 | (regs.status.negative = ((r & (1 << 7)) > 0)) | 11 | (regs.status.negative = ((r & (1 << 7)) > 0)) |
| 12 | 12 | ||
| 13 | #define PUSH(b) \ | ||
| 14 | (memwrite(0x0100 + regs.sp--, b)) | ||
| 15 | #define PULL() \ | ||
| 16 | (peek(0x0100 + regs.sp++)) | ||
| 17 | |||
| 13 | struct cpu_flags { | 18 | struct cpu_flags { |
| 14 | uint8_t carry : 1; | 19 | uint8_t carry : 1; |
| 15 | uint8_t zero : 1; | 20 | uint8_t zero : 1; |
| @@ -467,51 +472,48 @@ ora(uint8_t arg) | |||
| 467 | } | 472 | } |
| 468 | 473 | ||
| 469 | static void | 474 | static void |
| 470 | pha(uint8_t arg) | 475 | pha(void) |
| 471 | { | 476 | { |
| 472 | /* TODO: complete this */ | 477 | PUSH(regs.a); |
| 473 | } | 478 | } |
| 474 | 479 | ||
| 475 | static void | 480 | static void |
| 476 | php(uint8_t arg) | 481 | php(void) |
| 477 | { | 482 | { |
| 478 | /* TODO: complete this */ | 483 | uint8_t status; |
| 479 | } | ||
| 480 | 484 | ||
| 481 | static void | 485 | status = (regs.status.carry << 7) | (regs.status.zero << 6) |
| 482 | phx(uint8_t arg) | 486 | | (regs.status.interrupt_disable << 5) | (regs.status.decimal_mode << 4) |
| 483 | { | 487 | | (regs.status.brk << 3) | (regs.status.unused << 2) |
| 484 | /* TODO: complete this */ | 488 | | (regs.status.overflow << 1) | regs.status.negative; |
| 485 | } | ||
| 486 | 489 | ||
| 487 | static void | 490 | PUSH(status); |
| 488 | phy(uint8_t arg) | ||
| 489 | { | ||
| 490 | /* TODO: complete this */ | ||
| 491 | } | 491 | } |
| 492 | 492 | ||
| 493 | static void | 493 | static void |
| 494 | pla(uint8_t arg) | 494 | pla(void) |
| 495 | { | 495 | { |
| 496 | /* TODO: complete this */ | 496 | regs.a = PULL(); |
| 497 | } | ||
| 498 | 497 | ||
| 499 | static void | 498 | STATUS_UPDATE_ZERO(regs.a); |
| 500 | plp(uint8_t arg) | 499 | STATUS_UPDATE_NEGATIVE(regs.a); |
| 501 | { | ||
| 502 | /* TODO: complete this */ | ||
| 503 | } | 500 | } |
| 504 | 501 | ||
| 505 | static void | 502 | static void |
| 506 | plx(uint8_t arg) | 503 | plp(void) |
| 507 | { | 504 | { |
| 508 | /* TODO: complete this */ | 505 | uint8_t status; |
| 509 | } | ||
| 510 | 506 | ||
| 511 | static void | 507 | status = PULL(); |
| 512 | ply(uint8_t arg) | 508 | |
| 513 | { | 509 | regs.status.carry = (status & (1 << 7)) > 0; |
| 514 | /* TODO: complete this */ | 510 | regs.status.zero = (status & (1 << 6)) > 0; |
| 511 | regs.status.interrupt_disable = (status & (1 << 5)) > 0; | ||
| 512 | regs.status.decimal_mode = (status & (1 << 4)) > 0; | ||
| 513 | regs.status.brk = (status & (1 << 3)) > 0; | ||
| 514 | regs.status.unused = (status & (1 << 2)) > 0; | ||
| 515 | regs.status.overflow = (status & (1 << 1)) > 0; | ||
| 516 | regs.status.negative = (status & 1) > 0; | ||
| 515 | } | 517 | } |
| 516 | 518 | ||
| 517 | static void | 519 | static void |
| @@ -562,19 +564,19 @@ sbc(uint8_t arg) | |||
| 562 | } | 564 | } |
| 563 | 565 | ||
| 564 | static void | 566 | static void |
| 565 | sec(uint8_t arg) | 567 | sec(void) |
| 566 | { | 568 | { |
| 567 | regs.status.carry = 1; | 569 | regs.status.carry = 1; |
| 568 | } | 570 | } |
| 569 | 571 | ||
| 570 | static void | 572 | static void |
| 571 | sed(uint8_t arg) | 573 | sed(void) |
| 572 | { | 574 | { |
| 573 | regs.status.decimal_mode = 1; | 575 | regs.status.decimal_mode = 1; |
| 574 | } | 576 | } |
| 575 | 577 | ||
| 576 | static void | 578 | static void |
| 577 | sei(uint8_t arg) | 579 | sei(void) |
| 578 | { | 580 | { |
| 579 | regs.status.interrupt_disable = 1; | 581 | regs.status.interrupt_disable = 1; |
| 580 | } | 582 | } |
| @@ -607,7 +609,7 @@ tax(void) | |||
| 607 | } | 609 | } |
| 608 | 610 | ||
| 609 | static void | 611 | static void |
| 610 | tay(uint8_t arg) | 612 | tay(void) |
| 611 | { | 613 | { |
| 612 | regs.y = regs.a; | 614 | regs.y = regs.a; |
| 613 | 615 | ||
| @@ -616,13 +618,16 @@ tay(uint8_t arg) | |||
| 616 | } | 618 | } |
| 617 | 619 | ||
| 618 | static void | 620 | static void |
| 619 | tsx(uint8_t arg) | 621 | tsx(void) |
| 620 | { | 622 | { |
| 621 | /* TODO: complete this */ | 623 | regs.x = PULL(); |
| 624 | |||
| 625 | STATUS_UPDATE_ZERO(regs.x); | ||
| 626 | STATUS_UPDATE_NEGATIVE(regs.x); | ||
| 622 | } | 627 | } |
| 623 | 628 | ||
| 624 | static void | 629 | static void |
| 625 | txa(uint8_t arg) | 630 | txa(void) |
| 626 | { | 631 | { |
| 627 | regs.a = regs.x; | 632 | regs.a = regs.x; |
| 628 | 633 | ||
| @@ -631,13 +636,13 @@ txa(uint8_t arg) | |||
| 631 | } | 636 | } |
| 632 | 637 | ||
| 633 | static void | 638 | static void |
| 634 | txs(uint8_t arg) | 639 | txs(void) |
| 635 | { | 640 | { |
| 636 | /* TODO: complete this */ | 641 | PUSH(regs.x); |
| 637 | } | 642 | } |
| 638 | 643 | ||
| 639 | static void | 644 | static void |
| 640 | tya(uint8_t arg) | 645 | tya(void) |
| 641 | { | 646 | { |
| 642 | regs.a = regs.y; | 647 | regs.a = regs.y; |
| 643 | 648 | ||
| @@ -1121,35 +1126,19 @@ interpret(void) | |||
| 1121 | cycles += 5; | 1126 | cycles += 5; |
| 1122 | break; | 1127 | break; |
| 1123 | case 0x48: | 1128 | case 0x48: |
| 1124 | pha(opcode_arg(AM_ACC)); | 1129 | pha(); |
| 1125 | cycles += 3; | 1130 | cycles += 3; |
| 1126 | break; | 1131 | break; |
| 1127 | case 0x08: | 1132 | case 0x08: |
| 1128 | php(opcode_arg(AM_ACC)); | 1133 | php(); |
| 1129 | cycles += 3; | ||
| 1130 | break; | ||
| 1131 | case 0xda: | ||
| 1132 | phx(opcode_arg(AM_ACC)); | ||
| 1133 | cycles += 3; | ||
| 1134 | break; | ||
| 1135 | case 0x5a: | ||
| 1136 | phy(opcode_arg(AM_ACC)); | ||
| 1137 | cycles += 3; | 1134 | cycles += 3; |
| 1138 | break; | 1135 | break; |
| 1139 | case 0x68: | 1136 | case 0x68: |
| 1140 | pla(opcode_arg(AM_ACC)); | 1137 | pla(); |
| 1141 | cycles += 4; | 1138 | cycles += 4; |
| 1142 | break; | 1139 | break; |
| 1143 | case 0x28: | 1140 | case 0x28: |
| 1144 | plp(opcode_arg(AM_ACC)); | 1141 | plp(); |
| 1145 | cycles += 4; | ||
| 1146 | break; | ||
| 1147 | case 0xfa: | ||
| 1148 | plx(opcode_arg(AM_ACC)); | ||
| 1149 | cycles += 4; | ||
| 1150 | break; | ||
| 1151 | case 0x7a: | ||
| 1152 | ply(opcode_arg(AM_ACC)); | ||
| 1153 | cycles += 4; | 1142 | cycles += 4; |
| 1154 | break; | 1143 | break; |
| 1155 | case 0x2a: | 1144 | case 0x2a: |
| @@ -1237,15 +1226,15 @@ interpret(void) | |||
| 1237 | cycles += 5; | 1226 | cycles += 5; |
| 1238 | break; | 1227 | break; |
| 1239 | case 0x38: | 1228 | case 0x38: |
| 1240 | sec(opcode_arg(AM_ACC)); | 1229 | sec(); |
| 1241 | cycles += 2; | 1230 | cycles += 2; |
| 1242 | break; | 1231 | break; |
| 1243 | case 0xf8: | 1232 | case 0xf8: |
| 1244 | sed(opcode_arg(AM_ACC)); | 1233 | sed(); |
| 1245 | cycles += 2; | 1234 | cycles += 2; |
| 1246 | break; | 1235 | break; |
| 1247 | case 0x78: | 1236 | case 0x78: |
| 1248 | sei(opcode_arg(AM_ACC)); | 1237 | sei(); |
| 1249 | cycles += 2; | 1238 | cycles += 2; |
| 1250 | break; | 1239 | break; |
| 1251 | case 0x85: | 1240 | case 0x85: |
| @@ -1309,23 +1298,23 @@ interpret(void) | |||
| 1309 | cycles += 2; | 1298 | cycles += 2; |
| 1310 | break; | 1299 | break; |
| 1311 | case 0xa8: | 1300 | case 0xa8: |
| 1312 | tay(opcode_arg(AM_ACC)); | 1301 | tay(); |
| 1313 | cycles += 2; | 1302 | cycles += 2; |
| 1314 | break; | 1303 | break; |
| 1315 | case 0xba: | 1304 | case 0xba: |
| 1316 | tsx(opcode_arg(AM_ACC)); | 1305 | tsx(); |
| 1317 | cycles += 2; | 1306 | cycles += 2; |
| 1318 | break; | 1307 | break; |
| 1319 | case 0x8a: | 1308 | case 0x8a: |
| 1320 | txa(opcode_arg(AM_ACC)); | 1309 | txa(); |
| 1321 | cycles += 2; | 1310 | cycles += 2; |
| 1322 | break; | 1311 | break; |
| 1323 | case 0x9a: | 1312 | case 0x9a: |
| 1324 | txs(opcode_arg(AM_ACC)); | 1313 | txs(); |
| 1325 | cycles += 2; | 1314 | cycles += 2; |
| 1326 | break; | 1315 | break; |
| 1327 | case 0x98: | 1316 | case 0x98: |
| 1328 | tya(opcode_arg(AM_ACC)); | 1317 | tya(); |
| 1329 | cycles += 2; | 1318 | cycles += 2; |
| 1330 | break; | 1319 | break; |
| 1331 | default: | 1320 | default: |
| @@ -1353,6 +1342,8 @@ cpu_init(void) | |||
| 1353 | 1342 | ||
| 1354 | memset(®s.status, 0, sizeof(regs.status)); | 1343 | memset(®s.status, 0, sizeof(regs.status)); |
| 1355 | regs.status.unused = 1; | 1344 | regs.status.unused = 1; |
| 1345 | |||
| 1346 | cycles += 7; | ||
| 1356 | } | 1347 | } |
| 1357 | 1348 | ||
| 1358 | int | 1349 | int |
