LED Display in MIPS Assembly Language

LED Display in MIPS Assembly Language Homework Sample

The MARS assembly language simulator not only simulates the processor but also some peripherals. This assembly language assignment involves the simulated LED screen and the keyboard, which can be accessed from the tools menu. You will also need to use multiple assembly language files, so use the Settings > Assemble all files in the directory. Call display_set_pixel to update a pixel at x,y coordinates, and use display_update_and_clear to update the screen after you finish drawing. Write a program to move 3 pixels around the screen in response to the keyboard, and use the B key to switch between the 3 different pixels.

Solution:

main.asm

.include “convenience.asm”
.data
promtInt: .asciiz “Input three numbers (x, y, and size).\n”
intX: .asciiz “x input value is: ”
intY: .asciiz “y input value is: ”
intSize: .asciiz “size input value is: ”

promtStr: .asciiz “Input a character representing the color from the following options:\n”
promOpt: .asciiz “k = black, r = red, o = orange, y = yellow, g = green, b = blue, m = magenta, w = white\n”
charInp: .asciiz “Character input of color choice: ”

.text
.globl main
main:
li v0, 4 # prints promtInt
la a0, promtInt
syscall

li v0, 4 # prints intX
la a0, intX
syscall
li v0, 5 # read user input
syscall
move s0, v0 # moving user input into s0

li v0, 4 # prints inty
la a0, intY
syscall
li v0, 5 # read user input
syscall
move s1, v0 # moving user input into s1

li v0, 4 # prints intSize
la a0, intSize
syscall
li v0, 5 # read user input
syscall
move s2, v0 # moving user input into s2

li v0, 4 # prints promtStr
la a0, promtStr
syscall

li v0, 4 # prints promOpt
la a0, promOpt
syscall

li v0, 4 # prints charInp
la a0, charInp
syscall

li v0, 12
syscall
move a3, v0

get_LED:
beq a3, ‘k’, set_black
beq a3, ‘r’, set_red
beq a3, ‘o’, set_orange
beq a3, ‘y’, set_yellow
beq a3, ‘g’, set_green
beq a3, ‘b’, set_blue
beq a3, ‘m’, set_magenta
beq a3, ‘w’, set_white

set_black:
li a3, 0
j LED_setup

set_red:
li a3, 1
j LED_setup

set_orange:
li a3, 2
j LED_setup

set_yellow:
li a3, 3
j LED_setup

set_green:
li a3, 4
j LED_setup

set_blue:
li a3, 5
j LED_setup

set_magenta:
li a3, 6
j LED_setup

set_white:
li a3, 7

LED_setup:

move $a0, $s0
move $a1, $s1
move $a2, $s2
# jal draw_horizontal_line
# jal draw_vertical_line
jal draw_spiral
exit

# void draw_horizontal_line(int x, int y, int size, int colour)
# for(i=0; i<size; i++) {
# display_set_pixel(x+i, y, colour);
# }
draw_horizontal_line:
# prologue
enter s0, s1, s2, s3, s4

# Preserve all input parameters
move s0, a0 # s0 contains x
move s1, a1 # s1 contains y
move s2, a2 # s2 contains size
move s3, a3 # s3 contains colour

li s4, 0 # s4 contains i, initialize i=0
_draw_horizontal_line_loop:
bge s4, s2, _draw_horizontal_line_exit # Check if i >= size
# for loop implementation
add a0, s0, s4 # Calculate x-coordinate = x+i
move a1, s1 # Calculate y-coordinate is fixed
move a2, s3 # Colour set by user
jal display_set_pixel
jal display_update #_and_clear
inc s4 # Increment i
j _draw_horizontal_line_loop
_draw_horizontal_line_exit:
# epilogue
leave s0, s1, s2, s3, s4

draw_vertical_line:
# prologue
enter s0, s1, s2, s3, s4

# Preserve all input parameters
move s0, a0 # s0 contains x
move s1, a1 # s1 contains y
move s2, a2 # s2 contains size
move s3, a3 # s3 contains colour

li s4, 0 # s4 contains i, initialize i=0
_draw_vertical_line_loop:
bge s4, s2, _draw_vertical_line_exit # Check if i >= size
# for loop implementation
move a0, s0 # Calculate x-coordinate is fixed
add a1, s1, s4 # Calculate y-coordinate = y+i
move a2, s3 # Colour set by user
jal display_set_pixel
jal display_update_and_clear
inc s4 # Increment i
j _draw_vertical_line_loop
_draw_vertical_line_exit:
# epilogue
leave s0, s1, s2, s3, s4

draw_spiral:
enter s0, s1, s2, s3, s4

# Preserve all input parameters
move s0, a0 # s0 contains x
move s1, a1 # s1 contains y
move s2, a2 # s2 contains size
move s3, a3 # s3 contains colour

_draw_spiral_loop:
ble s2, 1, _draw_spiral_exit # while (size > 1)

move a0, s0
move a1, s1
move a2, s2
move a3, s3
jal draw_horizontal_line
jal display_update#_and_clear

add s0, s0, s2 # x = x+ size -1
addi s0, s0, -1
addi s2, s2, -1 # size —

move a0, s0
move a1, s1
move a2, s2
move a3, s3
jal draw_vertical_line
jal display_update#_and_clear

add s1, s1, s2 # y = y+ size -1
addi s1, s1, -1
addi s2, s2, -1 # size —

sub s0, s0, s2 # x = x – size +1
addi s0, s0, 1
move a0, s0
move a1, s1
move a2, s2
move a3, s3
jal draw_horizontal_line
jal display_update#_and_clear

addi s2, s2, -1 # size —

sub s1, s1, s2 # y = y – size +1
addi s1, s1, 1
move a0, s0
move a1, s1
move a2, s2
move a3, s3
jal draw_vertical_line
jal display_update#_and_clear

addi s2, s2, -1 # size —

j _draw_spiral_loop

_draw_spiral_exit:
leave s0, s1, s2, s3, s4

controller_pixel.asm

## This file implements the functions that control the pixels based on the keyboard input

# Include the convenience file so that we save some typing! 🙂
.include “convenience.asm”
# Include the game settings file with the board settings! 🙂
.include “game.asm”
# We will need to access the pixel model, include the structure offset definitions
.include “pixel_struct.asm”

# This function needs to be called by other files, so it needs to be global
.globl pixel_update

.data
old_frame: .word 0

.text
# void pixel_update(current_frame)
# 1. This function goes through the array of pixels and finds the one that is selected (maybe you want to implement this as a different function?)
# 2. If no pixel is selected, then select pixel 0
# 3. Reads the state of the keyboard buttons and move the selected pixel accordingly
# 3.1. The pixel moves up to one pixel up/down and up to one pixel left/right according to the keyboard input.
# 3.2. The pixel must not leave the bounds of the display (check the .eqv in game.asm)
# 4. If the user pressed the action button (B) the current selected pixel is deselected and the next pixel is selected (the array loops around).
pixel_update:
enter s0, s1, s2
move s2, a0 # save frames in s2

jal pixel_search_selected # search for the selected pixel or get first pixel if none is selected
move s1, v0

move a0, s1 # use found index
jal pixel_get_element # get the pixel struct pointer
move s0, v0

jal input_get_keys
andi t0, v0, KEY_UP # if key up is pressed
bnez t0, pixel_update_up
andi t0, v0, KEY_DOWN # if key down is pressed
bnez t0, pixel_update_down
andi t0, v0, KEY_LEFT # if key left is pressed
bnez t0, pixel_update_left
andi t0, v0, KEY_RIGHT # if key right is pressed
bnez t0, pixel_update_right
andi t0, v0, KEY_B # if key action is pressed
bnez t0, pixel_update_b
j pixel_update_return
pixel_update_up:
lw t0, pixel_y(s0) # load y position
addi t0,t0,-1 # move to y-1
bltz t0, pixel_update_return # if negative, don’t update
sw t0, pixel_y(s0) # update y position
j pixel_update_return
pixel_update_down:
lw t0, pixel_y(s0) # load y position
addi t0,t0,1 # move to y+1
bge t0, DISPLAY_H, pixel_update_return # if x>=Height, don’t update
sw t0, pixel_y(s0) # update y position
j pixel_update_return
pixel_update_left:
lw t0, pixel_x(s0) # load x position
addi t0,t0,-1 # move to x-1
bltz t0, pixel_update_return # if negative, don’t update
sw t0, pixel_x(s0) # update x position
j pixel_update_return
pixel_update_right:
lw t0, pixel_x(s0) # load x position
addi t0,t0,1 # move to x+1
bge t0, DISPLAY_W, pixel_update_return # if x>=Width, don’t update
sw t0, pixel_x(s0) # update x position
j pixel_update_return
pixel_update_b:
lw t0, old_frame # get last frame count

sub t0, s2, t0 # get difference of current – previous count

blt t0, 60, pixel_update_return # if < 60, do nothing
sw s2, old_frame # update frame number
sw zero, pixel_selected(s0) # deselect current pixel
addi s1, s1, 1 # select next pixel
blt s1, 3, _set_sel # if pixel < 3, set as selected
li s1, 0 # else wrap around
_set_sel:
move a0, s1 # use found index
jal pixel_get_element # get the pixel struct pointer
li t0, 1
sw t0, pixel_selected(v0) # select next pixel

pixel_update_return:
leave s0, s1, s2

# search for a selected pixel
pixel_search_selected:
enter s0
li s0, 0
_pixel_search_loop:
bge s0, 3, _pixel_search_exit # if we processed all 3 pixels, stop
move a0, s0 # use current index
jal pixel_get_element # get the pixel struct pointer

lw t0, pixel_selected($v0) # get selected value
bnez t0, _pixel_search_return # if is selected, return the pointer
addi s0,s0, 1 # increment array index
j _pixel_search_loop
_pixel_search_exit:
li s0, 0 # return first pixel if no pixel is selected
move a0, s0 # use current index
jal pixel_get_element # get the pixel struct pointer
li t0, 1
sw t0, pixel_selected(v0) # sele first pixel as selected
_pixel_search_return:
move v0, s0
leave s0

view_pixel.asm

## This file implements the functions that display the pixels based on the model

# Include the convenience file so that we save some typing! 🙂
.include “convenience.asm”
# Include the game settings file with the board settings! 🙂
.include “game.asm”
# We will need to access the pixel model, include the structure offset definitions
.include “pixel_struct.asm”

# This function needs to be called by other files, so it needs to be global
.globl pixel_draw

.text
# void pixel_update()
# 1. This function goes through the array of pixels and for each
# 1.1. Gets its (x, y) coordinates
# 1.2. Prints it in the display using function display_set_pixel (display.asm)
# 1.2.1. If the pixel is not selected, print it using some color (Not COLOR_BLACK, as this is the background color)
# 1.2.2. If the pixel is selected, print it using another color
pixel_draw:
enter s0
# Your code goes in here
li s0, 0
_pixel_draw_loop:
bge s0, 3, _pixel_draw_exit # if we processed all 3 pixels, stop
move a0, s0 # use current index
jal pixel_get_element # get the pixel struct pointer

lw $a0, pixel_x($v0) # load pixel x position
lw $a1, pixel_y($v0) # load pixel x position
lw $t0, pixel_selected($v0) # get selected value
beqz $t0, _pixel_draw_not_selected
_pixel_draw_selected:
li $a2, COLOR_YELLOW
j _pixel_draw_setpixel
_pixel_draw_not_selected:
li $a2, COLOR_BLUE
_pixel_draw_setpixel:
jal display_set_pixel
addi s0,s0, 1 # increment array index
j _pixel_draw_loop
_pixel_draw_exit:
leave s0