home *** CD-ROM | disk | FTP | other *** search
/ 64'er / 64ER_CD.iso / utilpc / c64dearc / listcbm.c < prev    next >
C/C++ Source or Header  |  1989-09-17  |  13KB  |  498 lines

  1. /*  list64.c                                                     27 Aug 88 - CS
  2.     ===========================================================================
  3.     Converts a tokenized Commodore 64 or 128 BASIC program to standard ASCII.
  4.  
  5.     Some steps are taken to aid in converting the file to Microsoft QuickBASIC,
  6.     but alot of manual editing will invariably be nessessary to complete the
  7.     conversion.
  8.  
  9.     Special Commodore cursor control and color control characters are
  10.     shown as "[Text]" so it should be fairly simple to deal with them using
  11.     your editor's search and replace function.
  12.     ===========================================================================
  13. */
  14.  
  15. #include <stdio.h>
  16. #include <string.h>
  17.  
  18. #ifdef MPU8086      /* If Manx */
  19. #define ROPEN "r"
  20. #else               /* If the rest of the civilized world */
  21. #define ROPEN "rb"
  22. #endif
  23.  
  24. /*  --------------------
  25.      BASIC 2.0 keywords
  26.     --------------------
  27. */
  28.  
  29. char * KeyWord[] = {
  30.  
  31.         " end ",                                /* Token 0x80 */
  32.         " for ",                                /*       0x81 */
  33.         " next ",                               /*       ...  */
  34.         " data ",
  35.         " input #",
  36.         " input ",
  37.         " dim ",
  38.         " read ",
  39.         " let ",
  40.         " goto ",
  41.         " run ",
  42.         " if ",
  43.         " restore ",
  44.         " gosub ",
  45.         " return ",
  46.         " rem ",
  47.         " stop ",
  48.         " on ",
  49.         " wait ",
  50.         " load ",
  51.         " save ",
  52.         " verify ",
  53.         " def ",
  54.         " poke ",
  55.         " print #",
  56.         " print ",
  57.         " cont ",
  58.         " list ",
  59.         " clr",
  60.         " cmd ",
  61.         " sys ",
  62.         " open ",
  63.         " close ",
  64.         " get ",
  65.         " new ",
  66.         " tab(",
  67.         " to ",
  68.         " fn",
  69.         " spc(",
  70.         " then ",
  71.         " not ",
  72.         " step ",
  73.         "+",
  74.         "-",
  75.         "*",
  76.         "/",
  77.         "^",
  78.         " and ",
  79.         " or ",
  80.         ">",
  81.         "=",
  82.         "<",
  83.         "sgn",
  84.         "int",
  85.         "abs",
  86.         "usr",
  87.         "fre",
  88.         "pos",
  89.         "sqr",
  90.         "rnd",
  91.         "log",
  92.         "exp",
  93.         "cos",
  94.         "sin",
  95.         "tan",
  96.         "atn",
  97.         "peek",
  98.         "len",
  99.         "str$",
  100.         "val",
  101.         "asc",
  102.         "chr$",
  103.         "left$",
  104.         "right$",
  105.         "mid$",
  106.         " go ",
  107.  
  108. /*  ----------------
  109.      C128 additions
  110.     ----------------
  111. */
  112.  
  113.         " rgr ",
  114.         " rclr ",
  115.         " [Function Token Extender] ",                          /* 0xce */
  116.         " joy",
  117.         " rdot",
  118.         " dec",
  119.         " hex$",
  120.         " err$",
  121.         " instr",
  122.         " else ",
  123.         " resume ",
  124.         " trap ",
  125.         " tron ",
  126.         " troff ",
  127.         " sound ",
  128.         " vol ",
  129.         " auto ",
  130.         " pudef ",
  131.         " graphic ",
  132.         " paint ",
  133.         " char ",
  134.         " box ",
  135.         " circle ",
  136.         " gshape ",
  137.         " sshape ",
  138.         " draw ",
  139.         " locate ",
  140.         " color ",
  141.         " scnclr ",
  142.         " scale ",
  143.         " help ",
  144.         " do ",
  145.         " loop ",
  146.         " exit ",
  147.         " directory ",
  148.         " dsave ",
  149.         " dload ",
  150.         " header ",
  151.         " scratch ",
  152.         " collect ",
  153.         " copy ",
  154.         " rename ",
  155.         " backup ",
  156.         " delete ",
  157.         " renumber ",
  158.         " key ",
  159.         " monitor ",
  160.         " using ",
  161.         " until ",
  162.         " while ",
  163.         " [Satement Token Extender] ",                      /* 0xfe */
  164.         0
  165. };
  166.  
  167. /*  -------------------------
  168.      C128 extended functions
  169.     -------------------------
  170. */
  171.     
  172. char *Function[] = {
  173.         " pot",
  174.         " bump",
  175.         " pen",
  176.         " rsppos",
  177.         " rsprite",
  178.         " rspcolor",
  179.         " xor",
  180.         " rwindow",
  181.         " pointer",
  182.         " [Undefined Token] ",
  183.         0
  184. };
  185.  
  186. char *Statement[] = {
  187.  
  188.         " bank ",
  189.         " filter ",
  190.         " play ",
  191.         " tempo ",
  192.         " movspr ",
  193.         " sprite ",
  194.         " sprcolor ",
  195.         " rreg ",
  196.         " envelope ",
  197.         " sleep ",
  198.         " catalog ",
  199.         " dopen ",
  200.         " append ",
  201.         " dclose ",
  202.         " bsave ",
  203.         " bload ",
  204.         " record ",
  205.         " concat ",
  206.         " dverify ",
  207.         " dclear ",
  208.         " sprsav ",
  209.         " collision ",
  210.         " begin ",
  211.         " bend ",
  212.         " window ",
  213.         " boot ",
  214.         " width ",
  215.         " sprdef ",
  216.         " quit ",
  217.         " stash ",
  218.         " [Undefined Token] ",
  219.         " fetch ",
  220.         " [Undefined Token] ",
  221.         " swap ",
  222.         " off ",
  223.         " fast ",
  224.         " slow ",
  225.         " [Undefined Token] ",
  226.         0
  227. };
  228.  
  229. unsigned getw(FILE * fp)
  230. {
  231.     union {
  232.         unsigned u;
  233.         char c[2];
  234.     } x;
  235.  
  236.     x.c[0] = fgetc(fp);
  237.     x.c[1] = fgetc(fp);
  238.  
  239.     return x.u;
  240. }
  241.  
  242.  
  243.  
  244. main(argc,argv)
  245. unsigned argc;
  246. char *argv[];
  247. {
  248.     FILE *  fp;
  249.     int     c, i;
  250.     char *  a;
  251.     char    filename[65];
  252.     int     Status = 0;
  253.  
  254.     if (argc != 2) {
  255.        if ( (a=strrchr(argv[0],'\\')) == 0)
  256.              a=argv[0];
  257.        else
  258.              a++;
  259.        printf("\nUsage:    %s [d:path\\]filename[.bas] [>output.file]\n",a);
  260.        printf("\nPurpose:  Convert tokenized Commodore 64 or 128 BASIC to standard ASCII.\n");
  261.        printf("          Use redirection to create an output file.\n");
  262.        exit(1);
  263.     }
  264.  
  265.     strcpy(filename,argv[1]);
  266.  
  267.     if ( access(filename,0) ) {
  268.  
  269.         if ( strchr(argv[1],'.') == 0 )
  270.             strcat(filename,".bas");
  271.  
  272.         if ( access(filename,0) ) {
  273.             printf("\nCan't open source file\n");
  274.             exit(1);
  275.         }
  276.     }
  277.  
  278.     if ((fp = fopen(filename, ROPEN)) == 0){
  279.        printf("\nCan't open \"%s\"\n",filename);
  280.        exit(2);
  281.     }
  282.  
  283.     getw(fp);                               /* Ignore load address */
  284.  
  285.     while(Status != EOF) {                  /* While still more data */
  286.         Status=DoLine(fp);                  /* Display one line */
  287.     }
  288.  
  289.     fclose(fp);
  290.  
  291. }
  292.  
  293. /* Convert CBM ASCII to Standard ASCII */
  294.  
  295. char *p2a(c)
  296. int  c;
  297. {
  298.     static unsigned cc;
  299.     static unsigned oldcc;
  300.     static char     s[2];
  301.  
  302.     oldcc = cc;
  303.     cc    = c;
  304.  
  305.     switch (cc) {
  306.  
  307.        case 5:  return "[White]";                   /* White        */
  308.        case 7:  return "[Bell]";
  309.        case 10: {                                   /* LF           */
  310.                 if (oldcc!=13)
  311.                    return "\012";
  312.                 else
  313.                    return "\0";
  314.                 }
  315.        case 13:  return "\n";                       /* CR           */
  316.        case 14:  return "[Text Mode]";              /* Select character set */
  317.        case 17:  return "[Down]";                   /* Cursor Down  */
  318.        case 18:  return "[Reverse]";                /* Reverse On   */
  319.        case 19:  return "[Home]";                   /* Cursor Home  */
  320.        case 20:  return "[Delete]";
  321.        case 28:  return "[Red]";                    /* Red          */
  322.        case 29:  return "[Right]";                  /* Cursor Right */
  323.        case 30:  return "[Green]";                  /* Green        */
  324.        case 31:  return "[Blue]";                   /* Blue         */
  325.        case 129: return "[Orange]";                 /* Orange       */
  326.        case 133: return "[F1]";                     /* Function keys*/
  327.        case 134: return "[F3]";
  328.        case 135: return "[F5]";
  329.        case 136: return "[F7]";
  330.        case 137: return "[F2]";
  331.        case 138: return "[F4]";
  332.        case 139: return "[F6]";
  333.        case 140: return "[F8]";
  334.        case 141: return "\n";                       /* Shifted CR   */
  335.        case 142: return "[Graphic Mode]";           /* Select character set */
  336.        case 145: return "[Up]";                     /* Cursor up    */
  337.        case 144: return "[Black]";                  /* Black        */
  338.        case 146: return "[Reverse Off]";            /* Reverse Off  */
  339.        case 147: return "[Clear]";                  /* Clear Screen */
  340.        case 148: return "[Insert]";
  341.        case 149: return "[Brown]";                  /* Brown        */
  342.        case 150: return "[Light Red]";              /* Light Red    */
  343.        case 151: return "[Dark Grey]";              /* Dark Grey    */
  344.        case 152: return "[Medium Grey]";            /* Medium Grey  */
  345.        case 153: return "[Light Green]";            /* Light Green  */
  346.        case 154: return "[Light Blue]";             /* Light Blue   */
  347.        case 155: return "[Light Grey]";             /* Light grey   */
  348.        case 156: return "[Purple]";                 /* Purple       */
  349.        case 157: return "[Left]";                   /* Cursor Left  */
  350.        case 158: return "[Yellow]";                 /* Yellow       */
  351.        case 159: return "[Cyan]";                   /* Cyan         */
  352.        case 160: return " ";                        /* Shift+space  */
  353.        case 164: return "_";
  354.        case 171: return "╠";
  355.        case 173: return "╚";
  356.        case 174: return "╗";
  357.        case 175: return "~";
  358.        case 176: return "╔";
  359.        case 177: return "╩";
  360.        case 178: return "╦";
  361.        case 179: return "╣";
  362.        case 189: return "╝";
  363.        case 192: return "═";
  364.        case 219: return "╬";
  365.        case 221: return "║";
  366.        case 223: return "|";
  367.  
  368.        default:  {
  369.             s[0] = cc;
  370.             s[1] = 0;
  371.             if (cc<65 || cc>219) return s;
  372.             if (cc<91) {
  373.                 s[0]=cc|0x20;
  374.                 return s;
  375.             }
  376.             if (cc<193) return s;
  377.             s[0]=cc&0x7f;
  378.             return s;
  379.        }
  380.    }
  381. }
  382.  
  383. /*  ----------------------------------------------------------
  384.      Concatenate keywords eliminating spaces where not needed
  385.     ----------------------------------------------------------
  386. */
  387.  
  388. cat(dest,add)
  389. char *dest;
  390. char *add;
  391. {
  392.     size_t last;
  393.  
  394.     last = strlen(dest)-1;                      /* Assume no null strings */
  395.  
  396.     switch (dest[last]) {
  397.  
  398.         case ' ': {
  399.  
  400.             if ( (*add == ' ') || (*add == ':') )
  401.                 dest[last]=0;
  402.             strcat(dest,add);
  403.             break;
  404.         }
  405.         case ':': {
  406.  
  407.             if (*add == ' ')
  408.                 strcat(dest,&add[1]);
  409.             else
  410.                 strcat(dest,add);
  411.             break;
  412.         }
  413.         default:
  414.             strcat(dest,add);
  415.     }
  416. }
  417.  
  418. /*  ---------------------
  419.      List one BASIC line
  420.     ---------------------
  421. */
  422.  
  423. int DoLine(fp)
  424. FILE *fp;
  425. {
  426.     unsigned LineNumber;
  427.     unsigned Link;
  428.     int      c, flag=0;
  429.     int      QuoteFlag = 0;
  430.     char     Line[300];
  431.  
  432.     *Line = 0;
  433.  
  434.     if ( !(Link = getw(fp)) )                   /* Exit if end of BASIC */
  435.         return EOF;
  436.  
  437.     LineNumber = getw(fp);
  438.  
  439.     sprintf(Line,"%u ",LineNumber);
  440.  
  441.     while ( ((c=fgetc(fp)) != 0) && (c != EOF) ) {
  442.  
  443.         if (strlen(Line) > 255)
  444.             break;
  445.  
  446.         if ( (c==' ') && flag)                  /* Eliminate double spaces */
  447.             continue;
  448.  
  449.         flag = 0;
  450.  
  451.         if (c=='\"') {
  452.             strcat(Line,"\"");
  453.             QuoteFlag = !QuoteFlag;
  454.             continue;
  455.         }
  456.  
  457.         if (QuoteFlag) {                        /* Print literally inside quotes */
  458.  
  459.             strcat(Line,p2a(c));
  460.             continue;
  461.         }
  462.  
  463.         if ( c == 0xce ) {                      /* C128 extended function */
  464.             if ( (c = fgetc(fp)) == EOF)
  465.                 continue;
  466.             if ( (c<2) || (c>10) )
  467.                 c = 11;
  468.             cat(Line,Function[c-2]);
  469.             flag = 1;
  470.             continue;
  471.         }
  472.  
  473.         if ( c == 0xfe ) {                      /* C128 extended statement */
  474.             if ( (c = fgetc(fp)) == EOF)
  475.                 continue;
  476.             if ( (c<2) || (c>38) )
  477.                 c = 39;
  478.             cat(Line,Statement[c-2]);
  479.             flag = 1;
  480.             continue;
  481.         }
  482.  
  483.         if ( c>127 ) {                          /* Regular token */
  484.  
  485.             cat(Line,KeyWord[c-128]);
  486.             flag = 1;
  487.             continue;
  488.         }
  489.  
  490.         strcat(Line,p2a(c));
  491.     }
  492.  
  493.     printf("%s\n",Line);
  494.  
  495.     return c;
  496. }
  497.  
  498.