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

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.2 ! root       30: const char NvRam_rcsid[] = "Hatari $Id: nvram.c,v 1.8 2008/08/05 23:26:47 thothy Exp $";
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: #include "araglue.h"
                     39: 
                     40: #define DEBUG 0
                     41: 
                     42: #if DEBUG
                     43: #define D(x) x
                     44: #else
                     45: #define D(x)
                     46: #endif
                     47: 
                     48: // Defs for checksum
                     49: #define CKS_RANGE_START        14
                     50: #define CKS_RANGE_END  (14+47)
                     51: #define CKS_RANGE_LEN  (CKS_RANGE_END-CKS_RANGE_START+1)
                     52: #define CKS_LOC                        (14+48)
                     53: 
                     54: #define NVRAM_START  14
                     55: #define NVRAM_LEN    50
                     56: 
1.1.1.2 ! root       57: static Uint8 nvram[64] = { 48,255,21,255,23,255,1,25,3,33,42,14,112,128,
1.1       root       58:        0,0,0,0,0,0,0,0,17,46,32,1,255,0,1,10,135,0,0,0,0,0,0,0,
                     59:        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 };
                     60: 
                     61: 
                     62: static Uint8 nvram_index;
                     63: static char nvram_filename[FILENAME_MAX];
                     64: 
                     65: 
                     66: /*-----------------------------------------------------------------------*/
                     67: /**
                     68:  * NvRam_Reset: Called during init and reset, used for resetting the
                     69:  * emulated chip.
                     70:  */
                     71: void NvRam_Reset(void)
                     72: {
                     73:        nvram_index = 0;
                     74: }
                     75: 
                     76: 
                     77: /*-----------------------------------------------------------------------*/
                     78: /**
                     79:  * Load NVRAM data from file.
                     80:  */
1.1.1.2 ! root       81: static bool NvRam_Load(void)
1.1       root       82: {
1.1.1.2 ! root       83:        bool ret = FALSE;
1.1       root       84:        FILE *f = fopen(nvram_filename, "rb");
                     85:        if (f != NULL)
                     86:        {
1.1.1.2 ! root       87:                Uint8 fnvram[NVRAM_LEN];
1.1       root       88:                if (fread(fnvram, 1, NVRAM_LEN, f) == NVRAM_LEN)
                     89:                {
                     90:                        memcpy(nvram+NVRAM_START, fnvram, NVRAM_LEN);
                     91:                        ret = TRUE;
                     92:                }
                     93:                fclose(f);
                     94:                Log_Printf(LOG_DEBUG, "NVRAM loaded from '%s'\n", nvram_filename);
                     95:        }
                     96:        else
                     97:        {
                     98:                Log_Printf(LOG_INFO, "NVRAM not found at '%s'\n", nvram_filename);
                     99:        }
                    100: 
                    101:        return ret;
                    102: }
                    103: 
                    104: 
                    105: /*-----------------------------------------------------------------------*/
                    106: /**
                    107:  * Save NVRAM data to file
                    108:  */
1.1.1.2 ! root      109: static bool NvRam_Save(void)
1.1       root      110: {
1.1.1.2 ! root      111:        bool ret = FALSE;
1.1       root      112:        FILE *f = fopen(nvram_filename, "wb");
                    113:        if (f != NULL)
                    114:        {
                    115:                if (fwrite(nvram+NVRAM_START, 1, NVRAM_LEN, f) == NVRAM_LEN)
                    116:                {
                    117:                        ret = TRUE;
                    118:                }
                    119:                fclose(f);
                    120:        }
                    121:        else
                    122:        {
1.1.1.2 ! root      123:                Log_Printf(LOG_WARN, "ERROR: cannot store NVRAM to '%s'\n", nvram_filename);
1.1       root      124:        }
                    125: 
                    126:        return ret;
                    127: }
                    128: 
                    129: 
                    130: /*-----------------------------------------------------------------------*/
                    131: /**
                    132:  * Create NVRAM checksum. The checksum is over all bytes except the
                    133:  * checksum bytes themselves; these are at the very end.
                    134:  */
                    135: static void NvRam_SetChecksum(void)
                    136: {
                    137:        int i;
                    138:        unsigned char sum = 0;
                    139:        
                    140:        for(i = CKS_RANGE_START; i <= CKS_RANGE_END; ++i)
                    141:                sum += nvram[i];
                    142:        nvram[NVRAM_CHKSUM1] = ~sum;
                    143:        nvram[NVRAM_CHKSUM2] = sum;
                    144: }
                    145: 
                    146: 
                    147: /*-----------------------------------------------------------------------*/
                    148: /**
                    149:  * Initialization
                    150:  */
                    151: void NvRam_Init(void)
                    152: {
                    153:        const char sBaseName[] = "hatari.nvram";
                    154:        const char *psHomeDir;
                    155: 
                    156:        // set up the nvram filename
                    157:        psHomeDir = Paths_GetHatariHome();
                    158:        if (strlen(psHomeDir)+sizeof(sBaseName)+1 < sizeof(nvram_filename))
                    159:                sprintf(nvram_filename, "%s%c%s", psHomeDir, PATHSEP, sBaseName);
                    160:        else
                    161:                strcpy(nvram_filename, sBaseName);
                    162: 
                    163:        if (!NvRam_Load())              // load NVRAM file automatically
                    164:        {
1.1.1.2 ! root      165:                if (ConfigureParams.Screen.nMonitorType == MONITOR_TYPE_VGA)   // VGA ?
1.1       root      166:                {
                    167:                        nvram[NVRAM_MONITOR] |= 32;             // VGA mode
                    168:                }
                    169:                else
                    170:                {
                    171:                        nvram[NVRAM_MONITOR] &= ~32;            // TV/RGB mode
                    172:                }
                    173:                NvRam_SetChecksum();
                    174:        }
                    175: 
                    176:        NvRam_Reset();
                    177: }
                    178: 
                    179: 
                    180: /*-----------------------------------------------------------------------*/
                    181: /**
                    182:  * De-Initialization
                    183:  */
                    184: void NvRam_UnInit(void)
                    185: {
                    186:        NvRam_Save();           // save NVRAM file upon exit automatically (should be conditionalized)
                    187: }
                    188: 
                    189: 
                    190: /*-----------------------------------------------------------------------*/
                    191: /**
                    192:  * Read from RTC/NVRAM offset selection register ($ff8961)
                    193:  */
                    194: void NvRam_Select_ReadByte(void)
                    195: {
                    196:        IoMem_WriteByte(0xff8961, nvram_index);
                    197: }
                    198: 
                    199: 
                    200: /*-----------------------------------------------------------------------*/
                    201: /**
                    202:  * Write to RTC/NVRAM offset selection register ($ff8961)
                    203:  */
                    204: void NvRam_Select_WriteByte(void)
                    205: {
                    206:        Uint8 value = IoMem_ReadByte(0xff8961);
                    207: 
                    208:        if (value < sizeof(nvram))
                    209:        {
                    210:                nvram_index = value;
                    211:        }
                    212:        else
                    213:        {
                    214:                Log_Printf(LOG_WARN, "NVRAM: trying to set out-of-bound position (%d)\n", value);
                    215:        }
                    216: }
                    217: 
                    218: 
                    219: /*-----------------------------------------------------------------------*/
                    220: /**
                    221:  * Read from RTC/NVRAM data register ($ff8963)
                    222:  */
                    223: void NvRam_Data_ReadByte(void)
                    224: {
1.1.1.2 ! root      225:        Uint8 value = 0;
1.1       root      226: 
                    227:        if (nvram_index == NVRAM_SECONDS || nvram_index == NVRAM_MINUTES || nvram_index == NVRAM_HOURS
                    228:            || (nvram_index >=NVRAM_DAY && nvram_index <=NVRAM_YEAR) )
                    229:        {
                    230:                /* access to RTC?  - then read host clock and return its values */
                    231:                time_t tim = time(NULL);
                    232:                struct tm *curtim = localtime(&tim);    /* current time */
                    233:                switch(nvram_index)
                    234:                {
                    235:                        case NVRAM_SECONDS: value = curtim->tm_sec; break;
                    236:                        case NVRAM_MINUTES: value = curtim->tm_min; break;
                    237:                        case NVRAM_HOURS: value = curtim->tm_hour; break;
                    238:                        case NVRAM_DAY: value = curtim->tm_mday; break;
                    239:                        case NVRAM_MONTH: value = curtim->tm_mon+1; break;
                    240:                        case NVRAM_YEAR: value = curtim->tm_year - 68; break;
                    241:                }
                    242:        }
                    243:        else if (nvram_index == 10)
                    244:        {
1.1.1.2 ! root      245:                static bool rtc_uip = true;
1.1       root      246:                value = rtc_uip ? 0x80 : 0;
                    247:                rtc_uip = !rtc_uip;
                    248:        }
                    249:        else if (nvram_index == 13)
                    250:        {
                    251:                value = 0x80;   // Valid RAM and Time bit
                    252:        }
                    253:        else if (nvram_index < 14)
                    254:        {
                    255:                Log_Printf(LOG_DEBUG, "Read from unsupported RTC/NVRAM register 0x%x.\n", nvram_index);
                    256:                value = nvram[nvram_index];
                    257:        }
                    258:        else
                    259:        {
                    260:                value = nvram[nvram_index];
                    261:        }
                    262:        D(bug("Reading NVRAM data at %d = %d ($%02x)", nvram_index, value, value));
                    263: 
                    264:        IoMem_WriteByte(0xff8963, value);
                    265: }
                    266: 
                    267: 
                    268: /*-----------------------------------------------------------------------*/
                    269: /**
                    270:  * Write to RTC/NVRAM data register ($ff8963)
                    271:  */
                    272: 
                    273: void NvRam_Data_WriteByte(void)
                    274: {
                    275:        Uint8 value = IoMem_ReadByte(0xff8963);
                    276:        D(bug("Writing NVRAM data at %d = %d ($%02x)", nvram_index, value, value));
                    277:        nvram[nvram_index] = value;
                    278: }
                    279: 

unix.superglobalmegacorp.com

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