summaryrefslogtreecommitdiff
path: root/v2.0/source/DEBCOM2.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v2.0/source/DEBCOM2.ASM')
-rw-r--r--v2.0/source/DEBCOM2.ASM1269
1 files changed, 1269 insertions, 0 deletions
diff --git a/v2.0/source/DEBCOM2.ASM b/v2.0/source/DEBCOM2.ASM
new file mode 100644
index 0000000..a800d4b
--- /dev/null
+++ b/v2.0/source/DEBCOM2.ASM
@@ -0,0 +1,1269 @@
1TITLE PART2 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 NOTFND:BYTE,NOROOM:BYTE,DRVLET:BYTE,NOSPACE:BYTE,NAMBAD:BYTE
18 EXTRN TOOBIG:BYTE,ERRMES:BYTE
19 EXTRN EXEBAD:BYTE,HEXERR:BYTE,EXEWRT:BYTE,HEXWRT:BYTE
20 EXTRN EXECEMES:BYTE,WRTMES1:BYTE,WRTMES2:BYTE,ACCMES:BYTE
21
22 EXTRN FLAGTAB:WORD,EXEC_BLOCK:BYTE,COM_LINE:DWORD,COM_FCB1:DWORD
23 EXTRN COM_FCB2:DWORD,COM_SSSP:DWORD,COM_CSIP:DWORD,RETSAVE:WORD
24 EXTRN NEWEXEC:BYTE,HEADSAVE:WORD
25 EXTRN REGTAB:BYTE,TOTREG:BYTE,NOREGL:BYTE
26 EXTRN USER_PROC_PDB:WORD,STACK:BYTE,RSTACK:WORD,AXSAVE:WORD
27 EXTRN BXSAVE:WORD,DSSAVE:WORD,ESSAVE:WORD,CSSAVE:WORD,IPSAVE:WORD
28 EXTRN SSSAVE:WORD,CXSAVE:WORD,SPSAVE:WORD,FSAVE:WORD
29 EXTRN SREG:BYTE,SEGTAB:WORD,REGDIF:WORD,RDFLG:BYTE
30
31CONST ENDS
32
33DATA SEGMENT PUBLIC BYTE
34
35 EXTRN DEFDUMP:BYTE,TRANSADD:DWORD,INDEX:WORD,BUFFER:BYTE
36 EXTRN ASMADD:BYTE,DISADD:BYTE,NSEG:WORD,BPTAB:BYTE
37 EXTRN BRKCNT:WORD,TCOUNT:WORD,SWITCHAR:BYTE,XNXCMD:BYTE,XNXOPT:BYTE
38 EXTRN AWORD:BYTE,EXTPTR:WORD,HANDLE:WORD,PARSERR:BYTE
39
40DATA ENDS
41
42DG GROUP CODE,CONST,DATA
43
44
45CODE SEGMENT PUBLIC BYTE 'CODE'
46ASSUME CS:DG,DS:DG,ES:DG,SS:DG
47
48 PUBLIC DEFIO,SKIP_FILE,PREPNAME,DEBUG_FOUND
49 PUBLIC REG,COMPARE,GO,INPUT,LOAD
50 PUBLIC NAME,OUTPUT,TRACE,ZTRACE,DWRITE
51 if sysver
52 PUBLIC DISPREG
53 endif
54
55 EXTRN GETHEX:NEAR,GETEOL:NEAR
56 EXTRN CRLF:NEAR,BLANK:NEAR,OUT:NEAR
57 EXTRN OUTSI:NEAR,OUTDI:NEAR,INBUF:NEAR,SCANB:NEAR,SCANP:NEAR
58 EXTRN RPRBUF:NEAR,HEX:NEAR,OUT16:NEAR,DIGIT:NEAR
59 EXTRN COMMAND:NEAR,DISASLN:NEAR,SET_TERMINATE_VECTOR:NEAR
60 EXTRN RESTART:NEAR,DABORT:NEAR,TERMINATE:NEAR,DRVERR:NEAR
61 EXTRN FIND_DEBUG:NEAR,NMIInt:NEAR,NMIIntEnd:NEAR
62 EXTRN HEXCHK:NEAR,GETHEX1:NEAR,PRINT:NEAR,DSRANGE:NEAR
63 EXTRN ADDRESS:NEAR,HEXIN:NEAR,PERROR:NEAR
64
65
66DEBCOM2:
67DISPREG:
68 MOV SI,OFFSET DG:REGTAB
69 MOV BX,OFFSET DG:AXSAVE
70 MOV BYTE PTR TOTREG,13
71 MOV CH,0
72 MOV CL,NOREGL
73REPDISP:
74 SUB TOTREG,CL
75 CALL DISPREGLINE
76 CALL CRLF
77 MOV CH,0
78 MOV CL,NOREGL
79 CMP CL,TOTREG
80 JL REPDISP
81 MOV CL,TOTREG
82 CALL DISPREGLINE
83 CALL BLANK
84 CALL DISPFLAGS
85 CALL CRLF
86 MOV AX,[IPSAVE]
87 MOV WORD PTR [DISADD],AX
88 PUSH AX
89 MOV AX,[CSSAVE]
90 MOV WORD PTR [DISADD+2],AX
91 PUSH AX
92 MOV [NSEG],-1
93 CALL DISASLN
94 POP WORD PTR DISADD+2
95 POP WORD PTR DISADD
96 MOV AX,[NSEG]
97 CMP AL,-1
98 JZ CRLFJ
99 CMP AH,-1
100 JZ NOOVER
101 XCHG AL,AH
102NOOVER:
103 CBW
104 MOV BX,AX
105 SHL BX,1
106 MOV AX,WORD PTR [BX+SREG]
107 CALL OUT
108 XCHG AL,AH
109 CALL OUT
110 MOV AL,":"
111 CALL OUT
112 MOV DX,[INDEX]
113 CALL OUT16
114 MOV AL,"="
115 CALL OUT
116 MOV BX,[BX+SEGTAB]
117 PUSH DS
118 MOV DS,[BX]
119 MOV BX,DX
120 MOV DX,[BX]
121 POP DS
122 TEST BYTE PTR [AWORD],-1
123 JZ OUT8
124 CALL OUT16
125CRLFJ:
126 JMP CRLF
127OUT8:
128 MOV AL,DL
129 CALL HEX
130 JMP CRLF
131
132DISPREGJ:JMP DISPREG
133
134; Perform register dump if no parameters or set register if a
135; register designation is a parameter.
136
137REG:
138 CALL SCANP
139 JZ DISPREGJ
140 MOV DL,[SI]
141 INC SI
142 MOV DH,[SI]
143 CMP DH,13
144 JZ FLAG
145 INC SI
146 CALL GETEOL
147 CMP DH," "
148 JZ FLAG
149 MOV DI,OFFSET DG:REGTAB
150 XCHG AX,DX
151 PUSH CS
152 POP ES
153 MOV CX,REGTABLEN
154 REPNZ SCASW
155 JNZ BADREG
156 OR CX,CX
157 JNZ NOTPC
158 DEC DI
159 DEC DI
160 MOV AX,CS:[DI-2]
161NOTPC:
162 CALL OUT
163 MOV AL,AH
164 CALL OUT
165 CALL BLANK
166 PUSH DS
167 POP ES
168 LEA BX,[DI+REGDIF-2]
169 MOV DX,[BX]
170 CALL OUT16
171 CALL CRLF
172 MOV AL,":"
173 CALL OUT
174 CALL INBUF
175 CALL SCANB
176 JZ RET4
177 MOV CX,4
178 CALL GETHEX1
179 CALL GETEOL
180 MOV [BX],DX
181RET4: RET
182BADREG:
183 MOV AX,5200H+"B" ; BR ERROR
184 JMP ERR
185FLAG:
186 CMP DL,"F"
187 JNZ BADREG
188 CALL DISPFLAGS
189 MOV AL,"-"
190 CALL OUT
191 CALL INBUF
192 CALL SCANB
193 XOR BX,BX
194 MOV DX,[FSAVE]
195GETFLG:
196 LODSW
197 CMP AL,13
198 JZ SAVCHG
199 CMP AH,13
200 JZ FLGERR
201 MOV DI,OFFSET DG:FLAGTAB
202 MOV CX,32
203 PUSH CS
204 POP ES
205 REPNE SCASW
206 JNZ FLGERR
207 MOV CH,CL
208 AND CL,0FH
209 MOV AX,1
210 ROL AX,CL
211 TEST AX,BX
212 JNZ REPFLG
213 OR BX,AX
214 OR DX,AX
215 TEST CH,16
216 JNZ NEXFLG
217 XOR DX,AX
218NEXFLG:
219 CALL SCANP
220 JMP SHORT GETFLG
221DISPREGLINE:
222 LODS CS:WORD PTR [SI]
223 CALL OUT
224 MOV AL,AH
225 CALL OUT
226 MOV AL,"="
227 CALL OUT
228 MOV DX,[BX]
229 INC BX
230 INC BX
231 CALL OUT16
232 CALL BLANK
233 CALL BLANK
234 LOOP DISPREGLINE
235 RET
236REPFLG:
237 MOV AX,4600H+"D" ; DF ERROR
238FERR:
239 CALL SAVCHG
240ERR:
241 CALL OUT
242 MOV AL,AH
243 CALL OUT
244 MOV SI,OFFSET DG:ERRMES
245 JMP PRINT
246SAVCHG:
247 MOV [FSAVE],DX
248 RET
249FLGERR:
250 MOV AX,4600H+"B" ; BF ERROR
251 JMP SHORT FERR
252DISPFLAGS:
253 MOV SI,OFFSET DG:FLAGTAB
254 MOV CX,16
255 MOV DX,[FSAVE]
256DFLAGS:
257 LODS CS:WORD PTR [SI]
258 SHL DX,1
259 JC FLAGSET
260 MOV AX,CS:[SI+30]
261FLAGSET:
262 OR AX,AX
263 JZ NEXTFLG
264 CALL OUT
265 MOV AL,AH
266 CALL OUT
267 CALL BLANK
268NEXTFLG:
269 LOOP DFLAGS
270 RET
271
272; Input from the specified port and display result
273
274INPUT:
275 MOV CX,4 ; Port may have 4 digits
276 CALL GETHEX ; Get port number in DX
277 CALL GETEOL
278 IN AL,DX ; Variable port input
279 CALL HEX ; And display
280 JMP CRLF
281
282; Output a value to specified port.
283
284OUTPUT:
285 MOV CX,4 ; Port may have 4 digits
286 CALL GETHEX ; Get port number
287 PUSH DX ; Save while we get data
288 MOV CX,2 ; Byte output only
289 CALL GETHEX ; Get data to output
290 CALL GETEOL
291 XCHG AX,DX ; Output data in AL
292 POP DX ; Port in DX
293 OUT DX,AL ; Variable port output
294RET5: RET
295COMPARE:
296 CALL DSRANGE
297 PUSH CX
298 PUSH AX
299 PUSH DX
300 CALL ADDRESS ; Same segment
301 CALL GETEOL
302 POP SI
303 MOV DI,DX
304 MOV ES,AX
305 POP DS
306 POP CX ; Length
307 DEC CX
308 CALL COMP ; Do one less than total
309 INC CX ; CX=1 (do last one)
310COMP:
311 REPE CMPSB
312 JZ RET5
313; Compare error. Print address, value; value, address.
314 DEC SI
315 CALL OUTSI
316 CALL BLANK
317 CALL BLANK
318 LODSB
319 CALL HEX
320 CALL BLANK
321 CALL BLANK
322 DEC DI
323 MOV AL,ES:[DI]
324 CALL HEX
325 CALL BLANK
326 CALL BLANK
327 CALL OUTDI
328 INC DI
329 CALL CRLF
330 XOR AL,AL
331 JMP SHORT COMP
332
333ZTRACE:
334IF ZIBO
335; just like trace except skips OVER next INT or CALL.
336 CALL SETADD ; get potential starting point
337 CALL GETEOL ; check for end of line
338 MOV [TCOUNT],1 ; only a single go at it
339 MOV ES,[CSSAVE] ; point to instruction to execute
340 MOV DI,[IPSAVE] ; include offset in segment
341 XOR DX,DX ; where to place breakpoint
342 MOV AL,ES:[DI] ; get the opcode
343 CMP AL,11101000B ; direct intra call
344 JZ ZTrace3 ; yes, 3 bytes
345 CMP AL,10011010B ; direct inter call
346 JZ ZTrace5 ; yes, 5 bytes
347 CMP AL,11111111B ; indirect?
348 JZ ZTraceModRM ; yes, go figure length
349 CMP AL,11001100B ; short interrupt?
350 JZ ZTrace1 ; yes, 1 byte
351 CMP AL,11001101B ; long interrupt?
352 JZ ZTrace2 ; yes, 2 bytes
353 CMP AL,11100010B ; loop
354 JZ ZTrace2 ; 2 byter
355 CMP AL,11100001B ; loopz/loope
356 JZ ZTrace2 ; 2 byter
357 CMP AL,11100000B ; loopnz/loopne
358 JZ ZTrace2 ; 2 byter
359 AND AL,11111110B ; check for rep
360 CMP AL,11110010B ; perhaps?
361 JNZ Step ; can't do anything special, step
362 MOV AL,ES:[DI+1] ; next instruction
363 AND AL,11111110B ; ignore w bit
364 CMP AL,10100100B ; MOVS
365 JZ ZTrace2 ; two byte
366 CMP AL,10100110B ; CMPS
367 JZ ZTrace2 ; two byte
368 CMP AL,10101110B ; SCAS
369 JZ ZTrace2 ; two byte
370 CMP AL,10101100B ; LODS
371 JZ ZTrace2 ; two byte
372 CMP AL,10101010B ; STOS
373 JZ ZTrace2 ; two byte
374 JMP Step ; bogus, do single step
375
376ZTraceModRM:
377 MOV AL,ES:[DI+1] ; get next byte
378 AND AL,11111000B ; get mod and type
379 CMP AL,01010000B ; indirect intra 8 bit offset?
380 JZ ZTrace3 ; yes, three byte whammy
381 CMP AL,01011000B ; indirect inter 8 bit offset
382 JZ ZTrace3 ; yes, three byte guy
383 CMP AL,10010000B ; indirect intra 16 bit offset?
384 JZ ZTrace4 ; four byte offset
385 CMP AL,10011000B ; indirect inter 16 bit offset?
386 JZ ZTrace4 ; four bytes
387 JMP Step ; can't figger out what this is!
388ZTrace5:INC DX
389ZTrace4:INC DX
390ZTrace3:INC DX
391ZTrace2:INC DX
392ZTrace1:INC DX
393 ADD DI,DX ; offset to breakpoint instruction
394 MOV WORD PTR [BPTab],DI ; save offset
395 MOV WORD PTR [BPTab+2],ES ; save segment
396 MOV AL,ES:[DI] ; get next opcode byte
397 MOV BYTE PTR [BPTab+4],AL ; save it
398 MOV BYTE PTR ES:[DI],0CCh ; break point it
399 MOV [BrkCnt],1 ; only this breakpoint
400 JMP DExit ; start the operation!
401 ENDIF
402
403; Trace 1 instruction or the number of instruction specified
404; by the parameter using 8086 trace mode. Registers are all
405; set according to values in save area
406
407TRACE:
408 CALL SETADD
409 CALL SCANP
410 CALL HEXIN
411 MOV DX,1
412 JC STOCNT
413 MOV CX,4
414 CALL GETHEX
415STOCNT:
416 MOV [TCOUNT],DX
417 CALL GETEOL
418STEP:
419 MOV [BRKCNT],0
420 OR BYTE PTR [FSAVE+1],1
421DEXIT:
422IF NOT SYSVER
423 MOV BX,[USER_PROC_PDB]
424 MOV AH,SET_CURRENT_PDB
425 INT 21H
426ENDIF
427 PUSH DS
428 XOR AX,AX
429 MOV DS,AX
430 MOV WORD PTR DS:[12],OFFSET DG:BREAKFIX ; Set vector 3--breakpoint instruction
431 MOV WORD PTR DS:[14],CS
432 MOV WORD PTR DS:[4],OFFSET DG:REENTER ; Set vector 1--Single step
433 MOV WORD PTR DS:[6],CS
434 CLI
435
436 IF SETCNTC
437 MOV WORD PTR DS:[8CH],OFFSET DG:CONTC ; Set vector 23H (CTRL-C)
438 MOV WORD PTR DS:[8EH],CS
439 ENDIF
440
441 POP DS
442 MOV SP,OFFSET DG:STACK
443 POP AX
444 POP BX
445 POP CX
446 POP DX
447 POP BP
448 POP BP
449 POP SI
450 POP DI
451 POP ES
452 POP ES
453 POP SS
454 MOV SP,[SPSAVE]
455 PUSH [FSAVE]
456 PUSH [CSSAVE]
457 PUSH [IPSAVE]
458 MOV DS,[DSSAVE]
459 IRET
460STEP1:
461 CALL CRLF
462 CALL DISPREG
463 JMP SHORT STEP
464
465; Re-entry point from CTRL-C. Top of stack has address in 86-DOS for
466; continuing, so we must pop that off.
467
468CONTC:
469 ADD SP,6
470 JMP SHORT ReEnterReal
471
472; Re-entry point from breakpoint. Need to decrement instruction
473; pointer so it points to location where breakpoint actually
474; occured.
475
476BREAKFIX:
477 PUSH BP
478 MOV BP,SP
479 DEC WORD PTR [BP].OldIP
480 POP BP
481 JMP ReenterReal
482
483; Re-entry point from trace mode or interrupt during
484; execution. All registers are saved so they can be
485; displayed or modified.
486
487Interrupt_Frame STRUC
488OldBP DW ?
489OldIP DW ?
490OldCS DW ?
491OldF DW ?
492OlderIP DW ?
493OlderCS DW ?
494OlderF DW ?
495Interrupt_Frame ENDS
496
497REENTER:
498 PUSH BP
499 MOV BP,SP ; get a frame to address from
500 PUSH AX
501 MOV AX,CS
502 CMP AX,[BP].OldCS ; Did we interrupt ourselves?
503 JNZ GoReEnter ; no, go reenter
504 MOV AX,[BP].OldIP
505 CMP AX,OFFSET DG:NMIInt ; interrupt below NMI interrupt?
506 JB GoReEnter ; yes, go reenter
507 CMP [BP].OLDIP,OFFSET DG:NMIIntEnd
508 JAE GoReEnter ; interrupt above NMI interrupt?
509 POP AX ; restore state
510 POP BP
511 SUB SP,6 ; switch TRACE and NMI stack frames
512 PUSH BP
513 MOV BP,SP ; set up frame
514 PUSH AX ; get temp variable
515 MOV AX,[BP].OlderIP ; get NMI Vector
516 MOV [BP].OldIP,AX ; stuff in new NMI vector
517 MOV AX,[BP].OlderCS ; get NMI Vector
518 MOV [BP].OldCS,AX ; stuff in new NMI vector
519 MOV AX,[BP].OlderF ; get NMI Vector
520 AND AH,0FEh ; turn off Trace if present
521 MOV [BP].OldF,AX ; stuff in new NMI vector
522 MOV [BP].OlderF,AX
523 MOV [BP].OlderIP,OFFSET DG:ReEnter ; offset of routine
524 MOV [BP].OlderCS,CS ; and CS
525 POP AX
526 POP BP
527 IRET ; go try again
528GoReEnter:
529 POP AX
530 POP BP
531ReEnterReal:
532 MOV CS:[SPSAVE+SEGDIF],SP
533 MOV CS:[SSSAVE+SEGDIF],SS
534 MOV CS:[FSAVE],CS
535 MOV SS,CS:[FSAVE]
536 MOV SP,OFFSET DG:RSTACK
537 PUSH ES
538 PUSH DS
539 PUSH DI
540 PUSH SI
541 PUSH BP
542 DEC SP
543 DEC SP
544 PUSH DX
545 PUSH CX
546 PUSH BX
547 PUSH AX
548 PUSH SS
549 POP DS
550 MOV SS,[SSSAVE]
551 MOV SP,[SPSAVE]
552 POP [IPSAVE]
553 POP [CSSAVE]
554 POP AX
555 AND AH,0FEH ; turn off trace mode bit
556 MOV [FSAVE],AX
557 MOV [SPSAVE],SP
558 PUSH DS
559 POP ES
560 PUSH DS
561 POP SS
562 MOV SP,OFFSET DG:STACK
563 PUSH DS
564 XOR AX,AX
565 MOV DS,AX
566
567 IF SETCNTC
568 MOV WORD PTR DS:[8CH],OFFSET DG:DABORT ; Set Ctrl-C vector
569 MOV WORD PTR DS:[8EH],CS
570 ENDIF
571
572 POP DS
573 STI
574 CLD
575IF NOT SYSVER
576 MOV AH,GET_CURRENT_PDB
577 INT 21H
578 MOV [USER_PROC_PDB],BX
579 MOV BX,DS
580 MOV AH,SET_CURRENT_PDB
581 INT 21H
582ENDIF
583 DEC [TCOUNT]
584 JZ CheckDisp
585 JMP Step1
586CheckDisp:
587 MOV SI,OFFSET DG:BPTAB
588 MOV CX,[BRKCNT]
589 JCXZ SHOREG
590 PUSH ES
591CLEARBP:
592 LES DI,DWORD PTR [SI]
593 ADD SI,4
594 MOVSB
595 LOOP CLEARBP
596 POP ES
597SHOREG:
598 CALL CRLF
599 CALL DISPREG
600 JMP COMMAND
601
602SETADD:
603 MOV BP,[CSSAVE]
604 CALL SCANP
605 CMP BYTE PTR [SI],"="
606 JNZ RET$5
607 INC SI
608 CALL ADDRESS
609 MOV [CSSAVE],AX
610 MOV [IPSAVE],DX
611RET$5: RET
612
613; Jump to program, setting up registers according to the
614; save area. up to 10 breakpoint addresses may be specified.
615
616GO:
617 CALL SETADD
618 XOR BX,BX
619 MOV DI,OFFSET DG:BPTAB
620GO1:
621 CALL SCANP
622 JZ DEXEC
623 MOV BP,[CSSAVE]
624 CALL ADDRESS
625 MOV [DI],DX ; Save offset
626 MOV [DI+2],AX ; Save segment
627 ADD DI,5 ; Leave a little room
628 INC BX
629 CMP BX,1+BPMAX
630 JNZ GO1
631 MOV AX,5000H+"B" ; BP ERROR
632 JMP ERR
633DEXEC:
634 MOV [BRKCNT],BX
635 MOV CX,BX
636 JCXZ NOBP
637 MOV DI,OFFSET DG:BPTAB
638 PUSH DS
639SETBP:
640 LDS SI,ES:DWORD PTR [DI]
641 ADD DI,4
642 MOVSB
643 MOV BYTE PTR [SI-1],0CCH
644 LOOP SETBP
645 POP DS
646NOBP:
647 MOV [TCOUNT],1
648 JMP DEXIT
649
650SKIP_FILE:
651 MOV AH,CHAR_OPER
652 INT 21H
653 MOV [SWITCHAR],DL ; GET THE CURRENT SWITCH CHARACTER
654FIND_DELIM:
655 LODSB
656 CALL DELIM1
657 JZ GOTDELIM
658 CALL DELIM2
659 JNZ FIND_DELIM
660GOTDELIM:
661 DEC SI
662 RET
663
664PREPNAME:
665 MOV ES,DSSAVE
666 PUSH SI
667 MOV DI,81H
668COMTAIL:
669 LODSB
670 STOSB
671 CMP AL,13
672 JNZ COMTAIL
673 SUB DI,82H
674 XCHG AX,DI
675 MOV ES:(BYTE PTR [80H]),AL
676 POP SI
677 MOV DI,FCB
678 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
679 INT 21H
680 MOV BYTE PTR [AXSAVE],AL ; Indicate analysis of first parm
681 CALL SKIP_FILE
682 MOV DI,6CH
683 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
684 INT 21H
685 MOV BYTE PTR [AXSAVE+1],AL ; Indicate analysis of second parm
686RET23: RET
687
688
689; OPENS A XENIX PATHNAME SPECIFIED IN THE UNFORMATTED PARAMETERS
690; VARIABLE [XNXCMD] SPECIFIES WHICH COMMAND TO OPEN IT WITH
691;
692; VARIABLE [HANDLE] CONTAINS THE HANDLE
693; VARIABLE [EXTPTR] POINTS TO THE FILES EXTENSION
694
695DELETE_A_FILE:
696 MOV BYTE PTR [XNXCMD],UNLINK
697 JMP SHORT OC_FILE
698
699PARSE_A_FILE:
700 MOV BYTE PTR [XNXCMD],0
701 JMP SHORT OC_FILE
702
703EXEC_A_FILE:
704 MOV BYTE PTR [XNXCMD],EXEC
705 MOV BYTE PTR [XNXOPT],1
706 JMP SHORT OC_FILE
707
708OPEN_A_FILE:
709 MOV BYTE PTR [XNXCMD],OPEN
710 MOV BYTE PTR [XNXOPT],2 ; Try read write
711 CALL OC_FILE
712 JNC RET23
713 MOV BYTE PTR [XNXCMD],OPEN
714 MOV BYTE PTR [XNXOPT],0 ; Try read only
715 JMP SHORT OC_FILE
716
717CREATE_A_FILE:
718 MOV BYTE PTR [XNXCMD],CREAT
719
720OC_FILE:
721 PUSH DS
722 PUSH ES
723 PUSH AX
724 PUSH BX
725 PUSH CX
726 PUSH DX
727 PUSH SI
728 XOR AX,AX
729 MOV [EXTPTR],AX ; INITIALIZE POINTER TO EXTENSIONS
730 MOV AH,CHAR_OPER
731 INT 21H
732 MOV [SWITCHAR],DL ; GET THE CURRENT SWITCH CHARACTER
733
734 MOV SI,81H
735
736OPEN1: CALL GETCHRUP
737 CALL DELIM2 ; END OF LINE?
738 JZ OPEN4
739 CALL DELIM1 ; SKIP LEADING DELIMITERS
740 JZ OPEN1
741
742 MOV DX,SI ; SAVE POINTER TO BEGINNING
743 DEC DX
744OPEN2: CMP AL,"." ; LAST CHAR A "."?
745 JNZ OPEN3
746 MOV [EXTPTR],SI ; SAVE POINTER TO THE EXTENSION
747OPEN3: CALL GETCHRUP
748 CALL DELIM1 ; LOOK FOR END OF PATHNAME
749 JZ OPEN4
750 CALL DELIM2
751 JNZ OPEN2
752
753OPEN4: DEC SI ; POINT BACK TO LAST CHAR
754 PUSH [SI] ; SAVE TERMINATION CHAR
755 MOV BYTE PTR [SI],0 ; NULL TERMINATE THE STRING
756
757 MOV AL,[XNXOPT]
758 MOV AH,[XNXCMD] ; OPEN OR CREATE FILE
759 OR AH,AH
760 JZ OPNRET
761 MOV BX,OFFSET DG:EXEC_BLOCK
762 XOR CX,CX
763 INT 21H
764 MOV CS:[HANDLE],AX ; SAVE ERROR CODE OR HANDLE
765
766OPNRET: POP [SI]
767
768 POP SI
769 POP DX
770 POP CX
771 POP BX
772 POP AX
773 POP ES
774 POP DS
775 RET
776
777GETCHRUP:
778 LODSB
779 CMP AL,"a"
780 JB GCUR
781 CMP AL,"z"
782 JA GCUR
783 SUB AL,32
784 MOV [SI-1],AL
785GCUR: RET
786
787DELIM0: CMP AL,"["
788 JZ LIMRET
789DELIM1: CMP AL," " ; SKIP THESE GUYS
790 JZ LIMRET
791 CMP AL,";"
792 JZ LIMRET
793 CMP AL,"="
794 JZ LIMRET
795 CMP AL,9
796 JZ LIMRET
797 CMP AL,","
798 JMP SHORT LIMRET
799
800DELIM2: CMP AL,[SWITCHAR] ; STOP ON THESE GUYS
801 JZ LIMRET
802 CMP AL,13
803LIMRET: RET
804
805NAME:
806 CALL PREPNAME
807 MOV AL,BYTE PTR AXSAVE
808 MOV PARSERR,AL
809 PUSH ES
810 POP DS
811 PUSH CS
812 POP ES
813 MOV SI,FCB ; DS:SI points to user FCB
814 MOV DI,SI ; ES:DI points to DEBUG FCB
815 MOV CX,82
816 REP MOVSW
817RET6: RET
818
819BADNAM:
820 MOV DX,OFFSET DG:NAMBAD
821 JMP RESTART
822
823IFHEX:
824 CMP BYTE PTR [PARSERR],-1 ; Invalid drive specification?
825 JZ BADNAM
826 CALL PARSE_A_FILE
827 MOV BX,[EXTPTR]
828 CMP WORD PTR DS:[BX],"EH" ; "HE"
829 JNZ RET6
830 CMP BYTE PTR DS:[BX+2],"X"
831 RET
832
833IFEXE:
834 PUSH BX
835 MOV BX,[EXTPTR]
836 CMP WORD PTR DS:[BX],"XE" ; "EX"
837 JNZ RETIF
838 CMP BYTE PTR DS:[BX+2],"E"
839RETIF: POP BX
840 RET
841
842LOAD:
843 MOV BYTE PTR [RDFLG],READ
844 JMP SHORT DSKIO
845
846DWRITE:
847 MOV BYTE PTR [RDFLG],WRITE
848DSKIO:
849 MOV BP,[CSSAVE]
850 CALL SCANB
851 JNZ PRIMIO
852 JMP DEFIO
853PRIMIO: CALL ADDRESS
854 CALL SCANB
855 JNZ PRMIO
856 JMP FILEIO
857PRMIO: PUSH AX ; Save segment
858 MOV BX,DX ; Put displacement in proper register
859 MOV CX,1
860 CALL GETHEX ; Drive number must be 1 digit
861 PUSH DX
862 MOV CX,4
863 CALL GETHEX ; Logical record number
864 PUSH DX
865 MOV CX,3
866 CALL GETHEX ; Number of records
867 CALL GETEOL
868 MOV CX,DX
869 POP DX ; Logical record number
870 POP AX ; Drive number
871 CBW ; Turn off verify after write
872 MOV BYTE PTR DRVLET,AL ; Save drive in case of error
873 PUSH AX
874 PUSH BX
875 PUSH DX
876 MOV DL,AL
877 INC DL
878 MOV AH,GET_DPB
879 INT 21H
880 POP DX
881 POP BX
882 OR AL,AL
883 POP AX
884 POP DS ; Segment of transfer
885 JNZ DRVERRJ
886 CMP CS:BYTE PTR [RDFLG],WRITE
887 JZ ABSWRT
888 INT 25H ; Primitive disk read
889 JMP SHORT ENDABS
890
891ABSWRT:
892 INT 26H ; Primitive disk write
893ENDABS:
894 JNC RET0
895DRVERRJ: JMP DRVERR
896
897RET0:
898 POPF
899 RET
900
901DEFIO:
902 MOV AX,[CSSAVE] ; Default segment
903 MOV DX,100H ; Default file I/O offset
904 CALL IFHEX
905 JNZ EXECHK
906 XOR DX,DX ; If HEX file, default OFFSET is zero
907HEX2BINJ:JMP HEX2BIN
908
909FILEIO:
910; AX and DX have segment and offset of transfer, respectively
911 CALL IFHEX
912 JZ HEX2BINJ
913EXECHK:
914 CALL IFEXE
915 JNZ BINFIL
916 CMP BYTE PTR [RDFLG],READ
917 JZ EXELJ
918 MOV DX,OFFSET DG:EXEWRT
919 JMP RESTART ; Can't write .EXE files
920
921BINFIL:
922 CMP BYTE PTR [RDFLG],WRITE
923 JZ BINLOAD
924 CMP WORD PTR DS:[BX],4F00H + "C" ; "CO"
925 JNZ BINLOAD
926 CMP BYTE PTR DS:[BX+2],"M"
927 JNZ BINLOAD
928EXELJ:
929 DEC SI
930 CMP DX,100H
931 JNZ PRER
932 CMP AX,[CSSAVE]
933 JZ OAF
934PRER: JMP PERROR
935OAF: CALL OPEN_A_FILE
936 JNC GDOPEN
937 MOV AX,exec_file_not_found
938 JMP EXECERR
939
940GDOPEN: XOR DX,DX
941 XOR CX,CX
942 MOV BX,[HANDLE]
943 MOV AL,2
944 MOV AH,LSEEK
945 INT 21H
946 CALL IFEXE ; SUBTRACT 512 BYTES FOR EXE
947 JNZ BIN2 ; FILE LENGTH BECAUSE OF
948 SUB AX,512 ; THE HEADER
949BIN2: MOV [BXSAVE],DX ; SET UP FILE SIZE IN DX:AX
950 MOV [CXSAVE],AX
951 MOV AH,CLOSE
952 INT 21H
953 JMP EXELOAD
954
955NO_MEM_ERR:
956 MOV DX,OFFSET DG:TOOBIG
957 MOV AH,STD_CON_STRING_OUTPUT
958 INT 21H
959 JMP COMMAND
960
961WRTFILEJ: JMP WRTFILE
962NOFILEJ: JMP NOFILE
963
964BINLOAD:
965 PUSH AX
966 PUSH DX
967 CMP BYTE PTR [RDFLG],WRITE
968 JZ WRTFILEJ
969 CALL OPEN_A_FILE
970 JC NOFILEJ
971 MOV BX,[HANDLE]
972 MOV AX,(LSEEK SHL 8) OR 2
973 XOR DX,DX
974 MOV CX,DX
975 INT 21H ; GET SIZE OF FILE
976 MOV SI,DX
977 MOV DI,AX ; SIZE TO SI:DI
978 MOV AX,(LSEEK SHL 8) OR 0
979 XOR DX,DX
980 MOV CX,DX
981 INT 21H ; RESET POINTER BACK TO BEGINNING
982 POP AX
983 POP BX
984 PUSH BX
985 PUSH AX ; TRANS ADDR TO BX:AX
986 ADD AX,15
987 MOV CL,4
988 SHR AX,CL
989 ADD BX,AX ; Start of transfer rounded up to seg
990 MOV DX,SI
991 MOV AX,DI ; DX:AX is size
992 MOV CX,16
993 DIV CX
994 OR DX,DX
995 JZ NOREM
996 INC AX
997NOREM: ; AX is number of paras in transfer
998 ADD AX,BX ; AX is first seg that need not exist
999 CMP AX,CS:[PDB_block_len]
1000 JA NO_MEM_ERR
1001 MOV CXSAVE,DI
1002 MOV BXSAVE,SI
1003 POP DX
1004 POP AX
1005
1006RDWR:
1007; AX:DX is disk transfer address (segment:offset)
1008; SI:DI is length (32-bit number)
1009
1010RDWRLOOP:
1011 MOV BX,DX ; Make a copy of the offset
1012 AND DX,000FH ; Establish the offset in 0H-FH range
1013 MOV CL,4
1014 SHR BX,CL ; Shift offset and
1015 ADD AX,BX ; Add to segment register to get new Seg:offset
1016 PUSH AX
1017 PUSH DX ; Save AX,DX register pair
1018 MOV WORD PTR [TRANSADD],DX
1019 MOV WORD PTR [TRANSADD+2],AX
1020 MOV CX,0FFF0H ; Keep request in segment
1021 OR SI,SI ; Need > 64K?
1022 JNZ BIGRDWR
1023 MOV CX,DI ; Limit to amount requested
1024BIGRDWR:
1025 PUSH DS
1026 PUSH BX
1027 MOV BX,[HANDLE]
1028 MOV AH,[RDFLG]
1029 LDS DX,[TRANSADD]
1030 INT 21H ; Perform read or write
1031 POP BX
1032 POP DS
1033 JC BADWR
1034 CMP BYTE PTR [RDFLG],WRITE
1035 JNZ GOODR
1036 CMP CX,AX
1037 JZ GOODR
1038BADWR: MOV CX,AX
1039 STC
1040 POP DX ; READ OR WRITE BOMBED OUT
1041 POP AX
1042 RET
1043
1044GOODR:
1045 MOV CX,AX
1046 SUB DI,CX ; Request minus amount transferred
1047 SBB SI,0 ; Ripple carry
1048 OR CX,CX ; End-of-file?
1049 POP DX ; Restore DMA address
1050 POP AX
1051 JZ RET8
1052 ADD DX,CX ; Bump DMA address by transfer length
1053 MOV BX,SI
1054 OR BX,DI ; Finished with request
1055 JNZ RDWRLOOP
1056RET8: CLC ; End-of-file not reached
1057 RET
1058
1059NOFILE:
1060 MOV DX,OFFSET DG:NOTFND
1061RESTARTJMP:
1062 JMP RESTART
1063
1064WRTFILE:
1065 CALL CREATE_A_FILE ; Create file we want to write to
1066 MOV DX,OFFSET DG:NOROOM ; Creation error - report error
1067 JC RESTARTJMP
1068 MOV SI,BXSAVE ; Get high order number of bytes to transfer
1069 CMP SI,000FH
1070 JLE WRTSIZE ; Is bx less than or equal to FH
1071 XOR SI,SI ; Ignore BX if greater than FH - set to zero
1072WRTSIZE:
1073 MOV DX,OFFSET DG:WRTMES1 ; Print number bytes we are writing
1074 CALL RPRBUF
1075 OR SI,SI
1076 JZ NXTBYT
1077 MOV AX,SI
1078 CALL DIGIT
1079NXTBYT:
1080 MOV DX,CXSAVE
1081 MOV DI,DX
1082 CALL OUT16 ; Amount to write is SI:DI
1083 MOV DX,OFFSET DG:WRTMES2
1084 CALL RPRBUF
1085 POP DX
1086 POP AX
1087 CALL RDWR
1088 JNC CLSFLE
1089 CALL CLSFLE
1090 CALL DELETE_A_FILE
1091 MOV DX,OFFSET DG:NOSPACE
1092 JMP RESTARTJMP
1093 CALL CLSFLE
1094 JMP COMMAND
1095
1096CLSFLE:
1097 MOV AH,CLOSE
1098 MOV BX,[HANDLE]
1099 INT 21H
1100 RET
1101
1102EXELOAD:
1103 POP [RETSAVE] ; Suck up return addr
1104 INC BYTE PTR [NEWEXEC]
1105 MOV BX,[USER_PROC_PDB]
1106 MOV AX,DS
1107 CMP AX,BX
1108 JZ DEBUG_CURRENT
1109 JMP FIND_DEBUG
1110
1111DEBUG_CURRENT:
1112 MOV AX,[DSSAVE]
1113DEBUG_FOUND:
1114 MOV BYTE PTR [NEWEXEC],0
1115 MOV [HEADSAVE],AX
1116 PUSH [RETSAVE] ; Get the return address back
1117 PUSH AX
1118 MOV BX,CS
1119 SUB AX,BX
1120 PUSH CS
1121 POP ES
1122 MOV BX,AX
1123 ADD BX,10H ; RESERVE HEADER
1124 MOV AH,SETBLOCK
1125 INT 21H
1126 POP AX
1127 MOV WORD PTR [COM_LINE+2],AX
1128 MOV WORD PTR [COM_FCB1+2],AX
1129 MOV WORD PTR [COM_FCB2+2],AX
1130
1131 CALL EXEC_A_FILE
1132 JC EXECERR
1133 CALL SET_TERMINATE_VECTOR ; Reset int 22
1134 MOV AH,GET_CURRENT_PDB
1135 INT 21H
1136 MOV [USER_PROC_PDB],BX
1137 MOV [DSSAVE],BX
1138 MOV [ESSAVE],BX
1139 MOV ES,BX
1140 MOV WORD PTR ES:[PDB_exit],OFFSET DG:TERMINATE
1141 MOV WORD PTR ES:[PDB_exit+2],DS
1142 LES DI,[COM_CSIP]
1143 MOV [CSSAVE],ES
1144 MOV [IPSAVE],DI
1145 MOV WORD PTR [DISADD+2],ES
1146 MOV WORD PTR [DISADD],DI
1147 MOV WORD PTR [ASMADD+2],ES
1148 MOV WORD PTR [ASMADD],DI
1149 MOV WORD PTR [DEFDUMP+2],ES
1150 MOV WORD PTR [DEFDUMP],DI
1151 MOV BX,DS
1152 MOV AH,SET_CURRENT_PDB
1153 INT 21H
1154 LES DI,[COM_SSSP]
1155 MOV AX,ES:[DI]
1156 INC DI
1157 INC DI
1158 MOV [AXSAVE],AX
1159 MOV [SSSAVE],ES
1160 MOV [SPSAVE],DI
1161 RET
1162
1163EXECERR:
1164 MOV DX,OFFSET DG:NOTFND
1165 CMP AX,exec_file_not_found
1166 JZ GOTEXECEMES
1167 MOV DX,OFFSET DG:ACCMES
1168 CMP AX,error_access_denied
1169 JZ GOTEXECEMES
1170 MOV DX,OFFSET DG:TOOBIG
1171 CMP AX,exec_not_enough_memory
1172 JZ GOTEXECEMES
1173 MOV DX,OFFSET DG:EXEBAD
1174 CMP AX,exec_bad_format
1175 JZ GOTEXECEMES
1176 MOV DX,OFFSET DG:EXECEMES
1177GOTEXECEMES:
1178 MOV AH,STD_CON_STRING_OUTPUT
1179 INT 21H
1180 JMP COMMAND
1181
1182HEX2BIN:
1183 MOV [INDEX],DX
1184 MOV DX,OFFSET DG:HEXWRT
1185 CMP BYTE PTR [RDFLG],WRITE
1186 JNZ RDHEX
1187 JMP RESTARTJ2
1188RDHEX:
1189 MOV ES,AX
1190 CALL OPEN_A_FILE
1191 MOV DX,OFFSET DG:NOTFND
1192 JNC HEXFND
1193 JMP RESTART
1194HEXFND:
1195 XOR BP,BP
1196 MOV SI,OFFSET DG:(BUFFER+BUFSIZ) ; Flag input buffer as empty
1197READHEX:
1198 CALL GETCH
1199 CMP AL,":" ; Search for : to start line
1200 JNZ READHEX
1201 CALL GETBYT ; Get byte count
1202 MOV CL,AL
1203 MOV CH,0
1204 JCXZ HEXDONE
1205 CALL GETBYT ; Get high byte of load address
1206 MOV BH,AL
1207 CALL GETBYT ; Get low byte of load address
1208 MOV BL,AL
1209 ADD BX,[INDEX] ; Add in offset
1210 MOV DI,BX
1211 CALL GETBYT ; Throw away type byte
1212READLN:
1213 CALL GETBYT ; Get data byte
1214 STOSB
1215 CMP DI,BP ; Check if this is the largest address so far
1216 JBE HAVBIG
1217 MOV BP,DI ; Save new largest
1218HAVBIG:
1219 LOOP READLN
1220 JMP SHORT READHEX
1221
1222GETCH:
1223 CMP SI,OFFSET DG:(BUFFER+BUFSIZ)
1224 JNZ NOREAD
1225 MOV DX,OFFSET DG:BUFFER
1226 MOV SI,DX
1227 MOV AH,READ
1228 PUSH BX
1229 PUSH CX
1230 MOV CX,BUFSIZ
1231 MOV BX,[HANDLE]
1232 INT 21H
1233 POP CX
1234 POP BX
1235 OR AX,AX
1236 JZ HEXDONE
1237NOREAD:
1238 LODSB
1239 CMP AL,1AH
1240 JZ HEXDONE
1241 OR AL,AL
1242 JNZ RET7
1243HEXDONE:
1244 MOV [CXSAVE],BP
1245 MOV BXSAVE,0
1246 RET
1247
1248HEXDIG:
1249 CALL GETCH
1250 CALL HEXCHK
1251 JNC RET7
1252 MOV DX,OFFSET DG:HEXERR
1253RESTARTJ2:
1254 JMP RESTART
1255
1256GETBYT:
1257 CALL HEXDIG
1258 MOV BL,AL
1259 CALL HEXDIG
1260 SHL BL,1
1261 SHL BL,1
1262 SHL BL,1
1263 SHL BL,1
1264 OR AL,BL
1265RET7: RET
1266
1267
1268CODE ENDS
1269 END DEBCOM2