jc-SpaceXp / cNES

NES emulator written in C and targeted for Linux.
zlib License
6 stars 4 forks source link

Single cycle branch decoder is incorrect #10

Open jc-SpaceXp opened 1 year ago

jc-SpaceXp commented 1 year ago

Followed appendix A of the synertek hardware manual to generate the single cycle code. The branch instructions in that document are incorrect.

Funny enough it is correct in the programmers manual from synertek.

jc-SpaceXp commented 1 year ago

Hardware manual:

  |------+-----------------------------+----------+-----+---------------------------------------------|
  | Tn   | Address Bus                 | Data Bus | R/W | Comments                                    |
  |------+-----------------------------+----------+-----+---------------------------------------------|
  | T0   | PC                          | OP CODE  |   1 | Fetch OP CODE                               |
  | T1   | PC + 1                      | Offset   |   1 | Fetch branch offset                         |
  | T2*  | PC + 2 + offset (w/o carry) | OP CODE  |   1 | Offset is added to PC                       |
  | T3** | PC + 2 + offset + carry     | OP CODE  |   1 | Carry added to branch offset (page crossed) |
  |------+-----------------------------+----------+-----+---------------------------------------------|

* and ** are potentially skipped cycles

jc-SpaceXp commented 1 year ago

Programmers manual

 |------+-----------------------------+--------------------+-----+---------------------------------------------|
 | Tn   | Address Bus                 | Data Bus           | R/W | Comments                                    |
 |------+-----------------------------+--------------------+-----+---------------------------------------------|
 | T0   | PC                          | OP CODE            |   1 | Fetch OP CODE                               |
 | T1   | PC + 1                      | Offset             |   1 | Fetch branch offset                         |
 | T2*  | PC + 2                      | MAYBE NEXT OP CODE |   1 | Fetch branch offset                         |
 | T3** | PC + 2 + offset (w/o carry) | MAYBE NEXT OP CODE |   1 | Offset is added to PC (no page cross)       |
 | T0   | PC + 2 + offset + carry     | MAYBE NEXT OP CODE |   1 | Carry added to branch offset (page crossed) |
 |------+-----------------------------+--------------------+-----+---------------------------------------------|
jc-SpaceXp commented 1 year ago

Issue is hardware manual goes PC, PC+1, PC+2+offset (w/o carry)

(When it should go PC, PC+1, PC+2, then PC+2+offset (w/o carry))

Offset has only just been fetched and can't appear on T2 address bus on the next phi1 clock which is what the hardware manual suggests.

jc-SpaceXp commented 1 year ago

It's a minor issue that doesn't effect cNES in any negative way, unless of course we read from a memory mapped address, in which case side effects are expected, since fetch from PC + 2 is skipped we might miss subtle side effects.