;*****************************************************************************
;PutImage
;
;this routine was developed by Martin and Milan Hrdlicka
;writes image (bit map) into VIDEO RAM
;may refresh the image directly
;
;Image is a raw bit map:
;1. First 4 bytes are a header
;2. The rest is data
;
;INPUT
;		CS:SI	- pointer to image data
;		BH	- function (mixing the image with background)
;				- 0	replace
;				- 1	xor
;				- 2	or
;				- 3	and
;
;		BL	- direct refresh
;				- 0	no refresh (must be refreshed later)
;				- 1	with LCD refresh
;		CX	- x co-ordinate (horizonal)
;               DX	- y co-ordinate (vertical)
;
;
;OUTPUT		none
;DESTROYS	flags
;***************************************************************************

       
PutImage:
		push    si
                push    cx
                push    dx
		mov 	[ref],bl
                call    putimagest
                pop     dx
                pop     cx
                pop     si
                ret


putimgbuf       db     96 dup (0)
Xvel            dw      0
Yvel            dw      0
Xmem            dw      0
Radek           dw      0
BituLev         db      0
BituPrav        db      0
UpravMem        db      0
ref		db	0	;1 - refresh permitted


ven:
		cmp b[ref],0
		if z ret

	        push    ax
                push    dx
                cli
                mov     dx,8011h
                xchg    ah,al
                out     dx,al
                mov     dx,8010h
                xchg    ah,al
                out     dx,al
                sti
                pop     dx
                pop     ax
                ret



putimg_nulb:    push    ax
                push    cx
                push    es
                mov     cx,ds
                mov     es,cx
                mov     al,0
                mov     cx,90
                mov     di,offset putimgbuf
                rep
                stosb
                pop     es
                pop     cx
                pop     ax
                ret


MovImgBuf:      push    cx
                push    es
                mov     cx,ds
                mov     es,cx
                mov     cx,word ptr ds:[offset Xmem]
                mov     di,offset putimgbuf
                rep
                movsb
                pop     es
                pop     cx
                ret


ShRImgBufJ:     push    cx
                push    ax
shrimgbufj_1:   mov     di,offset putimgbuf
                mov     cx,word ptr ds:[offset Xmem]
                inc     cx
                clc
shrimgbufj_2:   rcr     byte ptr ds:[di],1
                inc     di
                loop    shrimgbufj_2
                dec     ah
                jnz     shrimgbufj_1
                pop     ax
                pop     cx
                ret


ShRImgBufH:     push    cx
                push    si
                push    ax
                mov     cx,word ptr ds:[offset Xmem]
                inc     cx
                mov     si,offset putimgbuf
                add     si,cx
                mov     di,si
                mov     ah,0
                inc     cx
                add     di,ax   ; v AH je 0, v AL je hruby pocet
shrimgbufh_1:   mov     al,ds:[si]
                mov     ds:[di],al
                mov     ds:[si],ah
                dec     si
                dec     di
                loop    shrimgbufh_1
                inc     di
                pop     ax
                pop     si
                pop     cx
                ret


OutRadek:       mov     ax,di
                push    ax
                mov     ah,0ah
                call    ven
                pop     ax
                xchg    ah,al
                mov     ah,0bh
                call    ven
outradek_1:     mov     al,es:[di]
                inc     di
                shr     al,1
                rcl     ah,1
                shr     al,1
                rcl     ah,1
                shr     al,1
                rcl     ah,1
                shr     al,1
                rcl     ah,1
                shr     al,1
                rcl     ah,1
                shr     al,1
                rcl     ah,1
                shr     al,1
                rcl     ah,1
                shr     al,1
                rcl     ah,1  ; AL<-0, AH zrc AL
 
		push ax
		mov al,ah
		mov ah,0c
		call	ven
		pop ax

                loop    outradek_1
putimg_kon1:    ret


putimagest:     cld        ; Vstup: CX - x  DX - y  DS:SI - pointer
                cmp     cx,239
                jg      putimg_kon1  ; out of X
                cmp     dx,63
                jg      putimg_kon1  ; out of Y
                lodsw                ; do AX Xvel
                mov     word ptr ds:[offset Xvel],ax
                or      cx,cx
                jns     putimg_dal1  ; kdyz CX lezi v disp tak skoc
                add     ax,cx
                js      putimg_kon1  ; podout of X
putimg_dal1:    lodsw                ; do AX Yvel
                mov     word ptr ds:[offset Yvel],ax
                or      dx,dx
                jns     putimg_dal2  ; kdyz DX lezi v disp tak skoc
                add     ax,dx
                js      putimg_kon1

putimg_dal2:    mov     ax,ds:[offset Xvel]
                inc     ax
                mov     bl,8
                div     bl
                or      ah,ah
                jz      putimg_dal3
                inc     al
putimg_dal3:    mov     ah,0
                mov     word ptr ds:[offset Xmem],ax   ; ulozi delku jednoho radku
putimg_smc1:    or      dx,dx
                jns     putimg_dal4    ; DX>=0
                inc     dx
                dec     word ptr ds:[offset Yvel]
                add     si,ax
                jmp     short putimg_smc1
putimg_dal4:    mov     ax,dx
                add     ax,word ptr ds:[offset Yvel] ; do AX Ysour dol hrany
putimg_smc2:    cmp     ax,63
                jbe     putimg_dal5
                dec     ax
                dec     word ptr ds:[offset Yvel]
                jmp     short putimg_smc2
putimg_dal5:    add     cx,240
                mov     ax,cx
                mov     bl,8
                div     bl          ; AH jemne, AL hrube
                inc     word ptr ds:[offset Yvel]
                push    es
                mov     bp,0b000h
                mov     es,bp       ; do ES seg VideoRAM
putimg_smc3:    call    PutImg_NulB
                call    MovImgBuf
                or      ah,ah
                jz      putimg_dal6
                call    ShRImgBufJ
putimg_dal6:    call    ShRImgBufH  ; DS:DI adresa 1.byte v ImgBuf
                push    si
                push    ax
                push    cx
                push    dx
                mov     ds:[offset BituLev],ah
                mov     bl,ah
                mov     ax,word ptr ds:[offset Xvel]
                inc     ax
                add     al,bl
                adc     ah,0
                mov     bl,8
                div     bl
                or      ah,ah
                jnz     @putimg2
                dec     al
@putimg2:       mov     ds:[offset UpravMem],al
                or      ah,ah
                jz      @putimg1
                sub     bl,ah
                mov     ah,bl
@putimg1:       mov     ds:[offset BituPrav],ah
                mov     bp,di
                mov     ax,dx
                mov     bl,30
                mul     bl
                mov     di,ax                   ; v DI adresa DX-teho radku
                xor     cx,cx
                sub     bp,offset PutImgBuf+30
                js      Putimg_znv1    ; Zacatek nelezi ve Video
                add     di,bp          ; do DI adresu Video kam se bude strkat
                mov     ch,es:[di]
                jmp     short putimg_dal7
PutImg_ZNV1:    mov     ah,0           ; zacatek nelezi ve videoRAM
                mov     ds:[offset BituLev],ah
                mov     al,ds:[offset UpravMem]
                add     ax,bp
                mov     ds:[offset UpravMem],al
                xor     bp,bp
PutImg_dal7:    mov     ah,0
                mov     al,ds:[offset UpravMem]
                add     bp,ax
                cmp     bp,29
                ja      PutImg_knv1  ; konec nelezi ve video
                push    di
                add     di,ax
                mov     cl,es:[di]  ; do CL "posl" byte z video
                pop     di
                jmp     short putimg_dal8
PutImg_KNV1:    mov     ah,0
                mov     ds:[offset BituPrav],ah
                mov     al,ds:[offset UpravMem]
                sub     bp,29
                sub     ax,bp
                mov     bp,29
                mov     ds:[offset UpravMem],al
PutImg_dal8:    add     bp,30+offset putimgbuf  ; DS:BP ukazuje na pos rel byte
                cmp     bh,1
                jz      putimg_XOR
                cmp     bh,2
                jz      putimg_OR
                push    cx
                mov     dx,0ffffh
                mov     cl,ds:[offset BituLev]
                shr     dh,cl
                mov     cl,ds:[offset BituPrav]
                shl     dl,cl
                not     dx
                pop     cx
                cmp     bh,3
                jz      putimg_AND
                and     cl,dl      ; PutImg_MOV
                or      ds:[bp],cl   ; upravi pravou stranu IMG
                push    bp
                xor     ax,ax
                mov     al,ds:[offset UpravMem]
                sub     bp,ax
                and     ch,dh
                or      ds:[bp],ch  ; upravi levou stranu IMG
                mov     cx,ax
                inc     cx
                pop     si
                push    cx
                push    di
                add     di,cx
                dec     di
                std
                rep
                movsb
                cld
                pop     di
                pop     cx
                jmp     PutImg_dal9
PutImg_XOR:     mov     si,bp
                xor     cx,cx
                mov     cl,ds:[offset UpravMem]
                inc     cx
                push    cx
                push    di
                add     di,cx
                dec     di
Putimg_xor1:    mov     al,ds:[si]
                xor     es:[di],al
                dec     si
                dec     di
                loop    putimg_xor1
                pop     di
                pop     cx
                jmp     PutImg_dal9
PutImg_OR:      mov     si,bp
                xor     cx,cx
                mov     cl,ds:[offset UpravMem]
                inc     cx
                push    cx
                push    di
                add     di,cx
                dec     di
Putimg_or1:     mov     al,ds:[si]
                or      es:[di],al
                dec     si
                dec     di
                loop    putimg_or1
                pop     di
                pop     cx
                jmp     PutImg_dal9
Putimg_AND:     or      ds:[bp],dl
                push    bp
                xor     cx,cx
                mov     ch,ds:[offset UpravMem]
                sub     bp,cx
                or      ds:[bp],dh
                inc     cx
                pop     si
                push    cx
                push    di
                add     di,cx
                dec     di
Putimg_and1:    mov     al,ds:[si]
                and     es:[di],al
                dec     si
                dec     di
                loop    putimg_or1
                pop     di
                pop     cx
PutImg_dal9:    call    OutRadek
                pop     dx
                pop     cx
                pop     ax
                pop     si
                inc     dx
                dec     word ptr ds:[offset Yvel]
                jz      putimg_dal10
                jmp     putimg_smc3
putimg_dal10:   pop     es
                ret


;-------------- end of routine PutImage ---------------------------------