; ****************************************************************************
; FILECOPY.ASM (by Erdogan Tan)
;
; Test program for
; INT 21h Function 3Dh, Open File, INT 21h Function 3Eh, Close File
; INT 21h Function 3Fh, Read File, INT 21h Function 40h, Write File
;
; 07/05/2011
;
; ****************************************************************************


CODE_SEG_1	segment para public
		assume  CS:CODE_SEG_1, DS:CODE_SEG_1, SS:CODE_SEG_1, ES:CODE_SEG_1

		org	100h

proc_start	proc	far

start:
                mov si, offset 80h
                lodsb
                cmp al, 0
                ja short loc_scan_source_file_name
loc_print_bad_command_or_file_name:
                mov si, offset msg_bad_command_or_filename
                call proc_printmsg
                jmp loc_print_next_line

loc_scan_source_file_name:
loc_scan_source_file_name_next:
                inc si
                cmp byte ptr [SI], 20h
                je short loc_scan_source_file_name_next
                jb short loc_print_bad_command_or_file_name
    
                mov di, offset SourceFile_Name
                mov cx, 64
loc_copy_sfound_file_name_chr0:
                lodsb
                cmp al, 20h
                ja short loc_copy_sfound_file_name_chr1
                jb short loc_print_bad_command_or_file_name   
pass_copy_sfound_file_name_chr0:
                mov byte ptr [DI], 0
                jmp short loc_scan_destination_file_name
loc_copy_sfound_file_name_chr1:
                mov byte ptr [DI], al
                inc di
                loop loc_copy_sfound_file_name_chr0
                cmp byte ptr [SI], 20h
                jne short loc_print_bad_command_or_file_name

loc_scan_destination_file_name_next:
                inc si  
loc_scan_destination_file_name:
                cmp byte ptr [SI], 20h
                je short loc_scan_destination_file_name_next
                jb short loc_print_bad_command_or_file_name

                mov di, offset DestinationFile_Name
                mov cx, 64
loc_copy_dfound_file_name_chr0:
                lodsb
                cmp al, 20h
                ja short loc_copy_dfound_file_name_chr1 
pass_copy_dfound_file_name_chr0:
                mov byte ptr [DI], 0
                jmp short loc_copy_file
loc_copy_dfound_file_name_chr1:
                mov byte ptr [DI], al
                inc di
                loop loc_copy_dfound_file_name_chr0
                cmp byte ptr [SI], 20h
                ja short loc_print_bad_command_or_file_name
loc_copy_file:
                mov si, offset msg_Src_FileName
                call proc_printmsg
                mov si, offset msg_Dest_FileName
                call proc_printmsg
                mov si, offset NextLine
                call proc_printmsg

loc_open_source_file:
		mov dx, offset SourceFile_Name
                mov ah, 3Dh ; MS DOS Function = Open File
                xor al, al  
                int 21h
                jc short loc_print_error_1

loc_save_source_file_handle:
                mov word ptr [SrcFile_Handle], ax

loc_create_destination_file:
                mov dx, offset DestinationFile_Name
                mov ah, 3Ch ; MS DOS Function = Create File
                xor cx, cx ; File attribute = 0 
                int 21h
                jc short loc_print_error_2

loc_save_destination_file_handle:
                mov word ptr [DestFile_Handle], ax

loc_read_source_file:
                mov ah, 3Fh ; Read File
                mov cx, 512
                mov dx, offset R_W_BUFFER
                mov bx, word ptr [SrcFile_Handle]
                int 21h
                jc short loc_print_error_3
                
loc_write_destination_file:
                ; ax = byte count
                or ax, ax
                jz short loc_close_destination_file
                mov cx, ax 
                mov ah, 40h ; Write File
                mov dx, offset R_W_BUFFER
                mov bx, word ptr [DestFile_Handle]
                int 21h
                jc short loc_print_error_3
             
loc_copy_next_file_block:
                cmp ax, 512 ; written bytes (<512 --> EOF)
                jnb short loc_read_source_file
                                
loc_close_destination_file:
                mov ah, 3Eh ; Close File
                mov bx, word ptr [DestFile_Handle]
                mov word ptr [DestFile_Handle], 0
                int 21h
                jc short loc_print_error_4

loc_close_source_file:
                mov ah, 3Eh ; Close File
                mov bx, word ptr [SrcFile_Handle]
                mov word ptr [SrcFile_Handle], 0
                int 21h
                jc short loc_print_error_4

                cmp byte ptr [Error], 0
                ja short loc_print_next_line                 

                mov si, offset msg_OK
                call proc_printmsg
                jmp short loc_print_next_line
                
loc_print_error_1:
loc_file_not_found_error:
                cmp ax, 2
                jne short loc_path_not_found_error
                mov si, offset msg_file_notfound
                jmp short loc_print_error_msg 
loc_print_error_2:
loc_path_not_found_error:  
                cmp ax, 3
                jne short loc_too_many_open_files_error
                mov si, offset msg_path_notfound
                jmp short loc_print_error_msg
loc_too_many_open_files_error:
                cmp ax, 4
                jne short loc_access_denied_error
                mov si, offset msg_too_many_open_files
                jmp short loc_print_error_msg 
loc_print_error_3:
loc_access_denied_error:
                cmp ax, 5
                jne short loc_invalid_handle_error
                mov si, offset msg_access_denied
                jmp short loc_print_error_msg 
loc_print_error_4:
loc_check_invalid_handle_error:
                cmp ax, 6
                je short loc_invalid_handle_error
loc_unknown_error:
                mov si, offset msg_unknown_error
                jmp short loc_print_error_msg

loc_invalid_handle_error:
                mov si, offset msg_invalid_handle

loc_print_error_msg:
                push si
                mov si, offset NextLine
                call proc_printmsg
                pop si
                call proc_printmsg

                inc byte ptr [Error]
  
                cmp word ptr [DestFile_Handle], 0
                ja short loc_close_destination_file
                cmp word ptr [SrcFile_Handle], 0
                ja short loc_close_source_file

loc_print_next_line:
                mov si, offset NextLine
                call proc_printmsg
exit:
                int 20h

proc_start	endp


proc_printmsg   proc near

                ; INPUT: DS:SI -> ASCIIZ string 
loc_print:          
		lodsb				
                and al, al            
                je short loc_return 
		mov ah, 0Eh			
                mov bx, 07h             
		int 10h				
			
                jmp short loc_print           
loc_return:
                retn

proc_printmsg   endp

msg_Src_FileName::
                db 0Dh,0Ah
                db 'Source File: '
SourceFile_Name: db 64 dup (0)
                dw 0
msg_Dest_FileName:
                db 0Dh,0Ah
                db 'Destination File: '
DestinationFile_Name: db 64 dup (0)
                dw 0
 
msg_OK:         db 0Dh, 0Ah
                db 'OK ... '
                db 0

NextLine:       db 0Dh,0Ah,0h

msg_bad_command_or_filename: db "Bad command or file name !", 0
msg_file_notfound: db "File not found !", 0
msg_path_notfound: db "Path not found !", 0
msg_too_many_open_files: db "Too many open files !", 0
msg_access_denied: db "Access denied !", 0
msg_invalid_handle: db "Invalid handle !", 0
msg_unknown_error: db "File Read/Write Error !", 0

SrcFile_Handle: dw 0
DestFile_Handle: dw 0

Error: db 0

r_w_buffer:     db 512 dup (0)


CODE_SEG_1	ends

		end	start
