entry #1
written by olus2000
submitted at
3 likes
guesses
- Olivia (by Tæmt modʒiɹæ)
- Palaiologos (by Olivia)
- Palaiologos (by razetime)
- Palaiologos (by Edgex42)
- Palaiologos (by LyricLy)
- olus2000 (by Palaiologos)
comments 0
line_draw.asm magic text fragment for file(1) cmd, 1st line "#-------------------------------------------------------------------------------", 2nd line "#author: SoundOfSpouting#6980 (UID: 151149148639330304)"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 | #------------------------------------------------------------------------------- #author: SoundOfSpouting#6980 (UID: 151149148639330304) #date : 2022.08.12 #description : example RISC V program for drawing a line on a BMP file #------------------------------------------------------------------------------- # Recommended use with RARS simulator # Assumes a simple RGB 24bpp .bmp image # Coordinates originate from bottom left # for purpose of this example I define structure which will contain important # bitmap data for image read from the bmp file. Its C definition could be: # struct { # char* filename; // pointer to file name # unsigned char* hdrData; // pointer to BMP header buffer # unsigned char* imgData; // pointer to the first picture pixel in memory # int width, height; // width and height in pixels # int linebytes; // size of a line (in bytes) # } imgInfo; .eqv ImgInfo_fname 0 .eqv ImgInfo_hdrdat 4 .eqv ImgInfo_imdat 8 .eqv ImgInfo_width 12 .eqv ImgInfo_height 16 .eqv ImgInfo_lbytes 20 .eqv MAX_IMG_SIZE 230400 # 320 x 240 x 3 (pixels) # more information about bmp format: https://en.wikipedia.org/wiki/BMP_file_format .eqv BMPHeader_Size 54 .eqv BMPHeader_width 18 .eqv BMPHeader_height 22 # line is a structure which contains coordinaes of the line's ends and its color: # struct { # int x1, y1, x2, y2; # char r, g, b; # } line .eqv Line_x1 0 .eqv Line_y1 4 .eqv Line_x2 8 .eqv Line_y2 12 .eqv Line_0rgb 16 .eqv Line_b 16 .eqv Line_g 17 .eqv Line_r 18 .eqv Line_0 19 .eqv system_OpenFile 1024 .eqv system_ReadFile 63 .eqv system_WriteFile 64 .eqv system_CloseFile 57 .eqv system_Exit 10 .eqv system_PrintChar 11 .eqv system_ReadInt 5 .eqv system_ReadStr 8 .eqv system_PrintStr 4 .macro exit li a7, system_Exit ecall .end_macro .macro print (%string_addr) la a0, %string_addr li a7, system_PrintStr ecall .end_macro .macro input (%buff_addr, %buff_size) la a0, %buff_addr li a1, %buff_size li a7, system_ReadStr ecall li a3, 10 find_endl: lb a2, (a0) beq a2, a3, found_endl addi a0, a0, 1 addi a1, a1, -1 bgt a1, zero, find_endl j end_input found_endl: sb zero, (a0) end_input: .end_macro .macro int_input li a7, system_ReadInt ecall .end_macro .macro error (%message_addr) print %message_addr exit .end_macro .data imgInfo: .space 24 # image descriptor .align 2 dummy: .space 2 bmpHeader: .space BMPHeader_Size .align 2 imgData: .space MAX_IMG_SIZE .align 2 line: .space 20 # One 0 byte to make loading 0RGB values possible ifname: .space 64 ofname: .space 64 iprompt: .asciz "Input file > " oprompt: .asciz "Output file > " lineprompt: .asciz "coordinates of line in separate lines (x1, y1, x2, y2):\n" colorprompt: .asciz "color of the line in separate lines (r, g, b):\n" openError: .asciz "Error reading file\n" .text main: # Getting the input file name print iprompt input ifname 64 # filling the image descriptor la a0, imgInfo la t0, ifname sw t0, ImgInfo_fname(a0) la t0, bmpHeader sw t0, ImgInfo_hdrdat(a0) la t0, imgData sw t0, ImgInfo_imdat(a0) jal read_bmp beqz a0, read_success print openError j main read_success: # Get the output file name and line print oprompt input ofname 64 la a1, line print lineprompt int_input sw a0, Line_x1(a1) int_input sw a0, Line_y1(a1) int_input sw a0, Line_x2(a1) int_input sw a0, Line_y2(a1) print colorprompt sb zero, Line_0(a1) int_input sb a0, Line_r(a1) int_input sb a0, Line_g(a1) int_input sb a0, Line_b(a1) la a0, imgInfo la a1, line jal draw_line la a0, imgInfo la t0, ofname sw t0, ImgInfo_fname(a0) jal save_bmp exit #============================================================================ # read_bmp: # reads the content of a bmp file into memory # arguments: # a0 - address of image descriptor structure # input filename pointer, header and image buffers should be set # return value: # a0 - 0 if successful, error code in other cases read_bmp: mv t0, a0 # preserve imgInfo structure pointer #open file li a7, system_OpenFile lw a0, ImgInfo_fname(t0) #file name li a1, 0 #flags: 0-read file ecall blt a0, zero, rb_error mv t1, a0 # save file handle for the future #read header li a7, system_ReadFile lw a1, ImgInfo_hdrdat(t0) li a2, BMPHeader_Size ecall #extract image information from header lw a0, BMPHeader_width(a1) sw a0, ImgInfo_width(t0) # compute line size in bytes - bmp line has to be multiple of 4 add a2, a0, a0 add a0, a2, a0 # pixelbytes = width * 3 addi a0, a0, 3 srai a0, a0, 2 slli a0, a0, 2 # linebytes = ((pixelbytes + 3) / 4 ) * 4 sw a0, ImgInfo_lbytes(t0) lw a0, BMPHeader_height(a1) sw a0, ImgInfo_height(t0) #read image data li a7, system_ReadFile mv a0, t1 lw a1, ImgInfo_imdat(t0) li a2, MAX_IMG_SIZE ecall #close file li a7, system_CloseFile mv a0, t1 ecall mv a0, zero jr ra rb_error: li a0, 1 # error opening file jr ra # ============================================================================ # save_bmp - saves bmp file stored in memory to a file # arguments: # a0 - address of ImgInfo structure containing description of the image` # return value: # a0 - zero if successful, error code in other cases save_bmp: mv t0, a0 # preserve imgInfo structure pointer #open file li a7, system_OpenFile lw a0, ImgInfo_fname(t0) #file name li a1, 1 #flags: 1-write file ecall blt a0, zero, wb_error mv t1, a0 # save file handle for the future #write header li a7, system_WriteFile lw a1, ImgInfo_hdrdat(t0) li a2, BMPHeader_Size ecall #write image data li a7, system_WriteFile mv a0, t1 # compute image size (linebytes * height) lw a2, ImgInfo_lbytes(t0) lw a1, ImgInfo_height(t0) mul a2, a2, a1 lw a1, ImgInfo_imdat(t0) ecall #close file li a7, system_CloseFile mv a0, t1 ecall mv a0, zero jr ra wb_error: li a0, 2 # error writing file jr ra # ============================================================================ # set_pixel - sets the color of specified pixel #arguments: # a0 - address of ImgInfo image descriptor # a1 - x coordinate # a2 - y coordinate - (0,0) - bottom left corner # a3 - 0RGB - pixel color #return value: none #remarks - a0, a1, a2 values are left unchanged set_pixel: lw t1, ImgInfo_lbytes(a0) mul t1, t1, a2 # t1 = y * linebytes add t0, a1, a1 add t0, t0, a1 # t0 = x * 3 add t0, t0, t1 # t0 is offset of the pixel lw t1, ImgInfo_imdat(a0) # address of image data add t0, t0, t1 # t0 is address of the pixel #set new color sb a3,(t0) #store B srli a3, a3, 8 sb a3, 1(t0) #store G srli a3, a3, 8 sb a3, 2(t0) #store R jr ra # ============================================================================ .macro swap (%line_reg, %t1, %t2) lw %t1, Line_x1(%line_reg) lw %t2, Line_x2(%line_reg) sw %t1, Line_x2(%line_reg) sw %t2, Line_x1(%line_reg) lw %t1, Line_y1(%line_reg) lw %t2, Line_y2(%line_reg) sw %t1, Line_y2(%line_reg) sw %t2, Line_y1(%line_reg) .end_macro # ============================================================================ # draw_line - draws a line of a given color between two points # arguments: # a0 - address of ImgInfo image descriptor # a1 - addres of Line descriptor # return values: # none # remarks: # assumes that line coords are within the image # uses the fact that set_pixel only changes t0 and t1 draw_line: addi sp, sp, -8 sw ra, 4(sp) sw s1, 0(sp) mv s1, a1 lw t4, Line_x1(s1) lw t2, Line_x2(s1) sub t4, t2, t4 lw t5, Line_y1(s1) lw t2, Line_y2(s1) sub t5, t2, t5 sltz t2, t4 add t2, t2, t2 addi t2, t2, -1 sub t4, t4, t2 # Actually aim for one pixel off diagonally mul t2, t2, t4 sltz t3, t5 add t3, t3, t3 addi t3, t3, -1 sub t5, t5, t3 # This will make the line have nicer shape mul t3, t3, t5 bgt t2, t3, along_y along_x: bgtz t4, along_x_after_swap swap s1, t0, t1 sub t4, zero, t4 sub t5, zero, t5 along_x_after_swap: lw a1, Line_x1(s1) lw t2, Line_y1(s1) li t3, 0 along_x_loop: mul a2, t5, t3 div a2, a2, t4 add a2, a2, t2 lw a3, Line_0rgb(s1) jal set_pixel addi a1, a1, 1 addi t3, t3, 1 blt t3, t4, along_x_loop j line_ret along_y: bgtz t5, along_y_after_swap swap s1, t2, t3 sub t4, zero, t4 sub t5, zero, t5 along_y_after_swap: lw t2, Line_x1(s1) lw a2, Line_y1(s1) li t3, 0 along_y_loop: mul a1, t4, t3 div a1, a1, t5 add a1, a1, t2 lw a3, Line_0rgb(s1) jal set_pixel addi a2, a2, 1 addi t3, t3, 1 blt t3, t5, along_y_loop line_ret: lw s1, 0(sp) lw ra, 4(sp) addi sp, sp, 8 jr ra |
post a comment