Image on Canvas

Instructions

In this activity, you must write a program in RISC-V assembly language that reads an image in PGM format from a file and shows it on screen using the canvas peripheral.

Input

Your program must read a file called "image.pgm" that will be in the same directory as the executable file. The syscall open can be used to open the file (an example is shown at the Notes and Tips section)

Some examples of PGM images can be found on this site: PGMB Files - Binary Portable Gray Map Graphics Files. Smaller examples are also availabe here.

Output

Your program must show the image on the screen using syscalls to the Canvas peripheral. The Canvas must be adjusted to have the image size. The available syscalls are:

syscallInputDescription
setPixela0:pixel's x coordinate
a1: pixel's y coordinate
a2: concatenated pixel's colors: R|G|B|A
  • a2[31..24]: Red
  • a2[23..16]: Green
  • a2[15..8]: Blue
  • a2[7..0]: Alpha
a7: 2200 (syscall number)
Defines the color of a given canvas' pixel. For gray scale, use the same values for the colors (R = G = B) and alpha = 255.
setCanvasSizea0:canvas width (value between 0 and 512)
a1: canvas height (value between 0 and 512)
a7: 2201 (syscall number)
Resets and defines canvas' size.
setScalinga0: horizontal scaling
a1: vertical scaling
a7: 2202 (syscall number)
Updates canvas' scaling. Must be used only after all the canvas' pixels are set.

Notes and Tips

  • To test on the simulator, you have to load your program (.s file) and the image file (name "image.pgm") simultaneously.
  • When new files are loaded to the simulator, older ones are erased, so you have to load the program and image files together every time.
  • To use the Canvas, you must enable it on the simulator. To do so, go to the tab “Hardware” -> “External Devices” table -> “+” Icon on the Canvas row. A new tab will appear where the canvas can be seen.
  • This exercise uses multiple syscall numbers. These values will always be stored on the register a7, and the ecall function has a different behavior for each value. To check the syscall for a specific functionality, the simulator table can be checked (note that the syscalls related to external devices, like Canvas, are not shown in this table if the device is not enabled).
  • You will not receive images larger than 512x512 (that typically takes up 262159 bytes).
  • You can either read the image byte per byte, or use a buffer large enough to store the whole image file content and perform a single read syscall.
  • In all images, Maxval will be 255.
  • The canvas is indexed starting on 0.
  • You need to resize the canvas (setCanvasSize syscall) according to the file header.
  • The setScaling syscall can be used to scale the resulting image, in order to inspect the resulting image. However, it must not be used when running with the assistant.
  • You can test your code using the simulator's assistant from this link.

setPixel example:

    li a0, 100 # x coordinate = 100
    li a1, 200 # y coordinate = 200
    li a2, 0xFFFFFFFF # white pixel
    li a7, 2200 # syscall setPixel (2200)
    ecall

open example: The open syscall returns the file descriptor (fd) for the file on a0. This file descriptor must be used on the read syscall to indicate the file from which the operating system must read from to get the contents of the file.

    la a0, input_file    # address for the file path
    li a1, 0             # flags (0: rdonly, 1: wronly, 2: rdwr)
    li a2, 0             # mode
    li a7, 1024          # syscall open
    ecall

input_file: .asciz "image.pgm"

close example: The close syscall closes a file descriptor, so that it no longer refers to any file and may be reused.

    li a0, 3             # file descriptor (fd) 3
    li a7, 57            # syscall close
    ecall

input_file: .asciz "image.pgm"