Update devices to use file descriptor rather than handel. Create REFRESH syscall
This commit is contained in:
		
							parent
							
								
									47d5bdd1d9
								
							
						
					
					
						commit
						c80481de76
					
				
							
								
								
									
										
											BIN
										
									
								
								docs/favicon.ico
								
								
								
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/favicon.ico
								
								
								
								
							
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 298 KiB After Width: | Height: | Size: 298 KiB | 
							
								
								
									
										
											BIN
										
									
								
								docs/undar.png
								
								
								
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/undar.png
								
								
								
								
							
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 7.8 KiB | 
|  | @ -8,7 +8,7 @@ | |||
|    version="1.1" | ||||
|    id="svg1" | ||||
|    inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)" | ||||
|    sodipodi:docname="undâr.svg" | ||||
|    sodipodi:docname="undar.svg" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|  | @ -24,9 +24,9 @@ | |||
|      inkscape:deskcolor="#d1d1d1" | ||||
|      inkscape:document-units="mm" | ||||
|      showguides="false" | ||||
|      inkscape:zoom="10.504938" | ||||
|      inkscape:cx="69.062756" | ||||
|      inkscape:cy="50.880831" | ||||
|      inkscape:zoom="5.252469" | ||||
|      inkscape:cx="31.413798" | ||||
|      inkscape:cy="77.392175" | ||||
|      inkscape:window-width="1939" | ||||
|      inkscape:window-height="932" | ||||
|      inkscape:window-x="0" | ||||
|  | @ -40,16 +40,16 @@ | |||
|      inkscape:groupmode="layer" | ||||
|      id="layer1"> | ||||
|     <path | ||||
|        style="fill:#000000;stroke:#ffffff;stroke-width:0.259677;stroke-opacity:0.5" | ||||
|        style="fill:#000000;stroke:#ffffff;stroke-width:0.259677;stroke-opacity:0.80000001" | ||||
|        d="M 9.8701612,2.1298382 H 2.1298382 V 29.870162 h 7.740323 V 27.874455 H 3.9914349 V 4.0257595 h 5.8787263 z" | ||||
|        id="path1" /> | ||||
|     <path | ||||
|        style="fill:#000000;stroke:#ffffff;stroke-width:0.259677;stroke-opacity:0.5" | ||||
|        style="fill:#000000;stroke:#ffffff;stroke-width:0.259677;stroke-opacity:0.80000001" | ||||
|        d="m 22.129839,2.1298386 h 7.740323 V 29.870161 h -7.740323 v -1.995707 h 5.878726 V 4.02576 h -5.878726 z" | ||||
|        id="path1-3" /> | ||||
|     <path | ||||
|        d="m 9.9966523,7.2192166 c 0.00192,1.1921857 0,17.6324454 0,17.6324454 H 11.947933 V 10.838 c 0,0 6.10676,1.037363 7.80512,3.238279 0.180102,0.233395 0,10.775383 0,10.775383 h 1.951281 L 21.704,13.017 C 21.719643,11.169234 18.492009,9.5084126 16.302239,8.6458806 13.47112,7.5307272 9.9947373,6.0270309 9.9966523,7.2192166 Z" | ||||
|        style="stroke:#ffffff;stroke-width:0.292319;stroke-opacity:0.5" | ||||
|        style="stroke:#ffffff;stroke-width:0.292319;stroke-opacity:0.80000001" | ||||
|        id="path3" | ||||
|        sodipodi:nodetypes="zcccscccsz" /> | ||||
|   </g> | ||||
|  |  | |||
| Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB | 
|  | @ -140,10 +140,14 @@ i32 mouse_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) { | |||
| } | ||||
| 
 | ||||
| i32 mouse_read(void *data, u8 *buffer, u32 size) { | ||||
|   MouseDeviceData *mouse_data = (MouseDeviceData *)data; | ||||
| 
 | ||||
|   if (size < 12) | ||||
|   USED(data); | ||||
|   USED(buffer); | ||||
|   USED(size); | ||||
|   return -1; | ||||
| } | ||||
| 
 | ||||
| i32 mouse_refresh(void *data, u8 *buffer) { | ||||
|   MouseDeviceData *mouse_data = (MouseDeviceData *)data; | ||||
| 
 | ||||
|   u8 *info = (u8 *)buffer; | ||||
|   memcpy(&info[4], &mouse_data->x, sizeof(u32)); | ||||
|  |  | |||
|  | @ -52,6 +52,7 @@ i32 screen_ioctl(void *data, u32 cmd, const u8 *buffer); | |||
| 
 | ||||
| i32 mouse_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size); | ||||
| i32 mouse_read(void *data, u8 *buffer, u32 size); | ||||
| i32 mouse_refresh(void *data, u8 *buffer); | ||||
| i32 mouse_write(void *data, const u8 *buffer, u32 size); | ||||
| i32 mouse_close(void *data); | ||||
| 
 | ||||
|  |  | |||
|  | @ -15,19 +15,22 @@ static DeviceOps screen_ops = {.open = screen_open, | |||
|                                .read = screen_read, | ||||
|                                .write = screen_write, | ||||
|                                .close = screen_close, | ||||
|                                .ioctl = screen_ioctl}; | ||||
|                                .ioctl = screen_ioctl, | ||||
|                                .refresh = nil}; | ||||
| 
 | ||||
| static DeviceOps mouse_ops = {.open = mouse_open, | ||||
|                               .read = mouse_read, | ||||
|                               .write = mouse_write, | ||||
|                               .close = mouse_close, | ||||
|                               .ioctl = nil}; | ||||
|                               .ioctl = nil, | ||||
|                               .refresh = mouse_refresh}; | ||||
| 
 | ||||
| static DeviceOps keyboard_ops = {.open = keyboard_open, | ||||
|                                  .read = keyboard_read, | ||||
|                                  .write = keyboard_write, | ||||
|                                  .close = keyboard_close, | ||||
|                                  .ioctl = nil}; | ||||
|                                  .ioctl = nil, | ||||
|                                  .refresh = nil}; | ||||
| 
 | ||||
| static DeviceOps console_device_ops = { | ||||
|     .open = console_open, | ||||
|  | @ -35,6 +38,7 @@ static DeviceOps console_device_ops = { | |||
|     .write = console_write, | ||||
|     .close = console_close, | ||||
|     .ioctl = console_ioctl, | ||||
|     .refresh = nil | ||||
| }; | ||||
| 
 | ||||
| static ScreenDeviceData screen_data = {0}; | ||||
|  |  | |||
|  | @ -721,6 +721,8 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { | |||
|       syscall_id = SYSCALL_DEVICE_CLOSE; | ||||
|     else if (strcmp(syscall_name, "IOCTL") == 0) | ||||
|       syscall_id = SYSCALL_DEVICE_IOCTL; | ||||
|     else if (strcmp(syscall_name, "REFRESH") == 0) | ||||
|       syscall_id = SYSCALL_DEVICE_REFRESH; | ||||
| 
 | ||||
|     emit_u32(vm, syscall_id); | ||||
| 
 | ||||
|  |  | |||
|  | @ -103,7 +103,8 @@ typedef enum { | |||
|   SYSCALL_DEVICE_READ,  | ||||
|   SYSCALL_DEVICE_WRITE, | ||||
|   SYSCALL_DEVICE_CLOSE, | ||||
|   SYSCALL_DEVICE_IOCTL  | ||||
|   SYSCALL_DEVICE_IOCTL,  | ||||
|   SYSCALL_DEVICE_REFRESH | ||||
| } SyscallID; | ||||
| 
 | ||||
| typedef struct device_ops_s { | ||||
|  | @ -113,6 +114,7 @@ typedef struct device_ops_s { | |||
|   i32 (*close)(void *device_data); | ||||
|   i32 (*ioctl)(void *device_data, u32 cmd, | ||||
|                const u8 *buffer); /* optional control */ | ||||
|   i32 (*refresh)(void *device_data, u8 *buffer); | ||||
| } DeviceOps; | ||||
| 
 | ||||
| #define DEVICE_TYPE_MAX_LENGTH 16 /* 15 chars + null terminator */ | ||||
|  |  | |||
							
								
								
									
										71
									
								
								src/vm/vm.c
								
								
								
								
							
							
						
						
									
										71
									
								
								src/vm/vm.c
								
								
								
								
							|  | @ -556,7 +556,7 @@ bool step_vm(VM *vm) { | |||
|     switch (syscall_id) { | ||||
|     case SYSCALL_DEVICE_OPEN: { | ||||
|       Device *dev; | ||||
|       u32 path_ptr, mode, buffer_ptr; | ||||
|       u32 path_ptr, mode, device_ptr; | ||||
|       u8 path_reg, mode_reg, dest_reg; | ||||
|       dest_reg = read_u8(vm, code, vm->pc); | ||||
|       vm->pc++; | ||||
|  | @ -571,14 +571,14 @@ bool step_vm(VM *vm) { | |||
|       if (dev) { | ||||
|         if (dev->ops->open) { | ||||
|           /* return device plex to user */ | ||||
|           buffer_ptr = vm->mp; | ||||
|           frame->registers[dest_reg] = buffer_ptr; | ||||
|           device_ptr = vm->mp; | ||||
|           frame->registers[dest_reg] = device_ptr; | ||||
|           /* malloc size for device */ | ||||
|           write_u32(vm, memory, buffer_ptr, dev->size); | ||||
|           write_u32(vm, memory, device_ptr, dev->size); | ||||
|           vm->mp += (dev->size + 4); | ||||
|           /* set flag from user */ | ||||
|           vm->flag = dev->ops->open(dev->data, mode, dev->handle, | ||||
|                                     &vm->memory[buffer_ptr + 4], dev->size); | ||||
|                                     &vm->memory[device_ptr + 4], dev->size); | ||||
|         } else { | ||||
|           vm->flag = 1; /* success, no open needed */ | ||||
|         } | ||||
|  | @ -591,25 +591,23 @@ bool step_vm(VM *vm) { | |||
| 
 | ||||
|     case SYSCALL_DEVICE_READ: { | ||||
|       Device *dev; | ||||
|       u32 handle, buffer_ptr, size; | ||||
|       u16 handle_reg, buffer_reg, size_reg; | ||||
|       handle_reg = read_u8(vm, code, vm->pc); | ||||
|       u32 device_ptr, buffer_ptr, size; | ||||
|       u8 device_reg, buffer_reg, size_reg, handle; | ||||
|       device_reg = read_u8(vm, code, vm->pc); | ||||
|       vm->pc++; | ||||
|       buffer_reg = read_u8(vm, code, vm->pc); | ||||
|       vm->pc++; | ||||
|       size_reg = read_u8(vm, code, vm->pc); | ||||
|       vm->pc++; | ||||
|       dest = read_u8(vm, code, vm->pc); | ||||
|       vm->pc++; | ||||
| 
 | ||||
|       handle = frame->registers[handle_reg]; /* path pointer */ | ||||
|       device_ptr = frame->registers[device_reg]; /* device pointer */ | ||||
|       buffer_ptr = frame->registers[buffer_reg]; | ||||
|       size = frame->registers[size_reg];     /* size */ | ||||
|       buffer_ptr = frame->registers[dest]; | ||||
| 
 | ||||
|       handle = vm->memory[device_ptr + 4]; /* get device handle */ | ||||
|       dev = &vm->devices[handle]; | ||||
|       if (dev && dev->ops->read) { | ||||
|         vm->flag = dev->ops->read(dev->data, &vm->memory[buffer_ptr + 4], size); | ||||
|         frame->registers[buffer_reg] = buffer_ptr; | ||||
|       } else { | ||||
|         vm->flag = 0; | ||||
|       } | ||||
|  | @ -617,21 +615,42 @@ bool step_vm(VM *vm) { | |||
|       return true; | ||||
|     } | ||||
| 
 | ||||
|     case SYSCALL_DEVICE_REFRESH: { | ||||
|       Device *dev; | ||||
|       u32 handle, device_ptr; | ||||
|       u8 device_reg; | ||||
|       device_reg = read_u8(vm, code, vm->pc); | ||||
|       vm->pc++; | ||||
| 
 | ||||
|       device_ptr = frame->registers[device_reg]; /* device pointer */ | ||||
|       handle = vm->memory[device_ptr + 4]; /* get device handle */ | ||||
|       dev = &vm->devices[handle]; | ||||
|       if (dev && dev->ops->refresh) { | ||||
|         vm->flag = dev->ops->refresh(dev->data, &vm->memory[device_ptr + 4]); | ||||
|       } else { | ||||
|         vm->flag = 0; | ||||
|       } | ||||
| 
 | ||||
|       return true; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     case SYSCALL_DEVICE_WRITE: { | ||||
|       Device *dev; | ||||
|       u32 handle, buffer_ptr, size; | ||||
|       u16 handle_reg, buffer_reg, size_reg; | ||||
|       handle_reg = read_u8(vm, code, vm->pc); | ||||
|       u32 handle, buffer_ptr, size, device_ptr; | ||||
|       u8 device_reg, buffer_reg, size_reg; | ||||
|       device_reg = read_u8(vm, code, vm->pc); | ||||
|       vm->pc++; | ||||
|       buffer_reg = read_u8(vm, code, vm->pc); | ||||
|       vm->pc++; | ||||
|       size_reg = read_u8(vm, code, vm->pc); | ||||
|       vm->pc++; | ||||
| 
 | ||||
|       handle = frame->registers[handle_reg];     /* R0: path pointer */ | ||||
|       device_ptr = frame->registers[device_reg]; /* device pointer */ | ||||
|       buffer_ptr = frame->registers[buffer_reg]; /* R1: buffer pointer */ | ||||
|       size = frame->registers[size_reg];         /* R2: size */ | ||||
| 
 | ||||
|       handle = vm->memory[device_ptr + 4]; /* get device handle */ | ||||
|       dev = &vm->devices[handle]; | ||||
|       if (dev && dev->ops->write) { | ||||
|         vm->flag = dev->ops->write( | ||||
|  | @ -645,13 +664,14 @@ bool step_vm(VM *vm) { | |||
| 
 | ||||
|     case SYSCALL_DEVICE_CLOSE: { | ||||
|       Device *dev; | ||||
|       u32 handle; | ||||
|       u8 handle_reg; | ||||
|       handle_reg = read_u8(vm, code, vm->pc); | ||||
|       u32 handle, device_ptr; | ||||
|       u8 device_reg; | ||||
|       device_reg = read_u8(vm, code, vm->pc); | ||||
|       vm->pc++; | ||||
| 
 | ||||
|       handle = frame->registers[handle_reg]; /* R0: path pointer */ | ||||
|       device_ptr = frame->registers[device_reg]; /* device pointer */ | ||||
| 
 | ||||
|       handle = vm->memory[device_ptr + 4]; /* get device handle */ | ||||
|       dev = &vm->devices[handle]; | ||||
|       if (dev && dev->ops->close) { | ||||
|         i32 result = dev->ops->close(dev->data); | ||||
|  | @ -665,19 +685,20 @@ bool step_vm(VM *vm) { | |||
| 
 | ||||
|     case SYSCALL_DEVICE_IOCTL: { | ||||
|       Device *dev; | ||||
|       u32 handle, args_ptr, cmd; | ||||
|       u8 handle_reg, cmd_reg, args_ptr_reg; | ||||
|       handle_reg = read_u8(vm, code, vm->pc); | ||||
|       u32 handle, args_ptr, cmd, device_ptr; | ||||
|       u8 device_reg, cmd_reg, args_ptr_reg; | ||||
|       device_reg = read_u8(vm, code, vm->pc); | ||||
|       vm->pc++; | ||||
|       cmd_reg = read_u8(vm, code, vm->pc); | ||||
|       vm->pc++; | ||||
|       args_ptr_reg = read_u8(vm, code, vm->pc); | ||||
|       vm->pc++; | ||||
| 
 | ||||
|       handle = frame->registers[handle_reg];     /* R0: device path */ | ||||
|       device_ptr = frame->registers[device_reg]; /* device pointer */ | ||||
|       cmd = frame->registers[cmd_reg];           /* R1: ioctl command */ | ||||
|       args_ptr = frame->registers[args_ptr_reg]; /* R2: args pointer */ | ||||
| 
 | ||||
|       handle = vm->memory[device_ptr + 4]; /* get device handle */ | ||||
|       dev = &vm->devices[handle]; | ||||
|       if (dev && dev->ops && dev->ops->ioctl) { | ||||
|         i32 result = dev->ops->ioctl(dev->data, cmd, &vm->memory[args_ptr]); | ||||
|  |  | |||
|  | @ -4,20 +4,17 @@ | |||
|     ; use load immediate because it is a pointer to a string, not a value | ||||
|     (load-immediate $0 &screen-namespace) | ||||
|     (load-immediate $11 0) | ||||
|     (syscall OPEN $18 $0 $11) ; open(out Plex screen, in namespace, in flags) | ||||
|     (syscall OPEN $0 $18 $11) ; open(out Plex screen, in namespace, in flags) | ||||
| 
 | ||||
|     (load-offset-32 $0 $18 4) ; load handle | ||||
|     (load-offset-32 $20 $18 8) ; load width | ||||
|     (load-offset-32 $22 $18 12) ; load size | ||||
|     (load-offset-32 $20 $0 8) ; load width | ||||
|     (load-offset-32 $22 $0 12) ; load size | ||||
|     (load-immediate $1 16) ; offset for screen buffer | ||||
|     (add-nat $21 $18 $1) | ||||
|     (add-nat $21 $0 $1) | ||||
| 
 | ||||
|     ; open mouse | ||||
|     (load-immediate $16 &mouse-namespace) | ||||
|     (syscall OPEN $15 $16 $11) ; open(out Plex mouse, in namespace, in flags) | ||||
| 
 | ||||
|     (load-offset-32 $16 $15 4) ; load handle | ||||
| 
 | ||||
|     ; outline_swatch(screen, BLACK, 1, 1); | ||||
|     (load-absolute-32 $1 &BLACK) | ||||
|     (load-immediate $12 1) | ||||
|  | @ -33,16 +30,15 @@ | |||
|     ; screen.draw(); | ||||
|     (syscall WRITE $0 $21 $22) | ||||
| 
 | ||||
|     (load-immediate $3 16) | ||||
|     (label draw-loop | ||||
|       ; load mouse click data | ||||
| 	  	(syscall READ $16 $2 $3 $15) | ||||
|       (syscall REFRESH $15) | ||||
|       (load-offset-8 $9 $15 16) ; load btn1 pressed | ||||
| 
 | ||||
|       (jump-eq-nat &draw-loop $9 $11) | ||||
| 
 | ||||
|       (load-offset-32 $7 $2 8)  ; load x | ||||
|       (load-offset-32 $8 $2 12) ; load y | ||||
|       (load-offset-32 $7 $15 8)  ; load x | ||||
|       (load-offset-32 $8 $15 12) ; load y | ||||
| 
 | ||||
|       (load-immediate $14 20) ; box size | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,20 +4,17 @@ | |||
|     ; use load immediate because it is a pointer to a string, not a value | ||||
|     (load-immediate $0 &screen-namespace) | ||||
|     (load-immediate $11 0) | ||||
|     (syscall OPEN $18 $0 $11) ; Screen screen = open(namespace, flags) | ||||
|     (syscall OPEN $0 $0 $11) ; Screen screen = open(namespace, flags) | ||||
| 
 | ||||
|     (load-offset-32 $0 $18 4) ; load handle | ||||
|     (load-offset-32 $20 $18 8) ; load width | ||||
|     (load-offset-32 $22 $18 12) ; load size | ||||
|     (load-immediate $1 16) ; offset for screen buffer | ||||
|     (add-nat $21 $18 $1) | ||||
|     (load-offset-32 $20 $0 8) ; load width | ||||
|     (load-offset-32 $22 $0 12) ; load size | ||||
|     (load-immediate $1 16) ; pointer offset for screen buffer | ||||
|     (add-nat $21 $0 $1) | ||||
| 
 | ||||
|     ; open mouse | ||||
|     (load-immediate $16 &mouse-namespace) | ||||
|     (syscall OPEN $15 $16 $11) ; Mouse mouse = open(namespace, flags) | ||||
| 
 | ||||
|     (load-offset-32 $16 $15 4) ; load handle | ||||
| 
 | ||||
|     ; outline_swatch(screen, BLACK, 1, 1); | ||||
|     (load-absolute-32 $1 &BLACK) | ||||
|     (load-immediate $12 1) | ||||
|  | @ -73,16 +70,15 @@ | |||
|     ; screen.draw(); | ||||
|     (syscall WRITE $0 $21 $22) | ||||
| 
 | ||||
|     (load-immediate $3 16) | ||||
|     (label draw-loop | ||||
|       ; load mouse click data | ||||
| 	  	(syscall READ $16 $2 $3 $15) | ||||
|       (syscall REFRESH $15) | ||||
|       (load-offset-8 $9 $15 16) ; load btn1 pressed | ||||
| 
 | ||||
|       (jump-eq-nat &draw-loop $9 $11) | ||||
| 
 | ||||
|       (load-offset-32 $7 $2 8)  ; load x | ||||
|       (load-offset-32 $8 $2 12) ; load y | ||||
|       (load-offset-32 $7 $15 8)  ; load x | ||||
|       (load-offset-32 $8 $15 12) ; load y | ||||
| 
 | ||||
|       (load-immediate $14 20) ; box size | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| /** | ||||
|  * Constants | ||||
|  */ | ||||
| const str screen_namespace = "/dev/screen/0"; | ||||
| const str mouse_namespace = "/dev/mouse/0"; | ||||
| const byte BLACK = 0; | ||||
| const byte WHITE = 255; | ||||
| const byte DARK_GRAY = 73; | ||||
|  | @ -22,8 +20,10 @@ plex Screen implements Device { | |||
|   nat buffer_size; | ||||
|   byte[] screen_buffer; | ||||
| 
 | ||||
|   init(str namespace) { | ||||
|     this.handle = open(namespace);  | ||||
|   draw() { | ||||
|     unsafe { | ||||
|       write(this.handle, &this.screen_buffer, this.buffer_size); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | @ -35,29 +35,21 @@ plex Mouse implements Device { | |||
|   bool right; | ||||
|   bool middle; | ||||
|   bool btn4; | ||||
|   nat size; | ||||
| 
 | ||||
|   init(str namespace) { | ||||
|     this.handle = open(namespace);  | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Main function | ||||
|  */ | ||||
| function main() { | ||||
|     Screen screen(screen_namespace); | ||||
|     screen.open(0); | ||||
| 
 | ||||
|     Mouse mouse(mouse_namespace); | ||||
|     mouse.open(0); | ||||
|     Screen screen = open("/dev/screen/0", 0); | ||||
|     Mouse mouse = open("/dev/mouse/0", 0); | ||||
| 
 | ||||
|     outline_swatch(screen, BLACK, 1, 1); | ||||
|     outline_swatch(screen, WHITE, 21, 1); | ||||
|     screen.draw(); | ||||
| 
 | ||||
|     loop { | ||||
| 	    mouse.read(); | ||||
|       mouse.refresh(); | ||||
| 	    if (not mouse.left) continue;  | ||||
| 
 | ||||
| 	    int box_size = 20; | ||||
|  | @ -98,7 +90,7 @@ function set_color(int box_size, int bx, int by, int mx, int my, byte color) { | |||
| /** | ||||
|  * Draw a color box with a grey outline, if selected use a darker color | ||||
|  */ | ||||
| function outline_swatch(ref Device screen, byte color, int x, int y) { | ||||
| function outline_swatch(Device screen, byte color, int x, int y) { | ||||
|     byte bg_color = GRAY; | ||||
|     if (selected_color == color) { | ||||
| 	    bg_color = DARK_GRAY; | ||||
|  | @ -112,7 +104,7 @@ function outline_swatch(ref Device screen, byte color, int x, int y) { | |||
| /** | ||||
|  * Draw a rectangle | ||||
|  */  | ||||
| function rectangle(ref Device screen, byte color, int x, int y, int width, int height) { | ||||
| function rectangle(Device screen, byte color, int x, int y, int width, int height) { | ||||
|    // we need unsafe because we are using `ptr` and `memset` directly | ||||
|    // unsafe takes the guardrails off and allows you to access/modify memory directly | ||||
|    unsafe { | ||||
|  |  | |||
|  | @ -2,12 +2,14 @@ | |||
|  * Constants | ||||
|  */ | ||||
| const str nl = "\n"; | ||||
| const real x = 1.0; | ||||
| const real y = 1.0; | ||||
| 
 | ||||
| plex Terminal { | ||||
|   nat handle; | ||||
| 
 | ||||
|   init() { | ||||
|     handle = open("/dev/term/0", 0); | ||||
|     this.handle = open("/dev/term/0", 0); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | @ -15,7 +17,7 @@ plex Terminal { | |||
|  * Main function | ||||
|  */ | ||||
| function main() { | ||||
|     pln((1 + 2).str); | ||||
|     pln((x + y).str); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  |  | |||
|  | @ -2,26 +2,24 @@ | |||
|   (label main | ||||
|     ; Open screen | ||||
|     ; use load immediate because it is a pointer to a string, not a value | ||||
|     (load-immediate $0 &screen-namespace) | ||||
|     (syscall OPEN $18 $0 $11) ; open(out Plex screen, in namespace, in flags) | ||||
| 
 | ||||
|     (load-offset-32 $0 $18 4) ; load handle | ||||
|     (load-immediate $18 &screen-namespace) | ||||
|     (syscall OPEN $0 $18 $11) ; open(out Plex screen, in namespace, in flags) | ||||
| 
 | ||||
|     (nat-to-string $5 $0) | ||||
|     (call &pln ($5) nil) | ||||
| 
 | ||||
|     (load-offset-32 $20 $18 8) ; load width | ||||
|     (load-offset-32 $20 $0 8) ; load width | ||||
| 
 | ||||
|     (nat-to-string $5 $20) | ||||
|     (call &pln ($5) nil) | ||||
| 
 | ||||
|     (load-offset-32 $22 $18 12) ; load size    | ||||
|     (load-offset-32 $22 $0 12) ; load size    | ||||
| 
 | ||||
|     (nat-to-string $5 $22) | ||||
|     (call &pln ($5) nil) | ||||
| 
 | ||||
|     (load-immediate $1 16) ; offset for screen buffer | ||||
|     (add-nat $21 $18 $1) | ||||
|     (add-nat $21 $0 $1) | ||||
| 
 | ||||
|     (nat-to-string $5 $21) | ||||
|     (call &pln ($5) nil) | ||||
|  | @ -30,21 +28,17 @@ | |||
|     (load-immediate $16 &mouse-namespace) | ||||
|     (syscall OPEN $15 $16 $11) ; open(out Plex mouse, in namespace, in flags) | ||||
| 
 | ||||
|     (load-offset-32 $16 $15 4) ; load handle | ||||
| 
 | ||||
|     (syscall WRITE $0 $21 $22) ; redraw | ||||
| 
 | ||||
|     (load-immediate $3 16) | ||||
|     (label draw-loop | ||||
|       ; load mouse click data | ||||
| 	  	(syscall READ $16 $2 $3 $15) | ||||
| 
 | ||||
|       (syscall REFRESH $15) | ||||
|       (load-offset-8 $9 $15 16) ; load btn1 pressed | ||||
| 
 | ||||
|       (jump-eq-nat &draw-loop $9 $11) | ||||
| 
 | ||||
|       (load-offset-32 $7 $2 8) ; load x | ||||
|       (load-offset-32 $8 $2 12) ; load y | ||||
|       (load-offset-32 $7 $15 8)  ; load x | ||||
|       (load-offset-32 $8 $15 12) ; load y | ||||
| 
 | ||||
|       ; Compute start address: y*width + x | ||||
|       (mul-nat $30 $8 $20)        ; $15 = y * width | ||||
|  | @ -64,11 +58,10 @@ | |||
| 		  (load-immediate $11 0) | ||||
| 		  (syscall OPEN $1 $1 $11)	 | ||||
| 		  (load-immediate $3 &new-line) | ||||
|       (load-offset-32 $7 $1 4) ; load handle | ||||
| 		  (string-length $2 $0) | ||||
| 		  (syscall WRITE $7 $0 $2) | ||||
| 		  (syscall WRITE $1 $0 $2) | ||||
| 		  (string-length $4 $3) | ||||
| 		  (syscall WRITE $7 $3 $4) | ||||
| 		  (syscall WRITE $1 $3 $4) | ||||
| 		  (return nil))) | ||||
| (data | ||||
|   (label screen-namespace "/dev/screen/0") | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue