Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # First section: user data,
- # each process has its own "private" area.
- .data
- glob1: .byte 'A'
- .space 999
- glob2: .byte '0'
- .space 999
- glob3: .byte 'a'
- .space 999
- # Second section: user code.
- #
- # The first instructions initializes IO and Timer.
- # The last instruction in main are only used for start
- # up, they initialize the first process.
- .text
- .set noreorder
- main:
- li $t0, 0xFFFF0010 # address to Timer registers:
- # +0: Timer control register
- # +4: Timer count register
- # +8: Timer compare register
- li $t1, 0
- sw $t1, 4($t0) # reset counter register
- li $t1, 63 # count from 0 to 63
- sw $t1, 8($t0) # compare register := 63
- li $t1, 0b101001 # "101001": compare interrupt enable,
- # compare reset enable,
- # timer start
- sw $t1, 0($t0) # control register := "101001"
- li $t0, 0xFFFF0000 # address to I/O registers:
- # +0: Input control register
- li $t1, 0b10 # "10": interrupt enable
- sw $t1, 0($t0) # control register := "10"
- li $t0, 0x0C03 # enable HW Interrupt 1 (input): bit 11
- # enable HW Interrupt 0 (timer): bit 10
- # set user mode: bit 1
- # enable interrupts: bit 0
- mtc0 $t0, $12 # CP0 status := 0x0Cma03
- la $gp, glob1 # dirty setup for process 1
- proc1: # ++++++++++ first process +++++++++
- # Description: proc1 reads the byte stored at 0($gp),
- # prints it, increments to the next character,
- # saving that back into 0($gp). After printing 'Z',
- # this process should then start over again with 'A', in
- # an endless loop. The symbol "glob1" may not be used.
- lb $t0, 0($gp) #Loads a byte
- nop
- ori $t1, $zero, 90 #Loads 90 into t0
- move $a0, $t0 #
- lui $v0, 0x102
- nop
- syscall
- nop
- beq $t0, $t1, reset
- nop
- add:
- addiu $t0, $t0, 1
- sb $t0, 0($gp)
- j proc1
- nop
- reset:
- addiu $t0, $t0, -25
- sb $t0, 0($gp)
- j proc1
- nop
- proc2: # ++++++++++ second process +++++++++
- # Description: almost identical to the code of proc1 above,
- # only 2-3 lines should differ. Prints '0' through '9' in
- # an endless loop. The symbol "glob2" may not be used.
- lb $t0, 0($gp) #Loads a byte
- nop
- ori $t1, $zero, 57 #Loads 90 into t0
- move $a0, $t0 #
- lui $v0, 0x102
- nop
- syscall
- nop
- beq $t0, $t1, reset2
- nop
- add2:
- addiu $t0, $t0, 1
- sb $t0, 0($gp)
- j proc2
- nop
- reset2:
- addiu $t0, $t0, -9
- sb $t0, 0($gp)
- j proc2
- nop
- proc3: # +++++++++ third process ++++++++++
- # Description: almost identical to the code of proc1 above,
- # only 2-3 lines should differ. Prints 'a' through 'z' in
- # an endless loop. The symbol "glob3" may not be used.
- lb $t0, 0($gp) #Loads a byte
- nop
- ori $t1, $zero, 122 #Loads 90 into t0
- move $a0, $t0 #
- lui $v0, 0x102
- nop
- syscall
- nop
- beq $t0, $t1, reset3
- nop
- add3:
- addiu $t0, $t0, 1
- sb $t0, 0($gp)
- j proc3
- nop
- reset3:
- addiu $t0, $t0, -25
- sb $t0, 0($gp)
- j proc3
- nop
- # Third section: data structures for the kernel:
- # Process Control Block (PCB) consists of three words:
- # pcb: .word (next Program Counter for this process)
- # .word (contents of $gp for this process)
- # .word (contents of $sp for this process)
- # All other context is saved on the process' own stack
- # during exception handling and SYSCALL.
- .section .kdata
- curpcb: .word pcb1
- pcb1: .word 0, 0, 0
- pcb2: .word proc2, glob2, 0x7fffbf94
- pcb3: .word proc3, glob3, 0x7fff7f94
- # Fourth section: kernel code.
- .section .ktext , "xa"
- .set noreorder
- kernel_loop:
- mfc0 $t2, $13
- nop
- ori $t5, $zero, 8
- sll $t2, $t2, 26
- srl $t2, $t2, 28
- beq $t2, $t5, check
- nop
- beq $zero, $t2, exc
- nop
- b kernel_loop
- nop
- check:
- lui $t3, 0x102
- nop
- beq $v0, $t3, back
- nop
- rfe
- nop
- back:
- lui $t4, 0xFFFF
- sb $a0, 8($t4)
- nop
- nop
- mfc0 $k0, $14
- nop
- addiu $k0, $k0, 4
- jr $k0
- rfe
- exc:
- ori $t3, $zero, 1
- mfc0 $t2, $13
- sll $t2, $t2, 20
- srl $t2, $t2, 31
- beq $t2, $t3, timerint
- nop
- b kernel_loop
- nop
- timerint:
- #loads in the current stack pointer
- la $s0, curpcb
- nop
- #lw $s0, ($s0)
- nop
- ignore:
- mfc0 $k1, $14
- nop
- move $ra, $k1
- sw $k1, 0($s0)
- sw $gp, 4($s0)
- addiu $sp, $sp, -4
- sw $ra, 0($sp)
- addiu $sp, $sp, -4
- sw $fp, 0($sp)
- move $fp, $sp
- addiu $sp, $sp, -104
- sw $gp, -4($fp)
- sw $s0, -8($fp)
- sw $s1, -12($fp)
- sw $s2, -16($fp)
- sw $s3, -20($fp)
- sw $s4, -24($fp)
- sw $s5, -28($fp)
- sw $s6, -32($fp)
- sw $s7, -36($fp)
- sw $t0, -40($fp)
- sw $t1, -44($fp)
- sw $t2, -48($fp)
- sw $t3, -52($fp)
- sw $t4, -56($fp)
- sw $t5, -60($fp)
- sw $t6, -64($fp)
- sw $t7, -68($fp)
- sw $t8, -72($fp)
- sw $t9, -76($fp)
- sw $a0, -80($fp)
- sw $a1, -84($fp)
- sw $a2, -88($fp)
- sw $a3, -92($fp)
- sw $v0, -96($fp)
- sw $v1, -100($fp)
- .set noat
- sw $at, -104($fp) # FIX
- .set at
- la $s2, pcb2
- la $s4, pcb3
- lw $s5, ($s0)
- nop
- beq $s5, $s2, pcb2_3
- nop
- beq $s5, $s4, pcb3_1
- nop
- b pcb1_2
- nop
- pcb3_1:
- la $s3, pcb1
- #move $s0, $s3
- sw $s3, ($s0)
- lw $gp, 4($s3)
- nop
- b load
- nop
- pcb1_2:
- la $s3, pcb2
- #move $s0, $s3
- sw $s3, ($s0)
- lw $gp, 4($s3)
- nop
- b load
- nop
- pcb2_3:
- la $s3, pcb3
- #move $s0, $s3
- sw $s3, ($s0)
- lw $gp, 4($s3)
- nop
- load:
- #Clear Timer Interrupt
- li $k0, 0xFFFF0010
- li $k1, 0b101001
- sw $k1, 0($k0)
- #---------------------
- lw $sp, 8($s3)
- lw $ra, 0($s3)
- move $fp, $sp
- addiu $fp, $fp, -8
- sw $gp, 4($fp)
- sw $s0, -4($fp)
- lw $gp, 4($fp)
- lw $s0, -4($fp)
- lw $s1, -8($fp)
- lw $s2, -12($fp)
- lw $s3, -16($fp)
- lw $s4, -20($fp)
- lw $s5, -24($fp)
- lw $s6, -28($fp)
- lw $s7, -32($fp)
- lw $t0, -36($fp)
- lw $t1, -40($fp)
- lw $t2, -44($fp)
- lw $t3, -48($fp)
- lw $t4, -52($fp)
- lw $t5, -56($fp)
- lw $t6, -60($fp)
- lw $t7, -64($fp)
- lw $t8, -68($fp)
- lw $t9, -72($fp)
- lw $a0, -76($fp)
- lw $a1, -80($fp)
- lw $a2, -84($fp)
- lw $a3, -88($fp)
- lw $v0, -92($fp)
- lw $v1, -96($fp)
- .set noat
- lw $at, -104($fp) # FIX
- nop
- .set at
- jr $ra
- rfe
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement