.model medium, basic
.stack 24h
.386
.code

public VSBox
public VSLine
public VSXLine
public VSYLine

;===================The following is the source for Dash=====================
;==========================by 1998-2000 VirtuaSoft===========================

;=======This draws a horizontal line=========================================
VSXLine proc   ;segment, offset, x1, x2, y, color
      push ds
      push bp
      mov bp, sp

      mov ax, [bp+10]         ;ax = y
      cmp ax, 199
      ja endxline

      mov cx, [bp+12]         ;x2
      cmp cx, 319
      jng x2inscrn
      mov word ptr [bp+12], 319
   x2inscrn:
      mov cx, [bp+14]         ;x1
      cmp cx, 0
      jns x1inscrn
      mov word ptr [bp+14], 0
   x1inscrn:
      cmp cx, [bp+12]
      jg endxline             ;is x1>x2?

      mov ds, [bp+18]         ;set segment1

      xor bl, bl
      mov ax, [bp+10]
      mov bh, al              ;bx = y * 256
      shl ax, 6               ;ax = y * 64
      add bx, ax              ;bx = y * 320
      add bx, [bp+16]         ;bx = y * 320 + offset1
      mov dl, [bp+8]          ;set color
      add bx, [bp+14]
      mov si, bx

   xline:
      mov [si], dl            ;place pixel
      inc cx
      inc si
      cmp cx, [bp+12]
      jng xline

   endxline:
      pop bp
      pop ds
      ret 12
VSXLine endp

;=======This draws a vertical line===========================================
VSYLine proc   ;segment, offset, x, y1, y2, color
      push ds
      push bp
      mov bp, sp

      mov cx, [bp+14]         ;is it out of the screen?
      cmp cx, 319
      ja endyline

      mov cx, [bp+10]         ;y2
      cmp cx, 199
      jng y2inscrn
      mov word ptr [bp+10], 199
   y2inscrn:
      mov cx, [bp+12]         ;y1
      cmp cx, 0
      jns y1inscrn
      mov word ptr [bp+12], 0
   y1inscrn:
      cmp cx, [bp+10]
      jg endyline             ;is y1>y2?

      mov ds, [bp+18]         ;set segment1
      mov dl, [bp+8]          ;set color

      xor bl, bl
      mov ax, cx              ;y1
      mov bh, al              ;bx = y1 * 256
      shl ax, 6               ;ax = y1 * 64
      add bx, ax
      add bx, [bp+14]         ;bx = bx + x1
      add bx, [bp+16]
      mov si, bx

   yline:
      mov [si], dl            ;place pixel
      inc cx
      add si, 320
      cmp cx, [bp+10]
      jng yline

   endyline:
      pop bp
      pop ds
      ret 12
VSYLine endp

;=======This draws a line====================================================
;bp=i, bp+2=s, bp+4=ylen, bp+6=xlen
;bp+8=d2y, bp+10=d2x, bp+12=d1y, bp+14=d1x
;bp+16=bp, bp+18=QBoffset, bp+20=QBsegment, bp+22=color
;bp+24=y2, bp+26=x2, bp+28=y1, bp+30=x1
;bp+32=offset, bp+34=segment, di=xLength, si=yLength
VSLine proc
      ;***d2y% = 0***
      xor eax, eax
      push bp
      push eax                ;d1x, d1y
      push eax                ;d2x, d2y
      push eax                ;xlen, ylen
      push eax                ;s, i
      mov bp, sp

      ;***xLength% = x2% - x1%***
      mov word ptr [bp+14], 1 ;d1x
      mov di, [bp+26]
      sub di, [bp+30]
      ;***d1x% = SGN(xLength%)***
      jg greaterx
      jz zerox
      dec word ptr [bp+14]
   zerox:
      dec word ptr [bp+14]
   greaterx:

      ;***yLength% = y2% - y1%***
      mov word ptr [bp+12], 1 ;d1y
      mov si, [bp+24]         ;YLength=y2-y1
      sub si, [bp+28]
      ;***d1x% = SGN(xLength%)***
      jg greatery
      jz zeroy
      dec word ptr [bp+12]    ;d1y=sgn(YLength)
   zeroy:
      dec word ptr [bp+12]    ;d1y=0
   greatery:

      ;***d2x% = d1x%***
      mov ax, [bp+14]         ;d2x=d1x
      mov [bp+10], ax

      ;***IF d1x% < 0 THEN xLen% = -xLength% ELSE xLen% = xLength%
      mov ax, [bp+14]         ;XLen=xLength*sgn(d1x)
      mov bx, di
      cmp ax, 1
      je greaterxlen
      neg bx
   greaterxlen:
      mov [bp+6], bx

      ;***IF d1y% < 0 THEN yLen% = -yLength% ELSE yLen% = yLength%
      mov ax, [bp+12]         ;YLen=yLength*sgn(d1y)
      mov bx, si
      cmp ax, 1
      je greaterylen
      neg bx
   greaterylen:
      mov [bp+4], bx

      ;***IF XLen% <= YLen% THEN***
      mov ax, [bp+6]
      cmp ax, [bp+4]
      jns xlengreater

      ;******d2x% = 0***
      mov [bp+10], word ptr 0

      ;******d2y% = d1y%***
      mov ax, [bp+12]
      mov [bp+8], ax

      ;******IF d1y% < 0 THEN xLen% = -yLength% ELSE xLen% = yLength%***
      mov ax, [bp+12]
      mov bx, si
      cmp ax, 1
      je greaterxlen2
      neg bx
   greaterxlen2:
      mov [bp+6], bx

      ;******IF d1x% < 0 THEN yLen% = -xLength% ELSE yLen% = xLength%***
      mov ax, [bp+14]         ;YLen=xLength*sgn(d1y)
      mov bx, di
      cmp ax, 1
      je greaterylen2
      neg bx
   greaterylen2:
      mov [bp+4], bx

      ;***END IF***
   xlengreater:
      mov di, [bp+6]
      mov es, [bp+34]
      mov si, [bp+4]

      ;***FOR i% = 0 TO xLen%
      mov word ptr [bp], 0
      mov dl, [bp+22]         ;color
   nextlinepixel:
      ;******PSET (x%, y%), col%***
      mov bx, [bp+28]         ;BX=y
      cmp bx, 199
      ja linenotinscrn

      mov cx, [bp+30]         ;CX=x
      cmp cx, 319
      ja linenotinscrn

      mov al, bl              ;set up pixel address
      shl bx, 6
      add bh, al
      add bx, [bp+32]         ;+offset
      add bx, cx              ;+x
      mov es:[bx], dl         ;plot pixel

   linenotinscrn:
      ;******s% = s% + YLen%***
      mov ax, [bp+4]
      add [bp+2], ax

      ;******IF s% >= XLen% THEN***
      mov ax, [bp+6]
      cmp [bp+2], ax
      js secondcheck

      ;*********s% = s% - XLen%***
      mov ax, [bp+6]
      sub [bp+2], ax
      ;*********x% = x% + D1X%***
      mov ax, [bp+14]
      add [bp+30], ax
      ;*********y% = y% + D1Y%***
      mov ax, [bp+12]
      add [bp+28], ax
      jmp endcheck
      ;******ELSE***
   secondcheck:
      ;*********x% = x% + d2X%***
      mov ax, [bp+10]
      add [bp+30], ax
      ;*********y% = y% + d2Y%***
      mov ax, [bp+8]
      add [bp+28], ax
      ;******END IF***
   endcheck:
      ;***NEXT***
      inc word ptr [bp]
      mov ax, [bp+6]
      cmp [bp], ax
      jng nextlinepixel

      pop eax
      pop eax
      pop eax
      pop eax
      pop bp
      ret 14
VSLine endp

;=======This draws a box=====================================================
VSBox proc     ;segment, offset, x1, y1, x2, y2, color
      push ds
      push bp
      mov bp, sp

      mov ds, [bp+20]                 ;set segment

      cmp word ptr [bp+16], 319       ;is x1 past the screen?
      jg endbox
      cmp word ptr [bp+12], 0         ;is x2 past the screen?
      js endbox
      cmp word ptr [bp+14], 199       ;is y1 past the screen?
      jg endbox
      cmp word ptr [bp+10], 0         ;is y2 past the screen?
      js endbox

      cmp word ptr [bp+16], 0
      jns skipboxaddx1
      mov word ptr [bp+16], 0

   skipboxaddx1:
      cmp word ptr [bp+14], 0
      jns skipboxaddy1
      mov word ptr [bp+14], 0

   skipboxaddy1:
      cmp word ptr [bp+12], 319
      jng skipboxaddx2
      mov word ptr [bp+12], 319

   skipboxaddx2:
      cmp word ptr [bp+10], 199
      jng skipboxaddy2
      mov word ptr [bp+10], 199

   skipboxaddy2:
      xor bl, bl
      mov al, [bp+14]
      mov bh, al
      shl ax, 6
      mov cx, [bp+14]
      add bx, ax
      add bx, [bp+18]
      mov si, bx

      mov dl, [bp+8]
   startloop:
      mov bx, [bp+16]
   boxloop:
      mov [si+bx], dl
      inc bx
      cmp bx, [bp+12]
      jng boxloop

      add si, 320
      inc cx
      cmp cx, [bp+10]
      jng startloop

   endbox:
      pop bp
      pop ds
      ret 14
VSBox endp

end
