.model medium, basic
.stack 30h
.386
EXTRN gsclipx1:WORD
EXTRN gsclipy1:WORD
EXTRN gsclipx2:WORD
EXTRN gsclipy2:WORD
.code
public gsget
gsget proc
;gsget (x1,y1,x2,y2,fromseg,fromofs,toseg,toofs)
;stack:
;bp+22   x1
;bp+20   y1
;bp+18   x2
;bp+16   y2
;bp+14   fromseg
;bp+12   fromofs
;bp+10   toseg
;bp+8    toofs
;bp+6    retseg
;bp+4    retofs
;bp+2    bp
;bp      ds
;bp-2    clipping thingy
;bp-4    gsclipx1
;bp-6    gsclipy1
;bp-8    gsclipx2
;bp-10   gsclipy2
;bp-12   es

;important registers:
;es:di   the array
;ds:si   buffer (screen)

push bp
push ds

;

mov bp, sp   
mov bx, 0

push bx
mov ax, gsclipx1
                 
mov bx, gsclipx2
mov cx, gsclipy1

mov dx, gsclipy2
push ax

push cx
push bx

push dx
push es

mov es, [bp+10]
mov di, [bp+8]

mov ds, [bp+14]
mov si, [bp+12]

mov ax, [bp+16]
mov bx, [bp+20]

cmp ax, bx
jge noswapy

xchg ax, bx

mov [bp+16], ax
mov [bp+20], bx

noswapy:

mov cx, [bp+18]
mov dx, [bp+22]

cmp cx, dx
jge noswapx

xchg cx, dx

mov [bp+18], cx
mov [bp+22], dx

noswapx:

sub ax, bx
sub cx, dx

inc ax
inc cx

mul cx

mov cx, ax
mov dx, ax

shr cx, 2
and dx, 3

mov eax, 0
inc cx

rep stosd

cmp dx, 0
jz asdfghjl

mov cx, dx

rep stosb

asdfghjl:
;bx = x1, cx = 0, ax = 0, dx = width AND 3 
mov ax, [bp+18]
mov di, [bp+8]

sub ax, bx
mov dx, [bp+16]

mov cx, [bp+20]
inc dx

lea eax, [8*eax + 8]
sub dx, cx

mov es:[di], ax
mov es:[di+2], dx

;

shr ax, 3
add di, 4
;ok... ax = width, bx = x1, cx = y1, dx = height
;dx needs to be width, bx needs to be height, cx = right

;this is bad. Wow, I'm slacking off a lot here, but....
mov bx, dx
mov dx, ax

;blah :oP

cmp cx, [bp-10]
jg endofsolid

cmp cx, [bp-6]
jl toohighsolid

aftertoohighsolid:

lea ax, [ecx*4+ecx]

shl ax, 6

add si, ax
mov ax, cx

add ax, bx

cmp ax, [bp-10]
jg toolowsolid

aftertoolowsolid:
mov ax, [bp+22]

cmp ax, [bp-8]
jg endofsolid

cmp ax, [bp-4]
jl tooleftsolid

aftertooleftsolid:
add si, ax
add dx, ax

cmp dx, [bp-8]
jg toorightsolid

sub dx,ax
aftertoorightsolid:
mov cx,dx

;;;;;; ax = X, bx = height, cx = width, dx = width
and cx, 0000000000000011b
jnz solidwleftovers 

mov ax, dx

shr dx, 2

mov cx, dx
jmp solidloop

toohighsolid:
neg cx

add cx,[bp-6]

cmp cx, bx
jge endofsolid

toohighsolidloop:
add di, dx
dec bx

loop toohighsolidloop

mov cx,[bp-6]
jmp aftertoohighsolid

toolowsolid:
sub ax, [bp-10]

dec ax

sub bx, ax
jmp aftertoolowsolid

tooleftsolid:
neg ax

add ax,[bp-4]

cmp ax, dx
jge endofsolid

add di, ax
sub dx, ax

mov [bp-2], ax

mov ax,[bp-4]
jmp aftertooleftsolid

toorightsolid:
sub dx, [bp-8]

dec dx

add [bp-2], dx

mov dx, [bp-8]

inc dx

sub dx, ax
jmp aftertoorightsolid

solidloop:
rep movsd

add si, 320
mov cx, dx

add di, [bp-2]
sub si, ax

dec bx
jnz solidloop

jmp endofsolid

solidwleftovers:
shr dx, 2
jz smallstuff

mov ax, cx
mov cx, dx

solidwloop:
rep movsd

mov cx, ax

rep movsb

add si, 320
mov cx, dx

shl dx, 2
sub si, ax

add di, [bp-2]
sub si, dx

shr dx, 2
dec bx

jnz solidwloop
jmp endofsolid

smallstuff:
mov dx, cx
solidsloop:
rep movsb

mov cx, dx
add si, 320

add di, [bp-2]
sub si, dx

dec bx
jnz solidsloop

endofsolid:

pop es            
pop eax

pop ecx
pop bx

pop ds
pop bp

ret 16
gsget endp
end

