· 6 years ago · Mar 09, 2019, 09:32 PM
1; XPC-Mouse: POSITION CURSOR, COPY and PASTE in Dos Text Mode
2;
3; Copyright (c) 1994-1998 by Jürgen G. Weber and Grant B. Gustafson.
4; ALL RIGHTS RESERVED
5; Free for personal use under the Gnu Public License agreement. See the
6; end of this file for a copy of the License Agreement and documentation.
7;
8PVERSION equ '1.4: 5 Sept 1998'
9TRUE equ -1
10FALSE equ not TRUE
11;
12; Compile Time switches that change the final EXE size. Help text
13; is not resident, nor is any code after "pastebuf equ $" (see below).
14;
15; Paste only: Set ENABLEPASTE, ENABLEFILEAPPEND TRUE. Comment ENABLECURSOR
16; Resident size 4.1k (2.1k plus 2k buffer). xpcpaste.exe
17; Cursor only: Set ENABLECURSOR TRUE. Comment ENABLEPASTE, ENABLEFILEAPPEND
18; Resident size 1.6k (all code, no buffer). xpcarrow.exe
19; Paste+Cursor: Set ENABLECURSOR, ENABLEPASTE, ENABLEFILEAPPEND TRUE
20; Resident size 4.9k (2.9k plus 2k buffer). xpcmouse.exe
21;
22NOWARN PDC
23ENABLECURSOR equ TRUE ;TRUE to compile with cursor key code
24ENABLEPASTE equ TRUE ;TRUE to compile with paste key code
25ENABLEFILEAPPEND equ TRUE ;TRUE for file append, windows clipboard
26
27IFNDEF ENABLEPASTE
28 ENABLEPASTE equ FALSE
29 %OUT ENABLEPASTE == FALSE. (Paste functions)
30ENDIF
31IFNDEF ENABLEFILEAPPEND
32 ENABLEFILEAPPEND equ FALSE
33 %OUT ENABLEFILEAPPEND == FALSE. (File append, Win clipboard)
34ENDIF
35IFNDEF ENABLECURSOR
36 ENABLECURSOR equ FALSE
37 %OUT ENABLECURSOR == FALSE. (Cursor functions)
38ENDIF
39
40; Append file: Requires ENABLEFILEAPPEND TRUE and ENABLEPASTE TRUE
41; Append pastebuf to file on receipt of CTRL-LSHIFT-MOUSE2.
42IF ENABLEFILEAPPEND and (not ENABLEPASTE)
43 %OUT Bad definitions for ENABLEFILEAPPEND and ENABLEPASTE.
44 .ERR
45ENDIF
46
47;XT equ TRUE ; TRUE for PC or XT 8086/8088 cpu
48XT equ FALSE ; FALSE for 80188+ cpu and 286 opcodes.
49IF XT
50 %OUT XT == TRUE. (Assuming PC-XT 8086/8088 cpu)
51ELSE
52 %OUT XT == FALSE. (Assuming 80286+ cpu)
53ENDIF
54
55if ENABLEPASTE
56BUFFERLEN EQU 4096 ; Max buffer size for copying text and attributes.
57 ; Enough for a full screen. Blanks are compressed.
58 ; 1024 is enough for 1/2 of screen. Use /Bddd
59 ; option to set runtime buffer size (can be zero).
60 ; Code actually uses "BUFLEN" variable.
61
62BUFLENDEFAULT EQU 2048 ; Default buffer size if /B not used on command line.
63 ; Must be less than or equal to BUFFERLEN
64if BUFFERLEN lt BUFLENDEFAULT
65 %OUT Inequality BUFLENDEFAULT <= BUFFERLEN violated.
66 .ERR
67endif
68else
69if ENABLECURSOR
70BUFFERLEN EQU 0 ; Max buffer size for copying text and attributes.
71BUFLENDEFAULT EQU 0 ; Default buffer size if /B not used on command line.
72endif ;ENABLECURSOR
73endif ;ENABLEPASTE
74;
75; Masks for mouse events
76;
77M_MOVED EQU 1B ;bit 0 mouse movement
78M_LT_PRESSED EQU 10B ;bit 1 left button pressed (button1)
79M_LT_RELEASED EQU 100B ;bit 2 left button released
80M_RT_PRESSED EQU 1000B ;bit 3 right button pressed (button2)
81M_RT_RELEASED EQU 10000B ;bit 4 right button released
82M_MI_PRESSED EQU 100000B ;bit 5 middle button pressed (Mouse Systems)
83M_MI_RELEASED EQU 1000000B ;bit 6 middle button released (Mouse Systems)
84XPCMOUSEMASK EQU (M_MOVED or M_LT_PRESSED or M_LT_RELEASED or M_RT_PRESSED or M_RT_RELEASED or M_MI_PRESSED or M_MI_RELEASED)
85
86if not XT
87 .286 ; the times, they're a-changing ... memento mori 808[6|8]
88endif
89
90locals ; makes the local @@Label possible
91
92; Useful macros
93;
94PUSHR macro regs ;; eg: PUSHR <bx,ax,cx>
95local reg
96 irp reg,<regs>
97 push reg
98 endm
99endm
100
101POPR macro regs ;; eg: POPR <cx,ax,bx>
102local reg
103 irp reg,<regs>
104 pop reg
105 endm
106endm
107
108 XPUSHA macro
109if XT
110 PUSHR <AX,BX,CX,DX,BP,SI,DI>
111else
112 pusha
113endif
114 endm
115
116 XPOPA macro
117if XT
118 POPR <DI,SI,BP,DX,CX,BX,AX>
119else
120 popa
121endif
122 endm
123
124code segment
125assume cs:code
126
127begin_resident equ $ ; All resident code starts here
128
129XPC_pspadr dw 0 ; psp address of installed XPC-mouse
130BUFLEN dw BUFLENDEFAULT ; Buffer size in bytes, /B command line switch
131biosSEG dw 40h ; Bios variables segment address
132flag_reinstall_exec db FALSE ; TRUE to reinstall mouse handler before exec
133flag_reinstall_exit db TRUE ; TRUE to reinstall mouse handler after exit
134flag_busy_stuffing db 0 ; TRUE if stuffing keys (see new int 08h)
135FlagREINSTALL equ 00010000B ; Re-install the mouse handler
136FlagFILEAPPEND equ 00100000B ; Write paste buffer to TMP file
137FlagWINCLIP equ 01000000B ; Write paste buffer to Win 3.1/95 clipboard
138FlagPASTE equ 00000001B ; Pasting the buffer currently active
139FlagCURSOR equ 00000010B ; Stuffing cursor keys is active
140flag_event db 00000000B ; Data byte for above bit flags
141counter_int10 dw 0 ; Incremented at each call of int 10h
142flag_Left db FALSE ; TRUE if left button was pressed.
143flag_Right db FALSE ; TRUE when right button pressed.
144flag_MouseOn db FALSE ; TRUE if mouse cursor is on.
145flag_swapbuttons db FALSE ; TRUE if buttons are swapped by user
146button_1fix db 1 ; Shift amt button 1 in NewButtonOrder
147button_2fix db 3 ; Shift amt button 2 in NewButtonOrder
148button_3fix db 5 ; Shift amt button 3 in NewButtonOrder
149lineSize dw 0 ; Characters per line on screen
150lasttime dw 0,0 ; System time at last left click
151PositionLeft dw 0 ; Position of mouse at left click
152NextPositionLeft dw 0 ; Position of mouse at a later left click
153EndOfBuffer dw pastebuf+BUFFERLEN-1 ; Address of end of paste buffer
154
155if ENABLEPASTE
156lastChar db 0 ; Saved character from failed key-stuff.
157flag_Highlight db FALSE ; TRUE if an area is highlighted on screen.
158flag_CtrlRight db FALSE ; TRUE if last click was ctrl-right
159xor_mask db 01010000b ; XOR mask for selected screen area
160videosegment dw 0 ; Segment of screen memory
161videoOffset dw 0 ; Offset into video page
162;counter_blanks db 0 ; Counter for blanks yet to be stuffed.
163nextpair dw offset pastebuf ; Pointer to next character pair in paste buffer.
164lastpair dw offset pastebuf ; Pointer to end of text in paste buffer.
165
166flag_pastebuffer db TRUE ; Pastebuffer initially ON
167flag_double db FALSE ; TRUE if left button was double-clicked
168
169; Xterm-style char classes for double-click
170; Inequality a<=x<=b coded as "db a,b" below.
171;
172unix_pairs db 9 ; Number of active pairs below
173unix_ranges db 35,35 ; # (pound)
174 db 45,58 ; -./0123456789:
175 db 64,90 ; @ABCDEFGHIJKLMNOPQRSTUVWXYZ
176 db 92,92 ; \ (backslash)
177 db 95,95 ; _ (underline)
178 db 97,122 ; abcdefghijklmnopqrstuvwxyz
179 db 126,126 ; ~ (tilde)
180 db 128,165 ; European letters
181 db 224,238 ; Greek letters and infinity
182 db 0,0 ; extra space for more combos
183 db 0,0 ; This table can be changed dynamically
184 db 0,0 ; on program load or restart (not implemented).
185; db 0,0 ; If you change this, also change
186; db 0,0 ; variable "unix_pairs" above!
187MAX_unix_pairs equ ($-unix_pairs)/2
188SPEED_LDC equ 9 ; Double click threshold 9/18.2 seconds
189
190marginleft dw 0 ; Min col used in highlight
191marginright dw 0 ; Max col used in highlight
192dolimits db TRUE ;TRUE to do limits, else FALSE
193
194if ENABLEFILEAPPEND
195stringf db 0,0 ;data area for file write
196filen db 'c:\tmp\'
197 db 'xpcm####.tmp',0 ;fixed file name for the write
198endif ;ENABLEFILEAPPEND
199endif ;ENABLEPASTE
200
201if ENABLECURSOR ;=========Cursor Key code ==========;
202flag_arrowkeys db TRUE ; Arrowkeys initially ON
203flag_editor db 1 ; 1=emacs/vi/jove/jed, 2=matrix, 3=Xterm,
204current_X dw 0 ; Current mouse X coordinate (transient)
205current_Y dw 0 ; Current mouse Y coordinate (transient)
206FlagButton13 equ 00001000B ; Flag for button1+button3 combo
207FlagButton3 equ 00000100B ; Flag for button3
208FlagButton2 equ 00000010B ; Flag for button2
209FlagButton1 equ 00000001B ; Flag for button1
210FlagButtonCR equ 00010000B ; Flag for CR addon but not /A3
211FlagButtonsOFF equ 00010000B ; Turn off everything but CR flag
212flag_doButtons db 00000000B ; Set button flags
213MAX_of_A equ 3 ; max number of /A options (1,2,3)
214SPEED_LC equ 3 ; About 3/18.2 sec left button press required.
215col_present db 0 ; col for text cursor (not mouse cursor!)
216row_present db 0 ; row for text cursor
217col_target db 0 ; col where left button was pressed
218row_target db 0 ; row where left button was pressed
219;
220; Xterm escapes for buttons 1,2,3 are in format ASCII,SCANCODE
221; because they are to be stuffed directly into the keybuffer.
222;
223; Escape sequence for button 1
224Button1_ESC db 1bh, 01h ; ESC
225 db '[',1ah ; [
226 db 'M',32h ; M
227 db 20h,39h ; SPACE
228Button1_COL db 00h,00h ; Column position
229 db 00h,00h ; Row position
230Button1_LEN equ 6 ; Number of pairs in sequence
231; Escape sequence for button 2
232Button2_ESC db 1bh, 01h ; ESC
233 db '[',1ah ; [
234 db 'M',32h ; M
235 db 21h,02h ; SPACE+1
236Button2_COL db 00h,00h ; Column position
237 db 00h,00h ; Row position
238Button2_LEN equ 6 ; Number of pairs in sequence
239; Escape sequence for button 3
240Button3_ESC db 1bh, 01h ; ESC
241 db '[',1ah ; [
242 db 'M',32h ; M
243 db 22h,28h ; SPACE+2
244Button3_COL db 00h,00h ; Column position
245 db 00h,00h ; Row position
246Button3_LEN equ 6 ; Number of pairs in sequence
247CR_ESC db 0dh,1ch ; Carriage return
248CR_LEN equ 1 ; Number of pairs in sequence
249;
250Xterm_PAD equ ' '+1 ; Offset for Xterm escapes row,col
251;
252endif ;end ENABLECURSOR ;=========Cursor Key code ==========;
253
254;
255; The MOUSE HANDLER is called by the mouse driver
256; if an event occurs which matches the CX mask
257; that was supplied at the time of installation.
258; ENTRY: The mouse device driver supplies this info:
259; AX=Mouse event bits
260; BX=button state: bit0=left, bit1=right, bit2=center
261; CX=current X pixel coordinate, DX=current Y pixel coordinate
262; SI=raw Y mickeys, DI=raw X mickeys
263; DS=driver's data segment
264;
265MouseHandler proc far ; Handler ends with far ret
266 XPUSHA ; handler can't modify registers
267 push ds ; can't call DOS or BIOS
268;
269; Do not let mouse routines happen if interrupt 10h is active
270; or is there is no text mode active (eg, graphics modes ==> no mouse)
271;
272 cmp counter_int10,0 ; Int 10h interrupted?
273 jne short @@exit1 ; Yes, then get out of here.
274
275@@not_in10:
276
277if ENABLECURSOR ;=========Cursor Key code ==========;
278 mov current_X,cx ; Save button X and Y coordinates
279 mov current_Y,dx ; from this call.
280endif ;end ENABLECURSOR ;=========Cursor Key code ==========;
281
282 cmp flag_swapbuttons,TRUE ; Swapping button order?
283 jnz @@swap_done
284 call NewButtonOrder ; October 1995, swap buttons
285@@swap_done:
286 push ax
287 mov ds,biosSEG ; Use DS to read bios variables.
288 mov al,byte ptr [ds:49h] ; BIOS current video mode
289 cmp al,3
290 jna short @@test_events
291 cmp al,7 ; BIOS current video mode
292 jz short @@test_events
293 cmp al,13h ; Other video modes are graphics
294 jna short @@exit0
295 cmp word ptr [ds:4ch],0800h ; Assume text mode if video memory
296 jbe short @@test_events ; size is 4096k bytes or less.
297@@exit0:
298 pop ax
299 jmp short @@exit1
300@@test_events:
301 pop ax
302;
303; TEST button event flags passed to handler in register AX
304; In: AX=mouse event bits from device driver
305;
306@@tst_moved:
307 test ax,M_MOVED ; mouse was moved
308 jz short @@tst_released
309 jmp @@mouse_moved
310@@tst_released:
311 test ax,M_LT_RELEASED ; a button was released
312 jnz short @@left_released
313@@tst_right:
314 test ax,M_RT_PRESSED ; button2 (right on 2-button mouse)
315 jnz short @@test_button2_shifts
316@@tst_left:
317 test ax,M_LT_PRESSED ; button1 (left button)
318 jz short @@tst_button3
319 jmp @@test_button1_shifts
320@@tst_button3:
321
322if ENABLECURSOR ;=========Cursor Key code ==========;
323 test ax,M_MI_PRESSED ; button3 (middle on mouse systems)
324 jz short @@tst_exit
325 jmp @@exit_button3
326@@tst_exit:
327endif ;end ENABLECURSOR ;=========Cursor Key code ==========;
328
329@@exit1:
330 jmp @@exit
331;
332; END of TEST button events using ax. Below we can use ax.
333;
334
335; ======================================================================
336; Target of initial look at release of button 1
337; ======================================================================
338@@left_released:
339 cmp flag_Left,FALSE ; If left not pressed, then hide mouse.
340 je short @@skip_cursor
341if ENABLEPASTE
342 cmp flag_double,TRUE
343 je @@copy_region1
344 mov ax,NextPositionLeft
345 cmp ax,PositionLeft
346 jz short @@no_selection ; nothing at all marked
347@@copy_region1:
348 mov flag_double,FALSE ; Otherwise, copy screen text to
349 mov flag_Highlight,TRUE ; the pastebuffer.
350 mov flag_Left,FALSE
351 call Fill_pastebuffer ; Returns carry if chars to paste
352 jnc short @@skip_cursor ; Got chars, then hide mouse.
353@@copy_region2:
354if ENABLECURSOR ;=========Cursor Key code ==========;
355 or flag_doButtons,FlagButton13 ; Send button1+button3 info
356endif ;end ENABLECURSOR ;=========Cursor Key code ==========;
357 jmp short @@skip_cursor
358endif ;ENABLEPASTE
359
360@@no_selection:
361
362if ENABLECURSOR ;=========Cursor Key code ==========;
363; Mouse was released at same location. Test if enough time has
364; elapsed to call it a cursor positioning click. If so, then
365; set the cursor.
366 call ClickTimeCursor ; Calls set_cursor
367endif ;end ENABLECURSOR ;=========Cursor Key code ==========;
368
369@@skip_cursor:
370 mov flag_Left,FALSE
371 call HIDE_MOUSE ; Two cursors are confusing, turn it off
372@@exit2:
373 jmp short @@exit1
374
375; ======================================================================
376; Target of initial look at press of button 2
377; ======================================================================
378@@test_button2_shifts:
379 mov al,byte ptr ds:[17h]
380 and al,00001111B
381 jnz short @@rt_shifts
382 cmp flag_Left,TRUE
383 jz short @@exit2 ; both buttons simultaneously pressed
384if ENABLECURSOR
385 or flag_doButtons,FlagButton2 ; Send button2 info later on
386endif ;ENABLECURSOR
387@@test_paste:
388if ENABLEPASTE
389; Mouse-2 ................ Paste Text
390; CTRL-Mouse 2 ........... Paste text + ENTER
391 test flag_event,FlagPASTE ; Paste in progress?
392 jnz short @@test_paste_exit ; Yes, then quit
393 mov flag_Right,TRUE ;Mark Mouse2 pressed
394 mov nextpair,offset pastebuf
395 or flag_event,FlagPASTE ; Signal to process paste
396@@test_paste_exit:
397endif ;ENABLEPASTE
398 jmp short @@exit2
399@@rt_shifts: ; Get here by shift/alt/ctrl keys
400if ENABLEPASTE
401 cmp al,00000100B ;Bit 2 is CTRL
402 jne short @@test_ctrl_exit
403 mov flag_CtrlRight,TRUE ; Means: Add CR to end of paste output
404 jmp short @@test_paste
405@@test_ctrl_exit:
406; RSHIFT-Mouse 2 ......... Paste feature on/off
407; LSHIFT-CTRL-Mouse 2 .... Append text to TMP file
408 cmp al,00000001B ;Right Shift?
409 jne short @@endtest_Rshift
410 not flag_pastebuffer ; Flip bits
411 jmp short @@exit2
412@@endtest_Rshift:
413if ENABLEFILEAPPEND
414 cmp al,00000110B ;Ctrl Left Shift?
415 jne short @@endtest_LshiftCtrl
416 or flag_event,FlagFILEAPPEND
417@@endtest_LshiftCtrl:
418 cmp al,00001010B ; Alt Left Shift?
419 jne short @@endtest_LshiftAlt
420 or flag_event,FlagWINCLIP ; Request write to clipboard
421@@endtest_LshiftAlt:
422endif ;ENABLEFILEAPPEND
423endif ;ENABLEPASTE
424
425if ENABLECURSOR ;=========Cursor Key code ==========;
426; Mouse 3 ................ Carriage return (except /A3)
427; ALT-Mouse 2 ............ Mouse 3 duplicate
428;
429; If ALT-button2, then simulate button 3 on 3-button mouse
430 cmp al,00001000B ; Is ALT depressed?
431 jne short @@exit3
432@@exit_button3:
433 or flag_doButtons,FlagButton3+FlagButtonCR ; Send button3 info
434endif ;end ENABLECURSOR ;=========Cursor Key code ==========;
435 jmp short @@exit3
436
437; ======================================================================
438; Target of initial look at mouse movement
439; ======================================================================
440@@mouse_moved:
441 call SHOW_MOUSE ; switch on cursor after first movement
442if ENABLEPASTE
443 test ax,M_LT_RELEASED ; a button was released
444 jz short @@noleftrelease
445 jmp @@left_released
446@@noleftrelease:
447 cmp flag_Left,FALSE
448 je short @@mouse_moved_exit ; highlight if left button still pressed
449 call highlight_text ; In: cx,dx = mouse X,Y
450@@mouse_moved_exit:
451endif ;ENABLEPASTE ; Updates NextPositionLeft.
452@@exit3:
453 jmp @@exit
454;
455; ======================================================================
456; Target of initial look at press of button 1
457; ======================================================================
458@@test_button1_shifts: ; Test keyboard flag byte
459
460if ENABLECURSOR ;=========Cursor Key code ==========;
461; Mouse 1 ... ............ Position cursor (hold 1/6 sec)
462; LSHIFT-Mouse 1 ......... Cursor feature on/off
463; LSHIFT-ALT-Mouse 1 ..... Toggle methods /A1-/A3
464 mov al,byte ptr [ds:17h]
465 and al,00001111B ; Test alt, ctrl, Lshift, Rshift
466 jz @@test_button1_exit ; no modifiers were pressed
467 cmp al,00001010B ; ALT, LSHIFT
468 je short @@do_cursormethod
469 cmp al,00000010B
470 jne short @@leftshift_exit
471 not flag_arrowkeys ; Toggle the flag on/off (-1 or 0)
472 jmp short @@leftshift_exit
473@@do_cursormethod:
474 mov al,flag_editor
475 cmp al,MAX_of_A ; Toggle the cursor positioning method
476 jb short @@do_cursormethod_exit
477 xor al,al ; Flag will be 1,2,..,(MAX_of_A)
478@@do_cursormethod_exit:
479 inc al
480 mov flag_editor,al
481@@leftshift_exit:
482 jmp short @@exit ; finished
483@@test_button1_exit:
484endif ;end ENABLECURSOR ;=========Cursor Key code ==========;
485
486; ======================================================================
487; Target of button 1 press without key modifiers
488; ======================================================================
489@@left_pressed: ; get screen data after left click
490 mov ax,[ds:4ah]
491 mov lineSize,ax ; Characters per row for this video mode
492if ENABLEPASTE
493 mov ax,word ptr ds:[4eh]
494 mov videoOffset,ax ; Offset for current video page
495 cmp word ptr ds:[63h],3B4h ; Mono/Color BIOS word
496 mov videosegment,0b000h ; mono address
497 jz short @@left_pressed1
498 mov videosegment,0b800h ; color address
499@@left_pressed1:
500endif ;ENABLEPASTE
501 mov flag_Left,TRUE ; Mark Mouse1 pressed
502if ENABLECURSOR
503 or flag_doButtons,FlagButton1
504endif ;ENABLECURSOR
505if ENABLEPASTE
506 call unhighlight_text ; remove previous highlighting
507 mov flag_Right,FALSE ; why remove mark?
508; mov counter_blanks,0
509 call xy2offs ; In: cx,dx Out: ax
510 mov PositionLeft,ax ; Save mouse position and reset both
511 mov NextPositionLeft,ax ; because selected text was trashed.
512 call setLimits ; In: AX
513
514;
515; SPEED_LDC is the number of ticks of the system clock, 18.2 per
516; second, in which a left double-click must occur. Shorter times
517; are not considered double-click candidates.
518 mov flag_double,FALSE ; Assume not a double-click.
519 call ClickTimeDouble ; Uses: AX
520 jz short @@exit ; Not enough time.
521; double click
522 mov flag_double,TRUE
523 call highlight_word
524if ENABLECURSOR
525 and flag_doButtons,(not FlagButton1)
526endif ;ENABLECURSOR
527endif ;ENABLEPASTE
528@@exit:
529if ENABLECURSOR
530 cmp flag_doButtons,0
531 jz @@@exit
532 or flag_event,FlagCursor
533@@@exit:
534endif ;ENABLECURSOR
535 pop ds
536 XPOPA
537 ret
538MouseHandler endp
539
540SHOW_MOUSE proc
541 push ax
542 cmp flag_MouseOn,TRUE
543 jz short @@is_on
544 mov ax,1 ; Function show mouse
545 int 33h
546 mov flag_MouseOn,TRUE
547@@is_on:
548 pop ax
549 ret
550SHOW_MOUSE endp
551
552HIDE_MOUSE proc
553 push ax
554 cmp flag_MouseOn,FALSE
555 jz short @@no_hide
556 mov ax,2
557 int 33h
558 mov flag_MouseOn,FALSE
559@@no_hide:
560 pop ax
561 ret
562HIDE_MOUSE endp
563
564; Entry: AX = button bits from Mouse Device Driver
565; Exit: AX = button bits for swapped button order
566; Uses AX and flags
567
568NewButtonOrder proc
569 push cx
570 push bx
571 mov bl,al ; bits to fix
572 xor bh,bh ; accumulator
573 shl bl,1 ; fix up for BitBuster routine
574 mov cl,button_1fix ; shift amount for button 1
575 call BitBuster ; gather the bits
576 mov cl,button_2fix ; shift amount for button 2
577 call BitBuster ; gather the bits
578 mov cl,button_3fix ; shift amount for button 3
579 call BitBuster ; gather the bits
580 and al,10000001B ; strip relevant bits
581 or al,bh ; insert new bits
582 pop bx
583 pop cx
584 ret
585NewButtonOrder endp
586
587; Twiddle bits in the button word to get new order
588
589BitBuster proc
590 shr bl,1 ; move over 2 bits
591 shr bl,1
592 mov ch,bl
593 and ch,00000011B ; get lower two bits
594 shl ch,cl ; shift proper amount
595 or bh,ch ; add to accumulator
596 ret
597BitBuster endp
598
599; install mouse handler
600
601killed_flg db FALSE
602
603InstallMouseHandler proc far
604 XPUSHA
605 cmp killed_flg,TRUE ; /U in the mean time ?
606 je short @@exit ; we are in process of uninstall /U
607 push es
608 push cs
609 pop es
610 mov dx,offset MouseHandler
611 mov cx,XPCMOUSEMASK
612 mov ax,14h ; Swap Interrupt Subroutines
613 int 33h
614 and flag_event,(not FlagREINSTALL)
615 pop es
616@@exit:
617 XPOPA
618 ret
619InstallMouseHandler endp
620
621; Patch for EXEC Function
622; Fixed by GBG October 1995. See notes at top of file.
623; Fixed again 2 Feb 1997 GBG.
624new_21h proc far
625 pushf
626 cmp flag_reinstall_exit,FALSE
627 je short @@test_exec ; don't install mouse handler after exit
628 cmp ah,4ch ; Exit program
629 je short @@reinstall
630 cmp ah,00h ; Exit program
631 je short @@reinstall
632@@test_exec:
633 cmp flag_reinstall_exec,FALSE
634 je short @@do_old_21h ; don't install mouse handler before exec
635
636@@test_exec_x:
637 cmp ax,4b00h ; exec program
638 jne short @@do_old_21h ; nothing special
639@@reinstall:
640 or flag_event,FlagREINSTALL
641
642@@do_old_21h:
643 popf
644 db 0eah ; Code for jmp far
645old_21h dw 0,0
646new_21h endp
647
648; Patch for Interrupt 10h
649
650old_10h dw 0,0
651
652new_10h proc far
653 pushf ; simulate int
654 call dword ptr cs:[old_10h]
655 pushf
656 cmp counter_int10,0
657 jne @@exit
658 inc counter_int10 ; Mark int 10h active
659 call HIDE_MOUSE ; Video use hides the mouse
660if ENABLEPASTE
661 cmp flag_Highlight,FALSE
662 je short @@no_unselect
663 call unhighlight_text ; Uses no registers
664; mov flag_Left,FALSE ; why unmark a left press?
665@@no_unselect:
666endif ;ENABLEPASTE
667 dec counter_int10 ; Mark int 10h inactive
668@@exit:
669 popf
670 iret
671new_10h endp
672
673; BIOS data segment equates
674;
675biosdata segment at 40h
676org 1ah
677headptr dw (?) ; pointer to next key entry to read
678tailptr dw (?) ; pointer to last read key entry
679org 80h
680bufstrt dw (?) ; pointer to start keyboard buffer
681bufend dw (?) ; pointer to end keyboard buffer
682biosdata ends
683
684stuffkeyCX proc
685; substitute for Int 16h, function 5
686; in: ch=scan code
687; cl=ascii
688; out: al=0 success
689; al=1 buffer full
690; USES: ax,cx
691;
692 push ds
693 push bx
694 cli
695 mov ax,biosdata
696 mov ds,ax
697 mov ax,ds:tailptr
698 inc ax
699 inc ax ; ax += 2
700 xor bl,bl
701 inc bl ; bl == 1
702 cmp ax,ds:headptr ; don't want tailptr == headptr after exit
703 jz short @@full ; because it means buffer is empty!
704 cmp ax,ds:bufend ; Ringbuffer, may need to bump pointer
705 jnz short @@no_wrap
706 mov ax,ds:bufstrt ; wrap around was required
707@@no_wrap: ; AX == new tailptr position
708 cmp ax,ds:headptr ; don't want tailptr == headptr after exit
709 jz short @@full ; because it means buffer is empty!
710@@go_ahead:
711 mov bx,ds:tailptr ; old tailpointer
712 mov [ds:bx],cx ; store scan+ascii
713 mov ds:tailptr,ax
714 xor bl,bl
715@@full:
716 mov al,bl
717 pop bx
718 pop ds
719 or al,al ; 0 == save was successful
720 ret ; sti not appropriate here
721stuffkeyCX endp
722
723count_08h db 0
724count_waitkey db 0
725;
726; Patch for int 08h basic timer interrupt
727; Logic: Calls old 08h, including user timer 1c, then does
728; duties related to xpcmouse.
729; Needs a rewrite with bit operations so that the overhead is lower.
730; Example: all bits in one byte, test for bits with 1 instruction, not 10.
731;
732new_08h proc far
733 pushf
734 call dword ptr cs:[old_08h]
735 pushf
736 cmp count_08h,0
737 jne @@exit1
738 inc count_08h
739 cmp counter_int10,0 ; Get out now if int 10h active
740 jne @@exit1
741 push ax
742 cmp flag_event,0
743 jz @@getshiftstatus
744 call HouseKeeping ;Uses AX
745@@getshiftstatus:
746 push ds
747 mov ds,biosSEG
748 mov al,byte ptr ds:[17h]
749 pop ds
750 test al,00000001B ;Right shift depressed?
751 jz @@keyloop_exit
752 mov ah,00001111B
753 and ah,al
754 cmp ah,00000111B ;Right shift, Left shift and ctrl?
755 jne @@wait_exit
756 inc count_waitkey
757 cmp count_waitkey,20
758 jb @@keyloop_exit
759 or flag_event,FlagREINSTALL
760@@wait_exit:
761 mov count_waitkey,0
762@@keyloop_exit:
763 pop ax
764
765@@exit:
766 dec count_08h
767@@exit1:
768 popf
769 iret
770old_08h dw 0,0
771new_08h endp
772
773HouseKeeping proc near
774; Efficiency measure for the int 08h code, caller of HouseKeeping.
775; Ring the bell when we hit this routine to measure frequency.
776; push ax
777; mov ax,0E07h
778; int 10h
779; pop ax
780 mov al,flag_event
781 test al,FlagPASTE+FlagCURSOR
782 jz @@stuff2key_exit
783 call stuff2keybuffer
784 ret
785@@stuff2key_exit:
786 test al,FlagREINSTALL ; Is he dead, Jim?
787 jz @@install_exit
788 call InstallMouseHandler ; Blood transfusion.
789 ret
790@@install_exit:
791if ENABLEFILEAPPEND
792 test al,FlagFILEAPPEND ; Write the pastebuffer to a file?
793 jz @@fileappend_exit
794 call appendPaste2File ; May not work because the disk is busy
795 ret
796@@fileappend_exit:
797 test al,FlagWINCLIP ; Write pastebuffer to win clipboard
798 jz @@winclip_exit
799 call appendPaste2Windows ; Write to windows clipboard
800@@winclip_exit:
801endif ;ENABLEFILEAPPEND
802 ret
803HouseKeeping endp
804
805; Patch for int 16h
806MOUSE_FN equ 8080h ; new function of int 16h that detects
807 ; previous installation of the program
808MOUSE_FNDEC equ 7f80h ; Second detector
809IDENTCODE equ 46879 ; A 16-bit number used to test validity of /U
810 ; and /R options. 4=version 1.4
811
812new_16h proc far
813 cmp ax,MOUSE_FN ; New function for int 16h
814 jnz short @@skip1
815 dec ah ; AH unchanged by normal bios call
816 mov cx,IDENTCODE ; Return identity code
817 push cs ; and far address of the pastebuffer
818 pop es ; es:bx := buffer address
819 mov bx,offset pastebuf
820 iret
821@@skip1:
822 pushf
823 call stuff2keybuffer
824 popf
825 db 0eah ; Code for jmp far
826old_16h dw 0,0
827new_16h endp
828
829;
830; stuff2keybuffer --- Write characters into keyboard buffer
831;
832stuff2keybuffer proc ; stuff to keyboard buffer
833 cmp flag_busy_stuffing,1 ; In routine "stuff2keybuffer"?
834 je @@exitfast ; wait until next timer tick
835 mov flag_busy_stuffing,1 ; Don't let the timer interrupt
836 ; re-enter this routine!
837 XPUSHA
838
839if ENABLEPASTE
840 xor cx,cx
841 xchg cl,lastChar ; character left from last attempt
842 or cl,cl ; 0 == nothing left
843 jnz short @@after_rd ; save character from last trial
844@@loop:
845 call GetPastebuffer2AL ; Nothing returned if flag_pastebuffer == 0
846 mov cl,al ; else AL == char found in pastebuffer
847 jc short @@@exit ; nothing to stuff into keybuffer
848@@after_rd:
849 push cx
850 xor ch,ch ; default scancode 0; ENTER is trouble
851 cmp cl,13 ; cl==13 is end of line
852 jne @@scan_code ; Potential trouble: wrong scan codes!
853 mov ch,1ch ; scancode for ENTER
854@@scan_code:
855 call stuffkeyCX ; stuff CX to keyboard buffer, uses ax,cx
856 pop cx
857 jz short @@loop ; 0 == save was successful
858 mov lastChar,cl ; save for next time
859 jmp short @@exit
860
861@@@exit: ; Get here because pasting is finished.
862 mov lastChar,0
863 and flag_event,(not FlagPASTE) ; Mask off event, Paste Done!
864endif ;ENABLEPASTE
865
866if ENABLECURSOR ;=========Cursor Key code ==========;
867 call StuffArrows ; Stuff arrow keys and Xterm sequences
868endif ;end ENABLECURSOR ;=========Cursor Key code ==========;
869
870@@exit:
871 XPOPA
872 mov flag_busy_stuffing,0 ; Let the timer interrupt
873@@exitfast: ; re-enter this routine!
874 ret
875stuff2keybuffer endp
876
877
878if ENABLEPASTE
879; calculate video offset from x and y
880; The x and y are in pixel counts, not Mickeys.
881; (the Mouse unit is named after Mickey Mouse).
882; In: x=cx, y=dx ; Left upper corner of screen is x=0, y=0.
883; These values of x,y are Bios cursor locations.
884; We must convert to screen coordinates. In 40-col mode,
885; there are 16 pixels per char. In 80-col mode, 8 pixels per
886; char. In 132-col mode there are 4 pixels per char, but no mouse
887; device drivers are known to operate in 132 cols: they only know
888; about 40-col and 80-col bios modes 0 to 13h.
889; Out: ax := offs = (y*lineSize)/8 + (x/8 or x/16)
890; USES: ax
891xy2offs proc
892 PUSHR <dx,cx>
893 shr cx,1
894 shr cx,1
895 shr cx,1
896 cmp lineSize,40
897 jnz short @@no_40
898 shr cx,1 ; divide by 16 if there are 40 columns per line
899 @@no_40:
900 shr dx,1
901 shr dx,1
902 shr dx,1
903 mov ax,dx
904 mul lineSize
905 add ax,cx ; +=x
906 add ax,ax ; 2 bytes per character
907 add ax,videoOffset
908; inc ax ; -> attribute
909 POPR <cx,dx>
910 ret
911xy2offs endp
912
913; show or hide mark on screen
914; In: AX=characters*2 for XOR operation
915; USES: AX
916xor_screen proc
917 PUSHR <bx,cx,dx,ds>
918 call HIDE_MOUSE ; in order not to destroy the mouse cursor
919 mov ds,videosegment
920 mov dolimits,TRUE
921 mov cx,PositionLeft
922 mov bx,NextPositionLeft
923 cmp cx,bx
924 je @@exit
925 jb @@doswap
926 mov ax,cx
927 call findColumn
928 cmp dx,marginleft
929 je short @@dolimits
930 jmp short @@normal ; Matrix box highlighting
931@@doswap:
932 xchg cx,bx ; switch 'em
933@@dolimits:
934 mov ax,lineSize ; Set for Xterm highlighting
935 dec ax
936 add ax,ax
937 mov marginright,ax
938 mov marginleft,0
939 mov dolimits,FALSE
940@@normal:
941 mov dl,xor_mask
942@@loop:
943 mov ax,bx
944 inc bx
945 call column_test
946 jnz @@failed
947 xor byte ptr [ds:bx],dl ; xor_mask applied to attribute byte
948@@failed:
949 inc bx
950 cmp bx,cx
951 jbe short @@loop
952@@exit:
953; call SHOW_MOUSE
954 POPR <ds,dx,cx,bx> ;PUSHR <bx,cx,dx,ds>
955 ret
956xor_screen endp
957
958; Check for pointer inside column boundaries
959; In: AX == screen offset
960; Out: NZ if outside, Carry set if hit right margin
961; Uses: AX, FLAGS
962column_test proc near
963 push ax
964 push dx
965 call findColumn ;In: ax, Out: dx=col
966 cmp marginleft,dx
967 ja @@failed
968 cmp dx,marginright
969 ja @@failed
970 je @@failedright
971 xor ax,ax ; set Z flag and no Carry
972@@exit:
973 pop dx
974 pop ax
975 ret
976@@failedright:
977 xor ax,ax ; Z set
978 stc ; Carry set
979 jmp short @@exit
980@@failed:
981 xor ax,ax
982 inc ax ; No carry, NZ set
983 jmp short @@exit
984column_test endp
985
986; In: ax==screen offset
987; Out: dx==column
988; Uses: dx
989findColumn proc near
990 push ax
991 push cx
992 xor dx,dx
993 mov cx,lineSize
994 add cx,cx
995 div cx ; quotient ==> AX, Remainder ==> DX
996 pop cx
997 pop ax
998 ret
999findColumn endp
1000
1001; Determine matrix boundaries with max/min method
1002; In: Nothing
1003; Out: marginright, marginleft reset
1004setLimits proc near
1005 cmp dolimits,FALSE
1006 je @@quit
1007 push dx
1008 push cx
1009 push ax
1010
1011 mov ax,NextPositionLeft
1012 call findColumn
1013 mov cx,dx ;cx == current corner column
1014
1015 mov ax,PositionLeft
1016 call findColumn ;dx == first corner column
1017
1018 cmp dx,cx ;Is dx < cx?
1019 jb @@next
1020 xchg cx,dx ;switch 'em
1021@@next:
1022 mov marginleft,dx
1023 mov marginright,cx
1024 pop ax
1025 pop cx
1026 pop dx
1027@@quit:
1028 ret
1029setLimits endp
1030
1031; Highlight single word chosen by double click
1032; USES: AX
1033highlight_word proc
1034 PUSHR <bx,ds>
1035 xor bx,bx
1036 mov lasttime,bx
1037 mov lasttime+2,bx ; prevent Triple click
1038 mov ds,videosegment
1039 mov bx,PositionLeft ; point to letter
1040 call @@tst_letter
1041 jc @@exit ; clicked to void
1042 @@go_left: ; search for word begin
1043 call @@tst_letter
1044 dec bx
1045 dec bx
1046 jnc @@go_left
1047 add bx,4 ; points to letter again
1048 mov PositionLeft,bx
1049 @@go_right: ; search for word end
1050 inc bx
1051 inc bx
1052 call @@tst_letter
1053 jnc @@go_right
1054 dec bx
1055 dec bx
1056 mov NextPositionLeft,bx
1057 call setLimits
1058 call xor_screen ; Uses ax
1059 @@exit:
1060 POPR <ds,bx>
1061 ret
1062
1063; @@tst_letter --- Test character classes.
1064; Do this like Xterm, with a string of data pairs:
1065; 35:35,45:57,64:90,95:95,97:122,128:165
1066; USES: AX
1067;
1068 @@tst_letter:
1069 push si
1070 mov si,offset unix_ranges
1071 xor ah,ah
1072 mov al,[ds:bx]
1073 @@tst_loop:
1074 cmp ah,unix_pairs
1075 je @@tst_failed
1076 inc ah
1077 cmp byte ptr [cs:si],al
1078 jbe short @@tst_1
1079 inc si
1080 inc si
1081 jmp short @@tst_loop
1082 @@tst_1:
1083 inc si
1084 cmp al,byte ptr [cs:si]
1085 jbe short @@tst_worked
1086 inc si
1087 jmp short @@tst_loop
1088 @@tst_worked:
1089 clc
1090 jmp short @@tst_exit
1091 @@tst_failed:
1092 stc
1093 @@tst_exit:
1094 pop si
1095 ret
1096highlight_word endp
1097;
1098; Highlight screen area that was traversed during mouse motion.
1099; In: cx,dx = mouse X,Y
1100; USES: AX
1101highlight_text proc
1102 push bx
1103 call xy2offs ; In: cx,dx Out: ax
1104 push ax ; New left mouse position
1105 sub ax,NextPositionLeft ; ax/2 == number of positions traversed
1106 pop bx
1107 jz short @@exit ; too little mouse motion
1108 call unhighlight_text ; Turn off highlighting
1109 mov NextPositionLeft,bx ; update new mouse position
1110 call setLimits ; Find matrix width
1111 call xor_screen ; In: AX=number positions times 2
1112 mov flag_Highlight,TRUE
1113 @@exit:
1114 pop bx
1115 ret
1116highlight_text endp
1117
1118; Remove highlight from screen area.
1119; Uses: none
1120unhighlight_text proc
1121 push ax
1122 cmp flag_Highlight,FALSE
1123 je short @@exit ; Highlighting was already undone.
1124 call xor_screen ; Unhighlight. Uses: AX
1125 mov flag_Highlight,FALSE
1126 @@exit:
1127 pop ax
1128 ret
1129unhighlight_text endp
1130
1131;
1132; Fill_pastebuffer: Read the selected characters into pastebuffer.
1133; Called after double click or left selection.
1134; Return: Carry not set if pasting and PositionLeft==NextPositionLeft
1135Fill_pastebuffer proc
1136; PUSHR <bx,cx,dx,si,di,es,ds>
1137 XPUSHA
1138 PUSHR <es,ds>
1139 cmp flag_pastebuffer,FALSE ; Are we supposed to paste?
1140 stc
1141 je short @@quit ; No, then exit with carry set
1142 push cs ; Yes, then fool with pastebuffer
1143 pop es ; store chars to es:di
1144 mov bx,PositionLeft
1145 mov cx,NextPositionLeft
1146 cmp cx,bx
1147 ja short @@set_loop ; not marked from right to left
1148 xchg bx,cx ; now from left to right
1149 jnz short @@set_loop ; nothing at all marked
1150@@exit_nochars: ; Nothing marked
1151 clc
1152 jmp short @@@exit
1153
1154@@set_loop:
1155 mov di,offset pastebuf ; Start at top of paste buffer
1156 mov nextpair,di ; di == offset into buffer
1157 cld
1158 mov ds,videosegment
1159 dec bx
1160 dec bx ; back up to get started
1161 xor dl,dl ; initialize end of line markers
1162@@loop:
1163 cmp di,EndOfBuffer
1164 ja short @@OutofRoom ; Buffer is full
1165 or dl,dl
1166 jnz short @@trim
1167 cmp bx,cx
1168 jz short @@OutofData
1169 inc bx
1170 inc bx ; next char on screen
1171 mov ax,bx
1172 call column_test ;NZ if outside, Carry set if hit right margin
1173 jc short @@fixEOL ; Hit the right edge
1174 jnz short @@loop ; Outside margins
1175@@regularData:
1176 mov al,[ds:bx]
1177 cmp al,' ' ; Skip unprintable characters
1178 jb short @@loop
1179@@SaveCodedByte:
1180 stosb ; Otherwise, store coded byte
1181 jmp short @@loop
1182@@fixEOL:
1183 inc dl ; Mark the problem
1184 jmp short @@regularData ; Stuff the character
1185@@trim: ; discard blanks until end of line
1186 call @@trimFunction
1187 jmp short @@SaveCodedByte
1188
1189@@OutofRoom:
1190@@OutofData:
1191 mov lastpair,di ; pointer to end of used buffer area
1192 dec di
1193 cmp byte ptr [es:di],10 ; End with LF?
1194 jne short @@quit
1195 dec di
1196 mov lastpair,di ; pointer to end of used buffer area
1197@@quit:
1198 stc ; Carry set if something in buffer
1199
1200@@@exit:
1201 POPR <ds,es> ; PUSHR <es,ds>
1202 XPOPA
1203; POPR <ds,es,di,si,dx,cx,bx> ; PUSHR <bx,cx,dx,si,di,es,ds>
1204 ret
1205; Trim spaces on end and add CR/LF pair into buffer
1206@@trimFunction:
1207 cmp dl,2 ; Second time?
1208 jne @@trimLoop
1209 xor dl,dl ; Last time here
1210 mov al,10 ; Insert linefeed
1211 ret
1212@@trimLoop:
1213 dec di
1214 cmp byte ptr [es:di],' ' ; Expunge unprintables
1215 ja short @@trimDone
1216 cmp byte ptr [es:di],10 ; end of previous line ?
1217 jne short @@trimLoop
1218@@trimDone:
1219 inc di
1220 mov al,13 ; 13 to mark end of line
1221 inc dl ; Mark it done
1222 ret
1223Fill_pastebuffer endp
1224
1225; ClickTimeDouble --- Return Z if time since last left click too short.
1226; Uses: AX
1227ClickTimeDouble proc
1228 PUSHR <cx,dx>
1229 xor ah,ah
1230 int 1ah ; read system clock counter
1231 xor ax,ax ; Return AX==0 in Z flag
1232 push cx ; high word
1233 push dx ; low word
1234 sub dx,lasttime
1235 sbb cx,lasttime+2 ; cx:dx = ticks since last click
1236 pop cs:lasttime
1237 pop cs:lasttime+2 ; save new clock time
1238 or cx,cx
1239 jnz short @@exit ; Exceeded 65535/18.2 seconds
1240 cmp dx,SPEED_LDC
1241 ja short @@exit ; Exceeded SPEED_LDC seconds
1242 inc ax ; Was a double-click.
1243@@exit:
1244 or ax,ax
1245 POPR <dx,cx>
1246 ret
1247ClickTimeDouble endp
1248
1249; Get characters from the paste buffer
1250; Characters are 33 to 255
1251; A character nnn less than 33 represents nnn Blanks
1252; End of line is marked with 0
1253;
1254; In: Nothing
1255; Out: ZF flag == buffer empty else AL == char found
1256; Uses: AX, flags, es
1257;
1258GetPastebuffer2AL proc
1259 push es
1260 cmp flag_pastebuffer,FALSE ;Pasting enabled? (-1=enabled)
1261 je short @@buf_empty
1262 cmp flag_Right,FALSE ;Buffer defined? (-1=Yes)
1263 je short @@buf_empty
1264 push cs
1265 pop es
1266@@loop:
1267 call GetPasteBuf ; Grab char to AL
1268 jc @@buf_empty ; Exit with carry set
1269 cmp al,10 ; Purge linefeeds
1270 je short @@loop
1271 clc
1272 jmp short @@exit
1273@@buf_empty:
1274 stc
1275@@exit:
1276 pop es
1277 ret
1278GetPastebuffer2AL endp
1279
1280; In: es==segment of pastebuffer
1281; Out: ZF flag == buffer empty else AL == char found
1282; Uses: AX, flags, es
1283;
1284GetPasteBuf proc
1285 push bx
1286 mov bx,nextpair
1287 cmp bx,lastpair
1288 jnz short @@not_empty
1289 cmp flag_CtrlRight,TRUE ; append CR, too ?
1290 jne short @@buf_empty
1291 mov flag_CtrlRight,FALSE ; Mark that we did it.
1292 mov al,13 ; return CR
1293 jmp short @@char_found
1294
1295@@not_empty:
1296 mov al,[es:bx] ; get next character
1297 inc nextpair
1298@@char_found:
1299 clc
1300@@exit:
1301 pop bx
1302 ret
1303@@buf_empty:
1304 stc
1305 jmp short @@exit
1306GetPasteBuf endp
1307
1308if ENABLEFILEAPPEND
1309; These routines append active paste buffer to a file.
1310; by GBG February 1997
1311
1312; Entry: fileappend==file name
1313; Exit: paste buffer appended to file.
1314; Uses: ax
1315appendPaste2File proc
1316 PUSHR <bx,cx,dx,ds,es>
1317 cmp cs:counter_int13,0
1318 jnz @@done ;disk busy, don't try it
1319 mov ax,cs
1320 mov ds,ax
1321 mov es,ax
1322 mov nextpair,offset pastebuf
1323 mov flag_CtrlRight,FALSE ; Don't append CR
1324; mov counter_blanks,0
1325; Open the file
1326 mov ax,3d02h ;open file read and write
1327 mov dx,offset filen ;file name 0 terminated
1328 int 21h
1329 jnc @@goodopen
1330 xor cx,cx ;file attributes zero
1331 mov ah,03ch ;create file
1332 int 21h
1333 jnc @@goodopen ;carry flag means bad open
1334@@bad_open:
1335 call bell ;send terminal bell as a signal
1336 jmp short @@finished ;for bad open
1337@@goodopen:
1338 mov bx,ax ;bx=filehandle
1339@@seek: ; Seek to the end of the file
1340 xor cx,cx ;cx=high word=0
1341 mov dx,cx ;dx=low word of seek amount=0
1342 mov ax,4202h ;seek end of file, handle==bx
1343 int 21h
1344@@loop:
1345 call GetPasteBuf ; AL == char found in pastebuffer
1346 jc short @@@exit ; nothing left in pastebuffer
1347 call @@writeByte
1348 jmp short @@loop
1349@@@exit:
1350 mov al,13
1351 call @@writeByte
1352 mov al,10
1353 call @@writeByte
1354 mov ah,3eh
1355 int 21h ;close file, handle==bx
1356@@finished:
1357 and flag_event,(not FlagFILEAPPEND) ;Mark it done. Don't do it again!
1358@@done:
1359 POPR <es,ds,dx,cx,bx> ;PUSHR <bx,cx,dx,ds,es>
1360 ret
1361@@writeByte:
1362 mov byte ptr cs:stringf,al
1363 mov cx,1
1364 mov dx,offset stringf ; String location for write
1365 mov ah,40h
1366 int 21h ;write string to file, handle==bx
1367 ret
1368appendPaste2File endp
1369
1370count_winclip db 0
1371; Entry: Nothing
1372; Exit: paste buffer appended to windows clipboard, if it exists
1373; Uses: ax, flags
1374appendPaste2Windows proc
1375; PUSHR <bx,cx,dx,es,si,di>
1376 XPUSHA
1377 push es
1378 mov ax,1600h ;See if Enhanced mode windows
1379 int 2fh
1380 or al,al
1381 je @@finished ; Not enhanced mode, so quit
1382
1383; Open the file
1384 mov di,1
1385 mov ax,1700h ;Check API
1386 int 2fh
1387 or ax,ax ;no API
1388 je @@exit_error
1389 mov ax,1701h ;Open Windows Clipboard
1390 int 2fh
1391 or ax,ax
1392 je @@exit_error
1393 mov ax,1702h ;Clear Windows Clipboard
1394 int 2fh
1395 or ax,ax
1396 je @@closeClip ;Error, exit
1397 xor di,di
1398 push cs
1399 pop es
1400 mov bx,offset pastebuf ;ES:BX ptr to data
1401 mov cx,lastpair
1402 sub cx,bx ; CX == byte count
1403 mov ax,1703h ;Set clipboard data
1404 xor si,si ;SI,CX = data size
1405 mov dx,7 ;Data format is OEM text
1406 int 2fh
1407@@closeClip:
1408 mov ax,1708h ;Close Clipboard
1409 int 2fh
1410 or di,di
1411 jnz @@exit_error
1412@@finished:
1413 mov count_winclip,0 ; Reset counter
1414 and flag_event,(not FlagWINCLIP) ;Mark it done. Don't do it again!
1415@@done:
1416 pop es
1417 XPOPA
1418; POPR <di,si,es,dx,cx,bx> ;PUSHR <bx,cx,dx,es,si,di>
1419 ret
1420@@exit_error:
1421 inc count_winclip
1422 cmp count_winclip,18
1423 jb short @@done ;try again later
1424 call bell ;send terminal bell as a signal
1425 jmp short @@finished ;for any error
1426appendPaste2Windows endp
1427
1428
1429bell proc near ;Sound the terminal bell
1430 mov ax,0E07h
1431 int 10h
1432 ret
1433bell endp
1434
1435
1436; Patch for Interrupt 13h, disk
1437
1438old_13h dw 0,0
1439counter_int13 db 0
1440
1441new_13h proc far
1442 inc cs:counter_int13
1443 pushf ; simulate int
1444 call dword ptr cs:[old_13h]
1445 pushf
1446 dec cs:counter_int13
1447 popf
1448 ret 2 ;Preserve flags
1449new_13h endp
1450
1451; Has to be hooked into code during init and exit
1452
1453endif ;ENABLEFILEAPPEND
1454
1455endif ;ENABLEPASTE
1456
1457;; ========ENABLECURSOR: Begin cursor handling routines.===========
1458
1459if ENABLECURSOR ;=========Cursor Key code ==========;
1460
1461; ClickTimeCursor --- Return Z if time since last left-click was short.
1462; Uses: AX
1463ClickTimeCursor proc
1464 PUSHR <cx,dx>
1465 xor ah,ah
1466 int 1ah ; read system clock counter
1467if ENABLEPASTE
1468 sub dx,lasttime
1469 sbb cx,lasttime+2 ; cx:dx = ticks since last left press
1470 or cx,cx
1471 jnz short @@setcursor; Exceeds 65535/18.2 seconds
1472 cmp dx,SPEED_LC
1473 jb short @@exit ; Less than 3/18.2 seconds
1474endif ;ENABLEPASTE
1475@@setcursor:
1476 call set_cursor ; set text cursor position
1477@@exit:
1478 POPR <dx,cx>
1479 ret
1480ClickTimeCursor endp
1481
1482;
1483; Arrow key routines, does not depend on Xterm standard.
1484;
1485LeftArrow proc
1486 mov cx,4b00h ;cl=0, ch=4bh Left arrow key
1487 call stuffkeyCX ; uses ax,cx
1488 ret
1489LeftArrow endp
1490DownArrow proc
1491 mov cx,5000h ;cl=0, ch=50h Down arrow key
1492 call stuffkeyCX ; uses ax,cx
1493 ret
1494DownArrow endp
1495UpArrow proc
1496 mov cx,4800h ;cl=0, ch=48h Up arrow key
1497 call stuffkeyCX ; uses ax,cx
1498 ret
1499UpArrow endp
1500RightArrow proc
1501 mov cx,4d00h ;cl=0, ch=4dh Right arrow key
1502 call stuffkeyCX ; uses ax,cx
1503 ret
1504RightArrow endp
1505;
1506; Test keyboard buffer for room to copy scan codes
1507; In: AL == # scan codes
1508; Out: NZ flag set if no room exists
1509; Uses: AX, FLAGS
1510Check4Room proc
1511 PUSHR <ds,bx,ax>
1512 mov bl,al ; Number of pairs required
1513 mov ax,biosdata
1514 mov ds,ax
1515 mov ax,ds:tailptr
1516@@loop:
1517 add ax,2
1518 cmp ax,ds:bufend ; Ringbuffer, may need to bump pointer
1519 jnz short @@no_wrap
1520 mov ax,ds:bufstrt ; wrap around was required
1521@@no_wrap: ; AX == new tailptr position
1522 cmp ax,ds:headptr ; don't want tailptr == headptr after exit
1523 jz short @@full ; because it means buffer is empty!
1524@@go_ahead:
1525 dec bl
1526 or bl,bl
1527 jnz short @@loop
1528@@full:
1529 or bl,bl ; 0 == it worked, NZ == failed
1530 POPR <ax,bx,ds>
1531 ret
1532Check4Room endp
1533;
1534; Xterm standard uses the sequence "ESC [ M cb cx cy" where
1535; cb=32 for press button1, cb=34 for press button3, cb=33 for
1536; press button2, cb=35 for release (any) button, cx=32+1+col,
1537; cy=32+1+row where (0,0) is upper left corner of screen
1538;
1539; Stuff a string of scan code data into the keyboard buffer
1540;
1541; In: bx=offset to string, al=number of pairs
1542; Uses: ax,bx
1543;
1544; The string must fit all at once for this procedure to succeed.
1545; We test the keyboard buffer to see if there is room to do the copy.
1546; If not enough room, then the call fails!
1547;
1548StuffCodes2keybuffer proc
1549 push cx
1550 cmp flag_arrowkeys,FALSE ; Arrow and Xterm stuffing disabled?
1551 je short @@exit ; Yes, then quit fast.
1552; Test for room to do the copy
1553 call Check4Room ; Does the keyboard buffer have room
1554 jnz short @@exit ; for AL pairs? NZ flag == NO ROOM, Exit!
1555@@loop:
1556 cmp al,0
1557 je @@exit
1558 dec al
1559 mov cl,byte ptr [cs:bx] ; ASCII value
1560 inc bx
1561 mov ch,byte ptr [cs:bx] ; Scan code
1562 inc bx
1563 push ax
1564 call stuffkeyCX ; uses ax,cx
1565 pop ax
1566 jmp short @@loop
1567@@exit:
1568 pop cx
1569 ret
1570StuffCodes2keybuffer endp
1571
1572; Stuff cursor location into data area using Xterm codes
1573; In: al=Y=row, ah=Y=col, the cursor location in PC terms.
1574; bx=offset to data area
1575; Uses: ax,bx
1576; Xterm codes are ROW=X+' '+1, COL=Y+' '+1.
1577; Xterm_PAD==' '+1. Assume fake scan codes.
1578;
1579StuffLoc2buffer proc
1580 add ah,Xterm_PAD ; coded col for Xterm
1581 mov byte ptr [cs:bx],ah
1582 inc bx
1583 inc bx
1584 add al,Xterm_PAD ; coded row for Xterm
1585 mov byte ptr [cs:bx],al
1586 ret
1587StuffLoc2buffer endp
1588
1589; Stuff left button info into keyboard buffer
1590; In: al=row, ah=column
1591; Uses: ax
1592;
1593StuffButton1 proc
1594 push bx
1595 mov bx,offset Button1_COL ; Offset to data area
1596 call StuffLoc2buffer ; Stuff cursor location into buffer
1597 mov bx,offset Button1_ESC ; Escape sequence for button 1
1598 mov al,Button1_LEN ; Number of pairs in button 1 escape.
1599 call StuffCodes2keybuffer ; Stuff escape seq into key buffer
1600 pop bx
1601 ret
1602StuffButton1 endp
1603
1604; Simulate press of button 3 on any mouse. Left release is mapped to
1605; the press of button three which normally follows button one. This button
1606; ends the marking of a region and maybe it copies it too, depending on the
1607; client program at the remote host end.
1608;
1609StuffButton3 proc
1610; In: al=row, ah=column
1611; Uses: ax
1612; We assume the keyboard buffer empty!
1613; Simplifies logic, but may fail.
1614 push bx
1615 mov bx,offset Button3_COL ; Data area pointer
1616 call StuffLoc2buffer ; Stuff cursor location into buffer
1617 mov bx,offset Button3_ESC ; Escape sequence for button 3
1618 mov al,Button3_LEN ; Number of pairs in button 3 escape.
1619 call StuffCodes2keybuffer ; Stuff escape seq into key buffer
1620 pop bx
1621 ret
1622StuffButton3 endp
1623
1624StuffCR proc
1625; Uses: ax
1626; We assume the keyboard buffer empty!
1627; Simplifies logic, but may fail.
1628 push bx
1629 mov bx,offset CR_ESC ; Escape sequence for carriage return
1630 mov al,CR_LEN ; Number of pairs in cr escape.
1631 call StuffCodes2keybuffer ; Stuff escape seq into key buffer
1632 pop bx
1633 ret
1634StuffCR endp
1635;
1636; Simulate button2 press on any mouse.
1637;
1638StuffButton2 proc
1639; In: al=row, ah=column
1640; Uses: ax
1641; We assume the keyboard buffer empty!
1642; Simplifies logic, but may fail.
1643 push bx
1644 mov bx,offset Button2_COL ; Data area pointer
1645 call StuffLoc2buffer ; Stuff cursor location into buffer
1646 mov bx,offset Button2_ESC ; Escape sequence for button 2
1647 mov al,Button2_LEN ; Number of pairs in button 1 escape.
1648 call StuffCodes2keybuffer ; Stuff escape seq into key buffer
1649 pop bx
1650 ret
1651StuffButton2 endp
1652;
1653; Get mouse position from handler's last call
1654; OUT: al=row, ah=col
1655; USES: AX
1656GetMousePosition proc
1657 PUSHR <dx,cx>
1658 mov cx,current_X
1659 shr cx,1 ; Get target column position in cl
1660 shr cx,1
1661 shr cx,1
1662 cmp lineSize,40
1663 jnz short @@not_40
1664 shr cx,1 ; divide by 16 if there are 40 columns per line
1665 @@not_40:
1666 mov dx,current_Y
1667 shr dx,1 ; Get target row position in dl
1668 shr dx,1
1669 shr dx,1
1670 mov al,dl
1671 mov ah,cl
1672 POPR <cx,dx>
1673 ret
1674GetMousePosition endp
1675;
1676; Calculate from offset into screen memory the screen row, col
1677; Left upper corner of screen is row=0, col=0 [rows 0..59, cols 0..131]
1678; In: ax=offset into screen memory (includes attribute counts).
1679; Out: ah := col, al = row
1680offs2xy proc
1681 push bx
1682 shr ax,1 ; divide numerator AX by 2
1683 mov bx,lineSize ; bl=denominator
1684 idiv bl ; AX/bl --> al=quotient, ah=remainder
1685 pop bx
1686 ret
1687offs2xy endp
1688;
1689; Do Xterm selection by stuffing escapes into the keyboard buffer
1690; Return no carry bit when processing is over
1691DoXtermButtons proc
1692 and flag_doButtons,(not FlagButtonCR) ; Disallowed for /A3
1693@@top:
1694 mov al,flag_doButtons
1695 test al,FlagButton1
1696 jz short @@Button1_exit
1697@@do_xterm3:
1698 mov ah,col_target
1699 mov al,row_target
1700 cmp ah,col_present
1701 jne short @@do_xterma
1702 cmp al,row_present
1703 je short @@do_xterm_exit
1704@@do_xterma: ; We assume the keyboard buffer empty!
1705 ; Simplifies logic, but may fail.
1706 mov col_present,ah
1707 mov row_present,al ; AX=Where to report cursor
1708 call StuffButton1 ; Stuff Xterm escape into keybuffer
1709@@do_xterm_exit:
1710 and flag_doButtons,(not FlagButton1)
1711 jmp short @@top
1712@@Button1_exit:
1713 test al,FlagButton13
1714 jz short @@Button13_exit
1715; Our selection here maps a button1 drag into "press left", "move"
1716; and "press right", which is the 3-button Xterm standard for marking
1717; a region.
1718 push cx
1719 mov ax,PositionLeft
1720 mov cx,NextPositionLeft
1721 cmp ax,cx
1722 jc short @@no_swap ; not marked from right to left
1723 xchg ax,cx ; now from left to right
1724@@no_swap:
1725; Send left button info
1726 push cx
1727 call offs2xy ; AX/lineSize --> al=quotient, ah=remainder
1728 call StuffButton1 ; stuff Xterm escape for button 1
1729; Send right button info, to simulate button3 on a 2-button mouse.
1730 pop ax ; prep for integer division, AX=top
1731 call offs2xy ; AX/lineSize --> al=quotient, ah=remainder
1732 call StuffButton3 ; stuff Xterm escape for button 3
1733 pop cx
1734 and flag_doButtons,(not FlagButton13)
1735 jmp short @@top
1736@@Button13_exit:
1737;
1738; Stuff button 2 (see unix figure) info into the keyboard buffer
1739; This button normally causes the remote client to insert the
1740; local pastebuffer (unix Xterm standard).
1741;
1742 test al,FlagButton2
1743 jz short @@Button2_exit
1744 call GetMousePosition ;al=row, ah=col
1745 call StuffButton2
1746 and flag_doButtons,(not FlagButton2)
1747 jmp short @@top
1748@@Button2_exit:
1749; Stuff right button (button 3) info into the keyboard buffer
1750; This button normally causes the remote client to define the
1751; region after a left button was received (Xterm standard).
1752; This is the extra button on a PC 3-button mouse.
1753;
1754 test al,FlagButton3
1755 jz short @@exit
1756 call GetMousePosition ;al=row, ah=col
1757 call StuffButton3
1758 and flag_doButtons,(not FlagButton3)
1759@@exit:
1760 ret
1761DoXtermButtons endp
1762
1763;
1764; Move cursor by stuffing keyboard buffer with escapes or arrow keys.
1765;
1766StuffArrows proc
1767;
1768@@arrows:
1769;
1770; emacs/vi: If the target row is not equal to the present row, then move
1771; the cursor to column one of the same line before doing any
1772; further cursor motion. Logic from emacs/vi/jed/jove.
1773; matrix: Move to row first, then to column, no tricky cursor moves.
1774; xterm: Use the escape sequence \033 [ M cb cx cy
1775; for left button press.
1776;
1777 cmp flag_arrowkeys,FALSE ; Arrow keys on?
1778 je short @@test_editor_exit ; No, then get out of here fast.
1779@@test_editor:
1780 mov al,flag_editor
1781 cmp al,1 ; Using a method suitable for emacs/vi?
1782 je short @@do_emacs_vi
1783 cmp al,2 ; Using a method suitable for matrix editor?
1784 je short @@do_matrix ; Do matrix method
1785 cmp al,3 ; Method for X10/xterm?
1786 jne short @@kill_allflag
1787 call DoXtermButtons
1788@@test_editor_exit:
1789 jmp short @@kill_eventflag
1790;
1791@@do_emacs_vi:
1792 mov al,row_present
1793 cmp row_target,al
1794 je short @@downarrow ; row_target == row_present
1795@@arrow_loop:
1796 cmp col_present,0
1797 je short @@downarrow ; col_present == 0
1798 call LeftArrow
1799 jnz short @@exit ; it failed, keybuffer full
1800 dec col_present ; move one left
1801 jmp short @@arrow_loop
1802;
1803@@do_matrix:
1804@@downarrow:
1805 mov al,row_present
1806 cmp row_target,al
1807 je short @@rightarrow ;row_target == row_present
1808 jl short @@uparrow ;row_target < row_present
1809;
1810; row_target > row_present
1811;
1812 call DownArrow
1813 jnz short @@exit ; failed, keybuffer full
1814 inc row_present ; move one row down
1815 jmp short @@downarrow
1816;
1817; row_target < row_present
1818;
1819@@uparrow: ;row_target < row_present
1820 call UpArrow
1821 jnz short @@exit ; failed, keybuffer full
1822 dec row_present ; move one up
1823 jmp short @@downarrow
1824@@rightarrow:
1825 mov al,col_present
1826 cmp col_target,al
1827 je short @@kill_allflag ; col_target == col_present
1828 jl short @@leftarrow ; col_target < col_present
1829;
1830; col_target > col_present
1831;
1832 call RightArrow
1833 jnz short @@exit ; failed, keybuffer full
1834 inc col_present ; move one right
1835 jmp short @@rightarrow
1836;
1837; col_target < col_present
1838;
1839@@leftarrow:
1840 call LeftArrow
1841 jnz short @@exit ; failed, keybuffer full
1842 dec col_present ; move one left
1843 jmp short @@rightarrow
1844@@kill_allflag:
1845 and flag_doButtons,FlagButtonsOFF ; Leave FlagButtonCR on
1846@@kill_eventflag:
1847 and flag_event,(not FlagCURSOR) ; Cursor bits reset, nothing to do.
1848@@exit:
1849 test flag_doButtons,FlagButtonCR
1850 jz short @@@exit
1851 call StuffCR ; stuff CR into keybuffer
1852 jnz short @@@exit ; keybuffer full, failed
1853 and flag_doButtons,(not FlagButtonCR)
1854@@@exit:
1855 ret
1856StuffArrows endp
1857;
1858; Set cursor position. Later, the keyboard buffer is stuffed by "stuff2keybuffer".
1859; Uses: AX
1860set_cursor proc
1861 PUSHR <bx,ds>
1862 call GetMousePosition ;al=row, ah=col
1863 mov col_target,ah
1864 mov row_target,al
1865 ; Get current text cursor position from BIOS variable
1866 mov ds,biosSEG
1867 xor ah,ah
1868 mov al,byte ptr [ds:62h] ;Get current video page number
1869 add al,al ; AL=2*AL
1870 add al,50h ; 50h=cursor position bios data (8 16-bit words)
1871 mov bx,ax ; BX=offset in segment 40h
1872 mov ax,[ds:bx] ;Get cursor position for current page
1873 mov row_present,ah
1874 mov col_present,al
1875 xor bx,bx
1876 mov lasttime,bx
1877 mov lasttime+2,bx ; shut off click timing
1878@@exit:
1879 POPR <ds,bx> ; PUSHR <bx,ds>
1880 or flag_event,FlagCURSOR
1881 ret
1882set_cursor endp
1883
1884endif ;end ENABLECURSOR ;=========Cursor Key code ==========;
1885
1886; Paste buffer for copied screen characters,
1887; Can overwrite initialization code.
1888
1889guardbyte db 0 ; Guard byte for backward search in the paste buffer
1890pastebuf equ $
1891
1892;; Begin non-resident code. This code is transient, used during install.
1893
1894DE_INSTALL equ 2 ; See option /U, procedure "get_opt" below.
1895REACTIVATE equ 3 ; See option /R
1896if ENABLEPASTE
1897APPENDPASTE equ 4 ; See option /F=X
1898SHOWXTCLASS equ 5 ; See option /D
1899SETXTCLASS equ 6 ; See option /D
1900SETTMP equ 7 ; See option /F:X
1901endif ;ENABLEPASTE
1902
1903NOT_INSTALLED equ 40h ; FLAG for driver not installed.
1904ALL_OK equ 41h ; FLAG for all go.
1905WRO_VEC equ 42h ; FLAG for wrong vector detected.
1906
1907 TESTCPU macro
1908; Test for 80188 cpu or later. See startup code. Not used for XT.
1909if not XT
1910 mov cl,33 ; Test for 80188 or successor
1911 shl ax,cl
1912 or cl,cl ; 188+ maximally shift 32 positions
1913 jnz @@TESTCPU_exit
1914 mov dx,offset wro_cpu_str
1915 call messageAlways
1916 jmp @@errexit
1917@@TESTCPU_exit:
1918endif ; not XT
1919 endm
1920
1921 TESTBIOS macro
1922if not XT
1923; Test for modern Bios with int 16,5. See startup code. Not used for XT.
1924; Equipment check for enhanced keyboard.
1925 mov es,biosSEG
1926 test byte ptr [es:96h],10000b ; enhanced keyboard installed ?
1927 jz @@errexit
1928endif ; not XT
1929 endm
1930
1931; Local variables used to parse command line. These get wiped out by
1932; the paste buffer, which writes over this area.
1933;
1934quiet_flag db FALSE ; TRUE to display everything, FALSE defeats
1935copying_flag db FALSE ; TRUE to display copying info
1936counter_Xoption db 0 ; Counter for number of /M and /X options.
1937how_to_flag db FALSE ; TRUE if to display only How-To string
1938ExecExit_flag db FALSE ; TRUE if /N on command line
1939settmpname_flag db FALSE ; TRUE if changing name c:\tmp\xpcm####.tmp
1940
1941; change interrupts and install mouse handler
1942;
1943; GET OPTIONS. Returns special options in ah.
1944;
1945get_opt proc
1946 mov si,80h ; si => command line parameters
1947 seges
1948 lodsb ; count
1949 mov bh,0
1950 mov bl,al
1951 mov es:[si+bx],bh ; 0
1952 or al,al
1953 jnz @@findslash
1954@@@parm_done:
1955 jmp @@parm_done ; Exit ah == 1
1956@@findslash:
1957 seges
1958 lodsb ; Using register CX!
1959 or al,al
1960 jz @@@parm_done ; Exit ah==1
1961 cmp al," "
1962 jz short @@findslash
1963 cmp al,"/"
1964 jz short @@good_sep
1965 cmp al,"-"
1966 jz short @@good_sep
1967@@@parm_err:
1968 jmp @@parm_err
1969@@good_sep:
1970; Valid options to return in register ah:
1971; DE_INSTALL, REACTIVATE, APPENDPASTE, SHOWXTCLASS, SETXTCLASS
1972; SETTMP
1973@@loop: ; Added some documentation of steps
1974 seges ; on 1-Nov-1994
1975 lodsb
1976@@HELP_setup:
1977 cmp al,'?' ; Got /? or ? on command line
1978 jz short @@@parm_err
1979
1980 and al,not ('a'-'A') ; toupper
1981
1982 cmp al,'H' ; Got /H on command line
1983 jnz @@HELP_setup_exit
1984 mov how_to_flag,TRUE
1985 jz short @@@parm_err
1986@@HELP_setup_exit:
1987@@U_setup:
1988 cmp al,'U' ; Got /U for uninstall
1989 jnz short @@U_setup_exit
1990 mov ah,DE_INSTALL
1991 jmp @@exit
1992@@U_setup_exit:
1993@@R_setup:
1994 cmp al,'R' ; Got /R for reactivate driver
1995 jnz short @@R_setup_exit
1996 mov ah,REACTIVATE
1997 jmp @@exit
1998@@R_setup_exit:
1999if ENABLEPASTE
2000@@D_setup:
2001 cmp al,'D' ; Got /d for show or set Xterm Classes
2002 jnz short @@D_setup_exit
2003 cmp byte ptr es:[si],'='
2004 je @@D_setup1
2005 mov ah,SHOWXTCLASS
2006 call showXtermClasses
2007 jmp @@exit
2008@@D_setup1:
2009 inc si ; Point to file name
2010 mov di,offset fileappend
2011@@D_nameloop:
2012 mov al,es:[si]
2013 mov byte ptr cs:[di],al
2014 inc si
2015 inc di
2016 cmp al,0
2017 je @@D_nameloop_exit
2018 cmp al,' '
2019 jne @@D_nameloop
2020@@D_nameloop_exit:
2021 mov byte ptr cs:[di],0
2022 call setXtermClasses
2023 mov ah,SETXTCLASS
2024@@D_setup2:
2025 jmp @@findslash
2026@@D_setup_exit:
2027@@F_setup:
2028 cmp al,'F' ; Got /f for append active paste buffer to file
2029 jnz short @@F_setup_exit
2030 mov ah,byte ptr es:[si]
2031 cmp ah,'=' ;Set name for append now
2032 je short @@F_setup_getname
2033 cmp ah,':' ;Set default name hot button append
2034 jne short @@F_setup_exit
2035@@F_setup_getname:
2036 inc si ; Point to file name
2037 mov di,offset fileappend; 128 byte maximum
2038 mov settmpname_flag,ah
2039 xor ah,ah ;counter
2040@@nameloop:
2041 mov al,es:[si]
2042 mov byte ptr cs:[di],al
2043 cmp ah,128
2044 jb @@nameloop_go
2045 mov dx,offset MSGfilesize
2046 call messageAlways
2047 jmp @@parm_err
2048@@nameloop_go:
2049 cmp al,' '
2050 je @@nameloop_exit
2051 cmp al,0
2052 jz @@nameloop_exit
2053 inc si
2054 inc di
2055 inc ah
2056 jmp short @@nameloop
2057@@nameloop_exit:
2058 mov byte ptr cs:[di],0
2059 cmp settmpname_flag,':'
2060 mov settmpname_flag,TRUE ;We were here!
2061 je @@F_setup_setname
2062; Append the file now and quit.
2063 call appendfile
2064 mov ah,APPENDPASTE ; Get out without install
2065 jmp @@exit
2066; Change the name c:\tmp\xpcm####.tmp
2067@@F_setup_setname:
2068if ENABLEFILEAPPEND
2069 mov al,ah ;send it the string length
2070 call ChangeTmpName
2071 jc short @@parm_err
2072endif ;ENABLEFILEAPPEND
2073 jmp @@findslash
2074@@F_setup_exit:
2075endif ;ENABLEPASTE
2076;
2077; Loop on the other command line options
2078;
2079@@N_setup:
2080 cmp al,'N' ; Got /N for mouse handler re-install
2081 jnz short @@N_setup_exit
2082 mov ExecExit_flag,TRUE
2083 call parse_num ; 0=defeat, 1=on exec, 2=on exit, 3=both
2084 mov flag_reinstall_exec,FALSE
2085 mov flag_reinstall_exit,FALSE
2086 test ax,1
2087 jz @@N_1
2088 mov flag_reinstall_exec,TRUE
2089@@N_1:
2090 test ax,2
2091 jz @@N_2
2092 mov flag_reinstall_exit,TRUE
2093@@N_2:
2094 jmp @@findslash
2095@@N_setup_exit:
2096@@S_setup:
2097 cmp al,'S' ; Got /S for button swap order
2098 jnz short @@S_setup_exit
2099 call parse_num ; Get number nnn after '/S'
2100 call setbuttonswap
2101 jmp @@findslash
2102@@S_setup_exit:
2103@@C_setup:
2104 cmp al,'C' ; Got /C, display copying info
2105 jne short @@C_setup_exit
2106 mov copying_flag,1
2107 jmp @@findslash
2108@@C_setup_exit:
2109@@Q_setup:
2110 cmp al,'Q' ; Got /Q for quiet startup mode
2111 jnz short @@Q_setup_exit
2112 mov cs:quiet_flag,TRUE
2113 jmp @@findslash
2114@@Q_setup_exit:
2115 jmp short @@parm_done_exit
2116
2117@@parm_err:
2118 mov ah,FALSE
2119 jmp short @@exit
2120@@parm_done:
2121 mov ah,TRUE
2122 jmp short @@exit
2123
2124@@parm_done_exit:
2125
2126if ENABLEPASTE
2127@@P_setup:
2128 cmp al,'P' ; Got /P, defeat pastebuffer
2129 jne short @@P_setup_exit
2130 mov flag_pastebuffer,FALSE
2131 jmp @@findslash
2132@@P_setup_exit:
2133@@M_setup:
2134 cmp al,'M' ; Got /M for monochrome video mode
2135 jnz short @@M_setup_exit
2136 mov al,119 ; XOR byte mask for monochrome == /X119
2137 jmp short @@X_setup1
2138@@M_setup_exit:
2139@@X_setup:
2140 cmp al,'X' ; Got /X for XOR mask ddd
2141 jnz short @@X_setup_exit
2142 call parse_num ; Get number nnn after '/X'
2143 cmp ax,255 ; Value ddd==119 for monochrome
2144 ja @@parm_err
2145 cmp ax,0
2146 jb short @@parm_err
2147@@X_setup1:
2148 mov xor_mask,al
2149 inc counter_Xoption
2150 jmp @@findslash
2151@@X_setup_exit:
2152@@B_setup:
2153 cmp al,'B' ; Got /B for new buffer size in bytes
2154 jnz short @@B_setup1_exit
2155 call parse_num ; Get number nnn after '/B'
2156 cmp ax,BUFFERLEN ; Don't let it get bigger than BUFFERLEN
2157 ja @@parm_err ; But ZERO is OK!
2158 add ax,15 ; Round up to next paragraph
2159 mov cl,4
2160 shr ax,cl
2161 mov cl,4
2162 shl ax,cl ; ax == byte count for buffer size
2163 mov cs:BUFLEN,ax
2164 jmp @@findslash
2165@@B_setup1_exit:
2166endif ;ENABLEPASTE
2167
2168if ENABLECURSOR ;=========Cursor Key code ==========;
2169@@K_setup:
2170 cmp al,'K' ; Got /K, defeat arrow keys
2171 jne short @@K_setup_exit
2172 mov flag_arrowkeys,FALSE
2173 jmp @@findslash
2174@@K_setup_exit:
2175@@A_setup:
2176 cmp al,'A' ; Got /A, set emacs, matrix, xterm modes
2177 jnz short @@A_setup_exit
2178 call parse_num ; Get number nnn after '/A'
2179 cmp ax,MAX_of_A ; Valid options are 1,2,...,(MAX_of_A)
2180 ja short @@A_setup1
2181 cmp ax,1
2182 jb short @@A_setup1
2183 mov flag_editor,al
2184@@A_setup1:
2185 jmp @@findslash
2186@@A_setup_exit:
2187endif ;end ENABLECURSOR ;=========Cursor Key code ==========;
2188 jmp @@findslash
2189@@exit:
2190 ret
2191get_opt endp
2192
2193SwapButtonTable dw 123 ; 123 ==> 123
2194 db 1,3,5 ; shift factors for bit pattern
2195 dw 132
2196 db 1,5,3
2197 dw 213 ; Example: Button order 123 ==> 312
2198 db 3,1,5 ; Extra bytes are shift factors into
2199 dw 231 ; new position, eg, 00000110 are bits for
2200 db 3,5,1 ; for button 1, and we shift it to
2201 dw 312 ; 00000011 to normalize, then shift
2202 db 5,1,3 ; by 5 left to make it into button3
2203 dw 321 ; bits of 01100000
2204 db 5,3,1
2205 dw 0
2206 db 0,0,0
2207;
2208; Entry: ax == permutation of 123
2209; Table determines allowed values (SwapButtonTable).
2210; Exit: Updated variables button_1fix, button_2fix, button_3fix
2211;
2212setbuttonswap proc
2213 push si
2214 push bx
2215 mov si,offset SwapButtonTable
2216@@S_loop:
2217 cmp ax,word ptr [si]
2218 jne @@S_loopexit
2219 inc si
2220 inc si
2221 mov bl,byte ptr [si]
2222 mov button_1fix,bl
2223 inc si
2224 mov bl,byte ptr [si]
2225 mov button_2fix,bl
2226 inc si
2227 mov bl,byte ptr [si]
2228 mov button_3fix,bl
2229 jmp short @@S_exit
2230@@S_loopexit:
2231 add si,5
2232 cmp word ptr [si],0
2233 jnz @@S_loop
2234 jmp short @@S_exit1
2235@@S_exit:
2236 mov flag_swapbuttons,TRUE
2237@@S_exit1:
2238 pop bx
2239 pop si
2240 ret
2241setbuttonswap endp
2242
2243
2244parse_num proc
2245 push bx
2246 mov bx,10
2247 mov ax,0
2248 mov dh,0
2249@@addloop:
2250 seges
2251 mov dl,[si]
2252 or dl,dl
2253 jz short @@done
2254 sub dl,'0'
2255 jc short @@done
2256 cmp dl,9
2257 ja short @@done
2258 inc si
2259 push dx
2260 mul bx
2261 pop dx
2262 add ax,dx
2263 jmp short @@addloop
2264@@done:
2265 pop bx
2266 ret
2267parse_num endp
2268
2269if ENABLEPASTE
2270; These routines set and display the Xterm character classes.
2271; by GBG January 1997
2272
2273stringone db 0,0
2274notopened db 'Cannot open file','$'
2275filehandle dw 0
2276pasteseg dw 0
2277DisplayXtermClasses db 'Xterm Classes',13,10
2278fileappend db 128 dup (?)
2279SIZEfileappend equ $-fileappend
2280 db '$'
2281hundredsplace db 0
2282tensplace db 0
2283onesplace db 0
2284
2285
2286; Entry: al=byte to convert
2287; Exit: Writes answers to hundredsplace, tensplace, onesplace.
2288; Uses ax,bx,dx.
2289convertBase10 proc near
2290 mov ah,0 ;byte data
2291 mov bx,100
2292 push ax
2293 cwd
2294 idiv bx
2295 mov hundredsplace,al
2296 mov dx,100
2297 mul dx
2298 mov bx,ax
2299 pop ax
2300 sub ax,bx
2301 push ax
2302 mov bx,10
2303 cwd
2304 idiv bx
2305 mov tensplace,al
2306 mov dx,10
2307 mul dx
2308 mov bx,ax
2309 pop ax
2310 sub ax,bx
2311 mov onesplace,al
2312 ret
2313convertBase10 endp
2314
2315; Entry: ds:di points to place to write the string
2316; al=byte to convert
2317; Exit: di updated. Uses ax,di
2318byteToString10 proc near
2319
2320 push bx
2321 push dx
2322 call convertBase10
2323;; put digits into string
2324 mov al,hundredsplace
2325 cmp al,0
2326 jz @@tens
2327 add al,'0' ;100's digit
2328 mov byte ptr ds:[di],al
2329 inc di
2330@@tens:
2331 mov al,tensplace
2332 cmp al,0
2333 jnz @@tens_ok
2334 cmp hundredsplace,0
2335 jz @@ones
2336@@tens_ok:
2337 add al,'0' ;10's digit
2338 mov byte ptr ds:[di],al
2339 inc di
2340@@ones:
2341 mov al,onesplace
2342 add al,'0' ;1's digit
2343 mov byte ptr ds:[di],al
2344 inc di
2345 pop dx
2346 pop bx
2347 ret
2348byteToString10 endp
2349
2350showXtermClasses proc near
2351 XPUSHA
2352 call inst_tst ; exits with es:bx == far address of pastebuffer
2353 mov dx,es
2354 mov pasteseg,dx ; save segment
2355 cmp al,NOT_INSTALLED
2356 jne @@getclasses
2357 push cs
2358 pop es
2359@@getclasses:
2360 mov bx,offset unix_pairs
2361 mov al,byte ptr es:[bx]
2362 mov unix_pairs,al
2363
2364 mov di,offset fileappend ;place to put char classes
2365 mov bx,offset unix_ranges ;source data in other segment
2366
2367@@loop:
2368 mov al,unix_pairs
2369 cmp al,0
2370 jz @@loop_exit
2371 dec unix_pairs
2372 mov al,byte ptr es:[bx] ;first of pair
2373 inc bx
2374 call byteToString10
2375 mov byte ptr ds:[di],'-'
2376 inc di
2377 mov al,byte ptr es:[bx] ;second of pair
2378 inc bx
2379 call byteToString10
2380 mov byte ptr ds:[di],':'
2381 inc di
2382 jmp short @@loop
2383@@loop_exit:
2384 mov byte ptr ds:[di],13
2385 inc di
2386 mov byte ptr ds:[di],10
2387 inc di
2388 mov byte ptr ds:[di],'$'
2389 mov dx,offset DisplayXtermClasses
2390 call messageAlways
2391@@done:
2392 XPOPA
2393 ret
2394showXtermClasses endp
2395
2396get_num proc
2397 push bx
2398 mov bx,10
2399 mov ax,0
2400 mov dh,0
2401@@addloop:
2402 mov dl,byte ptr cs:[si]
2403 or dl,dl
2404 jz short @@done
2405 sub dl,'0'
2406 jc short @@done
2407 cmp dl,9
2408 ja short @@done
2409 inc si
2410 push dx
2411 mul bx
2412 pop dx
2413 add ax,dx
2414 jmp short @@addloop
2415@@done:
2416 pop bx
2417 ret
2418get_num endp
2419
2420
2421; Entry: fileappend == ASCIIZ file name
2422setXtermClasses proc near
2423 XPUSHA
2424 call inst_tst ; exits with es:bx == far address of pastebuffer
2425 mov dx,es
2426 mov pasteseg,dx ; save segment
2427 cmp al,NOT_INSTALLED
2428 jne @@setclasses
2429 jmp @@exit
2430@@setclasses:
2431; Open file. Abort if missing.
2432 mov al,0 ;read only
2433 mov ah,3dh ;open file
2434 mov dx,offset fileappend ;file name 0 terminated
2435 int 21h
2436 mov filehandle,ax
2437 jnc @@goodopen
2438 mov dx,offset notopened
2439 call messageAlways
2440 jmp short @@exit ;no such file, just quit
2441@@goodopen:
2442 mov bx,filehandle
2443 mov cx,SIZEfileappend
2444 mov dx,offset fileappend ; String location for read
2445 mov ah,3Fh
2446 int 21h ;read file into buffer loc
2447 mov bx,ax
2448 mov ax,offset fileappend
2449 add bx,ax ;end of data
2450 mov byte ptr ds:[bx],0 ;mark end of data with NULL
2451 mov ah,3eh
2452 mov bx,filehandle
2453 int 21h ;close file handle
2454 mov si,offset fileappend
2455 mov unix_pairs,0
2456 mov bx,offset unix_ranges
2457 mov es,pasteseg ;where to put the answers
2458@@parsestring: ;decode string
2459 call get_num ;ans in ax
2460 cmp ax,0
2461 je @@parsestring_exit
2462 mov byte ptr es:[bx],al
2463 inc bx
2464 cmp byte ptr cs:[si],0
2465 je @@parsestring_exit
2466 inc si
2467 call get_num ;ans in ax
2468 cmp ax,0
2469 je @@parsestring_exit
2470 mov byte ptr es:[bx],al
2471 inc bx
2472 inc unix_pairs
2473 mov al,unix_pairs
2474 cmp al,MAX_unix_pairs
2475 je @@parsestring_exit
2476 cmp byte ptr cs:[si],0 ;expect colon (:) or null (\0).
2477 je @@parsestring_exit ;was a null
2478 inc si ;was a colon, maybe
2479 jmp short @@parsestring
2480@@parsestring_exit:
2481 mov bx,offset unix_pairs
2482 mov al,unix_pairs
2483 mov byte ptr es:[bx],al
2484@@exit:
2485 XPOPA
2486 ret
2487setXtermClasses endp
2488endif ;ENABLEPASTE
2489
2490if ENABLEPASTE
2491; These routines append active paste buffer to a file.
2492; by GBG January 1997
2493
2494; Entry: cs:si=ASCIIZ path and file name
2495; Exit: bx=file handle, ax=0 for bad open
2496; Uses: ax,bx
2497openfile proc near
2498; Open file. Create it if missing.
2499 push dx
2500 push ds
2501 push cs
2502 pop ds
2503 mov al,2 ;read and write
2504 mov ah,3dh ;open file
2505 mov dx,si ;file name 0 terminated
2506 int 21h
2507 mov bx,ax ;bx=file handle
2508 mov ax,1 ;ax==1 means good open
2509 jnc @@goodopen
2510 mov cx,0 ;file attributes
2511 mov dx,si ;full path name to create in ds:dx
2512 mov ah,03ch ;create file
2513 int 21h
2514 mov bx,ax ;return bx=handle
2515 mov ax,1
2516 jnc @@goodopen
2517 mov ax,0 ;ax==0 means bad open
2518@@goodopen:
2519 pop ds
2520 pop dx
2521 ret
2522openfile endp
2523
2524; Entry: bx=file handle
2525; Exit: seek end of file, uses ax
2526seekend proc near
2527 push bx
2528 push cx
2529 push dx
2530 push es
2531; mov bx,file handle
2532 mov cx,0 ;cx=high word
2533 mov dx,0 ;dx=low word of seek amount
2534 mov al,2 ;seek end of file
2535 mov ah,42h ;set file pointer
2536 int 21h
2537 pop es
2538 pop dx
2539 pop cx
2540 pop bx
2541 ret
2542seekend endp
2543
2544; Entry: fileappend==file name
2545; Exit: paste buffer appended to file.
2546; Uses: ax, es, bx, si
2547appendfile proc
2548 push ds
2549 call inst_tst ; exits with es:bx == far address of pastebuffer
2550 mov pasteseg,es ;save segment
2551 cmp al,NOT_INSTALLED
2552 je @@done
2553; Store into local variables the offsets into the active pastebuffer.
2554@@getlocals:
2555 push cs
2556 pop ds
2557 mov nextpair,offset pastebuf
2558 mov bx,offset lastpair
2559 mov ax,word ptr es:[bx]
2560 mov lastpair,ax
2561
2562; Mark data in this program to keep GetPasteBuf under control.
2563 mov flag_CtrlRight,TRUE ; append CR
2564; mov counter_blanks,0
2565; Open the file in cs:si
2566 mov si,offset fileappend ; file name to open
2567 call openfile ; bx = file handle on success
2568 mov filehandle,bx ; save handle
2569 cmp ax,0 ; 0==failure to open file
2570 jne @@seek
2571 mov dx,offset notopened
2572 call messageAlways
2573 jmp short @@done
2574; Seek to the end of the file
2575@@seek:
2576 mov bx,filehandle
2577 call seekend
2578 mov es,pasteseg ; Segment of active pastebuffer
2579 mov si,offset stringone ; String location for write
2580@@loop:
2581 call GetPasteBuf ; AL == char found in pastebuffer
2582 jc short @@@exit ; nothing left in pastebuffer
2583@@@loop:
2584 mov byte ptr ds:[si],al
2585 mov bx,filehandle
2586 mov cx,1
2587 mov dx,offset stringone ; String location for write
2588 mov ah,40h
2589 int 21h ;write string to file
2590 cmp byte ptr ds:[si],13 ;was it a CR?
2591 jne @@loop
2592 mov al,10 ;add linefeed
2593 jmp short @@@loop
2594@@@exit:
2595 cmp byte ptr ds:[si],10 ;was it a LF?
2596 mov al,13
2597 jne @@@loop ;then add extra crlf
2598 mov ah,3eh
2599 mov bx,filehandle
2600 int 21h ;close file handle
2601@@done:
2602 pop ds
2603 ret
2604appendfile endp
2605
2606
2607if ENABLEFILEAPPEND
2608MSGfilesize db '/F:X error: Name X has a 20 character maximum.'
2609else
2610MSGfilesize db '/F=X error.'
2611endif ;ENABLEFILEAPPEND
2612 db 13,10
2613 db '/F=X allows name X with 128 character maximum.'
2614 db 13,10,'$'
2615
2616if ENABLEFILEAPPEND
2617; Entry: al == string length
2618; Uses: AX, FLAGS
2619ChangeTmpName proc
2620 push es
2621 push ds
2622 push si
2623 push di
2624 cmp al,21
2625 jb @@change
2626 mov dx,offset MSGfilesize
2627 call messageAlways
2628 stc
2629 jmp short @@exit
2630@@change:
2631 call inst_tst ; exits with es:bx == far address of pastebuffer
2632 mov di,offset filen
2633 mov si,offset fileappend
2634 cmp al,NOT_INSTALLED
2635 push cs
2636 pop ds
2637 je @@loop
2638 push es
2639 pop ds
2640@@loop: ; Move file name
2641 mov al,byte ptr cs:[si] ; Copy string with
2642 mov byte ptr ds:[di],al ; null terminator
2643 or al,al
2644 jz @@loopexit
2645 inc si
2646 inc di
2647 jmp short @@loop
2648@@loopexit:
2649 clc
2650@@exit:
2651 pop di
2652 pop si
2653 pop ds
2654 pop es
2655 ret
2656ChangeTmpName endp
2657endif ;ENABLEFILEAPPEND
2658endif ;ENABLEPASTE
2659
2660; Entry: None
2661; Exit: al=ALL_OK, es:bx == pointer to pastebuf
2662; Else al==NOT_INSTALLED
2663; Uses: ax, es, bx; ah unchanged
2664inst_tst proc
2665 push cx
2666 push ax
2667 mov ax,MOUSE_FN ; test for installed
2668 int 16h
2669 cmp ax,MOUSE_FNDEC ; must pass two tests, ah changed
2670 jnz short @@failed
2671 cmp cx,IDENTCODE ; and proper code in cx; see new_16h
2672 je @@worked
2673@@failed:
2674 mov al,NOT_INSTALLED
2675 jmp short @@exit
2676@@worked:
2677 mov al,ALL_OK ; es:bx points to pastebuf
2678@@exit:
2679 pop cx
2680 mov ah,ch
2681 pop cx
2682 ret
2683inst_tst endp
2684
2685cmp_fptr proc ; cmp ax:bx and cx:dx
2686 XPUSHA
2687 mov si,0
2688 mov di,0
2689
2690; si:ax *= 16
2691 rept 4
2692 shl ax,1
2693 rcl si,1
2694 endm
2695 add ax,bx
2696 adc si,0
2697
2698; di:cx *= 16
2699 rept 4
2700 shl cx,1
2701 rcl di,1
2702 endm
2703 add cx,dx
2704 adc di,0
2705
2706 cmp cx,ax
2707 jnz short @@exit
2708 cmp si,di
2709@@exit:
2710 XPOPA
2711 ret
2712cmp_fptr endp
2713
2714 ms_hnd_ptr dw 0,0
2715
2716re_activate proc
2717LOCAL hndadr:DWORD = AUTO_SIZE
2718 push bp
2719 mov bp,sp
2720 sub sp,AUTO_SIZE
2721 PUSHR <ds,es>
2722 call inst_tst ; es:bx == far address of pastebuffer
2723 cmp al,NOT_INSTALLED
2724 je short @@exit
2725
2726 push bx ; bx == & InstallMouseHandler
2727 push es
2728 sub bx,pastebuf-InstallMouseHandler
2729 mov word ptr hndadr,bx
2730 mov bx,es
2731 mov word ptr hndadr+2,bx
2732 call dword ptr [hndadr] ; call InstallMouseHandler
2733 pop es
2734 pop bx
2735 cmp ExecExit_flag,FALSE ; Process /N options?
2736 je @@exit
2737 push bx
2738 sub bx,pastebuf-flag_reinstall_exec
2739 mov al,flag_reinstall_exec
2740 mov byte ptr es:[bx],al
2741 pop bx
2742 sub bx,pastebuf-flag_reinstall_exit
2743 mov al,flag_reinstall_exit
2744 mov byte ptr es:[bx],al
2745 mov al,ALL_OK
2746
2747@@exit:
2748 POPR <es,ds>
2749 add sp,AUTO_SIZE
2750 pop bp
2751 ret
2752re_activate endp
2753
2754RSTVEC macro vec,old_vec_dist
2755 mov bx,pcmoffs
2756 sub bx,old_vec_dist
2757 lds dx,[es:bx]
2758 mov ax,(25h shl 8) + vec ; set vector
2759 int 21h
2760endm
2761
2762CMPVEC macro vec,new_vec_dist
2763 mov ax,(35h shl 8) + vec ; get vector
2764 int 21h ; to es:bx
2765
2766 mov ax,es
2767 mov cx,pcmseg
2768 mov dx,pcmoffs
2769 sub dx,new_vec_dist
2770 call cmp_fptr ; cmp ax:bx and cx:dx
2771 jnz @@wrong_vec
2772endm
2773
2774; Do soft reset on Mouse driver
2775
2776SoftMouseReset proc
2777; Software Reset, to put handler into defined state
2778 mov ax,21h ;soft reset
2779;;; mov ax,00h ;hard reset
2780 int 33h
2781 ret
2782SoftMouseReset endp
2783
2784de_inst proc
2785LOCAL pcmoffs,pcmseg:WORD,tckflg:BYTE = AUTO_SIZE
2786 push bp
2787 mov bp,sp
2788 sub sp,AUTO_SIZE
2789 PUSHR <ds,es>
2790 call inst_tst
2791 cmp al,ALL_OK ; Then es:bx == pastebuf address
2792 je short @@cont_de_inst
2793 jmp short @@goexit ; Then al == NOT_INSTALLED
2794@@cont_de_inst:
2795; now test for all patched vectors, if they point to xpcmouse
2796; We have now es:bx == pastebuf of in-memory copy of xpcmouse
2797;
2798 mov pcmoffs,bx ; Offset to pastebuf in segment es
2799 mov ax,es
2800 mov pcmseg,ax ; Segment of installed xpc-mouse
2801
2802; We always patch 21h, 16h, 10h, 08h.
2803
2804 CMPVEC 21h,pastebuf-new_21h ; jump to @@wrong_vec on error
2805 CMPVEC 16h,pastebuf-new_16h ; jump to @@wrong_vec on error
2806 CMPVEC 10h,pastebuf-new_10h ; jump to @@wrong_vec on error
2807 CMPVEC 08h,pastebuf-new_08h ; jump to @@wrong_vec on error
2808if ENABLEFILEAPPEND
2809 CMPVEC 13h,pastebuf-new_13h ; jump to @@wrong_vec on error
2810endif ;ENABLEFILEAPPEND
2811
2812 jmp short @@de_inst
2813
2814@@wrong_vec:
2815 mov al,WRO_VEC
2816@@goexit:
2817 jmp short @@exit
2818
2819@@de_inst:
2820
2821 call SoftMouseReset ; reset mouse driver & interrupt handler
2822 ; don't want surprises (1998)
2823if ENABLEFILEAPPEND
2824 RSTVEC 13h,pastebuf-old_13h ; Timer off first
2825endif ;ENABLEFILEAPPEND
2826 RSTVEC 21h,pastebuf-old_21h
2827 RSTVEC 16h,pastebuf-old_16h
2828 RSTVEC 10h,pastebuf-old_10h
2829 RSTVEC 08h,pastebuf-old_08h
2830
2831; reset driver is done at end of last exec, too
2832 call SoftMouseReset ; in case timer re-installed handler
2833 mov es,pcmseg ; segment of installed xpc-mouse
2834 mov bx,pcmoffs ; offset into that segment
2835 sub bx,pastebuf-killed_flg ; get offset to killed_flg in "new_21h"
2836 mov byte ptr [es:bx],TRUE ; Prevent re-entry of "new_21h"
2837 mov bx,pcmoffs ; offset to pastebuf
2838 sub bx,pastebuf-XPC_pspadr ; offset to storage word
2839 mov es,[es:bx] ; Get psp address word
2840 mov ah,49h ; free memory
2841 int 21h
2842
2843 mov al,ALL_OK
2844 jmp short @@exit
2845
2846@@exit:
2847 POPR <es,ds>
2848 add sp,AUTO_SIZE
2849 pop bp
2850 ret
2851de_inst endp
2852
2853messages proc near
2854 push ax
2855 cmp cs:quiet_flag,TRUE
2856 jz short @@exit
2857 mov ah,9
2858 int 21h
2859@@exit:
2860 pop ax
2861 ret
2862messages endp
2863
2864messageAlways proc near
2865 push ax
2866 mov ah,9
2867 int 21h
2868 pop ax
2869 ret
2870messageAlways endp
2871
2872init proc
2873 mov ax,es
2874 mov cs:XPC_pspadr,ax ; Save a copy in resident code
2875 mov ax,cs
2876 mov ds,ax
2877 call get_opt
2878
2879; Output copying message and quit?
2880 cmp cs:copying_flag,FALSE
2881 jz short @@no_copying
2882 mov dx,offset copying
2883 jmp @@do_exit
2884
2885@@no_copying:
2886 mov dx,offset onsign
2887 call messages
2888
2889@@no_onsign:
2890 cmp cs:how_to_flag,FALSE
2891 jz short @@no_onsign1
2892 jmp @@do_how_to_exit
2893@@no_onsign1:
2894 cmp ah,TRUE
2895 jz short @@cont_inst
2896 cmp ah,FALSE
2897 mov dx,offset help_str
2898 jz @@do_exit
2899
2900if ENABLEPASTE
2901@@tst_showxtclass:
2902 cmp ah,SHOWXTCLASS
2903 jnz short @@tst_appendpaste
2904 jmp short @@do_exit_raw
2905@@tst_appendpaste:
2906 cmp ah,APPENDPASTE
2907 jnz short @@tst_reactivate
2908 mov dx,offset appendf_str
2909 jmp @@do_message_exit
2910endif ;ENABLEPASTE
2911
2912@@tst_reactivate:
2913 cmp ah,REACTIVATE
2914 jnz short @@tst_de_inst
2915@@do_reactivate:
2916 call re_activate
2917 cmp al,NOT_INSTALLED
2918 jz short @@not_yet1
2919 mov dx,offset re_inst_str
2920 jmp short @@do_exit
2921
2922@@tst_de_inst:
2923 cmp ah,DE_INSTALL
2924 jnz short @@cont_inst
2925 call de_inst
2926 cmp al,NOT_INSTALLED
2927@@not_yet1:
2928 mov dx,offset not_yet_str
2929 jz @@do_exit
2930 cmp al,ALL_OK
2931 mov dx,offset ok_de_inst ; Install validated
2932 jz @@do_exit
2933 mov dx,offset wro_de_inst ; Bad vectors or bad install
2934 jmp short @@do_exit
2935
2936@@cont_inst:
2937
2938 TESTCPU ; Test for 80188 cpu or later. See macro above.
2939; TESTBIOS ; Test for modern bios. See macro above.
2940 ; We don't use int 16 function 5 in 1997
2941
2942
2943; use function 21h (instead of 0) to ensure that new
2944; mouse driver is installed
2945
2946 mov ax,21h ; Test, if mouse driver installed
2947 int 33h
2948 inc ax ; installed => 0
2949 jz short @@mouse_there
2950 mov dx,offset nomouse_str
2951 call messageAlways
2952@@errexit:
2953 mov dx,offset noins_str
2954 call messageAlways
2955 jmp short @@do_exit_raw
2956@@do_exit:
2957if ENABLEPASTE
2958 cmp settmpname_flag,TRUE
2959 je @@do_exit_raw
2960endif ;ENABLEPASTE
2961 call messages
2962@@do_exit_raw:
2963 mov ax,4c01h ; errorlevel 1 == no mouse driver
2964 int 21h
2965
2966@@mouse_there:
2967 call inst_tst
2968 jnz short @@install
2969 cmp ExecExit_flag,FALSE ; Any /N requests?
2970 je @@mouse_there_exit
2971 jmp @@do_reactivate ; /N implies /R if already installed
2972@@mouse_there_exit:
2973
2974@@do_how_to_exit:
2975 mov dx,offset help_switches
2976 call messages
2977
2978 cmp cs:how_to_flag,FALSE
2979 je @@exit02
2980
2981 mov dx,offset how_to
2982
2983@@do_message_exit:
2984 call messages
2985
2986 mov ax,4c03h ; errorlevel 3 == message exit
2987 int 21h
2988
2989@@exit02:
2990 mov dx,offset msgstr
2991 call messages
2992@@exit02_nomsg:
2993 mov ax,4c02h ; errorlevel 2 == re-installed
2994 int 21h
2995
2996@@install:
2997
2998; Set buffer length variable
2999
3000 mov ax,cs:BUFLEN ; Get ending address of the
3001 add ax,offset pastebuf-1 ; Paste Buffer
3002 mov cs:EndOfBuffer,ax ; and save it
3003
3004if ENABLEPASTE
3005; See if the video mode is appropriate for the /Xddd mask
3006 cmp cs:counter_Xoption,0 ; Over-ride on command line?
3007 jnz short @@video_OK
3008 ; Option /M for monochrome Video mode (/M==/X119).
3009 push ds
3010 mov ds,biosSEG
3011 cmp byte ptr [ds:49h],7 ; BIOS current video mode mono?
3012 pop ds
3013 jnz short @@video_OK
3014 mov xor_mask,119 ; Use /X119 for mono
3015@@video_OK:
3016endif ;ENABLEPASTE
3017
3018; free environment
3019; Space managed by DOS can be re-used.
3020;
3021 mov es,cs:XPC_pspadr
3022 mov es,[es:2ch] ; segment address of environment
3023 mov ah,49h ; free memory
3024 int 21h
3025
3026; save order: 08,10,13,16,21
3027
3028 mov ax,3508h
3029 int 21h ; get vector
3030 mov word ptr old_08h,bx
3031 mov word ptr cs:[old_08h+2],es
3032
3033 mov ax,3510h
3034 int 21h
3035 mov word ptr cs:[old_10h],bx
3036 mov word ptr cs:[old_10h+2],es
3037
3038if ENABLEFILEAPPEND
3039 mov ax,3513h
3040 int 21h ; get vector
3041 mov word ptr old_13h,bx
3042 mov word ptr cs:[old_13h+2],es
3043endif ;ENABLEFILEAPPEND
3044
3045 mov ax,3516h
3046 int 21h ; get vector
3047 mov word ptr old_16h,bx
3048 mov word ptr cs:[old_16h+2],es
3049
3050 mov ax,3521h
3051 int 21h
3052 mov word ptr cs:[old_21h],bx
3053 mov word ptr cs:[old_21h+2],es
3054
3055; set order: 08,10,13,16,21
3056
3057 mov dx,offset new_08h
3058 mov ax,2508h ; set vect
3059 int 21h
3060
3061 mov dx,offset new_10h
3062 mov ax,2510h ; set vect
3063 int 21h
3064
3065if ENABLEFILEAPPEND
3066 mov dx,offset new_13h
3067 mov ax,2513h ; set vect
3068 int 21h
3069endif ;ENABLEFILEAPPEND
3070
3071 mov dx,offset new_16h
3072 mov ax,2516h ; set vect
3073 int 21h
3074
3075 mov dx,offset new_21h
3076 mov ax,2521h ; set vect
3077 int 21h
3078
3079 call SoftMouseReset
3080 call InstallMouseHandler
3081
3082 mov dx,offset how_to
3083 call messages
3084 mov dx,offset worked
3085 call messages
3086
3087@@terminate:
3088 ; Compute how many paragraphs are to be resident.
3089 ; This count adds is code length plus paste buffer length. The
3090 ; paste buffer has by design a maximum length of BUFFERLEN bytes.
3091 ;
3092 mov dx,cs:BUFLEN ; Desired buffer length
3093 add dx,offset pastebuf ; resident code len + BUFLEN
3094 add dx,15+256 ; Roundup + EXE header size
3095 shr dx,1 ; dx --> (end_mouse - begin_resident+15+256)/2
3096 shr dx,1 ; dx --> (end_mouse - begin_resident+15+256)/4
3097 shr dx,1 ; dx --> (end_mouse - begin_resident+15+256)/8
3098 shr dx,1 ; dx --> (end_mouse - begin_resident+15+256)/16
3099 mov ax,3100h
3100 int 21h ; terminate stay resident
3101
3102init endp
3103
3104copying:
3105 db 'Copyright (c) 1994-1998 Jürgen G. Weber and G.B. Gustafson',13,10
3106 db 'xPC-Mouse is free software, distributed under the terms of the',13,10
3107 db 'GNU General Public License. For details, see the file COPYING.',13,10
3108 db 10
3109 db 'Jürgen G. Weber',13,10
3110 db 'Wiesentalstraße 1',13,10
3111 db 'D-74523 Schwäbisch Hall',13,10
3112 db 'Germany',13,10
3113 db 'email: weberj@dia.informatik.uni-stuttgart.de',13,10
3114 db 10
3115 db 'Grant B. Gustafson',13,10
3116 db '113 JWB Math Dept Univ Utah',13,10
3117 db 'Salt Lake City, UT 84112 USA',13,10
3118 db 'email: gustafson@math.utah.edu',13,10
3119 db '$'
3120
3121if ENABLEPASTE and ENABLECURSOR
3122MOUSEPROG equ 'xPCmouse'
3123endif ;ENABLEPASTE and ENABLECURSOR
3124
3125if ENABLEPASTE and (not ENABLECURSOR)
3126MOUSEPROG equ 'xPCpaste'
3127endif ;ENABLEPASTE and (not ENABLECURSOR)
3128
3129if (not ENABLEPASTE) and ENABLECURSOR
3130MOUSEPROG equ 'xPCarrow'
3131endif ;(not ENABLEPASTE) and ENABLECURSOR
3132
3133onsign db 13,10,MOUSEPROG,' version ',PVERSION,13,10
3134 db 'Copyright (c) 1994-1998 Jürgen G. Weber and G.B. Gustafson',13,10
3135 db 'Free for personal use under the Gnu license agreement.',13,10
3136 db '$'
3137
3138how_to:
3139 db 13,10
3140 db 'KEYS and BUTTONS FUNCTION',13,10
3141if ENABLEPASTE
3142 db 'Drag Mouse 1 ........... Copy text',13,10
3143 db 'Double-click Mouse 1 ... Copy word',13,10
3144 db 'Mouse 2 ................ Paste text',13,10
3145 db 'CTRL-Mouse 2 ........... Paste text + ENTER',13,10
3146 db 'RSHIFT-Mouse 2 ......... Paste feature on/off',13,10
3147 db 'LSHIFT-CTRL-Mouse 2 .... Append text to TMP file',13,10
3148 db 'LSHIFT-ALT-Mouse 2 ..... Paste into Windows clipboard',13,10
3149endif ;ENABLEPASTE
3150if ENABLECURSOR
3151 db 'Mouse 1 ... ............ Position cursor (hold 1/6 sec)',13,10
3152 db 'Mouse 3 ................ Carriage return (except /A3)',13,10
3153 db 'ALT-Mouse 2 ............ Mouse 3 duplicate',13,10
3154 db 'LSHIFT-Mouse 1 ......... Cursor feature on/off ',13,10
3155 db 'LSHIFT-ALT-Mouse 1 ..... Toggle methods /A1-/A3',13,10
3156endif ;ENABLECURSOR
3157 db 'CTRL-LSHIFT-RSHIFT ..... Re-install (hold 1 sec)',13,10
3158 db '$'
3159
3160worked db 13,10
3161 db MOUSEPROG,' is installed. Use "',MOUSEPROG
3162 db ' /U" to un-install.'
3163 db 13,10,'$'
3164msgstr db 13,10
3165 db 'xPC-Mouse was already installed.',13,10,'$'
3166not_yet_str db 13,10, MOUSEPROG,' was not installed yet.',13,10,'$'
3167ok_de_inst db 13,10, MOUSEPROG,' is un-installed.',13,10,'$'
3168re_inst_str db 13,10, MOUSEPROG,' is re-activated.',13,10,'$'
3169wro_de_inst db 13,10, 'Could not un-install ',MOUSEPROG,'.',13,10,'$'
3170nomouse_str db 13,10,7,'No mouse driver found or driver too old.',13,10,'$'
3171noins_str db MOUSEPROG,' not installed.',13,10,'$'
3172if not XT
3173wro_cpu_str db MOUSEPROG,' needs at least an 80286 cpu.',13,10,'$'
3174endif
3175
3176if ENABLEPASTE
3177appendf_str db 13,10, 'Paste buffer appended to file.',13,10,'$'
3178endif ;ENABLEPASTE
3179
3180help_str db 13,10,'Options: /Q : Quiet, no messages',13,10
3181 db ' /R : Re-activate xPC-Mouse',13,10
3182 db ' /Sabc : Swap buttons 123 to order abc',13,10
3183; db ' /T : Enable timer int 08h patch',13,10
3184 db ' /N0 : Defeat mouse handler re-install',13,10
3185 db ' /N1 : Re-install mouse handler before exec',13,10
3186 db ' /N2 : Re-install after exit (default)',13,10
3187 db ' /N3 : Re-install before exec and after exit',13,10
3188if ENABLECURSOR ;=========Cursor Key code ==========;
3189 db ' /K : Defeat arrow key emulation',13,10
3190 db ' /A1 : Emacs/vi arrow key method (default)',13,10
3191 db ' /A2 : Matrix arrow key method',13,10
3192 db ' /A3 : Xterm escape sequence method',13,10
3193endif ;end ENABLECURSOR ;=========Cursor Key code ==========;
3194if ENABLEPASTE
3195 db ' /M : Monochrome video mode (equals /X119)',13,10
3196 db ' /Xddd : Highlight XOR mask ddd (default /X80)',13,10
3197 db ' /Bdddd: Buffer size dddd bytes',13,10
3198 db ' /P : Defeat pastebuffer use',13,10
3199 db ' /D=X : Set Xterm character classes from file X',13,10
3200 db ' /F=X : Append active paste buffer to file X',13,10
3201 db ' /F:X : Change TMP name c:\tmp\xpcm####.tmp to X',13,10
3202endif ;ENABLEPASTE
3203help_switches:
3204 db 'Info: /C : Show copyright information',13,10
3205if ENABLEPASTE
3206 db ' /D : Show Xterm character classes',13,10
3207endif ;ENABLEPASTE
3208 db ' /? : Show command switches',13,10
3209 db ' /H : Show key and button assignments',13,10
3210 db ' /U : Uninstall',13,10
3211 db '$'
3212
3213if ENABLEPASTE
3214; Insure source file is long enough when loaded into memory
3215; so that the pastebuffer is the proper size.
3216;
3217if ($-pastebuf) lt BUFFERLEN
3218 db BUFFERLEN-($-pastebuf) dup (?)
3219endif
3220
3221end_mouse equ pastebuf+BUFFERLEN
3222endif ;ENABLEPASTE
3223code ends
3224
3225; Stack segment is only used during initialization
3226
3227stck segment para stack 'stack'
3228 db 256 dup (?)
3229stck ends
3230
3231end init
3232
3233comment *
3234
3235 XPC-Mouse: POSITION CURSOR, COPY and PASTE in Dos Text Mode
3236
3237 Copyright (c) 1994-1998 by Jürgen G. Weber and Grant B. Gustafson.
3238 ALL RIGHTS RESERVED
3239
3240 Free for personal use under the Gnu Public License agreement, which is
3241 distributed with this source. See the end of this file for a copy of
3242 the License Agreement.
3243
3244 CREDITS
3245 ----------------------------------------------------------------------
3246 Portions of this code originated with and were extracted from
3247 PCMOUSE (c) 1992,1994 by Jürgen G. Weber
3248 Wiesentalstraße 1
3249 D-74523 Schwäbisch Hall
3250 Germany - European Union
3251
3252 This ASM source written by GB Gustafson
3253 113 JWB Math Dept Univ Utah
3254 Salt Lake City, UT 84112
3255 USA
3256 in collaboration with Jürgen G. Weber to create this new product.
3257 Portions of this ASM code also appeared in MOUSE2G, copyright (c)
3258 1991, 1992 by GB Gustafson. Finally, credits are due to Al Williams,
3259 for solid advice about TSRs, in his book "DOS 5: A Developers Guide",
3260 M&T Press, 1991, and to Dave Williams, for his electronic reference on
3261 DOS, especially the mouse information and interrupt details.
3262 ----------------------------------------------------------------------
3263
3264 XPC-Mouse
3265 POSITION CURSOR, COPY and PASTE in Dos Text Mode
3266
3267 Function: Highlight text while left button is pressed. Left release
3268 causes the selected text to be copied from the screen into
3269 an internal pastebuffer. The right button pastes the
3270 pastebuffer at the text cursor position. Left button press
3271 of 1/6 second positions the text cursor [defeatable]. Middle
3272 button press emits a carriage return (except in Xterm mode).
3273 Emacs/vi, matrix and Xterm style mouse action methods. See
3274 the HELP at the end of the file for more.
3275
3276 MAKE: tasm xpcmouse
3277 tlink xpcmouse
3278
3279 COMMAND LINE OPTIONS: /U /T /Q /N0 /N1 /N2 /N3 /R /Xddd /Bddd
3280 /M /K /P /A1 /A2 /A3 /C /H /F=X /D /D=X
3281 See help text at the end of the file.
3282 STARTUP DEFAULTS:
3283 Auto default for video XOR highlight mask
3284 /X80 for color modes (xor mask == 64+16 )
3285 /M for mono modes (/M==/X119, xor mask == 64+32+16+4+2+1)
3286 /A1 for Emacs/jed/vi arrow keys
3287 /N2 for auto re-install of mouse handler
3288 /U, /Q, /R, /T, /C, /?, /A2, /A3 defeated
3289 /K and /P toggles are ON
3290 /B2048 is the default paste buffer size 2048 bytes
3291
3292 VERSIONS:
3293 1.0 First public release. 1-Dec-1994
3294 1.1 Second release (maintenance). 17-Oct-1995
3295 1.2 Third release (new features). 25-Jan-1997
3296 1.3 Fourth release (maintenance). 10-Aug-1997
3297 1.4 Fourth release (maintenance). 5-Sept-1998
3298
3299 Features of 1.0 inherited from Jürgen G. Weber's PC-Mouse versions 1.0-1.5:
3300 Option /T, enable stuffing the paste buffer into the
3301 keyboard buffer at every timer (int 1ch) tick.
3302 Un-install Option /U. Mouse hardware reset after de-install.
3303 8088 Version. Support mono, color, ega, vga text modes.
3304 Option /Xddd for XOR mask
3305 Option /Q for quiet start up
3306 Option /N to defeat int 21h patch (obsolete in ver 1.1)
3307 Option /R to reactivate TSR.
3308 Pastebuffer compression and interrupt logic.
3309 Install and de-install routines.
3310
3311 Features of 1.0 originating with this ASM source written by GB Gustafson:
3312 Pressing the left button for 1/6 second positions the cursor.
3313 Default /A1 for emacs/vi/jove/jed/epsilon mouse action.
3314 Option /A2 is matrix mouse action, qedit/pi editors.
3315 Option /A3 is for Xterm X10/X11 style escapes \033[M cb cx cy.
3316 Works with remote jed/emacs/pi and extensible editors.
3317 Toggle /A state dynamically using SHIFT-ALT-buttonleft
3318 with ring selection /A1 --> /A2 --> /A3 --> /A1.
3319 Option /K defeats arrow keys and Xterm sequences.
3320 Option /P defeats the pastebuffer.
3321 ALT-buttonright duplicates buttonmiddle (for 2-button mouse).
3322 SHIFT-buttonleft toggles arrow keys on/off (see /K).
3323 SHIFT-buttonright toggles the pastebuffer on/off (see /P).
3324 Option /M for monochrome Video mode (/M==/X119).
3325 Unix file name selection on double-click using the idea
3326 of the X11R5 Xterm character classes.
3327 Hide mouse cursor after highlighting.
3328 Auto default for video XOR highlight mask
3329 /X80 for color modes (xor mask == 64+16 )
3330 /M for mono modes (/M==/X119, xor mask == 64+32+16+4+2+1)
3331 Help file dump /? gives switch information.
3332 Author, copying and copyright switch /C for shorter signon.
3333 Help file dump /H gives How-To information on mouse actions.
3334 Dynamic buffer size up to max size compiled into program.
3335 GNU license agreement.
3336
3337 Features of 1.1 (by GBG 10-Oct-95):
3338 Fixed 40-col mode bug. Supports video modes 0-13h only.
3339 Add support for 3-button mouse systems PC mouse.
3340 Add carriage return function on button3 (==ALT-button2)
3341 Corrected documentation on DOS 6.2+Windows 3.1 and fixed a
3342 nasty Win 3.1 bug present in xpcmouse 1.0 and PCmouse
3343 versions to 1.6.
3344 Added swapping of mouse buttons, because most mouse device
3345 drivers don't do it.
3346 Option /N0 to defeat mouse handler re-install
3347 Options /N1, /N2, /N3 to set mouse handler re-install method.
3348 These work on the fly by re-running xpcmouse.
3349
3350 Features of 1.2 (by GBG 25-Jan-97):
3351 Advice from Howard Schwartz, theo@ccnet3.ccnet.com.
3352 Added colons as valid file separators for double click. This
3353 is needed for grabbing URLs like http://www.yahoo.com/.
3354 Added command line switch for appending the active paste
3355 buffer to a file (given on the command line).
3356 Added command line switch for setting and displaying character
3357 classes.
3358 Hot button combination RSHIFT then CTRL-LSHIFT-RSHIFT for 1
3359 second re-installs xpcmouse.
3360 Mouse click CTRL-LSHIFT-MOUSE 2 appends paste text to file
3361 c:\tmp\xpcm####.tmp. Added command line support for it.
3362 Re-worked interrupt handlers so that int 21h only sets flags
3363 and the actual work happens in int 08h.
3364 Removed /T switch.
3365 Mouse click ALT-LSHIFT-MOUSE 2 copys paste text to the windows
3366 clipboard (if windows is running).
3367 Mouse highlight API changed so a drag from lower right to
3368 upper left defines a box (matrix). Other drags unchanged.
3369 Paste buffer no longer compressed, so that windows paste is
3370 possible directly without conversions and without additional
3371 buffer space.
3372 Set /N2 as default re-install method, based upon Win 95
3373 experiments.
3374 Redid the code churning in the mouse handler and interrupt
3375 routines to minimize system impact.
3376
3377 Features of 1.3 (by GBG 10-Aug-97):
3378 Fixed highlighting problem for paste functions. Previously
3379 went crazy during a drag+release. Howard Schwartz reported
3380 this and said that the paste to file feature fails on his
3381 machine. I could not reproduce it on mine. Maybe the failure
3382 is related to false highlighting of text? Never resolved.
3383
3384 Features of 1.4 (by GBG 5-Sept-98):
3385 Win95 complains about xpcmouse, even though it was
3386 uninstalled. Tried to address this problem by a more careful
3387 de-install which took the interrupt handlers out of service in
3388 a different order.
3389
3390 Bug fixes:
3391 /T was always ON. Reset to initially OFF. 1-Dec-94
3392
3393 /T ASM code caused characters to be lost on paste, traced to
3394 recursive call of interrupt 1ch. Fixed by setting a flag to
3395 bypass the second call (until the first one finished). This
3396 bug was also in PCMOUSE 1.5, as observed under SunPC and sun4
3397 OS. 1-Dec-94
3398
3399 /T off worked with paste, but not with arrow keys. Traced to
3400 convoluted code which bypassed a call to stuff the keybuffer.
3401 Fixed by having a central place where the mouse handler calls
3402 the stuffer routines (near the exit). 1-Dec-94
3403
3404 Procedure "GetMousePosition" did not test for 40-col. 1-Oct-95
3405
3406 The int 21h patch caused windows to crash when DOS applications
3407 exited, because of "call dword ptr cs:[old_21h]", which
3408 corrupted the system stack. But "jmp dword ptr cs:[old_21h]"
3409 seems to be just fine. Now, InstallMouseHandler gets called
3410 before each program load and after each program exit. We will
3411 miss a CPM-style jump to address zero, but the /R switch will
3412 restart xPC-Mouse in this unlikely event. 10-Oct-95
3413
3414 Documentation 1.0 claimed xpcmouse did not work in Win
3415 3.1. This is true for certain mouse device drivers and
3416 Win3.1 video drivers, especially those produced by
3417 hardware manufacturers before Win3.1 was released. 13-Oct-95
3418
3419 For example, all DOS windows in Win3.1 get xPC-Mouse, for
3420 configuration DOS 6.2 + Win 3.1 + Genius mouse driver
3421 gmouse.com + 1994 Microsoft SVGA 256 video driver. In this
3422 example, xpcmouse.exe is installed in DOS 6.2 before running
3423 Win3.1. It fails for "gmouse.com" replaced by "mouse.com"
3424 obtained from the Win3.1 distribution disk!
3425
3426 Buffer size was given in paragraphs in version 1.0, which is
3427 confusing. Changed to bytes in 1.1, with code to bump the byte
3428 count to full paragraphs. Default compile size changed to
3429 4096 maximum buffer size (BUFFERLEN variable is 4096) and
3430 default buffer size 2048 (no /B on command line). The choice
3431 of BUFFERLEN affects "loadhigh", because code+data must load
3432 entirely before we can shrink the package to its runtime size.
3433
3434 BUTTON CONVENTIONS.
3435 A 2-button mouse (Microsoft) has a Left button and a Right
3436 button. A 3-button mouse (PC Mouse Systems) has a Left button,
3437 Right button and Middle button. The physical layout is not
3438 important, because most mouse drivers allow the buttons to be
3439 swapped. Our discussion here assumes a right-handed mouse
3440 (otherwise it would be completely confusing to read) and the
3441 configuration below for a unix workstation using Xterm
3442 conventions for the mouse buttons. To understand "button1" and
3443 "button3", consult the ++second++ diagram, not the first!
3444
3445 ┌────┬────┠┌────┬────┬────â”
3446 Mouse button │ │ │ │ │ │ │
3447 configuration │ L │ R │ │ L │ M │ R │
3448 for the PC │ 1 │ 2 │ │ 1 │ 2 │ 3 │
3449 └────┴────┘ └────┴────┴────┘
3450 ┌────┬────┠┌────┬────┬────â”
3451 Mouse button │ │ │ │ │ │ │
3452 configuration │ L │ R │ │ L │ R │ M │
3453 for unix console │ 1 │ 2 │ │ 1 │ 2 │ 3 │
3454 └────┴────┘ └────┴────┴────┘
3455 If you work at a unix console, then consider remapping the
3456 mouse keys from order 123 to 132 (3-button PC Mouse Systems
3457 only). Do this via the mouse device driver that comes on a
3458 disk with the Mouse hardware. If you are left-handed, then
3459 swapping buttons is not a new idea.
3460
3461 CONFIGURATION FOR 3-BUTTON MOUSE.
3462 Most of the cheap mice with 3 buttons are just fine. I bought one for
3463 $9.95. It came with a diskette of software and documentation. It is
3464 installed in autoexec.bat with a line like
3465
3466 loadhigh c:\mouse\mouse.com /c2
3467
3468 which specifies COM2 for the port. Everything else is configured by the
3469 driver and I needed to do NOTHING. When first installed it came up as
3470 "Microsoft Mouse". And it worked fine as a 2-button mouse. Following
3471 the instructions with the mouse, I pulled the mouse connector from the
3472 computer, then held down the left mouse button and plugged it back in,
3473 then released the button. After the machine rebooted, the screen said
3474 "Mouse Systems Mouse" installed.
3475
3476 In short, there are no mouse driver switches to set in order to get the
3477 3-button mouse to act like one. No changes are made to the device
3478 driver command line.
3479
3480 1997 update. The linux documentation project has a mouse page in which
3481 they describe how to make hardware modifications to certain mice so
3482 they will always wake up in Mouse Systems mode. Search for "mouse" on
3483 http://sunsite.unc.edu/pub/Linux/.
3484
3485 But Microsoft windows 3.1 already had its mind made up that the mouse
3486 was a "Microsoft Mouse". So I had to run the Win 3.1 SETUP program
3487 (from inside Windows). The same thing can be accomplished by editing
3488 the SYSTEM.INI and WIN.INI sources in the windows directory, if you
3489 know how to do that.
3490
3491 TESTING:
3492 The TSR was tested on about 6 different PC machines dating from 1984 to
3493 1998 manufacture. CPU's tested: 80286, 80386SX, 80386DX, 80486SX,
3494 80486DX, 80486DX2, 586-P75-133, P133, P233, P266, P300, P400. No
3495 workable XT 8088 could be found for testing! However, an XT style
3496 non-extended keyboard was used and found to work.
3497
3498 Tested with XT turned off in the ASM code for 80386, 486DX120 and
3499 586-P75-133 cpu. It will probably not affect the TSR to do so, but the
3500 code by default does not make use of 80286+ opcodes or special features
3501 of int 16h. Some mouse drivers and BIOS combinations disable the TSR
3502 unless it is compiled with the 8088 code control symbol "XT", because
3503 the nonresident CPU and mouse BIOS tests cause the TSR to fail it's
3504 initial load. However, the failure is superficial: it may only affect
3505 de-install /U on most machines.
3506
3507 Loads high with devices "HIMEM.SYS" and "EMM386.EXE noems" /w control
3508 "DOS=HIGH,UMB" under DOS 5.0 and 6.2. Loaded low with 386max, did not
3509 test loaded into high umb's under 386max.
3510
3511 SUNPC EMULATOR. Works with DOS 4.01 under SoftPC version 3 (1992) for
3512 SUN4 OS (SunPC, DOS emulator from Sun Microsystems, standard
3513 configuration). This is the only mouse TSR known to work for DOS
3514 copy/paste/position in a unix environment (X-windows, DOS emulator).
3515 Used with COMMANDO TSR, no conflicts loaded low. Also works with WCED
3516 loaded high or low. In both, the arrow key feature allows positioning
3517 on the command line.
3518
3519 DOSEMU EMULATOR. This driver can be installed as a replacement for the
3520 Linux programs "gpm" and "selection" under the DOS emulator called
3521 "dosemu", versions 0.60.4 and later (August 1995) for the Linux
3522 operating system (386/486 unix). Not tested on Power PC linux.
3523
3524 MEMORY USAGE:
3525 Complaints about the TSR's resident size should take note that it will
3526 reside in high memory and eat about 5k of upper memory. By cutting
3527 out the pastebuffer, using option "/B0 /P", usage can be reduced to
3528 3k. A recompile, removing the arrow key code or the pastebuffer code
3529 will cause correspondingly significant code size reductions. Resident
3530 code size of 1.7k is possible, with cursor keys only, or 2.2k with
3531 paste buffer only (add 1k to 2k buffer).
3532
3533 Vincent Penquerc'h (penquerc@merlin.enssat.fr) has a product called
3534 "CutPaste", which controls a paste buffer, plus a separate TSR
3535 called "Mousekey" which stuffs cursor keys into the keyboard buffer.
3536 Vincent's CutPaste product is shareware with a charge of 10
3537 dollars; his Mousekey is freeware, no charge. No sources are supplied.
3538 The claim is that "CutPaste" uses 1.9kb plus buffer space, or
3539 approximately 3952 bytes. Vincent's Mousekey uses 464 bytes (see also
3540 mouse02g.asm with about the same size). The total usage is 4416 bytes,
3541 smaller than xPCmouse. Vincent's package has the advantage of splitting
3542 the two functions into neat containers. Vincent's product "Mousekey"
3543 operates differently than xPCmouse: in his, the mouse cursor and text
3544 cursor are the same.
3545
3546 Jürgen G. Weber still distributes the original incarnation of PCmouse
3547 which does copy and paste only (no cursor positioning), hence Vincent's
3548 CutPaste program has a competitor (PCmouse 1.6). These two programs are
3549 different: one may work for you and the other one not.
3550
3551 Sources to Vincent's Mousekey may not be available; see instead
3552 Mouse2g.asm, mentioned above, and available from http://www.coast.net/.
3553
3554 EDITORS TESTED:
3555 Remote over modem line: Emacs, vi, jed, jove, pi, joe, ce.
3556 Local PC: epsilon, pi, qedit, jed, csed.
3557
3558 Special interfaces tested: emacs, jed, pi.
3559 For these, we had to write extension code for the editor involved, or
3560 else modify the sources. The standard "mousex.sl" in the JED library
3561 works as written. PI needed the unix Xterm mouse code enabled for
3562 compilation under DOS. EMACS needed a special LISP function for the
3563 mouse motions.
3564
3565* ; End comment
3566
3567comment *
3568GNU PUBLIC LICENSE.
3569 This software is released as copyrighted material under the GNU PUBLIC
3570 LICENSE:
3571
3572 NO WARRANTY
3573
3574 Because xPC-Mouse is licensed free of charge, absolutely no warranty
3575 is provided, to the extent permitted by applicable state law. Except
3576 when otherwise stated in writing, Jürgen G. Weber and Grant B.
3577 Gustafson provides xPC-Mouse "as is" without warranty of any kind,
3578 either expressed or implied, including, but not limited to, the
3579 implied warranties of merchantability and fitness for a particular
3580 purpose. The entire risk as to the quality and performance of the
3581 program is with you. Should the xPC-Mouse program prove defective,
3582 you assume the cost of all necessary servicing, repair or correction.
3583
3584 In no event unless required by applicable law will Grant B. Gustafson
3585 and Jürgen G. Weber and/or any other party who may modify and
3586 redistribute xPC-Mouse be liable to you for damages, including any
3587 lost profits, lost monies, or other special, incidental or
3588 consequential damages arising out of the use or inability to use
3589 (including but not limited to loss of data or data being rendered
3590 inaccurate or losses sustained by third parties or a failure of the
3591 program to operate with programs not distributed by Grant B.
3592 Gustafson and Jürgen G. Weber) the program, even if you have been
3593 advised of the possibility of such damages, or for any claim by any
3594 other party.
3595
3596NO COST?
3597 This software is provided free of charge to individuals and educational
3598 institutions. Money is not requested.
3599
3600POSTCARDS?
3601 Postcards and comments are welcome!
3602
3603 Jürgen G. Weber GB Gustafson
3604 Wiesentalstraße 1 113 JWB Math Dept Univ Utah
3605 D-74523 Schwäbisch Hall Salt Lake City, UT 84112
3606 Germany - European Union USA
3607
3608* ; End comment