summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/EDLIN/EDLCMD1.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/EDLIN/EDLCMD1.ASM')
-rw-r--r--v4.0/src/CMD/EDLIN/EDLCMD1.ASM664
1 files changed, 664 insertions, 0 deletions
diff --git a/v4.0/src/CMD/EDLIN/EDLCMD1.ASM b/v4.0/src/CMD/EDLIN/EDLCMD1.ASM
new file mode 100644
index 0000000..ea304f4
--- /dev/null
+++ b/v4.0/src/CMD/EDLIN/EDLCMD1.ASM
@@ -0,0 +1,664 @@
1 PAGE 60,132;
2 TITLE EDLCMD1.ASM
3
4;======================= START OF SPECIFICATIONS =========================
5;
6; MODULE NAME: EDLCMD1.SAL
7;
8; DESCRIPTIVE NAME: EDLIN ROUTINES
9;
10; FUNCTION: THIS MODULE PROVIDES ROUTINES NEEDED FOR EDLIN'S EXECUTION.
11;
12; ENTRY POINT: ANY CALLED ROUTINE
13;
14; EXIT NORMAL: NA
15;
16; EXIT ERROR : NA
17;
18; INTERNAL REFERENCES:
19;
20; EXTERNAL REFERENCES:
21;
22; ROUTINE: EDLCMD2 - ROUTINES MAY BE CALLED FROM EDLCMD2
23; EDLMES - ROUTINES MAY BE CALLED FROM EDLMES
24;
25; NOTES: THIS MODULE IS TO BE PREPPED BY SALUT WITH THE "PR" OPTIONS.
26; LINK EDLIN+EDLCMD1+EDLCMD2+EDLMES+EDLPARSE
27;
28; REVISION HISTORY:
29;
30; AN000 VERSION DOS 4.00 - REVISIONS MADE RELATE TO THE FOLLOWING:
31;
32; - IMPLEMENT SYSPARSE
33; - IMPLEMENT MESSAGE RETRIEVER
34; - IMPLEMENT DBCS ENABLING
35; - ENHANCED VIDEO SUPPORT
36; - EXTENDED OPENS
37; - SCROLLING ERROR
38;
39; COPYRIGHT: "MS DOS EDLIN UTILITY"
40; "VERSION 4.00 (C) COPYRIGHT 1988 Microsoft"
41;
42;======================= END OF SPECIFICATIONS ===========================
43
44include edlequ.asm
45
46SUBTTL Contants and Data areas
47PAGE
48
49
50CODE SEGMENT PUBLIC
51CODE ENDS
52
53CONST SEGMENT PUBLIC WORD
54CONST ENDS
55
56cstack segment stack
57cstack ends
58
59DATA SEGMENT PUBLIC WORD
60DATA ENDS
61
62DG GROUP CODE,CONST,cstack,DATA
63
64CONST SEGMENT PUBLIC WORD
65 EXTRN DSKFUL_ptr:word,READ_ERR_PTR:word
66 EXTRN NOSUCH_ptr:word,TOOLNG_ptr:word,EOF_ptr:word
67 extrn txt1:byte,txt2:byte
68CONST ENDS
69
70cstack segment stack
71cstack ends
72
73DATA SEGMENT PUBLIC WORD
74 extrn ParamCt:WORD
75 extrn current:word,pointer:word,start:word,endtxt:word
76 extrn wrt_handle:word,editbuf:byte,path_name:byte,fname_len:word
77 extrn arg_buf:byte,arg_buf_ptr:word
78 extrn olddat:byte,oldlen:word,newlen:word,param1:word,param2:word
79 extrn srchflg:byte,srchmod:byte,comline:word,lstfnd:word,numpos:word
80 extrn lstnum:word,srchcnt:word,amnt_req:word,delflg:byte,lastlin:word
81 extrn three4th:word,one4th:word,last:word,rd_handle:word,ending:byte
82 extrn haveof:byte
83 extrn Disp_Len:Byte
84
85DATA ENDS
86
87CODE SEGMENT PUBLIC
88ASSUME CS:DG,DS:DG,SS:CStack,ES:DG
89
90 extrn findlin:near,shownum:near,loadbuf:near
91 extrn delbak:near,unquote:near,lf:near
92 extrn dispone:near,display:near,query:near
93 extrn quit:near,scanln:near,scaneof:near
94 extrn fndfirst:near,fndnext:near,replace:near,memerr:near
95 extrn std_printf:near,chkrange:near,comerr:near
96
97 public xerror,bad_read,append,nocom,pager,list
98 public delete,replac_from_curr,search_from_curr,ewrite,wrt
99
100NOMOREJ:JMP NOMORE
101
102APPEND:
103 CMP ParamCt,1
104 JZ AppendOK
105 JMP ComErr
106AppendOK:
107 TEST BYTE PTR [HAVEOF],-1
108 JNZ NOMOREJ
109 MOV DX,[ENDTXT]
110 CMP [PARAM1],0 ;See if parameter is missing
111 JNZ PARMAPP
112 CMP DX,[THREE4TH] ;See if already 3/4ths full
113 jb parmapp
114 return ;If so, then done already
115PARMAPP:
116 MOV DI,DX
117 MOV CX,[LAST]
118 SUB CX,DX ;Amount of memory available
119 jnz sj53
120 jmp memerr
121sj53:
122 MOV DX,[ENDTXT]
123 MOV BX,[RD_HANDLE]
124 mov [amnt_req],cx ;Save number of chars requested
125 MOV AH,READ
126 INT 21H ;Fill memory with file data
127 CMP CX,AX ;Did we read less than we asked for?
128 JZ SJ55
129; Make sure this is an end-of-file by trying to read more
130 PUSH AX ;Save old byte count
131 ADD DX,AX ;Point to next open space in buffer
132 MOV CX,1 ;Just one character past EOF
133 MOV AH,READ
134 INT 21H
135 CMP AX,0 ;Is it EOF?
136 POP AX
137 JNZ SJ54 ;No -- we have one more character
138 MOV BYTE PTR [HAVEOF],1 ;Yes - set old style system call flag
139 JMP SHORT SJ55
140SJ54:
141 INC AX ;Include one more char in byte count
142sj55:
143 MOV CX,AX ;Want byte count in CX
144 PUSH CX ;Save actual byte count
145 CALL SCANEOF
146 JNZ NOTEND
147 MOV BYTE PTR [HAVEOF],1 ;Set flag if 1AH found in file
148NOTEND:
149 XOR DX,DX
150 MOV BX,[PARAM1]
151 OR BX,BX
152 JNZ COUNTLN
153 MOV AX,DI
154 ADD AX,CX ;First byte after loaded text
155 CMP AX,[THREE4TH] ;See if we made 3/4 full
156 JBE COUNTLN
157 MOV DI,[THREE4TH]
158 MOV CX,AX
159 SUB CX,DI ;Length remaining over 3/4
160 MOV BX,1 ;Look for one more line
161COUNTLN:
162 CALL SCANLN ;Look for BX lines
163 CMP [DI-1],AL ;Check for full line
164 JZ FULLN
165 CMP HavEof,1
166 JNZ DoBackScan
167;
168; We have an incomplete line in the buffer at end of file. Fix it up to be
169; pretty.
170;
171 MOV BYTE PTR [DI],13 ; CR
172 MOV BYTE PTR [DI+1],10 ; LF
173 ADD DI,2 ; length is 2 greater
174 POP CX
175 ADD CX,2
176 PUSH CX
177 JMP SHORT FULLN
178
179DoBackScan:
180 DEC DI
181 MOV CX,[LAST]
182 STD
183 REPNE SCASB ;Scan backwards for last line
184 CLD
185 INC DI
186 INC DI
187 DEC DX
188FULLN:
189 POP CX ;Actual amount read
190 MOV WORD PTR [DI],1AH ;Place EOF after last line
191 SUB CX,DI
192 XCHG DI,[ENDTXT]
193 ADD DI,CX ;Amount of file read but not used
194; Must seek for old partial line
195 OR DI,DI
196 JZ FULLN1
197 PUSH DX
198 PUSH BX
199 MOV BX,[RD_HANDLE]
200 MOV DX,DI
201 NEG DX
202 MOV CX,-1
203 MOV AL,1
204 MOV AH,LSEEK
205 INT 21H
206 POP BX
207 POP DX
208 JC BAD_READ
209FULLN1:
210 CMP BX,DX
211 JNZ EOFCHK
212 MOV BYTE PTR [HAVEOF],0
213 return
214NOMORE:
215 MOV DX,OFFSET DG:EOF_ptr
216 call std_printf
217ret3: return
218
219BAD_READ:
220 MOV DX,OFFSET DG:READ_ERR_ptr
221 MOV DI,offset dg:path_name
222 ADD DI,[FNAME_LEN]
223 MOV AL,0
224 STOSB
225 JMP XERROR
226
227EOFCHK:
228 TEST BYTE PTR [HAVEOF],-1
229 JNZ NOMORE
230 TEST BYTE PTR [ENDING],-1
231 retnz ;Suppress memory error during End
232 JMP MEMERR
233
234EWRITE:
235 CMP ParamCt,1
236 JBE EWriteOK
237 JMP ComErr
238EWriteOK:
239 MOV BX,[PARAM1]
240 OR BX,BX
241 JNZ WRT
242 MOV CX,[ONE4TH]
243 MOV DI,[ENDTXT]
244 SUB DI,CX ;Write everything in front of here
245 JBE RET3
246 CMP DI,OFFSET DG:START ;See if there's anything to write
247 JBE RET3
248 XOR DX,DX
249 MOV BX,1 ;Look for one more line
250 CALL SCANLN
251 JMP SHORT WRTADD
252WRT:
253 INC BX
254 CALL FINDLIN
255WRTADD:
256 CMP BYTE PTR [DELFLG],0
257 JNZ WRTADD1
258 PUSH DI
259 CALL DELBAK ;Want to delete the .BAK file
260 ;as soon as the first write occurs
261 POP DI
262WRTADD1:
263 MOV CX,DI
264 MOV DX,OFFSET DG:START
265 SUB CX,DX ;Amount to write
266 retz
267 MOV BX,[WRT_HANDLE]
268 MOV AH,WRITE
269 INT 21H
270 JC WRTERR
271 CMP AX,CX ; MZ correct full disk detection
272 JNZ WRTERR ; MZ correct full disk detection
273 MOV SI,DI
274 MOV DI,OFFSET DG:START
275 MOV [POINTER],DI
276 MOV CX,[ENDTXT]
277 SUB CX,SI
278 INC CX ;Amount of text remaining
279 CLD
280 REP MOVSB
281 DEC DI ;Point to EOF
282 MOV [ENDTXT],DI
283 MOV [CURRENT],1
284 return
285
286WRTERR:
287 MOV BX,[WRT_HANDLE]
288 MOV AH,CLOSE
289 INT 21H
290 MOV DX,OFFSET DG:DSKFUL_ptr
291xERROR:
292 push cs
293 pop ds
294 call std_printf
295 mov al,0ffh
296 mov ah,exit
297 int 21h
298
299NOTFNDJ:JMP NOTFND
300
301replac_from_curr:
302 CMP ParamCt,2
303 JBE Replace1
304 JMP ComErr
305Replace1:
306 mov byte ptr [srchmod],1 ;search from curr+1 line
307 jmp short sj6
308
309REPLAC:
310 mov byte ptr [srchmod],0 ;search from beg of buffer
311sj6:
312 MOV BYTE PTR [SRCHFLG],0
313 CALL FNDFIRST
314 JNZ NOTFNDJ
315REPLP:
316 MOV SI,[NUMPOS]
317 CALL LOADBUF ;Count length of line
318 SUB DX,[OLDLEN]
319 MOV CX,[NEWLEN]
320 ADD DX,CX ;Length of new line
321 CMP DX,254
322 jbe len_ok
323 Jmp TOOLONG
324len_ok:
325 MOV BX,[LSTNUM]
326 PUSH DX
327 CALL SHOWNUM
328 POP DX
329 MOV CX,[LSTFND]
330 MOV SI,[NUMPOS]
331 SUB CX,SI ;Get no. of char on line before change
332 DEC CX
333 mov di,offset dg:arg_buf ;Initialize the output string buffer
334 CALL OUTCNT ;Output first part of line
335 PUSH SI
336 MOV SI,1+ OFFSET DG:TXT2
337 MOV CX,[NEWLEN]
338 CALL OUTCNT ;Output change
339 POP SI
340 ADD SI,[OLDLEN] ;Skip over old stuff in line
341 MOV CX,DX ;DX=no. of char left in line
342 ADD CX,2 ;Include CR/LF
343 CALL OUTCNT ;Output last part of line
344 xor al,al
345 stosb
346 mov dx,offset dg:arg_buf_ptr
347 call std_printf
348 CALL QUERY ;Check if change OK
349 JNZ REPNXT
350 CALL PUTCURS
351 MOV DI,[LSTFND]
352 DEC DI
353 MOV SI,1+ OFFSET DG:TXT2
354 MOV DX,[OLDLEN]
355 MOV CX,[NEWLEN]
356 DEC CX
357 ADD [LSTFND],CX ;Bump pointer beyond new text
358 INC CX
359 DEC DX
360 SUB [SRCHCNT],DX ;Old text will not be searched
361 JAE SOMELEFT
362 MOV [SRCHCNT],0
363SOMELEFT:
364 INC DX
365 CALL REPLACE
366REPNXT:
367 CALL FNDNEXT
368 retnz
369 JMP REPLP
370
371OUTCNT:
372 JCXZ RET8
373OUTLP:
374 LODSB
375 stosb
376 DEC DX
377 LOOP OUTLP
378RET8: return
379
380TOOLONG:
381 MOV DX,OFFSET DG:TOOLNG_ptr
382 JMP SHORT PERR
383
384search_from_curr:
385 CMP ParamCt,2
386 JBE Search1
387 JMP ComErr
388Search1:
389 mov byte ptr [srchmod],1 ;search from curr+1 line
390 jmp short sj7
391
392SEARCH:
393 mov byte ptr [srchmod],0 ;search from beg of buffer
394sj7:
395 MOV BYTE PTR [SRCHFLG],1
396 CALL FNDFIRST
397 JNZ NOTFND
398SRCH:
399 MOV BX,[LSTNUM]
400 MOV SI,[NUMPOS]
401 CALL DISPONE
402 MOV DI,[LSTFND]
403 MOV CX,[SRCHCNT]
404 MOV AL,10
405 CLD
406 REPNE SCASB
407 JNZ NOTFND
408 MOV [LSTFND],DI
409 MOV [NUMPOS],DI
410 MOV [SRCHCNT],CX
411 INC [LSTNUM]
412 CALL QUERY
413 JZ PUTCURS1
414 CALL FNDNEXT
415 JZ SRCH
416NOTFND:
417 MOV DX,OFFSET DG:NOSUCH_ptr
418PERR:
419 call std_printf
420 return
421
422;
423; Replace enters here with LSTNUM pointing to the correct line.
424;
425PUTCURS:
426 MOV BX,[LSTNUM]
427 jmp short putcursor
428;
429; Search enters here with LSTNUM pointing AFTER the correct line
430;
431putcurs1:
432 MOV BX,[LSTNUM]
433 DEC BX ;Current <= Last matched line
434
435putcursor:
436 CALL FINDLIN
437 MOV [CURRENT],DX
438 MOV [POINTER],DI
439 return
440
441;
442; n,mD deletes a range of lines. Allowable values for n are:
443; 1 ... LAST. Allowable values for m are:
444; 1 ... LAST.
445; nD deletes a single line
446; D deletes the current line
447;
448DELETE:
449 CMP ParamCt,2 ; at most two parameters specified.
450 JA ComErrJ
451 MOV BX,Param1
452 OR BX,BX ; default first arg?
453 JNZ DelParm2
454 MOV BX,Current ; use current as default
455 MOV Param1,BX
456DelParm2:
457 MOV BX,Param2 ; did we default second arg?
458 OR BX,BX
459 JNZ DelCheck ; no, use it.
460 MOV BX,Param1 ; use param1 as default
461 MOV Param2,BX
462DelCheck:
463 MOV BX,Param1
464 CALL ChkRange ; returns by itself if bad range
465;
466; BX is first line of range to be deleted. Param2 is last line in range to
467; be deleted. Get pointer to beginning of block. Save location
468;
469 CALL FINDLIN ; Grab line
470 retnz ; If not found => return
471 PUSH BX
472 PUSH DI
473;
474; Get pointer past end of block (Param2+1).
475;
476 MOV BX,Param2
477 INC BX
478 CALL FINDLIN
479;
480; Set up pointers. Compute number of chars to move.
481;
482 MOV SI,DI ; move from second line+1
483 POP DI ; restore destination (first line)
484 POP Current ; Current line is first param
485 MOV Pointer,DI ; internal current line
486 MOV CX,EndTxt ; compute count
487 SUB CX,SI
488 JB ComErrJ ; should never occur: ChkRange
489 INC CX ; remember ^Z at end
490 CLD
491 REP MOVSB ; move data
492 DEC DI
493 MOV EndTxt,DI ; reset end pointer
494 return
495
496COMERRJ:
497 JMP COMERR
498
499PAGER:
500 CMP ParamCt,2
501 JA ComErrJ
502 xor bx,bx ;get last line in the buffer
503 call findlin
504 mov [lastlin],dx
505
506 mov bx,[param1]
507 or bx,bx ;was it specified?
508 jnz frstok ;yes, use it
509 mov bx,[current]
510 cmp bx,1 ;if current line =1 start from there
511 je frstok
512 inc bx ;start from current+1 line
513frstok:
514 cmp bx,[lastlin] ;check that we are in the buffer
515 jbe frstok1
516 return ;if not just quit
517frstok1:
518 mov dx,[param2]
519 or dx,dx ;was param2 specified?
520 jnz scndok ;yes,....
521 mov dx,bx ;no, take the end line to be the
522 ; start line + length of active display
523
524;=========================================================================
525; This modification is to provide support for screens larger than
526; 24 lines.
527;
528; Date : 6/10/87
529;=========================================================================
530
531 push ax ;an000;save affected registers
532
533 mov ah,00h ;an000;zero out high byte
534 mov al,dg:disp_len ;an000;set ax to active display length
535 sub ax,2 ;an000;adjust for length of screen & current
536 ; line
537 add dx,ax ;an000;this gives us the last line to be
538 ; printed
539 pop ax ;an000;restore affected registers
540
541;=========================================================================
542
543scndok:
544 inc dx
545 cmp dx,[lastlin] ;check that we are in the buffer
546 jbe infile
547 mov dx,[lastlin] ;we are not, take the last line as end
548infile:
549 cmp dx,bx ;is param1 < param2 ?
550 retz
551 ja sj33
552 jmp comerr ;yes, no backwards listing, print error
553sj33:
554 push dx ;save the end line
555 push bx ;save start line
556 mov bx,dx ;set the current line
557 dec bx
558 call findlin
559 mov [pointer],di
560 mov [current],dx
561 pop bx ;restore start line
562 call findlin ;get pointer to start line
563 mov si,di ;save pointer
564 pop di ;get end line
565 sub di,bx ;number of lines
566 jmp short display_lines
567
568
569LIST:
570 CMP ParamCt,2
571 JBE ListOK
572 JMP ComERR
573ListOK:
574 MOV BX,[PARAM1]
575 OR BX,BX
576 JNZ CHKP2
577 MOV BX,[CURRENT]
578 SUB BX,11
579 JA CHKP2
580 MOV BX,1
581CHKP2:
582 CALL FINDLIN
583 retnz
584 MOV SI,DI
585 MOV DI,[PARAM2]
586 INC DI
587 SUB DI,BX
588 JA DISPLAY_lines
589
590;=========================================================================
591; This modification is to provide support for screens larger than
592; 24 lines.
593;
594; Date : 6/10/87
595;=========================================================================
596
597 push ax ;an000;save affected registers
598
599 mov ah,00h ;an000;zero out high byte
600 mov al,dg:disp_len ;an000;set ax to active display length dec ax ;an000;allow room at bottom for
601 ; messages
602 mov di,ax ;an000;number of lines to print an
603 ; entire screen less 1.
604 pop ax ;an000;restore affected registers
605
606;=========================================================================
607
608display_lines:
609 call DISPLAY
610 return
611
612Break <NOCOM - edit a single line>
613
614;
615; NOCOM is called when there is a single line being edited. This occurs when
616; the command letter is CR or is ;.
617;
618NOCOM:
619 CMP ParamCt,2
620 JB NoComOK
621 JMP ComErr
622NoComOK:
623 DEC [COMLINE]
624 MOV BX,[PARAM1]
625 OR BX,BX
626 JNZ HAVLIN
627 MOV BX,[CURRENT]
628 INC BX ;Default is current line plus one
629 CALL CHKRANGE
630HAVLIN:
631 CALL FINDLIN
632 MOV SI,DI
633 MOV [CURRENT],DX
634 MOV [POINTER],SI
635 jz sj12
636ret12: return
637sj12:
638 CMP SI,[ENDTXT]
639 retz
640 CALL LOADBUF
641 MOV [OLDLEN],DX
642 MOV SI,[POINTER]
643 CALL DISPONE
644 CALL SHOWNUM
645 MOV AH,STD_CON_STRING_INPUT ;Get input buffer
646 MOV DX,OFFSET DG:EDITBUF
647 INT 21H
648 CALL lf
649 MOV CL,[EDITBUF+1]
650 MOV CH,0
651 JCXZ RET12
652 MOV DX,[OLDLEN]
653 MOV SI,2 + OFFSET DG:EDITBUF
654;-----------------------------------------------------------------------
655 call unquote ;scan for quote chars if any
656;-----------------------------------------------------------------------
657 mov cl,[EditBuf+1] ;an000; dms;get new line length
658 mov ch,0 ;an000; dms;clear high byte
659 MOV DI,[POINTER]
660 JMP Replace ; MZ 11/30
661
662CODE ENDS
663 END
664 \ No newline at end of file