     1                                  ;    File              : $HISTORY.ASM$
     2                                  ;
     3                                  ;    Description       :
     4                                  ;
     5                                  ;    Original Author   : DIGITAL RESEARCH
     6                                  ;
     7                                  ;    Last Edited By    : $CALDERA$
     8                                  ;
     9                                  ;-----------------------------------------------------------------------;
    10                                  ;    Copyright Work of Caldera, Inc. All Rights Reserved.
    11                                  ;      
    12                                  ;    THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
    13                                  ;    PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
    14                                  ;    ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
    15                                  ;    WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
    16                                  ;    THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
    17                                  ;    HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
    18                                  ;    AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
    19                                  ;    AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
    20                                  ;    COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
    21                                  ;    CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
    22                                  ;    TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
    23                                  ;    CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
    24                                  ;    AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
    25                                  ;    CIVIL LIABILITY.
    26                                  ;-----------------------------------------------------------------------;
    27                                  ;
    28                                  ;    *** Current Edit History ***
    29                                  ;    *** End of Current Edit History ***
    30                                  ;
    31                                  ;    $Log$
    32                                  ;    ENDLOG
    33                                  ;
    34                                  ; 	DOSPLUS Command Line Editor Routines
    35                                  ;
    36                                  
    37                                  group PCMCODE PCM_HISTORY
    38                                  group PCMDATA PCMODE_DATA FDOS_DSEG GLOBAL_DATA
    39                                  
    40                                  ASSUME DS:PCMDATA
    41                                  
    42                                  	[list -]
    48                                  
    49                                  
    50                                  section PCM_HISTORY public align=2 class=CODE
    51                                  
    52                                  	public	init_history, save_history
    53                                  	public	del_history_buffers, del_cur_history_buffer
    54                                  	public	prev_cmd, next_cmd, match_cmd, search_cmd
    55                                  	public	prev_word, next_word, match_word
    56                                  	public	goto_eol
    57                                  	public	del_bol
    58                                  	public	deln_word
    59                                  
    60                                  	extrn	next_char:near
    61                                  	extrn	save_line:near
    62                                  	extrn	space_out:near
    63                                  	extrn	bs_out:near
    64                                  	extrn	goto_bol:near
    65                                  	extrn	del_eol:near
    66                                  	extrn	del_line:near
    67                                  	extrn	char_info:near
    68                                  	extrn	put_string:near
    69                                  	extrn	prev_w20:near
    70                                  	extrn	deln_w10:near
    71                                  
    72                                  init_history:
    73                                  ;------------
    74                                  ; On Entry:
    75                                  ;	SS:BP -> history structure
    76                                  ; On Exit:
    77                                  ;	SS:SP filled in with appropriate history buffer
    78                                  ;	Preserve DX
    79                                  ;
    80 00000000 1E                      	push	ds
    81 00000001 06                      	push	es
    82 00000002 16                      	push	ss
    83 00000003 07                      	pop	es
    84 00000004 8D7EE4                  	lea	di,[RL_HIST_SEG]		; point at history buffer variables
    85 00000007 BE[0000]                	mov	si,offset histbuf1	; assume root buffer
    86 0000000A F746F48000              	test	word [RL_FLAGS],RLF_INROOT	; root task after all?
    87 0000000F 7503                    	 jnz	init_history10		; if not we need to switch
    88 00000011 BE[0000]                	mov	si,offset histbuf2	;  application buffer
    89                                  init_history10:
    90 00000014 A5                      	movsw				; copy the seg
    91 00000015 AD                      	lodsw				; get overall length
    92 00000016 83E804                  	sub	ax,2*2		; last two words contain pointers
    93 00000019 AB                      	stosw				; save the working length
    94 0000001A 96                      	xchg	ax,si			; SI -> saved buffer positions
    95 0000001B 8E5EE4                  	mov	ds,[RL_HIST_SEG]		;  in the buffer segment
    96 0000001E A5                      	movsw				; update save and
    97 0000001F A5                      	movsw				;  recall positions
    98 00000020 07                      	pop	es
    99 00000021 1F                      	pop	ds
   100 00000022 C3                      	ret
   101                                  
   102                                  
   103                                  save_history:
   104                                  ;------------
   105                                  ; We are exiting from READLINE - if line has been modified save the
   106                                  ; current line and update our pointers.
   107                                  ;
   108 00000023 85D2                    	test	dx,dx			; skip update of sav/recall pointers
   109 00000025 7421                    	 jz	save_history30		;  if empty line
   110 00000027 E83700                  	call	save_current		; save away current command line
   111 0000002A 8B7EE8                  	mov	di,[RL_HIST_SAVE]		; start with the old one
   112 0000002D E89D01                  	call	find_current_hist	; wrap it if we need to
   113 00000030 E86501                  	call	find_next_null		; find end of "new" command
   114 00000033 47                      	inc	di			; onto next character
   115 00000034 3B7EE6                  	cmp	di,[RL_HIST_SIZE]		; do we need to wrap ?
   116 00000037 7202                    	 jb	save_history10
   117 00000039 31FF                    	xor	di,di			; wrap the line
   118                                  save_history10:
   119 0000003B 897EE8                  	mov	[RL_HIST_SAVE],di		; update "save" pointer
   120 0000003E F746F42000              	test	word [RL_FLAGS],RLF_DIRTY	; if a line has been changed we'd
   121 00000043 7403                    	 jz	save_history30		;  better update "recall" pointer
   122 00000045 897EEA                  	mov	[RL_HIST_RECL],di		;  too
   123                                  save_history30:
   124 00000048 1E                      	push	ds
   125 00000049 06                      	push	es
   126 0000004A 16                      	push 	ss
   127 0000004B 1F                      	pop 	ds
   128 0000004C 8D76E8                  	lea	si,[RL_HIST_SAVE]		; point at history buffer variables
   129 0000004F 8E46E4                  	mov	es,[RL_HIST_SEG]
   130 00000052 8B7EE6                  	mov	di,[RL_HIST_SIZE]
   131 00000055 A5                      	movsw				; save the "save" pointer
   132 00000056 A5                      	movsw				;  and the "recall" one
   133 00000057 07                      	pop	es
   134 00000058 1F                      	pop	ds
   135 00000059 C3                      	ret
   136                                  
   137                                  save_current_if_dirty:
   138                                  ;---------------------
   139 0000005A F746F42000              	test	word [RL_FLAGS],RLF_DIRTY	; if data is dirty (ie. user modified)
   140 0000005F 7436                    	 jz	save_current20		;  then save it
   141                                  save_current:
   142                                  ;------------
   143                                  ; Copy current buffer contents to next free location in history buffer
   144                                  ;
   145 00000061 56                      	push	si
   146 00000062 57                      	push	di
   147 00000063 52                      	push	dx
   148 00000064 3B56E6                  	cmp	dx,[RL_HIST_SIZE]		; is history buffer big enough ?
   149 00000067 732B                    	 jae	save_current10		;  no, skip saving this line
   150 00000069 E81001                  	call	find_free_hist		; Find the next bit of space
   151 0000006C 59                      	pop 	cx
   152 0000006D 51                      	push 	cx			; CX = chars to save
   153 0000006E E324                    	 jcxz	save_current10		; none, forget about it
   154 00000070 1E                      	push	ds
   155 00000071 06                      	push	es
   156 00000072 C576F8                  	lds	si,[RL_BUFPTR]
   157 00000075 8E46E4                  	mov	es,[RL_HIST_SEG]
   158 00000078 F3A4                    	rep	movsb			; and save the data.  
   159 0000007A 31C0                    	xor	ax,ax			; Null terminate it.
   160 0000007C AA                      	stosb
   161 0000007D 07                      	pop	es
   162 0000007E 1F                      	pop	ds
   163 0000007F 57                      	push	di
   164 00000080 E81501                  	call	find_next_null		; Find the end of the entry we just
   165 00000083 89F9                    	mov	cx,di			;  overwrote - if any remains zap it
   166 00000085 5F                      	pop	di
   167 00000086 FC                      	cld
   168 00000087 31C0                    	xor	ax,ax			; Null terminate this entry
   169 00000089 29F9                    	sub	cx,di			; Figure out number of zeros to write
   170 0000008B 7607                    	 jbe	save_current10
   171 0000008D 06                      	push	es
   172 0000008E 8E46E4                  	mov	es,[RL_HIST_SEG]
   173 00000091 F3AA                    	rep	stosb			; and pad to the next entry	
   174 00000093 07                      	pop	es
   175                                  save_current10:
   176 00000094 5A                      	pop	dx
   177 00000095 5F                      	pop	di
   178 00000096 5E                      	pop	si
   179                                  save_current20:
   180 00000097 C3                      	ret
   181                                  
   182                                  
   183                                  ;
   184                                  ; Here is the code to deal with history buffers
   185                                  ;
   186                                  ; match_cmd	Does a string search based on what the user has typed so far
   187                                  ; search_cmd	Matches string, but doesn't change match state
   188                                  ; prev_cmd	Retrieves the previous command from the history buffer
   189                                  ; next_cmd 	     "     "  next       "      "     "    "      "
   190                                  ;
   191                                  match_cmd:
   192 00000098 A0[0000]                	mov	al,[@hist_flg]		; is matching enabled ?
   193 0000009B 83E008                  	and	ax,RLF_MATCH
   194 0000009E 7408                    	 jz	search_cmd		; no, always match
   195 000000A0 3146F4                  	xor	[RL_FLAGS],ax		; toggle match bit
   196 000000A3 8546F4                  	test	[RL_FLAGS],ax		; turning matching off ?
   197 000000A6 7458                    	 jz	match30			;  then just exit
   198                                  search_cmd:
   199 000000A8 8976EC                  	mov	[RL_SAVPOS],si		; any chars to save ?
   200 000000AB 85F6                    	test	si,si
   201 000000AD 7452                    	 jz	prev_cmd		; blank line - just get previous
   202 000000AF E8A8FF                  	call	save_current_if_dirty	; save current line if it needs saving
   203 000000B2 56                      	push	si			; save current offset in line
   204 000000B3 57                      	push	di
   205 000000B4 52                      	push	dx			; Save index to end of current line
   206 000000B5 89F2                    	mov	dx,si			; discard rest of line if no match
   207 000000B7 8B7EEA                  	mov	di,[RL_HIST_RECL]		; Point to the current entry
   208                                  match_loop:
   209 000000BA E8EB00                  	call	find_prev_hist		; DI-> previous cmd in buffer
   210 000000BD 57                      	push	di			; save this command position
   211 000000BE 8B7EEA                  	mov	di,[RL_HIST_RECL]		; get starting position
   212 000000C1 E80901                  	call	find_current_hist	;  handle any wrapping
   213 000000C4 5E                      	pop	si			; recover previous command
   214 000000C5 39F7                    	cmp	di,si			; have we been all round ?
   215 000000C7 7414                    	 je	match_error		; YES - We've looped so no match found
   216 000000C9 1E                      	push	ds
   217 000000CA 56                      	push	si			; save this entry
   218 000000CB 8E5EE4                  	mov	ds,[RL_HIST_SEG]
   219 000000CE 8B7EF8                  	mov	di,[RL_BUFOFF]		; ES:DI -> match string
   220 000000D1 8B4EEC                  	mov	cx,[RL_SAVPOS]		; try to match CX characters
   221 000000D4 F3A6                    	repe	cmpsb
   222 000000D6 5F                      	pop	di			; recover this entry
   223 000000D7 1F                      	pop	ds
   224 000000D8 75E0                    	 jne	match_loop		; try again if we didn't match
   225 000000DA E86C00                  	call	copy_from_hist		; if it did match copy it
   226                                  match_error:
   227 000000DD 59                      	pop	cx			; Get end of displayed line
   228 000000DE 5F                      	pop	di			; user's buffer
   229 000000DF 5E                      	pop	si
   230 000000E0 56                      	push	si			; save current position in lines
   231 000000E1 E8(0000)                	call	space_out		; Rub the displayed line out
   232 000000E4 E8(0000)                	call	bs_out			; And backspace to it's start
   233 000000E7 E84E00                  	call	goto_eol		; display the line
   234 000000EA E8(0000)                	call	goto_bol		; Move cursor to begining
   235 000000ED 59                      	pop	cx			; CX = end of matched portion
   236 000000EE 894EEC                  	mov	[RL_SAVPOS],cx		; CX = Current position in command
   237 000000F1 E307                    	 jcxz	match20
   238                                  match10:				; Move cursor forward to current
   239 000000F3 51                      	push	cx			;  position
   240 000000F4 E8(0000)                	call	next_char		; next_char destroys our loop count
   241 000000F7 59                      	pop	cx			;  so keep it
   242 000000F8 E2F9                    	loop	match10
   243                                  match20:
   244 000000FA 8B4EEE                  	mov	cx,[RL_SAVMAX]		; we can't copy any more
   245 000000FD 894EEC                  	mov	[RL_SAVPOS],cx
   246                                  match30:
   247 00000100 C3                      	ret
   248                                  
   249                                  
   250                                  prev_cmd:
   251                                  ; Get the previous command from the buffer
   252 00000101 F746F41000              	test	word [RL_FLAGS],RLF_RECALLED	; is this the 1st recall ?
   253 00000106 750D                    	 jnz	prev_cmd10
   254 00000108 51                      	push	cx
   255 00000109 57                      	push	di
   256 0000010A 8B7EE8                  	mov	di,[RL_HIST_SAVE]		; get existing "save" ptr
   257 0000010D E8BD00                  	call	find_current_hist	; wrap it if we need to
   258 00000110 897EEA                  	mov	[RL_HIST_RECL],di		;  and update "recall" pointer
   259 00000113 5F                      	pop	di
   260 00000114 59                      	pop	cx
   261                                  prev_cmd10:
   262 00000115 E842FF                  	call	save_current_if_dirty	; save current line if it needs saving
   263 00000118 E8(0000)                	call	del_line		;  then delete it
   264 0000011B 56                      	push	si
   265 0000011C 57                      	push	di
   266 0000011D 8B7EEA                  	mov	di,[RL_HIST_RECL]		; point to the current entry
   267 00000120 E88500                  	call	find_prev_hist		; DI -> previous entry
   268 00000123 EB0E                    	jmp	found_cmd		; now go and copy it to the user buffer
   269                                  
   270                                  next_cmd:
   271                                  ; Get the next command from the buffer
   272 00000125 E832FF                  	call	save_current_if_dirty	; save current line if it needs saving
   273 00000128 E8(0000)                	call	del_line		;  then delete it
   274 0000012B 56                      	push	si
   275 0000012C 57                      	push	di
   276 0000012D 8B7EEA                  	mov	di,[RL_HIST_RECL]		; point to the current entry
   277 00000130 E89400                  	call	find_next_hist		; DI -> next entry
   278                                  ;	jmp	found_cmd		; now go and copy it to the user buffer
   279                                  
   280                                  found_cmd:
   281 00000133 E81300                  	call	copy_from_hist		; Copy from history to user buffer
   282 00000136 5F                      	pop	di
   283 00000137 5E                      	pop	si
   284                                  ;	jmp	goto_eol		; Display new line.
   285                                  
   286                                  goto_eol:				; Move the cursor to the end of the
   287 00000138 89D1                    	mov 	cx,dx
   288 0000013A 29F1                    	sub 	cx,si			; displayed line
   289 0000013C E30A                    	 jcxz	goto_e10		; Already at the EOL
   290 0000013E 0376F8                  	add	si,[RL_BUFOFF]		; Get the Offset in the buffer
   291 00000141 E8(0000)                	call	put_string		; Output the sub_string
   292 00000144 01CF                    	add	di,cx			; Update the local variables
   293 00000146 89D6                    	mov	si,dx			; and return
   294                                  goto_e10:
   295 00000148 C3                      	ret
   296                                  
   297                                  ; DI-> Current entry in history buffer
   298                                  ;
   299                                  copy_from_hist:
   300 00000149 834EF410                	or	word [RL_FLAGS],RLF_RECALLED	; remember we have recalled something
   301 0000014D 8366F4DF                	and	word [RL_FLAGS],~ RLF_DIRTY	; this entry is already in buffers
   302 00000151 897EEA                  	mov	[RL_HIST_RECL],di		; update pointer for next time
   303 00000154 E84100                  	call	find_next_null		; how big is this entry ?
   304 00000157 89F9                    	mov	cx,di
   305 00000159 8B76EA                  	mov	si,[RL_HIST_RECL]
   306 0000015C 29F1                    	sub	cx,si			; (CX-SI)=No of bytes to copy
   307 0000015E 3B4EF2                  	cmp	cx,[RL_MAXLEN]		; is the line bigger than our buffer ?
   308 00000161 7203                    	 jb	copy_from_hist1		; if so we want to clip it
   309 00000163 8B4EF2                  	mov	cx,[RL_MAXLEN]		; to the maximum possible value
   310                                  copy_from_hist1:
   311 00000166 89CA                    	mov	dx,cx
   312 00000168 1E                      	push	ds
   313 00000169 8E5EE4                  	mov	ds,[RL_HIST_SEG]
   314 0000016C 8B7EF8                  	mov	di,[RL_BUFOFF]
   315 0000016F F3A4                    	rep	movsb			; copy to line buffer
   316 00000171 1F                      	pop	ds
   317 00000172 E8(0000)                	call	save_line		; save the line
   318 00000175 8B4EEE                  	mov	cx,[RL_SAVMAX]		; we can't copy any more
   319 00000178 894EEC                  	mov	[RL_SAVPOS],cx
   320 0000017B C3                      	ret
   321                                  
   322                                  ; Some primitives for history buffer handling:
   323                                  ;
   324                                  ; find_free_hist	Find the next free entry in the history buffer
   325                                  ; find_next_null	Finds the end of the current entry
   326                                  ; find_prev_hist	Finds the start of the previous entry
   327                                  ; find_next_hist	Finds the start of the next entry
   328                                  ; find_current_hist	Finds the start of current entry
   329                                  
   330                                  ;
   331                                  ; Make DI-> next entry of sufficient length for the current cmd buffer
   332                                  ; If we can't fit at the end zero the remainder of the buffer then wrap
   333                                  ; back to the start.
   334                                  ;
   335                                  
   336                                  find_free_hist:
   337 0000017C 8B7EE8                  	mov	di,[RL_HIST_SAVE]		; Point at current last entry
   338 0000017F 57                      	push	di			; Will DX bytes fit?
   339 00000180 01D7                    	add	di,dx
   340 00000182 3B7EE6                  	cmp	di,[RL_HIST_SIZE]		; Did we run out of buffer?
   341 00000185 5F                      	pop	di
   342 00000186 720F                    	 jb	find_free_hist20
   343 00000188 31C0                    	xor	ax,ax			; doesn't fit, so zero to end of buffer
   344                                  find_free_hist10:
   345 0000018A 06                      	push	es
   346 0000018B 8E46E4                  	mov	es,[RL_HIST_SEG]
   347 0000018E AA                      	stosb				; keep on zeroing
   348 0000018F 07                      	pop	es
   349 00000190 3B7EE6                  	cmp	di,[RL_HIST_SIZE]
   350 00000193 72F5                    	 jb	find_free_hist10
   351 00000195 31FF                    	xor	di,di			; wrap back to start of history buffer
   352                                  find_free_hist20:
   353 00000197 C3                      	ret
   354                                  
   355                                  ; Entry DI-> entry in the history buffer
   356                                  ; Make DI-> next NULL in the history buffer ( end of current entry )
   357                                  ;
   358                                  find_next_null:
   359 00000198 8B4EE6                  	mov	cx,[RL_HIST_SIZE]
   360 0000019B 29F9                    	sub	cx,di			; Calc no of bytes left
   361 0000019D 31C0                    	xor	ax,ax			; Look for next terminator
   362 0000019F 06                      	push	es
   363 000001A0 8E46E4                  	mov	es,[RL_HIST_SEG]
   364 000001A3 F2AE                    	repnz	scasb	
   365 000001A5 4F                      	dec	di			; point at the NUL
   366 000001A6 07                      	pop	es
   367 000001A7 C3                      	ret
   368                                  
   369                                  ; Entry DI-> entry in the history buffer
   370                                  ; Make DI-> previous entry in the history buffer
   371                                  ; Preserve CX
   372                                  find_prev_hist:
   373 000001A8 E82200                  	call	find_current_hist	; handle any wrapping
   374 000001AB 89F8                    	mov	ax,di			; AX = entry we want previous for
   375                                  find_prev_hist10:
   376 000001AD 50                      	push	ax			; save current offset
   377 000001AE 57                      	push	di			; save initial offset
   378 000001AF 97                      	xchg	ax,di			; find next from here until
   379 000001B0 E81400                  	call	find_next_hist		;  we get back where we started
   380 000001B3 97                      	xchg	ax,di			; AX = current offset
   381 000001B4 5F                      	pop	di			; recover initial value
   382 000001B5 5B                      	pop	bx			; recover previous offset
   383 000001B6 39F8                    	cmp	ax,di			; have we wrapped yet ?
   384 000001B8 740A                    	 je	find_prev_hist20	; yes, BX = previous entry
   385 000001BA 77F1                    	 ja	find_prev_hist10	; we are above target so continue
   386 000001BC 39FB                    	cmp	bx,di			; we are below target - if previous
   387 000001BE 73ED                    	 jae	find_prev_hist10	;  was above target we are OK
   388 000001C0 39D8                    	cmp	ax,bx			; if new below previous then we
   389 000001C2 73E9                    	 jnb	find_prev_hist10	;  have ERROR wrap, so stop
   390                                  find_prev_hist20:
   391 000001C4 89DF                    	mov	di,bx			; DI -> Previous entry
   392 000001C6 C3                      	ret
   393                                  
   394                                  find_next_hist:	
   395 000001C7 E80300                  	call	find_current_hist	; handle any wrapping
   396 000001CA E8CBFF                  	call	find_next_null		; point to end of current entry
   397                                  ;	jmp	find_current_hist	; handle any wrapping
   398                                  
   399                                  find_current_hist:
   400                                  ; This routine is complicated by the need to handle switchers, where
   401                                  ;  our buffers and pointers may get out of step
   402 000001CD 06                      	push	es
   403 000001CE 31C0                    	xor	ax,ax
   404 000001D0 8E46E4                  	mov	es,[RL_HIST_SEG]		; now work backwards to start of line
   405                                  find_current_hist10:
   406 000001D3 83FF01                  	cmp	di,1			; are we at the start of the buffer
   407 000001D6 7211                    	 jb	find_current_hist30	;  then don't wrap
   408 000001D8 FD                      	std
   409 000001D9 AE                      	scasb				; is previous char a NUL ?
   410 000001DA FC                      	cld				;  (it should be!)
   411 000001DB 75F6                    	 jne	find_current_hist10
   412 000001DD 47                      	inc	di			; ES:DI -> 1st char of line
   413                                  find_current_hist20:
   414 000001DE 8B4EE6                  	mov	cx,[RL_HIST_SIZE]
   415 000001E1 29F9                    	sub	cx,di			; CX= Remaining no: of bytes in buffer
   416 000001E3 7604                    	 jbe	find_current_hist30
   417 000001E5 F3AE                    	repe	scasb			; skip over zero's
   418 000001E7 7503                    	 jne	find_current_hist40
   419                                  find_current_hist30:
   420 000001E9 BF0100                  	mov	di,1			; wrap to start of buffer
   421                                  find_current_hist40:
   422 000001EC 4F                      	dec	di
   423 000001ED 07                      	pop	es
   424 000001EE C3                      	ret
   425                                  
   426                                  del_history_buffers:
   427                                  ;-------------------
   428                                  ; Delete contents of both history buffers
   429                                  ;
   430 000001EF A1[0000]                	mov	ax,[histbuf1]		; Segment of 1st history buffer
   431 000001F2 8B0E[0000]              	mov	cx,[histsiz1]		; End of 1st history buffer
   432 000001F6 E80F00                  	call	zap_buffer
   433 000001F9 A1[0000]                	mov	ax,[histbuf2]		; Segment of 2nd history buffer
   434 000001FC 8B0E[0000]              	mov	cx,[histsiz2]		; End of 2nd history buffer
   435 00000200 EB06                    	jmp	zap_buffer
   436                                  	
   437                                  del_cur_history_buffer:
   438                                  ;----------------------
   439                                  ; Delete contents of the current history buffer
   440                                  ;
   441 00000202 8B46E4                  	mov	ax,[RL_HIST_SEG]		; zero the current buffer
   442 00000205 8B4EE6                  	mov	cx,[RL_HIST_SIZE]
   443                                  zap_buffer:
   444 00000208 06                      	push	es			; zero fill CX bytes at AX:0
   445 00000209 57                      	push	di
   446 0000020A 8EC0                    	mov	es,ax
   447 0000020C 31C0                    	xor	ax,ax
   448 0000020E 8946EA                  	mov	[RL_HIST_RECL],ax
   449 00000211 8946E8                  	mov	[RL_HIST_SAVE],ax
   450 00000214 31FF                    	xor	di,di
   451 00000216 F3AA                    	rep	stosb			; zero fill the buffer
   452 00000218 5F                      	pop	di
   453 00000219 07                      	pop	es
   454 0000021A E8(0000)                	call	del_line		; then delete current line
   455 0000021D E9(0000)                	jmp	save_line
   456                                  
   457                                  
   458                                  next_word:
   459 00000220 89D1                    	mov	cx,dx			; Calculate the number of bytes
   460 00000222 29F1                    	sub	cx,si			; left to scan
   461 00000224 E314                    	jcxz	next_w10		; Skip if at the EOL
   462 00000226 56                      	push	si			; Save the current Index
   463 00000227 89FE                    	mov	si,di			; Scan from the current location
   464 00000229 E80F00                  	call	match_word		; Get the next word boundary
   465 0000022C 89F1                    	mov	cx,si
   466 0000022E 29F9                    	sub	cx,di			; Calculate the string length
   467 00000230 89FE                    	mov	si,di			; to be displayed from the current
   468 00000232 E8(0000)                	call	put_string		; location and output the data
   469 00000235 5E                      	pop	si
   470 00000236 01CE                    	add	si,cx			; Update the Index and Offset pointers
   471 00000238 01CF                    	add	di,cx
   472                                  next_w10:
   473 0000023A C3                      	ret
   474                                  
   475                                  ;
   476                                  ;	MATCH_WORD scans the buffer at ES:SI for word boundaries
   477                                  ;	and returns to the calling routine whenever it detects such
   478                                  ;	a boundary.
   479                                  ;
   480                                  ;	On Entry:	ES:SI	Buffer Address
   481                                  ;			CX	Maximum No of bytes to Scan
   482                                  ;
   483                                  ;	On Exit:	ES:SI	Next Word Boundary
   484                                  ;
   485                                  match_word:
   486 0000023B E8(0000)                	call	char_info
   487 0000023E F6C418                  	test	ah,CHAR_ALPHAN | CHAR_KANJI
   488 00000241 E0F8                    	loopnz	match_word		; scan the rest of the current word
   489 00000243 E314                    	 jcxz	match_w30		; end of word or kanji ?
   490                                  
   491 00000245 52                      	push	dx
   492                                  match_w10:
   493 00000246 89F2                    	mov	dx,si
   494 00000248 E8(0000)                	call	char_info
   495 0000024B F6C418                  	test	ah,CHAR_ALPHAN | CHAR_KANJI
   496 0000024E E1F6                    	loopz	match_w10
   497 00000250 7406                    	 jz	match_w20
   498 00000252 29D6                    	sub	si,dx			; Correct the count in CX
   499 00000254 01F1                    	add	cx,si			; and return the location of the
   500 00000256 89D6                    	mov	si,dx			; word boundary
   501                                  
   502                                  match_w20:
   503 00000258 5A                      	pop	dx
   504                                  match_w30:
   505 00000259 C3                      	ret
   506                                  
   507                                  prev_word:
   508 0000025A 89F1                    	mov 	cx,si
   509 0000025C E3FB                    	 jcxz 	match_w30		; Initialize the count
   510 0000025E 52                      	push 	dx
   511 0000025F 56                      	push 	si
   512 00000260 57                      	push 	di
   513 00000261 8B76F8                  	mov	si,[RL_BUFOFF]		; Scan from the begining of the buffer
   514 00000264 89F2                    	mov	dx,si			; keeping the last match in DX
   515                                  prev_w10:
   516 00000266 E8D2FF                  	call	match_word		; Find the next word boundary
   517 00000269 E304                    	jcxz	prev_w15		; Stop when we get to the current offset
   518 0000026B 89F2                    	mov	dx,si			; Save current location
   519 0000026D EBF7                    	jmp	prev_w10		; and repeat
   520                                  prev_w15:
   521 0000026F E9(0000)                	jmp	prev_w20
   522                                  
   523                                  del_bol:				; Delete to the begining of the line
   524 00000272 09F6                    	or 	si,si
   525 00000274 740C                    	 jz 	del_bol10		; Ignore if at the begining
   526 00000276 09D2                    	or 	dx,dx
   527 00000278 7408                    	 jz 	del_bol10		; Or the line is empty
   528 0000027A 57                      	push	di			; Save the current index
   529 0000027B E8(0000)                	call	goto_bol		; Move to the start of the line
   530 0000027E 59                      	pop	cx			; Restore the current offset
   531 0000027F E9(0000)                	jmp	deln_w10		; and jump to common code
   532                                  del_bol10:
   533 00000282 C3                      	ret
   534                                  
   535                                  deln_word:
   536 00000283 89D1                    	mov	cx,dx			; Calculate the number of bytes
   537 00000285 29F1                    	sub	cx,si			; left to scan
   538 00000287 E3F9                    	jcxz	del_bol10		; Skip if at the EOL
   539 00000289 56                      	push	si			; Save the current Index
   540 0000028A 89FE                    	mov	si,di			; Scan from the current location
   541 0000028C E8ACFF                  	call	match_word		; Get the next word boundary
   542 0000028F 89F1                    	mov	cx,si
   543 00000291 5E                      	pop	si
   544 00000292 E9(0000)                	jmp	deln_w10
   545                                  
   546                                  PCM_HISTORY	ends
   547                                  
   548                                  section PCMODE_DATA public align=2 class=DATA
   549                                  
   550                                  	extrn	@hist_flg:byte		; To select between histbufs 1 or 2
   551                                  
   552                                  PCMODE_DATA	ends
   553                                  
   554                                  section GLOBAL_DATA public align=2 class=DATA
   555                                  
   556                                  	extrn	histbuf1:word, histsiz1:word, histbuf2:word, histsiz2:word
   557                                  
   558                                  GLOBAL_DATA	ends
   559                                  
   560                                  	end
   561                                  
