Jump to content
IGNORED

Fixing known bugs in Handy emulator


LX.NET

Recommended Posts

Would it be feasible (and motivating) for you LX to provide a patch for the crackling audio to be fixed?

 

http://sourceforge.n...313&atid=640866 -- just to know your thoughts about that.

 

Hi Twipley,

 

Yes, motivating/motivated pretty much so.

This is one of my outstanding points of improvement to the emulator. Handy is built using a circular audio buffer, and I think that hickups in the emulation speed might be causing the buffer (0,25 seconds) to either be overrun or underrun. I use a reasonably similar method and experience the same thing.

 

I have heard that mednafen runs the audio perfectly. Can anyone confirm that? If so, I'll give it a spin and check out the source code.

Link to comment
Share on other sites

I am very interested in this from both a Lynx development point of view, and porting the fixes back into the GP2X version of Handy. There's a guy who ported it over to the GP2X from Handy sources a few years back and that version exhibits the problems you've addressed so far. The problem at the moment is I cannot get hold of the author and he never made the source open - ironic as it was open source to start with... Anyway, I will progress with the issues you've raised and fixed and try and get the GP2X version of Handy updated. The GP2X is a linux based handheld btw - i've developed a few games on it myself previously as well as bits and bobs on other platforms - wrote a NES emulator which has a 6502 CPU - I think the same as the Lynx, it's been a while since I looked at the 6502, from what I remember it was 8bit with 16bit addressing which fits with the Atari CPU spec ive seen (65SC02 - not sure what the SC code means).

 

Moving forward I am looking at getting an SDK, and possibly a Lynx flashcard (might be hard, seem to be next to none around) and developing some games for the Lynx. Keep up the good work, it's nice to see that some one has passion and enthusiasm for the Lynx - keeping it alive!!

Link to comment
Share on other sites

Incidentally, when I got to emulating the pAPU (embedded in the NES 6502), I ran into the same problems you are having with the crackling. A big part of the problem was timing and a few issues with the standard circular buffer approach:-

1) Timing - ie. writting bytes to active parts of the buffer, and the buffer size itself. I got better cleaner sound by creating an entirely new buffer each time and pointing to a new buffer. And if the code from the CPU (or pseudo CPU etc) sets bits and bytes to change frequency, amplitude etc, then in the real harware it probably doesnt just change instantly from one wave form to another without a tiny bit of drop off etc - probably explaining this badly, a simple example of what I am trying to say is, imaging a square wave and suddenly it changes to a saw tooth. Without some leveling / merge on some of the bytes you will get a an audio spike as you get half square half saw tooth.

2) Changing from one wave form to another but with an unclean join (as above).

 

I was not an expert on audio emulation at all though so take what I am saying with a pinch of salt - getting audio emulated perfectly is still a tiny bit of a black art to me and I gave up before I perfected audio in my NES emulator. I paid no attention to existing methods out there and just jumped in at the deep end. Used a circular buffer, created the standard wave forms (square, triangle etc) and applied logic to change amplitude and frequency, then merged the seperate audio channels over the top of each other using bit logic - it worked but wasnt great and lowered performance a lot. I guess a better way would have been to use a seperate audio stream for each of the 4 channels the NES 6502 pAPU had and and let directx merge them.

Edited by GadgetUK
Link to comment
Share on other sites

The problem at the moment is I cannot get hold of the author and he never made the source open - ironic as it was open source to start with... Anyway, I will progress with the issues you've raised and fixed and try and get the GP2X version of Handy updated.

I have looked through my list of emulators and found the GP2X and GP32 emulators there. Like you said, I haven't been able to find any source code for the GP2X, but did have an archive called "handygp02.zip" which contains source code (gpmain.cpp) and a handygp.xfe file (the binary I guess). Not sure if this is helpful, but I thought I would mention it.

 

(65SC02 - not sure what the SC code means).

 

The 6502 was the first chipset, then came the 65C02 and 65SC02. The 65C02 has the largest instruction set of the three and the 65SC02 has most of the extra instructions that the 65C02 has, but missing some (RMB, SMB, BBR and BBS).

 

Moving forward I am looking at getting an SDK, and possibly a Lynx flashcard (might be hard, seem to be next to none around) and developing some games for the Lynx. Keep up the good work, it's nice to see that some one has passion and enthusiasm for the Lynx - keeping it alive!!

 

Thanks. Good to hear.

I've begun programming a port of an Atari 2600 game myself and have gotten my development environment set up. Apart from debugging support I feel like it is very productive. I should really write something on this. It might not suit everyone, but there might be takers.

Link to comment
Share on other sites

Incidentally, when I got to emulating the pAPU (embedded in the NES 6502), I ran into the same problems you are having with the crackling. A big part of the problem was timing and a few issues with the standard circular buffer approach:-

1) Timing - ie. writting bytes to active parts of the buffer, and the buffer size itself. I got better cleaner sound by creating an entirely new buffer each time and pointing to a new buffer. And if the code from the CPU (or pseudo CPU etc) sets bits and bytes to change frequency, amplitude etc, then in the real harware it probably doesnt just change instantly from one wave form to another without a tiny bit of drop off etc - probably explaining this badly, a simple example of what I am trying to say is, imaging a square wave and suddenly it changes to a saw tooth. Without some leveling / merge on some of the bytes you will get a an audio spike as you get half square half saw tooth.

2) Changing from one wave form to another but with an unclean join (as above).

 

I was not an expert on audio emulation at all though so take what I am saying with a pinch of salt - getting audio emulated perfectly is still a tiny bit of a black art to me and I gave up before I perfected audio in my NES emulator. I paid no attention to existing methods out there and just jumped in at the deep end. Used a circular buffer, created the standard wave forms (square, triangle etc) and applied logic to change amplitude and frequency, then merged the seperate audio channels over the top of each other using bit logic - it worked but wasnt great and lowered performance a lot. I guess a better way would have been to use a seperate audio stream for each of the 4 channels the NES 6502 pAPU had and and let directx merge them.

 

This is very good feedback. I will look into this a bit further. My (ultimate) goal is to get "pixel-perfect" sound. From the earlier comments and yours I have some approaches I can take. Especially the one you mentioned (mixing channels by DirectX) seem like an idea. The other one is the circular buffer approach (or rather not having one). To me it seems that the buffer is the culprit indeed. You can clearly hear that the hickups are at the 0,25 second buffer edges. I have thought about double buffering the sound. I'll give it a spin in a couple of days.

Link to comment
Share on other sites

  • 1 month later...

Hi GadgetUK,

 

Only theoretical preparations. I have looked in to the Mednafen and Handy/SDL source code to see their approach. I still have to look at it a second time to really dig into it. For now I did see different approaches (copying buffers, variable length buffers). Working on a couple of things now and I have to be careful not to spend my time too fragmented. I'll keep updating as I progress.

 

Alex

Link to comment
Share on other sites

Great! I know what its like trying to balance time between different projects, work and family life etc! I am deperately trying to finish an IOS game for release to the app store. Keen to do something Lynx related after that, and before my next IOS release I think. Had ideas to look at NES to Lynx conversion of ROMs but not sure yet. I might just try and do a game for the Lynx instead.

Link to comment
Share on other sites

  • 2 months later...

It is great to hear lots of rambling around concerning the seemingly important number of different ways (DirectX channel mixing, circular-buffering avoidance, double buffering, buffer copying, and variable-length buffering) to reproduce as-accurate-as-troublelessly-possible Handy-console audio.

 

Keep us tuned while you are looking at it! Even if it is just theoretical rambling... ;)

Link to comment
Share on other sites

  • 4 months later...

Dropping in for a few words here.

The .NET code of my emulator is indeed not very portable across different platforms other than Windows. It does run on Windows, Windows Phone 7 and above, and (with some endian-bugs) on XBox360. Since I am far more proficient in managed languages of .NET I am starting work there with intentions to work it back into the Handy codebase. Two items (EVERON bug and sprite data unpacking) have been done so far.

Also, I am working on encryption algorithms and getting my head around that. Yesterday I finished the code that allows for arbitrary 65SC02 code to be encrypted, so the Lynx can decrypt it. Read the Lynx programming forum for more info (once I post there later today).

 

Current state of .NET emulator is:

  • No audio yet. I have done a port of the code in Handy, but the emulator is still too slow to keep up with the 0.25 second samples. Net effect is that the audio is stuttering. Also, it does not give any sounds on channel 1. I've read that was a bug in the Handy code (around version 0.70 or so), where Keith mentioned a fix for timer 0, because audio channel 1 was not giving any sound. Need to look into that, as I may have introduced the same bug
  • Starting work on EEPROM support. 93C46 (Lynxman Flashcart, Lynxopoly) and KM28C64-20 (Eye of the Beholder).
  • Graphically on par with Handy
  • 3 small bugs remaining
    • randomness doesn't seem to work yet (Lynxopoly always rolls 9 with dices, and Blockout always has 2x2x1 blocks
    • loading of "rebuild phase" screen in Rampart has bad graphics
    • interlaced graphics seem more flickery/unstable than in Handy (in both it looks aweful, but a little worse in my version)

On the audio in particular: Keith used a small circular audio buffer connected to DirectAudio that he kept writing to. His emulation code does exactly what the audio hardware would do. Create output levels (standard or integrated audio) for a period of time and averaging over the four channels. Emulate the shift register feedback for next output value and keep doing this whenever an audio timer triggers.

The comments on the audio give me some nice suggestions to try things a little differently. It would be relatively easy to store the data of an audio channel in a different stream for playback later on. That would allow for some easy experiments with the data. I'll give it a shot as soon as I finish the encryption stuff and the EEPROM emulation (also for Handy).

 

Hi,

 

I've compiled Handy today and applied a couple of the fixes you mentioned and had a tinker with the sound but still need to look at it a bit more in depth. I cannot see the problem you mentioned with random not working on Blockout - it seems fine to me? Would be useful to see a screenshot of whats wrong with Rampart, there is a black screen I spotted, is that what we are talking about? I thought it had crashed for a minute.

Link to comment
Share on other sites

Hi,

 

I've compiled Handy today and applied a couple of the fixes you mentioned and had a tinker with the sound but still need to look at it a bit more in depth. I cannot see the problem you mentioned with random not working on Blockout - it seems fine to me? Would be useful to see a screenshot of whats wrong with Rampart, there is a black screen I spotted, is that what we are talking about? I thought it had crashed for a minute.

Cool you are working on this as well.

The .NET emulator I wrote is not Handy. Handy does not suffer from the bugs in Blockout and Rampart like my emulator does. It is low on my priority list to fix these bugs. They are pretty hard to find, as they happen deep inside the gameplay.

Which other things did you fix? I believe there was the ending data of single pixel sprites that got fixed.

I am interested in your sound strategy. I spoke to a game developer on this and he said that you must double (or multi-) buffer sound to avoid the hickups.

Is there any way we can carry on with a open source repository on the Handy source. I would prefer some rights to push code into the Handy codebase, but I have never been able to contact (and thank) Keith Wilkins.

Link to comment
Share on other sites

Hi, I fixed that pixel ending bug you sorted, and one in Suzi I think (another of yours), basically fixing Lava in Joust, and the end if that polly in the 3d cube demo.

 

The fix that developer mentioned was exactly what I did. Increased the buffer size, change a line of code that worked with buffer and changed from x 2 to x 4 on code related to buffering. Also changed the value of cycles related to sound, its a define based on 16000000 / wav sample freq, which happens to not be divisble without a remainder (not sure if this is needed or whether C++ auto rounds ints up, I thought that was what the round function was for?) Basically in an ideal world the whole thing would be multithreaded and the sound core would run independantly of the CPU(s), and if cycle timing was right it would end up being more accurate with no buffering issues. It looks like every now and then the sound passes the rest of the system for very short periods of time and then the buffers empty. I think the opposite also could happen. I cant be 100 sure without spending more time on it but those small changes have made a big difference from what ive heard. Double Dragon intro is perfect now as are all of games ive tried. I want to check how hes done the waveforms later to see if they are accurate or whether they can be improved.

 

 

Link to comment
Share on other sites

I've tinkered with the sound a bit and it seems to be much better for me now. I've uploaded a binary if anyone wants to test it.

 

http://www.c5softwar...s/handy0.96.zip

 

EDIT: I think the sound is MUCH better now imo.

 

I could do with someone testing this new build of Handy (0.96) containing a couple of LX.NET's fixes and a sound fix I applied yesterday.

Link to comment
Share on other sites

Regards source, I can start sticking it on my site, it would be good if we could use SVN or something, but its not essential.

 

I have been using bitbucket for my Lynx sources. It is free and you can share it between developers.

 

https://bitbucket.or...i/solitaire/src

 

Ii can be checked out by

hg clone http://bitbucket.org/karri/solitaire/src

 

Bitbucket also supports a wiki for each project like

http://bitbucket.org/karri/solitaire/wiki

Edited by karri
Link to comment
Share on other sites

No takers on testing 0.96 (above)?? Starting to think no one uses Handy any more lol.

 

I dumped "Lynx Invades Japan" tonight and noticed it doesnt display properly - flickering with palette issues. Does anyone here know anything about the software and hardware techniques used in this (and perhaps other carts?) to display the photos with palette change per scanline? I am also not sure if these kinds of photo viewers interlace to get a pseudo high res?

 

Edit: Is it possible that this uses Sages viewer? Is there another cart that displays high colour photos? The more I can test / find out the more chance of fixing this. I suspect its a vblank timing issue.

Edited by GadgetUK
Link to comment
Share on other sites

I downloaded your binary but havent got around to testing it yet. Sage's viewer, I believe swaps between two screens every vblank so it probably will look bad on handy. Handy would need a mode that combines two frames (like the modern atari 8-bit emulators do...

 

AFAIK

 

Awesome that's pretty much the conclussion I jumped to last night after reading an email from LX.NET. Basically blurring the two images together. I had a look at the code and something struck me, it's hard coded to work at 50fps... After changing to work at 60 and 75 I noticed differences. At 75hz 'Lynx Invades Japan' actually looks a bit better - it now looks like 2 seperate frames with different palettes rather than a strobing palette with some wierd artifacts. I am now wondering how the Lynx is programmed to switch between different LCD refresh rates.

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...