📄 mem.c
字号:
{ RAISE_EXCEPTION (IBUS_EXCPT, BadVAddr = addr); SET_MEM_WORD (addr, ENCODING (inst));}#ifdef __STDC__mem_wordbad_mem_read (mem_addr addr, int mask, mem_word *dest)#elsemem_wordbad_mem_read (addr, mask, dest) mem_addr addr; int mask; mem_word *dest;#endif{ mem_word tmp; if (addr & mask) RAISE_EXCEPTION (ADDRL_EXCPT, BadVAddr = addr) else if (addr >= TEXT_BOT && addr < text_top) switch (mask) { case 0x0: tmp = ENCODING (text_seg [(addr - TEXT_BOT) >> 2]);#ifdef BIGENDIAN tmp = (unsigned)tmp >> (8 * (3 - (addr & 0x3)));#else tmp = (unsigned)tmp >> (8 * (addr & 0x3));#endif return (0xff & tmp); case 0x1: tmp = ENCODING (text_seg [(addr - TEXT_BOT) >> 2]);#ifdef BIGENDIAN tmp = (unsigned)tmp >> (8 * (2 - (addr & 0x2)));#else tmp = (unsigned)tmp >> (8 * (addr & 0x2));#endif return (0xffff & tmp); case 0x3: { instruction *inst = text_seg [(addr - TEXT_BOT) >> 2]; if (inst == NULL) return 0; else return (ENCODING (inst)); } default: run_error ("Bad mask (0x%x) in bad_mem_read\n", mask); } else if (addr > data_top && addr < stack_bot /* If more than 16 MB below stack, probably is bad data ref */ && addr > stack_bot - 16*K*K) { /* Grow stack segment */ expand_stack (stack_bot - addr + 4); *dest = 0; /* Newly allocated memory */ return (0); } else if (MM_IO_BOT <= addr && addr <= MM_IO_TOP) return (read_memory_mapped_IO (addr)); else /* Address out of range */ RAISE_EXCEPTION (DBUS_EXCPT, BadVAddr = addr) return (0);}#ifdef __STDC__voidbad_mem_write (mem_addr addr, mem_word value, int mask)#elsevoidbad_mem_write (addr, value, mask) mem_addr addr; mem_word value; int mask;#endif{ mem_word tmp; if (addr & mask) /* Unaligned address fault */ RAISE_EXCEPTION (ADDRS_EXCPT, BadVAddr = addr) else if (addr >= TEXT_BOT && addr < text_top) { switch (mask) { case 0x0: tmp = ENCODING (text_seg [(addr - TEXT_BOT) >> 2]);#ifdef BIGENDIAN tmp = ((tmp & ~(0xff << (8 * (3 - (addr & 0x3))))) | (value & 0xff) << (8 * (3 - (addr & 0x3))));#else tmp = ((tmp & ~(0xff << (8 * (addr & 0x3)))) | (value & 0xff) << (8 * (addr & 0x3)));#endif text_seg [(addr - TEXT_BOT) >> 2] = inst_decode (tmp); break; case 0x1: tmp = ENCODING (text_seg [(addr - TEXT_BOT) >> 2]);#ifdef BIGENDIAN tmp = ((tmp & ~(0xffff << (8 * (2 - (addr & 0x2))))) | (value & 0xffff) << (8 * (2 - (addr & 0x2))));#else tmp = ((tmp & ~(0xffff << (8 * (addr & 0x2)))) | (value & 0xffff) << (8 * (addr & 0x2)));#endif text_seg [(addr - TEXT_BOT) >> 2] = inst_decode (tmp); break; case 0x3: text_seg [(addr - TEXT_BOT) >> 2] = inst_decode (value); break; default: run_error ("Bad mask (0x%x) in bad_mem_read\n", mask); } text_modified = 1; } else if (addr > data_top && addr < stack_bot /* If more than 16 MB below stack, probably is bad data ref */ && addr > stack_bot - 16*K*K) { /* Grow stack segment */ expand_stack (stack_bot - addr + 4); if (addr >= stack_bot) { if (mask == 0) stack_seg_b [addr - stack_bot] = (char)value; else if (mask == 1) stack_seg_h [(addr - stack_bot) >> 1] = (short)value; else stack_seg [(addr - stack_bot) >> 2] = value; } else RAISE_EXCEPTION (DBUS_EXCPT, BadVAddr = addr) data_modified = 1; } else if (MM_IO_BOT <= addr && addr <= MM_IO_TOP) write_memory_mapped_IO (addr, value); else /* Address out of range */ RAISE_EXCEPTION (DBUS_EXCPT, BadVAddr = addr)}/* Memory-mapped IO routines: */static long recv_control, recv_buffer, recv_buffer_filled;static long trans_control, trans_buffer, trans_buffer_filled;/* Every IO_INTERVAL time steps, check if input is available and output is possible. If so, update the control registers and buffers. */#ifdef __STDC__voidcheck_memory_mapped_IO (void)#elsevoidcheck_memory_mapped_IO ()#endif{ static long mm_io_initialized = 0; if (!mm_io_initialized) { recv_control = RECV_READY; trans_control = TRANS_READY; mm_io_initialized = 1; } if (console_input_available ()) { recv_buffer_filled -= IO_INTERVAL; if (recv_buffer_filled <= 0) { recv_buffer = get_console_char (); recv_control |= RECV_READY; recv_buffer_filled = RECV_LATENCY; if ((recv_control & RECV_INT_ENABLE) && INTERRUPTS_ON && (Status_Reg & RECV_INT_MASK)) RAISE_EXCEPTION (INT_EXCPT, Cause |= RECV_INT_MASK); } } else if (recv_buffer_filled <= 0) recv_control &= ~RECV_READY; if (trans_buffer_filled > 0) { trans_buffer_filled -= IO_INTERVAL; if (trans_buffer_filled <= 0) { put_console_char ((char)trans_buffer); trans_control |= TRANS_READY; trans_buffer_filled = 0; if ((trans_control & TRANS_INT_ENABLE) && INTERRUPTS_ON && (Status_Reg & TRANS_INT_MASK)) RAISE_EXCEPTION (INT_EXCPT, Cause |= TRANS_INT_MASK) } }}/* Invoked on a write in the memory-mapped IO area. */#ifdef __STDC__static voidwrite_memory_mapped_IO (mem_addr addr, mem_word value)#elsestatic voidwrite_memory_mapped_IO (addr, value) mem_addr addr; mem_word value;#endif{ switch (addr) { case TRANS_CTRL_ADDR: trans_control = ((trans_control & ~TRANS_INT_ENABLE) | (value & TRANS_INT_ENABLE)); if ((trans_control & TRANS_READY) && (trans_control & TRANS_INT_ENABLE) && INTERRUPTS_ON && (Status_Reg & TRANS_INT_MASK)) /* Raise an interrupt immediately on enabling a ready xmitter */ RAISE_EXCEPTION (INT_EXCPT, Cause |= TRANS_INT_MASK) break; case TRANS_BUFFER_ADDR: if (trans_control & TRANS_READY) /* Ignore if not ready */ { trans_buffer = value & 0xff; trans_control &= ~TRANS_READY; trans_buffer_filled = TRANS_LATENCY; } break; case RECV_CTRL_ADDR: recv_control = ((recv_control & ~RECV_INT_ENABLE) | (value & RECV_INT_ENABLE)); break; case RECV_BUFFER_ADDR: break; default: run_error ("Write to unused memory-mapped IO address (0x%x)\n", addr); }}/* Invoked on a read in the memory-mapped IO area. */#ifdef __STDC__static mem_wordread_memory_mapped_IO (mem_addr addr)#elsestatic mem_wordread_memory_mapped_IO (addr) mem_addr addr;#endif{ switch (addr) { case TRANS_CTRL_ADDR: return (trans_control); case TRANS_BUFFER_ADDR: return (trans_buffer & 0xff); case RECV_CTRL_ADDR: return (recv_control); case RECV_BUFFER_ADDR: recv_control &= ~RECV_READY; recv_buffer_filled = 0; return (recv_buffer & 0xff); default: run_error ("Read from unused memory-mapped IO address (0x%x)\n", addr); return (0); }}/* Misc. routines */#ifdef __STDC__voidprint_mem (mem_addr addr)#elsevoidprint_mem (addr) mem_addr addr;#endif{ mem_word value; if (addr & 0x3) addr &= ~0x3; /* Address must be word-aligned */ if (TEXT_BOT <= addr && addr < text_top) print_inst (addr); else if (DATA_BOT <= addr && addr < data_top) { READ_MEM_WORD (value, addr); write_output (message_out, "Data seg @ 0x%08x (%d) = 0x%08x (%d)\n", addr, addr, value, value); } else if (stack_bot <= addr && addr < STACK_TOP) { READ_MEM_WORD (value, addr); write_output (message_out, "Stack seg @ 0x%08x (%d) = 0x%08x (%d)\n", addr, addr, value, value); } else if (K_TEXT_BOT <= addr && addr < k_text_top) print_inst (addr); else if (K_DATA_BOT <= addr && addr < k_data_top) { READ_MEM_WORD (value, addr); write_output (message_out, "Kernel Data seg @ 0x%08x (%d) = 0x%08x (%d)\n", addr, addr, value, value); } else error ("Address 0x%08x (%d) to print_mem is out of bounds\n", addr, addr);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -