Simple Disassembler

From BeebWiki
Revision as of 12:12, 3 June 2008 by Jgharston (talk) (returns CLV instead of SEV, LDX/STX addr,Y returned)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Here is a well-written, compact, simple disassembler that will disassemble code in any ROM bank. See http://mdfs.net/Software/Assembler for fuller-featured disassemblers and disassembly code for different CPUs.

     REM > 65Dis
     REM Simple disassembly program
     REM By J.G.Harston
     DIM ctrl% 31,data% 3:X%=ctrl%:Y%=X% DIV 256
     INPUT "Address: &"A$:addr%=EVAL("&"+A$)
     INPUT "ROM number: &"A$:addr%=addr%+65536*EVAL("&F"+A$)
     REPEAT
       FOR Z%=0 TO 2:data%?Z%=FNrm(addr%+Z%):NEXT
       num%=FNDis_Code(M%,addr%,data%)
       PRINTFNh0(addr%,6);" ";
       FOR Z%=data% TO data%-1+num%:PRINTFNh0(?Z%,2);" ";:NEXT
       PRINTTAB(20);$(X%+4)
       addr%=addr%+num%
     UNTIL0
     :
     DEFFNh0(A%,N%):=RIGHT$("0000000"+STR$~A%,N%)
     DEFFNrm(!&F6):LOCAL Y%:Y%=?&F8 EOR &F0:IF?&F8<&80:IF?&F7>&BF:?&F9=0
     IF!&F6<0:IF?&F7>&7F OR Y%=&E:=(USR&FFB9)AND&FF ELSE =?!&F6
     :
     REM > Dis65 1.00 - 11-Nov-1989 - 65x02 disassembly routines
     REM v1.01 - &B8 returns CLV instead of SEV, LDX/STX addr,Y returned
     :
     DEFFNDis_Name(cpu%)="65x02"
     DEFFNDis_Code(cpu%,Ptr%,Data%):LOCAL op%,ins%,md%,b0%,num%
     num%=1:op%=?Data%:ins%=op%DIV32:md%=(op%AND31)DIV4:b0%=(op%AND3)
     X%!0=0:$(X%+4)=FN_diss:X%?3=num%:=num%
     DEFFN_diss
     IF(op%AND&F)=8:=MID$("PHPCLCPLPSECPHACLIPLASEIDEYTYATAYCLVINYCLDINXSED",1+3*(op%DIV16),3)
     IF(op%AND&8F)=&8A:=MID$("TXATXSTAXTSXDEXPHXNOPPLX",3*(op%DIV16)-23,3)
     IFop%=&20:="JSR "+FNmde(3)
     IF(op%AND&9F)=0:X%?2=(op%AND64):=MID$("BRK***RTIRTS",ins%*3+1,3)
     IF(op%AND&DF)=&5A:=MID$("PHYPLY",ins%*3-5,3)
     IFop%=&89:="BIT "+FNmde(2)
     IFb0%=1:=FNalu(ins%)+" "+FNmde(md%)
     IF(op%AND31)=&12:=FNalu(ins%)+" "+FNmde(8)
     IF(op%AND&EF)=&64:="STZ "+FNmde(md%)
     IF(op%AND&FD)=&9C:="STZ "+FNmde(b0%*2+3)
     IF(op%AND&D7)=&96:=FNrot(ins%)+" "+FNmde(md%AND3)+",Y"
     IF(op%AND7)=6:=FNrot(ins%)+" "+FNmde(md%)
     IF(op%AND&1F)=16:num%=2:="B"+MID$("PLMIVCVSCCCSNEEQ",1+2*ins%,2)+" "+FNjr(Data%?1)
     IF(op%AND&8F)=10:=FNrot((ins%+(md%AND4)*1.5)EOR((md%>4)AND1))+" A"
     IF(op%AND&E7)=4:="T"+MID$("SR",1+(md%DIV4),1)+"B "+FNmde(md%AND3)
     IF(op%AND&D3)=&C0:=FNbxy(ins%)+" "+FNmde(((md%EOR3)-1)AND3)
     IF(op%AND&E7)=&24:="BIT "+FNmde(md%)
     IF(op%AND&C7)=&84:=FNbxy(ins%)+" "+FNmde(md%)
     IF(op%AND&FD)=&A0:="LD"+MID$("YX",1+((op%AND2)DIV2),1)+" "+FNmde(2)
     IF(op%AND&CF)=&4C:IFop%<>&5C:X%?2=64:="JMP "+LEFT$("(",op%>&5F)+FNmde(md%)+LEFT$(")",op%>&5F)
     IFop%=&80:num%=2:X%?2=64:="BRA "+FNjr(Data%?1)
     X%?2=128:="EQUB &"+FNh0(op%,2)
     :
     DEFFNalu(A%)=MID$("ORAANDEORADCSTALDACMPSBC",A%*3+1,3)
     DEFFNrot(A%)=MID$("ASLROLLSRRORSTXLDXDECINC",A%*3+1,3)
     DEFFNbxy(A%)=MID$("***BIT***STZSTYLDYCPYCPX",A%*3+1,3)
     :
     DEFFNmde(A%):num%=2:IFA%=2:="#&"+FNh0(Data%?1,2)
     IF(A%AND2):num%=3:="&"+FNh0(Data%!1,4)+LEFT$(",X",A%=7)+LEFT$(",Y",A%=6)
     IF(A%AND1):="&"+FNh0(Data%?1,2)+LEFT$(",X",A%=5)
     ="(&"+FNh0(Data%!1,2)+LEFT$(",X",A%=0)+")"+LEFT$(",Y",A%=4)
     :
     DEFFNjr(A%):IFA%<128:="&"+FNh0(Ptr%+A%+2,4) ELSE ="&"+FNh0(Ptr%+A%+2-256,4)