/* * * BList 1.0 * * List Applesoft BASIC Files * * Kelvin W Sherlock June 4th, 1997 */#include #include #include #define BASICFileType 0x00FCvoid usage(void);GSString255* CString2GS(char*);void TranslateFile(int);extern char *tokens[];#ifdef STACKvoid begin_stack_check(void);int end_stack_check(void);char ssize[7]="xxxxxx\0";#endifint main(int argc, char *argv[]){ static RefNumRecGS CloseOS={1,0}; static OpenRecGS OpenOS={15,0,NULL,readEnable}; #ifdef STACK begin_stack_check(); #endif if (argc<2){ usage(); #ifdef STACK Int2Dec(end_stack_check(),ssize,5,0); WriteCString(ssize); #endif exit(1); } /* open a file */ OpenOS.pathname=CString2GS(argv[1]); OpenGS(&OpenOS); if (_toolErr){ ErrWriteCString("Couldn't open file: "); ErrWriteCString(argv[1]); WriteChar('\r'); #ifdef STACK Int2Dec(end_stack_check(),ssize,5,0); WriteCString(ssize); #endif exit(1); } /* set up the file for closing */ CloseOS.refNum=OpenOS.refNum; /* set up for reading */ if (OpenOS.fileType!=BASICFileType){ ErrWriteCString(" Wrong File Type: "); ErrWriteCString(argv[1]); WriteChar('\r'); } else TranslateFile(OpenOS.refNum); CloseGS(&CloseOS); #ifdef STACK Int2Dec(end_stack_check(),ssize,5,0); WriteCString(ssize); #endif }void usage(void){ ErrWriteCString("\rBList 1.0 (C) 1997 Kelvin W Sherlock\r" "List Applesoft BASIC files\r" "\tUsage: blist file\r");}/* This is where the actual work is done. An Applesoft file is laid out like so: word word [variable # of bytes] <0x00> <-eol marker | | | | | |if >0x7F, it is a token, otherwise, it's a printed | | | |The line # (65535 max) | | This is an offset to the next line (?) if 0, the file is done. repeating over and over...*/void TranslateFile(int refNum){ static char temp[7]=" \0"; static IORecGS RWOS={5,0,NULL,NULL,NULL,0}; unsigned int opcode; RWOS.refNum=refNum; RWOS.dataBuffer=(void *)&opcode; RWOS.requestCount=2; ReadGS(&RWOS); if ( (opcode==0)|| _toolErr) return; ReadGS(&RWOS); if (_toolErr) return; RWOS.requestCount=1; Int2Dec(opcode,temp,5,0); WriteCString(temp); while(1){ ReadGS(&RWOS); if (_toolErr) return; opcode = opcode & 0x00ff; /* strip off hibyte */ if (opcode==0x0){ WriteChar('\r'); RWOS.requestCount=2; ReadGS(&RWOS); if ( (opcode==0)|| _toolErr) return; ReadGS(&RWOS); if (_toolErr) return; Int2Dec(opcode,temp,5,0); WriteCString(temp); RWOS.requestCount=1; } else if ( opcode > 0x7F) WriteCString(tokens[ opcode-0x80 ]); else if ( (opcode > 0x1F) && (opcode < 0x7F) ) WriteChar(opcode); }}/*this here is the array of tokens usedI spent a while taking apart Applesoft files and dropping intoBASIC.System, but I understand it now.*/const char *tokens[]={/*80*/ " END ", " FOR ", " NEXT ", " DATA ", " INPUT ", " DEL ", " DIM ", " READ ", " GR ", " TEXT ", " PR# ", " IN# ", " CALL ", " PLOT ", " HLIN ", " VLIN ", " HGR2 ", " HGR ", " HCOLOR= ", " HPLOT ", " DRAW ", " XDRAW ", " HTAB ", " HOME ", " ROT= ", " SCALE= ", " SHLOAD ", " TRACE ", " NOTRACE ", " NORMAL ", " INVERSE ", " FLASH ", " COLOR= ", " POP ", " VTAB ", " HIMEM: ", " LOMEM: ", " ONERR ", " RESUME ", " RECALL ", " STORE ", " SPEED= ", " LET ", " GOTO ", " RUN ", " IF ", " RESTORE ", " & ",/*B0*/ " GOSUB ", " RETURN ", " REM ", " STOP ", " ON ", " WAIT ", " LIST ", " SAVE ", " DEF ", " POKE ", " PRINT ", " CONT ", " LIST ", " CLEAR ", " GET ", " NEW ", " TAB( ", " TO ", " FN ", " SPC( ", " THEN ", " AT ", " NOT ", " STEP ", " + ", " - ", " * ", " / ", " ^ ", " AND ", " OR ", " > ", " = ", " < ", " SGN ", " INT ", " ABS ", " USR ", " FRE ", " SCRN( ", " PDL ", " POS ", " SQR ", " RND ", " LOG ", " EXP ", " COS ", " SIN ", " TAN ", " ATN ", " PEEK ", " LEN ", " STR$ ", " VAL ", " ASC ", " CHR$ ", " LEFT$ ", " RIGHT$ ", " MID$ ",/*EB*/ " ?? ", /* I'm pretty sure these aren't valid ... */ " ?? ", " ?? ", " ?? ", " ?? ", " ?? ", " ?? ", " ?? ", " ?? ", " ?? ", " ?? ", " ?? ", " ?? ", " ?? ", " ?? ", " ?? ", " ?? ", " ?? ", " ?? ", " ?? ",};