trunk/src/mame/drivers/namcos12.c
r18080 | r18081 | |
1039 | 1039 | #include "includes/psx.h" |
1040 | 1040 | #include "machine/at28c16.h" |
1041 | 1041 | #include "sound/c352.h" |
| 1042 | #include "machine/rtc4543.h" |
1042 | 1043 | |
1043 | 1044 | #define VERBOSE_LEVEL ( 0 ) |
1044 | 1045 | |
r18080 | r18081 | |
1047 | 1048 | public: |
1048 | 1049 | namcos12_state(const machine_config &mconfig, device_type type, const char *tag) |
1049 | 1050 | : psx_state(mconfig, type, tag), |
| 1051 | m_rtc(*this, "rtc"), |
1050 | 1052 | m_sharedram(*this, "sharedram") { } |
1051 | 1053 | |
| 1054 | required_device<rtc4543_device> m_rtc; |
1052 | 1055 | required_shared_ptr<UINT32> m_sharedram; |
1053 | 1056 | UINT32 m_n_bankoffset; |
1054 | 1057 | |
r18080 | r18081 | |
1467 | 1470 | |
1468 | 1471 | WRITE8_MEMBER(namcos12_state::s12_mcu_pa_w) |
1469 | 1472 | { |
1470 | | |
1471 | | // bit 0 = chip enable for the RTC |
1472 | | // reset the state on the rising edge of the bit |
1473 | | if ((!(m_s12_porta & 1)) && (data & 1)) |
1474 | | { |
1475 | | m_s12_rtcstate = 0; |
1476 | | } |
1477 | | |
| 1473 | m_rtc->ce_w(data & 1); |
1478 | 1474 | m_s12_porta = data; |
1479 | 1475 | } |
1480 | 1476 | |
1481 | | INLINE UINT8 make_bcd(UINT8 data) |
1482 | | { |
1483 | | return ((data / 10) << 4) | (data % 10); |
1484 | | } |
1485 | | |
1486 | 1477 | READ8_MEMBER(namcos12_state::s12_mcu_rtc_r) |
1487 | 1478 | { |
1488 | | UINT8 ret = 0; |
1489 | | system_time systime; |
1490 | | static const int weekday[7] = { 7, 1, 2, 3, 4, 5, 6 }; |
| 1479 | UINT8 ret = 0; |
1491 | 1480 | |
1492 | | machine().current_datetime(systime); |
| 1481 | for (int i = 0; i < 8; i++) |
| 1482 | { |
| 1483 | m_rtc->clk_w(0); |
| 1484 | m_rtc->clk_w(1); |
| 1485 | ret <<= 1; |
| 1486 | ret |= m_rtc->data_r(); |
| 1487 | } |
1493 | 1488 | |
1494 | | switch (m_s12_rtcstate) |
1495 | | { |
1496 | | case 0: |
1497 | | ret = make_bcd(systime.local_time.second); // seconds (BCD, 0-59) in bits 0-6, bit 7 = battery low |
1498 | | break; |
1499 | | case 1: |
1500 | | ret = make_bcd(systime.local_time.minute); // minutes (BCD, 0-59) |
1501 | | break; |
1502 | | case 2: |
1503 | | ret = make_bcd(systime.local_time.hour); // hour (BCD, 0-23) |
1504 | | break; |
1505 | | case 3: |
1506 | | ret = make_bcd(weekday[systime.local_time.weekday]); // low nibble = day of the week |
1507 | | ret |= (make_bcd(systime.local_time.mday) & 0x0f)<<4; // high nibble = low digit of day |
1508 | | break; |
1509 | | case 4: |
1510 | | ret = (make_bcd(systime.local_time.mday) >> 4); // low nibble = high digit of day |
1511 | | ret |= (make_bcd(systime.local_time.month + 1) & 0x0f)<<4; // high nibble = low digit of month |
1512 | | break; |
1513 | | case 5: |
1514 | | ret = make_bcd(systime.local_time.month + 1) >> 4; // low nibble = high digit of month |
1515 | | ret |= (make_bcd(systime.local_time.year % 10) << 4); // high nibble = low digit of year |
1516 | | break; |
1517 | | case 6: |
1518 | | ret = make_bcd(systime.local_time.year % 100) >> 4; // low nibble = tens digit of year (BCD, 0-9) |
1519 | | break; |
1520 | | } |
1521 | | |
1522 | | m_s12_rtcstate++; |
1523 | | |
1524 | 1489 | return ret; |
1525 | 1490 | } |
1526 | 1491 | |
r18080 | r18081 | |
1682 | 1647 | |
1683 | 1648 | MCFG_MACHINE_RESET_OVERRIDE(namcos12_state, namcos12 ) |
1684 | 1649 | |
| 1650 | MCFG_RTC4543_ADD("rtc", XTAL_32_768kHz) |
| 1651 | |
1685 | 1652 | /* video hardware */ |
1686 | 1653 | MCFG_PSXGPU_ADD( "maincpu", "gpu", CXD8654Q, 0x200000, XTAL_53_693175MHz ) |
1687 | 1654 | MCFG_PSXGPU_VBLANK_CALLBACK( vblank_state_delegate( FUNC( namcos12_sub_irq ), (namcos12_state *) owner ) ) |
trunk/src/mame/drivers/namcos23.c
r18080 | r18081 | |
1228 | 1228 | #include "cpu/sh2/sh2.h" |
1229 | 1229 | #include "sound/c352.h" |
1230 | 1230 | #include "machine/nvram.h" |
| 1231 | #include "machine/rtc4543.h" |
1231 | 1232 | |
1232 | 1233 | #define S23_BUSCLOCK (66664460/2) /* 33MHz CPU bus clock / input, somehow derived from 14.31721 MHz crystal */ |
1233 | 1234 | #define S23_H8CLOCK (14745600) |
r18080 | r18081 | |
1320 | 1321 | public: |
1321 | 1322 | namcos23_state(const machine_config &mconfig, device_type type, const char *tag) |
1322 | 1323 | : driver_device(mconfig, type, tag) , |
| 1324 | m_rtc(*this, "rtc"), |
1323 | 1325 | m_shared_ram(*this, "shared_ram"), |
1324 | 1326 | m_charram(*this, "charram"), |
1325 | 1327 | m_textram(*this, "textram"), |
r18080 | r18081 | |
1333 | 1335 | render_t m_render; |
1334 | 1336 | |
1335 | 1337 | tilemap_t *m_bgtilemap; |
| 1338 | required_device<rtc4543_device> m_rtc; |
1336 | 1339 | required_shared_ptr<UINT32> m_shared_ram; |
1337 | 1340 | required_shared_ptr<UINT32> m_charram; |
1338 | 1341 | required_shared_ptr<UINT32> m_textram; |
r18080 | r18081 | |
2610 | 2613 | WRITE8_MEMBER(namcos23_state::s23_mcu_pa_w) |
2611 | 2614 | { |
2612 | 2615 | // bit 0 = chip enable for the RTC |
2613 | | // reset the state on the rising edge of the bit |
2614 | | if ((!(m_s23_porta & 1)) && (data & 1)) |
2615 | | { |
2616 | | m_s23_rtcstate = 0; |
2617 | | } |
2618 | | |
| 2616 | m_rtc->ce_w(data & 1); |
2619 | 2617 | m_s23_porta = data; |
2620 | 2618 | } |
2621 | 2619 | |
2622 | | INLINE UINT8 make_bcd(UINT8 data) |
2623 | | { |
2624 | | return ((data / 10) << 4) | (data % 10); |
2625 | | } |
2626 | | |
2627 | 2620 | READ8_MEMBER(namcos23_state::s23_mcu_rtc_r) |
2628 | 2621 | { |
2629 | | UINT8 ret = 0; |
2630 | | system_time systime; |
2631 | | static const int weekday[7] = { 7, 1, 2, 3, 4, 5, 6 }; |
| 2622 | UINT8 ret = 0; |
2632 | 2623 | |
2633 | | machine().current_datetime(systime); |
| 2624 | for (int i = 0; i < 8; i++) |
| 2625 | { |
| 2626 | m_rtc->clk_w(0); |
| 2627 | m_rtc->clk_w(1); |
| 2628 | ret <<= 1; |
| 2629 | ret |= m_rtc->data_r(); |
| 2630 | } |
2634 | 2631 | |
2635 | | switch (m_s23_rtcstate) |
2636 | | { |
2637 | | case 0: |
2638 | | ret = make_bcd(systime.local_time.second); // seconds (BCD, 0-59) in bits 0-6, bit 7 = battery low |
2639 | | break; |
2640 | | case 1: |
2641 | | ret = make_bcd(systime.local_time.minute); // minutes (BCD, 0-59) |
2642 | | break; |
2643 | | case 2: |
2644 | | ret = make_bcd(systime.local_time.hour); // hour (BCD, 0-23) |
2645 | | break; |
2646 | | case 3: |
2647 | | ret = make_bcd(weekday[systime.local_time.weekday]); // low nibble = day of the week |
2648 | | ret |= (make_bcd(systime.local_time.mday) & 0x0f)<<4; // high nibble = low digit of day |
2649 | | break; |
2650 | | case 4: |
2651 | | ret = (make_bcd(systime.local_time.mday) >> 4); // low nibble = high digit of day |
2652 | | ret |= (make_bcd(systime.local_time.month + 1) & 0x0f)<<4; // high nibble = low digit of month |
2653 | | break; |
2654 | | case 5: |
2655 | | ret = make_bcd(systime.local_time.month + 1) >> 4; // low nibble = high digit of month |
2656 | | ret |= (make_bcd(systime.local_time.year % 10) << 4); // high nibble = low digit of year |
2657 | | break; |
2658 | | case 6: |
2659 | | ret = make_bcd(systime.local_time.year % 100) >> 4; // low nibble = tens digit of year (BCD, 0-9) |
2660 | | break; |
2661 | | } |
2662 | | |
2663 | | m_s23_rtcstate++; |
2664 | | |
2665 | 2632 | return ret; |
2666 | 2633 | } |
2667 | 2634 | |
r18080 | r18081 | |
3161 | 3128 | |
3162 | 3129 | MCFG_QUANTUM_TIME(attotime::from_hz(60000)) |
3163 | 3130 | |
| 3131 | MCFG_RTC4543_ADD("rtc", XTAL_32_768kHz) |
| 3132 | |
3164 | 3133 | MCFG_SCREEN_ADD("screen", RASTER) |
3165 | 3134 | MCFG_SCREEN_REFRESH_RATE(S23_VSYNC1) |
3166 | 3135 | MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) // Not in any way accurate |
r18080 | r18081 | |
3206 | 3175 | |
3207 | 3176 | MCFG_QUANTUM_TIME(attotime::from_hz(60000)) |
3208 | 3177 | |
| 3178 | MCFG_RTC4543_ADD("rtc", XTAL_32_768kHz) |
| 3179 | |
3209 | 3180 | MCFG_SCREEN_ADD("screen", RASTER) |
3210 | 3181 | MCFG_SCREEN_REFRESH_RATE(S23_VSYNC1) |
3211 | 3182 | MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) // Not in any way accurate |
r18080 | r18081 | |
3247 | 3218 | |
3248 | 3219 | MCFG_QUANTUM_TIME(attotime::from_hz(60000)) |
3249 | 3220 | |
| 3221 | MCFG_RTC4543_ADD("rtc", XTAL_32_768kHz) |
| 3222 | |
3250 | 3223 | MCFG_SCREEN_ADD("screen", RASTER) |
3251 | 3224 | MCFG_SCREEN_REFRESH_RATE(S23_VSYNC1) |
3252 | 3225 | MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) // Not in any way accurate |
trunk/src/emu/machine/rtc4543.c
r0 | r18081 | |
| 1 | /********************************************************************** |
| 2 | |
| 3 | rtc4543.c - Epson R4543 real-time clock chip emulation |
| 4 | by R. Belmont |
| 5 | |
| 6 | TODO: writing (not done by System 12 or 23 so no test case) |
| 7 | |
| 8 | **********************************************************************/ |
| 9 | |
| 10 | #include "rtc4543.h" |
| 11 | |
| 12 | //************************************************************************** |
| 13 | // MACROS / CONSTANTS |
| 14 | //************************************************************************** |
| 15 | |
| 16 | #define VERBOSE 0 |
| 17 | |
| 18 | //************************************************************************** |
| 19 | // LIVE DEVICE |
| 20 | //************************************************************************** |
| 21 | |
| 22 | // device type definition |
| 23 | const device_type RTC4543 = &device_creator<rtc4543_device>; |
| 24 | |
| 25 | |
| 26 | //------------------------------------------------- |
| 27 | // rtc4543_device - constructor |
| 28 | //------------------------------------------------- |
| 29 | |
| 30 | rtc4543_device::rtc4543_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 31 | : device_t(mconfig, RTC4543, "Epson R4543", tag, owner, clock), |
| 32 | device_rtc_interface(mconfig, *this) |
| 33 | { |
| 34 | } |
| 35 | |
| 36 | |
| 37 | //------------------------------------------------- |
| 38 | // device_start - device-specific startup |
| 39 | //------------------------------------------------- |
| 40 | |
| 41 | void rtc4543_device::device_start() |
| 42 | { |
| 43 | // allocate timers |
| 44 | m_clock_timer = timer_alloc(); |
| 45 | m_clock_timer->adjust(attotime::from_hz(clock() / 32768), 0, attotime::from_hz(clock() / 32768)); |
| 46 | |
| 47 | // state saving |
| 48 | save_item(NAME(m_ce)); |
| 49 | save_item(NAME(m_clk)); |
| 50 | save_item(NAME(m_wr)); |
| 51 | save_item(NAME(m_data)); |
| 52 | save_item(NAME(m_regs)); |
| 53 | save_item(NAME(m_curreg)); |
| 54 | } |
| 55 | |
| 56 | |
| 57 | //------------------------------------------------- |
| 58 | // device_reset - device-specific reset |
| 59 | //------------------------------------------------- |
| 60 | |
| 61 | void rtc4543_device::device_reset() |
| 62 | { |
| 63 | set_current_time(machine()); |
| 64 | |
| 65 | m_ce = 0; |
| 66 | m_wr = 0; |
| 67 | m_clk = 0; |
| 68 | m_data = 0; |
| 69 | m_curreg = 0; |
| 70 | } |
| 71 | |
| 72 | |
| 73 | //------------------------------------------------- |
| 74 | // device_timer - handler timer events |
| 75 | //------------------------------------------------- |
| 76 | |
| 77 | void rtc4543_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) |
| 78 | { |
| 79 | advance_seconds(); |
| 80 | } |
| 81 | |
| 82 | |
| 83 | INLINE UINT8 make_bcd(UINT8 data) |
| 84 | { |
| 85 | return ((data / 10) << 4) | (data % 10); |
| 86 | } |
| 87 | |
| 88 | //------------------------------------------------- |
| 89 | // rtc_clock_updated - |
| 90 | //------------------------------------------------- |
| 91 | |
| 92 | void rtc4543_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) |
| 93 | { |
| 94 | static const int weekday[7] = { 7, 1, 2, 3, 4, 5, 6 }; |
| 95 | |
| 96 | m_regs[0] = make_bcd(second); // seconds (BCD, 0-59) in bits 0-6, bit 7 = battery low |
| 97 | m_regs[1] = make_bcd(minute); // minutes (BCD, 0-59) |
| 98 | m_regs[2] = make_bcd(hour); // hour (BCD, 0-23) |
| 99 | m_regs[3] = make_bcd(weekday[day_of_week]); // low nibble = day of the week |
| 100 | m_regs[3] |= (make_bcd(day) & 0x0f)<<4; // high nibble = low digit of day |
| 101 | m_regs[4] = (make_bcd(day) >> 4); // low nibble = high digit of day |
| 102 | m_regs[4] |= (make_bcd(month & 0x0f)<<4); // high nibble = low digit of month |
| 103 | m_regs[5] = make_bcd(month & 0x0f) >> 4; // low nibble = high digit of month |
| 104 | m_regs[5] |= (make_bcd(year % 10) << 4); // high nibble = low digit of year |
| 105 | m_regs[6] = make_bcd(year % 100) >> 4; // low nibble = tens digit of year (BCD, 0-9) |
| 106 | } |
| 107 | |
| 108 | //------------------------------------------------- |
| 109 | // ce_w - chip enable write |
| 110 | //------------------------------------------------- |
| 111 | |
| 112 | WRITE_LINE_MEMBER( rtc4543_device::ce_w ) |
| 113 | { |
| 114 | if (VERBOSE) printf("RTC4543 '%s' CE: %u\n", tag(), state); |
| 115 | |
| 116 | if (!state && m_ce) // complete transfer |
| 117 | { |
| 118 | } |
| 119 | else if (state && !m_ce) // start new data transfer |
| 120 | { |
| 121 | m_curreg = 0; |
| 122 | m_bit = 8; // force immediate reload of output data |
| 123 | } |
| 124 | |
| 125 | m_ce = state; |
| 126 | } |
| 127 | |
| 128 | //------------------------------------------------- |
| 129 | // wr_w - data direction line write |
| 130 | //------------------------------------------------- |
| 131 | |
| 132 | WRITE_LINE_MEMBER( rtc4543_device::wr_w ) |
| 133 | { |
| 134 | if (VERBOSE) logerror("RTC4543 '%s' WR: %u\n", tag(), state); |
| 135 | |
| 136 | m_wr = state; |
| 137 | } |
| 138 | |
| 139 | //------------------------------------------------- |
| 140 | // clk_w - serial clock write |
| 141 | //------------------------------------------------- |
| 142 | |
| 143 | WRITE_LINE_MEMBER( rtc4543_device::clk_w ) |
| 144 | { |
| 145 | if (VERBOSE) logerror("RTC4543 '%s' CLK: %u\n", tag(), state); |
| 146 | |
| 147 | if (!m_ce) return; |
| 148 | |
| 149 | if (!m_clk && state) // rising edge - read data becomes valid here |
| 150 | { |
| 151 | if (m_bit > 7) // reload data? |
| 152 | { |
| 153 | m_bit = 0; |
| 154 | m_data = m_regs[m_curreg++]; |
| 155 | } |
| 156 | else // no reload, just continue with the current byte |
| 157 | { |
| 158 | m_data <<= 1; |
| 159 | } |
| 160 | |
| 161 | m_bit++; |
| 162 | } |
| 163 | else if (m_clk && !state) // falling edge - write data becomes valid here |
| 164 | { |
| 165 | } |
| 166 | |
| 167 | m_clk = state; |
| 168 | } |
| 169 | |
| 170 | |
| 171 | //------------------------------------------------- |
| 172 | // data_w - I/O write |
| 173 | //------------------------------------------------- |
| 174 | |
| 175 | WRITE_LINE_MEMBER( rtc4543_device::data_w ) |
| 176 | { |
| 177 | if (VERBOSE) logerror("RTC4543 '%s' I/O: %u\n", tag(), state); |
| 178 | |
| 179 | m_data |= (state & 1); |
| 180 | } |
| 181 | |
| 182 | |
| 183 | //------------------------------------------------- |
| 184 | // data_r - I/O read |
| 185 | //------------------------------------------------- |
| 186 | |
| 187 | READ_LINE_MEMBER( rtc4543_device::data_r ) |
| 188 | { |
| 189 | return (m_data & 0x80) ? 1 : 0; |
| 190 | } |
| 191 | |
trunk/src/emu/machine/rtc4543.h
r0 | r18081 | |
| 1 | /********************************************************************** |
| 2 | |
| 3 | rtc4543.h - Epson R4543 real-time clock emulation |
| 4 | by R. Belmont |
| 5 | |
| 6 | **********************************************************************/ |
| 7 | |
| 8 | #pragma once |
| 9 | |
| 10 | #ifndef __RTC4543_H__ |
| 11 | #define __RTC4543_H__ |
| 12 | |
| 13 | #include "emu.h" |
| 14 | |
| 15 | |
| 16 | |
| 17 | //************************************************************************** |
| 18 | // INTERFACE CONFIGURATION MACROS |
| 19 | //************************************************************************** |
| 20 | |
| 21 | #define MCFG_RTC4543_ADD(_tag, _clock) \ |
| 22 | MCFG_DEVICE_ADD(_tag, RTC4543, _clock) |
| 23 | |
| 24 | |
| 25 | |
| 26 | //************************************************************************** |
| 27 | // TYPE DEFINITIONS |
| 28 | //************************************************************************** |
| 29 | |
| 30 | // ======================> rtc4543_device |
| 31 | |
| 32 | class rtc4543_device : public device_t, |
| 33 | public device_rtc_interface |
| 34 | { |
| 35 | public: |
| 36 | // construction/destruction |
| 37 | rtc4543_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 38 | |
| 39 | DECLARE_WRITE_LINE_MEMBER( ce_w ); |
| 40 | DECLARE_WRITE_LINE_MEMBER( wr_w ); |
| 41 | DECLARE_WRITE_LINE_MEMBER( clk_w ); |
| 42 | DECLARE_READ_LINE_MEMBER( data_r ); |
| 43 | DECLARE_WRITE_LINE_MEMBER( data_w ); |
| 44 | |
| 45 | protected: |
| 46 | // device-level overrides |
| 47 | virtual void device_start(); |
| 48 | virtual void device_reset(); |
| 49 | virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); |
| 50 | |
| 51 | // device_rtc_interface overrides |
| 52 | virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second); |
| 53 | virtual bool rtc_feature_leap_year() { return true; } |
| 54 | |
| 55 | private: |
| 56 | int m_ce; |
| 57 | int m_clk; |
| 58 | int m_wr; |
| 59 | int m_data; |
| 60 | int m_regs[7]; |
| 61 | int m_curreg; |
| 62 | int m_bit; |
| 63 | |
| 64 | // timers |
| 65 | emu_timer *m_clock_timer; |
| 66 | }; |
| 67 | |
| 68 | |
| 69 | // device type definition |
| 70 | extern const device_type RTC4543; |
| 71 | |
| 72 | #endif |