CS计算机代考程序代写 algorithm # Credit: Jarrett Billingsley for most of this implementation

# Credit: Jarrett Billingsley for most of this implementation

# Keypad and LED Display Simulator driver/API file.
# All the public functions in this file are marked .globl.
################################################################
# DO NOT .include THIS FILE.
################################################################
# Instead, turn on “settings > assemble all files in directory”.

.include “constants.asm”
.include “macros.asm”

# ————————————————————————————————-
# Exposed functions
# ————————————————————————————————-

# ————————————————————————————————-
# returns a bitwise OR of the key constants, indicating which keys are being held down.
# you MUST call wait_for_next_frame for this to work properly.
.globl input_get_keys_held

# ————————————————————————————————-
# returns a bitwise OR of the key constants, indicating which keys were pressed on this frame.
# you MUST call wait_for_next_frame for this to work properly.
.globl input_get_keys_pressed

# ————————————————————————————————-
# returns a bitwise OR of the key constants, indicating which keys were released on this frame.
# you MUST call wait_for_next_frame for this to work properly.
.globl input_get_keys_released

# ————————————————————————————————-
# call once per main loop to keep the game running at a given FPS.
# also increments frame_counter once per call.
.globl wait_for_next_frame

# ————————————————————————————————-
# copies the color data from display RAM onto the screen.
.globl display_update

# ————————————————————————————————-
# copies the color data from display RAM onto the screen, and then clears display RAM.
# does not clear the display, only the RAM so you can draw a new frame from scratch!
.globl display_update_and_clear

# ————————————————————————————————-
# sets 1 pixel to a given color.
# (0, 0) is in the top LEFT, and Y increases DOWNWARDS!
# arguments:
# a0 = x
# a1 = y
# a2 = color (use one of the constants above)
.globl display_set_pixel

# ————————————————————————————————-
# draws a horizontal line starting at (x, y) and going to (x + width – 1, y).
# (0, 0) is in the top LEFT of the screen.
# arguments:
# a0 = x
# a1 = y
# a2 = width
# a3 = color (use one of the constants above)
.globl display_draw_hline

# ————————————————————————————————-
# draws a vertical line starting at (x, y) and going to (x, y + height – 1).
# (0, 0) is in the top LEFT, and Y increases DOWNWARDS!
# arguments:
# a0 = x
# a1 = y
# a2 = height
# a3 = color (use one of the constants above)
.globl display_draw_vline

# ————————————————————————————————-
# fills a rectangle of pixels with a given color.
# there are FIVE arguments, and I was naughty and used ‘v1’ as a “fifth argument register.”
# this is technically bad practice. sue me.
# arguments:
# a0 = top-left corner x
# a1 = top-left corner y
# a2 = width
# a3 = height
# v1 = color (use one of the constants above)
.globl display_fill_rect

# ————————————————————————————————-
# exactly the same as display_fill_rect, but works faster for rectangles whose width and X coord
# are a multiple of 4.
# IF X IS NOT A MULTIPLE OF 4, IT WILL CRASH.
# IF WIDTH IS NOT A MULTIPLE OF 4, IT WILL DO WEIRD THINGS.
# arguments:
# same as display_fill_rect.
.globl display_fill_rect_fast

# ——————————————————————————
# void display_draw_line(x1, y1, x2, y2, color: v1)
# Bresenham’s line algorithm, integer error version adapted from wikipedia
# not SUPER fast, use display_draw_hline/display_draw_vline if you only need those directions
.globl display_draw_line

# ————————————————————————————————-
# draws a string of text (using the font data at the top of the file) in white.
# a0 = top-left x
# a1 = top-left y
# a2 = pointer to string to print
.globl display_draw_text

# ————————————————————————————————-
# draws a string of text (using the font data at the top of the file) in whatever color you want.
# a0 = top-left x
# a1 = top-left y
# a2 = pointer to string to print
# a3 = color
.globl display_draw_colored_text

# ————————————————————————————————-
# draws a single character (using the font data at the top of the file) in white.
# a0 = top-left x
# a1 = top-left y
# a2 = character to print
.globl display_draw_char

# ————————————————————————————————-
# draws a single character (using the font data at the top of the file) in whatever color you want.
# a0 = top-left x
# a1 = top-left y
# a2 = character to print
# a3 = color
.globl display_draw_colored_char

# ————————————————————————————————-
# draws a textual representation of an int in white.
# a0 = top-left x
# a1 = top-left y
# a2 = integer to display (can be negative, will show a – sign)
.globl display_draw_int

# ————————————————————————————————-
# draws a textual representation of an int in whatever color you want.
# a0 = top-left x
# a1 = top-left y
# a2 = integer to display (can be negative, will show a – sign)
# a3 = color
.globl display_draw_colored_int

# ————————————————————————————————-
# draws a textual representation of an int in hex (WITHOUT leading 0x) in white.
# does not display negatives with a -, just FFF…etc.
# a0 = top-left x
# a1 = top-left y
# a2 = integer to display
# a3 = digits to display [1..8]
.globl display_draw_int_hex

# ————————————————————————————————-
# draws a textual representation of an int in hex (WITHOUT leading 0x)in whatever color you want.
# does not display negatives with a -, just FFF…etc.
# a0 = top-left x
# a1 = top-left y
# a2 = integer to display
# a3 = digits to display [1..8]
# v1 = color
.globl display_draw_colored_int_hex

# ————————————————————————————————-
# quickly draw a 5×5-pixel pattern to the display. it can have transparent
# pixels; those with COLOR_NONE will not change the display. This way you can
# have “holes” in your images.
# this function screen-wraps vertically properly. horizontally it just cheats
# and takes advantage of the fact that writing past the end of a row writes to
# the next row, but it’s one pixel… cmon………..
# a0 = top-left x
# a1 = top-left y
# a2 = pointer to pattern (an array of 25 bytes stored row-by-row)
.globl display_blit_5x5_trans

# ————————————————————————————————-
# quickly draw a 5×5-pixel pattern to the display without transparency.
# if it has any COLOR_NONE pixels, the result is undefined.
# a0 = top-left x
# a1 = top-left y
# a2 = pointer to pattern (an array of 25 bytes stored row-by-row)
.globl display_blit_5x5

# ————————————————————————————————-
# Exposed variables
# ————————————————————————————————-

# ————————————————————————————————-
# contains the current game frame number
.globl frame_counter

# ————————————————————————————————-
# Implementation
# ————————————————————————————————-

.data
.eqv CHAR_PATTERN_SIZE 5

# each character is a 5×5 pixel block, stored row-by-row.
# have a look at the comments on the right to see what each character is.
ASCII_patterns:
.byte 0b00100 0b00100 0b00100 0b00000 0b00100 # !
.byte 0b01010 0b01010 0b00000 0b00000 0b00000 # ”
.byte 0b01010 0b11111 0b01010 0b11111 0b01010 # #
.byte 0b01110 0b10100 0b01110 0b00101 0b01110 # $
.byte 0b10001 0b00010 0b00100 0b01000 0b10001 # %
.byte 0b01000 0b10100 0b01000 0b10101 0b01010 # &
.byte 0b00100 0b00100 0b00000 0b00000 0b00000 # ‘
.byte 0b00010 0b00100 0b00100 0b00100 0b00010 # (
.byte 0b01000 0b00100 0b00100 0b00100 0b01000 # )
.byte 0b00100 0b10101 0b01110 0b01010 0b10001 # *
.byte 0b00000 0b00100 0b01110 0b00100 0b00000 # +
.byte 0b00000 0b00000 0b00000 0b01000 0b10000 # ,
pat_dash:
.byte 0b00000 0b00000 0b01110 0b00000 0b00000 # –
.byte 0b00000 0b00000 0b00000 0b00000 0b10000 # .
.byte 0b00001 0b00010 0b00100 0b01000 0b10000 # /
Digit_patterns:
.byte 0b01110 0b10011 0b10101 0b11001 0b01110 # 0
.byte 0b00100 0b01100 0b00100 0b00100 0b01110 # 1
.byte 0b11111 0b00001 0b11111 0b10000 0b11111 # 2
.byte 0b11110 0b00001 0b00110 0b00001 0b11110 # 3
.byte 0b10001 0b10001 0b11111 0b00001 0b00001 # 4
.byte 0b11111 0b10000 0b11110 0b00001 0b11110 # 5
.byte 0b01110 0b10000 0b11110 0b10001 0b01110 # 6
.byte 0b11111 0b00001 0b00010 0b00100 0b01000 # 7
.byte 0b01110 0b10001 0b01110 0b10001 0b01110 # 8
.byte 0b01110 0b10001 0b01111 0b00001 0b01110 # 9
.byte 0b00000 0b01000 0b00000 0b01000 0b00000 # :
.byte 0b00000 0b01000 0b00000 0b01000 0b10000 # ;
.byte 0b00011 0b01100 0b10000 0b01100 0b00011 # < .byte 0b00000 0b01110 0b00000 0b01110 0b00000 # = .byte 0b11000 0b00110 0b00001 0b00110 0b11000 # >
.byte 0b01110 0b10001 0b00010 0b00000 0b00010 # ?
.byte 0b01110 0b10001 0b10111 0b10000 0b01110 # @
Uppercase_patterns:
.byte 0b01110 0b10001 0b11111 0b10001 0b10001 # A
.byte 0b11110 0b10001 0b11110 0b10001 0b11110 # B
.byte 0b01111 0b10000 0b10000 0b10000 0b01111 # C
.byte 0b11110 0b10001 0b10001 0b10001 0b11110 # D
.byte 0b11111 0b10000 0b11100 0b10000 0b11111 # E
.byte 0b11111 0b10000 0b11100 0b10000 0b10000 # F
.byte 0b01110 0b10000 0b10011 0b10001 0b01110 # G
.byte 0b10001 0b10001 0b11111 0b10001 0b10001 # H
.byte 0b01110 0b00100 0b00100 0b00100 0b01110 # I
.byte 0b01110 0b00100 0b00100 0b10100 0b01000 # J
.byte 0b10010 0b10100 0b11000 0b10100 0b10010 # K
.byte 0b10000 0b10000 0b10000 0b10000 0b11111 # L
.byte 0b10001 0b11011 0b10101 0b10001 0b10001 # M
.byte 0b10001 0b11001 0b10101 0b10011 0b10001 # N
.byte 0b01110 0b10001 0b10001 0b10001 0b01110 # O
.byte 0b11110 0b10001 0b11111 0b10000 0b10000 # P
.byte 0b01110 0b10001 0b10101 0b10011 0b01111 # Q
.byte 0b11110 0b10001 0b11111 0b10010 0b10001 # R
.byte 0b11111 0b10000 0b11111 0b00001 0b11111 # S
.byte 0b11111 0b00100 0b00100 0b00100 0b00100 # T
.byte 0b10001 0b10001 0b10001 0b10001 0b01110 # U
.byte 0b10001 0b10001 0b01010 0b01010 0b00100 # V
.byte 0b10001 0b10001 0b10101 0b11011 0b10001 # W
.byte 0b10001 0b01010 0b00100 0b01010 0b10001 # X
.byte 0b10001 0b01010 0b00100 0b00100 0b00100 # Y
.byte 0b11111 0b00010 0b00100 0b01000 0b11111 # Z
.byte 0b01110 0b01000 0b01000 0b01000 0b01110 # [
.byte 0b10000 0b01000 0b00100 0b00010 0b00001 # \
.byte 0b01110 0b00010 0b00010 0b00010 0b01110 # ]
.byte 0b00100 0b01010 0b00000 0b00000 0b00000 # ^
.byte 0b00000 0b00000 0b00000 0b00000 0b11111 # _
.byte 0b01000 0b00100 0b00010 0b00000 0b00000 # `
.byte 0b01110 0b10001 0b11111 0b10001 0b10001 # a (no actual lowercase tho)
.byte 0b11110 0b10001 0b11110 0b10001 0b11110 # b
.byte 0b01111 0b10000 0b10000 0b10000 0b01111 # c
.byte 0b11110 0b10001 0b10001 0b10001 0b11110 # d
.byte 0b11111 0b10000 0b11100 0b10000 0b11111 # e
.byte 0b11111 0b10000 0b11100 0b10000 0b10000 # f
.byte 0b01110 0b10000 0b10011 0b10001 0b01110 # g
.byte 0b10001 0b10001 0b11111 0b10001 0b10001 # h
.byte 0b01110 0b00100 0b00100 0b00100 0b01110 # i
.byte 0b01110 0b00100 0b00100 0b10100 0b01000 # j
.byte 0b10010 0b10100 0b11000 0b10100 0b10010 # k
.byte 0b10000 0b10000 0b10000 0b10000 0b11111 # l
.byte 0b10001 0b11011 0b10101 0b10001 0b10001 # m
.byte 0b10001 0b11001 0b10101 0b10011 0b10001 # n
.byte 0b01110 0b10001 0b10001 0b10001 0b01110 # o
.byte 0b11110 0b10001 0b11111 0b10000 0b10000 # p
.byte 0b01110 0b10001 0b10101 0b10011 0b01111 # q
.byte 0b11110 0b10001 0b11111 0b10010 0b10001 # r
.byte 0b11111 0b10000 0b11111 0b00001 0b11111 # s
.byte 0b11111 0b00100 0b00100 0b00100 0b00100 # t
.byte 0b10001 0b10001 0b10001 0b10001 0b01110 # u
.byte 0b10001 0b10001 0b01010 0b01010 0b00100 # v
.byte 0b10001 0b10001 0b10101 0b11011 0b10001 # w
.byte 0b10001 0b01010 0b00100 0b01010 0b10001 # x
.byte 0b10001 0b01010 0b00100 0b00100 0b00100 # y
.byte 0b11111 0b00010 0b00100 0b01000 0b11111 # z
.byte 0b00110 0b00100 0b01000 0b00100 0b00110 # {
.byte 0b00100 0b00100 0b00100 0b00100 0b00100 # |
.byte 0b01100 0b00100 0b00010 0b00100 0b01100 # }
.byte 0b01010 0b10100 0b00000 0b00000 0b00000 # ~

frame_counter: .word 0
last_frame_time: .word 0
last_frame_keys: .word 0
this_frame_keys: .word 0

.text
# ————————————————————————————————-
# returns a bitwise OR of the key constants, indicating which keys are being held down.
# you MUST call wait_for_next_frame for this to work properly.
input_get_keys_held:
lw v0, this_frame_keys
jr ra

# ————————————————————————————————-
# returns a bitwise OR of the key constants, indicating which keys were pressed on this frame.
# you MUST call wait_for_next_frame for this to work properly.
input_get_keys_pressed:
lw t0, last_frame_keys
not t0, t0
lw v0, this_frame_keys
and v0, v0, t0
jr ra

# ————————————————————————————————-
# returns a bitwise OR of the key constants, indicating which keys were released on this frame.
# you MUST call wait_for_next_frame for this to work properly.
input_get_keys_released:
lw t0, this_frame_keys
not t0, t0
lw v0, last_frame_keys
and v0, v0, t0
jr ra

# ————————————————————————————————-
# call once per main loop to keep the game running at a given FPS.
# also increments frame_counter once per call.
wait_for_next_frame:
enter s0
lw s0, last_frame_time
_loop:
# while (sys_time() – last_frame_time) < MS_PER_FRAME {} syscall_time sub t1, v0, s0 bltu t1, MS_PER_FRAME, _loop # save the time sw v0, last_frame_time # frame_counter++ lw t0, frame_counter inc t0 sw t0, frame_counter # last_frame_keys = this_frame_keys lw t0, this_frame_keys sw t0, last_frame_keys # this_frame_keys = DISPLAY_KEYS lw t0, DISPLAY_KEYS sw t0, this_frame_keys leave s0 # ------------------------------------------------------------------------------------------------- # copies the color data from display RAM onto the screen. display_update: sw zero, DISPLAY_CTRL jr ra # ------------------------------------------------------------------------------------------------- # copies the color data from display RAM onto the screen, and then clears display RAM. # does not clear the display, only the RAM so you can draw a new frame from scratch! display_update_and_clear: li t0, 1 sw t0, DISPLAY_CTRL jr ra # ------------------------------------------------------------------------------------------------- # sets 1 pixel to a given color. # (0, 0) is in the top LEFT, and Y increases DOWNWARDS! # arguments: # a0 = x # a1 = y # a2 = color (use one of the constants above) display_set_pixel: tlti a0, 0 tgei a0, 64 tlti a1, 0 tgei a1, 64 sll t0, a1, DISPLAY_W_SHIFT add t0, t0, a0 add t0, t0, DISPLAY_BASE sb a2, (t0) jr ra # ------------------------------------------------------------------------------------------------- # draws a horizontal line starting at (x, y) and going to (x + width - 1, y). # (0, 0) is in the top LEFT of the screen. # arguments: # a0 = x # a1 = y # a2 = width # a3 = color (use one of the constants above) display_draw_hline: tlti a0, 0 tgei a0, 64 tlti a1, 0 tgei a1, 64 sll t0, a1, DISPLAY_W_SHIFT add t0, t0, a0 add t0, t0, DISPLAY_BASE _loop: sb a3, (t0) inc t0 dec a2 bnez a2, _loop jr ra # ------------------------------------------------------------------------------------------------- # draws a vertical line starting at (x, y) and going to (x, y + height - 1). # (0, 0) is in the top LEFT, and Y increases DOWNWARDS! # arguments: # a0 = x # a1 = y # a2 = height # a3 = color (use one of the constants above) display_draw_vline: tlti a0, 0 tgei a0, 64 tlti a1, 0 tgei a1, 64 sll t0, a1, DISPLAY_W_SHIFT add t0, t0, a0 add t0, t0, DISPLAY_BASE _loop: sb a3, (t0) add t0, t0, DISPLAY_W dec a2 bnez a2, _loop jr ra # ------------------------------------------------------------------------------------------------- # fills a rectangle of pixels with a given color. # there are FIVE arguments, and I was naughty and used 'v1' as a "fifth argument register." # this is technically bad practice. sue me. # arguments: # a0 = top-left corner x # a1 = top-left corner y # a2 = width # a3 = height # v1 = color (use one of the constants above) display_fill_rect: tlti a0, 0 tgei a0, 64 tlti a1, 0 tgei a1, 64 # turn w/h into x2/y2 add a2, a2, a0 add a3, a3, a1 # turn y1/y2 into addresses li t0, DISPLAY_BASE sll a1, a1, DISPLAY_W_SHIFT add a1, a1, t0 add a1, a1, a0 sll a3, a3, DISPLAY_W_SHIFT add a3, a3, t0 move t0, a1 _loop_y: move t1, t0 move t2, a0 _loop_x: sb v1, (t1) inc t1 inc t2 blt t2, a2, _loop_x addi t0, t0, DISPLAY_W blt t0, a3, _loop_y jr ra # ------------------------------------------------------------------------------------------------- # exactly the same as display_fill_rect, but works faster for rectangles whose width and X coord # are a multiple of 4. # IF X IS NOT A MULTIPLE OF 4, IT WILL CRASH. # IF WIDTH IS NOT A MULTIPLE OF 4, IT WILL DO WEIRD THINGS. # arguments: # same as display_fill_rect. display_fill_rect_fast: tlti a0, 0 tgei a0, 64 tlti a1, 0 tgei a1, 64 # duplicate color across v1 and v1, v1, 0xFF mul v1, v1, 0x01010101 add a2, a2, a0 # a2 = x2 add a3, a3, a1 # a3 = y2 # t0 = display base address li t0, DISPLAY_BASE # a1 = start address sll a1, a1, DISPLAY_W_SHIFT add a1, a1, t0 add a1, a1, a0 # a3 = end address sll a3, a3, DISPLAY_W_SHIFT add a3, a3, t0 # t0 = current row's start address move t0, a1 _loop_y: move t1, t0 # t1 = current address move t2, a0 # t2 = current x _loop_x: sw v1, (t1) addi t1, t1, 4 addi t2, t2, 4 blt t2, a2, _loop_x addi t0, t0, DISPLAY_W blt t0, a3, _loop_y jr ra # ------------------------------------------------------------------------------ # void display_draw_line(x1, y1, x2, y2, color: v1) # Bresenham's line algorithm, integer error version adapted from wikipedia # not SUPER fast, use display_draw_hline/display_draw_vline if you only need those directions display_draw_line: tlti a0, 0 tgei a0, 64 tlti a1, 0 tgei a1, 64 # dx:t0 = abs(x2-x1); sub t0, a2, a0 abs t0, t0 # sx:t1 = x1= dy)
blt t5, t2, _dx
add t4, t4, t2 # err += dy;
add a0, a0, t1 # x1 += sx;

_dx:
# if(e2 <= dx) bgt t5, t0, _loop add t4, t4, t0 # err += dx; add a1, a1, t3 # y1 += sy; j _loop _exit: jr ra # ------------------------------------------------------------------------------------------------- # draws a string of text (using the font data at the top of the file) in white. # a0 = top-left x # a1 = top-left y # a2 = pointer to string to print display_draw_text: li a3, COLOR_WHITE j display_draw_colored_text # ------------------------------------------------------------------------------------------------- # draws a string of text (using the font data at the top of the file) in whatever color you want. # a0 = top-left x # a1 = top-left y # a2 = pointer to string to print # a3 = color display_draw_colored_text: enter s0, s1, s2, s3 tlti a0, 0 tgei a0, 64 tlti a1, 0 tgei a1, 64 move s0, a0 # s0: x move s1, a1 # s1: y move s2, a2 # s2: char* move s3, a3 # s3: color _loop: lbu t0, (s2) # t0 = ch beqz t0, _exit # zero terminator? ble t0, 32, _next # nonprintable? bge t0, 127, _next # nonprintable? # pattern = ASCII_patterns[ch - 33] sub t0, t0, 33 mul t0, t0, CHAR_PATTERN_SIZE la t1, ASCII_patterns add a2, t0, t1 # display_show_char(x, y, pattern, color) move a0, s0 move a1, s1 move a3, s3 jal display_show_char _next: add s0, s0, 6 inc s2 j _loop _exit: leave s0, s1, s2, s3 # ------------------------------------------------------------------------------------------------- # draws a single character (using the font data at the top of the file) in white. # a0 = top-left x # a1 = top-left y # a2 = character to print display_draw_char: li a3, COLOR_WHITE j display_draw_colored_char # ------------------------------------------------------------------------------------------------- # draws a single character (using the font data at the top of the file) in whatever color you want. # a0 = top-left x # a1 = top-left y # a2 = character to print # a3 = color display_draw_colored_char: enter tlti a0, 0 tgei a0, 64 tlti a1, 0 tgei a1, 64 beqz a2, _exit # NUL character? ble a2, 32, _exit # nonprintable? bge a2, 127, _exit # nonprintable? # pattern = ASCII_patterns[ch - 33] sub a2, a2, 33 mul a2, a2, CHAR_PATTERN_SIZE la t0, ASCII_patterns add a2, a2, t0 # display_show_char(x, y, pattern, color) jal display_show_char _exit: leave # ------------------------------------------------------------------------------------------------- # draws a textual representation of an int in white. # a0 = top-left x # a1 = top-left y # a2 = integer to display (can be negative, will show a - sign) display_draw_int: li a3, COLOR_WHITE j display_draw_colored_int # ------------------------------------------------------------------------------------------------- # draws a textual representation of an int in whatever color you want. # a0 = top-left x # a1 = top-left y # a2 = integer to display (can be negative, will show a - sign) # a3 = color display_draw_colored_int: enter s0, s1, s2, s3, s4 tlti a0, 0 tgei a0, 64 tlti a1, 0 tgei a1, 64 move s0, a0 # current x move s1, a1 # y move s2, a2 # remaining digits to draw li s3, 1 # radix (1, 10, 100 etc) move s4, a3 # color # if it's negative... bgez s2, _determine_length # make it positive neg s2, s2 # draw a - move a0, s0 move a1, s1 la a2, pat_dash move a3, s4 jal display_show_char # move right by 6 add s0, s0, 6 # determine the number of digits needed by multiplying radix # by 10 until the radix no longer divides into the number _determine_length: div t0, s2, s3 blt t0, 10, _loop mul s3, s3, 10 j _determine_length _loop: # extract and strip off top digit div s2, s3 mfhi s2 # keep lower digits in s2 mflo a2 # print top digit # get digit pattern address la t0, Digit_patterns mul a2, a2, CHAR_PATTERN_SIZE add a2, a2, t0 move a0, s0 move a1, s1 move a3, s4 jal display_show_char # scoot over, decrease radix until it's 0 add s0, s0, 6 div s3, s3, 10 bnez s3, _loop leave s0, s1, s2, s3, s4 # ------------------------------------------------------------------------------------------------- # draws a textual representation of an int in hex (WITHOUT leading 0x) in white. # does not display negatives with a -, just FFF...etc. # a0 = top-left x # a1 = top-left y # a2 = integer to display # a3 = digits to display [1..8] display_draw_int_hex: li v1, COLOR_WHITE j display_draw_colored_int_hex # ------------------------------------------------------------------------------------------------- # draws a textual representation of an int in hex (WITHOUT leading 0x)in whatever color you want. # does not display negatives with a -, just FFF...etc. # a0 = top-left x # a1 = top-left y # a2 = integer to display # a3 = digits to display [1..8] # v1 = color display_draw_colored_int_hex: enter s0, s1, s2, s3, s4 tlti a0, 0 tgei a0, 64 tlti a1, 0 tgei a1, 64 tlti a3, 1 tgei a3, 9 move s0, a0 # current x move s1, a1 # y move s2, a2 # remaining digits to draw sub s3, a3, 1 sll s3, s3, 2 # shift amount (28, 24, 20...) move s4, v1 # color _loop: # extract current digit ((value >> shift_distance) & 0xF)
srlv a2, s2, s3
and a2, a2, 0xF

la t0, Digit_patterns
blt a2, 10, _decimal
sub a2, a2, 10
la t0, Uppercase_patterns
_decimal:

# get pattern address
mul a2, a2, CHAR_PATTERN_SIZE
add a2, a2, t0
move a0, s0
move a1, s1
move a3, s4
jal display_show_char

# scoot over, decrease shift amount until it’s < 0 add s0, s0, 6 sub s3, s3, 4 bgez s3, _loop leave s0, s1, s2, s3, s4 # ------------------------------------------------------------------------------------------------- # quickly draw a 5x5-pixel pattern to the display. it can have transparent # pixels; those with COLOR_NONE will not change the display. This way you can # have "holes" in your images. # this function screen-wraps vertically properly. horizontally it just cheats # and takes advantage of the fact that writing past the end of a row writes to # the next row, but it's one pixel... cmon........... # a0 = top-left x # a1 = top-left y # a2 = pointer to pattern (an array of 25 bytes stored row-by-row) display_blit_5x5_trans: tlti a0, 0 tgei a0, 64 tlti a1, 0 tgei a1, 64 sll t1, a1, DISPLAY_W_SHIFT add t1, t1, DISPLAY_BASE add t1, t1, a0 .macro BLIT_TRANS_PIXEL %off1, %off2 lb t0, %off1(a2) bltz t0, _transparent sb t0, %off2(t1) _transparent: .end_macro .macro NEXT_ROW add t1, t1, 64 blt t1, DISPLAY_END, _nowrap sub t1, t1, DISPLAY_SIZE _nowrap: .end_macro BLIT_TRANS_PIXEL 0, 0 BLIT_TRANS_PIXEL 1, 1 BLIT_TRANS_PIXEL 2, 2 BLIT_TRANS_PIXEL 3, 3 BLIT_TRANS_PIXEL 4, 4 NEXT_ROW BLIT_TRANS_PIXEL 5, 0 BLIT_TRANS_PIXEL 6, 1 BLIT_TRANS_PIXEL 7, 2 BLIT_TRANS_PIXEL 8, 3 BLIT_TRANS_PIXEL 9, 4 NEXT_ROW BLIT_TRANS_PIXEL 10, 0 BLIT_TRANS_PIXEL 11, 1 BLIT_TRANS_PIXEL 12, 2 BLIT_TRANS_PIXEL 13, 3 BLIT_TRANS_PIXEL 14, 4 NEXT_ROW BLIT_TRANS_PIXEL 15, 0 BLIT_TRANS_PIXEL 16, 1 BLIT_TRANS_PIXEL 17, 2 BLIT_TRANS_PIXEL 18, 3 BLIT_TRANS_PIXEL 19, 4 NEXT_ROW BLIT_TRANS_PIXEL 20, 0 BLIT_TRANS_PIXEL 21, 1 BLIT_TRANS_PIXEL 22, 2 BLIT_TRANS_PIXEL 23, 3 BLIT_TRANS_PIXEL 24, 4 jr ra # ------------------------------------------------------------------------------------------------- # quickly draw a 5x5-pixel pattern to the display without transparency. # if it has any COLOR_NONE pixels, the result is undefined. # a0 = top-left x # a1 = top-left y # a2 = pointer to pattern (an array of 25 bytes stored row-by-row) display_blit_5x5: tlti a0, 0 tgei a0, 64 tlti a1, 0 tgei a1, 64 sll a1, a1, DISPLAY_W_SHIFT add a1, a1, DISPLAY_BASE add a1, a1, a0 .macro BLIT_PIXEL %off1, %off2 lb t0, %off1(a2) sb t0, %off2(a1) .end_macro BLIT_PIXEL 0, 0 BLIT_PIXEL 1, 1 BLIT_PIXEL 2, 2 BLIT_PIXEL 3, 3 BLIT_PIXEL 4, 4 BLIT_PIXEL 5, 64 BLIT_PIXEL 6, 65 BLIT_PIXEL 7, 66 BLIT_PIXEL 8, 67 BLIT_PIXEL 9, 68 BLIT_PIXEL 10, 128 BLIT_PIXEL 11, 129 BLIT_PIXEL 12, 130 BLIT_PIXEL 13, 131 BLIT_PIXEL 14, 132 BLIT_PIXEL 15, 192 BLIT_PIXEL 16, 193 BLIT_PIXEL 17, 194 BLIT_PIXEL 18, 195 BLIT_PIXEL 19, 196 BLIT_PIXEL 20, 256 BLIT_PIXEL 21, 257 BLIT_PIXEL 22, 258 BLIT_PIXEL 23, 259 BLIT_PIXEL 24, 260 jr ra # ------------------------------------------------------------------------------------------------- # draw a character pattern to the display. unlike graphical patterns, these are bitmasks: # 1 to draw a pixel and 0 for transparency. the drawn pixels' color is given by a3. # a0 = top-left x # a1 = top-left y # a2 = pointer to pattern (an array of 5 bytes stored row-by-row) # a3 = text color # NOT globl, internal to this file display_show_char: # t1: display pointer sll t1, a1, DISPLAY_W_SHIFT add t1, t1, DISPLAY_BASE add t1, t1, a0 .macro CHAR_PIXEL %mask, %off2 and t0, t2, %mask beqz t0, _transparent sb a3, %off2(t1) _transparent: .end_macro # t2: pixel mask lb t2, 0(a2) CHAR_PIXEL 0x10, 0 CHAR_PIXEL 0x08, 1 CHAR_PIXEL 0x04, 2 CHAR_PIXEL 0x02, 3 CHAR_PIXEL 0x01, 4 lb t2, 1(a2) CHAR_PIXEL 0x10, 64 CHAR_PIXEL 0x08, 65 CHAR_PIXEL 0x04, 66 CHAR_PIXEL 0x02, 67 CHAR_PIXEL 0x01, 68 lb t2, 2(a2) CHAR_PIXEL 0x10, 128 CHAR_PIXEL 0x08, 129 CHAR_PIXEL 0x04, 130 CHAR_PIXEL 0x02, 131 CHAR_PIXEL 0x01, 132 lb t2, 3(a2) CHAR_PIXEL 0x10, 192 CHAR_PIXEL 0x08, 193 CHAR_PIXEL 0x04, 194 CHAR_PIXEL 0x02, 195 CHAR_PIXEL 0x01, 196 lb t2, 4(a2) CHAR_PIXEL 0x10, 256 CHAR_PIXEL 0x08, 257 CHAR_PIXEL 0x04, 258 CHAR_PIXEL 0x02, 259 CHAR_PIXEL 0x01, 260 jr ra