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

unix.superglobalmegacorp.com

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