#include #include .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