Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1884 lines
44 KiB

  1. PAGE 60,132;
  2. TITLE EDLIN
  3. ;/*
  4. ; * Microsoft Confidential
  5. ; * Copyright (C) Microsoft Corporation 1991
  6. ; * All Rights Reserved.
  7. ; */
  8. ;======================= START OF SPECIFICATIONS =========================
  9. ;
  10. ; MODULE NAME: EDLIN.SAL
  11. ;
  12. ; DESCRIPTIVE NAME: LINE TEXT EDITOR
  13. ;
  14. ; FUNCTION: EDLIN IS A SIMPLE, LINE ORIENTED TEXT EDITOR. IT PROVIDES
  15. ; USERS OF DOS THE ABILITY TO CREATE AND EDIT TEXT FILES.
  16. ;
  17. ; ENTRY POINT: EDLIN
  18. ;
  19. ; INPUT: DOS COMMAND LINE
  20. ; EDLIN COMMANDS
  21. ; TEXT
  22. ;
  23. ; EXIT NORMAL: NA
  24. ;
  25. ; EXIT ERROR: NA
  26. ;
  27. ; INTERNAL REFERENCES:
  28. ;
  29. ; EXTERNAL REFERENCES:
  30. ;
  31. ; ROUTINE: EDLCMD1 - CONTAINS ROUTINES CALLED BY EDLIN
  32. ; EDLCMD1 - CONTAINS ROUTINES CALLED BY EDLIN
  33. ; EDLMES - CONTAINS ROUTINES CALLED BY EDLIN
  34. ;
  35. ; LINK EDLIN+EDLCMD1+EDLCMD2+EDLMES+EDLPARSE
  36. ;
  37. ; REVISION HISTORY:
  38. ;
  39. ; AN000 VERSION 4.00 - REVISIONS MADE RELATE TO THE FOLLOWING:
  40. ;
  41. ; - IMPLEMENT SYSPARSE
  42. ; - IMPLEMENT MESSAGE RETRIEVER
  43. ; - IMPLEMENT DBCS ENABLING
  44. ; - ENHANCED VIDEO SUPPORT
  45. ; - EXTENDED OPENS
  46. ; - SCROLLING ERROR
  47. ;
  48. ; COPYRIGHT: "MS DOS EDLIN UTILITY"
  49. ; "VERSION 4.00 (C) COPYRIGHT 1988 Microsoft"
  50. ; "LICENSED MATERIAL - PROPERTY OF Microsoft"
  51. ;
  52. ;
  53. ; MICROSOFT REVISION HISTORY:
  54. ; ;
  55. ; V1.02 ;
  56. ; ;
  57. ; V2.00 9/13/82 M.A.U ;
  58. ; ;
  59. ; 2/23/82 Rev. 13 N. P ;
  60. ; Changed to 2.0 system calls. ;
  61. ; Added an error message for READ-ONLY files ;
  62. ; ;
  63. ; 11/7/83 Rev. 14 N. P ;
  64. ; Changed to .EXE format and added Printf ;
  65. ; ;
  66. ; V2.50 11/15/83 Rev. 1 M.A. U ;
  67. ; Official dos 2.50 version. Some random bug ;
  68. ; fixes and message changes. ;
  69. ; ;
  70. ; 11/30/83 Rev. 2 MZ ;
  71. ; Close input file before rename. ;
  72. ; Jmp to replace after line edit ;
  73. ; ;
  74. ; 02/01/84 Rev. 3 M.A. U ;
  75. ; Now it is called 3.00 dos. Repaired problem ;
  76. ; with using printf and having %'s as data. ;
  77. ; ;
  78. ; 02/15/84 MZ make out of space a fatal error with output;
  79. ; ;
  80. ; 03/28/84 MZ fixes bogus (totally) code in MOVE/COPY ;
  81. ; ;
  82. ; 04/02/84 MZ fixes DELETE and changes MOVE/COPY/EDIT ;
  83. ; ;
  84. ; V3.20 08/29/86 Rev. 1 S.M. G ;
  85. ; ;
  86. ; 08/29/86 M001 MSKK TAR 593, TAB MOVEMENT ;
  87. ; ;
  88. ; 08/29/86 M002 MSKK TAR 157, BLKMOVE 1,1,1m, 1,3,1m ;
  89. ; ;
  90. ; 08/29/86 M003 MSKK TAR 476, EDLCMD2,MAKECAPS,kana char ;
  91. ; ;
  92. ; 08/29/86 M004 MSKK TAR 191, Append load size ;
  93. ; ;
  94. ; 08/29/86 M005 IBMJ TAR Transfer Load command ;
  95. ; ;
  96. ; 04/17/90 c-PaulB ;
  97. ; Added /? switch to display options ;
  98. ; Files changed: edlin.asm, edlparse.asm, edlmes.asm, ;
  99. ; edlin.skl. ;
  100. ; ;
  101. ;======================= END OF SPECIFICATIONS =========================== ;
  102. include version.inc
  103. include intnat.inc
  104. include syscall.inc
  105. include edlequ.asm
  106. SUBTTL Contants and Data areas
  107. PAGE
  108. extrn parser_command:near ;an000;SYSPARSE
  109. CODE SEGMENT PUBLIC
  110. CODE ENDS
  111. CONST SEGMENT PUBLIC WORD
  112. CONST ENDS
  113. cstack segment stack
  114. cstack ends
  115. DATA SEGMENT PUBLIC WORD
  116. DATA ENDS
  117. DG GROUP CODE,CONST,cstack,DATA
  118. CONST SEGMENT PUBLIC WORD
  119. public bak,$$$file,delflg,loadmod,txt1,txt2
  120. EXTRN BADDRV:abs,NDNAME:abs
  121. EXTRN opt_err_ptr:word,NOBAK:abs,BADCOM:abs
  122. EXTRN NEWFIL:abs,DEST:abs,MRGERR:abs
  123. EXTRN NODIR:abs,FILENM_ptr:word,ro_err:abs
  124. EXTRN bcreat:abs,msg_too_many:abs,msg_lf:abs
  125. EXTRN prompt:abs,MemFul_Ptr:word,simple_msg:word
  126. extrn dsp_options:abs
  127. extrn dsp_help:abs,num_help_msgs:abs
  128. BAK DB ".BAK",0
  129. $$$FILE DB ".$$$",0
  130. fourth db 0 ;fourth parameter flag
  131. loadmod db 0 ;Load mode flag, 0 = ^Z marks the
  132. ; end of a file, 1 = viceversa.
  133. optchar db "-"
  134. TXT1 DB 0,80H DUP (?)
  135. TXT2 DB 0,80H DUP (?)
  136. DELFLG DB 0
  137. fNew DB 0 ; old file
  138. HAVEOF DB 0
  139. CONST ENDS
  140. cstack segment stack
  141. db stksiz dup (?)
  142. cstack ends
  143. DATA SEGMENT PUBLIC WORD
  144. extrn arg_buf_ptr:word ;an000;
  145. extrn line_num_buf_ptr:word ;an000;
  146. public path_name,ext_ptr,start,line_num,line_flag
  147. public arg_buf,wrt_handle,temp_path
  148. public current,pointer,qflg,editbuf,amnt_req,fname_len,delflg,lastlin
  149. public olddat,oldlen,newlen,srchflg,srchmod
  150. public comline,lstfnd,numpos,lstnum,last_mem,srchcnt
  151. public rd_handle,haveof,ending,three4th,one4th
  152. public lc_adj ;an000;page length adj. factor
  153. public lc_flag ;an000;display cont. flag
  154. public pg_count ;an000;lines left on screen
  155. public Disp_Len ;an000;display length
  156. public Disp_Width ;an000;display width
  157. public continue ;an000;boolean T/F
  158. public temp_path ;an000;pointer to filespec buf
  159. Video_Buffer label word ;an000;buffer for video attr
  160. db 0 ;an000;dms;
  161. db 0 ;an000;dms;
  162. dw 14 ;an000;dms;
  163. dw 0 ;an000;dms;
  164. db ? ;an000;dms;
  165. db 0 ;an000;dms;
  166. dw ? ;an000;dms;# of colors
  167. dw ? ;an000;dms;# of pixels in width
  168. dw ? ;an000;dms;# of pixels in len.
  169. dw ? ;an000;dms;# of chars in width
  170. dw ? ;an000;dms;# of chars in length
  171. video_org db ? ;an000;original video mode on
  172. ; entry to EDLIN.
  173. lc_adj db ? ;an000;page length adj. factor
  174. lc_flag db ? ;an000;display cont. flag
  175. pg_count db ? ;an000;lines left on screen
  176. Disp_Len db ? ;an000;display length
  177. Disp_Width db ? ;an000;display width
  178. continue db ? ;an000;boolean T/F
  179. ;-----------------------------------------------------------------------;
  180. ; This is a table that is sequentially filled via GetNum. Any additions to it
  181. ; must be placed in the correct position. Currently Param4 is known to be a
  182. ; count and thus is treated specially.
  183. public param1,param2,Param3,param4,ParamCt
  184. PARAM1 DW ?
  185. PARAM2 DW ?
  186. PARAM3 DW ?
  187. PARAM4 DW ?
  188. ParamCt DW ? ; count of passed parameters
  189. ifdef DBCS ; Used in TESTKANJ:
  190. LBTbl dd ? ; long pointer to lead byte table
  191. endif ; in the dos (from syscall 63H)
  192. ;-----------------------------------------------------------------------;
  193. PUBLIC PTR_1, PTR_2, PTR_3, OLDLEN, NEWLEN, LSTFND, LSTNUM, NUMPOS, SRCHCNT
  194. PUBLIC CURRENT, POINTER, ONE4TH, THREE4TH, LAST_MEM, ENDTXT, COPYSIZ
  195. PUBLIC COMLINE, LASTLIN, COMBUF, EDITBUF, EOL, QFLG, ENDING, SRCHFLG
  196. PUBLIC PATH_NAME, FNAME_LEN, RD_HANDLE, TEMP_PATH, WRT_HANDLE, EXT_PTR
  197. PUBLIC MRG_PATH_NAME, MRG_HANDLE, amnt_req, olddat, srchmod, MOVFLG, org_ds
  198. ifdef DBCS
  199. public lbtbl
  200. endif
  201. ;
  202. ; These comprise the known state of the internal buffer. All editing
  203. ; functions must preserve these values.
  204. ;
  205. CURRENT DW ? ; the 1-based index of the current line
  206. POINTER DW ? ; pointer to the current line
  207. ENDTXT DW ? ; pointer to end of buffer. (at ^Z)
  208. LAST_MEM DW ? ; offset of last byte of memory
  209. ;
  210. ; The label Start is the beginning of the in-core buffer.
  211. ;
  212. ;
  213. ; Internal temporary pointers
  214. ;
  215. PTR_1 DW ?
  216. PTR_2 DW ?
  217. PTR_3 DW ?
  218. QFLG DB ? ; TRUE => query for replacement
  219. OLDLEN DW ?
  220. NEWLEN DW ?
  221. LSTFND DW ?
  222. LSTNUM DW ?
  223. NUMPOS DW ?
  224. SRCHCNT DW ?
  225. ONE4TH DW ?
  226. THREE4TH DW ?
  227. COPYSIZ DW ? ; total length to copy
  228. COPYLEN DW ? ; single copy length
  229. COMLINE DW ?
  230. LASTLIN DW ?
  231. COMBUF DB 82H DUP (?)
  232. EDITBUF DB 258 DUP (?)
  233. EOL DB ?
  234. ENDING DB ?
  235. SRCHFLG DB ?
  236. PATH_NAME DB 128 DUP(0)
  237. FNAME_LEN DW ?
  238. RD_HANDLE DW ?
  239. TEMP_PATH DB 128 DUP(?)
  240. WRT_HANDLE DW ?
  241. EXT_PTR DW ?
  242. MRG_PATH_NAME DB 128 DUP(?)
  243. MRG_HANDLE DW ?
  244. amnt_req dw ? ; amount of bytes requested to read
  245. olddat db ? ; Used in replace and search, replace
  246. ; by old data flag (1=yes)
  247. srchmod db ? ; Search mode: 1=from current+1 to
  248. ; end of buffer, 0=from beg. of
  249. ; buffer to the end (old way).
  250. MOVFLG DB ?
  251. org_ds dw ? ;Orginal ds points to header block
  252. arg_buf db 258 dup (?)
  253. EA_Flag db False ;an000; dms;set to false
  254. EA_Buffer_Size dw ? ;an000; dms;EA buffer's size
  255. EA_Parm_List label word ;an000; dms;EA parms
  256. dd dg:Start ;an000; dms;ptr to EA's
  257. dw 0001h ;an000; dms;additional parms
  258. db 06h ;an000; dms;
  259. dw 0002h ;an000; dms;iomode
  260. line_num dw ?
  261. line_flag db ?,0
  262. EVEN ;align on word boundaries
  263. ;
  264. ; Byte before start of data buffer must be < 40H !!!!!!
  265. ;
  266. dw 0 ;we scan backwards looking for
  267. ;a character which can't be part
  268. ;of a two-byte seqence. This
  269. ;double byte sequence will cause the back
  270. ;scan to stop here.
  271. START LABEL WORD
  272. DATA ENDS
  273. CODE SEGMENT PUBLIC
  274. ASSUME CS:DG,DS:NOTHING,ES:NOTHING,SS:CStack
  275. extrn pre_load_message:near ;an000;message loader
  276. extrn disp_fatal:near ;an000;fatal message
  277. extrn printf:near ;an000;new PRINTF routine
  278. extrn findlin:near,shownum:near,loadbuf:near,crlf:near,lf:near
  279. extrn abortcom:near,delbak:near,unquote:near,kill_bl:near
  280. extrn make_caps:near,dispone:near,display:near,query:near
  281. extrn quit:near,make_cntrl:near,scanln:near,scaneof:near
  282. extrn fndfirst:near,fndnext:near,replace:near,memerr:near
  283. extrn xerror:near
  284. extrn zerror:near
  285. extrn bad_read:near,append:near
  286. extrn nocom:near,pager:near,list:near,search_from_curr:near
  287. extrn replac_from_curr:near,ewrite:near,wrt:near,delete:near
  288. extrn filespec:byte ;an000;parser's filespec
  289. extrn parse_switch_b:byte ;an000;result of switch scan
  290. extrn parse_switch_?:byte ; result of switch scan
  291. public std_printf,command,chkrange,comerr
  292. public display_message
  293. ; exit from EDLIN
  294. IFDEF DBCS
  295. extrn testkanj:near
  296. ENDIF
  297. EDLIN:
  298. JMP SHORT SIMPED
  299. std_printf proc near ;ac000;convert to proc
  300. push dx
  301. call printf
  302. pop dx ;an000;balance the push
  303. ret
  304. std_printf endp ;ac000;end proc
  305. Break <Dispatch Table>
  306. ;-----------------------------------------------------------------------;
  307. ; Careful changing the order of the next two tables. They are linked and
  308. ; changes should be be to both.
  309. COMTAB DB 13,";ACDEILMPQRSTW"
  310. NUMCOM EQU $-COMTAB
  311. TABLE DW BLANKLINE ; Blank line
  312. DW NOCOM ; ;
  313. DW APPEND ; A(ppend)
  314. DW COPY ; C(opy)
  315. DW DELETE ; D(elete)
  316. DW ENDED ; E(xit)
  317. DW INSERT ; I(nsert)
  318. DW LIST ; L(ist)
  319. DW MOVE ; M(ove)
  320. DW PAGER ; P(age)
  321. DW QUIT ; Q(uit)
  322. dw replac_from_curr ; R(eplace)
  323. dw search_from_curr ; S(earch)
  324. DW MERGE ; T(merge)
  325. DW EWRITE ; W(rite)
  326. Break <Initialization Code>
  327. NONAME:
  328. mov ax,NDNAME
  329. jmp zerror
  330. SIMPED:
  331. mov org_ds,DS
  332. push ax ;ac000;save for drive compare
  333. push cs ;an000;exchange cs/es
  334. pop es ;an000;
  335. push cs ;an000;exchange cs/ds
  336. pop ds ;an000;
  337. assume ds:dg,es:dg ;an000;establish addressibility
  338. MOV dg:ENDING,0
  339. mov sp,stack
  340. call EDLIN_DISP_GET ;an000;get current video
  341. ; mode & set it to
  342. ; text
  343. ;=========================================================================
  344. ; invoke PRE_LOAD_MESSAGE here. If the messages were not loaded we will
  345. ; exit with an appropriate error message.
  346. ;
  347. ; Date : 6/14/87
  348. ;=========================================================================
  349. call PRE_LOAD_MESSAGE ;an000;invoke SYSLOADMSG
  350. ; $if c ;an000;if the load was unsuccessful
  351. JNC $$IF1
  352. mov ah,exit ;an000;exit EDLIN. PRE_LOAD_MESSAGE
  353. ; has said why we are exiting
  354. mov al,00h ;an000
  355. int 21h ;an000;exit
  356. ; $endif ;an000;
  357. $$IF1:
  358. VERS_OK:
  359. ;----- Check for valid drive specifier --------------------------------;
  360. pop ax
  361. OR AL,AL
  362. JZ get_switch_char
  363. mov ax,BADDRV
  364. jmp zerror
  365. get_switch_char:
  366. MOV AX,(CHAR_OPER SHL 8) ;GET SWITCH CHARACTER
  367. INT 21H
  368. CMP DL,"/"
  369. JNZ CMD_LINE ;IF NOT / , THEN NOT PC
  370. MOV OPTCHAR,"/" ;IN PC, OPTION CHAR = /
  371. IFDEF DBCS
  372. push ds ; SAVE! all regs destroyed on this
  373. push es
  374. push si ; call !!
  375. mov ax,(ECS_call shl 8) or 00h ; get kanji lead tbl
  376. int 21h
  377. assume ds:nothing
  378. assume es:nothing
  379. mov word ptr [LBTbl],si
  380. mov word ptr [LBTbl+2],ds
  381. pop si
  382. pop es
  383. pop ds
  384. assume ds:dg
  385. assume es:dg
  386. ENDIF
  387. CMD_LINE:
  388. push cs
  389. pop es
  390. ASSUME ES:DG
  391. ;----- Process any options ------------------------------------------;
  392. ;=========================================================================
  393. ; The system parser, called through PARSER_COMMAND, parses external
  394. ; command lines. In the case of EDLIN we are looking for two parameters
  395. ; on the command line.
  396. ;
  397. ; Parameter 1 - Filespec (REQUIRED)
  398. ; Parameter 2 - \B switch (OPTIONAL)
  399. ;
  400. ; PARSER_COMMAND - exit_normal : ffffh
  401. ; exit_error : not = ffffh
  402. ;=========================================================================
  403. call PARSER_COMMAND ;an000;invoke sysparse
  404. ; DMS:6/11/87
  405. ; Check for /? switch.
  406. ; If so, display the options
  407. ; and exit.
  408. ;
  409. ; This is done first so that if the user typed
  410. ; /? along with unknown commands, they can get
  411. ; a coherent message without being over-errored.
  412. ;
  413. ; 4/17/90 c-PaulB
  414. cmp [parse_switch_?], true ; is the /? switch on?
  415. jne CheckOptionsDone ; skip the rest of this if not
  416. mov ax,dsp_options
  417. call display_message
  418. mov al, 0 ; get an okay exit code
  419. mov ah, exit ; and
  420. int 21h ; bail out.
  421. CheckOptionsDone:
  422. cmp ax,nrm_parse_exit ;an000;was it a good parse
  423. ; $if z ;an000;it was a good parse
  424. JNZ $$IF3
  425. call EDLIN_COMMAND ;an000;interface results
  426. ; into EDLIN
  427. ; $else ;an000;
  428. JMP SHORT $$EN3
  429. $$IF3:
  430. cmp ax,too_many ;an000;too many operands
  431. ; $if z ;an000;we have too many
  432. JNZ $$IF5
  433. jmp short badopt ;an000;say why and exit
  434. ; $endif
  435. $$IF5:
  436. cmp ax,op_missing ;an000;required parm missing
  437. ; $if z ;an000;missing parm
  438. JNZ $$IF7
  439. ifdef DBCS
  440. jmp noname ;an000;say why and exit
  441. else
  442. jmp short noname ;an000;say why and exit
  443. endif
  444. ; $endif ;an000;
  445. $$IF7:
  446. cmp ax,sw_missing ;an000;is it an invalid switch
  447. ; $if z ;an000;invalid switch
  448. JNZ $$IF9
  449. jmp short badopt ;an000;say why and exit
  450. ; $endif ;an000;
  451. $$IF9:
  452. ; $endif ;an000;
  453. $$EN3:
  454. ;=========================================================================
  455. ;======================= begin .BAK check ================================
  456. ; Check for .BAK extension on the filename
  457. push ds ;an000;save reg.
  458. push cs ;an000;set up addressibility
  459. pop ds ;an000;
  460. assume ds:dg ;an000;
  461. push ax ;an000;save reg.
  462. mov ax,offset dg:path_name ;an000;point to path_name
  463. add ax,[fname_len] ;an000;calculate end of path_name
  464. mov si,ax ;an000;point to end of path_name
  465. pop ax ;an000;restore reg.
  466. MOV CX,4 ;compare 4 bytes
  467. SUB SI,4 ;Point 4th to last char
  468. MOV DI,OFFSET DG:BAK ;Point to string ".BAK"
  469. REPE CMPSB ;Compare the two strings
  470. pop ds
  471. ASSUME DS:NOTHING
  472. JNZ NOTBAK
  473. JMP HAVBAK
  474. ;======================= end .BAK check ==================================
  475. ;======================= begin NOTBAK ====================================
  476. ; we have a file without a .BAK extension, try to open it
  477. NOTBAK:
  478. push ds
  479. push cs
  480. pop ds
  481. ASSUME DS:DG
  482. ;=========================================================================
  483. ; implement EXTENDED OPEN
  484. ;=========================================================================
  485. push es ;an000;save reg.
  486. mov bx,RW ;an000;open for read/write
  487. mov cx,ATTR ;an000;file attributes
  488. mov dx,RW_FLAG ;an000;action to take on open
  489. mov di,0ffffh ;an000;nul parm list
  490. call EXT_OPEN1 ;an000;open for R/W;DMS:6/10/87
  491. pop es ;an000;restore reg.
  492. ;=========================================================================
  493. pop ds
  494. ASSUME DS:NOTHING
  495. JC CHK_OPEN_ERR ;an open error occurred
  496. MOV RD_HANDLE,AX ;Save the handle
  497. Jmp HavFil ;work with the opened file
  498. ;======================= end NOTBAK ======================================
  499. Badopt:
  500. MOV DX,OFFSET DG:OPT_ERR_ptr;Bad option specified
  501. JMP XERROR
  502. ;=========================================================================
  503. ;
  504. ; The open of the file failed. We need to figure out why and report the
  505. ; correct message. The circumstances we can handle are:
  506. ;
  507. ; open returns pathnotfound => bad drive or file name
  508. ; open returns toomanyopenfiles => too many open files
  509. ; open returns access denied =>
  510. ; chmod indicates read-only => cannot edit read only file
  511. ; else => file creation error
  512. ; open returns filenotfound =>
  513. ; creat ok => close, delete, new file
  514. ; creat fails => file creation error
  515. ; else => file cre
  516. ;
  517. CHK_OPEN_ERR:
  518. cmp ax,error_path_not_found
  519. jz BadDriveError
  520. cmp ax,error_too_many_open_files
  521. jz TooManyError
  522. cmp ax,error_access_denied
  523. jnz CheckFNF
  524. push ds
  525. push cs
  526. pop ds
  527. assume ds:dg
  528. mov ax,(chmod shl 8)
  529. MOV DX,OFFSET DG:PATH_NAME
  530. int 21h
  531. jc FileCreationError
  532. test cx,attr_read_only
  533. jz FileCreationError
  534. jmp short ReadOnlyError
  535. CheckFNF:
  536. cmp ax,error_file_not_found
  537. jnz FileCreationError
  538. ;
  539. ; Try to create the file to see if it is OK.
  540. ;
  541. push ds
  542. push cs
  543. pop ds
  544. assume ds:dg
  545. ;=========================================================================
  546. ; implement EXTENDED OPEN
  547. ;=========================================================================
  548. mov bx,RW ;an000;open for read/write
  549. mov cx,ATTR ;an000;file attributes
  550. mov dx,CREAT_FLAG ;an000;action to take on open
  551. mov di,0ffffh ;an000;null parm list
  552. call EXT_OPEN1 ;an000;create file;DMS:6/10/87
  553. ;=========================================================================
  554. pop ds
  555. assume ds:nothing
  556. jc CreateCheck
  557. mov bx,ax
  558. mov ah,close
  559. int 21h
  560. push ds
  561. push cs
  562. pop ds
  563. assume ds:dg
  564. mov ah,unlink
  565. MOV DX,OFFSET DG:PATH_NAME
  566. int 21h
  567. pop ds
  568. assume ds:nothing
  569. jc FileCreationError ; This should NEVER be taken!!!
  570. MOV HAVEOF,0FFH ; Flag from a system 1.xx call
  571. MOV fNew,-1
  572. JMP short HAVFIL
  573. CreateCheck:
  574. cmp ax,error_access_denied
  575. jnz BadDriveError
  576. DiskFull:
  577. mov ax,NODIR
  578. jmp zerror
  579. FileCreationError:
  580. mov ax,bcreat
  581. jmp zerror
  582. ReadOnlyError:
  583. mov ax,RO_ERR
  584. jmp zerror
  585. BadDriveError:
  586. mov ax,BADDRV
  587. jmp zerror
  588. TooManyError:
  589. mov ax,msg_too_many
  590. jmp zerror
  591. CREAT_ERR:
  592. CMP DELFLG,0
  593. JNZ DiskFull
  594. push cs
  595. pop ds
  596. CALL DELBAK
  597. JMP short MAKFIL
  598. HAVBAK:
  599. mov ax,NOBAK
  600. jmp zerror
  601. HAVFIL:
  602. push cs
  603. pop ds
  604. ASSUME DS:DG
  605. CMP fNew,0
  606. JZ MakeBak
  607. mov ax,newfil
  608. call display_message
  609. MakeBak:
  610. MOV SI,OFFSET DG:PATH_NAME
  611. MOV CX,[FNAME_LEN]
  612. PUSH CX
  613. MOV DI,OFFSET DG:TEMP_PATH
  614. REP MOVSB
  615. DEC DI
  616. MOV DX,DI
  617. POP CX
  618. MOV AL,"."
  619. STD
  620. REPNE SCASB
  621. JZ FOUND_EXT
  622. MOV DI,DX ;Point to last char in filename
  623. FOUND_EXT:
  624. CLD
  625. INC DI
  626. MOV [EXT_PTR],DI
  627. MOV SI,OFFSET DG:$$$FILE
  628. MOV CX,5
  629. REP MOVSB
  630. ;Create .$$$ file to make sure directory has room
  631. MAKFIL:
  632. ;=========================================================================
  633. ; implement EXTENDED OPEN
  634. ;=========================================================================
  635. mov bx,RW ;an000;open for read/write
  636. mov cx,ATTR ;an000;file attributes
  637. mov dx,Creat_Open_Flag ;an000;action to take on open
  638. cmp EA_Flag,True ;an000;EA_Buffer used?
  639. ; $if e ;an000;yes
  640. JNE $$IF12
  641. mov di,offset dg:EA_Parm_List ;an000; point to buffer
  642. ; $else ;an000;
  643. JMP SHORT $$EN12
  644. $$IF12:
  645. mov di,0ffffh ;an000;nul parm list
  646. ; $endif ;an000;
  647. $$EN12:
  648. call EXT_OPEN2 ;an000;create file;DMS:6/10/87
  649. ;=========================================================================
  650. JC CREAT_ERR
  651. MOV [WRT_HANDLE],AX
  652. ;
  653. ; We determine the size of the available memory. Use the word in the PDB at
  654. ; [2] to determine the number of paragraphs. Then truncate this to 64K at
  655. ; most.
  656. ;
  657. push ds ;save ds for size calc
  658. mov ds,[org_ds]
  659. MOV CX,DS:[2]
  660. MOV DI,CS
  661. SUB CX,DI
  662. CMP CX,1000h
  663. JBE GotSize
  664. MOV CX,0FFFh
  665. GotSize:
  666. SHL CX,1
  667. SHL CX,1
  668. SHL CX,1
  669. SHL CX,1
  670. pop ds ;restore ds after size calc
  671. DEC CX
  672. MOV [LAST_MEM],CX
  673. MOV DI,OFFSET DG:START
  674. TEST fNew,-1
  675. JNZ SAVEND
  676. SUB CX,OFFSET DG:START ;Available memory
  677. SHR CX,1 ;1/2 of available memory
  678. MOV AX,CX
  679. SHR CX,1 ;1/4 of available memory
  680. MOV [ONE4TH],CX ;Save amount of 1/4 full
  681. ADD CX,AX ;3/4 of available memory
  682. MOV DX,CX
  683. ADD DX,OFFSET DG:START
  684. MOV [THREE4TH],DX ;Save pointer to 3/4 full
  685. MOV DX,OFFSET DG:START
  686. SAVEND:
  687. CLD
  688. MOV BYTE PTR [DI],1AH
  689. MOV [ENDTXT],DI
  690. MOV BYTE PTR [COMBUF],128
  691. MOV BYTE PTR [EDITBUF],255
  692. MOV BYTE PTR [EOL],10
  693. MOV [POINTER],OFFSET DG:START
  694. MOV [CURRENT],1
  695. MOV ParamCt,1
  696. MOV [PARAM1],0 ;M004 Leave room in memory, was -1
  697. TEST fNew,-1
  698. JNZ COMMAND
  699. ;
  700. ; The above setting of PARAM1 to -1 causes this call to APPEND to try to read
  701. ; in as many lines that will fit, BUT.... What we are doing is simulating
  702. ; the user issuing an APPEND command, and if the user asks for more lines
  703. ; than we get then an "Insufficient memory" error occurs. In this case we
  704. ; DO NOT want this error, we just want as many lines as possible read in.
  705. ; The twiddle of ENDING suppresses the memory error
  706. ;
  707. MOV BYTE PTR [ENDING],1 ;Suppress memory errors
  708. CALL APPEND
  709. MOV ENDING,0 ; restore correct initial value
  710. Break <Main command loop>
  711. ;
  712. ; Main read/parse/execute loop. We reset the stack all the time as there
  713. ; are routines that JMP back here. Don't blame me; Tim Paterson write this.
  714. ;
  715. COMMAND:
  716. push cs ;an000;set up addressibility
  717. pop ds ;an000;
  718. push cs ;an000;
  719. pop es ;an000;
  720. assume ds:dg,es:dg ;an000;
  721. MOV SP, STACK
  722. MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H
  723. MOV DX,OFFSET DG:ABORTCOM
  724. INT 21H
  725. mov ax,prompt
  726. call display_message
  727. MOV DX,OFFSET DG:COMBUF
  728. MOV AH,STD_CON_STRING_INPUT
  729. INT 21H
  730. MOV [COMLINE],OFFSET DG:COMBUF + 2
  731. mov ax,msg_lf
  732. call display_message
  733. PARSE:
  734. MOV [PARAM2],0
  735. MOV [PARAM3],0
  736. MOV [PARAM4],0
  737. mov [fourth],0 ;reset the fourth parameter flag
  738. MOV QFLG,0
  739. MOV SI,[COMLINE]
  740. MOV BP,OFFSET DG:PARAM1
  741. XOR DI,DI
  742. CHKLP:
  743. CALL GETNUM
  744. ;
  745. ; AL has first char after arg
  746. ;
  747. MOV ds:[BP+DI],DX
  748. ADD DI,2
  749. MOV ParamCt,DI ; set up count of parameters
  750. SHR ParamCt,1 ; convert to index (1-based)
  751. CALL SKIP1 ; skip to next parameter
  752. CMP AL,"," ; is there a comma?
  753. jnz NOT_COMMA ; if not, then done with arguments
  754. cmp di,8 ; **** maximum size of PARAM array!
  755. jb CHKLP ; continue scanning if <4 PARAMS
  756. jmp short COMERR
  757. NOT_COMMA:
  758. DEC SI ; point at char next
  759. CALL Kill_BL ; skip all blanks
  760. CMP AL,"?" ; is there a ?
  761. JNZ DISPATCH ; no, got command letter
  762. MOV QFLG,-1 ; signal query
  763. CALL Kill_BL
  764. DISPATCH:
  765. CMP AL,5FH
  766. JBE UPCASE
  767. cmp al,"z"
  768. ja upcase
  769. AND AL,5FH
  770. UPCASE:
  771. MOV DI,OFFSET DG:COMTAB
  772. mov cx,NUMCOM
  773. REPNE SCASB
  774. JNZ COMERR
  775. SUB DI,1+OFFSET DG:COMTAB ; convert to index
  776. MOV BX,DI
  777. MOV AX,[PARAM2]
  778. OR AX,AX
  779. JZ PARMOK
  780. CMP AX,[PARAM1]
  781. JB COMERR ; Param. 2 must be >= param 1
  782. PARMOK:
  783. MOV [COMLINE],SI
  784. SHL BX,1
  785. CALL [BX+TABLE]
  786. COMOVER:
  787. MOV SI,[COMLINE]
  788. CALL Kill_BL
  789. CMP AL,0DH
  790. JZ COMMANDJ
  791. CMP AL,1AH
  792. JZ DELIM
  793. CMP AL,";"
  794. JNZ NODELIM
  795. DELIM:
  796. INC SI
  797. NODELIM:
  798. DEC SI
  799. MOV [COMLINE],SI
  800. JMP PARSE
  801. COMMANDJ:
  802. JMP COMMAND
  803. SKIP1:
  804. DEC SI
  805. CALL Kill_BL
  806. ret1: return
  807. Break <Range Checking and argument parsing>
  808. ;
  809. ; People call here. we need to reset the stack.
  810. ; Inputs: BX has param1
  811. ; Outputs: Returns if BX <= Param2
  812. ;
  813. CHKRANGE:
  814. CMP [PARAM2],0
  815. retz
  816. CMP BX,[PARAM2]
  817. JBE RET1
  818. POP DX ; clean up return address
  819. COMERR:
  820. mov ax,BADCOM
  821. zcomerr1:
  822. call display_message
  823. jmp command
  824. COMERR1:
  825. call std_printf
  826. JMP COMMAND
  827. ;
  828. ; GetNum parses off 1 argument from the command line. Argument forms are:
  829. ; nnn a number < 65536
  830. ; +nnn current line + number
  831. ; -nnn current line - number
  832. ; . current line
  833. ; # lastline + 1
  834. ;
  835. ;
  836. GETNUM:
  837. CALL Kill_BL
  838. cmp di,6 ;Is this the fourth parameter?
  839. jne sk1
  840. mov [fourth],1 ;yes, set the flag
  841. sk1:
  842. CMP AL,"."
  843. JZ CURLIN
  844. CMP AL,"#"
  845. JZ MAXLIN
  846. CMP AL,"+"
  847. JZ FORLIN
  848. CMP AL,"-"
  849. JZ BACKLIN
  850. MOV DX,0
  851. MOV CL,0 ;Flag no parameter seen yet
  852. NUMLP:
  853. CMP AL,"0"
  854. JB NUMCHK
  855. CMP AL,"9"
  856. JA NUMCHK
  857. CMP DX,6553 ;Max line/10
  858. JAE COMERR ;Ten times this is too big
  859. MOV CL,1 ;Parameter digit has been found
  860. SUB AL,"0"
  861. MOV BX,DX
  862. SHL DX,1
  863. SHL DX,1
  864. ADD DX,BX
  865. SHL DX,1
  866. CBW
  867. ADD DX,AX
  868. LODSB
  869. JMP SHORT NUMLP
  870. NUMCHK:
  871. CMP CL,0
  872. retz
  873. OR DX,DX
  874. JZ COMERR ;Don't allow zero as a parameter
  875. return
  876. CURLIN:
  877. cmp [fourth],1 ;the fourth parameter?
  878. je comerra ;yes, an error
  879. MOV DX,[CURRENT]
  880. LODSB
  881. return
  882. MAXLIN:
  883. cmp [fourth],1 ;the fourth parameter?
  884. je comerra ;yes, an error
  885. MOV DX,1
  886. MOV AL,0Ah
  887. PUSH DI
  888. MOV DI,OFFSET DG:START
  889. MOV CX,EndTxt
  890. SUB CX,DI
  891. MLoop:
  892. JCXZ MDone
  893. REPNZ SCASB
  894. JNZ MDone
  895. INC DX
  896. JMP MLoop
  897. MDone:
  898. POP DI
  899. LODSB
  900. return
  901. FORLIN:
  902. cmp [fourth],1 ;the fourth parameter?
  903. je comerra ;yes, an error
  904. CALL GETNUM
  905. ADD DX,[CURRENT]
  906. return
  907. BACKLIN:
  908. cmp [fourth],1 ;the fourth parameter?
  909. je comerra ;yes, an error
  910. CALL GETNUM
  911. MOV BX,[CURRENT]
  912. SUB BX,DX
  913. JA OkLin ; if negative or zero
  914. MOV BX,1 ; use first line
  915. OkLin:
  916. MOV DX,BX
  917. return
  918. comerra:
  919. jmp comerr
  920. ERRORJ:
  921. JMP COMERR
  922. ERROR1J:
  923. JMP zcomerr1
  924. BLANKLINE:
  925. cmp QFLG,0
  926. jnz SHOWHELP ; if ? at front of blank line, do HELP
  927. jmp NOCOM ; ignore blank line otherwise
  928. SHOWHELP:
  929. dec [COMLINE] ; point back to <cr>
  930. mov cx,num_help_msgs-1
  931. mov ax,dsp_help
  932. SHOWHELP1:
  933. call display_message
  934. inc ax
  935. loop SHOWHELP1
  936. ; fall into display_message for last message and return
  937. ;=========================================================================
  938. ; display_message : Displays a simple common message through the
  939. ; ; message retriever, using a common parameter
  940. ; ; block.
  941. ; Inputs : ax = message number to display
  942. ;
  943. ;=========================================================================
  944. display_message proc near
  945. mov dg:[simple_msg],ax
  946. mov dx,offset dg:simple_msg
  947. jmp printf ; display it
  948. display_message endp
  949. Break <Move and Copy commands>
  950. PUBLIC MOVE
  951. MOVE:
  952. CMP ParamCt,3
  953. JNZ ERRORJ
  954. MOV BYTE PTR [MOVFLG],1
  955. JMP SHORT BLKMOVE
  956. PUBLIC COPY
  957. COPY:
  958. CMP ParamCt,3
  959. JB ERRORJ
  960. MOV BYTE PTR [MOVFLG],0
  961. ;
  962. ; We are to move/copy a number of lines from one range to another.
  963. ;
  964. ; Memory looks like this:
  965. ;
  966. ; START: line 1
  967. ; ...
  968. ; pointer-> line n Current has n in it
  969. ; ...
  970. ; line m
  971. ; endtxt-> ^Z
  972. ;
  973. ; The algoritm is:
  974. ;
  975. ; Bounds check on args.
  976. ; set ptr1 and ptr2 to range before move
  977. ; set copysiz to number to move
  978. ; open up copysize * count for destination
  979. ; if destination is before ptr1 then
  980. ; add copysize * count to both ptrs
  981. ; while count > 0 do
  982. ; move from ptr1 to destination for copysize bytes
  983. ; count --
  984. ; if moving then
  985. ; move from ptr2 through end to ptr1
  986. ; set endtxt to last byte moved.
  987. ; set current, pointer to original destination
  988. ;
  989. BLKMOVE:
  990. ;
  991. ; Make sure that all correct arguments are specified.
  992. ;
  993. MOV BX,[PARAM3] ; get destination of move/copy
  994. OR BX,BX ; must be specified (non-0)
  995. mov ax,DEST
  996. JZ ERROR1J ; is 0 => error
  997. ;
  998. ; get arg 1 (defaulting if necessary) and range check it.
  999. ;
  1000. MOV BX,[PARAM1] ; get first argument
  1001. OR BX,BX ; do we default it?
  1002. JNZ NXTARG ; no, assume it is OK.
  1003. MOV BX,[CURRENT] ; Defaults to the current line
  1004. CALL CHKRANGE ; Make sure it is good.
  1005. MOV [PARAM1],BX ; set it
  1006. NXTARG:
  1007. CALL FINDLIN ; find first argument line
  1008. JNZ ErrorJ ; line not found
  1009. MOV [PTR_1],DI
  1010. ;
  1011. ; get arg 2 (defaulting if necessary) and range check it.
  1012. ;
  1013. MOV BX,[PARAM2] ; Get the second parameter
  1014. OR BX,BX ; do we default it too?
  1015. JNZ HAVARGS ; Nope.
  1016. MOV BX,[CURRENT] ; Defaults to the current line
  1017. MOV [PARAM2],BX ; Stash it away
  1018. HAVARGS:
  1019. CALL FindLin
  1020. JNZ ErrorJ ; line not found
  1021. MOV BX,Param2
  1022. INC BX ;Get pointer to line Param2+1
  1023. CALL FINDLIN
  1024. MOV [PTR_2],DI ;Save it
  1025. ;
  1026. ; We now have true line number arguments and pointers to the relevant places.
  1027. ; ptr_1 points to beginning of region and ptr_2 points to first byte beyond
  1028. ; that region.
  1029. ;
  1030. ; Check args for correct ordering of first two arguments
  1031. ;
  1032. mov dx,[param1]
  1033. cmp dx,[param2]
  1034. jbe havargs1 ; first must be <= second
  1035. jmp comerr
  1036. havargs1:
  1037. ;
  1038. ; make sure that the third argument is not contained in the first range
  1039. ;
  1040. MOV DX,[PARAM3]
  1041. CMP DX,[PARAM1] ; third must be <= first or
  1042. JBE NOERROR
  1043. CMP DX,[PARAM2]
  1044. JA NoError ; third must be > last
  1045. JMP ComErr
  1046. NOERROR:
  1047. ;
  1048. ; Determine number to move
  1049. ;
  1050. MOV CX,Ptr_2
  1051. SUB CX,Ptr_1 ; Calculate number of bytes to copy
  1052. MOV CopySiz,CX
  1053. MOV CopyLen,CX ; Save for individual move.
  1054. MOV AX,[PARAM4] ; Was count defaulted?
  1055. OR AX,AX
  1056. JZ SizeOk ; yes, CX has correct value
  1057. MUL [COPYSIZ] ; convert to true size
  1058. MOV CX,AX ; move to count register
  1059. OR DX,DX ; overflow?
  1060. JZ SizeOK ; no
  1061. JMP MEMERR ; yes, bomb.
  1062. SizeOK:
  1063. MOV [COPYSIZ],CX
  1064. ;
  1065. ; Check to see that we have room to grow by copysiz
  1066. ;
  1067. MOV AX,[ENDTXT] ; get pointer to last byte
  1068. MOV DI,[LAST_MEM] ; get offset of last location in memory
  1069. SUB DI,AX ; remainder of space
  1070. CMP DI,CX ; is there at least copysiz room?
  1071. JAE HAV_ROOM ; yes
  1072. JMP MEMERR
  1073. HAV_ROOM:
  1074. ;
  1075. ; Find destination of move/copy
  1076. ;
  1077. MOV BX,[PARAM3]
  1078. CALL FINDLIN
  1079. MOV [PTR_3],DI
  1080. ;
  1081. ; open up copysiz bytes of space at destination
  1082. ;
  1083. ; move (p3, p3+copysiz, endtxt-p3);
  1084. ;
  1085. MOV SI,EndTxt ; get source pointer to end
  1086. MOV CX,SI
  1087. SUB CX,DI ; number of bytes from here to end
  1088. INC CX ; remember ^Z at end
  1089. MOV DI,SI ; destination starts at end
  1090. ADD DI,[COPYSIZ] ; plus size we are opening
  1091. MOV [ENDTXT],DI ; new end point
  1092. STD ; go backwards
  1093. REP MOVSB ; and store everything
  1094. CLD ; go forward
  1095. ;
  1096. ; relocate ptr_1 and ptr_2 if we moved them
  1097. ;
  1098. MOV BX,Ptr_3
  1099. CMP BX,Ptr_1 ; was dest before source?
  1100. JA NoReloc ; no, above. no relocation
  1101. MOV BX,CopySiz
  1102. ADD Ptr_1,BX
  1103. ADD Ptr_2,BX ; relocate pointers
  1104. NoReloc:
  1105. ;
  1106. ; Now we copy for count times copylen bytes from ptr_1 to ptr_3
  1107. ;
  1108. ; move (ptr_1, ptr_3, copylen);
  1109. ;
  1110. MOV BX,Param4 ; count (0 and 1 are both 1)
  1111. MOV DI,Ptr_3 ; destination
  1112. CopyText:
  1113. MOV CX,CopyLen ; number to move
  1114. MOV SI,Ptr_1 ; start point
  1115. REP MOVSB ; move the bytes
  1116. SUB BX,1 ; exhaust count?
  1117. JG CopyText ; no, go for more
  1118. ;
  1119. ; If we are moving
  1120. ;
  1121. CMP BYTE PTR MovFlg,0
  1122. JZ CopyDone
  1123. ;
  1124. ; Delete the source text between ptr_1 and ptr_2
  1125. ;
  1126. ; move (ptr_2, ptr_1, endtxt-ptr_2);
  1127. ;
  1128. MOV DI,Ptr_1 ; destination
  1129. MOV SI,Ptr_2 ; source
  1130. MOV CX,EndTxt ; pointer to end
  1131. SUB CX,SI ; number of bytes to move
  1132. CLD ; forwards
  1133. REP MOVSB
  1134. MOV BYTE PTR ES:[DI],1Ah ; remember ^Z terminate
  1135. MOV EndTxt,DI ; new end of file
  1136. ;
  1137. ; May need to relocate current line (parameter 3).
  1138. ;
  1139. MOV BX,Param3 ; get new current line
  1140. CMP BX,Param1 ; do we need to relocate
  1141. JBE CopyDone ; no, current line is before removed M002
  1142. ADD BX,Param1 ; add in first
  1143. SUB BX,Param2 ; current += first-last - 1;
  1144. DEC BX
  1145. MOV Param3,BX
  1146. CopyDone:
  1147. ;
  1148. ; we are done. Make current line the destination
  1149. ;
  1150. MOV BX,Param3 ; set parameter 3 to be current
  1151. CALL FINDLIN
  1152. MOV [POINTER],DI
  1153. MOV [CURRENT],BX
  1154. return
  1155. Break <MoveFile - open up a hole in the internal file>
  1156. ;
  1157. ; MoveFile moves the text in the buffer to create a hole
  1158. ;
  1159. ; Inputs: DX is spot in buffer for destination
  1160. ; DI is spot in buffer for source
  1161. MOVEFILE:
  1162. MOV CX,[ENDTXT] ;Get End-of-text marker
  1163. MOV SI,CX
  1164. SUB CX,DI ;Calculate number of bytes to copy
  1165. INC CX ; remember ^Z
  1166. MOV DI,DX
  1167. STD
  1168. REP MOVSB ;Copy CX bytes
  1169. XCHG SI,DI
  1170. CLD
  1171. INC DI
  1172. MOV BP,SI
  1173. SETPTS:
  1174. MOV [POINTER],DI ;Current line is first free loc
  1175. MOV [CURRENT],BX ; in the file
  1176. MOV [ENDTXT],BP ;End-of-text is last free loc before
  1177. return
  1178. NAMERR:
  1179. cmp ax,error_file_not_found
  1180. jne otherMergeErr
  1181. MOV DX,OFFSET DG:FILENM_ptr
  1182. JMP COMERR1
  1183. otherMergeErr:
  1184. mov ax,BADDRV
  1185. jmp zcomerr1
  1186. PUBLIC MERGE
  1187. MERGE:
  1188. CMP ParamCt,1
  1189. JZ MergeOK
  1190. JMP Comerr
  1191. MergeOK:
  1192. CALL KILL_BL
  1193. DEC SI
  1194. MOV DI,OFFSET DG:MRG_PATH_NAME
  1195. XOR CX,CX
  1196. CLD
  1197. MRG1:
  1198. LODSB
  1199. CMP AL," "
  1200. JE MRG2
  1201. CMP AL,9
  1202. JE MRG2
  1203. CMP AL,CR
  1204. JE MRG2
  1205. CMP AL,";"
  1206. JE MRG2
  1207. STOSB
  1208. JMP SHORT MRG1
  1209. MRG2:
  1210. MOV BYTE PTR[DI],0
  1211. DEC SI
  1212. MOV [COMLINE],SI
  1213. ;=========================================================================
  1214. ; implement EXTENDED OPEN
  1215. ;=========================================================================
  1216. push es ;an000;save reg.
  1217. mov bx,ext_read ;an000;open for read
  1218. mov cx,ATTR ;an000;file attributes
  1219. mov dx,OPEN_FLAG ;an000;action to take on open
  1220. mov di,0ffffh ;an000;null parm list
  1221. call EXT_OPEN3 ;an000;create file;DMS:6/10/87
  1222. pop es ;an000;restore reg.
  1223. ;=========================================================================
  1224. JC NAMERR
  1225. MOV [MRG_HANDLE],AX
  1226. MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H
  1227. MOV DX,OFFSET DG:ABORTMERGE
  1228. INT 21H
  1229. MOV BX,[PARAM1]
  1230. OR BX,BX
  1231. JNZ MRG
  1232. MOV BX,[CURRENT]
  1233. CALL CHKRANGE
  1234. MRG:
  1235. CALL FINDLIN
  1236. MOV BX,DX
  1237. MOV DX,[LAST_MEM]
  1238. CALL MOVEFILE
  1239. MOV DX,[POINTER]
  1240. MOV CX,[ENDTXT]
  1241. SUB CX,[POINTER]
  1242. PUSH CX
  1243. MOV BX,[MRG_HANDLE]
  1244. MOV AH,READ
  1245. INT 21H
  1246. POP DX
  1247. MOV CX,AX
  1248. CMP DX,CX
  1249. JA FILEMRG ; M005
  1250. mov ax,mrgerr
  1251. call display_message
  1252. MOV CX,[POINTER]
  1253. JMP SHORT RESTORE_Z
  1254. FILEMRG:
  1255. ADD CX,[POINTER]
  1256. MOV SI,CX
  1257. dec si
  1258. LODSB
  1259. CMP AL,1AH
  1260. JNZ RESTORE_Z
  1261. dec cx
  1262. RESTORE_Z:
  1263. MOV DI,CX
  1264. MOV SI,[ENDTXT]
  1265. INC SI
  1266. MOV CX,[LAST_MEM]
  1267. SUB CX,SI
  1268. inc cx ; remember ^Z
  1269. REP MOVSB
  1270. dec di ; unremember ^Z
  1271. MOV [ENDTXT],DI
  1272. MOV BX,[MRG_HANDLE]
  1273. MOV AH,CLOSE
  1274. INT 21H
  1275. return
  1276. PUBLIC INSERT
  1277. INSERT:
  1278. CMP ParamCt,1
  1279. JBE OKIns
  1280. JMP ComErr
  1281. OKIns:
  1282. MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H ;Set vector 23H
  1283. MOV DX,OFFSET DG:ABORTINS
  1284. INT 21H
  1285. MOV BX,[PARAM1]
  1286. OR BX,BX
  1287. JNZ INS
  1288. MOV BX,[CURRENT]
  1289. CALL CHKRANGE
  1290. INS:
  1291. CALL FINDLIN
  1292. MOV BX,DX
  1293. MOV DX,[LAST_MEM]
  1294. CALL MOVEFILE
  1295. INLP:
  1296. CALL SETPTS ;Update the pointers into file
  1297. CALL SHOWNUM
  1298. MOV DX,OFFSET DG:EDITBUF
  1299. MOV AH,STD_CON_STRING_INPUT
  1300. INT 21H
  1301. CALL LF
  1302. MOV SI,2 + OFFSET DG:EDITBUF
  1303. CMP BYTE PTR [SI],1AH
  1304. JZ ENDINS
  1305. ;-----------------------------------------------------------------------
  1306. call unquote ;scan for quote chars if any
  1307. ;-----------------------------------------------------------------------
  1308. MOV CL,[SI-1]
  1309. MOV CH,0
  1310. MOV DX,DI
  1311. INC CX
  1312. ADD DX,CX
  1313. JC MEMERRJ1
  1314. JZ MEMERRJ1
  1315. CMP DX,BP
  1316. JB MEMOK
  1317. MEMERRJ1:
  1318. CALL END_INS
  1319. JMP MEMERR
  1320. MEMOK:
  1321. REP MOVSB
  1322. MOV AL,10
  1323. STOSB
  1324. INC BX
  1325. JMP SHORT INLP
  1326. ABORTMERGE:
  1327. MOV DX,OFFSET DG:START
  1328. MOV AH,SET_DMA
  1329. INT 21H
  1330. ABORTINS:
  1331. MOV AX,CS ;Restore segment registers
  1332. MOV DS,AX
  1333. MOV ES,AX
  1334. MOV AX,CSTACK
  1335. MOV SS,AX
  1336. MOV SP,STACK
  1337. STI
  1338. CALL CRLF
  1339. CALL ENDINS
  1340. JMP COMOVER
  1341. ENDINS:
  1342. CALL END_INS
  1343. return
  1344. END_INS:
  1345. MOV BP,[ENDTXT]
  1346. MOV DI,[POINTER]
  1347. MOV SI,BP
  1348. INC SI
  1349. MOV CX,[LAST_MEM]
  1350. SUB CX,BP
  1351. REP MOVSB
  1352. DEC DI
  1353. MOV [ENDTXT],DI
  1354. MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H
  1355. MOV DX,OFFSET DG:ABORTCOM
  1356. INT 21H
  1357. return
  1358. FILLBUF:
  1359. MOV [PARAM1],-1 ;Read in max. no of lines
  1360. MOV ParamCt,1
  1361. CALL APPEND
  1362. MOV Param1,0
  1363. PUBLIC ENDED
  1364. ENDED:
  1365. ;Write text out to .$$$ file
  1366. CMP ParamCt,1
  1367. JZ ENDED1
  1368. CERR: JMP ComErr
  1369. Ended1:
  1370. CMP Param1,0
  1371. JNZ Cerr
  1372. MOV BYTE PTR [ENDING],1 ;Suppress memory errors
  1373. MOV BX,-1 ;Write max. no of lines
  1374. CALL WRT
  1375. TEST BYTE PTR [HAVEOF],-1
  1376. JZ FILLBUF
  1377. MOV DX,[ENDTXT]
  1378. MOV CX,1
  1379. MOV BX,[WRT_HANDLE]
  1380. MOV AH,WRITE
  1381. INT 21H ;Write end-of-file byte
  1382. ;Close input file ; MZ 11/30
  1383. ; MZ 11/30
  1384. MOV BX,[RD_HANDLE] ; MZ 11/30
  1385. MOV AH,CLOSE ; MZ 11/30
  1386. INT 21H ; MZ 11/30
  1387. ;Close .$$$ file
  1388. MOV BX,[WRT_HANDLE]
  1389. MOV AH,CLOSE
  1390. INT 21H
  1391. ;Rename original file .BAK
  1392. MOV DI,[EXT_PTR]
  1393. MOV SI,OFFSET DG:BAK
  1394. MOVSW
  1395. MOVSW
  1396. MOVSB
  1397. MOV DX,OFFSET DG:PATH_NAME
  1398. MOV DI,OFFSET DG:TEMP_PATH
  1399. MOV AH,RENAME
  1400. INT 21H
  1401. MOV DI,[EXT_PTR]
  1402. MOV SI,OFFSET DG:$$$FILE
  1403. MOVSW
  1404. MOVSW
  1405. MOVSB
  1406. ;Rename .$$$ file to original name
  1407. MOV DX,OFFSET DG:TEMP_PATH
  1408. MOV DI,OFFSET DG:PATH_NAME
  1409. MOV AH,RENAME
  1410. INT 21H
  1411. ; mode
  1412. mov ah,exit
  1413. xor al,al
  1414. int 21h
  1415. ;=========================================================================
  1416. ; EDLIN_DISP_GET: This routine will give us the attributes of the
  1417. ; current display, which are to be used to restore the screen
  1418. ; back to its original state on exit from EDLIN. We also
  1419. ; set the screen to a text mode here with an 80 X 25 color
  1420. ; format.
  1421. ;
  1422. ; Inputs : VIDEO_GET - 0fH (get current video mode)
  1423. ; VIDEO_SET - 00h (set video mode)
  1424. ; VIDEO_TEXT- 03h (80 X 25 color mode)
  1425. ;
  1426. ; Outputs : VIDEO_ORG - Original video attributes on entry to EDLIN
  1427. ;
  1428. ;=========================================================================
  1429. EDLIN_DISP_GET proc near ;an000;video attributes
  1430. push ax ;an000;save affected regs.
  1431. push bx ;an000;
  1432. push cx ;an000;
  1433. push dx ;an000;
  1434. push si ;an000;
  1435. push ds ;an000;
  1436. push cs ;an000;exchange cs/ds
  1437. pop ds ;an000;
  1438. mov ax,440Ch ;an000;generic ioctl
  1439. mov bx,Std_Out ;an000;Console
  1440. mov cx,(Display_Attr shl 8) or Get_Display ;an000;get display
  1441. mov dx,offset dg:Video_Buffer ;an000;buffer for video attr.
  1442. int 21h ;an000;
  1443. ; $if nc ;an000;function returned a
  1444. JC $$IF15
  1445. ; buffer
  1446. mov si,dx ;an000;get pointer
  1447. mov ax,word ptr dg:[si].Display_Length_Char ;an000;get video len.
  1448. dec ax ;an000;allow room for message
  1449. mov dg:Disp_Len,al ;an000;put it into var.
  1450. mov ax,word ptr dg:[si].Display_Width_Char ;an000;get video width
  1451. mov dg:Disp_Width,al ;an000;put it into var.
  1452. ; $else ;an000;function failed use
  1453. JMP SHORT $$EN15
  1454. $$IF15:
  1455. ; default values
  1456. mov al,Def_Disp_Len ;an000;get default length
  1457. dec al ;an000;leave room for messages
  1458. mov dg:Disp_Len,al ;an000;use default length
  1459. mov dg:Disp_Width,Def_Disp_Width;an000;use default width
  1460. ; $endif ;an000;
  1461. $$EN15:
  1462. pop ds ;an000;restore affected regs.
  1463. pop si ;an000;
  1464. pop dx ;an000;
  1465. pop cx ;an000;
  1466. pop bx ;an000;
  1467. pop ax ;an000;
  1468. ret ;an000;return to caller
  1469. EDLIN_DISP_GET endp ;an000;end proc.
  1470. ;=========================================================================
  1471. ; EXT_OPEN1 : This routine opens a file for read/write access. If the file
  1472. ; if not present for opening the open will fail and return with a
  1473. ; carry set.
  1474. ;
  1475. ; Inputs : BX - Open mode
  1476. ; CX - File attributes
  1477. ; DX - Open action
  1478. ;
  1479. ; Outputs: CY - If error
  1480. ;
  1481. ; Date : 6/10/87
  1482. ;=========================================================================
  1483. EXT_OPEN1 proc near ;an000;open for R/W
  1484. assume ds:dg
  1485. push ds ;an000;save regs
  1486. push si ;an000;
  1487. mov ah,ExtOpen ;an000;extended open
  1488. mov al,0 ;an000;reserved by system
  1489. mov si,offset dg:path_name ;an000;point to PATH_NAME
  1490. int 21h ;an000;invoke function
  1491. pop si ;an000;restore regs
  1492. pop ds ;an000;
  1493. ret ;an000;return to caller
  1494. EXT_OPEN1 endp ;an000;end proc.
  1495. ;=========================================================================
  1496. ; EXT_OPEN2 : This routine will attempt to create a file for read/write
  1497. ; access. If the files exists the create will fail and return
  1498. ; with the carry set.
  1499. ;
  1500. ; Inputs : BX - Open mode
  1501. ; CX - File attributes
  1502. ; DX - Open action
  1503. ;
  1504. ; Outputs: CY - If error
  1505. ;
  1506. ; Date : 6/10/87
  1507. ;=========================================================================
  1508. EXT_OPEN2 proc near ;an000;create a file
  1509. assume ds:dg
  1510. push ds ;an000;save regs
  1511. push si ;an000;
  1512. mov ah,ExtOpen ;an000;extended open
  1513. mov al,0 ;an000;reserved by system
  1514. mov si,offset dg:temp_path ;an000;point to TEMP_PATH
  1515. int 21h ;an000;invoke function
  1516. pop si ;an000;restore regs
  1517. pop ds ;an000;
  1518. ret ;an000;return to caller
  1519. EXT_OPEN2 endp ;an000;end proc.
  1520. ;=========================================================================
  1521. ; EXT_OPEN3 : This routine will attempt to create a file for read
  1522. ; access. If the files exists the create will fail and return
  1523. ; with the carry set.
  1524. ;
  1525. ; Inputs : BX - Open mode
  1526. ; CX - File attributes
  1527. ; DX - Open action
  1528. ;
  1529. ; Outputs: CY - If error
  1530. ;
  1531. ; Date : 6/10/87
  1532. ;=========================================================================
  1533. EXT_OPEN3 proc near ;an000;create a file
  1534. assume ds:dg
  1535. push ds ;an000;save regs
  1536. push si ;an000;
  1537. mov ah,ExtOpen ;an000;extended open
  1538. mov al,0 ;an000;reserved by system
  1539. mov si,offset dg:mrg_path_name ;an000;point to mrg_path_name
  1540. int 21h ;an000;invoke function
  1541. pop si ;an000;restore regs
  1542. pop ds ;an000;
  1543. ret ;an000;return to caller
  1544. EXT_OPEN3 endp ;an000;end proc.
  1545. ;=========================================================================
  1546. ; EDLIN_COMMAND : This routine provides an interface between the new
  1547. ; parser and the existing logic of EDLIN. We will be
  1548. ; interfacing the parser with three existing variables.
  1549. ;
  1550. ; Inputs : FILESPEC - Filespec entered by the user and passed by
  1551. ; the parser.
  1552. ;
  1553. ; PARSE_SWITCH_B - Contains the result of the parse for the
  1554. ; /B switch. This is passed by the parser.
  1555. ;
  1556. ; Outputs: PATH_NAME - Filespec
  1557. ; LOADMOD - Flag for /B switch
  1558. ; FNAME_LEN - Length of filespec
  1559. ;
  1560. ; Date : 6/11/87
  1561. ;=========================================================================
  1562. EDLIN_COMMAND proc near ;an000;interface parser
  1563. push ax ;an000;save regs.
  1564. push cx ;an000;
  1565. push di ;an000
  1566. push si ;an000;
  1567. mov si,offset dg:filespec ;an000;get its offset
  1568. mov di,offset dg:path_name ;an000;get its offset
  1569. mov cx,00h ;an000;cx will count filespec
  1570. ; length
  1571. cmp parse_switch_b,true ;an000;do we have /B switch
  1572. ; $if z ;an000;we have the switch
  1573. JNZ $$IF18
  1574. mov [LOADMOD],01h ;an000;signal switch found
  1575. ; $endif ;an000
  1576. $$IF18:
  1577. ; $do ;an000;while we have filespec
  1578. $$DO20:
  1579. lodsb ;an000;move byte to al
  1580. cmp al,nul ;an000;see if we are at
  1581. ; the end of the
  1582. ; filespec
  1583. ; $leave e ;an000;exit while loop
  1584. JE $$EN20
  1585. stosb ;an000;move byte to path_name
  1586. inc cx ;an000;increment the length
  1587. ; of the filespec
  1588. ; $enddo ;an000;end do while
  1589. JMP SHORT $$DO20
  1590. $$EN20:
  1591. mov [FNAME_LEN],cx ;an000;save filespec's length
  1592. pop si ;an000; restore regs
  1593. pop di ;an000;
  1594. pop cx ;an000;
  1595. pop ax ;an000;
  1596. ret ;an000;return to caller
  1597. EDLIN_COMMAND endp ;an000;end proc
  1598. ;=========================================================================
  1599. ; Calc_Memory_Avail : This routine will calculate the memory
  1600. ; available for use by EDLIN.
  1601. ;
  1602. ; Inputs : ORG_DS - DS of PSP
  1603. ;
  1604. ; Outputs : DX - paras available
  1605. ;=========================================================================
  1606. Calc_Memory_Avail proc near ;an000; dms;
  1607. push ds ;save ds for size calc
  1608. push cx ;an000; dms;
  1609. push di ;an000; dms;
  1610. mov ds,cs:[org_ds]
  1611. MOV CX,DS:[2]
  1612. MOV DI,CS
  1613. SUB CX,DI
  1614. mov dx,cx ;an000; dms;put paras in DX
  1615. pop di ;an000; dms;
  1616. pop cx ;an000; dms;
  1617. pop ds ;an000; dms;
  1618. ret ;an000; dms;
  1619. Calc_Memory_Avail endp ;an000; dms;
  1620. ;=========================================================================
  1621. ; EA_Fail_Exit : This routine tells the user that there was
  1622. ; Insufficient memory and exits EDLIN.
  1623. ;
  1624. ; Inputs : MemFul_Ptr - "Insufficient memory"
  1625. ;
  1626. ; Outputs : message
  1627. ;=========================================================================
  1628. EA_Fail_Exit proc near ;an000; dms;
  1629. mov dx,offset dg:MemFul_Ptr ;an000; dms;"Insufficient
  1630. push cs ;an000; dms;xchange ds/cs
  1631. pop ds ;an000; dms;
  1632. ; memory"
  1633. call Std_Printf ;an000; dms;print message
  1634. mov ah,exit ;an000; dms;exit
  1635. xor al,al ;an000; dms;clear al
  1636. int 21h ;an000; dms;
  1637. ret ;an000; dms;
  1638. EA_Fail_Exit endp ;an000; dms;
  1639. CODE ENDS
  1640. END EDLIN
  1641.