From 5d413a61fd82bf04d8b569da4bf5f360aae83f41 Mon Sep 17 00:00:00 2001 From: sorgelig Date: Tue, 11 Jun 2019 06:42:20 +0800 Subject: [PATCH] Remove TZX parser. --- MiSTer.vcxproj | 2 - MiSTer.vcxproj.filters | 6 - tzx2wav.cpp | 1395 ---------------------------------------- tzx2wav.h | 3 - user_io.cpp | 87 ++- 5 files changed, 37 insertions(+), 1456 deletions(-) delete mode 100644 tzx2wav.cpp delete mode 100644 tzx2wav.h diff --git a/MiSTer.vcxproj b/MiSTer.vcxproj index 93ca23e..f136b04 100644 --- a/MiSTer.vcxproj +++ b/MiSTer.vcxproj @@ -84,7 +84,6 @@ - @@ -135,7 +134,6 @@ - diff --git a/MiSTer.vcxproj.filters b/MiSTer.vcxproj.filters index 8cd303b..568acde 100644 --- a/MiSTer.vcxproj.filters +++ b/MiSTer.vcxproj.filters @@ -70,9 +70,6 @@ Source Files - - Source Files - Source Files @@ -213,9 +210,6 @@ Header Files - - Header Files - Header Files diff --git a/tzx2wav.cpp b/tzx2wav.cpp deleted file mode 100644 index 0e45bca..0000000 --- a/tzx2wav.cpp +++ /dev/null @@ -1,1395 +0,0 @@ -///////////////////////////////////////////////////////////////////// -// TZX to VAV Converter v0.2 for Bloodshed Dev-C++ compiler // -// (C) 2005-2006 Francisco Javier Crespo // -// // -// MiSTer adaptation (CSW v1 only) // -// (C) 2017 Francisco Javier Crespo // -// // -// Originally based on source code from these works: // -// PLAYTZX v0.60b for Watcom C compiler (C) 1997-2004 Tomaz Kac // -// PLAYTZX Unix v0.12b (C) 2003 Tero Turtiainen / Fredrick Meunier // -///////////////////////////////////////////////////////////////////// - -#include -#include -#include -#include -#include -#include -#include -#include "tzx2wav.h" -#include "spi.h" - -// Computer entries -const char *hwids_01[] = { - "ZX Spectrum 16k", - "ZX Spectrum 48k, Plus", - "ZX Spectrum 48k Issue 1", - "ZX Spectrum 128k (Sinclair)", - "ZX Spectrum 128k +2 (Grey case)", - "ZX Spectrum 128k +2A, +3", - "Timex Sinclair TC-2048", - "Timex Sinclair TS-2068", - "Pentagon 128", - "Sam Coupe", - "Didaktik M", - "Didaktik Gama", - "ZX-81 with 1k RAM", - "ZX-81 with 16k RAM or more", - "ZX Spectrum 128k, Spanish version", - "ZX Spectrum, Arabic version", - "TK 90-X", - "TK 95", - "Byte", - "Elwro", - "ZS Scorpion", - "Amstrad CPC 464", - "Amstrad CPC 664", - "Amstrad CPC 6128", - "Amstrad CPC 464+", - "Amstrad CPC 6128+", - "Jupiter ACE" - "Enterprise", - "Commodore 64", - "Commodore 128" -}; - -#define MAJREV 1 // Major revision of the format this program supports -#define MINREV 13 // Minor revision of the format this program supports - -// C64 Loader defines ... - -#define ROM_S_HALF 616 // ROM Loader SHORT Half Wave -#define ROM_M_HALF 896 // ROM Loader MEDIUM Half Wave -#define ROM_L_HALF 1176 // ROM Loader LONG Half Wave - -#define STT_0_HALF 426 // Standard Turbo Tape BIT 0 Half Wave -#define STT_1_HALF 596 // Standard Turbo Tape BIT 1 Half Wave - -// Other defines ... - -#define LOAMP 0x26 // Low Level Amplitude (-3 dB) -#define HIAMP 0xDA // High Level Amplitude (-3 dB) -static unsigned int freq = 44100; // Default Sample Frequency - -static unsigned char *mem = 0; // File in Memory -static int pos; // Position in File -static int curr; // Current block that is playing -static int numblocks; // Total Num. of blocks -static unsigned long oflen; // Length of output file -static int block[2048]; // Array of Block starts -static double cycle; // Frequency / 3500000 (Z80 clock) - -static int cpc=0; // Amstrad CPC tape ? -static int sam=0; // SAM Coupe tape ? - -static int id; // Current Block ID -static int pilot; // Len of Pilot signal (in hp's) -static int sb_pilot; // Pilot pulse -static int sb_sync1; // Sync first half-period (hp) -static int sb_sync2; // Sync second -static int sb_bit0; // Bit-0 -static int sb_bit1; // Bit-1 -static int sb_pulse; // Pulse in Sequence of pulses and direct recording block -static int lastbyte; // How many bits are in last byte of data ? -static int pause_ms; // Pause after current block (in milliseconds) -static int skippause=0; // Overrides pause value in last TZX block - -static int singlepulse; // Flag to activate single pulse waves -static int manchester; // Flag to activate manchester encoded waves - -static unsigned char *data; // Data to be played -static int datalen; // Len of ^^^ -static int datapos; // Position in ^^^ -static int bitcount; // How many bits to play in current byte ? -static int sb_bit; // should we play bit 0 or 1 ? -static char databyte; // Current Byte to be replayed of the data -static signed short jump; // Relative Jump -static int not_rec; // Some blocks were not recognised ?? -static int starting=1; // starting block -static int ending=0; // ending block - -static int expand=0; // Expand Groups ? -static int draw=1; // Local flag for outputing a line when in a group - -static int speed; - -static int loop_start=0; // Position of the last Loop Start block -static int loop_count=0; // Counter of the Loop -static int call_pos=0; // Position of the last Call Sequence block -static int call_num=0; // Number of Calls in the last Call Sequence block -static int call_cur=0; // Current Call to be made -static int num_sel; // Number of Selections in the Select block -static int jumparray[256]; // Array of all possible jumps in Select block - -static int sb_bit0_f, sb_bit0_s, sb_bit1_f, sb_bit1_s, xortype, sb_finishbyte_f, - sb_finishbyte_s, sb_finishdata_f, sb_finishdata_s, num_lead_in, xorvalue; -static int trailing, sb_trailing; -static char lead_in_byte; -static int endian; -static char add_bit; - -static int inv = 0; - -static char tstr[255]; -static char spdstr[255]; -static char pstr[255]; - -static void core_write(const void *buf, int size) -{ - const char *addr = (const char*)buf; - while (size--) - { - spi8(*addr++); - oflen++; - } -} - -/////////////////////////////// -// CSW v1.01 handling routines -/////////////////////////////// - -static int amp, cswamp; -static unsigned int cswlen; - -void CSW1_Init(void) -{ - // Official CSW format documentation at: - // http://www.ramsoft.bbk.org/csw.html - - unsigned short Revision = 0x0101; - unsigned char CompType = 1; - unsigned int Reserved = 0; - - core_write("Compressed Square Wave\032", 23); - core_write(&Revision, 2); // Major & Minor revision - core_write(&freq, 2); // Sample Rate - core_write(&CompType, 1); // Compression Type - core_write(&inv, 1); // Polarity - core_write(&Reserved, 3); // Reserved bytes - - cswamp = LOAMP; - cswlen = 0; -} - -void CSW1_Write(unsigned int samples) -{ - if (cswamp == amp) - { - cswlen += samples; - return; - } - if (cswlen < 256) - { - core_write(&cswlen, 1); - } - else - { - int zero = 0; - core_write(&zero, 1); - core_write(&cswlen, 4); - } - - cswamp = amp; - cswlen = samples; -} - -////////////////////////////////// -// Generic wave handling routines -////////////////////////////////// - -unsigned int Samples(unsigned int n) -{ - // Convert a sampling value in Z80 T-States to samples for wave output - return ((unsigned int)(0.5 + (cycle*(double)n))); -} - -void ToggleAmp(void) -{ - // Toggles the sign of the wave - // WHOLE CONCEPT TO BE RECODED IN ToggleSgn(); - - if (amp == LOAMP) amp = HIAMP; - else amp = LOAMP; -} - -void PlayWave(unsigned int len) -{ - CSW1_Write(len); -} - -void PauseWave(unsigned int pause_ms) -{ - // Waits for "pause" milliseconds - - int p; - if (((!skippause) || (curr != (numblocks - 1)))) - { - if (!curr && pause_ms > 2000) pause_ms = 2000; - p = (unsigned int)((((float)pause_ms)*freq) / 1000.0); - PlayWave(p); - } -} - -void PlayFinish() -{ - if (cswlen) - { - ToggleAmp(); - CSW1_Write(0); - } -} - -///////////////////////////// -// TZX Commodore 64 routines -///////////////////////////// - -void PlayC64(unsigned int len) -{ - PlayWave(len); - ToggleAmp(); - PlayWave(len); - ToggleAmp(); -} - -void PlayC64ROMByte(char byte, int finish) -{ - xorvalue = xortype; - while (bitcount) - { - if (!endian) sb_bit = byte & 0x01; - else sb_bit = byte & 0x80; - if (sb_bit) - { - if (sb_bit1_f) PlayC64(sb_bit1_f); - if (sb_bit1_s) PlayC64(sb_bit1_s); - xorvalue ^= sb_bit; - } - else - { - if (sb_bit0_f) PlayC64(sb_bit0_f); - if (sb_bit0_s) PlayC64(sb_bit0_s); - xorvalue ^= sb_bit; - } - if (!endian) byte >>= 1; - else byte <<= 1; - bitcount--; - } - if (xortype != 0xFF) - { - if (xorvalue) - { - if (sb_bit1_f) PlayC64(sb_bit1_f); - if (sb_bit1_s) PlayC64(sb_bit1_s); - } - else - { - if (sb_bit0_f) PlayC64(sb_bit0_f); - if (sb_bit0_s) PlayC64(sb_bit0_s); - } - } - if (!finish) - { - if (sb_finishbyte_f) PlayC64(sb_finishbyte_f); - if (sb_finishbyte_s) PlayC64(sb_finishbyte_s); - } - else - { - if (sb_finishdata_f) PlayC64(sb_finishdata_f); - if (sb_finishdata_s) PlayC64(sb_finishdata_s); - } -} - -void PlayC64TurboByte(char byte) -{ - int add_num; - - add_num = add_bit & 3; - - if (add_num && !(add_bit & 4)) - { - while (add_num) - { - if (add_bit & 8) PlayC64(sb_bit1); - else PlayC64(sb_bit0); - add_num--; - } - } - - while (bitcount) - { - if (!endian) sb_bit = byte & 0x01; - else sb_bit = byte & 0x80; - if (sb_bit) PlayC64(sb_bit1); - else PlayC64(sb_bit0); - if (!endian) byte >>= 1; - else byte <<= 1; - bitcount--; - } - - if (add_num && (add_bit & 4)) - { - while (add_num) - { - if (add_bit & 8) PlayC64(sb_bit1); - else PlayC64(sb_bit0); - add_num--; - } - } -} - -//////////////////////////////// -// Game identification routines -//////////////////////////////// - -void GetC64ROMName(char *name, unsigned char *data) -{ - char d; - int n = 0; - for (; n < 16; n++) - { - d = data[14 + n]; - if (d < 32 || d>125) - name[n] = ' '; - else - name[n] = d; - } - name[n] = 0; -} - -void GetC64StandardTurboTapeName(char *name, unsigned char *data) -{ - char d; - int n = 0; - for (; n < 16; n++) - { - d = data[15 + n]; - if (d < 32 || d>125) - name[n] = ' '; - else - name[n] = d; - } - name[n] = 0; -} - -void IdentifyC64ROM(int pos, unsigned char *data, int type) -{ - char name[255]; - - // Determine Loader type - if ((sb_pilot == ROM_S_HALF) && (sb_sync1 == ROM_L_HALF) && (sb_sync2 == ROM_M_HALF) && - (sb_bit0_f == ROM_S_HALF) && (sb_bit0_s == ROM_M_HALF) && (sb_bit1_f == ROM_M_HALF) && - (sb_bit1_s == ROM_S_HALF) && (xortype == 0x01)) - { - // ROM Loader - if ((data[0] == 0x89) && (data[1] == 0x88) && (data[2] == 0x87) && (data[3] == 0x86) && - (data[4] == 0x85) && (data[5] == 0x84) && (data[6] == 0x83) && (data[7] == 0x82) && - (data[8] == 0x81)) - { - if (pos == 202) - { - if (!type) - { - strcpy(name, "Header: "); - GetC64ROMName(name + 8, data); - } - else - { - strcpy(name, "ROM Header: "); - GetC64ROMName(name + 12, data); - } - } - else - { - if (!type) - { - strcpy(name, "Data Block "); - } - else - { - strcpy(name, "ROM: Data Block"); - } - } - } - else - { - if (!type) strcpy(name, "------------------------"); - else strcpy(name, "ROM: Last Block Repeated"); - } - strcpy(tstr, name); - strcpy(spdstr, "C64 ROM Data "); - return; - } - - if (!type) strcpy(tstr, "------------------------"); - else strcpy(tstr, "Unknown"); - strcpy(spdstr, "C64 Data "); -} - -void IdentifyC64Turbo(int pos, unsigned char *data, int type) -{ - char name[255]; - - // Determine Loader type - if (sb_bit0 == STT_0_HALF && sb_bit1 == STT_1_HALF && lead_in_byte == 0x02) - { - // Standard Turbo Tape Loader - if (data[0] == 0x09 && data[1] == 0x08 && data[2] == 0x07 && data[3] == 0x06 && - data[4] == 0x05 && data[5] == 0x04 && data[6] == 0x03 && data[7] == 0x02 && - data[8] == 0x01) - { - if (pos == 32 && data[9] != 0x00) - { - if (!type) - { - strcpy(name, "Header: "); - GetC64StandardTurboTapeName(name + 8, data); - } - else - { - strcpy(name, "TurboTape Header: "); - GetC64StandardTurboTapeName(name + 18, data); - } - } - else - { - if (!type) strcpy(name, "------------------------"); - else strcpy(name, "TurboTape Data Block"); - } - } - else - { - if (!type) strcpy(name, "------------------------"); - else strcpy(name, "TurboTape Unknown"); - } - strcpy(tstr, name); - strcpy(spdstr, "C64 Turbo "); - return; - } - if (!type) strcpy(tstr, "------------------------"); - else strcpy(tstr, "Unknown"); - strcpy(spdstr, "C64 Data "); -} - -void Identify(int len, unsigned char *temp, int type) -{ - int n; - int s; - - if (cpc) - { - if (temp[0] == 44) - { - if (!type) s = 4; - else s = 0; - strcpy(tstr, " "); - for (n = 0; n < 16; n++) - { - if (temp[n + 1]) tstr[n + s] = temp[n + 1]; - else tstr[n + s] = ' '; - } - for (n = 0; n < 4; n++) tstr[n + s + 16] = ' '; - tstr[n + s + 16] = 0; - } - else - { - if (!type) - strcpy(tstr, " ------------------ "); - else - strcpy(tstr, "Headerless"); - } - return; - } - - if (sam) - { - if (temp[0] == 1 && (len>80 && len < 84) && (temp[1] >= 0x10 && temp[1] <= 0x13)) - { - if (!type) - { - s = 14; - switch (temp[1]) - { - case 0x10: strcpy(tstr, " Program : "); break; - case 0x11: strcpy(tstr, " Num. Array : "); break; - case 0x12: strcpy(tstr, "Char. Array : "); break; - case 0x13: strcpy(tstr, " Bytes : "); break; - } - } - else - { - switch (temp[1]) - { - case 0x10: strcpy(tstr, "Program : "); s = 10; break; - case 0x11: strcpy(tstr, "Num. Array : "); s = 13; break; - case 0x12: strcpy(tstr, "Char. Array : "); s = 14; break; - case 0x13: strcpy(tstr, "Bytes : "); s = 8; break; - } - } - for (n = 0; n < 10; n++) - { - if (temp[n + 2]>31 && temp[n + 2] < 127) - tstr[n + s] = temp[n + 2]; - else - tstr[n + s] = 32; - } - tstr[n + s] = 0; - } - else - { - if (!type) - strcpy(tstr, " --------------------"); // Not Header - else - strcpy(tstr, "Headerless"); - } - return; - } - - if (temp[0] == 0 && (len == 19 || len == 20) && temp[1] < 4) - { - if (!type) - { - s = 14; - switch (temp[1]) - { - case 0x00: strcpy(tstr, " Program : "); break; - case 0x01: strcpy(tstr, " Num. Array : "); break; - case 0x02: strcpy(tstr, "Char. Array : "); break; - case 0x03: strcpy(tstr, " Bytes : "); break; - } - } - else - { - switch (temp[1]) - { - case 0x00: strcpy(tstr, "Program : "); s = 10; break; - case 0x01: strcpy(tstr, "Num. Array : "); s = 13; break; - case 0x02: strcpy(tstr, "Char. Array : "); s = 14; break; - case 0x03: strcpy(tstr, "Bytes : "); s = 8; break; - } - } - for (n = 0; n < 10; n++) - { - if (temp[n + 2]>31 && temp[n + 2] < 127) - tstr[n + s] = temp[n + 2]; - else - tstr[n + s] = 32; - } - tstr[n + s] = 0; - } - else - { - if (!type) - strcpy(tstr, " --------------------"); // Not Header - else - strcpy(tstr, "Headerless"); - } -} - -////////////////////////////////////////////////////////// -// Conversion routines to fetch bytes in Big Endian order -////////////////////////////////////////////////////////// - -unsigned int Get2(unsigned char *pointer) -{ - return (pointer[0] | (pointer[1] << 8)); -} - -unsigned int Get3(unsigned char *pointer) -{ - return (pointer[0] | (pointer[1] << 8) | (pointer[2] << 16)); -} - -unsigned int Get4(unsigned char *pointer) -{ - return (pointer[0] | (pointer[1] << 8) | (pointer[2] << 16) | (pointer[3] << 24)); -} - -///////////////////////// -// Miscelaneous routines -///////////////////////// - -void CopyString(char *destination, unsigned char *source, unsigned int len) -{ - // Could just use strcpy ... - - unsigned int n; - for (n = 0; n < len; n++) - destination[n] = source[n]; - destination[n] = 0; -} - -void MakeFixedString(char *s, int i) -{ - // This will create a fixed length string from null-terminated one... - - int n = 0; - int k = 0; - - while (i) - { - if (!s[n]) k = 1; - if (k) s[n] = ' '; - n++; - i--; - } - s[n] = 0; -} - -/////////////////////////////// -// TZX Blocks Parsing routines -/////////////////////////////// - -void Analyse_ID10(void) // Standard Loading Data block -{ - pause_ms = Get2(&data[0]); - datalen = Get2(&data[2]); - data += 4; - if (data[0] == 0x00) pilot = 8064; - else pilot = 3220; - sb_pilot = Samples(2168); - sb_sync1 = Samples(667); - sb_sync2 = Samples(735); - sb_bit0 = Samples(885); - sb_bit1 = Samples(1710); - lastbyte = 8; -} - -void Analyse_ID11(void) // Custom Loading Data block -{ - sb_pilot = Samples(Get2(&data[0])); - sb_sync1 = Samples(Get2(&data[2])); - sb_sync2 = Samples(Get2(&data[4])); - sb_bit0 = Samples(Get2(&data[6])); - sb_bit1 = Samples(Get2(&data[8])); - speed = (int)((1710.0 / (double)Get2(&data[8]))*100.0); - pilot = Get2(&data[10]); - lastbyte = (int)data[12]; - pause_ms = Get2(&data[13]); - datalen = Get3(&data[15]); - data += 18; -} - -void Analyse_ID12(void) // Pure Tone -{ - sb_pilot = Samples(Get2(&data[0])); - pilot = Get2(&data[2]); - if (draw) printf(" Pure Tone Length: %5d\n", pilot); - while (pilot) - { - PlayWave(sb_pilot); - ToggleAmp(); - pilot--; - } -} - -void Analyse_ID13(void) // Sequence of Pulses -{ - pilot = (int)data[0]; data++; - if (draw) printf(" Sequence of Pulses Length: %5d\n", pilot); - while (pilot) - { - sb_pulse = Samples(Get2(&data[0])); - PlayWave(sb_pulse); - ToggleAmp(); - pilot--; - data += 2; - } -} - -void Analyse_ID14(void) // Pure Data -{ - sb_pilot = pilot = sb_sync1 = sb_sync2 = 0; - sb_bit0 = Samples(Get2(&data[0])); - sb_bit1 = Samples(Get2(&data[2])); - speed = (int)((1710.0 / (double)Get2(&data[2]))*100.0); - lastbyte = (int)data[4]; - pause_ms = Get2(&data[5]); - datalen = Get3(&data[7]); - data += 10; -} - -void Analyse_ID15(void) // Direct Recording -{ - // For now the BEST way is to use the sample frequency for replay that is - // exactly the SAME as the Original Freq. used when sampling this block ! - // i.e. NO downsampling is handled YET ... use TAPER when you need it ! ;-) - - sb_pulse = Samples(Get2(&data[0])); - if (!sb_pulse) sb_pulse = 1; // In case sample frequency > 44100 - pause_ms = Get2(&data[2]); // (Should work for frequencies upto 48000) - lastbyte = (int)data[4]; - datalen = Get3(&data[5]); - if (draw) printf(" Direct Recording Length:%6d Original Freq.: %5d Hz\n", - datalen, (int)(0.5 + (3500000.0 / (double)Get2(&data[0])))); - data = &data[8]; - datapos = 0; - // Replay Direct Recording block ... - while (datalen) - { - if (datalen != 1) bitcount = 8; - else bitcount = lastbyte; - databyte = data[datapos]; - while (bitcount) - { - if (databyte & 0x80) amp = HIAMP; - else amp = LOAMP; - PlayWave(sb_pulse); - databyte <<= 1; - bitcount--; - } - datalen--; - datapos++; - } - ToggleAmp(); - if (pause_ms) PauseWave(pause_ms); -} - -void Analyse_ID16(void) // C64 ROM Type Data Block -{ - data += 4; - sb_pilot = Get2(&data[0]); - pilot = Get2(&data[2]); - sb_sync1 = Get2(&data[4]); - sb_sync2 = Get2(&data[6]); - sb_bit0_f = Get2(&data[8]); - sb_bit0_s = Get2(&data[10]); - sb_bit1_f = Get2(&data[12]); - sb_bit1_s = Get2(&data[14]); - xortype = (int)(data[16]); - sb_finishbyte_f = Get2(&data[17]); - sb_finishbyte_s = Get2(&data[19]); - sb_finishdata_f = Get2(&data[21]); - sb_finishdata_s = Get2(&data[23]); - sb_trailing = Get2(&data[25]); - trailing = Get2(&data[27]); - lastbyte = (int)(data[29]); - endian = data[30]; - pause_ms = Get2(&data[31]); - datalen = Get3(&data[33]); - data += 36; - IdentifyC64ROM(datalen, data, 1); -} - -void Analyse_ID17(void) // C64 Turbo Tape Data Block -{ - data += 4; - sb_bit0 = Get2(&data[0]); - sb_bit1 = Get2(&data[2]); - add_bit = data[4]; - num_lead_in = Get2(&data[5]); - lead_in_byte = data[7]; - lastbyte = (int)data[8]; - endian = data[9]; - trailing = Get2(&data[10]); - sb_trailing = data[12]; - pause_ms = Get2(&data[13]); - datalen = Get3(&data[15]); - data += 18; - IdentifyC64Turbo(datalen, data, 1); -} - -void Analyse_ID20(void) // Pause or Stop the Tape command -{ - pause_ms = Get2(&data[0]); - amp = LOAMP; - if (pause_ms) - { - if (draw) printf(" Pause Length: %2.3fs\n", ((float)pause_ms) / 1000.0); - PauseWave(pause_ms); - amp = LOAMP; - } - else - { - if (draw) printf(" Stop the tape command!\n"); - PauseWave(2000); // 2 seconds of pause in "Stop Tape" wave output - amp = LOAMP; - } -} - -void Analyse_ID21(void) // Group Start -{ - CopyString(pstr, &data[1], data[0]); - if (draw) printf(" Group: %s\n", pstr); - if (!expand) draw = 0; -} - -void Analyse_ID22(void) // Group End -{ - if (draw) printf(" Group End\n"); - draw = 1; -} - -void Analyse_ID23(void) // Jump To Relative -{ - jump = (signed short)(data[0] + data[1] * 256); - if (draw) printf(" Jump Relative: %d (To Block %d)\n", jump, curr + jump + 1); - curr += jump; - curr--; -} - -void Analyse_ID24(void) // Loop Start -{ - loop_start = curr; - loop_count = Get2(&data[0]); - if (draw) printf(" Loop Start, Counter: %d\n", loop_count); -} - -void Analyse_ID25(void) // Loop End -{ - loop_count--; - if (loop_count > 0) - { - if (draw) printf(" Loop End, Still To Go %d Time(s)!\n", loop_count); - curr = loop_start; - } - else - { - if (draw) printf(" Loop End, Finished\n"); - } -} - -void Analyse_ID26(void) // Call Sequence -{ - call_pos = curr; - call_num = Get2(&data[0]); - call_cur = 0; - jump = (signed short)(data[2] + data[3] * 256); - if (draw) printf(" Call Sequence, Number of Calls : %d, First: %d (To Block %d)\n", call_num, jump, curr + jump + 1); - curr += jump; - curr--; -} - -void Analyse_ID27(void) // Return from Sequence -{ - call_cur++; - if (call_cur == call_num) - { - if (draw) printf(" Return from Call, Last Call Finished\n"); - curr = call_pos; - } - else - { - curr = call_pos; - data = &mem[block[curr] + 1]; - jump = (signed short)(data[call_cur * 2 + 2] + data[call_cur * 2 + 3] * 256); - if (draw) printf(" Return from Call, Calls Left: %d, Next: %d (To Block %d)\n", - call_num - call_cur, jump, curr + jump + 1); - curr += jump; - curr--; - } -} - -void Analyse_ID28(void) // Select Block -{ - num_sel = data[2]; - printf(" Select :\n"); - data += 3; - for (int n = 0; n < num_sel; n++) - { - jump = (signed short)(data[0] + data[1] * 256); - jumparray[n] = jump; - CopyString(spdstr, &data[3], data[2]); - printf("%5d : %s\n", n + 1, spdstr); - data += 3 + data[2]; - } - - //no interactive shell. choose 1. - PauseWave(200); - int k = 1; - amp = LOAMP; - - /* - printf(">> Press the number!\n"); - PauseWave(5000); // Why?!?!?!?! - k = getchar(); - if (k == 27) Error("ESCAPE key pressed!"); - k -= 48; - if (k<1 || k>num_sel) printf("Illegal Selection... Continuing...\n"); - else - */ - { - curr += jumparray[k - 1]; - curr--; - } -} - -void Analyse_ID2A(void) // Stop the tape if in 48k mode -{ - if (draw) printf(" Stop the tape in 48k mode!\n"); - PauseWave(3000); - amp=LOAMP; -} - -void Analyse_ID30(void) // Description -{ - CopyString(pstr, &data[1], data[0]); - if (draw) printf(" Description: %s\n", pstr); -} - -void Analyse_ID31(void) // Message -{ - CopyString(pstr, &data[2], data[1]); - // Pause in Message block is ignored ... - if (draw) printf(" Message: %s\n", pstr); -} - -void Analyse_ID32(void) // Archive Info -{ - if (draw) - { - if (data[3] == 0) - { - CopyString(spdstr, &data[5], data[4]); - sprintf(tstr, " Title: %s", spdstr); - MakeFixedString(tstr, 69); - strcpy(tstr + 52, " (-v for more)"); - printf("%s\n", tstr); - } - else - { - sprintf(tstr, " Archive Info"); - MakeFixedString(tstr, 69); - strcpy(tstr + 52, " (-v for more)"); - printf("%s\n", tstr); - } - } -} - -void Analyse_ID33(void) // Hardware Info -{ - if (data[1] == 0 && data[2] > 0x14 && data[2] < 0x1a && data[3] == 1) cpc = 1; - if (data[1] == 0 && data[2] == 0x09 && data[3] == 1) sam = 1; - if (draw) - { - if (data[1] != 0 || data[3] != 1) - { - sprintf(tstr, " Hardware Type"); - MakeFixedString(tstr, 69); - strcpy(tstr + 52, " (-v for more)"); - printf("%s\n", tstr); - } - else - { - printf(" This tape is made for %s !\n", hwids_01[data[2]]); - } - } -} - -void Analyse_ID34(void) // Emulation info -{ - if (draw) printf(" Information for emulators.\n"); -} - -void Analyse_ID35(void) // Custom Info -{ - CopyString(pstr, data, 16); - if (draw) - { - if (strcmp(pstr, "POKEs ")) - printf(" Custom Info: %s\n", pstr); - // Only Name of Custom info except POKEs is used ... - else - { - sprintf(tstr, " Custom Info: %s", pstr); - MakeFixedString(tstr, 69); - strcpy(tstr + 52, " (-v for more)"); - printf("%s\n", tstr); - } - } -} - -void Analyse_ID40(void) // Snapshot -{ - if (draw) printf(" Snapshot (Not Supported yet)\n"); -} - -void Analyse_ID5A(void) // ZXTape! -{ - if (draw) printf(" Start of the new tape (Merged Tapes)\n"); -} - -void Analyse_Unknown(void) // Unknown blocks -{ - if (draw) printf(" Unknown block %02X !\n", id); -} - -//////////////////////// -// Main TZX2WAV program -//////////////////////// - -int tzx2csw(fileTYPE *f) -{ - freq = 44100; - starting = 1; - ending = 0; - expand = 0; - skippause = 0; - inv = 0; - oflen = 0; - - mem = (unsigned char *)malloc(f->size); - if (mem == NULL) - { - printf("\n-- Not enough memory to load the file!"); - return 0; - } - - // Start reading file... - FileReadAdv(f, mem, 10); - mem[7] = 0; - - if (strcmp((const char*)mem, "ZXTape!")) - { - printf("\n-- File is not in ZXTape format!"); - free(mem); - return 0; - } - - printf("\nZXTape file revision %d.%02d\n", mem[8], mem[9]); - if (!mem[8]) - { - printf("\n-- Development versions of ZXTape format are not supported!"); - free(mem); - return 0; - } - - if (mem[8] > MAJREV) printf("\n-- Warning: Some blocks may not be recognised and used!\n"); - if (mem[8] == MAJREV && mem[9] > MINREV) printf("\n-- Warning: Some of the data might not be properly recognised!\n"); - FileReadAdv(f, mem, f->size - 10); - numblocks = 0; pos = 0; - not_rec = 0; - - // Go through the file and record block starts ... - // (not necessary, could just go right through it) - - while (pos < f->size - 10) - { - block[numblocks] = pos; - pos++; - switch (mem[pos - 1]) - { - case 0x10: pos += Get2(&mem[pos + 0x02]) + 0x04; break; - case 0x11: pos += Get3(&mem[pos + 0x0F]) + 0x12; break; - case 0x12: pos += 0x04; break; - case 0x13: pos += (mem[pos + 0x00] * 0x02) + 0x01; break; - case 0x14: pos += Get3(&mem[pos + 0x07]) + 0x0A; break; - case 0x15: pos += Get3(&mem[pos + 0x05]) + 0x08; break; - case 0x16: pos += Get4(&mem[pos + 0x00]) + 0x04; break; - case 0x17: pos += Get4(&mem[pos + 0x00]) + 0x04; break; - - case 0x20: pos += 0x02; break; - case 0x21: pos += mem[pos + 0x00] + 0x01; break; - case 0x22: break; - case 0x23: pos += 0x02; break; - case 0x24: pos += 0x02; break; - case 0x25: break; - case 0x26: pos += Get2(&mem[pos + 0x00]) * 0x02 + 0x02; break; - case 0x27: break; - case 0x28: pos += Get2(&mem[pos + 0x00]) + 0x02; break; - - case 0x2A: pos += 0x04; break; - - case 0x30: pos += mem[pos + 0x00] + 0x01; break; - case 0x31: pos += mem[pos + 0x01] + 0x02; break; - case 0x32: pos += Get2(&mem[pos + 0x00]) + 0x02; break; - case 0x33: pos += (mem[pos + 0x00] * 0x03) + 0x01; break; - case 0x34: pos += 0x08; break; - case 0x35: pos += Get4(&mem[pos + 0x10]) + 0x14; break; - - case 0x40: pos += Get3(&mem[pos + 0x01]) + 0x04; break; - - case 0x5A: pos += 0x09; break; - - default: pos += Get4(&mem[pos + 0x00]) + 0x04; - not_rec = 1; - } - numblocks++; - } - - printf("Number of Blocks: %d\n", numblocks); - - if (not_rec) - { - printf("\n-- Warning: Some blocks were *NOT* recognised!\n"); - } - - curr = 0; - - if (starting > 1) - { - if (starting > numblocks) - { - printf("\n-- Invalid Starting Block"); - free(mem); - return 0; - } - curr = starting - 1; - } - - if (ending > 0) - { - if (ending > numblocks || ending < starting) - { - printf("\n-- Invalid Ending Block"); - free(mem); - return 0; - } - numblocks = ending; - } - - printf("\nCreating CSW v1"); - printf(" file using %d Hz frequency ...\n\n", freq); - - CSW1_Init(); - amp = LOAMP; - - singlepulse = 0; - manchester = 0; - cycle = (double)freq / 3500000.0; // This is for the conversion later ... - - ///////////////////////////////////////////////////// - // Start replay of blocks (Main loop of the program) - ///////////////////////////////////////////////////// - - while (curr < numblocks) - { - if (draw) printf("Block %03d:", curr + 1); - - id = mem[block[curr]]; - data = &mem[block[curr] + 1]; - switch (id) - { - case 0x10: Analyse_ID10(); // Standard Loading Data block - break; - case 0x11: Analyse_ID11(); // Custom Loading Data block - break; - case 0x12: Analyse_ID12(); // Pure Tone - break; - case 0x13: Analyse_ID13(); // Sequence of Pulses - break; - case 0x14: Analyse_ID14(); // Pure Data - break; - case 0x15: Analyse_ID15(); // Direct Recording - break; - case 0x16: Analyse_ID16(); // C64 ROM Type Data Block - break; - case 0x17: Analyse_ID17(); // C64 Turbo Tape Data Block - break; - case 0x20: Analyse_ID20(); // Pause or Stop the Tape command - break; - case 0x21: Analyse_ID21(); // Group Start - break; - case 0x22: Analyse_ID22(); // Group End - break; - case 0x23: Analyse_ID23(); // Jump To Relative - break; - case 0x24: Analyse_ID24(); // Loop Start - break; - case 0x25: Analyse_ID25(); // Loop End - break; - case 0x26: Analyse_ID26(); // Call Sequence - break; - case 0x27: Analyse_ID27(); // Return from Sequence - break; - case 0x28: Analyse_ID28(); // Select Block - break; - case 0x2A: Analyse_ID2A(); // Stop the tape if in 48k mode - break; - case 0x30: Analyse_ID30(); // Description - break; - case 0x31: Analyse_ID31(); // Message - break; - case 0x32: Analyse_ID32(); // Archive Info - break; - case 0x33: Analyse_ID33(); // Hardware Info - break; - case 0x34: Analyse_ID34(); // Emulation info - break; - case 0x35: Analyse_ID35(); // Custom Info - break; - case 0x40: Analyse_ID40(); // Snapshot - break; - case 0x5A: Analyse_ID5A(); // ZXTape! - break; - default: Analyse_Unknown(); // Unknown blocks - } - - // TZX file blocks analysis finished - // Now we start generating the sound waves - - if ((id == 0x10 || id == 0x11 || id == 0x14)) // One of the data blocks ... - { - if (id != 0x14) Identify(datalen, data, 0); - else strcpy(tstr, " Pure Data "); - if (id == 0x10) sprintf(spdstr, "Normal Speed"); - else sprintf(spdstr, " Speed: %3d%%", speed); - sprintf(pstr, "Pause: %5d ms", pause_ms); - if (draw) printf("%s Length:%6d %s %s\n", tstr, datalen, spdstr, pstr); - - { - while (pilot) // Play PILOT TONE - { - PlayWave(sb_pilot); - ToggleAmp(); - pilot--; - } - if (sb_sync1) // Play first SYNC pulse - { - PlayWave(sb_sync1); - ToggleAmp(); - } - if (sb_sync2) // Play second SYNC pulse - { - PlayWave(sb_sync2); - ToggleAmp(); - } - datapos = 0; - while (datalen) // Play actual DATA - { - if (datalen != 1) bitcount = 8; - else bitcount = lastbyte; - databyte = data[datapos]; - while (bitcount) - { - if (databyte & 0x80) sb_bit = sb_bit1; - else sb_bit = sb_bit0; - PlayWave(sb_bit); // Play first pulse of the bit - ToggleAmp(); - if (!singlepulse) - { - PlayWave(sb_bit); // Play second pulse of the bit - ToggleAmp(); - } - databyte <<= 1; - bitcount--; - } - datalen--; datapos++; - } - singlepulse = 0; // Reset flag for next TZX blocks - - // If there is pause after block present then make first millisecond the oposite - // pulse of last pulse played and the rest in LOAMP ... otherwise don't do ANY pause - if (pause_ms) - { - PauseWave(1); - amp = LOAMP; - if (pause_ms > 1) PauseWave(pause_ms - 1); - } - } - } - - if (id == 0x16) // C64 ROM data block ... - { - IdentifyC64ROM(datalen, data, 0); - sprintf(pstr, "Pause: %5d ms", pause_ms); - if (draw) printf(" %s Length:%6d %s %s\n", tstr, datalen, spdstr, pstr); - - { - sb_pilot = Samples(sb_pilot); - sb_sync1 = Samples(sb_sync1); sb_sync2 = Samples(sb_sync2); - sb_bit1_f = Samples(sb_bit1_f); sb_bit1_s = Samples(sb_bit1_s); - sb_bit0_f = Samples(sb_bit0_f); sb_bit0_s = Samples(sb_bit0_s); - sb_finishbyte_f = Samples(sb_finishbyte_f); - sb_finishbyte_s = Samples(sb_finishbyte_s); - sb_finishdata_f = Samples(sb_finishdata_f); - sb_finishdata_s = Samples(sb_finishdata_s); - sb_trailing = Samples(sb_trailing); - num_lead_in = 0; - amp = LOAMP; // This might be just opposite !!!! - while (pilot) // Play PILOT TONE - { - PlayC64(sb_pilot); - pilot--; - } - if (sb_sync1) PlayC64(sb_sync1); // Play SYNC PULSES - if (sb_sync2) PlayC64(sb_sync2); - datapos = 0; - while (datalen) // Play actual DATA - { - if (datalen != 1) - { - bitcount = 8; - PlayC64ROMByte(data[datapos], 0); - } - else - { - bitcount = lastbyte; - PlayC64ROMByte(data[datapos], 1); - } - databyte = data[datapos]; - datalen--; datapos++; - } - while (trailing) // Play TRAILING TONE - { - PlayC64(sb_trailing); - trailing--; - } - - // If there is pause after block present then make first millisecond the oposite - // pulse of last pulse played and the rest in LOAMP ... otherwise don't do ANY pause - - if (pause_ms) - { - PauseWave(pause_ms / 2); - ToggleAmp(); - PauseWave((pause_ms / 2) + (pause_ms % 2)); - ToggleAmp(); - } - } - } - - if (id == 0x17) // C64 Turbo Tape data block ... - { - IdentifyC64Turbo(datalen, data, 0); - sprintf(pstr, "Pause: %5d ms", pause_ms); - if (draw) printf(" %s Length:%6d %s %s\n", tstr, datalen, spdstr, pstr); - - { - sb_bit1 = Samples(sb_bit1); - sb_bit0 = Samples(sb_bit0); - amp = LOAMP; // This might be just opposite !!!! - while (num_lead_in) // Play Lead In bytes - { - bitcount = 8; - PlayC64TurboByte(lead_in_byte); - num_lead_in--; - } - datapos = 0; - while (datalen) // Play actual DATA - { - if (datalen != 1) bitcount = 8; - else bitcount = lastbyte; - PlayC64TurboByte(data[datapos]); - databyte = data[datapos]; - datalen--; datapos++; - } - while (trailing) // Play Trailing bytes - { - bitcount = 8; - PlayC64TurboByte((unsigned char)sb_trailing); - trailing--; - } - - // If there is pause after block present then make first millisecond the oposite - // pulse of last pulse played and the rest in LOAMP ... otherwise don't do ANY pause - - if (pause_ms) - { - PauseWave(pause_ms / 2); - ToggleAmp(); - PauseWave((pause_ms / 2) + (pause_ms % 2)); - ToggleAmp(); - } - } - } - - curr++; // We continue to replay the next TZX block - } // This is the main loop end - - PauseWave(200); // Finish always with 200 ms of pause after the last block - PlayFinish(); - printf("\n%lu bytes sent to the core.\n", oflen); - free(mem); - return 1; -} diff --git a/tzx2wav.h b/tzx2wav.h deleted file mode 100644 index eed543f..0000000 --- a/tzx2wav.h +++ /dev/null @@ -1,3 +0,0 @@ -#include "file_io.h" - -int tzx2csw(fileTYPE *f); diff --git a/user_io.cpp b/user_io.cpp index bdeab9e..fd323ad 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -24,7 +24,6 @@ #include "DiskImage.h" #include "brightness.h" #include "sxmlc.h" -#include "tzx2wav.h" #include "bootcore.h" #include "charrom.h" #include "scaler.h" @@ -1366,63 +1365,51 @@ int user_io_file_tx(const char* name, unsigned char index, char opensave, char m spi8(0xff); DisableFpga(); - if (strlen(f.name) > 4 && (!strcasecmp(f.name + strlen(f.name) - 4, ".tzx") || !strcasecmp(f.name + strlen(f.name) - 4, ".cdt"))) + if (is_snes_core() && bytes2send) { - printf("Processing TZX...\n"); + printf("Load SNES ROM.\n"); + uint8_t* buf = snes_get_header(&f); + hexdump(buf, 16, 0); + EnableFpga(); + spi8(UIO_FILE_TX_DAT); + spi_write(buf, 512, fio_size); + DisableFpga(); + + //strip original SNES ROM header if present (not used) + if (bytes2send & 512) + { + bytes2send -= 512; + FileReadSec(&f, buf); + } + } + + file_crc = 0; + uint32_t skip = bytes2send & 0x3FF; // skip possible header up to 1023 bytes + + while (bytes2send) + { + printf("."); + + uint16_t chunk = (bytes2send > sizeof(buf)) ? sizeof(buf) : bytes2send; + + FileReadAdv(&f, buf, chunk); EnableFpga(); spi8(UIO_FILE_TX_DAT); - tzx2csw(&f); + spi_write(buf, chunk, fio_size); DisableFpga(); - } - else - { - if (is_snes_core() && bytes2send) + + bytes2send -= chunk; + + if (skip >= chunk) skip -= chunk; + else { - printf("Load SNES ROM.\n"); - uint8_t* buf = snes_get_header(&f); - hexdump(buf, 16, 0); - EnableFpga(); - spi8(UIO_FILE_TX_DAT); - spi_write(buf, 512, fio_size); - DisableFpga(); - - //strip original SNES ROM header if present (not used) - if (bytes2send & 512) - { - bytes2send -= 512; - FileReadSec(&f, buf); - } + file_crc = crc32(file_crc, buf + skip, chunk - skip); + skip = 0; } - - file_crc = 0; - uint32_t skip = bytes2send & 0x3FF; // skip possible header up to 1023 bytes - - while (bytes2send) - { - printf("."); - - uint16_t chunk = (bytes2send > sizeof(buf)) ? sizeof(buf) : bytes2send; - - FileReadAdv(&f, buf, chunk); - - EnableFpga(); - spi8(UIO_FILE_TX_DAT); - spi_write(buf, chunk, fio_size); - DisableFpga(); - - bytes2send -= chunk; - - if (skip >= chunk) skip -= chunk; - else - { - file_crc = crc32(file_crc, buf + skip, chunk - skip); - skip = 0; - } - } - printf("\n"); - printf("CRC32: %08X\n", file_crc); } + printf("\n"); + printf("CRC32: %08X\n", file_crc); FileClose(&f);