.model medium, basic
.stack 20h
.386
EXTRN gsclipx1:WORD
EXTRN gsclipy1:WORD
EXTRN gsclipx2:WORD
EXTRN gsclipy2:WORD
.code
public gsxput
gsxput proc
;stack
;bp+24   x1
;bp+22   y1
;bp+20   x2
;bp+18   y2
;bp+16   fromseg
;bp+14   fromofs
;bp+12   x3
;bp+10   y3
;bp+8    toseg
;bp+6    toofs
;bp+4    retseg
;bp+2    retofs
;bp      bp
;bp-2    ds
;bp-4    es
;ds:si   source
;es:di   destination

;neg eax = xor eax, ffffffffh / inc eax

push bp
mov bp, sp

mov cx, [bp+12]   ;cx = x3 
mov dx, [bp+10]   ;dx = y3

cmp cx, gsclipx2  ;if cx > clipx2 then end
jg endofput

cmp dx, gsclipy2  ;if dx > clipy2 then end
jg endofput

mov ax, [bp+24]   ;ax = x1
mov bx, [bp+20]   ;bx = x2

cmp ax,bx         
jle noswapx       ;if ax > bx then

xchg ax,bx        ;ax < bx now.

noswapx:
cmp ax, 0         ;if x1 < 0 then
jge x1good      

sub cx, ax        ;x3 = x3 - x1
mov ax, 0         ;x1 = 0

jmp x1small

x1good:
cmp ax, 320       ;if x1 > 320 then end
jge endofput

x1small:
cmp bx, 320       
jl x2good         ;if x2 >= 320 then

mov bx, 319       ;x2 = 319
jmp x2big

x2good:
cmp bx, 0         ;if bx < 0 then end
jl endofput

x2big:
cmp cx, gsclipx1  ;if x3 < clipx1 then
jge x3good

sub ax, cx        ;x1 =x1 + clipx1 - x3
mov cx, gsclipx1  ;x3 = clipx1

add ax, gsclipx1
x3good:

mov di, [bp+6]    ;di = destoffset
sub bx, ax        ;x2 = x2 - x1: bx = width -1

add di, cx        ;di = offset + x3
mov si, [bp+14]   ;si = sourceoffset

add si, ax        ;si = offset + x1
add cx, bx        ;cx = x3 + width - 1 = (x4)

cmp cx, gsclipx2  ;if x4 > clipx2 then
jle x4good

sub bx, cx        ;width = width - x4 + gsclipx2

add bx, gsclipx2
x4good:

cmp cx, gsclipx1
jl endofput

mov ax, [bp+22]   ;ax = y1
mov cx, [bp+18]   ;cx = y2

cmp ax, cx
jle noswapy

xchg ax, cx

noswapy:

cmp cx, 199
jle y2good

mov cx, 199
jmp y2bad

y2good:
cmp cx, 0
jl endofput

y2bad:
cmp ax, 0  
jge y1good  

sub dx, ax
xor ax, ax

y1good:
cmp ax, 199
jg endofput

;ax = y1, bx = width-1, cx = y2, dx = y3
cmp dx, gsclipy1
jge y3good 

add ax, gsclipy1
sub ax, dx

mov dx, gsclipy1
y3good:

push ax
push dx

shl dx, 2

add dx, [bp-4]

shl dx, 6

add di, dx
pop dx

shl ax, 2

add ax, [bp-2]

shl ax, 6

add si, ax
pop ax

sub cx, ax
inc bx

add dx, cx
inc cx

cmp dx, gsclipy2
jle y4good

sub cx, dx
mov dx, gsclipy2

add cx, dx
y4good:

cmp dx, gsclipy1
jl endofput

push ds
push es

mov ds, [bp+16]
mov es, [bp+8]

;cx = height
;bx = width
;es, di, ds, si are set

;heeeerrewego! :o)

mov dx, cx
mov cx, bx

shr bx, 2
jz smalll

mov al, bl
mov bx, cx

xor bx, 0ffffh
and cx, 3

mov ah, cl
jz clean

add bx, 321

messyloop:
rep movsb

mov cl, al

rep movsd

add si, bx
add di, bx

mov cl, ah
dec dx

jnz messyloop
jmp endofput1

clean:
add bx, 321
mov cl, al
cleanloop:
rep movsd
add si, bx
add di, bx

mov cl, al
dec dx

jnz cleanloop
jmp endofput1

smalll:
;dx = height
;cx = width
mov bx, cx
and cx, 3

xor bx, 0ffffh
mov al, cl

add bx, 321

smallloop:
rep movsb

add di, bx
add si, bx

mov cl, al
dec dx

jnz smallloop

endofput1:

pop es
pop ds

endofput:

pop bp
ret 20

gsxput endp
end
