1.Purpose——To showhow interrupt-driven Input/Output can interrupt a program that is running,execute the interrupt service routine, and return to the interrupted program,picking up exactly where it left off (just as if nothing had happened).
The assignment consists of three parts:
1)The user program
2)The keyboard interrupt service routine
3)The operating system enabling code
2.Principle: (1)本实验中对键盘输入采用interrupt I/O方式,对显示屏幕输出则采用polling的方式
(2)在user program 中,讲“cs@ustc”与“ ”作为两个字符串,控制二者轮流输出和换行时机,以达到实验要求输出方式
(3)为了至于显示频刷新过快,采用了延时的方法,即每一行输出后,count2500方进行下一行的输出
(4)在interrupt routine中不能采用trap指令,则逐一将需要输出的字符存储到DDR中以达到输出目的
3. procedure
代码注释:
.ORIG x3000
LDR6,STACK ; initialize the stack pointer
LD R2,ADDR ; set up the keyboard interrupt vector tableentry LD R3,VECTOR
STRR2,R3,#0
LD R2,ENABLE ;enable keyboard interrupts
LDR3,KBSR
STRR2,R3,#0
LDR1,FEEDNUM1 ; start of actual user programto print checkerboard
OUTPUT1 LEAR0,OUT1 ;输出第一行,从字符串OUT1开始轮流输出OUT1和
TRAPx22 ;OUT2两个字符串,共输出9个则换行
ADDR1,R1,#-1
LEAR0,OUT2
TRAPx22
ADDR1,R1,#-1
BRzOUTFED1 ;输出换行
BRpOUTPUT1
OUTFED1 JSRDELAY
LDR0,FEED
TRAPx21
LDR1,FEEDNUM2
BRnzpOUTPUT2 ;转至输出第二行部分
OUTPUT2 LEAR0,OUT2 ;输出第一行,从字符串OUT2开始轮流输出OUT2和
TRAPx22 ;OUT1两个字符串,共输出8个则换行
ADDR1,R1,#-1
LEAR0,OUT1
TRAPx22
ADDR1,R1,#-1
BRzOUTFED2
BRpOUTPUT2
OUTFED2 JSRDELAY ;换行并且转至输出line1的部分
LDR0,FEED
TRAPx21
LDR1,FEEDNUM1
BRnzpOUTPUT1
DELAY STR1, SaveR1 ;延时
LD R1, COUNT
REP ADDR1,R1,#-1
BRp REP
LD R1, SaveR1
RET
ENABLE .FILLx4000
KBSR .FILLxFE00
VECTOR .FILLx180
ADDR .FILLx1500
STACK .FILLx3000
COUNT .FILL#2500
SaveR1 .BLKW#1
FEED .FILL#13
FEEDNUM1 .FILL#9
FEEDNUM2 .FILL#8
OUT1 .STRINGZ"CS@USTC"
OUT2 .STRINGZ" "
.END
----------------------------------------------------------------------------
.ORIGx1500
STR0,SAVER0 ;store the registers
STR2,SAVER2
STR3,SAVER3
STR4,SAVER4
STR5,SAVER5
STR7,SAVER7
LDI R1,KBDR ;初始化值
LDR2,NUM0
LDR3,NUM9
NOTR2,R2 ;讲kbdr中只与0,9比较以判断是否是数字
ADDR2,R2,#1
ADDR2,R2,R1
BRnNOTNUM
NOTR3,R3
ADDR3,R3,#1
ADDR3,R3,R1
BRpNOTNUM
BRnzpISNUM
ISNUM LEAR2,OUT1 ;是数字输出相应的字符串
ISNUM2 LDRR0,R2,#0
JSROUTPUT
ADDR2,R2,#1
LEAR3,OUT2
NOTR3,R3
ADDR3,R3,#1
ADDR3,R3,R2
BRzDONE
BRnpISNUM2
NOTNUM LEAR3,OUT2 ;不是数字,输出相应的字符串
NOTNUM2 LDRR0,R3,#0
JSROUTPUT
ADDR3,R3,#1
LEAR2,KBDR
NOTR2,R2
ADDR2,R2,#1
ADDR2,R2,R3
BRzDONE
BRnpNOTNUM2
OUTPUT STR1,SAVER1 ;因为不能使用trap,采用的输出方法
LOOP LDIR1,DSR
BRzpLOOP
STIR0,DDR
LDR1,SAVER1
RET
DONE LDR1,ENABLE ;结束
LDR2,KBSR
STRR1,R2,#0
LDR0,SAVER0
LDR2,SAVER2
LDR3,SAVER3
LDR4,SAVER4
LDR5,SAVER5
LDR7,SAVER7
RTI
OUT1 .STRINGZ"\nICS2017:It is a number.\n"
OUT2 .STRINGZ"\nICS2017: ?????? What is this ??????\n"
KBDR .FILLxFE02
KBSR .FILLxFE02
ENABLE .FILLx4000
DSR .FILLxFE04
DDR .FILLxFE06
NUM0 .FILL#48
NUM9 .FILL#57
SAVER0 .BLKW#1
SAVER1 .BLKW#1
SAVER2 .BLKW#1
SAVER3 .BLKW#1
SAVER4 .BLKW#1
SAVER5 .BLKW#1
SAVER7 .BLKW#1
.END
4.results
(1)测试
输入1,结果如下
输入k,结果如下
*以其他字符进行测试,输出均与要求一致
(2)反思
1.每行延迟为计数2500,在实际操作中仍然过快,在本人实验中,每输出一个7个字符的字符串delay等同时间,显示效果较佳
2.上述轮流输出的方式较为繁琐,把每行设置成一个字符串能使代码简化
3.在实验中PC,PSR的栈的入栈操作由模拟器本身进行,出栈由RTI执行,未能清楚得到乃至修改PSR的值的方法