#include <iregdef.h>
#include <idtcpu.h>
.text
.globl main
/* *************************************************************************
Main program
The system is first initiated, the interrupt routine has to start at address
0x80000080, and the status register has to be set to enable external
interrupts from puls generator. and the "user" interrupthandler has to be
enabled by clearing BEV, bit 22 in SR.
After initialization of the "OS" a special test program is entered.
************************************************************************* */
main:
la t0,L1 // copy int handler
la t1,0x80000080 // to physical interrupt
lw t2,0(t0) // handler address
sw t2,0(t1)
lw t2,4(t0)
sw t2,4(t1)
la t1,0xbfa00000
L0: mfc0 t0,C0_CAUSE // Clear spurious interrupts
sw zero,(t1)
andi t0,t0,0x00002000
bnez t0,L0
nop
mfc0 t0,C0_SR // get SR
nop
ori t0,t0,0x0000a005 // set bit 13 and 0
// interrupt from puls generator bit 13
// enable interrupts bit 0,
and t0,t0,0xffbfffff // clear bit 22
// to select user interrupt handler
mtc0 t0,C0_SR // switch on interrupts and
j program // start the "program"
.set noreorder
L1: j inth // these two instructions are
nop // copied into physical
// interrupt handler
.set reorder
/* **************************************************************************
The test program may be written here. The test program should be a separate
process handled by a scheduler, but we do not implement a scheduler in this
small "mini-system". Thus we include the code directly here.
The silly nop loop may be used for simple interrupt testing (first interrupt
lab), but for the next lab handling syscall we need a bit more complicated
program loop.
************************************************************************** */
.data
format: .asciz "Klockan är %d \n"
form1: .asciz "125=%d\n"
.text
program:
j prog1 // choose one of prog1/prog2/prog3
/* Simple program to be used as a first test */
prog1:
loop: nop
nop
nop
j loop
/* this is a program to be used as the
"real" test of interrupt handling */
prog2: li s0,125
upp: move a1,s0
la a0,form1
jal printf
nop
li a0,5000000
jal delay
b upp
/* this is to be used as the program testing syscall */
prog3:
li v0,2
li v1,5
syscall
move s0,zero
li a0,100000
jal delay
up0: li v0,1
syscall
la a0,format
move a1,v0
jal printf
li a0,5000000
jal delay
add s0,s0,1
beq s0,10,dd1
b up0
dd1: li v0,2
move v1,s0
syscall
move s0,zero
b up0
/* a subroutine to be used to delay the execution */
delay:
move t0,zero
dy1: add t0,t0,1
blt t0,a0,dy1
jr ra
.data
klocka: .word 0
stk: .space 4*5
.text
inth: la k1,stk
sw t0,0(k1)
sw t1,4(k1)
sw t2,8(k1)
sw t3,12(k1)
mfc0 k0,C0_CAUSE
and k0,k0,0x7c
beqz k0,extint
b dismiss
beq v0,1,av1
jr k0
dismiss:la k1,stk
lw t0,0(k1) //vänster
lw t1,4(k1) //höger
lw t2,8(k1) //frekvens
lw t3,12(k1)
mfc0 k0,C0_EPC
.set noreorder
jr k0
rfe
.set reorder
extint: mfc0 k0,C0_CAUSE
and k0,k0,0x2000
bnez k0,puls
j dismiss
nop
v: la t0,0xbf900000 //lysdiodernas add.
lb t1,0(t0)
sb t1,0(t0) // osäkert!!
j dismiss
nop
h: la t1,klocka
la t0,0xbf900000
lw t2,0(t1)
sb t2,0(t0)
j dismiss
nop
f: la t0,klocka
lw t3,0(t0)
add t3,t3,1
sw t3,0(t0)
j dismiss
nop
puls: la t0,0xbfa00000
sb zero,0(t0)
lb t1,0(t0)
beq t1,1,h
beq t1,2,v
beq t1,4,f
j dismiss
nop
av1: la t1,klocka // sätter adressen till t1
lw v0,0(t1) // värdet i t1 itill v0
j dismiss
av2: la t1,klocka
sw v1,0(t1)
j dismiss