.286
.model small
.code
org 100h
jumps
include structs.inc
COUNT = 8
DRIVE = 'D'

BOOT32 struc
	_jumps	db 3 dup (?)
	OEM		db 8 dup (?)
    ExtBPB	A_BF_BPB <?>
    bDrvNo	db ?
    bt32_res1	db ?
    bExtBootSig	db ?
    wSerNo	dw ?
    wSerNoHi	dw ?
    abVolLabel	db 11 dup (?)
    abFileSysCode	db 8 dup (?)
    abBootCode db 200h-38-SIZE A_BF_BPB dup (?)
BOOT32 ends

start:
;{
  push cs			; 
  push offset _Boot	; Rec_Buf
  push 1			; Count
  push 0			; Sector
  push 0			; Cyl
  push 0			; Head
  push DRIVE-'@'	; Drive
  call ReadCyl
  jc error
  xor ax, ax
  mov al, _boot.ExtBPB.A_BF_BPB_SectorsPerCluster
  mov _ClustSize, ax
  mov ax, _boot.ExtBPB.A_BF_BPB_ReservedSectors
  mov bp, ax
  mov _FAT32Beg, ax
  mov ax, _boot.ExtBPB.A_BF_BPB_BigSectorsPerFat
  xor bx, bx
  mov bl, _boot.ExtBPB.A_BF_BPB_NumberOfFATs
  mul bx
  add bp, ax
  adc dx, 0
  mov _DataBeg, bp
  mov _DataBegHi, dx
;} Read Extended Boot Sector

  mov ax, 0
  mov dx, 0
  call GetFat32
  jc error

  mov dx, 0
  mov ax, 0ah
  call GetValFromFAT

  push cs
  push offset _buf
;  push _boot.ExtBPB.A_BF_BPB_RootDirStrtClusHi
;  push _boot.ExtBPB.A_BF_BPB_RootDirStrtClus
  push 0
  push 0Ah
  push Drive-'@'
  call ReadClust

  mov ah, 3ch
  lea dx, _fname
  mov cx, 0
  int 21h

  mov bx, ax
  mov ah, 40h
  mov cx, 200h*COUNT
  lea dx, _buf
  int 21h

  mov ah, 3eh
  int 21h

  jmp exit

error:
  mov dl, ah  
  mov cl, al
  mov ah, 2
  int 21h

  mov dl, cl
  int 21h

  mov ah, 9
  lea dx, _err
  int 21h

exit:  
  mov ah, 4ch
  int 21h

;===================================================================
;===================================================================
;===================================================================
;===================================================================
;===================================================================
;===================================================================
GetValFromFat proc near ; AX=Clstr, DX=ClstrHi
push si
push di
		mov vl_cls, 	ax
		mov vl_clshi,	dx

		cmp dx, FtBegHi
		jb  @NeedRd
		ja  @Big 
		cmp ax, FtBeg
		jb  @NeedRd
@BIG:
		cmp dx, FtEndHi
		ja  @NeedRD
		jb  @TblOK
		cmp ax, FtEnd
		jbe @TblOK
@NeedRd:
		mov ax, vl_cls
		mov dx, vl_clshi
		call GetFAT32
@TblOK:
		mov ax, vl_cls
		sub ax, ftBeg
		shl ax, 2
		mov bx, ax
		add bx, offset FAT32
		mov ax, [bx]
		mov dx, [bx+2]
pop di
pop si
ret
vl_cls   dw 0
vl_clshi dw 0
endp
;-----------------------------------------------------
GetFAT32 proc Near  ; AX=Clstr, DX = ClstrHi (Guarantied present)
push di
push si
  mov FtBeg, ax
  mov FtBegHi, dx
  mov FtEndHi, dx
  and FtBeg, 1111111110000000b 

  		xor cx, cx	;
  		shr ax, 7   ;  Div
  		mov cl, dl  ;  Cluster Num by 128
  		shl cl, 1   ;  to get sectorNum
  		shr dx, 7	;  from begining of FAT32
  		or  ah, cl  ; 

  		add ax, _FAT32Beg
  		adc dx, 0

  		push cs
  		push offset FAT32
  		push 1
        push dx
        push ax
        push Drive-'@'
  		call ReadAbsCyl

  mov ax, FtBeg
  mov FtEnd, ax
  add FtEnd, 128
  adc FtEndHi, 0
pop si
pop di
  ret
endp
;-------------------------------------------------------------------
ReadClust proc Near
push bp
mov bp, sp
push si
push di
cls_drv equ word ptr [bp+4]
cls_clstr  equ word ptr [bp+6]
cls_clstrHi  equ word ptr [bp+8]
cls_bufOf equ word ptr [bp+10]
cls_bufSeg equ word ptr [bp+12]
		mov si, cls_clstrHi
		mov ax, cls_clstr
		sub ax, 2
		sbb si, 0
		mov bx, _ClustSize
		mul bx
		push ax
		mov di, dx
		mov ax, si
		mul bx
		add ax, di
		mov dx, ax
		pop ax

		add ax, _DataBeg
		adc dx, _DataBegHi

		push cls_bufSeg
        push cls_bufof
		push bx
		push dx
		push ax
		push cls_drv
		call ReadAbsCyl
pop di
pop si
pop bp
ret 10
endp
;-------------------
ReadAbsCyl proc Near
	push bp
	mov bp, sp
abs_drv   equ word ptr [bp+4]
abs_cyl   equ word ptr [bp+6]
abs_cylHi equ word ptr [bp+8]
abs_count equ word ptr [bp+10]
abs_BufOf equ word ptr [bp+12]
abs_BufSeg equ word ptr [bp+14]
  push si
  push di

  mov ax, abs_cyl
  mov _NeedRead, ax
  mov ax, abs_cylHi
  mov _NeedReadHi, ax

  mov bx, _Boot.ExtBPB.A_BF_BPB_SectorsPerTrack   ;
  mov ax, _Boot.ExtBPB.A_BF_BPB_Heads             ; Calc
  mul bx                                          ;    Sect per
  mov bx, ax                                      ;           Cyl

  mov dx, _NeedReadHi				; Calc 
  mov ax, _NeedRead                 ;    Cyl
  div bx                            ;      Number

  mov si, ax  ; SI = Cyl Number
  mov ax, dx  ; Ostatok

  mov bx, _Boot.ExtBPB.A_BF_BPB_SectorsPerTrack ; Calc
  xor dx, dx                                    ;    Head
  div bx                                        ;       Number
  mov di, ax  ; Head

  push abs_bufSeg
  push abs_bufOf
  push abs_count
  push dx
  push si
  push di
  push abs_drv
  call ReadCyl

    pop di
    pop si
	pop bp
	ret 12

_NeedRead dw 0
_NeedReadHi dw 0
endp
;=======================
ReadCyl PROC near
    push bp
    mov bp,sp
par_Drive equ word ptr [bp+4]

  push cs 
  pop es
  mov ax, ss
  mov ds, ax


  mov di, offset _rb+1
  lea si, [bp+6]
  mov cx, 6
  repe movsw

  mov     bx, par_Drive	          ;See below
  mov     ch, 48h				  ;See below
  mov     cl, 61h                 ;Read track on logical drive
  mov     dx, offset _RB	 	  ;ds:dx points to RWBLOCK structure
  mov     ax, 440Dh               ;IOCTL for block device
  int     21h

  pop bp
  ret 14

_RB RWBLOCK <?>
endp
;
;-------------------------------------
; Global Varicables
;-------------------------------------
;
FtBeg		dw ?
FtBegHi		dw ?
FtEnd		dw ?
FtEndHi		dw ?

_FAT32Beg dw ?
_DataBeg dw ?
_DataBegHi dw ?
_ClustSize dw ?
_err db 'Error',10,13,'$'
_fname db 'RF2.dat',0
FAT32		dd 128 dup (?)
_Boot BOOT32 <?>
_buf db 200h*COUNT dup (?)
end start
