.model medium
.stack 20h
.386

EXTRN gsclipx1:WORD
EXTRN gsclipx2:WORD
EXTRN gsclipy1:WORD
EXTRN gsclipy2:WORD

.code
public gshline
gshline proc
;stack:
;bp+14	x1
;bp+12	x2
;bp+10	y
;bp+8	seg
;bp+6	ofs
;bp+4	col
;bp+2	retseg
;bp	retofs

mov si, bp
mov bp, sp

push es
mov bx, [bp+10] ;bx = y

cmp bx, gsclipy1
jl endofline

cmp bx, gsclipy2
jg endofline

mov ax, [bp+14] ;ax = x1
mov dx, [bp+12] ;dx = x2

cmp ax, dx
jg swapx        ;if x1 > x2 then swap them

afterswapx:
cmp ax, gsclipx2 ;x1 > clipx2? end
jg endofline

cmp dx, gsclipx1 ;x2 < clipx1? end
jl endofline

cmp ax, gsclipx1 ;clip x1?
jl tooleft

aftertooleft:
cmp dx, gsclipx2 ;clip x2?
jg tooright

aftertooright:
mov di, [bp+6]   ;di = offset
inc dx           ;dx = x2 + 1

add di, ax       ;offset = offset + x1
sub dx, ax       ;dx = length

shl bx, 6        ;bx = y*64
mov ax, [bp+4]   ;al = color

mov ah, al       ;ax = color*257
add di, bx       ;di = offset + x1 + 64*y

shl bx, 2        ;bx = 256*y
push ax          ;[bp-4] = color*257

shl eax, 16      ;eax = col.col.0.0
mov cx, dx       ;cx = length

add di, bx       ;di = offset + x1 + 320*y
pop ax           ;eax = col.col.col.col

and dx, 3        ;dx = length AND 3
jnz messy        ;if dx <> 0 then goto messy

shr cx, 2        ;cx = length \ 4
mov es, [bp+8]   ;es = segment

rep stosd        ;drawtheline
jmp endofline

messy:
mov es, [bp+8]
shr cx, 2        ;cx = length \ 4
jz smalll        ;if cx = 0 then don't do dwords

rep stosd        ;draw dwords

smalll:
mov cx, dx       ;cx = length AND 3

rep stosb        ;draw single pixels

endofline:
pop es           ;es = [bp-2]
mov bp, si       ;bp = original bp
retf 12          ;end/return

swapx:
xchg ax, dx      ;x1 is now =< x2
jmp afterswapx

tooleft:
mov ax, gsclipx1 
jmp aftertooleft

tooright:
mov dx, gsclipx2
jmp aftertooright

gshline endp
end
