📄 erc32.c
字号:
static int32mec_read(addr, asi, data) uint32 addr; uint32 asi; uint32 *data;{ switch (addr & 0x0ff) { case MEC_MCR: /* 0x00 */ *data = mec_mcr; break; case MEC_MEMCFG: /* 0x10 */ *data = mec_memcfg; break; case MEC_IOCR: *data = mec_iocr; /* 0x14 */ break; case MEC_SSA1: /* 0x20 */ *data = mec_ssa[0] | (mec_wpr[0] << 23); break; case MEC_SEA1: /* 0x24 */ *data = mec_sea[0]; break; case MEC_SSA2: /* 0x28 */ *data = mec_ssa[1] | (mec_wpr[1] << 23); break; case MEC_SEA2: /* 0x2c */ *data = mec_sea[1]; break; case MEC_ISR: /* 0x44 */ *data = mec_isr; break; case MEC_IPR: /* 0x48 */ *data = mec_ipr; break; case MEC_IMR: /* 0x4c */ *data = mec_imr; break; case MEC_IFR: /* 0x54 */ *data = mec_ifr; break; case MEC_RTC_COUNTER: /* 0x80 */ *data = rtc_counter_read(); break; case MEC_RTC_SCALER: /* 0x84 */ if (rtc_enabled) *data = rtc_scaler - (now() - rtc_scaler_start); else *data = rtc_scaler; break; case MEC_GPT_COUNTER: /* 0x88 */ *data = gpt_counter_read(); break; case MEC_GPT_SCALER: /* 0x8c */ if (rtc_enabled) *data = gpt_scaler - (now() - gpt_scaler_start); else *data = gpt_scaler; break; case MEC_SFSR: /* 0xA0 */ *data = mec_sfsr; break; case MEC_FFAR: /* 0xA4 */ *data = mec_ffar; break; case SIM_LOAD: fname[find] = 0; if (find == 0) strcpy(fname, "simload"); find = bfd_load(fname); if (find == -1) *data = 0; else *data = 1; find = 0; break; case MEC_ERSR: /* 0xB0 */ *data = mec_ersr; break; case MEC_TCR: /* 0xD0 */ *data = mec_tcr; break; case MEC_UARTA: /* 0xE0 */ case MEC_UARTB: /* 0xE4 */ if (asi != 0xb) { set_sfsr(MEC_ACC, addr, asi, 1); return (1); } *data = read_uart(addr); break; case MEC_UART_CTRL: /* 0xE8 */ *data = read_uart(addr); break; default: set_sfsr(MEC_ACC, addr, asi, 1); return (1); break; } return (MOK);}static intmec_write(addr, data) uint32 addr; uint32 data;{ if (sis_verbose > 1) printf("MEC write a: %08x, d: %08x\n",addr,data); switch (addr & 0x0ff) { case MEC_MCR: mec_mcr = data; decode_mcr(); if (mec_mcr & 0x08000) mecparerror(); break; case MEC_SFR: if (mec_mcr & 0x2) { sys_reset(); mec_ersr = 0x4000; if (sis_verbose) printf(" Software reset issued\n"); } break; case MEC_IOCR: mec_iocr = data; if (mec_iocr & 0xC0C0C0C0) mecparerror(); break; case MEC_SSA1: /* 0x20 */ if (data & 0xFE000000) mecparerror(); mec_ssa[0] = data & 0x7fffff; mec_wpr[0] = (data >> 23) & 0x03; mem_accprot = mec_wpr[0] || mec_wpr[1]; if (sis_verbose && mec_wpr[0]) printf("Segment 1 memory protection enabled (0x02%06x - 0x02%06x)\n", mec_ssa[0] << 2, mec_sea[0] << 2); break; case MEC_SEA1: /* 0x24 */ if (data & 0xFF800000) mecparerror(); mec_sea[0] = data & 0x7fffff; break; case MEC_SSA2: /* 0x28 */ if (data & 0xFE000000) mecparerror(); mec_ssa[1] = data & 0x7fffff; mec_wpr[1] = (data >> 23) & 0x03; mem_accprot = mec_wpr[0] || mec_wpr[1]; if (sis_verbose && mec_wpr[1]) printf("Segment 2 memory protection enabled (0x02%06x - 0x02%06x)\n", mec_ssa[1] << 2, mec_sea[1] << 2); break; case MEC_SEA2: /* 0x2c */ if (data & 0xFF800000) mecparerror(); mec_sea[1] = data & 0x7fffff; break; case MEC_UARTA: case MEC_UARTB: if (data & 0xFFFFFF00) mecparerror(); case MEC_UART_CTRL: if (data & 0xFF00FF00) mecparerror(); write_uart(addr, data); break; case MEC_GPT_RELOAD: gpt_reload_set(data); break; case MEC_GPT_SCALER: if (data & 0xFFFF0000) mecparerror(); gpt_scaler_set(data); break; case MEC_TIMER_CTRL: if (data & 0xFFFFF0F0) mecparerror(); timer_ctrl(data); break; case MEC_RTC_RELOAD: rtc_reload_set(data); break; case MEC_RTC_SCALER: if (data & 0xFFFFFF00) mecparerror(); rtc_scaler_set(data); break; case MEC_SFSR: /* 0xA0 */ if (data & 0xFFFF0880) mecparerror(); mec_sfsr = 0x78; break; case MEC_ISR: if (data & 0xFFFFE000) mecparerror(); mec_isr = data; break; case MEC_IMR: /* 0x4c */ if (data & 0xFFFF8001) mecparerror(); mec_imr = data & 0x7ffe; chk_irq(); break; case MEC_ICR: /* 0x50 */ if (data & 0xFFFF0001) mecparerror(); mec_ipr &= ~data & 0x0fffe; chk_irq(); break; case MEC_IFR: /* 0x54 */ if (mec_tcr & 0x080000) { if (data & 0xFFFF0001) mecparerror(); mec_ifr = data & 0xfffe; chk_irq(); } break; case SIM_LOAD: fname[find++] = (char) data; break; case MEC_MEMCFG: /* 0x10 */ if (data & 0xC0E08000) mecparerror(); mec_memcfg = data; decode_memcfg(); if (mec_memcfg & 0xc0e08000) mecparerror(); break; case MEC_WCR: /* 0x18 */ mec_wcr = data; decode_wcr(); break; case MEC_ERSR: /* 0xB0 */ if (mec_tcr & 0x100000) if (data & 0xFFFFEFC0) mecparerror(); mec_ersr = data & 0x103f; break; case MEC_TCR: /* 0xD0 */ if (data & 0xFFE1FFC0) mecparerror(); mec_tcr = data & 0x1e003f; break; case MEC_WDOG: /* 0x60 */ wdog_scaler = (data >> 16) & 0x0ff; wdog_counter = data & 0x0ffff; wdog_rst_delay = data >> 24; wdog_rston = 0; if (wdog_status == stopped) wdog_start(); wdog_status = enabled; break; case MEC_TRAPD: /* 0x64 */ if (wdog_status == init) { wdog_status = disabled; if (sis_verbose) printf("Watchdog disabled\n"); } break; case MEC_PWDR: if (mec_mcr & 1) wait_for_irq(); break; default: set_sfsr(MEC_ACC, addr, 0xb, 0); return (1); break; } return (MOK);}/* MEC UARTS */static int ifd1 = -1, ifd2 = -1, ofd1 = -1, ofd2 = -1;voidinit_stdio(){ if (dumbio) return; /* do nothing */ if (!ifd1) tcsetattr(0, TCSANOW, &ioc1); if (!ifd2) tcsetattr(0, TCSANOW, &ioc2);}voidrestore_stdio(){ if (dumbio) return; /* do nothing */ if (!ifd1) tcsetattr(0, TCSANOW, &iocold1); if (!ifd2) tcsetattr(0, TCSANOW, &iocold2);}#define DO_STDIO_READ( _fd_, _buf_, _len_ ) \ ( dumbio \ ? (0) /* no bytes read, no delay */ \ : read( _fd_, _buf_, _len_ ) )static voidport_init(){ if (uben) { f2in = stdin; f1in = NULL; f2out = stdout; f1out = NULL; } else { f1in = stdin; f2in = NULL; f1out = stdout; f2out = NULL; } if (uart_dev1[0] != 0) if ((fd1 = open(uart_dev1, O_RDWR | O_NONBLOCK)) < 0) { printf("Warning, couldn't open output device %s\n", uart_dev1); } else { if (sis_verbose) printf("serial port A on %s\n", uart_dev1); f1in = f1out = fdopen(fd1, "r+"); setbuf(f1out, NULL); f1open = 1; } if (f1in) ifd1 = fileno(f1in); if (ifd1 == 0) { if (sis_verbose) printf("serial port A on stdin/stdout\n"); if (!dumbio) { tcgetattr(ifd1, &ioc1); iocold1 = ioc1; ioc1.c_lflag &= ~(ICANON | ECHO); ioc1.c_cc[VMIN] = 0; ioc1.c_cc[VTIME] = 0; } f1open = 1; } if (f1out) { ofd1 = fileno(f1out); if (!dumbio && ofd1 == 1) setbuf(f1out, NULL); } if (uart_dev2[0] != 0) if ((fd2 = open(uart_dev2, O_RDWR | O_NONBLOCK)) < 0) { printf("Warning, couldn't open output device %s\n", uart_dev2); } else { if (sis_verbose) printf("serial port B on %s\n", uart_dev2); f2in = f2out = fdopen(fd2, "r+"); setbuf(f2out, NULL); f2open = 1; } if (f2in) ifd2 = fileno(f2in); if (ifd2 == 0) { if (sis_verbose) printf("serial port B on stdin/stdout\n"); if (!dumbio) { tcgetattr(ifd2, &ioc2); iocold2 = ioc2; ioc2.c_lflag &= ~(ICANON | ECHO); ioc2.c_cc[VMIN] = 0; ioc2.c_cc[VTIME] = 0; } f2open = 1; } if (f2out) { ofd2 = fileno(f2out); if (!dumbio && ofd2 == 1) setbuf(f2out, NULL); } wnuma = wnumb = 0;}static uint32read_uart(addr) uint32 addr;{ unsigned tmp; tmp = 0; switch (addr & 0xff) { case 0xE0: /* UART 1 */#ifndef _WIN32#ifdef FAST_UART if (aind < anum) { if ((aind + 1) < anum) mec_irq(4); return (0x700 | (uint32) aq[aind++]); } else { if (f1open) { anum = DO_STDIO_READ(ifd1, aq, UARTBUF); } if (anum > 0) { aind = 0; if ((aind + 1) < anum) mec_irq(4); return (0x700 | (uint32) aq[aind++]); } else { return (0x600 | (uint32) aq[aind]); } }#else tmp = uarta_data; uarta_data &= ~UART_DR; uart_stat_reg &= ~UARTA_DR; return tmp;#endif#else return(0);#endif break; case 0xE4: /* UART 2 */#ifndef _WIN32#ifdef FAST_UART if (bind < bnum) { if ((bind + 1) < bnum) mec_irq(5); return (0x700 | (uint32) bq[bind++]); } else { if (f2open) { bnum = DO_STDIO_READ(ifd2, bq, UARTBUF); } if (bnum > 0) { bind = 0; if ((bind + 1) < bnum) mec_irq(5); return (0x700 | (uint32) bq[bind++]); } else { return (0x600 | (uint32) bq[bind]); } }#else tmp = uartb_data; uartb_data &= ~UART_DR; uart_stat_reg &= ~UARTB_DR; return tmp;#endif#else return(0);#endif break; case 0xE8: /* UART status register */#ifndef _WIN32#ifdef FAST_UART Ucontrol = 0; if (aind < anum) { Ucontrol |= 0x00000001; } else { if (f1open) { anum = DO_STDIO_READ(ifd1, aq, UARTBUF); } if (anum > 0) { Ucontrol |= 0x00000001; aind = 0; mec_irq(4); } } if (bind < bnum) { Ucontrol |= 0x00010000; } else { if (f2open) { bnum = DO_STDIO_READ(ifd2, bq, UARTBUF); } if (bnum > 0) { Ucontrol |= 0x00010000; bind = 0; mec_irq(5); } } Ucontrol |= 0x00060006; return (Ucontrol);#else return (uart_stat_reg);#endif#else return(0x00060006);#endif break; default: if (sis_verbose) printf("Read from unimplemented MEC register (%x)\n", addr); } return (0);}static voidwrite_uart(addr, data) uint32 addr; uint32 data;{ unsigned char c; c = (unsigned char) data; switch (addr & 0xff) { case 0xE0: /* UART A */#ifdef FAST_UART if (f1open) { if (wnuma < UARTBUF) wbufa[wnuma++] = c; else { while (wnuma) wnuma -= fwrite(wbufa, 1, wnuma, f1out); wbufa[wnuma++] = c; } } mec_irq(4);#else if (uart_stat_reg & UARTA_SRE) { uarta_sreg = c; uart_stat_reg &= ~UARTA_SRE; event(uarta_tx, 0, UART_TX_TIME); } else { uarta_hreg = c; uart_stat_reg &= ~UARTA_HRE; }#endif break; case 0xE4: /* UART B */#ifdef FAST_UART if (f2open) { if (wnumb < UARTBUF) wbufb[wnumb++] = c; else { while (wnumb) wnumb -= fwrite(wbufb, 1, wnumb, f2out); wbufb[wnumb++] = c; } } mec_irq(5);#else if (uart_stat_reg & UARTB_SRE) { uartb_sreg = c; uart_stat_reg &= ~UARTB_SRE; event(uartb_tx, 0, UART_TX_TIME); } else { uartb_hreg = c; uart_stat_reg &= ~UARTB_HRE; }#endif break; case 0xE8: /* UART status register */#ifndef FAST_UART if (data & UARTA_CLR) { uart_stat_reg &= 0xFFFF0000; uart_stat_reg |= UARTA_SRE | UARTA_HRE; } if (data & UARTB_CLR) { uart_stat_reg &= 0x0000FFFF; uart_stat_reg |= UARTB_SRE | UARTB_HRE; }#endif break; default: if (sis_verbose) printf("Write to unimplemented MEC register (%x)\n", addr); }}static voidflush_uart(){ while (wnuma && f1open) wnuma -= fwrite(wbufa, 1, wnuma, f1out); while (wnumb && f2open) wnumb -= fwrite(wbufb, 1, wnumb, f2out);}static voiduarta_tx(){ while (f1open && fwrite(&uarta_sreg, 1, 1, f1out) != 1); if (uart_stat_reg & UARTA_HRE) { uart_stat_reg |= UARTA_SRE; } else { uarta_sreg = uarta_hreg; uart_stat_reg |= UARTA_HRE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -