⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 Verilog, c and asm source codes of the Minimig system, a fpga implementation of the Amiga computer.
💻 C
📖 第 1 页 / 共 3 页
字号:
			
			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 + -