;open_file
;input: ds:dx-->filename (asciiz)
;output: file handle in BP, file size in EDX

open_file proc near
        push    ds
        push    es

        pop     ds
        mov     ax, 3d00h
        int     21h              ; Openfile
        pop     ds

        jc      Fileerr
        mov     bp, ax            ; save handle in BP

        xor     cx, cx            ; Read length of file
        xor     dx, dx            ;
        mov     bx, bp            ; file handle from BP
        mov     ax, 4202h         ;
        int     21h               ;

        shl     edx, 16           ; EDX = 32 bit file length
        mov     dx, ax            ;
        clc
        ret

Fileerr:
        push    cs
        pop     ds
        mov     dx,offset Filemess
        mov     ah,9
        int     21h
        stc
        mov     ah, 1                   ; errorlevel
        ret
        
Filemess        db      "Error: File not found!",CR,LF,"$"


open_file endp





close_file proc near
                mov     bx,bp            ;file handle from BP
                mov     ax,3e00h
                int     21h              ;close file
                ret
close_file endp




; loads a file into high mem.
; gs:edi point to target buffer
; lame byte moves are done here...
; edx=file size
load_image proc near
                push    edx
                xor     cx,cx            ; Reset file pointer
                xor     dx,dx            ;
                mov     bx,bp            ; file handle from BP
                mov     ax,4200h         ;
                int     21h              ;


                pop     edx

                mov     ecx,edx            ; Calculate number of times
                shr     ecx,15             ; to load 32Kb
                inc     cx                 ;

                lea     dx,endflag         ; DS:DX=buffer "scratch" area
                add     dx, 16*1024


Loadloop:
                shl     ecx, 16            ; save 32k counter   
                                           ; Load 32Kb
                mov     cx,32*1024         ;
                mov     ax,3f00h           ;
                int     21h                ;

                mov     cx,ax              ; Number of bytes read
                or      cx,cx
                jz      Nodata             ; If nothing is read then quit

                lea     si, endflag
                add     si, 16*1024

low2high:
                lodsb
                mov     gs:byte ptr [edi],al
                inc     edi
                dec     cx
                jnz     low2high


                shr     ecx, 16            ; grab next 32k chunk
                dec     cx
                jnz     Loadloop

Nodata:                                    ; File is loaded now
        ret
load_image endp




; saves high mem to file
; lame byte moves are done here...
; copy 32k chunks from high mem to low mem, save chunks to disk
; ds:dx points to asciiz filename upon entry.
; assumes es=cs=ds upon entry
save_image proc near


        push    bp

        mov     al, 1                   ; open up the file 
        mov     cx, ARCHIVE             ; attributes
        mov     ah, 3ch       
	int     21h
        jc      save_error              
        mov     bp, ax                  ; handle to Bp

        mov     esi, DISK_START
        mov     edx, gs:[esi]           ; get disk size

        add     esi, 8                  ; point to 1st byte of image



saveloop:
        lea     di, endflag
        add     di, 16*1024
        mov     ecx, (32*1024)      ; copy 32k to low mem.

high2low:
        mov     al, gs:byte ptr [esi]
        stosb
        add     esi, 1
        sub     cx, 1
        jnz     high2low

        mov     cx, 32 * 1024           ; assume write of 32k
        sub     edx, ecx                ; remove 32k from buffer
        jnc     write_file
        add     edx, ecx                ; 32k is too big
        mov     cx, dx                  ; only write what's left of file.


write_file:

        ; got bytes in low memory, write it to disk
        push    edx
        lea     dx, endflag             ; DS:DX=buffer "scratch" area
        add     dx, 16*1024             ; point beyond save screen data

        mov     ah, 40h
        mov     bx, bp
        int     21h                     ; write data
        pop     edx
        jc      save_error

        cmp     cx, 32*1024
        jz      saveloop

        call    close_file
        pop     bp
        ret

save_error:
        push    cs
        pop     ds
        mov     dx,offset savemess
        mov     ah,9
        int     21h
        stc
        mov     ah, 1                   ; errorlevel
        pop     bp
        ret
        
savemess        db      "Error writing file!",CR,LF,"$"

save_image endp
