; File handling sample. Three strings are defined. myline - when a new file is created, this will 
;                       be written into it. newline - when the file already exists, this will be 
;                       added to it. readline - is used for whatever is in the file (40 bytes)

IDEAL
MODEL small
STACK 100h
DATASEG

filename      db  'file1.txt',0  ;file name must end with a zero
filehandle    dw  ?
line1         db  ' About to write into a file for the first time',10,13,'$' 
myline        db  'abcdefg$' 
newline       db  'hijklmn$' 
readline      db  '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$'
numofbytes    equ 40
CODESEG
;-----------------------------------------------------------------------------------------------------
proc          len
              push si                 ;preserve si
              xor  dx,dx
              xor  al,al
checkch:      mov  al,[si]
              cmp  al,'$'
              je   returnlen 
              inc  si
              inc  dx 
              jmp  checkch
returnlen:    pop  si                  ;restore si
              ret
endp          len 
;----------------------------------------------------------------------------------------------------- 

proc          createfile 
              mov bx,1                 ; bx=1 means create failed
              mov ah,3Ch
              mov cx,0              
              mov dx, offset filename
              int 21h 
              jc  nosuccess            ;if the carry flag (CF) is 1 - error occurred (jumps if CF=1)
              mov bx,0
              mov [filehandle],ax    
nosuccess:    ret
endp          createfile
;-----------------------------------------------------------------------------------------------------
proc          openfile                 ; bx=0 open succeeded, bx=1 file does not exist
              mov  bx,0                ; bx=2  other error with the file
              mov  ah,3Dh
              mov  al,2                ;open the file for read/write
              lea  dx,[filename]
              int  21h
              jc   openerror           ;if the carry flag (CF) is 1 - error occurred (jumps if CF=1)
              mov  [filehandle],ax
              ret
openerror:  
              mov   bx,1
              cmp   ax,2               ; ax==2 File not found
              je    endit
              mov   bx,2               ; Other error than file not found             
endit:        ret
endp          openfile
;-----------------------------------------------------------------------------------------------------
proc          readfile
              mov ah,3Fh
              mov bx,[filehandle]
              mov cx, numofbytes       ;max number of bytes to read
              mov dx,offset readline   ;readline must be equal or longer than file content
              int 21h                  ;ax contains number of bytes actually read (we do nothing with it)
readok:       ret                      
endp          readfile 
;-----------------------------------------------------------------------------------------------------
proc          writefile         ; Receives 2 parameters - how many bytes to write and area to write it
              push bp
              mov  bp,sp
              mov  ah,40h
              mov  bx,[filehandle]
              mov  cx,[bp+6]           ; length of line to write
              mov  dx,[bp+4]           ; offset of line (area to write)
              int  21h
              pop  bp
              ret  2  
endp          writefile 
;-----------------------------------------------------------------------------------------------------
proc          closefile
              mov ah,3Eh
              mov bx,[filehandle]
              int 21h
              ret  
endp          closefile 
;-----------------------------------------------------------------------------------------------------

start:
	mov ax, @data
	mov ds, ax
	
              call openfile              ; check if file exists                                       
              cmp  bx,2                  ; fatal error (other than file NF) - just end gracefully.
              je   exit
              cmp  bx,1                  ;bx=1  file not found
              je   createit
              call readfile              ;file exists (read it into newline) 
              mov  dx, offset readline   ;print to the screen file content
              mov  ah,9h
              int  21h                     
;erase, re-create the file.
;              mov  dx,offset filename 	 
;              mov  ah,41h 	        	  ; function 41h - delete file (if we want to override)
;              int  21h 		              
;              call createfile                
              mov  si, offset newline     ; calculate size of string to write
              call len                    ; puts the length of newline in dx
              push dx  
              push si      
              call writefile          
              jmp  cls                        
createit:                                   
              call createfile 
              mov  dx, offset line1       ; announcement
              mov  ah,9h
              int  21h  
              mov  si, offset myline
              call len                 
              push dx                     ;puts the length of myline in dx
              push si                                                 
              call writefile              ;writes a line whose offset loaded into si
              jmp  cls                             
cls:          call closefile 
	
exit:
	mov ax, 4c00h
	int 21h
END start