gbdev / pandocs

The single, most comprehensive Game Boy technical reference.
https://gbdev.io/pandocs/
Creative Commons Zero v1.0 Universal
617 stars 93 forks source link

Document more HDMA behaviours #561

Open ISSOtm opened 3 months ago

ISSOtm commented 3 months ago

Several HDMA behaviours are described in https://github.com/endrift/gambatte/commit/35d2db5be3a1407194ee163e16a512f31d8828ef, but not in Pan Docs. They should be added.

  • HDMA appears inactive during halt/speed change (presumably stop).
  • HDMA appears to trigger on unhalt if halt occurs during STAT mode!=0 and unhalt occurs during STAT mode=0, if enabled, and similarly for speed change (presumably stop).
  • If the mode=0 transition that would otherwise trigger an HDMA occurs during the first M-cycle of halt, HDMA appears to occur at unhalt time, and the next PC increment appears to be skipped (i.e. the next byte after the halt opcode will be fetched twice). The (semi-)prefetched instruction at halt time is executed after unhalt and HDMA.
  • If the mode=0 transition that would otherwise trigger an HDMA occurs during the first M-cycle of speed change (stop), HDMA appears to occur during the stopped state if in single speed mode prior to speed change, or upon wake-up from stop if in double speed mode prior to speed change (similarly as for the halt case). In both cases the prefetched (at stop time) second byte of the stop instruction appears to be used as the first byte of the next instruction after speed change. If, as a result of the above, HDMA occurs during the stopped state, HDMA appears to get disabled after the first 16 bytes have been transferred, and, rather than decrement the length count, the most significant bit (80h) is seemingly simply set in the HDMA5 register.
  • Additional HDMA triggers (mode=0 transitions) appear to be ignored during HDMA execution excepting the last 4 cycles of HDMA (i.e. no additional HDMA will occur until the next mode=0 transition after HDMA is done less the last 4 cycles).
  • In the event that HDMA is triggered unconditionally on unhalt or upon wake-up from speed change (presumably stop), as a result of halt/stop occurring at the mode=0 transition, the execution of the next (semi- prefetched) instruction appears to occur 4 cycles earlier than for other DMA events. The execution of this instruction appears to occur prior to pending interrupts or eventual additional HDMAs.

Additionally, the commit has test ROMs that we can rely on. (Note that endrift's fork is being used, as @sinamas has removed all history from his own repo. We might want to use gb-archive for this, though not auto-sync it, obviously.)