mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
Fixed the MC146818 modernisation so that local/utc & whether a century is stored in nvram can be specified in a sane way. Removed the century updating as this chip doesn't do that, but each driver can specify where the century should be stored. Fixed off by one errors in the date/time updating. Added support for different external clock speeds and dividers, the clock speeds have been set based on guesswork that the code would set the chip to update at 1hz but this isn't necessarily true. Most flags have been implemented, so that timer updating can be disabled & irq generation should be correct. [smf]
This commit is contained in:
parent
f4ff52905a
commit
e7517ea39e
@ -296,7 +296,8 @@ static MACHINE_CONFIG_FRAGMENT( e01 )
|
||||
MCFG_CPU_ADD(R65C102_TAG, M65C02, XTAL_8MHz/4) // Rockwell R65C102P3
|
||||
MCFG_CPU_PROGRAM_MAP(e01_mem)
|
||||
|
||||
MCFG_MC146818_IRQ_ADD(HD146818_TAG, MC146818_STANDARD, WRITELINE(e01_device, rtc_irq_w))
|
||||
MCFG_MC146818_ADD(HD146818_TAG, XTAL_32_768kHz)
|
||||
MCFG_MC146818_IRQ_HANDLER(WRITELINE(e01_device, rtc_irq_w))
|
||||
|
||||
// devices
|
||||
MCFG_VIA6522_ADD(R6522_TAG, XTAL_8MHz/4, via_intf)
|
||||
|
@ -62,6 +62,7 @@ enum
|
||||
XTAL_4MHz = 4000000,
|
||||
XTAL_4_028MHz = 4028000, /* Sony SMC-777 */
|
||||
XTAL_4_096MHz = 4096000, /* Used to drive OKI M9810 chips */
|
||||
XTAL_4_194304Mhz = 4194304, /* Used to drive MC146818 */
|
||||
XTAL_4_224MHz = 4224000, /* Used to drive OKI M6295 chips, usually with /4 divider */
|
||||
XTAL_4_41MHz = 4410000, /* Pioneer PR-8210 ldplayer */
|
||||
XTAL_4_43361MHz = 4433610, /* Cidelsa Draco */
|
||||
|
@ -4,74 +4,11 @@
|
||||
|
||||
Implementation of the MC146818 chip
|
||||
|
||||
Real time clock chip with battery backed ram (or CMOS)
|
||||
Real time clock chip with CMOS battery backed ram
|
||||
Used in IBM PC/AT, several PC clones, Amstrad NC200, Apollo workstations
|
||||
|
||||
Nathan Woods (npwoods@mess.org)
|
||||
Peter Trauner (peter.trauner@jk.uni-linz.ac.at)
|
||||
|
||||
PC CMOS info (based on info from Padgett Peterson):
|
||||
|
||||
Clock Related:
|
||||
0x00 Seconds (BCD 00-59, Hex 00-3B) Note: Bit 7 is read only
|
||||
0x01 Second Alarm (BCD 00-59, Hex 00-3B; "don't care" if C0-FF)
|
||||
0x02 Minutes (BCD 00-59, Hex 00-3B)
|
||||
0x03 Minute Alarm (BCD 00-59, Hex 00-3B; "don't care" if C0-FF))
|
||||
0x04 Hours (BCD 00-23, Hex 00-17 if 24 hr mode)
|
||||
(BCD 01-12, Hex 01-0C if 12 hr am)
|
||||
(BCD 81-92. Hex 81-8C if 12 hr pm)
|
||||
0x05 Hour Alarm (same as hours; "don't care" if C0-FF))
|
||||
0x06 Day of Week (01-07 Sunday=1)
|
||||
0x07 Date of Month (BCD 01-31, Hex 01-1F)
|
||||
0x08 Month (BCD 01-12, Hex 01-0C)
|
||||
0x09 Year (BCD 00-99, Hex 00-63)
|
||||
0x0B Status Register B (read/write)
|
||||
Bit 7 - 1 enables cycle update, 0 disables
|
||||
Bit 6 - 1 enables periodic interrupt
|
||||
Bit 5 - 1 enables alarm interrupt
|
||||
Bit 4 - 1 enables update-ended interrupt
|
||||
Bit 3 - 1 enables square wave output
|
||||
Bit 2 - Data Mode - 0: BCD, 1: Binary
|
||||
Bit 1 - 24/12 hour selection - 1 enables 24 hour mode
|
||||
Bit 0 - Daylight Savings Enable - 1 enables
|
||||
0x0C Status Register C (Read only)
|
||||
Bit 7 - Interrupt request flag - 1 when any or all of bits 6-4 are
|
||||
1 and appropriate enables (Register B) are set to 1. Generates
|
||||
IRQ 8 when triggered.
|
||||
Bit 6 - Periodic Interrupt flag
|
||||
Bit 5 - Alarm Interrupt flag
|
||||
Bit 4 - Update-Ended Interrupt Flag
|
||||
Bit 3-0 ???
|
||||
0x0D Status Register D (read only)
|
||||
Bit 7 - Valid RAM - 1 indicates batery power good, 0 if dead or
|
||||
disconnected.
|
||||
Bit 6-0 ???
|
||||
|
||||
Non-clock related:
|
||||
0x0E (PS/2) Diagnostic Status Byte
|
||||
Bit 7 - When set (1) indicates clock has lost power
|
||||
Bit 6 - (1) indicates incorrect checksum
|
||||
Bit 5 - (1) indicates that equipment configuration is incorrect
|
||||
power-on check requires that atleast one floppy be installed
|
||||
Bit 4 - (1) indicates error in memory size
|
||||
Bit 3 - (1) indicates that controller or disk drive failed initialization
|
||||
Bit 2 - (1) indicates that time is invalid
|
||||
Bit 1 - (1) indicates installed adaptors do not match configuration
|
||||
Bit 0 - (1) indicates a time-out while reading adaptor ID
|
||||
0x0E (AMSTRAD) 6 BYTEs time and date machine last used
|
||||
0x0F Reset Code (IBM PS/2 "Shutdown Status Byte")
|
||||
0x00-0x03 perform power-on reset
|
||||
0x04 INT 19h reboot
|
||||
0x05 flush keyboard and jump via 0040:0067
|
||||
0x06-0x07 reserved
|
||||
0x08 used by POST during protected-mode RAM test
|
||||
0x09 used for INT 15/87h (block move) support
|
||||
0x0A jump via 0040:0067
|
||||
0x0B-0xFF perform power-on reset
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "coreutil.h"
|
||||
#include "machine/mc146818.h"
|
||||
|
||||
@ -84,28 +21,6 @@
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// MACROS
|
||||
//**************************************************************************
|
||||
|
||||
#define USE_UTC 1
|
||||
|
||||
#define HOURS_24 (m_data[0xb]&2)
|
||||
#define BCD_MODE !(m_data[0xb]&4) // book has other description!
|
||||
#define CENTURY m_data[72]
|
||||
#define YEAR m_data[9]
|
||||
#define MONTH m_data[8]
|
||||
#define DAY m_data[7]
|
||||
#define WEEK_DAY m_data[6]
|
||||
#define HOUR m_data[4]
|
||||
#define MINUTE m_data[2]
|
||||
#define SECOND m_data[0]
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
// device type definition
|
||||
const device_type MC146818 = &device_creator<mc146818_device>;
|
||||
|
||||
@ -115,29 +30,16 @@ const device_type MC146818 = &device_creator<mc146818_device>;
|
||||
|
||||
mc146818_device::mc146818_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MC146818, "MC146818", tag, owner, clock, "mc146818", __FILE__),
|
||||
device_rtc_interface(mconfig, *this),
|
||||
device_nvram_interface(mconfig, *this),
|
||||
m_write_irq(*this),
|
||||
m_type(MC146818_STANDARD),
|
||||
m_index(0),
|
||||
m_eindex(0),
|
||||
m_updated(false),
|
||||
m_last_refresh(attotime::zero)
|
||||
m_last_refresh(attotime::zero),
|
||||
m_write_irq(*this),
|
||||
m_century_index(-1),
|
||||
m_use_utc(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// static_set_interface - configuration helper
|
||||
// to set the interface
|
||||
//-------------------------------------------------
|
||||
|
||||
void mc146818_device::static_set_type(device_t &device, mc146818_type type)
|
||||
{
|
||||
downcast<mc146818_device &>(device).m_type = type;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
@ -148,154 +50,115 @@ void mc146818_device::device_start()
|
||||
m_clock_timer = timer_alloc(TIMER_CLOCK);
|
||||
m_periodic_timer = timer_alloc(TIMER_PERIODIC);
|
||||
|
||||
memset(m_data, 0, sizeof(m_data));
|
||||
|
||||
m_clock_timer->adjust(attotime::from_hz(1), 0, attotime::from_hz(1));
|
||||
|
||||
m_periodic_timer->adjust(attotime::never);
|
||||
m_period = attotime::never;
|
||||
|
||||
set_base_datetime();
|
||||
|
||||
m_write_irq.resolve_safe();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void mc146818_device::device_reset()
|
||||
{
|
||||
m_data[REG_B] &= ~(REG_B_UIE | REG_B_AIE | REG_B_PIE | REG_B_SQWE);
|
||||
m_data[REG_C] = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_timer - handler timer events
|
||||
//-------------------------------------------------
|
||||
|
||||
void mc146818_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
int year/*, month*/;
|
||||
|
||||
if (id == TIMER_PERIODIC) {
|
||||
m_data[0x0c] |= 0xc0;
|
||||
m_write_irq(CLEAR_LINE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (BCD_MODE)
|
||||
switch (id)
|
||||
{
|
||||
SECOND=bcd_adjust(SECOND+1);
|
||||
if (SECOND>=0x60)
|
||||
case TIMER_PERIODIC:
|
||||
m_data[REG_C] |= REG_C_PF;
|
||||
update_irq();
|
||||
break;
|
||||
|
||||
case TIMER_CLOCK:
|
||||
if (!(m_data[REG_B] & REG_B_SET))
|
||||
{
|
||||
SECOND=0;
|
||||
MINUTE=bcd_adjust(MINUTE+1);
|
||||
if (MINUTE>=0x60)
|
||||
/// TODO: find out how the real chip deals with updates when binary/bcd values are already outside the normal range
|
||||
int seconds = get_seconds() + 1;
|
||||
if (seconds < 60)
|
||||
{
|
||||
MINUTE=0;
|
||||
HOUR=bcd_adjust(HOUR+1);
|
||||
// different handling of hours
|
||||
if (HOUR>=0x24)
|
||||
set_seconds(seconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_seconds(0);
|
||||
|
||||
int minutes = get_minutes() + 1;
|
||||
if (minutes < 60)
|
||||
{
|
||||
HOUR=0;
|
||||
WEEK_DAY=bcd_adjust(WEEK_DAY+1)%7;
|
||||
DAY=bcd_adjust(DAY+1);
|
||||
//month=bcd_2_dec(MONTH);
|
||||
year=bcd_2_dec(YEAR);
|
||||
if (m_type!=MC146818_IGNORE_CENTURY) year+=bcd_2_dec(CENTURY)*100;
|
||||
else year+=2000; // save for julian_days_in_month calculation
|
||||
DAY=bcd_adjust(DAY+1);
|
||||
if (DAY>gregorian_days_in_month(MONTH, year))
|
||||
set_minutes(minutes);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_minutes(0);
|
||||
|
||||
int hours = get_hours() + 1;
|
||||
if (hours < 24)
|
||||
{
|
||||
DAY=1;
|
||||
MONTH=bcd_adjust(MONTH+1);
|
||||
if (MONTH>0x12)
|
||||
set_hours(hours);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_hours(0);
|
||||
|
||||
int dayofweek = get_dayofweek() + 1;
|
||||
if (dayofweek <= 7)
|
||||
{
|
||||
MONTH=1;
|
||||
YEAR=year=bcd_adjust(YEAR+1);
|
||||
if (m_type!=MC146818_IGNORE_CENTURY)
|
||||
set_dayofweek(dayofweek);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_dayofweek(1);
|
||||
}
|
||||
|
||||
int dayofmonth = get_dayofmonth() + 1;
|
||||
if (dayofmonth <= gregorian_days_in_month(get_month(), get_year() + 2000))
|
||||
{
|
||||
set_dayofmonth(dayofmonth);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_dayofmonth(1);
|
||||
|
||||
int month = get_month() + 1;
|
||||
if (month <= 12)
|
||||
{
|
||||
if (year>=0x100)
|
||||
{
|
||||
CENTURY=bcd_adjust(CENTURY+1);
|
||||
}
|
||||
set_month(month);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_month(1);
|
||||
|
||||
set_year((get_year() + 1) % 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SECOND=SECOND+1;
|
||||
if (SECOND>=60)
|
||||
{
|
||||
SECOND=0;
|
||||
MINUTE=MINUTE+1;
|
||||
if (MINUTE>=60) {
|
||||
MINUTE=0;
|
||||
HOUR=HOUR+1;
|
||||
// different handling of hours //?
|
||||
if (HOUR>=24) {
|
||||
HOUR=0;
|
||||
WEEK_DAY=(WEEK_DAY+1)%7;
|
||||
year=YEAR;
|
||||
if (m_type!=MC146818_IGNORE_CENTURY) year+=CENTURY*100;
|
||||
else year+=2000; // save for julian_days_in_month calculation
|
||||
if (++DAY>gregorian_days_in_month(MONTH, year)) {
|
||||
DAY=1;
|
||||
if (++MONTH>12) {
|
||||
MONTH=1;
|
||||
YEAR++;
|
||||
if (m_type!=MC146818_IGNORE_CENTURY) {
|
||||
if (YEAR>=100) { CENTURY++;YEAR=0; }
|
||||
} else {
|
||||
YEAR%=100;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_data[REG_ALARM_SECONDS] == m_data[REG_SECONDS] || (m_data[REG_ALARM_SECONDS] & ALARM_DONTCARE) == ALARM_DONTCARE) &&
|
||||
(m_data[REG_ALARM_MINUTES] == m_data[REG_MINUTES] || (m_data[REG_ALARM_MINUTES] & ALARM_DONTCARE) == ALARM_DONTCARE) &&
|
||||
(m_data[REG_ALARM_HOURS] == m_data[REG_HOURS] || (m_data[REG_ALARM_HOURS] & ALARM_DONTCARE) == ALARM_DONTCARE))
|
||||
{
|
||||
// set the alarm interrupt flag AF
|
||||
m_data[REG_C] |= REG_C_AF;
|
||||
}
|
||||
|
||||
// set the update-ended interrupt Flag UF
|
||||
m_data[REG_C] |= REG_C_UF;
|
||||
update_irq();
|
||||
|
||||
m_last_refresh = machine().time();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_data[1] == SECOND && //
|
||||
m_data[3] == MINUTE && //
|
||||
m_data[5] == HOUR) {
|
||||
// set the alarm interrupt flag AF
|
||||
m_data[0x0c] |= 0x20;
|
||||
} else {
|
||||
// clear the alarm interrupt flag AF
|
||||
m_data[0x0c] &= ~0x20;
|
||||
if ((m_data[0x0c] & 0x70) == 0) {
|
||||
// clear IRQF
|
||||
m_data[0x0c] &= ~0x80;
|
||||
}
|
||||
}
|
||||
|
||||
// set the update-ended interrupt Flag UF
|
||||
m_data[0x0c] |= 0x10;
|
||||
|
||||
// set the interrupt request flag IRQF
|
||||
// FIXME: should throw IRQ line as well
|
||||
if ((m_data[0x0b] & m_data[0x0c] & 0x30) != 0) {
|
||||
m_data[0x0c] |= 0x80;
|
||||
}
|
||||
|
||||
// IRQ line is active low
|
||||
m_write_irq((m_data[0x0c] & 0x80) ? CLEAR_LINE : ASSERT_LINE);
|
||||
|
||||
m_updated = true; /* clock has been updated */
|
||||
m_last_refresh = machine().time();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// rtc_clock_updated -
|
||||
//-------------------------------------------------
|
||||
|
||||
void mc146818_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second)
|
||||
{
|
||||
YEAR = year;
|
||||
MONTH = month;
|
||||
DAY = day;
|
||||
WEEK_DAY = day_of_week;
|
||||
HOUR = hour;
|
||||
MINUTE = minute;
|
||||
SECOND = second;
|
||||
}
|
||||
|
||||
|
||||
@ -316,7 +179,14 @@ void mc146818_device::nvram_default()
|
||||
|
||||
memcpy(m_data, m_region->base(), bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(m_data, 0, sizeof(m_data));
|
||||
}
|
||||
|
||||
set_base_datetime();
|
||||
update_timer();
|
||||
update_irq();
|
||||
}
|
||||
|
||||
|
||||
@ -328,7 +198,10 @@ void mc146818_device::nvram_default()
|
||||
void mc146818_device::nvram_read(emu_file &file)
|
||||
{
|
||||
file.read(m_data, sizeof(m_data));
|
||||
|
||||
set_base_datetime();
|
||||
update_timer();
|
||||
update_irq();
|
||||
}
|
||||
|
||||
|
||||
@ -344,19 +217,144 @@ void mc146818_device::nvram_write(emu_file &file)
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// dec_2_local - convert from decimal to BCD if
|
||||
// necessary
|
||||
// to_ram - convert value to current ram format
|
||||
//-------------------------------------------------
|
||||
|
||||
inline int mc146818_device::dec_2_local(int a)
|
||||
int mc146818_device::to_ram(int a)
|
||||
{
|
||||
return BCD_MODE ? dec_2_bcd(a) : a;
|
||||
if (!(m_data[REG_B] & REG_B_DM))
|
||||
return dec_2_bcd(a);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// dec_2_local - convert from decimal to BCD if
|
||||
// necessary
|
||||
// from_ram - convert value from current ram format
|
||||
//-------------------------------------------------
|
||||
|
||||
int mc146818_device::from_ram(int a)
|
||||
{
|
||||
if (!(m_data[REG_B] & REG_B_DM))
|
||||
return bcd_2_dec(a);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
int mc146818_device::get_seconds()
|
||||
{
|
||||
return from_ram(m_data[REG_SECONDS]);
|
||||
}
|
||||
|
||||
void mc146818_device::set_seconds(int seconds)
|
||||
{
|
||||
m_data[REG_SECONDS] = to_ram(seconds);
|
||||
}
|
||||
|
||||
int mc146818_device::get_minutes()
|
||||
{
|
||||
return from_ram(m_data[REG_MINUTES]);
|
||||
}
|
||||
|
||||
void mc146818_device::set_minutes(int minutes)
|
||||
{
|
||||
m_data[REG_MINUTES] = to_ram(minutes);
|
||||
}
|
||||
|
||||
int mc146818_device::get_hours()
|
||||
{
|
||||
if (!(m_data[REG_B] & REG_B_24_12))
|
||||
{
|
||||
int hours = from_ram(m_data[REG_HOURS] & ~HOURS_PM);
|
||||
|
||||
if (hours == 12)
|
||||
{
|
||||
hours = 0;
|
||||
}
|
||||
|
||||
if (m_data[REG_HOURS] & HOURS_PM)
|
||||
{
|
||||
hours += 12;
|
||||
}
|
||||
|
||||
return hours;
|
||||
}
|
||||
else
|
||||
{
|
||||
return from_ram(m_data[REG_HOURS]);
|
||||
}
|
||||
}
|
||||
|
||||
void mc146818_device::set_hours(int hours)
|
||||
{
|
||||
if (!(m_data[REG_B] & REG_B_24_12))
|
||||
{
|
||||
int pm = 0;
|
||||
|
||||
if (hours >= 12)
|
||||
{
|
||||
hours -= 12;
|
||||
pm = HOURS_PM;
|
||||
}
|
||||
|
||||
if (hours == 0)
|
||||
{
|
||||
hours = 12;
|
||||
}
|
||||
|
||||
m_data[REG_HOURS] = to_ram(hours) | pm;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_data[REG_HOURS] = to_ram(hours);
|
||||
}
|
||||
}
|
||||
|
||||
int mc146818_device::get_dayofweek()
|
||||
{
|
||||
return from_ram(m_data[REG_DAYOFWEEK]);
|
||||
}
|
||||
|
||||
void mc146818_device::set_dayofweek(int dayofweek)
|
||||
{
|
||||
m_data[REG_DAYOFWEEK] = to_ram(dayofweek);
|
||||
}
|
||||
|
||||
int mc146818_device::get_dayofmonth()
|
||||
{
|
||||
return from_ram(m_data[REG_DAYOFMONTH]);
|
||||
}
|
||||
|
||||
void mc146818_device::set_dayofmonth(int dayofmonth)
|
||||
{
|
||||
m_data[REG_DAYOFMONTH] = to_ram(dayofmonth);
|
||||
}
|
||||
|
||||
int mc146818_device::get_month()
|
||||
{
|
||||
return from_ram(m_data[REG_MONTH]);
|
||||
}
|
||||
|
||||
void mc146818_device::set_month(int month)
|
||||
{
|
||||
m_data[REG_MONTH] = to_ram(month);
|
||||
}
|
||||
|
||||
int mc146818_device::get_year()
|
||||
{
|
||||
return from_ram(m_data[REG_YEAR]);
|
||||
}
|
||||
|
||||
void mc146818_device::set_year(int year)
|
||||
{
|
||||
m_data[REG_YEAR] = to_ram(year);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// set_base_datetime - update clock with real time
|
||||
//-------------------------------------------------
|
||||
|
||||
void mc146818_device::set_base_datetime()
|
||||
@ -366,34 +364,117 @@ void mc146818_device::set_base_datetime()
|
||||
|
||||
machine().base_datetime(systime);
|
||||
|
||||
current_time = (m_type == MC146818_UTC) ? systime.utc_time: systime.local_time;
|
||||
current_time = (m_use_utc) ? systime.utc_time: systime.local_time;
|
||||
|
||||
// logerror("mc146818_set_base_datetime %02d/%02d/%02d %02d:%02d:%02d\n",
|
||||
// current_time.year % 100, current_time.month + 1, current_time.mday,
|
||||
// current_time.hour,current_time.minute, current_time.second);
|
||||
|
||||
if (HOURS_24 || (current_time.hour < 12))
|
||||
HOUR = dec_2_local(current_time.hour);
|
||||
else
|
||||
HOUR = dec_2_local(current_time.hour - 12) | 0x80;
|
||||
set_seconds(current_time.second);
|
||||
set_minutes(current_time.minute);
|
||||
set_hours(current_time.hour);
|
||||
set_dayofweek(current_time.weekday + 1);
|
||||
set_dayofmonth(current_time.mday);
|
||||
set_month(current_time.month + 1);
|
||||
set_year(current_time.year % 100);
|
||||
|
||||
if (m_type != MC146818_IGNORE_CENTURY)
|
||||
CENTURY = dec_2_local(current_time.year /100);
|
||||
|
||||
SECOND = dec_2_local(current_time.second);
|
||||
MINUTE = dec_2_local(current_time.minute);
|
||||
DAY = dec_2_local(current_time.mday);
|
||||
MONTH = dec_2_local(current_time.month + 1);
|
||||
YEAR = dec_2_local(current_time.year % 100);
|
||||
|
||||
WEEK_DAY = current_time.weekday;
|
||||
if (current_time.is_dst)
|
||||
m_data[0xb] |= 1;
|
||||
else
|
||||
m_data[0xb] &= ~1;
|
||||
if (m_century_index >= 0)
|
||||
m_data[m_century_index] = to_ram(current_time.year / 100);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// update_timer - update timer based on A register
|
||||
//-------------------------------------------------
|
||||
|
||||
void mc146818_device::update_timer()
|
||||
{
|
||||
int bypass;
|
||||
|
||||
switch (m_data[REG_A] & (REG_A_DV2 | REG_A_DV1 | REG_A_DV0))
|
||||
{
|
||||
case 0:
|
||||
bypass = 0;
|
||||
break;
|
||||
|
||||
case REG_A_DV0:
|
||||
bypass = 2;
|
||||
break;
|
||||
|
||||
case REG_A_DV1:
|
||||
bypass = 7;
|
||||
break;
|
||||
|
||||
case REG_A_DV2 | REG_A_DV1:
|
||||
case REG_A_DV2 | REG_A_DV1 | REG_A_DV0:
|
||||
bypass = 22;
|
||||
break;
|
||||
|
||||
default:
|
||||
// TODO: other combinations of divider bits are used for test purposes only
|
||||
bypass = 22;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
attotime update_period = attotime::never;
|
||||
attotime update_interval = attotime::never;
|
||||
attotime periodic_period = attotime::never;
|
||||
attotime periodic_interval = attotime::never;
|
||||
|
||||
if (bypass < 22)
|
||||
{
|
||||
int shift = 22 - bypass;
|
||||
|
||||
double update_hz = (double) clock() / (1 << shift);
|
||||
|
||||
// TODO: take the time since last timer into account
|
||||
update_period = attotime::from_hz(update_hz * 2);
|
||||
update_interval = attotime::from_hz(update_hz);
|
||||
|
||||
int rate_select = m_data[REG_A] & (REG_A_RS3 | REG_A_RS2 | REG_A_RS1 | REG_A_RS0);
|
||||
if (rate_select != 0)
|
||||
{
|
||||
shift = (rate_select + 6) - bypass;
|
||||
if (shift <= 1)
|
||||
shift += 7;
|
||||
|
||||
double periodic_hz = (double) clock() / (1 << shift);
|
||||
|
||||
// TODO: take the time since last timer into account
|
||||
periodic_period = attotime::from_hz(periodic_hz * 2);
|
||||
periodic_interval = attotime::from_hz(periodic_hz);
|
||||
}
|
||||
}
|
||||
|
||||
m_clock_timer->adjust(update_period, 0, update_interval);
|
||||
m_periodic_timer->adjust(periodic_period, 0, periodic_interval);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// update_irq - Update irq based on B & C register
|
||||
//-------------------------------------------------
|
||||
|
||||
void mc146818_device::update_irq()
|
||||
{
|
||||
// IRQ line is active low
|
||||
if (((m_data[REG_C] & REG_C_UF) && (m_data[REG_B] & REG_B_UIE)) ||
|
||||
((m_data[REG_C] & REG_C_AF) && (m_data[REG_B] & REG_B_AIE)) ||
|
||||
((m_data[REG_C] & REG_C_PF) && (m_data[REG_B] & REG_B_PIE)))
|
||||
{
|
||||
m_data[REG_C] |= REG_C_IRQF;
|
||||
m_write_irq(CLEAR_LINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_data[REG_C] &= REG_C_IRQF;
|
||||
m_write_irq(ASSERT_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// read - I/O handler for reading
|
||||
//-------------------------------------------------
|
||||
@ -401,42 +482,38 @@ void mc146818_device::set_base_datetime()
|
||||
READ8_MEMBER( mc146818_device::read )
|
||||
{
|
||||
UINT8 data = 0;
|
||||
switch (offset) {
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
data = m_index;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
switch (m_index % MC146818_DATA_SIZE) {
|
||||
case 0xa:
|
||||
data = m_data[m_index % MC146818_DATA_SIZE];
|
||||
switch (m_index)
|
||||
{
|
||||
case REG_A:
|
||||
data = m_data[REG_A];
|
||||
// Update In Progress (UIP) time for 32768 Hz is 244+1984usec
|
||||
/// TODO: support other dividers
|
||||
if ((space.machine().time() - m_last_refresh) < attotime::from_usec(244+1984))
|
||||
data |= 0x80;
|
||||
#if 0
|
||||
/* for pc1512 bios realtime clock test */
|
||||
m_data[m_index % MC146818_DATA_SIZE] ^= 0x80; /* 0x80 update in progress */
|
||||
#endif
|
||||
data |= REG_A_UIP;
|
||||
break;
|
||||
|
||||
case 0xc:
|
||||
// if(m_updated) /* the clock has been updated */
|
||||
// data = 0x10;
|
||||
// else
|
||||
// data = 0x00;
|
||||
case REG_C:
|
||||
// the unused bits b0 ... b3 are always read as 0
|
||||
data = m_data[m_index % MC146818_DATA_SIZE] & 0xf0;
|
||||
data = m_data[REG_C] & (REG_C_IRQF | REG_C_PF | REG_C_AF | REG_C_UF);
|
||||
// read 0x0c will clear all IRQ flags in register 0x0c
|
||||
m_data[m_index % MC146818_DATA_SIZE] &= 0x0f;
|
||||
m_write_irq(ASSERT_LINE);
|
||||
m_data[REG_C] &= ~(REG_C_IRQF | REG_C_PF | REG_C_AF | REG_C_UF);
|
||||
update_irq();
|
||||
break;
|
||||
case 0xd:
|
||||
|
||||
case REG_D:
|
||||
/* battery ok */
|
||||
data = m_data[m_index % MC146818_DATA_SIZE] | 0x80;
|
||||
data = m_data[REG_D] | REG_D_VRT;
|
||||
break;
|
||||
|
||||
default:
|
||||
data = m_data[m_index % MC146818_DATA_SIZE];
|
||||
data = m_data[m_index];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -444,6 +521,7 @@ READ8_MEMBER( mc146818_device::read )
|
||||
|
||||
if (LOG_MC146818)
|
||||
logerror("mc146818_port_r(): index=0x%02x data=0x%02x\n", m_index, data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -454,51 +532,45 @@ READ8_MEMBER( mc146818_device::read )
|
||||
|
||||
WRITE8_MEMBER( mc146818_device::write )
|
||||
{
|
||||
attotime rate;
|
||||
if (LOG_MC146818)
|
||||
logerror("mc146818_port_w(): index=0x%02x data=0x%02x\n", m_index, data);
|
||||
|
||||
switch (offset) {
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
m_index = data;
|
||||
m_index = data % MC146818_DATA_SIZE;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
switch(m_index % MC146818_DATA_SIZE)
|
||||
switch (m_index)
|
||||
{
|
||||
case 0x0a:
|
||||
// fixme: allow different time base
|
||||
data &= 0x0f;
|
||||
if (data > 2)
|
||||
m_period = attotime::from_hz(32768 >> (data - 1));
|
||||
else if (data > 0)
|
||||
m_period = attotime::from_hz(32768 >> (data + 6));
|
||||
else m_period = attotime::never;
|
||||
case REG_SECONDS:
|
||||
// top bit of SECONDS is read only
|
||||
m_data[REG_SECONDS] = data & ~0x80;
|
||||
break;
|
||||
|
||||
if(m_data[0x0b] & 0x40)
|
||||
rate = attotime::zero;
|
||||
else rate = attotime::never;
|
||||
case REG_A:
|
||||
// top bit of A is read only
|
||||
m_data[REG_A] = data & ~REG_A_UIP;
|
||||
update_timer();
|
||||
break;
|
||||
|
||||
m_periodic_timer->adjust(rate, 0, m_period);
|
||||
data |= m_data[m_index % MC146818_DATA_SIZE] & 0xf0;
|
||||
m_data[m_index % MC146818_DATA_SIZE] = data;
|
||||
case REG_B:
|
||||
if ((data & REG_B_SET) && !(m_data[REG_B] & REG_B_SET))
|
||||
data &= ~REG_B_UIE;
|
||||
|
||||
m_data[REG_B] = data;
|
||||
update_irq();
|
||||
break;
|
||||
case 0x0b:
|
||||
if(data & 0x80)
|
||||
m_updated = false;
|
||||
// this probably isn't right but otherwise
|
||||
// you'll be making a lot of unnecessary callbacks
|
||||
if (data & 0x40)
|
||||
m_periodic_timer->adjust(attotime::zero, 0, m_period);
|
||||
else
|
||||
m_periodic_timer->adjust(attotime::never);
|
||||
m_data[m_index % MC146818_DATA_SIZE] = data;
|
||||
break;
|
||||
case 0x0c:
|
||||
// register 0x0c is readonly
|
||||
|
||||
case REG_C:
|
||||
case REG_D:
|
||||
// register C & D is readonly
|
||||
break;
|
||||
|
||||
default:
|
||||
m_data[m_index % MC146818_DATA_SIZE] = data;
|
||||
m_data[m_index] = data;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -4,29 +4,33 @@
|
||||
|
||||
Implementation of the MC146818 chip
|
||||
|
||||
Real time clock chip with battery backed ram
|
||||
Used in IBM PC/AT, several PC clones, Amstrad NC200
|
||||
|
||||
Peter Trauner (peter.trauner@jk.uni-linz.ac.at)
|
||||
Real time clock chip with CMOS battery backed ram
|
||||
Used in IBM PC/AT, several PC clones, Amstrad NC200, Apollo workstations
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef __MC146818_H__
|
||||
#define __MC146818_H__
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
//**************************************************************************
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
//**************************************************************************
|
||||
|
||||
#define MCFG_MC146818_IRQ_ADD(_tag, _type, _irq) \
|
||||
MCFG_DEVICE_ADD(_tag, MC146818, 0) \
|
||||
mc146818_device::static_set_type(*device, mc146818_device::_type); \
|
||||
#define MCFG_MC146818_ADD(_tag, _xtal) \
|
||||
MCFG_DEVICE_ADD(_tag, MC146818, _xtal)
|
||||
|
||||
#define MCFG_MC146818_IRQ_HANDLER(_irq) \
|
||||
downcast<mc146818_device *>(device)->set_irq_callback(DEVCB2_##_irq);
|
||||
|
||||
#define MCFG_MC146818_ADD(_tag, _type) \
|
||||
MCFG_DEVICE_ADD(_tag, MC146818, 0) \
|
||||
mc146818_device::static_set_type(*device, mc146818_device::_type);
|
||||
// The MC146818 doesn't have century support, but when syncing the date & time at startup we can optionally store the century.
|
||||
#define MCFG_MC146818_CENTURY_INDEX(_century_index) \
|
||||
downcast<mc146818_device *>(device)->set_century_index(_century_index);
|
||||
|
||||
// The MC146818 doesn't have UTC support, but when syncing the data & time at startup we can use UTC instead of local time.
|
||||
#define MCFG_MC146818_UTC(_utc) \
|
||||
downcast<mc146818_device *>(device)->set_use_utc(_utc);
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
@ -35,76 +39,134 @@
|
||||
// ======================> mc146818_device
|
||||
|
||||
class mc146818_device : public device_t,
|
||||
public device_rtc_interface,
|
||||
public device_nvram_interface
|
||||
{
|
||||
public:
|
||||
// values
|
||||
enum mc146818_type
|
||||
{
|
||||
MC146818_STANDARD,
|
||||
MC146818_IGNORE_CENTURY, // century is NOT set, for systems having other usage of this byte
|
||||
MC146818_ENHANCED,
|
||||
MC146818_UTC
|
||||
};
|
||||
|
||||
// construction/destruction
|
||||
mc146818_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// inline configuration helpers
|
||||
static void static_set_type(device_t &device, mc146818_type type);
|
||||
|
||||
// callbacks
|
||||
template<class _irq> void set_irq_callback(_irq irq) { m_write_irq.set_callback(irq); }
|
||||
void set_century_index(int century_index) { m_century_index = century_index; }
|
||||
void set_use_utc(bool use_utc) { m_use_utc = use_utc; }
|
||||
|
||||
// read/write access
|
||||
DECLARE_READ8_MEMBER( read );
|
||||
DECLARE_WRITE8_MEMBER( write );
|
||||
|
||||
DECLARE_WRITE8_MEMBER( address_w ) { write(space, 0, data); }
|
||||
DECLARE_READ8_MEMBER( data_r ) { return read(space, 1); }
|
||||
DECLARE_WRITE8_MEMBER( data_w ) { write(space, 1, data); }
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
|
||||
|
||||
// device_rtc_interface overrides
|
||||
virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second);
|
||||
|
||||
// device_nvram_interface overrides
|
||||
virtual void nvram_default();
|
||||
virtual void nvram_read(emu_file &file);
|
||||
virtual void nvram_write(emu_file &file);
|
||||
|
||||
// internal helpers
|
||||
int dec_2_local(int a);
|
||||
void set_base_datetime();
|
||||
static const unsigned char ALARM_DONTCARE = 0xc0;
|
||||
static const unsigned char HOURS_PM = 0x80;
|
||||
|
||||
devcb2_write_line m_write_irq;
|
||||
private:
|
||||
enum
|
||||
{
|
||||
REG_SECONDS = 0,
|
||||
REG_ALARM_SECONDS = 1,
|
||||
REG_MINUTES = 2,
|
||||
REG_ALARM_MINUTES = 3,
|
||||
REG_HOURS = 4,
|
||||
REG_ALARM_HOURS = 5,
|
||||
REG_DAYOFWEEK = 6,
|
||||
REG_DAYOFMONTH = 7,
|
||||
REG_MONTH = 8,
|
||||
REG_YEAR = 9,
|
||||
REG_A = 0xa,
|
||||
REG_B = 0xb,
|
||||
REG_C = 0xc,
|
||||
REG_D = 0xd
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
REG_A_RS0 = 1,
|
||||
REG_A_RS1 = 2,
|
||||
REG_A_RS2 = 4,
|
||||
REG_A_RS3 = 8,
|
||||
REG_A_DV0 = 16,
|
||||
REG_A_DV1 = 32,
|
||||
REG_A_DV2 = 64,
|
||||
REG_A_UIP = 128
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
REG_B_DSE = 1, // TODO: When set the chip will adjust the clock by an hour at start and end of DST
|
||||
REG_B_24_12 = 2,
|
||||
REG_B_DM = 4,
|
||||
REG_B_SQWE = 8, // TODO: When set the chip will output a square wave on SQW pin
|
||||
REG_B_UIE = 16,
|
||||
REG_B_AIE = 32,
|
||||
REG_B_PIE = 64,
|
||||
REG_B_SET = 128,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
REG_C_UF = 16,
|
||||
REG_C_AF = 32,
|
||||
REG_C_PF = 64,
|
||||
REG_C_IRQF = 128
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
REG_D_VRT = 128
|
||||
};
|
||||
|
||||
// internal helpers
|
||||
int to_ram(int a);
|
||||
int from_ram(int a);
|
||||
void set_base_datetime();
|
||||
void update_irq();
|
||||
void update_timer();
|
||||
|
||||
int get_seconds();
|
||||
void set_seconds(int seconds);
|
||||
int get_minutes();
|
||||
void set_minutes(int minutes);
|
||||
int get_hours();
|
||||
void set_hours(int hours);
|
||||
int get_dayofweek();
|
||||
void set_dayofweek(int dayofweek);
|
||||
int get_dayofmonth();
|
||||
void set_dayofmonth(int dayofmonth);
|
||||
int get_month();
|
||||
void set_month(int month);
|
||||
int get_year();
|
||||
void set_year(int year);
|
||||
|
||||
// internal state
|
||||
static const int MC146818_DATA_SIZE = 0x80;
|
||||
|
||||
mc146818_type m_type;
|
||||
// TODO: MC146818 only has 64 bytes, but semi-compatible chips have more.
|
||||
// drivers are using this device when the actual hardware uses a different
|
||||
// chip (which in most cases also has additional functionality).
|
||||
static const int MC146818_DATA_SIZE = 128;
|
||||
|
||||
UINT8 m_index;
|
||||
UINT8 m_data[MC146818_DATA_SIZE];
|
||||
|
||||
UINT16 m_eindex;
|
||||
UINT8 m_edata[0x2000];
|
||||
|
||||
bool m_updated; /* update ended interrupt flag */
|
||||
|
||||
attotime m_last_refresh;
|
||||
attotime m_period;
|
||||
|
||||
static const device_timer_id TIMER_CLOCK = 0;
|
||||
static const device_timer_id TIMER_PERIODIC = 1;
|
||||
|
||||
emu_timer *m_clock_timer;
|
||||
emu_timer *m_periodic_timer;
|
||||
|
||||
devcb2_write_line m_write_irq;
|
||||
int m_century_index;
|
||||
bool m_use_utc;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1709,7 +1709,7 @@ static MACHINE_CONFIG_START( aristmk4, aristmk4_state )
|
||||
MCFG_VIA6522_ADD("via6522_0", 0, via_interface) /* 1 MHz.(only 1 or 2 MHz.are valid) */
|
||||
MCFG_PIA6821_ADD("pia6821_0", aristmk4_pia1_intf)
|
||||
MCFG_MC6845_ADD("crtc", C6545_1, "screen", MAIN_CLOCK/8, mc6845_intf) // TODO: type is unknown
|
||||
MCFG_MC146818_ADD("rtc", MC146818_IGNORE_CENTURY)
|
||||
MCFG_MC146818_ADD( "rtc", XTAL_4_194304Mhz )
|
||||
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
|
||||
|
@ -891,7 +891,7 @@ static MACHINE_CONFIG_START( rastersp, rastersp_state )
|
||||
/* Devices */
|
||||
MCFG_TIMER_DRIVER_ADD("tms_timer1", rastersp_state, tms_timer1)
|
||||
MCFG_TIMER_DRIVER_ADD("tms_tx_timer", rastersp_state, tms_tx_timer)
|
||||
MCFG_MC146818_ADD("rtc", MC146818_STANDARD)
|
||||
MCFG_MC146818_ADD( "rtc", XTAL_32_768kHz )
|
||||
MCFG_NVRAM_HANDLER(rastersp)
|
||||
|
||||
MCFG_NSCSI_BUS_ADD("scsibus")
|
||||
|
@ -228,7 +228,9 @@ MACHINE_CONFIG_FRAGMENT(pcat_common)
|
||||
MCFG_I8237_ADD( "dma8237_1", XTAL_14_31818MHz/3, dma8237_1_config )
|
||||
MCFG_I8237_ADD( "dma8237_2", XTAL_14_31818MHz/3, dma8237_2_config )
|
||||
MCFG_PIT8254_ADD( "pit8254", at_pit8254_config )
|
||||
MCFG_MC146818_IRQ_ADD("rtc", MC146818_STANDARD, DEVWRITELINE("pic8259_2", pic8259_device, ir0_w))
|
||||
MCFG_MC146818_ADD("rtc", XTAL_32_768kHz)
|
||||
MCFG_MC146818_IRQ_HANDLER(DEVWRITELINE("pic8259_2", pic8259_device, ir0_w))
|
||||
MCFG_MC146818_CENTURY_INDEX(0x32)
|
||||
|
||||
MCFG_KBDC8042_ADD("kbdc", at8042)
|
||||
MACHINE_CONFIG_END
|
||||
|
@ -372,7 +372,7 @@ static MACHINE_CONFIG_START( ppc512, amstrad_pc_state )
|
||||
MCFG_FLOPPY_DRIVE_ADD("fdc:0", ibmpc_floppies, "525dd", ibmpc_floppy_formats)
|
||||
MCFG_FLOPPY_DRIVE_ADD("fdc:1", ibmpc_floppies, "525dd", ibmpc_floppy_formats)
|
||||
|
||||
MCFG_MC146818_ADD( "rtc", MC146818_IGNORE_CENTURY )
|
||||
MCFG_MC146818_ADD( "rtc", XTAL_32_768kHz )
|
||||
|
||||
/* internal ram */
|
||||
MCFG_RAM_ADD(RAM_TAG)
|
||||
|
@ -1016,7 +1016,7 @@ static MACHINE_CONFIG_DERIVED( aleste, amstrad )
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
|
||||
MCFG_PALETTE_LENGTH(32+64)
|
||||
MCFG_PALETTE_INIT_OVERRIDE(amstrad_state,aleste)
|
||||
MCFG_MC146818_ADD( "rtc", MC146818_IGNORE_CENTURY )
|
||||
MCFG_MC146818_ADD( "rtc", XTAL_4_194304Mhz )
|
||||
|
||||
MCFG_DEVICE_REMOVE("upd765")
|
||||
MCFG_I8272A_ADD("upd765", true)
|
||||
|
@ -339,7 +339,9 @@ static MACHINE_CONFIG_FRAGMENT( at_motherboard )
|
||||
MCFG_AT_KEYBOARD_CONTROLLER_ADD("keybc", XTAL_12MHz, keyboard_controller_intf)
|
||||
MCFG_PC_KBDC_ADD("pc_kbdc", pc_kbdc_intf)
|
||||
|
||||
MCFG_MC146818_IRQ_ADD( "rtc", MC146818_STANDARD, WRITELINE(at_state, at_mc146818_irq))
|
||||
MCFG_MC146818_ADD( "rtc", XTAL_32_768kHz )
|
||||
MCFG_MC146818_IRQ_HANDLER(WRITELINE(at_state, at_mc146818_irq))
|
||||
MCFG_MC146818_CENTURY_INDEX(0x32)
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
|
@ -872,7 +872,7 @@ static MACHINE_CONFIG_START( bbcm, bbc_state )
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
|
||||
|
||||
/* rtc and cmos */
|
||||
MCFG_MC146818_ADD( "rtc", MC146818_IGNORE_CENTURY )
|
||||
MCFG_MC146818_ADD( "rtc", XTAL_32_768kHz )
|
||||
|
||||
/* printer */
|
||||
MCFG_CENTRONICS_PRINTER_ADD("centronics", bbcb_centronics_config)
|
||||
|
@ -233,7 +233,7 @@ static MACHINE_CONFIG_START( bebox, bebox_state )
|
||||
MCFG_SMC37C78_ADD("smc37c78")
|
||||
MCFG_FLOPPY_DRIVE_ADD("smc37c78:0", bebox_floppies, "35hd", bebox_state::floppy_formats)
|
||||
|
||||
MCFG_MC146818_ADD( "rtc", MC146818_STANDARD )
|
||||
MCFG_MC146818_ADD( "rtc", XTAL_32_768kHz )
|
||||
|
||||
MCFG_KBDC8042_ADD("kbdc", bebox_8042_interface)
|
||||
/* internal ram */
|
||||
|
@ -860,7 +860,8 @@ static MACHINE_CONFIG_START( hx20, hx20_state )
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
|
||||
|
||||
// devices
|
||||
MCFG_MC146818_IRQ_ADD(MC146818_TAG, MC146818_STANDARD, WRITELINE(hx20_state, rtc_irq_w))
|
||||
MCFG_MC146818_ADD(MC146818_TAG, XTAL_4_194304Mhz)
|
||||
MCFG_MC146818_IRQ_HANDLER(WRITELINE(hx20_state, rtc_irq_w))
|
||||
MCFG_RS232_PORT_ADD(RS232_TAG, rs232_intf, default_rs232_devices, NULL)
|
||||
MCFG_CASSETTE_ADD(CASSETTE_TAG, default_cassette_interface)
|
||||
MCFG_EPSON_SIO_ADD("sio", "tf20")
|
||||
|
@ -855,7 +855,7 @@ static MACHINE_CONFIG_DERIVED( mbee256, mbee128 )
|
||||
MCFG_CPU_MODIFY( "maincpu" )
|
||||
MCFG_CPU_IO_MAP(mbee256_io)
|
||||
MCFG_MACHINE_RESET_OVERRIDE(mbee_state, mbee256 )
|
||||
MCFG_MC146818_ADD( "rtc", MC146818_STANDARD )
|
||||
MCFG_MC146818_ADD( "rtc", XTAL_32_768kHz )
|
||||
MCFG_DEVICE_REMOVE("crtc")
|
||||
MCFG_MC6845_ADD("crtc", SY6545_1, "screen", XTAL_13_5MHz / 8, mbee256_crtc)
|
||||
MACHINE_CONFIG_END
|
||||
@ -865,7 +865,7 @@ static MACHINE_CONFIG_DERIVED( mbeett, mbeeppc )
|
||||
MCFG_CPU_PROGRAM_MAP(mbeett_mem)
|
||||
MCFG_CPU_IO_MAP(mbeett_io)
|
||||
MCFG_MACHINE_RESET_OVERRIDE(mbee_state, mbeett )
|
||||
MCFG_MC146818_ADD( "rtc", MC146818_STANDARD )
|
||||
MCFG_MC146818_ADD( "rtc", XTAL_32_768kHz )
|
||||
MCFG_DEVICE_REMOVE("crtc")
|
||||
MCFG_MC6845_ADD("crtc", SY6545_1, "screen", XTAL_13_5MHz / 8, mbee256_crtc)
|
||||
MACHINE_CONFIG_END
|
||||
|
@ -391,7 +391,8 @@ static MACHINE_CONFIG_START( micronic, micronic_state )
|
||||
|
||||
MCFG_NVRAM_HANDLER(micronic)
|
||||
|
||||
MCFG_MC146818_IRQ_ADD( MC146818_TAG, MC146818_IGNORE_CENTURY, WRITELINE(micronic_state, mc146818_irq))
|
||||
MCFG_MC146818_ADD( MC146818_TAG, XTAL_4_194304Mhz )
|
||||
MCFG_MC146818_IRQ_HANDLER(WRITELINE(micronic_state, mc146818_irq))
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
/* ROM definition */
|
||||
|
@ -1644,7 +1644,7 @@ static MACHINE_CONFIG_DERIVED( nc200, nc100 )
|
||||
MCFG_FLOPPY_DRIVE_ADD("upd765:0", ibmpc_floppies, "525dd", ibmpc_floppy_formats)
|
||||
MCFG_FLOPPY_DRIVE_ADD("upd765:1", ibmpc_floppies, "525dd", ibmpc_floppy_formats)
|
||||
|
||||
MCFG_MC146818_ADD( "mc", MC146818_STANDARD )
|
||||
MCFG_MC146818_ADD( "mc", XTAL_4_194304Mhz )
|
||||
|
||||
/* internal ram */
|
||||
MCFG_RAM_MODIFY(RAM_TAG)
|
||||
|
@ -179,7 +179,7 @@ static MACHINE_CONFIG_START( orionz80, orion_state )
|
||||
|
||||
MCFG_VIDEO_START_OVERRIDE(orion_state,orion128)
|
||||
|
||||
MCFG_MC146818_ADD( "rtc", MC146818_IGNORE_CENTURY )
|
||||
MCFG_MC146818_ADD( "rtc", XTAL_4_194304Mhz )
|
||||
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
|
||||
|
@ -14,7 +14,6 @@
|
||||
TODO:
|
||||
|
||||
- adjust mouse speed
|
||||
- RTC should not be y2k compliant
|
||||
- pc1512 V3 VDU check fails
|
||||
- Amstrad SM2400 internal modem
|
||||
- Amstrad RP4 diagnostic ISA card (PC1512)
|
||||
@ -1305,7 +1304,8 @@ static MACHINE_CONFIG_START( pc1512, pc1512_state )
|
||||
MCFG_I8237_ADD(I8237A5_TAG, XTAL_24MHz/6, dmac_intf)
|
||||
MCFG_PIC8259_ADD(I8259A2_TAG, INPUTLINE(I8086_TAG, INPUT_LINE_IRQ0), VCC, NULL)
|
||||
MCFG_PIT8253_ADD(I8253_TAG, pit_intf)
|
||||
MCFG_MC146818_IRQ_ADD(MC146818_TAG, MC146818_STANDARD, DEVWRITELINE(I8259A2_TAG, pic8259_device, ir2_w))
|
||||
MCFG_MC146818_ADD(MC146818_TAG, XTAL_32_768kHz)
|
||||
MCFG_MC146818_IRQ_HANDLER(DEVWRITELINE(I8259A2_TAG, pic8259_device, ir2_w))
|
||||
MCFG_PC_FDC_XT_ADD(PC_FDC_XT_TAG)
|
||||
MCFG_FLOPPY_DRIVE_ADD(PC_FDC_XT_TAG ":0", pc1512_floppies, "525dd", pc1512_state::floppy_formats)
|
||||
MCFG_FLOPPY_DRIVE_ADD(PC_FDC_XT_TAG ":1", pc1512_floppies, NULL, pc1512_state::floppy_formats)
|
||||
@ -1368,7 +1368,8 @@ static MACHINE_CONFIG_START( pc1640, pc1640_state )
|
||||
MCFG_I8237_ADD(I8237A5_TAG, XTAL_24MHz/6, dmac_intf)
|
||||
MCFG_PIC8259_ADD(I8259A2_TAG, INPUTLINE(I8086_TAG, INPUT_LINE_IRQ0), VCC, NULL)
|
||||
MCFG_PIT8253_ADD(I8253_TAG, pit_intf)
|
||||
MCFG_MC146818_IRQ_ADD(MC146818_TAG, MC146818_STANDARD, DEVWRITELINE(I8259A2_TAG, pic8259_device, ir2_w))
|
||||
MCFG_MC146818_ADD(MC146818_TAG, XTAL_32_768kHz)
|
||||
MCFG_MC146818_IRQ_HANDLER(DEVWRITELINE(I8259A2_TAG, pic8259_device, ir2_w))
|
||||
MCFG_PC_FDC_XT_ADD(PC_FDC_XT_TAG)
|
||||
MCFG_FLOPPY_DRIVE_ADD(PC_FDC_XT_TAG ":0", pc1512_floppies, "525dd", pc1512_state::floppy_formats)
|
||||
MCFG_FLOPPY_DRIVE_ADD(PC_FDC_XT_TAG ":1", pc1512_floppies, NULL, pc1512_state::floppy_formats)
|
||||
|
@ -882,7 +882,8 @@ static MACHINE_CONFIG_START( qx10, qx10_state )
|
||||
MCFG_I8237_ADD("8237dma_1", MAIN_CLK/4, qx10_dma8237_1_interface)
|
||||
MCFG_I8237_ADD("8237dma_2", MAIN_CLK/4, qx10_dma8237_2_interface)
|
||||
MCFG_UPD7220_ADD("upd7220", MAIN_CLK/6, hgdc_intf, upd7220_map) // unk clock
|
||||
MCFG_MC146818_IRQ_ADD( "rtc", MC146818_STANDARD, DEVWRITELINE("pic8259_slave", pic8259_device, ir2_w))
|
||||
MCFG_MC146818_ADD( "rtc", XTAL_32_768kHz )
|
||||
MCFG_MC146818_IRQ_HANDLER(DEVWRITELINE("pic8259_slave", pic8259_device, ir2_w))
|
||||
MCFG_UPD765A_ADD("upd765", true, true)
|
||||
MCFG_FLOPPY_DRIVE_ADD("upd765:0", qx10_floppies, "525dd", floppy_image_device::default_floppy_formats)
|
||||
MCFG_FLOPPY_DRIVE_ADD("upd765:1", qx10_floppies, "525dd", floppy_image_device::default_floppy_formats)
|
||||
|
@ -490,7 +490,7 @@ static MACHINE_CONFIG_START( sgi_ip2, sgi_ip2_state )
|
||||
|
||||
MCFG_DUART68681_ADD( "duart68681a", XTAL_3_6864MHz, sgi_ip2_duart68681a_config ) /* Y3 3.6864MHz Xtal ??? copy-over from dectalk */
|
||||
MCFG_DUART68681_ADD( "duart68681b", XTAL_3_6864MHz, sgi_ip2_duart68681b_config ) /* Y3 3.6864MHz Xtal ??? copy-over from dectalk */
|
||||
MCFG_MC146818_ADD( "rtc", MC146818_IGNORE_CENTURY )
|
||||
MCFG_MC146818_ADD( "rtc", XTAL_4_194304Mhz )
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
|
@ -1394,7 +1394,8 @@ MACHINE_CONFIG_FRAGMENT( apollo )
|
||||
MCFG_PIC8259_ADD( APOLLO_PIC2_TAG, WRITELINE(apollo_state,apollo_pic8259_slave_set_int_line), GND, NULL)
|
||||
|
||||
MCFG_PTM6840_ADD(APOLLO_PTM_TAG, apollo_ptm_config)
|
||||
MCFG_MC146818_ADD( APOLLO_RTC_TAG, MC146818_UTC )
|
||||
MCFG_MC146818_ADD( APOLLO_RTC_TAG, XTAL_4_194304Mhz )
|
||||
MCFG_MC146818_UTC( true )
|
||||
MCFG_DUART68681_ADD( APOLLO_SIO_TAG, XTAL_3_6864MHz, apollo_sio_config )
|
||||
MCFG_DUART68681_ADD( APOLLO_SIO2_TAG, XTAL_3_6864MHz, apollo_sio2_config )
|
||||
|
||||
|
@ -170,7 +170,9 @@ static MACHINE_CONFIG_FRAGMENT( cs4031 )
|
||||
MCFG_PIC8259_ADD("intc1", WRITELINE(cs4031_device, intc1_int_w), VCC, READ8(cs4031_device, intc1_slave_ack_r))
|
||||
MCFG_PIC8259_ADD("intc2", DEVWRITELINE("intc1", pic8259_device, ir2_w), GND, NULL)
|
||||
MCFG_PIT8254_ADD("ctc", cs4031_pit_config)
|
||||
MCFG_MC146818_IRQ_ADD("rtc", MC146818_STANDARD, WRITELINE(cs4031_device, rtc_irq_w))
|
||||
MCFG_MC146818_ADD("rtc", XTAL_32_768kHz)
|
||||
MCFG_MC146818_IRQ_HANDLER(WRITELINE(cs4031_device, rtc_irq_w))
|
||||
MCFG_MC146818_CENTURY_INDEX(0x32)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
machine_config_constructor cs4031_device::device_mconfig_additions() const
|
||||
@ -317,8 +319,7 @@ void cs4031_device::device_start()
|
||||
m_space_io->install_readwrite_handler(0x0060, 0x0063, read8_delegate(FUNC(cs4031_device::keyb_data_r), this), write8_delegate(FUNC(cs4031_device::keyb_data_w), this), 0x000000ff);
|
||||
m_space_io->install_readwrite_handler(0x0060, 0x0063, read8_delegate(FUNC(cs4031_device::portb_r), this), write8_delegate(FUNC(cs4031_device::portb_w), this), 0x0000ff00);
|
||||
m_space_io->install_readwrite_handler(0x0064, 0x0067, read8_delegate(FUNC(cs4031_device::keyb_status_r), this), write8_delegate(FUNC(cs4031_device::keyb_command_w), this), 0x000000ff);
|
||||
m_space_io->install_write_handler(0x0070, 0x0073, write8_delegate(FUNC(cs4031_device::rtc_w), this), 0x000000ff);
|
||||
m_space_io->install_readwrite_handler(0x0070, 0x0073, read8_delegate(FUNC(mc146818_device::data_r), &(*m_rtc)), write8_delegate(FUNC(mc146818_device::data_w), &(*m_rtc)), 0x0000ff00);
|
||||
m_space_io->install_readwrite_handler(0x0070, 0x0073, read8_delegate(FUNC(mc146818_device::read), &(*m_rtc)), write8_delegate(FUNC(cs4031_device::rtc_w), this), 0x0000ffff);
|
||||
m_space_io->install_readwrite_handler(0x0080, 0x008f, read8_delegate(FUNC(cs4031_device::dma_page_r), this), write8_delegate(FUNC(cs4031_device::dma_page_w), this), 0xffffffff);
|
||||
m_space_io->install_readwrite_handler(0x0090, 0x0093, read8_delegate(FUNC(cs4031_device::sysctrl_r), this), write8_delegate(FUNC(cs4031_device::sysctrl_w), this), 0x00ff0000);
|
||||
m_space_io->install_readwrite_handler(0x00a0, 0x00a3, read8_delegate(FUNC(pic8259_device::read), &(*m_intc2)), write8_delegate(FUNC(pic8259_device::write), &(*m_intc2)), 0x0000ffff);
|
||||
@ -993,6 +994,11 @@ WRITE8_MEMBER( cs4031_device::rtc_w )
|
||||
if (0)
|
||||
logerror("cs4031_device::rtc_w: %02x\n", data);
|
||||
|
||||
m_nmi_mask = !BIT(data, 7);
|
||||
m_rtc->address_w(space, 0, data & 0x7f);
|
||||
if (offset == 0)
|
||||
{
|
||||
m_nmi_mask = !BIT(data, 7);
|
||||
data &= 0x7f;
|
||||
}
|
||||
|
||||
m_rtc->write(space, offset, data);
|
||||
}
|
||||
|
@ -114,7 +114,9 @@ static MACHINE_CONFIG_FRAGMENT( southbridge )
|
||||
MCFG_PC_KBDC_ADD("pc_kbdc", pc_kbdc_intf)
|
||||
MCFG_PC_KBDC_SLOT_ADD("pc_kbdc", "kbd", pc_at_keyboards, STR_KBD_MICROSOFT_NATURAL)
|
||||
|
||||
MCFG_MC146818_IRQ_ADD("rtc", MC146818_STANDARD, DEVWRITELINE("pic8259_slave", pic8259_device, ir0_w))
|
||||
MCFG_MC146818_ADD("rtc", XTAL_32_768kHz)
|
||||
MCFG_MC146818_IRQ_HANDLER(DEVWRITELINE("pic8259_slave", pic8259_device, ir0_w))
|
||||
MCFG_MC146818_CENTURY_INDEX(0x32)
|
||||
|
||||
MCFG_BUS_MASTER_IDE_CONTROLLER_ADD("ide", ata_devices, "hdd", NULL, false)
|
||||
MCFG_ATA_INTERFACE_IRQ_HANDLER(DEVWRITELINE("pic8259_slave", pic8259_device, ir6_w))
|
||||
|
Loading…
Reference in New Issue
Block a user