实验描述:
表明中断驱动的输入、输出可以中断一个正在运行的程序,执行中断服务程序,返回被中断的程序,从被中断位置下一个地址继续执行(好像什么也没发生似的)。实验中我使用键盘作为输入设备,中断正在运行的程序。
A.用户程序
1.你的用户程序将会包含连续地输出纵横交替的ICS,通过交替输出两个不同行,如下:
ICS ICS ICS ICS ICS ICS
ICS ICS ICS ICS ICS
ICS ICS ICS ICS ICS ICS
ICS ICS ICS ICS ICS
ICS ICS ICS ICS ICS ICS
ICS ICS ICS ICS ICS
ICS ICS ICS ICS ICS ICS
ICS ICS ICS ICS ICS
2.确保你的输出不至于太快,以至于肉眼不能察觉。用户程序应该包含以小段代码用于每行间的计数,间隔为从2500开始倒计时输出在屏幕上。
B.键盘中断服务程序
1.键盘中断服务程序将会简单地在屏幕上写上十次,用户随机输入的字符并以Enter(x0A)结束。
2.或许你在你的中断服务程序中并不使用TRAP指令。如在屏幕上显示一个字符,你必须检测DSR寄存器,然后写进DDR寄存器,或许你也不可以调用 TRAP x21(OUT),或者其它TRAP程序。
C.操作系统支持的代码
1.正常情况下,操作系统将会先安装一些栈空间,所以当中断发生的时候 PC和PSR可以被放进栈中(正如你知道的,当程序执行RTI,PC和PSR都会被弹出栈,处理器返回到执行被中断的程序)由于没有操作系统,请先把R6初始化为x3000,表示一个空的栈。
2.正常情况下,操作系统会建立中断向量表,它包含对应中断服务程序的起始地址,你必须为键盘中断先建立一个中断向量表。中断向量表的开始地址是x0100,键盘中断的中断向量是x80。你必须在中断向量表提供一个入口供本实验使用。
中断驱动I/O示意图:
中断驱动I/O执行流程如下。本实验中,我们在键盘输入一个字符,则I/O设备请求服务,且优先级高于用户程序,则中断开始服务,直到输入回车(x000A)结束。
用户程序流程图:
中断服务流程图:
实验结果:
随机输入一个字符时,中断发生,不再循环输出ICS,直到按回车键结束。可以看到被输入的字符输出10次(画红线部分),然后死循环继续。
具体代码实现:
用户程序lab4_ID_user_program
; The code is designed by Li Mingzhao.
; User program to print ICS checkerboard in an infinite loop.
;
.ORIG x3000
;initialize the stack pointer
LD R6,STACK
;set up the keyboard interrupt vector table entry
LD R1,INKB ; x0180
LD R2,ADDER ; x2000
STR R2,R1,#0
;enable keyboard interrupts
LD R3,IEE ; x4000. set 1 to the Interrupt Enable(14th bit)
STI R3,KBSR
;start of actual user program to print ICS checkerboard
REPUT LEA R0,ICS1
TRAP x22 ; output the string
JSR DELAY
LEA R0,ICS2
TRAP x22 ; output the string
JSR DELAY
BRnzp REPUT
TRAP x25
; delay output.
DELAY ST R1,SaveR1
LD R1,COUNT ; #2500
REP ADD R1,R1,#-1
BRp REP
LD R1,SaveR1
RET
COUNT .FILL #25000
SaveR1 .BLKW 1
IEE .FILL x4000
STACK .FILL x3000
ADDER .FILL x2000
INKB .FILL x0180 ;INTV
KBSR .FILL xFE00
ICS1 .STRINGZ "ICS ICS ICS ICS ICS ICS \n"
ICS2 .STRINGZ " ICS ICS ICS ICS ICS ICS\n"
.END
中断服务程序lab4_interrupt_service_routine
; The code is desgined by Li Mingzhao.
; The interrupt service routine to output character you input 10 times.
; The interrupt service End with Enter(x000A).
;
.ORIG x2000 ; Start at x2000
ADD R6,R6,#-1 ; Store the data at a stack.
STR R0,R6,#0
ADD R6,R6,#-1
STR R1,R6,#0
ADD R6,R6,#-1
STR R2,R6,#0
ADD R6,R6,#-1
STR R3,R6,#0
LOOP ST R0,SaveR0
STAR LDI R1,KBSR ; Check the keyboard state.
BRzp STAR
LDI R0,KBDR
LD R2,NEWLINE ; -x000A
ADD R2,R2,R0
BRnp LOOP
AND R3,R3,#0
ADD R3,R3,#10
AGAIN LD R0,SaveR0
START LDI R1,DSR ; Check the display state.
BRzp START
STI R0,DDR
ADD R3,R3,#-1
BRp AGAIN
LDR R3,R6,#0 ; Restore register.
ADD R6,R6,#1
LDR R2,R6,#0
ADD R6,R6,#1
LDR R1,R6,#0
ADD R6,R6,#1
LDR R0,R6,#0
ADD R6,R6,#1
RTI ; Return to the user program.
KBSR .FILL xFE00
KBDR .FILL xFE02
DSR .FILL xFE04
DDR .FILL xFE06
FIRST .FILL x4000
NEWLINE .FILL xFFF6
SaveR0 .FILL 0
.END