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

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"
                     26: 
                     27: #define DIV10 5 /* Yes, a bad identifier. */
                     28: 
                     29: /* battclock stuff */
                     30: #define RTC_D_ADJ      8
                     31: #define RTC_D_IRQ      4
                     32: #define RTC_D_BUSY     2
                     33: #define RTC_D_HOLD     1
                     34: #define RTC_E_t1       8
                     35: #define RTC_E_t0       4
                     36: #define RTC_E_INTR     2
                     37: #define RTC_E_MASK     1
                     38: #define RTC_F_TEST     8
                     39: #define RTC_F_24_12    4
                     40: #define RTC_F_STOP     2
                     41: #define RTC_F_RSET     1
                     42: 
1.1.1.3   root       43: static unsigned int clock_control_d = RTC_D_ADJ + RTC_D_HOLD;
                     44: static unsigned int clock_control_e = 0;
                     45: static unsigned int clock_control_f = RTC_F_24_12;
                     46: 
                     47: unsigned int ciaaicr,ciaaimask,ciabicr,ciabimask;
                     48: unsigned int ciaacra,ciaacrb,ciabcra,ciabcrb;
                     49: unsigned long ciaata,ciaatb,ciabta,ciabtb;
                     50: unsigned long ciaatod,ciabtod,ciaatol,ciabtol,ciaaalarm,ciabalarm;
1.1.1.2   root       51: int ciaatlatch,ciabtlatch;
1.1.1.3   root       52: 
                     53: unsigned int ciabpra;
                     54: 
                     55: unsigned int gui_ledstate;
                     56: 
                     57: static unsigned long ciaala,ciaalb,ciabla,ciablb;
                     58: static int ciaatodon, ciabtodon;
                     59: static unsigned int ciaapra,ciaaprb,ciaadra,ciaadrb,ciaasdr;
                     60: static unsigned int ciabprb,ciabdra,ciabdrb,ciabsdr;
1.1       root       61: static int div10;
1.1.1.2   root       62: static int kbstate, kback, ciaasdr_unread = 0;
1.1       root       63: 
                     64: static int prtopen;
                     65: static FILE *prttmp;
                     66: 
1.1.1.3   root       67: static void setclr(unsigned int *p, unsigned int val)
1.1       root       68: {
                     69:     if (val & 0x80) {
                     70:        *p |= val & 0x7F;
                     71:     } else {
                     72:        *p &= ~val;
                     73:     }
                     74: }
                     75: 
                     76: static void RethinkICRA(void)
                     77: {
                     78:     if (ciaaimask & ciaaicr) {
                     79:        ciaaicr |= 0x80;
                     80:        custom_bank.wput(0xDFF09C,0x8008);
                     81:     } else {
                     82:        ciaaicr &= 0x7F;
                     83: /*     custom_bank.wput(0xDFF09C,0x0008);*/
                     84:     }
                     85: }
                     86: 
                     87: static void RethinkICRB(void)
                     88: {
                     89: #if 0 /* ??? What's this then? */
                     90:     if (ciabicr & 0x10) {
                     91:        custom_bank.wput(0xDFF09C,0x9000);
                     92:     }
                     93: #endif
                     94:     if (ciabimask & ciabicr) {
                     95:        ciabicr |= 0x80;
                     96:        custom_bank.wput(0xDFF09C,0xA000);
                     97:     } else {
                     98:        ciabicr &= 0x7F;
                     99: /*     custom_bank.wput(0xDFF09C,0x2000);*/
                    100:     }
                    101: }
                    102: 
                    103: static int lastdiv10;
                    104: 
                    105: static void CIA_update(void)
                    106: {
                    107:     unsigned long int ccount = cycles - eventtab[ev_cia].oldcycles + lastdiv10;
                    108:     unsigned long int ciaclocks = ccount / DIV10;
                    109: 
                    110:     int aovfla = 0, aovflb = 0, bovfla = 0, bovflb = 0;
                    111: 
                    112:     lastdiv10 = div10;
                    113:     div10 = ccount % DIV10;
1.1.1.3   root      114: 
1.1       root      115:     /* CIA A timers */
                    116:     if ((ciaacra & 0x21) == 0x01) {
                    117:        assert((ciaata+1) >= ciaclocks);
                    118:        if ((ciaata+1) == ciaclocks) {
                    119:            aovfla = 1;
                    120:            if ((ciaacrb & 0x61) == 0x41) {
1.1.1.3   root      121:                if (ciaatb-- == 0) aovflb = 1;
1.1       root      122:            }
1.1.1.3   root      123:        }
1.1       root      124:        ciaata -= ciaclocks;
                    125:     }
                    126:     if ((ciaacrb & 0x61) == 0x01) {
                    127:        assert((ciaatb+1) >= ciaclocks);
                    128:        if ((ciaatb+1) == ciaclocks) aovflb = 1;
                    129:        ciaatb -= ciaclocks;
                    130:     }
1.1.1.3   root      131: 
1.1       root      132:     /* CIA B timers */
                    133:     if ((ciabcra & 0x21) == 0x01) {
                    134:        assert((ciabta+1) >= ciaclocks);
                    135:        if ((ciabta+1) == ciaclocks) {
                    136:            bovfla = 1;
                    137:            if ((ciabcrb & 0x61) == 0x41) {
                    138:                if (ciabtb-- == 0) bovflb = 1;
                    139:            }
1.1.1.3   root      140:        }
1.1       root      141:        ciabta -= ciaclocks;
                    142:     }
                    143:     if ((ciabcrb & 0x61) == 0x01) {
                    144:        assert ((ciabtb+1) >= ciaclocks);
                    145:        if ((ciabtb+1) == ciaclocks) bovflb = 1;
                    146:        ciabtb -= ciaclocks;
                    147:     }
                    148:     if (aovfla) {
                    149:        ciaaicr |= 1; RethinkICRA();
                    150:        ciaata = ciaala;
                    151:        if (ciaacra & 0x8) ciaacra &= ~1;
                    152:     }
                    153:     if (aovflb) {
                    154:        ciaaicr |= 2; RethinkICRA();
                    155:        ciaatb = ciaalb;
                    156:        if (ciaacrb & 0x8) ciaacrb &= ~1;
                    157:     }
                    158:     if (bovfla) {
                    159:        ciabicr |= 1; RethinkICRB();
                    160:        ciabta = ciabla;
                    161:        if (ciabcra & 0x8) ciabcra &= ~1;
                    162:     }
                    163:     if (bovflb) {
                    164:        ciabicr |= 2; RethinkICRB();
                    165:        ciabtb = ciablb;
                    166:        if (ciabcrb & 0x8) ciabcrb &= ~1;
                    167:     }
                    168: }
                    169: 
                    170: static void CIA_calctimers(void)
                    171: {
                    172:     int ciaatimea = -1, ciaatimeb = -1, ciabtimea = -1, ciabtimeb = -1;
                    173: 
                    174:     eventtab[ev_cia].oldcycles = cycles;
1.1.1.3   root      175: 
1.1       root      176:     if ((ciaacra & 0x21) == 0x01) {
1.1.1.3   root      177:        ciaatimea = (DIV10-div10) + DIV10*ciaata;
1.1       root      178:     }
                    179:     if ((ciaacrb & 0x61) == 0x41) {
                    180:        /* Timer B will not get any pulses if Timer A is off. */
                    181:        if (ciaatimea >= 0) {
                    182:            /* If Timer A is in one-shot mode, and Timer B needs more than
                    183:             * one pulse, it will not underflow. */
                    184:            if (ciaatb == 0 || (ciaacra & 0x8) == 0) {
                    185:                /* Otherwise, we can determine the time of the underflow. */
                    186:                ciaatimeb = ciaatimea + ciaala * DIV10 * ciaatb;
                    187:            }
                    188:        }
                    189:     }
                    190:     if ((ciaacrb & 0x61) == 0x01) {
                    191:        ciaatimeb = (DIV10-div10) + DIV10*ciaatb;
                    192:     }
                    193: 
                    194:     if ((ciabcra & 0x21) == 0x01) {
1.1.1.3   root      195:        ciabtimea = (DIV10-div10) + DIV10*ciabta;
1.1       root      196:     }
                    197:     if ((ciabcrb & 0x61) == 0x41) {
                    198:        /* Timer B will not get any pulses if Timer A is off. */
                    199:        if (ciabtimea >= 0) {
                    200:            /* If Timer A is in one-shot mode, and Timer B needs more than
                    201:             * one pulse, it will not underflow. */
                    202:            if (ciabtb == 0 || (ciabcra & 0x8) == 0) {
                    203:                /* Otherwise, we can determine the time of the underflow. */
                    204:                ciabtimeb = ciabtimea + ciabla * DIV10 * ciabtb;
                    205:            }
                    206:        }
                    207:     }
                    208:     if ((ciabcrb & 0x61) == 0x01) {
                    209:        ciabtimeb = (DIV10-div10) + DIV10*ciabtb;
                    210:     }
                    211:     eventtab[ev_cia].active = (ciaatimea != -1 || ciaatimeb != -1
                    212:                               || ciabtimea != -1 || ciabtimeb != -1);
                    213:     if (eventtab[ev_cia].active) {
                    214:        unsigned long int ciatime = ~0L;
                    215:        if (ciaatimea != -1) ciatime = ciaatimea;
                    216:        if (ciaatimeb != -1 && ciaatimeb < ciatime) ciatime = ciaatimeb;
                    217:        if (ciabtimea != -1 && ciabtimea < ciatime) ciatime = ciabtimea;
                    218:        if (ciabtimeb != -1 && ciabtimeb < ciatime) ciatime = ciabtimeb;
                    219:        eventtab[ev_cia].evtime = ciatime + cycles;
                    220:     }
                    221:     events_schedule();
                    222: }
                    223: 
                    224: void CIA_handler(void)
                    225: {
                    226:     CIA_update();
                    227:     CIA_calctimers();
                    228: }
                    229: 
1.1.1.8   root      230: void cia_diskindex(void)
1.1       root      231: {
                    232:     ciabicr |= 0x10;
                    233:     RethinkICRB();
                    234: }
                    235: 
                    236: void CIA_hsync_handler(void)
                    237: {
1.1.1.3   root      238:     static unsigned int keytime = 0, sleepyhead = 0;
1.1       root      239: 
                    240:     if (ciabtodon)
                    241:        ciabtod++;
                    242:     ciabtod &= 0xFFFFFF;
                    243: 
                    244:     if (ciabtod == ciabalarm) {
                    245:        ciabicr |= 4; RethinkICRB();
                    246:     }
1.1.1.3   root      247: 
                    248:     /* check wether the serial port gets some data */
                    249:     if (doreadser)
                    250:        doreadser = SERDATS();
                    251: 
1.1       root      252:     if (keys_available() && kback && (++keytime & 15) == 0) {
1.1.1.3   root      253:        /*
1.1.1.2   root      254:         * This hack lets one possible ciaaicr cycle go by without any key
                    255:         * being read, for every cycle in which a key is pulled out of the
                    256:         * queue.  If no hack is used, a lot of key events just get lost
                    257:         * when you type fast.  With a simple hack that waits for ciaasdr
                    258:         * to be read before feeding it another, it will keep up until the
                    259:         * queue gets about 14 characters ahead and then lose events, and
                    260:         * the mouse pointer will freeze while typing is being taken in.
                    261:         * With this hack, you can type 30 or 40 characters ahead with little
                    262:         * or no lossage, and the mouse doesn't get stuck.  The tradeoff is
                    263:         * that the total slowness of typing appearing on screen is worse.
                    264:         */
1.1.1.3   root      265:        if (ciaasdr_unread == 2)
                    266:            ciaasdr_unread = 0;
                    267:        else if (ciaasdr_unread == 0) {
                    268:            switch (kbstate) {
1.1.1.2   root      269:             case 0:
1.1.1.3   root      270:                ciaasdr = (uae_s8)~0xFB; /* aaarghh... stupid compiler */
                    271:                kbstate++;
                    272:                break;
1.1.1.2   root      273:             case 1:
1.1.1.3   root      274:                kbstate++;
                    275:                ciaasdr = (uae_s8)~0xFD;
                    276:                break;
1.1.1.2   root      277:             case 2:
1.1.1.3   root      278:                ciaasdr = ~get_next_key();
                    279:                ciaasdr_unread = 1;      /* interlock to prevent lost keystrokes */
                    280:                break;
1.1.1.2   root      281:            }
                    282:            ciaaicr |= 8;
                    283:            RethinkICRA();
                    284:            sleepyhead = 0;
1.1.1.3   root      285:        } else if (!(++sleepyhead & 15))
                    286:            ciaasdr_unread = 0;          /* give up on this key event after unread for a long time */
1.1       root      287:     }
                    288: }
                    289: 
                    290: void CIA_vsync_handler()
1.1.1.3   root      291: {
                    292:     if (ciaatodon)
1.1       root      293:        ciaatod++;
                    294:     ciaatod &= 0xFFFFFF;
                    295:     if (ciaatod == ciaaalarm) {
                    296:        ciaaicr |= 4; RethinkICRA();
                    297:     }
1.1.1.3   root      298: 
                    299:     doreadser = 1;
                    300:     serstat = -1;
                    301:     serial_flush_buffer();
1.1       root      302: }
                    303: 
1.1.1.3   root      304: static uae_u8 ReadCIAA(unsigned int addr)
1.1       root      305: {
1.1.1.3   root      306:     unsigned int tmp;
                    307: 
1.1.1.5   root      308:     switch(addr & 0xf) {
1.1.1.7   root      309:     case 0:
1.1.1.3   root      310:        if (currprefs.use_serial && (serstat < 0)) /* Only read status when needed */
                    311:            serstat=serial_readstatus();                /* and only once per frame */
                    312: 
1.1       root      313:        tmp = (DISK_status() & 0x3C);
1.1.1.6   root      314:        if ((JSEM_ISMOUSE (0, &currprefs) && !buttonstate[0])
                    315:            || (!JSEM_ISMOUSE (0, &currprefs) && !(joy0button & 1)))
1.1.1.3   root      316:            tmp |= 0x40;
                    317:        if (!(joy1button & 1))
                    318:            tmp |= 0x80;
1.1       root      319:        return tmp;
1.1.1.7   root      320:     case 1:
                    321:        /* Returning 0xFF is necessary for Tie Break - otherwise its joystick
                    322:           code won't work.  */
                    323:        return prtopen ? ciaaprb : 0xFF;
                    324:     case 2:
1.1       root      325:        return ciaadra;
1.1.1.7   root      326:     case 3:
1.1       root      327:        return ciaadrb;
1.1.1.7   root      328:     case 4:
1.1       root      329:        return ciaata & 0xff;
1.1.1.7   root      330:     case 5:
1.1       root      331:        return ciaata >> 8;
1.1.1.7   root      332:     case 6:
1.1       root      333:        return ciaatb & 0xff;
1.1.1.7   root      334:     case 7:
1.1       root      335:        return ciaatb >> 8;
1.1.1.7   root      336:     case 8:
1.1       root      337:        if (ciaatlatch) {
                    338:            ciaatlatch = 0;
                    339:            return ciaatol & 0xff;
1.1.1.3   root      340:        } else
                    341:            return ciaatod & 0xff;
1.1.1.7   root      342:     case 9:
1.1.1.3   root      343:        if (ciaatlatch)
                    344:            return (ciaatol >> 8) & 0xff;
                    345:        else
                    346:            return (ciaatod >> 8) & 0xff;
1.1.1.7   root      347:     case 10:
1.1.1.3   root      348:        ciaatlatch = 1;
                    349:        ciaatol = ciaatod; /* ??? only if not already latched? */
1.1       root      350:        return (ciaatol >> 16) & 0xff;
1.1.1.7   root      351:     case 12:
1.1.1.3   root      352:        if (ciaasdr == 1) ciaasdr_unread = 2;
1.1       root      353:        return ciaasdr;
1.1.1.7   root      354:     case 13:
1.1       root      355:        tmp = ciaaicr; ciaaicr = 0; RethinkICRA(); return tmp;
1.1.1.7   root      356:     case 14:
1.1       root      357:        return ciaacra;
1.1.1.7   root      358:     case 15:
1.1       root      359:        return ciaacrb;
                    360:     }
                    361:     return 0;
                    362: }
                    363: 
1.1.1.3   root      364: static uae_u8 ReadCIAB(unsigned int addr)
1.1       root      365: {
1.1.1.3   root      366:     unsigned int tmp;
                    367: 
1.1.1.5   root      368:     switch(addr & 0xf) {
1.1.1.7   root      369:     case 0:
1.1.1.3   root      370:        if (currprefs.use_serial && serstat < 0) /* Only read status when needed */
                    371:            serstat=serial_readstatus();         /* and only once per frame      */
1.1.1.7   root      372:        /* Returning some 1 bits is necessary for Tie Break - otherwise its joystick
                    373:           code won't work.  */
                    374:        return ciabpra | (prtopen ? 0 : 3);
                    375:     case 1:
1.1       root      376:        return ciabprb;
1.1.1.7   root      377:     case 2:
1.1       root      378:        return ciabdra;
1.1.1.7   root      379:     case 3:
1.1       root      380:        return ciabdrb;
1.1.1.7   root      381:     case 4:
1.1       root      382:        return ciabta & 0xff;
1.1.1.7   root      383:     case 5:
1.1       root      384:        return ciabta >> 8;
1.1.1.7   root      385:     case 6:
1.1       root      386:        return ciabtb & 0xff;
1.1.1.7   root      387:     case 7:
1.1       root      388:        return ciabtb >> 8;
1.1.1.7   root      389:     case 8:
1.1       root      390:        if (ciabtlatch) {
                    391:            ciabtlatch = 0;
                    392:            return ciabtol & 0xff;
1.1.1.3   root      393:        } else
                    394:            return ciabtod & 0xff;
1.1.1.7   root      395:     case 9:
1.1.1.3   root      396:        if (ciabtlatch)
                    397:            return (ciabtol >> 8) & 0xff;
                    398:        else
                    399:            return (ciabtod >> 8) & 0xff;
1.1.1.7   root      400:     case 10:
1.1.1.3   root      401:        ciabtlatch = 1;
                    402:        ciabtol = ciabtod;
1.1       root      403:        return (ciabtol >> 16) & 0xff;
1.1.1.7   root      404:     case 12:
1.1       root      405:        return ciabsdr;
1.1.1.7   root      406:     case 13:
1.1       root      407:        tmp = ciabicr; ciabicr = 0; RethinkICRB();
                    408:        return tmp;
1.1.1.7   root      409:     case 14:
1.1       root      410:        return ciabcra;
1.1.1.7   root      411:     case 15:
1.1       root      412:        return ciabcrb;
                    413:     }
                    414:     return 0;
                    415: }
                    416: 
1.1.1.3   root      417: static void WriteCIAA(uae_u16 addr,uae_u8 val)
1.1       root      418: {
1.1.1.3   root      419:     int oldled, oldovl;
1.1.1.5   root      420:     switch(addr & 0xf) {
1.1.1.7   root      421:     case 0:
1.1.1.3   root      422:        oldovl = ciaapra & 1;
1.1       root      423:        oldled = ciaapra & 2;
                    424:        ciaapra = (ciaapra & ~0x3) | (val & 0x3); LED(ciaapra & 0x2);
1.1.1.3   root      425:        gui_ledstate &= ~1;
                    426:        gui_ledstate |= ((~ciaapra & 2) >> 1);
1.1       root      427:        if ((ciaapra & 2) != oldled)
                    428:            gui_led (0, !(ciaapra & 2));
1.1.1.3   root      429:        if ((ciaapra & 1) != oldovl) {
                    430:            map_banks(oldovl || ersatzkickfile ? &chipmem_bank : &kickmem_bank, 0, 32);
                    431:        }
1.1       root      432:        break;
1.1.1.7   root      433:     case 1:
1.1       root      434:        ciaaprb = val;
                    435:        if (prtopen==1) {
                    436: #ifndef __DOS__
1.1.1.4   root      437:            fprintf (prttmp, "%c",val);
1.1       root      438: #else
                    439:            fputc (val, prttmp);
                    440:            fflush (prttmp);
                    441: #endif
                    442:            if (val==0x04) {
1.1.1.2   root      443: #if defined(__unix) && !defined(__BEOS__) && !defined(__DOS__)
1.1       root      444:                pclose (prttmp);
                    445: #else
                    446:                fclose (prttmp);
                    447: #endif
                    448:                prtopen = 0;
                    449:            }
1.1.1.3   root      450:        } else {
1.1.1.2   root      451: #if defined(__unix) && !defined(__BEOS__) && !defined(__DOS__)
1.1.1.6   root      452:            prttmp = (FILE *)popen ((const char *)currprefs.prtname, "w");
1.1       root      453: #else
1.1.1.6   root      454:            prttmp = (FILE *)fopen ((const char *)currprefs.prtname, "wb");
1.1       root      455: #endif
                    456:            if (prttmp != NULL) {
                    457:                prtopen = 1;
                    458: #ifndef __DOS__
                    459:                fprintf (prttmp,"%c",val);
                    460: #else
                    461:                fputc (val, prttmp);
                    462:                fflush (prttmp);
                    463: #endif
                    464:            }
1.1.1.3   root      465:        }
1.1       root      466:        ciaaicr |= 0x10;
                    467:        break;
1.1.1.7   root      468:     case 2:
1.1       root      469:        ciaadra = val; break;
1.1.1.7   root      470:     case 3:
1.1       root      471:        ciaadrb = val; break;
1.1.1.7   root      472:     case 4:
1.1       root      473:        CIA_update();
                    474:        ciaala = (ciaala & 0xff00) | val;
                    475:        CIA_calctimers();
                    476:        break;
1.1.1.7   root      477:     case 5:
1.1       root      478:        CIA_update();
                    479:        ciaala = (ciaala & 0xff) | (val << 8);
                    480:        if ((ciaacra & 1) == 0)
                    481:            ciaata = ciaala;
1.1.1.3   root      482:        if (ciaacra & 8) {
                    483:            ciaata = ciaala;
                    484:            ciaacra |= 1;
1.1       root      485:        }
                    486:        CIA_calctimers();
                    487:        break;
1.1.1.7   root      488:     case 6:
1.1       root      489:        CIA_update();
                    490:        ciaalb = (ciaalb & 0xff00) | val;
                    491:        CIA_calctimers();
                    492:        break;
1.1.1.7   root      493:     case 7:
1.1       root      494:        CIA_update();
                    495:        ciaalb = (ciaalb & 0xff) | (val << 8);
                    496:        if ((ciaacrb & 1) == 0)
                    497:            ciaatb = ciaalb;
1.1.1.3   root      498:        if (ciaacrb & 8) {
1.1       root      499:            ciaatb = ciaalb;
1.1.1.3   root      500:            ciaacrb |= 1;
1.1       root      501:        }
                    502:        CIA_calctimers();
                    503:        break;
1.1.1.7   root      504:     case 8:
1.1.1.5   root      505:        if (ciaacrb & 0x80) {
1.1       root      506:            ciaaalarm = (ciaaalarm & ~0xff) | val;
                    507:        } else {
                    508:            ciaatod = (ciaatod & ~0xff) | val;
                    509:            ciaatodon = 1;
                    510:        }
                    511:        break;
1.1.1.7   root      512:     case 9:
1.1.1.5   root      513:        if (ciaacrb & 0x80) {
1.1       root      514:            ciaaalarm = (ciaaalarm & ~0xff00) | (val << 8);
                    515:        } else {
                    516:            ciaatod = (ciaatod & ~0xff00) | (val << 8);
                    517:            ciaatodon = 0;
                    518:        }
                    519:        break;
1.1.1.7   root      520:     case 10:
1.1.1.5   root      521:        if (ciaacrb & 0x80) {
1.1       root      522:            ciaaalarm = (ciaaalarm & ~0xff0000) | (val << 16);
                    523:        } else {
                    524:            ciaatod = (ciaatod & ~0xff0000) | (val << 16);
                    525:            ciaatodon = 0;
                    526:        }
                    527:        break;
1.1.1.7   root      528:     case 12:
1.1       root      529:        ciaasdr = val; break;
1.1.1.7   root      530:     case 13:
1.1       root      531:        setclr(&ciaaimask,val); break; /* ??? call RethinkICR() ? */
1.1.1.7   root      532:     case 14:
1.1       root      533:        CIA_update();
                    534:        ciaacra = val;
1.1.1.5   root      535:        if (ciaacra & 0x10) {
1.1       root      536:            ciaacra &= ~0x10;
                    537:            ciaata = ciaala;
                    538:        }
                    539:        if (ciaacra & 0x40) {
                    540:            kback = 1;
                    541:        }
                    542:        CIA_calctimers();
                    543:        break;
1.1.1.7   root      544:     case 15:
1.1       root      545:        CIA_update();
1.1.1.3   root      546:        ciaacrb = val;
1.1.1.5   root      547:        if (ciaacrb & 0x10) {
1.1       root      548:            ciaacrb &= ~0x10;
                    549:            ciaatb = ciaalb;
                    550:        }
                    551:        CIA_calctimers();
                    552:        break;
                    553:     }
                    554: }
                    555: 
1.1.1.3   root      556: static void WriteCIAB(uae_u16 addr,uae_u8 val)
1.1       root      557: {
1.1.1.3   root      558:     int oldval;
1.1.1.5   root      559:     switch(addr & 0xf) {
1.1.1.7   root      560:     case 0:
1.1.1.3   root      561:        if (currprefs.use_serial) {
1.1.1.7   root      562:            oldval = ciabpra;
                    563:            ciabpra  = serial_writestatus(oldval,val);
1.1.1.3   root      564:        } else
1.1.1.7   root      565:            ciabpra  = val;
1.1.1.3   root      566:        break;
1.1.1.7   root      567:     case 1:
1.1       root      568:        ciabprb = val; DISK_select(val); break;
1.1.1.7   root      569:     case 2:
1.1       root      570:        ciabdra = val; break;
1.1.1.7   root      571:     case 3:
1.1       root      572:        ciabdrb = val; break;
1.1.1.7   root      573:     case 4:
1.1       root      574:        CIA_update();
                    575:        ciabla = (ciabla & 0xff00) | val;
                    576:        CIA_calctimers();
                    577:        break;
1.1.1.7   root      578:     case 5:
1.1       root      579:        CIA_update();
                    580:        ciabla = (ciabla & 0xff) | (val << 8);
1.1.1.3   root      581:        if ((ciabcra & 1) == 0)
1.1       root      582:            ciabta = ciabla;
                    583:        if (ciabcra & 8) {
1.1.1.3   root      584:            ciabta = ciabla;
                    585:            ciabcra |= 1;
                    586:        }
1.1       root      587:        CIA_calctimers();
                    588:        break;
1.1.1.7   root      589:     case 6:
1.1       root      590:        CIA_update();
                    591:        ciablb = (ciablb & 0xff00) | val;
                    592:        CIA_calctimers();
                    593:        break;
1.1.1.7   root      594:     case 7:
1.1       root      595:        CIA_update();
                    596:        ciablb = (ciablb & 0xff) | (val << 8);
                    597:        if ((ciabcrb & 1) == 0)
                    598:            ciabtb = ciablb;
                    599:        if (ciabcrb & 8) {
                    600:            ciabtb = ciablb;
                    601:            ciabcrb |= 1;
                    602:        }
                    603:        CIA_calctimers();
                    604:        break;
1.1.1.7   root      605:     case 8:
1.1.1.5   root      606:        if (ciabcrb & 0x80) {
1.1       root      607:            ciabalarm = (ciabalarm & ~0xff) | val;
                    608:        } else {
                    609:            ciabtod = (ciabtod & ~0xff) | val;
                    610:            ciabtodon = 1;
                    611:        }
                    612:        break;
1.1.1.7   root      613:     case 9:
1.1.1.5   root      614:        if (ciabcrb & 0x80) {
1.1       root      615:            ciabalarm = (ciabalarm & ~0xff00) | (val << 8);
                    616:        } else {
                    617:            ciabtod = (ciabtod & ~0xff00) | (val << 8);
                    618:            ciabtodon = 0;
                    619:        }
                    620:        break;
1.1.1.7   root      621:     case 10:
1.1.1.5   root      622:        if (ciabcrb & 0x80) {
1.1       root      623:            ciabalarm = (ciabalarm & ~0xff0000) | (val << 16);
                    624:        } else {
                    625:            ciabtod = (ciabtod & ~0xff0000) | (val << 16);
                    626:            ciabtodon = 0;
                    627:        }
                    628:        break;
1.1.1.7   root      629:     case 12:
1.1.1.3   root      630:        ciabsdr = val;
1.1       root      631:        break;
1.1.1.7   root      632:     case 13:
1.1.1.3   root      633:        setclr(&ciabimask,val);
1.1       root      634:        break;
1.1.1.7   root      635:     case 14:
1.1       root      636:        CIA_update();
                    637:        ciabcra = val;
1.1.1.5   root      638:        if (ciabcra & 0x10) {
1.1       root      639:            ciabcra &= ~0x10;
                    640:            ciabta = ciabla;
                    641:        }
                    642:        CIA_calctimers();
                    643:        break;
1.1.1.7   root      644:     case 15:
1.1       root      645:        CIA_update();
1.1.1.3   root      646:        ciabcrb = val;
1.1.1.5   root      647:        if (ciabcrb & 0x10) {
1.1       root      648:            ciabcrb &= ~0x10;
                    649:            ciabtb = ciablb;
                    650:        }
                    651:        CIA_calctimers();
                    652:        break;
                    653:     }
                    654: }
                    655: 
                    656: void CIA_reset(void)
                    657: {
                    658:     kback = 1;
                    659:     kbstate = 0;
1.1.1.3   root      660: 
1.1       root      661:     ciaatlatch = ciabtlatch = 0;
1.1.1.3   root      662:     ciaapra = 3;
1.1       root      663:     ciaatod = ciabtod = 0; ciaatodon = ciabtodon = 0;
                    664:     ciaaicr = ciabicr = ciaaimask = ciabimask = 0;
                    665:     ciaacra = ciaacrb = ciabcra = ciabcrb = 0x4; /* outmode = toggle; */
                    666:     ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF;
                    667:     div10 = 0;
                    668:     lastdiv10 = 0;
                    669:     CIA_calctimers();
1.1.1.2   root      670:     ciabpra = 0x8C;
1.1.1.3   root      671:     if (! ersatzkickfile)
                    672:        map_banks(&kickmem_bank, 0, 32);
                    673: 
                    674:     if (currprefs.use_serial) serial_dtr_off(); /* Drop DTR at reset */
1.1       root      675: }
                    676: 
                    677: void dumpcia(void)
                    678: {
                    679:     printf("A: CRA: %02x, CRB: %02x, IMASK: %02x, TOD: %08lx %7s TA: %04lx, TB: %04lx\n",
1.1.1.3   root      680:           (int)ciaacra, (int)ciaacrb, (int)ciaaimask, ciaatod,
1.1       root      681:           ciaatlatch ? " latched" : "", ciaata, ciaatb);
                    682:     printf("B: CRA: %02x, CRB: %02x, IMASK: %02x, TOD: %08lx %7s TA: %04lx, TB: %04lx\n",
1.1.1.3   root      683:           (int)ciabcra, (int)ciabcrb, (int)ciabimask, ciabtod,
1.1       root      684:           ciabtlatch ? " latched" : "", ciabta, ciabtb);
                    685: }
                    686: 
                    687: /* CIA memory access */
                    688: 
1.1.1.3   root      689: static uae_u32 cia_lget (uaecptr) REGPARAM;
                    690: static uae_u32 cia_wget (uaecptr) REGPARAM;
                    691: static uae_u32 cia_bget (uaecptr) REGPARAM;
                    692: static void cia_lput (uaecptr, uae_u32) REGPARAM;
                    693: static void cia_wput (uaecptr, uae_u32) REGPARAM;
                    694: static void cia_bput (uaecptr, uae_u32) REGPARAM;
1.1       root      695: 
                    696: addrbank cia_bank = {
                    697:     cia_lget, cia_wget, cia_bget,
                    698:     cia_lput, cia_wput, cia_bput,
                    699:     default_xlate, default_check
                    700: };
                    701: 
1.1.1.3   root      702: uae_u32 REGPARAM2 cia_lget (uaecptr addr)
1.1       root      703: {
1.1.1.9 ! root      704:     special_mem |= S_READ;
        !           705:     return cia_bget (addr + 3);
1.1       root      706: }
                    707: 
1.1.1.3   root      708: uae_u32 REGPARAM2 cia_wget (uaecptr addr)
1.1       root      709: {
1.1.1.9 ! root      710:     special_mem |= S_READ;
        !           711:     return cia_bget (addr + 1);
1.1       root      712: }
                    713: 
1.1.1.3   root      714: uae_u32 REGPARAM2 cia_bget (uaecptr addr)
1.1       root      715: {
1.1.1.9 ! root      716:     special_mem |= S_READ;
1.1       root      717:     if ((addr & 0x3001) == 0x2001)
1.1.1.3   root      718:        return ReadCIAA((addr & 0xF00) >> 8);
1.1       root      719:     if ((addr & 0x3001) == 0x1000)
1.1.1.3   root      720:        return ReadCIAB((addr & 0xF00) >> 8);
1.1       root      721:     return 0;
                    722: }
                    723: 
1.1.1.3   root      724: void REGPARAM2 cia_lput (uaecptr addr, uae_u32 value)
1.1       root      725: {
1.1.1.9 ! root      726:     special_mem |= S_WRITE;
        !           727:     cia_bput (addr + 3, value); /* FIXME ? */
1.1       root      728: }
                    729: 
1.1.1.3   root      730: void REGPARAM2 cia_wput (uaecptr addr, uae_u32 value)
1.1       root      731: {
1.1.1.9 ! root      732:     special_mem |= S_WRITE;
        !           733:     cia_bput (addr + 1, value);
1.1       root      734: }
                    735: 
1.1.1.3   root      736: void REGPARAM2 cia_bput (uaecptr addr, uae_u32 value)
1.1       root      737: {
1.1.1.9 ! root      738:     special_mem |= S_WRITE;
1.1       root      739:     if ((addr & 0x3001) == 0x2001)
1.1.1.9 ! root      740:        WriteCIAA ((addr & 0xF00) >> 8, value);
1.1       root      741:     if ((addr & 0x3001) == 0x1000)
1.1.1.9 ! root      742:        WriteCIAB ((addr & 0xF00) >> 8, value);
1.1       root      743: }
                    744: 
                    745: /* battclock memory access */
                    746: 
1.1.1.3   root      747: static uae_u32 clock_lget (uaecptr) REGPARAM;
                    748: static uae_u32 clock_wget (uaecptr) REGPARAM;
                    749: static uae_u32 clock_bget (uaecptr) REGPARAM;
                    750: static void clock_lput (uaecptr, uae_u32) REGPARAM;
                    751: static void clock_wput (uaecptr, uae_u32) REGPARAM;
                    752: static void clock_bput (uaecptr, uae_u32) REGPARAM;
1.1       root      753: 
                    754: addrbank clock_bank = {
                    755:     clock_lget, clock_wget, clock_bget,
                    756:     clock_lput, clock_wput, clock_bput,
                    757:     default_xlate, default_check
                    758: };
                    759: 
1.1.1.3   root      760: uae_u32 REGPARAM2 clock_lget (uaecptr addr)
1.1       root      761: {
1.1.1.9 ! root      762:     special_mem |= S_READ;
        !           763:     return clock_bget (addr + 3);
1.1       root      764: }
                    765: 
1.1.1.3   root      766: uae_u32 REGPARAM2 clock_wget (uaecptr addr)
1.1       root      767: {
1.1.1.9 ! root      768:     special_mem |= S_READ;
        !           769:     return clock_bget (addr + 1);
1.1       root      770: }
                    771: 
1.1.1.3   root      772: uae_u32 REGPARAM2 clock_bget (uaecptr addr)
1.1       root      773: {
1.1.1.9 ! root      774:     time_t t = time(0);
1.1       root      775:     struct tm *ct;
1.1.1.9 ! root      776: 
        !           777:     ct = localtime (&t);
        !           778:     special_mem |= S_READ;
        !           779: 
1.1.1.7   root      780:     switch (addr & 0x3f) {
                    781:     case 0x03: return ct->tm_sec % 10;
                    782:     case 0x07: return ct->tm_sec / 10;
                    783:     case 0x0b: return ct->tm_min % 10;
                    784:     case 0x0f: return ct->tm_min / 10;
                    785:     case 0x13: return ct->tm_hour % 10;
                    786:     case 0x17: return ct->tm_hour / 10;
                    787:     case 0x1b: return ct->tm_mday % 10;
                    788:     case 0x1f: return ct->tm_mday / 10;
                    789:     case 0x23: return (ct->tm_mon+1) % 10;
                    790:     case 0x27: return (ct->tm_mon+1) / 10;
                    791:     case 0x2b: return ct->tm_year % 10;
                    792:     case 0x2f: return ct->tm_year / 10;
                    793: 
                    794:     case 0x33: return ct->tm_wday;  /*Hack by -=SR=- */
                    795:     case 0x37: return clock_control_d;
                    796:     case 0x3b: return clock_control_e;
                    797:     case 0x3f: return clock_control_f;
1.1       root      798:     }
                    799:     return 0;
                    800: }
                    801: 
1.1.1.3   root      802: void REGPARAM2 clock_lput (uaecptr addr, uae_u32 value)
1.1       root      803: {
1.1.1.9 ! root      804:     special_mem |= S_WRITE;
1.1       root      805:     /* No way */
                    806: }
                    807: 
1.1.1.3   root      808: void REGPARAM2 clock_wput (uaecptr addr, uae_u32 value)
1.1       root      809: {
1.1.1.9 ! root      810:     special_mem |= S_WRITE;
1.1       root      811:     /* No way */
                    812: }
                    813: 
1.1.1.3   root      814: void REGPARAM2 clock_bput (uaecptr addr, uae_u32 value)
1.1       root      815: {
1.1.1.9 ! root      816:     special_mem |= S_WRITE;
1.1.1.7   root      817:     switch (addr & 0x3f) {
1.1.1.9 ! root      818:     case 0x37: clock_control_d = value; break;
        !           819:     case 0x3b: clock_control_e = value; break;
        !           820:     case 0x3f: clock_control_f = value; break;
1.1       root      821:     }
                    822: }

unix.superglobalmegacorp.com

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