245 Commits

Author SHA1 Message Date
sinamas
40ce0c2732 libgambatte: non-functional given ascii-compatible charset 2019-10-01 15:12:01 +02:00
sinamas
3a515bc4bd libgambatte: ensure save states are always initialised 2019-10-01 15:12:01 +02:00
sinamas
1ee21d442b libgambatte/statesaver: misc. non-functional 2019-10-01 15:12:01 +02:00
sinamas
a30cbca986 libgambatte: attempt to better support old save states 2019-10-01 15:12:01 +02:00
sinamas
1348dcc5e5 libgambatte: s/skip/prefetched/ 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
26d9edde65 libgambatte: simplify halt prefetch/skip handling a bit 2019-10-01 00:20:13 +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
93db07a526 libgambatte: minor re todo 2019-09-30 17:51:48 +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
a9307ea5c5 libgambatte: preliminary speculative lcd timing adjustments
Preliminary speculative timing adjustments prior to testing in odd LCD
cycle offset states.

Reuse some constants to ensure consistency between some trigger windows
and respective trigger events.
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
dffa1523fb libgambatte: minor fixme/todo 2019-05-13 22:48:02 +02:00
sinamas
11eb53b99d libgambatte: minor fixme comment 2019-04-17 01:16:09 +02:00
sinamas
b0f83b69da libgambatte: misc non-functional 2019-04-15 07:31:58 +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
a7f55b3de7 libgambatte: simplify a bit 2019-04-14 09:15:36 +02:00
sinamas
f490326180 libgambatte: reduce number of "stat regs" 2019-04-11 23:55:28 +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
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
cfad0d9a65 libgambatte: avoid some inefficiencies 2019-03-19 19:59:07 +01:00
sinamas
61e51c9417 libgambatte: irq ack timing re work 2019-03-18 13:46:08 +01:00
sinamas
659b5508b3 libgambatte: irq precedence timing re work
fixes Pinball Deluxe.
2019-03-17 18:05:06 +01:00
sinamas
588dbd8386 libgambatte: misc non-functional 2019-03-17 18:05:06 +01:00
sinamas
1d311d98c0 libgambatte: avoid GCC (8.1.0 x86[-64]) regression 2019-03-07 22:21:30 +01:00
sinamas
e644525a43 libgambatte: silence GCC warnings 2019-03-07 21:39:04 +01:00
sinamas
62e64bb655 libgambatte: avoid long line 2019-03-04 23:59:34 +01:00
sinamas
8ab5b681f9 libgambatte: misc non-functional 2019-03-04 23:51:05 +01:00
sinamas
af9e3e16a3 libgambatte: misc non-functional 2019-03-03 23:33:59 +01:00
sinamas
f1ec850332 libgambatte: misc non-functional 2019-02-27 14:51:27 +01:00
sinamas
2195c64b0e libgambatte: fix up indentation 2019-02-25 20:37:31 +01:00
sinamas
b2ecf2db55
Merge pull request #15 from jkotlinski/fix-mbc5-romswitching
Fixed MBC5 rom bank switching
2019-02-24 19:46:12 +01:00
sinamas
9b693febdb
Merge pull request #12 from Ben10do/more-sram-banks
Enable support for more than four SRAM banks
2019-02-24 19:45:39 +01:00
sinamas
2b474ca1bc libgambatte: oam dma re work 2019-02-24 19:00:26 +01:00
sinamas
326db1999d libgambatte: misc non-functional 2019-02-24 19:00:11 +01:00
Johan Kotlinski
c421ae0f5f Fixed MBC5 rom bank switching 2018-05-26 22:22:21 +02:00
Ben10do
69ba252346 Enable support for more than four SRAM banks
More cases of the SRAM flag of the cartridge header are now considered, allowing 64KiB and 128KiB saves to be made (with 8 and 16 banks, respectively).

The extra space is taken advantage of by software such as LSDj.
2017-02-05 19:42:59 +00:00
sinamas
5695cd55f2 libgambatte: avoid bools in save state struct.
ensure boolean conversion on assignment.
2015-03-22 17:29:47 +01:00
sinamas
e8292b7bed Merge pull request #5 from bentley/fsfaddr
Update FSF address.
2015-03-22 17:13:45 +01:00
sinamas
46e06da8bd libgambatte: push return address after pc mod.
unsurprising that the call target is fetched prior to
pushing the return address (sufficiently so to verify
this based on wtf-factor alone, really). more surprising
that the 4 cycle delay that accompanies pc mods also
precedes it.

"woody woodpecker racing" barely avoids an oam dma bus
conflict due to this fact.
2014-12-14 11:13:14 +01:00
Anthony J. Bentley
cc336279d1 Update FSF address. 2014-11-19 03:37:12 -07:00