Mac PoP emulation
Re: Mac PoP emulation
Players appear to agree that the Macintosh port plays slower than the original Apple II game and than most ports (including DOS, SNES). I've experienced this too and have also seen this in recordings, such as this video. According to DavidXNewton, perhaps the game was tuned (intended) to run slower than the PC version. This raises the question: a hex edit to tweak the DOS speed, is a similar hex edit possible with the Macintosh port? When emulating the game on my PC, BasiliskII hovers around 87% of a single CPU core, which might indicate that while the emulation is non-optimal, it's not causing the slower game speed.
Re: Mac PoP emulation
According to my tests, it actually does run slower on BasiliskII.
Re: Mac PoP emulation
Frame times are defined here:
Code: Select all
03:14a6: 0c 2d 00 02 b9 76 CMP.B #0x0002,(D_B976,A5) ; Kid.sword
03:14ac: 66 08 BNE B_14B6
03:14ae: 70 06 MOVEQ #0x06,D0 ; <-- speed when fighting (smaller is faster)
03:14b0: 2b 40 96 4c MOVE D0,(D_964C,A5) ; frame time
03:14b4: 60 06 BRA B_14BC
03:14b6: 70 05 MOVEQ #0x05,D0 ; <-- speed when not fighting (smaller is faster)
03:14b8: 2b 40 96 4c MOVE D0,(D_964C,A5) ; frame time
03:14bc: 70 00 MOVEQ #0x00,D0
03:14be: 60 1c BRA B_14DC
This is the code that executes the timings:
Code: Select all
02:00ee: 42 a7 CLR -(A7)
02:00f0: a9 75 _TickCount
02:00f2: 2b 5f a5 62 MOVE (A7)+,(D_A562,A5) ; current ticks
02:00f6: 4e ba 2b 12 JSR (D_2B12,PC) ; = 02:2C0A
02:00fa: 20 2d a5 62 MOVE (D_A562,A5),D0 ; current ticks
02:00fe: 90 ad a5 5e SUB (D_A55E,A5),D0 ; previous ticks
02:0102: b0 ad 96 4c CMP (D_964C,A5),D0 ; frame time
02:0106: 6f e6 BLE B_00EE
02:0108: 2b 6d a5 62 a5 5e MOVE (D_A562,A5),(D_A55E,A5) ; current ticks ; previous ticks
The DOS version sets the system timer to the same frequency, and the length of a frame in ticks (6 or 5) also matches the DOS version, so I don't know why is the Mac version slower.
This is the above code in C:
Code: Select all
do {
current_ticks = TickCount();
sub_02_2C0A();
} while(current_ticks - previous_ticks <= frame_time);
previous_ticks = current_ticks;
Consider this:
Suppose that the previous waiting ended when TickCount() returned some T value. Then previous_ticks = T.
Then suppose that frame_time = 5.
Now, the loop condition will be true when TickCount() returns T+5, because (T+5) - T <= 5 is true.
So the loop will stop when TickCount() returns T+6 !
This means that 6 ticks have elapsed since the end of the previous waiting, with is 1 tick (1/60 second) too much!
At least this is what I think.
Re: Mac PoP emulation
I have another theory...
The 1/60 sec. looks like a default monitor refresh rate (60hz) and I think thats what it is. However, back when Prince of Persia was released, the default refresh rate was 67hz. So that comparison was good to have a speed as close as possible to the DOS version.
The 1/60 sec. looks like a default monitor refresh rate (60hz) and I think thats what it is. However, back when Prince of Persia was released, the default refresh rate was 67hz. So that comparison was good to have a speed as close as possible to the DOS version.
Re: Mac PoP emulation
Indeed, the docs say that the tick count is incremented at vertical retrace.
Thanks, I didn't know that.
I found something about that here: https://en.wikipedia.org/wiki/Extended_ ... ation_Data
But then why don't emulators follow this?
Strangely, this page says a different refresh rate:
But this doesn't say anything about Macintosh computers that don't have a built-in screen.On Macintosh computers that have a built-in screen (such as the Macintosh Plus or Macintosh Classic), the vertical retrace frequency is approximately 60.15 Hz,
DOS: 5/60 = 0,0833
Mac: 6/67 = 0,0895
and
DOS: 6/60 = 0,1
Mac: 7/67 = 0,1044
Well, it seems close enough.
Re: Mac PoP emulation
Hey, your question made me look up and notice that Basilisk II is set to just 10Hz by default. Setting this to 60Hz finally makes using System 7 bearable. And then making the PoP1 playing speed faster, from 5 to 3 (at 0x9F07 in the .bin), finally makes the game playable. So, your post killed two guards with one sword. For a next popyorn release I'll add a note about the Basilisk II "Window Refresh Rate" to the hover text, and I'll make the game's speed settings modifiable via the EXE screen.
Re: Mac PoP emulation
I experimented with changing the speed of Mini vMac to match a refresh rate of 67 Hz.
I can confirm that PoP 1 and 2 run much better after making some changes.
There is still a problem with the sound though (it does not completely match the timing).
I wrote a message about this problem to Paul Pratt, the developer of Mini vMac (mailing list).
I can confirm that PoP 1 and 2 run much better after making some changes.
There is still a problem with the sound though (it does not completely match the timing).
I wrote a message about this problem to Paul Pratt, the developer of Mini vMac (mailing list).
See the attachment for a Windows x86 build where I applied the changes (Use F1 for Control Mode).Hi Paul,
Prince of Persia runs noticably too slowly on emulators, including Mini vMac.
There is some discussion about that here:
viewtopic.php?f=63&t=3009&start=15#p24520
Apparently the Mac II had a refresh rate of 67 Hz, instead of 60.14742 Hz. Prince of Persia relies on _TickCount for frame timing, which is incremented at every vertical retrace interrupt. Hence the too slow gameplay.
(Running on Windows x86) I tried changing MyInvTimeStep in OSGLUWIN.C from 1089590 to 987149 (=1000/67*MyInvTimeDiv), and the constant in CyclesScaledPerTick in PROGMAIN.C from 130240UL to 116919UL (=7833600/67). After making these changes, the gameplay speed seems to be correct, although there are some issues. Most notably, sound becomes garbled. I can reduce the number of samples per subtick from 370 to 332 like so in ASCEMDEV.C:
// (22254.54545 / 67) / 16 = 20.75 samples per subtick
LOCALVAR const ui3r SubTick_n[kNumSubTicks] = {
21, 21, 21, 20, 21, 21, 21, 20,
21, 21, 21, 20, 21, 21, 21, 20
};
But, that causes noticable skipping in the sound... I don't know what is the correct fix for this.
Would you be willing to address these timing-related issues in Mini vMac? It would be great to be able to emulate Prince of Persia, and other games, at the intended speed and without sound hitches!
Thanks!
- Attachments
-
- minivmac_67Hz_F1_is_control_mode.zip
- (123.3 KiB) Downloaded 201 times
Re: Mac PoP emulation
Thanks for the report. I have posted a reply on that mail page.Falcury wrote: ↑September 9th, 2018, 2:40 pm I wrote a message about this problem to Paul Pratt, the developer of Mini vMac (mailing list).
Re: Mac PoP emulation
Gryphel wrote: ↑September 9th, 2018, 5:36 pm Thanks for the report. I have posted a reply on that mail page.
Thank you for your reply!Gryphel wrote:Thanks for the report.
A Macintosh II, unlike previous Macs with built in monitors, can have one or more external monitors, each of which can have its own resolution, color depth, and refresh rate. Furthermore, these values may be changed, and the driver software of each monitor gives information on what values are allowed.
For compatibility, the Macintosh II uses its second VIA chip to generate the same 60.15 Hz interrupt as on previous models, which is used to update the tick count and other tasks. (See the Vertical Retrace Manager chapter of the Inside Macintosh: Processes book.)
My guess is that Prince of Persia is assuming the ability of monitors to use a specific refresh rate, which Mini vMac does not implement. (It pretends to have a single monitor which only supports 60.15 Hz. ) Changing Mini vMac to use 67 Hz for the VIA2 timer, as well as the intended monitor vertical refresh interrupt, would not be accurate, and break compatibility with most other software. In the future, perhaps Mini vMac could have an option for monitor refresh rate. This will complicate things somewhat.
Very interesting that the Macintosh II uses a second VIA chip for compatibility.
Then, maybe an implementation error in Prince of Persia is causing the slowness. I guess David may have already identified the bug:
(If this is indeed the root cause, then maybe we could consider publishing some sort of unoffical patch for PoP for Mac?)David wrote: ↑September 8th, 2018, 8:22 pm Consider this:
Suppose that the previous waiting ended when TickCount() returned some T value. Then previous_ticks = T.
Then suppose that frame_time = 5.
Now, the loop condition will be true when TickCount() returns T+5, because (T+5) - T <= 5 is true.
So the loop will stop when TickCount() returns T+6 !
This means that 6 ticks have elapsed since the end of the previous waiting, with is 1 tick (1/60 second) too much!
At least this is what I think.
Alternatively, if it's not an implementation error, then I suppose the game should run faster on a physical Mac II.
I'll try to look some more into the other audio issues I have been experiencing (popping noises, and skipping).
Re: Mac PoP emulation
After I don't know how many tests, I've come to the following conclusions:
1. The game IS slower on a Mac compared to the DOS version (unless that's the DOS emulator that is too fast)
2. The game is even slower in BasiliskII. In fact, the speed of the game in Basilisk is very irregular an can change depending on many factors.
3. The BLE->BLT change will help you get closer to the DOS speed in BasiliskII.
4. If your looking for true Mac speed, you can test with the gate opening and closing sounds. It should take very close to 4.5 sec between the first opening sound and the final "opened" sound. Closing the gate should take very close to 18.75 sec. Sounds should also come at very regular intervals.
5. Controls in that minivmac version above are not right. I usually play with the 456789 keys on the numeric keypad. If I turn numlock off, I can't jump forward, if I turn it on, I can't walk.
1. The game IS slower on a Mac compared to the DOS version (unless that's the DOS emulator that is too fast)
2. The game is even slower in BasiliskII. In fact, the speed of the game in Basilisk is very irregular an can change depending on many factors.
3. The BLE->BLT change will help you get closer to the DOS speed in BasiliskII.
4. If your looking for true Mac speed, you can test with the gate opening and closing sounds. It should take very close to 4.5 sec between the first opening sound and the final "opened" sound. Closing the gate should take very close to 18.75 sec. Sounds should also come at very regular intervals.
5. Controls in that minivmac version above are not right. I usually play with the 456789 keys on the numeric keypad. If I turn numlock off, I can't jump forward, if I turn it on, I can't walk.
Re: Mac PoP emulation
Indeed, there is a setting in BasiliskIIGUI.exe, called "Milliseconds between frames". For me it's set to 16, which is about 1000/60.
In the "BasiliskII_prefs" config file, this option is called "framesleepticks".
However, it doesn't affect the speed of PoP.
Strangely, Mac OS thinks that the refresh rate is 75 Hz!
Go to Apple menu -> Control Panels -> Monitors & Sound:
Re: Mac PoP emulation
Paul recently released a new stable version of Mini vMac (version 36.04).
Here is a build for x86 Windows, with various customizations enabled.
The zip file includes a Mac II ROM.
Minor known issues running Prince of Persia 1 and 2:
* Audio popping (most noticable in PoP 1).
* Music skipping in Prince of Persia 2. (Edit: reducing the emulation speed seems to fix this a bit.)
* Prince of Persia 1 runs too slowly (however, as has been discussed in this thread, this a bug in PoP itself and not due to the emulator).
Here is a build for x86 Windows, with various customizations enabled.
The zip file includes a Mac II ROM.
Minor known issues running Prince of Persia 1 and 2:
* Audio popping (most noticable in PoP 1).
* Music skipping in Prince of Persia 2. (Edit: reducing the emulation speed seems to fix this a bit.)
* Prince of Persia 1 runs too slowly (however, as has been discussed in this thread, this a bug in PoP itself and not due to the emulator).
- Attachments
-
- minivmac36.04_win32.zip
- (732.38 KiB) Downloaded 204 times
Re: Mac PoP emulation
It looks like this issue is related to a Mini vMac option to output 16 bit sound samples, which I had enabled:
If the default setting (8 bit sound) is used instead, the audio issues go away.https://www.gryphel.com/c/minivmac/options.html wrote:Sound Sample Size
-sss 3 { (default) 8 bit sound }
-sss 4 { 16 bit sound }
A Macintosh Plus outputs 8 bit sound (256 possible levels), which is then modulated by the sound volume setting (8 possible levels), and also by the square wave generator. By default Mini vMac currently outputs 8 bit sound, but there is an option to output 16 bit sound, which allows more accurate output when the sound volume setting is less than maximum, and when the square wave generator is used.
Re: Mac PoP emulation
Here is a build of Mini vMac (version 36.04, Windows 32-bit) with the audio issue fixed.
I have also attached disk images with System 6.0.8 and System 7.0.1 installed on them. Prince of Persia 2 won't run on 6.0.8, so I would recommend going with 7.0.1 even though 6.0.8 is more lightweight. Both of them should boot up pretty much instantly in an emulator.
By the way, you can download blank HFS disk images of various sizes here:
https://www.gryphel.com/c/minivmac/extr ... index.html
I have also attached disk images with System 6.0.8 and System 7.0.1 installed on them. Prince of Persia 2 won't run on 6.0.8, so I would recommend going with 7.0.1 even though 6.0.8 is more lightweight. Both of them should boot up pretty much instantly in an emulator.
By the way, you can download blank HFS disk images of various sizes here:
https://www.gryphel.com/c/minivmac/extr ... index.html
- Attachments
-
- minivmac36.04_win32_fix.zip
- (732.26 KiB) Downloaded 255 times
-
- system608.zip
- (553.98 KiB) Downloaded 190 times
-
- system701.zip
- (1.84 MiB) Downloaded 254 times
Re: Mac PoP emulation
Here is a disk image of Prince of Persia for Mac with the patch applied.David wrote: ↑September 8th, 2018, 8:22 pm On second thought, I'm not sure if "<=" (BLE, 0x6F) is the correct comparison. Maybe it should be "<" (BLT, 0x6D) instead?
Consider this:
Suppose that the previous waiting ended when TickCount() returned some T value. Then previous_ticks = T.
Then suppose that frame_time = 5.
Now, the loop condition will be true when TickCount() returns T+5, because (T+5) - T <= 5 is true.
So the loop will stop when TickCount() returns T+6 !
This means that 6 ticks have elapsed since the end of the previous waiting, with is 1 tick (1/60 second) too much!
At least this is what I think.
Indeed, this fixes the slowness.
(I used Super ResEdit, which has a built-in disassembler and hex editor.)
- Attachments
-
- PoP1_speedfix.zip
- (1.33 MiB) Downloaded 507 times