Fabio Fumi
/
send_to_sharp
Renamed
Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Sat Jul 16 2022 05:01:30 by 1.7.2