]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/CMD/DEBUG/DEBCOM1.ASM

wirehaze git hosting

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