uxn

Varvara Ordinator, written in ANSI C(SDL2)
git clone https://git.eamoncaddigan.net/uxn.git
Log | Files | Refs | README | LICENSE

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 }