VOGONS


First post, by superfury

User metadata
Rank l33t
Rank
l33t

I still seem to see that Jazz Jackrabbit gets an extreme slowdown when running selecting the Sound Blaster sound card while a SB 2.0 is emulated. This mainly seems to be because the DMA transfer is incorrect setup for said card? It's rendering 1 sample each time, then issuing an interrupt because the DMA size setting is set to 0(1 sample before each interrupt, instead of the higher setting that's set in the DMA controller).

Jazz Jackrabbit doesn't seem to like that issue, causing it to become extremely slow when selecting Sound Blaster as it's sound card(in it's setup.exe settings) while using the SB 2.0 instead of the SB 1.x.
Selecting the Sound Claster Compatible clone setting in the setup.exe seems to make it run at normal speed(which has no issue with the SB 2.0 card)? So it's an issue with the DMA being incorrectly(bugged) setup for rendering samples?

Last edited by superfury on 2020-06-19, 11:59. Edited 2 times in total.

UniPCemu Git repository
UniPCemu for Android, Windows and PSP on itch.io
Older UniPCemu PC/Android/PSP releases

Reply 1 of 17, by superfury

User metadata
Rank l33t
Rank
l33t

This makes me think about something... What is the default DMA block size after a reset is performed on the DSP? UniPCemu currently has it set to 0(thus an IRQ after every sample using auto-init DMA DAC/ADC). Is it supposed to be something else on those DSP versions?

UniPCemu Git repository
UniPCemu for Android, Windows and PSP on itch.io
Older UniPCemu PC/Android/PSP releases

Reply 3 of 17, by superfury

User metadata
Rank l33t
Rank
l33t

@Rawit, so you mean an extreme slowdown on real hardware. As in the game itself running at a fraction of the speed it's supposed to(as in 1/100th of it's speed, with a framerate of less than 1 FPS)?

Even at 25% emulated speed, I can see it draw about 1 letter on the screen each second(with about 1/3 second for 1/3 character of the gameplay options being painted red/white).

One weird thing I also see, is that it's writing 0x7FF after the SB 2.01 DSP's command/data register, which is being interpreted as commands(which do nothing), after the 0x1C DMA playback command(sending 0xFF, then 0x7F to the port)?
The DMA block size is 0(the reset default), thus it throws an IRQ after each sample.

UniPCemu Git repository
UniPCemu for Android, Windows and PSP on itch.io
Older UniPCemu PC/Android/PSP releases

Reply 5 of 17, by superfury

User metadata
Rank l33t
Rank
l33t

Could it be that Auto-Init DMA DAC commands are simply dependent on the Set DMA Block Size(command 0x48) command(undocumented behaviour)? When it's already set, the transfers use the block size as setup with said command, and the 0x1C/0x2C/0x90/0x98 commands(perhaps all Auto-Init commands) receive their 2-byte parameter that is the DMA block size when none is set using command 0x48 yet(acting as a merged 0x48 followed by 0x1C command)?

So they're like this:
- 0x1C received? If so, then if DMA Block size has been received since reset, start the transfer immediately.
- Otherwise: receive the Set DMA Block Size as normal parameters and execute that (like 0x14 does when merged with 0x48's behaviour) and then start the transfer like 0x1C is received again.

And perhaps this applies to all other Auto-Init DMA commands as well?

Edit: Just adjusted all DMA auto-init commands to behave like that. Now, if an auto-init command is received, it will only directly start the DMA transfer with the current block size(command 0x48 parameters, cleared at reset) if such a 0x48 command has been received after reset. If it hasn't been received yet, the auto-init commands will wait for the CPU to give 2 byte parameters(like their non auto-init versions) and use said parameters to perform a set block size command before immediately starting the specified commands' execution(which starts up it's DMA transfer with the specified block size).

This undocumented behaviour bugfix seems to fix the SB 2.0 emulation with regards to that game at least.

Also one small thing to note: said slowdown doesn't happen on Dosbox, even with it's no-parameter auto-init commands on SB 2.0?
Edit: Dosbox 0.74 simply seems to have no sound with Sound Blaster 2.0 and setup selecting Sound Blaster(even with the correct IRQ/DMA settings)?

UniPCemu Git repository
UniPCemu for Android, Windows and PSP on itch.io
Older UniPCemu PC/Android/PSP releases

Reply 6 of 17, by superfury

User metadata
Rank l33t
Rank
l33t

OK. So it's actually undocumented behaviour?

rpix86 has something about this in it's documentation:
From https://rpix86.patrickaalto.com/rblog.html :

At this point the game started up, but then dropped to the debugger with an "Unsupported SB DSP command FF!". As I mentioned in the DS2x86 blog post, the game seems to have a bug where it attempts to send the DMA length as parameters to SB DSP command 0x1C (start 8-bit autoinit DMA). Since this command does not actually take any parameters, those extra bytes are interpreted as additional (undocumented) commands.

Then he shows the code that's running:

0417:25DE	cmp	word [22ED],0200	
jbe 25F8 Jump if SoundBlaster DSP version <= 2.00
mov al,1C
call 22F5 Send DSP command 0x1C (start 8-bit autoinit DMA)
mov ax,[22F1] ax = 0x0800
dec ax ax = 0x07FF
call 22F5 Send DSP command 0xFF (undocumented!)
mov al,ah
call 22F5 Send DSP command 0x07 (undocumented!)
0417:25F7

So it sends the 0x7FF DMA length to the 0x1C command instead of properly sending a seperate 0x48 command for it! Thus DMA length is 1 sample and the parameters would do nothing on the hardware itself(interpreted as NOPs afaik, since 0xFF and 0x7F aren't valid commands).

UniPCemu now properly interprets those parameters as input for a 0x48 command, executes it once it's fully received those parameters(setting the DMA block size) and starts up the DMA transfer as required by the command itself(e.g. 0x1C, 0x91, 0x90, 0x98 etc. normal behaviour without parameters).

UniPCemu Git repository
UniPCemu for Android, Windows and PSP on itch.io
Older UniPCemu PC/Android/PSP releases

Reply 7 of 17, by superfury

User metadata
Rank l33t
Rank
l33t

Just found out something interesting with Jazz Jackrabbit on UniPCemu: the top screen keeps jumping up and down?

I see the line compare register not changing at all, while the start address register keeps changing between be78h and 3202h, thus causing the display to wobble up and down constantly?

Edit: Perhaps it's the result of using cheats to test some functionality quickly?

UniPCemu Git repository
UniPCemu for Android, Windows and PSP on itch.io
Older UniPCemu PC/Android/PSP releases

Reply 8 of 17, by superfury

User metadata
Rank l33t
Rank
l33t

Perhaps the issue with the start address being toggled constantly has to do with the way that Jazz Jackrabbit scrolls the screen, which is incorrectly emulated somehow(reloading the counter at the wrong timing)?

UniPcemu reloads them at vertical total(CGA/MDA) and vertical retrace(VGA). Is that correct behaviour?

Edit: Looking it up some more(http://www.scs.stanford.edu/10wi-cs140/pintos … a/vga/vgafx.htm), it seems that all those panning and scrolling values are reloaded at the end of vertical retrace? So not just the start address is loaded at that time, the other byte panning, preset row scan and pixel shift count are loaded when vertical retrace ends?

Edit: OK. For the PGAME VGA scrolling demo to work correctly, the vertical retrace starting(bit 3 of the Input Status Register getting set) has to load the start address, while when vertical retrace ends, the other values need to be latched(the mentioned above panning and scrolling values).

UniPCemu Git repository
UniPCemu for Android, Windows and PSP on itch.io
Older UniPCemu PC/Android/PSP releases

Reply 9 of 17, by superfury

User metadata
Rank l33t
Rank
l33t

Weird that Jazz Jackrabbit seems to load said register at inappropriate times according to said demo, while the demo assumes it loads just the start address registers at the start of vertical retrace, while all others are loaded at the end of vertical retrace?

UniPCemu Git repository
UniPCemu for Android, Windows and PSP on itch.io
Older UniPCemu PC/Android/PSP releases

Reply 10 of 17, by superfury

User metadata
Rank l33t
Rank
l33t

Hmmm... Having moved the loading of the start address to the end of the vertical retrace, like most documentation seems to say (where the other loading of the other values mentioned also happens. This was at the start of vertical retrace according to someone of this forums as well, can't remember who atm), the demo(pgame) starts to fail somehow(glitching horizontal movement), while most of Jazz Jackrabbit's glitches disappear. Now only once every few seconds, the display somehow still glitches(mostly seeming to move upwards, with the bottom window(split screen bottom window) being unaffected and showing up at the top of the top window s well(making it appear twice, while pushing the top window downwards, behind the bottom window)? With top window I mean the normally functioning one (from the start address onwards), while the bottom window is the static, unchanging one(which contains the health, time, ammo etc.).

UniPCemu Git repository
UniPCemu for Android, Windows and PSP on itch.io
Older UniPCemu PC/Android/PSP releases

Reply 11 of 17, by superfury

User metadata
Rank l33t
Rank
l33t

OK. It's the demo from: https://pcem-emulator.co.uk/phpBB3/viewtopic.php?t=3089 .
It seems to have been based on: https://www.drdobbs.com/database/ega-and-vga- … nning/184408045

I see something interesting there:
- Pel panning seems to wait for vertical retrace to start? And writes said pel panning register during vertical retrace. So it's loaded when vertical retrace ends(as UniPCemu does)?
- Vertical scrolling seems odd, according to most VGA documentation:

/* wait for a vertical retrace */
while (!(inp(video.isr) & 8));
/* wait for horizontal or vertical retrace */
while (inp(video.isr) & 1);

/* address the preset row scan register */
outpw(video.crtc, (vpel << 8) | PRESET_ROW_SCAN);

/* Reset the start address */
set_start_addr(screen.start_addr);

That first line is just like the horizontal pel panning one. But it loads the start address during vertical retrace, so that would mean it's activated/cached after vertical retrace starts(like UniPCemu does now).
The line after that is weird: it waits while bit 0 is set(saying it's waiting for 'horizontal or vertical retrace')...
FreeVGA says this:

DD -- Display Disabled
"When set to 1, this bit indicates a horizontal or vertical retrace interval. This bit is the real-time status of the inverted 'display enable' signal. Programs have used this status bit to restrict screen updates to the inactive display intervals in order to reduce screen flicker. The video subsystem is designed to eliminate this software requirement; screen updates may be made at any time without screen degradation."

Why would it be waiting for said bit to clear, in other words: for display to become non-retracing(both vertical and horizontal) before writing the new preset row scan and start address after starting the vertical retrace and only write them after the retrace is complete and the vertical and horizontal retrace have finished? Isn't it latched when vertical retrace ends and horizontal retrace finished? So the loading is too late, having effect on the next frame(the loading doesn't apply to the current one)?

It's also strange that it says it's waiting for horizontal or vertical retrace, while the WhatVGA documentation on said bit 0(DD) says it's the opposite as the comment says? If WhatVGA is the correct behaviour, said demo is waiting for the display to start the next frame rendering, while the code's comment says the opposite?

Edit: The IBM EGA documentation indeed says it's inverted: 0 is horizontal and/or vertical retrace?

UniPCemu Git repository
UniPCemu for Android, Windows and PSP on itch.io
Older UniPCemu PC/Android/PSP releases

Reply 12 of 17, by superfury

User metadata
Rank l33t
Rank
l33t

OK. More interestingly: with the bit 0 of the Input Status register inverted and the CPU set to 7800 cycles(80386@33MHz) in IPS clocking mode, the display of Jazz in the level (and the surrounding area) becomes incorrect 100% of the time. The area that's displayed seems to shift in and out of the screen at both sides as I move Jazz around, like the way the surrounding area of games are loaded when running around(so effectively, you see everything that's out of bounds instead of what's inside the bounds)...

So I'm actually seeing the shifting area that's being shifted into/out into instead of the area Jazz is in(so everything left of the screen area and right of the screen area. Same with top and bottom).

If you would picture the active display as an rectangle, you would essentially see everything left, top, bottom and right of said rectangle(probably just everything to the right and bottom). So as you move left, the right side gets updated with new pixels, inverse for moving right. And as you move up, the bottom part gets updated and the same for moving down(the top gets updated).

So it looks like I'm actually looking at the second window that's being scrolled inside view, instead of the window I'm supposed to look at?
Essentially what happens in the gif at https://wiki.nesdev.com/w/index.php/PPU_scrolling . I see what's at the top right half of the gif, instead of what's at the output part?

1350-Jazz Jackrabbit incorrect scrolling and panning.jpg
Filename
1350-Jazz Jackrabbit incorrect scrolling and panning.jpg
File size
68.41 KiB
Views
210 views
File comment
Jazz Jackrabbit's incorrect scrolling and panning
File license
Fair use/fair dealing exception

That's currently:
- The start address is reloaded into a cache when vertical retrace starts.
- The remainder of the settings(byte panning, preset row scan, pixel shift count, pixel panning mode, split screen start scanline) are loaded into a cache when vertical retrace ends. Before, said caches were nonexistent and would affect data being rendered constanly on each 0th scanline(of the top and bottom window).

The only thing that is currently working correctly is the bar at the bottom(the independent window, which forces all above settings to 0).

UniPCemu Git repository
UniPCemu for Android, Windows and PSP on itch.io
Older UniPCemu PC/Android/PSP releases

Reply 13 of 17, by superfury

User metadata
Rank l33t
Rank
l33t

Just have been thinking... Perhaps, those other latches are actually loaded when the vertical display starts only? So vertical retrace starting latches the start address, while vertical display starting latches all those other values(effectively loading the scanline counter)? So that would be on the first active display pixel being rendered?

UniPCemu Git repository
UniPCemu for Android, Windows and PSP on itch.io
Older UniPCemu PC/Android/PSP releases

Reply 14 of 17, by superfury

User metadata
Rank l33t
Rank
l33t

After some more tinkering(byte panning, preset row scan, character height(for preset row scan check) and start address in vertical retrace start and horizontal panning, pixel panning mode, top window start after vertical total(when the first new active display cycle begins), most of the graphical glitches seem to be gone.

There still seems to be some weird periodic glitch happening always, though?

I've made a little video that shows what's happening:
https://www.dropbox.com/s/wz8cp6i89fjy7bu/Uni … kRabbit.7z?dl=0

Anyone knows something about this glitch? Dosbox doesn't seem to exhibit said glitch(0.74 seems to run correctly without issues, even on extremly low cycle counts(below 500 kIPS), it'll just hang when getting extremely low(below 100 cycles or so))?

UniPCemu Git repository
UniPCemu for Android, Windows and PSP on itch.io
Older UniPCemu PC/Android/PSP releases

Reply 15 of 17, by darry

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote on 2020-06-17, 19:49:
After some more tinkering(byte panning, preset row scan, character height(for preset row scan check) and start address in vertic […]
Show full quote

After some more tinkering(byte panning, preset row scan, character height(for preset row scan check) and start address in vertical retrace start and horizontal panning, pixel panning mode, top window start after vertical total(when the first new active display cycle begins), most of the graphical glitches seem to be gone.

There still seems to be some weird periodic glitch happening always, though?

I've made a little video that shows what's happening:
https://www.dropbox.com/s/wz8cp6i89fjy7bu/Uni … kRabbit.7z?dl=0

Anyone knows something about this glitch? Dosbox doesn't seem to exhibit said glitch(0.74 seems to run correctly without issues, even on extremly low cycle counts(below 500 kIPS), it'll just hang when getting extremely low(below 100 cycles or so))?

Sorry if this is nonsense, but doesn't Jazz Jackrabbit some very weird non-standard video timings and apparently 320x199 video resolution (I imagine it reprograms the VGA CRTC, I could be completely wrong though) ? Could that be the cause of those periodic glitches ?

Sorry again if this completely useless to you .

Reply 16 of 17, by jmarsh

User metadata
Rank Oldbie
Rank
Oldbie
darry wrote on 2020-06-18, 01:11:

Sorry if this is nonsense, but doesn't Jazz Jackrabbit some very weird non-standard video timings and apparently 320x199 video resolution (I imagine it reprograms the VGA CRTC, I could be completely wrong though) ? Could that be the cause of those periodic glitches ?

Not really anything fancy, it uses 320x240 (60fps, 1:1 pixel aspect ratio) with the active window set to 320x199 to produce a letterbox/widescreen effect.

Reply 17 of 17, by superfury

User metadata
Rank l33t
Rank
l33t

I'm still wondering what might cause the weird start address behaviour in Jazz Jackrabbit? Does it assume that the start address register is loaded after vertical retrace or at vertical retrace? Because each time I move said loading to the start of the vertical retrace, the display becomes shifted in a incorrect way for most of the time(moving the active display to about 3/4 of the screen, with the top part displaying incorrect(offscreen rendering) data)?

UniPCemu Git repository
UniPCemu for Android, Windows and PSP on itch.io
Older UniPCemu PC/Android/PSP releases