From d87b1e06771aeb63ff43f5a289b19563d9af0eb0 Mon Sep 17 00:00:00 2001 From: Aaron Taylor Date: Thu, 8 Jul 2021 17:18:01 -0700 Subject: [PATCH] Trimmed down NEDsim to a single CPU, single thread, 64MB RAM, 64k element stack, no SLU, and no MVSTCK syllable (and still no CMPSWP syllable). --- hacks/NEDsim/NEDsim.c | 10 ++++- hacks/NEDsim/simulator.c | 85 +++++++--------------------------------- hacks/NEDsim/simulator.h | 15 +++---- 3 files changed, 29 insertions(+), 81 deletions(-) diff --git a/hacks/NEDsim/NEDsim.c b/hacks/NEDsim/NEDsim.c index 2b576f0..73c72f9 100644 --- a/hacks/NEDsim/NEDsim.c +++ b/hacks/NEDsim/NEDsim.c @@ -677,8 +677,16 @@ NEDsim_event(Display * dpy, Window win, void * closure, XEvent * event) static void NEDsim_free(Display * dpy, Window win, void * closure) { - // TODO: Replace all this with proper code to free everything. struct NEDsim * nedsim = closure; + + if (nedsim->nedstate != NULL) { + free(nedsim->nedstate->active_thread->psw); + free(nedsim->nedstate->active_thread); + free(nedsim->nedstate->hack); + free(nedsim->nedstate); + } + + // TODO: Replace all this with proper code to free everything related to the screensaver itself. XFreeGC(nedsim->dpy, nedsim->gc); free(nedsim); } diff --git a/hacks/NEDsim/simulator.c b/hacks/NEDsim/simulator.c index 4857946..f5c56ee 100644 --- a/hacks/NEDsim/simulator.c +++ b/hacks/NEDsim/simulator.c @@ -27,26 +27,6 @@ #include "a.out.h" #include "simulator.h" -int -is_stdin_nonempty(void) -{ - fd_set read_fds; - FD_ZERO(&read_fds); - FD_SET(STDIN_FILENO, &read_fds); - - struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = 0; - - int retval = select(1, &read_fds, NULL, NULL, &timeout); - - if (retval == -1) { - /* TODO: How do I want to handle this error? */ - } - - return retval; -} - uint32_t generate_binary_psw(struct NEDstate * state) { @@ -59,29 +39,21 @@ generate_binary_psw(struct NEDstate * state) void ram_w_byte(struct NEDstate * state, uint32_t address, uint8_t data) { - state->ram[address] = data; + state->ram[address-RAM_BASE_ADDRESS] = data; } uint8_t ram_r_byte(struct NEDstate * state, uint32_t address) { - return state->ram[address]; + return state->ram[address-RAM_BASE_ADDRESS]; } /* For now, with only a terminal for IO, we pick off IO requests when accessing RAM. */ -/* TODO: Improve this before adding any other IO devices like disks. */ void ram_w_word(struct NEDstate * state, uint32_t address, uint32_t data) { - /* TODO: Since PC and PSW are memory mapped, they should accept writes. */ - /* Should writes to the PC automatically reset the syllable counter? */ - if (address == 0x8000000) { /* SLU: XBUF */ - printf("%c", data); - fflush(stdout); - } else if (address == 0x0 || address == 0x4) { - /* Intentionally empty */ - } else if (address >= 0x20000000) { + if (address >= RAM_BASE_ADDRESS) { for (int i=3; i>=0; i--) { uint8_t tmp_byte = ((data >> (8*(3-i))) & 0xff); ram_w_byte(state,address+i,tmp_byte); @@ -100,23 +72,7 @@ ram_r_word(struct NEDstate * state, uint32_t address) return state->active_thread->pc; } else if (address == 0xC) { /* PSW register */ return generate_binary_psw(state); - } else if (address == 0x8000004) { /* SLU: XCSR */ - /* TODO: Should I artificially restrict printing in the simulator? */ - /* It might help catch bugs like the GCC bug that slipped past SIMH. */ - return 0b1; - } else if (address == 0x8000008) { /* SLU: RBUF */ - if (is_stdin_nonempty()) { - return getchar(); - } else { - return (uint8_t)rand(); - } - } else if (address == 0x800000C) { /* SLU: RCSR */ - if (is_stdin_nonempty()) { - return 0b1; - } else { - return 0b0; - } - } else if (address >= 0x20000000) { /* RAM */ + } else if (address >= RAM_BASE_ADDRESS) { /* RAM */ uint32_t word = 0; for (int i=0; i<4; i++) word |= (ram_r_byte(state,address+i)) << (8*(3-i)); return word; @@ -214,18 +170,6 @@ ned_instruction_add(struct NEDstate * state) set_psw_flags(stack_r(state->active_thread,0), state); } -void -ned_instruction_mvstck(struct NEDstate * state) -{ - uint32_t new_id = stack_pop(state->active_thread); - if (new_id < THREAD_COUNT) { - state->active_thread = state->thread[new_id]; - } else { - printf("ERROR: Attempted MVSTCK to ID higher than THREAD_COUNT.\n"); - state->halted = true; - } -} - void ned_instruction_shift(struct NEDstate * state) { @@ -319,9 +263,9 @@ execute_syllable(struct NEDstate * state, enum syllables syllable) case NOT: ned_instruction_not(state); break; case XOR: ned_instruction_xor(state); break; case ADD: ned_instruction_add(state); break; - case MVSTCK: ned_instruction_mvstck(state); break; + case MVSTCK: /* Intentionally blank */ break; case SHIFT: ned_instruction_shift(state); break; - case CMPSWP: /* TODO */ break; + case CMPSWP: /* Intentionally blank */ break; case TEST: ned_instruction_test(state); break; case JMP: ned_instruction_jmp(state); break; case SWAP: ned_instruction_swap(state); break; @@ -439,17 +383,15 @@ init_simulator(void) { struct NEDstate * state = malloc(sizeof(struct NEDstate)); state->hack = malloc(sizeof(struct NEDhack)); - for (size_t i=0; i < THREAD_COUNT; i++) { - state->thread[i] = malloc(sizeof(struct NEDthread)); - state->thread[i]->psw = malloc(sizeof(struct NEDpsw)); - } + state->thread[0] = malloc(sizeof(struct NEDthread)); + state->thread[0]->psw = malloc(sizeof(struct NEDpsw)); state->thread[0]->pc = 0; state->thread[0]->sc = 0; state->thread[0]->sp = 0; state->thread[0]->psw->zero = false; state->thread[0]->psw->negative = false; - state->thread[0]->pc = 0x20000000; /* Data region starts 512 MB into address space. */ - state->active_thread = state->thread[0]; /* By convention, use thread 0 for init. */ + state->thread[0]->pc = RAM_BASE_ADDRESS; + state->active_thread = state->thread[0]; state->halted = false; state->hack->resume_word = false; @@ -457,7 +399,6 @@ init_simulator(void) #define AOUT_PATH "./test.out" /* Load an initial image into memory. */ - uint32_t address = 0x20000000; struct exec aout_exec; struct nlist * symbol_table; uint32_t symbol_count; @@ -466,8 +407,12 @@ init_simulator(void) fprintf(stderr, "ERROR: %s: %s\n", AOUT_PATH, strerror(errno)); state->halted = true; } - parse_aout_file(input, &aout_exec, &(state->ram[address]), &symbol_table, &symbol_count); + parse_aout_file(input, &aout_exec, state->ram, &symbol_table, &symbol_count); fclose(input); + for (size_t i=0; i < symbol_count; i++) { + free(symbol_table[i].n_un.n_name); + } + free(symbol_table); return state; } diff --git a/hacks/NEDsim/simulator.h b/hacks/NEDsim/simulator.h index 927f73b..971e76c 100644 --- a/hacks/NEDsim/simulator.h +++ b/hacks/NEDsim/simulator.h @@ -22,20 +22,15 @@ #include "./a.out.h" -// TODO: Can get rid of this since I don't do a show_usage() anymore? -#define VERSION 5 - /* Bytes per word. */ #define BPW 4 /* Number of stack words. */ -#define STACK_LENGTH 1048576 +#define STACK_LENGTH 65536 /* Number of bytes of RAM. */ -#define RAM_LENGTH 1073741824 - -/* Number of hardware threads. */ -#define THREAD_COUNT 8 +#define RAM_LENGTH 67108864 +#define RAM_BASE_ADDRESS 0x20000000 /* Number of syllables per word. */ #define SPW 5 @@ -58,11 +53,11 @@ struct NEDhack { bool resume_word; }; -// TODO: Make this a single thread before committing. Multi-thread is broken with my current main loop. struct NEDstate { bool halted; uint8_t ram[RAM_LENGTH]; - struct NEDthread * thread[THREAD_COUNT]; + /* Although NED is multi-threaded, this screensaver is restricted to a single thread. */ + struct NEDthread * thread[1]; struct NEDthread * active_thread; struct NEDhack * hack; }; -- 2.20.1