summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/DEBUG/DEBCOM3.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/DEBUG/DEBCOM3.ASM')
-rw-r--r--v4.0/src/CMD/DEBUG/DEBCOM3.ASM678
1 files changed, 678 insertions, 0 deletions
diff --git a/v4.0/src/CMD/DEBUG/DEBCOM3.ASM b/v4.0/src/CMD/DEBUG/DEBCOM3.ASM
new file mode 100644
index 0000000..21e971c
--- /dev/null
+++ b/v4.0/src/CMD/DEBUG/DEBCOM3.ASM
@@ -0,0 +1,678 @@
1 PAGE 80,132 ;
2 TITLE DEBCOM3.ASM - PART3 DEBUGGER COMMANDS
3; ROUTINES TO PERFORM DEBUGGER COMMANDS
4
5 IF1
6 %OUT COMPONENT=DEBUG, MODULE=DEBCOM3
7 ENDIF
8.XLIST
9.XCREF
10 INCLUDE DOSSYM.INC
11 INCLUDE DEBEQU.ASM
12 INCLUDE DPL.ASM
13.CREF
14.LIST
15CODE SEGMENT PUBLIC BYTE
16CODE ENDS
17
18CONST SEGMENT PUBLIC BYTE
19 EXTRN USER_PROC_PDB:WORD,RSTACK:WORD,STACK:BYTE
20 EXTRN DSSAVE:WORD,CSSAVE:WORD,IPSAVE:WORD,axSAVE:WORD,dxSAVE:WORD
21 EXTRN SSSAVE:WORD,SPSAVE:WORD,FLSAVE:WORD
22 EXTRN NEXTCS:WORD,NEXTIP:WORD, RSETFLAG:BYTE
23CONST ENDS
24
25CSTACK SEGMENT STACK
26CSTACK ENDS
27
28DATA SEGMENT PUBLIC BYTE
29 EXTRN BRKCNT:WORD,TCOUNT:WORD,SWITCHAR:BYTE,BPTAB:BYTE
30 EXTRN BP_ERROR:BYTE,COMP_ARG1:WORD,COMP_ARG2:WORD,COMP_ARG3:WORD
31 EXTRN COMP_ARG4:WORD,COMP_ARG5:WORD,COMP_ARG6:WORD,COMP_PTR:BYTE
32 EXTRN ARG_BUF:BYTE,ARG_BUF_PTR:BYTE
33 EXTRN FZTRACE:BYTE, SYNERR_PTR:BYTE
34 EXTRN BEGSEG:WORD
35 IF IBMVER
36 EXTRN OLD_MASK:BYTE
37 ENDIF
38 EXTRN SAVESTATE:BYTE
39DATA ENDS
40
41DG GROUP CODE,CONST,CSTACK,DATA
42
43CODE SEGMENT PUBLIC BYTE
44ASSUME CS:DG,DS:DG,ES:DG,SS:DG
45 PUBLIC COMPARE,INPUT,OUTPUT,GO
46 PUBLIC TRACE,ZTRACE,SKIP_FILE
47 EXTRN GETHEX:NEAR,GETEOL:NEAR,CRLF:NEAR,ERR:NEAR, PERR:NEAR
48 EXTRN HEX:NEAR,DIGIT:NEAR,SCANP:NEAR,DISPREG:NEAR
49 EXTRN COMMAND:NEAR,DABORT:NEAR,DELIM1:NEAR,DELIM2:NEAR
50 EXTRN NMIINT:NEAR,NMIINTEND:NEAR,PRINTF_CRLF:NEAR
51 EXTRN ADDRESS:NEAR,HEXIN:NEAR,DSRANGE:NEAR
52; just like trace except skips OVER next INT or CALL.
53DEBCOM3:
54ZTRACE:
55 MOV FZTRACE,-1
56 CALL SETADD
57 CALL SCANP
58 CALL HEXIN
59 MOV DX,1
60 JC ZSTOCNT
61 MOV CX,4
62 CALL GETHEX
63 CALL CHECKNONE
64ZSTOCNT:
65 MOV [TCOUNT],DX
66 CALL GETEOL
67 MOV DX,NEXTCS
68 MOV CSSAVE,DX
69 MOV DX,NEXTIP
70 MOV IPSAVE,DX
71ZSTEP:
72 MOV ES,[CSSAVE] ; point to instruction to execute
73 MOV DI,[IPSAVE] ; include offset in segment
74 XOR DX,DX ; where to place breakpoint
75get_opcode:
76 MOV AL,ES:[DI] ; get the opcode
77 cmp al,0f0h ; lock
78 je is_override
79 cmp al,26h ; es:
80 je is_override
81 cmp al,2eh ; cs:
82 je is_override
83 cmp al,36h ; ss:
84 je is_override
85 cmp al,3eh ; ds:
86 jne not_override
87Is_override:
88; inc dx ; this seemed to put us in an endless
89 inc di ; loop, try this.
90 jmp get_opcode
91Not_override:
92 CMP AL,11101000B ; direct intra call
93 JZ ZTRACE3 ; yes, 3 bytes
94 CMP AL,10011010B ; direct inter call
95 JZ ZTRACE5 ; yes, 5 bytes
96 CMP AL,11111111B ; indirect?
97 JZ ZTRACEMODRM ; yes, go figure length
98 CMP AL,11001100B ; short interrupt?
99 JZ ZTRACE1 ; yes, 1 byte
100 CMP AL,11001101B ; long interrupt?
101 JZ ZTRACE2 ; yes, 2 bytes
102 CMP AL,11100010B ; loop
103 JZ ZTRACE2 ; 2 byter
104 CMP AL,11100001B ; loopz/loope
105 JZ ZTRACE2 ; 2 byter
106 CMP AL,11100000B ; loopnz/loopne
107 JZ ZTRACE2 ; 2 byter
108 AND AL,11111110B ; check for rep
109 CMP AL,11110010B ; perhaps?
110 JZ FOO1
111 JMP STEP ; can't do anything special, step
112FOO1:
113 MOV AL,ES:[DI+1] ; next instruction
114 AND AL,11111110B ; ignore w bit
115 CMP AL,10100100B ; MOVS
116 JZ ZTRACE2 ; two byte
117 CMP AL,10100110B ; CMPS
118 JZ ZTRACE2 ; two byte
119 CMP AL,10101110B ; SCAS
120 JZ ZTRACE2 ; two byte
121 CMP AL,10101100B ; LODS
122 JZ ZTRACE2 ; two byte
123 CMP AL,10101010B ; STOS
124 JZ ZTRACE2 ; two byte
125 JMP STEP ; bogus, do single step
126
127ZTRACEMODRM:
128 MOV AL,ES:[DI+1] ; get next byte
129 AND AL,11111000B ; get mod and type
130 CMP AL,01010000B ; indirect intra 8 bit offset?
131 JZ ZTRACE3 ; yes, three byte whammy
132 CMP AL,01011000B ; indirect inter 8 bit offset
133 JZ ZTRACE3 ; yes, three byte guy
134 CMP AL,10010000B ; indirect intra 16 bit offset?
135 JZ ZTRACE4 ; four byte offset
136 CMP AL,10011000B ; indirect inter 16 bit offset?
137 JZ ZTRACE4 ; four bytes
138 CMP AL,11010000B ; indirect through reg?
139 JZ ZTRACE2 ; two byte instruction
140 JMP STEP ; can't figger out what this is!
141ZTRACE5:
142 INC DX
143ZTRACE4:
144 INC DX
145ZTRACE3:
146 INC DX
147ZTRACE2:
148 INC DX
149ZTRACE1:
150 INC DX
151 ADD DI,DX ; offset to breakpoint instruction
152 MOV WORD PTR [BPTAB],DI ; save offset
153 MOV WORD PTR [BPTAB+2],ES ; save segment
154 MOV AL,ES:[DI] ; get next opcode byte
155 MOV BYTE PTR [BPTAB+4],AL ; save it
156 MOV BYTE PTR ES:[DI],0CCH ; break point it
157 MOV [BRKCNT],1 ; only this breakpoint
158 JMP DEXIT ; start the operation!
159
160; Trace 1 instruction or the number of instruction specified
161; by the parameter using 8086 trace mode. Registers are all
162; set according to values in save area
163TRACE:
164 MOV FZTRACE,0
165 CALL SETADD
166 CALL SCANP
167 CALL HEXIN
168 MOV DX,1
169 JC STOCNT
170 MOV CX,4
171 CALL GETHEX
172 CALL CHECKNONE
173STOCNT:
174 MOV [TCOUNT],DX
175 CALL GETEOL
176 MOV DX,NEXTCS
177 MOV CSSAVE,DX
178 MOV DX,NEXTIP
179 MOV IPSAVE,DX
180STEP:
181 MOV [BRKCNT],0
182; The 286 has a problem with trace mode and software interrupt instructions;
183; it treats them as atomic operations. We simulate the operation in software.
184 MOV ES,[CSSAVE] ; Get next instruction pointer
185 MOV DI,[IPSAVE]
186 MOV AL,ES:[DI] ; get next opcode
187 cmp al,0e4h ; check for 'IN' opcode
188 jne not_inal_op
189 cmp es:byte ptr[di+1],21h
190 jne not_mask_op
191 add [ipsave],2
192 JMP SETalmask
193
194not_inal_op:
195 cmp al,0ech ; in al,DX ?
196 jne not_mask_op
197 cmp dxsave,21h
198 jne not_mask_op
199 add [ipsave],1
200SETalmask:
201 mov ax,[axsave]
202 in al,21h
203 mov [axsave],ax
204 JMP SETENVIRON
205
206not_mask_op:
207 CMP AL,0CDH ; trace over an interrupt?
208 JZ DOINT ; no, check for other special cases
209 CMP AL,0CEH ; how about int overflow
210 JNZ CHECKCC
211 TEST FLSAVE,F_OVERFLOW ; see it overflow is present
212 JZ CHECKOP
213 MOV BX,4 ; INTO = INT 4
214 DEC IPSAVE ; INTO is a singel byte
215 JMP SHORT DOVAL
216CHECKCC:
217 CMP AL,0CCH
218 JNZ CHECKOP
219 MOV BX,3 ; INT 3 = CC
220 DEC IPSAVE
221 JMP SHORT DOVAL
222DOINT:
223; We have a software interrupt. Get destination vector
224 MOV BL,BYTE PTR ES:[DI+1] ; get vector number
225 XOR BH,BH ; clear out upper
226DOVAL:
227 SHL BX,1 ; word index
228 SHL BX,1 ; dword index
229 XOR DI,DI ; interrupt table
230 MOV ES,DI
231 MOV AX,ES:[BX] ; point to vector
232 MOV BX,ES:[BX+2] ; point to vector
233; AX:BX is the vector. Swap it with currect CS:IP
234 XCHG AX,IPSAVE ; new CS:IP
235 XCHG BX,CSSAVE
236; AX:BX is old CS:IP. We 'PUSH' flags, oldCS and oldIP, reset flags (ifl) and
237; set CS:IP to point to interrupt instruction.
238 MOV ES,SSSAVE ; point to user stack
239 MOV DI,SPSAVE
240; Take old flags and PUSH the flags.
241 MOV CX,FLSAVE ; get flags
242 SUB DI,2 ; PUSHF
243 MOV ES:[DI],CX ; rest of push
244; Push the old CS
245 SUB DI,2 ; PUSH CS
246 MOV ES:[DI],BX ; rest of push
247; Push the old IP
248 SUB DI,2 ; PUSH IP
249 ADD AX,2 ; increment IP
250 MOV ES:[DI],AX ; rest of push
251; Update stack
252 MOV SPSAVE,DI ; store
253; Take flags and turn interrupts off and trace mode off
254 AND CX,NOT F_INTERRUPT ; CLI
255 AND CX,NOT F_TRACE ; no trace
256 MOV FLSAVE,CX ; rest of CLI
257; Set up correct process and go to normal reentry code.
258 IF NOT SYSVER
259 MOV BX,[USER_PROC_PDB]
260 MOV AH,SET_CURRENT_PDB
261 INT 21H
262 ENDIF
263 JMP SETENVIRON
264; We need to special case the following instructions that may push a TRACE bit
265; on the stack: PUSHF (9C)
266
267; Save the opcode in A Special place
268CHECKOP:
269 MOV RSETFLAG,AL ; no bits to turn off
270SETTRACE:
271 OR FLSAVE,F_TRACE ; Turn on trace bit
272 IF IBMVER
273 CLI
274 IN AL,MASK_PORT ; Get current mask
275 JMP SHORT FOO
276FOO:
277 MOV [OLD_MASK],AL ; Save it
278 MOV AL,INT_MASK ; New mask
279 OUT MASK_PORT,AL ; Set it
280 STI
281 ENDIF
282DEXIT:
283 IF NOT SYSVER
284 MOV BX,[USER_PROC_PDB]
285 MOV AH,SET_CURRENT_PDB
286 INT 21H
287 ENDIF
288; Unfortunately, any system call we issue will muck with the current extended
289; errors. Here we must restore the extended error state so that if the user
290; program gets it, we do not interfere.
291 MOV AX,(SERVERCALL SHL 8) + 10
292 MOV DX,OFFSET DG:SAVESTATE
293 INT 21H
294 PUSH DS
295 XOR AX,AX
296 MOV DS,AX
297 MOV WORD PTR DS:[12],OFFSET DG:BREAKFIX ; Set vector 3--breakpoint instruction
298 MOV WORD PTR DS:[14],CS
299 MOV WORD PTR DS:[4],OFFSET DG:REENTER ; Set vector 1--Single step
300 MOV WORD PTR DS:[6],CS
301 CLI
302 IF SETCNTC
303 MOV WORD PTR DS:[8CH],OFFSET DG:CONTC ; Set vector 23H (CTRL-C)
304 MOV WORD PTR DS:[8EH],CS
305 ENDIF
306 POP DS
307 MOV SP,OFFSET DG:STACK
308 POP AX
309 POP BX
310 POP CX
311 POP DX
312 POP BP
313 POP BP
314 POP SI
315 POP DI
316 POP ES
317 POP ES
318 POP SS
319 MOV SP,[SPSAVE]
320 PUSH [FLSAVE]
321 PUSH [CSSAVE]
322 PUSH [IPSAVE]
323 MOV DS,[DSSAVE]
324 IRET
325STEP1:
326 CALL CRLF
327 CALL DISPREG
328 TEST FZTRACE,-1
329 JNZ STEPZ
330 JMP STEP
331STEPZ: JMP ZSTEP
332
333; Re-entry point from CTRL-C. Top of stack has address in 86-DOS for
334; continuing, so we must pop that off.
335CONTC:
336 ADD SP,6
337 JMP SHORT REENTERREAL
338
339; Re-entry point from breakpoint. Need to decrement instruction
340; pointer so it points to location where breakpoint actually
341; occured.
342BREAKFIX:
343 PUSH BP
344 MOV BP,SP
345 DEC WORD PTR [BP].OLDIP
346 POP BP
347 JMP REENTERREAL
348
349; Re-entry point from trace mode or interrupt during execution. All registers
350; are saved so they can be displayed or modified.
351INTERRUPT_FRAME STRUC
352OLDBP DW ?
353OLDIP DW ?
354OLDCS DW ?
355OLDF DW ?
356OLDERIP DW ?
357OLDERCS DW ?
358OLDERF DW ?
359INTERRUPT_FRAME ENDS
360
361ASSUME CS:DG,DS:NOTHING,ES:NOTHING,SS:NOTHING
362; ReEnter is the main entry point for breakpoint interrupts and for trace mode
363; interrupts. We treat both of these cases identically: save state, display
364; registers and go for another command. If we get NMI's, we skip them or if
365; it turns out that we are debugging ourselves, we skip them.
366
367; Due to bogosities in the 808x chip, Consider tracing over an interrupt and
368; then setting a breakpoint to where the interrupt returns. You get the INT 3
369; and then trace mode gets invoked! This is why we ignore interrupts within
370; ourselves.
371REENTER:
372 PUSH BP
373 MOV BP,SP ; get a frame to address from
374 PUSH AX
375; MOV AX,CS
376; CMP AX,[BP].OLDCS ; Did we interrupt ourselves?
377; JNZ GOREENTER ; no, go reenter
378 IF IBMJAPAN
379 MOV AX,[BP].OLDIP
380 CMP AX,OFFSET DG:NMIINT ; interrupt below NMI interrupt?
381 JB GOREENTER ; yes, go reenter
382 CMP [BP].OLDIP,OFFSET DG:NMIINTEND
383 JAE GOREENTER ; interrupt above NMI interrupt?
384 POP AX ; restore state
385 POP BP
386 SUB SP,6 ; switch TRACE and NMI stack frames
387 PUSH BP
388 MOV BP,SP ; set up frame
389 PUSH AX ; get temp variable
390 MOV AX,[BP].OLDERIP ; get NMI Vector
391 MOV [BP].OLDIP,AX ; stuff in new NMI vector
392 MOV AX,[BP].OLDERCS ; get NMI Vector
393 MOV [BP].OLDCS,AX ; stuff in new NMI vector
394 MOV AX,[BP].OLDERF ; get NMI Vector
395 AND AH,0FEH ; turn off Trace if present
396 MOV [BP].OLDF,AX ; stuff in new NMI vector
397 MOV [BP].OLDERF,AX
398 MOV [BP].OLDERIP,OFFSET DG:REENTER ; offset of routine
399 MOV [BP].OLDERCS,CS ; and CS
400 POP AX
401 POP BP
402 IRET ; go try again
403 ENDIF
404GOREENTER:
405 IF IBMVER
406 MOV AL,CS:[OLD_MASK] ; Recover Old mask
407 OUT MASK_PORT,AL ; Restore it
408 ENDIF
409 MOV AL,CS:[RSETFLAG]
410; Determine, based on the previous instruction, what we are supposed to do
411; to flags on the users stack.
412 CMP AL,09CH ; PUSHF
413 JNZ NOFIX
414; OlderIP = flags. Turn off trace bit
415 AND [BP].OLDERIP,NOT F_TRACE
416NOFIX:
417 POP AX
418 POP BP
419REENTERREAL:
420 MOV CS:[SPSAVE+SEGDIF],SP
421 MOV CS:[SSSAVE+SEGDIF],SS
422 MOV CS:[FLSAVE],CS
423 MOV SS,CS:[FLSAVE]
424 MOV SP,OFFSET DG:RSTACK
425 ASSUME SS:DG
426
427 PUSH ES
428 PUSH DS
429 PUSH DI
430 PUSH SI
431 PUSH BP
432 DEC SP
433 DEC SP
434 PUSH DX
435 PUSH CX
436 PUSH BX
437 PUSH AX
438 PUSH SS
439 POP DS
440 ASSUME DS:DG
441
442 MOV SS,[SSSAVE]
443 MOV SP,[SPSAVE]
444 ASSUME SS:NOTHING
445
446 POP [IPSAVE]
447 POP [CSSAVE]
448 POP AX
449 AND AX,NOT F_TRACE ; TURN OFf trace mode bit
450 MOV [FLSAVE],AX
451 MOV [SPSAVE],SP
452SETENVIRON:
453 PUSH DS
454 POP ES
455 ASSUME ES:DG
456
457 PUSH DS
458 POP SS
459 ASSUME SS:DG
460
461 MOV SP,OFFSET DG:STACK
462 PUSH DS
463 XOR AX,AX
464 MOV DS,AX
465 ASSUME DS:NOTHING
466
467 IF SETCNTC
468 MOV WORD PTR DS:[8CH],OFFSET DG:DABORT ; Set Ctrl-C vector
469 MOV WORD PTR DS:[8EH],CS
470 ENDIF
471 POP DS
472 ASSUME DS:DG
473
474 STI
475 CLD
476; Since we are about to issue system calls, let's grab the current user's
477; extended error info.
478 MOV AH,GETEXTENDEDERROR
479 INT 21H
480 ASSUME DS:NOTHING,ES:NOTHING
481
482 MOV SAVESTATE.DPL_AX,AX
483 MOV SAVESTATE.DPL_BX,BX
484 MOV SAVESTATE.DPL_CX,CX
485 MOV SAVESTATE.DPL_DX,DX
486 MOV SAVESTATE.DPL_SI,SI
487 MOV SAVESTATE.DPL_DI,DI
488 MOV SAVESTATE.DPL_DS,DS
489 MOV SAVESTATE.DPL_ES,ES
490 MOV AX,CS
491 MOV DS,AX
492 MOV ES,AX
493 ASSUME DS:DG,ES:DG
494
495 IF NOT SYSVER
496 MOV AH,GET_CURRENT_PDB
497 INT 21H
498 MOV [USER_PROC_PDB],BX
499 MOV BX,BEGSEG
500 MOV AH,SET_CURRENT_PDB
501 INT 21H
502 ENDIF
503 MOV SI,OFFSET DG:BPTAB
504 MOV CX,[BRKCNT]
505 JCXZ SHOREG
506 PUSH ES
507CLEARBP:
508 LES DI,DWORD PTR [SI]
509 ADD SI,4
510 MOVSB
511 LOOP CLEARBP
512 POP ES
513SHOREG:
514 DEC [TCOUNT]
515 JZ CHECKDISP
516 JMP STEP1
517CHECKDISP:
518 CALL CRLF
519 CALL DISPREG
520 JMP COMMAND
521
522; Input from the specified port and display result
523INPUT:
524 MOV CX,4 ; Port may have 4 digits
525 CALL GETHEX ; Get port number in DX
526 CALL GETEOL
527
528 IN AL,DX ; Variable port input
529
530 PUSH CS
531 POP ES
532 MOV DI,OFFSET DG:ARG_BUF
533 CALL HEX ; And display
534
535 XOR AL,AL
536 STOSB
537 MOV DX,OFFSET DG:ARG_BUF_PTR
538 JMP PRINTF_CRLF
539
540; Output a value to specified port.
541OUTPUT:
542 MOV CX,4 ; Port may have 4 digits
543 CALL GETHEX ; Get port number
544 PUSH DX ; Save while we get data
545 MOV CX,2 ; Byte output only
546 CALL GETHEX ; Get data to output
547 CALL GETEOL
548 XCHG AX,DX ; Output data in AL
549 POP DX ; Port in DX
550
551 OUT DX,AL ; Variable port output
552
553 RETURN
554
555SETADD:
556 MOV DX,CSSAVE ; set up start addresses
557 MOV NEXTCS,DX
558 MOV DX,IPSAVE
559 MOV NEXTIP,DX
560 MOV BP,[CSSAVE]
561 CALL SCANP
562 CMP BYTE PTR [SI],"="
563 RETNZ
564 INC SI
565 CALL ADDRESS
566 MOV NEXTCS,AX
567 MOV NEXTIP,DX
568 RETURN
569
570; Jump to program, setting up registers according to the
571; save area. up to 10 breakpoint addresses may be specified.
572GO:
573 MOV RSETFLAG,0
574 CALL SETADD
575 XOR BX,BX
576 MOV DI,OFFSET DG:BPTAB
577GO1:
578 CALL SCANP
579 JZ DEXEC
580 MOV BP,[CSSAVE]
581 PUSH DI
582 PUSH BX ;AN000; DMS;SAVE BX - ADDRESS KILLS IT
583 CALL ADDRESS
584 POP BX ;AN000; DMS;RESTORE BX
585 POP DI
586 MOV [DI],DX ; Save offset
587 MOV [DI+2],AX ; Save segment
588 ADD DI,5 ; Leave a little room
589 INC BX
590 CMP BX,1+BPMAX
591 JNZ GO1
592 MOV DX,OFFSET DG:BP_ERROR ; BP ERROR
593 JMP ERR
594DEXEC:
595 MOV [BRKCNT],BX
596 MOV CX,BX
597 JCXZ NOBP
598 MOV DI,OFFSET DG:BPTAB
599 PUSH DS
600SETBP:
601 LDS SI,ES:DWORD PTR [DI]
602 ADD DI,4
603 MOVSB
604 MOV BYTE PTR [SI-1],0CCH
605 LOOP SETBP
606 POP DS
607NOBP:
608 MOV DX,NEXTCS
609 MOV CSSAVE,DX
610 MOV DX,NEXTIP
611 MOV IPSAVE,DX
612 MOV [TCOUNT],1
613 JMP DEXIT
614
615SKIP_FILE:
616 MOV AH,CHAR_OPER
617 INT 21H
618 MOV CS:[SWITCHAR],DL ; GET THE CURRENT SWITCH CHARACTER
619FIND_DELIM:
620 LODSB
621 CALL DELIM1
622 JZ GOTDELIM
623 CALL DELIM2
624 JNZ FIND_DELIM
625GOTDELIM:
626 DEC SI
627 RETURN
628
629COMPARE:
630 CALL DSRANGE
631 PUSH CX
632 PUSH AX
633 PUSH DX
634 CALL ADDRESS ; Same segment
635 CALL GETEOL
636 POP SI
637 MOV DI,DX
638 MOV ES,AX
639 POP DS
640 POP CX ; Length
641 DEC CX
642 CALL COMP ; Do one less than total
643 INC CX ; CX=1 (do last one)
644COMP:
645 REPE CMPSB
646 RETZ
647; Compare error. Print address, value; value, address.
648 DEC SI
649 MOV CS:COMP_ARG1,DS
650 MOV CS:COMP_ARG2,SI
651 XOR AH,AH
652 LODSB
653 MOV CS:COMP_ARG3,AX
654 DEC DI
655 MOV AL,ES:[DI]
656 MOV CS:COMP_ARG4,AX
657 MOV CS:COMP_ARG5,ES
658 MOV CS:COMP_ARG6,DI
659 INC DI
660 PUSH DS
661 PUSH CS
662 POP DS
663 MOV DX,OFFSET DG:COMP_PTR
664 CALL PRINTF_CRLF
665 POP DS
666 XOR AL,AL
667 JMP SHORT COMP
668
669 PROCEDURE CHECKNONE,NEAR
670 OR DX,DX
671 RETNZ
672 MOV DX,OFFSET DG:SYNERR_PTR ; ERROR MESSAGE
673 JMP PERR
674 ENDPROC CHECKNONE
675
676CODE ENDS
677 END DEBCOM3
678 \ No newline at end of file