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

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:                {
                    166:                        nvram[NVRAM_MONITOR] |= 32;             // VGA mode
                    167:                }
                    168:                else
                    169:                {
                    170:                        nvram[NVRAM_MONITOR] &= ~32;            // TV/RGB mode
                    171:                }
                    172:                NvRam_SetChecksum();
                    173:        }
                    174: 
                    175:        NvRam_Reset();
                    176: }
                    177: 
                    178: 
                    179: /*-----------------------------------------------------------------------*/
                    180: /**
                    181:  * De-Initialization
                    182:  */
                    183: void NvRam_UnInit(void)
                    184: {
                    185:        NvRam_Save();           // save NVRAM file upon exit automatically (should be conditionalized)
                    186: }
                    187: 
                    188: 
                    189: /*-----------------------------------------------------------------------*/
                    190: /**
                    191:  * Read from RTC/NVRAM offset selection register ($ff8961)
                    192:  */
                    193: void NvRam_Select_ReadByte(void)
                    194: {
                    195:        IoMem_WriteByte(0xff8961, nvram_index);
                    196: }
                    197: 
                    198: 
                    199: /*-----------------------------------------------------------------------*/
                    200: /**
                    201:  * Write to RTC/NVRAM offset selection register ($ff8961)
                    202:  */
                    203: void NvRam_Select_WriteByte(void)
                    204: {
                    205:        Uint8 value = IoMem_ReadByte(0xff8961);
                    206: 
                    207:        if (value < sizeof(nvram))
                    208:        {
                    209:                nvram_index = value;
                    210:        }
                    211:        else
                    212:        {
                    213:                Log_Printf(LOG_WARN, "NVRAM: trying to set out-of-bound position (%d)\n", value);
                    214:        }
                    215: }
                    216: 
                    217: 
                    218: /*-----------------------------------------------------------------------*/
                    219: /**
                    220:  * Read from RTC/NVRAM data register ($ff8963)
                    221:  */
                    222: void NvRam_Data_ReadByte(void)
                    223: {
1.1.1.2   root      224:        Uint8 value = 0;
1.1       root      225: 
                    226:        if (nvram_index == NVRAM_SECONDS || nvram_index == NVRAM_MINUTES || nvram_index == NVRAM_HOURS
                    227:            || (nvram_index >=NVRAM_DAY && nvram_index <=NVRAM_YEAR) )
                    228:        {
                    229:                /* access to RTC?  - then read host clock and return its values */
                    230:                time_t tim = time(NULL);
                    231:                struct tm *curtim = localtime(&tim);    /* current time */
                    232:                switch(nvram_index)
                    233:                {
                    234:                        case NVRAM_SECONDS: value = curtim->tm_sec; break;
                    235:                        case NVRAM_MINUTES: value = curtim->tm_min; break;
                    236:                        case NVRAM_HOURS: value = curtim->tm_hour; break;
                    237:                        case NVRAM_DAY: value = curtim->tm_mday; break;
                    238:                        case NVRAM_MONTH: value = curtim->tm_mon+1; break;
                    239:                        case NVRAM_YEAR: value = curtim->tm_year - 68; break;
                    240:                }
                    241:        }
                    242:        else if (nvram_index == 10)
                    243:        {
1.1.1.2   root      244:                static bool rtc_uip = true;
1.1       root      245:                value = rtc_uip ? 0x80 : 0;
                    246:                rtc_uip = !rtc_uip;
                    247:        }
                    248:        else if (nvram_index == 13)
                    249:        {
                    250:                value = 0x80;   // Valid RAM and Time bit
                    251:        }
                    252:        else if (nvram_index < 14)
                    253:        {
                    254:                Log_Printf(LOG_DEBUG, "Read from unsupported RTC/NVRAM register 0x%x.\n", nvram_index);
                    255:                value = nvram[nvram_index];
                    256:        }
                    257:        else
                    258:        {
                    259:                value = nvram[nvram_index];
                    260:        }
1.1.1.4 ! root      261:        Dprintf(("Reading NVRAM data at %d = %d ($%02x)\n", nvram_index, value, value));
1.1       root      262: 
                    263:        IoMem_WriteByte(0xff8963, value);
                    264: }
                    265: 
                    266: 
                    267: /*-----------------------------------------------------------------------*/
                    268: /**
                    269:  * Write to RTC/NVRAM data register ($ff8963)
                    270:  */
                    271: 
                    272: void NvRam_Data_WriteByte(void)
                    273: {
                    274:        Uint8 value = IoMem_ReadByte(0xff8963);
1.1.1.4 ! root      275:        Dprintf(("Writing NVRAM data at %d = %d ($%02x)\n", nvram_index, value, value));
1.1       root      276:        nvram[nvram_index] = value;
                    277: }

unix.superglobalmegacorp.com

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