Jump to content
IGNORED

Handy emulator - the latest version and source code


Cyprian

Recommended Posts

The part that bothers me about superclip is that currently it's used as an optimization technique. Throw away parts of the quad that are invisible.

But this runs into corner cases that can't be easily controlled, when that tilt / rotation factor is included. Warbirds hit 1 but that can be worked around. The comment with Euro Soccer is another example. And there might be others that I could've introduced by accident or are less observable.

I'd think it make more sense to just remove the speedup trick and just raw clip each pixel as it's drawn? Any system within the last 10 years should handle it plenty.

Link to comment
Share on other sites

Rather than junk up the repo with possible wip drafts, I'll just mention here for later.


Another optimization technique that maybe can go bye.

https://github.com/bspruck/handy-fork/blob/master/handy-win32src-0.95-patched/core/mikie.cpp#L1747

https://github.com/bspruck/handy-fork/blob/master/handy-win32src-0.95-patched/core/mikie.cpp#L3706

 

 

Whenever mAUDIO_x_VOLUME is 0, it just skips the counter stuff. Which could be bad for handybug debugging and possibly muck up the timers and reloading. Imagine muting and later unmuting a channel for sfx purposes.

 

 

Maybe when sage later clears out the PR queue, more things can be re-introduced. Less clutter to work with.

 

Oh, btw. Is handy-sdl-master (0.98) or win32-0.95-patched considered more "master"? Because it'd be really helpful if the two could be merged together, like the libretro port pr. I'm guessing sdl-master is preferred but I'm afraid to touch anything until the pr line is sorted out.

Edited by snes2600
Link to comment
Share on other sites

2 minutes ago, snes2600 said:

Oh, btw. Is handy-sdl-master (0.98) or win32-0.95-patched considered more "master"? Because it'd be really helpful if the two could be merged together, like the libretro port pr. I'm guessing sdl-master is preferred but I'm afraid to touch anything until the pr line is sorted out.

 

I believe that SDL-Master is considered GPL, and win32-095-patched is under the original Keith Wilkins license, which is pretty much an MIT license.

 

We have been doing all of our work on and contributing back to the MIT licensed version, as we aren't including any GPL in our project.

 

So... At least from this contributor, we'd rather that the win32-095 fork be considered the new "master", otherwise there still ends up being two main branches.

 

Link to comment
Share on other sites

@snes2600 by the way, thanks for digging deep into all these issues! The updates have been coming fast and furious. Would you prefer to be tracking these issues via individual topics in this forum, or keep it here? (we have a separate jira entry for each on our side)

 

Most of our own work last week was in support of running multiple cores at the same time, which was more at the layer above the core than in the core itself.

Link to comment
Share on other sites

Uhm.. I have no idea. Whatever works best. :) Thanks guys for the info btw!


As for Roadblasters, I've found a possibly interesting lead. Mikie goes to sleep because Susie does its drawing. It gets timer interrupted every so often. Okay. But Susie reaches the NMI VBlank.

CMikie::DisplayEndOfFrame(void)


Shouldn't Susie just "stop" or "abort" at this time? There's nothing left to draw because its VBlank for several lines? Because I remember reading that when Susie stops using the bus, Mikie comes back awake.

Either way, I tried this and it removed a lot of the nasty flickering.


Oh. I did try Ms. Pac-Man with 1/0 r/w to simulate the simultaneous 2 nybble processing idea. It runs close to 30 fps all the time. Especially if that DisplayEndOfFrame Susie CPUSleep abort is used.

Link to comment
Share on other sites

Cool. I just did this:

ULONG CMikie::DisplayEndOfFrame(void)
{
   // Stop any further line rendering
   mLynxLineDMACounter=0;
   mLynxLine=mTIM_2_BKUP;

   if(gCPUWakeupTime) {
      gCPUWakeupTime = 0;
      ClearCPUSleep();
   }
..

 

Confused where the last flicker is coming from. It's like either Mikie doesn't have enough time to draw the last few lines or Susie isn't blitting fast enough. Some black rectangle that only shows up in-game when that condition hits; over several frames it floats upward but only affects the hud.

 

 

About the license hell, all the emucore files in both branches have the same 2004 Wilkins license. Would it be possible to then do either:

 

1. Make an independent branch with just the core files. Say handy-core. Then have separate frontend branches (sdl, windows, libretro) all pull from handy-core. 3 different frontend licenses, with the 1 core license. If one wants to release, then bundle the files together.

 

2. Make a new branch.

 

Branch = handy-bspruck

- Files = license.txt, this_is_a_modified_version.txt

 

- Folder 1 = core

--- Merge the 2 branches, as the sdl one has some extras macros and formatting changes

 

- Folder 2 = zlib-113

--- I think both branches are the same?

 

- Folder 3 = sdl

--- Files = gpl.txt, makefile, readme

--- Folder 3a = src

----- Folder 3b = sdlemu
 

- Folder 4 = windows

--- Files = sln, vcproj

--- Folder 4a = gui-windows

 

- Folder 5 = libretro

--- Files = libretro, misc

--- Folder 5a,5b = libretro stuff

 

which I guess is very similar to idea 1.

 

 

No-intro went headerless with all their roms. I wonder how good the raw auto-detect works, if we switch to that instead of defaulting with the "needs header" message.

 

 

edit:

Figure worth asking. Does Lynx have any refresh period pauses?

https://forums.nesdev.com/viewtopic.php?f=23&t=15261

Edited by snes2600
Link to comment
Share on other sites

Quote

For example: 16K NOPs on a real Lynx need 152*64µs (@75Hz). On Handy 115*64µs.

Means, the 2 cycles on the Lynx take 0.594µs and on Handy 0.449µs, hence 25% to quick.

Does the code for 16K NOPs constantly cross page boundaries? Because I'd wonder if that'd trigger slowdowns.

 

 

https://www.atariarchives.org/cfn/08/03/01.php

Quote

The Lynx contains 64K (half a megabit) of 120ns DRAM

We could have possible dram refresh penalties. As SNES uses 120ns DRAM and has refresh periods per scanline.

 

 

https://github.com/bspruck/handy-fork/blob/master/handy-win32src-0.95-patched/core/c65c02.h#L1544

gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));

 

The part about this that makes me wonder. System is a 16MHz crystal and CPU runs at 4MHz. Maybe that 1 internal cpu cycle should be raised? Suzy runs at 16MHz so I can forgive that. But the CPU too? Unsure.

 

But gritty cycle stuff is getting above my league.

 

 

And I've read here that

Quote

Suzy is shifting 4-bit pixels per Suzy cycle

which zaps the 2 nybble at a time idea. Still 1/1 ram r/w penalty seems reasonable for Ms. Pac-Man.

Link to comment
Share on other sites

3 hours ago, snes2600 said:

Does the code for 16K NOPs constantly cross page boundaries? Because I'd wonder if that'd trigger slowdowns.

 

See: https://github.com/42Bastian/lynx_hacking/blob/b19118e1148b2a33d8798d9756255f603c180469/cycle_check/cycle_check.asm#L99

The timing is an average over the 512 opcodes plus the looping. Number of loops depends on the instruction or better on what I want to measure. Since the timer will overflow. *hmm* I could have linked two timers.

 

Link to comment
Share on other sites

Urg. Well, snes has 40 cycles per line. Maybe experiment with a kludge (smaller ram) and see where we go.

 

 

Roadblasters is still a puzzle. I'd thought that it would be Suzy going too slow, since Handy system cycles seems to revolve around Mikie MHz timing. So 4:1 Suzy to Mikie = /4 the cpu hold time.

https://github.com/bspruck/handy-fork/blob/master/handy-win32src-0.95-patched/core/susie.cpp#L981

 

Which now HUD black flickers really badly instead.

 

 

Tried blocking nested cpu irqs to slow down Mikie and we get the opposite with fun green flashing again.

 

 

Guess have to try inspecting if this mystery black box is another sprite being laid on top, or that part of the hud not being drawn. Weird stuff.

Link to comment
Share on other sites

Back to Ms. Pac-Man again. A diagram understanding.

   out      susie       in
xxxx xxxx || xxxx || xxxx xxxx

1. Read ram. 1 penalty.    xxxx xxxx || xxxx || aaaa bbbb
2. Pixel 1.                xxxx xxxx || aaaa || bbbb xxxx
3. Pixel 2.                xxxx aaaa || bbbb || xxxx xxxx
4. Write ram. 1 penalty.   aaaa bbbb || xxxx || xxxx xxxx

So that's 2 ram cycles per 2 pixels. Or average is 1 ram per pixel.

 

We have to read every pixel, which incurs 1 ram cycle. So I'm simulating (cheating) this way.

https://github.com/snes2600/handy-fork/commit/a27ee34e849e13217285af7621458baa7cb38bd5

Link to comment
Share on other sites

https://github.com/snes2600/handy-fork/commit/c27c1c552e0f53dde006dcc37136ba3b705edca0

 

Turn back on Mikie when Susie hits VBlank. And (+100) extend the DMA penalty per hblank rendering. Roadblasters is now enjoyable for once. Less than +100 and we get less flicker but it's there.

 

I might go back and change some older links to git commits for easier reading.

Link to comment
Share on other sites

On 7/29/2019 at 7:10 PM, snes2600 said:

Cool. I just did this:


ULONG CMikie::DisplayEndOfFrame(void)
{
   // Stop any further line rendering
   mLynxLineDMACounter=0;
   mLynxLine=mTIM_2_BKUP;

   if(gCPUWakeupTime) {
      gCPUWakeupTime = 0;
      ClearCPUSleep();
   }
..

 

Confused where the last flicker is coming from. It's like either Mikie doesn't have enough time to draw the last few lines or Susie isn't blitting fast enough. Some black rectangle that only shows up in-game when that condition hits; over several frames it floats upward but only affects the hud.

 

 

About the license hell, all the emucore files in both branches have the same 2004 Wilkins license. Would it be possible to then do either:

 

1. Make an independent branch with just the core files. Say handy-core. Then have separate frontend branches (sdl, windows, libretro) all pull from handy-core. 3 different frontend licenses, with the 1 core license. If one wants to release, then bundle the files together.

 

2. Make a new branch.

 

Branch = handy-bspruck

- Files = license.txt, this_is_a_modified_version.txt

 

- Folder 1 = core

--- Merge the 2 branches, as the sdl one has some extras macros and formatting changes

 

- Folder 2 = zlib-113

--- I think both branches are the same?

 

- Folder 3 = sdl

--- Files = gpl.txt, makefile, readme

--- Folder 3a = src

----- Folder 3b = sdlemu
 

- Folder 4 = windows

--- Files = sln, vcproj

--- Folder 4a = gui-windows

 

- Folder 5 = libretro

--- Files = libretro, misc

--- Folder 5a,5b = libretro stuff

 

which I guess is very similar to idea 1.

 

 

 

I could see either approach working... Cleaner to have a "core" branch and then each front end layered on top of that (and each front end could have a different license if it wanted).

 

Also, you'd want to start from the original core (Keith Wilkins License) and then layer on SDL, etc, rather than start from SDL and subtract.

 

Link to comment
Share on other sites

On 7/27/2019 at 5:12 PM, snes2600 said:

eeprom is cleared on startup only, to avoid (libretro) reset from zero'ing out the data
- cart.cpp mempcy needs size checks to avoid random crashes when it allocs memory in low private mapped areas
- eeprom mAUDIN_ext is reset initialized also
- added eeprom to savestates

This may be the case, but just to be clear, don't you only want EEPROM cleared the first time you see the cart?

 

And related to that, I can see pros and cons to having EEPROM be part of saved state, rather than separate.

 

I'll start a new topic on emulators and behavior of Saved States/EEPROM/SD persistence.

 

Link to comment
Share on other sites

Libretro had some stupid problem where it would keep zero'ing out eeprom on reset and exit. And then save this zero eeprom to disk.

 

https://github.com/snes2600/handy-fork/commit/ba4507890de5756bfba75499f3972047687ab28d

 

By memset(0) at constructor time only, it's done only once at cart creation. Handy then does eeprom::load afterwards to restore any previously saved data. And anytime we reset or quit, Handy will not accidentally reset the data again.


There eventually could be Lynx homebrews that will use eeprom as extra "temporary ram". That would require it to be part of the savestate. Otherwise a loadstate would have some inconsistent data that would require it to be thrown away. This is more often with snes (commercial), sms + gg (translation hacks).

Edited by snes2600
hyperlink
Link to comment
Share on other sites

Okay. So if we make the 1st initial "core branch" commit using just the vanilla (0.95-patched core), the Keith Wilkins license will remain in good standing. And then we can safely backport the SDL additions without introducing GPL into the mix.

Sounds cool. I guess when to split it off will be sage's jurisdiction.


I did the libretro eeprom testing using the Flappy Bird demo, since it's easy to tinker with. And it was kinda disorienting to lose my (better) high score saves because the eeprom data wasn't part of a savestate, and I did some accidental loadstates using older, lower scores.

Someone who doesn't know hex editing could get upset.

Link to comment
Share on other sites

Here my 2cents:

User point:

- Keep output and core as separate as possible. On my machine, for example, the SDL version just does not work.

- EEPROM should be part of the save state, though it is surely not used as "RAM" extension because of the high access latency.

 

Lynx developer point:

- "Clearing" an EEPROM means filling with $FF not 0

- Choice to enable/disable EEPROM. If disabled, reading should return $FF.

- The breakpoints are currently part of the CPU class, thus on load they are reset which is a pain.

- Watchpoints would be great as well.

- And as a nice to have: Loading some kind of symbol file (ASCII would be sufficient).

Link to comment
Share on other sites

 

8 hours ago, 42bs said:

 

- Keep output and core as separate as possible. On my machine, for example, the SDL version just does not work.

Lots of agreement on this approach. Add me also.

 

8 hours ago, 42bs said:

- EEPROM should be part of the save state, though it is surely not used as "RAM" extension because of the high access latency.

Ah, okay. So someone would have to be a troll and write a demo that'd CPU waste time doing that.

 

8 hours ago, 42bs said:

- "Clearing" an EEPROM means filling with $FF not 0 

Fixed for my build.

https://github.com/snes2600/handy-fork/commit/27e855e1b343f2be585232250a3caad83d179145

 

8 hours ago, 42bs said:

- Choice to enable/disable EEPROM. If disabled, reading should return $FF.

Have to check where EEPROM port is being dummy read.

 

8 hours ago, 42bs said:

 

- The breakpoints are currently part of the CPU class, thus on load they are reset which is a pain.

That could be important to look into. I hate frontend / GUI stuff so I'd leave others alone.

Edited by snes2600
hyperlink
Link to comment
Share on other sites

  • 3 months later...

Just sharing that libretro-handy has some changes that might be useful for others.

 

1) https://github.com/libretro/libretro-handy/commit/6e560105f8a6fc94b07ddc407610dce062bd1642

 

Some homebrews like Flappy Bird and Shaken not Stirred can memcpy past the boundary, causing random crashes on loading. So these are safety checks to prevent.

 

 

2) https://github.com/libretro/libretro-handy/pull/58/files

 

Shanghai when left idle for 59 in-game minutes can power down the Lynx. This stops the nullptr crashes.

 

 

3) https://github.com/libretro/libretro-handy/pull/63/files

 

The current Zendocon laughing spider fix is kinda incomplete.

https://github.com/libretro/libretro-handy/commit/434786dac2b23c5ed00c5ddc17a632839f494aba

https://github.com/libretro/libretro-handy/commit/0c335cd2cf6212a0a51aaeb5230947338896a82c

 

Current code runs when BKUP is 0 but this messes up the waveshaper for other games. So the link above is the add-on fix from Beetle Lynx, an older Handy core. And supposedly fixes the percussion in Zaku.

 

It's been said that Beetle Lynx has no problems with both the Zendocon laugh and Zaku percussion.

 

 

4) https://github.com/libretro/libretro-handy/pulls

 

There's a PR by @zakuahem which involves the Zaku homebrew game. It's said that MAME runs it since 2016 but not Handy because. The game has a detection to STP on Handy emulators only. If you patch the register to behave like real hardware (aka MAME), then the game plays.

 

For Handy, it's been tested that you'll also need the Zendocon fix posted in #3 above to fix the percussion. Don't have this game so can't personally verify.

Edited by tryal-star
remove direct link
Link to comment
Share on other sites

14 hours ago, tryal-star said:

Just sharing that libretro-handy has some changes that might be useful for others.

 

Yes indeed, thanks!

 

Did you make these changes yourself?

 

One of these days we (collective "we") need to get a definitive version on GitHub...

 

Some of the changes we made were to get it ready for an IPC implementation of ComLynx (making it thread safe and remove globals) which we hope to do sometime next year...

Link to comment
Share on other sites

Wait a minute... Are you saying that ZAKU has some kind of DRM that forbids running on Handy because reading of unused register $fd97 returns Answer to the Ultimate Question of Life, the Universe, and Everything instead of usual $ff?

 

What a sofisticated way to detect the emulator...

 

 

  • Haha 1
Link to comment
Share on other sites

2 hours ago, laoo said:

Wait a minute... Are you saying that ZAKU has some kind of DRM that forbids running on Handy because reading of unused register $fd97 returns Answer to the Ultimate Question of Life, the Universe, and Everything instead of usual $ff?

 

What a sofisticated way to detect the emulator...

 

 

If I remember well there is also a basic XOR obfuscation of that part of code. Removing that protection was 5 mins of fun.

 

Obviously I deleted the modified ROM ?, but seems it doesn't matter anymore. 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...