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

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

unix.superglobalmegacorp.com

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