10MODE7 20DIM workspace 40: DIM Buffer &2000: SymbolTableSize=1000:Address=Buffer 30RomNumber=15 40IO = FALSE 50INPUT LINE "Output file: "Out$ 60INPUT LINE "Object file: "File$ 70IF File$<>"" THEN GOTO 130 80INPUT LINE "Address: &"Address$ 90IF Address$ = "" GOTO 80 ELSE Address=EVAL("&"+Address$) 100IF PAGE<>&800 AND (&8000<=Address) AND (Address<=&BFFF) THEN IO = TRUE 110IF (&FFFF8000<=Address) AND (Address<=&FFFFBFFF) THEN IO = TRUE 120IF IO THEN INPUT LINE "Rom slot:"RomNumber 130INPUT LINE "Length: &"Length$ :IF Length$="" THEN Length=&100 ELSELength=EVAL("&"+Length$) 140INPUT LINE "Relocate: &"Reloc8$ 150IF Reloc8$<>"" THEN Reloc8=EVAL("&"+Reloc8$):RelOrg=Reloc8-Address ELSE RelOrg=0 160IF Out$<>"" THEN OSCLI"SPOOL "+Out$ 170PROCInitTables 180PRINT "AUTO" 190PROCInitSymbols 200 210Illegal$ = "?" 220IF File$<>"" THEN OSCLI("LOAD "+File$+" "+STR$~Buffer) 230PROCDisassemble(Address,Length) 240IF Out$<>"" THEN *SPOOL 250END 260 270DEFPROCDisassemble(Start,Length) 280Org=Start 290IF (Start AND &FFFF0000)=&FFFF0000 THEN Start=Start AND &FFFF:IO=TRUE 300PC = Start 310REPEAT 320 labsymb=FNlookup(PC+RelOrg) 330 IF labsymb<>0 IF (!labsymb AND &FFFF)=PC+RelOrg THEN PRINT " .";FNlabel(PC+RelOrg) 340 PC = PC+FN_dis(PC) 350 IF Opcode=&60 OR Opcode=&4C THEN PRINT 360UNTIL PC >= Start+Length 370ENDPROC 380 390DEFFN_dis(PC) 400 Opcode = FNget(PC) 410 Mode$ = FNmode(Opcode) 420 Name$ = FNname(Opcode) 430 IF Mode$ = Illegal$ THEN =FNillegal (Opcode) 440 ON INSTR(" ARI&#XYxyz()",Mode$) GOTO 480,520,560,600, 640,690,730,780,830,880,930,990,1030 ELSE 450 PRINT "Internal Error: Mode = "+Mode$ 460 470 480REM " " - Implicit 490=FNOpcode (1,"") 500 510 520REM "A" - Accumulator 530=FNOpcode (1," A") 540 550 560REM "R" - Relative 570=FNOpcode (2," "+FNlabel(PC+2+FNsex(FNget(PC+1))+RelOrg)) 580 590 600REM "I" - Indirect 610=FNOpcode (3," ("+FNlabel(FNpair)+")") 620 630 640REM "&" - Absolute 650Extra$ = "" 660=FNOpcode (3," "+FNlabel(FNpair)+Extra$) 670 680 690REM "#" - Immediate 700=FNOpcode (2," #"+STR$(FNget(PC+1))) 710 720 730REM "X" - Absolute, X 740Extra$ = ",X" 750GOTO 660 760 770 780REM "Y" - Absolute, Y 790Extra$ = ",Y" 800GOTO 660 810 820 830REM "x" - Xero page, X 840Extra$ = ",X" 850GOTO 950 860 870 880REM "y" - Zero page, Y 890Extra$ = ",Y" 900GOTO 950 910 920 930REM "z" - Zero page 940Extra$ = "" 950=FNOpcode (2," "+FNlabel(FNsingle)+Extra$) 960 970 980 990REM "(" - Pre indexed by X 1000=FNOpcode (2," ("+FNlabel(FNsingle)+",X)") 1010 1020 1030REM ")" - Post indexed by Y 1040=FNOpcode (2," ("+FNlabel(FNsingle)+"),Y") 1050 1060DEFFNillegal(Opcode) 1070 IF (ASC(" ")<=FNget(PC+1) AND FNget(PC+1)<=ASC("~")) AND (ASC(" ")<=Opcode AND Opcode<=ASC("~")) THEN =FNascii 1080 PROCaddress(1) 1090 PRINT " EQUB "; 1100 IF ASC(" ")<=Opcode AND Opcode<=ASC("~") THEN PRINT "ASC(""";CHR$(Opcode);""")" ELSE PRINT "&";STR$~(Opcode) 1110PRINT 1120=1 1130 1140DEFFNascii 1150 PROCaddress(3) 1160 PRINT " EQUS """; 1170 Count = 0 1180REM 1190 IF ASC(" ")<=FNget(PC+Count) AND FNget(PC+Count)<=ASC("~") THEN VDU FNget(PC+Count):Count=Count+1: GOTO 1180 1200 PRINT""": EQUB &"+FNHex(FNget(PC+Count),2) 1210PRINT 1220=Count+1 1230 1240 1250DEFFNsex(Byte) 1260IF Byte >= 128 THEN =(Byte OR &FFFFFF00) ELSE =Byte 1270 1280 1290DEFFNpair 1300 = FNget(PC+2)*256 + FNget(PC+1) 1310 1320 1330DEFFNsingle 1340 = FNget(PC+1) 1350 1360 1370 1380 1390DEFFNget(Address) 1400 IF IO THEN =FNgetHost(Address) : ELSE =Buffer?(Address-Org) 1410 1420 1430 DEFFNgetHost(Address) 1440 IF &8000 <= Address AND Address < &C000 THEN =FNgetRom(Address) 1450 Address=Address OR &FFFF0000 1460 !workspace=Address 1470 A%=5 : X%=workspace MOD 256: Y%=workspace DIV 256: CALL &FFF1 1480 =workspace?4 1490 1500 1510 DEFFNgetRom(Address) 1520 IF PAGE<>&800 THEN =FNlocalGetRom(Address) 1530 LOCAL OldRom, TheByte : OldRom=FNgetHost(&00F4) 1540 Address=Address OR &FFFF0000 1550 workspace!0=&FFFF00F4 1560 workspace?4=RomNumber 1570 A%=6 : X%=workspace MOD 256: Y%=workspace DIV 256: CALL &FFF1 1580 workspace!0=&FFFFFE30 1590 A%=6 : X%=workspace MOD 256: Y%=workspace DIV 256: CALL &FFF1 1600 !workspace=Address 1610 workspace?4=OldRom 1620 A%=5 : X%=workspace MOD 256: Y%=workspace DIV 256: CALL &FFF1 1630 TheByte=workspace?4 1640 workspace!0=&FFFF00F4 1650 workspace?4=OldRom 1660 A%=6 : X%=workspace MOD 256: Y%=workspace DIV 256: CALL &FFF1 1670 workspace!0=&FFFFFE30 1680 workspace?4=OldRom 1690 A%=6 : X%=workspace MOD 256: Y%=workspace DIV 256: CALL &FFF1 1700 =TheByte 1710 1720 1730DEFFNlocalGetRom(Address) 1740?&F6 = Address MOD 256 1750?&F7 = Address DIV 256 1760Y%=RomNumber 1770=USR(&FFB9) AND &FF 1780 1790 1800DEFFNlabel(Addr) 1810 LOCAL name$,symb 1820 symb=FNlookup(Addr) 1830 IF symb=0 THEN ="&"+STR$~Addr 1840 FOR i=3 TO SymbolEntrySize-1 1850 IF symb?i=ASC" " THEN workspace?(i-3)=13 ELSE workspace?(i-3)=symb?i 1860 NEXT 1870 workspace?SymbolEntrySize=13 1880 name$=$workspace 1890 IF (!symb AND &FFFF)=Addr THEN =name$ 1900 =name$+"+"+STR$(Addr-(!symb AND &FFFF)) 1910 1920 1930DEFFNOpcode (Size, Operand$) 1940 PROCaddress(Size) 1950 PRINT " "; Name$; Operand$ 1960 =Size 1970 1980 1990DEFFNx(Addr,Low,Size) 2000 =(Low <= Addr AND Addr < Low+Size) 2010 2020 2030 2040DEFFNr(Offset) 2050IF Offset>0 THEN = "+"+STR$(Offset) 2060="" 2070 2080 2090 2100DEFPROCaddress(Size) 2110 PRINT "\ ";FNHex((PC AND &FFFF)+RelOrg,4); 2120 FOR p = 1 TO 3 2130 IF p <= Size THEN PRINT " "FNHex(FNget((PC AND &FFFF)+p-1),2); ELSE PRINT " "; 2140 NEXT 2150 PRINT":"; 2160ENDPROC 2170 2180 2190DEFFNHex(I,J) 2200 = RIGHT$("000"+STR$~(I),J) 2210 2220 2230 2240 DEF PROCInitTables 2250 LOCAL a,b 2260 DIM Opcodes%(255) 2270 FOR a = 0 TO 15 2280 READ entry$ 2290 FOR b = 0 TO 15 2300 Opcodes%(a*16 + b)=FNencode(MID$(entry$,b*4+1,4)) 2310 NEXT 2320 NEXT 2330 2340 ENDPROC 2350 2360 DEF FNencode(string$) : REM Packs a 4 character string into 4 bytes !!! 2370 $workspace=string$ 2380 =!workspace 2390 2400 DEF FNname(op) 2410 LOCAL name$ 2420 workspace?4=13 2430 !workspace=Opcodes%(op) 2440 name$=$workspace 2450 =MID$(name$,1,3) 2460 2470 DEF FNmode(op) 2480 LOCAL name$ 2490 !workspace=Opcodes%(op) 2500 workspace?4=13 2510 name$=$workspace 2520 =MID$(name$,4,1) 2530 2540 REM Data table of all opcodes 2550 REM Each entry is 3 chars of opcode + one char of addressing mode 2560 REM The modes are :- 2570 REM None ( Space ) 2580 REM A Acc 2590 REM R Relative 2600 REM I Indirect 2610 REM & Absolute 2620 REM # Immediate 2630 REM z Zpage 2640 REM x Zpage,X 2650 REM y Zpage,Y 2660 REM X Abs,X 2670 REM Y Abs,Y 2680 REM ( Ind,X 2690 REM ) Ind,Y 2700 REM ? Illegal 2710 2720 REM "&x0 &x1 &x2 &x3 &x4 &x5 &x6 &x7 &x8 &x9 &xA &xB &xC &xD &xE &xF 2730 DATA"Brk Ora(????????????OrazAslz????Php Ora#AslA????????Ora&Asl&????" 2740 DATA"BplROra)????????????OraxAslx????Clc OraY????????????OraXAslX????" 2750 DATA"Jsr&And(????????BitzAndzRolz????Plp And#RolA????Bit&And&Rol&????" 2760 DATA"BmiRAnd)????????????AndxRolx????Sec AndY????????????AndXRolX????" 2770 DATA"Rti Eor(????????????EorzLsrz????Pha Eor#LsrA????Jmp&Eor&Lsr&????" 2780 DATA"BvcREor)????????????EorxLsrx????Cli EorY????????????EorXLsrX????" 2790 DATA"Rts Adc(????????????AdczRorz????Pla Adc#RorA????JmpIAdc&Ror&????" 2800 DATA"BvsRAdc)????????????AdcxRorx????Sei AdcY????????????AdcX????????" 2810 DATA"????Sta(????????StyzStazStxz????Dey ????Txa ????Sty&Sta&Stx&????" 2820 DATA"BccRSta)????????StyxStaxStxy????Tya StaYTxs ????????StaX????????" 2830 DATA"Ldy#Lda(Ldx#????LdyzLdazLdxz????Tay Lda#Tax ????Ldy&Lda&Ldx&????" 2840 DATA"BcsRLda)????????LdyxLdaxLdxy????Clv LdaYTsx ????LdyXLdaXLdxY????" 2850 DATA"Cpy#Cmp(????????CpyzCmpzDecz????Iny Cmp#Dex ????Cpy&Cmp&Dec&????" 2860 DATA"BneRCmp)????????????CmpxDecx????Cld CmpY????????????CmpXDecX????" 2870 DATA"Cpx#Sbc(????????CpxzSbczIncz????Inx Sbc#Nop ????Cpx&Sbc&Inc&????" 2880 DATA"BeqRSbc)????????????SbcxIncx????Sed SbcY????????????SbcXIncX????" 2890 2900 2910 DEFPROCInitSymbols 2920 LOCAL name$,Addr,Size 2930 DIM SymbolTable SymbolTableSize 2940 SymbolEntrySize=2+1+7 2950 RESTORE 3370 2960 NextFreeSymb=SymbolTable 2970 REPEAT 2980 READ name$,Addr,Size 2990 IF name$<>"" PROCdefine(name$,Addr,Size) 3000 UNTIL name$="" 3010 ENDPROC 3020 3030 3040 DEFPROCdefine(name$,Addr,Size) 3050 LOCAL symb,i 3060 IF NextFreeSymb-SymbolTable>= SymbolTableSize THEN PRINT "Too Many Symbols": ENDPROC 3070 symb=NextFreeSymb : NextFreeSymb=NextFreeSymb+SymbolEntrySize 3080 $workspace=name$+" " 3090 symb?0=Addr MOD 256 3100 symb?1=Addr DIV 256 3110 symb?2=Size 3120 FOR i=3 TO SymbolEntrySize-1 3130 symb?i=workspace?(i-3) 3140 NEXT 3150 IF (((Address+RelOrg) AND &0000FFFF) <= Addr) AND (Addr <= ((Address+RelOrg) AND &0000FFFF) + Length) THEN ENDPROC 3160 PRINT LEFT$(name$+" ",SymbolEntrySize-3);" = &";FNHex(Addr,4) 3170 ENDPROC 3180 3190 3200 DEFPROCprintsymbol(symb) 3210 PRINT """"; : FOR i=3 TO SymbolEntrySize-1 : VDU symb?i : NEXT 3220 PRINT " : ";FNHex(!symb AND &FFFF,4);" ";symb?2 3230 ENDPROC 3240 3250 3260 DEFFNlookup(Addr) 3270 LOCAL symb 3280 symb=SymbolTable 3290 IF FNx(Addr,!symb AND &FFFF,symb?2) THEN =symb 3300 symb=symb+SymbolEntrySize 3310 IF symb