diff --git a/Processors/65816/Implementation/65816Storage.cpp b/Processors/65816/Implementation/65816Storage.cpp index 5281a1aa8..754918146 100644 --- a/Processors/65816/Implementation/65816Storage.cpp +++ b/Processors/65816/Implementation/65816Storage.cpp @@ -28,12 +28,15 @@ struct CPU::WDC65816::ProcessorStorageConstructor { case LDA: case LDX: case LDY: - // The access type for the rest of these ::Reads is arbitrary. + // The access type for the rest of these ::Reads is arbitrary; they're + // not relevantly either read or write. case JMP: case JSR: case JML: case JSL: case ASL: case DEC: case INC: case LSR: case ROL: case ROR: case TRB: case TSB: + case MVN: case MVP: + return AccessType::Read; case STA: case STX: case STY: case STZ: @@ -317,7 +320,7 @@ struct CPU::WDC65816::ProcessorStorageConstructor { read_modify_write(is8bit, target); } - // 6a. Absolute, Y; a, y. + // 7. Absolute, Y; a, y. static void absolute_y(AccessType type, bool is8bit, const std::function &target) { target(CycleFetchIncrementPC); // AAL. target(CycleFetchIncrementPC); // AAH. @@ -333,7 +336,7 @@ struct CPU::WDC65816::ProcessorStorageConstructor { read_write(type, is8bit, target); } - // 7. Accumulator; A. + // 8. Accumulator; A. static void accumulator(AccessType, bool, const std::function &target) { target(CycleFetchPC); // IO. @@ -343,6 +346,23 @@ struct CPU::WDC65816::ProcessorStorageConstructor { target(OperationPerform); target(OperationCopyDataToA); } + + // 9a. Block Move Negative [and] + // 9b. Block Move Positive. + // + // These don't fit the general model very well at all, hence the specialised fetch and store cycles. + static void block_move(AccessType, bool, const std::function &target) { + target(CycleFetchIncrementPC); // DBA. + target(CycleFetchIncrementPC); // SBA. + + target(CycleFetchBlockX); // SRC Data. + target(CycleStoreBlockY); // Dest Data. + + target(CycleFetchBlockY); // IO. + target(CycleFetchBlockY); // IO. + + target(OperationPerform); // [MVN or MVP] + } }; // TEMPORARY. Kneejerk way to get a step debug of 65816 storage construction. @@ -426,7 +446,7 @@ ProcessorStorage::ProcessorStorage() { /* 0x41 EOR (d, x) */ /* 0x42 WDM i */ /* 0x43 EOR d, s */ - /* 0x44 MVP xyc */ + /* 0x44 MVP xyc */ op(block_move, MVP); /* 0x45 EOR d */ /* 0x46 LSR d */ /* 0x47 EOR [d] */ @@ -443,7 +463,7 @@ ProcessorStorage::ProcessorStorage() { /* 0x51 EOR (d), y */ /* 0x52 EOR (d) */ /* 0x53 EOR (d, s), y */ - /* 0x54 MVN xyc */ + /* 0x54 MVN xyc */ op(block_move, MVN); /* 0x55 EOR d, x */ /* 0x56 LSR d, x */ /* 0x57 EOR [d],y */ diff --git a/Processors/65816/Implementation/65816Storage.hpp b/Processors/65816/Implementation/65816Storage.hpp index bb1840d78..dc7d73ae5 100644 --- a/Processors/65816/Implementation/65816Storage.hpp +++ b/Processors/65816/Implementation/65816Storage.hpp @@ -23,6 +23,11 @@ enum MicroOp: uint8_t { /// of the instruction buffer, throwing the result away. CycleFetchIncorrectDataAddress, + // Dedicated block-move cycles; these use the data buffer as an intermediary. + CycleFetchBlockX, + CycleFetchBlockY, + CycleStoreBlockY, + /// Stores a byte from the data buffer. CycleStoreData, /// Stores a byte to the data address from the data buffer and increments the data address. @@ -87,6 +92,10 @@ enum Operation: uint8_t { // These modify the value in the data buffer as part of a read-modify-write. ASL, DEC, INC, LSR, ROL, ROR, TRB, TSB, + // These merely decrement A, increment or decrement X and Y, and regress + // the program counter only if appropriate. + MVN, MVP, + /// Loads the PC with the operand from the data buffer. JMP,