Category : Assembly Language Source Code
Archive   : MATHASM.ZIP
Filename : PLOT.ASM

 
Output of file : PLOT.ASM contained in archive : MATHASM.ZIP
PAGE 255,132
;-------------------------------------------------------------
;
; orline.asm
; orpt.asm
;
; written by Bruce A. Smith 7/24/84
;
;-------------------------------------------------------------
;
; The two procedures here plot a point or draw a line on the
; medium resolution screen of the IBM PCjr or IBM PC. The
; line drawing routine uses self-modifying code. They both
; are written to OR the color bits onto the screen. The
; objective of writing these routines was to achieve as much
; speed performance as possible with the 8088 microprocessor
; used in these machines. The line drawing routine is
; approximately three times faster than the one listed in the
; BLUEBOOK OF ASSEMBLY ROUTINES FOR THE IBM PC & XT by
; Christopher Morgan. It is also three times faster than the
; line drawing routine used in the ROM BASIC on the PCjr.
; The point plotting routine is a little more difficult to
; compare because the overhead of the call and the computation
; for the next point become significant. In performance tests
; it plotted points half again as fast as the routine in the
; previously mentioned book by Christopher Morgan and in
; spite of the overhead it performed four times faster than
; the ROM BIOS point plotting routines. So this point plotting
; routine is probably about five times faster than the ROM BIOS.
;
;------------------------------------------------------------
; REFERENCES
;
; Foley, James d. and Andries Van Dam, Fundamentals of Interactive
; Computer Graphics, Addison-Wesley, Reading, MA, 1982.
;
; Morgan, Christopher L., Bluebook of Assembly Routines for
; the IBM PC & XT, The Waite Group, New York, NY, 1984.
;
;------------------------------------------------------------
;
DGROUP GROUP DATA
DATA SEGMENT WORD PUBLIC 'DATA'
ASSUME DS:DGROUP
PUBLIC COLOR,X1,X2,Y1,Y2
;
; the order and type of declaration is important here
;
y2 dw 0
x2 dw 0
y1 dw 0
x1 dw 0
color db 0
;
; color = color * 4 + 1, color 0 == mask
;
ctableh db 03Fh,0CFh,0F3h,0FCh
db 040h,010h,004h,001h
db 080h,020h,008h,002h
db 0C0h,030h,00Ch,003h
;
fakedw = 1000h
;
DATA ENDS
;
;------------------------------------------------------------
;
PGROUP GROUP PROG
PROG SEGMENT BYTE PUBLIC 'PROG'
PUBLIC ORLINE,ORPT
ASSUME CS:PGROUP
;
;-------------------------------------------------------------
;
; orline.asm
;
;------------------------------------------------------------
;
; ROUTINE TO OR A LINE ONTO MEDIUM RESOLUTION SCREEN
;
; uses Bresenham's algorithm
;
orline proc near
push bp ; save calling bp
; only reg needed to save for 'C'
push ds ; save ds
; ------------------------------
; get x & y values
mov si,OFFSET y2 ; addr y2
lodsw ; ax = y2
xchg ax,dx ; dx = y2
lodsw ; ax = x2
xchg ax,di ; di = x2
lodsw ; ax = y1
xchg ax,cx ; cx = y1
lodsw ; ax = x1
mov bx,si ; bx = addr color
xchg ax,si ; si = x1
;
cmp si,di ; cmp x1,x2
jle swapxy ; skip if (x1<=x2)
xchg cx,dx ; (x1>x2): swap y1,y2
xchg si,di ; swap x1,x2
swapxy:
;
; ............................................
; | H | L |
; -----------------------------------------------
; ax | | |
; -----------------------------------------------
; bx | addr color |
; -----------------------------------------------
; cx | 0 | y1 | if ( x1 > x2 )
; ----------------------------------------------- swap (x1,y1) with
; dx | 0 | y2 | (x2,y2)
; ----------------------------------------------- ie.
; si | x1 | xchg cx,dx
; ----------------------------------------------- xchg si,di
; di | x2 |
; -----------------------------------------------
; bp | |
; ----------------------------------,=-----------
;
;
; ch = deldy = (y1>y2) ? -80 : 80
; dx = |y2-y1|
sub dx,cx ; y2-y1
mov al,80 ; deldy = 80
jge ydown ; skip if (y1<=y2)
neg dx ; |y2-y1|
neg al ; deldy = -1
ydown:
sub di,si ; x2-x1
; di = |x2-x1|
;
; ............................................
; | H | L |
; ----------------------------------------------- al=80
; ax | | (y1>y2)? -80: 80 | dx-cx = y2-y1
; ----------------------------------------------- if neg (y1>y2)
; bx | addr color | neg dx =|y2-y1|
; ----------------------------------------------- al=-80
; cx | 0 | y1 |
; ----------------------------------------------- deldy = al
; dx | 0 | absdy = |y2-y1| |
; -----------------------------------------------
; si | x1 |
; ----------------------------------------------- di-si
; di | absdx = x2-x1 | = |x2-x1|
; -----------------------------------------------
; bp | |
; -----------------------------------------------
;
;
cmp di,dx ; absdx,absdy
lahf
jnl minmax ; skip if (absdx>=absdy)
xchg di,dx
minmax:
; dx = dmin
; di = dmax
;
; ............................................
; | H | L | if (absdx < absdy)
; ----------------------------------------------- cmp di,dx lahf
; ax | flags absdx,absdy| deldy | jnl -
; ----------------------------------------------- swap(absdx,absdy)
; bx | addr color | xchg di,dx
; ----------------------------------------------- -:
; cx | 0 | y1 |
; -----------------------------------------------
; dx | 0 | dmin |
; -----------------------------------------------
; si | x1 |
; -----------------------------------------------
; di | dmax |
; -----------------------------------------------
; bp | |
; -----------------------------------------------
;
;
xchg ax,bp ; bp=flags(absdx,absdy) & deldy
;
; ROUTINE TO FIND INITIAL Y-ADDR, X-ADDR, AND ROTATED COLOR
;
; multiply y-coord by bytes per row and adjust for even/odd lines
ror cl,1 ; adjust odd/even
mov ax,cx ; ax = cx = adj y-coord
and al,7Fh ; page mask
sal cx,1 ; times 2
sal cx,1 ; times 4
add cx,ax ; y-coord times 5
sal cx,1 ; times 10
sal cx,1 ; times 20
sal cx,1 ; times 40
sal cx,1 ; times 80
;
; ............................................
; | H | L |
; -----------------------------------------------
; ax | 0 | |
; -----------------------------------------------
; bx | addr color = addr ctableh-1 |
; -----------------------------------------------
; cx | y-addr |
; -----------------------------------------------
; dx | 0 | dmin |
; -----------------------------------------------
; si | x1 |
; -----------------------------------------------
; di | dmax |
; -----------------------------------------------
; bp | flags absdx,absdy| deldy |
; -----------------------------------------------
;
;
; compute the rotated mask and color
; bx = ctableh-1 = addr color
mov al,3 ; pixel position mask
and ax,si ; just the bit count into the index
add al,[bx] ; pixel position + color (* 4 + 1)
xlat ; look up the masks al=[al+bx]
;
mov bx,0B800H ; disp seg base addr
mov ds,bx ; ds = display base addr
;
; al = rotated color
; cx = y-addr offset
; ds = display addr
;
; ............................................
; | H | L |
; -----------------------------------------------
; ax | 0 | rotated color |
; -----------------------------------------------
; bx | | |
; -----------------------------------------------
; cx | y-addr |
; -----------------------------------------------
; dx | 0 | dmin |
; -----------------------------------------------
; si | x1 |
; -----------------------------------------------
; di | dmax |
; -----------------------------------------------
; bp | flags absdx,absdy| deldy |
; -----------------------------------------------
;
;
sal dx,1 ; dx = delse = dmin * 2
xchg cx,di ; cx = dmax, di = y-addr
xchg ax,dx ; ax=delse, dx=rotated color
xchg ax,bp ; ax=flags(absdx,absdy), bp=delse
;
; ............................................
; | H | L |
; -----------------------------------------------
; ax | flags absdx,absdy| deldy |
; -----------------------------------------------
; bx | | |
; -----------------------------------------------
; cx | dmax |
; -----------------------------------------------
; dx | 0 | rotated color |
; -----------------------------------------------
; si | x1 |
; -----------------------------------------------
; di | y-addr |
; -----------------------------------------------
; bp | dmin * 2 = delse |
; -----------------------------------------------
;
;
sahf ; cmp absdx,absdy
pushf
;
cbw ; ax = deldy
mov cs:delsy,ax ; save deldy
mov cs:deldy,ax
mov cs:deldy2,ax
mov bx,di ; bx = y-addr
or ax,ax
js negdeldy ; if deldy<0 jmp
;
test bh,20H ; is page bit set?
jz toggle ; skip to toggle page
;
add bx,ax ; add deldy to y-addr
jmp toggle ; skip to toggle page
negdeldy:
test bh,20H ; is page bit set?
jnz toggle ; skip to toggle page
;
add bx,ax ; add deldy to y-addr
toggle:
xor bh,20H ; flip page bit
; bx = next y-addr
;
; ............................................
; | H | L |
; -----------------------------------------------
; ax | | |
; -----------------------------------------------
; bx | y-addr (next) |
; -----------------------------------------------
; cx | dmax |
; -----------------------------------------------
; dx | 0 | rotated color |
; -----------------------------------------------
; si | x1 |
; -----------------------------------------------
; di | y-addr |
; -----------------------------------------------
; bp | dmin * 2 = delse |
; -----------------------------------------------
;
;
xchg ax,bp ; ax = dmin * 2 = delse
mov cs:delse,ax ; save delse
mov cs:delse2,ax ; save delse
sub ax,cx ; ax = dmin * 2 - dmax = d
mov bp,ax ; bp = d = error term
sub ax,cx ; ax = dmin * 2 - dmax * 2
mov cs:delde,ax ; save delde
mov cs:delde2,ax ; save delde
;
xchg ax,bx ; ax = next y-addr
;
; figure x-coord address
mov bx,si ; get x-coordinate
sar bx,1 ; divide
sar bx,1 ; by 4
; bx = x-addr offset
;
; ............................................
; | H | L |
; -----------------------------------------------
; ax | y-addr (next) |
; -----------------------------------------------
; bx | x-addr |
; -----------------------------------------------
; cx | loop count |
; -----------------------------------------------
; dx | | rotated color |
; -----------------------------------------------
; si | x value |
; -----------------------------------------------
; di | y-addr |
; -----------------------------------------------
; bp | error term |
; -----------------------------------------------
;
;
popf ; cmp absdx,absdy
jns delsx2 ; if (absdx>=absdy) goto delsx2
;
; -----------------------------------------------
; delsx = 0 (absdx < absdy)
;
or [bx][di],dl ; or disp with color (plot point)
jcxz lineexit ; quit when cx=0
or bp,bp ; set bp flags
jge diagonal ; if bp>=0 jmp
;
; case for straight move
straight:
xchg ax,di ; every other for page adj
delsy = $+1
add ax,fakedw ; ++y
;
or [bx][di],dl ; or disp with color (plot point)
dec cx ; --loop counter
jz lineexit ; quit when cx=0
;
delse = $+2
add bp,fakedw ; update error term
js straight ; if bp<0 goto straight
;
; case for diagonal move
diagonal:
inc si ; ++x value
mov bx,si ; bx = x value
sar bx,1
sar bx,1 ; bx = x addr offset
;
ror dl,1 ; adjust color position
ror dl,1
;
xchg ax,di ; every other for page adj
deldy = $+1
add ax,fakedw ; ++y
;
or [bx][di],dl ; or disp with color (plot point)
dec cx ; --loop counter
jz lineexit ; quit when cx=0
;
delde = $+2
add bp,fakedw ; update error term
js straight ; if bp<0 goto straight
jmp diagonal ; if bp>=0 goto diagonal
;
; -----------------------------------------------
delsx2:
; delsx = 1 (absdx >= absdy)
;
or [bx][di],dl ; or disp with color (plot point)
jcxz lineexit ; quit when cx=0
or bp,bp ; set bp flags
jge diagonal2 ; if bp>=0 jmp
;
; case for straight move
straight2:
inc si ; ++x value
mov bx,si ; bx = x value
sar bx,1
sar bx,1 ; bx = x addr offset
;
ror dl,1 ; adjust color position
ror dl,1
;
or [bx][di],dl ; or disp with color (plot point)
dec cx ; --loop counter
jz lineexit ; quit when cx=0
;
delse2 = $+2
add bp,fakedw ; update error term
js straight2 ; if bp<0 goto straight
;
; case for diagonal move
diagonal2:
inc si ; ++x value
mov bx,si ; bx = x value
sar bx,1
sar bx,1 ; bx = x addr offset
;
ror dl,1 ; adjust color position
ror dl,1
;
xchg ax,di ; every other for page adj
deldy2 = $+1
add ax,fakedw ; ++y
;
or [bx][di],dl ; or disp with color (plot point)
dec cx ; --loop counter
jz lineexit ; quit when cx=0
;
delde2 = $+2
add bp,fakedw ; update error term
js straight2 ; if bp<0 goto straight
jmp diagonal2 ; if bp>=0 goto diagonal
;
; -----------------------------------------------
lineexit:
pop ds ; restore ds
pop bp ; restore calling bp
ret
;
orline endp
;
;------------------------------------------------------------
;
; orx<.asm
;
;------------------------------------------------------------
;
; ROUTINE TO OR A POINT ONTO MEDIUM RES COLOR SCREEN
;
orpt proc near
;
; get initial values for x and y
mov si,OFFSET y1 ; addr y1
lodsw ; ax = y1
;
; multiply y-coord by bytes per row and adjust for even/odd lines
ror al,1 ; adjust odd/even
;
mov dx,0B87FH ; disp addr and page mask
and dl,al ; mask page bit, disp + y.coord
sal ax,1 ; times 32
sal ax,1 ; times 64
add dx,ax ; addr disp seg + y-coord times 5 (80)
;
; compute x-coord address offset
lodsw ; ax = x1
mov di,ax ; get x-coordinate
sar di,1 ; divide
sar di,1 ; by 4
;
; compute the rotated mask and color
and al,3 ; just the bit count into the index
add al,[si] ; pixel position + color (* 4 + 1)
mov bx,si ; bx = ctableh - 1
mov si,ds ; save ds
xlat ; look up the masks al=[al+bx]
;
mov ds,dx ; set seg to disp + y-addr
or [di],al ; or the byte with the color
;
mov ds,si ; restore ds
ret
;
orpt endp
;
;------------------------------------------------------------
;
PROG ENDS
END


  3 Responses to “Category : Assembly Language Source Code
Archive   : MATHASM.ZIP
Filename : PLOT.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/