diff options
Diffstat (limited to 'v2.0/source/DEBUG.ASM')
| -rw-r--r-- | v2.0/source/DEBUG.ASM | 838 |
1 files changed, 838 insertions, 0 deletions
diff --git a/v2.0/source/DEBUG.ASM b/v2.0/source/DEBUG.ASM new file mode 100644 index 0000000..91db1ca --- /dev/null +++ b/v2.0/source/DEBUG.ASM | |||
| @@ -0,0 +1,838 @@ | |||
| 1 | TITLE DEBUGger for MS-DOS | ||
| 2 | ; DEBUG-86 8086 debugger runs under 86-DOS version 2.30 | ||
| 3 | ; | ||
| 4 | ; Modified 5/4/82 by AaronR to do all I/O direct to devices | ||
| 5 | ; Runs on MS-DOS 1.28 and above | ||
| 6 | ; REV 1.20 | ||
| 7 | ; Tab expansion | ||
| 8 | ; New device interface (1.29 and above) | ||
| 9 | ; REV 2.0 | ||
| 10 | ; line by line assembler added by C. Peters | ||
| 11 | ; REV 2.1 | ||
| 12 | ; Uses EXEC system call | ||
| 13 | ; REV 2.2 | ||
| 14 | ; Ztrace mode by zibo. | ||
| 15 | ; Fix dump display to indent properly | ||
| 16 | ; Parity nonsense by zibo | ||
| 17 | ; | ||
| 18 | ; REV 2.3 | ||
| 19 | ; Split into seperate modules to allow for | ||
| 20 | ; assembly on an IBM PC | ||
| 21 | ; | ||
| 22 | |||
| 23 | |||
| 24 | |||
| 25 | .xlist | ||
| 26 | .xcref | ||
| 27 | INCLUDE DEBEQU.ASM | ||
| 28 | INCLUDE DOSSYM.ASM | ||
| 29 | .cref | ||
| 30 | .list | ||
| 31 | |||
| 32 | IF SYSVER | ||
| 33 | |||
| 34 | ; Structure for system call 72 | ||
| 35 | |||
| 36 | SYSINITVAR STRUC | ||
| 37 | DPBHEAD DD ? ; Pointer to head of DPB-FAT list | ||
| 38 | sft_addr DD ? ; Pointer to first FCB table | ||
| 39 | ; The following address points to the CLOCK device | ||
| 40 | BCLOCK DD ? | ||
| 41 | ; The following address is used by DISKSTATCHK it is always | ||
| 42 | ; points to the console input device header | ||
| 43 | BCON DD ? ; Console device entry points | ||
| 44 | NUMIO DB 0 ; Number of disk tables | ||
| 45 | MAXSEC DW 0 ; Maximum allowed sector size | ||
| 46 | BUFFHEAD DD ? | ||
| 47 | DEVHEAD DD ? | ||
| 48 | SYSINITVAR ENDS | ||
| 49 | |||
| 50 | ENDIF | ||
| 51 | |||
| 52 | |||
| 53 | CODE SEGMENT PUBLIC 'CODE' | ||
| 54 | CODE ENDS | ||
| 55 | |||
| 56 | CONST SEGMENT PUBLIC BYTE | ||
| 57 | |||
| 58 | EXTRN USER_PROC_PDB:WORD,STACK:BYTE,CSSAVE:WORD,DSSAVE:WORD | ||
| 59 | EXTRN SPSAVE:WORD,IPSAVE:WORD,LINEBUF:BYTE,QFLAG:BYTE | ||
| 60 | EXTRN NEWEXEC:BYTE,HEADSAVE:WORD,LBUFSIZ:BYTE,BACMES:BYTE | ||
| 61 | EXTRN BADVER:BYTE,ENDMES:BYTE,CARRET:BYTE,ParityMes:BYTE | ||
| 62 | |||
| 63 | IF IBMVER | ||
| 64 | EXTRN DSIZ:BYTE,NOREGL:BYTE,DISPB:WORD | ||
| 65 | ENDIF | ||
| 66 | |||
| 67 | IF SYSVER | ||
| 68 | EXTRN CONFCB:BYTE,POUT:DWORD,COUT:DWORD,CIN:DWORD,IOBUFF:BYTE | ||
| 69 | EXTRN IOADDR:DWORD,IOCALL:BYTE,IOCOM:BYTE,IOSTAT:WORD,IOCNT:WORD | ||
| 70 | EXTRN IOSEG:WORD,COLPOS:BYTE,BADDEV:BYTE,BADLSTMES:BYTE | ||
| 71 | EXTRN LBUFFCNT:BYTE,PFLAG:BYTE | ||
| 72 | ENDIF | ||
| 73 | |||
| 74 | CONST ENDS | ||
| 75 | |||
| 76 | DATA SEGMENT PUBLIC BYTE | ||
| 77 | |||
| 78 | EXTRN PARSERR:BYTE,DATAEND:WORD,ParityFlag:BYTE,DISADD:BYTE | ||
| 79 | EXTRN ASMADD:BYTE,DEFDUMP:BYTE,BYTEBUF:BYTE | ||
| 80 | |||
| 81 | DATA ENDS | ||
| 82 | |||
| 83 | DG GROUP CODE,CONST,DATA | ||
| 84 | |||
| 85 | |||
| 86 | CODE SEGMENT PUBLIC 'CODE' | ||
| 87 | ASSUME CS:DG,DS:DG,ES:DG,SS:DG | ||
| 88 | |||
| 89 | PUBLIC RESTART,SET_TERMINATE_VECTOR,DABORT,TERMINATE,COMMAND | ||
| 90 | PUBLIC FIND_DEBUG,CRLF,BLANK,TAB,OUT,INBUF,SCANB,SCANP | ||
| 91 | PUBLIC PRINTMES,RPRBUF,HEX,OUTSI,OUTDI,OUT16,DIGIT,BACKUP,RBUFIN | ||
| 92 | |||
| 93 | IF SYSVER | ||
| 94 | PUBLIC SETUDEV,DEVIOCALL | ||
| 95 | EXTRN DISPREG:NEAR,IN:NEAR | ||
| 96 | ENDIF | ||
| 97 | |||
| 98 | EXTRN PERR:NEAR,COMPARE:NEAR,DUMP:NEAR,ENTER:NEAR,FILL:NEAR | ||
| 99 | EXTRN GO:NEAR,INPUT:NEAR,LOAD:NEAR,MOVE:NEAR,NAME:NEAR | ||
| 100 | EXTRN REG:NEAR,SEARCH:NEAR,DWRITE:NEAR,UNASSEM:NEAR,ASSEM:NEAR | ||
| 101 | EXTRN OUTPUT:NEAR,ZTRACE:NEAR,TRACE:NEAR,GETHEX:NEAR,GETEOL:NEAR | ||
| 102 | |||
| 103 | EXTRN PREPNAME:NEAR,DEFIO:NEAR,SKIP_FILE:NEAR,DEBUG_FOUND:NEAR | ||
| 104 | EXTRN TrapParity:NEAR,ReleaseParity:NEAR | ||
| 105 | |||
| 106 | ORG 100H | ||
| 107 | |||
| 108 | START: | ||
| 109 | DEBUG: | ||
| 110 | JMP SHORT DSTRT | ||
| 111 | |||
| 112 | HEADER DB "Vers 2.30" | ||
| 113 | |||
| 114 | DSTRT: | ||
| 115 | DOSVER_HIGH EQU 0200H ; 2.00 in hex | ||
| 116 | MOV AH,GET_VERSION | ||
| 117 | INT 21H | ||
| 118 | XCHG AH,AL ; Turn it around to AH.AL | ||
| 119 | CMP AX,DOSVER_HIGH | ||
| 120 | JAE OKDOS | ||
| 121 | GOTBADDOS: | ||
| 122 | MOV DX,OFFSET DG:BADVER | ||
| 123 | MOV AH,STD_CON_STRING_OUTPUT | ||
| 124 | INT 21H | ||
| 125 | INT 20H | ||
| 126 | |||
| 127 | OKDOS: | ||
| 128 | CALL TrapParity ; scarf up those parity guys | ||
| 129 | MOV AH,GET_CURRENT_PDB | ||
| 130 | INT 21H | ||
| 131 | MOV [USER_PROC_PDB],BX ; Initially set to DEBUG | ||
| 132 | |||
| 133 | IF SYSVER | ||
| 134 | MOV [IOSEG],CS | ||
| 135 | ENDIF | ||
| 136 | |||
| 137 | MOV SP,OFFSET DG:STACK | ||
| 138 | MOV [PARSERR],AL | ||
| 139 | MOV AH,GET_IN_VARS | ||
| 140 | INT 21H | ||
| 141 | |||
| 142 | |||
| 143 | IF SYSVER | ||
| 144 | LDS SI,ES:[BX.BCON] | ||
| 145 | MOV WORD PTR CS:[CIN+2],DS | ||
| 146 | MOV WORD PTR CS:[CIN],SI | ||
| 147 | MOV WORD PTR CS:[COUT+2],DS | ||
| 148 | MOV WORD PTR CS:[COUT],SI | ||
| 149 | PUSH CS | ||
| 150 | POP DS | ||
| 151 | MOV DX,OFFSET DG:CONFCB | ||
| 152 | MOV AH,FCB_OPEN | ||
| 153 | INT 21H | ||
| 154 | OR AL,AL | ||
| 155 | JZ GOTLIST | ||
| 156 | MOV DX,OFFSET DG:BADLSTMES | ||
| 157 | CALL RPRBUF | ||
| 158 | CALL RBUFIN | ||
| 159 | CALL CRLF | ||
| 160 | MOV CL,[LBUFFCNT] | ||
| 161 | OR CL,CL | ||
| 162 | JZ NOLIST1 ; User didn't specify one | ||
| 163 | XOR CH,CH | ||
| 164 | MOV DI,OFFSET DG:(CONFCB + 1) | ||
| 165 | MOV SI,OFFSET DG:LINEBUF | ||
| 166 | REP MOVSB | ||
| 167 | MOV DX,OFFSET DG:CONFCB | ||
| 168 | MOV AH,FCB_OPEN | ||
| 169 | INT 21H | ||
| 170 | OR AL,AL | ||
| 171 | JZ GOTLIST ; GOOD | ||
| 172 | MOV DX,OFFSET DG:BADDEV | ||
| 173 | CALL RPRBUF | ||
| 174 | NOLIST1: | ||
| 175 | MOV WORD PTR [POUT+2],CS | ||
| 176 | MOV WORD PTR [POUT],OFFSET DG:LONGRET | ||
| 177 | JMP NOLIST | ||
| 178 | |||
| 179 | XXX PROC FAR | ||
| 180 | LONGRET:RET | ||
| 181 | XXX ENDP | ||
| 182 | ENDIF | ||
| 183 | |||
| 184 | GOTLIST: | ||
| 185 | IF SYSVER | ||
| 186 | MOV SI,DX | ||
| 187 | LDS SI,DWORD PTR DS:[SI.fcb_FIRCLUS] | ||
| 188 | MOV WORD PTR CS:[POUT+2],DS | ||
| 189 | MOV WORD PTR CS:[POUT],SI | ||
| 190 | ENDIF | ||
| 191 | NOLIST: | ||
| 192 | MOV AX,CS | ||
| 193 | MOV DS,AX | ||
| 194 | MOV ES,AX | ||
| 195 | |||
| 196 | ; Code to print header | ||
| 197 | ; MOV DX,OFFSET DG:HEADER | ||
| 198 | ; CALL RPRBUF | ||
| 199 | |||
| 200 | CALL SET_TERMINATE_VECTOR | ||
| 201 | |||
| 202 | IF SETCNTC | ||
| 203 | MOV AL,23H ; Set vector 23H | ||
| 204 | MOV DX,OFFSET DG:DABORT | ||
| 205 | INT 21H | ||
| 206 | ENDIF | ||
| 207 | |||
| 208 | MOV DX,CS ; Get DEBUG's segment | ||
| 209 | MOV AX,OFFSET DG:DATAEND + 15 ; End of debug | ||
| 210 | SHR AX,1 ; Convert to segments | ||
| 211 | SHR AX,1 | ||
| 212 | SHR AX,1 | ||
| 213 | SHR AX,1 | ||
| 214 | ADD DX,AX ; Add siz of debug in paragraphs | ||
| 215 | MOV AH,CREATE_PROCESS_DATA_BLOCK ; create program segment just after DEBUG | ||
| 216 | INT 21H | ||
| 217 | MOV AX,DX | ||
| 218 | MOV DI,OFFSET DG:DSSAVE | ||
| 219 | CLD | ||
| 220 | STOSW | ||
| 221 | STOSW | ||
| 222 | STOSW | ||
| 223 | STOSW | ||
| 224 | MOV WORD PTR [DISADD+2],AX | ||
| 225 | MOV WORD PTR [ASMADD+2],AX | ||
| 226 | MOV WORD PTR [DEFDUMP+2],AX | ||
| 227 | MOV AX,100H | ||
| 228 | MOV WORD PTR[DISADD],AX | ||
| 229 | MOV WORD PTR[ASMADD],AX | ||
| 230 | MOV WORD PTR [DEFDUMP],AX | ||
| 231 | MOV DS,DX | ||
| 232 | MOV ES,DX | ||
| 233 | MOV DX,80H | ||
| 234 | MOV AH,SET_DMA | ||
| 235 | INT 21H ; Set default DMA address to 80H | ||
| 236 | MOV AX,WORD PTR DS:[6] | ||
| 237 | MOV BX,AX | ||
| 238 | CMP AX,0FFF0H | ||
| 239 | PUSH CS | ||
| 240 | POP DS | ||
| 241 | JAE SAVSTK | ||
| 242 | MOV AX,WORD PTR DS:[6] | ||
| 243 | PUSH BX | ||
| 244 | MOV BX,OFFSET DG:DATAEND + 15 | ||
| 245 | AND BX,0FFF0H ; Size of DEBUG in bytes (rounded up to PARA) | ||
| 246 | SUB AX,BX | ||
| 247 | POP BX | ||
| 248 | SAVSTK: | ||
| 249 | PUSH BX | ||
| 250 | DEC AX | ||
| 251 | DEC AX | ||
| 252 | MOV BX,AX | ||
| 253 | MOV WORD PTR [BX],0 | ||
| 254 | POP BX | ||
| 255 | MOV SPSAVE,AX | ||
| 256 | DEC AH | ||
| 257 | MOV ES:WORD PTR [6],AX | ||
| 258 | SUB BX,AX | ||
| 259 | MOV CL,4 | ||
| 260 | SHR BX,CL | ||
| 261 | ADD ES:WORD PTR [8],BX | ||
| 262 | |||
| 263 | IF IBMVER | ||
| 264 | ; Get screen size and initialize display related variables | ||
| 265 | MOV AH,15 | ||
| 266 | INT 10H | ||
| 267 | CMP AH,40 | ||
| 268 | JNZ PARSCHK | ||
| 269 | MOV BYTE PTR DSIZ,7 | ||
| 270 | MOV BYTE PTR NOREGL,4 | ||
| 271 | MOV DISPB,64 | ||
| 272 | ENDIF | ||
| 273 | |||
| 274 | PARSCHK: | ||
| 275 | ; Copy rest of command line to test program's parameter area | ||
| 276 | MOV DI,FCB | ||
| 277 | MOV SI,81H | ||
| 278 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H | ||
| 279 | INT 21H | ||
| 280 | CALL SKIP_FILE ; Make sure si points to delimiter | ||
| 281 | CALL PREPNAME | ||
| 282 | PUSH CS | ||
| 283 | POP ES | ||
| 284 | FILECHK: | ||
| 285 | MOV DI,80H | ||
| 286 | CMP BYTE PTR ES:[DI],0 ; ANY STUFF FOUND? | ||
| 287 | JZ COMMAND ; NOPE | ||
| 288 | FILOOP: INC DI | ||
| 289 | CMP BYTE PTR ES:[DI],13 ; COMMAND LINE JUST SPACES? | ||
| 290 | JZ COMMAND | ||
| 291 | CMP BYTE PTR ES:[DI]," " | ||
| 292 | JZ FILOOP | ||
| 293 | CMP BYTE PTR ES:[DI],9 | ||
| 294 | JZ FILOOP | ||
| 295 | |||
| 296 | CALL DEFIO ; WELL READ IT IN | ||
| 297 | MOV AX,CSSAVE | ||
| 298 | MOV WORD PTR DISADD+2,AX | ||
| 299 | MOV WORD PTR ASMADD+2,AX | ||
| 300 | MOV AX,IPSAVE | ||
| 301 | MOV WORD PTR DISADD,AX | ||
| 302 | MOV WORD PTR ASMADD,AX | ||
| 303 | COMMAND: | ||
| 304 | CLD | ||
| 305 | MOV AX,CS | ||
| 306 | MOV DS,AX | ||
| 307 | MOV ES,AX | ||
| 308 | MOV SS,AX | ||
| 309 | MOV SP,OFFSET DG:STACK | ||
| 310 | STI | ||
| 311 | CMP [ParityFlag],0 ; did we detect a parity error? | ||
| 312 | JZ GoPrompt ; nope, go prompt | ||
| 313 | MOV [ParityFlag],0 ; reset flag | ||
| 314 | MOV DX,OFFSET DG:ParityMes ; message to print | ||
| 315 | MOV AH,STD_CON_STRING_OUTPUT; easy way out | ||
| 316 | INT 21h ; blam | ||
| 317 | GoPrompt: | ||
| 318 | MOV AL,PROMPT | ||
| 319 | CALL OUT | ||
| 320 | CALL INBUF ; Get command line | ||
| 321 | ; From now and throughout command line processing, DI points | ||
| 322 | ; to next character in command line to be processed. | ||
| 323 | CALL SCANB ; Scan off leading blanks | ||
| 324 | JZ COMMAND ; Null command? | ||
| 325 | LODSB ; AL=first non-blank character | ||
| 326 | ; Prepare command letter for table lookup | ||
| 327 | SUB AL,"A" ; Low end range check | ||
| 328 | JB ERR1 | ||
| 329 | CMP AL,"Z"-"A" ; Upper end range check | ||
| 330 | JA ERR1 | ||
| 331 | SHL AL,1 ; Times two | ||
| 332 | CBW ; Now a 16-bit quantity | ||
| 333 | XCHG BX,AX ; In BX we can address with it | ||
| 334 | CALL CS:[BX+COMTAB] ; Execute command | ||
| 335 | JMP SHORT COMMAND ; Get next command | ||
| 336 | ERR1: JMP PERR | ||
| 337 | |||
| 338 | SET_TERMINATE_VECTOR: | ||
| 339 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 22H ; Set vector 22H | ||
| 340 | MOV DX,OFFSET DG:TERMINATE | ||
| 341 | INT 21H | ||
| 342 | RET | ||
| 343 | |||
| 344 | TERMINATE: | ||
| 345 | CMP BYTE PTR CS:[QFLAG],0 | ||
| 346 | JNZ QUITING | ||
| 347 | MOV CS:[USER_PROC_PDB],CS | ||
| 348 | CMP BYTE PTR CS:[NEWEXEC],0 | ||
| 349 | JZ NORMTERM | ||
| 350 | MOV AX,CS | ||
| 351 | MOV DS,AX | ||
| 352 | MOV SS,AX | ||
| 353 | MOV SP,OFFSET DG:STACK | ||
| 354 | MOV AX,[HEADSAVE] | ||
| 355 | JMP DEBUG_FOUND | ||
| 356 | |||
| 357 | NORMTERM: | ||
| 358 | MOV DX,OFFSET DG:ENDMES | ||
| 359 | JMP SHORT RESTART | ||
| 360 | |||
| 361 | QUITING: | ||
| 362 | MOV AX,(EXIT SHL 8) | ||
| 363 | INT 21H | ||
| 364 | |||
| 365 | DABORT: | ||
| 366 | MOV DX,OFFSET DG:CARRET | ||
| 367 | RESTART: | ||
| 368 | MOV AX,CS | ||
| 369 | MOV DS,AX | ||
| 370 | MOV SS,AX | ||
| 371 | MOV SP,OFFSET DG:STACK | ||
| 372 | CALL RPRBUF | ||
| 373 | JMP COMMAND | ||
| 374 | |||
| 375 | IF SYSVER | ||
| 376 | SETUDEV: | ||
| 377 | MOV DI,OFFSET DG:CONFCB | ||
| 378 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H | ||
| 379 | INT 21H | ||
| 380 | CALL USERDEV | ||
| 381 | JMP DISPREG | ||
| 382 | |||
| 383 | USERDEV: | ||
| 384 | MOV DX,OFFSET DG:CONFCB | ||
| 385 | MOV AH,FCB_OPEN | ||
| 386 | INT 21H | ||
| 387 | OR AL,AL | ||
| 388 | JNZ OPENERR | ||
| 389 | MOV SI,DX | ||
| 390 | TEST BYTE PTR [SI.fcb_DEVID],080H ; Device? | ||
| 391 | JZ OPENERR ; NO | ||
| 392 | LDS SI,DWORD PTR [CONFCB.fcb_FIRCLUS] | ||
| 393 | MOV WORD PTR CS:[CIN],SI | ||
| 394 | MOV WORD PTR CS:[CIN+2],DS | ||
| 395 | MOV WORD PTR CS:[COUT],SI | ||
| 396 | MOV WORD PTR CS:[COUT+2],DS | ||
| 397 | PUSH CS | ||
| 398 | POP DS | ||
| 399 | RET | ||
| 400 | |||
| 401 | |||
| 402 | OPENERR: | ||
| 403 | MOV DX,OFFSET DG:BADDEV | ||
| 404 | CALL RPRBUF | ||
| 405 | RET | ||
| 406 | ENDIF | ||
| 407 | |||
| 408 | ; Get input line. Convert all characters NOT in quotes to upper case. | ||
| 409 | |||
| 410 | INBUF: | ||
| 411 | CALL RBUFIN | ||
| 412 | MOV SI,OFFSET DG:LINEBUF | ||
| 413 | MOV DI,OFFSET DG:BYTEBUF | ||
| 414 | CASECHK: | ||
| 415 | LODSB | ||
| 416 | CMP AL,'a' | ||
| 417 | JB NOCONV | ||
| 418 | CMP AL,'z' | ||
| 419 | JA NOCONV | ||
| 420 | ADD AL,"A"-"a" ; Convert to upper case | ||
| 421 | NOCONV: | ||
| 422 | STOSB | ||
| 423 | CMP AL,13 | ||
| 424 | JZ INDONE | ||
| 425 | CMP AL,'"' | ||
| 426 | JZ QUOTSCAN | ||
| 427 | CMP AL,"'" | ||
| 428 | JNZ CASECHK | ||
| 429 | QUOTSCAN: | ||
| 430 | MOV AH,AL | ||
| 431 | KILLSTR: | ||
| 432 | LODSB | ||
| 433 | STOSB | ||
| 434 | CMP AL,13 | ||
| 435 | JZ INDONE | ||
| 436 | CMP AL,AH | ||
| 437 | JNZ KILLSTR | ||
| 438 | JMP SHORT CASECHK | ||
| 439 | |||
| 440 | INDONE: | ||
| 441 | MOV SI,OFFSET DG:BYTEBUF | ||
| 442 | |||
| 443 | ; Output CR/LF sequence | ||
| 444 | |||
| 445 | CRLF: | ||
| 446 | MOV AL,13 | ||
| 447 | CALL OUT | ||
| 448 | MOV AL,10 | ||
| 449 | JMP OUT | ||
| 450 | |||
| 451 | ; Physical backspace - blank, backspace, blank | ||
| 452 | |||
| 453 | BACKUP: | ||
| 454 | MOV SI,OFFSET DG:BACMES | ||
| 455 | |||
| 456 | ; Print ASCII message. Last char has bit 7 set | ||
| 457 | |||
| 458 | PRINTMES: | ||
| 459 | LODS CS:BYTE PTR [SI] ; Get char to print | ||
| 460 | CALL OUT | ||
| 461 | SHL AL,1 ; High bit set? | ||
| 462 | JNC PRINTMES | ||
| 463 | RET | ||
| 464 | |||
| 465 | ; Scan for parameters of a command | ||
| 466 | |||
| 467 | SCANP: | ||
| 468 | CALL SCANB ; Get first non-blank | ||
| 469 | CMP BYTE PTR [SI],"," ; One comma between params OK | ||
| 470 | JNE EOLCHK ; If not comma, we found param | ||
| 471 | INC SI ; Skip over comma | ||
| 472 | |||
| 473 | ; Scan command line for next non-blank character | ||
| 474 | |||
| 475 | SCANB: | ||
| 476 | PUSH AX | ||
| 477 | SCANNEXT: | ||
| 478 | LODSB | ||
| 479 | CMP AL," " | ||
| 480 | JZ SCANNEXT | ||
| 481 | CMP AL,9 | ||
| 482 | JZ SCANNEXT | ||
| 483 | DEC SI ; Back to first non-blank | ||
| 484 | POP AX | ||
| 485 | EOLCHK: | ||
| 486 | CMP BYTE PTR [SI],13 | ||
| 487 | RET | ||
| 488 | |||
| 489 | ; Hex addition and subtraction | ||
| 490 | |||
| 491 | HEXADD: | ||
| 492 | MOV CX,4 | ||
| 493 | CALL GETHEX | ||
| 494 | MOV DI,DX | ||
| 495 | MOV CX,4 | ||
| 496 | CALL GETHEX | ||
| 497 | CALL GETEOL | ||
| 498 | PUSH DX | ||
| 499 | ADD DX,DI | ||
| 500 | CALL OUT16 | ||
| 501 | CALL BLANK | ||
| 502 | CALL BLANK | ||
| 503 | POP DX | ||
| 504 | SUB DI,DX | ||
| 505 | MOV DX,DI | ||
| 506 | CALL OUT16 | ||
| 507 | JMP SHORT CRLF | ||
| 508 | |||
| 509 | ; Print the hex address of DS:SI | ||
| 510 | |||
| 511 | OUTSI: | ||
| 512 | MOV DX,DS ; Put DS where we can work with it | ||
| 513 | CALL OUT16 ; Display segment | ||
| 514 | MOV AL,":" | ||
| 515 | CALL OUT | ||
| 516 | MOV DX,SI | ||
| 517 | JMP SHORT OUT16 ; Output displacement | ||
| 518 | |||
| 519 | ; Print hex address of ES:DI | ||
| 520 | ; Same as OUTSI above | ||
| 521 | |||
| 522 | OUTDI: | ||
| 523 | MOV DX,ES | ||
| 524 | CALL OUT16 | ||
| 525 | MOV AL,":" | ||
| 526 | CALL OUT | ||
| 527 | MOV DX,DI | ||
| 528 | |||
| 529 | ; Print out 16-bit value in DX in hex | ||
| 530 | |||
| 531 | OUT16: | ||
| 532 | MOV AL,DH ; High-order byte first | ||
| 533 | CALL HEX | ||
| 534 | MOV AL,DL ; Then low-order byte | ||
| 535 | |||
| 536 | ; Output byte in AL as two hex digits | ||
| 537 | |||
| 538 | HEX: | ||
| 539 | MOV AH,AL ; Save for second digit | ||
| 540 | ; Shift high digit into low 4 bits | ||
| 541 | PUSH CX | ||
| 542 | MOV CL,4 | ||
| 543 | SHR AL,CL | ||
| 544 | POP CX | ||
| 545 | |||
| 546 | CALL DIGIT ; Output first digit | ||
| 547 | MOV AL,AH ; Now do digit saved in AH | ||
| 548 | DIGIT: | ||
| 549 | AND AL,0FH ; Mask to 4 bits | ||
| 550 | ; Trick 6-byte hex conversion works on 8086 too. | ||
| 551 | ADD AL,90H | ||
| 552 | DAA | ||
| 553 | ADC AL,40H | ||
| 554 | DAA | ||
| 555 | |||
| 556 | ; Console output of character in AL. No registers affected but bit 7 | ||
| 557 | ; is reset before output. | ||
| 558 | |||
| 559 | IF SYSVER | ||
| 560 | OUT: | ||
| 561 | PUSH AX | ||
| 562 | AND AL,7FH | ||
| 563 | CMP AL,7FH | ||
| 564 | JNZ NOTDEL | ||
| 565 | MOV AL,8 ; DELETE same as backspace | ||
| 566 | NOTDEL: | ||
| 567 | CMP AL,9 | ||
| 568 | JZ TABDO | ||
| 569 | CALL DOCONOUT | ||
| 570 | CMP AL,0DH | ||
| 571 | JZ ZEROPOS | ||
| 572 | CMP AL,0AH | ||
| 573 | JZ ZEROPOS | ||
| 574 | CMP AL,8 | ||
| 575 | JNZ OOKRET | ||
| 576 | MOV AL," " | ||
| 577 | CALL DOCONOUT | ||
| 578 | MOV AL,8 | ||
| 579 | CALL DOCONOUT | ||
| 580 | CMP BYTE PTR CS:[COLPOS],0 | ||
| 581 | JZ NOTINC | ||
| 582 | DEC BYTE PTR CS:[COLPOS] | ||
| 583 | JMP NOTINC | ||
| 584 | ZEROPOS: | ||
| 585 | MOV BYTE PTR CS:[COLPOS],0FFH | ||
| 586 | OOKRET: | ||
| 587 | INC BYTE PTR CS:[COLPOS] | ||
| 588 | NOTINC: | ||
| 589 | TEST BYTE PTR CS:[PFLAG],1 | ||
| 590 | JZ POPRET | ||
| 591 | CALL LISTOUT | ||
| 592 | POPRET: | ||
| 593 | POP AX | ||
| 594 | RET | ||
| 595 | |||
| 596 | TABDO: | ||
| 597 | MOV AL,CS:[COLPOS] | ||
| 598 | OR AL,0F8H | ||
| 599 | NEG AL | ||
| 600 | PUSH CX | ||
| 601 | MOV CL,AL | ||
| 602 | XOR CH,CH | ||
| 603 | JCXZ POPTAB | ||
| 604 | TABLP: | ||
| 605 | MOV AL," " | ||
| 606 | CALL OUT | ||
| 607 | LOOP TABLP | ||
| 608 | POPTAB: | ||
| 609 | POP CX | ||
| 610 | POP AX | ||
| 611 | RET | ||
| 612 | |||
| 613 | |||
| 614 | DOCONOUT: | ||
| 615 | PUSH DS | ||
| 616 | PUSH SI | ||
| 617 | PUSH AX | ||
| 618 | CONOWAIT: | ||
| 619 | LDS SI,CS:[COUT] | ||
| 620 | MOV AH,10 | ||
| 621 | CALL DEVIOCALL | ||
| 622 | MOV AX,CS:[IOSTAT] | ||
| 623 | AND AX,200H | ||
| 624 | JNZ CONOWAIT | ||
| 625 | POP AX | ||
| 626 | PUSH AX | ||
| 627 | MOV AH,8 | ||
| 628 | CALL DEVIOCALL | ||
| 629 | POP AX | ||
| 630 | POP SI | ||
| 631 | POP DS | ||
| 632 | RET | ||
| 633 | |||
| 634 | |||
| 635 | LISTOUT: | ||
| 636 | PUSH DS | ||
| 637 | PUSH SI | ||
| 638 | PUSH AX | ||
| 639 | LISTWAIT: | ||
| 640 | LDS SI,CS:[POUT] | ||
| 641 | MOV AH,10 | ||
| 642 | CALL DEVIOCALL | ||
| 643 | MOV AX,CS:[IOSTAT] | ||
| 644 | AND AX,200H | ||
| 645 | JNZ LISTWAIT | ||
| 646 | POP AX | ||
| 647 | PUSH AX | ||
| 648 | MOV AH,8 | ||
| 649 | CALL DEVIOCALL | ||
| 650 | POP AX | ||
| 651 | POP SI | ||
| 652 | POP DS | ||
| 653 | RET | ||
| 654 | |||
| 655 | DEVIOCALL: | ||
| 656 | PUSH ES | ||
| 657 | PUSH BX | ||
| 658 | PUSH CS | ||
| 659 | POP ES | ||
| 660 | MOV BX,OFFSET DG:IOCALL | ||
| 661 | MOV CS:[IOCOM],AH | ||
| 662 | MOV WORD PTR CS:[IOSTAT],0 | ||
| 663 | MOV WORD PTR CS:[IOCNT],1 | ||
| 664 | MOV CS:[IOBUFF],AL | ||
| 665 | MOV WORD PTR CS:[IOADDR+2],DS | ||
| 666 | MOV AX,[SI+6] | ||
| 667 | MOV WORD PTR CS:[IOADDR],AX | ||
| 668 | CALL DWORD PTR CS:[IOADDR] | ||
| 669 | MOV AX,[SI+8] | ||
| 670 | MOV WORD PTR CS:[IOADDR],AX | ||
| 671 | CALL DWORD PTR CS:[IOADDR] | ||
| 672 | MOV AL,CS:[IOBUFF] | ||
| 673 | POP BX | ||
| 674 | POP ES | ||
| 675 | RET | ||
| 676 | ELSE | ||
| 677 | |||
| 678 | OUT: | ||
| 679 | PUSH DX | ||
| 680 | PUSH AX | ||
| 681 | AND AL,7FH | ||
| 682 | MOV DL,AL | ||
| 683 | MOV AH,2 | ||
| 684 | INT 21H | ||
| 685 | POP AX | ||
| 686 | POP DX | ||
| 687 | RET | ||
| 688 | ENDIF | ||
| 689 | |||
| 690 | |||
| 691 | IF SYSVER | ||
| 692 | RBUFIN: | ||
| 693 | PUSH AX | ||
| 694 | PUSH ES | ||
| 695 | PUSH DI | ||
| 696 | PUSH CS | ||
| 697 | POP ES | ||
| 698 | MOV BYTE PTR [LBUFFCNT],0 | ||
| 699 | MOV DI,OFFSET DG:LINEBUF | ||
| 700 | FILLBUF: | ||
| 701 | CALL IN | ||
| 702 | CMP AL,0DH | ||
| 703 | JZ BDONE | ||
| 704 | CMP AL,8 | ||
| 705 | JZ ECHR | ||
| 706 | CMP AL,7FH | ||
| 707 | JZ ECHR | ||
| 708 | CMP BYTE PTR [LBUFFCNT],BUFLEN | ||
| 709 | JAE BFULL | ||
| 710 | STOSB | ||
| 711 | INC BYTE PTR [LBUFFCNT] | ||
| 712 | JMP SHORT FILLBUF | ||
| 713 | |||
| 714 | BDONE: | ||
| 715 | STOSB | ||
| 716 | POP DI | ||
| 717 | POP ES | ||
| 718 | POP AX | ||
| 719 | RET | ||
| 720 | |||
| 721 | BFULL: | ||
| 722 | MOV AL,8 | ||
| 723 | CALL OUT | ||
| 724 | MOV AL,7 | ||
| 725 | CALL OUT | ||
| 726 | JMP SHORT FILLBUF | ||
| 727 | |||
| 728 | ECHR: | ||
| 729 | CMP DI,OFFSET DG:LINEBUF | ||
| 730 | JZ FILLBUF | ||
| 731 | DEC DI | ||
| 732 | DEC BYTE PTR [LBUFFCNT] | ||
| 733 | JMP SHORT FILLBUF | ||
| 734 | ELSE | ||
| 735 | |||
| 736 | RBUFIN: | ||
| 737 | PUSH AX | ||
| 738 | PUSH DX | ||
| 739 | MOV AH,10 | ||
| 740 | MOV DX,OFFSET DG:LBUFSIZ | ||
| 741 | INT 21H | ||
| 742 | POP DX | ||
| 743 | POP AX | ||
| 744 | RET | ||
| 745 | ENDIF | ||
| 746 | |||
| 747 | |||
| 748 | IF SYSVER | ||
| 749 | RPRBUF: | ||
| 750 | PUSHF | ||
| 751 | PUSH AX | ||
| 752 | PUSH SI | ||
| 753 | MOV SI,DX | ||
| 754 | PLOOP: | ||
| 755 | LODSB | ||
| 756 | CMP AL,"$" | ||
| 757 | JZ PRTDONE | ||
| 758 | CALL OUT | ||
| 759 | JMP SHORT PLOOP | ||
| 760 | PRTDONE: | ||
| 761 | POP SI | ||
| 762 | POP AX | ||
| 763 | POPF | ||
| 764 | RET | ||
| 765 | ELSE | ||
| 766 | |||
| 767 | RPRBUF: | ||
| 768 | MOV AH,9 | ||
| 769 | INT 21H | ||
| 770 | RET | ||
| 771 | ENDIF | ||
| 772 | |||
| 773 | ; Output one space | ||
| 774 | |||
| 775 | BLANK: | ||
| 776 | MOV AL," " | ||
| 777 | JMP OUT | ||
| 778 | |||
| 779 | ; Output the number of blanks in CX | ||
| 780 | |||
| 781 | TAB: | ||
| 782 | CALL BLANK | ||
| 783 | LOOP TAB | ||
| 784 | RET | ||
| 785 | |||
| 786 | ; Command Table. Command letter indexes into table to get | ||
| 787 | ; address of command. PERR prints error for no such command. | ||
| 788 | |||
| 789 | COMTAB DW ASSEM ; A | ||
| 790 | DW PERR ; B | ||
| 791 | DW COMPARE ; C | ||
| 792 | DW DUMP ; D | ||
| 793 | DW ENTER ; E | ||
| 794 | DW FILL ; F | ||
| 795 | DW GO ; G | ||
| 796 | DW HEXADD ; H | ||
| 797 | DW INPUT ; I | ||
| 798 | DW PERR ; J | ||
| 799 | DW PERR ; K | ||
| 800 | DW LOAD ; L | ||
| 801 | DW MOVE ; M | ||
| 802 | DW NAME ; N | ||
| 803 | DW OUTPUT ; O | ||
| 804 | IF ZIBO | ||
| 805 | DW ZTRACE | ||
| 806 | ELSE | ||
| 807 | DW PERR ; P | ||
| 808 | ENDIF | ||
| 809 | DW QUIT ; Q (QUIT) | ||
| 810 | DW REG ; R | ||
| 811 | DW SEARCH ; S | ||
| 812 | DW TRACE ; T | ||
| 813 | DW UNASSEM ; U | ||
| 814 | DW PERR ; V | ||
| 815 | DW DWRITE ; W | ||
| 816 | IF SYSVER | ||
| 817 | DW SETUDEV ; X | ||
| 818 | ELSE | ||
| 819 | DW PERR | ||
| 820 | ENDIF | ||
| 821 | DW PERR ; Y | ||
| 822 | DW PERR ; Z | ||
| 823 | |||
| 824 | QUIT: | ||
| 825 | INC BYTE PTR [QFLAG] | ||
| 826 | MOV BX,[USER_PROC_PDB] | ||
| 827 | FIND_DEBUG: | ||
| 828 | IF NOT SYSVER | ||
| 829 | MOV AH,SET_CURRENT_PDB | ||
| 830 | INT 21H | ||
| 831 | ENDIF | ||
| 832 | CALL ReleaseParity ; let system do normal parity stuff | ||
| 833 | MOV AX,(EXIT SHL 8) | ||
| 834 | INT 21H | ||
| 835 | |||
| 836 | CODE ENDS | ||
| 837 | END START | ||
| 838 | |||