天天看點

雷軍的代碼

;
; RI.ASM Revision  [ July ,  ]
Revision equ 'V2.12 '
;
; 
;  
;  RAMinit Release  
;  Copyright (c) - 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 v6F, WPS v3F
; Game Busters III, IV
; NETX ( Novell  )
; PC-CACHE
; Norton Cache
; Microsoft SmartDrv
; SideKick A
; MOUSE Driver
; Crazy (Monochrome simulate CGA program)
; RAMBIOS v2
; MAX Version 
; ..........................................................................
; No cancel softwares:
; Windows  MSD
;
; No removed TSR softwares:
; MS-DOS fastopen
; Buffers, Files ... (QEMM )
; QCache (MAX )
; ..........................................................................
;
COMMENT 

V2 Use mouse driver software reset function to initiation mouse
// by Mr. Lei and Mr. Feng
V2 RI cannot work in Windows DOS prompt
// by Mr. Lei
V2  When XMS cannot allocate K memory, RI halts.
 RI repeat deallocates EMS memory.
V2 HotKey Setup Error
// by Mr. Lei
V2 KB Buffer
V2  Release high memory blocks (EMM386 QEMM386 S-ICE MAX)
 RI copies flag
V2  Exists a critical error in Init  procedure
 Save [:F0--FF] user data area



dosseg
.model tiny
.code
locals @@
org h

Start: jmp Main
org h

True equ 
False equ 
MaxHandles equ h

INT3 macro
out ffh,al
endm
;
; HotKey Status Test Var
; --------------- ---------------
;
;           
; . . x . x . . . Left Alt is pressed  
; x . . . x . . . Right Alt is pressed  
; . . . x . x . . Left Ctrl is pressed  
; . x . . . x . . Right Ctrl is pressed  
; . . . . . . x . Left Shift is pressed 
; . . . . . . . x Right Shift is pressed 
;
LeftAlt equ b
RightAlt equ b
LeftCtrl equ b
RightCtrl equ b
LeftShift equ b
RightShift equ b
HotKey db LeftCtrl or RightCtrl

DataBegin dw 
NextDataSeg dw ffffh
oldInt2F_addr dw , 
XMS_control dw , 
Handle_begin dw 
cvtOfs dw  ; DOS  equ  and above DOS  is 
org h
db dh
db Revision
db ??date
db 
org h
tsrLength dw 
MachineID db FCh ; IBM PC/AT

AuxHotKey db  ; Dh ; 'X' Scan Code
AuxHotKeyName db 'X$ '
Power db True
Flag db '!'
Kbd102 db 
NoFlag db 
StopFlag db 
DosEnv dw 
WorkSeg dw 
PrevDataSeg dw 
Copies db '1'
old_8259 db  ; h port
db  ; a1h port

Status dw 
XMSbit equ b
EMSbit equ b
SKbit equ b

GoINT1C: db eah
oldInt1C_addr dw , 
newINT1C:
test cs:Status, SKbit
jnz GoINT1C
cmp cs:StopFlag, 
jz @@
;
; Mr. Lei //
; Problem: if WPS quit and reenter, old RI cann't control keyboard. ;
push ds
push ax
xor ax, ax
mov ds, ax
mov ax, ds:[]
cmp ax, offset NewInt9
pop ax
pop ds
jnz GoINT1C
mov cs:StopFlag, 

@@: push ax
push ds
push es
xor ax, ax
mov ds, ax
mov es, ds:[+]
cmp word ptr es:[h], 'IE' ; 'LEI'
jz @@
cli
mov cs:StopFlag, 
mov ax, ds:[]
mov cs:oldINT9_addr2, ax
mov ax, ds:[+]
mov cs:oldINT9_addr2[], ax
mov ds:[], offset newINT9_2
mov ds:[+], cs
sti
@@: pop es
pop ds
pop ax
jmp 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, c0d7h ; LEI Hanzi GB Code
jnz @@
push cs
pop ax
iret
@@: cmp ax, c0d7h+
jnz @@
jmp KeepSelf
@@: cmp ax, c0d7h+
jnz @@
jmp NoKeepSelf
@@: cmp ax, c0d7h+
jnz @@
mov cs:NextDataSeg, -
mov cs:Copies, '1'
jmp NoKeepSelf
@@: jmp dword ptr cs:oldInt2F_addr


CallInt9:
ret


newINT9_2:
mov cs:NoFlag, 
pushf
db ah ; call far ptr oldint9_addr
oldInt9_Addr2 dw , 
jmp newINT9_proc

newINT9:
pushf
db ah ; call far ptr oldint9_addr
oldInt9_Addr dw ,  cmp cs:NoFlag, 
jz newINT9_proc
mov cs:NoFlag, 
iret
newINT9_proc:
cmp cs:Flag, '!' ; busy ?
jnz @@
iret
@@:
mov cs:Flag, '!' ; set busy flag
push ax ; cmp hot key
push bx
push es
mov ax,h
mov es,ax

cmp cs:AuxHotKey, 
jz @@_1
mov bx, es:[ah]
cmp bx, es:[ch]
jz @@
push bx
mov bl, es:[bx+]
cmp bl, cs:AuxHotKey
pop bx
jnz @@
@@_1:
mov ah,es:[h] ; test CTRL SHIFT ALT
mov al,cs:HotKey
push ax
and ax,f0fh
cmp al,ah
pop ax
jnz @@ cmp cs:Kbd102, True
jnz @@
shr al, 
shr al, 
shr al, 
shr al, 
push ax
mov ah, es:[h]
and ax, h
cmp al, ah
pop ax
jnz @@
mov ah, es:[h]
shr ax, 
shr ax, 
and ax, h
cmp al, ah
jnz @@ cmp cs:AuxHotKey, 
jz @@_3
inc bx
inc bx
cmp bx, eh
jb @@_2
mov bx, eh
@@_2:
mov es:[ah], bx
@@_3:
call IsWinDos
or ax, ax
jz @@
call Beep
@@:
sti
pop es
pop bx
pop ax
mov cs:Flag, ' ' ; no busy
iret
@@: ; OK
pop es
pop bx
pop ax

KeepSelf:
call RemoveTSR
push es
mov es,cs:WorkSeg
mov dx,es:tsrLength
mov di,dx
mov al,h ; Aug , 
mov cx,h
rep stosb
pop es
int h

NoKeepSelf:
mov ax,h
int h
mov cs:clsStr, h ; Color (White in Red)
call RemoveTSR
dec cs:Copies
call RestoreSelfIntVec
push es
cmp cs:PrevDataSeg, 
jz @@
mov es, cs:PrevDataSeg
mov es:NextDataSeg, -
@@: pop es
mov ax, c00h
int h

; ---------------------------------------------------------------------------

IsWinDOS:
mov ax, h
int fh
cmp al, h
jz @@ cmp al, ffh
jz @@ ; Windows/ Version X
cmp al, h
jz @@ cmp al, h
jnz @@ ; Windows  in enhanced mode
; Version number in AL/AH
@@:
mov ax, h
int fh
cmp al, h
jnz @@
xor ax, ax
jmp @@
@@: mov ax, 
@@: ret

; -----------------------------------------------------------------------
RestoreSelfIntVec:
cmp Copies, '0'
jz @@
ret
@@:
cli
push cs
pop ds
xor ax, ax
mov es, ax
mov si, offset oldInt9_Addr
mov di, 
movsw
movsw
mov si, offset oldInt2F_Addr
mov di, Fh4
movsw
movsw
mov si, offset oldInt1C_Addr
mov di, Ch4
movsw
movsw
sti
ret

; ------------- KERNEL PROGRAM ----------------------------------------------
RemoveTSR:
pop ax
cli ; Set stack
mov sp, cs
mov ss, sp
mov sp, h
sti
push ax

cmp cs:Power, True
jnz @@
call Init8259
@@:
push cs
pop ds
@@_0:
mov ax,ds:NextDataSeg
cmp ax, -
jz @@_1
mov cs:PrevDataSeg, ds
mov ds, ax
jmp @@_0
@@_1: mov si,ds:DataBegin
mov cs:WorkSeg, ds
lodsw
cmp ax, 'XX'
jz @@_2
call Beep
ret
@@_2:
call RestoreEnvStr
call RestoreMCB ; restore current mcb
call CloseFiles
call RestorePort
call RestoreLEDs
call RestoreVecList ; Restore vectors list
call RestoreFloppyParam
cmp cs:Power, True
jnz @@
call RestoreCVTchain ; Restore cvt chain
call RestoreMemoryManager
@@:
call RestoreBiosData
call Enable8259
mov ah,  int h

call RestoreClockSpeed
call CloseSpeaker
call ResetDisk
call UpdateTime

call ClosePRN
mov bx,cs:WorkSeg
mov ah,h
int h ; Set PSP segment
mov ax, int h ; Set display mode

call InitPRN
call InitMouse
mov al, cs:Copies
cmp al, '1'
ja @@_sh1
mov cs:ShowCopies, ''
jmp @@_sh2
@@_sh1: mov cs:ShowCopies, al
@@_sh2:
mov si, offset clsStr
call ColorPrintStr
mov cs:Flag, ' ' ; no busy
cmp Copies, '1'
jnz @@_end
mov cs:StopFlag, 
@@_end:
call ClearKB_buffer
ret

Beep:
mov ax,h
int h
ret

; #########################################################################

ClearKB_Buffer:
push es
push bx
mov bx, h
mov es, bx
cli
mov bx, es:[ah]
mov es:[ch], bx
sti
pop bx
pop es
ret


Init8259:
; cmp cs:Copies, '1'
; jz @@
; ret
@@:
cmp cs:MachineID, fch
ja @@pc_xt
@@AT:
mov bx,h ;
mov al, ;
out F1h,al ;
jcxz $+
jcxz $+
mov al,h ; ICW1
out A0h,al
jcxz $+
jcxz $+
out h,al
jcxz $+
jcxz $+
mov al,bl ; ICW2
out A1h,al
jcxz $+
jcxz $+
mov al,bh
out h,al
jcxz $+
jcxz $+
mov al, ; ICW3
out A1h,al
jcxz $+
jcxz $+
mov al,
out h,al
jcxz $+
jcxz $+
mov al, ; ICW4
out A1h,al
jcxz $+
jcxz $+
out h,al
jcxz $+
jcxz $+
mov al,FFh ; OCW1
out A1h,al
jcxz $+
jcxz $+
out h,al
ret
@@PC_XT:
mov al,h ; ICW1
out h,al
jcxz $+
jcxz $+
mov al, ; ICW2
out h,al
jcxz $+
jcxz $+
mov al, ; ICW4
out h,al
jcxz $+
jcxz $+
mov al,FFh ; OCW1
out h,al
ret

Enable8259:
mov ax, word ptr cs:old_8259
out h,al
jcxz $+
jcxz $+
mov al,ah
out a1h,al ; DEC PC Bus Mouse
ret ; July  by Mr. Lei

; -------------------------------------------------------------------------

RestoreBiosData:
lodsw
cmp ax, '--'
jz @@
call Beep
ret
@@: push es
push di
mov di, h
mov es, di

mov di, h
movsw
mov di, a8h ; [h:a8h]
movsw
movsw
mov di, h
mov cx, dh
rep movsb

mov di, f0h ; User data
mov cx, 
rep movsw

pop di
pop es
ret

; -------------------------------------------------------------------------

RestoreMCB:
push ds
push es
lodsw ; 'MZ'
@@: lodsw
cmp ax, 'MM'
jz @@
mov es,ax
xor di,di
movsb
movsw
movsw
inc ax
mov bx, ds
cmp ax, bx
jz @@
mov byte ptr es:[],  ; Aug , 
@@: cmp byte ptr es:[], 'Z'
jnz @@
mov byte ptr es:[h], 
jmp @@
@@:
pop es
pop ds
ret

; -------------------------------------------------------------------------
CloseFiles:
mov ax,  ; Begin handle
push ds
push si
mov cx,  ; Max handle
sub cx, ax
inc cx
mov bx, ax
@@: push bx
push cx
mov ah, eh
int h
pop cx
pop bx
inc bx
loop @@
pop si
pop ds
ret

; -------------------------------------------------------------------------
RestorePort:
mov di, h ; restore port
mov es, di
xor di, di
mov cx, 
rep movsw
ret

; -------------------------------------------------------------------------
RestoreLEDs:
lodsb
and al, b ; LED status
mov ah, es:[h]
and ah, b
or ah, al
and ah, f0h ; Clear CTRL ALT SHIFT
mov es:[h], ah
ret

; -------------------------------------------------------------------------
RestoreEnvStr:
lodsw
push si
push di
push ds
push es
mov es, cs:DosEnv
mov ds, ax
xor si, si
mov di, si
@@: lodsb
or al, al
jnz @@ cmp byte ptr ds:[si], 
jz @@
@@: stosb
jmp @@
@@: stosb
stosb
pop es
pop ds
pop di
pop si
ret

; -----------------------------------------------------------------------
RestoreVecList:
xor ax,ax
mov di,ax
mov es,ax
mov cx,h
@@: lodsw
xchg dx, ax
lodsw
cmp dx, 'EL'
jnz @@ cmp al, 'I'
jnz @@
sub cl, ah
push cx
mov cl, ah
mov ax, es:[di-]
mov dx, es:[di-]
@@a: stosw
xchg ax, dx
stosw
xchg ax, dx
loop @@a
pop cx
or cx, cx
jz @@
jmp @@
@@:
xchg ax, dx
stosw
xchg ax, dx
stosw
loop @@
@@:
ret

;----------------------------------------------------------------------------
RestoreFloppyParam: ; Mr. Lei //
push es
push ax
xor ax, ax
mov es, ax
mov byte ptr es:[h], 
pop ax
pop es
ret

;---------------------------------------------------------------------------
RestoreCVTchain:
lodsw
cmp ax, 'VC'
jz @@_0
call Beep
ret
@@_0:
push ax
push cx
push es

; -----------------------------------------------------------------
lodsw ; DPB
mov di, ax
lodsw
mov es, ax
@@: lodsb
inc di
stosb
add di, cs:cvtOfs
add di, h
movsw
movsw
les di, es:[di+]
cmp di, -
jnz @@

; -----------------------------------------------------------------
lodsw ; DCB
mov di, ax
lodsw
mov es, ax
xor ax, ax
dec ax
stosw

; -----------------------------------------------------------------
lodsw ; Device Driver Chain
mov di, ax
lodsw
mov es, ax
xor cx, cx
@@: push di
mov cl, 
rep movsw
pop di
les di, es:[di]
mov ax, di
inc ax
jnz @@
pop es
pop cx
pop ax
ret

; ----------------------------------------------------------------------------
RestoreMemoryManager:
test cs:Status, XMSbit
jz @@
call LoadXMSstatus
@@:
test cs:Status, EMSbit
jz @@
call LoadEMSstatus
@@:
ret


LoadEMSstatus:
lodsw
cmp ax, 'ME'
jz @@_0
call Beep
ret
@@_0:
lodsw
mov cx, ax
xor dx, dx
@@_1: push ds
push si
push dx
push cx

@@: cmp dx, ds:[si]
jz @@
add si, 
loop @@

push cx
mov cx, 
@@: mov ah, h ; Deallocate Handle and Memory
int h
or ah, ah
jz @@
loop @@
@@: pop cx

@@:
pop cx
pop dx
pop si
pop ds
inc dx
cmp dx, h
jb @@_1
shl cx, 
shl cx, 
add si, cx
ret


LoadXMSstatus:
lodsw
cmp ax, 'MX'
jz @@_0
call Beep
ret
@@_0:
lodsw
mov cx, ax
jcxz @@
@@:
lodsw
mov dx, ax
@@: push dx
mov ah, ah ; free
call dword ptr cs:xms_control
or ax, ax
pop dx
jnz @@ cmp bl, abh
jnz @@
push dx
mov ah, dh ; unlock
call dword ptr cs:xms_control
or ax, ax
pop dx
jmp @@
@@: loop @@
@@: ret
endp

; -----------------------------------------------------------------------
CloseSpeaker:
in al, h
and al, fch
out h, al
ret

; -----------------------------------------------------------------------
RestoreClockSpeed:
mov al, b
out h, al
xor ax, ax
out h, al
out h, al
ret

; -----------------------------------------------------------------------
ResetDisk:
xor ax, ax
xor dx, dx
int h ; Restore A
inc dx
int h ; Restore B
mov dl, h
int h ; Restore C
ret



; --------------------------------------------------------------------------
ClosePRN:
mov ah, h ; Get PSP seg
int h
mov es, bx
mov ax, es:[h] ; Prev PSP seg
cmp ax, bx
jnz @@
mov ax, h ; COMMAND
mov bx,  int h
@@:
ret

InitPRN:
mov ax, h
mov bx,  ; PRN
int h
mov ax, d01h
mov dx, offset PRNname
push cs
pop ds
int h
ret
PRNname db 'PRN',0

InitMouse: ; // by Mr. Lei
push es
xor ax, ax
mov es, ax
cmp word ptr es:[h4+], 
jz @@ cmp word ptr es:[h4], 
jz @@
mov ax, h
int h ; Hook Mouse Interrupt
@@: pop es
ret

; ------------- CMOS CLOCK set to System -----------------------------------
UpdateTime:
call GetRealTime
mov ah, dh
int h
ret

GetRealTime:
mov ah, int Ah
mov al,ch
call bcdxchg
mov ch,al
mov al,cl
call bcdxchg
mov cl,al
mov al,dh
call bcdxchg
mov dh,al
mov dl,
ret

BCDxchg:
push ax
push cx
mov cl,
shr al,cl
pop cx
mov bl,Ah
mul bl
pop bx
and bl,Fh
add al,bl
ret

; -----------------------------------------------------------------------
; Display string
ColorPrintStr:
lodsb
mov bh, al ; color
xor cx, cx
mov dx, fh
mov ax, h
int h

mov ah,  ; GotoXY (, )
xor dx, dx
mov bh,  int h
PrintStr:
push cs
pop ds
xor bx, bx
@@: lodsb
cmp al, '$'
jz @@
or al, al
jz @@
mov ah, eh
int h
jmp short @@
@@: mov al, cs:clsStrcolor
mov cs:clsStr, al
ret

; -----------------------------------------------------------------------
Self dw 
clsStrcolor db h
clsStr db h ; Color (White in Blue)
db ' RAMinit Version 2.12 (c) 1989-1994 by KingSoft Ltd. Mr. Leijun'
db dh,ah
db ' ['
ShowCopies db ''
db '] Activate...',0ah,0dh,'$'

endTSR equ $
mcbList equ offset endTSR +  + 
vecList equ mcbList +  +  + h +  + h
devLink equ vecList +  +    +  +   h + 
xmsList equ devLink +  + MaxHandles  
emsList equ xmsList +  + 
crtMode equ emsList +  + Dh +  + h
tsrLen equ crtMode + 
;
; DOS Environment Reserved by RI
; --------------------------------------------------
; Flag 'XX' 2 bytes
; Environment Segment  word
; Free MCBs <= bytes
; MCB segment  word
; MCB  bytes
; End flag 'MM' 1 word
; COM LPT ports h bytes
; LEDs status  bytes
; Packed vectors list <=h bytes
; Flag 'CV' 2 bytes
; CVT First DPB pointer  bytes
; DPBs data <= bytes
; First DCB pointer  bytes
; Pointer to NUL  bytes
; All device driver datas <=h10 bytes
; Flag 'XM' 2 bytes
; XMS free handle counter  bytes
; EMS free handle list <=h4 bytes
; Flag 'EM' 2 bytes
; EMS free handle counter  bytes
; EMS free handle list <= bytes
; EMS handle  word
; Number of pages  word
; Flag '--' 1 word
; Equipment List  word
; CRT :h-h dh bytes
; :A8h  dword
; BIOS User Data Area :F0--FF h bytes
; **
;
main: jmp main0

Print Macro Str
Lea dx, Str
call DisplayStr
endm

InstMsg db 'RAMinit Version 2.12 '
db 'Copyright (c) 1989-1994 by KingSoft Ltd. ',0dh,0ah,'$'
Msg0 db 'Already installed !',0dh,0ah,0ah
db 'For Help, type "RI /?". ',0dh,0ah,'$'
Msg_0 db ah,'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 dh,ah,'$'

HelpMsg db 'Programmed by Mr. Leijun Dec 1992', 0dh,0ah,0ah
db 'Usage: RI [options]',0dh,0ah,0ah
db '/H,/? Display this screen',0dh,0ah
db '/CLS Removes all TSR programs after current RI',0dh,0ah
db '/RET Removes TSR programs include current RI',0dh,0ah
db '/NEW Residents a new data copy of current environment',0dh,0ah
db '/ALL Removes all RI copies and all other tsr programs',0dh,0ah
db '/Sxyy.. Define Hotkey x=AuxHotkey yy..=shift status',0dh,0ah
db ' x=auxiliary hotkey (default is "X") ',0dh,0ah
db ' x equ "1" means need AuxHotkey',0dh,0ah
db ' yy..=shift status [CAScas]',0dh,0ah
db ' C: Left Ctrl A: Left Alt S: Left Shift',0dh,0ah
db ' c: Right Ctrl a: Right Alt s: Right Shift',0dh,0ah,0ah
db 'Example: "RI /S1c" means Hotkey is Right_Ctrl+X',0dh,0ah
db ' "RI /S0Cc" means HotKey is Left_Ctrl+Right_Ctrl',0dh,0ah
db ' "RI /CLS" equals simply press hotkey',0dh,0ah
db ' "RI /RET" Removes all TSRs after current RI and this RI',0dh,0ah
db ah
db 'Contact me for RAMinit problems: (01)2561155 Call 1997',0dh,0ah
db '$'
ErrMsg db 'ERROR: Invalid options !',0dh,0ah,0ah,'$'
WinErr db , 'Sorry, I cannot work in Windows DOS environment.',0dh,0ah,'$'
SetMsg db , 'Defines new Hotkey successful !',0dh,0ah,0ah,'$'
tsrOK db False

Main0:
cld
Print instMsg
call IsWinDos
or ax, ax
jz @@
Print WinErr
mov ax, c00h
int h
@@:
call HotKeyValid
mov cs:Status, 
call EMS_test
call CmpDosVer
call CmpSideKick
call GetMachineID
call ModifyHotKeyPrompt

mov ax, c0d7h
int fh
mov es, ax
cmp word ptr es:[h], 'IE' ; 'LEI'
jnz @@
mov cs:Self, ax
@@:
call CmdLine
call PrintHotKeyPrompt

cmp cs:tsrOK, true
jz @@
call tsrReplyOK
@@: cmp cs:tsrOK, true
jnz @@_2
call PrintCopies
@@_2:
mov word ptr cs:[h], 'EL'
mov byte ptr cs:[h], 'I'

push cs
pop es
push cs
pop ds
std
mov si, offset eof
mov cx, eof - offset Here
mov di, tsrLen
add di, cx
inc cx
rep movsb
cld
mov bx, tsrLen
jmp bx

Here:
mov ax,cs
mov es,ax
mov di,offset endTSR
mov cs:DataBegin, di
mov cs:NextDataSeg, -
mov ax, 'XX'
stosw
in al, a1h
mov ah, al
in al, h
push ax
mov word ptr cs:old_8259, ax
xor ax, ax
out h,al ; CLI
call SaveOthers
call SetSelfInt
call BackupVecList
cmp cs:Power, true
jnz @@
call BackupCVTchain
call BackupMemoryManager
@@:
call BackupBiosData

sti
mov cs:Flag, ' ' ; no busy
mov cs:StopFlag,  ;

mov cs:tsrLength, di
call SetDosEnvSeg
cmp cs:Self, 
jz @@
push cs
pop ds
push cs
pop es
cld
mov cx, cs:tsrLength
mov si, cs:DataBegin
sub cx, si
mov di, h
mov cs:DataBegin, di
rep movsb
mov cs:tsrLength, di
@@:
pop ax
out h, al ; STI
mov al, ah
out a1h, al
mov dx, cs:tsrLength
inc dx
int h

; ----------------------------------------------------------------------------
SetDosEnvSeg:
push ds
push es
mov ax, cs
@@: mov es, ax
mov ax, es:[h] ; Get father process psp segment
or ax, ax
jz @@
mov bx, es
cmp ax, bx
jnz @@
@@:
mov es, word ptr es:[ch] ; Get father process env segment
mov cs:DosEnv, es
pop es
pop ds
ret

; ----------------------------------------------------------------------------

SaveOthers:
mov ax, cs:[ch] ; Env Seg
stosw
call backupMCB ; Current MCB
mov ax, h ; COM LPT Port
mov ds, ax
mov si, h
mov cx, 
rep movsw

mov si, h ; LED status
lodsb
stosb
; call OpenLEDs
ret

; --------------------------------------------------------------------------
backupMCB:
mov ax, 'ZM'
stosw
push ds
push es
mov ah, h
int h ; Get MCB chain head
mov ax, es:[bx-]
pop es
@@: mov ds, ax
cmp byte ptr ds:[], 'Z' ; End ?
jz @@ cmp byte ptr ds:[], 'M' ; Memory control block
jnz @@ cmp word ptr ds:[],  ; Nul mcb
jz @@ cmp word ptr ds:[],  ; Free MCB
jnz @@
call SaveFreeMCB
@@: inc ax
add ax, ds:[]
jmp @@
@@:
call SaveFreeMCB
cmp ax, a000h
inc ax
jnb @@
mov ax, fffh ; MS-DOS UMB
jmp @@

@@:
cmp ax, c000h ; MAX
ja @@
mov ax, c020h
jmp @@

@@: ; Error ?
pop ds
mov ax, 'MM' ; Set MCB flag
stosw
ret

SaveFreeMCB:
stosw
xor si,si
movsb
movsw
movsw
ret
;
; push ax
; stosw
; xor si,si
; movsb
; movsw
; movsw
; pop ax
; cmp ax, fffh
; jnb @@
; push ax
; push ds
; mov ds,ax
; cmp byte ptr ds:[], 'M'
; pop ds
; pop ax
; jnz @@
; mov ax, fffh ; MS-DOS UMB
; jmp @@
; @@: cmp ax, c000h
; ja @@
; mov ax, c020h ; MAX
; jmp @@
;
; --------------------------------------------------------------------------

OpenLEDs: push ax ; Open all LEDs
or al, h
mov ds:[h], al
mov ah,  int h
mov cx,  ; Delay
@@: push cx
xor cx, cx
@@: loop @@
pop cx
loop @@
pop ax
mov ds:[h], al
mov ah,  int h
ret

; --------------------------------------------------------------------------
SetSelfInt:
push es
push di

cmp cs:self, 
jnz @@
push cs
pop ds
mov ax,h
int h
mov word ptr cs:oldInt9_addr,bx
mov word ptr cs:oldInt9_addr[],es
mov dx,offset NewInt9
mov ax,h
int h

mov ax,Fh
int h
mov word ptr cs:oldInt2F_addr,bx
mov word ptr cs:oldInt2F_addr[],es
mov dx,offset newInt2F
mov ax,Fh
int h

mov ax,Ch
int h
mov word ptr cs:oldInt1C_addr,bx
mov word ptr cs:oldInt1C_addr[],es
mov dx,offset newInt1C
mov ax,ch
int h
cli
jmp @@
@@:
mov es, cs:Self
inc es:Copies
@@_0: cmp es:NextDataSeg, -
jz @@_1
mov es, es:NextDataSeg
jmp @@_0
@@_1: mov es:NextDataSeg, cs
@@:
pop di
pop es
ret

; -----------------------------------------------------------------------
SaveCounter:
mov word ptr es:[di], 'EL'
mov byte ptr es:[di+], 'I'
mov byte ptr es:[di+], bl
xor bx, bx
add di, 
ret

; -----------------------------------------------------------------------
DisplayStr: push cs
pop ds
mov ah,  int h
ret

; -----------------------------------------------------------------------
CmdLine:
push cs
pop ds
xor ax, ax
mov si, h
lodsb
or al, al
jnz @@
ret
@@:
mov cx, ax
dec ax
push ax
push si
@@: lodsb
cmp al, ' '
jz @@ cmp al, '/'
jnz @@
lodsb
cmp al, 'S'
jz @@_2
cmp al, 's'
jnz @@
@@_2:
call SetHotKey
Print SetMsg
mov ax, c00h
int h
@@:
pop si
pop ax
push ax
push si
@@_3: lodsb
cmp al, 'A'
jb @@ cmp al, 'Z'
ja @@
add byte ptr ds:[si-],h ; DownCase
@@: loop @@_3
pop si
pop cx

add si, cx
lodsb
cmp al, 's' ; CLS
jnz @@ cmp word ptr ds:[si-], 'lc'
jnz @@ cmp cs:Self, 
jz @Err
mov ax, c0d7h+ int fh

@@: cmp al, 'h' ; HELP
jz @help
cmp al, '?'
jz @help
cmp al, 't' ; RET
jnz @@ cmp word ptr ds:[si-], 'er'
jnz @@
@@:
cmp cs:Self, 
jz @Err
mov ax, c0d7h+ int fh
@@: cmp al, 'w' ; NEW
jnz @@ cmp word ptr ds:[si-], 'en'
jnz @@
mov cs:tsrOK, true
ret
@@:
cmp al, 'l' ; ALL
jnz @@ cmp word ptr ds:[si-], 'la'
jnz @@
mov ax, c0d7h+ int fh
@@:
cmp al, ' '
jnz @Err
ret

@Err:
Print ErrMsg
@help:
Print HelpMsg
mov ax, c00h
int h

;---------------------------------------------------------------------------
tsrReplyOK:
cmp cs:Self, 
jz @@
Print Msg0

push es
mov ax, cs:Self
@@_10: mov es, ax
mov ax, es:NextDataSeg
cmp ax, -
jnz @@_10
mov ax, es

@@_0: push ax
dec ax
mov es, ax
mov bx, es:[]
pop ax

add ax, bx
inc ax
mov es, ax
cmp word ptr es:[], 'OC'
jz @@_0

mov bx, cs
cmp ax, bx
pop es
jz @@
Print Msg_0
mov ah,  int h

push ax
Print crlf
pop ax

cmp al, 'y'
jz @@ cmp al, 'Y'
jz @@
@@: ; Print Msg_1
mov ax, c01h
int h
@@:
@@: mov cs:tsrOK, true
ret

PrintCopies:
cmp cs:Self, 
jz @@
push es ; Added -by- Mr. Lei
mov es, cs:Self ; Aug , 
mov al, es:Copies
inc al ; Total RI copies
push ax ; Set es = current mcb
mov ax, cs
dec ax
mov es, ax
pop ax
mov cx,  ; Search end of file name
mov bx, 
@@: inc bx
cmp byte ptr es:[bx], h
jz @@ cmp byte ptr es:[bx], ffh
jz @@ cmp byte ptr es:[bx], h
jz @@
loop @@
@@: ; Set current RI no
mov byte ptr es:[bx], ':' ; "RI:2"
mov byte ptr es:[bx+], al
cmp bx, +
jnb @@
mov byte ptr es:[bx+], 
@@:
pop es

mov cs:Msg_RI, al
Print Msg_2
@@: ret

;---------------------------------------------------------------------------
; Backup Interrupt Vector List
;
BackupVecList:
push ds
push cs
pop es
xor si,si ; Vectors
mov ds,si
movsw
movsw
xor bx, bx
mov cx,ffh
@@: lodsw
xchg dx, ax
lodsw
cmp ax, es:[di-]
jnz @@ cmp dx, es:[di-]
jz @@
@@: or bx, bx
jz @@
call SaveCounter
@@: xchg dx, ax
stosw
xchg dx, ax
stosw
loop @@
jmp @@
@@: inc bx
loop @@
call SaveCounter
@@:
pop ds
ret
;
;-----------------------------------------------------------------------------
BackupCVTchain:
mov ax, 'VC'
stosw
push ax
push bx
push cx
push ds
push es
mov ah, h
int h ; ES:BX -- DOS table as described below

; --------------------------------------------------------------------
push es ; DPB chains
push bx
lds si, es:[bx]
push cs
pop es
mov ax, si
stosw
mov ax, ds
stosw
mov bx, cs:cvtOfs
xor cx, cx
@@: mov al, ds:[si+]
stosb
mov ax, ds:[si+bx+h]
stosw
mov ax, ds:[si+bx+h]
stosw
inc cx
lds si, ds:[si+bx+h]
cmp si, -
jnz @@
; mov ax, 
; mul cl
; add ax, 
; add cs:tsrLength, ax
pop bx
pop es

; --------------------------------------------------------------------
push es ; DCB file control blocks
push bx
les bx, es:[bx+]
@@: cmp word ptr es:[bx], -
jz @@
les bx, es:[bx]
jmp @@
@@:
mov ax, es
xchg ax, bx
push cs
pop es
stosw
xchg ax, bx
stosw
pop bx
pop es
; add cs:tsrLength, 

; ---------------------------------------------------------------------
push es ; Device Driver Chains
pop ds
add bx, h
mov si, bx ; NUL

pop es
mov ax, si
stosw
mov ax, ds
stosw
xor cx, cx
xor bx, bx
@@: push si
mov cl, 
rep movsw
inc bx
pop si
lds si, ds:[si]
mov ax, si
inc ax
jnz @@

pop ds
pop cx
pop bx
pop ax
ret

; ----------------------------------------------------------------------------

BackupBiosData:
mov ax, '--'
stosw
push ds
push si
mov si, h
mov ds, si
mov si, h
movsw
mov si, a8h
movsw
movsw
mov si, h
mov cx, dh
rep movsb

mov si, f0h
mov cx, 
rep movsw
pop si
pop ds
ret

; ---------------------------------------------------------------------------

BackupMemoryManager:
push cs
pop es
push ds
push es
call SaveXMSstatus
call SaveEMSstatus
pop es
pop ds
ret

;---------------------------------------------------------------------

SaveEMSstatus:
test cs:status, EMSbit
jnz @@
ret
@@:
mov ax, 'ME'
stosw
inc di
inc di
push di
mov ah, dh
int h
pop di
mov es:[di-], bx
shl bx, 
shl bx, 
add di, bx
ret
; -------------------------------------------------------------------

SaveXMSstatus:
call XMS_test
test cs:status, XMSbit
jnz @@
ret
@@:
mov ax, 'MX'
stosw

mov dx, 
call XMS_alloc
jnz @@_1
xor cx, cx ; XMS alloc failure
stosw
ret
@@_1:
push dx
sub dx, MaxHandles  
@@:
push dx
call XMS_Lock
pop dx
jnz @@ cmp bl, a2h
jnz @@
add dx, 
jmp @@
@@: push dx
call XMS_unlock
pop dx
@@:
mov cs:handle_begin, dx
pop dx
push dx
call XMS_bstat
xor cx, cx
mov cl, bl
inc cx
pop dx
call XMS_Free
mov dx, cs:Handle_begin

push cx
push cs
pop es
mov ax, cx
stosw
@@: push dx
call XMS_Lock
pop dx
jnz @@ cmp bl, a2h ; Handle invalid
jz @@
@@: call XMS_unlock
add dx, 
jmp @@
@@: mov ax, dx
stosw
add dx, 
loop @@
pop cx
ret
; ------------------------------------------------------------------

XMS_test:
push es
mov ax, h
int fh
cmp al, h
jnz @@
mov ax, h
int fh
mov cs:XMS_control, bx
mov cs:XMS_control[], es
or cs:Status, XMSbit
@@:
pop es
ret

XMS_stat:
mov ah, 
call dword ptr cs:xms_control
mov hma_exist, dl
ret
hma_exist db 

XMS_alloc:
mov ah, 
call dword ptr cs:xms_control
or ax, ax
ret

XMS_lock:
mov ah, ch
call dword ptr cs:xms_control
or ax, ax
ret

XMS_unlock:
mov ah, dh
call dword ptr cs:xms_control
or ax, ax
ret
XMS_bstat:
mov ah, eh
call dword ptr cs:xms_control
or ax, ax
ret

XMS_free:
mov ah, ah
call dword ptr cs:xms_control
or ax, ax
ret

; ----------------------------------------------------------------------------
EMS_test:
push cs
pop ds
mov dx, offset EMMname
mov ax, d00h
int h
jc @@
mov bx, ax
mov ah, eh
int h
or cs:Status, EMSbit
@@:
ret
EMMname db 'EMMXXXX0',0

; -----------------------------------------------------------------------------

SetHotKey:
xor bx, bx
lodsb
push ax

@@: lodsb
cmp al, dh
jz @@ cmp al, 'C'
jnz @@
or bl, LeftCtrl
jmp @@
@@:
cmp al, 'c'
jnz @@
or bl, RightCtrl
jmp @@
@@:
cmp al, 'A'
jnz @@
or bl, LeftAlt
jmp @@
@@:
cmp al, 'a'
jnz @@
or bl, RightAlt
jmp @@
@@:
cmp al, 'S'
jnz @@
or bl, LeftShift
jmp @@
@@:
cmp al, 's'
jnz @@
or bl, RightShift
jmp @@
@@: pop ax
jmp @Err
@@:
mov cs:HotKey, bl
pop ax
mov cs:AuxHotKey, dh ; 'X' scan key
cmp al, '1'
jz @@
mov cs:AuxHotKey, 
@@:
cmp cs:Self, 
jz @@
push es
mov es, cs:Self
mov es:HotKey, bl
mov bl, cs:AuxHotKey
mov es:AuxHotKey, bl
pop es
@@:
call GetRunFileName
mov ax, d02h
int h
jc @@
push cs
pop ds
mov bx, ax
mov cx, 
mov dx, h
mov ah, h
int h
jc @@
mov ax, h
xor cx, cx
mov dx, h
int h
jc @@
mov cx, 
mov dx, offset AuxHotKey
mov ah, h
int h
jc @@
mov ah, eh
int h
@@:
ret


; -----------------------------------------------------------------------
GetRunFileName:
; Return:
; DS:DX Pointer of this run file name ASCIIZ string
push ax
push bx
push cx
push si
push di
push es

push cs
pop es
mov ax, es:[ch]
mov es, ax
xor di, di
mov cx, h
xor al, al
@@: repnz scasb
cmp es:[di], al
loopnz @@
mov dx, di
add dx, 
push es
pop ds

pop es
pop di
pop si
pop cx
pop bx
pop ax
ret

; ---------------------------------------------------------------------------
GetMachineID:
push es
mov KBD102,True
mov ax,h
mov es,ax
test byte ptr es:[h], b
jnz @@
mov Kbd102,False
@@:
xor ax,ax
dec ax
mov es,ax
mov al,es:[eh]
mov cs:MachineID, al
pop es
ret

; ---------------------------------------------------------------------------
ModifyHotKeyPrompt:
cmp cs:Kbd102, True
jz @@
push cs
pop es
push cs
pop ds
mov cx, 
mov si, offset KMsg2
mov di, offset KMsg1
rep movsb
@@: cmp cs:MachineID, fch
jna @@
mov cs:clsStrcolor, h ; Mono
mov cs:clsStr, h
@@:
ret

; ---------------------------------------------------------------------------
PrintHotKeyPrompt:
Print Msg1
mov al, cs:HotKey
mov ah, al
shr al, 
shr al, 
and ax, ch
or al, ah
mov dx, offset KeyMsg
@@:
or ax, ax ; Mr. Lei //
jz @@_42
shr al, 
push ax
jnc @@

push ax
call ColorDisplayStr
; mov ah, 
; int h
pop ax

or al, al
jz @@

push dx
mov dx, offset PlusMsg
call ColorDisplayStr
; Print PlusMsg
pop dx

@@: add dx, 
pop ax
jmp @@
@@: pop ax
@@_42: cmp cs:AuxHotKey, 
jz @@ cmp cs:HotKey,  ; Mr. Lei
jz @@_43
mov dx, offset PlusMsg
call ColorDisplayStr
; Print PlusMsg
@@_43: mov dx, offset AuxHotKeyName
call ColorDisplayStr
; Print AuxHotKeyName
@@:
Print crlf
ret

ColorDisplayStr:
push bx
push cx
push dx
push si
mov bl, fh
mov si, dx
xor bh, bh
mov cx, 
@@: lodsb
cmp al, '$'
jz @@
or al, al
jz @@
push cx
mov ah, h
int h
mov ah,  int h
inc dl
mov ah,  int h
pop cx
jmp short @@
@@:
pop si
pop dx
pop cx
pop bx
ret

; ---------------------------------------------------------------------------
CmpSideKick:
xor ax, ax
mov es, ax
les bx, es:[h]
cmp word ptr es:[bx-], b53h
jnz @@ cmp word ptr es:[bx-], h
jz @@
@@: mov es, ax
les bx, es:[h]
cmp word ptr es:[bx-], b53h
jz @@
ret
@@: or cs:Status, SKbit
ret

; ---------------------------------------------------------------------------
CmpDosVer: mov ah, h
int h
cmp al, 
jb @@ cmp al, 
jna @@
mov cs:cvtOfs, 
ret
@@: mov cs:cvtOfs, 
ret
@@: Print DosVerErr
mov ax, cffh
int h

DosVerErr db 'Sorry, DOS version too lower !',0dh,0ah,'$'

HotKeyValid:
cmp cs:HotKey, 
jnz @@_1
cmp cs:AuxHotKey, 
jnz @@_1
Print HotKeyErr
mov ax, cfeh
int h
@@_1: ret

HotKeyErr db 'Sorry, please setup hotkey again. ',0dh,0ah,'$'

eof:
ends
end Start

; ------------- The End ! ---------------------------------------------------