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

1.1       root        1: /*
                      2:   Hatari - nvram.c
                      3: 
1.1.1.6   root        4:   This file is distributed under the GNU General Public License, version 2
                      5:   or at your option any later version. Read the file gpl.txt for details.
1.1       root        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: 
1.1.1.6   root       18:   14-15    Preferred operating system (TOS, Unix)
1.1       root       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"
1.1.1.6   root       38: #include "vdi.h"
1.1       root       39: 
1.1.1.4   root       40: 
1.1       root       41: // Defs for checksum
                     42: #define CKS_RANGE_START        14
                     43: #define CKS_RANGE_END  (14+47)
                     44: #define CKS_RANGE_LEN  (CKS_RANGE_END-CKS_RANGE_START+1)
                     45: #define CKS_LOC                        (14+48)
                     46: 
                     47: #define NVRAM_START  14
                     48: #define NVRAM_LEN    50
                     49: 
1.1.1.2   root       50: static Uint8 nvram[64] = { 48,255,21,255,23,255,1,25,3,33,42,14,112,128,
1.1       root       51:        0,0,0,0,0,0,0,0,17,46,32,1,255,0,1,10,135,0,0,0,0,0,0,0,
                     52:        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 };
                     53: 
                     54: 
                     55: static Uint8 nvram_index;
                     56: static char nvram_filename[FILENAME_MAX];
                     57: 
                     58: 
                     59: /*-----------------------------------------------------------------------*/
                     60: /**
                     61:  * Load NVRAM data from file.
                     62:  */
1.1.1.2   root       63: static bool NvRam_Load(void)
1.1       root       64: {
1.1.1.4   root       65:        bool ret = false;
1.1       root       66:        FILE *f = fopen(nvram_filename, "rb");
                     67:        if (f != NULL)
                     68:        {
1.1.1.2   root       69:                Uint8 fnvram[NVRAM_LEN];
1.1       root       70:                if (fread(fnvram, 1, NVRAM_LEN, f) == NVRAM_LEN)
                     71:                {
                     72:                        memcpy(nvram+NVRAM_START, fnvram, NVRAM_LEN);
1.1.1.7   root       73:                        LOG_TRACE(TRACE_NVRAM, "NVRAM: loaded from '%s'\n", nvram_filename);
1.1.1.4   root       74:                        ret = true;
1.1       root       75:                }
1.1.1.7   root       76:                else
                     77:                {
1.1.1.8 ! root       78:                        Log_Printf(LOG_WARN, "NVRAM loading from '%s' failed\n", nvram_filename);
1.1.1.7   root       79:                }
1.1       root       80:                fclose(f);
                     81:        }
                     82:        else
                     83:        {
                     84:                Log_Printf(LOG_INFO, "NVRAM not found at '%s'\n", nvram_filename);
                     85:        }
                     86: 
                     87:        return ret;
                     88: }
                     89: 
                     90: 
                     91: /*-----------------------------------------------------------------------*/
                     92: /**
                     93:  * Save NVRAM data to file
                     94:  */
1.1.1.2   root       95: static bool NvRam_Save(void)
1.1       root       96: {
1.1.1.4   root       97:        bool ret = false;
1.1       root       98:        FILE *f = fopen(nvram_filename, "wb");
                     99:        if (f != NULL)
                    100:        {
                    101:                if (fwrite(nvram+NVRAM_START, 1, NVRAM_LEN, f) == NVRAM_LEN)
                    102:                {
1.1.1.7   root      103:                        LOG_TRACE(TRACE_NVRAM, "NVRAM: saved to '%s'\n", nvram_filename);
1.1.1.4   root      104:                        ret = true;
1.1       root      105:                }
1.1.1.7   root      106:                else
                    107:                {
1.1.1.8 ! root      108:                        Log_Printf(LOG_WARN, "Writing NVRAM to '%s' failed\n", nvram_filename);
1.1.1.7   root      109:                }
1.1       root      110:                fclose(f);
                    111:        }
                    112:        else
                    113:        {
1.1.1.8 ! root      114:                Log_Printf(LOG_WARN, "Storing NVRAM to '%s' failed\n", nvram_filename);
1.1       root      115:        }
                    116: 
                    117:        return ret;
                    118: }
                    119: 
                    120: 
                    121: /*-----------------------------------------------------------------------*/
                    122: /**
                    123:  * Create NVRAM checksum. The checksum is over all bytes except the
                    124:  * checksum bytes themselves; these are at the very end.
                    125:  */
                    126: static void NvRam_SetChecksum(void)
                    127: {
                    128:        int i;
                    129:        unsigned char sum = 0;
                    130:        
                    131:        for(i = CKS_RANGE_START; i <= CKS_RANGE_END; ++i)
                    132:                sum += nvram[i];
                    133:        nvram[NVRAM_CHKSUM1] = ~sum;
                    134:        nvram[NVRAM_CHKSUM2] = sum;
                    135: }
                    136: 
1.1.1.6   root      137: /*-----------------------------------------------------------------------*/
                    138: /**
                    139:  * NvRam_Reset: Called during init and reset, used for resetting the
                    140:  * emulated chip.
                    141:  */
                    142: void NvRam_Reset(void)
                    143: {
                    144:        if (bUseVDIRes)
                    145:        {
                    146:                /* The objective is to start the TOS with a video mode similar
                    147:                 * to the requested one. This is important for the TOS to initialize
                    148:                 * the right font height and palette. */
                    149:                if (VDIHeight < 400)
                    150:                {
                    151:                        /* This will select the 8x8 system font */
                    152:                        switch(VDIPlanes)
                    153:                        {
                    154:                        /* The case 1 is not handled, because that would result in 0x0000
                    155:                         * which is an invalide video mode. This does not matter,
                    156:                         * since any color palette is good for monochrome, anyway. */
                    157:                        case 2: /* set 320x200x4 colors */
                    158:                                nvram[NVRAM_VMODE1] = 0x00;
                    159:                                nvram[NVRAM_VMODE2] = 0x01;
                    160:                                break;
                    161:                        case 4: /* set 320x200x16 colors */
                    162:                        default:
                    163:                                nvram[NVRAM_VMODE1] = 0x00;
                    164:                                nvram[NVRAM_VMODE2] = 0x02;
                    165:                        }
                    166:                }
                    167:                else
                    168:                {
                    169:                        /* This will select the 8x16 system font */
                    170:                        switch(VDIPlanes)
                    171:                        {
                    172:                        case 4: /* set 640x400x16 colors */
                    173:                                nvram[NVRAM_VMODE1] = 0x01;
                    174:                                nvram[NVRAM_VMODE2] = 0x0a;
                    175:                                break;
                    176:                        case 2: /* set 640x400x4 colors */
                    177:                                nvram[NVRAM_VMODE1] = 0x01;
                    178:                                nvram[NVRAM_VMODE2] = 0x09;
                    179:                                break;
                    180:                        case 1: /* set 640x400x2 colors */
                    181:                        default:
                    182:                                nvram[NVRAM_VMODE1] = 0x01;
                    183:                                nvram[NVRAM_VMODE2] = 0x08;
                    184:                        }
                    185:                }
                    186:                NvRam_SetChecksum();
                    187:        }
                    188:        nvram_index = 0;
                    189: }
1.1       root      190: 
                    191: /*-----------------------------------------------------------------------*/
                    192: /**
                    193:  * Initialization
                    194:  */
                    195: void NvRam_Init(void)
                    196: {
                    197:        const char sBaseName[] = "hatari.nvram";
                    198:        const char *psHomeDir;
                    199: 
                    200:        // set up the nvram filename
                    201:        psHomeDir = Paths_GetHatariHome();
                    202:        if (strlen(psHomeDir)+sizeof(sBaseName)+1 < sizeof(nvram_filename))
                    203:                sprintf(nvram_filename, "%s%c%s", psHomeDir, PATHSEP, sBaseName);
                    204:        else
                    205:                strcpy(nvram_filename, sBaseName);
                    206: 
                    207:        if (!NvRam_Load())              // load NVRAM file automatically
                    208:        {
1.1.1.2   root      209:                if (ConfigureParams.Screen.nMonitorType == MONITOR_TYPE_VGA)   // VGA ?
1.1       root      210:                {
1.1.1.5   root      211:                        nvram[NVRAM_VMODE1] &= ~0x01;           // No doublescan
                    212:                        nvram[NVRAM_VMODE2] |= 0x10;            // VGA mode
                    213:                        nvram[NVRAM_VMODE2] &= ~0x20;           // 60 Hz
1.1       root      214:                }
                    215:                else
                    216:                {
1.1.1.5   root      217:                        nvram[NVRAM_VMODE1] |= 0x01;            // Interlaced
                    218:                        nvram[NVRAM_VMODE2] &= ~0x10;           // TV/RGB mode
                    219:                        nvram[NVRAM_VMODE2] |= 0x20;            // 50 Hz
1.1       root      220:                }
                    221:                NvRam_SetChecksum();
                    222:        }
                    223: 
                    224:        NvRam_Reset();
                    225: }
                    226: 
                    227: 
                    228: /*-----------------------------------------------------------------------*/
                    229: /**
                    230:  * De-Initialization
                    231:  */
                    232: void NvRam_UnInit(void)
                    233: {
                    234:        NvRam_Save();           // save NVRAM file upon exit automatically (should be conditionalized)
                    235: }
                    236: 
                    237: 
                    238: /*-----------------------------------------------------------------------*/
                    239: /**
                    240:  * Read from RTC/NVRAM offset selection register ($ff8961)
                    241:  */
                    242: void NvRam_Select_ReadByte(void)
                    243: {
                    244:        IoMem_WriteByte(0xff8961, nvram_index);
                    245: }
                    246: 
                    247: 
                    248: /*-----------------------------------------------------------------------*/
                    249: /**
                    250:  * Write to RTC/NVRAM offset selection register ($ff8961)
                    251:  */
                    252: void NvRam_Select_WriteByte(void)
                    253: {
                    254:        Uint8 value = IoMem_ReadByte(0xff8961);
                    255: 
                    256:        if (value < sizeof(nvram))
                    257:        {
                    258:                nvram_index = value;
                    259:        }
                    260:        else
                    261:        {
                    262:                Log_Printf(LOG_WARN, "NVRAM: trying to set out-of-bound position (%d)\n", value);
                    263:        }
                    264: }
                    265: 
                    266: 
                    267: /*-----------------------------------------------------------------------*/
                    268: /**
                    269:  * Read from RTC/NVRAM data register ($ff8963)
                    270:  */
                    271: void NvRam_Data_ReadByte(void)
                    272: {
1.1.1.2   root      273:        Uint8 value = 0;
1.1       root      274: 
                    275:        if (nvram_index == NVRAM_SECONDS || nvram_index == NVRAM_MINUTES || nvram_index == NVRAM_HOURS
                    276:            || (nvram_index >=NVRAM_DAY && nvram_index <=NVRAM_YEAR) )
                    277:        {
                    278:                /* access to RTC?  - then read host clock and return its values */
                    279:                time_t tim = time(NULL);
                    280:                struct tm *curtim = localtime(&tim);    /* current time */
                    281:                switch(nvram_index)
                    282:                {
                    283:                        case NVRAM_SECONDS: value = curtim->tm_sec; break;
                    284:                        case NVRAM_MINUTES: value = curtim->tm_min; break;
                    285:                        case NVRAM_HOURS: value = curtim->tm_hour; break;
                    286:                        case NVRAM_DAY: value = curtim->tm_mday; break;
                    287:                        case NVRAM_MONTH: value = curtim->tm_mon+1; break;
                    288:                        case NVRAM_YEAR: value = curtim->tm_year - 68; break;
                    289:                }
                    290:        }
                    291:        else if (nvram_index == 10)
                    292:        {
1.1.1.2   root      293:                static bool rtc_uip = true;
1.1       root      294:                value = rtc_uip ? 0x80 : 0;
                    295:                rtc_uip = !rtc_uip;
                    296:        }
                    297:        else if (nvram_index == 13)
                    298:        {
                    299:                value = 0x80;   // Valid RAM and Time bit
                    300:        }
                    301:        else if (nvram_index < 14)
                    302:        {
                    303:                Log_Printf(LOG_DEBUG, "Read from unsupported RTC/NVRAM register 0x%x.\n", nvram_index);
                    304:                value = nvram[nvram_index];
                    305:        }
                    306:        else
                    307:        {
                    308:                value = nvram[nvram_index];
                    309:        }
                    310: 
1.1.1.7   root      311:        LOG_TRACE(TRACE_NVRAM, "NVRAM: read data at %d = %d ($%02x)\n", nvram_index, value, value);
1.1       root      312:        IoMem_WriteByte(0xff8963, value);
                    313: }
                    314: 
                    315: 
                    316: /*-----------------------------------------------------------------------*/
                    317: /**
                    318:  * Write to RTC/NVRAM data register ($ff8963)
                    319:  */
                    320: 
                    321: void NvRam_Data_WriteByte(void)
                    322: {
                    323:        Uint8 value = IoMem_ReadByte(0xff8963);
1.1.1.7   root      324:        LOG_TRACE(TRACE_NVRAM, "NVRAM: write data at %d = %d ($%02x)\n", nvram_index, value, value);
1.1       root      325:        nvram[nvram_index] = value;
                    326: }

unix.superglobalmegacorp.com

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