home *** CD-ROM | disk | FTP | other *** search
-
- /*
- The following software can be used and modified freely. I can not
- however be sold in any way. This includes both seperately and
- compiled into programs.
-
- The following is the work I have done on creating .BGI driver
- files for TURBO-C 2.0 and TURBO PASCAL. Although the majority
- of the functions work and can be used as is, it is by no means a
- complete . My main reason for posting this is so that people
- who want to create their own BGI drivers have a good starting point
- and a good example to follow. The routines that to block fills/reads
- have been written a little trickier than need be. This was to make
- them fast enough to be usable (the tricks are somewhat described
- in the code where they are used).
-
- The two main ingredients that went into this were:
- 1. A skeleton of a BGI header which was posted to the net
- sometime ago.
- 2. The book "Graphics Programming in Turbo-C 2.0" written
- by Ben Ezzell and published by Addison-Wesley. I found
- it a B-Dalton. This book is almost a must if you hope
- to write a BGI driver.
-
- I will help answer questions (at least until I get tired of it).
- Mainly I will look gather up all the commo questions and post
- them to the net.
-
- I also want to make it clear that I am basically a High level
- language programmer and had to learn Assembly as I went to
- write this. Therefor, I DONT want to here any comments about
- my poor assembly language programming style.
-
- REMEMBER, THIS IS MAINLY INTENDED AS A DEVELOPEMENT EXAMPLE
- AND IS NOT INTENDED TO BE A RELEASED PRODUCT ( although almost
- all of the functions do work for this graphics card ).
-
- ======================= CUT APART HERE AND NAME BGITEST.C ===========
- /*
-
- This is a real hack of a demo program but it at least shows you
- what your C program must do to install and use a user-written
- device driver. I had most of the BORLAND SUPPLIED bgidemo.c
- program working after I took out their palette demo routine
- and change the program to use another font other than DEFAULT
- ( which I could not make work ). I didn't post I because I
- was afraid BORLAND could bust me for posting it.
-
- */
-
-
-
- #include <graphics.h>
- #include <stdlib.h>
- #include <stdio.h>
-
- int huge detectLEEVGA(void);
-
-
- main()
- {
-
- int driver, mode;
- int ysize, xsize;
- int i;
-
-
- driver =installuserdriver ("LEEVGA", detectLEEVGA);
-
-
- {
- int ec;
- if ((ec=graphresult()) < 0) {
- printf("unable to register\n");
- printf("reason <%s>\n", grapherrormsg(ec));
- exit(-1);
- return(-1);
- }
- }
-
-
- driver = DETECT;
- initgraph(&driver, &mode, "");
-
- {
- int ec;
- if ((ec=graphresult()) < 0) {
- printf("unable to open this graphics mode\n");
- printf("reason <%s>\n", grapherrormsg(ec));
- exit(-1);
- return(-1);
- }
- }
-
-
- printf(" max x= %d\n", xsize=getmaxx());
- printf(" max y= %d\n", ysize=getmaxy());
- printf(" modename= %s\n", getmodename(0));
- printf(" drivername= %s\n", getdrivername());
- printf(" maxcolors= %d\n", getmaxcolor());
- printf(" palette size=%d\n", getpalettesize());
-
-
- #define DO 1
- #ifdef DO
- setfillstyle ( SOLID_FILL, 15 );
- setcolor ( 12 );
-
- outtextxy(xsize/6,ysize/3,"A b C d E f G h I J k"); getch();
- printf(" Outtext ( DEFAULT FONT ) is done\n"); getch();
-
- settextstyle(TRIPLEX_FONT,HORIZ_DIR,4);
- outtextxy(xsize/6,ysize/4,"0 1 2 3 4 5 6 7 8 9 0");
- printf(" Outtext ( TRIPLEX_FONT ) is done\n"); getch();
-
- setlinestyle(DASHED_LINE,0,NORM_WIDTH);
-
- for (i=10; i < xsize/3*2 ; i++) {
- putpixel(i,ysize/4,12);
- }
- printf(" pixel puts are done, press a key\n");getch();
-
- #endif
-
- setfillstyle ( SLASH_FILL, 11 );
- setlinestyle(DASHED_LINE,0,NORM_WIDTH);
-
- pieslice(xsize/2,ysize/2,45,45+90,ysize/3);
-
-
- circle (xsize/2, ysize/2,ysize/2);
- ellipse(xsize/2,ysize/2,0,0,100,100);
- printf(" circle done press a key\n");getch();
-
- setlinestyle(CENTER_LINE,0,NORM_WIDTH);
- line ( 10,ysize/2,ysize-100,ysize/2);
- line ( xsize/2, 10 , xsize/2 , ysize/2 );
- printf(" lines done, press a key\n");getch();
-
- rectangle (10,20,xsize/6,ysize/2);
- printf(" rectangle done, press a key\n");getch();
-
-
- setlinestyle(DOTTED_LINE,0,THICK_WIDTH);
-
- setfillstyle ( XHATCH_FILL, 21 );
- setcolor(83);
- bar3d ( xsize/2,ysize/2, xsize/6*5,ysize, 50, 1);
- printf(" bar is done, press a key\n");getch();
- setlinestyle(DASHED_LINE,0,NORM_WIDTH);
-
-
- {
- int pp[10]={100,100, 100,150, 180,195, 300,150, 330,100};
-
- setfillstyle ( CLOSE_DOT_FILL, 11 );
-
- fillpoly ( 5 , &pp );
- printf(" filled polygon is done, press a key\n");getch();
- }
-
-
-
-
- setrgbpalette(12,1,2,3);
-
- {
- typedef struct {
- char r,g,b;
- } entry;
-
- struct p {
- char size;
- entry index[256];
- } palette;
-
- palette.size = 3*256;
- palette.index[0].r =1;
- palette.index[0].g =2;
- palette.index[0].b =3;
-
-
- setallpalette(&palette);
- }
-
-
-
-
- cleardevice();
- printf(" clear done\n");
-
-
- printf(" press a key\n");getch();
- closegraph();
-
- }
-
-
-
-
- /* ______________________ */
-
- int huge detectLEEVGA(void)
- {
-
- printf("detecting\n");
-
- /*
- You must write code here to detect whether or not
- the graphics card is available and what its maximum mode
- is. By returning the value of ONE here, I am telling
- it I have detected my graphics card and the mode I want
- it to use is ONE.
-
- */
-
- return(1);
- }
-
- ======================== CUT APART HERE and NAME IT LEEVGA.ASM ==========
-
- ; know problems
- ; 1. the default font has not been done.
- ; 2. flood fill has not been done.
-
- ; to compile (create) the .BGI file use the following
-
- ; masm leevga.asm leevga.obj NUL.LST NUL.LST
- ; link leevga.obj,leevga.exe,NUL.MAP,.LIB
- ; exe2bin leevga.exe leevga.bgi
- ; del leevga.exe
- ; del leevga.obj
-
-
- ;------------------------------------------------------;
- ; LEEBGI.BGI ;
- ; Borland Graphic Interface for TP 5.0, TC2.0 ;
- ; Paridise VGA Graphics Board ;
- ; Copyright (c) 1989 Gene W. Lee ;
- ;------------------------------------------------------;
- ;
- ACODE segment 'BGI'
- ;
- ;
- astart DB 'pk' ; BGI magic word (Phillipe K.)
- DB 8,8
- DB 'BGI Device Driver V1.0 Gene W. Lee - 1989 '
- db 0Dh,0Ah
- DB 'Copyright (c) 1989 Gene W. Lee',0Dh,0Ah
- db 0,1Ah
- dw 00A0h,11
- dw endofcode ; This is a label that precedes CODE ENDS
- dw 2
- db 1,1
- org 80h
- dw 00A0h,11
- dw endofcode ; see above
- dw 2
- db 1,1
-
- ; The following is returned by GetDriverName.
- db 6,'LEEVGA'
- alen = $-astart ; Pad this segment out to
- db (160 - alen) dup(0) ; 160 bytes
- ACODE ends
-
- CODE SEGMENT 'BGI'
- ;
- ; Now for the real BGI driver code. A separate segment is required
- ; because although this code starts at offset 0A0h in the file
- ; ATTDEB.BGI, GRAPH will adjust its address up by 10 paras and then
- ; do a CALL FAR xxxx:[0000]. So all memrefs have to be 0 relative to
- ; the label BGIENTRY below. IMPORTANT: All code from here to JMP_TABLE
- ; needs to be exactly as it is. GRAPH expects the label EMULATE to be
- ; at the offset that it is in this code (GRAPH is going to shove code
- ;
- ASSUME CS:CODE,DS:CODE,ES:CODE
- BGIENTRY PROC FAR ; "FAR" So that the RET is a RETF
- PUSH DS
- PUSH CS
- POP DS
- CLD
- PUSH BP
- ;
- ; The Function number to be performed in SI. SI is used to index into
- ; a jump table. Note: all SI values are even.
- ;
- CALL [SI+JMP_TABLE] ; See JMP_TABLE
- POP BP
- POP DS
- RET
- BGIENTRY ENDP
- ;
- db 'CB' ; ?
- dw 0
- ;
- EMULATE PROC NEAR ; This is the entry point of functions
- RET ; you want Turbo XX to emulate. Note:
- dw 0 ; only select entries may be emulated.
- dw 0
- EMULATE ENDP
-
- NOP_02 PROC NEAR ; This is the entry point for all functions
- RET ; which are not implemented.
- NOP_02 ENDP
-
- ; Now for the Jump Table; The SVC_xx labels correspond to the
- ; value in SI when the driver is called(ie: SVC_00 is the entry point
- ; when SI = 0. IF the labels are EMULATE or NOP_02 the value of SI is
- ; to the right in braces. NOP_02 means this function is a NOP and
- ; GRAPH should never call it (at least relative to TP5). The label
- ; EMULATE is a JMP to a CALL back to GRAPH to perform the function.
- ; (Aren't you glad you don't have to write a Circle Drawing Algorithm!)
- ;
- ; It should also be noted that calls to the BGI code are both pre-
- ; processed and post-processed by GRAPH. Some calls never make it to
- ; your code. One example is the DisplayText functions. The only time
- ; that calls make it here is for the bit-map text displays. GRAPH
- ; handles all of the stroked CHR fonts.
- ;
- jmp_table dw install ; {0} Initialize
- dw init ; {2} Set Mode
- dw clear ; {4} Clear Graphics Screen
- dw nop_02 ; {06} POST
- dw move ; {8} current pointer (CP)
- dw draw ; {A} draw line from CP to new CP
- dw vect ; {C} Draw Line
- dw EMULATE ; {0E} Draw/Fill Poly
- dw emulate ; {10} Bar3D
- dw patbar ; {12} pattern Bar
- dw EMULATE ; {14} Draw Circle
- dw EMULATE ; {16} Draw Pie Slice
- dw EMULATE ; {18} Draw Ellipse
- dw palette ; {1A} Set Palette
- dw SVC_1C ; {1C} Set All Palette
- dw color ; {1E} Set Color
- dw fillstyle ; {20} Set Fill Style/Pattern
- dw linestyle ; {22} Set Line Style/Pattern
- dw textstyle ; {24} Set UserCharSize
- dw text ; {26} Display Text
- dw textsize ; {28} Text Width/Height
- dw EMULATE ; {2A} ; I never figured this one out !
- dw flood_fill ; {2C} FloodFill
- dw get_pixel ; {2E} GetPixel
- dw put_pixel ; {30} SetPixel
- dw bitmaputil ; {32} Set CallTable
- dw get_image ; {34} GetImage
- dw put_image ; {36} PutImage
- dw set_clip ; {38} Set View Min/Max
- dw color_query ; {3A} SetParameters
- dw emulate ; {3C} reserved
- dw EMULATE ; {3E} symbol
-
- dw NOP_03 ; 40
- dw NOP_03 ; 42
- dw NOP_03 ; 44
- dw NOP_03 ; 46
- dw NOP_03 ; 48
- dw NOP_03 ; 4A
- dw NOP_03 ; 4C
- dw NOP_03 ; 4E
- dw NOP_03 ; 50
- dw NOP_03 ; 52
- dw NOP_03 ; 54
- dw NOP_03 ; 56
- dw NOP_03 ; 46
- dw NOP_03 ; 48
- dw NOP_03 ; 4A
- dw NOP_03 ; 4C
- dw NOP_03 ; 4E
- dw NOP_03 ; 50
- dw NOP_03 ; 52
- dw NOP_03 ; 54
- dw NOP_03 ; 56
- dw NOP_03 ; 46
- dw NOP_03 ; 48
- dw NOP_03 ; 4A
- dw NOP_03 ; 4C
- dw NOP_03 ; 4E
- dw NOP_03 ; 50
- dw NOP_03 ; 46
- dw NOP_03 ; 48
- dw NOP_03 ; 52
- dw NOP_03 ; 54
- dw NOP_03 ; 56
- ;
-
- NOP_03 PROC FAR ; stub procedure for far returns
- RET
- NOP_03 ENDP
-
-
- ;
-
- ; structure for 320x200 256 color mode
- statustype0 struc
- db 0 ; current device status
- db 0 ; device type identifier ( must be zero )
- dw 319 ; full resolution in the x direction
- dw 199 ; full resolution in the y direction
- xefres0 dw 319 ; effective resolution in x direction
- dw 199 ; effective resolution in y direction
- dw 9000 ; device x size in inches * 1000
- dw 7000 ; device y size in inches * 1000
- dw 8572 ; aspect ratio = ( ysize / xsize ) * 1000
- ; next four bytes are for compatibilty
- db 8h
- db 8h
- db 90h
- db 90h
- statustype0 ends
-
- status0 statustype0<>
-
- ; structure for 640x400 256 color mode (0x5E)
- statustype1 struc
- db 0 ; current device status
- db 0 ; device type identifier ( must be zero )
- dw 639 ; full resolution in the x direction
- dw 399 ; full resolution in the y direction
- xefres1 dw 639 ; effective resolution in x direction
- dw 399 ; effective resolution in y direction
- dw 9000 ; device x size in inches * 1000
- dw 7000 ; device y size in inches * 1000
- dw 8572 ; aspect ratio = ( ysize / xsize ) * 1000
- ; next four bytes are for compatibilty
- db 8h
- db 8h
- db 90h
- db 90h
- statustype1 ends
-
- status1 statustype1<>
-
- active_mode db ? ; the currently active mode number
-
- modestring0 db 18,'320 x 200 VGA Mode',0
- modestring1 db 18,'640 x 400 VGA Mode',0
-
- xsize dw ? ; the xsize of the currently selected mode
- max_x dw ? ; the maximum value of x for the current mode
-
-
-
- ; table for ellipse function calls
- ; Let it used my put_pixel routine, there is not much I could do to speed
- ; up pixel writing anyway.
- the_util_table dw offset NOP_03 ; enter pixel mode
- dw offset NOP_03 ; Leave pixel mode
- dw offset NOP_03 ; write a pixel
- dw offset NOP_03 ; get a pixel
- dw offset bitsperpixel ; return bits per pixel in AX
- dw offset NOP_03 ; set draw page
- dw offset NOP_03 ; set visual page
- dw offset NOP_03 ; set xor mode
-
- enter_pixel_mode proc far
- call unlock_vga
- mov doing_ellipse,1
- ret
- enter_pixel_mode endp
-
- exit_pixel_mode proc far
- call lock_vga
- mov doing_ellipse,0
- ret
- exit_pixel_mode endp
-
- bitsperpixel proc far
- mov ax,8 ; eight bits per pixel in VGA mode
- ret
- bitsperpixel endp
-
-
-
- ; the bit patterns for default linestyles
- default_linestyles dw 0FFFFh ; SOLID_LINE
- dw 0CCCCh ; DOTTED_LINE
- dw 0FC78h ; CENTER_LINE
- dw 0F8F8h ; DASHED_LINE
-
- active_linestyle dw 0FFFFh ; the currently selected line style is written
- ; into this word.
- line_bit_ptr db 0 ; pointer into linestyle word (bit ptr)
-
-
- default_fillpaterns db 000h,000h,000h,000h,000h,000h,000h,000h ; No Fill
- db 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh ; Solid fill
- db 0FFh,0FFh,000h,000h,0FFh,0FFh,000h,000h ; Line FIll
- db 001h,002h,004h,008h,010h,020h,040h,080h ; Lt Slash fil
- db 0E0h,0C1h,083h,007h,00Eh,01Ch,038h,070h ; Slash fill
- db 0F0h,078h,03Ch,01Eh,00Fh,087h,0C3h,0E1h ; Backslash
- db 0A5h,0D2h,069h,0B4h,05Ah,02Dh,096h,04Bh ; lt Backslash
- db 0FFh,088h,088h,088h,0FFh,088h,088h,088h ; Hatch Fill
- db 081h,042h,024h,018h,018h,024h,042h,081h ; XHatch Fill
- db 0CCh,033h,0CCh,033h,0CCh,033h,0CCh,033h ; interleave
- db 080h,000h,008h,000h,080h,000h,008h,000h ; Wide Dot
- db 088h,000h,022h,000h,088h,000h,022h,000h ; Close Dot
-
- active_fillpattern db ?,?,?,?,?,?,?,? ; the currently selected fill
- ; style is written into this array.
- fill_byte_ptr dw ? ; pointer to fill pattern byte
- fill_bit_ptr dw ? ; pointer to bit of fill pattern byte
-
-
-
-
- ; I don't really understand what this is all about. I just tell it I don't
- ; have a default color table
- color_table db 0
-
- current_background_color db ?
- current_line_color db ? ; the currently selected color for lines
- current_fill_color db ? ; the currently selected fill color
- cp_x dw ? ; the current pointer - x
- cp_y dw ? ; the current pointer - y
- clip_x1 dw ? ; clipping window
- clip_y1 dw ? ; clipping window
- clip_x2 dw ? ; clipping window
- clip_y2 dw ? ; clipping window
-
-
- ; start x,y and end x,y for line draws
- x1 dw ?
- y1 dw ?
- x2 dw ?
- y2 dw ?
-
- ; vars used by line draw routine
- delta_x dw ?
- delta_y dw ?
- count dw ?
- halfx label word ; only need halfx or halfy at one time
- halfy dw ?
-
- ; vars used to do pixel read/writes in VGA mode
- lasthio dw -1 ; keeps track of the last hioffset value calculated
- next_row dw ? ; variable used by patbar, getimage and putimage
-
- ; vars used by palette routines
- red db ?
- green db ?
- blue db ?
-
- doing_ellipse db 0 ; set true when unlock has been called to start
- ; drawing an ellipse. Saves time on ellipse draws
-
-
-
- ; 0 ----------------------------------------------------------------------
-
- ; if al=0 ( install device )
- ; input: cl = mode number for device
- ; ch = autodetect maximum device number
- ; return: es:bx = pointer to device status table
- ; if al=1 ( mode query )
- ; input: nothing
- ; return: cx = number of modes supported by this device
- ; if al=2 ( return mode name )
- ; input cx: the mode number for query
- ; return es:bx = pointer to PASCAL string containing the name
-
- install:
- cmp al,0
- jz installit
- cmp al,1
- jz modequery
-
- ; else it must be a modename() call
- push cs
- pop es
- cmp cx,0
- je modename0
- mov bx, offset modestring1 ; return pointer to mode name
- ret
-
- modename0:
- mov bx, offset modestring0 ; return pointer to mode name
- ret
-
- installit:
- mov active_mode,cl ; remember what mode were in
- cmp cl,1
- je install_mode1
- ; else we install mode 0
- ; keep track of current x and y screen size
- mov ax,status0.xefres0
- mov max_x,ax
- inc ax
- mov xsize,ax
-
- push cs
- pop es
- mov bx,offset status0 ; return location of status table
- ret
-
- install_mode1:
- mov ax,status1.xefres1 ; keep track of current x and y screen size
- mov max_x,ax
- inc ax
- mov xsize,ax
-
- push cs
- pop es
- mov bx,offset status1 ; return location of status table
- ret
-
- modequery:
- mov cx,2 ; only two modes supported for now
- ret
-
- ; 2 ----------------------------------------------------------------------
-
- ; input:
- ; es:bx = pointer to device table
- ; return: nothing
-
- init:
- cmp active_mode,1
- je init_mode1
- ; else we init mode 0
- mov ax,13h
- int 10h
-
- ret
-
-
- init_mode1:
- mov ax,5Eh
- int 10h
-
- ret
-
-
- ; 4 ----------------------------------------------------------------------
-
- ; input: nothing
- ; output: nothing
- ; clear the device
-
- clear:
- call init
- ret
-
-
- ; 8 ------------------------------------------------------------------------
-
- ; input:
- ; ax = the new CP x coord
- ; bx = the new CP y coord
- ; return: nothing
- move: ; set current pointer (CP)
-
- ; load the new current pointer
- mov cp_x,ax
- mov cp_y,bx
- ret
-
-
-
- ; A -----------------------------------------------------------------------
-
- ; draw line from CP to x,y
- ; input:
- ; ax: ending x coord
- ; bx: ending y coord
- ; output:
- ; nothing
-
- draw: ; draw line from CP to new CP
-
- push cx
- mov cx,cp_x ; draw starts at current position (cp)
- mov x1,cx
- mov cx,cp_y
- mov y1,cx
- pop cx
-
- mov x2,ax ; load the end points
- mov y2,bx
-
- mov cp_x,ax ; end points are now new current points
- mov cp_y,bx
-
- mov line_bit_ptr,0 ; reset the line style
-
- call draw_line ; draw the line from x1,y1 to x2,y2
-
- ret
-
-
- ; C ----------------------------------------------------------------------
-
- ; draw line from x1,y1 to x2,y2
-
- ; input:
- ; ax = x1
- ; bx = y1
- ; cx = x2
- ; dx = y1
- ; output:
- ; nothing
-
- vect: ; Draw Line
-
- ; setup the start and end points
- mov x1,ax
- mov y1,bx
- mov x2,cx
- mov y2,dx
-
- mov line_bit_ptr,0 ; reset the line style
-
- call draw_line ; draw a line
-
- ret
-
-
-
-
-
- ; 1A --------------------------------------------------------------------
-
- ; set a single palette entry
- ; input:
- ; ax = the index number to load
- ; bx = the color value
- ; return: nothing
-
- palette:
-
- push ax
- push cx
-
- mov cl,14
- shr ax,cl ; only want upper to bits of cl
-
- cmp ax,010b ; set rgb palette
-
- pop cx
- pop ax
-
- jne p_done ; the other values are meaningless in vga mode
-
- mov red,bl
- mov green,cl
- mov blue,dl
- ; get rid of upper two control bits, leave index
- and ax,03FFFh
-
-
- mov dh,red
- mov ch,green
- mov cl,blue
- mov bx,ax
-
- mov ax,01010h ; set single palette entry
-
- int 10h
-
-
- p_done:
- ret
-
-
-
- ; 1C ---------------------------------------------------------------------
-
- ; Set all Palette entries with one call
- SVC_1C: ; Set All Palette
- ; not compatible with 256 color VGA modes, you have to provide
- ; the user with a library function to do this.
- ret
-
-
- ; 1E -------------------------------------------------------------------
-
- ; input:
- ; al = index number of current drawing color
- ; ah = index number of current fill color
- ; return: nothing
-
- color: ; Set Color
-
- mov current_line_color,al
- mov current_fill_color,ah
-
- ret
-
-
- ; 20 ------------------------------------------------------------------
-
- ; input:
- ; al = fill pattern number
- ; es:bx = if pattern number = 0FFh, this points to user fill pattern
- ; return: nothing
-
- fillstyle: ; Set Fill Style/Pattern
-
-
- cmp al,0FFh ; test if user defined fill
- jz user_fill
-
- cbw
- mov cl,3 ; multiply by 8 for eight bytes per fill type
- shl ax,cl
- mov si,ax
- add si,offset default_fillpaterns ; point to the selected fill patern
- jmp cont_fill ; ds:si point to selected fill pattern
-
- user_fill: ; user defined fill passed by pointer ES:BX
- push bx
- pop si
- push es
- pop ds ; setup so ds:si points to users fill pattern
-
- cont_fill:
-
- mov di,offset active_fillpattern
- push cs
- pop es ; es:cs is the destination of the copy
-
- mov cx,8 ; setup to copy eight bytes of pattern
- repz movsb ; copy pattern into active pattern
-
- ret
-
-
- ; 22 ------------------------------------------------------------------
-
- ; input:
- ; al = line pattern number
- ; bx = user defined line pattern if al = 4
- ; cx = line width
- ; return: nothing
-
- linestyle: ; set current line style
-
- cmp ax,4
- jz user_defined ; check if its a user defined line
-
- and ax,0FFh ; pattern number in AL
- shl al,1 ; used two index by 2 bytes at a time
- mov si,ax
- mov bx,[default_linestyles +si] ; load a pre-defined pattern
-
- user_defined: ; user defined are passed in BX
- mov active_linestyle,bx
-
- ret
-
-
-
- ; 24 -------------------------------------------------------------------
-
- ; input:
- ; al = hardware font number
- ; ah = hardware font orientation
- ; bx = desired X size
- ; cx = desired Y size
- ; return:
- ; bx = closest X size available
- ; cx = closest Y size available
-
- textstyle: ; Set UserCharSize
- ; this code works but thats about all
- mov bx,bx ; let say the characters are 8 x 16
- mov cx,cx
- ret
-
-
-
- ; 26 --------------------------------------------------------------------
-
- ; input:
- ; es:bx = pointer to ascii string to display
- ; cx = number of chars in string
- ; al = horizontal justification ( 0=left,1=center,2=right )
- ; ah = vertical justification (0=bottom,1=center,2=top)
- ; return:
- ; bx = width of string in graphics units
- ; cx = height of string in graphics units
-
- text: ; Display Text ( DEFAULT FONT )
-
- ; this is one of the things I could not figure out
- ; if you come up with something please let me know.
- push bx
- push cx
- ; hack here
-
-
- ; end hack
- pop cx
- pop bx
- mov bx,bx ; NOTE this should be 8 * length of string (cx)
- mov cx,cx
- ret
-
-
- ; 28 --------------------------------------------------------------------
-
- ; input:
- ; es:bx = pointer to ascii text
- ; cx = number of chars in test
- ; return:
- ; bx = width of string in graphics units
- ; cx = height of string in graphics units
-
- textsize: ; Text Width/Height ( DEFAULT FONT )
-
- ; again I did not know how to do this
- mov bx,bx ; NOTE this is not right
- mov cx,cx
- ret
-
-
- ; 2C --------------------------------------------------------------------
-
- ; input:
- ; ax = x coord to start at
- ; bx = y coord to start at
- ; cl = boundry color
- ; return: nothing
-
- flood_fill: ; FloodFill
- ; flood fill needs implemented also
- ret
-
-
- ; 2E -----------------------------------------------------------------
-
- ; input:
- ; ax = x coord
- ; bx = y coord
- ; return:
- ; dl = color
-
- get_pixel: ; GetPixel
-
- ; if you don't mind being slow, just use the bios calls
- ; mov cx,ax ; load x value
- ; mov dx,bx ; load y value
- ; mov bh,0 ; page zero
- ; mov ah,0Dh ; read pixel function
- ;
- ; int 10h
- ;
- ; mov dl,al ; return the color of pixel read
- ; ret
-
-
- cmp active_mode,1
- je getpixel_mode1
-
- ; else read pixels in mode 0
- push di ; save these registers
- push es
-
- mov cx,ax ; save the column value (x)
-
-
- mov ax,bx ; load the row value (y)
- mul xsize ; offset =(xsize * y)
- add ax,cx ; + x
- mov di,ax ; load screen address into di
-
- mov ax,0A000h ; video ram segement address
- mov es,ax
- mov dl,es:[di] ; read the pixel
-
-
- pop es
- pop di
-
- ret
-
-
-
- getpixel_mode1: ; read pixel this way when in mode 1
- push di ; save these registers
- push es
-
- mov cx,ax ; save the column value (x)
-
- mov ax,bx ; load the row value (y)
-
- call calc_hilow ; find vga offset values into screen memory
-
- cmp bx,lasthio ; see of hioffset is the same as last time
- je no_hio_chg_r ; if it is, save time by not resetting it
-
- cmp doing_ellipse,1
- je no_unlock_get ; its already unlocked
- call unlock_vga
- no_unlock_get:
-
- mov ax,bx ;
- call set_hioffset ; sets the hioffset register for vga mem addressing
-
- cmp doing_ellipse,1
- je no_lock_get
- call lock_vga
- no_lock_get:
-
- no_hio_chg_r:
- mov ax,0A000h ; video ram segement address
- mov es,ax
- mov dl,es:[di] ; read the pixel
-
-
- pop es
- pop di
-
- ret
-
-
-
- ; 30 -----------------------------------------------------------------
-
- ; input:
- ; ax = x coord
- ; bx = y coord
- ; dl = color
- ; return: nothing
-
-
- put_pixel: ; SetPixel
-
- ; p[XSIZE*y+x] = color; for 320 x 200 - 256 mode
-
- ; if you don't mind being slow, just call the bios plot dot
- ; push dx ; save color value
- ; mov cx,ax ; load x value
- ; mov dx,bx ; load y value
- ; pop ax ; color value from pushed dx
- ; mov bh,0 ; page zero
- ; mov ah,0Ch ; write pixel function
- ;
- ; int 10h
- ; ret
-
- ; else get fancy to make it faster.
-
- cmp active_mode,1
- je putpixel_mode1
-
- ; else plot pixels in mode 0
- push di ; save these registers
- push es
- push ax
- push bx
- push cx
- push dx
-
- push dx ; save the color
- mov cx,ax ; save the column value (x)
-
- mov ax,bx ; load the row value (y)
- mul xsize ; offset =(xsize * y)
- add ax,cx ; + x
- mov di,ax ; load screen address into di
-
- mov ax,0A000h ; video ram segement address
- mov es,ax
-
- pop dx ; get the color info back
-
- mov es:[di],dl ; plot the pixel
-
- pop dx
- pop cx
- pop bx
- pop ax
- pop es
- pop di
-
- ret
-
-
-
-
- putpixel_mode1: ; routine to plot pixels when in mode 1
- push di ; save these registers
- push es
- push ax
- push bx
- push cx
- push dx
-
- push dx ; save the color
- mov cx,ax ; save the column value (x)
-
- mov ax,bx ; load the row value (y)
-
- call calc_hilow ; find vga hi and low offset value for screen mem
-
- cmp bx,lasthio ; see of hioffset is the same as last time
- je no_hio_chg_w ; if it is, save time by not resetting it
-
- cmp doing_ellipse,1
- je no_unlock_put ; its already done
- call unlock_vga
- no_unlock_put:
-
- mov ax,bx ;
- call set_hioffset ; sets the hioffset register for vga mem addressing
-
- cmp doing_ellipse,1
- je no_lock_put
- call lock_vga
- no_lock_put:
-
- no_hio_chg_w:
- mov ax,0A000h ; video ram segement address
- mov es,ax
-
- pop dx ; get the color info back
-
- mov es:[di],dl ; plot the pixel
-
- pop dx
- pop cx
- pop bx
- pop ax
- pop es
- pop di
-
- ret
-
-
-
-
- ; 32 -------------------------------------------------------------------
-
- bitmaputil: ; Set CallTable
-
- ; see the book, basically don't worry (be happy)
-
- push cs
- pop es
- mov bx, offset the_util_table
- ret
-
- ; 34 -------------------------------------------------------------------
-
- ; input:
- ; ax = x1 corner
- ; bx = y1 corner
- ; cx = x2 corner
- ; dx = y2 corner
- ; return: nothing
-
- patbar: ; fill the rectangle using current fillstyle and color
-
- ; this version of pattern filling uses the following trick to greatly
- ; improve speed. Instead of calling put_pixel for every pixel to plot
- ; it does the write to screen memory on its own. What makes it fast is
- ; that it only has to find the original offset by multipling XSIZE by
- ; y1. From then on it increments a pointer to find the next location
- ; in screen memory (not multiplies required after initial one).
-
- ; first, make sure x1 < x2 and y1 < y2
- cmp ax,cx ; if x1 < x2
- jle x_ok
- xchg ax,cx
- x_ok:
-
- cmp bx,dx ; if y1 < y2
- jle y_ok
- xchg bx,dx
- y_ok:
-
- ; then load the start and end values
- mov x1,ax
- mov x2,cx
- mov y1,bx
- mov y2,dx
-
-
- cmp active_mode,1
- je patbar_mode1 ; different way to calc pixel offset
-
- ; Next, setup the starting value of the VGA's hioffset reg
- push ax
- push bx
- push cx
-
- mov cx,ax ; load x value
- mov ax,bx ; load the y value
- mul xsize ; find the pixel offset
- add ax,cx ; add inthe x value
- mov di,ax
-
- mov ax,0a000h ; screen memory segment
- mov es,ax
-
- ; calculate ho many screen byte are from right edge of box
- ; to left edge of box on next row
- mov ax,max_x
- sub ax,x2
- add ax,x1
- mov next_row,ax
-
- pop cx
- pop bx
- pop ax
-
- again0:
-
- ; First, lets figure out the fill pattern parameters
-
-
- push ax
- push cx
- push si
-
-
-
- ; the bit/byte pointer are relative to the absolute
- ; screen position mod 8
- mov fill_byte_ptr,bx ; load the current y value
- mov fill_bit_ptr,ax ; load the current x value
- and fill_byte_ptr,07h
- and fill_bit_ptr,07h
-
-
- mov si,fill_byte_ptr;
- mov al,[offset active_fillpattern + si]
- mov cx,fill_bit_ptr
- shl al,cl
- and al,80h
- cmp al,80h
-
-
- jne use_background0 ; if not plotting this dot
- mov dl,current_fill_color ; else load fill color
- jmp selected0
-
- use_background0:
- mov dl,current_background_color ; assume background
-
- selected0:
-
- pop si
- pop cx
- pop ax
-
-
-
-
- ; this is the slow way, it has to recalute the offset into
- ; display memory every time it puts a pixel
-
- ; push ax
- ; push bx
- ; call put_pixel
- ; pop bx
- ; pop ax
-
- mov es:[di],dl
-
-
- inc di ; advvance screen mapped memory pointer
- inc ax ; advance in x dir till at right edge
- cmp ax,x2
- jle again0
-
- mov ax,x1 ; reset to left size of rectangle
- inc bx ; go to down to next row
- cmp bx,y2
- jg fill_done0
-
-
- ; Since were changing rows we'll find a new hi and low
- ; the trick is to add the number of bytes from the right side of the
- ; box to the left side of the box ( note: no multiplies needed )
-
- add di,next_row
-
- jmp again0
-
-
-
- fill_done0:
- ret ; end of patbar in mode 0
-
-
-
-
- patbar_mode1:
- ; first, make sure x1 < x2 and y1 < y2
-
- call unlock_vga ; keep vga ready to plot pixels
-
-
- ; Next, setup the starting value of the VGA's hioffset reg
- push ax
- push bx
- push cx
-
- mov cx,ax ; load x value
- mov ax,bx ; load the y value
- call calc_hilow ; find the values of hio and lowo
- mov ax,bx ; load hio
- call set_hioffset ; set the vga register for the hioffset
-
- mov ax,0a000h ; screen memory segment
- mov es,ax
-
- ; calculate ho many screen byte are from right edge of box
- ; to left edge of box on next row
- mov ax,max_x
- sub ax,x2
- add ax,x1
- mov next_row,ax
-
- pop cx
- pop bx
- pop ax
-
- again1:
-
- ; First, lets figure out the fill pattern parameters
-
-
- push ax
- push cx
- push si
-
-
-
- ; the bit/byte pointer are relative to the absolute
- ; screen position mod 8
- mov fill_byte_ptr,bx ; load the current y value
- mov fill_bit_ptr,ax ; load the current x value
- and fill_byte_ptr,07h
- and fill_bit_ptr,07h
-
-
- mov si,fill_byte_ptr;
- mov al,[offset active_fillpattern + si]
- mov cx,fill_bit_ptr
- shl al,cl
- and al,80h
- cmp al,80h
-
-
- jne use_background1 ; if not plotting this dot
- mov dl,current_fill_color ; else load fill color
- jmp selected1
-
- use_background1:
- mov dl,current_background_color ; assume background
-
- selected1:
-
-
- pop si
- pop cx
- pop ax
-
-
-
-
- ; this is the slow way, it has to recalute the offset into
- ; display memory every time it puts a pixel
- ; but it shows the easy way to do it.
-
- ; push ax
- ; push bx
- ; call put_pixel
- ; pop bx
- ; pop ax
-
- mov es:[di],dl
-
-
- inc di
- cmp di,0FFFh
- jle leave_hio1
- sub di,1000h
- inc lasthio
-
- push ax ; let vga card know we incremented hi offset
- mov ax,lasthio
- call set_hioffset
- pop ax
-
- leave_hio1:
- inc ax ; advance in x dir till at right edge
- cmp ax,x2
- jle again1
-
- mov ax,x1 ; reset to left size of rectangle
- inc bx ; go to down to next row
- cmp bx,y2
- jg fill_done1
-
-
- ;Since were changing rows we'll find a new hi and low
- ; the trick is to add the number of bytes from the right side of the
- ; box to the left side of the box ( note: no multiplies needed )
-
- add di,next_row
- cmp di,0FFFh
- jle no_bump1
- sub di,1000h
- inc lasthio
- push ax
- mov ax,lasthio
- call set_hioffset
- pop ax
- no_bump1:
-
-
- jmp again1
-
-
-
- fill_done1:
- call lock_vga ; protect the vgas register again
-
- ret
-
-
-
- ; 36 ------------------------------------------------------------------
-
- buf_ptr dw ? ; pointer to the buffer for getimage/putimage
- put_mode db ? ; pixel writing mode for putting images (and,xor,etc)
-
- ; NOTE: the book has mistakes in input/output parameters
- ; input:
- ; es:bx = pointer to memory buffer
- ; buffer[0] = window width in x direction
- ; buffer[2] = window height in y direction
- ; cx = x1 corner of window
- ; dx = y1 corner of window
- ; return: nothing
-
- get_image: ; GetImage
-
-
- ; this version of pattern filling uses the following trick to greatly
- ; improve speed. Instead of calling put_pixel for every pixel to plot
- ; it does the write to screen memory on its own. What makes it fast is
- ; that it only has to find the original offset by multipling XSIZE by
- ; y1. From then on it increments a pointer to find the next location
- ; in screen memory.
-
-
- mov buf_ptr,bx ; pointer to the buffer where we'll store image
-
- mov ax,es:[bx]
- add ax,cx ; add x1 plus xsize of image window
-
- mov bx,es:[bx +2]
- add bx,dx ; add y1 plus ysize of image window
-
-
- mov x1,cx
- mov y1,dx
- mov x2,ax
- mov y2,bx
-
- mov bx,buf_ptr
- add bx,4 ; first word was used for xsize dimension
- mov buf_ptr,bx
-
- mov ax,x1
- mov bx,y1
-
-
-
- cmp active_mode,1
- je getimage_mode1 ; different way to calc pixel offset
-
- ; Next, setup the starting value of the VGA's hioffset reg
- push ax
- push bx
- push cx
-
- mov cx,ax ; load x value
- mov ax,bx ; load the y value
- mul xsize ; find the pixel offset
- add ax,cx ; add inthe x value
- mov di,ax
-
-
- ; calculate ho many screen byte are from right edge of box
- ; to left edge of box on next row
- mov ax,max_x
- sub ax,x2
- add ax,x1
- mov next_row,ax
-
- pop cx
- pop bx
- pop ax
-
- g_again0:
- ; move a byte from the screen to the image buffer
- push ax
- push es
- mov ax,0A000h
- mov es,ax
- mov al,byte ptr es:[di]
- pop es
- push bx
- mov bx,buf_ptr
- mov byte ptr es:[bx],al
- pop bx
- pop ax
- inc buf_ptr ; point to next byte in the users buffer
-
-
- inc di ; advvance screen mapped memory pointer
- inc ax ; advance in x dir till at right edge
- cmp ax,x2
- jle g_again0
-
- mov ax,x1 ; reset to left size of rectangle
- inc bx ; go to down to next row
- cmp bx,y2
- jg geti_done0
-
-
- ;Since were changing rows we'll find a new hi and low
- ;the trick is to add the number of bytes from the right side of the
- ; box to the left side of the box ( note: no multiplies needed )
-
- add di,next_row
-
- jmp g_again0
-
-
-
- geti_done0:
- ret ; end of patbar in mode 0
-
-
-
-
- getimage_mode1:
- ; first, make sure x1 < x2 and y1 < y2
-
- call unlock_vga ; keep vga ready to plot pixels
-
-
- ; Next, setup the starting value of the VGA's hioffset reg
- push ax
- push bx
- push cx
-
- mov cx,ax ; load x value
- mov ax,bx ; load the y value
- call calc_hilow ; find the values of hio and lowo
- mov ax,bx ; load hio
- call set_hioffset ; set the vga register for the hioffset
-
- ; calculate ho many screen byte are from right edge of box
- ; to left edge of box on next row
- mov ax,max_x
- sub ax,x2
- add ax,x1
- mov next_row,ax
-
- pop cx
- pop bx
- pop ax
-
- g_again1:
-
- ; move a byte from the screen to the image buffer
- push ax
- push es
- mov ax,0A000h
- mov es,ax
- mov al,byte ptr es:[di]
- pop es
- push bx
- mov bx,buf_ptr
- mov byte ptr es:[bx],al
- pop bx
- pop ax
- inc buf_ptr ; point to next byte in the users buffer
-
-
- inc di
- cmp di,0FFFh
- jle g_leave_hio1
- sub di,1000h
- inc lasthio
-
- push ax ; let vga card know we incremented hi offset
- mov ax,lasthio
- call set_hioffset
- pop ax
-
- g_leave_hio1:
- inc ax ; advance in x dir till at right edge
- cmp ax,x2
- jle g_again1
-
- mov ax,x1 ; reset to left size of rectangle
- inc bx ; go to down to next row
- cmp bx,y2
- jg geti_done1
-
-
- ;Since were changing rows we'll find a new hi and low
- ;the trick is to add the number of bytes from the right side of the
- ; box to the left side of the box ( note: no multiplies needed )
-
- add di,next_row
- cmp di,0FFFh
- jle g_no_bump1
- sub di,1000h
- inc lasthio
- push ax
- mov ax,lasthio
- call set_hioffset
- pop ax
- g_no_bump1:
-
- jmp g_again1
-
- geti_done1:
- call lock_vga ; protect the vgas register again
-
- ret
-
- ; 38 -------------------------------------------------------------------------
-
- ; NOTE: the book has mistakes in input/output parameters
- ; input:
- ; es:bx = pointer to memory buffer
- ; buffer[0] = window width in x direction
- ; buffer[2] = window height in y direction
- ; cx = x1 corner of window
- ; dx = y1 corner of window
- ; return: nothing
-
-
- put_image: ; putImage
-
- ; this version of pattern filling uses the following trick to greatly
- ; improve speed. Instead of calling put_pixel for every pixel to plot
- ; it does the write to screen memory on its own. What makes it fast is
- ; that it only has to find the original offset by multipling XSIZE by
- ; y1. From then on it increments a pointer to find the next location
- ; in screen memory.
-
- mov put_mode,al ; save the put image pixel writing mode
- mov buf_ptr,bx ; pointer to the buffer where we'll store image
-
- mov ax,es:[bx]
- add ax,cx ; add x1 plut xsize of image window
-
- mov bx,es:[bx +2]
- ; mov bx,di
- add bx,dx ; add y1 plus ysize of image window
-
-
- mov x1,cx
- mov y1,dx
- mov x2,ax
- mov y2,bx
-
- mov bx,buf_ptr
- add bx,4 ; first word was used for xsize dimension
- mov buf_ptr,bx
-
- mov ax,x1
- mov bx,y1
-
-
- cmp active_mode,1
- je putimage_mode1 ; different way to calc pixel offset
-
- ; Next, setup the starting value of the VGA's hioffset reg
- push ax
- push bx
- push cx
-
- mov cx,ax ; load x value
- mov ax,bx ; load the y value
- mul xsize ; find the pixel offset
- add ax,cx ; add inthe x value
- mov di,ax
-
-
- ; calculate ho many screen byte are from right edge of box
- ; to left edge of box on next row
- mov ax,max_x
- sub ax,x2
- add ax,x1
- mov next_row,ax
-
- pop cx
- pop bx
- pop ax
-
-
- mov cl,put_mode ; keep the put_mode in cl for access speed
- p_again0:
- call buf_to_screen
-
- inc di ; advvance screen mapped memory pointer
- inc ax ; advance in x dir till at right edge
- cmp ax,x2
- jle p_again0
-
- mov ax,x1 ; reset to left size of rectangle
- inc bx ; go to down to next row
- cmp bx,y2
- jg puti_done0
-
-
- ;Since were changing rows we'll find a new hi and low
- ; the trick is to add the number of bytes from the right side of the
- ; box to the left side of the box ( note: no multiplies needed )
-
- add di,next_row
-
- jmp p_again0
-
-
-
- puti_done0:
- ret ; end of patbar in mode 0
-
-
- ; ----------------- putimage for mode 1 ------------------
-
- putimage_mode1:
- ; first, make sure x1 < x2 and y1 < y2
-
- call unlock_vga ; keep vga ready to plot pixels
-
-
- ; Next, setup the starting value of the VGA's hioffset reg
- push ax
- push bx
- push cx
-
- mov cx,ax ; load x value
- mov ax,bx ; load the y value
- call calc_hilow ; find the values of hio and lowo
- mov ax,bx ; load hio
- call set_hioffset ; set the vga register for the hioffset
-
-
- ; calculate ho many screen byte are from right edge of box
- ; to left edge of box on next row
- mov ax,max_x
- sub ax,x2
- add ax,x1
- mov next_row,ax
-
- pop cx
- pop bx
- pop ax
-
- mov cl,put_mode ; keep the put_mode in cl for access speed
- p_again1:
- call buf_to_screen
-
- inc di
- cmp di,0FFFh
- jle p_leave_hio1
- sub di,1000h
- inc lasthio
-
- push ax ; let vga card know we incremented hi offset
- mov ax,lasthio
- call set_hioffset
- pop ax
-
- p_leave_hio1:
- inc ax ; advance in x dir till at right edge
- cmp ax,x2
- jle p_again1
-
- mov ax,x1 ; reset to left size of rectangle
- inc bx ; go to down to next row
- cmp bx,y2
- jg puti_done1
-
-
- ;Since were changing rows we'll find a new hi and low
- ; the trick is to add the number of bytes from the right side of the
- ; box to the left side of the box ( note: no multiplies needed )
-
- add di,next_row
- cmp di,0FFFh
- jle p_no_bump1
- sub di,1000h
- inc lasthio
- push ax
- mov ax,lasthio
- call set_hioffset
- pop ax
- p_no_bump1:
-
- jmp p_again1
-
- puti_done1:
- call lock_vga ; protect the vgas register again
-
- ret
-
-
- ; ----------------------------------------------
- ; this code write the next byte from the put image buffer
- ; to the display screen
-
- buf_to_screen proc near
- ; move a byte from the image buffer to the screen
- push ax
- push bx
-
- ; get the byte out of the users buffer
- mov bx,buf_ptr
- mov al,byte ptr es:[bx]
-
- pop bx
- push es
- push ax
-
- mov ax,0A000h
- mov es,ax ; es reg is pointer to VGA screen
-
- pop ax
-
- ; write the byte to screen mem according to users mode
- ; mov cl,put_mode
- cmp cl,0
- jne try_xor0
- mov byte ptr es:[di],al
- jmp mode_found0
- try_xor0:
- cmp cl,1
- jne try_or0
- xor byte ptr es:[di],al
- jmp mode_found0
- try_or0:
- cmp cl,2
- jne try_and0
- or byte ptr es:[di],al
- jmp mode_found0
- try_and0:
- cmp cl,3
- jne then_comp0
- and byte ptr es:[di],al
- jmp mode_found0
- then_comp0:
- xor al,0FFh ; complement the byte
- and byte ptr es:[di],al
- mode_found0:
-
- pop es
- pop ax
-
- inc buf_ptr ; point to next byte in the users buffer
-
- ret
-
- buf_to_screen endp
-
-
- ; 40 -------------------------------------------------------------------
-
- ; input:
- ; ax = x1
- ; bx = y1
- ; cx = x2
- ; dx = y2
- ; return: nothing
-
- set_clip: ; Set clipping
- ; load the limits of the clipping window
- mov clip_x1,ax
- mov clip_y1,bx
- mov clip_x2,cx
- mov clip_y2,dx
-
- ret
-
-
-
- ; 3A -------------------------------------------------------------------
-
- ; if al = 0
- ; input: nothing
- ; return:
- ; bx = size of color table
- ; cx = maximum color number
- ; if al = 1
- ; input: nothing
- ; return:
- ; es:bx = pointer to default color table (first byte is size)
-
- color_query: ; SetParameters
-
- cmp al,0
- jnz color_table_q
-
- mov bx,256
- mov cx,255
- ret
-
- color_table_q:
- push cs
- pop es
- mov bx,offset color_table
- ret
-
-
-
-
- ; =========================================================================
-
- ; line drawing routine from Assembly language
- ; primer - The Waite Group - page 339-340
-
- draw_line proc near
- mov ax,y2
- sub ax,y1
-
- mov si,1
- jge store_y
- mov si,-1
- neg ax
-
- store_y:
- mov delta_y,ax
-
- mov ax,x2
- sub ax,x1
-
- mov di,1
- jge store_x
- mov di,-1
- neg ax
-
- store_x:
- mov delta_x,ax
-
- mov ax,delta_x
- cmp ax,delta_y
- jl csteep
- call easy
- jmp finish_line
-
- csteep:
- call steep
-
- finish_line:
- ret
-
- draw_line endp
-
-
- ; ---------------------------------
-
- easy proc near
-
- mov ax,delta_x
- shr ax,1
- mov halfx,ax
-
- mov cx,x1
- mov dx,y1
- mov bx,0
- mov ax,delta_x
- mov count,ax
-
- newdot:
- call dotplot
- add cx,di
- add bx,delta_y
- cmp bx,halfx
- jle dcount
- sub bx,delta_x
-
- add dx,si
-
- dcount:
- dec count
- jge newdot
-
- ret
-
- easy endp
-
-
- ; --------------------------------
-
-
- steep proc near
-
- mov ax,delta_y
- shr ax,1
- mov halfy,ax
-
- mov cx,x1
- mov dx,y1
-
- mov bx,0
- mov ax,delta_y
- mov count,ax
-
- newdot2:
- call dotplot
- add dx,si
- add bx,delta_x
- cmp bx,halfy
- jle dcount2
- sub bx,delta_y
-
- add cx,di
-
- dcount2:
- dec count
- jge newdot2
-
- ret
-
- steep endp
-
-
- ; ------------------------------
-
-
- dotplot proc near
-
- push ax ; save old values
- push bx
- push cx
- push dx
-
- ; check to see if line style pattern dictates a plot or not
- ; if active_bit_pattern[line_bit_ptr] = 0 then dont plot a dot
-
- push ax
- push cx
-
- mov ax,active_linestyle
- mov cl,line_bit_ptr
- shl ax,cl
- and ax,8000h
- cmp ax,8000h
-
- pop cx
- pop ax
-
- mov ax,cx
- mov bx,dx
-
- jne no_dot_plot
-
- mov dl,current_line_color ; do plot dot, so load line color
-
- call put_pixel ; call the pixel writing routine
- no_dot_plot:
-
-
- inc line_bit_ptr ; move to next bit in pattern
- cmp line_bit_ptr,16 ; are we at the end of the pattern
- jne no_reset_linestyle ; if not do nothing
- mov line_bit_ptr,0 ; else start over at the pattern beginning
- no_reset_linestyle:
-
- pop dx ; save old values
- pop cx
- pop bx
- pop ax
-
-
-
- ret
-
- dotplot endp
-
-
- ; --------------------------------------------------------------------------
-
- calc_hilow: ; find hi and low vga offsets for x,y location
- ; cx is column (x) , ax is row (y)
- ; uses value in varible 'xsize'
- ; results are lowoffset in di and hioffset in bx
-
- push dx
-
- mul xsize ; offset =(xsize * y)
- add ax,cx ; + x
- jnc nocarry_o
- inc dx ; (DxAx + Cx)
- nocarry_o:
-
- mov di,ax
- and di,0FFFh ; low offset is lowest 12 bits of offset
-
- mov cl,12 ; (hioffset = offset >> 12
- shr ax,cl
- mov cl,4
- shl dx,cl
- or dx,ax
- mov bx,dx ; hioffset saved in bx
-
- pop dx
-
- ret
-
-
- ; ---------------------------------------------------------------------------
-
- unlock_vga: ; unlock vga registers
-
- push ax
- push dx
-
- mov dx,03CEh ; vga I/O port
- mov ax,050Fh
- out dx,ax ; unlock vga registers
-
- pop dx
- pop ax
-
- ret
-
-
- ; ---------------------------------------------------------------------------
-
- lock_vga: ; lock vga registers
-
- push ax
- push dx
-
- mov dx,03CEh ; vga I/O port
- mov ax,000Fh
- out dx,ax ; unlock vga registers
-
- pop dx
- pop ax
-
- ret
-
-
- ; ---------------------------------------------------------------------------
-
- set_hioffset: ; sets the vga hi offset register
- ; ax contains the value for HIoffset
-
- push dx
-
- mov lasthio,ax
-
- mov ah,al ; hioffset goes in ah
- mov al,9 ; function code to set PR0A register
-
- mov dx,03CEh ; vga I/O address
- out dx,ax ; set the hioffset value
-
- pop dx
-
- ret
-
-
-
- ; ---------------------------------------------------------------------------
-
- ; .
- endofcode label byte ; This is the label ref'd in ACODE segment
- CODE ENDS
- END
- --
- Gene Lee UUCP: ...!amdahl!ems!minnow!lee
- Unisys Corporation
- Phone: +1 612 635 3993 CSNET: lee@minnow.SP.Unisys.Com
- If not for the courage of the fearless manager, the paycheck would be lost.
-
-
-