diff options
Diffstat (limited to 'v4.0/src/CMD/DEBUG/DEBCOM1.ASM')
| -rw-r--r-- | v4.0/src/CMD/DEBUG/DEBCOM1.ASM | 969 |
1 files changed, 969 insertions, 0 deletions
diff --git a/v4.0/src/CMD/DEBUG/DEBCOM1.ASM b/v4.0/src/CMD/DEBUG/DEBCOM1.ASM new file mode 100644 index 0000000..fda97c0 --- /dev/null +++ b/v4.0/src/CMD/DEBUG/DEBCOM1.ASM | |||
| @@ -0,0 +1,969 @@ | |||
| 1 | PAGE 60,132 ; | ||
| 2 | TITLE DEBCOM1.ASM - PART1 DEBUGGER COMMANDS PC DOS | ||
| 3 | ;======================= START OF SPECIFICATIONS ========================= | ||
| 4 | ; | ||
| 5 | ; MODULE NAME: DECOM1.SAL | ||
| 6 | ; | ||
| 7 | ; DESCRIPTIVE NAME: DEBUGGING TOOL | ||
| 8 | ; | ||
| 9 | ; FUNCTION: PROVIDES USERS WITH A TOOL FOR DEBUGGING PROGRAMS. | ||
| 10 | ; | ||
| 11 | ; ENTRY POINT: ANY CALLED ROUTINE | ||
| 12 | ; | ||
| 13 | ; INPUT: NA | ||
| 14 | ; | ||
| 15 | ; EXIT NORMAL: NA | ||
| 16 | ; | ||
| 17 | ; EXIT ERROR: NA | ||
| 18 | ; | ||
| 19 | ; INTERNAL REFERENCES: | ||
| 20 | ; | ||
| 21 | ; EXTERNAL REFERENCES: | ||
| 22 | ; | ||
| 23 | ; ROUTINE: DEBCOM2 - CONTAINS ROUTINES CALLED BY DEBUG | ||
| 24 | ; DEBCOM3 - CONTAINS ROUTINES CALLED BY DEBUG | ||
| 25 | ; DEBASM - CONTAINS ROUTINES CALLED BY DEBUG | ||
| 26 | ; DEBUASM - CONTAINS ROUTINES CALLED BY DEBUG | ||
| 27 | ; DEBMES - CONTAINS ROUTINES CALLED BY DEBUG | ||
| 28 | ; | ||
| 29 | ; NOTES: THIS MODULE IS TO BE PREPPED BY SALUT WITH THE "PR" OPTIONS. | ||
| 30 | ; LINK DEBUG+DEBCOM1+DEBCOM2+DEBCOM3+DEBASM+DEBUASM+DEBERR+ | ||
| 31 | ; DEBCONST+DEBDATA+DEBMES | ||
| 32 | ; | ||
| 33 | ; REVISION HISTORY: | ||
| 34 | ; | ||
| 35 | ; AN000 VERSION 4.00 - REVISIONS MADE RELATE TO THE FOLLOWING: | ||
| 36 | ; | ||
| 37 | ; - IMPLEMENT DBCS HANDLING DMS:6/17/87 | ||
| 38 | ; - IMPLEMENT MESSAGE RETRIEVER DMS:6/17/87 | ||
| 39 | ; - IMPLEMENT > 32MB SUPPORT DMS:6/17/87 | ||
| 40 | ; | ||
| 41 | ; COPYRIGHT: "MS DOS DEBUG UTILITY" | ||
| 42 | ; "VERSION 4.00 (C) COPYRIGHT 1988 Microsoft" | ||
| 43 | ; "LICENSED MATERIAL - PROPERTY OF Microsoft " | ||
| 44 | ; | ||
| 45 | ;======================= END OF SPECIFICATIONS =========================== | ||
| 46 | |||
| 47 | ; Routines to perform debugger commands except ASSEMble and UASSEMble | ||
| 48 | |||
| 49 | IF1 | ||
| 50 | %OUT COMPONENT=DEBUG, MODULE=DEBCOM1 | ||
| 51 | ENDIF | ||
| 52 | .XLIST | ||
| 53 | .XCREF | ||
| 54 | INCLUDE DOSSYM.INC | ||
| 55 | INCLUDE DEBEQU.ASM | ||
| 56 | .CREF | ||
| 57 | .LIST | ||
| 58 | |||
| 59 | CODE SEGMENT PUBLIC BYTE | ||
| 60 | CODE ENDS | ||
| 61 | |||
| 62 | CONST SEGMENT PUBLIC BYTE | ||
| 63 | EXTRN SYNERR_PTR:BYTE | ||
| 64 | EXTRN DISPB:WORD,DSIZ:BYTE,DSSAVE:WORD | ||
| 65 | IF SYSVER | ||
| 66 | EXTRN CIN:DWORD,PFLAG:BYTE | ||
| 67 | ENDIF | ||
| 68 | CONST ENDS | ||
| 69 | |||
| 70 | CSTACK SEGMENT STACK | ||
| 71 | CSTACK ENDS | ||
| 72 | |||
| 73 | DATA SEGMENT PUBLIC BYTE | ||
| 74 | EXTRN DEFLEN:WORD,BYTEBUF:BYTE,DEFDUMP:BYTE | ||
| 75 | EXTRN ARG_BUF:BYTE,ARG_BUF_PTR:BYTE | ||
| 76 | EXTRN ONE_CHAR_BUF:BYTE,ONE_CHAR_BUF_PTR:WORD | ||
| 77 | DATA ENDS | ||
| 78 | |||
| 79 | DG GROUP CODE,CONST,CSTACK,DATA | ||
| 80 | |||
| 81 | CODE SEGMENT PUBLIC BYTE | ||
| 82 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 83 | PUBLIC HEXCHK,GETHEX1,PRINT,DSRANGE,ADDRESS,HEXIN,PERROR | ||
| 84 | PUBLIC GETHEX,GET_ADDRESS,GETEOL,GETHX,PERR | ||
| 85 | PUBLIC PERR,MOVE,DUMP,ENTERDATA,FILL,SEARCH,DEFAULT | ||
| 86 | IF SYSVER | ||
| 87 | PUBLIC IN | ||
| 88 | EXTRN DISPREG:NEAR,DEVIOCALL:NEAR | ||
| 89 | ENDIF | ||
| 90 | EXTRN CRLF:NEAR,OUTDI:NEAR,OUTSI:NEAR,SCANP:NEAR | ||
| 91 | EXTRN SCANB:NEAR,BLANK:NEAR,TAB:NEAR,COMMAND:NEAR | ||
| 92 | EXTRN HEX:NEAR,BACKUP:NEAR | ||
| 93 | EXTRN PRINTF_CRLF:NEAR,HEX_ADDRESS_ONLY:NEAR,HEX_ADDRESS_STR:NEAR | ||
| 94 | EXTRN STD_PRINTF:NEAR | ||
| 95 | DEBCOM1: | ||
| 96 | ; RANGE - Looks for parameters defining an address range. | ||
| 97 | ; The first parameter is the starting address. The second parameter | ||
| 98 | ; may specify the ending address, or it may be preceded by | ||
| 99 | ; "L" and specify a length (4 digits max), or it may be | ||
| 100 | ; omitted and a length of 128 bytes is assumed. Returns with | ||
| 101 | ; segment in AX, displacement in DX, and length in CX. | ||
| 102 | DSRANGE: | ||
| 103 | MOV BP,[DSSAVE] ; Set default segment to DS | ||
| 104 | MOV [DEFLEN],128 ; And default length to 128 bytes | ||
| 105 | RANGE: | ||
| 106 | CALL ADDRESS | ||
| 107 | |||
| 108 | PUSH AX ; Save segment | ||
| 109 | PUSH DX ; Save offset | ||
| 110 | CALL SCANP ; Get to next parameter | ||
| 111 | |||
| 112 | MOV AL,[SI] | ||
| 113 | CMP AL,UPPER_L ; Length indicator? | ||
| 114 | JE GETLEN | ||
| 115 | |||
| 116 | MOV DX,[DEFLEN] ; Default length | ||
| 117 | CALL HEXIN ; Second parameter present? | ||
| 118 | |||
| 119 | JC GETDEF ; If not, use default | ||
| 120 | |||
| 121 | MOV CX,4 | ||
| 122 | CALL GETHEX ; Get ending address (same segment) | ||
| 123 | |||
| 124 | MOV CX,DX ; Low 16 bits of ending addr. | ||
| 125 | POP DX ; Low 16 bits of starting addr. | ||
| 126 | SUB CX,DX ; Compute range | ||
| 127 | JAE DSRNG2 | ||
| 128 | |||
| 129 | DSRNG1: | ||
| 130 | JMP PERROR ; Negative range | ||
| 131 | DSRNG2: | ||
| 132 | INC CX ; Include last location | ||
| 133 | ; JCXZ DSRNG1 ; Wrap around error | ||
| 134 | ; Removing this instruction allows 0 FFFF to valid range | ||
| 135 | POP AX ; Restore segment | ||
| 136 | RET | ||
| 137 | GETDEF: | ||
| 138 | POP CX ; get original offset | ||
| 139 | PUSH CX ; save it | ||
| 140 | NEG CX ; rest of segment | ||
| 141 | JZ RNGRET ; use default | ||
| 142 | |||
| 143 | CMP CX,DX ; more room in segment? | ||
| 144 | JAE RNGRET ; yes, use default | ||
| 145 | |||
| 146 | JMP RNGRET1 ; no, length is in CX | ||
| 147 | |||
| 148 | GETLEN: | ||
| 149 | INC SI ; Skip over "L" to length | ||
| 150 | MOV CX,4 ; Length may have 4 digits | ||
| 151 | CALL GETHEX ; Get the range | ||
| 152 | |||
| 153 | RNGRET: | ||
| 154 | MOV CX,DX ; Length | ||
| 155 | RNGRET1: | ||
| 156 | POP DX ; Offset | ||
| 157 | MOV AX,CX | ||
| 158 | ADD AX,DX | ||
| 159 | JNC OKRET | ||
| 160 | |||
| 161 | CMP AX,1 | ||
| 162 | JAE DSRNG1 ; Look for wrap error | ||
| 163 | |||
| 164 | OKRET: | ||
| 165 | POP AX ; Segment | ||
| 166 | RET | ||
| 167 | DEFAULT: | ||
| 168 | ; DI points to default address and CX has default length | ||
| 169 | CALL SCANP | ||
| 170 | |||
| 171 | JZ USEDEF ; Use default if no parameters | ||
| 172 | |||
| 173 | MOV [DEFLEN],CX | ||
| 174 | CALL RANGE | ||
| 175 | |||
| 176 | JMP GETEOL | ||
| 177 | |||
| 178 | USEDEF: | ||
| 179 | MOV SI,DI | ||
| 180 | LODSW ; Get default displacement | ||
| 181 | MOV DX,AX | ||
| 182 | LODSW ; Get default segment | ||
| 183 | RET | ||
| 184 | |||
| 185 | ; Dump an area of memory in both hex and ASCII | ||
| 186 | DUMP: | ||
| 187 | MOV BP,[DSSAVE] | ||
| 188 | MOV CX,DISPB | ||
| 189 | MOV DI,OFFSET DG:DEFDUMP | ||
| 190 | CALL DEFAULT ; Get range if specified | ||
| 191 | |||
| 192 | MOV DS,AX ; Set segment | ||
| 193 | ASSUME DS:NOTHING | ||
| 194 | |||
| 195 | MOV SI,DX ; SI has displacement in segment | ||
| 196 | PUSH SI ; save SI away | ||
| 197 | MOV AL,DSIZ | ||
| 198 | XOR AH,AH | ||
| 199 | XOR AX,-1 | ||
| 200 | AND SI,AX ; convert to para number | ||
| 201 | MOV DI,OFFSET DG:ARG_BUF ; Build the output str in arg_buf | ||
| 202 | CALL OUTSI ; display location | ||
| 203 | |||
| 204 | POP SI ; get SI back | ||
| 205 | ; Determine where the registers display should begin. | ||
| 206 | MOV AX,SI ; move offset | ||
| 207 | MOV AH,3 ; spaces per byte | ||
| 208 | AND AL,DSIZ ; convert to real offset | ||
| 209 | MUL AH ; 3 char positions per byte of output | ||
| 210 | OR AL,AL ; at beginning? | ||
| 211 | JZ INROW ; if so, then no movement. | ||
| 212 | |||
| 213 | PUSH CX | ||
| 214 | MOV CX,AX | ||
| 215 | CALL TAB | ||
| 216 | |||
| 217 | POP CX | ||
| 218 | INROW: | ||
| 219 | PUSH SI ; Save address for ASCII dump | ||
| 220 | BYTE0: | ||
| 221 | CALL BLANK ; Space between bytes | ||
| 222 | BYTE1: | ||
| 223 | LODSB ; Get byte to dump | ||
| 224 | CALL HEX ; and display it | ||
| 225 | |||
| 226 | POP DX ; DX has start addr. for ASCII dump | ||
| 227 | DEC CX ; Drop loop count | ||
| 228 | JZ ASCII ; If through do ASCII dump | ||
| 229 | |||
| 230 | MOV AX,SI | ||
| 231 | TEST AL,DSIZ ; On row boundary? | ||
| 232 | JZ ENDROW | ||
| 233 | |||
| 234 | PUSH DX ; Didn't need ASCII addr. yet | ||
| 235 | TEST AL,7 ; On 8-byte boundary? | ||
| 236 | JNZ BYTE0 | ||
| 237 | |||
| 238 | MOV AL,CHAR_MINUS ; Mark every 8 bytes with "-" | ||
| 239 | STOSB | ||
| 240 | JMP SHORT BYTE1 | ||
| 241 | |||
| 242 | ENDROW: | ||
| 243 | CALL ASCII ; Show it in ASCII | ||
| 244 | |||
| 245 | MOV DI,OFFSET DG:ARG_BUF ; Build the output str in arg_buf | ||
| 246 | CALL OUTSI ; Get the address at start of line | ||
| 247 | |||
| 248 | JMP INROW ; Loop until count is zero | ||
| 249 | |||
| 250 | ; Produce a dump of the ascii text characters. We take the current SI which | ||
| 251 | ; contains the byte after the last one dumped. From this we determine how | ||
| 252 | ; many spaces we need to output to get to the ascii column. Then we look at | ||
| 253 | ; the beginning address of the dump to tsee how many spaces we need to indent. | ||
| 254 | ASCII: | ||
| 255 | PUSH CX ; Save count of remaining bytes | ||
| 256 | ; Determine how many spaces to go until the ASCII column. | ||
| 257 | MOV AX,SI ; get offset of next byte | ||
| 258 | DEC AL | ||
| 259 | AND AL,DSIZ | ||
| 260 | INC AL | ||
| 261 | ; AX now has the number of bytes that we have displayed: 1 to Dsiz+1. | ||
| 262 | ; Compute characters remaining to be displayed. We *always* put the ASCII | ||
| 263 | ; dump in column 51 (or whereever) | ||
| 264 | SUB AL,10H ; get negative of number | ||
| 265 | DEC AL ; | ||
| 266 | NEG AL ; convert to positive | ||
| 267 | CBW ; convert to word | ||
| 268 | ; 3 character positions for each byte displayed. | ||
| 269 | MOV CX,AX | ||
| 270 | SHL AX,1 | ||
| 271 | ADD CX,AX | ||
| 272 | ; Compute indent for ascii dump | ||
| 273 | MOV AX,DX | ||
| 274 | AND AL,DSIZ | ||
| 275 | XOR AH,AH | ||
| 276 | ADD CX,AX | ||
| 277 | ; Tab over | ||
| 278 | CALL TAB | ||
| 279 | |||
| 280 | ; Set up for true dump | ||
| 281 | MOV CX,SI | ||
| 282 | MOV SI,DX | ||
| 283 | SUB CX,SI | ||
| 284 | ASCDMP: | ||
| 285 | LODSB ; Get ASCII byte to dump | ||
| 286 | CMP AL,CHAR_RUBOUT | ||
| 287 | JAE NOPRT ; Don't print RUBOUT or above | ||
| 288 | |||
| 289 | CMP AL,CHAR_BLANK | ||
| 290 | JAE PRIN ; print space through RUBOUT-1 | ||
| 291 | |||
| 292 | NOPRT: | ||
| 293 | MOV AL,CHAR_PERIOD ; If unprintable character | ||
| 294 | PRIN: | ||
| 295 | STOSB | ||
| 296 | LOOP ASCDMP ; CX times | ||
| 297 | MOV AL,0 | ||
| 298 | STOSB | ||
| 299 | PUSH DS | ||
| 300 | PUSH CS | ||
| 301 | POP DS | ||
| 302 | ASSUME DS:DG | ||
| 303 | |||
| 304 | CALL HEX_ADDRESS_STR | ||
| 305 | |||
| 306 | CALL CRLF | ||
| 307 | |||
| 308 | POP DS | ||
| 309 | ASSUME DS:NOTHING | ||
| 310 | |||
| 311 | POP CX ; Restore overall dump len | ||
| 312 | MOV WORD PTR [DEFDUMP],SI | ||
| 313 | MOV WORD PTR [DEFDUMP+WORD],DS ; Save last address as def | ||
| 314 | RET | ||
| 315 | |||
| 316 | ASSUME DS:DG | ||
| 317 | ; Block move one area of memory to another Overlapping moves are performed | ||
| 318 | ; correctly, i.e., so that a source byte is not overwritten until after it has | ||
| 319 | ; been moved. | ||
| 320 | MOVE: | ||
| 321 | CALL DSRANGE ; Get range of source area | ||
| 322 | |||
| 323 | PUSH CX ; Save length | ||
| 324 | PUSH AX ; Save segment | ||
| 325 | PUSH DX ; Save source displacement | ||
| 326 | CALL ADDRESS ; Get destination address (sam | ||
| 327 | |||
| 328 | CALL GETEOL ; Check for errors | ||
| 329 | |||
| 330 | POP SI | ||
| 331 | MOV DI,DX ; Set dest. displacement | ||
| 332 | POP BX ; Source segment | ||
| 333 | MOV DS,BX | ||
| 334 | MOV ES,AX ; Destination segment | ||
| 335 | POP CX ; Length | ||
| 336 | CMP DI,SI ; Check direction of move | ||
| 337 | SBB AX,BX ; Extend the CMP to 32 bits | ||
| 338 | JB COPYLIST ; Move forward into lower mem. | ||
| 339 | |||
| 340 | ; Otherwise, move backward. Figure end of source and destination | ||
| 341 | ; areas and flip direction flag. | ||
| 342 | DEC CX | ||
| 343 | ADD SI,CX ; End of source area | ||
| 344 | ADD DI,CX ; End of destination area | ||
| 345 | STD ; Reverse direction | ||
| 346 | INC CX | ||
| 347 | COPYLIST: | ||
| 348 | MOVSB ; Do at least 1 - Range is 1-1 | ||
| 349 | DEC CX | ||
| 350 | REP MOVSB ; Block move | ||
| 351 | RET1: | ||
| 352 | RET | ||
| 353 | |||
| 354 | ; Fill an area of memory with a list values. If the list | ||
| 355 | ; is bigger than the area, don't use the whole list. If the | ||
| 356 | ; list is smaller, repeat it as many times as necessary. | ||
| 357 | FILL: | ||
| 358 | CALL DSRANGE ; Get range to fill | ||
| 359 | |||
| 360 | PUSH CX ; Save length | ||
| 361 | PUSH AX ; Save segment number | ||
| 362 | PUSH DX ; Save displacement | ||
| 363 | CALL LIST ; Get list of values to fill w | ||
| 364 | |||
| 365 | POP DI ; Displacement in segment | ||
| 366 | POP ES ; Segment | ||
| 367 | POP CX ; Length | ||
| 368 | CMP BX,CX ; BX is length of fill list | ||
| 369 | MOV SI,OFFSET DG:BYTEBUF ; List is in byte buffer | ||
| 370 | JCXZ BIGRNG | ||
| 371 | |||
| 372 | JAE COPYLIST ; If list is big, copy part of | ||
| 373 | |||
| 374 | BIGRNG: | ||
| 375 | SUB CX,BX ; How much bigger is area than | ||
| 376 | XCHG CX,BX ; CX=length of list | ||
| 377 | PUSH DI ; Save starting addr. of area | ||
| 378 | REP MOVSB ; Move list into area | ||
| 379 | POP SI | ||
| 380 | ; The list has been copied into the beginning of the | ||
| 381 | ; specified area of memory. SI is the first address | ||
| 382 | ; of that area, DI is the end of the copy of the list | ||
| 383 | ; plus one, which is where the list will begin to repeat. | ||
| 384 | ; All we need to do now is copy [SI] to [DI] until the | ||
| 385 | ; end of the memory area is reached. This will cause the | ||
| 386 | ; list to repeat as many times as necessary. | ||
| 387 | MOV CX,BX ; Length of area minus list | ||
| 388 | PUSH ES ; Different index register | ||
| 389 | POP DS ; requires different segment r | ||
| 390 | JMP SHORT COPYLIST ; Do the block move | ||
| 391 | |||
| 392 | ; Search a specified area of memory for given list of bytes. | ||
| 393 | ; Print address of first byte of each match. | ||
| 394 | SEARCH: | ||
| 395 | CALL DSRANGE ; Get area to be searched | ||
| 396 | |||
| 397 | PUSH CX ; Save count | ||
| 398 | PUSH AX ; Save segment number | ||
| 399 | PUSH DX ; Save displacement | ||
| 400 | CALL LIST ; Get search list | ||
| 401 | |||
| 402 | DEC BX ; No. of bytes in list-1 | ||
| 403 | POP DI ; Displacement within segment | ||
| 404 | POP ES ; Segment | ||
| 405 | POP CX ; Length to be searched | ||
| 406 | SUB CX,BX ; minus length of list | ||
| 407 | SCAN: | ||
| 408 | MOV SI,OFFSET DG:BYTEBUF ; List kept in byte buffer | ||
| 409 | LODSB ; Bring first byte into AL | ||
| 410 | DOSCAN: | ||
| 411 | SCASB ; Search for first byte | ||
| 412 | LOOPNE DOSCAN ; Do at least once by using LO | ||
| 413 | |||
| 414 | JNZ RET1 ; Exit if not found | ||
| 415 | |||
| 416 | PUSH BX ; Length of list minus 1 | ||
| 417 | XCHG BX,CX | ||
| 418 | PUSH DI ; Will resume search here | ||
| 419 | REPE CMPSB ; Compare rest of string | ||
| 420 | MOV CX,BX ; Area length back in CX | ||
| 421 | POP DI ; Next search location | ||
| 422 | POP BX ; Restore list length | ||
| 423 | JNZ TTEST ; Continue search if no match | ||
| 424 | |||
| 425 | DEC DI ; Match address | ||
| 426 | CALL OUTDI ; Print it | ||
| 427 | |||
| 428 | INC DI ; Restore search address | ||
| 429 | CALL HEX_ADDRESS_ONLY ; Print the addresss | ||
| 430 | |||
| 431 | CALL CRLF | ||
| 432 | |||
| 433 | TTEST: | ||
| 434 | JCXZ RET1 | ||
| 435 | |||
| 436 | JMP SHORT SCAN ; Look for next occurrence | ||
| 437 | |||
| 438 | ; Get the next parameter, which must be a hex number. | ||
| 439 | ; CX is maximum number of digits the number may have. | ||
| 440 | |||
| 441 | ;========================================================================= | ||
| 442 | ; GETHX: This routine calculates the binary representation of an address | ||
| 443 | ; entered in ASCII by a user. GETHX has been modified to provide | ||
| 444 | ; support for sector addresses > 32mb. To do this the bx register | ||
| 445 | ; has been added to provide a 32 bit address. BX is the high word | ||
| 446 | ; and DX is the low word. For routines that rely on DX for a 16 | ||
| 447 | ; bit address, the use of BX will have no effect. | ||
| 448 | ; | ||
| 449 | ; Date : 6/16/87 | ||
| 450 | ;========================================================================= | ||
| 451 | |||
| 452 | GETHX: | ||
| 453 | CALL SCANP | ||
| 454 | GETHX1: | ||
| 455 | XOR DX,DX ; Initialize the number | ||
| 456 | xor bx,bx ;an000;initialize high word for | ||
| 457 | ; sector address | ||
| 458 | CALL HEXIN ; Get a hex digit | ||
| 459 | |||
| 460 | JC HXERR ; Must be one valid digit | ||
| 461 | |||
| 462 | MOV DL,AL ; First 4 bits in position | ||
| 463 | GETLP: | ||
| 464 | INC SI ; Next char in buffer | ||
| 465 | DEC CX ; Digit count | ||
| 466 | CALL HEXIN ; Get another hex digit? | ||
| 467 | |||
| 468 | JC RETHX ; All done if no more digits | ||
| 469 | |||
| 470 | STC | ||
| 471 | JCXZ HXERR ; Too many digits? | ||
| 472 | |||
| 473 | |||
| 474 | call ADDRESS_32_BIT ;an000;multiply by 32 | ||
| 475 | JMP SHORT GETLP ; Get more digits | ||
| 476 | |||
| 477 | GETHEX: | ||
| 478 | CALL GETHX ; Scan to next parameter | ||
| 479 | |||
| 480 | JMP SHORT GETHX2 | ||
| 481 | |||
| 482 | GETHEX1: | ||
| 483 | CALL GETHX1 | ||
| 484 | GETHX2: | ||
| 485 | JC PERROR | ||
| 486 | RETHX: | ||
| 487 | CLC | ||
| 488 | HXERR: | ||
| 489 | RET | ||
| 490 | |||
| 491 | ; Check if next character in the input buffer is a hex digit | ||
| 492 | ; and convert it to binary if it is. Carry set if not. | ||
| 493 | HEXIN: | ||
| 494 | MOV AL,[SI] | ||
| 495 | ; Check if AL is a hex digit and convert it to binary if it | ||
| 496 | ; is. Carry set if not. | ||
| 497 | HEXCHK: | ||
| 498 | SUB AL,CHAR_ZERO ; Kill ASCII numeric bias | ||
| 499 | JC RET2 | ||
| 500 | |||
| 501 | CMP AL,10 | ||
| 502 | CMC | ||
| 503 | JNC RET2 ; OK if 0-9 | ||
| 504 | |||
| 505 | AND AL,5FH | ||
| 506 | SUB AL,7 ; Kill A-F bias | ||
| 507 | CMP AL,10 | ||
| 508 | JC RET2 | ||
| 509 | |||
| 510 | CMP AL,16 | ||
| 511 | CMC | ||
| 512 | RET2: | ||
| 513 | RET | ||
| 514 | |||
| 515 | ; Process one parameter when a list of bytes is | ||
| 516 | ; required. Carry set if parameter bad. Called by LIST. | ||
| 517 | LISTITEM: | ||
| 518 | CALL SCANP ; Scan to parameter | ||
| 519 | |||
| 520 | CALL HEXIN ; Is it in hex? | ||
| 521 | |||
| 522 | JC STRINGCHK ; If not, could be a string | ||
| 523 | |||
| 524 | MOV CX,2 ; Only 2 hex digits for bytes | ||
| 525 | push bx ;an000;save it - we stomp it | ||
| 526 | CALL GETHEX ; Get the byte value | ||
| 527 | pop bx ;an000;restore it | ||
| 528 | |||
| 529 | MOV [BX],DL ; Add to list | ||
| 530 | INC BX | ||
| 531 | GRET: | ||
| 532 | CLC ; Parameter was OK | ||
| 533 | RET | ||
| 534 | |||
| 535 | STRINGCHK: | ||
| 536 | MOV AL,[SI] ; Get first character of param | ||
| 537 | CMP AL,SINGLE_QUOTE ; String? | ||
| 538 | JZ STRING | ||
| 539 | |||
| 540 | CMP AL,DOUBLE_QUOTE ; Either quote is all right | ||
| 541 | JZ STRING | ||
| 542 | |||
| 543 | STC ; Not string, not hex - bad | ||
| 544 | RET | ||
| 545 | STRING: | ||
| 546 | MOV AH,AL ; Save for closing quote | ||
| 547 | INC SI | ||
| 548 | STRNGLP: | ||
| 549 | LODSB ; Next char of string | ||
| 550 | CMP AL,CR ; Check for end of line | ||
| 551 | JZ PERR ; Must find a close quote | ||
| 552 | |||
| 553 | CMP AL,AH ; Check for close quote | ||
| 554 | JNZ STOSTRG ; Add new character to list | ||
| 555 | |||
| 556 | CMP AH,[SI] ; Two quotes in a row? | ||
| 557 | JNZ GRET ; If not, we're done | ||
| 558 | |||
| 559 | INC SI ; Yes - skip second one | ||
| 560 | STOSTRG: | ||
| 561 | MOV [BX],AL ; Put new char in list | ||
| 562 | INC BX | ||
| 563 | JMP SHORT STRNGLP ; Get more characters | ||
| 564 | |||
| 565 | ; Get a byte list for ENTER, FILL or SEARCH. Accepts any number | ||
| 566 | ; of 2-digit hex values or character strings in either single | ||
| 567 | ; (') or double (") quotes. | ||
| 568 | LIST: | ||
| 569 | MOV BX,OFFSET DG:BYTEBUF ; Put byte list in the byte buffer | ||
| 570 | LISTLP: | ||
| 571 | CALL LISTITEM ; Process a parameter | ||
| 572 | |||
| 573 | JNC LISTLP ; If OK, try for more | ||
| 574 | |||
| 575 | SUB BX,OFFSET DG:BYTEBUF ; BX now has no. of bytes in list | ||
| 576 | JZ PERROR ; List must not be empty | ||
| 577 | |||
| 578 | ; Make sure there is nothing more on the line except for | ||
| 579 | ; blanks and carriage return. If there is, it is an | ||
| 580 | ; unrecognized parameter and an error. | ||
| 581 | GETEOL: | ||
| 582 | CALL SCANB ; Skip blanks | ||
| 583 | |||
| 584 | JNZ PERROR ; Better be a RETURN | ||
| 585 | RET3: | ||
| 586 | RET | ||
| 587 | |||
| 588 | ; Command error. SI has been incremented beyond the command letter so it must | ||
| 589 | ; decremented for the error pointer to work. | ||
| 590 | PERR: | ||
| 591 | DEC SI | ||
| 592 | ; Syntax error. SI points to character in the input buffer which caused | ||
| 593 | ; error. By subtracting from start of buffer, we will know how far to tab | ||
| 594 | ; over to appear directly below it on the terminal. Then print "^ Error". | ||
| 595 | PERROR: | ||
| 596 | SUB SI,OFFSET DG:(BYTEBUF-1) ; How many char processed so far? | ||
| 597 | MOV CX,SI ; Parameter for TAB in CX | ||
| 598 | MOV DI,OFFSET DG:ARG_BUF ; | ||
| 599 | CALL TAB ; Directly below bad char | ||
| 600 | |||
| 601 | MOV BYTE PTR [DI],0 ; nul terminate the tab | ||
| 602 | MOV DX,OFFSET DG:SYNERR_PTR ; Error message | ||
| 603 | ; Print error message and abort to command level | ||
| 604 | PRINT: | ||
| 605 | CALL PRINTF_CRLF | ||
| 606 | |||
| 607 | JMP COMMAND | ||
| 608 | |||
| 609 | ; Gets an address in Segment:Displacement format. Segment may be omitted | ||
| 610 | ; and a default (kept in BP) will be used, or it may be a segment | ||
| 611 | ; register (DS, ES, SS, CS). Returns with segment in AX, OFFSET in DX. | ||
| 612 | ADDRESS: | ||
| 613 | CALL GET_ADDRESS | ||
| 614 | |||
| 615 | JC PERROR | ||
| 616 | |||
| 617 | ADRERR: | ||
| 618 | STC | ||
| 619 | RET | ||
| 620 | |||
| 621 | GET_ADDRESS: | ||
| 622 | CALL SCANP | ||
| 623 | |||
| 624 | MOV AL,[SI+1] | ||
| 625 | CMP AL,UPPER_S | ||
| 626 | JZ SEGREG | ||
| 627 | |||
| 628 | MOV CX,4 | ||
| 629 | CALL GETHX | ||
| 630 | |||
| 631 | JC ADRERR | ||
| 632 | |||
| 633 | MOV AX,BP ; Get default segment | ||
| 634 | CMP BYTE PTR [SI],CHAR_COLON | ||
| 635 | JNZ GETRET | ||
| 636 | |||
| 637 | PUSH DX | ||
| 638 | GETDISP: | ||
| 639 | INC SI ; Skip over ":" | ||
| 640 | MOV CX,4 | ||
| 641 | CALL GETHX | ||
| 642 | |||
| 643 | POP AX | ||
| 644 | JC ADRERR | ||
| 645 | |||
| 646 | GETRET: | ||
| 647 | CLC | ||
| 648 | RET | ||
| 649 | |||
| 650 | SEGREG: | ||
| 651 | MOV AL,[SI] | ||
| 652 | MOV DI,OFFSET DG:SEGLET ; SEGLET DB "CSED" | ||
| 653 | MOV CX,4 | ||
| 654 | REPNE SCASB | ||
| 655 | JNZ ADRERR | ||
| 656 | |||
| 657 | INC SI | ||
| 658 | INC SI | ||
| 659 | SHL CX,1 | ||
| 660 | MOV BX,CX | ||
| 661 | CMP BYTE PTR [SI],CHAR_COLON | ||
| 662 | JNZ ADRERR | ||
| 663 | |||
| 664 | PUSH [BX+DSSAVE] | ||
| 665 | JMP SHORT GETDISP | ||
| 666 | |||
| 667 | SEGLET DB "CSED" ; First letter of each of the segregs: CS,SS,ES,DS | ||
| 668 | |||
| 669 | ; Short form of ENTER command. A list of values from the | ||
| 670 | ; command line are put into memory without using normal | ||
| 671 | ; ENTER mode. | ||
| 672 | GETLIST: | ||
| 673 | CALL LIST ; Get the bytes to enter | ||
| 674 | |||
| 675 | POP DI ; Displacement within segment | ||
| 676 | POP ES ; Segment to enter into | ||
| 677 | MOV SI,OFFSET DG:BYTEBUF ; List of bytes is in byte buffer | ||
| 678 | MOV CX,BX ; Count of bytes | ||
| 679 | REP MOVSB ; Enter that byte list | ||
| 680 | RET | ||
| 681 | |||
| 682 | ; Enter values into memory at a specified address. If the line contains | ||
| 683 | ; nothing but the address we go into "enter mode", where the address and its | ||
| 684 | ; current value are printed and the user may change it if desired. To change, | ||
| 685 | ; type in new value in hex. Backspace works to correct errors. If an illegal | ||
| 686 | ; hex digit or too many digits are typed, the bell is sounded but it is | ||
| 687 | ; otherwise ignored. To go to the next byte (with or without change), hit | ||
| 688 | ; space bar. To back CLDto a previous address, type "-". On every 8-byte | ||
| 689 | ; boundary a new line is started and the address is printed. To terminate | ||
| 690 | ; command, type carriage return. | ||
| 691 | ; Alternatively, the list of bytes to be entered may be included on the | ||
| 692 | ; original command line immediately following the address. This is in regular | ||
| 693 | ; LIST format so any number of hex values or strings in quotes may be entered. | ||
| 694 | ENTERDATA: | ||
| 695 | MOV BP,[DSSAVE] ; Set default segment to DS | ||
| 696 | CALL ADDRESS | ||
| 697 | |||
| 698 | PUSH AX ; Save for later | ||
| 699 | PUSH DX | ||
| 700 | CALL SCANB ; Any more parameters? | ||
| 701 | |||
| 702 | JNZ GETLIST ; If not end-of-line get list | ||
| 703 | |||
| 704 | POP DI ; Displacement of ENTER | ||
| 705 | POP ES ; Segment | ||
| 706 | GETROW: | ||
| 707 | CALL OUTDI ; Print address of entry | ||
| 708 | |||
| 709 | PUSH DI | ||
| 710 | PUSH ES | ||
| 711 | PUSH DS | ||
| 712 | POP ES | ||
| 713 | MOV DI,OFFSET DG:ARG_BUF | ||
| 714 | CALL BLANK | ||
| 715 | |||
| 716 | XOR AL,AL | ||
| 717 | STOSB | ||
| 718 | CALL HEX_ADDRESS_STR | ||
| 719 | |||
| 720 | POP ES | ||
| 721 | POP DI | ||
| 722 | GETBYTE: | ||
| 723 | MOV AL,ES:[DI] ; Get current value | ||
| 724 | PUSH DI | ||
| 725 | PUSH ES | ||
| 726 | PUSH DS | ||
| 727 | POP ES | ||
| 728 | MOV DI,OFFSET DG:ARG_BUF | ||
| 729 | CALL HEX ; And display it | ||
| 730 | |||
| 731 | MOV AL,CHAR_PERIOD | ||
| 732 | STOSB | ||
| 733 | XOR AL,AL | ||
| 734 | STOSB | ||
| 735 | MOV DX,OFFSET DG:ARG_BUF_PTR | ||
| 736 | CALL STD_PRINTF | ||
| 737 | |||
| 738 | POP ES | ||
| 739 | POP DI | ||
| 740 | LOOK_AGAIN: | ||
| 741 | MOV CX,2 ; Max of 2 digits in new value | ||
| 742 | MOV DX,0 ; Intial new value | ||
| 743 | GETDIG: | ||
| 744 | CALL INPT ; Get digit from user | ||
| 745 | |||
| 746 | MOV AH,AL ; Save | ||
| 747 | CALL HEXCHK ; Hex digit? | ||
| 748 | |||
| 749 | XCHG AH,AL ; Need original for echo | ||
| 750 | JC NOHEX ; If not, try special command | ||
| 751 | |||
| 752 | MOV DH,DL ; Rotate new value | ||
| 753 | MOV DL,AH ; And include new digit | ||
| 754 | LOOP GETDIG ; At most 2 digits | ||
| 755 | |||
| 756 | ; We have two digits, so all we will accept now is a command. | ||
| 757 | DWAIT: | ||
| 758 | CALL INPT ; Get command character | ||
| 759 | NOHEX: | ||
| 760 | CMP AL,CHAR_BACKSPACE ; Backspace | ||
| 761 | JZ BS | ||
| 762 | |||
| 763 | CMP AL,CHAR_RUBOUT ; RUBOUT | ||
| 764 | JZ RUB | ||
| 765 | |||
| 766 | CMP AL,CHAR_MINUS ; Back up to previous address | ||
| 767 | JZ PREV | ||
| 768 | |||
| 769 | CMP AL,CR ; All done with command? | ||
| 770 | JZ EOL | ||
| 771 | |||
| 772 | CMP AL,CHAR_BLANK ; Go to next address | ||
| 773 | JZ NEXT | ||
| 774 | |||
| 775 | MOV AL,CHAR_BACKSPACE | ||
| 776 | CALL OUT_CHAR ; Back up over illegal character | ||
| 777 | |||
| 778 | CALL BACKUP | ||
| 779 | |||
| 780 | JCXZ DWAIT | ||
| 781 | |||
| 782 | JMP SHORT GETDIG | ||
| 783 | |||
| 784 | RUB: | ||
| 785 | MOV AL,CHAR_BACKSPACE | ||
| 786 | CALL OUT_char | ||
| 787 | BS: | ||
| 788 | CMP CL,2 ; CX=2 means nothing typed yet | ||
| 789 | JZ PUTDOT ; Put back the dot we backed up over | ||
| 790 | |||
| 791 | INC CL ; Accept one more character | ||
| 792 | MOV DL,DH ; Rotate out last digit | ||
| 793 | MOV DH,CH ; Zero this digit | ||
| 794 | CALL BACKUP ; Physical backspace | ||
| 795 | |||
| 796 | JMP SHORT GETDIG ; Get more digits | ||
| 797 | |||
| 798 | PUTDOT: | ||
| 799 | MOV AL,CHAR_PERIOD | ||
| 800 | CALL OUT_CHAR | ||
| 801 | |||
| 802 | JMP LOOK_AGAIN | ||
| 803 | |||
| 804 | ; If new value has been entered, convert it to binary and | ||
| 805 | ; put into memory. Always bump pointer to next location | ||
| 806 | STORE: | ||
| 807 | CMP CL,2 ; CX=2 means nothing typed yet | ||
| 808 | JZ NOSTO ; So no new value to store | ||
| 809 | |||
| 810 | ; Rotate DH left 4 bits to combine with DL and make a byte value | ||
| 811 | PUSH CX | ||
| 812 | MOV CL,4 | ||
| 813 | SHL DH,CL | ||
| 814 | POP CX | ||
| 815 | OR DL,DH ; Hex is now converted to binary | ||
| 816 | MOV ES:[DI],DL ; Store new value | ||
| 817 | NOSTO: | ||
| 818 | INC DI ; Prepare for next location | ||
| 819 | RET | ||
| 820 | |||
| 821 | NEXT: | ||
| 822 | CALL STORE ; Enter new value | ||
| 823 | |||
| 824 | INC CX ; Leave a space plus two for | ||
| 825 | INC CX ; each digit not entered | ||
| 826 | PUSH DI | ||
| 827 | MOV DI,OFFSET DG:ARG_BUF | ||
| 828 | PUSH ES | ||
| 829 | PUSH DS | ||
| 830 | POP ES | ||
| 831 | CALL TAB | ||
| 832 | |||
| 833 | XOR AL,AL | ||
| 834 | STOSB | ||
| 835 | MOV DX,OFFSET DG:ARG_BUF_PTR | ||
| 836 | CALL STD_PRINTF | ||
| 837 | |||
| 838 | POP ES | ||
| 839 | POP DI | ||
| 840 | MOV AX,DI ; Next memory address | ||
| 841 | AND AL,7 ; Check for 8-byte boundary | ||
| 842 | JZ NEWROW ; Take 8 per line | ||
| 843 | |||
| 844 | JMP GETBYTE | ||
| 845 | |||
| 846 | NEWROW: | ||
| 847 | CALL CRLF ; Terminate line | ||
| 848 | |||
| 849 | JMP GETROW ; Print address on new line | ||
| 850 | |||
| 851 | PREV: | ||
| 852 | CALL STORE ; Enter the new value | ||
| 853 | |||
| 854 | ; DI has been bumped to next byte. Drop it 2 to go to previous addr | ||
| 855 | DEC DI | ||
| 856 | DEC DI | ||
| 857 | JMP SHORT NEWROW ; Terminate line after backing CLD | ||
| 858 | |||
| 859 | EOL: | ||
| 860 | CALL STORE ; Enter the new value | ||
| 861 | |||
| 862 | JMP CRLF ; CR/LF and terminate | ||
| 863 | |||
| 864 | ; Console input of single character | ||
| 865 | IF SYSVER | ||
| 866 | INPT: ;*** change for build - label to inpt | ||
| 867 | PUSH DS | ||
| 868 | PUSH SI | ||
| 869 | LDS SI,CS:[CIN] | ||
| 870 | MOV AH,4 | ||
| 871 | CALL DEVIOCALL | ||
| 872 | |||
| 873 | POP SI | ||
| 874 | POP DS | ||
| 875 | CMP AL,3 | ||
| 876 | JNZ NOTCNTC | ||
| 877 | |||
| 878 | INT VEC_CTRL_BREAK ;23H | ||
| 879 | |||
| 880 | NOTCNTC: | ||
| 881 | CMP AL,UPPER_P - CHAR_AT_SIGN | ||
| 882 | JZ PRINTON | ||
| 883 | |||
| 884 | CMP AL,UPPER_N - CHAR_AT_SIGN | ||
| 885 | JZ PRINTOFF | ||
| 886 | |||
| 887 | CALL OUT_CHAR | ||
| 888 | |||
| 889 | RET | ||
| 890 | |||
| 891 | PRINTOFF: | ||
| 892 | PRINTON: | ||
| 893 | NOT [PFLAG] | ||
| 894 | JMP SHORT IN | ||
| 895 | |||
| 896 | ELSE | ||
| 897 | INPT: ; Change label for build | ||
| 898 | MOV AH,Std_Con_Input ;OPTION=1, STANDARD CONSOLE INPUT | ||
| 899 | INT 21H | ||
| 900 | |||
| 901 | RET | ||
| 902 | |||
| 903 | ENDIF | ||
| 904 | OUT_CHAR: | ||
| 905 | PUSH DI | ||
| 906 | PUSH DX | ||
| 907 | PUSH ES | ||
| 908 | PUSH DS | ||
| 909 | POP ES | ||
| 910 | MOV DI,OFFSET DG:ONE_CHAR_BUF | ||
| 911 | STOSB | ||
| 912 | MOV AL,0 | ||
| 913 | STOSB | ||
| 914 | MOV DX,OFFSET DG:ONE_CHAR_BUF_PTR | ||
| 915 | CALL STD_PRINTF | ||
| 916 | |||
| 917 | POP ES | ||
| 918 | POP DX | ||
| 919 | POP DI | ||
| 920 | RET | ||
| 921 | |||
| 922 | ;========================================================================= | ||
| 923 | ; ADDRESS_32_BIT: This routine will build an address for 32bit sector | ||
| 924 | ; addressibility. BX will be the high word, with DX being | ||
| 925 | ; the low word. | ||
| 926 | ; | ||
| 927 | ; Inputs : DX/BX - registers to contain 32bit sector address | ||
| 928 | ; DX & BX are both initialized to 0 on first call to routine. | ||
| 929 | ; | ||
| 930 | ; Outputs: DX/BX - registers to contain 32bit sector address | ||
| 931 | ; | ||
| 932 | ; Date : 6/16/87 | ||
| 933 | ;========================================================================= | ||
| 934 | |||
| 935 | ADDRESS_32_BIT proc near ;an000;perform 32 bit address | ||
| 936 | ; creation | ||
| 937 | push cx ;an000;save affected regs. | ||
| 938 | mov cx,04h ;an000;initialize to | ||
| 939 | ; nibble shift | ||
| 940 | ; $do ;an000;while cx not= 0 | ||
| 941 | $$DO1: | ||
| 942 | cmp cx,00h ;an000;are we done? | ||
| 943 | ; $leave e ;an000;yes, quit loop | ||
| 944 | JE $$EN1 | ||
| 945 | shl bx,1 ;an000;shift bx 1 bit | ||
| 946 | shl dx,1 ;an000;shift dx 1 bit | ||
| 947 | ; $if c ;an000;did low word carry | ||
| 948 | JNC $$IF3 | ||
| 949 | or bx,01h ;an000;set bit 0 of high word | ||
| 950 | ; $endif ;an000; | ||
| 951 | $$IF3: | ||
| 952 | dec cx ;an000;decrease counter | ||
| 953 | ; $enddo ;an000;end while loop | ||
| 954 | JMP SHORT $$DO1 | ||
| 955 | $$EN1: | ||
| 956 | or dl, al ;an000;overlay low word | ||
| 957 | ; bits 0-3 with next | ||
| 958 | ; portion of the address | ||
| 959 | pop cx ;an000;restore affected regs. | ||
| 960 | |||
| 961 | ret ;an000;return to caller | ||
| 962 | |||
| 963 | ADDRESS_32_BIT endp ;an000;end proc | ||
| 964 | |||
| 965 | |||
| 966 | |||
| 967 | CODE ENDS | ||
| 968 | END DEBCOM1 | ||
| 969 | \ No newline at end of file | ||