blob: 92adcddd4992cdcd8082f0f0808860fa8787e26f [file] [log] [blame]
/****************************************************************************
*
* SciTech OS Portability Manager Library
*
* ========================================================================
*
* The contents of this file are subject to the SciTech MGL Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.scitechsoft.com/mgl-license.txt
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
*
* The Initial Developer of the Original Code is SciTech Software, Inc.
* All Rights Reserved.
*
* ========================================================================
*
* Language: ANSI C
* Environment: any
*
* Description: Test program to check the ability to generate real mode
* interrupts and to be able to obtain direct access to the
* video memory from protected mode. Compile and link with
* the appropriate command line for your DOS extender.
*
* Functions tested: PM_getBIOSSelector()
* PM_mapPhysicalAddr()
* PM_int86()
*
****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include "pmapi.h"
uchar *bios; /* Pointer to BIOS data area */
uchar *videoPtr; /* Pointer to VGA framebuffer */
void *stateBuf; /* Console state save buffer */
/* Routine to return the current video mode number */
int getVideoMode(void)
{
return PM_getByte(bios+0x49);
}
/* Routine to set a specified video mode */
void setVideoMode(int mode)
{
RMREGS r;
r.x.ax = mode;
PM_int86(0x10, &r, &r);
}
/* Routine to clear a rectangular region on the display by calling the
* video BIOS.
*/
void clearScreen(int startx, int starty, int endx, int endy, unsigned char attr)
{
RMREGS r;
r.x.ax = 0x0600;
r.h.bh = attr;
r.h.cl = startx;
r.h.ch = starty;
r.h.dl = endx;
r.h.dh = endy;
PM_int86(0x10, &r, &r);
}
/* Routine to fill a rectangular region on the display using direct
* video writes.
*/
#define SCREEN(x,y) (videoPtr + ((y) * 160) + ((x) << 1))
void fill(int startx, int starty, int endx, int endy, unsigned char c,
unsigned char attr)
{
unsigned char *v;
int x,y;
for (y = starty; y <= endy; y++) {
v = SCREEN(startx,y);
for (x = startx; x <= endx; x++) {
*v++ = c;
*v++ = attr;
}
}
}
/* Routine to display a single character using direct video writes */
void writeChar(int x, int y, unsigned char c, unsigned char attr)
{
unsigned char *v = SCREEN(x,y);
*v++ = c;
*v = attr;
}
/* Routine to draw a border around a rectangular area using direct video
* writes.
*/
static unsigned char border_chars[] = {
186, 205, 201, 187, 200, 188 /* double box chars */
};
void border(int startx, int starty, int endx, int endy, unsigned char attr)
{
unsigned char *v;
unsigned char *b;
int i;
b = border_chars;
for (i = starty+1; i < endy; i++) {
writeChar(startx, i, *b, attr);
writeChar(endx, i, *b, attr);
}
b++;
for (i = startx+1, v = SCREEN(startx+1, starty); i < endx; i++) {
*v++ = *b;
*v++ = attr;
}
for (i = startx+1, v = SCREEN(startx+1, endy); i < endx; i++) {
*v++ = *b;
*v++ = attr;
}
b++;
writeChar(startx, starty, *b++, attr);
writeChar(endx, starty, *b++, attr);
writeChar(startx, endy, *b++, attr);
writeChar(endx, endy, *b++, attr);
}
int main(void)
{
int orgMode;
PM_HWND hwndConsole;
printf("Program running in ");
switch (PM_getModeType()) {
case PM_realMode:
printf("real mode.\n\n");
break;
case PM_286:
printf("16 bit protected mode.\n\n");
break;
case PM_386:
printf("32 bit protected mode.\n\n");
break;
}
hwndConsole = PM_openConsole(0,0,0,0,0,true);
printf("Hit any key to start 80x25 text mode and perform some direct video output.\n");
PM_getch();
/* Allocate a buffer to save console state and save the state */
if ((stateBuf = PM_malloc(PM_getConsoleStateSize())) == NULL) {
printf("Unable to allocate console state buffer!\n");
exit(1);
}
PM_saveConsoleState(stateBuf,0);
bios = PM_getBIOSPointer();
orgMode = getVideoMode();
setVideoMode(0x3);
if ((videoPtr = PM_mapPhysicalAddr(0xB8000,0xFFFF,true)) == NULL) {
printf("Unable to obtain pointer to framebuffer!\n");
exit(1);
}
/* Draw some text on the screen */
fill(0, 0, 79, 24, 176, 0x1E);
border(0, 0, 79, 24, 0x1F);
PM_getch();
clearScreen(0, 0, 79, 24, 0x7);
/* Restore the console state on exit */
PM_restoreConsoleState(stateBuf,0);
PM_free(stateBuf);
PM_closeConsole(hwndConsole);
/* Display useful status information */
printf("\n");
printf("Original Video Mode = %02X\n", orgMode);
printf("BIOS Pointer = %08X\n", (int)bios);
printf("Video Memory = %08X\n", (int)videoPtr);
return 0;
}