昨天把磁盘的结构搞清楚了,今天搞清楚软盘的细解。函数
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