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

unix.superglobalmegacorp.com

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