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 |