MEGA65 / mega65-core

MEGA65 FPGA core
Other
239 stars 84 forks source link

STQ CPU instruction affects status register flags, but shouldn't #661

Open grubi opened 1 year ago

grubi commented 1 year ago

Test Environment (required) MEGA65 with core 0.95 93D55F0, ROM 920377.

Describe the bug When executing the STQ CPU instruction, zero flag (Z) and negative flag (N) in the status register are affected - while in the Mega65 documentation (mega65-book) is is stated that STQ does not affect any status flags. This can lead to side effects when the programmer is not aware of that behaviour.

To Reproduce Steps to reproduce the behavior:

  1. Use MONITOR to enter the following program: A1800 LDA #$01 LDX #$00 (sets zero flag) STQ $1900 (changes zero flag according to A register, but shouldn't) BRK (jump into monitor and displays status register)

  2. Execute the program with J 1800 You will see that the zero flag is clear (A was not zero), even if it should be set according to the LDX #0 instruction.

  3. Change the first line to: A1800 LDA #$00 and execute again. Now the zero flag is set.

Expected behavior STQ should not modify any status register flags, as documented in the mega65-book.

Additional context The problem seems to occur because of the $42 $42 (NEG NEG) prefix of the STQ instruction. The NEG is actually executed by the CPU and sets the status flags according to the accumulator. A possible solution, as discussed with lydon, could be a shadow status register. The first NEG could copy the status register into the shadow register. When the instruction that follows the double-NEG is actrually modfied by the NEG NEG, the status register could be restored. Open questions: What if an interrupt occurs in between?

lgblgblgb commented 1 year ago

No interrupts should be able to be accepted during execution of an opcode, and STQ itself is a "compound" opcode. In fact, if it is interruptable, even the result what STQ stores would be invalid not only flags (because then it is forgot that it was a "prefixed' opcode and would execute as a normal STA only ie what the opcode would mean without the NEG NEG stuff).