wok view runcom/stuff/debug.S @ rev 22764

updated florence again (0.5.4 -> 0.6.3)
author Hans-G?nter Theisgen
date Fri Jan 24 17:42:38 2020 +0100 (2020-01-24)
parents 289a2f495cd6
children
line source
1 // Usage:
2 //
3 // f DX:CX load one CHS sector to 0000:7C00
4 // t trace one step
5 // g <address> go to adrs
6 // d <address> display 16 bytes, CR for next 16 bytes...
7 // e <address> <words>... enter memory byte/word/dword
8 // m <segment> self move
9 // + <segment> default segment offset
10 //
11 // Example:
12 // m 0FC0 move debugger to 0FC0:0000 0FC0:01FF
13 // f 1 read floppy boot sector to 0000:7C00
14 // f 80:1 read hard disk master boot sector to 0000:7C00
15 // g 7C0E ...
17 #define REGS32 28 bytes display FS, GS and 32 bits datas for AX..DI
18 #define ADJESDI 16 bytes add segment overflow support for e and d
19 #define ASCIIDUMP 20 bytes display hexa and ascii datas
20 #define INPUTBUFFER 3 bytes overload init code with a 32+ bytes input buffer
22 .macro pushib val
23 .byte 0x6A, \val-_start
24 .endm
26 #ifdef REGS32
27 #define SEGREGSZ 10
28 #define REGSZ 32
29 #define USER_SP REGSZ+SEGREGSZ-28(%bp)
30 #define FIXSP 14
31 #else
32 #define SEGREGSZ 6
33 #define REGSZ 16
34 #define USER_SP REGSZ+SEGREGSZ-14(%bp)
35 #define FIXSP 10
36 #endif
37 #define USER_FLAGS REGSZ+SEGREGSZ+4(%bp)
38 #define USER_FLAGS_HIGH REGSZ+SEGREGSZ+5(%bp)
39 #define USER_IP REGSZ+SEGREGSZ(%bp)
40 #define USER_CS REGSZ+SEGREGSZ+2(%bp)
41 #define USER_CSIP REGSZ+SEGREGSZ(%bp)
43 #ifdef INPUTBUFFER
44 //#define ABS(x) (x-(setvectors-_start))
45 #define ABS(x) (x-32)
46 #else
47 #define ABS(x) (x)
48 #endif
49 .macro initcode
50 movw $0x0FC0, %di # move (and jump) to 0FC0:0000
51 subw $_startz-_start, USER_IP
52 movw USER_IP, %ax
53 shrw $4, %ax # _start MUST be aligned on paragraph
54 addw USER_CS, %ax # normalize %cs to have _start=0
55 movw %ax, %ds
56 .endm
58 .text
59 .code16
60 .org 0
62 .globl _start
63 _start:
64 pushf
65 pushw %cs
66 stc
67 call init # the start code will be overwritten by the input buffer
68 _startz:
70 #ifdef INPUTBUFFER
71 isinit:
72 initcode
73 addw $FIXSP, USER_SP # adjust SP with [FLAGS CS IP DS ES [FS GS]] size
74 pushib setvectors
75 jmp moveself
76 #endif
78 setvectors:
79 xorw %si, %si # set interrupt vectors in 0 segment
80 movw %si, %ds
81 movb $0x7D, %cl # skip nmi
82 hooklp: # interrupts: 0=div0 1=step 2=nmi 3=brk 4=ov 5=bound 6=invalid
83 pushw %cs
84 pushib ABS(dbgstart) # set %cs:dbgstart
85 popl (%si) # to interrupt vector
86 skiphook:
87 lodsl # %si += 4
88 shrb $1,%cl
89 jnc skiphook
90 jnz hooklp # note %cx will be cleared: SP will be untouched
91 decw (3-7)*4(%si) # update int3 vector
92 jmp dbgstartz # registers are already pushed by startup code
94 regs:
95 .ascii "ss"
96 .ascii "di"
97 .ascii "si"
98 .ascii "bp"
99 .ascii "sp"
100 .ascii "bx"
101 .ascii "dx"
102 .ascii "cx"
103 .ascii "ax"
104 #ifdef REGS32
105 .ascii "gs"
106 .ascii "fs"
107 #endif
108 .ascii "es"
109 .ascii "ds"
110 .ascii "ip"
111 .ascii "cs"
112 # Bit Label Desciption
113 # ---------------------------
114 # 0 CF Carry flag
115 # 2 PF Parity flag
116 # 4 AF Auxiliary carry flag
117 # 6 ZF Zero flag
118 # 7 SF Sign flag
119 # 8 TF Trap flag
120 # 9 IF Interrupt enable flag
121 # 10 DF Direction flag
122 # 11 OF Overflow flag
123 #ifdef REGS32
124 .ascii "odi|sz|a|p|c" # flags bits
125 #else
126 .ascii "oditsz?a?p c=" # flags bits
127 #endif
128 # 12-13 IOPL I/O Priviledge level
129 # 14 NT Nested task flag
130 # 16 RF Resume flag
131 # 17 VM Virtual 8086 mode flag
132 # 18 AC Alignment check flag (486+)
133 # 19 VIF Virutal interrupt flag
134 # 20 VIP Virtual interrupt pending flag
135 # 21 ID ID flag
137 #ifdef INPUTBUFFER
138 ismove:
139 pushw %ax
140 moveself:
141 popw %si
142 #else
143 isinit:
144 initcode
145 ismove:
146 xorw %si, %si
147 #endif
148 movw %di, %es # move code to %di:0
149 pushw %di
150 #ifdef INPUTBUFFER
151 xorw %di, %di # and jmp into (%di:setvectors) with retf
152 #else
153 movw $setvectors, %di # and jmp into (%di:setvectors) with retf
154 movw %di, %si
155 #endif
156 movw $_end-setvectors, %cx
157 pushw %di
158 rep movsb
159 retf
161 int3:
162 .byte 0x68 # push $0x086A OV UP DI NT PL ZR - NA - PO - NC
163 # interrupt entry point: the registers [FLAGS CS IP] are already pushed
164 dbgstart:
165 .byte 0x6A, 0x08 # push $0x08 NV UP DI NT PL NZ - NA - PO - NC
166 popf
167 init:
168 pushw %ds
169 pushw %es
170 #ifdef REGS32
171 pushw %fs
172 pushw %gs
173 pushal # [FLAGS CS IP DS ES FS GS] EAX ECX EDX EBX ESP EBP ESI EDI [SS]
174 #else
175 pushaw # [FLAGS CS IP DS ES] AX CX DX BX SP BP SI DI [SS]
176 #endif
177 pushw %ss
178 movw %sp, %bp
179 #ifndef INPUTBUFFER
180 pushf
181 addw $FIXSP, USER_SP # adjust SP with [FLAGS CS IP DS ES [FS GS]] size
182 popf
183 #endif
184 jc isinit
185 jnz notint3
186 decw USER_IP
187 lesw USER_CSIP, %di
188 #define OPCODE_BRK 0xCC
189 .byte 0xB0 # movb $IM, %al
190 break:
191 .byte 0xCC
192 stosb
193 notint3:
194 #ifdef INPUTBUFFER
195 addw $FIXSP, USER_SP # adjust SP with [FLAGS CS IP DS ES [FS GS]] size
196 #endif
197 dbgstartz:
198 dbgregslp:
199 pushw %cs
200 popw %ds
201 movw $ABS(regs), %si
202 #ifdef REGS32
203 subw %si, %bp
204 movw $15, %cx
205 #else
206 movw $13, %cx
207 #endif
208 regslp:
209 call putreg # display register name and value
210 loop regslp
211 #ifdef REGS32
212 movw (%bp,%si), %dx # get flags
213 #else
214 movw USER_FLAGS, %dx
215 pushw %si
216 stc # add trailing =
217 #endif
218 movb $13, %cl
219 rcrw %cl, %dx
220 nextbit:
221 lodsb
222 shlw $1, %dx
223 #ifdef REGS32
224 jnc skipflag
225 cmpb $'|', %al # remove system flags
226 je skipflag
227 call dbgputc
228 skipflag:
229 #else
230 call dbgputcbit # display active flags bits
231 #endif
232 loop nextbit
233 #ifdef REGS32
234 movw %sp, %bp
235 #else
236 popw %si
237 movb $8, %cl
238 stacklp:
239 lodsw # si += 2
240 call putr16 # display flags and the beginning of the stack
241 loop stacklp
242 #endif
243 call getline
244 lodsb
245 xchgw %ax, %di
246 call getval
247 .byte 0x81, 0xC3 # addw $0, %bx
248 offset_value:
249 .word 0
250 movw %bx, %es
251 xchgw %ax, %di
252 subb $'m', %al
253 je ismove
254 subb $'+'-'m', %al
255 jne not_offset
256 movw %di, ABS(offset_value)
257 not_offset:
258 orb $1, USER_FLAGS_HIGH # set TF
259 subb $'t'-'+', %al
260 je done
261 subb $'d'-'t', %al
262 xchgw %ax, %cx
263 jcxz dump # 'd' ?
264 loop noenter # 'e' ?
265 nextval:
266 call getval
267 jcxz dbgregslp
268 xchgb %dl, %dh
269 mextmsb:
270 stosb
271 xchgw %ax, %dx
272 xchgb %al, %dh
273 #ifdef ADJESDI
274 call adjustESDI
275 #endif
276 decw %cx
277 loopne mextmsb
278 jmp nextval
279 noenter:
280 loop not_floppy_load # f DX:CX ?
281 movw %es, %dx
282 movw %cx, %es
283 movw %di, %cx
284 movw $0x0201, %ax
285 movw $0x7C00, %bx
286 pushw %bx
287 int $0x13
288 popw %di
289 godbgregslpifc:
290 jc dbgregslp
291 dump:
292 movw %es, %ax
293 call putax
294 movw %di, %ax
295 call putax
296 movw $16, %cx
297 dhex:
298 movb %es:(%di), %ah
299 #ifdef ASCIIDUMP
300 movb %ah, (%si)
301 incw %si
302 #endif
303 #ifdef ADJESDI
304 call incESDI
305 #else
306 incw %di
307 #endif
308 #ifdef REGS32
309 movb $0x30, %dh # the data has 2 digits
310 #else
311 movb $0x01, %dh # the data has 2 digits
312 #endif
313 call putx
314 loop dhex
315 #ifdef ASCIIDUMP
316 movb $16, %cl
317 subw %cx, %si
318 dascii:
319 lodsb
320 cmpb $0x7F, %al
321 jnc skipascii
322 cmpb $0x20, %al
323 cmc
324 skipascii:
325 call dbgputcbit
326 loop dascii
327 #endif
328 call dbgputcr
329 int $0x16
330 cmpb $13, %al
331 je dump
332 notdump:
333 not_floppy_load:
334 stc
335 loop godbgregslpifc # g ?
336 isgo:
337 andb $0xfe, USER_FLAGS_HIGH # clear TF
338 xchgw %ax, %cx
339 jcxz done
340 setbreak:
341 movb $OPCODE_BRK, %al
342 xchgb %al, %es:(%di)
343 movb %al, ABS(break)
344 done:
345 popw %ax # %ss
346 #ifdef REGS32
347 popal
348 popw %gs
349 popw %fs
350 #else
351 popaw
352 #endif
353 popw %es
354 popw %ds
355 iret
357 #ifdef ADJESDI
358 adjustESDI:
359 decw %di
360 incESDI:
361 incw %di
362 jnz esok
363 pushw %es
364 addb $0x10,-3(%bp)
365 popw %es
366 esok:
367 ret
368 #endif
370 putreg:
371 call dbgput2c
372 movb $'=', %al
373 call dbgputc
374 putr16:
375 #ifdef REGS32
376 movl -2(%bp,%si), %eax
377 movw $0x3FC0, %dx # check bits 7..14
378 shrw %cl, %dx
379 putax:
380 movb $0xF0, %dh # the data has 4 digits
381 jnc putx # 16 bits register ?
382 incw %bp # a 32 bits register, not 16 bits
383 incw %bp
384 movb $0xFF, %dh # the data has 8 digits
385 jmp putx
386 putxlp:
387 #else
388 # movw _start-ABS(regs)-2(%bp,%si), %ax
389 .byte 0x8b, 0x42, _start-ABS(regs)-2
390 putax:
391 movb $0x07, %dh # the data has 4 digits
392 putx:
393 putxlp:
394 rolw $4, %ax
395 #endif
396 pushw %ax
397 andb $0xf, %al
398 addb $0x90, %al
399 daa
400 adcb $0x40, %al
401 daa
402 call dbgputc
403 popw %ax
404 #ifdef REGS32
405 putx:
406 roll $4, %eax
407 #endif
408 shrb $1, %dh
409 jc putxlp
410 #ifdef REGS32
411 jnz putx
412 #endif
413 dbgputcbit:
414 jc dbgputc
415 mov $0x20, %al
416 dbgputc:
417 movw $7, %bx
418 mov $0xE, %ah
419 int $0x10
420 xchgw %ax, %bx
421 # clc # for putax
422 ret
424 # get value in DX:AX, BX is segment CX is digits count.
425 getval:
426 xorw %ax, %ax
427 xorw %bx, %bx
428 xorw %cx, %cx
429 getvalz:
430 xchgw %ax, %bx
431 cwd
432 decw %cx
433 isx:
434 shll $4, %edx
435 orb %al, %dl
436 incw %cx
437 gotspc:
438 getvallp:
439 lodsb
440 cmpb $0x20, %al # heat heading spaces
441 jne notspc
442 jcxz gotspc
443 notspc:
444 subb $'0', %al
445 cmpb $10, %al # in 0..9 ?
446 jb isx
447 subb $'a'-'0'-10, %al
448 cmpb $16, %al # in a..f ?
449 jb isx
450 cmpb $':'-'a'+10, %al
451 pushl %edx
452 popw %ax
453 popw %dx
454 je getvalz # store segment in %bx
455 pushw %dx
456 shlw $12, %dx
457 orw %dx, %bx
458 popw %dx
459 ret
461 getline:
462 call dbgputcr
463 getlinebs:
464 cmpw $ABS(buffer), %si
465 je getc
466 decw %si
467 getlinelp:
468 call dbgputc
469 getc:
470 int $0x16
471 cmpb $8, %al
472 je getlinebs
473 orb $0x20, %al
474 movb %al, (%si)
475 inc %si
476 cmpb $0x2D, %al
477 jne getlinelp
478 dbgputcr:
479 movw $ABS(crlf), %si
480 dbgput2c:
481 call dbgput1c
482 dbgput1c:
483 lodsb
484 jmp dbgputc
486 crlf:
487 .byte 13,10
488 _end:
489 buffer:
491 .org 510
492 .byte 0x55, 0xAA