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

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: */
        !            30: const char NvRam_rcsid[] = "Hatari $Id: nvram.c,v 1.4 2008/02/23 21:15:56 thothy Exp $";
        !            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: 
        !            57: static uint8 nvram[64] = { 48,255,21,255,23,255,1,25,3,33,42,14,112,128,
        !            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:  */
        !            81: static BOOL NvRam_Load(void)
        !            82: {
        !            83:        BOOL ret = FALSE;
        !            84:        FILE *f = fopen(nvram_filename, "rb");
        !            85:        if (f != NULL)
        !            86:        {
        !            87:                uint8 fnvram[NVRAM_LEN];
        !            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:  */
        !           109: static BOOL NvRam_Save(void)
        !           110: {
        !           111:        BOOL ret = FALSE;
        !           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:        {
        !           123:                Log_Printf(LOG_ERROR, "ERROR: cannot store NVRAM to '%s'\n", nvram_filename);
        !           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:        {
        !           165:                if (ConfigureParams.Screen.MonitorType == MONITOR_TYPE_VGA)   // VGA ?
        !           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: {
        !           225:        uint8 value = 0;
        !           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:        {
        !           245:                static BOOL rtc_uip = TRUE;
        !           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.