From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/INC/PCINPUT.INC | 3794 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 3794 insertions(+) create mode 100644 v4.0/src/INC/PCINPUT.INC (limited to 'v4.0/src/INC/PCINPUT.INC') diff --git a/v4.0/src/INC/PCINPUT.INC b/v4.0/src/INC/PCINPUT.INC new file mode 100644 index 0000000..dc94520 --- /dev/null +++ b/v4.0/src/INC/PCINPUT.INC @@ -0,0 +1,3794 @@ +; +PAGE +;-----------------------------------------------------------------------------+ +; : +; Source...: PCINPUT.INC : +; Created..: 01-01-82 : +; Standards: 01-07-86 : +; Revised..: 11-17-87 : +; Version..: PC DOS : +; Called as: FAR, NEAR or INT : +; Public as: INPUT : +; : +;-----------------------------------------------------------------------------+ +; +PAGE +;-----------------------------------------------------------------------------+ +; : +; DEFAULT : +; : +; Performs the following functions: : +; : +; - Initializes pointers and counters : +; - Initializes input buffer with default value (from screen or strg) : +; - Set options and display input buffer as default on screen : +; - Display field delimiters : +; - Display minus or plus sign : +; : +; : +; Entry: ES:SI = Points to current ICB : +; DS:DI = Points to PB : +; : +; WR_CURSIZE = Current cursor size : +; : +; Exit: Default displayed : +; : +;-----------------------------------------------------------------------------+ +; +DEFAULT PROC NEAR +; +; Initialize input buffer with default buffer +; + PUSH BP + PUSH ES ;save registers + PUSH DS + PUSH DI + PUSH SI +; + MOV DX,ES:[SI]+ICB_FIELDLEN ;save for later ;=W + MOV BX,ES:[SI]+ICB_DEFLEN ;save for later ;=W +; + MOV AX,ES:[SI]+ICB_DEFSEG ;get source string segment ;=W + MOV DS,AX ;=W +; + MOV AX,ES:[SI]+ICB_FIELDOFF ;get destination offset ;=W + MOV DI,AX ;=W +; + MOV AX,ES:[SI]+ICB_FIELDSEG ;get destination segment ;=W + MOV CX,ES:[SI]+ICB_DEFOFF ;get source string offset ;=W + MOV SI,CX ;=W + MOV ES,AX ;=W +; + PUSH DI + MOV CX,DX ;clear input buffer ;=W + MOV AL,WR_SPACE ;=W + CLD ;=W + REP STOSB ;=W + POP DI +; ;=W + MOV BP,0 + MOV CX,BX ;initialize number of bytes in ;=W + ; default string + CMP CX,DX ;check if default string is + JBE DEF10 ; longer than input buffer +; + MOV CX,DX ;error set to input buffer leng + MOV BP,ICB_STRU ;set error indicating default was + ; truncated +DEF10: + CLD + REP MOVSB ;move default into input buffer +; + POP SI ;restore registers + POP DI + POP DS + POP ES +; + OR ES:[SI]+ICB_STATUS,BP ;save error status + POP BP +; +; Calculate row and column of input field and set the desired display attribute +; + MOV AX,ES:[SI]+ICB_ROW ;get input field row + MOV [DI]+CR_ROW,AX +; + MOV AX,ES:[SI]+ICB_COL ;get input field column + MOV [DI]+CR_COL,AX +; + CALL PCROWCL_CALL ;calculate row and column info + ; return CR_RCOFF and CR_BEGROWOFF + MOV AL,[DI]+WR_EATTR ;set the entry attribute to the + MOV [DI]+WR_CATTR,AL ; current attribute +; +; Initialize variables for left justified field +; + TEST ES:[SI]+ICB_OPT1,ICB_RJU ;check if right justified + JNE DEF20 +; + MOV [DI]+WR_LEFTCHAR,1 ;set left character marker to + ;beginning of input field + MOV AX,ES:[SI]+ICB_FIELDLEN ;get max field length ;=W +; + TEST ES:[SI]+ICB_OPT3,ICB_HOR ;check if horizontal scrolling ;=W + JE DEF15 ;no ;=W + MOV AX,ES:[SI]+ICB_WIDTH ;get field width for horizontal scrolling ;=W + ;because we only show a windowful of field ;=W +DEF15: ;=W + MOV [DI]+WR_RIGHTCHAR,AX ;set ptr to rightmost character ;=W + CALL CAL_COORS ;get end of field char, byte ;=W + JMP DEF30 ;and next byte positions +; +; Initialize variables for right justified field +; +DEF20: ; + ; code here + ; +; +; Display default even if password option is active +; +DEF30: PUSH ES:[SI]+ICB_OPT1 ;save option word +; + TEST ES:[SI]+ICB_OPT1,ICB_PSW ;check if password option active + JE DEF40 +; + AND ES:[SI]+ICB_OPT1,NOT ICB_PSW + ;set option word to force disp + ; of default value +DEF40: + MOV AX,2 ;set option to actually display + CALL WORD PTR [DI]+WR_DISPLAY ; default value in proper + ; justification + POP ES:[SI]+ICB_OPT1 ;restore original password +; +; Display initial cursor in proper size and location +; + MOV AX,[DI]+IN_CURNOR ;set cursor size for replace + MOV [DI]+WR_CURSIZE,AX +; + TEST ES:[SI]+ICB_STATUS,ICB_SINS + JE DEF45 ;check if insert is active +; + MOV AX,[DI]+IN_CURINS ;set cursor size for insert + MOV [DI]+WR_CURSIZE,AX +; +DEF45: + CALL CAL_COORS ;calculate coordinates ;=W + CALL CURSOR ;initialize cursor size and locat +; +; Determine if characters in input buffer are allowonce chars and set flags +; + + jmp Def65 ;temp until bug in allowonce scan fixed + + PUSH ES ;save registers + PUSH SI +; + MOV BX,ES ;set segment of ICB + MOV DX,SI ;set offset of ICB +; + MOV CX,ES:[SI]+ICB_FIELDLEN ;get field length +; + PUSH ES:[SI]+ICB_FIELDOFF ;get field offset + PUSH ES:[SI]+ICB_FIELDSEG ;get field segment + POP ES + POP SI +; +DEF50: MOV AL,ES:[SI] ;get character from input buffer + MOV [DI]+DBC_KS,AL ; and set to PCINDBC PB +; + INC SI ;point to next byte +; + CALL PCINDBC_CALL ;call PCINDBC + + TEST [DI]+DBC_STAT,DBC_DBCS ;check if keystroke double byte + JE DEF60 +; + CMP CX,0 ;if last loop is double character + JBE DEF60 ; and is missing trailing byte + ; then, consider a single byte +; + MOV AH,ES:[SI] ;get character from input buffer + MOV [DI]+DBC_KS,AH ; and set to PCINDBC PB + INC SI ;point to next byte + DEC CX ;adjust loop pointer for additial + ; character read (double byte) +; +DEF60: PUSH ES ;save registers + PUSH SI +; + MOV ES,BX ;load ICB + MOV SI,DX +; + CALL ON_ALLOWONCE ;Scan the allowonce string for + ; the character in AX and set flag + ; if found + POP SI ;restore registers + POP ES +; + LOOP DEF50 ;get next keystroke +; + POP SI ;restore registers + POP ES +; +; Display field delimiters +; +DEF65: ;=W + MOV AX,01 ;assume "[ ]" as delimiters ;=W +; ;=W + TEST ES:[SI]+ICB_OPT1,ICB_BEN ;display entry delimiters ;=W + JE DEF100 ;no, leave ;=W +; ;=W + TEST ES:[SI]+ICB_OPT3,ICB_WIN ;does field use windowing ;=W + JE DEF70 ;no, check others ;=W +; ;=W + TEST ES:[SI]+ICB_OPT1,ICB_BOX ;check if delimiter = box ;=W + JE DEF90 ;no, display normal delimiters ;=W +; ;=W + MOV AX,06 ;display box ;=W + JMP DEF90 ;done with delimiters ;=W +DEF70: ;=W + TEST ES:[SI]+ICB_OPT3,ICB_HOR ;does field use horiz. window ;=W + JE DEF80 ;=W +; ;=W + MOV AX,03 ;display "[ >" ;=W + CMP ES:[SI]+ICB_HRSTART,01H ;are we at beginning of window ? ;=W + JLE DEF80 ;yes ;=W +; + MOV AX,04 ;no, display "< >" ;=W +DEF80: ;=W + CALL DELIMITER ;do it ;=W +; + TEST ES:[SI]+ICB_OPT1,ICB_BOX ;check if also need box ;=W + JE DEF100 ;=W +; ;=W + MOV AX,06 ;display box ;=W +DEF90: ;=W + CALL DELIMITER ;do it ;=W +; +; Display minus or plus sign if active +; +DEF100: + TEST ES:[SI]+ICB_OPT1,ICB_MUS ;Check if minus/plus sign + JE DEFEXIT ; display option is active +; + MOV [DI]+WR_KEYCONF,0 ;initialize to plus sign key +; + TEST ES:[SI]+ICB_OPT1,ICB_SMU ;Check if default is negative + JE DEF110 +; + OR [DI]+WR_KEYCONF,WR_MUS ;initialize to minus sign key +; +DEF110: CALL PLUS_MINUS ;display plus or minus sign and + ; set status +; +DEFEXIT: ;continue +; + RET +DEFAULT ENDP +; +PAGE +;-----------------------------------------------------------------------------+ +; : +; PRE_EXIT : +; : +; Performs the following functions: : +; : +; - Removes field delimiters : +; - Inserts commas as specified : +; - Inserts decimal point as specified : +; - Adjusts field to specified significant digits : +; - Displays buffer contents in exit color : +; - Checks if original default has changed : +; - Check if entry is in specified numeric range : +; - Sets minus or plus sign indicator in exit color : +; - Remove thousand separators from input string buffer : +; - Restore original cursor position and size, only in text mode : +; : +; Entry: ES:SI = Points to current ICB : +; DS:DI = Points to PB : +; : +; Exit: None : +; : +;-----------------------------------------------------------------------------+ +; +PRE_EXIT PROC NEAR + +; +; Inserts commas as specified +; + ; + ; Code here + ; +; +; Inserts decimal point as specified +; + ; + ; Code here + ; +; +; Adjusts field to specified significant digits +; + ; + ; Code here + ; +; +; Calculate color attribute of exit colors +; + TEST ES:[SI]+ICB_OPT1,ICB_XCL ;check if option to use exit + JE PRE10 ; colors is active +; + MOV AL,[DI]+WR_XATTR ;set the exit attribute to the + MOV [DI]+WR_CATTR,AL ; current attribute +; +; Display default value of input buffer in proper justification +; +PRE10: MOV [DI]+WR_LEFTCHAR,1 ;set left character + MOV AX,ES:[SI]+ICB_FIELDLEN ;set right marker +; + TEST ES:[SI]+ICB_OPT3,ICB_HOR ;horizontal scrolling mode ? ;=W + JE PRE15 ;no, display all buffer ;=W + MOV AX,ES:[SI]+ICB_WIDTH ;use width instead of all buffer ;=W +PRE15: + MOV [DI]+WR_RIGHTCHAR,AX +; + MOV AX,2 ;set option to actually display + CALL WORD PTR [DI]+WR_DISPLAY ; default value in proper +; ; justification +; Process minus/plus key options +; + TEST ES:[SI]+ICB_OPT1,ICB_MUS ;Check if minus/plus sign + JE PRE40 ; display option is active +; + MOV [DI]+WR_KEYCONF,0 ;initialize to plus sign +; + TEST ES:[SI]+ICB_STATUS,ICB_SMUS + JE PRE20 ;Check if sign is negative +; + OR [DI]+WR_KEYCONF,WR_MUS ;initialize to minus sign key +; +PRE20: TEST ES:[SI]+ICB_STATUS,ICB_SPUS + JE PRE30 ;Check if sign is positive +; + OR [DI]+WR_KEYCONF,WR_PUS ;initialize to plus sign key +; +PRE30: CALL PLUS_MINUS ;display plus or minus sign + ; according to WR_KEYCONF setting +; +; Replace field entry delimiters with exit delimiters +; +PRE40: TEST ES:[SI]+ICB_OPT1,ICB_BEX ;check if field delimiters + JE PRE60 ; should be displayed on exit +; + MOV AX,2 ;option to remove delimiters + CALL DELIMITER ;display delimiters +; + TEST ES:[SI]+ICB_OPT1,ICB_BOX ;check if box around field + JE PRE60 ; should be displayed +; + MOV AX,7 ;set option to remove box + CALL DELIMITER ;display delimiters +; +; Check if default value has changed and set return flag +; +PRE60: PUSH DS ;save registers + PUSH SI + PUSH ES + PUSH DI +; + MOV CX,ES:[SI]+ICB_DEFLEN ;initialize to default length + CMP CX,ES:[SI]+ICB_FIELDLEN ;check if default length is less + JBE PRE70 ; than field length +; + MOV CX,ES:[SI]+ICB_FIELDLEN ;initialize to field length +; +PRE70: MOV AX,ES:[SI]+ICB_DEFSEG ;compare default string to ;=W + MOV DS,AX ;=W + MOV AX,ES:[SI]+ICB_FIELDOFF ;=W + MOV DI,AX ;=W +; + MOV AX,ES:[SI]+ICB_DEFOFF ; current input string ;=W + MOV BX,ES:[SI]+ICB_FIELDSEG ;=W + MOV ES,BX ;=W + MOV SI,AX ;=W +; + REPE CMPSB ;compare default and input strings +; + POP DI ;restore registers + POP ES + POP SI + POP DS +; + CMP CX,0 ;are we done ? ;=W + JE PRE80 ;check if strings compared +; + OR ES:[SI]+ICB_STATUS,ICB_SDEF + ;set flag that default changed +; +; Check if entry is within specified numeric range, if not set flag +; +PRE80: ; + ; code here + ; +; +; Remove thousand separators if specified from input string buffer +; +PRE90: ; + ; code here + ; +; +; Restore original cursor position and size +; +PRE95: + TEST ES:[SI]+ICB_STATUS,ICB_CUR_ON ;is cursor on ? + JE PRE100 ;no, quit + CALL CURSOR ;erase the graphics cursor +PRE100: + OR ES:[SI]+ICB_STATUS,ICB_DONE ;exit condition found, exit ;=W +; ;=W +; Check if ICB_SAV option selected. If selected, then save contents of the ;=W +; input buffer to the default buffer. ;=W +; ;=W + TEST ES:[SI]+ICB_OPT4,ICB_SAV ;check ? ;=W + JE PRE200 ;no, exit now ;=W +; ;=W + PUSH ES ;save registers ;=W + PUSH DS ;=W + PUSH DI ;=W + PUSH SI ;=W +; ;=W + MOV CX,ES:[SI]+ICB_ENDBYTE ;# of bytes to copy from input ;=W + ; buffer to default buffer ;=W + MOV ES:[SI]+ICB_DEFLEN,CX ;reset default length +; + MOV AX,ES:[SI]+ICB_FIELDSEG ;get destination segment ;=W + MOV DS,AX ;=W +; ;=W + MOV AX,ES:[SI]+ICB_DEFOFF ;get source string offset ;=W + MOV DI,AX ;=W +; ;=W + MOV AX,ES:[SI]+ICB_DEFSEG ;get source string segment ;=W + MOV BX,ES:[SI]+ICB_FIELDOFF ;get destination offset ;=W + MOV SI,BX ;=W + MOV ES,AX ;=W +; ;=W + CLD ;=W + REP MOVSB ;move default into input buffer ;=W +; ;=W + POP SI ;restore registers ;=W + POP DI ;=W + POP DS ;=W + POP ES ;=W +PRE200: ;=W + RET +PRE_EXIT ENDP +; ;=W +PAGE ;=W +;-----------------------------------------------------------------------------+ ;=W +; : ;=W +; RIGHT_H_JUST : ;=W +; : ;=W +; Process keystroke and update display with input buffer changes : ;=W +; for the following functions: : ;=W +; : ;=W +; Home key Up arrow Allowonce replace mode : ;=W +; End key Down arrow Allowonce insert mode : ;=W +; Left arrow Control end Allow replace mode : ;=W +; Right arrow Delete key Allow insert mode : ;=W +; : ;=W +;-----------------------------------------------------------------------------+ ;=W +; ;=W +RIGHT_H_JUST PROC NEAR ;=W +; ;=W + ; ;=W + ; code here ;=W + ; ;=W +; ;=W + RET ;=W +RIGHT_H_JUST ENDP ;=W +; +PAGE +;-----------------------------------------------------------------------------+ +; : +; RIGHT_JUST : +; : +; Process keystroke and update display with input buffer changes : +; for the following functions: : +; : +; Home key Up arrow Allowonce replace mode : +; End key Down arrow Allowonce insert mode : +; Left arrow Control end Allow replace mode : +; Right arrow Delete key Allow insert mode : +; : +;-----------------------------------------------------------------------------+ +; +RIGHT_JUST PROC NEAR +; + ; + ; code here + ; +; + RET +RIGHT_JUST ENDP +; ;=W +PAGE ;=W +;-----------------------------------------------------------------------------+ ;=W +; : ;=W +; LEFT_H_JUST : ;=W +; : ;=W +; Process keystroke and update display with input buffer changes : ;=W +; for the following functions: : ;=W +; : ;=W +; Home key Up arrow Allowonce replace mode : ;=W +; End key Down arrow Allowonce insert mode : ;=W +; Left arrow Control end Allow replace mode : ;=W +; Right arrow Delete key Allow insert mode : ;=W +; : ;=W +; : ;=W +; Following information is used: : ;=W +; : ;=W +; : ;=W +; ÚÄ (ICB_FIELDSEG:ICB_FIELDOFF) Beginning address of input : ;=W +; ³ buffer in memory. : ;=W +; ³ : ;=W +; ³ ÚÄ (WR_CUBYTE) Byte offset into the input buffer : ;=W +; ³ ³ of where characters will be added : ;=W +; ³ ³ to input buffer. : ;=W +; ³ ³ : ;=W +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W +; ³ S ³ L ³ T ³ L ³ T ³ S ³ S ³ ³ ³ ³ ³ ³ ³ ³ : ;=W +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ : ;=W +; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ : ;=W +; ³ : ;=W +; (ICB_FIELDLEN) Length of input field in bytes. : ;=W +; : ;=W +; : ;=W +; The following demonstrates the before and after input buffer : ;=W +; images. (S = Single byte, L = DBCS lead byte, T = DBCS trailing : ;=W +; byte) : ;=W +; : ;=W +; Deleting a double byte: : ;=W +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W +; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ S ³ ³ ³ : ;=W +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ : ;=W +; : ;=W +; Deleting a single byte: : ;=W +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W +; ³ S ³ L ³ T ³ S ³ L ³ T ³ ³ S ³ L ³ T ³ L ³ T ³ ³ : ;=W +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ : ;=W +; : ;=W +; Backspace removal of a double byte: : ;=W +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W +; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ S ³ ³ ³ : ;=W +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ : ;=W +; : ;=W +; Backspace removal of a single byte: : ;=W +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W +; ³ S ³ S ³ S ³ S ³ L ³ T ³ ³ S ³ S ³ S ³ L ³ T ³ ³ : ;=W +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÁÄÄÄÙ : ;=W +; : ;=W +; Replacing a double byte with a double byte: : ;=W +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W +; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ L ³ T ³ S ³ : ;=W +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÙ : ;=W +; : ;=W +; Replacing a double byte with a single byte: (Option 1) : ;=W +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W +; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ S ³ S ³ ³ : ;=W +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ : ;=W +; : ;=W +; Replacing a double byte with a single byte: (Option 2) : ;=W +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W +; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ S ³ ³ S ³ : ;=W +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ : ;=W +; : ;=W +; Replacing a single byte with a single byte: : ;=W +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W +; ³ S ³ L ³ T ³ S ³ L ³ T ³ ³ S ³ L ³ T ³ S ³ L ³ T ³ : ;=W +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ : ;=W +; : ;=W +; Replacing a single byte with a double byte. : ;=W +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W +; ³ S ³ L ³ T ³ S ³ ³ ³ ³ S ³ L ³ T ³ L ³ T ³ ³ : ;=W +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÙ : ;=W +; : ;=W +; Replacing a single byte with a double byte without enough buffer: : ;=W +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W +; ³ S ³ L ³ T ³ S ³ L ³ T ³ ³ S ³ L ³ T ³ S ³ L ³ T ³ : ;=W +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ : ;=W +; : ;=W +; Inserting a single byte. : ;=W +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W +; ³ S ³ L ³ T ³ L ³ T ³ ³ ³ S ³ L ³ T ³ S ³ L ³ T ³ : ;=W +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ : ;=W +; : ;=W +; Inserting a single byte without enough buffer generate an error: : ;=W +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W +; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ L ³ T ³ S ³ : ;=W +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ : ;=W +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W +; ³ S ³ L ³ T ³ S ³ S ³ ³ ³ S ³ L ³ T ³ S ³ S ³ ³ : ;=W +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ : ;=W +; : ;=W +; Inserting a double byte character: : ;=W +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W +; ³ S ³ L ³ T ³ S ³ ³ ³ ³ S ³ L ³ T ³ L ³ T ³ S ³ : ;=W +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÙ : ;=W +; : ;=W +; : ;=W +; Entry: ES:SI = Points to current ICB : ;=W +; DS:DI = Points to PB : ;=W +; : ;=W +; INC_KS = Keystroke from returned from PCINCHA : ;=W +; : ;=W +; WR_KEYCONF = Bit flag inidicating the options set for INC_KS : ;=W +; WR_KEYCONF2 keystroke. : ;=W +; : ;=W +; Exit: None. : ;=W +; : ;=W +;-----------------------------------------------------------------------------+ ;=W +; ;=W +LEFT_H_JUST PROC NEAR ;=W +; ;=W +; Initialize right and left boundary markers ;=W +; ;=W + TEST [DI]+WR_KEYCONF,WR_MASK ;check to see if editing key entered ;=W + JNE LHJ5 ;yes, must check for editing keys ;=W + JMP LHJ190 ;no, skip checks for editing keys ;=W + ;=W +; ;=W +; Process home key ;=W +; ;=W +LHJ5: TEST [DI]+WR_KEYCONF,WR_HOM ;check if home key pressed ;=W + JE LHJ10 ;=W +; ;=W + ; ;=W + ; add ICB_WHM option to process window home key movement ;=W + ; ;=W +; ;=W + MOV ES:[SI]+ICB_CURCHAR,1 ;initialize cursor to 1st byte ;=W + ; position, assuming no windowing ;=W + ; wrap is occurring ;=W + MOV [DI]+WR_HRCHAR,1 ;reset the horiz. window ;=W + CALL CAL_COORS ;calculate cursor position ;=W + MOV AX,3 ;display delimiters "[ >" ;=W + CALL DELIMITER ;display delimiter ;=W + JMP LHJEXIT ; returns WR_CURROW, WR_CURROW ;=W + ; and WR_CUBYTE ;=W +; ;=W +; Process end key ;=W +; ;=W +LHJ10: TEST [DI]+WR_KEYCONF,WR_END ;check if home key pressed ;=W + JNE LHJ12 ;=W + JMP LHJ20 +LHJ12: ;=W + ; ;=W + ; add ICB_WEN to move cursor to end of current window row ;=W + ; ;=W +; ;=W + CALL CAL_COORS ;get current end of field info ;=W + MOV AX,[DI]+WR_ENCHAR ;adjust one past end buffer charac ;=W + INC AX ;=W + MOV ES:[SI]+ICB_CURCHAR,AX ;set current cursor position to ;=W + CALL CAL_COORS ;get cursor position ;=W + MOV AX,4 ;display delimiters "< >" ;=W + CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W + JE LHJ17 ;no ;=W + MOV AX,5 ;display delimiters "< ]" ;=W + TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W + JE LHJ15 + MOV ES:[SI]+ICB_CURCHAR,1 ;wrap to first character position + MOV [DI]+WR_HRCHAR,1 ;reset the horiz. window ;=W + MOV AX,3 ;display delimiters "[ >" ;=W + JMP LHJ19 ;exit +LHJ15: + TEST ES:[SI]+ICB_OPT2,ICB_AXC ;is autoexit option set ? ;=W + JE LHJ16 ;no ;=W + OR [DI]+WR_KEYCONF2,WR_RET ;yes, set autoexit flag ;=W +LHJ16: ;=W + MOV BX,ES:[SI]+ICB_FIELDLEN ;adjust horizontal window ;=W + SUB BX,ES:[SI]+ICB_WIDTH ;(below this line may not work for ;=W + INC BX ; DBCS support) ;=W + MOV [DI]+WR_HRCHAR,BX ;=W + JMP LHJ19 ;=W +LHJ17: ;=W + MOV CX,[DI]+WR_CUBYTE ;check if need to adjust horz. ;=W + CMP CX,ES:[SI]+ICB_WIDTH ; window ;=W + JA LHJ18 ;=W + MOV [DI]+WR_HRCHAR,1 ;=W + MOV AX,3 ;display delimiters "[ >" ;=W + JMP LHJ19 ;=W +LHJ18: ;=W + MOV BX,[DI]+WR_ENBYTE ;yes, adjust it ;=W + SUB BX,ES:[SI]+ICB_WIDTH ;=W + ADD BX,2 ;=W + MOV [DI]+WR_HRCHAR,BX ;=W +LHJ19: ;=W + CALL CAL_COORS ;re-calculate display ;=W + CALL DELIMITER ;display delimiter ;=W + JMP LHJEXIT ;exit ;=W +; ;=W +; Process left arrow ;=W +; ;=W +LHJ20: TEST [DI]+WR_KEYCONF,WR_LFT ;check if left arrow key pressed ;=W + JE LHJ40 ;=W +; ;=W + ; ;=W + ; add ICB_CSW option to wrap cursor from top/bottom end to end ;=W + ; ;=W +; ;=W + ; ;=W + ; add ICB_WAR option to wrap cursor on same row end to end ;=W + ; ;=W +; ;=W + MOV BX,ES:[SI]+ICB_CURCHAR ;get cursor position ;=W + CMP BX,1 ;is cursor in first position ? ;=W + JA LHJ30 ;no ;=W + TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W + JE LHJ23 + MOV BX,ES:[SI]+ICB_FIELDLEN ;adjust horizontal window ;=W + MOV ES:[SI]+ICB_CURCHAR,BX ;wrap to first character position + SUB BX,ES:[SI]+ICB_WIDTH ;(below this line may not work for ;=W + INC BX ; DBCS support) ;=W + MOV [DI]+WR_HRCHAR,BX ;=W +; + MOV AX,5 ;display delimiters "< ]" ;=W + CALL DELIMITER ;display delimiter ;=W + JMP LHJ32 ;exit +LHJ23: + MOV AX,3 ;display delimiters "[ >" ;=W + CALL DELIMITER ;display delimiter ;=W + TEST ES:[SI]+ICB_OPT2,ICB_AXC ;is autoexit option set ? ;=W + JE LHJ25 ;no ;=W + OR [DI]+WR_KEYCONF2,WR_RET ;yes, set autoexit flag ;=W + JMP LHJ400 ;=W +LHJ25: ;=W + CALL PCMBEEP_CALL ;error beep ;=W + JMP LHJEXIT ;exit ;=W +LHJ30: ;=W + DEC ES:[SI]+ICB_CURCHAR ;adjust cursor to one position ;=W +; + CMP BX,[DI]+WR_HRCHAR ;is cursor to the left of horz.wind. ? ;=W + JG LHJ32 ;no ;=W + DEC [DI]+WR_HRCHAR ;yes, adjust horiz. window ;=W + MOV AX,4 ;display delimiters "< >" ;=W + CALL DELIMITER ;display delimiter ;=W +LHJ32: ; towards the left ;=W + CALL CAL_COORS ;calculate cursor position + JMP LHJEXIT ;exit ;=W +; ;=W +; Process right arrow ;=W +; ;=W +LHJ40: TEST [DI]+WR_KEYCONF,WR_RGT ;check if left arrow key pressed ;=W + JE LHJ60 ;=W +; ;=W + ; ;=W + ; add ICB_WAR option to wrap cursor on same row end to end ;=W + ; ;=W +; ;=W + CALL CAL_COORS ;get cursor position ;=W +; ;=W + CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W + JE LHJ50 ;=W +; ;=W + MOV AX,5 ;display delimiters "< ]" ;=W + CALL DELIMITER ;display delimiter ;=W + CALL PCMBEEP_CALL ;error beep ;=W + JMP LHJEXIT ;exit ;=W +; ;=W +LHJ50: INC ES:[SI]+ICB_CURCHAR ;adjust cursor to one position ;=W + ; towards the right ;=W + MOV BX,[DI]+WR_HRCHAR ;get begin. of horiz. wondow ;=W + ADD BX,ES:[SI]+ICB_WIDTH ;add width to get end of window ;=W + CMP BX,ES:[SI]+ICB_CURCHAR ;is cursor past end of window ? ;=W + JG LHJ52 ;no ;=W + INC [DI]+WR_HRCHAR ;yes, adjust the horiz. window ;=W + MOV AX,4 ;display delimiters "< >" ;=W + CALL DELIMITER ;display delimiter ;=W +LHJ52: ;=W + CALL CAL_COORS ;calculate cursor position ;=W + CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W + JE LHJ55 ;no ;=W + TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W + JE LHJ53 + MOV ES:[SI]+ICB_CURCHAR,1 ;wrap to first character position + MOV [DI]+WR_HRCHAR,1 ;reset the horiz. window ;=W + MOV AX,3 ;display delimiters "[ >" ;=W + CALL DELIMITER ;display delimiter ;=W + JMP LHJ55 ;exit +LHJ53: + DEC [DI]+WR_HRCHAR ;yes, adjust wind back one position ;=W + MOV AX,5 ;display delimiters "< ]" ;=W + CALL DELIMITER ;display delimiter ;=W + TEST ES:[SI]+ICB_OPT2,ICB_AXC ;is autoexit option set ? ;=W + JE LHJ55 ;no ;=W + OR [DI]+WR_KEYCONF2,WR_RET ;set autoexit flag ;=W +LHJ55: ;=W + CALL CAL_COORS ;calculate cursor position ;=W + JMP LHJEXIT ;exit ;=W +; ;=W +; Process up arrow ;=W +; ;=W +LHJ60: ; ;=W + ; adjust cursor position ;=W + ; ;=W + ;=W + ; ;=W + ; check for field wrap, exit, error beep ;=W + ; ;=W +; ;=W +; Process down arrow ;=W +; ;=W +LHJ70: ; ;=W + ; adjust cursor position ;=W + ; ;=W + ;=W + ; ;=W + ; check for field wrap, exit, error beep ;=W + ; ;=W +; ;=W +; Process cntrl+end key ;=W +; ;=W +LHJ80: TEST [DI]+WR_KEYCONF,WR_CED ;check if control+end key pressed ;=W + JE LHJ100 ;=W +; ;=W + CALL CAL_COORS ;get cursor position ;=W + CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W + JE LHJ90 ;=W +; ;=W + CALL PCMBEEP_CALL ;error beep ;=W + JMP LHJEXIT ;exit ;=W +LHJ90: + MOV BX,[DI]+WR_CUBYTE ;delete from current byte position ;=W + CALL CLEAR_BUFFER ;=W +; ;=W + CALL CAL_COORS ;calculate cursor position + JMP LHJEXIT ;display field, set cursor, exit ;=W +; ;=W +; Process delete key ;=W +; ;=W +LHJ100: TEST [DI]+WR_KEYCONF,WR_DEL ;check if delete key pressed ;=W + JE LHJ130 ;=W +; ;=W + ; ;=W + ; Add ICB_WDL option in off state to delete on current line only ;=W + ; ;=W +; ;=W + CALL CAL_COORS ;get cursor position ;=W +; ;=W + CMP [DI]+WR_FIELDEND,1 ;check if cursor past end of field ;=W + JE LHJ110 ;=W +; ;=W + CALL REMOVE_CHAR ;remove character at current offst ;=W + ; and shift remaining in place ;=W + CALL CAL_COORS ;calculate cursor position + JMP LHJEXIT ;display field, set cursor, exit ;=W +; ;=W +LHJ110: CALL PCMBEEP_CALL ;error beep ;=W + JMP LHJEXIT ;exit ;=W +; ;=W +; Process backspace key ;=W +; ;=W +LHJ130: TEST [DI]+WR_KEYCONF,WR_BCK ;check if backspace key pressed ;=W + JE LHJ160 ;=W +; ;=W + MOV BX,ES:[SI]+ICB_CURCHAR ;get cursor position ;=W + CMP BX,1 ;check if cursor is at first ;=W + JA LHJ140 ; field position ;=W +; + TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W + JE LHJ133 + MOV BX,ES:[SI]+ICB_FIELDLEN ;adjust horizontal window ;=W + MOV ES:[SI]+ICB_CURCHAR,BX ;wrap to first character position + SUB BX,ES:[SI]+ICB_WIDTH ;(below this line may not work for ;=W + INC BX ; DBCS support) ;=W + MOV [DI]+WR_HRCHAR,BX ;=W +; + MOV AX,5 ;display delimiters "< ]" ;=W + CALL DELIMITER ;display delimiter ;=W + JMP LHJ145 ;exit +LHJ133: + MOV AX,3 ;display delimiters "[ >" ;=W + TEST ES:[SI]+ICB_OPT2,ICB_AXC ;is autoexit option set ? ;=W + JE LHJ135 ;no ;=W + OR [DI]+WR_KEYCONF2,WR_RET ;yes, set autoexit flag ;=W + CALL DELIMITER ;display delimiter ;=W + JMP LHJ400 ;=W +LHJ135: ;=W + CALL DELIMITER ;display delimiter ;=W + CALL PCMBEEP_CALL ;error beep ;=W + JMP LHJEXIT ;exit ;=W +LHJ140: ;=W + DEC ES:[SI]+ICB_CURCHAR ;adjust cursor to one position + ; towards the left ;=W + CMP BX,[DI]+WR_HRCHAR ;is cursor in front of the wind. ? ;=W + JG LHJ142 ;no ;=W + DEC [DI]+WR_HRCHAR ;yes, adjust the horiz. window ;=W + MOV AX,4 ;display delimiters "< >" ;=W + CALL DELIMITER ;display delimiter ;=W +LHJ142: ;=W +; ;=W + CALL CAL_COORS ;get cursor position ;=W + CALL REMOVE_CHAR ;remove character at current offst ;=W + ; and shift remaining in place ;=W +LHJ145: ;=W + CALL CAL_COORS ;calculate cursor position + JMP LHJEXIT ;display field, set cursor, exit ;=W +; ;=W +; Process insert key toggle ;=W +; ;=W +LHJ160: TEST [DI]+WR_KEYCONF,WR_INS ;check if insert key pressed ;=W + JE LHJ180 ; if not, continue ;=W +; ;=W + TEST ES:[SI]+ICB_STATUS,ICB_SINS ;check if in insert mode ? ;=W + JE LHJ165 ;no, put in insert mode ;=W +; ;=W + MOV BX,[DI]+IN_CURNOR ;set cursor size for normal ;=W + MOV [DI]+WR_CURSIZE,BX ; cursor ;=W +; ;=W + AND ES:[SI]+ICB_STATUS,NOT ICB_SINS ;=W + JMP LHJ170 ;turn insert mode off ;=W +; ;=W +LHJ165: MOV BX,[DI]+IN_CURINS ;set cursor size for insert ;=W + MOV [DI]+WR_CURSIZE,BX ; cursor ;=W +; ;=W + OR ES:[SI]+ICB_STATUS,ICB_SINS ;=W + ;turn insert mode on ;=W +; ;=W +LHJ170: ;=W +; ;=W + PUSH DS ;save registers ;=W + PUSH DI ;=W +; ;=W + MOV DI,40H ;point DS:DI to KB_FLAG in BIOS ;=W + MOV DS,DI ;=W + MOV DI,17H ;=W + MOV AX,[DI] ;get current BIOS KB_FLAG ;=W +; ;=W + AND AX,NOT WR_INSSTATE ;set BIOS insert active flag off ;=W +; ;=W + TEST ES:[SI]+ICB_STATUS,ICB_SINS ;=W + JE LHJ175 ;check if insert should be set on ;=W +; ;=W + OR AX,WR_INSSTATE ;set BIOS insert active flag on ;=W +; ;=W +LHJ175: POP DI ;restore registers ;=W + POP DS ;=W +; ;=W + JMP LHJEXIT ;exit ;=W +; ;=W +; Process allowonce key option ;=W +; ;=W +LHJ180: ; ;=W + ; insert or replace ;=W + ; ;=W +; ;=W + ; ;=W + ; adjust input buffer ;=W + ; ;=W +; ;=W + ; ;=W + ; check for field wrap, exit, error beep ;=W + ; ;=W +; ;=W + ; ;=W + ; adjust cursor position ;=W + ; ;=W +; ;=W +; Process allowed keystroke in replace mode ;=W +; ;=W +LHJ190: TEST [DI]+WR_KEYCONF,WR_ALL ;check if allow key pressed ;=W + JNE LHJ195 ;=W +; ;=W + CALL PCMBEEP_CALL ;error beep key not defined ;=W + JMP LHJEXIT ;exit ;=W +; ;=W +LHJ195: TEST ES:[SI]+ICB_STATUS,ICB_SINS ;=W + JE LHJ198 ;check if insert is active ;=W +; ;=W + JMP LHJ270 ;do insert display ;=W +; ;=W +LHJ198: ;=W + CALL CAL_COORS ;get cursor position ;=W + CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W + JE LHJ200 ;=W +; ;=W + CALL PCMBEEP_CALL ;error beep key not defined ;=W + JMP LHJEXIT ;exit ;=W +; ;=W +; Check if character to be replaced in field buffer is double byte character ;=W +; ;=W +LHJ200: PUSH ES ;save registers ;=W + PUSH SI ;=W +; ;=W + PUSH ES:[SI]+ICB_FIELDSEG ;get segment of input buffer ;=W + PUSH ES:[SI]+ICB_FIELDOFF ;get offset of input buffer ;=W + POP SI ;=W + POP ES ;=W +; ;=W + ADD SI,[DI]+WR_CUBYTE ;add cursor offset into buffer ;=W + DEC SI ;make zero based ;=W +; ;=W + MOV CX,ES ;save offset of character to ;=W + MOV DX,SI ; replace ;=W +; ;=W + MOV AL,ES:[SI] ;get byte that cursor is pointing ;=W + MOV [DI]+DBC_KS,AL ; to check if DBCS ;=W + CALL PCINDBC_CALL ;call routine to check if char ;=W + ; is lead double byte char ;=W +; ;=W + POP SI ;restore registers ;=W + POP ES ;=W +; ;=W + TEST [DI]+DBC_STAT,DBC_DBCS ;check if char is lead DBCS ;=W + JE LHJ220 ; if no, jump to single byte code ;=W +; ;=W +; Replace double byte character with double byte character ;=W +; ;=W + TEST [DI]+WR_KEYCONF2,WR_DBC ;check if keystroke is DBC ;=W + JE LHJ210 ;continue with single byte ;=W +; ;=W + MOV AX,[DI]+INC_KS ;set double byte character to ;=W + ; input buffer replacing ;=W + ; double byte character ;=W + PUSH ES ;=W + PUSH SI ;=W +; ;=W + MOV ES,CX ;save offset of character to ;=W + MOV SI,DX ; replace ;=W + MOV ES:[SI],AX ;replace double byte ;=W +; ;=W + POP SI ;restore registers ;=W + POP ES ;=W +; ;=W + JMP LHJ260 ;exit ;=W +; ;=W +; Replace double byte character with single byte character ;=W +; ;=W +LHJ210: MOV AX,[DI]+INC_KS ;get keystroke and replace double ;=W + ; byte with single byte ;=W +; ;=W + PUSH ES ;=W + PUSH SI ;=W +; ;=W + MOV ES,CX ;save offset of character to ;=W + MOV SI,DX ; replace single byte ;=W + MOV ES:[SI],AL ;=W +; ;=W + POP SI ;restore registers ;=W + POP ES ;=W +; ;=W + MOV AX,ES:[SI]+ICB_FIELDLEN ;set ending byte ;=W + MOV [DI]+WR_RIGHTBYTE,AX ;=W +; ;=W + MOV AX,[DI]+WR_CUBYTE ;set markers for shift to remove ;=W + INC AX ;adjust past replaced leading byte ;=W + MOV [DI]+WR_LEFTBYTE,AX ; trailing byte ;=W +; ;=W + MOV BX,1 ;set number of positions to shift ;=W + MOV AX,2 ;set option to shift left ;=W + CALL SHIFT ;call shift 1 position toward left ;=W + JMP LHJ260 ;exit ;=W +; ;=W +; Replace single byte character with single byte character ;=W +; ;=W +LHJ220: TEST [DI]+WR_KEYCONF2,WR_DBC ;check if double byte character ;=W + JNE LHJ230 ; continue with single byte ;=W +; ;=W + MOV AX,[DI]+INC_KS ;get keystroke ;=W +; ;=W + PUSH ES ;=W + PUSH SI ;=W +; ;=W + MOV ES,CX ;save offset of character to ;=W + MOV SI,DX ; replace single byte ;=W + MOV ES:[SI],AL ;=W +; ;=W + POP SI ;restore registers ;=W + POP ES ;=W +; ;=W + JMP LHJ260 ;exit ;=W +; ;=W +; Replace single byte character with double byte character ;=W +; ;=W +LHJ230: ;=W + CALL CAL_COORS ;calculate cursor position ;=W + MOV BX,[DI]+WR_ENBYTE ;get end byte of input field ;=W + MOV AX,[DI]+WR_ENCHAR ;get end character of field ;=W + CMP AX,ES:[SI]+ICB_CURCHAR ;is cursor past end character ;=W + JA LHJ240 ;=W +; ;=W + MOV BX,[DI]+WR_CUBYTE ;set cursor character position ;=W +LHJ240: ;=W + MOV AX,ES:[SI]+ICB_FIELDLEN ;get end of field position ;=W + SUB AX,BX ;subtract to get the remaining space ;=W + CMP AX,1 ;will byte fit ? ;=W + JGE LHJ250 ;yes ;=W +; ;=W + CALL PCMBEEP_CALL ;error beep because replace char ;=W + JMP LHJEXIT ; will not fit and exit ;=W +; ;=W +LHJ250: MOV BX,ES:[SI]+ICB_FIELDLEN ;set ending byte ;=W + MOV [DI]+WR_RIGHTBYTE,BX ;=W +; ;=W + MOV BX,[DI]+WR_CUBYTE ;set markers for shift to remove ;=W + INC BX ;adjust past replaced leading byte ;=W + MOV [DI]+WR_LEFTBYTE,BX ; trailing byte ;=W +; ;=W + MOV BX,1 ;set number of positions to shift ;=W + MOV AX,1 ;set option to shift right ;=W + CALL SHIFT ;call shift 1 position toward ;=W + ; left ;=W + MOV AX,[DI]+INC_KS ;get keystroke ;=W +; ;=W + PUSH ES ;=W + PUSH SI ;=W +; ;=W + MOV ES,CX ;save offset of character to ;=W + MOV SI,DX ; replace double byte ;=W + MOV ES:[SI],AX ;=W +; ;=W + POP SI ;restore registers ;=W + POP ES ;=W +; ;=W +; Calculate new ending and cursor coordinates ;=W +; ;=W +LHJ260: ;=W + CALL CAL_COORS ;calculate cursor position ;=W + INC ES:[SI]+ICB_CURCHAR ;point to next char ;=W + MOV BX,[DI]+WR_HRCHAR ;get begin. of horiz. wondow ;=W + ADD BX,ES:[SI]+ICB_WIDTH ;add width to get end of window ;=W + CMP BX,ES:[SI]+ICB_CURCHAR ;is cursor past end of window ? ;=W + JG LHJ265 ;no ;=W + INC [DI]+WR_HRCHAR ;yes, adjust the horiz. window ;=W + MOV AX,4 ;display delimiters "< >" ;=W + CALL DELIMITER ;display delimiter ;=W +LHJ265: ;=W + CALL CAL_COORS ;calculate cursor position ;=W + CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W + JE LHJ267 ;no ;=W + TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W + JE LHJ266 + MOV ES:[SI]+ICB_CURCHAR,1 ;wrap to first character position + MOV [DI]+WR_HRCHAR,1 ;reset the horiz. window ;=W + MOV AX,3 ;display delimiters "[ >" ;=W + CALL DELIMITER ;display delimiter ;=W + JMP LHJ267 ;exit +LHJ266: + + DEC [DI]+WR_HRCHAR ;yes, adjust wind back one position ;=W + MOV AX,5 ;display delimiters "< ]" ;=W + CALL DELIMITER ;display delimiter ;=W + TEST ES:[SI]+ICB_OPT2,ICB_AXD ;is autoexit option set ? ;=W + JE LHJ267 ;no ;=W + OR [DI]+WR_KEYCONF2,WR_RET ;set autoexit flag ;=W +LHJ267: ;=W + CALL CAL_COORS ;calculate cursor position ;=W + JMP LHJEXIT ;display field, set cursor, exit ;=W +; ;=W +; Process allowed keystroke in insert mode ;=W +; ;=W +LHJ270: ;=W + CALL CAL_COORS ;get cursor position ;=W + CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W + JE LHJ280 ;=W +; ;=W + CALL PCMBEEP_CALL ;error beep key not defined ;=W + JMP LHJEXIT ;exit ;=W +; ;=W +; Check if enough room available to insert single or double byte character ;=W +; ;=W +LHJ280: ;=W + MOV CX,ES:[SI]+ICB_FIELDSEG ;get segment of input buffer ;=W + MOV DX,ES:[SI]+ICB_FIELDOFF ;get offset of input buffer ;=W +; ;=W + ADD DX,[DI]+WR_CUBYTE ;add cursor offset into buffer ;=W + DEC DX ;make zero based ;=W +; ;=W + MOV BX,1 ;initialize to single byte ;=W +; ;=W + TEST [DI]+WR_KEYCONF2,WR_DBC ;check for double byte character ;=W + JE LHJ290 ;=W +; ;=W + MOV BX,2 ;reset to double byte character ;=W +LHJ290: ;=W + PUSH BX ;=W + CALL CAL_COORS ;calculate cursor position ;=W + MOV BX,[DI]+WR_ENBYTE ;get end byte of input field ;=W + MOV AX,[DI]+WR_ENCHAR ;get end character of field ;=W + CMP AX,ES:[SI]+ICB_CURCHAR ;is cursor past end character ;=W + JA LHJ300 ;=W +; ;=W + MOV BX,[DI]+WR_CUBYTE ;set cursor character position ;=W +LHJ300: ;=W + MOV AX,ES:[SI]+ICB_FIELDLEN ;get end of field position ;=W + SUB AX,BX ;subtract to get the remaining space ;=W + POP BX ;=W + CMP AX,BX ;will byte fit ? ;=W + JGE LHJ310 ;yes ;=W +; ;=W + CALL PCMBEEP_CALL ;error beep replace character ;=W + JMP LHJEXIT ; will not fit and exit ;=W +; ;=W +; Shift to insert single or double byte character, BX= # bytes to shift ;=W +; ;=W +LHJ310: MOV AX,ES:[SI]+ICB_FIELDLEN ;set ending byte to make room in ;=W + MOV [DI]+WR_RIGHTBYTE,AX ; buffer by shifting characters ;=W +; ;=W + MOV AX,[DI]+WR_CUBYTE ;set markers for shift to remove ;=W + MOV [DI]+WR_LEFTBYTE,AX ; trailing byte ;=W +; ;=W + MOV AX,1 ;set option to shift right, BX= ;=W + ; number of bytes to insert ;=W + CALL SHIFT ;call shift 1 position toward ;=W + ; left ;=W + MOV AX,[DI]+INC_KS ;get keystroke ;=W +; ;=W +; Insert single byte character ;=W +; ;=W + CMP BX,2 ;check how many bytes should be ;=W + JE LHJ320 ; inserted ;=W +; ;=W + PUSH ES ;=W + PUSH SI ;=W +; ;=W + MOV ES,CX ;save offset of character to ;=W + MOV SI,DX ; replace single byte ;=W + MOV ES:[SI],AL ;insert single byte character ;=W +; ;=W + POP SI ;restore registers ;=W + POP ES ;=W +; ;=W + JMP LHJ330 ;=W +; ;=W +; Insert double byte character ;=W +; ;=W +LHJ320: PUSH ES ;=W + PUSH SI ;=W +; ;=W + MOV ES,CX ;save offset of character to ;=W + MOV SI,DX ; replace ;=W + MOV ES:[SI],AX ;insert double byte character ;=W +; ;=W + POP SI ;restore registers ;=W + POP ES ;=W +; ;=W +; Calculate new ending and cursor coordinates ;=W +; ;=W +LHJ330: ;=W + CALL CAL_COORS ;get new end coordinates ;=W +; ;=W + INC ES:[SI]+ICB_CURCHAR ;point to next char ;=W + MOV BX,[DI]+WR_HRCHAR ;get begin. of horiz. wondow ;=W + ADD BX,ES:[SI]+ICB_WIDTH ;add width to get end of window ;=W + CMP BX,ES:[SI]+ICB_CURCHAR ;is cursor past end of window ? ;=W + JG LHJ332 ;no ;=W + INC [DI]+WR_HRCHAR ;yes, adjust the horiz. window ;=W + MOV AX,4 ;display delimiters "< >" ;=W + CALL DELIMITER ;display delimiter ;=W +LHJ332: ;=W + CALL CAL_COORS ;calculate cursor position + CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W + JE LHJ335 ;no ;=W + TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W + JE LHJ333 + MOV ES:[SI]+ICB_CURCHAR,1 ;wrap to first character position + MOV [DI]+WR_HRCHAR,1 ;reset the horiz. window ;=W + MOV AX,3 ;display delimiters "[ >" ;=W + CALL DELIMITER ;display delimiter ;=W + JMP LHJ335 ;exit +LHJ333: + DEC [DI]+WR_HRCHAR ;yes, adjust wind back one position ;=W + MOV AX,5 ;display delimiters "< ]" ;=W + CALL DELIMITER ;display delimiter ;=W + TEST ES:[SI]+ICB_OPT2,ICB_AXD ;is autoexit option set ? ;=W + JE LHJ335 ;no ;=W + OR [DI]+WR_KEYCONF2,WR_RET ;set autoexit flag ;=W +LHJ335: + CALL CAL_COORS ;calculate cursor position ;=W + JMP LHJEXIT ;display cursor +; ;=W +; Display field & Exit ;=W +; ;=W +LHJ400: + CALL WORD PTR [DI]+WR_DISPLAY ;display current input buffer ;=W + ; in left justified field ;=W + JMP LHJCUR +LHJEXIT: ;=W + CALL WORD PTR [DI]+WR_DISPLAY ;display current input buffer ;=W + ; in left justified field ;=W + TEST ES:[SI]+ICB_STATUS,ICB_CUR_ON ;is cursor on ? + JNE LHJCUR ;cursor is already on, don't turn it on ;=W + CALL CURSOR ;display cursor ;=W +LHJCUR: +; ;=W + RET ;=W +LEFT_H_JUST ENDP ;=W +; +PAGE +;-----------------------------------------------------------------------------+ +; : +; LEFT_JUST : +; : +; Process keystroke and update display with input buffer changes : +; for the following functions: : +; : +; Home key Up arrow Allowonce replace mode : +; End key Down arrow Allowonce insert mode : +; Left arrow Control end Allow replace mode : +; Right arrow Delete key Allow insert mode : +; : +; : +; Following information is used: : +; : +; : +; ÚÄ (ICB_FIELDSEG:ICB_FIELDOFF) Beginning address of input : +; ³ buffer in memory. : +; ³ : +; ³ ÚÄ (WR_CUBYTE) Byte offset into the input buffer : +; ³ ³ of where characters will be added : +; ³ ³ to input buffer. : +; ³ ³ : +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : +; ³ S ³ L ³ T ³ L ³ T ³ S ³ S ³ ³ ³ ³ ³ ³ ³ ³ : +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ : +; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ : +; ³ : +; (ICB_FIELDLEN) Length of input field in bytes. : +; : +; : +; The following demonstrates the before and after input buffer : +; images. (S = Single byte, L = DBCS lead byte, T = DBCS trailing : +; byte) : +; : +; Deleting a double byte: : +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : +; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ S ³ ³ ³ : +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ : +; : +; Deleting a single byte: : +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : +; ³ S ³ L ³ T ³ S ³ L ³ T ³ ³ S ³ L ³ T ³ L ³ T ³ ³ : +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ : +; : +; Backspace removal of a double byte: : +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : +; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ S ³ ³ ³ : +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ : +; : +; Backspace removal of a single byte: : +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : +; ³ S ³ S ³ S ³ S ³ L ³ T ³ ³ S ³ S ³ S ³ L ³ T ³ ³ : +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÁÄÄÄÙ : +; : +; Replacing a double byte with a double byte: : +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : +; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ L ³ T ³ S ³ : +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÙ : +; : +; Replacing a double byte with a single byte: (Option 1) : +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : +; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ S ³ S ³ ³ : +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ : +; : +; Replacing a double byte with a single byte: (Option 2) : +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : +; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ S ³ ³ S ³ : +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ : +; : +; Replacing a single byte with a single byte: : +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : +; ³ S ³ L ³ T ³ S ³ L ³ T ³ ³ S ³ L ³ T ³ S ³ L ³ T ³ : +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ : +; : +; Replacing a single byte with a double byte. : +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : +; ³ S ³ L ³ T ³ S ³ ³ ³ ³ S ³ L ³ T ³ L ³ T ³ ³ : +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÙ : +; : +; Replacing a single byte with a double byte without enough buffer: : +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : +; ³ S ³ L ³ T ³ S ³ L ³ T ³ ³ S ³ L ³ T ³ S ³ L ³ T ³ : +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ : +; : +; Inserting a single byte. : +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : +; ³ S ³ L ³ T ³ L ³ T ³ ³ ³ S ³ L ³ T ³ S ³ L ³ T ³ : +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ : +; : +; Inserting a single byte without enough buffer generate an error: : +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : +; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ L ³ T ³ S ³ : +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ : +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : +; ³ S ³ L ³ T ³ S ³ S ³ ³ ³ S ³ L ³ T ³ S ³ S ³ ³ : +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ : +; : +; Inserting a double byte character: : +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : +; ³ S ³ L ³ T ³ S ³ ³ ³ ³ S ³ L ³ T ³ L ³ T ³ S ³ : +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÙ : +; : +; : +; Entry: ES:SI = Points to current ICB : +; DS:DI = Points to PB : +; : +; INC_KS = Keystroke from returned from PCINCHA : +; : +; WR_KEYCONF = Bit flag inidicating the options set for INC_KS : +; WR_KEYCONF2 keystroke. : +; : +; Exit: None. : +; : +;-----------------------------------------------------------------------------+ +; +LEFT_JUST PROC NEAR +; +; Initialize right and left boundary markers +; + MOV [DI]+WR_LEFTCHAR,1 ;set left character to beginning + ; of field +; + MOV AX,ES:[SI]+ICB_FIELDLEN ;set right marker past end of + INC AX ; field + MOV [DI]+WR_RIGHTCHAR,AX +; + TEST [DI]+WR_KEYCONF,WR_MASK ;check to see if editing key entered ;=W + JNE LJ5 ;yes, must check for editing keys ;=W + JMP LJ190 ;no, skip checks for editing keys ;=W + +; +; Process home key +; +LJ5: TEST [DI]+WR_KEYCONF,WR_HOM ;check if home key pressed + JE LJ10 +; + ; + ; add ICB_WHM option to process window home key movement + ; +; + MOV ES:[SI]+ICB_CURCHAR,1 ;initialize cursor to 1st byte + ; position, assuming no windowing + ; wrap is occurring + CALL CAL_COORS ;get cursor position ;=W + JMP LJEXIT ; returns WR_CURROW, WR_CURROW + ; and WR_CUBYTE +; +; Process end key +; +LJ10: TEST [DI]+WR_KEYCONF,WR_END ;check if home key pressed + JE LJ20 +; + ; + ; add ICB_WEN to move cursor to end of current window row + ; +; + CALL CAL_COORS ;get current end of field info ;=W +; + MOV AX,[DI]+WR_ENCHAR ;adjust one past end buffer charac + INC AX + MOV ES:[SI]+ICB_CURCHAR,AX ;set current cursor position to + ; end of field + CALL CAL_COORS ;get cursor position ;=W + CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W + JE LJ17 ;no ;=W + TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W + JE LJ16 + MOV ES:[SI]+ICB_CURCHAR,1 ;wrap to first character position + CALL CAL_COORS ;get cursor position + JMP LJEXIT ;exit +LJ16: + TEST ES:[SI]+ICB_OPT2,ICB_AXC ;is autoexit option set ? ;=W + JE LJ17 ;no ;=W + OR [DI]+WR_KEYCONF2,WR_RET ;yes, set autoexit flag ;=W +LJ17: ;=W + JMP LJEXIT ;exit +; +; Process left arrow +; +LJ20: TEST [DI]+WR_KEYCONF,WR_LFT ;check if left arrow key pressed + JE LJ40 +; + ; + ; add ICB_WAR option to wrap cursor on same row end to end + ; +; + CMP ES:[SI]+ICB_CURCHAR,1 ;check if cursor is at first + JA LJ30 ; field position +; + TEST ES:[SI]+ICB_OPT2,ICB_AXC ;is autoexit option set ? ;=W + JE LJ25 ;no ;=W + OR [DI]+WR_KEYCONF2,WR_RET ;yes, set autoexit flag ;=W + JMP LJCUR ;=W +LJ25: ;=W + TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W + JE LJ27 + MOV AX,ES:[SI]+ICB_FIELDLEN ;get last position + MOV ES:[SI]+ICB_CURCHAR,AX ;put as current position + CALL CAL_COORS + JMP LJEXIT +LJ27: + CALL PCMBEEP_CALL ;error beep + JMP LJEXIT ;exit +; +LJ30: DEC ES:[SI]+ICB_CURCHAR ;adjust cursor to one position + ; towards the left + CALL CAL_COORS ;get cursor position ;=W + JMP LJEXIT ;exit +; +; Process right arrow +; +LJ40: TEST [DI]+WR_KEYCONF,WR_RGT ;check if left arrow key pressed + JE LJ60 +; + ; + ; add ICB_CSW option to wrap cursor from top/bottom end to end + ; +; + ; + ; add ICB_AXC option to auto enter if cursor reaches end + ; +; + ; + ; add ICB_WAR option to wrap cursor on same row end to end + ; +; + CALL CAL_COORS ;get cursor position ;=W + CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field + JE LJ50 +; + CALL PCMBEEP_CALL ;error beep + JMP LJEXIT ;exit +; +LJ50: INC ES:[SI]+ICB_CURCHAR ;adjust cursor to one position + ; towards the left + CALL CAL_COORS ;get cursor position ;=W + CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W + JE LJ55 ;no ;=W + TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W + JE LJ52 + MOV ES:[SI]+ICB_CURCHAR,1 ;wrap to first character position + CALL CAL_COORS ;get cursor position + JMP LJEXIT ;exit +LJ52: + TEST ES:[SI]+ICB_OPT2,ICB_AXC ;is autoexit option set ? ;=W + JE LJ55 ;no ;=W + OR [DI]+WR_KEYCONF2,WR_RET ;set autoexit flag ;=W +LJ55: ;=W + JMP LJEXIT ;exit +; +; Process up arrow +; +LJ60: ; + ; adjust cursor position + ; + + ; + ; check for field wrap, exit, error beep + ; +; +; Process down arrow +; +LJ70: ; + ; adjust cursor position + ; + + ; + ; check for field wrap, exit, error beep + ; +; +; Process cntrl+end key +; +LJ80: TEST [DI]+WR_KEYCONF,WR_CED ;check if control+end key pressed + JE LJ100 +; + CALL CAL_COORS ;get cursor position ;=W + CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field + JE LJ90 +; + CALL PCMBEEP_CALL ;error beep + JMP LJEXIT ;exit +; +LJ90: CALL CAL_COORS ;get current end of field info ;=W +; + MOV AX,ES:[SI]+ICB_FIELDLEN ;set rightmost area to refresh on + MOV [DI]+WR_RIGHTDISP,AX ; display to entire field +; + MOV BX,[DI]+WR_CUBYTE ;delete from current byte position + CALL CLEAR_BUFFER +; + CALL CAL_COORS ;get cursor position ;=W + JMP LJ340 ;display field, set cursor, exit +; +; Process delete key +; +LJ100: TEST [DI]+WR_KEYCONF,WR_DEL ;check if delete key pressed + JE LJ130 +; + ; + ; Add ICB_WDL option in off state to delete on current line only + ; +; + CALL CAL_COORS ;get cursor position ;=W + CMP [DI]+WR_FIELDEND,1 ;check if cursor past end of field + JE LJ110 +; + CALL REMOVE_CHAR ;remove character at current offst + ; and shift remaining in place + JMP LJ340 ;display field, set cursor, exit +; +LJ110: CALL PCMBEEP_CALL ;error beep + JMP LJEXIT ;exit +; +; Process backspace key +; +LJ130: TEST [DI]+WR_KEYCONF,WR_BCK ;check if backspace key pressed + JE LJ160 +; + CMP ES:[SI]+ICB_CURCHAR,1 ;check if cursor is at first + JA LJ140 ; field position +; + TEST ES:[SI]+ICB_OPT2,ICB_AXC ;is autoexit option set ? ;=W + JE LJ135 ;no ;=W + OR [DI]+WR_KEYCONF2,WR_RET ;yes, set autoexit flag ;=W + JMP LJCUR ;=W +LJ135: ;=W + TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W + JE LJ137 + MOV AX,ES:[SI]+ICB_FIELDLEN ;get last position + MOV ES:[SI]+ICB_CURCHAR,AX ;put as current position + CALL CAL_COORS + JMP LJEXIT +LJ137: + CALL PCMBEEP_CALL ;error beep + JMP LJEXIT ;exit +; +LJ140: DEC ES:[SI]+ICB_CURCHAR ;adjust cursor to one position + ; towards the left + CALL CAL_COORS ;get cursor position ;=W + CALL REMOVE_CHAR ;remove character at current offst + ; and shift remaining in place +; + CALL CAL_COORS ;get cursor position ;=W + JMP LJ340 ;display field, set cursor, exit +; +; Process insert key toggle +; +LJ160: TEST [DI]+WR_KEYCONF,WR_INS ;check if insert key pressed + JE LJ180 ; if not, continue +; + TEST ES:[SI]+ICB_STATUS,ICB_SINS ;check if in insert mode ? + JE LJ165 ;no, put in insert mode +; + MOV BX,[DI]+IN_CURNOR ;set cursor size for normal + MOV [DI]+WR_CURSIZE,BX ; cursor +; + AND ES:[SI]+ICB_STATUS,NOT ICB_SINS + JMP LJ170 ;turn insert mode off +; +LJ165: MOV BX,[DI]+IN_CURINS ;set cursor size for insert + MOV [DI]+WR_CURSIZE,BX ; cursor +; + OR ES:[SI]+ICB_STATUS,ICB_SINS + ;turn insert mode on +; +LJ170: +; + PUSH DS ;save registers + PUSH DI +; + MOV DI,40H ;point DS:DI to KB_FLAG in BIOS + MOV DS,DI + MOV DI,17H + MOV AX,[DI] ;get current BIOS KB_FLAG +; + AND AX,NOT WR_INSSTATE ;set BIOS insert active flag off +; + TEST ES:[SI]+ICB_STATUS,ICB_SINS + JE LJ175 ;check if insert should be set on +; + OR AX,WR_INSSTATE ;set BIOS insert active flag on +; +LJ175: POP DI ;restore registers + POP DS +; + JMP LJEXIT ;exit +; +; Process allowonce key option +; +LJ180: ; + ; insert or replace + ; +; + ; + ; adjust input buffer + ; +; + ; + ; check for field wrap, exit, error beep + ; +; + ; + ; adjust cursor position + ; +; +; Process allowed keystroke in replace mode +; +LJ190: TEST [DI]+WR_KEYCONF,WR_ALL ;check if allow key pressed + JNE LJ195 +; + CALL PCMBEEP_CALL ;error beep key not defined + JMP LJEXIT ;exit +; +LJ195: TEST ES:[SI]+ICB_STATUS,ICB_SINS + JE LJ198 ;check if insert is active +; + JMP LJ270 ;do insert display +; +LJ198: + CALL CAL_COORS ;get cursor position ;=W + CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field + JE LJ200 +; + CALL PCMBEEP_CALL ;error beep key not defined + JMP LJEXIT ;exit +; +; Check if character to be replaced in field buffer is double byte character +; +LJ200: PUSH ES ;save registers + PUSH SI +; + PUSH ES:[SI]+ICB_FIELDSEG ;get segment of input buffer + PUSH ES:[SI]+ICB_FIELDOFF ;get offset of input buffer + POP SI + POP ES +; + ADD SI,[DI]+WR_CUBYTE ;add cursor offset into buffer + DEC SI ;make zero based +; + MOV CX,ES ;save offset of character to + MOV DX,SI ; replace +; + MOV AL,ES:[SI] ;get byte that cursor is pointing + MOV [DI]+DBC_KS,AL ; to check if DBCS + CALL PCINDBC_CALL ;call routine to check if char + ; is lead double byte char +; + POP SI ;restore registers + POP ES +; + TEST [DI]+DBC_STAT,DBC_DBCS ;check if char is lead DBCS + JE LJ220 ; if no, jump to single byte code +; +; Replace double byte character with double byte character +; + TEST [DI]+WR_KEYCONF2,WR_DBC ;check if keystroke is DBC + JE LJ210 ;continue with single byte +; + MOV AX,[DI]+INC_KS ;set double byte character to + ; input buffer replacing + ; double byte character + PUSH ES + PUSH SI +; + MOV ES,CX ;save offset of character to + MOV SI,DX ; replace + MOV ES:[SI],AX ;replace double byte +; + POP SI ;restore registers + POP ES +; + JMP LJ260 ;exit +; +; Replace double byte character with single byte character +; +LJ210: MOV AX,[DI]+INC_KS ;get keystroke and replace double + ; byte with single byte +; + PUSH ES + PUSH SI +; + MOV ES,CX ;save offset of character to + MOV SI,DX ; replace single byte + MOV ES:[SI],AL +; + POP SI ;restore registers + POP ES +; + MOV AX,ES:[SI]+ICB_FIELDLEN ;set ending byte + MOV [DI]+WR_RIGHTBYTE,AX +; + MOV AX,[DI]+WR_CUBYTE ;set markers for shift to remove + INC AX ;adjust past replaced leading byte ;=W + MOV [DI]+WR_LEFTBYTE,AX ; trailing byte +; + MOV BX,1 ;set number of positions to shift + MOV AX,2 ;set option to shift left + CALL SHIFT ;call shift 1 position toward left + JMP LJ260 ;exit +; +; Replace single byte character with single byte character +; +LJ220: TEST [DI]+WR_KEYCONF2,WR_DBC ;check if double byte character + JNE LJ230 ; continue with single byte +; + MOV AX,[DI]+INC_KS ;get keystroke +; + PUSH ES + PUSH SI +; + MOV ES,CX ;save offset of character to + MOV SI,DX ; replace single byte + MOV ES:[SI],AL +; + POP SI ;restore registers + POP ES +; + JMP LJ260 ;exit +; +; Replace single byte character with double byte character +; +LJ230: MOV BX,ES:[SI]+ICB_CURCHAR ;set cursor character position + MOV [DI]+WR_LEFTCHAR,BX ; to left marker +; + CALL CAL_COORS ;get the current end of field ;=W + ; coordinates + MOV AX,[DI]+WR_ENCHAR ;get end character of field + CMP AX,ES:[SI]+ICB_CURCHAR ;is cursor past end character + JA LJ240 +; + MOV AX,ES:[SI]+ICB_CURCHAR ;cursor is past last char +; +LJ240: MOV [DI]+WR_RIGHTCHAR,AX ;set right marker +; + MOV BX,1 ;One byte is already available + ; check if room for trailing byte + MOV AX,1 ;set up call to LEFT_DISP to + CALL WORD PTR [DI]+WR_DISPLAY ; determine if additional byte + ; will fit in input buffer + CMP AX,0 ;check if double byte character + JE LJ250 ; will fit +; + CALL PCMBEEP_CALL ;error beep because replace char + JMP LJEXIT ; will not fit and exit +; +LJ250: MOV BX,ES:[SI]+ICB_FIELDLEN ;set ending byte + MOV [DI]+WR_RIGHTBYTE,BX +; + MOV BX,[DI]+WR_CUBYTE ;set markers for shift to remove + INC BX ;adjust past replaced leading byte + MOV [DI]+WR_LEFTBYTE,BX ; trailing byte +; + MOV BX,1 ;set number of positions to shift + MOV AX,1 ;set option to shift right + CALL SHIFT ;call shift 1 position toward + ; left + MOV AX,[DI]+INC_KS ;get keystroke +; + PUSH ES + PUSH SI +; + MOV ES,CX ;save offset of character to + MOV SI,DX ; replace double byte + MOV ES:[SI],AX +; + POP SI ;restore registers + POP ES +; +; Calculate new ending and cursor coordinates +; +LJ260: + MOV BX,[DI]+WR_ENCHAR ;set rightmost area to refresh on ;=W + CALL CAL_COORS ;get new end coordinates ;=W + CMP BX,[DI]+WR_ENCHAR ;is old END_CHAR > new END_CHAR ? ;=W + JG LJ261 ;yes, use old END_CHAR (so display ;=W + MOV BX,[DI]+WR_ENCHAR ; is updated correctly) + +LJ261: ;set rightmost area to refresh on ;=W + MOV [DI]+WR_RIGHTDISP,BX ; display to new ending character + + INC ES:[SI]+ICB_CURCHAR ;point to next char + + CALL CAL_COORS ;get cursor position ;=W + CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W + JE LJ265 ;no ;=W + TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W + JE LJ262 + MOV ES:[SI]+ICB_CURCHAR,1 ;wrap to first character position + JMP LJ340 ;display field, set cursor, exit +LJ262: + TEST ES:[SI]+ICB_OPT2,ICB_AXD ;is autoexit option set ? ;=W + JE LJ265 ;no ;=W + OR [DI]+WR_KEYCONF2,WR_RET ;set autoexit flag ;=W +LJ265: ;=W + JMP LJ340 ;display field, set cursor, exit +; +; Process allowed keystroke in insert mode +; +LJ270: + CALL CAL_COORS ;get cursor position ;=W + CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field + JE LJ280 +; + CALL PCMBEEP_CALL ;error beep key not defined + JMP LJEXIT ;exit +; +; Check if enough room available to insert single or double byte character +; +LJ280: + MOV CX,ES:[SI]+ICB_FIELDSEG ;get segment of input buffer + MOV DX,ES:[SI]+ICB_FIELDOFF ;get offset of input buffer +; + ADD DX,[DI]+WR_CUBYTE ;add cursor offset into buffer + DEC DX ;make zero based +; + MOV BX,1 ;initialize to single byte +; + TEST [DI]+WR_KEYCONF2,WR_DBC ;check for double byte character + JE LJ290 +; + MOV BX,2 ;reset to double byte character +; +LJ290: MOV AX,ES:[SI]+ICB_CURCHAR ;set cursor character position + MOV [DI]+WR_LEFTCHAR,AX ; to left marker +; + CALL CAL_COORS ;get the current end of field ;=W + ; coordinates + MOV AX,[DI]+WR_ENCHAR ;get end character of field +; + CMP AX,ES:[SI]+ICB_CURCHAR ;is cursor past end character + JA LJ300 +; + MOV AX,ES:[SI]+ICB_CURCHAR ;cursor is past last char + DEC AX +; +LJ300: MOV [DI]+WR_RIGHTCHAR,AX ;set right marker +; + MOV AX,1 ;set up call to LEFT_DISP to + CALL WORD PTR [DI]+WR_DISPLAY ; determine if additional byte + ; will fit in input buffer + ; BX= number of bytes to insert + CMP AX,0 ;check if double byte character + JE LJ310 ; will fit +; + CALL PCMBEEP_CALL ;error beep replace character + JMP LJEXIT ; will not fit and exit +; +; Shift to insert single or double byte character, BX= # bytes to shift +; +LJ310: MOV AX,ES:[SI]+ICB_FIELDLEN ;set ending byte to make room in + MOV [DI]+WR_RIGHTBYTE,AX ; buffer by shifting characters +; + MOV AX,[DI]+WR_CUBYTE ;set markers for shift to remove + MOV [DI]+WR_LEFTBYTE,AX ; trailing byte +; + MOV AX,1 ;set option to shift right, BX= + ; number of bytes to insert + CALL SHIFT ;call shift 1 position toward + ; left + MOV AX,[DI]+INC_KS ;get keystroke +; +; Insert single byte character +; + CMP BX,2 ;check how many bytes should be + JE LJ320 ; inserted +; + PUSH ES + PUSH SI +; + MOV ES,CX ;save offset of character to + MOV SI,DX ; replace single byte + MOV ES:[SI],AL ;insert single byte character +; + POP SI ;restore registers + POP ES +; + JMP LJ330 +; +; Insert double byte character +; +LJ320: PUSH ES + PUSH SI +; + MOV ES,CX ;save offset of character to + MOV SI,DX ; replace + MOV ES:[SI],AX ;insert double byte character +; + POP SI ;restore registers + POP ES +; +; Calculate new ending and cursor coordinates +; +LJ330: + CALL CAL_COORS ;get new end coordinates ;=W +; + MOV AX,[DI]+WR_ENCHAR ;set rightmost area to refresh on + MOV [DI]+WR_RIGHTDISP,AX ; display to old ending character +; + INC ES:[SI]+ICB_CURCHAR ;point to next char +; + CALL CAL_COORS ;get cursor position ;=W + CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W + JE LJ340 ;no ;=W + TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W + JE LJ335 + MOV ES:[SI]+ICB_CURCHAR,1 ;wrap to first character position + JMP LJ340 ;display field, set cursor, exit +LJ335: + TEST ES:[SI]+ICB_OPT2,ICB_AXD ;is autoexit option set ? ;=W + JE LJ340 ;no ;=W + OR [DI]+WR_KEYCONF2,WR_RET ;set autoexit flag ;=W +; +; Display field +; +LJ340: + MOV AX,ES:[SI]+ICB_CURCHAR ;set left character to cursor + DEC AX ; last cursor position + MOV [DI]+WR_LEFTCHAR,AX +; + MOV AX,[DI]+WR_RIGHTDISP ;set right character marker to ;=W + MOV [DI]+WR_RIGHTCHAR,AX ; max possible field length +; + CALL CAL_COORS ;get end of field char, byte ;=W + ; and next byte positions + + MOV AX,2 ;set display option + CALL WORD PTR [DI]+WR_DISPLAY ;display current input buffer + ; in left justified field +; +; Exit +; +LJEXIT: ;continue + TEST ES:[SI]+ICB_STATUS,ICB_CUR_ON ;is cursor on ? + JNE LJCUR ;cursor is already on, don't turn it on ;=W + CALL CURSOR ;display cursor ;=W +LJCUR: +; + RET +LEFT_JUST ENDP +;-----------------------------------------------------------------------------+ +; : +; CAL_COORS : +; : +; Calculates character coordinates based on the display format : +; currently active (windowing and horizontal display). : +; : +; The following examples demonstrate the values that are set on : +; exit from this routine: : +; : +; : +; Example: Horizontal field coordinates calculated. : +; : +; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ : +; ³123456789012345678901234567890 : +; ³2 : +; ³3 [sLtLtssss....] : +; ^ : +; ³ ³ ³ : +; ³ ³ ÀÄ WR_ENCHAR = 7 : +; ³ ³ WR_ENBYTE = 9 : +; ³ ³ WR_RGCHAR = 7 : +; ³ ³ : +; ³ ÀÄÄÄÄÄÄ WR_CUCHAR = 3 : +; ³ WR_CUBYTE = 4 : +; ³ WR_UPCHAR = 3 : +; ³ WR_DNCHAR = 3 : +; ³ WR_CURROW = 3 : +; ³ WR_CURCOL = 13 : +; ³ : +; ÀÄÄÄÄÄÄÄÄÄ WR_LFCHAR = 1 : +; WR_HRCHAR = 1 : +; : +; : +; Example: Horizontal field scroll coordinates calculated: : +; : +; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ : +; ³123456789012345678901234567890 : +; ³2 ÚÄÄÄÄÄ¿ : +; ³3 s³LtLt ³Ltsss..... : +; ³ÀÄÄÄÄÄÙ ³ : +; ³ ³ ^ ³ : +; ³ ³ ³ ³ : +; ³ ³ ³ À WR_ENCHAR = 7 : +; ³ ³ ³ WR_ENBYTE = 10 : +; ³ ³ ³ WR_RGCHAR = 7 : +; ³ ³ ³ : +; ³ ³ ÀÄÄÄÄÄÄÄÄ WR_CUCHAR = 3 : +; ³ ³ WR_CUBYTE = 4 : +; ³ ³ WR_UPCHAR = 3 : +; ³ ³ WR_DNCHAR = 3 : +; ³ ³ WR_CURROW = 3 : +; ³ ³ WR_CURCOL = 14 : +; ³ ³ : +; ³ ÀÄÄÄÄÄÄÄÄÄÄ WR_HRCHAR = 2 : +; ³ : +; ÀÄÄÄÄÄÄÄÄÄÄÄÄ WR_LFCHAR = 1 : +; : +; : +; : +; Example: Windowed field coordinates calculated. : +; : +; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ : +; ³123456789012345678901234567890 : +; ³2 ÚÄÄÄÄÄÄÄÄÄÄÄÄÄ WR_LFCHAR= 6 : +; ³3 ³ ÚÄÄÄÄÄÄÄÄ WR_UPCHAR= 3 : +; ³4 ³ ÚÄijÄÄ¿ : +; ³5 ³ ³ABCDE³ : +; ³6 ÀÄÄFGHI.³ : +; ³7 ³ Ú³³ÀÄÄÄÄÄÄ WR_RGCHAR= 10 : +; ³8 Àij³ÀÄÄÄÄÄÄÄ WR_ENCHAR= 9 : +; ³9 ³³ : +; ³ÀÄÄÄÄÄÄÂÄ WR_CUCHAR= 8 : +; ³ ÃÄ WR_CURCOL= 24 : +; ³ ÀÄ WR_CURROW= 6 : +; ³ : +; ÀÄÄÄÄÄÄÄÄÄ WR_DNCHAR= 13 : +; : +; : +; Entry: ICB_CURCHAR = The character position into the input field from : +; which the exit coordinates will be calculated. : +; : +; WR_HRCHAR = The character position into the input field that : +; is currently the first displayed character of the : +; horizontal window. : +; : +; ICB_WIDTH = The width of windowed or horizontal scroll field. : +; : +; ICB_FIELDLEN = Input field buffer length. : +; : +; ICB_FIELDOFF = Input field buffer offset. : +; : +; ICB_FIELDSEG = Input field buffer segment. : +; : +; : +; Exit: WR_RGCHAR = Character offset into input buffer of the character : +; appearing at the beginning of the current line that : +; WR_CUCHAR is located on. : +; : +; WR_LFCHAR = Character offset into input buffer of the character : +; appearing at the end of the current line that : +; WR_CUCHAR is located on. : +; : +; WR_UPCHAR = Character offset into input buffer of the character : +; displayed directly above the position that : +; WR_CUCHAR is located on. : +; : +; WR_DNCHAR = Character offset into input buffer of the character : +; displayed directly below the position that : +; WR_CUCHAR is located on. : +; : +; WR_ENCHAR = Number of characters currently entered in the : +; field. This value may be less than the number : +; of bytes used to represent the characters if : +; double byte characters are present. : +; : +; WR_CURROW = Actual row offset into the video buffer of the : +; character specified by WR_CURCHAR. : +; : +; WR_CURCOL = Actual column offset into the video buffer of the : +; character specified by WR_CUCHAR. : +; : +; WR_ENBYTE = Number of bytes currently used to represent : +; entered characters in the buffer. This counter : +; can be used to calculate the current end : +; position of the entered data in the field. : +; : +; WR_CUBYTE = Number of bytes into input field where WR_CUCHAR : +; appears. : +; : ;=W +; WR_CUCHAR = Offset of current cursor position in input field. : ;=W +; : ;=W +; WR_HRBYTE = Number of bytes into input field where WR_HRCHAR : +; appears. : +; : +; WR_FIELDEND = Boolean flag, 0 = cursor not past end of field : ;=W +; 1 = cursor is past end of field : ;=W +; : +;-----------------------------------------------------------------------------+ +; +CAL_COORS PROC NEAR +; + PUSH AX ;save registers + PUSH BX + PUSH CX + PUSH DX + PUSH ES + PUSH SI + PUSH BP ;=W +; ;=W +; initialize general variables for all display modes ;=W +; + MOV [DI]+WR_FIELDEND,0 ;initialize boolean flag that ;=W + ;cursor is not past end of field ;=W + MOV AX,ES:[SI]+ICB_CURCHAR ;get current char. offset ;=W + MOV [DI]+WR_CUCHAR,AX ;save it ;=W +; + MOV AX,ES:[SI]+ICB_ROW ;initialize row offset of field ;=W + DEC AX ;=W + MOV [DI]+WR_CURROW,AX ;char row offset inot video buf ;=W + MOV AX,ES:[SI]+ICB_COL ;initialize col offset of field ;=W + DEC AX ;=W + MOV [DI]+WR_CURCOL,AX ;char col offset into video buf ;=W +; + MOV [DI]+WR_LFCHAR,1 ;leftmost character possible char ;=W + MOV [DI]+WR_RGCHAR,1 ;rightmost character possible char ;=W + MOV [DI]+WR_ENBYTE,0 ;end byte of data in input buffer ;=W + MOV [DI]+WR_ENCHAR,0 ;end character in input buffer ;=W + MOV [DI]+WR_HRBYTE,1 ;byte of first char in horz. window ;=W +; + MOV AX,[DI]+WR_CUCHAR ;get current position ;=W + MOV [DI]+WR_UPCHAR,1 ;topmost char in current column ;=W + MOV [DI]+WR_DNCHAR,1 ;bottommost char in current column ;=W +; + MOV BP,0 ;have not found current char yet ;=W + MOV CX,1 ;counter tracking number of bytes ;=W + MOV DX,1 ;counter tracking number of chars ;=W +; +; Determine display format of field +; + TEST ES:[SI]+ICB_OPT3,ICB_WIN ;check if windowing option on + JE CC10 +; + JMP CC200 ;process window option +; +CC10: TEST ES:[SI]+ICB_OPT3,ICB_HOR ;check if horizontal scroll option + JE CC20 ; on +; + JMP CC100 ;process horizontal scroll +; +; Process fully displayed horizontal field +; +CC20: ;=W + MOV [DI]+WR_HRCHAR,1 ;leftmost character possible char +; +; Examine the next byte in the input buffer +; +CC30: CMP CX,ES:[SI]+ICB_FIELDLEN ;check if entire field has been + JBE CC35 ; scanned and exit +; + CMP BP,0 ;found current char yet ? ;=W + JE CC40 ;no, find it ;=W + JMP CCEXIT +; +CC35: PUSH ES ;save registers + PUSH SI +; + PUSH ES:[SI]+ICB_FIELDSEG ;get segment of input buffer + PUSH ES:[SI]+ICB_FIELDOFF ;get offset of input buffer + POP SI + POP ES +; + DEC CX ;make byte count zero based + ADD SI,CX ;add byte count to input fld offst + INC CX ;make byte count one based + MOV AL,ES:[SI] ;get byte in input buffer to + MOV [DI]+DBC_KS,AL ; check if DBCS + CALL PCINDBC_CALL ;call routine to check if char + ; is lead double byte char +; + POP SI ;restore registers + POP ES +; +; Check if end data byte and character should be updated +; + CMP AL,WR_BLANK ;check if blanking character found + JE CC40 ;now adjust pointers +; + MOV [DI]+WR_ENBYTE,CX ;set current byte count + MOV [DI]+WR_ENCHAR,DX ;set current character count + MOV [DI]+WR_RGCHAR,DX ;set right most character +; +; Check if current character pointer +; +CC40: CMP [DI]+WR_CUCHAR,DX ;check if current character found + JNE CC50 +; + MOV BP,1 ;current char found ;=W + MOV [DI]+WR_UPCHAR,DX ;set up and down character + MOV [DI]+WR_DNCHAR,DX ; to current character +; + MOV [DI]+WR_CUBYTE,CX ;set current character byte count + ADD [DI]+WR_CURCOL,CX ;set actual column of cursor based + DEC [DI]+WR_CURCOL ; on current character byte count ;=W +; +; Increment pointers and counters to next character and byte position check +; +CC50: INC CX ;adjust byte counter + INC DX ;adjust character counter +; + TEST [DI]+DBC_STAT,DBC_DBCS ;check if byte is leading DBC byte + JE CC30 +; + INC CX ;adjust byte count for trail byte + JMP CC30 + + + + + +; +; Calculate horizontal scroll coordinates +; +CC100: + MOV AX,[DI]+WR_CUCHAR ;initialize current character + CMP AX,[DI]+WR_HRCHAR ;horizontal display position must + JAE CC120 ; not be less than current char + ; position + MOV [DI]+WR_HRCHAR,AX ;set current char position as + ; new horizontal position +; +; Examine the next byte in the input buffer +; +CC120: CMP CX,ES:[SI]+ICB_FIELDLEN ;check if entire field has been + JBE CC122 ; scanned and exit ;=W +; + CMP BP,0 ;found current char yet ? ;=W + JE CC130 ;no, find it ;=W +; + JMP CCEXIT ;=W +CC122: ;=W + PUSH ES ;save registers + PUSH SI +; + PUSH ES:[SI]+ICB_FIELDSEG ;get segment of input buffer + PUSH ES:[SI]+ICB_FIELDOFF ;get offset of input buffer + POP SI + POP ES +; + DEC CX ;make byte count zero based + ADD SI,CX ;add byte count to input fld offst + INC CX ;make byte count one based + MOV AL,ES:[SI] ;get byte in input buffer to + MOV [DI]+DBC_KS,AL ; check if DBCS + CALL PCINDBC_CALL ;call routine to check if char + ; is lead double byte char +; + POP SI ;restore registers + POP ES +; ;=W +; Set WR_HRBYTE to correct byte count ;=W +; ;=W + CMP [DI]+WR_HRCHAR,DX ;is this position the first char ;=W + ;in the horizl. window ? ;=W + JNE CC125 ;no ;=W +; + MOV [DI]+WR_HRBYTE,CX ;save # byte for first char in h. wind. ;=W +; +; Check if end data byte and character should be updated +; +CC125: CMP AL,WR_BLANK ;check if blanking character found + JE CC130 ;now adjust pointers +; + MOV [DI]+WR_ENBYTE,CX ;set current byte count + MOV [DI]+WR_ENCHAR,DX ;set current character count + MOV [DI]+WR_RGCHAR,DX ;set right most character +; +; Check if current character pointer +; +CC130: CMP [DI]+WR_CUCHAR,DX ;check if current character found + JNE CC140 +; + MOV BP,1 ;current char found + MOV [DI]+WR_UPCHAR,DX ;set up and down character + MOV [DI]+WR_DNCHAR,DX ; to current character +; + MOV [DI]+WR_CUBYTE,CX ;set current character byte count + MOV BX,CX ;set actual column of cursor based ;=W + ; on current character byte count ;=W + SUB BX,[DI]+WR_HRBYTE ;subtract beginning of horiz. wind. ;=W + ADD [DI]+WR_CURCOL,BX ;add to window offset = new column ;=W +; +; Increment pointers and counters to next character and byte position check +; +CC140: INC CX ;adjust byte counter + INC DX ;adjust character counter +; + TEST [DI]+DBC_STAT,DBC_DBCS ;check if byte is leading DBC byte + JE CC120 +; + INC CX ;adjust byte count for trail byte + JMP CC120 + + + + + +; +; Calculate windowing coordinates ;=W +; +CC200: ;=W +; +; Examine the next byte in the input buffer ;=W +; + CMP CX,ES:[SI]+ICB_FIELDLEN ;check if entire field has been ;=W + JBE CC235 ; scanned and exit ;=W +; + CMP BP,0 ;found current char yet ? ;=W + JE CC240 ;no, find it ;=W +; + JMP CCBYE ;boolean flag should have been set ;=W + ; already, if needed ;=W +CC235: PUSH ES ;save registers ;=W + PUSH SI ;=W +; + PUSH ES:[SI]+ICB_FIELDSEG ;get segment of input buffer ;=W + PUSH ES:[SI]+ICB_FIELDOFF ;get offset of input buffer ;=W + POP SI ;=W + POP ES ;=W +; + DEC CX ;make byte count zero based ;=W + ADD SI,CX ;add byte count to input fld offst ;=W + INC CX ;make byte count one based ;=W + MOV AL,ES:[SI] ;get byte in input buffer to ;=W + MOV [DI]+DBC_KS,AL ; check if DBCS ;=W + CALL PCINDBC_CALL ;call routine to check if char ;=W + ; is lead double byte char ;=W +; + POP SI ;restore registers ;=W + POP ES ;=W +; ;=W +; Check if end data byte and character should be updated ;=W +; ;=W + CMP AL,WR_BLANK ;check if blanking character found ;=W + JE CC240 ;now adjust pointers ;=W +; + MOV [DI]+WR_ENBYTE,CX ;set current byte count ;=W + MOV [DI]+WR_ENCHAR,DX ;set current character count ;=W + MOV [DI]+WR_RGCHAR,DX ;set right most character ;=W +; ;=W +; Check if current character pointer ;=W +; ;=W +CC240: + CMP [DI]+WR_CUCHAR,DX ;check if current character found ;=W + JNE CC250 ;no ;=W +; + MOV BP,1 ;found current char + MOV [DI]+WR_CUBYTE,CX ;set current character byte count ;=W +; + PUSH DX ;needed for division ;=W + MOV AX,CX ;get current cursor pos. in field ;=W + DEC AX ;make it zero based for divide ;=W +; + CMP CX,ES:[SI]+ICB_FIELDLEN ;are we past end of field ? ;=W + JLE CC241 ;no ;=W + MOV [DI]+WR_FIELDEND,1 ;yes, set boolean flag ;=W + DEC AX ;make cursor pos. be inside field ;=W + ; for division ;=W + CWD ;calculate current row,column ;=W + IDIV ES:[SI]+ICB_WIDTH ; row = cur_byte / width-1 ;=W + ; col = cur_byte mod width-1 ;=W + INC DX ;reposition cursor in correct pos. ;=W + JMP CC244 ;=W +CC241: ;=W + CWD ;calculate current row,column for ;=W + IDIV ES:[SI]+ICB_WIDTH ; cursor positions inside the field ;=W + ; row = cur_byte / width of field ;=W + ; col = cur_byte mod width of field ;=W +CC244: ;=W + ADD [DI]+WR_CURROW,AX ;set actual row of cursor ;=W + ADD [DI]+WR_CURCOL,DX ;set actual column of cursor ;=W +; + MOV BX,CX ;calculate WR_LFCHAR ;=W +CC245: DEC BX ;get the correct cur_byte ;=W + MOV AX,BX ;cur_byte/width ;=W + CWD ;=W + IDIV ES:[SI]+ICB_WIDTH ;=W + CMP DX,0 ;is the remainder zero ? ;=W + JNE CC245 ;no, not at beginning of row, do again ;=W +; + MOV [DI]+WR_LFCHAR,BX ;yes, this is beginning of row ;=W +; + POP DX ;=W +; +; Increment pointers and counters to next character and byte position check ;=W +; ;=W +CC250: INC CX ;adjust byte counter ;=W + INC DX ;adjust character counter ;=W +; + TEST [DI]+DBC_STAT,DBC_DBCS ;check if byte is leading DBC byte ;=W + JE CC260 ;=W +; + INC CX ;adjust byte count for trail byte ;=W +CC260: + JMP CC200 ;=W +; +; Exit +; +CCEXIT: ;=W + MOV AX,[DI]+WR_CUBYTE ;is cursor past end of field ;=W + CMP AX,ES:[SI]+ICB_FIELDLEN ;?? ;=W + JLE CCBYE ;no ;=W +; + MOV [DI]+WR_FIELDEND,1 ;yes, set boolean flag ;=W +CCBYE: + MOV AX,[DI]+WR_ENBYTE ;set ICB_ENDBYTE ;=W + MOV ES:[SI]+ICB_ENDBYTE,AX ;=W +; + MOV AX,[DI]+WR_HRBYTE ;set ICB_HRSTART ;=W + MOV ES:[SI]+ICB_HRSTART,AX ;=W +; + POP BP + POP SI ;restore registers + POP ES + POP DX ;restore registers + POP CX + POP BX + POP AX +; + RET +CAL_COORS ENDP +; +PAGE ;=W +;-----------------------------------------------------------------------------+ ;=W +; : ;=W +; SET_DISP_ADDR : ;=W +; : ;=W +; Determine which display routine to use. The choice is between : ;=W +; left justified, right justified, double byte support, no double : ;=W +; byte support, windowing, horizontal scrolling. : ;=W +; Also pick the justify routine to use. : ;=W +; : ;=W +; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ : ;=W +; ³ DISPLAY ³ : ;=W +; ÀÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÙ : ;=W +; ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄ¿ : ;=W +; ÚÄÄÄÄÁÄÄÄÄ¿ ³ ³ ÚÄÄÄÄÁÄÄÄÄÄ¿ ³ ³ : ;=W +; ³LEFT_DISP³ ³ ³ ³RIGHT_DISP³ ³ ³ : ;=W +; ÀÄÄÄÄÄÄÄÄÄÙ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÙ ³ ³ : ;=W +; ÚÄÄÄÄÄÁÄÄÄÄÄ¿ ³ ÚÄÄÄÄÄÄÁÄÄÄÄÄ¿ ³ : ;=W +; ³LEFT_H_DISP³ ³ ³RIGHT_H_DISP³ ³ : ;=W +; ÀÄÄÄÄÄÄÄÄÄÄÄÙ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ : ;=W +; ÚÄÄÄÄÄÁÄÄÄÄ¿ ÚÄÄÄÄÄÄÁÄÄÄÄ¿ : ;=W +; ³LEFTS_DISP³ ³RIGHTS_DISP³ : ;=W +; ÀÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÙ : ;=W +; : ;=W +; : ;=W +; : ;=W +; : ;=W +; : ;=W +; DISPLAY ROUTINES : ;=W +; LEFT_DISP - left justified, double byte support, windowing : ;=W +; LEFTS_DISP - left justified, no double byte support, windowing : ;=W +; LEFT_H_DISP - left justified, double byte support, horizontal scrolling : ;=W +; RIGHT_DISP - right justified, double byte support, windowing : ;=W +; RIGHTS_DISP - right justified, no double byte support, windowing : ;=W +; RIGHT_H_DISP - right justified, double byte support, horizontal scrolling : ;=W +; : ;=W +; JUSTIFY ROUTINES : ;=W +; LEFT_H_JUST - left justified, horizontal scrolling : ;=W +; LEFT_JUST - left justified, windowing : ;=W +; RIGHT_H_JUST - right justified, horizontal scrolling : ;=W +; RIGHT_JUST - right justified, windowing : ;=W +; : ;=W +; Entry: ES:SI - ICB control block : ;=W +; DS:DI - IN control block : ;=W +; Exit: none : ;=W +; : ;=W +;-----------------------------------------------------------------------------+ ;=W +; ;=W +SET_DISP_ADDR PROC NEAR ;=W +; + PUSH AX ;=W + PUSH BX ;=W +; + TEST ES:[SI]+ICB_OPT1,ICB_RJU ;check if field right just ;=W + JNE SD20 ;if yes, jump ;=W +; +; Display value of input buffer left justified ;=W +; + TEST ES:[SI]+ICB_OPT3,ICB_HOR ;check if field is in horizontial ;=W + JE SD10 ;no, windowing mode ;=W +; + MOV AX,OFFSET LEFT_H_DISP ;=W + MOV BX,OFFSET LEFT_H_JUST ;=W +; + JMP SDEXIT ;=W +SD10: ;=W + MOV AX,OFFSET LEFT_DISP ;=W + MOV BX,OFFSET LEFT_JUST ;=W +; + TEST DS:[DI]+IN_OPT,IN_ADBCS ;check if double byte is active ;=W + JNE SDEXIT ;yes ;=W + MOV AX,OFFSET LEFTS_DISP ;no, single byte only ;=W + JMP SDEXIT ;=W +; +; Display default value of input buffer right justified ;=W +; +SD20: ;=W + TEST ES:[SI]+ICB_OPT3,ICB_HOR ;check if field is in horizontial ;=W + JE SD30 ;no, windowing mode ;=W +; + MOV AX,OFFSET RIGHT_H_DISP ;=W + MOV BX,OFFSET RIGHT_H_JUST ;=W +; + JMP SDEXIT ;=W +SD30: ;=W + MOV AX,OFFSET RIGHT_DISP ;=W + MOV BX,OFFSET RIGHT_DISP ;=W +; + TEST DS:[DI]+IN_OPT,IN_ADBCS ;check if double byte is active ;=W + JNE SDEXIT ;yes ;=W + MOV AX,OFFSET RIGHTS_DISP ;no, single byte only ;=W +; +SDEXIT: ;=W + MOV DS:[DI]+WR_DISPLAY,AX ;save addr of routine to call ;=W + MOV DS:[DI]+WR_JUSTIFY,BX ;save addr of routine to call ;=W +; + POP BX ;=W + POP AX ;=W +; + RET ;=W +SET_DISP_ADDR ENDP ;=W +; +PAGE ;=W +;-----------------------------------------------------------------------------+ ;=W +; : ;=W +; RIGHTS_DISP : ;=W +; : ;=W +; Entry: : ;=W +; : ;=W +; Exit: : ;=W +; : ;=W +;-----------------------------------------------------------------------------+ ;=W +; ;=W +RIGHTS_DISP PROC NEAR ;=W +; ;=W + ; ;=W + ; code here ;=W + ; ;=W +; ;=W + RET ;=W +RIGHTS_DISP ENDP ;=W +; +PAGE +;-----------------------------------------------------------------------------+ +; : +; RIGHT_H_DISP : +; : +; Entry: : +; : +; Exit: : +; : +;-----------------------------------------------------------------------------+ +; +RIGHT_H_DISP PROC NEAR +; + ; + ; code here + ; +; + RET +RIGHT_H_DISP ENDP +; +PAGE ;=W +;-----------------------------------------------------------------------------+ ;=W +; : ;=W +; RIGHT_DISP : ;=W +; : ;=W +; Entry: : ;=W +; : ;=W +; Exit: : ;=W +; : ;=W +;-----------------------------------------------------------------------------+ ;=W +; ;=W +RIGHT_DISP PROC NEAR ;=W +; ;=W + ; ;=W + ; code here ;=W + ; ;=W +; ;=W + RET ;=W +RIGHT_DISP ENDP ;=W +; ;=W +PAGE ;=W +;-----------------------------------------------------------------------------+ ;=W +; : ;=W +; LEFT_H_DISP : ;=W +; : ;=W +; Calculates if the specified character will fit in the input : ;=W +; buffer at the specified character position without display. : ;=W +; The byte offset where this character should be inserted is : ;=W +; returned or a flag indicating that the character will not fit. : ;=W +; : ;=W +; Displays the specified portion of the input field buffer from : ;=W +; the left character marker to the end of the field. The following : ;=W +; display options are handled by this routine: : ;=W +; : ;=W +; - Display of the input field in a wrapped window : ;=W +; - Adjustment of double byte characters to prevent malformed : ;=W +; characters : ;=W +; : ;=W +; : ;=W +; The following pointers are used: : ;=W +; : ;=W +; ÚÄ (ICB_FIELDSEG:ICB_FIELDOFF) Beginning address of input : ;=W +; ³ buffer in memory. : ;=W +; ³ : ;=W +; ³ ÚÄ (WR_HRCHAR) Left marker delimiting the left : ;=W +; ³ ³ most character position in the : ;=W +; ³ ³ input buffer. : ;=W +; ³ ³ : ;=W +; ³ ³ : ;=W +; ³ ³ : ;=W +; ³ ³ : ;=W +; ³ ³ : ;=W +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W +; ³ S ³ L ³ T ³ L ³ T ³ S ³ L ³ T ³ S ³ S ³ S ³ S ³ ³ ³ : ;=W +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ : ;=W +; ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ : ;=W +; ³ ³ Area to display (ICB_WIDTH) : ;=W +; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ : ;=W +; ³ : ;=W +; ICB_FIELDLEN Length of input field in bytes. : ;=W +; : ;=W +; : ;=W +; Entry: ES:SI = Points to current ICB : ;=W +; DS:DI = Points to PB : ;=W +; : ;=W +; WR_CATTR = Logical color attribute to use when updating screen : ;=W +; if the use of the color attribute string is not : ;=W +; specified. : ;=W +; : ;=W +; CR_RCOFF = Beginning offset of the upper left input field : ;=W +; display corner from the beginning of the video : ;=W +; buffer. : ;=W +; : ;=W +; CR_SCRWIDTH = Width of the video buffer in characters and : ;=W +; attributes. : ;=W +; : ;=W +; WR_HRCHAR = The offset into the input buffer, in characters, : ;=W +; of where to begin display. : ;=W +; : ;=W +; Exit: (none) : ;=W +;-----------------------------------------------------------------------------+ ;=W +; ;=W +LEFT_H_DISP PROC NEAR ;=W +; + PUSH ES ;save PB pointers ;=W + PUSH DI ;=W + PUSH BX ;=W + PUSH [DI]+CR_RCOFF ;save input field display offset ;=W +; ;=W +; Initialize MOVEG parm block ;=W +; + MOV AX,ES:[SI]+ICB_FIELDOFF ;get offset of the input buffer ;=W + MOV [DI]+WR_FIELDOFF,AX ;=W + ;=W + MOV AX,ES:[SI]+ICB_FIELDSEG ;get segment of the input buffer ;=W + MOV [DI]+MG_TEXTSEG,AX ;=W + ;=W + MOV AX,ES:[SI]+ICB_ATTROFF ;get offset of color attribute buffer ;=W + MOV [DI]+MG_ATTOFF,AX ;=W + ;=W + MOV AX,ES:[SI]+ICB_ATTRSEG ;get segment of color attribute ;=W + MOV [DI]+MG_ATTSEG,AX ;buffer ;=W + ;=W + MOV AX,[DI]+IN_LVBSEG ;get segment of the LVB ;=W + MOV [DI]+MG_MIXSEG,AX ;=W + ;=W + MOV AL,[DI]+WR_CATTR ;get logical color attribute ;=W + MOV [DI]+MG_SOURCE_A,AL ;=W +; ;=W +; Display all characters in input buffer starting with WR_HRCHAR ;=W +; and continuing until ICB_WIDTH-1 number of characters has been displayed. ;=W +; + MOV AX,ES:[SI]+ICB_FIELDOFF ;calcuate beginning character ;=W + ADD AX,[DI]+WR_HRBYTE ;to display ;=W + DEC AX ;=W + MOV [DI]+WR_FIELDOFF,AX ;save it ;=W + MOV [DI]+MG_TEXTOFF,AX ; to display ;=W +; + MOV [DI]+MG_OPT,MG_WA+MG_SC+MG_UA ;=W + ;set write attribute option ;=W + ;set use logical attribute option ;=W + TEST ES:[SI]+ICB_OPT1,ICB_PSW ;check if password option active ;=W + JNE LHD10 ;=W +; + OR [DI]+MG_OPT,MG_WC ;set write character option ;=W +LHD10: ;=W + MOV AX,ES:[SI]+ICB_WIDTH ;get field width ;=W + MOV [DI]+MG_NUM,AX ;number of words to move into the ;=W + ; LVB ;=W +; + MOV AX,[DI]+IN_LVBOFF ;set the actual LVB offset of ;=W + ADD AX,[DI]+CR_RCOFF ; the character to write ;=W + MOV [DI]+MG_MIXOFF,AX ;=W +; + CALL PCMOVEG_CALL ;call PCMOVEG to write the char(s) ;=W +; ;=W +; Check if last character is DBCS ;=W +; ;=W + PUSH ES ;=W + PUSH SI ;=W +; + MOV AX,ES:[SI]+ICB_FIELDSEG ;get input buffer segment ;=W + MOV BX,ES:[SI]+ICB_FIELDOFF ;get input buffer offset ;=W + ADD BX,[DI]+WR_HRBYTE ;add offset of beginning of window ;=W + ADD BX,ES:[SI]+ICB_WIDTH ;add width to get last character ;=W + SUB BX,2 ;subtract to get correct byte ;=W + MOV ES,AX ;=W + MOV SI,BX ;=W + MOV AL,ES:[SI] ;get the character ;=W +; + POP SI ;=W + POP ES ;=W +; + PUSH AX ;=W + MOV [DI]+DBC_KS,AL ;=W + CALL PCINDBC_CALL ;check if char is lead DBCS ;=W + POP AX ;=W + TEST [DI]+DBC_STAT,DBC_DBCS ;is it ? ;=W + JE LHD30 ;no, display the character ;=W +; + MOV AL,1DH ;display '', can't split DBCS char ;=W +; ;=W +; Display the last character ;=W +; ;=W +LHD30: ;=W + MOV [DI]+MG_OPT,MG_WA+MG_SC+MG_UA ;=W + ;set write attribute option ;=W + ;set use logical attribute option ;=W + TEST ES:[SI]+ICB_OPT1,ICB_PSW ;check if password option active ;=W + JNE LHD40 ;=W +; + OR [DI]+MG_OPT,MG_WC+MG_UC ;set write character option ;=W +LHD40: ;=W + MOV [DI]+MG_SOURCE_C,AL ;character to display ;=W + MOV [DI]+MG_NUM,1 ;number of words to move into the ;=W + ; LVB ;=W +; + MOV AX,ES:[SI]+ICB_WIDTH ;add width to get last character ;=W + MOV BX,2 ;=W + MUL BX ;x2 to account for attr. bytes ;=W + ADD AX,[DI]+IN_LVBOFF ;set the actual LVB offset of ;=W + ADD AX,[DI]+CR_RCOFF ; the character to write ;=W + SUB AX,2 ;subtract to get correct byte ;=W + MOV [DI]+MG_MIXOFF,AX ;=W +; + CALL PCMOVEG_CALL ;call PCMOVEG to write the char(s) ;=W +LHDEXIT: ;=W + POP [DI]+CR_RCOFF ;save input field display offset ;=W + POP BX ;restore registers ;=W + POP DI ;=W + POP ES ;=W +; + RET ;=W +LEFT_H_DISP ENDP ;=W +; +PAGE +;-----------------------------------------------------------------------------+ +; : +; LEFT_DISP : +; : +; Calculates if the specified character will fit in the input : +; buffer at the specified character position without display. : +; The byte offset where this character should be inserted is : +; returned or a flag indicating that the character will not fit. : +; : +; Displays the specified portion of the input field buffer from : +; the left character marker to the end of the field. The following : +; display options are handled by this routine: : +; : +; - Display of the input field in a wrapped window : +; - Adjustment of double byte characters to prevent malformed : +; characters : +; : +; : +; The following pointers are used: : +; : +; ÚÄ (ICB_FIELDSEG:ICB_FIELDOFF) Beginning address of input : +; ³ buffer in memory. : +; ³ : +; ³ ÚÄ (WR_LEFTCHAR) Left marker delimiting the left : +; ³ ³ most character position in the : +; ³ ³ input buffer. : +; ³ ³ : +; ³ ³ Right marker delimiting the right : +; ³ ³ most character position in the : +; ³ ³ input buffer. (WR_RIGHTCHAR) : +; ³ ³ ³ : +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : +; ³ S ³ L ³ T ³ L ³ T ³ S ³ L ³ T ³ S ³ S ³ S ³ S ³ ³ ³ : +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ : +; ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ : +; ³ ³ Area to display : +; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ : +; ³ : +; ICB_FIELDLEN Length of input field in bytes. : +; : +; : +; Entry: ES:SI = Points to current ICB : +; DS:DI = Points to PB : +; : +; AX 1 = This option will calculate if the specified number : +; of bytes in BX can fit into input buffer at the : +; specified character position considering the display : +; coordinates and options. No update of the display : +; screen will occur. A flag indicating if the bytes : +; can be inserted or not is returned. If the bytes : +; will fit the offset from the beginning of the input : +; field in bytes is returned indicating where the : +; characters should be inserted. : +; : +; 2 = This option will update the display screen in the : +; proper format with the input buffer characters : +; starting at the specified left offset character : +; to the right character marker. : +; : +; BX = Number of bytes to insert starting at the specified : +; character position. : +; : +; WR_CATTR = Logical color attribute to use when updating screen : +; if the use of the color attribute string is not : +; specified. : +; : +; CR_RCOFF = Beginning offset of the upper left input field : +; display corner from the beginning of the video : +; buffer. : +; : +; CR_SCRWIDTH = Width of the video buffer in characters and : +; attributes. : +; : +; WR_LEFTCHAR = The offset into the input buffer, in characters, : +; of where the specified bytes should fit. : +; : +; WR_RIGHTCHAR = The offset into the input buffer, in characters, : +; of where the right most character position. : +; : +; : +; Exit: If AX on entry is set to 1 then on exit: : +; : +; AX 0 = The specified number of characters will fit. : +; 1 = The specified number of characters will not fit. : +; : +; WR_LEFTBYTE = The offset into the input buffer, in bytes, of the : +; left most character position. : +; : +; WR_RIGHTBYTE = The offset into the input buffer, in bytes, of the : +; right most character position. : +; : +; : +; If AX on entry is set to 2 then the input field buffer is : +; displayed on the screen. : +; : +;-----------------------------------------------------------------------------+ +; +LEFT_DISP PROC NEAR +; + PUSH ES ;save PB pointers + PUSH DI + PUSH BX + PUSH [DI]+CR_RCOFF ;save input field display offset +; + CALL LEFT_DISP_INIT ;initialize internal counter & vars ;=W +; + JMP LF20 ;begin of first row +; +; Start a new row in LVB +; +LF10: MOV AX,[DI]+CR_RCOFF ;set ptr into LVB to next row. + ADD AX,[DI]+CR_SCRWIDTH ; Start with current position in + SUB AX,ES:[SI]+ICB_WIDTH ; LVB, add screen width in text + SUB AX,ES:[SI]+ICB_WIDTH ; and attributes, then subtract + MOV [DI]+CR_RCOFF,AX ; the length of the input field + ; twice since length is just in + ; text chars +; +; Do not start new row +; +LF20: MOV AX,ES:[SI]+ICB_WIDTH ;counter contains number of bytes + MOV [DI]+WR_CNTR2,AX ; available in current row of + ; input field +; +; Prepare to place next byte into LVB, verify chars remaining in input buffer +; +LF30: MOV AX,[DI]+WR_CNTR3 ;check if last character has been + CMP [DI]+WR_RIGHTCHAR,AX ; written in LVB (rightmost) + JGE LF40 ;if not last char jump ? +; + JMP LF160 ;yes, last character written + ; prepare to exit +; +; Check if end of field on display has been reached +; +LF40: MOV AX,ES:[SI]+ICB_FIELDLEN ;loop if number chars moved is + CMP [DI]+WR_CNTR1,AX ; less than input buffer length + JLE LF50 ; +; + JMP LF160 +; +; Not complete +; +LF50: CMP [DI]+WR_CNTR2,0 ;loop while number of bytes + JE LF10 ; remaining in the row is greater + ; than zero, jump if bytes avail +; + CMP [DI]+WR_MOVE,1 ;check if entry option is to + JNE LF60 ; determine if bytes may be + ; inserted in displayed field +; + MOV AX,[DI]+WR_LEFTCHAR ;check if insertion calculations + CMP [DI]+WR_CNTR3,AX ; should begin by comparing + JNE LF60 ; current counter with beginning + ; left character marker +; + MOV AL,1 ;check if insertion calculations + CMP [DI]+WR_INSDONE,AL ; are complete + JE LF60 ;if yes, jump +; +; Adjust counters after pretending to insert a character into string and LVB +; + MOV AX,[DI]+WR_BYTESINST ;dec number bytes avail in row + ADD [DI]+WR_CNTR1,AX ;inc number bytes moved into LVB + SUB [DI]+WR_CNTR2,AX ;dec number bytes remaining in row + MOV [DI]+WR_INSDONE,1 ;set flag indicating insert calc + JMP LF30 ; complete +; +; Determine if current byte is a DBCS lead byte +; +LF60: MOV BX,[DI]+WR_FIELDOFF ;get the current byte in the +; + PUSH ES ;save registers + PUSH SI +; + PUSH ES:[SI]+ICB_FIELDSEG ; input field buffer + PUSH [DI]+WR_FIELDOFF ;get the current byte in the + POP SI + POP ES +; + MOV AL,ES:[SI] ;get character in input buffer +; + POP SI ;restore registers + POP ES +; + MOV [DI]+DBC_KS,AL +; + CALL PCINDBC_CALL ;call routine to check if char + ; is lead double byte char +; + TEST [DI]+DBC_STAT,DBC_DBCS ;check if char is lead DBCS + JNE LF70 ;if yes, jump to double byte code +; + JMP LF130 ;if no, jump to single byte code +; +; Current byte is leading byte of a double byte character +; +LF70: CMP [DI]+WR_CNTR2,1 ;check if there is room in current + JNE LF80 ; row for double byte character +; + JMP LF110 ;no room, adjust to next row +; +; Double byte character fits on current row +; +LF80: CMP [DI]+WR_MOVE,2 ;check if option to actually + JNE LF100 ; update display is active +; + MOV AX,[DI]+WR_LEFTCHAR ;check if character should be + CMP [DI]+WR_CNTR3,AX ; displayed by verifying that + JL LF100 ; current character falls + ; between the left and right + MOV AX,[DI]+WR_RIGHTCHAR ; character markers + CMP [DI]+WR_CNTR3,AX + JG LF100 +; + MOV AX,[DI]+WR_FIELDOFF ;get offset of character(s) + MOV [DI]+MG_TEXTOFF,AX ; to display +; + MOV [DI]+MG_OPT,MG_WA+MG_SC ;set write attribute option +; + TEST ES:[SI]+ICB_OPT1,ICB_USC ;use attribute string + JNE LF84 +; + OR [DI]+MG_OPT,MG_UA ;set use logical attribute option +; +LF84: TEST ES:[SI]+ICB_OPT1,ICB_PSW ;is option for password write + JNE LF85 ; active +; + OR [DI]+MG_OPT,MG_WC ;set write character option +; +LF85: MOV [DI]+MG_NUM,2 ;number of words to move into LVB + MOV AX,[DI]+IN_LVBOFF ;set actual offset into LVB + ADD AX,[DI]+CR_RCOFF ; where character(s) will be + MOV [DI]+MG_MIXOFF,AX ; written +; + CALL PCMOVEG_CALL ;call PCMOVEG to write characters +; +; Adjust pointers and counters after moving double byte character +; +LF100: MOV AX,[DI]+WR_CNTR3 ;LEFT returns the right and left + CMP AX,[DI]+WR_LEFTCHAR ; byte positions of the right and + JNE LF104 ; left chars. See if the current +; + MOV AX,[DI]+WR_CNTR4 ; char is the left char, if so + MOV [DI]+WR_LEFTBYTE,AX ; store the byte offset, WR_CNTR4, + JMP LF106 ; into WR_LEFTBYTE +; +; Update right byte marker +; +LF104: MOV AX,[DI]+WR_CNTR3 ;LEFT returns the right and left + CMP AX,[DI]+WR_RIGHTCHAR ; byte positions of the right and + JNE LF106 ; left chars. See if the current +; + MOV AX,[DI]+WR_CNTR4 ; char is the right char, if so + MOV [DI]+WR_RIGHTBYTE,AX ; store the byte offset, WR_CNTR4, + ; into WR_RIGHTBYTE +; +LF106: ADD [DI]+WR_FIELDOFF,2 ;inc number bytes moved from input + ; buffer + ADD [DI]+CR_RCOFF,4 ;inc pointer into LVB + ADD [DI]+WR_CNTR1,2 ;inc number of bytes moved into + ; LVB + SUB [DI]+WR_CNTR2,2 ;dec number of bytes remain + INC [DI]+WR_CNTR3 ;inc number of characters moved + ; into LVB from input string + ADD [DI]+WR_CNTR4,2 ;inc number of bytes moved from + JMP LF30 ; input string +; +; Blank fill remaining screen character positions on current row to prevent +; double byte character from being split +; +LF110: CMP [DI]+WR_MOVE,2 ;check if option to update display + JNE LF120 ; is active +; + MOV AX,[DI]+WR_LEFTCHAR ;check if current character + CMP [DI]+WR_CNTR3,AX ; should be displayed by verifying + JL LF120 ; that the character falls + ; within the left and right + MOV AX,[DI]+WR_RIGHTCHAR ; character markers + CMP [DI]+WR_CNTR3,AX + JG LF120 +; + MOV AL,WR_BLANK ;get blanking character + MOV [DI]+MG_SOURCE_C,AL +; + MOV [DI]+MG_OPT,MG_WA+MG_SC+MG_UC + ;set write attr, char and syn chk + TEST ES:[SI]+ICB_OPT1,ICB_USC + JNE LF114 ;use attribute string +; + OR [DI]+MG_OPT,MG_UA ;set use logical attribute option +; +LF114: TEST ES:[SI]+ICB_OPT1,ICB_PSW ;check if password option active + JNE LF115 +; + OR [DI]+MG_OPT,MG_WC ;set write character option +; +LF115: MOV [DI]+MG_NUM,1 ;number of words to move into the + ; LVB + MOV AX,[DI]+IN_LVBOFF ;set the actual LVB offset of + ADD AX,[DI]+CR_RCOFF ; the character to write + MOV [DI]+MG_MIXOFF,AX +; + CALL PCMOVEG_CALL ;call PCMOVEG to write the char(s) +; +; Adjust pointers and counters after writing blanking character to LVB +; +LF120: ADD [DI]+CR_RCOFF,2 ;inc pointer into the LVB + INC [DI]+WR_CNTR1 ;inc number of bytes moved into + ; the LVB + DEC [DI]+WR_CNTR2 ;dec number of bytes remaining in + JMP LF10 ; the current row +; +; Byte is a single byte character +; +LF130: CMP [DI]+WR_MOVE,2 ;check if option to update display + JNE LF150 ; is active +; + MOV AX,[DI]+WR_LEFTCHAR ;check if current character + CMP [DI]+WR_CNTR3,AX ; should be displayed by verifying + JL LF150 ; that the character falls +; + MOV AX,[DI]+WR_RIGHTCHAR ; character markers + CMP [DI]+WR_CNTR3,AX + JG LF150 +; + MOV AX,[DI]+WR_FIELDOFF ;get offset of character(s) + MOV [DI]+MG_TEXTOFF,AX ; to display +; + MOV [DI]+MG_OPT,MG_WA+MG_SC+MG_UA + ;set write attribute option + ;set use logical attribute option + TEST ES:[SI]+ICB_OPT1,ICB_PSW ;check if password option active + JNE LF135 +; + OR [DI]+MG_OPT,MG_WC ;set write character option +; +LF135: MOV [DI]+MG_NUM,1 ;number of words to move into the + ; LVB +; + MOV AX,[DI]+IN_LVBOFF ;set the actual LVB offset of + ADD AX,[DI]+CR_RCOFF ; the character to write + MOV [DI]+MG_MIXOFF,AX +; + CALL PCMOVEG_CALL ;call PCMOVEG to write the char(s) +; +; Adjust pointers and counters after moving single byte character +; +LF150: MOV AX,[DI]+WR_CNTR3 ;LEFT returns the right and left + CMP AX,[DI]+WR_LEFTCHAR ; byte positions of the right and + JNE LF154 ; left chars. See if the current +; + MOV AX,[DI]+WR_CNTR4 ; char is the left char, if so + MOV [DI]+WR_LEFTBYTE,AX ; store the byte offset, WR_CNTR4, + JMP LF156 ; into WR_LEFTBYTE +; +; Update right byte marker +; +LF154: MOV AX,[DI]+WR_CNTR3 ;LEFT returns the right and left + CMP AX,[DI]+WR_RIGHTCHAR ; byte positions of the right and + JNE LF156 ; left chars. See if the current +; + MOV AX,[DI]+WR_CNTR4 ; char is the right char, if so + MOV [DI]+WR_RIGHTBYTE,AX ; store the byte offset, WR_CNTR4, + ; into WR_RIGHTBYTE +; +LF156: INC [DI]+WR_FIELDOFF ;inc pointer input buffer + ADD [DI]+CR_RCOFF,2 ;inc pointer into LVB + INC [DI]+WR_CNTR1 ;inc counter with number bytes + ; moved into LVB + DEC [DI]+WR_CNTR2 ;dec counter with number of bytes + ; remaining in current row + ADD [DI]+WR_CNTR3,1 ;inc counter with number of chars + ; moved into the LVB from input + ; buffer + ADD [DI]+WR_CNTR4,1 ;inc counter with number of bytes + JMP LF30 ; moved into the LVB from input + ; buffer +; +; Completed updating LVB, adjust pointers +; +LF160: CMP [DI]+WR_MOVE,1 ;Check if option to calculate + JNE LFEXIT ; if chars fit in buffer +; +; Set up proper return values for insert calculation +; + MOV AX,1 ;set flag indicating insert did + ; not fit + MOV BX,[DI]+WR_CNTR3 ;see if input field fit into LVB + DEC BX ; by comparing the right char + CMP [DI]+WR_RIGHTCHAR,BX ; number with the number of chars + JNE LFEXIT ; moved into the LVB. If they + ; are equal the string fit into + ; the LVB. + CMP [DI]+WR_INSDONE,1 ;see if insert has been done + JE LF170 ;if yes set up return values +; + MOV BX,ES:[SI]+ICB_FIELDLEN ;if no, then insert is at end of + SUB BX,[DI]+WR_CNTR1 ; line i.e. past right char + INC BX ;see if there is enough room left + CMP BX,[DI]+WR_BYTESINST ; to display char being inserted + JL LFEXIT +; +LF170: MOV AX,0 ;set flag indicating insert fits +; +; Restores the registers to entry values and exits +; +LFEXIT: POP [DI]+CR_RCOFF ;save input field display offset +; + POP BX ;restore registers + POP DI + POP ES +; + RET +LEFT_DISP ENDP +; +PAGE +;-----------------------------------------------------------------------------+ ;=W +; : ;=W +; LEFTS_DISP (no double byte support) : ;=W +; : ;=W +; Calculates if the specified character will fit in the input : ;=W +; buffer at the specified character position without display. : ;=W +; The byte offset where this character should be inserted is : ;=W +; returned or a flag indicating that the character will not fit. : ;=W +; : ;=W +; Displays the specified portion of the input field buffer from : ;=W +; the left character marker to the end of the field. The following : ;=W +; display options are handled by this routine: : ;=W +; : ;=W +; - Display of the input field in a wrapped window : ;=W +; - Adjustment of double byte characters to prevent malformed : ;=W +; characters : ;=W +; : ;=W +; : ;=W +; The following pointers are used: : ;=W +; : ;=W +; ÚÄ (ICB_FIELDSEG:ICB_FIELDOFF) Beginning address of input : ;=W +; ³ buffer in memory. : ;=W +; ³ : ;=W +; ³ ÚÄ (WR_LEFTCHAR) Left marker delimiting the left : ;=W +; ³ ³ most character position in the : ;=W +; ³ ³ input buffer. : ;=W +; ³ ³ : ;=W +; ³ ³ Right marker delimiting the right : ;=W +; ³ ³ most character position in the : ;=W +; ³ ³ input buffer. (WR_RIGHTCHAR) : ;=W +; ³ ³ ³ : ;=W +; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W +; ³ S ³ L ³ T ³ L ³ T ³ S ³ L ³ T ³ S ³ S ³ S ³ S ³ ³ ³ : ;=W +; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ : ;=W +; ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ : ;=W +; ³ ³ Area to display : ;=W +; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ : ;=W +; ³ : ;=W +; ICB_FIELDLEN Length of input field in bytes. : ;=W +; : ;=W +; : ;=W +; Entry: ES:SI = Points to current ICB : ;=W +; DS:DI = Points to PB : ;=W +; : ;=W +; AX 1 = This option will calculate if the specified number : ;=W +; of bytes in BX can fit into input buffer at the : ;=W +; specified character position considering the display : ;=W +; coordinates and options. No update of the display : ;=W +; screen will occur. A flag indicating if the bytes : ;=W +; can be inserted or not is returned. If the bytes : ;=W +; will fit the offset from the beginning of the input : ;=W +; field in bytes is returned indicating where the : ;=W +; characters should be inserted. : ;=W +; : ;=W +; 2 = This option will update the display screen in the : ;=W +; proper format with the input buffer characters : ;=W +; starting at the specified left offset character : ;=W +; to the right character marker. : ;=W +; : ;=W +; BX = Number of bytes to insert starting at the specified : ;=W +; character position. : ;=W +; : ;=W +; WR_CATTR = Logical color attribute to use when updating screen : ;=W +; if the use of the color attribute string is not : ;=W +; specified. : ;=W +; : ;=W +; CR_RCOFF = Beginning offset of the upper left input field : ;=W +; display corner from the beginning of the video : ;=W +; buffer. : ;=W +; : ;=W +; CR_SCRWIDTH = Width of the video buffer in characters and : ;=W +; attributes. : ;=W +; : ;=W +; WR_LEFTCHAR = The offset into the input buffer, in characters, : ;=W +; of where the specified bytes should fit. : ;=W +; : ;=W +; WR_RIGHTCHAR = The offset into the input buffer, in characters, : ;=W +; of where the right most character position. : ;=W +; : ;=W +; : ;=W +; Exit: If AX on entry is set to 1 then on exit: : ;=W +; : ;=W +; AX 0 = The specified number of characters will fit. : ;=W +; 1 = The specified number of characters will not fit. : ;=W +; : ;=W +; WR_LEFTBYTE = The offset into the input buffer, in bytes, of the : ;=W +; left most character position. : ;=W +; : ;=W +; WR_RIGHTBYTE = The offset into the input buffer, in bytes, of the : ;=W +; right most character position. : ;=W +; : ;=W +; : ;=W +; If AX on entry is set to 2 then the input field buffer is : ;=W +; displayed on the screen. : ;=W +; : ;=W +;-----------------------------------------------------------------------------+ ;=W +; ;=W +LEFTS_DISP PROC NEAR ;=W +; + PUSH ES ;save PB pointers ;=W + PUSH DI ;=W + PUSH BX ;=W + PUSH [DI]+CR_RCOFF ;save input field display offset ;=W +; + CALL LEFT_DISP_INIT ;initialize internal counters & vars ;=W +; + JMP LS20 ;begin of first row ;=W +; ;=W +; Start a new row in LVB ;=W +; ;=W +LS10: MOV AX,[DI]+CR_RCOFF ;set ptr into LVB to next row. ;=W + ADD AX,[DI]+CR_SCRWIDTH ; Start with current position in ;=W + SUB AX,ES:[SI]+ICB_WIDTH ; LVB, add screen width in text ;=W + SUB AX,ES:[SI]+ICB_WIDTH ; and attributes, then subtract ;=W + MOV [DI]+CR_RCOFF,AX ; the length of the input field ;=W + ; twice since length is just in ;=W + ; text chars ;=W +; ;=W +; Do not start new row ;=W +; ;=W +LS20: MOV AX,ES:[SI]+ICB_WIDTH ;counter contains number of bytes ;=W + MOV [DI]+WR_CNTR2,AX ; available in current row of ;=W + ; input field ;=W +; ;=W +; Prepare to place next byte into LVB, verify chars remaining in input buffer ;=W +; ;=W +LS30: MOV AX,[DI]+WR_CNTR3 ;check if last character has been ;=W + CMP [DI]+WR_RIGHTCHAR,AX ; written in LVB (rightmost) ;=W + JGE LS40 ;if not last char jump ? ;=W +; + JMP LS160 ;yes, last character written ;=W + ; prepare to exit ;=W +; ;=W +; Check if end of field on display has been reached ;=W +; ;=W +LS40: MOV AX,ES:[SI]+ICB_FIELDLEN ;loop if number chars moved is ;=W + CMP [DI]+WR_CNTR1,AX ; less than input buffer length ;=W + JLE LS50 ; ;=W +; + JMP LS160 ;=W +; ;=W +; Not complete ;=W +; ;=W +LS50: CMP [DI]+WR_CNTR2,0 ;loop while number of bytes ;=W + JE LS10 ; remaining in the row is greater ;=W + ; than zero, jump if bytes avail ;=W +; + CMP [DI]+WR_MOVE,1 ;check if entry option is to ;=W + JNE LS130 ; determine if bytes may be ;=W + ; inserted in displayed field ;=W +; + MOV AX,[DI]+WR_LEFTCHAR ;check if insertion calculations ;=W + CMP [DI]+WR_CNTR3,AX ; should begin by comparing ;=W + JNE LS130 ; current counter with beginning ;=W + ; left character marker ;=W +; + MOV AL,1 ;check if insertion calculations ;=W + CMP [DI]+WR_INSDONE,AL ; are complete ;=W + JE LS130 ;if yes, jump ;=W +; ;=W +; Adjust counters after pretending to insert a character into string and LVB ;=W +; ;=W + MOV AX,[DI]+WR_BYTESINST ;dec number bytes avail in row ;=W + ADD [DI]+WR_CNTR1,AX ;inc number bytes moved into LVB ;=W + SUB [DI]+WR_CNTR2,AX ;dec number bytes remaining in row ;=W + MOV [DI]+WR_INSDONE,1 ;set flag indicating insert calc ;=W + JMP LS30 ; complete ;=W +; ;=W +; Byte is a single byte character ;=W +; ;=W +LS130: CMP [DI]+WR_MOVE,2 ;check if option to update display ;=W + JNE LS150 ; is active ;=W +; + MOV AX,[DI]+WR_LEFTCHAR ;check if current character ;=W + CMP [DI]+WR_CNTR3,AX ; should be displayed by verifying ;=W + JL LS150 ; that the character falls ;=W + ; within the left and right ;=W + MOV AX,[DI]+WR_RIGHTCHAR ; character markers ;=W + CMP [DI]+WR_CNTR3,AX ;=W + JG LS150 ;=W +; + MOV AX,[DI]+WR_FIELDOFF ;get offset of character(s) ;=W + MOV [DI]+MG_TEXTOFF,AX ; to display ;=W +; + MOV [DI]+MG_OPT,MG_WA+MG_SC+MG_UA ;=W + ;set write attribute option ;=W + ;set use logical attribute option ;=W + TEST ES:[SI]+ICB_OPT1,ICB_PSW ;check if password option active ;=W + JNE LS135 ;=W +; + OR [DI]+MG_OPT,MG_WC ;set write character option ;=W +; +LS135: MOV [DI]+MG_NUM,1 ;number of words to move into the ;=W + ; LVB ;=W +; + MOV AX,[DI]+IN_LVBOFF ;set the actual LVB offset of ;=W + ADD AX,[DI]+CR_RCOFF ; the character to write ;=W + MOV [DI]+MG_MIXOFF,AX ;=W +; + CALL PCMOVEG_CALL ;call PCMOVEG to write the char(s) ;=W +; ;=W +; Adjust pointers and counters after moving single byte character ;=W +; ;=W +LS150: MOV AX,[DI]+WR_CNTR3 ;LEFT returns the right and left ;=W + CMP AX,[DI]+WR_LEFTCHAR ; byte positions of the right and ;=W + JNE LS154 ; left chars. See if the current ;=W +; + MOV AX,[DI]+WR_CNTR4 ; char is the left char, if so ;=W + MOV [DI]+WR_LEFTBYTE,AX ; store the byte offset, WR_CNTR4, ;=W + JMP LS156 ; into WR_LEFTBYTE ;=W +; ;=W +; Update right byte marker ;=W +; ;=W +LS154: MOV AX,[DI]+WR_CNTR3 ;LEFT returns the right and left ;=W + CMP AX,[DI]+WR_RIGHTCHAR ; byte positions of the right and ;=W + JNE LS156 ; left chars. See if the current ;=W +; + MOV AX,[DI]+WR_CNTR4 ; char is the right char, if so ;=W + MOV [DI]+WR_RIGHTBYTE,AX ; store the byte offset, WR_CNTR4, ;=W + ; into WR_RIGHTBYTE ;=W +LS156: INC [DI]+WR_FIELDOFF ;inc pointer input buffer ;=W + ADD [DI]+CR_RCOFF,2 ;inc pointer into LVB ;=W + INC [DI]+WR_CNTR1 ;inc counter with number bytes ;=W + ; moved into LVB ;=W + DEC [DI]+WR_CNTR2 ;dec counter with number of bytes ;=W + ; remaining in current row ;=W + ADD [DI]+WR_CNTR3,1 ;inc counter with number of chars ;=W + ; moved into the LVB from input ;=W + ; buffer ;=W + ADD [DI]+WR_CNTR4,1 ;inc counter with number of bytes ;=W + JMP LS30 ; moved into the LVB from input ;=W + ; buffer ;=W +; ;=W +; Completed updating LVB, adjust pointers ;=W +; ;=W +LS160: CMP [DI]+WR_MOVE,1 ;Check if option to calculate ;=W + JNE LSEXIT ; if chars fit in buffer ;=W +; ;=W +; Set up proper return values for insert calculation ;=W +; ;=W + MOV AX,1 ;set flag indicating insert did ;=W + ; not fit ;=W + MOV BX,[DI]+WR_CNTR3 ;see if input field fit into LVB ;=W + DEC BX ; by comparing the right char ;=W + CMP [DI]+WR_RIGHTCHAR,BX ; number with the number of chars ;=W + JNE LSEXIT ; moved into the LVB. If they ;=W + ; are equal the string fit into ;=W + ; the LVB. ;=W + CMP [DI]+WR_INSDONE,1 ;see if insert has been done ;=W + JE LS170 ;if yes set up return values ;=W +; + MOV BX,ES:[SI]+ICB_FIELDLEN ;if no, then insert is at end of ;=W + SUB BX,[DI]+WR_CNTR1 ; line i.e. past right char ;=W + INC BX ;see if there is enough room left ;=W + CMP BX,[DI]+WR_BYTESINST ; to display char being inserted ;=W + JL LSEXIT ;=W +; +LS170: MOV AX,0 ;set flag indicating insert fits ;=W +; ;=W +; Restores the registers to entry values and exits ;=W +; ;=W +LSEXIT: POP [DI]+CR_RCOFF ;save input field display offset ;=W +; + POP BX ;restore registers ;=W + POP DI ;=W + POP ES ;=W +; + RET ;=W +LEFTS_DISP ENDP ;=W +; +PAGE +;-----------------------------------------------------------------------------+ ;=W +; : ;=W +; DRAW_DEM : ;=W +; Draw a input field delimiter : ;=W +; : ;=W +; Entry: : ;=W +; ES:SI address of icon : ;=W +; GC_ROW - character row to display delimiter : ;=W +; GC_COL - character column to display delimiter : ;=W +; : ;=W +; Exit: None : ;=W +; : ;=W +;-----------------------------------------------------------------------------+ ;=W +DRAW_DEM PROC NEAR ;=W +; + PUSH AX ;=W + PUSH BX ;=W + PUSH CX ;=W + PUSH DX ;=W + PUSH DI ;=W + PUSH SI ;=W + PUSH DS ;=W + PUSH ES ;=W + PUSH BP ;=W +; + MOV BP,AX +; + MOV DX,300H + graph_addr ;=W + MOV AH,2 ; Write Mode 2 ;=W + MOV AL,5 ; Write Mode Register ;=W + OUT DX,AX ;=W +; + MOV DL,seq_addr ;=W + MOV AH,0FFH ;enable all maps ;=W + MOV AL,s_map ;map mask ;=W + OUT DX,AX ;set the registers ;=W +; + MOV AX,[DI]+WR_ROWBYTES ;=W + MOV BX,50H ;=W + MUL BX ;=W + ;=W + MOV BX,[DI]+GC_ROW ;=W + MUL BX ;=W + ADD AX,[DI]+GC_COL ;=W +; + MOV BH,[DI]+WR_CATTR ;get current color attribute ;=W +; + CMP [DI]+WR_VIDMODE,11H ;check for graphics mode 11H + JNE DD05 ;nop, continue + MOV BH,0FH ;yes, mode 11 is only black & +; +DD05: MOV CL,4 ;count for shift ;=W + SHR BX,CL ;separate background/foreground ;=W + MOV CL,4 ;count for shift ;=W + SHR BL,CL ;put in low order nibble ;=W + XCHG BL,BH ;foreground/background are reversed ;=W + ; for delimiter +; BL = background color, BH = foreground color + CMP BP,02 ;check if we want to remove delimiters ;=W + JNE DD10 ;no, ok ;=W + MOV BH,BL ;make both background color ;=W + ;=W +DD10: ;=W + MOV CL,[DI]+WR_VIDMODE ;=W + MOV DX,[DI]+IN_OPT +; + PUSH ES ;make DS:SI point to bit maps ;=W + POP DS ;=W +; + MOV DI,AX ;=W + MOV AX,0A000H ;=W + MOV ES,AX ;=W +; + TEST DX,IN_MCGA ;mode 11H, non-VGA hardware? + JNE DD100 ;if so, go do it +;--------------------------------------------- ;=W +; Mode 10,11,12 with VGA : ;=W +;--------------------------------------------- ;=W + MOV DX,300H + graph_addr ;graphics chip ;=W + XOR CH,CH ;=W +; + MOV AL,CL ;save vid mode + MOV CL,0EH ;# pixel rows in delimiter ;=W + CMP AL,10H ;are we in graphics mode 10H + JE DD40 ;yes, # rows ok + ADD CL,2 ;no, mode 11,12 have 16 pixel rows +DD40: ; instead of 14 pixel rows. + MOV BP,02H ;# pixel columns/8 in delimiter ;=W +; + MOV AH,0FFH ;=W + MOV AL,g_bit_mask ;bit mask index ;=W + OUT DX,AX ;set bit mask ;=W +DD50: ;=W + PUSH CX ;=W + PUSH DI ;=W + MOV CX,BP ;=W +DD60: ;=W + MOV AH,0FFH ;background ;=W + MOV AL,g_bit_mask ;bit mask index ;=W + OUT DX,AX ;set bit mask ;=W +; + MOV AL,ES:[DI] ;latch data ;=W + MOV ES:[DI],BH ;set the dot ;=W +; + LODSB ;foreground ;=W + XCHG AL,AH ;=W +; + MOV AL,g_bit_mask ;bit mask index ;=W + OUT DX,AX ;set bit mask ;=W +; + MOV AL,ES:[DI] ;latch data ;=W + MOV ES:[DI],BL ;set the dot ;=W +; + INC DI ;=W + LOOP DD60 ;=W +; + POP DI ;=W + ADD DI,LINELEN ;=W + POP CX ;=W + LOOP DD50 ;=W + JMP DDEXIT ;=W +;--------------------------------------------- ;=W +; Mode 11H with no VGA : ;=W +;--------------------------------------------- ;=W +DD100: XOR CH,CH + MOV CL,10H ;# pixel rows in delimiter + MOV BP,02H ;# of pixel columns in delimiter + +DD110: PUSH CX + PUSH DI +; + MOV CX,BP +; +DD120: LODSB ;get icon row +; +DD130: XOR AL,0FFH + MOV ES:[DI],AL ;set the dot + INC DI + LOOP DD120 +; + POP DI +; + ADD DI,50H ;line length, 80 +; + POP CX +; + LOOP DD110 +; +DDEXIT: POP BP + POP ES + POP DS + POP SI + POP DI + POP DX + POP CX + POP BX + POP AX +; + RET +DRAW_DEM ENDP +; +PAGE +;-----------------------------------------------------------------------------+ ;=W +; : ;=W +; GET_MONO_DOS : ;=W +; Get segment and offset of the DOS monocasing table and return it : ;=W +; : ;=W +; Entry: None : ;=W +; : ;=W +; Exit: None : ;=W +; : ;=W +;-----------------------------------------------------------------------------+ ;=W +GET_MONO_DOS PROC NEAR ;=W +; + PUSH SI ;save registers ;=W + PUSH ES ;=W + PUSH DI ;=W +; + MOV AH,65H ;extended country info ;=W + MOV AL,02H ;get uppercase table ptrs ;=W + MOV BX,-1 ;default code page ;=W + MOV DX,-1 ;default country id ;=W + MOV CX,05H ;# bytes returned ;=W + PUSH DS ;=W + POP ES ;ES:DI ptrs to return buffer ;=W + MOV DI,OFFSET WR_CUCHAR ;use as temp buffer ;=W +; + INT 21H ;=W +; + INC DI ;skip info id ;=W + MOV SI,DI ;we need DI so use SI ;=W + POP DI ;=W +; + MOV AX,WORD PTR [SI] ;get DOS monocasing table offset ;=W + MOV [DI]+IN_MONOOFF,AX ;save it ;=W + ADD SI,2 ;=W + MOV AX,WORD PTR [SI] ;get DOS monocasing table segment ;=W + MOV [DI]+IN_MONOSEG,AX ;save it ;=W +; + POP ES ;restore registers ;=W + POP SI ;=W +; + RET ;=W +GET_MONO_DOS ENDP +; +PAGE +;-----------------------------------------------------------------------------+ ;=W +; : ;=W +; GET_DBCS : ;=W +; Get segment and offset of the DOS double byte support table. : ;=W +; : ;=W +; Entry: DS:DI : ;=W +; : ;=W +; Exit: None : ;=W +; : ;=W +;-----------------------------------------------------------------------------+ ;=W +GET_DBCS PROC NEAR ;=W +; + PUSH SI + PUSH ES ;=W + PUSH DI ;=W + PUSH DI ;=W +; + MOV AH,65H ;get extended country info + MOV AL,07H ;get DBCS environment table + INT 21H ;DOS function call,vector returned + ; in ES:DI + POP SI ;ptr, SI -> IN_PB + INC DI ;skip over id byte returned + MOV AX,WORD PTR ES:[DI] ;get offset of DBCS table + MOV [DI]+IN_DBCSOFF,AX ;save it +; + ADD DI,2 ;skip over offset to get segment + MOV BX,WORD PTR ES:[DI] ;get segment of DBCS table + MOV [DI]+IN_DBCSSEG,BX ;save it +; + POP DI +; + MOV SI,AX ;Point to DBCS table to get length + MOV ES,BX + MOV AX,WORD PTR ES:[SI] + MOV [DI]+IN_DBCSLEN,AX + ADD [DI]+IN_DBCSOFF,2 ;change offset to point to table +; + POP ES + POP SI +; + RET +GET_DBCS ENDP -- cgit v1.2.3