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

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"
1.1.1.3 ! root       16: #include "dimension.hpp"
1.1       root       17: #include "sysReg.h"
                     18: #include "rtcnvram.h"
                     19: 
                     20: #include <time.h>
                     21: 
                     22: 
1.1.1.2   root       23: #define LOG_RTC_LEVEL   LOG_DEBUG
1.1       root       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) {
1.1.1.2   root       48:     phase    = 0;
1.1       root       49:     rtc_addr = 0;
1.1.1.2   root       50:     rtc_val  = 0;
1.1       root       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: 
1.1.1.2   root      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: }
1.1       root      312: 
                    313: Uint8 rtc_get_clock(Uint8 addr) {
                    314:     Uint8 val = 0x00;
                    315:     
1.1.1.2   root      316:     my_get_rtc_time();
1.1       root      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:     
1.1.1.2   root      540:     newrtc.timecntr = host_unix_time();
1.1       root      541:     
                    542:     switch (rtc_addr&RTC_ADDR_MASK) {
                    543:         case 0x20:
1.1.1.2   root      544:             val = (newrtc.timecntr>>24);
                    545:             break;
1.1       root      546:         case 0x21:
1.1.1.2   root      547:             val = (newrtc.timecntr>>16);
                    548:             break;
1.1       root      549:         case 0x22:
1.1.1.2   root      550:             val = (newrtc.timecntr>>8);
                    551:             break;
1.1       root      552:         case 0x23:
1.1.1.2   root      553:             val = newrtc.timecntr;
                    554:             break;
1.1       root      555:             
                    556:         case 0x24:
1.1.1.2   root      557:             val = (newrtc.alarmcntr>>24);
                    558:             break;
1.1       root      559:         case 0x25:
1.1.1.2   root      560:             val = (newrtc.alarmcntr>>16);
                    561:             break;
1.1       root      562:         case 0x26:
1.1.1.2   root      563:             val = (newrtc.alarmcntr>>8);
                    564:             break;
1.1       root      565:         case 0x27:
1.1.1.2   root      566:             val = newrtc.alarmcntr;
                    567:             break;
1.1       root      568: 
                    569:         case 0x30: /* status register */
                    570:             val = newrtc.status|NRTC_NEWCHIP;
                    571:             break;
                    572:         case 0x31: /* control register */
1.1.1.2   root      573:             val = newrtc.control&~NRTC_CTRL_0;
                    574:             break;
1.1       root      575:             
1.1.1.2   root      576:         default:
                    577:             break;
1.1       root      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:
1.1.1.2   root      586:             newrtc.timecntr &= 0x00FFFFFF;
                    587:             newrtc.timecntr |= val << 24;
                    588:             host_set_unix_time(newrtc.timecntr);
                    589:             break;
1.1       root      590:         case 0x21:
1.1.1.2   root      591:             newrtc.timecntr &= 0xFF00FFFF;
                    592:             newrtc.timecntr |= val << 16;
                    593:             host_set_unix_time(newrtc.timecntr);
                    594:             break;
1.1       root      595:         case 0x22:
1.1.1.2   root      596:             newrtc.timecntr &= 0xFFFF00FF;
                    597:             newrtc.timecntr |= val << 8;
                    598:             host_set_unix_time(newrtc.timecntr);
                    599:             break;
1.1       root      600:         case 0x23:
1.1.1.2   root      601:             newrtc.timecntr &= 0xFFFFFF00;
                    602:             newrtc.timecntr |= val;
                    603:             host_set_unix_time(newrtc.timecntr);
                    604:             break;
1.1       root      605:         case 0x24:
1.1.1.2   root      606:             newrtc.alarmcntr &= 0x00FFFFFF;
                    607:             newrtc.alarmcntr |= val << 24;
                    608:             break;
1.1       root      609:         case 0x25:
1.1.1.2   root      610:             newrtc.alarmcntr &= 0xFF00FFFF;
                    611:             newrtc.alarmcntr |= val << 16;
                    612:             break;
1.1       root      613:         case 0x26:
1.1.1.2   root      614:             newrtc.alarmcntr &= 0xFFFF00FF;
                    615:             newrtc.alarmcntr |= val << 8;
                    616:             break;
1.1       root      617:         case 0x27:
1.1.1.2   root      618:             newrtc.alarmcntr &= 0xFFFFFF00;
                    619:             newrtc.alarmcntr |= val;
                    620:             break;
1.1       root      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:     }
1.1.1.2   root      876: 
1.1       root      877:        /* Set prefered console slot */
1.1.1.3 ! root      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:         }
1.1       root      886:     }
1.1.1.2   root      887: 
                    888:        /* Re-calculate checksum */
1.1       root      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;
1.1.1.2   root      924:     int ni_hw_pwd;
1.1       root      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.