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