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

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

unix.superglobalmegacorp.com

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