mirror of
https://github.com/cc65/cc65.git
synced 2024-08-17 03:29:15 +00:00
297 lines
5.5 KiB
ArmAsm
297 lines
5.5 KiB
ArmAsm
;
|
|
; Ullrich von Bassewitz, 07.08.1998
|
|
;
|
|
; unsigned DbgDisAsm (char* buf, unsigned addr);
|
|
; unsigned DbgDisAsm (unsigned addr);
|
|
;
|
|
;
|
|
; Part of this code is taken from the Plus/4 machine language monitor
|
|
; (TEDMon).
|
|
;
|
|
|
|
.import popax
|
|
.import __hextab, OffsetTab, AdrFlagTab
|
|
.import SymbolTab1, SymbolTab2, MnemoTab1, MnemoTab2
|
|
|
|
|
|
|
|
; -------------------------------------------------------------------------
|
|
; Equates for better readability
|
|
|
|
.importzp sreg, tmp1, tmp2, tmp3, tmp4, ptr1, ptr2, ptr3
|
|
|
|
BufIndex = tmp1 ; Index into output buffer
|
|
OperandLen = tmp2 ; Length of operand
|
|
BufLen = tmp3 ; Length of output buffer
|
|
AdrFlagBuf = tmp4 ; Flag for addressing mode
|
|
YSave = sreg ; Temp storage
|
|
XSave = sreg+1 ; Dito
|
|
BufPtr = ptr1 ; Pointer to output buffer
|
|
MemPtr = ptr2 ; Pointer to memory to disassemble
|
|
MnemoBuf = ptr3 ; Buffer for decoding mnemonic
|
|
|
|
|
|
; -------------------------------------------------------------------------
|
|
; Main entries
|
|
|
|
.export _DbgDisAsm, _DbgDisAsmLen
|
|
|
|
.proc _DbgDisAsm
|
|
sta BufLen ; Save the buffer length
|
|
jsr popax ; Get the buffer pointer
|
|
sta BufPtr
|
|
stx BufPtr+1
|
|
jsr popax ; Get the address
|
|
sta MemPtr
|
|
stx MemPtr+1
|
|
lda #0
|
|
sta BufIndex ; Initialize index into buffer
|
|
jsr DisAssLine ; Disassemble one line into the buffer
|
|
|
|
lda BufLen ; Get requested length
|
|
sec
|
|
sbc BufIndex
|
|
beq L2
|
|
tax ; Count into X
|
|
ldy BufIndex
|
|
lda #$20 ; Get a space
|
|
L1: sta (BufPtr),y
|
|
iny
|
|
dex
|
|
bne L1
|
|
L2: lda #0 ; Add C string terminator
|
|
sta (BufPtr),y
|
|
beq disassret
|
|
|
|
.endproc
|
|
|
|
|
|
_DbgDisAsmLen:
|
|
sta MemPtr ; Save address
|
|
stx MemPtr+1
|
|
ldy #$00
|
|
lda (MemPtr),y ; Get the opcode from memory...
|
|
jsr AnalyzeOPCode ; ...and analyze it
|
|
disassret:
|
|
ldx OperandLen ; Get length of operand
|
|
inx ; Adjust for opcode byte
|
|
txa
|
|
ldx #$00 ; Clear high byte
|
|
rts
|
|
|
|
; -------------------------------------------------------------------------
|
|
; Helper functions
|
|
|
|
|
|
Put3Spaces:
|
|
jsr PutSpace
|
|
Put2Spaces:
|
|
jsr PutSpace
|
|
PutSpace:
|
|
lda #$20
|
|
PutChar:
|
|
sty YSave ; Save Y
|
|
ldy BufIndex ; Get current line pointer
|
|
cpy BufLen ; Be sure not to overflow the buffer
|
|
bcs PC9
|
|
sta (BufPtr),y ; store character
|
|
iny ; bump index
|
|
sty BufIndex
|
|
PC9: ldy YSave ; get old value
|
|
rts
|
|
|
|
; Print the 16 bit hex value in X/Y
|
|
|
|
PutHex16:
|
|
txa
|
|
jsr PutHex8
|
|
tya
|
|
|
|
; Print 8 bit value in A, save X and Y
|
|
|
|
PutHex8:
|
|
stx XSave
|
|
sty YSave
|
|
ldy BufIndex
|
|
pha
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
tax
|
|
lda __hextab,x
|
|
sta (BufPtr),y
|
|
iny
|
|
pla
|
|
and #$0F
|
|
tax
|
|
lda __hextab,x
|
|
sta (BufPtr),y
|
|
iny
|
|
sty BufIndex
|
|
ldy YSave
|
|
ldx XSave
|
|
rts
|
|
|
|
; -------------------------------------------------------------------------
|
|
; Disassemble one line
|
|
|
|
DisAssLine:
|
|
ldy MemPtr
|
|
ldx MemPtr+1
|
|
jsr PutHex16 ; Print the address
|
|
jsr Put2Spaces ; Add some space
|
|
ldy #$00
|
|
lda (MemPtr),y ; Get the opcode from memory...
|
|
jsr AnalyzeOPCode ; ...and analyze it
|
|
pha ; Save mnemonic
|
|
ldx OperandLen ; Number of bytes
|
|
|
|
; Print the bytes that make up the instruction
|
|
|
|
inx
|
|
L2083: dex
|
|
bpl L208C ; Print the instruction bytes
|
|
jsr Put3Spaces ; If none left, print spaces instead
|
|
jmp L2094
|
|
L208C: lda (MemPtr),y ; Get a byte from memory
|
|
jsr PutHex8 ; ...and print it
|
|
jsr PutSpace ; Add some space
|
|
|
|
L2094: iny ; Next one...
|
|
cpy #$03 ; Maximum is three
|
|
bcc L2083 ;
|
|
|
|
jsr Put2Spaces ; Add some space after bytes
|
|
|
|
; Print the assembler mnemonic
|
|
|
|
pla ; Get mnemonic code
|
|
ldx #$03
|
|
jsr PutMnemo ; Print the mnemonic
|
|
ldx #$06
|
|
|
|
; Print the operand
|
|
|
|
L20A4: cpx #$03
|
|
bne L20BA
|
|
ldy OperandLen
|
|
beq L20BA
|
|
|
|
L20AC: lda AdrFlagBuf
|
|
cmp #$E8 ; Branch?
|
|
lda (MemPtr),y ; Get branch offset
|
|
bcs GetBranchAdr ; If branch: Calculate address
|
|
jsr PutHex8 ; Otherwise print 8bit value
|
|
dey
|
|
bne L20AC
|
|
|
|
L20BA: asl AdrFlagBuf
|
|
bcc L20CC
|
|
lda SymbolTab1-1,x
|
|
jsr PutChar
|
|
lda SymbolTab2-1,x
|
|
beq L20CC
|
|
jsr PutChar
|
|
|
|
L20CC: dex
|
|
bne L20A4
|
|
rts
|
|
|
|
; If the instruction is a branch, calculate the absolute address of the
|
|
; branch target and print it.
|
|
|
|
GetBranchAdr:
|
|
jsr L20DD
|
|
clc
|
|
adc #$01
|
|
bne L20D9
|
|
inx ; Bump high byte
|
|
L20D9: tay
|
|
jmp PutHex16 ; Output address
|
|
|
|
L20DD: ldx MemPtr+1
|
|
tay
|
|
bpl L20E3
|
|
dex
|
|
L20E3: adc MemPtr
|
|
bcc L20E8
|
|
inx ; Bump high byte
|
|
L20E8: rts
|
|
|
|
; -------------------------------------------------------------------------
|
|
; Subroutine to analyze an opcode byte in A. Will return a byte that
|
|
; encodes the mnemonic, and will set the number of bytes needed for this
|
|
; instruction in OperandLen
|
|
|
|
AnalyzeOPCode:
|
|
tay
|
|
lsr a
|
|
bcc L20F8
|
|
lsr a
|
|
bcs L2107
|
|
cmp #$22
|
|
beq L2107
|
|
and #$07
|
|
ora #$80
|
|
L20F8: lsr a
|
|
tax
|
|
lda OffsetTab,x
|
|
bcs L2103
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
L2103: and #$0F
|
|
bne L210B
|
|
L2107: ldy #$80
|
|
lda #$00
|
|
L210B: tax
|
|
lda AdrFlagTab,x
|
|
sta AdrFlagBuf
|
|
and #$03
|
|
sta OperandLen
|
|
tya
|
|
and #$8F
|
|
tax
|
|
tya
|
|
ldy #$03
|
|
cpx #$8A
|
|
beq L212B
|
|
|
|
L2120: lsr a
|
|
bcc L212B
|
|
lsr a
|
|
L2124: lsr a
|
|
ora #$20
|
|
dey
|
|
bne L2124
|
|
iny
|
|
L212B: dey
|
|
bne L2120
|
|
rts
|
|
|
|
; -------------------------------------------------------------------------
|
|
; Print the mnemonic with code in A (that code was returned by
|
|
; AnalyzeOpcode).
|
|
|
|
PutMnemo:
|
|
tay
|
|
lda MnemoTab1,y
|
|
sta MnemoBuf
|
|
lda MnemoTab2,y
|
|
sta MnemoBuf+1
|
|
L213A: lda #$00
|
|
ldy #$05 ; 3*5 bits in two bytes
|
|
L213E: asl MnemoBuf+1
|
|
rol MnemoBuf
|
|
rol a
|
|
dey
|
|
bne L213E
|
|
adc #$3F
|
|
jsr PutChar
|
|
dex
|
|
bne L213A
|
|
jmp PutSpace
|
|
|