# # concatenate this file with the file containing the bitblt function # and use the result as input to xspim, e.g., run the commands # # % cat driver.asm bitblt.asm > all.asm # % xspim -file all.asm # # to debug your bitblt.asm code. to run it on test input, make sure that # the WIDTH, HEIGHT, WIDTHPLUS2, etc constants have values that match the # input file, then do # # % cat driver.asm bitblt.asm > all.asm # % spim -file all.asm < test_data.txt # # nb: if you modify bitblt.asm, you have to re-create all.spm before xspim # will see the modifications. # # # because bitblt will appear at the end of all.asm after the contents of # this file, the constants defined here may be used there. you should # be careful to avoid name conflicts. # SYS_PRINT_INT=1 SYS_PRINT_FLOAT=2 SYS_PRINT_DOUBLE=3 SYS_PRINT_STR=4 SYS_READ_INT=5 SYS_READ_FLOAT=6 SYS_READ_DOUBLE=7 SYS_READ_STR=8 SYS_SBRK=9 SYS_EXIT=10 # # the following symbolic constants will be changed for timing on a # full-sized screen, i.e., # # WIDTH=800 # WIDTHPLUS2=802 # HEIGHT=600 # WORDS_PER_ROW=25 # (800+31)/32 # # if you need other symbolic constants than these the values of which # depends on WIDTH and HEIGHT, put them in a separate file consts.asm, # and create all.asm by # # % cat consts.asm driver.asm bitblt.asm > all.asm # WIDTH=80 WIDTHPLUS2=82 HEIGHT=60 WORDS_PER_ROW=3 # (80+31)/32 VSCROLL_AMOUNT=6 HEIGHT_MINUS_SCROLL=54 # (HEIGHT-VSCROLL_AMOUNT) # # independent constants # PIXELS_PER_WORD=32 LOG_PPW=5 # 2^{LOG_PPW} = PIXELS_PER_WORD PPW_MASK=0x1f # PIXELS_PER_WORD-1 # offsets from the frame pointer (which has the original stack pointer # value) # arg0 a0 # arg1 a1 # arg2 a2 # arg3 a3 ARG4_OFF=4 ARG5_OFF=8 ARG6_OFF=12 ARG7_OFF=16 # # int get_bit_value(unsigned int *gbuffer, # unsigned int row, # unsigned int col) # # LEAF # get_bit_value: mul $t0,$a1,WORDS_PER_ROW sll $t0,$t0,2 addu $t0,$t0,$a0 # row_start srl $t1,$a2,LOG_PPW sll $t1,$t1,2 addu $t1,$t0,$t1 # row_start + col_word_offset lw $t1,0($t1) # w and $t0,$a2,PPW_MASK# col_bit_offset srl $t1,$t1,$t0 and $v0,$t1,1 jr $ra # # void set_bit_value(unsigned int *gbuffer, # unsigned int row, # unsigned int col, # int val) # # LEAF set_bit_value: mul $t0,$a1,WORDS_PER_ROW sll $t0,$t0,2 addu $t0,$t0,$a0 # row_start srl $t1,$a2,LOG_PPW sll $t1,$t1,2 addu $t1,$t0,$t1 # wptr lw $t2,0($t1) # w andi $t0,$a2,PPW_MASK# col_bit_offset li $t3,1 sll $t0,$t3,$t0 # mask not $t3,$t0 and $t2,$t2,$t3 # w = w & ~mask beq $a3,$zero,sbv_clear or $t2,$t2,$t0 # w = w | mask sbv_clear: sw $t2,0($t1) # *wptr = w jr $ra .data .align 2 prev_page: .space 720 # 4 * 60 * 3 shown_page: .space 720 # 4 * 60 * 3 next_page: .space 720 # 4 * 60 * 3 .text # WIDTH+2 = 82 -> 84 # plus $s0/r, $s1/c, $gbuffer, ra, fp. RP_FSZ=104 RP_FP=-100 RP_RA=-96 RP_GBUFFER=-92 RP_R=-88 RP_C=-84 RP_LINEBUFF=-80 read_page: subu $sp,$sp,RP_FSZ sw $fp,4($sp) addu $fp,$sp,RP_FSZ sw $ra,RP_RA($fp) sw $s0,RP_R($fp) sw $s1,RP_C($fp) sw $a0,RP_GBUFFER($fp) li $s0,0 b rp_rtest rp_rloop: la $a0,RP_LINEBUFF($fp) li $a1,WIDTHPLUS2 li $v0,SYS_READ_STR syscall li $s1,0 b rp_ctest rp_cloop: addu $t1,$s1,$fp lb $t0,RP_LINEBUFF($t1) bne $t0,' ',rp_not_blank lw $a0,RP_GBUFFER($fp) move $a1,$s0 move $a2,$s1 li $a3,0 jal set_bit_value b rp_cloop_cont rp_not_blank: lw $a0,RP_GBUFFER($fp) move $a1,$s0 move $a2,$s1 li $a3,1 jal set_bit_value rp_cloop_cont: addu $s1,$s1,1 rp_ctest: blt $s1,WIDTH,rp_cloop addu $s0,$s0,1 rp_rtest: blt $s0,HEIGHT,rp_rloop lw $s1,RP_C($fp) lw $s0,RP_R($fp) lw $ra,RP_RA($fp) lw $fp,RP_FP($fp) addu $sp,$sp,RP_FSZ jr $ra # # void print_page(unsigned int *gbuffer) # .data pp_not_set_str: .asciiz " " pp_is_set_str: .asciiz "*" pp_newline_str: .asciiz "\n" PP_FSZ=20 PP_FP=-16 PP_RA=-12 PP_S2=-8 PP_S1=-4 PP_S0=0 .text print_page: subu $sp,$sp,PP_FSZ sw $fp,4($sp) addu $fp,$sp,PP_FSZ sw $ra,PP_RA($fp) sw $s0,PP_S0($fp) sw $s1,PP_S1($fp) sw $s2,PP_S2($fp) move $s0,$a0 # gbuffer li $s1,0 # r b pp_rtest pp_rloop: li $s2,0 # c b pp_ctest pp_cloop: move $a0,$s0 move $a1,$s1 move $a2,$s2 jal get_bit_value bnez $v0,pp_bit_is_set la $a0,pp_not_set_str li $v0,SYS_PRINT_STR syscall b pp_cloop_cont pp_bit_is_set: la $a0,pp_is_set_str li $v0,SYS_PRINT_STR syscall pp_cloop_cont: addu $s2,$s2,1 # c++ pp_ctest: blt $s2,WIDTH,pp_cloop la $a0,pp_newline_str li $v0,SYS_PRINT_STR syscall addu $s1,$s1,1 # r++ pp_rtest: blt $s1,HEIGHT,pp_rloop lw $s0,PP_S0($fp) lw $s1,PP_S1($fp) lw $s2,PP_S2($fp) lw $ra,PP_RA($fp) lw $fp,PP_FP($fp) addu $sp,$sp,PP_FSZ jr $ra # # void render_page(unsigned int *gbuffer) # render_page: jal $ra .data main_str1: .asciiz "Before:\n" main_str2: .asciiz "prev_page:\n" main_str3: .asciiz "shown_page:\n" main_str4: .asciiz "next_page:\n" main_str5: .asciiz "after scroll:\n" main_str6: .asciiz "after move:\n" main_str7: .asciiz "after flip:\n" .text MAIN_FSZ=4 main: subu $sp,$sp,MAIN_FSZ sw $ra,4($sp) la $a0,prev_page jal read_page la $a0,shown_page jal read_page la $a0,next_page jal read_page la $a0,main_str1 # before li $v0,SYS_PRINT_STR syscall la $a0,main_str2 # prev_page li $v0,SYS_PRINT_STR syscall la $a0,prev_page jal print_page la $a0,main_str3 # shown_page li $v0,SYS_PRINT_STR syscall la $a0,shown_page jal print_page la $a0,main_str4 # next_page li $v0,SYS_PRINT_STR syscall la $a0,next_page jal print_page subu $sp,$sp,16 li $t0,WIDTH li $t1,HEIGHT_MINUS_SCROLL li $t3,VSCROLL_AMOUNT sw $t0,ARG7_OFF($sp) sw $t1,ARG6_OFF($sp) sw $zero,ARG5_OFF($sp) sw $t3,ARG4_OFF($sp) la $a3,shown_page li $a2,0 li $a1,0 move $a0,$a3 jal bitblt # addu $sp,$sp,16 # subu $sp,$sp,16 li $t0,WIDTH li $t1,VSCROLL_AMOUNT sw $t0,ARG7_OFF($sp) sw $t1,ARG6_OFF($sp) sw $zero,ARG5_OFF($sp) sw $zero,ARG4_OFF($sp) la $a3,next_page li $a2,0 li $a1,HEIGHT_MINUS_SCROLL la $a0,shown_page jal bitblt addu $sp,$sp,16 la $a0,main_str5 # after scroll li $v0,SYS_PRINT_STR syscall la $a0,main_str2 # prev_page li $v0,SYS_PRINT_STR syscall la $a0,prev_page jal print_page la $a0,main_str3 # shown_page li $v0,SYS_PRINT_STR syscall la $a0,shown_page jal print_page la $a0,main_str4 # next_page li $v0,SYS_PRINT_STR syscall la $a0,next_page jal print_page subu $sp,$sp,16 li $t0,30 li $t1,25 sw $t0,ARG7_OFF($sp) sw $t0,ARG6_OFF($sp) sw $t1,ARG5_OFF($sp) sw $t1,ARG4_OFF($sp) la $a3,shown_page li $a2,10 li $a1,10 la $a0,shown_page jal bitblt addu $sp,$sp,16 la $a0,main_str6 # after move li $v0,SYS_PRINT_STR syscall la $a0,main_str2 # prev_page li $v0,SYS_PRINT_STR syscall la $a0,prev_page jal print_page la $a0,main_str3 # shown_page li $v0,SYS_PRINT_STR syscall la $a0,shown_page jal print_page la $a0,main_str4 # next_page li $v0,SYS_PRINT_STR syscall la $a0,next_page jal print_page subu $sp,$sp,16 li $t0,WIDTH li $t1,HEIGHT sw $t0,ARG7_OFF($sp) sw $t1,ARG6_OFF($sp) sw $zero,ARG5_OFF($sp) sw $zero,ARG4_OFF($sp) la $a3,shown_page li $a2,0 li $a1,0 la $a0,prev_page jal bitblt # addu $sp,$sp,16 # subu $sp,$sp,16 li $t0,WIDTH li $t1,HEIGHT sw $t0,ARG7_OFF($sp) sw $t1,ARG6_OFF($sp) sw $zero,ARG5_OFF($sp) sw $zero,ARG4_OFF($sp) la $a3,next_page li $a2,0 li $a1,0 la $a0,shown_page jal bitblt addu $sp,$sp,16 la $a0,next_page jal render_page la $a0,main_str7 # after flip li $v0,SYS_PRINT_STR syscall la $a0,main_str2 # prev_page li $v0,SYS_PRINT_STR syscall la $a0,prev_page jal print_page la $a0,main_str3 # shown_page li $v0,SYS_PRINT_STR syscall la $a0,shown_page jal print_page la $a0,main_str4 # next_page li $v0,SYS_PRINT_STR syscall la $a0,next_page jal print_page li $v0,0 lw $ra,4($sp) addu $sp,$sp,MAIN_FSZ jr $ra