]> git.sur5r.net Git - cc65/blob - libsrc/dbg/dbgdasm.s
Fixed _textcolor definition.
[cc65] / libsrc / dbg / dbgdasm.s
1 ;
2 ; Ullrich von Bassewitz, 07.08.1998
3 ;
4 ; unsigned DbgDisAsm (char* buf, unsigned addr);
5 ; unsigned DbgDisAsm (unsigned addr);
6 ;
7 ;
8 ; Part of this code is taken from the Plus/4 machine language monitor
9 ; (TEDMon).
10 ;
11
12         .import         popax
13         .import         __hextab, OffsetTab, AdrFlagTab
14         .import         SymbolTab1, SymbolTab2, MnemoTab1, MnemoTab2
15
16
17
18 ; -------------------------------------------------------------------------
19 ; Equates for better readability
20
21         .importzp       sreg, tmp1, tmp2, tmp3, tmp4, ptr1, ptr2, ptr3
22
23 BufIndex        = tmp1          ; Index into output buffer
24 OperandLen      = tmp2          ; Length of operand
25 BufLen          = tmp3          ; Length of output buffer
26 AdrFlagBuf      = tmp4          ; Flag for addressing mode
27 YSave           = sreg          ; Temp storage
28 XSave           = sreg+1        ; Dito
29 BufPtr          = ptr1          ; Pointer to output buffer
30 MemPtr          = ptr2          ; Pointer to memory to disassemble
31 MnemoBuf        = ptr3          ; Buffer for decoding mnemonic
32
33
34 ; -------------------------------------------------------------------------
35 ; Main entries
36
37         .export         _DbgDisAsm, _DbgDisAsmLen
38
39 .proc   _DbgDisAsm
40         sta     BufLen          ; Save the buffer length
41         jsr     popax           ; Get the buffer pointer
42         sta     BufPtr
43         stx     BufPtr+1
44         jsr     popax           ; Get the address
45         sta     MemPtr
46         stx     MemPtr+1
47         lda     #0
48         sta     BufIndex        ; Initialize index into buffer
49         jsr     DisAssLine      ; Disassemble one line into the buffer
50
51         lda     BufLen          ; Get requested length
52         sec
53         sbc     BufIndex
54         beq     L2
55         tax                     ; Count into X
56         ldy     BufIndex
57         lda     #$20            ; Get a space
58 L1:     sta     (BufPtr),y
59         iny
60         dex
61         bne     L1
62 L2:     lda     #0              ; Add C string terminator
63         sta     (BufPtr),y
64         beq     disassret
65
66 .endproc
67
68
69 _DbgDisAsmLen:
70         sta     MemPtr          ; Save address
71         stx     MemPtr+1
72         ldy     #$00
73         lda     (MemPtr),y      ; Get the opcode from memory...
74         jsr     AnalyzeOPCode   ; ...and analyze it
75 disassret:
76         ldx     OperandLen      ; Get length of operand
77         inx                     ; Adjust for opcode byte
78         txa
79         ldx     #$00            ; Clear high byte
80         rts     
81
82 ; -------------------------------------------------------------------------
83 ; Helper functions
84
85
86 Put3Spaces:
87         jsr     PutSpace
88 Put2Spaces:
89         jsr     PutSpace
90 PutSpace:
91         lda     #$20
92 PutChar:
93         sty     YSave           ; Save Y
94         ldy     BufIndex        ; Get current line pointer
95         cpy     BufLen          ; Be sure not to overflow the buffer
96         bcs     PC9
97         sta     (BufPtr),y      ; store character
98         iny                     ; bump index
99         sty     BufIndex
100 PC9:    ldy     YSave           ; get old value
101         rts
102
103 ; Print the 16 bit hex value in X/Y
104
105 PutHex16:
106         txa
107         jsr     PutHex8
108         tya
109
110 ; Print 8 bit value in A, save X and Y
111
112 PutHex8:
113         stx     XSave
114         sty     YSave
115         ldy     BufIndex
116         pha
117         lsr     a
118         lsr     a
119         lsr     a
120         lsr     a
121         tax
122         lda     __hextab,x
123         sta     (BufPtr),y
124         iny
125         pla
126         and     #$0F
127         tax
128         lda     __hextab,x
129         sta     (BufPtr),y
130         iny
131         sty     BufIndex
132         ldy     YSave
133         ldx     XSave
134         rts
135
136 ; -------------------------------------------------------------------------
137 ; Disassemble one line
138
139 DisAssLine:
140         ldy     MemPtr
141         ldx     MemPtr+1
142         jsr     PutHex16                ; Print the address
143         jsr     Put2Spaces              ; Add some space
144         ldy     #$00
145         lda     (MemPtr),y              ; Get the opcode from memory...
146         jsr     AnalyzeOPCode           ; ...and analyze it
147         pha                             ; Save mnemonic
148         ldx     OperandLen              ; Number of bytes
149
150 ; Print the bytes that make up the instruction
151
152         inx
153 L2083:  dex
154         bpl     L208C                   ; Print the instruction bytes
155         jsr     Put3Spaces              ; If none left, print spaces instead
156         jmp     L2094
157 L208C:  lda     (MemPtr),y              ; Get a byte from memory
158         jsr     PutHex8                 ; ...and print it
159         jsr     PutSpace                ; Add some space
160
161 L2094:  iny                             ; Next one...
162         cpy     #$03                    ; Maximum is three
163         bcc     L2083                   ;
164
165         jsr     Put2Spaces              ; Add some space after bytes
166
167 ; Print the assembler mnemonic
168
169         pla                             ; Get mnemonic code
170         ldx     #$03
171         jsr     PutMnemo                ; Print the mnemonic
172         ldx     #$06
173
174 ; Print the operand
175
176 L20A4:  cpx     #$03
177         bne     L20BA
178         ldy     OperandLen
179         beq     L20BA
180
181 L20AC:  lda     AdrFlagBuf
182         cmp     #$E8                    ; Branch?
183         lda     (MemPtr),y              ; Get branch offset
184         bcs     GetBranchAdr            ; If branch: Calculate address
185         jsr     PutHex8                 ; Otherwise print 8bit value
186         dey
187         bne     L20AC
188
189 L20BA:  asl     AdrFlagBuf
190         bcc     L20CC
191         lda     SymbolTab1-1,x
192         jsr     PutChar
193         lda     SymbolTab2-1,x
194         beq     L20CC
195         jsr     PutChar
196
197 L20CC:  dex
198         bne     L20A4
199         rts
200
201 ; If the instruction is a branch, calculate the absolute address of the
202 ; branch target and print it.
203
204 GetBranchAdr:
205         jsr     L20DD
206         clc
207         adc     #$01
208         bne     L20D9
209         inx                             ; Bump high byte
210 L20D9:  tay
211         jmp     PutHex16                ; Output address
212
213 L20DD:  ldx     MemPtr+1
214         tay
215         bpl     L20E3
216         dex
217 L20E3:  adc     MemPtr
218         bcc     L20E8
219         inx                             ; Bump high byte
220 L20E8:  rts
221
222 ; -------------------------------------------------------------------------
223 ; Subroutine to analyze an opcode byte in A. Will return a byte that
224 ; encodes the mnemonic, and will set the number of bytes needed for this
225 ; instruction in OperandLen
226
227 AnalyzeOPCode:
228         tay
229         lsr     a
230         bcc     L20F8
231         lsr     a
232         bcs     L2107
233         cmp     #$22
234         beq     L2107
235         and     #$07
236         ora     #$80
237 L20F8:  lsr     a
238         tax
239         lda     OffsetTab,x
240         bcs     L2103
241         lsr     a
242         lsr     a
243         lsr     a
244         lsr     a
245 L2103:  and     #$0F
246         bne     L210B
247 L2107:  ldy     #$80
248         lda     #$00
249 L210B:  tax
250         lda     AdrFlagTab,x
251         sta     AdrFlagBuf
252         and     #$03
253         sta     OperandLen
254         tya
255         and     #$8F
256         tax
257         tya
258         ldy     #$03
259         cpx     #$8A
260         beq     L212B
261
262 L2120:  lsr     a
263         bcc     L212B
264         lsr     a
265 L2124:  lsr     a
266         ora     #$20
267         dey
268         bne     L2124
269         iny
270 L212B:  dey
271         bne     L2120
272         rts
273
274 ; -------------------------------------------------------------------------
275 ; Print the mnemonic with code in A (that code was returned by
276 ; AnalyzeOpcode).
277
278 PutMnemo:
279         tay
280         lda     MnemoTab1,y
281         sta     MnemoBuf
282         lda     MnemoTab2,y
283         sta     MnemoBuf+1
284 L213A:  lda     #$00
285         ldy     #$05            ; 3*5 bits in two bytes
286 L213E:  asl     MnemoBuf+1
287         rol     MnemoBuf
288         rol     a
289         dey
290         bne     L213E
291         adc     #$3F
292         jsr     PutChar
293         dex
294         bne     L213A
295         jmp     PutSpace
296