wok view runcom/stuff/debug8086.S @ rev 13597

Up get-flash-plugin (1.4)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Nov 09 13:13:08 2012 +0100 (2012-11-09)
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 ADJESDI 16 bytes add segment overflow support for e and d
18 #define ASCIIDUMP 20 bytes display hexa and ascii datas
19 #define INPUTBUFFER 2 bytes overload init code with a 32+ bytes input buffer
20 //#define CPU186 -26 bytes 80186+ CPU
22 .macro pusham
23 pushw %ax
24 pushw %cx
25 pushw %dx
26 pushw %bx
27 movw %sp, %bx
28 leaw 14(%bx), %bx # adjust SP with [FLAGS CS IP AX CX DX BX] size
29 pushw %bx # %sp
30 pushw %bp
31 pushw %si
32 pushw %di
33 .endm
35 .macro popam
36 popw %di
37 popw %si
38 popw %bp
39 popw %ax # %sp
40 popw %bx
41 popw %dx
42 popw %cx
43 popw %ax
44 .endm
46 #ifdef INPUTBUFFER
47 //#define ABS(x) (x-(setvectors-_start))
48 #define ABS(x) (x-30)
49 #else
50 #define ABS(x) (x)
51 #endif
53 #define SEGREGSZ 6
54 #define REGSZ 16
55 #define USER_SP REGSZ+SEGREGSZ-10(%bp)
56 #define USER_FLAGS REGSZ+SEGREGSZ+4(%bp)
57 #define USER_FLAGS_HIGH REGSZ+SEGREGSZ+5(%bp)
58 #define USER_IP REGSZ+SEGREGSZ(%bp)
59 #define USER_CS REGSZ+SEGREGSZ+2(%bp)
60 #define USER_CSIP REGSZ+SEGREGSZ(%bp)
62 .macro initcode
63 movw $0x0FC0, %di # move (and jump) to 0FC0:0000
64 subw $_startz-_start, USER_IP
65 movw USER_IP, %ax
66 #ifdef CPU186
67 cld # ensure movsb will work
68 shrw $4, %ax # _start MUST be aligned on paragraph
69 #else
70 movb $4, %cl
71 shrw %cl, %ax # _start MUST be aligned on paragraph
72 #endif
73 addw USER_CS, %ax # normalize %cs to have _start=0
74 movw %ax, %ds
75 .endm
76 .text
77 .code16
78 #ifdef CPU186
79 .arch i186
80 #else
81 .arch i8086
82 #endif
83 .org 0
85 .globl _start
86 _start:
87 pushf
88 pushw %cs
89 stc
90 call init # the start code will be overwritten by the input buffer
91 _startz:
93 #ifdef INPUTBUFFER
94 isinit:
95 initcode
96 movw $setvectors, %si
97 jmp moveself
98 #endif
100 setvectors:
101 xorw %si, %si # set interrupt vectors in 0 segment
102 movw %si, %ds
103 movb $0xF9, %ch # skip nmi
104 hooklp: # interrupts: 0=div0 1=step 2=nmi 3=brk 4=ov 5=bound 6=invalid
105 movw $ABS(dbgstart), (%si) # set %cs:dbgstart
106 lodsw # %si += 2
107 movw %cs, (%si) # to interrupt vector
108 skiphook:
109 lodsw # %si += 2
110 shrb $1,%ch
111 jnc skiphook
112 jnz hooklp # note %cx will be cleared: SP will be untouched
113 #ifdef CPU186
114 decw (3-7)*4(%si) # update int3 vector
115 #else
116 movb $ABS(int3), (3-7)*4(%si) # update int3 vector
117 #endif
118 jmp dbgstartz # registers are already pushed by startup code
120 regs:
121 .ascii "ss"
122 .ascii "es"
123 .ascii "ds"
124 .ascii "di"
125 .ascii "si"
126 .ascii "bp"
127 .ascii "sp"
128 .ascii "bx"
129 .ascii "dx"
130 .ascii "cx"
131 .ascii "ax"
132 .ascii "ip"
133 .ascii "cs"
134 # Bit Label Desciption
135 # ---------------------------
136 # 0 CF Carry flag
137 # 2 PF Parity flag
138 # 4 AF Auxiliary carry flag
139 # 6 ZF Zero flag
140 # 7 SF Sign flag
141 # 8 TF Trap flag
142 # 9 IF Interrupt enable flag
143 # 10 DF Direction flag
144 # 11 OF Overflow flag
145 .ascii "oditsz?a?p c=" # flags bits
147 int3:
148 #ifdef CPU186
149 .byte 0x68 # push $0x086A OV UP DI NT PL ZR - NA - PO - NC
150 # interrupt entry point: the registers [FLAGS CS IP] are already pushed
151 dbgstart:
152 .byte 0x6A, 0x08 # push $0x08 NV UP DI NT PL NZ - NA - PO - NC
153 popf
154 init:
155 pushaw # [FLAGS CS IP] AX CX DX BX SP BP SI DI [DS ES SS]
156 #else
157 stc
158 .byte 0x73 # jnc
159 # interrupt entry point: the registers [FLAGS CS IP] are already pushed
160 dbgstart:
161 clc
162 pushw %ax
163 sbbw %ax,%ax # copy CF to SF
164 clc
165 popw %ax
166 init:
167 cld # ensure movsb will work
168 pusham # [FLAGS CS IP] AX CX DX BX SP BP SI DI [DS ES SS]
169 #endif
170 pushw %ds
171 pushw %es
172 pushw %ss
173 movw %sp, %bp
174 #ifdef CPU186
175 pushf
176 addw $6, USER_SP # adjust SP with [FLAGS CS IP] size
177 popf
178 #endif
179 jc isinit
180 jns notint3
181 decw USER_IP
182 lesw USER_CSIP, %di
183 #define OPCODE_BRK 0xCC
184 .byte 0xB0 # movb $IM, %al
185 break:
186 .byte 0xCC
187 stosb
188 notint3:
189 dbgstartz:
190 dbgregslp:
191 call getcmd
192 .byte 0x81, 0xC3 # addw $0, %bx
193 offset_value:
194 .word 0
195 movw %bx, %es
196 xchgw %ax, %di
197 subb $'m', %al
198 jne isinotmove
199 #ifdef INPUTBUFFER
200 ismove:
201 xchgw %ax, %si
202 moveself:
203 #else
204 isinit:
205 jmp ismove
206 initcode
207 ismove:
208 #endif
209 movw %di, %es # move code to %di:0
210 pushw %di
211 #ifdef INPUTBUFFER
212 xorw %di, %di # and jmp into (%di:setvectors) with retf
213 #else
214 movw $setvectors, %di # and jmp into (%di:setvectors) with retf
215 movw %di, %si
216 #endif
217 movw $_end-setvectors, %cx
218 pushw %di
219 rep movsb
220 retf
222 isinotmove:
223 subb $'+'-'m', %al
224 jne not_offset
225 movw %di, ABS(offset_value)
226 not_offset:
227 orb $1, USER_FLAGS_HIGH # set TF
228 subb $'t'-'+', %al
229 je done
230 subb $'d'-'t', %al
231 xchgw %ax, %cx
232 jcxz dump # 'd' ?
233 loop noenter # 'e' ?
234 nextval:
235 call getval
236 jcxz dbgregslp
237 xchgb %dl, %dh
238 mextmsb:
239 stosb
240 xchgw %ax, %dx
241 xchgb %al, %dh
242 #ifdef ADJESDI
243 call adjustESDI
244 #endif
245 decw %cx
246 loopne mextmsb
247 jmp nextval
248 noenter:
249 loop not_floppy_load # f DX:CX ?
250 movw %es, %dx
251 movw %cx, %es
252 movw %di, %cx
253 movw $0x0201, %ax
254 movw $0x7C00, %bx
255 pushw %bx
256 int $0x13
257 popw %di
258 godbgregslpifc:
259 jc dbgregslp
260 dump:
261 movw %es, %ax
262 call putax
263 movw %di, %ax
264 call putax
265 movw $16, %cx
266 dhex:
267 movb %es:(%di), %ah
268 #ifdef ASCIIDUMP
269 movb %ah, (%si)
270 incw %si
271 #endif
272 #ifdef ADJESDI
273 call incESDI
274 #else
275 incw %di
276 #endif
277 movb $0x01, %dh # the data has 2 digits
278 call putx
279 loop dhex
280 #ifdef ASCIIDUMP
281 movb $16, %cl
282 subw %cx, %si
283 dascii:
284 lodsb
285 cmpb $0x7F, %al
286 jnc skipascii
287 cmpb $0x20, %al
288 cmc
289 skipascii:
290 call dbgputcbit
291 loop dascii
292 #endif
293 call dbgputcr
294 int $0x16
295 cmpb $13, %al
296 je dump
297 notdump:
298 not_floppy_load:
299 stc
300 loop godbgregslpifc # g ?
301 isgo:
302 andb $0xfe, USER_FLAGS_HIGH # clear TF
303 xchgw %ax, %cx
304 jcxz done
305 setbreak:
306 movb $OPCODE_BRK, %al
307 xchgb %al, %es:(%di)
308 movb %al, ABS(break)
309 done:
310 popw %ax # %ss
311 popw %es
312 popw %ds
313 #ifdef CPU186
314 popaw
315 #else
316 popam
317 #endif
318 iret
320 #ifdef ADJESDI
321 adjustESDI:
322 decw %di
323 incESDI:
324 incw %di
325 jnz esok
326 pushw %es
327 addb $0x10,-3(%bp)
328 popw %es
329 esok:
330 ret
331 #endif
333 putreg:
334 call dbgput2c
335 movb $'=', %al
336 call dbgputc
337 putr16:
338 # movw _start-ABS(regs)-2(%bp,%si), %ax
339 .byte 0x8b, 0x42, _start-ABS(regs)-2
340 putax:
341 movb $0x07, %dh # the data has 4 digits
342 putx:
343 putxlp:
344 #ifdef CPU186
345 rolw $4, %ax
346 #else
347 pushw %cx
348 movb $4, %cl
349 rolw %cl, %ax
350 popw %cx
351 #endif
352 pushw %ax
353 andb $0xf, %al
354 addb $0x90, %al
355 daa
356 adcb $0x40, %al
357 daa
358 call dbgputc
359 popw %ax
360 shrb $1, %dh
361 jc putxlp
362 dbgputcbit:
363 jc dbgputc
364 mov $0x20, %al
365 dbgputc:
366 movw $7, %bx
367 mov $0xE, %ah
368 int $0x10
369 xchgw %ax, %bx
370 ret
372 getline:
373 movw $ABS(regs), %si
374 movw $13, %cx
375 regslp:
376 call putreg # display register name and value
377 loop regslp
378 movw USER_FLAGS, %dx
379 pushw %si
380 movb $13, %cl
381 stc # add trailing =
382 rcrw %cl, %dx
383 nextbit:
384 lodsb
385 shlw $1, %dx
386 call dbgputcbit # display active flags bits
387 loop nextbit
388 popw %si
389 movb $8, %cl
390 stacklp:
391 lodsw # si += 2
392 call putr16 # display flags and the beginning of the stack
393 loop stacklp
394 call dbgputcr
395 getlinebs:
396 cmpw $ABS(buffer), %si
397 je getc
398 decw %si
399 getlinelp:
400 call dbgputc
401 getc:
402 int $0x16
403 cmpb $8, %al
404 je getlinebs
405 orb $0x20, %al
406 movb %al, (%si)
407 inc %si
408 cmpb $0x2D, %al
409 jne getlinelp
410 dbgputcr:
411 movw $ABS(crlf), %si
412 dbgput2c:
413 call dbgput1c
414 dbgput1c:
415 lodsb
416 jmp dbgputc
418 getcmd:
419 pushw %cs
420 popw %ds
421 call getline
422 lodsb
423 xchgw %ax, %di
424 # get value in DX:AX, BX is segment CX is digits count.
425 getval:
426 xorw %bx, %bx
427 xorw %cx, %cx
428 getvalz:
429 pushw %bx # save segment
430 xorw %bx, %bx
431 mul %bx # clear %dx:%ax
432 decw %cx
433 isx:
434 incw %cx
435 orb $0xE0, %dh
436 getvalbit:
437 shlw $1, %bx
438 rclw $1, %dx
439 jc getvalbit
440 orb %al, %bl
441 gotspc:
442 lodsb
443 cmpb $0x20, %al # space ?
444 jne notspc
445 jcxz gotspc
446 notspc:
447 sub $'0', %al
448 cmpb $10, %al # in 0..9 ?
449 jb isx
450 sub $'a'-'0'-10, %al
451 cmpb $16, %al # in a..f ?
452 jb isx
453 cmpb $':'-'a'+10, %al
454 popw %ax
455 je getvalz # store segment in %bx
456 xchgw %ax, %bx
457 pushw %dx
458 #ifdef CPU186
459 shlw $12, %dx
460 #else
461 pushw %cx
462 movb $12, %cl
463 shlw %cl, %dx
464 popw %cx
465 #endif
466 addw %dx, %bx
467 popw %dx
468 ret
470 crlf:
471 .byte 13,10
472 _end:
473 buffer:
475 .org 510
476 .byte 0x55, 0xAA