home *** CD-ROM | disk | FTP | other *** search
- ; vga_font: Some primitives for working with text mode evga fonts.
- ;
- ; To use this system with the higher-level unit, V_FONT_U, first call
- ; FontInit, then use the graphic primitives in the standard fashion.
- ; I.e., Line(0,0,639,399) to draw a diagonal line. The ClearChars
- ; procedure is used to de-allocate all of the characters that have
- ; been used to draw any graphic image on the screen, and clear the
- ; screen to the way it was when you used FontInit.
- ;
- ; Memory required: The main program must declare two areas of memory:
- ; One to be used to store the contents of the current screen (4096 bytes),
- ; and another to store the 384-element character set (6144 bytes).
- ; Procedure headers are clearly marked as to which buffers should
- ; be used with which procedure.
- ;
- ; Specifications:
- ; - Programmed for 80x25 color EGA or VGA text modes only.
- ; - Works with resolutions of 640x200, 640x350, and 640x400
- ; - Redefines up to 384 characters, starting with character number 511
- ; and working down to character number 128. Extended characters are
- ; used which means that only 8 colors can be controlled directly.
- ; - Two major primitives supported are Line and Ellipse, as well as
- ; many other less-significant ones.
-
-
- data segment public
- ; Line variables:
- delta_x dw ?
- delta_y dw ?
- halfy label word
- halfx dw ?
- count dw ?
- ; Temporary variables:
- Temp dw ?
- Temp2 dw ?
- ; Internal control variables:
- extrn SizeFor128Chars:word
-
- ; Global variables:
- extrn Buffer: dword ; Font buffer
- extrn TotalUsed: word ; Total # of allocated chars
- extrn CharsUsed: byte ; Array of 384 character flags
- extrn MaxX: word ; Maximum X coordinate
- extrn MaxY: word ; Maximum Y coordinate
- extrn Points: byte ; # of bytes per character
-
- ; Ellipse variables:
- even
- t_e_lo dw ?
- t_e_hi dw ?
- r1_lo dw ?
- r1_hi dw ?
- r2_lo dw ?
- r2_hi dw ?
- y_p_lo dw ?
- y_p_hi dw ?
- max_x dw ?
- c_x dw ?
- c_y dw ?
- xe dw ?
- ye dw ?
- portion db ?
- Old_BP dw ?
-
- data ends
-
- Code segment public
- assume cs:code,ds:data
-
- public Line
- public Freeze
- public Unfreeze
- public Ellipse
- public Hlin
- public Vlin
- public Box
- public OpenBox
- public MaskColors
- public Pset
- public Make512chars
- public GetScrn
- public PutScrn
- public WriteFont
- public FontInit
- public ClearChars
- public Make8bitChars
- public Make9bitChars
-
- Make8bitChars proc far
- ; Calling sequence: Make8bitChars(Lines: integer);
- ; This procedure sets the BIOS video mode so that the character generator
- ; displays only 8 pixels per character. Two modes support this: a 350
- ; line mode, and a 200 line mode.
- ; Note: Lines can be 350 or 200.
- Lines equ word ptr [bp+6]
-
- push bp
- mov bp,sp
- mov ah,12h
- mov bl,30h
- cmp Lines,200
- jz Set200lines
- mov al,1 ; 350 scan lines
- int 10h
- mov MaxY,349
- mov Points,14
- mov SizeFor128chars,128*14
- jmp short ExitM8
- Set200lines: mov al,0
- int 10h
- mov MaxY,199
- mov Points,8
- mov SizeFor128chars,128*8
- ExitM8: pop bp
- ret 2
- Make8bitChars endp
-
- Make9bitChars proc far
- ; 400-line mode.
- ; Configures the BIOS to program the character generator to display 9
- ; pixels for every 8-bit character. Doing this adds a blank vertical line
- ; to the right of every displayed character, except for the ones designated
- ; as border characters which have their rightmost pixels extended to the
- ; ninth position. Using graphics with this mode is more difficult than
- ; with the 200 & 350 line modes since the programmer must be able to
- ; deal with the problem of having blank spaces in an otherwise solid
- ; graphic. Sometimes this effect might actually be beneficial. As for
- ; diagonal or vertical lines, this effect won't be noticed as much. Keep
- ; in mind that the screen is still 640 pixels wide, and all pixels will
- ; be displayed as usual; it's just that there are added blanks.
- mov ah,12h
- mov bl,30h
- mov al,2 ; 400 scan lines
- int 10h
- mov MaxY,399
- mov Points,16
- mov SizeFor128chars,128*16
- ret
- Make9bitChars endp
-
- ClearChars proc far
- ; Calling sequence: ClearChars(ScrnBuf: pointer);
- ; Display original screen (in ScrnBuf), clear the font, and de-allocate
- ; all of the characters. Note that the video page gets set to page 0.
- ScrnBuf equ [bp+6]
-
- push bp
- mov bp,sp
- cld
- mov ax,ds
- mov es,ax
- mov di,offset CharsUsed
- mov cx,192
- mov ax,0
- rep stosw
- mov TotalUsed,0
- les di,Buffer
- mov cx,0c00h
- rep stosw
- push word ptr ScrnBuf[2]
- push word ptr ScrnBuf
- call far ptr PutScrn
- call far ptr WriteFont
- pop bp
- ret 4
- ClearChars endp
-
- FontInit proc far
- ; Calling sequence: FontInit(FontBuffer,ScrnBuffer: pointer);
- ; Initializes the font information. FontBuffer is a pointer to a
- ; 6144-byte array used to store the font. ScrnBuffer is a pointer to
- ; a 4096-byte array used to store the current screen. PutScrn & GetScrn
- ; are alternate ways of using ScrnBuffer. FontInit also configures the
- ; BIOS to handle 512-character fonts, 384 of which are used for VGA_FONT.
- ScrnBuffer equ [bp+6]
- FontBuffer equ [bp+10]
-
- push bp
- mov bp,sp
- mov TotalUsed,0
- les di,FontBuffer
- mov word ptr Buffer,di
- mov word ptr Buffer[2],es
- push word ptr ScrnBuffer[2]
- push word ptr ScrnBuffer
- call far ptr GetScrn
- cld
- mov ax,ds
- mov es,ax
- mov di,offset CharsUsed
- mov ax,0
- mov cx,192
- rep stosw
- les di,Buffer
- mov cx,0c00h
- rep stosw
- call far ptr Make512chars
- pop bp
- ret 8
- FontInit endp
-
- WriteFont proc far
- ; Uses the BIOS to write the font information (contained in Buffer) to the
- ; EVGA adapter. This procedure has the unfortunate consequence of setting
- ; the video page to page 0 (among other things). This makes it more difficult
- ; to stop flickering since the primary way to achieve animation is to use
- ; the Freeze & UnFreeze procedures to copy the screen to another page and
- ; switch to it, thereby effectively "freezing" the screen until
- ; page 0 is switched back. WriteFont will do this switching -- although
- ; it is usually not the correct time to be doing it.
- push bp
- mov ax,1100h
- mov bh,Points
- mov bl,0
- mov cx,128
- mov dx,128
- les bp,Buffer
- int 10h
- mov ax,1100h
- mov bh,Points
- mov bl,1
- mov cx,256
- xor dx,dx
- les bp,Buffer
- add bp,SizeFor128chars
- int 10h
- pop bp
- call far ptr Make512chars
- ret
- WriteFont endp
-
- GetScrn proc far
- ; Calling sequence: GetScrn(SBuffer: pointer);
- ; Reads the screen into the 4096-byte buffer pointed to by SBuffer.
- ; Copies all character codes & attributes. In the future, ClearChars
- ; can use this screen to switch to in order to get a clean slate.
- ; This method allows text to remain constant while graphics get
- ; cleared.
- SBuffer equ [bp+6]
-
- push bp
- mov bp,sp
- push ds
- cld
- mov si,0
- mov ax,0b800h
- mov ds,ax
- les di,SBuffer
- mov cx,2048
- rep movsw
- pop ds
- pop bp
- ret 4
- GetScrn endp
-
- PutScrn proc far
- ; Calling sequence: PutScrn(SBuffer: pointer);
- ; Opposite of GetScrn; transfers SBuffer to the screen.
- SBuffer equ [bp+6]
-
- push bp
- mov bp,sp
- push ds
- cld
- lds si,SBuffer
- mov di,0
- mov ax,0b800h
- mov es,ax
- mov cx,2048
- rep movsw
- pop ds
- pop bp
- ret 4
- PutScrn endp
-
- Make512chars proc far
- ; Configures the BIOS for 512-element fonts. The lower 256 characters
- ; remain in bank 0 while the upper 256 characters are in bank 1.
- mov ax,1103h
- mov bl,4
- int 10h
- ret
- Make512chars endp
-
- PutChar proc near
- ; Calling sequence: PutChar(CharNo: integer; Color,x,y: byte);
- ; Displays CharNo at the specified x,y coordinate. x & y are given
- ; as character positions, based on a resolution of 80x25. The attribute
- ; of the character is in Color. CharNo can be anywhere from 0 to 511.
- y equ byte ptr [bp+4]
- x equ byte ptr [bp+6]
- Color equ byte ptr [bp+8]
- CharNo equ word ptr [bp+10]
-
- push bp
- mov bp,sp
- mov bx,CharNo
- cmp bx,255
- jbe Less255
- or Color,8
- jmp short SkipNextPC
- Less255: and Color,0f7h
- SkipNextPC: mov si,80
- mov al,y
- xor ah,ah
- xor dx,dx
- mul si
- add al,x
- adc ah,0
- shl ax,1
- mov si,ax
- mov ax,0b800h
- mov es,ax
- mov ah,Color
- mov al,bl
- mov es:[si],ax
- pop bp
- ret 8
- PutChar endp
-
- WriteDot proc near
- ; Calling sequence: WriteDot(CharNo,x,y: integer; Value,Color: byte);
- ; Sets a pixel of a particular character given in CharNo. The x & y
- ; values specified are offsets into the character matrix based on
- ; resolutions of 8x8, 8x14, and 8x16. Value is either a 1 or a 0 and
- ; represents the value of the pixel. Color is a standard text-mode attribute.
- ; CharNo must be in the range of 128 through 511.
- Color equ byte ptr [bp+4]
- Value equ byte ptr [bp+6]
- y equ word ptr [bp+8]
- x equ word ptr [bp+10]
- CharNo equ word ptr [bp+12]
-
- push bp
- mov bp,sp
- push CharNo
- mov ax,x
- and ax,7
- push ax
- mov ax,y
- div Points
- mov Temp,ax
- mov al,ah
- xor ah,ah
- push ax
- mov al,Value
- push ax
- call ModifyPixel
- cmp ax,0 ; Is character blank or not?
- jz ContWD ; Not blank; continue
- mov CharNo,32 ; It's blank, and a space
- ContWD: push CharNo
- mov al,Color
- xor ah,ah
- push ax
- mov ax,x
- mov cl,3
- shr ax,cl
- push ax
- and Temp,0ffh
- push Temp
- call PutChar
- pop bp
- ret 10
- WriteDot endp
-
- GetNewChar proc near
- ; Calling sequence: GetNewChar: integer;
- ; This function returns and allocates a new character to be used for
- ; graphics display. GetNewChar starts from character 511 and goes
- ; backwards to character 128, thereby allowing the program to be
- ; easily changed to allow fewer characters to be displayed (and
- ; use the remaining characters as the symbols that IBM intended them
- ; to be). TotalUsed gets incremented.
- mov si,(offset CharsUsed)+383
- std
- mov bx,128
- WhileLoop: cmp bx,511
- ja LimitExceeded
- lodsb
- cmp al,1
- jnz FoundSpot
- inc bx
- jmp short WhileLoop
- FoundSpot: mov ax,639
- sub ax,bx
- mov bx,ax
- sub bx,128
- mov CharsUsed[bx],1
- inc TotalUsed
- push ax
- mov al,Points
- xor ah,ah
- mul bx
- les di,Buffer
- add di,ax
- mov cl,Points
- xor ch,ch
- shr cl,1
- cld
- xor ax,ax
- rep stosw
- pop ax
- ret
- LimitExceeded: xor ax,ax
- ret
- GetNewChar endp
-
- SeeIfSpace proc near
- ; Search the currect character (pointed to by Tmp2) to see if it is blank.
- ; If it is, de-allocate character from list, and return 1 in AX.
- ; If it is not blank, return 0 in AX. SeeIfSpace is for use by
- ; ModifyPixel.
- cld
- les di,Buffer
- add di,Temp2
- mov cl,Points
- xor ch,ch
- shr cl,1
- xor ax,ax
- repe scasw
- or cx,cx
- jnz ExitSIS0
- mov si,[bp+10]
- sub si,128
- mov CharsUsed[si],0
- dec TotalUsed
- mov ax,1
- ExitSIS0: ret
- SeeIfSpace endp
-
- ModifyPixel proc near
- ; Calling sequence: ModifyPixel(CharNo: integer; x,y,Value: byte);
- ; Set a pixel in CharNo to Value, which can be 0 or 1. x & y are offsets
- ; into the character matrix which are based on resolutions of 8x8, 8x14,
- ; and 8x16. CharNo is in the range of 128 to 511.
-
- Value equ byte ptr [bp+4]
- y equ word ptr [bp+6] ; Treat as a word so it
- x equ byte ptr [bp+8] ; can be added quickly
- CharNo equ word ptr [bp+10]
-
- push bp
- mov bp,sp
- mov si,CharNo
- cmp si,128
- jb ExitMP
- cmp si,511
- ja ExitMP
- les di,Buffer
- sub si,128
- mov al,Points
- xor ah,ah
- xor dx,dx
- mul si
- mov si,ax
- mov Temp2,ax
- and y,0ffh
- add si,y
- add di,si
- cmp Value,1
- jz SetPixel
- mov cl,x
- mov bl,128
- shr bl,cl
- not bl
- and es:[di],bl
- call SeeIfSpace
- jmp short ExitMP
- SetPixel: mov cl,x
- mov bl,128
- shr bl,cl
- or es:[di],bl
- xor ax,ax
- ExitMP: pop bp
- ret 8
- ModifyPixel endp
-
- GetChar proc near
- ; Calling sequence: GetChar(x,y: integer): integer;
- ; Given a coordinate, return the character at that coordinate. x & y
- ; are given as screen coordinates in the range of 640x200, 640x350, or
- ; 640x400 depending on the mode. The returned character is in the range
- ; of 0 to 511.
- y equ word ptr [bp+4]
- x equ word ptr [bp+6]
-
- push bp
- mov bp,sp
- mov ax,0b800h
- mov es,ax
- mov ax,y
- div Points
- xor ah,ah
- mov si,ax
- mov ax,80
- xor dx,dx
- mul si
- mov si,x
- mov cl,3
- shr si,cl
- add ax,si
- shl ax,1
- mov si,ax
- mov ax,es:[si]
- and ah,8
- shr ah,cl
- pop bp
- ret 4
- GetChar endp
-
- Pset proc far
- ; Calling sequence: Pset(x,y: integer; Color: byte);
- ; Plot a point at x,y with the attribute in Color. Update the hardware
- ; font with the new information.
- Color equ byte ptr [bp+6]
- y equ word ptr [bp+8]
- x equ word ptr [bp+10]
-
- push bp
- mov bp,sp
- push x
- push y
- call GetChar
- cmp ax,128
- jae InRang
- cmp TotalUsed,384
- jb InRang2
- jmp short ExitP1
- InRang2: cmp Color,0
- jz ExitP1
- call GetNewChar
- InRang: cmp ax,0
- jz ExitP1
- push ax
- push x
- push y
- cmp Color,0
- jz DoPush0
- mov ax,1
- push ax
- jmp short DidPush1
- DoPush0: mov ax,0
- push ax
- DidPush1: mov al,Color
- xor ah,ah
- push ax
- call WriteDot
- call WriteFont
- ExitP1: pop bp
- ret 6
- Pset endp
-
- Pset2 proc near
- ; Calling sequence: Pset2(x,y: integer; Color: byte);
- ; Plot a point at x,y with the attribute in Color. Does not update the
- ; actual hardware font table (for use by higher-level routines).
- Color equ byte ptr [bp+4]
- y equ word ptr [bp+6]
- x equ word ptr [bp+8]
-
- push bp
- mov bp,sp
- push x
- push y
- call GetChar
- cmp ax,128
- jae InRange
- cmp TotalUsed,384
- jb InRange2
- jmp short ExitP2
- InRange2: cmp Color,0
- jz ExitP2
- call GetNewChar
- InRange: cmp ax,0
- jz ExitP2
- push ax
- push x
- push y
- cmp Color,0
- jz Push0
- mov ax,1
- push ax
- jmp short Pushed1
- Push0: mov ax,0
- push ax
- Pushed1: mov al,Color
- xor ah,ah
- push ax
- call WriteDot
- ExitP2: pop bp
- ret 6
- Pset2 endp
-
- MaskColors proc far
- ; Display the low-intensity character attributes only, disregarding the
- ; value specfied at bit 3 of the attribute bytes. Effective until
- ; the video mode is changed.
- mov ax,1000h
- mov bx,0712h
- int 10h
- ret
- MaskColors endp
-
- Freeze proc far
- ; Copies video memory to an alternate page and flips to that page.
- push ax
- push ds
- mov ax,40h ; Save CRT start & active page
- mov es,ax
- push word ptr es:[4eh] ; BIOS CRT_START
- push word ptr es:[62h] ; BIOS ACTIVE_PAGE
- mov ax,0b800h ; Segment of mode CO80 (3)
- mov es,ax
- mov ds,ax
- mov si,0 ; Source: This page
- mov di,2000h ; Destination: Page 2
- mov cx,1000h ; Set to copy 2000h bytes
- cld ; Forward copy
- rep movsw ; Do the copy
- mov ax,0502h ; Function: Go to page 2
- int 10h ; Switch the page
- mov ax,40h ; Restore CRT start &
- mov es,ax ; active page so that all
- pop word ptr es:[62h] ; BIOS functions take
- pop word ptr es:[4eh] ; place on "frozen," non-
- pop ds ; displayed page 0
- pop ax
- ret
- Freeze endp
-
- Unfreeze proc far
- ; Flips back to page 0 to show what has been put there.
- mov ax,0500h ; Function: Display page 0
- int 10h ; Call BIOS
- ret
- Unfreeze endp
-
- DoHlin proc near
- ; Designed for interface with Ellipse procedure. Call with the first
- ; (x,y) coordinate in CX,DX, and the amount to add (twice) in SI
- ; Color is in AX
- push ax
- push bx
- push cx
- push dx
- push si
- push di
-
- push cx
- push dx
- add cx,si
- add cx,si
- push cx
- push ax
- call Hlin2
-
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- DoHlin endp
-
- DoPset proc near
- ; For use with the Ellipse procedure as an interface to the main pixel-set
- ; routine, Pset2.
- x equ word ptr [bp+8]
- y equ word ptr [bp+6]
- Color equ byte ptr [bp+4]
- push bp
- mov bp,sp
-
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push es
-
- push x
- push y
- mov al,Color
- xor ah,ah
- push ax
- call Pset2
-
- pop es
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- pop bp
- ret 6
- DoPset endp
-
- ; The following macro swaps n1 & n2 if n1>n2:
- SwapIfNeeded macro n1,n2
- Local ExitSwap
- mov ax,n1
- cmp ax,n2
- jle ExitSwap
- xchg ax,n2
- mov n1,ax
- ExitSwap:
- endm
-
- Hlin proc far
- ; Calling sequence: Hlin(x1,y1,x2: integer; Color: byte);
- ; Draws a horizontal line from x1,y1 to x2,y1 using the attribute
- ; specified in Color. Updates the hardware font table.
- Color equ byte ptr [bp+6]
- x2 equ word ptr [bp+8]
- y1 equ word ptr [bp+10]
- x1 equ word ptr [bp+12]
-
- push bp
- mov bp,sp
- SwapIfNeeded x1,x2
- mov bx,x1
- LoopHlin1: push bx
- push bx
- push y1
- mov al,Color
- xor ah,ah
- push ax
- call Pset2
- pop bx
- inc bx
- cmp bx,x2
- jbe LoopHlin1
- call WriteFont
- pop bp
- ret 8
- Hlin endp
-
- Hlin2 proc near
- ; Calling sequence: Hlin2(x1,y1,x2: integer; Color: byte);
- ; Draws a horizontal line from x1,y1 to x2,y1 using the attribute
- ; specified in Color. The hardware font table is not updated.
- Color equ byte ptr [bp+4]
- x2 equ word ptr [bp+6]
- y1 equ word ptr [bp+8]
- x1 equ word ptr [bp+10]
-
- push bp
- mov bp,sp
- SwapIfNeeded x1,x2
- mov bx,x1
- LoopHlin2: push bx
- push bx
- push y1
- mov al,Color
- xor ah,ah
- push ax
- call Pset2
- pop bx
- inc bx
- cmp bx,x2
- jbe LoopHlin2
- pop bp
- ret 8
- Hlin2 endp
-
- Vlin proc far
- ; Calling sequence: Vlin(x1,y1,y2: integer; Color: byte);
- ; Draws a vertical line from x1,y1 to x1,y2 using the attribute specified
- ; in Color. The hardware font table is updated.
- Color equ byte ptr [bp+6]
- y2 equ word ptr [bp+8]
- y1 equ word ptr [bp+10]
- x1 equ word ptr [bp+12]
-
- push bp
- mov bp,sp
- SwapIfNeeded y1,y2
- mov bx,y1
- LoopVlin: push bx
- push x1
- push bx
- mov al,Color
- xor ah,ah
- push ax
- call Pset2
- pop bx
- inc bx
- cmp bx,y2
- jbe LoopVlin
- call WriteFont
- pop bp
- ret 8
- Vlin endp
-
- Vlin2 proc near
- ; Calling sequence: Vlin(x1,y1,y2: integer; Color: byte);
- ; Draws a vertical line from x1,y1 to x1,y2 using the attribute
- ; specified in Color. The hardware font table is not updated.
- Color equ byte ptr [bp+4]
- y2 equ word ptr [bp+6]
- y1 equ word ptr [bp+8]
- x1 equ word ptr [bp+10]
-
- push bp
- mov bp,sp
- SwapIfNeeded y1,y2
- mov bx,y1
- LoopVlin2: push bx
- push x1
- push bx
- mov al,Color
- xor ah,ah
- push ax
- call Pset2
- pop bx
- inc bx
- cmp bx,y2
- jbe LoopVlin2
- pop bp
- ret 8
- Vlin2 endp
-
- Box proc far
- ; Calling sequence: Box(x1,y1,x2,y2: integer; Color: byte);
- ; Draws a filled-in box with the attribute specified in Color.
- ; The upper-left coordinate is x1,y1. The lower right is x2,y2.
- Color equ byte ptr [bp+6]
- y2 equ word ptr [bp+8]
- x2 equ word ptr [bp+10]
- y1 equ word ptr [bp+12]
- x1 equ word ptr [bp+14]
-
- push bp
- mov bp,sp
- SwapIfNeeded x1,x2
- SwapIfNeeded y1,y2
- mov bx,y1
- LoopBox: push bx
- push x1
- push bx
- push x2
- mov al,Color
- xor ah,ah
- push ax
- call Hlin2
- pop bx
- inc bx
- cmp bx,y2
- jbe LoopBox
- call WriteFont
- pop bp
- ret 10
- Box endp
-
- OpenBox proc far
- ; Calling sequence: OpenBox(x1,y1,x2,y2: integer; Color: byte);
- ; Draws the outline of a box using the attribute specified in Color.
- ; The upper-left coordinate is x1,y1. The lower-right is x2,y2.
- Color equ byte ptr [bp+6]
- y2 equ word ptr [bp+8]
- x2 equ word ptr [bp+10]
- y1 equ word ptr [bp+12]
- x1 equ word ptr [bp+14]
-
- push bp
- mov bp,sp
- mov al,Color
- xor ah,ah
- push ax
- push x1
- push y1
- push x2
- push ax
- call Hlin2
- pop ax
- push ax
- push x1
- push y2
- push x2
- push ax
- call Hlin2
- pop ax
- push ax
- push x1
- push y1
- push y2
- push ax
- call Vlin2
- pop ax
- push ax
- push x2
- push y1
- push y2
- push ax
- call Vlin2
- pop ax
- call WriteFont
- pop bp
- ret 10
- OpenBox endp
-
- Line proc far
- ; Calling sequence: Line(x1,y1,x2,y2: integer; Color: byte);
- ; Draws a line from x1,y1 to x2,y2 using the attribute specified in Color.
- ; Uses Bresenham's line algorithm. Actual code has been taken from
- ; a Plume/Waite book by Robert Lafore: Assembly language primer for the
- ; IBM PC & XT.
- Color equ word ptr [bp+6]
- y2 equ word ptr [bp+8]
- x2 equ word ptr [bp+10]
- y1 equ word ptr [bp+12]
- x1 equ word ptr [bp+14]
-
- push bp
- mov bp,sp
- 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
- csteep: call steep
- finish: call WriteFont
- pop bp
- ret 10
-
- 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: push cx
- push dx
- push Color
- call DoPset
- add cx,di
- add bx,delta_y
- cmp bx,halfy
- 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: push cx
- push dx
- push Color
- call DoPset
- 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
- Line endp
-
- Ellipse proc far
- ; Call With: Ellipse(x1,y1,r1,r2: word; Color: byte);
- ; Draws an ellipse centered at x1,y1; the x-radius is in r1, and the
- ; y-radius is in r2. The attribute is specified in Color.
- ; Note: if bit 7 of the color is high, the entire ellipse if
- ; filled (and the bit is stripped). If it's low, just the
- ; perimeter is filled.
- ; The code has been taken from "EGA/VGA, A Programmer's Reference Guide" by
- ; Dyck Kliewer and published by Intertext/McGraw-Hill
- x1 equ word ptr [bp+14]
- y1 equ word ptr [bp+12]
- r1 equ word ptr [bp+10]
- r2 equ word ptr [bp+8]
- Color equ byte ptr [bp+6]
- ;
- r_l equ 1
- t_b equ 11111110b
- pixpb equ 3
- b_mask equ 10000000b
-
-
- push bp
- mov bp,sp
-
- and portion,t_b
- call e_call
- or portion,r_l
- push r2
- push r1
- pop r2
- pop r1
- call e_call
-
- call WriteFont
-
- pop bp
- ret 10
-
- e_call proc near
- push ax
- push bx
- push cx
- push dx
- mov ax,x1
- mov c_x,ax
- mov ax,y1
- mov c_y,ax
- mov ax,0
- mov xe,0
- mov bx,r2
- mov ye,bx
- mov cx,r1
- call near ptr ellip
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- e_call endp
-
-
- ellip proc near
- push bp
- mov Old_BP,bp
- mov si,ax
- mov ax,bx
- mul bx
- mov bp,dx
- mov bx,ax
- mov r2_lo,ax
- mov r2_hi,dx
- mov ax,cx
- mul cx
- mov di,dx
- mov cx,ax
- mov r1_lo,ax
- mov r1_hi,dx
-
- push bx
- push cx
- push di
- push bp
- push si
- mul ax
- mov bp,ax
- mov bx,dx
- mov ax,di
- mul cx
- shl ax,1
- rcl dx,1
- add bx,ax
- mov cx,dx
- mov ax,di
- mul ax
- add cx,ax
- mov ax,bp
- mov dx,r2_lo
- mov di,r2_hi
- add dx,r1_lo
- adc di,r1_hi
- mov bp,0
- mov si,0
- div_loop: cmp cx,0
- jne c_div
- cmp bx,di
- ja c_div
- cmp ax,dx
- jae c_div
- jmp short div_done
- c_div: inc bp
- jnz no_of
- inc si
- no_of: sub ax,dx
- sbb bx,di
- sbb cx,0
- jmp short div_loop
- div_done: shl ax,1
- rcl bx,1
- cmp di,bx
- ja no_up
- cmp dx,ax
- ja no_up
- inc bp
- jnz no_up
- inc si
- no_up: sub bx,bx
- cmp dx,0
- jne rt_strt
- cmp si,0
- jne rt_strt
- jmp rt_done
- rt_strt: mov bx,512
- mov cx,512
- rt_lp: shr cx,1
- mov ax,bx
- mul ax
- cmp dx,si
- jg t_lg
- jl t_sm
- cmp ax,bp
- jb t_sm
- jmp short t_lg
- t_sm: add ax,bx
- adc dx,0
- cmp si,dx
- ja t_sm2
- cmp bp,ax
- ja t_sm2
- jmp short rt_done
- t_sm2: add bx,cx
- jmp short rt_lp
- t_lg: sub ax,bx
- sbb dx,0
- cmp dx,si
- ja t_lg2
- cmp ax,bp
- ja t_lg2
- jmp short rt_done
- t_lg2: sub bx,cx
- jmp short rt_lp
- rt_done: inc bx
- mov max_x,bx
- pop si
- pop bp
- pop di
- pop cx
- pop bx
-
- push bx
- push bp
- mov ax,cx
- mul ye
- mov bx,ax
- mov bp,dx
- mov ax,di
- mul ye
- add bp,ax
- neg bx
- not bp
- shl bx,1
- rcl bp,1
- add cx,bx
- adc di,bp
- mov t_e_lo,cx
- mov t_e_hi,di
-
- shl r1_lo,1
- rcl r1_hi,1
- shl r1_lo,1
- rcl r1_hi,1
- mov bx,ye
- dec bx
- mov ax,r1_lo
- mul bx
- mov bp,dx
- neg ax
- mov y_p_lo,ax
- mov ax,r1_hi
- mul bx
- add ax,bp
- not ax
- mov y_p_hi,ax
- pop bp
- pop bx
- shl bx,1
- rcl bp,1
- push bx
- push bp
- shl bx,1
- rcl bp,1
- mov r2_lo,bx
- mov r2_hi,bp
- mov cx,bx
- mov di,bp
- pop bp
- pop bx
- mov dx,t_e_hi
- mov ax,t_e_lo
-
- retest: ; Plot the points:
-
- push ax
- push bx
- push cx
- push dx
- push di
- push si
- push bp
- mov bp,Old_BP
- mov di,ye
- test portion,r_l
- jz no_xchg
- xchg si,di
- no_xchg: mov al,Color
- xor ah,ah
- test al,128
- jnz DoHlinPlot
- mov cx,c_x
- add cx,si
- mov dx,c_y
- add dx,di
- push cx
- push dx
- push ax
- call DoPset
- sub cx,si
- sub cx,si
- push cx
- push dx
- push ax
- call DoPset
- sub dx,di
- sub dx,di
- push cx
- push dx
- push ax
- call DoPset
- add cx,si
- add cx,si
- push cx
- push dx
- push ax
- call DoPset
- jmp short DonePlot
-
- DoHlinPlot: and al,01111111b
- mov cx,c_x
- sub cx,si
- mov dx,c_y
- add dx,di
- call DoHlin
- sub dx,di
- sub dx,di
- call DoHlin
-
- DonePlot: pop bp
- pop si
- pop di
- pop dx
- pop cx
- pop bx
- pop ax
-
- cmp si,max_x
- jne e_cont
- jmp e_done
-
- e_cont: cmp dx,0
- jl Less1
- push bx
- push bp
- mov bx,y_p_lo
- mov bp,y_p_hi
- add ax,bx
- adc dx,bp
- dec ye
- add bx,r1_lo
- adc bp,r1_hi
- mov y_p_lo,bx
- mov y_p_hi,bp
- pop bp
- pop bx
- Less1: add ax,bx
- adc dx,bp
- inc si
- add bx,cx
- adc bp,di
- jmp Retest
- e_done: pop bp
- ret
- ellip endp
- Ellipse endp
-
- Code ends
- end