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" |    version="1.1" | ||||||
|    id="svg1" |    id="svg1" | ||||||
|    inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)" |    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:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||||
|    xmlns="http://www.w3.org/2000/svg" |    xmlns="http://www.w3.org/2000/svg" | ||||||
|  | @ -24,9 +24,9 @@ | ||||||
|      inkscape:deskcolor="#d1d1d1" |      inkscape:deskcolor="#d1d1d1" | ||||||
|      inkscape:document-units="mm" |      inkscape:document-units="mm" | ||||||
|      showguides="false" |      showguides="false" | ||||||
|      inkscape:zoom="10.504938" |      inkscape:zoom="5.252469" | ||||||
|      inkscape:cx="69.062756" |      inkscape:cx="31.413798" | ||||||
|      inkscape:cy="50.880831" |      inkscape:cy="77.392175" | ||||||
|      inkscape:window-width="1939" |      inkscape:window-width="1939" | ||||||
|      inkscape:window-height="932" |      inkscape:window-height="932" | ||||||
|      inkscape:window-x="0" |      inkscape:window-x="0" | ||||||
|  | @ -40,16 +40,16 @@ | ||||||
|      inkscape:groupmode="layer" |      inkscape:groupmode="layer" | ||||||
|      id="layer1"> |      id="layer1"> | ||||||
|     <path |     <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" |        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" /> |        id="path1" /> | ||||||
|     <path |     <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" |        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" /> |        id="path1-3" /> | ||||||
|     <path |     <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" |        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" |        id="path3" | ||||||
|        sodipodi:nodetypes="zcccscccsz" /> |        sodipodi:nodetypes="zcccscccsz" /> | ||||||
|   </g> |   </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) { | i32 mouse_read(void *data, u8 *buffer, u32 size) { | ||||||
|   MouseDeviceData *mouse_data = (MouseDeviceData *)data; |   USED(data); | ||||||
|  |   USED(buffer); | ||||||
|  |   USED(size); | ||||||
|  |   return -1; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|   if (size < 12) | i32 mouse_refresh(void *data, u8 *buffer) { | ||||||
|     return -1; |   MouseDeviceData *mouse_data = (MouseDeviceData *)data; | ||||||
| 
 | 
 | ||||||
|   u8 *info = (u8 *)buffer; |   u8 *info = (u8 *)buffer; | ||||||
|   memcpy(&info[4], &mouse_data->x, sizeof(u32)); |   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_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size); | ||||||
| i32 mouse_read(void *data, 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_write(void *data, const u8 *buffer, u32 size); | ||||||
| i32 mouse_close(void *data); | i32 mouse_close(void *data); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -15,19 +15,22 @@ static DeviceOps screen_ops = {.open = screen_open, | ||||||
|                                .read = screen_read, |                                .read = screen_read, | ||||||
|                                .write = screen_write, |                                .write = screen_write, | ||||||
|                                .close = screen_close, |                                .close = screen_close, | ||||||
|                                .ioctl = screen_ioctl}; |                                .ioctl = screen_ioctl, | ||||||
|  |                                .refresh = nil}; | ||||||
| 
 | 
 | ||||||
| static DeviceOps mouse_ops = {.open = mouse_open, | static DeviceOps mouse_ops = {.open = mouse_open, | ||||||
|                               .read = mouse_read, |                               .read = mouse_read, | ||||||
|                               .write = mouse_write, |                               .write = mouse_write, | ||||||
|                               .close = mouse_close, |                               .close = mouse_close, | ||||||
|                               .ioctl = nil}; |                               .ioctl = nil, | ||||||
|  |                               .refresh = mouse_refresh}; | ||||||
| 
 | 
 | ||||||
| static DeviceOps keyboard_ops = {.open = keyboard_open, | static DeviceOps keyboard_ops = {.open = keyboard_open, | ||||||
|                                  .read = keyboard_read, |                                  .read = keyboard_read, | ||||||
|                                  .write = keyboard_write, |                                  .write = keyboard_write, | ||||||
|                                  .close = keyboard_close, |                                  .close = keyboard_close, | ||||||
|                                  .ioctl = nil}; |                                  .ioctl = nil, | ||||||
|  |                                  .refresh = nil}; | ||||||
| 
 | 
 | ||||||
| static DeviceOps console_device_ops = { | static DeviceOps console_device_ops = { | ||||||
|     .open = console_open, |     .open = console_open, | ||||||
|  | @ -35,6 +38,7 @@ static DeviceOps console_device_ops = { | ||||||
|     .write = console_write, |     .write = console_write, | ||||||
|     .close = console_close, |     .close = console_close, | ||||||
|     .ioctl = console_ioctl, |     .ioctl = console_ioctl, | ||||||
|  |     .refresh = nil | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static ScreenDeviceData screen_data = {0}; | static ScreenDeviceData screen_data = {0}; | ||||||
|  |  | ||||||
|  | @ -721,6 +721,8 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { | ||||||
|       syscall_id = SYSCALL_DEVICE_CLOSE; |       syscall_id = SYSCALL_DEVICE_CLOSE; | ||||||
|     else if (strcmp(syscall_name, "IOCTL") == 0) |     else if (strcmp(syscall_name, "IOCTL") == 0) | ||||||
|       syscall_id = SYSCALL_DEVICE_IOCTL; |       syscall_id = SYSCALL_DEVICE_IOCTL; | ||||||
|  |     else if (strcmp(syscall_name, "REFRESH") == 0) | ||||||
|  |       syscall_id = SYSCALL_DEVICE_REFRESH; | ||||||
| 
 | 
 | ||||||
|     emit_u32(vm, syscall_id); |     emit_u32(vm, syscall_id); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -103,7 +103,8 @@ typedef enum { | ||||||
|   SYSCALL_DEVICE_READ,  |   SYSCALL_DEVICE_READ,  | ||||||
|   SYSCALL_DEVICE_WRITE, |   SYSCALL_DEVICE_WRITE, | ||||||
|   SYSCALL_DEVICE_CLOSE, |   SYSCALL_DEVICE_CLOSE, | ||||||
|   SYSCALL_DEVICE_IOCTL  |   SYSCALL_DEVICE_IOCTL,  | ||||||
|  |   SYSCALL_DEVICE_REFRESH | ||||||
| } SyscallID; | } SyscallID; | ||||||
| 
 | 
 | ||||||
| typedef struct device_ops_s { | typedef struct device_ops_s { | ||||||
|  | @ -113,6 +114,7 @@ typedef struct device_ops_s { | ||||||
|   i32 (*close)(void *device_data); |   i32 (*close)(void *device_data); | ||||||
|   i32 (*ioctl)(void *device_data, u32 cmd, |   i32 (*ioctl)(void *device_data, u32 cmd, | ||||||
|                const u8 *buffer); /* optional control */ |                const u8 *buffer); /* optional control */ | ||||||
|  |   i32 (*refresh)(void *device_data, u8 *buffer); | ||||||
| } DeviceOps; | } DeviceOps; | ||||||
| 
 | 
 | ||||||
| #define DEVICE_TYPE_MAX_LENGTH 16 /* 15 chars + null terminator */ | #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) { |     switch (syscall_id) { | ||||||
|     case SYSCALL_DEVICE_OPEN: { |     case SYSCALL_DEVICE_OPEN: { | ||||||
|       Device *dev; |       Device *dev; | ||||||
|       u32 path_ptr, mode, buffer_ptr; |       u32 path_ptr, mode, device_ptr; | ||||||
|       u8 path_reg, mode_reg, dest_reg; |       u8 path_reg, mode_reg, dest_reg; | ||||||
|       dest_reg = read_u8(vm, code, vm->pc); |       dest_reg = read_u8(vm, code, vm->pc); | ||||||
|       vm->pc++; |       vm->pc++; | ||||||
|  | @ -571,14 +571,14 @@ bool step_vm(VM *vm) { | ||||||
|       if (dev) { |       if (dev) { | ||||||
|         if (dev->ops->open) { |         if (dev->ops->open) { | ||||||
|           /* return device plex to user */ |           /* return device plex to user */ | ||||||
|           buffer_ptr = vm->mp; |           device_ptr = vm->mp; | ||||||
|           frame->registers[dest_reg] = buffer_ptr; |           frame->registers[dest_reg] = device_ptr; | ||||||
|           /* malloc size for device */ |           /* 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); |           vm->mp += (dev->size + 4); | ||||||
|           /* set flag from user */ |           /* set flag from user */ | ||||||
|           vm->flag = dev->ops->open(dev->data, mode, dev->handle, |           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 { |         } else { | ||||||
|           vm->flag = 1; /* success, no open needed */ |           vm->flag = 1; /* success, no open needed */ | ||||||
|         } |         } | ||||||
|  | @ -591,25 +591,23 @@ bool step_vm(VM *vm) { | ||||||
| 
 | 
 | ||||||
|     case SYSCALL_DEVICE_READ: { |     case SYSCALL_DEVICE_READ: { | ||||||
|       Device *dev; |       Device *dev; | ||||||
|       u32 handle, buffer_ptr, size; |       u32 device_ptr, buffer_ptr, size; | ||||||
|       u16 handle_reg, buffer_reg, size_reg; |       u8 device_reg, buffer_reg, size_reg, handle; | ||||||
|       handle_reg = read_u8(vm, code, vm->pc); |       device_reg = read_u8(vm, code, vm->pc); | ||||||
|       vm->pc++; |       vm->pc++; | ||||||
|       buffer_reg = read_u8(vm, code, vm->pc); |       buffer_reg = read_u8(vm, code, vm->pc); | ||||||
|       vm->pc++; |       vm->pc++; | ||||||
|       size_reg = read_u8(vm, code, vm->pc); |       size_reg = read_u8(vm, code, vm->pc); | ||||||
|       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 */ |       size = frame->registers[size_reg];     /* size */ | ||||||
|       buffer_ptr = frame->registers[dest]; |  | ||||||
| 
 | 
 | ||||||
|  |       handle = vm->memory[device_ptr + 4]; /* get device handle */ | ||||||
|       dev = &vm->devices[handle]; |       dev = &vm->devices[handle]; | ||||||
|       if (dev && dev->ops->read) { |       if (dev && dev->ops->read) { | ||||||
|         vm->flag = dev->ops->read(dev->data, &vm->memory[buffer_ptr + 4], size); |         vm->flag = dev->ops->read(dev->data, &vm->memory[buffer_ptr + 4], size); | ||||||
|         frame->registers[buffer_reg] = buffer_ptr; |  | ||||||
|       } else { |       } else { | ||||||
|         vm->flag = 0; |         vm->flag = 0; | ||||||
|       } |       } | ||||||
|  | @ -617,21 +615,42 @@ bool step_vm(VM *vm) { | ||||||
|       return true; |       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: { |     case SYSCALL_DEVICE_WRITE: { | ||||||
|       Device *dev; |       Device *dev; | ||||||
|       u32 handle, buffer_ptr, size; |       u32 handle, buffer_ptr, size, device_ptr; | ||||||
|       u16 handle_reg, buffer_reg, size_reg; |       u8 device_reg, buffer_reg, size_reg; | ||||||
|       handle_reg = read_u8(vm, code, vm->pc); |       device_reg = read_u8(vm, code, vm->pc); | ||||||
|       vm->pc++; |       vm->pc++; | ||||||
|       buffer_reg = read_u8(vm, code, vm->pc); |       buffer_reg = read_u8(vm, code, vm->pc); | ||||||
|       vm->pc++; |       vm->pc++; | ||||||
|       size_reg = read_u8(vm, code, vm->pc); |       size_reg = read_u8(vm, code, vm->pc); | ||||||
|       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 */ |       buffer_ptr = frame->registers[buffer_reg]; /* R1: buffer pointer */ | ||||||
|       size = frame->registers[size_reg];         /* R2: size */ |       size = frame->registers[size_reg];         /* R2: size */ | ||||||
| 
 | 
 | ||||||
|  |       handle = vm->memory[device_ptr + 4]; /* get device handle */ | ||||||
|       dev = &vm->devices[handle]; |       dev = &vm->devices[handle]; | ||||||
|       if (dev && dev->ops->write) { |       if (dev && dev->ops->write) { | ||||||
|         vm->flag = dev->ops->write( |         vm->flag = dev->ops->write( | ||||||
|  | @ -645,13 +664,14 @@ bool step_vm(VM *vm) { | ||||||
| 
 | 
 | ||||||
|     case SYSCALL_DEVICE_CLOSE: { |     case SYSCALL_DEVICE_CLOSE: { | ||||||
|       Device *dev; |       Device *dev; | ||||||
|       u32 handle; |       u32 handle, device_ptr; | ||||||
|       u8 handle_reg; |       u8 device_reg; | ||||||
|       handle_reg = read_u8(vm, code, vm->pc); |       device_reg = read_u8(vm, code, vm->pc); | ||||||
|       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]; |       dev = &vm->devices[handle]; | ||||||
|       if (dev && dev->ops->close) { |       if (dev && dev->ops->close) { | ||||||
|         i32 result = dev->ops->close(dev->data); |         i32 result = dev->ops->close(dev->data); | ||||||
|  | @ -665,19 +685,20 @@ bool step_vm(VM *vm) { | ||||||
| 
 | 
 | ||||||
|     case SYSCALL_DEVICE_IOCTL: { |     case SYSCALL_DEVICE_IOCTL: { | ||||||
|       Device *dev; |       Device *dev; | ||||||
|       u32 handle, args_ptr, cmd; |       u32 handle, args_ptr, cmd, device_ptr; | ||||||
|       u8 handle_reg, cmd_reg, args_ptr_reg; |       u8 device_reg, cmd_reg, args_ptr_reg; | ||||||
|       handle_reg = read_u8(vm, code, vm->pc); |       device_reg = read_u8(vm, code, vm->pc); | ||||||
|       vm->pc++; |       vm->pc++; | ||||||
|       cmd_reg = read_u8(vm, code, vm->pc); |       cmd_reg = read_u8(vm, code, vm->pc); | ||||||
|       vm->pc++; |       vm->pc++; | ||||||
|       args_ptr_reg = read_u8(vm, code, vm->pc); |       args_ptr_reg = read_u8(vm, code, vm->pc); | ||||||
|       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 */ |       cmd = frame->registers[cmd_reg];           /* R1: ioctl command */ | ||||||
|       args_ptr = frame->registers[args_ptr_reg]; /* R2: args pointer */ |       args_ptr = frame->registers[args_ptr_reg]; /* R2: args pointer */ | ||||||
| 
 | 
 | ||||||
|  |       handle = vm->memory[device_ptr + 4]; /* get device handle */ | ||||||
|       dev = &vm->devices[handle]; |       dev = &vm->devices[handle]; | ||||||
|       if (dev && dev->ops && dev->ops->ioctl) { |       if (dev && dev->ops && dev->ops->ioctl) { | ||||||
|         i32 result = dev->ops->ioctl(dev->data, cmd, &vm->memory[args_ptr]); |         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 |     ; use load immediate because it is a pointer to a string, not a value | ||||||
|     (load-immediate $0 &screen-namespace) |     (load-immediate $0 &screen-namespace) | ||||||
|     (load-immediate $11 0) |     (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 $0 8) ; load width | ||||||
|     (load-offset-32 $20 $18 8) ; load width |     (load-offset-32 $22 $0 12) ; load size | ||||||
|     (load-offset-32 $22 $18 12) ; load size |  | ||||||
|     (load-immediate $1 16) ; offset for screen buffer |     (load-immediate $1 16) ; offset for screen buffer | ||||||
|     (add-nat $21 $18 $1) |     (add-nat $21 $0 $1) | ||||||
| 
 | 
 | ||||||
|     ; open mouse |     ; open mouse | ||||||
|     (load-immediate $16 &mouse-namespace) |     (load-immediate $16 &mouse-namespace) | ||||||
|     (syscall OPEN $15 $16 $11) ; open(out Plex mouse, in namespace, in flags) |     (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); |     ; outline_swatch(screen, BLACK, 1, 1); | ||||||
|     (load-absolute-32 $1 &BLACK) |     (load-absolute-32 $1 &BLACK) | ||||||
|     (load-immediate $12 1) |     (load-immediate $12 1) | ||||||
|  | @ -33,16 +30,15 @@ | ||||||
|     ; screen.draw(); |     ; screen.draw(); | ||||||
|     (syscall WRITE $0 $21 $22) |     (syscall WRITE $0 $21 $22) | ||||||
| 
 | 
 | ||||||
|     (load-immediate $3 16) |  | ||||||
|     (label draw-loop |     (label draw-loop | ||||||
|       ; load mouse click data |       ; load mouse click data | ||||||
| 	  	(syscall READ $16 $2 $3 $15) |       (syscall REFRESH $15) | ||||||
|       (load-offset-8 $9 $15 16) ; load btn1 pressed |       (load-offset-8 $9 $15 16) ; load btn1 pressed | ||||||
| 
 | 
 | ||||||
|       (jump-eq-nat &draw-loop $9 $11) |       (jump-eq-nat &draw-loop $9 $11) | ||||||
| 
 | 
 | ||||||
|       (load-offset-32 $7 $2 8)  ; load x |       (load-offset-32 $7 $15 8)  ; load x | ||||||
|       (load-offset-32 $8 $2 12) ; load y |       (load-offset-32 $8 $15 12) ; load y | ||||||
| 
 | 
 | ||||||
|       (load-immediate $14 20) ; box size |       (load-immediate $14 20) ; box size | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,20 +4,17 @@ | ||||||
|     ; use load immediate because it is a pointer to a string, not a value |     ; use load immediate because it is a pointer to a string, not a value | ||||||
|     (load-immediate $0 &screen-namespace) |     (load-immediate $0 &screen-namespace) | ||||||
|     (load-immediate $11 0) |     (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 $0 8) ; load width | ||||||
|     (load-offset-32 $20 $18 8) ; load width |     (load-offset-32 $22 $0 12) ; load size | ||||||
|     (load-offset-32 $22 $18 12) ; load size |     (load-immediate $1 16) ; pointer offset for screen buffer | ||||||
|     (load-immediate $1 16) ; offset for screen buffer |     (add-nat $21 $0 $1) | ||||||
|     (add-nat $21 $18 $1) |  | ||||||
| 
 | 
 | ||||||
|     ; open mouse |     ; open mouse | ||||||
|     (load-immediate $16 &mouse-namespace) |     (load-immediate $16 &mouse-namespace) | ||||||
|     (syscall OPEN $15 $16 $11) ; Mouse mouse = open(namespace, flags) |     (syscall OPEN $15 $16 $11) ; Mouse mouse = open(namespace, flags) | ||||||
| 
 | 
 | ||||||
|     (load-offset-32 $16 $15 4) ; load handle |  | ||||||
| 
 |  | ||||||
|     ; outline_swatch(screen, BLACK, 1, 1); |     ; outline_swatch(screen, BLACK, 1, 1); | ||||||
|     (load-absolute-32 $1 &BLACK) |     (load-absolute-32 $1 &BLACK) | ||||||
|     (load-immediate $12 1) |     (load-immediate $12 1) | ||||||
|  | @ -73,16 +70,15 @@ | ||||||
|     ; screen.draw(); |     ; screen.draw(); | ||||||
|     (syscall WRITE $0 $21 $22) |     (syscall WRITE $0 $21 $22) | ||||||
| 
 | 
 | ||||||
|     (load-immediate $3 16) |  | ||||||
|     (label draw-loop |     (label draw-loop | ||||||
|       ; load mouse click data |       ; load mouse click data | ||||||
| 	  	(syscall READ $16 $2 $3 $15) |       (syscall REFRESH $15) | ||||||
|       (load-offset-8 $9 $15 16) ; load btn1 pressed |       (load-offset-8 $9 $15 16) ; load btn1 pressed | ||||||
| 
 | 
 | ||||||
|       (jump-eq-nat &draw-loop $9 $11) |       (jump-eq-nat &draw-loop $9 $11) | ||||||
| 
 | 
 | ||||||
|       (load-offset-32 $7 $2 8)  ; load x |       (load-offset-32 $7 $15 8)  ; load x | ||||||
|       (load-offset-32 $8 $2 12) ; load y |       (load-offset-32 $8 $15 12) ; load y | ||||||
| 
 | 
 | ||||||
|       (load-immediate $14 20) ; box size |       (load-immediate $14 20) ; box size | ||||||
| 
 | 
 | ||||||
|  | @ -229,8 +225,8 @@ | ||||||
|     (return nil))) |     (return nil))) | ||||||
| (data | (data | ||||||
| 	(label screen-namespace "/dev/screen/0") | 	(label screen-namespace "/dev/screen/0") | ||||||
|   (label mouse-namespace "/dev/mouse/0") | 	(label mouse-namespace "/dev/mouse/0") | ||||||
|   (label SELECTED-COLOR 255) | 	(label SELECTED-COLOR 255) | ||||||
| 	(label BLACK 0) | 	(label BLACK 0) | ||||||
| 	(label WHITE 255) | 	(label WHITE 255) | ||||||
| 	(label CHARCOAL 36) | 	(label CHARCOAL 36) | ||||||
|  |  | ||||||
|  | @ -1,8 +1,6 @@ | ||||||
| /** | /** | ||||||
|  * Constants |  * Constants | ||||||
|  */ |  */ | ||||||
| const str screen_namespace = "/dev/screen/0"; |  | ||||||
| const str mouse_namespace = "/dev/mouse/0"; |  | ||||||
| const byte BLACK = 0; | const byte BLACK = 0; | ||||||
| const byte WHITE = 255; | const byte WHITE = 255; | ||||||
| const byte DARK_GRAY = 73; | const byte DARK_GRAY = 73; | ||||||
|  | @ -22,8 +20,10 @@ plex Screen implements Device { | ||||||
|   nat buffer_size; |   nat buffer_size; | ||||||
|   byte[] screen_buffer; |   byte[] screen_buffer; | ||||||
| 
 | 
 | ||||||
|   init(str namespace) { |   draw() { | ||||||
|     this.handle = open(namespace);  |     unsafe { | ||||||
|  |       write(this.handle, &this.screen_buffer, this.buffer_size); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -35,29 +35,21 @@ plex Mouse implements Device { | ||||||
|   bool right; |   bool right; | ||||||
|   bool middle; |   bool middle; | ||||||
|   bool btn4; |   bool btn4; | ||||||
|   nat size; |  | ||||||
| 
 |  | ||||||
|   init(str namespace) { |  | ||||||
|     this.handle = open(namespace);  |  | ||||||
|   } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Main function |  * Main function | ||||||
|  */ |  */ | ||||||
| function main() { | function main() { | ||||||
|     Screen screen(screen_namespace); |     Screen screen = open("/dev/screen/0", 0); | ||||||
|     screen.open(0); |     Mouse mouse = open("/dev/mouse/0", 0); | ||||||
| 
 |  | ||||||
|     Mouse mouse(mouse_namespace); |  | ||||||
|     mouse.open(0); |  | ||||||
| 
 | 
 | ||||||
|     outline_swatch(screen, BLACK, 1, 1); |     outline_swatch(screen, BLACK, 1, 1); | ||||||
|     outline_swatch(screen, WHITE, 21, 1); |     outline_swatch(screen, WHITE, 21, 1); | ||||||
|     screen.draw(); |     screen.draw(); | ||||||
| 
 | 
 | ||||||
|     loop { |     loop { | ||||||
| 	    mouse.read(); |       mouse.refresh(); | ||||||
| 	    if (not mouse.left) continue;  | 	    if (not mouse.left) continue;  | ||||||
| 
 | 
 | ||||||
| 	    int box_size = 20; | 	    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 |  * 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; |     byte bg_color = GRAY; | ||||||
|     if (selected_color == color) { |     if (selected_color == color) { | ||||||
| 	    bg_color = DARK_GRAY; | 	    bg_color = DARK_GRAY; | ||||||
|  | @ -112,7 +104,7 @@ function outline_swatch(ref Device screen, byte color, int x, int y) { | ||||||
| /** | /** | ||||||
|  * Draw a rectangle |  * 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 |    // 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 takes the guardrails off and allows you to access/modify memory directly | ||||||
|    unsafe { |    unsafe { | ||||||
|  |  | ||||||
|  | @ -11,7 +11,7 @@ | ||||||
| 		(load-immediate $11 0) | 		(load-immediate $11 0) | ||||||
| 		(syscall OPEN $1 $1 $11)	 | 		(syscall OPEN $1 $1 $11)	 | ||||||
| 		(load-immediate $3 &new-line) | 		(load-immediate $3 &new-line) | ||||||
|     	(load-offset-32 $7 $1 4) ; load handle | 		(load-offset-32 $7 $1 4) ; load handle | ||||||
| 		(string-length $2 $0) | 		(string-length $2 $0) | ||||||
| 		(syscall WRITE $7 $0 $2) | 		(syscall WRITE $7 $0 $2) | ||||||
| 		(string-length $4 $3) | 		(string-length $4 $3) | ||||||
|  |  | ||||||
|  | @ -2,12 +2,14 @@ | ||||||
|  * Constants |  * Constants | ||||||
|  */ |  */ | ||||||
| const str nl = "\n"; | const str nl = "\n"; | ||||||
|  | const real x = 1.0; | ||||||
|  | const real y = 1.0; | ||||||
| 
 | 
 | ||||||
| plex Terminal { | plex Terminal { | ||||||
|   nat handle; |   nat handle; | ||||||
| 
 | 
 | ||||||
|   init() { |   init() { | ||||||
|     handle = open("/dev/term/0", 0); |     this.handle = open("/dev/term/0", 0); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -15,7 +17,7 @@ plex Terminal { | ||||||
|  * Main function |  * Main function | ||||||
|  */ |  */ | ||||||
| function main() { | function main() { | ||||||
|     pln((1 + 2).str); |     pln((x + y).str); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  |  | ||||||
|  | @ -2,26 +2,24 @@ | ||||||
|   (label main |   (label main | ||||||
|     ; Open screen |     ; Open screen | ||||||
|     ; use load immediate because it is a pointer to a string, not a value |     ; use load immediate because it is a pointer to a string, not a value | ||||||
|     (load-immediate $0 &screen-namespace) |     (load-immediate $18 &screen-namespace) | ||||||
|     (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 |  | ||||||
| 
 | 
 | ||||||
|     (nat-to-string $5 $0) |     (nat-to-string $5 $0) | ||||||
|     (call &pln ($5) nil) |     (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) |     (nat-to-string $5 $20) | ||||||
|     (call &pln ($5) nil) |     (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) |     (nat-to-string $5 $22) | ||||||
|     (call &pln ($5) nil) |     (call &pln ($5) nil) | ||||||
| 
 | 
 | ||||||
|     (load-immediate $1 16) ; offset for screen buffer |     (load-immediate $1 16) ; offset for screen buffer | ||||||
|     (add-nat $21 $18 $1) |     (add-nat $21 $0 $1) | ||||||
| 
 | 
 | ||||||
|     (nat-to-string $5 $21) |     (nat-to-string $5 $21) | ||||||
|     (call &pln ($5) nil) |     (call &pln ($5) nil) | ||||||
|  | @ -30,21 +28,17 @@ | ||||||
|     (load-immediate $16 &mouse-namespace) |     (load-immediate $16 &mouse-namespace) | ||||||
|     (syscall OPEN $15 $16 $11) ; open(out Plex mouse, in namespace, in flags) |     (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 |     (syscall WRITE $0 $21 $22) ; redraw | ||||||
| 
 | 
 | ||||||
|     (load-immediate $3 16) |  | ||||||
|     (label draw-loop |     (label draw-loop | ||||||
|       ; load mouse click data |       ; load mouse click data | ||||||
| 	  	(syscall READ $16 $2 $3 $15) |       (syscall REFRESH $15) | ||||||
| 
 |  | ||||||
|       (load-offset-8 $9 $15 16) ; load btn1 pressed |       (load-offset-8 $9 $15 16) ; load btn1 pressed | ||||||
| 
 | 
 | ||||||
|       (jump-eq-nat &draw-loop $9 $11) |       (jump-eq-nat &draw-loop $9 $11) | ||||||
| 
 | 
 | ||||||
|       (load-offset-32 $7 $2 8) ; load x |       (load-offset-32 $7 $15 8)  ; load x | ||||||
|       (load-offset-32 $8 $2 12) ; load y |       (load-offset-32 $8 $15 12) ; load y | ||||||
| 
 | 
 | ||||||
|       ; Compute start address: y*width + x |       ; Compute start address: y*width + x | ||||||
|       (mul-nat $30 $8 $20)        ; $15 = y * width |       (mul-nat $30 $8 $20)        ; $15 = y * width | ||||||
|  | @ -64,11 +58,10 @@ | ||||||
| 		  (load-immediate $11 0) | 		  (load-immediate $11 0) | ||||||
| 		  (syscall OPEN $1 $1 $11)	 | 		  (syscall OPEN $1 $1 $11)	 | ||||||
| 		  (load-immediate $3 &new-line) | 		  (load-immediate $3 &new-line) | ||||||
|       (load-offset-32 $7 $1 4) ; load handle |  | ||||||
| 		  (string-length $2 $0) | 		  (string-length $2 $0) | ||||||
| 		  (syscall WRITE $7 $0 $2) | 		  (syscall WRITE $1 $0 $2) | ||||||
| 		  (string-length $4 $3) | 		  (string-length $4 $3) | ||||||
| 		  (syscall WRITE $7 $3 $4) | 		  (syscall WRITE $1 $3 $4) | ||||||
| 		  (return nil))) | 		  (return nil))) | ||||||
| (data | (data | ||||||
|   (label screen-namespace "/dev/screen/0") |   (label screen-namespace "/dev/screen/0") | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue