la t0,handler csrw mtvec,t0 # Set trap handler address and mode (0/direct) li t0,0x400 csrc mstatush,t0 # Enable trap handler li t0,0x80 csrw mie,t0 # Enable machine timer interrupt and disable others la t1,mmio csrw 0x801,t1 # Set MMIO base address lw t0,2(t1) # Load current mtime addi t0,t0,1 sw t0,10(t1) # Set mtimecmp for 1 second in the future csrsi mstatus,8 # Enable interrupts globally task1: li a0,1 li a7,1 ecall j task1 task2: li a0,2 li a7,1 ecall j task2 .balign 4 handler: lw t0,2(t1) # Load current mtime addi t0,t0,1 sw t0,10(t1) # Set mtimecmp for 1 second in the future la t0,currenttask lw t2,0(t0) # Get current task number addi t2,t2,1 # Flip to the other task andi t2,t2,1 sw t2,0(t0) # Write the number back beqz t2,handler_return1 j handler_return2 handler_return1: la a0,task1 csrw mepc,a0 # Set return address to start of task 1 mret handler_return2: la a0,task2 csrw mepc,a0 # Set return address to start of task 2 mret currenttask: .word 1 mmio: