Annotation of uae/src/cia.c, revision 1.1.1.21

1.1.1.3   root        1:  /*
1.1       root        2:   * UAE - The Un*x Amiga Emulator
1.1.1.3   root        3:   *
1.1       root        4:   * CIA chip support
                      5:   *
                      6:   * Copyright 1995 Bernd Schmidt, Alessandro Bissacco
1.1.1.3   root        7:   * Copyright 1996, 1997 Stefan Reinauer, Christian Schmitt
1.1       root        8:   */
                      9: 
                     10: #include "sysconfig.h"
                     11: #include "sysdeps.h"
                     12: #include <assert.h>
                     13: 
                     14: #include "options.h"
1.1.1.12  root       15: #include "threaddep/thread.h"
1.1       root       16: #include "events.h"
                     17: #include "memory.h"
                     18: #include "custom.h"
                     19: #include "cia.h"
1.1.1.3   root       20: #include "serial.h"
1.1       root       21: #include "disk.h"
                     22: #include "xwin.h"
1.1.1.18  root       23: #include "inputdevice.h"
1.1       root       24: #include "keybuf.h"
                     25: #include "gui.h"
1.1.1.11  root       26: #include "savestate.h"
1.1.1.20  root       27: #include "audio.h"
1.1       root       28: 
1.1.1.10  root       29: #define DIV10 (5*CYCLE_UNIT) /* Yes, a bad identifier. */
1.1       root       30: 
                     31: /* battclock stuff */
                     32: #define RTC_D_ADJ      8
                     33: #define RTC_D_IRQ      4
                     34: #define RTC_D_BUSY     2
                     35: #define RTC_D_HOLD     1
                     36: #define RTC_E_t1       8
                     37: #define RTC_E_t0       4
                     38: #define RTC_E_INTR     2
                     39: #define RTC_E_MASK     1
                     40: #define RTC_F_TEST     8
                     41: #define RTC_F_24_12    4
                     42: #define RTC_F_STOP     2
                     43: #define RTC_F_RSET     1
                     44: 
1.1.1.3   root       45: static unsigned int clock_control_d = RTC_D_ADJ + RTC_D_HOLD;
                     46: static unsigned int clock_control_e = 0;
                     47: static unsigned int clock_control_f = RTC_F_24_12;
                     48: 
1.1.1.16  root       49: static unsigned int ciaaicr, ciaaimask, ciabicr, ciabimask;
                     50: static unsigned int ciaacra, ciaacrb, ciabcra, ciabcrb;
1.1.1.10  root       51: 
                     52: /* Values of the CIA timers.  */
1.1.1.16  root       53: static unsigned long ciaata, ciaatb, ciabta, ciabtb;
1.1.1.10  root       54: /* Computed by compute_passed_time.  */
1.1.1.16  root       55: static unsigned long ciaata_passed, ciaatb_passed, ciabta_passed, ciabtb_passed;
1.1.1.10  root       56: 
1.1.1.16  root       57: static unsigned long ciaatod, ciabtod, ciaatol, ciabtol, ciaaalarm, ciabalarm;
                     58: static int ciaatlatch, ciabtlatch;
1.1.1.20  root       59: static int oldled, oldovl;
1.1.1.3   root       60: 
1.1.1.16  root       61: static unsigned int ciabpra;
1.1.1.3   root       62: 
                     63: unsigned int gui_ledstate;
                     64: 
1.1.1.11  root       65: static unsigned long ciaala, ciaalb, ciabla, ciablb;
1.1.1.3   root       66: static int ciaatodon, ciabtodon;
1.1.1.11  root       67: static unsigned int ciaapra, ciaaprb, ciaadra, ciaadrb, ciaasdr;
                     68: static unsigned int ciabprb, ciabdra, ciabdrb, ciabsdr;
1.1       root       69: static int div10;
1.1.1.2   root       70: static int kbstate, kback, ciaasdr_unread = 0;
1.1       root       71: 
                     72: static int prtopen;
                     73: static FILE *prttmp;
1.1.1.18  root       74: static int warned = 10;
1.1       root       75: 
1.1.1.10  root       76: static void setclr (unsigned int *p, unsigned int val)
1.1       root       77: {
                     78:     if (val & 0x80) {
                     79:        *p |= val & 0x7F;
                     80:     } else {
                     81:        *p &= ~val;
                     82:     }
                     83: }
                     84: 
1.1.1.10  root       85: static void RethinkICRA (void)
1.1       root       86: {
                     87:     if (ciaaimask & ciaaicr) {
                     88:        ciaaicr |= 0x80;
1.1.1.17  root       89:        INTREQ_0 (0x8000 | 0x0008);
1.1       root       90:     } else {
                     91:        ciaaicr &= 0x7F;
                     92: /*     custom_bank.wput(0xDFF09C,0x0008);*/
                     93:     }
                     94: }
                     95: 
1.1.1.10  root       96: static void RethinkICRB (void)
1.1       root       97: {
                     98:     if (ciabimask & ciabicr) {
                     99:        ciabicr |= 0x80;
1.1.1.17  root      100:        INTREQ_0 (0x8000 | 0x2000);
1.1       root      101:     } else {
                    102:        ciabicr &= 0x7F;
                    103:     }
                    104: }
                    105: 
1.1.1.11  root      106: void rethink_cias (void)
                    107: {
                    108:     RethinkICRA ();
                    109:     RethinkICRB ();
                    110: }
                    111: 
1.1.1.10  root      112: /* Figure out how many CIA timer cycles have passed for each timer since the
                    113:    last call of CIA_calctimers.  */
1.1       root      114: 
1.1.1.10  root      115: static void compute_passed_time (void)
1.1       root      116: {
1.1.1.10  root      117:     unsigned long int ccount = (get_cycles () - eventtab[ev_cia].oldcycles + div10);
                    118:     unsigned long int ciaclocks = ccount / DIV10;
                    119: 
                    120:     ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0;
                    121: 
                    122:     /* CIA A timers */
                    123:     if ((ciaacra & 0x21) == 0x01) {
1.1.1.20  root      124:        assert ((ciaata + 1) >= ciaclocks);
1.1.1.10  root      125:        ciaata_passed = ciaclocks;
                    126:     }
                    127:     if ((ciaacrb & 0x61) == 0x01) {
1.1.1.20  root      128:        assert ((ciaatb + 1) >= ciaclocks);
1.1.1.10  root      129:        ciaatb_passed = ciaclocks;
                    130:     }
                    131: 
                    132:     /* CIA B timers */
                    133:     if ((ciabcra & 0x21) == 0x01) {
1.1.1.20  root      134:        assert ((ciabta + 1) >= ciaclocks);
1.1.1.10  root      135:        ciabta_passed = ciaclocks;
                    136:     }
                    137:     if ((ciabcrb & 0x61) == 0x01) {
1.1.1.20  root      138:        assert ((ciabtb + 1) >= ciaclocks);
1.1.1.10  root      139:        ciabtb_passed = ciaclocks;
                    140:     }
                    141: }
                    142: 
                    143: /* Called to advance all CIA timers to the current time.  This expects that
                    144:    one of the timer values will be modified, and CIA_calctimers will be called
                    145:    in the same cycle.  */
                    146: 
                    147: static void CIA_update (void)
                    148: {
                    149:     unsigned long int ccount = (get_cycles () - eventtab[ev_cia].oldcycles + div10);
1.1       root      150:     unsigned long int ciaclocks = ccount / DIV10;
                    151: 
                    152:     int aovfla = 0, aovflb = 0, bovfla = 0, bovflb = 0;
                    153: 
                    154:     div10 = ccount % DIV10;
1.1.1.3   root      155: 
1.1       root      156:     /* CIA A timers */
                    157:     if ((ciaacra & 0x21) == 0x01) {
1.1.1.20  root      158:        assert ((ciaata + 1) >= ciaclocks);
                    159:        if ((ciaata + 1) == ciaclocks) {
1.1       root      160:            aovfla = 1;
                    161:            if ((ciaacrb & 0x61) == 0x41) {
1.1.1.18  root      162:                if (ciaatb-- == 0)
                    163:                    aovflb = 1;
1.1       root      164:            }
1.1.1.3   root      165:        }
1.1       root      166:        ciaata -= ciaclocks;
                    167:     }
                    168:     if ((ciaacrb & 0x61) == 0x01) {
1.1.1.20  root      169:        assert ((ciaatb + 1) >= ciaclocks);
                    170:        if ((ciaatb + 1) == ciaclocks)
1.1.1.18  root      171:            aovflb = 1;
1.1       root      172:        ciaatb -= ciaclocks;
                    173:     }
1.1.1.3   root      174: 
1.1       root      175:     /* CIA B timers */
                    176:     if ((ciabcra & 0x21) == 0x01) {
1.1.1.20  root      177:        assert ((ciabta + 1) >= ciaclocks);
                    178:        if ((ciabta + 1) == ciaclocks) {
1.1       root      179:            bovfla = 1;
                    180:            if ((ciabcrb & 0x61) == 0x41) {
1.1.1.18  root      181:                if (ciabtb-- == 0)
                    182:                    bovflb = 1;
1.1       root      183:            }
1.1.1.3   root      184:        }
1.1       root      185:        ciabta -= ciaclocks;
                    186:     }
                    187:     if ((ciabcrb & 0x61) == 0x01) {
1.1.1.20  root      188:        assert ((ciabtb + 1) >= ciaclocks);
                    189:        if ((ciabtb + 1) == ciaclocks)
1.1.1.18  root      190:            bovflb = 1;
1.1       root      191:        ciabtb -= ciaclocks;
                    192:     }
                    193:     if (aovfla) {
1.1.1.20  root      194:        ciaaicr |= 1; RethinkICRA ();
1.1       root      195:        ciaata = ciaala;
                    196:        if (ciaacra & 0x8) ciaacra &= ~1;
                    197:     }
                    198:     if (aovflb) {
1.1.1.20  root      199:        ciaaicr |= 2; RethinkICRA ();
1.1       root      200:        ciaatb = ciaalb;
                    201:        if (ciaacrb & 0x8) ciaacrb &= ~1;
                    202:     }
                    203:     if (bovfla) {
1.1.1.20  root      204:        ciabicr |= 1; RethinkICRB ();
1.1       root      205:        ciabta = ciabla;
                    206:        if (ciabcra & 0x8) ciabcra &= ~1;
                    207:     }
                    208:     if (bovflb) {
1.1.1.20  root      209:        ciabicr |= 2; RethinkICRB ();
1.1       root      210:        ciabtb = ciablb;
                    211:        if (ciabcrb & 0x8) ciabcrb &= ~1;
                    212:     }
                    213: }
                    214: 
1.1.1.10  root      215: /* Call this only after CIA_update has been called in the same cycle.  */
                    216: 
                    217: static void CIA_calctimers (void)
1.1       root      218: {
1.1.1.21! root      219:     unsigned long ciaatimea = ~0UL, ciaatimeb = ~0UL, ciabtimea = ~0UL, ciabtimeb = ~0UL;
1.1       root      220: 
1.1.1.10  root      221:     eventtab[ev_cia].oldcycles = get_cycles ();
1.1       root      222:     if ((ciaacra & 0x21) == 0x01) {
1.1.1.10  root      223:        ciaatimea = (DIV10 - div10) + DIV10 * ciaata;
1.1       root      224:     }
                    225:     if ((ciaacrb & 0x61) == 0x41) {
                    226:        /* Timer B will not get any pulses if Timer A is off. */
1.1.1.21! root      227:        if (ciaatimea != ~0UL) {
1.1       root      228:            /* If Timer A is in one-shot mode, and Timer B needs more than
                    229:             * one pulse, it will not underflow. */
                    230:            if (ciaatb == 0 || (ciaacra & 0x8) == 0) {
                    231:                /* Otherwise, we can determine the time of the underflow. */
1.1.1.15  root      232:                /* This may overflow, however.  So just ignore this timer and
                    233:                   use the fact that we'll call CIA_handler for the A timer.  */
                    234: #if 0
1.1       root      235:                ciaatimeb = ciaatimea + ciaala * DIV10 * ciaatb;
1.1.1.15  root      236: #endif
1.1       root      237:            }
                    238:        }
                    239:     }
                    240:     if ((ciaacrb & 0x61) == 0x01) {
1.1.1.10  root      241:        ciaatimeb = (DIV10 - div10) + DIV10 * ciaatb;
1.1       root      242:     }
                    243: 
                    244:     if ((ciabcra & 0x21) == 0x01) {
1.1.1.10  root      245:        ciabtimea = (DIV10 - div10) + DIV10 * ciabta;
1.1       root      246:     }
                    247:     if ((ciabcrb & 0x61) == 0x41) {
                    248:        /* Timer B will not get any pulses if Timer A is off. */
1.1.1.21! root      249:        if (ciabtimea != ~0UL) {
1.1       root      250:            /* If Timer A is in one-shot mode, and Timer B needs more than
                    251:             * one pulse, it will not underflow. */
                    252:            if (ciabtb == 0 || (ciabcra & 0x8) == 0) {
                    253:                /* Otherwise, we can determine the time of the underflow. */
1.1.1.15  root      254: #if 0
1.1       root      255:                ciabtimeb = ciabtimea + ciabla * DIV10 * ciabtb;
1.1.1.15  root      256: #endif
1.1       root      257:            }
                    258:        }
                    259:     }
                    260:     if ((ciabcrb & 0x61) == 0x01) {
1.1.1.10  root      261:        ciabtimeb = (DIV10 - div10) + DIV10 * ciabtb;
1.1       root      262:     }
1.1.1.21! root      263:     eventtab[ev_cia].active = (ciaatimea != ~0UL || ciaatimeb != ~0UL
        !           264:                               || ciabtimea != ~0UL || ciabtimeb != ~0UL);
1.1       root      265:     if (eventtab[ev_cia].active) {
1.1.1.21! root      266:        unsigned long int ciatime = ~0UL;
        !           267:        if (ciaatimea != ~0UL) ciatime = ciaatimea;
        !           268:        if (ciaatimeb != ~0UL && ciaatimeb < ciatime) ciatime = ciaatimeb;
        !           269:        if (ciabtimea != ~0UL && ciabtimea < ciatime) ciatime = ciabtimea;
        !           270:        if (ciabtimeb != ~0UL && ciabtimeb < ciatime) ciatime = ciabtimeb;
1.1.1.10  root      271:        eventtab[ev_cia].evtime = ciatime + get_cycles ();
1.1       root      272:     }
                    273:     events_schedule();
                    274: }
                    275: 
1.1.1.10  root      276: void CIA_handler (void)
1.1       root      277: {
1.1.1.10  root      278:     CIA_update ();
                    279:     CIA_calctimers ();
1.1       root      280: }
                    281: 
1.1.1.10  root      282: void cia_diskindex (void)
1.1       root      283: {
                    284:     ciabicr |= 0x10;
1.1.1.20  root      285:     RethinkICRB ();
                    286: }
                    287: 
                    288: static int checkalarm (unsigned long tod, unsigned long alarm, int inc)
                    289: {
                    290:     if (tod == alarm)
                    291:        return 1;
                    292:     if (!inc)
                    293:        return 0;
                    294:     /* emulate buggy TODMED counter.
                    295:      * it counts: .. 29 2A 2B 2C 2D 2E 2F 20 30 31 32 ..
                    296:      * (2F->20->30 only takes couple of cycles but it will trigger alarm..
                    297:      */
                    298:     if (tod & 0x000fff)
                    299:        return 0;
                    300:     if (((tod - 1) & 0xfff000) == alarm)
                    301:        return 1;
                    302:     return 0;
                    303: }
                    304: 
                    305: STATIC_INLINE void ciab_checkalarm (int inc)
                    306: {
                    307:     if (checkalarm (ciabtod, ciabalarm, inc)) {
                    308:        ciabicr |= 4;
                    309:        RethinkICRB ();
                    310:     }
                    311: }
                    312: 
                    313: STATIC_INLINE void ciaa_checkalarm (int inc)
                    314: {
                    315:     if (checkalarm (ciaatod, ciaaalarm, inc)) {
                    316:        ciaaicr |= 4;
                    317:        RethinkICRA ();
                    318:     }
1.1       root      319: }
                    320: 
1.1.1.10  root      321: void CIA_hsync_handler (void)
1.1       root      322: {
1.1.1.3   root      323:     static unsigned int keytime = 0, sleepyhead = 0;
1.1       root      324: 
1.1.1.20  root      325:     if (ciabtodon) {
1.1       root      326:        ciabtod++;
1.1.1.20  root      327:        ciabtod &= 0xFFFFFF;
                    328:        ciab_checkalarm (1);
                    329:     }
1.1       root      330: 
                    331:     if (ciabtod == ciabalarm) {
1.1.1.20  root      332:        ciabicr |= 4; RethinkICRB ();
1.1       root      333:     }
1.1.1.3   root      334: 
                    335:     /* check wether the serial port gets some data */
                    336:     if (doreadser)
                    337:        doreadser = SERDATS();
                    338: 
1.1.1.18  root      339:     if (keys_available() && kback && (ciaacra & 0x40) == 0 && (++keytime & 15) == 0) {
1.1.1.3   root      340:        /*
1.1.1.2   root      341:         * This hack lets one possible ciaaicr cycle go by without any key
                    342:         * being read, for every cycle in which a key is pulled out of the
                    343:         * queue.  If no hack is used, a lot of key events just get lost
                    344:         * when you type fast.  With a simple hack that waits for ciaasdr
                    345:         * to be read before feeding it another, it will keep up until the
                    346:         * queue gets about 14 characters ahead and then lose events, and
                    347:         * the mouse pointer will freeze while typing is being taken in.
                    348:         * With this hack, you can type 30 or 40 characters ahead with little
                    349:         * or no lossage, and the mouse doesn't get stuck.  The tradeoff is
                    350:         * that the total slowness of typing appearing on screen is worse.
                    351:         */
1.1.1.17  root      352:        if (ciaasdr_unread == 2) {
1.1.1.3   root      353:            ciaasdr_unread = 0;
1.1.1.17  root      354:        } else if (ciaasdr_unread == 0) {
1.1.1.3   root      355:            switch (kbstate) {
1.1.1.2   root      356:             case 0:
1.1.1.3   root      357:                ciaasdr = (uae_s8)~0xFB; /* aaarghh... stupid compiler */
                    358:                kbstate++;
                    359:                break;
1.1.1.2   root      360:             case 1:
1.1.1.3   root      361:                kbstate++;
                    362:                ciaasdr = (uae_s8)~0xFD;
                    363:                break;
1.1.1.2   root      364:             case 2:
1.1.1.3   root      365:                ciaasdr = ~get_next_key();
                    366:                ciaasdr_unread = 1;      /* interlock to prevent lost keystrokes */
                    367:                break;
1.1.1.2   root      368:            }
                    369:            ciaaicr |= 8;
1.1.1.20  root      370:            RethinkICRA ();
1.1.1.2   root      371:            sleepyhead = 0;
1.1.1.17  root      372:        } else if (!(++sleepyhead & 15)) {
1.1.1.3   root      373:            ciaasdr_unread = 0;          /* give up on this key event after unread for a long time */
1.1.1.17  root      374:        }
1.1       root      375:     }
                    376: }
                    377: 
1.1.1.10  root      378: void CIA_vsync_handler ()
1.1.1.3   root      379: {
1.1.1.20  root      380:     if (ciaatodon) {
1.1       root      381:        ciaatod++;
1.1.1.20  root      382:        ciaatod &= 0xFFFFFF;
                    383:        ciaa_checkalarm (1);
1.1       root      384:     }
1.1.1.3   root      385: 
                    386:     doreadser = 1;
                    387:     serstat = -1;
                    388:     serial_flush_buffer();
1.1       root      389: }
                    390: 
1.1.1.20  root      391: static void bfe001_change (void)
                    392: {
                    393:     uae_u8 v = ciaapra;
                    394: 
                    395:     v |= ~ciaadra; /* output is high when pin's direction is input */
                    396:     if ((v & 2) != oldled) {
                    397:        int led = (v & 2) ? 0 : 1;
                    398:        oldled = v & 2;
                    399:        gui_ledstate &= ~1;
                    400:        gui_ledstate |= led;
                    401:        gui_data.powerled = led;
                    402:        gui_led (0, led);
                    403:        led_filter_audio ();
                    404:     }
                    405:     if ((v & 1) != oldovl) {
                    406:        int i = (allocated_chipmem>>16) > 32 ? allocated_chipmem >> 16 : 32;
                    407:        oldovl = v & 1;
                    408: 
                    409:        if (!oldovl || ersatzkickfile) {
                    410:            map_overlay (1);
                    411:        } else if (!(currprefs.chipset_mask & CSMASK_AGA)) {
                    412:            /* pin disconnected in AGA chipset, CD audio mute on/off on CD32 */
                    413:            map_overlay (0);
                    414:        }
                    415:     }
                    416: }
                    417: 
1.1.1.10  root      418: static uae_u8 ReadCIAA (unsigned int addr)
1.1       root      419: {
1.1.1.3   root      420:     unsigned int tmp;
                    421: 
1.1.1.10  root      422:     compute_passed_time ();
1.1.1.18  root      423: 
1.1.1.10  root      424:     switch (addr & 0xf) {
1.1.1.7   root      425:     case 0:
1.1.1.3   root      426:        if (currprefs.use_serial && (serstat < 0)) /* Only read status when needed */
                    427:            serstat=serial_readstatus();                /* and only once per frame */
                    428: 
1.1       root      429:        tmp = (DISK_status() & 0x3C);
1.1.1.18  root      430:        tmp |= handle_joystick_buttons (ciaadra);
                    431:        tmp |= (ciaapra | (ciaadra ^ 3)) & 0x03;
                    432:        if (ciaadra & 0x40)
                    433:            tmp = (tmp & ~0x40) | (ciaapra & 0x40);
                    434:        if (ciaadra & 0x80)
                    435:            tmp = (tmp & ~0x80) | (ciaapra & 0x80);
1.1       root      436:        return tmp;
1.1.1.7   root      437:     case 1:
                    438:        /* Returning 0xFF is necessary for Tie Break - otherwise its joystick
                    439:           code won't work.  */
                    440:        return prtopen ? ciaaprb : 0xFF;
                    441:     case 2:
1.1       root      442:        return ciaadra;
1.1.1.7   root      443:     case 3:
1.1       root      444:        return ciaadrb;
1.1.1.7   root      445:     case 4:
1.1.1.10  root      446:        return (ciaata - ciaata_passed) & 0xff;
1.1.1.7   root      447:     case 5:
1.1.1.10  root      448:        return (ciaata - ciaata_passed) >> 8;
1.1.1.7   root      449:     case 6:
1.1.1.10  root      450:        return (ciaatb - ciaatb_passed) & 0xff;
1.1.1.7   root      451:     case 7:
1.1.1.10  root      452:        return (ciaatb - ciaatb_passed) >> 8;
1.1.1.7   root      453:     case 8:
1.1       root      454:        if (ciaatlatch) {
                    455:            ciaatlatch = 0;
                    456:            return ciaatol & 0xff;
1.1.1.3   root      457:        } else
                    458:            return ciaatod & 0xff;
1.1.1.7   root      459:     case 9:
1.1.1.3   root      460:        if (ciaatlatch)
                    461:            return (ciaatol >> 8) & 0xff;
                    462:        else
                    463:            return (ciaatod >> 8) & 0xff;
1.1.1.7   root      464:     case 10:
1.1.1.3   root      465:        ciaatlatch = 1;
                    466:        ciaatol = ciaatod; /* ??? only if not already latched? */
1.1       root      467:        return (ciaatol >> 16) & 0xff;
1.1.1.7   root      468:     case 12:
1.1.1.18  root      469:        if (ciaasdr_unread == 1)
                    470:            ciaasdr_unread = 2;
1.1       root      471:        return ciaasdr;
1.1.1.7   root      472:     case 13:
1.1.1.20  root      473:        tmp = ciaaicr; ciaaicr = 0; RethinkICRA ();
1.1.1.17  root      474:        return tmp;
1.1.1.7   root      475:     case 14:
1.1       root      476:        return ciaacra;
1.1.1.7   root      477:     case 15:
1.1       root      478:        return ciaacrb;
                    479:     }
                    480:     return 0;
                    481: }
                    482: 
1.1.1.10  root      483: static uae_u8 ReadCIAB (unsigned int addr)
1.1       root      484: {
1.1.1.3   root      485:     unsigned int tmp;
                    486: 
1.1.1.10  root      487:     compute_passed_time ();
                    488: 
                    489:     switch (addr & 0xf) {
1.1.1.7   root      490:     case 0:
1.1.1.3   root      491:        if (currprefs.use_serial && serstat < 0) /* Only read status when needed */
                    492:            serstat=serial_readstatus();         /* and only once per frame      */
1.1.1.7   root      493:        /* Returning some 1 bits is necessary for Tie Break - otherwise its joystick
                    494:           code won't work.  */
                    495:        return ciabpra | (prtopen ? 0 : 3);
                    496:     case 1:
1.1       root      497:        return ciabprb;
1.1.1.7   root      498:     case 2:
1.1       root      499:        return ciabdra;
1.1.1.7   root      500:     case 3:
1.1       root      501:        return ciabdrb;
1.1.1.7   root      502:     case 4:
1.1.1.10  root      503:        return (ciabta - ciabta_passed) & 0xff;
1.1.1.7   root      504:     case 5:
1.1.1.10  root      505:        return (ciabta - ciabta_passed) >> 8;
1.1.1.7   root      506:     case 6:
1.1.1.10  root      507:        return (ciabtb - ciabtb_passed) & 0xff;
1.1.1.7   root      508:     case 7:
1.1.1.10  root      509:        return (ciabtb - ciabtb_passed) >> 8;
1.1.1.7   root      510:     case 8:
1.1       root      511:        if (ciabtlatch) {
                    512:            ciabtlatch = 0;
                    513:            return ciabtol & 0xff;
1.1.1.3   root      514:        } else
                    515:            return ciabtod & 0xff;
1.1.1.7   root      516:     case 9:
1.1.1.3   root      517:        if (ciabtlatch)
                    518:            return (ciabtol >> 8) & 0xff;
                    519:        else
                    520:            return (ciabtod >> 8) & 0xff;
1.1.1.7   root      521:     case 10:
1.1.1.3   root      522:        ciabtlatch = 1;
                    523:        ciabtol = ciabtod;
1.1       root      524:        return (ciabtol >> 16) & 0xff;
1.1.1.7   root      525:     case 12:
1.1       root      526:        return ciabsdr;
1.1.1.7   root      527:     case 13:
1.1.1.20  root      528:        tmp = ciabicr; ciabicr = 0; RethinkICRB ();
1.1       root      529:        return tmp;
1.1.1.7   root      530:     case 14:
1.1       root      531:        return ciabcra;
1.1.1.7   root      532:     case 15:
1.1       root      533:        return ciabcrb;
                    534:     }
                    535:     return 0;
                    536: }
                    537: 
1.1.1.20  root      538: static void WriteCIAA (uae_u16 addr, uae_u8 val)
1.1       root      539: {
1.1.1.3   root      540:     int oldled, oldovl;
1.1.1.10  root      541:     switch (addr & 0xf) {
1.1.1.7   root      542:     case 0:
1.1.1.20  root      543:        ciaapra = (ciaapra & ~0x3) | (val & 0x3);
                    544:        bfe001_change ();
1.1       root      545:        break;
1.1.1.7   root      546:     case 1:
1.1       root      547:        ciaaprb = val;
                    548:        if (prtopen==1) {
                    549: #ifndef __DOS__
1.1.1.4   root      550:            fprintf (prttmp, "%c",val);
1.1       root      551: #else
                    552:            fputc (val, prttmp);
                    553:            fflush (prttmp);
                    554: #endif
                    555:            if (val==0x04) {
1.1.1.2   root      556: #if defined(__unix) && !defined(__BEOS__) && !defined(__DOS__)
1.1       root      557:                pclose (prttmp);
                    558: #else
                    559:                fclose (prttmp);
                    560: #endif
                    561:                prtopen = 0;
                    562:            }
1.1.1.3   root      563:        } else {
1.1.1.2   root      564: #if defined(__unix) && !defined(__BEOS__) && !defined(__DOS__)
1.1.1.6   root      565:            prttmp = (FILE *)popen ((const char *)currprefs.prtname, "w");
1.1       root      566: #else
1.1.1.6   root      567:            prttmp = (FILE *)fopen ((const char *)currprefs.prtname, "wb");
1.1       root      568: #endif
                    569:            if (prttmp != NULL) {
                    570:                prtopen = 1;
                    571: #ifndef __DOS__
                    572:                fprintf (prttmp,"%c",val);
                    573: #else
                    574:                fputc (val, prttmp);
                    575:                fflush (prttmp);
                    576: #endif
                    577:            }
1.1.1.3   root      578:        }
1.1       root      579:        ciaaicr |= 0x10;
                    580:        break;
1.1.1.7   root      581:     case 2:
1.1.1.17  root      582:        ciaadra = val;
1.1.1.20  root      583:        bfe001_change ();
1.1.1.17  root      584:        break;
1.1.1.7   root      585:     case 3:
1.1.1.17  root      586:        ciaadrb = val;
                    587:        break;
1.1.1.7   root      588:     case 4:
1.1.1.10  root      589:        CIA_update ();
1.1       root      590:        ciaala = (ciaala & 0xff00) | val;
1.1.1.10  root      591:        CIA_calctimers ();
1.1       root      592:        break;
1.1.1.7   root      593:     case 5:
1.1.1.10  root      594:        CIA_update ();
1.1       root      595:        ciaala = (ciaala & 0xff) | (val << 8);
                    596:        if ((ciaacra & 1) == 0)
                    597:            ciaata = ciaala;
1.1.1.3   root      598:        if (ciaacra & 8) {
                    599:            ciaata = ciaala;
                    600:            ciaacra |= 1;
1.1       root      601:        }
1.1.1.10  root      602:        CIA_calctimers ();
1.1       root      603:        break;
1.1.1.7   root      604:     case 6:
1.1.1.10  root      605:        CIA_update ();
1.1       root      606:        ciaalb = (ciaalb & 0xff00) | val;
1.1.1.10  root      607:        CIA_calctimers ();
1.1       root      608:        break;
1.1.1.7   root      609:     case 7:
1.1.1.10  root      610:        CIA_update ();
1.1       root      611:        ciaalb = (ciaalb & 0xff) | (val << 8);
                    612:        if ((ciaacrb & 1) == 0)
                    613:            ciaatb = ciaalb;
1.1.1.3   root      614:        if (ciaacrb & 8) {
1.1       root      615:            ciaatb = ciaalb;
1.1.1.3   root      616:            ciaacrb |= 1;
1.1       root      617:        }
1.1.1.10  root      618:        CIA_calctimers ();
1.1       root      619:        break;
1.1.1.7   root      620:     case 8:
1.1.1.5   root      621:        if (ciaacrb & 0x80) {
1.1       root      622:            ciaaalarm = (ciaaalarm & ~0xff) | val;
                    623:        } else {
                    624:            ciaatod = (ciaatod & ~0xff) | val;
                    625:            ciaatodon = 1;
                    626:        }
                    627:        break;
1.1.1.7   root      628:     case 9:
1.1.1.5   root      629:        if (ciaacrb & 0x80) {
1.1       root      630:            ciaaalarm = (ciaaalarm & ~0xff00) | (val << 8);
                    631:        } else {
                    632:            ciaatod = (ciaatod & ~0xff00) | (val << 8);
                    633:            ciaatodon = 0;
                    634:        }
                    635:        break;
1.1.1.7   root      636:     case 10:
1.1.1.5   root      637:        if (ciaacrb & 0x80) {
1.1       root      638:            ciaaalarm = (ciaaalarm & ~0xff0000) | (val << 16);
                    639:        } else {
                    640:            ciaatod = (ciaatod & ~0xff0000) | (val << 16);
                    641:            ciaatodon = 0;
                    642:        }
                    643:        break;
1.1.1.7   root      644:     case 12:
1.1.1.17  root      645:        ciaasdr = val;
                    646:        break;
1.1.1.7   root      647:     case 13:
1.1.1.17  root      648:        setclr(&ciaaimask,val);
                    649:        break;
1.1.1.7   root      650:     case 14:
1.1.1.10  root      651:        CIA_update ();
1.1       root      652:        ciaacra = val;
1.1.1.5   root      653:        if (ciaacra & 0x10) {
1.1       root      654:            ciaacra &= ~0x10;
                    655:            ciaata = ciaala;
                    656:        }
1.1.1.17  root      657:        if (ciaacra & 0x40)
1.1       root      658:            kback = 1;
1.1.1.10  root      659:        CIA_calctimers ();
1.1       root      660:        break;
1.1.1.7   root      661:     case 15:
1.1.1.10  root      662:        CIA_update ();
1.1.1.3   root      663:        ciaacrb = val;
1.1.1.5   root      664:        if (ciaacrb & 0x10) {
1.1       root      665:            ciaacrb &= ~0x10;
                    666:            ciaatb = ciaalb;
                    667:        }
1.1.1.10  root      668:        CIA_calctimers ();
1.1       root      669:        break;
                    670:     }
                    671: }
                    672: 
1.1.1.20  root      673: static void WriteCIAB (uae_u16 addr, uae_u8 val)
1.1       root      674: {
1.1.1.3   root      675:     int oldval;
1.1.1.10  root      676:     switch (addr & 0xf) {
1.1.1.7   root      677:     case 0:
1.1.1.3   root      678:        if (currprefs.use_serial) {
1.1.1.7   root      679:            oldval = ciabpra;
1.1.1.20  root      680:            ciabpra = serial_writestatus (oldval, val);
1.1.1.3   root      681:        } else
1.1.1.20  root      682:            ciabpra = val;
1.1.1.3   root      683:        break;
1.1.1.7   root      684:     case 1:
1.1       root      685:        ciabprb = val; DISK_select(val); break;
1.1.1.7   root      686:     case 2:
1.1       root      687:        ciabdra = val; break;
1.1.1.7   root      688:     case 3:
1.1       root      689:        ciabdrb = val; break;
1.1.1.7   root      690:     case 4:
1.1.1.10  root      691:        CIA_update ();
1.1       root      692:        ciabla = (ciabla & 0xff00) | val;
1.1.1.10  root      693:        CIA_calctimers ();
1.1       root      694:        break;
1.1.1.7   root      695:     case 5:
1.1.1.10  root      696:        CIA_update ();
1.1       root      697:        ciabla = (ciabla & 0xff) | (val << 8);
1.1.1.3   root      698:        if ((ciabcra & 1) == 0)
1.1       root      699:            ciabta = ciabla;
                    700:        if (ciabcra & 8) {
1.1.1.3   root      701:            ciabta = ciabla;
                    702:            ciabcra |= 1;
                    703:        }
1.1.1.10  root      704:        CIA_calctimers ();
1.1       root      705:        break;
1.1.1.7   root      706:     case 6:
1.1.1.10  root      707:        CIA_update ();
1.1       root      708:        ciablb = (ciablb & 0xff00) | val;
1.1.1.10  root      709:        CIA_calctimers ();
1.1       root      710:        break;
1.1.1.7   root      711:     case 7:
1.1.1.10  root      712:        CIA_update ();
1.1       root      713:        ciablb = (ciablb & 0xff) | (val << 8);
                    714:        if ((ciabcrb & 1) == 0)
                    715:            ciabtb = ciablb;
                    716:        if (ciabcrb & 8) {
                    717:            ciabtb = ciablb;
                    718:            ciabcrb |= 1;
                    719:        }
1.1.1.10  root      720:        CIA_calctimers ();
1.1       root      721:        break;
1.1.1.7   root      722:     case 8:
1.1.1.5   root      723:        if (ciabcrb & 0x80) {
1.1       root      724:            ciabalarm = (ciabalarm & ~0xff) | val;
                    725:        } else {
                    726:            ciabtod = (ciabtod & ~0xff) | val;
                    727:            ciabtodon = 1;
                    728:        }
                    729:        break;
1.1.1.7   root      730:     case 9:
1.1.1.5   root      731:        if (ciabcrb & 0x80) {
1.1       root      732:            ciabalarm = (ciabalarm & ~0xff00) | (val << 8);
                    733:        } else {
                    734:            ciabtod = (ciabtod & ~0xff00) | (val << 8);
                    735:            ciabtodon = 0;
                    736:        }
                    737:        break;
1.1.1.7   root      738:     case 10:
1.1.1.5   root      739:        if (ciabcrb & 0x80) {
1.1       root      740:            ciabalarm = (ciabalarm & ~0xff0000) | (val << 16);
                    741:        } else {
                    742:            ciabtod = (ciabtod & ~0xff0000) | (val << 16);
                    743:            ciabtodon = 0;
                    744:        }
                    745:        break;
1.1.1.7   root      746:     case 12:
1.1.1.3   root      747:        ciabsdr = val;
1.1       root      748:        break;
1.1.1.7   root      749:     case 13:
1.1.1.3   root      750:        setclr(&ciabimask,val);
1.1       root      751:        break;
1.1.1.7   root      752:     case 14:
1.1.1.10  root      753:        CIA_update ();
1.1       root      754:        ciabcra = val;
1.1.1.5   root      755:        if (ciabcra & 0x10) {
1.1       root      756:            ciabcra &= ~0x10;
                    757:            ciabta = ciabla;
                    758:        }
1.1.1.10  root      759:        CIA_calctimers ();
1.1       root      760:        break;
1.1.1.7   root      761:     case 15:
1.1.1.10  root      762:        CIA_update ();
1.1.1.3   root      763:        ciabcrb = val;
1.1.1.5   root      764:        if (ciabcrb & 0x10) {
1.1       root      765:            ciabcrb &= ~0x10;
                    766:            ciabtb = ciablb;
                    767:        }
1.1.1.10  root      768:        CIA_calctimers ();
1.1       root      769:        break;
                    770:     }
                    771: }
                    772: 
1.1.1.10  root      773: void CIA_reset (void)
1.1       root      774: {
                    775:     kback = 1;
                    776:     kbstate = 0;
1.1.1.20  root      777:     oldovl = -1;
                    778:     oldled = -1;
1.1.1.3   root      779: 
1.1.1.11  root      780:     if (!savestate_state) {
                    781:        ciaatlatch = ciabtlatch = 0;
                    782:        ciaapra = 3;
                    783:        ciaatod = ciabtod = 0; ciaatodon = ciabtodon = 0;
                    784:        ciaaicr = ciabicr = ciaaimask = ciabimask = 0;
                    785:        ciaacra = ciaacrb = ciabcra = ciabcrb = 0x4; /* outmode = toggle; */
                    786:        ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF;
                    787:        ciabpra = 0x8C;
1.1.1.13  root      788:        div10 = 0;
1.1.1.11  root      789:     }
1.1.1.10  root      790:     CIA_calctimers ();
1.1.1.14  root      791:     if (! ersatzkickfile) {
                    792:        int i = allocated_chipmem > 0x200000 ? allocated_chipmem >> 16 : 32;
                    793:        map_banks (&kickmem_bank, 0, i, 0x80000);
                    794:     }
1.1.1.3   root      795: 
1.1.1.18  root      796:     if (currprefs.use_serial && !savestate_state)
1.1.1.11  root      797:        serial_dtr_off (); /* Drop DTR at reset */
                    798: 
                    799:     if (savestate_state) {
1.1.1.20  root      800:        bfe001_change ();
1.1.1.11  root      801:        /* select drives */
                    802:        DISK_select (ciabprb);
                    803:     }
1.1       root      804: }
                    805: 
1.1.1.10  root      806: void dumpcia (void)
1.1       root      807: {
1.1.1.13  root      808:     printf("A: CRA: %02x, CRB: %02x, IMASK: %02x, TOD: %08lx %7s TA: %04lx (%04lx), TB: %04lx (%04lx)\n",
1.1.1.3   root      809:           (int)ciaacra, (int)ciaacrb, (int)ciaaimask, ciaatod,
1.1.1.13  root      810:           ciaatlatch ? "L" : "", ciaata, ciaala, ciaatb, ciaalb);
                    811:     printf("B: CRA: %02x, CRB: %02x, IMASK: %02x, TOD: %08lx %7s TA: %04lx (%04lx), TB: %04lx (%04lx)\n",
1.1.1.3   root      812:           (int)ciabcra, (int)ciabcrb, (int)ciabimask, ciabtod,
1.1.1.13  root      813:           ciabtlatch ? "L" : "", ciabta, ciabla, ciabtb, ciablb);
1.1       root      814: }
                    815: 
                    816: /* CIA memory access */
                    817: 
1.1.1.3   root      818: static uae_u32 cia_lget (uaecptr) REGPARAM;
                    819: static uae_u32 cia_wget (uaecptr) REGPARAM;
                    820: static uae_u32 cia_bget (uaecptr) REGPARAM;
                    821: static void cia_lput (uaecptr, uae_u32) REGPARAM;
                    822: static void cia_wput (uaecptr, uae_u32) REGPARAM;
                    823: static void cia_bput (uaecptr, uae_u32) REGPARAM;
1.1       root      824: 
                    825: addrbank cia_bank = {
                    826:     cia_lget, cia_wget, cia_bget,
                    827:     cia_lput, cia_wput, cia_bput,
1.1.1.20  root      828:     default_xlate, default_check, NULL, "CIA"
1.1       root      829: };
                    830: 
1.1.1.15  root      831: static void cia_wait (void)
1.1       root      832: {
1.1.1.15  root      833:     if (!div10)
                    834:        return;
                    835:     do_cycles (DIV10 - div10 + CYCLE_UNIT);
                    836:     CIA_handler ();
                    837: }
                    838: 
                    839: uae_u32 REGPARAM2 cia_bget (uaecptr addr)
                    840: {
                    841:     int r = (addr & 0xf00) >> 8;
1.1.1.18  root      842:     uae_u8 v;
                    843: 
1.1.1.15  root      844:     cia_wait ();
1.1.1.18  root      845:     v = 0xff;
1.1.1.15  root      846:     switch ((addr >> 12) & 3)
                    847:     {
                    848:     case 0:
1.1.1.18  root      849:        v = (addr & 1) ? ReadCIAA (r) : ReadCIAB (r);
                    850:        break;
1.1.1.15  root      851:     case 1:
1.1.1.18  root      852:        v = (addr & 1) ? 0xff : ReadCIAB (r);
                    853:        break;
1.1.1.15  root      854:     case 2:
1.1.1.18  root      855:        v = (addr & 1) ? ReadCIAA (r) : 0xff;
                    856:        break;
                    857: #if 0
                    858:     case 3:
                    859:        if (currprefs.cpu_level == 0 && currprefs.cpu_compatible)
                    860:            v = (addr & 1) ? regs.irc : regs.irc >> 8;
                    861:        if (warned > 0) {
1.1.1.20  root      862:            write_log ("cia_bget: unknown CIA address %x PC=%x\n", addr, m68k_getpc ());
1.1.1.18  root      863:            warned--;
                    864:        }
                    865:        break;
                    866: #endif
1.1.1.15  root      867:     }
1.1.1.18  root      868:     return v;
1.1       root      869: }
                    870: 
1.1.1.3   root      871: uae_u32 REGPARAM2 cia_wget (uaecptr addr)
1.1       root      872: {
1.1.1.15  root      873:     int r = (addr & 0xf00) >> 8;
1.1.1.18  root      874:     uae_u16 v;
1.1.1.15  root      875:     cia_wait ();
1.1.1.18  root      876:     v = 0xffff;
1.1.1.15  root      877:     switch ((addr >> 12) & 3)
                    878:     {
                    879:     case 0:
1.1.1.18  root      880:        v = (ReadCIAB (r) << 8) | ReadCIAA (r);
                    881:        break;
1.1.1.15  root      882:     case 1:
1.1.1.18  root      883:        v = (ReadCIAB (r) << 8) | 0xff;
                    884:        break;
1.1.1.15  root      885:     case 2:
1.1.1.18  root      886:        v = (0xff << 8) | ReadCIAA (r);
                    887:        break;
1.1.1.15  root      888:     }
1.1.1.18  root      889:     return v;
1.1       root      890: }
                    891: 
1.1.1.15  root      892: uae_u32 REGPARAM2 cia_lget (uaecptr addr)
1.1       root      893: {
1.1.1.15  root      894:     uae_u32 v;
                    895:     v = cia_wget (addr) << 16;
                    896:     v |= cia_wget (addr + 2);
                    897:     return v;
1.1       root      898: }
                    899: 
1.1.1.15  root      900: void REGPARAM2 cia_bput (uaecptr addr, uae_u32 value)
1.1       root      901: {
1.1.1.15  root      902:     int r = (addr & 0xf00) >> 8;
                    903:     cia_wait ();
                    904:     if ((addr & 0x2000) == 0)
                    905:        WriteCIAB (r, value);
                    906:     if ((addr & 0x1000) == 0)
                    907:        WriteCIAA (r, value);
1.1       root      908: }
                    909: 
1.1.1.3   root      910: void REGPARAM2 cia_wput (uaecptr addr, uae_u32 value)
1.1       root      911: {
1.1.1.15  root      912:     int r = (addr & 0xf00) >> 8;
                    913:     cia_wait ();
                    914:     if ((addr & 0x2000) == 0)
                    915:        WriteCIAB (r, value >> 8);
                    916:     if ((addr & 0x1000) == 0)
                    917:        WriteCIAA (r, value & 0xff);
1.1       root      918: }
                    919: 
1.1.1.15  root      920: void REGPARAM2 cia_lput (uaecptr addr, uae_u32 value)
1.1       root      921: {
1.1.1.15  root      922:     cia_wput (addr, value >> 16);
                    923:     cia_wput (addr + 2, value & 0xffff);
1.1       root      924: }
                    925: 
                    926: /* battclock memory access */
                    927: 
1.1.1.3   root      928: static uae_u32 clock_lget (uaecptr) REGPARAM;
                    929: static uae_u32 clock_wget (uaecptr) REGPARAM;
                    930: static uae_u32 clock_bget (uaecptr) REGPARAM;
                    931: static void clock_lput (uaecptr, uae_u32) REGPARAM;
                    932: static void clock_wput (uaecptr, uae_u32) REGPARAM;
                    933: static void clock_bput (uaecptr, uae_u32) REGPARAM;
1.1       root      934: 
                    935: addrbank clock_bank = {
                    936:     clock_lget, clock_wget, clock_bget,
                    937:     clock_lput, clock_wput, clock_bput,
1.1.1.20  root      938:     default_xlate, default_check, NULL, "Battery backed up clock"
1.1       root      939: };
                    940: 
1.1.1.3   root      941: uae_u32 REGPARAM2 clock_lget (uaecptr addr)
1.1       root      942: {
1.1.1.9   root      943:     return clock_bget (addr + 3);
1.1       root      944: }
                    945: 
1.1.1.3   root      946: uae_u32 REGPARAM2 clock_wget (uaecptr addr)
1.1       root      947: {
1.1.1.9   root      948:     return clock_bget (addr + 1);
1.1       root      949: }
                    950: 
1.1.1.3   root      951: uae_u32 REGPARAM2 clock_bget (uaecptr addr)
1.1       root      952: {
1.1.1.9   root      953:     time_t t = time(0);
1.1       root      954:     struct tm *ct;
1.1.1.9   root      955: 
                    956:     ct = localtime (&t);
                    957: 
1.1.1.7   root      958:     switch (addr & 0x3f) {
                    959:     case 0x03: return ct->tm_sec % 10;
                    960:     case 0x07: return ct->tm_sec / 10;
                    961:     case 0x0b: return ct->tm_min % 10;
                    962:     case 0x0f: return ct->tm_min / 10;
                    963:     case 0x13: return ct->tm_hour % 10;
                    964:     case 0x17: return ct->tm_hour / 10;
                    965:     case 0x1b: return ct->tm_mday % 10;
                    966:     case 0x1f: return ct->tm_mday / 10;
                    967:     case 0x23: return (ct->tm_mon+1) % 10;
                    968:     case 0x27: return (ct->tm_mon+1) / 10;
                    969:     case 0x2b: return ct->tm_year % 10;
                    970:     case 0x2f: return ct->tm_year / 10;
                    971: 
                    972:     case 0x33: return ct->tm_wday;  /*Hack by -=SR=- */
                    973:     case 0x37: return clock_control_d;
                    974:     case 0x3b: return clock_control_e;
                    975:     case 0x3f: return clock_control_f;
1.1       root      976:     }
                    977:     return 0;
                    978: }
                    979: 
1.1.1.3   root      980: void REGPARAM2 clock_lput (uaecptr addr, uae_u32 value)
1.1       root      981: {
                    982:     /* No way */
                    983: }
                    984: 
1.1.1.3   root      985: void REGPARAM2 clock_wput (uaecptr addr, uae_u32 value)
1.1       root      986: {
                    987:     /* No way */
                    988: }
                    989: 
1.1.1.3   root      990: void REGPARAM2 clock_bput (uaecptr addr, uae_u32 value)
1.1       root      991: {
1.1.1.7   root      992:     switch (addr & 0x3f) {
1.1.1.9   root      993:     case 0x37: clock_control_d = value; break;
                    994:     case 0x3b: clock_control_e = value; break;
                    995:     case 0x3f: clock_control_f = value; break;
1.1       root      996:     }
                    997: }
1.1.1.11  root      998: 
                    999: /* CIA-A and CIA-B save/restore code */
                   1000: 
1.1.1.19  root     1001: const uae_u8 *restore_cia (int num, const uae_u8 *src)
1.1.1.11  root     1002: {
                   1003:     uae_u8 b;
                   1004:     uae_u16 w;
                   1005:     uae_u32 l;
                   1006: 
                   1007:     /* CIA registers */
                   1008:     b = restore_u8 ();                                 /* 0 PRA */
                   1009:     if (num) ciabpra = b; else ciaapra = b;
                   1010:     b = restore_u8 ();                                 /* 1 PRB */
                   1011:     if (num) ciabprb = b; else ciaaprb = b;
                   1012:     b = restore_u8 ();                                 /* 2 DDRA */
                   1013:     if (num) ciabdra = b; else ciaadra = b;
                   1014:     b = restore_u8 ();                                 /* 3 DDRB */
                   1015:     if (num) ciabdrb = b; else ciaadrb = b;
                   1016:     w = restore_u16 ();                                        /* 4 TA */
                   1017:     if (num) ciabta = w; else ciaata = w;
                   1018:     w = restore_u16 ();                                        /* 6 TB */
                   1019:     if (num) ciabtb = w; else ciaatb = w;
                   1020:     l = restore_u8 ();                                 /* 8/9/A TOD */
                   1021:     l |= restore_u8 () << 8;
                   1022:     l |= restore_u8 () << 16;
                   1023:     if (num) ciabtod = l; else ciaatod = l;
                   1024:     restore_u8 ();                                             /* B unused */
                   1025:     b = restore_u8 ();                                 /* C SDR */
                   1026:     if (num) ciabsdr = b; else ciaasdr = b;
                   1027:     b = restore_u8 ();                                 /* D ICR INFORMATION (not mask!) */
                   1028:     if (num) ciabicr = b; else ciaaicr = b;
                   1029:     b = restore_u8 ();                                 /* E CRA */
                   1030:     if (num) ciabcra = b; else ciaacra = b;
                   1031:     b = restore_u8 ();                                 /* F CRB */
                   1032:     if (num) ciabcrb = b; else ciaacrb = b;
                   1033: 
                   1034: /* CIA internal data */
                   1035: 
                   1036:     b = restore_u8 ();                                 /* ICR MASK */
                   1037:     if (num) ciabimask = b; else ciaaimask = b;
                   1038:     w = restore_u8 ();                                 /* timer A latch */
                   1039:     w |= restore_u8 () << 8;
1.1.1.13  root     1040:     if (num) ciabla = w; else ciaala = w;
1.1.1.11  root     1041:     w = restore_u8 ();                                 /* timer B latch */
                   1042:     w |= restore_u8 () << 8;
                   1043:     if (num) ciablb = w; else ciaalb = w;
                   1044:     w = restore_u8 ();                                 /* TOD latched value */
                   1045:     w |= restore_u8 () << 8;
                   1046:     w |= restore_u8 () << 16;
                   1047:     if (num) ciabtol = w; else ciaatol = w;
                   1048:     l = restore_u8 ();                                 /* alarm */
                   1049:     l |= restore_u8 () << 8;
                   1050:     l |= restore_u8 () << 16;
                   1051:     if (num) ciabalarm = l; else ciaaalarm = l;
                   1052:     b = restore_u8 ();
                   1053:     if (num) ciabtlatch = b & 1; else ciaatlatch = b & 1;      /* is TOD latched? */
                   1054:     if (num) ciabtodon = b & 2; else ciaatodon = b & 2;                /* is TOD stopped? */
                   1055:     if (num) {
                   1056:        div10 = CYCLE_UNIT * restore_u8 ();
                   1057:     }
                   1058:     return src;
                   1059: }
                   1060: 
1.1.1.18  root     1061: uae_u8 *save_cia (int num, int *len, uae_u8 *dstptr)
1.1.1.11  root     1062: {
                   1063:     uae_u8 *dstbak,*dst, b;
                   1064:     uae_u16 t;
                   1065: 
1.1.1.18  root     1066:     if (dstptr)
                   1067:        dstbak = dst = dstptr;
                   1068:     else
                   1069:        dstbak = dst = malloc (16 + 12 + 1);
1.1.1.11  root     1070: 
                   1071:     compute_passed_time ();
                   1072: 
                   1073:     /* CIA registers */
                   1074: 
                   1075:     b = num ? ciabpra : ciaapra;                               /* 0 PRA */
                   1076:     save_u8 (b);
                   1077:     b = num ? ciabprb : ciaaprb;                               /* 1 PRB */
                   1078:     save_u8 (b);
                   1079:     b = num ? ciabdra : ciaadra;                               /* 2 DDRA */
1.1.1.18  root     1080:     save_u8 (b);
1.1.1.11  root     1081:     b = num ? ciabdrb : ciaadrb;                               /* 3 DDRB */
                   1082:     save_u8 (b);
                   1083:     t = (num ? ciabta - ciabta_passed : ciaata - ciaata_passed);/* 4 TA */
                   1084:     save_u16 (t);
                   1085:     t = (num ? ciabtb - ciabtb_passed : ciaatb - ciaatb_passed);/* 8 TB */
                   1086:     save_u16 (t);
                   1087:     b = (num ? ciabtod : ciaatod);                     /* 8 TODL */
                   1088:     save_u8 (b);
                   1089:     b = (num ? ciabtod >> 8 : ciaatod >> 8);           /* 9 TODM */
                   1090:     save_u8 (b);
                   1091:     b = (num ? ciabtod >> 16 : ciaatod >> 16);         /* A TODH */
                   1092:     save_u8 (b);
                   1093:     save_u8 (0);                                               /* B unused */
                   1094:     b = num ? ciabsdr : ciaasdr;                               /* C SDR */
                   1095:     save_u8 (b);
                   1096:     b = num ? ciabicr : ciaaicr;                               /* D ICR INFORMATION (not mask!) */
                   1097:     save_u8 (b);
                   1098:     b = num ? ciabcra : ciaacra;                               /* E CRA */
                   1099:     save_u8 (b);
                   1100:     b = num ? ciabcrb : ciaacrb;                               /* F CRB */
                   1101:     save_u8 (b);
                   1102: 
                   1103:     /* CIA internal data */
                   1104: 
                   1105:     save_u8 (num ? ciabimask : ciaaimask);                     /* ICR */
                   1106:     b = (num ? ciabla : ciaala);                       /* timer A latch LO */
                   1107:     save_u8 (b);
                   1108:     b = (num ? ciabla >> 8 : ciaala >> 8);             /* timer A latch HI */
                   1109:     save_u8 (b);
                   1110:     b = (num ? ciablb : ciaalb);                       /* timer B latch LO */
                   1111:     save_u8 (b);
                   1112:     b = (num ? ciablb >> 8 : ciaalb >> 8);             /* timer B latch HI */
                   1113:     save_u8 (b);
                   1114:     b = (num ? ciabtol : ciaatol);                     /* latched TOD LO */
                   1115:     save_u8 (b);
                   1116:     b = (num ? ciabtol >> 8 : ciaatol >> 8);           /* latched TOD MED */
                   1117:     save_u8 (b);
                   1118:     b = (num ? ciabtol >> 16 : ciaatol >> 16);         /* latched TOD HI */
                   1119:     save_u8 (b);
                   1120:     b = (num ? ciabalarm : ciaaalarm);                 /* alarm LO */
                   1121:     save_u8 (b);
1.1.1.20  root     1122:     b = (num ? ciabalarm >> 8 : ciaaalarm >> 8);       /* alarm MED */
1.1.1.11  root     1123:     save_u8 (b);
                   1124:     b = (num ? ciabalarm >> 16 : ciaaalarm >> 16);     /* alarm HI */
                   1125:     save_u8 (b);
                   1126:     b = 0;
                   1127:     if (num)
                   1128:        b |= ciabtlatch ? 1 : 0;
                   1129:     else
                   1130:        b |= ciaatlatch ? 1 : 0; /* is TOD latched? */
                   1131:     if (num)
                   1132:        b |= ciabtodon ? 2 : 0;
                   1133:     else
                   1134:        b |= ciaatodon ? 2 : 0;   /* TOD stopped? */
                   1135:     save_u8 (b);
                   1136:     if (num) {
                   1137:        /* Save extra state with CIAB.  */
                   1138:        save_u8 (div10 / CYCLE_UNIT);
                   1139:     }
                   1140:     *len = dst - dstbak;
                   1141:     return dstbak;
                   1142: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.