home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1989
/
02
/
porter.asc
< prev
next >
Wrap
Text File
|
1989-01-04
|
15KB
|
425 lines
_Graphics Programming Column_
by Kent Porter
[LISTING ONE]
; DRAWPT.ASM: Writes pixel directly to 6845 Video Controller
; Microsoft MASM 5.1
; C prototype is
; void far draw_point (int x, int y);
; To be included in GRAFIX.LIB
; K. Porter, DDJ Graphics Programming Column, February '89
.MODEL LARGE
.CODE
PUBLIC _draw_point
EXTRN _color1 : BYTE ; From GRAFIX.LIB
x EQU [bp+6] ; Arguments passed from C
y EQU [bp+8]
_draw_point PROC FAR
push bp ; Entry processing
mov bp, sp
; Point ES to video memory segment
mov ax, 0A000h
mov es, ax
; Row offset = y * 80;
mov bx, y ; Get y argument
mov ax, 80
mul bx ; Result in AX
mov bx, ax ; Row offset in BX
; Column offset = x SHR 3
mov ax, x ; Get x
mov cl, 3 ; Shift operand
shr ax, cl ; Column offset
; Complete address of pixel byte
add bx, ax ; ES:BX = address
; Build bit mask for pixel
mov cx, x ; Get x again
and cx, 7 ; Isolate low-order bits
xor cl, 7 ; Number of bits to shift
mov ah, 1 ; Start bit mask
shl ah, cl ; Shift for pixel
mov cl, ah ; Save it
; Use write mode 2 (single-pixel update)
mov dx, 03CEh ; 6845 command register
mov al, 5 ; Specify mode register
mov ah, 2 ; Write mode 2
out dx, ax ; Send
; Set 6845 bit mask register
mov al, 8 ; Specify bit mask register
mov ah, cl ; al = mask
out dx, ax ; Send bit mask
; Draw the pixel
mov al, es:[bx] ; Load 6845 latch registers
xor al, al ; Clear
mov byte ptr es:[bx], al ; Zero the pixel for replace
mov al, _color1 ; Get the pixel value
mov es:[bx], al ; Write the pixel
; Restore video controller to default state
mov dx, 03CEh
mov ax, 0005h ; write mode 0, read mode 0
out dx, ax
mov ax, 0FF08h ; default bit mask
out dx, ax
mov ax, 0003h ; default function select
out dx, ax
xor ax, ax ; zero Set/Reset
out dx, ax
mov ax, 0001h ; zero Enable Set/Reset
out dx, ax
mov dx, 03C4h ; 6845 address reg
mov ax, 0F02h ; Data reg, enable all planes
out dx, ax
; Exit
mov sp, bp
pop bp
retf
_draw_point ENDP
END
[LISTING TWO]
1| /* Library source file GRAFIX.C */
2| /* EGA/VGA graphics subsystem */
3| /* Following library routines are external: */
4| /* DRAWPT.ASM Feb '89 */
5| /* K. Porter, DDJ Graphics Programming Column */
6| /* ------------------------------------------ */
7|
8| #include <dos.h>
9| #include <stdlib.h>
10| #include <string.h>
11| #include <stdio.h>
12| #include "grafix.h"
13|
14| #if !defined TRUE
15| #define FALSE 0
16| #define TRUE !FALSE
17| #endif
18|
19| /* Variables global to this library */
20| int color1, /* foreground color */
21| oldmode = 0, /* pre-graphics mode */
22| grafixmode = 0, /* default graphics mode */
23| ega = FALSE, /* equipment Booleans */
24| vga = FALSE,
25| colormonitor = FALSE,
26| curpos, /* text cursor position */
27| textpage; /* active text page */
28| unsigned vidmem; /* video buffer segment */
29| char far *vidsave; /* video buffer save area */
30|
31| /* -------------------------------------------------------- */
32|
33| int far init_video (int mode)
34|
35| /* Initializes video adapter and defaults for mode */
36| /* Sets up pc_textmode() to be called on pgm termination */
37| /* Returns TRUE or FALSE indicating success */
38| /* This function will be expanded in a later version */
39| {
40| union REGS r;
41| int result = FALSE;
42|
43| /* Determine attached adapter and monitor */
44| r.h.ah = 0x1A; /* VGA inquiry function */
45| r.h.al = 0;
46| int86 (0x10, &r, &r); /* ROM BIOS call */
47| if (r.h.al == 0x1A)
48| switch (r.h.bl) {
49| case 4 : ega = TRUE; /* EGA color */
50| colormonitor = TRUE;
51| break;
52| case 5 : ega = TRUE; /* EGA mono */
53| break;
54| case 7 : ega = TRUE; /* VGA mono */
55| vga = TRUE;
56| break;
57| case 8 : ega = TRUE; /* VGA color */
58| vga = TRUE;
59| colormonitor = TRUE;
60| }
61| else { /* No VGA, so check for EGA */
62| r.h.ah = 0x12;
63| r.x.bx = 0x10;
64| int86 (0x10, &r, &r);
65| if (r.x.bx != 0x10) { /* if EGA present... */
66| ega = TRUE; /* set flag */
67| r.h.ah = 0x12;
68| r.h.bl = 0x10; /* find out which monitor */
69| int86 (0x10, &r, &r);
70| if (r.h.bh == 0)
71| colormonitor = TRUE; /* EGA color */
72| }
73| }
74|
75| /* Proceed only if EGA or VGA present */
76| if (ega | vga) {
77| set_color1 (15); /* default pixel color */
78|
79| r.h.ah = 0x0F; /* get current screen mode */
80| int86 (0x10, &r, &r);
81| oldmode = r.h.al; /* store it */
82| textpage = r.h.bh; /* also active text page */
83|
84| if (colormonitor) /* point to video memory */
85| vidmem = 0xB800;
86| else
87| vidmem = 0xB000;
88| vidsave = malloc (4096); /* allocate save area */
89| movedata /* save text screen contents */
90| (vidmem, 0, FP_SEG (vidsave), FP_OFF (vidsave), 4096);
91|
92| r.h.ah = 3; /* get text cursor position */
93| r.h.bh = textpage;
94| int86 (0x10, &r, &r);
95| curpos = r.x.dx; /* and save it */
96|
97| if ((mode == EGA) && ega) {
98| r.h.ah = 0;
99| r.h.al = mode; /* set EGA mode */
100| int86 (0x10, &r, &r);
101| result = TRUE;
102| } else
103| if ((mode == vga) && vga) {
104| r.h.ah = 0;
105| r.h.al = mode;
106| int86 (0x10, &r, &r);
107| result = TRUE;
108| }
109| }
110| if (!result) { /* unable to switch to graphics */
111| oldmode = 0; /* so cancel text screen save */
112| free (vidsave);
113| vidsave = 0;
114| } else { /* successful, so... */
115| grafixmode = mode; /* save mode */
116| atexit (pc_textmode); /* register exit function */
117| }
118| return result;
119| } /* ------------------------------------------------------ */
120|
121| void far pc_textmode (void)
122| /* SPECIFIC TO MS-DOS */
123| /* Restore text mode */
124| /* Automatically called on pgm termination */
125| {
126| union REGS r;
127|
128| if (oldmode) { /* if not in text mode now... */
129| r.h.ah = 0;
130| r.h.al = oldmode; /* restore text mode */
131| int86 (0x10, &r, &r);
132| movedata /* restore text screen */
133| (FP_SEG (vidsave), FP_OFF (vidsave), vidmem, 0, 4096);
134| free (vidsave); /* free allocated memory */
135| vidsave = 0; /* zero pointer */
136| oldmode = 0; /* reset */
137| r.h.ah = 2; /* restore old cursor position */
138| r.h.bh = textpage;
139| r.x.dx = curpos;
140| int86 (0x10, &r, &r);
141| }
142| } /* ------------------------------------------------------ */
143|
144| void far set_color1 (int palette_reg)
145| /* Select pixel color from palette register */
146| {
147| color1 = palette_reg;
148| } /* ------------------------------------------------------ */
[LISTING THREE]
/* Library source file GRAFIX.C */
/* EGA/VGA graphics subsystem */
/* Following library routines are external: */
/* DRAWPT.ASM Feb '89 */
/* K. Porter, DDJ Graphics Programming Column */
/* ------------------------------------------ */
#include <dos.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "grafix.h"
#if !defined TRUE
#define FALSE 0
#define TRUE !FALSE
#endif
/* Variables global to this library */
int color1, /* foreground color */
oldmode = 0, /* pre-graphics mode */
grafixmode = 0, /* default graphics mode */
ega = FALSE, /* equipment Booleans */
vga = FALSE,
colormonitor = FALSE,
curpos, /* text cursor position */
textpage; /* active text page */
unsigned vidmem; /* video buffer segment */
char far *vidsave; /* video buffer save area */
/* -------------------------------------------------------- */
int far init_video (int mode)
/* Initializes video adapter and defaults for mode */
/* Sets up pc_textmode() to be called on pgm termination */
/* Returns TRUE or FALSE indicating success */
/* This function will be expanded in a later version */
{
union REGS r;
int result = FALSE;
/* Determine attached adapter and monitor */
r.h.ah = 0x1A; /* VGA inquiry function */
r.h.al = 0;
int86 (0x10, &r, &r); /* ROM BIOS call */
if (r.h.al == 0x1A)
switch (r.h.bl) {
case 4 : ega = TRUE; /* EGA color */
colormonitor = TRUE;
break;
case 5 : ega = TRUE; /* EGA mono */
break;
case 7 : ega = TRUE; /* VGA mono */
vga = TRUE;
break;
case 8 : ega = TRUE; /* VGA color */
vga = TRUE;
colormonitor = TRUE;
}
else { /* No VGA, so check for EGA */
r.h.ah = 0x12;
r.x.bx = 0x10;
int86 (0x10, &r, &r);
if (r.x.bx != 0x10) { /* if EGA present... */
ega = TRUE; /* set flag */
r.h.ah = 0x12;
r.h.bl = 0x10; /* find out which monitor */
int86 (0x10, &r, &r);
if (r.h.bh == 0)
colormonitor = TRUE; /* EGA color */
}
}
/* Proceed only if EGA or VGA present */
if (ega | vga) {
set_color1 (15); /* default pixel color */
r.h.ah = 0x0F; /* get current screen mode */
int86 (0x10, &r, &r);
oldmode = r.h.al; /* store it */
textpage = r.h.bh; /* also active text page */
if (colormonitor) /* point to video memory */
vidmem = 0xB800;
else
vidmem = 0xB000;
vidsave = malloc (4096); /* allocate save area */
movedata /* save text screen contents */
(vidmem, 0, FP_SEG (vidsave), FP_OFF (vidsave), 4096);
r.h.ah = 3; /* get text cursor position */
r.h.bh = textpage;
int86 (0x10, &r, &r);
curpos = r.x.dx; /* and save it */
if ((mode == EGA) && ega) {
r.h.ah = 0;
r.h.al = mode; /* set EGA mode */
int86 (0x10, &r, &r);
result = TRUE;
} else
if ((mode == vga) && vga) {
r.h.ah = 0;
r.h.al = mode;
int86 (0x10, &r, &r);
result = TRUE;
}
}
if (!result) { /* unable to switch to graphics */
oldmode = 0; /* so cancel text screen save */
free (vidsave);
vidsave = 0;
} else { /* successful, so... */
grafixmode = mode; /* save mode */
atexit (pc_textmode); /* register exit function */
}
return result;
} /* ------------------------------------------------------ */
void far pc_textmode (void)
/* SPECIFIC TO MS-DOS */
/* Restore text mode */
/* Automatically called on pgm termination */
{
union REGS r;
if (oldmode) { /* if not in text mode now... */
r.h.ah = 0;
r.h.al = oldmode; /* restore text mode */
int86 (0x10, &r, &r);
movedata /* restore text screen */
(FP_SEG (vidsave), FP_OFF (vidsave), vidmem, 0, 4096);
free (vidsave); /* free allocated memory */
vidsave = 0; /* zero pointer */
oldmode = 0; /* reset */
r.h.ah = 2; /* restore old cursor position */
r.h.bh = textpage;
r.x.dx = curpos;
int86 (0x10, &r, &r);
}
} /* ------------------------------------------------------ */
void far set_color1 (int palette_reg)
/* Select pixel color from palette register */
{
color1 = palette_reg;
} /* ------------------------------------------------------ */
[LISTING FOUR]
/* STRIPES.C: Demos pixel-writing with GRAFIX library */
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include "grafix.h"
void main ()
{
int x, y, color;
if (!init_video (EGA)) {
puts ("No EGA/VGA present in system: Program ended");
exit (1);
} else {
for (y = 95; y < 255; y++) {
color = y % 16; /* first color this row */
for (x = 160; x < 480; x++) {
set_color1 (color); /* set color this pixel */
draw_point (x, y);
if (++color == 16) color = 0; /* wrap around palette */
}
}
getch(); /* hold for keypress */
}
}