.global alt_main
.text
alt_main:
movia sp, 0x00800000 //Set up stack address
movia r10, 0x10000040 //Assigns r10 to address for slider switch
movi r9, 0b00 //Used as initial contents of slider switch
movi r11, 0b001 //Assigns value for SW0
movi r12, 0b010 //Assigns value for SW1
movi r13, 0b011 //Assigns value for SW2
movia r17, 0x00800030 //Assigns r17 to address for LCD control port
movia r16, 0x00800040 //Assigns r18 to address for LCD data port
call LCDportInit //Sets the port for the LCD to OUTPUT
call LCDinit //Sets the details that the LCD will follow
slider_check:
ldbio r9, 0(r10) //Loads contents of the slider switch
andi r9, r9, 0b011 //Checks only first 3 bits/switches
beq r9, r0, slider_check //Loop if 0
beq r4, r9, slider_check //Loop is same as the check register r4
mov r4, r9 //Store new check register as equivalent to r9
beq r9, r11, Hello //If only first slider is on, branch to Hello
beq r9, r12, HowAreYou //If only second slider is on, branch to HowAreYou
beq r9, r13, IAmFine //If only third slider is on, branch to IAmFine
Hello:
movia r18, Message1 //Assigns r18 as the address of Message1
call LCDprintString //Run the subroutine to print the message
br slider_check
HowAreYou:
movia r18, Message2 //Assigns r18 as the address of Message2
call LCDprintString //Run the subroutine to print the message
br slider_check
IAmFine:
movia r18, Message3 //Assigns r18 as the address of Message3
call LCDprintString //Run the subroutine to print the message
br slider_check
LCDcmdWrt:
subi sp, sp, 8 //Make room on stack
stw r6, 0(sp) //Save r6
stw ra, 4(sp) //Save ra incase another
//subroutine is called
call delay_20ms //Time needed to perform command
movi r6, 0 //E=RS=RW=0
stbio r6, 0(r17) //LCD control port
stbio r7, 0(r16) //Send command to LCD data port. The command
//is passed to subroutine in r7
ori r6, r6, 0b100 //E = 1
stbio r6, 0(r17) //LCD control port
call delay_500ns //Keep E high > 450ns
andi r6, r6, 0b11111011 //E = 0
stbio r6, 0(r17) //LCD control port
ldw r6, 0(sp) //restore r6
ldw ra, 4(sp) //restore ra
addi sp, sp, 8 //restore sp up to initial address
ret
LCDdataWrt:
subi sp, sp, 8 //Make room on stack
stw r6, 0(sp) //Save r6
stw ra, 4(sp) //Save ra incase another subroutine is called
call delay_20ms //Time needed to perform command
movi r6, 0b010 //E=0 RS=1 RW=0
stbio r6, 0(r17) //LCD control port
stbio r7, 0(r16) //Send command to LCD data port. The command
//is passed to subroutine in r7
ori r6, r6, 0b100 //E = 1
stbio r6, 0(r17) //LCD control port
call delay_500ns //Keep E high > 450ns
andi r6, r6, 0b11111011 //E = 0
stbio r6, 0(r17) //LCD control port
ldw r6, 0(sp) //restore r6
ldw ra, 4(sp) //restore ra
addi sp, sp, 8 //restore sp up to initial address
ret
LCDportInit:
subi sp, sp, 8 //Make room on stack
stw r6, 0(sp) //Save r6
stw ra, 4(sp) //Save ra incase another subroutine is called
movi r6, 0xff //Value used to initiate the LCD as OUTPUT
stbio r6, 4(r17) //Store to LCD control port
stbio r6, 4(r16) //Store to LCD data port
ldw r6, 0(sp) //restore r6
ldw ra, 4(sp) //restore ra
addi sp, sp, 8 //restore sp up to initial address
ret
LCDinit:
subi sp, sp, 4 //Make room on stack
stw ra, 0(sp) //Save ra
movi r7, 0x38 //Data length 8-bits, 5x7 font
call LCDcmdWrt
movi r7, 0x0f //display ON, cursor ON, cursor Blink
call LCDcmdWrt
movi r7, 0x01 //clear display
call LCDcmdWrt
movi r7, 0x06 //increment cursor position
call LCDcmdWrt
movi r7, 0x02 //home cursor
call LCDcmdWrt
ldw ra, 0(sp) //restore ra
addi sp, sp, 4 //restore sp up to initial address
ret
LCDprintString:
subi sp, sp, 8 //Make room on stack
stw r7, 0(sp) //Save r7
stw ra, 4(sp) //Save ra
movi r7, 0x01 //clear display
call LCDcmdWrt
movi r7, 0x02 //home cursor
call LCDcmdWrt
next_char:
ldb r7, 0(r18) //Load the current character in the string
beq r7, r0, end_printString //If LCD has reached the '0' at the end
//of the string, go to end_printString
call LCDdataWrt //Run the subroutine LCDdataWrt
addi r18, r18, 0x01 //Add 1 to the character string value
br next_char //Loop the current subroutine
end_printString:
ldw r7, 0(sp) //Restore r7
ldw ra, 4(sp) //Restore ra
addi sp, sp, 8 //Restore sp up to initial address
ret
delay_20ms:
subi sp, sp, 8 //Allocate 8 bytes on stack
stw r6, 0(sp) //Save r6
stw ra, 4(sp) //Save return address, allows nesting subroutines
movia r6, 45455 //This value allows for 20ms to pass
again_20ms:
subi r6, r6, 1
bne r6, r0, again_20ms
ldw r6, 0(sp) //Restore r6
ldw ra, 4(sp) //Restore return address
addi sp, sp, 8 //de-allocate stack locations
ret
delay_500ns:
andi r0, r0, 0b0 //These instructions will provide enough
andi r0, r0, 0b0 //time to complete the necessary delay time
ret
.data
Message1:
.asciz "Hello"
Message2:
.asciz "How are you?"
Message3:
.asciz "I am fine"
.end