// license:BSD-3-Clause // copyright-holders:Tim Schuerewegen #include "emu.h" #include "s3c24xx.h" #include "coreutil.h" #include #include //#define VERBOSE 1 #define LOG_OUTPUT_FUNC std::printf #include "logmacro.h" void s3c24xx_peripheral_types::usbhost_t::reset() { std::memset(®s, 0, sizeof(regs)); } void s3c24xx_peripheral_types::memcon_t::reset() { std::memset(®s, 0, sizeof(regs)); regs.data[0x04 / 4] = 0x00000700; regs.data[0x08 / 4] = 0x00000700; regs.data[0x0c / 4] = 0x00000700; regs.data[0x10 / 4] = 0x00000700; regs.data[0x14 / 4] = 0x00000700; regs.data[0x18 / 4] = 0x00000700; regs.data[0x1c / 4] = 0x00018008; regs.data[0x20 / 4] = 0x00018008; regs.data[0x24 / 4] = 0x00AC0000; } void s3c24xx_peripheral_types::uart_t::reset() { std::memset(®s, 0, sizeof(regs)); regs.utrstat = 6; } void s3c24xx_peripheral_types::pwm_t::reset() { std::memset(®s, 0, sizeof(regs)); for (emu_timer *&tmr : timer) tmr->adjust(attotime::never); } uint16_t s3c24xx_peripheral_types::pwm_t::calc_observation(unsigned ch) const { double const timeleft = timer[ch]->remaining().as_double(); LOG("timeleft %f freq %d cntb %d cmpb %d\n", timeleft, freq[ch], cnt[ch], cmp[ch]); double const x1 = 1 / (double(freq[ch]) / (cnt[ch] - cmp[ch] + 1)); double const x2 = x1 / timeleft; LOG("x1 %f\n", x1); uint32_t cnto = cmp[ch] + ((cnt[ch]- cmp[ch]) / x2); LOG("cnto %u\n", cnto); return cnto; } void s3c24xx_peripheral_types::wdt_t::reset() { std::memset(®s, 0, sizeof(regs)); regs.wtcon = 0x8021; regs.wtdat = 0x8000; regs.wtcnt = 0x8000; timer->adjust(attotime::never); } uint16_t s3c24xx_peripheral_types::wdt_t::calc_current_count() const { double const timeleft = timer->remaining().as_double(); LOG("timeleft %f freq %d cnt %d\n", timeleft, freq, cnt); double const x1 = 1 / (double(freq) / cnt); double const x2 = x1 / timeleft; printf("x1 %f\n", x1); uint32_t const res = cnt / x2; printf("cnt %d\n", res); return res; } void s3c24xx_peripheral_types::iis_t::reset() { std::memset(®s, 0, sizeof(regs)); fifo_index = 0; regs.iiscon = 0x0100; timer->adjust(attotime::never); } void s3c24xx_peripheral_types::rtc_t::reset() { std::memset(®s, 0, sizeof(regs)); regs.almday = 1; regs.almmon = 1; timer_update->adjust(attotime::never); timer_update->adjust(attotime::from_msec(1000), 0, attotime::from_msec(1000)); } void s3c24xx_peripheral_types::rtc_t::recalc() { if (BIT(regs.ticnt, 7)) { uint32_t const ttc = BITS(regs.ticnt, 6, 0); double const freq = 128.0 / (ttc + 1); LOG("ttc %u freq %f\n", ttc, freq); timer_tick_count->adjust(attotime::from_hz(freq), 0, attotime::from_hz(freq)); } else { timer_tick_count->adjust(attotime::never); } } void s3c24xx_peripheral_types::rtc_t::update() { // increase second regs.bcdsec = bcd_adjust(regs.bcdsec + 1); if (regs.bcdsec >= 0x60) { regs.bcdsec = 0; // increase minute regs.bcdmin = bcd_adjust(regs.bcdmin + 1); if (regs.bcdmin >= 0x60) { regs.bcdmin = 0; // increase hour regs.bcdhour = bcd_adjust(regs.bcdhour + 1); if (regs.bcdhour >= 0x24) { regs.bcdhour = 0; // increase day-of-week regs.bcddow = (regs.bcddow % 7) + 1; // increase day regs.bcdday = bcd_adjust(regs.bcdday + 1); uint32_t const bcdday_max = dec_2_bcd(gregorian_days_in_month(bcd_2_dec(regs.bcdmon), bcd_2_dec(regs.bcdyear) + 2000)); if (regs.bcdday > bcdday_max) { regs.bcdday = 1; // increase month regs.bcdmon = bcd_adjust(regs.bcdmon + 1); if (regs.bcdmon >= 0x12) { regs.bcdmon = 1; // increase year regs.bcdyear = bcd_adjust(regs.bcdyear + 1); if (regs.bcdyear >= 0x100) { regs.bcdyear = 0; } } } } } } } bool s3c24xx_peripheral_types::rtc_t::check_alarm() const { return (regs.rtcalm & 0x40) && (!(regs.rtcalm & 0x20) || (regs.almyear == regs.bcdyear)) && (!(regs.rtcalm & 0x10) || (regs.almmon == regs.bcdmon)) && (!(regs.rtcalm & 0x08) || (regs.almday == regs.bcdday)) && (!(regs.rtcalm & 0x04) || (regs.almhour == regs.bcdhour)) && (!(regs.rtcalm & 0x02) || (regs.almmin == regs.bcdmin)) && (!(regs.rtcalm & 0x01) || (regs.almsec == regs.bcdsec)); } void s3c24xx_peripheral_types::mmc_t::reset() { std::memset(®s, 0, sizeof(regs)); } void s3c24xx_peripheral_types::cam_t::reset() { std::memset(®s, 0, sizeof(regs)); } void s3c24xx_peripheral_types::ac97_t::reset() { std::memset(®s, 0, sizeof(regs)); }