Renamed

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers send_pc1403.cpp Source File

send_pc1403.cpp

00001 #include "send_pc1403.h"
00002 
00003 ///////////////////////////////////////////////////////
00004 // variables from PocketTools code
00005 uint  SHCc = 0 ,      /* Read not from bin, but from Transfile PC plus SHC-format (header included) */
00006       SHCe = 0 ;      /* End marks are the SHC Basic image included only*/
00007 uint  QTc  = 0 ;      /* Write to Quick-Tape wave format */
00008 uint  STc  = 0 ;      /* Header of SuperTape or file header of PC-1600 format is in the image included */
00009 uint  TAPc = 0 ;      /* Write not to wave format but to emulator tap format (raw bytes)*/
00010 uint  Qcnt = 0 ;      /* Quiet, minimal output */
00011 uint  Scnt = 0 ;      /* Number of sync parameters or sync and sync spaces was defined */
00012 uint  Acnt = 0 ;      /* Number of address parameters, non standard load or entry addresses */
00013 uint  Mcnt = 0 ;      /* Read header parameter from a file */
00014 
00015 double  speed = 1.00 ;  /* Used it for modified Pocket Computer with a CPU Speed Up switched on */
00016 
00017 ulong  pcId  = 1500 ;  /* ID number of the pocket computer */
00018 ushort pcgrpId = IDENT_UNKNOWN ;
00019 // ulong  pcAddr = 0 ;         /* PC-specific address, used for the end of variable data of PCs with DB-tables */
00020 bool  cnvstr_upr = false ; /* Convert strings to upper, for Pokecon with SML-key not */
00021 bool  type_asm = false ;   /* Image contains assembler source code (subtype), true for CASL and CAP-X */
00022 // TODO (mr#2#): Count all warnings and errors
00023 ulong  err_cnt = 0 ;    /* counts minor errors */
00024 ulong  wrn_cnt = 0 ;    /* counts warnings */
00025 
00026 FileInfo  fileInfo ;    /* File information */
00027 
00028 ////////////////////////////////////////////////////////////////////////////////
00029 // WriteBitToWav replaced from PocketTools version (writing to a WAV file)
00030 // Here we send directly signals to OUT lines
00031 int WriteBitToWav (int   value)
00032 {
00033     // Calling the buffered bit-sending routine
00034     switch ( value ) {
00035         case 1:
00036             if  ( bitWaitSend ( value, 0 ) > MAX_BIT_TIME_ERR )
00037                 return ( ERR_NOK ) ;
00038             break;
00039         case 0:
00040             if  ( bitWaitSend ( value, 0 ) > MAX_BIT_TIME_ERR )
00041                 return ( ERR_NOK ) ;
00042             break;
00043         default:
00044             break;
00045     }
00046         
00047     return ( ERR_OK ) ;
00048 }
00049 
00050 ////////////////////////////////////////////////////////////////////////////////
00051 // Write* methods taken from Pocket-Tools source code 
00052 // https://www.peil-partner.de/ifhe.de/sharp/
00053 int WriteQuaterToWav (uint   value,
00054                       uint   stopBits)
00055 {
00056       uint  tmp ;
00057       uint  ii ;
00058        int  error ;
00059 
00060     // if (TAPc > 0) return (WriteQuaterToTap (value )); // no  
00061     
00062     do {
00063         
00064         error = WriteBitToWav (0 ) ;
00065         if (error != ERR_OK) break ;
00066 
00067         for ( ii = 0 ; ii < 4 ; ++ii ) {
00068             tmp = 1 << ii ;
00069             if ( (value & tmp) == 0 )
00070                 error = WriteBitToWav (0 ) ;
00071             else
00072                 error = WriteBitToWav (1 ) ;
00073 
00074             if (error != ERR_OK) break ;
00075         }
00076         if (error != ERR_OK) break ;
00077 
00078         for ( ii = 0 ; ii < stopBits ; ++ii ) {
00079             error = WriteBitToWav (1 ) ;
00080             if (error != ERR_OK) break ;
00081         }
00082         if (error != ERR_OK) break ;
00083 
00084     } while (0) ;
00085     return (error);
00086 }
00087 
00088 int WriteByteToWav (ulong  value,
00089                     uchar  order,
00090                     uchar  mode)
00091 {
00092       uint  lsq ;
00093       uint  msq ;
00094       int  error ;
00095 
00096     // if (TAPc > 0) return (WriteByteToTap (value, order )) ; // no  
00097 
00098     // if (order == ORDER_E) return (WriteByteToEWav (value )) ; // no  1403
00099 
00100     do {
00101         lsq = value & 0x0F ;
00102         msq = (value >> 4) & 0x0F ;
00103         if (order == ORDER_INV) {
00104             error = WriteQuaterToWav (lsq, Mode[mode].stopb1 ) ;
00105             if (error != ERR_OK) break ;
00106             error = WriteQuaterToWav (msq, Mode[mode].stopb2 ) ;
00107             if (error != ERR_OK) break ;
00108         }
00109         else {
00110             error = WriteQuaterToWav (msq, Mode[mode].stopb1 ) ;
00111             if (error != ERR_OK) break ;
00112             error = WriteQuaterToWav (lsq, Mode[mode].stopb2 ) ;
00113             if (error != ERR_OK) break ;
00114         }
00115 
00116     } while (0) ;
00117     return (error);
00118 }
00119 
00120 int CheckSumB1 (  ulong  Byte )
00121 {
00122     ushort sum ;
00123 
00124     /* Update the checksum */
00125         sum = fileInfo.sum + ((Byte & 0xF0) >> 4) ;
00126         if (sum > 0xFF) {
00127             ++sum ;
00128             sum &= 0xFF ;
00129             }
00130         fileInfo.sum = (sum + (Byte & 0x0F)) & 0xFF ;
00131 
00132     return (0);
00133 }
00134 
00135 
00136 int CheckSumE (  ulong  Byte 
00137 //               ulong*  ptrSum 
00138       )
00139 {
00140     uint tmp, ii ;
00141 
00142     /* Update the checksum */
00143     tmp = 0x80 ;
00144     for ( ii = 0 ; ii < 8 ; ++ii, tmp >>= 1 )
00145         if ( (Byte & tmp) != 0 )  
00146             // ++ *ptrSum ;
00147              ++ fileInfo.sum ;
00148 
00149     return (0);
00150 }
00151 
00152 
00153 int WriteSyncToWav (ulong  nbSync )
00154 {
00155     ulong  ii ;
00156     int    error = ERR_OK ;
00157 
00158     if (TAPc > 0) return (ERR_OK); // no
00159 
00160     do {
00161         /* Write the Synchro patern */
00162         for ( ii = 0 ; ii < nbSync ; ++ii ) {
00163             error = WriteBitToWav (1 ) ;
00164             if (error != ERR_OK) break ;
00165         }
00166         if (error != ERR_OK) break ;
00167 
00168     } while (0) ;
00169     return (error);
00170 }
00171 
00172 int WriteUsedatLenToQTWav ( uchar  order, /* Quick-Tape incomplete blocks with fill data */
00173                             uchar  mode )
00174 {   long tmpL ;
00175     int  error ;
00176 
00177     tmpL = fileInfo.nbByte - fileInfo.total_diff - fileInfo.total ; //not for IDENT_QT_DAT: variable block in RAM based
00178 
00179     if (tmpL > 0) {
00180             if (tmpL > BLK_OLD) tmpL = BLK_OLD ;
00181             --tmpL ;
00182             if (tmpL < BLK_OLD -1) fileInfo.usedat_len = tmpL + 1 ;
00183             else fileInfo.usedat_len = 0 ; /* L:0x4F ignored, no effect */
00184 
00185             error = WriteByteToWav (tmpL, order, mode ) ;
00186             if (error != ERR_OK) return (error) ;
00187             if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG (L:%02X)", (uint) tmpL);
00188 
00189             fileInfo.sum = tmpL ;
00190     }
00191     else if (tmpL == 0 ) error = ERR_OK ;
00192     else {
00193             printf(" WUsedatLQT: End of file was expected");
00194             error = ERR_FMT ;
00195     }
00196     fileInfo.count = 0 ;
00197 
00198     return (error);
00199 }
00200 
00201 int WriteByteSumToWav (ulong  value,
00202                        uchar  order,
00203                        uchar  mode)
00204 {
00205     int   error ;
00206     bool  writ_full_block = false ;
00207     
00208     do {
00209 
00210         if ( (fileInfo.debug & 0x0040) > 0)  
00211             debug_printf(" %02X", (uchar) value);
00212         error = WriteByteToWav (value, order, mode ) ;
00213         if (error != ERR_OK) break ;
00214 
00215         if (mode == MODE_B22 || mode == MODE_B11) fileInfo.sum += value ;
00216         else if (mode == MODE_B9 || mode == MODE_B10) CheckSumE (value ) ; //ptrFile
00217         else CheckSumB1 (value ) ;
00218 
00219         ++fileInfo.count ;
00220         if (!writ_full_block) ++fileInfo.total ;
00221 
00222         if ( fileInfo.usedat_len > 0) { /* QTape incomplete block */
00223             if (--fileInfo.usedat_len == 0) {
00224                 if ( ( (fileInfo.debug & 0x0040) > 0 ) && (Qcnt == 0) ) debug_printf("DEBUG Fill data:");
00225                 value = 0x00 ;
00226                 writ_full_block = true ;
00227             }
00228         }
00229 
00230         switch (mode) {
00231         case MODE_B22 :
00232             if ( fileInfo.count >= BLK_OLD ) {
00233 
00234                 if ( (fileInfo.debug & 0x0040) > 0 )
00235                     debug_printf(" (%04X)\n\r", (uint) fileInfo.sum);
00236 
00237                 /* Write the checksum */
00238                 error = WriteByteToWav (fileInfo.sum >> 8 & 0xFF, order, mode ) ;
00239                 if (error != ERR_OK) break ;
00240                 error = WriteByteToWav (fileInfo.sum & 0xFF, order, mode ) ;
00241                 if (error != ERR_OK) break ;
00242 
00243                 fileInfo.count = 0 ;
00244                 fileInfo.sum   = 0 ;
00245             }
00246             break ;
00247 
00248         case MODE_B21 :
00249         case MODE_B20 :
00250         case MODE_B19 :
00251             if ( (fileInfo.count % BLK_OLD_SUM) == 0) {
00252 
00253                 if ( (fileInfo.debug & 0x0040) > 0 )
00254                     debug_printf(" (%02X)\n\r", (uchar) fileInfo.sum);
00255 
00256                 /* Write the checksum */
00257                 error = WriteByteToWav (fileInfo.sum, order, mode ) ;
00258                 if (error != ERR_OK) break ;
00259 
00260                 if ( fileInfo.count >= BLK_OLD ) {
00261                     fileInfo.count = 0 ;
00262                     fileInfo.sum   = 0 ;
00263                     // if (pcgrpId==IDENT_PC1211) error = WriteSyncToWav (1803 ) ; //DATA not
00264                     if (fileInfo.ident == IDENT_PC1211) /* default 1803 bits, data not */
00265                         error = WriteSyncToWav (fileInfo.nbSync ) ;
00266                 }
00267             }
00268             break ;
00269 
00270         case MODE_B17 :
00271         case MODE_B16 :
00272         case MODE_B15 :
00273             if ( fileInfo.count >= BLK_OLD_SUM) {
00274 
00275                 if ( (fileInfo.debug & 0x0040) > 0 )
00276                     debug_printf(" (%02X)\n\r", (uchar) fileInfo.sum);
00277 
00278                 /* Write the checksum */
00279                 error = WriteByteToWav (fileInfo.sum, order, mode) ;
00280                 if (error != ERR_OK) break ;
00281 
00282                 fileInfo.count = 0 ;
00283                 fileInfo.sum   = 0 ;
00284             }
00285             break ;
00286 
00287         case MODE_B14 :
00288         case MODE_B13 :
00289             if ( fileInfo.count >= BLK_NEW ) {
00290 
00291                 if ( (fileInfo.debug & 0x0040) > 0 )
00292                     debug_printf(" *(%02X)", (uchar) fileInfo.sum);
00293 
00294                 /* Write the checksum */
00295                 error = WriteByteToWav (fileInfo.sum, order, mode ) ;
00296                 if (error != ERR_OK) break ;
00297 
00298                 fileInfo.count = 0 ;
00299                 fileInfo.sum   = 0 ;
00300             }
00301             break ;
00302 
00303         case MODE_B9 : /* PC-E/G/1600 */
00304             if ( fileInfo.count >= fileInfo.block_len ) {
00305 
00306                 if ( (fileInfo.debug & 0x0040) > 0 )
00307                     debug_printf(" (%04X)\n\r", (uint) fileInfo.sum & 0xFFFF);
00308 
00309                 /* Write the checksum */
00310                 error = WriteByteToWav (fileInfo.sum >> 8 & 0xFF, order, mode ) ;
00311                 if (error != ERR_OK) break ;
00312                 error = WriteByteToWav (fileInfo.sum & 0xFF, order, mode ) ;
00313                 if (error != ERR_OK) break ;
00314 
00315                 fileInfo.count = 0 ;
00316                 fileInfo.sum   = 0 ;
00317             }
00318             break ;
00319 
00320         case MODE_B10 : /* SuperTape */
00321             if ( fileInfo.count >= fileInfo.block_len ) {
00322 
00323                 if ( (fileInfo.debug & 0x0040) > 0 )
00324                     debug_printf(" (%04X)", (uint) fileInfo.sum & 0xFFFF);
00325 
00326                 /* Write the checksum */
00327                 error = WriteByteToWav (fileInfo.sum & 0xFF, order, mode ) ;
00328                 if (error != ERR_OK) break ;
00329                 error = WriteByteToWav (fileInfo.sum >> 8 & 0xFF, order, mode ) ;
00330                 if (error != ERR_OK) break ;
00331 
00332                 if ( (fileInfo.debug & 0x0040) > 0) debug_printf(" %02X", (uchar) SUPT_END);
00333                 error = WriteByteToWav (SUPT_END, order, mode ) ;
00334                 if (error != ERR_OK) break ;
00335 
00336                 fileInfo.count = 0 ;
00337                 fileInfo.sum   = 0 ;
00338             }
00339             break ;
00340 
00341         case MODE_B11 :
00342             if ( fileInfo.count >= BLK_OLD ) {
00343 
00344                 if ( (fileInfo.debug & 0x0040) > 0 )
00345                     debug_printf(" (%04X)\n\r", (uint) fileInfo.sum);
00346                 /* Write the checksum */
00347                 error = WriteByteToWav (fileInfo.sum >> 8 & 0xFF, order, mode ) ;
00348                 if (error != ERR_OK) break ;
00349                 error = WriteByteToWav (fileInfo.sum & 0xFF, order, mode ) ;
00350                 if (error != ERR_OK) break ;
00351 
00352                 error = WriteByteToWav (EOF_15, order, mode ) ;
00353                 if (error != ERR_OK) break ;
00354                 if ( (fileInfo.debug & 0x0040) > 0) debug_printf(" (E:%02X)", (uint) EOF_15);
00355                 writ_full_block = false ;
00356 
00357                 error = WriteSyncToWav (50 ) ; /* 0.02 s */
00358                 if (error != ERR_OK) break ;
00359                 error = WriteUsedatLenToQTWav (order, mode ) ;
00360             }
00361             break ;
00362 
00363         default :
00364             debug_printf ("%s: Unknown Mode\n", argP) ;
00365             break ;
00366         }
00367 
00368     } while (writ_full_block) ;
00369 
00370     return (error);
00371 }
00372 
00373 ulong SwapByte (ulong byte)
00374 {
00375     return ( (byte >> 4) + (byte << 4 & 0xF0) );
00376 }
00377 
00378 /* File name for New and Old BASIC */
00379 int WriteSaveNameToWav (char*  ptrName,
00380                         uchar  mode)
00381 {
00382      uint  ii ;
00383      uint  tmpL ;
00384      char  byte ;
00385      char  tmpS[20] ;
00386       int  error ;
00387 
00388    if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG ptrName %s\n\r", ptrName);
00389 
00390     do {
00391         /* Uppercase the name is done in main if needed */
00392         // tmpL = strlen (ptrName) ;
00393         for (ii = 0; ii < cLPF-1 && ptrName[ii] != '\0'; ii++) ;
00394         tmpL = ii;
00395         
00396         if (tmpL > 7)
00397             tmpL = 7 ;
00398             
00399         for ( ii = 0 ; ii < tmpL ; ++ii )
00400             tmpS[ii] = ptrName[ii] ;
00401     
00402         tmpS[tmpL] = 0 ;
00403         //if (Qcnt == 0) debug_printf ("Save name    : %s\n", tmpS) ;
00404         // strncpy( ptrName, tmpS, cLPF-1) ;
00405         for (ii = 0; ii < cLPF-1 && ptrName[ii] != '\0'; ii++) 
00406            tmpS[ii] = ptrName[ii]; 
00407        /* crash?
00408        for ( ; ii < cLPF-1; ii++)
00409            tmpS[ii] = '\0';
00410        */
00411        tmpL = 7 - tmpL ;
00412        for ( ii = 0 ; ii < tmpL ; ++ii )
00413             tmpS[ii] = 0 ;
00414 
00415         if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG tmpS %s\n\r", tmpS);
00416         for ( ii = tmpL ; ii < 7 ; ++ii ) {
00417             byte = (ulong) ptrName[6 - ii] ;
00418 
00419             switch (mode) {
00420             case MODE_B19 :
00421             case MODE_B20 :
00422 
00423                 if (byte < 0x80)
00424                     byte = (char)CodeOld[byte] ;
00425                 else
00426                     byte = (char)CodeOld[0] ;
00427                 break ;
00428 
00429             default :
00430 
00431                 if (byte >= 0x80)
00432                     byte = 0x20 ;
00433                 break ;
00434             }
00435             tmpS[ii] = (char) SwapByte(byte) ;
00436         }
00437         tmpS[7] = 0x5F ;
00438 
00439         /* Write the Name */
00440         fileInfo.count = 0 ;
00441         fileInfo.sum   = 0 ;
00442         for ( ii = 0 ; ii < 8 ; ++ii ) {
00443             error = WriteByteSumToWav (tmpS[ii], ORDER_STD, mode ) ;
00444             if (error != ERR_OK) break ;
00445         }
00446 
00447         if (fileInfo.ident == IDENT_PC1211)
00448             error = WriteSyncToWav (151 ) ;
00449         else if (fileInfo.ident == IDENT_PC121_DAT)
00450             error = WriteSyncToWav (111 ) ;
00451 
00452         fileInfo.count = 0 ;
00453         fileInfo.sum   = 0 ;
00454 
00455     } while (0) ;
00456     return (error);
00457 }
00458 
00459 int DEBUGSaveNameToWav (char*  ptrName,
00460                         uchar  mode)
00461 {
00462      uint  ii ;
00463      uint  i ;
00464     ulong  byte ;
00465     ulong  tmpL ;
00466      char  tmpS[10] ;
00467       int  error ;
00468 
00469     do {
00470         /* Uppercase the name is done in main if needed */
00471         tmpL = strlen (ptrName) ;
00472         debug_printf("DEBUG tmpL %u\n\r", tmpL);
00473 
00474         if (tmpL > 7)
00475             tmpL = 7 ;
00476 
00477         for ( ii = 0 ; ii < tmpL ; ++ii ) {
00478             debug_printf("DEBUG ptrName[ii] %c\n\r", ptrName[ii]);
00479             tmpS[ii] = ptrName[ii] ;
00480         }
00481         tmpS[tmpL] = 0 ;
00482         //if (Qcnt == 0) debug_printf ("Save name    : %s\n", tmpS) ;
00483         debug_printf("DEBUG ptrName %s\n\r", ptrName);
00484         debug_printf("DEBUG i 1 ");
00485 
00486         // strncpy( ptrName, tmpS, cLPF-1) ;
00487         for (i = 0; i < cLPF-1 && ptrName[i] != '\0'; i++) {
00488            debug_printf("%u ", i);
00489            tmpS[i] = ptrName[i]; 
00490         }
00491         debug_printf("\n\rDEBUG i 2 ");
00492         /* crash?
00493         for ( ; i < cLPF-1; i++) {
00494             debug_printf("%u ", i);
00495             tmpS[i] = '\0';
00496         }
00497         */
00498         debug_printf("\n\rDEBUG tmpS %s\n\r", tmpS);
00499         tmpL = 7 - tmpL ;
00500         for ( ii = 0 ; ii < tmpL ; ++ii )
00501             tmpS[ii] = 0 ;
00502         debug_printf("DEBUG tmpS %s\n\r", tmpS);
00503 
00504         /* reverse-order bytes */
00505         for ( ii = tmpL ; ii < 7 ; ++ii ) {
00506             byte = (ulong) ptrName[6 - ii] ;
00507             debug_printf("DEBUG byte %u\n\r", byte);
00508 
00509             switch (mode) {
00510             case MODE_B19 :
00511             case MODE_B20 :
00512 
00513                 if (byte < 0x80)
00514                     byte = (char)CodeOld[byte] ;
00515                 else
00516                     byte = (char)CodeOld[0] ;
00517                 break ;
00518 
00519             default :
00520 
00521                 if (byte >= 0x80)
00522                     byte = 0x20 ;
00523                 break ;
00524             }
00525             tmpS[ii] = (char) SwapByte(byte) ;
00526         }
00527         tmpS[7] = 0x5F ;
00528         debug_printf("DEBUG ii %u\n\r", ii);
00529 
00530         /* Write the Name */
00531         fileInfo.count = 0 ;
00532         fileInfo.sum   = 0 ;
00533         for ( ii = 0 ; ii < 8 ; ++ii ) {
00534             error = WriteByteSumToWav (tmpS[ii], ORDER_STD, mode ) ;
00535             if (error != ERR_OK) break ;
00536         }
00537         if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG Name - Bytes was printed swapped.\n\r");
00538 
00539         if (fileInfo.ident == IDENT_PC1211)
00540             error = WriteSyncToWav (151 ) ;
00541         else if (fileInfo.ident == IDENT_PC121_DAT)
00542             error = WriteSyncToWav (111 ) ;
00543 
00544         fileInfo.count = 0 ;
00545         fileInfo.sum   = 0 ;
00546 
00547     } while (0) ;
00548     return (error);
00549 }
00550 
00551 /* Head of Binary Data for New and Old series */
00552 int WriteHeadToBinWav (ulong  addr,
00553                        ulong  size,
00554                        uchar  mode)
00555 {
00556       int  ii ;
00557     ulong  len ;
00558     ulong  tmpL ;
00559       int  error ;
00560 
00561     do {
00562     /*    if (Qcnt == 0)
00563     {
00564         debug_printf ("Start Address: 0x%04X\n", (uint) addr);
00565         debug_printf ("End   Address: 0x%04X, Length: %d bytes\n", (uint) (addr + size -1), (uint) size);
00566     }
00567     */
00568 
00569         fileInfo.count = 0 ;
00570         fileInfo.sum   = 0 ;
00571         for ( ii = 0 ; ii < 4 ; ++ii ) {
00572             error = WriteByteSumToWav (0, ORDER_STD, mode ) ;
00573             if (error != ERR_OK) break ;
00574         }
00575 
00576         /* Write the address, this method is necessary because of swapped checksums in the header. */
00577         tmpL = ((addr >> 4) & 0xF0) + (addr >> 12) ;        /* H swapped */
00578         error = WriteByteSumToWav (tmpL, ORDER_STD, mode ) ;
00579         if (error != ERR_OK) break ;
00580 
00581         tmpL = ((addr << 4) & 0xF0) + ((addr >> 4) & 0x0F) ;/* L swapped */
00582         error = WriteByteSumToWav (tmpL, ORDER_STD, mode ) ;
00583         if (error != ERR_OK) break ;
00584 
00585         /* Write the Length */
00586         len = size - 1 ;
00587         tmpL = ((len >> 4) & 0xF0) + (len >> 12) ;
00588         error = WriteByteSumToWav (tmpL, ORDER_STD, mode ) ;
00589         if (error != ERR_OK) break ;
00590 
00591         tmpL = ((len << 4) & 0xF0) + ((len >> 4) & 0x0F) ;
00592         error = WriteByteSumToWav (tmpL, ORDER_STD, mode ) ;
00593         if (error != ERR_OK) break ;
00594 
00595         fileInfo.count = 0 ;
00596         fileInfo.sum   = 0 ;
00597 
00598     } while (0) ;
00599     return (error);
00600 }
00601 
00602 int WriteFooterToNewWav ( void )
00603 {
00604     int  error ;
00605 
00606     do {
00607         fileInfo.count = 0 ; /* no checksum writing from here until the end */
00608 
00609         error = WriteByteSumToWav(BAS_NEW_EOF, ORDER_STD, fileInfo.mode ) ;
00610         // error = WriteByteSumToB13Wav (BAS_NEW_EOF ) ;
00611         if (error != ERR_OK) break ;
00612 
00613         error = WriteByteToWav(BAS_NEW_EOF, ORDER_STD, fileInfo.mode ) ;
00614         if (error != ERR_OK) break ;
00615 
00616         if ( (fileInfo.debug & 0x00C0) > 0 )
00617             debug_printf(" EOF:%02X", (uchar) BAS_NEW_EOF);
00618 
00619         error = WriteByteToWav(fileInfo.sum, ORDER_STD, fileInfo.mode ) ;
00620         if (error != ERR_OK) break ;
00621 
00622         if ( (fileInfo.debug & 0x0040) > 0 )
00623             debug_printf(" (%02X)", (uchar) fileInfo.sum);
00624 
00625     /* there are 2bits more HIGH at the end of transmission (at least for PC-1402) M. NOSSWITZ */
00626      error = WriteBitToWav (1 ) ;
00627     if (error != ERR_OK) break ;
00628 
00629     error = WriteBitToWav (1 ) ;
00630     if (error != ERR_OK) break ;
00631  
00632     /* This puts 2 bits of silence (or 2 HIGH bits alternatively) to the end of the wave file. */
00633     /* CLOAD does not accept any sound, that could be interpreted as a start bit,              */
00634     /* during post-processing. Original CSAVE switches the signal low ms after the            */
00635     /* end of transmission, before the motor of the cassette recorder is switched off.        */
00636     /* This level out is visible in the CSAVE audio signal after the last bit. T. Muecker     */
00637     /* not needed for the MBed direct-write version
00638     error = WriteBitToWav (3 ) ; 125us High , 
00639     if (error != ERR_OK) break ;
00640     error = WriteBitToWav (2 ) ; 1 ms Midsignal
00641     if (error != ERR_OK) break ;
00642     */
00643 
00644     } while (0) ;
00645     return (error);
00646 }
00647 
00648 int WriteFooterToMemoWav ( void )
00649 {
00650     int  error ;
00651 
00652     do {
00653         error = WriteByteToWav(fileInfo.sum, ORDER_STD, fileInfo.mode ) ;
00654         if (error != ERR_OK) break ;
00655 
00656         if ( (fileInfo.debug & 0x0040) > 0 )
00657             debug_printf(" (%02X)", (uchar) fileInfo.sum);
00658 
00659     error = WriteBitToWav (1 ) ;
00660     if (error != ERR_OK) break ;
00661 
00662     error = WriteBitToWav (1 ) ;
00663     if (error != ERR_OK) break ;
00664 
00665     /* This puts 2 bits of silence (or 2 HIGH bits alternatively) to the end of the wave file. */
00666     /* not needed for the MBed send version
00667     error = WriteBitToWav (3 ) ;
00668     if (error != ERR_OK) break ;
00669 
00670     error = WriteBitToWav (2 ) ;
00671     if (error != ERR_OK) break ;
00672     */
00673 
00674     } while (0) ;
00675     return (error);
00676 }
00677 
00678 
00679 // File completion check
00680 bool isFileSendComplete ( void ) {
00681 #ifdef FILE_BUF_SIZE 
00682     return ( isFilePullComplete() ) ;
00683 #else
00684     return ( file_pos == BIN_FILE_SIZE - 1 ) ; 
00685 #endif
00686 }
00687 
00688 // Input file data access, depends on build
00689 char fileGetNext ( void ) {
00690     // byte = fgetc (srcFd) ; // DOS / UNIX file - not applicable here 
00691 #ifdef FILE_BUF_SIZE 
00692     return ( filePullData () ) ;
00693 #else
00694     return ( bin_file_bytes[file_pos++] ); 
00695 #endif
00696 }
00697 
00698 
00699 /////////////////////////////////////////////////////////////////////////////
00700 // file-send implementation, largely inspired to Pocket-Tools source code
00701 int FileSend ( void )
00702 {
00703     
00704     int      pcId  =  PC_ID;  // hardcoded for PC-1403 here
00705     uint32_t nbSync = N_SYNC_BITS; 
00706     int      ii;
00707     uchar    type ;
00708     uint32_t nbByte;
00709     uint32_t addr;
00710     int      error ;
00711     char     inVal;   
00712 
00713     fileInfo.nbSync = nbSync;
00714 #ifndef FILE_BUF_SIZE 
00715     file_pos = 0;
00716 #endif
00717 
00718     switch (fileInfo.ident) {
00719     /* . . .*/
00720         case IDENT_NEW_BIN :
00721             pcgrpId = GRP_NEW ; /*or GRP_EXT */
00722             type = TYPE_BIN ;
00723             break ;
00724     /* . . .*/
00725         case IDENT_NEW_BAS :
00726             pcgrpId = GRP_NEW ;
00727             type = TYPE_IMG ;
00728             break ;
00729         default :
00730             debug_printf ("%s: Unknown Ident\n", argP) ;
00731             return (ERR_ARG);
00732     }
00733 
00734     /* if (pcgrpId == GRP_E || pcgrpId == GRP_G || pcgrpId == GRP_16) { 
00735        . . .
00736     }   
00737     else { //   PC-1211 to PC-1500, QTape 
00738     */   
00739         if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG WriteSyncToWav\n\r");
00740         error = WriteSyncToWav (nbSync ) ;
00741     /*
00742         . . .
00743     */
00744     if (error != ERR_OK) return ( error ) ;
00745                     
00746     switch (pcId) {
00747     /*
00748       . . . 
00749     */
00750     case 1403:
00751        /* if (type == TYPE_BIN && Acnt==0 && SHCc==0 && addr==0) */ addr = TYPE_BIN_ADDR;
00752     /*
00753       . . . 
00754     */
00755         break;
00756     default :
00757         debug_printf ("%s: Sharp PC-%d not implemented\n", argP, pcId) ;
00758         // MoreInfo (ERR_ARG);
00759         error = ERR_ARG ;
00760             // break ;
00761     }
00762     if (error != ERR_OK) return ( error )  ;
00763 
00764 /*  ...
00765     else { // PC-121x ... PC-1475 
00766 */
00767     if ( (fileInfo.debug & 0x0040) > 0 ) 
00768         debug_printf("DEBUG set Header Mode (ident %d)\n\r", fileInfo.ident);
00769     switch (fileInfo.ident) { /* Header Mode */
00770     case IDENT_PC1211 :
00771         fileInfo.mode = fileInfo.mode_h = MODE_B20 ;
00772         break ;
00773 
00774     case IDENT_PC121_DAT :
00775     case IDENT_OLD_BAS :
00776     case IDENT_OLD_DAT :
00777     case IDENT_OLD_BIN :
00778     case IDENT_OLD_MEM :
00779         fileInfo.mode = fileInfo.mode_h = MODE_B19 ;
00780         break ;
00781 
00782     case IDENT_NEW_TEL :
00783     case IDENT_NEW_SCD :
00784     case IDENT_NEW_NOT :
00785     case IDENT_NEW_CRD :
00786 
00787     case IDENT_NEW_CSL :
00788 
00789     case IDENT_NEW_BAS :
00790     case IDENT_EXT_BAS :
00791     case IDENT_NEW_DAT :
00792     case IDENT_NEW_BIN :
00793         fileInfo.mode = fileInfo.mode_h = MODE_B16 ;
00794         break ;
00795 
00796     default :
00797         debug_printf ("%s: Unknown Ident\n", argP) ;
00798         fileInfo.mode = fileInfo.mode_h = MODE_B21 ;
00799         return (ERR_ARG);
00800     }
00801     if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG Header fileInfo.mode_h %u\n\r",fileInfo.mode_h);
00802 
00803     /* Write the TAPE code */
00804     if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG Write the TAPE code\n\r");
00805     error = WriteByteToWav ( (ulong) fileInfo.ident, ORDER_STD, fileInfo.mode_h ) ;
00806     if (error != ERR_OK) return ( error )  ;
00807 
00808     /* Write the Name */
00809     if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG Writing Name...\n\r");
00810     error = WriteSaveNameToWav ( "NONAME", fileInfo.mode_h ) ; // NOT USING FILENAME !!
00811     if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG error (ERR_OK) %d (%d)\n\r", error, ERR_OK);
00812     if (error != ERR_OK) return ( error )  ;
00813     
00814     if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG set Body Data Mode\n\r");
00815     switch (fileInfo.ident) { /* Body Data Mode */
00816         case IDENT_PC1211 :
00817             fileInfo.mode = MODE_B20 ;
00818             break ;
00819     
00820         case IDENT_PC121_DAT :
00821         case IDENT_OLD_BAS :
00822         case IDENT_OLD_BIN :
00823         case IDENT_OLD_MEM :
00824             fileInfo.mode = MODE_B19 ;
00825             break ;
00826     
00827         case IDENT_OLD_DAT :
00828         case IDENT_NEW_DAT :
00829             fileInfo.mode = MODE_B15 ;
00830         break ;
00831     
00832         case IDENT_EXT_BAS :
00833     
00834         case IDENT_NEW_BAS :
00835         case IDENT_NEW_CSL :
00836     
00837         case IDENT_NEW_TEL :
00838         case IDENT_NEW_SCD :
00839         case IDENT_NEW_NOT :
00840         case IDENT_NEW_CRD :
00841         case IDENT_NEW_BIN :
00842           // TODO (mr#2#): Check whitch MODE_B13 or _B14
00843             if (cnvstr_upr && pcId < 1440) fileInfo.mode = MODE_B13 ; /*older part of new series*/
00844             else  fileInfo.mode = MODE_B14 ;     /*new series and extended series*/
00845             break ;
00846     
00847         default :
00848             debug_printf ("%s: Unknown Ident\n", argP) ;
00849             return ( ERR_ARG );
00850         }
00851         if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG Body fileInfo.mode %u\n\r", fileInfo.mode);
00852 
00853         fileInfo.total = 0 ; /* count bytes of body only */
00854                 
00855         switch (fileInfo.ident) { /* header was written, write all data now */
00856         /* ... 
00857         case 
00858         ... */
00859         case IDENT_NEW_BAS :
00860         case IDENT_NEW_CSL :
00861         case IDENT_EXT_BAS :
00862             if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG Writing data...\n\r");
00863             /* Write the datas */
00864 //            info.mode = MODE_B13 ; /* PC-1403 and newer should be MODE_14 */
00865             /* the older simple algorithm seems to work as well, but this is now, what the PC does originally */
00866             while  ( !isFileSendComplete() ) {
00867                 inVal = fileGetNext();
00868                 if ( inVal == EOF ) break ; // ending if 
00869                 if ( inVal == BAS_NEW_EOF ) {
00870                     if (fileInfo.count + 1 == BLK_NEW && fileInfo.sum == 0xE1) { /* Constellation will generate 2-times BAS_NEW_EOF */
00871                         printf ("\nERROR %i at %lu. byte, usually the low byte of a BASIC line number\n", ERR_SUM, fileInfo.total) ;
00872                         printf ("This binary constellation activates the CLOAD bug of this series. The line\n") ;
00873                         printf ("number must be changed or minor changes done in the BASIC text before.\n") ;
00874                         /* Seldom Bug in CLOAD, for PC-1402/(01) at known ROM address: 40666 */
00875                         if ((fileInfo.debug & 0x800) == 0 ) {
00876                             error = ERR_SUM ;
00877                             break ;
00878                         }
00879                     }
00880                 }
00881                 error = WriteByteSumToWav ( (uint) inVal, ORDER_STD, fileInfo.mode ) ;
00882                 if (error != ERR_OK) break ;
00883             }
00884             if (error != ERR_OK) break ;
00885             if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("\n\rDEBUG ii %u\n\r", ii);
00886 
00887             inVal = fileGetNext(); /* Read the last byte before EOF mark */
00888             if (inVal == EOF) break ;
00889             if (inVal == BAS_NEW_EOF) {
00890                 /* EOF mark should not be included for this file type normally*/
00891                 if (Qcnt == 0) printf ("End of File mark %i should not be included in the image\n", inVal) ;
00892                 /* if end of block, then an additional checksum would be written, but this does work anyhow */
00893             }
00894             else {
00895                 if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG last byte: %02X\n\r", (uchar) inVal);
00896                 error = WriteByteToWav ( (uint) inVal, ORDER_STD, fileInfo.mode ) ;
00897                 if (error != ERR_OK) break ;
00898                 CheckSumB1 ((uint) inVal ) ; /* never write the checksum before BAS_NEW_EOF */
00899 
00900                 ++fileInfo.total ;
00901                 ++fileInfo.count ; /* for debug purposes only, WriteFooter will reset it */
00902             }
00903 
00904             /* Write the END code */
00905             if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG WriteFooterToNewWav\n\r");
00906             error = WriteFooterToNewWav ( ) ;
00907 
00908             break ; // IDENT_NEW_BAS, IDENT_EXT_BAS
00909 
00910         case IDENT_NEW_BIN :
00911             /* Write the address and length */
00912             error = WriteHeadToBinWav (addr, nbByte, fileInfo.mode_h ) ;
00913             if (error != ERR_OK) break ;
00914             /* no break */
00915 
00916         case IDENT_NEW_TEL :
00917         case IDENT_NEW_SCD :
00918         case IDENT_NEW_NOT :
00919         case IDENT_NEW_CRD :
00920 
00921             /* Write the datas */
00922             while  ( !isFileSendComplete() ) {
00923                 inVal = fileGetNext();
00924                 if (inVal == EOF ) break ; // premature ending shouldn't happen ...
00925 
00926                 error = WriteByteSumToWav ( (uint) inVal, ORDER_STD, fileInfo.mode ) ;
00927                 if (error != ERR_OK) break ;
00928             }
00929             if (error != ERR_OK) break ;
00930 
00931             inVal = fileGetNext();
00932             if (inVal == EOF) break ;
00933 
00934             if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG %02X", (uchar) inVal);
00935             error = WriteByteToWav ( (uint) inVal, ORDER_STD, fileInfo.mode ) ;
00936             if (error != ERR_OK) break ;
00937             CheckSumB1 ( (uint) inVal  ) ; /* never write the checksum before BAS_NEW_EOF */
00938             ++fileInfo.total ;
00939             ++fileInfo.count ; /* for debug purposes only, WriteFooter will reset it */
00940 
00941             /* Write the END code */
00942             if ( fileInfo.ident == IDENT_NEW_BIN) error = WriteFooterToNewWav ( ) ;
00943             else WriteFooterToMemoWav ( ) ;
00944 
00945             break ; // IDENT_NEW_BIN and IDENT_NEW_Memos
00946         default:
00947             printf ("%s: Unknown Ident\n", argP) ;
00948             error = ERR_ARG;
00949             break;
00950         }        
00951 
00952     return (error);
00953 
00954 }
00955