Instructions
Requirements and Specifications
Screenshots of output
Source Code
.data
TEST_A_16x16:
.byte 9 3 8 5 7 0 8 3 9 3 4 7 3 5 7 1
4 3 2 1 7 8 5 3 7 5 3 6 6 3 1 6
7 4 3 1 9 5 4 6 6 3 6 1 6 6 0 7
3 8 1 5 0 5 5 0 4 9 2 0 6 2 4 1
2 6 5 9 7 2 7 8 4 2 8 0 1 1 0 9
5 8 7 1 9 9 7 2 2 3 8 7 2 1 2 4
5 6 1 0 8 8 5 7 0 3 4 5 1 4 2 4
7 3 6 1 8 5 3 1 4 2 0 0 6 9 7 9
0 5 3 4 7 3 8 9 8 5 5 0 2 4 5 5
6 6 0 3 8 1 3 2 1 2 5 1 5 0 7 3
5 8 8 3 2 7 8 8 5 4 4 4 3 6 3 7
4 0 3 0 9 5 7 7 0 4 8 3 0 7 9 0
0 6 7 4 9 2 7 0 0 4 9 1 1 9 7 5
8 1 2 7 6 1 4 0 3 5 3 8 1 3 3 2
2 9 3 7 2 0 3 8 8 3 1 9 8 0 5 8
2 9 7 2 1 1 0 7 9 9 9 9 1 4 6 2
.text
main:
# Students may modify this "main" section temporarily for their testing.
# However, when evaluating your submission, all code from lines 1
# to 49 will be replaced by other testing code (i.e., we will only
# keep code from lines 50 onward). If your solution breaks because
# you have ignored this note, then a mark of zero for Part 2
# of the assignment is possible.
la $a0, TEST_A_16x16
addi $a1, $zero, 4
addi $a2, $zero, 0
jal sum_neighbours # Test 2a; $v0 should be 30
la $a0, TEST_A_16x16
addi $a1, $zero, 9
addi $a2, $zero, 8
jal sum_neighbours # Test 2b; $v0 should be 43
la $a0, TEST_A_16x16
addi $a1, $zero, 15
addi $a2, $zero, 15
jal sum_neighbours # Test 2c; $v0 should be 19
addi $v0, $zero, 10
syscall
# STUDENTS MAY MODIFY CODE BELOW
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
.data
# Available for any extra `.eqv` or data needed for your solution.
.text
# sum_neighbours:
#
# $a0 is 16x16 byte array
# $a1 is row (0 is topmost)
# $a2 is column (0 is leftmost)
#
# $v0 holds the value of the bytes around the row and column
sum_neighbours:
addi $sp, $sp, -24 # allocate space in stack to save registers
sw $ra, 0($sp) # save return address
sw $s0, 4($sp) # save register
sw $s1, 8($sp) # save register
sw $s2, 12($sp) # save register
sw $s3, 16($sp) # save register
sw $s4, 20($sp) # save register
add $s0, $zero, $a1 # copy row to s1
add $s1, $zero, $a2 # copy column to s2
addi $s2, $zero, 0 # initialize sum to zero
addi $s3, $zero, -1 # initialize relative row to -1
sum_row:
addi $s4, $zero, -1 # initialize relative column to -1
sum_col:
or $t0, $s3, $s4 # combine relative row and column
beqz $t0, sum_skip # if row and column are zero, do not sum
add $a1, $s0, $s3 # use current row
add $a2, $s1, $s4 # use current column
jal get_16x16 # get value at (row,col)
add $s2, $s2, $v0 # add value to sum
sum_skip:
addi $s4, $s4, 1 # increment column
slti $t0, $s4, 2 # compare relative column with 2
bnez $t0, sum_col # repeat while column < 2
addi $s3, $s3, 1 # increment row
slti $t0, $s3, 2 # compare relative row with 2
bnez $t0, sum_row # repeat while row < 2
add $v0, $zero, $s2 # return sum
lw $ra, 0($sp) # load return address
lw $s0, 4($sp) # load register
lw $s1, 8($sp) # load register
lw $s2, 12($sp) # load register
lw $s3, 16($sp) # load register
lw $s4, 20($sp) # load register
addi $sp, $sp, 24 # remove allocated space from stack
jr $ra
# Use here your solution to Part A for this function
# (i.e., copy-and-paste your code).
set_16x16:
bltz $a1, set_return # if row < 0, do nothing
slti $t0, $a1, 16 # compare row with 16
beq $t0, $zero, set_return # if row>=16, do nothing
bltz $a2, set_return # if column < 0, do nothing
slti $t0, $a2, 16 # compare column with 16
beq $t0, $zero, set_return # if column>=16, do nothing
sll $t0, $a1, 4 # multiply row by 16 using left shift
add $t0, $t0, $a2 # add column to get value offset
add $t0, $t0, $a0 # add array address to get the value address
sb $a3, 0($t0) # save value in the calculated array addres
set_return:
jr $ra
# Use here your solution to Part A for this function
# (i.e., copy-and-paste your code).
get_16x16:
addi $v0, $zero, 0 # by default, return 0 in $v0
bltz $a1, get_return # if row < 0, do nothing
slti $t0, $a1, 16 # compare row with 16
beq $t0, $zero, get_return # if row>=16, do nothing
bltz $a2, get_return # if column < 0, do nothing
slti $t0, $a2, 16 # compare column with 16
beq $t0, $zero, get_return # if column>=16, do nothing
sll $t0, $a1, 4 # multiply row by 16 using left shift
add $t0, $t0, $a2 # add column to get value offset
add $t0, $t0, $a0 # add array address to get the value address
lb $v0, 0($t0) # load value from the calculated array addres, return it in $v0
get_return:
jr $ra
# Use here your solution to Part A for this function
# (i.e., copy-and-paste your code).
copy_16x16:
addi $sp, $sp, -12 # allocate space in stack to save registers
sw $ra, 0($sp) # save return address
sw $s0, 4($sp) # save register
sw $s1, 8($sp) # save register
add $s0, $zero, $a0 # copy array address to s0
add $s1, $zero, $a1 # copy array address to s1
addi $t3, $zero, 16 # initialize array size to 16
addi $t1, $zero, 0 # initialize row index to zero
copy_row:
addi $t2, $zero, 0 # initialize column index to zero
copy_col:
add $a0, $zero, $s1 # copy address of second array (source)
add $a1, $zero, $t1 # copy current row index
add $a2, $zero, $t2 # copy current column index
jal get_16x16 # get value from second array
add $a0, $zero, $s0 # copy address of first array (destination)
add $a1, $zero, $t1 # copy current row index
add $a2, $zero, $t2 # copy current column index
add $a3, $zero, $v0 # copy value loaded from second array
jal set_16x16 # set value in first array
addi $t2, $t2, 1 # increment column index
bne $t2, $t3, copy_col # repeat while column != 16
addi $t1, $t1, 1 # increment row index
bne $t1, $t3, copy_row # repeat while row != 16
lw $ra, 0($sp) # load return address
lw $s0, 4($sp) # load register
lw $s1, 8($sp) # load register
addi $sp, $sp, 12 # remove allocated space from stack
jr $ra
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# STUDENTS MAY MODIFY CODE ABOVE
.data
GEN_A: .space 256
GEN_B: .space 256
GEN_Z: .space 256
TEST_A_16x16:
.byte 9 3 8 5 7 0 8 3 9 3 4 7 3 5 7 1
4 3 2 1 7 8 5 3 7 5 3 6 6 3 1 6
7 4 3 1 9 5 4 6 6 3 6 1 6 6 0 7
3 8 1 5 0 5 5 0 4 9 2 0 6 2 4 1
2 6 5 9 7 2 7 8 4 2 8 0 1 1 0 9
5 8 7 1 9 9 7 2 2 3 8 7 2 1 2 4
5 6 1 0 8 8 5 7 0 3 4 5 1 4 2 4
7 3 6 1 8 5 3 1 4 2 0 0 6 9 7 9
0 5 3 4 7 3 8 9 8 5 5 0 2 4 5 5
6 6 0 3 8 1 3 2 1 2 5 1 5 0 7 3
5 8 8 3 2 7 8 8 5 4 4 4 3 6 3 7
4 0 3 0 9 5 7 7 0 4 8 3 0 7 9 0
0 6 7 4 9 2 7 0 0 4 9 1 1 9 7 5
8 1 2 7 6 1 4 0 3 5 3 8 1 3 3 2
2 9 3 7 2 0 3 8 8 3 1 9 8 0 5 8
2 9 7 2 1 1 0 7 9 9 9 9 1 4 6 2
.text
main:
# Students may modify this "main" section temporarily for their testing.
# However, when evaluating your submission, all code from lines 1
# to 61 will be replaced by other testing code (i.e., we will only
# keep code from lines 62 onward). If your solution breaks because
# you have ignored this note, then a mark of zero for Part 1
# of the assignment is possible.
la $a0, GEN_A
addi $a1, $zero, 0
addi $a2, $zero, 0
addi $a3, $zero, 0x1
jal set_16x16 # Test 1a
la $a0, GEN_A
addi $a1, $zero, 15
addi $a2, $zero, 15
addi $a3, $zero, 0x1
jal set_16x16 # Test 1b
la $a0, TEST_A_16x16
addi $a1, $zero, 13
addi $a2, $zero, 4
jal get_16x16 # Test 1c; $v0 should be 6
la $a0, GEN_B
la $a1, TEST_A_16x16
jal copy_16x16 # Memory in data area for GEN_B
# be an exact copy of data area
# for TEST_A_16x16
addi $v0, $zero, 10
syscall
# STUDENTS MAY MODIFY CODE BELOW
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
.data
# Available for any extra `.eqv` or data needed for your solution.
.text
# set_16x16:
#
# $a0 is 16x16 byte array
# $a1 is row (0 is topmost)
# $a2 is column (0 is leftmost)
# $a3 is the value to be stored (i.e., rightmost 8 bits)
#
# If $a1 or $a2 are outside bounds of array, then
# nothing happens.
set_16x16:
bltz $a1, set_return # if row < 0, do nothing
slti $t0, $a1, 16 # compare row with 16
beq $t0, $zero, set_return # if row>=16, do nothing
bltz $a2, set_return # if column < 0, do nothing
slti $t0, $a2, 16 # compare column with 16
beq $t0, $zero, set_return # if column>=16, do nothing
sll $t0, $a1, 4 # multiply row by 16 using left shift
add $t0, $t0, $a2 # add column to get value offset
add $t0, $t0, $a0 # add array address to get the value address
sb $a3, 0($t0) # save value in the calculated array addres
set_return:
jr $ra
# get_16x16:
#
# $a0 is 16x16 byte array
# $a1 is row (0 is topmost)
# $a2 is column (0 is leftmost)
#
# If $a1 or $a2 are outside bounds of array, then
# the value of zero is returned
#
# $v0 holds the value of the byte at that array location
get_16x16:
addi $v0, $zero, 0 # by default, return 0 in $v0
bltz $a1, get_return # if row < 0, do nothing
slti $t0, $a1, 16 # compare row with 16
beq $t0, $zero, get_return # if row>=16, do nothing
bltz $a2, get_return # if column < 0, do nothing
slti $t0, $a2, 16 # compare column with 16
beq $t0, $zero, get_return # if column>=16, do nothing
sll $t0, $a1, 4 # multiply row by 16 using left shift
add $t0, $t0, $a2 # add column to get value offset
add $t0, $t0, $a0 # add array address to get the value address
lb $v0, 0($t0) # load value from the calculated array addres, return it in $v0
get_return:
jr $ra
# copy_16x16:
#
# $a0 is the destination 16x16 byte array
# $a1 is the source 16x16 byte array
copy_16x16:
addi $sp, $sp, -12 # allocate space in stack to save registers
sw $ra, 0($sp) # save return address
sw $s0, 4($sp) # save register
sw $s1, 8($sp) # save register
add $s0, $zero, $a0 # copy array address to s0
add $s1, $zero, $a1 # copy array address to s1
addi $t3, $zero, 16 # initialize array size to 16
addi $t1, $zero, 0 # initialize row index to zero
copy_row:
addi $t2, $zero, 0 # initialize column index to zero
copy_col:
add $a0, $zero, $s1 # copy address of second array (source)
add $a1, $zero, $t1 # copy current row index
add $a2, $zero, $t2 # copy current column index
jal get_16x16 # get value from second array
add $a0, $zero, $s0 # copy address of first array (destination)
add $a1, $zero, $t1 # copy current row index
add $a2, $zero, $t2 # copy current column index
add $a3, $zero, $v0 # copy value loaded from second array
jal set_16x16 # set value in first array
addi $t2, $t2, 1 # increment column index
bne $t2, $t3, copy_col # repeat while column != 16
addi $t1, $t1, 1 # increment row index
bne $t1, $t3, copy_row # repeat while row != 16
lw $ra, 0($sp) # load return address
lw $s0, 4($sp) # load register
lw $s1, 8($sp) # load register
addi $sp, $sp, 12 # remove allocated space from stack
jr $ra
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# STUDENTS MAY MODIFY CODE ABOVE
.include "display.asm"
.data
GEN_A: .space 256
GEN_B: .space 256
GEN_Z: .space 256
# Students may modify the ".data" and "main" section temporarily
# for their testing. However, when evaluating your submission, all
# code from lines 1 to 33 will be replaced by other testing code
# (i.e., we will only keep code from lines 34 onward). If your
# solution breaks because you have ignored this note, then a mark
# of zero for Part 3 of the assignment is possible.
TEST_PATTERN:
.word 0x0000 0x0000 0x0ff8 0x1004 0x0000 0x0630 0x0000 0x0080
0x0080 0x2002 0x1004 0x0808 0x0630 0x01c0 0x0000 0x0000
.text
main:
la $a0, GEN_A
la $a1, TEST_PATTERN
jal bitmap_to_16x16
la $a0, GEN_A
jal draw_16x16
addi $v0, $zero, 10
syscall
# STUDENTS MAY MODIFY CODE BELOW
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
.data
# Available for any extra `.eqv` or data needed for your solution.
.text
# bitmap_to_16x16:
#
# $a0 holds the address of first byte in the array
# $a1 holds the address of the first word holding a row’s bitmap pattern
bitmap_to_16x16:
addi $t3, $zero, 16 # repeat the loop 16 times to process all rows in bitmap
bitmap_row:
lw $t0, 0($a1) # load word from bitmap corresponding to a row
addi $a1, $a1, 4 # increment address to advance to next word in bitmap
addi $t1, $zero, 15 # load current bit being tested
bitmap_col:
srlv $t2, $t0, $t1 # move the bit down
andi $t2, $t2, 1 # get the lowest bit
sb $t2, 0($a0) # save bit in byte array
addi $a0, $a0, 1 # advance to next position in byte array
addi $t1, $t1, -1 # decrement bit position
bgez $t1, bitmap_col # repeat while position is >= 0
addi $t3, $t3, -1 # decrement number of rows
bnez $t3, bitmap_row # repeat while number of rows is not zero
jr $ra
# draw_16x16:
#
# $a0 holds the address of first byte in the array
draw_16x16:
addi $sp, $sp, -16 # allocate space in stack to save registers
sw $ra, 0($sp) # save return address
sw $s0, 4($sp) # save register
sw $s1, 8($sp) # save register
sw $s2, 12($sp) # save register
add $s2, $zero, $a0 # save array address in s2
addi $s0, $zero, 0 # start in row 0
draw_row:
addi $s1, $zero, 0 # start in column 0
draw_col:
add $a0, $zero, $s2 # copy byte array address
add $a1, $zero, $s0 # copy current row
add $a2, $zero, $s1 # copy current column
jal get_16x16 # get pixel from array
beqz $v0, draw_pix # if the color is zero, draw pixel
addi $v0, $zero, -1 # else, load -1 to set to white colour
draw_pix:
add $a0, $zero, $s0 # copy current row
add $a1, $zero, $s1 # copy current column
add $a2, $zero, $v0 # copy colour
jal set_pixel # save byte in display
addi $s1, $s1, 1 # increment column
slti $t0, $s1, 16 # compare column with 16
bnez $t0, draw_col # repeat while column < 16
addi $s0, $s0, 1 # increment row
slti $t0, $s0, 16 # compare row with 16
bnez $t0, draw_row # repeat while row < 16
lw $ra, 0($sp) # load return address
lw $s0, 4($sp) # load register
lw $s1, 8($sp) # load register
lw $s2, 12($sp) # load register
addi $sp, $sp, 16 # remove allocated space from stack
jr $ra
# Use here your solution to Part A for this function
# (i.e., copy-and-paste your code).
get_16x16:
addi $v0, $zero, 0 # by default, return 0 in $v0
bltz $a1, get_return # if row < 0, do nothing
slti $t0, $a1, 16 # compare row with 16
beq $t0, $zero, get_return # if row>=16, do nothing
bltz $a2, get_return # if column < 0, do nothing
slti $t0, $a2, 16 # compare column with 16
beq $t0, $zero, get_return # if column>=16, do nothing
sll $t0, $a1, 4 # multiply row by 16 using left shift
add $t0, $t0, $a2 # add column to get value offset
add $t0, $t0, $a0 # add array address to get the value address
lb $v0, 0($t0) # load value from the calculated array addres, return it in $v0
get_return:
jr $ra
# Use here your solution to Part A for this function
# (i.e., copy-and-paste your code).
copy_16x16:
addi $sp, $sp, -12 # allocate space in stack to save registers
sw $ra, 0($sp) # save return address
sw $s0, 4($sp) # save register
sw $s1, 8($sp) # save register
add $s0, $zero, $a0 # copy array address to s0
add $s1, $zero, $a1 # copy array address to s1
addi $t3, $zero, 16 # initialize array size to 16
addi $t1, $zero, 0 # initialize row index to zero
copy_row:
addi $t2, $zero, 0 # initialize column index to zero
copy_col:
add $a0, $zero, $s1 # copy address of second array (source)
add $a1, $zero, $t1 # copy current row index
add $a2, $zero, $t2 # copy current column index
jal get_16x16 # get value from second array
add $a0, $zero, $s0 # copy address of first array (destination)
add $a1, $zero, $t1 # copy current row index
add $a2, $zero, $t2 # copy current column index
add $a3, $zero, $v0 # copy value loaded from second array
jal set_16x16 # set value in first array
addi $t2, $t2, 1 # increment column index
bne $t2, $t3, copy_col # repeat while column != 16
addi $t1, $t1, 1 # increment row index
bne $t1, $t3, copy_row # repeat while row != 16
lw $ra, 0($sp) # load return address
lw $s0, 4($sp) # load register
lw $s1, 8($sp) # load register
addi $sp, $sp, 12 # remove allocated space from stack
jr $ra
set_16x16:
bltz $a1, set_return # if row < 0, do nothing
slti $t0, $a1, 16 # compare row with 16
beq $t0, $zero, set_return # if row>=16, do nothing
bltz $a2, set_return # if column < 0, do nothing
slti $t0, $a2, 16 # compare column with 16
beq $t0, $zero, set_return # if column>=16, do nothing
sll $t0, $a1, 4 # multiply row by 16 using left shift
add $t0, $t0, $a2 # add column to get value offset
add $t0, $t0, $a0 # add array address to get the value address
sb $a3, 0($t0) # save value in the calculated array addres
set_return:
jr $ra
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# STUDENTS MAY MODIFY CODE ABOVE