;----------------------------------------------------------------------- ; MODULE XLINE ; ; Line drawing functions. ; ; Compile with Tasm. ; C callable. ; ; ; ****** XLIB - Mode X graphics library **************** ; ****** **************** ; ****** Written By Themie Gouthas **************** ; ; egg@dstos3.dsto.gov.au ; teg@bart.dsto.gov.au ;----------------------------------------------------------------------- include xlib.inc include xline.inc .code ModeXAddr macro mov cl,bl push dx mov dx,[_ScrnLogicalByteWidth] mul dx pop dx shr bx,1 shr bx,1 add bx,ax add bx,[bp+14] and cl,3 endm ;----------------------------------------------------------------------- ; _x_line ; ; Line drawing function for all MODE X 256 Color resolutions ; Based on code from "PC and PS/2 Video Systems" by Richard Wilton. ; ; Compile with Tasm. ; C callable. ; _x_line proc ;ARG x1:word,y1:word,x2:word,y2:word,Color:word,PgOffs:word LOCAL vertincr:word,incr1:word,incr2:word,routine:word=LocalStk push bp ; Set up stack frame mov bp,sp sub sp,LocalStk push si push di mov ax,0a000h mov es,ax mov dx,SC_INDEX ; setup for plane mask access ; check for vertical line mov si,[_ScrnLogicalByteWidth] mov cx,[bp+8] sub cx,[bp+4] jz VertLine ; force x1 < x2 jns L01 neg cx mov bx,[bp+8] xchg bx,[bp+4] mov [bp+8],bx mov bx,[bp+10] xchg bx,[bp+6] mov [bp+10],bx ; calc dy = abs(y2 - y1) L01: mov bx,[bp+10] sub bx,[bp+6] jnz short skip jmp HorizLine skip: jns L03 neg bx neg si ; select appropriate routine for slope of line L03: mov [vertincr],si mov [routine],offset LoSlopeLine cmp bx,cx jle L04 mov [routine],offset HiSlopeLine xchg bx,cx ; calc initial decision variable and increments L04: shl bx,1 mov [incr1],bx sub bx,cx mov si,bx sub bx,cx mov [incr2],bx ; calc first pixel address push cx mov ax,[bp+6] mov bx,[bp+4] ModeXAddr mov di,bx mov al,1 shl al,cl mov ah,al ; duplicate nybble shl al,1 shl al,1 shl al,1 shl al,1 add ah,al mov bl,ah pop cx inc cx jmp [routine] ; routine for verticle lines VertLine: mov ax,[bp+6] mov bx,[bp+10] mov cx,bx sub cx,ax jge L31 neg cx mov ax,bx L31: inc cx mov bx,[bp+4] push cx ModeXAddr mov ah,1 shl ah,cl mov al,MAP_MASK out dx,ax pop cx mov ax, word ptr [bp+12] ; draw the line L32: mov es:[bx],al add bx,si loop L32 jmp Lexit ; routine for horizontal line HorizLine: push ds mov ax,[bp+6] mov bx,[bp+4] ModeXAddr mov di,bx ; set dl = first byte mask mov dl,00fh shl dl,cl mov cx,[bp+8] ; set dh = last byte mask and cl,3 mov dh,00eh shl dh,cl not dh ; determine byte offset of first and last pixel in line mov ax,[bp+8] mov bx,[bp+4] shr ax,1 ; set ax = last byte column shr bx,1 ; set bx = first byte column shr ax,1 ; set ax = last byte column shr bx,1 ; set bx = first byte column mov cx,ax ; cx = ax - bx sub cx,bx mov ax,dx ; mov end byte masks to ax mov dx,SC_INDEX ; setup dx for VGA outs mov bx, [bp+12] ; set pixels in leftmost byte of line or cx,cx ; is start and end pt in same byte jnz L42 ; no ! and ah,al ; combine start and end masks jmp short L44 L42: push ax mov ah,al mov al,MAP_MASK out dx,ax mov al,bl stosb dec cx ; draw remainder of the line L43: mov ah,0Fh mov al,MAP_MASK out dx,ax mov al,bl rep stosb pop ax ; set pixels in rightmost byte of line L44: mov al,MAP_MASK out dx, ax mov byte ptr es:[di],bl pop ds jmp short Lexit ; routine for dy >= dx (slope <= 1) LoSlopeLine: mov al,MAP_MASK mov bh,byte ptr [bp+12] L10: mov ah,bl L11: or ah,bl rol bl,1 jc L14 ; bit mask not shifted out or si,si jns L12 add si,[incr1] loop L11 out dx,ax mov es:[di],bh jmp short Lexit L12: add si,[incr2] out dx,ax mov es:[di],bh add di,[vertincr] loop L10 jmp short Lexit ; bit mask shifted out L14: out dx,ax mov es:[di],bh inc di or si,si jns L15 add si,[incr1] loop L10 jmp short Lexit L15: add si,[incr2] add di,[vertincr] loop L10 jmp short Lexit ; routine for dy > dx (slope > 1) HiSlopeLine: mov bx,[vertincr] mov al,MAP_MASK L21: out dx,ax push ax mov ax,[bp+12] mov es:[di],al pop ax add di,bx L22: or si,si jns L23 add si,[incr1] loop L21 jmp short Lexit L23: add si,[incr2] rol ah,1 adc di,0 lx21: loop L21 ; return to caller Lexit: pop di pop si mov sp,bp pop bp ret _x_line endp end