str screen_namespace = "/dev/screen/0"; str mouse_namespace = "/dev/mouse/0"; byte BLACK = 0; byte WHITE = 255; byte DARK_GRAY = 73; byte GRAY = 146; byte LIGHT_GRAY = 182; byte CHARCOAL = 36; byte DARK_RED = 128; byte RED = 224; byte DARK_YELLOW = 144; byte YELLOW = 252; byte DARK_TEAL = 9; byte TEAL = 18; byte DARK_GREEN = 12; byte GREEN = 16; byte LIME = 28; byte LIGHT_CYAN = 159; byte NAVY = 2; byte BLUE = 3; byte DEEP_SKY_BLUE = 10; byte LIGHT_BLUE = 19; byte PURPLE = 131; byte LIGHT_PURPLE = 147; byte DARK_MAGENTA = 130; byte MAGENTA = 227; byte PLUM = 129; byte PINK = 226; byte SADDLE_BROWN = 72; byte PERU = 141; byte SIENNA = 136; byte ORANGE = 241; byte DARK_ORANGE = 208; byte GOLD = 244; byte SELECTED_COLOR = 255; function main () { // Open screen ptr screen; str screen_name; int mode; nat screen_buffer; // use load immediate because it a pointer to a string, not a value load_address screen_namespace -> screen_name; load_immediate 0 -> mode; syscall OPEN screen_name mode screen; // Screen screen = open("/dev/screen/0", 0); nat width; nat size; load_offset_32 screen 8 -> width; // load width load_offset_32 screen 12 -> size; // load size nat offset; load_immediate 16 -> offset; // offset for screen buffer add_nat screen offset -> screen_buffer; // open mouse ptr mouse; str mouse_name; load_address mouse_namespace -> mouse_name; syscall OPEN mouse_name mode mouse; // Mouse mouse = open("/dev/mouse/0", 0); byte color; nat x_pos; nat y_pos; load_absolute_8 BLACK -> color; load_immediate 1 -> x_pos; load_immediate 1 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); load_absolute_8 WHITE -> color; load_immediate 21 -> x_pos; load_immediate 1 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); load_absolute_8 CHARCOAL -> color; load_immediate 1 -> x_pos; load_immediate 21 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); load_absolute_8 DARK_GRAY -> color; load_immediate 21 -> x_pos; load_immediate 21 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); load_absolute_8 RED -> color; load_immediate 1 -> x_pos; load_immediate 41 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); load_absolute_8 ORANGE -> color; load_immediate 21 -> x_pos; load_immediate 41 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); load_absolute_8 YELLOW -> color; load_immediate 1 -> x_pos; load_immediate 61 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); load_absolute_8 GREEN -> color; load_immediate 21 -> x_pos; load_immediate 61 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); load_absolute_8 BLUE -> color; load_immediate 1 -> x_pos; load_immediate 81 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); load_absolute_8 PURPLE -> color; load_immediate 21 -> x_pos; load_immediate 81 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); // screen.draw syscall WRITE screen screen_buffer size; nat zero; load_immediate 0 -> zero; loop draw_loop { // load mouse click data syscall REFRESH mouse; byte left_down; load_offset_8 mouse 16 -> left_down; // load btn1 pressed jump_eq_nat draw_loop left_down zero; // if (!btn1.left) continue; nat mouse_x; nat mouse_y; load_offset_32 mouse 8 -> mouse_x; // load x load_offset_32 mouse 12 -> mouse_y; // load y nat box_size; load_immediate 20 -> box_size; // first row load_absolute_8 BLACK -> color; load_immediate 1 -> x_pos; load_immediate 1 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size); load_absolute_8 WHITE -> color; load_immediate 21 -> x_pos; load_immediate 1 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size); load_absolute_8 CHARCOAL -> color; load_immediate 1 -> x_pos; load_immediate 21 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size); load_absolute_8 DARK_GRAY -> color; load_immediate 21 -> x_pos; load_immediate 21 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size); load_absolute_8 RED -> color; load_immediate 1 -> x_pos; load_immediate 41 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size); load_absolute_8 ORANGE -> color; load_immediate 21 -> x_pos; load_immediate 41 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size); load_absolute_8 YELLOW -> color; load_immediate 1 -> x_pos; load_immediate 61 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size); load_absolute_8 GREEN -> color; load_immediate 21 -> x_pos; load_immediate 61 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size); load_absolute_8 BLUE -> color; load_immediate 1 -> x_pos; load_immediate 81 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size); load_absolute_8 PURPLE -> color; load_immediate 21 -> x_pos; load_immediate 81 -> y_pos; call draw_outlined_swatch (screen_buffer color x_pos y_pos width); call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size); syscall WRITE screen screen_buffer size; byte selected_color; load_absolute_8 SELECTED_COLOR -> selected_color; nat brush_size; load_immediate 5 -> brush_size; call draw_box (screen_buffer width selected_color mouse_x mouse_y brush_size brush_size); jump draw_loop; } // Flush and exit exit 0; } function set_color_if_clicked (int click_x, int click_y, int box_x, int box_y, byte check_color, int size) { // Compute right int right_edge; add_int box_x size -> right_edge; // Compute bottom = box_y + size int bottom_edge; add_int box_y size -> bottom_edge; // Bounds check: x in [box_x, right] and y in [box_y, bottom] jump_lt_int fail click_x box_x; jump_gt_int fail click_x right_edge; jump_lt_int fail click_y box_y; jump_gt_int fail click_y bottom_edge; store_absolute_8 check_color -> SELECTED_COLOR; else fail return; } function draw_outlined_swatch(nat base, byte color, int x, int y, int width) { // Constants nat background_color; load_absolute_8 GRAY -> background_color; byte selected_color; load_absolute_8 SELECTED_COLOR -> selected_color; jump_eq_int set_selected color selected_color; jump end_set_selected; do set_selected load_absolute_8 DARK_GRAY -> background_color; else end_set_selected nat outline_size; load_immediate 20 -> outline_size; nat fill_size; load_immediate 17 -> fill_size; nat offset; load_immediate 2 -> offset; call draw_box (base width background_color x y outline_size outline_size); int x_off; int y_off; add_int x offset -> x_off; // x + 2 add_int y offset -> y_off; // y + 2 call draw_box (base width color x_off y_off fill_size fill_size); return; } function draw_box (nat db_base, nat screen_width, byte box_color, nat x_start, nat y_start, nat db_width, nat height) { // Compute start address: base + y*640 + x nat fat_ptr_size; load_immediate 4 -> fat_ptr_size; nat offset; mul_nat y_start screen_width -> offset; add_nat offset x_start -> offset; add_nat offset db_base -> offset; add_nat offset fat_ptr_size -> offset; // need to add offset for fat pointer size int i; load_immediate 1 -> i; int zero; load_immediate 0 -> zero; loop draw_box_outer { memset_8 box_color db_width -> offset; // draw row add_int offset screen_width -> offset; // next row += 640 sub_int height i -> height; // decrement row count jump_gt_int draw_box_outer height zero; } return; }