import { BaseMemory } from "../disassembler/basememory" ; import { Opcode , Opcodes } from "../disassembler/opcode" ; import { Format } from "../disassembler/format" ; import { Disassembler } from "../disassembler/disasm" ; import { Utility } from './utility' ; import { Settings } from '../settings' ; import { Z80Registers } from "../remotes/z80registers" ; import { Labels } from "../labels/labels" ; const TmpDasmFileName = 'disasm.asm' ; /**
 * This class capsulates a few disassembling functions.
 */ export class DisassemblyClass extends Disassembler { param addr param data param count returns public static getLines ( addr , data , count ) { if ( count == undefined || count > data . length / 4 ) count = data . length / 4 ; const size = 4 * count ; const buffer = new BaseMemory ( addr , size ) ; for ( let i = 0 ; i < size ; i ++ ) { const value = data [ i ] ; buffer . setValueAtIndex ( i , value ) ; } const prevLabelHandler = ( Opcode as any ) . convertToLabelHandler ; Opcode . setConvertToLabelHandler ( undefined as any ) ; let address = addr ; const list = new Array < { address : number ; instruction : string ; } > ( ) ; for ( let i = 0 ; i < count ; i ++ ) { const opcode = Opcode . getOpcodeAt ( buffer , address ) ; const opCodeDescription = opcode . disassemble ( ) ; const instruction = Format . formatDisassembly ( undefined , false , 0 , 0 , 0 , 0 , address , opcode . length , opCodeDescription . mnemonic ) ; list . push ( { address , instruction } ) ; address = ( address + opcode . length ) & 0xFFFF ; } Opcode . setConvertToLabelHandler ( prevLabelHandler ) ; return list ; } param addr param data param count returns public static getDasmMemory ( addr , data ) { const size = data . length - 3 ; if ( size <= 0 ) return [ ] ; const buffer = new BaseMemory ( addr , data . length ) ; for ( let i = 0 ; i < data . length ; i ++ ) { const value = data [ i ] ; buffer . setValueAtIndex ( i , value ) ; } const prevLabelHandler = ( Opcode as any ) . convertToLabelHandler ; Opcode . setConvertToLabelHandler ( undefined as any ) ; const end = addr + size ; const list = new Array < { address : number ; instruction : string ; } > ( ) ; while ( addr < end ) { const address = addr & 0xFFFF ; const opcode = Opcode . getOpcodeAt ( buffer , address ) ; const opCodeDescription = opcode . disassemble ( ) ; const instruction = Format . formatDisassembly ( undefined , false , 0 , 0 , 0 , 0 , address , opcode . length , opCodeDescription . mnemonic ) ; list . push ( { address , instruction } ) ; addr += opcode . length ; } Opcode . setConvertToLabelHandler ( prevLabelHandler ) ; return list ; } param addr param data returns public static getInstruction ( addr , data ) { const disArray = this . getLines ( addr , data , 1 ) ; return disArray [ 0 ] . instruction ; } /**
     * Creates the singleton.
     */ public static createDisassemblyInstance ( ) { Disassembly = new DisassemblyClass ( ) ; Disassembly . funcAssignLabels = ( addr ) => { return 'L' + Utility . getHexString ( addr , 4 ) ; } ; Opcodes [ 0xCF ] = new Opcode ( 0xCF , "RST %s" ) ; if ( Settings . launch . disassemblerArgs . esxdosRst ) { Opcodes [ 0xCF ] . appendToOpcode ( ",#n" ) ; } } returns public static getAbsFilePath ( ) { if ( ! Settings . launch ) return undefined as any ; const relPath = Utility . getRelTmpFilePath ( TmpDasmFileName ) ; const absPath = Utility . getAbsFilePath ( relPath ) ; return absPath ; } protected addrLineMap = new Map < number , number > ( ) ; protected lineAddrArray = new Array < number | undefined > ( ) ; /**
     * Initializes the memory with the data at the given addresses.
     * Additionally puts the addresses in the address queue.
     */ public initWithCodeAdresses ( addresses , mem ) { this . initLabels ( ) ; this . addrLineMap = new Map < number , number > ( ) ; this . lineAddrArray = new Array < number | undefined > ( ) ; this . memory . clrAssignedAttributesAt ( 0x0000 , 0x10000 ) ; for ( const block of mem ) this . setMemory ( block . address & 0xFFFF , block . data ) ; this . setAddressQueue ( addresses . map ( addr => addr & 0xFFFF ) ) ; } /**
     * Disassembles the memory.
     * Additionally keeps the address/line locations.
     */ public disassemble ( ) { this . disableCommentsInDisassembly = true ; super . disassemble ( ) ; let lineNr = 0 ; this . addrLineMap . clear ( ) ; this . lineAddrArray . length = 0 ; let slots ; if ( Labels . AreLongAddressesUsed ( ) ) slots = Z80Registers . getSlots ( ) ; for ( const line of this . disassembledLines ) { let address = parseInt ( line , 16 ) ; if ( ! isNaN ( address ) ) { address = Z80Registers . createLongAddress ( address , slots ) ; this . addrLineMap . set ( address , lineNr ) ; while ( this . lineAddrArray . length <= lineNr ) this . lineAddrArray . push ( address ) ; } lineNr ++ ; } } param address returns public getLineForAddress ( address ) { return this . addrLineMap . get ( address ) ; } param addresses returns public getLinesForAddresses ( addresses ) { const lines = new Array < number > ( ) ; const map = this . addrLineMap ; if ( addresses . size > map . size ) { map . forEach ( ( value , key ) => { if ( addresses . has ( key ) ) lines . push ( value ) ; } ) ; } else { for ( const address of addresses ) { const line = map . get ( address ) ; if ( line ) lines . push ( line ) ; } } return lines ; } param lineNr returns public getAddressForLine ( lineNr ) { if ( lineNr >= this . lineAddrArray . length ) return - 1 ; return this . lineAddrArray [ lineNr ] ; } } export let Disassembly ;