/* Receive one byte from the serial bus. */ int serial_trap_receive(void) { BYTE data; if (serial_truedrive && ((TrapDevice & 0x0f) != 4) && ((TrapDevice & 0x0f) != 5)) { return 0; } data = serial_iec_bus_read(TrapDevice, TrapSecondary, serial_set_st); mem_store(tmp_in, data); /* If at EOF, call specified callback function. */ if ((serial_get_st() & 0x40) && eof_callback_func != NULL) { eof_callback_func(); } /* Set registers like the Kernal routine does. */ MOS6510_REGS_SET_A(&maincpu_regs, data); MOS6510_REGS_SET_SIGN(&maincpu_regs, (data & 0x80) ? 1 : 0); MOS6510_REGS_SET_ZERO(&maincpu_regs, data ? 0 : 1); MOS6510_REGS_SET_CARRY(&maincpu_regs, 0); MOS6510_REGS_SET_INTERRUPT(&maincpu_regs, 0); return 1; }
/* Flush pending characters into the kernal's queue if possible. */ void kbdbuf_flush(void) { unsigned int i, n; if ((!kbd_buf_enabled) || num_pending == 0 || maincpu_clk < kernal_init_cycles || !kbdbuf_is_empty()) return; n = num_pending > buffer_size ? buffer_size : num_pending; for (i = 0; i < n; head_idx = (head_idx + 1) % QUEUE_SIZE, i++) mem_store((WORD)(buffer_location + i), queue[head_idx]); mem_store((WORD)(num_pending_location), (BYTE)(n)); num_pending -= n; }
/* Flash load body routine replacement. */ int flash_trap_load_body(void) { DWORD addr; BYTE laddr, maddr, haddr; /* bail out if true fs, not emulated */ if (flash_trap_trueflashfs) { return 0; } /* start address */ addr = mem_read(0xFB) | (mem_read(0xFC) << 8) | (mem_read(0xFD) << 16); /* load */ if (fi) { BYTE b; while (fileio_read(fi, &b, 1)) { mem_ram[addr & 0x1FFFFF] = b; addr++; } fileio_close(fi); fi = NULL; } /* set exit values for success and return */ laddr = (BYTE)(addr & 0xff); maddr = (BYTE)((addr >> 8) & 0xff); haddr = (BYTE)((addr >> 16) & 0xff); mem_store((WORD)0xFB, laddr); mem_store((WORD)0xFC, maddr); mem_store((WORD)0xFD, haddr); maincpu_set_x(laddr); maincpu_set_y(maddr); mem_store((WORD)0xAE, laddr); mem_store((WORD)0xAF, maddr); return 1; }
sval_t sval_symbol(struct vm *vm, const char *name, word_t namelen) { sval_t sym; vaddr_t vaddr; word_t len; int i; char *cp; for (i = 0; allsymbols[i] != 0; i++) { sym = allsymbols[i]; len = sval_symbol_length(vm, sym); cp = mem_sval_to_ptr(vm, sym, WORDSIZE); if (namelen == len && memcmp(name, cp, len) == 0) return sym; } len = WORDSIZE + WORDWRAP(namelen); vaddr = mem_allocate(vm, len); mem_store(vm, vaddr, namelen); memcpy(mem_vaddr_to_ptr(vm, vaddr, WORDSIZE), name, namelen); sym = vaddr | 0x03; allsymbols[i] = sym; return sym; }
/** * Opens the references file, reads in each line, and dispatches the commands * specified as appropriate to the CPU and OS modules. */ void sim_readdata(void) { FILE *fp; char buff[512]; if ((fp = fopen(filename, "r")) == NULL) { PERROR(filename); exit(EXIT_FAILURE); } /* For each line in the file... */ while (fgets(buff, sizeof(buff), fp) != NULL) { char *cmd, *arg1, *arg2, *arg3; int pid; vaddr_t addr; word_t val, val2; /* Parse command and possible arguments */ cmd = strtok(buff, WHITESPACE); arg1 = strtok(NULL, WHITESPACE); arg2 = strtok(NULL, WHITESPACE); arg3 = strtok(NULL, WHITESPACE); switch (cmd[0]) { /* Create a new process */ case '@': pid = atoi(arg1); if (pid < max_jobs) { printf("Forking new process %s. Assigning pid: %d.\n\n", arg2, pid); proc_fork(pid, arg2); } else { printf("Too many jobs, not forking new process!\n"); } break; /* Load from a memory location */ case 'l': pid = atoi(arg1); addr = atoi(arg2); val = atoi(arg3) % 256; if (pid >= max_jobs) { break; } else if (current == NULL || current->pid != pid) { printf("===================================================\n"); printf("Switching to process: %s. Corresponding pid: %d.\n", proc_getname(pid), pid); printf("===================================================\n\n"); proc_switch(pid); } val2 = mem_load(addr); printf("Value Loaded: %d\n", val2); if (val2 != val) { printf(" ERROR! loaded value did not equal expected!\nValue Expected: %d\n\n", val); /* XXX: Dump a mem image here and quit */ } else { printf("Complete\n\n"); } break; /* Store to a memory location */ case 's': pid = atoi(arg1); addr = atoi(arg2); val = atoi(arg3) % 256; if (pid >= max_jobs) { break; } else if (current == NULL || current->pid != pid) { printf("===================================================\n"); printf("Switching to process: %s. Corresponding pid: %d.\n", proc_getname(pid), pid); printf("===================================================\n\n"); proc_switch(pid); } mem_store(addr, val); printf("Complete\n\n"); /* Ignore other commands (for comments and the like */ default: break; } } fclose(fp); }
/* Flash seek next routine replacement. Create valid directory entry at $0100 */ int flash_trap_seek_next(void) { unsigned int i; BYTE direntry[0x20]; DWORD entry; /* bail out if true fs, not emulated */ if (flash_trap_trueflashfs) { return 0; } /* if we are reading the very first entry in the flash, do initialization stuff. */ entry = mem_read(0xF8) | (mem_read(0xF9) << 8) | (mem_read(0xFA) << 16); if (entry == 0x010000) { read_name_from_mem(); if (name_len == 0) { /* the missing filename detection of the original kernal requires at least one valid entry to work. */ name_len = 5; memcpy(name, "DUMMY", 5); seek_state = ST_ENTRY; } else { char *path = flash_trap_fsflashdir; if (!strlen(path)) { path = NULL; } /* open file */ if (fi) { fileio_close(fi); } fi = fileio_open(name, path, FILEIO_FORMAT_RAW, FILEIO_COMMAND_READ, FILEIO_TYPE_ANY); if (fi) { BYTE addr[2]; fileio_read(fi, addr, 2); load_addr = addr[0] | (addr[1] << 8); seek_state = ST_ENTRY; } else { seek_state = ST_END; } } } switch (seek_state) { case ST_ENTRY: memset(direntry, 0x00, sizeof(direntry)); /* copy the actual searched name to force a match */ memcpy(direntry, name, name_len); /* flash_address */ direntry[0x18] = 0x11; direntry[0x19] = 0x10; direntry[0x1A] = 0x02; /* load_address */ direntry[0x1B] = (BYTE)(load_addr & 0xff); direntry[0x1C] = (BYTE)((load_addr >> 8) & 0xff); direntry[0x1D] = (BYTE)((load_addr >> 16) & 0xff); /* sys_address (non-standard) */ direntry[0x1E] = 0x00; direntry[0x1F] = 0x00; seek_state = ST_END; break; case ST_END: memset(direntry, 0x00, sizeof(direntry)); seek_state = ST_EMPTY; break; default: case ST_EMPTY: memset(direntry, 0xFF, sizeof(direntry)); break; } /* write out directory entry to the buffer at $0100-$011F */ for (i = 0; i < sizeof(direntry); i++) { mem_store((WORD)(0x0100 + i), direntry[i]); } return 1; }
static inline void set_st(BYTE b) { mem_store(st_addr, (BYTE)(mem_read(st_addr) | b)); }
static void serial_set_st(BYTE st) { mem_store((WORD)0x90, (BYTE)(mem_read((WORD)0x90) | st)); }