2 TITLE DEBUG
.SAL - DEBUGger for PC DOS
4 ;======================= START OF SPECIFICATIONS =========================
6 ; MODULE NAME: DEBUG.SAL
8 ; DESCRIPTIVE NAME: DEBUGGING TOOL
10 ; FUNCTION: PROVIDES USERS WITH A TOOL FOR DEBUGGING PROGRAMS.
14 ; INPUT: DOS COMMAND LINE
21 ; INTERNAL REFERENCES:
23 ; EXTERNAL REFERENCES:
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
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
38 ; AN000 VERSION 4.00 - REVISIONS MADE RELATE TO THE FOLLOWING:
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
45 ; COPYRIGHT: "MS DOS DEBUG UTILITY"
46 ; "VERSION 4.00 (C) COPYRIGHT 1988 Microsoft"
47 ; "LICENSED MATERIAL - PROPERTY OF Microsoft "
49 ; MICROSOFT REVISION HISTORY:
51 ; Modified 5/4/82 by AaronR to do all I/O direct to devices
52 ; Runs on MS-DOS 1.28 and above
56 ; New device interface (1.29 and above)
58 ; line by line assembler added by C. P.
60 ; Uses EXEC system call
62 ; Ztrace mode by zibo.
63 ; Fix dump display to indent properly
64 ; Parity nonsense by zibo
67 ; Use Printf for all standard output.
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 ===========================
76 %
OUT COMPONENT
=DEBUG
, MODULE
=DEBUG
80 INCLUDE DOSSYM
.INC ; ALSO VERSION NUMBER
85 ; Structure for system call 72
87 DPBHEAD
DD ?
; Pointer to head of DPB-FAT list
88 SFT_ADDR
DD ?
; Pointer to first FCB table
89 ; The following address points to the CLOCK device
91 ; The following address is used by DISKSTATCHK it is always
92 ; points to the console input device header
93 BCON
DD ?
; Console device entry points
94 MAXSEC
DW 0 ; Maximum allowed sector size
99 NUMIO
DB 0 ; Number of disk tables
107 ;======================= macro equates ===================================
109 dbcs_delim equ 81h
;an000;delimits dbcs char
110 asian_blk equ 40h
;an000;asian blank
111 amer_blk equ 20h
;an000;american blank
112 quote_char equ 22h
;an000;quote delim "
114 ;======================= end macro equates ===============================
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!
123 A_CREATE_BLOCK
SEGMENT
127 ;The other arguements to this system call have been set up
131 MOV AH,CREATE_PROCESS_DATA_BLOCK
152 DG GROUP
CODE,CONST
,CSTACK
,DATA
154 CONST
SEGMENT PUBLIC BYTE
155 EXTRN BADVER
:BYTE,ENDMES_PTR
:BYTE,CRLF_PTR
:BYTE
157 EXTRN PARITYMES_PTR
:BYTE
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
165 EXTRN DSIZ
:BYTE,NOREGL
:BYTE,DISPB
:WORD
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
180 DB (362 - 80H
) + 80H
DUP(?
) ; (362 - 80H) == IBM'S ROM REQUIREMENTS
181 ; (NEW - OLD) == SIZE TO GROW STACK
184 DATA 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
192 extrn lbtbl
:dword ;an000;lead byte table pointer
196 EXTRN PRINTF
:NEAR ;ac000;changed to NEAR call
199 ASSUME
CS:DG
,DS:NOTHING
,ES:NOTHING
,SS:CSTACK
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
211 ; PUBLIC SETUDEV,DEVIOCALL ; kwc 12/10/86
212 PUBLIC SETUDEV
; kwc 12/10/86
213 EXTRN DISPREG
:NEAR,INPT
:NEAR
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
231 HEADER
DB "Vers 2.40"
234 ;=========================================================================
235 ; invoke PRE_LOAD_MESSAGE here. If the messages were not loaded we will
236 ; exit with an appropriate error message.
239 ;=========================================================================
241 push ds ;an000;save regs
242 push es ;an000;save resg
244 push cs ;an000;transfer cs
247 push cs ;an000;transfer cs
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
253 mov ax,(exit
shl 8) ;an000;exit EDLIN. PRE_LOAD_MESSAGE
254 ; has already said why
259 pop es ;an000;restore regs.
261 assume
ds:nothing
,es:nothing
;an000;back to original
263 MOV AX,(GET_INTERRUPT_VECTOR
SHL 8) OR VEC_BREAKPOINT
;get original contents
264 INT 21H
; of the BREAKPOINT vector
266 MOV WORD PTR [BPINTSAV
],BX ; and save that vector for later
267 MOV WORD PTR [BPINTSAV
+WORD],ES ; restoration
269 MOV AX,(GET_INTERRUPT_VECTOR
SHL 8) OR VEC_SING_STEP
;get original contents
270 INT 21H
; of the SINGLE STEP vector
272 MOV WORD PTR [SSINTSAV
],BX ; and save that vector for later
273 MOV WORD PTR [SSINTSAV
+WORD],ES ; restoration
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
286 CALL TRAPPARITY
; scarf up those parity guys
287 MOV AH,GET_CURRENT_PDB
;(undocumented function call - 51h)
290 MOV [USER_PROC_PDB
],BX ; Initially set to DEBUG
300 MOV AH,GET_IN_VARS
;(undocumented function call - 52h)
303 LDS SI,ES:[BX.BCON
] ; get system console device
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
314 MOV DX,OFFSET DG
:CONFCB
; get system printer device
315 MOV AH,FCB_OPEN
; open system printer "PRN"
319 JZ GOTLIST
; yes, it was there
321 MOV DX,OFFSET DG
:BADLSTMES_ptr
; no list file found...
322 CALL STD_PRINTF
; tell user
324 CALL RBUFIN
; ask for a new one
330 JZ NOLIST1
; User didn't specify one
333 MOV DI,OFFSET DG
:(CONFCB
+ BYTE)
334 MOV SI,OFFSET DG
:LINEBUF
; get one from input line
336 MOV DX,OFFSET DG
:CONFCB
337 MOV AH,FCB_OPEN
; try to open it
341 JZ GOTLIST
; yep, use it...
343 MOV DX,OFFSET DG
:BADDEV_Ptr
; complain again
345 NOLIST1: ; kwc 12/10/86
346 MOV WORD PTR [POUT
+WORD],CS ; use null device for printer
347 MOV WORD PTR [POUT
],OFFSET DG
:LONGRET
357 ;DX = OFFSET OF 'CONFCB', WHICH HAS JUST BEEN OPENED OK
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
364 MOV WORD PTR CS:[POUT
+WORD],DS
365 MOV WORD PTR CS:[POUT
],SI
368 MOV AX,CS ;restore the DS and ES segregs
369 MOV DS,AX ; to become once again just like CS
373 ; Code to print header
374 ; MOV DX,OFFSET DG:HEADER_PTR
377 CALL SET_TERMINATE_VECTOR
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
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
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
394 MOV AL,VEC_CTRL_BREAK
; Set vector 23H
395 MOV DX,OFFSET DG
:DABORT
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
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
410 ; Initialize the segments
411 MOV DI,OFFSET DG
:DSSAVE
417 MOV WORD PTR [DISADD
+WORD],AX
418 MOV WORD PTR [ASMADD
+WORD],AX
419 MOV WORD PTR [DEFDUMP
+WORD],AX
422 MOV WORD PTR[DISADD
],AX
423 MOV WORD PTR[ASMADD
],AX
424 MOV WORD PTR [DEFDUMP
],AX
428 ASSUME
DS:NOTHING
,ES:NOTHING
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
445 ; MOV AX,WORD PTR DS:[6]
447 ; MOV BX,OFFSET DG:DATAEND + 15
448 ; AND BX,0FFF0H ; Size of DEBUG in bytes (rounded up to PARA)
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
463 MOV ES:WORD PTR [6],AX ; change PSP to show usage of
464 SUB BX,AX ; new stack area
467 ADD ES:WORD PTR [8],BX
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
487 call DEBUG_LEAD_BYTE
;an000;build the dbcs env. table
488 ; of valid dbcs lead bytes
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 ;=========================================================================
496 push si ;an000;save si
498 mov si,81h
;an000;point to command line
499 call prep_command_line
;an000;invoke command line conversion
501 pop si ;an000;restore si
503 ;=========================================================================
504 ; we have prepped the command line for dbcs. we can now enter the old
506 ;=========================================================================
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
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
520 CALL SKIP_FILE
; Make sure si points to delimiter
521 test1: ;for testing only - u can remove this
524 PUSH CS ;restore ES to point to the
525 POP ES ; common group
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
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
547 PUSH CS ;restore DS to point to the
548 POP DS ; common group
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
562 cli ;disable before setting up the stack - EMK
563 MOV SS,AX ;now everything points to the same group
566 MOV SP,OFFSET DG
:STACK
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
573 MOV DX,OFFSET DG
:PARITYMES_PTR
574 CALL STD_PRINTF
;display msg about parity error
577 MOV DX,OFFSET DG
:PROMPT_PTR
;display the user prompt request
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
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
594 CMP AL,UPPER_Z
- UPPER_A
; Upper end range check
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
602 JMP SHORT COMMAND
; Get next command
606 SET_TERMINATE_VECTOR:
610 MOV AX,(SET_INTERRUPT_VECTOR
SHL 8) OR VEC_TERM_ADDR
; Set vector 22H
611 MOV DX,OFFSET DG
:TERMINATE
622 MOV AX,(SET_INTERRUPT_VECTOR
SHL 8) OR VEC_BREAKPOINT
;Vector 3
626 MOV AX,(SET_INTERRUPT_VECTOR
SHL 8) OR VEC_SING_STEP
;Vector 1
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.
641 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
643 ; If we are already inside an INT 24, just ignore this error
647 MOV AL,0 ; signal ignore
650 ; Let the user decide what to do
653 CALL PREV24
; simulate INT 24 to him
655 CMP AL,2 ; was it ABORT?
656 JNZ DOIRET
; no, let it happen
660 MOV AH,GET_CURRENT_PDB
; find out who's terminating
663 CMP BX,BEGSEG
; is it us?
666 JZ DORESET
; no, let it happen
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
675 MOV FIN24
,-1 ; signal that we ignore errors
677 INT 21H
; clean out cache
679 MOV FIN24
,0 ; reset flag
683 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
696 ;is CLI/STI needed here ? - emk
701 MOV SP,OFFSET DG
:STACK
707 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
713 MOV DX,OFFSET DG
:ENDMES_PTR
717 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
719 CALL RESTORE_DEB_VECT
731 ;is CLI\STI needed here? - emk
736 MOV SP,OFFSET DG
:STACK
744 MOV DI,OFFSET DG
:CONFCB
745 MOV AX,(PARSE_FILE_DESCRIPTOR
SHL 8) OR SET_DRIVEID_OPTION
753 MOV DX,OFFSET DG
:CONFCB
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
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
774 MOV WORD PTR CS:[COUT
],SI
775 MOV WORD PTR CS:[COUT
+WORD],DS
781 MOV DX,OFFSET DG
:BADDEV_PTR
786 ; Get input line. Convert all characters NOT in quotes to upper case.
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 ;=========================================================================
796 push si ;an000;save si
798 mov si,offset dg
:linebuf
;an000;point to command line
799 call prep_command_line
;an000;invoke command line conversion
801 pop si ;an000;restore si
803 ;=========================================================================
804 ; we have prepped the command line for dbcs. we can now enter the old
806 ;=========================================================================
808 MOV SI,OFFSET DG
:LINEBUF
809 MOV DI,OFFSET DG
:BYTEBUF
815 call Test_Lead
;DBCS lead byte ;an000; dms;
816 ; $if c ;yes - ignore 2nd. byte ;an000; dms;
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;
831 ADD AL,UPPER_A
- LOWER_A
; Convert to upper case
848 CMP AL,CR
;CARRIAGE RETURN?
857 MOV SI,OFFSET DG
:BYTEBUF
862 ; Physical backspace - blank, backspace, blank
865 MOV DX,OFFSET DG
:BACMES_PTR
871 ; Scan for parameters of a command
873 CALL SCANB
; Get first non-blank
875 CMP BYTE PTR [SI],CHAR_COMMA
; One comma between params OK
876 JNE EOLCHK
; If not comma, we found param
878 INC SI ; Skip over comma
879 ; Scan command line for next non-blank character
884 CMP AL,CHAR_BLANK
;is this char a "blank"?
887 CMP AL,CHAR_TAB
;is this char a "tab"?
890 DEC SI ; Back to first non-blank
893 CMP BYTE PTR [SI],CR
;CARRIAGE RETURN
896 ; Hex addition and subtraction
913 MOV DX,OFFSET DG
:ADD_PTR
918 ; Put the hex address in DS:SI in the argument list for a call to printf
924 ;Put the hex address in ES:DI in the argument list for a call to printf
931 MOV BYTE PTR [ARG_BUF
],0
933 MOV DX,OFFSET DG
:HEX_PTR
937 POP DX ;ac000;restore dx
944 POP DX ;ac000;restore dx
946 MOV DX,OFFSET DG
:CRLF_PTR
949 POP DX ;ac000;restore dx
954 MOV AH,AL ; Save for second digit
960 CALL DIGIT
; First digit
962 MOV AL,AH ; Now do digit saved in AH
964 AND AL,0FH ; Mask to 4 bits
976 MOV AH,STD_CON_STRING_INPUT
977 MOV DX,OFFSET DG
:LBUFSIZ
984 ; Put one space in the printf output uffer
990 ; Put CX spaces in the printf output buffer
1000 ; Command Table. Command letter indexes into table to get
1001 ; address of command. PERR prints error for no such command.
1035 INC BYTE PTR [QFLAG
]
1036 MOV BX,[USER_PROC_PDB
]
1039 MOV AH,SET_CURRENT_PDB
1042 CALL RELEASEPARITY
; let system do normal parity stuff
1044 CALL RESTORE_DEB_VECT
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
1059 ; input: ds - segment of command line
1060 ; si - offset of command line
1062 ; output: command line with Asian blanks (8140h) converted to
1065 ;=========================================================================
1067 prep_command_line proc
near ;command line conversion
1068 push ax ;save affected regs.
1072 mov bl,00h ;initialize flag
1073 ;bl is used to signal
1075 ; $DO ;do while not CR
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
1082 cmp al,quote_char
;is it a quote ?
1083 ; $IF Z ;if it is a quote
1085 xor bl,01h ;set or reset the flag
1089 cmp bl,01h ;is 1st quote set ?
1090 ; $IF NZ ;if not continue
1092 call TEST_LEAD
;test for dbcs lead byte
1093 ; $IF C ;we have a lead byte
1095 cmp al,dbcs_delim
;is it a dbcs char? 81h
1096 ; $IF Z ;if a dbcs char
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
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
1109 inc si ;point to dbcs char
1114 ; $ENDIF ;end lead byte test
1118 inc si ;point to si+1
1119 ; $ENDDO ;end do while
1122 pop si ;restore affected regs.
1125 ret ;return to caller
1126 prep_command_line endp
;end proc
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
1137 ; Outputs- pointer to dbcs environmental vector table of lead bytes
1141 ;=========================================================================
1143 DEBUG_LEAD_BYTE proc
near ;an000;get lead byte vector
1145 push ds ;an000;save affected regs
1149 mov ax,(ECS_call
shl 8) or 00h ;an000;get dbcs env. vector
1150 int 21h
;an000;invoke function
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
1157 pop si ;an000;restore affected regs
1161 ret ;an000;return to caller
1163 DEBUG_LEAD_BYTE endp
;an000;end proc
1165 ;=========================================================================
1166 ; TEST_LEAD - This routine will determine whether or not we have a valid
1167 ; lead byte for a DBCS character.
1169 ; Inputs : AL - Holds the byte to compare. Passed by POP. ;an001;bgb
1171 ; Outputs: Carry set if lead byte
1172 ; No carry if not lead byte
1175 ;=========================================================================
1177 TEST_LEAD proc
near ;an000;check for dbcs lead byte
1179 push ds ;an000;save affected regs
1183 xchg ah,al ;an000;ah used for compare
1184 mov si,word ptr cs:lbtbl
[2] ;an000;get segment of table
1186 mov si,word ptr cs:lbtbl
[0] ;an000;get offset of table
1190 lodsb ;an000;load al with byte table
1191 or al,al ;an000;end of table?
1192 ; $IF z ;an000;yes, end of table
1194 jmp lead_exit
;an000;exit with clear carry
1198 cmp al,ah ;an000;start > character?
1199 ; $IF a ;an000;it is above
1201 clc ;an000;clear carry flag
1202 jmp lead_exit
;an000;exit with clear carry
1206 lodsb ;an000;load al with byte table
1207 cmp ah,al ;an000;character > end range
1208 ; $IF a ;an000;not a lead
1210 jmp ck_next
;an000;check next range
1211 ; $ELSE ;an000;lead byte found
1214 stc ;an000;set carry flag
1222 lead_exit: ;an000;exit from check
1225 pop si ;an000;restore affected regs.
1228 ret ;an000;return to caller
1230 TEST_LEAD endp
;an000;end proc