MCUME/MCUME_teensy41/teensyhandy/eeprom.cpp

317 wiersze
8.4 KiB
C++

//////////////////////////////////////////////////////////////////////////////
// Lynx 3wire EEPROM Class //
//////////////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "system.h"
#include "eeprom.h"
CEEPROM::CEEPROM(UBYTE typ)
{
*filename=0;
memset(romdata, 0xff, sizeof(romdata));
Reset();
SetEEPROMType(type);
}
void CEEPROM::Reset(void)
{
busy_count=0;
state=EE_NONE;
readdata=0;
data=0;
addr=0;
sendbits=0;
readonly=true;
counter=0;
iodir=0;
iodat=0;
mAUDIN_ext=0;
}
CEEPROM::~CEEPROM()
{
}
void CEEPROM::Load(void)
{
if(!Available()) return;
FILE *fe;
if((fe=fopen(filename,"rb"))!=NULL){
log_printf("EEPROM: Loading from '%s'\n",filename);
fread(romdata,1,1024,fe);
fclose(fe);
}
}
void CEEPROM::Save(void)
{
if(!Available()) return;
FILE *fe;
if((fe=fopen(filename,"wb+"))!=NULL){
log_printf("EEPROM: Saving to '%s'\n",filename);
fwrite(romdata,1,Size(),fe);
fclose(fe);
}
}
bool CEEPROM::ContextSave(LSS_FILE *fp)
{
if(!lss_printf(fp,"CEEPROM::ContextSave")) return 0;
if(!lss_write(&busy_count,sizeof(ULONG),1,fp)) return 0;
if(!lss_write(&state,sizeof(ULONG),1,fp)) return 0;
if(!lss_write(&readdata,sizeof(UWORD),1,fp)) return 0;
if(!lss_write(&data,sizeof(ULONG),1,fp)) return 0;
if(!lss_write(&addr,sizeof(UWORD),1,fp)) return 0;
if(!lss_write(&sendbits,sizeof(ULONG),1,fp)) return 0;
if(!lss_write(&readonly,sizeof(UBYTE),1,fp)) return 0;
if(!lss_write(&counter,sizeof(UWORD),1,fp)) return 0;
if(!lss_write(&iodir,sizeof(UBYTE),1,fp)) return 0;
if(!lss_write(&iodat,sizeof(UBYTE),1,fp)) return 0;
if(!lss_write(&mAUDIN_ext,sizeof(UBYTE),1,fp)) return 0;
if(!lss_write(&romdata,sizeof(UWORD),1024,fp)) return 0;
return 1;
}
bool CEEPROM::ContextLoad(LSS_FILE *fp)
{
char teststr[32]="XXXXXXXXXXXXXXXXXXXX";
if(!lss_read(teststr,sizeof(char),20,fp)) return 0;
teststr[20]=0;
if(strcmp(teststr,"CEEPROM::ContextSave")!=0) return 0;
if(!lss_read(&busy_count,sizeof(ULONG),1,fp)) return 0;
if(!lss_read(&state,sizeof(ULONG),1,fp)) return 0;
if(!lss_read(&readdata,sizeof(UWORD),1,fp)) return 0;
if(!lss_read(&data,sizeof(ULONG),1,fp)) return 0;
if(!lss_read(&addr,sizeof(UWORD),1,fp)) return 0;
if(!lss_read(&sendbits,sizeof(ULONG),1,fp)) return 0;
if(!lss_read(&readonly,sizeof(UBYTE),1,fp)) return 0;
if(!lss_read(&counter,sizeof(UWORD),1,fp)) return 0;
if(!lss_read(&iodir,sizeof(UBYTE),1,fp)) return 0;
if(!lss_read(&iodat,sizeof(UBYTE),1,fp)) return 0;
if(!lss_read(&mAUDIN_ext,sizeof(UBYTE),1,fp)) return 0;
if(!lss_read(&romdata,sizeof(UWORD),1024,fp)) return 0;
return 1;
}
void CEEPROM::SetEEPROMType(UBYTE b)
{
type=b;
const char *type = "none";
switch(b&0x7) {
case 1: // 93C46 , 8 bit mode
ADDR_MASK = 0x7F;
CMD_BITS = 10;
ADDR_BITS = 7;
type = "93C46";
break;
case 2: // 93C56 , 8 bit mode
ADDR_MASK = 0xFF;
CMD_BITS = 12;
ADDR_BITS = 9;
type = "93C56";
break;
case 3: // 93C66 , 8 bit mode
ADDR_MASK = 0x1FF;
CMD_BITS = 12;
ADDR_BITS = 9;
type = "93C66";
break;
case 4: // 93C76 , 8 bit mode
ADDR_MASK = 0x3FF;
CMD_BITS = 14;
ADDR_BITS = 11;
type = "93C76";
break;
case 5: // 93C86 , 8 bit mode
ADDR_MASK = 0x7FF;
CMD_BITS = 14;
ADDR_BITS = 11;
type = "93C86";
break;
case 0: // NONE, fallthrou
default:
ADDR_MASK = 0;
CMD_BITS = 1;
ADDR_BITS = 1;
break;
}
if(b&0x80) { // 8 bit access
DONE_MASK = 0x100;
log_printf("EEPROM: Type: %s 8bit\n", type);
} else { // 16 bit access
ADDR_MASK>>=1;
CMD_BITS--;
ADDR_BITS--;
DONE_MASK = 0x10000;
log_printf("EEPROM: Type: %s 16bit\n", type);
}
}
int CEEPROM::Size(void)
{
int m=ADDR_MASK+1;
if(type&0x80) return m; else return m*2;
}
void CEEPROM::ProcessEepromBusy(void)
{
if(state==EE_BUSY || state==EE_NONE) {
if(busy_count<2) {
busy_count++;
readdata=0x0000;// RDY
mAUDIN_ext=0;
} else {
readdata=0xFFFF;// RDY
mAUDIN_ext=1;
state=EE_WAIT;
}
// printf("(%d)",busy_count);
}
}
void CEEPROM::ProcessEepromCounter(UWORD cnt)
{
// Update if either counter strobed or AUDIN changed
UpdateEeprom( cnt);
}
void CEEPROM::ProcessEepromIO(UBYTE iodir_loc,UBYTE iodat_loc)
{
// Update if either counter strobed or AUDIN changed
iodat=iodat_loc;
iodir=iodir_loc;
}
void CEEPROM::UpdateEeprom(UWORD cnt)
{
// Update if either counter strobed or AUDIN changed
bool CLKp, CLKn;
CLKp=counter&0x02;
counter=cnt;
CLKn=counter&0x02;
if( CLKp!=CLKn && CLKn) { // Rising edge
bool CS, DI;
mAUDIN_ext=(readdata&(DONE_MASK>>1)) ? 1 : 0 ;
readdata<<=1;
CS=cnt&0x80;
DI=false;
if(iodir&0x10) {
DI=iodat&0x10;
}
if(!CS) state=EE_NONE;
switch(state) {
case EE_NONE:
data=0;
if( CS) {
if(DI && (iodir&0x10)) {
//if( state!=EE_START) printf("EE Start...\n");
mAUDIN_ext=0;
state=EE_START;
data=0;
sendbits=CMD_BITS-1;
} else if(!(iodir&0x10)) {
state=EE_BUSY;
//printf("BUSY\n");
readdata=0x0000;// RDY
mAUDIN_ext=0;
busy_count=0;
}
}
break;
case EE_START:
data<<=1;
if(DI) data++;
sendbits--;
if( sendbits>0) break;
state=EE_NONE;
// if(data!=(0xFFFF&((ADDR_MASK<<2)|0x3))) printf("EE Byte $%02X .. ",(int)data);
addr=data&ADDR_MASK;
switch(data>>ADDR_BITS) {
case 0x3:
if(!readonly) {
// printf("ERASE ADD $%02X RO %d\n",(int)addr,readonly);
romdata[addr]=0xFFFF;
}
break;
case 0x2:
if(type&0x80) readdata=((unsigned char *)romdata)[addr]; else readdata=romdata[addr];
mAUDIN_ext=0;
// printf("Read ADD $%02X $%04X\n",(int)addr,readdata);
state=EE_WAIT;
break;
case 0x1:
// printf("Write ADD $%02X RO %d\n",(int)addr,readonly);
data=0x1;
state=EE_DATA;
break;
case 0x00:
if((data>>(ADDR_BITS-2))==0x0) {
// printf("EWDS\n");
readonly=true;
break;
};
if((data>>(ADDR_BITS-2))==0x3) {
// printf("EWEN\n");
readonly=false;
break;
};
if((data>>(ADDR_BITS-2))==0x1) {
// printf("WRAL\n");
break;
};
if((data>>(ADDR_BITS-2))==0x2) {
// printf("ERAL\n");
break;
};
// falltrhou
default:
// printf("Unknown $%03X\n",(int)data);
break;
}
break;
case EE_DATA:
data<<=1;
if(DI) data++;
if(data&DONE_MASK) {
state=EE_NONE;
// printf("EE Written Data $%04X ",(unsigned int)data&0xFFFF);
if(readonly) {
// printf("WRITE PROT!\n");
} else {
if(type &0x80){
((unsigned char *)romdata)[addr]=(data&0xFF);
} else {
romdata[addr]=(data&0xFFFF);
}
// printf("done\n");
}
busy_count=0;
readdata=0x0000;// RDY
mAUDIN_ext=0;
state=EE_WAIT;
}
break;
case EE_WAIT:
// printf(".%d.",mAUDIN_ext);
break;
}
}
}