home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
listings
/
v_02_03
/
2n03038a
< prev
next >
Wrap
Text File
|
1991-01-31
|
18KB
|
421 lines
/* plot1024.c Copyright 1990 by Gary R. Olhoeft */
/*
Compile with the MicroWay NDP C-386 v2.1.0 compiler and run
with the Phar Lap 386|DOS extender.
*/
#include <dos.h>
#include <stdio.h>
#include <math.h>
#include <grex.h> /* MicroWay NDP C-386 extended graphics library */
#include <reg8514.h> /* VESA 8514/A registers after Richter & Smith (1990) */
#define outpw(p,v) dx = p; ax = v; asm(dx,ax," out dx,ax")
unsigned char **image();
void free_image();
void plot_image_tseng();
void grey_vga();
void plot_image_hgsc();
void grey_hgsc();
void plot_image_8514();
void grey_8514();
void set_hgsc();
union REGS reg; /* required by DOS INT */
int _pmode;
/* VESA 8514/A 1024x768x256 timing control register parameters */
static short initRegs[] =
{ DISP_CNTL, ADVFUNC_CNTL, V_TOTAL, V_SYNC_STRT,
V_DISP, H_TOTAL, H_SYNC_STRT, H_DISP,
H_SYNC_WID, V_SYNC_WID, DISP_CNTL, 0 };
static short mode1024x8[] =
{ 0x0053, 0x0007, 0x0660, 0x0600,
0x05FB, 0x009D, 0x0081, 0x007F,
0x0016, 0x0008, 0x0033 };
int _pmode;
unsigned char hpgl_page;
main ()
{
reg$eax unsigned short ax, v; /* required by inline assembler */
reg$edx unsigned short dx, p;
FILE *stream_in;
char file_in[80];
unsigned char str[4096], **image_array;
int i,j,k;
char hstr[20];
asm("hstdata equ 0C7000h"); /* HGSC 34010 host addresses */
asm("hstctrl equ 0C7D00h"); /* for inline assembler use */
asm("hstadrl equ 0C7E00h");
asm("hstadrh equ 0C7F00h");
_pmode=0x8000; /* binary disk access */
/* read in the image to be displayed (Jupiter's moon Io from Voyager I) */
strcpy(file_in,"e:\\img\\c1636828.img\0");
if ((stream_in = fopen(file_in,"r")) == NULL)
{
printf("Cannot find File %s\n",file_in); exit(0);
}
else
{
printf("Reading Image File %s\n",file_in);
i=fread(str,1,2*836,stream_in); /* ignore PDS header */
image_array = image(768,1024); /* create space for image */
for (i=0; i<768; i++) fread(&image_array[i][0], 1, 836, stream_in);
i=fclose(stream_in);
}
/* Tseng 4000 STB EM-16 Plus PowerGraph 1024x768x256 */
blk_mb(str, 0x34, 0xC0000, 500); /* read BIOS area */
k = -1;
strcpy(hstr," STB \0");
for (i=0; i<480; i++) {j = memcmp(str+i,hstr,5); if (j==0) k=j;}
if (k != -1)
{
k = -1;
strcpy(hstr,"AWARD\0");
for (i=0; i<480; i++) { j = memcmp(str+i,hstr,5); if (j==0) k = j;}
if (k != -1) /* Tseng 4000 (STB EM-16 Plus PowerGraph) found */
{
reg.b.ah = 0;
reg.b.al = 56;
int386(0x10,®,®); /* set mode */
/* set grey scale using MicroWay libGREX palette function */
/* up to 2. sec */
for (i=0; i<256; i++) {j = i>>2; vga_palette(i,j,j,j);}
plot_image_tseng(image_array); /* plot image in 0.193 sec */
getch(); /* wait for keypress */
}
}
/* IBM 8514/A 1024x768x256 setup after Richter and Smith (1990) */
outp(DAC_MASK, 0x00); /* blank screen by turning all planes off */
outpw(SUBSYS_CNTL, GPCTRL_RESET | CHPTEST_NORMAL); /* reset 8514/A */
outpw(SUBSYS_CNTL, GPCTRL_ENAB | CHPTEST_NORMAL);
outpw(ERR_TERM, 0xFFFF); /* test for 8514/A card */
if (inpw(ERR_TERM) == 0xFFFF) /* 8514/A card found */
{
i = inpw(SUBSYS_STAT); /* get board status information */
if ((i & MONITORID_MASK) == MONITORID_8514) /* 1024x768 monitor */
{
outpw(MULTIFUNC_CNTL, MEM_CNTL | VRTCFG_4 | HORCFG_8);
i = 0; /* setup 1024x768 timing parameters */
while (initRegs[i]) { outpw(initRegs[i], mode1024x8[i]); i++;}
outpw(DAC_MASK, 0xFF); /* enable all 8 planes */
outpw(FRGD_MIX, FSS_FRGDCOL | MIX_REPLACE);
outpw(BKGD_MIX, BSS_BKGDCOL | MIX_REPLACE);
/* clip to full drawable space (0,0 to 1023,1023) */
outpw(MULTIFUNC_CNTL, SCISSORS_T | 0x000);
outpw(MULTIFUNC_CNTL, SCISSORS_L | 0x000);
outpw(MULTIFUNC_CNTL, SCISSORS_B | 0x3FF);
outpw(MULTIFUNC_CNTL, SCISSORS_R | 0x3FF);
outpw(WRT_MASK, 0xFFFF); /* enable writes to all planes */
outpw(MULTIFUNC_CNTL, PIX_CNTL | 0); /* clear lower bits */
WaitQueue(6); /* wait until 8514 queue ready */
outpw(FRGD_COLOR, 0); /* set color */
outpw(CUR_X, 0); /* set origin */
outpw(CUR_Y, 0);
outpw(MAJ_AXIS_PCNT, 1023); /* set size */
outpw(MULTIFUNC_CNTL, MIN_AXIS_PCNT | 1023);
outpw(CMD, CMD_RECT | INC_Y | INC_X | DRAW | PLANAR | WRTDATA);
WaitQueue(4);
outpw(CUR_X, 0); /* reset draw position to (0,0) */
outpw(CUR_Y, 0);
outpw(FRGD_COLOR, 0xFFFF); /* foreground all on */
outpw(BKGD_COLOR, 0); /* background all off */
grey_8514(); /* setup 8514 grey scale 0.00087 sec*/
outpw(FRGD_MIX, FSS_PCDATA | MIX_REPLACE);
plot_image_8514(image_array); /* plot image in 0.385 sec */
getch(); /* wait for key press */
outpw(ADVFUNC_CNTL, 6); /* restore 8514/A to VGA */
}
}
/* Hercules Graphics Station Card GB1024 TI34010 1024x768x256 */
blk_mb(str, 0x34, 0xC0000, 500); /* read BIOS area */
k = -1;
strcpy(hstr,"Hercules\0");
for (i=0; i<480; i++) {j = memcmp(str+i,hstr,8); if (j==0) k=j;}
if (k != -1)
{
k = -1;
strcpy(hstr,"Graphics Station\0");
for (i=0; i<480; i++) { j = memcmp(str+i,hstr,16); if (j==0) k = j;}
if (k != -1) /* HGSC found */
{
set_hgsc(); /* set 34010 mode 1024x768 */
grey_hgsc(); /* setup grey scale 0.00082 sec */
plot_image_hgsc(image_array); /* plot image in 0.275 sec */
getch(); /* wait for key press */
setvga(); /* restore HGSC to VGA modes */
/* setvga is found in TECH Specialist, v.1, n.5, p.35 */
}
}
free_image(image_array, 768); /* free image memory */
set_video_mode(0x02); /* restore text mode */
}
unsigned char **image(row,col)
int row,col;
{ /* allocates 8-bit 2D image matrix with range [0...row-1][0...col-1] */
int i;
unsigned char **m; /* no error checking: assumes enough memory exists */
m = (unsigned char **) malloc((unsigned)(row)*sizeof(unsigned char *));
for (i=0; i<row; i++)
m[i] = (unsigned char *) malloc((unsigned)(col)*sizeof(unsigned char));
return m;
}
void free_image(m,row)
unsigned char **m;
int row;
{ /* frees memory malloc'd by image function in Listing 2 */
int i;
for (i=row-1; i>=0; i--) free(m[i]);
free(m);
}
void plot_image_tseng(image_array) /* Tseng 4000 chipset 1024x768x256 */
unsigned char **image_array;
{
reg$eax unsigned short ax; /* required by inline assembler */
reg$esi unsigned esi;
reg$edi unsigned edi;
reg$ecx unsigned ecx;
int j, jj, k, vcol, row;
unsigned int cm;
unsigned short pel;
vcol = 1024; /* length of horizontal screen row */
row = -vcol;
asm(" push es"); /* save es register */
asm(" mov ax, 034h"); /* set Phar Lap LDT to access */
asm(" mov es, ax"); /* first megabyte of real memory */
hpgl_page = 99; /* force first page */
for (j=0; j<768; j++) /* vertical lines (rows) on screen */
{
row += vcol;
ax = (unsigned char)(row >> 16);/* divide by 64k to determine page */
if (ax!=hpgl_page) /* don't page unless changed */
{
hpgl_page = ax; /* save new page */
asm(" pushfd"); /* save flags */
asm(" cli "); /* clear interrupts */
asm(ax," or al,40h"); /* 8 64k pages */
asm(" mov dx,3cdh");/* GDC segment select register */
asm(" out dx,al"); /* select page */
asm(" popfd "); /* restore flags */
}
esi = &image_array[j][0]; /* 386 address of image row */
cm = (row % 65536); /* determine where in 64k page */
edi = 655360 + cm; /* VGA video address of row */
ecx = 256; /* number of pixels/4 to move */
asm(ecx,esi,edi, " rep movsd"); /* 256 double word mov's */
}
asm(" pop es"); /* restore es register */
}
void grey_8514()
{
asm(" xor eax,eax"); /* eax = 0 */
asm(" mov dx,02ECh");
asm(" out dx,al"); /* starting palette index */
asm(" mov dx,02EDh");
asm(" xor ebx,ebx"); /* ebx = 0 */
asm("lll: mov eax,ebx");
asm(" shr eax,2"); /* divide by 4 for 6-bit palette */
asm(" out dx,al"); /* red */
asm(" out dx,al"); /* green */
asm(" out dx,al"); /* blue */
asm(" inc ebx");
asm(" cmp ebx,256"); /* 256 palette entries */
asm(" jl lll");
}
void plot_image_8514(image_array)
unsigned char **image_array;
{
reg$eax unsigned eax; /* required by inline assembler */
reg$eax unsigned short ax, v;
reg$ecx unsigned ecx;
reg$edx unsigned short dx, p;
reg$esi unsigned esi;
int i;
unsigned short pel;
WaitQueue(8); /* wait until queue is empty */
outpw(MULTIFUNC_CNTL, 0); /* line width 0 = single pixel */
outpw(MAJ_AXIS_PCNT, 1023); /* line length = 1024 pixels */
pel = BYTSEQ | _16BIT | CMD_LINE | PCDATA | LINETYPE | DRAW | WRTDATA;
for (i=0; i<768; i++) /* cycle through rows (y) */
{
outpw(CUR_Y, (short)(i)); /* y position in 8514/A memory */
outpw(CUR_X, 0); /* x position in 8514/A memory */
outpw(CMD, pel); /* setup transfer command */
dx = PIX_TRANS; /* port for transfer to 8514 */
ecx = 512; /* 16-bit words to move */
esi = &image_array[i][0]; /* address of line in 386 memory */
asm(dx, esi, ecx, "rep outsw");/* send whole line of pixel pairs */
}
}
void set_hgsc()
{
asm(" push es"); /* save es register */
asm(" mov ax,034h"); /* setup Phar Lap LDT to first MByte */
asm(" mov es,ax");
asm(" mov cx,0C000h");
asm(" mov ax,0B040h"); /* dpyctl = enable video, interlaced */
asm(" and ax,7FFFh"); /* blank video */
asm(" mov bx,80h");
asm(" call write"); /* write ax to cx:bx in 34010 */
asm(" mov ax,157"); /* htotal */
asm(" mov bx,30h");
asm(" call write");
asm(" mov ax,156"); /* hsblnk; hsblnk-heblnk = 1024/8 */
asm(" mov bx,20h");
asm(" call write");
asm(" mov ax,28"); /* heblnk; increase to move screen right */
asm(" mov bx,10h");
asm(" call write");
asm(" mov ax,21"); /* hesync */
asm(" mov bx,0");
asm(" call write");
asm(" mov ax,407"); /* vtotal */
asm(" mov bx,70h");
asm(" call write");
asm(" mov ax,405"); /* vsblnk; vsblnk-veblnk = 768/2 */
asm(" mov bx,60h");
asm(" call write");
asm(" mov ax,21"); /* veblnk; increase to move screen down */
asm(" mov bx,50h");
asm(" call write");
asm(" mov ax,4"); /* vesync */
asm(" mov bx,40h");
asm(" call write");
asm(" mov ax,0"); /* dpytap */
asm(" mov bx,1B0h");
asm(" call write");
asm(" mov ax,0FFFCh"); /* dpystrt; 1 scan line per refresh */
asm(" mov bx,90h");
asm(" call write");
asm(" mov cx,600h");
asm(" mov bx,0E0h"); /* 0600:00E0 write config.2 reg. */
asm(" mov ax,0Fh"); /* bppsync = 8 bpp, -horz, -vert sync */
asm(" call write");
asm(" mov bx,0C0h"); /* 0600:00C0 write config.1 reg. */
asm(" mov ax,12"); /* cmdfreq = 44.9 MHz, cmd & overlay */
asm(" call write");
asm(" mov bx,20h"); /* 0600:0020 = cmd register in DAC */
asm(" mov ax,05Bh"); /* daclut = 8bpp + 24-bit LUT, no overlay */
asm(" call write");
asm(" mov bx,0C0h"); /* 0600:00C0 = write config. 1 */
asm(" mov ax,4"); /* normfreq = 44.9 Mhz, normal palette */
asm(" call write");
asm(" mov ax,0C000h"); /* no autoincrement */
asm(" mov es:hstctrl,ax"); /* setup 34010 */
asm(" mov cx,0C000h");
asm(" mov ax,0B040h"); /* dpyctl */
asm(" mov bx,80h");
asm(" call write"); /* enable video */
asm(" pop es"); /* restore es register */
asm(" ret"); /* return to calling program */
asm("write proc near"); /* create subroutine */
asm(" mov es:hstadrl,bx");
asm(" mov es:hstadrh,cx");
asm(" mov es:hstdata,ax"); /* write ax to cx:bx */
asm(" ret");
asm("write endp");
}
void grey_hgsc()
{
asm(" push es"); /* save es register */
asm(" mov ax,034h"); /* setup Phar Lap LDT to first Mbyte */
asm(" mov es,ax");
asm(" pushfd"); /* save flags */
asm(" cli"); /* disable interrupts */
asm(" mov ax,0C000h");
asm(" mov es:hstctrl,ax"); /* turn off autoincrement */
asm(" mov ax,01E0h");
asm(" mov es:hstadrl,ax");
asm(" mov ax,0600h");
asm(" mov es:hstadrh,ax");
asm(" mov cx,es:hstdata"); /* read & save config 2 */
asm(" mov ax,80h");
asm(" mov es:hstadrl,ax");
asm(" mov ax,0C000h");
asm(" mov es:hstadrh,ax");
asm(" mov ax,es:hstdata"); /* read dpyctl */
asm(" push eax"); /* save eax (dpyctl) */
asm(" and ax,7FFFh");
asm(" mov es:hstdata,ax"); /* blank video */
asm(" mov ax,00E0h");
asm(" mov es:hstadrl,ax");
asm(" mov ax,0600h");
asm(" mov es:hstadrh,ax");
asm(" mov ax,0Ch"); /* -H -V sync VGA control VRAM */
asm(" mov es:hstdata,ax"); /* write config 2 for VGA */
asm(" xor eax,eax"); /* can only change palette in VGA */
asm(" mov dx,03C8h");
asm(" out dx,al"); /* starting palette index */
asm(" mov dx,03C9h");
asm(" xor eax,eax");
asm("ll: out dx,al"); /* red */
asm(" out dx,al"); /* green */
asm(" out dx,al"); /* blue */
asm(" inc eax");
asm(" cmp eax,256"); /* 256 palette entries */
asm(" jl ll");
asm(" mov es:hstdata,cx"); /* restore original config 2 */
asm(" mov ax,80h");
asm(" mov es:hstadrl,ax");
asm(" mov ax,0C000h");
asm(" mov es:hstadrh,ax");
asm(" pop eax"); /* get saved eax */
asm(" mov es:hstdata,ax"); /* restore dpyctl, enable video */
asm(" popfd"); /* restore flags (interrupts) */
asm(" pop es"); /* restore es register */
}
void plot_image_hgsc(image_array) /* 1024x768x256 HGSC */
unsigned char **image_array;
{
reg$ebx unsigned ebx; /* required by inline assembler */
reg$esi unsigned esi;
esi = &image_array[0][0]; /* image array address in 386 memory */
ebx = 12; /* lines = height/64 */
asm(esi,ebx," push es"); /* send esi & ebx to assembler, save es */
asm(" mov ax,034h"); /* setup Phar Lap LDT to first Mbyte */
asm(" mov es,ax");
asm(" mov ax,0D800h");
asm(" mov es:hstctrl,ax"); /* setup 34010 for transfer */
asm(" cld"); /* set direction of movsd */
asm(" xor eax,eax"); /* eax = 0 */
asm(" mov es:hstadrl,ax");
asm(" mov es:hstadrh,ax"); /* starting address in 34010 memory */
asm(" mov dx,46E8h");
asm(" out dx,ax"); /* disable VGA */
asm(" align 4");
asm("slp: lea edi,es:[655360]"); /* starting address of hstdata shadow */
asm(" mov eax,64"); /* 64 lines per shadow page */
asm("llp: mov ecx,256"); /* 256 double words per 1024 pixel line */
asm("rep movsd"); /* move 1024 pixel line */
asm(" add esi,8"); /* skip array pointers */
asm(" dec eax");
asm(" cmp eax,0");
asm(" jnz llp"); /* loop 64 lines/page */
asm(" dec ebx");
asm(" cmp ebx,0");
asm(" jnz slp"); /* loop 12 pages/image */
asm(" mov dx,46E8h");
asm(" mov ax,0Eh");
asm(" out dx,ax"); /* enable VGA */
asm(" mov ax,0C000h"); /* turn off autoincrement */
asm(" mov es:hstctrl,ax");
asm(" pop es"); /* restore es register */
}