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.