
statline   db  13,'Writing cylinder ',0
statline1  db  ' of ',0

are_sure_str   db  13,10,10,' *** WARNING *** all data on floppy disk will be lost.'
               db  13,10,' Continue? [Y/N] ',0

abort_str      db  13,10,' User abort...',0

bad_drive_str  db 13,10,' Drive letter must be A: or B:',0
bad_drive_str1 db 13,10,' Drive '
bad_drive_let  db ' '
               db ': does not exist',0

; the type strings must remain 32 bytes each
type_string    db  13,10,' Drive Type: ',0
type_str       db  ' * unknown *                   ',0
               db  ' 360-Kb, 5.25-inch             ',0
               db  ' 1.2-Meg, 5.25-inch            ',0
               db  ' 720-Kb, 3.50-inch             ',0
               db  ' 1.44-Meg, 3.50-inch           ',0
               db  ' * unknown *                   ',0
               db  ' 2.88-Meg, 3.50-inch           ',0
type_heads     db  13,10,'      Heads: ',0
type_spt       db  13,10,'        SPT: ',0
type_cyl       db  13,10,'  Cylinders: ',0

heads          dw  0
spt            dw  0
cylinders      dw  0

no_file_str    db 13,10,' Did not find given filename...',0
fnd_file_str   db 13,10,' Found file: ',0
file_size_str  db 13,10,'  File size: ',0

size_match_str db 13,10," Size of image doesn't match disk drive:  ",0
not_equal_str  db ' != ',0
file_size      dd  0

spinup_str     db 13,10,'Waiting for disk to spin up...'
               db 13,10,'Please note, if you are running this in a DOS box under Windows,'
               db 13,10,' and this installer seems to freeze at this point, it may be that'
               db 13,10,' Windows is not allowing you to have direct access to the disk.'
               db 13,10,' Please switch to the Windows Desktop (Alt+Tab) and see if there'
               db 13,10,' is a message box displayed.',13,10,0
spaces_str     db 13,'                                 ',0

MErrorS    db  13,10,10,'**** Error reading file/writing to disk ****',0
SuccessS   db  13,10,'Successfull',0




; ===========================================================================
cmdparams proc far
; ES:DI -> BUFFER,NUL,NUL
;    CX =  SIZE
; 
; ===========================================================================
            push di
            xor  al, al
            rep  stosb
            pop  di

            mov  si, 80h  ; len
            lodsb
            xor  ch, ch
            mov  cl, al
            inc  cx
cmd_line:
            cmp  byte ptr es:[si], 20h
            je   short cmd_line       ; ch == ' ' skipspace
            lodsb
            ; call upper
            stosb

skipspace:
            inc  si
            loop cmd_line


            jcxz cmd_done
nonspace:

            jcxz cmd_done
@procstr:
            lodsb
            ; call upper
            stosb
            dec  cx
            jz   cmd_done
            cmp  byte ptr [si], 20h
            ja   short cmd_line     ; is the next char a space, null, or 0Dh?

            xor  al, al
            stosb
            loop cmd_line
cmd_done:
       ret
cmdparams endp


param_loop:
           ; if the current byte is null, we are done
           cmp  byte [si],0
           je   short param_done

           ; check to see if it is a drive specification.
           mov  al,[si]
           call alpha
           jc   short not_drive_spec
           cmp  byte [si+1],':'
           jne  short not_drive_spec
           cmp  byte [si+2],0
           jne  short not_drive_spec
           
           ; is drive spec, so update drive.
           mov  al,[si]
           sub  al,'A'
           mov  drive,al

           add  si,3
           jmp  short param_loop

           ; it might be the name
not_drive_spec:
           mov  di,offset imgfile
@@:        lodsb
           stosb
           or   al,al
           jnz  short @b

           jmp  short param_loop

; we now have the image filename and the drive value.
param_done:
           mov  al, drive
           cmp  al, 2
           jb   drive_okay
           _print bad_drive_str, 0
_exit:
           call halt

drive_okay:
           mov  ah, 15h   ; floppy present
           mov  dl, drive
           int  13h
           cmp  ah,0
           ja   valid_drive
           mov  al, drive
           add  al, 'A'
           mov  bad_drive_let, al
           _print bad_drive_str1, 0
           jmp  _exit
valid_drive:
           push es        ; this function destroys es
           xor  di, di     ; bug in some BIOSes if this isn't zero
           mov  ah, 08h    ; disk size
           mov  dl, drive
           int  13h
           pop  es

           push dx
           _print type_string, 0
           xor  bh, bh
           cmp  bx, 06
           jb   short @f
           xor  bx,bx
@@:        mov  ax, 32    ; size of strings
           mul  bx
           mov  si,offset type_str
           add  si,ax

           mov  dl, 1  
           mov  bh, 0
           xor  cx, cx
           call print

           pop  dx

           _print type_heads, 0

           xor  eax,eax
           mov  al,dh
           xor  ah,ah
           mov  heads,ax
           inc  ax
           call ltoa

           _print type_spt, 0
           xor  eax,eax
           mov  al,cl
           and  ax,3Fh
           mov  spt,ax
           call ltoa

           _print type_cyl, 0
           xor  eax,eax
           mov  al,ch
           mov  ah,cl
           shr  ah,6
           mov  cylinders,ax
           inc  ax
           call ltoa

           ; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
           ; is disk present in drive?





; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; now find and get the size of the image file
           _newline

           ; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
           ; use DOS to open the file
           mov  dx,offset imgfile
           mov  ax,3D00h   ; open for read only
           int  21h
           jnc  short @f

           _print no_file_str
           call halt

           ; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
           ; found the file
@@:        mov  handle,ax

           ; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
           ; print true name
           mov  si,offset fnd_file_str
           call display_string
           mov  ah,60h
           mov  si,offset imgfile
           mov  di,offset truename
           int  21h
           mov  si,offset truename
           call display_string

           ; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
           ; get the size of the file
           mov  ax,4202h
           mov  bx,handle
           xor  cx,cx
           xor  dx,dx
           int  21h

           ; store the size
           mov  [file_size+0],ax
           mov  [file_size+2],dx

           ; restore the position to the first of the file
           mov  ax,4200h
           mov  bx,handle
           xor  cx,cx
           xor  dx,dx
           int  21h

           ; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
           ; print the size of the file
           mov  si,offset file_size_str
           call display_string
           mov  eax,file_size
           call ltoa

           ; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
           ; now see if the file size is compatible with the size
           ;  of disk drive found
           ; i.e.: does heads * spt * cylinders * 512 == image size
           xor  edx,edx
           xor  eax,eax
           xor  ebx,ebx
           mov  ax,heads
           inc  ax
           mov  bx,spt
           mul  ebx
           mov  bx,cylinders
           inc  bx
           mul  ebx
           mov  bx,512
           mul  ebx

           ; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
           ; eax = size of disk in bytes.
           cmp  eax,file_size
           je   short size_match
           push eax
           mov  si,offset size_match_str
           call display_string
           mov  eax,file_size
           call ltoa
           mov  si,offset not_equal_str
           call display_string
           pop  eax
           call ltoa

           mov  bx,handle
           mov  ah,3Eh
           int  21h

           call halt

           ; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
           ; image file matches disk drive size
           ; so print the 'are you sure' and continue
size_match:         
           mov  si,offset are_sure_str  ;
           call display_string
           mov  ah,01h                  ; get a key
           int  21h                     ;
           call upper_case              ;
           cmp  al,'Y'                  ; if 'Y' then continue
           je   short @f                ;

           ; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
           ; if answer is not Y or y, then close file and abort
           mov  si,offset abort_str     ;
           call display_string          ;

           mov  bx,handle               ;
           mov  ah,3Eh                  ;
           int  21h                     ;

           call halt

           ; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
           ; Now do the dirty work
@@:
           _newline

           xor  bp,bp                   ; start at cylinder 0 (lba)

           xor  ah,ah                   ; reset disk system
           mov  dl,drive                ; drive = 0
           int  13h

           _print spinup_str, 0

           mov  cx,8
@@:        push cx
           mov  ax,0401h                ; verify a sector
           xor  dx,dx                   ;  because WRITE does
           mov  cx,0001h                ;  not wait for the disk to spin up
           int  13h                     ;
           pop  cx
           loop @b

           mov  si,offset spaces_str
           call display_string


; this part of the code sure needs some clean up.
; it was ripped out of some other code I had laying around.

loop_m:
           _print statline, 0
           xor  eax,eax
           mov  ax,bp                   ; bp = cylinder #
           inc  ax                      ; make it one based
           call ltoa

           _print statline1, 0
           mov  ax,cylinders
           call ltoa

           mov  cx,spt                  ; a cylinder at a time
           shl  cx,9                    ; times by 512
           cmp  word heads,0            ; 2 sides?
           je   short @f                ;
           shl  cx,1                    ;
@@:        mov  bx,handle               ; handle to use
           mov  ah,3Fh                  ; read from file
           mov  dx,offset Buffer        ; in to our buffer
           int  21h                     ;
           jc   short MError

           mov  ax,bp                   ; bp = cylinder #
           mov  cx,spt                  ; count
           cmp  word heads,0            ; 2 sides?
           je   short @f                ;
           shl  cx,1                    ;
@@:        mul  cx                      ;
           mov  dx,ax                   ; dx = lba
           mov  bx,offset Buffer        ;
           mov  al,drive                ;
           int  26h                     ; absolute disk write
           pop  cx                      ; clean the stack
           jc   short MError            ; carry = error
          
           inc  bp                      ; cylinder number
           mov  ax,bp                   ;
           cmp  ax,cylinders            ;
           jb   short loop_m            ;
           
           mov  si,offset SuccessS      ; else we are done, print message
           jmp  short MError1           ;  and exit

MError:    mov  si,offset MErrorS       ; Assume Error
MError1:   call display_string

           mov  bx,handle               ; handle to use
           mov  ah,3Eh                  ; close handle
           int  21h

           call halt
