def D65.disassemble(buffer,start_address=0)
index=0
s=""
while index<buffer.length
byte=buffer[index]
current_address=start_address+index
opcode_name=OPCODES[byte][0]
operand_type=OPCODES[byte][1]
next_byte=(index<buffer.length-1?buffer[index+1]:0)
next_word=(index<buffer.length-2?buffer[index+1]+buffer[index+2]*256:0)
operand_format,operand_address= case operand_type
when :imp then ['','']
when :acc then ["A",'']
when :imm then ["\#$%02X",next_byte]
when :abs then ["$%04X",next_word]
when :abx then ["$%04X,X",next_word]
when :aby then ["$%04X,Y",next_word]
when :zpg then ["$%02X",next_byte]
when :zpx then ["$%02X,X",next_byte]
when :zpy then ["$%02X,Y",next_byte]
when :ind then ["($%04X)",next_word]
when :inx then ["($%02X),X",next_byte]
when :iny then ["($%02X),Y",next_byte]
when :inz then ["($%02X)",next_byte]
when :rel then ["$%04X",(current_address+next_byte.chr.unpack("c")[0]+2)%0x10000]
else
abort("unknown symbol #{operand_type}")
end
operand = sprintf(operand_format,operand_address)
opcode_size=OPCODE_SIZE[operand_type]
instruction_bytes=case opcode_size
when 1 then sprintf("%02X ",byte)
when 2 then sprintf("%02X %02X ",byte,next_byte)
when 3 then sprintf("%02X %02X %02X",byte,next_byte,next_word>>8)
end
s<<sprintf("%04X: %s %s %s ; ",current_address,instruction_bytes,opcode_name,operand.ljust(10))
annotation=annotations[operand_address]
if (annotation && (operand_type!=:imm)) then
s<<" "+annotation.to_s
end
s<< "\n"
index+=opcode_size
end
s
end