home *** CD-ROM | disk | FTP | other *** search
- _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 */
- }
- }
-
-