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