6800 / 6802 / 68HC11 disassembler by Peter A. Stark (pastark@cloud9.net) This disassembler is written in Basic and runs in GWBASIC (so I suppose it should be called a cross-disassembler!). Hence it is easily modified for other processors or other file structures. Feel free to use and/or modify it. The program was a quick-and-dirty solution to a problem I had; hence it works, but is not a commercial-quality, finished piece of art. It's a bit quirky, and you have to set up the input files just right. But it works. As written, this program assumes an input file that looks like this: 1000 B6 10 1A BB 10 1B 8B 05 B7 10 30 FE 10 1C BD 30 1010 00 CE 10 1E BD 40 00 7E 10 17 04 05 10 00 54 48 1020 49 53 20 49 53 20 53 4F 4D 45 20 54 45 58 54 2E I used this particular format because that is what I got from the hex dump routine of a particular system that I was working with. In this particular case, there is a single space at the end of each line -- the program wants that. So you may have to doctor up your source code a bit to fit, or may have to change the program to fit your data. In addition, the program wants a file called LIMITS, which specifies what you think is in different regions of the program. For example, the LIMITS file for this particular program is P,1000 B,101A W,101C T,101E This file says that "P" Program instructions start at address $1000, there is "B" Byte data starting at 101A, "W" Word data starting at 101C, and "T" Text data starting at 101E. In addition, you could use "L" for Labels, and "Q" or Quiet to turn off listing for certain sections. Obviously you don't know what's where when you first start disassembling, but the program insists on having the file anyway. So I usually start with a simple file with just one line that reads P,0000 to get things started. Each time I disassemble, I then add more info to the LIMITS file as I learn more about the program. Furthermore, the program also wants a file called LABELS. The one for the above program reads like this: START ,1000 NUM1 ,101A NUM2 ,101B ANSWER,1030 NUM3 ,101C SUBR1 ,3000 SUBR2 ,4000 HERE ,1017 TEXT ,101E This file tells the disassembler what labels to use for which addresses. As before, you obviously don't know what labels to use for what as you start. So I usually start off with a one-line file that reads ABCDEF,0000 which assigns the label ABCDEF to address 0000 (notice how exactly six columns are set aside for each label -- add spaces to shorter ones to stretch to six.) I then run the program on these three files. It produces a disassembly listing on the screen, plus three new files: LISTING.TXT is the same disassembly listing as was on the screen. As usual, it shows the machine code on the left, and the assembly code on the right. SOURCE.TXT is just the machine code, formatted so it is pretty much ready for an assembler. LABELS.NEW is a new LABELS file. This file contains all the lines from your original LABELS file, but in addition it contains entries for all other addresses that are somehow referenced in the program, and for which it therefore needs labels. This file uses the labels L00001, L00002, and so on. The idea is to look at the LISTING.TXT file, and try to come up with meaningful names for labels that you recognize. Then edit the LABELS.NEW file to change the L000.. labels to your meaningful names, delete any unneeded ones, rename LABELS.NEW to LABELS, and disassemble again. Disassembly is thus an iterative process -- you disassemble a number of times, each time improving your LIMITS and LABELS files, until you get it right. Listed below is the actual code for the disassembler. Good Luck and let me know how you make out. Pete Stark ======================================================================== 10 PRINT "6800/6802/68XX11 DISASSEMBLER IN BASIC" 20 PRINT "COPYRIGHT 1997 BY PETER A. STARK" 30 PRINT "ALL RIGHTS RESERVED" 40 PRINT " ... working - please wait ..." 50 DIM OP$(255) 60 FOR I=0 TO 255 : READ OP$(I) : NEXT I 70 REM INSTRUCTION CODE TABLE 80 DATA -,NOP\0/I,IDIV\0/I,FDIV\0/I,LSRD\0/I,ASLD\0/I,TAP\0/I,TPA\0/I '0 90 DATA INX\0/I,DEX\0/I,CLV\0/I,SEV\0/I,CLC\0/I,SEC\0/I,CLI\0/I,SEI\0/I 100 DATA SBA\0/I,CBA\0/I,BRSET\3/D,BRCLR\3/D,BSET\2/D,BCLR\2/D,TAB\0/I,TBA\0/I '1 110 DATA -,DAA\0/I,-,ABA\0/I,BSET\2/X,BCLR\2/X,BRSET\3/X,BRCLR\3/X 120 DATA BRA\1/B,BRN\1/B,BHI\1/B,BLS\1/B,BCC\1/B,BCS\1/B,BNE\1/B,BEQ\1/B 130 DATA BVC\1/B,BVS\1/B,BPL\1/B,BMI\1/B,BGE\1/B,BLT\1/B,BGT\1/B,BLE\1/B 140 DATA TSX\0/I,INS\0/I,PULA\0/I,PULB\0/I,DES\0/I,TXS\0/I,PSHA\0/I,PSHB\0/I 150 DATA PULX\0/I,RTS\0/I,ABX\0/I,RTI\0/I,PSHX\0/I,MUL\0/I,WAI\0/I,SWI\0/I 160 DATA NEGA\0/I,-,-,COMA\0/I,LSRA\0/I,-,RORA\0/I,ASRA\0/I 170 DATA ASLA\0/I,ROLA\0/I,DECA\0/I,-,INCA\0/I,TSTA\0/I,-,CLRA\0/I 180 DATA NEGB\0/I,-,-,COMB\0/I,LSRB\0/I,-,RORB\0/I,ASRB\0/I 190 DATA ASLB\0/I,ROLB\0/I,DECB\0/I,-,INCB\0/I,TSTB\0/I,-,CLRB\0/I 200 DATA NEG\1/X,-,-,COM\1/X,LSR\1/X,-,ROR\1/X,ASR\1/X 210 DATA ASL\1/X,ROL\1/X,DEC\1/X,-,INC\1/X,TST\1/X,JMP\1/X,CLR\1/X 220 DATA NEG\2/E,-,-,COM\2/E,LSR\2/E,-,ROR\2/E,ASR\2/E 230 DATA ASL\2/E,ROL\2/E,DEC\2/E,-,INC\2/E,TST\2/E,JMP\2/E,CLR\2/E 240 DATA SUBA\1/#,CMPA\1/#,SBCA\1/#,SUBD\2/#,ANDA\1/#,BITA\1/#,LDAA\1/#,- 250 DATA EORA\1/#,ADCA\1/#,ORAA\1/#,ADDA\1/#,CPX\2/#,BSR\1/B,LDS\2/#,XGDX\0/I 260 DATA SUBA\1/D,CMPA\1/D,SBCA\1/D,SUBD\1/D,ANDA\1/D,BITA\1/D,LDAA\1/D,STAA\1/D 270 DATA EORA\1/D,ADCA\1/D,ORAA\1/D,ADDA\1/D,CPX\1/D,JSR\1/D,LDS\1/D,STS\1/D 280 DATA SUBA\1/X,CMPA\1/X,SBCA\1/X,SUBD\1/X,ANDA\1/X,BITA\1/X,LDAA\1/X,STAA\1/X 290 DATA EORA\1/X,ADCA\1/X,ORAA\1/X,ADDA\1/X,CPX\1/X,JSR\1/X,LDS\1/X,STS\1/X 300 DATA SUBA\2/E,CMPA\2/E,SBCA\2/E,SUBD\2/E,ANDA\2/E,BITA\2/E,LDAA\2/E,STAA\2/E 310 DATA EORA\2/E,ADCA\2/E,ORAA\2/E,ADDA\2/E,CPX\2/E,JSR\2/E,LDS\2/E,STS\2/E 320 DATA SUBB\1/#,CMPB\1/#,SBCB\1/#,ADDD\2/#,ANDB\1/#,BITB\1/#,LDAB\1/#,- 330 DATA EORB\1/#,ADCB\1/#,ORAB\1/#,ADDB\1/#,LDD\2/#,-,LDX\2/#,STOP\0/I 340 DATA SUBB\1/D,CMPB\1/D,SBCB\1/D,ADDD\2/#,ANDB\1/D,BITB\1/D,LDAB\1/D,STAB\1/D 350 DATA EORB\1/D,ADCB\1/D,ORAB\1/D,ADDB\1/D,LDD\1/D,STD\1/D,LDX\1/D,STX\1/D 360 DATA SUBB\1/X,CMPB\1/X,SBCB\1/X,ADDD\1/X,ANDB\1/X,BITB\1/X,LDAB\1/X,STAB\1/X 370 DATA EORB\1/X,ADCB\1/X,ORAB\1/X,ADDB\1/X,LDD\1/X,STD\1/X,LDX\1/X,STX\1/X 380 DATA SUBB\2/E,CMPB\2/E,SBCB\2/E,ADDD\2/E,ANDB\2/E,BITB\2/E,LDAB\2/E,STAB\2/E 390 DATA EORB\2/E,ADCB\2/E,ORAB\2/E,ADDB\2/E,LDD\2/E,STD\2/E,LDX\2/E,STX\2/E 400 DIM LIMITS$(300,2), LABELS$(300,2) 410 OPEN "LIMITS" FOR INPUT AS 1 420 FOR I=1 TO 300 430 IF EOF(1) THEN GOTO 470 440 INPUT #1, LIMITS$(I,1), LIMITS$(I,2) 450 NEXT I 460 PRINT "TOO MANY LIMITS" : END 470 LIMITS=I-1 480 CLOSE 1 490 OPEN "LABELS" FOR INPUT AS 1 500 FOR I=1 TO 300 510 IF EOF(1) THEN GOTO 580 520 INPUT #1, LABELS$(I,1), LABELS$(I,2) 530 IF LEFT$(LABELS$(I,1),2)="L0" THEN GOTO 510 540 IF LEN(LABELS$(I,1))<6 THEN LABELS$(I,1)=LABELS$(I,1)+" " : GOTO 540 550 IF LEN(LABELS$(I,1))>6 THEN LABELS$(I,1)=LEFT$(LABELS$(I,1),6) 560 NEXT I 570 PRINT "TOO MANY LABELS" : END 580 LABELS=I-1 590 CLOSE 1 610 INPUT "Input name of file to disassemble"; F$ 620 PASS=1 630 TYPE$="B" 'default type is binary 635 ZZ$="" 640 QUIET=0 650 LOADD$="FFFF" : HIADD$ = "0000" 660 OPEN F$ FOR INPUT AS 1 680 ' main loop 690 PREFIX=0 'start with prefix flag normal 700 GOSUB 720 'get next address or data item 710 GOTO 970 'bypass the two subroutines 720 '=========subroutine to get the next address or data byte from file 730 IF LEN(ZZ$)<2 AND EOF(1) THEN GOTO 3000 740 IF LEN(ZZ$)<2 THEN LINE INPUT #1, ZZ$ 742 IF LEN(ZZ$)=0 THEN GOTO 3000 750 LN=INSTR(ZZ$," ") 760 IF LN=1 THEN ZZ$=MID$(ZZ$,2) : GOTO 730 770 NXT$=LEFT$(ZZ$,LN-1) 780 ZZ$=MID$(ZZ$,LN) 790 IF LEN(NXT$)<3 THEN GOTO 830 800 IF PC$<>NXT$ AND L$<>"" THEN GOSUB 2660 810 IF OPC$="" AND PC$<>NXT$ THEN L$=STRING$(32," ")+"ORG $"+NXT$ : GOSUB 2660 820 PC$=NXT$ : GOTO 730 830 PRPC$=PC$ 840 IF PC$HIADD$ THEN HIADD$=PC$ 860 CARRY=1 870 FOR J=LEN(PC$) TO 1 STEP -1 880 C$=MID$(PC$,J,1) 890 C$=CHR$(ASC(C$)+CARRY) 'also PC <- PC + 1 900 IF C$=":" THEN C$="A" 910 IF C$="G" THEN C$="0" : CARRY = 1 ELSE CARRY = 0 920 MID$(PC$,J,1)=C$ 930 NEXT J 940 RETURN 950 '======= end of subroutine to get next data or address from input file 960 ' 970 BY$=NXT$ 980 OPLOC$=PRPC$ 990 FOR I=1 TO LIMITS 1000 IF OPLOC$<>LIMITS$(I,2) THEN GOTO 1050 1010 PRTYPE$=TYPE$ 1020 TYPE$=LIMITS$(I,1) 1030 IF PRTYPE$="Q" AND TYPE$<>"Q" THEN QUIET=0 : L$="" : GOSUB 2660 : L$=STRING$(32," ")+"ORG $"+PRPC$ : GOSUB 2660 1040 GOTO 1060 1050 NEXT I 1060 NAM$=" " 1070 FOR I=1 TO LABELS 1080 IF OPLOC$=LABELS$(I,2) THEN NAM$=LABELS$(I,1) : GOTO 1100 1090 NEXT I 1100 IF TYPE$<>"B" THEN GOTO 1200 'do binary type ====================== 1110 L$=OPLOC$ + " " + BY$ + " " + NAM$ + " FCB $" + BY$ 1120 GOSUB 2660 : GOTO 690 1130 '====== Subroutine to convert hex byte BY$ to decimal 1140 C1=ASC(LEFT$(BY$,1))-48 : IF C1>9 THEN C1=C1-7 1150 C2=ASC(RIGHT$(BY$,1))-48 : IF C2>9 THEN C2=C2-7 1160 BY=C1*16+C2 1170 RETURN 1180 '======= End of subroutine to convert hex byte to decimal 1190 ' 1200 IF TYPE$<>"W" THEN GOTO 1250 'do word type ======================== 1210 GOSUB 720 1220 L$=OPLOC$ + " " + BY$ + NXT$ + " " + NAM$ + " FDB $" + BY$ + NXT$ 1230 GOSUB 2660 : GOTO 690 1240 ' 1250 IF TYPE$<>"T" THEN GOTO 1370 'do text type ======================== 1260 OPC$="FCC" 1270 L$=OPLOC$ + " " + BY$ + "... " + NAM$ + " FCC '" 1280 IF BY$<"20" OR BY$>"7E" THEN OPLOC$=PRPC$ : GOTO 1110 'DO AS BYTE IF NOT TEXT 1290 GOSUB 1130 'hex by$ to dec 1300 L$=L$+CHR$(BY) 'IF TEXT, ADD TO STRING 1310 GOSUB 720 'GET NEXT 1320 BY$=NXT$ 1330 IF BY$<"20" OR BY$>"7E" THEN L$=L$+"'": GOSUB 2660: OPLOC$=PRPC$ : GOTO 1110 1340 IF LEN(L$)>60 AND BY$="20" THEN L$=L$ + "'" : GOSUB 2660: OPLOC$=PRPC$ : GOTO 1270 1350 GOTO 1290 'if OK, add to string 1360 ' 1370 IF TYPE$<>"P" THEN GOTO 2790 'do program type ==================== 1380 GOSUB 1130 'hex by$ to dec 1390 IF BY$="18" OR BY$="1A" OR BY$="CD" THEN GOTO 2440 'HC11 prefixes 1400 OP$=OP$(BY) 1410 IF OP$="-" THEN GOTO 1110 1420 LNF=INSTR(OP$,"/") 1430 LNB=INSTR(OP$,"\") 1440 OPC$=LEFT$(OP$,LNB-1) 1450 IF LEN(OPC$)<6 THEN OPC$=OPC$ + " " : GOTO 1450 1460 OLE$=MID$(OP$,LNB+1,1) 1470 IF LNF>0 THEN OTY$=RIGHT$(OP$,1) ELSE OTY$="" 1480 L$=OPLOC$ + " " + BY$ + " " 1490 IF OLE$="0" THEN GOTO 1540 1500 IF OLE$="1" THEN GOTO 1570 1510 IF OLE$="2" THEN GOTO 2140 1520 IF OLE$="3" THEN GOTO 2400 'new BRSET and BRCLR instructions 1530 STOP 1540 ' length=0 must be inherent ----------------- 1550 L$=L$ + " " + NAM$ + " " + OPC$ 1560 GOSUB 2660 : GOTO 690 1570 ' length = 1; could be D,X,#,B -------------- 1580 GOSUB 730 : BY1$=NXT$ 'get 1 byte, bump addr 1590 L$=L$ + BY1$ + " " + NAM$ + " " + OPC$ + " " 1600 IF OTY$="D" THEN GOTO 1650 1610 IF OTY$="X" THEN GOTO 1770 1620 IF OTY$="#" THEN GOTO 1810 1630 IF OTY$="B" THEN GOTO 1850 1640 STOP 1650 ' process direct instruction ------------------------------------- 1660 OPADD$="00" + BY1$ 1670 FOR I=1 TO LABELS 1680 IF OPADD$=LABELS$(I,2) THEN OPAND$=LABELS$(I,1) : GOTO 1750 1690 NEXT I 1700 LABELS=LABELS+1 1710 OPAND$=MID$(STR$(LABELS),2) 1720 IF LEN(OPAND$)<5 THEN OPAND$="0"+OPAND$ : GOTO 1720 1730 OPAND$="L" + OPAND$ 1740 LABELS$(LABELS,1)=OPAND$ : LABELS$(LABELS,2)=OPADD$ 1750 L$ = L$ + OPAND$ 1760 GOSUB 2660 : GOTO 690 1770 ' process indexed instruction ----------------------------------- 1780 BY$=BY1$ : GOSUB 1130 'cvt hex to dec 1790 L$ = L$ + MID$(STR$(BY),2) + ",X 1800 GOSUB 2660 : GOTO 690 1810 ' process immediate instruction ------------------------------- 1820 BY$=BY1$ : GOSUB 1130 'cvt hex to dec 1830 L$ = L$ + "#" + MID$(STR$(BY),2) 1840 GOSUB 2660 : GOTO 690 1850 ' process branch ----------------------------------------------- 1855 BRLEN = 2 'most branches are 2 bytes, except BRCLR and the like 1860 BY$=BY1$ : GOSUB 1130 'cvt hex to dec 1870 OFFSET = BY : IF OFFSET>127 THEN OFFSET = OFFSET - 256 1880 BY$=LEFT$(OPLOC$,2) : GOSUB 1130 : OPLOC=BY 1890 BY$=RIGHT$(OPLOC$,2) : GOSUB 1130 : OPLOC = OPLOC*256 + BY 1900 BRADDR=OPLOC + OFFSET + BRLEN 'address the branch goes to 1910 D1=INT(BRADDR/4096) 1920 D2 = INT((BRADDR-D1*4096)/256) 1930 D3 = INT((BRADDR-D1*4096-D2*256)/16) 1940 D4 = BRADDR-D1*4096-D2*256-D3*16 1950 IF D1>9 THEN D1=D1+7 1960 D1$=CHR$(D1+48) 1970 IF D2>9 THEN D2=D2+7 1980 D2$=CHR$(D2+48) 1990 IF D3>9 THEN D3=D3+7 2000 D3$=CHR$(D3+48) 2010 IF D4>9 THEN D4=D4+7 2020 D4$=CHR$(D4+48) 2030 OPADD$=D1$+D2$+D3$+D4$ 2040 FOR I=1 TO LABELS 2050 IF OPADD$=LABELS$(I,2) THEN OPAND$=LABELS$(I,1) : GOTO 2120 2060 NEXT I 2070 LABELS=LABELS+1 2080 OPAND$=MID$(STR$(LABELS),2) 2090 IF LEN(OPAND$)<5 THEN OPAND$="0"+OPAND$ : GOTO 2090 2100 OPAND$="L" + OPAND$ 2110 LABELS$(LABELS,1)=OPAND$ : LABELS$(LABELS,2)=OPADD$ 2120 L$ = L$ + OPAND$ 2130 GOSUB 2660 : GOTO 690 2140 ' length = 2; could be E,#,X ---------------- 2150 GOSUB 730 : BY1$=NXT$ : GOSUB 730 : BY2$=NXT$ 2160 L$=L$ + BY1$ + BY2$ + " " + NAM$ + " " + OPC$ + " " 2170 IF OTY$="E" THEN GOTO 2210 2180 IF OTY$="#" THEN GOTO 2230 2190 IF OTY$="X" THEN GOTO 2350 2200 STOP 2210 ' process extended instruction ---------------------------------- 2220 OPADD$= BY1$ + BY2$ : GOTO 1670 'otherwise same as direct 2230 ' process immediate x-reg or stack reg instruction -------------- 2240 OPADD$= BY1$ + BY2$ 2250 FOR I=1 TO LABELS 2260 IF OPADD$=LABELS$(I,2) THEN OPAND$=LABELS$(I,1) : GOTO 2330 2270 NEXT I 2280 LABELS=LABELS+1 2290 OPAND$=MID$(STR$(LABELS),2) 2300 IF LEN(OPAND$)<5 THEN OPAND$="0"+OPAND$ : GOTO 2300 2310 OPAND$="L" + OPAND$ 2320 LABELS$(LABELS,1)=OPAND$ : LABELS$(LABELS,2)=OPADD$ 2330 L$ = L$ + "#" + OPAND$ 2340 GOSUB 2660 : GOTO 690 2350 ' process indexed BCLR, BSET instructions ---------------------- 2360 BY$=BY1$ : GOSUB 1130 'cvt hex to dec 2370 L$ = L$ + MID$(STR$(BY),2) + ",X $" + BY2$ 2380 GOSUB 2660 : GOTO 690 2390 ' Process 68HC11 BRSET and BRCLR instructions: length=3, D or X--- 2400 GOSUB 730 : BY1$=NXT$ : GOSUB 730 : BY2$=NXT$ : GOSUB 730 : BY3$=NXT$ 2402 L$ = L$ + BY1$ + " " + BY2$ + " " + BY3$ + " " + NAM$ + " " + OPC$ + " " 2409 IF OTY$="D" THEN GOTO 2412 2410 IF OTY$="X" THEN GOTO 2430 2411 STOP 2412 '3 bytes add'l for BRSET or BRCLR direct instruction 2413 OPADD$="00" + BY1$ 2414 FOR I=1 TO LABELS 2415 IF OPADD$=LABELS$(I,2) THEN OPAND$=LABELS$(I,1) : GOTO 2422 2416 NEXT I 2417 LABELS=LABELS+1 2418 OPAND$=MID$(STR$(LABELS),2) 2419 IF LEN(OPAND$)<5 THEN OPAND$="0"+OPAND$ : GOTO 2419 2420 OPAND$="L" + OPAND$ 2421 LABELS$(LABELS,1)=OPAND$ : LABELS$(LABELS,2)=OPADD$ 2422 L$ = L$ + OPAND$ + " $" + BY2$ + " " 2423 GOTO 2436 2429 STOP 2430 '3 bytes add'l for BRSET or BRCLR indexed instruction 2433 BY$=BY1$ : GOSUB 1130 'cvt hex to dec 2434 L$ = L$ + MID$(STR$(BY),2) + ",X $" + BY2$ + " " 2436 BY1$ = BY3$ : BRLEN=4 : GOTO 1860 'process the rest as a 4-byte branch 2439 STOP 2440 ' Process 68HC11 prefixed instructions --------------------------- 2450 PREFIX$=BY$ 2460 PRELOC$=OPLOC$ 2470 PREFIX=1 'flag 2480 GOTO 700 'return to program and do as if there is no prefix 2490 ' then return here on a diverted output in case of a prefix 2500 OPC$=MID$(L$,9,11) 'insert prefix into output line 2510 MID$(L$,12,11)=OPC$ 2520 MID$(L$,1,4)=PRELOC$ ' and also fix address 2530 MID$(L$,9,2)=PREFIX$ 2540 IF MID$(L$,33,4)="SUBD" THEN GOTO 2590 2550 IF PREFIX$="CD" THEN GOTO 2620 2560 LN=INSTR(33,L$,"X") 2570 MID$(L$,LN,1)="Y" 'change first X to Y 2580 GOTO 2690 'continue normal 2590 MID$(L$,33,4)="CPD " 'all SUBD become CPD 2600 IF PREFIX$="CD" GOTO 2620 'prefix CD SUBD's also change X->Y 2610 GOTO 2690 'non-CD SUBD's don't change X->Y 2620 LN=INSTR(33,L$,",X") 2630 MID$(L$,LN,2)=",Y" 'change ,X to ,Y for all CD's 2640 GOTO 2690 2650 ' Output results =============================================== 2660 OPC$="" 2670 IF QUIET=1 THEN RETURN 2680 IF PREFIX>0 THEN GOTO 2500 'divert output if we have a prefix 2690 IF PASS=2 THEN PRINT L$ 2700 'PRINT L$ 2710 IF PASS=2 THEN PRINT #2, L$ 2720 IF PASS=2 THEN PRINT #3, MID$(L$,26) 2730 C$=MID$(L$,33,3) 2740 IF PASS=2 AND (C$="BRA" OR C$="JMP" OR C$="RTS" OR C$="RTI") THEN PRINT "" 2750 IF PASS=2 AND (C$="BRA" OR C$="JMP" OR C$="RTS" OR C$="RTI") THEN PRINT #2, "" 2760 IF PASS=2 AND (C$="BRA" OR C$="JMP" OR C$="RTS" OR C$="RTI") THEN PRINT #3, "" 2770 NAM$=" " : L$="" 2780 RETURN 2790 IF TYPE$<>"Q" THEN GOTO 2830 'Quit output on Q code ================== 2800 QUIET=1 2810 GOTO 690 2820 ' 2830 IF TYPE$<>"L" THEN GOTO 2970 ' words as labels ====================== 2840 GOSUB 720 2850 OPADD$=BY$ + NXT$ 2860 FOR I=1 TO LABELS 2870 IF OPADD$=LABELS$(I,2) THEN OPAND$=LABELS$(I,1) : GOTO 2940 2880 NEXT I 2890 LABELS=LABELS+1 2900 OPAND$=MID$(STR$(LABELS),2) 2910 IF LEN(OPAND$)<5 THEN OPAND$="0"+OPAND$ : GOTO 2910 2920 OPAND$="L" + OPAND$ 2930 LABELS$(LABELS,1)=OPAND$ : LABELS$(LABELS,2)=OPADD$ 2940 L$=OPLOC$ + " " + BY$ + NXT$ + " " + NAM$ + " FDB " + OPAND$ 2950 GOSUB 2660 : GOTO 690 2960 ' 2970 STOP 'here we'll handle other kinds of statements? ==================== 2980 'End of pass; beginning of next pass =================================== 2990 ' 3000 IF L$<>"" THEN GOSUB 2660 3008 L$=STRING$(32," ") + "END" : GOSUB 2660 3010 CLOSE 3020 IF PASS=2 THEN GOTO 3150 3030 PASS=2 '=================PASS 2============ 3040 OPEN "listing.txt" FOR OUTPUT AS 2 3050 OPEN "source.txt" FOR OUTPUT AS 3 3060 L$="" : GOSUB 2660 3070 L$=STRING$(25," ") + "* EQUATES" : GOSUB 2660 3080 L$="" : GOSUB 2660 3090 FOR I = 1 TO LABELS 3100 L$=STRING$(25," ") + LABELS$(I,1) + " EQU $" + LABELS$(I,2) 3110 IF LABELS$(I,2)HIADD$ THEN GOSUB 2660 3120 NEXT I 3130 L$="" : GOSUB 2660 3140 GOTO 630 3150 ' end of pass 3; just output labels.new file ========================== 3160 OPEN "labels.new" FOR OUTPUT AS 2 3170 FOR I = 1 TO LABELS 3180 PRINT #2, LABELS$(I,1); ","; LABELS$(I,2) 3190 NEXT I 3200 CLOSE 3PEN "source.txt" FOR OUTPUT AS 3 3060 L$="" : GOSUB 2660 3070 L$=STRING$(25," ") + "* EQUATES" : GOSUB 2660 3080 L$="" : GOSUB 2660 3090 FOR I = 1 TO LABELS 3100 L$=STRING$(25," ") + LABELS$(I,1) + " EQU $" + LABELS$(I,2) 3110 IF LABELS$(I,2)HIADD$ THEN GOSUB 2660 3120 NEXT I 3130 L$="" : GOSUB 2660 3140 GOTO 630 3150 ' end of pass 3; just output labels.new file ========================== 3160 OPEN "labels.new" FOR OUTPUT AS 2 3170 FOR I = 1 TO LABELS 3180 PRINT #2, LABELS$(I,1); ","; LABELS$(I,2) 3190 NEXT I 3200 CLOSE 3210 END