VOGONS


First post, by keenmaster486

User metadata
Rank l33t
Rank
l33t

Title says it all. I've been playing around with Open Watcom, writing functions to draw things with VGA in 16-bit real mode DOS. I have had success doing simple things like setting the video mode (mode 13 for now) and drawing a pixel, and building shapes using my pset function, but to be honest I'm not really sure exactly what I'm doing other than that I am writing values to certain registers in the VGA chip. I'm following David Brackeen's tutorial, which seems to be pretty much the only mainstream resource on this sort of thing that is immediately available on the internet. I'm using C++ but all the routines are easily workable even though they were written in C, and for Borland Turbo C at that, but they are working just fine in Open Watcom compiling for 16-bit real mode DOS. I'm using Windows 9x for development so far as it makes it easy to test things.

So far so good. But what I really need is to go much deeper than just drawing pixels on the screen. On my list of functions I want to write are (among others):

  • Change active/visible pages
  • Flip pages
  • Copy pages one to another
  • Scroll a page horizontally or vertically, in hardware (this seems to be the hardest to do and I cannot find ANY information on exactly how to do this, anywhere on the internet)

But information on how to do these is scarce. I'm not totally in the dark - for example I know that in order to have more than one video page I have to use Mode X instead of Mode 13h, because in 13 you have only 64 KB of video memory, whereas with Mode X you get access to all 256 K - but I am still very much confused on how to do things like scrolling.

I wonder if any VGA and 16-bit DOS programming gurus can help me out with this, or maybe link to some resources that would help me.

World's foremost 486 enjoyer.

Reply 1 of 37, by VileR

User metadata
Rank l33t
Rank
l33t

That's weird; I would've thought there would be some more C routines/libraries available online for this sort of stuff. Although it wouldn't surprise me if most of them were in Turbo Pascal, assembly, or both... like this article, which covers a few of the things on your list.

My suggestion would be to arm yourself with more general VGA programming references, not necessarily something specific for your language/compiler. Once you have the principles down, the implementation is mostly port-mapped I/O anyway.
I assume you've at least heard of Abrash's Graphics Programming Black Book (link). Besides that, I can point you to:

- osdever's VGA programming page - stuffed with information and kind of disorganized, but you might as well start with some of this
- osdev.org's VGA wiki (archived version in case it's down for you too). A few more resources under 'Category: VGA'.
- VGA programmers master reference manual

If you'd like a C library however, there is the old XLIB, a mode-X library with extensive references, so even if you can't use it directly in Open Watcom (I wouldn't know) it should be quite helpful. There was a later one for Pascal which had some bugfixes iirc, but for C that's what I know of.

[ WEB ] - [ BLOG ] - [ TUBE ] - [ CODE ]

Reply 2 of 37, by amadeus777999

User metadata
Rank Oldbie
Rank
Oldbie

Abrash ha some vital info on page flipping pertaining to when the adress change really is made and how to deal with it.

There's also some info about mode X + some functionality in
https://www.phatcode.net/downloads.php?id=225 … underground.pdf

I took a, short, look at Brackeen's site and there's a LOT of info and he links to the PC-PGE site which has further info... combined with the info posted above it should be a solid start. vgaman.txt appears to be especially potent.

Reply 3 of 37, by pan069

User metadata
Rank Oldbie
Rank
Oldbie

I'd say, work through these tutorials first and try to make a basic game with that knowledge, say a simple Tetris clone:

http://www.brackeen.com/vga/

Then dive into Part II of Michael Abrash's Graphics Programming Black Book:

https://www.phatcode.net/res/224/files/html/ch23/23-01.html

Just keep in mind that it starts with 16 color VGA and then works its way up to 256 color modes and Mode X, you might have to read it a couple of times.

Once your comfortable with the VGA stuff, read Part I to learn how to make things fast. 😀

PS: Probably best to ask "specific" programming questions on Stackexchange Retrocomputing:

https://retrocomputing.stackexchange.com/

Reply 5 of 37, by keenmaster486

User metadata
Rank l33t
Rank
l33t
VileRancour wrote:

If you'd like a C library however, there is the old XLIB, a mode-X library with extensive references, so even if you can't use it directly in Open Watcom (I wouldn't know) it should be quite helpful. There was a later one for Pascal which had some bugfixes iirc, but for C that's what I know of.

This seems amazing, but I cannot get it working with Open Watcom yet:

  • Using C++ (the XLIB headers are or claim to be C++ compatible)
  • Building the library using Borland Turbo C 2.01 and TASM 2.01: the library builds, but it gives a bunch of warnings from TLIB: "<module> not found in library" where <module> is the name of the XLib module it's adding
  • Open Watcom appears to link the library successfully, but I cannot use any of the functions; it says "<function name>_ is an undefined reference" (notice how it adds an underscore at the end for some reason)
  • I tried adding the line
    #pragma aux <function name> "!"
    -- which got rid of the underscore in the undefined reference error, but did not fix it!

This is pretty much the extent of what I know how to do to try to fix this. Can anyone tell me what's going on here? I have a feeling it might be something with how I'm building the library but I'm not sure.

World's foremost 486 enjoyer.

Reply 6 of 37, by keenmaster486

User metadata
Rank l33t
Rank
l33t

Update:

I seem to have fixed it by changing the pragma to

#pragma aux <function name> "_!"

World's foremost 486 enjoyer.

Reply 7 of 37, by BloodyCactus

User metadata
Rank Oldbie
Rank
Oldbie

check out x2ftp there is a tonne of stuff.

http://ftp.lanet.lv/ftp/mirror/x2ftp/msdos/programming/

--/\-[ Stu : Bloody Cactus :: [ https://bloodycactus.com :: http://kråketær.com ]-/\--

Reply 8 of 37, by keenmaster486

User metadata
Rank l33t
Rank
l33t
BloodyCactus wrote:

check out x2ftp there is a tonne of stuff.

Thanks!

keenmaster486 wrote:
Update: […]
Show full quote

Update:

I seem to have fixed it by changing the pragma to

#pragma aux <function name> "_!"

This did work, but I cannot set the video mode. It simply returns -1 (X_MODE_INVALID) every time I call it. I'm calling it in the exact same way it's being called in the demo programs.

Calling x_text_mode() results in a blank screen and a hanging cursor.

I am out of my mind trying to figure out why any of this would happen. Maybe this library just does not play well with Open Watcom.

World's foremost 486 enjoyer.

Reply 9 of 37, by pan069

User metadata
Rank Oldbie
Rank
Oldbie

From your initial post I was under the impression that you wanted to write your own VGA graphics routines but from the latest few posts I get the impression that you don't mind using a library? Is that correct?

You seem to have settled on xlib for the moment. Which one did you use/download? The one provided in the link in an earlier comment?

It's difficult to help you since you're not providing enough information. Can you:

1. Provide the smallest possible "complete" code example that is not working.
2. Provide the steps how you build the exe.

Reply 10 of 37, by BloodyCactus

User metadata
Rank Oldbie
Rank
Oldbie

the errors of '_' with watcom often indicates which calling methods are used. My guess is your mixing stuff up that you have no idea about. Are you compiling watcom using watcom fastcall (default) register calling converntion, etc and your xlib is something else, probably stack calling convention... since you compiled it with tasm.

you might also have structure packing differences if you compiled with tasm and watcom.

--/\-[ Stu : Bloody Cactus :: [ https://bloodycactus.com :: http://kråketær.com ]-/\--

Reply 11 of 37, by keenmaster486

User metadata
Rank l33t
Rank
l33t
pan069 wrote:

From your initial post I was under the impression that you wanted to write your own VGA graphics routines but from the latest few posts I get the impression that you don't mind using a library? Is that correct?

The ultimate goal is still to write my own stuff, but if I can get XLib to work and do what I need, I will use it for now because I don't have unlimited time.

Yes, I downloaded version 6.0 from the link VileRancour provided.

pan069 wrote:

It's difficult to help you since you're not providing enough information. Can you:

1. Provide the smallest possible "complete" code example that is not working.
2. Provide the steps how you build the exe.

Here's my GitHub repository that contains the latest code, only one part of which is not working: https://github.com/keenmaster486/BEEP6

Notice how I have it split so far into three files: kge_main.cpp, kge_detect.cpp, and kge_vga.cpp. The functions in kge_detect.cpp all work perfectly as you can see if you run BEEP6.EXE. The functions in kge_vga.cpp do NOT work; kge_setTextMode() always blanks the screen and hangs the program, and kge_setVGAMode() always fails due to x_set_mode() returning X_MODE_INVALID.

BloodyCactus wrote:

the errors of '_' with watcom often indicates which calling methods are used. My guess is your mixing stuff up that you have no idea about. Are you compiling watcom using watcom fastcall (default) register calling converntion, etc and your xlib is something else, probably stack calling convention... since you compiled it with tasm.

you might also have structure packing differences if you compiled with tasm and watcom.

This is revealing the limits of my knowledge in this arena. I will dig into the watcom settings and documentation to try to see if I can figure out what you are talking about.

World's foremost 486 enjoyer.

Reply 12 of 37, by keenmaster486

User metadata
Rank l33t
Rank
l33t
pan069 wrote:

1. Provide the smallest possible "complete" code example that is not working.

Here you go:

#include <iostream>
#include "./XLIB06/XLIB_ALL.H"

#pragma aux x_processor "_!"
#pragma aux x_set_mode "_!"

using namespace std;

int main ()
{
//this works (function gets called and returns what it should):
cout<<x_processor()<<endl;

//this does NOT work:
int mode = x_set_mode(X_MODE_320x200, 320);

cout<<mode<<endl;

//that cout should be printing on a newly entered VGA ModeX but no!
//The mode set fails and it always returns X_MODE_INVALID
}
pan069 wrote:

2. Provide the steps how you build the exe.

I'm not quite sure what you mean; I added XLib to the linker options (lib ./XLIB06/XLIB06L.LIB). Yes I am compiling in the large model as is the library. Then I just hit the "Make all targets" button in the Open Watcom IDE; it runs through the process with no errors and that's it. When I started out I selected the option to make a "DOS 16 bit" project.

World's foremost 486 enjoyer.

Reply 13 of 37, by BloodyCactus

User metadata
Rank Oldbie
Rank
Oldbie

I used the xlib lib file in your beep github, when I linked it, your doing far memory calls but its doing small memory model returns. stack is being screwed up. I debugged it and I can see the returns doing "ret" and not "retf" inside xlib06l.lib

you also have convention calling wrong. you need "-ecc" but you cant use it with C++, it gives errors in conio etc. doing it as C works with -ecc.. this removes the pramga _! stuff in the source too. fixes that up.

so probably the xlib in beep is compiled wrong and not large memory model at all.

also, your going into modex and turning to dos, that will leave the screen messed up. you need to reset to video mode 0x03

works fine as below;

my test;

(-ecc for c calling convection, ms for small model)

"wcl -2 -ms -ecc test.c xlib06\XLIB06l.lib"

#include <stdio.h>
#include "./XLIB06/XLIB_ALL.H"

extern void reset_dos_video_mode(void);
#pragma aux reset_dos_video_mode =\
"mov ax,3" \
"int 0x10" \
modify [ax] \
;

int main(void)
{
int mode;

mode = x_set_mode(X_MODE_320x200, 320);
reset_dos_video_mode();
return 0;
}

--/\-[ Stu : Bloody Cactus :: [ https://bloodycactus.com :: http://kråketær.com ]-/\--

Reply 14 of 37, by keenmaster486

User metadata
Rank l33t
Rank
l33t
BloodyCactus wrote:

I used the xlib lib file in your beep github, when I linked it, your doing far memory calls but its doing small memory model returns. stack is being screwed up. I debugged it and I can see the returns doing "ret" and not "retf" inside xlib06l.lib

OK, so what I need to do is figure out why XLib is not compiling with the large memory model. Here's my makefile: https://github.com/keenmaster486/BEEP6/blob/m … XLIB06/MAKEFILE
I'm not sure what more I can do here; the model is set to large there and that carries over to all the switches. I'm using Turbo C 2.01 and TASM 2.01.

BloodyCactus wrote:

you also have convention calling wrong. you need "-ecc" but you cant use it with C++, it gives errors in conio etc. doing it as C works with -ecc.. this removes the pramga _! stuff in the source too. fixes that up.

This makes sense to me, but what do I do if I really want to use C++? I can program in C but I would rather not.

BloodyCactus wrote:

also, your going into modex and turning to dos, that will leave the screen messed up. you need to reset to video mode 0x03

Yes, I was trying to do that but x_text_mode() wasn't working due to the same issues.

BloodyCactus wrote:

CODE

Great! I will experiment with this. Thank you!

World's foremost 486 enjoyer.

Reply 15 of 37, by gerwin

User metadata
Rank l33t
Rank
l33t

Are you sure Mode-X is the way to go? It is a hack. It is a planar mode, meaning you can't just write bytes of pixels in a straightforward manner. Many developers at the time decided to stick to mode 13h because of that, because for their projects the overhead of planar drawing negated the benefit.

VESA fixed it eventually: Paging combined with a proper linear frame buffer.

See: Doom in DOS: Original vs Source Ports

--> ISA Soundcard Overview // Doom MBF 2.04 // SetMul

Reply 16 of 37, by pan069

User metadata
Rank Oldbie
Rank
Oldbie

As with everything, that depends entirely on what it is you're trying to do.

Are you sure Mode-X is the way to go? It is a hack.

That's not really true. It's actually mode 13h that is an abstraction on-top of unchained mode (modex, if you will) to give the programmer a convenient linear frame buffer at the expense of not being able to access 75% of the remaining video memory. Modex basically turns the abstraction off.

You are correct though, that by the time the 486 arrived, the combination of increased CPU and bus speeds (most notably VLB), for most games mode 13h with the linear frame buffer had a higher performance, but no square pixels though.

On a 286 and 386, going into unchained mode can give you great benefits (e.g. smooth scrolling) that isn't really possible on those machines by simply using a linear frame buffer since the bandwidth simply isn't there.

Reply 17 of 37, by keenmaster486

User metadata
Rank l33t
Rank
l33t

Status update:

I think I figured out what was wrong with the library. I had old object files from a previous build attempt. After removing those, it rebuilds with no warnings.

BloodyCactus wrote:
my test; […]
Show full quote

my test;

(-ecc for c calling convection, ms for small model)

"wcl -2 -ms -ecc test.c xlib06\XLIB06l.lib"

CODE

THIS works. And with my new build of the library it works with -ml for large model as well.

I still can't get my C++ code working, however, even with the new build of the library. Maybe I will just have to use C, but I would rather not.

World's foremost 486 enjoyer.

Reply 18 of 37, by gerwin

User metadata
Rank l33t
Rank
l33t

@pan069 - Well, all good points there.

When I wrote Mode-X is a hack, it is because it was not in the normal list of modes offered by the hardware, and as such it is was not tested like those modes. Some video hardware has quirks with Mode-X, Like I can recognize mode-X on my CL VLB graphics card because it starts to give random blinking pixels. I read some cards do not scroll smoothly. I figure that when Doom got popular, hardware vendors were forced to better prepare for Mode-X and variants. But that is 486-era already.

What I miss in your description is what is my main point: that one cannot store 8-bit textures and sprites in their original linear form and then copy them directly to a planar framebuffer. On-the-fly conversion tends to take too much time. AFAIK the solution is to convert all bitmaps to planar before the game loop starts. A programmer has to be aware of such requirements.

I never programmed in planar much myself, so I cannot say exactly how difficult it is. John Carmack described it like this for Doom: "It is still a lot of grief, and it polutes the program quite a bit". More of his Mode-X anecdotes are in the link in my previous post, together with those of Shawn Hargreaves.
I only (re)wrote an on-the-fly linear to planar conversion for Doom MBF 2.04. It allowed for the game to use page flipping without VESA, There was no speed benefit. IIRC it is usually a bit slower.

--> ISA Soundcard Overview // Doom MBF 2.04 // SetMul

Reply 19 of 37, by Deksor

User metadata
Rank l33t
Rank
l33t

I apologise for ""stealing"" that thread, but I think this is on topic.

Look at that video https://www.youtube.com/watch?v=QLVi2zKCgCo

Now someone in the comments says this :

It's actually in a 16 color mode, using copper timing to change the palette every few scanlines. Each of the effects (big scroller, background, vertical scroller, SPD) is on a separate bitplane. The scroller at the bottom is also done with copper, changing the screen origin address every scanline

This makes me quite curious, the timings thing must be very tough to do, but having several separated bitplanes displayed at the same time could give pretty cool effects despite being stuck at 16 colors. Now I'm wondering, how is he achieving that, and what special mode is that ? This doesn't seem it is mode 0x0D, is it ?

There's also this post on pouet.net which explains it some more ...

Trying to identify old hardware ? Visit The retro web - Project's thread The Retro Web project - a stason.org/TH99 alternative