Advertisement
mcleod_ideafix

Jupiter ACE TAP to TZX converter

Nov 17th, 2018
462
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.66 KB | None | 0 0
  1. /*
  2. ACETAP2TZX
  3. ----------
  4.  
  5. (C)2011 Miguel Angel Rodriguez Jodar (McLeod/IdeaFix).
  6. miguel.angel@zxprojects.com
  7.  
  8. A quick and dirty utility to convert TAP files designed for the Jupiter ACE
  9. computer, into more flexible TZX files.
  10. This utility outputs a TZX confirming to version 1.20
  11.  
  12. This program is free software: you can redistribute it and/or modify it
  13. under the terms of the GNU General Public License as published by the Free
  14. Software Foundation, either version 3 of the License, or (at your option)
  15. any later version.
  16.  
  17. This program is distributed in the hope that it will be useful, but WITHOUT
  18. ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or
  19. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  20. more details.
  21.  
  22. You should have received a copy of the GNU General Public License along with
  23. this program.  If not, see <http://www.gnu.org/licenses/>.
  24.  
  25. Changelog
  26. ---------
  27. 2011-01-04:
  28. Simplified TZX enconding using just ID11 and ID13.
  29.  
  30.  
  31. 2011-01-01:
  32. First version released to the public. For each block of TAP data, the following
  33. is written to the TZX output:
  34.     A pure tone (pilot), two pulses (sync), data, and a single 0 bit.
  35.  
  36. Multiple TAP blocks are treated as pairs, assuming that each pair contains
  37. a header block (26 bytes) and a data block.
  38.  
  39. Possibly multiple security flaws in the code, and a number of unknown errors.
  40. The code has been written and tested in less than 1 hour...
  41. */
  42.  
  43.  
  44. #include <stdio.h>
  45. #include <stdlib.h>
  46. #include <string.h>
  47.  
  48. /*
  49. These timings are adjusted from the original timings from the 3.25MHz
  50. Jupiter ACE to a Z80 frequency of 3.5MHz, as required by the TZX file format
  51. standard (1.20). To get the actual Jupiter ACE timings, multiply each
  52. value by 325/350. More information about these timings at:
  53. http://jupiterace.proboards.com/index.cgi?board=programmingaceforth&action=display&thread=266
  54. */
  55.  
  56. #define PILOT 2114
  57. #define SYNC1 602
  58. #define SYNC2 826
  59. #define ZERO 812
  60. #define ONE 1666
  61. #define ENDMARK1 972
  62. #define ENDMARK2 4509
  63.  
  64. void WriteTZXBlock (FILE *, unsigned char, unsigned char *, int);
  65. int  ReadTAPBlock (FILE *, unsigned char *);
  66. void WriteTZXHeader (FILE *);
  67.  
  68. int main (int argc, char *argv[])
  69. {
  70.     FILE *fi, *fo;
  71.     char ni[256],no[256];
  72.     unsigned char ffhd=0;
  73.     unsigned char *bloque;
  74.     int lbloque;
  75.    
  76.     if (argc<2)
  77.     {
  78.         printf ("ERROR! Need a file to convert!\n");
  79.         exit(-1);
  80.     }
  81.    
  82.     strncpy (ni, argv[1], 255);
  83.     ni[255]=0;
  84.    
  85.     strcpy (no, ni);
  86.     strcat (no, ".tzx");
  87.    
  88.     bloque=(unsigned char *)malloc(65536);
  89.     if (!bloque)
  90.     {
  91.         printf ("ERROR! Out of memory (shouldn't happen!)\n");
  92.         exit(-1);
  93.     }
  94.  
  95.     fi=fopen(ni,"rb");
  96.     if (!fi)
  97.     {
  98.         printf ("ERROR! Cannot open '%s'\n", ni);
  99.         exit(-1);
  100.     }
  101.    
  102.     fo=fopen(no,"wb");
  103.     if (!fo)
  104.     {
  105.         printf ("ERROR! Cannot create '%s'\n", no);
  106.         exit(-1);
  107.     }
  108.    
  109.     WriteTZXHeader (fo);
  110.    
  111.     lbloque = ReadTAPBlock (fi, bloque);
  112.     while(lbloque>0)
  113.     {
  114.         WriteTZXBlock (fo, ffhd, bloque, lbloque);
  115.         ffhd=~ffhd;
  116.         lbloque = ReadTAPBlock (fi, bloque);
  117.     }
  118.    
  119.     fclose(fi);
  120.     fclose(fo);
  121.     free(bloque);
  122.    
  123.     return 0;
  124. }
  125.  
  126.  
  127. void WriteTZXBlock (FILE *fo, unsigned char ffhd, unsigned char *bloque, int lbloque)
  128. {
  129.     unsigned char id2b[5]={1,0,0,0,1};
  130.     unsigned char id13[6]={0x13, 2, ENDMARK1&0xff, (ENDMARK1>>8)&0xff, ENDMARK2&0xff, (ENDMARK2>>8)&0xff};
  131.     unsigned char id11[19]={0x11, PILOT&0xff, (PILOT>>8)&0xff,
  132.                                  SYNC1&0xff, (SYNC1>>8)&0xff,
  133.                                  SYNC2&0xff, (SYNC2>>8)&0xff,
  134.                                  ZERO&0xff, (ZERO>>8)&0xff,
  135.                                  ONE&0xff, (ONE>>8)&0xff,
  136.                                  0, 0, /* length of pilot tone */
  137.                                  8, 0, 0,
  138.                                  0, 0, 0 /* length of data to follow */
  139.                           };
  140.                          
  141.    
  142.     id11[12]=(!ffhd)? 0x20 : 0x04;  /* length of pilot tone is different for header and data blocks */
  143.     id11[16]=(lbloque+1)&0xff;      /* actual data in the TZX file has one byte added: the flag byte */
  144.     id11[17]=((lbloque+1)>>8)&0xff;  
  145.    
  146.     /* fwrite (id2b, 1, 5, fo);  set signal level */
  147.     fwrite (id11, 1, 19, fo); /* turbo data block */
  148.     fwrite (&ffhd, 1, 1, fo); /* flag byte */
  149.     fwrite (bloque, 1, lbloque, fo); /* the actual data */
  150.     fwrite (id13, 1, 6, fo); /* end mark */
  151. }
  152.  
  153.  
  154. int ReadTAPBlock (FILE *fi, unsigned char *bloque)
  155. {
  156.     int leido;
  157.     int lbloque;
  158.     unsigned char lowb, hib;
  159.    
  160.     leido=fread (&lowb, 1, 1, fi);
  161.     leido=fread (&hib, 1, 1, fi);
  162.     if (leido<1)
  163.         return 0;
  164.    
  165.     lbloque=(hib<<8) | lowb;
  166.     leido=fread (bloque, 1, lbloque, fi);
  167.     if (leido!=lbloque)
  168.         return 0;
  169.        
  170.     return lbloque;
  171. }
  172.  
  173.  
  174. void WriteTZXHeader (FILE *fo)
  175. {
  176.     unsigned char headtzx[10]={'Z','X','T','a','p','e','!',0x1a, 1, 13};
  177.    
  178.     fwrite (headtzx, 1, 10, fo);
  179. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement