; ****************************************************************************
; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - trfdboot.s - FAT12 FD BOOT SECTOR
; ----------------------------------------------------------------------------
; Last Update: 12/02/2016
; ----------------------------------------------------------------------------
; Beginning: 25/01/2016
; ----------------------------------------------------------------------------
; Assembler: NASM version 2.11 (trfdboot.s)
; ----------------------------------------------------------------------------
; Turkish Rational DOS
; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
;
; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
; TRFDBOOT.ASM (31/07/2011)
; ****************************************************************************

; TRDOS FAT12 Floppy Disk Boot Sector code (as a part of 'trfdboot.s')
; Copyright (C) 1998-2016  Erdogan TAN  [ Last Modification: 25/01/2016 ]

; incbin "TRFDBS.BIN" (in 'trfdboot.s')

notvalidfmask   equ	0018h

root_dir_buff   equ	0700h
rts_segment     equ	1000h
FAT_Buffer      equ	0700h

[BITS 16]
[ORG 7C00h]

                jmp     short BS_01
                nop

; BootSector Identification (Data) Block

bsOemName:      db 'TRDOS2.0'          
bsBytesPerSec:  dw 512
bsSecPerClust:  db 1
bsResSectors:   dw 1
bsFATs:         db 2
bsRootDirEnts:  dw 224
bsSectors:      dw 2880
bsMedia:        db 0F0h
bsFATsecs:      dw 9
bsSecPerTrack:  dw 18
bsHeads:        dw 2
bsHidden1:      dw 0
bsHidden2:      dw 0
bsHugeSectors:  dd 2880
bsDriveNumber:  db 0
bsReserved1:    db 0
bsBpbSignature: db 29h                 
bsVolumeID:     dd 0
bsVolumeLabel:  db 'TRDOS      '
bsFileSysType:  db 'FAT12   '          
bsReserved2:    dw 'RT'

BS_01:          
                mov	ax, cs
		mov	ds, ax
		mov	es, ax

		cli
		mov	ss, ax
		mov     sp, 0FFFEh
		sti

		; overwrite fd drive number !
                mov	[bsDriveNumber], dl 	; drive number from INT 19h

		xor	ax, ax
BS_02:
                ;mov	dl, [bsDriveNumber]
		int     13h                     ; BIOS Service func ( ah ) = 0
                                                ; Reset disk system
                jc      short BS_07         	; To print i/o error message
                                                ; AX = 0 no error
BS_03:                                 
                mov     ax, 19                  ; Root Dir Location
                mov     cx, 14                  ; Root Directory Sectors
                mov     bx, root_dir_buff       ; Destination offset = 700h
                mov     si, bx
                call    fd_read
BS_04:          jc      short BS_07		; Disk read error message

                mov     bx, 224                 ; Number of root dir entries

BS_05:          cmp     byte [si], 0		; Is it null entry?
                je      short BS_06		; Jump if zero ( = )
                mov     cx, 0Bh                 ; Size of file/directory name
                push    si
                mov     di, rtsfilename   
                repe    cmpsb                   ; Repeat if ZF = 1, CX > 0
						; Cmp byte DS:SI with ES:DI
                pop	si
                je      short BS_09		; If the file name found
                dec     bx                    
                jz      short BS_06		; Jump if no next entry
                add     si, 32                  ; To next directory entry
                jmp     short BS_05             ; Jump for next sector
BS_06:
                mov     si, Replace_Msg
                jmp     short BS_08
BS_07:      
                mov     si, Error_Msg
BS_08:          
                call    print_msg

                xor	ax, ax
		int	16h			; BIOS Service func ( ah ) = 0
						; Read next kbd char
						; AH-scan code AL-char code
		int	19h			; Reboot

BS_09:
                mov     al, [si+0Bh]		; Move attributes byte to BL
                and     al, notvalidfmask       ; Is it a file, really?
                ja      short BS_06		; Jump if above ( > )
                mov     ax, [si+1Ah]		; First cluster of the file
                cmp     ax, 2                   ; Start cluster
                jb      short BS_07

                mov	[bsReserved2], ax	; Save the first cluster
    
		; Load FAT
                mov     ax, 1                   ; FAT Location
                mov     cx, 9                   ; FAT Sectors
                mov     bx, FAT_Buffer    
                call    fd_read
                jc      short BS_07

		; Load  RTS (Kernel) file
                mov     si, Loading_Msg
                call    print_msg
                mov     ax, [bsReserved2]	; The First cluster
                mov     bx, rts_segment
                mov     es, bx
                xor     bx, bx
                call    load_file
                jc      short BS_07

		; Launch RTS (Kernel)
                mov     dl, [bsDriveNumber]	; 12/06/2011
                mov     ax, rts_segment ; 1000h
                mov     ds, ax
                ;mov     es, ax
                cli
                mov     ss, ax
                ;mov	sp, 0FFFEh
                sti

                mov     ax, 417 ; TRDOS boot sector sign for TRDOS386.SYS

             	;jmp	1000h:0000h
             	;(OP Code: EA00000010)
                db      0EAh
                dw      0
                dw      rts_segment	; 1000h

print_msg:
BS_10:
		lodsb				; Load byte at DS:SI to AL
                and     al, al            
                jz	short BS_11		; If AL = 00h then stop

                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 BS_10
BS_11:
		retn

fd_read:
                ; Only for FAT12 Floppy Disks (18 sector/track)
                
                mov     byte [RetryCount], 4
BS_12:
                push    cx
                push    ax                      ; PHYSICAL ADRESS CALCULATION
                mov     cl, 18                  ; Sectors per track
                div     cl                      
                mov     cl, ah                  ; Sector (zero based)
                inc     cl                      ; To make it 1 based
                ;xor     ah, ah
                ;mov     dl, 2			; Heads 
                ;div     dl
                                                ; AL=cyl, AH=head, CL=sector
                ;mov	dh, ah
		sub	dh, dh
		shr	al, 1
		adc	dh, 0
                mov     dl, [bsDriveNumber] 
                mov     ch, al            

                mov     ax, 0201h
		int	13h			; BIOS Service func ( ah ) = 2
						; Read disk sectors
						; AL-sec num CH-track CL-sec
						; DH-head DL-drive ES:BX-buffer
						; CF-flag AH-stat AL-sec read
		pop	ax			
                pop     cx
                jc      short BS_13
                inc     ax
	                
                dec     cx
                jz      short BS_14
                add     bx, 512
                mov     byte [RetryCount], 4
                jmp     short BS_12
BS_13:         
                dec     byte [RetryCount]
                jnz     short BS_12
                stc
BS_14:
                retn

load_file:
              ; ES:BX = File Buffer
              ; AX = First Cluster Number
              ; Only for FAT12 Floppy Disks (1 sector per cluster)
BS_15:
                mov     [File_Cluster], ax
                mov     [File_BufferOff], bx
                dec     ax                      ; First cluster is cluster 2
                dec     ax               
                mov     cx, 1                   ; Sector count
                add     ax, 33                  ; Beginning sector of Data
                call    fd_read
                jc      short BS_17
BS_16:
                mov     ax, [File_Cluster]
                call    get_next_cluster
                jnc     short BS_18
                cmp     ax, 1
                cmc
BS_17:
                retn
BS_18:
                mov     bx, [File_BufferOff]
                add     bx, 512
                jmp     short BS_15

get_next_cluster:
                ; INPUT -> AX = Cluster Number
                ; OUTPUT -> clc -> No Error, AX = Next Cluster
                ; OUTPUT -> cf = 1 & AX = 0 -> End Of Cluster Chain
                ; OUTPUT -> cf = 1 & AX > 0 -> Error
BS_19:
                mov     bx, ax
                mov     dx, 3
                mul     dx
                shr     ax, 1 ; Divide by 2
                xchg    bx, ax
                ; BX = Buffer Byte Offset
                ; AX = Current Cluster
                mov     ax, [FAT_Buffer+bx]
                jnc     short BS_22
                shr     ax, 4
BS_20:
                cmp     ax, 0FF7h
                jc      short BS_21
                xor     ax, ax
BS_21:
                cmc
                retn
BS_22:
                and     ah, 0Fh
                jmp     short BS_20

File_Cluster:   dw 0
File_BufferOff: dw 0

rtsfilename:
                db      'TRDOS386SYS'
                db      0
Error_Msg:
                db      0Dh, 0Ah
                db      'TRDOS Loading Error!'
Replace_Msg:    db      0Dh, 0Ah
                db      'Replace the disk and press any key to reboot.'
                db      0Dh, 0Ah,0
Loading_Msg:    db      0Dh, 0Ah
                db      "Loading Kernel TRDOS386.SYS ..."
                db      0Dh, 0Ah, 0

RetryCount:     db      0
		
		times	510 - ($ - $$) db 0

bootsignature:  db      55h, 0AAh