AppleWin / AppleWin

Apple II emulator for Windows
GNU General Public License v2.0
703 stars 162 forks source link

Linux, AppleWin & Qt #538

Open audetto opened 6 years ago

audetto commented 6 years ago

Hi,

I would like to share a little project on which I have worked in the last months. It is a port of AppleWin to a native linux application based on Qt.

It is available here https://github.com/audetto/AppleWin

It is actually 2 ports, one to ncurses and one to Qt as described in https://github.com/audetto/AppleWin/blob/master/linux.md.

I have written 2 frontends to better understand what is emulator code and what is frontend.

I have reached a point where "normal" emulator features are in a usable state and don't feel embarrassed any longer to share it.

The main goal of this exercise is the following: keep merging from AppleWin trivial. I do not want to spend ages to merge and for this reason very few changes to the AppleWin source files have been allowed. Mostly to fix unavoidable compilation errors in gcc or when the cost of making the code compile was too high (see the #ifdef at the end of MouseInterface.cpp).

What about graphics? It is very similar to linapple (maybe like AppleWin 1.25), lo res in color, hi res in BW. No options, and I don't think I am making good usage of OpenGL.

What's next? Good question!

I don't really know myself. I would definitely like to commit to AppleWin all the "pure c++" changes to make merging even easier, and I will create a branch for this if anyone is interested.

Why Qt? Why not SDL? To be honest I have chosen Qt because it provides so many UI widgets and features that I had no idea how to create in SDL. But at the same time I have realised that timers in Qt are nowhere as precise as in Windows.

More features? Audio? libretro? debugger (there is too much Win32 code in the debugger files to be used as they are)? Android? Depends on time.

Anyway, guess I will stop when the fun stops.

audetto commented 6 years ago

Here is the branch that includes the minimum set changes to compile with gcc.

https://github.com/audetto/AppleWin/tree/gcc

It is just for information for the time being. It needs a little work to ensure it works in VS as well.

snaxxus commented 6 years ago

Thank you!

On Feb 10, 2018 1:16 PM, "Andrea" notifications@github.com wrote:

Hi,

I would like to share a little project on which I have worked in the last months. It is a port of AppleWin to a native linux application based on Qt.

It is available here https://github.com/audetto/AppleWin

It is actually 2 ports, one to ncurses and one to Qt as described in https://github.com/audetto/AppleWin/blob/master/linux.md.

I have written 2 frontends to better understand what is emulator code and what is frontend.

I have reached a point where "normal" emulator features are in a usable state and don't feel embarrassed any longer to share it.

The main goal of this exercise is the following: keep merging from AppleWin trivial. I do not want to spend ages to merge and for this reason very few changes to the AppleWin source files have been allowed. Mostly to fix unavoidable compilation errors in gcc or when the cost of making the code compile was too high (see the #ifdef at the end of MouseInterface.cpp).

What about graphics? It is very similar to linapple (maybe like AppleWin 1.25), lo res in color, hi res in BW. No options, and I don't think I am making good usage of OpenGL.

What's next? Good question!

I don't really know myself. I would definitely like to commit to AppleWin all the "pure c++" changes to make merging even easier, and I will create a branch for this if anyone is interested.

Why Qt? Why not SDL? To be honest I have chosen Qt because it provides so many UI widgets and features that I had no idea how to create in SDL. But at the same time I have realised that timers in Qt are nowhere as precise as in Windows.

More features? Audio? libretro? debugger (there is too much Win32 code in the debugger files to be used as they are)? Android? Depends on time.

Anyway, guess I will stop when the fun stops.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/AppleWin/AppleWin/issues/538, or mute the thread https://github.com/notifications/unsubscribe-auth/AY4qZes49EE1iIUYLdiu6xz09IRZz0T1ks5tTdzlgaJpZM4SBBcf .

sicklittlemonkey commented 6 years ago

It is a port of AppleWin to a native linux application based on Qt.

Great.

I have written 2 frontends to better understand what is emulator code and what is frontend.

It would be awesome to have a truly cross-platform AppleWin and abstract away the OS dependent parts.

The main goal of this exercise is the following: keep merging from AppleWin trivial.

Fair enough.

I don't really know myself. I would definitely like to commit to AppleWin all the "pure c++" changes to make merging even easier, and I will create a branch for this if anyone is interested.

Sounds good! I hope Tom agrees.

Cheers, Nick.

audetto commented 6 years ago

This is a better branch to look at

https://github.com/audetto/AppleWin/tree/gcc_vs

These are most of the changes required and it compiles in VS2017 as well.

1) const char * 2) NULL or 0 3) include 4) HDD, Disk_t 5) unzOpen 6) delete [] vs free 7) remove a static 8) memimage = newloc (required to run under valgrind)

They could be split into multiple commits if there is an interest in integrating them.

Andrea

tomcw commented 6 years ago

Hi Andrea,

I took a very quick look at your Linux/Qt branch. I think if we do this, then we should think about design (eg. front-end, common core and platform specific), and also project structure (source code layout). I appreciate that your current layout is just to minimise your merge pain.

I think we need a solid plan for this before proceeding. Obviously you've taken a stab at this, so perhaps you can share your thoughts?

I'd also like to get Michael's (@Michaelangel007) input, as I know he's looked at SDL in the past (see: #184, #223, #274). But he's currently on sabbatical.

re. patches to compile with gcc

They could be split into multiple commits if there is an interest in integrating them.

I think it's OK to just put all the commits into a single pull-request.

Thanks.

audetto commented 6 years ago

I will make a pull request for the changes.

My thoughts about this exercise so far are

I think that splitting emulator code from frontend could be a start and ensure that one can create a "headless" AppleWin which has no interaction with the outside world (except disk maybe), without pulling in non required code.

Andrea

audetto commented 6 years ago

I've settled for this branch, https://github.com/audetto/AppleWin/tree/gcc_vs2

It is basically everything where I could find some common ground. There are a few more little things, but I did not want to add #ifdef.

Andrea

tomcw commented 6 years ago

FTR, @audetto created PR #539, which was then superseded by PR #541. This latter PR then got merged into master.

rmacri commented 6 years ago

From personal experience with the simulator (logistics) I develop, its very healthy having a codebase that compiles cleanly with both Visual Studio and gcc, each nitpicks differently. In my case I can build with Visual Studio 2018 (32 or 64 bit Windows, full graphical editing/animation), MinGW/gcc (32 bit Windows graphical Windows app as per VS) and plain gcc (Linux batch run only, no UI, made possible by a toolkit layer and my own "windoze.h' stub). No demand for Linux graphical sadly so its not been worth my while even trying Winelib let alone Qt. The main body of work has very few conditional compiles. Not sure how MinGW would go with DirectSound etc, AppleWin is more demanding library wise. I could write a lot more on same code performance comparison discoveries.

xandark commented 6 years ago

I can't tell you how happy I am to hear that steps are being made to bring AppleWin to Qt and thus to all platforms. Now I'll be able to run it natively on Linux, woohoo!

audetto commented 6 years ago

Please give it a try. I don't think anyone else has ever tried to compile it. Open an issue there if you have problems.

Probably the single most annoying thing is missing audio. I've written it, but I have not fully understood QT Audio times so it drifts after a while especially when the emulator goes at maximum speed.

Michaelangel007 commented 6 years ago

Catching up on stuff here.

@tomcw Feel free to shoot me an email if there is anything you want me to take a look at. I'm still not sure when my sabbatical is over -- but I can always make time to take a quick look at stuff.

@audetto Thanks for all the work and feedback.

Some quick feedback:

Regardless if we go Qt or SDL someone has to do all the grunt work of removing all the "Win32ism" deeply embedded in the application. Audetto, it looks like you have started this process? That's great to hear!

Personally, I would like to see a "clean SDL" version of AppleWin that builds across Windows, OSX (er, macOS), and Linux down the road.

One of the reasons we "failed" to merge LinApple is that the debugger got removed. /oblg. Not Cool, Man! :-1:

Temporarily stubbing functionality out is OK in the short-term but not long-term. And yeah, I probably should make a pass on cleaning up all the Win32 stuff in the debugger section(s).

Since rewriting a new version from scratch really isn't really feasible and AppleWin has been extremely organic we'll just have to manage the complexity of re-factoring code as it comes up.

I am excited to see people using gcc to compile AppleWin! The sooner we address portability issues, and compile with MSVC, GCC, and Clang the better we are. At some point we probably should put together a C++ usage guide -- if we haven't already -- to keep all the bloated C++ crap to a minimum. (Which I thing we've done a pretty good job of.) Hopefully we shouldn't have any compiler dependency stuff?

I think the first order of business would be to make a pass over the all the Win32 types: BYTE, DWORD, etc and convert these to standard C++ types: uint8_t, uint16_t, uint32_t wherever possible. Obviously we can't remove all the Win32 cruft but we can phase this out.

I really like the idea of your own windoze.h wrapper! In theory we should be able to switch to Qt or SDL on the back-end but in practice we'll have to see how much coupling we have with Win32.

Also, I'm an older MSVC version (2010) -- if things don't work there I can't test it out. At some point I'll install MSVC 2017 (2018?) -- hopefully we can get everyone on board with at least the same (Windows) compiler.

OK, enough rambling.

@tomcw Tom, was there anything in particular you wanted me to take a look at?

@audetto I don't see your branches anymore? Did they get moved / renamed?

audetto commented 6 years ago

About Qt vs SDL, I still believe a hard choice is not required. If the "emulator" code is separated into a library then many different frontends can coexist: I wanted to try to create a version for libretro but have not found the time yet. As I said in the original post, this helps a lot in understanding where to set the boundary. Maybe a quick look at other projects (VICE, N64...) could provide some inspiration.

Agreed on the Win32 types, I would remove all the Win32 specific Memory Management and String Manipulations: I think here C++ could help a lot using vectors, strings, shared ptr. And after that, all the file manipulations but I don't think there is such a standard set of API to access folders and file attributes. The version in Linux works as a 64bit app: ensuring it works 32/64 helps as well. I have compiled AppleWin as a 64 bit app, but it required a few changes to more portable version of some Win32 APIs (forgot which ones right now...)

About the debugger: you can't really blame LinApple for dropping it, it is just too much interleaved with Win32 functions. I have done exactly the same: the only alternative being a complete rewrite, but this was against my goal to reuse most of the code.

Another thing which I found difficult was to have a bit-by-bit reproducible runs to debug and compare different versions. I was not able to use existing options to achieve this so I changed some of the "non deterministic" parts to be able to do this. Maybe worth adding such a flag.

Then there is all the NTSC stuff which honestly I did not understand a bit ...

The branch is still present here

https://github.com/audetto/AppleWin

xandark commented 6 years ago

Regarding this thought:

Qt, while being functional complete. is NOT light-weight.

Is that a specific, stated goal of AppleWin? To be light-weight?

I'd like to present the case for Qt. With Qt, one significant advantage is that the GUI style automatically adapts to user's platform and is thematically congruent.

Because Qt has paid, professional developers evolving it constantly, it is terrifically cross-platform and will even adapt to Android, iOS, embedded platforms, and whatever else comes up in the future.

Qt is also modular, and the full stack doesn't have to ship with every Qt shared library.

For example, the 4k Video Downloader utility uses Qt and it ships with just 9 Qt dll's for its particular use case. I've recommended this utility to several friends who use differing OS's and none of them complain about the size of the download; they're just happy to have something that works elegantly for them and is intuitive to use.

Michaelangel007 commented 6 years ago

I'm strongly against including Yet-Another-C++-Library such as Qt for the reason mentioned above -- swapping out the "fat" Win32 API for another "fat" Qt API isn't really solving the problem long term.

A light-weight goal isn't a explicit goal but an implicit one. I come from a professional game developer background and detest the bloated C++ style of including everything and the kitchen sink. Qt falls in this category as well -- bloated compile times and a bloated exe.

it ships with just 9 Qt dll's

I rest my case. AppleWin doesn't ship with any .dll's because it doesn't need them; 1 file is easier to manage then X of them.

KISS is the goal here. We should be only including the bare minimum of code to get the job done.

Likewise we should be keeping the C++ usage to a minimum. If we need to use std::shared_ptr then we are probably doing something wrong.

A user should be able to download the AppleWin source and immediately be able to compile it. They shouldn't need to download a billion dependencies.

From past SDL2 experience:

Going with SDL2 has a few benefits:

The problem with frameworks is that they work great for getting something up and running but as soon as you try to do something outside their design they become a hindrance. I can guarantee we won't have that problem with SDL2 due to its design philosophy of being a thin veneer -- I can't say the same for Qt. Is it possible Qt could meet our needs? Potentially. Can I guarantee that with Qt? Nope.

What UI frameworks are other emulators using? SDL? Qt? Their own?

Emulators that we should be looking at include:

We already know these ones:

Yes, sadly the debugger is pretty integrated with Win32, so I don't blame LinApple in any fashion for dropping it. Sheldon's NTSC port dropped it too -- that's a sign it needs to be cleaned up and made more portable.

In an ideal world we would have both SDL and Qt versions -- that would provide an apple-to-apples comparison.

I don't speak for the rest of the team but my vote is:

Those are my thoughts.

sicklittlemonkey commented 6 years ago

Yes, sadly the debugger is pretty integrated with Win32, so I don't blame LinApple in any fashion for dropping it. Sheldon's NTSC port dropped it too -- that's a sign it needs to be cleaned up and made more portable.

It would be great to abstract this to an interface get/set memory/softswitch/register/breakpoint etc. We could have a separate debugger (process) Window.

Cheers, Nick.

sicklittlemonkey commented 6 years ago

Re Qt etc, what about: https://www.wxwidgets.org/ http://www.fltk.org/index.php

They supposedly both support OpenGL.

Cheers, Nick.

ryanmusante commented 5 years ago

Is this thread still open for discussion?

DXVK is a compatibility layer for Linux that translates Direct3D calls to Vulkan. Is there a way of implementing something similar for AppleWin? DXVK requires MinGW for compiler support yet it is multi platform.

AppleWin could run inside a compatiblity layer as a workaround until or if there was native support for it to function multi platform.

audetto commented 5 years ago

Hi,

when I opened the issue, I had in mind a real native portable application that could work on a Pi as well.

I still keep the fork updated (except the video code which I never fully understood, it is similar to linapple).

Andrea

abcbarryn commented 5 years ago

Is this still up to date? I was going to try and build a Mac .app package using this code.

tomcw commented 5 years ago

@audetto said:

when I opened the issue, I had in mind a real native portable application that could work on a Pi as well.

From csa2, "Alternatives to Ciderpress", this comment:

I just checked again and I tried installing WINE on my Raspberry Pi 4 with no x86 emulator. It works!

It'd be interesting to try AppleWin on Wine on a RPi4.

tomcw commented 5 years ago

@abcbarryn:

Is this still up to date? I was going to try and build a Mac .app package using this code.

I don't know - can anyone else comment?

audetto commented 5 years ago

Is this still up to date? I was going to try and build a Mac .app package using this code.

I've just updated it to the current master from AppleWin.

Same caveats apply: video rendering is naive and there is no audio as of now.

abcbarryn commented 5 years ago

Darn! No audio eh? I may have to play with it anyway though I'll probably keep using the regular copy via Wine for now. Thanks for your efforts. Maybe I can get the audio working, who knows...

audetto commented 5 years ago

To be honest, audio is easy

https://github.com/audetto/AppleWin/tree/audio

(this is an out of date branch implementing audio).

Problem is the reliability, I struggled to understand exactly when QT needs / accepts more samples, so it can drift...

I need to write an exact model for it and resuscitate it.

audetto commented 4 years ago

@abcbarryn there is audio now. It is in the branch audio2. I am happy with it. Unfortunately I cannot do better than the quality of qt timers. Unless you resize the main window, it works well and tries to automatically recover from under-runs.

A quick questions to AppleWin users: what is a good title that plays a lot of music, so I can test a bit better (been using karateka so far). And I wanted to see if Mockingboard can be supported too: what is a good title using it?

tomcw commented 4 years ago

A quick questions to AppleWin users: what is a good title that plays a lot of music, so I can test a bit better (been using karateka so far). And I wanted to see if Mockingboard can be supported too: what is a good title using it?

Are you aware of the AppleWin-Test project, here?

You can use this to run the same tests I use before releasing AppleWin, and it includes speaker and Mockingboard tests.

Specifically (but far from complete coverage):

audetto commented 4 years ago

Perfect, I will try them.

audetto commented 4 years ago

Another milestone in the Linux port.

The AppleWin's NTSC code is now executed natively, which means all the video update are exactly the same.

On one hand it fells great, on the other it feels that at some point I will have reused enough of AppleWin that it will be just AppleWin, except it does not run in wine...

Anyway as long as it is fun it will last...

One thing to note is the CPU consumption

Basically the code emulator is just running AppleWin code. So either my Win 7 PC is just 4x faster or Visual Studio does a fantastic job as optimising the NTSC code.

What is your experience?

How do you measure the speed of AW?

tomcw commented 4 years ago

What is your experience?

1. Task Manager

AppleWin 1.29.6.0 on my Win7-64, AMD Phenom II dual-core @3ghz:

NB. different video modes/settings (50% vs 100%; RGB Monitor vs Color TV; 1x vs 2x) take more or less time. 50%/RGB Monitor/1x/No Vertical Blend is the quickest. ('Vertical Blend' can only be enabled for RGB Monitor.)

On Windows, AppleWin is built as 32-bit. Are you building 32 or 64-bit on Linux?

2. AZTEC.DSK boot time

Another thing I do to test the speed is time how long it takes to boot AZTEC.DSK. If you enable logging (-log) then from a power-cycle (F2) AppleWin can be repeatedly used to time how long until the "Press any key" message (ie. BIT $C000).

applewin.exe -log -d1 aztec.dsk

Then examine the resulting log file, searching for "$C000", Eg. 1.29.6.0, 50% Color, RGB Monitor, 1x, Vertical Blend:

Time from emulation reboot until first $C000 access: 764 msec
Time from emulation reboot until first $C000 access: 749 msec
Time from emulation reboot until first $C000 access: 749 msec

3. Built-in benchmark

Configuration -> Benchmark Emulator.

Not all the numbers are particularly meaningful. I tend to look at 'Pure CPU MHz (video update)' and 'Pure CPU MHz (full-speed)' - ie. full-speed with & without video update.

See #424 for some recent data.

audetto commented 4 years ago

Time from emulation reboot until first $C000 access: 749 mse

This is not so easy as it depends a lot on the full speed / real time policy.

I wanted to compare the actual CPU emulator time so 1) cpu video update = true / false 2) no sleep (like in full speed) 3) no screen blit

Which I can do in mine. I will have to modify AW code and test on the other PC.

Then I get either 112 (video update = false), 1041 (video update = true) This uses the default TV NTSC code.

tomcw commented 4 years ago

Then I get either 112 (video update = false), 1041 (video update = true)

To be clear: are these numbers in msec? and for Aztec boot times?

audetto commented 4 years ago

Yes, it is the output of LogFileTimeUntilFirstKeyRead(void) of Aztec. btw, it is a 64 bit app.

First one is:

Second one is:

This is compatible with vtune output. Because it is running full-throttle it is difficult to compare with Windows, just that 85% time is spent in VideoUpdate, so any improvement there will be really noticeable.

Screenshot from 2019-11-23 20-43-49

audetto commented 4 years ago

Extremely odd results. First in AppleWin in wine (RGB Vertical blend), 2nd my Qt port (Color TV)

Screenshot from 2019-11-23 21-33-33 Screenshot from 2019-11-23 21-32-58

I am definitely doing something odd

audetto commented 4 years ago

One question:

just realised that different apps report CPU usage in different ways. when I say 20% I mean 20% of 1 CPU, not 20% of the total CPU power

Screenshot from 2019-11-23 21-44-03

It can be 21% above and 5% below

tomcw commented 4 years ago

re. your Benchmark data

Can you do the test using the same video mode? (You did Wine/RGB-Monitor vs QT/Color-TV)

For reference these are my Win7-64 (AMD Phenon-II) numbers for AppleWin 1.29.6.0. For 'Pure CPU MHz/video-update', you can see that 'Color (RGB Monitor)' (with Vertical blend) is ~75% of 'Color TV', whereas you see ~50%.. but under different environments (Wine vs QT).

Color (RGB Monitor), 50%, Windowed-1x, Vertical Blend

Pure Video FPS: 398 hires, 400 text Pure CPU MHz: 7.6 (video update) Pure CPU MHz: 245.1 (full-speed)

EXPECTED AVERAGE VIDEO GAME PERFORMANCE: 342 FPS

Color (RGB Monitor), 50%, Windowed-1x, No Vertical Blend

Pure Video FPS: 405 hires, 399 text Pure CPU MHz: 18.9 (video update) Pure CPU MHz: 246.1 (full-speed)

EXPECTED AVERAGE VIDEO GAME PERFORMANCE: 387 FPS

Color TV, 50%, Windowed-1x

Pure Video FPS: 398 hires, 402 text Pure CPU MHz: 10.8 (video update) Pure CPU MHz: 245.9 (full-speed)

EXPECTED AVERAGE VIDEO GAME PERFORMANCE: 375 FPS

tomcw commented 4 years ago

just realised that different apps report CPU usage in different ways.

Yeah. For Windows Task Manager the CPU Usage is for Total CPU (not core).

So on my dual-core system at most, AppleWin (release build) uses 2%(upper-bound) of a core (assuming that the 0% reported by Task Manager is ~0.9% and doubling to get rough core usage).

audetto commented 4 years ago

These are my benchmarks I take that Windowed-1x means the normal size

RGB Monitor, 50%, Vertical

RGB Monitor, 50%, No Vertical

Color TV, 50%, No Vertical

Does it make sense? Not sure... Strange the vertical blend has no impact. Will need to dig further.

But first an observation:

audetto commented 4 years ago

Running with vertical blend:

Screenshot from 2019-11-25 21-58-48

you can see the CopyMixedSource

and without vertical blend

Screenshot from 2019-11-25 22-03-02

It takes more or less the same time... could it be a better/different optimiser?

Times are cumulative, so MixColorVerticals is included in the function above.

If I factor these 2 calls to the top of CopySource I get a much better non vertical blend result

bool half = IsVideoStyle(VS_HALF_SCANLINES); int ww = GetFrameBufferWidth();

RGB Monitor, 50%, No Vertical

tomcw commented 4 years ago

I take that Windowed-1x means the normal size[?]

Yes.

Your results are faster than mine - eg. comparing with "Pure CPU MHz: XX.X (video update)".

Also my RGB (No Vert Blend) is faster than NTSC (Color TV), whereas your NTSC (Color TV) is faster than RGB.

What CPU & CPU frequency are you running on?

audetto commented 4 years ago

model name : Intel(R) Core(TM) i5-4460 CPU @ 3.20GHz

I am puzzled by the CPU utilisation, but maybe it is a very poor indicator and subject to so many more things... With the code change I mentioned, my fasted mode is again RGB No Vertical.

This is probably a different compiler optimisation.

audetto commented 4 years ago

Looking at all this, I think the Task Manager CPU utilization is misleading. Take your results for

At full throttle (i.e. 100% of 1 CPU), it can do 375 FPS. To go at real speed, it needs to go at 60 FPS, which is 1/6 of the speed, so it needs to sleep on average 5/6 of the time. This implies 16.6% of 1 CPU. How come Task Manager reports < 1%?

In my results this is more as one would expect. I get FPS between 311 and 352 which means between 17% and 19% of 1 CPU. Add a little of Qt overhead and I get the 20-21% reported by top.

What seems to be clear is that I need to improve the repaint screen speed.

audetto commented 4 years ago

Have a look at this

https://github.com/AppleWin/AppleWin/pull/730

I get a massive speedup in RGB for non vertical blend both in Windows and Linux. Little improvement for vertical blend too.

tomcw commented 4 years ago

Nice speed-ups! Thanks (merged now).

tomcw commented 4 years ago

NB. For Pure CPU MHz (video update) these configs make a difference:

audetto commented 4 years ago

You can use this to run the same tests I use before releasing AppleWin, and it includes speaker and Mockingboard tests.

Specifically (but far from complete coverage):

* speaker: Archon (archon_i.aws.yaml) and PoP (Prince of Persia.aws.yaml)

* Mockingboard: Cybernoid (Cybernoid*.aws.yaml)

I finally got some time to work on this. Managed to compile MockingBird.cpp (stabbing out a few things of course).

I know I could read the code and step through, but I wonder if someone could give me a very high-level overview of what the Card does, or what it is supposed to do.

Something like: 3 oscillators (sin? square?), with some envelope...., volume... I read the word phoneme and I get confused.

I want to have a go to implement the linux version of whatever it does...

tomcw commented 4 years ago

Mockingboard = 2x 6522 + 2x AY-3-8913 + (optional) 1x SSI263 speech chip

Each AY-3-8913 has 3x square wave channels + noise. So pretty simple.

AppleWin's implementation is a ring-buffer for the sound, and periodically (eg. every ~1000 cycles) it gets updated with new samples. But IIRC, AppleWin will also update the buffer after a 6522 timer interrupt too.

There's low-level emulation of the AY-3-8913 in AY8910.cpp, which takes AY register changes as inputs, and is called periodically to output a set of new samples, which are then mixed with the other channels and copied into the ring buffer.

The ring-buffer support is in Mockingboard.cpp. Also in Mockingboard.cpp is the 6522 emulation and the SSI263 emulation.

Currently the SSI263 is done by playing back a phoneme sample as a "one-shot" sample (so no a ring buffer). NB. A phoneme is just a fragment of sound that can be played back as a sequence to form a word. There are 64 phonemes, and AppleWin just has a sample for each one... so very basic emulation, resulting in very crude speech emulation. I am currently trying to improve this, and I will switch from a "one-shot" to a ring buffer for the speech phonemes too.

You could ignore the SSI263 for now, and just focus on the AY-3-8913. If you already have speaker support, then it's more or less the same ring-buffer solution.

audetto commented 4 years ago

Looking at the AY-3-8913, is this the line where the samples are added to each buffer

https://github.com/AppleWin/AppleWin/blob/master/source/Mockingboard.cpp#L893

and this where they are mixed together?

https://github.com/AppleWin/AppleWin/blob/master/source/Mockingboard.cpp#L975

I will try to write to a file and see if they sound correctly.

tomcw commented 4 years ago

Yes, that's right.

btw, you can also #define RIFF_MB (in SoundCore.h) to enable writing the Mockingboard buffer to a .wav file, eg. done at the end of that function is this line: https://github.com/AppleWin/AppleWin/blob/e48ea095a3eea6d6c58f28bad6ed8502111dd6a1/source/Mockingboard.cpp#L1020

audetto commented 4 years ago

I am understanding how it works and it is not too bad.

One question about this block https://github.com/AppleWin/AppleWin/blob/master/source/Mockingboard.cpp#L902

Why not just use dwCurrentWriteCursor rather than keeping a similar looking offset dwByteOffset? Similar but not exactly the same?

Moreover, there is something which does not look right to me: This line https://github.com/AppleWin/AppleWin/blob/master/source/Mockingboard.cpp#L907 is ever executed only once per run of AppleWin (being static, and never reset to -1).

On the other hand the buffer in MockingboardVoice is created each time MB_DSInit() is called, and it can indeed be called multiple times.

So surely the initialisation should re happen for each new buffer. (is this correct?) I think that if dwByteOffset is actually needed, it should go inside VOICE, to be reinitialised with the buffer.

What do you think?