/* * *	BList 1.0 * *       List Applesoft BASIC Files * *       Kelvin W Sherlock June 4th, 1997 */#include <texttool.h>#include <intmath.h>#include <gsos.h>#define BASICFileType 0x00FCvoid usage(void);GSString255* CString2GS(char*);void TranslateFile(int);extern char *tokens[];#ifdef STACKvoid begin_stack_check(void);int end_stack_check(void);char ssize[7]="xxxxxx\0";#endifint 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 usedI spent a while taking apart Applesoft files and dropping intoBASIC.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 ... */	" ?? ",	" ?? ",	" ?? ",	" ?? ",	" ?? ",	" ?? ",	" ?? ",	" ?? ",	" ?? ",	" ?? ",	" ?? ",	" ?? ",	" ?? ",	" ?? ",	" ?? ",	" ?? ",	" ?? ",	" ?? ",	" ?? ",};       
