6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Apr 26, 2024 12:36 pm

All times are UTC




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: Writing an emulator...
PostPosted: Wed Dec 17, 2014 11:53 am 
Offline

Joined: Sat Dec 13, 2014 6:59 pm
Posts: 3
Heyas!

This is my first post! Whoo!

Okay... I'm very interested in getting involved in the C65GS project but I can't afford to buy a board right now. I'm looking into it but its not on the table at this point in time. But, I want to help write any software that is required...

So, I decided that getting an emulator up and running for a C65 would be a good idea. I've looked and MESS is broken (and the source for the old versions is no longer available) and besides, the code is poorly written and a complete nightmare from the perspective of maintainability and learning it from the ground up to resolve its bugs.

Unfortunately, VICE was written more with the intention of emulating specific platforms and is not really very customisable. It would take a great deal of work to work-around all of the ways in which it makes assumptions about what is happening or what can happen and all of the optimisations that have been made. When not so much is known about the system to the extent that VICE knows about its platforms, its really not practical to base the emulation on VICE.

With all of that, and having stabbed at writing an emulator for dealing with PSIDs/RSIDs before, I've decided that writing my own might be the way to go. I've decided to keep it "open" in that I'm writing it around the interactions of the components in the system, clocks, buses, ICs, inputs and outputs. That way I can "connect up" and prototype things more quickly with whatever information is available and see what happens as a result.

I figured I'd start with implementing the C64 roughly. I've only just started today but I've got the beginnings of a VIC-II and SID connected to a "multimedia output"... The VIC-II effectively receives the PhiIN dot clock and divides that up into Phi0, Phi1 and Phi2 and steps through its raster output (just outputting random background colours every raster line). The Phi2 is connected to the SID and it generates some sound (I have implemented my own version of ReSID before and I have it doing a test tone). The buffers are collected by the "multimedia output" every frame and given to the user (OpenGL and OpenAL). I'm implementing it on Windows at the moment but it is entirely cross-platform. Oh, its in Pascal (Delphi or FPC/Lazarus) because I hate C/C++.

Its all well and good but I've got a strange problem and I've wasted hours trying to figure it out. For some reason, the emulation absolutely refuses to run at the expected PAL speed (I'm implementing PAL first). I've tried all sorts of combinations of stunning the thread but nothing works. It either runs happily at around 60fps or just dies, even if it goes slightly below 50fps. I've tried everything I can think of and I've triple checked all of my calculations but I can't figure it out.

Has anyone had this kind of problem before and been able to resolve it?

Thanks for any help!


Daniel.


Top
 Profile  
Reply with quote  
PostPosted: Wed Dec 17, 2014 2:07 pm 
Offline

Joined: Sun Jul 28, 2013 12:59 am
Posts: 235
You have video and audio output going already? I don't know what you mean by "just dies", but if your emulation logic is tied to the output process then you might be looking at a display refresh rate issue on your host. It's hard to do 50 frames per second with vblank-timed output on a 60 Hz video mode, and vice versa. I'm expecting that your audio process isn't nearly as vulnerable to host configuration issues. It could be something as simple as the output process trying to get a frame and there not being one available yet.

Good luck!


Top
 Profile  
Reply with quote  
PostPosted: Wed Dec 17, 2014 6:35 pm 
Offline

Joined: Sat Dec 13, 2014 6:59 pm
Posts: 3
Well... By "just dies" I mean, gets very choppy and unstable.

When I have tried to use "yield" and "sleep" type functions, the host has just laughed at me and ignored it until I do something ridiculous like purposefully hold a lock for half a second. Seriously, no effect on any period of any delays until some ridiculous amount and then dies. I've even increased the frame rate stability and efficiency to be more consistently 60Hz somehow by using yield to trying to slow it down.

I have done some work on building an emulation for handling PSIDs/RSIDs. I was building it to do manipulations of the songs and dumping to register usage logs but I never finished it. I got more interested in doing the decompilation tools and started building some IDE type tools to manage (assemble, disassemble, link, unlink to/from archives etc, etc) relocatable o65 objects. Another project collecting dust...

However, I have built a software synthesiser inspired by the Roland Gaia using a ReSID core which I converted to Pascal from the C++ (out of VICE, I admit because the implementation in VICE is more efficient). I found a few bugs (fatal crash, memory corruption, still incorrect voice output range mapping) in the VICE ReSID implementation which they are effectively not seeing because of the way they use it but I haven't reported them yet (*tsk*). I've also started implementing a few "improvements" but I still haven't translated the ASM parts. Don't know why (wasn't using them because I was only using linear interpolation?)... Delphi has an internal failure compiling it with the inline function support turned on. I have reported the bug to Embarcadero but they'd moved on from my version (XE4) and they have never, even in the late Borland days, done these kind of patches to releases pre-dating the current. The FPC compiled version isn't any better performing on Windows but it really flies running on Linux (of course).

I ended up just using VICE's vsid (or even just x64) to do the dumps from the PSIDs/RSIDs which I can then translate into something like a MIDI file format using a tool I built for the purpose. I can then play back the song on my synth engine. You can of course play the synth with an on-screen keyboard (mostly implemented and as yet incomplete but will be the same as the Gaia for handling multiple oscillator usage via the keyboard). The synth reuses the waveform and envelope generators of the SID for LFO generation, as well (just clocked differently and mapped via the same kind of "matrix" - but not really - control on the Gaia to modulate other outputs). I haven't implemented MIDI input on it yet because I was investigating the best (most compatible with other software) way of doing it and accidentally made the program run very slowly (unusable) on my old machine (7 years old?) with some "crazy" experimental code. The LFOs are probably still clocked too fast because they are well into the audio frequency range but I was trying to make sure I covered what could be done on a C64 with an 8x player. Its probably too much.

I have a new computer now and I should fix it and finish it. Its a nice project and I would actually use it. I even use it occasionally to play SID tunes because I hand-tweaked (by audio comparison) the settings and it has a nice peak meter... Hehe.

I'm hoping my song file format (which I call XSID) will be endorsed by the community when I release it because it allows exact song lengths, it entirely seek-able in the same way that a MIDI file is (it is seekable by event and the events are effectively time-stamped), can be stream-able, is simpler to play back (only the SID and a tick counter required), can be translated on the fly between SID and C64 versions, can have in-built filter config information for best playback and it is much, much smaller than an MP3 file (of course) although still bigger than a PSID/RSID. I'm sure there are other benefits, too and I'm still working out the specifications for the release version. I'm working on a new compression scheme based on some readings about 64KB demo synthesisers but it won't be stream-able and seeking would be a bit of a mess. Implementing my own dumping tool and improving the manipulation tools is a bit more of a priority.

Anyway, I've gone off topic a bit. The point is that I had some of the code I needed, already.

I've collected a lot of the information I need into an emulation "cheat sheet" kind of document from different sources. While I was doing that, I got started working on a better version of the C64 Programmer's Reference Guide (better as in from the "Project 64" version) with the missing graphics and some nice artwork inspired by the original in ODT format (could be produced as PDF) and a couple of corrections (but I've stopped short in my temptation to correct the "English" into real English... Haha). Its layed-out correctly (paginated properly) on A5 pages so it would print something like the original, too. Actually, it looks great and fits really nicely on A5. I'm revising the header/footers and adding hyper links to the contents and index because I think that could be valuable to the community (I use the "Project 64" conversion all of the time and having a "proper" electronic version would be so nice). I will also embed the correct Petscii glyphs and convert all of the Ascii tables and diagrams into graphical ones. *whew*

I've studied some schematics diagrams for the C64, too. So I did a clear day's worth of pure investigation before I started. All-in-all I think I've developed a pretty good idea of what the VIC-II emulation needs to do which helps in implementing it. The PLA and memory buses are a little less clear to me but I'm starting to get it.

Dang, drifting off yet again.

I think you are correct about it being determined by the graphics hardware or OpenGL interface. Its just strange because its not immediately obvious what it is exactly because I haven't enabled vsync. I think I do remember reading somewhere that its actually turned on by default. I will see if changing it helps. I just didn't think of it until after my post because I hadn't enabled it even though I was thinking the graphics hardware was involved because of the 60Hz lock in. I thought it might be Windows...

Thanks for your feedback! I'll post an update when I've tried changing the vsync setting of OpenGL.


Daniel.


PS: Argh! I almost lost my post because I had to log in again!


Top
 Profile  
Reply with quote  
PostPosted: Wed Dec 17, 2014 7:47 pm 
Offline

Joined: Sat Dec 13, 2014 6:59 pm
Posts: 3
Hmm... Turning off VSync doesn't seem to get me anywhere. Either the emulation tries to run at some 80+Hz and is unstable or just looks strange or I try to get it to stay at 50Hz and it is still unstable.

I think the problem is more prevalent for my implementation because it is multi-threaded, unless I am still doing something wrong... The user interface and the "multimedia output" run in the main thread, the VIC-II (and clocks and probably system buses) in its own thread, the SID runs in another thread and I will implement the 6510 in yet another one, too (although this probably isn't necessary and it could possibly be argued as incorrect).

I have decided the best thing to do is to decouple the frame display/updating and the emulation VIC-II and clocks. The front-end can then update at whatever speed it is happy with and I'll make sure that new frames are only presented at the correct rate by directly controlling Phi0. Effectively I was trying to control the dot clock PhiIN by the frame display rate which would have a flow down effect to Phi0 but I can see how this isn't ideal.

It will mean that I have two frame rates but that's no big deal. Actually, decoupling the "multimedia output" will probably work out for the best in the future, anyway.


Daniel.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: