#include <iregdef.h>
#include <idtcpu.h>
	.text
	.globl	start
/* *************************************************************************
	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.
************************************************************************* */

start:	
	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,0x00002005	// 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	prog3		// 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
	
	



