procedure $STD_CON_STRING_INPUT,NEAR ;System call 10 ASSUME DS:NOTHING,ES:NOTHING ; Inputs: ; DS:DX Point to an input buffer ; Function: ; Fill buffer from console input until CR ; Returns: ; None MOV AX,SS MOV ES,AX MOV SI,DX XOR CH,CH LODSW OR AL,AL retz ;Buffer is 0 length!!? MOV BL,AH ;Init template counter MOV BH,CH ;Init template counter CMP AL,BL JBE NOEDIT ;If length of buffer inconsistent with contents CMP BYTE PTR [BX+SI],c_CR JZ EDITON ;If CR correctly placed EDIT is OK NOEDIT: MOV BL,CH ;Reset buffer EDITON: MOV DL,AL DEC DX ;DL is # of bytes we can put in the buffer NEWLIN: MOV AL,[CARPOS] MOV [STARTPOS],AL ;Remember position in raw buffer PUSH SI MOV DI,OFFSET DOSGROUP:INBUF ;Build the new line here MOV [INSMODE],CH ;Insert mode off MOV BH,CH ;No chars from template yet MOV DH,CH ;No chars to new line yet invoke $STD_CON_INPUT_NO_ECHO ;Get first char CMP AL,c_LF ;Linefeed JNZ GOTCH ;Filter out LF so < works entry GETCH invoke $STD_CON_INPUT_NO_ECHO GOTCH: CMP AL,"F"-"@" ;Ignore ^F JZ GETCH CMP AL,[ESCCHAR] JZ ESC CMP AL,c_DEL JZ BACKSPJ CMP AL,c_BS JZ BACKSPJ CMP AL,c_CR JZ ENDLIN CMP AL,c_LF JZ PHYCRLF CMP AL,CANCEL JZ KILNEW SAVCH: CMP DH,DL JAE BUFFUL ;No room STOSB INC DH ;Got a char invoke BUFOUT ;Print control chars nicely CMP BYTE PTR [INSMODE],0 JNZ GETCH ;In insert mode, get more chars CMP BH,BL JAE GETCH ;We are out of chars in template INC SI ;Skip to next char in template INC BH JMP SHORT GETCH BACKSPJ: JMP SHORT BACKSP BUFFUL: MOV AL,7 ;Bell invoke OUT JMP SHORT GETCH ESC: transfer OEMFunctionKey ENDLIN: STOSB ;Put the CR in the buffer invoke OUT ;Echo it POP DI ;Get start of buffer MOV [DI-1],DH ;Tell user how many bytes INC DH ;DH is length including CR COPYNEW: MOV BP,ES ;XCHG ES,DS MOV BX,DS MOV ES,BX MOV DS,BP MOV SI,OFFSET DOSGROUP:INBUF MOV CL,DH REP MOVSB ;Copy final line to user buffer return ;All done ;Output a CRLF entry CRLF MOV AL,c_CR invoke OUT MOV AL,c_LF JMP OUT ;Output a CRLF which is not terminate buffer PHYCRLF: invoke CRLF JMP GETCH ;Zap the line without zapping the template entry KILNEW MOV AL,"\" invoke OUT ;Print the CANCEL indicator POP SI ;Remember start of edit buffer PUTNEW: invoke CRLF ;Go to next line on screen MOV AL,[STARTPOS] invoke TAB ;Tab over JMP NEWLIN ;Start over again ;Back up one char entry BACKSP OR DH,DH JZ OLDBAK ;No chars in line, do nothing to line CALL BACKUP ;Do the backup MOV AL,ES:[DI] ;Get the deleted char CMP AL," " JAE OLDBAK ;Was a normal char CMP AL,c_HT JZ BAKTAB ;Was a tab, fix up users display CALL BACKMES ;Was a control char, zap the '^' OLDBAK: CMP BYTE PTR [INSMODE],0 JNZ GETCH1 ;In insert mode, get more chars OR BH,BH JZ GETCH1 ;Not advanced in template, stay where we are DEC BH ;Go back in template DEC SI GETCH1: JMP GETCH BAKTAB: PUSH DI DEC DI ;Back up one char STD ;Go backward MOV CL,DH ;Number of chars currently in line MOV AL," " PUSH BX MOV BL,7 ;Max JCXZ FIGTAB ;At start, do nothing FNDPOS: SCASB ;Look back JNA CHKCNT CMP BYTE PTR ES:[DI+1],9 JZ HAVTAB ;Found a tab DEC BL ;Back one char if non tab control char CHKCNT: LOOP FNDPOS FIGTAB: SUB BL,[STARTPOS] HAVTAB: SUB BL,DH ADD CL,BL AND CL,7 ;CX has correct number to erase CLD ;Back to normal POP BX POP DI JZ OLDBAK ;Nothing to erase TABBAK: invoke BACKMES LOOP TABBAK ;Erase correct number of chars JMP SHORT OLDBAK BACKUP: DEC DH ;Back up in line DEC DI BACKMES: MOV AL,c_BS ;Backspace invoke OUT MOV AL," " ;Erase invoke OUT MOV AL,c_BS ;Backspace JMP OUT ;Done ;User really wants an ESC character in his line entry TwoEsc MOV AL,[ESCCHAR] JMP SAVCH ;Copy the rest of the template entry COPYLIN MOV CL,BL ;Total size of template SUB CL,BH ;Minus position in template, is number to move JMP SHORT COPYEACH entry CopyStr invoke FINDOLD ;Find the char JMP SHORT COPYEACH ;Copy up to it ;Copy one char from template to line entry COPYONE MOV CL,1 ;Copy CX chars from template to line COPYEACH: MOV BYTE PTR [INSMODE],0 ;All copies turn off insert mode CMP DH,DL JZ GETCH2 ;At end of line, can't do anything CMP BH,BL JZ GETCH2 ;At end of template, can't do anything LODSB STOSB invoke BUFOUT INC BH ;Ahead in template INC DH ;Ahead in line LOOP COPYEACH GETCH2: JMP GETCH ;Skip one char in template entry SKIPONE CMP BH,BL JZ GETCH2 ;At end of template INC BH ;Ahead in template INC SI JMP GETCH entry SKIPSTR invoke FINDOLD ;Find out how far to go ADD SI,CX ;Go there ADD BH,CL JMP GETCH ;Get the next user char, and look ahead in template for a match ;CX indicates how many chars to skip to get there on output ;NOTE: WARNING: If the operation cannot be done, the return ; address is popped off and a jump to GETCH is taken. ; Make sure nothing extra on stack when this routine ; is called!!! (no PUSHes before calling it). FINDOLD: invoke $STD_CON_INPUT_NO_ECHO CMP AL,[ESCCHAR] ; did he type a function key? JNZ FindSetup ; no, set up for scan invoke $STD_CON_INPUT_NO_ECHO ; eat next char JMP NotFnd ; go try again FindSetup: MOV CL,BL SUB CL,BH ;CX is number of chars to end of template JZ NOTFND ;At end of template DEC CX ;Cannot point past end, limit search JZ NOTFND ;If only one char in template, forget it PUSH ES PUSH DS POP ES PUSH DI MOV DI,SI ;Template to ES:DI INC DI REPNE SCASB ;Look POP DI POP ES JNZ NOTFND ;Didn't find the char NOT CL ;Turn how far to go into how far we went ADD CL,BL ;Add size of template SUB CL,BH ;Subtract current pos, result distance to skip return NOTFND: POP BP ;Chuck return address JMP GETCH entry REEDIT MOV AL,"@" ;Output re-edit character invoke OUT POP DI PUSH DI PUSH ES PUSH DS invoke COPYNEW ;Copy current line into template POP DS POP ES POP SI MOV BL,DH ;Size of line is new size template JMP PUTNEW ;Start over again entry EXITINS entry ENTERINS NOT BYTE PTR [INSMODE] JMP GETCH ;Put a real live ^Z in the buffer (embedded) entry CTRLZ MOV AL,"Z"-"@" JMP SAVCH $STD_CON_STRING_INPUT ENDP