summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/DEBUG/DEBCOM1.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/DEBUG/DEBCOM1.ASM')
-rw-r--r--v4.0/src/CMD/DEBUG/DEBCOM1.ASM969
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
59CODE SEGMENT PUBLIC BYTE
60CODE ENDS
61
62CONST 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
68CONST ENDS
69
70CSTACK SEGMENT STACK
71CSTACK ENDS
72
73DATA 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
77DATA ENDS
78
79DG GROUP CODE,CONST,CSTACK,DATA
80
81CODE SEGMENT PUBLIC BYTE
82ASSUME 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
95DEBCOM1:
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.
102DSRANGE:
103 MOV BP,[DSSAVE] ; Set default segment to DS
104 MOV [DEFLEN],128 ; And default length to 128 bytes
105RANGE:
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
129DSRNG1:
130 JMP PERROR ; Negative range
131DSRNG2:
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
137GETDEF:
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
148GETLEN:
149 INC SI ; Skip over "L" to length
150 MOV CX,4 ; Length may have 4 digits
151 CALL GETHEX ; Get the range
152
153RNGRET:
154 MOV CX,DX ; Length
155RNGRET1:
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
164OKRET:
165 POP AX ; Segment
166 RET
167DEFAULT:
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
178USEDEF:
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
186DUMP:
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
218INROW:
219 PUSH SI ; Save address for ASCII dump
220BYTE0:
221 CALL BLANK ; Space between bytes
222BYTE1:
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
242ENDROW:
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.
254ASCII:
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
284ASCDMP:
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
292NOPRT:
293 MOV AL,CHAR_PERIOD ; If unprintable character
294PRIN:
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.
320MOVE:
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
347COPYLIST:
348 MOVSB ; Do at least 1 - Range is 1-1
349 DEC CX
350 REP MOVSB ; Block move
351RET1:
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.
357FILL:
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
374BIGRNG:
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.
394SEARCH:
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
407SCAN:
408 MOV SI,OFFSET DG:BYTEBUF ; List kept in byte buffer
409 LODSB ; Bring first byte into AL
410DOSCAN:
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
433TTEST:
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
452GETHX:
453 CALL SCANP
454GETHX1:
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
463GETLP:
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
477GETHEX:
478 CALL GETHX ; Scan to next parameter
479
480 JMP SHORT GETHX2
481
482GETHEX1:
483 CALL GETHX1
484GETHX2:
485 JC PERROR
486RETHX:
487 CLC
488HXERR:
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.
493HEXIN:
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.
497HEXCHK:
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
512RET2:
513 RET
514
515; Process one parameter when a list of bytes is
516; required. Carry set if parameter bad. Called by LIST.
517LISTITEM:
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
531GRET:
532 CLC ; Parameter was OK
533 RET
534
535STRINGCHK:
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
545STRING:
546 MOV AH,AL ; Save for closing quote
547 INC SI
548STRNGLP:
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
560STOSTRG:
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.
568LIST:
569 MOV BX,OFFSET DG:BYTEBUF ; Put byte list in the byte buffer
570LISTLP:
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.
581GETEOL:
582 CALL SCANB ; Skip blanks
583
584 JNZ PERROR ; Better be a RETURN
585RET3:
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.
590PERR:
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".
595PERROR:
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
604PRINT:
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.
612ADDRESS:
613 CALL GET_ADDRESS
614
615 JC PERROR
616
617ADRERR:
618 STC
619 RET
620
621GET_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
638GETDISP:
639 INC SI ; Skip over ":"
640 MOV CX,4
641 CALL GETHX
642
643 POP AX
644 JC ADRERR
645
646GETRET:
647 CLC
648 RET
649
650SEGREG:
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
667SEGLET 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.
672GETLIST:
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.
694ENTERDATA:
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
706GETROW:
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
722GETBYTE:
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
740LOOK_AGAIN:
741 MOV CX,2 ; Max of 2 digits in new value
742 MOV DX,0 ; Intial new value
743GETDIG:
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.
757DWAIT:
758 CALL INPT ; Get command character
759NOHEX:
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
784RUB:
785 MOV AL,CHAR_BACKSPACE
786 CALL OUT_char
787BS:
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
798PUTDOT:
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
806STORE:
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
817NOSTO:
818 INC DI ; Prepare for next location
819 RET
820
821NEXT:
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
846NEWROW:
847 CALL CRLF ; Terminate line
848
849 JMP GETROW ; Print address on new line
850
851PREV:
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
859EOL:
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
866INPT: ;*** 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
880NOTCNTC:
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
891PRINTOFF:
892PRINTON:
893 NOT [PFLAG]
894 JMP SHORT IN
895
896 ELSE
897INPT: ; Change label for build
898 MOV AH,Std_Con_Input ;OPTION=1, STANDARD CONSOLE INPUT
899 INT 21H
900
901 RET
902
903 ENDIF
904OUT_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
935ADDRESS_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
963ADDRESS_32_BIT endp ;an000;end proc
964
965
966
967CODE ENDS
968 END DEBCOM1
969 \ No newline at end of file