I was wondering if anyone could recommend me any resources relating to programming graphics in assembly in a 16-BIT DOS environment. I don't really mind what assembler it is for (could be NASM, FASM, MASM etc), I just want something to start with, I'm a bit lost  :sad:. I would prefer NASM, but as I said, I don't mind.
Posted on 2009-03-10 06:15:35 by Grich
You could look for mode 13h stuff (that's the standard 320x200 256 colour VGA mode), int 10h (the videocard BIOS interface), or VESA (extended graphics features).

The standard way for DOS graphics is to set mode 13h, and then you can just use the A000h segment to write your pixels to. Each pixel is 1 byte, and is an index into the palette. Since the resolution is 320x200, you can address a pixel at (x,y) at offset (320*y) + x. (each scanline has 320 pixels, and the scanlines are stored linearly in memory).
The palette can be set with some VGA registers using the out-instruction. I know it was somewhere in the 300h range, not quite sure (it's been ages).

Ralfs Interrupt List should provide you with a good basic reference of the int 10h API and the VGA registers.
Posted on 2009-03-10 06:54:57 by Scali
Download OASML from ProgrammersHeaven. I have some graphics mode code in there. The code is in TASM.
Posted on 2009-03-10 07:41:24 by XCHG
Posted on 2009-03-10 12:27:19 by SpooK
I still don't get it! Why would somebody still want to do 16-bit DOS programming? :(
Posted on 2009-03-10 12:49:27 by XCHG
Some people believe it's easier to start with 16bit and some need it for college courses. I don't understand why they still teach 16bit in those CompSci classes. Randy does have a point on teaching his students 32bit assembly although doing it with HLA is a totally different story.
Posted on 2009-03-10 15:38:26 by JimmyClif
I can see the appeal. Jumping into 32-bit means you have to make decisions about the OS, versions of that OS, graphics libraries, etc... to the point where you are learning more about the OS and API than general assembly language concepts.

OTOH, segmented memory models in modern machines are virtually obsolete.

Perhaps they should start using something like 32-bit MenuetOS to bridge the gap.
Posted on 2009-03-10 17:50:00 by SpooK
I think the main reason why people still teach 16-bit DOS in CompSci is simply because:
1) They don't want to put a lot of effort into developing new material for a new OS.
2) These teachers often haven't kept up with technology themselves, so they would have to learn a new 32-bit (let alone 64-bit) OS aswell.

I think a good solution for a class is to provide a framework. That's how some classes were done at our uni.
Eg, for our 3d computer graphics class, we were given the sourcecode for a simlpe 3d engine, it was just missing a few functions. Our assignment was to implement the missing functions.

For an asm class you could do the same. You could eg take a DirectDraw framework that would handle the basic stuff to set up a fullscreen graphics mode, and then let the students implement the actual drawing code. The drawing code will be very similar to how it was in DOS in mode 13h or such. Just get a pointer and index the pixels off it.
Posted on 2009-03-11 02:53:02 by Scali
But if you teach 32-bit asm it will probably be windows, which locks you out of the millions of alternatives...
Posted on 2009-03-11 03:16:33 by sinsi
If you provide a framework that abstracts the OS for you, it doesn't matter what OS you use. Like in my example with 3d computer graphics. The framework used OpenGL, but we didn't have to communicate with OpenGL directly.
The framework could just as easily have used Direct3D or something else, and we could pretty much write the same code and it would all still work. We just had to provide the correct code for the math, and didn't have to deal with any API directly.
Posted on 2009-03-11 03:34:03 by Scali
A wrapper around a wrapper is just overhead - that's one more reason that I love what I do, and despise what I could be doing.
Nice to see you back Scali, I appreciate your input as usual :)
Posted on 2009-03-11 04:35:25 by Homer
Oh well, it depends on where the overhead is.
Back in the day I used a simple wrapper myself, that basically set up a render-loop something like this:

while (!exit)
{
   FrameBufferInfo = GetFrameBuffer();

   DrawPixels(frameBufferInfo);

   WaitVBL();

  DisplayFrame();
}

I then implemented this wrapper for DOS, Win32 DirectDraw (windowed and fullscreen), Win32 GDI and *nix X.
I could then just 'plug' the same DrawPixels() routine into any of these wrappers, and have an instant port of whatever graphics routines I developed.
Since the overhead that this wrapper causes is only done once per frame, the effect on performance was negligible.
All the time was spent in DrawPixels().

I could basically write an entire portable 3d software renderer this way. On Windows I used GDI as a fallback if somehow the DirectDraw videomode wasn't supported.
I abandoned this approach when I started using 3d acceleration however. You work more directly with the API during the drawing itself, rather than just filling some array. Things like shaders wouldn't be portable anyway, so you can't write the core of your code in a way that it runs 1:1 on different APIs.
Instead I just abstracted at a different level. Concepts like Material, Mesh and Draw() exist in any 3d API.
The actual implementation of these would be API/platform-dependent, but the logic using these 'conceptual' classes could be re-used, and much of it could be written in a portable/reusable way, even though not as elegant and simple as the example above.
Posted on 2009-03-11 05:02:33 by Scali
Well if the goal is just to teach 32-bit Asm, they could simply tell the users what for example a C string is and how it is terminated with a null character and then ask the users to create functions that work with a really simple array of bytes in the memory.

The prototype of functions will just use char* and that's really easy to deal with but at the same time you will force the student to learn the 32-bit instructions that are supported on most modern CPUs and their equivalents perhaps on other CPUs. It doesn't necessarily have to be a high level abstraction of Asm. Could be as simple as moving one array to the other, filling an array with Fibonacci numbers, reversing an array, perform matrix operations on the array and dozens of other things. Then at the end, you could teach them MessageBox() in Win32 so they could see the results of their work or an equivalent of this API on other Operating Systems!
Posted on 2009-03-11 05:09:28 by XCHG
Yea, exactly. C strings are used in many OSes. And even if they don't use C strings, their format is probably very similar (like DOS using a $ terminator rather than 0, or like Pascal storing the length of the string instead).
Same with matrices and vectors. They are generally a linear sequence of IEEE floating point numbers in memory.
The OS is just the 'glue' to put all your main logic together into a working program. It shouldn't be the main focus of learning assembly, but at some point you cannot avoid using the OS for some basic input/output.
You could opt for using ANSI C functions, since these are supported by many OSes, and can be called from asm easily.
Posted on 2009-03-11 05:17:13 by Scali
yes we all love 32bit asm as alternative to do things in C or Java with all its wrappers around winapi functions etc
but I think the goal to learn 16bit asm in Cg courses is more to when your finally thru with school, its more preparation to work with embedded stuff, might be closer to program some lot simpler device than a PC, what about if the embedded cpu is the heart of Electronic fuel injection, or just a washing machine, there is no need for knowing loads of winapi stuff.
for people who is complete newbies to for example winapi and all that goes along with make a win32asm application so it plays nice with windoze and other applications, is taking attention and making it a steeper learning curve to learn both asm and winapi and things like reserve dynamic memory etc
it would be nice to hear the opinion of our local ARM-coder Ultrano on this
Posted on 2009-03-11 11:52:41 by daydreamer
Well, I think they should be taught the basics of the Win32API (or whatever OS you're using), before working with ASM.
That way you don't have to learn everything at once.
I think it's also easier to explain asm if you can describe what a piece of C/C++ code will look like in ASM. Like how a function call actually works at instruction level.
If you have to learn about functions and datastructures and such at the same time as learning ASM, it will also be more difficult.
Posted on 2009-03-11 12:44:42 by Scali

I still don't get it! Why would somebody still want to do 16-bit DOS programming? :(


I have a hobby in legacy systems!
If I was to make something modern I would be asking about 32 bit windows, but this is a hobby.
Posted on 2009-03-16 05:43:16 by Grich
I also still use 16-bit as a hobby.  Here's a tutorial showing how to plot pixels.  It is geared towards QBASIC users.
Posted on 2009-04-17 21:43:09 by rCX
Starting your study in asm with anything but 32-bit x86 is impractical, a waste of time, and guarantees a massive drop in interest from all the students. 65535 is an insanely low and useless number. Not being able to use most registers and memory to your immediate bidding is an immensely huge obstacle. Printing stuff in a DOS prompt is another setback.

Provide several API:
int IsKeyDown(int key) // returns 0 or 1
DWORD* Initialize(int width,int height); // returns address to an int, that is the backbuffer. sDraw's sdLockRect() can/should be used
void ShowOnscreen(); // copies backbuffer onscreen, uses PeekMessage on current queue, waits for 16ms
void Exit();
and the macros:
prints // this is PrintStringByAddr from VKDebug
print // this is PrintDec
printh // this is PrintHex
PrintFloat


This way, the students don't need to care about Win32 specifics apart from not messing-up ESP (it'll be ok to let them trash EBX,ESI and EDI!!). The students get nice, color-highlighted, intellisense-enabled IDEs, can debug their code in two ways, and can try their hand on alphablending and custom blending/drawing of true-color.
But first, get them to see a step-debug of a simple asm-program, that calls nothing OS-specific. Show them what RAM really is: how a dword and a string look there, and how we interpret RAM values in different ways.

On other cpus, you'll be just overwhelming them with limitations. So much, that it can be shorter to write a 300-page book listing what you CAN do with the ISA :P

After they are very familiar with 32-bit x86, you can try opening the gates to hell - i mean show them what ARM, PIC, Power, etc ISA are like.
Posted on 2009-04-17 22:59:14 by Ultrano