uae_u32 passed;
uae_u16 inputpipe;
uae_u32 loaddelay;
+ uae_u8 preovfl;
uae_u8 cr;
};
static struct rtc_ricoh_data rtc_ricoh;
static int internaleclockphase;
+static bool cia_cycle_accurate;
static bool acc_mode(void)
{
- return currprefs.m68k_speed >= 0 && currprefs.cpu_compatible;
+ return cia_cycle_accurate;
}
int blop, blop2;
if (c->icr1 & c->imask & ICR_MASK) {
#if CIAA_DEBUG_IRQ
- write_log(_T("CIA%c IRQ %02X\n"), num ? 'B' : 'A', c->icr);
+ write_log(_T("CIA%c IRQ %02X %02X\n"), num ? 'B' : 'A', c->icr1, c->icr2);
#endif
if (!(c->icr1 & 0x80)) {
c->icr1 |= 0x80 | 0x40;
static void timer_reset(struct CIATimer *t)
{
t->timer = t->latch;
- if (t->cr & CR_RUNMODE) {
- t->inputpipe &= ~CIA_PIPE_CLR1;
- } else {
- t->inputpipe &= ~CIA_PIPE_CLR2;
+ if (acc_mode()) {
+ if (t->cr & CR_RUNMODE) {
+ t->inputpipe &= ~CIA_PIPE_CLR1;
+ } else {
+ t->inputpipe &= ~CIA_PIPE_CLR2;
+ }
}
}
{
int ccout = cc;
- if (cc == 1) {
+ if (cc == 1 && acc_mode()) {
int out = t->inputpipe & CIA_PIPE_OUTPUT;
t->inputpipe >>= 1;
if ((t->cr & crmask) == CR_START) {
for (int tn = 0; tn < 2; tn++) {
struct CIATimer *t = &c->t[tn];
- if (ovfl[tn]) {
+ if (ovfl[tn] || t->preovfl) {
c->icr2 |= tn ? ICR_B : ICR_A;
t->timer = t->latch;
if (!loaded[tn]) {
// timer does not stop.
if (!loaded2[tn]) {
t->cr &= ~CR_START;
+ if (!acc_mode()) {
+ t->inputpipe = 0;
+ }
+ }
+ if (acc_mode()) {
+ t->inputpipe &= ~CIA_PIPE_CLR2;
}
- t->inputpipe &= ~CIA_PIPE_CLR2;
} else {
- t->inputpipe &= ~CIA_PIPE_CLR1;
+ if (acc_mode()) {
+ t->inputpipe &= ~CIA_PIPE_CLR1;
+ }
}
}
icr |= 1 << num;
+ t->preovfl = false;
}
}
if (!acc_mode()) {
c->icr1 |= c->icr2;
c->icr2 = 0;
- }
- if (icr) {
- c->icr_change = true;
+ } else {
+ if (icr) {
+ c->icr_change = true;
+ }
}
}
}
// modes. Real hardware value written to ciabtod by KS is always
// at least 1 or larger due to bus cycle delays when reading
// old value.
-#if 1
+#if 0
if (num) {
if (!currprefs.cpu_compatible && (munge24(m68k_getpc()) & 0xFFF80000) != 0xF80000) {
if (c->tod == 0 && c->alarm == 0)
heartbeat_cnt = 10;
}
-static void do_tod_hack(int dotod)
+static void do_tod_hack(void)
{
struct timeval tv;
static int oldrate;
docount = 1;
}
- if (!dotod && currprefs.cs_ciaatod == 0)
+ if (currprefs.cs_ciaatod == 0)
return;
if (tod_hack_delay > 0) {
return;
int hpos = current_hpos();
hpos -= c->tod_offset;
- if (hpos >= 0 || currprefs.m68k_speed < 0) {
+ if (hpos >= 0 || !acc_mode()) {
// Program should see the changed TOD
CIA_tod_inc(true, num);
return;
void CIAA_tod_handler(int hoffset)
{
+ struct CIA *c = &cia[0];
#ifdef TOD_HACK
if (currprefs.tod_hack && tod_hack_enabled == 1) {
- cia[0].tod_event_state = 0;
+ c->tod_event_state = 0;
return;
}
#endif
// custom hsync
if (resetwarning_phase) {
resetwarning_check();
- while (keys_available())
+ while (keys_available()) {
get_next_key();
+ }
} else {
- if ((hsync_counter & 15) == 0)
+ if ((hsync_counter & 15) == 0) {
check_keyboard();
+ }
}
} else {
while (keys_available()) {
get_next_key();
}
}
+
if (!ciahsync) {
- // Delayed CIA-A VSync pulse
+ // Increase CIA-A TOD if delayed from previous line
cia_delayed_tod(0);
if (currprefs.tod_hack && cia[0].todon) {
- do_tod_hack(dotod);
+ do_tod_hack();
}
}
+
}
static void calc_led(int old_led)
#endif
}
}
+
+ cia_cycle_accurate = currprefs.m68k_speed >= 0 && currprefs.cpu_compatible;
}
static void check_led(void)
struct CIA *c = &cia[num];
struct CIATimer *t = &c->t[tnum];
- uae_u16 latch_old = t->latch;
t->latch = (t->latch & 0xff) | (val << 8);
- t->loaddelay |= 1 << 2;
- if (!(t->cr & CR_START)) {
- t->loaddelay |= 1 << 1;
- }
+ if (!acc_mode()) {
+ // if inaccurate mode: do everything immediately
+
+ if (!(t->cr & CR_START)) {
+ t->timer = t->latch;
+ }
+
+ if (t->cr & CR_RUNMODE) {
+ t->cr |= CR_START;
+ t->inputpipe = CIA_PIPE_ALL_MASK;
+ }
- if (t->cr & CR_RUNMODE) {
- t->cr |= CR_START;
- t->loaddelay |= 0x01000000 << 1;
+ if (t->cr & CR_START) {
+ if (t->timer <= 1) {
+ t->preovfl = true;
+ }
+ }
+
+ } else {
+ // if accurate mode: handle delays cycle-accurately
+
+ t->loaddelay |= 1 << 2;
+
+ if (!(t->cr & CR_START)) {
+ t->loaddelay |= 1 << 1;
+ }
+
+ if (t->cr & CR_RUNMODE) {
+ t->cr |= CR_START;
+ t->loaddelay |= 0x01000000 << 1;
+ }
}
}
val &= 0x7f; /* bit 7 is unused */
}
- if (val & CR_LOAD) {
- val &= ~CR_LOAD;
- t->loaddelay |= 0x0001 << 2;
- t->loaddelay |= 0x0100 << 0;
- if (!(t->cr & CR_START)) {
- t->loaddelay |= 0x0001 << 1;
+ if (!acc_mode()) {
+ // if inaccurate mode: do everything immediately
+
+ if (val & CR_LOAD) {
+ val &= ~CR_LOAD;
+ t->timer = t->latch;
}
+ if (val & CR_START) {
+ t->inputpipe = CIA_PIPE_ALL_MASK;
+ if (t->timer <= 1) {
+ t->preovfl = true;
+ }
+ } else {
+ t->inputpipe = 0;
+ }
+
} else {
- if ((val & CR_START)) {
- t->loaddelay |= 0x010000 << 0;
+ // if accurate mode: handle delays cycle-accurately
+
+ if (val & CR_LOAD) {
+ val &= ~CR_LOAD;
+ t->loaddelay |= 0x0001 << 2;
+ t->loaddelay |= 0x0100 << 0;
+ if (!(t->cr & CR_START)) {
+ t->loaddelay |= 0x0001 << 1;
+ }
+ } else {
+ if ((val & CR_START)) {
+ t->loaddelay |= 0x010000 << 0;
+ }
}
- }
- if (!(val & CR_START)) {
- t->inputpipe &= ~CIA_PIPE_CLR1;
+ if (!(val & CR_START)) {
+ t->inputpipe &= ~CIA_PIPE_CLR1;
+ }
}
t->cr = val;