首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 汇编语言 >

8259A设置有关问题

2012-12-15 
8259A设置问题本帖最后由 pang68599 于 2012-11-08 14:34:39 编辑ORG 7c00hSTART:把我自己的键盘处理程序

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键盘中断后连接的其他芯片,找了好久才让我找到。


热点排行