Annotation of hatari/src/falcon/nvram.c, revision 1.1.1.5

1.1       root        1: /*
                      2:   Hatari - nvram.c
                      3: 
                      4:   This file is distributed under the GNU Public License, version 2 or at
                      5:   your option any later version. Read the file gpl.txt for details.
                      6: 
                      7:   This file is partly based on GPL code taken from the Aranym project.
                      8:   - Copyright (c) 2001-2004 Petr Stehlik of ARAnyM dev team
                      9:   - Adaption to Hatari (c) 2006 by Thomas Huth
                     10: 
                     11:   Atari TT and Falcon NVRAM/RTC emulation code.
                     12:   This is a MC146818A or compatible chip with a non-volatile RAM area.
                     13: 
                     14:   These are the important bytes in the nvram array:
                     15: 
                     16:   Byte:    Description:
                     17: 
                     18:   14-15    Prefered operating system (TOS, Unix)
                     19:    20      Language
                     20:    21      Keyboard layout
                     21:    22      Format of date/time
                     22:    23      Separator for date
                     23:    24      Boot delay
                     24:   28-29    Video mode
                     25:    30      SCSI-ID in bits 0-2, bus arbitration flag in bit 7 (1=off, 0=on)
                     26:   62-63    Checksum
                     27: 
                     28:   All other cells are reserved / unused.
                     29: */
1.1.1.4   root       30: const char NvRam_fileid[] = "Hatari nvram.c : " __DATE__ " " __TIME__;
1.1       root       31: 
                     32: #include "main.h"
                     33: #include "configuration.h"
                     34: #include "ioMem.h"
                     35: #include "log.h"
                     36: #include "nvram.h"
                     37: #include "paths.h"
                     38: 
                     39: #define DEBUG 0
                     40: #if DEBUG
1.1.1.4   root       41: #define Dprintf(a) printf a
1.1       root       42: #else
1.1.1.4   root       43: #define Dprintf(a)
1.1       root       44: #endif
                     45: 
1.1.1.4   root       46: 
1.1       root       47: // Defs for checksum
                     48: #define CKS_RANGE_START        14
                     49: #define CKS_RANGE_END  (14+47)
                     50: #define CKS_RANGE_LEN  (CKS_RANGE_END-CKS_RANGE_START+1)
                     51: #define CKS_LOC                        (14+48)
                     52: 
                     53: #define NVRAM_START  14
                     54: #define NVRAM_LEN    50
                     55: 
1.1.1.2   root       56: static Uint8 nvram[64] = { 48,255,21,255,23,255,1,25,3,33,42,14,112,128,
1.1       root       57:        0,0,0,0,0,0,0,0,17,46,32,1,255,0,1,10,135,0,0,0,0,0,0,0,
                     58:        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
                     59: 
                     60: 
                     61: static Uint8 nvram_index;
                     62: static char nvram_filename[FILENAME_MAX];
                     63: 
                     64: 
                     65: /*-----------------------------------------------------------------------*/
                     66: /**
                     67:  * NvRam_Reset: Called during init and reset, used for resetting the
                     68:  * emulated chip.
                     69:  */
                     70: void NvRam_Reset(void)
                     71: {
                     72:        nvram_index = 0;
                     73: }
                     74: 
                     75: 
                     76: /*-----------------------------------------------------------------------*/
                     77: /**
                     78:  * Load NVRAM data from file.
                     79:  */
1.1.1.2   root       80: static bool NvRam_Load(void)
1.1       root       81: {
1.1.1.4   root       82:        bool ret = false;
1.1       root       83:        FILE *f = fopen(nvram_filename, "rb");
                     84:        if (f != NULL)
                     85:        {
1.1.1.2   root       86:                Uint8 fnvram[NVRAM_LEN];
1.1       root       87:                if (fread(fnvram, 1, NVRAM_LEN, f) == NVRAM_LEN)
                     88:                {
                     89:                        memcpy(nvram+NVRAM_START, fnvram, NVRAM_LEN);
1.1.1.4   root       90:                        ret = true;
1.1       root       91:                }
                     92:                fclose(f);
                     93:                Log_Printf(LOG_DEBUG, "NVRAM loaded from '%s'\n", nvram_filename);
                     94:        }
                     95:        else
                     96:        {
                     97:                Log_Printf(LOG_INFO, "NVRAM not found at '%s'\n", nvram_filename);
                     98:        }
                     99: 
                    100:        return ret;
                    101: }
                    102: 
                    103: 
                    104: /*-----------------------------------------------------------------------*/
                    105: /**
                    106:  * Save NVRAM data to file
                    107:  */
1.1.1.2   root      108: static bool NvRam_Save(void)
1.1       root      109: {
1.1.1.4   root      110:        bool ret = false;
1.1       root      111:        FILE *f = fopen(nvram_filename, "wb");
                    112:        if (f != NULL)
                    113:        {
                    114:                if (fwrite(nvram+NVRAM_START, 1, NVRAM_LEN, f) == NVRAM_LEN)
                    115:                {
1.1.1.4   root      116:                        ret = true;
1.1       root      117:                }
                    118:                fclose(f);
                    119:        }
                    120:        else
                    121:        {
1.1.1.2   root      122:                Log_Printf(LOG_WARN, "ERROR: cannot store NVRAM to '%s'\n", nvram_filename);
1.1       root      123:        }
                    124: 
                    125:        return ret;
                    126: }
                    127: 
                    128: 
                    129: /*-----------------------------------------------------------------------*/
                    130: /**
                    131:  * Create NVRAM checksum. The checksum is over all bytes except the
                    132:  * checksum bytes themselves; these are at the very end.
                    133:  */
                    134: static void NvRam_SetChecksum(void)
                    135: {
                    136:        int i;
                    137:        unsigned char sum = 0;
                    138:        
                    139:        for(i = CKS_RANGE_START; i <= CKS_RANGE_END; ++i)
                    140:                sum += nvram[i];
                    141:        nvram[NVRAM_CHKSUM1] = ~sum;
                    142:        nvram[NVRAM_CHKSUM2] = sum;
                    143: }
                    144: 
                    145: 
                    146: /*-----------------------------------------------------------------------*/
                    147: /**
                    148:  * Initialization
                    149:  */
                    150: void NvRam_Init(void)
                    151: {
                    152:        const char sBaseName[] = "hatari.nvram";
                    153:        const char *psHomeDir;
                    154: 
                    155:        // set up the nvram filename
                    156:        psHomeDir = Paths_GetHatariHome();
                    157:        if (strlen(psHomeDir)+sizeof(sBaseName)+1 < sizeof(nvram_filename))
                    158:                sprintf(nvram_filename, "%s%c%s", psHomeDir, PATHSEP, sBaseName);
                    159:        else
                    160:                strcpy(nvram_filename, sBaseName);
                    161: 
                    162:        if (!NvRam_Load())              // load NVRAM file automatically
                    163:        {
1.1.1.2   root      164:                if (ConfigureParams.Screen.nMonitorType == MONITOR_TYPE_VGA)   // VGA ?
1.1       root      165:                {
1.1.1.5 ! root      166:                        nvram[NVRAM_VMODE1] &= ~0x01;           // No doublescan
        !           167:                        nvram[NVRAM_VMODE2] |= 0x10;            // VGA mode
        !           168:                        nvram[NVRAM_VMODE2] &= ~0x20;           // 60 Hz
1.1       root      169:                }
                    170:                else
                    171:                {
1.1.1.5 ! root      172:                        nvram[NVRAM_VMODE1] |= 0x01;            // Interlaced
        !           173:                        nvram[NVRAM_VMODE2] &= ~0x10;           // TV/RGB mode
        !           174:                        nvram[NVRAM_VMODE2] |= 0x20;            // 50 Hz
1.1       root      175:                }
                    176:                NvRam_SetChecksum();
                    177:        }
                    178: 
                    179:        NvRam_Reset();
                    180: }
                    181: 
                    182: 
                    183: /*-----------------------------------------------------------------------*/
                    184: /**
                    185:  * De-Initialization
                    186:  */
                    187: void NvRam_UnInit(void)
                    188: {
                    189:        NvRam_Save();           // save NVRAM file upon exit automatically (should be conditionalized)
                    190: }
                    191: 
                    192: 
                    193: /*-----------------------------------------------------------------------*/
                    194: /**
                    195:  * Read from RTC/NVRAM offset selection register ($ff8961)
                    196:  */
                    197: void NvRam_Select_ReadByte(void)
                    198: {
                    199:        IoMem_WriteByte(0xff8961, nvram_index);
                    200: }
                    201: 
                    202: 
                    203: /*-----------------------------------------------------------------------*/
                    204: /**
                    205:  * Write to RTC/NVRAM offset selection register ($ff8961)
                    206:  */
                    207: void NvRam_Select_WriteByte(void)
                    208: {
                    209:        Uint8 value = IoMem_ReadByte(0xff8961);
                    210: 
                    211:        if (value < sizeof(nvram))
                    212:        {
                    213:                nvram_index = value;
                    214:        }
                    215:        else
                    216:        {
                    217:                Log_Printf(LOG_WARN, "NVRAM: trying to set out-of-bound position (%d)\n", value);
                    218:        }
                    219: }
                    220: 
                    221: 
                    222: /*-----------------------------------------------------------------------*/
                    223: /**
                    224:  * Read from RTC/NVRAM data register ($ff8963)
                    225:  */
                    226: void NvRam_Data_ReadByte(void)
                    227: {
1.1.1.2   root      228:        Uint8 value = 0;
1.1       root      229: 
                    230:        if (nvram_index == NVRAM_SECONDS || nvram_index == NVRAM_MINUTES || nvram_index == NVRAM_HOURS
                    231:            || (nvram_index >=NVRAM_DAY && nvram_index <=NVRAM_YEAR) )
                    232:        {
                    233:                /* access to RTC?  - then read host clock and return its values */
                    234:                time_t tim = time(NULL);
                    235:                struct tm *curtim = localtime(&tim);    /* current time */
                    236:                switch(nvram_index)
                    237:                {
                    238:                        case NVRAM_SECONDS: value = curtim->tm_sec; break;
                    239:                        case NVRAM_MINUTES: value = curtim->tm_min; break;
                    240:                        case NVRAM_HOURS: value = curtim->tm_hour; break;
                    241:                        case NVRAM_DAY: value = curtim->tm_mday; break;
                    242:                        case NVRAM_MONTH: value = curtim->tm_mon+1; break;
                    243:                        case NVRAM_YEAR: value = curtim->tm_year - 68; break;
                    244:                }
                    245:        }
                    246:        else if (nvram_index == 10)
                    247:        {
1.1.1.2   root      248:                static bool rtc_uip = true;
1.1       root      249:                value = rtc_uip ? 0x80 : 0;
                    250:                rtc_uip = !rtc_uip;
                    251:        }
                    252:        else if (nvram_index == 13)
                    253:        {
                    254:                value = 0x80;   // Valid RAM and Time bit
                    255:        }
                    256:        else if (nvram_index < 14)
                    257:        {
                    258:                Log_Printf(LOG_DEBUG, "Read from unsupported RTC/NVRAM register 0x%x.\n", nvram_index);
                    259:                value = nvram[nvram_index];
                    260:        }
                    261:        else
                    262:        {
                    263:                value = nvram[nvram_index];
                    264:        }
1.1.1.4   root      265:        Dprintf(("Reading NVRAM data at %d = %d ($%02x)\n", nvram_index, value, value));
1.1       root      266: 
                    267:        IoMem_WriteByte(0xff8963, value);
                    268: }
                    269: 
                    270: 
                    271: /*-----------------------------------------------------------------------*/
                    272: /**
                    273:  * Write to RTC/NVRAM data register ($ff8963)
                    274:  */
                    275: 
                    276: void NvRam_Data_WriteByte(void)
                    277: {
                    278:        Uint8 value = IoMem_ReadByte(0xff8963);
1.1.1.4   root      279:        Dprintf(("Writing NVRAM data at %d = %d ($%02x)\n", nvram_index, value, value));
1.1       root      280:        nvram[nvram_index] = value;
                    281: }

unix.superglobalmegacorp.com

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