Revision 62
Added by markw over 11 years ago
| firmware/atari_drive_emulator.c | ||
|---|---|---|
| 
     #define MAX_DRIVES 4
 
   | 
||
| 
     | 
||
| 
     struct SimpleFile * drives[MAX_DRIVES];
 
   | 
||
| 
     unsigned char drive_info[MAX_DRIVES];
 
   | 
||
| 
     enum DriveInfo {DI_XD=0,DI_SD=1,DI_MD=2,DI_DD=3,DI_BITS=3,DI_RO=4};
 
   | 
||
| 
     | 
||
| 
     struct ATRHeader
 
   | 
||
| 
     {
 
   | 
||
| ... | ... | |
| 
     {
 
   | 
||
| 
     	int read = 0;
 
   | 
||
| 
     	int xfd = 0;
 
   | 
||
| 
     	unsigned char info;
 
   | 
||
| 
     | 
||
| 
     	drives[driveNumber] = 0;
 
   | 
||
| 
     	drive_info[driveNumber] = 0;
 
   | 
||
| 
     | 
||
| 
     	if (!file) return;
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     		atr_header.wMagic = 0x296;
 
   | 
||
| 
     		atr_header.wPars = file_size(file)/16;
 
   | 
||
| 
     		atr_header.wSecSize = 0x80;
 
   | 
||
| 
     		atr_header.btFlags = 0;
 
   | 
||
| 
     		atr_header.btFlags |= file_readonly(file);
 
   | 
||
| 
     	}
 
   | 
||
| 
     	else if (atr_header.wMagic == 0xFFFF) // XEX
 
   | 
||
| 
     	{
 
   | 
||
| ... | ... | |
| 
     	{
 
   | 
||
| 
     		//printf("ATR ");
 
   | 
||
| 
     		offset = 16;
 
   | 
||
| 
     		atr_header.btFlags |= file_readonly(file);
 
   | 
||
| 
     	}
 
   | 
||
| 
     	else
 
   | 
||
| 
     	{
 
   | 
||
| ... | ... | |
| 
     		return;
 
   | 
||
| 
     	}
 
   | 
||
| 
     | 
||
| 
     	if (atr_header.btFlags&1)
 
   | 
||
| 
     	{
 
   | 
||
| 
     		info |= DI_RO;
 
   | 
||
| 
     	}
 
   | 
||
| 
     | 
||
| 
     	if (atr_header.wSecSize == 0x80)
 
   | 
||
| 
     	{
 
   | 
||
| 
     	/*	if (atr_header.wPars>(720*128/16))
 
   | 
||
| 
     			printf("MD ");
 
   | 
||
| 
     		if (atr_header.wPars>(720*128/16))
 
   | 
||
| 
     			info |= DI_MD;
 
   | 
||
| 
     		else
 
   | 
||
| 
     			printf("SD ");*/
 
   | 
||
| 
     			info |= DI_SD;
 
   | 
||
| 
     	}
 
   | 
||
| 
     	else if (atr_header.wSecSize == 0x100)
 
   | 
||
| 
     	{
 
   | 
||
| 
     		//printf("DD ");
 
   | 
||
| 
     		info |= DI_DD;
 
   | 
||
| 
     	}
 
   | 
||
| 
     	else if (atr_header.wSecSize < 0x100)
 
   | 
||
| 
     	{
 
   | 
||
| 
     		//printf("XD ");
 
   | 
||
| 
     		info |= DI_XD;
 
   | 
||
| 
     	}
 
   | 
||
| 
     	else
 
   | 
||
| 
     	{
 
   | 
||
| ... | ... | |
| 
     	//printf("0\n");
 
   | 
||
| 
     | 
||
| 
     	drives[driveNumber] = file;
 
   | 
||
| 
     	drive_info[driveNumber] = info;
 
   | 
||
| 
     	//printf("appears valid\n");
 
   | 
||
| 
     }
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     			clearAtariSectorBuffer();
 
   | 
||
| 
     | 
||
| 
     			status = 0x10; // Motor on;
 
   | 
||
| 
     			status |= 0x08; // write protected; // no write support yet...
 
   | 
||
| 
     			if (atr_header.btFlags&1)
 
   | 
||
| 
     			{
 
   | 
||
| 
     				status |= 0x08; // write protected; // no write support yet...
 
   | 
||
| 
     			}
 
   | 
||
| 
     			if (atr_header.wSecSize == 0x80) // normal sector size
 
   | 
||
| 
     			{
 
   | 
||
| 
     				if (atr_header.wPars>(720*128/16))
 
   | 
||
| ... | ... | |
| 
     | 
||
| 
     			//printf("WACK:");
 
   | 
||
| 
     			USART_Transmit_Mode();
 
   | 
||
| 
     			if (file_readonly(file))
 
   | 
||
| 
     			{
 
   | 
||
| 
     				send_NACK();
 
   | 
||
| 
     				USART_Wait_Transmit_Complete();
 
   | 
||
| 
     				USART_Receive_Mode();
 
   | 
||
| 
     				return;
 
   | 
||
| 
     			}
 
   | 
||
| 
     			send_ACK();
 
   | 
||
| 
     			USART_Wait_Transmit_Complete();
 
   | 
||
| 
     			USART_Receive_Mode();
 
   | 
||
| ... | ... | |
| 
     	printf("%d",check_sum);
 
   | 
||
| 
     	printf(")");*/
 
   | 
||
| 
     }
 
   | 
||
| 
     | 
||
| 
     void describe_disk(int driveNumber, char * buffer)
 
   | 
||
| 
     {
 
   | 
||
| 
     	if (drives[driveNumber]==0)
 
   | 
||
| 
     	{
 
   | 
||
| 
     		buffer[0] = 'N';
 
   | 
||
| 
     		buffer[1] = 'O';
 
   | 
||
| 
     		buffer[2] = 'N';
 
   | 
||
| 
     		buffer[3] = 'E';
 
   | 
||
| 
     		buffer[4] = '\0';
 
   | 
||
| 
     		return;
 
   | 
||
| 
     	}
 
   | 
||
| 
     //enum DriveInfo {DI_XD=0,DI_SD=1,DI_MD=2,DI_DD=3,DI_BITS=3,DI_RO=4};
 
   | 
||
| 
     	unsigned char info = drive_info[driveNumber];
 
   | 
||
| 
     	buffer[0] = 'R';
 
   | 
||
| 
     	buffer[1] = info&DI_RO ? 'O' : 'W';
 
   | 
||
| 
     	buffer[2] = ' ';
 
   | 
||
| 
     	unsigned char density;
 
   | 
||
| 
     	switch (info&3)
 
   | 
||
| 
     	{
 
   | 
||
| 
     	case DI_XD:
 
   | 
||
| 
     		density = 'X';
 
   | 
||
| 
     		break;
 
   | 
||
| 
     	case DI_SD:
 
   | 
||
| 
     		density = 'S';
 
   | 
||
| 
     		break;
 
   | 
||
| 
     	case DI_MD:
 
   | 
||
| 
     		density = 'M';
 
   | 
||
| 
     		break;
 
   | 
||
| 
     	case DI_DD:
 
   | 
||
| 
     		density = 'D';
 
   | 
||
| 
     		break;
 
   | 
||
| 
     	}
 
   | 
||
| 
     	buffer[3] = density;
 
   | 
||
| 
     	buffer[4] = 'D';
 
   | 
||
| 
     	buffer[5] = '\0';
 
   | 
||
| 
     }
 
   | 
||
| firmware/atari_drive_emulator.h | ||
|---|---|---|
| 
     // For a read-only disk, just have no write function!
 
   | 
||
| 
     struct SimpleFile;
 
   | 
||
| 
     void set_drive_status(int driveNumber, struct SimpleFile * file);
 
   | 
||
| 
     void describe_disk(int driveNumber, char * buffer);
 
   | 
||
| 
     | 
||
| firmware/fat/pff_file.c | ||
|---|---|---|
| 
     void file_init(struct SimpleFile * file)
 
   | 
||
| 
     {
 
   | 
||
| 
     	file->path[0] = '\0';
 
   | 
||
| 
     	file->is_readonly = 1;
 
   | 
||
| 
     	file->size = 0;
 
   | 
||
| 
     }
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     	FRESULT res;
 
   | 
||
| 
     | 
||
| 
     	//printf("went\n");
 
   | 
||
| 
     	if (file->is_readonly) return SimpleFile_FAIL;
 
   | 
||
| 
     | 
||
| 
     	file_check_open(file);
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     	return file->size;
 
   | 
||
| 
     }
 
   | 
||
| 
     | 
||
| 
     int file_readonly(struct SimpleFile * file)
 
   | 
||
| 
     {
 
   | 
||
| 
     	return file->is_readonly;
 
   | 
||
| 
     }
 
   | 
||
| 
     | 
||
| 
     int file_struct_size()
 
   | 
||
| 
     {
 
   | 
||
| 
     	return sizeof(struct SimpleFile);
 
   | 
||
| ... | ... | |
| 
     	FRESULT res;
 
   | 
||
| 
     | 
||
| 
     	strcpy(&file->path[0],dir->path);
 
   | 
||
| 
     	file->is_readonly = dir->is_readonly;
 
   | 
||
| 
     	file->size = dir->size;
 
   | 
||
| 
     | 
||
| 
     	file_write_flush();
 
   | 
||
| ... | ... | |
| 
     	prev->filename_ptr = prev->path;
 
   | 
||
| 
     	prev->size = 0;
 
   | 
||
| 
     	prev->is_subdir = 1;
 
   | 
||
| 
     	prev->is_readonly = 1;
 
   | 
||
| 
     	--room;
 
   | 
||
| 
     | 
||
| 
     	//int count=0;
 
   | 
||
| ... | ... | |
| 
     		//printf("next %x %d ",entry,room);
 
   | 
||
| 
     | 
||
| 
     		entry->is_subdir = (filinfo.fattrib & AM_DIR) ? 1 : 0;
 
   | 
||
| 
     		entry->is_readonly = (filinfo.fattrib & AM_RDO) ? 1 : 0;
 
   | 
||
| 
     | 
||
| 
     		//printf("%s ",filinfo.fname);
 
   | 
||
| 
     | 
||
| firmware/fat/pff_file.h | ||
|---|---|---|
| 
     struct SimpleFile
 
   | 
||
| 
     {
 
   | 
||
| 
     	char path[MAX_PATH_LENGTH];
 
   | 
||
| 
     	int is_readonly;
 
   | 
||
| 
     	int size;
 
   | 
||
| 
     };
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     	char lfn[256];
 
   | 
||
| 
     	int size;
 
   | 
||
| 
     	int is_subdir;
 
   | 
||
| 
     	int is_readonly;
 
   | 
||
| 
     	struct SimpleDirEntry * next; // as linked list - want to allow sorting...
 
   | 
||
| 
     };
 
   | 
||
| 
     | 
||
| firmware/fileselector.c | ||
|---|---|---|
| 
     	return (compare_ext(f,"ROM"));
 
   | 
||
| 
     }
 
   | 
||
| 
     | 
||
| 
     void dir_of(char * dir, char const * path); // TODO - into simpledir
 
   | 
||
| 
     | 
||
| 
     void file_selector(struct SimpleFile * file)
 
   | 
||
| 
     {
 
   | 
||
| 
     	char dir[MAX_PATH_LENGTH] = "";
 
   | 
||
| 
     	char dir[MAX_PATH_LENGTH];
 
   | 
||
| 
     	dir_of(&dir[0],file_name(file));
 
   | 
||
| 
     	for (;;)
 
   | 
||
| 
     	{
 
   | 
||
| 
     		// TODO last selected dir...
 
   | 
||
| 
     		struct SimpleDirEntry * entry = dir_entries_filtered(dir,filter);
 
   | 
||
| 
     | 
||
| 
     		// Count how many we have
 
   | 
||
| ... | ... | |
| 
     | 
||
| 
     		// Selected item
 
   | 
||
| 
     		int pos = 0;
 
   | 
||
| 
     		int prevstartpos = -1;
 
   | 
||
| 
     | 
||
| 
     		struct joystick_status joy;
 
   | 
||
| 
     		joy.x_ = joy.y_ = joy.fire_ = 0;
 
   | 
||
| ... | ... | |
| 
     				}
 
   | 
||
| 
     | 
||
| 
     				// clear the screen
 
   | 
||
| 
     				clearscreen();
 
   | 
||
| 
     				if (startpos!=prevstartpos)
 
   | 
||
| 
     				{
 
   | 
||
| 
     					clearscreen();
 
   | 
||
| 
     					prevstartpos = startpos;
 
   | 
||
| 
     				}
 
   | 
||
| 
     | 
||
| 
     				// find selected entry
 
   | 
||
| 
     				struct SimpleDirEntry * sel_entry = entry;
 
   | 
||
| ... | ... | |
| 
     					//printf("%s %s %d %d %d",dir_is_subdir(sel_entry) ? "DIR":"", dir_filename(sel_entry), joy.x_, joy.y_, pos);
 
   | 
||
| 
     					printf("%s %s",dir_is_subdir(sel_entry) ? "DIR":"", dir_filename(sel_entry));
 
   | 
||
| 
     				}
 
   | 
||
| 
     				int i;
 
   | 
||
| 
     				for (i=0;i!=40;++i) printf(" ");
 
   | 
||
| 
     			}
 
   | 
||
| 
     | 
||
| 
     			// Slow it down a bit
 
   | 
||
| firmware/main.c | ||
|---|---|---|
| 
     		{
 
   | 
||
| 
     			int temp = debug_pos;
 
   | 
||
| 
     			debug_adjust = row==i+2 ? 128 : 0;
 
   | 
||
| 
     			printf("Drive %d:%s", i, file_name(files[i-1]));
 
   | 
||
| 
     			char buffer[20];
 
   | 
||
| 
     			describe_disk(i-1,&buffer[0]);
 
   | 
||
| 
     			printf("Drive %d:%s %s", i, file_name(files[i-1]), &buffer[0]);
 
   | 
||
| 
     			debug_pos = temp+40;
 
   | 
||
| 
     		}
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     				{
 
   | 
||
| 
     					// Remove disk
 
   | 
||
| 
     					file_init(files[row-3]);
 
   | 
||
| 
     					set_drive_status(row-3,files[row-3]);
 
   | 
||
| 
     					set_drive_status(row-3,0);
 
   | 
||
| 
     				}
 
   | 
||
| 
     				else if (joy.fire_)
 
   | 
||
| 
     				{
 
   | 
||
| firmware/simplefile.h | ||
|---|---|---|
| 
     enum SimpleFileStatus file_read(struct SimpleFile * file, void * buffer, int bytes, int * bytesread);
 
   | 
||
| 
     enum SimpleFileStatus file_seek(struct SimpleFile * file, int offsetFromStart);
 
   | 
||
| 
     int file_size(struct SimpleFile * file);
 
   | 
||
| 
     int file_readonly(struct SimpleFile * file);
 
   | 
||
| 
     | 
||
| 
     enum SimpleFileStatus file_write(struct SimpleFile * file, void * buffer, int bytes, int * byteswritten);
 
   | 
||
| 
     enum SimpleFileStatus file_write_flush();
 
   | 
||
| firmware/test_file.c | ||
|---|---|---|
| 
     		loadrom("osaorig.rom",0x2800, (void *)0x719800);
 
   | 
||
| 
     		loadrom("ataribas.rom",0x2000,(void *)0x700000);
 
   | 
||
| 
     | 
||
| 
     	//file_selector(file);
 
   | 
||
| 
     	entry = dir_entries("/DCIM");
 
   | 
||
| 
     	entry = dir_next(entry);
 
   | 
||
| 
     	fprintf(stderr, " Name:%s", dir_filename(entry));
 
   | 
||
| 
     	struct SimpleFile * file = alloca(file_struct_size());
 
   | 
||
| 
     	file_open_dir(entry,file);
 
   | 
||
| 
     	file_selector(file);
 
   | 
||
| 
     | 
||
| 
     	return 0;
 
   | 
||
| 
     }
 
   | 
||
Added real-only support. Describe disk image in menu.