/* * UNIX2CPM Converts Unix-format EOL's to CP/M ones (LF=>CRLF). * * Optimized for ease of use, ease of writing, and for * fast speed operation under CP/M. This is for Z80s ONLY. * * Version 1.2 * * Change from 1.1->1.2: * Files processed now stay on the "other disk" for * situations like "A> unix2cpm c:fred.c" * * Improved malloc scheme for use on systems with * teeny tiney TPA memory. * * Original (and modifying) author: * * -Mike Kersenbrock * tektronix!copper!michaelk * */ #include "c:stdio.h" /* Kept in my 720K RAMDISK "C:" */ #include "c:fcntl.h" int Input; /* File desciptor for input files */ int Tempfile; /* File desciptor for output files */ char *Tbuf; /* Pointer to Input buffer */ int Count; /* Number of bytes in input buffer */ int Tbufsize; /* Size of that buffer */ char *Obuf; /* Pointer to Output buffer */ int Obufsize; /* Size of that buffer */ char *xlate(); /* making everybody happy */ int look4eof(); /* just keeping in habit */ char Tempname[] = "z:temp@@83.$$$"; main(argc,argv) int argc; char *argv[]; { register int loop; register char *temp; register char *tmpname; puts("\nUNIX2CPM Version 1.2 (M. Kersenbrock)"); if (argc < 2 ) { puts("Usage: unix2cpm filename [filename...] afn's OK"); exit(3); } /* * This way the output buffer is twice the size of the * input buffer. So, in a near worse case inputfile of almost pure LFs, * the output buffer will still just hold it all w/o having to check. */ for (Obufsize=0x7000 ; (1) ; Obufsize /= 2) { if ((Obuf=malloc(Obufsize))!=NULL) { Tbufsize=Obufsize/2; if ((Tbuf=malloc(Tbufsize))!=NULL) { break; } else { free(Obuf); } } } for (loop = 1 ; loop < argc ; loop++) { if ((Input=open(argv[loop],O_RDONLY)) < 0) { fputs("\nproblem opening file: ",stdout); puts(argv[loop]); puts("\n"); exit(1); } chekkbd(); if (*(argv[loop] + 1) == ':') { Tempname[0] = *argv[loop]; tmpname = Tempname; } else { tmpname = &Tempname[2]; } fputs("\nStarting to process file: ",stdout); fputs(argv[loop],stdout); Tempfile = open(tmpname,O_WRONLY+O_CREAT); if (Tempfile < 0) { puts("\nproblem opening temp file "); puts(tmpname); puts("\n"); exit(2); } chekkbd(); while ((Count=read(Input,Tbuf,Tbufsize)) > 0) { /* * Observe the CTL-Z that may be in the * input buffer. */ Count = look4eof(Tbuf,Count); /* * Xlate translates Count chars of data from Tbuf to * Obuf, returning a pointer one past end of data in * the Obuf. */ temp=xlate(); chekkbd(); write(Tempfile,Obuf,temp-Obuf); } *Obuf = '\032'; write(Tempfile,Obuf,1); close(Tempfile); unlink(argv[loop]); close(Input); rename(tmpname,argv[loop]); } puts("\n"); exit(0); } #define LBCD db 0edh,4bh /*LD BC,(nn) where nn follows */ #define LDI db 0edh,0a0h /*LDI incremental block move Z80 instruction */ #asm xlate_: push b ; Save register variable mvi a,0ah ; Lookn for linefeeds LBCD dw Count_ ; Load count into BC lhld Obuf_ ; Get destination buffer address xchg ; and put it into DE lhld Tbuf_ ; Put Source address into HL look4: cmp m ; linefeed? jnz noinsert ; nope xchg ; yup mvi m,0dh xchg ; put CR into destination string inx d ; then update dest. pointer ; and drop down to transfer the LF noinsert: LDI ; so do straight copy transfer jpe look4 ; if Count not done, go do another xchg ; put destination pointer into HL pop b ; put register variable back mov a,h ora l ; set flags to HLs contents ret #endasm /* * Search a buffer of length maxcount, and return the number * of characters *before* finding CP/M's EOF. If EOF is not found * then maxcount is returned. Uses Z80 Block-search instruction. * * This is for a Z80 only. -Mike Kersenbrock * tektronix!copper!michaelk * look4eof(buffer,maxcount) * char *buffer; * int maxcount; * */ #asm look4eof_: lxi h,2 dad sp mov e,m inx h mov d,m ; buffer pointer is now in DE push b ; Save incoming register variable inx h mov c,m inx h mov b,m ; maxcount is now in BC xchg ; buffer pointer is now in HL mov e,c mov d,b ; (save original count in DE) mvi a,1ah ; EOF in accumulator db 0edh,0b1h ; Z80 Block-compare look for EOF (CPIR) xchg ; put original count into HL jnz nofound ; nope, hadnt found EOF ; else,... stc ; set carry flag db 0edh,042h ; subtract current count(BC) from orig count-1 ; (leave new actual count in HL (rtn value)) nofound: ; The calling count is still in HL mov a,h ora l ; set zero flag to HLs contents pop b ; return register variable back again ret #endasm