1 // license:BSD-3-Clause 2 // copyright-holders:Curt Coder 3 /********************************************************************* 4 5 mc146818.h 6 7 Implementation of the MC146818 chip 8 9 Real time clock chip with CMOS battery backed ram 10 Used in IBM PC/AT, several PC clones, Amstrad NC200, Apollo workstations 11 12 *********************************************************************/ 13 14 #ifndef MAME_MACHINE_MC146818_H 15 #define MAME_MACHINE_MC146818_H 16 17 #pragma once 18 19 20 class mc146818_device : public device_t, 21 public device_nvram_interface 22 { 23 public: 24 // construction/destruction 25 mc146818_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 26 27 // callbacks irq()28 auto irq() { return m_write_irq.bind(); } 29 30 // The MC146818 doesn't have century support (some variants do), but when syncing the date & time at startup we can optionally store the century. set_century_index(int century_index)31 void set_century_index(int century_index) { assert(!century_count_enabled()); m_century_index = century_index; } 32 33 // The MC146818 doesn't have UTC support, but when syncing the data & time at startup we can use UTC instead of local time. set_use_utc(bool use_utc)34 void set_use_utc(bool use_utc) { m_use_utc = use_utc; } 35 set_binary(bool binary)36 void set_binary(bool binary) { m_binary = binary; } set_24hrs(bool hour)37 void set_24hrs(bool hour) { m_hour = hour; } set_epoch(int epoch)38 void set_epoch(int epoch) { m_epoch = epoch; } set_binary_year(int bin)39 void set_binary_year(int bin) { m_binyear = bin; } 40 41 // read/write access 42 uint8_t read(offs_t offset); 43 void write(offs_t offset, uint8_t data); 44 45 // direct-mapped read/write access 46 uint8_t read_direct(offs_t offset); 47 void write_direct(offs_t offset, uint8_t data); 48 49 protected: 50 mc146818_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); 51 52 // device-level overrides 53 virtual void device_start() override; 54 virtual void device_reset() override; 55 virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; 56 57 // device_nvram_interface overrides 58 virtual void nvram_default() override; 59 virtual void nvram_read(emu_file &file) override; 60 virtual void nvram_write(emu_file &file) override; 61 62 static constexpr unsigned char ALARM_DONTCARE = 0xc0; 63 static constexpr unsigned char HOURS_PM = 0x80; 64 data_size()65 virtual int data_size() const { return 64; } data_logical_size()66 virtual int data_logical_size() const { return data_size(); } century_count_enabled()67 virtual bool century_count_enabled() const { return false; } 68 69 virtual void internal_set_address(uint8_t address); 70 virtual uint8_t internal_read(offs_t offset); 71 virtual void internal_write(offs_t offset, uint8_t data); 72 73 enum 74 { 75 REG_SECONDS = 0, 76 REG_ALARM_SECONDS = 1, 77 REG_MINUTES = 2, 78 REG_ALARM_MINUTES = 3, 79 REG_HOURS = 4, 80 REG_ALARM_HOURS = 5, 81 REG_DAYOFWEEK = 6, 82 REG_DAYOFMONTH = 7, 83 REG_MONTH = 8, 84 REG_YEAR = 9, 85 REG_A = 0xa, 86 REG_B = 0xb, 87 REG_C = 0xc, 88 REG_D = 0xd 89 }; 90 91 enum 92 { 93 REG_A_RS0 = 1, 94 REG_A_RS1 = 2, 95 REG_A_RS2 = 4, 96 REG_A_RS3 = 8, 97 REG_A_DV0 = 16, 98 REG_A_DV1 = 32, 99 REG_A_DV2 = 64, 100 REG_A_UIP = 128 101 }; 102 103 enum 104 { 105 REG_B_DSE = 1, // TODO: When set the chip will adjust the clock by an hour at start and end of DST 106 REG_B_24_12 = 2, 107 REG_B_DM = 4, 108 REG_B_SQWE = 8, // TODO: When set the chip will output a square wave on SQW pin 109 REG_B_UIE = 16, 110 REG_B_AIE = 32, 111 REG_B_PIE = 64, 112 REG_B_SET = 128 113 }; 114 115 enum 116 { 117 REG_C_UF = 16, 118 REG_C_AF = 32, 119 REG_C_PF = 64, 120 REG_C_IRQF = 128 121 }; 122 123 enum 124 { 125 REG_D_VRT = 128 126 }; 127 128 // internal helpers 129 int to_ram(int a) const; 130 int from_ram(int a) const; 131 void set_base_datetime(); 132 void update_irq(); 133 void update_timer(); 134 virtual int get_timer_bypass() const; 135 int get_seconds() const; 136 void set_seconds(int seconds); 137 int get_minutes() const; 138 void set_minutes(int minutes); 139 int get_hours() const; 140 void set_hours(int hours); 141 int get_dayofweek() const; 142 void set_dayofweek(int dayofweek); 143 int get_dayofmonth() const; 144 void set_dayofmonth(int dayofmonth); 145 int get_month() const; 146 void set_month(int month); 147 int get_year() const; 148 void set_year(int year); 149 int get_century() const; 150 void set_century(int year); 151 152 optional_memory_region m_region; 153 154 // internal state 155 156 uint8_t m_index; 157 std::unique_ptr<uint8_t[]> m_data; 158 159 attotime m_last_refresh; 160 161 static const device_timer_id TIMER_CLOCK = 0; 162 static const device_timer_id TIMER_PERIODIC = 1; 163 164 emu_timer *m_clock_timer; 165 emu_timer *m_periodic_timer; 166 167 devcb_write_line m_write_irq; 168 int m_century_index, m_epoch; 169 bool m_use_utc, m_binary, m_hour, m_binyear; 170 }; 171 172 173 // device type definition 174 DECLARE_DEVICE_TYPE(MC146818, mc146818_device) 175 176 #endif // MAME_MACHINE_MC146818_H 177