57 Commits

Author SHA1 Message Date
sinamas
f8d041c01c test: ch3 wave ram read/write timing tests 2019-10-01 15:12:03 +02:00
sinamas
152c686af0 libgambatte: test/improve psg en frame seq inc double speed timing 2019-10-01 15:12:03 +02:00
sinamas
2061bb4be9 libgambatte: speed change work 2019-10-01 15:12:02 +02:00
sinamas
c2d7e9d8dd libgambatte: speed change work 2019-10-01 15:12:02 +02:00
sinamas
01681c9b67 Revert "libgambatte: psg speed change work"
This reverts commit b395a3963389d7fa1a8d7ab1f4935ce71c03a834.
2019-10-01 15:12:02 +02:00
sinamas
cfc2cac309 libgambatte: psg speed change work 2019-10-01 15:12:02 +02:00
sinamas
36a2ce0baa libgambatte: speed change work 2019-10-01 15:12:02 +02:00
sinamas
0fc5f09b75 libgambatte: add/test dmg oam writable at mode=2/mode=3 boundary
This is apparently different on the DMG.
Fixes mooneye-gb "lcdon_write_timing-GS" in "DMG" mode.
2019-10-01 15:12:02 +02:00
sinamas
36e4230bf6 libgambatte: also test late mode=2 vram reads on the dmg
This is apparently different on the DMG.
Fixes mooneye-gb "lcdon_timing-GS" in "DMG" mode.
2019-10-01 15:12:02 +02:00
sinamas
7369d76bc6 libgambatte: fix/test invalid lyc irq retrigger on lcd enable
This was found by running mooneye-gb "stat_lyc_onoff" (which now
passes),
2019-10-01 15:12:02 +02:00
sinamas
fb978976e1 libgambatte: add/test oam dma busy during src change
Fixes mooneye-gb "oam_dma_start".
2019-10-01 15:12:02 +02:00
sinamas
0628e4582b libgambatte: serial transfer div reset re work 2019-10-01 15:12:02 +02:00
sinamas
8427860e82 libgambatte: initial psg div reset re work 2019-10-01 15:12:02 +02:00
sinamas
2b17aa8490 libgambatte: tima tac change inc re work 2019-10-01 15:12:02 +02:00
sinamas
9e83d7f2bf libgambatte: add/test tima affected by div reset
Appears to be sufficient to pass mooneye-gb TIMA tests.
2019-10-01 15:12:02 +02:00
sinamas
cca5f5a5bf libgambatte: test/implement unused opcodes
halt CPU indefinitely on unused opcodes.
2019-10-01 15:12:02 +02:00
sinamas
cd2958c8f2 test: more lyc irq stat trigger boundary tests
Test after multiple speed changes for apparently more precise testing.
2019-10-01 15:12:02 +02:00
sinamas
3f12b5ff4b libgambatte: mode=1/lyc irq prevention period improvements/tests
Test after multiple speed changes for apparently more precise testing.
2019-10-01 15:12:02 +02:00
sinamas
adb8db3fe8 libgambatte: hdma period/trigger boundary improvements/tests
Test after multiple speed changes for apparently more precise testing.
2019-10-01 15:12:02 +02:00
sinamas
a900b7d169 libgambatte: more oam inaccessible period tests
Test after multiple speed changes for apparently more precise testing.
2019-10-01 15:12:02 +02:00
sinamas
7ce9d27a94 libgambatte: cgb palette inaccessible period improvements/tests
Test after multiple speed changes for apparently more precise testing.
2019-10-01 15:12:02 +02:00
sinamas
ad2ea7ff3b libgambatte: vram inaccessible period improvements/tests
Test after multiple speed changes for apparently more precise testing.
2019-10-01 15:12:02 +02:00
sinamas
3906275c36 libgambatte: wy/we mode=2 timing improvements/tests
Test after multiple speed changes for apparently more precise testing.
2019-10-01 15:12:02 +02:00
sinamas
85b140f6ab libgambatte: lyc irq ff45 increment trigger improvements/tests
Test after multiple speed changes for apparently more precise testing.
2019-10-01 15:12:02 +02:00
sinamas
443db3c874 libgambatte: mode=1/lyc irq ff45 trigger prevention improvements/tests
Test after multiple speed changes for apparently more precise testing.
2019-10-01 15:12:02 +02:00
sinamas
46acab9235 libgambatte: lyc irq ff45 trigger period improvements/tests
Test after multiple speed changes for apparently more precise testing.
2019-10-01 15:12:02 +02:00
sinamas
da5b3e054c libgambatte: mode=2 irq trigger boundary improvements/tests
Test after multiple speed changes for apparently more precise testing.
2019-10-01 15:12:02 +02:00
sinamas
ed1b4af800 test: more mode=1 irq trigger boundary tests
Test after multiple speed changes for apparently more precise testing.
2019-10-01 15:12:02 +02:00
sinamas
e058790102 test: more mode=0 irq trigger boundary tests
Test after multiple speed changes for apparently more precise testing.
2019-10-01 15:12:01 +02:00
sinamas
5f7aef2255 test: s/skew/offset/ 2019-10-01 15:12:01 +02:00
sinamas
18df9ddcba test: lcd/ppu non-ds non-4n offset stat tests
Test STAT mode changes and related IRQs at apparent non-4n, as compared
with normal, LCD/PPU cycle offsets in single speed mode after multiple
speed changes (timing across one frame of display is tested). This also
covers LYC IRQ timing (and the LYC flag, at least, in part).
2019-10-01 15:12:01 +02:00
sinamas
58d012706f libgambatte: non-ds non-4n offset ly timing re work
Test LY timing at apparent non-4n cycle offsets in single speed mode.
Adjust accordingly.
2019-10-01 15:11:50 +02:00
sinamas
43ad6f2094 libgambatte: hdma/gdma next instruction prefetch re work
Findings of note:
- The first byte of the next instruction appears to be fetched prior to
DMA.
2019-10-01 00:20:13 +02:00
sinamas
35d2db5be3 libgambatte: hdma halt/speed change re work
Findings of note:
- 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.
2019-10-01 00:20:13 +02:00
sinamas
d82a5281ec libgambatte: lcd/ppu odd offset ds timing re work
Test timing of STAT modes and related IRQs at an apparent odd cycle
offset in double speed mode (timing across one frame of display is
tested). LYC IRQ timing is also covered (and the LYC flag, at least, in
part). Adjust timing accordingly.
2019-10-01 00:16:49 +02:00
sinamas
a742b5e01d libgambatte: oam dma halt/speed change re work
OAM DMA appears to be inactive during halt as well as CGB speed change
(presumably stop in general). This adds some simple tests for that and
adjusts the implementation accordingly.

HDMA appears to be similarly affected (not covered by this change).
2019-10-01 00:16:49 +02:00
sinamas
6bb606be66 libgambatte: hdma versus interrupt precedence re work
Ensure that HDMA always takes precedence over interrupts, otherwise
occurring on the same instruction boundary, after eventual additional
cycles due to unhalt. As suggested by the included tests.
2019-10-01 00:16:49 +02:00
sinamas
6db94b78ea libgambatte: lcd disable lyc irq trigger re work
The LYC flag was previously found to remain in an eventual high state
after LCD disable. An extension to this is that it might be possible to
trigger LYC IRQs via STAT write in such a case and some testing (tests
included) suggests that this is possible. Adjust accordingly.
2019-10-01 00:16:49 +02:00
sinamas
01c9b09fc6 libgambatte: ds odd offset ly timing re work
Test LY timing at an apparent odd cycle offset in double speed mode
after multiple speed changes. Adjust accordingly.

Findings of note:
- In the event that LY is read at the boundary at which it gets
incremented, in an apparent window of one (single speed) cycle, the
resulting value appears to be LY & LY+1, where '&' denotes the bitwise
AND operation, and 'LY' is the value of LY prior to increment.
2019-10-01 00:16:34 +02:00
sinamas
9fd046a0e6 libgambatte: fix an off-by-one
Inspection revealed a likely off-by-one w.r.t. which LYC IRQs may be
prevented by a preceding mode=2 IRQ. Verified by some tests.
2019-09-30 17:51:48 +02:00
sinamas
1a0ce36a69 libgambatte: speed change re work
Findings of note:
- The LCD (PPU) can seemingly end up at a cycle offset relative to the
CPU that is a non-multiple of 4 when switching away from double speed
mode (as compared with normal). The behaviour appears equivalent to a
CPU tick being skipped relative to the LCD/PPU, which can result in 2
different offsets depending on whether the speed change is done at an
odd M-cycle (i.e. an odd multiple of 4 cycles in double speed mode).
This will also seemingly carry over to double speed mode upon another
speed change, and, repeated speed changes can seemingly produce all 4
offsets.
2019-09-30 17:45:53 +02:00
sinamas
be3034c206 libgambatte: lcdc enable ds timing re work and simplification
Test LCD/PPU timing relative to LCD/PPU display enable and improve
implementation accordingly.

Also fix and test an apparent inconsistency between mode=0 IRQ trigger
checks and event timing in the implementation.

Temporarily disable a speed change test that fails after these changes.
2019-09-30 16:30:27 +02:00
sinamas
4b884ec7de libgambatte: subject m2 irqs to lyc comparison latency
Some inspection suggested that an apparent latency of LYC comparisons,
when modifying the LYC register, which has previously been seen in
relation to prevention of "mode 0" IRQs (and to the triggering of LYC
IRQs), should, also, have consequence for when a "mode 2" IRQ may be
prevented as a result of a previous LYC IRQ (i.e. when an LYC write that
might influence this is done shortly before the "mode 2" IRQ occurs) on
the CGB revision tested -- and that there was a lack of such an effect
in the implementation. Some testing confirms that this, indeed, appears
to be the case.

Adjust accordingly.
2019-04-14 09:18:24 +02:00
sinamas
f1898abe95 libgambatte: more lcd mode 2 status irq re work
A "mode 2" IRQ at the beginning of line 144, when transitioning from
"mode 0" to "mode 1", has been discovered (this was found as a result of
adding tests that verified the timing of each "mode 2" IRQ for the first
two frames of display after LCD display enable).

The time periods for when "mode 0" or "mode 2" IRQs may be triggered via
STAT writes were also found to be slightly different on the CGB revision
tested for the "mode 0" to "mode 1" transition, as compared with for the
0 to 2 transition (slightly longer and slightly shorter, respectively --
up to one instruction as seen from the CPU [in "double speed" mode and
independent of "double speed", respectively]). No difference was seen on
the DMG revision tested.

Adding more test coverage, after some inspection, for the case where an
LYC status flag IRQ period is at its end, and a "mode 2" status flag IRQ
is triggered via STAT write, also uncovered an implementation deficiency
that could allow an IRQ trigger that should have been prevented on the
CGB in "double speed" mode (in a time window of up to one instruction)
-- hence the movement of the relevant check in the implementation.
Furthermore, this also uncovered that, in the case that the LYC status
flag IRQ is disabled shortly before a "mode 2" IRQ at LY=0 on the CGB,
then, that there is a similar latency as for when the "mode 1" IRQ is
disabled w.r.t. whether this avoids preventing the "mode 2" IRQ from
occurring (in non-"double speed" mode this can be observed as an up to
one instruction difference from the CPU, in "double speed" mode it
appears to be irrelevant) -- hence the amendment in the implementation
to the "mode 1" enable bit select with the LYC enable bit to the code
that avoids a late enable from being of consequence for the "mode 2" IRQ
assertion event.

Adjust accordingly (the "mode 1"-related changes result from the fact
that a preceding "mode 2" IRQ may prevent the triggering of a subsequent
"mode 1" IRQ).
2019-04-10 09:11:40 +02:00
sinamas
425e56083f libgambatte: further lcd enable timing re work
More detailed timing tests uncovered some differences w.r.t. the timing
of the very first line after LCD display enable (an additional 2 cycles
of delay before "mode 3" begins).

("Double speed" testing with some related simplifications is in progress
-- which should, finally, get rid of some of the odd "ds" offsets
[emphasis has been on implementing observed behaviour].)
2019-04-08 23:51:48 +02:00
sinamas
0b87d54229 libgambatte: halt re work
Findings of note:
- The "skip" glitch, when halt is cancelled early, is not limited to the
DMG; it is also present on the CGB revision tested and on a GBA SP.
- The skip glitch also applies to the case when IME is high, in which
case, the pushed return address is decremented (so that it points to the
halt instruction, rather than to the subsequent instruction; the halt is
repeated on an eventual ret).
- The timing for when pending interrupts can cancel the halt state is
different on the DMG (as in they can be detected earlier as compared
with on the CGB revision tested), excepting the first/second M-cycle.
(To facilitate this, information about when IRQs occur is propagated in
the implementation.)
2019-03-31 23:46:26 +02:00
sinamas
0d2cb208a3 test: remove some obsolete stuff 2019-03-31 23:43:59 +02:00
sinamas
7f31aca5c2 verify DMG TIMA test output 2019-03-31 23:42:46 +02:00
sinamas
ac291bc950 libgambatte: irq timing detail re work
Besides the improved coverage, this uncovered a few off-by-ones w.r.t.
IF writes, and IRQ ACK timing.

The IF write adjustment is a one-liner that has as consequence that mode
0 IRQs for lines with particular timing (e.g. due to scx offsets and/or
object positions) can be overwritten at up to one instruction earlier
than previously.

The ACK-related adjustments have consequence for cases when the same IRQ
is reasserted shortly after it has effected an interrupt in the sense
that, for the affected IRQs, the time window for when this will be
ignored is up to one instruction longer.
2019-03-25 23:31:04 +01:00
sinamas
61e51c9417 libgambatte: irq ack timing re work 2019-03-18 13:46:08 +01:00