📄 skyeye_mach_s3c44b0x.c
字号:
*pUrxh = (ARMword)pUfifo->rx[0]; } else { /* non FIFO mode */ *pUtrstat &= ~0x1; } } break; case UBRDIV0: *data = io.ubrdiv0; break; case UBRDIV1: *data = io.ubrdiv1; break; default: break; } DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, *data);}static void s3c44b0x_uart_write(ARMul_State *state, ARMword addr, ARMword data){ DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, data); switch (addr) { case ULCON0: io.ulcon0 = data; break; case ULCON1: io.ulcon1 = data; break; case UCON0: io.ucon0 = data; break; case UCON1: io.ucon1 = data; break; case UFCON0: case UFCON1: { ARMword *pUfcon = (addr == UFCON0 ? &io.ufcon0 : &io.ufcon1); *pUfcon = (data & ~0x6); if (!((data & 0x1) == 0 || (data & 0x6) == 0)) { ARMword *pUfstat = (addr == UFCON0 ? &io.ufstat0 : &io.ufstat1); if (data & 0x2) *pUfstat &= ~0x10f; /* Rx FIFO reset */ if (data & 0x4) *pUfstat &= ~0x2f0; /* Tx FIFO reset */ } } break; case UMCON0: io.umcon0 = data; break; case UMCON1: io.umcon1 = data; break; case UTXH0: case UTXH1: { ARMword *pUtrstat = (addr == UTXH0 ? &io.utrstat0 : &io.utrstat1); ARMword *pUcon = (addr == UTXH0 ? &io.ucon0 : &io.ucon1); ARMword *pUfcon = (addr == UTXH0 ? &io.ufcon0 : &io.ufcon1); char tmp = data & 0xff;#if 0 /* Disabled the line to show some messages when booting use incorrect bootrom */ if ((*pUcon & 0xc) == 0x0) break;#endif if (*pUfcon & 0x1) { /* FIFO mode */ ARMword *pUfstat = (addr == UTXH0 ? &io.ufstat0 : &io.ufstat1); if ((*pUfstat & 0x200) == 0) { /* FIFO not full */ struct s3c44b0x_uart_fifo *pUfifo = (addr == UTXH0 ? &io.ufifo0 : &io.ufifo1); int count = ((*pUfstat >> 4) & 0xf); pUfifo->tx[count++] = tmp; *pUfstat &= ~0xf0; *pUfstat |= (count == 16 ? 0x2f0 : (count << 4)); } } else { /* non FIFO mode */ skyeye_uart_write(addr == UTXH0 ? 0 : 1, (void*)&tmp, 1, NULL); *pUtrstat |= 0x6; if ((*pUcon & 0xc) == 0x4) { /* Transmit Mode: Interrupt request or polling mode */ s3c44b0x_set_interrupt(addr == UTXH0 ? INT_UTXD0 : INT_UTXD1); } } } break; case UBRDIV0: io.ubrdiv0 = data; break; case UBRDIV1: io.ubrdiv1 = data; break; default: break; }}/* Timer Routine */static int s3c44b0x_timer_check_state(int timer_index, int op_code){ int bit_offset; if (timer_index == 5) { switch (op_code) { case TIMER_OP_START: bit_offset = 24; break; case TIMER_OP_MANUAL: bit_offset = 25; break; case TIMER_OP_RELOAD: bit_offset = 26; break; default: return 0; /* invalid */ } } else { bit_offset = op_code + (timer_index == 0 ? 0 : 8 + 4 * (timer_index - 1)); } return (io.tcon & (0x1 << bit_offset));}static void s3c44b0x_timer_do_cycle(ARMul_State *state){ int i, cnt_down, cnt_divider; for (i = 0; i < 6; i++) { if (s3c44b0x_timer_check_state(i, TIMER_OP_START) == 0) continue; cnt_divider = (io.tprescaler[i] + 1) << io.tdivider[i]; cnt_down = TIMER_COUNT_DOWN_PER_CYCLE / cnt_divider; if (cnt_down == 0) { if (io.tcnt_scaler[i] == 0) { io.tcnt_scaler[i] = cnt_divider / TIMER_COUNT_DOWN_PER_CYCLE; continue; } else if ((io.tcnt_scaler[i] -= 1) != 0) { continue; } cnt_down = 1; } if ((io.tcnt[i] -= min(io.tcnt[i], cnt_down)) > 0) continue; if (((io.tcfg1 >> 24) & 0xf) == i + 1) { /* BDMA request */ do { if (s3c44b0x_dma_is_valid(3) != 1) break; if (((DMA_CCNT(io.dma[3]) >> 30) & 0x3) != 0x1) break; s3c44b0x_dma_proccess(state, 3); } while (0); } else { /* interrupt mode */ s3c44b0x_set_interrupt(INT_TIMER0 - i); } if (s3c44b0x_timer_check_state(i, TIMER_OP_RELOAD) == 0) continue; io.tcnt[i] = io.tcntb[i]; if (i < 5) io.tcmp[i] = io.tcmpb[i]; } if (io.wtcon & 0x20) { cnt_divider = (io.tprescaler[6] + 1) << io.tdivider[6]; cnt_down = TIMER_COUNT_DOWN_PER_CYCLE / cnt_divider; if (cnt_down == 0) { if (io.tcnt_scaler[6] == 0) { io.tcnt_scaler[6] = cnt_divider / TIMER_COUNT_DOWN_PER_CYCLE; goto next; } else if ((io.tcnt_scaler[6] -= 1) != 0) { goto next; } cnt_down = 1; } if ((io.wtcnt -= min(io.wtcnt, cnt_down)) > 0) return; if ((io.wtcon & 0x4) != 0) { /* interrupt mode */ s3c44b0x_set_interrupt(INT_WDT); } if (io.wtcon & 0x1) { /* asserts reset signal */ state->NresetSig = LOW; PRINT("****************** WATCHDOG RESET ******************\n"); } io.wtcnt = io.wtdat; }next: return;}static void s3c44b0x_timer_read(ARMword addr, ARMword *data){ switch (addr) { case TCFG0: *data = io.tcfg0; break; case TCFG1: *data = io.tcfg1; break; case TCON: *data = io.tcon; break; case TCNTB0: case TCNTB1: case TCNTB2: case TCNTB3: case TCNTB4: case TCNTB5: *data = io.tcntb[(addr - TCNTB0) / 0xc]; break; case TCMPB0: case TCMPB1: case TCMPB2: case TCMPB3: case TCMPB4: *data = io.tcmpb[(addr - TCMPB0) / 0xc]; break; case TCNTO0: case TCNTO1: case TCNTO2: case TCNTO3: case TCNTO4: *data = io.tcnt[(addr - TCNTO0) / 0xc]; break; case TCNTO5: *data = io.tcnt[5]; break; case WTCON: *data = io.wtcon; break; case WTDAT: *data = io.wtdat; break; case WTCNT: *data = io.wtcnt; break; default: break; } DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, *data);}static void s3c44b0x_timer_write(ARMul_State *state, ARMword addr, ARMword data){ int i, prescaler, divider; DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, data); switch (addr) { case TCFG0: case TCFG1: if (addr == TCFG0) { io.tcfg0 = data; } else { io.tcfg1 = data; } for (i = 0; i < 6; i++) { io.tprescaler[i] = ((io.tcfg0 >> ((i >> 1) << 3)) & 0xff); io.tdivider[i] = min(4, ((io.tcfg1 >> (i << 2)) & 0xf)); } break; case TCON: io.tcon = data; for (i = 0; i < 6; i++) { if (s3c44b0x_timer_check_state(i, TIMER_OP_MANUAL) != 0) { io.tcnt[i] = io.tcntb[i]; if (i < 5) io.tcmp[i] = io.tcmpb[i]; } } break; case TCNTB0: case TCNTB1: case TCNTB2: case TCNTB3: case TCNTB4: case TCNTB5: io.tcntb[(addr - TCNTB0) / 0xc] = min(data, 0xffff); break; case TCMPB0: case TCMPB1: case TCMPB2: case TCMPB3: case TCMPB4: io.tcmpb[(addr - TCMPB0) / 0xc] = data; break; case WTCON: io.wtcon = data; io.tprescaler[6] = ((io.wtcon >> 8) & 0xff); io.tdivider[6] = ((io.wtcon >> 3) & 0x3) + 4; break; case WTDAT: io.wtdat = data; break; case WTCNT: io.wtcnt = data; break; default: break; }}/* I/O Ports Routine */static void s3c44b0x_ports_read(ARMword addr, ARMword *data){ /* TODO */ DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, *data);}static void s3c44b0x_ports_write(ARMul_State *state, ARMword addr, ARMword data){ /* TODO */ DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, data);}/* RTC Routine */static void s3c44b0x_rtc_do_cycle(ARMul_State *state){ if ((io.rtcalm & 0x40) != 0 && (io.rtcalm & 0x3f) != 0) { struct timeval curr_time; struct tm *curr_tm; time_t curr_timer; unsigned int almen = 0; if (gettimeofday(&curr_time, NULL) != 0 || ((curr_timer = (time_t)((long int)curr_time.tv_sec + io.rtc_offset)), (curr_tm = gmtime(&curr_timer))) == NULL) return; if (curr_tm->tm_sec >= io.rtc_alarm.tm_sec) almen |= 0x1; if (curr_tm->tm_min == io.rtc_alarm.tm_min) almen |= 0x2; if (curr_tm->tm_hour == io.rtc_alarm.tm_hour) almen |= 0x4; if (curr_tm->tm_mday == io.rtc_alarm.tm_mday) almen |= 0x8; if (curr_tm->tm_mon == io.rtc_alarm.tm_mon) almen |= 0x10; if (curr_tm->tm_year == io.rtc_alarm.tm_year) almen |= 0x20; if ((io.rtcalm & 0x3f) == almen) { io.rtcalm &= 0x3f; s3c44b0x_set_interrupt(INT_RTC); } } if ((io.ticint & 0x80) != 0) { /* WARNING: RTC tick is unexacting */ if (io.tick_count > 0) io.tick_count -= 1; if (io.tick_count == 0) s3c44b0x_set_interrupt(INT_TICK); }}static void s3c44b0x_rtc_read(ARMword addr, ARMword *data){ struct timeval curr_time; struct tm *curr_tm; time_t curr_timer; if (addr == RTCCON) { *data = io.rtccon; goto exit; } else if ((io.rtccon & 0x1) == 0) { goto exit; } switch (addr) { case RTCALM: *data = io.rtcalm; goto exit; case RTCRST: *data = io.rtcrst; goto exit; case TICINT: *data = io.ticint; goto exit; case ALMSEC: *data = BIN_TO_BCD(io.rtc_alarm.tm_sec); goto exit; case ALMMIN: *data = BIN_TO_BCD(io.rtc_alarm.tm_min); goto exit; case ALMHOUR: *data = BIN_TO_BCD(io.rtc_alarm.tm_hour); goto exit; case ALMDAY: *data = BIN_TO_BCD(io.rtc_alarm.tm_mday); goto exit; case ALMMON: *data = BIN_TO_BCD(io.rtc_alarm.tm_mon + 1); goto exit; case ALMYEAR: *data = io.rtc_alarm.tm_year - 100; goto exit; default: break; } if (gettimeofday(&curr_time, NULL) != 0 || ((curr_timer = (time_t)((long int)curr_time.tv_sec + io.rtc_offset)), (curr_tm = gmtime(&curr_timer))) == NULL) goto exit; switch (addr) { case BCDSEC: *data = BIN_TO_BCD(curr_tm->tm_sec); break; case BCDMIN: *data = BIN_TO_BCD(curr_tm->tm_min); break; case BCDHOUR: *data = BIN_TO_BCD(curr_tm->tm_hour); break; case BCDDAY: *data = BIN_TO_BCD(curr_tm->tm_mday); break; case BCDDATE: *data = (curr_tm->tm_wday == 0 ? 7 : curr_tm->tm_wday); break; case BCDMON: *data = BIN_TO_BCD(curr_tm->tm_mon + 1); break; case BCDYEAR: *data = curr_tm->tm_year - 100; break; default: goto exit; }exit: DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, *data); return;}static void s3c44b0x_rtc_write(ARMul_State *state, ARMword addr, ARMword data){ struct timeval curr_time; struct tm *curr_tm; time_t curr_timer; DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, data); if (addr == RTCCON) { io.rtccon = data; goto exit; } else if ((io.rtccon & 0x1) == 0) { goto exit; } switch (addr) { case RTCALM: io.rtcalm = data; goto exit; case RTCRST: io.rtcrst = data; goto exit; case TICINT: io.ticint = data; io.tick_count = (data & 0x7f); io.tick_count *= (CYCLE_TIMES_PER_SECOND / 128); /* 1/128 sec per count down */ goto exit; case ALMSEC: io.rtc_alarm.tm_sec = BCD_TO_BIN(data); goto exit; case ALMMIN: io.rtc_alarm.tm_min = BCD_TO_BIN(data); goto exit; case ALMHOUR: io.rtc_alarm.tm_hour = BCD_TO_BIN(data); goto exit; case ALMDAY: io.rtc_alarm.tm_mday = BCD_TO_BIN(data); goto exit; case ALMMON: io.rtc_alarm.tm_mon = BCD_TO_BIN(data) - 1; goto exit; case ALMYEAR: io.rtc_alarm.tm_year = data + 100; goto exit; default: break; } if (gettimeofday(&curr_time, NULL) != 0 || ((curr_timer = (time_t)((long int)curr_time.tv_sec + io.rtc_offset)), (curr_tm = gmtime(&curr_timer))) == NULL) goto exit; switch (addr) { case BCDSEC: curr_tm->tm_sec = BCD_TO_BIN(data); break; case BCDMIN: curr_tm->tm_min = BCD_TO_BIN(data); break; case BCDHOUR: curr_tm->tm_hour = BCD_TO_BIN(data); break; case BCDDAY: curr_tm->tm_mday = BCD_TO_BIN(data); break; case BCDDATE: break; case BCDMON: curr_tm->tm_mon = BCD_TO_BIN(data) - 1; break; case BCDYEAR: curr_tm->tm_mon = data + 100; break; default: goto exit;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -