Fabio Fumi
/
send_to_sharp
Renamed
send_pc1403.cpp
- Committer:
- ffxx68
- Date:
- 2022-03-29
- Revision:
- 5:062962db7a48
- Parent:
- 2:dff96be9617e
File content as of revision 5:062962db7a48:
#include "send_pc1403.h" /////////////////////////////////////////////////////// // variables from PocketTools code uint SHCc = 0 , /* Read not from bin, but from Transfile PC plus SHC-format (header included) */ SHCe = 0 ; /* End marks are the SHC Basic image included only*/ uint QTc = 0 ; /* Write to Quick-Tape wave format */ uint STc = 0 ; /* Header of SuperTape or file header of PC-1600 format is in the image included */ uint TAPc = 0 ; /* Write not to wave format but to emulator tap format (raw bytes)*/ uint Qcnt = 0 ; /* Quiet, minimal output */ uint Scnt = 0 ; /* Number of sync parameters or sync and sync spaces was defined */ uint Acnt = 0 ; /* Number of address parameters, non standard load or entry addresses */ uint Mcnt = 0 ; /* Read header parameter from a file */ double speed = 1.00 ; /* Used it for modified Pocket Computer with a CPU Speed Up switched on */ ulong pcId = 1500 ; /* ID number of the pocket computer */ ushort pcgrpId = IDENT_UNKNOWN ; // ulong pcAddr = 0 ; /* PC-specific address, used for the end of variable data of PCs with DB-tables */ bool cnvstr_upr = false ; /* Convert strings to upper, for Pokecon with SML-key not */ bool type_asm = false ; /* Image contains assembler source code (subtype), true for CASL and CAP-X */ // TODO (mr#2#): Count all warnings and errors ulong err_cnt = 0 ; /* counts minor errors */ ulong wrn_cnt = 0 ; /* counts warnings */ FileInfo fileInfo ; /* File information */ //////////////////////////////////////////////////////////////////////////////// // WriteBitToWav replaced from PocketTools version (writing to a WAV file) // Here we send directly signals to OUT lines int WriteBitToWav (int value) { // Calling the buffered bit-sending routine switch ( value ) { case 1: if ( bitWaitSend ( value, 0 ) > MAX_BIT_TIME_ERR ) return ( ERR_NOK ) ; break; case 0: if ( bitWaitSend ( value, 0 ) > MAX_BIT_TIME_ERR ) return ( ERR_NOK ) ; break; default: break; } return ( ERR_OK ) ; } //////////////////////////////////////////////////////////////////////////////// // Write* methods taken from Pocket-Tools source code // https://www.peil-partner.de/ifhe.de/sharp/ int WriteQuaterToWav (uint value, uint stopBits) { uint tmp ; uint ii ; int error ; // if (TAPc > 0) return (WriteQuaterToTap (value )); // no do { error = WriteBitToWav (0 ) ; if (error != ERR_OK) break ; for ( ii = 0 ; ii < 4 ; ++ii ) { tmp = 1 << ii ; if ( (value & tmp) == 0 ) error = WriteBitToWav (0 ) ; else error = WriteBitToWav (1 ) ; if (error != ERR_OK) break ; } if (error != ERR_OK) break ; for ( ii = 0 ; ii < stopBits ; ++ii ) { error = WriteBitToWav (1 ) ; if (error != ERR_OK) break ; } if (error != ERR_OK) break ; } while (0) ; return (error); } int WriteByteToWav (ulong value, uchar order, uchar mode) { uint lsq ; uint msq ; int error ; // if (TAPc > 0) return (WriteByteToTap (value, order )) ; // no // if (order == ORDER_E) return (WriteByteToEWav (value )) ; // no 1403 do { lsq = value & 0x0F ; msq = (value >> 4) & 0x0F ; if (order == ORDER_INV) { error = WriteQuaterToWav (lsq, Mode[mode].stopb1 ) ; if (error != ERR_OK) break ; error = WriteQuaterToWav (msq, Mode[mode].stopb2 ) ; if (error != ERR_OK) break ; } else { error = WriteQuaterToWav (msq, Mode[mode].stopb1 ) ; if (error != ERR_OK) break ; error = WriteQuaterToWav (lsq, Mode[mode].stopb2 ) ; if (error != ERR_OK) break ; } } while (0) ; return (error); } int CheckSumB1 ( ulong Byte ) { ushort sum ; /* Update the checksum */ sum = fileInfo.sum + ((Byte & 0xF0) >> 4) ; if (sum > 0xFF) { ++sum ; sum &= 0xFF ; } fileInfo.sum = (sum + (Byte & 0x0F)) & 0xFF ; return (0); } int CheckSumE ( ulong Byte // ulong* ptrSum ) { uint tmp, ii ; /* Update the checksum */ tmp = 0x80 ; for ( ii = 0 ; ii < 8 ; ++ii, tmp >>= 1 ) if ( (Byte & tmp) != 0 ) // ++ *ptrSum ; ++ fileInfo.sum ; return (0); } int WriteSyncToWav (ulong nbSync ) { ulong ii ; int error = ERR_OK ; if (TAPc > 0) return (ERR_OK); // no do { /* Write the Synchro patern */ for ( ii = 0 ; ii < nbSync ; ++ii ) { error = WriteBitToWav (1 ) ; if (error != ERR_OK) break ; } if (error != ERR_OK) break ; } while (0) ; return (error); } int WriteUsedatLenToQTWav ( uchar order, /* Quick-Tape incomplete blocks with fill data */ uchar mode ) { long tmpL ; int error ; tmpL = fileInfo.nbByte - fileInfo.total_diff - fileInfo.total ; //not for IDENT_QT_DAT: variable block in RAM based if (tmpL > 0) { if (tmpL > BLK_OLD) tmpL = BLK_OLD ; --tmpL ; if (tmpL < BLK_OLD -1) fileInfo.usedat_len = tmpL + 1 ; else fileInfo.usedat_len = 0 ; /* L:0x4F ignored, no effect */ error = WriteByteToWav (tmpL, order, mode ) ; if (error != ERR_OK) return (error) ; if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG (L:%02X)", (uint) tmpL); fileInfo.sum = tmpL ; } else if (tmpL == 0 ) error = ERR_OK ; else { printf(" WUsedatLQT: End of file was expected"); error = ERR_FMT ; } fileInfo.count = 0 ; return (error); } int WriteByteSumToWav (ulong value, uchar order, uchar mode) { int error ; bool writ_full_block = false ; do { if ( (fileInfo.debug & 0x0040) > 0) debug_printf(" %02X", (uchar) value); error = WriteByteToWav (value, order, mode ) ; if (error != ERR_OK) break ; if (mode == MODE_B22 || mode == MODE_B11) fileInfo.sum += value ; else if (mode == MODE_B9 || mode == MODE_B10) CheckSumE (value ) ; //ptrFile else CheckSumB1 (value ) ; ++fileInfo.count ; if (!writ_full_block) ++fileInfo.total ; if ( fileInfo.usedat_len > 0) { /* QTape incomplete block */ if (--fileInfo.usedat_len == 0) { if ( ( (fileInfo.debug & 0x0040) > 0 ) && (Qcnt == 0) ) debug_printf("DEBUG Fill data:"); value = 0x00 ; writ_full_block = true ; } } switch (mode) { case MODE_B22 : if ( fileInfo.count >= BLK_OLD ) { if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf(" (%04X)\n\r", (uint) fileInfo.sum); /* Write the checksum */ error = WriteByteToWav (fileInfo.sum >> 8 & 0xFF, order, mode ) ; if (error != ERR_OK) break ; error = WriteByteToWav (fileInfo.sum & 0xFF, order, mode ) ; if (error != ERR_OK) break ; fileInfo.count = 0 ; fileInfo.sum = 0 ; } break ; case MODE_B21 : case MODE_B20 : case MODE_B19 : if ( (fileInfo.count % BLK_OLD_SUM) == 0) { if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf(" (%02X)\n\r", (uchar) fileInfo.sum); /* Write the checksum */ error = WriteByteToWav (fileInfo.sum, order, mode ) ; if (error != ERR_OK) break ; if ( fileInfo.count >= BLK_OLD ) { fileInfo.count = 0 ; fileInfo.sum = 0 ; // if (pcgrpId==IDENT_PC1211) error = WriteSyncToWav (1803 ) ; //DATA not if (fileInfo.ident == IDENT_PC1211) /* default 1803 bits, data not */ error = WriteSyncToWav (fileInfo.nbSync ) ; } } break ; case MODE_B17 : case MODE_B16 : case MODE_B15 : if ( fileInfo.count >= BLK_OLD_SUM) { if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf(" (%02X)\n\r", (uchar) fileInfo.sum); /* Write the checksum */ error = WriteByteToWav (fileInfo.sum, order, mode) ; if (error != ERR_OK) break ; fileInfo.count = 0 ; fileInfo.sum = 0 ; } break ; case MODE_B14 : case MODE_B13 : if ( fileInfo.count >= BLK_NEW ) { if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf(" *(%02X)", (uchar) fileInfo.sum); /* Write the checksum */ error = WriteByteToWav (fileInfo.sum, order, mode ) ; if (error != ERR_OK) break ; fileInfo.count = 0 ; fileInfo.sum = 0 ; } break ; case MODE_B9 : /* PC-E/G/1600 */ if ( fileInfo.count >= fileInfo.block_len ) { if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf(" (%04X)\n\r", (uint) fileInfo.sum & 0xFFFF); /* Write the checksum */ error = WriteByteToWav (fileInfo.sum >> 8 & 0xFF, order, mode ) ; if (error != ERR_OK) break ; error = WriteByteToWav (fileInfo.sum & 0xFF, order, mode ) ; if (error != ERR_OK) break ; fileInfo.count = 0 ; fileInfo.sum = 0 ; } break ; case MODE_B10 : /* SuperTape */ if ( fileInfo.count >= fileInfo.block_len ) { if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf(" (%04X)", (uint) fileInfo.sum & 0xFFFF); /* Write the checksum */ error = WriteByteToWav (fileInfo.sum & 0xFF, order, mode ) ; if (error != ERR_OK) break ; error = WriteByteToWav (fileInfo.sum >> 8 & 0xFF, order, mode ) ; if (error != ERR_OK) break ; if ( (fileInfo.debug & 0x0040) > 0) debug_printf(" %02X", (uchar) SUPT_END); error = WriteByteToWav (SUPT_END, order, mode ) ; if (error != ERR_OK) break ; fileInfo.count = 0 ; fileInfo.sum = 0 ; } break ; case MODE_B11 : if ( fileInfo.count >= BLK_OLD ) { if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf(" (%04X)\n\r", (uint) fileInfo.sum); /* Write the checksum */ error = WriteByteToWav (fileInfo.sum >> 8 & 0xFF, order, mode ) ; if (error != ERR_OK) break ; error = WriteByteToWav (fileInfo.sum & 0xFF, order, mode ) ; if (error != ERR_OK) break ; error = WriteByteToWav (EOF_15, order, mode ) ; if (error != ERR_OK) break ; if ( (fileInfo.debug & 0x0040) > 0) debug_printf(" (E:%02X)", (uint) EOF_15); writ_full_block = false ; error = WriteSyncToWav (50 ) ; /* 0.02 s */ if (error != ERR_OK) break ; error = WriteUsedatLenToQTWav (order, mode ) ; } break ; default : debug_printf ("%s: Unknown Mode\n", argP) ; break ; } } while (writ_full_block) ; return (error); } ulong SwapByte (ulong byte) { return ( (byte >> 4) + (byte << 4 & 0xF0) ); } /* File name for New and Old BASIC */ int WriteSaveNameToWav (char* ptrName, uchar mode) { uint ii ; uint tmpL ; char byte ; char tmpS[20] ; int error ; if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG ptrName %s\n\r", ptrName); do { /* Uppercase the name is done in main if needed */ // tmpL = strlen (ptrName) ; for (ii = 0; ii < cLPF-1 && ptrName[ii] != '\0'; ii++) ; tmpL = ii; if (tmpL > 7) tmpL = 7 ; for ( ii = 0 ; ii < tmpL ; ++ii ) tmpS[ii] = ptrName[ii] ; tmpS[tmpL] = 0 ; //if (Qcnt == 0) debug_printf ("Save name : %s\n", tmpS) ; // strncpy( ptrName, tmpS, cLPF-1) ; for (ii = 0; ii < cLPF-1 && ptrName[ii] != '\0'; ii++) tmpS[ii] = ptrName[ii]; /* crash? for ( ; ii < cLPF-1; ii++) tmpS[ii] = '\0'; */ tmpL = 7 - tmpL ; for ( ii = 0 ; ii < tmpL ; ++ii ) tmpS[ii] = 0 ; if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG tmpS %s\n\r", tmpS); for ( ii = tmpL ; ii < 7 ; ++ii ) { byte = (ulong) ptrName[6 - ii] ; switch (mode) { case MODE_B19 : case MODE_B20 : if (byte < 0x80) byte = (char)CodeOld[byte] ; else byte = (char)CodeOld[0] ; break ; default : if (byte >= 0x80) byte = 0x20 ; break ; } tmpS[ii] = (char) SwapByte(byte) ; } tmpS[7] = 0x5F ; /* Write the Name */ fileInfo.count = 0 ; fileInfo.sum = 0 ; for ( ii = 0 ; ii < 8 ; ++ii ) { error = WriteByteSumToWav (tmpS[ii], ORDER_STD, mode ) ; if (error != ERR_OK) break ; } if (fileInfo.ident == IDENT_PC1211) error = WriteSyncToWav (151 ) ; else if (fileInfo.ident == IDENT_PC121_DAT) error = WriteSyncToWav (111 ) ; fileInfo.count = 0 ; fileInfo.sum = 0 ; } while (0) ; return (error); } int DEBUGSaveNameToWav (char* ptrName, uchar mode) { uint ii ; uint i ; ulong byte ; ulong tmpL ; char tmpS[10] ; int error ; do { /* Uppercase the name is done in main if needed */ tmpL = strlen (ptrName) ; debug_printf("DEBUG tmpL %u\n\r", tmpL); if (tmpL > 7) tmpL = 7 ; for ( ii = 0 ; ii < tmpL ; ++ii ) { debug_printf("DEBUG ptrName[ii] %c\n\r", ptrName[ii]); tmpS[ii] = ptrName[ii] ; } tmpS[tmpL] = 0 ; //if (Qcnt == 0) debug_printf ("Save name : %s\n", tmpS) ; debug_printf("DEBUG ptrName %s\n\r", ptrName); debug_printf("DEBUG i 1 "); // strncpy( ptrName, tmpS, cLPF-1) ; for (i = 0; i < cLPF-1 && ptrName[i] != '\0'; i++) { debug_printf("%u ", i); tmpS[i] = ptrName[i]; } debug_printf("\n\rDEBUG i 2 "); /* crash? for ( ; i < cLPF-1; i++) { debug_printf("%u ", i); tmpS[i] = '\0'; } */ debug_printf("\n\rDEBUG tmpS %s\n\r", tmpS); tmpL = 7 - tmpL ; for ( ii = 0 ; ii < tmpL ; ++ii ) tmpS[ii] = 0 ; debug_printf("DEBUG tmpS %s\n\r", tmpS); /* reverse-order bytes */ for ( ii = tmpL ; ii < 7 ; ++ii ) { byte = (ulong) ptrName[6 - ii] ; debug_printf("DEBUG byte %u\n\r", byte); switch (mode) { case MODE_B19 : case MODE_B20 : if (byte < 0x80) byte = (char)CodeOld[byte] ; else byte = (char)CodeOld[0] ; break ; default : if (byte >= 0x80) byte = 0x20 ; break ; } tmpS[ii] = (char) SwapByte(byte) ; } tmpS[7] = 0x5F ; debug_printf("DEBUG ii %u\n\r", ii); /* Write the Name */ fileInfo.count = 0 ; fileInfo.sum = 0 ; for ( ii = 0 ; ii < 8 ; ++ii ) { error = WriteByteSumToWav (tmpS[ii], ORDER_STD, mode ) ; if (error != ERR_OK) break ; } if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG Name - Bytes was printed swapped.\n\r"); if (fileInfo.ident == IDENT_PC1211) error = WriteSyncToWav (151 ) ; else if (fileInfo.ident == IDENT_PC121_DAT) error = WriteSyncToWav (111 ) ; fileInfo.count = 0 ; fileInfo.sum = 0 ; } while (0) ; return (error); } /* Head of Binary Data for New and Old series */ int WriteHeadToBinWav (ulong addr, ulong size, uchar mode) { int ii ; ulong len ; ulong tmpL ; int error ; do { /* if (Qcnt == 0) { debug_printf ("Start Address: 0x%04X\n", (uint) addr); debug_printf ("End Address: 0x%04X, Length: %d bytes\n", (uint) (addr + size -1), (uint) size); } */ fileInfo.count = 0 ; fileInfo.sum = 0 ; for ( ii = 0 ; ii < 4 ; ++ii ) { error = WriteByteSumToWav (0, ORDER_STD, mode ) ; if (error != ERR_OK) break ; } /* Write the address, this method is necessary because of swapped checksums in the header. */ tmpL = ((addr >> 4) & 0xF0) + (addr >> 12) ; /* H swapped */ error = WriteByteSumToWav (tmpL, ORDER_STD, mode ) ; if (error != ERR_OK) break ; tmpL = ((addr << 4) & 0xF0) + ((addr >> 4) & 0x0F) ;/* L swapped */ error = WriteByteSumToWav (tmpL, ORDER_STD, mode ) ; if (error != ERR_OK) break ; /* Write the Length */ len = size - 1 ; tmpL = ((len >> 4) & 0xF0) + (len >> 12) ; error = WriteByteSumToWav (tmpL, ORDER_STD, mode ) ; if (error != ERR_OK) break ; tmpL = ((len << 4) & 0xF0) + ((len >> 4) & 0x0F) ; error = WriteByteSumToWav (tmpL, ORDER_STD, mode ) ; if (error != ERR_OK) break ; fileInfo.count = 0 ; fileInfo.sum = 0 ; } while (0) ; return (error); } int WriteFooterToNewWav ( void ) { int error ; do { fileInfo.count = 0 ; /* no checksum writing from here until the end */ error = WriteByteSumToWav(BAS_NEW_EOF, ORDER_STD, fileInfo.mode ) ; // error = WriteByteSumToB13Wav (BAS_NEW_EOF ) ; if (error != ERR_OK) break ; error = WriteByteToWav(BAS_NEW_EOF, ORDER_STD, fileInfo.mode ) ; if (error != ERR_OK) break ; if ( (fileInfo.debug & 0x00C0) > 0 ) debug_printf(" EOF:%02X", (uchar) BAS_NEW_EOF); error = WriteByteToWav(fileInfo.sum, ORDER_STD, fileInfo.mode ) ; if (error != ERR_OK) break ; if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf(" (%02X)", (uchar) fileInfo.sum); /* there are 2bits more HIGH at the end of transmission (at least for PC-1402) M. NOSSWITZ */ error = WriteBitToWav (1 ) ; if (error != ERR_OK) break ; error = WriteBitToWav (1 ) ; if (error != ERR_OK) break ; /* This puts 2 bits of silence (or 2 HIGH bits alternatively) to the end of the wave file. */ /* CLOAD does not accept any sound, that could be interpreted as a start bit, */ /* during post-processing. Original CSAVE switches the signal low ms after the */ /* end of transmission, before the motor of the cassette recorder is switched off. */ /* This level out is visible in the CSAVE audio signal after the last bit. T. Muecker */ /* not needed for the MBed direct-write version error = WriteBitToWav (3 ) ; 125us High , if (error != ERR_OK) break ; error = WriteBitToWav (2 ) ; 1 ms Midsignal if (error != ERR_OK) break ; */ } while (0) ; return (error); } int WriteFooterToMemoWav ( void ) { int error ; do { error = WriteByteToWav(fileInfo.sum, ORDER_STD, fileInfo.mode ) ; if (error != ERR_OK) break ; if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf(" (%02X)", (uchar) fileInfo.sum); error = WriteBitToWav (1 ) ; if (error != ERR_OK) break ; error = WriteBitToWav (1 ) ; if (error != ERR_OK) break ; /* This puts 2 bits of silence (or 2 HIGH bits alternatively) to the end of the wave file. */ /* not needed for the MBed send version error = WriteBitToWav (3 ) ; if (error != ERR_OK) break ; error = WriteBitToWav (2 ) ; if (error != ERR_OK) break ; */ } while (0) ; return (error); } // File completion check bool isFileSendComplete ( void ) { #ifdef FILE_BUF_SIZE return ( isFilePullComplete() ) ; #else return ( file_pos == BIN_FILE_SIZE - 1 ) ; #endif } // Input file data access, depends on build char fileGetNext ( void ) { // byte = fgetc (srcFd) ; // DOS / UNIX file - not applicable here #ifdef FILE_BUF_SIZE return ( filePullData () ) ; #else return ( bin_file_bytes[file_pos++] ); #endif } ///////////////////////////////////////////////////////////////////////////// // file-send implementation, largely inspired to Pocket-Tools source code int FileSend ( void ) { int pcId = PC_ID; // hardcoded for PC-1403 here uint32_t nbSync = N_SYNC_BITS; int ii; uchar type ; uint32_t nbByte; uint32_t addr; int error ; char inVal; fileInfo.nbSync = nbSync; #ifndef FILE_BUF_SIZE file_pos = 0; #endif switch (fileInfo.ident) { /* . . .*/ case IDENT_NEW_BIN : pcgrpId = GRP_NEW ; /*or GRP_EXT */ type = TYPE_BIN ; break ; /* . . .*/ case IDENT_NEW_BAS : pcgrpId = GRP_NEW ; type = TYPE_IMG ; break ; default : debug_printf ("%s: Unknown Ident\n", argP) ; return (ERR_ARG); } /* if (pcgrpId == GRP_E || pcgrpId == GRP_G || pcgrpId == GRP_16) { . . . } else { // PC-1211 to PC-1500, QTape */ if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG WriteSyncToWav\n\r"); error = WriteSyncToWav (nbSync ) ; /* . . . */ if (error != ERR_OK) return ( error ) ; switch (pcId) { /* . . . */ case 1403: /* if (type == TYPE_BIN && Acnt==0 && SHCc==0 && addr==0) */ addr = TYPE_BIN_ADDR; /* . . . */ break; default : debug_printf ("%s: Sharp PC-%d not implemented\n", argP, pcId) ; // MoreInfo (ERR_ARG); error = ERR_ARG ; // break ; } if (error != ERR_OK) return ( error ) ; /* ... else { // PC-121x ... PC-1475 */ if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG set Header Mode (ident %d)\n\r", fileInfo.ident); switch (fileInfo.ident) { /* Header Mode */ case IDENT_PC1211 : fileInfo.mode = fileInfo.mode_h = MODE_B20 ; break ; case IDENT_PC121_DAT : case IDENT_OLD_BAS : case IDENT_OLD_DAT : case IDENT_OLD_BIN : case IDENT_OLD_MEM : fileInfo.mode = fileInfo.mode_h = MODE_B19 ; break ; case IDENT_NEW_TEL : case IDENT_NEW_SCD : case IDENT_NEW_NOT : case IDENT_NEW_CRD : case IDENT_NEW_CSL : case IDENT_NEW_BAS : case IDENT_EXT_BAS : case IDENT_NEW_DAT : case IDENT_NEW_BIN : fileInfo.mode = fileInfo.mode_h = MODE_B16 ; break ; default : debug_printf ("%s: Unknown Ident\n", argP) ; fileInfo.mode = fileInfo.mode_h = MODE_B21 ; return (ERR_ARG); } if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG Header fileInfo.mode_h %u\n\r",fileInfo.mode_h); /* Write the TAPE code */ if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG Write the TAPE code\n\r"); error = WriteByteToWav ( (ulong) fileInfo.ident, ORDER_STD, fileInfo.mode_h ) ; if (error != ERR_OK) return ( error ) ; /* Write the Name */ if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG Writing Name...\n\r"); error = WriteSaveNameToWav ( "NONAME", fileInfo.mode_h ) ; // NOT USING FILENAME !! if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG error (ERR_OK) %d (%d)\n\r", error, ERR_OK); if (error != ERR_OK) return ( error ) ; if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG set Body Data Mode\n\r"); switch (fileInfo.ident) { /* Body Data Mode */ case IDENT_PC1211 : fileInfo.mode = MODE_B20 ; break ; case IDENT_PC121_DAT : case IDENT_OLD_BAS : case IDENT_OLD_BIN : case IDENT_OLD_MEM : fileInfo.mode = MODE_B19 ; break ; case IDENT_OLD_DAT : case IDENT_NEW_DAT : fileInfo.mode = MODE_B15 ; break ; case IDENT_EXT_BAS : case IDENT_NEW_BAS : case IDENT_NEW_CSL : case IDENT_NEW_TEL : case IDENT_NEW_SCD : case IDENT_NEW_NOT : case IDENT_NEW_CRD : case IDENT_NEW_BIN : // TODO (mr#2#): Check whitch MODE_B13 or _B14 if (cnvstr_upr && pcId < 1440) fileInfo.mode = MODE_B13 ; /*older part of new series*/ else fileInfo.mode = MODE_B14 ; /*new series and extended series*/ break ; default : debug_printf ("%s: Unknown Ident\n", argP) ; return ( ERR_ARG ); } if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG Body fileInfo.mode %u\n\r", fileInfo.mode); fileInfo.total = 0 ; /* count bytes of body only */ switch (fileInfo.ident) { /* header was written, write all data now */ /* ... case ... */ case IDENT_NEW_BAS : case IDENT_NEW_CSL : case IDENT_EXT_BAS : if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG Writing data...\n\r"); /* Write the datas */ // info.mode = MODE_B13 ; /* PC-1403 and newer should be MODE_14 */ /* the older simple algorithm seems to work as well, but this is now, what the PC does originally */ while ( !isFileSendComplete() ) { inVal = fileGetNext(); if ( inVal == EOF ) break ; // ending if if ( inVal == BAS_NEW_EOF ) { if (fileInfo.count + 1 == BLK_NEW && fileInfo.sum == 0xE1) { /* Constellation will generate 2-times BAS_NEW_EOF */ printf ("\nERROR %i at %lu. byte, usually the low byte of a BASIC line number\n", ERR_SUM, fileInfo.total) ; printf ("This binary constellation activates the CLOAD bug of this series. The line\n") ; printf ("number must be changed or minor changes done in the BASIC text before.\n") ; /* Seldom Bug in CLOAD, for PC-1402/(01) at known ROM address: 40666 */ if ((fileInfo.debug & 0x800) == 0 ) { error = ERR_SUM ; break ; } } } error = WriteByteSumToWav ( (uint) inVal, ORDER_STD, fileInfo.mode ) ; if (error != ERR_OK) break ; } if (error != ERR_OK) break ; if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("\n\rDEBUG ii %u\n\r", ii); inVal = fileGetNext(); /* Read the last byte before EOF mark */ if (inVal == EOF) break ; if (inVal == BAS_NEW_EOF) { /* EOF mark should not be included for this file type normally*/ if (Qcnt == 0) printf ("End of File mark %i should not be included in the image\n", inVal) ; /* if end of block, then an additional checksum would be written, but this does work anyhow */ } else { if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG last byte: %02X\n\r", (uchar) inVal); error = WriteByteToWav ( (uint) inVal, ORDER_STD, fileInfo.mode ) ; if (error != ERR_OK) break ; CheckSumB1 ((uint) inVal ) ; /* never write the checksum before BAS_NEW_EOF */ ++fileInfo.total ; ++fileInfo.count ; /* for debug purposes only, WriteFooter will reset it */ } /* Write the END code */ if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG WriteFooterToNewWav\n\r"); error = WriteFooterToNewWav ( ) ; break ; // IDENT_NEW_BAS, IDENT_EXT_BAS case IDENT_NEW_BIN : /* Write the address and length */ error = WriteHeadToBinWav (addr, nbByte, fileInfo.mode_h ) ; if (error != ERR_OK) break ; /* no break */ case IDENT_NEW_TEL : case IDENT_NEW_SCD : case IDENT_NEW_NOT : case IDENT_NEW_CRD : /* Write the datas */ while ( !isFileSendComplete() ) { inVal = fileGetNext(); if (inVal == EOF ) break ; // premature ending shouldn't happen ... error = WriteByteSumToWav ( (uint) inVal, ORDER_STD, fileInfo.mode ) ; if (error != ERR_OK) break ; } if (error != ERR_OK) break ; inVal = fileGetNext(); if (inVal == EOF) break ; if ( (fileInfo.debug & 0x0040) > 0 ) debug_printf("DEBUG %02X", (uchar) inVal); error = WriteByteToWav ( (uint) inVal, ORDER_STD, fileInfo.mode ) ; if (error != ERR_OK) break ; CheckSumB1 ( (uint) inVal ) ; /* never write the checksum before BAS_NEW_EOF */ ++fileInfo.total ; ++fileInfo.count ; /* for debug purposes only, WriteFooter will reset it */ /* Write the END code */ if ( fileInfo.ident == IDENT_NEW_BIN) error = WriteFooterToNewWav ( ) ; else WriteFooterToMemoWav ( ) ; break ; // IDENT_NEW_BIN and IDENT_NEW_Memos default: printf ("%s: Unknown Ident\n", argP) ; error = ERR_ARG; break; } return (error); }