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