Commander Keen 4-6 are very slow, when I try to speed up the CPU, it appears to do slight speed bursts, but overall it's still horribly sluggish. Keens 1-3 work just fine, so...
Hmm.. I just tried keen 4 with DOSBox-X and DOSBox SVN, ECE and Staging
With DOSBox-X it is almost a slideshow with the default cycles (3000). With the exact same config with the other DOSBox flavours the game plays fine.
Changing core= or output= options makes no difference. And there are no errors in the LOG.
setting machine=ega resolves the slide-show problem, but any screen scrolling causes lots of tearing.
machine=vgaonly suffers from the same slowness problem as the default machine=svga_s3
They run fine in ECE for me as well...
Since they run fine (mostly) with machine=ega in DOSBox-X, I suspect there may be something wrong with the VGA code...
I just checked: DOSBox-X 0.82.19 runs the game fine with the default setting, but DOSBox-X 0.82.20 does not. So it is bug introduced between 0.82.19 and 0.82.20.
After some efforts to track down the problem, it turns out the issue occurred since commit 277b35d (“Normal core: STI should not immediately break to process interrupts...”) which made change to the src/cpu/core_normal/prefix_none.h file on Jul 6, 2019. @joncampbell123 probably know how to fix this one.
Is Commander Keen using CLI and STI constantly? Or maybe just STI?
The whole point of that code is to prevent STI from processing interrupts immediately in case the next instruction is CLI. When interrupts are disabled, STI+CLI does not cause the CPU to process any interrupts on real hardware (STI+NOP+CLI will though).
Can you break into the debugger and type "LOG ffff" and use LOGCPU.TXT to see how often it uses STI?
That change was needed for PC-98 game Peret em Heru who's FM driver interrupt is non-reentrant yet for some reason the interrupt handler has STI+CLI in it's routine. Processing interrupts immediately on STI causes crashes. Real hardware (verified during the change on a 486) does not process interrupts if STI is immediately followed by CLI.
Hm, actually that shouldn't cause any issues. Commits since that point make sure to either break normally for interrupts or reduce the cycles left to break soon. Code is already in place to peek ahead for CLI.
Found a copy of Keen 4.
Wow, that is really bad.
Reducing the cycle count does help.
Also the game seems to spend most of it's time in a fairly long subroutine full of code that polls 3DAh waiting for vertical retrace. With interrupts disabled.
Commenting out that STI+CLI check doesn't help.
@joncampbell123 I checked earlier that the slowness issue with the game Commander Keen 4 did immediately disappear if I changed line 1230 of the current src/cpu/core_normal/prefix_none.h file to:
if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end;
It is already very late here, so I cannot try it now.
Of course the change above was only for testing, not the real fix.
@Wengier Okay, here's the troublesome code:
All the vsync + vblank wait code eventually jumps back here:
262C:00000763 FB sti
262C:00000764 EB00 jmp short 00000766 ($+0) (down)
262C:00000766 FA cli
; And this code checks a 32-bit value incremented by the timer interrupt
262C:00000767 391E3DA5 cmp [A53D],bx ds:[A53D]=00EE
262C:0000076B 746C je 000007D9 ($+6c) (no jmp)
Keen is doing a STI + JMP short (a delay) + CLI. Clearly intended to allow interrupts to process.
The 2 cycle reset is not helping here, obviously, so there needs to be some adjustments to that code.
Well I tried, but Keen 4 has weird vsync wait code that has problems with machine=vgaonly and page flipping I haven't figured out yet. machine=ega seems to work perfectly now that I've added an option for EGA to latch hpel on display start like VGA.
Keen 6, dreams, and Keen 1 don't have these hpel/panning issues.
Keen 4 should be tested on real hardware to see if any real hardware has the same issues.
The wait loop is weird. It doesn't wait for vsync. It waits for one hblank, and then there's loads of "if vsync jump to interrupt check" "if not blanking jump to interrupt check". There's no actual wait for vsync.
@joncampbell123 I confirm that Commander Keen 4 now works fine with the default setting and machine=ega (with the new config option), which I think is already good enough for now. Thanks for the fix!
Keen 4 should be tested on real hardware to see if any real hardware has the same issues.
I'm assuming you mean real VGA? Because I had a PC with a S3 video chip where the scrolling didn't work properly (it kept jumping back and forth horizontally based on position, as if bit 2 of the horizontal scroll position went missing), so there is some hardware out there that gets it wrong. It was much newer than VGA so there's a chance that something got overlooked when implementing backwards compatibility.