I've been reading the MSP430 manual, thinking about making an emulator for it. (I know some already exist) There is one thing that doesn't seem to be made clear. Many of the instructions have very clear diagrams showing sample program bytes, src and dst RAM areas, and the exact changes to the dst area.
An exception is PUSH.B.
The manual is clear that byte operations with a memory src or dst load or store a single byte and do nothing else, while byte operations with a register dst store 0 into the hi byte.
PUSH.B decrements SP then stores the data at @SP.
As the stack must always be aligned, the decrement is by 2, not 1.
Does the write to @SP then modify only that 1 byte, leaving 1(SP) undisturbed? This seems to follow from the description given. Or is the write done as a 16 bit write, zeroing the hi byte?
Oh. One other thing is not at all clear. R3 seems to be a "throw the result away" register, as any read from it, no matter the addressing mode, gives a constant. Is it legal to use R3 as a destination register for any instruction, even though the result will be invisible?
The NOP mnemonic is shows as generating "MOV #0,R3" (which in turn is encoded as "MOV R3,R3"). Is that a special case, or all instructions with destination R3 should be accepted but basically be no-ops (except for the effect on flags)? What about with addressing mode 1 i.e. offset(R3)? Should the instruction be accepted? Should the offset be read from the program stream? What should it be added to? Does that give another way of encoding absolute addressing? (Absolute addressing officially uses R2/SR as the apparent base register)
Or, can you use R3 as the dst of an instruction to ACTUALLY store a value there, but it's invisible except if used as a base address for a dst using addressing mode 1?
Similarly, what happens if you use R3 as the src/dst register for a single operand instruction?
I imagine "PUSH R3", "PUSH 0(R3)", "PUSH @R3", "PUSH @R3+" should actually push 0,1,2,-1 respectively i.e. the same as any instruction using R3 as a src. The PUSH instruction specifies that the register is used in SRC mode.
But the other single operand instructions (let's say SWPB) specify that the register is used as a DST, albeit with a 2-bit address mode field. Can all four addressing modes be used? If so, is the address generated used for both src data and the dst, or is constant generation used for the src? So should "MOV #1234h,R3; SWPB R3; MOV #1,1(R3)" end up storing 0001h into memory address 3413h? And "MOV #1234h,R3; MOV #5678h, &1234h; SWPB @R3" ends up with 7856h in memory at address 1234h?
Of course, you're not supposed to write programs like that, but what is a CPU/emulator supposed to do if it executes one?