/* [04/22/2003] 修改 load 檔案時原先每個 block(256 BYTES)寫入一次,改成兩個 blocks(512 BYTES) 寫入一次。 */ #include #include #include #include #include #include"8000.h" #include"fs_s256.h" //#define PUTCH ToCom2 //#define KBHIT IsCom2 //#define GETCH ReadCom2 #define PUTCH Putch #define KBHIT Kbhit #define GETCH Getch #define ACK 0x06 #define NAK 0x15 //#define dPrint printCom3 #define dPrint int ShowDebugMsg=0; static char *Msg_ErrorCmd="Error Command !\n\r"; static unsigned char far *fptr=(unsigned char far *)0xC0000000L; static unsigned FlashBase=0xC000; static int FlashSectorNo=4; struct Block { unsigned datano; unsigned char data[256]; unsigned char CRC16Hi; unsigned char CRC16Lo; }; struct FileInfo { char fname[13]; long size; int year,month,day; int hour,minute,second; }; struct FileInfo *fileinfo; unsigned char DataBuf[sizeof(struct Block)]; struct Block *block=(struct Block *)DataBuf; static unsigned *Crc16Table=NULL; static unsigned crc16=0; static void ResetCrc16(void) { crc16=0; } static unsigned ReadCrc16(void) { return crc16; } static void UpdateCrc16(unsigned char data) { crc16=(unsigned)(Crc16Table[crc16>>8] ^ (crc16<<8) ^ data); } static unsigned GetCRC16(unsigned char *data,int length) { ResetCrc16(); while(length--){ UpdateCrc16(*data++); } return crc16; } static void MakeCRC16Table(void) { int i,j,k,crc; static int Crc16TableOK=0; if(!Crc16Table) Crc16Table=(unsigned *)malloc(256*2); if(Crc16Table && !Crc16TableOK){ for(i=0;i<256;i++){ k=i<<8; crc=0; for(j=0;j<8;j++){ if((crc^k)&0x8000) crc=(crc<<1)^0x1021; else crc<<=1; k<<=1; } Crc16Table[i]=(unsigned)crc; } Crc16TableOK=1; } } #ifndef __FILE_DATA__ #define __FILE_DATA__ typedef struct { unsigned mark; // 0x7188 -> is file unsigned char fname[12]; unsigned char year; unsigned char month; unsigned char day; unsigned char hour; unsigned char minute; unsigned char sec; unsigned long size; char far *addr; unsigned CRC; // crc-16 unsigned CRC32; } FILE_DATA; #endif FILE_DATA CurFileData; void far *AddFarPtrLong(void far * ptr1,unsigned long size) { size +=(long)FP_OFF(ptr1); return MK_FP(FP_SEG(ptr1)+(unsigned)(size>>4),(unsigned)(size & 0x0F)); } //static long FreeSizeForFile; /* every block has data_length(2 bytes)+data(256 bytes)+CRC_16(2 bytes) =260 bytes. */ /* //New MiniOS7 library with this function. unsigned long GetTimeTicks(void) { unsigned long tmp; _asm pushf _asm cli tmp=*TimeTicks; _asm popf return tmp; } */ int ReceiveDataBlock(void) { unsigned char *dataptr; int i,quit=0; int times=0; unsigned long time,time1; while(!quit){ dataptr=DataBuf; time=GetTimeTicks(); while(!KBHIT()){ time1=GetTimeTicks(); if(time1-time > 30000){ return -1; } } ResetCrc16(); ///2 for(i=0;i 300){ break; } } } if(i==sizeof(struct Block)){ if(ReadCrc16()){ ///2 /* CRC error */ PUTCH(NAK); dPrint("[NAK]"); times++; if(times>=3) quit=1; } else { return NoError; } } else { PUTCH(NAK); dPrint("[NAK1]"); times++; if(times>=3) quit=1; } } return -1; } //#define _DEBUG_LOAD_ unsigned char WriteBuf[512]; unsigned WriteSize; void LoadFile(void) { long BlockNo,i; int data; int err,idx,offset; // unsigned fileno; unsigned char *ptr; PCFD out_fd; DATESTR date; MakeCRC16Table(); Print("Press ALT_E to download file!"); if(ReceiveDataBlock()) goto EndTransfer; if(*(int *)DataBuf==0) goto EndTransfer; fileinfo=(struct FileInfo *)(DataBuf+2); /* save the file info. */ // CurFileData.year=fileinfo->year; // CurFileData.month=fileinfo->month; // CurFileData.day=fileinfo->day; // CurFileData.hour=fileinfo->hour; // CurFileData.minute=fileinfo->minute; // CurFileData.sec=fileinfo->second; date.time = (word) ( (fileinfo->hour << 11) | (fileinfo->minute << 5) | (fileinfo->second/2)); date.date = (word) ( ((fileinfo->year) << 9) | (fileinfo->month << 5) | fileinfo->day); strncpy(CurFileData.fname,fileinfo->fname,12); if(ShowDebugMsg){ dPrint("filename=%s\r\n",CurFileData.fname); dPrint("length=%lu\r\n",fileinfo->size); // dPrint("FreeSize=%lu\r\n",FreeSizeForFile); dPrint("%d-%02d-%02d\r\n",1980+fileinfo->year,fileinfo->month,fileinfo->day); } if ((out_fd = pc_open(CurFileData.fname,(word) (PO_BINARY|PO_WRONLY|PO_CREAT|PO_TRUNC),(word) (PS_IWRITE | PS_IREAD) ) ) < 0) { PUTCH('S'); if(ShowDebugMsg){ dPrint("Cant open %s\n\r", CurFileData.fname); } return; } else { if(ShowDebugMsg){ dPrint("[Open %s success]\n\r", CurFileData.fname); } } BlockNo=(fileinfo->size+255)/256; PUTCH(ACK); dPrint("[ACK0]"); for(i=0,WriteSize=0;idata,block->datano); WriteSize+=block->datano; if(WriteSize==512 || block->datano < 256){ err=pc_write(out_fd,WriteBuf,WriteSize); if(err != WriteSize){ Print("Write failure(%d)\n\r",err); WriteSize=0; break; } else WriteSize=0; } /* if (pc_write(out_fd,block->data,block->datano) != block->datano){ Print("Write failure\n\r"); break; } */ PUTCH(ACK); dPrint("[ACK%ld]",i); } if(WriteSize){ err=pc_write(out_fd,WriteBuf,WriteSize); if(err != WriteSize){ Print("Write failure(%d)\n\r",err); } } EndTransfer: if(out_fd) pc_close(out_fd); if(i==BlockNo) pc_set_ftime(CurFileData.fname,date); } int SendDataBlock(void) { int quit=0; int times=0; int i; long t; unsigned char ack; while(!quit){ for(i=0;i<260;i++){ Putch(DataBuf[i]); } t=GetTimeTicks(); // wait for ACK/NAK while(!Kbhit()){ if((GetTimeTicks()-t) > 3000) return 2; } ack=Getch(); if(ack==ACK){ return 0; } else { if(ack==NAK){ times++; if(times>=3) quit=1; } else { quit=1; } } } return 1; } unsigned char TmpBuf[512]; int DoGetFile(int argc, char *argv[]) { PCFD out_fd; STAT stat; unsigned j,nread; long i,BlockNo; void GetFile(PCFD in_fd); if(argc){ if ((out_fd = pc_open(argv[0],(word) (PO_BINARY|PO_RDONLY),(word) (PS_IWRITE | PS_IREAD) ) ) < 0) { Print("Can not open %s\n\r", argv[0]); } else { MakeCRC16Table(); if(pc_fstat(out_fd, &stat)){ Print("Get file info. Error!"); return 1; } Print("Press ALT_G to get file!"); do { if(Kbhit()){ if(Getch()=='S') { Show5DigitLed(1,0); Show5DigitLed(2,0); Show5DigitLed(3,0); Show5DigitLed(4,0); Show5DigitLed(5,1); break; } else { Show5DigitLed(1,14); Show5DigitLed(2,0); Show5DigitLed(3,0); Show5DigitLed(4,0); Show5DigitLed(5,1); goto Get_Error; } } }while(1); //Make File info. block fileinfo=(struct FileInfo *)(DataBuf+2); /* save the file info. */ fileinfo->year=1980+((stat.st_mtime.date >> 9) & 0xff); fileinfo->month=(stat.st_mtime.date >> 5 ) & 0xf; fileinfo->day=(stat.st_mtime.date & 0x1f); fileinfo->hour=(stat.st_mtime.time >> 11) & 0x1f; fileinfo->minute=(stat.st_mtime.time >> 5) & 0x3f; fileinfo->second=(stat.st_mtime.time & 0x1f) << 1; fileinfo->size=stat.st_size; strncpy(fileinfo->fname,argv[0],12); block->datano=sizeof(struct FileInfo); block->CRC16Hi=block->CRC16Lo=0; i=GetCRC16(DataBuf,sizeof(struct Block)); block->CRC16Lo=i; block->CRC16Hi=(i>>8); if((i=SendDataBlock())) { Show5DigitLed(1,14); Show5DigitLed(2,0); Show5DigitLed(3,i); Show5DigitLed(4,0); Show5DigitLed(5,2); goto EndTransfer; } if(*(int *)DataBuf==0) { Show5DigitLed(1,14); Show5DigitLed(2,0); Show5DigitLed(3,0); Show5DigitLed(4,0); Show5DigitLed(5,3); goto EndTransfer; } BlockNo=(stat.st_size+255)/256; Show5DigitLed(2,BlockNo/16); Show5DigitLedWithDot(3,BlockNo%16); #define _USE_METHOD_1_ #ifdef _USE_METHOD_0_ for(i=0;i0 && nread <= 256){ if(ShowDebugMsg) dPrint("{%ld}",i); block->datano=nread; block->CRC16Hi=block->CRC16Lo=0; j=GetCRC16(DataBuf,sizeof(struct Block)); block->CRC16Lo=j; block->CRC16Hi=(j>>8); if(SendDataBlock()) goto EndTransfer; } else { Print("Read failure\n\r"); break; } } #endif #ifdef _USE_METHOD_1_ for(i=0;i0 && nread <= 512){ char *tmp=TmpBuf; int datano; if(ShowDebugMsg) dPrint("{%ld}",i); do{ if(nread>256){ datano=256; } else datano=nread; memcpy(DataBuf+2,tmp,datano); block->datano=datano; block->CRC16Hi=block->CRC16Lo=0; j=GetCRC16(DataBuf,sizeof(struct Block)); block->CRC16Lo=j; block->CRC16Hi=(j>>8); if(SendDataBlock()) goto EndTransfer; nread-=datano; tmp+=datano; }while(nread); } else { Print("Read failure\n\r"); break; } } #endif Get_Error: pc_close(out_fd); EndTransfer: } } return 1; }