OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/trunk/bootloaders/orpmon/common
    from Rev 389 to Rev 406
    Reverse comparison

Rev 389 → Rev 406

/dosfs.c
6,132 → 6,197
payment of royalty, regardless of the license(s) you choose for those projects.
 
You cannot re-copyright or restrict use of the code as released by Lewin Edwards.
*/
 
*/
/*
@2010, adam.edvardsson@orsoc.se
Added local copy of the functions,
div_t, memcmp2,strcpy2,strcmp2. The one from the string library is not comatible
*/
*/
- //#include //#include //#include "or32_utils.h" #include "dosfs.h" #include "sdc.h" - + #include "common.h" #include "support.h" #include "uart.h" +unsigned long int init_fat(VOLINFO * vis) +{ +unsigned char sector[SECTOR_SIZE]; +unsigned long int pstart, psize, i, fisz; +unsigned char pactive, ptype; +VOLINFO vi; + //uart_init(DEFAULT_UART); + printf("FAT INIT START\n"); +memCardInit(); +pstart = DFS_GetPtnStart(0, sector, 0, &pactive, &ptype, &psize); +if (pstart == 0xffffffff) { +printf("Cannot find first partition\n"); +return -1; +} +printf + ("Partition 0 start sector 0x%-08.8lX active %-02.2hX type %-02.2hX size %-08.8lX\n", + pstart, pactive, ptype, psize); +if (DFS_GetVolInfo(0, sector, pstart, &vi)) { +printf("Error getting volume information\n"); +return -1; +} +*vis = vi; +} + +unsigned long int DFS_ReadSector(unsigned char unit, unsigned char *buffer, + unsigned long int sector, + unsigned long int count) +{ +unsigned long int block_add = 0; +int i; +for (i = 0; i < count; i++) { +block_add = sector + i; +DBGA("\n readSector %u, block_addr %u \n", sector, block_add); +setup_bd_transfer(READ_OP, block_add, buffer); +if (finnish_bd_transfer() == FALSE) +return 0xff; +} +return 0; +} + +unsigned long int DFS_WriteSector(unsigned char unit, unsigned char *buffer, + unsigned long int sector, + unsigned long int count) +{ +unsigned long int block_add = 0; +unsigned char scr[SECTOR_SIZE]; +block_add = sector; +DBGA("\n writeSector %u, block_addr2 %u \n", sector, block_add); +setup_bd_transfer(WRITE_OP, block_add, buffer); +if (finnish_bd_transfer() == FALSE) { +printf("TRANSACTION FAILED, Buffer %x \n", buffer); + //reset_card(); + // sd_wait_rsp(); + // SD_REG(SD_SOFTWARE_RST)=1; + + //SD_REG(SD_SOFTWARE_RST)=0; +DBGA("FREE BD TX/RX: 0x%x \n", SD_REG(BD_STATUS)); +DBGA("TRY READ SECTOR \n"); +setup_bd_transfer(READ_OP, 526571008, scr); +finnish_bd_transfer(); +DBGA("PRINT test wreite to 526571008 \n"); +setup_bd_transfer(WRITE_OP, 526571008, scr); +finnish_bd_transfer(); +setup_bd_transfer(WRITE_OP, block_add, buffer); +if (finnish_bd_transfer() == FALSE) { +printf("TRANSACTION FAILED AGAIN!, Buffer %x \n", + buffer); +return 0xff; +} +} +return 0; +} + -unsigned long int init_fat(VOLINFO *vis){ - - - - unsigned char sector[SECTOR_SIZE]; - unsigned long int pstart,psize, i,fisz; - unsigned char pactive, ptype; - VOLINFO vi; - - - //uart_init(DEFAULT_UART); - printf("FAT INIT START\n"); - memCardInit(); - - - pstart = DFS_GetPtnStart(0, sector, 0, &pactive, &ptype, &psize); - if (pstart == 0xffffffff) { - printf("Cannot find first partition\n"); - return -1; - } - - printf("Partition 0 start sector 0x%-08.8lX active %-02.2hX type %-02.2hX size %-08.8lX\n", pstart, pactive, ptype, psize); - - if (DFS_GetVolInfo(0, sector, pstart, &vi)) { - printf("Error getting volume information\n"); - return -1; - } - - - - - *vis=vi; - - - -} - - -unsigned long int DFS_ReadSector(unsigned char unit, unsigned char *buffer, unsigned long int sector, unsigned long int count) -{ - - unsigned long int block_add = 0; - int i ; - - - - for (i=0; i 3) +return DFS_ERRMISC; -unsigned long int DFS_GetPtnStart(unsigned char unit, unsigned char *scratchsector, unsigned char pnum, unsigned char *pactive, unsigned char *pptype, unsigned long int *psize) -{ - unsigned long int result; - PMBR mbr = (PMBR) scratchsector; + // Read MBR from target media + if (DFS_ReadSector(unit, scratchsector, 0, 1)) { +return DFS_ERRMISC; +} +result = (unsigned long int)mbr->ptable[pnum].start_0 | + (((unsigned long int)mbr->ptable[pnum].start_1) << 8) | + (((unsigned long int)mbr->ptable[pnum].start_2) << 16) | + (((unsigned long int)mbr->ptable[pnum].start_3) << 24); - // DOS ptable supports maximum 4 partitions - if (pnum > 3) - return DFS_ERRMISC; + //unsigned char active; // 0x80 if partition active + //unsigned char start_h; // starting head + //unsigned char start_cs_l; // starting cylinder and sector (low byte) + //unsigned char start_cs_h; // starting cylinder and sector (high byte) +printf("active 0:%x 1:%x 2:%x 3:%x \n", mbr->ptable[pnum].active, + mbr->ptable[pnum].start_h, mbr->ptable[pnum].start_cs_l, + mbr->ptable[pnum].start_cs_h); +printf("start 0:%x 1:%x 2:%x 3:%x \n", mbr->ptable[pnum].start_0, + mbr->ptable[pnum].start_1, mbr->ptable[pnum].start_2, + mbr->ptable[pnum].start_3); +if (pactive) +*pactive = mbr->ptable[pnum].active; +if (pptype) +*pptype = mbr->ptable[pnum].type; +if (psize) { +*psize = (unsigned long int)mbr->ptable[pnum].size_0 | + (((unsigned long int)mbr->ptable[pnum].size_1) << 8) | + (((unsigned long int)mbr->ptable[pnum].size_2) << 16) | + (((unsigned long int)mbr->ptable[pnum].size_3) << 24); +printf("size 0:%x 1:%x 2:%x 3:%x \n", mbr->ptable[pnum].size_0, + mbr->ptable[pnum].size_1, mbr->ptable[pnum].size_2, + mbr->ptable[pnum].size_3); +} +return result; +} + +ldiv_t ldiv(long int numer, long int denom) +{ +ldiv_t result; +result.quot = numer / denom; +result.rem = numer % denom; - // Read MBR from target media - if (DFS_ReadSector(unit,scratchsector,0,1)) { - return DFS_ERRMISC; - } + /* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where + NUMER / DENOM is to be computed in infinite precision. In + other words, we should always truncate the quotient towards + zero, never -infinity. Machine division and remainer may + work either way when one or both of NUMER or DENOM is + negative. If only one is negative and QUOT has been + truncated towards -infinity, REM will have the same sign as + DENOM and the opposite sign of NUMER; if both are negative + and QUOT has been truncated towards -infinity, REM will be + positive (will have the opposite sign of NUMER). These are + considered `wrong'. If both are NUM and DENOM are positive, + RESULT will always be positive. This all boils down to: if + NUMER >= 0, but REM < 0, we got the wrong answer. In that + case, to get the right answer, add 1 to QUOT and subtract + DENOM from REM. */ +if (numer >= 0 && result.rem < 0) + { +++result.quot; +result.rem -= denom; +} +return result; +} + +div_t div(int numer, int denom) +{ +div_t result; +result.quot = numer / denom; +result.rem = numer % denom; - result = (unsigned long int) mbr->ptable[pnum].start_0 | - (((unsigned long int) mbr->ptable[pnum].start_1) << 8) | - (((unsigned long int) mbr->ptable[pnum].start_2) << 16) | - (((unsigned long int) mbr->ptable[pnum].start_3) << 24); - - - //unsigned char active; // 0x80 if partition active - //unsigned char start_h; // starting head - //unsigned char start_cs_l; // starting cylinder and sector (low byte) - //unsigned char start_cs_h; // starting cylinder and sector (high byte) - - printf("active 0:%x 1:%x 2:%x 3:%x \n", mbr->ptable[pnum].active, mbr->ptable[pnum].start_h, mbr->ptable[pnum].start_cs_l,mbr->ptable[pnum].start_cs_h); - - printf("start 0:%x 1:%x 2:%x 3:%x \n", mbr->ptable[pnum].start_0, mbr->ptable[pnum].start_1,mbr->ptable[pnum].start_2,mbr->ptable[pnum].start_3); - if (pactive) - *pactive = mbr->ptable[pnum].active; + /* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where + NUMER / DENOM is to be computed in infinite precision. In + other words, we should always truncate the quotient towards + zero, never -infinity. Machine division and remainer may + work either way when one or both of NUMER or DENOM is + negative. If only one is negative and QUOT has been + truncated towards -infinity, REM will have the same sign as + DENOM and the opposite sign of NUMER; if both are negative + and QUOT has been truncated towards -infinity, REM will be + positive (will have the opposite sign of NUMER). These are + considered `wrong'. If both are NUM and DENOM are positive, + RESULT will always be positive. This all boils down to: if + NUMER >= 0, but REM < 0, we got the wrong answer. In that + case, to get the right answer, add 1 to QUOT and subtract + DENOM from REM. */ +if (numer >= 0 && result.rem < 0) + { +++result.quot; +result.rem -= denom; +} +return result; +} + - if (pptype) - *pptype = mbr->ptable[pnum].type; - - if (psize){ - *psize = (unsigned long int) mbr->ptable[pnum].size_0 | - (((unsigned long int) mbr->ptable[pnum].size_1) << 8) | - (((unsigned long int) mbr->ptable[pnum].size_2) << 16) | - (((unsigned long int) mbr->ptable[pnum].size_3) << 24); - printf("size 0:%x 1:%x 2:%x 3:%x \n", mbr->ptable[pnum].size_0, mbr->ptable[pnum].size_1,mbr->ptable[pnum].size_2,mbr->ptable[pnum].size_3); - } - - return result; -} - - - - ldiv_t ldiv (long int numer, long int denom) -{ - ldiv_t result; - - result.quot = numer / denom; - result.rem = numer % denom; - - /* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where - NUMER / DENOM is to be computed in infinite precision. In - other words, we should always truncate the quotient towards - zero, never -infinity. Machine division and remainer may - work either way when one or both of NUMER or DENOM is - negative. If only one is negative and QUOT has been - truncated towards -infinity, REM will have the same sign as - DENOM and the opposite sign of NUMER; if both are negative - and QUOT has been truncated towards -infinity, REM will be - positive (will have the opposite sign of NUMER). These are - considered `wrong'. If both are NUM and DENOM are positive, - RESULT will always be positive. This all boils down to: if - NUMER >= 0, but REM < 0, we got the wrong answer. In that - case, to get the right answer, add 1 to QUOT and subtract - DENOM from REM. */ - - if (numer >= 0 && result.rem < 0) - { - ++result.quot; - result.rem -= denom; - } - - return result; -} - - div_t div ( int numer, int denom) -{ - div_t result; - - result.quot = numer / denom; - result.rem = numer % denom; - - /* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where - NUMER / DENOM is to be computed in infinite precision. In - other words, we should always truncate the quotient towards - zero, never -infinity. Machine division and remainer may - work either way when one or both of NUMER or DENOM is - negative. If only one is negative and QUOT has been - truncated towards -infinity, REM will have the same sign as - DENOM and the opposite sign of NUMER; if both are negative - and QUOT has been truncated towards -infinity, REM will be - positive (will have the opposite sign of NUMER). These are - considered `wrong'. If both are NUM and DENOM are positive, - RESULT will always be positive. This all boils down to: if - NUMER >= 0, but REM < 0, we got the wrong answer. In that - case, to get the right answer, add 1 to QUOT and subtract - DENOM from REM. */ - - if (numer >= 0 && result.rem < 0) - { - ++result.quot; - result.rem -= denom; - } - - return result; -} /* Retrieve volume info from BPB and store it in a VOLINFO structure You must provide the unit and starting sector of the filesystem, and @@ -259,94 +380,158 @@ a pointer to a sector buffer for scratch Attempts to read BPB and glean information about the FS from that. Returns 0 OK, nonzero for any error. -*/ -unsigned long int DFS_GetVolInfo(unsigned char unit, unsigned char *scratchsector, unsigned long int startsector, PVOLINFO volinfo) -{ - PLBR lbr = (PLBR) scratchsector; - volinfo->unit = unit; - volinfo->startsector = startsector; +*/ +unsigned long int DFS_GetVolInfo(unsigned char unit, + unsigned char *scratchsector, + unsigned long int startsector, + PVOLINFO volinfo) +{ +PLBR lbr = (PLBR) scratchsector; +volinfo->unit = unit; +volinfo->startsector = startsector; +if (DFS_ReadSector(unit, scratchsector, startsector, 1)) +return DFS_ERRMISC; - if(DFS_ReadSector(unit,scratchsector,startsector,1)) - return DFS_ERRMISC; - // tag: OEMID, refer dosfs.h -// strncpy(volinfo->oemid, lbr->oemid, 8); -// volinfo->oemid[8] = 0; +// strncpy(volinfo->oemid, lbr->oemid, 8); +// volinfo->oemid[8] = 0; +volinfo->secperclus = lbr->bpb.secperclus; +volinfo->reservedsecs = (unsigned short)lbr->bpb.reserved_l | + (((unsigned short)lbr->bpb.reserved_h) << 8); +volinfo->numsecs = (unsigned short)lbr->bpb.sectors_s_l | + (((unsigned short)lbr->bpb.sectors_s_h) << 8); +if (!volinfo->numsecs) +volinfo->numsecs = (unsigned long int)lbr->bpb.sectors_l_0 | + (((unsigned long int)lbr->bpb.sectors_l_1) << 8) | + (((unsigned long int)lbr->bpb.sectors_l_2) << 16) | + (((unsigned long int)lbr->bpb.sectors_l_3) << 24); - volinfo->secperclus = lbr->bpb.secperclus; - volinfo->reservedsecs = (unsigned short) lbr->bpb.reserved_l | - (((unsigned short) lbr->bpb.reserved_h) << 8); + // If secperfat is 0, we must be in a FAT32 volume; get secperfat + // from the FAT32 EBPB. The volume label and system ID string are also + // in different locations for FAT12/16 vs FAT32. + volinfo->secperfat = (unsigned short)lbr->bpb.secperfat_l | + (((unsigned short)lbr->bpb.secperfat_h) << 8); +if (!volinfo->secperfat) { +volinfo->secperfat = + (unsigned long int)lbr->ebpb.ebpb32. + fatsize_0 | +(((unsigned long int)lbr->ebpb.ebpb32. +(((unsigned long int)lbr->ebpb. + ebpb32. +(((unsigned + long int) + lbr->ebpb. + ebpb32. + fatsize_3) + << 24); +memcpy(volinfo->label, lbr->ebpb.ebpb32.label, 11); +volinfo->label[11] = 0; - volinfo->numsecs = (unsigned short) lbr->bpb.sectors_s_l | - (((unsigned short) lbr->bpb.sectors_s_h) << 8); - - if (!volinfo->numsecs) - volinfo->numsecs = (unsigned long int) lbr->bpb.sectors_l_0 | - (((unsigned long int) lbr->bpb.sectors_l_1) << 8) | - (((unsigned long int) lbr->bpb.sectors_l_2) << 16) | - (((unsigned long int) lbr->bpb.sectors_l_3) << 24); - - // If secperfat is 0, we must be in a FAT32 volume; get secperfat - // from the FAT32 EBPB. The volume label and system ID string are also - // in different locations for FAT12/16 vs FAT32. - volinfo->secperfat = (unsigned short) lbr->bpb.secperfat_l | - (((unsigned short) lbr->bpb.secperfat_h) << 8); - if (!volinfo->secperfat) { - volinfo->secperfat = (unsigned long int) lbr->ebpb.ebpb32.fatsize_0 | - (((unsigned long int) lbr->ebpb.ebpb32.fatsize_1) << 8) | - (((unsigned long int) lbr->ebpb.ebpb32.fatsize_2) << 16) | - (((unsigned long int) lbr->ebpb.ebpb32.fatsize_3) << 24); - - memcpy(volinfo->label, lbr->ebpb.ebpb32.label, 11); - volinfo->label[11] = 0; - // tag: OEMID, refer dosfs.h -// memcpy(volinfo->system, lbr->ebpb.ebpb32.system, 8); -// volinfo->system[8] = 0; - } - else { - memcpy(volinfo->label, lbr->ebpb.ebpb.label, 11); - volinfo->label[11] = 0; +// memcpy(volinfo->system, lbr->ebpb.ebpb32.system, 8); +// volinfo->system[8] = 0; + } + else { +memcpy(volinfo->label, lbr->ebpb.ebpb.label, 11); +volinfo->label[11] = 0; + // tag: OEMID, refer dosfs.h -// memcpy(volinfo->system, lbr->ebpb.ebpb.system, 8); -// volinfo->system[8] = 0; - } +// memcpy(volinfo->system, lbr->ebpb.ebpb.system, 8); +// volinfo->system[8] = 0; + } - // note: if rootentries is 0, we must be in a FAT32 volume. - volinfo->rootentries = (unsigned short) lbr->bpb.rootentries_l | - (((unsigned short) lbr->bpb.rootentries_h) << 8); + // note: if rootentries is 0, we must be in a FAT32 volume. + volinfo->rootentries = (unsigned short)lbr->bpb.rootentries_l | + (((unsigned short)lbr->bpb.rootentries_h) << 8); - // after extracting raw info we perform some useful precalculations - volinfo->fat1 = startsector + volinfo->reservedsecs; + // after extracting raw info we perform some useful precalculations + volinfo->fat1 = startsector + volinfo->reservedsecs; - // The calculation below is designed to round up the root directory size for FAT12/16 - // and to simply ignore the root directory for FAT32, since it's a normal, expandable - // file in that situation. - if (volinfo->rootentries) { - volinfo->rootdir = volinfo->fat1 + (volinfo->secperfat * 2); - volinfo->dataarea = volinfo->rootdir + (((volinfo->rootentries * 32) + (SECTOR_SIZE - 1)) / SECTOR_SIZE); - } - else { - volinfo->dataarea = volinfo->fat1 + (volinfo->secperfat * 2); - volinfo->rootdir = (unsigned long int) lbr->ebpb.ebpb32.root_0 | - (((unsigned long int) lbr->ebpb.ebpb32.root_1) << 8) | - (((unsigned long int) lbr->ebpb.ebpb32.root_2) << 16) | - (((unsigned long int) lbr->ebpb.ebpb32.root_3) << 24); - } + // The calculation below is designed to round up the root directory size for FAT12/16 + // and to simply ignore the root directory for FAT32, since it's a normal, expandable + // file in that situation. + if (volinfo->rootentries) { +volinfo->rootdir = volinfo->fat1 + (volinfo->secperfat * 2); +volinfo->dataarea = + volinfo->rootdir + + (((volinfo->rootentries * 32) + + (SECTOR_SIZE - 1)) / SECTOR_SIZE); +} + + else { +volinfo->dataarea = volinfo->fat1 + (volinfo->secperfat * 2); +volinfo->rootdir = + (unsigned long int)lbr->ebpb.ebpb32. +(((unsigned long int)lbr->ebpb.ebpb32.root_1) << +(((unsigned long int)lbr->ebpb.ebpb32. +(((unsigned long int) + lbr->ebpb.ebpb32. + root_3) << 24); - // Calculate number of clusters in data area and infer FAT type from this information. - volinfo->numclusters = (volinfo->numsecs - volinfo->dataarea) / volinfo->secperclus; - if (volinfo->numclusters < 4085) - volinfo->filesystem = FAT12; - else if (volinfo->numclusters < 65525) - volinfo->filesystem = FAT16; - else - volinfo->filesystem = FAT32; + // Calculate number of clusters in data area and infer FAT type from this information. + volinfo->numclusters = + (volinfo->numsecs - volinfo->dataarea) / volinfo->secperclus; +if (volinfo->numclusters < 4085) +volinfo->filesystem = FAT12; + + else if (volinfo->numclusters < 65525) +volinfo->filesystem = FAT16; + + else +volinfo->filesystem = FAT32; +return DFS_OK; +} + - return DFS_OK; -} - /* Fetch FAT entry for specified cluster number You must provide a scratch buffer for one sector (SECTOR_SIZE) and a populated VOLINFO @@ -354,86 +539,136 @@ FAT entry. scratchcache should point to a UINT32. This variable caches the physical sector number last read into the scratch buffer for performance enhancement reasons. -*/ -unsigned long int DFS_GetFAT(PVOLINFO volinfo, unsigned char *scratch, unsigned long int *scratchcache, unsigned long int cluster) -{ - unsigned long int offset, sector, result; +*/ +unsigned long int DFS_GetFAT(PVOLINFO volinfo, unsigned char *scratch, + unsigned long int *scratchcache, + unsigned long int cluster) +{ +unsigned long int offset, sector, result; +if (volinfo->filesystem == FAT12) { +offset = cluster + (cluster / 2); +} + + else if (volinfo->filesystem == FAT16) { +offset = cluster * 2; +} + + else if (volinfo->filesystem == FAT32) { +offset = cluster * 4; +} + + else +return 0x0ffffff7; // FAT32 bad cluster + + // at this point, offset is the BYTE offset of the desired sector from the start + // of the FAT. Calculate the physical sector containing this FAT entry. + sector = ldiv(offset, SECTOR_SIZE).quot + volinfo->fat1; - if (volinfo->filesystem == FAT12) { - offset = cluster + (cluster / 2); - } - else if (volinfo->filesystem == FAT16) { - offset = cluster * 2; - } - else if (volinfo->filesystem == FAT32) { - offset = cluster * 4; - } - else - return 0x0ffffff7; // FAT32 bad cluster + // If this is not the same sector we last read, then read it into RAM + if (sector != *scratchcache) { +if (DFS_ReadSector(volinfo->unit, scratch, sector, 1)) { + + // avoid anyone assuming that this cache value is still valid, which + // might cause disk corruption + *scratchcache = 0; +return 0x0ffffff7; // FAT32 bad cluster + } +*scratchcache = sector; +} - // at this point, offset is the BYTE offset of the desired sector from the start - // of the FAT. Calculate the physical sector containing this FAT entry. - sector = ldiv(offset, SECTOR_SIZE).quot + volinfo->fat1; + // At this point, we "merely" need to extract the relevant entry. + // This is easy for FAT16 and FAT32, but a royal PITA for FAT12 as a single entry + // may span a sector boundary. The normal way around this is always to read two + // FAT sectors, but that luxury is (by design intent) unavailable to DOSFS. + offset = ldiv(offset, SECTOR_SIZE).rem; +if (volinfo->filesystem == FAT12) { + + // Special case for sector boundary - Store last byte of current sector. + // Then read in the next sector and put the first byte of that sector into + // the high byte of result. + if (offset == SECTOR_SIZE - 1) { +result = (unsigned long int)scratch[offset]; +sector++; +if (DFS_ReadSector(volinfo->unit, scratch, sector, 1)) { + + // avoid anyone assuming that this cache value is still valid, which + // might cause disk corruption + *scratchcache = 0; +return 0x0ffffff7; // FAT32 bad cluster + } +*scratchcache = sector; + + // Thanks to Claudio Leonel for pointing out this missing line. + result |= ((unsigned long int)scratch[0]) << 8; +} + + else { +result = (unsigned long int)scratch[offset] | + ((unsigned long int)scratch[offset + 1]) << 8; +if (cluster & 1) +result = result >> 4; + + else +result = result & 0xfff; +} + + else if (volinfo->filesystem == FAT16) { +result = (unsigned long int)scratch[offset] | + ((unsigned long int)scratch[offset + 1]) << 8; +} + + else if (volinfo->filesystem == FAT32) { +result = ((unsigned long int)scratch[offset] | + ((unsigned long int)scratch[offset + 1]) << 8 | + ((unsigned long int)scratch[offset + 2]) << 16 | + ((unsigned long int)scratch[offset + 3]) << 24) & + 0x0fffffff; +} + + else +result = 0x0ffffff7; // FAT32 bad cluster + return result; +} + - // If this is not the same sector we last read, then read it into RAM - if (sector != *scratchcache) { - if(DFS_ReadSector(volinfo->unit, scratch, sector, 1)) { - // avoid anyone assuming that this cache value is still valid, which - // might cause disk corruption - *scratchcache = 0; - return 0x0ffffff7; // FAT32 bad cluster - } - *scratchcache = sector; - } - - // At this point, we "merely" need to extract the relevant entry. - // This is easy for FAT16 and FAT32, but a royal PITA for FAT12 as a single entry - // may span a sector boundary. The normal way around this is always to read two - // FAT sectors, but that luxury is (by design intent) unavailable to DOSFS. - offset = ldiv(offset, SECTOR_SIZE).rem; - - if (volinfo->filesystem == FAT12) { - // Special case for sector boundary - Store last byte of current sector. - // Then read in the next sector and put the first byte of that sector into - // the high byte of result. - if (offset == SECTOR_SIZE - 1) { - result = (unsigned long int) scratch[offset]; - sector++; - if(DFS_ReadSector(volinfo->unit, scratch, sector, 1)) { - // avoid anyone assuming that this cache value is still valid, which - // might cause disk corruption - *scratchcache = 0; - return 0x0ffffff7; // FAT32 bad cluster - } - *scratchcache = sector; - // Thanks to Claudio Leonel for pointing out this missing line. - result |= ((unsigned long int) scratch[0]) << 8; - } - else { - result = (unsigned long int) scratch[offset] | - ((unsigned long int) scratch[offset+1]) << 8; - } - if (cluster & 1) - result = result >> 4; - else - result = result & 0xfff; - } - else if (volinfo->filesystem == FAT16) { - result = (unsigned long int) scratch[offset] | - ((unsigned long int) scratch[offset+1]) << 8; - } - else if (volinfo->filesystem == FAT32) { - result = ((unsigned long int) scratch[offset] | - ((unsigned long int) scratch[offset+1]) << 8 | - ((unsigned long int) scratch[offset+2]) << 16 | - ((unsigned long int) scratch[offset+3]) << 24) & 0x0fffffff; - } - else - result = 0x0ffffff7; // FAT32 bad cluster - return result; -} - - /* Set FAT entry for specified cluster number You must provide a scratch buffer for one sector (SECTOR_SIZE) and a populated VOLINFO @@ -449,171 +684,326 @@ If you are operating DOSFS over flash, you are strongly advised to implement a writeback cache in your physical I/O driver. This will speed up your code significantly and will also conserve power and flash write life. -*/ -unsigned long int DFS_SetFAT(PVOLINFO volinfo, unsigned char *scratch, unsigned long int *scratchcache, unsigned long int cluster, unsigned long int new_contents) -{ - unsigned long int offset, sector, result; - if (volinfo->filesystem == FAT12) { - offset = cluster + (cluster / 2); - new_contents &=0xfff; - } - else if (volinfo->filesystem == FAT16) { - offset = cluster * 2; - new_contents &=0xffff; - } - else if (volinfo->filesystem == FAT32) { - offset = cluster * 4; - new_contents &=0x0fffffff; // FAT32 is really "FAT28" - } - else - return DFS_ERRMISC; +*/ +unsigned long int DFS_SetFAT(PVOLINFO volinfo, unsigned char *scratch, + unsigned long int *scratchcache, + unsigned long int cluster, + unsigned long int new_contents) +{ +unsigned long int offset, sector, result; +if (volinfo->filesystem == FAT12) { +offset = cluster + (cluster / 2); +new_contents &= 0xfff; +} + + else if (volinfo->filesystem == FAT16) { +offset = cluster * 2; +new_contents &= 0xffff; +} + + else if (volinfo->filesystem == FAT32) { +offset = cluster * 4; +new_contents &= 0x0fffffff; // FAT32 is really "FAT28" + } + + else +return DFS_ERRMISC; - // at this point, offset is the BYTE offset of the desired sector from the start - // of the FAT. Calculate the physical sector containing this FAT entry. - sector = ldiv(offset, SECTOR_SIZE).quot + volinfo->fat1; + // at this point, offset is the BYTE offset of the desired sector from the start + // of the FAT. Calculate the physical sector containing this FAT entry. + sector = ldiv(offset, SECTOR_SIZE).quot + volinfo->fat1; - // If this is not the same sector we last read, then read it into RAM - if (sector != *scratchcache) { - if(DFS_ReadSector(volinfo->unit, scratch, sector, 1)) { - // avoid anyone assuming that this cache value is still valid, which - // might cause disk corruption - *scratchcache = 0; - return DFS_ERRMISC; - } - *scratchcache = sector; - } + // If this is not the same sector we last read, then read it into RAM + if (sector != *scratchcache) { +if (DFS_ReadSector(volinfo->unit, scratch, sector, 1)) { + + // avoid anyone assuming that this cache value is still valid, which + // might cause disk corruption + *scratchcache = 0; +return DFS_ERRMISC; +} +*scratchcache = sector; +} - // At this point, we "merely" need to extract the relevant entry. - // This is easy for FAT16 and FAT32, but a royal PITA for FAT12 as a single entry - // may span a sector boundary. The normal way around this is always to read two - // FAT sectors, but that luxury is (by design intent) unavailable to DOSFS. - offset = ldiv(offset, SECTOR_SIZE).rem; + // At this point, we "merely" need to extract the relevant entry. + // This is easy for FAT16 and FAT32, but a royal PITA for FAT12 as a single entry + // may span a sector boundary. The normal way around this is always to read two + // FAT sectors, but that luxury is (by design intent) unavailable to DOSFS. + offset = ldiv(offset, SECTOR_SIZE).rem; +if (volinfo->filesystem == FAT12) { - if (volinfo->filesystem == FAT12) { + // If this is an odd cluster, pre-shift the desired new contents 4 bits to + // make the calculations below simpler + if (cluster & 1) +new_contents = new_contents << 4; - // If this is an odd cluster, pre-shift the desired new contents 4 bits to - // make the calculations below simpler - if (cluster & 1) - new_contents = new_contents << 4; + // Special case for sector boundary + if (offset == SECTOR_SIZE - 1) { - // Special case for sector boundary - if (offset == SECTOR_SIZE - 1) { + // Odd cluster: High 12 bits being set + if (cluster & 1) { +scratch[offset] = + (scratch[offset] & 0x0f) | new_contents & + 0xf0; +} + + // Even cluster: Low 12 bits being set + else { +scratch[offset] = new_contents & 0xff; +} +result = + DFS_WriteSector(volinfo->unit, scratch, + *scratchcache, 1); + + // mirror the FAT into copy 2 + if (DFS_OK == result) +result = + DFS_WriteSector(volinfo->unit, scratch, + (*scratchcache) + + volinfo->secperfat, 1); - // Odd cluster: High 12 bits being set - if (cluster & 1) { - scratch[offset] = (scratch[offset] & 0x0f) | new_contents & 0xf0; - } - // Even cluster: Low 12 bits being set - else { - scratch[offset] = new_contents & 0xff; - } - result = DFS_WriteSector(volinfo->unit, scratch, *scratchcache, 1); - // mirror the FAT into copy 2 - if (DFS_OK == result) - result = DFS_WriteSector(volinfo->unit, scratch, (*scratchcache)+volinfo->secperfat, 1); + // If we wrote that sector OK, then read in the subsequent sector + // and poke the first byte with the remainder of this FAT entry. + if (DFS_OK == result) { +*scratchcache++; +result = + DFS_ReadSector(volinfo->unit, scratch, + *scratchcache, 1); +if (DFS_OK == result) { + + // Odd cluster: High 12 bits being set + if (cluster & 1) { +scratch[0] = + new_contents & 0xff00; +} + + // Even cluster: Low 12 bits being set + else { +scratch[0] = + (scratch[0] & 0xf0) | + new_contents & 0x0f; +} +result = + DFS_WriteSector(volinfo->unit, + scratch, + *scratchcache, 1); + + // mirror the FAT into copy 2 + if (DFS_OK == result) +result = + DFS_WriteSector(volinfo-> + unit, + scratch, + (*scratchcache) + + + volinfo-> + secperfat, + 1); +} + + else { + + // avoid anyone assuming that this cache value is still valid, which + // might cause disk corruption + *scratchcache = 0; +} +} +} // if (offset == SECTOR_SIZE - 1) + + // Not a sector boundary. But we still have to worry about if it's an odd + // or even cluster number. + else { + + // Odd cluster: High 12 bits being set + if (cluster & 1) { +scratch[offset] = + (scratch[offset] & 0x0f) | new_contents & + 0xf0; +scratch[offset + 1] = new_contents & 0xff00; +} + + // Even cluster: Low 12 bits being set + else { +scratch[offset] = new_contents & 0xff; +scratch[offset + 1] = + (scratch[offset + 1] & 0xf0) | new_contents + & 0x0f; +} +result = + DFS_WriteSector(volinfo->unit, scratch, + *scratchcache, 1); + + // mirror the FAT into copy 2 + if (DFS_OK == result) +result = + DFS_WriteSector(volinfo->unit, scratch, + (*scratchcache) + + volinfo->secperfat, 1); +} +} + + else if (volinfo->filesystem == FAT16) { +scratch[offset] = (new_contents & 0xff); +scratch[offset + 1] = (new_contents & 0xff00) >> 8; +result = + DFS_WriteSector(volinfo->unit, scratch, *scratchcache, 1); + + // mirror the FAT into copy 2 + if (DFS_OK == result) +result = + DFS_WriteSector(volinfo->unit, scratch, + (*scratchcache) + + volinfo->secperfat, 1); +} + + else if (volinfo->filesystem == FAT32) { +scratch[offset] = (new_contents & 0xff); +scratch[offset + 1] = (new_contents & 0xff00) >> 8; +scratch[offset + 2] = (new_contents & 0xff0000) >> 16; +scratch[offset + 3] = + (scratch[offset + 3] & 0xf0) | ((new_contents & 0x0f000000) + >> 24); + + // Note well from the above: Per Microsoft's guidelines we preserve the upper + // 4 bits of the FAT32 cluster value. It's unclear what these bits will be used + // for; in every example I've encountered they are always zero. + result = + DFS_WriteSector(volinfo->unit, scratch, *scratchcache, 1); + + // mirror the FAT into copy 2 + if (DFS_OK == result) +result = + DFS_WriteSector(volinfo->unit, scratch, + (*scratchcache) + + volinfo->secperfat, 1); +} + + else +result = DFS_ERRMISC; +return result; +} + - // If we wrote that sector OK, then read in the subsequent sector - // and poke the first byte with the remainder of this FAT entry. - if (DFS_OK == result) { - *scratchcache++; - result = DFS_ReadSector(volinfo->unit, scratch, *scratchcache, 1); - if (DFS_OK == result) { - // Odd cluster: High 12 bits being set - if (cluster & 1) { - scratch[0] = new_contents & 0xff00; - } - // Even cluster: Low 12 bits being set - else { - scratch[0] = (scratch[0] & 0xf0) | new_contents & 0x0f; - } - result = DFS_WriteSector(volinfo->unit, scratch, *scratchcache, 1); - // mirror the FAT into copy 2 - if (DFS_OK == result) - result = DFS_WriteSector(volinfo->unit, scratch, (*scratchcache)+volinfo->secperfat, 1); - } - else { - // avoid anyone assuming that this cache value is still valid, which - // might cause disk corruption - *scratchcache = 0; - } - } - } // if (offset == SECTOR_SIZE - 1) - - // Not a sector boundary. But we still have to worry about if it's an odd - // or even cluster number. - else { - // Odd cluster: High 12 bits being set - if (cluster & 1) { - scratch[offset] = (scratch[offset] & 0x0f) | new_contents & 0xf0; - scratch[offset+1] = new_contents & 0xff00; - } - // Even cluster: Low 12 bits being set - else { - scratch[offset] = new_contents & 0xff; - scratch[offset+1] = (scratch[offset+1] & 0xf0) | new_contents & 0x0f; - } - result = DFS_WriteSector(volinfo->unit, scratch, *scratchcache, 1); - // mirror the FAT into copy 2 - if (DFS_OK == result) - result = DFS_WriteSector(volinfo->unit, scratch, (*scratchcache)+volinfo->secperfat, 1); - } - } - else if (volinfo->filesystem == FAT16) { - scratch[offset] = (new_contents & 0xff); - scratch[offset+1] = (new_contents & 0xff00) >> 8; - result = DFS_WriteSector(volinfo->unit, scratch, *scratchcache, 1); - // mirror the FAT into copy 2 - if (DFS_OK == result) - result = DFS_WriteSector(volinfo->unit, scratch, (*scratchcache)+volinfo->secperfat, 1); - } - else if (volinfo->filesystem == FAT32) { - scratch[offset] = (new_contents & 0xff); - scratch[offset+1] = (new_contents & 0xff00) >> 8; - scratch[offset+2] = (new_contents & 0xff0000) >> 16; - scratch[offset+3] = (scratch[offset+3] & 0xf0) | ((new_contents & 0x0f000000) >> 24); - // Note well from the above: Per Microsoft's guidelines we preserve the upper - // 4 bits of the FAT32 cluster value. It's unclear what these bits will be used - // for; in every example I've encountered they are always zero. - result = DFS_WriteSector(volinfo->unit, scratch, *scratchcache, 1); - // mirror the FAT into copy 2 - if (DFS_OK == result) - result = DFS_WriteSector(volinfo->unit, scratch, (*scratchcache)+volinfo->secperfat, 1); - } - else - result = DFS_ERRMISC; - - return result; -} - /* Convert a filename element from canonical (8.3) to directory entry (11) form src must point to the first non-separator character. dest must point to a 12-byte buffer. -*/ -unsigned char *DFS_CanonicalToDir(unsigned char *dest, unsigned char *src) -{ - unsigned char *destptr = dest; +*/ +unsigned char *DFS_CanonicalToDir(unsigned char *dest, unsigned char *src) +{ +unsigned char *destptr = dest; +memset(dest, ' ', 11); +dest[11] = 0; +while (*src && (*src != DIR_SEPARATOR) && (destptr - dest < 11)) { +if (*src >= 'a' && *src <= 'z') { +*destptr++ = (*src - 'a') + 'A'; +src++; +} + + else if (*src == '.') { +src++; +destptr = dest + 8; +} + + else { +*destptr++ = *src++; +} +} +return dest; +} + - memset(dest, ' ', 11); - dest[11] = 0; - - while (*src && (*src != DIR_SEPARATOR) && (destptr - dest < 11)) { - if (*src >= 'a' && *src <='z') { - *destptr++ = (*src - 'a') + 'A'; - src++; - } - else if (*src == '.') { - src++; - destptr = dest + 8; - } - else { - *destptr++ = *src++; - } - } - - return dest; -} - /* Find the first unused FAT entry You must provide a scratch buffer for one sector (SECTOR_SIZE) and a populated VOLINFO @@ -620,23 +1010,33 @@ Returns a FAT32 BAD_CLUSTER value for any error, otherwise the contents of the desired FAT entry. Returns FAT32 bad_sector (0x0ffffff7) if there is no free cluster available -*/ -unsigned long int DFS_GetFreeFAT(PVOLINFO volinfo, unsigned char *scratch) -{ - unsigned long int i, result = 0xffffffff, scratchcache = 0; - - // Search starts at cluster 2, which is the first usable cluster - // NOTE: This search can't terminate at a bad cluster, because there might - // legitimately be bad clusters on the disk. - for (i=2; i < volinfo->numclusters; i++) { - result = DFS_GetFAT(volinfo, scratch, &scratchcache, i); - if (!result) { - return i; - } - } - return 0x0ffffff7; // Can't find a free cluster -} +*/ +unsigned long int DFS_GetFreeFAT(PVOLINFO volinfo, unsigned char *scratch) +{ +unsigned long int i, result = 0xffffffff, scratchcache = 0; + // Search starts at cluster 2, which is the first usable cluster + // NOTE: This search can't terminate at a bad cluster, because there might + // legitimately be bad clusters on the disk. + for (i = 2; i < volinfo->numclusters; i++) { +result = DFS_GetFAT(volinfo, scratch, &scratchcache, i); +if (!result) { +return i; +} +} +return 0x0ffffff7; // Can't find a free cluster +} + /* Open a directory for enumeration by DFS_GetNextDirEnt @@ -644,106 +1044,209 @@ The empty string or a string containing only the directory separator are considered to be the root directory. Returns 0 OK, nonzero for any error. -*/ -unsigned long int DFS_OpenDir(PVOLINFO volinfo, unsigned char *dirname, PDIRINFO dirinfo) -{ - // Default behavior is a regular search for existing entries - dirinfo->flags = 0; +*/ +unsigned long int DFS_OpenDir(PVOLINFO volinfo, unsigned char *dirname, + PDIRINFO dirinfo) +{ + + // Default behavior is a regular search for existing entries + dirinfo->flags = 0; +if (!strlen((char *)dirname) + || (strlen((char *)dirname) == 1 + && dirname[0] == DIR_SEPARATOR)) { +if (volinfo->filesystem == FAT32) { +dirinfo->currentcluster = volinfo->rootdir; +dirinfo->currentsector = 0; +dirinfo->currententry = 0; - if (!strlen((char *) dirname) || (strlen((char *) dirname) == 1 && dirname[0] == DIR_SEPARATOR)) { - if (volinfo->filesystem == FAT32) { - dirinfo->currentcluster = volinfo->rootdir; - dirinfo->currentsector = 0; - dirinfo->currententry = 0; + // read first sector of directory + return DFS_ReadSector(volinfo->unit, + dirinfo->scratch, + volinfo->dataarea + + ((volinfo->rootdir - + 2) * volinfo->secperclus), + 1); +} + + else { +dirinfo->currentcluster = 0; +dirinfo->currentsector = 0; +dirinfo->currententry = 0; - // read first sector of directory - return DFS_ReadSector(volinfo->unit, dirinfo->scratch, volinfo->dataarea + ((volinfo->rootdir - 2) * volinfo->secperclus), 1); - } - else { - dirinfo->currentcluster = 0; - dirinfo->currentsector = 0; - dirinfo->currententry = 0; + // read first sector of directory + return DFS_ReadSector(volinfo->unit, + dirinfo->scratch, + volinfo->rootdir, 1); +} +} - // read first sector of directory - return DFS_ReadSector(volinfo->unit, dirinfo->scratch, volinfo->rootdir, 1); - } - } + // This is not the root directory. We need to find the start of this subdirectory. + // We do this by devious means, using our own companion function DFS_GetNext. + else { +unsigned char tmpfn[12]; +unsigned char *ptr = dirname; +unsigned long int result; +DIRENT de; +if (volinfo->filesystem == FAT32) { +dirinfo->currentcluster = volinfo->rootdir; +dirinfo->currentsector = 0; +dirinfo->currententry = 0; - // This is not the root directory. We need to find the start of this subdirectory. - // We do this by devious means, using our own companion function DFS_GetNext. - else { - unsigned char tmpfn[12]; - unsigned char *ptr = dirname; - unsigned long int result; - DIRENT de; + // read first sector of directory + if (DFS_ReadSector + (volinfo->unit, dirinfo->scratch, + volinfo->dataarea + + ((volinfo->rootdir - 2) * volinfo->secperclus), + 1)) +return DFS_ERRMISC; +} + + else { +dirinfo->currentcluster = 0; +dirinfo->currentsector = 0; +dirinfo->currententry = 0; - if (volinfo->filesystem == FAT32) { - dirinfo->currentcluster = volinfo->rootdir; - dirinfo->currentsector = 0; - dirinfo->currententry = 0; + // read first sector of directory + if (DFS_ReadSector + (volinfo->unit, dirinfo->scratch, + volinfo->rootdir, 1)) +return DFS_ERRMISC; +} - // read first sector of directory - if (DFS_ReadSector(volinfo->unit, dirinfo->scratch, volinfo->dataarea + ((volinfo->rootdir - 2) * volinfo->secperclus), 1)) - return DFS_ERRMISC; - } - else { - dirinfo->currentcluster = 0; - dirinfo->currentsector = 0; - dirinfo->currententry = 0; + // skip leading path separators + while (*ptr == DIR_SEPARATOR && *ptr) +ptr++; - // read first sector of directory - if (DFS_ReadSector(volinfo->unit, dirinfo->scratch, volinfo->rootdir, 1)) - return DFS_ERRMISC; - } + // Scan the path from left to right, finding the start cluster of each entry + // Observe that this code is inelegant, but obviates the need for recursion. + while (*ptr) { +DFS_CanonicalToDir(tmpfn, ptr); +de.name[0] = 0; - // skip leading path separators - while (*ptr == DIR_SEPARATOR && *ptr) - ptr++; + do { +result = DFS_GetNext(volinfo, dirinfo, &de); +} while (!result && memcmp2(de.name, tmpfn, 11)); +if (!memcmp2(de.name, tmpfn, 11) + && ((de.attr & ATTR_DIRECTORY) == + ATTR_DIRECTORY)) { +if (volinfo->filesystem == FAT32) { +dirinfo->currentcluster = + (unsigned long int)de. + startclus_l_l | +((unsigned long int)de. +((unsigned + long int) + de. + startclus_h_l) +((unsigned long int)de. + startclus_h_h) << 24; +} + + else { +dirinfo->currentcluster = + (unsigned long int)de. + startclus_l_l | +((unsigned long int)de. + startclus_l_h) << 8; +dirinfo->currentsector = 0; +dirinfo->currententry = 0; +if (DFS_ReadSector + (volinfo->unit, dirinfo->scratch, + volinfo->dataarea + + ((dirinfo->currentcluster - + 2) * volinfo->secperclus), 1)) +return DFS_ERRMISC; +} + + else if (!memcmp2(de.name, tmpfn, 11) + && !(de.attr & ATTR_DIRECTORY)) +return DFS_NOTFOUND; - // Scan the path from left to right, finding the start cluster of each entry - // Observe that this code is inelegant, but obviates the need for recursion. - while (*ptr) { - DFS_CanonicalToDir(tmpfn, ptr); + // seek to next item in list + while (*ptr != DIR_SEPARATOR && *ptr) +ptr++; +if (*ptr == DIR_SEPARATOR) +ptr++; +} +if (!dirinfo->currentcluster) +return DFS_NOTFOUND; +} +return DFS_OK; +} + - de.name[0] = 0; - - do { - result = DFS_GetNext(volinfo, dirinfo, &de); - } while (!result && memcmp2(de.name, tmpfn, 11)); - - if (!memcmp2(de.name, tmpfn, 11) && ((de.attr & ATTR_DIRECTORY) == ATTR_DIRECTORY)) { - if (volinfo->filesystem == FAT32) { - dirinfo->currentcluster = (unsigned long int) de.startclus_l_l | - ((unsigned long int) de.startclus_l_h) << 8 | - ((unsigned long int) de.startclus_h_l) << 16 | - ((unsigned long int) de.startclus_h_h) << 24; - } - else { - dirinfo->currentcluster = (unsigned long int) de.startclus_l_l | - ((unsigned long int) de.startclus_l_h) << 8; - } - dirinfo->currentsector = 0; - dirinfo->currententry = 0; - - if (DFS_ReadSector(volinfo->unit, dirinfo->scratch, volinfo->dataarea + ((dirinfo->currentcluster - 2) * volinfo->secperclus), 1)) - return DFS_ERRMISC; - } - else if (!memcmp2(de.name, tmpfn, 11) && !(de.attr & ATTR_DIRECTORY)) - return DFS_NOTFOUND; - - // seek to next item in list - while (*ptr != DIR_SEPARATOR && *ptr) - ptr++; - if (*ptr == DIR_SEPARATOR) - ptr++; - } - - if (!dirinfo->currentcluster) - return DFS_NOTFOUND; - } - return DFS_OK; -} - /* Get next entry in opened directory structure. Copies fields into the dirent structure, updates dirinfo. Note that it is the _caller's_ responsibility to @@ -753,78 +1256,138 @@ automatically. Long file name entries will be returned as NULL. returns DFS_EOF if there are no more entries, DFS_OK if this entry is valid, or DFS_ERRMISC for a media error -*/ -unsigned long int DFS_GetNext(PVOLINFO volinfo, PDIRINFO dirinfo, PDIRENT dirent) -{ - unsigned long int tempint; // required by DFS_GetFAT +*/ +unsigned long int DFS_GetNext(PVOLINFO volinfo, PDIRINFO dirinfo, + PDIRENT dirent) +{ +unsigned long int tempint; // required by DFS_GetFAT + + // Do we need to read the next sector of the directory? + if (dirinfo->currententry >= SECTOR_SIZE / sizeof(DIRENT)) { +dirinfo->currententry = 0; +dirinfo->currentsector++; - // Do we need to read the next sector of the directory? - if (dirinfo->currententry >= SECTOR_SIZE / sizeof(DIRENT)) { - dirinfo->currententry = 0; - dirinfo->currentsector++; + // Root directory; special case handling + // Note that currentcluster will only ever be zero if both: + // (a) this is the root directory, and + // (b) we are on a FAT12/16 volume, where the root dir can't be expanded + if (dirinfo->currentcluster == 0) { + + // Trying to read past end of root directory? + if (dirinfo->currentsector * + (SECTOR_SIZE / sizeof(DIRENT)) >= + volinfo->rootentries) +return DFS_EOF; - // Root directory; special case handling - // Note that currentcluster will only ever be zero if both: - // (a) this is the root directory, and - // (b) we are on a FAT12/16 volume, where the root dir can't be expanded - if (dirinfo->currentcluster == 0) { - // Trying to read past end of root directory? - if (dirinfo->currentsector * (SECTOR_SIZE / sizeof(DIRENT)) >= volinfo->rootentries) - return DFS_EOF; + // Otherwise try to read the next sector + if (DFS_ReadSector + (volinfo->unit, dirinfo->scratch, + volinfo->rootdir + dirinfo->currentsector, 1)) +return DFS_ERRMISC; +} - // Otherwise try to read the next sector - if (DFS_ReadSector(volinfo->unit, dirinfo->scratch, volinfo->rootdir + dirinfo->currentsector, 1)) - return DFS_ERRMISC; - } + // Normal handling + else { +if (dirinfo->currentsector >= volinfo->secperclus) { +dirinfo->currentsector = 0; +if ((dirinfo->currentcluster >= 0xff7 + && volinfo->filesystem == FAT12) +(dirinfo->currentcluster >= 0xfff7 + && volinfo->filesystem == FAT16) +(dirinfo->currentcluster >= 0x0ffffff7 + && volinfo->filesystem == FAT32)) { - // Normal handling - else { - if (dirinfo->currentsector >= volinfo->secperclus) { - dirinfo->currentsector = 0; - if ((dirinfo->currentcluster >= 0xff7 && volinfo->filesystem == FAT12) || - (dirinfo->currentcluster >= 0xfff7 && volinfo->filesystem == FAT16) || - (dirinfo->currentcluster >= 0x0ffffff7 && volinfo->filesystem == FAT32)) { - - // We are at the end of the directory chain. If this is a normal - // find operation, we should indicate that there is nothing more - // to see. - if (!(dirinfo->flags & DFS_DI_BLANKENT)) - return DFS_EOF; - - // On the other hand, if this is a "find free entry" search, - // we need to tell the caller to allocate a new cluster - else - return DFS_ALLOCNEW; - } - dirinfo->currentcluster = DFS_GetFAT(volinfo, dirinfo->scratch, &tempint, dirinfo->currentcluster); - } - if (DFS_ReadSector(volinfo->unit, dirinfo->scratch, volinfo->dataarea + ((dirinfo->currentcluster - 2) * volinfo->secperclus) + dirinfo->currentsector, 1)) - return DFS_ERRMISC; - } - } + // We are at the end of the directory chain. If this is a normal + // find operation, we should indicate that there is nothing more + // to see. + if (! + (dirinfo-> + flags & DFS_DI_BLANKENT)) +return DFS_EOF; - memcpy(dirent, &(((PDIRENT) dirinfo->scratch)[dirinfo->currententry]), sizeof(DIRENT)); - - if (dirent->name[0] == 0) { // no more files in this directory + // On the other hand, if this is a "find free entry" search, + // we need to tell the caller to allocate a new cluster + else +return DFS_ALLOCNEW; +} +dirinfo->currentcluster = + DFS_GetFAT(volinfo, dirinfo->scratch, + &tempint, + dirinfo->currentcluster); +} +if (DFS_ReadSector + (volinfo->unit, dirinfo->scratch, + volinfo->dataarea + + ((dirinfo->currentcluster - + 2) * volinfo->secperclus) + + dirinfo->currentsector, 1)) +return DFS_ERRMISC; +} +} +memcpy(dirent, &(((PDIRENT) dirinfo->scratch)[dirinfo->currententry]), + sizeof(DIRENT)); +if (dirent->name[0] == 0) { // no more files in this directory // If this is a "find blank" then we can reuse this name. - if (dirinfo->flags & DFS_DI_BLANKENT) - return DFS_OK; - else - return DFS_EOF; - } - - if (dirent->name[0] == 0xe5) // handle deleted file entries - dirent->name[0] = 0; - else if ((dirent->attr & ATTR_LONG_NAME) == ATTR_LONG_NAME) - dirent->name[0] = 0; + if (dirinfo->flags & DFS_DI_BLANKENT) +return DFS_OK; + + else +return DFS_EOF; +} +if (dirent->name[0] == 0xe5) // handle deleted file entries + dirent->name[0] = 0; + + else if ((dirent->attr & ATTR_LONG_NAME) == ATTR_LONG_NAME) +dirent->name[0] = 0; + else if (dirent->name[0] == 0x05) // handle kanji filenames beginning with 0xE5 - dirent->name[0] = 0xe5; + dirent->name[0] = 0xe5; +dirinfo->currententry++; +return DFS_OK; +} + - dirinfo->currententry++; - - return DFS_OK; -} - /* INTERNAL Find a free directory entry in the directory specified by path @@ -834,66 +1397,118 @@ de is a scratch structure Returns DFS_ERRMISC if a new entry could not be located or created de is updated with the same return information you would expect from DFS_GetNext -*/ -unsigned long int DFS_GetFreeDirEnt(PVOLINFO volinfo, unsigned char *path, PDIRINFO di, PDIRENT de) -{ - unsigned long int tempclus,i; +*/ +unsigned long int DFS_GetFreeDirEnt(PVOLINFO volinfo, unsigned char *path, + PDIRINFO di, PDIRENT de) +{ +unsigned long int tempclus, i; +if (DFS_OpenDir(volinfo, path, di)) +return DFS_NOTFOUND; - if (DFS_OpenDir(volinfo, path, di)) - return DFS_NOTFOUND; + // Set "search for empty" flag so DFS_GetNext knows what we're doing + di->flags |= DFS_DI_BLANKENT; - // Set "search for empty" flag so DFS_GetNext knows what we're doing - di->flags |= DFS_DI_BLANKENT; + // We seek through the directory looking for an empty entry + // Note we are reusing tempclus as a temporary result holder. + tempclus = 0; + + do { +tempclus = DFS_GetNext(volinfo, di, de); - // We seek through the directory looking for an empty entry - // Note we are reusing tempclus as a temporary result holder. - tempclus = 0; - do { - tempclus = DFS_GetNext(volinfo, di, de); + // Empty entry found + if (tempclus == DFS_OK && (!de->name[0])) { +return DFS_OK; +} - // Empty entry found - if (tempclus == DFS_OK && (!de->name[0])) { - return DFS_OK; - } + // End of root directory reached + else if (tempclus == DFS_EOF) +return DFS_ERRMISC; - // End of root directory reached - else if (tempclus == DFS_EOF) - return DFS_ERRMISC; + else if (tempclus == DFS_ALLOCNEW) { +tempclus = DFS_GetFreeFAT(volinfo, di->scratch); +if (tempclus == 0x0ffffff7) +return DFS_ERRMISC; + + // write out zeroed sectors to the new cluster + memset(di->scratch, 0, SECTOR_SIZE); +for (i = 0; i < volinfo->secperclus; i++) { +if (DFS_WriteSector + (volinfo->unit, di->scratch, + volinfo->dataarea + + ((tempclus - 2) * volinfo->secperclus) + + i, 1)) +return DFS_ERRMISC; +} - else if (tempclus == DFS_ALLOCNEW) { - tempclus = DFS_GetFreeFAT(volinfo, di->scratch); - if (tempclus == 0x0ffffff7) - return DFS_ERRMISC; + // Point old end cluster to newly allocated cluster + i = 0; +DFS_SetFAT(volinfo, di->scratch, &i, + di->currentcluster, tempclus); - // write out zeroed sectors to the new cluster - memset(di->scratch, 0, SECTOR_SIZE); - for (i=0;isecperclus;i++) { - if (DFS_WriteSector(volinfo->unit, di->scratch, volinfo->dataarea + ((tempclus - 2) * volinfo->secperclus) + i, 1)) - return DFS_ERRMISC; - } - // Point old end cluster to newly allocated cluster - i = 0; - DFS_SetFAT(volinfo, di->scratch, &i, di->currentcluster, tempclus); - - // Update DIRINFO so caller knows where to place the new file - di->currentcluster = tempclus; - di->currentsector = 0; - di->currententry = 1; // since the code coming after this expects to subtract 1 + // Update DIRINFO so caller knows where to place the new file + di->currentcluster = tempclus; +di->currentsector = 0; +di->currententry = 1; // since the code coming after this expects to subtract 1 - // Mark newly allocated cluster as end of chain - switch(volinfo->filesystem) { - case FAT12: tempclus = 0xff8; break; - case FAT16: tempclus = 0xfff8; break; - case FAT32: tempclus = 0x0ffffff8; break; - default: return DFS_ERRMISC; - } - DFS_SetFAT(volinfo, di->scratch, &i, di->currentcluster, tempclus); - } - } while (!tempclus); + // Mark newly allocated cluster as end of chain + switch (volinfo->filesystem) { +case FAT12: + tempclus = 0xff8; + break; +case FAT16: + tempclus = 0xfff8; + break; +case FAT32: + tempclus = 0x0ffffff8; + break; +default: + return DFS_ERRMISC; +} +DFS_SetFAT(volinfo, di->scratch, &i, + di->currentcluster, tempclus); +} +} while (!tempclus); - // We shouldn't get here - return DFS_ERRMISC; -} + // We shouldn't get here + return DFS_ERRMISC; +} + /* Open a file for reading or writing. You supply populated VOLINFO, a path to the file, @@ -901,164 +1516,301 @@ provide a pointer to a sector-sized scratch buffer. Returns various DFS_* error states. If the result is DFS_OK, fileinfo can be used to access the file from this point on. -*/ -unsigned long int DFS_OpenFile(PVOLINFO volinfo, unsigned char *path, unsigned char mode, unsigned char *scratch, PFILEINFO fileinfo) -{ - unsigned char tmppath[MAX_PATH]; - unsigned char filename[12]; - unsigned char *p; - DIRINFO di; - DIRENT de; +*/ +unsigned long int DFS_OpenFile(PVOLINFO volinfo, unsigned char *path, + unsigned char mode, unsigned char *scratch, + PFILEINFO fileinfo) +{ +unsigned char tmppath[MAX_PATH]; +unsigned char filename[12]; +unsigned char *p; +DIRINFO di; +DIRENT de; - // larwe 2006-09-16 +1 zero out file structure - memset(fileinfo, 0, sizeof(FILEINFO)); + // larwe 2006-09-16 +1 zero out file structure + memset(fileinfo, 0, sizeof(FILEINFO)); - // save access mode - fileinfo->mode = mode; + // save access mode + fileinfo->mode = mode; - // Get a local copy of the path. If it's longer than MAX_PATH, abort. - strcpy2((char *) tmppath, (char *) path); - tmppath[MAX_PATH - 1] = 0; - if (strcmp2((char *) path,(char *) tmppath)) { - return DFS_PATHLEN; - } + // Get a local copy of the path. If it's longer than MAX_PATH, abort. + strcpy2((char *)tmppath, (char *)path); +tmppath[MAX_PATH - 1] = 0; +if (strcmp2((char *)path, (char *)tmppath)) { +return DFS_PATHLEN; +} - - // strip leading path separators - while (tmppath[0] == DIR_SEPARATOR) - strcpy2((char *) tmppath, (char *) tmppath + 1); + // strip leading path separators + while (tmppath[0] == DIR_SEPARATOR) +strcpy2((char *)tmppath, (char *)tmppath + 1); - // Parse filename off the end of the supplied path - p = tmppath; - while (*(p++)); + // Parse filename off the end of the supplied path + p = tmppath; +while (*(p++)) ; +p--; +while (p > tmppath && *p != DIR_SEPARATOR) // larwe 9/16/06 ">=" to ">" bugfix + p--; +if (*p == DIR_SEPARATOR) +p++; +DFS_CanonicalToDir(filename, p); +if (p > tmppath) +p--; +if (*p == DIR_SEPARATOR || p == tmppath) // larwe 9/16/06 +"|| p == tmppath" bugfix + *p = 0; - p--; - while (p > tmppath && *p != DIR_SEPARATOR) // larwe 9/16/06 ">=" to ">" bugfix - p--; - if (*p == DIR_SEPARATOR) - p++; + // At this point, if our path was MYDIR/MYDIR2/FILE.EXT, filename = "FILE EXT" and + // tmppath = "MYDIR/MYDIR2". + di.scratch = scratch; +if (DFS_OpenDir(volinfo, tmppath, &di)) +return DFS_NOTFOUND; +while (!DFS_GetNext(volinfo, &di, &de)) { +if (!memcmp2(de.name, filename, 11)) { + + // You can't use this function call to open a directory. + if (de.attr & ATTR_DIRECTORY) +return DFS_NOTFOUND; +printf("get enxt \n"); +fileinfo->volinfo = volinfo; +fileinfo->pointer = 0; + + // The reason we store this extra info about the file is so that we can + // speedily update the file size, modification date, etc. on a file that is + // opened for writing. + if (di.currentcluster == 0) +fileinfo->dirsector = + volinfo->rootdir + di.currentsector; + + else +fileinfo->dirsector = + volinfo->dataarea + + ((di.currentcluster - + 2) * volinfo->secperclus) + + di.currentsector; +fileinfo->diroffset = di.currententry - 1; +if (volinfo->filesystem == FAT32) { +fileinfo->cluster = + (unsigned long int)de. +((unsigned long int)de. + startclus_l_h) << 8 | +((unsigned long int)de. +((unsigned long + int)de. + startclus_h_h) << + 24; +} + + else { +fileinfo->cluster = + (unsigned long int)de. +((unsigned long int)de. + startclus_l_h) << 8; +fileinfo->firstcluster = fileinfo->cluster; +fileinfo->filelen = + (unsigned long int)de. +((unsigned long int)de. +((unsigned long + int)de. + filesize_2) << +((unsigned long int)de.filesize_3) << 24; +return DFS_OK; +} +} - DFS_CanonicalToDir(filename, p); + // At this point, we KNOW the file does not exist. If the file was opened + // with write access, we can create it. + if (mode & DFS_WRITE) { +unsigned long int cluster, temp; - if (p > tmppath) - p--; - if (*p == DIR_SEPARATOR || p == tmppath) // larwe 9/16/06 +"|| p == tmppath" bugfix - *p = 0; + // Locate or create a directory entry for this file + if (DFS_OK != DFS_GetFreeDirEnt(volinfo, tmppath, &di, &de)) +return DFS_ERRMISC; - // At this point, if our path was MYDIR/MYDIR2/FILE.EXT, filename = "FILE EXT" and - // tmppath = "MYDIR/MYDIR2". - di.scratch = scratch; - if (DFS_OpenDir(volinfo, tmppath, &di)) - return DFS_NOTFOUND; + // put sane values in the directory entry + memset(&de, 0, sizeof(de)); +memcpy(de.name, filename, 11); +de.crttime_l = 0x20; // 01:01:00am, Jan 1, 2006. + de.crttime_h = 0x08; +de.crtdate_l = 0x11; +de.crtdate_h = 0x34; +de.lstaccdate_l = 0x11; +de.lstaccdate_h = 0x34; +de.wrttime_l = 0x20; +de.wrttime_h = 0x08; +de.wrtdate_l = 0x11; +de.wrtdate_h = 0x34; - while (!DFS_GetNext(volinfo, &di, &de)) { - - if (!memcmp2(de.name, filename, 11)) { - // You can't use this function call to open a directory. - if (de.attr & ATTR_DIRECTORY) - return DFS_NOTFOUND; - printf("get enxt \n"); - fileinfo->volinfo = volinfo; - fileinfo->pointer = 0; - // The reason we store this extra info about the file is so that we can - // speedily update the file size, modification date, etc. on a file that is - // opened for writing. - if (di.currentcluster == 0) - fileinfo->dirsector = volinfo->rootdir + di.currentsector; - else - fileinfo->dirsector = volinfo->dataarea + ((di.currentcluster - 2) * volinfo->secperclus) + di.currentsector; - fileinfo->diroffset = di.currententry - 1; - if (volinfo->filesystem == FAT32) { - fileinfo->cluster = (unsigned long int) de.startclus_l_l | - ((unsigned long int) de.startclus_l_h) << 8 | - ((unsigned long int) de.startclus_h_l) << 16 | - ((unsigned long int) de.startclus_h_h) << 24; - } - else { - fileinfo->cluster = (unsigned long int) de.startclus_l_l | - ((unsigned long int) de.startclus_l_h) << 8; - } - fileinfo->firstcluster = fileinfo->cluster; - fileinfo->filelen = (unsigned long int) de.filesize_0 | - ((unsigned long int) de.filesize_1) << 8 | - ((unsigned long int) de.filesize_2) << 16 | - ((unsigned long int) de.filesize_3) << 24; + // allocate a starting cluster for the directory entry + cluster = DFS_GetFreeFAT(volinfo, scratch); +de.startclus_l_l = cluster & 0xff; +de.startclus_l_h = (cluster & 0xff00) >> 8; +de.startclus_h_l = (cluster & 0xff0000) >> 16; +de.startclus_h_h = (cluster & 0xff000000) >> 24; - return DFS_OK; - } - } - - // At this point, we KNOW the file does not exist. If the file was opened - // with write access, we can create it. - if (mode & DFS_WRITE) { - unsigned long int cluster, temp; - - // Locate or create a directory entry for this file - if (DFS_OK != DFS_GetFreeDirEnt(volinfo, tmppath, &di, &de)) - return DFS_ERRMISC; - - // put sane values in the directory entry - memset(&de, 0, sizeof(de)); - memcpy(de.name, filename, 11); - de.crttime_l = 0x20; // 01:01:00am, Jan 1, 2006. - de.crttime_h = 0x08; - de.crtdate_l = 0x11; - de.crtdate_h = 0x34; - de.lstaccdate_l = 0x11; - de.lstaccdate_h = 0x34; - de.wrttime_l = 0x20; - de.wrttime_h = 0x08; - de.wrtdate_l = 0x11; - de.wrtdate_h = 0x34; - - // allocate a starting cluster for the directory entry - cluster = DFS_GetFreeFAT(volinfo, scratch); - - de.startclus_l_l = cluster & 0xff; - de.startclus_l_h = (cluster & 0xff00) >> 8; - de.startclus_h_l = (cluster & 0xff0000) >> 16; - de.startclus_h_h = (cluster & 0xff000000) >> 24; - - // update FILEINFO for our caller's sake - fileinfo->volinfo = volinfo; - fileinfo->pointer = 0; - // The reason we store this extra info about the file is so that we can - // speedily update the file size, modification date, etc. on a file that is - // opened for writing. - if (di.currentcluster == 0) - fileinfo->dirsector = volinfo->rootdir + di.currentsector; - else - fileinfo->dirsector = volinfo->dataarea + ((di.currentcluster - 2) * volinfo->secperclus) + di.currentsector; - fileinfo->diroffset = di.currententry - 1; - fileinfo->cluster = cluster; - fileinfo->firstcluster = cluster; - fileinfo->filelen = 0; + // update FILEINFO for our caller's sake + fileinfo->volinfo = volinfo; +fileinfo->pointer = 0; - // write the directory entry - // note that we no longer have the sector containing the directory entry, - // tragically, so we have to re-read it - if (DFS_ReadSector(volinfo->unit, scratch, fileinfo->dirsector, 1)) - return DFS_ERRMISC; - memcpy(&(((PDIRENT) scratch)[di.currententry-1]), &de, sizeof(DIRENT)); - if (DFS_WriteSector(volinfo->unit, scratch, fileinfo->dirsector, 1)) - return DFS_ERRMISC; + // The reason we store this extra info about the file is so that we can + // speedily update the file size, modification date, etc. on a file that is + // opened for writing. + if (di.currentcluster == 0) +fileinfo->dirsector = + volinfo->rootdir + di.currentsector; + + else +fileinfo->dirsector = + volinfo->dataarea + + ((di.currentcluster - 2) * volinfo->secperclus) + + di.currentsector; +fileinfo->diroffset = di.currententry - 1; +fileinfo->cluster = cluster; +fileinfo->firstcluster = cluster; +fileinfo->filelen = 0; - // Mark newly allocated cluster as end of chain - switch(volinfo->filesystem) { - case FAT12: cluster = 0xff8; break; - case FAT16: cluster = 0xfff8; break; - case FAT32: cluster = 0x0ffffff8; break; - default: return DFS_ERRMISC; - } - temp = 0; - DFS_SetFAT(volinfo, scratch, &temp, fileinfo->cluster, cluster); + // write the directory entry + // note that we no longer have the sector containing the directory entry, + // tragically, so we have to re-read it + if (DFS_ReadSector + (volinfo->unit, scratch, fileinfo->dirsector, 1)) +return DFS_ERRMISC; +memcpy(&(((PDIRENT) scratch)[di.currententry - 1]), &de, + sizeof(DIRENT)); +if (DFS_WriteSector + (volinfo->unit, scratch, fileinfo->dirsector, 1)) +return DFS_ERRMISC; - return DFS_OK; - } + // Mark newly allocated cluster as end of chain + switch (volinfo->filesystem) { +case FAT12: + cluster = 0xff8; + break; +case FAT16: + cluster = 0xfff8; + break; +case FAT32: + cluster = 0x0ffffff8; + break; +default: + return DFS_ERRMISC; +} +temp = 0; +DFS_SetFAT(volinfo, scratch, &temp, fileinfo->cluster, + cluster); +return DFS_OK; +} +return DFS_NOTFOUND; +} + - return DFS_NOTFOUND; -} - /* Read an open file You must supply a prepopulated FILEINFO as provided by DFS_OpenFile, and a @@ -1065,122 +1817,212 @@ pointer to a SECTOR_SIZE scratch buffer. Note that returning DFS_EOF is not an error condition. This function updates the successcount field with the number of bytes actually read. -*/ -unsigned long int DFS_ReadFile(PFILEINFO fileinfo, unsigned char *scratch, unsigned char *buffer, unsigned long int *successcount, unsigned long int len) -{ - unsigned long int remain; - unsigned long int result = DFS_OK; - unsigned long int sector; - unsigned long int bytesread; - - // Don't try to read past EOF - if (len > fileinfo->filelen - fileinfo->pointer) - len = fileinfo->filelen - fileinfo->pointer; +*/ +unsigned long int DFS_ReadFile(PFILEINFO fileinfo, unsigned char *scratch, + unsigned char *buffer, + unsigned long int *successcount, + unsigned long int len) +{ +unsigned long int remain; +unsigned long int result = DFS_OK; +unsigned long int sector; +unsigned long int bytesread; - remain = len; - *successcount = 0; + // Don't try to read past EOF + if (len > fileinfo->filelen - fileinfo->pointer) +len = fileinfo->filelen - fileinfo->pointer; +remain = len; +*successcount = 0; +while (remain && result == DFS_OK) { + + // This is a bit complicated. The sector we want to read is addressed at a cluster + // granularity by the fileinfo->cluster member. The file pointer tells us how many + // extra sectors to add to that number. + sector = fileinfo->volinfo->dataarea + + ((fileinfo->cluster - 2) * fileinfo->volinfo->secperclus) + +div(div + (fileinfo->pointer, + fileinfo->volinfo->secperclus * SECTOR_SIZE).rem, + SECTOR_SIZE).quot; - while (remain && result == DFS_OK) { - // This is a bit complicated. The sector we want to read is addressed at a cluster - // granularity by the fileinfo->cluster member. The file pointer tells us how many - // extra sectors to add to that number. - sector = fileinfo->volinfo->dataarea + - ((fileinfo->cluster - 2) * fileinfo->volinfo->secperclus) + - div(div(fileinfo->pointer,fileinfo->volinfo->secperclus * SECTOR_SIZE).rem, SECTOR_SIZE).quot; + // Case 1 - File pointer is not on a sector boundary + if (div(fileinfo->pointer, SECTOR_SIZE).rem) { +unsigned short tempreadsize; - // Case 1 - File pointer is not on a sector boundary - if (div(fileinfo->pointer, SECTOR_SIZE).rem) { - - unsigned short tempreadsize; - - - // We always have to go through scratch in this case - result = DFS_ReadSector(fileinfo->volinfo->unit, scratch, sector, 1); + // We always have to go through scratch in this case + result = + DFS_ReadSector(fileinfo->volinfo->unit, scratch, + sector, 1); - // This is the number of bytes that we actually care about in the sector - // just read. - - tempreadsize = SECTOR_SIZE - (div(fileinfo->pointer, SECTOR_SIZE).rem); - + // This is the number of bytes that we actually care about in the sector + // just read. +tempreadsize = + SECTOR_SIZE - + (div(fileinfo->pointer, SECTOR_SIZE).rem); + + // Case 1A - We want the entire remainder of the sector. After this + // point, all passes through the read loop will be aligned on a sector + // boundary, which allows us to go through the optimal path 2A below. + if (remain >= tempreadsize) { +memcpy(buffer, + scratch + (SECTOR_SIZE - tempreadsize), + tempreadsize); +bytesread = tempreadsize; +buffer += tempreadsize; +fileinfo->pointer += tempreadsize; +remain -= tempreadsize; +} - // Case 1A - We want the entire remainder of the sector. After this - // point, all passes through the read loop will be aligned on a sector - // boundary, which allows us to go through the optimal path 2A below. - if (remain >= tempreadsize) { - memcpy(buffer, scratch + (SECTOR_SIZE - tempreadsize), tempreadsize); - bytesread = tempreadsize; - buffer += tempreadsize; - fileinfo->pointer += tempreadsize; - remain -= tempreadsize; - } - // Case 1B - This read concludes the file read operation - else { - memcpy(buffer, scratch + (SECTOR_SIZE - tempreadsize), remain); + // Case 1B - This read concludes the file read operation + else { +memcpy(buffer, + scratch + (SECTOR_SIZE - tempreadsize), + remain); +buffer += remain; +fileinfo->pointer += remain; +bytesread = remain; +remain = 0; +} +} + + // Case 2 - File pointer is on sector boundary + else { - buffer += remain; - fileinfo->pointer += remain; - bytesread = remain; - remain = 0; - } - } - // Case 2 - File pointer is on sector boundary - else { - - // Case 2A - We have at least one more full sector to read and don't have - // to go through the scratch buffer. You could insert optimizations here to - // read multiple sectors at a time, if you were thus inclined (note that - // the maximum multi-read you could perform is a single cluster, so it would - // be advantageous to have code similar to case 1A above that would round the - // pointer to a cluster boundary the first pass through, so all subsequent - // [large] read requests would be able to go a cluster at a time). - if (remain >= SECTOR_SIZE) { - - result = DFS_ReadSector(fileinfo->volinfo->unit, buffer, sector, 1); + // Case 2A - We have at least one more full sector to read and don't have + // to go through the scratch buffer. You could insert optimizations here to + // read multiple sectors at a time, if you were thus inclined (note that + // the maximum multi-read you could perform is a single cluster, so it would + // be advantageous to have code similar to case 1A above that would round the + // pointer to a cluster boundary the first pass through, so all subsequent + // [large] read requests would be able to go a cluster at a time). + if (remain >= SECTOR_SIZE) { +result = + DFS_ReadSector(fileinfo->volinfo->unit, + buffer, sector, 1); +remain -= SECTOR_SIZE; +buffer += SECTOR_SIZE; +fileinfo->pointer += SECTOR_SIZE; +bytesread = SECTOR_SIZE; +} - remain -= SECTOR_SIZE; - - buffer += SECTOR_SIZE; - - fileinfo->pointer += SECTOR_SIZE; - - bytesread = SECTOR_SIZE; - - } - // Case 2B - We are only reading a partial sector - else { - - result = DFS_ReadSector(fileinfo->volinfo->unit, scratch, sector, 1); - memcpy(buffer, scratch, remain); - buffer += remain; - fileinfo->pointer += remain; - bytesread = remain; - remain = 0; - } - } + // Case 2B - We are only reading a partial sector + else { +result = + DFS_ReadSector(fileinfo->volinfo->unit, + scratch, sector, 1); +memcpy(buffer, scratch, remain); +buffer += remain; +fileinfo->pointer += remain; +bytesread = remain; +remain = 0; +} +} +*successcount += bytesread; - *successcount += bytesread; - - - // check to see if we stepped over a cluster boundary - if (div(fileinfo->pointer - bytesread, fileinfo->volinfo->secperclus * SECTOR_SIZE).quot != - div(fileinfo->pointer, fileinfo->volinfo->secperclus * SECTOR_SIZE).quot) { - // An act of minor evil - we use bytesread as a scratch integer, knowing that - // its value is not used after updating *successcount above + // check to see if we stepped over a cluster boundary + if (div + (fileinfo->pointer - bytesread, + fileinfo->volinfo->secperclus * SECTOR_SIZE).quot != +div(fileinfo->pointer, + fileinfo->volinfo->secperclus * + SECTOR_SIZE).quot) { - bytesread = 0; - - if (((fileinfo->volinfo->filesystem == FAT12) && (fileinfo->cluster >= 0xff8)) || - ((fileinfo->volinfo->filesystem == FAT16) && (fileinfo->cluster >= 0xfff8)) || - ((fileinfo->volinfo->filesystem == FAT32) && (fileinfo->cluster >= 0x0ffffff8))) - result = DFS_EOF; - else - fileinfo->cluster = DFS_GetFAT(fileinfo->volinfo, scratch, &bytesread, fileinfo->cluster); - } - } - - - return result; -} + // An act of minor evil - we use bytesread as a scratch integer, knowing that + // its value is not used after updating *successcount above +bytesread = 0; +if (((fileinfo->volinfo->filesystem == FAT12) + && (fileinfo->cluster >= 0xff8)) +((fileinfo->volinfo->filesystem == FAT16) + && (fileinfo->cluster >= 0xfff8)) +((fileinfo->volinfo->filesystem == FAT32) + && (fileinfo->cluster >= 0x0ffffff8))) +result = DFS_EOF; + + else +fileinfo->cluster = + DFS_GetFAT(fileinfo->volinfo, scratch, + &bytesread, fileinfo->cluster); +} +} +return result; +} + /* Seek file pointer to a given position @@ -1187,306 +2029,574 @@ This function does not return status - refer to the fileinfo->pointer value to see where the pointer wound up. Requires a SECTOR_SIZE scratch buffer -*/ -void DFS_Seek(PFILEINFO fileinfo, unsigned long int offset, unsigned char *scratch) -{ - unsigned long int tempint; +*/ +void DFS_Seek(PFILEINFO fileinfo, unsigned long int offset, + unsigned char *scratch) +{ +unsigned long int tempint; - // larwe 9/16/06 bugfix split case 0a/0b and changed fallthrough handling - // Case 0a - Return immediately for degenerate case - if (offset == fileinfo->pointer) { - return; - } - - // Case 0b - Don't allow the user to seek past the end of the file - if (offset > fileinfo->filelen) { - offset = fileinfo->filelen; - // NOTE NO RETURN HERE! - } + // larwe 9/16/06 bugfix split case 0a/0b and changed fallthrough handling + // Case 0a - Return immediately for degenerate case + if (offset == fileinfo->pointer) { +return; +} - // Case 1 - Simple rewind to start - // Note _intentional_ fallthrough from Case 0b above - if (offset == 0) { - fileinfo->cluster = fileinfo->firstcluster; - fileinfo->pointer = 0; - return; // larwe 9/16/06 +1 bugfix - } - // Case 2 - Seeking backwards. Need to reset and seek forwards - else if (offset < fileinfo->pointer) { - fileinfo->cluster = fileinfo->firstcluster; - fileinfo->pointer = 0; - // NOTE NO RETURN HERE! - } + // Case 0b - Don't allow the user to seek past the end of the file + if (offset > fileinfo->filelen) { +offset = fileinfo->filelen; + + // NOTE NO RETURN HERE! + } - // Case 3 - Seeking forwards - // Note _intentional_ fallthrough from Case 2 above + // Case 1 - Simple rewind to start + // Note _intentional_ fallthrough from Case 0b above + if (offset == 0) { +fileinfo->cluster = fileinfo->firstcluster; +fileinfo->pointer = 0; +return; // larwe 9/16/06 +1 bugfix + } + + // Case 2 - Seeking backwards. Need to reset and seek forwards + else if (offset < fileinfo->pointer) { +fileinfo->cluster = fileinfo->firstcluster; +fileinfo->pointer = 0; + + // NOTE NO RETURN HERE! + } - // Case 3a - Seek size does not cross cluster boundary - - // very simple case - // larwe 9/16/06 changed .rem to .quot in both div calls, bugfix - if (div(fileinfo->pointer, fileinfo->volinfo->secperclus * SECTOR_SIZE).quot == - div(fileinfo->pointer + offset, fileinfo->volinfo->secperclus * SECTOR_SIZE).quot) { - fileinfo->pointer = offset; - } - // Case 3b - Seeking across cluster boundary(ies) - else { - // round file pointer down to cluster boundary - fileinfo->pointer = div(fileinfo->pointer, fileinfo->volinfo->secperclus * SECTOR_SIZE).quot * - fileinfo->volinfo->secperclus * SECTOR_SIZE; + // Case 3 - Seeking forwards + // Note _intentional_ fallthrough from Case 2 above + + // Case 3a - Seek size does not cross cluster boundary - + // very simple case + // larwe 9/16/06 changed .rem to .quot in both div calls, bugfix + if (div + (fileinfo->pointer, + fileinfo->volinfo->secperclus * SECTOR_SIZE).quot == +div(fileinfo->pointer + offset, + fileinfo->volinfo->secperclus * SECTOR_SIZE).quot) { +fileinfo->pointer = offset; +} + + // Case 3b - Seeking across cluster boundary(ies) + else { + + // round file pointer down to cluster boundary + fileinfo->pointer = + div(fileinfo->pointer, + fileinfo->volinfo->secperclus * SECTOR_SIZE).quot * +fileinfo->volinfo->secperclus * SECTOR_SIZE; - // seek by clusters - // larwe 9/30/06 bugfix changed .rem to .quot in both div calls - while (div(fileinfo->pointer, fileinfo->volinfo->secperclus * SECTOR_SIZE).quot != - div(fileinfo->pointer + offset, fileinfo->volinfo->secperclus * SECTOR_SIZE).quot) { + // seek by clusters + // larwe 9/30/06 bugfix changed .rem to .quot in both div calls + while (div + (fileinfo->pointer, + fileinfo->volinfo->secperclus * SECTOR_SIZE).quot != +div(fileinfo->pointer + offset, + fileinfo->volinfo->secperclus * + SECTOR_SIZE).quot) { +fileinfo->cluster = + DFS_GetFAT(fileinfo->volinfo, scratch, &tempint, + fileinfo->cluster); + + // Abort if there was an error + if (fileinfo->cluster == 0x0ffffff7) { +fileinfo->pointer = 0; +fileinfo->cluster = fileinfo->firstcluster; +return; +} +fileinfo->pointer += + SECTOR_SIZE * fileinfo->volinfo->secperclus; +} - fileinfo->cluster = DFS_GetFAT(fileinfo->volinfo, scratch, &tempint, fileinfo->cluster); - // Abort if there was an error - if (fileinfo->cluster == 0x0ffffff7) { - fileinfo->pointer = 0; - fileinfo->cluster = fileinfo->firstcluster; - return; - } - fileinfo->pointer += SECTOR_SIZE * fileinfo->volinfo->secperclus; - } + // since we know the cluster is right, we have no more work to do + fileinfo->pointer = offset; +} +} + - // since we know the cluster is right, we have no more work to do - fileinfo->pointer = offset; - } -} - /* Delete a file scratch must point to a sector-sized buffer -*/ -unsigned long int DFS_UnlinkFile(PVOLINFO volinfo, unsigned char *path, unsigned char *scratch) -{ - PDIRENT de = (PDIRENT) scratch; - FILEINFO fi; - unsigned long int cache = 0; - unsigned long int tempclus; +*/ +unsigned long int DFS_UnlinkFile(PVOLINFO volinfo, unsigned char *path, + unsigned char *scratch) +{ +PDIRENT de = (PDIRENT) scratch; +FILEINFO fi; +unsigned long int cache = 0; +unsigned long int tempclus; - // DFS_OpenFile gives us all the information we need to delete it - if (DFS_OK != DFS_OpenFile(volinfo, path, DFS_READ, scratch, &fi)) - return DFS_NOTFOUND; + // DFS_OpenFile gives us all the information we need to delete it + if (DFS_OK != DFS_OpenFile(volinfo, path, DFS_READ, scratch, &fi)) +return DFS_NOTFOUND; - // First, read the directory sector and delete that entry - if (DFS_ReadSector(volinfo->unit, scratch, fi.dirsector, 1)) - return DFS_ERRMISC; - ((PDIRENT) scratch)[fi.diroffset].name[0] = 0xe5; - if (DFS_WriteSector(volinfo->unit, scratch, fi.dirsector, 1)) - return DFS_ERRMISC; + // First, read the directory sector and delete that entry + if (DFS_ReadSector(volinfo->unit, scratch, fi.dirsector, 1)) +return DFS_ERRMISC; +((PDIRENT) scratch)[fi.diroffset].name[0] = 0xe5; +if (DFS_WriteSector(volinfo->unit, scratch, fi.dirsector, 1)) +return DFS_ERRMISC; - // Now follow the cluster chain to free the file space - while (!((volinfo->filesystem == FAT12 && fi.firstcluster >= 0x0ff7) || - (volinfo->filesystem == FAT16 && fi.firstcluster >= 0xfff7) || - (volinfo->filesystem == FAT32 && fi.firstcluster >= 0x0ffffff7))) { - tempclus = fi.firstcluster; + // Now follow the cluster chain to free the file space + while (! + ((volinfo->filesystem == FAT12 && fi.firstcluster >= 0x0ff7) +(volinfo->filesystem == FAT16 + && fi.firstcluster >= 0xfff7) +(volinfo->filesystem == FAT32 + && fi.firstcluster >= 0x0ffffff7))) { +tempclus = fi.firstcluster; +fi.firstcluster = + DFS_GetFAT(volinfo, scratch, &cache, fi.firstcluster); +DFS_SetFAT(volinfo, scratch, &cache, tempclus, 0); +} +return DFS_OK; +} + - fi.firstcluster = DFS_GetFAT(volinfo, scratch, &cache, fi.firstcluster); - DFS_SetFAT(volinfo, scratch, &cache, tempclus, 0); - - } - return DFS_OK; -} - - /* Write an open file You must supply a prepopulated FILEINFO as provided by DFS_OpenFile, and a pointer to a SECTOR_SIZE scratch buffer. This function updates the successcount field with the number of bytes actually written. -*/ -unsigned long int DFS_WriteFile(PFILEINFO fileinfo, unsigned char *scratch, unsigned char *buffer, unsigned long int *successcount, unsigned long int len) -{ - unsigned long int remain; - unsigned long int result = DFS_OK; - unsigned long int sector; - unsigned long int byteswritten; +*/ +unsigned long int DFS_WriteFile(PFILEINFO fileinfo, unsigned char *scratch, + unsigned char *buffer, + unsigned long int *successcount, + unsigned long int len) +{ +unsigned long int remain; +unsigned long int result = DFS_OK; +unsigned long int sector; +unsigned long int byteswritten; - // Don't allow writes to a file that's open as readonly - if (!(fileinfo->mode & DFS_WRITE)) - return DFS_ERRMISC; + // Don't allow writes to a file that's open as readonly + if (!(fileinfo->mode & DFS_WRITE)) +return DFS_ERRMISC; +remain = len; +*successcount = 0; +while (remain && result == DFS_OK) { + + // This is a bit complicated. The sector we want to read is addressed at a cluster + // granularity by the fileinfo->cluster member. The file pointer tells us how many + // extra sectors to add to that number. + sector = fileinfo->volinfo->dataarea + + ((fileinfo->cluster - 2) * fileinfo->volinfo->secperclus) + +div(div + (fileinfo->pointer, + fileinfo->volinfo->secperclus * SECTOR_SIZE).rem, + SECTOR_SIZE).quot; - remain = len; - *successcount = 0; + // Case 1 - File pointer is not on a sector boundary + if (div(fileinfo->pointer, SECTOR_SIZE).rem) { +unsigned short tempsize; +printf("CASE 1 \n"); + + // We always have to go through scratch in this case + result = + DFS_ReadSector(fileinfo->volinfo->unit, scratch, + sector, 1); - while (remain && result == DFS_OK) { - // This is a bit complicated. The sector we want to read is addressed at a cluster - // granularity by the fileinfo->cluster member. The file pointer tells us how many - // extra sectors to add to that number. - sector = fileinfo->volinfo->dataarea + - ((fileinfo->cluster - 2) * fileinfo->volinfo->secperclus) + - div(div(fileinfo->pointer,fileinfo->volinfo->secperclus * SECTOR_SIZE).rem, SECTOR_SIZE).quot; + // This is the number of bytes that we don't want to molest in the + // scratch sector just read. + tempsize = div(fileinfo->pointer, SECTOR_SIZE).rem; - // Case 1 - File pointer is not on a sector boundary - if (div(fileinfo->pointer, SECTOR_SIZE).rem) { - unsigned short tempsize; - printf("CASE 1 \n"); - // We always have to go through scratch in this case - result = DFS_ReadSector(fileinfo->volinfo->unit, scratch, sector, 1); - - // This is the number of bytes that we don't want to molest in the - // scratch sector just read. - tempsize = div(fileinfo->pointer, SECTOR_SIZE).rem; - - // Case 1A - We are writing the entire remainder of the sector. After - // this point, all passes through the read loop will be aligned on a - // sector boundary, which allows us to go through the optimal path - // 2A below. - if (remain >= SECTOR_SIZE - tempsize) { - memcpy(scratch + tempsize, buffer, SECTOR_SIZE - tempsize); - if (!result) - result = DFS_WriteSector(fileinfo->volinfo->unit, scratch, sector, 1); - - byteswritten = SECTOR_SIZE - tempsize; - buffer += SECTOR_SIZE - tempsize; - fileinfo->pointer += SECTOR_SIZE - tempsize; - if (fileinfo->filelen < fileinfo->pointer) { - fileinfo->filelen = fileinfo->pointer; - } - remain -= SECTOR_SIZE - tempsize; - } - // Case 1B - This concludes the file write operation - else { - printf("CASE 1B \n"); - memcpy(scratch + tempsize, buffer, remain); - if (!result) - result = DFS_WriteSector(fileinfo->volinfo->unit, scratch, sector, 1); - - buffer += remain; - fileinfo->pointer += remain; - if (fileinfo->filelen < fileinfo->pointer) { - fileinfo->filelen = fileinfo->pointer; - } - byteswritten = remain; - remain = 0; - } - } // case 1 + // Case 1A - We are writing the entire remainder of the sector. After + // this point, all passes through the read loop will be aligned on a + // sector boundary, which allows us to go through the optimal path + // 2A below. + if (remain >= SECTOR_SIZE - tempsize) { +memcpy(scratch + tempsize, buffer, + SECTOR_SIZE - tempsize); +if (!result) +result = + DFS_WriteSector(fileinfo->volinfo-> + unit, scratch, + sector, 1); +byteswritten = SECTOR_SIZE - tempsize; +buffer += SECTOR_SIZE - tempsize; +fileinfo->pointer += SECTOR_SIZE - tempsize; +if (fileinfo->filelen < fileinfo->pointer) { +fileinfo->filelen = fileinfo->pointer; +} +remain -= SECTOR_SIZE - tempsize; +} + + // Case 1B - This concludes the file write operation + else { +printf("CASE 1B \n"); +memcpy(scratch + tempsize, buffer, remain); +if (!result) +result = + DFS_WriteSector(fileinfo->volinfo-> + unit, scratch, + sector, 1); +buffer += remain; +fileinfo->pointer += remain; +if (fileinfo->filelen < fileinfo->pointer) { +fileinfo->filelen = fileinfo->pointer; +} +byteswritten = remain; +remain = 0; +} +} // case 1 // Case 2 - File pointer is on sector boundary - else { - printf("CASE 2 \n"); - // Case 2A - We have at least one more full sector to write and don't have - // to go through the scratch buffer. You could insert optimizations here to - // write multiple sectors at a time, if you were thus inclined. Refer to - // similar notes in DFS_ReadFile. - if (remain >= SECTOR_SIZE) { - result = DFS_WriteSector(fileinfo->volinfo->unit, buffer, sector, 1); - remain -= SECTOR_SIZE; - buffer += SECTOR_SIZE; - fileinfo->pointer += SECTOR_SIZE; - if (fileinfo->filelen < fileinfo->pointer) { - fileinfo->filelen = fileinfo->pointer; - } - byteswritten = SECTOR_SIZE; - } - // Case 2B - We are only writing a partial sector and potentially need to - // go through the scratch buffer. - else { - printf("CASE 2B \n"); - // If the current file pointer is not yet at or beyond the file - // length, we are writing somewhere in the middle of the file and - // need to load the original sector to do a read-modify-write. - if (fileinfo->pointer < fileinfo->filelen) { - result = DFS_ReadSector(fileinfo->volinfo->unit, scratch, sector, 1); - if (!result) { - memcpy(scratch, buffer, remain); - result = DFS_WriteSector(fileinfo->volinfo->unit, scratch, sector, 1); - } - } - else { - result = DFS_WriteSector(fileinfo->volinfo->unit, buffer, sector, 1); - } + else { +printf("CASE 2 \n"); + + // Case 2A - We have at least one more full sector to write and don't have + // to go through the scratch buffer. You could insert optimizations here to + // write multiple sectors at a time, if you were thus inclined. Refer to + // similar notes in DFS_ReadFile. + if (remain >= SECTOR_SIZE) { +result = + DFS_WriteSector(fileinfo->volinfo->unit, + buffer, sector, 1); +remain -= SECTOR_SIZE; +buffer += SECTOR_SIZE; +fileinfo->pointer += SECTOR_SIZE; +if (fileinfo->filelen < fileinfo->pointer) { +fileinfo->filelen = fileinfo->pointer; +} +byteswritten = SECTOR_SIZE; +} + + // Case 2B - We are only writing a partial sector and potentially need to + // go through the scratch buffer. + else { +printf("CASE 2B \n"); + + // If the current file pointer is not yet at or beyond the file + // length, we are writing somewhere in the middle of the file and + // need to load the original sector to do a read-modify-write. + if (fileinfo->pointer < fileinfo->filelen) { +result = + DFS_ReadSector(fileinfo->volinfo-> + unit, scratch, + sector, 1); +if (!result) { +memcpy(scratch, buffer, + remain); +result = + DFS_WriteSector(fileinfo-> + volinfo-> + unit, + scratch, + sector, 1); +} +} + + else { +result = + DFS_WriteSector(fileinfo->volinfo-> + unit, buffer, + sector, 1); +} +buffer += remain; +fileinfo->pointer += remain; +if (fileinfo->filelen < fileinfo->pointer) { +fileinfo->filelen = fileinfo->pointer; +} +byteswritten = remain; +remain = 0; +} +} +*successcount += byteswritten; +printf("Writen byte %d \n", *successcount); + + // check to see if we stepped over a cluster boundary + if (div + (fileinfo->pointer - byteswritten, + fileinfo->volinfo->secperclus * SECTOR_SIZE).quot != +div(fileinfo->pointer, + fileinfo->volinfo->secperclus * + SECTOR_SIZE).quot) { +unsigned long int lastcluster; - buffer += remain; - fileinfo->pointer += remain; - if (fileinfo->filelen < fileinfo->pointer) { - fileinfo->filelen = fileinfo->pointer; - } - byteswritten = remain; - remain = 0; - } - } + // We've transgressed into another cluster. If we were already at EOF, + // we need to allocate a new cluster. + // An act of minor evil - we use byteswritten as a scratch integer, knowing + // that its value is not used after updating *successcount above + byteswritten = 0; +lastcluster = fileinfo->cluster; +fileinfo->cluster = + DFS_GetFAT(fileinfo->volinfo, scratch, + &byteswritten, fileinfo->cluster); - *successcount += byteswritten; - printf("Writen byte %d \n", *successcount ); - // check to see if we stepped over a cluster boundary - if (div(fileinfo->pointer - byteswritten, fileinfo->volinfo->secperclus * SECTOR_SIZE).quot != - div(fileinfo->pointer, fileinfo->volinfo->secperclus * SECTOR_SIZE).quot) { - unsigned long int lastcluster; + // Allocate a new cluster? + if (((fileinfo->volinfo->filesystem == FAT12) + && (fileinfo->cluster >= 0xff8)) +((fileinfo->volinfo->filesystem == FAT16) + && (fileinfo->cluster >= 0xfff8)) +((fileinfo->volinfo->filesystem == FAT32) + && (fileinfo->cluster >= 0x0ffffff8))) { +unsigned long int tempclus; +tempclus = + DFS_GetFreeFAT(fileinfo->volinfo, scratch); +byteswritten = 0; // invalidate cache + if (tempclus == 0x0ffffff7) +return DFS_ERRMISC; - // We've transgressed into another cluster. If we were already at EOF, - // we need to allocate a new cluster. - // An act of minor evil - we use byteswritten as a scratch integer, knowing - // that its value is not used after updating *successcount above - byteswritten = 0; + // Link new cluster onto file + DFS_SetFAT(fileinfo->volinfo, scratch, + &byteswritten, lastcluster, + tempclus); +fileinfo->cluster = tempclus; - lastcluster = fileinfo->cluster; - fileinfo->cluster = DFS_GetFAT(fileinfo->volinfo, scratch, &byteswritten, fileinfo->cluster); + // Mark newly allocated cluster as end of chain + switch (fileinfo->volinfo->filesystem) { +case FAT12: + tempclus = 0xff8; + break; +case FAT16: + tempclus = 0xfff8; + break; +case FAT32: + tempclus = 0x0ffffff8; + break; +default: + return DFS_ERRMISC; +} +DFS_SetFAT(fileinfo->volinfo, scratch, + &byteswritten, fileinfo->cluster, + tempclus); +result = DFS_OK; +} - // Allocate a new cluster? - if (((fileinfo->volinfo->filesystem == FAT12) && (fileinfo->cluster >= 0xff8)) || - ((fileinfo->volinfo->filesystem == FAT16) && (fileinfo->cluster >= 0xfff8)) || - ((fileinfo->volinfo->filesystem == FAT32) && (fileinfo->cluster >= 0x0ffffff8))) { - unsigned long int tempclus; + // No else clause is required. + } +} - tempclus = DFS_GetFreeFAT(fileinfo->volinfo, scratch); - byteswritten = 0; // invalidate cache - if (tempclus == 0x0ffffff7) - return DFS_ERRMISC; - - // Link new cluster onto file - DFS_SetFAT(fileinfo->volinfo, scratch, &byteswritten, lastcluster, tempclus); - fileinfo->cluster = tempclus; - - // Mark newly allocated cluster as end of chain - switch(fileinfo->volinfo->filesystem) { - case FAT12: tempclus = 0xff8; break; - case FAT16: tempclus = 0xfff8; break; - case FAT32: tempclus = 0x0ffffff8; break; - default: return DFS_ERRMISC; - } - DFS_SetFAT(fileinfo->volinfo, scratch, &byteswritten, fileinfo->cluster, tempclus); - - result = DFS_OK; - } - // No else clause is required. - } - } + // Update directory entry + if (DFS_ReadSector + (fileinfo->volinfo->unit, scratch, fileinfo->dirsector, 1)) +return DFS_ERRMISC; +((PDIRENT) scratch)[fileinfo->diroffset].filesize_0 = + fileinfo->filelen & 0xff; +((PDIRENT) scratch)[fileinfo->diroffset].filesize_1 = + (fileinfo->filelen & 0xff00) >> 8; +((PDIRENT) scratch)[fileinfo->diroffset].filesize_2 = + (fileinfo->filelen & 0xff0000) >> 16; +((PDIRENT) scratch)[fileinfo->diroffset].filesize_3 = + (fileinfo->filelen & 0xff000000) >> 24; +if (DFS_WriteSector + (fileinfo->volinfo->unit, scratch, fileinfo->dirsector, 1)) +return DFS_ERRMISC; +return result; +} + +int memcmp2(const void *s1, const void *s2, size_t n) +{ +const unsigned char *p1 = s1, *p2 = s2; +while (n--) +if (*p1 != *p2) +return *p1 - *p2; - // Update directory entry - if (DFS_ReadSector(fileinfo->volinfo->unit, scratch, fileinfo->dirsector, 1)) - return DFS_ERRMISC; - ((PDIRENT) scratch)[fileinfo->diroffset].filesize_0 = fileinfo->filelen & 0xff; - ((PDIRENT) scratch)[fileinfo->diroffset].filesize_1 = (fileinfo->filelen & 0xff00) >> 8; - ((PDIRENT) scratch)[fileinfo->diroffset].filesize_2 = (fileinfo->filelen & 0xff0000) >> 16; - ((PDIRENT) scratch)[fileinfo->diroffset].filesize_3 = (fileinfo->filelen & 0xff000000) >> 24; - if (DFS_WriteSector(fileinfo->volinfo->unit, scratch, fileinfo->dirsector, 1)) - return DFS_ERRMISC; - return result; -} - -int memcmp2(const void* s1, const void* s2,size_t n) -{ - const unsigned char *p1 = s1, *p2 = s2; - while(n--) - if( *p1 != *p2 ) - return *p1 - *p2; - else - *p1++,*p2++; - return 0; -} - -char *strcpy2(char *dest, char* src) -{ - char *ret = dest; - while (*dest++ = *src++) - ; - return ret; -} - -int strcmp2(const char* s1, const char* s2) -{ - while(*s1 && (*s1==*s2)) - s1++,s2++; - return *(const unsigned char*)s1-*(const unsigned char*)s2; -} + else +*p1++, *p2++; +return 0; +} + +char *strcpy2(char *dest, char *src) +{ +char *ret = dest; +while (*dest++ = *src++) +; +return ret; +} + +int strcmp2(const char *s1, const char *s2) +{ +while (*s1 && (*s1 == *s2)) +s1++, s2++; +return *(const unsigned char *)s1 - *(const unsigned char *)s2; +}
/screen.c
11,86 → 11,96
extern unsigned char font[256][12];
static char screen[CHARSY][CHARSX];
 
void put_char_xy (int x, int y, char c) {
int i, j;
screen[y][x] = c;
x *= CHAR_WIDTH;
y *= CHAR_HEIGHT;
for (i = 0; i < CHAR_HEIGHT; i++) {
int t = font[(unsigned char)c][i];
for (j = 0; j < CHAR_WIDTH; j++) {
PUT_PIXEL(x + j, y + i, (t & 1) ? fg_color : bg_color);
t >>= 1;
}
}
void put_char_xy(int x, int y, char c)
{
int i, j;
screen[y][x] = c;
x *= CHAR_WIDTH;
y *= CHAR_HEIGHT;
for (i = 0; i < CHAR_HEIGHT; i++) {
int t = font[(unsigned char)c][i];
for (j = 0; j < CHAR_WIDTH; j++) {
PUT_PIXEL(x + j, y + i, (t & 1) ? fg_color : bg_color);
t >>= 1;
}
}
}
 
static void scroll (void) {
int x,y;
static void scroll(void)
{
int x, y;
#if 1
for (y = 1; y < CHARSY; y++)
for (x = 0; x < CHARSX; x++)
put_char_xy (x, y-1, screen[y][x]);
for (y = 1; y < CHARSY; y++)
for (x = 0; x < CHARSX; x++)
put_char_xy(x, y - 1, screen[y][x]);
#else
memcpy ( (unsigned char *)FB_BASE_ADDR, ((unsigned char *)FB_BASE_ADDR) + RESX * CHAR_HEIGHT, (RESY - CHAR_HEIGHT) * RESX);
memcpy (&screen[0][0], &screen[1][0], (CHARSY - 1) * CHARSX);
memcpy((unsigned char *)FB_BASE_ADDR,
((unsigned char *)FB_BASE_ADDR) + RESX * CHAR_HEIGHT,
(RESY - CHAR_HEIGHT) * RESX);
memcpy(&screen[0][0], &screen[1][0], (CHARSY - 1) * CHARSX);
#endif
for (x = 0; x < CHARSX; x++)
put_char_xy (x, CHARSY-1, ' ');
cy--;
for (x = 0; x < CHARSX; x++)
put_char_xy(x, CHARSY - 1, ' ');
cy--;
}
 
void screen_putc (char c) {
int t;
switch (c) {
case '\n':
cy++;
cx = 0;
if (cy >= CHARSY)
scroll();
break;
case '\r':
cx = 0;
break;
case '\t':
for (t = 0; t < 8 - (cx & 7); t++)
screen_putc (' ');
break;
case '\b':
if (cx > 0) cx--;
put_char_xy(cx, cy, ' ');
break;
default:
put_char_xy(cx, cy, c);
cx++;
if(cx >= CHARSX) screen_putc ('\n');
break;
}
void screen_putc(char c)
{
int t;
switch (c) {
case '\n':
cy++;
cx = 0;
if (cy >= CHARSY)
scroll();
break;
case '\r':
cx = 0;
break;
case '\t':
for (t = 0; t < 8 - (cx & 7); t++)
screen_putc(' ');
break;
case '\b':
if (cx > 0)
cx--;
put_char_xy(cx, cy, ' ');
break;
default:
put_char_xy(cx, cy, c);
cx++;
if (cx >= CHARSX)
screen_putc('\n');
break;
}
}
 
void screen_clear () {
memset ((unsigned char *)FB_BASE_ADDR, bg_color, RESX * RESY);
memset (&screen[0][0], ' ', CHARSX * CHARSY);
cx = cy = 0;
void screen_clear()
{
memset((unsigned char *)FB_BASE_ADDR, bg_color, RESX * RESY);
memset(&screen[0][0], ' ', CHARSX * CHARSY);
cx = cy = 0;
}
 
void screen_puts (char *s) {
while (*s) {
screen_putc (*s);
s++;
}
void screen_puts(char *s)
{
while (*s) {
screen_putc(*s);
s++;
}
}
 
void screen_init () {
screen_clear ();
SET_PALLETE(COLOR_BLACK, 0, 0, 0);
SET_PALLETE(COLOR_WHITE, 127, 127, 127);
void screen_init()
{
screen_clear();
SET_PALLETE(COLOR_BLACK, 0, 0, 0);
SET_PALLETE(COLOR_WHITE, 127, 127, 127);
 
/* Set screen offset */
*((unsigned long *)CRT_BUFFER_REG) = FB_BASE_ADDR;
/* Set screen offset */
*((unsigned long *)CRT_BUFFER_REG) = FB_BASE_ADDR;
 
/* Turn screen on */
*((unsigned long *)CRT_REG) = 0x00000001;
/* Turn screen on */
*((unsigned long *)CRT_REG) = 0x00000001;
}
 
#endif /* CRT_ENABLED */
/ctype.c
22,34 → 22,33
 
#include <ctype.h>
 
const unsigned char __ctype_table[256] =
{
/* only the first 128 characters are really defined 0 1 2 3 4 5 6 7 */
0, __CT_c, __CT_c, __CT_c, __CT_c, __CT_c, __CT_c, __CT_c, /*0 NUL SOH STX ETX EOT ENQ ACK BEL */
__CT_c, __CT_b, __CT_s, __CT_b, __CT_s, __CT_s, __CT_c, __CT_c, /*1 BS HT LF VT FF CR SO SI */
__CT_c, __CT_c, __CT_c, __CT_c, __CT_c, __CT_c, __CT_c, __CT_c, /*2 DLE DC1 DC2 DC3 DC4 NAK SYN ETB */
__CT_c, __CT_c, __CT_c, __CT_c, __CT_c, __CT_c, __CT_c, __CT_c, /*3 CAN EM SUB ESC FS GS RS US */
__CT_b, __CT_p, __CT_p, __CT_p, __CT_p, __CT_p, __CT_p, __CT_p, /*4 SP ! " # $ % & ' */
__CT_p, __CT_p, __CT_p, __CT_p, __CT_p, __CT_p, __CT_p, __CT_p, /*5 ( ) * + , - . / */
__CT_d, __CT_d, __CT_d, __CT_d, __CT_d, __CT_d, __CT_d, __CT_d, /*6 0 1 2 3 4 5 6 7 */
__CT_d, __CT_d, __CT_p, __CT_p, __CT_p, __CT_p, __CT_p, __CT_p, /*7 8 9 : ; < = > ? */
__CT_p, __CT_ux, __CT_ux, __CT_ux, __CT_ux, __CT_ux, __CT_ux, __CT_u, /*8 @ A B C D E F G */
__CT_u, __CT_u, __CT_u, __CT_u, __CT_u, __CT_u, __CT_u, __CT_u, /*9 H I J K L M N O */
__CT_u, __CT_u, __CT_u, __CT_u, __CT_u, __CT_u, __CT_u, __CT_u, /*a P Q R S T U V W */
__CT_u, __CT_u, __CT_u, __CT_p, __CT_p, __CT_p, __CT_p, __CT_p, /*b X Y Z [ \ ] ^ _ */
__CT_p, __CT_lx, __CT_lx, __CT_lx, __CT_lx, __CT_lx, __CT_lx, __CT_l, /*c ` a b c d e f g */
__CT_l, __CT_l, __CT_l, __CT_l, __CT_l, __CT_l, __CT_l, __CT_l, /*d h i j k l m n o */
__CT_l, __CT_l, __CT_l, __CT_l, __CT_l, __CT_l, __CT_l, __CT_l, /*e p q r s t u v w */
__CT_l, __CT_l, __CT_l, __CT_p, __CT_p, __CT_p, __CT_p, __CT_c, /*f x y z { | } ~ DEL */
const unsigned char __ctype_table[256] = {
/* only the first 128 characters are really defined 0 1 2 3 4 5 6 7 */
0, __CT_c, __CT_c, __CT_c, __CT_c, __CT_c, __CT_c, __CT_c, /*0 NUL SOH STX ETX EOT ENQ ACK BEL */
__CT_c, __CT_b, __CT_s, __CT_b, __CT_s, __CT_s, __CT_c, __CT_c, /*1 BS HT LF VT FF CR SO SI */
__CT_c, __CT_c, __CT_c, __CT_c, __CT_c, __CT_c, __CT_c, __CT_c, /*2 DLE DC1 DC2 DC3 DC4 NAK SYN ETB */
__CT_c, __CT_c, __CT_c, __CT_c, __CT_c, __CT_c, __CT_c, __CT_c, /*3 CAN EM SUB ESC FS GS RS US */
__CT_b, __CT_p, __CT_p, __CT_p, __CT_p, __CT_p, __CT_p, __CT_p, /*4 SP ! " # $ % & ' */
__CT_p, __CT_p, __CT_p, __CT_p, __CT_p, __CT_p, __CT_p, __CT_p, /*5 ( ) * + , - . / */
__CT_d, __CT_d, __CT_d, __CT_d, __CT_d, __CT_d, __CT_d, __CT_d, /*6 0 1 2 3 4 5 6 7 */
__CT_d, __CT_d, __CT_p, __CT_p, __CT_p, __CT_p, __CT_p, __CT_p, /*7 8 9 : ; < = > ? */
__CT_p, __CT_ux, __CT_ux, __CT_ux, __CT_ux, __CT_ux, __CT_ux, __CT_u, /*8 @ A B C D E F G */
__CT_u, __CT_u, __CT_u, __CT_u, __CT_u, __CT_u, __CT_u, __CT_u, /*9 H I J K L M N O */
__CT_u, __CT_u, __CT_u, __CT_u, __CT_u, __CT_u, __CT_u, __CT_u, /*a P Q R S T U V W */
__CT_u, __CT_u, __CT_u, __CT_p, __CT_p, __CT_p, __CT_p, __CT_p, /*b X Y Z [ \ ] ^ _ */
__CT_p, __CT_lx, __CT_lx, __CT_lx, __CT_lx, __CT_lx, __CT_lx, __CT_l, /*c ` a b c d e f g */
__CT_l, __CT_l, __CT_l, __CT_l, __CT_l, __CT_l, __CT_l, __CT_l, /*d h i j k l m n o */
__CT_l, __CT_l, __CT_l, __CT_l, __CT_l, __CT_l, __CT_l, __CT_l, /*e p q r s t u v w */
__CT_l, __CT_l, __CT_l, __CT_p, __CT_p, __CT_p, __CT_p, __CT_c, /*f x y z { | } ~ DEL */
 
/* The other 128 characters are system dependant */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* The other 128 characters are system dependant */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/cprintf.c
182,7 → 182,8
#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
#define DEFPREC 6
 
static char *cvt _PARAMS((struct _reent *, double, int, int, char *, int *, int, int *));
static char *cvt
_PARAMS((struct _reent *, double, int, int, char *, int *, int, int *));
static int exponent _PARAMS((char *, int, int));
 
#else /* no FLOATING_POINT */
201,15 → 202,15
/*
* Flags used during conversion.
*/
#define ALT 0x001 /* alternate form */
#define HEXPREFIX 0x002 /* add 0x or 0X prefix */
#define LADJUST 0x004 /* left adjustment */
#define LONGDBL 0x008 /* long double; unimplemented */
#define LONGINT 0x010 /* long integer */
#define QUADINT 0x020 /* quad integer */
#define SHORTINT 0x040 /* short integer */
#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
#define FPT 0x100 /* Floating point number */
#define ALT 0x001 /* alternate form */
#define HEXPREFIX 0x002 /* add 0x or 0X prefix */
#define LADJUST 0x004 /* left adjustment */
#define LONGDBL 0x008 /* long double; unimplemented */
#define LONGINT 0x010 /* long integer */
#define QUADINT 0x020 /* quad integer */
#define SHORTINT 0x040 /* short integer */
#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
#define FPT 0x100 /* Floating point number */
 
/*
* Choose PADSIZE to trade efficiency vs. size. If larger printf
217,29 → 218,35
* below longer.
*/
#define PADSIZE 16 /* pad chunk size */
static _CONST char blanks[PADSIZE] =
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
static _CONST char zeroes[PADSIZE] =
{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
static _CONST char blanks[PADSIZE] =
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ' };
static _CONST char zeroes[PADSIZE] =
{ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'0' };
 
inline void pc (_CONST char c) {
inline void pc(_CONST char c)
{
#ifdef OR1K
putc (c);
putc(c);
#else
printf ("%c", c);
printf("%c", c);
#endif
}
 
/*
* BEWARE, these `goto error' on error, and PAD uses `n'.
*/
inline void PRINT(_CONST char *ptr, int len) {
int i;
for (i = 0; i < len; i++)
pc(*(ptr++));
inline void PRINT(_CONST char *ptr, int len)
{
int i;
for (i = 0; i < len; i++)
pc(*(ptr++));
}
 
inline void PAD(int howmany, _CONST char *with) {
int n;
inline void PAD(int howmany, _CONST char *with)
{
int n;
if ((n = howmany) > 0) {
while (n > PADSIZE) {
PRINT(with, PADSIZE);
249,11 → 256,11
}
}
 
int printf(const char *fmt0, ...)
{
int printf(const char *fmt0, ...)
{
register char *fmt; /* format string */
register int ch; /* character from fmt */
int n; /* handy integers (short term usage) */
int n; /* handy integers (short term usage) */
register char *cp; /* handy char pointer (short term usage) */
register int flags; /* flags as above */
int ret; /* return value accumulator */
261,7 → 268,7
int prec; /* precision from format (%.3d), or -1 */
char sign; /* sign prefix (' ', '+', '-', or \0) */
va_list ap;
 
#ifdef FLOATING_POINT
char *decimal_point = localeconv()->decimal_point;
char softsign; /* temporary negative sign for floats */
276,8 → 283,12
#if 0
double _double; /* double precision arguments %[eEfgG] */
#else
/* double precision arguments %[eEfgG] */
union { int i; double d; } _double_ = {0};
/* double precision arguments %[eEfgG] */
union {
int i;
double d;
} _double_ = {
0};
#define _double (_double_.d)
#endif
int expt; /* integer value of exponent */
296,15 → 307,15
#else
u_long _uquad;
#endif
enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
enum { OCT, DEC, HEX } base; /* base for [diouxX] conversion */
int dprec; /* a copy of prec if [diouxX], 0 otherwise */
int realsz; /* field size expanded by dprec */
int size; /* size of converted field or string */
char *xdigs = (char *)0; /* digits for [xX] conversion */
char *xdigs = (char *)0; /* digits for [xX] conversion */
#define NIOV 8
 
char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */
char ox[2]; /* space for 0x hex-prefix */
char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */
char ox[2]; /* space for 0x hex-prefix */
 
#define FLUSH()
 
334,7 → 345,7
(u_long)va_arg(ap, u_int))
#endif
 
va_start (ap, fmt0);
va_start(ap, fmt0);
fmt = (char *)fmt0;
ret = 0;
 
342,16 → 353,16
* Scan the format for conversions (`%' character).
*/
for (;;) {
while (*fmt != 0 && *fmt != '%') {
pc (*fmt);
fmt++;
ret++;
}
 
while (*fmt != 0 && *fmt != '%') {
pc(*fmt);
fmt++;
ret++;
}
if (!*fmt)
goto done;
goto done;
 
fmt++; /* Skip % */
fmt++; /* Skip % */
flags = 0;
dprec = 0;
width = 0;
364,7 → 375,7
/*
* ``If the space and + flags both appear, the space
* flag will be ignored.''
* -- ANSI X3J11
* -- ANSI X3J11
*/
if (!sign)
sign = ' ';
376,11 → 387,11
/*
* ``A negative field width argument is taken as a
* - flag followed by a positive field width.''
* -- ANSI X3J11
* -- ANSI X3J11
* They don't exclude field widths read from args.
*/
if ((width = va_arg(ap, int)) >= 0)
goto rflag;
goto rflag;
width = -width;
/* FALLTHROUGH */
case '-':
406,12 → 417,19
/*
* ``Note that 0 is taken as a flag, not as the
* beginning of a field width.''
* -- ANSI X3J11
* -- ANSI X3J11
*/
flags |= ZEROPAD;
goto rflag;
case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
n = 0;
do {
n = 10 * n + to_digit(ch);
445,14 → 463,13
break;
case 'D':
flags |= LONGINT;
/*FALLTHROUGH*/
case 'd':
/*FALLTHROUGH*/ case 'd':
case 'i':
_uquad = SARG();
#ifndef _NO_LONGLONG
if ((quad_t)_uquad < 0)
if ((quad_t) _uquad < 0)
#else
if ((long) _uquad < 0)
if ((long)_uquad < 0)
#endif
{
 
474,7 → 491,7
}
 
if (flags & LONGDBL) {
_double = (double) va_arg(ap, long double);
_double = (double)va_arg(ap, long double);
} else {
_double = va_arg(ap, double);
}
495,13 → 512,13
 
flags |= FPT;
cp = cvt(data, _double, prec, flags, &softsign,
&expt, ch, &ndig);
&expt, ch, &ndig);
if (ch == 'g' || ch == 'G') {
if (expt <= -4 || expt > prec)
ch = (ch == 'g') ? 'e' : 'E';
else
ch = 'g';
}
}
if (ch <= 'e') { /* 'e' or 'E' fmt */
--expt;
expsize = exponent(expstr, expt, ch);
508,7 → 525,7
size = expsize + ndig;
if (ndig > 1 || flags & ALT)
++size;
} else if (ch == 'f') { /* f fmt */
} else if (ch == 'f') { /* f fmt */
if (expt > 0) {
size = expt;
if (prec || flags & ALT)
520,8 → 537,7
if (flags & ALT)
++size;
} else
size = ndig + (expt > 0 ?
1 : 2 - expt);
size = ndig + (expt > 0 ? 1 : 2 - expt);
 
if (softsign)
sign = '-';
531,7 → 547,7
#ifndef _NO_LONGLONG
if (flags & QUADINT)
*va_arg(ap, quad_t *) = ret;
else
else
#endif
if (flags & LONGINT)
*va_arg(ap, long *) = ret;
542,8 → 558,7
continue; /* no output */
case 'O':
flags |= LONGINT;
/*FALLTHROUGH*/
case 'o':
/*FALLTHROUGH*/ case 'o':
_uquad = UARG();
base = OCT;
goto nosign;
553,10 → 568,11
* value of the pointer is converted to a sequence
* of printable characters, in an implementation-
* defined manner.''
* -- ANSI X3J11
* -- ANSI X3J11
*/
/* NOSTRICT */
_uquad = (u_long)(unsigned _POINTER_INT)va_arg(ap, void *);
_uquad =
(u_long) (unsigned _POINTER_INT)va_arg(ap, void *);
base = HEX;
xdigs = "0123456789abcdef";
flags |= HEXPREFIX;
585,8 → 601,7
break;
case 'U':
flags |= LONGINT;
/*FALLTHROUGH*/
case 'u':
/*FALLTHROUGH*/ case 'u':
_uquad = UARG();
base = DEC;
goto nosign;
602,19 → 617,19
flags |= HEXPREFIX;
 
/* unsigned conversions */
nosign: sign = '\0';
nosign: sign = '\0';
/*
* ``... diouXx conversions ... if a precision is
* specified, the 0 flag will be ignored.''
* -- ANSI X3J11
* -- ANSI X3J11
*/
number: if ((dprec = prec) >= 0)
number: if ((dprec = prec) >= 0)
flags &= ~ZEROPAD;
 
/*
* ``The result of converting a zero value with an
* explicit precision of zero is no characters.''
* -- ANSI X3J11
* -- ANSI X3J11
*/
cp = buf + BUF;
if (_uquad != 0 || prec != 0) {
657,7 → 672,7
}
}
size = buf + BUF - cp;
skipsize:
skipsize:
break;
default: /* "%?" prints ?, unless ? is NUL */
if (ch == '\0')
688,10 → 703,10
if (sign)
realsz++;
else if (flags & HEXPREFIX)
realsz+= 2;
realsz += 2;
 
/* right-adjusting blank padding */
if ((flags & (LADJUST|ZEROPAD)) == 0)
if ((flags & (LADJUST | ZEROPAD)) == 0)
PAD(width - realsz, blanks);
 
/* prefix */
704,7 → 719,7
}
 
/* right-adjusting zero padding */
if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
if ((flags & (LADJUST | ZEROPAD)) == ZEROPAD)
PAD(width - realsz, zeroes);
 
/* leading zeroes from decimal precision */
737,7 → 752,7
PRINT(cp, expt);
cp += expt;
PRINT(".", 1);
PRINT(cp, ndig-expt);
PRINT(cp, ndig - expt);
}
} else { /* 'e' or 'E' */
if (ndig > 1 || flags & ALT) {
745,7 → 760,7
ox[1] = '.';
PRINT(ox, 2);
if (_double || flags & ALT == 0) {
PRINT(cp, ndig-1);
PRINT(cp, ndig - 1);
} else /* 0.[0..] */
/* __dtoa irregularity */
PAD(ndig - 1, zeroes);
767,7 → 782,7
FLUSH(); /* copy out the I/O vectors */
}
done:
va_end (ap);
va_end(ap);
FLUSH();
return (ret);
/* NOTREACHED */
778,19 → 793,18
extern char *_dtoa_r _PARAMS((struct _reent *, double, int,
int, int *, int *, char **));
 
static char *
cvt(data, value, ndigits, flags, sign, decpt, ch, length)
struct _reent *data;
double value;
int ndigits, flags, *decpt, ch, *length;
char *sign;
static char *cvt(data, value, ndigits, flags, sign, decpt, ch, length)
struct _reent *data;
double value;
int ndigits, flags, *decpt, ch, *length;
char *sign;
{
int mode, dsgn;
char *digits, *bp, *rve;
union double_union tmp;
union double_union tmp;
 
if (ch == 'f') {
mode = 3; /* ndigits after the decimal point */
mode = 3; /* ndigits after the decimal point */
} else {
/* To obtain ndigits after the decimal point for the 'e'
* and 'E' formats, round to ndigits + 1 significant
799,14 → 813,14
if (ch == 'e' || ch == 'E') {
ndigits++;
}
mode = 2; /* ndigits significant digits */
mode = 2; /* ndigits significant digits */
}
 
tmp.d = value;
if (word0(tmp) & Sign_bit) { /* this will check for < 0 and -0.0 */
tmp.d = value;
if (word0(tmp) & Sign_bit) { /* this will check for < 0 and -0.0 */
value = -value;
*sign = '-';
} else
} else
*sign = '\000';
digits = _dtoa_r(data, value, mode, ndigits, decpt, &dsgn, &rve);
if ((ch != 'g' && ch != 'G') || flags & ALT) { /* Print trailing zeros */
825,10 → 839,9
return (digits);
}
 
static int
exponent(p0, exp, fmtch)
char *p0;
int exp, fmtch;
static int exponent(p0, exp, fmtch)
char *p0;
int exp, fmtch;
{
register char *p, *t;
char expbuf[MAXEXP];
838,8 → 851,7
if (exp < 0) {
exp = -exp;
*p++ = '-';
}
else
} else
*p++ = '+';
t = expbuf + MAXEXP;
if (exp > 9) {
847,9 → 859,8
*--t = to_char(exp % 10);
} while ((exp /= 10) > 9);
*--t = to_char(exp);
for (; t < expbuf + MAXEXP; *p++ = *t++);
}
else {
for (; t < expbuf + MAXEXP; *p++ = *t++) ;
} else {
*p++ = '0';
*p++ = to_char(exp);
}
/font.c
2,308 → 2,262
#if CRT_ENABLED
 
unsigned char font[256][12] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0, 00h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 1, 01h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 2, 02h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 3, 03h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 4, 04h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 5, 05h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 6, 06h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 7, 07h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 8, 08h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 9, 09h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 10, 0ah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 11, 0bh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 12, 0ch */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 13, 0dh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 14, 0eh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 15, 0fh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 16, 10h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 17, 11h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 18, 12h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 19, 13h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 20, 14h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 21, 15h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 22, 16h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 23, 17h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 24, 18h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 25, 19h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 26, 1ah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 27, 1bh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 28, 1ch */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 29, 1dh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 30, 1eh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 31, 1fh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 32, 20h, ' ' */
{0x00, 0x0c, 0x1e, 0x1e, 0x1e, 0x0c, 0x0c, 0x00, 0x0c, 0x0c, 0x00, 0x00}, /* 33, 21h, '!' */
{0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 34, 22h, '"' */
{0x00, 0x36, 0x36, 0x7f, 0x36, 0x36, 0x36, 0x7f, 0x36, 0x36, 0x00, 0x00}, /* 35, 23h, '#' */
{0x0c, 0x0c, 0x3e, 0x03, 0x03, 0x1e, 0x30, 0x30, 0x1f, 0x0c, 0x0c, 0x00}, /* 36, 24h, '$' */
{0x00, 0x00, 0x00, 0x23, 0x33, 0x18, 0x0c, 0x06, 0x33, 0x31, 0x00, 0x00}, /* 37, 25h, '%' */
{0x00, 0x0e, 0x1b, 0x1b, 0x0e, 0x5f, 0x7b, 0x33, 0x3b, 0x6e, 0x00, 0x00}, /* 38, 26h, '&' */
{0x00, 0x0c, 0x0c, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 39, 27h, ''' */
{0x00, 0x30, 0x18, 0x0c, 0x06, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x00}, /* 40, 28h, '(' */
{0x00, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00}, /* 41, 29h, ')' */
{0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00}, /* 42, 2ah, '*' */
{0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 43, 2bh, '+' */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x06, 0x00}, /* 44, 2ch, ',' */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 45, 2dh, '-' */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00}, /* 46, 2eh, '.' */
{0x00, 0x00, 0x40, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01, 0x00, 0x00}, /* 47, 2fh, '/' */
{0x00, 0x3e, 0x63, 0x73, 0x7b, 0x6b, 0x6f, 0x67, 0x63, 0x3e, 0x00, 0x00}, /* 48, 30h, '0' */
{0x00, 0x08, 0x0c, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00}, /* 49, 31h, '1' */
{0x00, 0x1e, 0x33, 0x33, 0x30, 0x18, 0x0c, 0x06, 0x33, 0x3f, 0x00, 0x00}, /* 50, 32h, '2' */
{0x00, 0x1e, 0x33, 0x30, 0x30, 0x1c, 0x30, 0x30, 0x33, 0x1e, 0x00, 0x00}, /* 51, 33h, '3' */
{0x00, 0x30, 0x38, 0x3c, 0x36, 0x33, 0x7f, 0x30, 0x30, 0x78, 0x00, 0x00}, /* 52, 34h, '4' */
{0x00, 0x3f, 0x03, 0x03, 0x03, 0x1f, 0x30, 0x30, 0x33, 0x1e, 0x00, 0x00}, /* 53, 35h, '5' */
{0x00, 0x1c, 0x06, 0x03, 0x03, 0x1f, 0x33, 0x33, 0x33, 0x1e, 0x00, 0x00}, /* 54, 36h, '6' */
{0x00, 0x7f, 0x63, 0x63, 0x60, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x00, 0x00}, /* 55, 37h, '7' */
{0x00, 0x1e, 0x33, 0x33, 0x37, 0x1e, 0x3b, 0x33, 0x33, 0x1e, 0x00, 0x00}, /* 56, 38h, '8' */
{0x00, 0x1e, 0x33, 0x33, 0x33, 0x3e, 0x18, 0x18, 0x0c, 0x0e, 0x00, 0x00}, /* 57, 39h, '9' */
{0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00}, /* 58, 3ah, ':' */
{0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x1c, 0x1c, 0x18, 0x0c, 0x00}, /* 59, 3bh, ';' */
{0x00, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x00}, /* 60, 3ch, '<' */
{0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 61, 3dh, '=' */
{0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00}, /* 62, 3eh, '>' */
{0x00, 0x1e, 0x33, 0x30, 0x18, 0x0c, 0x0c, 0x00, 0x0c, 0x0c, 0x00, 0x00}, /* 63, 3fh, '?' */
{0x00, 0x3e, 0x63, 0x63, 0x7b, 0x7b, 0x7b, 0x03, 0x03, 0x3e, 0x00, 0x00}, /* 64, 40h, '@' */
{0x00, 0x0c, 0x1e, 0x33, 0x33, 0x33, 0x3f, 0x33, 0x33, 0x33, 0x00, 0x00}, /* 65, 41h, 'A' */
{0x00, 0x3f, 0x66, 0x66, 0x66, 0x3e, 0x66, 0x66, 0x66, 0x3f, 0x00, 0x00}, /* 66, 42h, 'B' */
{0x00, 0x3c, 0x66, 0x63, 0x03, 0x03, 0x03, 0x63, 0x66, 0x3c, 0x00, 0x00}, /* 67, 43h, 'C' */
{0x00, 0x1f, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x36, 0x1f, 0x00, 0x00}, /* 68, 44h, 'D' */
{0x00, 0x7f, 0x46, 0x06, 0x26, 0x3e, 0x26, 0x06, 0x46, 0x7f, 0x00, 0x00}, /* 69, 45h, 'E' */
{0x00, 0x7f, 0x66, 0x46, 0x26, 0x3e, 0x26, 0x06, 0x06, 0x0f, 0x00, 0x00}, /* 70, 46h, 'F' */
{0x00, 0x3c, 0x66, 0x63, 0x03, 0x03, 0x73, 0x63, 0x66, 0x7c, 0x00, 0x00}, /* 71, 47h, 'G' */
{0x00, 0x33, 0x33, 0x33, 0x33, 0x3f, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00}, /* 72, 48h, 'H' */
{0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00}, /* 73, 49h, 'I' */
{0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0x33, 0x33, 0x33, 0x1e, 0x00, 0x00}, /* 74, 4ah, 'J' */
{0x00, 0x67, 0x66, 0x36, 0x36, 0x1e, 0x36, 0x36, 0x66, 0x67, 0x00, 0x00}, /* 75, 4bh, 'K' */
{0x00, 0x0f, 0x06, 0x06, 0x06, 0x06, 0x46, 0x66, 0x66, 0x7f, 0x00, 0x00}, /* 76, 4ch, 'L' */
{0x00, 0x63, 0x77, 0x7f, 0x7f, 0x6b, 0x63, 0x63, 0x63, 0x63, 0x00, 0x00}, /* 77, 4dh, 'M' */
{0x00, 0x63, 0x63, 0x67, 0x6f, 0x7f, 0x7b, 0x73, 0x63, 0x63, 0x00, 0x00}, /* 78, 4eh, 'N' */
{0x00, 0x1c, 0x36, 0x63, 0x63, 0x63, 0x63, 0x63, 0x36, 0x1c, 0x00, 0x00}, /* 79, 4fh, 'O' */
{0x00, 0x3f, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x06, 0x06, 0x0f, 0x00, 0x00}, /* 80, 50h, 'P' */
{0x00, 0x1c, 0x36, 0x63, 0x63, 0x63, 0x73, 0x7b, 0x3e, 0x30, 0x78, 0x00}, /* 81, 51h, 'Q' */
{0x00, 0x3f, 0x66, 0x66, 0x66, 0x3e, 0x36, 0x66, 0x66, 0x67, 0x00, 0x00}, /* 82, 52h, 'R' */
{0x00, 0x1e, 0x33, 0x33, 0x03, 0x0e, 0x18, 0x33, 0x33, 0x1e, 0x00, 0x00}, /* 83, 53h, 'S' */
{0x00, 0x3f, 0x2d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00}, /* 84, 54h, 'T' */
{0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x1e, 0x00, 0x00}, /* 85, 55h, 'U' */
{0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x1e, 0x0c, 0x00, 0x00}, /* 86, 56h, 'V' */
{0x00, 0x63, 0x63, 0x63, 0x63, 0x6b, 0x6b, 0x36, 0x36, 0x36, 0x00, 0x00}, /* 87, 57h, 'W' */
{0x00, 0x33, 0x33, 0x33, 0x1e, 0x0c, 0x1e, 0x33, 0x33, 0x33, 0x00, 0x00}, /* 88, 58h, 'X' */
{0x00, 0x33, 0x33, 0x33, 0x33, 0x1e, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00}, /* 89, 59h, 'Y' */
{0x00, 0x7f, 0x73, 0x19, 0x18, 0x0c, 0x06, 0x46, 0x63, 0x7f, 0x00, 0x00}, /* 90, 5ah, 'Z' */
{0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00}, /* 91, 5bh, '[' */
{0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x40, 0x00, 0x00}, /* 92, 5ch, '\' */
{0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00}, /* 93, 5dh, ']' */
{0x08, 0x1c, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 94, 5eh, '^' */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00}, /* 95, 5fh, '_' */
{0x0c, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 96, 60h, '`' */
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x3e, 0x33, 0x33, 0x6e, 0x00, 0x00}, /* 97, 61h, 'a' */
{0x00, 0x07, 0x06, 0x06, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3b, 0x00, 0x00}, /* 98, 62h, 'b' */
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x33, 0x03, 0x03, 0x33, 0x1e, 0x00, 0x00}, /* 99, 63h, 'c' */
{0x00, 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00}, /* 100, 64h, 'd' */
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x33, 0x3f, 0x03, 0x33, 0x1e, 0x00, 0x00}, /* 101, 65h, 'e' */
{0x00, 0x1c, 0x36, 0x06, 0x06, 0x1f, 0x06, 0x06, 0x06, 0x0f, 0x00, 0x00}, /* 102, 66h, 'f' */
{0x00, 0x00, 0x00, 0x00, 0x6e, 0x33, 0x33, 0x33, 0x3e, 0x30, 0x33, 0x1e}, /* 103, 67h, 'g' */
{0x00, 0x07, 0x06, 0x06, 0x36, 0x6e, 0x66, 0x66, 0x66, 0x67, 0x00, 0x00}, /* 104, 68h, 'h' */
{0x00, 0x18, 0x18, 0x00, 0x1e, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00}, /* 105, 69h, 'i' */
{0x00, 0x30, 0x30, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1e}, /* 106, 6ah, 'j' */
{0x00, 0x07, 0x06, 0x06, 0x66, 0x36, 0x1e, 0x36, 0x66, 0x67, 0x00, 0x00}, /* 107, 6bh, 'k' */
{0x00, 0x1e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00}, /* 108, 6ch, 'l' */
{0x00, 0x00, 0x00, 0x00, 0x3f, 0x6b, 0x6b, 0x6b, 0x6b, 0x63, 0x00, 0x00}, /* 109, 6dh, 'm' */
{0x00, 0x00, 0x00, 0x00, 0x1f, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00}, /* 110, 6eh, 'n' */
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x33, 0x33, 0x33, 0x33, 0x1e, 0x00, 0x00}, /* 111, 6fh, 'o' */
{0x00, 0x00, 0x00, 0x00, 0x3b, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x0f}, /* 112, 70h, 'p' */
{0x00, 0x00, 0x00, 0x00, 0x6e, 0x33, 0x33, 0x33, 0x33, 0x3e, 0x30, 0x78}, /* 113, 71h, 'q' */
{0x00, 0x00, 0x00, 0x00, 0x37, 0x76, 0x6e, 0x06, 0x06, 0x0f, 0x00, 0x00}, /* 114, 72h, 'r' */
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x33, 0x06, 0x18, 0x33, 0x1e, 0x00, 0x00}, /* 115, 73h, 's' */
{0x00, 0x00, 0x04, 0x06, 0x3f, 0x06, 0x06, 0x06, 0x36, 0x1c, 0x00, 0x00}, /* 116, 74h, 't' */
{0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00}, /* 117, 75h, 'u' */
{0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x1e, 0x0c, 0x00, 0x00}, /* 118, 76h, 'v' */
{0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x6b, 0x6b, 0x36, 0x36, 0x00, 0x00}, /* 119, 77h, 'w' */
{0x00, 0x00, 0x00, 0x00, 0x63, 0x36, 0x1c, 0x1c, 0x36, 0x63, 0x00, 0x00}, /* 120, 78h, 'x' */
{0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x30, 0x18, 0x0f}, /* 121, 79h, 'y' */
{0x00, 0x00, 0x00, 0x00, 0x3f, 0x31, 0x18, 0x06, 0x23, 0x3f, 0x00, 0x00}, /* 122, 7ah, 'z' */
{0x00, 0x38, 0x0c, 0x0c, 0x06, 0x03, 0x06, 0x0c, 0x0c, 0x38, 0x00, 0x00}, /* 123, 7bh, '{' */
{0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00}, /* 124, 7ch, '|' */
{0x00, 0x07, 0x0c, 0x0c, 0x18, 0x30, 0x18, 0x0c, 0x0c, 0x07, 0x00, 0x00}, /* 125, 7dh, '}' */
{0x00, 0xce, 0x5b, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 126, 7eh, '~' */
{0x00, 0x00, 0x00, 0x08, 0x1c, 0x36, 0x63, 0x63, 0x7f, 0x00, 0x00, 0x00}, /* 127, 7fh, '' */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 128, 80h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 129, 81h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 130, 82h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 131, 83h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 132, 84h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 133, 85h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 134, 86h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 135, 87h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 136, 88h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 137, 89h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 138, 8ah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 139, 8bh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 140, 8ch */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 141, 8dh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 142, 8eh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 143, 8fh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 144, 90h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 145, 91h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 146, 92h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 147, 93h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 148, 94h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 149, 95h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 150, 96h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 151, 97h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 152, 98h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 153, 99h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 154, 9ah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 155, 9bh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 156, 9ch */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 157, 9dh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 158, 9eh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 159, 9fh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 160, a0h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 161, a1h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 162, a2h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 163, a3h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 164, a4h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 165, a5h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 166, a6h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 167, a7h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 168, a8h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 169, a9h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 170, aah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 171, abh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 172, ach */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 173, adh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 174, aeh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 175, afh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 176, b0h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 177, b1h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 178, b2h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 179, b3h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 180, b4h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 181, b5h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 182, b6h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 183, b7h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 184, b8h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 185, b9h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 186, bah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 187, bbh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 188, bch */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 189, bdh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 190, beh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 191, bfh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 192, c0h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 193, c1h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 194, c2h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 195, c3h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 196, c4h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 197, c5h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 198, c6h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 199, c7h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 200, c8h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 201, c9h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 202, cah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 203, cbh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 204, cch */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 205, cdh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 206, ceh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 207, cfh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 208, d0h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 209, d1h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 210, d2h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 211, d3h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 212, d4h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 213, d5h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 214, d6h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 215, d7h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 216, d8h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 217, d9h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 218, dah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 219, dbh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 220, dch */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 221, ddh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 222, deh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 223, dfh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 224, e0h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 225, e1h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 226, e2h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 227, e3h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 228, e4h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 229, e5h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 230, e6h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 231, e7h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 232, e8h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 233, e9h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 234, eah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 235, ebh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 236, ech */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 237, edh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 238, eeh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 239, efh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 240, f0h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 241, f1h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 242, f2h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 243, f3h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 244, f4h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 245, f5h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 246, f6h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 247, f7h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 248, f8h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 249, f9h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 250, fah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 251, fbh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 252, fch */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 253, fdh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 254, feh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};/* 255, ffh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0, 00h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 1, 01h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 2, 02h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 3, 03h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 4, 04h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 5, 05h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 6, 06h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 7, 07h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 8, 08h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 9, 09h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 10, 0ah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 11, 0bh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 12, 0ch */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 13, 0dh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 14, 0eh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 15, 0fh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 16, 10h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 17, 11h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 18, 12h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 19, 13h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 20, 14h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 21, 15h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 22, 16h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 23, 17h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 24, 18h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 25, 19h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 26, 1ah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 27, 1bh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 28, 1ch */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 29, 1dh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 30, 1eh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 31, 1fh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 32, 20h, ' ' */
{0x00, 0x0c, 0x1e, 0x1e, 0x1e, 0x0c, 0x0c, 0x00, 0x0c, 0x0c, 0x00, 0x00}, /* 33, 21h, '!' */
{0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 34, 22h, '"' */
{0x00, 0x36, 0x36, 0x7f, 0x36, 0x36, 0x36, 0x7f, 0x36, 0x36, 0x00, 0x00}, /* 35, 23h, '#' */
{0x0c, 0x0c, 0x3e, 0x03, 0x03, 0x1e, 0x30, 0x30, 0x1f, 0x0c, 0x0c, 0x00}, /* 36, 24h, '$' */
{0x00, 0x00, 0x00, 0x23, 0x33, 0x18, 0x0c, 0x06, 0x33, 0x31, 0x00, 0x00}, /* 37, 25h, '%' */
{0x00, 0x0e, 0x1b, 0x1b, 0x0e, 0x5f, 0x7b, 0x33, 0x3b, 0x6e, 0x00, 0x00}, /* 38, 26h, '&' */
{0x00, 0x0c, 0x0c, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 39, 27h, ''' */
{0x00, 0x30, 0x18, 0x0c, 0x06, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x00}, /* 40, 28h, '(' */
{0x00, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00}, /* 41, 29h, ')' */
{0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00}, /* 42, 2ah, '*' */
{0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 43, 2bh, '+' */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x06, 0x00}, /* 44, 2ch, ',' */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 45, 2dh, '-' */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00}, /* 46, 2eh, '.' */
{0x00, 0x00, 0x40, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01, 0x00, 0x00}, /* 47, 2fh, '/' */
{0x00, 0x3e, 0x63, 0x73, 0x7b, 0x6b, 0x6f, 0x67, 0x63, 0x3e, 0x00, 0x00}, /* 48, 30h, '0' */
{0x00, 0x08, 0x0c, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00}, /* 49, 31h, '1' */
{0x00, 0x1e, 0x33, 0x33, 0x30, 0x18, 0x0c, 0x06, 0x33, 0x3f, 0x00, 0x00}, /* 50, 32h, '2' */
{0x00, 0x1e, 0x33, 0x30, 0x30, 0x1c, 0x30, 0x30, 0x33, 0x1e, 0x00, 0x00}, /* 51, 33h, '3' */
{0x00, 0x30, 0x38, 0x3c, 0x36, 0x33, 0x7f, 0x30, 0x30, 0x78, 0x00, 0x00}, /* 52, 34h, '4' */
{0x00, 0x3f, 0x03, 0x03, 0x03, 0x1f, 0x30, 0x30, 0x33, 0x1e, 0x00, 0x00}, /* 53, 35h, '5' */
{0x00, 0x1c, 0x06, 0x03, 0x03, 0x1f, 0x33, 0x33, 0x33, 0x1e, 0x00, 0x00}, /* 54, 36h, '6' */
{0x00, 0x7f, 0x63, 0x63, 0x60, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x00, 0x00}, /* 55, 37h, '7' */
{0x00, 0x1e, 0x33, 0x33, 0x37, 0x1e, 0x3b, 0x33, 0x33, 0x1e, 0x00, 0x00}, /* 56, 38h, '8' */
{0x00, 0x1e, 0x33, 0x33, 0x33, 0x3e, 0x18, 0x18, 0x0c, 0x0e, 0x00, 0x00}, /* 57, 39h, '9' */
{0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00}, /* 58, 3ah, ':' */
{0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x1c, 0x1c, 0x18, 0x0c, 0x00}, /* 59, 3bh, ';' */
{0x00, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x00}, /* 60, 3ch, '<' */
{0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 61, 3dh, '=' */
{0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00}, /* 62, 3eh, '>' */
{0x00, 0x1e, 0x33, 0x30, 0x18, 0x0c, 0x0c, 0x00, 0x0c, 0x0c, 0x00, 0x00}, /* 63, 3fh, '?' */
{0x00, 0x3e, 0x63, 0x63, 0x7b, 0x7b, 0x7b, 0x03, 0x03, 0x3e, 0x00, 0x00}, /* 64, 40h, '@' */
{0x00, 0x0c, 0x1e, 0x33, 0x33, 0x33, 0x3f, 0x33, 0x33, 0x33, 0x00, 0x00}, /* 65, 41h, 'A' */
{0x00, 0x3f, 0x66, 0x66, 0x66, 0x3e, 0x66, 0x66, 0x66, 0x3f, 0x00, 0x00}, /* 66, 42h, 'B' */
{0x00, 0x3c, 0x66, 0x63, 0x03, 0x03, 0x03, 0x63, 0x66, 0x3c, 0x00, 0x00}, /* 67, 43h, 'C' */
{0x00, 0x1f, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x36, 0x1f, 0x00, 0x00}, /* 68, 44h, 'D' */
{0x00, 0x7f, 0x46, 0x06, 0x26, 0x3e, 0x26, 0x06, 0x46, 0x7f, 0x00, 0x00}, /* 69, 45h, 'E' */
{0x00, 0x7f, 0x66, 0x46, 0x26, 0x3e, 0x26, 0x06, 0x06, 0x0f, 0x00, 0x00}, /* 70, 46h, 'F' */
{0x00, 0x3c, 0x66, 0x63, 0x03, 0x03, 0x73, 0x63, 0x66, 0x7c, 0x00, 0x00}, /* 71, 47h, 'G' */
{0x00, 0x33, 0x33, 0x33, 0x33, 0x3f, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00}, /* 72, 48h, 'H' */
{0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00}, /* 73, 49h, 'I' */
{0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0x33, 0x33, 0x33, 0x1e, 0x00, 0x00}, /* 74, 4ah, 'J' */
{0x00, 0x67, 0x66, 0x36, 0x36, 0x1e, 0x36, 0x36, 0x66, 0x67, 0x00, 0x00}, /* 75, 4bh, 'K' */
{0x00, 0x0f, 0x06, 0x06, 0x06, 0x06, 0x46, 0x66, 0x66, 0x7f, 0x00, 0x00}, /* 76, 4ch, 'L' */
{0x00, 0x63, 0x77, 0x7f, 0x7f, 0x6b, 0x63, 0x63, 0x63, 0x63, 0x00, 0x00}, /* 77, 4dh, 'M' */
{0x00, 0x63, 0x63, 0x67, 0x6f, 0x7f, 0x7b, 0x73, 0x63, 0x63, 0x00, 0x00}, /* 78, 4eh, 'N' */
{0x00, 0x1c, 0x36, 0x63, 0x63, 0x63, 0x63, 0x63, 0x36, 0x1c, 0x00, 0x00}, /* 79, 4fh, 'O' */
{0x00, 0x3f, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x06, 0x06, 0x0f, 0x00, 0x00}, /* 80, 50h, 'P' */
{0x00, 0x1c, 0x36, 0x63, 0x63, 0x63, 0x73, 0x7b, 0x3e, 0x30, 0x78, 0x00}, /* 81, 51h, 'Q' */
{0x00, 0x3f, 0x66, 0x66, 0x66, 0x3e, 0x36, 0x66, 0x66, 0x67, 0x00, 0x00}, /* 82, 52h, 'R' */
{0x00, 0x1e, 0x33, 0x33, 0x03, 0x0e, 0x18, 0x33, 0x33, 0x1e, 0x00, 0x00}, /* 83, 53h, 'S' */
{0x00, 0x3f, 0x2d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00}, /* 84, 54h, 'T' */
{0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x1e, 0x00, 0x00}, /* 85, 55h, 'U' */
{0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x1e, 0x0c, 0x00, 0x00}, /* 86, 56h, 'V' */
{0x00, 0x63, 0x63, 0x63, 0x63, 0x6b, 0x6b, 0x36, 0x36, 0x36, 0x00, 0x00}, /* 87, 57h, 'W' */
{0x00, 0x33, 0x33, 0x33, 0x1e, 0x0c, 0x1e, 0x33, 0x33, 0x33, 0x00, 0x00}, /* 88, 58h, 'X' */
{0x00, 0x33, 0x33, 0x33, 0x33, 0x1e, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00}, /* 89, 59h, 'Y' */
{0x00, 0x7f, 0x73, 0x19, 0x18, 0x0c, 0x06, 0x46, 0x63, 0x7f, 0x00, 0x00}, /* 90, 5ah, 'Z' */
{0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00}, /* 91, 5bh, '[' */
{0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x40, 0x00, 0x00}, /* 92, 5ch, '\' */
{0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00}, /* 93, 5dh, ']' */
{0x08, 0x1c, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 94, 5eh, '^' */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00}, /* 95, 5fh, '_' */
{0x0c, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 96, 60h, '`' */
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x3e, 0x33, 0x33, 0x6e, 0x00, 0x00}, /* 97, 61h, 'a' */
{0x00, 0x07, 0x06, 0x06, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3b, 0x00, 0x00}, /* 98, 62h, 'b' */
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x33, 0x03, 0x03, 0x33, 0x1e, 0x00, 0x00}, /* 99, 63h, 'c' */
{0x00, 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00}, /* 100, 64h, 'd' */
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x33, 0x3f, 0x03, 0x33, 0x1e, 0x00, 0x00}, /* 101, 65h, 'e' */
{0x00, 0x1c, 0x36, 0x06, 0x06, 0x1f, 0x06, 0x06, 0x06, 0x0f, 0x00, 0x00}, /* 102, 66h, 'f' */
{0x00, 0x00, 0x00, 0x00, 0x6e, 0x33, 0x33, 0x33, 0x3e, 0x30, 0x33, 0x1e}, /* 103, 67h, 'g' */
{0x00, 0x07, 0x06, 0x06, 0x36, 0x6e, 0x66, 0x66, 0x66, 0x67, 0x00, 0x00}, /* 104, 68h, 'h' */
{0x00, 0x18, 0x18, 0x00, 0x1e, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00}, /* 105, 69h, 'i' */
{0x00, 0x30, 0x30, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1e}, /* 106, 6ah, 'j' */
{0x00, 0x07, 0x06, 0x06, 0x66, 0x36, 0x1e, 0x36, 0x66, 0x67, 0x00, 0x00}, /* 107, 6bh, 'k' */
{0x00, 0x1e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00}, /* 108, 6ch, 'l' */
{0x00, 0x00, 0x00, 0x00, 0x3f, 0x6b, 0x6b, 0x6b, 0x6b, 0x63, 0x00, 0x00}, /* 109, 6dh, 'm' */
{0x00, 0x00, 0x00, 0x00, 0x1f, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00}, /* 110, 6eh, 'n' */
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x33, 0x33, 0x33, 0x33, 0x1e, 0x00, 0x00}, /* 111, 6fh, 'o' */
{0x00, 0x00, 0x00, 0x00, 0x3b, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x0f}, /* 112, 70h, 'p' */
{0x00, 0x00, 0x00, 0x00, 0x6e, 0x33, 0x33, 0x33, 0x33, 0x3e, 0x30, 0x78}, /* 113, 71h, 'q' */
{0x00, 0x00, 0x00, 0x00, 0x37, 0x76, 0x6e, 0x06, 0x06, 0x0f, 0x00, 0x00}, /* 114, 72h, 'r' */
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x33, 0x06, 0x18, 0x33, 0x1e, 0x00, 0x00}, /* 115, 73h, 's' */
{0x00, 0x00, 0x04, 0x06, 0x3f, 0x06, 0x06, 0x06, 0x36, 0x1c, 0x00, 0x00}, /* 116, 74h, 't' */
{0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00}, /* 117, 75h, 'u' */
{0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x1e, 0x0c, 0x00, 0x00}, /* 118, 76h, 'v' */
{0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x6b, 0x6b, 0x36, 0x36, 0x00, 0x00}, /* 119, 77h, 'w' */
{0x00, 0x00, 0x00, 0x00, 0x63, 0x36, 0x1c, 0x1c, 0x36, 0x63, 0x00, 0x00}, /* 120, 78h, 'x' */
{0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x30, 0x18, 0x0f}, /* 121, 79h, 'y' */
{0x00, 0x00, 0x00, 0x00, 0x3f, 0x31, 0x18, 0x06, 0x23, 0x3f, 0x00, 0x00}, /* 122, 7ah, 'z' */
{0x00, 0x38, 0x0c, 0x0c, 0x06, 0x03, 0x06, 0x0c, 0x0c, 0x38, 0x00, 0x00}, /* 123, 7bh, '{' */
{0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00}, /* 124, 7ch, '|' */
{0x00, 0x07, 0x0c, 0x0c, 0x18, 0x30, 0x18, 0x0c, 0x0c, 0x07, 0x00, 0x00}, /* 125, 7dh, '}' */
{0x00, 0xce, 0x5b, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 126, 7eh, '~' */
{0x00, 0x00, 0x00, 0x08, 0x1c, 0x36, 0x63, 0x63, 0x7f, 0x00, 0x00, 0x00}, /* 127, 7fh, '' */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 128, 80h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 129, 81h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 130, 82h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 131, 83h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 132, 84h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 133, 85h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 134, 86h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 135, 87h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 136, 88h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 137, 89h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 138, 8ah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 139, 8bh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 140, 8ch */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 141, 8dh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 142, 8eh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 143, 8fh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 144, 90h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 145, 91h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 146, 92h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 147, 93h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 148, 94h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 149, 95h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 150, 96h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 151, 97h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 152, 98h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 153, 99h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 154, 9ah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 155, 9bh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 156, 9ch */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 157, 9dh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 158, 9eh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 159, 9fh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 160, a0h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 161, a1h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 162, a2h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 163, a3h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 164, a4h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 165, a5h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 166, a6h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 167, a7h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 168, a8h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 169, a9h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 170, aah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 171, abh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 172, ach */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 173, adh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 174, aeh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 175, afh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 176, b0h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 177, b1h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 178, b2h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 179, b3h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 180, b4h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 181, b5h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 182, b6h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 183, b7h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 184, b8h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 185, b9h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 186, bah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 187, bbh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 188, bch */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 189, bdh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 190, beh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 191, bfh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 192, c0h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 193, c1h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 194, c2h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 195, c3h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 196, c4h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 197, c5h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 198, c6h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 199, c7h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 200, c8h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 201, c9h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 202, cah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 203, cbh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 204, cch */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 205, cdh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 206, ceh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 207, cfh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 208, d0h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 209, d1h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 210, d2h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 211, d3h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 212, d4h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 213, d5h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 214, d6h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 215, d7h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 216, d8h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 217, d9h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 218, dah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 219, dbh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 220, dch */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 221, ddh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 222, deh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 223, dfh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 224, e0h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 225, e1h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 226, e2h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 227, e3h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 228, e4h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 229, e5h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 230, e6h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 231, e7h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 232, e8h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 233, e9h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 234, eah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 235, ebh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 236, ech */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 237, edh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 238, eeh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 239, efh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 240, f0h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 241, f1h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 242, f2h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 243, f3h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 244, f4h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 245, f5h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 246, f6h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 247, f7h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 248, f8h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 249, f9h */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 250, fah */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 251, fbh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 252, fch */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 253, fdh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 254, feh */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
}; /* 255, ffh */
 
#endif /* CRT_ENABLED */
/string.c
32,13 → 32,13
*/
size_t strlen(const char *s)
{
size_t cnt = 0;
size_t cnt = 0;
 
/* count the length of string s, not including the \0 character */
while (*s++)
cnt++;
/* count the length of string s, not including the \0 character */
while (*s++)
cnt++;
 
return cnt;
return cnt;
}
 
/*
48,217 → 48,198
*/
char *strcpy(char *dest, const char *src)
{
char *d = dest;
char *d = dest;
 
/* copy src to dest */
while ( (*dest++ = *src++) )
;
/* copy src to dest */
while ((*dest++ = *src++)) ;
 
return d;
return d;
}
 
 
char *strncpy(char *dest, const char *src, size_t n)
{
char *d = dest;
char *d = dest;
 
/* copy src to dest */
while ( *src && n ) {
*dest++ = *src++;
n--;
}
/* copy src to dest */
while (*src && n) {
*dest++ = *src++;
n--;
}
 
/* fill the remainder of d with nulls */
while (n--)
*dest++ = '\0';
/* fill the remainder of d with nulls */
while (n--)
*dest++ = '\0';
 
return d;
return d;
}
 
 
char *strcat(char *dest, const char *src)
{
char *d = dest;
char *d = dest;
 
/* find the end of the destination string */
while (*dest++)
;
/* find the end of the destination string */
while (*dest++) ;
 
/* append the source string to the destination string */
while ( (*dest++ = *src++) )
;
/* append the source string to the destination string */
while ((*dest++ = *src++)) ;
 
return d;
return d;
}
 
 
char *strncat(char *dest, const char *src, size_t n)
{
char *d = dest;
char *d = dest;
 
/* find the end of the destination string */
while (*dest++)
;
/* find the end of the destination string */
while (*dest++) ;
 
/* copy src to dest */
while ( (*dest = *src) && n-- ) {
dest++;
src++;
}
/* copy src to dest */
while ((*dest = *src) && n--) {
dest++;
src++;
}
 
/* add terminating '\0' character */
*dest = '\0';
 
/* add terminating '\0' character */
*dest = '\0';
 
return d;
return d;
}
 
 
int strcmp(const char *s1, const char *s2)
{
while ( *s1 && (*s1 == *s2) ) {
s1++;
s2++;
}
while (*s1 && (*s1 == *s2)) {
s1++;
s2++;
}
 
return *s1 - *s2;
return *s1 - *s2;
}
 
 
int strncmp(const char *s1, const char *s2, size_t n)
{
while ( *s1 && (*s1 == *s2) && n-- ) {
s1++;
s2++;
}
while (*s1 && (*s1 == *s2) && n--) {
s1++;
s2++;
}
 
return *s1 - *s2;
return *s1 - *s2;
}
 
 
char *strchr(const char *s, int c)
{
/* search for the character c */
while (*s && (*s != c) )
s++;
/* search for the character c */
while (*s && (*s != c))
s++;
 
return (char *)s;
return (char *)s;
}
 
 
char *strrchr(const char *s, int c)
{
char *fnd = NULL;
char *fnd = NULL;
 
/* search for the character c */
while (*s) {
if (*s == c)
fnd = (char *)s;
s++;
}
/* search for the character c */
while (*s) {
if (*s == c)
fnd = (char *)s;
s++;
}
 
return fnd;
return fnd;
}
 
 
/* Basic mem functions */
void *memcpy(void *dest, const void *src, size_t n)
{
/* check if 'src' and 'dest' are on LONG boundaries */
if ( (sizeof(unsigned long) -1) & ((unsigned long)dest | (unsigned long)src) )
{
/* no, do a byte-wide copy */
char *cs = (char *) src;
char *cd = (char *) dest;
/* check if 'src' and 'dest' are on LONG boundaries */
if ((sizeof(unsigned long) -
1) & ((unsigned long)dest | (unsigned long)src)) {
/* no, do a byte-wide copy */
char *cs = (char *)src;
char *cd = (char *)dest;
 
while (n--)
*cd++ = *cs++;
}
else
{
/* yes, speed up copy process */
/* copy as many LONGs as possible */
long *ls = (long *)src;
long *ld = (long *)dest;
while (n--)
*cd++ = *cs++;
} else {
/* yes, speed up copy process */
/* copy as many LONGs as possible */
long *ls = (long *)src;
long *ld = (long *)dest;
 
size_t cnt = n >> 2;
while (cnt--)
*ld++ = *ls++;
size_t cnt = n >> 2;
while (cnt--)
*ld++ = *ls++;
 
/* finally copy the remaining bytes */
char *cs = (char *) (src + (n & ~0x03));
char *cd = (char *) (dest + (n & ~0x03));
/* finally copy the remaining bytes */
char *cs = (char *)(src + (n & ~0x03));
char *cd = (char *)(dest + (n & ~0x03));
 
cnt = n & 0x3;
while (cnt--)
*cd++ = *cs++;
}
cnt = n & 0x3;
while (cnt--)
*cd++ = *cs++;
}
 
return dest;
return dest;
}
 
/* memcpy, return checksum of bytes copied instead of pointer to dest */
unsigned char memcpy_crc(void *dest, const void *src, size_t n)
{
unsigned char sum = 0;
unsigned char tmp;
unsigned char sum = 0;
unsigned char tmp;
 
char *cs = (char *) src;
char *cd = (char *) dest;
while (n--)
{
tmp = *cs++;
sum += tmp;
*cd++ = tmp;
}
return sum;
char *cs = (char *)src;
char *cd = (char *)dest;
 
while (n--) {
tmp = *cs++;
sum += tmp;
*cd++ = tmp;
}
return sum;
}
 
void *memmove(void *dest, void *src, size_t n)
{
char *d = dest;
char *s = src;
char *d = dest;
char *s = src;
 
while (n--)
*d++ = *s++;
while (n--)
*d++ = *s++;
 
return dest;
return dest;
}
 
 
int memcmp(const void *s1, const void *s2, size_t n)
{
char *p1 = (void *)s1;
char *p2 = (void *)s2;
char *p1 = (void *)s1;
char *p2 = (void *)s2;
 
while ( (*p1 == *p2) && n-- ) {
p1++;
p2++;
}
while ((*p1 == *p2) && n--) {
p1++;
p2++;
}
 
return *p1 - *p2;
return *p1 - *p2;
}
 
 
void *memchr(const void *s, char c, size_t n)
{
char *p = (void *)s;
char *p = (void *)s;
 
/* search for the character c */
while ( (*p != c) && n-- )
p++;
/* search for the character c */
while ((*p != c) && n--)
p++;
 
return (*p == c) ? p : NULL;
return (*p == c) ? p : NULL;
}
 
 
void *memset(void *s, int c, size_t n)
{
char *p = s;
char *p = s;
 
while (n--)
*p++ = c;
while (n--)
*p++ = c;
 
return s;
return s;
}
/spincursor.c
4,52 → 4,49
 
int spin_cursor_enabled = 0;
 
 
void enable_spincursor(void)
{
spin_cursor_enabled = 1;
spin_cursor_enabled = 1;
}
 
 
void disable_spincursor(void)
{
spin_cursor_enabled = 0;
spin_cursor_enabled = 0;
 
}
 
void spincursor(void)
{
static int last_spin_char = 0;
static int last_spin_ticks = 0;
if (!spin_cursor_enabled)
return;
if ((get_timer(0) - last_spin_ticks) < (TICKS_PER_US*2000))
return;
// Put a backspace
uart_putc(0x8);
if (last_spin_char == 0)
uart_putc("/");
else if (last_spin_char == 1)
uart_putc("-");
else if (last_spin_char == 2)
uart_putc("\\");
else if (last_spin_char == 3)
uart_putc("|");
else if (last_spin_char == 4)
uart_putc("/");
else if (last_spin_char == 5)
uart_putc("-");
else if (last_spin_char == 6)
uart_putc("\\");
else if (last_spin_char == 7)
{
uart_putc("|");
last_spin_char=-1;
}
last_spin_char++;
last_spin_ticks = get_timer(0);
static int last_spin_char = 0;
static int last_spin_ticks = 0;
 
if (!spin_cursor_enabled)
return;
 
if ((get_timer(0) - last_spin_ticks) < (TICKS_PER_US * 2000))
return;
 
// Put a backspace
uart_putc(0x8);
if (last_spin_char == 0)
uart_putc("/");
else if (last_spin_char == 1)
uart_putc("-");
else if (last_spin_char == 2)
uart_putc("\\");
else if (last_spin_char == 3)
uart_putc("|");
else if (last_spin_char == 4)
uart_putc("/");
else if (last_spin_char == 5)
uart_putc("-");
else if (last_spin_char == 6)
uart_putc("\\");
else if (last_spin_char == 7) {
uart_putc("|");
last_spin_char = -1;
}
 
last_spin_char++;
last_spin_ticks = get_timer(0);
}
/common.c
20,182 → 20,186
 
command_struct command[MAX_COMMANDS];
 
void putc (const char c)
void putc(const char c)
{
debug ("putc %i, %i = %c\n", bd.bi_console_type, c, c);
switch (bd.bi_console_type) {
case CT_NONE:
break;
case CT_UART:
uart_putc (c);
break;
debug("putc %i, %i = %c\n", bd.bi_console_type, c, c);
switch (bd.bi_console_type) {
case CT_NONE:
break;
case CT_UART:
uart_putc(c);
break;
#if CRT_ENABLED==1
case CT_CRT:
screen_putc (c);
break;
case CT_CRT:
screen_putc(c);
break;
#endif
case CT_SIM:
__printf ("%c", c);
break;
}
case CT_SIM:
__printf("%c", c);
break;
}
}
 
int getc ()
int getc()
{
int ch = 0;
debug ("getc %i\n", bd.bi_console_type);
switch (bd.bi_console_type) {
int ch = 0;
debug("getc %i\n", bd.bi_console_type);
switch (bd.bi_console_type) {
#if KBD_ENABLED==1
case CT_CRT:
while ((volatile int)kbd_head == (volatile int)kbd_tail);
ch = kbd_buf[kbd_tail];
kbd_tail = (kbd_tail + 1) % KBDBUF_SIZE;
return ch;
case CT_CRT:
while ((volatile int)kbd_head == (volatile int)kbd_tail) ;
ch = kbd_buf[kbd_tail];
kbd_tail = (kbd_tail + 1) % KBDBUF_SIZE;
return ch;
#endif
case CT_UART:
return uart_getc ();
break;
case CT_NONE: /* just to satisfy the compiler */
case CT_SIM:
break;
}
return -1;
case CT_UART:
return uart_getc();
break;
case CT_NONE: /* just to satisfy the compiler */
case CT_SIM:
break;
}
return -1;
}
 
int testc ()
int testc()
{
debug ("testc %i\n", bd.bi_console_type);
switch (bd.bi_console_type) {
debug("testc %i\n", bd.bi_console_type);
switch (bd.bi_console_type) {
#if KBD_ENABLED
case CT_CRT:
if (kbd_head == kbd_tail) return 0;
else return getc ();
case CT_CRT:
if (kbd_head == kbd_tail)
return 0;
else
return getc();
#endif
case CT_UART:
return uart_testc ();
break;
case CT_NONE: /* just to satisfy the compiler */
case CT_SIM:
break;
}
return -1;
case CT_UART:
return uart_testc();
break;
case CT_NONE: /* just to satisfy the compiler */
case CT_SIM:
break;
}
return -1;
}
 
int ctrlc ()
int ctrlc()
{
if (testc ()) {
switch (getc ()) {
case 0x03: /* ^C - Control C */
return 1;
default:
break;
}
}
return 0;
if (testc()) {
switch (getc()) {
case 0x03: /* ^C - Control C */
return 1;
default:
break;
}
}
return 0;
}
 
void
print_or1k_cache_info()
void print_or1k_cache_info()
{
// Read out UPR, check what modules we have
unsigned long upr = mfspr(SPR_UPR);
printf("Instruction cache:\t");
if (upr & SPR_UPR_ICP)
{
// We have instruction cache, read out ICCFGR
unsigned long iccfgr = mfspr(SPR_ICCFGR);
unsigned int cbs; // cache block size
unsigned long ncs = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
if (iccfgr & SPR_ICCFGR_CBS)
cbs = 32;
else
cbs = 16;
// Read out UPR, check what modules we have
unsigned long upr = mfspr(SPR_UPR);
printf("Instruction cache:\t");
if (upr & SPR_UPR_ICP) {
// We have instruction cache, read out ICCFGR
 
printf("%dkB (BS: %d Sets: %d)\n",
(cbs * ncs)/1024, cbs, ncs);
}
else
printf(" not present\n");
unsigned long iccfgr = mfspr(SPR_ICCFGR);
unsigned int cbs; // cache block size
unsigned long ncs = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
if (iccfgr & SPR_ICCFGR_CBS)
cbs = 32;
else
cbs = 16;
 
printf("Data cache:\t\t");
if (upr & SPR_UPR_DCP)
{
// We have instruction cache, read out DCCFGR
unsigned long iccfgr = mfspr(SPR_DCCFGR);
unsigned int cbs; // cache block size
unsigned long ncs = 1 << ((iccfgr & SPR_DCCFGR_NCS) >> 3);
if (iccfgr & SPR_DCCFGR_CBS)
cbs = 32;
else
cbs = 16;
printf("%dkB (BS: %d Sets: %d)\n",
(cbs * ncs) / 1024, cbs, ncs);
 
printf("%dkB (BS: %d Sets: %d)\n",
(cbs * ncs)/1024, cbs, ncs);
}
else
printf(" not present\n");
} else
printf(" not present\n");
 
printf("Data cache:\t\t");
if (upr & SPR_UPR_DCP) {
// We have instruction cache, read out DCCFGR
 
unsigned long iccfgr = mfspr(SPR_DCCFGR);
unsigned int cbs; // cache block size
unsigned long ncs = 1 << ((iccfgr & SPR_DCCFGR_NCS) >> 3);
if (iccfgr & SPR_DCCFGR_CBS)
cbs = 32;
else
cbs = 16;
 
printf("%dkB (BS: %d Sets: %d)\n",
(cbs * ncs) / 1024, cbs, ncs);
 
} else
printf(" not present\n");
 
}
 
unsigned long parse_ip (char *ip)
unsigned long parse_ip(char *ip)
{
unsigned long num;
num = strtoul (ip, &ip, 10) & 0xff;
if (*ip++ != '.') return 0;
num = (num << 8) | (strtoul (ip, &ip, 10) & 0xff);
if (*ip++ != '.') return 0;
num = (num << 8) | (strtoul (ip, &ip, 10) & 0xff);
if (*ip++ != '.') return 0;
num = (num << 8) | (strtoul (ip, &ip, 10) & 0xff);
return num;
unsigned long num;
num = strtoul(ip, &ip, 10) & 0xff;
if (*ip++ != '.')
return 0;
num = (num << 8) | (strtoul(ip, &ip, 10) & 0xff);
if (*ip++ != '.')
return 0;
num = (num << 8) | (strtoul(ip, &ip, 10) & 0xff);
if (*ip++ != '.')
return 0;
num = (num << 8) | (strtoul(ip, &ip, 10) & 0xff);
return num;
}
 
void change_console_type (enum bi_console_type_t con_type)
void change_console_type(enum bi_console_type_t con_type)
{
debug ("Console change %i -> %i\n", bd.bi_console_type, con_type);
/* Close previous */
switch (bd.bi_console_type) {
case CT_NONE:
case CT_UART:
case CT_CRT:
case CT_SIM:
break;
}
bd.bi_console_type = con_type;
/* Initialize new */
switch (bd.bi_console_type) {
case CT_NONE:
break;
case CT_UART:
uart_init ();
break;
case CT_CRT:
debug("Console change %i -> %i\n", bd.bi_console_type, con_type);
/* Close previous */
switch (bd.bi_console_type) {
case CT_NONE:
case CT_UART:
case CT_CRT:
case CT_SIM:
break;
}
bd.bi_console_type = con_type;
/* Initialize new */
switch (bd.bi_console_type) {
case CT_NONE:
break;
case CT_UART:
uart_init();
break;
case CT_CRT:
#if CRT_ENABLED==1
screen_init ();
screen_init();
#endif
#if KBD_ENABLED
kbd_init ();
kbd_init();
#endif
break;
case CT_SIM:
break;
}
break;
case CT_SIM:
break;
}
}
 
void register_command_func (const char *name, const char *params, const char *help, int (*func)(int argc, char *argv[]))
void register_command_func(const char *name, const char *params,
const char *help, int (*func) (int argc,
char *argv[]))
{
debug ("register_command '%s'\n", name);
if (num_commands < MAX_COMMANDS) {
command[num_commands].name = name;
command[num_commands].params = params;
command[num_commands].help = help;
command[num_commands].func = func;
num_commands++;
} else printf ("Command '%s' ignored; MAX_COMMANDS limit reached\n", name);
debug("register_command '%s'\n", name);
if (num_commands < MAX_COMMANDS) {
command[num_commands].name = name;
command[num_commands].params = params;
command[num_commands].help = help;
command[num_commands].func = func;
num_commands++;
} else
printf("Command '%s' ignored; MAX_COMMANDS limit reached\n",
name);
}
 
/* Process command and arguments by executing
202,192 → 206,188
specific function. */
void mon_command(void)
{
char c = '\0';
char str[1000];
char *pstr = str;
char *command_str;
char *argv[20];
int argc = 0;
int chcnt = 0;
char c = '\0';
char str[1000];
char *pstr = str;
char *command_str;
char *argv[20];
int argc = 0;
int chcnt = 0;
 
/* Show prompt */
printf ("\n" BOARD_DEF_NAME"> ");
/* Show prompt */
printf("\n" BOARD_DEF_NAME "> ");
 
while(1)
{
c=getc();
while (1) {
c = getc();
 
if (c == 0x7f) // Backspace on picocom is showing up as 0x7f
c = '\b';
if (c == 0x7f) // Backspace on picocom is showing up as 0x7f
c = '\b';
 
if (c == '\r' || c == '\f' || c == '\n')
{
// Mark end of string
*pstr = '\0';
putc('\n');
break;
if (c == '\r' || c == '\f' || c == '\n') {
// Mark end of string
*pstr = '\0';
putc('\n');
break;
} else if (c == '\b') // Backspace
{
if (chcnt > 0) {
putc(c);
putc(' '); // cover char with space
putc(c);
pstr--;
chcnt--;
}
} else {
putc(c);
*pstr++ = c;
chcnt++;
}
}
else if (c == '\b') // Backspace
{
if (chcnt > 0)
{
putc(c);
putc(' '); // cover char with space
putc(c);
pstr--;
chcnt--;
}
}
else
{
putc(c);
*pstr++ = c;
chcnt++;
}
}
 
/* Skip leading blanks */
pstr = str;
while (*pstr == ' ' && *pstr != '\0') pstr++;
/* Skip leading blanks */
pstr = str;
while (*pstr == ' ' && *pstr != '\0')
pstr++;
 
/* Get command from the string */
command_str = pstr;
/* Get command from the string */
command_str = pstr;
 
while (1) {
/* Go to next argument */
while (*pstr != ' ' && *pstr != '\0') pstr++;
if (*pstr) {
*pstr++ = '\0';
while (*pstr == ' ') pstr++;
argv[argc++] = pstr;
}
else
break;
}
while (1) {
/* Go to next argument */
while (*pstr != ' ' && *pstr != '\0')
pstr++;
if (*pstr) {
*pstr++ = '\0';
while (*pstr == ' ')
pstr++;
argv[argc++] = pstr;
} else
break;
}
 
{
int i, found = 0;
{
int i, found = 0;
 
for (i = 0; i < num_commands; i++)
if (strcmp (command_str, command[i].name) == 0)
{
switch ( command[i].func(argc, &argv[0]) )
{
case -1:
printf ("Missing/wrong parameters, usage: %s %s\n",
command[i].name, command[i].params);
break;
}
for (i = 0; i < num_commands; i++)
if (strcmp(command_str, command[i].name) == 0) {
switch (command[i].func(argc, &argv[0])) {
case -1:
printf
("Missing/wrong parameters, usage: %s %s\n",
command[i].name,
command[i].params);
break;
}
 
found++;
break;
}
/* 'built-in' build command */
if(strcmp(command_str, "build") == 0) {
printf("Build tag: %s", BUILD_VERSION);
found++;
}
if (!found)
printf ("Unknown command. Type 'help' for help.\n");
}
found++;
break;
}
/* 'built-in' build command */
if (strcmp(command_str, "build") == 0) {
printf("Build tag: %s", BUILD_VERSION);
found++;
}
if (!found)
printf("Unknown command. Type 'help' for help.\n");
}
 
}
 
#if HELP_ENABLED
extern unsigned long _src_addr; // Stack section ends here, will print it out
extern unsigned long _src_addr; // Stack section ends here, will print it out
/* Displays help screen */
int help_cmd (int argc, char *argv[])
int help_cmd(int argc, char *argv[])
{
int i;
for (i = 0; i < num_commands; i++)
printf ("%-10s %-20s - %s\n", command[i].name, command[i].params, command[i].help);
int i;
for (i = 0; i < num_commands; i++)
printf("%-10s %-20s - %s\n", command[i].name, command[i].params,
command[i].help);
 
// Build info....
printf("\n");
printf("CPU info\n");
printf("Frequency\t\t%dMHz\n", IN_CLK/1000000);
print_or1k_cache_info();
printf("\n");
printf("Info: Stack section addr 0x%x\n",(unsigned long) &_src_addr);
printf("Build tag: %s", BUILD_VERSION);
// Build info....
printf("\n");
printf("CPU info\n");
printf("Frequency\t\t%dMHz\n", IN_CLK / 1000000);
print_or1k_cache_info();
printf("\n");
printf("Info: Stack section addr 0x%x\n", (unsigned long)&_src_addr);
printf("Build tag: %s", BUILD_VERSION);
 
return 0;
return 0;
}
#endif /* HELP_ENABLED */
 
void module_cpu_init (void);
void module_memory_init (void);
void module_eth_init (void);
void module_dhry_init (void);
void module_coremark_init (void);
void module_camera_init (void);
void module_load_init (void);
void module_cpu_init(void);
void module_memory_init(void);
void module_eth_init(void);
void module_dhry_init(void);
void module_coremark_init(void);
void module_camera_init(void);
void module_load_init(void);
void tick_init(void);
void module_touch_init (void);
void module_ata_init (void);
void module_hdbug_init (void);
void module_touch_init(void);
void module_ata_init(void);
void module_hdbug_init(void);
 
 
/* List of all initializations */
void mon_init (void)
void mon_init(void)
{
/* Set defaults */
global.erase_method = 2; /* as needed */
global.src_addr = (unsigned long)&_src_addr;
global.dst_addr = FLASH_BASE_ADDR;
global.eth_add[0] = ETH_MACADDR0;
global.eth_add[1] = ETH_MACADDR1;
global.eth_add[2] = ETH_MACADDR2;
global.eth_add[3] = ETH_MACADDR3;
global.eth_add[4] = ETH_MACADDR4;
global.eth_add[5] = ETH_MACADDR5;
global.ip = BOARD_DEF_IP;
global.gw_ip = BOARD_DEF_GW;
global.mask = BOARD_DEF_MASK;
/* Set defaults */
global.erase_method = 2; /* as needed */
global.src_addr = (unsigned long)&_src_addr;
global.dst_addr = FLASH_BASE_ADDR;
global.eth_add[0] = ETH_MACADDR0;
global.eth_add[1] = ETH_MACADDR1;
global.eth_add[2] = ETH_MACADDR2;
global.eth_add[3] = ETH_MACADDR3;
global.eth_add[4] = ETH_MACADDR4;
global.eth_add[5] = ETH_MACADDR5;
global.ip = BOARD_DEF_IP;
global.gw_ip = BOARD_DEF_GW;
global.mask = BOARD_DEF_MASK;
 
#define CPU_CMDS
#define MEM_CMDS
#define DHRY_CMDS
#define COREMARK_CMDS
//#define CAMERA_CMDS
//#define CAMERA_CMDS
#define LOAD_CMDS
//#define TOUCHSCREEN_CMDS
//#define ATA_CMDS
//#define HDBUG_CMDS
//#define TOUCHSCREEN_CMDS
//#define ATA_CMDS
//#define HDBUG_CMDS
#define TICK_CMDS
#define ETH_CMDS
#define LOAD_CMDS
/* Init modules */
 
/* Init modules */
#ifdef CPU_CMDS
module_cpu_init ();
module_cpu_init();
#endif
#ifdef MEM_CMDS
module_memory_init ();
module_memory_init();
#endif
#ifdef ETH_CMDS
module_eth_init ();
module_eth_init();
#endif
#ifdef DHRY_CMDS
module_dhry_init ();
module_dhry_init();
#endif
#ifdef COREMARK_CMDS
module_coremark_init ();
module_coremark_init();
#endif
#ifdef CAMERA_CMDS
module_camera_init ();
module_camera_init();
#endif
#ifdef LOAD_CMDS
module_load_init ();
module_load_init();
#endif
#ifdef TOUCHSCREEN_CMDS
module_touch_init ();
module_touch_init();
#endif
#ifdef ATA_CMDS
module_ata_init ();
module_ata_init();
#endif
#ifdef HDBUG_CMDS
module_hdbug_init ();
module_hdbug_init();
#endif
 
#ifdef TICK_CMDS
394,49 → 394,49
#endif
 
}
int tboot_cmd (int argc, char *argv[]);
 
int tboot_cmd(int argc, char *argv[]);
/* Main shell loop */
int main(int argc, char **argv)
{
extern unsigned long calc_mycrc32 (void);
extern unsigned long calc_mycrc32(void);
 
#if 0
extern unsigned long mycrc32, mysize;
extern unsigned long mycrc32, mysize;
#endif
 
timestamp = 0; // clear timer counter
int_init ();
timestamp = 0; // clear timer counter
 
change_console_type (CONSOLE_TYPE);
int_init();
 
mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE);
change_console_type(CONSOLE_TYPE);
 
mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE);
 
#if SELF_CHECK
printf ("Self check... ");
if ((t = calc_mycrc32 ()))
printf ("FAILED!!!\n");
else
printf ("OK\n");
printf("Self check... ");
if ((t = calc_mycrc32()))
printf("FAILED!!!\n");
else
printf("OK\n");
#endif /* SELF_CHECK */
 
num_commands=0;
mon_init ();
num_commands = 0;
mon_init();
 
disable_spincursor();
tick_init();
disable_spincursor();
 
tick_init();
 
if (HELP_ENABLED) register_command ("help", "", "shows this help", help_cmd);
if (HELP_ENABLED)
register_command("help", "", "shows this help", help_cmd);
 
printf ("\n" BOARD_DEF_NAME " monitor (type 'help' for help)\n");
printf("\tbuild: %s", BUILD_VERSION);
printf("\n" BOARD_DEF_NAME " monitor (type 'help' for help)\n");
printf("\tbuild: %s", BUILD_VERSION);
 
// Loop forever, accepting commands
while(1)
{
mon_command();
}
// Loop forever, accepting commands
while (1) {
mon_command();
}
 
}
/support.c
12,11 → 12,11
void int_main(void);
 
/* return value by making a syscall */
void exit (int i)
void exit(int i)
{
asm("l.add r3,r0,%0": : "r" (i));
asm("l.nop %0": :"K" (NOP_EXIT));
while (1);
asm("l.add r3,r0,%0": :"r"(i));
asm("l.nop %0": :"K"(NOP_EXIT));
while (1) ;
}
 
/* activate printf support in simulator */
23,11 → 23,11
void __printf(const char *fmt, ...)
{
#if 0
va_list args;
va_start(args, fmt);
__asm__ __volatile__ (" l.addi\tr3,%1,0\n \
va_list args;
va_start(args, fmt);
__asm__ __volatile__(" l.addi\tr3,%1,0\n \
l.addi\tr4,%2,0\n \
l.nop %0": :"K" (NOP_PRINTF), "r" (fmt), "r" (args) : "r3", "r4");
l.nop %0"::"K"(NOP_PRINTF), "r"(fmt), "r"(args):"r3", "r4");
#endif
}
 
34,8 → 34,8
/* print long */
void report(unsigned long value)
{
asm("l.addi\tr3,%0,0": :"r" (value));
asm("l.nop %0": :"K" (NOP_REPORT));
asm("l.addi\tr3,%0,0": :"r"(value));
asm("l.nop %0": :"K"(NOP_REPORT));
}
 
/* just to satisfy linker */
46,86 → 46,87
/* For writing into SPR. */
void mtspr(unsigned long spr, unsigned long value)
{
asm("l.mtspr\t\t%0,%1,0": : "r" (spr), "r" (value));
asm("l.mtspr\t\t%0,%1,0": :"r"(spr), "r"(value));
}
 
/* For reading SPR. */
unsigned long mfspr(unsigned long spr)
{
unsigned long value;
asm("l.mfspr\t\t%0,%1,0" : "=r" (value) : "r" (spr));
return value;
unsigned long value;
asm("l.mfspr\t\t%0,%1,0": "=r"(value):"r"(spr));
return value;
}
 
 
 
/* Parses hex or decimal number */
unsigned long strtoul (const char *str, char **endptr, int base)
unsigned long strtoul(const char *str, char **endptr, int base)
{
 
{
{
 
unsigned long number = 0;
char *pos = (char *) str;
char *fail_char = (char *) str;
unsigned long number = 0;
char *pos = (char *)str;
char *fail_char = (char *)str;
 
while (isspace(*pos))
pos++; /* skip leading whitespace */
 
while (isspace(*pos)) pos++; /* skip leading whitespace */
if ((base == 16) && (*pos == '0')) { /* handle option prefix */
++pos;
fail_char = pos;
if ((*pos == 'x') || (*pos == 'X'))
++pos;
}
 
if ((base == 16) && (*pos == '0')) { /* handle option prefix */
++pos;
fail_char = pos;
if ((*pos == 'x') || (*pos == 'X')) ++pos;
}
if (base == 0) { /* dynamic base */
base = 10; /* default is 10 */
if (*pos == '0') {
++pos;
base -= 2; /* now base is 8 (or 16) */
fail_char = pos;
if ((*pos == 'x') || (*pos == 'X')) {
base += 8; /* base is 16 */
++pos;
}
}
}
 
if (base == 0) { /* dynamic base */
base = 10; /* default is 10 */
if (*pos == '0') {
++pos;
base -= 2; /* now base is 8 (or 16) */
fail_char = pos;
if ((*pos == 'x') || (*pos == 'X')) {
base += 8; /* base is 16 */
++pos;
}
}
}
/* check for illegal base */
if (!((base < 2) || (base > 36)))
while (1) {
int digit = 40;
if ((*pos >= '0') && (*pos <= '9')) {
digit = (*pos - '0');
} else if (*pos >= 'a') {
digit = (*pos - 'a' + 10);
} else if (*pos >= 'A') {
digit = (*pos - 'A' + 10);
} else
break;
 
/* check for illegal base */
if ( !((base < 2) || (base > 36)) )
while (1) {
int digit = 40;
if ((*pos >= '0') && (*pos <= '9')) {
digit = (*pos - '0');
} else if (*pos >= 'a') {
digit = (*pos - 'a' + 10);
} else if (*pos >= 'A') {
digit = (*pos - 'A' + 10);
} else break;
if (digit >= base)
break;
 
if (digit >= base) break;
fail_char = ++pos;
number = number * base + digit;
}
 
fail_char = ++pos;
number = number * base + digit;
}
if (endptr)
*endptr = fail_char; {
return number;
}
}
}
 
if (endptr) *endptr = fail_char; {
return number;
}
}
}
unsigned long get_timer (unsigned long base)
unsigned long get_timer(unsigned long base)
{
/*
__printf("%s - %s: %d\n", __FILE__, __FUNCTION__, __LINE__);
__printf(" timestamp = %.8lx base = %.8lx\n", timestamp, base);
*/
return (timestamp - base);
/*
__printf("%s - %s: %d\n", __FILE__, __FUNCTION__, __LINE__);
__printf(" timestamp = %.8lx base = %.8lx\n", timestamp, base);
*/
return (timestamp - base);
}
void set_timer (unsigned long t)
 
void set_timer(unsigned long t)
{
timestamp = t;
timestamp = t;
}
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.