Commit Graph

7 Commits

Author SHA1 Message Date
Tim Allen 68f04c3bb8 Update to v102r10 release.
byuu says:

Changelog:

  - removed Emulator::Interface::Capabilities¹
  - MS: improved the PSG emulation a bit
  - MS: added cheat code support
  - MS: added save state support²
  - MD: emulated the PSG³

¹: there's really no point to it anymore. I intend to add cheat codes
to the GBA core, as well as both cheat codes and save states to the Mega
Drive core. I no longer intend to emulate any new systems, so these
values will always be true. Further, the GUI doesn't respond to these
values to disable those features anymore ever since the hiro rewrite, so
they're double useless.

²: right now, the Z80 core is using a pointer for HL-\>(IX,IY)
overrides. But I can't reliably serialize pointers, so I need to convert
the Z80 core to use an integer here. The save states still appear to
work fine, but there's the potential for an instruction to execute
incorrectly if you're incredibly unlucky, so this needs to be fixed as
soon as possible. Further, I still need a way to serialize
array<T, Size> objects, and I should also add nall::Boolean
serialization support.

³: I don't have a system in place to share identical sound chips. But
this chip is so incredibly simple that it's not really much trouble to
duplicate it. Further, I can strip out the stereo sound support code
from the Game Gear portion, so it's even tinier.

Note that the Mega Drive only just barely uses the PSG. Not at all in
Altered Beast, and only for a tiny part of the BGM music on Sonic 1,
plus his jump sound effect.
2017-02-23 08:25:01 +11:00
Tim Allen d76c0c7e82 Update to v102r08 release.
byuu says:

Changelog:

  - PCE: restructured VCE, VDCs to run one scanline at a time
  - PCE: bound VDCs to 1365x262 timing (in order to decouple the VDCs
    from the VCE)
  - PCE: the two changes above allow save states to function; also
    grants a minor speed boost
  - PCE: added cheat code support (uses 21-bit bus addressing; compare
    byte will be useful here)
  - 68K: fixed `mov *,ccr` to read two bytes instead of one [Cydrak]
  - Z80: emulated /BUSREQ, /BUSACK; allows 68K to suspend the Z80
    [Cydrak]
  - MD: emulated the Z80 executing instructions [Cydrak]
  - MD: emulated Z80 interrupts (triggered during each Vblank period)
    [Cydrak]
  - MD: emulated Z80 memory map [Cydrak]
  - MD: added stubs for PSG, YM2612 accesses [Cydrak]
  - MD: improved bus emulation [Cydrak]

The PCE core is pretty much ready to go. The only major feature missing
is FM modulation.

The Mega Drive improvements let us start to see the splash screens for
Langrisser II, Shining Force, Shining in the Darkness. I was hoping I
could get them in-game, but no such luck. My Z80 implementation is
probably flawed in some way ... now that I think about it, I believe I
missed the BusAPU::reset() check for having been granted access to the
Z80 first. But I doubt that's the problem.

Next step is to implement Cydrak's PSG core into the Master System
emulator. Once that's in, I'm going to add save states and cheat code
support to the Master System core.

Next, I'll add the PSG core into the Mega Drive. Then I'll add the
'easy' PCM part of the YM2612. Then the rest of the beastly YM2612 core.
Then finally, cap things off with save state and cheat code support.

Should be nearing a new release at that point.
2017-02-20 19:13:10 +11:00
Tim Allen bdc100e123 Update to v102r02 release.
byuu says:

Changelog:

  - I caved on the `samples[] = {0.0}` thing, but I'm very unhappy about it
      - if it's really invalid C++, then GCC needs to stop accepting it
        in strict `-std=c++14` mode
  - Emulator::Interface::Information::resettable is gone
  - Emulator::Interface::reset() is gone
  - FC, SFC, MD cores updated to remove soft reset behavior
  - split GameBoy::Interface into GameBoyInterface,
    GameBoyColorInterface
  - split WonderSwan::Interface into WonderSwanInterface,
    WonderSwanColorInterface
  - PCE: fixed off-by-one scanline error [hex_usr]
  - PCE: temporary hack to prevent crashing when VDS is set to < 2
  - hiro: Cocoa: removed (u)int(#) constants; converted (u)int(#)
    types to (u)int_(#)t types
  - icarus: replaced usage of unique with strip instead (so we don't
    mess up frameworks on macOS)
  - libco: added macOS-specific section marker [Ryphecha]

So ... the major news this time is the removal of the soft reset
behavior. This is a major!! change that results in a 100KiB diff file,
and it's very prone to accidental mistakes!! If anyone is up for
testing, or even better -- looking over the code changes between v102r01
and v102r02 and looking for any issues, please do so. Ideally we'll want
to test every NES mapper type and every SNES coprocessor type by loading
said games and power cycling to make sure the games are all cleanly
resetting. It's too big of a change for me to cover there not being any
issues on my own, but this is truly critical code, so yeah ... please
help if you can.

We technically lose a bit of hardware documentation here. The soft reset
events do all kinds of interesting things in all kinds of different
chips -- or at least they do on the SNES. This is obviously not ideal.
But in the process of removing these portions of code, I found a few
mistakes I had made previously. It simplifies resetting the system state
a lot when not trying to have all the power() functions call the reset()
functions to share partial functionality.

In the future, the goal will be to come up with a way to add back in the
soft reset behavior via keyboard binding as with the Master System core.
What's going to have to happen is that the key binding will have to send
a "reset pulse" to every emulated chip, and those chips are going to
have to act independently to power() instead of reusing functionality.
We'll get there eventually, but there's many things of vastly greater
importance to work on right now, so it'll be a while. The information
isn't lost ... we'll just have to pull it out of v102 when we are ready.

Note that I left the SNES reset vector simulation code in, even though
it's not possible to trigger, for the time being.

Also ... the Super Game Boy core is still disconnected. To be honest, it
totally slipped my mind when I released v102 that it wasn't connected
again yet. This one's going to be pretty tricky to be honest. I'm
thinking about making a third GameBoy::Interface class just for SGB, and
coming up with some way of bypassing platform-> calls when in this
mode.
2017-01-23 08:04:26 +11:00
Tim Allen 1df2549d18 Update to v101r04 release.
byuu says:

Changelog:

  - pulled the (u)intN type aliases into higan instead of leaving them
    in nall
  - added 68K LINEA, LINEF hooks for illegal instructions
  - filled the rest of the 68K lambda table with generic instance of
    ILLEGAL
  - completed the 68K disassembler effective addressing modes
      - still unsure whether I should use An to decode absolute
        addresses or not
      - pro: way easier to read where accesses are taking place
      - con: requires An to be valid; so as a disassembler it does a
        poor job
      - making it optional: too much work; ick
  - added I/O decoding for the VDP command-port registers
  - added skeleton timing to all five processor cores
  - output at 1280x480 (needed for mixed 256/320 widths; and to handle
    interlace modes)

The VDP, PSG, Z80, YM2612 are all stepping one clock at a time and
syncing; which is the pathological worst case for libco. But they also
have no logic inside of them. With all the above, I'm averaging around
250fps with just the 68K core actually functional, and the VDP doing a
dumb "draw white pixels" loop. Still way too early to tell how this
emulator is going to perform.

Also, the 320x240 mode of the Genesis means that we don't need an aspect
correction ratio. But we do need to ensure the output window is a
multiple 320x240 so that the scale values work correctly. I was
hard-coding aspect correction to stretch the window an additional \*8/7.
But that won't work anymore so ... the main higan window is now 640x480,
960x720, or 1280x960. Toggling aspect correction only changes the video
width inside the window.

It's a bit jarring ... the window is a lot wider, more black space now
for most modes. But for now, it is what it is.
2016-08-12 11:07:04 +10:00
Tim Allen ca277cd5e8 Update to v100r14 release.
byuu says:

(Windows: compile with -fpermissive to silence an annoying error. I'll
fix it in the next WIP.)

I completely replaced the time management system in higan and overhauled
the scheduler.

Before, processor threads would have "int64 clock"; and there would
be a 1:1 relationship between two threads. When thread A ran for X
cycles, it'd subtract X * B.Frequency from clock; and when thread B ran
for Y cycles, it'd add Y * A.Frequency from clock. This worked well
and allowed perfect precision; but it doesn't work when you have more
complicated relationships: eg the 68K can sync to the Z80 and PSG; the
Z80 to the 68K and PSG; so the PSG needs two counters.

The new system instead uses a "uint64 clock" variable that represents
time in attoseconds. Every time the scheduler exits, it subtracts
the smallest clock count from all threads, to prevent an overflow
scenario. The only real downside is that rounding errors mean that
roughly every 20 minutes, we have a rounding error of one clock cycle
(one 20,000,000th of a second.) However, this only applies to systems
with multiple oscillators, like the SNES. And when you're in that
situation ... there's no such thing as a perfect oscillator anyway. A
real SNES will be thousands of times less out of spec than 1hz per 20
minutes.

The advantages are pretty immense. First, we obviously can now support
more complex relationships between threads. Second, we can build a
much more abstracted scheduler. All of libco is now abstracted away
completely, which may permit a state-machine / coroutine version of
Thread in the future. We've basically gone from this:

    auto SMP::step(uint clocks) -> void {
      clock += clocks * (uint64)cpu.frequency;
      dsp.clock -= clocks;
      if(dsp.clock < 0 && !scheduler.synchronizing()) co_switch(dsp.thread);
      if(clock >= 0 && !scheduler.synchronizing()) co_switch(cpu.thread);
    }

To this:

    auto SMP::step(uint clocks) -> void {
      Thread::step(clocks);
      synchronize(dsp);
      synchronize(cpu);
    }

As you can see, we don't have to do multiple clock adjustments anymore.
This is a huge win for the SNES CPU that had to update the SMP, DSP, all
peripherals and all coprocessors. Likewise, we don't have to synchronize
all coprocessors when one runs, now we can just synchronize the active
one to the CPU.

Third, when changing the frequencies of threads (think SGB speed setting
modes, GBC double-speed mode, etc), it no longer causes the "int64
clock" value to be erroneous.

Fourth, this results in a fairly decent speedup, mostly across the
board. Aside from the GBA being mostly a wash (for unknown reasons),
it's about an 8% - 12% speedup in every other emulation core.

Now, all of this said ... this was an unbelievably massive change, so
... you know what that means >_> If anyone can help test all types of
SNES coprocessors, and some other system games, it'd be appreciated.

----

Lastly, we have a bitchin' new about screen. It unfortunately adds
~200KiB onto the binary size, because the PNG->C++ header file
transformation doesn't compress very well, and I want to keep the
original resource files in with the higan archive. I might try some
things to work around this file size increase in the future, but for now
... yeah, slightly larger archive sizes, sorry.

The logo's a bit busted on Windows (the Label control's background
transparency and alignment settings aren't working), but works well on
GTK. I'll have to fix Windows before the next official release. For now,
look on my Twitter feed if you want to see what it's supposed to look
like.

----

EDIT: forgot about ICD2::Enter. It's doing some weird inverse
run-to-save thing that I need to implement support for somehow. So, save
states on the SGB core probably won't work with this WIP.
2016-07-30 13:56:12 +10:00
Tim Allen 76a8ecd32a Update to v100r03 release.
byuu says:

Changelog:
- moved Thread, Scheduler, Cheat functionality into emulator/ for
  all cores
- start of actual Mega Drive emulation (two 68K instructions)

I'm going to be rather terse on MD emulation, as it's too early for any
meaningful dialogue here.
2016-07-10 15:28:26 +10:00
Tim Allen 3dd1aa9c1b Update to v100r02 release.
byuu says:

Sigh ... I'm really not a good person. I'm inherently selfish.

My responsibility and obligation right now is to work on loki, and
then on the Tengai Makyou Zero translation, and then on improving the
Famicom emulation.

And yet ... it's not what I really want to do. That shouldn't matter;
I should work on my responsibilities first.

Instead, I'm going to be a greedy, self-centered asshole, and work on
what I really want to instead.

I'm really sorry, guys. I'm sure this will make a few people happy,
and probably upset even more people.

I'm also making zero guarantees that this ever gets finished. As always,
I wish I could keep these things secret, so if I fail / give up, I could
just drop it with no shame. But I would have to cut everyone out of the
WIP process completely to make it happen. So, here goes ...

This WIP adds the initial skeleton for Sega Mega Drive / Genesis
emulation. God help us.

(minor note: apparently the new extension for Mega Drive games is .md,
neat. That's what I chose for the folders too. I thought it was .smd,
so that'll be fixed in icarus for the next WIP.)

(aside: this is why I wanted to get v100 out. I didn't want this code in
a skeleton state in v100's source. Nor did I want really broken emulation,
which the first release is sure to be, tarring said release.)

...

So, basically, I've been ruminating on the legacy I want to leave behind
with higan. 3D systems are just plain out. I'm never going to support
them. They're too complex for my abilities, and they would run too slowly
with my design style. I'm not willing to compromise my design ideals. And
I would never want to play a 3D game system at native 240p/480i resolution
... but 1080p+ upscaling is not accurate, so that's a conflict I want
to avoid entirely. It's also never going to emulate computer systems
(X68K, PC-98, FM-Towns, etc) because holy shit that would completely
destroy me. It's also never going emulate arcade machines.

So I think of higan as a collection of 2D emulators for consoles
and handhelds. I've gone over every major 2D gaming system there is,
looking for ones with games I actually care about and enjoy. And I
basically have five of those systems supported already. Looking at the
remaining list, I see only three systems left that I have any interest
in whatsoever: PC-Engine, Master System, Mega Drive. Again, I'm not in
any way committing to emulating any of these, but ... if I had all of
those in higan, I think I'd be content to really, truly, finally stop
writing more emulators for the rest of my life.

And so I decided to tackle the most difficult system first. If I'm
successful, the Z80 core should cover a lot of the work on the SMS. And
the HuC6280 should land somewhere between the NES and SNES in terms of
difficulty ... closer to the NES.

The systems that just don't appeal to me at all, which I will never touch,
include, but are not limited to:
* Atari 2600/5200/7800
* Lynx
* Jaguar
* Vectrex
* Colecovision
* Commodore 64
* Neo-Geo
* Neo-Geo Pocket / Color
* Virtual Boy
* Super A'can
* 32X
* CD-i
* etc, etc, etc.

And really, even if something were mildly interesting in there ... we
have to stop. I can't scale infinitely. I'm already way past my limit,
but I'm doing this anyway. Too many cores bloats everything and kills
quality on everything. I don't want higan to become MESS v2.

I don't know what I'll do about the Famicom Disk System, PC-Engine CD,
and Mega CD. I don't think I'll be able to achieve 60fps emulating the
Mega CD, even if I tried to.

I don't know what's going to happen here with even the Mega Drive. Maybe
I'll get driven crazy with the documentation and quit. Maybe it'll end
up being too complicated and I'll quit. Maybe the emulation will end up
way too slow and I'll give up. Maybe it'll take me seven years to get
any games playable at all. Maybe Steve Snake, AamirM and Mike Pavone
will pool money to hire a hitman to come after me. Who knows.

But this is what I want to do, so ... here goes nothing.
2016-07-09 14:21:37 +10:00