Annotation of previous/src/rtcnvram.c, revision 1.1.1.1

1.1       root        1: /*  Previous - rtcnvram.c
                      2:  
                      3:  This file is distributed under the GNU Public License, version 2 or at
                      4:  your option any later version. Read the file gpl.txt for details.
                      5:  
                      6:  Emulation of Real Time Clock including NVRAM.
                      7:  
                      8:  Old systems use MC68HC68T1 chip, new systems use MCCS1850 chip.
                      9: 
                     10:  */
                     11: 
                     12: #include "ioMem.h"
                     13: #include "ioMemTables.h"
                     14: #include "m68000.h"
                     15: #include "configuration.h"
                     16: #include "dimension.h"
                     17: #include "sysReg.h"
                     18: #include "rtcnvram.h"
                     19: 
                     20: #include <time.h>
                     21: 
                     22: 
                     23: #define LOG_RTC_LEVEL   LOG_WARN
                     24: 
                     25: 
                     26: /* RTC interface */
                     27: #define RTC_ADDR_WRITE  0x80
                     28: #define RTC_ADDR_CLOCK  0x20
                     29: #define RTC_ADDR_MASK   0x7F
                     30: Uint8 rtc_addr = 0;
                     31: Uint8 rtc_val = 0;
                     32: int phase = 0;
                     33: bool freeze = false;
                     34: 
                     35: int oldrtc_interface_io(Uint8 rtdatabit);
                     36: int newrtc_interface_io(Uint8 rtdatabit);
                     37: 
                     38: int rtc_interface_io(Uint8 rtdatabit) {
                     39:     switch (ConfigureParams.System.nRTC) {
                     40:         case MC68HC68T1: return oldrtc_interface_io(rtdatabit);
                     41:         case MCCS1850: return newrtc_interface_io(rtdatabit);
                     42:         default:
                     43:             Log_Printf(LOG_WARN, "[RTC] error: no I/O function for this chip!");
                     44:             return oldrtc_interface_io(rtdatabit); /* trying old chip */
                     45:     }
                     46: }
                     47: 
                     48: void rtc_interface_reset(void) {
                     49:     phase = 0;
                     50:     rtc_addr = 0;
                     51:     rtc_val = 0;
                     52:     freeze = false;
                     53: }
                     54: 
                     55: 
                     56: /* RTC power down request */
                     57: void oldrtc_request_power_down(void);
                     58: void newrtc_request_power_down(void);
                     59: 
                     60: void oldrtc_stop_pdown_request(void);
                     61: void newrtc_stop_pdown_request(void);
                     62: 
                     63: void rtc_request_power_down(void) {
                     64:     switch (ConfigureParams.System.nRTC) {
                     65:         case MC68HC68T1: oldrtc_request_power_down(); return;
                     66:         case MCCS1850: newrtc_request_power_down(); return;
                     67:         default:
                     68:             Log_Printf(LOG_WARN, "[RTC] error: no power down function for this chip!");
                     69:             oldrtc_request_power_down(); return; /* trying old chip */
                     70:     }
                     71: }
                     72: 
                     73: void rtc_stop_pdown_request(void) {
                     74:     switch (ConfigureParams.System.nRTC) {
                     75:         case MC68HC68T1: oldrtc_stop_pdown_request(); return;
                     76:         case MCCS1850: newrtc_stop_pdown_request(); return;
                     77:         default:
                     78:             Log_Printf(LOG_WARN, "[RTC] error: no power down function for this chip!");
                     79:             oldrtc_stop_pdown_request(); return; /* trying old chip */
                     80:     }
                     81: }
                     82: 
                     83: 
                     84: 
                     85: /* --------------------- MC68HC68T1 --------------------- */
                     86: 
                     87: /* RTC NVRAM is located at address 0x00 to 0x1F (32 bytes),
                     88:  * time registers, alarm registers and control/status
                     89:  * registers are located at address 0x20 to 0x32.
                     90:  */
                     91: 
                     92: Uint8 rtc_get_clock(Uint8 addr);
                     93: void rtc_put_clock(Uint8 addr, Uint8 val);
                     94: 
                     95: /* All time values in RTC clock are in packed decimal format */
                     96: 
                     97: typedef struct {
                     98:     Uint8 sec;      /* 00 - 59 */
                     99:     Uint8 min;      /* 00 - 59 */
                    100:     Uint8 hour;     /* 01 - 12 or 00 - 24; bit 7: 1 = 12 hr, 0 = 24 hr; bit 5: 1 = pm, 0 = am */
                    101:     Uint8 wday;     /* 01 - 07; 1 = sunday */
                    102:     Uint8 mday;     /* 01 - 31 */
                    103:     Uint8 month;    /* 01 - 12; 1 = january */
                    104:     Uint8 year;     /* 00 - 99 */
                    105: } RTC_TIME;
                    106: 
                    107: RTC_TIME get_rtc_time(void);
                    108: 
                    109: typedef struct {
                    110:     Uint8 sec;      /* 00 - 59 */
                    111:     Uint8 min;      /* 00 - 59 */
                    112:     Uint8 hour;     /* 01 - 12 or 00 - 24; bit 5: 1 = pm, 0 = am in 24 hr mode */
                    113: } RTC_ALARM;
                    114: 
                    115: 
                    116: /* There are 3 status and control registers inside the chip */
                    117: 
                    118: /* RTC Status Register at 0x30 (r only)
                    119:  *
                    120:  * 0-0- ----    always 0 (0 in bit 7 identifies MC68HC68T1 chip)
                    121:  * -x-- ----    watchdog detected cpu failure
                    122:  * ---x ----    first time up
                    123:  * ---- x---    interrupt true (one of following interrupts is valid)
                    124:  * ---- -x--    power sense interrupt
                    125:  * ---- --x-    alarm interrupt
                    126:  * ---- ---x    clock interrupt
                    127:  */
                    128: 
                    129: #define RTC_CPUFAIL     0x40
                    130: #define RTC_FIRSTUP     0x10
                    131: #define RTC_INT         0x08
                    132: #define RTC_INT_SENSE   0x04
                    133: #define RTC_INT_ALARM   0x02
                    134: #define RTC_INT_CLOCK   0x01
                    135: 
                    136: 
                    137: /* RTC Clock Control Register at 0x31 (r) or 0xB1 (w)
                    138:  *
                    139:  * x--- ----    1 = start, 0 = stop counter
                    140:  * -x-- ----    1 = enable line input, 0 = enable chrystal input
                    141:  * --xx ----    chrystal select: 0 = 4.194304 MHz, 1 = 2.097152, 2 = 1.048576, 3 = 32.768 kHz
                    142:  * ---- x---    1 = line input 50 Hz, 0 = line input 60 Hz
                    143:  * ---- -xxx    clock out frequency:
                    144:  *
                    145:  * 0 = chrystal
                    146:  * 1 = chrystal/2
                    147:  * 2 = chrystal/4
                    148:  * 3 = chrystal/8
                    149:  * 4 = disable
                    150:  * 5 = 1 Hz
                    151:  * 6 = 2 Hz
                    152:  * 7 = 50/60 Hz for line operation; 64 Hz for chrystal operation
                    153:  */
                    154: 
                    155: #define RTC_START   0x80
                    156: #define RTC_STOP    0x00
                    157: #define RTC_LINE    0x40
                    158: #define RTC_XTAL    0x30
                    159: #define RTC_L50HZ   0x08
                    160: #define RTC_FREQ    0x07
                    161: 
                    162: 
                    163: /* RTC Interrupt Control Register at 0x32 (r) or 0xB2 (w)
                    164:  *
                    165:  * x--- ----    watchdog enable
                    166:  * -x-- ----    initiate power down
                    167:  * --x- ----    power sense
                    168:  * ---x ----    enable alarm
                    169:  * ---- xxxx    select frequency of periodic interrupt:
                    170:  *
                    171:  * 0 = diable
                    172:  * chrystal:
                    173:  * 1 = 2048 Hz, 2 = 1024 Hz, ... , C = 1 Hz
                    174:  * D = 1 per min, E = 1 per hour, F = 1 per day
                    175:  * line:
                    176:  * 6 = 50 or 60 Hz, B = 2 Hz, C = 1 Hz
                    177:  * D = 1 per min, E = 1 per hour, F = 1 per day
                    178:  */
                    179: 
                    180: #define RTC_WATCHDOG    0x80
                    181: #define RTC_POWERDOWN   0x40
                    182: #define RTC_PWRSENSE    0x20
                    183: #define RTC_ENABLEALRM  0x10
                    184: #define RTC_PERIODIC    0x0F
                    185: 
                    186: struct {
                    187:     Uint8 ram[32];      /* 0x00 - 0x1F (r), 0x80 - 0x9F (w) */
                    188:     RTC_TIME time;      /* 0x20 - 0x26 (r), 0xA0 - 0xA6 (w) */
                    189:     RTC_ALARM alarm;    /* 0xA8 - 0xAA (w) */
                    190:     Uint8 status;       /* 0x30 (r) */
                    191:     Uint8 clkctrl;      /* 0x31 (r), 0xB1 (w) */
                    192:     Uint8 intctrl;      /* 0x32 (r), 0xB2 (w) */
                    193: } rtc;
                    194: 
                    195: 
                    196: int oldrtc_interface_io(Uint8 rtdatabit) {
                    197:     
                    198:     phase++;
                    199:     
                    200:     if (phase<=8) {
                    201:         rtc_addr = (rtc_addr<<1)|(rtdatabit?1:0);
                    202:     } else {
                    203:         
                    204:         if (phase==9) {
                    205:             if (!(rtc_addr&RTC_ADDR_WRITE)) {
                    206:                 if (rtc_addr&RTC_ADDR_CLOCK) {
                    207:                     rtc_val = rtc_get_clock(rtc_addr);
                    208:                 } else {
                    209:                     rtc_val = rtc.ram[rtc_addr&RTC_ADDR_MASK];
                    210:                 }
                    211:                 
                    212:                 Log_Printf(LOG_RTC_LEVEL,"[RTC] reading val $%02X from addr $%02X at PC=$%08x\n",
                    213:                            rtc_val,rtc_addr,m68k_getpc());
                    214:             }
                    215:         }
                    216:         
                    217:         if (rtc_addr&RTC_ADDR_WRITE) {
                    218:             rtc_val = (rtc_val<<1)|(rtdatabit?1:0);
                    219:         } else {
                    220:             rtdatabit = (rtc_val&(1<<(16-phase)))?1:0;
                    221:         }
                    222:         
                    223:         if (phase==16) {
                    224:             if (rtc_addr&RTC_ADDR_WRITE) {
                    225:                 Log_Printf(LOG_RTC_LEVEL,"[RTC] writing val $%02X to addr $%02X at PC=$%08x\n",
                    226:                            rtc_val,rtc_addr,m68k_getpc());
                    227:                 
                    228:                 if (rtc_addr&RTC_ADDR_CLOCK) {
                    229:                     rtc_put_clock(rtc_addr, rtc_val);
                    230:                 } else {
                    231:                     rtc.ram[rtc_addr&RTC_ADDR_MASK] = rtc_val;
                    232:                 }
                    233:             }
                    234:             
                    235:             switch (rtc_addr) {
                    236:                 case 0x1F:
                    237:                 case 0x9F: rtc_addr = 0x00; break;
                    238:                 case 0x32:
                    239:                 case 0xB2: rtc_addr = 0x20; break;
                    240:                 default: rtc_addr++; break;
                    241:             }
                    242:             phase-=8;
                    243:         }
                    244:     }
                    245:     
                    246:     /* RTC returns 0 or 1 */
                    247:     return rtdatabit;
                    248: }
                    249: 
                    250: RTC_TIME my_get_rtc_time(void);
                    251: 
                    252: Uint8 rtc_get_clock(Uint8 addr) {
                    253:     Uint8 val = 0x00;
                    254:     
                    255: //    if (!freeze) {
                    256:         rtc.time = my_get_rtc_time();
                    257:         freeze = true;
                    258: //    }
                    259:     
                    260:     switch (rtc_addr&RTC_ADDR_MASK) {
                    261:         case 0x20: /* seconds */
                    262:             val = rtc.time.sec; break;
                    263:         case 0x21: /* minutes */
                    264:             val = rtc.time.min; break;
                    265:         case 0x22: /* hours */
                    266:             val = rtc.time.hour; break;
                    267:         case 0x23: /* day of week (sunday = 1) */
                    268:             val = rtc.time.wday; break;
                    269:         case 0x24: /* day of month */
                    270:             val = rtc.time.mday; break;
                    271:         case 0x25: /* month */
                    272:             val = rtc.time.month; break;
                    273:         case 0x26: /* year (0 - 99) */
                    274:             val = rtc.time.year ; break;            
                    275:         case 0x30: /* status register */
                    276:             val = rtc.status;
                    277:             rtc.status &= RTC_INT_SENSE;
                    278:             break;
                    279:         case 0x31: /* clock control register */
                    280:             val = rtc.clkctrl; break;
                    281:         case 0x32: /* interrupt control register */
                    282:             val = rtc.intctrl; break;
                    283:             
                    284:         default: break;
                    285:     }
                    286:     
                    287:     return val;
                    288: }
                    289: 
                    290: void my_set_rtc_time(int which,int val);
                    291: 
                    292: void rtc_put_clock(Uint8 addr, Uint8 val) {
                    293:     switch (rtc_addr&RTC_ADDR_MASK) {
                    294:         case 0x20: /* seconds */
                    295:                my_set_rtc_time(0,val);
                    296:                break;
                    297:         case 0x21: /* minutes */
                    298:                my_set_rtc_time(1,val);
                    299:                break;
                    300:         case 0x22: /* hours */
                    301:                my_set_rtc_time(2,val);
                    302:                break;
                    303:         case 0x23: /* day of week (sunday = 1) */
                    304:                break;
                    305:         case 0x24: /* day of month */
                    306:                my_set_rtc_time(3,val);
                    307:                break;
                    308:         case 0x25: /* month */
                    309:                my_set_rtc_time(4,val);
                    310:                break;
                    311:         case 0x26: /* year (0 - 99) */
                    312:                my_set_rtc_time(5,val);
                    313:                break;
                    314:             
                    315:         case 0x28: /* alarm: seconds */
                    316:         case 0x29: /* alarm: minutes */
                    317:         case 0x2A: /* alarm: hours */
                    318:                Log_Printf(LOG_WARN,"Trying to program alarm (not implemented) %x",val);
                    319:             break; /* not yet! */
                    320:             
                    321:         case 0x31: /* clock control register */
                    322:             rtc.clkctrl = val;
                    323:             break;
                    324:         case 0x32: /* interrupt control register */
                    325:             rtc.intctrl = val;
                    326:             if (rtc.intctrl&RTC_POWERDOWN) {
                    327:                 Log_Printf(LOG_WARN, "[RTC] Power down!");
                    328:                 M68000_Stop();
                    329:             }
                    330:             break;
                    331:             
                    332:         default: break;
                    333:     }
                    334: }
                    335: 
                    336: time_t time_offset=0;
                    337: 
                    338: RTC_TIME my_get_rtc_time(void) {
                    339:     RTC_TIME rt;
                    340:     
                    341:     time_t tmp = time(NULL) + time_offset;
                    342:     struct tm t =*localtime(&tmp);
                    343:     
                    344:     rt.sec = (((t.tm_sec/10)%10)<<4)|(t.tm_sec%10);
                    345:     rt.min = (((t.tm_min/10)%10)<<4)|(t.tm_min%10);
                    346:     rt.hour = (((t.tm_hour/10)%10)<<4)|(t.tm_hour%10);
                    347:     rt.wday = t.tm_wday+1;
                    348:     rt.mday = (((t.tm_mday/10)%10)<<4)|(t.tm_mday%10);
                    349:     rt.month = ((((t.tm_mon+1)/10)%10)<<4)|((t.tm_mon+1)%10);
                    350:     rt.year = (((t.tm_year/10)%10)<<4)|(t.tm_year%10);
                    351:     
                    352:     return rt;
                    353: }
                    354: 
                    355: void my_set_rtc_time(int which,int val) {
                    356:     RTC_TIME rt;
                    357:     
                    358:     time_t tmp = time(NULL);
                    359:     time_t tmp2;
                    360: 
                    361:     static struct tm t;
                    362: 
                    363:     t.tm_wday=0;
                    364: 
                    365:     val=((val&0xF0)>>4)*10+(val&0xF);
                    366: 
                    367:     switch (which) {
                    368:        /* sec */
                    369:        case 0:
                    370:                t.tm_sec=val;
                    371:                break;
                    372:        case 1:
                    373:                t.tm_min=val;
                    374:                break;
                    375:        case 2:
                    376:                t.tm_hour=val;
                    377:                break;
                    378:        case 3:
                    379:                t.tm_mday=val;
                    380:                break;
                    381:        case 4:
                    382:                t.tm_mon=val-1;
                    383:                break;
                    384:        case 5:
                    385:                t.tm_year=val;
                    386:                break;
                    387:        }
                    388:        
                    389:        Log_Printf(LOG_WARN,"setting %d to %x",which,val);
                    390: 
                    391:        tmp2=mktime(&t);
                    392:        
                    393:        if (tmp2!=0) {
                    394:                time_offset=tmp-tmp2;
                    395:                Log_Printf(LOG_WARN,"Offset is %d",time_offset);
                    396:        }     
                    397: }
                    398: 
                    399: void oldrtc_request_power_down(void) {
                    400:     set_interrupt(INT_POWER, SET_INT);
                    401: }
                    402: 
                    403: void oldrtc_stop_pdown_request(void) {
                    404:     set_interrupt(INT_POWER, RELEASE_INT);
                    405: }
                    406: 
                    407: 
                    408: /* ------------------------- MCCS1850 ------------------------- */
                    409: 
                    410: /* RTC NVRAM (64 bytes) is located at address 0x00 to 0x1F
                    411:  * and 0x40 to 0x5F, time registers, alarm registers and 
                    412:  * control/status registers are located at address 0x20 to 0x31.
                    413:  */
                    414: 
                    415: Uint8 newrtc_get_clock(Uint8 addr);
                    416: void newrtc_put_clock(Uint8 addr, Uint8 val);
                    417: 
                    418: /* New RTC has two 32 bit counters, one for time and one for alarm */
                    419: 
                    420: /* There are 3 status and control registers inside the chip */
                    421: 
                    422: /* RTC Status Register at 0x30 (r only)
                    423:  *
                    424:  * 1--- ----    always 1 (identifies MCCS1850 chip)
                    425:  * -0-- ----    always 0
                    426:  * --x- ----    test mode status
                    427:  * ---x ----    first time up
                    428:  * ---- x---    interrupt true (one of following interrupts is valid)
                    429:  * ---- -x--    low battery interrupt
                    430:  * ---- --x-    alarm interrupt
                    431:  * ---- ---x    power down interrupt
                    432:  */
                    433: 
                    434: #define NRTC_NEWCHIP    0x80
                    435: #define NRTC_TMODE      0x20
                    436: #define NRTC_FIRSTUP    0x10
                    437: #define NRTC_INT        0x08
                    438: #define NRTC_INT_LBAT   0x04
                    439: #define NRTC_INT_ALARM  0x02
                    440: #define NRTC_INT_PDOWN  0x01
                    441: 
                    442: 
                    443: /* RTC Control Register at 0x31 (r) or 0xB1 (w)
                    444:  *
                    445:  * x--- ----    1 = start, 0 = stop counter
                    446:  * -x-- ----    initiate power down
                    447:  * --x- ----    enable auto restart sequence
                    448:  * ---x ----    enable alarm
                    449:  * ---- x---    alarm clear (clear alarm int bit in status)
                    450:  * ---- -x--    first time up clear (clear first up bit in status)
                    451:  * ---- --x-    enable low battery interrupting
                    452:  * ---- ---x    request power down clear (clear power down int bit in status)
                    453:  *
                    454:  * ---- xx-x    always read as 0
                    455:  */
                    456: 
                    457: #define NRTC_CTRL_0     0x0D
                    458: 
                    459: #define NRTC_START      0x80
                    460: #define NRTC_STOP       0x00
                    461: #define NRTC_POWERDOWN  0x40
                    462: #define NRTC_AR         0x20
                    463: #define NRTC_ENABLEALRM 0x10
                    464: #define NRTC_CLRALARM   0x08
                    465: #define NRTC_CLRFTU     0x04
                    466: #define NRTC_LBE        0x02
                    467: #define NRTC_CLRPDOWN   0x01
                    468: 
                    469: 
                    470: struct {
                    471:     /* --> see old chip  * 0x00 - 0x1F (r), 0x80 - 0x9F (w) */
                    472:     Uint32 timecntr;    /* 0x20 - 0x23 (r), 0xA0 - 0xA3 (w) */
                    473:     Uint32 alarmcntr;   /* 0x24 - 0x27 (r), 0xA4 - 0xA7 (w) */
                    474:     Uint8 status;       /* 0x30 (r) */
                    475:     Uint8 control;      /* 0x31 (r), 0xB1 (w) */
                    476:     Uint8 ram2[32];     /* 0x40 - 0x5F (r), 0xC0 - 0xDF (w) */
                    477: } newrtc;
                    478: 
                    479: #define RTC_ADDR_NEWRAM 0x40
                    480: 
                    481: int newrtc_interface_io(Uint8 rtdatabit) {
                    482:     
                    483:     phase++;
                    484:     
                    485:     if (phase<=8) {
                    486:         rtc_addr = (rtc_addr<<1)|(rtdatabit?1:0);
                    487:     } else {
                    488:         
                    489:         if (phase==9) {
                    490:             if (!(rtc_addr&RTC_ADDR_WRITE)) {
                    491:                 if (rtc_addr&RTC_ADDR_CLOCK) {
                    492:                     rtc_val = newrtc_get_clock(rtc_addr);
                    493:                 } else {
                    494:                     if (rtc_addr&RTC_ADDR_NEWRAM) {
                    495:                         rtc_val = newrtc.ram2[rtc_addr&0x1F];
                    496:                     } else {
                    497:                         rtc_val = rtc.ram[rtc_addr&0x1F];
                    498:                     }
                    499:                 }
                    500:                 
                    501:                 Log_Printf(LOG_RTC_LEVEL,"[newRTC] reading val $%02X from addr $%02X at PC=$%08x\n",
                    502:                            rtc_val,rtc_addr,m68k_getpc());
                    503:             }
                    504:         }
                    505:         
                    506:         if (rtc_addr&RTC_ADDR_WRITE) {
                    507:             rtc_val = (rtc_val<<1)|(rtdatabit?1:0);
                    508:         } else {
                    509:             rtdatabit = (rtc_val&(1<<(16-phase)))?1:0;
                    510:         }
                    511:         
                    512:         if (phase==16) {
                    513:             if (rtc_addr&RTC_ADDR_WRITE) {
                    514:                 Log_Printf(LOG_RTC_LEVEL,"[newRTC] writing val $%02X to addr $%02X at PC=$%08x\n",
                    515:                            rtc_val,rtc_addr,m68k_getpc());
                    516:                 
                    517:                 if (rtc_addr&RTC_ADDR_CLOCK) {
                    518:                     newrtc_put_clock(rtc_addr, rtc_val);
                    519:                 } else {
                    520:                     if (rtc_addr&RTC_ADDR_NEWRAM) {
                    521:                         newrtc.ram2[rtc_addr&0x1F] = rtc_val;
                    522:                     } else {
                    523:                         rtc.ram[rtc_addr&0x1F] = rtc_val;
                    524:                     }
                    525:                 }
                    526:             }
                    527:             
                    528:             switch (rtc_addr) {
                    529:                 case 0x7F: rtc_addr = 0x00; break;
                    530:                 case 0xFF: rtc_addr = 0x80; break;
                    531:                 default: rtc_addr++; break;
                    532:             }
                    533:             phase-=8;
                    534:         }
                    535:     }
                    536:     
                    537:     /* RTC returns 0 or 1 */
                    538:     return rtdatabit;
                    539: }
                    540: 
                    541: 
                    542: Uint8 newrtc_get_clock(Uint8 addr) {
                    543:     Uint8 val = 0x00;
                    544:     
                    545:     newrtc.timecntr = time(NULL);
                    546:     
                    547:     switch (rtc_addr&RTC_ADDR_MASK) {
                    548:         case 0x20:
                    549:             val = (newrtc.timecntr>>24)&0xFF; break;
                    550:         case 0x21:
                    551:             val = (newrtc.timecntr>>16)&0xFF; break;
                    552:         case 0x22:
                    553:             val = (newrtc.timecntr>>8)&0xFF; break;
                    554:         case 0x23:
                    555:             val = newrtc.timecntr&0xFF; break;
                    556:             
                    557:         case 0x24:
                    558:             val = (newrtc.alarmcntr>>24)&0xFF; break;
                    559:         case 0x25:
                    560:             val = (newrtc.alarmcntr>>16)&0xFF; break;
                    561:         case 0x26:
                    562:             val = (newrtc.alarmcntr>>8)&0xFF; break;
                    563:         case 0x27:
                    564:             val = newrtc.alarmcntr&0xFF; break;
                    565: 
                    566:         case 0x30: /* status register */
                    567:             val = newrtc.status|NRTC_NEWCHIP;
                    568:             break;
                    569:         case 0x31: /* control register */
                    570:             val = newrtc.control&~NRTC_CTRL_0; break;
                    571:             
                    572:         default: break;
                    573:     }
                    574:     
                    575:     return val;
                    576: }
                    577: 
                    578: void newrtc_put_clock(Uint8 addr, Uint8 val) {
                    579:     switch (rtc_addr&RTC_ADDR_MASK) {
                    580:         case 0x20:
                    581:         case 0x21:
                    582:         case 0x22:
                    583:         case 0x23:
                    584:                Log_Printf(LOG_WARN,"Trying to force rtc failed (not implemented) %x",val);
                    585:             break; /* not yet! */
                    586:         case 0x24:
                    587:         case 0x25:
                    588:         case 0x26:
                    589:         case 0x27:
                    590:                Log_Printf(LOG_WARN,"Trying to force rtc failed (not implemented) %x",val);
                    591:             break; /* not yet! */
                    592:             
                    593:         case 0x31: /* control register */
                    594:             newrtc.control = val;
                    595:             if (newrtc.control&NRTC_CLRFTU) {
                    596:                 newrtc.status&= ~NRTC_FIRSTUP;
                    597:             }
                    598:             if (newrtc.control&NRTC_CLRALARM) {
                    599:                 newrtc.status&= ~NRTC_INT_ALARM;
                    600:             }
                    601:             if (newrtc.control&NRTC_CLRPDOWN) {
                    602:                 newrtc.status&= ~NRTC_INT_PDOWN;
                    603:             }
                    604:             if (newrtc.control&NRTC_POWERDOWN) {
                    605:                 Log_Printf(LOG_WARN, "[newRTC] Power down!");
                    606:                 M68000_Stop();
                    607:             }
                    608:             break;
                    609:             
                    610:         default: break;
                    611:     }
                    612: }
                    613: 
                    614: void newrtc_request_power_down(void) {
                    615:     newrtc.status |= (NRTC_INT|NRTC_INT_PDOWN);
                    616:     set_interrupt(INT_POWER, SET_INT);
                    617: }
                    618: 
                    619: void newrtc_stop_pdown_request(void) {
                    620:     set_interrupt(INT_POWER, RELEASE_INT);
                    621: }
                    622: 
                    623: 
                    624: /* ---------------------- RTC NVRAM ---------------------- */
                    625: 
                    626: // file mon/nvram.h
                    627: // struct nvram_info {
                    628: // #define     NI_RESET        9
                    629: //     u_int   ni_reset : 4,
                    630: // #define     SCC_ALT_CONS    0x08000000
                    631: //             ni_alt_cons : 1,
                    632: // #define     ALLOW_EJECT     0x04000000
                    633: //             ni_allow_eject : 1,
                    634: //             ni_vol_r : 6,
                    635: //             ni_brightness : 6,
                    636: // #define     HW_PWD  0x6
                    637: //             ni_hw_pwd : 4,
                    638: //             ni_vol_l : 6,
                    639: //             ni_spkren : 1,
                    640: //             ni_lowpass : 1,
                    641: // #define     BOOT_ANY        0x00000002
                    642: //             ni_boot_any : 1,
                    643: // #define     ANY_CMD         0x00000001
                    644: //             ni_any_cmd : 1;
                    645: // #define     NVRAM_HW_PASSWD 6
                    646: //     u_char ni_ep[NVRAM_HW_PASSWD];
                    647: // #define     ni_enetaddr     ni_ep
                    648: // #define     ni_hw_passwd    ni_ep
                    649: //     u_short ni_simm;                /* 4 SIMMs, 4 bits per SIMM */
                    650: //     char ni_adobe[2];
                    651: //     u_char ni_pot[3];
                    652: //     u_char  ni_new_clock_chip : 1,
                    653: //             ni_auto_poweron : 1,
                    654: //             ni_use_console_slot : 1,        /* Console slot was set by user. */
                    655: //             ni_console_slot : 2,            /* Preferred console dev slot>>1 */
                    656: //             ni_use_parity_mem : 1,  /* Use parity RAM if available? */
                    657: //             : 2;
                    658: // #define     NVRAM_BOOTCMD   12
                    659: //     char ni_bootcmd[NVRAM_BOOTCMD];
                    660: //     u_short ni_cksum;
                    661: // };
                    662: 
                    663: // #define     N_brightness    0
                    664: // #define     N_volume_l      1
                    665: // #define     N_volume_r      2
                    666: 
                    667: /* nominal values during self test */
                    668: // #define     BRIGHT_NOM      20
                    669: // #define     VOL_NOM         0
                    670: 
                    671: /* bits in ni_pot[0] */
                    672: #define POT_ON              0x01
                    673: #define EXTENDED_POT        0x02
                    674: #define LOOP_POT            0x04
                    675: #define VERBOSE_POT         0x08
                    676: #define TEST_DRAM_POT       0x10
                    677: #define BOOT_POT            0x20
                    678: #define TEST_MONITOR_POT    0x40
                    679: 
                    680: /* bits in byte 17 */
                    681: #define NEW_CLOCK_CHIP      0x80
                    682: #define AUTO_POWERON        0x40
                    683: #define USE_CONSOLE_SLOT    0x20
                    684: #define CONSOLE_SLOT        0x18
                    685: #define USE_PARITY_MEM      0x04
                    686: 
                    687: /* bits in ni_simm (rtc ram byte 10 and 11) *
                    688:  * -------- -----xxx bit 0 - 2: 1st simm: bit 1+2 define size, bit 3 defines page mode
                    689:  * -------- --xxx--- bit 3 - 5: 2nd simm: bit 1+2 define size, bit 3 defines page mode
                    690:  * -------x xx------ bit 6 - 8: 3rd simm: bit 1+2 define size, bit 3 defines page mode
                    691:  * ----xxx- -------- bit 9 -11: 4th simm: bit 1+2 define size, bit 3 defines page mode
                    692:  * xxxx---- -------- bit 12-15: defines parity, 1 bit for each simm (ignored on 68030)
                    693:  */
                    694: /* for 68030 and monochrome non-turbo systems */
                    695: #define SIMM_EMPTY          0x0
                    696: #define SIMM_16MB           0x1 /* Group of four 4 Mbyte SIMMs */
                    697: #define SIMM_4MB            0x2 /* Group of four 1 Mbyte SIMMs */
                    698: #define SIMM_1MB            0x3 /* Group of four 256 KByte SIMMs */
                    699: #define SIMM_PAGE_MODE      0x4 /* SIMM type is page mode, else nibble mode */
                    700: /* for all 68040 systems */
                    701: #define SIMM_PARITY         0x8 /* SIMMs support parity */
                    702: /* for non-turbo color systems */
                    703: #define SIMM_8MB_C          0x1 /* Pair of 4 Mbyte SIMMs */
                    704: #define SIMM_2MB_C          0x2 /* Pair of 1 Mbyte SIMMs */
                    705: #define SIMM_EMPTY2         0x3 /* reserved */
                    706: /* for turbo systems */
                    707: #define SIMM_32MB_T         0x1 /* Pair of 16 or 32 MByte SIMMs (front or back) */
                    708: #define SIMM_8MB_T          0x2 /* Pair of 4 or 8 MByte SIMMs (front or back) */
                    709: #define SIMM_2MB_T          0x3 /* Pair of 1 or 2 MByte SIMMs (front or back) */
                    710: 
                    711: /* bits in ni_reset (rtc ram byte 0 to 3) *
                    712:  * -------- -------- -------- -------x bit 0:     any cmd
                    713:  * -------- -------- -------- ------x- bit 1:     boot any
                    714:  * -------- -------- -------- -----x-- bit 2:     enable lowpass filter
                    715:  * -------- -------- -------- ----x--- bit 3:     disable speaker
                    716:  * -------- -------- ------xx xxxx---- bit 4-9:   volume left (max 0, min 0x2B)
                    717:  * -------- -------- --xxxx-- -------- bit 10-13: hardware password
                    718:  * -------- ----xxxx xx------ -------- bit 14-19: brightness (max 0x3D, min 0)
                    719:  * ------xx xxxx---- -------- -------- bit 20-25: volume right (max 0, min 0x2B)
                    720:  * -----x-- -------- -------- -------- bit 26:    allow eject
                    721:  * ----x--- -------- -------- -------- bit 27:    alt cons
                    722:  * xxxx---- -------- -------- -------- bit 28-31: reset
                    723:  */
                    724: 
                    725: /* RTC RAM */
                    726: Uint8 nvram_default[32]={
                    727:     0x94,0x0f,0x40,0x00, // byte 0 - 3: volume, brightness, ...
                    728:     0x00,0x00,0x00,0x00,0x00,0x00, // byte 4 - 9: hardware password, ethernet address (?)
                    729:     0x00,0x00, // byte 10, 11: simm type and size (4 simms, 4 bits per simm), see bits in ni_simm above
                    730:     0x00,0x00, // byte 12, 13: adobe (?)
                    731:     0x4b,0x00,0x00, // byte 14: POT, byte 15: oldest ..., byte 16: most recent selftest error code
                    732:     0x00, // byte 17: bit7:clock chip; 6:auto poweron; 5:enable console slot; 3,4:console slot; 2:parity mem
                    733:     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // byte 18 - 29: boot command
                    734:     0x0F,0x13 // byte 30, 31: checksum
                    735: };
                    736: 
                    737: void nvram_init(void) {
                    738:     /* Reset RTC RAM */
                    739:     memset(rtc.ram, 0, 32);
                    740:     
                    741:     /* Build configuration bytes */
                    742:     Uint32 config = 0x94000000; /* reset = 9, allow eject = 1 */
                    743:     config |= 0x3D<<14; /* brightness */
                    744:     
                    745:     rtc.ram[0] = config>>24;
                    746:     rtc.ram[1] = config>>16;
                    747:     rtc.ram[2] = config>>8;
                    748:     rtc.ram[3] = config;
                    749:     
                    750:     /* Build boot command */
                    751:     switch (ConfigureParams.Boot.nBootDevice) {
                    752:         case BOOT_ROM:
                    753:             rtc.ram[18] = 0x00;
                    754:             rtc.ram[19] = 0x00;
                    755:             break;
                    756:         case BOOT_SCSI:
                    757:             rtc.ram[18] = 's';
                    758:             rtc.ram[19] = 'd';
                    759:             break;
                    760:         case BOOT_ETHERNET:
                    761:             rtc.ram[18] = 'e';
                    762:             rtc.ram[19] = 'n';
                    763:             break;
                    764:         case BOOT_MO:
                    765:             rtc.ram[18] = 'o';
                    766:             rtc.ram[19] = 'd';
                    767:             break;
                    768:         case BOOT_FLOPPY:
                    769:             rtc.ram[18] = 'f';
                    770:             rtc.ram[19] = 'd';
                    771:             break;
                    772:             
                    773:         default: break;
                    774:     }
                    775:     
                    776:     /* Copy ethernet address from ROM to RTC RAM */
                    777:     int i;
                    778:     for (i = 0; i<6; i++) {
                    779:         rtc.ram[i+4]=NEXTRom[i+8];
                    780:     }
                    781:     
                    782:     /* Build SIMM bytes */
                    783:     Uint16 SIMMconfig = 0x0000;
                    784:     Uint8 simm[4];
                    785:     Uint8 parity = 0xF0;
                    786:     if (ConfigureParams.System.bTurbo) {
                    787:         parity = 0x00;
                    788:         for (i = 0; i<4; i++) {
                    789:             switch (ConfigureParams.Memory.nMemoryBankSize[i]) {
                    790:                 case 0: simm[i] = SIMM_EMPTY; break;
                    791:                 case 2: simm[i] = SIMM_2MB_T; break;
                    792:                 case 8: simm[i] = SIMM_8MB_T; break;
                    793:                 case 32: simm[i] = SIMM_32MB_T; break;
                    794:                 default: simm[i] = SIMM_EMPTY; break;
                    795:             }
                    796:         }
                    797:         
                    798:     } else if (ConfigureParams.System.bColor) {
                    799:         for (i = 0; i<4; i++) {
                    800:             switch (ConfigureParams.Memory.nMemoryBankSize[i]) {
                    801:                 case 0: simm[i] = SIMM_EMPTY; parity &= ~(0x10<<i); break;
                    802:                 case 2: simm[i] = SIMM_2MB_C; break;
                    803:                 case 8: simm[i] = SIMM_8MB_C; break;
                    804:                 default: simm[i] = SIMM_EMPTY; break;
                    805:             }
                    806:         }
                    807:         
                    808:     } else {
                    809:         for (i = 0; i<4; i++) {
                    810:             switch (ConfigureParams.Memory.nMemoryBankSize[i]) {
                    811:                 case 0: simm[i] = SIMM_EMPTY; parity &= ~(0x10<<i); break;
                    812:                 case 1: simm[i] = SIMM_1MB | SIMM_PAGE_MODE; break;
                    813:                 case 4: simm[i] = SIMM_4MB | SIMM_PAGE_MODE; break;
                    814:                 case 16: simm[i] = SIMM_16MB | SIMM_PAGE_MODE; break;
                    815:                 default: simm[i] = SIMM_EMPTY | SIMM_PAGE_MODE; break;
                    816:             }
                    817:         }
                    818:     }
                    819:     
                    820:     SIMMconfig = ((parity&0xF0)<<8) | (simm[3]<<9) | (simm[2]<<6) | (simm[1]<<3) | simm[0];
                    821:     rtc.ram[10] = (SIMMconfig>>8)&0xFF;
                    822:     rtc.ram[11] = SIMMconfig&0xFF;
                    823:     
                    824:     /* Build POT byte[0] */
                    825:     rtc.ram[14] = 0x00;
                    826:     if (ConfigureParams.Boot.bEnableDRAMTest)
                    827:         rtc.ram[14] |= TEST_DRAM_POT;
                    828:     if (ConfigureParams.Boot.bEnablePot)
                    829:         rtc.ram[14] |= POT_ON;
                    830:     if (ConfigureParams.Boot.bEnableSoundTest)
                    831:         rtc.ram[14] |= TEST_MONITOR_POT;
                    832:     if (ConfigureParams.Boot.bEnableSCSITest)
                    833:         rtc.ram[14] |= EXTENDED_POT;
                    834:     if (ConfigureParams.Boot.bLoopPot)
                    835:         rtc.ram[14] |= LOOP_POT;
                    836:     if (ConfigureParams.Boot.bVerbose)
                    837:         rtc.ram[14] |= VERBOSE_POT;
                    838:     if (ConfigureParams.Boot.bExtendedPot)
                    839:         rtc.ram[14] |= BOOT_POT;
                    840:     
                    841:     /* Set clock chip bit */
                    842:     switch (ConfigureParams.System.nRTC) {
                    843:         case MCCS1850: rtc.ram[17] |= NEW_CLOCK_CHIP; break;
                    844:         case MC68HC68T1: rtc.ram[17] &= ~NEW_CLOCK_CHIP; break;
                    845:         default: break;
                    846:     }
                    847: #if ENABLE_DIMENSION
                    848:        /* Set prefered console slot */
                    849:        if (ConfigureParams.Dimension.bEnabled) {
                    850:                rtc.ram[17] |= USE_CONSOLE_SLOT;
                    851:                if (ConfigureParams.Screen.nMonitorType==MONITOR_TYPE_DIMENSION) {
                    852:                        rtc.ram[17] |= (ND_SLOT>>1)<<3;
                    853:                }
                    854:     }
                    855: #endif
                    856:     /* Re-calculate checksum */
                    857:     nvram_checksum(1);
                    858: }
                    859: 
                    860: void nvram_checksum(int force) {
                    861:        int sum,i;
                    862:        sum=0;
                    863:        for (i=0;i<30;i+=2) {
                    864:                sum+=(rtc.ram[i]<<8)|(rtc.ram[i+1]);
                    865:                if (sum>=0x10000) {
                    866:                        sum-=0x10000;
                    867:                        sum+=1;
                    868:                }
                    869:        }
                    870:     
                    871:        sum=0xFFFF-sum;
                    872:     
                    873:        if (force) {
                    874:                rtc.ram[30]=(sum&0xFF00)>>8;
                    875:                rtc.ram[31]=(sum&0xFF);
                    876:                Log_Printf(LOG_WARN,"Forcing RTC checksum to %x %x",rtc.ram[30],rtc.ram[31]);
                    877:        } else {
                    878:                Log_Printf(LOG_WARN,"Check RTC checksum to %x %x %x %x",
                    879:                    rtc.ram[30],(sum&0xFF00)>>8,
                    880:                    rtc.ram[31],(sum&0xFF));
                    881:        }
                    882: }
                    883: 
                    884: 
                    885: #if 1
                    886: static char rtc_ram_info[1024];
                    887: char * get_rtc_ram_info(void) {
                    888:     char buf[256];
                    889:     int sum;
                    890:     int i;
                    891:     int ni_vol_l,ni_vol_r,ni_brightness;
                    892:     int ni_hw_pwd,ni_spkren,ni_lowpass;
                    893:     sprintf(buf,"Rtc info:\n");
                    894:     strcpy(rtc_ram_info,buf);
                    895:     
                    896:     // struct nvram_info {
                    897:     // #define NI_RESET        9
                    898:     //         u_int   ni_reset : 4,
                    899:     
                    900:     sprintf(buf,"RTC RESET:x%1X ",rtc.ram[0]>>4);
                    901:     strcat(rtc_ram_info,buf);
                    902:     
                    903:     // #define SCC_ALT_CONS    0x08000000
                    904:     //                 ni_alt_cons : 1,
                    905:     if (rtc.ram[0]&0x08) strcat(rtc_ram_info,"ALT_CONS ");
                    906:     // #define ALLOW_EJECT     0x04000000
                    907:     //                 ni_allow_eject : 1,
                    908:     if (rtc.ram[0]&0x04) strcat(rtc_ram_info,"ALLOW_EJECT ");
                    909:     //                 ni_vol_r : 6,
                    910:     //                 ni_brightness : 6,
                    911:     // #define HW_PWD  0x6
                    912:     //                 ni_hw_pwd : 4,
                    913:     //                 ni_vol_l : 6,
                    914:     //                 ni_spkren : 1,
                    915:     //                 ni_lowpass : 1,
                    916:     // #define BOOT_ANY        0x00000002
                    917:     //                 ni_boot_any : 1,
                    918:     // #define ANY_CMD         0x00000001
                    919:     //                 ni_any_cmd : 1;
                    920:     
                    921:     ni_vol_r=(((rtc.ram[0]&0x3)<<4)|((rtc.ram[1]&0xF0)>>4));
                    922:     ni_brightness=(((rtc.ram[1]&0xF)<<2)|((rtc.ram[2]&0xC0)>>6));
                    923:     ni_vol_l=((rtc.ram[2]&0x3F)<<2);
                    924:     ni_hw_pwd=(rtc.ram[3]&0xF0)>>4;
                    925:     sprintf(buf,"VOL_R:x%1X BRIGHT:x%1X HWPWD:x%1X VOL_L:x%1X",ni_vol_r,ni_brightness,ni_vol_l,ni_hw_pwd);
                    926:     strcat(rtc_ram_info,buf);
                    927:     
                    928:     if (rtc.ram[3]&0x08) strcat(rtc_ram_info,"SPK_ENABLE ");
                    929:     if (rtc.ram[3]&0x04) strcat(rtc_ram_info,"LOW_PASS ");
                    930:     if (rtc.ram[3]&0x02) strcat(rtc_ram_info,"BOOT_ANY ");
                    931:     if (rtc.ram[3]&0x01) strcat(rtc_ram_info,"ANY_CMD ");
                    932:     
                    933:     
                    934:     
                    935:     // #define NVRAM_HW_PASSWD 6
                    936:     //         u_char ni_ep[NVRAM_HW_PASSWD];
                    937:     
                    938:     sprintf(buf,"NVRAM_HW_PASSWD:%2X %2X %2X %2X %2X %2X ",rtc.ram[4],rtc.ram[5],rtc.ram[6],rtc.ram[7],rtc.ram[8],rtc.ram[9]);
                    939:     strcat(rtc_ram_info,buf);
                    940:     // #define ni_enetaddr     ni_ep
                    941:     // #define ni_hw_passwd    ni_ep
                    942:     //         u_short ni_simm;                /* 4 SIMMs, 4 bits per SIMM */
                    943:     sprintf(buf,"SIMM:%1X %1X %1X %1X ",rtc.ram[10]>>4,rtc.ram[10]&0x0F,rtc.ram[11]>>4,rtc.ram[11]&0x0F);
                    944:     strcat(rtc_ram_info,buf);
                    945:     
                    946:     
                    947:     //         char ni_adobe[2];
                    948:     sprintf(buf,"ADOBE:%2X %2X ",rtc.ram[12],rtc.ram[13]);
                    949:     strcat(rtc_ram_info,buf);
                    950:     
                    951:     //         u_char ni_pot[3];
                    952:     sprintf(buf,"POT:%2X %2X %2X ",rtc.ram[14],rtc.ram[15],rtc.ram[16]);
                    953:     strcat(rtc_ram_info,buf);
                    954:     
                    955:     //         u_char  ni_new_clock_chip : 1,
                    956:     //                 ni_auto_poweron : 1,
                    957:     //                 ni_use_console_slot : 1,        /* Console slot was set by user. */
                    958:     //                 ni_console_slot : 2,            /* Preferred console dev slot>>1 */
                    959:     //                 ni_use_parity_mem : 1,  /* Use parity RAM if available? */
                    960:     //                 : 2;
                    961:     if (rtc.ram[17]&0x80) strcat(rtc_ram_info,"NEW_CLOCK_CHIP ");
                    962:     if (rtc.ram[17]&0x40) strcat(rtc_ram_info,"AUTO_POWERON ");
                    963:     if (rtc.ram[17]&0x20) strcat(rtc_ram_info,"CONSOLE_SLOT ");
                    964:     
                    965:     sprintf(buf,"console_slot:%X ",(rtc.ram[17]&0x18)>>3);
                    966:     strcat(rtc_ram_info,buf);
                    967:     
                    968:     if (rtc.ram[17]&0x04) strcat(rtc_ram_info,"USE_PARITY ");
                    969:     
                    970:     
                    971:     strcat(rtc_ram_info,"boot_command:");
                    972:     for (i=0;i<12;i++) {
                    973:         if ((rtc.ram[18+i]>=0x20) && (rtc.ram[18+i]<=0x7F)) {
                    974:             sprintf(buf,"%c",rtc.ram[18+i]);
                    975:             strcat(rtc_ram_info,buf);
                    976:         }
                    977:     }
                    978:     
                    979:     strcat(rtc_ram_info," ");
                    980:     sprintf(buf,"CKSUM:%2X %2X ",rtc.ram[30],rtc.ram[31]);
                    981:     strcat(rtc_ram_info,buf);
                    982:     
                    983:     
                    984:     sum=0;
                    985:     for (i=0;i<30;i+=2) {
                    986:         sum+=(rtc.ram[i]<<8)|(rtc.ram[i+1]);
                    987:         if (sum>=0x10000) { sum-=0x10000;
                    988:             sum+=1;
                    989:         }
                    990:     }
                    991:     
                    992:     sum=0xFFFF-sum;
                    993:     
                    994:     sprintf(buf,"CALC_CKSUM:%04X ",sum&0xFFFF);
                    995:     strcat(rtc_ram_info,buf);
                    996:     
                    997:     // #define NVRAM_BOOTCMD   12
                    998:     //         char ni_bootcmd[NVRAM_BOOTCMD];
                    999:     //         u_short ni_cksum;
                   1000:     // };
                   1001:     
                   1002:     return rtc_ram_info;
                   1003: }
                   1004: #endif

unix.superglobalmegacorp.com

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