📄 main.c
字号:
if (menu)/*return to main menu*/
{
menustate = MENU_MAIN1;
menusub = 0;
OsdClear();
}
break;
/******************************************************************/
/*reset menu*/
/******************************************************************/
case MENU_RESET1:
/*menu title*/
OsdWrite(0," Reset Minimig?",0);
OsdWrite(2," yes",menusub==0);
OsdWrite(3," no",menusub==1);
/*goto to second state of reset menu*/
menustate = MENU_RESET2;
break;
case MENU_RESET2:
if (down && menusub<1)
{
menusub++;
menustate = MENU_RESET1;
}
if (up && menusub>0)
{
menusub--;
menustate = MENU_RESET1;
}
if (select)
{
if (menusub==0)
{
OsdReset(0);
menustate = MENU_NONE1;
}
}
if (menu || (select && menusub==1))/*exit menu*/
{
menustate = MENU_MAIN1;
menusub = 2;
OsdClear();
}
break;
/******************************************************************/
/*settings menu*/
/******************************************************************/
case MENU_SETTINGS1:
/*menu title*/
OsdWrite(0," ** SETTINGS **",0);
strcpy(s," Lores Filter: ");
strcpy(&s[16],filter_msg[lr_filter]);
OsdWrite(2,s,menusub==0);
strcpy(s," Hires Filter: ");
strcpy(&s[16],filter_msg[hr_filter]);
OsdWrite(3,s,menusub==1);
strcpy(s," RAM: ");
strcpy(&s[7],memcfg_msg[memcfg]);
OsdWrite(4,s,menusub==2);
strcpy(s," ROM: ");
strncpy(&s[7],kickname,8);
OsdWrite(5,s,menusub==3);
OsdWrite(7," exit",menusub==4);
/*goto to second state of reset menu*/
menustate = MENU_SETTINGS2;
break;
case MENU_SETTINGS2:
if (down && menusub<4)
{
menusub++;
menustate = MENU_SETTINGS1;
}
if (up && menusub>0)
{
menusub--;
menustate = MENU_SETTINGS1;
}
if (select)
{
if (menusub==0)
{
lr_filter++;
lr_filter &= 0x03;
menustate = MENU_SETTINGS1;
OsdFilter(lr_filter,hr_filter);
}
else if (menusub==1)
{
hr_filter++;
hr_filter &= 0x03;
menustate = MENU_SETTINGS1;
OsdFilter(lr_filter,hr_filter);
}
else if (menusub==2)
{
memcfg++;
memcfg &= 0x03;
menustate = MENU_SETTINGS1;
OsdMemoryConfig(memcfg);
}
else if (menusub==3)
{
if (df0.status&DSK_INSERTED)
OsdWrite(5," Remove floppy!",1);
else
{
menustate = MENU_ROMSELECT1;
OsdClear();
}
}
else if (menusub==4)
{
if (lr_filter != eeprom_read(EEPROM_LRFILTER))
eeprom_write(EEPROM_LRFILTER,lr_filter);
if (hr_filter != eeprom_read(EEPROM_HRFILTER))
eeprom_write(EEPROM_HRFILTER,hr_filter);
if (memcfg != eeprom_read(EEPROM_MEMCFG))
eeprom_write(EEPROM_MEMCFG,memcfg);
}
}
if (menu || (select && menusub==4)) /*return to main menu*/
{
menustate = MENU_MAIN1;
menusub = 1;
OsdClear();
}
break;
/******************************************************************/
/*kickstart rom select menu*/
/******************************************************************/
case MENU_ROMSELECT1:
/*menu title*/
OsdWrite(0," ** Kickstart **",0);
strcpy(s," ROM: ");
strncpy(&s[9],kickname,8);
s[9+8] = 0;
OsdWrite(2,s,0);
OsdWrite(3," select",menusub==0);
OsdWrite(4," rekick",menusub==1);
OsdWrite(5," rekick & save",menusub==2);
OsdWrite(7," exit",menusub==3);
/*goto to second state of reset menu*/
menustate = MENU_ROMSELECT2;
break;
case MENU_ROMSELECT2:
if (down && menusub<3)
{
menusub++;
menustate = MENU_ROMSELECT1;
}
if (up && menusub>0)
{
menusub--;
menustate = MENU_ROMSELECT1;
}
if (select)
{
if (menusub==0)
{
ScrollDir("ROM",0);
menustate = MENU_ROMFILE1;
OsdClear();
}
else if (menusub==1 || menusub==2)
{
OsdDisable();
menustate = MENU_NONE1;
OsdReset(1);
if (UploadKickstart(kickname)==0)
{
BootExit();
if (menusub==2)
{
for (i=0;i<8;i++)
{
if (kickname[i] != eeprom_read(EEPROM_KICKNAME+i))
eeprom_write(EEPROM_KICKNAME+i,kickname[i]);
}
}
}
}
}
if (menu || (select && menusub==3))/*return to settings menu*/
{
menustate = MENU_SETTINGS1;
menusub = 3;
OsdClear();
}
break;
/******************************************************************/
/*rom file requester menu*/
/******************************************************************/
case MENU_ROMFILE1:
PrintDir();
menustate = MENU_ROMFILE2;
break;
case MENU_ROMFILE2:
if (down)/*scroll down through file requester*/
{
ScrollDir("ROM",1);
menustate = MENU_ROMFILE1;
}
if (up)/*scroll up through file requester*/
{
ScrollDir("ROM",2);
menustate=MENU_ROMFILE1;
}
if (select)/*select rom file*/
{
menusub = 3;
if (directory[dirptr].len)
{
file = directory[dirptr];
strncpy(kickname,file.name,8+3);
menusub = 1;
}
ScrollDir("ADF",0);
menustate = MENU_ROMSELECT1;
OsdClear();
}
if (menu)/*return to kickstrat rom select menu*/
{
ScrollDir("ADF",0);
menustate = MENU_ROMSELECT1;
menusub = 0;
OsdClear();
}
break;
/******************************************************************/
/*error message menu*/
/******************************************************************/
case MENU_ERROR:
if (menu) /*exit when menu button is pressed*/
{
menustate = MENU_NONE1;
}
break;
/******************************************************************/
/*we should never come here*/
/******************************************************************/
default:
break;
}
}
void ErrorMessage(const char* message, unsigned char code)
{
unsigned char i;
menustate = MENU_ERROR;
OsdClear();
OsdWrite(0," *** ERROR ***",1);
strncpy(s,message,21);
s[21] = 0;
OsdWrite(2,s,0);
if (code)
{
sprintf(s," error #%d",code);
OsdWrite(4,s,0);
}
OsdEnable();
}
/*print the contents of directory[] and the pointer dirptr onto the OSD*/
void PrintDir(void)
{
unsigned char i;
for(i=0;i<21;i++)
s[i] = ' ';
s[21] = 0;
if (directory[0].len==0)
OsdWrite(1," No files!",1);
else
for(i=0;i<DIRSIZE;i++)
{
strncpy(&s[3],directory[i].name,8);
OsdWrite(i,s,i==dirptr);
}
}
/*This function "scrolls" through the flashcard directory and fills the directory[] array to be printed later.
modes set by <mode>:
0: fill directory[] starting at beginning of directory on flashcard
1: move down through directory
2: move up through directory
This function can also filter on filetype. <type> must point to a string containing the 3-letter filetype
to filter on. If the first character is a '*', no filter is applied (wildcard)*/
void ScrollDir(const unsigned char *type, unsigned char mode)
{
unsigned char i,rc;
switch (mode)
{
/*reset directory to beginning*/
case 0:
default:
i = 0;
mode = FILESEEK_START;
memset(directory,0,sizeof(directory));
/*fill directory with available files*/
while (i<DIRSIZE)
{
if (!FileSearch2(&file,mode))/*search file*/
break;
mode = FILESEEK_NEXT;
if ((type[0]=='*') || (strncmp(&file.name[8],type,3)==0))/*check filetype*/
directory[i++] = file;
}
/*clear rest of directory*/
while (i<DIRSIZE)
directory[i++].len = 0;
/*preset pointer*/
dirptr = 0;
break;
/*scroll down*/
case 1:
if (dirptr >= DIRSIZE-1)/*pointer is at bottom of directory window*/
{
file = directory[(DIRSIZE-1)];
/*search next file and check for filetype/wildcard and/or end of directory*/
do
rc = FileSearch2(&file,FILESEEK_NEXT);
while ((type[0]!='*') && (strncmp(&file.name[8],type,3)) && rc);
/*update directory[] if file found*/
if (rc)
{
for (i=0;i<DIRSIZE-1;i++)
directory[i] = directory[i+1];
directory[DIRSIZE-1] = file;
}
}
else/*just move pointer in window*/
{
dirptr++;
if (directory[dirptr].len==0)
dirptr--;
}
break;
/*scroll up*/
case 2:
if (dirptr==0)/*pointer is at top of directory window*/
{
file = directory[0];
/*search previous file and check for filetype/wildcard and/or end of directory*/
do
rc = FileSearch2(&file,FILESEEK_PREV);
while ((type[0]!='*') && (strncmp(&file.name[8],type,3)) && rc);
/*update directory[] if file found*/
if (rc)
{
for (i=DIRSIZE-1;i>0;i--)
directory[i] = directory[i-1];
directory[0] = file;
}
}
else/*just move pointer in window*/
dirptr--;
break;
}
}
/*insert floppy image pointed to to by global <file> into <drive>*/
void InsertFloppy(struct adfTYPE *drive)
{
unsigned char i,j;
/*clear OSD and prepare progress bar*/
OsdClear();
OsdWrite(0," Inserting floppy",0);
OsdWrite(1," in DF0",0);
strcpy(s,"[ ]");
/*fill cache*/
for(i=0;i<160;i++)
{
if (i%9==0)
{
s[(i/9)+1]='*';
OsdWrite(3,s,0);
}
drive->cache[i]=file.cluster;
for(j=0;j<11;j++)
FileNextSector2(&file);
}
/*copy name*/
for(i=0;i<12;i++)
drive->name[i]=file.name[i];
/*initialize rest of struct*/
drive->status = DSK_INSERTED;
if (!(file.attributes&0x01))//read-only attribute
drive->status |= DSK_WRITABLE;
drive->clusteroffset=drive->cache[0];
drive->sectoroffset=0;
drive->track=0;
drive->trackprev=-1;
printf("Inserting floppy: \"%s\", attributes: %02X\r",file.name,file.attributes);
printf("drive status: %02X\r",drive->status);
}
/*Handle an FPGA command*/
void HandleFpgaCmd(unsigned char c1, unsigned char c2)
{
/*c1 is command byte*/
switch(c1&(CMD_GETDSKSTAT|CMD_RDTRCK|CMD_WRTRCK))
{
/*FPGA is requesting track status*/
case CMD_GETDSKSTAT:
CheckTrack(&df0);
break;
/*FPGA wants to read a track
c2 is track number*/
case CMD_RDTRCK:
df0.track=c2;
DISKLED=1;
ReadTrack(&df0);
DISKLED=0;
break;
/*FPGA wants to write a track
c2 is track number*/
case CMD_WRTRCK:
df0.track=c2;
DISKLED=1;
WriteTrack(&df0);
DISKLED=0;
break;
/*no command*/
default:
break;
}
}
/*CheckTrack, respond with disk status*/
void CheckTrack(struct adfTYPE *drive)
{
EnableFpga();
SPI(0x00);
SPI(0x00);
SPI(0x00);
SPI(drive->status);
DisableFpga();
}
/*load kickstart rom*/
void SendFile(struct file2TYPE *file)
{
unsigned char c1,c2;
unsigned char j;
unsigned short n;
unsigned char *p;
n = file->len/512; //sector count (rounded up)
while (n--)
{
/*read sector from mmc*/
FileRead2(file);
do
{
/*read command from FPGA*/
EnableFpga();
c1=SPI(0);
c2=SPI(0);
SPI(0);
SPI(1); // disk present status
DisableFpga();
}
while(!(c1&0x02));
putchar('.');
/*send sector to fpga*/
EnableFpga();
c1=SPI(0);
c2=SPI(0);
SPI(0);
SPI(1);
p=secbuf;
j=128;
do
{
SSPBUF=*(p++);
while(!BF);
SSPBUF=*(p++);
while(!BF);
SSPBUF=*(p++);
while(!BF);
SSPBUF=*(p++);
while(!BF);
}
while(--j);
DisableFpga();
FileNextSector2(file);
}
}
/*configure FPGA*/
unsigned char ConfigureFpga(void)
{
unsigned short t;
unsigned char *ptr;
/*reset FGPA configuration sequence*/
PROG_B=0;
PROG_B=1;
/*now wait for INIT to go high*/
t=50000;
while(!INIT_B)
if (--t==0)
{
printf("FPGA init is NOT high!\r");
FatalError(3);
//return(0);
}
printf("FPGA init is high\r");
if (DONE)
{
printf("FPGA done is high before configuration!\r");
FatalError(3);
}
/*open bitstream file*/
if (Open("MINIMIG1BIN")==0)
{
printf("No FPGA configuration file found!\r");
FatalError(4);
}
printf("FPGA bitstream file opened\r");
/*send all bytes to FPGA in loop*/
t=0;
do
{
/*read sector if 512 (64*8) bytes done*/
if (t%64==0)
{
DISKLED = !((t>>9)&1);
putchar('*');
if (!FileRead2(&file))
return(0);
ptr=secbuf;
}
/*send data in packets of 8 bytes*/
ShiftFpga(*(ptr++));
ShiftFpga(*(ptr++));
ShiftFpga(*(ptr++));
ShiftFpga(*(ptr++));
ShiftFpga(*(ptr++));
ShiftFpga(*(ptr++));
ShiftFpga(*(ptr++));
ShiftFpga(*(ptr++));
t++;
/*read next sector if 512 (64*8) bytes done*/
if (t%64==0)
{
FileNextSector2(&file);
}
}
while(t<26549);
printf("\rFPGA bitstream loaded\r");
DISKLED = 0;
/*check if DONE is high*/
if (DONE)
return(1);
else
{
printf("FPGA done is NOT high!\r");
FatalError(5);
}
return 0;
}
/*read a track from disk*/
void ReadTrack(struct adfTYPE *drive)
{ //track number is updated in drive struct before calling this function
unsigned char sector;
unsigned char c,c1,c2,c3,c4;
unsigned short n;
/*display track number: cylinder & head*/
#ifdef DEBUG
printf("*%d:",drive->track);
#endif
if (drive->track != drive->trackprev)
{/*track step or track 0, start at beginning of track*/
drive->trackprev = drive->track;
sector = 0;
file.cluster = drive->cache[drive->track];
file.sec = drive->track*11;
drive->sectoroffset = sector;
drive->clusteroffset = file.cluster;
}
else
{/*same track, start at next sector in track*/
sector = drive->sectoroffset;
file.cluster = drive->clusteroffset;
file.sec = (drive->track*11)+sector;
}
EnableFpga();
c1 = SPI(0); //read request signal
c2 = SPI(0); //track number (cylinder & head)
c3 = 0x3F&SPI(0); //msb of mfm words to transfer
c4 = SPI(drive->status); //lsb of mfm words to transfer
DisableFpga();
// if dma read count is bigger than 11 sectors then we start the transfer from the begining of current track
if ((c3>0x17) || (c3==0x17 && c4>=0x60))
{
sector = 0;
file.cluster = drive->cache[drive->track];
file.sec = drive->track*11;
}
while (1)
{
FileRead2(&file);
EnableFpga();
/*check if FPGA is still asking for data*/
c1 = SPI(0); //read request signal
c2 = SPI(0); //track number (cylinder & head)
c3 = SPI(0); //msb of mfm words to transfer
c4 = SPI(drive->status); //lsb of mfm words to transfer
#ifdef DEBUG
c = sector + '0';
if (c>'9')
c += 'A'-'9'-1;
putchar(c);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -