summaryrefslogtreecommitdiff
path: root/v2.0/source/DEBCOM1.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v2.0/source/DEBCOM1.ASM')
-rw-r--r--v2.0/source/DEBCOM1.ASM694
1 files changed, 694 insertions, 0 deletions
diff --git a/v2.0/source/DEBCOM1.ASM b/v2.0/source/DEBCOM1.ASM
new file mode 100644
index 0000000..8e992d9
--- /dev/null
+++ b/v2.0/source/DEBCOM1.ASM
@@ -0,0 +1,694 @@
1TITLE PART1 DEBUGGER COMMANDS
2
3; Routines to perform debugger commands except ASSEMble and UASSEMble
4
5.xlist
6.xcref
7 INCLUDE DEBEQU.ASM
8 INCLUDE DOSSYM.ASM
9.cref
10.list
11
12CODE SEGMENT PUBLIC BYTE 'CODE'
13CODE ENDS
14
15CONST SEGMENT PUBLIC BYTE
16
17 EXTRN SYNERR:BYTE
18
19 EXTRN DISPB:WORD,DSIZ:BYTE,DSSAVE:WORD
20 if sysver
21 EXTRN CIN:DWORD,PFLAG:BYTE
22 endif
23
24CONST ENDS
25
26DATA SEGMENT PUBLIC BYTE
27
28 EXTRN DEFLEN:WORD,BYTEBUF:BYTE,DEFDUMP:BYTE
29
30DATA ENDS
31
32DG GROUP CODE,CONST,DATA
33
34
35CODE SEGMENT PUBLIC BYTE 'CODE'
36ASSUME CS:DG,DS:DG,ES:DG,SS:DG
37
38
39 PUBLIC HEXCHK,GETHEX1,PRINT,DSRANGE,ADDRESS,HEXIN,PERROR
40 PUBLIC GETHEX,GET_ADDRESS,GETEOL,GETHX,PERR
41 PUBLIC PERR,MOVE,DUMP,ENTER,FILL,SEARCH,DEFAULT
42 if sysver
43 PUBLIC IN
44 EXTRN DISPREG:NEAR,DEVIOCALL:NEAR
45 endif
46
47 EXTRN OUT:NEAR,CRLF:NEAR,OUTDI:NEAR,OUTSI:NEAR,SCANP:NEAR
48 EXTRN SCANB:NEAR,BLANK:NEAR,TAB:NEAR,PRINTMES:NEAR,COMMAND:NEAR
49 EXTRN HEX:NEAR,BACKUP:NEAR
50
51
52DEBCOM1:
53
54; RANGE - Looks for parameters defining an address range.
55; The first parameter is the starting address. The second parameter
56; may specify the ending address, or it may be preceded by
57; "L" and specify a length (4 digits max), or it may be
58; omitted and a length of 128 bytes is assumed. Returns with
59; segment in AX, displacement in DX, and length in CX.
60
61DSRANGE:
62 MOV BP,[DSSAVE] ; Set default segment to DS
63 MOV [DEFLEN],128 ; And default length to 128 bytes
64RANGE:
65 CALL ADDRESS
66 PUSH AX ; Save segment
67 PUSH DX ; Save offset
68 CALL SCANP ; Get to next parameter
69 MOV AL,[SI]
70 CMP AL,"L" ; Length indicator?
71 JE GETLEN
72 MOV DX,[DEFLEN] ; Default length
73 CALL HEXIN ; Second parameter present?
74 JC GetDef ; If not, use default
75 MOV CX,4
76 CALL GETHEX ; Get ending address (same segment)
77 MOV CX,DX ; Low 16 bits of ending addr.
78 POP DX ; Low 16 bits of starting addr.
79 SUB CX,DX ; Compute range
80 JAE DSRNG2
81DSRNG1: JMP PERROR ; Negative range
82DSRNG2: INC CX ; Include last location
83 JCXZ DSRNG1 ; Wrap around error
84 POP AX ; Restore segment
85 RET
86GetDef:
87 POP CX ; get original offset
88 PUSH CX ; save it
89 NEG CX ; rest of segment
90 JZ RngRet ; use default
91 CMP CX,DX ; more room in segment?
92 JAE RngRet ; yes, use default
93 JMP RngRet1 ; no, length is in CX
94
95GETLEN:
96 INC SI ; Skip over "L" to length
97 MOV CX,4 ; Length may have 4 digits
98 CALL GETHEX ; Get the range
99RNGRET:
100 MOV CX,DX ; Length
101RngRet1:
102 POP DX ; Offset
103 MOV AX,CX
104 ADD AX,DX
105 JNC OKRET
106 CMP AX,1
107 JAE DSRNG1 ; Look for wrap error
108OKRET:
109 POP AX ; Segment
110 RET
111
112DEFAULT:
113; DI points to default address and CX has default length
114 CALL SCANP
115 JZ USEDEF ; Use default if no parameters
116 MOV [DEFLEN],CX
117 CALL RANGE
118 JMP GETEOL
119USEDEF:
120 MOV SI,DI
121 LODSW ; Get default displacement
122 MOV DX,AX
123 LODSW ; Get default segment
124 RET
125
126; Dump an area of memory in both hex and ASCII
127
128DUMP:
129 MOV BP,[DSSAVE]
130 MOV CX,DISPB
131 MOV DI,OFFSET DG:DEFDUMP
132 CALL DEFAULT ; Get range if specified
133 MOV DS,AX ; Set segment
134 MOV SI,DX ; SI has displacement in segment
135
136 IF ZIBO
137 PUSH SI ; save SI away
138 AND SI,0FFF0h ; convert to para number
139 CALL OutSI ; display location
140 POP SI ; get SI back
141 MOV AX,SI ; move offset
142 MOV AH,3 ; spaces per byte
143 AND AL,0Fh ; convert to real offset
144 MUL AH ; compute (AL+1)*3-1
145 OR AL,AL ; set flag
146 JZ InRow ; if xero go on
147 PUSH CX ; save count
148 MOV CX,AX ; move to convenient spot
149 CALL Tab ; move over
150 POP CX ; get back count
151 JMP InRow ; display line
152 ENDIF
153
154ROW:
155 CALL OUTSI ; Print address at start of line
156InRow:
157 PUSH SI ; Save address for ASCII dump
158 CALL BLANK
159BYTE0:
160 CALL BLANK ; Space between bytes
161BYTE1:
162 LODSB ; Get byte to dump
163 CALL HEX ; and display it
164 POP DX ; DX has start addr. for ASCII dump
165 DEC CX ; Drop loop count
166 JZ ToAscii ; If through do ASCII dump
167 MOV AX,SI
168 TEST AL,CS:(BYTE PTR DSIZ) ; On 16-byte boundary?
169 JZ ENDROW
170 PUSH DX ; Didn't need ASCII addr. yet
171 TEST AL,7 ; On 8-byte boundary?
172 JNZ BYTE0
173 MOV AL,"-" ; Mark every 8 bytes
174 CALL OUT
175 JMP SHORT BYTE1
176ENDROW:
177 CALL ASCII ; Show it in ASCII
178 JMP SHORT ROW ; Loop until count is zero
179ToAscii:
180 MOV AX,SI ; get offset
181 AND AL,0Fh ; real offset
182 JZ ASCII ; no loop if already there
183 SUB AL,10h ; remainder
184 NEG AL
185 MOV CL,3
186 MUL CL
187 MOV CX,AX ; number of chars to move
188 CALL Tab
189ASCII:
190 PUSH CX ; Save byte count
191 MOV AX,SI ; Current dump address
192 MOV SI,DX ; ASCII dump address
193 SUB AX,DX ; AX=length of ASCII dump
194 IF NOT ZIBO
195; Compute tab length. ASCII dump always appears on right side
196; screen regardless of how many bytes were dumped. Figure 3
197; characters for each byte dumped and subtract from 51, which
198; allows a minimum of 3 blanks after the last byte dumped.
199 MOV BX,AX
200 SHL AX,1 ; Length times 2
201 ADD AX,BX ; Length times 3
202 MOV CX,51
203 SUB CX,AX ; Amount to tab in CX
204 CALL TAB
205 MOV CX,BX ; ASCII dump length back in CX
206 ELSE
207 MOV CX,SI ; get starting point
208 DEC CX
209 AND CX,0Fh
210 INC CX
211 AND CX,0Fh
212 ADD CX,3 ; we have the correct number to tab
213 PUSH AX ; save count
214 CALL TAB
215 POP CX ; get count back
216 ENDIF
217ASCDMP:
218 LODSB ; Get ASCII byte to dump
219 AND AL,7FH ; ASCII uses 7 bits
220 CMP AL,7FH ; Don't try to print RUBOUT
221 JZ NOPRT
222 CMP AL," " ; Check for control characters
223 JNC PRIN
224NOPRT:
225 MOV AL,"." ; If unprintable character
226PRIN:
227 CALL OUT ; Print ASCII character
228 LOOP ASCDMP ; CX times
229 POP CX ; Restore overall dump length
230 MOV ES:WORD PTR [DEFDUMP],SI
231 MOV ES:WORD PTR [DEFDUMP+2],DS ; Save last address as default
232 CALL CRLF ; Print CR/LF and return
233 RET
234
235
236; Block move one area of memory to another. Overlapping moves
237; are performed correctly, i.e., so that a source byte is not
238; overwritten until after it has been moved.
239
240MOVE:
241 CALL DSRANGE ; Get range of source area
242 PUSH CX ; Save length
243 PUSH AX ; Save segment
244 PUSH DX ; Save source displacement
245 CALL ADDRESS ; Get destination address (same segment)
246 CALL GETEOL ; Check for errors
247 POP SI
248 MOV DI,DX ; Set dest. displacement
249 POP BX ; Source segment
250 MOV DS,BX
251 MOV ES,AX ; Destination segment
252 POP CX ; Length
253 CMP DI,SI ; Check direction of move
254 SBB AX,BX ; Extend the CMP to 32 bits
255 JB COPYLIST ; Move forward into lower mem.
256; Otherwise, move backward. Figure end of source and destination
257; areas and flip direction flag.
258 DEC CX
259 ADD SI,CX ; End of source area
260 ADD DI,CX ; End of destination area
261 STD ; Reverse direction
262 INC CX
263COPYLIST:
264 MOVSB ; Do at least 1 - Range is 1-10000H not 0-FFFFH
265 DEC CX
266 REP MOVSB ; Block move
267RET1: RET
268
269; Fill an area of memory with a list values. If the list
270; is bigger than the area, don't use the whole list. If the
271; list is smaller, repeat it as many times as necessary.
272
273FILL:
274 CALL DSRANGE ; Get range to fill
275 PUSH CX ; Save length
276 PUSH AX ; Save segment number
277 PUSH DX ; Save displacement
278 CALL LIST ; Get list of values to fill with
279 POP DI ; Displacement in segment
280 POP ES ; Segment
281 POP CX ; Length
282 CMP BX,CX ; BX is length of fill list
283 MOV SI,OFFSET DG:BYTEBUF ; List is in byte buffer
284 JCXZ BIGRNG
285 JAE COPYLIST ; If list is big, copy part of it
286BIGRNG:
287 SUB CX,BX ; How much bigger is area than list?
288 XCHG CX,BX ; CX=length of list
289 PUSH DI ; Save starting addr. of area
290 REP MOVSB ; Move list into area
291 POP SI
292; The list has been copied into the beginning of the
293; specified area of memory. SI is the first address
294; of that area, DI is the end of the copy of the list
295; plus one, which is where the list will begin to repeat.
296; All we need to do now is copy [SI] to [DI] until the
297; end of the memory area is reached. This will cause the
298; list to repeat as many times as necessary.
299 MOV CX,BX ; Length of area minus list
300 PUSH ES ; Different index register
301 POP DS ; requires different segment reg.
302 JMP SHORT COPYLIST ; Do the block move
303
304; Search a specified area of memory for given list of bytes.
305; Print address of first byte of each match.
306
307SEARCH:
308 CALL DSRANGE ; Get area to be searched
309 PUSH CX ; Save count
310 PUSH AX ; Save segment number
311 PUSH DX ; Save displacement
312 CALL LIST ; Get search list
313 DEC BX ; No. of bytes in list-1
314 POP DI ; Displacement within segment
315 POP ES ; Segment
316 POP CX ; Length to be searched
317 SUB CX,BX ; minus length of list
318SCAN:
319 MOV SI,OFFSET DG:BYTEBUF ; List kept in byte buffer
320 LODSB ; Bring first byte into AL
321DOSCAN:
322 SCASB ; Search for first byte
323 LOOPNE DOSCAN ; Do at least once by using LOOP
324 JNZ RET1 ; Exit if not found
325 PUSH BX ; Length of list minus 1
326 XCHG BX,CX
327 PUSH DI ; Will resume search here
328 REPE CMPSB ; Compare rest of string
329 MOV CX,BX ; Area length back in CX
330 POP DI ; Next search location
331 POP BX ; Restore list length
332 JNZ TEST ; Continue search if no match
333 DEC DI ; Match address
334 CALL OUTDI ; Print it
335 INC DI ; Restore search address
336 CALL CRLF
337TEST:
338 JCXZ RET1
339 JMP SHORT SCAN ; Look for next occurrence
340
341; Get the next parameter, which must be a hex number.
342; CX is maximum number of digits the number may have.
343
344GETHX:
345 CALL SCANP
346GETHX1:
347 XOR DX,DX ; Initialize the number
348 CALL HEXIN ; Get a hex digit
349 JC HXERR ; Must be one valid digit
350 MOV DL,AL ; First 4 bits in position
351GETLP:
352 INC SI ; Next char in buffer
353 DEC CX ; Digit count
354 CALL HEXIN ; Get another hex digit?
355 JC RETHX ; All done if no more digits
356 STC
357 JCXZ HXERR ; Too many digits?
358 SHL DX,1 ; Multiply by 16
359 SHL DX,1
360 SHL DX,1
361 SHL DX,1
362 OR DL,AL ; and combine new digit
363 JMP SHORT GETLP ; Get more digits
364
365GETHEX:
366 CALL GETHX ; Scan to next parameter
367 JMP SHORT GETHX2
368GETHEX1:
369 CALL GETHX1
370GETHX2: JC PERROR
371RETHX: CLC
372HXERR: RET
373
374
375; Check if next character in the input buffer is a hex digit
376; and convert it to binary if it is. Carry set if not.
377
378HEXIN:
379 MOV AL,[SI]
380
381; Check if AL has a hex digit and convert it to binary if it
382; is. Carry set if not.
383
384HEXCHK:
385 SUB AL,"0" ; Kill ASCII numeric bias
386 JC RET2
387 CMP AL,10
388 CMC
389 JNC RET2 ; OK if 0-9
390 AND AL,5FH
391 SUB AL,7 ; Kill A-F bias
392 CMP AL,10
393 JC RET2
394 CMP AL,16
395 CMC
396RET2: RET
397
398; Process one parameter when a list of bytes is
399; required. Carry set if parameter bad. Called by LIST.
400
401LISTITEM:
402 CALL SCANP ; Scan to parameter
403 CALL HEXIN ; Is it in hex?
404 JC STRINGCHK ; If not, could be a string
405 MOV CX,2 ; Only 2 hex digits for bytes
406 CALL GETHEX ; Get the byte value
407 MOV [BX],DL ; Add to list
408 INC BX
409GRET: CLC ; Parameter was OK
410 RET
411STRINGCHK:
412 MOV AL,[SI] ; Get first character of param
413 CMP AL,"'" ; String?
414 JZ STRING
415 CMP AL,'"' ; Either quote is all right
416 JZ STRING
417 STC ; Not string, not hex - bad
418 RET
419STRING:
420 MOV AH,AL ; Save for closing quote
421 INC SI
422STRNGLP:
423 LODSB ; Next char of string
424 CMP AL,13 ; Check for end of line
425 JZ PERR ; Must find a close quote
426 CMP AL,AH ; Check for close quote
427 JNZ STOSTRG ; Add new character to list
428 CMP AH,[SI] ; Two quotes in a row?
429 JNZ GRET ; If not, we're done
430 INC SI ; Yes - skip second one
431STOSTRG:
432 MOV [BX],AL ; Put new char in list
433 INC BX
434 JMP SHORT STRNGLP ; Get more characters
435
436; Get a byte list for ENTER, FILL or SEARCH. Accepts any number
437; of 2-digit hex values or character strings in either single
438; (') or double (") quotes.
439
440LIST:
441 MOV BX,OFFSET DG:BYTEBUF ; Put byte list in the byte buffer
442LISTLP:
443 CALL LISTITEM ; Process a parameter
444 JNC LISTLP ; If OK, try for more
445 SUB BX,OFFSET DG:BYTEBUF ; BX now has no. of bytes in list
446 JZ PERROR ; List must not be empty
447
448; Make sure there is nothing more on the line except for
449; blanks and carriage return. If there is, it is an
450; unrecognized parameter and an error.
451
452GETEOL:
453 CALL SCANB ; Skip blanks
454 JNZ PERROR ; Better be a RETURN
455RET3: RET
456
457; Command error. SI has been incremented beyond the
458; command letter so it must decremented for the
459; error pointer to work.
460
461PERR:
462 DEC SI
463
464; Syntax error. SI points to character in the input buffer
465; which caused error. By subtracting from start of buffer,
466; we will know how far to tab over to appear directly below
467; it on the terminal. Then print "^ Error".
468
469PERROR:
470 SUB SI,OFFSET DG:(BYTEBUF-1); How many char processed so far?
471 MOV CX,SI ; Parameter for TAB in CX
472 CALL TAB ; Directly below bad char
473 MOV SI,OFFSET DG:SYNERR ; Error message
474
475; Print error message and abort to command level
476
477PRINT:
478 CALL PRINTMES
479 JMP COMMAND
480
481; Gets an address in Segment:Displacement format. Segment may be omitted
482; and a default (kept in BP) will be used, or it may be a segment
483; register (DS, ES, SS, CS). Returns with segment in AX, OFFSET in DX.
484
485ADDRESS:
486 CALL GET_ADDRESS
487 JC PERROR
488ADRERR: STC
489 RET
490
491GET_ADDRESS:
492 CALL SCANP
493 MOV AL,[SI+1]
494 CMP AL,"S"
495 JZ SEGREG
496 MOV CX,4
497 CALL GETHX
498 JC ADRERR
499 MOV AX,BP ; Get default segment
500 CMP BYTE PTR [SI],":"
501 JNZ GETRET
502 PUSH DX
503GETDISP:
504 INC SI ; Skip over ":"
505 MOV CX,4
506 CALL GETHX
507 POP AX
508 JC ADRERR
509GETRET: CLC
510 RET
511SEGREG:
512 MOV AL,[SI]
513 MOV DI,OFFSET DG:SEGLET
514 MOV CX,4
515 REPNE SCASB
516 JNZ ADRERR
517 INC SI
518 INC SI
519 SHL CX,1
520 MOV BX,CX
521 CMP BYTE PTR [SI],":"
522 JNZ ADRERR
523 PUSH [BX+DSSAVE]
524 JMP SHORT GETDISP
525
526SEGLET DB "CSED"
527
528; Short form of ENTER command. A list of values from the
529; command line are put into memory without using normal
530; ENTER mode.
531
532GETLIST:
533 CALL LIST ; Get the bytes to enter
534 POP DI ; Displacement within segment
535 POP ES ; Segment to enter into
536 MOV SI,OFFSET DG:BYTEBUF ; List of bytes is in byte 2uffer
537 MOV CX,BX ; Count of bytes
538 REP MOVSB ; Enter that byte list
539 RET
540
541; Enter values into memory at a specified address. If the
542; line contains nothing but the address we go into "enter
543; mode", where the address and its current value are printed
544; and the user may change it if desired. To change, type in
545; new value in hex. Backspace works to correct errors. If
546; an illegal hex digit or too many digits are typed, the
547; bell is sounded but it is otherwise ignored. To go to the
548; next byte (with or without change), hit space bar. To
549; back CLDto a previous address, type "-". On
550; every 8-byte boundary a new line is started and the address
551; is printed. To terminate command, type carriage return.
552; Alternatively, the list of bytes to be entered may be
553; included on the original command line immediately following
554; the address. This is in regular LIST format so any number
555; of hex values or strings in quotes may be entered.
556
557ENTER:
558 MOV BP,[DSSAVE] ; Set default segment to DS
559 CALL ADDRESS
560 PUSH AX ; Save for later
561 PUSH DX
562 CALL SCANB ; Any more parameters?
563 JNZ GETLIST ; If not end-of-line get list
564 POP DI ; Displacement of ENTER
565 POP ES ; Segment
566GETROW:
567 CALL OUTDI ; Print address of entry
568 CALL BLANK ; Leave a space
569 CALL BLANK
570GETBYTE:
571 MOV AL,ES:[DI] ; Get current value
572 CALL HEX ; And display it
573PUTDOT:
574 MOV AL,"."
575 CALL OUT ; Prompt for new value
576 MOV CX,2 ; Max of 2 digits in new value
577 MOV DX,0 ; Intial new value
578GETDIG:
579 CALL IN ; Get digit from user
580 MOV AH,AL ; Save
581 CALL HEXCHK ; Hex digit?
582 XCHG AH,AL ; Need original for echo
583 JC NOHEX ; If not, try special command
584 MOV DH,DL ; Rotate new value
585 MOV DL,AH ; And include new digit
586 LOOP GETDIG ; At most 2 digits
587; We have two digits, so all we will accept now is a command.
588DWAIT:
589 CALL IN ; Get command character
590NOHEX:
591 CMP AL,8 ; Backspace
592 JZ BS
593 CMP AL,7FH ; RUBOUT
594 JZ RUB
595 CMP AL,"-" ; Back CLDto previous address
596 JZ PREV
597 CMP AL,13 ; All done with command?
598 JZ EOL
599 CMP AL," " ; Go to next address
600 JZ NEXT
601 MOV AL,8
602 CALL OUT ; Back CLDover illegal character
603 CALL BACKUP
604 JCXZ DWAIT
605 JMP SHORT GETDIG
606
607RUB:
608 MOV AL,8
609 CALL OUT
610BS:
611 CMP CL,2 ; CX=2 means nothing typed yet
612 JZ PUTDOT ; Put back the dot we backed CLDover
613 INC CL ; Accept one more character
614 MOV DL,DH ; Rotate out last digit
615 MOV DH,CH ; Zero this digit
616 CALL BACKUP ; Physical backspace
617 JMP SHORT GETDIG ; Get more digits
618
619; If new value has been entered, convert it to binary and
620; put into memory. Always bump pointer to next location
621
622STORE:
623 CMP CL,2 ; CX=2 means nothing typed yet
624 JZ NOSTO ; So no new value to store
625; Rotate DH left 4 bits to combine with DL and make a byte value
626 PUSH CX
627 MOV CL,4
628 SHL DH,CL
629 POP CX
630 OR DL,DH ; Hex is now converted to binary
631 MOV ES:[DI],DL ; Store new value
632NOSTO:
633 INC DI ; Prepare for next location
634 RET
635NEXT:
636 CALL STORE ; Enter new value
637 INC CX ; Leave a space plus two for
638 INC CX ; each digit not entered
639 CALL TAB
640 MOV AX,DI ; Next memory address
641 AND AL,7 ; Check for 8-byte boundary
642 JNZ GETBYTE ; Take 8 per line
643NEWROW:
644 CALL CRLF ; Terminate line
645 JMP GETROW ; Print address on new line
646PREV:
647 CALL STORE ; Enter the new value
648; DI has been bumped to next byte. Drop it 2 to go to previous addr
649 DEC DI
650 DEC DI
651 JMP SHORT NEWROW ; Terminate line after backing CLD
652
653EOL:
654 CALL STORE ; Enter the new value
655 JMP CRLF ; CR/LF and terminate
656
657; Console input of single character
658
659 IF SYSVER
660IN:
661 PUSH DS
662 PUSH SI
663 LDS SI,CS:[CIN]
664 MOV AH,4
665 CALL DEVIOCALL
666 POP SI
667 POP DS
668 CMP AL,3
669 JNZ NOTCNTC
670 INT 23H
671NOTCNTC:
672 CMP AL,'P'-'@'
673 JZ PRINTON
674 CMP AL,'N'-'@'
675 JZ PRINTOFF
676 CALL OUT
677 RET
678
679PRINTOFF:
680PRINTON:
681 NOT [PFLAG]
682 JMP SHORT IN
683
684 ELSE
685
686IN:
687 MOV AH,1
688 INT 21H
689 RET
690 ENDIF
691
692CODE ENDS
693 END DEBCOM1
694