/
fat_to_file_code.inc
71 lines (62 loc) · 2.02 KB
/
fat_to_file_code.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; routine for finding a directory entry
%ifndef FAT_TO_FILE_CODE__INC
%define FAT_TO_FILE_CODE__INC
%include "bios.inc"
%include "macros.inc"
%include "bpb.inc"
%include "dir_entry.inc"
%include "stage2_parameters.inc"
%include "simple_disk_handling_code.inc"
hi_nibble_mask equ 0x0FFF
lo_nibble_shift equ 4
end_of_chain_mask equ 0x0FF0
;;; fat_to_file - read a chain of FAT entries to
;;; get the file sectors it maps to
;;; and read those sectors into a buffer
;;; Inputs:
;;; BX - starting FAT entry
;;; DI - FAT buffer
;;; SI - buffer to read the entry to
;;; Outputs:
;;; buffer to read file into
fat_to_file:
.read_loop:
mov ax, bx
sub ax, 2
add ax, first_data_sector
mov bx, si
call read_LBA_sector
call extract_next_fat12_entry
mov bx, ax
test ax, end_of_chain_mask
jz .end_of_file
; call print_hex_word
jmp .read_loop
.end_of_file:
; call print_hex_word
ret
;;; extract_next_fat12_entry - read a FAT entry to
;;; see where the next FAT entry is,
;;; if any
;;; Inputs:
;;; DI - FAT entry buffer
;;; BX - current FAT entry's value
;;; Outputs:
;;; AX - next FAT entry's value
extract_next_fat12_entry:
;; address_of_FAT_entry = fat_buffer + (current_cluster + current_cluster / 2)
mov ax, bx ; BX == current cluster
shr ax, 1 ; current_cluster / 2
add ax, bx ; (current_cluster + current_cluster / 2) == FAT entry offset
add di, ax ; index fat buffer by offset
mov ax, [di] ; get the indexed entry
test bx, 1 ; check if the existing entry is odd
jz .even
.odd:
shr ax, lo_nibble_shift ; extract the high bits
ret
.even:
and ax, hi_nibble_mask ; extract the low bits
ret
%endif