home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Boston 2
/
boston-2.iso
/
DOS
/
PROGRAM
/
PASCAL
/
VGAFONT
/
VGA_FONT.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-12-01
|
50KB
|
1,308 lines
; 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