VOGONS


First post, by Andersen

User metadata
Rank Newbie
Rank
Newbie

Hello people, new Dosbox fan here. 😊

I have a problem with DosBox0.60 and Captive blinking in "space map". Whole interface is normal for about 0,5 seconds and then starts blinking between proper ingame view and black. Dont know if this continues after landing, havent tried landing yet. 😜

I have DosBox0.60 with very basic settings, just installed it and havent played around with more advanced settings yet.

Specs:
Athlon XP 2400+@2,2Ghz
Abit NF7-S v2.0
1GB RAM
Radeon 9700 Pro + dual monitors
Win2k Pro + SP3
Soundstorm in use
Latest drivers for all except builtin NIC and Soundstorm which use slightly older drivers.

[Edit]
Tried landing and yes it keeps on blinking. Changing frameskip and command rate doesnt help. Rate of blinking changes depending on how much "objects" you have in view. Looking at more dense area makes blinking faster.
[/Edit]

A64 3000+ Venice | Abit KN8 | GF6600GT | 1GB
307GB Storage
HP Pavilion ZE4423EA
Win2k + Fedora

Reply 3 of 13, by Andersen

User metadata
Rank Newbie
Rank
Newbie

More cycles = faster blinking.

Changing frameskip just makes "blinks" longer.

A64 3000+ Venice | Abit KN8 | GF6600GT | 1GB
307GB Storage
HP Pavilion ZE4423EA
Win2k + Fedora

Reply 5 of 13, by taiken7

User metadata
Rank Member
Rank
Member

(Note that EGA works fine)

its reading 0x9 from port 0x3da (VGA-Detect Retrace)
every frame/blink .. so its alternating on every frame-retrace.
(-- must be some kind of alternating 2-page scheme)

Notice that if you click on the red writing to the left it "pauses"
the game AND stops blinking!
But from here modifying anything alternates a single blink/noblink
cycle. ( Alternate on screen update it appears )

*UPDATE #1*
Keeping an eye on ES it appears to alternate between
A000 and B000, 'dosbox didn't do it' - so every second frame
should be there.

*UPDATE #2* Analysis of segment b000 reveals a valid frame
so it seems it is dosbox not updating VGA_virtual memory on its side.
will try figure out how the game is trying to do a page-flip..

(Note that this should be fixed when frames are rendered from real memory and not a seperate VGA buffer)

Reply 6 of 13, by taiken7

User metadata
Rank Member
Rank
Member

For those happy to help debug; heres what I have so far:

Overview: cs:[007C] holds the current "Active Page"
which is either 0xA000 (On Screen) or
0xB000 (offscreen). The Offscreen render is the "blank"
(although it shouldnt be blank, the data is there, dosbox isnt)
The code below shows how we alternate using "xor"
(Now all we need is some form of memory transfer and/or
the elusive currently-not-implemented VGA call)
Code:

007E:0895 E85AFD call 000005F2 ($-2a6)
007E:0898 2E81367C000010 xor word cs:[007C],1000 cs:[007C]=B000
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
007E:089F EB1E jmp short 000008BF ($+1e)

...
007E:0AE3 2EA17C00 mov ax,cs:[007C] cs:[007C]=A000
007E:0AE7 350010 xor ax,1000
^^^^^^^^^^^^^^^^^^^^
007E:0AEA 8ED8 mov ds,ax
007E:0AEC 2E8B0E2000 mov cx,cs:[0020]
...
007E:0ADE BFBD0E mov di,0EBD
007E:0AE1 8EC7 mov es,di
007E:0AE3 2EA17C00 mov ax,cs:[007C] cs:[007C]=B000
007E:0AE7 350010 xor ax,1000
^^^^^^^^^^^^^^^^^^^^
007E:0AEA 8ED8 mov ds,ax

Now if only we can find where it tries to blit the data to the screen.
(Looks like it might make use of DS .. but my first guess is ES).

Reply 7 of 13, by Fizzban

User metadata
Rank Newbie
Rank
Newbie

Switch is done at 007B:0000087E.

Captive contacts the VGA CRCT there and tells him to set the display start to either 0x0000 or 0x4000 (port 0x3D4/0x3D5, functions 0x0C+0x0D).

When the display start is set to 0x0000, an image is shown. 0x4000 => Black. So Dosbox should switch between the content of a000:0000 and b000:000 but somehow doesn't..

To verify my theory, I told the CRCT to ignore 0C+0D calls and the blinking stopped. Of course, this is not a solution because we lose double buffering this way and the sprites starts flickering.. 😀

Reply 8 of 13, by taiken7

User metadata
Rank Member
Rank
Member

Yes you are correct, I recently spotted that after disassembling
most of the PM manager (.. aaarggh .. always the little things!)

...

Here's a posibility, it fixes some things and breaks others (well
prehistoric 2 is still blank so this may still be incorrect) ..
let me know what you think:

[Hmm.. 8bits = 2 hex chars, so why is this working and 0x00ff not?]

(I've commented out the original for comparison)

file VGA_CRTC.CPP:

case 0x0C: /* Start Address High Register */
crtc(start_address_high)=val;
// vga.config.display_start=(vga.config.display_start & 0xFF00FF)| (val << 8 );
vga.config.display_start=(vga.config.display_start & 0x0000FFFF)| (val << 8 );
/* 0-7 Upper 8 bits of the start address of the display buffer */
break;
case 0x0D: /* Start Address Low Register */
crtc(start_address_low)=val;
// vga.config.display_start=(vga.config.display_start & 0xFFFF00)| val;
vga.config.display_start=(vga.config.display_start & 0xFFFF0000)| val;
/* 0-7 Lower 8 bits of the start address of the display buffer */
break;

Reply 9 of 13, by Fizzban

User metadata
Rank Newbie
Rank
Newbie

This bugfix actually breaks the 0x0C and 0x0D functions in a way that the start of the display is always zero:

Initial value: vga.config.display_start = 0

Programs calls 0x0C with parameter 0x40:

vga.config.display_start=(vga.config.display_start & 0x0000FFFF)| (val << 8 ) = (0x0 & 0x0000FFFF) | (0x40 << 8) = 0x0 | 0x4000 = 0x4000

Programs calls 0x0D with parameter 0x00:

vga.config.display_start=(vga.config.display_start & 0xFFFF0000)| val = (0x4000 & 0xFFFF0000)| 0x0 = 0x0 | 0x0 = 0x0

End value: vga.config.display_start = 0

So you just turns off double buffering which helps but isn't a proper solution.

Edit: It seems that this is a cpu memory -> video memory space mapping problem. As soon as the blinking starts, real_readb(0xb000,0x0001) returns 0x17 but vga.mem.linear[0x10001] stays 0x00. However, Captive obviously expects these two to be the same. Probably Captive configures mapping in a very exotic way. I will investigate that further.

Reply 10 of 13, by Fizzban

User metadata
Rank Newbie
Rank
Newbie

Found the bug: The values 0x00 and 0x01 of the "Memory Map Select" bits of the Miscellaneous Graphics Register (Index 06h) of the Graphics Registers (Port 0x3CE/0x3CF) are treated as the same although they are different.

Well, Sourceforge's CVS does not like me today, so no diff.

In vga_memory.cpp replace

switch ((vga.gfx.miscellaneous >> 2) & 3) {
case 0:
case 1:
vgapages.map_base=VGA_PAGE_A0;
MEM_SetPageHandler(VGA_PAGE_A0,16,range_handler);
MEM_SetPageHandler(VGA_PAGE_B0,16,&vgaph.hram);
break;

by

switch ((vga.gfx.miscellaneous >> 2) & 3) {
case 0:
vgapages.map_base=VGA_PAGE_A0;
MEM_SetPageHandler(VGA_PAGE_A0,32,range_handler);
break;
case 1:
vgapages.map_base=VGA_PAGE_A0;
MEM_SetPageHandler(VGA_PAGE_A0,16,range_handler);
MEM_SetPageHandler(VGA_PAGE_B0,16,&vgaph.hram);
break;

After this patch has been applied, there is no blinking or flickering in Captive.

Reply 13 of 13, by Harekiet

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Hmm hehe i have teh same game only my version doesn't flicker 😀

They must have released another version later or something since that 128kb memory access is not supported by a lot of vga cards.