#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)
{
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);
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;
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)
{
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;
{
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;
#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;
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;
}