;
;		Vision Factory
; 		Gif Loader
;
; 	Base version
; 	(w) by Atan (Matthias Rasch)
;		compiled on 11/13/93
;
; 	loads Gif image 320*200 in mode 13h
; 	see main program for call
.286

	clr=256
	eof=257
  w equ word ptr
  b equ byte ptr

;codeg group code
code segment public
assume cs:code,ds:code
public loadgif
public setpal
public blackpal
public dealloc
extrn p13_2_modex:near
extrn picture:byte

GifRead proc pascal n:word
  push ds
  mov ax,cs
  mov ds,ax
  mov es,ax
  lea di,buf
  lea si,picture
  add si,w picpos
  mov cx,word ptr n
  rep movsb
  mov ax,n
  add w picpos,ax
  pop ds
  ret
endp
GifSeekdelta proc pascal delta:dword
  mov ax,04200h
  mov bx,w handle
  mov cx,word ptr delta + 2
  mov dx,word ptr delta
  int 21h
  ret
Endp
ShiftPal proc pascal
  push ds
  mov ax,cs
  mov es,ax
  mov ds,ax

  mov si,offset Buf
  mov di,offset Palette
  mov cx,768
@l1:
  lodsb
  shr al,2
  stosb
  loop @l1
  pop ds
  ret
Endp
FillBuf proc pascal
  push 1
  call gifread
  mov al,b buf[0]
  xor ah,ah
  mov w restbyte,ax
  push ax
  call gifread
  ret
Endp

GetPhysByte proc pascal
  push bx
  cmp w restbyte,0
  ja @restthere
  pusha
  push es
  call fillbuf
  pop es
  popa
  mov w bufind,0
@restthere:
  mov bx,w BufInd
  mov al,b Buf[bx]
  inc w bufind
  pop bx
  ret
Endp

GetLogByte proc pascal
  push si
  mov ax,w width1
  mov si,ax
  mov dx,w restbits
  mov cx,8
  sub cx,dx
  mov ax,w lByte
  shr ax,cl
  mov w cur_code,ax
  sub si,dx
@nextbyte:
  call getphysbyte
  xor ah,ah
  mov w lByte,ax
  dec w restbyte

  mov bx,1
  mov cx,si
  shl bx,cl
  dec bx
  and ax,bx

  mov cx,dx
  shl ax,cl
  add w cur_code,ax

  sbb dx,w width1
  add dx,8
  jns @positive
  add dx,8
@positive:
  sub si,8
  jle @finished
  add dx,w width1
  sub dx,8
  jmp @nextbyte
@finished:
  mov w restbits,dx
  mov ax,w cur_code
  pop si
  ret
Endp
err_mem db 'not enough memory$'
getvmem proc pascal
  mov ax,cs
  mov es,ax
  mov bx,20000d
  mov ah,4ah
  int 21h

  mov ah,48h
  mov bx,2001d 			;(32000/16+1)
  int 21h
  jae ok			;jump, if carry 0

  mov ax,3
  int 10h
  mov ax,cs
  mov ds,ax
  mov ah,9
  mov dx,offset err_mem
  int 21h
  mov ah,4ch
  mov al,1
  int 21h
ok:
  mov word ptr vscreen+2,ax
  ret
getvmem endp
dealloc proc pascal
  mov ah,49h
  les di,cs:dword ptr vscreen
  int 21h
  ret
dealloc endp



LoadGif proc pascal
  push ds
  mov ax,cs
  mov ds,ax

;  call GifOpen
;  push 0
;  push 13
;  call gifseekdelta
  push 768
  call gifread
  call shiftpal
  push 1
  call gifread

@extloop:
  cmp w buf[0],21h
  jne @noext
  push 2
  call gifread
  mov al,b buf[1]
  inc al
  xor ah,ah
  push ax
  call gifread
  jmp @extloop
@noext:
  push 10
  call gifread
  test b buf[8],128
  je @noloc
  push 768
  call gifread
  call shiftpal
@noloc:
  mov w lbyte,0
  call getvmem
  les di,dword ptr vscreen

  mov w free,258
  mov w width1,9
  mov w max,511
  mov w stackp,0
  mov w restbits,0
  mov w restbyte,0
@mainloop:
  call getlogByte
  cmp ax,eof
  jne @no_abort
  jmp @abort
@no_abort:
  cmp ax,clr
  jne @no_clear
  jmp @clear
@no_clear:
  mov w readbyt,ax
  cmp ax,w free
  jb @code_in_ab
  mov ax,w old_code
  mov w cur_code,ax
  mov bx,w stackp
  mov cx,w specialcase
  mov w abstack[bx],cx
  inc w stackp
@code_in_ab:
  cmp ax,clr
  jb @concrete
@fillstack_loop:
  mov bx,w cur_code
  shl bx,1
  push bx
  mov ax,w ab_tail[bx]
  mov bx,w stackp
  shl bx,1
  mov w abstack[bx],ax
  inc w stackp
  pop bx
  mov ax,w ab_prfx[bx]
  mov w cur_code,ax
  cmp ax,clr
  ja @fillstack_loop
@concrete:
  mov bx,w stackp
  shl bx,1
  mov w abstack[bx],ax
  mov w specialcase,ax
  inc w stackp
  mov bx,w stackp
  dec bx
  shl bx,1
@readstack_loop:
  mov ax,w abstack[bx]
		stosb
  cmp di,32003
    jbe @noovl1
    call p13_2_modex pascal,0,8001
    les di,dword ptr vscreen
@noovl1:
    dec bx
    dec bx
    jns @readstack_loop
    mov w stackp,0
    mov bx,w free
    shl bx,1
    mov ax,w old_code
    mov w ab_prfx[bx],ax
    mov ax,w cur_code
    mov w ab_tail[bx],ax
    mov ax,w readbyt
    mov w old_code,ax
    inc w free
    mov ax,w free
    cmp ax,w max
    ja @no_mainloop
    jmp @mainloop
	@no_mainloop:
    cmp b width1,12
    jb @no_mainloop2
    jmp @mainloop
  @no_mainloop2:
    inc w width1
    mov cl,b width1
    mov ax,1
    shl ax,cl
    dec ax
    mov w max,ax
    jmp @mainloop
  @clear:
    mov w width1,9
    mov w max,511
    mov w free,258
    call getlogbyte
    mov w specialcase,ax
    mov w old_code,ax
		stosb
    cmp di,32003
    jbe @noovl2
    call p13_2_modex pascal,0,8001
		les di,dword ptr vscreen
@noovl2:
    jmp @mainloop
  @abort:
	call dealloc
;	  call gifclose;
  pop ds
  ret
Endp

SetPal proc pascal
  push ds
  push si
  mov ax,cs
  mov ds,ax
  mov si,offset palette
  mov cx,256*3
  xor al,al
  mov dx,03c8h
  out dx,al
  inc dx
@lp:
  rep outsb
  pop si
  pop ds
  ret
Endp
blackpal proc pascal
	mov ax,cs
  mov es,ax
  lea di,palette
  mov cx,256*3/2
  mov ax,0
  rep stosw
  ret
Endp

	handle: 	dw 0
	Buf: 			db 768 dup (0)
  BufInd: 	dw 0
  abStack:	db 1281 dup (0)
  ab_prfx:	dw 2049 dup (0)
	ab_tail:	dw 2049 dup (0)
  byte1:                db 0
  free:			dw 0
	width1:		dw 0
	max:			dw 0
	stackp:		dw 0
	restbits: dw 0
	restbyte: dw 0
	specialcase: dw 0
  cur_code: dw 0
	old_code: dw 0
	readbyt: 	dw 0
	bits:			dw 0
	bits2get: dw 0
  lbyte:		dw 0
  GifName:	db 'logo_st.gif',0
  Palette:	db 768 dup (0)
  extrn vscreen:dword
  picpos:		dw 13

;locdata ends
code ends
;Note: If it doesn't work with really complex images,
;	please report it, extensive changes in the memory management
; necessary. Need to save memory.
end

