; ****************************************************************************
; Turkish Rational SINGLIX  
; Disk Operation System v1.0 Project
; 1.44 MB Floppy Disk Image Writing Code
;
; Copyright (C) Erdogan TAN - 02/08/2011 - 03/08/2011 - 06/08/2011 
;
;
; ****************************************************************************

; DTA (PSP+80h= Offset 128)
DTA_Time equ 150 ; PSP+22
DTA_Date equ 152 ; PSP 24
DTA_FileSize equ 154 ; PSP + 26
DTA_FileName equ 158 ; PSP + 30

.8086

SINGLIXBOOT     SEGMENT PUBLIC 'CODE'
                assume cs:SINGLIXBOOT,ds:SINGLIXBOOT,es:SINGLIXBOOT,ss:SINGLIXBOOT

                org 100h

START_CODE:

proc_start      proc near

                mov bx, SizeOfFile+100
                add bx, 15
                shr bx, 1
        	shr bx, 1
		shr bx, 1
		shr bx, 1
                mov ah, 4Ah ; modify memory allocation
               ;push cs
               ;pop es
                int 21h 
                                  
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; see if drive specified
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
              
                mov si, 80h                     	; PSP command tail
                mov cl, byte ptr [SI]
                or cl, cl                               
                jnz short WRITESTUB_02           	; jump if not zero

WRITESTUB_01:
                mov si, offset SINGLIX_Welcome
                call SINGLIX_PRINTMSG
                jmp WRITESTUB_24

WRITESTUB_02:
                inc si
                mov dx, word ptr [SI]
                cmp dl, " "                      	; is it SPACE ?
                jne short WRITESTUB_03

                dec cl                                  
                jnz short WRITESTUB_02             
                jmp short WRITESTUB_01

WRITESTUB_03:
                cmp dl, "f"
                jne WRITESTUB_04
                cmp dh, "d"
                jne WRITESTUB_01
                mov dx, word ptr [SI]+2
                cmp dh, ":"
                jne short WRITESTUB_01
                cmp dl, "0"                            
                jb WRITESTUB_01
                cmp dl, "1"
                ja WRITESTUB_01
                sub dl, "0"
                add si, 4  ; 03/08/2011
                jmp short WRITESTUB_06
               
WRITESTUB_04:
                cmp dh, ":"
                jne short WRITESTUB_01    
                cmp dl, "A"
                jb  short WRITESTUB_01
                cmp dl, "B"	                        ; A - B
                jna short WRITESTUB_05                    
                cmp dl, "a"                             ; a - b
                jb  short WRITESTUB_01                  
                cmp dl, "b"                         
                ja  short WRITESTUB_01                 
                sub dl, "a"-"A"	      
WRITESTUB_05:
                sub dl, "A"
                add si, 2  ; 03/08/2011
WRITESTUB_06:
                mov byte ptr [Drive_Number], dl
                mov ah, 08h
                int 13h
                ; ES <> DS
                jc WRITESTUB_26
               
                cmp dl, byte ptr [Drive_Number] ; 03/08/2011
                jna WRITESTUB_26

                cmp bl, 04h
                jnb short WRITESTUB_07

                mov si, offset msg_Drive_Not_Compatible
                call SINGLIX_PRINTMSG

                retn

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Write message
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

WRITESTUB_07:
               ; 03/08/2011
                push ds
                pop es
                mov di, offset Image_File_Name
WRITESTUB_08:
                lodsb
                cmp al, 20h
                jb short WRITESTUB_10
                je short WRITESTUB_08
                mov cx, 64 
WRITESTUB_09:
                stosb
                lodsb
                cmp al, 20h 
                jna short WRITESTUB_10
                loop WRITESTUB_09
                mov byte ptr [Image_File_Name], 0
                jmp short WRITESTUB_11
WRITESTUB_10:
                xor al, al
                stosb
WRITESTUB_11:
                mov si, offset Msg_DoYouWantToWrite
                call SINGLIX_PRINTMSG
               
                mov si, offset SINGLIX_FD_Name
                call SINGLIX_PRINTMSG

		mov si, offset msg_yes_no
                call SINGLIX_PRINTMSG
WRITESTUB_12:
                xor ax, ax
                int 16h                                 ; wait for keyboard command
                cmp al, "C"-40h
                je WRITESTUB_24                   
                cmp al, 27
                je WRITESTUB_24
                and al, 0DFh
                cmp al, "Y"                             ; Yes?
                je short WRITESTUB_13_Y                 ; write
                cmp al, "N"                             ; No?
                jne short WRITESTUB_12                 

WRITESTUB_13_N:
                mov si, offset msg_NO
                call SINGLIX_PRINTMSG
                jmp WRITESTUB_24

WRITESTUB_13_Y:
                mov si, offset msg_YES
                call SINGLIX_PRINTMSG
               
               ; 03/08/2011
                cmp byte ptr [Image_File_Name], 20h
                ja short WRITESTUB_14
                
                mov si, offset Msg_DosFile_Name
                call SINGLIX_PRINTMSG
                call proc_rw_char
                jnc short WRITESTUB_14_no_crlf
                mov si, offset msg_cancel
                call SINGLIX_PRINTMSG               
                jmp WRITESTUB_24

WRITESTUB_14:
                mov si, offset SINGLIX_CRLF
                call SINGLIX_PRINTMSG
WRITESTUB_14_no_crlf:
                mov dx, offset Image_File_Name
                mov cx, 27h ; File Attributes
                mov ah, 4Eh ; MS Dos Function = Find First File
                int 21h
                jnc short WRITESTUB_15

                mov si, offset Msg_File_Not_Found
                call SINGLIX_PRINTMSG

                jmp short WRITESTUB_24

WRITESTUB_15:
                mov ax, 8000h
                mov dx, 16h
                mov si, DTA_FileSize
                cmp ax, word ptr [SI]
                jne short WRITESTUB_25
                cmp dx, word ptr [SI]+2
                jne short WRITESTUB_25

WRITESTUB_16:
                mov dx, offset Image_File_name
                mov ah, 3Dh ; MS Dos Function = Open File
                xor al, al  
                int 21h
                jc short WRITESTUB_26  ;03/08/2011

WRITESTUB_17:
		mov word ptr [FileHandle], ax

                mov si, offset Msg_writing_if
                call SINGLIX_PRINTMSG

WRITESTUB_18:  
  		mov AH, 3
                xor BH, BH
                int 10h ; Return Cursor Position
                ; DL = Column, DH= Line
                mov word ptr [Cursor_Pos], DX
                ; 03/08/2011 
                mov word ptr [Cursor_Type], CX

WRITESTUB_19: 
                mov ah, 3Fh ; Read File
                mov cx, 512
                mov dx, offset SECBUFFER
                mov bx, word ptr [FileHandle]
                int 21h
                jc short WRITESTUB_23

WRITESTUB_20: 
               ; 03/08/2011
                mov AX, word ptr [FD_Sector]
                push AX
                inc AX 
                mov SI, offset Sector_Str
                call proc_bin_to_decimal
                pop AX
                mov BX, offset SECBUFFER
                call proc_write_fd_sector
               ; 06/08/2011
                jc short WRITESTUB_26

WRITESTUB_21:  ; 03/08/2011                 
                cmp AX, 2879
                jnb short WRITESTUB_22
                inc AX
                mov word ptr [FD_Sector], AX
                jmp short WRITESTUB_19

WRITESTUB_22:        
                mov si, offset Msg_OK
                call SINGLIX_PRINTMSG

WRITESTUB_23:
                mov ah, 3Eh ; Close File
                mov bx, word ptr [FileHandle]
                int 21h
WRITESTUB_24:
                mov si, offset SINGLIX_CRLF
                call SINGLIX_PRINTMSG

                int 20h
                
                int 19h 

WRITESTUB_25:
                mov si, offset Msg_Image_Not_Compatible
                call SINGLIX_PRINTMSG
               
                jmp short WRITESTUB_23

WRITESTUB_26:
                mov si, offset msg_singlix_drv_read_write_error
                call SINGLIX_PRINTMSG

                cmp byte ptr [FileHandle], 0
                ja short WRITESTUB_23

                jmp short WRITESTUB_24

proc_start     endp

Drive_Number: db 0
FileHandle: dw 0
FD_Sector: dw 0 ; 03/08/2011
Cursor_Pos: dw 0
Cursor_Type: dw 0 ; 03/08/2011
Error_Code: db 0

proc_write_fd_sector    proc near
                ; Only for 1.44 MB FAT12 Floppy Disks
                ; INPUT -> AX = Logical Block Address
                ; ES:BX = Sector Buffer
                ; OUTPUT -> clc or stc
                ; CLC -> AX = Logical Block Address
                ; STC -> DX = Logical Block Address
                ; STC -> AH = Error Number
                mov     CX, 7  ; Retry Count
loc_write_fd_chs:
                push    AX                      ; Linear sector number
                push    CX                      
                mov     DX, 18                  ; Sectors per Track
                div     DL
                mov     CL, AH                  ; Sector (zero based)
                inc     CL                      ; To make it 1 based
                shr     AL, 1                   ; Convert Track to Cylinder
                adc     DH, 0                   ; Head (0 or 1)
                mov     DL, Byte Ptr [Drive_Number]
                mov     CH,AL                   
                mov     AX,0301h
                int     13h                     ; BIOS Service func ( ah ) = 3
                                                ; Write disk sectors
               ;mov     byte ptr [Error_Code], ah
                pop     CX
                pop     AX

                jnc     short pass_write_fd_chs_error
                loop    loc_write_fd_chs
               ;mov     DX, AX
               ;mov     ah, byte ptr [Error_Code]
                stc
pass_write_fd_chs_error:
                retn

proc_write_fd_sector    endp

SINGLIX_PRINTMSG     proc near
 
SINGLIX_PRINTMSG_LOOP:
                lodsb                           ; Load byte at DS:SI to AL
                and     AL,AL            
                jz      short SINGLIX_PRINTMSG_OK       
                mov     AH,0Eh                  
                mov     BX,07h             
                int     10h                     ; BIOS Service func ( ah ) = 0Eh
                                                ; Write char as TTY
                                                ;AL-char BH-page BL-color
                jmp     short SINGLIX_PRINTMSG_LOOP           

SINGLIX_PRINTMSG_OK:
                retn

SINGLIX_PRINTMSG     endp

proc_bin_to_decimal proc near
               ; 3-8-2011
               ; 1-3-2005, 25-5-2009
               ;  Erdogan Tan
               ; INPUT: DS:SI = Target location (last digit)
               ;        AX= Binary Number (Integer)
               ; OUTPUT: Decimal char at DS:SI
               ; SI decremented after every division
               ; till AX<10.
               ; CX, DX will be changed.

               push si
               add si, 3
               mov cx, 10
loc_btd_re_divide:
               xor dx, dx
               div cx
               add dl, '0'
               mov byte ptr [SI], dl
               cmp ax, 0
               jna short print_decimal_sector_number
               dec si
               jmp short loc_btd_re_divide

print_decimal_sector_number:
               ; 23/05/2009
                mov ah, 1                      ; Set Cursor Type 
                mov ch, 20h                    ; Disable cursor  
                int 10h          
                mov ah, 2                      ; Set Cursor Position    
                mov dx, word ptr [Cursor_Pos]
                xor bh, bh
                int 10h  ; Set Cursor Position             
                pop si
               ;mov si, offset Sector_Str
                call SINGLIX_PRINTMSG
                mov ah, 1                      ; Set Cursor Type 
                mov cx, word ptr [Cursor_Type]  
                int 10h  

                retn

;Str_Number_Input: dw 0

proc_bin_to_decimal endp

proc_rw_char   proc    near
               ; 03/08/2011
               ; 02/08/2011 
               ; 30/07/2011
               ; 15/03/2005 
               ; OUTPUT -> DS:SI = Entered String (ASCIIZ)
               mov     si, offset Image_File_Name
               xor     di, di ; 03/08/2011
               mov     bx, 7
               mov     ah, 3
               int     10h
               mov     Word Ptr [Cursor_Pos], dx
read_next_char:
               xor     ah, ah
               int     16h
               and     al, al
               jz      short loc_arrow    
               cmp     al, 0E0h          
               je      short loc_arrow
               cmp     al, 8
               jne     short char_return
loc_back:
               mov     ah, 3
               int     10h
               cmp     dl, Byte ptr [Cursor_Pos]
               jna     short loc_beep
prev_column:
               dec     dl
set_cursor_pos:
               mov     ah, 2
               int     10h
               mov     bl, dl
               sub     bl, byte ptr [Cursor_Pos] 
               mov     cx,1
               mov     ah, 9
               mov     al, 20h
               mov     Byte Ptr [SI][BX], al
loc_write_it:
               mov     bl, 7
               int     10h
               mov     dx, Word Ptr [Cursor_Pos]
               jmp     short read_next_char
loc_beep:
               mov     ah, 0Eh
               mov     al, 7
               int     10h
               jmp     short read_next_char
loc_arrow:    
               cmp     AH, 4Bh
               je      short loc_back
               cmp     AH, 53h
               je      short loc_back
               jmp     short read_next_char
char_return:
               mov     ah, 3
               int     10h
check_char_type:
               cmp     al, 20h
               jb      short loc_escape
               mov     ah, dl
               sub     ah, byte ptr [Cursor_Pos] 
               cmp     ah, 64
               ja      short loc_beep
               cmp     al, "z"
               ja      short read_next_char
               cmp     al, "a"
               jb      short pass_capitalize
               and     al, 0DFh
pass_capitalize:
               mov     bl, ah
               xor     ah, ah
               mov     Word Ptr [SI][BX], ax
               mov     di, bx ; 03/08/2011
               inc     di ; 03/08/2011
               mov     bl, 7
               mov     ah, 0Eh
               int     10h
               jmp     short read_next_char
pass_escape:
               cmp     al, 0Dh
               jne     short read_next_char
	       mov     ah, 0Eh
               int     10h
               mov     al, 0Ah
               int     10h
               jmp     short loc_rw_char_retn
loc_escape:
               cmp     al, 1Bh
               jne     short pass_escape
               stc
               retn

loc_rw_char_retn:
              ; 03/08/2011
               add     di, offset Image_File_name  
               mov     Byte Ptr [DI], 0
               retn

proc_rw_char   endp


;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;  messages
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

SINGLIX_Welcome:
                db 0Dh, 0Ah
                db "TR-DOS 1.44 MB Floppy Disk Image File Writing Utility"
                db 0Dh, 0Ah
                db "v1.0.060811  (c) Erdogan TAN 2011"
                db 0Dh,0Ah
                db 0Dh,0Ah
                db "Usage: fdwrite [Drive] "
                db 0Dh,0Ah
                db 0Dh,0Ah
                db "Drive names:"
                db 0Dh,0Ah
                db 0Dh,0Ah
                db "fd0     (Floppy Disk 1, A:)", 0Dh, 0Ah
                db "fd1     (Floppy Disk 2, B:)", 0Dh, 0Ah
                db 0

Msg_DoYouWantToWrite:
                db 07h
                db 0Dh, 0Ah
                db "Do you want to write fd image file onto drive ", 0
msg_yes_no:
                db "(Yes/No)? ", 0

SINGLIX_FD_Name:
                db 'fd'
SINGLIX_FD_Number:
                db "0: ", 0

Msg_File_Not_Found:
                db 0Dh, 0Ah
                db "File not found !", 0

Msg_writing_if:
                db 0Dh, 0Ah
                db "Writing sector: ", 0

Sector_Str:     db "0000", 0

Msg_DosFile_Name:
                db 0Dh, 0Ah
                db 0Dh, 0Ah
                db "File Name : ", 0

Msg_OK:
                db " OK.", 0

msg_YES:        db " YES"
                db 0
msg_NO:         db " NO"
                db 0   
; 03/08/2011
msg_Cancel:     db " CANCEL"
                db 0   

SINGLIX_CRLF:
                db 0Dh, 0Ah, 0

msg_singlix_drv_read_write_error:
                db 0Dh, 0Ah
                db "Drive not ready or read/write error !"
                db 0

msg_Drive_Not_Compatible:
                db 0Dh, 0Ah
                db "Drive not compatible with 1.44 MB floppy disk !"
                db 0

msg_Image_Not_Compatible:
                db 0Dh, 0Ah
                db "Image not compatible with 1.44 MB floppy disk !"
                db 0

fdwrite_CopyRight:
                db  "(c) Erdogan TAN - 06/08/2011"

SECBUFFER:      db 512 dup(0)

image_file_name: db 66 dup(0) ; 03/08/2011

SizeOfFile      equ $-100

               
SINGLIXBOOT     ends

                end     START_CODE
