作为小米科技的创始人、董事长和首席执行官,雷军的名字如雷贯耳。那么作为技术员出身的雷军,他的代码水平如何,最近也成为网上的一个热点议题。
伴随这个热点议题一起出现的是雷军写于1994年的RAMinit程序源码。
;
(完整代码附后)
看到那份用汇编语言写的源代码,备感亲切,因为我也喜欢用汇编语言来写程序,而且写过这类DOS下的TSR(Terminate and Stay Resident,常驻内存)程序,也喜欢用.com格式(DOS下有64KB的长度限制)。
评价源代码质量,至少可以从三个指标来衡量,一是算法效率;二是模块化水平,包括函数、过程的封装,全局变量、局部变量的设定等;三是代码可读性,也就是代码风格,如函数、过程、变量的命名规则,特别是注释。后两个指标直接影响到程序的维护和升级。
第一次看源代码,首先感受到的就是代码可读性,这对于汇编语言尤其明显,如果代码没有完善的注释,看代码无异于读天书。
在DOS时代,代码规模不大,可以一个人独立完成,因此代码风格往往凭个人喜好,因人而异。
说到使用汇编语言的牛人,不得不提Anders Hejlsberg(安德斯·海尔斯伯格,1960.12~),用汇编语言写编译器。Turbo Pascal编译器的主要作者,Delphi、C#和TypeScript之父,同时也是.NET创立者。我最直接的感受是,同一个8086汇编源码,用TASM生成的可执行文件会比MASM生成的小,同一个Delphi源码,有Delphi2生成的可执行文件比Delphi5生成的小。
关于Anders Hejlsberg,可以看看李维先生写的《Borland传奇》。《Borland传奇》有电子工业出版社于2003-04 出的第一版和水利电力出版社于2004-06出的第二版,价格均为¥28.00。上Kongfz上查了一下,第一版卖得便宜,第二版比卖得比原价还高。
附完整代码
; RI.ASM Revision 2.12 [ July 12, 1994 ]Revision equ 'V2.12 ';; **************************************************************************; * *; * RAMinit Release 2.0 *; * Copyright (c) 1989-1994 by Yellow Rose Software Co. *; * Written by Mr. Leijun *; * *; * Function: *; * Press HotKey to remove all TSR program after this program *; * *; **************************************************************************; ..........................................................................; Removed Softwares by RI:; SPDOS v6.0F, WPS v3.0F; Game Busters III, IV; NETX ( Novell 3.11 ); PC-CACHE; Norton Cache; Microsoft SmartDrv; SideKick 1.56A; MOUSE Driver; Crazy (Monochrome simulate CGA program); RAMBIOS v2.0; 386MAX Version 6.01; ..........................................................................; No cancel softwares:; Windows 3.1 MSD;; No removed TSR softwares:; MS-DOS fastopen; Buffers, Files ... (QEMM 6.0); QCache (386MAX 6.01); ..........................................................................;COMMENT *V2.04 Use mouse driver software reset function to initiation mouse2/17/1993 by Mr. Lei and Mr. FengV2.05 RI cannot work in Windows DOS prompt3/9/1993 by Mr. LeiV2.06 1. When XMS cannot allocate 1K memory, RI halts.2. RI repeat deallocates EMS memory.V2.07 HotKey Setup Error4/25/1993 by Mr. LeiV2.08 KB BufferV2.10 1. Release high memory blocks (EMM386 QEMM386 S-ICE 386MAX)2. RI copies flagV2.12 1. Exists a critical error in Init 8259 procedure2. Save [40:F0--FF] user data area*dosseg.model tiny.codelocals @@org 100hStart: jmp Mainorg 103hTrue equ 1False equ 0MaxHandles equ 100hINT3 macroout 0ffh,alendm;; HotKey Status Test Var; --------------- ---------------;; 7 6 5 4 3 2 1 0 417 418 496; . . x . x . . . Left Alt is pressed 8 2; x . . . x . . . Right Alt is pressed 8 8; . . . x . x . . Left Ctrl is pressed 4 1; . x . . . x . . Right Ctrl is pressed 4 4; . . . . . . x . Left Shift is pressed 2; . . . . . . . x Right Shift is pressed 1;LeftAlt equ 00101000bRightAlt equ 10001000bLeftCtrl equ 00010100bRightCtrl equ 01000100bLeftShift equ 00000010bRightShift equ 00000001bHotKey db LeftCtrl or RightCtrlDataBegin dw 0NextDataSeg dw 0ffffholdInt2F_addr dw 0, 0XMS_control dw 0, 0Handle_begin dw 0cvtOfs dw 0 ; DOS 3.0 equ 0 and above DOS 4.0 is 1org 104hdb 0dhdb Revisiondb ??datedb 26org 114htsrLength dw 0MachineID db 0FCh ; IBM PC/ATAuxHotKey db 0 ; 2Dh ; 'X' Scan CodeAuxHotKeyName db 'X$ 'Power db TrueFlag db '!'Kbd102 db 0NoFlag db 0StopFlag db 1DosEnv dw 0WorkSeg dw 0PrevDataSeg dw 0Copies db '1'old_8259 db 0 ; 21h portdb 0 ; a1h portStatus dw 0XMSbit equ 00000001bEMSbit equ 00000010bSKbit equ 10000000bGoINT1C: db 0eaholdInt1C_addr dw 0, 0newINT1C:test cs:Status, SKbitjnz GoINT1Ccmp cs:StopFlag, 0jz @@0;; Mr. Lei 2/8/1993; Problem: if WPS quit and reenter, old RI cann't control keyboard.;push dspush axxor ax, axmov ds, axmov ax, ds:[9*4]cmp ax, offset NewInt9pop axpop dsjnz GoINT1Cmov cs:StopFlag, 0@@0: push axpush dspush esxor ax, axmov ds, axmov es, ds:[9*4+2]cmp word ptr es:[101h], 'IE' ; 'LEI'jz @@1climov cs:StopFlag, 1mov ax, ds:[9*4]mov cs:oldINT9_addr2, axmov ax, ds:[9*4+2]mov cs:oldINT9_addr2[2], axmov ds:[9*4], offset newINT9_2mov ds:[9*4+2], cssti@@1: pop espop dspop axjmp GoINT1C; ----------------------------------------------------------------------; INT2F Func;; AX = C0D7h Return RI segment in AX; AX = C0D8h Removes all TSR programs after RI; AX = C0D9h Removes all TSR programs include RI; AX = C0DAh Removes all RI copies; ----------------------------------------------------------------------newINT2F:cmp ax, 0c0d7h ; LEI Hanzi GB Codejnz @@1push cspop axiret@@1: cmp ax, 0c0d7h+1jnz @@2jmp KeepSelf@@2: cmp ax, 0c0d7h+2jnz @@3jmp NoKeepSelf@@3: cmp ax, 0c0d7h+3jnz @@9mov cs:NextDataSeg, -1mov cs:Copies, '1'jmp NoKeepSelf@@9: jmp dword ptr cs:oldInt2F_addrCallInt9:retnewINT9_2:mov cs:NoFlag, 1pushfdb 9ah ; call far ptr oldint9_addroldInt9_Addr2 dw 0, 0jmp newINT9_procnewINT9:pushfdb 9ah ; call far ptr oldint9_addroldInt9_Addr dw 0, 0cmp cs:NoFlag, 0jz newINT9_procmov cs:NoFlag, 0iretnewINT9_proc:cmp cs:Flag, '!' ; busy ?jnz @@0iret@@0:mov cs:Flag, '!' ; set busy flagpush ax ; cmp hot keypush bxpush esmov ax,40hmov es,axcmp cs:AuxHotKey, 0jz @@_1mov bx, es:[1ah]cmp bx, es:[1ch]jz @@10push bxmov bl, es:[bx+1]cmp bl, cs:AuxHotKeypop bxjnz @@10@@_1:mov ah,es:[17h] ; test CTRL SHIFT ALTmov al,cs:HotKeypush axand ax,0f0fhcmp al,ahpop axjnz @@10cmp cs:Kbd102, Truejnz @@1shr al, 1shr al, 1shr al, 1shr al, 1push axmov ah, es:[18h]and ax, 303hcmp al, ahpop axjnz @@10mov ah, es:[96h]shr ax, 1shr ax, 1and ax, 303hcmp al, ahjnz @@10cmp cs:AuxHotKey, 0jz @@_3inc bxinc bxcmp bx, 3ehjb @@_2mov bx, 1eh@@_2:mov es:[1ah], bx@@_3:call IsWinDosor ax, axjz @@1call Beep@@10:stipop espop bxpop axmov cs:Flag, ' ' ; no busyiret@@1: ; OKpop espop bxpop axKeepSelf:call RemoveTSRpush esmov es,cs:WorkSegmov dx,es:tsrLengthmov di,dxmov al,0h ; Aug 24, 1993mov cx,100hrep stosbpop esint 27hNoKeepSelf:mov ax,0e07hint 10hmov cs:clsStr, 47h ; Color (White in Red)call RemoveTSRdec cs:Copiescall RestoreSelfIntVecpush escmp cs:PrevDataSeg, 0jz @@1mov es, cs:PrevDataSegmov es:NextDataSeg, -1@@1: pop esmov ax, 4c00hint 21h; ---------------------------------------------------------------------------IsWinDOS:mov ax, 1600hint 2fhcmp al, 01hjz @@9cmp al, 0ffhjz @@9 ; Windows/386 Version 2.Xcmp al, 00hjz @@1cmp al, 80hjnz @@9 ; Windows 3 in enhanced mode; Version number in AL/AH@@1:mov ax, 4680hint 2fhcmp al, 80hjnz @@9xor ax, axjmp @@10@@9: mov ax, 1@@10: ret; -----------------------------------------------------------------------RestoreSelfIntVec:cmp Copies, '0'jz @@0ret@@0:clipush cspop dsxor ax, axmov es, axmov si, offset oldInt9_Addrmov di, 9*4movswmovswmov si, offset oldInt2F_Addrmov di, 2Fh*4movswmovswmov si, offset oldInt1C_Addrmov di, 1Ch*4movswmovswstiret; ------------- KERNEL PROGRAM ----------------------------------------------RemoveTSR:pop axcli ; Set stackmov sp, csmov ss, spmov sp, 100hstipush axcmp cs:Power, Truejnz @@1call Init8259@@1:push cspop ds@@_0:mov ax,ds:NextDataSegcmp ax, -1jz @@_1mov cs:PrevDataSeg, dsmov ds, axjmp @@_0@@_1: mov si,ds:DataBeginmov cs:WorkSeg, dslodswcmp ax, 'XX'jz @@_2call Beepret@@_2:call RestoreEnvStrcall RestoreMCB ; restore current mcbcall CloseFilescall RestorePortcall RestoreLEDscall RestoreVecList ; Restore vectors listcall RestoreFloppyParamcmp cs:Power, Truejnz @@2call RestoreCVTchain ; Restore cvt chaincall RestoreMemoryManager@@2:call RestoreBiosDatacall Enable8259mov ah, 1int 16hcall RestoreClockSpeedcall CloseSpeakercall ResetDiskcall UpdateTimecall ClosePRNmov bx,cs:WorkSegmov ah,50hint 21h ; Set PSP segmentmov ax,3int 10h ; Set display modecall InitPRNcall InitMousemov al, cs:Copiescmp al, '1'ja @@_sh1mov cs:ShowCopies, '*'jmp @@_sh2@@_sh1: mov cs:ShowCopies, al@@_sh2:mov si, offset clsStrcall ColorPrintStrmov cs:Flag, ' ' ; no busycmp Copies, '1'jnz @@_endmov cs:StopFlag, 0@@_end:call ClearKB_bufferretBeep:mov ax,0e07hint 10hret; #########################################################################ClearKB_Buffer:push espush bxmov bx, 0040hmov es, bxclimov bx, es:[1ah]mov es:[1ch], bxstipop bxpop esretInit8259:; cmp cs:Copies, '1'; jz @@1; ret@@1:cmp cs:MachineID, 0fchja @@pc_xt@@AT:mov bx,870h ;mov al,0 ;out 0F1h,al ;jcxz $+2jcxz $+2mov al,11h ; ICW1out 0A0h,aljcxz $+2jcxz $+2out 20h,aljcxz $+2jcxz $+2mov al,bl ; ICW2out 0A1h,aljcxz $+2jcxz $+2mov al,bhout 21h,aljcxz $+2jcxz $+2mov al,2 ; ICW3out 0A1h,aljcxz $+2jcxz $+2mov al,4out 21h,aljcxz $+2jcxz $+2mov al,1 ; ICW4out 0A1h,aljcxz $+2jcxz $+2out 21h,aljcxz $+2jcxz $+2mov al,0FFh ; OCW1out 0A1h,aljcxz $+2jcxz $+2out 21h,alret@@PC_XT:mov al,13h ; ICW1out 20h,aljcxz $+2jcxz $+2mov al,8 ; ICW2out 21h,aljcxz $+2jcxz $+2mov al,9 ; ICW4out 21h,aljcxz $+2jcxz $+2mov al,0FFh ; OCW1out 21h,alretEnable8259:mov ax, word ptr cs:old_8259out 021h,aljcxz $+2jcxz $+2mov al,ahout 0a1h,al ; DEC PC Bus Mouseret ; July 1994 by Mr. Lei; -------------------------------------------------------------------------RestoreBiosData:lodswcmp ax, '--'jz @@1call Beepret@@1: push espush dimov di, 40hmov es, dimov di, 10hmovswmov di, 0a8h ; [40h:a8h]movswmovswmov di, 49hmov cx, 1dhrep movsbmov di, 0f0h ; User datamov cx, 8rep movswpop dipop esret; -------------------------------------------------------------------------RestoreMCB:push dspush eslodsw ; 'MZ'@@0: lodswcmp ax, 'MM'jz @@1mov es,axxor di,dimovsbmovswmovswinc axmov bx, dscmp ax, bxjz @@10mov byte ptr es:[8], 0 ; Aug 24, 1993@@10: cmp byte ptr es:[0], 'Z'jnz @@0mov byte ptr es:[10h], 0jmp @@0@@1:pop espop dsret; -------------------------------------------------------------------------CloseFiles:mov ax, 5 ; Begin handlepush dspush simov cx, 15 ; Max handlesub cx, axinc cxmov bx, ax@@1: push bxpush cxmov ah, 3ehint 21hpop cxpop bxinc bxloop @@1pop sipop dsret; -------------------------------------------------------------------------RestorePort:mov di, 40h ; restore portmov es, dixor di, dimov cx, 8rep movswret; -------------------------------------------------------------------------RestoreLEDs:lodsband al, 11110000b ; LED statusmov ah, es:[17h]and ah, 00001111bor ah, aland ah, 0f0h ; Clear CTRL ALT SHIFTmov es:[17h], ahret; -------------------------------------------------------------------------RestoreEnvStr:lodswpush sipush dipush dspush esmov es, cs:DosEnvmov ds, axxor si, simov di, si@@0: lodsbor al, aljnz @@1cmp byte ptr ds:[si], 0jz @@2@@1: stosbjmp @@0@@2: stosbstosbpop espop dspop dipop siret; -----------------------------------------------------------------------RestoreVecList:xor ax,axmov di,axmov es,axmov cx,100h@@0: lodswxchg dx, axlodswcmp dx, 'EL'jnz @@1cmp al, 'I'jnz @@1sub cl, ahpush cxmov cl, ahmov ax, es:[di-4]mov dx, es:[di-2]@@a: stoswxchg ax, dxstoswxchg ax, dxloop @@apop cxor cx, cxjz @@9jmp @@0@@1:xchg ax, dxstoswxchg ax, dxstoswloop @@0@@9:ret;----------------------------------------------------------------------------RestoreFloppyParam: ; Mr. Lei 2/10/1992push espush axxor ax, axmov es, axmov byte ptr es:[525h], 2pop axpop esret;---------------------------------------------------------------------------RestoreCVTchain:lodswcmp ax, 'VC'jz @@_0call Beepret@@_0:push axpush cxpush es; -----------------------------------------------------------------lodsw ; DPBmov di, axlodswmov es, ax@@1: lodsbinc distosbadd di, cs:cvtOfsadd di, 10hmovswmovswles di, es:[di+2]cmp di, -1jnz @@1; -----------------------------------------------------------------lodsw ; DCBmov di, axlodswmov es, axxor ax, axdec axstosw; -----------------------------------------------------------------lodsw ; Device Driver Chainmov di, axlodswmov es, axxor cx, cx@@9: push dimov cl, 5rep movswpop diles di, es:[di]mov ax, diinc axjnz @@9pop espop cxpop axret; ----------------------------------------------------------------------------RestoreMemoryManager:test cs:Status, XMSbitjz @@1call LoadXMSstatus@@1:test cs:Status, EMSbitjz @@2call LoadEMSstatus@@2:retLoadEMSstatus:lodswcmp ax, 'ME'jz @@_0call Beepret@@_0:lodswmov cx, axxor dx, dx@@_1: push dspush sipush dxpush cx@@0: cmp dx, ds:[si]jz @@1add si, 4loop @@0push cxmov cx, 5@@__0: mov ah, 45h ; Deallocate Handle and Memoryint 67hor ah, ahjz @@__1loop @@__0@@__1: pop cx@@1:pop cxpop dxpop sipop dsinc dxcmp dx, 100hjb @@_1shl cx, 1shl cx, 1add si, cxretLoadXMSstatus:lodswcmp ax, 'MX'jz @@_0call Beepret@@_0:lodswmov cx, axjcxz @@5@@1:lodswmov dx, ax@@2: push dxmov ah, 0ah ; freecall dword ptr cs:xms_controlor ax, axpop dxjnz @@4cmp bl, 0abhjnz @@4push dxmov ah, 0dh ; unlockcall dword ptr cs:xms_controlor ax, axpop dxjmp @@2@@4: loop @@1@@5: retendp; -----------------------------------------------------------------------CloseSpeaker:in al, 61hand al, 0fchout 61h, alret; -----------------------------------------------------------------------RestoreClockSpeed:mov al, 00110110bout 43h, alxor ax, axout 40h, alout 40h, alret; -----------------------------------------------------------------------ResetDisk:xor ax, axxor dx, dxint 13h ; Restore Ainc dxint 13h ; Restore Bmov dl, 80hint 13h ; Restore Cret; --------------------------------------------------------------------------ClosePRN:mov ah, 51h ; Get PSP segint 21hmov es, bxmov ax, es:[16h] ; Prev PSP segcmp ax, bxjnz @@9mov ax, 3e00h ; COMMANDmov bx, 4int 21h@@9:retInitPRN:mov ax, 3e00hmov bx, 4 ; PRNint 21hmov ax, 3d01hmov dx, offset PRNnamepush cspop dsint 21hretPRNname db 'PRN',0InitMouse: ; 2/16/1993 by Mr. Leipush esxor ax, axmov es, axcmp word ptr es:[33h*4+2], 0jz @@0cmp word ptr es:[33h*4], 0jz @@0mov ax, 21hint 33h ; Hook Mouse Interrupt@@0: pop esret; ------------- CMOS CLOCK set to System -----------------------------------UpdateTime:call GetRealTimemov ah, 2dhint 21hretGetRealTime:mov ah,2int 1Ahmov al,chcall bcdxchgmov ch,almov al,clcall bcdxchgmov cl,almov al,dhcall bcdxchgmov dh,almov dl,0retBCDxchg:push axpush cxmov cl,4shr al,clpop cxmov bl,0Ahmul blpop bxand bl,0Fhadd al,blret; -----------------------------------------------------------------------; Display stringColorPrintStr:lodsbmov bh, al ; colorxor cx, cxmov dx, 014fhmov ax, 0600hint 10hmov ah, 02 ; GotoXY (0, 0)xor dx, dxmov bh, 0int 10hPrintStr:push cspop dsxor bx, bx@@1: lodsbcmp al, '$'jz @@2or al, aljz @@2mov ah, 0ehint 10hjmp short @@1@@2: mov al, cs:clsStrcolormov cs:clsStr, alret; -----------------------------------------------------------------------Self dw 0clsStrcolor db 17hclsStr db 17h ; Color (White in Blue)db ' RAMinit Version 2.12 (c) 1989-1994 by KingSoft Ltd. Mr. Leijun'db 0dh,0ahdb ' ['ShowCopies db '*'db '] Activate...',0ah,0dh,'$'endTSR equ $mcbList equ offset endTSR + 2 + 2vecList equ mcbList + 7*10 + 2 + 10h + 1 + 400hdevLink equ vecList + 4 + 5 * 26 + 4 + 10 * 30h + 4xmsList equ devLink + 2 + MaxHandles * 2emsList equ xmsList + 4 + 1024crtMode equ emsList + 2 + 1Dh + 4 + 10htsrLen equ crtMode + 1;; DOS Environment Reserved by RI; --------------------------------------------------; Flag 'XX' 2 bytes; Environment Segment 1 word; Free MCBs <=7*10 bytes; MCB segment 1 word; MCB 5 bytes; End flag 'MM' 1 word; COM LPT ports 10h bytes; LEDs status 1 bytes; Packed vectors list <=400h bytes; Flag 'CV' 2 bytes; CVT First DPB pointer 4 bytes; DPBs data <=5*26 bytes; First DCB pointer 4 bytes; Pointer to NUL 4 bytes; All device driver datas <=30h*10 bytes; Flag 'XM' 2 bytes; XMS free handle counter 2 bytes; EMS free handle list <=100h*4 bytes; Flag 'EM' 2 bytes; EMS free handle counter 2 bytes; EMS free handle list <=1024 bytes; EMS handle 1 word; Number of pages 1 word; Flag '--' 1 word; Equipment List 1 word; CRT 40:49h-66h 1dh bytes; 40:A8h 1 dword; BIOS User Data Area 40:F0--FF 10h bytes; ***************************************************************************;main: jmp main0Print Macro StrLea dx, Strcall DisplayStrendmInstMsg db 'RAMinit Version 2.12 'db 'Copyright (c) 1989-1994 by KingSoft Ltd. ',0dh,0ah,'$'Msg0 db 'Already installed !',0dh,0ah,0ahdb 'For Help, type "RI /?". ',0dh,0ah,'$'Msg_0 db 0ah,'Residents a new RAMinit copy [y/n] ? $'Msg_2 db 'OK, RI No.'Msg_RI db '2'db ' residents successful !', 0dh,0ah,'$'Msg1 db 'Activate with: $'KeyMsg db 'Right_Shift$'db 'Left_Shift$ 'KMsg1 db 'Left_Ctrl$ 'db 'Left_Alt$ 'db 'Right_Ctrl$ 'db 'Right_Alt$ 'KMsg2 db 'Ctrl$ 'db 'Alt$ 'db 'Ctrl$ 'db 'Alt$ 'PlusMsg db ' + $'crlf db 0dh,0ah,'$'HelpMsg db 'Programmed by Mr. Leijun Dec 1992', 0dh,0ah,0ahdb 'Usage: RI [options]',0dh,0ah,0ahdb '/H,/? Display this screen',0dh,0ahdb '/CLS Removes all TSR programs after current RI',0dh,0ahdb '/RET Removes TSR programs include current RI',0dh,0ahdb '/NEW Residents a new data copy of current environment',0dh,0ahdb '/ALL Removes all RI copies and all other tsr programs',0dh,0ahdb '/Sxyy.. Define Hotkey x=AuxHotkey yy..=shift status',0dh,0ahdb ' x=auxiliary hotkey (default is "X") ',0dh,0ahdb ' x equ "1" means need AuxHotkey',0dh,0ahdb ' yy..=shift status [CAScas]',0dh,0ahdb ' C: Left Ctrl A: Left Alt S: Left Shift',0dh,0ahdb ' c: Right Ctrl a: Right Alt s: Right Shift',0dh,0ah,0ahdb 'Example: "RI /S1c" means Hotkey is Right_Ctrl+X',0dh,0ahdb ' "RI /S0Cc" means HotKey is Left_Ctrl+Right_Ctrl',0dh,0ahdb ' "RI /CLS" equals simply press hotkey',0dh,0ahdb ' "RI /RET" Removes all TSRs after current RI and this RI',0dh,0ahdb 0ahdb 'Contact me for RAMinit problems: (01)2561155 Call 1997',0dh,0ahdb '$'ErrMsg db 'ERROR: Invalid options !',0dh,0ah,0ah,'$'WinErr db 7, 'Sorry, I cannot work in Windows DOS environment.',0dh,0ah,'$'SetMsg db 7, 'Defines new Hotkey successful !',0dh,0ah,0ah,'$'tsrOK db FalseMain0:cldPrint instMsgcall IsWinDosor ax, axjz @@1Print WinErrmov ax, 4c00hint 21h@@1:call HotKeyValidmov cs:Status, 0call EMS_testcall CmpDosVercall CmpSideKickcall GetMachineIDcall ModifyHotKeyPromptmov ax, 0c0d7hint 2fhmov es, axcmp word ptr es:[101h], 'IE' ; 'LEI'jnz @@0mov cs:Self, ax@@0:call CmdLinecall PrintHotKeyPromptcmp cs:tsrOK, truejz @@2call tsrReplyOK@@2: cmp cs:tsrOK, truejnz @@_2call PrintCopies@@_2:mov word ptr cs:[100h], 'EL'mov byte ptr cs:[102h], 'I'push cspop espush cspop dsstdmov si, offset eofmov cx, eof - offset Heremov di, tsrLenadd di, cxinc cxrep movsbcldmov bx, tsrLenjmp bxHere:mov ax,csmov es,axmov di,offset endTSRmov cs:DataBegin, dimov cs:NextDataSeg, -1mov ax, 'XX'stoswin al, 0a1hmov ah, alin al, 21hpush axmov word ptr cs:old_8259, axxor ax, axout 21h,al ; CLIcall SaveOtherscall SetSelfIntcall BackupVecListcmp cs:Power, truejnz @@20call BackupCVTchaincall BackupMemoryManager@@20:call BackupBiosDatastimov cs:Flag, ' ' ; no busymov cs:StopFlag, 0 ;mov cs:tsrLength, dicall SetDosEnvSegcmp cs:Self, 0jz @@29push cspop dspush cspop escldmov cx, cs:tsrLengthmov si, cs:DataBeginsub cx, simov di, 120hmov cs:DataBegin, direp movsbmov cs:tsrLength, di@@29:pop axout 21h, al ; STImov al, ahout 0a1h, almov dx, cs:tsrLengthinc dxint 27h; ----------------------------------------------------------------------------SetDosEnvSeg:push dspush esmov ax, cs@@10: mov es, axmov ax, es:[16h] ; Get father process psp segmentor ax, axjz @@11mov bx, escmp ax, bxjnz @@10@@11:mov es, word ptr es:[2ch] ; Get father process env segmentmov cs:DosEnv, espop espop dsret; ----------------------------------------------------------------------------SaveOthers:mov ax, cs:[2ch] ; Env Segstoswcall backupMCB ; Current MCBmov ax, 40h ; COM LPT Portmov ds, axmov si, 0hmov cx, 8rep movswmov si, 17h ; LED statuslodsbstosb; call OpenLEDsret; --------------------------------------------------------------------------backupMCB:mov ax, 'ZM'stoswpush dspush esmov ah, 52hint 21h ; Get MCB chain headmov ax, es:[bx-2]pop es@@0: mov ds, axcmp byte ptr ds:[0], 'Z' ; End ?jz @@20cmp byte ptr ds:[0], 'M' ; Memory control blockjnz @@30cmp word ptr ds:[3], 0 ; Nul mcbjz @@10cmp word ptr ds:[1], 0 ; Free MCBjnz @@10call SaveFreeMCB@@10: inc axadd ax, ds:[3]jmp @@0@@20:call SaveFreeMCBcmp ax, 0a000hinc axjnb @@30mov ax, 9fffh ; MS-DOS UMBjmp @@0@@30:cmp ax, 0c000h ; 386MAXja @@90mov ax, 0c020hjmp @@0@@90: ; Error ?pop dsmov ax, 'MM' ; Set MCB flagstoswretSaveFreeMCB:stoswxor si,simovsbmovswmovswret;; push ax; stosw; xor si,si; movsb; movsw; movsw; pop ax; cmp ax, 09fffh; jnb @@3; push ax; push ds; mov ds,ax; cmp byte ptr ds:[0], 'M'; pop ds; pop ax; jnz @@4; mov ax, 09fffh ; MS-DOS UMB; jmp @@0; @@4: cmp ax, 0c000h; ja @@3; mov ax, 0c020h ; 386MAX; jmp @@0;; --------------------------------------------------------------------------OpenLEDs: push ax ; Open all LEDsor al, 070hmov ds:[17h], almov ah, 1int 16hmov cx, 4 ; Delay@@20: push cxxor cx, cx@@21: loop @@21pop cxloop @@20pop axmov ds:[17h], almov ah, 1int 16hret; --------------------------------------------------------------------------SetSelfInt:push espush dicmp cs:self, 0jnz @@1push cspop dsmov ax,3509hint 21hmov word ptr cs:oldInt9_addr,bxmov word ptr cs:oldInt9_addr[2],esmov dx,offset NewInt9mov ax,2509hint 21hmov ax,352Fhint 21hmov word ptr cs:oldInt2F_addr,bxmov word ptr cs:oldInt2F_addr[2],esmov dx,offset newInt2Fmov ax,252Fhint 21hmov ax,351Chint 21hmov word ptr cs:oldInt1C_addr,bxmov word ptr cs:oldInt1C_addr[2],esmov dx,offset newInt1Cmov ax,251chint 21hclijmp @@2@@1:mov es, cs:Selfinc es:Copies@@_0: cmp es:NextDataSeg, -1jz @@_1mov es, es:NextDataSegjmp @@_0@@_1: mov es:NextDataSeg, cs@@2:pop dipop esret; -----------------------------------------------------------------------SaveCounter:mov word ptr es:[di], 'EL'mov byte ptr es:[di+2], 'I'mov byte ptr es:[di+3], blxor bx, bxadd di, 4ret; -----------------------------------------------------------------------DisplayStr: push cspop dsmov ah, 9int 21hret; -----------------------------------------------------------------------CmdLine:push cspop dsxor ax, axmov si, 80hlodsbor al, aljnz @@1ret@@1:mov cx, axdec axpush axpush si@@0: lodsbcmp al, ' 'jz @@0cmp al, '/'jnz @@2lodsbcmp al, 'S'jz @@_2cmp al, 's'jnz @@2@@_2:call SetHotKeyPrint SetMsgmov ax, 4c00hint 21h@@2:pop sipop axpush axpush si@@_3: lodsbcmp al, 'A'jb @@3cmp al, 'Z'ja @@3add byte ptr ds:[si-1],20h ; DownCase@@3: loop @@_3pop sipop cxadd si, cxlodsbcmp al, 's' ; CLSjnz @@5cmp word ptr ds:[si-3], 'lc'jnz @@5cmp cs:Self, 0jz @Errmov ax, 0c0d7h+1int 2fh@@5: cmp al, 'h' ; HELPjz @helpcmp al, '?'jz @helpcmp al, 't' ; RETjnz @@6cmp word ptr ds:[si-3], 'er'jnz @@6@@7:cmp cs:Self, 0jz @Errmov ax, 0c0d7h+2int 2fh@@6: cmp al, 'w' ; NEWjnz @@8cmp word ptr ds:[si-3], 'en'jnz @@8mov cs:tsrOK, trueret@@8:cmp al, 'l' ; ALLjnz @@9cmp word ptr ds:[si-3], 'la'jnz @@9mov ax, 0c0d7h+3int 2fh@@9:cmp al, ' 'jnz @Errret@Err:Print ErrMsg@help:Print HelpMsgmov ax, 4c00hint 21h;---------------------------------------------------------------------------tsrReplyOK:cmp cs:Self, 0jz @@1Print Msg0push esmov ax, cs:Self@@_10: mov es, axmov ax, es:NextDataSegcmp ax, -1jnz @@_10mov ax, es@@_0: push axdec axmov es, axmov bx, es:[3]pop axadd ax, bxinc axmov es, axcmp word ptr es:[0], 'OC'jz @@_0mov bx, cscmp ax, bxpop esjz @@2Print Msg_0mov ah, 1int 21hpush axPrint crlfpop axcmp al, 'y'jz @@3cmp al, 'Y'jz @@3@@2: ; Print Msg_1mov ax, 4c01hint 21h@@3:@@1: mov cs:tsrOK, trueretPrintCopies:cmp cs:Self, 0jz @@1push es ; Added -by- Mr. Leimov es, cs:Self ; Aug 24, 1993mov al, es:Copiesinc al ; Total RI copiespush ax ; Set es = current mcbmov ax, csdec axmov es, axpop axmov cx, 5 ; Search end of file namemov bx, 8@@10: inc bxcmp byte ptr es:[bx], 20hjz @@20cmp byte ptr es:[bx], 0ffhjz @@20cmp byte ptr es:[bx], 00hjz @@20loop @@10@@20: ; Set current RI nomov byte ptr es:[bx], ':' ; "RI:2"mov byte ptr es:[bx+1], alcmp bx, 8+7jnb @@30mov byte ptr es:[bx+2], 0@@30:pop esmov cs:Msg_RI, alPrint Msg_2@@1: ret;---------------------------------------------------------------------------; Backup Interrupt Vector List;BackupVecList:push dspush cspop esxor si,si ; Vectorsmov ds,simovswmovswxor bx, bxmov cx,00ffh@@0: lodswxchg dx, axlodswcmp ax, es:[di-2]jnz @@1cmp dx, es:[di-4]jz @@2@@1: or bx, bxjz @@3call SaveCounter@@3: xchg dx, axstoswxchg dx, axstoswloop @@0jmp @@4@@2: inc bxloop @@0call SaveCounter@@4:pop dsret;;-----------------------------------------------------------------------------BackupCVTchain:mov ax, 'VC'stoswpush axpush bxpush cxpush dspush esmov ah, 52hint 21h ; ES:BX -- DOS table as described below; --------------------------------------------------------------------push es ; DPB chainspush bxlds si, es:[bx]push cspop esmov ax, sistoswmov ax, dsstoswmov bx, cs:cvtOfsxor cx, cx@@1: mov al, ds:[si+1]stosbmov ax, ds:[si+bx+12h]stoswmov ax, ds:[si+bx+14h]stoswinc cxlds si, ds:[si+bx+18h]cmp si, -1jnz @@1; mov ax, 5; mul cl; add ax, 4; add cs:tsrLength, axpop bxpop es; --------------------------------------------------------------------push es ; DCB file control blockspush bxles bx, es:[bx+4]@@11: cmp word ptr es:[bx], -1jz @@10les bx, es:[bx]jmp @@11@@10:mov ax, esxchg ax, bxpush cspop esstoswxchg ax, bxstoswpop bxpop es; add cs:tsrLength, 4; ---------------------------------------------------------------------push es ; Device Driver Chainspop dsadd bx, 22hmov si, bx ; NULpop esmov ax, sistoswmov ax, dsstoswxor cx, cxxor bx, bx@@9: push simov cl, 5rep movswinc bxpop silds si, ds:[si]mov ax, siinc axjnz @@9pop dspop cxpop bxpop axret; ----------------------------------------------------------------------------BackupBiosData:mov ax, '--'stoswpush dspush simov si, 40hmov ds, simov si, 10hmovswmov si, 0a8hmovswmovswmov si, 49hmov cx, 1dhrep movsbmov si, 0f0hmov cx, 8rep movswpop sipop dsret; ---------------------------------------------------------------------------BackupMemoryManager:push cspop espush dspush escall SaveXMSstatuscall SaveEMSstatuspop espop dsret;---------------------------------------------------------------------SaveEMSstatus:test cs:status, EMSbitjnz @@1ret@@1:mov ax, 'ME'stoswinc diinc dipush dimov ah, 4dhint 67hpop dimov es:[di-2], bxshl bx, 1shl bx, 1add di, bxret; -------------------------------------------------------------------SaveXMSstatus:call XMS_testtest cs:status, XMSbitjnz @@1ret@@1:mov ax, 'MX'stoswmov dx, 1call XMS_allocjnz @@_1xor cx, cx ; XMS alloc failurestoswret@@_1:push dxsub dx, MaxHandles * 10@@2:push dxcall XMS_Lockpop dxjnz @@3cmp bl, 0a2hjnz @@4add dx, 10jmp @@2@@3: push dxcall XMS_unlockpop dx@@4:mov cs:handle_begin, dxpop dxpush dxcall XMS_bstatxor cx, cxmov cl, blinc cxpop dxcall XMS_Freemov dx, cs:Handle_beginpush cxpush cspop esmov ax, cxstosw@@5: push dxcall XMS_Lockpop dxjnz @@6cmp bl, 0a2h ; Handle invalidjz @@7@@6: call XMS_unlockadd dx, 10jmp @@5@@7: mov ax, dxstoswadd dx, 10loop @@5pop cxret; ------------------------------------------------------------------XMS_test:push esmov ax, 4300hint 2fhcmp al, 80hjnz @@9mov ax, 4310hint 2fhmov cs:XMS_control, bxmov cs:XMS_control[2], esor cs:Status, XMSbit@@9:pop esretXMS_stat:mov ah, 0call dword ptr cs:xms_controlmov hma_exist, dlrethma_exist db 0XMS_alloc:mov ah, 9call dword ptr cs:xms_controlor ax, axretXMS_lock:mov ah, 0chcall dword ptr cs:xms_controlor ax, axretXMS_unlock:mov ah, 0dhcall dword ptr cs:xms_controlor ax, axretXMS_bstat:mov ah, 0ehcall dword ptr cs:xms_controlor ax, axretXMS_free:mov ah, 0ahcall dword ptr cs:xms_controlor ax, axret; ----------------------------------------------------------------------------EMS_test:push cspop dsmov dx, offset EMMnamemov ax, 3d00hint 21hjc @@2mov bx, axmov ah, 3ehint 21hor cs:Status, EMSbit@@2:retEMMname db 'EMMXXXX0',0; -----------------------------------------------------------------------------SetHotKey:xor bx, bxlodsbpush ax@@1: lodsbcmp al, 0dhjz @@9cmp al, 'C'jnz @@2or bl, LeftCtrljmp @@1@@2:cmp al, 'c'jnz @@3or bl, RightCtrljmp @@1@@3:cmp al, 'A'jnz @@4or bl, LeftAltjmp @@1@@4:cmp al, 'a'jnz @@5or bl, RightAltjmp @@1@@5:cmp al, 'S'jnz @@6or bl, LeftShiftjmp @@1@@6:cmp al, 's'jnz @@7or bl, RightShiftjmp @@1@@7: pop axjmp @Err@@9:mov cs:HotKey, blpop axmov cs:AuxHotKey, 2dh ; 'X' scan keycmp al, '1'jz @@29mov cs:AuxHotKey, 0@@29:cmp cs:Self, 0jz @@30push esmov es, cs:Selfmov es:HotKey, blmov bl, cs:AuxHotKeymov es:AuxHotKey, blpop es@@30:call GetRunFileNamemov ax, 3d02hint 21hjc @@10push cspop dsmov bx, axmov cx, 4mov dx, 100hmov ah, 40hint 21hjc @@10mov ax, 4200hxor cx, cxmov dx, 17hint 21hjc @@10mov cx, 1mov dx, offset AuxHotKeymov ah, 40hint 21hjc @@10mov ah, 3ehint 21h@@10:ret; -----------------------------------------------------------------------GetRunFileName:; Return:; DS:DX Pointer of this run file name ASCIIZ stringpush axpush bxpush cxpush sipush dipush espush cspop esmov ax, es:[2ch]mov es, axxor di, dimov cx, 1000hxor al, al@@1: repnz scasbcmp es:[di], alloopnz @@1mov dx, diadd dx, 3push espop dspop espop dipop sipop cxpop bxpop axret; ---------------------------------------------------------------------------GetMachineID:push esmov KBD102,Truemov ax,40hmov es,axtest byte ptr es:[96h], 00010000bjnz @@1mov Kbd102,False@@1:xor ax,axdec axmov es,axmov al,es:[0eh]mov cs:MachineID, alpop esret; ---------------------------------------------------------------------------ModifyHotKeyPrompt:cmp cs:Kbd102, Truejz @@9push cspop espush cspop dsmov cx, 12*4mov si, offset KMsg2mov di, offset KMsg1rep movsb@@9: cmp cs:MachineID, 0fchjna @@10mov cs:clsStrcolor, 70h ; Monomov cs:clsStr, 70h@@10:ret; ---------------------------------------------------------------------------PrintHotKeyPrompt:Print Msg1mov al, cs:HotKeymov ah, alshr al, 1shr al, 1and ax, 33chor al, ahmov dx, offset KeyMsg@@40:or ax, ax ; Mr. Lei 4/25/1993jz @@_42shr al, 1push axjnc @@41push axcall ColorDisplayStr; mov ah, 9; int 21hpop axor al, aljz @@42push dxmov dx, offset PlusMsgcall ColorDisplayStr; Print PlusMsgpop dx@@41: add dx, 12pop axjmp @@40@@42: pop ax@@_42: cmp cs:AuxHotKey, 0jz @@43cmp cs:HotKey, 0 ; Mr. Leijz @@_43mov dx, offset PlusMsgcall ColorDisplayStr; Print PlusMsg@@_43: mov dx, offset AuxHotKeyNamecall ColorDisplayStr; Print AuxHotKeyName@@43:Print crlfretColorDisplayStr:push bxpush cxpush dxpush simov bl, 0fhmov si, dxxor bh, bhmov cx, 1@@1: lodsbcmp al, '$'jz @@2or al, aljz @@2push cxmov ah, 09hint 10hmov ah, 3int 10hinc dlmov ah, 2int 10hpop cxjmp short @@1@@2:pop sipop dxpop cxpop bxret; ---------------------------------------------------------------------------CmpSideKick:xor ax, axmov es, axles bx, es:[20h]cmp word ptr es:[bx-4], 4b53hjnz @@1cmp word ptr es:[bx-2], 4942hjz @@2@@1: mov es, axles bx, es:[94h]cmp word ptr es:[bx-2], 4b53hjz @@2ret@@2: or cs:Status, SKbitret; ---------------------------------------------------------------------------CmpDosVer: mov ah, 30hint 21hcmp al, 3jb @@1cmp al, 3jna @@2mov cs:cvtOfs, 1ret@@2: mov cs:cvtOfs, 0ret@@1: Print DosVerErrmov ax, 4cffhint 21hDosVerErr db 'Sorry, DOS version too lower !',0dh,0ah,'$'HotKeyValid:cmp cs:HotKey, 0jnz @@_1cmp cs:AuxHotKey, 0jnz @@_1Print HotKeyErrmov ax, 4cfehint 21h@@_1: retHotKeyErr db 'Sorry, please setup hotkey again. ',0dh,0ah,'$'eof:endsend Start; ------------- The End ! ---------------------------------------------------