六、直接读一个软盘扇区

    昨天把磁盘的结构搞清楚了,今天搞清楚软盘的细解。

    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 提供了对磁盘读写操作的相关中断:

; ========================================================================================
; int 13h(直接磁盘服务)功能表
; ----------------------------------------------------------------------------------------
; 1、磁盘系统复位
; 入口参数: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 — 检测操作失败(硬盘)
; ----------------------------------------------------------------------------------------
; 2、读、写 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 中断提供的读写操作不能跨越磁道,连续读两个扇区有可能导致跨越扇区的错误,写一个只一个扇区操作。很简单,照着上面的公式计算就行:

; ----------------------------------------------------------------------------------------
; 函数功能:从软盘读取 1 个逻辑扇区
; 入口参数:ax = 逻辑扇区号
;           es : bx = 存放数据的内存缓冲区地址
; 出口参数:同 ah = 2、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


你可能感兴趣的:(六、直接读一个软盘扇区)