summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/DEBUG/DEBUG.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/DEBUG/DEBUG.ASM')
-rw-r--r--v4.0/src/CMD/DEBUG/DEBUG.ASM1236
1 files changed, 1236 insertions, 0 deletions
diff --git a/v4.0/src/CMD/DEBUG/DEBUG.ASM b/v4.0/src/CMD/DEBUG/DEBUG.ASM
new file mode 100644
index 0000000..e986db9
--- /dev/null
+++ b/v4.0/src/CMD/DEBUG/DEBUG.ASM
@@ -0,0 +1,1236 @@
1 PAGE 60,132 ;
2 TITLE DEBUG.SAL - DEBUGger for PC DOS
3
4;======================= START OF SPECIFICATIONS =========================
5;
6; MODULE NAME: DEBUG.SAL
7;
8; DESCRIPTIVE NAME: DEBUGGING TOOL
9;
10; FUNCTION: PROVIDES USERS WITH A TOOL FOR DEBUGGING PROGRAMS.
11;
12; ENTRY POINT: START
13;
14; INPUT: DOS COMMAND LINE
15; DEBUG COMMANDS
16;
17; EXIT NORMAL: NA
18;
19; EXIT ERROR: NA
20;
21; INTERNAL REFERENCES:
22;
23; EXTERNAL REFERENCES:
24;
25; ROUTINE: DEBCOM1 - CONTAINS ROUTINES CALLED BY DEBUG
26; DEBCOM2 - CONTAINS ROUTINES CALLED BY DEBUG
27; DEBCOM3 - CONTAINS ROUTINES CALLED BY DEBUG
28; DEBASM - CONTAINS ROUTINES CALLED BY DEBUG
29; DEBUASM - CONTAINS ROUTINES CALLED BY DEBUG
30; DEBMES - CONTAINS MESSAGE RETRIEVER ROUTINES
31;
32; NOTES: THIS MODULE IS TO BE PREPPED BY SALUT WITH THE "PR" OPTIONS.
33; LINK DEBUG+DEBCOM1+DEBCOM2+DEBCOM3+DEBASM+DEBUASM+DEBERR+
34; DEBCONST+DEBDATA+DEBMES
35;
36; REVISION HISTORY:
37;
38; AN000 VERSION 4.00 - REVISIONS MADE RELATE TO THE FOLLOWING:
39;
40; - IMPLEMENT DBCS HANDLING DMS:6/17/87
41; - IMPLEMENT DBCS HANDLING bgb:5/03/88 ;an001;bgb
42; - IMPLEMENT MESSAGE RETRIEVER DMS:6/17/87
43; - > 32 MB SUPPORT DMS:6/17/87
44;
45; COPYRIGHT: "MS DOS DEBUG UTILITY"
46; "VERSION 4.00 (C) COPYRIGHT 1988 Microsoft"
47; "LICENSED MATERIAL - PROPERTY OF Microsoft "
48;
49; MICROSOFT REVISION HISTORY:
50;
51; Modified 5/4/82 by AaronR to do all I/O direct to devices
52; Runs on MS-DOS 1.28 and above
53;
54; REV 1.20
55; Tab expansion
56; New device interface (1.29 and above)
57; REV 2.0
58; line by line assembler added by C. P.
59; REV 2.1
60; Uses EXEC system call
61; REV 2.2
62; Ztrace mode by zibo.
63; Fix dump display to indent properly
64; Parity nonsense by zibo
65;
66; REV 2.3 NP
67; Use Printf for all standard output.
68; Change to EXE file
69; REV 2.4 ARR
70; Bug fixes. TEST, XCHG instructions reg order reversed.
71; Single step, break point interrupts saved and restored.
72; Access denied given on W to read only file.
73;======================= END OF SPECIFICATIONS ===========================
74
75 IF1
76 %OUT COMPONENT=DEBUG, MODULE=DEBUG
77 ENDIF
78.XLIST
79.XCREF
80 INCLUDE DOSSYM.INC ; ALSO VERSION NUMBER
81.CREF
82.LIST
83 INCLUDE DEBEQU.ASM
84 IF SYSVER
85; Structure for system call 72
86SYSINITVAR STRUC
87DPBHEAD DD ? ; Pointer to head of DPB-FAT list
88SFT_ADDR DD ? ; Pointer to first FCB table
89; The following address points to the CLOCK device
90BCLOCK DD ?
91; The following address is used by DISKSTATCHK it is always
92; points to the console input device header
93BCON DD ? ; Console device entry points
94MAXSEC DW 0 ; Maximum allowed sector size
95BUFFHEAD DD ?
96CDS DD ?
97SFTFCB DD ?
98KEEP DW ?
99NUMIO DB 0 ; Number of disk tables
100NCDS DB ?
101DEVHEAD DD ?
102SYSINITVAR ENDS
103
104 ENDIF
105
106
107;======================= macro equates ===================================
108
109dbcs_delim equ 81h ;an000;delimits dbcs char
110asian_blk equ 40h ;an000;asian blank
111amer_blk equ 20h ;an000;american blank
112quote_char equ 22h ;an000;quote delim "
113
114;======================= end macro equates ===============================
115
116
117;This segment must be the first loaded since we are using it to make
118;a CREATE_PROCESS_DATA_BLOCK system call a la 1.0 and .COM files.
119;For this system call CS must point to the Program Prefix Header, so
120;by setting up a seperate segment just after the header we can issue
121;an INT 21H via a long call. So don't move this guy around!
122
123A_CREATE_BLOCK SEGMENT
124
125 PUBLIC CREATE_CALL
126
127;The other arguements to this system call have been set up
128;by the caller.
129
130CREATE_CALL PROC FAR
131 MOV AH,CREATE_PROCESS_DATA_BLOCK
132 INT 21H
133 RET
134
135CREATE_CALL ENDP
136
137A_CREATE_BLOCK ENDS
138
139
140CODE SEGMENT PUBLIC
141CODE ENDS
142
143CONST SEGMENT PUBLIC
144CONST ENDS
145
146CSTACK SEGMENT STACK
147CSTACK ENDS
148
149DATA SEGMENT PUBLIC
150DATA ENDS
151
152DG GROUP CODE,CONST,CSTACK,DATA
153
154CONST SEGMENT PUBLIC BYTE
155 EXTRN BADVER:BYTE,ENDMES_PTR:BYTE,CRLF_PTR:BYTE
156 IF IBMJAPAN
157 EXTRN PARITYMES_PTR:BYTE
158 ENDIF
159 EXTRN PROMPT_PTR:BYTE,ADD_PTR:BYTE,HEX_PTR:BYTE
160 EXTRN USER_PROC_PDB:WORD,CSSAVE:WORD,DSSAVE:WORD
161 EXTRN SPSAVE:WORD,IPSAVE:WORD,LINEBUF:BYTE,QFLAG:BYTE
162 EXTRN NEWEXEC:BYTE,HEADSAVE:WORD,LBUFSIZ:BYTE,BACMES_PTR:WORD
163
164 IF IBMVER
165 EXTRN DSIZ:BYTE,NOREGL:BYTE,DISPB:WORD
166 ENDIF
167
168 IF SYSVER
169 EXTRN CONFCB:BYTE,POUT:DWORD,COUT:DWORD,CIN:DWORD,IOBUFF:BYTE
170 EXTRN IOADDR:DWORD,IOCALL:BYTE,IOCOM:BYTE,IOSTAT:WORD,IOCNT:WORD
171 EXTRN IOSEG:WORD,COLPOS:BYTE,BADDEV_PTR:BYTE,BADLSTMES_PTR:BYTE
172 EXTRN LBUFFCNT:BYTE,PFLAG:BYTE
173 ENDIF
174
175 EXTRN NAMESPEC:BYTE
176
177CONST ENDS
178
179CSTACK SEGMENT STACK
180 DB (362 - 80H) + 80H DUP(?) ; (362 - 80H) == IBM'S ROM REQUIREMENTS
181 ; (NEW - OLD) == SIZE TO GROW STACK
182CSTACK ENDS
183
184DATA SEGMENT PUBLIC BYTE
185 EXTRN ARG_BUF:BYTE,ADD_ARG:WORD,SUB_ARG:WORD,HEX_ARG1:WORD
186 EXTRN HEX_ARG2:WORD,STACK:BYTE, PREV24:DWORD, FIN24:BYTE
187 EXTRN PARSERR:BYTE,DATAEND:WORD,PARITYFLAG:BYTE,DISADD:BYTE
188 EXTRN ASMADD:BYTE,DEFDUMP:BYTE,BYTEBUF:BYTE,BEGSEG:WORD
189 EXTRN BPINTSAV:DWORD,SSINTSAV:DWORD ;ARR 2.4
190 EXTRN CREATE_LONG:DWORD
191
192 extrn lbtbl:dword ;an000;lead byte table pointer
193
194DATA ENDS
195
196 EXTRN PRINTF:NEAR ;ac000;changed to NEAR call
197
198CODE SEGMENT PUBLIC
199 ASSUME CS:DG,DS:NOTHING,ES:NOTHING,SS:CSTACK
200
201 PUBLIC RESTART
202 PUBLIC STD_PRINTF,PRINTF_CRLF
203 PUBLIC HEX_ADDRESS_ONLY,HEX_ADDRESS_STR
204 PUBLIC RESTART,SET_TERMINATE_VECTOR,DABORT,TERMINATE,COMMAND
205 PUBLIC FIND_DEBUG,CRLF,BLANK,TAB,INBUF,SCANB,SCANP
206 PUBLIC HEX,OUTSI,OUTDI,DIGIT,BACKUP,RBUFIN
207 public test_lead ;an001;bgb
208 public test1 ;an001;bgb
209
210 IF SYSVER
211; PUBLIC SETUDEV,DEVIOCALL ; kwc 12/10/86
212 PUBLIC SETUDEV ; kwc 12/10/86
213 EXTRN DISPREG:NEAR,INPT:NEAR
214 ENDIF
215
216 EXTRN PERR:NEAR,COMPARE:NEAR,DUMP:NEAR,ENTERDATA:NEAR,FILL:NEAR
217 EXTRN GO:NEAR,INPUT:NEAR,LOAD:NEAR,MOVE:NEAR,NAMED:NEAR
218 EXTRN REG:NEAR,SEARCH:NEAR,DWRITE:NEAR,UNASSEM:NEAR,ASSEM:NEAR
219 EXTRN OUTPUT:NEAR,ZTRACE:NEAR,TRACE:NEAR,GETHEX:NEAR,GETEOL:NEAR
220 EXTRN PREPNAME:NEAR,DEFIO:NEAR,SKIP_FILE:NEAR,DEBUG_FOUND:NEAR
221 EXTRN TRAPPARITY:NEAR,RELEASEPARITY:NEAR
222 extrn pre_load_message:near ;an000;load messages
223 extrn debems:near ;an000;ems support
224
225
226 DB 100H DUP (?)
227
228START:
229 JMP SHORT DSTRT
230
231HEADER DB "Vers 2.40"
232
233DSTRT:
234;=========================================================================
235; invoke PRE_LOAD_MESSAGE here. If the messages were not loaded we will
236; exit with an appropriate error message.
237;
238; Date : 6/14/87
239;=========================================================================
240
241 push ds ;an000;save regs
242 push es ;an000;save resg
243
244 push cs ;an000;transfer cs
245 pop ds ;an000; to ds
246
247 push cs ;an000;transfer cs
248 pop es ;an000; to es
249 assume ds:dg,es:dg ;an000;assume them
250 call PRE_LOAD_MESSAGE ;an000;invoke SYSLOADMSG
251; $if c ;an000;if the load was unsuccessful
252 JNC $$IF1
253 mov ax,(exit shl 8) ;an000;exit EDLIN. PRE_LOAD_MESSAGE
254 ; has already said why
255 int 21h ;an000;exit
256; $endif ;an000;
257$$IF1:
258
259 pop es ;an000;restore regs.
260 pop ds ;an000;
261 assume ds:nothing,es:nothing ;an000;back to original
262
263 MOV AX,(GET_INTERRUPT_VECTOR SHL 8) OR VEC_BREAKPOINT ;get original contents
264 INT 21H ; of the BREAKPOINT vector
265
266 MOV WORD PTR [BPINTSAV],BX ; and save that vector for later
267 MOV WORD PTR [BPINTSAV+WORD],ES ; restoration
268
269 MOV AX,(GET_INTERRUPT_VECTOR SHL 8) OR VEC_SING_STEP ;get original contents
270 INT 21H ; of the SINGLE STEP vector
271
272 MOV WORD PTR [SSINTSAV],BX ; and save that vector for later
273 MOV WORD PTR [SSINTSAV+WORD],ES ; restoration
274
275 MOV BEGSEG,DS ; save beginning DS
276 PUSH CS ; repair damaged ES to be
277 POP ES ; back to just like CS
278 XOR SI,SI ; set source and destination
279 XOR DI,DI ; indices both to zero
280 MOV CX,256 ; set count to size of PSP
281 REP MOVSB ; move to es:[di] from ds:[si]
282 PUSH CS ; set up DS to be just like CS
283 POP DS ; to match .COM rules of addressability
284 ASSUME DS:DG,ES:DG ; like CS, also have DS and DS as bases
285
286 CALL TRAPPARITY ; scarf up those parity guys
287 MOV AH,GET_CURRENT_PDB ;(undocumented function call - 51h)
288 INT 21H
289
290 MOV [USER_PROC_PDB],BX ; Initially set to DEBUG
291
292 IF SYSVER
293 MOV [IOSEG],CS
294 ENDIF
295
296 MOV [PARSERR],AL
297
298
299 IF SYSVER
300 MOV AH,GET_IN_VARS ;(undocumented function call - 52h)
301 INT 21H
302
303 LDS SI,ES:[BX.BCON] ; get system console device
304 ASSUME DS:NOTHING
305
306 MOV WORD PTR CS:[CIN+WORD],DS ;save vector to console input device
307 MOV WORD PTR CS:[CIN],SI
308 MOV WORD PTR CS:[COUT+WORD],DS ;save vector to console output device
309 MOV WORD PTR CS:[COUT],SI
310 PUSH CS ; restore DS to be
311 POP DS ; just like CS, as before
312 ASSUME DS:DG
313
314 MOV DX,OFFSET DG:CONFCB ; get system printer device
315 MOV AH,FCB_OPEN ; open system printer "PRN"
316 INT 21H
317
318 OR AL,AL ; open ok?
319 JZ GOTLIST ; yes, it was there
320
321 MOV DX,OFFSET DG:BADLSTMES_ptr ; no list file found...
322 CALL STD_PRINTF ; tell user
323
324 CALL RBUFIN ; ask for a new one
325
326 CALL CRLF
327
328 MOV CL,[LBUFFCNT]
329 OR CL,CL
330 JZ NOLIST1 ; User didn't specify one
331
332 XOR CH,CH
333 MOV DI,OFFSET DG:(CONFCB + BYTE)
334 MOV SI,OFFSET DG:LINEBUF ; get one from input line
335 REP MOVSB
336 MOV DX,OFFSET DG:CONFCB
337 MOV AH,FCB_OPEN ; try to open it
338 INT 21H
339
340 OR AL,AL
341 JZ GOTLIST ; yep, use it...
342
343 MOV DX,OFFSET DG:BADDEV_Ptr ; complain again
344 CALL STD_PRINTF
345NOLIST1: ; kwc 12/10/86
346 MOV WORD PTR [POUT+WORD],CS ; use null device for printer
347 MOV WORD PTR [POUT],OFFSET DG:LONGRET
348 JMP NOLIST
349
350XXX PROC FAR
351LONGRET:
352 RET
353XXX ENDP
354 ENDIF
355
356GOTLIST:
357;DX = OFFSET OF 'CONFCB', WHICH HAS JUST BEEN OPENED OK
358 IF SYSVER
359 MOV SI,DX
360; LDS SI,DWORD PTR DS:[SI.FCB_FIRCLUS] ; KWC 12/10/86
361 LDS SI,DWORD PTR DS:[SI.FCB_NSLD_DRVPTR] ; KWC 12/10/86
362 ASSUME DS:NOTHING
363
364 MOV WORD PTR CS:[POUT+WORD],DS
365 MOV WORD PTR CS:[POUT],SI
366 ENDIF
367NOLIST:
368 MOV AX,CS ;restore the DS and ES segregs
369 MOV DS,AX ; to become once again just like CS
370 MOV ES,AX
371 ASSUME DS:DG,ES:DG
372
373; Code to print header
374; MOV DX,OFFSET DG:HEADER_PTR
375; CALL STD_PRINTF
376
377 CALL SET_TERMINATE_VECTOR
378
379; Save the current INT 24 vector. We will need this to link to the previous
380; handler for handling of int 24 output.
381 PUSH ES ; save it, about to clobber it...
382 MOV AX,(GET_INTERRUPT_VECTOR SHL 8) + VEC_CRIT_ERR ; get original contents
383 INT 21H ; of the int 24h vector
384
385 MOV WORD PTR PREV24,BX ; remember what int 24h used to
386 MOV WORD PTR PREV24+WORD,ES ; point to
387 POP ES ; restore ES to be like CS and DS
388
389 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) + VEC_CRIT_ERR ; change int 24h to
390 MOV DX,OFFSET DG:MY24 ; point to my own int 24h handler
391 INT 21H
392
393 IF SETCNTC
394 MOV AL,VEC_CTRL_BREAK ; Set vector 23H
395 MOV DX,OFFSET DG:DABORT
396 INT 21H
397 ENDIF
398
399 MOV DX,CS ;get para of where this pgm starts
400 MOV AX,OFFSET DG:DATAEND+15 ;get offset of end of this program
401 MOV CL,4 ; (plus 15 padding for rounding)
402 SHR AX,CL ; adjusted to number of paragraphs
403 ADD DX,AX ;get para of where this pgm ends
404 MOV AX,CS
405 SUB AX,BEGSEG ; add in size of printf
406 ADD DX,AX ; create program segment here
407 CALL [CREATE_LONG] ; and call special routine
408
409 MOV AX,DX
410; Initialize the segments
411 MOV DI,OFFSET DG:DSSAVE
412 CLD
413 STOSW
414 STOSW
415 STOSW
416 STOSW
417 MOV WORD PTR [DISADD+WORD],AX
418 MOV WORD PTR [ASMADD+WORD],AX
419 MOV WORD PTR [DEFDUMP+WORD],AX
420
421 MOV AX,100H
422 MOV WORD PTR[DISADD],AX
423 MOV WORD PTR[ASMADD],AX
424 MOV WORD PTR [DEFDUMP],AX
425
426 MOV DS,DX
427 MOV ES,DX
428 ASSUME DS:NOTHING,ES:NOTHING
429
430 MOV DX,80H
431 MOV AH,SET_DMA
432 INT 21H ; Set default DMA address to 80H
433; Set up initial stack. We already have a 'good' stack set up already. DS:6
434; has the number of bytes remaining in the segment. We should take this
435; value, add 100h and use it as the Stack pointer.
436 MOV AX,WORD PTR DS:[6] ; get bytes remaining
437 MOV BX,AX
438 ADD AX,100h
439
440; MOV BX,AX
441; CMP AX,0FFF0H
442; PUSH CS
443; POP DS
444; JAE SAVSTK
445; MOV AX,WORD PTR DS:[6]
446; PUSH BX
447; MOV BX,OFFSET DG:DATAEND + 15
448; AND BX,0FFF0H ; Size of DEBUG in bytes (rounded up to PARA)
449; SUB AX,BX
450; POP BX
451;SAVSTK:
452 PUSH CS
453 POP DS
454 ASSUME DS:DG
455 PUSH BX ; bx is no. bytes remaining from PSP+6
456 DEC AX ; ax was no. bytes remaining +100h
457 DEC AX ; back up one word from end of new stack
458 MOV BX,AX ; set base to point to last word in new stack
459 MOV WORD PTR ES:[BX],0 ; set final word in new stack to zero
460 POP BX ; back to beginning of new stack area
461 MOV SPSAVE,AX ; remember where new stack is
462 DEC AH
463 MOV ES:WORD PTR [6],AX ; change PSP to show usage of
464 SUB BX,AX ; new stack area
465 MOV CL,4
466 SHR BX,CL
467 ADD ES:WORD PTR [8],BX
468
469 IF IBMVER
470; Get screen size and initialize display related variables
471 MOV AH,15 ;function = "request current video state"
472 INT 10H ;set al=screen mode
473 ; ah=no. char cols on screen
474 ; bh=current active display page
475 CMP AH,40 ;is screen in 40 col mode?
476 JNZ PARSCHK ; no, skip
477 ; yes, 40 col, continue
478 ;next fields defined in 'debconst.asm'
479 MOV BYTE PTR DSIZ,7 ; originally assembled as 0fh
480 MOV BYTE PTR NOREGL,4 ; originally assembled as 8
481 MOV DISPB,64 ; originally assembled as 128
482 ENDIF
483
484PARSCHK:
485
486
487 call DEBUG_LEAD_BYTE ;an000;build the dbcs env. table
488 ; of valid dbcs lead bytes
489
490;=========================================================================
491; prep_command_line requires the use of ds:si. ds is left intact for
492; the call. si is initialized to point to the command line input buffer.
493; ds and si are saved since we stomp all over them in prep_command_line.
494;=========================================================================
495
496 push si ;an000;save si
497
498 mov si,81h ;an000;point to command line
499 call prep_command_line ;an000;invoke command line conversion
500
501 pop si ;an000;restore si
502
503;=========================================================================
504; we have prepped the command line for dbcs. we can now enter the old
505; routines.
506;=========================================================================
507
508; Copy rest of command line to test program's parameter area
509 MOV DI,FCB ;es[di]=to be filled with unopened FCB
510 MOV SI,81H ;ds[si]=command line to parse
511 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR SET_DRIVEID_OPTION
512 ;func=29H, option al=1, which
513 ; says, drive id byte in fcb is set
514 ; only if drive specified in command
515 ; line being parsed.
516 INT 21H ;parse filename from command to fcb
517 ; ds:si=points to first char AFTER parsed filename
518 ; es:di=points to first byte of formatted FCB
519
520 CALL SKIP_FILE ; Make sure si points to delimiter
521test1: ;for testing only - u can remove this
522 CALL PREPNAME
523
524 PUSH CS ;restore ES to point to the
525 POP ES ; common group
526FILECHK:
527 MOV DI,80H ;point to byte in PSP defining parm length
528 CMP BYTE PTR ES:[DI],0 ; ANY STUFF FOUND?
529 JZ COMMAND ; no parms, skip
530 ; yes parms, continue
531FILOOP:
532 INC DI ;set index to first/next char in parm text
533 CMP BYTE PTR ES:[DI],CR ; carriage return? (at end of parms)
534 JZ COMMAND ; yes, at end of parms
535 ; no, not at end of parms yet, continue
536 CMP BYTE PTR ES:[DI],CHAR_BLANK ; is this parm text char a blank?
537 JZ FILOOP ; yes, a blank, skip
538 ; no, not a blank, continue
539 CMP BYTE PTR ES:[DI],CHAR_TAB ; is this parm text char a tab?
540 JZ FILOOP ; yes, a tab, skip
541 ; no, not a tab, continue
542 OR [NAMESPEC],1 ; set flag to indicate
543 ; we have a specified file
544 ; (this could be set by "N" command also)
545 CALL DEFIO ; READ in the specified file
546
547 PUSH CS ;restore DS to point to the
548 POP DS ; common group
549
550 ;perform self-relocation on some internal vectors:
551 MOV AX,CSSAVE ; pick up the seg id to go to vectors
552 MOV WORD PTR DISADD+WORD,AX ; shove it into the segid portion
553 MOV WORD PTR ASMADD+WORD,AX ; of these two vectors
554 MOV AX,IPSAVE ; pick up the offset to go to vectors
555 MOV WORD PTR DISADD,AX ; shove it into the offset portion
556 MOV WORD PTR ASMADD,AX ; of these two vectors
557COMMAND:
558 CLD
559 MOV AX,CS
560 MOV DS,AX
561 MOV ES,AX
562 cli ;disable before setting up the stack - EMK
563 MOV SS,AX ;now everything points to the same group
564 ASSUME SS:DG
565
566 MOV SP,OFFSET DG:STACK
567 STI ;re-enable
568 CMP [PARITYFLAG],0 ; did we detect a parity error?
569 JZ GOPROMPT ; no, go prompt
570 ; yes, parity error, continue
571 MOV [PARITYFLAG],0 ; reset flag
572 IF IBMJAPAN
573 MOV DX,OFFSET DG:PARITYMES_PTR
574 CALL STD_PRINTF ;display msg about parity error
575 ENDIF
576GOPROMPT:
577 MOV DX,OFFSET DG:PROMPT_PTR ;display the user prompt request
578 CALL STD_PRINTF
579
580 CALL INBUF ; Get command line
581; From now and throughout command line processing, DI points
582; to next character in command line to be processed.
583 CALL SCANB ; Scan off leading blanks
584
585 JZ COMMAND ; if zero, Null command, go get another
586 ; nonzero, got something in response
587 LODSB ; AL=first non-blank character
588; Prepare command letter for table lookup
589; converts the first non-blank (assumed to be the command letter)
590; to in index in the "comtab" array.
591 SUB AL,UPPER_A ; Low end range check
592 JB ERR1
593
594 CMP AL,UPPER_Z - UPPER_A ; Upper end range check
595 JA ERR1
596
597 SHL AL,1 ; Times two
598 CBW ; Now a 16-bit quantity
599 XCHG BX,AX ; In BX we can address with it
600 CALL CS:[BX+COMTAB] ; Execute command
601
602 JMP SHORT COMMAND ; Get next command
603ERR1:
604 JMP PERR
605
606SET_TERMINATE_VECTOR:
607 PUSH DS
608 PUSH CS
609 POP DS
610 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR VEC_TERM_ADDR ; Set vector 22H
611 MOV DX,OFFSET DG:TERMINATE
612 INT 21H
613
614 POP DS
615 RET
616
617RESTORE_DEB_VECT:
618 PUSH DS
619 PUSH DX
620 PUSH AX
621 LDS DX,CS:[BPINTSAV]
622 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR VEC_BREAKPOINT ;Vector 3
623 INT 21H
624
625 LDS DX,CS:[SSINTSAV]
626 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR VEC_SING_STEP ;Vector 1
627 INT 21H
628
629 POP AX
630 POP DX
631 POP DS
632 RET
633
634; Internal INT 24 handler. We allow our parent's handler to decide what to do
635; and how to prompt. When our parent returns, we note the return in AL. If
636; he said ABORT, we need to see if we are aborting ourselves. If so, we
637; cannot turn it into fail; we may get a cascade of errors due to the original
638; cause. Instead, we do the ol' disk-reset hack to clean up. This involves
639; issuing a disk-reset, ignoring all errors, and then returning to the caller.
640MY24:
641 ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
642
643; If we are already inside an INT 24, just ignore this error
644 TEST FIN24,-1
645 JZ DO24
646
647 MOV AL,0 ; signal ignore
648 IRET
649
650; Let the user decide what to do
651DO24:
652 PUSHF
653 CALL PREV24 ; simulate INT 24 to him
654
655 CMP AL,2 ; was it ABORT?
656 JNZ DOIRET ; no, let it happen
657
658 PUSH AX
659 PUSH BX
660 MOV AH,GET_CURRENT_PDB ; find out who's terminating
661 INT 21H
662
663 CMP BX,BEGSEG ; is it us?
664 POP BX
665 POP AX
666 JZ DORESET ; no, let it happen
667
668DOIRET:
669 IRET
670
671; We have been instructed to abort ourselves. Since we can't do this, we will
672; perform a disk reset to flush out all buffers and then ignore the errors we
673; get.
674DORESET:
675 MOV FIN24,-1 ; signal that we ignore errors
676 MOV AH,DISK_RESET
677 INT 21H ; clean out cache
678
679 MOV FIN24,0 ; reset flag
680 JMP COMMAND
681
682TERMINATE:
683 ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
684
685 CMP QFLAG,0
686 JNZ QUITING
687
688 MOV AX,BEGSEG
689 MOV USER_PROC_PDB,AX
690 CMP NEWEXEC,0
691 JZ NORMTERM
692
693 MOV AX,CS
694 MOV DS,AX
695 ASSUME DS:DG
696 ;is CLI/STI needed here ? - emk
697 CLI
698 MOV SS,AX
699 ASSUME SS:DG
700
701 MOV SP,OFFSET DG:STACK
702 STI
703 MOV AX,HEADSAVE
704 JMP DEBUG_FOUND
705
706NORMTERM:
707 ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
708
709 PUSH CS
710 POP DS
711 ASSUME DS:DG
712
713 MOV DX,OFFSET DG:ENDMES_PTR
714 JMP SHORT RESTART
715
716QUITING:
717 ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
718
719 CALL RESTORE_DEB_VECT
720
721 MOV AX,(EXIT SHL 8)
722 INT 21H
723
724RESTART:
725 CALL STD_PRINTF
726DABORT:
727 MOV AX,CS
728 MOV DS,AX
729 ASSUME DS:DG
730
731 ;is CLI\STI needed here? - emk
732 CLI
733 MOV SS,AX
734 ASSUME SS:DG
735
736 MOV SP,OFFSET DG:STACK
737 STI
738;;;;;; CALL CRLF
739
740 JMP COMMAND
741
742 IF SYSVER
743SETUDEV:
744 MOV DI,OFFSET DG:CONFCB
745 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR SET_DRIVEID_OPTION
746 INT 21H
747
748 CALL USERDEV
749
750 JMP DISPREG
751
752USERDEV:
753 MOV DX,OFFSET DG:CONFCB
754 MOV AH,FCB_OPEN
755 INT 21H
756
757 OR AL,AL
758 JNZ OPENERR
759
760 MOV SI,DX
761; TEST BYTE PTR [SI.FCB_DEVID],080H ; Device? ; KWC 12/10/86
762; JZ OPENERR ; NO ; KWC 12/10/86
763 MOV AL,BYTE PTR [SI.FCB_NSL_DRIVE] ; KWC 12/10/86
764 AND AL,NOT FCBMASK ; KWC 12/10/86
765 CMP AL,0C0H ; KWC 12/10/86
766 JNE OPENERR ; KWC 12/10/86
767 XOR AL,AL ; KWC 12/10/86
768
769; LDS SI,DWORD PTR [CONFCB.FCB_FIRCLUS] ; KWC 12/10/86
770 LDS SI,DWORD PTR [CONFCB.FCB_NSLD_DRVPTR] ; KWC 12/10/86
771 MOV WORD PTR CS:[CIN],SI
772 MOV WORD PTR CS:[CIN+WORD],DS
773
774 MOV WORD PTR CS:[COUT],SI
775 MOV WORD PTR CS:[COUT+WORD],DS
776 PUSH CS
777 POP DS
778 RET
779
780OPENERR:
781 MOV DX,OFFSET DG:BADDEV_PTR
782 CALL STD_PRINTF
783
784 RET
785 ENDIF
786; Get input line. Convert all characters NOT in quotes to upper case.
787INBUF:
788 CALL RBUFIN
789
790;=========================================================================
791; prep_command_line requires the use of ds:si. ds is left intact for
792; the call. si is initialized to point to the command line input buffer.
793; ds and si are saved since we stomp all over them in prep_command_line.
794;=========================================================================
795
796 push si ;an000;save si
797
798 mov si,offset dg:linebuf ;an000;point to command line
799 call prep_command_line ;an000;invoke command line conversion
800
801 pop si ;an000;restore si
802
803;=========================================================================
804; we have prepped the command line for dbcs. we can now enter the old
805; routines.
806;=========================================================================
807
808 MOV SI,OFFSET DG:LINEBUF
809 MOV DI,OFFSET DG:BYTEBUF
810
811CASECHK:
812
813 LODSB
814
815 call Test_Lead ;DBCS lead byte ;an000; dms;
816; $if c ;yes - ignore 2nd. byte ;an000; dms;
817 JNC $$IF3
818 stosb ;save the byte ;an000; dms;
819 lodsb ;pick up the 2nd. character ;an000; dms;
820 stosb ;save it also ;an000; dms;
821 jmp CaseChk ;read next character ;an000; dms;
822; $endif ; ;an000; dms;
823$$IF3:
824
825 CMP AL,LOWER_A
826 JB NOCONV
827
828 CMP AL,LOWER_Z
829 JA NOCONV
830
831 ADD AL,UPPER_A - LOWER_A ; Convert to upper case
832NOCONV:
833 STOSB
834 CMP AL,CR
835 JZ INDONE
836
837 CMP AL,DOUBLE_QUOTE
838 JZ QUOTSCAN
839
840 CMP AL,SINGLE_QUOTE
841 JNZ CASECHK
842
843QUOTSCAN:
844 MOV AH,AL
845KILLSTR:
846 LODSB
847 STOSB
848 CMP AL,CR ;CARRIAGE RETURN?
849 JZ INDONE
850
851 CMP AL,AH
852 JNZ KILLSTR
853
854 JMP SHORT CASECHK
855
856INDONE:
857 MOV SI,OFFSET DG:BYTEBUF
858 CALL CRLF
859
860 RET
861
862; Physical backspace - blank, backspace, blank
863BACKUP:
864 PUSH DX
865 MOV DX,OFFSET DG:BACMES_PTR
866 CALL STD_PRINTF
867
868 POP DX
869 RET
870
871; Scan for parameters of a command
872SCANP:
873 CALL SCANB ; Get first non-blank
874
875 CMP BYTE PTR [SI],CHAR_COMMA ; One comma between params OK
876 JNE EOLCHK ; If not comma, we found param
877
878 INC SI ; Skip over comma
879; Scan command line for next non-blank character
880SCANB:
881 PUSH AX
882SCANNEXT:
883 LODSB
884 CMP AL,CHAR_BLANK ;is this char a "blank"?
885 JZ SCANNEXT
886
887 CMP AL,CHAR_TAB ;is this char a "tab"?
888 JZ SCANNEXT
889
890 DEC SI ; Back to first non-blank
891 POP AX
892EOLCHK:
893 CMP BYTE PTR [SI],CR ;CARRIAGE RETURN
894 RET
895
896; Hex addition and subtraction
897HEXADD:
898 MOV CX,4
899 CALL GETHEX
900
901 MOV DI,DX
902 MOV CX,4
903 CALL GETHEX
904
905 CALL GETEOL
906
907 PUSH DX
908 ADD DX,DI
909 MOV [ADD_ARG],DX
910 POP DX
911 SUB DI,DX
912 MOV [SUB_ARG],DI
913 MOV DX,OFFSET DG:ADD_PTR
914 CALL PRINTF_CRLF
915
916 RET
917
918; Put the hex address in DS:SI in the argument list for a call to printf
919OUTSI:
920 MOV CS:[HEX_ARG1],DS
921 MOV CS:[HEX_ARG2],SI
922 RET
923
924;Put the hex address in ES:DI in the argument list for a call to printf
925OUTDI:
926 MOV [HEX_ARG1],ES
927 MOV [HEX_ARG2],DI
928 RET
929
930HEX_ADDRESS_ONLY:
931 MOV BYTE PTR [ARG_BUF],0
932HEX_ADDRESS_STR:
933 MOV DX,OFFSET DG:HEX_PTR
934STD_PRINTF:
935 PUSH DX
936 CALL PRINTF
937 POP DX ;ac000;restore dx
938
939 RET
940
941PRINTF_CRLF:
942 PUSH DX
943 CALL PRINTF
944 POP DX ;ac000;restore dx
945CRLF:
946 MOV DX,OFFSET DG:CRLF_PTR
947 PUSH DX
948 CALL PRINTF
949 POP DX ;ac000;restore dx
950
951 RET
952
953HEX:
954 MOV AH,AL ; Save for second digit
955 PUSH CX
956 MOV CL,4
957 SHR AL,CL
958 POP CX
959
960 CALL DIGIT ; First digit
961
962 MOV AL,AH ; Now do digit saved in AH
963DIGIT:
964 AND AL,0FH ; Mask to 4 bits
965 ADD AL,90H
966 DAA
967 ADC AL,40H
968 DAA
969 AND AL,7FH
970 STOSB
971 RET
972
973RBUFIN:
974 PUSH AX
975 PUSH DX
976 MOV AH,STD_CON_STRING_INPUT
977 MOV DX,OFFSET DG:LBUFSIZ
978 INT 21H
979
980 POP DX
981 POP AX
982 RET
983
984; Put one space in the printf output uffer
985BLANK:
986 MOV AL,CHAR_BLANK
987 STOSB
988 RET
989
990; Put CX spaces in the printf output buffer
991TAB:
992 JCXZ TAB_RET
993
994 CALL BLANK
995
996 LOOP TAB
997TAB_RET:
998 RET
999
1000; Command Table. Command letter indexes into table to get
1001; address of command. PERR prints error for no such command.
1002
1003COMTAB DW ASSEM ; A
1004 DW PERR ; B
1005 DW COMPARE ; C
1006 DW DUMP ; D
1007 DW ENTERDATA ; E
1008 DW FILL ; F
1009 DW GO ; G
1010 DW HEXADD ; H
1011 DW INPUT ; I
1012 DW PERR ; J
1013 DW PERR ; K
1014 DW LOAD ; L
1015 DW MOVE ; M
1016 DW NAMED ; N
1017 DW OUTPUT ; O
1018 DW ZTRACE ; P
1019 DW QUIT ; Q (QUIT)
1020 DW REG ; R
1021 DW SEARCH ; S
1022 DW TRACE ; T
1023 DW UNASSEM ; U
1024 DW PERR ; V
1025 DW DWRITE ; W
1026 IF SYSVER
1027 DW SETUDEV ; X
1028 ELSE
1029 DW DEBEMS
1030 ENDIF
1031 DW PERR ; Y
1032 DW PERR ; Z
1033
1034QUIT:
1035 INC BYTE PTR [QFLAG]
1036 MOV BX,[USER_PROC_PDB]
1037FIND_DEBUG:
1038 IF NOT SYSVER
1039 MOV AH,SET_CURRENT_PDB
1040 INT 21H
1041 ENDIF
1042 CALL RELEASEPARITY ; let system do normal parity stuff
1043
1044 CALL RESTORE_DEB_VECT
1045
1046 MOV AX,(EXIT SHL 8)
1047 INT 21H
1048
1049;======================= proc prep_command_line =========================
1050; prep_command_line: This proc converts a Asian DBCS space delimiter (8140h)
1051; into 2 20h values. In this way we can pass command
1052; lines throughout DEBUG without major modification
1053; to the source code. This proc is invoked anywhere
1054; a command line is initially accessed. In the case
1055; of DEBUG it is used in PARSCHK and INBUF.
1056; Any quoted string, a string delimited by ("), will
1057; be ignored.
1058;
1059; input: ds - segment of command line
1060; si - offset of command line
1061;
1062; output: command line with Asian blanks (8140h) converted to
1063; 2020h.
1064;
1065;=========================================================================
1066
1067prep_command_line proc near ;command line conversion
1068 push ax ;save affected regs.
1069 push bx ;
1070 push si ;
1071
1072 mov bl,00h ;initialize flag
1073 ;bl is used to signal
1074 ; a quote delimiter
1075; $DO ;do while not CR
1076$$DO5:
1077 mov al,[si] ;move char from cmd line for compare
1078 cmp al,CR ;is it a CR ?
1079; $LEAVE E ;if CR exit
1080 JE $$EN5
1081
1082 cmp al,quote_char ;is it a quote ?
1083; $IF Z ;if it is a quote
1084 JNZ $$IF7
1085 xor bl,01h ;set or reset the flag
1086; $ENDIF
1087$$IF7:
1088
1089 cmp bl,01h ;is 1st quote set ?
1090; $IF NZ ;if not continue
1091 JZ $$IF9
1092 call TEST_LEAD ;test for dbcs lead byte
1093; $IF C ;we have a lead byte
1094 JNC $$IF10
1095 cmp al,dbcs_delim ;is it a dbcs char? 81h
1096; $IF Z ;if a dbcs char
1097 JNZ $$IF11
1098 mov al,[si+1] ;move next char al
1099 cmp al,asian_blk ;is it an Asian blank? 40h
1100; $IF Z ;if an Asian blank
1101 JNZ $$IF12
1102 mov al,amer_blk ;set up moves
1103 mov [si],al ; to replace
1104 mov [si+1],al ; Asian blank w/20h
1105 inc si ;point to si+1
1106; $ELSE ;if not an asian blank
1107 JMP SHORT $$EN12
1108$$IF12:
1109 inc si ;point to dbcs char
1110; $ENDIF ;
1111$$EN12:
1112; $ENDIF ;
1113$$IF11:
1114; $ENDIF ;end lead byte test
1115$$IF10:
1116; $ENDIF ;
1117$$IF9:
1118 inc si ;point to si+1
1119; $ENDDO ;end do while
1120 JMP SHORT $$DO5
1121$$EN5:
1122 pop si ;restore affected regs.
1123 pop bx ;
1124 pop ax ;
1125 ret ;return to caller
1126prep_command_line endp ;end proc
1127
1128
1129;=========================================================================
1130; DEBUG_LEAD_BYTE - This routine sets the lead-byte-pointers to point
1131; to the dbcs environmental vector table of lead bytes.
1132; This table will be used to determine if we have a
1133; dbcs lead byte.
1134;
1135; Inputs - none
1136;
1137; Outputs- pointer to dbcs environmental vector table of lead bytes
1138; LBTBL DD ?
1139;
1140; Date : 6/16/87
1141;=========================================================================
1142
1143DEBUG_LEAD_BYTE proc near ;an000;get lead byte vector
1144
1145 push ds ;an000;save affected regs
1146 push es ;an000;
1147 push si ;an000;
1148
1149 mov ax,(ECS_call shl 8) or 00h ;an000;get dbcs env. vector
1150 int 21h ;an000;invoke function
1151
1152 assume ds:nothing
1153
1154 mov word ptr cs:lbtbl[0],si ;an000;move offset of table
1155 mov word ptr cs:lbtbl[2],ds ;an000;move segment of table
1156
1157 pop si ;an000;restore affected regs
1158 pop es ;an000;
1159 pop ds ;an000;
1160
1161 ret ;an000;return to caller
1162
1163DEBUG_LEAD_BYTE endp ;an000;end proc
1164
1165;=========================================================================
1166; TEST_LEAD - This routine will determine whether or not we have a valid
1167; lead byte for a DBCS character.
1168;
1169; Inputs : AL - Holds the byte to compare. Passed by POP. ;an001;bgb
1170;
1171; Outputs: Carry set if lead byte
1172; No carry if not lead byte
1173;
1174; Date : 6/16/87
1175;=========================================================================
1176
1177TEST_LEAD proc near ;an000;check for dbcs lead byte
1178
1179 push ds ;an000;save affected regs
1180 push si ;an000;
1181 push ax ;an000;
1182
1183 xchg ah,al ;an000;ah used for compare
1184 mov si,word ptr cs:lbtbl[2] ;an000;get segment of table
1185 mov ds,si ;an000;
1186 mov si,word ptr cs:lbtbl[0] ;an000;get offset of table
1187
1188ck_next:
1189
1190 lodsb ;an000;load al with byte table
1191 or al,al ;an000;end of table?
1192; $IF z ;an000;yes, end of table
1193 JNZ $$IF19
1194 jmp lead_exit ;an000;exit with clear carry
1195; $ELSE ;an000;
1196 JMP SHORT $$EN19
1197$$IF19:
1198 cmp al,ah ;an000;start > character?
1199; $IF a ;an000;it is above
1200 JNA $$IF21
1201 clc ;an000;clear carry flag
1202 jmp lead_exit ;an000;exit with clear carry
1203; $ELSE ;an000;
1204 JMP SHORT $$EN21
1205$$IF21:
1206 lodsb ;an000;load al with byte table
1207 cmp ah,al ;an000;character > end range
1208; $IF a ;an000;not a lead
1209 JNA $$IF23
1210 jmp ck_next ;an000;check next range
1211; $ELSE ;an000;lead byte found
1212 JMP SHORT $$EN23
1213$$IF23:
1214 stc ;an000;set carry flag
1215; $ENDIF ;an000;
1216$$EN23:
1217; $ENDIF ;an000;
1218$$EN21:
1219; $ENDIF ;an000;
1220$$EN19:
1221
1222lead_exit: ;an000;exit from check
1223
1224 pop ax ;an000;
1225 pop si ;an000;restore affected regs.
1226 pop ds ;an000;
1227
1228 ret ;an000;return to caller
1229
1230TEST_LEAD endp ;an000;end proc
1231
1232
1233
1234CODE ENDS
1235 END START
1236 \ No newline at end of file