diff options
Diffstat (limited to 'v4.0/src/CMD/DEBUG/DEBCOM3.ASM')
| -rw-r--r-- | v4.0/src/CMD/DEBUG/DEBCOM3.ASM | 678 |
1 files changed, 678 insertions, 0 deletions
diff --git a/v4.0/src/CMD/DEBUG/DEBCOM3.ASM b/v4.0/src/CMD/DEBUG/DEBCOM3.ASM new file mode 100644 index 0000000..21e971c --- /dev/null +++ b/v4.0/src/CMD/DEBUG/DEBCOM3.ASM | |||
| @@ -0,0 +1,678 @@ | |||
| 1 | PAGE 80,132 ; | ||
| 2 | TITLE DEBCOM3.ASM - PART3 DEBUGGER COMMANDS | ||
| 3 | ; ROUTINES TO PERFORM DEBUGGER COMMANDS | ||
| 4 | |||
| 5 | IF1 | ||
| 6 | %OUT COMPONENT=DEBUG, MODULE=DEBCOM3 | ||
| 7 | ENDIF | ||
| 8 | .XLIST | ||
| 9 | .XCREF | ||
| 10 | INCLUDE DOSSYM.INC | ||
| 11 | INCLUDE DEBEQU.ASM | ||
| 12 | INCLUDE DPL.ASM | ||
| 13 | .CREF | ||
| 14 | .LIST | ||
| 15 | CODE SEGMENT PUBLIC BYTE | ||
| 16 | CODE ENDS | ||
| 17 | |||
| 18 | CONST SEGMENT PUBLIC BYTE | ||
| 19 | EXTRN USER_PROC_PDB:WORD,RSTACK:WORD,STACK:BYTE | ||
| 20 | EXTRN DSSAVE:WORD,CSSAVE:WORD,IPSAVE:WORD,axSAVE:WORD,dxSAVE:WORD | ||
| 21 | EXTRN SSSAVE:WORD,SPSAVE:WORD,FLSAVE:WORD | ||
| 22 | EXTRN NEXTCS:WORD,NEXTIP:WORD, RSETFLAG:BYTE | ||
| 23 | CONST ENDS | ||
| 24 | |||
| 25 | CSTACK SEGMENT STACK | ||
| 26 | CSTACK ENDS | ||
| 27 | |||
| 28 | DATA SEGMENT PUBLIC BYTE | ||
| 29 | EXTRN BRKCNT:WORD,TCOUNT:WORD,SWITCHAR:BYTE,BPTAB:BYTE | ||
| 30 | EXTRN BP_ERROR:BYTE,COMP_ARG1:WORD,COMP_ARG2:WORD,COMP_ARG3:WORD | ||
| 31 | EXTRN COMP_ARG4:WORD,COMP_ARG5:WORD,COMP_ARG6:WORD,COMP_PTR:BYTE | ||
| 32 | EXTRN ARG_BUF:BYTE,ARG_BUF_PTR:BYTE | ||
| 33 | EXTRN FZTRACE:BYTE, SYNERR_PTR:BYTE | ||
| 34 | EXTRN BEGSEG:WORD | ||
| 35 | IF IBMVER | ||
| 36 | EXTRN OLD_MASK:BYTE | ||
| 37 | ENDIF | ||
| 38 | EXTRN SAVESTATE:BYTE | ||
| 39 | DATA ENDS | ||
| 40 | |||
| 41 | DG GROUP CODE,CONST,CSTACK,DATA | ||
| 42 | |||
| 43 | CODE SEGMENT PUBLIC BYTE | ||
| 44 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 45 | PUBLIC COMPARE,INPUT,OUTPUT,GO | ||
| 46 | PUBLIC TRACE,ZTRACE,SKIP_FILE | ||
| 47 | EXTRN GETHEX:NEAR,GETEOL:NEAR,CRLF:NEAR,ERR:NEAR, PERR:NEAR | ||
| 48 | EXTRN HEX:NEAR,DIGIT:NEAR,SCANP:NEAR,DISPREG:NEAR | ||
| 49 | EXTRN COMMAND:NEAR,DABORT:NEAR,DELIM1:NEAR,DELIM2:NEAR | ||
| 50 | EXTRN NMIINT:NEAR,NMIINTEND:NEAR,PRINTF_CRLF:NEAR | ||
| 51 | EXTRN ADDRESS:NEAR,HEXIN:NEAR,DSRANGE:NEAR | ||
| 52 | ; just like trace except skips OVER next INT or CALL. | ||
| 53 | DEBCOM3: | ||
| 54 | ZTRACE: | ||
| 55 | MOV FZTRACE,-1 | ||
| 56 | CALL SETADD | ||
| 57 | CALL SCANP | ||
| 58 | CALL HEXIN | ||
| 59 | MOV DX,1 | ||
| 60 | JC ZSTOCNT | ||
| 61 | MOV CX,4 | ||
| 62 | CALL GETHEX | ||
| 63 | CALL CHECKNONE | ||
| 64 | ZSTOCNT: | ||
| 65 | MOV [TCOUNT],DX | ||
| 66 | CALL GETEOL | ||
| 67 | MOV DX,NEXTCS | ||
| 68 | MOV CSSAVE,DX | ||
| 69 | MOV DX,NEXTIP | ||
| 70 | MOV IPSAVE,DX | ||
| 71 | ZSTEP: | ||
| 72 | MOV ES,[CSSAVE] ; point to instruction to execute | ||
| 73 | MOV DI,[IPSAVE] ; include offset in segment | ||
| 74 | XOR DX,DX ; where to place breakpoint | ||
| 75 | get_opcode: | ||
| 76 | MOV AL,ES:[DI] ; get the opcode | ||
| 77 | cmp al,0f0h ; lock | ||
| 78 | je is_override | ||
| 79 | cmp al,26h ; es: | ||
| 80 | je is_override | ||
| 81 | cmp al,2eh ; cs: | ||
| 82 | je is_override | ||
| 83 | cmp al,36h ; ss: | ||
| 84 | je is_override | ||
| 85 | cmp al,3eh ; ds: | ||
| 86 | jne not_override | ||
| 87 | Is_override: | ||
| 88 | ; inc dx ; this seemed to put us in an endless | ||
| 89 | inc di ; loop, try this. | ||
| 90 | jmp get_opcode | ||
| 91 | Not_override: | ||
| 92 | CMP AL,11101000B ; direct intra call | ||
| 93 | JZ ZTRACE3 ; yes, 3 bytes | ||
| 94 | CMP AL,10011010B ; direct inter call | ||
| 95 | JZ ZTRACE5 ; yes, 5 bytes | ||
| 96 | CMP AL,11111111B ; indirect? | ||
| 97 | JZ ZTRACEMODRM ; yes, go figure length | ||
| 98 | CMP AL,11001100B ; short interrupt? | ||
| 99 | JZ ZTRACE1 ; yes, 1 byte | ||
| 100 | CMP AL,11001101B ; long interrupt? | ||
| 101 | JZ ZTRACE2 ; yes, 2 bytes | ||
| 102 | CMP AL,11100010B ; loop | ||
| 103 | JZ ZTRACE2 ; 2 byter | ||
| 104 | CMP AL,11100001B ; loopz/loope | ||
| 105 | JZ ZTRACE2 ; 2 byter | ||
| 106 | CMP AL,11100000B ; loopnz/loopne | ||
| 107 | JZ ZTRACE2 ; 2 byter | ||
| 108 | AND AL,11111110B ; check for rep | ||
| 109 | CMP AL,11110010B ; perhaps? | ||
| 110 | JZ FOO1 | ||
| 111 | JMP STEP ; can't do anything special, step | ||
| 112 | FOO1: | ||
| 113 | MOV AL,ES:[DI+1] ; next instruction | ||
| 114 | AND AL,11111110B ; ignore w bit | ||
| 115 | CMP AL,10100100B ; MOVS | ||
| 116 | JZ ZTRACE2 ; two byte | ||
| 117 | CMP AL,10100110B ; CMPS | ||
| 118 | JZ ZTRACE2 ; two byte | ||
| 119 | CMP AL,10101110B ; SCAS | ||
| 120 | JZ ZTRACE2 ; two byte | ||
| 121 | CMP AL,10101100B ; LODS | ||
| 122 | JZ ZTRACE2 ; two byte | ||
| 123 | CMP AL,10101010B ; STOS | ||
| 124 | JZ ZTRACE2 ; two byte | ||
| 125 | JMP STEP ; bogus, do single step | ||
| 126 | |||
| 127 | ZTRACEMODRM: | ||
| 128 | MOV AL,ES:[DI+1] ; get next byte | ||
| 129 | AND AL,11111000B ; get mod and type | ||
| 130 | CMP AL,01010000B ; indirect intra 8 bit offset? | ||
| 131 | JZ ZTRACE3 ; yes, three byte whammy | ||
| 132 | CMP AL,01011000B ; indirect inter 8 bit offset | ||
| 133 | JZ ZTRACE3 ; yes, three byte guy | ||
| 134 | CMP AL,10010000B ; indirect intra 16 bit offset? | ||
| 135 | JZ ZTRACE4 ; four byte offset | ||
| 136 | CMP AL,10011000B ; indirect inter 16 bit offset? | ||
| 137 | JZ ZTRACE4 ; four bytes | ||
| 138 | CMP AL,11010000B ; indirect through reg? | ||
| 139 | JZ ZTRACE2 ; two byte instruction | ||
| 140 | JMP STEP ; can't figger out what this is! | ||
| 141 | ZTRACE5: | ||
| 142 | INC DX | ||
| 143 | ZTRACE4: | ||
| 144 | INC DX | ||
| 145 | ZTRACE3: | ||
| 146 | INC DX | ||
| 147 | ZTRACE2: | ||
| 148 | INC DX | ||
| 149 | ZTRACE1: | ||
| 150 | INC DX | ||
| 151 | ADD DI,DX ; offset to breakpoint instruction | ||
| 152 | MOV WORD PTR [BPTAB],DI ; save offset | ||
| 153 | MOV WORD PTR [BPTAB+2],ES ; save segment | ||
| 154 | MOV AL,ES:[DI] ; get next opcode byte | ||
| 155 | MOV BYTE PTR [BPTAB+4],AL ; save it | ||
| 156 | MOV BYTE PTR ES:[DI],0CCH ; break point it | ||
| 157 | MOV [BRKCNT],1 ; only this breakpoint | ||
| 158 | JMP DEXIT ; start the operation! | ||
| 159 | |||
| 160 | ; Trace 1 instruction or the number of instruction specified | ||
| 161 | ; by the parameter using 8086 trace mode. Registers are all | ||
| 162 | ; set according to values in save area | ||
| 163 | TRACE: | ||
| 164 | MOV FZTRACE,0 | ||
| 165 | CALL SETADD | ||
| 166 | CALL SCANP | ||
| 167 | CALL HEXIN | ||
| 168 | MOV DX,1 | ||
| 169 | JC STOCNT | ||
| 170 | MOV CX,4 | ||
| 171 | CALL GETHEX | ||
| 172 | CALL CHECKNONE | ||
| 173 | STOCNT: | ||
| 174 | MOV [TCOUNT],DX | ||
| 175 | CALL GETEOL | ||
| 176 | MOV DX,NEXTCS | ||
| 177 | MOV CSSAVE,DX | ||
| 178 | MOV DX,NEXTIP | ||
| 179 | MOV IPSAVE,DX | ||
| 180 | STEP: | ||
| 181 | MOV [BRKCNT],0 | ||
| 182 | ; The 286 has a problem with trace mode and software interrupt instructions; | ||
| 183 | ; it treats them as atomic operations. We simulate the operation in software. | ||
| 184 | MOV ES,[CSSAVE] ; Get next instruction pointer | ||
| 185 | MOV DI,[IPSAVE] | ||
| 186 | MOV AL,ES:[DI] ; get next opcode | ||
| 187 | cmp al,0e4h ; check for 'IN' opcode | ||
| 188 | jne not_inal_op | ||
| 189 | cmp es:byte ptr[di+1],21h | ||
| 190 | jne not_mask_op | ||
| 191 | add [ipsave],2 | ||
| 192 | JMP SETalmask | ||
| 193 | |||
| 194 | not_inal_op: | ||
| 195 | cmp al,0ech ; in al,DX ? | ||
| 196 | jne not_mask_op | ||
| 197 | cmp dxsave,21h | ||
| 198 | jne not_mask_op | ||
| 199 | add [ipsave],1 | ||
| 200 | SETalmask: | ||
| 201 | mov ax,[axsave] | ||
| 202 | in al,21h | ||
| 203 | mov [axsave],ax | ||
| 204 | JMP SETENVIRON | ||
| 205 | |||
| 206 | not_mask_op: | ||
| 207 | CMP AL,0CDH ; trace over an interrupt? | ||
| 208 | JZ DOINT ; no, check for other special cases | ||
| 209 | CMP AL,0CEH ; how about int overflow | ||
| 210 | JNZ CHECKCC | ||
| 211 | TEST FLSAVE,F_OVERFLOW ; see it overflow is present | ||
| 212 | JZ CHECKOP | ||
| 213 | MOV BX,4 ; INTO = INT 4 | ||
| 214 | DEC IPSAVE ; INTO is a singel byte | ||
| 215 | JMP SHORT DOVAL | ||
| 216 | CHECKCC: | ||
| 217 | CMP AL,0CCH | ||
| 218 | JNZ CHECKOP | ||
| 219 | MOV BX,3 ; INT 3 = CC | ||
| 220 | DEC IPSAVE | ||
| 221 | JMP SHORT DOVAL | ||
| 222 | DOINT: | ||
| 223 | ; We have a software interrupt. Get destination vector | ||
| 224 | MOV BL,BYTE PTR ES:[DI+1] ; get vector number | ||
| 225 | XOR BH,BH ; clear out upper | ||
| 226 | DOVAL: | ||
| 227 | SHL BX,1 ; word index | ||
| 228 | SHL BX,1 ; dword index | ||
| 229 | XOR DI,DI ; interrupt table | ||
| 230 | MOV ES,DI | ||
| 231 | MOV AX,ES:[BX] ; point to vector | ||
| 232 | MOV BX,ES:[BX+2] ; point to vector | ||
| 233 | ; AX:BX is the vector. Swap it with currect CS:IP | ||
| 234 | XCHG AX,IPSAVE ; new CS:IP | ||
| 235 | XCHG BX,CSSAVE | ||
| 236 | ; AX:BX is old CS:IP. We 'PUSH' flags, oldCS and oldIP, reset flags (ifl) and | ||
| 237 | ; set CS:IP to point to interrupt instruction. | ||
| 238 | MOV ES,SSSAVE ; point to user stack | ||
| 239 | MOV DI,SPSAVE | ||
| 240 | ; Take old flags and PUSH the flags. | ||
| 241 | MOV CX,FLSAVE ; get flags | ||
| 242 | SUB DI,2 ; PUSHF | ||
| 243 | MOV ES:[DI],CX ; rest of push | ||
| 244 | ; Push the old CS | ||
| 245 | SUB DI,2 ; PUSH CS | ||
| 246 | MOV ES:[DI],BX ; rest of push | ||
| 247 | ; Push the old IP | ||
| 248 | SUB DI,2 ; PUSH IP | ||
| 249 | ADD AX,2 ; increment IP | ||
| 250 | MOV ES:[DI],AX ; rest of push | ||
| 251 | ; Update stack | ||
| 252 | MOV SPSAVE,DI ; store | ||
| 253 | ; Take flags and turn interrupts off and trace mode off | ||
| 254 | AND CX,NOT F_INTERRUPT ; CLI | ||
| 255 | AND CX,NOT F_TRACE ; no trace | ||
| 256 | MOV FLSAVE,CX ; rest of CLI | ||
| 257 | ; Set up correct process and go to normal reentry code. | ||
| 258 | IF NOT SYSVER | ||
| 259 | MOV BX,[USER_PROC_PDB] | ||
| 260 | MOV AH,SET_CURRENT_PDB | ||
| 261 | INT 21H | ||
| 262 | ENDIF | ||
| 263 | JMP SETENVIRON | ||
| 264 | ; We need to special case the following instructions that may push a TRACE bit | ||
| 265 | ; on the stack: PUSHF (9C) | ||
| 266 | |||
| 267 | ; Save the opcode in A Special place | ||
| 268 | CHECKOP: | ||
| 269 | MOV RSETFLAG,AL ; no bits to turn off | ||
| 270 | SETTRACE: | ||
| 271 | OR FLSAVE,F_TRACE ; Turn on trace bit | ||
| 272 | IF IBMVER | ||
| 273 | CLI | ||
| 274 | IN AL,MASK_PORT ; Get current mask | ||
| 275 | JMP SHORT FOO | ||
| 276 | FOO: | ||
| 277 | MOV [OLD_MASK],AL ; Save it | ||
| 278 | MOV AL,INT_MASK ; New mask | ||
| 279 | OUT MASK_PORT,AL ; Set it | ||
| 280 | STI | ||
| 281 | ENDIF | ||
| 282 | DEXIT: | ||
| 283 | IF NOT SYSVER | ||
| 284 | MOV BX,[USER_PROC_PDB] | ||
| 285 | MOV AH,SET_CURRENT_PDB | ||
| 286 | INT 21H | ||
| 287 | ENDIF | ||
| 288 | ; Unfortunately, any system call we issue will muck with the current extended | ||
| 289 | ; errors. Here we must restore the extended error state so that if the user | ||
| 290 | ; program gets it, we do not interfere. | ||
| 291 | MOV AX,(SERVERCALL SHL 8) + 10 | ||
| 292 | MOV DX,OFFSET DG:SAVESTATE | ||
| 293 | INT 21H | ||
| 294 | PUSH DS | ||
| 295 | XOR AX,AX | ||
| 296 | MOV DS,AX | ||
| 297 | MOV WORD PTR DS:[12],OFFSET DG:BREAKFIX ; Set vector 3--breakpoint instruction | ||
| 298 | MOV WORD PTR DS:[14],CS | ||
| 299 | MOV WORD PTR DS:[4],OFFSET DG:REENTER ; Set vector 1--Single step | ||
| 300 | MOV WORD PTR DS:[6],CS | ||
| 301 | CLI | ||
| 302 | IF SETCNTC | ||
| 303 | MOV WORD PTR DS:[8CH],OFFSET DG:CONTC ; Set vector 23H (CTRL-C) | ||
| 304 | MOV WORD PTR DS:[8EH],CS | ||
| 305 | ENDIF | ||
| 306 | POP DS | ||
| 307 | MOV SP,OFFSET DG:STACK | ||
| 308 | POP AX | ||
| 309 | POP BX | ||
| 310 | POP CX | ||
| 311 | POP DX | ||
| 312 | POP BP | ||
| 313 | POP BP | ||
| 314 | POP SI | ||
| 315 | POP DI | ||
| 316 | POP ES | ||
| 317 | POP ES | ||
| 318 | POP SS | ||
| 319 | MOV SP,[SPSAVE] | ||
| 320 | PUSH [FLSAVE] | ||
| 321 | PUSH [CSSAVE] | ||
| 322 | PUSH [IPSAVE] | ||
| 323 | MOV DS,[DSSAVE] | ||
| 324 | IRET | ||
| 325 | STEP1: | ||
| 326 | CALL CRLF | ||
| 327 | CALL DISPREG | ||
| 328 | TEST FZTRACE,-1 | ||
| 329 | JNZ STEPZ | ||
| 330 | JMP STEP | ||
| 331 | STEPZ: JMP ZSTEP | ||
| 332 | |||
| 333 | ; Re-entry point from CTRL-C. Top of stack has address in 86-DOS for | ||
| 334 | ; continuing, so we must pop that off. | ||
| 335 | CONTC: | ||
| 336 | ADD SP,6 | ||
| 337 | JMP SHORT REENTERREAL | ||
| 338 | |||
| 339 | ; Re-entry point from breakpoint. Need to decrement instruction | ||
| 340 | ; pointer so it points to location where breakpoint actually | ||
| 341 | ; occured. | ||
| 342 | BREAKFIX: | ||
| 343 | PUSH BP | ||
| 344 | MOV BP,SP | ||
| 345 | DEC WORD PTR [BP].OLDIP | ||
| 346 | POP BP | ||
| 347 | JMP REENTERREAL | ||
| 348 | |||
| 349 | ; Re-entry point from trace mode or interrupt during execution. All registers | ||
| 350 | ; are saved so they can be displayed or modified. | ||
| 351 | INTERRUPT_FRAME STRUC | ||
| 352 | OLDBP DW ? | ||
| 353 | OLDIP DW ? | ||
| 354 | OLDCS DW ? | ||
| 355 | OLDF DW ? | ||
| 356 | OLDERIP DW ? | ||
| 357 | OLDERCS DW ? | ||
| 358 | OLDERF DW ? | ||
| 359 | INTERRUPT_FRAME ENDS | ||
| 360 | |||
| 361 | ASSUME CS:DG,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 362 | ; ReEnter is the main entry point for breakpoint interrupts and for trace mode | ||
| 363 | ; interrupts. We treat both of these cases identically: save state, display | ||
| 364 | ; registers and go for another command. If we get NMI's, we skip them or if | ||
| 365 | ; it turns out that we are debugging ourselves, we skip them. | ||
| 366 | |||
| 367 | ; Due to bogosities in the 808x chip, Consider tracing over an interrupt and | ||
| 368 | ; then setting a breakpoint to where the interrupt returns. You get the INT 3 | ||
| 369 | ; and then trace mode gets invoked! This is why we ignore interrupts within | ||
| 370 | ; ourselves. | ||
| 371 | REENTER: | ||
| 372 | PUSH BP | ||
| 373 | MOV BP,SP ; get a frame to address from | ||
| 374 | PUSH AX | ||
| 375 | ; MOV AX,CS | ||
| 376 | ; CMP AX,[BP].OLDCS ; Did we interrupt ourselves? | ||
| 377 | ; JNZ GOREENTER ; no, go reenter | ||
| 378 | IF IBMJAPAN | ||
| 379 | MOV AX,[BP].OLDIP | ||
| 380 | CMP AX,OFFSET DG:NMIINT ; interrupt below NMI interrupt? | ||
| 381 | JB GOREENTER ; yes, go reenter | ||
| 382 | CMP [BP].OLDIP,OFFSET DG:NMIINTEND | ||
| 383 | JAE GOREENTER ; interrupt above NMI interrupt? | ||
| 384 | POP AX ; restore state | ||
| 385 | POP BP | ||
| 386 | SUB SP,6 ; switch TRACE and NMI stack frames | ||
| 387 | PUSH BP | ||
| 388 | MOV BP,SP ; set up frame | ||
| 389 | PUSH AX ; get temp variable | ||
| 390 | MOV AX,[BP].OLDERIP ; get NMI Vector | ||
| 391 | MOV [BP].OLDIP,AX ; stuff in new NMI vector | ||
| 392 | MOV AX,[BP].OLDERCS ; get NMI Vector | ||
| 393 | MOV [BP].OLDCS,AX ; stuff in new NMI vector | ||
| 394 | MOV AX,[BP].OLDERF ; get NMI Vector | ||
| 395 | AND AH,0FEH ; turn off Trace if present | ||
| 396 | MOV [BP].OLDF,AX ; stuff in new NMI vector | ||
| 397 | MOV [BP].OLDERF,AX | ||
| 398 | MOV [BP].OLDERIP,OFFSET DG:REENTER ; offset of routine | ||
| 399 | MOV [BP].OLDERCS,CS ; and CS | ||
| 400 | POP AX | ||
| 401 | POP BP | ||
| 402 | IRET ; go try again | ||
| 403 | ENDIF | ||
| 404 | GOREENTER: | ||
| 405 | IF IBMVER | ||
| 406 | MOV AL,CS:[OLD_MASK] ; Recover Old mask | ||
| 407 | OUT MASK_PORT,AL ; Restore it | ||
| 408 | ENDIF | ||
| 409 | MOV AL,CS:[RSETFLAG] | ||
| 410 | ; Determine, based on the previous instruction, what we are supposed to do | ||
| 411 | ; to flags on the users stack. | ||
| 412 | CMP AL,09CH ; PUSHF | ||
| 413 | JNZ NOFIX | ||
| 414 | ; OlderIP = flags. Turn off trace bit | ||
| 415 | AND [BP].OLDERIP,NOT F_TRACE | ||
| 416 | NOFIX: | ||
| 417 | POP AX | ||
| 418 | POP BP | ||
| 419 | REENTERREAL: | ||
| 420 | MOV CS:[SPSAVE+SEGDIF],SP | ||
| 421 | MOV CS:[SSSAVE+SEGDIF],SS | ||
| 422 | MOV CS:[FLSAVE],CS | ||
| 423 | MOV SS,CS:[FLSAVE] | ||
| 424 | MOV SP,OFFSET DG:RSTACK | ||
| 425 | ASSUME SS:DG | ||
| 426 | |||
| 427 | PUSH ES | ||
| 428 | PUSH DS | ||
| 429 | PUSH DI | ||
| 430 | PUSH SI | ||
| 431 | PUSH BP | ||
| 432 | DEC SP | ||
| 433 | DEC SP | ||
| 434 | PUSH DX | ||
| 435 | PUSH CX | ||
| 436 | PUSH BX | ||
| 437 | PUSH AX | ||
| 438 | PUSH SS | ||
| 439 | POP DS | ||
| 440 | ASSUME DS:DG | ||
| 441 | |||
| 442 | MOV SS,[SSSAVE] | ||
| 443 | MOV SP,[SPSAVE] | ||
| 444 | ASSUME SS:NOTHING | ||
| 445 | |||
| 446 | POP [IPSAVE] | ||
| 447 | POP [CSSAVE] | ||
| 448 | POP AX | ||
| 449 | AND AX,NOT F_TRACE ; TURN OFf trace mode bit | ||
| 450 | MOV [FLSAVE],AX | ||
| 451 | MOV [SPSAVE],SP | ||
| 452 | SETENVIRON: | ||
| 453 | PUSH DS | ||
| 454 | POP ES | ||
| 455 | ASSUME ES:DG | ||
| 456 | |||
| 457 | PUSH DS | ||
| 458 | POP SS | ||
| 459 | ASSUME SS:DG | ||
| 460 | |||
| 461 | MOV SP,OFFSET DG:STACK | ||
| 462 | PUSH DS | ||
| 463 | XOR AX,AX | ||
| 464 | MOV DS,AX | ||
| 465 | ASSUME DS:NOTHING | ||
| 466 | |||
| 467 | IF SETCNTC | ||
| 468 | MOV WORD PTR DS:[8CH],OFFSET DG:DABORT ; Set Ctrl-C vector | ||
| 469 | MOV WORD PTR DS:[8EH],CS | ||
| 470 | ENDIF | ||
| 471 | POP DS | ||
| 472 | ASSUME DS:DG | ||
| 473 | |||
| 474 | STI | ||
| 475 | CLD | ||
| 476 | ; Since we are about to issue system calls, let's grab the current user's | ||
| 477 | ; extended error info. | ||
| 478 | MOV AH,GETEXTENDEDERROR | ||
| 479 | INT 21H | ||
| 480 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 481 | |||
| 482 | MOV SAVESTATE.DPL_AX,AX | ||
| 483 | MOV SAVESTATE.DPL_BX,BX | ||
| 484 | MOV SAVESTATE.DPL_CX,CX | ||
| 485 | MOV SAVESTATE.DPL_DX,DX | ||
| 486 | MOV SAVESTATE.DPL_SI,SI | ||
| 487 | MOV SAVESTATE.DPL_DI,DI | ||
| 488 | MOV SAVESTATE.DPL_DS,DS | ||
| 489 | MOV SAVESTATE.DPL_ES,ES | ||
| 490 | MOV AX,CS | ||
| 491 | MOV DS,AX | ||
| 492 | MOV ES,AX | ||
| 493 | ASSUME DS:DG,ES:DG | ||
| 494 | |||
| 495 | IF NOT SYSVER | ||
| 496 | MOV AH,GET_CURRENT_PDB | ||
| 497 | INT 21H | ||
| 498 | MOV [USER_PROC_PDB],BX | ||
| 499 | MOV BX,BEGSEG | ||
| 500 | MOV AH,SET_CURRENT_PDB | ||
| 501 | INT 21H | ||
| 502 | ENDIF | ||
| 503 | MOV SI,OFFSET DG:BPTAB | ||
| 504 | MOV CX,[BRKCNT] | ||
| 505 | JCXZ SHOREG | ||
| 506 | PUSH ES | ||
| 507 | CLEARBP: | ||
| 508 | LES DI,DWORD PTR [SI] | ||
| 509 | ADD SI,4 | ||
| 510 | MOVSB | ||
| 511 | LOOP CLEARBP | ||
| 512 | POP ES | ||
| 513 | SHOREG: | ||
| 514 | DEC [TCOUNT] | ||
| 515 | JZ CHECKDISP | ||
| 516 | JMP STEP1 | ||
| 517 | CHECKDISP: | ||
| 518 | CALL CRLF | ||
| 519 | CALL DISPREG | ||
| 520 | JMP COMMAND | ||
| 521 | |||
| 522 | ; Input from the specified port and display result | ||
| 523 | INPUT: | ||
| 524 | MOV CX,4 ; Port may have 4 digits | ||
| 525 | CALL GETHEX ; Get port number in DX | ||
| 526 | CALL GETEOL | ||
| 527 | |||
| 528 | IN AL,DX ; Variable port input | ||
| 529 | |||
| 530 | PUSH CS | ||
| 531 | POP ES | ||
| 532 | MOV DI,OFFSET DG:ARG_BUF | ||
| 533 | CALL HEX ; And display | ||
| 534 | |||
| 535 | XOR AL,AL | ||
| 536 | STOSB | ||
| 537 | MOV DX,OFFSET DG:ARG_BUF_PTR | ||
| 538 | JMP PRINTF_CRLF | ||
| 539 | |||
| 540 | ; Output a value to specified port. | ||
| 541 | OUTPUT: | ||
| 542 | MOV CX,4 ; Port may have 4 digits | ||
| 543 | CALL GETHEX ; Get port number | ||
| 544 | PUSH DX ; Save while we get data | ||
| 545 | MOV CX,2 ; Byte output only | ||
| 546 | CALL GETHEX ; Get data to output | ||
| 547 | CALL GETEOL | ||
| 548 | XCHG AX,DX ; Output data in AL | ||
| 549 | POP DX ; Port in DX | ||
| 550 | |||
| 551 | OUT DX,AL ; Variable port output | ||
| 552 | |||
| 553 | RETURN | ||
| 554 | |||
| 555 | SETADD: | ||
| 556 | MOV DX,CSSAVE ; set up start addresses | ||
| 557 | MOV NEXTCS,DX | ||
| 558 | MOV DX,IPSAVE | ||
| 559 | MOV NEXTIP,DX | ||
| 560 | MOV BP,[CSSAVE] | ||
| 561 | CALL SCANP | ||
| 562 | CMP BYTE PTR [SI],"=" | ||
| 563 | RETNZ | ||
| 564 | INC SI | ||
| 565 | CALL ADDRESS | ||
| 566 | MOV NEXTCS,AX | ||
| 567 | MOV NEXTIP,DX | ||
| 568 | RETURN | ||
| 569 | |||
| 570 | ; Jump to program, setting up registers according to the | ||
| 571 | ; save area. up to 10 breakpoint addresses may be specified. | ||
| 572 | GO: | ||
| 573 | MOV RSETFLAG,0 | ||
| 574 | CALL SETADD | ||
| 575 | XOR BX,BX | ||
| 576 | MOV DI,OFFSET DG:BPTAB | ||
| 577 | GO1: | ||
| 578 | CALL SCANP | ||
| 579 | JZ DEXEC | ||
| 580 | MOV BP,[CSSAVE] | ||
| 581 | PUSH DI | ||
| 582 | PUSH BX ;AN000; DMS;SAVE BX - ADDRESS KILLS IT | ||
| 583 | CALL ADDRESS | ||
| 584 | POP BX ;AN000; DMS;RESTORE BX | ||
| 585 | POP DI | ||
| 586 | MOV [DI],DX ; Save offset | ||
| 587 | MOV [DI+2],AX ; Save segment | ||
| 588 | ADD DI,5 ; Leave a little room | ||
| 589 | INC BX | ||
| 590 | CMP BX,1+BPMAX | ||
| 591 | JNZ GO1 | ||
| 592 | MOV DX,OFFSET DG:BP_ERROR ; BP ERROR | ||
| 593 | JMP ERR | ||
| 594 | DEXEC: | ||
| 595 | MOV [BRKCNT],BX | ||
| 596 | MOV CX,BX | ||
| 597 | JCXZ NOBP | ||
| 598 | MOV DI,OFFSET DG:BPTAB | ||
| 599 | PUSH DS | ||
| 600 | SETBP: | ||
| 601 | LDS SI,ES:DWORD PTR [DI] | ||
| 602 | ADD DI,4 | ||
| 603 | MOVSB | ||
| 604 | MOV BYTE PTR [SI-1],0CCH | ||
| 605 | LOOP SETBP | ||
| 606 | POP DS | ||
| 607 | NOBP: | ||
| 608 | MOV DX,NEXTCS | ||
| 609 | MOV CSSAVE,DX | ||
| 610 | MOV DX,NEXTIP | ||
| 611 | MOV IPSAVE,DX | ||
| 612 | MOV [TCOUNT],1 | ||
| 613 | JMP DEXIT | ||
| 614 | |||
| 615 | SKIP_FILE: | ||
| 616 | MOV AH,CHAR_OPER | ||
| 617 | INT 21H | ||
| 618 | MOV CS:[SWITCHAR],DL ; GET THE CURRENT SWITCH CHARACTER | ||
| 619 | FIND_DELIM: | ||
| 620 | LODSB | ||
| 621 | CALL DELIM1 | ||
| 622 | JZ GOTDELIM | ||
| 623 | CALL DELIM2 | ||
| 624 | JNZ FIND_DELIM | ||
| 625 | GOTDELIM: | ||
| 626 | DEC SI | ||
| 627 | RETURN | ||
| 628 | |||
| 629 | COMPARE: | ||
| 630 | CALL DSRANGE | ||
| 631 | PUSH CX | ||
| 632 | PUSH AX | ||
| 633 | PUSH DX | ||
| 634 | CALL ADDRESS ; Same segment | ||
| 635 | CALL GETEOL | ||
| 636 | POP SI | ||
| 637 | MOV DI,DX | ||
| 638 | MOV ES,AX | ||
| 639 | POP DS | ||
| 640 | POP CX ; Length | ||
| 641 | DEC CX | ||
| 642 | CALL COMP ; Do one less than total | ||
| 643 | INC CX ; CX=1 (do last one) | ||
| 644 | COMP: | ||
| 645 | REPE CMPSB | ||
| 646 | RETZ | ||
| 647 | ; Compare error. Print address, value; value, address. | ||
| 648 | DEC SI | ||
| 649 | MOV CS:COMP_ARG1,DS | ||
| 650 | MOV CS:COMP_ARG2,SI | ||
| 651 | XOR AH,AH | ||
| 652 | LODSB | ||
| 653 | MOV CS:COMP_ARG3,AX | ||
| 654 | DEC DI | ||
| 655 | MOV AL,ES:[DI] | ||
| 656 | MOV CS:COMP_ARG4,AX | ||
| 657 | MOV CS:COMP_ARG5,ES | ||
| 658 | MOV CS:COMP_ARG6,DI | ||
| 659 | INC DI | ||
| 660 | PUSH DS | ||
| 661 | PUSH CS | ||
| 662 | POP DS | ||
| 663 | MOV DX,OFFSET DG:COMP_PTR | ||
| 664 | CALL PRINTF_CRLF | ||
| 665 | POP DS | ||
| 666 | XOR AL,AL | ||
| 667 | JMP SHORT COMP | ||
| 668 | |||
| 669 | PROCEDURE CHECKNONE,NEAR | ||
| 670 | OR DX,DX | ||
| 671 | RETNZ | ||
| 672 | MOV DX,OFFSET DG:SYNERR_PTR ; ERROR MESSAGE | ||
| 673 | JMP PERR | ||
| 674 | ENDPROC CHECKNONE | ||
| 675 | |||
| 676 | CODE ENDS | ||
| 677 | END DEBCOM3 | ||
| 678 | \ No newline at end of file | ||