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

📄 dmar.asm

📁 大学微型计算机接口技术实验源代码,直接就可以运行,包含了C++和asm代码,比较前面.
💻 ASM
字号:
;*************************************
;*		Source Code
;*		"DMA Write" 
;*		采用DMA方式读软盘数据到主存
;*		DMAC: 0号8237A
;*		FDC: uPD765
;*************************************

	;8237的模式字:
	;46H: 单一方式,地址加1,非自动预置,DMA写主存,通道2
	;4aH: 单一方式,地址加1,非自动预置,DMA读主存,通道2
;=====================================================

DMA	EQU	0
;=====================================================
DISP_CH	MACRO	CHAR
	PUSH	BX
	MOV	AL,CHAR		;字符
	MOV	AH,0EH		;显示字符
	MOV	BL,0		;背景色
	INT	10H
	POP	BX
        ENDM
;=====================================================        
SSTACK	SEGMENT	PARA	STACK 	'STACK'
	DB	100	DUP(?)
SSTACK	ENDS
;=====================================================
S0040	SEGMENT	AT	40H		;以下11字节为软盘数据区
	ORG	3EH
DISKDATA	LABEL	BYTE	
SSS		DB	?		;询道状态
MS		DB	?		;马达状态
MC		DB	?		;马达计数
DSS		DB	?		;软区状态
NS		DB	7 DUP(?)	;nec状态
S0040	ENDS
;=====================================================
DDATA           SEGMENT
DPARA		LABEL	BYTE		;软盘参数表,系统BIOS中使用的参数值
                DB      11011111B
		DB	00000010B
		DB	25H
                DB      02H
                DB      3FH
                DB      1BH
		DB	0FFH
                DB      054H
		DB	0F6H
                DB      0FH
                DB      08H
BUF             DB      512 DUP(?)      ;磁盘缓冲区
EMES            DB      'ERROR!$'
OLDPARAS	DW	0		;保存系统软盘参数入口地址
OLDPARAO	DW	0
OLDINTS		DW	0		;保存系统软盘中断处理程序入口
OLDINTO		DW	0
DDATA           ENDS
;=====================================================
CODE	SEGMENT	PARA	PUBLIC	'CODE'
        ASSUME  CS:CODE,ES:DDATA,DS:S0040,SS:SSTACK
START	PROC	FAR
        MOV     AX,DDATA
        MOV     DS,AX
	CLI				;关中断	
	XOR	AX,AX			;设置中断向量
	MOV	ES,AX
        MOV     DI,38H			;4*0EH,0EH号中断为软盘中断
	MOV	AX,ES:[DI]
	MOV	OLDINTO,AX
	MOV	AX,OFFSET DISKINT
	CLD	
	STOSW
	MOV	AX,ES:[DI]
	MOV	OLDINTS,AX
	MOV	AX,SEG	DISKINT
	STOSW

        MOV     DI,78H          	;4*1EH,1EH为软盘参数块
        MOV	AX,ES:[DI]
        MOV	OLDPARAO,AX
	MOV	AX,OFFSET DPARA
	STOSW
	MOV	AX,ES:[DI]
	MOV	OLDPARAS,AX
	MOV	AX,SEG	DPARA
	STOSW

	MOV	AX,S0040
	MOV	DS,AX
        MOV     AX,DDATA		;ES指向系统数据区
	MOV	ES,AX
	MOV	SI,OFFSET DPARA		;SI指向软盘参数区入口
	AND	SSS,07FH		;清中断标志
	STI

	MOV	DH,1			;设置DMA参数
	MOV	BX,OFFSET BUF
	MOV	AX,SEG BUF
	MOV	ES,AX
	MOV	AL,46H			;46H为8237的模式字
	CALL	DMA_SETUP

	JNC	ST1
	MOV	DSS,09H
	MOV	AX,09H			;返回DOS系统
	CALL	SHWORD
	MOV	AX,4C00H
	INT	21H

ST1:    MOV     AX,DDATA
	MOV	ES,AX
	CLI
	MOV	MC,0FFH			;马达延长计数值设置为最大
        TEST    MS,01H                  ;驱动器1马达是否已经转动
	JNZ	ST2			;已转动转J14
	
	AND	MS,0F0H			;以下为启动处理
        OR      MS,01H
	MOV	AL,00011100B		;选择驱动器1,开马达,允许中断,FDC
	MOV	DX,3F2H
	OUT	DX,AL			;送数字输出寄存器
	
	MOV	SSS,0
	MOV	DSS,0
	
ST2:	STI				;开中断,完成询道操作
        TEST    SSS,01H			;检查1号驱动器是否需要归零道
        JNZ     ST3
        
ST21:	MOV	AH,07H			;执行归零操作
	CALL	NEC_OUTPUT		
	MOV	BX,11H
	JC	ST22
	MOV	AH,0H
	CALL	NEC_OUTPUT
	MOV	BX,12H
	JC	ST21
        mov     cx,0F10h
st211:  CALL    CHK_STAT
        mov     bx,13h
	JNC	ST3
        loop    st211
ST22:	MOV	AX,bx
	CALL	SHWORD
	JMP	ENDR

ST3:	MOV	AH,0FH
	CALL	NEC_OUTPUT
        MOV     BX,21H
        JC      ST31
	MOV	AH,0
	CALL	NEC_OUTPUT
        MOV     BX,22H
        JC      ST31
        MOV     AH,12
	CALL	NEC_OUTPUT
        MOV     BX,23H
        MOV     CX,0F10H
ST311:  CALL    CHK_STAT
        mov     bx,24h
        JNC	J29
        LOOP    ST311
ST31:   MOV     AX,BX
	CALL	SHWORD
	JMP	ENDR
J29:	MOV	AH,ES:[SI+9]
J29A:	OR	AH,AH
	JZ	J31
        MOV     CX,550
J30:	LOOP	J30
	DEC	AH
	JMP	J29A
J31:    MOV     AH,066H
	CALL	NEC_OUTPUT
	MOV	AH,0
	CALL	NEC_OUTPUT
        MOV     AH,12
	CALL	NEC_OUTPUT
	MOV	AH,0
	CALL	NEC_OUTPUT
	MOV	AH,1
	CALL	NEC_OUTPUT
	MOV	AH,ES:[SI+3]
	CALL	NEC_OUTPUT
	MOV	AH,ES:[SI+4]
	CALL	NEC_OUTPUT
	MOV	AH,ES:[SI+5]
	CALL	NEC_OUTPUT
	MOV	AH,ES:[SI+6]
	CALL	NEC_OUTPUT
        MOV     CX,0F10H
J311:   CALL    WAIT_INT
        JNC	J32
        LOOP    J311        
        CALL    RESULTS
        MOV	AX,07H
	CALL	SHWORD
        JMP	ENDR
J32:	CALL	RESULTS
        JNC     S11
        MOV     AX,08H
        CALL    SHWORD
        JMP     ENDR
S11:    call    delay
        mov     ax,ddata
        mov     es,ax
        mov     di,offset buf
        mov     cx,20h
s111:   mov     ax,es:[di]
        call    shword
        loop    s111
        JMP     REND

ENDR:	MOV	AH,ES:[SI+2]
	MOV	MC,AH
	MOV	DX,OFFSET EMES
	MOV	AH,09H
	INT	21H	
REND:   CLI                             ;关中断 
        MOV     AX,DDATA
        MOV     DS,AX
        XOR     AX,AX                   ;设置中断向量
        MOV     ES,AX
        MOV     DI,38H                  ;4*0EH,0EH号中断为软盘中断
        MOV     AX,ES:[DI]
        MOV     AX,OLDINTO
        CLD 
        STOSW
        MOV     AX,ES:[DI]
        MOV     AX,OLDINTS
        STOSW
        MOV     DI,78H                  ;4*1EH,1EH为软盘参数块
        MOV     AX,ES:[DI]
        MOV     AX,OLDPARAO
        STOSW
        MOV     AX,ES:[DI]
        MOV     AX,OLDPARAS
        STOSW
        STI 
wait_press_key:
		mov	ah, 0bh	;检测是否有键按下?检查键盘状态,al=00则无输入
		int	21h
		cmp	al, 0h
		je		wait_press_key	;若无键按下,则程序往下执行

        MOV     AX,4C00H
        INT     21H
START	ENDP

NEC_OUTPUT	PROC	NEAR	;AH为参数
	PUSH	DS
        PUSH    DX
        PUSH    CX
        MOV	DX,S0040
        MOV	DS,DX
        MOV	DX,3F4H		;将软盘FDC的主状态寄存器地址送DX
	XOR	CX,CX		;置循环等待时间,清标志
N1:	IN	AL,DX		;读主状态寄存器,判是否可以写数据寄存器
        MOV	BL,AL
        AND	AL,0C0H
        CMP     AL,80H
        JZ      N3
        LOOP    N1
N2:     OR      DSS,80H		;置超时错误码
        POP     CX
        POP     DX
        POP	DS
        STC
        RET
N3:     MOV     AL,AH		;输出命令
        MOV     DX,3F5H
	OUT	DX,AL
        POP     CX
        POP     DX
        POP	DS
	RET
NEC_OUTPUT	ENDP

DISKINT	PROC FAR
	STI
	PUSH	DS
	PUSH	AX
	MOV	AX,S0040
	MOV	DS,AX
	OR	SSS,80H
	MOV	AL,20H
	OUT	20H,AL
	POP	AX
	POP	DS
	IRET
DISKINT	ENDP

WAIT_INT	PROC	NEAR
	STI
        PUSH	DS
        PUSH    BX
        PUSH    CX
        MOV	BX,S0040
        MOV	DS,BX
 	XOR	CX,CX
        MOV     CX,0FFFFH
W1:     TEST    SSS,80H
        JNZ     W2
        LOOP    W1
	OR	DSS,80H
        STC
W2:     PUSHF
        AND     SSS,07FH
        POPF
        POP     CX
        POP     BX
        POP	DS
	RET	
	ENDP
	
DMA_SETUP PROC NEAR
        PUSH    CX
	CLI
        OUT     0CH,AL
        OUT     0BH,AL
	MOV	AX,ES		;缓冲区段地址
	MOV	CL,4
	ROL	AX,CL
	MOV	CH,AL
	AND	AL,0F0H
	ADD	AX,BX
        JNC     D1
	INC	CH
D1:     PUSH    AX
        OUT     04H,AL
	MOV	AL,AH
        OUT     04H,AL
	MOV	AL,CH
	AND	AL,0FH
	OUT	81H,AL
	MOV	AH,DH
	SUB	AL,AL
	SHR	AX,1
	PUSH	AX
        PUSH    DS
        MOV     AX,DDATA
        MOV     DS,AX
        MOV     AX,OFFSET DPARA
        MOV     SI,AX
        MOV     BX,3
        MOV     AH,[BX+SI]
        POP     DS
        JNC     D2
        CALL    NEC_OUTPUT
D2:     MOV     CL,AH
        POP     AX
	SHL	AX,CL
	DEC	AX
	PUSH	AX
        OUT     05,AL
        MOV     AL,AH
        OUT     05,AL
        STI
        POP     CX
        POP     AX
	ADD	AX,CX
        MOV     AL,2
        OUT     0AH,AL
        POP     CX
	RET
DMA_SETUP	ENDP

RESULTS	PROC	NEAR
        CLD     
	PUSH	DS
        PUSH    CX
        PUSH    DX
        PUSH    BX
        MOV	BX,S0040
        MOV	DS,BX
        MOV     DI,OFFSET NS
        MOV	BL,7
R1:     XOR     CX,CX
	MOV	DX,3F4H
R2:     IN      AL,DX
	TEST	AL,80H
        JNZ     R4
        LOOP    R2
	OR	DSS,80H
R3:     STC
        POP     BX
        POP     DX
        POP     CX
	POP	DS
	RET
R4:     IN      AL,DX
	TEST	AL,40H
        JNZ     R6
R5:     OR      DSS,20H
        JMP     R3
R6:     MOV     DX,3F5H
	IN	AL,DX
	MOV	[DI],AL
	INC	DI
        XOR	CX,CX
R7:     LOOP    R7
	MOV	DX,3F4H
	IN	AL,DX
	TEST	AL,10H
        JZ      R8
	DEC	BL
        JNZ     R1
        JMP     R5
R8:     POP     BX
        POP     DX
        POP     CX
	POP	DS
        RET
RESULTS	ENDP

CHK_STAT	PROC	NEAR
        PUSH    CX
	CALL	WAIT_INT
	mov	bx,55H
        JC      C1
        MOV     AH,08H
	CALL	NEC_OUTPUT
	CALL	RESULTS
	mov 	bx,66H
        JC      C1
	MOV	AL,NS
	AND	AL,60H
	CMP	AL,60H
        mov	bx,77H
        JZ      C2
	CLC	
	mov 	bx,88H
C1:     POP     CX
        RET
C2:     OR      DSS,40H
	STC
        POP     CX
	RET
CHK_STAT	ENDP

SHWORD	PROC	NEAR
	PUSH	BX
	MOV	BL,AH
	CALL	SHOW
	MOV	BL,AL
	CALL	SHOW
	POP	BX
	RET	
SHWORD	ENDP
		
SHOW	PROC	NEAR
	PUSH	AX
	PUSH	DX
	MOV	AL,BL
	AND	AL,0F0H			;取高4位
	SHR	AL,4
	CMP	AL,0AH			;是否是A以上的数
        JB      SC2       
	ADD	AL,07H		
SC2:    ADD     AL,30H   
	MOV	DL,AL			;显示字符
	MOV	AH,02H
	INT	21H
	MOV	AL,BL
	AND	AL,0FH			;取低4位
	CMP	AL,0AH
        JB      SC3
	ADD 	AL,07H
SC3:    ADD     AL,30H
	MOV	DL,AL			;显示字符
	MOV	AH,02H
	INT	21H
	POP	DX
	POP	AX
	RET
SHOW	ENDP	

DELAY	PROC	NEAR
	PUSH	BX
	PUSH	CX
	MOV	CX,0FFFFH
DD2:	PUSH	CX
	MOV	CX,0FFFH
DD1:	LOOP	DD1
	POP	CX
	LOOP	DD2
	POP	CX
	POP	BX
	RET
DELAY	ENDP
CODE	ENDS
        END START

⌨️ 快捷键说明

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