home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / ENTERPRS / CPM / UTILS / S / UNIX2CPM.LBR / UNIX2CPM.CZ / UNIX2CPM.C
Text File  |  2000-06-30  |  5KB  |  211 lines

  1. /* 
  2.  * UNIX2CPM  Converts Unix-format EOL's to CP/M ones (LF=>CRLF).
  3.  *
  4.  *         Optimized for ease of use, ease of writing, and for
  5.  *         fast speed operation under CP/M.  This is for Z80s ONLY.
  6.  *
  7.  * Version 1.2
  8.  *
  9.  * Change from 1.1->1.2:
  10.  *             Files processed now stay on the "other disk" for
  11.  *             situations like "A> unix2cpm c:fred.c"
  12.  *
  13.  *             Improved malloc scheme for use on systems with
  14.  *             teeny tiney TPA memory.
  15.  *
  16.  *                Original (and modifying) author:
  17.  *        
  18.  *                -Mike Kersenbrock
  19.  *                  tektronix!copper!michaelk
  20.  *
  21.  */
  22.  
  23.  
  24. #include "c:stdio.h"    /* Kept in my 720K RAMDISK "C:"    */
  25. #include "c:fcntl.h"
  26.  
  27. int Input;        /* File desciptor for input files  */
  28. int Tempfile;        /* File desciptor for output files */
  29.  
  30. char *Tbuf;        /* Pointer to Input buffer         */
  31. int Count;        /* Number of bytes in input buffer */
  32. int Tbufsize;        /* Size of that buffer             */
  33.  
  34. char *Obuf;        /* Pointer to Output buffer        */
  35. int Obufsize;        /* Size of that buffer             */
  36.  
  37. char *xlate();        /* making everybody happy          */
  38. int  look4eof();    /* just keeping in habit       */
  39.  
  40. char Tempname[] = "z:temp@@83.$$$";
  41.  
  42. main(argc,argv)
  43. int argc;
  44. char *argv[];
  45. {
  46.  
  47.     register int loop;
  48.     register char *temp;
  49.     register char *tmpname;
  50.  
  51.     puts("\nUNIX2CPM     Version 1.2 (M. Kersenbrock)");
  52.  
  53.     if (argc < 2 ) {
  54.         puts("Usage: unix2cpm  filename [filename...]  afn's OK");
  55.         exit(3);
  56.     }
  57.  
  58.     /* 
  59.      * This way the output buffer is twice the size of the
  60.      * input buffer. So, in a near worse case inputfile of almost pure LFs,
  61.      * the output buffer will still just hold it all w/o having to check.
  62.      */
  63.     for (Obufsize=0x7000 ; (1) ; Obufsize /= 2) {
  64.         if ((Obuf=malloc(Obufsize))!=NULL) {
  65.             Tbufsize=Obufsize/2; 
  66.             if ((Tbuf=malloc(Tbufsize))!=NULL) {
  67.                 break;
  68.             }
  69.             else {
  70.                 free(Obuf);
  71.             }
  72.         }
  73.     }
  74.         
  75.     for (loop = 1 ; loop < argc ; loop++) {
  76.         if ((Input=open(argv[loop],O_RDONLY)) < 0) {
  77.             fputs("\nproblem opening file: ",stdout);
  78.                   puts(argv[loop]);
  79.             puts("\n");
  80.             exit(1);
  81.         }
  82.         chekkbd();
  83.         if (*(argv[loop] + 1) == ':') {
  84.             Tempname[0] = *argv[loop];
  85.             tmpname = Tempname;
  86.         }
  87.         else {
  88.             tmpname = &Tempname[2];
  89.         }
  90.         fputs("\nStarting to process file: ",stdout);
  91.         fputs(argv[loop],stdout);
  92.         Tempfile = open(tmpname,O_WRONLY+O_CREAT);
  93.         if (Tempfile < 0) {
  94.             puts("\nproblem opening temp file ");
  95.             puts(tmpname);
  96.             puts("\n");
  97.             exit(2);
  98.         }
  99.         chekkbd();
  100.  
  101.         while ((Count=read(Input,Tbuf,Tbufsize)) > 0) {
  102.  
  103.             /*
  104.              * Observe the CTL-Z that may be in the
  105.              * input buffer.
  106.              */
  107.             Count = look4eof(Tbuf,Count);
  108.  
  109.             /* 
  110.                  * Xlate translates Count chars of data from Tbuf to
  111.              * Obuf, returning a pointer one past end of data in
  112.              * the Obuf.
  113.              */
  114.             temp=xlate();
  115.             chekkbd();
  116.             write(Tempfile,Obuf,temp-Obuf);
  117.         }
  118.         *Obuf = '\032';
  119.         write(Tempfile,Obuf,1);
  120.         close(Tempfile);
  121.         unlink(argv[loop]);
  122.         close(Input);
  123.         rename(tmpname,argv[loop]);
  124.     }
  125.     puts("\n");
  126.     exit(0);
  127. }
  128.  
  129. #define LBCD db 0edh,4bh    /*LD BC,(nn)  where nn follows */
  130. #define LDI  db 0edh,0a0h     /*LDI incremental block move Z80 instruction */
  131.  
  132. #asm
  133.  
  134. xlate_:
  135.     push b        ; Save register variable
  136.     mvi a,0ah    ; Lookn for linefeeds
  137.     LBCD
  138.     dw Count_    ; Load count into BC
  139.     lhld Obuf_    ; Get destination buffer address
  140.     xchg        ; and put it into DE
  141.     lhld Tbuf_    ; Put Source address into HL
  142.  
  143. look4:
  144.     cmp m        ; linefeed?
  145.     jnz noinsert    ; nope
  146.     xchg        ; yup
  147.     mvi m,0dh
  148.     xchg        ; put CR into destination string
  149.     inx d        ; then update dest. pointer
  150.             ; and drop down to transfer the LF
  151. noinsert:
  152.     LDI        ;  so do straight copy transfer
  153.     jpe look4    ; if Count not done, go do another
  154.  
  155.     xchg        ; put destination pointer into HL
  156.     pop b        ; put register variable back
  157.     mov a,h
  158.     ora l        ; set flags to HLs contents
  159.     ret
  160. #endasm
  161.  
  162.  
  163.  
  164. /*
  165.  * Search a buffer of length maxcount, and return the number
  166.  * of characters *before* finding CP/M's EOF.  If EOF is not found
  167.  * then maxcount is returned.  Uses Z80 Block-search instruction.
  168.  *
  169.  * This is for a Z80 only.        -Mike Kersenbrock
  170.  *                         tektronix!copper!michaelk
  171.  * look4eof(buffer,maxcount)
  172.  * char *buffer;
  173.  * int maxcount;
  174.  *
  175.  */
  176.  
  177. #asm
  178.  
  179. look4eof_:
  180.     lxi h,2
  181.     dad sp
  182.     mov e,m
  183.     inx h
  184.     mov d,m            ; buffer pointer is now in DE
  185.     push b            ; Save incoming register variable
  186.     inx h
  187.     mov c,m
  188.     inx h
  189.     mov b,m            ; maxcount is now in BC
  190.     xchg            ; buffer pointer is now in HL
  191.     mov e,c
  192.     mov d,b            ; (save original count in DE)
  193.     mvi a,1ah        ; EOF in accumulator
  194.     db 0edh,0b1h        ; Z80 Block-compare look for EOF (CPIR)
  195.     xchg            ; put original count into HL
  196.     jnz nofound        ; nope, hadnt found EOF
  197.                 ; else,...
  198.     
  199.     stc            ; set carry flag
  200.     db 0edh,042h        ; subtract current count(BC) from orig count-1
  201.                 ; (leave new actual count in HL (rtn value))
  202. nofound:            ; The calling count is still in HL
  203.     mov a,h    
  204.     ora l            ; set zero flag to HLs contents
  205.     pop b            ; return register variable back again
  206.     ret
  207.  
  208. #endasm
  209.  * then maxcount is returned.  Uses Z80 Block-search instruction.
  210.  *
  211.  * This is for a Z80 only.        -