6、直接讀一個軟盤扇區

    昨天把磁盤的結構搞清楚了,今天搞清楚軟盤的細解。函數

    3.5 英寸軟盤是舊時代的產物了,只能採用 CHS 方式尋址編碼

; ========================================================================================
; 3.5英寸軟盤的 CHS 參數:
;   80個柱面,柱面編號 0 ~ 79;
;   2個磁頭,磁頭編號 0、1;
;   每一個磁道有 18 個扇區,每一個磁道上扇區編號 1 ~ 18;
;   每一個扇區可存放 512 字節的數據。
; ----------------------------------------------------------------------------------------
; LBA 與 CHS 的換算:
;   NH 表示磁頭數,NS 表示每磁道扇區數,C、H、S 表示柱面號、磁頭號和扇區號
;   LBA 表示邏輯扇區號
;   div 表示整除求商,mod 表示整除求餘
;   則由:LBA = ( NH × C + H ) × NS + S - 1
;   推算出:C = ( LBA div NS ) div NH,H = ( LBA div NS ) mod NH,S = ( LBA mod NS ) + 1
; ----------------------------------------------------------------------------------------
; 對 3.5 英寸軟盤而言,NH = 2,NS = 18,則:
;   C = LBA div 36,H = ( LBA div 18) mod 2,S = ( LBA mod 18) + 1
; ****************************************************************************************

    系統 BIOS 提供了對磁盤讀寫操做的相關中斷:
spa

; ========================================================================================
; int 13h(直接磁盤服務)功能表
; ----------------------------------------------------------------------------------------
; 一、磁盤系統復位
; 入口參數:AH = 00H
;           DL = 須要進行復位的驅動器號:00H ~ 7FH 爲軟驅(00h 軟驅 A,01h 軟驅 B ……)
;                                         80H ~ FFH 爲硬盤(80h 硬盤 C,81h 硬盤 D ……)
; 出口參數:CF = 0 —— 操做成功,AH = 00H;
;                          不然,AH = 狀態代碼,其定義以下:
;                                      00H — 無錯
;                                      01H — 非法命令
;                                      02H — 地址目標未發現
;                                      03H — 磁盤寫保護(軟盤)
;                                      04H — 扇區未發現
;                                      05H — 復位失敗(硬盤)
;                                      06H — 軟盤取出(軟驅)
;                                      07H — 錯誤的參數表(硬盤)
;                                      08H — DMA(Direct Memory Access)越界(軟盤)
;                                      09H — DMA 超過 64K 界限
;                                      0AH — 錯誤的扇區標誌(硬盤)
;                                      0BH — 錯誤的磁道標誌(硬盤)
;                                      0CH — 介質類型未發現(軟盤)
;                                      0DH — 格式化時非法扇區號(硬盤)
;                                      0EH — 控制數據地址目標被發現(硬盤)
;                                      0FH — DMA 仲裁越界(硬盤)
;                                      10H — 不正確的 CRC(Cyclic Redundancy Check code)
;                                          或 ECC(Error Checking & Correcting code)編碼
;                                      11H — ECC 校訂數據錯(硬盤)
;                                      20H — 控制器失敗
;                                      40H — 查找失敗
;                                      80H — 磁盤超時(未響應)
;                                      AAH — 驅動器未準備好(硬盤)
;                                      BBH — 未定義的錯誤(硬盤)
;                                      CCH — 寫錯誤(硬盤)
;                                      E0H — 狀態寄存器錯(硬盤)
;                                      FFH — 檢測操做失敗(硬盤)
; ----------------------------------------------------------------------------------------
; 二、讀、寫 CHS 扇區
; 入口參數:AH = 功能號:02H 讀扇區、03H 寫扇區
;           AL = 須要進行操做的扇區個數,須要進行操做的所有扇區必須在同一條磁道內
;           CH = 柱面號
;           CL = 起始扇區號
;           DH = 磁頭號
;           DL = 驅動器號:00H ~ 7FH 爲軟驅(00h 軟驅 A,01h 軟驅 B ……)
;                           80H ~ FFH 爲硬盤(80h 硬盤 C,81h 硬盤 D ……)
;           ES : BX = 存放數據的內存緩衝區地址
; 出口參數:CF = 0 —— 操做成功,AH = 00H,AL = 實際完成操做的扇區個數;
;                          不然,AH = 狀態代碼,參見上面的說明。
; ****************************************************************************************

    好了,準備工做都完成了,如今能夠直接讀寫3.5英寸軟盤了。因爲 int 0x13 中斷提供的讀寫操做不能跨越磁道,連續讀兩個扇區有可能致使跨越扇區的錯誤,寫一個只一個扇區操做。很簡單,照着上面的公式計算就行:code

; ----------------------------------------------------------------------------------------
; 函數功能:從軟盤讀取 1 個邏輯扇區
; 入口參數:ax = 邏輯扇區號
;           es : bx = 存放數據的內存緩衝區地址
; 出口參數:同 ah = 二、int 0x13
Read1Sector:
    push bp
    mov bp, sp

    push dx
    push cx

    ; 由 LBA 計算 CHS
    mov dl, 18
    div dl
    mov ch, al
    mov dh, al
    mov cl, ah
    shr ch, 1
    inc cl
    and dh, 1

    ; 讀一個扇區
    mov ax, 0x0201
    xor dl, dl
    int 0x13

.Return:
    pop cx
    pop dx

    mov sp, bp
    pop bp
    ret
相關文章
相關標籤/搜索