Documente Academic
Documente Profesional
Documente Cultură
DOSSEG
.MODEL SMALL
.DATA
TRUE = 0ffh
FALSE = 0
_HDPHYS STRUC
bios_HD_num db 0
fat_type db 0
head db 0
cylinder db 0
sector db 0
_HDPHYS ENDS
_HDindex STRUC
IDXlogdrive_num db 0
IDXbios_HD_num db 0
IDXfat_type db 0
IDXhead db 0
IDXcylinder db 0 ;cylinder# (low order 7 bits)
IDXsector db 0 ;sector# (bits 5-0); bits 7,6 (cylinder 2 high bits)
_HDindex ENDS
EVEN
EVEN
EVEN
; ----------------------------------------------
; MAIN: HIGH LEVEL DEMONSTRATION TEST CODE
; ----------------------------------------------
.CODE
START:
mov ax,@DATA
mov ds,ax
mov es,ax
NEXT_DRIVE:
;For LOGICAL DOS DRIVE = A: TO Z:
map_log_to_phy:
call HDMapLogToPhy ;DS:SI gets ptr to log drv's info
jz next_drv ;no entry in HDindex for this drive
;Have valid entry in HDindex table for this logical drive. Extract
data
;from table using returned ptr, convert, format it and display it.
call format_linebuff
NEXT_DRV:
;inc drive letter id
inc [log_drv_no]
cmp [log_drv_no],MAX_LOG_NO ;max is logical drive 'Z'
jbe next_drive ;do next logical drive
;test is done
mov dx,offset cr_lf
mov ah,9
int 21h
;term prog
mov ax,4c00h
int 21h
FORMAT_LINEBUFF proc
;Format logical drive's data for display
;On entry: DS:SI has ptr to logical drives's entry in table HDindex
;get, convert, and plug logical drive letter in display line buffer
cld
lodsb
add al,'A'-1
mov ah,':'
mov bp,offset line_buff+3
mov ds:[bp],ax
add bp,7
VAL_TO_HEX_ASCII proc
;On entry: AL contains byte value to convert to hex ascii.
; BP has ptr to buffer that will get ascii string
;Note: No leading zero supression
;On exit: DI has length of string excluding null terminating byte
xor di,di
hex_16s:
xor ah,ah
mov bl,16
div bl
call store_hex_char
hex_ones:
mov al,ah ;use remainder
call store_hex_char
ret
VAL_TO_HEX_ASCII endp
STORE_HEX_CHAR proc
add al,'0'
cmp al,'9'
jbe to_buffer
add al,'@'-'9'
to_buffer:
mov byte ptr ds:[bp][di],al
inc di
ret
STORE_HEX_CHAR endp
; ------------------------------------------------------
; LOW LEVEL FUNCTIONS: HDMapLogToPhy and HDSysInventory
; ------------------------------------------------------
HDMapLogToPhy proc
;On Entry: reg AL contains physical based logical drive number
;On Exit : ZR clr and DS:SI contains dword pointer to offset +0
; of logical drive's entry in HDIndex table, else ZR set
; indicating no valid data found for drive in HDindex.
push ax
get_ptr_to_log_info:
;get ptr to logical drive's entry in HDIndex table
pop ax
;Check if have valid data in HDindex for this logical drive. A zero
;value in first field (logical drive #) indicates no data. Comparison
;here sets or clrs ZR flag that can be tested by caller.
cmp byte ptr [si],0
RET
HDMapLogToPhy endp
; ----------------------------------------------
; FUNCTION: HDSysInventory
; ----------------------------------------------
HDSysInventory proc
;Perform system hard drive inventory, apply DOS logical drive
assignment
;rules to build final lookup table to be used by proc HDMapLogToPhy.
;Use BIOS Int 13h, fcn 15h (read DASD type) to determine total # hard
drives
;in system instead of fcn 8h (return drv parms) because although fcn 8
;does infact return count of hard drives beyond 2, it's undocumented.
mov [num_hdrvs],0ffh ;init count to -1
mov dl,80h
count_hdrvs:
inc [num_hdrvs]
mov ah,15h
push dx
int 13h
pop dx
inc dl ;next hard drv #
cmp ah,3 ;hard drive?
je count_hdrvs ;yes, check for next one
call read_sector
jc next_HD ;read failed, num_logic_drvs in HDtable
;entry for this HD remains 0
ck_first_partition_table:
;FOR partition entry = 1 to 4 (16 bytes each)
mov si,offset sec_buffer+1beh ;partition bias in first sector
process_part_table:
cmp byte ptr [si][4],0 ;ck TYPE part. Used?
jz DONE_PART_TABLE ;no, assume no entries follow
mark_primary:
or [bx].part_flags,PRIM_PARTITION
inc [bx].num_logic_drvs
update_hdphys_tab:
;update HDphys table with this logical drive's info
call update_HDphys
next_part_tab_entry:
add si,16
jmp short process_part_table
process_extended:
;Extended partition table can only have up two entries in it:
;one for the logical drive and a possible extended entry for
;next logical drive in this extended partition.
;Therefore we continue to process extended partition obtaining
;new first sectors for any additional logical drives.
call read_sector
jc next_HD ;read failed, do not process any more
;logical drives for this extended partition
process_ext_entry:
;end of extended table?
cmp byte ptr [si][4],0 ;ck TYPE part. Used?
Jz next_HD ;no, done ext table
;have entry, find out what, eliminate DOS logical drive type
call ck_primary_part
jz inc_log_count
inc_log_count:
inc [bx].num_logic_drvs
next_ext_entry:
add si,16 ;next ext partition table entry
jmp short process_ext_entry
NEXT_HD:
call next_HDentry
jb PROCESS_HD
DONE_PART_TABLE:
;Now Apply DOS Logical drive assignment rules.
mov al,[first_HD_log]
mov [log_drv_no],al
mov di,offset HDindex
PROCESS_A_Z:
;Process entries marked with primary attribute first.
;Check remaining entries in table for primaries to be assigned.
mov bx,offset HDtable
mov [HDdrv_no],0
PRIMARY_CHK:
;any logical drives left on this physical drive?
cmp [bx].num_logic_drvs,0
jz next_prim_ck ;no
test [bx].part_flags,PRIM_PARTITION
jz next_prim_ck
test [bx].part_flags,PRIM_ASSIGNED
jnz next_prim_ck
next_prim_ck:
call next_HDentry
jb primary_chk
;no more primaries, now process logical drives that were found in
;extended partitions
mov bx,offset HDtable
mov [HDdrv_no],0
LOGICAL_CHK:
;any logical drives left?
cmp [bx].num_logic_drvs,0
je next_log_ck
;yes, update HDtable entry for this log drive and display stats
call create_index_table_entry
call update_remain_and_seq_numbers
jmp short NEXT_LOG ;this log drive done
next_log_ck:
call next_HDentry
jb logical_chk
SECOND_PRIM_CHK:
;any logical drives left on this physical drive?
cmp [bx].num_logic_drvs,0
jz next_sec_prim_ck ;no
test [bx].part_flags,SEC_PRIM_PART
jz next_sec_prim_ck
test [bx].part_flags,SEC_PRIM_ASSIGN
jnz next_sec_prim_ck
next_sec_prim_ck:
call next_HDentry
jb second_prim_chk
NEXT_LOG:
;next logical drive
inc [log_drv_no]
cmp [log_drv_no],MAX_LOG_NO
jbe PROCESS_A_Z
HDSysInventory endp
; ----------------------------------------------
; MISC SUPPORT PROCS
; ----------------------------------------------
READ_SECTOR proc
;On Entry: ax, cx, dx contains values:
; dl = bios hard disk number
; dh = head number
; cl = sector# (bits 5-0); bits 7,6 (cylinder 2 high bits)
; ch = cylinder# (low order 7 bits)
;On exit: CY set if could not read drive, else CY clr
push bx
mov bx,offset sec_buffer
mov ax,0201h ;read one sector
int 13h
pop bx
ret
READ_SECTOR endp
NEXT_HDENTRY proc
;On exit: bx ptr updated to next hdtable entry
; var HDdrv_no incremented
; CY set if have another entry to process
CK_PRIMARY_PART proc
;On exit: ZR flag set if have DOS primary partition type
; AL has partition type
UPDATE_HDPHYS proc
;On entry: al has partition fat type
;On Exit : ptr to HDphys is updated to next available table entry
CREATE_INDEX_TABLE_ENTRY proc
;create index table entry from HDtable and HDPhys table info
;first locate operand HD in table by indexing on [HDdrv_no]
push si
push di
pop di
add di,SIZE_HDindex ;point to next IDX avail. entry
pop si
ret
CREATE_INDEX_TABLE_ENTRY endp
UPDATE_REMAIN_AND_SEQ_NUMBERS proc
;obtain logical sequence number, increment it and decrement
;remaining log drvs for this entry
;Return: al has log drv seq number (one based)
mov al,[bx].sequence_num
inc al ;make physical based
inc [bx].sequence_num
dec [bx].num_logic_drvs
ret
UPDATE_REMAIN_AND_SEQ_NUMBERS endp
END START