Commit Graph

6 Commits

Author SHA1 Message Date
Tim Allen d4876a831f Update to v103r07 release.
byuu says:

Changelog:

  - gba/cpu: massive code cleanup effort
  - gba/cpu: DMA can run in between active instructions¹
  - gba/cpu: added two-cycle startup delay between DMA activation and
    DMA transfers²
  - processor/spc700: BBC, BBC, CBNE cycle 4 is an idle cycle
  - processor/spc700: ADDW, SUBW, MOVW (read) cycle 4 is an idle cycle

¹: unfortunately, this causes yet another performance penalty for the
poor GBA core =( Also, I think I may have missed disabling DMAs while
the CPU is stopped. I'll fix that in the next WIP.

²: I put the waiting counter decrement at the wrong place, so this
doesn't actually work. Needs to be more like
this:

    auto CPU::step(uint clocks) -> void {
      for(auto _ : range(clocks)) {
        for(auto& timer : this->timer) timer.run();
        for(auto& dma : this->dma) if(dma.active && dma.waiting) dma.waiting--;
        context.clock++;
      }
      ...

    auto CPU::DMA::run() -> bool {
      if(cpu.stopped() || !active || waiting) return false;

      transfer();
      if(irq) cpu.irq.flag |= CPU::Interrupt::DMA0 << id;
      if(drq && id == 3) cpu.irq.flag |= CPU::Interrupt::Cartridge;
      return true;
    }

Of course, the real fix will be restructuring how DMA works, so that
it's always running in parallel with the CPU instead of this weird
design where it tries to run all channels in some kind of loop until no
channels are active anymore whenever one channel is activated.

Not really sure how to design that yet, however.
2017-07-05 15:29:27 +10:00
Tim Allen 16f736307e Update to v103r06 release.
byuu says:

Changelog:

  - processor/spc700: restored fetch/load/store/pull/push shorthand
    functions
  - processor/spc700: split functions that tested the algorithm used (`op
    != &SPC700:...`) to separate instructions
      - mostly for code clarity over code size: it was awkward having
        cycle counts change based on a function parameter
  - processor/spc700: implemented Overload's new findings on which
    cycles are truly internal (no bus reads)
  - sfc/smp: TEST register emulation has been vastly improved¹

¹: it turns out that TEST.d4,d5 is the external clock divider (used
when accessing RAM through the DSP), and TEST.d6,d7 is the internal
clock divider (used when accessing IPLROM, IO registers, or during idle
cycles.)

The DSP (24576khz) feeds its clock / 12 through to the SMP (2048khz).
The clock divider setting further divides the clock by 2, 4, 8, or 16.
Since 8 and 16 are not cleanly divislbe by 12, the SMP cycle count
glitches out and seems to take 10 and 2 clocks instead of 8 or 16. This
can on real hardware either cause the SMP to run very slowly, or more
likely, crash the SMP completely until reset.

What's even stranger is the timers aren't affected by this. They still
clock by 2, 4, 8, or 16.

Note that technically I could divide my own clock counters by 24 and
reduce these to {1,2,5,10} and {1,2,4,8}, I instead chose to divide by
12 to better illustrate this hardware issue and better model that the
SMP clock runs at 2048khz and not 1024khz.

Further, note that things aren't 100% perfect yet. This seems to throw
off some tests, such as blargg's `test_timer_speed`. I can't tell how
far off I am because blargg's test tragically doesn't print out fail
values. But you can see the improvements in that higan is now passing
all of Revenant's tests that were obviously completely wrong before.
2017-07-03 17:24:47 +10:00
Tim Allen 78f341489e Update to v103r03 release.
byuu says:

Changelog:

  - md/psg: fixed output frequency rate regression from v103r02
  - processor/m68k: fixed calculations for ABCD, NBCD, SBCD [hex\_usr,
    SuperMikeMan]
  - processor/spc700: renamed abbreviated instructions to functional
    descriptions (eg `XCN` → `ExchangeNibble`)
  - processor/spc700: removed memory.cpp shorthand functions (fetch,
    load, store, pull, push)
  - processor/spc700: updated all instructions to follow cycle behavior
    as documented by Overload with a logic analyzer

Once again, the changes to the SPC700 core are really quite massive. And
this time it's not just cosmetic: the idle cycles have been updated to
pull from various memory addresses. This is why I removed the shorthand
functions -- so that I could handle the at-times very bizarre addresses
the SPC700 has on its address bus during its idle cycles.

There is one behavior Overload mentioned that I don't emulate ... one of
the cycles of the (X) transfer functions seems to not actually access
the $f0-ff internal SMP registers? I don't fully understand what
Overload is getting at, so I haven't tried to support it just yet.

Also, there are limits to logic analyzers. In many cases the same
address is read from twice consecutively. It is unclear which of the two
reads the SPC700 actually utilizes. I tried to choose the most logical
values (usually the first one), but ... I don't know that we'll be able
to figure this one out. It's going to be virtually impossible to test
this through software, because the PC can't really execute out of
registers that have side effects on reads.
2017-06-28 17:24:46 +10:00
Tim Allen 3517d5c4a4 Update to v103r02 release.
byuu says:

Changelog:

  - fc/apu: improved phase duty cycle emulation (mode 3 is 25% phase
    inverted; counter decrements)
  - md/apu: power/reset do not cancel 68K bus requests
  - md/apu: 68K is not granted bus access on Z80 power/reset
  - md/controller: replaced System::Peripherals with ControllerPort
    concept
  - md/controller: CTRL port is now read-write, maintains value across
    controller changes (and soon, soft resets)
  - md/psg: PSG sampling rate unintentionally modified¹
  - processor/spc700: improve cycle timing of (indirect),y instructions
    [Overload]
  - processor/spc700: idle() cycles actually read from the program
    counter; much like the 6502 [Overload]
      - some of the idle() cycles should read from other addresses; this
        still needs to be supported
  - processor/spc700: various cleanups to instruction function naming
  - processor/z80: prefix state (HL→IX,IY override) can now be
    serialized
  - icarus: fix install rule for certain platforms (it wasn't buggy on
    FreeBSD, but was on Linux?)

¹: the clock speed of the PSG is oscillator/15. But I was setting the
sampling rate to oscillator/15/16, which was around 223KHz. I am not
sure whether the PSG should be outputting at 3MHz or 223KHz. Amazingly
... I don't really hear a difference either way `o_O` I didn't actually
mean to make this change; I just noticed it after comparing the diff
between r01 and r02. If this turns out to be wrong, set

    stream = Emulator::audio.createStream(1, frequency() / 16.0);

in md/psg.cpp to revert this change.
2017-06-27 11:18:28 +10:00
Tim Allen e7806dd6e8 Update to v102r27 release.
byuu says:

Changelog:

  - processor/gsu: minor code cleanup
  - processor/hg51b: renamed reg(Read,Write) to register(Read,Write)
  - processor/lr35902: minor code cleanup
  - processor/spc700: completed code cleanup (sans disassembler)
      - no longer uses internal global state inside instructions
  - processor/spc700: will no longer hang the emulator if stuck in a WAI
    (SLEEP) or STP (STOP) instruction
  - processor/spc700: fixed bug in handling of OR1 and AND1 instructions
  - processor/z80: minor code cleanup
  - sfc/dsp: revert to initializing registers to 0x00; save for
    ENDX=random(), FLG=0xe0 [Jonas Quinn]

Major testing of the SNES game library would be appreciated, now that
its CPU cores have all been revised.

We know the DSP registers read back as randomized data ... mostly, but
there are apparently internal latches, which we can't emulate with the
current DSP design. So until we know which registers have separate
internal state that actually *is* initialized, I'm going to play it safe
and not break more games.

Thanks again to Jonas Quinn for the continued research into this issue.

EDIT: that said ... `MD works if((ENDX&0x30) > 0)` is only a 3:4 chance
that the game will work. That seems pretty unlikely that the odds of it
working are that low, given hardware testing by others in the past :/ I
thought if worked if `PITCH != 0` before, which would have been way more
likely.

The two remaining CPU cores that need major cleanup efforts are the
LR35902 and ARM cores. Both are very large, complicated, annoying cores
that will probably be better off as full rewrites from scratch. I don't
think I want to delay v103 in trying to accomplish that, however.

So I think it'll be best to focus on allowing the Mega Drive core to not
lock when processors are frozen waiting on a response from other
processors during a save state operation. Then we should be good for a
new release.
2017-06-19 12:07:54 +10:00
Tim Allen 50411a17d1 Update to v102r26 release.
byuu says:

Changelog:

  - md/ym2612: initialize DAC sample to center volume [Cydrak]
  - processor/arm: add accumulate mode extra cycle to mlal [Jonas
    Quinn]
  - processor/huc6280: split off algorithms, improve naming of functions
  - processor/mos6502: split off algorithms
  - processor/spc700: major revamp of entire core (~50% completed)
  - processor/wdc65816: fixed several bugs introduced by rewrite

For the SPC700, this turns out to be very old code as well, with global
object state variables, those annoying `{Boolean,Natural}BitField` types,
`under_case` naming conventions, heavily abbreviated function names, etc.
I'm working to get the code to be in the same design as the MOS6502,
HuC6280, WDC65816 cores, since they're all extremely similar in terms of
architectural design (the SPC700 is more of an off-label
reimplementation of a 6502 core, but still.)

The main thing left is that about 90% of the actual instructions still
need to be adapted to not use the internal state (`aa`, `rd`, `dp`,
`sp`, `bit` variables.) I wanted to finish this today, but ran out of
time before work.

I wouldn't suggest too much testing just yet. We should wait until the
SPC700 core is finished for that. However, if some does want to and
spots regressions, please let me know.
2017-06-16 10:06:17 +10:00