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