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

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

unix.superglobalmegacorp.com

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