*
* Copyright 1995 Bernd Schmidt, Alessandro Bissacco
* Copyright 1996, 1997 Stefan Reinauer, Christian Schmitt
+* Copyright 2022 Toni Wilen
*/
#define DONGLE_DEBUG 0
#define KB_DEBUG 0
#define CLOCK_DEBUG 0
+#define CIA_EVERY_CYCLE_DEBUG 0
#define TOD_HACK
+#define CIA_IRQ_PROCESS_DELAY 0
+
+#define CR_START 1
+#define CR_PBON 2
+#define CR_OUTMODE 4
+#define CR_RUNMODE 8
+#define CR_LOAD 0x10
+#define CR_INMODE 0x20
+#define CR_INMODE1 0x40
+#define CR_SPMODE 0x40
+#define CR_ALARM 0x80
+
+#define ICR_A 1
+#define ICR_B 2
+#define ICR_ALARM 4
+#define ICR_SP 8
+#define ICR_FLAG 0x10
+#define ICR_MASK 0x1f
+
+#define CIA_PIPE_ALL_BITS 2
+#define CIA_PIPE_ALL_MASK ((1 << CIA_PIPE_ALL_BITS) - 1)
+#define CIA_PIPE_INPUT 2
+#define CIA_PIPE_CLR1 1
+#define CIA_PIPE_CLR2 3
+#define CIA_PIPE_OUTPUT 1
+
/* Akiko internal CIA differences:
- BFE101 and BFD100: reads 3F if data direction is in.
*/
-/* e-clock is 10 CPU cycles, 6 cycles low, 4 high
-* data transfer happens during 4 high cycles
-*/
-#define ECLOCK_WAIT_CYCLE 6
-#define ECLOCK_DATA_CYCLE 4
+#define E_CLOCK_SYNC 2
+#define E_CLOCK_1 4
+#define E_CLOCK_2 6
+
+#define E_CLOCK_LENGTH (E_CLOCK_1 + E_CLOCK_2)
+#define E_CYCLE_UNIT (CYCLE_UNIT / 2)
+#define DIV10 ((E_CLOCK_LENGTH) * E_CYCLE_UNIT) /* Yes, a bad identifier. */
-#define DIV10 ((ECLOCK_WAIT_CYCLE + ECLOCK_DATA_CYCLE) * CYCLE_UNIT / 2) /* Yes, a bad identifier. */
-#define CIASTARTCYCLESHI 2
-#define CIASTARTCYCLESCRA 1
-static uae_u32 ciaaicr, ciaaimask, ciabicr, ciabimask;
-static uae_u32 ciaacra, ciaacrb, ciabcra, ciabcrb;
-static uae_u32 ciaastarta, ciaastartb, ciabstarta, ciabstartb;
+struct CIATimer
+{
+ uae_u16 timer;
+ uae_u16 latch;
+ uae_u32 passed;
+ uae_u16 inputpipe;
+ uae_u32 loaddelay;
+ uae_u8 cr;
+};
-/* Values of the CIA timers. */
-static uae_u32 ciaata, ciaatb, ciabta, ciabtb;
-/* Computed by compute_passed_time. */
-static uae_u32 ciaata_passed, ciaatb_passed, ciabta_passed, ciabtb_passed;
+struct CIA
+{
+ uae_u8 pra, prb;
+ uae_u8 dra, drb;
+ struct CIATimer t[2];
+ uae_u32 tod;
+ uae_u32 tol;
+ uae_u32 alarm;
+ uae_u32 tlatch;
+ uae_u8 todon;
+ int tod_event_state;
+ int tod_offset;
+ uae_u8 icr1, icr2;
+ bool icr_change;
+ uae_u8 imask;
+ uae_u8 sdr;
+ uae_u8 sdr_buf;
+ uae_u8 sdr_load;
+ uae_u8 sdr_cnt;
+};
+
+static struct CIA cia[2];
-static uae_u32 ciaatod, ciabtod, ciaatol, ciabtol, ciaaalarm, ciabalarm;
-static int ciaatlatch, ciabtlatch;
static bool oldovl;
static bool led;
static int led_old_brightness;
static evt_t led_cycles_on, led_cycles_off, led_cycle;
-uae_u32 ciabpra;
-
-static uae_u32 ciaala, ciaalb, ciabla, ciablb;
-static int ciaatodon, ciabtodon;
-static uae_u32 ciaapra, ciaaprb, ciaadra, ciaadrb, ciaasdr, ciaasdr_buf, ciaasdr_load, ciaasdr_cnt;
-static uae_u32 ciabprb, ciabdra, ciabdrb, ciabsdr, ciabsdr_buf, ciabsdr_load, ciabsdr_cnt;
static int kbstate, kblostsynccnt;
static evt_t kbhandshakestart;
static uae_u8 kbcode;
static uae_u8 serbits;
-static int warned = 10;
+static int warned = 100;
static struct rtc_msm_data rtc_msm;
static struct rtc_ricoh_data rtc_ricoh;
-static void setclr (uae_u32 *p, uae_u32 val)
+static bool acc_mode(void)
+{
+ return currprefs.m68k_speed >= 0 && currprefs.cpu_compatible;
+}
+
+int blop;
+// temporary e-clock phase shortcut
+static evt_t get_e_cycles(void)
+{
+ if (blop > 4) {
+ blop = 0;
+ }
+
+ evt_t c = get_cycles();
+ c += currprefs.cs_eclockphase * E_CYCLE_UNIT;
+ c += blop * 2 * E_CYCLE_UNIT;
+ return c;
+}
+
+static void setclr(uae_u8 *p, uae_u8 val)
{
if (val & 0x80) {
*p |= val & 0x7F;
}
}
+#if CIA_IRQ_PROCESS_DELAY
/* delay interrupt after current CIA register access if
* interrupt would have triggered mid access
*/
static int cia_interrupt_disabled;
static int cia_interrupt_delay;
+#endif
-static void ICR (uae_u32 data)
+static void ICRIRQ(uae_u32 data)
{
safe_interrupt_set(IRQ_SOURCE_CIA, 0, (data & 0x2000) != 0);
}
-static void ICRA (uae_u32 dummy)
+static void ICR(uae_u32 num)
{
- if (ciaaicr & 0x80)
- ciaaicr |= 0x40;
-#if 1
- if (currprefs.cpu_memory_cycle_exact && !(ciaaicr & 0x20) && (cia_interrupt_disabled & 1)) {
- cia_interrupt_delay |= 1;
-#if CIAB_DEBUG_IRQ
- write_log(_T("ciab interrupt disabled ICR=%02X PC=%x\n"), ciabicr, M68K_GETPC);
-#endif
- return;
- }
-#endif
- ciaaicr |= 0x20;
- ICR (0x0008);
-}
+ struct CIA *c = &cia[num];
-static void ICRB (uae_u32 dummy)
-{
- if (ciabicr & 0x80)
- ciabicr |= 0x40;
-#if 1
- if (currprefs.cpu_memory_cycle_exact && !(ciabicr & 0x20) && (cia_interrupt_disabled & 2)) {
- cia_interrupt_delay |= 2;
+#if CIA_IRQ_PROCESS_DELAY
+ if (currprefs.cpu_memory_cycle_exact && !(c->icr & 0x20) && (cia_interrupt_disabled & (1 << num))) {
+ c->cia_interrupt_delay |= 1 << num;
#if CIAB_DEBUG_IRQ
- write_log(_T("ciab interrupt disabled ICR=%02X PC=%x\n"), ciabicr, M68K_GETPC);
+ write_log(_T("cia%c interrupt disabled ICR=%02X PC=%x\n"), num ? 'b' : 'a', c->icr, M68K_GETPC);
#endif
return;
}
#endif
- ciabicr |= 0x20;
- if (currprefs.cs_compatible == CP_VELVET) {
- // Both CIAs in Velvet are connected to level 2.
- ICR (0x0008);
+ c->icr1 |= 0x20;
+ if (num && currprefs.cs_compatible != CP_VELVET) {
+ ICRIRQ(0x2000);
} else {
- ICR (0x2000);
+ ICRIRQ(0x0008);
}
}
-static void RethinkICRA (void)
+static void RethinkICR(int num)
{
- if (ciaaicr & ciaaimask) {
+ struct CIA *c = &cia[num];
+
+ if (c->icr1 & c->imask & ICR_MASK) {
#if CIAA_DEBUG_IRQ
- write_log (_T("CIAA IRQ %02X\n"), ciaaicr);
+ write_log(_T("CIA%c IRQ %02X\n"), num ? 'B' : 'A', c->icr);
#endif
- if (!(ciaaicr & 0x80)) {
- ciaaicr |= 0x80;
- if (currprefs.cpu_memory_cycle_exact) {
- event2_newevent_xx (-1, DIV10 + 2 * CYCLE_UNIT + CYCLE_UNIT / 2 + 4 * CYCLE_UNIT, 0, ICRA);
- } else {
- ICRA (0);
+ if (!(c->icr1 & 0x80)) {
+ c->icr1 |= 0x80 | 0x40;
+ if (debug_dma) {
+ record_dma_event(num ? DMA_EVENT_CIAB_IRQ : DMA_EVENT_CIAA_IRQ, current_hpos(), vpos);
}
+ ICR(num);
}
}
+
}
-static void RethinkICRB (void)
+void rethink_cias(void)
{
- if (ciabicr & ciabimask) {
-#if CIAB_DEBUG_IRQ
- write_log (_T("CIAB IRQ %02X\n"), ciabicr);
-#endif
- if (!(ciabicr & 0x80)) {
- ciabicr |= 0x80;
- if (currprefs.cpu_memory_cycle_exact) {
- event2_newevent_xx (-1, DIV10 + 2 * CYCLE_UNIT + CYCLE_UNIT / 2 + 4 * CYCLE_UNIT, 0, ICRB);
- } else {
- ICRB (0);
- }
+ if (cia[0].icr1 & 0x40) {
+ ICRIRQ(0x0008);
+ }
+ if (cia[1].icr1 & 0x40) {
+ if (currprefs.cs_compatible == CP_VELVET) {
+ ICRIRQ(0x0008);
+ } else {
+ ICRIRQ(0x2000);
}
}
}
-void rethink_cias (void)
+static uae_u16 bitstodelay(uae_u16 v)
{
- if (ciaaicr & 0x40)
- ICRA (0);
- if (ciabicr & 0x40)
- ICRB (0);
+ switch (v)
+ {
+ case 0:
+ return CIA_PIPE_ALL_BITS - 0;
+ case 1:
+ case 2:
+#if CIA_PIPE_ALL_BITS > 2
+ case 4:
+#endif
+ return CIA_PIPE_ALL_BITS - 1;
+ case 3:
+#if CIA_PIPE_ALL_BITS > 2
+ case 5:
+ case 6:
+#endif
+ return CIA_PIPE_ALL_BITS - 2;
+#if CIA_PIPE_ALL_BITS > 2
+ case 7:
+ return CIA_PIPE_ALL_BITS - 3;
+#endif
+ default:
+ abort();
+ break;
+ }
}
/* Figure out how many CIA timer cycles have passed for each timer since the
last call of CIA_calctimers. */
-static void compute_passed_time (void)
+static void compute_passed_time_cia(int num, uae_u32 ciaclocks)
{
- evt_t ccount = get_cycles() - eventtab[ev_cia].oldcycles;
- if (ccount > MAXINT) {
- ccount = MAXINT;
- }
- uae_u32 ciaclocks = (uae_u32)(ccount / DIV10);
+ struct CIA *c = &cia[num];
- ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0;
+ c->t[0].passed = 0;
+ c->t[1].passed = 0;
- /* CIA A timers */
- if ((ciaacra & 0x21) == 0x01) {
+ if ((c->t[0].cr & (CR_INMODE | CR_START)) == CR_START) {
uae_u32 cc = ciaclocks;
- if (cc > ciaastarta)
- cc -= ciaastarta;
- else
+ int pipe = bitstodelay(c->t[0].inputpipe);
+ if (cc > pipe) {
+ cc -= pipe;
+ } else {
cc = 0;
- assert ((ciaata + 1) >= cc);
- ciaata_passed = cc;
+ }
+ c->t[0].passed = cc;
+ assert(cc < 65536);
}
- if ((ciaacrb & 0x61) == 0x01) {
+ if ((c->t[1].cr & (CR_INMODE | CR_INMODE1 | CR_START)) == CR_START) {
uae_u32 cc = ciaclocks;
- if (cc > ciaastartb)
- cc -= ciaastartb;
- else
+ int pipe = bitstodelay(c->t[1].inputpipe);
+ if (cc > pipe) {
+ cc -= pipe;
+ } else {
cc = 0;
- assert ((ciaatb + 1) >= cc);
- ciaatb_passed = cc;
+ }
+ c->t[1].passed = cc;
+ assert(cc < 65536);
}
+}
- /* CIA B timers */
- if ((ciabcra & 0x21) == 0x01) {
- uae_u32 cc = ciaclocks;
- if (cc > ciabstarta)
- cc -= ciabstarta;
- else
- cc = 0;
- assert ((ciabta + 1) >= cc);
- ciabta_passed = cc;
+static void compute_passed_time(void)
+{
+ evt_t ccount = get_cycles() - eventtab[ev_cia].oldcycles;
+ if (ccount > MAXINT) {
+ ccount = MAXINT;
}
- if ((ciabcrb & 0x61) == 0x01) {
- uae_u32 cc = ciaclocks;
- if (cc > ciabstartb)
- cc -= ciabstartb;
- else
- cc = 0;
- assert ((ciabtb + 1) >= cc);
- ciabtb_passed = cc;
+ uae_u32 ciaclocks = (uae_u32)ccount / DIV10;
+
+ compute_passed_time_cia(0, ciaclocks);
+ compute_passed_time_cia(1, ciaclocks);
+}
+
+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;
}
}
+static uae_u8 cia_inmode_cnt(int num)
+{
+ struct CIA *c = &cia[num];
+ uae_u8 icr = 0;
+ bool decb = false;
+
+ // A INMODE=1 (count CNT pulses)
+ if ((c->t[0].cr & (CR_INMODE | CR_START)) == (CR_INMODE | CR_START)) {
+ c->t[0].timer--;
+ if (c->t[0].timer == 0) {
+ icr |= ICR_A;
+ timer_reset(&c->t[0]);
+ if (c->t[0].cr & CR_RUNMODE) {
+ c->t[0].cr &= ~CR_START;
+ }
+ // B INMODE = 1x (count A undeflows)
+ if ((c->t[1].cr & (CR_INMODE1 | CR_START)) == (CR_INMODE1 | CR_START)) {
+ decb = true;
+ }
+ }
+ }
+ // B INMODE=01 (count CNT pulses)
+ if ((c->t[1].cr & (CR_INMODE1 | CR_INMODE | CR_START)) == (CR_INMODE | CR_START)) {
+ decb = 1;
+ }
+
+ if (decb) {
+ c->t[1].timer--;
+ if (c->t[1].timer == 0) {
+ icr |= ICR_B;
+ timer_reset(&c->t[1]);
+ if (c->t[1].cr & CR_RUNMODE) {
+ c->t[1].cr &= ~CR_START;
+ }
+ }
+ }
+ return icr;
+}
+
+static int process_pipe(struct CIATimer *t, int cc, uae_u8 crmask, int *ovfl)
+{
+ int ccout = cc;
+
+ if (cc == 1) {
+ int out = t->inputpipe & CIA_PIPE_OUTPUT;
+ t->inputpipe >>= 1;
+ if ((t->cr & crmask) == CR_START) {
+ t->inputpipe |= CIA_PIPE_INPUT;
+ }
+ // interrupt 1 cycle early if timer is already zero
+ if (t->timer == 0 && (t->inputpipe & CIA_PIPE_OUTPUT)) {
+ *ovfl = 1;
+ }
+ return out;
+ }
+
+ while (t->inputpipe != CIA_PIPE_ALL_MASK && cc > 0) {
+ if (!(t->inputpipe & CIA_PIPE_OUTPUT)) {
+ ccout--;
+ }
+ t->inputpipe >>= 1;
+ if ((t->cr & crmask) == CR_START) {
+ t->inputpipe |= CIA_PIPE_INPUT;
+ }
+ cc--;
+ }
+
+ return ccout;
+}
+
/* Called to advance all CIA timers to the current time. This expects that
one of the timer values will be modified, and CIA_calctimers will be called
in the same cycle. */
-static int CIA_update_check (void)
+static void CIA_update_check(void)
{
evt_t ccount = get_cycles() - eventtab[ev_cia].oldcycles;
if (ccount > MAXINT) {
ccount = MAXINT;
}
- uae_u32 ciaclocks = (uae_u32)(ccount / DIV10);
+ int ciaclocks = (uae_u32)(ccount / DIV10);
+ if (!ciaclocks) {
+ return;
+ }
- int aovfla = 0, aovflb = 0, asp = 0, bovfla = 0, bovflb = 0, bsp = 0;
- int icr = 0;
+ uae_u8 icr = 0;
+ for (int num = 0; num < 2; num++) {
+ struct CIA *c = &cia[num];
+ int ovfl[2], sp;
+ bool loaded[2], loaded2[2];
- /* CIA A timers */
- // A INMODE=0
- if ((ciaacra & 0x21) == 0x01) {
- bool check = true;
- uae_u32 cc = ciaclocks;
- if (ciaastarta > 0) {
- if (cc > ciaastarta) {
- cc -= ciaastarta;
- ciaastarta = 0;
- } else {
- ciaastarta -= cc;
- check = false;
+ c->icr1 |= c->icr2;
+ c->icr2 = 0;
+ c->icr_change = false;
+
+
+ ovfl[0] = 0;
+ ovfl[1] = 0;
+ sp = 0;
+
+ for (int tn = 0; tn < 2; tn++) {
+ struct CIATimer *t = &c->t[tn];
+
+ loaded[tn] = false;
+ loaded2[tn] = false;
+
+ // CIA special cases
+ if (t->loaddelay) {
+ if (ciaclocks > 1) {
+ abort();
+ }
+ if (t->loaddelay & 1) {
+ t->timer = t->latch;
+ t->inputpipe &= ~CIA_PIPE_CLR1;
+ }
+ if ((t->loaddelay & 0x0100) && t->timer != 0) {
+ loaded2[tn] = true;
+ }
+ if ((t->loaddelay & 0x010000)) {
+ if ((t->timer != 1 || t->latch != 1) && (t->inputpipe & CIA_PIPE_OUTPUT)) {
+ loaded2[tn] = true;
+ }
+ }
+ if ((t->loaddelay & 0x01000000)) {
+ loaded[tn] = true;
+ if (t->timer == 0) {
+ ovfl[tn] = true;
+ }
+ }
+
+ t->loaddelay >>= 1;
+ t->loaddelay &= 0x7f7f7f7f;
}
+
}
- if (check) {
- assert ((ciaata + 1) >= cc);
- if ((ciaata + 1) == cc) {
- // SP in output mode (data sent can be ignored)
- if ((ciaacra & 0x48) == 0x40 && ciaasdr_cnt > 0) {
- ciaasdr_cnt--;
- if (ciaasdr_cnt == 0) {
- asp = 1;
- if (ciaasdr_load) {
- ciaasdr_load = 0;
- ciaasdr_buf = ciaasdr;
- ciaasdr_cnt = 8 * 2;
+
+ // Timer A
+ int cc = 0;
+ if ((c->t[0].cr& (CR_INMODE | CR_START)) == CR_START || c->t[0].inputpipe) {
+ cc = process_pipe(&c->t[0], ciaclocks, CR_INMODE | CR_START, &ovfl[0]);
+ }
+ if (cc > 0) {
+ c->t[0].timer -= cc;
+ if (c->t[0].timer == 0) {
+ // SP in output mode (data sent can be ignored if CIA-A)
+ if ((c->t[0].cr & (CR_SPMODE | CR_RUNMODE)) == CR_SPMODE && c->sdr_cnt > 0) {
+ c->sdr_cnt--;
+ if (c->sdr_cnt == 0) {
+ sp = 1;
+ if (c->sdr_load) {
+ c->sdr_load = 0;
+ c->sdr_buf = c->sdr;
+ c->sdr_cnt = 8 * 2;
}
}
}
- aovfla = 1;
+ ovfl[0] = 1;
// B INMODE=10 or 11
- if ((ciaacrb & 0x61) == 0x41 || (ciaacrb & 0x61) == 0x61) {
- if (ciaatb-- == 0)
- aovflb = 1;
+ if ((c->t[1].cr & (CR_INMODE | CR_INMODE1 | CR_START)) == (CR_INMODE1 | CR_START) || (c->t[1].cr & (CR_INMODE | CR_INMODE1 | CR_START)) == (CR_INMODE | CR_INMODE1 | CR_START)) {
+ c->t[1].inputpipe |= CIA_PIPE_INPUT;
}
}
- ciaata -= cc;
}
- }
- // A INMODE=00
- if ((ciaacrb & 0x61) == 0x01) {
- bool check = true;
- uae_u32 cc = ciaclocks;
- if (ciaastartb > 0) {
- if (cc > ciaastartb) {
- cc -= ciaastartb;
- ciaastartb = 0;
- } else {
- ciaastartb -= cc;
- check = false;
- }
- }
- if (check) {
- assert ((ciaatb + 1) >= cc);
- if ((ciaatb + 1) == cc)
- aovflb = 1;
- ciaatb -= cc;
- }
- }
+ assert(c->t[0].timer < 0x10000);
- /* CIA B timers */
- // A INMODE=0
- if ((ciabcra & 0x21) == 0x01) {
- bool check = true;
- uae_u32 cc = ciaclocks;
- if (ciabstarta > 0) {
- if (cc > ciabstarta) {
- cc -= ciabstarta;
- ciabstarta = 0;
- } else {
- ciabstarta -= cc;
- check = false;
+ // Timer B
+ cc = 0;
+ if ((c->t[1].cr & (CR_INMODE | CR_INMODE1 | CR_START)) == CR_START || c->t[1].inputpipe) {
+ cc = process_pipe(&c->t[1], ciaclocks, CR_INMODE | CR_INMODE1 | CR_START, &ovfl[1]);
+ }
+ if (cc > 0) {
+ c->t[1].timer -= cc;
+ if (c->t[1].timer == 0) {
+ ovfl[1] = 1;
}
}
- if (check) {
- assert ((ciabta + 1) >= cc);
- if ((ciabta + 1) == cc) {
- // SP in output mode
- if ((ciabcra & 0x48) == 0x40 && ciabsdr_cnt > 0) {
- ciaasdr_cnt--;
- if (!(ciaasdr_cnt & 1)) {
- ciabsdr_buf <<= 1;
- }
- if (ciabsdr_cnt == 0) {
- bsp = 1;
- if (ciabsdr_load) {
- ciabsdr_load = 0;
- ciabsdr_buf = ciabsdr;
- ciabsdr_cnt = 8 * 2;
+ assert(c->t[1].timer < 0x10000);
+
+ for (int tn = 0; tn < 2; tn++) {
+ struct CIATimer *t = &c->t[tn];
+
+ if (ovfl[tn]) {
+ c->icr2 |= tn ? ICR_B : ICR_A;
+ t->timer = t->latch;
+ if (!loaded[tn]) {
+ if (t->cr & CR_RUNMODE) {
+ // if oneshot timer expires exactly when
+ // CR is written with START and ONESHOT set:
+ // timer does not stop.
+ if (!loaded2[tn]) {
+ t->cr &= ~CR_START;
}
+ t->inputpipe &= ~CIA_PIPE_CLR2;
+ } else {
+ t->inputpipe &= ~CIA_PIPE_CLR1;
}
}
- bovfla = 1;
- // B INMODE=10 or 11
- if ((ciabcrb & 0x61) == 0x41 || (ciabcrb & 0x61) == 0x61) {
- if (ciabtb-- == 0)
- bovflb = 1;
- }
+ icr |= 1 << num;
}
- ciabta -= cc;
}
- }
- // B INMODE=00
- if ((ciabcrb & 0x61) == 0x01) {
- bool check = true;
- uae_u32 cc = ciaclocks;
- if (ciabstartb > 0) {
- if (cc > ciabstartb) {
- cc -= ciabstartb;
- ciabstartb = 0;
- } else {
- ciabstartb -= cc;
- check = false;
- }
- }
- if (check) {
- assert ((ciabtb + 1) >= cc);
- if ((ciabtb + 1) == cc)
- bovflb = 1;
- ciabtb -= cc;
- }
- }
- if (aovfla) {
- ciaaicr |= 1; icr = 1;
- ciaata = ciaala;
- if (ciaacra & 0x8) {
- ciaacra &= ~1;
+ if (sp) {
+ c->icr2 |= ICR_SP;
+ icr |= 1 << num;
}
- }
- if (aovflb) {
- ciaaicr |= 2; icr = 1;
- ciaatb = ciaalb;
- if (ciaacrb & 0x8) {
- ciaacrb &= ~1;
+
+ if (!acc_mode()) {
+ c->icr1 |= c->icr2;
+ c->icr2 = 0;
}
- }
- if (asp) {
- ciaaicr |= 8; icr = 1;
- }
- if (bovfla) {
- ciabicr |= 1; icr |= 2;
- ciabta = ciabla;
- if (ciabcra & 0x8) {
- ciabcra &= ~1;
+ if (icr) {
+ c->icr_change = true;
}
}
- if (bovflb) {
- ciabicr |= 2; icr |= 2;
- ciabtb = ciablb;
- if (ciabcrb & 0x8) {
- ciabcrb &= ~1;
- }
+}
+
+static void CIA_check_ICR(void)
+{
+ if (cia[0].icr1 & ICR_MASK) {
+ RethinkICR(0);
}
- if (bsp) {
- ciabicr |= 8; icr |= 2;
+ if (cia[1].icr1 & ICR_MASK) {
+ RethinkICR(1);
}
- return icr;
}
-static void CIA_update (void)
+
+static void CIA_update(void)
{
- int icr = CIA_update_check ();
- if (icr & 1)
- RethinkICRA ();
- if (icr & 2)
- RethinkICRB ();
+ CIA_update_check();
+ CIA_check_ICR();
}
-
/* Call this only after CIA_update has been called in the same cycle. */
-
-static void CIA_calctimers (void)
+static void CIA_calctimers(void)
{
- uae_s32 ciaatimea = -1, ciaatimeb = -1, ciabtimea = -1, ciabtimeb = -1;
- int div10diff = DIV10;
+ uae_s32 timevals[4];
+
+ timevals[0] = -1;
+ timevals[1] = -1;
+ timevals[2] = -1;
+ timevals[3] = -1;
eventtab[ev_cia].oldcycles = get_cycles();
- if ((ciaacra & 0x21) == 0x01) {
- ciaatimea = div10diff + DIV10 * (ciaata + ciaastarta);
- }
-#if 0
- if ((ciaacrb & 0x61) == 0x41) {
- /* Timer B will not get any pulses if Timer A is off. */
- if (ciaatimea >= 0) {
- /* If Timer A is in one-shot mode, and Timer B needs more than
- * one pulse, it will not underflow. */
- if (ciaatb == 0 || (ciaacra & 0x8) == 0) {
- /* Otherwise, we can determine the time of the underflow. */
- /* This may overflow, however. So just ignore this timer and
- use the fact that we'll call CIA_handler for the A timer. */
- /* ciaatimeb = ciaatimea + ciaala * DIV10 * ciaatb; */
+ for (int num = 0; num < 2; num++) {
+ struct CIA *c = &cia[num];
+ int idx = num * 2;
+
+ if ((c->t[0].cr & (CR_INMODE | CR_START)) == CR_START) {
+ int pipe = bitstodelay(c->t[0].inputpipe);
+ timevals[idx + 0] = DIV10 * (c->t[0].timer + pipe);
+ if (!timevals[idx + 0]) {
+ timevals[idx + 0] = DIV10;
}
}
- }
-#endif
- if ((ciaacrb & 0x61) == 0x01) {
- ciaatimeb = div10diff + DIV10 * (ciaatb + ciaastartb);
- }
- if ((ciabcra & 0x21) == 0x01) {
- ciabtimea = div10diff + DIV10 * (ciabta + ciabstarta);
- }
-#if 0
- if ((ciabcrb & 0x61) == 0x41) {
- /* Timer B will not get any pulses if Timer A is off. */
- if (ciabtimea >= 0) {
- /* If Timer A is in one-shot mode, and Timer B needs more than
- * one pulse, it will not underflow. */
- if (ciabtb == 0 || (ciabcra & 0x8) == 0) {
- /* Otherwise, we can determine the time of the underflow. */
- /* ciabtimeb = ciabtimea + ciabla * DIV10 * ciabtb; */
+ if ((c->t[1].cr & (CR_INMODE | CR_INMODE1 | CR_START)) == CR_START) {
+ int pipe = bitstodelay(c->t[1].inputpipe);
+ timevals[idx + 1] = DIV10 * (c->t[1].timer + pipe);
+ if (!timevals[idx + 1]) {
+ timevals[idx + 1] = DIV10;
}
}
- }
+
+ for (int tn = 0; tn < 2; tn++) {
+ struct CIATimer *t = &c->t[tn];
+ bool timerspecial = t->loaddelay != 0;
+ if (t->cr & CR_START) {
+ if (t->inputpipe != CIA_PIPE_ALL_MASK) {
+ timerspecial = true;
+ }
+ } else {
+ if (t->inputpipe != 0) {
+ timerspecial = true;
+ }
+ }
+ if (timerspecial && (timevals[idx] < 0 || timevals[idx] > DIV10)) {
+ timevals[idx + tn] = DIV10;
+ }
+ }
+
+ if (c->icr_change && (timevals[idx] < 0 || timevals[idx] > DIV10)) {
+ timevals[idx] = DIV10;
+ }
+
+#if CIA_EVERY_CYCLE_DEBUG
+ timevals[idx] = DIV10;
#endif
- if ((ciabcrb & 0x61) == 0x01) {
- ciabtimeb = div10diff + DIV10 * (ciabtb + ciabstartb);
+
}
uae_s32 ciatime = INT_MAX;
- if (ciaatimea > 0)
- ciatime = ciaatimea;
- if (ciaatimeb > 0 && ciaatimeb < ciatime)
- ciatime = ciaatimeb;
- if (ciabtimea > 0 && ciabtimea < ciatime)
- ciatime = ciabtimea;
- if (ciabtimeb > 0 && ciabtimeb < ciatime)
- ciatime = ciabtimeb;
+ if (timevals[0] >= 0)
+ ciatime = timevals[0];
+ if (timevals[1] >= 0 && timevals[1] < ciatime)
+ ciatime = timevals[1];
+ if (timevals[2] >= 0 && timevals[2] < ciatime)
+ ciatime = timevals[2];
+ if (timevals[3] >= 0 && timevals[3] < ciatime)
+ ciatime = timevals[3];
if (ciatime < INT_MAX) {
eventtab[ev_cia].evtime = get_cycles() + ciatime;
eventtab[ev_cia].active = true;
events_schedule();
}
-void CIA_handler (void)
+void CIA_handler(void)
{
- CIA_update ();
- CIA_calctimers ();
+ CIA_update();
+ CIA_calctimers();
}
-void cia_diskindex (void)
+static void CIA_synced_interrupt(uae_u32 v)
{
- ciabicr |= 0x10;
- RethinkICRB ();
+ CIA_update();
+ CIA_calctimers();
}
-void cia_parallelack (void)
+
+static void CIA_sync_interrupt(int num, uae_u8 icr)
{
- ciaaicr |= 0x10;
- RethinkICRA ();
+ struct CIA *c = &cia[num];
+
+ if (acc_mode()) {
+ c->icr2 |= icr;
+ if ((c->icr1 & ICR_MASK) == (c->icr2 & ICR_MASK)) {
+ return;
+ }
+ if (!(icr & c->imask)) {
+ c->icr1 |= icr;
+ return;
+ }
+ c->icr_change = true;
+ evt_t evt = get_e_cycles();
+ int div10 = evt % DIV10;
+ int delay = 0;
+ if (div10 > 0) {
+ delay += DIV10 - div10;
+ }
+ event2_newevent_xx(-1, DIV10 + delay, num, CIA_synced_interrupt);
+ } else {
+ c->icr1 |= icr;
+ c->icr_change = true;
+ CIA_check_ICR();
+ }
}
-static bool checkalarm (uae_u32 tod, uae_u32 alarm, bool inc, int ab)
+void cia_diskindex(void)
+{
+ CIA_sync_interrupt(1, ICR_FLAG);
+}
+void cia_parallelack(void)
+{
+ CIA_sync_interrupt(0, ICR_FLAG);
+}
+
+static bool checkalarm(uae_u32 tod, uae_u32 alarm, bool inc, int ab)
{
if (tod == alarm)
return true;
-// if (!ab)
-// return false;
if (!currprefs.cs_ciatodbug)
return false;
if (!inc)
return false;
}
-static bool ciab_checkalarm (bool inc, bool irq)
+static bool ciab_checkalarm(bool inc, bool irq)
{
+ struct CIA *c = &cia[1];
+
// hack: do not trigger alarm interrupt if KS code and both
// tod and alarm == 0. This incorrectly triggers on non-cycle exact
// 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 ((munge24 (m68k_getpc ()) & 0xFFF80000) != 0xF80000) {
- if (ciabtod == 0 && ciabalarm == 0)
+ if (!currprefs.cpu_compatible && (munge24(m68k_getpc()) & 0xFFF80000) != 0xF80000) {
+ if (c->tod == 0 && c->alarm == 0)
return false;
}
#endif
- if (checkalarm (ciabtod, ciabalarm, inc, 1)) {
+ if (checkalarm(c->tod, c->alarm, inc, 1)) {
#if CIAB_DEBUG_IRQ
- write_log (_T("CIAB tod %08x %08x\n"), ciabtod, ciabalarm);
+ write_log(_T("CIAB tod %08x %08x\n"), c->tod, c->alarm);
#endif
if (irq) {
- ciabicr |= 4;
- RethinkICRB ();
+ CIA_sync_interrupt(1, ICR_ALARM);
}
return true;
}
return false;
}
-static void ciaa_checkalarm (bool inc)
+static void ciaa_checkalarm(bool inc)
{
- if (checkalarm (ciaatod, ciaaalarm, inc, 0)) {
+ struct CIA *c = &cia[0];
+
+ if (checkalarm(c->tod, c->alarm, inc, 0)) {
#if CIAA_DEBUG_IRQ
- write_log (_T("CIAA tod %08x %08x\n"), ciaatod, ciaaalarm);
+ write_log(_T("CIAA tod %08x %08x\n"), c->tod, c->alarm);
#endif
- ciaaicr |= 4;
- RethinkICRA ();
+ CIA_sync_interrupt(0, ICR_ALARM);
+ }
+}
+
+static void cia_checkalarm(int num, bool inc)
+{
+ switch (num)
+ {
+ case 0:
+ ciaa_checkalarm(inc);
+ break;
+ case 1:
+ ciab_checkalarm(inc, true);
+ break;
}
}
static int tod_diff_cnt;
#define TOD_HACK_DELAY 50
#define TOD_HACK_TIME 312 * 50 * 10
-static void tod_hack_reset (void)
+
+static void tod_hack_reset(void)
{
struct timeval tv;
- gettimeofday (&tv, NULL);
+ gettimeofday(&tv, NULL);
tod_hack_tv = (uae_u64)tv.tv_sec * 1000000 + tv.tv_usec;
- tod_hack_tod = ciaatod;
+ tod_hack_tod = cia[0].tod;
tod_hack_tod_last = tod_hack_tod;
tod_diff_cnt = 0;
}
#endif
static int heartbeat_cnt;
-void cia_heartbeat (void)
+void cia_heartbeat(void)
{
heartbeat_cnt = 10;
}
-static void do_tod_hack (int dotod)
+static void do_tod_hack(int dotod)
{
struct timeval tv;
static int oldrate;
if (tod_hack_enabled > 1) {
tod_hack_enabled--;
if (tod_hack_enabled == 1) {
- //write_log (_T("TOD HACK enabled\n"));
- tod_hack_reset ();
+ //write_log(_T("TOD HACK enabled\n"));
+ tod_hack_reset();
}
return;
}
}
if (rate <= 0)
return;
- if (rate != oldrate || (ciaatod & 0xfff) != (tod_hack_tod_last & 0xfff)) {
- write_log (_T("TOD HACK reset %d,%d %ld,%lld\n"), rate, oldrate, ciaatod, tod_hack_tod_last);
- tod_hack_reset ();
+ if (rate != oldrate || (cia[0].tod & 0xfff) != (tod_hack_tod_last & 0xfff)) {
+ write_log(_T("TOD HACK reset %d,%d %ld,%lld\n"), rate, oldrate, cia[0].tod, tod_hack_tod_last);
+ tod_hack_reset();
oldrate = rate;
docount = 1;
}
tod_hack_delay = TOD_HACK_DELAY;
}
- gettimeofday (&tv, NULL);
+ gettimeofday(&tv, NULL);
t = (uae_u64)tv.tv_sec * 1000000 + tv.tv_usec;
if (t - tod_hack_tv >= 1000000 / rate) {
tod_hack_tv += 1000000 / rate;
docount = 1;
}
if (docount) {
- ciaatod++;
- ciaatod &= 0x00ffffff;
- tod_hack_tod_last = ciaatod;
- ciaa_checkalarm (false);
+ cia[0].tod++;
+ cia[0].tod &= 0x00ffffff;
+ tod_hack_tod_last = cia[0].tod;
+ ciaa_checkalarm(false);
}
}
static int resetwarning_phase, resetwarning_timer;
-static void setcode (uae_u8 keycode)
+static void setcode(uae_u8 keycode)
{
kbcode = ~((keycode << 1) | (keycode >> 7));
}
-static void sendrw (void)
+static void sendrw(void)
{
- setcode (AK_RESETWARNING);
- ciaasdr = kbcode;
+ setcode(AK_RESETWARNING);
+ cia[0].sdr = kbcode;
kblostsynccnt = 8 * maxvpos * 8; // 8 frames * 8 bits.
- ciaaicr |= 8;
- RethinkICRA ();
- write_log (_T("KB: sent reset warning code (phase=%d)\n"), resetwarning_phase);
+ CIA_sync_interrupt(0, ICR_SP);
+ write_log(_T("KB: sent reset warning code (phase=%d)\n"), resetwarning_phase);
}
-int resetwarning_do (int canreset)
+int resetwarning_do(int canreset)
{
if (!currprefs.keyboard_connected)
return 0;
}
resetwarning_phase = 1;
resetwarning_timer = maxvpos_nom * 5;
- write_log (_T("KB: reset warning triggered\n"));
- sendrw ();
+ write_log(_T("KB: reset warning triggered\n"));
+ sendrw();
return 1;
}
-static void resetwarning_check (void)
+static void resetwarning_check(void)
{
if (resetwarning_timer > 0) {
resetwarning_timer--;
if (resetwarning_timer <= 0) {
- write_log (_T("KB: reset warning forced reset. Phase=%d\n"), resetwarning_phase);
+ write_log(_T("KB: reset warning forced reset. Phase=%d\n"), resetwarning_phase);
resetwarning_phase = -1;
kblostsynccnt = 0;
- send_internalevent (INTERNALEVENT_KBRESET);
- uae_reset (0, 1);
+ send_internalevent(INTERNALEVENT_KBRESET);
+ uae_reset(0, 1);
}
}
if (resetwarning_phase == 1) {
if (!kblostsynccnt) { /* first AK_RESETWARNING handshake received */
- write_log (_T("KB: reset warning second phase..\n"));
+ write_log(_T("KB: reset warning second phase..\n"));
resetwarning_phase = 2;
resetwarning_timer = maxvpos_nom * 5;
- sendrw ();
+ sendrw();
}
} else if (resetwarning_phase == 2) {
- if (ciaacra & 0x40) { /* second AK_RESETWARNING handshake active */
+ if (cia[0].t[0].cr & CR_SPMODE) { /* second AK_RESETWARNING handshake active */
resetwarning_phase = 3;
- write_log (_T("KB: reset warning SP = output\n"));
+ write_log(_T("KB: reset warning SP = output\n"));
/* System won't reset until handshake signal becomes inactive or 10s has passed */
resetwarning_timer = (int)(10 * maxvpos_nom * vblank_hz);
}
} else if (resetwarning_phase == 3) {
- if (!(ciaacra & 0x40)) { /* second AK_RESETWARNING handshake disabled */
- write_log (_T("KB: reset warning end by software. reset.\n"));
+ if (!(cia[0].t[0].cr & CR_SPMODE)) { /* second AK_RESETWARNING handshake disabled */
+ write_log(_T("KB: reset warning end by software. reset.\n"));
resetwarning_phase = -1;
kblostsynccnt = 0;
- send_internalevent (INTERNALEVENT_KBRESET);
- uae_reset (0, 1);
+ send_internalevent(INTERNALEVENT_KBRESET);
+ uae_reset(0, 1);
}
}
}
static void keyreq (void)
{
#if KB_DEBUG
- write_log (_T("code=%02x (%02x)\n"), kbcode, (uae_u8)(~((kbcode >> 1) | (kbcode << 7))));
+ write_log(_T("code=%02x (%02x)\n"), kbcode, (uae_u8)(~((kbcode >> 1) | (kbcode << 7))));
#endif
- ciaasdr = kbcode;
+ cia[0].sdr = kbcode;
kblostsynccnt = 8 * maxvpos * 8; // 8 frames * 8 bits.
- ciaaicr |= 8;
- RethinkICRA ();
+ CIA_sync_interrupt(0, ICR_SP);
}
-/* All this complexity to lazy evaluate TOD increase.
+/* All this complexity to lazy evaluate CIA-B TOD increase.
* Only increase it cycle-exactly if it is visible to running program:
- * causes interrupt or program is reading or writing TOD registers
+ * causes interrupt (ALARM) or program is reading or writing TOD registers
*/
-static int ciab_tod_hoffset;
-static int ciab_tod_event_state;
-// TOD increase has extra delay
-#define TOD_INC_DELAY (13 * DIV10)
+// TOD increase has extra delay. CCKs.
+#define TOD_INC_DELAY (12 * E_CLOCK_LENGTH / 2)
+
+static int tod_inc_delay(int hoffset)
+{
+ int hoff = hoffset + 1; // 1 = HSYNC Agnus pin output is delayed by 1 CCK
+ evt_t c = get_e_cycles() + 2 * E_CYCLE_UNIT + hoff * CYCLE_UNIT;
+ int offset = hoff;
+ offset += TOD_INC_DELAY;
+ int unit = (E_CLOCK_LENGTH * 4) / 2; // 4 E-clocks
+ int div10 = (c / CYCLE_UNIT) % unit;
+ offset += unit - div10;
+ return offset;
+}
+
+static void CIAA_tod_inc(uae_u32 v)
+{
+ if (!cia[0].todon)
+ return;
+ cia[0].tod++;
+ cia[0].tod &= 0xFFFFFF;
+ ciaa_checkalarm(true);
+}
+
+void CIAA_tod_handler(int hoffset)
+{
+#ifdef TOD_HACK
+ if (currprefs.tod_hack && tod_hack_enabled == 1)
+ return;
+#endif
+ if (!cia[0].todon)
+ return;
+ int delay = tod_inc_delay(hoffset);
+ event2_newevent_xx(-1, delay * CYCLE_UNIT, 0, CIAA_tod_inc);
+}
static void CIAB_tod_inc(bool irq)
{
- ciab_tod_event_state = 3; // done
- if (!ciabtodon)
+ cia[1].tod_event_state = 3; // done
+ if (!cia[1].todon)
return;
- ciabtod++;
- ciabtod &= 0xFFFFFF;
+ cia[1].tod++;
+ cia[1].tod &= 0xFFFFFF;
ciab_checkalarm(true, irq);
}
static void CIAB_tod_inc_event(uae_u32 v)
{
- if (ciab_tod_event_state != 2)
+ int hpos = current_hpos();
+ if (cia[1].tod_event_state != 2)
return;
CIAB_tod_inc(true);
}
static void CIAB_tod_event_check(void)
{
- if (ciab_tod_event_state == 1) {
+ if (cia[1].tod_event_state == 1) {
int hpos = current_hpos();
- if (hpos >= ciab_tod_hoffset) {
+ if (hpos >= cia[1].tod_offset) {
CIAB_tod_inc(false);
- ciab_tod_event_state = 0;
+ cia[1].tod_event_state = 0;
}
}
}
static void CIAB_tod_check(void)
{
CIAB_tod_event_check();
- if (!ciabtodon)
+ if (!cia[1].todon || cia[1].tod_event_state > 1 || cia[1].tod_offset < 0)
return;
int hpos = current_hpos();
- hpos -= ciab_tod_hoffset;
+ hpos -= cia[1].tod_offset;
if (hpos >= 0 || currprefs.m68k_speed < 0) {
// Program should see the changed TOD
CIAB_tod_inc(true);
return;
}
// Not yet, add event to guarantee exact TOD inc position
- ciab_tod_event_state = 2; // event active
+ cia[1].tod_event_state = 2; // event active
event2_newevent_xx(-1, -hpos * CYCLE_UNIT, 0, CIAB_tod_inc_event);
}
void CIAB_tod_handler(int hoffset)
{
- if (!ciabtodon || ciab_tod_event_state)
+ cia[1].tod_event_state = 0;
+ cia[1].tod_offset = tod_inc_delay(hoffset);
+ if (cia[1].tod_offset >= maxhpos) {
return;
- ciab_tod_hoffset = hoffset;
- ciab_tod_hoffset += TOD_INC_DELAY / CYCLE_UNIT;
- //ciab_tod_hoffset += ((total_ciaclocks % 4) * DIV10) / CYCLE_UNIT;
- ciab_tod_event_state = 1; // TOD inc needed
- if (checkalarm ((ciabtod + 1) & 0xffffff, ciabalarm, true, 1)) {
+ }
+ cia[1].tod_event_state = 1; // TOD inc needed
+ if (checkalarm((cia[1].tod + 1) & 0xffffff, cia[1].alarm, true, 1)) {
// causes interrupt on this line, add event
- ciab_tod_event_state = 2; // event active
- event2_newevent_xx (-1, ciab_tod_hoffset * CYCLE_UNIT, 0, CIAB_tod_inc_event);
+ cia[1].tod_event_state = 2; // event active
+ event2_newevent_xx(-1, cia[1].tod_offset * CYCLE_UNIT, 0, CIAB_tod_inc_event);
+ }
+}
+
+static void CIA_tod_check(int num)
+{
+ if (num == 1) {
+ CIAB_tod_check();
}
}
static void check_keyboard(void)
{
if (currprefs.keyboard_connected) {
- if ((keys_available () || kbstate < 3) && !kblostsynccnt ) {
+ if ((keys_available() || kbstate < 3) && !kblostsynccnt ) {
switch (kbstate)
{
case 0:
kbstate++;
break;
case 1:
- setcode (AK_INIT_POWERUP);
+ setcode(AK_INIT_POWERUP);
kbstate++;
break;
case 2:
- setcode (AK_TERM_POWERUP);
+ setcode(AK_TERM_POWERUP);
kbstate++;
break;
case 3:
- kbcode = ~get_next_key ();
+ kbcode = ~get_next_key();
break;
}
- keyreq ();
+ keyreq();
}
} else {
while (keys_available()) {
void CIA_hsync_posthandler (bool ciahsync, bool dotod)
{
if (ciahsync) {
- // cia hsync
- // Previous line was supposed to increase TOD but
- // no one cared. Do it now.
- if (ciab_tod_event_state == 1)
- CIAB_tod_inc (false);
- ciab_tod_event_state = 0;
- if (currprefs.tod_hack && ciaatodon)
- do_tod_hack (dotod);
+ // CIA HSync pulse
+ // Delayed previous line TOD increase.
+ if (cia[1].tod_event_state == 1)
+ CIAB_tod_inc(false);
+ cia[1].tod_event_state = 0;
+ cia[1].tod_offset = -1;
+ if (currprefs.tod_hack && cia[0].todon)
+ do_tod_hack(dotod);
} else if (currprefs.keyboard_connected) {
// custom hsync
if (resetwarning_phase) {
- resetwarning_check ();
- while (keys_available ())
- get_next_key ();
+ resetwarning_check();
+ while (keys_available())
+ get_next_key();
} else {
if ((hsync_counter & 15) == 0)
check_keyboard();
}
}
-static void calc_led (int old_led)
+static void calc_led(int old_led)
{
- evt_t c = get_cycles ();
+ evt_t c = get_cycles();
evt_t t = (c - led_cycle) / CYCLE_UNIT;
if (old_led)
led_cycles_on += t;
led_cycle = c;
}
-static void led_vsync (void)
+static void led_vsync(void)
{
int v;
- calc_led (led);
+ calc_led(led);
if (led_cycles_on && !led_cycles_off)
v = 255;
else if (led_cycles_off && !led_cycles_on)
if (led_old_brightness != gui_data.powerled_brightness) {
gui_data.powerled = gui_data.powerled_brightness > 96;
gui_led (LED_POWER, gui_data.powerled, gui_data.powerled_brightness);
- led_filter_audio ();
+ led_filter_audio();
}
led_old_brightness = gui_data.powerled_brightness;
- led_cycle = get_cycles ();
+ led_cycle = get_cycles();
}
-static void write_battclock (void);
-void CIA_vsync_prehandler (void)
+static void write_battclock(void);
+void CIA_vsync_prehandler(void)
{
if (heartbeat_cnt > 0)
heartbeat_cnt--;
} else if (rtc_msm.delayed_write > 0) {
rtc_msm.delayed_write--;
if (rtc_msm.delayed_write == 0)
- write_battclock ();
+ write_battclock();
}
if (rtc_ricoh.delayed_write < 0) {
rtc_ricoh.delayed_write = 50;
} else if (rtc_ricoh.delayed_write > 0) {
rtc_ricoh.delayed_write--;
if (rtc_ricoh.delayed_write == 0)
- write_battclock ();
+ write_battclock();
}
- led_vsync ();
+ led_vsync();
keybuf_vsync();
if (kblostsynccnt > 0) {
kblostsynccnt -= maxvpos;
if (kblostsynccnt <= 0) {
kblostsynccnt = 0;
kbcode = 0;
- keyreq ();
+ keyreq();
#if KB_DEBUG
- write_log (_T("lostsync\n"));
+ write_log(_T("lostsync\n"));
#endif
}
}
}
-static void CIAA_tod_handler (uae_u32 v)
+static void check_led(void)
{
- ciaatod++;
- ciaatod &= 0xFFFFFF;
- ciaa_checkalarm (true);
+ uae_u8 v = cia[0].pra;
+ bool led2;
+
+ v |= ~cia[0].dra; /* output is high when pin's direction is input */
+ led2 = (v & 2) ? 0 : 1;
+ if (led2 != led) {
+ calc_led(led);
+ led = led2;
+ led_old_brightness = -1;
+ }
}
-void CIAA_tod_inc (int cycles)
+static void bfe001_change(void)
{
-#ifdef TOD_HACK
- if (currprefs.tod_hack && tod_hack_enabled == 1)
+ uae_u8 v = cia[0].pra;
+ v |= ~cia[0].dra; /* output is high when pin's direction is input */
+ check_led();
+ if (currprefs.cs_ciaoverlay && (v & 1) != oldovl) {
+ oldovl = v & 1;
+ if (!oldovl) {
+ map_overlay(1);
+ } else {
+ map_overlay(0);
+ }
+ }
+ akiko_mute((v & 1) == 0);
+}
+
+static uae_u32 getciatod(uae_u32 tod)
+{
+ if (!currprefs.cs_cia6526)
+ return tod;
+ uae_u32 bcdtod = 0;
+ for (int i = 0; i < 4; i++) {
+ int val = tod % 10;
+ bcdtod *= 16;
+ bcdtod += val;
+ tod /= 10;
+ }
+ return bcdtod;
+}
+static void setciatod(uae_u32 *tod, uae_u32 v)
+{
+ if (!currprefs.cs_cia6526) {
+ *tod = v;
return;
+ }
+ uae_u32 bintod = 0;
+ for (int i = 0; i < 4; i++) {
+ int val = v / 16;
+ bintod *= 10;
+ bintod += val;
+ v /= 16;
+ }
+ *tod = bintod;
+}
+
+// E-clock count mode?
+static bool CIA_timer_02(int num, uae_u8 cr)
+{
+ if (num) {
+ return (cr & (CR_INMODE | CR_INMODE1)) == 0;
+ }
+ return (cr & CR_INMODE) == 0;
+}
+
+static uae_u8 ReadCIAReg(int num, int reg)
+{
+ struct CIA *c = &cia[num];
+ uae_u8 tmp;
+ int tnum = 0;
+
+ switch (reg)
+ {
+ case 6:
+ case 7:
+ case 15:
+ tnum = 1;
+ break;
+ }
+
+ struct CIATimer *t = &c->t[tnum];
+
+ switch (reg)
+ {
+ case 4:
+ case 6:
+ case 5:
+ case 7:
+ {
+ uae_u16 tval = t->timer - t->passed;
+ if (reg == 4 || reg == 6) {
+ return tval & 0xff;
+ }
+ return tval >> 8;
+ }
+ case 8:
+ CIA_tod_check(num);
+ if (c->tlatch) {
+ c->tlatch = 0;
+ return getciatod(c->tol);
+ } else {
+ return getciatod(c->tod);
+ }
+ case 9:
+ CIA_tod_check(num);
+ if (c->tlatch) {
+ return getciatod(c->tol) >> 8;
+ } else {
+ return getciatod(c->tod) >> 8;
+ }
+ case 10:
+ CIA_tod_check(num);
+ /* only if not already latched. A1200 confirmed. (TW) */
+ if (!currprefs.cs_cia6526) {
+ if (!c->tlatch) {
+ /* no latching if ALARM is set */
+ if (!(c->t[1].cr & CR_ALARM)) {
+ c->tlatch = 1;
+ }
+ c->tol = c->tod;
+ }
+ return getciatod(c->tol) >> 16;
+ } else {
+ if (c->tlatch)
+ return getciatod(c->tol) >> 16;
+ else
+ return getciatod(c->tod) >> 16;
+ }
+ break;
+ case 11:
+ CIA_tod_check(num);
+ if (currprefs.cs_cia6526) {
+ if (!c->tlatch) {
+ if (!(c->t[1].cr & CR_ALARM)) {
+ c->tlatch = 1;
+ }
+ c->tol = c->tod;
+ }
+ if (c->tlatch) {
+ return getciatod(c->tol) >> 24;
+ } else{
+ return getciatod(c->tod) >> 24;
+ }
+ } else {
+ return 0xff;
+ }
+ break;
+ case 12:
+#if KB_DEBUG
+ write_log(_T("CIAA serial port: %02x %08x\n"), c->sdr, M68K_GETPC);
#endif
- if (!ciaatodon)
- return;
- event2_newevent_xx (-1, cycles + TOD_INC_DELAY, 0, CIAA_tod_handler);
+ return c->sdr;
+ case 13:
+ tmp = c->icr1 & ~(0x40 | 0x20);
+ c->icr1 = 0;
+ return tmp;
+ case 14:
+ case 15:
+ return t->cr;
+ }
+ return 0xff;
}
-static void check_led(void)
+static void CIA_thi_write(int num, int tnum, uae_u8 val)
{
- uae_u8 v = ciaapra;
- bool led2;
+ struct CIA *c = &cia[num];
+ struct CIATimer *t = &c->t[tnum];
- v |= ~ciaadra; /* output is high when pin's direction is input */
- led2 = (v & 2) ? 0 : 1;
- if (led2 != led) {
- calc_led(led);
- led = led2;
- led_old_brightness = -1;
+ 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 (t->cr & CR_RUNMODE) {
+ t->cr |= CR_START;
+ t->loaddelay |= 0x01000000 << 1;
}
}
-static void bfe001_change(void)
+static void CIA_cr_write(int num, int tnum, uae_u8 val)
{
- uae_u8 v = ciaapra;
- v |= ~ciaadra; /* output is high when pin's direction is input */
- check_led();
- if (currprefs.cs_ciaoverlay && (v & 1) != oldovl) {
- oldovl = v & 1;
- if (!oldovl) {
- map_overlay(1);
- } else {
- //activate_debugger();
- map_overlay(0);
+ struct CIA *c = &cia[num];
+ struct CIATimer *t = &c->t[tnum];
+
+ if (!tnum) {
+ 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;
+ }
+ } else {
+ if ((val & CR_START)) {
+ t->loaddelay |= 0x010000 << 0;
}
}
- akiko_mute((v & 1) == 0);
+
+ if (!(val & CR_START)) {
+ t->inputpipe &= ~CIA_PIPE_CLR1;
+ }
+
+ t->cr = val;
}
-static uae_u32 getciatod(uae_u32 tod)
+static void WriteCIAReg(int num, int reg, uae_u8 val)
{
- if (!currprefs.cs_cia6526)
- return tod;
- uae_u32 bcdtod = 0;
- for (int i = 0; i < 4; i++) {
- int val = tod % 10;
- bcdtod *= 16;
- bcdtod += val;
- tod /= 10;
+ struct CIA *c = &cia[num];
+ int tnum = 0;
+
+ switch (reg)
+ {
+ case 6:
+ case 7:
+ case 15:
+ tnum = 1;
+ break;
+ }
+
+ struct CIATimer *t = &c->t[tnum];
+
+ switch (reg) {
+ case 4:
+ case 6:
+ t->latch = (t->latch & 0xff00) | val;
+ break;
+ case 5:
+ case 7:
+ CIA_thi_write(num, tnum, val);
+ break;
+ case 8:
+ CIA_tod_check(num);
+ if (c->t[1].cr & CR_ALARM) {
+ setciatod(&c->alarm, (getciatod(c->alarm) & ~0xff) | val);
+ } else {
+ setciatod(&c->tod, (getciatod(c->tod) & ~0xff) | val);
+ c->todon = 1;
+ cia_checkalarm(num, false);
+ CIA_tod_check(num);
+ }
+ break;
+ case 9:
+ CIA_tod_check(num);
+ if (c->t[1].cr & CR_ALARM) {
+ setciatod(&c->alarm, (getciatod(c->alarm) & ~0xff00) | (val << 8));
+ } else {
+ setciatod(&c->tod, (getciatod(c->tod) & ~0xff00) | (val << 8));
+ }
+ break;
+ case 10:
+ CIA_tod_check(num);
+ if (c->t[1].cr & CR_ALARM) {
+ setciatod(&c->alarm, (getciatod(c->alarm) & ~0xff0000) | (val << 16));
+ } else {
+ setciatod(&c->tod, (getciatod(c->tod) & ~0xff0000) | (val << 16));
+ if (!currprefs.cs_cia6526) {
+ c->todon = 0;
+ }
+ }
+ break;
+ case 11:
+ CIA_tod_check(num);
+ if (currprefs.cs_cia6526) {
+ if (c->t[1].cr & CR_ALARM) {
+ setciatod(&c->alarm, (getciatod(c->alarm) & ~0xff000000) | (val << 24));
+ } else {
+ setciatod(&c->tod, (getciatod(c->tod) & ~0xff000000) | (val << 24));
+ c->todon = 0;
+ }
+ }
+ break;
+ case 12:
+ c->sdr = val;
+ if ((c->t[0].cr & (CR_INMODE1 | CR_START)) == (CR_INMODE1 | CR_START)) {
+ c->sdr_load = 1;
+ if (c->sdr_cnt == 0) {
+ c->sdr_cnt = 8 * 2;
+ c->sdr_load = 0;
+ c->sdr_buf = c->sdr;
+ }
+ }
+ break;
+ case 13:
+ setclr(&c->imask, val);
+ RethinkICR(num);
+ break;
+ case 14:
+ case 15:
+ CIA_cr_write(num, tnum, val);
+ break;
}
- return bcdtod;
}
-static void setciatod(uae_u32 *tod, uae_u32 v)
+
+static uae_u8 CIA_PBON(struct CIA *c, uae_u8 v)
{
- if (!currprefs.cs_cia6526) {
- *tod = v;
- return;
+ // A PBON
+ if (c->t[0].cr & CR_PBON) {
+ int pb6 = 0;
+ if (c->t[0].cr & CR_OUTMODE)
+ pb6 = c->t[0].cr & CR_START;
+ v &= ~0x40;
+ v |= pb6 ? 0x40 : 00;
}
- uae_u32 bintod = 0;
- for (int i = 0; i < 4; i++) {
- int val = v / 16;
- bintod *= 10;
- bintod += val;
- v /= 16;
+ // B PBON
+ if (c->t[1].cr & CR_PBON) {
+ int pb7 = 0;
+ if (c->t[1].cr & CR_OUTMODE)
+ pb7 = c->t[1].cr & CR_START;
+ v &= ~0x80;
+ v |= pb7 ? 0x80 : 00;
}
- *tod = bintod;
+ return v;
}
-static uae_u8 ReadCIAA (uae_u32 addr, uae_u32 *flags)
+static uae_u8 ReadCIAA(uae_u32 addr, uae_u32 *flags)
{
+ struct CIA *c = &cia[0];
uae_u32 tmp;
int reg = addr & 15;
- compute_passed_time ();
+ compute_passed_time();
#if CIAA_DEBUG_R > 0
if (CIAA_DEBUG_R > 1 || (munge24 (M68K_GETPC) & 0xFFF80000) != 0xF80000)
- write_log (_T("R_CIAA: bfe%x01 %08X\n"), reg, M68K_GETPC);
+ write_log(_T("R_CIAA: bfe%x01 %08X\n"), reg, M68K_GETPC);
#endif
switch (reg) {
{
*flags |= 1;
uae_u8 v = DISK_status_ciaa() & 0x3c;
- v |= handle_joystick_buttons (ciaapra, ciaadra);
- v |= (ciaapra | (ciaadra ^ 3)) & 0x03;
- v = dongle_cia_read (0, reg, ciaadra, v);
- v = alg_joystick_buttons(ciaapra, ciaadra, v);
+ v |= handle_joystick_buttons(c->pra, c->dra);
+ v |= (c->pra | (c->dra ^ 3)) & 0x03;
+ v = dongle_cia_read(0, reg, c->dra, v);
+ v = alg_joystick_buttons(c->pra, c->dra, v);
// 391078-01 CIA: output mode bits always return PRA contents
if (currprefs.cs_ciatype[0]) {
- v &= ~ciaadra;
- v |= ciaapra & ciaadra;
+ v &= ~c->dra;
+ v |= c->pra & c->dra;
}
#if DONGLE_DEBUG > 0
if (notinrom())
- write_log (_T("BFE001 R %02X %s\n"), v, debuginfo(0));
+ write_log(_T("BFE001 R %02X %s\n"), v, debuginfo(0));
#endif
if (inputrecord_debug & 2) {
if (input_record > 0)
- inprec_recorddebug_cia (v, 0, m68k_getpc ());
+ inprec_recorddebug_cia(v, 0, m68k_getpc ());
else if (input_play > 0)
- inprec_playdebug_cia (v, 0, m68k_getpc ());
+ inprec_playdebug_cia(v, 0, m68k_getpc ());
}
return v;
}
case 1:
- tmp = (ciaaprb & ciaadrb) | (ciaadrb ^ 0xff);
+ tmp = (c->prb & c->drb) | (c->drb ^ 0xff);
#ifdef PARALLEL_PORT
if (isprinter() > 0) {
- tmp = ciaaprb;
+ tmp = c->prb;
} else if (isprinter() < 0) {
uae_u8 v;
parallel_direct_read_data(&v);
tmp = v;
#ifdef ARCADIA
} else if (arcadia_bios) {
- tmp = arcadia_parport(0, ciaaprb, ciaadrb);
+ tmp = arcadia_parport(0, c->prb, c->drb);
#endif
} else if (currprefs.win32_samplersoundcard >= 0) {
- tmp = sampler_getsample((ciabpra & 4) ? 1 : 0);
+ tmp = sampler_getsample((c->pra & 4) ? 1 : 0);
#endif
} else if (parallel_port_scsi) {
- tmp = parallel_port_scsi_read(0, ciaaprb, ciaadrb);
+ tmp = parallel_port_scsi_read(0, c->prb, c->drb);
} else {
tmp = handle_parport_joystick (0, tmp);
- tmp = dongle_cia_read (1, reg, ciaadrb, tmp);
+ tmp = dongle_cia_read (1, reg, c->drb, tmp);
#if DONGLE_DEBUG > 0
if (notinrom())
- write_log (_T("BFE101 R %02X %s\n"), tmp, debuginfo(0));
+ write_log(_T("BFE101 R %02X %s\n"), tmp, debuginfo(0));
#endif
}
- // PBON
- if (ciaacrb & 2) {
- int pb7 = 0;
- // OUTMODE
- if (ciaacrb & 4) {
- pb7 = ciaacrb & 1;
- }
- tmp &= ~0x80;
- tmp |= pb7 ? 0x80 : 00;
- }
- if (ciaacra & 2) {
- int pb6 = 0;
- // OUTMODE
- if (ciaacra & 4) {
- pb6 = ciaacra & 1;
- }
- tmp &= ~0x40;
- tmp |= pb6 ? 0x40 : 00;
- }
-
+ tmp = CIA_PBON(c, tmp);
if (currprefs.cs_ciatype[0]) {
- tmp &= ~ciaadrb;
- tmp |= ciaaprb & ciaadrb;
+ tmp &= ~c->drb;
+ tmp |= c->prb & c->drb;
}
return tmp;
case 2:
#if DONGLE_DEBUG > 0
- if (notinrom ())
- write_log (_T("BFE201 R %02X %s\n"), ciaadra, debuginfo(0));
+ if (notinrom())
+ write_log(_T("BFE201 R %02X %s\n"), c->dra, debuginfo(0));
#endif
- return ciaadra;
+ return c->dra;
case 3:
#if DONGLE_DEBUG > 0
- if (notinrom ())
- write_log (_T("BFE301 R %02X %s\n"), ciaadrb, debuginfo(0));
+ if (notinrom())
+ write_log(_T("BFE301 R %02X %s\n"), c->drb, debuginfo(0));
#endif
- return ciaadrb;
+ return c->drb;
case 4:
- return (uae_u8)((ciaata - ciaata_passed) & 0xff);
case 5:
- return (uae_u8)((ciaata - ciaata_passed) >> 8);
case 6:
- return (uae_u8)((ciaatb - ciaatb_passed) & 0xff);
case 7:
- return (uae_u8)((ciaatb - ciaatb_passed) >> 8);
case 8:
- if (ciaatlatch) {
- ciaatlatch = 0;
- return getciatod(ciaatol);
- } else
- return getciatod(ciaatod);
case 9:
- if (ciaatlatch)
- return getciatod(ciaatol) >> 8;
- else
- return getciatod(ciaatod) >> 8;
case 10:
- /* only if not already latched. A1200 confirmed. (TW) */
- if (!currprefs.cs_cia6526) {
- if (!ciaatlatch) {
- /* no latching if ALARM is set */
- if (!(ciaacrb & 0x80))
- ciaatlatch = 1;
- ciaatol = ciaatod;
- }
- return getciatod(ciaatol) >> 16;
- } else {
- if (ciaatlatch)
- return getciatod(ciaatol) >> 16;
- else
- return getciatod(ciaatod) >> 16;
- }
- break;
case 11:
- if (currprefs.cs_cia6526) {
- if (!ciaatlatch) {
- if (!(ciaacrb & 0x80))
- ciaatlatch = 1;
- ciaatol = ciaatod;
- }
- if (ciaatlatch)
- return getciatod(ciaatol) >> 24;
- else
- return getciatod(ciaatod) >> 24;
- } else {
- return 0xff;
- }
- break;
case 12:
-#if KB_DEBUG
- write_log (_T("CIAA serial port: %02x %08x\n"), ciaasdr, M68K_GETPC);
-#endif
- return ciaasdr;
case 13:
- tmp = ciaaicr & ~(0x40 | 0x20);
- ciaaicr = 0;
- return tmp;
case 14:
- return ciaacra;
case 15:
- return ciaacrb;
+ return ReadCIAReg(0, reg);
}
return 0;
}
-static uae_u8 ReadCIAB (uae_u32 addr, uae_u32 *flags)
+static uae_u8 ReadCIAB(uae_u32 addr, uae_u32 *flags)
{
+ struct CIA *c = &cia[1];
uae_u32 tmp;
int reg = addr & 15;
#if CIAB_DEBUG_R > 0
if (CIAB_DEBUG_R > 1 || (munge24 (M68K_GETPC) & 0xFFF80000) != 0xF80000) {
if ((addr >= 8 && addr <= 10) || CIAB_DEBUG_R > 1)
- write_log (_T("R_CIAB: bfd%x00 %08X\n"), reg, M68K_GETPC);
+ write_log(_T("R_CIAB: bfd%x00 %08X\n"), reg, M68K_GETPC);
}
#endif
- compute_passed_time ();
+ compute_passed_time();
switch (reg) {
case 0:
- tmp = (ciabpra & ciabdra) | (ciabdra ^ 0xff);
+ tmp = (c->pra & c->dra) | (c->dra ^ 0xff);
#ifdef SERIAL_PORT
if (currprefs.use_serial) {
tmp &= 7;
- tmp |= serial_readstatus(ciabdra) & 0xf8;
+ tmp |= serial_readstatus(c->dra) & 0xf8;
}
#endif
#ifdef PARALLEL_PORT
parallel_direct_read_status(&v);
tmp |= v & 7;
} else if (parallel_port_scsi) {
- tmp = parallel_port_scsi_read(1, ciabpra, ciabdra);
+ tmp = parallel_port_scsi_read(1, c->pra, c->dra);
} else {
// serial port in output mode
- if (ciabcra & 0x40) {
+ if (c->t[0].cr & 0x40) {
tmp &= ~3;
- tmp |= (ciabsdr_cnt & 1) ? 2 : 0; // clock
- tmp |= (ciabsdr_buf & 0x80) ? 1 : 0; // data
+ tmp |= (c->sdr_cnt & 1) ? 2 : 0; // clock
+ tmp |= (c->sdr_buf & 0x80) ? 1 : 0; // data
}
tmp = handle_parport_joystick(1, tmp);
}
#endif
- tmp = dongle_cia_read(1, reg, ciabpra, tmp);
+ tmp = dongle_cia_read(1, reg, c->pra, tmp);
#if DONGLE_DEBUG > 0
if (notinrom())
write_log(_T("BFD000 R %02X %s\n"), tmp, debuginfo(0));
#endif
if (currprefs.cs_ciatype[1]) {
- tmp &= ~ciabdra;
- tmp |= ciabpra & ciabdra;
+ tmp &= ~c->dra;
+ tmp |= c->pra & c->dra;
}
return tmp;
case 1:
#if DONGLE_DEBUG > 0
- if (notinrom ())
- write_log (_T("BFD100 R %02X %s\n"), ciabprb, debuginfo(0));
+ if (notinrom())
+ write_log(_T("BFD100 R %02X %s\n"), c->prb, debuginfo(0));
#endif
- tmp = ciabprb;
+ tmp = c->prb;
tmp = DISK_status_ciab(tmp);
- tmp = dongle_cia_read (1, reg, ciabprb, tmp);
- // A PBON
- if (ciabcrb & 2) {
- int pb7 = 0;
- if (ciabcrb & 4)
- pb7 = ciabcrb & 1;
- tmp &= ~0x80;
- tmp |= pb7 ? 0x80 : 00;
- }
- // B PBON
- if (ciabcra & 2) {
- int pb6 = 0;
- if (ciabcra & 4)
- pb6 = ciabcra & 1;
- tmp &= ~0x40;
- tmp |= pb6 ? 0x40 : 00;
- }
-
+ tmp = dongle_cia_read(1, reg, c->prb, tmp);
+ tmp = CIA_PBON(c, tmp);
if (currprefs.cs_ciatype[1]) {
- tmp &= ~ciabdrb;
- tmp |= ciabprb & ciabdrb;
+ tmp &= ~c->drb;
+ tmp |= c->prb & c->drb;
}
return tmp;
case 2:
- return ciabdra;
+ return c->dra;
case 3:
- return ciabdrb;
+ return c->drb;
case 4:
- return (uae_u8)((ciabta - ciabta_passed) & 0xff);
case 5:
- return (uae_u8)((ciabta - ciabta_passed) >> 8);
case 6:
- return (uae_u8)((ciabtb - ciabtb_passed) & 0xff);
case 7:
- return (uae_u8)((ciabtb - ciabtb_passed) >> 8);
case 8:
- CIAB_tod_check ();
- if (ciabtlatch) {
- ciabtlatch = 0;
- return getciatod(ciabtol);
- } else
- return getciatod(ciabtod);
case 9:
- CIAB_tod_check ();
- if (ciabtlatch)
- return getciatod(ciabtol) >> 8;
- else
- return getciatod(ciabtod) >> 8;
case 10:
- CIAB_tod_check ();
- if (!currprefs.cs_cia6526) {
- if (!ciabtlatch) {
- /* no latching if ALARM is set */
- if (!(ciabcrb & 0x80))
- ciabtlatch = 1;
- ciabtol = ciabtod;
- }
- return getciatod(ciabtol) >> 16;
- } else {
- if (ciabtlatch)
- return getciatod(ciabtol) >> 16;
- else
- return getciatod(ciabtod) >> 16;
- }
case 11:
- if (currprefs.cs_cia6526) {
- if (!ciabtlatch) {
- if (!(ciabcrb & 0x80))
- ciabtlatch = 1;
- ciabtol = ciabtod;
- }
- if (ciabtlatch)
- return getciatod(ciabtol) >> 24;
- else
- return getciatod(ciabtod) >> 24;
- } else {
- return 0xff;
- }
- break;
case 12:
- return ciabsdr;
case 13:
-#if CIAB_DEBUG_IRQ
- if (ciabicr & (0x80 | 0x40))
- write_log (_T("CIAB IRQ cleared PC=%x\n"), M68K_GETPC);
-#endif
- tmp = ciabicr & ~(0x40 | 0x20);
- ciabicr = 0;
- return tmp;
case 14:
- //write_log (_T("CIABCRA READ %d %x\n"), ciabcra, M68K_GETPC);
- return ciabcra;
case 15:
- return ciabcrb;
+ return ReadCIAReg(1, reg);
}
return 0;
}
-static void WriteCIAA (uae_u16 addr, uae_u8 val, uae_u32 *flags)
+static void WriteCIAA(uae_u16 addr, uae_u8 val, uae_u32 *flags)
{
+ struct CIA *c = &cia[0];
int reg = addr & 15;
#if CIAA_DEBUG_W > 0
- write_log (_T("W_CIAA: bfe%x01 %02X %08X\n"), reg, val, M68K_GETPC);
+ write_log(_T("W_CIAA: bfe%x01 %02X %08X\n"), reg, val, M68K_GETPC);
#endif
#ifdef ACTION_REPLAY
ar_ciaa[reg] = val;
#endif
if (!currprefs.cs_ciaoverlay && oldovl) {
- map_overlay (1);
+ map_overlay(1);
oldovl = 0;
}
switch (reg) {
case 0:
#if DONGLE_DEBUG > 0
if (notinrom ())
- write_log (_T("BFE001 W %02X %s\n"), val, debuginfo(0));
+ write_log(_T("BFE001 W %02X %s\n"), val, debuginfo(0));
#endif
- ciaapra = (ciaapra & ~0xc3) | (val & 0xc3);
- bfe001_change ();
- handle_cd32_joystick_cia (ciaapra, ciaadra);
- dongle_cia_write (0, reg, ciaadra, val);
+ c->pra = (c->pra & ~0xc3) | (val & 0xc3);
+ bfe001_change();
+ handle_cd32_joystick_cia(c->pra, c->dra);
+ dongle_cia_write(0, reg, c->dra, val);
#ifdef AMAX
if (is_device_rom(&currprefs, ROMTYPE_AMAX, 0) > 0)
- amax_bfe001_write (val, ciaadra);
+ amax_bfe001_write(val, c->dra);
#endif
break;
case 1:
#if DONGLE_DEBUG > 0
if (notinrom ())
- write_log (_T("BFE101 W %02X %s\n"), val, debuginfo(0));
+ write_log(_T("BFE101 W %02X %s\n"), val, debuginfo(0));
#endif
- ciaaprb = val;
- dongle_cia_write (0, reg, ciaadrb, val);
+ c->prb = val;
+ dongle_cia_write(0, reg, c->drb, val);
#ifdef PARALLEL_PORT
if (isprinter()) {
if (isprinter() > 0) {
doprinter(val);
cia_parallelack();
} else if (isprinter() < 0) {
- parallel_direct_write_data(val, ciaadrb);
+ parallel_direct_write_data(val, c->drb);
cia_parallelack();
}
}
#endif
#ifdef ARCADIA
if (!isprinter() && arcadia_bios) {
- arcadia_parport(1, ciaaprb, ciaadrb);
+ arcadia_parport(1, c->prb, c->drb);
}
#endif
if (!isprinter() && parallel_port_scsi) {
- parallel_port_scsi_write(0, ciaaprb, ciaadrb);
+ parallel_port_scsi_write(0, c->prb, c->drb);
}
break;
case 2:
#if DONGLE_DEBUG > 0
if (notinrom ())
- write_log (_T("BFE201 W %02X %s\n"), val, debuginfo(0));
+ write_log(_T("BFE201 W %02X %s\n"), val, debuginfo(0));
#endif
- ciaadra = val;
- dongle_cia_write (0, reg, ciaapra, val);
- bfe001_change ();
+ c->dra = val;
+ dongle_cia_write(0, reg, c->pra, val);
+ bfe001_change();
break;
case 3:
- ciaadrb = val;
- dongle_cia_write (0, reg, ciaaprb, val);
+ c->drb = val;
+ dongle_cia_write(0, reg, c->prb, val);
#if DONGLE_DEBUG > 0
if (notinrom ())
- write_log (_T("BFE301 W %02X %s\n"), val, debuginfo(0));
+ write_log(_T("BFE301 W %02X %s\n"), val, debuginfo(0));
#endif
#ifdef ARCADIA
if (arcadia_bios)
- arcadia_parport (1, ciaaprb, ciaadrb);
+ arcadia_parport(1, c->prb, c->drb);
#endif
break;
case 4:
- CIA_update ();
- ciaala = (ciaala & 0xff00) | val;
- CIA_calctimers ();
- break;
case 5:
- CIA_update ();
- ciaala = (ciaala & 0xff) | (val << 8);
- if ((ciaacra & 1) == 0)
- ciaata = ciaala;
- if (ciaacra & 8) {
- ciaata = ciaala;
- ciaacra |= 1;
- ciaastarta = CIASTARTCYCLESHI;
- }
- CIA_calctimers ();
- break;
case 6:
- CIA_update ();
- ciaalb = (ciaalb & 0xff00) | val;
- CIA_calctimers ();
- break;
case 7:
- CIA_update ();
- ciaalb = (ciaalb & 0xff) | (val << 8);
- if ((ciaacrb & 1) == 0)
- ciaatb = ciaalb;
- if (ciaacrb & 8) {
- ciaatb = ciaalb;
- ciaacrb |= 1;
- ciaastartb = CIASTARTCYCLESHI;
- }
- CIA_calctimers ();
- break;
case 8:
- if (ciaacrb & 0x80) {
- setciatod(&ciaaalarm , (getciatod(ciaaalarm) & ~0xff) | val);
- } else {
- setciatod(&ciaatod, (getciatod(ciaatod) & ~0xff) | val);
- ciaatodon = 1;
- ciaa_checkalarm (false);
- }
- break;
case 9:
- if (ciaacrb & 0x80) {
- setciatod(&ciaaalarm, (getciatod(ciaaalarm) & ~0xff00) | (val << 8));
- } else {
- setciatod(&ciaatod, (getciatod(ciaatod) & ~0xff00) | (val << 8));
- }
- break;
case 10:
- if (ciaacrb & 0x80) {
- setciatod(&ciaaalarm, (getciatod(ciaaalarm) & ~0xff0000) | (val << 16));
- } else {
- setciatod(&ciaatod, (getciatod(ciaatod) & ~0xff0000) | (val << 16));
- if (!currprefs.cs_cia6526)
- ciaatodon = 0;
- }
- break;
case 11:
- if (currprefs.cs_cia6526) {
- if (ciaacrb & 0x80) {
- setciatod(&ciaaalarm, (getciatod(ciaaalarm) & ~0xff000000) | (val << 24));
- } else {
- setciatod(&ciaatod, (getciatod(ciaatod) & ~0xff000000) | (val << 24));
- ciaatodon = 0;
- }
- }
- break;
case 12:
- CIA_update ();
- ciaasdr = val;
- if ((ciaacra & 0x41) == 0x41) {
- ciaasdr_load = 1;
- if (ciaasdr_cnt == 0) {
- ciaasdr_cnt = 8 * 2;
- ciaasdr_load = 0;
- ciaasdr_buf = ciaasdr;
- }
- }
-#if KB_DEBUG
- write_log (_T("CIAA serial port write: %02x cnt=%d PC=%08x\n"), ciaasdr, ciaasdr_cnt, M68K_GETPC);
-#endif
- CIA_calctimers ();
- break;
case 13:
- setclr (&ciaaimask,val);
- RethinkICRA ();
+ case 15:
+ CIA_update();
+ WriteCIAReg(0, reg, val);
+ CIA_calctimers();
break;
case 14:
- CIA_update ();
- val &= 0x7f; /* bit 7 is unused */
- if ((val & 1) && !(ciaacra & 1))
- ciaastarta = CIASTARTCYCLESCRA;
- if (currprefs.cpuboard_type != 0 && (val & 0x40) != (ciaacra & 0x40)) {
+ CIA_update();
+ // keyboard handshake handling
+ if (currprefs.cpuboard_type != 0 && (val & 0x40) != (c->t[0].cr & 0x40)) {
/* bleh, Phase5 CPU timed early boot key check fix.. */
if (m68k_getpc() >= 0xf00000 && m68k_getpc() < 0xf80000)
check_keyboard();
}
- if ((val & 0x40) != 0 && (ciaacra & 0x40) == 0) {
+ if ((val & CR_INMODE1) != 0 && (c->t[0].cr & CR_INMODE1) == 0) {
// handshake start
if (kblostsynccnt > 0 && currprefs.cs_kbhandshake) {
kbhandshakestart = get_cycles();
}
#if KB_DEBUG
- write_log(_T("KB_ACK_START %02x->%02x %08x\n"), ciaacra, val, M68K_GETPC);
+ write_log(_T("KB_ACK_START %02x->%02x %08x\n"), c->t[0].cr, val, M68K_GETPC);
#endif
- } else if ((val & 0x40) == 0 && (ciaacra & 0x40) != 0) {
+ } else if ((val & CR_INMODE1) == 0 && (c->t[0].cr & CR_INMODE1) != 0) {
// handshake end
/* todo: check if low to high or high to low only */
if (kblostsynccnt > 0 && currprefs.cs_kbhandshake) {
- int len = (int)get_cycles() - (int)kbhandshakestart;
+ evt_t len = get_cycles() - kbhandshakestart;
if (len < currprefs.cs_kbhandshake * CYCLE_UNIT) {
write_log(_T("Keyboard handshake pulse length %d < %d (CCKs)\n"), len / CYCLE_UNIT, currprefs.cs_kbhandshake);
}
}
kblostsynccnt = 0;
#if KB_DEBUG
- write_log (_T("KB_ACK_END %02x->%02x %08x\n"), ciaacra, val, M68K_GETPC);
+ write_log(_T("KB_ACK_END %02x->%02x %08x\n"), c->t[0].cr, val, M68K_GETPC);
#endif
}
- ciaacra = val;
- if (ciaacra & 0x10) {
- ciaacra &= ~0x10;
- ciaata = ciaala;
- }
- CIA_calctimers ();
- break;
- case 15:
- CIA_update ();
- if ((val & 1) && !(ciaacrb & 1))
- ciaastartb = CIASTARTCYCLESCRA;
- ciaacrb = val;
- if (ciaacrb & 0x10) {
- ciaacrb &= ~0x10;
- ciaatb = ciaalb;
- }
- CIA_calctimers ();
+ WriteCIAReg(0, reg, val);
+ CIA_calctimers();
break;
}
}
static void write_ciab_serial(uae_u8 ndata, uae_u8 odata, uae_u8 ndir, uae_u8 odir)
{
+ struct CIA *c = &cia[1];
uae_u8 val = ndata & ndir;
+ uae_u8 icr = 0;
+
// CNT 0->1?
if ((val & 2) && !((odata & odir) & 2)) {
- int icr = 0;
// CIA-B SP in input mode
- if (!(ciabcra & 0x40)) {
- ciabsdr_buf <<= 1;
- ciabsdr_buf |= (val & 1) ? 0x01 : 0x00;
- ciabsdr_cnt++;
- if (ciabsdr_cnt >= 8) {
+ if (!(c->t[0].cr & CR_SPMODE)) {
+ c->sdr_buf <<= 1;
+ c->sdr_buf |= (val & 1) ? 0x01 : 0x00;
+ c->sdr_cnt++;
+ if (c->sdr_cnt >= 8) {
// Data received
- ciabsdr = ciabsdr_buf;
- ciabicr |= 8;
- icr = 1;
- ciabsdr_cnt = 0;
- }
- }
- // A INMODE=1 (count CNT pulses)
- if ((ciabcra & 0x21) == 0x21) {
- ciabta--;
- if (ciabta == 0) {
- ciabicr |= 1;
- ciabta = ciabla;
- if (ciabcra & 0x8) {
- ciabcra &= ~1;
- }
- // B INMODE = 10 or 11 (count A undeflows)
- if ((ciabcrb & 0x41) == 0x41) {
- ciabtb--;
- if (ciabtb == 0) {
- ciabicr |= 2;
- ciabtb = ciablb;
- if (ciabcrb & 0x8) {
- ciabcrb &= ~1;
- }
- }
- }
- icr = 1;
+ c->sdr = c->sdr_buf;
+ icr |= ICR_SP;
+ c->sdr_cnt = 0;
}
}
- // B INMODE=01 (count CNT pulses)
- if ((ciabcrb & 0x61) == 0x21) {
- ciabtb--;
- if (ciabtb == 0) {
- ciabicr |= 2;
- ciabtb = ciablb;
- if (ciabcrb & 0x8) {
- ciabcrb &= ~1;
- }
- icr = 1;
- }
- }
- if (icr) {
- RethinkICRB();
- }
+ icr |= cia_inmode_cnt(1);
+ }
+ if (icr) {
+ CIA_sync_interrupt(1, icr);
}
}
-static void WriteCIAB (uae_u16 addr, uae_u8 val, uae_u32 *flags)
+static void WriteCIAB(uae_u16 addr, uae_u8 val, uae_u32 *flags)
{
+ struct CIA *c = &cia[1];
int reg = addr & 15;
#if CIAB_DEBUG_W > 0
if (((addr >= 8 && addr <= 10) || addr == 15) || CIAB_DEBUG_W > 1)
- write_log (_T("W_CIAB: bfd%x00 %02X %08X\n"), reg, val, M68K_GETPC);
+ write_log(_T("W_CIAB: bfd%x00 %02X %08X\n"), reg, val, M68K_GETPC);
#endif
#ifdef ACTION_REPLAY
ar_ciab[reg] = val;
switch (reg) {
case 0:
#if DONGLE_DEBUG > 0
- if (notinrom ())
- write_log (_T("BFD000 W %02X %s\n"), val, debuginfo(0));
+ if (notinrom())
+ write_log(_T("BFD000 W %02X %s\n"), val, debuginfo(0));
#endif
- dongle_cia_write (1, reg, ciabdra, val);
- write_ciab_serial(val, ciabpra, ciabdra, ciabdra);
- ciabpra = val;
+ dongle_cia_write(1, reg, c->dra, val);
+ write_ciab_serial(val, c->pra, c->dra, c->dra);
+ c->pra = val;
#ifdef SERIAL_PORT
if (currprefs.use_serial)
- serial_writestatus(ciabpra, ciabdra);
+ serial_writestatus(c->pra, c->dra);
#endif
#ifdef PARALLEL_PORT
- if (isprinter () < 0) {
- parallel_direct_write_status (val, ciabdra);
- } else if (parallel_port_scsi) {
- parallel_port_scsi_write(1, ciabpra, ciabdra);
+ if (isprinter() < 0) {
+ parallel_direct_write_status(val, c->dra);
+ }
+ else if (parallel_port_scsi) {
+ parallel_port_scsi_write(1, c->pra, c->dra);
}
#endif
break;
case 1:
*flags |= 2;
#if DONGLE_DEBUG > 0
- if (notinrom ())
- write_log (_T("BFD100 W %02X %s\n"), val, debuginfo(0));
-#endif
- dongle_cia_write (1, ciabdrb, reg, val);
- ciabprb = val;
- // PBON overrides PB6 and PB7
- if (ciabcrb & 2) {
- int pb7 = 0;
- // OUTMODE
- if (ciabcrb & 4) {
- pb7 = ciabcrb & 1;
- }
- val &= ~0x80;
- val |= pb7 ? 0x80 : 00;
- }
- if (ciabcra & 2) {
- int pb6 = 0;
- // OUTMODE
- if (ciabcra & 4) {
- pb6 = ciabcra & 1;
- }
- val &= ~0x40;
- val |= pb6 ? 0x40 : 00;
- }
- DISK_select (val);
+ if (notinrom())
+ write_log(_T("BFD100 W %02X %s\n"), val, debuginfo(0));
+#endif
+ dongle_cia_write(1, c->drb, reg, val);
+ c->prb = val;
+ val = CIA_PBON(c, val);
+ DISK_select(val);
break;
case 2:
#if DONGLE_DEBUG > 0
- if (notinrom ())
- write_log (_T("BFD200 W %02X %s\n"), val, debuginfo(0));
+ if (notinrom())
+ write_log(_T("BFD200 W %02X %s\n"), val, debuginfo(0));
#endif
- dongle_cia_write (1, reg, ciabpra, val);
- write_ciab_serial(ciabpra, ciabpra, val, ciabdra);
- ciabdra = val;
+ dongle_cia_write(1, reg, c->pra, val);
+ write_ciab_serial(c->pra, c->pra, val, c->dra);
+ c->dra = val;
#ifdef SERIAL_PORT
if (currprefs.use_serial)
- serial_writestatus (ciabpra, ciabdra);
+ serial_writestatus(c->pra, c->dra);
#endif
break;
case 3:
#if DONGLE_DEBUG > 0
- if (notinrom ())
- write_log (_T("BFD300 W %02X %s\n"), val, debuginfo(0));
+ if (notinrom())
+ write_log(_T("BFD300 W %02X %s\n"), val, debuginfo(0));
#endif
- dongle_cia_write (1, reg, ciabprb, val);
- ciabdrb = val;
+ dongle_cia_write(1, reg, c->prb, val);
+ c->drb = val;
break;
case 4:
- CIA_update ();
- ciabla = (ciabla & 0xff00) | val;
- CIA_calctimers ();
- break;
case 5:
- CIA_update ();
- ciabla = (ciabla & 0xff) | (val << 8);
- if ((ciabcra & 1) == 0)
- ciabta = ciabla;
- if (ciabcra & 8) {
- ciabta = ciabla;
- ciabcra |= 1;
- ciabstarta = CIASTARTCYCLESHI;
- }
- CIA_calctimers ();
- break;
case 6:
- CIA_update ();
- ciablb = (ciablb & 0xff00) | val;
- CIA_calctimers ();
- break;
case 7:
- CIA_update ();
- ciablb = (ciablb & 0xff) | (val << 8);
- if ((ciabcrb & 1) == 0)
- ciabtb = ciablb;
- if (ciabcrb & 8) {
- ciabtb = ciablb;
- ciabcrb |= 1;
- ciabstartb = CIASTARTCYCLESHI;
- }
- CIA_calctimers ();
- break;
case 8:
- CIAB_tod_check ();
- if (ciabcrb & 0x80) {
- setciatod(&ciabalarm, (getciatod(ciabalarm) & ~0xff) | val);
- } else {
- setciatod(&ciabtod, (getciatod(ciabtod) & ~0xff) | val);
- ciabtodon = 1;
- ciab_checkalarm (false, true);
- }
- break;
case 9:
- CIAB_tod_check ();
- if (ciabcrb & 0x80) {
- setciatod(&ciabalarm, (getciatod(ciabalarm) & ~0xff00) | (val << 8));
- } else {
- setciatod(&ciabtod, (getciatod(ciabtod) & ~0xff00) | (val << 8));
- }
- break;
case 10:
- CIAB_tod_check ();
- if (ciabcrb & 0x80) {
- setciatod(&ciabalarm, (getciatod(ciabalarm) & ~0xff0000) | (val << 16));
- } else {
- setciatod(&ciabtod, (getciatod(ciabtod) & ~0xff0000) | (val << 16));
- if (!currprefs.cs_cia6526)
- ciabtodon = 0;
- }
- break;
case 11:
- if (currprefs.cs_cia6526) {
- CIAB_tod_check ();
- if (ciabcrb & 0x80) {
- setciatod(&ciabalarm, (getciatod(ciabalarm) & ~0xff000000) | (val << 24));
- } else {
- setciatod(&ciabtod, (getciatod(ciabtod) & ~0xff000000) | (val << 24));
- ciabtodon = 0;
- }
- }
- break;
case 12:
- CIA_update ();
- ciabsdr = val;
- if ((ciabcra & 0x41) == 0x41) {
- ciabsdr_load = 1;
- if (ciabsdr_cnt == 0) {
- ciabsdr_cnt = 8 * 2;
- ciabsdr_load = 0;
- }
- }
- CIA_calctimers ();
- break;
case 13:
- setclr (&ciabimask, val);
- RethinkICRB ();
- break;
case 14:
- CIA_update ();
- val &= 0x7f; /* bit 7 is unused */
- if ((val & 1) && !(ciabcra & 1))
- ciabstarta = CIASTARTCYCLESCRA;
- ciabcra = val;
- if (ciabcra & 0x10) {
- ciabcra &= ~0x10;
- ciabta = ciabla;
- }
- CIA_calctimers ();
- break;
case 15:
- CIA_update ();
- if ((val & 1) && !(ciabcrb & 1))
- ciabstartb = CIASTARTCYCLESCRA;
- ciabcrb = val;
- if (ciabcrb & 0x10) {
- ciabcrb &= ~0x10;
- ciabtb = ciablb;
- }
- CIA_calctimers ();
+ CIA_update();
+ WriteCIAReg(1, reg, val);
+ CIA_calctimers();
break;
}
}
-void cia_set_overlay (bool overlay)
+void cia_set_overlay(bool overlay)
{
oldovl = overlay;
}
-void CIA_reset (void)
+void CIA_reset(void)
{
#ifdef TOD_HACK
tod_hack_tv = 0;
serbits = 0;
resetwarning_phase = resetwarning_timer = 0;
heartbeat_cnt = 0;
- ciab_tod_event_state = 0;
+ cia[1].tod_event_state = 0;
if (!savestate_state) {
oldovl = true;
kbstate = 0;
- ciaatlatch = ciabtlatch = 0;
- ciaapra = 0; ciaadra = 0;
- ciaaprb = 0; ciaadrb = 0;
- ciaatod = ciabtod = 0; ciaatodon = ciabtodon = 0;
- ciaaicr = ciabicr = ciaaimask = ciabimask = 0;
- ciaacra = ciaacrb = ciabcra = ciabcrb = 0;
- ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF;
- ciaaalarm = ciabalarm = 0;
- ciabpra = 0x8C; ciabdra = 0;
- ciabprb = 0; ciabdrb = 0;
- ciaasdr_cnt = 0; ciaasdr = 0; ciaasdr_load = 0;
- ciabsdr_cnt = 0; ciabsdr = 0; ciabsdr_buf = 0; ciabsdr_load = 0;
- ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0;
+ memset(&cia, 0, sizeof(cia));
+ cia[0].t[0].timer = 0xffff;
+ cia[0].t[1].timer = 0xffff;
+ cia[1].t[0].timer = 0xffff;
+ cia[1].t[1].timer = 0xffff;
+ cia[0].t[0].latch = 0xffff;
+ cia[0].t[1].latch = 0xffff;
+ cia[1].t[0].latch = 0xffff;
+ cia[1].t[1].latch = 0xffff;
+ cia[1].pra = 0x8c;
CIA_calctimers();
- DISK_select_set(ciabprb);
+ DISK_select_set(cia[1].prb);
}
map_overlay(0);
check_led();
void dumpcia(void)
{
+ struct CIA *a = &cia[0];
+ struct CIA *b = &cia[1];
+
+ compute_passed_time();
+
console_out_f(_T("A: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)\n"),
- ciaacra, ciaacrb, ciaaicr, ciaaimask, ciaata, ciaala, ciaatb, ciaalb);
- console_out_f(_T("TOD %06x (%06x) ALARM %06x %c%c CYC=%08X\n"),
- ciaatod, ciaatol, ciaaalarm, ciaatlatch ? 'L' : ' ', ciaatodon ? ' ' : 'S', get_cycles());
+ a->t[0].cr, a->t[1].cr, a->icr1, a->imask, a->t[0].timer - a->t[0].passed, a->t[0].latch, a->t[1].timer - a->t[1].passed, a->t[1].latch);
+ console_out_f(_T("TOD %06x (%06x) ALARM %06x %c%c CYC=%016llX\n"),
+ a->tod, a->tol, a->alarm, a->tlatch ? 'L' : '-', a->todon ? '-' : 'S', get_cycles());
console_out_f(_T("B: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)\n"),
- ciabcra, ciabcrb, ciabicr, ciabimask, ciabta, ciabla, ciabtb, ciablb);
+ b->t[0].cr, b->t[1].cr, b->icr1, b->imask, b->t[0].timer - b->t[0].passed, b->t[0].latch, b->t[1].timer - b->t[1].passed, b->t[1].latch);
console_out_f(_T("TOD %06x (%06x) ALARM %06x %c%c\n"),
- ciabtod, ciabtol, ciabalarm, ciabtlatch ? 'L' : ' ', ciabtodon ? ' ' : 'S');
+ b->tod, b->tol, b->alarm, b->tlatch ? 'L' : '-', b->todon ? '-' : 'S');
}
/* CIA memory access */
return;
#endif
+#if CIA_IRQ_PROCESS_DELAY
if (currprefs.cpu_memory_cycle_exact) {
cia_interrupt_disabled |= cianummask;
}
+#endif
#ifndef CUSTOM_SIMPLE
- evt_t c = get_cycles();
+ evt_t c = get_e_cycles();
int div10 = c % DIV10;
int add = 0;
- if (div10 == 0) {
- add = CYCLE_UNIT;
- } else if (div10 > CYCLE_UNIT) {
- add = DIV10 - div10;
- add += CYCLE_UNIT;
+ int synccycle = E_CLOCK_SYNC * E_CYCLE_UNIT;
+ if (div10 < synccycle) {
+ add += synccycle - div10;
+ } else if (div10 > synccycle) {
+ add += DIV10 - div10;
+ add += synccycle;
}
// sync + 4 first cycles of E-clock
- add += 4 * CYCLE_UNIT / 2;
+ add += E_CLOCK_1 * E_CYCLE_UNIT;
x_do_cycles_pre(add);
#endif
}
-static void cia_wait_post (int cianummask, uae_u32 value)
+static void cia_wait_post(int cianummask, uaecptr addr, uae_u32 value, bool rw)
{
+#ifdef DEBUGGER
+ if (currprefs.cpu_memory_cycle_exact && debug_dma) {
+ int r = (addr & 0xf00) >> 8;
+ int hpos = current_hpos();
+ record_cia_access(r, cianummask, value, rw, hpos, vpos);
+ }
+#endif
+
#ifdef WITH_PPC
if (ppc_state)
return;
if (currprefs.cpu_thread)
return;
if (currprefs.cachesize) {
- do_cycles (8 * CYCLE_UNIT /2);
+ do_cycles(8 * E_CYCLE_UNIT);
} else {
- // Last 4 cycles of E-clock
- x_do_cycles_post(4 * CYCLE_UNIT / 2, value);
+ // Last 6 cycles of E-clock
+ x_do_cycles_post(E_CLOCK_2 * E_CYCLE_UNIT, value);
+#if CIA_IRQ_PROCESS_DELAY
if (currprefs.cpu_memory_cycle_exact) {
cia_interrupt_disabled &= ~cianummask;
if ((cia_interrupt_delay & cianummask) & 1) {
ICR(0x2000);
}
}
+#endif
}
+#if CIA_IRQ_PROCESS_DELAY
if (!currprefs.cpu_memory_cycle_exact && cia_interrupt_delay) {
int v = cia_interrupt_delay;
cia_interrupt_delay = 0;
if (v & 2)
ICR(0x2000);
}
+#endif
}
static void validate_cia(uaecptr addr, int write, uae_u8 val)
return cs;
}
-static uae_u32 REGPARAM2 cia_bget (uaecptr addr)
+static uae_u32 REGPARAM2 cia_bget(uaecptr addr)
{
int r = (addr & 0xf00) >> 8;
uae_u8 v = 0;
switch (cia_chipselect(addr))
{
case 0:
- if (!issinglecia ()) {
- cia_wait_pre (1 | 2);
- v = (addr & 1) ? ReadCIAA (r, &flags) : ReadCIAB (r, &flags);
- cia_wait_post (1 | 2, v);
+ if (!issinglecia()) {
+ cia_wait_pre(1 | 2);
+ v = (addr & 1) ? ReadCIAA(r, &flags) : ReadCIAB(r, &flags);
+ cia_wait_post(1 | 2, addr, v, false);
}
break;
case 1:
- cia_wait_pre (2);
+ cia_wait_pre(2);
if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible) {
- v = (addr & 1) ? regs.irc : ReadCIAB (r, &flags);
+ v = (addr & 1) ? regs.irc : ReadCIAB(r, &flags);
} else {
- v = (addr & 1) ? dummy_get_safe(addr, 1, false, 0) : ReadCIAB (r, &flags);
+ v = (addr & 1) ? dummy_get_safe(addr, 1, false, 0) : ReadCIAB(r, &flags);
}
- cia_wait_post (2, v);
+ cia_wait_post(2, addr, v, false);
break;
case 2:
- cia_wait_pre (1);
+ cia_wait_pre(1);
if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible)
- v = (addr & 1) ? ReadCIAA (r, &flags) : regs.irc >> 8;
+ v = (addr & 1) ? ReadCIAA(r, &flags) : regs.irc >> 8;
else
- v = (addr & 1) ? ReadCIAA (r, &flags) : dummy_get_safe(addr, 1, false, 0);
- cia_wait_post (1, v);
+ v = (addr & 1) ? ReadCIAA(r, &flags) : dummy_get_safe(addr, 1, false, 0);
+ cia_wait_post(1, addr, v, false);
break;
case 3:
if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible) {
- cia_wait_pre (0);
+ cia_wait_pre(0);
v = (addr & 1) ? regs.irc : regs.irc >> 8;
- cia_wait_post (0, v);
+ cia_wait_post(0, addr, v, false);
}
if (warned > 0 || currprefs.illegal_mem) {
- write_log (_T("cia_bget: unknown CIA address %08X=%02X PC=%08X\n"), addr, v & 0xff, M68K_GETPC);
+ write_log(_T("cia_bget: unknown CIA address %08X=%02X PC=%08X\n"), addr, v & 0xff, M68K_GETPC);
warned--;
}
break;
return v;
}
-static uae_u32 REGPARAM2 cia_wget (uaecptr addr)
+static uae_u32 REGPARAM2 cia_wget(uaecptr addr)
{
int r = (addr & 0xf00) >> 8;
uae_u16 v = 0;
switch (cia_chipselect(addr))
{
case 0:
- if (!issinglecia ())
+ if (!issinglecia())
{
- cia_wait_pre (1 | 2);
+ cia_wait_pre(1 | 2);
v = ReadCIAB(r, &flags) << 8;
v |= ReadCIAA(r, &flags);
- cia_wait_post (1 | 2, v);
+ cia_wait_post(1 | 2, addr, v, false);
}
break;
case 1:
- cia_wait_pre (2);
+ cia_wait_pre(2);
v = ReadCIAB(r, &flags) << 8;
- v |= dummy_get_safe(addr + 1, 1, false, 0);
- cia_wait_post (2, v);
+ v |= dummy_get_safe(addr + 1, 1, false, 0) & 0xff;
+ cia_wait_post(2, addr, v, false);
break;
case 2:
- cia_wait_pre (1);
+ cia_wait_pre(1);
v = ReadCIAA(r, &flags);
v |= dummy_get_safe(addr, 1, false, 0) << 8;
- cia_wait_post (1, v);
+ cia_wait_post(1, addr, v, false);
break;
case 3:
if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible) {
- cia_wait_pre (0);
+ cia_wait_pre(0);
v = regs.irc;
- cia_wait_post (0, v);
+ cia_wait_post(0, addr, v, false);
}
if (warned > 0 || currprefs.illegal_mem) {
- write_log (_T("cia_wget: unknown CIA address %08X=%04X PC=%08X\n"), addr, v & 0xffff, M68K_GETPC);
+ write_log(_T("cia_wget: unknown CIA address %08X=%04X PC=%08X\n"), addr, v & 0xffff, M68K_GETPC);
warned--;
}
break;
return v;
}
-static uae_u32 REGPARAM2 cia_lget (uaecptr addr)
+static uae_u32 REGPARAM2 cia_lget(uaecptr addr)
{
uae_u32 v;
- v = cia_wget (addr) << 16;
- v |= cia_wget (addr + 2);
+ v = cia_wget(addr) << 16;
+ v |= cia_wget(addr + 2);
return v;
}
-static uae_u32 REGPARAM2 cia_wgeti (uaecptr addr)
+static uae_u32 REGPARAM2 cia_wgeti(uaecptr addr)
{
if (currprefs.cpu_model >= 68020)
- return dummy_wgeti (addr);
- return cia_wget (addr);
+ return dummy_wgeti(addr);
+ return cia_wget(addr);
}
-static uae_u32 REGPARAM2 cia_lgeti (uaecptr addr)
+static uae_u32 REGPARAM2 cia_lgeti(uaecptr addr)
{
if (currprefs.cpu_model >= 68020)
- return dummy_lgeti (addr);
- return cia_lget (addr);
+ return dummy_lgeti(addr);
+ return cia_lget(addr);
}
return false;
}
-static void REGPARAM2 cia_bput (uaecptr addr, uae_u32 value)
+static void REGPARAM2 cia_bput(uaecptr addr, uae_u32 value)
{
int r = (addr & 0xf00) >> 8;
return;
}
- if (!isgaylenocia (addr))
+ if (!isgaylenocia(addr))
return;
if (memwatch_access_validator) {
int cs = cia_chipselect(addr);
- if (!issinglecia () || (cs & 3) != 0) {
+ if (!issinglecia() || (cs & 3) != 0) {
uae_u32 flags = 0;
- cia_wait_pre (((cs & 2) == 0 ? 1 : 0) | ((cs & 1) == 0 ? 2 : 0));
+ cia_wait_pre(((cs & 2) == 0 ? 1 : 0) | ((cs & 1) == 0 ? 2 : 0));
if ((cs & 2) == 0)
- WriteCIAB (r, value, &flags);
+ WriteCIAB(r, value, &flags);
if ((cs & 1) == 0)
- WriteCIAA (r, value, &flags);
- cia_wait_post (((cs & 2) == 0 ? 1 : 0) | ((cs & 1) == 0 ? 2 : 0), value);
+ WriteCIAA(r, value, &flags);
+ cia_wait_post(((cs & 2) == 0 ? 1 : 0) | ((cs & 1) == 0 ? 2 : 0), addr, value, true);
if (((cs & 3) == 3) && (warned > 0 || currprefs.illegal_mem)) {
- write_log (_T("cia_bput: unknown CIA address %08X=%02X PC=%08X\n"), addr, value & 0xff, M68K_GETPC);
+ write_log(_T("cia_bput: unknown CIA address %08X=%02X PC=%08X\n"), addr, value & 0xff, M68K_GETPC);
warned--;
}
#ifdef ACTION_REPLAY
}
}
-static void REGPARAM2 cia_wput (uaecptr addr, uae_u32 v)
+static void REGPARAM2 cia_wput(uaecptr addr, uae_u32 v)
{
int r = (addr & 0xf00) >> 8;
return;
}
- if (!isgaylenocia (addr))
+ if (!isgaylenocia(addr))
return;
if (memwatch_access_validator) {
int cs = cia_chipselect(addr);
- if (!issinglecia () || (cs & 3) != 0) {
+ if (!issinglecia() || (cs & 3) != 0) {
uae_u32 flags = 0;
- cia_wait_pre (((cs & 2) == 0 ? 1 : 0) | ((cs & 1) == 0 ? 2 : 0));
+ cia_wait_pre(((cs & 2) == 0 ? 1 : 0) | ((cs & 1) == 0 ? 2 : 0));
if ((cs & 2) == 0)
- WriteCIAB (r, v >> 8, &flags);
+ WriteCIAB(r, v >> 8, &flags);
if ((cs & 1) == 0)
- WriteCIAA (r, v & 0xff, &flags);
- cia_wait_post (((cs & 2) == 0 ? 1 : 0) | ((cs & 1) == 0 ? 2 : 0), v);
+ WriteCIAA(r, v & 0xff, &flags);
+ cia_wait_post(((cs & 2) == 0 ? 1 : 0) | ((cs & 1) == 0 ? 2 : 0), addr, v, true);
if (((cs & 3) == 3) && (warned > 0 || currprefs.illegal_mem)) {
- write_log (_T("cia_wput: unknown CIA address %08X=%04X %08X\n"), addr, v & 0xffff, M68K_GETPC);
+ write_log(_T("cia_wput: unknown CIA address %08X=%04X %08X\n"), addr, v & 0xffff, M68K_GETPC);
warned--;
}
#ifdef ACTION_REPLAY
}
}
-static void REGPARAM2 cia_lput (uaecptr addr, uae_u32 value)
+static void REGPARAM2 cia_lput(uaecptr addr, uae_u32 value)
{
if (cia_debug(addr, value, sz_long))
return;
- cia_wput (addr, value >> 16);
- cia_wput (addr + 2, value & 0xffff);
+ cia_wput(addr, value >> 16);
+ cia_wput(addr + 2, value & 0xffff);
}
/* battclock memory access */
-static uae_u32 REGPARAM3 clock_lget (uaecptr) REGPARAM;
-static uae_u32 REGPARAM3 clock_wget (uaecptr) REGPARAM;
-static uae_u32 REGPARAM3 clock_bget (uaecptr) REGPARAM;
-static void REGPARAM3 clock_lput (uaecptr, uae_u32) REGPARAM;
-static void REGPARAM3 clock_wput (uaecptr, uae_u32) REGPARAM;
-static void REGPARAM3 clock_bput (uaecptr, uae_u32) REGPARAM;
+static uae_u32 REGPARAM3 clock_lget(uaecptr) REGPARAM;
+static uae_u32 REGPARAM3 clock_wget(uaecptr) REGPARAM;
+static uae_u32 REGPARAM3 clock_bget(uaecptr) REGPARAM;
+static void REGPARAM3 clock_lput(uaecptr, uae_u32) REGPARAM;
+static void REGPARAM3 clock_wput(uaecptr, uae_u32) REGPARAM;
+static void REGPARAM3 clock_bput(uaecptr, uae_u32) REGPARAM;
addrbank clock_bank = {
clock_lget, clock_wget, clock_bget,
ABFLAG_IO, S_READ, S_WRITE, NULL, 0x3f, 0xd80000
};
-static uae_u8 getclockreg (int addr, struct tm *ct)
+static uae_u8 getclockreg(int addr, struct tm *ct)
{
uae_u8 v = 0;
return v;
}
-static void write_battclock (void)
+static void write_battclock(void)
{
if (!currprefs.rtcfile[0] || currprefs.cs_rtc == 0)
return;
TCHAR path[MAX_DPATH];
cfgfile_resolve_path_out_load(currprefs.rtcfile, path, MAX_DPATH, PATH_ROM);
- struct zfile *f = zfile_fopen (path, _T("wb"));
+ struct zfile *f = zfile_fopen(path, _T("wb"));
if (f) {
struct tm *ct;
- time_t t = time (0);
+ time_t t = time(0);
t += currprefs.cs_rtc_adjust;
- ct = localtime (&t);
+ ct = localtime(&t);
uae_u8 od;
if (currprefs.cs_rtc == 2) {
od = rtc_ricoh.clock_control_d;
od = rtc_msm.clock_control_d;
}
for (int i = 0; i < 13; i++) {
- uae_u8 v = getclockreg (i, ct);
- zfile_fwrite (&v, 1, 1, f);
+ uae_u8 v = getclockreg(i, ct);
+ zfile_fwrite(&v, 1, 1, f);
}
if (currprefs.cs_rtc == 2) {
rtc_ricoh.clock_control_d = od;
- zfile_fwrite (&rtc_ricoh.clock_control_d, 1, 1, f);
- zfile_fwrite (&rtc_ricoh.clock_control_e, 1, 1, f);
- zfile_fwrite (&rtc_ricoh.clock_control_f, 1, 1, f);
+ zfile_fwrite(&rtc_ricoh.clock_control_d, 1, 1, f);
+ zfile_fwrite(&rtc_ricoh.clock_control_e, 1, 1, f);
+ zfile_fwrite(&rtc_ricoh.clock_control_f, 1, 1, f);
} else {
rtc_msm.clock_control_d = od;
- zfile_fwrite (&rtc_msm.clock_control_d, 1, 1, f);
- zfile_fwrite (&rtc_msm.clock_control_e, 1, 1, f);
- zfile_fwrite (&rtc_msm.clock_control_f, 1, 1, f);
+ zfile_fwrite(&rtc_msm.clock_control_d, 1, 1, f);
+ zfile_fwrite(&rtc_msm.clock_control_e, 1, 1, f);
+ zfile_fwrite(&rtc_msm.clock_control_f, 1, 1, f);
}
if (currprefs.cs_rtc == 2) {
- zfile_fwrite (rtc_ricoh.rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
- zfile_fwrite (rtc_ricoh.rtc_memory, RF5C01A_RAM_SIZE, 1, f);
+ zfile_fwrite(rtc_ricoh.rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
+ zfile_fwrite(rtc_ricoh.rtc_memory, RF5C01A_RAM_SIZE, 1, f);
}
- zfile_fclose (f);
+ zfile_fclose(f);
}
}
-void rtc_hardreset (void)
+void rtc_hardreset(void)
{
if (currprefs.cs_rtc == 1 || currprefs.cs_rtc == 3) { /* MSM6242B */
clock_bank.name = currprefs.cs_rtc == 1 ? _T("Battery backed up clock (MSM6242B)") : _T("Battery backed up clock A2000 (MSM6242B)");
rtc_ricoh.clock_control_d = 0x8; /* Timer EN */
rtc_ricoh.clock_control_e = 0;
rtc_ricoh.clock_control_f = 0;
- memset (rtc_ricoh.rtc_memory, 0, RF5C01A_RAM_SIZE);
- memset (rtc_ricoh.rtc_alarm, 0, RF5C01A_RAM_SIZE);
+ memset(rtc_ricoh.rtc_memory, 0, RF5C01A_RAM_SIZE);
+ memset(rtc_ricoh.rtc_alarm, 0, RF5C01A_RAM_SIZE);
rtc_ricoh.rtc_alarm[10] = 1; /* 24H mode */
rtc_ricoh.delayed_write = 0;
}
if (currprefs.rtcfile[0]) {
TCHAR path[MAX_DPATH];
cfgfile_resolve_path_out_load(currprefs.rtcfile, path, MAX_DPATH, PATH_ROM);
- struct zfile *f = zfile_fopen (path, _T("rb"));
+ struct zfile *f = zfile_fopen(path, _T("rb"));
if (f) {
uae_u8 empty[13];
- zfile_fread (empty, 13, 1, f);
+ zfile_fread(empty, 13, 1, f);
uae_u8 v;
- zfile_fread (&v, 1, 1, f);
+ zfile_fread(&v, 1, 1, f);
rtc_ricoh.clock_control_d = v;
rtc_msm.clock_control_d = v;
- zfile_fread (&v, 1, 1, f);
+ zfile_fread(&v, 1, 1, f);
rtc_ricoh.clock_control_e = v;
rtc_msm.clock_control_d = v;
- zfile_fread (&v, 1, 1, f);
+ zfile_fread(&v, 1, 1, f);
rtc_ricoh.clock_control_f = v;
rtc_msm.clock_control_d = v;
- zfile_fread (rtc_ricoh.rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
- zfile_fread (rtc_ricoh.rtc_memory, RF5C01A_RAM_SIZE, 1, f);
- zfile_fclose (f);
+ zfile_fread(rtc_ricoh.rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
+ zfile_fread(rtc_ricoh.rtc_memory, RF5C01A_RAM_SIZE, 1, f);
+ zfile_fclose(f);
}
}
}
-static uae_u32 REGPARAM2 clock_lget (uaecptr addr)
+static uae_u32 REGPARAM2 clock_lget(uaecptr addr)
{
if ((addr & 0xffff) >= 0x8000 && currprefs.cs_fatgaryrev >= 0)
return dummy_get(addr, 4, false, 0);
- return (clock_wget (addr) << 16) | clock_wget (addr + 2);
+ return (clock_wget(addr) << 16) | clock_wget(addr + 2);
}
-static uae_u32 REGPARAM2 clock_wget (uaecptr addr)
+static uae_u32 REGPARAM2 clock_wget(uaecptr addr)
{
if ((addr & 0xffff) >= 0x8000 && currprefs.cs_fatgaryrev >= 0)
return dummy_get(addr, 2, false, 0);
- return (clock_bget (addr) << 8) | clock_bget (addr + 1);
+ return (clock_bget(addr) << 8) | clock_bget(addr + 1);
}
-static uae_u32 REGPARAM2 clock_bget (uaecptr addr)
+static uae_u32 REGPARAM2 clock_bget(uaecptr addr)
{
struct tm *ct;
uae_u8 v = 0;
#ifdef CDTV
if (currprefs.cs_cdtvram && (addr & 0xffff) >= 0x8000)
- return cdtv_battram_read (addr);
+ return cdtv_battram_read(addr);
#endif
addr &= 0x3f;
if ((addr & 3) == 2 || (addr & 3) == 0 || currprefs.cs_rtc == 0) {
return dummy_get_safe(addr, 1, false, v);
}
- time_t t = time (0);
+ time_t t = time(0);
t += currprefs.cs_rtc_adjust;
- ct = localtime (&t);
+ ct = localtime(&t);
addr >>= 2;
- return getclockreg (addr, ct);
+ return getclockreg(addr, ct);
}
static void cputester_event(uae_u32 v)
{
- IRQ_forced(4, 64 / 2);
+ IRQ_forced(4, 28 / 2);
}
-static void REGPARAM2 clock_lput (uaecptr addr, uae_u32 value)
+static void REGPARAM2 clock_lput(uaecptr addr, uae_u32 value)
{
if ((addr & 0xffff) >= 0x8000 && currprefs.cs_fatgaryrev >= 0) {
dummy_put(addr, 4, value);
return;
}
- clock_wput (addr, value >> 16);
- clock_wput (addr + 2, value);
+ clock_wput(addr, value >> 16);
+ clock_wput(addr + 2, value);
}
-static void REGPARAM2 clock_wput (uaecptr addr, uae_u32 value)
+static void REGPARAM2 clock_wput(uaecptr addr, uae_u32 value)
{
if ((addr & 0xffff) >= 0x8000 && currprefs.cs_fatgaryrev >= 0) {
dummy_put(addr, 2, value);
return;
}
- clock_bput (addr, value >> 8);
- clock_bput (addr + 1, value);
+ clock_bput(addr, value >> 8);
+ clock_bput(addr + 1, value);
}
-static void REGPARAM2 clock_bput (uaecptr addr, uae_u32 value)
+static void REGPARAM2 clock_bput(uaecptr addr, uae_u32 value)
{
// write_log(_T("W: %x (%x): %x, PC=%08x\n"), addr, (addr & 0xff) >> 2, value & 0xff, M68K_GETPC);
if (currprefs.cputester && (addr & 65535) == 0) {
- event2_newevent_xx(-1, CYCLE_UNIT * (64 / 2), 0, cputester_event);
+ event2_newevent_xx(-1, CYCLE_UNIT * (62 / 2), 0, cputester_event);
}
if ((addr & 0xffff) >= 0x8000 && currprefs.cs_fatgaryrev >= 0) {
#ifdef CDTV
if (currprefs.cs_cdtvram && (addr & 0xffff) >= 0x8000) {
- cdtv_battram_write (addr, value);
+ cdtv_battram_write(addr, value);
return;
}
#endif
value &= 0x0f;
if (currprefs.cs_rtc == 1 || currprefs.cs_rtc == 3) { /* MSM6242B */
#if CLOCK_DEBUG
- write_log (_T("CLOCK W %X: %X\n"), addr, value);
+ write_log(_T("CLOCK W %X: %X\n"), addr, value);
#endif
put_clock_msm(&rtc_msm, addr, value);
} else if (currprefs.cs_rtc == 2) { /* RF5C01A */
/* CIA-A and CIA-B save/restore code */
-static void save_cia_prepare (void)
+static void save_cia_prepare(void)
{
- CIA_update_check ();
- CIA_calctimers ();
- compute_passed_time ();
+ CIA_update_check();
+ CIA_calctimers();
+ compute_passed_time();
}
-void restore_cia_start (void)
+void restore_cia_start(void)
{
/* Fixes very old statefiles without keyboard state */
kbstate = 3;
- setcapslockstate (0);
+ setcapslockstate(0);
kblostsynccnt = 0;
}
-void restore_cia_finish (void)
+void restore_cia_finish(void)
{
- eventtab[ev_cia].oldcycles = get_cycles ();
- CIA_update ();
- CIA_calctimers ();
- compute_passed_time ();
+ eventtab[ev_cia].oldcycles = get_cycles();
+ CIA_update();
+ CIA_calctimers();
+ compute_passed_time();
//dumpcia ();
- DISK_select_set (ciabprb);
+ DISK_select_set(cia[1].prb);
}
-uae_u8 *restore_cia (int num, uae_u8 *src)
+uae_u8 *restore_cia(int num, uae_u8 *src)
{
+ struct CIA *c = &cia[num];
uae_u8 b;
uae_u16 w;
uae_u32 l;
/* CIA registers */
- b = restore_u8 (); /* 0 PRA */
- if (num) ciabpra = b; else ciaapra = b;
- b = restore_u8 (); /* 1 PRB */
- if (num) ciabprb = b; else ciaaprb = b;
- b = restore_u8 (); /* 2 DDRA */
- if (num) ciabdra = b; else ciaadra = b;
- b = restore_u8 (); /* 3 DDRB */
- if (num) ciabdrb = b; else ciaadrb = b;
- w = restore_u16 (); /* 4 TA */
- if (num) ciabta = w; else ciaata = w;
- w = restore_u16 (); /* 6 TB */
- if (num) ciabtb = w; else ciaatb = w;
- l = restore_u8 (); /* 8/9/A TOD */
- l |= restore_u8 () << 8;
- l |= restore_u8 () << 16;
- if (num) ciabtod = l; else ciaatod = l;
- restore_u8 (); /* B unused */
- b = restore_u8 (); /* C SDR */
- if (num) ciabsdr = b; else ciaasdr = b;
- b = restore_u8 (); /* D ICR INFORMATION (not mask!) */
- if (num) ciabicr = b; else ciaaicr = b;
- b = restore_u8 (); /* E CRA */
- if (num) ciabcra = b; else ciaacra = b;
- b = restore_u8 (); /* F CRB */
- if (num) ciabcrb = b; else ciaacrb = b;
+ c->pra = restore_u8(); /* 0 PRA */
+ c->prb = restore_u8(); /* 1 PRB */
+ c->dra = restore_u8(); /* 2 DDRA */
+ c->drb = restore_u8(); /* 3 DDRB */
+ c->t[0].timer = restore_u16(); /* 4 TA */
+ c->t[1].timer = restore_u16(); /* 6 TB */
+ l = restore_u8(); /* 8/9/A TOD */
+ l |= restore_u8() << 8;
+ l |= restore_u8() << 16;
+ c->tod = l;
+ restore_u8(); /* B unused */
+ c->sdr = restore_u8(); /* C SDR */
+ c->icr2 = c->icr1 = restore_u8(); /* D ICR INFORMATION (not mask!) */
+ c->t[0].cr = restore_u8(); /* E CRA */
+ c->t[1].cr = restore_u8(); /* F CRB */
/* CIA internal data */
- b = restore_u8 (); /* ICR MASK */
- if (num) ciabimask = b; else ciaaimask = b;
- w = restore_u8 (); /* timer A latch */
- w |= restore_u8 () << 8;
- if (num) ciabla = w; else ciaala = w;
- w = restore_u8 (); /* timer B latch */
- w |= restore_u8 () << 8;
- if (num) ciablb = w; else ciaalb = w;
- w = restore_u8 (); /* TOD latched value */
- w |= restore_u8 () << 8;
- w |= restore_u8 () << 16;
- if (num) ciabtol = w; else ciaatol = w;
- l = restore_u8 (); /* alarm */
- l |= restore_u8 () << 8;
- l |= restore_u8 () << 16;
- if (num) ciabalarm = l; else ciaaalarm = l;
- b = restore_u8 ();
- if (num) ciabtlatch = b & 1; else ciaatlatch = b & 1; /* is TOD latched? */
- if (num) ciabtodon = b & 2; else ciaatodon = b & 2; /* is TOD stopped? */
- if (num) ciaasdr_load = b & 4; else ciaasdr_load = b & 4; /* SP data pending */
- b = restore_u8 ();
+ c->imask = restore_u8(); /* ICR MASK */
+ w = restore_u8(); /* timer A latch */
+ w |= restore_u8() << 8;
+ c->t[0].latch = w;
+ w = restore_u8(); /* timer B latch */
+ w |= restore_u8() << 8;
+ c->t[1].latch = w;
+ l = restore_u8(); /* TOD latched value */
+ l |= restore_u8() << 8;
+ l |= restore_u8() << 16;
+ c->tol = w;
+ l = restore_u8(); /* alarm */
+ l |= restore_u8() << 8;
+ l |= restore_u8() << 16;
+ c->alarm = l;
+ b = restore_u8();
+ c->tlatch = (b & 1) != 0; /* flags */
+ c->todon = (b & 2) != 0;
+ c->sdr_load = (b & 4) != 0;
+ b = restore_u8();
// if (num)
// div10 = CYCLE_UNIT * b;
- b = restore_u8 ();
- if (num) ciabsdr_cnt = b; else ciaasdr_cnt = b;
- b = restore_u8();
- if (num) ciabsdr_buf = b; else ciaasdr_buf = b;
+ c->sdr_cnt = restore_u8();
+ c->sdr_buf = restore_u8();
+
+ // 4.9.2+
+ c->icr1 = c->icr2;
+ c->t[0].loaddelay = 0;
+ c->t[0].inputpipe = 0;
+ if (c->t[0].cr & CR_START) {
+ c->t[0].inputpipe = CIA_PIPE_ALL_MASK;
+ }
+ c->t[1].loaddelay = 0;
+ c->t[1].inputpipe = 0;
+ if (c->t[1].cr & CR_START) {
+ c->t[1].inputpipe = CIA_PIPE_ALL_MASK;
+ }
+ if (restore_u8() & 1) {
+ c->icr1 = restore_u8();
+ c->t[0].inputpipe = restore_u16();
+ c->t[1].inputpipe = restore_u16();
+ c->t[0].loaddelay = restore_u32();
+ c->t[1].loaddelay = restore_u32();
+
+ }
+
return src;
}
-uae_u8 *save_cia (int num, size_t *len, uae_u8 *dstptr)
+uae_u8 *save_cia(int num, size_t *len, uae_u8 *dstptr)
{
+ struct CIA *c = &cia[num];
uae_u8 *dstbak,*dst, b;
uae_u16 t;
if (dstptr)
dstbak = dst = dstptr;
else
- dstbak = dst = xmalloc (uae_u8, 1000);
+ dstbak = dst = xmalloc(uae_u8, 1000);
- save_cia_prepare ();
+ save_cia_prepare();
/* CIA registers */
- b = num ? ciabpra : ciaapra; /* 0 PRA */
- save_u8 (b);
- b = num ? ciabprb : ciaaprb; /* 1 PRB */
- save_u8 (b);
- b = num ? ciabdra : ciaadra; /* 2 DDRA */
- save_u8 (b);
- b = num ? ciabdrb : ciaadrb; /* 3 DDRB */
- save_u8 (b);
- t = (num ? ciabta - ciabta_passed : ciaata - ciaata_passed);/* 4 TA */
- save_u16 (t);
- t = (num ? ciabtb - ciabtb_passed : ciaatb - ciaatb_passed);/* 6 TB */
- save_u16 (t);
- b = (num ? ciabtod : ciaatod); /* 8 TODL */
- save_u8 (b);
- b = (num ? ciabtod >> 8 : ciaatod >> 8); /* 9 TODM */
- save_u8 (b);
- b = (num ? ciabtod >> 16 : ciaatod >> 16); /* A TODH */
- save_u8 (b);
- save_u8 (0); /* B unused */
- b = num ? ciabsdr : ciaasdr; /* C SDR */
- save_u8 (b);
- b = num ? ciabicr : ciaaicr; /* D ICR INFORMATION (not mask!) */
- save_u8 (b);
- b = num ? ciabcra : ciaacra; /* E CRA */
- save_u8 (b);
- b = num ? ciabcrb : ciaacrb; /* F CRB */
- save_u8 (b);
+ save_u8(c->pra); /* 0 PRA */
+ save_u8(c->prb); /* 1 PRB */
+ save_u8(c->dra); /* 2 DDRA */
+ save_u8(c->drb); /* 3 DDRB */
+ t = c->t[0].timer - c->t[0].passed; /* 4 TA */
+ save_u16(t);
+ t = c->t[1].timer - c->t[1].passed; /* 6 TB */
+ save_u16(t);
+ save_u8((uae_u8)c->tod); /* 8 TODL */
+ save_u8((uae_u8)(c->tod >> 8)); /* 9 TODM */
+ save_u8((uae_u8)(c->tod >> 16)); /* A TODH */
+ save_u8(0); /* B unused */
+ save_u8(c->sdr); /* C SDR */
+ save_u8(c->icr2); /* D ICR INFORMATION (not mask!) */
+ save_u8(c->t[0].cr); /* E CRA */
+ save_u8(c->t[1].cr); /* F CRB */
/* CIA internal data */
- save_u8 (num ? ciabimask : ciaaimask); /* ICR */
- b = (num ? ciabla : ciaala); /* timer A latch LO */
- save_u8 (b);
- b = (num ? ciabla >> 8 : ciaala >> 8); /* timer A latch HI */
- save_u8 (b);
- b = (num ? ciablb : ciaalb); /* timer B latch LO */
- save_u8 (b);
- b = (num ? ciablb >> 8 : ciaalb >> 8); /* timer B latch HI */
- save_u8 (b);
- b = (num ? ciabtol : ciaatol); /* latched TOD LO */
- save_u8 (b);
- b = (num ? ciabtol >> 8 : ciaatol >> 8); /* latched TOD MED */
- save_u8 (b);
- b = (num ? ciabtol >> 16 : ciaatol >> 16); /* latched TOD HI */
- save_u8 (b);
- b = (num ? ciabalarm : ciaaalarm); /* alarm LO */
- save_u8 (b);
- b = (num ? ciabalarm >> 8 : ciaaalarm >> 8);/* alarm MED */
- save_u8 (b);
- b = (num ? ciabalarm >> 16 : ciaaalarm >> 16); /* alarm HI */
- save_u8 (b);
+ save_u8(c->imask); /* ICR */
+ save_u8((uae_u8)c->t[0].latch); /* timer A latch LO */
+ save_u8(c->t[0].latch >> 8); /* timer A latch HI */
+ save_u8((uae_u8)c->t[1].latch); /* timer B latch LO */
+ save_u8(c->t[1].latch >> 8); /* timer B latch HI */
+ save_u8(c->tol); /* latched TOD LO */
+ save_u8(c->tol >> 8); /* latched TOD MED */
+ save_u8(c->tol >> 16); /* latched TOD HI */
+ save_u8(c->alarm); /* alarm LO */
+ save_u8(c->alarm >> 8); /* alarm MED */
+ save_u8(c->alarm >> 16); /* alarm HI */
b = 0;
- if (num)
- b |= ciabtlatch ? 1 : 0;
- else
- b |= ciaatlatch ? 1 : 0; /* is TOD latched? */
- if (num)
- b |= ciabtodon ? 2 : 0;
- else
- b |= ciaatodon ? 2 : 0; /* TOD stopped? */
- if (num)
- b |= ciabsdr_load ? 4 : 0;
- else
- b |= ciaasdr_load ? 2 : 0; /* TOD stopped? */
+ b |= c->tlatch ? 1 : 0; /* is TOD latched? */
+ b |= c->todon ? 2 : 0; /* TOD stopped? */
+ b |= c->sdr_load ? 4 : 0; /* SDR loaded */
save_u8(b);
save_u8(0); // save_u8(num ? div10 / CYCLE_UNIT : 0);
- save_u8(num ? ciabsdr_cnt : ciaasdr_cnt);
- save_u8(num ? ciabsdr_buf : ciaasdr_buf);
+ save_u8(c->sdr_cnt);
+ save_u8(c->sdr_buf);
+
+ // 4.9.2+
+ save_u8(1);
+ save_u8(c->icr1);
+ save_u16(c->t[0].inputpipe);
+ save_u16(c->t[1].inputpipe);
+ save_u32(c->t[0].loaddelay);
+ save_u32(c->t[1].loaddelay);
+
*len = dst - dstbak;
return dstbak;
}
-uae_u8 *save_keyboard (size_t *len, uae_u8 *dstptr)
+uae_u8 *save_keyboard(size_t *len, uae_u8 *dstptr)
{
uae_u8 *dst, *dstbak;
if (dstptr)
dstbak = dst = dstptr;
else
- dstbak = dst = xmalloc (uae_u8, 4 + 4 + 1 + 1 + 1 + 1 + 1 + 2);
- save_u32 (getcapslockstate () ? 1 : 0);
- save_u32 (1);
- save_u8 (kbstate);
- save_u8 (0);
- save_u8 (0);
- save_u8 (0);
- save_u8 (kbcode);
- save_u16 (kblostsynccnt);
+ dstbak = dst = xmalloc(uae_u8, 4 + 4 + 1 + 1 + 1 + 1 + 1 + 2);
+ save_u32(getcapslockstate() ? 1 : 0);
+ save_u32(1);
+ save_u8(kbstate);
+ save_u8(0);
+ save_u8(0);
+ save_u8(0);
+ save_u8(kbcode);
+ save_u16(kblostsynccnt);
*len = dst - dstbak;
return dstbak;
}
-uae_u8 *restore_keyboard (uae_u8 *src)
+uae_u8 *restore_keyboard(uae_u8 *src)
{
- setcapslockstate (restore_u32 () & 1);
- uae_u32 v = restore_u32 ();
- kbstate = restore_u8 ();
- restore_u8 ();
- restore_u8 ();
- restore_u8 ();
- kbcode = restore_u8 ();
- kblostsynccnt = restore_u16 ();
+ setcapslockstate(restore_u32() & 1);
+ uae_u32 v = restore_u32();
+ kbstate = restore_u8();
+ restore_u8();
+ restore_u8();
+ restore_u8();
+ kbcode = restore_u8();
+ kblostsynccnt = restore_u16();
if (!(v & 1)) {
kbstate = 3;
kblostsynccnt = 0;