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

📄 main.c

📁 Verilog, c and asm source codes of the Minimig system, a fpga implementation of the Amiga computer.
💻 C
📖 第 1 页 / 共 3 页
字号:
		putchar(':');
		c = ((c3>>4)&0xF) + '0';
		if (c>'9')
			c += 'A'-'9'-1;
		putchar(c);
		c = (c3&0xF) + '0';
		if (c>'9')
			c += 'A'-'9'-1;
		putchar(c);

		c = ((c4>>4)&0xF) + '0';
		if (c>'9')
			c += 'A'-'9'-1;
		putchar(c);
		c = (c4&0xF) + '0';
		if (c>'9')
			c += 'A'-'9'-1;
		putchar(c);
	#endif

		c3 &= 0x3F;

		//some loaders stop dma if sector header isn't what they expect
		//we don't check dma transfer count after sending every word
		//so the track can be changed while we are sending the rest of the previous sector
		//in this case let's start transfer from the beginning
		if (c2 == drive->track)				
		/*send sector if fpga is still asking for data*/
		if (c1&0x02)
		{
			if (c3==0 && c4<4)
				SectorHeaderToFpga(c4);
			else 
			{
				n = SectorToFpga(sector,drive->track);

				
			#ifdef DEBUG					// printing remaining dma count 
				putchar('-');
				c = ((n>>12)&0xF) + '0';
				if (c>'9')
					c += 'A'-'9'-1;
				putchar(c);
				c = ((n>>8)&0xF) + '0';
				if (c>'9')
					c += 'A'-'9'-1;
				putchar(c);
		
				c = ((n>>4)&0xF) + '0';
				if (c>'9')
					c += 'A'-'9'-1;
				putchar(c);
				c = (n&0xF) + '0';
				if (c>'9')
					c += 'A'-'9'-1;
				putchar(c);					
			#endif

				n--;
				c3 = (n>>8)&0x3F;
				c4 = n;

				if (c3==0 && c4<4)
				{
					SectorHeaderToFpga(c4);
				#ifdef DEBUG
					putchar('+');
					c4 += '0';
					putchar(c4);	
				#endif
				}
				else 
				if (sector==10)
				{
					SectorGapToFpga();
				#ifdef DEBUG
					putchar('+');
					putchar('+');
					putchar('+');
				#endif
				}
			}	
		}
		
		/*we are done accessing FPGA*/
		DisableFpga();

		//track has changed
		if (c2 != drive->track)
			break;

		//read dma request
		if (!(c1&0x02))
			break;


		//don't go to the next sector if there is not enough data in the fifo
		if (c3==0 && c4<4)
			break;

		// go to the next sector
		sector++;
		if (sector<11)
		{			
			FileNextSector2(&file);
		}
		else	//go to the start of current track
		{
			sector       = 0;
			file.cluster = drive->cache[drive->track];
			file.sec     = drive->track*11;
		}
		
		//remember current sector and cluster
		drive->sectoroffset  = sector;
		drive->clusteroffset = file.cluster;

	#ifdef DEBUG
		putchar('-');
		putchar('>');
	#endif

	}

#ifdef DEBUG
	putchar(':');
	putchar('O');
	putchar('K');
	putchar('\r');
#endif

}

void WriteTrack(struct adfTYPE *drive)
{
	unsigned char sector;
	unsigned char Track;
	unsigned char Sector;
	
	//setting file pointer to begining of current track
	file.cluster = drive->cache[drive->track];
	file.sec     = drive->track*11;
	sector = 0;

	drive->trackprev = drive->track+1;	//just to force next read from the start of current track

#ifdef DEBUG
	printf("*%d:\r",drive->track);
#endif

	while (FindSync(drive))
	{
		if (GetHeader(&Track,&Sector))
		{
			if (Track == drive->track)
			{
				while (sector != Sector)
				{
					if (sector < Sector)
					{
						FileNextSector2(&file);
						sector++;
					}
					else
					{
						file.cluster = drive->cache[drive->track];
						file.sec     = drive->track*11;
						sector = 0;
					}
				}				
	
				if (GetData())
				{
					if (drive->status&DSK_WRITABLE)
						FileWrite2(&file);
					else
					{
						Error = 30;
						printf("Write attempt to protected disk!\r");
					}
				}
			}
			else
				Error = 27;		//track number reported in sector header is not the same as current drive track
		}
		if (Error)
		{
			printf("WriteTrack: error %d\r",Error);
			ErrorMessage("  WriteTrack",Error);
		}
	}

}

unsigned char FindSync(struct adfTYPE *drive)
//this function reads data from fifo till it finds sync word
// or fifo is empty and dma inactive (so no more data is expected)
{
	unsigned char c1,c2,c3,c4;
	unsigned short n;

	while (1)
	{
		EnableFpga();
		c1 = SPI(0);			//write request signal
		c2 = SPI(0);			//track number (cylinder & head)
		if (!(c1&CMD_WRTRCK))
			break;
		if (c2 != drive->track)
			break;
		c3 = SPI(0)&0xBF;		//msb of mfm words to transfer 
		c4 = SPI(0);			//lsb of mfm words to transfer

		if (c3==0 && c4==0)
			break;

		n = ((c3&0x3F)<<8) + c4;

		while (n--)
		{
			c3 = SPI(0);
			c4 = SPI(0);
			if (c3==0x44 && c4==0x89)
			{
				DisableFpga();
			#ifdef DEBUG
				printf("#SYNC:");
			#endif
				return 1;
			}
		}
		DisableFpga();
	}
	DisableFpga();
	return 0;
}

unsigned char GetHeader(unsigned char *pTrack, unsigned char *pSector)
//this function reads data from fifo till it finds sync word or dma is inactive
{
	unsigned char c,c1,c2,c3,c4;
	unsigned char i;
	unsigned char checksum[4];

	Error = 0;
	while (1)
	{
		EnableFpga();
		c1 = SPI(0);			//write request signal
		c2 = SPI(0);			//track number (cylinder & head)
		if (!(c1&CMD_WRTRCK))
			break;
		c3 = SPI(0);			//msb of mfm words to transfer 
		c4 = SPI(0);			//lsb of mfm words to transfer

		if ((c3&0x3F)!=0 || c4>24)	//remaining header data is 25 mfm words
		{
			c1 = SPI(0);		//second sync lsb
			c2 = SPI(0);		//second sync msb
			if (c1!=0x44 || c2!=0x89)
			{
				Error = 21;
				printf("\rSecond sync word missing...\r",c1,c2,c3,c4);
				break;
			}

			c = SPI(0);
			checksum[0] = c;
			c1 = (c&0x55)<<1;
			c = SPI(0);
			checksum[1] = c;
			c2 = (c&0x55)<<1;
			c = SPI(0);
			checksum[2] = c;
			c3 = (c&0x55)<<1;
			c = SPI(0);
			checksum[3] = c;
			c4 = (c&0x55)<<1;

			c = SPI(0);
			checksum[0] ^= c;
			c1 |= c&0x55;
			c = SPI(0);
			checksum[1] ^= c;
			c2 |= c&0x55;
			c = SPI(0);
			checksum[2] ^= c;
			c3 |= c&0x55;
			c = SPI(0);
			checksum[3] ^= c;
			c4 |= c&0x55;

			if (c1 != 0xFF)		//always 0xFF
				Error = 22;
			else if (c2 > 159)		//Track number (0-159)
				Error = 23;
			else if (c3 > 10)		//Sector number (0-10)
				Error = 24;
			else if (c4>11 || c4==0)	//Number of sectors to gap (1-11)
				Error = 25;

			if (Error)
			{
				printf("\rWrong header: %d.%d.%d.%d\r",c1,c2,c3,c4);
				break;
			}

		#ifdef DEBUG
			printf("T%dS%d\r",c2,c3);
		#endif

			*pTrack = c2;
			*pSector = c3;

			for (i=0;i<8;i++)
			{
				checksum[0] ^= SPI(0);
				checksum[1] ^= SPI(0);
				checksum[2] ^= SPI(0);
				checksum[3] ^= SPI(0);
			}

			checksum[0] &= 0x55;
			checksum[1] &= 0x55;
			checksum[2] &= 0x55;
			checksum[3] &= 0x55;

			c1 = (SPI(0)&0x55)<<1;
			c2 = (SPI(0)&0x55)<<1;
			c3 = (SPI(0)&0x55)<<1;
			c4 = (SPI(0)&0x55)<<1;

			c1 |= SPI(0)&0x55;
			c2 |= SPI(0)&0x55;
			c3 |= SPI(0)&0x55;
			c4 |= SPI(0)&0x55;

			if (c1!=checksum[0] || c2!=checksum[1] || c3!=checksum[2] || c4!=checksum[3])
			{
				Error = 26;
				break;
			}

			DisableFpga();
			return 1;
		}
		else				//not enough data for header
		if ((c3&0x80)==0)	//write dma is not active
		{
			Error = 20;
			break;
		}

		DisableFpga();
	}

	DisableFpga();
	return 0;
}

unsigned char GetData()
{
	unsigned char c,c1,c2,c3,c4;
	unsigned char i;
	unsigned char *p;
	unsigned short n;
	unsigned char checksum[4];

	Error = 0;
	while (1)
	{
		EnableFpga();
		c1 = SPI(0);			//write request signal
		c2 = SPI(0);			//track number (cylinder & head)
		if (!(c1&CMD_WRTRCK))
			break;
		c3 = SPI(0);			//msb of mfm words to transfer 
		c4 = SPI(0);			//lsb of mfm words to transfer

		n = ((c3&0x3F)<<8) + c4;

		if (n >= 0x204)
		{
			c1 = (SPI(0)&0x55)<<1;
			c2 = (SPI(0)&0x55)<<1;
			c3 = (SPI(0)&0x55)<<1;
			c4 = (SPI(0)&0x55)<<1;

			c1 |= SPI(0)&0x55;
			c2 |= SPI(0)&0x55;
			c3 |= SPI(0)&0x55;
			c4 |= SPI(0)&0x55;

			checksum[0] = 0;
			checksum[1] = 0;
			checksum[2] = 0;
			checksum[3] = 0;

			/*odd bits of data field*/	
			i = 128;
			p = secbuf;
			do
			{
				c = SPI(0);
				checksum[0] ^= c;
				*p++ = (c&0x55)<<1;
				c = SPI(0);
				checksum[1] ^= c;
				*p++ = (c&0x55)<<1;
				c = SPI(0);
				checksum[2] ^= c;
				*p++ = (c&0x55)<<1;
				c = SPI(0);
				checksum[3] ^= c;
				*p++ = (c&0x55)<<1;
			}
			while(--i);

			/*even bits of data field*/	
			i = 128;
			p = secbuf;
			do
			{
				c = SPI(0);
				checksum[0] ^= c;
				*p++ |= c&0x55;
				c = SPI(0);
				checksum[1] ^= c;
				*p++ |= c&0x55;
				c = SPI(0);
				checksum[2] ^= c;
				*p++ |= c&0x55;
				c = SPI(0);
				checksum[3] ^= c;
				*p++ |= c&0x55;
			}
			while(--i);

			checksum[0] &= 0x55;
			checksum[1] &= 0x55;
			checksum[2] &= 0x55;
			checksum[3] &= 0x55;

			if (c1!=checksum[0] || c2!=checksum[1] || c3!=checksum[2] || c4!=checksum[3])
			{
				Error = 29;
				break;
			}

			DisableFpga();
			return 1;
		}
		else				//not enough data in fifo
		if ((c3&0x80)==0)	//write dma is not active
		{
			Error = 28;
			break;
		}	

		DisableFpga();
	}
	DisableFpga();
	return 0;
}

unsigned char Open(const unsigned char *name)
{
	unsigned char i,j;
	
	if (FileSearch2(&file,0))
	{
		do
		{
			i=0;
			for(j=0;j<11;j++)
				if (file.name[j]==name[j])
					i++;
			if (i==11)
			{
				printf("file \"%s\" found\r",name);
				return 1;	
			}
		}
		while(FileSearch2(&file,1));
	}
	printf("file \"%s\" not found\r",name);
	return 0;
}

/*this function sends the data in the sector buffer to the FPGA, translated
into an Amiga floppy format sector
sector is the sector number in the track
track is the track number
note that we do not insert clock bits because they will be stripped
by the Amiga software anyway*/
unsigned short SectorToFpga(unsigned char sector,unsigned char track)
{
	unsigned char c,i;
	unsigned char csum[4];
	unsigned char *p;
	unsigned char c3,c4;
	
	/*preamble*/
	SPI(0xaa);		
	SPI(0xaa);		
	SPI(0xaa);		
	SPI(0xaa);
	
	/*synchronization*/
	SPI(0x44);
	SPI(0x89);		
	SPI(0x44);
	SPI(0x89);		

	/*clear header checksum*/
	csum[0]=0;
	csum[1]=0;
	csum[2]=0;
	csum[3]=0;
	
	/*odd bits of header*/
	c=0x55;
	csum[0]^=c;
	SPI(c);
	c=(track>>1)&0x55;
	csum[1]^=c;
	SPI(c);
	c=(sector>>1)&0x55;
	csum[2]^=c;
	SPI(c);
	c=((11-sector)>>1)&0x55;
	csum[3]^=c;
	SPI(c);

	/*even bits of header*/
	c=0x55;
	csum[0]^=c;
	SPI(c);
	c=track&0x55;
	csum[1]^=c;
	SPI(c);
	c=sector&0x55;
	csum[2]^=c;
	SPI(c);
	c=(11-sector)&0x55;
	csum[3]^=c;
	SPI(c);
	
	/*sector label and reserved area (changes nothing to checksum)*/
	for(i=0;i<32;i++)
		SPI(0x55);
	
	/*checksum over header*/
	SPI((csum[0]>>1)|0xaa);
	SPI((csum[1]>>1)|0xaa);
	SPI((csum[2]>>1)|0xaa);
	SPI((csum[3]>>1)|0xaa);
	SPI(csum[0]|0xaa);
	SPI(csum[1]|0xaa);
	SPI(csum[2]|0xaa);
	SPI(csum[3]|0xaa);
	
	/*calculate data checksum*/
	csum[0]=0;
	csum[1]=0;
	csum[2]=0;
	csum[3]=0;
	i=128;
	p=secbuf;
	do
	{
		c=*(p++);
		csum[0]^=c>>1;
		csum[0]^=c;
		c=*(p++);
		csum[1]^=c>>1;
		csum[1]^=c;
		c=*(p++);
		csum[2]^=c>>1;
		csum[2]^=c;
		c=*(p++);
		csum[3]^=c>>1;
		csum[3]^=c;
	}	
	while(--i);
	csum[0]&=0x55;
	csum[1]&=0x55;
	csum[2]&=0x55;
	csum[3]&=0x55;
	
		
	/*checksum over data*/
	SPI((csum[0]>>1)|0xaa);
	SPI((csum[1]>>1)|0xaa);
	SPI((csum[2]>>1)|0xaa);
	SPI((csum[3]>>1)|0xaa);
	SPI(csum[0]|0xaa);
	SPI(csum[1]|0xaa);
	SPI(csum[2]|0xaa);
	SPI(csum[3]|0xaa);
	
	/*odd bits of data field*/	
	i=128;
	p=secbuf;
	do
	{
		c=*(p++);
		c>>=1;
		c|=0xaa;
		SSPBUF=c;
		while(!BF);		
		
		c=*(p++);
		c>>=1;
		c|=0xaa;
		SSPBUF=c;
		while(!BF);		
		
		c=*(p++);
		c>>=1;
		c|=0xaa;
		SSPBUF=c;
		while(!BF);		
		
		c=*(p++);
		c>>=1;
		c|=0xaa;
		SSPBUF=c;
		while(!BF);
	}
	while(--i);
	
	/*even bits of data field*/	
	i=128;
	p=secbuf;
	do
	{
		c=*(p++);
		SSPBUF=c|0xaa;
		while(!BF);		
		c=*(p++);
		SSPBUF=c|0xaa;
		while(!BF);		
		c=*(p++);
		SSPBUF=c|0xaa;
		while(!BF);
		c3 = SSPBUF;
		c=*(p++);
		SSPBUF=c|0xaa;
		while(!BF);
		c4 = SSPBUF;
	}
	while(--i);
	
	return((c3<<8)|c4);
}
	

void SectorGapToFpga()
{
	unsigned char i;
	i = 190;
	do
	{
		SPI(0xAA);
		SPI(0xAA);
	}	
	while (--i);
}
	
void SectorHeaderToFpga(unsigned char n)
{
	if (n)
	{
		SPI(0xAA);
		SPI(0xAA);
		
		if (--n)
		{
			SPI(0xAA);
			SPI(0xAA);
	
			if (--n)
			{
				SPI(0x44);
				SPI(0x89);
			}
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -