Commit Graph

11 Commits

Author SHA1 Message Date
Tim Allen 8476f35153 Update to v102r28 release.
byuu says:

Changelog:

  - higan: `Emulator::<Platform::load>()` now returns a struct containing
    both a path ID and a string option
  - higan: `Emulator::<Platform::load>()` now takes an optional final
    argument of string options
  - fc: added PAL emulation (finally, only took six years)
  - md: added PAL emulation
  - md: fixed address parameter to `VDP::Sprite::write()`; fixes missing
    sprites in Super Street Fighter II
  - md: emulated HIRQ counter; fixes many games
      - Super Street Fighter II - status bar
      - Altered Beast - status bar
      - Sonic the Hedgehog - Labyrinth Zone - water effect
      - etc.
  - ms: added PAL emulation
  - sfc: added the ability to override the default region auto-detection
  - sfc: removed "system.region" override setting from `Super Famicom.sys`
  - tomoko: added options list to game folder load dialog window
  - tomoko: added the ability to specify game folder load options on the
    command-line

So, basically ... Sega forced a change with the way region detection
works. You end up with games that can run on multiple regions, and the
content changes accordingly. Bare Knuckle in NTSC-J mode will become
Streets of Rage in NTSC-U mode. Some games can even run in both NTSC and
PAL mode.

In my view, there should be a separate ROM for each region a game was
released in, even if the ROM content were identical. But unfortunately
that's not how things were done by anyone else.

So to support this, the higan load dialog now has a drop-down at the
bottom-right, where you can choose the region to load games from. On the
SNES, it defaults to "Auto", which will pull the region setting from the
manifest, or fall back on NTSC. On the Mega Drive ... unfortunately, I
can't auto-detect the region from the ROM header. $1f0 is supposed to
contain a string like "JUE", but instead you get games like Maui Mallard
that put an "A" there, and other such nonsense. Sega was far more lax
than Nintendo with the ROM header validity. So for now at least, you
have to manually select your region every time you play a Mega Drive
game, thus you have "NTSC-J", "NTSC-U", and "PAL". The same goes for the
Master System for the same reason, but there's only "NTSC" and "PAL"
here. I'm not sure if games have a way to detect domestic vs
international consoles.

And for now ... the Famicom is the same as well, with no auto-detection.
I'd sincerely hope iNES has a header bit for the region, but I didn't
bother with updating icarus to support that yet.

The way to pass these parameters on the command-line is to prefix the
game path with "option:", so for example:

    higan "PAL:/path/to/Sonic the Hedgehog (USA, Europe).md"

If you don't provide a prefix, it uses the default (NTSC-J, NTSC, or
Auto.) Obviously, it's not possible to pass parameters with
drag-and-drop, so you will always get the default option in said case.
2017-06-20 22:34:50 +10:00
Tim Allen 82c58527c3 Update to v102r17 release.
byuu says:

Changelog:

  - GBA: process audio at 2MHz instead of 32KHz¹
  - MD: do not allow the 68K to stop the Z80, unless it has been granted
    bus access first
  - MD: do not reset bus requested/granted signals when the 68K resets
    the Z80
      - the above two fix The Lost Vikings
  - MD: clean up the bus address decoding to be more readable
  - MD: add support for a13000-a130ff (#TIME) region; pass to cartridge
    I/O²
  - MD: emulate SRAM mapping used by >16mbit games; bank mapping used
    by >32mbit games³
  - MD: add 'reset pending' flag so that loading save states won't
    reload 68K PC, SP registers
      - this fixes save state support ... mostly⁴
  - MD: if DMA is not enabled, do not allow CD5 to be set [Cydrak]
      - this fixes in-game graphics for Ristar. Title screen still
        corrupted on first run
  - MD: detect and break sprite lists that form an infinite loop
    [Cydrak]
      - this fixes the emulator from dead-locking on certain games
  - MD: add DC offset to sign DAC PCM samples [Cydrak]
      - this improves audio in Sonic 3
  - MD: 68K TAS has a hardware bug that prevents writing the result back
    to RAM
      - this fixes Gargoyles
  - MD: 68K TRAP should not change CPU interrupt level
      - this fixes Shining Force II, Shining in the Darkness, etc
  - icarus: better SRAM heuristics for Mega Drive games

Todo:

  - need to serialize the new cartridge ramEnable, ramWritable, bank
    variables

¹: so technically, the GBA has its FIFO queue (raw PCM), plus a GB
chipset. The GB audio runs at 2MHz. However, I was being lazy and
running the sequencer 64 times in a row, thus decimating the audio to
32KHz. But simply discarding 63 out of every 64 samples resorts in
muddier sound with more static in it.

However ... increasing the audio thread processing intensity 64-fold,
and requiring heavy-duty three-chain lowpass and highpass filters is not
cheap. For this bump in sound quality, we're eating a loss of about 30%
of previous performance.

Also note that the GB audio emulation in the GBA core still lacks many
of the improvements made to the GB core. I was hoping to complete the GB
enhancements, but it seems like I'm never going to pass blargg's
psychotic edge case tests. So, first I want to clean up the GB audio to
my current coding standards, and then I'll port that over to the GBA,
which should further increase sound quality. At that point, it sound
exceed mGBA's audio quality (due to the ridiculously high sampling rate
and strong-attenuation audio filtering.)

²: word writes are probably not handled correctly ... but games are
only supposed to do byte writes here.

³: the SRAM mapping is used by games like "Story of Thor" and
"Phantasy Star IV." Unfortunately, the former wasn't released in the US
and is region protected. So you'll need to change the NTSU to NTSCJ in
md/system/system.cpp in order to boot it. But it does work nicely now.
The write protection bit is cleared in the game, and then it fails to
write to SRAM (soooooooo many games with SRAM write protection do this),
so for now I've had to disable checking that bit. Phantasy Star IV has a
US release, but sadly the game doesn't boot yet. Hitting some other bug.

The bank mapping is pretty much just for the 40mbit Super Street Fighter
game. It shows the Sega and Capcom logos now, but is hitting yet another
bug and deadlocking.

For now, I emulate the SRAM/bank mapping registers on all cartridges,
and set sane defaults. So long as games don't write to $a130XX, they
should all continue to work. But obviously, we need to get to a point
where higan/icarus can selectively enable these registers on a per-game
basis.

⁴: so, the Mega Drive has various ways to lock a chip until another
chip releases it. The VDP can lock the 68K, the 68K can lock the Z80,
etc. If this happens when you save a state, it'll dead-lock the
emulator. So that's obviously a problem that needs to be fixed. The fix
will be nasty ... basically, bypassing the dead-lock, creating a
miniature, one-instruction-long race condition. Extremely unlikely to
cause any issues in practice (it's only a little worse than the SNES
CPU/SMP desync), but ... there's nothing I can do about it. So you'll
have to take it or leave it. But yeah, for now, save states may lock up
the emulator. I need to add code to break the loops when in the process
of creating a save state still.
2017-03-10 21:23:29 +11:00
Tim Allen 04072b278b Update to v102r16 release.
byuu says:

Changelog:

  - Emulator::Stream now allows adding low-pass and high-pass filters
    dynamically
      - also accepts a pass# count; each pass is a second-order biquad
        butterworth IIR filter
  - Emulator::Stream no longer automatically filters out >20KHz
    frequencies for all streams
  - FC: added 20Hz high-pass filter; 20KHz low-pass filter
  - GB: removed simple 'magic constant' high-pass filter of unknown
    cutoff frequency (missed this one in the last WIP)
  - GB,SGB,GBC: added 20Hz high-pass filter; 20KHz low-pass filter
  - MS,GG,MD/PSG: added 20Hz high-pass filter; 20KHz low-pass filter
  - MD: added save state support (but it's completely broken for now;
    sorry)
  - MD/YM2612: fixed Voice#3 per-operator pitch support (fixes sound
    effects in Streets of Rage, etc)
  - PCE: added 20Hz high-pass filter; 20KHz low-pass filter
  - WS,WSC: added 20Hz high-pass filter; 20KHz low-pass filter

So, the point of the low-pass filters is to remove frequencies above
human hearing. If we don't do this, then resampling will introduce
aliasing that results in sounds that are audible to the human ear. Which
basically an annoying buzzing sound. You'll definitely hear the
improvement from these in games like Mega Man 2 on the NES. Of course,
these already existed before, so this WIP won't sound better than
previous WIPs.

The high-pass filters are a little more complicated. Their main role is
to remove DC bias and help to center the audio stream. I don't
understand how they do this at all, but ... that's what everyone who
knows what they're talking about says, thus ... so be it.

I have set all of the high-pass filters to 20Hz, which is below the
limit of human hearing. Now this is where it gets really interesting ...
technically, some of these systems actually cut off a lot of range. For
instance, the GBA should technically use an 800Hz high-pass filter when
output is done through the system's speakers. But of course, if you plug
in headphones, you can hear the lower frequencies.

Now 800Hz ... you definitely can hear. At that level, nearly all of the
bass is stripped out and the audio is very tinny. Just like the real
system. But for now, I don't want to emulate the audio being crushed
that badly.

I'm sticking with 20Hz everywhere since it won't negatively affect audio
quality. In fact, you should not be able to hear any difference between
this WIP and the previous WIP. But theoretically, DC bias should mostly
be removed as a result of these new filters. It may be that we need to
raise the values on some cores in the future, but I don't want to do
that until we know for certain that we have to.

What I can say is that compared to even older WIPs than r15 ... the
removal of the simple one-pole low-pass and high-pass filters with the
newer three-pass, second-order filters should result in much better
attenuation (less distortion of audible frequencies.) Probably not
enough to be noticeable in a blind test, though.
2017-03-09 07:20:40 +11:00
Tim Allen 1cab2dfeb8 Update to v102r11 release.
byuu says:

Changelog:

  - MD: connected 32KB cartridge RAM up to every Genesis game under 2MB
    loaded¹
  - MS, GG, MD: improved PSG noise channel emulation, hopefully²
  - MS, GG, MD: lowered PSG volume so that the lowpass doesn't clamp
    samples³
  - MD: added read/write handlers for VRAM, VSRAM, CRAM
  - MD: block VRAM copy when CD4 is clear⁴
  - MD: rewrote VRAM fill, VRAM copy to be byte-based⁵
  - MD: VRAM fill byte set should fall through to regular data port
    write handler⁶

¹: the header parsing for backup RAM is really weird. It's spaces
when not used, and seems to be 0x02000001-0x02003fff for the Shining
games. I don't understand why it starts at 0x02000001 instead of
0x02000000. So I'm just forcing every game to have 32KB of RAM for now.
There's also special handling for ROMs > 2MB that also have RAM
(Phantasy Star IV, etc) where there's a toggle to switch between ROM and
RAM. For now, that's not emulated.

I was hoping the Shining games would run after this, but they're still
dead-locking on me :(

²: Cydrak pointed out some flaws in my attempt to implement what he
had. I was having trouble understanding what he meant, so I went back
and read the docs on the sound chip and tried implementing the counter
the way the docs describe. Hopefully I have this right, but I don't know
of any good test ROMs to make sure my noise emulation is correct. The
docs say the shifted-out value goes to the output instead of the low bit
of the LFSR, so I made that change as well.

I think I hear the noise I'm supposed to in Sonic Marble Zone now, but
it seems like it's not correct in Green Hill Zone, adding a bit of an
annoying buzz to the background music. Maybe it sounds better with the
YM2612, but more likely, I still screwed something up :/

³: it's set to 50% range for both cores right now. For the MD, it
will need to be 25% once YM2612 emulation is in.

⁴: technically, this deadlocks the VDP until a hard reset. I could
emulate this, but for now I just don't do the VRAM copy in this case.

⁵: VSRAM fill and CRAM fill not supported in this new mode. They're
technically undocumented, and I don't have good notes on how they work.
I've been seeing conflicting notes on whether the VRAM fill buffer is
8-bits or 16-bits (I chose 8-bits), and on whether you write the low
byte and then high byte of each words, or the high byte and then low
byte (I chose the latter.)

The VRAM copy improvements fix the opening text in Langrisser II, so
that's great.

⁶: Langrisser II sets the transfer length to one less than needed to
fill the background letter tile on the scenario overview screen. After
moving to byte-sized transfers, a black pixel was getting stuck there.
So effectively, VRAM fill length becomes DMA length + 1, and the first
byte uses the data port so it writes a word value instead of just a byte
value. Hopefully this is all correct, although it probably gets way more
complicated with the VDP FIFO.
2017-02-25 22:11:46 +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 bf90bdfcc8 Update to v101r31 release.
byuu says:

Changelog:

  - converted Emulator::Interface::Bind to Emulator::Platform
  - temporarily disabled SGB hooks
  - SMS: emulated Game Gear palette (latching word-write behavior not
    implemented yet)
  - SMS: emulated Master System 'Reset' button, Game Gear 'Start' button
  - SMS: removed reset() functionality, driven by the mappable input now
    instead
  - SMS: split interface class in two: one for Master System, one for
    Game Gear
  - SMS: emulated Game Gear video cropping to 160x144
  - PCE: started on HuC6280 CPU core—so far only registers, NOP
    instruction has been implemented

Errata:

  - Super Game Boy support is broken and thus disabled
  - if you switch between Master System and Game Gear without
    restarting, bad things happen:
      - SMS→GG, no video output on the GG
      - GG→SMS, no input on the SMS

I'm not sure what's causing the SMS\<-\>GG switch bug, having a hard
time debugging it. Help would be very much appreciated, if anyone's up
for it. Otherwise I'll keep trying to track it down on my end.
2017-01-13 12:15:45 +11:00
Tim Allen 5df717ff2a Update to v101r12 release.
byuu says:

Changelog:

  - new md/bus/ module for bus reads/writes
      - abstracts byte/word accesses wherever possible (everything but
        RAM; forces all but I/O to word, I/O to byte)
      - holds the system RAM since that's technically not part of the
        CPU anyway
  - added md/controller and md/system/peripherals
  - added emulation of gamepads
  - added stub PSG audio output (silent) to cap the framerate at 60fps
    with audio sync enabled
  - fixed VSRAM reads for plane vertical scrolling (two bugs here: add
    instead of sub; interlave plane A/B)
  - mask nametable read offsets (can't exceed 8192-byte nametables
    apparently)
  - emulated VRAM/VSRAM/CRAM reads from VDP data port
  - fixed sprite width/height size calculations
  - added partial emulation of 40-tile per scanline limitation (enough
    to fix Sonic's title screen)
  - fixed off-by-one sprite range testing
  - fixed sprite tile indexing
  - Vblank happens at Y=224 with overscan disabled
      - unsure what happens when you toggle it between Y=224 and Y=240
        ... probably bad things
  - fixed reading of address register for ADDA, CMPA, SUBA
  - fixed sign extension for MOVEA effect address reads
  - updated MOVEM to increment the read addresses (but not writeback)
    for (aN) mode

With all of that out of the way, we finally have Sonic the Hedgehog
(fully?) playable. I played to stage 1-2 and through the special stage,
at least. EDIT: yeah, we probably need HIRQs for Labyrinth Zone.

Not much else works, of course. Most games hang waiting on the Z80, and
those that don't (like Altered Beast) are still royally screwed. Tons of
features still missing; including all of the Z80/PSG/YM2612.

A note on the perihperals this time around: the Mega Drive EXT port is
basically identical to the regular controller ports. So unlike with the
Famicom and Super Famicom, I'm inheriting the exension port from the
controller class.
2016-08-22 08:11:24 +10: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 059347e575 Update to v100r07 release.
byuu says:

Four and a half hours of work and ... zero new opcodes implemented.

This was the best job I could do refining the effective address
computations. Should have all twelve 68000 modes implemented now. Still
have a billion questions about when and how I'm supposed to perform
certain edge case operations, though.
2016-07-17 13:24:28 +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