3 ;-----------------------------------------------------------------------------+
5 ; Source...: PCINPUT.INC :
6 ; Created..: 01-01-82 :
7 ; Standards: 01-07-86 :
8 ; Revised..: 11-17-87 :
10 ; Called as: FAR, NEAR or INT :
13 ;-----------------------------------------------------------------------------+
16 ;-----------------------------------------------------------------------------+
20 ; Performs the following functions: :
22 ; - Initializes pointers and counters :
23 ; - Initializes input buffer with default value (from screen or strg) :
24 ; - Set options and display input buffer as default on screen :
25 ; - Display field delimiters :
26 ; - Display minus or plus sign :
29 ; Entry: ES:SI = Points to current ICB :
30 ; DS:DI = Points to PB :
32 ; WR_CURSIZE = Current cursor size :
34 ; Exit: Default displayed :
36 ;-----------------------------------------------------------------------------+
40 ; Initialize input buffer with default buffer
43 PUSH ES ;save registers
48 MOV DX,ES:[SI]+ICB_FIELDLEN ;save for later ;=W
49 MOV BX,ES:[SI]+ICB_DEFLEN ;save for later ;=W
51 MOV AX,ES:[SI]+ICB_DEFSEG ;get source string segment ;=W
54 MOV AX,ES:[SI]+ICB_FIELDOFF ;get destination offset ;=W
57 MOV AX,ES:[SI]+ICB_FIELDSEG ;get destination segment ;=W
58 MOV CX,ES:[SI]+ICB_DEFOFF ;get source string offset ;=W
63 MOV CX,DX ;clear input buffer ;=W
70 MOV CX,BX ;initialize number of bytes in ;=W
72 CMP CX,DX ;check if default string is
73 JBE DEF10 ; longer than input buffer
75 MOV CX,DX ;error set to input buffer leng
76 MOV BP,ICB_STRU ;set error indicating default was
80 REP MOVSB ;move default into input buffer
82 POP SI ;restore registers
87 OR ES:[SI]+ICB_STATUS,BP ;save error status
90 ; Calculate row and column of input field and set the desired display attribute
92 MOV AX,ES:[SI]+ICB_ROW ;get input field row
95 MOV AX,ES:[SI]+ICB_COL ;get input field column
98 CALL PCROWCL_CALL ;calculate row and column info
99 ; return CR_RCOFF and CR_BEGROWOFF
100 MOV AL,[DI]+WR_EATTR ;set the entry attribute to the
101 MOV [DI]+WR_CATTR,AL ; current attribute
103 ; Initialize variables for left justified field
105 TEST ES:[SI]+ICB_OPT1,ICB_RJU ;check if right justified
108 MOV [DI]+WR_LEFTCHAR,1 ;set left character marker to
109 ;beginning of input field
110 MOV AX,ES:[SI]+ICB_FIELDLEN ;get max field length ;=W
112 TEST ES:[SI]+ICB_OPT3,ICB_HOR ;check if horizontal scrolling ;=W
114 MOV AX,ES:[SI]+ICB_WIDTH ;get field width for horizontal scrolling ;=W
115 ;because we only show a windowful of field ;=W
117 MOV [DI]+WR_RIGHTCHAR,AX ;set ptr to rightmost character ;=W
118 CALL CAL_COORS ;get end of field char, byte ;=W
119 JMP DEF30 ;and next byte positions
121 ; Initialize variables for right justified field
127 ; Display default even if password option is active
129 DEF30: PUSH ES:[SI]+ICB_OPT1 ;save option word
131 TEST ES:[SI]+ICB_OPT1,ICB_PSW ;check if password option active
134 AND ES:[SI]+ICB_OPT1,NOT ICB_PSW
135 ;set option word to force disp
138 MOV AX,2 ;set option to actually display
139 CALL WORD PTR [DI]+WR_DISPLAY ; default value in proper
141 POP ES:[SI]+ICB_OPT1 ;restore original password
143 ; Display initial cursor in proper size and location
145 MOV AX,[DI]+IN_CURNOR ;set cursor size for replace
146 MOV [DI]+WR_CURSIZE,AX
148 TEST ES:[SI]+ICB_STATUS,ICB_SINS
149 JE DEF45 ;check if insert is active
151 MOV AX,[DI]+IN_CURINS ;set cursor size for insert
152 MOV [DI]+WR_CURSIZE,AX
155 CALL CAL_COORS ;calculate coordinates ;=W
156 CALL CURSOR ;initialize cursor size and locat
158 ; Determine if characters in input buffer are allowonce chars and set flags
161 jmp Def65 ;temp until bug in allowonce scan fixed
163 PUSH ES ;save registers
166 MOV BX,ES ;set segment of ICB
167 MOV DX,SI ;set offset of ICB
169 MOV CX,ES:[SI]+ICB_FIELDLEN ;get field length
171 PUSH ES:[SI]+ICB_FIELDOFF ;get field offset
172 PUSH ES:[SI]+ICB_FIELDSEG ;get field segment
176 DEF50: MOV AL,ES:[SI] ;get character from input buffer
177 MOV [DI]+DBC_KS,AL ; and set to PCINDBC PB
179 INC SI ;point to next byte
181 CALL PCINDBC_CALL ;call PCINDBC
183 TEST [DI]+DBC_STAT,DBC_DBCS ;check if keystroke double byte
186 CMP CX,0 ;if last loop is double character
187 JBE DEF60 ; and is missing trailing byte
188 ; then, consider a single byte
190 MOV AH,ES:[SI] ;get character from input buffer
191 MOV [DI]+DBC_KS,AH ; and set to PCINDBC PB
192 INC SI ;point to next byte
193 DEC CX ;adjust loop pointer for additial
194 ; character read (double byte)
196 DEF60: PUSH ES ;save registers
202 CALL ON_ALLOWONCE ;Scan the allowonce string for
203 ; the character in AX and set flag
205 POP SI ;restore registers
208 LOOP DEF50 ;get next keystroke
210 POP SI ;restore registers
213 ; Display field delimiters
216 MOV AX,01 ;assume "[ ]" as delimiters ;=W
218 TEST ES:[SI]+ICB_OPT1,ICB_BEN ;display entry delimiters ;=W
219 JE DEF100 ;no, leave ;=W
221 TEST ES:[SI]+ICB_OPT3,ICB_WIN ;does field use windowing ;=W
222 JE DEF70 ;no, check others ;=W
224 TEST ES:[SI]+ICB_OPT1,ICB_BOX ;check if delimiter = box ;=W
225 JE DEF90 ;no, display normal delimiters ;=W
227 MOV AX,06 ;display box ;=W
228 JMP DEF90 ;done with delimiters ;=W
230 TEST ES:[SI]+ICB_OPT3,ICB_HOR ;does field use horiz. window ;=W
233 MOV AX,03 ;display "[ >" ;=W
234 CMP ES:[SI]+ICB_HRSTART,01H ;are we at beginning of window ? ;=W
237 MOV AX,04 ;no, display "< >" ;=W
239 CALL DELIMITER ;do it ;=W
241 TEST ES:[SI]+ICB_OPT1,ICB_BOX ;check if also need box ;=W
244 MOV AX,06 ;display box ;=W
246 CALL DELIMITER ;do it ;=W
248 ; Display minus or plus sign if active
251 TEST ES:[SI]+ICB_OPT1,ICB_MUS ;Check if minus/plus sign
252 JE DEFEXIT ; display option is active
254 MOV [DI]+WR_KEYCONF,0 ;initialize to plus sign key
256 TEST ES:[SI]+ICB_OPT1,ICB_SMU ;Check if default is negative
259 OR [DI]+WR_KEYCONF,WR_MUS ;initialize to minus sign key
261 DEF110: CALL PLUS_MINUS ;display plus or minus sign and
270 ;-----------------------------------------------------------------------------+
274 ; Performs the following functions: :
276 ; - Removes field delimiters :
277 ; - Inserts commas as specified :
278 ; - Inserts decimal point as specified :
279 ; - Adjusts field to specified significant digits :
280 ; - Displays buffer contents in exit color :
281 ; - Checks if original default has changed :
282 ; - Check if entry is in specified numeric range :
283 ; - Sets minus or plus sign indicator in exit color :
284 ; - Remove thousand separators from input string buffer :
285 ; - Restore original cursor position and size, only in text mode :
287 ; Entry: ES:SI = Points to current ICB :
288 ; DS:DI = Points to PB :
292 ;-----------------------------------------------------------------------------+
297 ; Inserts commas as specified
303 ; Inserts decimal point as specified
309 ; Adjusts field to specified significant digits
315 ; Calculate color attribute of exit colors
317 TEST ES:[SI]+ICB_OPT1,ICB_XCL ;check if option to use exit
318 JE PRE10 ; colors is active
320 MOV AL,[DI]+WR_XATTR ;set the exit attribute to the
321 MOV [DI]+WR_CATTR,AL ; current attribute
323 ; Display default value of input buffer in proper justification
325 PRE10: MOV [DI]+WR_LEFTCHAR,1 ;set left character
326 MOV AX,ES:[SI]+ICB_FIELDLEN ;set right marker
328 TEST ES:[SI]+ICB_OPT3,ICB_HOR ;horizontal scrolling mode ? ;=W
329 JE PRE15 ;no, display all buffer ;=W
330 MOV AX,ES:[SI]+ICB_WIDTH ;use width instead of all buffer ;=W
332 MOV [DI]+WR_RIGHTCHAR,AX
334 MOV AX,2 ;set option to actually display
335 CALL WORD PTR [DI]+WR_DISPLAY ; default value in proper
337 ; Process minus/plus key options
339 TEST ES:[SI]+ICB_OPT1,ICB_MUS ;Check if minus/plus sign
340 JE PRE40 ; display option is active
342 MOV [DI]+WR_KEYCONF,0 ;initialize to plus sign
344 TEST ES:[SI]+ICB_STATUS,ICB_SMUS
345 JE PRE20 ;Check if sign is negative
347 OR [DI]+WR_KEYCONF,WR_MUS ;initialize to minus sign key
349 PRE20: TEST ES:[SI]+ICB_STATUS,ICB_SPUS
350 JE PRE30 ;Check if sign is positive
352 OR [DI]+WR_KEYCONF,WR_PUS ;initialize to plus sign key
354 PRE30: CALL PLUS_MINUS ;display plus or minus sign
355 ; according to WR_KEYCONF setting
357 ; Replace field entry delimiters with exit delimiters
359 PRE40: TEST ES:[SI]+ICB_OPT1,ICB_BEX ;check if field delimiters
360 JE PRE60 ; should be displayed on exit
362 MOV AX,2 ;option to remove delimiters
363 CALL DELIMITER ;display delimiters
365 TEST ES:[SI]+ICB_OPT1,ICB_BOX ;check if box around field
366 JE PRE60 ; should be displayed
368 MOV AX,7 ;set option to remove box
369 CALL DELIMITER ;display delimiters
371 ; Check if default value has changed and set return flag
373 PRE60: PUSH DS ;save registers
378 MOV CX,ES:[SI]+ICB_DEFLEN ;initialize to default length
379 CMP CX,ES:[SI]+ICB_FIELDLEN ;check if default length is less
380 JBE PRE70 ; than field length
382 MOV CX,ES:[SI]+ICB_FIELDLEN ;initialize to field length
384 PRE70: MOV AX,ES:[SI]+ICB_DEFSEG ;compare default string to ;=W
386 MOV AX,ES:[SI]+ICB_FIELDOFF ;=W
389 MOV AX,ES:[SI]+ICB_DEFOFF ; current input string ;=W
390 MOV BX,ES:[SI]+ICB_FIELDSEG ;=W
394 REPE CMPSB ;compare default and input strings
396 POP DI ;restore registers
401 CMP CX,0 ;are we done ? ;=W
402 JE PRE80 ;check if strings compared
404 OR ES:[SI]+ICB_STATUS,ICB_SDEF
405 ;set flag that default changed
407 ; Check if entry is within specified numeric range, if not set flag
413 ; Remove thousand separators if specified from input string buffer
419 ; Restore original cursor position and size
422 TEST ES:[SI]+ICB_STATUS,ICB_CUR_ON ;is cursor on ?
424 CALL CURSOR ;erase the graphics cursor
426 OR ES:[SI]+ICB_STATUS,ICB_DONE ;exit condition found, exit ;=W
428 ; Check if ICB_SAV option selected. If selected, then save contents of the ;=W
429 ; input buffer to the default buffer. ;=W
431 TEST ES:[SI]+ICB_OPT4,ICB_SAV ;check ? ;=W
432 JE PRE200 ;no, exit now ;=W
434 PUSH ES ;save registers ;=W
439 MOV CX,ES:[SI]+ICB_ENDBYTE ;# of bytes to copy from input ;=W
440 ; buffer to default buffer ;=W
441 MOV ES:[SI]+ICB_DEFLEN,CX ;reset default length
443 MOV AX,ES:[SI]+ICB_FIELDSEG ;get destination segment ;=W
446 MOV AX,ES:[SI]+ICB_DEFOFF ;get source string offset ;=W
449 MOV AX,ES:[SI]+ICB_DEFSEG ;get source string segment ;=W
450 MOV BX,ES:[SI]+ICB_FIELDOFF ;get destination offset ;=W
455 REP MOVSB ;move default into input buffer ;=W
457 POP SI ;restore registers ;=W
466 ;-----------------------------------------------------------------------------+ ;=W
470 ; Process keystroke and update display with input buffer changes : ;=W
471 ; for the following functions: : ;=W
473 ; Home key Up arrow Allowonce replace mode : ;=W
474 ; End key Down arrow Allowonce insert mode : ;=W
475 ; Left arrow Control end Allow replace mode : ;=W
476 ; Right arrow Delete key Allow insert mode : ;=W
478 ;-----------------------------------------------------------------------------+ ;=W
480 RIGHT_H_JUST PROC NEAR ;=W
487 RIGHT_H_JUST ENDP ;=W
490 ;-----------------------------------------------------------------------------+
494 ; Process keystroke and update display with input buffer changes :
495 ; for the following functions: :
497 ; Home key Up arrow Allowonce replace mode :
498 ; End key Down arrow Allowonce insert mode :
499 ; Left arrow Control end Allow replace mode :
500 ; Right arrow Delete key Allow insert mode :
502 ;-----------------------------------------------------------------------------+
514 ;-----------------------------------------------------------------------------+ ;=W
518 ; Process keystroke and update display with input buffer changes : ;=W
519 ; for the following functions: : ;=W
521 ; Home key Up arrow Allowonce replace mode : ;=W
522 ; End key Down arrow Allowonce insert mode : ;=W
523 ; Left arrow Control end Allow replace mode : ;=W
524 ; Right arrow Delete key Allow insert mode : ;=W
527 ; Following information is used: : ;=W
530 ; ÚÄ (ICB_FIELDSEG:ICB_FIELDOFF) Beginning address of input : ;=W
531 ; ³ buffer in memory. : ;=W
533 ; ³ ÚÄ (WR_CUBYTE) Byte offset into the input buffer : ;=W
534 ; ³ ³ of where characters will be added : ;=W
535 ; ³ ³ to input buffer. : ;=W
537 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W
538 ; ³ S ³ L ³ T ³ L ³ T ³ S ³ S ³ ³ ³ ³ ³ ³ ³ ³ : ;=W
539 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ : ;=W
540 ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ : ;=W
542 ; (ICB_FIELDLEN) Length of input field in bytes. : ;=W
545 ; The following demonstrates the before and after input buffer : ;=W
546 ; images. (S = Single byte, L = DBCS lead byte, T = DBCS trailing : ;=W
549 ; Deleting a double byte: : ;=W
550 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W
551 ; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ S ³ ³ ³ : ;=W
552 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ : ;=W
554 ; Deleting a single byte: : ;=W
555 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W
556 ; ³ S ³ L ³ T ³ S ³ L ³ T ³ ³ S ³ L ³ T ³ L ³ T ³ ³ : ;=W
557 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ : ;=W
559 ; Backspace removal of a double byte: : ;=W
560 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W
561 ; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ S ³ ³ ³ : ;=W
562 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ : ;=W
564 ; Backspace removal of a single byte: : ;=W
565 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W
566 ; ³ S ³ S ³ S ³ S ³ L ³ T ³ ³ S ³ S ³ S ³ L ³ T ³ ³ : ;=W
567 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÁÄÄÄÙ : ;=W
569 ; Replacing a double byte with a double byte: : ;=W
570 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W
571 ; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ L ³ T ³ S ³ : ;=W
572 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÙ : ;=W
574 ; Replacing a double byte with a single byte: (Option 1) : ;=W
575 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W
576 ; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ S ³ S ³ ³ : ;=W
577 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ : ;=W
579 ; Replacing a double byte with a single byte: (Option 2) : ;=W
580 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W
581 ; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ S ³ ³ S ³ : ;=W
582 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ : ;=W
584 ; Replacing a single byte with a single byte: : ;=W
585 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W
586 ; ³ S ³ L ³ T ³ S ³ L ³ T ³ ³ S ³ L ³ T ³ S ³ L ³ T ³ : ;=W
587 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ : ;=W
589 ; Replacing a single byte with a double byte. : ;=W
590 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W
591 ; ³ S ³ L ³ T ³ S ³ ³ ³ ³ S ³ L ³ T ³ L ³ T ³ ³ : ;=W
592 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÙ : ;=W
594 ; Replacing a single byte with a double byte without enough buffer: : ;=W
595 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W
596 ; ³ S ³ L ³ T ³ S ³ L ³ T ³ ³ S ³ L ³ T ³ S ³ L ³ T ³ : ;=W
597 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ : ;=W
599 ; Inserting a single byte. : ;=W
600 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W
601 ; ³ S ³ L ³ T ³ L ³ T ³ ³ ³ S ³ L ³ T ³ S ³ L ³ T ³ : ;=W
602 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ : ;=W
604 ; Inserting a single byte without enough buffer generate an error: : ;=W
605 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W
606 ; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ L ³ T ³ S ³ : ;=W
607 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ : ;=W
608 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W
609 ; ³ S ³ L ³ T ³ S ³ S ³ ³ ³ S ³ L ³ T ³ S ³ S ³ ³ : ;=W
610 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ : ;=W
612 ; Inserting a double byte character: : ;=W
613 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W
614 ; ³ S ³ L ³ T ³ S ³ ³ ³ ³ S ³ L ³ T ³ L ³ T ³ S ³ : ;=W
615 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÙ : ;=W
618 ; Entry: ES:SI = Points to current ICB : ;=W
619 ; DS:DI = Points to PB : ;=W
621 ; INC_KS = Keystroke from returned from PCINCHA : ;=W
623 ; WR_KEYCONF = Bit flag inidicating the options set for INC_KS : ;=W
624 ; WR_KEYCONF2 keystroke. : ;=W
628 ;-----------------------------------------------------------------------------+ ;=W
630 LEFT_H_JUST PROC NEAR ;=W
632 ; Initialize right and left boundary markers ;=W
634 TEST [DI]+WR_KEYCONF,WR_MASK ;check to see if editing key entered ;=W
635 JNE LHJ5 ;yes, must check for editing keys ;=W
636 JMP LHJ190 ;no, skip checks for editing keys ;=W
639 ; Process home key ;=W
641 LHJ5: TEST [DI]+WR_KEYCONF,WR_HOM ;check if home key pressed ;=W
645 ; add ICB_WHM option to process window home key movement ;=W
648 MOV ES:[SI]+ICB_CURCHAR,1 ;initialize cursor to 1st byte ;=W
649 ; position, assuming no windowing ;=W
650 ; wrap is occurring ;=W
651 MOV [DI]+WR_HRCHAR,1 ;reset the horiz. window ;=W
652 CALL CAL_COORS ;calculate cursor position ;=W
653 MOV AX,3 ;display delimiters "[ >" ;=W
654 CALL DELIMITER ;display delimiter ;=W
655 JMP LHJEXIT ; returns WR_CURROW, WR_CURROW ;=W
658 ; Process end key ;=W
660 LHJ10: TEST [DI]+WR_KEYCONF,WR_END ;check if home key pressed ;=W
665 ; add ICB_WEN to move cursor to end of current window row ;=W
668 CALL CAL_COORS ;get current end of field info ;=W
669 MOV AX,[DI]+WR_ENCHAR ;adjust one past end buffer charac ;=W
671 MOV ES:[SI]+ICB_CURCHAR,AX ;set current cursor position to ;=W
672 CALL CAL_COORS ;get cursor position ;=W
673 MOV AX,4 ;display delimiters "< >" ;=W
674 CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W
676 MOV AX,5 ;display delimiters "< ]" ;=W
677 TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W
679 MOV ES:[SI]+ICB_CURCHAR,1 ;wrap to first character position
680 MOV [DI]+WR_HRCHAR,1 ;reset the horiz. window ;=W
681 MOV AX,3 ;display delimiters "[ >" ;=W
684 TEST ES:[SI]+ICB_OPT2,ICB_AXC ;is autoexit option set ? ;=W
686 OR [DI]+WR_KEYCONF2,WR_RET ;yes, set autoexit flag ;=W
688 MOV BX,ES:[SI]+ICB_FIELDLEN ;adjust horizontal window ;=W
689 SUB BX,ES:[SI]+ICB_WIDTH ;(below this line may not work for ;=W
690 INC BX ; DBCS support) ;=W
691 MOV [DI]+WR_HRCHAR,BX ;=W
694 MOV CX,[DI]+WR_CUBYTE ;check if need to adjust horz. ;=W
695 CMP CX,ES:[SI]+ICB_WIDTH ; window ;=W
697 MOV [DI]+WR_HRCHAR,1 ;=W
698 MOV AX,3 ;display delimiters "[ >" ;=W
701 MOV BX,[DI]+WR_ENBYTE ;yes, adjust it ;=W
702 SUB BX,ES:[SI]+ICB_WIDTH ;=W
704 MOV [DI]+WR_HRCHAR,BX ;=W
706 CALL CAL_COORS ;re-calculate display ;=W
707 CALL DELIMITER ;display delimiter ;=W
708 JMP LHJEXIT ;exit ;=W
710 ; Process left arrow ;=W
712 LHJ20: TEST [DI]+WR_KEYCONF,WR_LFT ;check if left arrow key pressed ;=W
716 ; add ICB_CSW option to wrap cursor from top/bottom end to end ;=W
720 ; add ICB_WAR option to wrap cursor on same row end to end ;=W
723 MOV BX,ES:[SI]+ICB_CURCHAR ;get cursor position ;=W
724 CMP BX,1 ;is cursor in first position ? ;=W
726 TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W
728 MOV BX,ES:[SI]+ICB_FIELDLEN ;adjust horizontal window ;=W
729 MOV ES:[SI]+ICB_CURCHAR,BX ;wrap to first character position
730 SUB BX,ES:[SI]+ICB_WIDTH ;(below this line may not work for ;=W
731 INC BX ; DBCS support) ;=W
732 MOV [DI]+WR_HRCHAR,BX ;=W
734 MOV AX,5 ;display delimiters "< ]" ;=W
735 CALL DELIMITER ;display delimiter ;=W
738 MOV AX,3 ;display delimiters "[ >" ;=W
739 CALL DELIMITER ;display delimiter ;=W
740 TEST ES:[SI]+ICB_OPT2,ICB_AXC ;is autoexit option set ? ;=W
742 OR [DI]+WR_KEYCONF2,WR_RET ;yes, set autoexit flag ;=W
745 CALL PCMBEEP_CALL ;error beep ;=W
746 JMP LHJEXIT ;exit ;=W
748 DEC ES:[SI]+ICB_CURCHAR ;adjust cursor to one position ;=W
750 CMP BX,[DI]+WR_HRCHAR ;is cursor to the left of horz.wind. ? ;=W
752 DEC [DI]+WR_HRCHAR ;yes, adjust horiz. window ;=W
753 MOV AX,4 ;display delimiters "< >" ;=W
754 CALL DELIMITER ;display delimiter ;=W
755 LHJ32: ; towards the left ;=W
756 CALL CAL_COORS ;calculate cursor position
757 JMP LHJEXIT ;exit ;=W
759 ; Process right arrow ;=W
761 LHJ40: TEST [DI]+WR_KEYCONF,WR_RGT ;check if left arrow key pressed ;=W
765 ; add ICB_WAR option to wrap cursor on same row end to end ;=W
768 CALL CAL_COORS ;get cursor position ;=W
770 CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W
773 MOV AX,5 ;display delimiters "< ]" ;=W
774 CALL DELIMITER ;display delimiter ;=W
775 CALL PCMBEEP_CALL ;error beep ;=W
776 JMP LHJEXIT ;exit ;=W
778 LHJ50: INC ES:[SI]+ICB_CURCHAR ;adjust cursor to one position ;=W
779 ; towards the right ;=W
780 MOV BX,[DI]+WR_HRCHAR ;get begin. of horiz. wondow ;=W
781 ADD BX,ES:[SI]+ICB_WIDTH ;add width to get end of window ;=W
782 CMP BX,ES:[SI]+ICB_CURCHAR ;is cursor past end of window ? ;=W
784 INC [DI]+WR_HRCHAR ;yes, adjust the horiz. window ;=W
785 MOV AX,4 ;display delimiters "< >" ;=W
786 CALL DELIMITER ;display delimiter ;=W
788 CALL CAL_COORS ;calculate cursor position ;=W
789 CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W
791 TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W
793 MOV ES:[SI]+ICB_CURCHAR,1 ;wrap to first character position
794 MOV [DI]+WR_HRCHAR,1 ;reset the horiz. window ;=W
795 MOV AX,3 ;display delimiters "[ >" ;=W
796 CALL DELIMITER ;display delimiter ;=W
799 DEC [DI]+WR_HRCHAR ;yes, adjust wind back one position ;=W
800 MOV AX,5 ;display delimiters "< ]" ;=W
801 CALL DELIMITER ;display delimiter ;=W
802 TEST ES:[SI]+ICB_OPT2,ICB_AXC ;is autoexit option set ? ;=W
804 OR [DI]+WR_KEYCONF2,WR_RET ;set autoexit flag ;=W
806 CALL CAL_COORS ;calculate cursor position ;=W
807 JMP LHJEXIT ;exit ;=W
809 ; Process up arrow ;=W
812 ; adjust cursor position ;=W
816 ; check for field wrap, exit, error beep ;=W
819 ; Process down arrow ;=W
822 ; adjust cursor position ;=W
826 ; check for field wrap, exit, error beep ;=W
829 ; Process cntrl+end key ;=W
831 LHJ80: TEST [DI]+WR_KEYCONF,WR_CED ;check if control+end key pressed ;=W
834 CALL CAL_COORS ;get cursor position ;=W
835 CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W
838 CALL PCMBEEP_CALL ;error beep ;=W
839 JMP LHJEXIT ;exit ;=W
841 MOV BX,[DI]+WR_CUBYTE ;delete from current byte position ;=W
842 CALL CLEAR_BUFFER ;=W
844 CALL CAL_COORS ;calculate cursor position
845 JMP LHJEXIT ;display field, set cursor, exit ;=W
847 ; Process delete key ;=W
849 LHJ100: TEST [DI]+WR_KEYCONF,WR_DEL ;check if delete key pressed ;=W
853 ; Add ICB_WDL option in off state to delete on current line only ;=W
856 CALL CAL_COORS ;get cursor position ;=W
858 CMP [DI]+WR_FIELDEND,1 ;check if cursor past end of field ;=W
861 CALL REMOVE_CHAR ;remove character at current offst ;=W
862 ; and shift remaining in place ;=W
863 CALL CAL_COORS ;calculate cursor position
864 JMP LHJEXIT ;display field, set cursor, exit ;=W
866 LHJ110: CALL PCMBEEP_CALL ;error beep ;=W
867 JMP LHJEXIT ;exit ;=W
869 ; Process backspace key ;=W
871 LHJ130: TEST [DI]+WR_KEYCONF,WR_BCK ;check if backspace key pressed ;=W
874 MOV BX,ES:[SI]+ICB_CURCHAR ;get cursor position ;=W
875 CMP BX,1 ;check if cursor is at first ;=W
876 JA LHJ140 ; field position ;=W
878 TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W
880 MOV BX,ES:[SI]+ICB_FIELDLEN ;adjust horizontal window ;=W
881 MOV ES:[SI]+ICB_CURCHAR,BX ;wrap to first character position
882 SUB BX,ES:[SI]+ICB_WIDTH ;(below this line may not work for ;=W
883 INC BX ; DBCS support) ;=W
884 MOV [DI]+WR_HRCHAR,BX ;=W
886 MOV AX,5 ;display delimiters "< ]" ;=W
887 CALL DELIMITER ;display delimiter ;=W
890 MOV AX,3 ;display delimiters "[ >" ;=W
891 TEST ES:[SI]+ICB_OPT2,ICB_AXC ;is autoexit option set ? ;=W
893 OR [DI]+WR_KEYCONF2,WR_RET ;yes, set autoexit flag ;=W
894 CALL DELIMITER ;display delimiter ;=W
897 CALL DELIMITER ;display delimiter ;=W
898 CALL PCMBEEP_CALL ;error beep ;=W
899 JMP LHJEXIT ;exit ;=W
901 DEC ES:[SI]+ICB_CURCHAR ;adjust cursor to one position
902 ; towards the left ;=W
903 CMP BX,[DI]+WR_HRCHAR ;is cursor in front of the wind. ? ;=W
905 DEC [DI]+WR_HRCHAR ;yes, adjust the horiz. window ;=W
906 MOV AX,4 ;display delimiters "< >" ;=W
907 CALL DELIMITER ;display delimiter ;=W
910 CALL CAL_COORS ;get cursor position ;=W
911 CALL REMOVE_CHAR ;remove character at current offst ;=W
912 ; and shift remaining in place ;=W
914 CALL CAL_COORS ;calculate cursor position
915 JMP LHJEXIT ;display field, set cursor, exit ;=W
917 ; Process insert key toggle ;=W
919 LHJ160: TEST [DI]+WR_KEYCONF,WR_INS ;check if insert key pressed ;=W
920 JE LHJ180 ; if not, continue ;=W
922 TEST ES:[SI]+ICB_STATUS,ICB_SINS ;check if in insert mode ? ;=W
923 JE LHJ165 ;no, put in insert mode ;=W
925 MOV BX,[DI]+IN_CURNOR ;set cursor size for normal ;=W
926 MOV [DI]+WR_CURSIZE,BX ; cursor ;=W
928 AND ES:[SI]+ICB_STATUS,NOT ICB_SINS ;=W
929 JMP LHJ170 ;turn insert mode off ;=W
931 LHJ165: MOV BX,[DI]+IN_CURINS ;set cursor size for insert ;=W
932 MOV [DI]+WR_CURSIZE,BX ; cursor ;=W
934 OR ES:[SI]+ICB_STATUS,ICB_SINS ;=W
935 ;turn insert mode on ;=W
939 PUSH DS ;save registers ;=W
942 MOV DI,40H ;point DS:DI to KB_FLAG in BIOS ;=W
945 MOV AX,[DI] ;get current BIOS KB_FLAG ;=W
947 AND AX,NOT WR_INSSTATE ;set BIOS insert active flag off ;=W
949 TEST ES:[SI]+ICB_STATUS,ICB_SINS ;=W
950 JE LHJ175 ;check if insert should be set on ;=W
952 OR AX,WR_INSSTATE ;set BIOS insert active flag on ;=W
954 LHJ175: POP DI ;restore registers ;=W
957 JMP LHJEXIT ;exit ;=W
959 ; Process allowonce key option ;=W
962 ; insert or replace ;=W
966 ; adjust input buffer ;=W
970 ; check for field wrap, exit, error beep ;=W
974 ; adjust cursor position ;=W
977 ; Process allowed keystroke in replace mode ;=W
979 LHJ190: TEST [DI]+WR_KEYCONF,WR_ALL ;check if allow key pressed ;=W
982 CALL PCMBEEP_CALL ;error beep key not defined ;=W
983 JMP LHJEXIT ;exit ;=W
985 LHJ195: TEST ES:[SI]+ICB_STATUS,ICB_SINS ;=W
986 JE LHJ198 ;check if insert is active ;=W
988 JMP LHJ270 ;do insert display ;=W
991 CALL CAL_COORS ;get cursor position ;=W
992 CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W
995 CALL PCMBEEP_CALL ;error beep key not defined ;=W
996 JMP LHJEXIT ;exit ;=W
998 ; Check if character to be replaced in field buffer is double byte character ;=W
1000 LHJ200: PUSH ES ;save registers ;=W
1003 PUSH ES:[SI]+ICB_FIELDSEG ;get segment of input buffer ;=W
1004 PUSH ES:[SI]+ICB_FIELDOFF ;get offset of input buffer ;=W
1008 ADD SI,[DI]+WR_CUBYTE ;add cursor offset into buffer ;=W
1009 DEC SI ;make zero based ;=W
1011 MOV CX,ES ;save offset of character to ;=W
1012 MOV DX,SI ; replace ;=W
1014 MOV AL,ES:[SI] ;get byte that cursor is pointing ;=W
1015 MOV [DI]+DBC_KS,AL ; to check if DBCS ;=W
1016 CALL PCINDBC_CALL ;call routine to check if char ;=W
1017 ; is lead double byte char ;=W
1019 POP SI ;restore registers ;=W
1022 TEST [DI]+DBC_STAT,DBC_DBCS ;check if char is lead DBCS ;=W
1023 JE LHJ220 ; if no, jump to single byte code ;=W
1025 ; Replace double byte character with double byte character ;=W
1027 TEST [DI]+WR_KEYCONF2,WR_DBC ;check if keystroke is DBC ;=W
1028 JE LHJ210 ;continue with single byte ;=W
1030 MOV AX,[DI]+INC_KS ;set double byte character to ;=W
1031 ; input buffer replacing ;=W
1032 ; double byte character ;=W
1036 MOV ES,CX ;save offset of character to ;=W
1037 MOV SI,DX ; replace ;=W
1038 MOV ES:[SI],AX ;replace double byte ;=W
1040 POP SI ;restore registers ;=W
1043 JMP LHJ260 ;exit ;=W
1045 ; Replace double byte character with single byte character ;=W
1047 LHJ210: MOV AX,[DI]+INC_KS ;get keystroke and replace double ;=W
1048 ; byte with single byte ;=W
1053 MOV ES,CX ;save offset of character to ;=W
1054 MOV SI,DX ; replace single byte ;=W
1057 POP SI ;restore registers ;=W
1060 MOV AX,ES:[SI]+ICB_FIELDLEN ;set ending byte ;=W
1061 MOV [DI]+WR_RIGHTBYTE,AX ;=W
1063 MOV AX,[DI]+WR_CUBYTE ;set markers for shift to remove ;=W
1064 INC AX ;adjust past replaced leading byte ;=W
1065 MOV [DI]+WR_LEFTBYTE,AX ; trailing byte ;=W
1067 MOV BX,1 ;set number of positions to shift ;=W
1068 MOV AX,2 ;set option to shift left ;=W
1069 CALL SHIFT ;call shift 1 position toward left ;=W
1070 JMP LHJ260 ;exit ;=W
1072 ; Replace single byte character with single byte character ;=W
1074 LHJ220: TEST [DI]+WR_KEYCONF2,WR_DBC ;check if double byte character ;=W
1075 JNE LHJ230 ; continue with single byte ;=W
1077 MOV AX,[DI]+INC_KS ;get keystroke ;=W
1082 MOV ES,CX ;save offset of character to ;=W
1083 MOV SI,DX ; replace single byte ;=W
1086 POP SI ;restore registers ;=W
1089 JMP LHJ260 ;exit ;=W
1091 ; Replace single byte character with double byte character ;=W
1094 CALL CAL_COORS ;calculate cursor position ;=W
1095 MOV BX,[DI]+WR_ENBYTE ;get end byte of input field ;=W
1096 MOV AX,[DI]+WR_ENCHAR ;get end character of field ;=W
1097 CMP AX,ES:[SI]+ICB_CURCHAR ;is cursor past end character ;=W
1100 MOV BX,[DI]+WR_CUBYTE ;set cursor character position ;=W
1102 MOV AX,ES:[SI]+ICB_FIELDLEN ;get end of field position ;=W
1103 SUB AX,BX ;subtract to get the remaining space ;=W
1104 CMP AX,1 ;will byte fit ? ;=W
1107 CALL PCMBEEP_CALL ;error beep because replace char ;=W
1108 JMP LHJEXIT ; will not fit and exit ;=W
1110 LHJ250: MOV BX,ES:[SI]+ICB_FIELDLEN ;set ending byte ;=W
1111 MOV [DI]+WR_RIGHTBYTE,BX ;=W
1113 MOV BX,[DI]+WR_CUBYTE ;set markers for shift to remove ;=W
1114 INC BX ;adjust past replaced leading byte ;=W
1115 MOV [DI]+WR_LEFTBYTE,BX ; trailing byte ;=W
1117 MOV BX,1 ;set number of positions to shift ;=W
1118 MOV AX,1 ;set option to shift right ;=W
1119 CALL SHIFT ;call shift 1 position toward ;=W
1121 MOV AX,[DI]+INC_KS ;get keystroke ;=W
1126 MOV ES,CX ;save offset of character to ;=W
1127 MOV SI,DX ; replace double byte ;=W
1130 POP SI ;restore registers ;=W
1133 ; Calculate new ending and cursor coordinates ;=W
1136 CALL CAL_COORS ;calculate cursor position ;=W
1137 INC ES:[SI]+ICB_CURCHAR ;point to next char ;=W
1138 MOV BX,[DI]+WR_HRCHAR ;get begin. of horiz. wondow ;=W
1139 ADD BX,ES:[SI]+ICB_WIDTH ;add width to get end of window ;=W
1140 CMP BX,ES:[SI]+ICB_CURCHAR ;is cursor past end of window ? ;=W
1142 INC [DI]+WR_HRCHAR ;yes, adjust the horiz. window ;=W
1143 MOV AX,4 ;display delimiters "< >" ;=W
1144 CALL DELIMITER ;display delimiter ;=W
1146 CALL CAL_COORS ;calculate cursor position ;=W
1147 CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W
1149 TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W
1151 MOV ES:[SI]+ICB_CURCHAR,1 ;wrap to first character position
1152 MOV [DI]+WR_HRCHAR,1 ;reset the horiz. window ;=W
1153 MOV AX,3 ;display delimiters "[ >" ;=W
1154 CALL DELIMITER ;display delimiter ;=W
1158 DEC [DI]+WR_HRCHAR ;yes, adjust wind back one position ;=W
1159 MOV AX,5 ;display delimiters "< ]" ;=W
1160 CALL DELIMITER ;display delimiter ;=W
1161 TEST ES:[SI]+ICB_OPT2,ICB_AXD ;is autoexit option set ? ;=W
1163 OR [DI]+WR_KEYCONF2,WR_RET ;set autoexit flag ;=W
1165 CALL CAL_COORS ;calculate cursor position ;=W
1166 JMP LHJEXIT ;display field, set cursor, exit ;=W
1168 ; Process allowed keystroke in insert mode ;=W
1171 CALL CAL_COORS ;get cursor position ;=W
1172 CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W
1175 CALL PCMBEEP_CALL ;error beep key not defined ;=W
1176 JMP LHJEXIT ;exit ;=W
1178 ; Check if enough room available to insert single or double byte character ;=W
1181 MOV CX,ES:[SI]+ICB_FIELDSEG ;get segment of input buffer ;=W
1182 MOV DX,ES:[SI]+ICB_FIELDOFF ;get offset of input buffer ;=W
1184 ADD DX,[DI]+WR_CUBYTE ;add cursor offset into buffer ;=W
1185 DEC DX ;make zero based ;=W
1187 MOV BX,1 ;initialize to single byte ;=W
1189 TEST [DI]+WR_KEYCONF2,WR_DBC ;check for double byte character ;=W
1192 MOV BX,2 ;reset to double byte character ;=W
1195 CALL CAL_COORS ;calculate cursor position ;=W
1196 MOV BX,[DI]+WR_ENBYTE ;get end byte of input field ;=W
1197 MOV AX,[DI]+WR_ENCHAR ;get end character of field ;=W
1198 CMP AX,ES:[SI]+ICB_CURCHAR ;is cursor past end character ;=W
1201 MOV BX,[DI]+WR_CUBYTE ;set cursor character position ;=W
1203 MOV AX,ES:[SI]+ICB_FIELDLEN ;get end of field position ;=W
1204 SUB AX,BX ;subtract to get the remaining space ;=W
1206 CMP AX,BX ;will byte fit ? ;=W
1209 CALL PCMBEEP_CALL ;error beep replace character ;=W
1210 JMP LHJEXIT ; will not fit and exit ;=W
1212 ; Shift to insert single or double byte character, BX= # bytes to shift ;=W
1214 LHJ310: MOV AX,ES:[SI]+ICB_FIELDLEN ;set ending byte to make room in ;=W
1215 MOV [DI]+WR_RIGHTBYTE,AX ; buffer by shifting characters ;=W
1217 MOV AX,[DI]+WR_CUBYTE ;set markers for shift to remove ;=W
1218 MOV [DI]+WR_LEFTBYTE,AX ; trailing byte ;=W
1220 MOV AX,1 ;set option to shift right, BX= ;=W
1221 ; number of bytes to insert ;=W
1222 CALL SHIFT ;call shift 1 position toward ;=W
1224 MOV AX,[DI]+INC_KS ;get keystroke ;=W
1226 ; Insert single byte character ;=W
1228 CMP BX,2 ;check how many bytes should be ;=W
1229 JE LHJ320 ; inserted ;=W
1234 MOV ES,CX ;save offset of character to ;=W
1235 MOV SI,DX ; replace single byte ;=W
1236 MOV ES:[SI],AL ;insert single byte character ;=W
1238 POP SI ;restore registers ;=W
1243 ; Insert double byte character ;=W
1248 MOV ES,CX ;save offset of character to ;=W
1249 MOV SI,DX ; replace ;=W
1250 MOV ES:[SI],AX ;insert double byte character ;=W
1252 POP SI ;restore registers ;=W
1255 ; Calculate new ending and cursor coordinates ;=W
1258 CALL CAL_COORS ;get new end coordinates ;=W
1260 INC ES:[SI]+ICB_CURCHAR ;point to next char ;=W
1261 MOV BX,[DI]+WR_HRCHAR ;get begin. of horiz. wondow ;=W
1262 ADD BX,ES:[SI]+ICB_WIDTH ;add width to get end of window ;=W
1263 CMP BX,ES:[SI]+ICB_CURCHAR ;is cursor past end of window ? ;=W
1265 INC [DI]+WR_HRCHAR ;yes, adjust the horiz. window ;=W
1266 MOV AX,4 ;display delimiters "< >" ;=W
1267 CALL DELIMITER ;display delimiter ;=W
1269 CALL CAL_COORS ;calculate cursor position
1270 CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W
1272 TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W
1274 MOV ES:[SI]+ICB_CURCHAR,1 ;wrap to first character position
1275 MOV [DI]+WR_HRCHAR,1 ;reset the horiz. window ;=W
1276 MOV AX,3 ;display delimiters "[ >" ;=W
1277 CALL DELIMITER ;display delimiter ;=W
1280 DEC [DI]+WR_HRCHAR ;yes, adjust wind back one position ;=W
1281 MOV AX,5 ;display delimiters "< ]" ;=W
1282 CALL DELIMITER ;display delimiter ;=W
1283 TEST ES:[SI]+ICB_OPT2,ICB_AXD ;is autoexit option set ? ;=W
1285 OR [DI]+WR_KEYCONF2,WR_RET ;set autoexit flag ;=W
1287 CALL CAL_COORS ;calculate cursor position ;=W
1288 JMP LHJEXIT ;display cursor
1290 ; Display field & Exit ;=W
1293 CALL WORD PTR [DI]+WR_DISPLAY ;display current input buffer ;=W
1294 ; in left justified field ;=W
1297 CALL WORD PTR [DI]+WR_DISPLAY ;display current input buffer ;=W
1298 ; in left justified field ;=W
1299 TEST ES:[SI]+ICB_STATUS,ICB_CUR_ON ;is cursor on ?
1300 JNE LHJCUR ;cursor is already on, don't turn it on ;=W
1301 CALL CURSOR ;display cursor ;=W
1305 LEFT_H_JUST ENDP ;=W
1308 ;-----------------------------------------------------------------------------+
1312 ; Process keystroke and update display with input buffer changes :
1313 ; for the following functions: :
1315 ; Home key Up arrow Allowonce replace mode :
1316 ; End key Down arrow Allowonce insert mode :
1317 ; Left arrow Control end Allow replace mode :
1318 ; Right arrow Delete key Allow insert mode :
1321 ; Following information is used: :
1324 ; ÚÄ (ICB_FIELDSEG:ICB_FIELDOFF) Beginning address of input :
1325 ; ³ buffer in memory. :
1327 ; ³ ÚÄ (WR_CUBYTE) Byte offset into the input buffer :
1328 ; ³ ³ of where characters will be added :
1329 ; ³ ³ to input buffer. :
1331 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ :
1332 ; ³ S ³ L ³ T ³ L ³ T ³ S ³ S ³ ³ ³ ³ ³ ³ ³ ³ :
1333 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ :
1334 ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ :
1336 ; (ICB_FIELDLEN) Length of input field in bytes. :
1339 ; The following demonstrates the before and after input buffer :
1340 ; images. (S = Single byte, L = DBCS lead byte, T = DBCS trailing :
1343 ; Deleting a double byte: :
1344 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ :
1345 ; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ S ³ ³ ³ :
1346 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ :
1348 ; Deleting a single byte: :
1349 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ :
1350 ; ³ S ³ L ³ T ³ S ³ L ³ T ³ ³ S ³ L ³ T ³ L ³ T ³ ³ :
1351 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ :
1353 ; Backspace removal of a double byte: :
1354 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ :
1355 ; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ S ³ ³ ³ :
1356 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ :
1358 ; Backspace removal of a single byte: :
1359 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ :
1360 ; ³ S ³ S ³ S ³ S ³ L ³ T ³ ³ S ³ S ³ S ³ L ³ T ³ ³ :
1361 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÁÄÄÄÙ :
1363 ; Replacing a double byte with a double byte: :
1364 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ :
1365 ; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ L ³ T ³ S ³ :
1366 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÙ :
1368 ; Replacing a double byte with a single byte: (Option 1) :
1369 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ :
1370 ; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ S ³ S ³ ³ :
1371 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ :
1373 ; Replacing a double byte with a single byte: (Option 2) :
1374 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ :
1375 ; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ S ³ ³ S ³ :
1376 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ :
1378 ; Replacing a single byte with a single byte: :
1379 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ :
1380 ; ³ S ³ L ³ T ³ S ³ L ³ T ³ ³ S ³ L ³ T ³ S ³ L ³ T ³ :
1381 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ :
1383 ; Replacing a single byte with a double byte. :
1384 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ :
1385 ; ³ S ³ L ³ T ³ S ³ ³ ³ ³ S ³ L ³ T ³ L ³ T ³ ³ :
1386 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÙ :
1388 ; Replacing a single byte with a double byte without enough buffer: :
1389 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ :
1390 ; ³ S ³ L ³ T ³ S ³ L ³ T ³ ³ S ³ L ³ T ³ S ³ L ³ T ³ :
1391 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ :
1393 ; Inserting a single byte. :
1394 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ :
1395 ; ³ S ³ L ³ T ³ L ³ T ³ ³ ³ S ³ L ³ T ³ S ³ L ³ T ³ :
1396 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÙ :
1398 ; Inserting a single byte without enough buffer generate an error: :
1399 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ :
1400 ; ³ S ³ L ³ T ³ L ³ T ³ S ³ ³ S ³ L ³ T ³ L ³ T ³ S ³ :
1401 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ :
1402 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ :
1403 ; ³ S ³ L ³ T ³ S ³ S ³ ³ ³ S ³ L ³ T ³ S ³ S ³ ³ :
1404 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ :
1406 ; Inserting a double byte character: :
1407 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ :
1408 ; ³ S ³ L ³ T ³ S ³ ³ ³ ³ S ³ L ³ T ³ L ³ T ³ S ³ :
1409 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÙ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÙ :
1412 ; Entry: ES:SI = Points to current ICB :
1413 ; DS:DI = Points to PB :
1415 ; INC_KS = Keystroke from returned from PCINCHA :
1417 ; WR_KEYCONF = Bit flag inidicating the options set for INC_KS :
1418 ; WR_KEYCONF2 keystroke. :
1422 ;-----------------------------------------------------------------------------+
1426 ; Initialize right and left boundary markers
1428 MOV [DI]+WR_LEFTCHAR,1 ;set left character to beginning
1431 MOV AX,ES:[SI]+ICB_FIELDLEN ;set right marker past end of
1433 MOV [DI]+WR_RIGHTCHAR,AX
1435 TEST [DI]+WR_KEYCONF,WR_MASK ;check to see if editing key entered ;=W
1436 JNE LJ5 ;yes, must check for editing keys ;=W
1437 JMP LJ190 ;no, skip checks for editing keys ;=W
1442 LJ5: TEST [DI]+WR_KEYCONF,WR_HOM ;check if home key pressed
1446 ; add ICB_WHM option to process window home key movement
1449 MOV ES:[SI]+ICB_CURCHAR,1 ;initialize cursor to 1st byte
1450 ; position, assuming no windowing
1452 CALL CAL_COORS ;get cursor position ;=W
1453 JMP LJEXIT ; returns WR_CURROW, WR_CURROW
1458 LJ10: TEST [DI]+WR_KEYCONF,WR_END ;check if home key pressed
1462 ; add ICB_WEN to move cursor to end of current window row
1465 CALL CAL_COORS ;get current end of field info ;=W
1467 MOV AX,[DI]+WR_ENCHAR ;adjust one past end buffer charac
1469 MOV ES:[SI]+ICB_CURCHAR,AX ;set current cursor position to
1471 CALL CAL_COORS ;get cursor position ;=W
1472 CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W
1474 TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W
1476 MOV ES:[SI]+ICB_CURCHAR,1 ;wrap to first character position
1477 CALL CAL_COORS ;get cursor position
1480 TEST ES:[SI]+ICB_OPT2,ICB_AXC ;is autoexit option set ? ;=W
1482 OR [DI]+WR_KEYCONF2,WR_RET ;yes, set autoexit flag ;=W
1486 ; Process left arrow
1488 LJ20: TEST [DI]+WR_KEYCONF,WR_LFT ;check if left arrow key pressed
1492 ; add ICB_WAR option to wrap cursor on same row end to end
1495 CMP ES:[SI]+ICB_CURCHAR,1 ;check if cursor is at first
1496 JA LJ30 ; field position
1498 TEST ES:[SI]+ICB_OPT2,ICB_AXC ;is autoexit option set ? ;=W
1500 OR [DI]+WR_KEYCONF2,WR_RET ;yes, set autoexit flag ;=W
1503 TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W
1505 MOV AX,ES:[SI]+ICB_FIELDLEN ;get last position
1506 MOV ES:[SI]+ICB_CURCHAR,AX ;put as current position
1510 CALL PCMBEEP_CALL ;error beep
1513 LJ30: DEC ES:[SI]+ICB_CURCHAR ;adjust cursor to one position
1515 CALL CAL_COORS ;get cursor position ;=W
1518 ; Process right arrow
1520 LJ40: TEST [DI]+WR_KEYCONF,WR_RGT ;check if left arrow key pressed
1524 ; add ICB_CSW option to wrap cursor from top/bottom end to end
1528 ; add ICB_AXC option to auto enter if cursor reaches end
1532 ; add ICB_WAR option to wrap cursor on same row end to end
1535 CALL CAL_COORS ;get cursor position ;=W
1536 CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field
1539 CALL PCMBEEP_CALL ;error beep
1542 LJ50: INC ES:[SI]+ICB_CURCHAR ;adjust cursor to one position
1544 CALL CAL_COORS ;get cursor position ;=W
1545 CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W
1547 TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W
1549 MOV ES:[SI]+ICB_CURCHAR,1 ;wrap to first character position
1550 CALL CAL_COORS ;get cursor position
1553 TEST ES:[SI]+ICB_OPT2,ICB_AXC ;is autoexit option set ? ;=W
1555 OR [DI]+WR_KEYCONF2,WR_RET ;set autoexit flag ;=W
1562 ; adjust cursor position
1566 ; check for field wrap, exit, error beep
1569 ; Process down arrow
1572 ; adjust cursor position
1576 ; check for field wrap, exit, error beep
1579 ; Process cntrl+end key
1581 LJ80: TEST [DI]+WR_KEYCONF,WR_CED ;check if control+end key pressed
1584 CALL CAL_COORS ;get cursor position ;=W
1585 CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field
1588 CALL PCMBEEP_CALL ;error beep
1591 LJ90: CALL CAL_COORS ;get current end of field info ;=W
1593 MOV AX,ES:[SI]+ICB_FIELDLEN ;set rightmost area to refresh on
1594 MOV [DI]+WR_RIGHTDISP,AX ; display to entire field
1596 MOV BX,[DI]+WR_CUBYTE ;delete from current byte position
1599 CALL CAL_COORS ;get cursor position ;=W
1600 JMP LJ340 ;display field, set cursor, exit
1602 ; Process delete key
1604 LJ100: TEST [DI]+WR_KEYCONF,WR_DEL ;check if delete key pressed
1608 ; Add ICB_WDL option in off state to delete on current line only
1611 CALL CAL_COORS ;get cursor position ;=W
1612 CMP [DI]+WR_FIELDEND,1 ;check if cursor past end of field
1615 CALL REMOVE_CHAR ;remove character at current offst
1616 ; and shift remaining in place
1617 JMP LJ340 ;display field, set cursor, exit
1619 LJ110: CALL PCMBEEP_CALL ;error beep
1622 ; Process backspace key
1624 LJ130: TEST [DI]+WR_KEYCONF,WR_BCK ;check if backspace key pressed
1627 CMP ES:[SI]+ICB_CURCHAR,1 ;check if cursor is at first
1628 JA LJ140 ; field position
1630 TEST ES:[SI]+ICB_OPT2,ICB_AXC ;is autoexit option set ? ;=W
1632 OR [DI]+WR_KEYCONF2,WR_RET ;yes, set autoexit flag ;=W
1635 TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W
1637 MOV AX,ES:[SI]+ICB_FIELDLEN ;get last position
1638 MOV ES:[SI]+ICB_CURCHAR,AX ;put as current position
1642 CALL PCMBEEP_CALL ;error beep
1645 LJ140: DEC ES:[SI]+ICB_CURCHAR ;adjust cursor to one position
1647 CALL CAL_COORS ;get cursor position ;=W
1648 CALL REMOVE_CHAR ;remove character at current offst
1649 ; and shift remaining in place
1651 CALL CAL_COORS ;get cursor position ;=W
1652 JMP LJ340 ;display field, set cursor, exit
1654 ; Process insert key toggle
1656 LJ160: TEST [DI]+WR_KEYCONF,WR_INS ;check if insert key pressed
1657 JE LJ180 ; if not, continue
1659 TEST ES:[SI]+ICB_STATUS,ICB_SINS ;check if in insert mode ?
1660 JE LJ165 ;no, put in insert mode
1662 MOV BX,[DI]+IN_CURNOR ;set cursor size for normal
1663 MOV [DI]+WR_CURSIZE,BX ; cursor
1665 AND ES:[SI]+ICB_STATUS,NOT ICB_SINS
1666 JMP LJ170 ;turn insert mode off
1668 LJ165: MOV BX,[DI]+IN_CURINS ;set cursor size for insert
1669 MOV [DI]+WR_CURSIZE,BX ; cursor
1671 OR ES:[SI]+ICB_STATUS,ICB_SINS
1672 ;turn insert mode on
1676 PUSH DS ;save registers
1679 MOV DI,40H ;point DS:DI to KB_FLAG in BIOS
1682 MOV AX,[DI] ;get current BIOS KB_FLAG
1684 AND AX,NOT WR_INSSTATE ;set BIOS insert active flag off
1686 TEST ES:[SI]+ICB_STATUS,ICB_SINS
1687 JE LJ175 ;check if insert should be set on
1689 OR AX,WR_INSSTATE ;set BIOS insert active flag on
1691 LJ175: POP DI ;restore registers
1696 ; Process allowonce key option
1703 ; adjust input buffer
1707 ; check for field wrap, exit, error beep
1711 ; adjust cursor position
1714 ; Process allowed keystroke in replace mode
1716 LJ190: TEST [DI]+WR_KEYCONF,WR_ALL ;check if allow key pressed
1719 CALL PCMBEEP_CALL ;error beep key not defined
1722 LJ195: TEST ES:[SI]+ICB_STATUS,ICB_SINS
1723 JE LJ198 ;check if insert is active
1725 JMP LJ270 ;do insert display
1728 CALL CAL_COORS ;get cursor position ;=W
1729 CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field
1732 CALL PCMBEEP_CALL ;error beep key not defined
1735 ; Check if character to be replaced in field buffer is double byte character
1737 LJ200: PUSH ES ;save registers
1740 PUSH ES:[SI]+ICB_FIELDSEG ;get segment of input buffer
1741 PUSH ES:[SI]+ICB_FIELDOFF ;get offset of input buffer
1745 ADD SI,[DI]+WR_CUBYTE ;add cursor offset into buffer
1746 DEC SI ;make zero based
1748 MOV CX,ES ;save offset of character to
1751 MOV AL,ES:[SI] ;get byte that cursor is pointing
1752 MOV [DI]+DBC_KS,AL ; to check if DBCS
1753 CALL PCINDBC_CALL ;call routine to check if char
1754 ; is lead double byte char
1756 POP SI ;restore registers
1759 TEST [DI]+DBC_STAT,DBC_DBCS ;check if char is lead DBCS
1760 JE LJ220 ; if no, jump to single byte code
1762 ; Replace double byte character with double byte character
1764 TEST [DI]+WR_KEYCONF2,WR_DBC ;check if keystroke is DBC
1765 JE LJ210 ;continue with single byte
1767 MOV AX,[DI]+INC_KS ;set double byte character to
1768 ; input buffer replacing
1769 ; double byte character
1773 MOV ES,CX ;save offset of character to
1775 MOV ES:[SI],AX ;replace double byte
1777 POP SI ;restore registers
1782 ; Replace double byte character with single byte character
1784 LJ210: MOV AX,[DI]+INC_KS ;get keystroke and replace double
1785 ; byte with single byte
1790 MOV ES,CX ;save offset of character to
1791 MOV SI,DX ; replace single byte
1794 POP SI ;restore registers
1797 MOV AX,ES:[SI]+ICB_FIELDLEN ;set ending byte
1798 MOV [DI]+WR_RIGHTBYTE,AX
1800 MOV AX,[DI]+WR_CUBYTE ;set markers for shift to remove
1801 INC AX ;adjust past replaced leading byte ;=W
1802 MOV [DI]+WR_LEFTBYTE,AX ; trailing byte
1804 MOV BX,1 ;set number of positions to shift
1805 MOV AX,2 ;set option to shift left
1806 CALL SHIFT ;call shift 1 position toward left
1809 ; Replace single byte character with single byte character
1811 LJ220: TEST [DI]+WR_KEYCONF2,WR_DBC ;check if double byte character
1812 JNE LJ230 ; continue with single byte
1814 MOV AX,[DI]+INC_KS ;get keystroke
1819 MOV ES,CX ;save offset of character to
1820 MOV SI,DX ; replace single byte
1823 POP SI ;restore registers
1828 ; Replace single byte character with double byte character
1830 LJ230: MOV BX,ES:[SI]+ICB_CURCHAR ;set cursor character position
1831 MOV [DI]+WR_LEFTCHAR,BX ; to left marker
1833 CALL CAL_COORS ;get the current end of field ;=W
1835 MOV AX,[DI]+WR_ENCHAR ;get end character of field
1836 CMP AX,ES:[SI]+ICB_CURCHAR ;is cursor past end character
1839 MOV AX,ES:[SI]+ICB_CURCHAR ;cursor is past last char
1841 LJ240: MOV [DI]+WR_RIGHTCHAR,AX ;set right marker
1843 MOV BX,1 ;One byte is already available
1844 ; check if room for trailing byte
1845 MOV AX,1 ;set up call to LEFT_DISP to
1846 CALL WORD PTR [DI]+WR_DISPLAY ; determine if additional byte
1847 ; will fit in input buffer
1848 CMP AX,0 ;check if double byte character
1851 CALL PCMBEEP_CALL ;error beep because replace char
1852 JMP LJEXIT ; will not fit and exit
1854 LJ250: MOV BX,ES:[SI]+ICB_FIELDLEN ;set ending byte
1855 MOV [DI]+WR_RIGHTBYTE,BX
1857 MOV BX,[DI]+WR_CUBYTE ;set markers for shift to remove
1858 INC BX ;adjust past replaced leading byte
1859 MOV [DI]+WR_LEFTBYTE,BX ; trailing byte
1861 MOV BX,1 ;set number of positions to shift
1862 MOV AX,1 ;set option to shift right
1863 CALL SHIFT ;call shift 1 position toward
1865 MOV AX,[DI]+INC_KS ;get keystroke
1870 MOV ES,CX ;save offset of character to
1871 MOV SI,DX ; replace double byte
1874 POP SI ;restore registers
1877 ; Calculate new ending and cursor coordinates
1880 MOV BX,[DI]+WR_ENCHAR ;set rightmost area to refresh on ;=W
1881 CALL CAL_COORS ;get new end coordinates ;=W
1882 CMP BX,[DI]+WR_ENCHAR ;is old END_CHAR > new END_CHAR ? ;=W
1883 JG LJ261 ;yes, use old END_CHAR (so display ;=W
1884 MOV BX,[DI]+WR_ENCHAR ; is updated correctly)
1886 LJ261: ;set rightmost area to refresh on ;=W
1887 MOV [DI]+WR_RIGHTDISP,BX ; display to new ending character
1889 INC ES:[SI]+ICB_CURCHAR ;point to next char
1891 CALL CAL_COORS ;get cursor position ;=W
1892 CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W
1894 TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W
1896 MOV ES:[SI]+ICB_CURCHAR,1 ;wrap to first character position
1897 JMP LJ340 ;display field, set cursor, exit
1899 TEST ES:[SI]+ICB_OPT2,ICB_AXD ;is autoexit option set ? ;=W
1901 OR [DI]+WR_KEYCONF2,WR_RET ;set autoexit flag ;=W
1903 JMP LJ340 ;display field, set cursor, exit
1905 ; Process allowed keystroke in insert mode
1908 CALL CAL_COORS ;get cursor position ;=W
1909 CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field
1912 CALL PCMBEEP_CALL ;error beep key not defined
1915 ; Check if enough room available to insert single or double byte character
1918 MOV CX,ES:[SI]+ICB_FIELDSEG ;get segment of input buffer
1919 MOV DX,ES:[SI]+ICB_FIELDOFF ;get offset of input buffer
1921 ADD DX,[DI]+WR_CUBYTE ;add cursor offset into buffer
1922 DEC DX ;make zero based
1924 MOV BX,1 ;initialize to single byte
1926 TEST [DI]+WR_KEYCONF2,WR_DBC ;check for double byte character
1929 MOV BX,2 ;reset to double byte character
1931 LJ290: MOV AX,ES:[SI]+ICB_CURCHAR ;set cursor character position
1932 MOV [DI]+WR_LEFTCHAR,AX ; to left marker
1934 CALL CAL_COORS ;get the current end of field ;=W
1936 MOV AX,[DI]+WR_ENCHAR ;get end character of field
1938 CMP AX,ES:[SI]+ICB_CURCHAR ;is cursor past end character
1941 MOV AX,ES:[SI]+ICB_CURCHAR ;cursor is past last char
1944 LJ300: MOV [DI]+WR_RIGHTCHAR,AX ;set right marker
1946 MOV AX,1 ;set up call to LEFT_DISP to
1947 CALL WORD PTR [DI]+WR_DISPLAY ; determine if additional byte
1948 ; will fit in input buffer
1949 ; BX= number of bytes to insert
1950 CMP AX,0 ;check if double byte character
1953 CALL PCMBEEP_CALL ;error beep replace character
1954 JMP LJEXIT ; will not fit and exit
1956 ; Shift to insert single or double byte character, BX= # bytes to shift
1958 LJ310: MOV AX,ES:[SI]+ICB_FIELDLEN ;set ending byte to make room in
1959 MOV [DI]+WR_RIGHTBYTE,AX ; buffer by shifting characters
1961 MOV AX,[DI]+WR_CUBYTE ;set markers for shift to remove
1962 MOV [DI]+WR_LEFTBYTE,AX ; trailing byte
1964 MOV AX,1 ;set option to shift right, BX=
1965 ; number of bytes to insert
1966 CALL SHIFT ;call shift 1 position toward
1968 MOV AX,[DI]+INC_KS ;get keystroke
1970 ; Insert single byte character
1972 CMP BX,2 ;check how many bytes should be
1978 MOV ES,CX ;save offset of character to
1979 MOV SI,DX ; replace single byte
1980 MOV ES:[SI],AL ;insert single byte character
1982 POP SI ;restore registers
1987 ; Insert double byte character
1992 MOV ES,CX ;save offset of character to
1994 MOV ES:[SI],AX ;insert double byte character
1996 POP SI ;restore registers
1999 ; Calculate new ending and cursor coordinates
2002 CALL CAL_COORS ;get new end coordinates ;=W
2004 MOV AX,[DI]+WR_ENCHAR ;set rightmost area to refresh on
2005 MOV [DI]+WR_RIGHTDISP,AX ; display to old ending character
2007 INC ES:[SI]+ICB_CURCHAR ;point to next char
2009 CALL CAL_COORS ;get cursor position ;=W
2010 CMP [DI]+WR_FIELDEND,0 ;check if cursor past end of field ;=W
2012 TEST ES:[SI]+ICB_OPT2,ICB_CSW ;is cursor wrap option on ? ;=W
2014 MOV ES:[SI]+ICB_CURCHAR,1 ;wrap to first character position
2015 JMP LJ340 ;display field, set cursor, exit
2017 TEST ES:[SI]+ICB_OPT2,ICB_AXD ;is autoexit option set ? ;=W
2019 OR [DI]+WR_KEYCONF2,WR_RET ;set autoexit flag ;=W
2024 MOV AX,ES:[SI]+ICB_CURCHAR ;set left character to cursor
2025 DEC AX ; last cursor position
2026 MOV [DI]+WR_LEFTCHAR,AX
2028 MOV AX,[DI]+WR_RIGHTDISP ;set right character marker to ;=W
2029 MOV [DI]+WR_RIGHTCHAR,AX ; max possible field length
2031 CALL CAL_COORS ;get end of field char, byte ;=W
2032 ; and next byte positions
2034 MOV AX,2 ;set display option
2035 CALL WORD PTR [DI]+WR_DISPLAY ;display current input buffer
2036 ; in left justified field
2041 TEST ES:[SI]+ICB_STATUS,ICB_CUR_ON ;is cursor on ?
2042 JNE LJCUR ;cursor is already on, don't turn it on ;=W
2043 CALL CURSOR ;display cursor ;=W
2048 ;-----------------------------------------------------------------------------+
2052 ; Calculates character coordinates based on the display format :
2053 ; currently active (windowing and horizontal display). :
2055 ; The following examples demonstrate the values that are set on :
2056 ; exit from this routine: :
2059 ; Example: Horizontal field coordinates calculated. :
2061 ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ :
2062 ; ³123456789012345678901234567890 :
2064 ; ³3 [sLtLtssss....] :
2067 ; ³ ³ ÀÄ WR_ENCHAR = 7 :
2068 ; ³ ³ WR_ENBYTE = 9 :
2069 ; ³ ³ WR_RGCHAR = 7 :
2071 ; ³ ÀÄÄÄÄÄÄ WR_CUCHAR = 3 :
2076 ; ³ WR_CURCOL = 13 :
2078 ; ÀÄÄÄÄÄÄÄÄÄ WR_LFCHAR = 1 :
2082 ; Example: Horizontal field scroll coordinates calculated: :
2084 ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ :
2085 ; ³123456789012345678901234567890 :
2087 ; ³3 s³LtLt ³Ltsss..... :
2091 ; ³ ³ ³ À WR_ENCHAR = 7 :
2092 ; ³ ³ ³ WR_ENBYTE = 10 :
2093 ; ³ ³ ³ WR_RGCHAR = 7 :
2095 ; ³ ³ ÀÄÄÄÄÄÄÄÄ WR_CUCHAR = 3 :
2096 ; ³ ³ WR_CUBYTE = 4 :
2097 ; ³ ³ WR_UPCHAR = 3 :
2098 ; ³ ³ WR_DNCHAR = 3 :
2099 ; ³ ³ WR_CURROW = 3 :
2100 ; ³ ³ WR_CURCOL = 14 :
2102 ; ³ ÀÄÄÄÄÄÄÄÄÄÄ WR_HRCHAR = 2 :
2104 ; ÀÄÄÄÄÄÄÄÄÄÄÄÄ WR_LFCHAR = 1 :
2108 ; Example: Windowed field coordinates calculated. :
2110 ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ :
2111 ; ³123456789012345678901234567890 :
2112 ; ³2 ÚÄÄÄÄÄÄÄÄÄÄÄÄÄ WR_LFCHAR= 6 :
2113 ; ³3 ³ ÚÄÄÄÄÄÄÄÄ WR_UPCHAR= 3 :
2117 ; ³7 ³ Ú³³ÀÄÄÄÄÄÄ WR_RGCHAR= 10 :
2118 ; ³8 Àij³ÀÄÄÄÄÄÄÄ WR_ENCHAR= 9 :
2120 ; ³ÀÄÄÄÄÄÄÂÄ WR_CUCHAR= 8 :
2121 ; ³ ÃÄ WR_CURCOL= 24 :
2122 ; ³ ÀÄ WR_CURROW= 6 :
2124 ; ÀÄÄÄÄÄÄÄÄÄ WR_DNCHAR= 13 :
2127 ; Entry: ICB_CURCHAR = The character position into the input field from :
2128 ; which the exit coordinates will be calculated. :
2130 ; WR_HRCHAR = The character position into the input field that :
2131 ; is currently the first displayed character of the :
2132 ; horizontal window. :
2134 ; ICB_WIDTH = The width of windowed or horizontal scroll field. :
2136 ; ICB_FIELDLEN = Input field buffer length. :
2138 ; ICB_FIELDOFF = Input field buffer offset. :
2140 ; ICB_FIELDSEG = Input field buffer segment. :
2143 ; Exit: WR_RGCHAR = Character offset into input buffer of the character :
2144 ; appearing at the beginning of the current line that :
2145 ; WR_CUCHAR is located on. :
2147 ; WR_LFCHAR = Character offset into input buffer of the character :
2148 ; appearing at the end of the current line that :
2149 ; WR_CUCHAR is located on. :
2151 ; WR_UPCHAR = Character offset into input buffer of the character :
2152 ; displayed directly above the position that :
2153 ; WR_CUCHAR is located on. :
2155 ; WR_DNCHAR = Character offset into input buffer of the character :
2156 ; displayed directly below the position that :
2157 ; WR_CUCHAR is located on. :
2159 ; WR_ENCHAR = Number of characters currently entered in the :
2160 ; field. This value may be less than the number :
2161 ; of bytes used to represent the characters if :
2162 ; double byte characters are present. :
2164 ; WR_CURROW = Actual row offset into the video buffer of the :
2165 ; character specified by WR_CURCHAR. :
2167 ; WR_CURCOL = Actual column offset into the video buffer of the :
2168 ; character specified by WR_CUCHAR. :
2170 ; WR_ENBYTE = Number of bytes currently used to represent :
2171 ; entered characters in the buffer. This counter :
2172 ; can be used to calculate the current end :
2173 ; position of the entered data in the field. :
2175 ; WR_CUBYTE = Number of bytes into input field where WR_CUCHAR :
2178 ; WR_CUCHAR = Offset of current cursor position in input field. : ;=W
2180 ; WR_HRBYTE = Number of bytes into input field where WR_HRCHAR :
2183 ; WR_FIELDEND = Boolean flag, 0 = cursor not past end of field : ;=W
2184 ; 1 = cursor is past end of field : ;=W
2186 ;-----------------------------------------------------------------------------+
2190 PUSH AX ;save registers
2198 ; initialize general variables for all display modes ;=W
2200 MOV [DI]+WR_FIELDEND,0 ;initialize boolean flag that ;=W
2201 ;cursor is not past end of field ;=W
2202 MOV AX,ES:[SI]+ICB_CURCHAR ;get current char. offset ;=W
2203 MOV [DI]+WR_CUCHAR,AX ;save it ;=W
2205 MOV AX,ES:[SI]+ICB_ROW ;initialize row offset of field ;=W
2207 MOV [DI]+WR_CURROW,AX ;char row offset inot video buf ;=W
2208 MOV AX,ES:[SI]+ICB_COL ;initialize col offset of field ;=W
2210 MOV [DI]+WR_CURCOL,AX ;char col offset into video buf ;=W
2212 MOV [DI]+WR_LFCHAR,1 ;leftmost character possible char ;=W
2213 MOV [DI]+WR_RGCHAR,1 ;rightmost character possible char ;=W
2214 MOV [DI]+WR_ENBYTE,0 ;end byte of data in input buffer ;=W
2215 MOV [DI]+WR_ENCHAR,0 ;end character in input buffer ;=W
2216 MOV [DI]+WR_HRBYTE,1 ;byte of first char in horz. window ;=W
2218 MOV AX,[DI]+WR_CUCHAR ;get current position ;=W
2219 MOV [DI]+WR_UPCHAR,1 ;topmost char in current column ;=W
2220 MOV [DI]+WR_DNCHAR,1 ;bottommost char in current column ;=W
2222 MOV BP,0 ;have not found current char yet ;=W
2223 MOV CX,1 ;counter tracking number of bytes ;=W
2224 MOV DX,1 ;counter tracking number of chars ;=W
2226 ; Determine display format of field
2228 TEST ES:[SI]+ICB_OPT3,ICB_WIN ;check if windowing option on
2231 JMP CC200 ;process window option
2233 CC10: TEST ES:[SI]+ICB_OPT3,ICB_HOR ;check if horizontal scroll option
2236 JMP CC100 ;process horizontal scroll
2238 ; Process fully displayed horizontal field
2241 MOV [DI]+WR_HRCHAR,1 ;leftmost character possible char
2243 ; Examine the next byte in the input buffer
2245 CC30: CMP CX,ES:[SI]+ICB_FIELDLEN ;check if entire field has been
2246 JBE CC35 ; scanned and exit
2248 CMP BP,0 ;found current char yet ? ;=W
2249 JE CC40 ;no, find it ;=W
2252 CC35: PUSH ES ;save registers
2255 PUSH ES:[SI]+ICB_FIELDSEG ;get segment of input buffer
2256 PUSH ES:[SI]+ICB_FIELDOFF ;get offset of input buffer
2260 DEC CX ;make byte count zero based
2261 ADD SI,CX ;add byte count to input fld offst
2262 INC CX ;make byte count one based
2263 MOV AL,ES:[SI] ;get byte in input buffer to
2264 MOV [DI]+DBC_KS,AL ; check if DBCS
2265 CALL PCINDBC_CALL ;call routine to check if char
2266 ; is lead double byte char
2268 POP SI ;restore registers
2271 ; Check if end data byte and character should be updated
2273 CMP AL,WR_BLANK ;check if blanking character found
2274 JE CC40 ;now adjust pointers
2276 MOV [DI]+WR_ENBYTE,CX ;set current byte count
2277 MOV [DI]+WR_ENCHAR,DX ;set current character count
2278 MOV [DI]+WR_RGCHAR,DX ;set right most character
2280 ; Check if current character pointer
2282 CC40: CMP [DI]+WR_CUCHAR,DX ;check if current character found
2285 MOV BP,1 ;current char found ;=W
2286 MOV [DI]+WR_UPCHAR,DX ;set up and down character
2287 MOV [DI]+WR_DNCHAR,DX ; to current character
2289 MOV [DI]+WR_CUBYTE,CX ;set current character byte count
2290 ADD [DI]+WR_CURCOL,CX ;set actual column of cursor based
2291 DEC [DI]+WR_CURCOL ; on current character byte count ;=W
2293 ; Increment pointers and counters to next character and byte position check
2295 CC50: INC CX ;adjust byte counter
2296 INC DX ;adjust character counter
2298 TEST [DI]+DBC_STAT,DBC_DBCS ;check if byte is leading DBC byte
2301 INC CX ;adjust byte count for trail byte
2309 ; Calculate horizontal scroll coordinates
2312 MOV AX,[DI]+WR_CUCHAR ;initialize current character
2313 CMP AX,[DI]+WR_HRCHAR ;horizontal display position must
2314 JAE CC120 ; not be less than current char
2316 MOV [DI]+WR_HRCHAR,AX ;set current char position as
2317 ; new horizontal position
2319 ; Examine the next byte in the input buffer
2321 CC120: CMP CX,ES:[SI]+ICB_FIELDLEN ;check if entire field has been
2322 JBE CC122 ; scanned and exit ;=W
2324 CMP BP,0 ;found current char yet ? ;=W
2325 JE CC130 ;no, find it ;=W
2329 PUSH ES ;save registers
2332 PUSH ES:[SI]+ICB_FIELDSEG ;get segment of input buffer
2333 PUSH ES:[SI]+ICB_FIELDOFF ;get offset of input buffer
2337 DEC CX ;make byte count zero based
2338 ADD SI,CX ;add byte count to input fld offst
2339 INC CX ;make byte count one based
2340 MOV AL,ES:[SI] ;get byte in input buffer to
2341 MOV [DI]+DBC_KS,AL ; check if DBCS
2342 CALL PCINDBC_CALL ;call routine to check if char
2343 ; is lead double byte char
2345 POP SI ;restore registers
2348 ; Set WR_HRBYTE to correct byte count ;=W
2350 CMP [DI]+WR_HRCHAR,DX ;is this position the first char ;=W
2351 ;in the horizl. window ? ;=W
2354 MOV [DI]+WR_HRBYTE,CX ;save # byte for first char in h. wind. ;=W
2356 ; Check if end data byte and character should be updated
2358 CC125: CMP AL,WR_BLANK ;check if blanking character found
2359 JE CC130 ;now adjust pointers
2361 MOV [DI]+WR_ENBYTE,CX ;set current byte count
2362 MOV [DI]+WR_ENCHAR,DX ;set current character count
2363 MOV [DI]+WR_RGCHAR,DX ;set right most character
2365 ; Check if current character pointer
2367 CC130: CMP [DI]+WR_CUCHAR,DX ;check if current character found
2370 MOV BP,1 ;current char found
2371 MOV [DI]+WR_UPCHAR,DX ;set up and down character
2372 MOV [DI]+WR_DNCHAR,DX ; to current character
2374 MOV [DI]+WR_CUBYTE,CX ;set current character byte count
2375 MOV BX,CX ;set actual column of cursor based ;=W
2376 ; on current character byte count ;=W
2377 SUB BX,[DI]+WR_HRBYTE ;subtract beginning of horiz. wind. ;=W
2378 ADD [DI]+WR_CURCOL,BX ;add to window offset = new column ;=W
2380 ; Increment pointers and counters to next character and byte position check
2382 CC140: INC CX ;adjust byte counter
2383 INC DX ;adjust character counter
2385 TEST [DI]+DBC_STAT,DBC_DBCS ;check if byte is leading DBC byte
2388 INC CX ;adjust byte count for trail byte
2396 ; Calculate windowing coordinates ;=W
2400 ; Examine the next byte in the input buffer ;=W
2402 CMP CX,ES:[SI]+ICB_FIELDLEN ;check if entire field has been ;=W
2403 JBE CC235 ; scanned and exit ;=W
2405 CMP BP,0 ;found current char yet ? ;=W
2406 JE CC240 ;no, find it ;=W
2408 JMP CCBYE ;boolean flag should have been set ;=W
2409 ; already, if needed ;=W
2410 CC235: PUSH ES ;save registers ;=W
2413 PUSH ES:[SI]+ICB_FIELDSEG ;get segment of input buffer ;=W
2414 PUSH ES:[SI]+ICB_FIELDOFF ;get offset of input buffer ;=W
2418 DEC CX ;make byte count zero based ;=W
2419 ADD SI,CX ;add byte count to input fld offst ;=W
2420 INC CX ;make byte count one based ;=W
2421 MOV AL,ES:[SI] ;get byte in input buffer to ;=W
2422 MOV [DI]+DBC_KS,AL ; check if DBCS ;=W
2423 CALL PCINDBC_CALL ;call routine to check if char ;=W
2424 ; is lead double byte char ;=W
2426 POP SI ;restore registers ;=W
2429 ; Check if end data byte and character should be updated ;=W
2431 CMP AL,WR_BLANK ;check if blanking character found ;=W
2432 JE CC240 ;now adjust pointers ;=W
2434 MOV [DI]+WR_ENBYTE,CX ;set current byte count ;=W
2435 MOV [DI]+WR_ENCHAR,DX ;set current character count ;=W
2436 MOV [DI]+WR_RGCHAR,DX ;set right most character ;=W
2438 ; Check if current character pointer ;=W
2441 CMP [DI]+WR_CUCHAR,DX ;check if current character found ;=W
2444 MOV BP,1 ;found current char
2445 MOV [DI]+WR_CUBYTE,CX ;set current character byte count ;=W
2447 PUSH DX ;needed for division ;=W
2448 MOV AX,CX ;get current cursor pos. in field ;=W
2449 DEC AX ;make it zero based for divide ;=W
2451 CMP CX,ES:[SI]+ICB_FIELDLEN ;are we past end of field ? ;=W
2453 MOV [DI]+WR_FIELDEND,1 ;yes, set boolean flag ;=W
2454 DEC AX ;make cursor pos. be inside field ;=W
2456 CWD ;calculate current row,column ;=W
2457 IDIV ES:[SI]+ICB_WIDTH ; row = cur_byte / width-1 ;=W
2458 ; col = cur_byte mod width-1 ;=W
2459 INC DX ;reposition cursor in correct pos. ;=W
2462 CWD ;calculate current row,column for ;=W
2463 IDIV ES:[SI]+ICB_WIDTH ; cursor positions inside the field ;=W
2464 ; row = cur_byte / width of field ;=W
2465 ; col = cur_byte mod width of field ;=W
2467 ADD [DI]+WR_CURROW,AX ;set actual row of cursor ;=W
2468 ADD [DI]+WR_CURCOL,DX ;set actual column of cursor ;=W
2470 MOV BX,CX ;calculate WR_LFCHAR ;=W
2471 CC245: DEC BX ;get the correct cur_byte ;=W
2472 MOV AX,BX ;cur_byte/width ;=W
2474 IDIV ES:[SI]+ICB_WIDTH ;=W
2475 CMP DX,0 ;is the remainder zero ? ;=W
2476 JNE CC245 ;no, not at beginning of row, do again ;=W
2478 MOV [DI]+WR_LFCHAR,BX ;yes, this is beginning of row ;=W
2482 ; Increment pointers and counters to next character and byte position check ;=W
2484 CC250: INC CX ;adjust byte counter ;=W
2485 INC DX ;adjust character counter ;=W
2487 TEST [DI]+DBC_STAT,DBC_DBCS ;check if byte is leading DBC byte ;=W
2490 INC CX ;adjust byte count for trail byte ;=W
2497 MOV AX,[DI]+WR_CUBYTE ;is cursor past end of field ;=W
2498 CMP AX,ES:[SI]+ICB_FIELDLEN ;?? ;=W
2501 MOV [DI]+WR_FIELDEND,1 ;yes, set boolean flag ;=W
2503 MOV AX,[DI]+WR_ENBYTE ;set ICB_ENDBYTE ;=W
2504 MOV ES:[SI]+ICB_ENDBYTE,AX ;=W
2506 MOV AX,[DI]+WR_HRBYTE ;set ICB_HRSTART ;=W
2507 MOV ES:[SI]+ICB_HRSTART,AX ;=W
2510 POP SI ;restore registers
2512 POP DX ;restore registers
2521 ;-----------------------------------------------------------------------------+ ;=W
2523 ; SET_DISP_ADDR : ;=W
2525 ; Determine which display routine to use. The choice is between : ;=W
2526 ; left justified, right justified, double byte support, no double : ;=W
2527 ; byte support, windowing, horizontal scrolling. : ;=W
2528 ; Also pick the justify routine to use. : ;=W
2530 ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ : ;=W
2532 ; ÀÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÙ : ;=W
2533 ; ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄ¿ : ;=W
2534 ; ÚÄÄÄÄÁÄÄÄÄ¿ ³ ³ ÚÄÄÄÄÁÄÄÄÄÄ¿ ³ ³ : ;=W
2535 ; ³LEFT_DISP³ ³ ³ ³RIGHT_DISP³ ³ ³ : ;=W
2536 ; ÀÄÄÄÄÄÄÄÄÄÙ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÙ ³ ³ : ;=W
2537 ; ÚÄÄÄÄÄÁÄÄÄÄÄ¿ ³ ÚÄÄÄÄÄÄÁÄÄÄÄÄ¿ ³ : ;=W
2538 ; ³LEFT_H_DISP³ ³ ³RIGHT_H_DISP³ ³ : ;=W
2539 ; ÀÄÄÄÄÄÄÄÄÄÄÄÙ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ : ;=W
2540 ; ÚÄÄÄÄÄÁÄÄÄÄ¿ ÚÄÄÄÄÄÄÁÄÄÄÄ¿ : ;=W
2541 ; ³LEFTS_DISP³ ³RIGHTS_DISP³ : ;=W
2542 ; ÀÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÙ : ;=W
2548 ; DISPLAY ROUTINES : ;=W
2549 ; LEFT_DISP - left justified, double byte support, windowing : ;=W
2550 ; LEFTS_DISP - left justified, no double byte support, windowing : ;=W
2551 ; LEFT_H_DISP - left justified, double byte support, horizontal scrolling : ;=W
2552 ; RIGHT_DISP - right justified, double byte support, windowing : ;=W
2553 ; RIGHTS_DISP - right justified, no double byte support, windowing : ;=W
2554 ; RIGHT_H_DISP - right justified, double byte support, horizontal scrolling : ;=W
2556 ; JUSTIFY ROUTINES : ;=W
2557 ; LEFT_H_JUST - left justified, horizontal scrolling : ;=W
2558 ; LEFT_JUST - left justified, windowing : ;=W
2559 ; RIGHT_H_JUST - right justified, horizontal scrolling : ;=W
2560 ; RIGHT_JUST - right justified, windowing : ;=W
2562 ; Entry: ES:SI - ICB control block : ;=W
2563 ; DS:DI - IN control block : ;=W
2566 ;-----------------------------------------------------------------------------+ ;=W
2568 SET_DISP_ADDR PROC NEAR ;=W
2573 TEST ES:[SI]+ICB_OPT1,ICB_RJU ;check if field right just ;=W
2574 JNE SD20 ;if yes, jump ;=W
2576 ; Display value of input buffer left justified ;=W
2578 TEST ES:[SI]+ICB_OPT3,ICB_HOR ;check if field is in horizontial ;=W
2579 JE SD10 ;no, windowing mode ;=W
2581 MOV AX,OFFSET LEFT_H_DISP ;=W
2582 MOV BX,OFFSET LEFT_H_JUST ;=W
2586 MOV AX,OFFSET LEFT_DISP ;=W
2587 MOV BX,OFFSET LEFT_JUST ;=W
2589 TEST DS:[DI]+IN_OPT,IN_ADBCS ;check if double byte is active ;=W
2591 MOV AX,OFFSET LEFTS_DISP ;no, single byte only ;=W
2594 ; Display default value of input buffer right justified ;=W
2597 TEST ES:[SI]+ICB_OPT3,ICB_HOR ;check if field is in horizontial ;=W
2598 JE SD30 ;no, windowing mode ;=W
2600 MOV AX,OFFSET RIGHT_H_DISP ;=W
2601 MOV BX,OFFSET RIGHT_H_JUST ;=W
2605 MOV AX,OFFSET RIGHT_DISP ;=W
2606 MOV BX,OFFSET RIGHT_DISP ;=W
2608 TEST DS:[DI]+IN_OPT,IN_ADBCS ;check if double byte is active ;=W
2610 MOV AX,OFFSET RIGHTS_DISP ;no, single byte only ;=W
2613 MOV DS:[DI]+WR_DISPLAY,AX ;save addr of routine to call ;=W
2614 MOV DS:[DI]+WR_JUSTIFY,BX ;save addr of routine to call ;=W
2620 SET_DISP_ADDR ENDP ;=W
2623 ;-----------------------------------------------------------------------------+ ;=W
2631 ;-----------------------------------------------------------------------------+ ;=W
2633 RIGHTS_DISP PROC NEAR ;=W
2640 RIGHTS_DISP ENDP ;=W
2643 ;-----------------------------------------------------------------------------+
2651 ;-----------------------------------------------------------------------------+
2653 RIGHT_H_DISP PROC NEAR
2663 ;-----------------------------------------------------------------------------+ ;=W
2671 ;-----------------------------------------------------------------------------+ ;=W
2673 RIGHT_DISP PROC NEAR ;=W
2683 ;-----------------------------------------------------------------------------+ ;=W
2687 ; Calculates if the specified character will fit in the input : ;=W
2688 ; buffer at the specified character position without display. : ;=W
2689 ; The byte offset where this character should be inserted is : ;=W
2690 ; returned or a flag indicating that the character will not fit. : ;=W
2692 ; Displays the specified portion of the input field buffer from : ;=W
2693 ; the left character marker to the end of the field. The following : ;=W
2694 ; display options are handled by this routine: : ;=W
2696 ; - Display of the input field in a wrapped window : ;=W
2697 ; - Adjustment of double byte characters to prevent malformed : ;=W
2701 ; The following pointers are used: : ;=W
2703 ; ÚÄ (ICB_FIELDSEG:ICB_FIELDOFF) Beginning address of input : ;=W
2704 ; ³ buffer in memory. : ;=W
2706 ; ³ ÚÄ (WR_HRCHAR) Left marker delimiting the left : ;=W
2707 ; ³ ³ most character position in the : ;=W
2708 ; ³ ³ input buffer. : ;=W
2714 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W
2715 ; ³ S ³ L ³ T ³ L ³ T ³ S ³ L ³ T ³ S ³ S ³ S ³ S ³ ³ ³ : ;=W
2716 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ : ;=W
2717 ; ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ : ;=W
2718 ; ³ ³ Area to display (ICB_WIDTH) : ;=W
2719 ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ : ;=W
2721 ; ICB_FIELDLEN Length of input field in bytes. : ;=W
2724 ; Entry: ES:SI = Points to current ICB : ;=W
2725 ; DS:DI = Points to PB : ;=W
2727 ; WR_CATTR = Logical color attribute to use when updating screen : ;=W
2728 ; if the use of the color attribute string is not : ;=W
2731 ; CR_RCOFF = Beginning offset of the upper left input field : ;=W
2732 ; display corner from the beginning of the video : ;=W
2735 ; CR_SCRWIDTH = Width of the video buffer in characters and : ;=W
2738 ; WR_HRCHAR = The offset into the input buffer, in characters, : ;=W
2739 ; of where to begin display. : ;=W
2741 ; Exit: (none) : ;=W
2742 ;-----------------------------------------------------------------------------+ ;=W
2744 LEFT_H_DISP PROC NEAR ;=W
2746 PUSH ES ;save PB pointers ;=W
2749 PUSH [DI]+CR_RCOFF ;save input field display offset ;=W
2751 ; Initialize MOVEG parm block ;=W
2753 MOV AX,ES:[SI]+ICB_FIELDOFF ;get offset of the input buffer ;=W
2754 MOV [DI]+WR_FIELDOFF,AX ;=W
2756 MOV AX,ES:[SI]+ICB_FIELDSEG ;get segment of the input buffer ;=W
2757 MOV [DI]+MG_TEXTSEG,AX ;=W
2759 MOV AX,ES:[SI]+ICB_ATTROFF ;get offset of color attribute buffer ;=W
2760 MOV [DI]+MG_ATTOFF,AX ;=W
2762 MOV AX,ES:[SI]+ICB_ATTRSEG ;get segment of color attribute ;=W
2763 MOV [DI]+MG_ATTSEG,AX ;buffer ;=W
2765 MOV AX,[DI]+IN_LVBSEG ;get segment of the LVB ;=W
2766 MOV [DI]+MG_MIXSEG,AX ;=W
2768 MOV AL,[DI]+WR_CATTR ;get logical color attribute ;=W
2769 MOV [DI]+MG_SOURCE_A,AL ;=W
2771 ; Display all characters in input buffer starting with WR_HRCHAR ;=W
2772 ; and continuing until ICB_WIDTH-1 number of characters has been displayed. ;=W
2774 MOV AX,ES:[SI]+ICB_FIELDOFF ;calcuate beginning character ;=W
2775 ADD AX,[DI]+WR_HRBYTE ;to display ;=W
2777 MOV [DI]+WR_FIELDOFF,AX ;save it ;=W
2778 MOV [DI]+MG_TEXTOFF,AX ; to display ;=W
2780 MOV [DI]+MG_OPT,MG_WA+MG_SC+MG_UA ;=W
2781 ;set write attribute option ;=W
2782 ;set use logical attribute option ;=W
2783 TEST ES:[SI]+ICB_OPT1,ICB_PSW ;check if password option active ;=W
2786 OR [DI]+MG_OPT,MG_WC ;set write character option ;=W
2788 MOV AX,ES:[SI]+ICB_WIDTH ;get field width ;=W
2789 MOV [DI]+MG_NUM,AX ;number of words to move into the ;=W
2792 MOV AX,[DI]+IN_LVBOFF ;set the actual LVB offset of ;=W
2793 ADD AX,[DI]+CR_RCOFF ; the character to write ;=W
2794 MOV [DI]+MG_MIXOFF,AX ;=W
2796 CALL PCMOVEG_CALL ;call PCMOVEG to write the char(s) ;=W
2798 ; Check if last character is DBCS ;=W
2803 MOV AX,ES:[SI]+ICB_FIELDSEG ;get input buffer segment ;=W
2804 MOV BX,ES:[SI]+ICB_FIELDOFF ;get input buffer offset ;=W
2805 ADD BX,[DI]+WR_HRBYTE ;add offset of beginning of window ;=W
2806 ADD BX,ES:[SI]+ICB_WIDTH ;add width to get last character ;=W
2807 SUB BX,2 ;subtract to get correct byte ;=W
2810 MOV AL,ES:[SI] ;get the character ;=W
2816 MOV [DI]+DBC_KS,AL ;=W
2817 CALL PCINDBC_CALL ;check if char is lead DBCS ;=W
2819 TEST [DI]+DBC_STAT,DBC_DBCS ;is it ? ;=W
2820 JE LHD30 ;no, display the character ;=W
2822 MOV AL,1DH ;display '
\1d', can't split DBCS char ;=W
2824 ; Display the last character ;=W
2827 MOV [DI]+MG_OPT,MG_WA+MG_SC+MG_UA ;=W
2828 ;set write attribute option ;=W
2829 ;set use logical attribute option ;=W
2830 TEST ES:[SI]+ICB_OPT1,ICB_PSW ;check if password option active ;=W
2833 OR [DI]+MG_OPT,MG_WC+MG_UC ;set write character option ;=W
2835 MOV [DI]+MG_SOURCE_C,AL ;character to display ;=W
2836 MOV [DI]+MG_NUM,1 ;number of words to move into the ;=W
2839 MOV AX,ES:[SI]+ICB_WIDTH ;add width to get last character ;=W
2841 MUL BX ;x2 to account for attr. bytes ;=W
2842 ADD AX,[DI]+IN_LVBOFF ;set the actual LVB offset of ;=W
2843 ADD AX,[DI]+CR_RCOFF ; the character to write ;=W
2844 SUB AX,2 ;subtract to get correct byte ;=W
2845 MOV [DI]+MG_MIXOFF,AX ;=W
2847 CALL PCMOVEG_CALL ;call PCMOVEG to write the char(s) ;=W
2849 POP [DI]+CR_RCOFF ;save input field display offset ;=W
2850 POP BX ;restore registers ;=W
2855 LEFT_H_DISP ENDP ;=W
2858 ;-----------------------------------------------------------------------------+
2862 ; Calculates if the specified character will fit in the input :
2863 ; buffer at the specified character position without display. :
2864 ; The byte offset where this character should be inserted is :
2865 ; returned or a flag indicating that the character will not fit. :
2867 ; Displays the specified portion of the input field buffer from :
2868 ; the left character marker to the end of the field. The following :
2869 ; display options are handled by this routine: :
2871 ; - Display of the input field in a wrapped window :
2872 ; - Adjustment of double byte characters to prevent malformed :
2876 ; The following pointers are used: :
2878 ; ÚÄ (ICB_FIELDSEG:ICB_FIELDOFF) Beginning address of input :
2879 ; ³ buffer in memory. :
2881 ; ³ ÚÄ (WR_LEFTCHAR) Left marker delimiting the left :
2882 ; ³ ³ most character position in the :
2883 ; ³ ³ input buffer. :
2885 ; ³ ³ Right marker delimiting the right :
2886 ; ³ ³ most character position in the :
2887 ; ³ ³ input buffer. (WR_RIGHTCHAR) :
2889 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ :
2890 ; ³ S ³ L ³ T ³ L ³ T ³ S ³ L ³ T ³ S ³ S ³ S ³ S ³ ³ ³ :
2891 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ :
2892 ; ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ :
2893 ; ³ ³ Area to display :
2894 ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ :
2896 ; ICB_FIELDLEN Length of input field in bytes. :
2899 ; Entry: ES:SI = Points to current ICB :
2900 ; DS:DI = Points to PB :
2902 ; AX 1 = This option will calculate if the specified number :
2903 ; of bytes in BX can fit into input buffer at the :
2904 ; specified character position considering the display :
2905 ; coordinates and options. No update of the display :
2906 ; screen will occur. A flag indicating if the bytes :
2907 ; can be inserted or not is returned. If the bytes :
2908 ; will fit the offset from the beginning of the input :
2909 ; field in bytes is returned indicating where the :
2910 ; characters should be inserted. :
2912 ; 2 = This option will update the display screen in the :
2913 ; proper format with the input buffer characters :
2914 ; starting at the specified left offset character :
2915 ; to the right character marker. :
2917 ; BX = Number of bytes to insert starting at the specified :
2918 ; character position. :
2920 ; WR_CATTR = Logical color attribute to use when updating screen :
2921 ; if the use of the color attribute string is not :
2924 ; CR_RCOFF = Beginning offset of the upper left input field :
2925 ; display corner from the beginning of the video :
2928 ; CR_SCRWIDTH = Width of the video buffer in characters and :
2931 ; WR_LEFTCHAR = The offset into the input buffer, in characters, :
2932 ; of where the specified bytes should fit. :
2934 ; WR_RIGHTCHAR = The offset into the input buffer, in characters, :
2935 ; of where the right most character position. :
2938 ; Exit: If AX on entry is set to 1 then on exit: :
2940 ; AX 0 = The specified number of characters will fit. :
2941 ; 1 = The specified number of characters will not fit. :
2943 ; WR_LEFTBYTE = The offset into the input buffer, in bytes, of the :
2944 ; left most character position. :
2946 ; WR_RIGHTBYTE = The offset into the input buffer, in bytes, of the :
2947 ; right most character position. :
2950 ; If AX on entry is set to 2 then the input field buffer is :
2951 ; displayed on the screen. :
2953 ;-----------------------------------------------------------------------------+
2957 PUSH ES ;save PB pointers
2960 PUSH [DI]+CR_RCOFF ;save input field display offset
2962 CALL LEFT_DISP_INIT ;initialize internal counter & vars ;=W
2964 JMP LF20 ;begin of first row
2966 ; Start a new row in LVB
2968 LF10: MOV AX,[DI]+CR_RCOFF ;set ptr into LVB to next row.
2969 ADD AX,[DI]+CR_SCRWIDTH ; Start with current position in
2970 SUB AX,ES:[SI]+ICB_WIDTH ; LVB, add screen width in text
2971 SUB AX,ES:[SI]+ICB_WIDTH ; and attributes, then subtract
2972 MOV [DI]+CR_RCOFF,AX ; the length of the input field
2973 ; twice since length is just in
2976 ; Do not start new row
2978 LF20: MOV AX,ES:[SI]+ICB_WIDTH ;counter contains number of bytes
2979 MOV [DI]+WR_CNTR2,AX ; available in current row of
2982 ; Prepare to place next byte into LVB, verify chars remaining in input buffer
2984 LF30: MOV AX,[DI]+WR_CNTR3 ;check if last character has been
2985 CMP [DI]+WR_RIGHTCHAR,AX ; written in LVB (rightmost)
2986 JGE LF40 ;if not last char jump ?
2988 JMP LF160 ;yes, last character written
2991 ; Check if end of field on display has been reached
2993 LF40: MOV AX,ES:[SI]+ICB_FIELDLEN ;loop if number chars moved is
2994 CMP [DI]+WR_CNTR1,AX ; less than input buffer length
3001 LF50: CMP [DI]+WR_CNTR2,0 ;loop while number of bytes
3002 JE LF10 ; remaining in the row is greater
3003 ; than zero, jump if bytes avail
3005 CMP [DI]+WR_MOVE,1 ;check if entry option is to
3006 JNE LF60 ; determine if bytes may be
3007 ; inserted in displayed field
3009 MOV AX,[DI]+WR_LEFTCHAR ;check if insertion calculations
3010 CMP [DI]+WR_CNTR3,AX ; should begin by comparing
3011 JNE LF60 ; current counter with beginning
3012 ; left character marker
3014 MOV AL,1 ;check if insertion calculations
3015 CMP [DI]+WR_INSDONE,AL ; are complete
3016 JE LF60 ;if yes, jump
3018 ; Adjust counters after pretending to insert a character into string and LVB
3020 MOV AX,[DI]+WR_BYTESINST ;dec number bytes avail in row
3021 ADD [DI]+WR_CNTR1,AX ;inc number bytes moved into LVB
3022 SUB [DI]+WR_CNTR2,AX ;dec number bytes remaining in row
3023 MOV [DI]+WR_INSDONE,1 ;set flag indicating insert calc
3026 ; Determine if current byte is a DBCS lead byte
3028 LF60: MOV BX,[DI]+WR_FIELDOFF ;get the current byte in the
3030 PUSH ES ;save registers
3033 PUSH ES:[SI]+ICB_FIELDSEG ; input field buffer
3034 PUSH [DI]+WR_FIELDOFF ;get the current byte in the
3038 MOV AL,ES:[SI] ;get character in input buffer
3040 POP SI ;restore registers
3045 CALL PCINDBC_CALL ;call routine to check if char
3046 ; is lead double byte char
3048 TEST [DI]+DBC_STAT,DBC_DBCS ;check if char is lead DBCS
3049 JNE LF70 ;if yes, jump to double byte code
3051 JMP LF130 ;if no, jump to single byte code
3053 ; Current byte is leading byte of a double byte character
3055 LF70: CMP [DI]+WR_CNTR2,1 ;check if there is room in current
3056 JNE LF80 ; row for double byte character
3058 JMP LF110 ;no room, adjust to next row
3060 ; Double byte character fits on current row
3062 LF80: CMP [DI]+WR_MOVE,2 ;check if option to actually
3063 JNE LF100 ; update display is active
3065 MOV AX,[DI]+WR_LEFTCHAR ;check if character should be
3066 CMP [DI]+WR_CNTR3,AX ; displayed by verifying that
3067 JL LF100 ; current character falls
3068 ; between the left and right
3069 MOV AX,[DI]+WR_RIGHTCHAR ; character markers
3070 CMP [DI]+WR_CNTR3,AX
3073 MOV AX,[DI]+WR_FIELDOFF ;get offset of character(s)
3074 MOV [DI]+MG_TEXTOFF,AX ; to display
3076 MOV [DI]+MG_OPT,MG_WA+MG_SC ;set write attribute option
3078 TEST ES:[SI]+ICB_OPT1,ICB_USC ;use attribute string
3081 OR [DI]+MG_OPT,MG_UA ;set use logical attribute option
3083 LF84: TEST ES:[SI]+ICB_OPT1,ICB_PSW ;is option for password write
3086 OR [DI]+MG_OPT,MG_WC ;set write character option
3088 LF85: MOV [DI]+MG_NUM,2 ;number of words to move into LVB
3089 MOV AX,[DI]+IN_LVBOFF ;set actual offset into LVB
3090 ADD AX,[DI]+CR_RCOFF ; where character(s) will be
3091 MOV [DI]+MG_MIXOFF,AX ; written
3093 CALL PCMOVEG_CALL ;call PCMOVEG to write characters
3095 ; Adjust pointers and counters after moving double byte character
3097 LF100: MOV AX,[DI]+WR_CNTR3 ;LEFT returns the right and left
3098 CMP AX,[DI]+WR_LEFTCHAR ; byte positions of the right and
3099 JNE LF104 ; left chars. See if the current
3101 MOV AX,[DI]+WR_CNTR4 ; char is the left char, if so
3102 MOV [DI]+WR_LEFTBYTE,AX ; store the byte offset, WR_CNTR4,
3103 JMP LF106 ; into WR_LEFTBYTE
3105 ; Update right byte marker
3107 LF104: MOV AX,[DI]+WR_CNTR3 ;LEFT returns the right and left
3108 CMP AX,[DI]+WR_RIGHTCHAR ; byte positions of the right and
3109 JNE LF106 ; left chars. See if the current
3111 MOV AX,[DI]+WR_CNTR4 ; char is the right char, if so
3112 MOV [DI]+WR_RIGHTBYTE,AX ; store the byte offset, WR_CNTR4,
3115 LF106: ADD [DI]+WR_FIELDOFF,2 ;inc number bytes moved from input
3117 ADD [DI]+CR_RCOFF,4 ;inc pointer into LVB
3118 ADD [DI]+WR_CNTR1,2 ;inc number of bytes moved into
3120 SUB [DI]+WR_CNTR2,2 ;dec number of bytes remain
3121 INC [DI]+WR_CNTR3 ;inc number of characters moved
3122 ; into LVB from input string
3123 ADD [DI]+WR_CNTR4,2 ;inc number of bytes moved from
3124 JMP LF30 ; input string
3126 ; Blank fill remaining screen character positions on current row to prevent
3127 ; double byte character from being split
3129 LF110: CMP [DI]+WR_MOVE,2 ;check if option to update display
3130 JNE LF120 ; is active
3132 MOV AX,[DI]+WR_LEFTCHAR ;check if current character
3133 CMP [DI]+WR_CNTR3,AX ; should be displayed by verifying
3134 JL LF120 ; that the character falls
3135 ; within the left and right
3136 MOV AX,[DI]+WR_RIGHTCHAR ; character markers
3137 CMP [DI]+WR_CNTR3,AX
3140 MOV AL,WR_BLANK ;get blanking character
3141 MOV [DI]+MG_SOURCE_C,AL
3143 MOV [DI]+MG_OPT,MG_WA+MG_SC+MG_UC
3144 ;set write attr, char and syn chk
3145 TEST ES:[SI]+ICB_OPT1,ICB_USC
3146 JNE LF114 ;use attribute string
3148 OR [DI]+MG_OPT,MG_UA ;set use logical attribute option
3150 LF114: TEST ES:[SI]+ICB_OPT1,ICB_PSW ;check if password option active
3153 OR [DI]+MG_OPT,MG_WC ;set write character option
3155 LF115: MOV [DI]+MG_NUM,1 ;number of words to move into the
3157 MOV AX,[DI]+IN_LVBOFF ;set the actual LVB offset of
3158 ADD AX,[DI]+CR_RCOFF ; the character to write
3159 MOV [DI]+MG_MIXOFF,AX
3161 CALL PCMOVEG_CALL ;call PCMOVEG to write the char(s)
3163 ; Adjust pointers and counters after writing blanking character to LVB
3165 LF120: ADD [DI]+CR_RCOFF,2 ;inc pointer into the LVB
3166 INC [DI]+WR_CNTR1 ;inc number of bytes moved into
3168 DEC [DI]+WR_CNTR2 ;dec number of bytes remaining in
3169 JMP LF10 ; the current row
3171 ; Byte is a single byte character
3173 LF130: CMP [DI]+WR_MOVE,2 ;check if option to update display
3174 JNE LF150 ; is active
3176 MOV AX,[DI]+WR_LEFTCHAR ;check if current character
3177 CMP [DI]+WR_CNTR3,AX ; should be displayed by verifying
3178 JL LF150 ; that the character falls
3180 MOV AX,[DI]+WR_RIGHTCHAR ; character markers
3181 CMP [DI]+WR_CNTR3,AX
3184 MOV AX,[DI]+WR_FIELDOFF ;get offset of character(s)
3185 MOV [DI]+MG_TEXTOFF,AX ; to display
3187 MOV [DI]+MG_OPT,MG_WA+MG_SC+MG_UA
3188 ;set write attribute option
3189 ;set use logical attribute option
3190 TEST ES:[SI]+ICB_OPT1,ICB_PSW ;check if password option active
3193 OR [DI]+MG_OPT,MG_WC ;set write character option
3195 LF135: MOV [DI]+MG_NUM,1 ;number of words to move into the
3198 MOV AX,[DI]+IN_LVBOFF ;set the actual LVB offset of
3199 ADD AX,[DI]+CR_RCOFF ; the character to write
3200 MOV [DI]+MG_MIXOFF,AX
3202 CALL PCMOVEG_CALL ;call PCMOVEG to write the char(s)
3204 ; Adjust pointers and counters after moving single byte character
3206 LF150: MOV AX,[DI]+WR_CNTR3 ;LEFT returns the right and left
3207 CMP AX,[DI]+WR_LEFTCHAR ; byte positions of the right and
3208 JNE LF154 ; left chars. See if the current
3210 MOV AX,[DI]+WR_CNTR4 ; char is the left char, if so
3211 MOV [DI]+WR_LEFTBYTE,AX ; store the byte offset, WR_CNTR4,
3212 JMP LF156 ; into WR_LEFTBYTE
3214 ; Update right byte marker
3216 LF154: MOV AX,[DI]+WR_CNTR3 ;LEFT returns the right and left
3217 CMP AX,[DI]+WR_RIGHTCHAR ; byte positions of the right and
3218 JNE LF156 ; left chars. See if the current
3220 MOV AX,[DI]+WR_CNTR4 ; char is the right char, if so
3221 MOV [DI]+WR_RIGHTBYTE,AX ; store the byte offset, WR_CNTR4,
3224 LF156: INC [DI]+WR_FIELDOFF ;inc pointer input buffer
3225 ADD [DI]+CR_RCOFF,2 ;inc pointer into LVB
3226 INC [DI]+WR_CNTR1 ;inc counter with number bytes
3228 DEC [DI]+WR_CNTR2 ;dec counter with number of bytes
3229 ; remaining in current row
3230 ADD [DI]+WR_CNTR3,1 ;inc counter with number of chars
3231 ; moved into the LVB from input
3233 ADD [DI]+WR_CNTR4,1 ;inc counter with number of bytes
3234 JMP LF30 ; moved into the LVB from input
3237 ; Completed updating LVB, adjust pointers
3239 LF160: CMP [DI]+WR_MOVE,1 ;Check if option to calculate
3240 JNE LFEXIT ; if chars fit in buffer
3242 ; Set up proper return values for insert calculation
3244 MOV AX,1 ;set flag indicating insert did
3246 MOV BX,[DI]+WR_CNTR3 ;see if input field fit into LVB
3247 DEC BX ; by comparing the right char
3248 CMP [DI]+WR_RIGHTCHAR,BX ; number with the number of chars
3249 JNE LFEXIT ; moved into the LVB. If they
3250 ; are equal the string fit into
3252 CMP [DI]+WR_INSDONE,1 ;see if insert has been done
3253 JE LF170 ;if yes set up return values
3255 MOV BX,ES:[SI]+ICB_FIELDLEN ;if no, then insert is at end of
3256 SUB BX,[DI]+WR_CNTR1 ; line i.e. past right char
3257 INC BX ;see if there is enough room left
3258 CMP BX,[DI]+WR_BYTESINST ; to display char being inserted
3261 LF170: MOV AX,0 ;set flag indicating insert fits
3263 ; Restores the registers to entry values and exits
3265 LFEXIT: POP [DI]+CR_RCOFF ;save input field display offset
3267 POP BX ;restore registers
3275 ;-----------------------------------------------------------------------------+ ;=W
3277 ; LEFTS_DISP (no double byte support) : ;=W
3279 ; Calculates if the specified character will fit in the input : ;=W
3280 ; buffer at the specified character position without display. : ;=W
3281 ; The byte offset where this character should be inserted is : ;=W
3282 ; returned or a flag indicating that the character will not fit. : ;=W
3284 ; Displays the specified portion of the input field buffer from : ;=W
3285 ; the left character marker to the end of the field. The following : ;=W
3286 ; display options are handled by this routine: : ;=W
3288 ; - Display of the input field in a wrapped window : ;=W
3289 ; - Adjustment of double byte characters to prevent malformed : ;=W
3293 ; The following pointers are used: : ;=W
3295 ; ÚÄ (ICB_FIELDSEG:ICB_FIELDOFF) Beginning address of input : ;=W
3296 ; ³ buffer in memory. : ;=W
3298 ; ³ ÚÄ (WR_LEFTCHAR) Left marker delimiting the left : ;=W
3299 ; ³ ³ most character position in the : ;=W
3300 ; ³ ³ input buffer. : ;=W
3302 ; ³ ³ Right marker delimiting the right : ;=W
3303 ; ³ ³ most character position in the : ;=W
3304 ; ³ ³ input buffer. (WR_RIGHTCHAR) : ;=W
3306 ; ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ : ;=W
3307 ; ³ S ³ L ³ T ³ L ³ T ³ S ³ L ³ T ³ S ³ S ³ S ³ S ³ ³ ³ : ;=W
3308 ; ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÍÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ : ;=W
3309 ; ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ : ;=W
3310 ; ³ ³ Area to display : ;=W
3311 ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ : ;=W
3313 ; ICB_FIELDLEN Length of input field in bytes. : ;=W
3316 ; Entry: ES:SI = Points to current ICB : ;=W
3317 ; DS:DI = Points to PB : ;=W
3319 ; AX 1 = This option will calculate if the specified number : ;=W
3320 ; of bytes in BX can fit into input buffer at the : ;=W
3321 ; specified character position considering the display : ;=W
3322 ; coordinates and options. No update of the display : ;=W
3323 ; screen will occur. A flag indicating if the bytes : ;=W
3324 ; can be inserted or not is returned. If the bytes : ;=W
3325 ; will fit the offset from the beginning of the input : ;=W
3326 ; field in bytes is returned indicating where the : ;=W
3327 ; characters should be inserted. : ;=W
3329 ; 2 = This option will update the display screen in the : ;=W
3330 ; proper format with the input buffer characters : ;=W
3331 ; starting at the specified left offset character : ;=W
3332 ; to the right character marker. : ;=W
3334 ; BX = Number of bytes to insert starting at the specified : ;=W
3335 ; character position. : ;=W
3337 ; WR_CATTR = Logical color attribute to use when updating screen : ;=W
3338 ; if the use of the color attribute string is not : ;=W
3341 ; CR_RCOFF = Beginning offset of the upper left input field : ;=W
3342 ; display corner from the beginning of the video : ;=W
3345 ; CR_SCRWIDTH = Width of the video buffer in characters and : ;=W
3348 ; WR_LEFTCHAR = The offset into the input buffer, in characters, : ;=W
3349 ; of where the specified bytes should fit. : ;=W
3351 ; WR_RIGHTCHAR = The offset into the input buffer, in characters, : ;=W
3352 ; of where the right most character position. : ;=W
3355 ; Exit: If AX on entry is set to 1 then on exit: : ;=W
3357 ; AX 0 = The specified number of characters will fit. : ;=W
3358 ; 1 = The specified number of characters will not fit. : ;=W
3360 ; WR_LEFTBYTE = The offset into the input buffer, in bytes, of the : ;=W
3361 ; left most character position. : ;=W
3363 ; WR_RIGHTBYTE = The offset into the input buffer, in bytes, of the : ;=W
3364 ; right most character position. : ;=W
3367 ; If AX on entry is set to 2 then the input field buffer is : ;=W
3368 ; displayed on the screen. : ;=W
3370 ;-----------------------------------------------------------------------------+ ;=W
3372 LEFTS_DISP PROC NEAR ;=W
3374 PUSH ES ;save PB pointers ;=W
3377 PUSH [DI]+CR_RCOFF ;save input field display offset ;=W
3379 CALL LEFT_DISP_INIT ;initialize internal counters & vars ;=W
3381 JMP LS20 ;begin of first row ;=W
3383 ; Start a new row in LVB ;=W
3385 LS10: MOV AX,[DI]+CR_RCOFF ;set ptr into LVB to next row. ;=W
3386 ADD AX,[DI]+CR_SCRWIDTH ; Start with current position in ;=W
3387 SUB AX,ES:[SI]+ICB_WIDTH ; LVB, add screen width in text ;=W
3388 SUB AX,ES:[SI]+ICB_WIDTH ; and attributes, then subtract ;=W
3389 MOV [DI]+CR_RCOFF,AX ; the length of the input field ;=W
3390 ; twice since length is just in ;=W
3393 ; Do not start new row ;=W
3395 LS20: MOV AX,ES:[SI]+ICB_WIDTH ;counter contains number of bytes ;=W
3396 MOV [DI]+WR_CNTR2,AX ; available in current row of ;=W
3399 ; Prepare to place next byte into LVB, verify chars remaining in input buffer ;=W
3401 LS30: MOV AX,[DI]+WR_CNTR3 ;check if last character has been ;=W
3402 CMP [DI]+WR_RIGHTCHAR,AX ; written in LVB (rightmost) ;=W
3403 JGE LS40 ;if not last char jump ? ;=W
3405 JMP LS160 ;yes, last character written ;=W
3406 ; prepare to exit ;=W
3408 ; Check if end of field on display has been reached ;=W
3410 LS40: MOV AX,ES:[SI]+ICB_FIELDLEN ;loop if number chars moved is ;=W
3411 CMP [DI]+WR_CNTR1,AX ; less than input buffer length ;=W
3418 LS50: CMP [DI]+WR_CNTR2,0 ;loop while number of bytes ;=W
3419 JE LS10 ; remaining in the row is greater ;=W
3420 ; than zero, jump if bytes avail ;=W
3422 CMP [DI]+WR_MOVE,1 ;check if entry option is to ;=W
3423 JNE LS130 ; determine if bytes may be ;=W
3424 ; inserted in displayed field ;=W
3426 MOV AX,[DI]+WR_LEFTCHAR ;check if insertion calculations ;=W
3427 CMP [DI]+WR_CNTR3,AX ; should begin by comparing ;=W
3428 JNE LS130 ; current counter with beginning ;=W
3429 ; left character marker ;=W
3431 MOV AL,1 ;check if insertion calculations ;=W
3432 CMP [DI]+WR_INSDONE,AL ; are complete ;=W
3433 JE LS130 ;if yes, jump ;=W
3435 ; Adjust counters after pretending to insert a character into string and LVB ;=W
3437 MOV AX,[DI]+WR_BYTESINST ;dec number bytes avail in row ;=W
3438 ADD [DI]+WR_CNTR1,AX ;inc number bytes moved into LVB ;=W
3439 SUB [DI]+WR_CNTR2,AX ;dec number bytes remaining in row ;=W
3440 MOV [DI]+WR_INSDONE,1 ;set flag indicating insert calc ;=W
3441 JMP LS30 ; complete ;=W
3443 ; Byte is a single byte character ;=W
3445 LS130: CMP [DI]+WR_MOVE,2 ;check if option to update display ;=W
3446 JNE LS150 ; is active ;=W
3448 MOV AX,[DI]+WR_LEFTCHAR ;check if current character ;=W
3449 CMP [DI]+WR_CNTR3,AX ; should be displayed by verifying ;=W
3450 JL LS150 ; that the character falls ;=W
3451 ; within the left and right ;=W
3452 MOV AX,[DI]+WR_RIGHTCHAR ; character markers ;=W
3453 CMP [DI]+WR_CNTR3,AX ;=W
3456 MOV AX,[DI]+WR_FIELDOFF ;get offset of character(s) ;=W
3457 MOV [DI]+MG_TEXTOFF,AX ; to display ;=W
3459 MOV [DI]+MG_OPT,MG_WA+MG_SC+MG_UA ;=W
3460 ;set write attribute option ;=W
3461 ;set use logical attribute option ;=W
3462 TEST ES:[SI]+ICB_OPT1,ICB_PSW ;check if password option active ;=W
3465 OR [DI]+MG_OPT,MG_WC ;set write character option ;=W
3467 LS135: MOV [DI]+MG_NUM,1 ;number of words to move into the ;=W
3470 MOV AX,[DI]+IN_LVBOFF ;set the actual LVB offset of ;=W
3471 ADD AX,[DI]+CR_RCOFF ; the character to write ;=W
3472 MOV [DI]+MG_MIXOFF,AX ;=W
3474 CALL PCMOVEG_CALL ;call PCMOVEG to write the char(s) ;=W
3476 ; Adjust pointers and counters after moving single byte character ;=W
3478 LS150: MOV AX,[DI]+WR_CNTR3 ;LEFT returns the right and left ;=W
3479 CMP AX,[DI]+WR_LEFTCHAR ; byte positions of the right and ;=W
3480 JNE LS154 ; left chars. See if the current ;=W
3482 MOV AX,[DI]+WR_CNTR4 ; char is the left char, if so ;=W
3483 MOV [DI]+WR_LEFTBYTE,AX ; store the byte offset, WR_CNTR4, ;=W
3484 JMP LS156 ; into WR_LEFTBYTE ;=W
3486 ; Update right byte marker ;=W
3488 LS154: MOV AX,[DI]+WR_CNTR3 ;LEFT returns the right and left ;=W
3489 CMP AX,[DI]+WR_RIGHTCHAR ; byte positions of the right and ;=W
3490 JNE LS156 ; left chars. See if the current ;=W
3492 MOV AX,[DI]+WR_CNTR4 ; char is the right char, if so ;=W
3493 MOV [DI]+WR_RIGHTBYTE,AX ; store the byte offset, WR_CNTR4, ;=W
3494 ; into WR_RIGHTBYTE ;=W
3495 LS156: INC [DI]+WR_FIELDOFF ;inc pointer input buffer ;=W
3496 ADD [DI]+CR_RCOFF,2 ;inc pointer into LVB ;=W
3497 INC [DI]+WR_CNTR1 ;inc counter with number bytes ;=W
3498 ; moved into LVB ;=W
3499 DEC [DI]+WR_CNTR2 ;dec counter with number of bytes ;=W
3500 ; remaining in current row ;=W
3501 ADD [DI]+WR_CNTR3,1 ;inc counter with number of chars ;=W
3502 ; moved into the LVB from input ;=W
3504 ADD [DI]+WR_CNTR4,1 ;inc counter with number of bytes ;=W
3505 JMP LS30 ; moved into the LVB from input ;=W
3508 ; Completed updating LVB, adjust pointers ;=W
3510 LS160: CMP [DI]+WR_MOVE,1 ;Check if option to calculate ;=W
3511 JNE LSEXIT ; if chars fit in buffer ;=W
3513 ; Set up proper return values for insert calculation ;=W
3515 MOV AX,1 ;set flag indicating insert did ;=W
3517 MOV BX,[DI]+WR_CNTR3 ;see if input field fit into LVB ;=W
3518 DEC BX ; by comparing the right char ;=W
3519 CMP [DI]+WR_RIGHTCHAR,BX ; number with the number of chars ;=W
3520 JNE LSEXIT ; moved into the LVB. If they ;=W
3521 ; are equal the string fit into ;=W
3523 CMP [DI]+WR_INSDONE,1 ;see if insert has been done ;=W
3524 JE LS170 ;if yes set up return values ;=W
3526 MOV BX,ES:[SI]+ICB_FIELDLEN ;if no, then insert is at end of ;=W
3527 SUB BX,[DI]+WR_CNTR1 ; line i.e. past right char ;=W
3528 INC BX ;see if there is enough room left ;=W
3529 CMP BX,[DI]+WR_BYTESINST ; to display char being inserted ;=W
3532 LS170: MOV AX,0 ;set flag indicating insert fits ;=W
3534 ; Restores the registers to entry values and exits ;=W
3536 LSEXIT: POP [DI]+CR_RCOFF ;save input field display offset ;=W
3538 POP BX ;restore registers ;=W
3546 ;-----------------------------------------------------------------------------+ ;=W
3549 ; Draw a input field delimiter : ;=W
3552 ; ES:SI address of icon : ;=W
3553 ; GC_ROW - character row to display delimiter : ;=W
3554 ; GC_COL - character column to display delimiter : ;=W
3558 ;-----------------------------------------------------------------------------+ ;=W
3559 DRAW_DEM PROC NEAR ;=W
3573 MOV DX,300H + graph_addr ;=W
3574 MOV AH,2 ; Write Mode 2 ;=W
3575 MOV AL,5 ; Write Mode Register ;=W
3579 MOV AH,0FFH ;enable all maps ;=W
3580 MOV AL,s_map ;map mask ;=W
3581 OUT DX,AX ;set the registers ;=W
3583 MOV AX,[DI]+WR_ROWBYTES ;=W
3587 MOV BX,[DI]+GC_ROW ;=W
3589 ADD AX,[DI]+GC_COL ;=W
3591 MOV BH,[DI]+WR_CATTR ;get current color attribute ;=W
3593 CMP [DI]+WR_VIDMODE,11H ;check for graphics mode 11H
3594 JNE DD05 ;nop, continue
3595 MOV BH,0FH ;yes, mode 11 is only black &
3597 DD05: MOV CL,4 ;count for shift ;=W
3598 SHR BX,CL ;separate background/foreground ;=W
3599 MOV CL,4 ;count for shift ;=W
3600 SHR BL,CL ;put in low order nibble ;=W
3601 XCHG BL,BH ;foreground/background are reversed ;=W
3603 ; BL = background color, BH = foreground color
3604 CMP BP,02 ;check if we want to remove delimiters ;=W
3605 JNE DD10 ;no, ok ;=W
3606 MOV BH,BL ;make both background color ;=W
3609 MOV CL,[DI]+WR_VIDMODE ;=W
3612 PUSH ES ;make DS:SI point to bit maps ;=W
3619 TEST DX,IN_MCGA ;mode 11H, non-VGA hardware?
3620 JNE DD100 ;if so, go do it
3621 ;--------------------------------------------- ;=W
3622 ; Mode 10,11,12 with VGA : ;=W
3623 ;--------------------------------------------- ;=W
3624 MOV DX,300H + graph_addr ;graphics chip ;=W
3627 MOV AL,CL ;save vid mode
3628 MOV CL,0EH ;# pixel rows in delimiter ;=W
3629 CMP AL,10H ;are we in graphics mode 10H
3630 JE DD40 ;yes, # rows ok
3631 ADD CL,2 ;no, mode 11,12 have 16 pixel rows
3632 DD40: ; instead of 14 pixel rows.
3633 MOV BP,02H ;# pixel columns/8 in delimiter ;=W
3636 MOV AL,g_bit_mask ;bit mask index ;=W
3637 OUT DX,AX ;set bit mask ;=W
3643 MOV AH,0FFH ;background ;=W
3644 MOV AL,g_bit_mask ;bit mask index ;=W
3645 OUT DX,AX ;set bit mask ;=W
3647 MOV AL,ES:[DI] ;latch data ;=W
3648 MOV ES:[DI],BH ;set the dot ;=W
3650 LODSB ;foreground ;=W
3653 MOV AL,g_bit_mask ;bit mask index ;=W
3654 OUT DX,AX ;set bit mask ;=W
3656 MOV AL,ES:[DI] ;latch data ;=W
3657 MOV ES:[DI],BL ;set the dot ;=W
3667 ;--------------------------------------------- ;=W
3668 ; Mode 11H with no VGA : ;=W
3669 ;--------------------------------------------- ;=W
3671 MOV CL,10H ;# pixel rows in delimiter
3672 MOV BP,02H ;# of pixel columns in delimiter
3679 DD120: LODSB ;get icon row
3682 MOV ES:[DI],AL ;set the dot
3688 ADD DI,50H ;line length, 80
3708 ;-----------------------------------------------------------------------------+ ;=W
3710 ; GET_MONO_DOS : ;=W
3711 ; Get segment and offset of the DOS monocasing table and return it : ;=W
3717 ;-----------------------------------------------------------------------------+ ;=W
3718 GET_MONO_DOS PROC NEAR ;=W
3720 PUSH SI ;save registers ;=W
3724 MOV AH,65H ;extended country info ;=W
3725 MOV AL,02H ;get uppercase table ptrs ;=W
3726 MOV BX,-1 ;default code page ;=W
3727 MOV DX,-1 ;default country id ;=W
3728 MOV CX,05H ;# bytes returned ;=W
3730 POP ES ;ES:DI ptrs to return buffer ;=W
3731 MOV DI,OFFSET WR_CUCHAR ;use as temp buffer ;=W
3735 INC DI ;skip info id ;=W
3736 MOV SI,DI ;we need DI so use SI ;=W
3739 MOV AX,WORD PTR [SI] ;get DOS monocasing table offset ;=W
3740 MOV [DI]+IN_MONOOFF,AX ;save it ;=W
3742 MOV AX,WORD PTR [SI] ;get DOS monocasing table segment ;=W
3743 MOV [DI]+IN_MONOSEG,AX ;save it ;=W
3745 POP ES ;restore registers ;=W
3752 ;-----------------------------------------------------------------------------+ ;=W
3755 ; Get segment and offset of the DOS double byte support table. : ;=W
3757 ; Entry: DS:DI : ;=W
3761 ;-----------------------------------------------------------------------------+ ;=W
3762 GET_DBCS PROC NEAR ;=W
3769 MOV AH,65H ;get extended country info
3770 MOV AL,07H ;get DBCS environment table
3771 INT 21H ;DOS function call,vector returned
3773 POP SI ;ptr, SI -> IN_PB
3774 INC DI ;skip over id byte returned
3775 MOV AX,WORD PTR ES:[DI] ;get offset of DBCS table
3776 MOV [DI]+IN_DBCSOFF,AX ;save it
3778 ADD DI,2 ;skip over offset to get segment
3779 MOV BX,WORD PTR ES:[DI] ;get segment of DBCS table
3780 MOV [DI]+IN_DBCSSEG,BX ;save it
3784 MOV SI,AX ;Point to DBCS table to get length
3786 MOV AX,WORD PTR ES:[SI]
3787 MOV [DI]+IN_DBCSLEN,AX
3788 ADD [DI]+IN_DBCSOFF,2 ;change offset to point to table