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

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

unix.superglobalmegacorp.com

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