#include <dpmi.h> __dpmi_regs regs; memset(®s, 0, sizeof regs); regs.x.ax = 0x13; /* 0x13 is the mode number */ __dpmi_int(0x10, ®s);Ok, you've got the mode. Now, how do we write to the frame buffer?
#include <sys/farptr.h> #include <go32.h> /* for _dos_ds */ _farpokeb(_dos_ds, 0xa0000, 1)
sets the pixel in the upper left hand corner of the screen to 1. It compiles to:
movl $0xa0000, %eax movw $_dos_ds, %fs movb $1, fs:(%eax)
as long as you have at least -O1 turned on. (That's kind of a mangled AT&T+TASM syntax.) You can do a _farsetsel(_dos_ds) once before your sequence of peeks and pokes, and it'll leave FS set, and you can then use the _farns* functions like so:
#include <sys/farptr.h> #include <go32.h> /* for _dos_ds */ _farsetsel(_dos_ds); _farnspokeb(0xa0000, 1); _farnspokeb(0xa0001, 2);
which will avoid loading FS every iteration.
#include <sys/nearptr.h> char *screen; if (__djgpp_nearptr_enable() == 0) return ERROR; /* could happen */ /* You must recalculate the screen pointer every time you enter this mode because __djgpp_conventional_base can change when you malloc/new and other misc stuff. */ screen = 0xa0000 + __djgpp_conventional_base; screen[0] = 1; screen[1] = 1; /* etc. */ __djgpp_nearptr_disable();
Each of those screen moves is one instruction, of course. And screen is a honest-to-god [19] pointer, that you can memcpy to and from, or whatever. (Hint: If the length of a memcpy is fixed, and -O1 and up is turned on, memcpy becomes an inline rep movsl (rep movsd in TASM notation).)
Extra Note: __djgpp_nearptr_enable() is SLOW. Call it at most once per frame, and preferably just once at startup. While you're still debugging, though, you might want to turn it off and on per memory access.
#include <sys/movedata.h> void putpixel(int x, int y, int c) { _dosmemputb(&c, 1, 0xa0000 + x + y * 320); }Cheesey putpixel via far pointers:
#include <sys/farptr.h> #include <go32.h> /* for _dos_ds */ void putpixel(int x, int y, int c) { _farpokeb(_dos_ds, 0xa0000 + x + y * 320, c) }Cheesey putpixel via near pointers:
#include <sys/nearptr.h> void init_putpixel(void) { __djgpp_nearptr_enable(); } void putpixel(int x, int y, int c) { char *screen = 0xa0000 + __djgpp_conventional_base; *(screen + x + y * 320) = c; }
Example code:
#include <pc.h> char my_palette[768]; /* 256 rgb triplets */ void get_palette(char *pal) { int i; /* get the palette */ outportb(0x3c7, 0); /* want to read */ for (i = 0; i < 768; i++) pal[i] = inportb(0x3c9); } void set_palette(char *pal) { int i; /* set palette */ outportb(0x3c8, 0); /* want to write */ for (i = 0; i < 768; i++) outportb(0x3c9, pal[i]); }Viola!