home *** CD-ROM | disk | FTP | other *** search
- ;
- ; GRDP
- ;
- ; Copyright(c) LADsoft
- ;
- ; David Lindauer, camille@bluegrass.net
- ;
- ;
- ; HISTORY.ASM
- ;
- ; Function: Handle command line history
- ;
- ;MASM MODE
- .MODEL SMALL
- .386
- HISTSIZE EQU 1024 ; MUST be longer than longest command line!!!!
- ; but shorter than 32K
-
- include eprints.inc
- include einput.inc
- include emtrap.inc
- include ebreaks.inc
- include eloader.inc
- include edos.inc
- include eoptions.inc
- include eexec.inc
- include ememory.inc
- include elogging.inc
-
- PUBLIC CheckHistory, EnterHistory, LoadHistory, histoff,histon
- .data
- oldhistory db 0 ;to keep track of when history opt changes
- db 0 ; safety net for pushing value
- histlen dw 0 ;length of history segment
- histseg dw 0 ;history segment itself
- histpos dw 0 ;position in history segment
- nonext db 0 ; flag to not do first find next after new
- ; command entered
- .code
- histonm db 13,10,"History enabled",0
- histoffm db 13,10,"History disabled",0
- histerrm db 13,10,"No mem for history",0
- histmsg db " (History access)",0
- ;
- ; turn history off temporarily
- ;
- histoff proc
- mov ax,word ptr [oldhistory]
- xchg ax,[esp]
- mov [oldhistory],0
- jmp ax
- histoff endp
- ;
- ; turn history back on
- ;
- histon proc
- pop ax
- pop word ptr [oldhistory]
- jmp ax
- histon endp
-
- ; log that we are doing a history access
- ;
- CommandToLog PROC
- push di ; save hist buffer index
- sub si,offset inputbuffer ; get length of input
- mov cx,si ; this many backspaces
- jcxz nobkspc
- clrlp:
- mov ah,2 ; we are bypassing the logger
- ; for this, in a moment we will
- ; log a message saying we did this
- mov dl,8
- int 21h ;
- mov dl,' '
- int 21h ;
- mov dl,8
- int 21h ;
- loop clrlp ;
- nobkspc:
- mov bx,offset histmsg ; now log a message saying we
- cllp: ; did this
- mov al,cs:[bx]
- or al,al
- jz clnd
- inc bx
- call LogToFile
- jmp cllp
- clnd:
- pop si ; retreive hist buffer index
- push si
- cllp2:
- lods byte ptr es:[si] ; play out the new string
- or al,al
- jz clnd2
- mov dl,al
- call PutChar
- jmp cllp2
- clnd2:
- pop di
- ret
- CommandToLog ENDP
- ;
- ; go back one history line
- ;
- findprev proc
- mov di,[histpos] ; start here
- or di,di ; check if here is beginning
- jnz prevnowrap
- add di,[histlen] ; yes,start at end
-
- prevnowrap:
- dec di ; point back one char
- or di,di
- jle zerprev ; get out if past zero
- test byte ptr es:[di-1],0ffh ; check for null terminator
- jnz prevnowrap ; loop if not
- mov [histpos],di ; else exit with pointer
- ret
-
- zerprev:
- sub di,di ; zero pointer
- mov [histpos],di
- ret
- findprev endp
- ;
- ; go forward one history line
- ;
- findnext proc
- mov di,[histpos] ; start here
- test [nonext],1
- jnz nofindnext
- fnlp:
- inc di ; inc di
- cmp di,[histlen] ; see if past end
- jae zernext ; yes, zero
- test byte ptr es:[di-1],0ffh ; no, test for null term
- jnz fnlp ; loop until found
- mov [histpos],di ; exit with pointer
- ret
- zernext:
- sub di,di ;
- mov [histpos],di
- ret
- nofindnext:
- mov [nonext],0
- ret
- findnext endp
- ;
- ; compare two strings
- ;
- compare1 proc
- jcxz matches
- push cx
- push si
- push di
- repe cmpsb
- pop di
- pop si
- pop cx
- ret
- matches:
- sub ax,ax
- ret
- compare1 endp
- ;
- ; search to see if in history list
- ;
- search1 proc
- push es
- mov es,[histseg]
- sub di,di
- mov [histpos],di
- lp:
- call stringsize
- mov cx,ax
- dec cx
- push si
- call compare1
- pop si
- jz founds
- call findnext
- or di,di
- jnz lp
- pop es
- stc
- ret
- founds:
- pop es
- clc
- ret
- search1 endp
- ;
- ; find the size of a string, including null terminator
- ;
- stringsize proc
- push di
- push cx
- mov cx,-1
- sub al,al
- repne scasb
- not cx
- mov ax,cx
- pop cx
- pop di
- ret
- stringsize endp
- ;
- ; string copy back to main buffer
- ;
- copystring proc
- lodsb
- or al,al
- jz csend
- stosb
- jmp copystring
- csend:
- ret
- copystring endp
-
-
- CheckHistory PROC
- push di
- push si
- push es
- test [oldhistory],1 ;history on?
- jz okcheck
- test [histlen],-1 ; anything in history buf?
- jz okcheck
- mov cx,si ; calculate length of input
- sub cx,di
- mov si,di
- cmp ax,3d00h ; F3 key
- jz dof3
- cmp ax,5000h ; down arrow
- jz up
- cmp ax,4800h ; up arrow
- clc
- jnz okcheck
- down:
- mov es,[histseg] ; down arr, load stuf
- mov di,[histpos]
- call findprev ; back one
- jmp found
- dof3:
- mov es,[histseg]
- sub di,di ; F3, just go to last item
- mov [histpos],di
- call findprev
- jmp found
- up:
- mov es,[histseg] ; up arr, load stuff
- mov di,[histpos]
- call findnext ; forward one
- jmp found
- found:
- call CommandToLog ; output the command
- pop es ; found, swap seg regs
- push es
- push ds
- mov ds,[histseg]
- mov si,di ; put string in input buffer
- mov di,offset inputbuffer
- call copystring
- pop ds
- pop es
- pop si
- add sp,2
- stc
- ret
- nokcheck:
- stc
- okcheck:
- pop es
- pop si
- pop di
- ret
-
- CheckHistory ENDP
-
- ;
- ; add a new line to the history segment
- ;
- EnterHistory PROC
- test [oldhistory],1 ; history on ?
- jz noenter
- mov cx,di ; yes, any chars besides CR?
- sub cx,si
- cmp cx,1
- jbe noenter ; no, get out
- push di ; is in hist list?
- push cx
- push [histpos]
- call search1
- pop [histpos]
- pop cx
- pop di
- jnc noenter ; yes, don't put again
- push es
- push si
- mov es,[histseg] ; ES = hist segment
- ehsl:
- sub di,di ; di = pointer to first string
- mov ax,HISTSIZE ; See if enough room for new string
- sub ax,[histlen]
- sub ax,cx
- jnc enoughroom ; yes, go insert new string
- push cx ; no, get size of first string
- call stringsize
- mov cx,HISTSIZE ; count to move = seg size - string size
- sub cx,ax
- mov si,di
- add si,ax ; SI = second string
- push ds
- mov ds,[histseg]
- rep movsb ; cancel out first string
- pop ds
- sub [histlen],ax
- pop cx
- jmp ehsl ; loop
- enoughroom:
- mov di,[histlen] ; add new length to hist seg
- pop si
- push si
- push di
- add [histlen],cx
- rep movsb ; concat new string
- mov byte ptr es:[di-1],0 ; null terminator
- pop di
- pop si
- pop es
- mov [histpos],0 ; pos = 0...
- noenter:
- ret
- EnterHistory ENDP
- ;
- ; turn history on or off
- ;
- LoadHistory PROC
- sub ah,ah
- mov al,[opthist] ; see if history flag changed
- cmp al,[oldhistory]
- jz nochange ; get out if not
- call KillFiles ; else clear mem state to allow
- call ReleaseMemory ; the change
- test [opthist],0ffh ; turning on?
- jnz doload ; yes, turn on
- push es
- mov es,[histseg] ; else unload history seg
- mov ah,49h
- int 21h
- mov [oldhistory],0 ; flag off
- pop es
- mov bx,offset histoffm ; history off message
- jmp reload
- doload:
- mov bx,HISTSIZE SHR 4 ; load history seg
- mov ax,4800h
- int 21h
- mov bx, offset histerrm
- mov [opthist],0 ; assume it didn't succeed
- jc reload
- mov [oldhistory],1 ; turn on history
- mov [opthist],1
- mov [histseg],ax ; init the vars
- mov [histlen],0
- mov [histpos],0
- mov [nonext],1
- mov bx, offset histonm ; history on message
- reload:
- call olMessage
- mov si,offset grdbname ; reload empty program
- call MakeEmptyProg
- sub ax,ax
- test [loadfile],0ffh
- jz nochange
- call LoadProgram ; reload user program
- lahf
- nochange:
- ret
- LoadHistory ENDP
-
- end