From f3a1881d6539d6f28e4866118459cd75103df1f5 Mon Sep 17 00:00:00 2001 From: Ivan Tatarinov Date: Mon, 3 May 2021 13:32:54 +0300 Subject: [PATCH] sdk: added `GenTape` tool --- sdk/bin/.gitignore | 2 + sdk/bin/GenTape.exe | Bin 0 -> 25088 bytes sdk/bin/GenTape.exe.license | 11 + sdk/src/tools/GenTape.c | 538 ++++++++++++++++++++++++++++++++++++ sdk/src/tools/Makefile | 1 + 5 files changed, 552 insertions(+) create mode 100755 sdk/bin/GenTape.exe create mode 100644 sdk/bin/GenTape.exe.license create mode 100644 sdk/src/tools/GenTape.c diff --git a/sdk/bin/.gitignore b/sdk/bin/.gitignore index ccf57af..2c6336a 100644 --- a/sdk/bin/.gitignore +++ b/sdk/bin/.gitignore @@ -10,6 +10,8 @@ fcut fpad fpoke rcs +Png2Rcs +GenTape GenRom AddItem Bit2Bin diff --git a/sdk/bin/GenTape.exe b/sdk/bin/GenTape.exe new file mode 100755 index 0000000000000000000000000000000000000000..8f7c9697e94d4d5e23200c02171ed2e8ddc17ae7 GIT binary patch literal 25088 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 E0~6n*TmS$7 literal 0 HcmV?d00001 diff --git a/sdk/bin/GenTape.exe.license b/sdk/bin/GenTape.exe.license new file mode 100644 index 0000000..2e6530d --- /dev/null +++ b/sdk/bin/GenTape.exe.license @@ -0,0 +1,11 @@ +SPDX-FileName: GenTape.exe + +SPDX-FileType: BINARY + +SPDX-FileChecksum: SHA1: a45dbb2e6ed331da5258f0d1a1d8348a7f9e4868 + +SPDX-FileCopyrightText: Copyright (C) 2013-2015, 2021 Antonio Villena + +SPDX-License-Identifier: GPL-3.0-only + +SPDX-FileComment: GenTape version 1.0 (1 Jun 2015) - a Tape File Generator. diff --git a/sdk/src/tools/GenTape.c b/sdk/src/tools/GenTape.c new file mode 100644 index 0000000..ea50e22 --- /dev/null +++ b/sdk/src/tools/GenTape.c @@ -0,0 +1,538 @@ +/* + * GenTape - a Tape File Generator. + * + * Copyright (C) 2013-2015, 2021 Antonio Villena + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-FileCopyrightText: Copyright (C) 2013-2015, 2021 Antonio Villena + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include +#include +#include + +#define PROGRAM "GenTape" +#define DESCRIPTION "a Tape File Generator." +#define VERSION "1.0 (1 Jun 2015)" +#define COPYRIGHT "Copyright (C) 2013-2015, 2021 Antonio Villena" +#define LICENSE \ +"This program is free software: you can redistribute it and/or modify\n" \ +"it under the terms of the GNU General Public License as published by\n" \ +"the Free Software Foundation, version 3." +#define HOMEPAGE "https://github.com/zxdos/zxuno/" + +unsigned char *mem, *precalc; +char *ext, *command; +unsigned char rem= 0, inibit= 0, tzx= 0, wav= 0, channel_type= 1, + checksum, turbo, mod; +FILE *fi, *fo; +int i, j, k, l, ind= 0, nextsilence= 0; +float silence; +unsigned short length, param, frequency= 44100; + +int my_strcasecmp(const char *s1, const char *s2){ + register const unsigned char *us1= (const unsigned char *)s1, + *us2= (const unsigned char *)s2; + while ( (*us1 & 95) == (*us2++ & 95) ) + if( *us1++ == '\0' ) + return 0; + return (*us1 & 95) - (*--us2 & 95); +} + +void outbits( short val ){ + for ( i= 0; i0xff000 ) + fwrite( precalc, 1, ind, fo ), + ind= 0; + inibit^= 1; +} + +void obgen( int nor ){ + outbits( (nor+rem)/mod ); + rem= (nor+rem)%mod; +} + +char char2hex(char value, char * name){ + if( value<'0' || value>'f' || value<'A' && value>'9' || value<'a' && value>'F' ) + printf("Invalid character %c or '%s' not exists\n", value, name), + exit(-1); + return value>'9' ? 9+(value&7) : value-'0'; +} + +int parseHex(char * name, int index){ + int flen= strlen(name); + if( name[0]!='-' ) + for ( i= 0; i<10 && name[i]; i++ ) + mem[i+7]= name[i]; + else if( flen & 1 ){ + flen>>= 1; + flen>10 && index==7 && (flen= 10); + for ( i= 0; i < flen; i++ ) + mem[i+index]= char2hex(name[i+1<<1], name) | char2hex(name[i<<1|1], name) << 4; + } + while( ++i<11 ) + mem[i+6]= ' '; + return flen; +} + +int wavsilence( float msecs ){ + fwrite( precalc, 1, ind, fo ); + rem= ind= 0; + fwrite( precalc+0x100000, 1, frequency*(channel_type&3)*msecs/1000, fo); +} + +void tapewrite( unsigned char *buff, int length ){ + if( wav ){ + buff+= 2; + length-= 2; + j= *buff>>7&1 ? 3223 : 8063; + while( j-- ) + obgen( 2168*2 ); + obgen( 667*2 ); + obgen( 735*2 ); + while ( length-- ) + for( k= 0, j= *buff++; k<8; k++, j<<= 1 ) + obgen( l= 1710 << ((j & 0x80)>>7) ), + obgen( l ); + obgen( l ); + } + else + fwrite(buff, 1, length, fo); +} + +void show_help() { + printf( + PROGRAM " version " VERSION " - " DESCRIPTION "\n" + COPYRIGHT "\n" + LICENSE "\n" + "Home page: " HOMEPAGE "\n" + "\n" + "Usage:\n" + " " PROGRAM " [] [] \n" + " [ basic \n" + " | hdata
\n" + " | data \n" + " | pilot \n" + " | pulse .. \n" + " | pause \n" + " | pure \n" + " | turbo \n" + " \n" + " | stop48\n" + " | plug-xxx-N .. ]\n" + "\n" + " Target file, between TAP, TZX or WAV file\n" + " Up to 10 chars name between single quotes or in hexadecimal\n" + " In decimal, first BASIC line to execute\n" + "
In hexadecimal, address of the binary block\n" + " Hexadecimal string or filename as data origin of that block\n" + " \n" + " Length of zero/one/syncs/pilot pulses at 3.528MHz clock\n" + " \n" + " Duration of pilot/pause after block in milliseconds\n" + " Number of pulses in the sequence of pulses\n" + " Length of X-th pulse in the sequence at 3.528MHz clock\n" + " External generator, must exists xxx.exe and accept N params\n" + " stop48 Only TZX. Signal end of tape on 48K machines\n" + "\n" + " WAV options:\n" + " Sample frequency, 44100 or 48000. Default is 44100\n" + " Possible values are: mono (default), stereo or stereoinv\n" + ); +} + +int main(int argc, char* argv[]){ + mem= (unsigned char *) malloc (0x20000); + if( argc==1 ) + show_help(), + exit(0); + while( 1 ) + if( !my_strcasecmp(argv[1], "mono") || !my_strcasecmp(argv[1], "44100") ) + ++argv, --argc; + else if( !my_strcasecmp(argv[1], "stereo") ) + channel_type= 2, ++argv, --argc; + else if( !my_strcasecmp(argv[1], "stereoinv") ) + channel_type= 6, ++argv, --argc; + else if( !my_strcasecmp(argv[1], "48000") ) + frequency= 48000, ++argv, --argc; + else + break; + mod= 7056000/frequency; + if( !(ext= strchr(argv[1], '.')) ) + printf("Invalid argument name: %s\n", argv[1]), + exit(-1); + fo= fopen(argv[1], "wb+"); + if( !fo ) + printf("Cannot create output file: %s\n", argv[1]), + exit(-1); + char filename[40]; + strcpy( filename, argv[1] ); + precalc= (unsigned char *) malloc (0x200000); + if( !my_strcasecmp((char *)strchr(argv[1], '.'), ".tzx" ) ) + fprintf( fo, "ZXTape!" ), + *(int*)mem= 0xa011a, + fwrite(mem, ++tzx, 3, fo), + mem[0]= 0x10; + else if( !my_strcasecmp((char *)strchr(argv[1], '.'), ".wav" ) ){ + memset(mem, wav++, 44); + memset(precalc, 128, 0x200000); + *(int*)mem= 0x46464952; + *(int*)(mem+8)= 0x45564157; + *(int*)(mem+12)= 0x20746d66; + *(char*)(mem+16)= 0x10; + *(char*)(mem+20)= 0x01; + *(char*)(mem+22)= *(char*)(mem+32)= channel_type&3; + *(short*)(mem+24)= frequency; + *(int*)(mem+28)= frequency*(channel_type&3); + *(char*)(mem+34)= 8; + *(int*)(mem+36)= 0x61746164; + fwrite(mem, 1, 44, fo); + } + while ( argc-- > 2 ){ + wav && nextsilence && wavsilence( silence ); + if( !my_strcasecmp(argv++[2], "basic")){ + *(short*)(mem+1)= 1000; + tzx && fwrite(mem, 1, 3, fo); + param= atoi(argv[3]); + fi= fopen(argv[4], "rb"); + if( fi ) + length= fread(mem+27, 1, 0x20000-27, fi); + else + length= parseHex(argv[4], 27); + *(int*)(mem+3)= 19; + parseHex(argv[2], 7); + *(short*)(mem+17)= *(short*)(mem+21)= length; + *(short*)(mem+19)= param; + length+= 2; + *(short*)(mem+24)= length; + mem[26]= 255; + for ( checksum= 0, i= 5; i<23; ++i ) + checksum^= mem[i]; + mem[23]= checksum; + for ( checksum= 0, i= 26; i<26+length-1; ++i ) + checksum^= mem[i]; + mem[length+25]= checksum; + tapewrite(mem+3, 21); + wav && wavsilence( 1000 ); + *(short*)(mem+1)= 2000; + tzx && fwrite(mem, 1, 3, fo); + tapewrite(mem+24, length+2); + silence= nextsilence= 2000; + fclose(fi); + argc-= 3; + argv+= 3; + } + else if( !my_strcasecmp(argv[1], "hdata")){ + *(short*)(mem+1)= 1000; + tzx && fwrite(mem, 1, 3, fo); + param= strtol(argv[3], NULL, 16); + fi= fopen(argv[4], "rb"); + if( fi ) + length= fread(mem+27, 1, 0x20000-27, fi); + else + length= parseHex(argv[4], 27); + *(short*)(mem+1)= 1000; + *(short*)(mem+3)= 19; + *(short*)(mem+5)= 0x300; + parseHex(argv[2], 7); + *(short*)(mem+17)= length; + *(short*)(mem+19)= param; + *(unsigned short*)(mem+21)= 0x8000; + length+= 2; + *(short*)(mem+24)= length; + mem[26]= 255; + for ( checksum= 0, i= 5; i<23; ++i ) + checksum^= mem[i]; + mem[23]= checksum; + for ( checksum= 0, i= 26; i<26+length-1; ++i ) + checksum^= mem[i]; + mem[length+25]= checksum; + tapewrite(mem+3, 21); + wav && wavsilence( 1000 ); + *(short*)(mem+1)= 2000; + tzx && fwrite(mem, 1, 3, fo); + tapewrite(mem+24, length+2); + silence= nextsilence= 2000; + fclose(fi); + argc-= 3; + argv+= 3; + } + else if( !my_strcasecmp(argv[1], "data")){ + *(short*)(mem+1)= 2000; + tzx && fwrite(mem, 1, 3, fo); + fi= fopen(argv[2], "rb"); + if( fi ) + length= fread(mem+6, 1, 0x20000-6, fi); + else + length= parseHex(argv[2], 6); + *(short*)(mem+3)= length+= 2; + mem[5]= 255; + for ( checksum= 0, i= 5; i<5+length-1; ++i ) + checksum^= mem[i]; + mem[length+4]= checksum; + tapewrite(mem+3, length+2); + silence= nextsilence= 2000; + fclose(fi); + --argc; + ++argv; + } + else if( !my_strcasecmp(argv[1], "pause")){ + nextsilence= silence= atof(argv[2]); + if( tzx ) + mem[1]= 0x20, + *(short*)(mem+2)= nextsilence, + fwrite(mem+1, 1, 3, fo); + else if( !wav ) + printf("Error: pause command not allowed in TAP files\n"), + exit(-1); + --argc; + ++argv; + } + else if( !my_strcasecmp(argv[1], "pilot")){ + k= atoi(argv[2]); + if( tzx ) + mem[1]= 0x12, + *(short*)(mem+2)= k, + *(unsigned short*)(mem+4)= atof(argv[3])*3500/k+0.5, + fwrite(mem+1, 1, 5, fo); + else if( wav ){ + k<<= 1; + j= atof(argv[3])*7056/k+0.5; + while( j-- ) + obgen( k ); + } + else + printf("Error: pilot command not allowed in TAP files\n"), + exit(-1); + nextsilence= 0; + argc-= 2; + argv+= 2; + } + else if( !my_strcasecmp(argv[1], "pulse")){ + k= atoi(argv++[2]); + if( tzx ){ + mem[1]= 0x13; + *(unsigned char*)(mem+2)= k; + for ( j= 0; j>16; + fwrite(mem+1, 1, length+19, fo); + } + else{ + mem[1]= 0x14; + *(short*)(mem+2)= atoi(argv++[2]); + *(short*)(mem+4)= atoi(argv++[2]); + *(char*)(mem+6)= 8; + *(unsigned short*)(mem+7)= atoi(argv++[2]); + if( fi ) + length= fread(mem+12, 1, 0x20000-12, fi); + else + length= parseHex(argv[2], 12); + *(unsigned short*)(mem+9)= length; + *(unsigned char*)(mem+11)= length>>16; + fwrite(mem+1, 1, length+11, fo); + } + ++argv; + } + else if( wav ){ + if( turbo ){ + k= atoi(argv[2]) << 1; + j= atof(argv[7])*7056/k+0.5; + while( j-- ) + obgen( k ); + obgen( atoi(argv[3]) << 1 ); + obgen( atoi(argv[4]) << 1 ); + } + if( fi ) + length= fread(mem, 1, 0x20000, fi); + else + length= parseHex(argv[5+turbo*4], 0); + j= 0; + param= atoi(argv[2+turbo*3]) << 1; + k= atoi(argv[3+turbo*3]) << 1; + while ( length-- ) + for( wav= 0, checksum= mem[j++]; wav<8; wav++, checksum<<= 1 ) + obgen( l= checksum & 0x80 ? k : param ), + obgen( l ); + obgen( l ); + fclose(fi); + argv+= turbo+1<<2; + nextsilence= silence= atof(argv[0]); + } + else + printf("Error: pure or turbo command not allowed in TAP files\n"), + exit(-1); + argc-= turbo+1<<2; + } + else if( strchr(argv[1], '-') + && (*strchr(argv[1], '-')= 0, !my_strcasecmp(argv[1], "plug")) ){ + argv[1]+= 5; + k= atoi(strstr(argv[1], "-")+1); + *strchr(argv[1], '-')= 0; + command= (char *) malloc (0x100); + sprintf(command, "%s %d %s tmp.%s", argv[1], frequency, + channel_type-1 ? (channel_type-2?"stereoinv":"stereo") : "mono", ext+1); + argc-= k; + while( k-- ) + strcat(command, " "), + strcat(command, argv++[2]); + if( system(command) ) + printf("Error: plug error with command: %s\n", command), + exit(-1); + else{ + fwrite( precalc, 1, ind, fo ); + rem= ind= 0; + sprintf(command, "tmp.%s", ext+1); + fi= fopen(command, "rb"); + if( fi ){ + if( tzx ) + fseek(fi, 0, SEEK_END), + i= ftell(fi)-10, + fseek(fi, 10, SEEK_SET); + else + 0!=fread(mem, 1, 44, fi), + i= *(int*)(mem+40); + j= i>>20; + k= i&0xfffff; + for ( int i= 0; i