;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Requires: cars.bmp, cars.blf ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; #define _x_size 128 #define _y_size 128 #define BITMAP_ADDR 16 ; define the memory address of ; the stored bitmap portion #define PEL_NUM 15 ; number of pixel-1 #define THRESHOLD 100 ; threshold value s_call THRESHOLD_NODES s_call DISPLAY_ARRAY ; s_call DILATE ; ; s_call ERODE ; ; s_call DISPLAY_ARRAY ; s_end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; This subroutine loads in a gray-scale image and converts it to a ;; binary image. 16 pixels per processor node are sampled. If all ;; 16 pixels have a gray scale value below THRESHOLD, then the ;; node's threshold flag is cleared (0), otherwise it is set (to 1). ;; The threshold flag is stored in R2 (output of the subroutine). ;; ;; SR0: Loop counter ;; R0: Temporary register holding 16-bit immediate value ;; R2: Threshold flag ;; R3: Temporary value ;; R5: Threshold level ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; THRESHOLD_NODES loadi THRESHOLD ; R0 <= THRESHOLD addi R5, R0, 0 ; R5 <= THRESHOLD s_loadi PEL_NUM ; SR0 <= PEL_NUM loadi 1 ; R0 <= 1 addi R2, R0, 0 ; Defaultly set threshold flag. sample ; Sample the image. ;; For SR0 = PEL_NUM ... 0, do the following: L1 ploads R3, SR0 ; R3 <= Pixel(SR0) sub R3, R3, R5 ; Compute THRESHOLD predicate: ; R3 <= Pixel_i - THRESHOLD. sgei R3 0x01 ; Put all nodes above THRESHOLD to sleep. s_subi SR0, SR0, 1 ; Decrement SR0. s_bge SR0, L1 ; If SR0 >= 0 then goto L1. sub R2, R2, R2 ; The only nodes awake are those having ; all 16 pixels below THRESHOLD, so clear ; their threshold flag. wakeupi 0x01 ; Wake all nodes up. s_return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; This subroutine writes a binary image out to memory and ;; then uses OS_BITMAP_OUT to display it. It assumes a ;; threshold flag has been set for each node and stored in ;; R2 (input). ;; ;; R0: Temporary register holding 16-bit immediate value ;; R2: Threshold flag ;; R4: Node output level ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DISPLAY_ARRAY sub R4, R4, R4 ; Initialize output level to 0 (black). loadi 255 ; R0 <= 255 seqi R2, 0x01 ; If node's threshold flag is set, addi R4, R0, 0 ; then set output level to 255 (white) wakeupi 0x01 ; Wake all nodes up. s_call DISPLAY_OUTPUT_LEVEL s_return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; This subroutine displays a gray scale image constructed ;; based on the processor node's cluster IDs (CIDS), which ;; it assumes are stored in R15. It assumes regions have ;; been identified and all processor nodes in the same ;; region have the same CID. It displays a gray-scale ;; image in which each region has a different shade of gray. ;; ;; R0: An 8-bit mask ;; R4: Node output level ;; R15: Cluster ID (CID) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DISPLAY_REGIONS ;; Scale CID to be within 0 ... 255 and put it in R4. addi R4, R15, 1 ; Put R4 into the range 0 ... 2^16. loadi 255 ; R0 <= 255. and R4, R0, R4 ; Mask off upper 8 bits of CID. s_call DISPLAY_OUTPUT_LEVEL s_return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; This subroutine displays an image based on the node ;; output level stored in R4 (input). ;; ;; SR0: Loop counter ;; R1: Memory location pointer ;; R3: Temporary value ;; R4: Node output level ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DISPLAY_OUTPUT_LEVEL loadi PEL_NUM ; R0 <= PEL_NUM addi R3, R0, 0 ; R3 <= PEL_NUM s_loadi PEL_NUM ; SR0 <= PEL_NUM addi R1, R3, BITMAP_ADDR ; R1 <= 31. ; The pixels are scanned from 15 to 1. ;; For SR0 = PEL_NUM ... 0 (and R1 from 31 ... 16), do: L2 store R1, R4 ; *(R1) <= R4 ; Store the output level in memory ; at location (R1). subi R1, R1, 1 ; Decrement R1. s_subi SR0, SR0, 1 ; Decrement SRO. s_bge SR0, L2 ; if SR0 >= 0 then goto L2. OS_BITMAP_OUT BITMAP_ADDR ; output the bitmap s_return ; end of code to students ;; This will dilate each node based on its threshold flag. ;; It uses R10, R11, R12, and R13 as temporary registers. DILATE sub R10, R10, R10 ; initialize R10 to 0 sub R11, R11, R11 ; initialize R11 to 0 sub R12, R12, R12 ; initialize R12 to 0 sub R13, R13, R13 ; initialize R13 to 0 xfer R10, R2, 0 ; NORTH neighbor's R10 gets node's threshold flag xfer R11, R2, 1 ; EAST neighbor's R11 gets node's threshold flag xfer R12, R2, 2 ; WEST neighbor's R12 gets node's threshold flag xfer R13, R2, 3 ; SOUTH neighbor's R13 gets node's threshold flag or R10, R10, R11 or R10, R10, R12 or R10, R10, R13 or R2, R10, R2 s_return ;; This will erode each node based on its threshold flag. ;; It uses R10, R11, R12, and R13 as temporary registers. ERODE sub R10, R10, R10 ; initialize R10... R13 to 1 addi R10, R10, 1 addi R11, R10, 0 addi R12, R10, 0 addi R13, R10, 0 xfer R10, R2, 0 ; NORTH neighbor's R10 gets node's threshold flag xfer R11, R2, 1 ; EAST neighbor's R11 gets node's threshold flag xfer R12, R2, 2 ; WEST neighbor's R12 gets node's threshold flag xfer R13, R2, 3 ; SOUTH neighbor's R13 gets node's threshold flag and R10, R10, R11 and R10, R10, R12 and R10, R10, R13 and R2, R10, R2 s_return