VOGONS


First post, by RetroMaster137

User metadata
Rank Newbie
Rank
Newbie

Hello.

I don't know if this is the proper section; posted this here because it is not a release, but rather me asking how to do it 🤣

TL;DR:
- How do I run code every VBlank?
- Which would be proper development tools for DOS?
- How do I need to deal with real/protected/etc modes? Which modes does it need to support, or in what way?
(i.e. I could try all modes but I don't know whether some might be more difficult or important to implement than others, I'm just trying to sort the priorities so I can release most important functions first and least important later)

Long time no see, I had been finishing my studies. I haven't forgot about the TSR I planned to make, and I made... a very little progress: Just got my first ever custom "TSR Code" to run!; by editing an old keyboard TSR made for Microsoft C Optimizing Compiler. I also happened to learn how to overwrite an interrupt pointer (int 0x10 in this case), getting input parameters through the calls, and sending them to the old int 0x10 using a magical function called chain_intr.
But I hit a roadblock when trying to implement the display mode replacement function... For my custom 0x4F01, I couldn't prepare a custom struct and set a pointer to it in a specific register to return because... No matter what, I simply couldn't set the struct's pointer to a register.

To keep it simple:

_asm { mov _ax, ax }; […]
Show full quote

_asm
{
mov _ax, ax
};

asm
{
mov _ax, ax
};

__asm
{
mov _ax, ax
};

None of these work! Essential for either:
- Preparing a new struct and return it
or
- Accessing firmware's returned struct and modifying it
That was my attempt from weeks ago, but I only managed to come back to it today so I don't know if I'll find a workaround before dropping my pirated copy of Microsoft's compiler for good...

... I guess this is what VBEPlus is meant to do? I wish it worked on my PC though, it says there's no "free modes available" IIRC, it could need a rather quick hotfix, but it's closed source AND the creator seems unreachable (??? or maybe I haven't tried hard enough).

I do know C (not C++!), but looks like I'm required to learn x86 ASM to do this... there's just not much to look at, just a bunch of ASM-based TSR examples with no C code, and useful TSRs and tools which might need tweaking but happen to be closed source and too old for their authors to be contactable.

In the meantime during my studies I have learnt more about PCs architecture and... oof, what about real/protected/etc modes? I got a bunch more to learn about that for sure, but what would be the best way for dealing with this, or which would be the "best tools"?
For instance, Microsoft C Compiler is most likely very different from the more widely used DJGPP.
I don't have "big" plans though, I'd just offer a pretty dumb tool to get lower display resolutions to work, by abusing CPU if necessary (and keeping it all the most hardware-independent as possible). I'm currently relying on the fact that my PC's internal graphics (Radeon HD 8570d/Trinity ATOMBIOS), aside of having fewer resolution modes and reporting VBE version 3 (the number alone breaks the checks within MAANY programs), the rest of the implementation SEEMS completely flawless: 8 bit modes available, 15 & 16 modes too, no artifacts in older windows versions/basic drivers, I get no problems with the mirrors in Duke3D, and so on

For now the first step is making a functional clone of VBEPlus (I guess): "Produce" lower resolution modes, based off the higher resolution ones (i.e. replace 1024x768 with 512x384 (and yes I'm still totally determined to get NO$GMB's interface running correctly here)).
That would leave graphics running on the top-left of the screen + whatever other programs left outside that area + whatever bug causes your program to draw outside the intended display area 😜

The next and final step (if possible and not too difficult (?)) would be to scale said top-left area to the full screen, and convert color bit-depth if necessary! That way it could emulate 8-bit color support.
The problem is, I got no idea how to even tackle that... I suposse I could just allocate and return a backbuffer to the programs, then convert size/color transfering from the backbuffer into the visible framebuffer... through software, every VBlank. But how do I even get code running on every VBlank?

Reply 1 of 4, by bakemono

User metadata
Rank Oldbie
Rank
Oldbie

The goal is to emulate 8bpp modes using 32bpp modes? Might as well use asm. I don't see high level lanugages helping much here (although I am biased). If you hook an interrupt in DOS, your routine will get called in realmode. That is assuming it gets called at all, it's always possible that the application installs its own handler.

You could hook the timer interrupt to do your framebuffer scale/copy periodically. Who knows if the GPU can generate a vblank interrupt.

BTW, Does the Radeon 6970 have 8bpp support? It's Terascale 3, so maybe some BIOS hacking would reveal how to set real 8bpp modes on other Terascale 3 hardware.

GBAJAM 2024 submission on itch: https://90soft90.itch.io/wreckage

Reply 2 of 4, by zyzzle

User metadata
Rank Member
Rank
Member

For those without 8bpp support in newer onboard (crippled / borked) graphics from Intel and AMD (on Ryzen CPUs), such an 8 bpp--> 32bpp utility will be very useful, as it would allow us to make use of DOS games which are 8bpp only and 320x200 / 320x240 only. Even if displayed at 640x480x32 (VESA) which "emulated" 320x200x8, it would make all of those thousands of programs usable in baremetal DOS on such systems with the crippled onboard graphics vBIOses which refuse to support 8bpp and lower-resolution VGA.

Reply 3 of 4, by RetroMaster137

User metadata
Rank Newbie
Rank
Newbie
bakemono wrote on 2024-12-08, 18:27:

You could hook the timer interrupt to do your framebuffer scale/copy periodically. Who knows if the GPU can generate a vblank interrupt.

Ouch at the last point. So I guess the only way to avoid screen tearing is through the (in this case inaccessible) dedicated driver? Because I guess I could set a timer manually but with no way of determining whether the system is drawing on top or bottom of the screen...

Speaking about timers, could I ask you to tell me more? So far I got some barely-read information on them; I promise to read more ASAP, but I can't spend much time on my stuff as of lately so I'm going really slow with everything 🙁 .
There's apparently a fixed 18-19hz timer + its "alarm" interrupt, and there's RTC which I don't know how it works but to what I understand there's no alarm
If I understand correctly, I'd have to wait in loop for RTC to tell me 1 frame-worth of time has happened, but I can't take away execution from the program; even if a timer was settable, wouldn't it conflict with the program if it happens to do the same and/or at different times? I can't count with it being differrent or same from the refresh rate
Due to both cases, would investigating how to throw this process to another CPU core be a good idea? Most of DOS software is single-core anyways, then my TSR's only task would be to stay in loop and send the converted data to the front buffer every 1 frame according to refresh rate.

I don't know about Radeon 6970 (by number alone looks earlier than mine iGPU? It seems like a good candidate for 8bpp... Anything older than this might be, considering it's from 2013), but I do know that VInfo and X-VESA have been really useful; they work right away with the built-in FreeDOS version from Rufus without EMS setup or other prerequisites.

Reply 4 of 4, by bakemono

User metadata
Rank Oldbie
Rank
Oldbie
RetroMaster137 wrote on 2024-12-09, 20:27:

Ouch at the last point. So I guess the only way to avoid screen tearing is through the (in this case inaccessible) dedicated driver? Because I guess I could set a timer manually but with no way of determining whether the system is drawing on top or bottom of the screen...

On VGA there is a register bit you can check to know whether it's in vertical retrace or not. On more modern hardware this likely doesn't work. Whatever alternative exists may be proprietary/undocumented. Though VBE is supposed to have a synchronized page flip function which might help.

There's apparently a fixed 18-19hz timer + its "alarm" interrupt

You can get a higher precision from the 8253/8254 timer by polling the counter. It's also possible to get a faster interrupt rate by reconfiguring it. The problem is that the application might do this itself. Using the APIC timer might be better.

Due to both cases, would investigating how to throw this process to another CPU core be a good idea?

Yes, I agree.

GBAJAM 2024 submission on itch: https://90soft90.itch.io/wreckage