#include #include #include struct symbol { struct symbol *next; int id; char s[256]; }; struct symbol *sym_tab = NULL; struct symbol *read_sym( int len, int id ) { struct symbol *sym; int i; if( sym = malloc( sizeof( struct symbol ) ) ) { sym->next = NULL; sym->id = id; for( i = 0; i < len; i++ ) sym->s[i] = getchar(); sym->s[len] = '\0'; } return sym; } void store_sym( struct symbol *sym ) { struct symbol *s = (struct symbol *)&sym_tab; while( s->next ) s = s->next; s->next = sym; } char *get_sym( int id ) { struct symbol *sym; for( sym = sym_tab; sym; sym = sym->next ) if( sym->id == id ) return sym->s; return NULL; } void delete_sym_tab( void ) { struct symbol *sym, *next; for( sym = sym_tab; sym; sym = next ) { next = sym->next; free( sym ); } } int getword( void ) { int hi; hi = 0x100 * getchar(); return hi + getchar(); } int getlong( void ) { int hi; hi = 0x10000 * getword(); return hi + getword(); } int expand( void ) { int count = 0, c, id; char *s; float f; c = getchar(); count++; switch( c ) { case '"': putchar( c ); for(;;) { c = getchar(); count++; putchar( c ); if( c == '"' ) { char c1; c1 = getchar(); if( c1 == '"' ) { count++; putchar( c1 ); } else { ungetc( c1, stdin ); break; } } } break; case 0x00: putchar( '\n' ); break; case 0x08: getchar(); count++; getchar(); count++; getchar(); count++; break; case 0xAF: printf( "REM" ); do { c = getchar(); count++; if( c ) putchar( c ); } while( c ); putchar( '\n' ); break; case 0xC0: printf( "ELSE IF" ); break; case 0xf1: printf( "AND" ); break; case 0x80: printf( "ABS" ); break; case 0x81: printf( "ASC" ); break; case 0x82: printf( "ATN" ); break; case 0xc4: printf( "AREA" ); break; case 0x83: printf( "CALL" ); break; case 0x84: printf( "CDBL" ); break; case 0x85: printf( "CHR$" ); break; case 0x86: printf( "CINT" ); break; case 0x87: printf( "CLOSE" ); break; case 0x88: printf( "COMMON" ); break; case 0x89: printf( "COS" ); break; case 0x8a: printf( "CVD" ); break; case 0x8b: printf( "CVI" ); break; case 0x8c: printf( "CVS" ); break; case 0xc1: printf( "CLNG" ); break; case 0xc2: printf( "CVL" ); break; case 0x8d: printf( "DATA" ); break; case 0xf4: printf( "EQV" ); break; case 0x8e: printf( "ELSE" ); break; case 0x8f: printf( "EOF" ); break; case 0x90: printf( "EXP" ); break; case 0x91: printf( "FIELD" ); break; case 0x92: printf( "FIX" ); break; case 0x93: printf( "FN" ); break; case 0x94: printf( "FOR" ); break; case 0x95: printf( "GET" ); break; case 0x96: printf( "GOSUB" ); break; case 0x97: printf( "GOTO" ); break; case 0xf5: printf( "IMP" ); break; case 0x98: printf( "IF" ); break; case 0x99: printf( "INKEY$" ); break; case 0x9a: printf( "INPUT" ); break; case 0x9b: printf( "INT" ); break; case 0x9c: printf( "LEFT$" ); break; case 0x9d: printf( "LEN" ); break; case 0x9e: printf( "LET" ); break; case 0x9f: printf( "LINE" ); break; case 0xa1: printf( "LOC" ); break; case 0xa2: printf( "LOF" ); break; case 0xa3: printf( "LOG" ); break; case 0xa4: printf( "LSET" ); break; case 0xf6: printf( "MOD" ); break; case 0xa5: printf( "MID$" ); break; case 0xa6: printf( "MKD$" ); break; case 0xa7: printf( "MKI$" ); break; case 0xa8: printf( "MKS$" ); break; case 0xc3: printf( "MKL$" ); break; case 0xa9: printf( "NEXT" ); break; case 0xe7: printf( "NOT" ); break; case 0xf2: printf( "OR" ); break; case 0xaa: printf( "ON" ); break; case 0xab: printf( "OPEN" ); break; case 0xac: printf( "PRINT" ); break; case 0xad: printf( "PUT" ); break; case 0xae: printf( "READ" ); break; case 0xb0: printf( "RETURN" ); break; case 0xb1: printf( "RIGHT$" ); break; case 0xb2: printf( "RND" ); break; case 0xb3: printf( "RSET" ); break; case 0xb4: printf( "SGN" ); break; case 0xb5: printf( "SIN" ); break; case 0xb6: printf( "SPACE$" ); break; case 0xb7: printf( "SQR" ); break; case 0xb8: printf( "STR$" ); break; case 0xb9: printf( "STRING$" ); break; case 0xe3: printf( "STATIC" ); break; case 0xba: printf( "TAN" ); break; case 0xe6: printf( "THEN" ); break; case 0xe5: printf( "TO" ); break; case 0xe4: printf( "USING" ); break; case 0xbc: printf( "VAL" ); break; case 0xbd: printf( "WEND" ); break; case 0xbe: printf( "WHILE" ); break; case 0xbf: printf( "WRITE" ); break; case 0xf3: printf( "XOR" ); break; case 0xF8: c = getchar(); count++; switch( c ) { case 0xd8: printf( "AREAFILL" ); break; case 0xb5: printf( "BEEP" ); break; case 0x81: printf( "CHAIN" ); break; case 0x82: printf( "CLEAR" ); break; case 0x83: printf( "CLS" ); break; case 0x84: printf( "CONT" ); break; case 0x85: printf( "CSNG" ); break; case 0xb6: printf( "CIRCLE" ); break; case 0xc6: printf( "CSRLIN" ); break; case 0xd9: printf( "COLOR" ); break; case 0xdd: printf( "CHDIR" ); break; case 0x86: printf( "DATE$" ); break; case 0x87: printf( "DEFINT" ); break; case 0x88: printf( "DEFSNG" ); break; case 0x89: printf( "DEFDBL" ); break; case 0x8a: printf( "DEFSTR" ); break; case 0x8b: printf( "DEF" ); break; case 0x8c: printf( "DELETE" ); break; case 0x8d: printf( "DIM" ); break; case 0xd4: printf( "DECLARE" ); break; case 0xd6: printf( "DEFLNG" ); break; case 0x8e: printf( "EDIT" ); break; case 0x8f: printf( "END" ); break; case 0x90: printf( "ERASE" ); break; case 0x91: printf( "ERL" ); break; case 0x92: printf( "ERROR" ); break; case 0x93: printf( "ERR" ); break; case 0xbf: printf( "EXIT" ); break; case 0x94: printf( "FILES" ); break; case 0x95: printf( "FRE" ); break; case 0xd5: printf( "FUNCTION" ); break; case 0x96: printf( "HEX$" ); break; case 0x97: printf( "INSTR" ); break; case 0x98: printf( "KILL" ); break; case 0x99: printf( "LIST" ); break; case 0x9a: printf( "LLIST" ); break; case 0x9b: printf( "LOAD" ); break; case 0x9c: printf( "LPOS" ); break; case 0x9d: printf( "LPRINT" ); break; case 0xc5: printf( "LOCATE" ); break; case 0xc7: printf( "LBOUND" ); break; case 0xcc: printf( "LIBRARY" ); break; case 0x9e: printf( "MERGE" ); break; case 0xb8: printf( "MOUSE" ); break; case 0xc2: printf( "MENU" ); break; case 0x9f: printf( "NAME" ); break; case 0xa0: printf( "NEW" ); break; case 0xa1: printf( "OCT$" ); break; case 0xa2: printf( "OPTION" ); break; case 0xa3: printf( "PEEK" ); break; case 0xa4: printf( "POKE" ); break; case 0xa5: printf( "POS" ); break; case 0xb9: printf( "POINT" ); break; case 0xba: printf( "PRESET" ); break; case 0xbb: printf( "PSET" ); break; case 0xd2: printf( "PAINT" ); break; case 0xda: printf( "PATTERN" ); break; case 0xdb: printf( "PALETTE" ); break; case 0xa6: printf( "RANDOMIZE" ); break; case 0xa8: printf( "RESTORE" ); break; case 0xa9: printf( "RESUME" ); break; case 0xaa: printf( "RUN" ); break; case 0xbc: printf( "RESET" ); break; case 0xab: printf( "SAVE" ); break; case 0xad: printf( "STOP" ); break; case 0xae: printf( "SWAP" ); break; case 0xaf: printf( "SYSTEM" ); break; case 0xbe: printf( "SUB" ); break; case 0xc0: printf( "SOUND" ); break; case 0xc9: printf( "SHARED" ); break; case 0xcb: printf( "SCROLL" ); break; case 0xd3: printf( "SCREEN" ); break; case 0xd7: printf( "SADD" ); break; case 0xdc: printf( "SLEEP" ); break; case 0xde: printf( "STRIG" ); break; case 0xdf: printf( "STICK" ); break; case 0xb0: printf( "TIME" ); break; case 0xb1: printf( "TRON" ); break; case 0xb2: printf( "TROFF" ); break; case 0xbd: printf( "TIMER" ); break; case 0xc8: printf( "UBOUND" ); break; case 0xca: printf( "UCASE$" ); break; case 0xb3: printf( "VARPTR" ); break; case 0xb4: printf( "WIDTH" ); break; case 0xc3: printf( "WINDOW" ); break; } break; case 0xF9: c = getchar(); count++; switch( c ) { case 0xfa: printf( "SPC" ); break; case 0xff: printf( "ALL" ); break; case 0xfe: printf( "APPEND" ); break; case 0xfd: printf( "AS" ); break; case 0xfc: printf( "BASE" ); break; case 0xf5: printf( "BREAK" ); break; case 0xfb: printf( "OUTPUT" ); break; case 0xf4: printf( "OFF" ); break; case 0xf9: printf( "STEP" ); break; case 0xf8: printf( "TAB" ); break; case 0xf6: printf( "WAIT" ); break; case 0xf7: printf( "USR" ); break; } break; case 0xFA: c = getchar(); count++; switch( c ) { case 0x97: printf( "COLLISION" ); break; case 0x87: printf( "OBJECT.SHAPE" ); break; case 0x88: printf( "OBJECT.PRIORITY" ); break; case 0x89: printf( "OBJECT.X" ); break; case 0x8a: printf( "OBJECT.Y" ); break; case 0x8b: printf( "OBJECT.VX" ); break; case 0x8c: printf( "OBJECT.VY" ); break; case 0x8d: printf( "OBJECT.AX" ); break; case 0x8e: printf( "OBJECT.AY" ); break; case 0x8f: printf( "OBJECT.CLIP" ); break; case 0x90: printf( "OBJECT.PLANES" ); break; case 0x91: printf( "OBJECT.HIT" ); break; case 0x92: printf( "OBJECT.ON" ); break; case 0x93: printf( "OBJECT.OFF" ); break; case 0x94: printf( "OBJECT.START" ); break; case 0x95: printf( "OBJECT.STOP" ); break; case 0x96: printf( "OBJECT.CLOSE" ); break; case 0x81: printf( "POKEW" ); break; case 0x82: printf( "POKEL" ); break; case 0x83: printf( "PEEKW" ); break; case 0x84: printf( "PEEKL" ); break; case 0x85: printf( "SAY" ); break; case 0x86: printf( "TRANSLATE$" ); break; case 0x80: printf( "WAVE" ); break; } break; case 0xFB: c = getchar(); count++; switch( c ) { case 0xFF: printf( "PTAB" ); break; default: printf( "<%02x>", c ); break; } break; case 0x01: /* variable */ case 0x02: /* define label */ id = getword(); count += 2; if( s = get_sym( id ) ) printf( "%s", s ); else printf( "<%04x>", id ); break; case 0x03: /* use label */ c = getchar(); count++; if( !c ) { id = getword(); count += 2; if( s = get_sym( id ) ) printf( "%s", s ); else printf( "<%04x>", id ); } break; case 0xE9: putchar( '>' ); break; case 0xF0: putchar( '^' ); break; case 0xEB: putchar( '<' ); break; case 0xEA: putchar( '=' ); break; case 0xED: putchar( '-' ); break; case 0xEE: putchar( '*' ); break; case 0xEF: putchar( '/' ); break; case 0xEC: putchar( '+' ); break; case 0x0F: printf( "%d", getchar() ); count++; break; case 0x11: putchar( '0' ); break; case 0x12: putchar( '1' ); break; case 0x13: putchar( '2' ); break; case 0x14: putchar( '3' ); break; case 0x15: putchar( '4' ); break; case 0x16: putchar( '5' ); break; case 0x17: putchar( '6' ); break; case 0x18: putchar( '7' ); break; case 0x19: putchar( '8' ); break; case 0x1A: putchar( '9' ); break; case 0x0C: printf( "&H%x", getword() ); count += 2; break; case 0x1C: printf( "%d", getword() ); count += 2; break; case 0x1D: *((long *)&f) = getlong(); printf( "%g", f ); count += 4; break; case 0x1E: printf( "%ld", getlong() ); count += 4; break; default: if( isprint( c ) ) putchar( c ); else printf( "<%02x>", c ); break; } return count; } void main( int argc, char *argv[] ) { int chars = 0, count, indent, nsym = 0; struct symbol *sym; /* pass 1 - read symbol table */ getchar(); /* skip F5 */ while( count = getword() ) /* skip code area */ { chars += count; count -= 2; while( count-- ) getchar(); } getchar(); /* skip null byte */ if( !( chars & 1 ) ) getchar(); while( ( count = getchar() ) != EOF ) { if( sym = read_sym( count, nsym++ ) ) store_sym( sym ); } #ifdef DUMP_SYM_TAB printf( "--- %d symbols ---\n", nsym ); for( sym = sym_tab; sym; sym = sym->next ) printf( "%d : %s\n", sym->id, sym->s ); printf( "------------------\n" ); #endif rewind( stdin ); /* pass 2 - read code */ getchar(); while( count = getword() ) { count -= 2; indent = getchar(); count--; while( indent-- ) putchar( ' ' ); while( count ) count -= expand(); } delete_sym_tab(); }