Project

General

Profile

« Previous | Next » 

Revision 52

Added by markw over 11 years ago

Long firmname support. Several bugfixes, e.g. multi-drive support

View differences:

firmware/atari_drive_emulator.c
{
actions();
}
printf("cmd:");
//printf("cmd:");
//printf("Gone high\n");
atari_sector_buffer[0] = cmd->deviceId;
atari_sector_buffer[1] = cmd->command;
......
expchk = get_checksum(&atari_sector_buffer[0],4);
//printf("Device id:");
printf("%d",cmd->deviceId);
//printf("%d",cmd->deviceId);
//printf("\n");
//printf("command:");
printf("%d",cmd->command);
//printf("%d",cmd->command);
//printf("\n");
//printf("aux1:");
printf("%d",cmd->aux1);
//printf("%d",cmd->aux1);
//printf("\n");
//printf("aux2:");
printf("%d",cmd->aux2);
//printf("%d",cmd->aux2);
//printf("\n");
//printf("chksum:");
printf("%d",cmd->chksum);
printf("%d",expchk);
//printf("%x ",cmd->chksum);
//printf("%x ",expchk);
if (expchk!=cmd->chksum || USART_Framing_Error())
{
printf("ERR ");
//printf("ERR ");
//wait_us(1000000);
if (speed == speedslow)
{
speed = speedfast;
printf("SPDF");
printf("%d",speed);
//printf("SPDF");
//printf("%d",speed);
}
else
{
speed = speedslow;
printf("SPDS");
printf("%d",speed);
//printf("SPDS");
//printf("%d",speed);
}
}
printf("\n");
//printf("\n");
DELAY_T2_MIN;
}
......
if (!file) return;
//printf("WTF:%d %x\n",driveNumber, file);
// Read header
read = 0;
file_seek(file,0);
file_read(file,(unsigned char *)&atr_header, 16, &read);
if (read!=16)
{
printf("Could not read header\n");
//printf("Could not read header\n");
return; //while(1);
}
byteswap(&atr_header.wMagic);
......
if (xfd == 1)
{
printf("XFD ");
//printf("XFD ");
// build a fake atr header
offset = 0;
atr_header.wMagic = 0x296;
......
else if (atr_header.wMagic == 0xFFFF) // XEX
{
int i;
printf("XEX ");
//printf("XEX ");
offset = -256;
xex_loader = 1;
atr_header.wMagic = 0xffff;
......
}
else if (atr_header.wMagic == 0x296) // ATR
{
printf("ATR ");
//printf("ATR ");
offset = 16;
}
else
{
printf("Unknown file type");
//printf("Unknown file type");
return;
}
......
}
else if (atr_header.wSecSize == 0x100)
{
printf("DD ");
//printf("DD ");
}
else if (atr_header.wSecSize < 0x100)
{
printf("XD ");
//printf("XD ");
}
else
{
printf("BAD sector size");
//printf("BAD sector size");
return;
}
printf("%d",atr_header.wPars);
printf("0\n");
//printf("%d",atr_header.wPars);
//printf("0\n");
drives[driveNumber] = file;
//printf("appears valid\n");
}
void init_drive_emulator()
......
++commandcount;
/*FIXME if (commandcount==4 && (4==(4&(*zpu_switches))))
{
printf("Paused\n");
//printf("Paused\n");
pause_6502(1);
while(1);
}*/
/*if (badcommandcount==8)
{
printf("Stuck?\n");
//printf("Stuck?\n");
pause_6502(1);
while(1);
}*/
if (command.deviceId >= 0x31 && command.deviceId < 0x34)
if (command.deviceId >= 0x31 && command.deviceId <= 0x34)
{
int sent = 0;
int drive = 0;
struct SimpleFile * file = 0;
drive = command.deviceId&0xf -1;
printf("Drive:");
printf("%d",drive);
drive = (command.deviceId&0xf) -1;
// printf("Drive:");
// printf("%x %d",command.deviceId,drive);
if (drive!=opendrive)
{
if (drive<MAX_DRIVES && drive>=0)
{
opendrive = drive;
set_drive_status(drive, drives[drive]);
//printf("HERE!:%d\n",drive);
}
}
......
//wait_us(100); // Wait for transmission to complete - Pokey bug, gets stuck active...
//USART_Receive_Mode();
printf("Drive not present");
//printf("Drive not present:%d %x", drive, drives[drive]);
return;
}
......
{
case 0x3f:
{
printf("Speed:");
//printf("Speed:");
int sector = ((int)command.aux1) + (((int)command.aux2&0x7f)<<8);
USART_Transmit_Mode();
send_ACK();
......
if (sector == 0)
{
speed = speedfast;
printf("SPDF");
printf("%d",speed);
//printf("SPDF");
//printf("%d",speed);
}
else
{
speed = speedslow;
printf("SPDS");
printf("%d",speed);
//printf("SPDS");
//printf("%d",speed);
}
}
case 0x53:
{
unsigned char status;
printf("Stat:");
//printf("Stat:");
USART_Transmit_Mode();
send_ACK();
clearAtariSectorBuffer();
......
hexdump_pure(atari_sector_buffer,4); // Somehow with this...
USART_Send_cmpl_and_atari_sector_buffer_and_check_sum(4);
sent = 1;
printf("%d",atari_sector_buffer[0]); // and this... The wrong checksum is sent!!
printf(":done\n");
//printf("%d",atari_sector_buffer[0]); // and this... The wrong checksum is sent!!
//printf(":done\n");
}
break;
default:
......
int sectorSize = 0;
int location =0;
printf("WACK:");
//printf("WACK:");
USART_Transmit_Mode();
send_ACK();
USART_Wait_Transmit_Complete();
......
unsigned char checksum = USART_Receive_Byte();
//hexdump_pure(atari_sector_buffer,sectorSize); // Somehow with this...
unsigned char expchk = get_checksum(&atari_sector_buffer[0],sectorSize);
printf("DATA:%d:",sectorSize);
printf("CHK:%02x EXP:%02x", checksum, expchk);
//printf("DATA:%d:",sectorSize);
//printf("CHK:%02x EXP:%02x", checksum, expchk);
//printf(" %d",atari_sector_buffer[0]); // and this... The wrong checksum is sent!!
printf(":done\n");
//printf(":done\n");
if (checksum==expchk)
{
USART_Transmit_Mode();
printf(":WACK2:");
//printf(":WACK2:");
send_ACK();
USART_Wait_Transmit_Complete();
printf("%d",location);
printf("\n");
//printf("%d",location);
//printf("\n");
file_seek(file,location);
int written = 0;
file_write(file,&atari_sector_buffer[0], sectorSize, &written);
......
DELAY_T5_MIN;
if (ok)
{
printf(":CMPL:");
//printf(":CMPL:");
send_CMPL();
}
else
{
printf(":NACK:");
//printf(":NACK:");
send_NACK();
}
......
}
else
{
printf(":NACK:");
//printf(":NACK:");
send_NACK();
USART_Wait_Transmit_Complete();
......
USART_Transmit_Mode();
send_ACK();
printf("Sector:");
printf("%d",sector);
printf(":");
//printf("Sector:");
//printf("%d",sector);
//printf(":");
if(xex_loader) //n_sector>0 && //==0 se overuje hned na zacatku
{
//sektory xex bootloaderu, tj. 1 nebo 2
......
//zarovnano nahoru, tj. =(size+124)/125
file_sectors = ((xex_size+(u32)(XEX_SECTOR_SIZE-3-1))/((u32)XEX_SECTOR_SIZE-3));
printf("XEX ");
//printf("XEX ");
if (sector<=2)
{
printf("boot ");
//printf("boot ");
spt= &boot_xex_loader[(u16)(sector-1)*((u16)XEX_SECTOR_SIZE)];
dpt= atari_sector_buffer;
......
else
if(sector==0x168)
{
printf("numtobuffer ");
//printf("numtobuffer ");
//vrati pocet sektoru diskety
//byty 1,2
goto set_number_of_sectors_to_buffer_1_2;
......
else
if(sector>=0x171)
{
printf("data ");
//printf("data ");
file_seek(file,((u32)sector-0x171)*((u32)XEX_SECTOR_SIZE-3));
file_read(file,&atari_sector_buffer[0], XEX_SECTOR_SIZE-3, &read);
......
atari_sector_buffer[XEX_SECTOR_SIZE-2]=((sector)&0xff); //pak DB!!! (je to HB,DB)
atari_sector_buffer[XEX_SECTOR_SIZE-1]=read;
}
printf(" sending\n");
//printf(" sending\n");
sectorSize = XEX_SECTOR_SIZE;
}
......
location += 128*(sector-1);
sectorSize = 128;
}
printf("%d",location);
printf("\n");
//printf("%d",location);
//printf("\n");
file_seek(file,location);
file_read(file,&atari_sector_buffer[0], sectorSize, &read);
}
......
//pause_6502(1);
//hexdump_pure(0x10000+0x400,128);
unsigned char chksumreceive = 0; //get_checksum(0x10000+0x400, sectorSize);
printf(" receive:");
printf("%d",chksumreceive);
printf("\n");
//printf(" receive:");
//printf("%d",chksumreceive);
//printf("\n");
//pause_6502(1);
//while(1);
}
......
void USART_Send_cmpl_and_atari_sector_buffer_and_check_sum(unsigned short len)
{
u08 check_sum;
printf("(send:");
printf("%d",len);
//printf("(send:");
//printf("%d",len);
DELAY_T5_MIN;
send_CMPL();
......
check_sum = get_checksum(atari_sector_buffer,len);
USART_Transmit_Byte(check_sum);
//hexdump_pure(atari_sector_buffer,len);
printf(":chk:");
/*printf(":chk:");
printf("%d",check_sum);
printf(")");
printf(")");*/
}
firmware/build_native_drive
gcc -g -O0 -DLITTLE_ENDIAN test_drive.c atari_drive_emulator.c native/uart.c hexdump.c printf/printf.c fat/pff_file.c fat/pff.c common/utils.c native/diskio_image.c -I. -Iprintf -Ifat -Icommon
gcc -g -O0 -DLITTLE_ENDIAN test_drive.c fileutils.c atari_drive_emulator.c native/uart.c hexdump.c printf/printf.c fat/pff_file.c fat/pff.c common/utils.c sd_direct/diskio_mmc.c native/mmc.c -I. -Iprintf -Ifat -Icommon
firmware/common/utils.c
while (*src)
{
char val = *src++;
if (val>='A' && val<='Z') val-='A'+'a';
if (val>='A' && val<='Z') val+=-'A'+'a';
*dest++ = val;
}
*dest = '\0';
}
int strlen(char const * a)
firmware/fat/pff.c
#include "pff.h" /* Petit FatFs configurations and declarations */
#include "diskio.h" /* Declarations of low level disk I/O functions */
#include "printf.h"
......
static
FRESULT dir_read (
DIR *dj, /* Pointer to the directory object to store read object name */
BYTE *dir /* 32-byte working buffer */
BYTE *dir, /* 32-byte working buffer */
BYTE *lfn_buffer /* 256-byte lfn buffer */
)
{
FRESULT res;
BYTE a, c;
int lfn = 0;
char *lfn_pos = &lfn_buffer[255];
lfn_buffer[255] = '\0';
res = FR_NO_FILE;
while (dj->sect) {
res = disk_readp(dir, dj->sect, (WORD)((dj->index % 16) * 32), 32) /* Read an entry */
? FR_DISK_ERR : FR_OK;
if (res != FR_OK) break;
c = dir[DIR_Name];
if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */
a = dir[DIR_Attr] & AM_MASK;
if (a&AM_LFN == AM_LFN && ((dir[0]&0xbf) < 16) && dir[0x1a]==0 && dir[0x1c]!=0)
{
lfn_pos-=13;
char * ptr = lfn_pos;
int i;
for (i=1;i!=32;i+=2)
{
if (i==0xb) i=0xe;
if (i==0x1a) i=0x1c;
char b1 = dir[i];
char b2 = dir[i+1];
if (b2==0) *ptr++ = b1; else *ptr++ = '_';
}
//printf("LFN seq:%d %c%c%c%c%c%c%c%c%c%c%c%c%c \n",dir[0],dir[1],dir[3],dir[5],dir[7],dir[9],dir[14],dir[16],dir[18],dir[20],dir[22],dir[24],dir[28],dir[30]);
lfn = 1;
}
if (c != 0xE5 && c != '.' && !(a & AM_VOL)) /* Is it a valid entry? */
break;
res = dir_next(dj); /* Next entry */
if (res != FR_OK) break;
}
lfn_buffer[0] = '\0';
if (lfn)
{
strcpy(&lfn_buffer[0],lfn_pos);
}
if (res != FR_OK) dj->sect = 0;
return res;
......
if (!fno) {
res = dir_rewind(dj);
} else {
res = dir_read(dj, dir);
res = dir_read(dj, dir, &fno->lfname[0]);
if (res == FR_NO_FILE) {
dj->sect = 0;
res = FR_OK;
......
}
}
if (fno->lfname[0] == '\0') strcpy(&fno->lfname[0],&fno->fname[0]);
//printf("%s %s(%d)\n",&fno->fname[0], &fno->lfname[0],strlen(&fno->lfname[0]));
return res;
}
firmware/fat/pff.h
WORD ftime; /* Last modified time */
BYTE fattrib; /* Attribute */
char fname[13]; /* File name */
char lfname[256]; /* File name */
} FILINFO;
firmware/fat/pff_file.c
--start;
if (*start == '/')
{
--start;
++start;
break;
}
}
......
return file_of(&file->path[0]);
}
void file_init(struct SimpleFile * file)
{
file->path[0] = '\0';
file->size = 0;
}
void file_check_open(struct SimpleFile * file)
{
if (openfile!=file)
......
return dir_entries_filtered(dirPath,0);
}
int dircmp(struct SimpleDirEntry * a, struct SimpleDirEntry * b)
{
if (a->is_subdir==b->is_subdir)
return strcmp(a->lfn,b->lfn);
else
return a->is_subdir<b->is_subdir;
}
void sort_ll(struct SimpleDirEntry * h)
{
//struct SimpleDirEntry
//{
// char path[MAX_PATH_LENGTH];
// char * filename_ptr;
// int size;
// int is_subdir;
// struct SimpleDirEntry * next; // as linked list - want to allow sorting...
//};
struct SimpleDirEntry * p,*temp,*prev;
int i,j,n,sorted=0;
temp=h;
prev=0;
for(n=0;temp!=0;temp=temp->next) n++;
for(i=0;i<n-1 && !sorted;i++){
p=h;sorted=1;
prev=0;
for(j=0;j<n-(i+1);j++){
// printf("p->issubdir:%d(%s) p->next->issubdir:%d(%s)",p->is_subdir,p->path,p->next->is_subdir,p->next->path);
if(dircmp(p,p->next)>0) {
// printf("SWITCH!\n");
struct SimpleDirEntry * a = p;
struct SimpleDirEntry * b = p->next;
a->next=b->next;
b->next=a;
if (prev)
prev->next=b;
p=b;
sorted=0;
}
prev=p;
p=p->next;
}
}
//temp=h;
//for(n=0;temp!=0;temp=temp->next) printf("POST:%s\n",temp->path);
}
struct SimpleDirEntry * dir_entries_filtered(char const * dirPath,int(* filter)(struct SimpleDirEntry *))
{
int room = dir_cache_size/sizeof(struct SimpleDirEntry);
......
struct SimpleDirEntry * prev = (struct SimpleDirEntry *)dir_cache;
strcpy(prev->path,"..");
strcpy(prev->lfn,"..");
prev->filename_ptr = prev->path;
prev->size = 0;
prev->is_subdir = 1;
--room;
//int count=0;
struct SimpleDirEntry * entry = 0;
while (FR_OK == pf_readdir(&dir,&filinfo) && filinfo.fname[0]!='\0')
{
......
break; // OUT OF ROOM!
}
printf("next %x %d ",entry,room);
//printf("next %x %d ",entry,room);
entry->is_subdir = (filinfo.fattrib & AM_DIR) ? 1 : 0;
printf("%s ",filinfo.fname);
//printf("%s ",filinfo.fname);
strcpy(&entry->path[0],dirPath);
ptr = &entry->path[0];
......
strcpy(ptr,filinfo.fname);
entry->size = filinfo.fsize;
strcpy(&entry->lfn[0],&filinfo.lfname[0]);
// printf("%d %s %s\n",count++, filinfo.fname, filinfo.lfname);
entry->next = 0;
if (filter && !filter(entry))
......
prev->next = entry;
prev = entry;
printf("n %d %d %x ",filinfo.fsize, entry->size, entry->next);
//printf("n %d %d %x ",filinfo.fsize, entry->size, entry->next);
}
printf("dir_entries done ");
//printf("dir_entries done ");
entry->next = 0;
/* struct SimpleDirEntry * begin = (struct SimpleDirEntry *) dir_cache;
count = 0;
while (begin)
{
printf("%d %s\n",count++, begin->path);
begin = begin->next;
}*/
sort_ll((struct SimpleDirEntry *) dir_cache);
return (struct SimpleDirEntry *) dir_cache;
}
......
char const * dir_filename(struct SimpleDirEntry * entry)
{
return entry->filename_ptr;
//return entry->filename_ptr;
return &entry->lfn[0];
}
int dir_filesize(struct SimpleDirEntry * entry)
firmware/fat/pff_file.h
{
char path[MAX_PATH_LENGTH];
char * filename_ptr;
char lfn[256];
int size;
int is_subdir;
struct SimpleDirEntry * next; // as linked list - want to allow sorting...
firmware/fileselector.c
++entries;
temp_entry = dir_next(temp_entry);
}
printf("Entries:%d\n",entries);
// Selected item
int pos = 0;
......
// render
{
// find which chunk to render
int startpos = pos-20;
int startpos = pos-10;
//printf("\nA pos:%d, startpos:%d\n",pos,startpos);
//startpos &= 0xfffffffe;
//printf("startpos:%d\n",startpos);
if (startpos<0) startpos=0;
//printf("pos:%d, startpos:%d\n",pos,startpos);
// get the dir entries for these
struct SimpleDirEntry * render_entry = entry;
......
// output the new entries
int line;
for (line=0; line<44; ++line)
debug_pos = 0;
int end = 21*40;
for (;;)
{
if (!render_entry) break;
debug_pos = line*20;
int prev_debug_pos = debug_pos;
if (render_entry == sel_entry)
{
debug_adjust = 128;
......
printf("%s",dir_filename(render_entry));
render_entry = dir_next(render_entry);
while(prev_debug_pos<debug_pos)
{
prev_debug_pos+=40;
}
debug_pos = prev_debug_pos;
//printf("debug_pos:%d",debug_pos);
if (debug_pos>=end) break;
}
debug_pos = 40*23;
......
return;
}
pos += joy.x_;
pos += joy.y_*2;
pos += joy.x_*10;
pos += joy.y_;
}
}
}
firmware/fileutils.c
#include "printf.h"
int compare_ext(char const * filenamein, char const * extin)
{
int dot = 0;
char filename[64];
char ext[64];
char filename[256];
char ext[4];
stricpy(filename,filenamein);
stricpy(ext,extin);
//printf("WTFA:%s %s\n",filenamein, extin);
//printf("WTFB:%s %s\n",filename, ext);
while (1)
{
if (filename[dot] == '\0')
firmware/main.c
for (i=0; i!=4; ++i)
{
files[i] = (struct SimpleFile *)alloca(file_struct_size());
file_init(files[i]);
}
freeze_init((void*)0xc20000); // 128k
......
int row = 0;
for (;;)
int done = 0;
for (;!done;)
{
// Render
clearscreen();
......
debug_pos = 160;
debug_adjust = row==2 ? 128 : 0;
printf("Rom bank:%d", get_rom_select());
debug_pos = 240;
int i;
for (i=1;i!=5;++i)
{
int temp = debug_pos;
debug_adjust = row==i+2 ? 128 : 0;
printf("Drive %d:%s", i, file_name(files[i-1]));
debug_pos = temp+40;
}
debug_pos = 440;
debug_adjust = row==7 ? 128 : 0;
printf("Exit");
// Slow it down a bit
wait_us(100000);
......
joystick_wait(&joy,WAIT_QUIET);
joystick_wait(&joy,WAIT_EITHER);
if (joy.fire_) break;
row+=joy.y_;
if (row<0) row = 0;
if (row>2) row = 2;
if (row>7) row = 7;
switch (row)
{
case 0:
......
set_rom_select(rom_select);
}
break;
case 3:
case 4:
case 5:
case 6:
{
if (joy.x_>0)
{
// Choose new disk
file_selector(files[row-3]);
set_drive_status(row-3,files[row-3]);
}
else if(joy.x_<0)
{
// Remove disk
file_init(files[row-3]);
set_drive_status(row-3,files[row-3]);
}
else if (joy.fire_)
{
struct SimpleFile * temp;
temp = files[0];
files[0] = files[row-3];
files[row-3] = temp;
set_drive_status(row-3,temp);
set_drive_status(0,files[0]);
}
}
break;
case 7:
if (joy.fire_)
{
done = 1;
}
break;
}
}
}
firmware/sd_direct/diskio_mmc.c
// Finalize write process
int retry=16; //zkusi to maximalne 16x
int ret;
printf(":WSECT:%d",n_actual_mmc_sector);
//printf(":WSECT:%d",n_actual_mmc_sector);
do
{
ret = mmcWrite(n_actual_mmc_sector); //vraci 0 kdyz ok
retry--;
} while (ret && retry);
printf(":WD:");
//printf(":WD:");
}
firmware/simplefile.h
int file_struct_size();
void file_init(struct SimpleFile * file);
char const * file_name(struct SimpleFile * file);
enum SimpleFileStatus file_read(struct SimpleFile * file, void * buffer, int bytes, int * bytesread);
enum SimpleFileStatus file_seek(struct SimpleFile * file, int offsetFromStart);
firmware/test_drive.c
once = 1;
receive_buffer[receive_buffer_last++] = 0x31;
//receive_buffer[receive_buffer_last++] = 0x32;
receive_buffer[receive_buffer_last++] = 0x52;
receive_buffer[receive_buffer_last++] = 0x01;
receive_buffer[receive_buffer_last++] = 0x00;
receive_buffer[receive_buffer_last++] = 0x84;
//receive_buffer[receive_buffer_last++] = 0x85;
}
else
{
firmware/test_file.c
}*/
file_write(file,"Blah",4,&written);
printf("\n*** WTF:%s - %s - %s\n",file_name(file), file_of("/WTF"),file_of("/BLAH/BOOP"));
// So... for write can only seek to nearest 512...
fprintf(stderr,"\n\n");
......
fprintf(stderr,"%c", buffer[i]);
}
//file_selector(file);
file_selector(file);
return 0;
}

Also available in: Unified diff