Opcode
Handling interrupts and pushing the program counter to the stack.:: ON THIS PAGE 2
Shift Instructions
Implementing the NES 6502 in Rust has been quiet the adventure. I was trying to keep the logic simple, avoid magic numbers and make it easy to read. Then I got to the shift instructions...
By no means am I an expert in bitwise logic, in fact I actively avoid it when solving leetcode or any other problems. Luckily it does not come up a whole lot in day to day life for me. But I knew implementing the 6502, this was only going to be a matter of time.
ASL - Arithmetic Shift Left
- ASL shifts either the accumulator or the address memory location 1 bit to the left.
- Bit 0 always being set to 0 and the input bit 7 being stored in the carry flag.
- ASL either shifts the accumulator left 1 bit or is a read/modify/write instruction that affects only memory.
INITIAL STATE
We have the value 172 (Binary 1010 1100).
[ Carry ] [ Bit 7 ............ Bit 0 ]
+---------+ +---------------------------+
| ? | | 1 0 1 0 1 1 0 0 |
+---------+ +---------------------------+
^
|
This '1' is about to fall off!
THE SHIFT (<<<<)
Everything moves one spot to the left. A new '0' is always inserted at the right (Bit 0).
/---- The '1' is pushed out...
|
v
+---------+ +---------------------------+
| 1 | <------- | 0 1 0 1 1 0 0 0 | <-- [0]
+---------+ +---------------------------+ New 0
^ enters
|
CAPTURED!
WHY WE NEED CARRY:
- Data Preservation: That '1' isn't lost; it's saved in the Status Register.
- Multi-Byte Math: If this was the lower half of a 16-bit number, the next instruction (ROL) would pick this '1' up and move it into the upper byte.
Where I Went Wrong
I wanted a helper function called shift_left (how imaginative right?)
What I imagined would happen is this would check if the 7th bit is 1, if so set the carry flag, otherwise clear it.
Right? WRONG
1 << 7equals 128 (1000 0000).- ANDing
datawith128is either0or128. - The result will never be
1!
The Fix
Read-Modify-Write
Up until this point I was fine using:
pub Until I realized that these instructions technically do both a read and a write.
(it's a little more complex than that but I'll get into that later).
I could have made a ReadModifyWrite but since this is the only type of instruction that does both a read and a write, I decided to keep it simple.
OpCodes
