Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .globl mecall
- .globl handler
- handler:
- addi sp sp, -16 #Create stack space #@ NEW, MIGHT NEED POP STACK CAUSE MECALL WILL RUN AFTER HANDLER,
- #@ and i think this ceate stack space twice
- #and we need to pop stack before creating space again
- sw ra, 12(sp) #Preserve caller's return address
- sw t0, 8(sp)
- csrrw s1, 66, zero #Load ucause into s1
- la s10, ExceptionTbl #Load address exceptions
- addi s9, zero, 4
- mul s1, s1, s9 #Mult ucause # by by 4 to get offset
- add s10, s10, s1 #Increment subroutine by offset
- lw, s8, (s10) #Load word at address s10 (exceptiontbl + offset)
- jalr s8
- mecall: #a7 contains num to indicate which subroutine to use
- mv a7, a6
- #USE CALLSTACK INSTEAD
- addi sp sp, -16 #Create stack space
- sw ra, 12(sp) #Preserve caller's return address
- sw t0, 8(sp) #@ ADDED B/C PLANCK USES T0 IN MAIN
- #sw t1, 52(sp)
- #sw t2, 48(sp)
- #sw t3, 44(sp)
- #sw t4, 40(sp)
- #sw t5, 36(sp)
- #sw t6, 32(sp)
- #sw a0, 28(sp)
- #sw a1, 24(sp)
- #sw a2, 20(sp)
- #sw a3, 16(sp)
- #sw a4, 12(sp)
- #sw a5 8(sp)
- #sw a6, 4(sp)
- #sw a7, (sp)
- #sw s0, 8(sp) #Preserve frame pointer (Dont think i need this
- #sw s1, 36(sp) #Preserve s1, (do i need this?)
- #addi s0, sp, 12 #Set frame pointer (do i need this?)
- #JUMP TO VECTOR TABLE
- #FOR UCAUSE 0 AND 1, DONT NEED TO INCREMENT EPC BY 4 BECAUSE JUMP AUTOMATICALLY DOES THIS?
- ENVCALL:
- #Identify subroutine. RUN THIS IF UCAUSE IS 8
- la s10 Subroutines #Load address of Subroutines into x18
- mv s11, a7 #load a7 into other reg so we don't mess it up
- addi s9, zero, 4
- mul s11, s11, s9 #multiply s11 by 4 to get offset
- add s10, s10, s11 #Increment Subroutine address by offset
- lw s8, (s10) #load word at address s10
- jalr s8
- #@ LOOK AT BIT 31 TO SEE IF CAUSED BY INT OR EXC.
- PrintStringHelper: #Same as PrintChar but returns to PrintString instead of returning to inttest
- li s6, 1 #holds immediate val 1
- lw s2, TCR #load value of word at label TCR (which is actual address of TCR) into s2
- lw s1, (s2) #loads value from TCR into s1
- bne s1, s6, PrintChar #loop if TCR not ready to display
- lw s5, TDR #Load address TDR into t0
- sw a0(s5) #Store a0 to TDR #THIS LINE IS BREAKINNG THINGS. A0
- ret
- PrintChar:
- li s6, 1 #holds immediate val 1
- lw s2, TCR #load value of word at label TCR (which is actual address of TCR) into s2
- lw s1, (s2) #loads value from TCR into s1
- bne s1, s6, PrintChar #loop if TCR not ready to display
- lw s5, TDR #Load address TDR
- sw a0(s5) #Store a0 to TDR
- b teardown #Return to inttest
- ReadInt:
- lw s0, RCR #Load RCR address
- lw s1, (s0) #Load value of RCR
- beqz s1, ReadInt #Branch if keyboard has not entered character
- lw s2, RDR #load address of RDR
- lb a0, (s2) #Load value RDR into a0
- addi a0, a0 -48 #convert to decimal from hex
- ret
- ReadChar:
- lw s0, RCR #Load RCR address
- lw s1, (s0) #Load RCR value
- beqz s1, ReadChar #branch if keyboard has not received char
- lw s2, RDR #load address of RDR
- lb a0, (s2) #Load value of RDR
- b teardown
- #Only s0-s11. These are preserved across calls and (And I don't use them in quiz.asm)
- #If I used registers that aren't preserved (a0-17, t0-t6), store the values of these registers into memory using sw (the values they contain from quiz.asm)
- #Then use them as needed in mecall file
- #Finally load the values back into register before returning to quiz.asm
- ReadString:
- lw s1, enter #load x31 with enter key
- li s8, 1 #Start counter at 1
- li s9, 20
- ReceiverVerify: #x28 holds immediate 1
- #bgt s8, a1, EnterKeyPressed #branch if counter > max # of chars read #WHY??
- #beq s8, a1, NullChar #if max num? #DONT THINK I NEED THIS, JUST BRANCH WHEN ENTER KEY PRESSED
- lw s3, RCR #load address RCR
- lw s4, (s3) #load value RCR into s4 (RCR is 1 when keyboard receives new char)
- bnez s4, CharTyped #b if RCR is 1 (keyboard has received char)
- #@ The Ready bit is automatically reset to 0 when the program reads the Receiver Data using an 'lw' instruction.
- b ReceiverVerify #if keyboard has not received new char, loop
- CharTyped:
- lw s5, RDR #load address RDR
- lw s6, (s5) #load value RDR (last character typed), this resets RCR back o 0
- beq s6, s1, EnterKeyPressed
- sb s6, (a0) #Store letter into space for string #@ PRETTY SURE I SHOULD BE STORING IN A0, SHOULD ONLY STORE WHEN NEW CHAR TYPED
- addi a0, a0, 1 #Increment string space pointer
- addi s8, s8, 1 #Increment total counter
- b ReceiverVerify
- NullChar:
- li s6, 0
- sb s6(s7) #Store NullChar
- EnterKeyPressed: #end str
- b teardown
- Exit:
- la a0, ExitMessage #Use Trap 4 (PrintString) to print Exit Message
- li a6, 4
- jal mecall
- ret
- Undefined:
- la a0, Error #Use Trap 4 (PrintString) to print Error Message
- li a6, 4
- jal mecall
- li a7, 10 #Use exit routin
- ecall
- PrintString:
- #la a0, test_str #This is for testing. For asgn8, a str is already loaded into a0
- li a7, 4
- #jal mecall
- mv t1, a0
- printstrloop:
- lb a0, (t1) #AFTER THIS STEP DO I OUTPUT TO TDR?
- beq zero, a0, teardown #Works successfuly, branches at end of string #@ !!! maybe i need to change this to add new line
- jal PrintStringHelper #previously, this jumped to PrintChar
- addi t1, t1, 1 #Get next char into t1 PROBLEM: After nullchar, execution resumes here
- b printstrloop
- #addnewline:
- #li a0, 0x0A #Putnewchar in a0
- #lw s5, TDR #Load address TDR
- #sw a0(s5) #Store a0
- #UCAUSE 0
- IAM:
- la a0, IAM_MSG
- li a6, 4 #PrintString
- #COPY RA INTO EPC
- lw ra, 12(sp)
- addi ra, ra, -4 #Decrement RA because teardown increments it
- csrrw zero, 65, ra #Load RA into EPC
- jal mecall
- IAF:
- la a0, IAF_MSG
- li a6, 4 #PrintString
- lw ra, 12(sp)
- addi ra, ra, -4 #Decrement RA because teardown increments it
- csrrw zero, 65, ra #Load RA into EPC
- jal mecall
- #Note: Only IAM & IAF should load ra into EPC
- LAM:
- la a0, LAM_MSG1
- li a6, 4 #PrintString
- addi a5, zero, 1 #***STORE 1 IN A5*** IMPORTANT FOR TEARDOWN!!!
- jal mecall #after jal
- #after printing, resume execution here
- csrrw a0, 65, zero #store epc in a0
- jal hex_init
- #After store_byte, resume execution here
- print_epc:
- la a0, hex_buffer
- li a6, 4 #load printstr
- addi a5, zero, 1 #***STORE 1 IN A5*** IMPORTANT FOR TEARDOWN!!!
- jal mecall
- LAM2:
- la a0, LAM_MSG2
- li a6, 4 #PrintString
- addi a5, zero, 1 #***STORE 1 IN A5*** IMPORTANT FOR TEARDOWN!!
- jal mecall
- csrrw a0, 67, zero #store utval in a0
- jal hex_init
- #should resume exec here
- print_utval:
- la a0, hex_buffer
- li a6, 4 #load printstr
- addi a5, zero, 1 #***STORE 1 IN A5*** IMPORTANT FOR TEARDOWN!!!
- jal mecall
- hex_init:
- addi sp, sp, -32
- sw ra, 28(sp)
- sw t0, 24(sp)
- sw t1, 20(sp)
- sw t2, 16(sp)
- sw t3, 12(sp)
- sw t4, 8(sp)
- sw t5, 4(sp)
- sw t6, (sp)
- la t0, hex_buffer
- li t1, 0
- li t2, 28
- li t3, 32
- printhex:
- ebreak
- andi t4, t4, 0 #clear t4
- sll t4, a0, t1 #store epc in t4
- srl, t4, t4, t2 #Shift right 28 bits
- li t5, 9 #String converter
- ble t4, t5, inc_epc
- addi t4, t4, 87
- b store_byte
- inc_epc:
- addi t4, t4, 48
- store_byte:
- sb t4, (t0) #store into buffer
- addi t0, t0, 1 #Point to next byte
- addi t1, t1, 4
- bne t1, t3, printhex #print another char if we havent reached 32nd bit
- lw ra, 28(sp) #HERE I NEED TO B BRACK TO LAMV
- ret
- LAF:
- addi x0, x0, 4
- b LAF
- SAM:
- addi x0, x0, 5
- b SAM
- SAF:
- BAD:
- None:
- teardown:
- lw ra, 12(sp) #Retrieve RA
- lw t0, 8(sp) #Retrieve t0
- #addi sp, sp, 16 #Pop current stack frame
- #handler: # Just ignore it by moving epc (65) to the next instruction
- #Add 4 to epc, so uret returns to line AFTER ecall
- #lw t1, 52(sp)
- #lw t2, 48(sp)
- #lw t3, 44(sp)
- #lw t4, 40(sp)
- #lw t5, 36(sp)
- #lw t6, 32(sp)
- #lw a0, 28(sp)
- #lw a1, 24(sp)
- #lw a2, 20(sp)
- #lw a3, 16(sp)
- #lw a4, 12(sp)
- #lw a5, 8(sp)
- #lw a6, 4(sp)
- #lw a7, (sp)
- csrrw t6, 65, zero
- addi t6, t6, 4
- csrrw zero, 65, t6
- addi a7, zero 0 #Clear a7 ecall won't jump to mecall if a7 contains something
- #ebreak
- bgt a5, zero, a5_triggered #IF a5 is 1, store ra in epc (LAM)
- uret #Returns from handling an interrupt, used instead of jumping to uepc (the user-level exception program counter)
- a5_triggered:
- csrrw zero, 65, ra
- andi a5, a5, 0 #Clear a5
- uret
- #8 is ID of ecall exception. ucause should be 8?
- #lw zero, 0
- # trigger trap for load access fault? #@ What does this mean? Dont need this. it causes exception
- #To add external device interrupts. The “User External Interrupt Enable” (UEIP) bit must be set in the mie/uie register (CSR 4).
- #csrrsi zero, 4, 1
- #Set scratch reg to starting address of system stack?
- #leave a7 as 0, load 4 into a6
- .data #Use num in a7 as index to table
- test_str:
- .string "hi" #printstring called"
- Subroutines:
- .word Undefined Undefined Undefined Undefined PrintString ReadInt Undefined Undefined ReadString Undefined Exit PrintChar ReadChar
- Error:
- .string "invalid or unimplemented syscall service"
- ExitMessage:
- .string "-- program is finished running --"
- enter:
- .word 0x0A #Holds enter key
- ReadStringBuffer:
- .space 20
- TDR: #Transmitter Data Register - Characters written here will be displayed on screen
- .word 0xffff000c
- TCR: #Transmitter Control Register - set to 1 when device ready to display character on screen
- .word 0xffff0008
- RDR: #Receiver Data Register - Characters typed are stored here
- .word 0xffff0004
- RCR: #Receiver Control Register - Bit [0] is one when keyboard has received a new character.
- .word 0xffff0000
- #IndexTbl:
- #.word 0, 1, 4, 5, 6, 7, 8, -1 #WHY -1?
- ExceptionTbl:
- .word IAM IAF None None LAM LAF SAM SAF ENVCALL BAD #WHY BAD?
- IAM_MSG:
- .string "Error in : Instruction load alignment error\n"
- IAF_MSG:
- .string "Error in : Instruction load access error\n"
- None_MSG:
- .string "?"
- LAM_MSG1:
- .string "Runtime exception at "
- LAM_MSG2:
- .string ": Load address not aligned to word boundary "
- LAF_MSG1:
- .string "Runtime exception at "
- LAF_MSG2:
- .string ": Cannot read directly from text segment!"
- SAM_MSG1:
- .string "Runtime exception at 0x00400004"
- SAM_MSG2:
- .string ": Store address not aligned to word boundary "
- SAF_MSG1:
- .string "Runtime exception at "
- SAF_MSG2:
- .string ": Store address not aligned to word boundary "
- hex_buffer:
- .space 32
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement