Annotation of previous/src/rtcnvram.c, revision 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.