Advertisement
Guest User

Untitled

a guest
Dec 7th, 2019
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 32.67 KB | None | 0 0
  1. .data
  2. # syscall constants
  3. PRINT_STRING = 4
  4. PRINT_CHAR = 11
  5. PRINT_INT = 1
  6.  
  7. # memory-mapped I/O
  8. VELOCITY = 0xffff0010
  9. ANGLE = 0xffff0014
  10. ANGLE_CONTROL = 0xffff0018
  11.  
  12. BOT_X = 0xffff0020
  13. BOT_Y = 0xffff0024
  14. OTHER_BOT_X = 0xffff00a0
  15. OTHER_BOT_Y = 0xffff00a4
  16.  
  17. TIMER = 0xffff001c
  18. ARENA_MAP = 0xffff00dc
  19. SCORES_REQUEST = 0xffff1018
  20.  
  21. POWERUP_MAP = 0xffff00e0
  22. GET_OPPONENT_POWERUP = 0xffff00c4
  23. PICKUP_POWERUP = 0xffff00f4
  24. USE_POWERUP = 0xffff00ec
  25.  
  26. REQUEST_PUZZLE = 0xffff00d0 ## Puzzle
  27. SUBMIT_SOLUTION = 0xffff00d4 ## Puzzle
  28.  
  29. BONK_INT_MASK = 0x1000
  30. BONK_ACK = 0xffff0060
  31.  
  32. TIMER_INT_MASK = 0x8000
  33. TIMER_ACK = 0xffff006c
  34.  
  35. REQUEST_PUZZLE_INT_MASK = 0x800 ## Puzzle
  36. REQUEST_PUZZLE_ACK = 0xffff00d8 ## Puzzle
  37.  
  38. GET_PAINT_BUCKETS = 0xffff00e4
  39. SWITCH_MODE = 0xffff00f0
  40.  
  41. ### Puzzle
  42. GRIDSIZE = 8
  43. puzzle: .half 0:164
  44. heap: .half 0:50000
  45. flag: .word 0
  46. #heap_powerup: .half 0:50000
  47.  
  48. three: .float 3.0
  49. five: .float 5.0
  50. PI: .float 3.141592
  51. F180: .float 180.0
  52.  
  53. .text
  54. main:
  55. # Construct interrupt mask
  56. li $t4, 0
  57. or $t4, $t4, BONK_INT_MASK # request bonk
  58. or $t4, $t4, REQUEST_PUZZLE_INT_MASK # puzzle interrupt bit
  59. or $t4, $t4, 1 # global enable
  60. mtc0 $t4, $12
  61.  
  62. li $s3, 5 # Iterator for number of buckets
  63. bucket_collector:
  64. la $s0, puzzle
  65. sw $s0, REQUEST_PUZZLE ($0)
  66. la $s1, flag
  67. wait_for_puzzle_flag:
  68. lw $t0, 0 ($s1)
  69. beq $t0, $0, wait_for_puzzle_flag
  70.  
  71. sw $0, flag($0)
  72.  
  73. la $a0, puzzle
  74. la $a1, heap
  75. jal copy_board # Copy board to heap
  76.  
  77. la $a0, heap
  78. li $a1, 0
  79. li $a2, 0
  80. la $a3, puzzle
  81. jal solve
  82. sw $a0, SUBMIT_SOLUTION ($0)
  83. addi $s3, $s3, -1 # Decrement
  84. bne $s3, $0, bucket_collector
  85.  
  86.  
  87.  
  88. li $t1, 1
  89. sw $t1, VELOCITY($0) # Initialize Velocity
  90.  
  91. li $t1, 1
  92. sw $t1, SWITCH_MODE($0)
  93. li $s0, 0 # let s0 be true if we have an opponent (true if Part 2)
  94. # add other bot x == -1 check
  95. lhu $t0, OTHER_BOT_X
  96. beq $t0, -1, infinite
  97. li $s0, 1
  98. infinite:
  99. # If on a powerup and we have inventory space, pick it up
  100. la $t0, heap
  101. sw $t0, POWERUP_MAP($0)
  102. add $t1, $t0, 4
  103. lw $t0, 0 ($t0)
  104. li $t2, 0
  105. bge $t2, $t0, powerup_done
  106. lhu $t3, 0 ($t1)
  107. lhu $t4, BOT_X
  108. bne $t3, $t4, increment_powerup_search
  109. add $t1, $t1, 2
  110. lhu $t3, 0 ($t1)
  111. lhu $t4, BOT_Y
  112. beq $t3, $t4, resolved_on_powerup
  113. sub $t1, $t1, 2
  114. increment_powerup_search:
  115. add $t1, $t1, 7 #Offset between Xs
  116. add $t2, $t2, 1
  117. j infinite
  118. resolved_on_powerup:
  119. li $t0, 1
  120. sw $t0, PICKUP_POWERUP
  121. # If picked up a powerup ((and on Part 1 (s0 = 0))?), use it immediately and set s1 to true
  122.  
  123. powerup_done:
  124. # Locate place we should head to - if Part 1, head toward a powerup while we haven't found one yet (s1 = false)
  125. # Jank implementation, go to first power up on map
  126.  
  127. la $t0, heap
  128. sw $t0, POWERUP_MAP($0)
  129. add $t0, $t0, 4
  130. lhu $a0, 0 ($t0)
  131. lhu $a1, 2 ($t0)
  132. jal move_dir
  133. j infinite
  134. jr $ra
  135.  
  136. # move_dir: Sets the heading of the bot towards an input coordinate
  137. ## a0: x pos
  138. ## a1: y pos
  139. move_dir:
  140. lhu $t0, BOT_X
  141. lhu $t1, BOT_Y
  142. sub $a0, $a0, $t0
  143. sub $a1, $a1, $t1
  144. jal sb_arctan
  145. move $a0, $v0
  146. sw $a0, ANGLE($0)
  147. li $a0, 1
  148. sw $a0, ANGLE_CONTROL($0)
  149. li $t1, 10
  150. sw $t1, VELOCITY($0) # Initialize Velocity
  151. jr $ra
  152.  
  153. solve:
  154. sub $sp, $sp, 36
  155. sw $ra, 0($sp)
  156. sw $s0, 4($sp)
  157. sw $s1, 8($sp)
  158. sw $s2, 12($sp)
  159. sw $s3, 16($sp)
  160. sw $s4, 20($sp)
  161. sw $s5, 24($sp)
  162. sw $s6, 28($sp)
  163. sw $s7, 32($sp)
  164. li $s7, GRIDSIZE
  165. move $s0, $a1 # row
  166. move $s1, $a2 # col
  167.  
  168. move $s2, $a0 # current_board
  169. move $s3, $a3 # puzzle
  170.  
  171. bge $s0, $s7, solve_done_check # row >= GRIDSIZE
  172. bge $s1, $s7, solve_done_check # col >= GRIDSIZE
  173. j solve_not_done
  174. solve_done_check:
  175. move $a0, $s2 # current_board
  176. move $a1, $s3 # puzzle
  177. jal board_done
  178.  
  179. beq $v0, $0, solve_done_false # if (done)
  180. move $s7, $v0 # save done
  181. move $a0, $s2 # current_board
  182. move $a1, $s3 # puzzle // same as puzzle->board
  183. jal copy_board
  184.  
  185. move $v0, $s7 # $v0: done
  186.  
  187. j solve_done
  188.  
  189. solve_not_done:
  190.  
  191. move $a0, $s2 # current_board
  192. jal increment_heap
  193. move $s2, $v0 # update current_board
  194.  
  195. li $v0, 0 # changed = false
  196. solve_start_do:
  197.  
  198. move $a0, $s2
  199.  
  200.  
  201. jal rule1 # changed = rule1(current_board);
  202. move $s6, $v0 # done
  203.  
  204. move $a0, $s2 # current_board
  205. jal rule2
  206.  
  207. or $v0, $v0, $s6 # changed |= rule2(current_board);
  208.  
  209. bne $v0, $0, solve_start_do # while (changed)
  210.  
  211. move $a0, $s2 # current_board
  212. move $a1, $s3 # puzzle
  213. jal board_done
  214.  
  215. beq $v0, $0, solve_board_not_done_after_dowhile # if (done)
  216. move $s7, $v0 # save done
  217. move $a0, $s2 # current_board
  218. move $a1, $s3 # puzzle // same as puzzle->board
  219. jal copy_board
  220.  
  221. move $v0, $s7 # $v0: done
  222. j solve_done
  223.  
  224. solve_board_not_done_after_dowhile:
  225.  
  226.  
  227. mul $t0, $s0, $s7 # row*GRIDSIZE
  228. add $t0, $t0, $s1 # row*GRIDSIZE + col
  229. mul $t0, $t0, 2 # sizeof(unsigned short) * (row*GRIDSIZE + col)
  230. add $s4, $t0, $s2 # &current_board[row*GRIDSIZE + col]
  231. lhu $s6, 0($s4) # possibles = current_board[row*GRIDSIZE + col]
  232.  
  233. li $s5, 0 # char number = 0
  234. solve_start_guess:
  235. bge $s5, $s7, solve_start_guess_end # number < GRIDSIZE
  236. li $t0, 1
  237. sll $t1, $t0, $s5 # (1 << number)
  238. and $t0, $t1, $s6 # (1 << number) & possibles
  239. beq $t0, $0, solve_start_guess_else
  240. sh $t1, 0($s4) # current_board[row*GRIDSIZE + col] = 1 << number;
  241.  
  242. move $a0, $s2 # current_board
  243. move $a1, $s0 # next_row = row
  244. sub $t0, $s7, 1 # GRIDSIZE-1
  245. bne $s1, $t0, solve_start_guess_same_row # col < GRIDSIZE // col==GRIDSIZE-1
  246. addi $a1, $a1, 1 # row + 1
  247. solve_start_guess_same_row:
  248. move $a2, $s1 # col
  249. addu $a2, $a2, 1 # col + 1
  250. divu $a2, $s7
  251. mfhi $a2 # (col + 1) % GRIDSIZE
  252. move $a3, $s3 # puzzle
  253. jal solve # solve(current_board, next_row, (col + 1) % GRIDSIZE, puzzle)
  254.  
  255. bne $v0, $0, solve_done_true # if done {return true}
  256. sh $s6, 0($s4) # current_board[row*GRIDSIZE + col] = possibles;
  257. solve_start_guess_else:
  258. addi $s5, $s5, 1
  259. j solve_start_guess
  260.  
  261. solve_done_false:
  262. solve_start_guess_end:
  263. li $v0, 0 # done = false
  264.  
  265. solve_done:
  266. lw $ra, 0($sp)
  267. lw $s0, 4($sp)
  268. lw $s1, 8($sp)
  269. lw $s2, 12($sp)
  270. lw $s3, 16($sp)
  271. lw $s4, 20($sp)
  272. lw $s5, 24($sp)
  273. lw $s6, 28($sp)
  274. lw $s7, 32($sp)
  275. add $sp, $sp, 36
  276. jr $ra
  277.  
  278. solve_done_true:
  279. li $v0, 1
  280. j solve_done
  281.  
  282. # // bool rule1(unsigned short* board) {
  283. #a0: board
  284. rule1:
  285. sub $sp, $sp, 36
  286. sw $ra, 0($sp)
  287. sw $s0, 4($sp)
  288. sw $s1, 8($sp)
  289. sw $s2, 12($sp)
  290. sw $s3, 16($sp)
  291. sw $s4, 20($sp)
  292. sw $s5, 24($sp)
  293. sw $s6, 28($sp)
  294. sw $s7, 32($sp)
  295. li $s0, GRIDSIZE # $s0: GRIDSIZE = 4
  296. move $s1, $a0 # $s1: board
  297. li $s2, 0 # $s2: changed = false
  298. li $s3, 0 # $s3: y = 0
  299. r1_for_y_start:
  300. bge $s3, $s0, r1_for_y_end # for: y < GRIDSIZE
  301. li $s4, 0 # $s4: x = 0
  302. r1_for_x_start:
  303. bge $s4, $s0, r1_for_x_end # for: x < GRIDSIZE
  304. mul $a0, $s3, $s0 # $a0: y*GRIDSIZE
  305. add $a0, $a0, $s4 # $a0: y*GRIDSIZE + x
  306. sll $a0, $a0, 1 # $a0: 2*(y*GRIDSIZE + x)
  307. add $a0, $a0, $s1 # $a0: &board[y*GRIDSIZE+x]
  308. lhu $a0, 0($a0) # $a0: value = board[y*GRIDSIZE+x]
  309. move $s6, $a0 # $s6: value
  310. jal has_single_bit_set
  311. beq $v0, 0, r1_for_x_inc # if(has_single_bit_set(value))
  312. li $s5, 0 # $s5: k = 0
  313. r1_for_k_start:
  314. bge $s5, $s0, r1_for_k_end # for: k < GRIDSIZE
  315. beq $s5, $s4, r1_if_kx_end # if (k != x)
  316. mul $t0, $s3, $s0 # $t0: y*GRIDSIZE
  317. add $t0, $t0, $s5 # $t0: y*GRIDSIZE + k
  318. sll $t0, $t0, 1 # $t0: 2*(y*GRIDSIZE + k)
  319. add $t0, $t0, $s1 # $t0: &board[y*GRIDSIZE+k]
  320. lhu $t1, 0($t0) # $t1: board[y*GRIDSIZE + k]
  321. and $t2, $t1, $s6 # $t2: board[y*GRIDSIZE + k] & value
  322. beq $t2, 0, r1_if_kx_end # if (board[y*GRIDSIZE + k] & value)
  323. not $t3, $s6 # $t3: ~value
  324. and $t1, $t1, $t3 # $t1: board[y*GRIDSIZE + k] & ~value
  325. sh $t1, 0($t0) # board[y*GRIDSIZE + k] &= ~value
  326. li $s2, 1 # changed = true
  327. r1_if_kx_end:
  328. beq $s5, $s3, r1_if_ky_end # if (k != y)
  329. mul $t0, $s5, $s0 # $t0: k*GRIDSIZE
  330. add $t0, $t0, $s4 # $t0: k*GRIDSIZE + x
  331. sll $t0, $t0, 1 # $t0: 2*(k*GRIDSIZE + x)
  332. add $t0, $t0, $s1 # $t0: &board[k*GRIDSIZE+x]
  333. lhu $t1, 0($t0) # $t1: board[k*GRIDSIZE + x]
  334. and $t2, $t1, $s6 # $t2: board[k*GRIDSIZE + x] & value
  335. beq $t2, 0, r1_if_ky_end # if (board[k*GRIDSIZE + x] & value)
  336. not $t3, $s6 # $t3: ~value
  337. and $t1, $t1, $t3 # $t1: board[k*GRIDSIZE + x] & ~value
  338. sh $t1, 0($t0) # board[k*GRIDSIZE + x] &= ~value
  339. li $s2, 1 # changed = true
  340. r1_if_ky_end:
  341. add $s5, $s5, 1 # for: k++
  342. j r1_for_k_start
  343. r1_for_k_end:
  344. r1_for_x_inc:
  345. add $s4, $s4, 1 # for: x++
  346. j r1_for_x_start
  347. r1_for_x_end:
  348. r1_for_y_inc:
  349. add $s3, $s3, 1 # for: y++
  350. j r1_for_y_start
  351. r1_for_y_end:
  352. move $v0, $s2 # return changed
  353. r1_return:
  354. lw $ra, 0($sp)
  355. lw $s0, 4($sp)
  356. lw $s1, 8($sp)
  357. lw $s2, 12($sp)
  358. lw $s3, 16($sp)
  359. lw $s4, 20($sp)
  360. lw $s5, 24($sp)
  361. lw $s6, 28($sp)
  362. lw $s7, 32($sp)
  363. add $sp, $sp, 36
  364. jr $ra
  365.  
  366. # rule2 #####################################################
  367. #
  368. # argument $a0: pointer to current board
  369. rule2:
  370. sub $sp, $sp, 4 #Store ra onto stack and initialize GRIDSIZE
  371. sw $ra, 0($sp)
  372. li $t0, GRIDSIZE # GRIDSIZE
  373. li $t1, 1
  374. sll $t1, $t1, $t0
  375. subu $t1, $t1, 1 #int ALL_VALUES = (1 << GRIDSIZE) - 1;
  376. li $v0, 0 #bool changed = false
  377. li $t2, 0 #i = 0
  378. rule2iloopstart:
  379. bge $t2, $t0, rule2iloopend
  380. li $t3, 0 #j = 0
  381. rule2jloopstart:
  382. bge $t3, $t0, rule2jloopend
  383.  
  384. mul $t4, $t2, $t0
  385. add $t4, $t4, $t3
  386. mul $t4, $t4, 2 #sizeof(unsigned short)*(i*GRIDSIZE + j)
  387. add $t4, $a0, $t4 #address of board[i*GRIDSIZE+j]
  388. lhu $t4, 0($t4) #board[i*GRIDSIZE + j]
  389.  
  390. sub $sp, $sp, 24 # Allocate stack
  391. sw $a0, 0($sp)
  392. sw $t0, 4($sp)
  393. sw $t1, 8($sp)
  394. sw $t2, 12($sp)
  395. sw $t3, 16($sp)
  396. sw $v0, 20($sp) #Store all necessary variables on stack
  397. move $a0, $t4
  398. jal has_single_bit_set
  399. lw $a0, 0($sp)
  400. lw $t0, 4($sp)
  401. lw $t1, 8($sp)
  402. lw $t2, 12($sp)
  403. lw $t3, 16($sp)
  404. move $t4, $v0 # Save $v0 into $t4
  405. lw $v0, 20($sp) # Restore variables
  406. add $sp, $sp, 24 # Deallocate stack
  407.  
  408. bne $t4, $0, rule2continuestatement #if (has_single_bit_set(value)) continue;
  409.  
  410. li $t5, 0 #isum = 0
  411. li $t6, 0 #jsum = 0
  412. li $t4, 0 #k = 0, t2 = i, t3 = j, t4 = k
  413. rule2kloopstart:
  414. bge $t4, $t0, rule2kloopend
  415. beq $t4, $t3, rule2kequalsj
  416. mul $t7, $t2, $t0 #i*GRIDSIZE
  417. add $t7, $t7, $t4 #i*GRIDSIZE+k
  418. mul $t7, $t7, 2
  419. add $t7, $a0, $t7 #&board[i*GRIDSIZE + k]
  420. lhu $t7, 0($t7)
  421. or $t6, $t6, $t7 #jsum |= board[i*GRIDSIZE + k];
  422. rule2kequalsj:
  423. beq $t4, $t2, rule2kequalsi
  424. mul $t7, $t4, $t0 #k*GRIDSIZE
  425. add $t7, $t7, $t3 #k*GRIDSIZE+j
  426. mul $t7, $t7, 2
  427. add $t7, $a0, $t7 #&board[k*GRIDSIZE + j]
  428. lhu $t7, 0($t7)
  429. or $t5, $t5, $t7 #isum |= board[k*GRIDSIZE + j];
  430. rule2kequalsi:
  431. add $t4, $t4, 1
  432. j rule2kloopstart
  433. rule2kloopend:
  434. beq $t1, $t6, rule2allvalequalsjsum
  435. not $t6, $t6 # ~jsum
  436. and $t6, $t1, $t6 #ALL_VALUES & ~jsum
  437. mul $t7, $t0, $t2 # i*GRIDSIZE
  438. add $t7, $t7, $t3 #[i*GRIDSIZE+j]
  439. mul $t7, $t7, 2 #(i*GRIDSIZE+j)*sizeof(unsigned short)
  440. add $t7, $a0, $t7
  441. sh $t6, 0($t7) #board[i*GRIDSIZE + j] = ALL_VALUES & ~jsum;
  442. li $v0, 1
  443. j rule2continuestatement
  444. rule2allvalequalsjsum:
  445. beq $t1, $t5, rule2continuestatement
  446. not $t5, $t5 # ~isum
  447. and $t5, $t1, $t5 #ALL_VALUES & ~isum;
  448. mul $t7, $t0, $t2 # i*GRIDSIZE
  449. add $t7, $t7, $t3 #[i*GRIDSIZE+j]
  450. mul $t7, $t7, 2 #(i*GRIDSIZE+j)*sizeof(unsigned short)
  451. add $t7, $a0, $t7
  452. sh $t5, 0($t7) #board[i*GRIDSIZE + j] = ALL_VALUES & ~isum;
  453. li $v0, 1
  454. rule2continuestatement:
  455. add $t3, $t3, 1
  456. j rule2jloopstart #continue; iterates to next index of jloop
  457. rule2jloopend:
  458. add $t2, $t2, 1
  459. j rule2iloopstart
  460. rule2iloopend:
  461.  
  462. lw $ra, 0($sp)
  463. add $sp, $sp, 4
  464. jr $ra
  465.  
  466.  
  467. # board done ##################################################
  468. #
  469. # argument $a0: pointer to current board to check
  470. # argument $a1: pointer to puzzle struct
  471. board_done:
  472. sub $sp, $sp, 36
  473. sw $ra, 0($sp)
  474. sw $s0, 4($sp)
  475. sw $s1, 8($sp)
  476. sw $s2, 12($sp)
  477. sw $s3, 16($sp)
  478. sw $s4, 20($sp)
  479. sw $s5, 24($sp)
  480. sw $s6, 28($sp)
  481. sw $s7, 32($sp)
  482.  
  483. move $s0, $a0 # s0 = current_board
  484. move $s1, $a1 # s1 = puzzle
  485. li $s2, GRIDSIZE # s2 = GRIDSIZE
  486. li $t0, 1
  487. sll $t0, $t0, $s2 # 1 << GRIDSIZE
  488. sub $s3, $t0, 1 # s3 = ALL_VALUES = (1 << GRIDSIZE) - 1
  489.  
  490. li $s4, 0 # s4 = i = 0
  491. bd_i1_loop_start:
  492. bge $s4, $s2, bd_i1_loop_end # !(i < GRIDSIZE)
  493. bd_i1_loop_body:
  494. li $s5, 0 # s5 = acc = 0
  495. li $s6, 0 # s6 = j = 0
  496. bd_j1_loop_start:
  497. bge $s6, $s2, bd_j1_loop_end # !(j < GRIDSIZE)
  498. bd_j1_loop_body:
  499. mul $t0, $s4, $s2 # i*GRIDSIZE
  500. add $t0, $t0, $s6 # i*GRIDSIZE + j
  501. mul $t0, $t0, 2 # sizeof(unsigned short)*(i*GRIDSIZE + j)
  502. add $t0, $s0, $t0 # &current_board[i*GRIDSIZE + j]
  503. lhu $s7, 0($t0) # s7 = value = current_board[i*GRIDSIZE + j]
  504.  
  505. move $a0, $s7
  506. jal has_single_bit_set
  507. beq $v0, $0, bd_j1_loop_increment # if (!hsbs(value)) continue
  508. xor $s5, $s5, $s7
  509.  
  510. bd_j1_loop_increment:
  511. add $s6, $s6, 1 # ++ j
  512. j bd_j1_loop_start
  513. bd_j1_loop_end:
  514. bne $s5, $s3, bd_return_false # if (acc != ALL_VALUES) return false
  515.  
  516. li $s5, 0 # s5 = acc = 0
  517. li $s6, 0 # s6 = j = 0
  518. bd_j2_loop_start:
  519. bge $s6, $s2, bd_j2_loop_end # !(j < GRIDSIZE)
  520. bd_j2_loop_body:
  521. mul $t0, $s6, $s2 # j*GRIDSIZE
  522. add $t0, $t0, $s4 # j*GRIDSIZE + i
  523. mul $t0, $t0, 2
  524. add $t0, $s0, $t0 # &current_board[j*GRIDSIZE + i]
  525. lhu $s7, 0($t0) # s7 = value = current_board[j*GRIDSIZE + i]
  526.  
  527. move $a0, $s7
  528. jal has_single_bit_set
  529. beq $v0, $0, bd_j2_loop_increment # if (!hsbs(value)) continue
  530. xor $s5, $s5, $s7
  531.  
  532. bd_j2_loop_increment:
  533. add $s6, $s6, 1 # ++ j
  534. j bd_j2_loop_start
  535. bd_j2_loop_end:
  536. bne $s5, $s3, bd_return_false # if (acc != ALL_VALUES) return false
  537.  
  538. bd_i1_loop_increment:
  539. add $s4, $s4, 1 # ++ i
  540. j bd_i1_loop_start
  541. bd_i1_loop_end:
  542. li $s4, 0 # s4 = i = 0
  543. bd_i2_loop_start:
  544. bge $s4, $s2, bd_i2_loop_end # !(i < GRIDSIZE)
  545. bd_i2_loop_body:
  546. li $t0, 2 # sizeof(short)
  547. mul $t0, $t0, $s2
  548. mul $t0, $t0, $s2 # sizeof(unsigned short board[GRIDSIZE*GRIDSIZE])
  549. add $s3, $s1, $t0 # s3 = &(puzzle->constraints)
  550.  
  551. add $t0, $s4, 1 # i+1
  552. add $t1, $s2, 2 # GRIDSIZE+2
  553. mul $t0, $t0, $t1 # (i+1)*(GRIDSIZE+2)
  554. mul $t0, $t0, 2
  555. add $t0, $t0, $s3 # &puzzle->constraints[(i+1)*(GRIDSIZE+2) + 0]
  556. lhu $t9, 0($t0) # t9 = left_constraint = puzzle->constraints[(i+1)*(GRIDSIZE+2) + 0]
  557. li $s5, 0 # s5 = count = 0
  558. li $s6, 0 # s6 = last = 0
  559.  
  560. li $s7, 0 # s7 = j = 0
  561. bd_j3_loop_start:
  562. bge $s7, $s2, bd_j3_loop_end # !(j < GRIDSIZE)
  563. bd_j3_loop_body:
  564. mul $t0, $s4, $s2 # i*GRIDSIZE
  565. add $t0, $t0, $s7 # i*GRIDSIZE + j
  566. mul $t0, $t0, 2
  567. add $t0, $s0, $t0 # &current_board[i*GRIDSIZE + j]
  568. lhu $t0, 0($t0) # t0 = current = current_board[i*GRIDSIZE + j]
  569. ble $t0, $s6, bd_j3_loop_increment # !(current > last)
  570. add $s5, $s5, 1 # count += 1
  571. move $s6, $t0 # last = current
  572. bd_j3_loop_increment:
  573. add $s7, $s7, 1 # ++ j
  574. j bd_j3_loop_start
  575. bd_j3_loop_end:
  576. bne $s5, $t9, bd_return_false # if (count != left_constraint) return false
  577.  
  578. add $t0, $s4, 1 # i+1
  579. add $t1, $s2, 2 # GRIDSIZE+2
  580. mul $t0, $t0, $t1 # (i+1)*(GRIDSIZE+2)
  581. add $t0, $t0, $s2 # (i+1)*(GRIDSIZE+2) + GRIDSIZE
  582. add $t0, $t0, 1 # (i+1)*(GRIDSIZE+2) + GRIDSIZE + 1
  583. mul $t0, $t0, 2
  584. add $t0, $t0, $s3 # &puzzle->constraints[(i+1)*(GRIDSIZE+2) + GRIDSIZE + 1]
  585. lhu $t9, 0($t0) # t9 = right_constraint = puzzle->constraints[(i+1)*(GRIDSIZE+2) + GRIDSIZE + 1]
  586. li $s5, 0 # s5 = count = 0
  587. li $s6, 0 # s6 = last = 0
  588.  
  589. sub $s7, $s2, 1 # s7 = j = GRIDSIZE - 1
  590. bd_j4_loop_start:
  591. blt $s7, $0, bd_j4_loop_end # !(j >= 0)
  592. bd_j4_loop_body:
  593. mul $t0, $s4, $s2 # i*GRIDSIZE
  594. add $t0, $t0, $s7 # i*GRIDSIZE + j
  595. mul $t0, $t0, 2
  596. add $t0, $s0, $t0 # &current_board[i*GRIDSIZE + j]
  597. lhu $t0, 0($t0) # t0 = current = current_board[i*GRIDSIZE + j]
  598. ble $t0, $s6, bd_j4_loop_increment # !(current > last)
  599. add $s5, $s5, 1 # count += 1
  600. move $s6, $t0 # last = current
  601. bd_j4_loop_increment:
  602. sub $s7, $s7, 1 # -- j
  603. j bd_j4_loop_start
  604. bd_j4_loop_end:
  605. bne $s5, $t9, bd_return_false # if (count != right_constraint) return false
  606. add $t0, $s4, 1 # i+1
  607. mul $t0, $t0, 2
  608. add $t0, $t0, $s3 # &puzzle->constraints[i + 1]
  609. lhu $t9, 0($t0) # t9 = top_constraint = puzzle->constraints[i + 1]
  610. li $s5, 0 # s5 = count = 0
  611. li $s6, 0 # s6 = last = 0
  612.  
  613. li $s7, 0 # s7 = j = 0
  614. bd_j5_loop_start:
  615. bge $s7, $s2, bd_j5_loop_end # !(j < GRIDSIZE)
  616. bd_j5_loop_body:
  617. mul $t0, $s7, $s2 # j*GRIDSIZE
  618. add $t0, $t0, $s4 # j*GRIDSIZE + i
  619. mul $t0, $t0, 2
  620. add $t0, $s0, $t0 # &current_board[j*GRIDSIZE + i]
  621. lhu $t0, 0($t0) # t0 = current = current_board[j*GRIDSIZE + i]
  622. ble $t0, $s6, bd_j5_loop_increment # !(current > last)
  623. add $s5, $s5, 1 # count += 1
  624. move $s6, $t0 # last = current
  625. bd_j5_loop_increment:
  626. add $s7, $s7, 1 # ++ j
  627. j bd_j5_loop_start
  628. bd_j5_loop_end:
  629. bne $s5, $t9, bd_return_false # if (count != top_constraint) return false
  630.  
  631. add $t0, $s2, 1 # GRIDSIZE+1
  632. add $t1, $s2, 2 # GRIDSIZE+2
  633. mul $t0, $t0, $t1 # (GRIDSIZE+1)*(GRIDSIZE+2)
  634. add $t0, $t0, $s4 # (GRIDSIZE+1)*(GRIDSIZE+2) + i
  635. add $t0, $t0, 1 # (GRIDSIZE+1)*(GRIDSIZE+2) + i + 1
  636. mul $t0, $t0, 2
  637. add $t0, $t0, $s3 # &puzzle->constraints[(GRIDSIZE+1)*(GRIDSIZE+2) + i + 1]
  638. lhu $t9, 0($t0) # t9 = bottom_constraint = puzzle->constraints[(GRIDSIZE+1)*(GRIDSIZE+2) + i + 1]
  639. li $s5, 0 # s5 = count = 0
  640. li $s6, 0 # s6 = last = 0
  641.  
  642. sub $s7, $s2, 1 # s7 = j = GRIDSIZE - 1
  643. bd_j6_loop_start:
  644. blt $s7, $0, bd_j6_loop_end # !(j >= 0)
  645. bd_j6_loop_body:
  646. mul $t0, $s7, $s2 # j*GRIDSIZE
  647. add $t0, $t0, $s4 # j*GRIDSIZE + i
  648. mul $t0, $t0, 2
  649. add $t0, $s0, $t0 # &current_board[j*GRIDSIZE + i]
  650. lhu $t0, 0($t0) # t0 = current = current_board[j*GRIDSIZE + i]
  651. ble $t0, $s6, bd_j6_loop_increment # !(current > last)
  652. add $s5, $s5, 1 # count += 1
  653. move $s6, $t0 # last = current
  654. bd_j6_loop_increment:
  655. sub $s7, $s7, 1 # -- j
  656. j bd_j6_loop_start
  657. bd_j6_loop_end:
  658. bne $s5, $t9, bd_return_false # if (count != bottom_constraint) return false
  659. bd_i2_loop_increment:
  660. add $s4, $s4, 1
  661. j bd_i2_loop_start
  662. bd_i2_loop_end:
  663. li $v0, 1 # return true
  664. j bd_return
  665. bd_return_false:
  666. li $v0, 0 # return false
  667. bd_return:
  668. lw $ra, 0($sp)
  669. lw $s0, 4($sp)
  670. lw $s1, 8($sp)
  671. lw $s2, 12($sp)
  672. lw $s3, 16($sp)
  673. lw $s4, 20($sp)
  674. lw $s5, 24($sp)
  675. lw $s6, 28($sp)
  676. lw $s7, 32($sp)
  677. add $sp, $sp, 36
  678. jr $ra
  679.  
  680.  
  681. # has single bit set ###########################################
  682. #
  683. # argument $a0: bit mask
  684. has_single_bit_set:
  685. beq $a0, $0, has_single_bit_set_iszero
  686. sub $v0, $a0, 1 # $v0: b-1
  687. and $v0, $a0, $v0 # $v0: b & (b-1)
  688. not $v0, $v0 # $v0: !(b & (b-1))
  689. # if $v0 is zero, return zero
  690. bne $v0, -1, has_single_bit_set_iszero
  691. li $v0, 1
  692. j has_single_bit_set_done
  693. has_single_bit_set_iszero:
  694. li $v0, 0
  695. has_single_bit_set_done:
  696. jr $ra
  697.  
  698.  
  699.  
  700. # increment heap ###############################################
  701. #
  702. # argument $a0: pointer to current board to check
  703. increment_heap:
  704. sub $sp, $sp, 4
  705. sw $ra, 0($sp) # save $ra on stack
  706.  
  707. li $t0, GRIDSIZE
  708. mul $t0, $t0, $t0 # GRIDSIZE * GRIDSIZE
  709. mul $a1, $t0, 2
  710. add $a1, $a0, $a1 # new_board = old_board + GRIDSIZE*GRIDSIZE
  711.  
  712. jal copy_board
  713.  
  714. move $v0, $v0 # // output the output of copy_board
  715. lw $ra, 0($sp)
  716. add $sp, $sp, 4
  717. jr $ra
  718.  
  719.  
  720. # copy board ###################################################
  721. #
  722. # argument $a0: pointer to old board
  723. # argument $a1: pointer to new board
  724. copy_board:
  725. li $t0, GRIDSIZE
  726. mul $t0, $t0, $t0 # GRIDSIZE * GRIDSIZE
  727. li $t1, 0 # i = 0
  728. ih_loop:
  729. bge $t1, $t0, ih_done # i < GRIDSIZE*GRIDSIZE
  730.  
  731. mul $t2, $t1, 2 # i * sizeof(unsigned short)
  732. add $t3, $a0, $t2 # &old_board[i]
  733. lhu $t3, 0($t3) # old_board[i]
  734.  
  735. add $t4, $a1, $t2 # &new_board[i]
  736. sh $t3, 0($t4) # new_board[i] = old_board[i]
  737.  
  738. addi $t1, $t1, 1 # i++
  739. j ih_loop
  740. ih_done:
  741. move $v0, $a1
  742. jr $ra
  743.  
  744. # -----------------------------------------------------------------------
  745. # sb_arctan - computes the arctangent of y / x
  746. # $a0 - x
  747. # $a1 - y
  748. # returns the arctangent
  749. # -----------------------------------------------------------------------
  750. sb_arctan:
  751. li $v0, 0 # angle = 0;
  752. abs $t0, $a0 # get absolute values
  753. abs $t1, $a1
  754. ble $t1, $t0, no_TURN_90
  755. ## if (abs(y) > abs(x)) { rotate 90 degrees }
  756. move $t0, $a1 # int temp = y;
  757. neg $a1, $a0 # y = -x;
  758. move $a0, $t0 # x = temp;
  759. li $v0, 90 # angle = 90;
  760. no_TURN_90:
  761. bgez $a0, pos_x # skip if (x >= 0)
  762. ## if (x < 0)
  763. add $v0, $v0, 180 # angle += 180;
  764. pos_x:
  765. mtc1 $a0, $f0
  766. mtc1 $a1, $f1
  767. cvt.s.w $f0, $f0 # convert from ints to floats
  768. cvt.s.w $f1, $f1
  769. div.s $f0, $f1, $f0 # float v = (float) y / (float) x;
  770. mul.s $f1, $f0, $f0 # v^^2
  771. mul.s $f2, $f1, $f0 # v^^3
  772. l.s $f3, three # load 3.0
  773. div.s $f3, $f2, $f3 # v^^3/3
  774. sub.s $f6, $f0, $f3 # v - v^^3/3
  775. mul.s $f4, $f1, $f2 # v^^5
  776. l.s $f5, five # load 5.0
  777. div.s $f5, $f4, $f5 # v^^5/5
  778. add.s $f6, $f6, $f5 # value = v - v^^3/3 + v^^5/5
  779. l.s $f8, PI # load PI
  780. div.s $f6, $f6, $f8 # value / PI
  781. l.s $f7, F180 # load 180.0
  782. mul.s $f6, $f6, $f7 # 180.0 * value / PI
  783. cvt.w.s $f6, $f6 # convert "delta" back to integer
  784. mfc1 $t0, $f6
  785. add $v0, $v0, $t0 # angle += delta
  786. jr $ra
  787.  
  788. .kdata
  789. chunkIH: .space 32
  790. non_intrpt_str: .asciiz "Non-interrupt exception\n"
  791. unhandled_str: .asciiz "Unhandled interrupt type\n"
  792. .ktext 0x80000180
  793. interrupt_handler:
  794. .set noat
  795. move $k1, $at # Save $at
  796. .set at
  797. la $k0, chunkIH
  798. sw $a0, 0($k0) # Get some free registers
  799. sw $v0, 4($k0) # by storing them to a global variable
  800. sw $t0, 8($k0)
  801. sw $t1, 12($k0)
  802. sw $t2, 16($k0)
  803. sw $t3, 20($k0)
  804. sw $t4, 24($k0)
  805. sw $t5, 28($k0)
  806.  
  807. mfc0 $k0, $13 # Get Cause register
  808. srl $a0, $k0, 2
  809. and $a0, $a0, 0xf # ExcCode field
  810. bne $a0, 0, non_intrpt
  811.  
  812. interrupt_dispatch: # Interrupt:
  813. mfc0 $k0, $13 # Get Cause register, again
  814. beq $k0, 0, done # handled all outstanding interrupts
  815.  
  816. and $a0, $k0, BONK_INT_MASK # is there a bonk interrupt?
  817. bne $a0, 0, bonk_interrupt
  818.  
  819. and $a0, $k0, TIMER_INT_MASK # is there a timer interrupt?
  820. bne $a0, 0, timer_interrupt
  821.  
  822. and $a0, $k0, REQUEST_PUZZLE_INT_MASK
  823. bne $a0, 0, request_puzzle_interrupt
  824.  
  825. li $v0, PRINT_STRING # Unhandled interrupt types
  826. la $a0, unhandled_str
  827. syscall
  828. j done
  829.  
  830. bonk_interrupt:
  831. ### TODO
  832. sw $0, BONK_ACK
  833.  
  834. #Fill in your code here
  835. li $t1, -1
  836. sw $t1, VELOCITY($0)
  837. li $a0, 225
  838. sw $a0, ANGLE($0)
  839. li $a0, 0
  840. sw $a0, ANGLE_CONTROL($0)
  841. li $t1, 1
  842. sw $t1, VELOCITY($0)
  843.  
  844. j interrupt_dispatch # see if other interrupts are waiting
  845.  
  846. request_puzzle_interrupt:
  847. li $t1, 1
  848. sw $t1, REQUEST_PUZZLE_ACK
  849. #Fill in your code here
  850. la $t0, flag
  851. sw $t1, 0 ($t0)
  852. j interrupt_dispatch
  853.  
  854. timer_interrupt:
  855. sw $0, TIMER_ACK
  856. #Fill in your code here
  857. j interrupt_dispatch # see if other interrupts are waiting
  858.  
  859. non_intrpt: # was some non-interrupt
  860. li $v0, PRINT_STRING
  861. la $a0, non_intrpt_str
  862. syscall # print out an error message
  863. # fall through to done
  864.  
  865. done:
  866. la $k0, chunkIH
  867. lw $a0, 0($k0) # Restore saved registers
  868. lw $v0, 4($k0)
  869. lw $t0, 8($k0)
  870. lw $t1, 12($k0)
  871. lw $t2, 16($k0)
  872. lw $t3, 20($k0)
  873. lw $t4, 24($k0)
  874. lw $t5, 28($k0)
  875. .set noat
  876. move $at, $k1 # Restore $at
  877. .set at
  878. eret
  879.  
  880.  
  881. # # This is the only file that will be considered for grading
  882.  
  883. # .data
  884. # # syscall constants
  885. # PRINT_STRING = 4
  886. # PRINT_CHAR = 11
  887. # PRINT_INT = 1
  888.  
  889. # # memory-mapped I/O
  890. # VELOCITY = 0xffff0010
  891. # ANGLE = 0xffff0014
  892. # ANGLE_CONTROL = 0xffff0018
  893.  
  894. # BOT_X = 0xffff0020
  895. # BOT_Y = 0xffff0024
  896.  
  897. # TIMER = 0xffff001c
  898. # ARENA_MAP = 0xffff00dc
  899.  
  900. # POWERUP_MAP = 0xffff00e0
  901. # GET_OPPONENT_POWERUP = 0xffff00c4
  902. # PICKUP_POWERUP = 0xffff00f4
  903. # USE_POWERUP = 0xffff00ec
  904.  
  905.  
  906. # REQUEST_PUZZLE = 0xffff00d0 ## Puzzle
  907. # SUBMIT_SOLUTION = 0xffff00d4 ## Puzzle
  908.  
  909. # BONK_INT_MASK = 0x1000
  910. # BONK_ACK = 0xffff0060
  911.  
  912. # TIMER_INT_MASK = 0x8000
  913. # TIMER_ACK = 0xffff006c
  914.  
  915. # REQUEST_PUZZLE_INT_MASK = 0x800 ## Puzzle
  916. # REQUEST_PUZZLE_ACK = 0xffff00d8 ## Puzzle
  917.  
  918. # GET_PAINT_BUCKETS = 0xffff00e4
  919. # SWITCH_MODE = 0xffff00f0
  920.  
  921. # ### Puzzle
  922. # GRIDSIZE = 8
  923.  
  924. # .text
  925. # main:
  926. # # Construct interrupt mask
  927. # li $t4, 0
  928. # or $t4, $t4, BONK_INT_MASK # request bonk
  929. # or $t4, $t4, REQUEST_PUZZLE_INT_MASK # puzzle interrupt bit
  930. # or $t4, $t4, 1 # global enable
  931. # mtc0 $t4, $12
  932.  
  933. # #Fill in your code here
  934. # jr $ra
  935.  
  936. # .kdata
  937. # chunkIH: .space 32
  938. # non_intrpt_str: .asciiz "Non-interrupt exception\n"
  939. # unhandled_str: .asciiz "Unhandled interrupt type\n"
  940. # .ktext 0x80000180
  941. # interrupt_handler:
  942. # .set noat
  943. # move $k1, $at # Save $at
  944. # .set at
  945. # la $k0, chunkIH
  946. # sw $a0, 0($k0) # Get some free registers
  947. # sw $v0, 4($k0) # by storing them to a global variable
  948. # sw $t0, 8($k0)
  949. # sw $t1, 12($k0)
  950. # sw $t2, 16($k0)
  951. # sw $t3, 20($k0)
  952. # sw $t4, 24($k0)
  953. # sw $t5, 28($k0)
  954.  
  955. # mfc0 $k0, $13 # Get Cause register
  956. # srl $a0, $k0, 2
  957. # and $a0, $a0, 0xf # ExcCode field
  958. # bne $a0, 0, non_intrpt
  959.  
  960.  
  961.  
  962. # interrupt_dispatch: # Interrupt:
  963. # mfc0 $k0, $13 # Get Cause register, again
  964. # beq $k0, 0, done # handled all outstanding interrupts
  965.  
  966. # and $a0, $k0, BONK_INT_MASK # is there a bonk interrupt?
  967. # bne $a0, 0, bonk_interrupt
  968.  
  969. # and $a0, $k0, TIMER_INT_MASK # is there a timer interrupt?
  970. # bne $a0, 0, timer_interrupt
  971.  
  972. # and $a0, $k0, REQUEST_PUZZLE_INT_MASK
  973. # bne $a0, 0, request_puzzle_interrupt
  974.  
  975. # li $v0, PRINT_STRING # Unhandled interrupt types
  976. # la $a0, unhandled_str
  977. # syscall
  978. # j done
  979.  
  980. # bonk_interrupt:
  981. # sw $0, BONK_ACK
  982. # #Fill in your code here
  983. # j interrupt_dispatch # see if other interrupts are waiting
  984.  
  985. # request_puzzle_interrupt:
  986. # sw $0, REQUEST_PUZZLE_ACK
  987. # #Fill in your code here
  988. # j interrupt_dispatch
  989.  
  990. # timer_interrupt:
  991. # sw $0, TIMER_ACK
  992. # #Fill in your code here
  993. # j interrupt_dispatch # see if other interrupts are waiting
  994.  
  995. # non_intrpt: # was some non-interrupt
  996. # li $v0, PRINT_STRING
  997. # la $a0, non_intrpt_str
  998. # syscall # print out an error message
  999. # # fall through to done
  1000.  
  1001. # done:
  1002. # la $k0, chunkIH
  1003. # lw $a0, 0($k0) # Restore saved registers
  1004. # lw $v0, 4($k0)
  1005. # lw $t0, 8($k0)
  1006. # lw $t1, 12($k0)
  1007. # lw $t2, 16($k0)
  1008. # lw $t3, 20($k0)
  1009. # lw $t4, 24($k0)
  1010. # lw $t5, 28($k0)
  1011. # .set noat
  1012. # move $at, $k1 # Restore $at
  1013. # .set at
  1014. # eret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement