Flash.cpp

Go to the documentation of this file.
00001 /* ES40 emulator.
00002  * Copyright (C) 2007-2008 by the ES40 Emulator Project
00003  *
00004  * Website: http://sourceforge.net/projects/es40
00005  * E-mail : camiel@camicom.com
00006  * 
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  * 
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00020  * 
00021  * Although this is not required, the author would appreciate being notified of, 
00022  * and receiving any modifications you may make to the source code that might serve
00023  * the general public.
00024  */
00025 
00092 #include "StdAfx.h"
00093 #include "Flash.h"
00094 #include "System.h"
00095 #include "AlphaCPU.h"
00096 
00097 // These are the modes for our flash-state-machine.
00098 #define MODE_READ         0
00099 #define MODE_STEP1        1
00100 #define MODE_STEP2        2
00101 #define MODE_AUTOSEL      3
00102 #define MODE_PROGRAM      4
00103 #define MODE_ERASE_STEP3  5
00104 #define MODE_ERASE_STEP4  6
00105 #define MODE_ERASE_STEP5  7
00106 #define MODE_CONFIRM_0    8
00107 #define MODE_CONFIRM_1    9
00108 
00109 extern CAlphaCPU*   cpu[4];
00110 
00114 CFlash::CFlash(CConfigurator* cfg, CSystem* c) : CSystemComponent(cfg, c)
00115 {
00116   if(theSROM)
00117     FAILURE(Configuration, "More than one Flash");
00118   theSROM = this;
00119   c->RegisterMemory(this, 0, U64(0x0000080100000000), 0x8000000); // 2MB
00120   memset(state.Flash, 0xff, 2 * 1024 * 1024);
00121   RestoreStateF();
00122   state.mode = MODE_READ;
00123 
00124   printf("%s: $Id: Flash.cpp,v 1.19 2008/03/24 22:11:50 iamcamiel Exp $\n",
00125          devid_string);
00126 }
00127 
00131 CFlash::~CFlash()
00132 { }
00133 
00139 u64 CFlash::ReadMem(int index, u64 address, int dsize)
00140 {
00141   u64 data = 0;
00142   int a = (int) (address >> 6);
00143 
00144   switch(state.mode)
00145   {
00146   case MODE_AUTOSEL:
00147     switch(a)
00148     {
00149     case 0:   data = 1;     // manufacturer
00150       break;
00151     case 1:   data = 0xad;  // device
00152       break;
00153     default:  data = 0;
00154     }
00155     break;
00156 
00157   case MODE_CONFIRM_0:
00158     data = 0x80;
00159     state.mode = MODE_READ;
00160     break;
00161 
00162   case MODE_CONFIRM_1:
00163     data = 0x80;
00164     state.mode = MODE_CONFIRM_0;
00165     break;
00166 
00167   default:
00168     data = state.Flash[a];
00169   }
00170 
00171   return data;
00172 }
00173 
00217 void CFlash::WriteMem(int index, u64 address, int dsize, u64 data)
00218 {
00219   int a = (int) (address >> 6);
00220 
00221   switch(state.mode)
00222   {
00223   case MODE_READ:
00224   case MODE_AUTOSEL:
00225     if((a == 0x5555) && (data == 0xaa))
00226     {
00227       state.mode = MODE_STEP1;
00228       return;
00229     }
00230 
00231     state.mode = MODE_READ;
00232     return;
00233 
00234   case MODE_STEP1:
00235     if((a == 0x2aaa) && (data == 0x55))
00236     {
00237       state.mode = MODE_STEP2;
00238       return;
00239     }
00240 
00241     state.mode = MODE_READ;
00242     return;
00243 
00244   case MODE_STEP2:
00245     if(a != 0x5555)
00246     {
00247       state.mode = MODE_READ;
00248       return;
00249     }
00250 
00251     switch(data)
00252     {
00253     case 0x90:  state.mode = MODE_AUTOSEL; return;
00254     case 0xa0:  state.mode = MODE_PROGRAM; return;
00255     case 0x80:  state.mode = MODE_ERASE_STEP3; return;
00256     }
00257 
00258     state.mode = MODE_READ;
00259     return;
00260 
00261   case MODE_ERASE_STEP3:
00262     if((a == 0x5555) && (data == 0xaa))
00263     {
00264       state.mode = MODE_ERASE_STEP4;
00265       return;
00266     }
00267 
00268     state.mode = MODE_READ;
00269     return;
00270 
00271   case MODE_ERASE_STEP4:
00272     if((a == 0x2aaa) && (data == 0x55))
00273     {
00274       state.mode = MODE_ERASE_STEP5;
00275       return;
00276     }
00277 
00278     state.mode = MODE_READ;
00279     return;
00280 
00281   case MODE_ERASE_STEP5:
00282     if((a == 0x5555) && (data == 0x10))
00283     {
00284       memset(state.Flash, 0xff, 1 << 21);
00285       state.mode = MODE_CONFIRM_1;
00286       return;
00287     }
00288 
00289     if(data == 0x30)
00290     {
00291       memset(&state.Flash[(a >> 16) << 16], 0xff, 1 << 16);
00292       state.mode = MODE_CONFIRM_1;
00293       return;
00294     }
00295 
00296     state.mode = MODE_READ;
00297     return;
00298   }
00299 
00300   // we must now be in mode program...
00301   state.Flash[a] = (u8) data;
00302   state.mode = MODE_READ;
00303 }
00304 
00308 void CFlash::SaveStateF(char* fn)
00309 {
00310   FILE*   ff;
00311   ff = fopen(fn, "wb");
00312   if(ff)
00313   {
00314     SaveState(ff);
00315     fclose(ff);
00316     printf("%%FLS-I-SAVEST: Flash state saved to %s\n", fn);
00317   }
00318   else
00319   {
00320     printf("%%FLS-F-NOSAVE: Flash could not be saved to %s\n", fn);
00321   }
00322 }
00323 
00327 void CFlash::SaveStateF()
00328 {
00329   SaveStateF(myCfg->get_text_value("rom.flash", "flash.rom"));
00330 }
00331 
00335 void CFlash::RestoreStateF(char* fn)
00336 {
00337   FILE*   ff;
00338   ff = fopen(fn, "rb");
00339   if(ff)
00340   {
00341     RestoreState(ff);
00342     fclose(ff);
00343     printf("%%FLS-I-RESTST: Flash state restored from %s\n", fn);
00344   }
00345   else
00346   {
00347     printf("%%FLS-F-NOREST: Flash could not be restored from %s\n", fn);
00348   }
00349 }
00350 
00354 void CFlash::RestoreStateF()
00355 {
00356   RestoreStateF(myCfg->get_text_value("rom.flash", "flash.rom"));
00357 }
00358 
00359 static u32  flash_magic1 = 0xFF3E3FF3;
00360 static u32  flash_magic2 = 0x3FF3E3FF;
00361 
00365 int CFlash::SaveState(FILE* f)
00366 {
00367   long  ss = sizeof(state);
00368   fwrite(&flash_magic1, sizeof(u32), 1, f);
00369   fwrite(&ss, sizeof(long), 1, f);
00370   fwrite(&state, sizeof(state), 1, f);
00371   fwrite(&flash_magic2, sizeof(u32), 1, f);
00372   printf("flash: %d bytes saved.\n", ss);
00373   return 0;
00374 }
00375 
00379 int CFlash::RestoreState(FILE* f)
00380 {
00381   long    ss;
00382   u32     m1;
00383   u32     m2;
00384   size_t  r;
00385 
00386   r = fread(&m1, sizeof(u32), 1, f);
00387   if(r != 1)
00388   {
00389     printf("flash: unexpected end of file!\n");
00390     return -1;
00391   }
00392 
00393   if(m1 != flash_magic1)
00394   {
00395     printf("flash: MAGIC 1 does not match!\n");
00396     return -1;
00397   }
00398 
00399   fread(&ss, sizeof(long), 1, f);
00400   if(r != 1)
00401   {
00402     printf("flash: unexpected end of file!\n");
00403     return -1;
00404   }
00405 
00406   if(ss != sizeof(state))
00407   {
00408     printf("flash: STRUCT SIZE does not match!\n");
00409     return -1;
00410   }
00411 
00412   fread(&state, sizeof(state), 1, f);
00413   if(r != 1)
00414   {
00415     printf("flash: unexpected end of file!\n");
00416     return -1;
00417   }
00418 
00419   r = fread(&m2, sizeof(u32), 1, f);
00420   if(r != 1)
00421   {
00422     printf("flash: unexpected end of file!\n");
00423     return -1;
00424   }
00425 
00426   if(m2 != flash_magic2)
00427   {
00428     printf("flash: MAGIC 1 does not match!\n");
00429     return -1;
00430   }
00431 
00432   printf("flash: %d bytes restored.\n", ss);
00433   return 0;
00434 }
00435 
00436 CFlash*   theSROM = 0;

SourceForge.net Logo
Project space on SourceForge.net