⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat12-f.asm

📁 一个类linux的dos下开发的操作系统.
💻 ASM
📖 第 1 页 / 共 2 页
字号:
; jump to second stage that is ORGed to address "SS_ORG"
%ifdef DOS
	mov ax,ds
	add ax,((SS_ADR - SS_ORG) >> 4)
%else
	mov ax,((SS_ADR - SS_ORG) >> 4)
%endif
	mov ds,ax
	mov es,ax
	mov ss,ax
	push ax
	push word SS_ORG
	retf

; disk read error; display blinking 'R'
err:
	mov ax,9F52h
err2:
	mov bx,0B800h				; assumes color emulation
	mov es,bx
	xor bx,bx
	mov [es:bx],ax

; *** BEEEP ***
	mov ax,0E07h
	int 10h

; await key pressed
	mov ah,0
	int 16h

; re-start the boot process
	int 19h

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; name:			find_file
; action:		searches for file in root dir
; in:			11-char all-caps filename at SI, [root_start] set
; out (disk error):	CY=1
; out (file not found):	CY=0, ZF=0
; out (found it):	CY=0, ZF=1, BX=starting cluster of file,
;			ES:DI is left pointing to the directory entry
; modifies:		AX, BX, CX, DX, DI, ES
; minimum CPU:		8088
; notes:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

find_file:
		xor dx,dx
		mov ax,[root_start]		; 1st sector in root dir
%ifdef DOS
		mov bx,ds			; where to load it
		add bx,(ADR_DIRBUF >> 4)
%else
		mov bx,(ADR_DIRBUF >> 4)
%endif
		mov es,bx
find_file_1:
		mov cx,1
		call read_sectors		; one sector at a time
		jc find_file_5			; disk read error
		xor di,di
find_file_2:
		test [es:di],byte 0FFh		; 0 byte = end of root dir
		je find_file_3
		mov cl,11			; 'read_sectors' zeroed CH
		push si
		push di				; compare filename to dirent
			rep cmpsb
		pop di
		pop si
		je find_file_4

; if filename comparision failed, advance 32 bytes to next dir entry
		add di,byte 32
		cmp di,[bp - (over -bytes_per_sector)]
		jb find_file_2
		inc ax
		cmp ax,[bp - (over - data_start)]
		jb find_file_1			; go to next sector of root

find_file_3:
; did not find the file: return with CY=0, ZF=0
		or al,1
find_file_4:
; found the file
		mov bx,[es:di + 26]		; get first cluster of file
find_file_5:
	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; name:			walk_fat
; action:		converts cluster value to sector,
;			and gets next cluster of file from FAT
; in:			BX=cluster
; out (disk error):	CY=1
; out (success):	CY=0, DX:AX=first sector of cluster, BX=next cluster
; modifies:		AX, BX, DX, SI
; minimum CPU:		8088
; notes:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

walk_fat:
	push es
	push cx
		mov ax,bx

; cluster 2 is the first data cluster
		dec ax
		dec ax

; convert from clusters to sectors
		mov dh,0
		mov dl,[bp - (over - sectors_per_cluster)]
		mul dx
		add ax,[bp - (over - data_start)]
		adc dx,byte 0

; 0:AX is return value; save it
		push ax

%ifdef DOS
			mov ax,ds
			add ax,(ADR_FATBUF >> 4)
%else
			mov ax,(ADR_FATBUF >> 4)
%endif
			mov es,ax

; FAT12 entries are 12 bits, bytes are 8 bits. Ratio is 3 / 2,
; so multiply cluster by 3, and divide by 2 later.
			mov ax,bx
			shl ax,1		; entry * 2
			add ax,bx		; + entry = entry * 3

			mov bx,ax
; BX:0		=use high or low 12 bits of 16-bit value read from FAT
; BX:9...BX:1	=byte offset into FAT sector (9 assumes 512-byte sectors)
; BX:?...BX:10	=which sector of FAT to load

; figure out which FAT sectors to load
			shr ax,1		; entry / 2
			xor dx,dx
			div word [bp - (over - bytes_per_sector)]

; remainder is byte offset into FAT; put it in SI
			mov si,dx

; quotient in AX is FAT sector: add FAT starting sector
			add ax,[bp - (over - fat_start)]


; check the FAT buffer to see if this sector is already loaded
			cmp ax,[bp - (over - curr_sector)]
			je walk_fat_1
			mov [curr_sector],ax

; read the target FAT sector plus the sector after it
; (in case the 12-bit FAT entry straddles the two sectors)
			xor dx,dx
			mov cx,2
			call read_sectors
			jc walk_fat_4
; get 16 bits from FAT
walk_fat_1:
			mov ax,[es:si]

; look at BX:0 to see if we want the high 12 bits or the low 12 bits
			shr bx,1
			jc walk_fat_2
			and ax,0FFFh		; CY=1: use low 12 bits
			jmp short walk_fat_3
walk_fat_2:
			mov cl,4
			shr ax,cl		; CY=0: use high 12 bits
walk_fat_3:
			mov bx,ax

; clear CY bit to signal success
			xor dx,dx
walk_fat_4:
		pop ax

	pop cx
	pop es
	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; name:			read_sectors
; action:		reads one or more disk sectors into memory
; in:			ES:0=address of memory where sectors should be read
;			DX:AX=first sector to read
;			CX=number of sectors to read
; out (disk error):	CY=1
; out (success):	CY=0
; modifies:		DX, CX, AX
; minimum CPU:		8088
; notes:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

read_sectors:
	push es
	push bx
		xor bx,bx

; add partition start
		add ax,[bp - (over - hidden_sectors) + 0]
		adc dx,[bp - (over - hidden_sectors) + 2]
read_sectors_1:
		push dx
		push cx
		push ax

; DX:AX=LBA sector number
			push ax
				mov ax,dx
				xor dx,dx

; divide LBA by sectors_per_track (spt).
; Use a two-step 32-bit/16-bit divide to avoid overflow.
; See "9.3.5 Extended Precision Division" in Randall Hyde's "Art of Assembly"
				div word [bp- (over - sectors_per_track)]

; DX=high LBA % spt, AX=high LBA / spt
				mov cx,ax
			pop ax

; DX=high LBA % spt, CX=high LBA / spt, AX=low LBA
; New 32-bit dividend is DX:AX
			div word [bp- (over - sectors_per_track)]

; CX:AX=LBA / spt, DX=LBA % spt
			xchg cx,dx
			inc cx			; CL=sector

; DX:AX=LBA / spt, do normal one-step divide by heads value
			div word [bp - (over - heads)]
			mov dh,dl		; DH=head
			mov ch,al		; CH=cylinder 7:0
			mov dl,[bp - (over - boot_drive)]
			shl cl,1
			shl cl,1		; trying to use only...
			shr ah,1		; ...8088 asm here
			rcr cl,1
			shr ah,1
			rcr cl,1		; CL7:6=cyl 9:8, CL5:0=sector

; now: read one sector
			mov ax,0201h
			int 13h
			jnc read_sectors_3

; disk error; recalibrate/reset drive
			mov ah,0
			int 13h
			jc read_sectors_2
; try the read again. If it fails a second time, give up.
			mov ax,0201h
			int 13h
			jnc read_sectors_3
read_sectors_2:
		pop ax
		pop cx
		pop dx
		jmp short read_sectors_5

; advance memory pointer
read_sectors_3:
			mov ax,es
			add ax,[bp - (over - para_per_sector)]
			mov es,ax
		pop ax
		pop cx
		pop dx

; increment DX:AX to advance to next sector
		inc ax
		jne read_sectors_4
		inc dx
read_sectors_4:
		loop read_sectors_1

; clear CY bit to signal success
		clc
read_sectors_5:
	pop bx
	pop es
	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 1st-stage data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

curr_sector:	; which sector is in the FAT buffer
	dw -1

; name of the second stage bootloader
second_stage:
	db SS_NAME

; pad with NOPs to offset 510
	times (510 + $$ - $) nop

; 2-byte magic bootsector signature
	db 55h, 0AAh

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -