system.c (3364B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #include "../uxn.h" 5 6 #include "system.h" 7 8 /* 9 Copyright (c) 2022-2025 Devine Lu Linvega, Andrew Alderwick 10 11 Permission to use, copy, modify, and distribute this software for any 12 purpose with or without fee is hereby granted, provided that the above 13 copyright notice and this permission notice appear in all copies. 14 15 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 16 WITH REGARD TO THIS SOFTWARE. 17 */ 18 19 char *boot_path; 20 21 static void 22 system_print(Stack *s) 23 { 24 Uint8 i; 25 for(i = s->ptr - 8; i != (Uint8)(s->ptr); i++) 26 fprintf(stderr, "%02x%c", s->dat[i], i == 0xff ? '|' : ' '); 27 fprintf(stderr, "< \n"); 28 } 29 30 int 31 system_error(char *msg, const char *err) 32 { 33 fprintf(stderr, "%s: %s\n", msg, err), fflush(stderr); 34 return 0; 35 } 36 37 static int 38 system_load(Uint8 *ram, char *rom_path) 39 { 40 FILE *f = fopen(rom_path, "rb"); 41 if(f) { 42 int i = 0, l = fread(ram, 0x10000 - PAGE_PROGRAM, 1, f); 43 while(l && ++i < RAM_PAGES) 44 l = fread(ram + 0x10000 * i - PAGE_PROGRAM, 0x10000, 1, f); 45 fclose(f); 46 } 47 return !!f; 48 } 49 50 void 51 system_reboot(int soft) 52 { 53 int i; 54 for(i = soft ? 0x100 : 0; i < 0x10000; i++) uxn.ram[i] = 0; 55 for(i = 0x0; i < 0x100; i++) uxn.dev[i] = 0; 56 uxn.wst.ptr = uxn.rst.ptr = 0; 57 if(system_load(&uxn.ram[PAGE_PROGRAM], boot_path)) 58 uxn_eval(PAGE_PROGRAM); 59 } 60 61 int 62 system_boot(Uint8 *ram, char *rom_path) 63 { 64 uxn.ram = ram, boot_path = rom_path; 65 return system_load(uxn.ram + PAGE_PROGRAM, rom_path); 66 } 67 68 /* IO */ 69 70 Uint8 71 system_dei(Uint8 addr) 72 { 73 switch(addr) { 74 case 0x4: return uxn.wst.ptr; 75 case 0x5: return uxn.rst.ptr; 76 default: return uxn.dev[addr]; 77 } 78 } 79 80 void 81 system_deo(Uint8 port) 82 { 83 switch(port) { 84 case 0x3: { 85 Uint16 addr = PEEK2(uxn.dev + 2); 86 if(uxn.ram[addr] == 0x0) { 87 Uint16 i, value = uxn.ram[addr + 7], length = PEEK2(uxn.ram + addr + 1); 88 unsigned int dst_page = PEEK2(uxn.ram + addr + 3), dst_addr = PEEK2(uxn.ram + addr + 5); 89 unsigned int dst = dst_page * 0x10000; 90 if(dst_page < RAM_PAGES) 91 for(i = 0; i < length; i++) 92 uxn.ram[dst + (Uint16)(dst_addr + i)] = value; 93 } else if(uxn.ram[addr] == 0x1) { 94 Uint16 i, length = PEEK2(uxn.ram + addr + 1); 95 unsigned int a_page = PEEK2(uxn.ram + addr + 3), a_addr = PEEK2(uxn.ram + addr + 5); 96 unsigned int b_page = PEEK2(uxn.ram + addr + 7), b_addr = PEEK2(uxn.ram + addr + 9); 97 unsigned int src = a_page * 0x10000, dst = b_page * 0x10000; 98 if(a_page < RAM_PAGES && b_page < RAM_PAGES) 99 for(i = 0; i < length; i++) 100 uxn.ram[dst + (Uint16)(b_addr + i)] = uxn.ram[src + (Uint16)(a_addr + i)]; 101 } else if(uxn.ram[addr] == 0x2) { 102 Uint16 i, length = PEEK2(uxn.ram + addr + 1); 103 unsigned int a_page = PEEK2(uxn.ram + addr + 3), a_addr = PEEK2(uxn.ram + addr + 5); 104 unsigned int b_page = PEEK2(uxn.ram + addr + 7), b_addr = PEEK2(uxn.ram + addr + 9); 105 unsigned int src = a_page * 0x10000, dst = b_page * 0x10000; 106 if(a_page < RAM_PAGES && b_page < RAM_PAGES) 107 for(i = length - 1; i != 0xffff; i--) 108 uxn.ram[dst + (Uint16)(b_addr + i)] = uxn.ram[src + (Uint16)(a_addr + i)]; 109 } else 110 fprintf(stderr, "Unknown Expansion Command 0x%02x\n", uxn.ram[addr]); 111 break; 112 } 113 case 0x4: 114 uxn.wst.ptr = uxn.dev[4]; 115 break; 116 case 0x5: 117 uxn.rst.ptr = uxn.dev[5]; 118 break; 119 case 0xe: 120 fprintf(stderr, "WST "), system_print(&uxn.wst); 121 fprintf(stderr, "RST "), system_print(&uxn.rst); 122 break; 123 } 124 }