/*  typcbm.c
    ====================================================================
    Types a file that is in Commodore ASCII to STDOUT       30Jul88 - CS
    ====================================================================
    Requires ANSI.SYS
*/

#include <stdio.h>
#include <string.h>

/*  cflag is set to true if the file being typed has an extension of .C

    This is nessessary since the C128/C64 does not have curly braces,
    tildas or underscores and the two C compilers for those machines
    redefine the character set slightly.
*/


char cflag;

void main(argc, argv)
int    argc;
char * argv[];
{
    FILE * fp;
    int    c, i;
    char * a;
    char * p2a();

    if (argc != 2) {
        puts("\nUsage:    tt [d:path\\]filename\n");
        puts("\nPurpose:  Type a Commodore ASCII file to STDOUT.\n");
        puts("          (Assumes ANSI.SYS is active)\n");
        exit(1);
    }

    if ((fp = fopen(argv[1], "r")) == 0) {
        fputs("\nCan't open \"",stdout);
        fputs(argv[1],stdout);
        fputs("\"\n",stdout);
        exit(1);
    }

    i=strlen(argv[1]);
    cflag=0;

    if ( (toupper(argv[1][i-1])=='C') && (argv[1][i-2]=='.') )
        cflag=1;

    while((c=getc(fp))!=EOF) {
        a = p2a(c);
        fputs(a,stdout);
    }

    fclose(fp);

}

/* Convert CBM ASCII as implemented on the Commodore 128 to 'Standard' ASCII */
/* as implemented on an IBM PC or compatible using ANSI.SYS                  */

char * p2a(c)
int c;
{
    static unsigned cc;
    static unsigned oldcc;
    static char     s[2];
    extern char     cflag;

    oldcc = cc;
    cc    = c;

    switch (cc) {

       case 5:  return  "\033[37;1m";                /* White        */
       case 10: {                                    /* LF           */
                if (oldcc!=13)
                   return  "\012";
                else
                   return  "\0";
                }
       case 13:  return  "\n";                       /* CR           */
       case 17:  return  "\033[B";                   /* Cursor Down  */
       case 18:  return  "\033[44m";                 /* Reverse On   */
       case 19:  return  "\033[H";                   /* Cursor Home  */
       case 28:  return  "\033[31;1m";               /* Red          */
       case 29:  return  "\033[C";                   /* Cursor Right */
       case 30:  return  "\033[32;1m";               /* Green        */
       case 31:  return  "\033[34;1m";               /* Blue         */
       case 129: return  "\033[0m\033[35m";          /* Orange       */
       case 135: return  "\033[A";                   /* Cursor up    */
       case 144: return  "\033[30;1m";               /* Black        */
       case 146: return  "\033[40m";                 /* Reverse Off  */
       case 147: return  "\033[2J";                  /* Clear Screen */
       case 149: return  "\033[0m\033[33m";          /* Brown        */
       case 150: return  "\033[0m\033[31m";          /* Light Red    */
       case 151: return  "\033[0m\033[37m";          /* Dark Grey    */
       case 152: return  "\033[0m\033[37m";          /* Medium Grey  */
       case 153: return  "\033[0m\033[32m";          /* Light Green  */
       case 154: return  "\033[0m\033[34m";          /* Light Blue   */
       case 155: return  "\033[0m\033[37m";          /* Light grey   */
       case 156: return  "\033[35;1m";               /* Purple       */
       case 157: return  "\033[D";                   /* Cursor Left  */
       case 158: return  "\033[33;1m";               /* Yellow       */
       case 159: return  "\033[36;1m";               /* Cyan         */
       case 160: return  " ";                        /* Shift+space  */
       case 164: return  "_";
       case 171: return  "Ì";
       case 173: return  "È";
       case 174: return  "»";
       case 175: return  "~";
       case 176: return  "É";
       case 177: return  "Ê";
       case 178: return  "Ë";
       case 179: return  "¹";
       case 189: return  "¼";
       case 192: return  "Í";
       case 219: return (cflag) ?  "{" :  "Î";
       case 221: return (cflag) ?  "}" :  "º";
       case  95: return (cflag) ? 0xa4 :  cc;
       case 223: return  "|";

       default:  {

            s[0]=cc;
            s[1]=0;

            if (cc<65 || cc>219)
                return s;

            if (cc<91) {
                s[0]=cc|0x20;
                return s;
            }

            if (cc<193)
                return s;

            s[0]=cc&0x7f;
            return s;
       }
   }
}

