To: opendos AT delorie DOT com Message-Id: Organization: Inst. of Evolutionary Physiology & Biochemistry, St.Petersburg From: pavel AT insect DOT ief DOT spb DOT su (Pavel Ozerski) Date: Wed, 28 May 97 18:20:56 +0300 Reply-To: pavel AT insect DOT ief DOT spb DOT su Subject: wishes to OpenDOS developer and an useful utility Precedence: bulk I whill tell several wishes about OpenDOS 1. A problem with VSHARE.386 is greater as it looks because the default locks count of SHARE.EXE is not enough to several applications (WINWORD 6 etc.) That problem can be fixed by correct SHARE parameters (e.g. SHARE /L:200) but not every user can configure the system independently! I think, the best solving is adding to SETUP program a new feature, 'Windows VSHARE support' that (if "YES") must add the line 'SHARE /l:...' to AUTOEXEC.BAT file. 2. TASKMGR must have a feature to copy/paste (probably optionally compatible with Windows clipboard). I use a my utility (CLIP) but it don't support mouse and the Windows clipboard. It is a freeware but can have some bugs. Every can use it and make changes in code. To begin marking and to accept block you must use Enter key. Esc, Home, End, PgUp, PgDown, arrows supported. The applied source code is compatible with Borland Pascal 7 but incompatible with Stony Brook. {(C) P.Ozerski, Institute of Evolutionary Physiology & Biochemistry of Russian Academy of Science, St.Petersburg.} {Release 2.0b, 1997} {uses some tricks developmed by A.Shekhovtzov (Kiev, Ukraine)} {Must be loaded before TASKMGR, compatible with: - HILOAD and Quarterdeck LOADHI; - different text video modes including some non-standard (card-specific); can use text .INI-file } {Freeware, but no warranty!!! Compiler - TP7/BP7 (real mode), (?)TP6} {$A+,B-,D-,E-,F-,G-,I-,L-,N-,O-,R-,S-,V-,X-} {$M 1024,0,0} uses DOS,CRT; type BufType=array[1..132,1..60]of char; var mode:array[0..255]of boolean; vectorstochange:array[1..3]of pointer; OldCursorShape:word; buf:buftype; intvec:array[0..255]of pointer absolute 0:0; i,j,x1,y1,x2,y2,__x1,__x2,EndCounter:byte; returner:(label_left,label_right,label_up,label_down); menucolor:byte; currentmode,maxrows,maxcolumns,_maxrows,_maxcolumns:byte; oldvector9,oldvector60,old1C:procedure; oldvector9_addr:pointer absolute oldvector9; oldvector60_addr:pointer absolute oldvector60; old1c_addr:pointer absolute old1C; PrefixSeg,EnvSeg,MenuCmd,ArrowsCmd:word; MenuOK,MenuDone,ArrowsDone,EGAVGA,marking:boolean; OldXY:word; var Old,New,Start:record case byte of 1:(_X,_Y:byte); 2:(_XY:word) end; const int60H:byte=$60; EndMode:boolean=false; Top_Y:byte=0; Bottom_Y:byte=0; Left_X:byte=0; Right_X:byte=0; _X:byte=1; _Y:byte=1; down=True; up=false; ALT:boolean=up; CTRL:boolean=up; lSHIFT:boolean=up; rSHIFT:boolean=up; menu:array[1..7,1..14]of char=( #218#196#196#196#196#196#196#196#196#196#196#196#196#191, #179' Copy F5 '#179, #195#196#196#196#196#196#196#196#196#196#196#196#196#180, #179' Paste F6 '#179, #195#196#196#196#196#196#196#196#196#196#196#196#196#180, #179' Close Esc '#179, #192#196#196#196#196#196#196#196#196#196#196#196#196#217); menuInUse:boolean=false; pasteFlag:boolean=false; StrCount:byte=0; StrLen:byte=0; var backgr:array[1..7,1..14]of word; __i,__j:byte; type btype=array[1..sizeof(menu)]of record case byte of 1:(c1,c2:char); 2:(b1,b2:byte); 3:(w:word); end; bPtr=^btype; var HotAlt,HotCtrl,HotlShift,HotrShift:boolean; HotKey,Port60H:byte; Video:Bptr; VideoSeg:word; _left,_right,_top,_bottom:byte; procedure Move( VAR Source, Dest; Count : word ); TYPE Bytes = array[1..MaxInt] of byte; VAR I : word; begin FOR I := 1 TO Count DO Bytes(Dest)[I]:=Bytes(Source)[I]; end; procedure BufferDS; begin end; procedure PasteProc;interrupt; const X:word=0; KbdStart = $1E; KbdEnd = $3C; var KbdHead : Word absolute $40 : $1A; KbdTail : Word absolute $40 : $1C; SaveKbdTail : Word; __X:char absolute X; begin asm mov ax, cs : word ptr [BufferDS] mov ds,ax end; if PasteFlag and(strcount=0) then PasteFlag:=false; if PasteFlag then begin if __j>strlen then X:=7181 else begin X:=0; __X:=buf[__j,__i]; end; SaveKbdTail := KbdTail; if KbdTail = KbdEnd then KbdTail := KbdStart else Inc(KbdTail, 2); if KbdTail = KbdHead then KbdTail := SaveKbdTail else MemW[$40:SaveKbdTail] := X; if (__i=StrCount)and(__j=StrLen)then PasteFlag:=false else if __j<=strLen then inc(__j) else begin __j:=1; inc(__i); end end; asm pushf end; Old1C end; procedure MyRes; interrupt; begin asm mov ax, cs : word ptr [BufferDS] mov ds,ax pushf call oldvector9 end; port60H:=port[$60]; case port60H of 29:Ctrl:=down; 157:Ctrl:=up; 56:ALT:=down; 184:ALT:=up; 42:lShift:=down; 170:lShift:=up; 54:rShift:=down; 182:rShift:=up; end; if menuInUse then exit; if(port60H=HotKey)and (alt=HotAlt)and (ctrl=HotCtrl)and (lshift=HotlShift)and (rShift=HotrShift)then begin asm cli mov AH,$0F int $10 mov CurrentMode,AL mov MaxColumns,AH mov _MaxColumns,AH dec _MaxColumns end; if not Mode[CurrentMode] then begin asm sti end; exit; end; if EGAVGA then asm mov AH,$11 mov AL,$30 xor BH,BH push BP push ES int $10 pop ES pop BP inc DL mov MaxRows,DL mov _MaxRows,DL dec _MaxRows end else begin MaxRows:=25; _MaxRows:=24; end; for i:=1 to 7 do begin Video:=ptr(VideoSeg,pred(i)*MaxColumns*2); for j:=1 to 14 do begin backgr[i,j]:=Video^[j].w; Video^[j].c1:=Menu[i,j]; Video^[j].b2:=MenuColor; end; end; menuInUse:=true; marking:=false; asm mov AX,2002 int $60 sti end; end; end; procedure _60(_AX,_BX,_CX,_DX,_SI,_DI,_DS,_ES,_BP:Word);interrupt; procedure Arrows;near; label Lab1,UpDown,LeftRight, __L,__R,__U,__D, __E,__R_Entry, __H,__L_Entry, __PU,__U_Entry, __PD,__D_Entry; var D:record L,H:byte end absolute _DX; begin case arrowscmd of 20224:{End} begin EndMode:=true; EndCounter:=0; while EndCounter<_maxColumns do asm mov AH,$3 xor BH,BH int $10 mov EndCounter,DL jmp __R_Entry; __E: end; EndMode:=false; end; 18176:{Home} begin EndMode:=true; EndCounter:=_MaxColumns; while EndCounter>0 do asm mov AH,$3 xor BH,BH int $10 mov EndCounter,DL jmp __L_Entry; __H: end; EndMode:=false; end; 18688:{PgUp} begin EndMode:=true; EndCounter:=_MaxRows; while EndCounter>0 do asm mov AH,$3 xor BH,BH int $10 mov EndCounter,DH jmp __U_Entry; __PU: end; EndMode:=false; end; 20736:{PgDn} begin EndMode:=true; EndCounter:=0; while EndCounter<_MaxRows do asm mov AH,$3 xor BH,BH int $10 mov EndCounter,DH jmp __D_Entry; __PD: end; EndMode:=false; end; 19712:{->} begin EndMode:=false; __R_Entry: asm mov AH,$3 xor BH,BH int $10 mov Old,DX mov New,DX cmp DL,_maxcolumns je lab1 inc DL cmp DL,_right jg @1 mov _left,DL jmp @2 @1: mov _right,DL @2: mov AH,$2 xor BH,BH mov New,DX int $10 end; if Marking Then begin if New._X>right_X then Right_X:=New._X else Left_X:=New._X; returner:=label_right; goto LeftRight; __R: end; if EndMode then Goto __E end; 19200:{<-} begin EndMode:=false; __L_Entry: asm mov AH,$3 xor BH,BH int $10 mov Old,DX mov New,DX cmp DL,0 je lab1 dec DL cmp DL,_left jl @1 mov _right,DL jmp @2 @1: mov _left,DL @2: mov AH,$2 xor BH,BH mov New,DX int $10 end; if Marking Then begin if New._X=Start._Y then begin y1:=Succ(New._Y); y2:=Succ(Old._Y); end else begin y1:=(New._Y); y2:=(Old._Y); end; returner:=Label_Up; goto UpDown; __U: end; if EndMode then Goto __PU end; 20480:{Down} begin EndMode:=false; __D_Entry: asm mov AH,$3 xor BH,BH int $10 mov Old,DX mov New,DX cmp DH,_maxrows je lab1 inc DH cmp DH,_bottom jg @1 mov _top,DH jmp @2 @1: mov _bottom,DH @2: mov AH,$2 xor BH,BH mov New,DX int $10 end; if Marking then begin if New._Y>Bottom_Y then Bottom_Y:=New._Y else Top_Y:=New._Y; if New._Y>Start._Y then begin y1:=succ(Old._Y); y2:=succ(New._Y); end else begin y1:=Old._Y; y2:=New._Y; end; returner:=Label_Down; goto UpDown; __D: end; if EndMode then Goto __PD end; end; goto Lab1; Updown: for i:=y1 to y2 do begin if i<=y1 then x1:=succ(Old._X) else x1:=Start._X; if (x1<=New._X)or(i=y1) then begin __x1:=x1; __x2:=New._X end else begin __x1:=New._X; __x2:=x1 end; Video:=ptr(VideoSeg,pred(i)*MaxColumns*2); for j:=succ(__x1) to succ(__x2) do Video^[j].b2:=$7F-Video^[j].b2; end; case returner of Label_Up:goto __U; Label_Down:goto __D; end; leftRight: if (New._X>Start._X)or((New._X=Start._X)and(Returner=Label_left)) then begin x1:=succ(Old._X); x2:=succ(New._X); end else begin x1:=Old._X; x2:=New._X; end; if returner=Label_Right then asm mov CL,x1 mov CH,x2 mov x1,CH mov x2,CL end; for i:=Top_Y to Bottom_Y do begin Video:=ptr(VideoSeg,i*MaxColumns*2); for j:=succ(x2) to x1 do Video^[j].b2:=$7F-Video^[j].b2; end; case returner of Label_Left:goto __L; Label_Right:goto __R; end; Lab1: end; begin asm mov ax, cs : word ptr [BufferDS] mov ds,ax end; if _AX=2000 then asm mov AX,'LC' mov BX,'PI' mov _AX,AX mov _BX,BX end else if _AX=2001 then begin if (intvec[$60]=@_60)and(intvec[$9]=@myres)and(intvec[$1C]=@pasteProc)then begin vectorstochange[1]:=oldvector60_addr; vectorstochange[2]:=oldvector9_addr; vectorstochange[3]:=old1C_addr; _AX:=4002; _BX:=PrefixSeg; _CX:=ofs(vectorstochange); _DX:=seg(vectorstochange); end else _AX:=4000 end else if _AX=2002 then begin repeat asm xor AH,AH int 16H mov MenuCmd,AX end; case MenuCmd of 283,16128,16384: begin for i:=1 to 7 do begin Video:=ptr(VideoSeg,pred(i)*MaxColumns*2); for j:=1 to 14 do Video^[j].w:=backgr[i,j]; end; if MenuCmd=283{Esc}then begin MenuOK:=false; MenuDone:=true; end else if MenuCmd=16384{F6}then begin __i:=1; __j:=1; PasteFlag:=true; end else {F5} begin asm mov AH,$3 xor BH,BH int $10 mov OldCursorShape,CX mov OldXY,DX mov AH,$2 mov BH,$0 xor DX,DX int $10 mov AH,$1 mov CX,$0505 int $10 end; MenuOK:=true; ArrowsDone:=false; asm xor AH,AH mov _left,AH mov _right,AH mov _top,AH mov _bottom,AH end; repeat asm xor AH,AH int 16H mov ArrowsCmd,AX end; case ArrowsCmd of 283:{Esc} begin MenuOK:=false; ArrowsDone:=true; end; 7181:{Enter} begin ArrowsDone:=true; asm mov AH,$3 xor BH,BH int $10 mov Start,DX mov Top_Y,DH mov Bottom_Y,DH mov Left_X,DL mov Right_X,DL end; Video:=ptr(VideoSeg,Start._Y*MaxColumns*2); Video^[succ(Start._X)].b2:=$7F-Video^[succ(Start._X)].b2 end; else arrows end; until ArrowsDone; if MenuOK then begin ArrowsDone:=false; repeat asm xor AH,AH int $16 mov ArrowsCmd,AX end; marking:=true; case ArrowsCmd of 283:{Esc} begin MenuOK:=false; ArrowsDone:=true; end; 7181:{Enter} begin strlen:=succ(Right_X-Left_X); strCount:=succ(Bottom_Y-Top_Y); for i:=1 to strCount do begin Video:=ptr(VideoSeg,(i+Top_Y-1)*MaxColumns*2); for j:=1 to StrLen do buf[j,i]:=Video^[j+Left_X].c1; end; ArrowsDone:=true; end; else arrows end; until ArrowsDone; for i:=Top_Y to Bottom_Y do begin Video:=ptr(VideoSeg,i*MaxColumns*2); for j:=Left_X to Right_X do Video^[succ(j)].b2:=$7F-Video^[succ(j)].b2; end; end; MenuDone:=true; asm mov AH,$1 mov CX,OldCursorShape int $10 end end; end; else MenuDone:=false; end until MenuDone; MenuInUse:=false end; end; procedure DummyProc; forward; procedure Keep(ExitCode:byte); var ResidSize,NewDS,DataSize:word; begin NewDS:=(CSeg+Ofs(DummyProc)DIV 16)+1; DataSize:=SSeg-DSeg; ResidSize:=NewDS-PrefixSeg+DataSize; asm mov ax,NewDS mov cs:word ptr[BufferDS],ax end; move(MEM[DSeg:0],MEM[NewDS:0],(SSeg-DSeg)*16); asm mov ax,[SYSTEM.PREFIXSEG] mov es,ax mov es,es:[02CH] mov ah,49H int 21H mov dx,ResidSize mov ah,31H mov al,ExitCode int 21H end end; procedure DummyProc; begin end; var code:integer; ID:array[1..4]of char absolute buf; IniFile:record t:text; d:dirstr; n:namestr; e:extstr; end absolute buf; ModeString:string; const keyname:array[1..88]of string[4]= ( 'Esc', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 'Bksp', 'Tab', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', #17#196#217, 'CTRL', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', '''', '`', '(l)'#24, '\', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', '(r)'#24, 'PrSc', 'lALT', 'SPBR', 'CAPS', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'NmlK', 'ScLk', 'HOME', 'UP', 'PgUp', '-', 'Left', 'Rght', 'g5', '+', 'END', 'DOWN', 'PgDn', 'INS', 'DEL', 'SysR', '???', '???', 'F11', 'F12' ); procedure UpStr(var _s);near; var s:string absolute _s; ls:byte absolute _s; i:byte; begin for i:=1 to ls do s[i]:=UpCase(s[i]); end; var section,item,default:string; function GetIni:string;near; var endsection,found:boolean; s:string; ps:byte; begin with IniFile do begin GetIni:=default; reset(t); if ioresult=0 then begin found:=false; endsection:=false; while not(endSection or found ) do begin if eof(t) then endSection:=true else begin readln(t,s); UpStr(s); while (s[0]>#0)and(s[1]<#32) do delete(s,1,1); ps:=pos(section,s); if ps=1 then while not(endSection or found ) do if eof(t) then endSection:=true else begin readln(t,s); UpStr(s); while (s[0]>#0)and(s[1]<#32) do delete(s,1,1); if pos('[',s)=1 then endSection:=true else begin ps:=pos(item+'=',s); if ps=1 then begin found:=true; GetIni:=copy(s,length(item)+2,255) end; end; end; end; end; close(t); end end end; function Val(s:string):longint;near; var result:longint; begin system.val(s,result,code); Val:=result; end; function STR7(var s:string):string;near; var ss:string[7]; begin ss:=s; while length(ss)<7 do ss:=ss+' '; STR7:=ss end; const ClipAlreadyLoaded:boolean=true; Unloaded:boolean=false; var OldPtr:pointer; OldRec:record O,S:word end absolute oldPtr; label ll1,ll2; begin ModeString:=paramstr(1); ModeString[2]:=UpCase(ModeString[2]); GetIntVec($60,@Oldvector60); if (ModeString='/?')or(ModeString='/H') then begin write('/U - Uninstall;'#13#10+ '.INI file syntax:'#13#10+ '[KEYS]'#13#10+ 'ALT=ON{default}|OFF'#13#10+ 'CTRL=ON|OFF{default}'#13#10+ 'LEFTSHIFT=ON|OFF{default}'#13#10+ 'RIGHTSHIFT=ON|OFF{default}'#13#10+ 'HOTKEY=nn{default=$1}'#13#10+ '[COLOR]'#13#10+ 'COLOR=nn{default=$07}'#13#10+ '[VIDEOMODES]'#13#10+ 'TEXT=n1,n2...{default=0,1,2,3,7}'#13#10#13#10+ 'Hit Ente'); writeln('r to hot key codes list'); readln; for j:=1 to 88 do begin write(j:0,': ',STR7(keyname[j])); if j mod 4 =0 then writeln; end; halt end else if (ModeString='/U') then begin if (@Oldvector60<>nil)and(@Oldvector60<>ptr($F000,$E3D4)) then begin asm mov AX,2000 int $60 cmp AX,'LC' jne ll1 cmp BX,'PI' jne ll1 mov AX,2001 int $60 cmp AX,4002 jne ll2 mov PrefixSeg,BX mov oldRec.O,CX mov oldRec.S,DX end; for i:=1 to 3 do begin case i of 1: j:=$60; 2: j:=$9; 3: j:=$1C; end; setintvec(j,pointer(OldPtr^)); inc(OldRec.O,4) end; EnvSeg:=MemW[PrefixSeg:$2C]; asm push ES mov AH,$49 mov ES,PrefixSeg int $21 mov AH,$49 mov ES,EnvSeg int $21 pop ES mov Unloaded,true jmp ll2 ll1: mov ClipAlreadyLoaded,false ll2: end end else ClipAlreadyLoaded:=false; if not ClipAlreadyLoaded then writeln('CLIP not loaded') else begin if Unloaded then writeln('CLIP is removed from memory') else writeln('CLIP cannot be removed from memory'); end; halt(2) end; EGAVGA:=true; asm mov AX,$1A00 int $10 cmp AL,$1A je @1 mov EGAVGA,false @1: mov AH,$0F int $10 mov CurrentMode,AL end; if currentmode=7 then VideoSeg:=$B000 else VideoSeg:=$B800; PrefixSeg:=System.PrefixSeg; if(@Oldvector60<>nil)and(@Oldvector60<>ptr($F000,$E3D4))then begin asm mov AX,2000 int $60 mov word ptr[buf],AX mov word ptr[buf+2],BX end; if ID='CLIP' then begin writeln('CLIP already loaded'); halt(1) end; end; with IniFile do begin fsplit(paramstr(0),D,N,E); assign(t,D+N+'.INI'); end; Section:='[KEYS]'; Item:='ALT'; Default:='ON'; HotALT:=GetIni='ON'; Section:='[KEYS]'; Item:='CTRL'; Default:='OFF'; HotCTRL:=GetIni='ON'; Section:='[KEYS]'; Item:='LEFTSHIFT'; Default:='OFF'; HotlSHIFT:=GetIni='ON'; Section:='[KEYS]'; Item:='RIGHTSHIFT'; Default:='OFF'; HotrSHIFT:=GetIni='ON'; Section:='[KEYS]'; Item:='HOTKEY'; Default:='1'; HotKey:=Val(GetIni); Section:='[COLOR]'; Item:='COLOR'; Default:='7'; MenuColor:=Val(GetIni); Section:='[VIDEOMODES]'; Item:='TEXT'; Default:='0,1,2,3,7'; ModeString:=GetIni+','; fillchar(mode,sizeof(mode),char(false)); Mode[0]:=true; Mode[1]:=true; Mode[2]:=true; Mode[3]:=true; Mode[7]:=true; code:=0; while (code=0)and(modestring[0]>#1)do begin Mode[val(copy(Modestring,1,pred(pos(',',modestring))))]:=true; delete(ModeString,1,pos(',',modestring)); end; writeln('CLIP R2.0, utility to copy/paste in DOS text mode'); write('Hot Key: '); if HotAlt then write('ALT+'); if HotCtrl then write('CTRL+'); if HotlShift then write('Left SHIFT+'); if HotrShift then write('Right SHIFT+'); if (HotKey in [1..88])and(KeyName[HotKey]<>'???') then writeln(KeyName[HotKey]) else writeln('Unknown key #',Hotkey:0); fillchar(buf,sizeof(buf),0); SetIntVec($60,@_60); GetIntVec($9,@Oldvector9); SetIntVec($9,Addr(MyRes)); GetIntVec($1C,@Old1C); SetIntVec($1C,Addr(PasteProc)); SwapVectors; Keep(0); end. -- Pavel V. Ozerski | Inst. of Evolutionary Physiology & Biochemistry, office +7 (812)552-6870(291)| Russian Academy of Sciences, FAX +7 (812)552-3012 | Thorez pr. 44, St.Petersburg, 194223, Russia home +7 (812)528-5576 | E-mail: pavel AT insect DOT ief DOT spb DOT su