读书人

8259A设置有关问题

发布时间: 2012-12-15 15:16:03 作者: rapoo

8259A设置问题
本帖最后由 pang68599 于 2012-11-08 14:34:39 编辑



ORG 7c00h
START:


;把我自己的键盘处理程序写入中断向量表
mov AX , KEYBOARD
MOV [ES:0024H], AX
MOV AX , CS
MOV [ES:0026H] , AX


;master

MOV AL , 0x11;ICW1 必须设置成0x11 ,设置成0x13不级联会报错
OUT 0x20 , AL

MOV AL , 0x08;ICW2
OUT 0x21 , AL

MOV AL , 0x04;ICW3
OUT 0x21 , AL

MOV AL , 0x01;ICW4
OUT 0x21 , AL

MOV AL , 0xFD;OCW1 打开键盘中断IMR
OUT 0x21 , AL


JMP $
;设置的中断
KEYBOARD:
sti
MOV AX , 0B800H
MOV DS , AX
MOV DI , 2
MOV AX , 97
MOV [DS:DI] , AX
MOV AX , 34H
INC DI
MOV [DS:DI] , AX

MOV AL , 20H
OUT 20H , AL
iret
times 510 - ($ - START) DB 0
DW 0AA55H



在实模式下面,修改8259A为什么不能响应中断,ICW1 必须设置成0x11 ,设置成0x13不级联会报错,不会响应中断。
[解决办法]

ORG 7c00h
START:
mov ax , 0000h
mov ss , ax
mov sp , 0400h
MOV AX , 0B800H
MOV GS , AX
MOV DI , 0
MOV AX , 97
MOV [GS:DI] , AX
MOV AX , 34H
INC DI
MOV [GS:DI] , AX
mov ax , 0000h
mov es , ax
mov AX , CLOCK
MOV [ES:0080H], AX
MOV AX , CS
MOV [ES:0082H] , AX
mov AX , KEYBOARD
MOV [ES:0084H], AX
MOV AX , CS
MOV [ES:0086H] , AX
MOV AL , 0x15;ICW1 , master
OUT 0x20 , AL
CALL DELAY
OUT 0xA0 , AL;ICW1 , slave
CALL DELAY
MOV AL , 0x20;ICW2 , master
OUT 0x21 , AL
CALL DELAY
MOV AL , 0x28;ICW2 , slave
OUT 0xA1 , AL
CALL DELAY
MOV AL , 0x04;ICW3 , master
OUT 0x21 , AL
CALL DELAY
MOV AL , 0x03;ICW3 , slave
OUT 0xA1 , AL
CALL DELAY
MOV AL , 0x01;ICW4 MASTER
OUT 0x21 , AL
CALL DELAY
OUT 0xA1 , AL;ICW4 SLAVE
CALL DELAY
MOV AL , 0xFD;OCW1
OUT 0x21 , AL
CALL DELAY
MOV AL , 0xFF
OUT 0xA1 , AL
CALL DELAY
MOV AL , 20h;OCW2
OUT 0x20 , AL
CALL DELAY
OUT 0xA0 , AL
CALL DELAY
MOV DI , 4
MOV AX , 98
MOV [GS:DI] , AX
MOV AX , 35H
INC DI
MOV [GS:DI] , AX
int 0x20
int 0x21
JMP $
DELAY:
nop
nop
nop
nop
ret
CLOCK:
push ax
inc byte [gs:0006h]
mov al , 20h
out 20h , al
pop ax
iret
KEYBOARD:


;STI
MOV DI , 2
MOV AL , 98
MOV [GS:DI] , AL
MOV AX , 34H
INC DI
MOV [GS:DI] , AL
mov ax , 0FFFFH
.s1:mov cx , 4000H
.s2:dec cx
jnz .s2
dec ax
jnz .s1
MOV DI , 2
MOV AX , 0
MOV [GS:DI] , AL
INC DI
MOV [GS:DI] , AL
;CLI
MOV AL , 20H
OUT 20H , AL
IRET
times 510 - ($ - START) DB 0
DW 0AA55H


我这个是在bochs中运行的,但是为什么8259A不能调用这个两个子函数呢?8259A不能响应时钟中断和键盘中断呢?
[解决办法]
引用一个操作系统的实现--于渊

8259A ---- 8042 ---- 8048 ,当8048监测到一个键盘动作之后会吧响应的扫瞄码发送给8042,会把它转换成响应的Scan code set 1码,并将其放入输入缓冲区中,然后8042告诉8259A产生中断(IRQ1),如果此时键盘又有新的键被按下,8042将不再接收,一直到缓冲区被清空,8042才会收到更多的扫瞄码。
8042 寄存器表

寄存器名称 寄存器大小 端口 用法 R/W
输出缓冲区 1 byte 0x60 读输入缓冲区 read
输入缓冲区 1 byte 0x60 写输入缓冲区 write
状态寄存器 1 byte 0x64 读状态寄存器 read
控制寄存器 1 byte 0x64 发送命令 write


例子
KEYBOARD:
....
in al , 0x60 ;不读取键盘中断无法再次响应
....
iret


我发现国内的好多微机原理书中,只告诉你的读键盘,但是并没有告诉你,键盘如何连续的读,并且没有告诉,8259A键盘中断后连接的其他芯片,找了好久才让我找到。


读书人网 >汇编语言

热点推荐