| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1118 人关注过本帖
标题:【分享】关于int 13H
只看楼主 加入收藏
isunxuechun
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2008-3-26
收藏
 问题点数:0 回复次数:0 
【分享】关于int 13H
无意间在Google中找到了一个网址,发现里面是一段汇编源代码,但看了半天,奈何功力太浅竟然无法全部弄明白,同时秉着共同分享的心情将代码贴在这儿,望哪位前辈高人能够将其中的种种分析一下,拜托!

        ENTRY   0EC59h                          ; IBM entry point for floppy

INT_13: STI                                     ; Floppy disk services
        PUSH    BP
        PUSH    SI
        PUSH    DI
        PUSH    DS
        PUSH    ES
        PUSH    BX
        MOV     DI,AX                           ; Request type in DI, for index
        XOR     AX,AX
        MOV     DS,AX                           ; get interrupt vector 13h
        LES     SI,DWord ptr DS:78h             ; Get disk parameter table
        MOV     AX,40h
        MOV     DS,AX
        MOV     BX,5
        MOV     AX,ES:[BX+SI]                   ; Get (Gap Length, DTL) in AX
        PUSH    AX                              ;  ...save it
        DEC     BX
        DEC     BX
        MOV     AX,ES:[BX+SI]                   ; Get (Bytes/sector,EOT) in AX
        PUSH    AX                              ;  ...save it
        XCHG    CL,DH
        XCHG    DL,CL
        PUSH    DX                              ; Push (Head,Drive) swapped
        PUSH    CX
        PUSH    DI
        MOV     BP,SP                           ; Mark bottom of stack frame
ifdef   SLOW_FLOPPY
        CALL    FD_SPD                          ;  ...execute request lo speed
else
        CALL    FD_XQT                          ;  ...execute at current speed
endif
        MOV     AH,ES:[SI+2]                    ; Get new motor count
        MOV     DS:40h,AH                       ;  ...and save it
        MOV     AH,DS:41h                       ; Get completion status
        CMP     AH,1                            ;  ...check for write protect
        CMC                                     ;  ...was write protect error
        POP     BX
        POP     CX
        POP     DX
        XCHG    DL,CL
        XCHG    CL,DH
        POP     BX                              ; Clean
        POP     BX                              ;  ...up
        POP     BX                              ;  ...stack
        POP     ES
        POP     DS
        POP     DI
        POP     SI
        POP     BP
        RETF    2

FD_XQT: MOV     AL,[BP+1]                       ; Get floppy service number
        OR      AL,AL
        JZ      FD_RST                          ;  ...reset, AH=0
        DEC     AL
        JZ      FD_XQ3                          ;  ...read status, AH=1
        CMP     Byte ptr [BP+2],3               ; For track number above 3?
        JA      FD_XQ1                          ;  ...yes
        CMP     AL,5                            ; Service within range?
        JBE     FD_XQ2                          ; ...yes

FD_XQ1: MOV     Byte ptr DS:41h,1               ; Say write protect error
        RET

FD_XQ2: JMP     FD_001                          ; Execute legal service

FD_XQ3: MOV     AL,DS:41h                       ; Return NEC status byte
        RET

FD_RST: MOV     DX,3F2h                         ; Reset the floppy disk system
        CLI
        AND     Byte ptr DS:3Fh,0Fh             ; Clear "write in progress"
        MOV     AL,DS:3Fh                       ;  ...find out busy drives
        MOV     CL,4
        SHL     AL,CL
        TEST    AL,20h
        JNZ     FD_RS1                          ; Drive #1 active
        TEST    AL,40h
        JNZ     FD_RS2                          ; Drive #2 active
        TEST    AL,80h
        JZ      FD_RS0                          ; Drive #3 idle

FD_RS3: INC     AL
FD_RS2: INC     AL
FD_RS1: INC     AL

FD_RS0: MOV     Byte ptr DS:3Eh,0               ; All drives need recalibrate
        MOV     Byte ptr DS:41h,0               ;  ...no completion status
        OR      AL,8                            ; Interrupt ON in command word
        OUT     DX,AL                           ;  ...send word to controller
        OR      AL,4                            ; "Reset" in command word
        OUT     DX,AL                           ;  ...send word to controller
        STI
        CALL    NC_BSY                          ; Wait for completion
        CALL    NC_STS                          ;  ...read result block
        MOV     AL,DS:42h
        CMP     AL,0C0h                         ; Did the reset work
        JZ      FD_RS4                          ;  ...yes
        MOV     Byte ptr DS:41h,20h             ; Else set controller error
        JMP     SHORT   FD_RS5                  ;  ...return

FD_RS4: MOV     AL,3                            ; Specify command to NEC
        CALL    NEC765                          ;  ...send it
        MOV     AL,ES:[SI]                      ; First byte in param block
        CALL    NEC765                          ;  ...send it
        MOV     AL,ES:[SI+1]                    ; Secnd byte in param block
        CALL    NEC765                          ;  ...send it

FD_RS5: RET

NECFUN  DB      003h,000h,0E6h,0C5h,0E6h,04Dh   ; NEC function table lookup
NECDMA  DB      000h,000h,046h,04Ah,042h,04Ah   ; DMA modes for 8237
NECWRT  DB      000h,000h,000h,080h,000h,080h   ; Write flag   table lookup
NECDRV  DB      1,2,4,8                         ; Drive number table lookup
NECERR  DB      80h,20h,10h,4,2,1               ; Error code   table lookup
NECSTS  DB      04h,10h,08h,04h,03h,02h,20h     ; Disk status  table lookup

FD_001: CLI                                     ; Normal (non-reset) commands
        MOV     Byte ptr DS:41h,0               ;  ...reset status
        MOV     AL,[BP+1]                       ; Get command word
        XOR     AH,AH
        MOV     DI,AX                           ; Save copy, zero-extended
        OUT     0Ch,AL                          ;  ...diddle LSB/MSB flip-flop
        MOV     AL,CS:[DI+NECDMA]               ; Fetch DMA mode
        OUT     0Bh,AL                          ;  ...send it to IC8237
        MOV     AX,[BP+0Ch]                     ; Get segment address
        MOV     CL,4                            ;  ...convert
        ROL     AX,CL                           ;  ...to bytes
        MOV     CH,AL                           ; Copy the wrap around
        AND     CH,0Fh                          ;  ...mask out not wrapped, CH
        AND     AL,0F0h                         ;  ...mask out wrapped, AL
        ADD     AX,[BP+0Ah]                     ; Add offset to AX
        ADC     CH,0                            ;  ...do carry if set
        MOV     DX,AX                           ; Now save lo 16 bits of addr.
        OUT     4,AL                            ;  ...send lowest 8 bits  " "
        MOV     AL,AH
        OUT     4,AL                            ;  ...send next   8 bits  " "
        MOV     AL,CH
        OUT     81h,AL                          ; Send hi bits to DMA page reg
        MOV     AH,[BP+0]
        XOR     AL,AL
        SHR     AX,1                            ; Sector cnt * 128
        MOV     CL,[BP+6]                       ; Track count
        SHL     AX,CL                           ;  * sector count
        DEC     AX                              ; - 1
        OUT     5,AL                            ; Send 1/2 of the word count
        XCHG    AL,AH
        OUT     5,AL                            ; Send 2/2 of the word count
        XCHG    AL,AH
        ADD     AX,DX                           ; Compute final address
        JNB     FD_002                          ;  ...ok
        STI
        MOV     Byte ptr DS:41h,9h              ; Else wrapped around page reg
        JMP     FD_011

FD_002: MOV     AL,2                            ; Disable floppy disk dma
        OUT     0Ah,AL
        MOV     Byte ptr DS:40h,0FFh            ; Set large motor timeout
        MOV     BL,[BP+2]                       ;  ...get drive number
        XOR     BH,BH
        MOV     AL,CS:[BX+NECDRV]               ; Table lookup bit position
        MOV     CH,AL                           ;  ...save mask
        MOV     CL,4
        SHL     AL,CL                           ; Shift mask into place
        OR      AL,BL                           ;  ...or in drive select
        OR      AL,0Ch                          ;  ...or in DMA and NO RESET
        MOV     DX,3F2h
        OUT     DX,AL                           ; Send to floppy control port
        STI
        MOV     AL,CS:[DI+NECWRT]               ; Table lookup for write  flag
        OR      DS:3Fh,AL                       ;  ...set write flag if active
        OR      AL,AL
        JNS     FD_003                          ;  ...skip if non-write
        MOV     AH,ES:[SI+0Ah]                  ; Motor start from param blk
        OR      AH,AH
        JZ      FD_003                          ;  ...none specified
        TEST    CH,DS:3Fh                       ; Was this drive motor running?
        JNZ     FD_003                          ;  ...skip if so
        CALL    FD_WT1                          ; Else delay for motor start

FD_003: OR      DS:3Fh,CH                       ; Show this motor is running
        TEST    CH,DS:3Eh                       ; Drive recalibration needed?
        JNZ     FD_004                          ;  ...no, skip
        OR      DS:3Eh,CH                       ; Else show recalibrated
        MOV     AL,7                            ; Send RECAL command
        CALL    NEC765                          ;  ...to NEC 765 chip
        MOV     AL,BL
        CALL    NEC765                          ;  ...drive number
        CALL    NC_BSY                          ; Wait for completion of RECAL
        CALL    NEC_04                          ;  ...dummy call to RET

FD_004: MOV     AL,0Fh                          ; Request a seek
        CALL    NEC765                          ;  ...from the NEC 765
        MOV     AL,BL
        CALL    NEC765                          ; Drive number
        MOV     AL,[BP+3]
        CALL    NEC765                          ; Cylinder number
        CALL    NC_BSY                          ;  ...wait for completion
        CALL    NC_STS                          ;  ...read results
        MOV     AL,ES:[SI+9]                    ; Get head settle time
        OR      AL,AL                           ;  ...none specified?
        JZ      FD_005                          ;  ...if none, skip

FD_STL: MOV     CX,226h                         ; Delay time for head settle

FD_STZ: LOOP    FD_STZ                          ;  ...timed wait
        DEC     AL                              ;  ...delay in millisec
        JNZ     FD_STL                          ;  ...wait some more

FD_005: MOV     AL,CS:[DI+NECFUN]               ; Translate user service, then
        CALL    NEC765                          ;  ...and send as NEC func
        MOV     AL,[BP+4]                       ;
        AND     AL,1
        SHL     AL,1
        SHL     AL,1
        OR      AL,BL
        CALL    NEC765
        CMP     Byte ptr [BP+1],5               ; Is this a format request?
        JNZ     FD_006                          ;  ...skip if not
        MOV     AL,[BP+6]                       ; Else use user bytes/sector
        CALL    NEC765
        MOV     AL,[BP+7]                       ;  ... user EOT  
        CALL    NEC765
        MOV     AL,ES:[SI+7]                    ; Disk table format gap length
        CALL    NEC765
        MOV     AL,ES:[SI+8]                    ; Disk table format fill byte
        CALL    NEC765
        JMP     SHORT   FD_008

FD_006: MOV     CX,7                            ; Else lookup bytes * 512/sec
        MOV     DI,3                            ;  ...from disk table

FD_007: MOV     AL,[BP+DI]                      ; AL has bytes/sector * 512
        CALL    NEC765
        INC     DI                              ;  ...get next item for table
        LOOP    FD_007                          ;  ...also (EOT,GAP,DTL...)

FD_008: CALL    NC_BSY                          ; Wait on floppy i/o completion
        CALL    NC_ST1                          ;  ...get NEC status
        MOV     AL,DS:42h                       ;  ...into AL
        AND     AL,0C0h                         ; Isolate errors
        JZ      FD_012                          ;  ...no errors
        CMP     AL,40h                          ; Test direction bit
        JZ      FD_ERR
        MOV     Byte ptr DS:41h,20h             ; Set if bad controller
        JMP     SHORT   FD_012                  ;  ...return error

FD_ERR: MOV     AL,DS:43h                       ; Read return code from block
        MOV     CX,6                            ;  ...number of error types
        XOR     BX,BX                           ; Start at error type 0

FD_009: TEST    AL,CS:[BX+NECERR]               ; Has error type BX occured?
        JNZ     FD_010                          ;  ...yes
        INC     BX                              ; Else try next error type
        LOOP    FD_009                          ;  ...until done

FD_010: MOV     AL,CS:[BX+NECSTS]               ; Translate error code again
        MOV     DS:41h,AL                       ;  ...store it as disk status

FD_012: MOV     AL,DS:45h                       ; Get bytes read
        CMP     AL,[BP+3]                       ;  ...compare with requested
        MOV     AL,DS:47h                       ; Read sectors requested
        JZ      FD_013                          ;  ...return if all read
        MOV     AL,[BP+7]                       ; Else read sectors requested
        INC     AL                              ;  ...add one for luck

FD_013: SUB     AL,[BP+5]                       ; Subtract stectors read
        RET

FD_011: MOV     AL,0                            ; Show no sectors read
        RET

NC_BSY: STI                                     ; Wait for operatin to finish
        XOR     CX,CX                           ;  ...zero lo orderdelay
        MOV     AL,2                            ; Load hi order delay

NC_BS1: TEST    Byte ptr DS:3Eh,80h             ; Has interrupt set the flag?
        CLC                                     ;  ...hack to slow CPU
        JNZ     NC_BS2                          ;  ...yes
        LOOP    NC_BS1                          ; Else back for more
        DEC     AL
        JNZ     NC_BS1

        MOV     Byte ptr DS:41h,80h             ; Time-out, say it completed
        POP     AX
        XOR     AL,AL                           ;  ...return time out code
        STC                                     ;  ...error status
        RET

NC_BS2: AND     Byte ptr DS:3Eh,7Fh             ; Mask off completion status
        RET                                     ;  ...return carry clear

NC_RDY: PUSH    CX                              ; Wait for NEC ready for comand
        XOR     CX,CX
        MOV     DX,3F4h                         ;  ...NEC status port

NC_RD1: IN      AL,DX                           ; Read status of NEC 765 chip
        OR      AL,AL
        JS      NC_RD2                          ;  ...able to accept command
        LOOP    NC_RD1
        MOV     Byte ptr DS:41h,80h             ; Else show timeout error
        JMP     SHORT   NC_RD3

NC_RD2: TEST    AL,40h                          ; Test the direction bit
        JNZ     NC_RD4
        MOV     Byte ptr DS:41h,20h             ;  ...clear iff controller err

NC_RD3: POP     CX
        STC
        RET

NC_RD4: INC     DX                              ; Load NEC data port
        IN      AL,DX                           ;  ...read it
        PUSH    AX

        MOV     CX,0Ah                          ; Short delay
NC_RD5: LOOP    NC_RD5

        DEC     DX                              ; Load NEC status port
        IN      AL,DX                           ;  ...read status
        TEST    AL,10h                          ;  ...set Z flag if done
        CLC                                     ;  ...return success
        POP     AX
        POP     CX
        RET

FD_WT1: PUSH    CX                              ; Millisecond delay in AH
FD_WT2: XOR     CX,CX
FD_WT3: LOOP    FD_WT3
        DEC     AH
        JNZ     FD_WT2
        POP     CX
        RET

ifdef   SLOW_FLOPPY                             ; Run floppy at SLOWEST speed

FD_SPD: IN      AL,61h                          ; Toggle speed on Floppy Disk
        PUSH    AX                              ;  ...save old clock rate
        AND     AL,0F3h                         ;  ...load slowest clock rate
        OUT     61h,AL                          ;  ...slow down to 4.77 mHz
        CALL    FD_XQT                          ; Execute the i/o request
        POP     AX                              ;  ...restore old clock rate
        OUT     61h,AL                          ;  ...from saved clock byte
        RET
endif

        ENTRY   0EF57h                          ; Disk interrupt entry

INT_E:  STI                                     ; Floppy disk attention
        PUSH    DS
        PUSH    AX
        MOV     AX,40h
        MOV     DS,AX
        OR      Byte ptr DS:3Eh,80h             ; Raise "attention" flag
        MOV     AL,20h                          ; Send end_of_interrupt code
        OUT     20h,AL                          ;  ...to 8259 interrupt chip
        POP     AX
        POP     DS
        IRET

NC_STS: MOV     AL,8                            ; Send a "Request status"
        CALL    NEC765                          ;  ...to the NEC 765 chip

NC_ST1: PUSH    BX                              ; Alternate entry point
        PUSH    CX
        MOV     CX,7
        XOR     BX,BX

NC_ST2: CALL    NC_RDY                          ; Wait for NEC 765 ready
        JB      NC_ST3                          ;  ...NEC 765 error
        MOV     [BX+42h],AL                     ; Save status in BIOS block
        JZ      NC_ST4                          ;  ...NEC 765 ready
        INC     BX                              ; Count more
        LOOP    NC_ST2
        MOV     Byte ptr DS:41h,20h             ; NEC 765 controller error

NC_ST3: STC                                     ; Set error condition
        POP     CX
        POP     BX
        POP     AX
        XOR     AL,AL
        RET

NC_ST4: POP     CX                              ; Successful return
        POP     BX
        RET

NEC765: PUSH    CX                              ; Send control to NEC 765 chip
        PUSH    DX
        PUSH    AX
        XOR     CX,CX
        MOV     DX,3F4h                         ; Load NEC 765 status port

NEC_01: IN      AL,DX                           ; Read NEC 765 status
        OR      AL,AL
        JS      NEC_02                          ;  ...done
        LOOP    NEC_01
        MOV     Byte ptr DS:41h,80h             ; Set time out status
        JMP     SHORT   NEC_05

NEC_02: TEST    AL,40h                          ; Check data direction
        JZ      NEC_03
        MOV     Byte ptr DS:41h,20h             ;  ...NEC 765 is gimped
        JMP     SHORT   NEC_05

NEC_03: INC     DX                              ; Load NEC 765 data port
        POP     AX
        OUT     DX,AL                           ;  ...write user's parameter
        CLC
        POP     DX
        POP     CX
NEC_04: RET

NEC_05: POP     AX                              ; Common error return
        POP     DX
        POP     CX
        POP     AX
        XOR     AL,AL
        STC
        RET

        ENTRY   0EFC7h                          ; IBM entry for disk param

INT_1E: db      11001111B                       ; Disk parameter table
        db      2
        db      25h
        db      2
        db      8
        db      2Ah
        db      0FFh
        db      50h
        db      0F6h
        db      19h
        db      4
搜索更多相关主题的帖子: int 分享 
2008-03-30 00:12
快速回复:【分享】关于int 13H
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.024011 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved