Standardized varvara boot
This commit is contained in:
parent
6ebc44baeb
commit
7dac87dcba
|
@ -24,6 +24,16 @@ console_input(Uxn *u, char c, int type)
|
||||||
return uxn_eval(u, PEEK2(d));
|
return uxn_eval(u, PEEK2(d));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
console_listen(Uxn *u, int i, int argc, char **argv)
|
||||||
|
{
|
||||||
|
for(; i < argc; i++) {
|
||||||
|
char *p = argv[i];
|
||||||
|
while(*p) console_input(u, *p++, CONSOLE_ARG);
|
||||||
|
console_input(u, '\n', i == argc - 1 ? CONSOLE_END : CONSOLE_EOA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
console_deo(Uint8 *d, Uint8 port)
|
console_deo(Uint8 *d, Uint8 port)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,4 +19,5 @@ WITH REGARD TO THIS SOFTWARE.
|
||||||
#define CONSOLE_END 0x4
|
#define CONSOLE_END 0x4
|
||||||
|
|
||||||
int console_input(Uxn *u, char c, int type);
|
int console_input(Uxn *u, char c, int type);
|
||||||
|
void console_listen(Uxn *u, int i, int argc, char **argv);
|
||||||
void console_deo(Uint8 *d, Uint8 port);
|
void console_deo(Uint8 *d, Uint8 port);
|
||||||
|
|
|
@ -38,7 +38,7 @@ screen_change(Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2)
|
||||||
if(y2 > uxn_screen.y2) uxn_screen.y2 = y2;
|
if(y2 > uxn_screen.y2) uxn_screen.y2 = y2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
screen_fill(Uint8 *layer, int x1, int y1, int x2, int y2, int color)
|
screen_fill(Uint8 *layer, int x1, int y1, int x2, int y2, int color)
|
||||||
{
|
{
|
||||||
int x, y, width = uxn_screen.width, height = uxn_screen.height;
|
int x, y, width = uxn_screen.width, height = uxn_screen.height;
|
||||||
|
|
|
@ -22,10 +22,12 @@ typedef struct UxnScreen {
|
||||||
extern UxnScreen uxn_screen;
|
extern UxnScreen uxn_screen;
|
||||||
extern int emu_resize(int width, int height);
|
extern int emu_resize(int width, int height);
|
||||||
|
|
||||||
|
void screen_fill(Uint8 *layer, int x1, int y1, int x2, int y2, int color);
|
||||||
void screen_palette(Uint8 *addr);
|
void screen_palette(Uint8 *addr);
|
||||||
void screen_resize(Uint16 width, Uint16 height);
|
void screen_resize(Uint16 width, Uint16 height);
|
||||||
void screen_change(Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2);
|
void screen_change(Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2);
|
||||||
void screen_redraw(void);
|
void screen_redraw(void);
|
||||||
void screen_debugger(Uxn *u);
|
void screen_debugger(Uxn *u);
|
||||||
|
|
||||||
Uint8 screen_dei(Uxn *u, Uint8 addr);
|
Uint8 screen_dei(Uxn *u, Uint8 addr);
|
||||||
void screen_deo(Uint8 *ram, Uint8 *d, Uint8 port);
|
void screen_deo(Uint8 *ram, Uint8 *d, Uint8 port);
|
||||||
|
|
|
@ -15,11 +15,27 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
WITH REGARD TO THIS SOFTWARE.
|
WITH REGARD TO THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
char *boot_rom;
|
||||||
|
|
||||||
static const char *errors[] = {
|
static const char *errors[] = {
|
||||||
"underflow",
|
"underflow",
|
||||||
"overflow",
|
"overflow",
|
||||||
"division by zero"};
|
"division by zero"};
|
||||||
|
|
||||||
|
static int
|
||||||
|
system_load(Uxn *u, char *filename)
|
||||||
|
{
|
||||||
|
int l, i = 0;
|
||||||
|
FILE *f = fopen(filename, "rb");
|
||||||
|
if(!f)
|
||||||
|
return 0;
|
||||||
|
l = fread(&u->ram[PAGE_PROGRAM], 0x10000 - PAGE_PROGRAM, 1, f);
|
||||||
|
while(l && ++i < RAM_PAGES)
|
||||||
|
l = fread(u->ram + 0x10000 * i, 0x10000, 1, f);
|
||||||
|
fclose(f);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
system_print(Stack *s, char *name)
|
system_print(Stack *s, char *name)
|
||||||
{
|
{
|
||||||
|
@ -32,19 +48,6 @@ system_print(Stack *s, char *name)
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
system_cmd(Uint8 *ram, Uint16 addr)
|
|
||||||
{
|
|
||||||
if(ram[addr] == 0x1) {
|
|
||||||
Uint16 i, length = PEEK2(ram + addr + 1);
|
|
||||||
Uint16 a_page = PEEK2(ram + addr + 1 + 2), a_addr = PEEK2(ram + addr + 1 + 4);
|
|
||||||
Uint16 b_page = PEEK2(ram + addr + 1 + 6), b_addr = PEEK2(ram + addr + 1 + 8);
|
|
||||||
int src = (a_page % RAM_PAGES) * 0x10000, dst = (b_page % RAM_PAGES) * 0x10000;
|
|
||||||
for(i = 0; i < length; i++)
|
|
||||||
ram[dst + (Uint16)(b_addr + i)] = ram[src + (Uint16)(a_addr + i)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
system_error(char *msg, const char *err)
|
system_error(char *msg, const char *err)
|
||||||
{
|
{
|
||||||
|
@ -53,20 +56,6 @@ system_error(char *msg, const char *err)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
system_load(Uxn *u, char *filename)
|
|
||||||
{
|
|
||||||
int l, i = 0;
|
|
||||||
FILE *f = fopen(filename, "rb");
|
|
||||||
if(!f)
|
|
||||||
return 0;
|
|
||||||
l = fread(&u->ram[PAGE_PROGRAM], 0x10000 - PAGE_PROGRAM, 1, f);
|
|
||||||
while(l && ++i < RAM_PAGES)
|
|
||||||
l = fread(u->ram + 0x10000 * i, 0x10000, 1, f);
|
|
||||||
fclose(f);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
system_inspect(Uxn *u)
|
system_inspect(Uxn *u)
|
||||||
{
|
{
|
||||||
|
@ -94,6 +83,32 @@ system_version(char *name, char *date)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
system_reboot(Uxn *u, char *rom, int soft)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i = 0x100 * soft; i < 0x10000; i++)
|
||||||
|
u->ram[i] = 0;
|
||||||
|
for(i = 0x0; i < 0x100; i++)
|
||||||
|
u->dev[i] = 0;
|
||||||
|
u->wst.ptr = 0;
|
||||||
|
u->rst.ptr = 0;
|
||||||
|
if(system_load(u, boot_rom))
|
||||||
|
if(uxn_eval(u, PAGE_PROGRAM))
|
||||||
|
boot_rom = rom;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
system_init(Uxn *u, Uint8 *ram, char *rom)
|
||||||
|
{
|
||||||
|
u->ram = ram;
|
||||||
|
if(!system_load(u, rom))
|
||||||
|
if(!system_load(u, "boot.rom"))
|
||||||
|
return system_error("Init", "Failed to load rom.");
|
||||||
|
boot_rom = rom;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* IO */
|
/* IO */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -101,13 +116,15 @@ system_deo(Uxn *u, Uint8 *d, Uint8 port)
|
||||||
{
|
{
|
||||||
switch(port) {
|
switch(port) {
|
||||||
case 0x3:
|
case 0x3:
|
||||||
system_cmd(u->ram, PEEK2(d + 2));
|
Uint8 *ram = u->ram;
|
||||||
break;
|
Uint16 addr = PEEK2(d + 2);
|
||||||
case 0x5:
|
if(ram[addr] == 0x1) {
|
||||||
if(PEEK2(d + 4)) {
|
Uint16 i, length = PEEK2(ram + addr + 1);
|
||||||
Uxn friend;
|
Uint16 a_page = PEEK2(ram + addr + 1 + 2), a_addr = PEEK2(ram + addr + 1 + 4);
|
||||||
uxn_boot(&friend, u->ram);
|
Uint16 b_page = PEEK2(ram + addr + 1 + 6), b_addr = PEEK2(ram + addr + 1 + 8);
|
||||||
uxn_eval(&friend, PEEK2(d + 4));
|
int src = (a_page % RAM_PAGES) * 0x10000, dst = (b_page % RAM_PAGES) * 0x10000;
|
||||||
|
for(i = 0; i < length; i++)
|
||||||
|
ram[dst + (Uint16)(b_addr + i)] = ram[src + (Uint16)(a_addr + i)];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xe:
|
case 0xe:
|
||||||
|
|
|
@ -15,9 +15,13 @@ WITH REGARD TO THIS SOFTWARE.
|
||||||
|
|
||||||
#define RAM_PAGES 0x10
|
#define RAM_PAGES 0x10
|
||||||
|
|
||||||
|
extern char *boot_rom;
|
||||||
|
|
||||||
void system_connect(Uint8 device, Uint8 ver, Uint16 dei, Uint16 deo);
|
void system_connect(Uint8 device, Uint8 ver, Uint16 dei, Uint16 deo);
|
||||||
int system_version(char *emulator, char *date);
|
void system_reboot(Uxn *u, char *rom, int soft);
|
||||||
int system_load(Uxn *u, char *filename);
|
|
||||||
void system_inspect(Uxn *u);
|
void system_inspect(Uxn *u);
|
||||||
|
int system_version(char *emulator, char *date);
|
||||||
int system_error(char *msg, const char *err);
|
int system_error(char *msg, const char *err);
|
||||||
|
int system_init(Uxn *u, Uint8 *ram, char *rom);
|
||||||
|
|
||||||
void system_deo(Uxn *u, Uint8 *d, Uint8 port);
|
void system_deo(Uxn *u, Uint8 *d, Uint8 port);
|
||||||
|
|
11
src/uxn.c
11
src/uxn.c
|
@ -117,14 +117,3 @@ uxn_eval(Uxn *u, Uint16 pc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
uxn_boot(Uxn *u, Uint8 *ram)
|
|
||||||
{
|
|
||||||
Uint32 i;
|
|
||||||
char *cptr = (char *)u;
|
|
||||||
for(i = 0; i < sizeof(*u); i++)
|
|
||||||
cptr[i] = 0;
|
|
||||||
u->ram = ram;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
|
@ -46,5 +46,4 @@ extern Uint16 dev_vers[0x10], dei_mask[0x10], deo_mask[0x10];
|
||||||
|
|
||||||
/* built-ins */
|
/* built-ins */
|
||||||
|
|
||||||
int uxn_boot(Uxn *u, Uint8 *ram);
|
|
||||||
int uxn_eval(Uxn *u, Uint16 pc);
|
int uxn_eval(Uxn *u, Uint16 pc);
|
||||||
|
|
41
src/uxn11.c
41
src/uxn11.c
|
@ -32,8 +32,6 @@ static Display *display;
|
||||||
static Visual *visual;
|
static Visual *visual;
|
||||||
static Window window;
|
static Window window;
|
||||||
|
|
||||||
char *rom_path;
|
|
||||||
|
|
||||||
#define WIDTH (64 * 8)
|
#define WIDTH (64 * 8)
|
||||||
#define HEIGHT (40 * 8)
|
#define HEIGHT (40 * 8)
|
||||||
#define PAD 2
|
#define PAD 2
|
||||||
|
@ -86,7 +84,8 @@ emu_resize(int width, int height)
|
||||||
static int
|
static int
|
||||||
emu_start(Uxn *u, char *rom)
|
emu_start(Uxn *u, char *rom)
|
||||||
{
|
{
|
||||||
|
(void)u;
|
||||||
|
(void)rom;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +143,7 @@ emu_event(Uxn *u)
|
||||||
u->dev[0x0e] = !u->dev[0x0e];
|
u->dev[0x0e] = !u->dev[0x0e];
|
||||||
if(sym == XK_F4)
|
if(sym == XK_F4)
|
||||||
if(!emu_start(u, "boot.rom"))
|
if(!emu_start(u, "boot.rom"))
|
||||||
emu_start(u, rom_path);
|
emu_start(u, boot_rom);
|
||||||
controller_down(u, &u->dev[0x80], get_button(sym));
|
controller_down(u, &u->dev[0x80], get_button(sym));
|
||||||
controller_key(u, &u->dev[0x80], sym < 0x80 ? sym : (Uint8)buf[0]);
|
controller_key(u, &u->dev[0x80], sym < 0x80 ? sym : (Uint8)buf[0]);
|
||||||
} break;
|
} break;
|
||||||
|
@ -176,6 +175,13 @@ emu_event(Uxn *u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
emu_init(void)
|
||||||
|
{
|
||||||
|
screen_resize(WIDTH, HEIGHT);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
emu_run(Uxn *u, char *rom)
|
emu_run(Uxn *u, char *rom)
|
||||||
{
|
{
|
||||||
|
@ -259,24 +265,15 @@ main(int argc, char **argv)
|
||||||
/* Read flags */
|
/* Read flags */
|
||||||
if(argv[i][0] == '-' && argv[i][1] == 'v')
|
if(argv[i][0] == '-' && argv[i][1] == 'v')
|
||||||
return system_version("Uxn11 - Graphical Varvara Emulator", "16 Aug 2023");
|
return system_version("Uxn11 - Graphical Varvara Emulator", "16 Aug 2023");
|
||||||
|
if(!emu_init())
|
||||||
rom_path = argv[1];
|
return system_error("Init", "Failed to initialize varvara.");
|
||||||
if(!uxn_boot(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8))))
|
if(!system_init(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8)), argv[i++]))
|
||||||
return system_error("boot", "Failed");
|
return system_error("Init", "Failed to initialize uxn.");
|
||||||
/* start sequence */
|
/* Game Loop */
|
||||||
screen_resize(WIDTH, HEIGHT);
|
u.dev[0x17] = argc - i;
|
||||||
|
if(uxn_eval(&u, PAGE_PROGRAM)) {
|
||||||
if(!system_load(&u, rom_path))
|
console_listen(&u, i, argc, argv);
|
||||||
return 0;
|
emu_run(&u, boot_rom);
|
||||||
if(!uxn_eval(&u, PAGE_PROGRAM))
|
|
||||||
return system_error("boot", "Failed to start rom.");
|
|
||||||
|
|
||||||
/* console vector */
|
|
||||||
for(i = 2; i < argc; i++) {
|
|
||||||
char *p = argv[i];
|
|
||||||
while(*p) console_input(&u, *p++, CONSOLE_ARG);
|
|
||||||
console_input(&u, '\n', i == argc ? CONSOLE_END : CONSOLE_EOA);
|
|
||||||
}
|
}
|
||||||
emu_run(&u, rom_path);
|
|
||||||
return emu_end(&u);
|
return emu_end(&u);
|
||||||
}
|
}
|
||||||
|
|
42
src/uxncli.c
42
src/uxncli.c
|
@ -41,6 +41,23 @@ emu_deo(Uxn *u, Uint8 addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emu_run(Uxn *u)
|
||||||
|
{
|
||||||
|
while(!u->dev[0x0f]) {
|
||||||
|
int c = fgetc(stdin);
|
||||||
|
if(c == EOF) break;
|
||||||
|
console_input(u, (Uint8)c, CONSOLE_STD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
emu_end(Uxn *u)
|
||||||
|
{
|
||||||
|
free(u->ram);
|
||||||
|
return u->dev[0x0f] & 0x7f;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
@ -56,27 +73,14 @@ main(int argc, char **argv)
|
||||||
system_connect(0xc, DATETIME_VERSION, DATETIME_DEIMASK, DATETIME_DEOMASK);
|
system_connect(0xc, DATETIME_VERSION, DATETIME_DEIMASK, DATETIME_DEOMASK);
|
||||||
/* Read flags */
|
/* Read flags */
|
||||||
if(argv[i][0] == '-' && argv[i][1] == 'v')
|
if(argv[i][0] == '-' && argv[i][1] == 'v')
|
||||||
return system_version("Uxncli - Console Varvara Emulator", "9 Aug 2023");
|
return system_version("Uxncli - Console Varvara Emulator", "15 Aug 2023");
|
||||||
/* Continue.. */
|
if(!system_init(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8)), argv[i++]))
|
||||||
if(!uxn_boot(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8))))
|
return system_error("Init", "Failed to initialize uxn.");
|
||||||
return system_error("Boot", "Failed");
|
|
||||||
/* Load rom */
|
|
||||||
if(!system_load(&u, argv[i++]))
|
|
||||||
return system_error("Load", "Failed");
|
|
||||||
/* Game Loop */
|
/* Game Loop */
|
||||||
u.dev[0x17] = argc - i;
|
u.dev[0x17] = argc - i;
|
||||||
if(uxn_eval(&u, PAGE_PROGRAM)) {
|
if(uxn_eval(&u, PAGE_PROGRAM)) {
|
||||||
for(; i < argc; i++) {
|
console_listen(&u, i, argc, argv);
|
||||||
char *p = argv[i];
|
emu_run(&u);
|
||||||
while(*p) console_input(&u, *p++, CONSOLE_ARG);
|
|
||||||
console_input(&u, '\n', i == argc - 1 ? CONSOLE_END : CONSOLE_EOA);
|
|
||||||
}
|
}
|
||||||
while(!u.dev[0x0f]) {
|
return emu_end(&u);
|
||||||
int c = fgetc(stdin);
|
|
||||||
if(c == EOF) break;
|
|
||||||
console_input(&u, (Uint8)c, CONSOLE_STD);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(u.ram);
|
|
||||||
return u.dev[0x0f] & 0x7f;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue