Документ взят из кэша поисковой машины. Адрес оригинального документа : http://crydee.sai.msu.ru/ftproot/pub/misc/doc/os2.hints/mode13
Дата изменения: Fri May 26 09:12:34 1995
Дата индексирования: Sun Apr 10 16:48:52 2016
Кодировка:
From ns.itep.ru!CERN.ch!EU.net!howland.reston.ans.net!news-e1a.megaweb.com!newstf01.news.aol.com!uunet!mr.net!winternet.com!pinch.io.org!gvc.com!tor250!org!gryn!x259_414!peter.fitzsimmons Wed May 24 09:55:59 1995
Path: ns.itep.ru!CERN.ch!EU.net!howland.reston.ans.net!news-e1a.megaweb.com!newstf01.news.aol.com!uunet!mr.net!winternet.com!pinch.io.org!gvc.com!tor250!org!gryn!x259_414!peter.fitzsimmons
From: Peter.Fitzsimmons@x259_414.gryn.org (Peter Fitzsimmons)
Date: 22 May 95 16:47:08
Newsgroups: comp.os.os2.programmer.porting
Subject: Mode 13h in OS/2 fullscreen apps
Message-ID: <38a_9505231456@tor250.org>
X-FTN-To: E9325123@Stud1.Tuwien.Ac.At
Organization: Gateway: sol3@olc.gvc.com
References:
Lines: 203

e> I want to port some DOS games to OS/2. I4ve a demo for OS/2 using a mode
e> 13h fullscreen. Unfortunatelly It doesn4t work anymore
e> after recompiling with
e> Watcom v10.0, which I use.
e> Does anyone have information about 4VioSetMode( )4 and 4VioPhysMode( )4,
e> which are used in those demos ??

Here is a sample that I (finally!) got working. Watcom (10.0b) does not
produce proper code for the following:


PCH pchScreen;

viopb.pBuf = (PBYTE) 0xA0000L;
viopb.cb = 64000L;
VioScrLock(LOCKIO_WAIT, (PBYTE) &fStatus, 0);
VioGetPhysBuf(&viopb, 0);
pchScreen = MAKEP(viopb.asel[0], 0);


'pchScreen' does not contain a properly thunked 0:32 pointer. This code works
fine for IBM Cset.

I had to change it to this:

ULONG ul16;
PUCHAR pchScreen;

viopb.pBuf = (PBYTE) 0xA0000L;
viopb.cb = 64000L;
VioScrLock(LOCKIO_WAIT, (PBYTE) &fStatus, 0);
VioGetPhysBuf(&viopb, 0);

// need to do this in two steps to work around Watcom v10 bug:
ul16 = viopb.asel[0] << 16;
pchScreen = (char * _Seg16)ul16; // compiler will now thunk 16:16 to 0:32

Here is the whole sample (NOTE: see the note about VIOCOLORREG in the code):

// icc /O /Gf /Kb /W3 /Ssp4 foo2.c
// (or) msc /Ox /W3 foo2.c

/* MAND graphs the Mandelbrot set. This is the core of the program.
Programmed by Radoslaw Osada. */

//#include
#include
#include
#include
#include
#define INCL_NOPM
#define INCL_NOPMAPI
#define INCL_VIO
#define INCL_DOS
#include

#define X_RES 320
#define Y_RES 200
#define COLORS 256
#define MAX_ITER 20
#define LEFT -2.5
#define RIGHT 1.5
#define CENTER 0
#define BAILOUT 1e12

static void setmode(void)
{
VIOMODEINFO vi;
USHORT rc;

vi.cb = sizeof(vi);
VioGetMode(&vi, 0);
vi.fbType = 3;
vi.color = 8;
vi.col = 40;
vi.row = 25;
vi.hres = X_RES;
vi.vres = Y_RES;
if( 0 != (rc = VioSetMode(&vi, 0))){
printf("SYS%04u: Could not set video mode to 320x200x256", rc);
exit(1);
}
}

// before this function will work with a 32 bit compiler, you must
// fix bsesub.h:
#if 0
typedef struct _VIOCOLORREG /* viocreg */
{
USHORT cb;
USHORT type;
USHORT firstcolorreg;
USHORT numcolorregs;
//PCH colorregaddr;
PUCHAR16 colorregaddr; /*PLF Sun 94-02-13 16:01:29*/
} VIOCOLORREG;
typedef VIOCOLORREG *PVIOCOLORREG;
#endif

static void rotate(void)
{
USHORT rc;
int i;
static VIOCOLORREG vcr;
static int init = FALSE;
static BYTE pal[768];

if(!init){
vcr.cb = sizeof(vcr);
vcr.type = 3;
vcr.firstcolorreg = 0;
vcr.numcolorregs = 256;
vcr.colorregaddr = pal;
rc = VioGetState(&vcr, 0);
if(rc){
printf( "SYS%04u: Error getting palette registers.\n", rc);
exit(1);
}
init = TRUE;
}
for(i=0; i<255; i++){
pal[(i * 3) + 0] = pal[(1+i)*3 + 0];
pal[(i * 3) + 1] = pal[(1+i)*3 + 1];
pal[(i * 3) + 2] = pal[(1+i)*3 + 2];
}
pal[255 * 3 + 0] = pal[0];
pal[255 * 3 + 1] = pal[1];
pal[255 * 3 + 2] = pal[2];
rc = VioSetState(&vcr, 0);
if(rc){
printf( "SYS%04u: Error setting palette registers.\n", rc);
exit(1);
}
}

int main(void)
{
VIOPHYSBUF viopb;
ULONG ul16;
PUCHAR pchScreen;
USHORT fStatus;

double width, height, top;
double x, y, real, imag, old_x;
double x_ratio, y_ratio;
int iter, x_cord, y_cord;


setmode();
viopb.pBuf = (PBYTE) 0xA0000L;
viopb.cb = 64000L;
VioScrLock(LOCKIO_WAIT, (PBYTE) &fStatus, 0);
VioGetPhysBuf(&viopb, 0);
// need to do this in two steps to work around Watcom v10 bug:
ul16 = viopb.asel[0] << 16;
pchScreen = (char * _Seg16)ul16; // compiler will thunk 16:16 to 0:32
_fmemset(pchScreen, 0, (size_t)viopb.cb);


width = RIGHT - LEFT;
height = width * .75;
top = CENTER + height * .5;

x_ratio = width / (X_RES - 1);
y_ratio = height / (Y_RES - 1);


for (y_cord = 0; y_cord < Y_RES; y_cord++) {
y = top - y_cord * y_ratio;

for (x_cord = 0; x_cord < X_RES; x_cord++) {
x = x_cord * x_ratio + LEFT;
real = x;
imag = y;

for (iter = 0; iter <= MAX_ITER; iter++) {
if (real * real + imag * imag > BAILOUT)
break;

old_x = real;
real = real * real - imag * imag + x;
imag = 2 * old_x * imag + y;
}

if (iter != MAX_ITER + 1) {
pchScreen[y_cord * X_RES + x_cord] = (UCHAR)(iter % COLORS);
}
}
// if( kbhit() ) break; this is a huge waste of CPU under os/2.
}
VioScrUnLock(0);
DosSetPriority(PRTYS_PROCESS, PRTYC_IDLETIME, 1, 0);
while(!kbhit()){
rotate();
DosSleep(50L);
}
return 0;
}


--
| Fidonet: Peter Fitzsimmons 1:259/414
| Internet: Peter.Fitzsimmons@x259_414.gryn.org