--- uae/src/cia.c 2018/04/24 17:12:29 1.1.1.17 +++ uae/src/cia.c 2018/04/24 17:18:25 1.1.1.20 @@ -11,7 +11,6 @@ #include "sysdeps.h" #include -#include "config.h" #include "options.h" #include "threaddep/thread.h" #include "events.h" @@ -21,9 +20,11 @@ #include "serial.h" #include "disk.h" #include "xwin.h" +#include "inputdevice.h" #include "keybuf.h" #include "gui.h" #include "savestate.h" +#include "audio.h" #define DIV10 (5*CYCLE_UNIT) /* Yes, a bad identifier. */ @@ -55,6 +56,7 @@ static unsigned long ciaata_passed, ciaa static unsigned long ciaatod, ciabtod, ciaatol, ciabtol, ciaaalarm, ciabalarm; static int ciaatlatch, ciabtlatch; +static int oldled, oldovl; static unsigned int ciabpra; @@ -69,6 +71,7 @@ static int kbstate, kback, ciaasdr_unrea static int prtopen; static FILE *prttmp; +static int warned = 10; static void setclr (unsigned int *p, unsigned int val) { @@ -118,21 +121,21 @@ static void compute_passed_time (void) /* CIA A timers */ if ((ciaacra & 0x21) == 0x01) { - assert ((ciaata+1) >= ciaclocks); + assert ((ciaata + 1) >= ciaclocks); ciaata_passed = ciaclocks; } if ((ciaacrb & 0x61) == 0x01) { - assert ((ciaatb+1) >= ciaclocks); + assert ((ciaatb + 1) >= ciaclocks); ciaatb_passed = ciaclocks; } /* CIA B timers */ if ((ciabcra & 0x21) == 0x01) { - assert ((ciabta+1) >= ciaclocks); + assert ((ciabta + 1) >= ciaclocks); ciabta_passed = ciaclocks; } if ((ciabcrb & 0x61) == 0x01) { - assert ((ciabtb+1) >= ciaclocks); + assert ((ciabtb + 1) >= ciaclocks); ciabtb_passed = ciaclocks; } } @@ -152,54 +155,58 @@ static void CIA_update (void) /* CIA A timers */ if ((ciaacra & 0x21) == 0x01) { - assert ((ciaata+1) >= ciaclocks); - if ((ciaata+1) == ciaclocks) { + assert ((ciaata + 1) >= ciaclocks); + if ((ciaata + 1) == ciaclocks) { aovfla = 1; if ((ciaacrb & 0x61) == 0x41) { - if (ciaatb-- == 0) aovflb = 1; + if (ciaatb-- == 0) + aovflb = 1; } } ciaata -= ciaclocks; } if ((ciaacrb & 0x61) == 0x01) { - assert ((ciaatb+1) >= ciaclocks); - if ((ciaatb+1) == ciaclocks) aovflb = 1; + assert ((ciaatb + 1) >= ciaclocks); + if ((ciaatb + 1) == ciaclocks) + aovflb = 1; ciaatb -= ciaclocks; } /* CIA B timers */ if ((ciabcra & 0x21) == 0x01) { - assert ((ciabta+1) >= ciaclocks); - if ((ciabta+1) == ciaclocks) { + assert ((ciabta + 1) >= ciaclocks); + if ((ciabta + 1) == ciaclocks) { bovfla = 1; if ((ciabcrb & 0x61) == 0x41) { - if (ciabtb-- == 0) bovflb = 1; + if (ciabtb-- == 0) + bovflb = 1; } } ciabta -= ciaclocks; } if ((ciabcrb & 0x61) == 0x01) { - assert ((ciabtb+1) >= ciaclocks); - if ((ciabtb+1) == ciaclocks) bovflb = 1; + assert ((ciabtb + 1) >= ciaclocks); + if ((ciabtb + 1) == ciaclocks) + bovflb = 1; ciabtb -= ciaclocks; } if (aovfla) { - ciaaicr |= 1; RethinkICRA(); + ciaaicr |= 1; RethinkICRA (); ciaata = ciaala; if (ciaacra & 0x8) ciaacra &= ~1; } if (aovflb) { - ciaaicr |= 2; RethinkICRA(); + ciaaicr |= 2; RethinkICRA (); ciaatb = ciaalb; if (ciaacrb & 0x8) ciaacrb &= ~1; } if (bovfla) { - ciabicr |= 1; RethinkICRB(); + ciabicr |= 1; RethinkICRB (); ciabta = ciabla; if (ciabcra & 0x8) ciabcra &= ~1; } if (bovflb) { - ciabicr |= 2; RethinkICRB(); + ciabicr |= 2; RethinkICRB (); ciabtb = ciablb; if (ciabcrb & 0x8) ciabcrb &= ~1; } @@ -275,26 +282,61 @@ void CIA_handler (void) void cia_diskindex (void) { ciabicr |= 0x10; - RethinkICRB(); + RethinkICRB (); +} + +static int checkalarm (unsigned long tod, unsigned long alarm, int inc) +{ + if (tod == alarm) + return 1; + if (!inc) + return 0; + /* emulate buggy TODMED counter. + * it counts: .. 29 2A 2B 2C 2D 2E 2F 20 30 31 32 .. + * (2F->20->30 only takes couple of cycles but it will trigger alarm.. + */ + if (tod & 0x000fff) + return 0; + if (((tod - 1) & 0xfff000) == alarm) + return 1; + return 0; +} + +STATIC_INLINE void ciab_checkalarm (int inc) +{ + if (checkalarm (ciabtod, ciabalarm, inc)) { + ciabicr |= 4; + RethinkICRB (); + } +} + +STATIC_INLINE void ciaa_checkalarm (int inc) +{ + if (checkalarm (ciaatod, ciaaalarm, inc)) { + ciaaicr |= 4; + RethinkICRA (); + } } void CIA_hsync_handler (void) { static unsigned int keytime = 0, sleepyhead = 0; - if (ciabtodon) + if (ciabtodon) { ciabtod++; - ciabtod &= 0xFFFFFF; + ciabtod &= 0xFFFFFF; + ciab_checkalarm (1); + } if (ciabtod == ciabalarm) { - ciabicr |= 4; RethinkICRB(); + ciabicr |= 4; RethinkICRB (); } /* check wether the serial port gets some data */ if (doreadser) doreadser = SERDATS(); - if (keys_available() && kback && (++keytime & 15) == 0) { + if (keys_available() && kback && (ciaacra & 0x40) == 0 && (++keytime & 15) == 0) { /* * This hack lets one possible ciaaicr cycle go by without any key * being read, for every cycle in which a key is pulled out of the @@ -325,7 +367,7 @@ void CIA_hsync_handler (void) break; } ciaaicr |= 8; - RethinkICRA(); + RethinkICRA (); sleepyhead = 0; } else if (!(++sleepyhead & 15)) { ciaasdr_unread = 0; /* give up on this key event after unread for a long time */ @@ -335,11 +377,10 @@ void CIA_hsync_handler (void) void CIA_vsync_handler () { - if (ciaatodon) + if (ciaatodon) { ciaatod++; - ciaatod &= 0xFFFFFF; - if (ciaatod == ciaaalarm) { - ciaaicr |= 4; RethinkICRA(); + ciaatod &= 0xFFFFFF; + ciaa_checkalarm (1); } doreadser = 1; @@ -347,23 +388,51 @@ void CIA_vsync_handler () serial_flush_buffer(); } +static void bfe001_change (void) +{ + uae_u8 v = ciaapra; + + v |= ~ciaadra; /* output is high when pin's direction is input */ + if ((v & 2) != oldled) { + int led = (v & 2) ? 0 : 1; + oldled = v & 2; + gui_ledstate &= ~1; + gui_ledstate |= led; + gui_data.powerled = led; + gui_led (0, led); + led_filter_audio (); + } + if ((v & 1) != oldovl) { + int i = (allocated_chipmem>>16) > 32 ? allocated_chipmem >> 16 : 32; + oldovl = v & 1; + + if (!oldovl || ersatzkickfile) { + map_overlay (1); + } else if (!(currprefs.chipset_mask & CSMASK_AGA)) { + /* pin disconnected in AGA chipset, CD audio mute on/off on CD32 */ + map_overlay (0); + } + } +} + static uae_u8 ReadCIAA (unsigned int addr) { unsigned int tmp; compute_passed_time (); - + switch (addr & 0xf) { case 0: if (currprefs.use_serial && (serstat < 0)) /* Only read status when needed */ serstat=serial_readstatus(); /* and only once per frame */ tmp = (DISK_status() & 0x3C); - if ((JSEM_ISMOUSE (0, &currprefs) && !buttonstate[0]) - || (!JSEM_ISMOUSE (0, &currprefs) && !(joy0button & 1))) - tmp |= 0x40; - if (!(joy1button & 1)) - tmp |= 0x80; + tmp |= handle_joystick_buttons (ciaadra); + tmp |= (ciaapra | (ciaadra ^ 3)) & 0x03; + if (ciaadra & 0x40) + tmp = (tmp & ~0x40) | (ciaapra & 0x40); + if (ciaadra & 0x80) + tmp = (tmp & ~0x80) | (ciaapra & 0x80); return tmp; case 1: /* Returning 0xFF is necessary for Tie Break - otherwise its joystick @@ -397,10 +466,11 @@ static uae_u8 ReadCIAA (unsigned int add ciaatol = ciaatod; /* ??? only if not already latched? */ return (ciaatol >> 16) & 0xff; case 12: - if (ciaasdr == 1) ciaasdr_unread = 2; + if (ciaasdr_unread == 1) + ciaasdr_unread = 2; return ciaasdr; case 13: - tmp = ciaaicr; ciaaicr = 0; RethinkICRA(); + tmp = ciaaicr; ciaaicr = 0; RethinkICRA (); return tmp; case 14: return ciaacra; @@ -455,7 +525,7 @@ static uae_u8 ReadCIAB (unsigned int add case 12: return ciabsdr; case 13: - tmp = ciabicr; ciabicr = 0; RethinkICRB(); + tmp = ciabicr; ciabicr = 0; RethinkICRB (); return tmp; case 14: return ciabcra; @@ -465,30 +535,13 @@ static uae_u8 ReadCIAB (unsigned int add return 0; } -static void WriteCIAA (uae_u16 addr,uae_u8 val) +static void WriteCIAA (uae_u16 addr, uae_u8 val) { int oldled, oldovl; switch (addr & 0xf) { case 0: - oldovl = ciaapra & 1; - oldled = ciaapra & 2; - ciaapra = (ciaapra & ~0x3) | (val & 0x3); - LED(ciaapra & 0x2); - gui_ledstate &= ~1; - gui_ledstate |= ((~ciaapra & 2) >> 1); - gui_data.powerled = ((~ciaapra & 2) >> 1); - if ((ciaapra & 2) != oldled) - gui_led (0, !(ciaapra & 2)); - if ((ciaapra & 1) != oldovl) { - int i = (allocated_chipmem>>16) > 32 ? allocated_chipmem >> 16 : 32; - - if (oldovl || ersatzkickfile) { - map_banks (&chipmem_bank, 0, i, allocated_chipmem); - } else { - /* Is it OK to do this for more than 2M of chip? */ - map_banks (&kickmem_bank, 0, i, 0x80000); - } - } + ciaapra = (ciaapra & ~0x3) | (val & 0x3); + bfe001_change (); break; case 1: ciaaprb = val; @@ -527,6 +580,7 @@ static void WriteCIAA (uae_u16 addr,uae_ break; case 2: ciaadra = val; + bfe001_change (); break; case 3: ciaadrb = val; @@ -616,16 +670,16 @@ static void WriteCIAA (uae_u16 addr,uae_ } } -static void WriteCIAB (uae_u16 addr,uae_u8 val) +static void WriteCIAB (uae_u16 addr, uae_u8 val) { int oldval; switch (addr & 0xf) { case 0: if (currprefs.use_serial) { oldval = ciabpra; - ciabpra = serial_writestatus(oldval,val); + ciabpra = serial_writestatus (oldval, val); } else - ciabpra = val; + ciabpra = val; break; case 1: ciabprb = val; DISK_select(val); break; @@ -720,6 +774,8 @@ void CIA_reset (void) { kback = 1; kbstate = 0; + oldovl = -1; + oldled = -1; if (!savestate_state) { ciaatlatch = ciabtlatch = 0; @@ -737,15 +793,11 @@ void CIA_reset (void) map_banks (&kickmem_bank, 0, i, 0x80000); } - if (currprefs.use_serial && !savestate_state) + if (currprefs.use_serial && !savestate_state) serial_dtr_off (); /* Drop DTR at reset */ if (savestate_state) { - /* Reset oldovl and oldled */ - uae_u8 v = ReadCIAA (0); - WriteCIAA (0,3); - WriteCIAA (0,0); - WriteCIAA (0,v); + bfe001_change (); /* select drives */ DISK_select (ciabprb); } @@ -773,7 +825,7 @@ static void cia_bput (uaecptr, uae_u32) addrbank cia_bank = { cia_lget, cia_wget, cia_bget, cia_lput, cia_wput, cia_bput, - default_xlate, default_check, NULL + default_xlate, default_check, NULL, "CIA" }; static void cia_wait (void) @@ -787,41 +839,59 @@ static void cia_wait (void) uae_u32 REGPARAM2 cia_bget (uaecptr addr) { int r = (addr & 0xf00) >> 8; - special_mem |= S_READ; + uae_u8 v; + cia_wait (); + v = 0xff; switch ((addr >> 12) & 3) { case 0: - return (addr & 1) ? ReadCIAA (r) : ReadCIAB (r); + v = (addr & 1) ? ReadCIAA (r) : ReadCIAB (r); + break; case 1: - return (addr & 1) ? 0xff : ReadCIAB (r); + v = (addr & 1) ? 0xff : ReadCIAB (r); + break; case 2: - return (addr & 1) ? ReadCIAA (r) : 0xff; + v = (addr & 1) ? ReadCIAA (r) : 0xff; + break; +#if 0 + case 3: + if (currprefs.cpu_level == 0 && currprefs.cpu_compatible) + v = (addr & 1) ? regs.irc : regs.irc >> 8; + if (warned > 0) { + write_log ("cia_bget: unknown CIA address %x PC=%x\n", addr, m68k_getpc ()); + warned--; + } + break; +#endif } - return 0xff; + return v; } uae_u32 REGPARAM2 cia_wget (uaecptr addr) { int r = (addr & 0xf00) >> 8; - special_mem |= S_READ; + uae_u16 v; cia_wait (); + v = 0xffff; switch ((addr >> 12) & 3) { case 0: - return (ReadCIAB (r) << 8) | ReadCIAA (r); + v = (ReadCIAB (r) << 8) | ReadCIAA (r); + break; case 1: - return (ReadCIAB (r) << 8) | 0xff; + v = (ReadCIAB (r) << 8) | 0xff; + break; case 2: - return (0xff << 8) | ReadCIAA (r); + v = (0xff << 8) | ReadCIAA (r); + break; } - return 0xffff; + return v; } uae_u32 REGPARAM2 cia_lget (uaecptr addr) { uae_u32 v; - special_mem |= S_READ; v = cia_wget (addr) << 16; v |= cia_wget (addr + 2); return v; @@ -830,7 +900,6 @@ uae_u32 REGPARAM2 cia_lget (uaecptr addr void REGPARAM2 cia_bput (uaecptr addr, uae_u32 value) { int r = (addr & 0xf00) >> 8; - special_mem |= S_WRITE; cia_wait (); if ((addr & 0x2000) == 0) WriteCIAB (r, value); @@ -841,7 +910,6 @@ void REGPARAM2 cia_bput (uaecptr addr, u void REGPARAM2 cia_wput (uaecptr addr, uae_u32 value) { int r = (addr & 0xf00) >> 8; - special_mem |= S_WRITE; cia_wait (); if ((addr & 0x2000) == 0) WriteCIAB (r, value >> 8); @@ -851,7 +919,6 @@ void REGPARAM2 cia_wput (uaecptr addr, u void REGPARAM2 cia_lput (uaecptr addr, uae_u32 value) { - special_mem |= S_WRITE; cia_wput (addr, value >> 16); cia_wput (addr + 2, value & 0xffff); } @@ -868,18 +935,16 @@ static void clock_bput (uaecptr, uae_u32 addrbank clock_bank = { clock_lget, clock_wget, clock_bget, clock_lput, clock_wput, clock_bput, - default_xlate, default_check, NULL + default_xlate, default_check, NULL, "Battery backed up clock" }; uae_u32 REGPARAM2 clock_lget (uaecptr addr) { - special_mem |= S_READ; return clock_bget (addr + 3); } uae_u32 REGPARAM2 clock_wget (uaecptr addr) { - special_mem |= S_READ; return clock_bget (addr + 1); } @@ -889,7 +954,6 @@ uae_u32 REGPARAM2 clock_bget (uaecptr ad struct tm *ct; ct = localtime (&t); - special_mem |= S_READ; switch (addr & 0x3f) { case 0x03: return ct->tm_sec % 10; @@ -915,19 +979,16 @@ uae_u32 REGPARAM2 clock_bget (uaecptr ad void REGPARAM2 clock_lput (uaecptr addr, uae_u32 value) { - special_mem |= S_WRITE; /* No way */ } void REGPARAM2 clock_wput (uaecptr addr, uae_u32 value) { - special_mem |= S_WRITE; /* No way */ } void REGPARAM2 clock_bput (uaecptr addr, uae_u32 value) { - special_mem |= S_WRITE; switch (addr & 0x3f) { case 0x37: clock_control_d = value; break; case 0x3b: clock_control_e = value; break; @@ -937,7 +998,7 @@ void REGPARAM2 clock_bput (uaecptr addr, /* CIA-A and CIA-B save/restore code */ -uae_u8 *restore_cia (int num, uae_u8 *src) +const uae_u8 *restore_cia (int num, const uae_u8 *src) { uae_u8 b; uae_u16 w; @@ -997,12 +1058,15 @@ uae_u8 *restore_cia (int num, uae_u8 *sr return src; } -uae_u8 *save_cia (int num, int *len) +uae_u8 *save_cia (int num, int *len, uae_u8 *dstptr) { uae_u8 *dstbak,*dst, b; uae_u16 t; - dstbak = dst = malloc (16 + 12 + 1); + if (dstptr) + dstbak = dst = dstptr; + else + dstbak = dst = malloc (16 + 12 + 1); compute_passed_time (); @@ -1013,7 +1077,7 @@ uae_u8 *save_cia (int num, int *len) b = num ? ciabprb : ciaaprb; /* 1 PRB */ save_u8 (b); b = num ? ciabdra : ciaadra; /* 2 DDRA */ - save_u8 (b); + save_u8 (b); b = num ? ciabdrb : ciaadrb; /* 3 DDRB */ save_u8 (b); t = (num ? ciabta - ciabta_passed : ciaata - ciaata_passed);/* 4 TA */ @@ -1055,7 +1119,7 @@ uae_u8 *save_cia (int num, int *len) save_u8 (b); b = (num ? ciabalarm : ciaaalarm); /* alarm LO */ save_u8 (b); - b = (num ? ciabalarm >> 8 : ciaaalarm >>8 ); /* alarm MED */ + b = (num ? ciabalarm >> 8 : ciaaalarm >> 8); /* alarm MED */ save_u8 (b); b = (num ? ciabalarm >> 16 : ciaaalarm >> 16); /* alarm HI */ save_u8 (b);