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

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

unix.superglobalmegacorp.com

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