home *** CD-ROM | disk | FTP | other *** search
- ; ▄┌═════════════════┐▄ ;
- ; ─══╣│ CPUidle for DOS │╠══─ ;
- ; ▀└─────────────────┘▀ ;
-
-
- ;[KERNEL CHARACTERISTICS]
- ; Kernel name: CPUidle for DOS.
- ; Kernel version: V2.10 [Build 0077]
- ; Programming stage: Working version, Under development.
- ; Last modified: 1998 May 07.
-
- ;[NOTES]
- ; Ralphs intlist -> more idle possibilities.
-
-
-
- ;╔══════════════════════════════════════════════════════════════════════════╗;
- ;║ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ RESIDENT PART OF PROGRAM ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ║;
- ;╚══════════════════════════════════════════════════════════════════════════╝;
- ;────────────────────────────────────────────────────────────────────────────;
- ;░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒ GLOBAL CODE & DATA FOR ALL HANDLERS ▒▒▒▒▒▒▒▒▒▒░░░░░░░░░;
- ;────────────────────────────────────────────────────────────────────────────;
-
- ideal ; Yep, this prog is TASM 4.0 coded!
- include "_stddata.ah"
- include "_tsrres.ah"
- include "_dcon.ah"
-
-
- ;════════════════════════════════════════════════════════════════════════════;
-
-
- Struct qk_item
- prog db 12 dup (0), 0 ; Name of the child process.
- hooknum db 0 ; Number of FN hooks.
- execnum dw 0 ; "PID number" of child.
- Ends
-
- Struct qk_hook
- fnaddr dw 0 ; Address of FN to hook.
- newaddr dw 0 ; New address of the FN.
- oldaddr dw 0 ; Old address of the FN.
- Ends
-
-
- ;════════════════════════════════════════════════════════════════════════════;
-
-
- MODE_OPTIMIZE = 01h ; Set if CPU optimization selected.
- MODE_HLT = 02h ; Set if normal HLT method selected.
- MODE_APM = 04h ; Set if APM cooling method selected.
- MODE_NOFORCE = 08h ; Set if any FORCE MODE is disabled.
- MODE_WFORCE = 10h ; Set if WEAK FORCE strategy selected.
- MODE_SFORCE = 20h ; Set if STRONG FORCE strategy selected.
-
- IRQ_00 = 01h ;
- IRQ_01 = 02h ;
- IRQ_02 = 04h ;
- IRQ_03 = 08h ;
- IRQ_04 = 10h ;
- IRQ_05 = 20h ; Flag set if that specific IRQ was
- IRQ_06 = 40h ; invoked. Should later be cleared by
- IRQ_07 = 80h ; kernel...
-
- INT_XXH_FORCE = 300 ; # of calls to FN before forced HLT.
-
-
- ;════════════════════════════════════════════════════════════════════════════;
-
-
- RESIDENTDATA begin
-
- Align 4
- int_xxh_fcount dd 0 ; # int xxh FN(x) called repeatedly.
-
- mode_flags db MODE_SFORCE ; Config flags for program startup.
- irq_flags db 0 ; IRQ flags for kernel.
-
- quirk_table qk_item <"NC.EXE", 1, 0>
- qk_hook <int_21h_fntable + 2ch * 2, int_xxh_forcehlt, int_xxh_zerocount>
- qk_item <"SCANDISK.EXE", 1, 0>
- qk_hook <int_21h_fntable + 0bh * 2, int_xxh_zerocount, int_xxh_forcehlt>
- QK_ITEMS = 2
-
- exec_calls dw 200 ; Count of DOS FN 4bh calls.
- child_name db 13 dup (0) ; Name of the child to be executed.
-
- RESIDENTDATA end
-
-
- ;════════════════════════════════════════════════════════════════════════════;
-
-
- RESIDENTCODE begin
-
- Proc _str_cmp ; NOTE: Copied from _string.h!!
- push ax cx si di
-
- mov cx,DEF_STR_LEN ; CX = default string length.
- @@cmp: mov al,[ds:si] ; Read char from string #1.
- cmp al,[es:di] ; Char (#1) == char (#2)?
- jne short @@done ; Nope, strings can't be equal.
-
- test al,al ; Done (char (#1) = char (#2) = 0)?
- jz short @@done ; Yes, string are equal.
-
- inc si ;
- inc di ;
- loop @@cmp ; Continue.
-
- @@done: pop di si cx ax
- ret
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
- Proc int_xxh_forcehlt
- inc [int_xxh_fcount] ; Increase force counter.
- cmp [int_xxh_fcount],INT_XXH_FORCE ; Over the minimum?
- jb short @@done ; Nah, don't HLT yet.
-
- mov [irq_flags],0 ; Clear IRQ flags.
- sti ; Enable IRQs for following HLT.
-
- test [mode_flags],MODE_APM ; APM usage requested?
- jnz short @@apm ; Yes.
-
- ;- - - - - - - - - - -;
- @@std: test [mode_flags],MODE_SFORCE ; Running under STRONG FORCE mode?
- jnz short @@stds ; Yes.
-
- @@stdw: hlt ; Enter power saving mode.
- ret ; Fast exit.
-
- @@stds: and [irq_flags],not IRQ_00 ; Clear IRQ0 occurred flag.
- hlt ; Enter power saving mode.
-
- cmp [irq_flags],IRQ_00 ; Was it IRQ0 (timer) ONLY?!
- je @@stds ; Yes, go back HLTing.
- ret ; Fast exit.
- ;- - - - - - - - - - -;
-
- ;- - - - - - - - - - -;
- @@apm: test [mode_flags],MODE_SFORCE ; Running under STRONG FORCE mode?
- jnz short @@apms ; Yes.
-
- @@apmw: mov ax,5305h ;
- pushf ;
- call [dword old_int_15h] ; Call APM FN to put the CPU idle.
- ret
-
- @@apms: and [irq_flags],not IRQ_00 ; Clear IRQ0 occurred flag.
- mov ax,5305h ;
- pushf ;
- call [dword old_int_15h] ; Call APM FN to put the CPU idle.
-
- cmp [irq_flags],IRQ_00 ; Was it IRQ0 (timer) ONLY?!
- je @@apms ; Yes, go back HLTing.
- ;- - - - - - - - - - -;
- @@done: ret
- Endp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- Proc int_xxh_zerocount ; Zero ALL FORCE counters.
- mov [int_xxh_fcount],0 ; Zero int xxh force counter.
- ret
- Endp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- Proc int_xxh_skip ; Skip ALL FORCE counter updates.
- ret
- Endp
-
- RESIDENTCODE end
-
-
-
- ;────────────────────────────────────────────────────────────────────────────;
- ;░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒ INT 21H HANDLER ▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░;
- ;────────────────────────────────────────────────────────────────────────────;
-
- INT_21H_TOPFN = 4ch ; Highest FN that is handled.
-
-
- ;════════════════════════════════════════════════════════════════════════════;
-
-
- RESIDENTDATA begin
-
- Align 4
- old_int_21h rmdw <0, 0>
-
- int_21h_fntable dw int_xxh_zerocount ; FN 00h: Terminate.
- dw int_21h_normalhlt ; FN 01h: Keyboard input.
- dw int_xxh_zerocount ; FN 02h: Display char.
- dw int_xxh_skip ; FN 03h: Auxiliary input.
- dw int_xxh_zerocount ; FN 04h: Auxiliary output.
- dw int_xxh_zerocount ; FN 05h: Printer output.
- dw int_21h_fn06h ; FN 06h: Console I/O.
- dw int_21h_normalhlt ; FN 07h: No echo unfiltered input.
- dw int_21h_normalhlt ; FN 08h: No echo input.
- dw int_xxh_zerocount ; FN 09h: Display string.
- dw int_xxh_skip ; FN 0ah: Buffered input.
- dw int_xxh_forcehlt ; FN 0bh: "Keypressed?"
- dw int_xxh_skip ; FN 0ch: Clear buffer and input.
- dw 24h dup (int_xxh_zerocount) ; FNs 0dh - 30h.
- dw int_21h_fn31h ; FN 31h: Terminate and Stay Resident.
- dw 19h dup (int_xxh_zerocount) ; FNs 32h - 4ah.
- dw int_21h_fn4bh ; FN 4bh: Execute child process.
- dw int_21h_fn4ch ; FN 4ch: Terminate child process.
-
- RESIDENTDATA end
-
-
- ;════════════════════════════════════════════════════════════════════════════;
-
-
- RESIDENTCODE begin
-
- Proc int_21h_fn06h ; DOS FN: Console I/O.
- cmp dl,0ffh ; "Keypressed?" function requested?
- jne short @@done ; No.
-
- jmp [int_21h_fntable + 0bh * 2] ; Force HLT (as FN 0bh does it).
- @@done: ret
- Endp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- Proc int_21h_fn31h ; DOS FN: Terminate and Stay Resident.
- jmp int_21h_fn4ch ; Same as standard exit...
- Endp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- Proc int_21h_fn4bh ; DOS FN: Execute child process.
- pusha
- push es ;
- mov bp,sp ; BP = ptr to entry DS on stack.
-
- inc [exec_calls] ; Increase count of exec calls.
-
- test al,al ; Load and execute child?
- jnz short @@done ; No, no work for us.
-
- mov ax,[ss:bp + 2 + 16 + 2] ; Get DS from stack.
- mov es,ax ;
- mov di,dx ; ES:DI = caller's DS:DX = child name.
-
- ;- - - - - - - - - - -;
- lea si,[child_name] ; DS:SI = target buffer for child name.
- xor bx,bx ; BX = index of char at [DS:SI].
-
- @@read: mov al,[es:di] ; Get char of child name in int 21h.
- mov [ds:si + bx],al ; Save it to our buffer.
-
- cmp al,':' ; Was it a DRIVE specifier?
- je short @@kill ; Yes.
-
- cmp al,'\' ; Was it a PATH separator?
- jne short @@next ; No.
-
- @@kill: mov bx,-1 ; Restart savig to buffer...
-
- @@next: inc di ;
- inc bx ; Advance index pointers.
- test al,al ; At end of ASCIIZ filename?
- jnz @@read ; No.
- ;- - - - - - - - - - -;
-
- ;- - - - - - - - - - -;
- lea bx,[quirk_table] ; BX = ptr to table of quirky programs.
- mov cx,QK_ITEMS ; CX = number of entries in table.
- lea di,[child_name] ;
- mov ax,ds ;
- mov es,ax ; ES:DI = ptr to ASCIIZ name of child.
-
- @@find: lea si,[(qk_item bx).prog] ; SI = ptr to quirky child name.
- call _str_cmp ; Is this child being executed?
- je short @@set ; Yes, handle it.
-
- mov al,[(qk_item bx).hooknum] ; AL = number of FN hooks.
- mov ah,size qk_hook ; AH = size of one FN hook.
- mul ah ; AX = value to increment BX with.
-
- add bx,ax ;
- add bx,size qk_item ;
- loop @@find ; Continue.
- jmp short @@done ; Child is NOT a quirky program, done.
- ;- - - - - - - - - - -;
-
- ;- - - - - - - - - - -;
- @@set: mov ax,[exec_calls] ;
- mov [(qk_item bx).execnum],ax ; Save "PID" of this quirky program.
-
- xor ch,ch ;
- mov cl,[(qk_item bx).hooknum] ; CX = number of hooks to install.
- add bx,size qk_item ; BX = ptr to first hook data.
-
- test cl,cl ; No hooks needed?
- jz short @@done ; Yes, crazy but quit...
-
- @@hook: mov si,[(qk_hook bx).fnaddr] ; SI = address of FN to hook.
- mov ax,[ds:si] ; Get old FN handler.
- mov [(qk_hook bx).oldaddr],ax ; Save it.
-
- mov ax,[(qk_hook bx).newaddr] ; Get new address for FN handler.
- mov [ds:si],ax ; Hook FN.
-
- add bx,size qk_hook ;
- loop @@hook ; Continue.
- ;- - - - - - - - - - -;
-
- @@done: pop es
- popa
- ret
- Endp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- Proc int_21h_fn4ch ; DOS FN: Terminate child process.
- pusha
- lea bx,[quirk_table] ; BX = ptr to table of quirky programs.
- mov cx,QK_ITEMS ; CX = number of entries in table.
-
- ;- - - - - - - - - - -;
- @@find: mov ax,[(qk_item bx).execnum] ; Get "PID" of saved program.
- cmp ax,[exec_calls] ; Is it this program?
- je short @@set ; Yes, handle it.
-
- mov al,[(qk_item bx).hooknum] ; AL = number of FN hooks.
- mov ah,size qk_hook ; AH = size of one FN hook.
- mul ah ; AX = value to increment BX with.
-
- add bx,ax ;
- add bx,size qk_item ;
- loop @@find ; Continue.
- jmp short @@done ; Finish, program wasn't found.
- ;- - - - - - - - - - -;
-
- ;- - - - - - - - - - -;
- @@set: xor ch,ch ;
- mov cl,[(qk_item bx).hooknum] ; CX = number of hooks to deinstall.
- add bx,size qk_item ; BX = ptr to first hook data.
-
- test cl,cl ; No hooks needed?
- jz short @@done ; Yes, crazy but quit...
-
- @@unhk: mov si,[(qk_hook bx).fnaddr] ; SI = address of FN to unhook.
- mov ax,[(qk_hook bx).oldaddr] ; Get old FN handler.
- mov [ds:si],ax ; Restore original handler.
-
- add bx,size qk_hook ;
- loop @@unhk ; Continue.
- ;- - - - - - - - - - -;
-
- @@done: dec [exec_calls]
- popa
- ret
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Proc int_21h_normalhlt
- sti ; Enable IRQs for following HLT.
- mov ah,0bh ; Int 21h FN: "Keypressed?".
-
- test [mode_flags],MODE_APM ; APM usage requested?
- jnz short @@apml ; Yes.
-
- @@stdl: hlt ; Enter power saving mode.
- pushf ;
- call [dword old_int_21h] ; Simulate int 21h without reentrancy.
-
- cmp al,0ffh ; Keystroke ready?
- jne @@stdl ; No, continue HLTing.
- jmp short @@done ; Finish.
-
- @@apml: mov ax,5305h ;
- pushf ;
- call [dword old_int_15h] ; Call APM FN to put the CPU idle.
-
- mov ah,0bh ; Int 21h FN: "Keypressed?"
- pushf ;
- call [dword old_int_21h] ; Simulate int 21h without reentrancy.
-
- cmp al,0ffh ; Keystroke ready?
- jne @@apml ; No, continue HLTing.
- @@done: ret
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Align 16
- Proc int_21h_handler ; DOS functions handler.
- push ax bx ds
- mov bx,cs ;
- mov ds,bx ; CODE = DATA.
-
- cmp ah,INT_21H_TOPFN ; FN irrelevant for our handler?
- ja short @@old ; Yes, zero force counter and chain.
-
- xor bh,bh ;
- mov bl,ah ;
- add bx,bx ; BX = index to int_21h_fntable.
- add bx,offset int_21h_fntable ; BX = offset of handler.
-
- call [word bx] ; Call the appropriate FN handler.
- jmp short @@oldn ; Chain without zeroing force count.
-
- @@old: mov [int_xxh_fcount],0 ; Zero int xxh force counter.
-
- @@oldn: pop ds bx ax
- jmp [dword cs:old_int_21h] ; Chain to old interrupt handler.
- Endp
-
- RESIDENTCODE end
-
-
-
- ;────────────────────────────────────────────────────────────────────────────;
- ;░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒ INT 16H HANDLER ▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░;
- ;────────────────────────────────────────────────────────────────────────────;
-
- INT_16H_TOPFN = 12h ; Highest FN that is handled.
-
-
- ;════════════════════════════════════════════════════════════════════════════;
-
-
- RESIDENTDATA begin
-
- Align 4
- old_int_16h rmdw <0, 0>
-
- int_16h_fntable dw int_16h_normalhlt ; FN 00h: Keyboard input.
- dw int_xxh_forcehlt ; FN 01h: "Keypressed?".
- dw int_xxh_forcehlt ; FN 02h: "SHIFT Keypressed?".
- dw 0dh dup (int_xxh_zerocount) ; FNs 03h - 09h.
- dw int_16h_normalhlt ; FN 10h: Keyboard input (101-keys).
- dw int_xxh_forcehlt ; FN 11h: "Keypressed?" (101-keys).
- dw int_xxh_forcehlt ; FN 12h: "SHIFT Keypressed?" (101).
-
- RESIDENTDATA end
-
-
- ;════════════════════════════════════════════════════════════════════════════;
-
-
- RESIDENTCODE begin
-
- Proc int_16h_normalhlt
- inc ah ; Int 16h FN: Is keystroke ready?
- mov bh,ah ; Save AH (FN number).
- sti ; Enable IRQs for following HLT.
-
- test [mode_flags],MODE_APM ; APM usage requested?
- jnz short @@apml ; Yes.
-
- @@stdl: pushf ;
- call [dword old_int_16h] ; Simulate int 16h without reentrancy.
- jnz short @@done ; If ZF == 0 then key is ready.
-
- hlt ; Enter power saving mode.
-
- mov ah,bh ; Restore saved AH (FN number).
- jmp @@stdl
-
- @@apml: pushf ;
- call [dword old_int_16h] ; Simulate int 16h without reentrancy.
- jnz short @@done ; If ZF == 0 then key is ready.
-
- mov ax,5305h ;
- pushf ;
- call [dword old_int_15h] ; Call APM FN to put the CPU idle.
-
- mov ah,bh ; Restore saved AH (FN number).
- jmp @@apml ; No, continue HLTing.
- @@done: ret
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Align 16
- Proc int_16h_handler ; BIOS keyboard functions handler.
- push ax bx ds
- mov bx,cs ;
- mov ds,bx ; CODE = DATA.
-
- cmp ah,INT_16H_TOPFN ; FN irrelevant for our handler?
- ja short @@old ; Yes, zero force counter and chain.
-
- xor bh,bh ;
- mov bl,ah ;
- add bx,bx ; BX = index to int_16h_fntable.
- add bx,offset int_16h_fntable ; BX = offset of handler.
-
- call [word bx] ; Call the appropriate FN handler.
- jmp short @@oldn ; Chain without zeroing force count.
-
- @@old: mov [int_xxh_fcount],0 ; Zero int xxh force counter.
-
- @@oldn: pop ds bx ax
- jmp [dword cs:old_int_16h] ; Chain to old interrupt handler.
- Endp
-
- RESIDENTCODE end
-
-
-
- ;────────────────────────────────────────────────────────────────────────────;
- ;░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒ INT 2FH HANDLER ▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░;
- ;────────────────────────────────────────────────────────────────────────────;
-
- INT_2FH_TOPFN = 0ffffh ; Highest FN that is handled.
-
-
- ;════════════════════════════════════════════════════════════════════════════;
-
-
- RESIDENTDATA begin
-
- Align 4
- old_int_2fh rmdw <0, 0>
-
- RESIDENTDATA end
-
-
- ;════════════════════════════════════════════════════════════════════════════;
-
-
- RESIDENTCODE begin
-
- Align 16
- Proc int_2fh_handler
- push dx ds
- mov dx,cs ;
- mov ds,dx ; CODE = DATA.
-
- cmp ax,1680h ; DPMI release time slice?
- je short @@dpmi ; Yes.
-
- cmp ax,1607 ; Windows VMPoll Idle callout?
- jne short @@old ; No, exit.
-
- @@vmpl: cmp bx,0018h ; Is it the VMPoll VxD ID number?
- jne short @@old ; No, exit.
-
- test cx,cx ; Is it the VMPoll driver?
- jnz short @@old ; No, exit.
-
- @@dpmi: call int_xxh_forcehlt ; Enter power saving mode.
- jmp short @@oldn ; Chain without zeroing force count.
-
- @@old: mov [int_xxh_fcount],0 ; Zero int xxh force counter.
-
- @@oldn: pop ds dx
- jmp [dword cs:old_int_2fh] ; Chain to old interrupt handler.
- Endp
-
- RESIDENTCODE end
-
-
-
- ;────────────────────────────────────────────────────────────────────────────;
- ;░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒ INT 14H HANDLER ▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░;
- ;────────────────────────────────────────────────────────────────────────────;
-
- INT_14H_TOPFN = 03h ; Highest FN that is handled.
-
-
- ;════════════════════════════════════════════════════════════════════════════;
-
-
- RESIDENTDATA begin
-
- Align 4
- old_int_14h rmdw <0, 0>
-
- int_14h_fntable dw int_xxh_zerocount ; FN 00h: Init COM port.
- dw int_xxh_zerocount ; FN 01h: Send char to COM port.
- dw int_14h_normalhlt ; FN 02h: Read char from COM port.
- dw int_xxh_forcehlt ; FN 03h: "Char ready?"
-
- RESIDENTDATA end
-
-
- ;════════════════════════════════════════════════════════════════════════════;
-
-
- RESIDENTCODE begin
-
- Proc int_14h_normalhlt
- sti ; Enable IRQs for following HLT.
-
- test [mode_flags],MODE_APM ; APM usage requested?
- jnz short @@apml ; Yes.
-
- @@stdl: hlt ; Enter power saving mode.
- mov ah,03h ; Int 14h FN: Get serial port status.
- pushf ;
- call [dword old_int_14h] ; Simulate int 14h without reentrancy.
-
- test ah,1 ; Is data ready?
- jz @@stdl ; No, continue loop.
- jmp short @@done ; Finish.
-
- @@apml: mov ax,5305h ;
- pushf ;
- call [dword old_int_15h] ; Call APM FN to put the CPU idle.
-
- mov ah,03h ; Int 14h FN: Get serial port status.
- pushf ;
- call [dword old_int_14h] ; Simulate int 14h without reentrancy.
-
- test ah,1 ; Is data ready?
- jz @@apml ; No, continue loop.
- @@done: ret
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Align 16
- Proc int_14h_handler ; BIOS serial I/O handler.
- push ax bx ds
- mov bx,cs ;
- mov ds,bx ; CODE = DATA.
-
- cmp ah,INT_14H_TOPFN ; FN irrelevant for our handler?
- ja short @@old ; Yes, zero force counter and chain.
-
- xor bh,bh ;
- mov bl,ah ;
- add bx,bx ; BX = index to int_14h_fntable.
- add bx,offset int_14h_fntable ; BX = offset of handler.
-
- call [word bx] ; Call the appropriate FN handler.
- jmp short @@oldn ; Chain without zeroing force count.
-
- @@old: mov [int_xxh_fcount],0 ; Zero int xxh force counter.
-
- @@oldn: pop ds bx ax
- jmp [dword cs:old_int_14h] ; Chain to old interrupt handler.
- Endp
-
- RESIDENTCODE end
-
-
-
- ;────────────────────────────────────────────────────────────────────────────;
- ;░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒ INT 1xH HANDLER ▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░;
- ;────────────────────────────────────────────────────────────────────────────;
-
- RESIDENTDATA begin
-
- Align 4
- old_int_10h rmdw <0, 0> ;
- old_int_15h rmdw <0, 0> ; Original vector values.
-
- RESIDENTDATA end
-
-
- ;════════════════════════════════════════════════════════════════════════════;
-
-
- RESIDENTCODE begin
-
- Proc int_10h_handler ; BIOS video functions handler.
- mov [cs:int_xxh_fcount],0 ; Zero int xxh force counter.
- jmp [dword cs:old_int_10h] ; Chain to old interrupt handler.
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Proc int_15h_handler ; BIOS AT Services handler.
- cmp ax,5305h ; APM function: CPU idle called?
- je short @@old ; No.
-
- mov [cs:int_xxh_fcount],0 ; Zero int xxh force counter.
-
- @@old: jmp [dword cs:old_int_15h] ; Chain to old interrupt handler.
- Endp
-
- RESIDENTCODE end
-
-
-
- ;────────────────────────────────────────────────────────────────────────────;
- ;░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ IRQ HANDLERS ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░;
- ;────────────────────────────────────────────────────────────────────────────;
-
- RESIDENTDATA begin
-
- Align 4
- old_masterirqs rmdw 8 dup (<0, 0>) ; Original handlers of the hooked IRQs.
-
- new_masterirqs rmdw <irq_00_handler, @CODE16>, <irq_01_handler, @CODE16>
- rmdw <irq_02_handler, @CODE16>, <irq_03_handler, @CODE16>
- rmdw <irq_04_handler, @CODE16>, <irq_05_handler, @CODE16>
- rmdw <irq_06_handler, @CODE16>, <irq_07_handler, @CODE16>
-
- RESIDENTDATA end
-
-
- ;════════════════════════════════════════════════════════════════════════════;
-
-
- RESIDENTCODE begin
-
- Align 16
- Proc irq_00_handler ; Handler for IRQ 0 (timer).
- or [cs:irq_flags],IRQ_00 ; Mark that IRQ 0 occurred.
- jmp [dword cs:old_masterirqs] ; Chain to old interrupt handler.
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Proc irq_01_handler ; Handler for IRQ 1 (keyboard).
- or [cs:irq_flags],IRQ_01 ; Mark that IRQ 1 occurred.
-
- mov [cs:int_xxh_fcount],0 ; Zero int xxh force counter.
- jmp [dword cs:old_masterirqs + 4] ; Chain to old interrupt handler.
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Proc irq_02_handler ; Handler for IRQ 2 (slave PIC).
- or [cs:irq_flags],IRQ_02 ; Mark that IRQ 2 occurred.
-
- mov [cs:int_xxh_fcount],0 ; Zero int xxh force counter.
- jmp [dword cs:old_masterirqs + 8] ; Chain to old interrupt handler.
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Proc irq_03_handler ; Handler for IRQ 3 (COM2).
- or [cs:irq_flags],IRQ_03 ; Mark that IRQ 3 occurred.
-
- mov [cs:int_xxh_fcount],0 ; Zero int xxh force counter.
- jmp [dword cs:old_masterirqs + 12] ; Chain to old interrupt handler.
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Proc irq_04_handler ; Handler for IRQ 4 (COM1).
- or [cs:irq_flags],IRQ_04 ; Mark that IRQ 4 occurred.
-
- mov [cs:int_xxh_fcount],0 ; Zero int xxh force counter.
- jmp [dword cs:old_masterirqs + 16] ; Chain to old interrupt handler.
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Proc irq_05_handler ; Handler for IRQ 5.
- or [cs:irq_flags],IRQ_05 ; Mark that IRQ 5 occurred.
-
- mov [cs:int_xxh_fcount],0 ; Zero int xxh force counter.
- jmp [dword cs:old_masterirqs + 20] ; Chain to old interrupt handler.
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Proc irq_06_handler ; Handler for IRQ 6.
- or [cs:irq_flags],IRQ_06 ; Mark that IRQ 6 occurred.
-
- mov [cs:int_xxh_fcount],0 ; Zero int xxh force counter.
- jmp [dword cs:old_masterirqs + 24] ; Chain to old interrupt handler.
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Proc irq_07_handler ; Handler for IRQ 7.
- or [cs:irq_flags],IRQ_07 ; Mark that IRQ 7 occurred.
-
- mov [cs:int_xxh_fcount],0 ; Zero int xxh force counter.
- jmp [dword cs:old_masterirqs + 28] ; Chain to old interrupt handler.
- Endp
-
- RESIDENTCODE end
-
-
-
- ;╔══════════════════════════════════════════════════════════════════════════╗;
- ;║ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ INITIALIZATION PART OF PROGRAM ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ║;
- ;╚══════════════════════════════════════════════════════════════════════════╝;
-
- include "_tsrinit.ah"
- include "_cmdline.ah"
- include "_console.ah"
- include "_process.ah"
- include "_test.ah"
- include "_irq.ah"
- include "_vcpi.ah"
- include "_cpu.ah"
-
-
- ;════════════════════════════════════════════════════════════════════════════;
-
-
- KERNEL_NAME equ "CPUidle for DOS" ; Name of the kernel.
- KERNEL_FILE equ "DOSidle" ; Name of the .exe (compiled) kernel.
- KERNEL_ID equ 0deedh ; ID number of this program.
-
- SYS_RAW = 01h ;
- SYS_VCPI = 02h ; Flags for PM hosts driving the
- SYS_DPMI = 04h ; system.
-
-
- ;════════════════════════════════════════════════════════════════════════════;
-
-
- INITIALIZATIONSTACK begin
- db 2000 dup (?) ; Stack for initialization part.
- INITIALIZATIONSTACK end
-
-
- ;════════════════════════════════════════════════════════════════════════════;
-
-
- INITIALIZATIONDATA begin
-
- psp_seg dw 0
- env_seg dw 0
-
- dos_version dw 0 ; MS-DOS version.
- apm_version dw 0 ; Advanced Power Management version.
- apm_state db OFF ; State of APM (enabled, disabled).
-
- sys_type db SYS_RAW ; Type of system (Raw, VCPI, DPMI).
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- par_table par_item <"-H", par_help>
- par_item <"-?", par_help>
- par_item <"-U", par_uninst>
- par_item <"-ON", par_on>
- par_item <"-OFF", par_off>
- par_item <"-CPU", par_cpu>
- par_item <"-HLT", par_hlt>
- par_item <"-APM", par_apm>
- par_item <"-FM0", par_noforce>
- par_item <"-FM1", par_weakforce>
- par_item <"-FM2", par_strongforce>
- par_item <0> ; Marks end of par_table.
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- msg_intro db KERNEL_NAME, " V2.10 [Build 0077]", NL
- db "Copyright (C) by Marton Balog, 1998.", NL,0
- msg_help db "Syntax: ", KERNEL_FILE, " [Options]", NL
- db "--------", NL,0
- msg_options_1 db "Standard -On Activate ", KERNEL_FILE, ".", NL
- db "Options: -Off Suspend ", KERNEL_FILE, ".", NL
- db "-------- -U Uninstall ", KERNEL_FILE, ".", NL
- db " -H, -? Display this help message.", NL,0
- msg_options_2 db "Advanced -Cpu Optimize processor for performance.", NL
- db "Options: -Hlt Select cooling method: HLT idle cycles (default).", NL
- db "-------- -Apm Select cooling method: APM V1.00+ cycles.", 0
- msg_options_3 db " -Fm2 Select cooling strategy: Strong Forcing (default).", NL
- db " -Fm1 Select cooling strategy: Weak Forcing.", NL
- db " -Fm0 Select cooling strategy: No Forcing.", NL,0
- msg_examples_1 db "Example: ", KERNEL_FILE, " Install and activate ", KERNEL_FILE, ".", NL
- db "-------- ", KERNEL_FILE, " -Off Suspend ", KERNEL_FILE, " temporarily.", 0
- msg_examples_2 db " ", KERNEL_FILE, " -Fm2 -Apm Enable Strong Forcing and use APM for cooling.",NL
- db " ", KERNEL_FILE, " -Fm1 -Cpu Enable Weak Forcing and optimize CPU.", NL,0
-
- msg_inst db NL, KERNEL_FILE, " installed successfully.",0
- msg_uninst db KERNEL_FILE, " uninstalled successfully.",0
- msg_activate db KERNEL_FILE, " is now activated.",0
- msg_suspend db KERNEL_FILE, " is now suspended.",0
-
- msg_marci db "Zsuzsmi",0
- msg_nl db NL, 0
- msg_na db "N/A",0
-
- msg_detect db "DETECTING...", 0
- msg_cpudet db "[Processor]: ", 0
- msg_apmdet db "[Power/Man]: ", 0
- msg_osdet db "[Op/System]: ", 0
- msg_pmdet db "[32-bit mode]: ", 0
-
- msg_apm db "APM V",0
- msg_apm_on db " [Enabled].",0
- msg_apm_off db " [Disabled].",0
- msg_msdos db "MS-DOS V",0
- msg_msdos_std db " [Standard].",0
- msg_msdos_win db " [Windows 95/98].",0
- msg_raw db "16-bit MS-DOS interface.",0
- msg_vcpi db "32-bit VCPI interface.",0
- msg_dpmi db "32-bit DPMI interface.",0
-
- msg_optimize db NL, "OPTIMIZING...", 0
- msg_cpuopt db "[Processor]: ", 0
- msg_optnomod db "No modifications made",0
-
- err_str db "FATAL ",0
- err_resize db "[#10]: Failed to resize program memory.",0
- err_notinst db "[#20]: ", KERNEL_FILE, " is not installed.",0
- err_inst db "[#21]: ", KERNEL_FILE, " is already installed.",0
- err_uninst db "[#22]: Cannot uninstall ", KERNEL_FILE ,".",0
- err_activate db "[#23]: ", KERNEL_FILE, " is already activated.",0
- err_suspend db "[#24]: ", KERNEL_FILE, " is already suspended.",0
- err_cpu db "[#30]: A 386 CPU or better is required.",0
- err_dos_vers db "[#32]: MS-DOS 5.00 or later is required.",0
- err_cmdln db "[#40]: Invalid command-line switch.",0
- err_v86 db "[#50]: CPU in V86 mode and no VCPI or DPMI host present.",0
-
- INITIALIZATIONDATA end
-
-
- ;════════════════════════════════════════════════════════════════════════════;
-
-
- INITIALIZATIONCODE begin
-
- Proc error_exit ; Exits with error message.
- push si
- lea si,[err_str] ;
- call con_writef ; Print "[FATAL]: "
- pop si
-
- sti
- call con_writeln ; Print error message.
- exit 0 ; Off we go...
- ret
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Proc init
- mov ax,cs ;
- mov ds,ax ; Set data segment.
-
- mov [psp_seg],es ; Save PSP segment.
- mov ax,[es:2ch] ;
- mov [env_seg],ax ; Save enviroment segment.
-
- lea si,[msg_intro] ;
- call con_writeln ; Display program name, copyright...
-
- call test_cpu ; Get CPU family number.
- lea si,[err_cpu] ;
- cmp al,3 ; Less than a 386 (286-)?
- jb error_exit ; Yep, error.
-
- mov ax,3000h ;
- int 21h ; Get DOS version.
- mov [dos_version],ax ; Save it.
-
- lea si,[err_dos_vers] ; Prepare for error.
- cmp al,5 ; Is DOS new enough (5.00+)?
- jb error_exit ; No (4.99-) fail.
-
- mov ax,[psp_seg] ; Shrink DOSidle's memory block to
- mov cx,1000h ; 64 KBs now, TSR will shrink more
- call mem_lresize ; later...
- ret
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Proc par_help
- lea si,[msg_help] ;
- call con_writeln ; Display help message.
-
- lea si,[msg_options_1] ;
- call con_writeln ; Display options help part 1.
-
- lea si,[msg_options_2] ;
- call con_writeln ; Display options help part 2.
-
- lea si,[msg_options_3] ;
- call con_writeln ; Display options help part 3.
-
- lea si,[msg_examples_1] ;
- call con_writeln ; Display examples help part 1.
-
- lea si,[msg_examples_2] ;
- call con_writeln ; Display examples help part 2.
- exit 0
- Endp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- Proc par_uninst
- mov dx,KERNEL_ID ;
- call tsr_instcheck ; Is kernel installed already?
-
- lea si,[err_notinst] ;
- test ax,ax ; AX == 0 if not installed.
- je error_exit ; Nope, can't uninstall, error.
-
- mov dx,KERNEL_ID ;
- call tsr_uninstall ; Try to uninstall kernel.
-
- lea si,[err_uninst] ; Prepare for error.
- test ax,ax ; Uninstallation failed?
- jz error_exit ; Yes, fail.
-
- lea si,[msg_uninst] ;
- call con_writeln ; Print success message.
- exit 0 ; Quit.
- Endp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- Proc par_on
- mov dx,KERNEL_ID ;
- call tsr_instcheck ; Is kernel installed already?
-
- test ax,ax ; AX == 0 if not installed.
- jnz short @@on ; It's installed, try to activate.
-
- ret ; Do normal install if it's 1st time.
-
- @@on: mov dx,KERNEL_ID ;
- call tsr_reactivate ; Try to reactivate int handlers.
-
- lea si,[err_activate] ;
- test ax,ax ; Reactivation of ints failed?
- jz error_exit ; Yes, fail.
-
- lea si,[msg_activate] ;
- call con_writeln ; Print success message.
- exit 0 ; Quit.
- Endp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- Proc par_off
- mov dx,KERNEL_ID ;
- call tsr_instcheck ; Is kernel installed already?
-
- lea si,[err_notinst] ;
- test ax,ax ; AX == 0 if not installed.
- jz error_exit ; Nope, can't suspend, error.
-
- mov dx,KERNEL_ID ;
- call tsr_suspend ; Try to suspend interrupt handlers.
-
- lea si,[err_suspend] ;
- test ax,ax ; Suspension of ints failed?
- jz error_exit ; Yes, fail.
-
- lea si,[msg_suspend] ;
- call con_writeln ; Print success message.
- exit 0 ; Quit.
- Endp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- Proc par_cpu
- or [mode_flags],MODE_OPTIMIZE ; Request CPU optimization.
- ret
- Endp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- Proc par_apm
- or [mode_flags],MODE_APM ;
- and [mode_flags],not MODE_HLT ; Set APM MODE in config flags.
- ret
- Endp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- Proc par_hlt
- or [mode_flags],MODE_HLT ;
- and [mode_flags],not MODE_APM ; Set HLT MODE in config flags.
- ret
- Endp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- Proc par_noforce
- or [mode_flags],MODE_NOFORCE ; Set NO FORCE in config flags.
-
- and [mode_flags],not MODE_WFORCE
- and [mode_flags],not MODE_SFORCE
- ret
- Endp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- Proc par_weakforce
- or [mode_flags],MODE_WFORCE ; Set WEAK FORCE in config flags.
-
- and [mode_flags],not MODE_SFORCE
- and [mode_flags],not MODE_NOFORCE
- ret
- Endp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- Proc par_strongforce
- or [mode_flags],MODE_SFORCE ; Set STRONG FORCE in config flags.
-
- and [mode_flags],not MODE_WFORCE
- and [mode_flags],not MODE_NOFORCE
- ret
- Endp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- Proc read_cmdln
- mov di,80h ;
- mov es,[psp_seg] ; ES:DI = ptr to command-line.
- lea si,[par_table] ; DS:SI = ptr to parameter_table.
-
- call parse_cmdln ; Process the command line.
- lea si,[err_cmdln] ;
- jc error_exit ; Quit if invalid command-line switch.
- ret
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Proc init_modes
- test [mode_flags],MODE_NOFORCE ; FORCE MODE disabled?
- jz short @@sfor ; No.
-
- mov [byte int_xxh_forcehlt],0c3h ; Disable FORCE HLT/APM procedure.
-
- @@sfor: test [mode_flags],MODE_SFORCE ; STRONG FORCE MODE enabled?
- jz short @@apm ; No.
-
- cmp [sys_type],SYS_DPMI ; Running under DPMI (possibly Win95)?
- jne short @@apm ; No
-
- cmp [byte dos_version],7 ; Windows MS-DOS 7.00+ (Win95)?
- jb short @@apm ; No.
-
- or [mode_flags],MODE_WFORCE ; Set WEAK FORCE in config flags.
- and [mode_flags],not MODE_SFORCE
- and [mode_flags],not MODE_NOFORCE
-
- @@apm: test [mode_flags],MODE_APM ; APM usage requested?
- jz short @@cpu ; No.
-
- and [mode_flags],not MODE_APM ; Assume APM is disabled/disengaged.
-
- cmp [apm_state],OFF ; APM disabled/disengaged?
- je short @@cpu ; Yes, no APM.
-
- mov ax,5304h ;
- xor bx,bx ;
- int 15h ; Disconnect Real-mode APM interface.
- jc short @@cpu ; Call failed, no APM.
-
- mov ax,5301h ;
- xor bx,bx ;
- int 15h ; Connect Real-mode APM interface.
- jc short @@cpu ; Call failed, no APM.
-
- mov ax,530eh ;
- xor bx,bx ;
- mov cx,[apm_version] ;
- xchg cl,ch ; Connect appropriate version of APM
- int 15h ; BIOS (needed for V1.00+).
- jc short @@cpu ; Call failed, no APM.
-
- mov ax,5305h ;
- int 15h ; Call APM FN to put the CPU idle.
- jc short @@cpu ; Call failed, no APM.
-
- or [mode_flags],MODE_APM ; It's safe to use APM...
-
- @@cpu: test [mode_flags],MODE_OPTIMIZE ; CPU optimization requested?
- jz short @@done ; No.
-
- lea si,[msg_optimize] ;
- call con_writeln ; Print optimization message.
-
- lea si,[msg_cpudet] ;
- call con_writef ; Print message for CPU detection.
-
- call cpu_optimize ; Optimize CPU.
- lea si,[msg_optnomod] ; Assume optimization failed.
- jc short @@prnt ; Go..
-
- call cpu_getname ;
- lea si,[cpu_name] ; Get full name of CPU.
-
- @@prnt: call con_writef ; Print results of optimization.
-
- mov al,'.' ;
- call con_writech ; Period.
-
- mov al,CR ;
- call con_writech ;
- mov al,LF ;
- call con_writech ; New line.
-
- @@done: ret
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Proc check_system
- call test_vcpi ; Running under VCPI server?
- jne short @@dpmi ; No.
-
- mov [sys_type],SYS_VCPI ; Mark that running under VCPI.
- jmp short @@done
-
- @@dpmi: call test_dpmi ; Running under DPMI host?
- jne short @@v86 ; No.
-
- mov [sys_type],SYS_DPMI ; Mark that running under DPMI.
- jmp short @@done
-
- @@v86: call test_v86 ; Running in V86 mode without PM host?
- lea si,[err_v86] ; Yes, can't execute HLT instruction,
- je error_exit ; fail program.
- @@done: ret
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Proc hook_ints
- xor ax,ax ;
- mov gs,ax ; GS = segment of IVT.
-
- ;- - - - - - - - - - -;
- mov eax,[gs:(10h * 4)] ;
- mov [dword old_int_10h],eax ; Get and save original int 10h.
-
- mov eax,[gs:(15h * 4)] ;
- mov [dword old_int_15h],eax ; Get and save original int 15h.
-
- mov eax,[gs:(14h * 4)] ;
- mov [dword old_int_14h],eax ; Get and save original int 14h.
-
- mov eax,[gs:(16h * 4)] ;
- mov [dword old_int_16h],eax ; Get and save original int 16h.
-
- mov eax,[gs:(21h * 4)] ;
- mov [dword old_int_21h],eax ; Get and save original int 21h.
-
- mov eax,[gs:(2fh * 4)] ;
- mov [dword old_int_2fh],eax ; Get and save original int 2fh.
- ;- - - - - - - - - - -;
-
- ;- - - - - - - - - - -;
- mov ax,@CODE16 ;
- shl eax,16 ; High WORD of EAX = CODE16.
-
- mov bl,10h ; BL = int number of video handler.
- mov ax,offset int_10h_handler ; EAX = new handler for int 10h.
- call tsr_hookint ; Hook int 10h.
-
- mov bl,15h ; BL = int number of AT services.
- mov ax,offset int_15h_handler ; EAX = new handler for int 15h.
- call tsr_hookint ; Hook int 15h.
-
- mov bl,14h ; BL = int number of BIOS COM handler.
- mov ax,offset int_14h_handler ; EAX = new handler for int 14h.
- call tsr_hookint ; Hook int 14h.
-
- mov bl,16h ; BL = int number of keyboard handler.
- mov ax,offset int_16h_handler ; EAX = new handler for int 16h.
- call tsr_hookint ; Hook int 16h.
-
- mov bl,21h ; BL = int number of DOS FNs handler.
- mov ax,offset int_21h_handler ; EAX = new handler for int 21h.
- call tsr_hookint ; Hook int 21h.
-
- mov bl,2fh ; BL = int # of DOS Multiplex handler.
- mov ax,offset int_2fh_handler ; EAX = new handler for int 2fh.
- call tsr_hookint ; Hook int 2fh.
- ;- - - - - - - - - - -;
- ret
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Proc hook_irqs
- xor ax,ax ;
- mov gs,ax ; GS = segment of IVT.
-
- ;- - - - - - - - - - -;
- @@vcpi: cmp [sys_type],SYS_VCPI ; Running under VCPI?
- jne short @@dpmi ; No.
-
- call vcpi_getpic ; Get VCPI IRQ mappings.
- jmp short @@hook
-
- @@dpmi: cmp [sys_type],SYS_DPMI ; Running under DPMI?
- jne short @@raw ; No.
-
- call irq_getpic ; Assume RM IRQ settings (should work).
- jmp short @@hook
-
- @@raw: call irq_getpic ; Get IRQ mappings.
- ;- - - - - - - - - - -;
-
- ;- - - - - - - - - - -;
- @@hook: movzx ebx,bl ; EBX = base int # for master PIC.
- mov cx,8 ; CX = number of IRQ in master PIC.
- xor di,di ; DI = index to irq arrays.
-
- @@mstr: mov eax,[gs:(ebx * 4)] ;
- mov [dword old_masterirqs + di],eax ; Get and save old IRQ handler.
-
- mov eax,[dword new_masterirqs + di] ; Get new handler of IRQ.
- call tsr_hookint ; Hook IRQ.
- inc bl ; BL = next interrupt # for IRQ.
- add di,4 ; DI = next IRQ number.
- loop @@mstr
- ;- - - - - - - - - - -;
- @@done: ret
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Proc detect_cpu
- lea si,[msg_cpudet] ;
- call con_writef ; Print message for CPU detection.
-
- call cpu_getname ; Get full name of CPU.
- lea si,[cpu_name] ;
- call con_writef ; Print it.
-
- mov al,'.' ;
- call con_writech ; Period.
-
- lea si,[msg_nl] ;
- call con_writef ; New Line.
- ret
- Endp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- Proc detect_os
- lea si,[msg_osdet] ;
- call con_writef ; Print message for OS detection.
-
- lea si,[msg_msdos] ;
- call con_writef ; Print "MS-DOS V"
-
- movzx eax,[byte dos_version] ;
- call con_writedec ; Print major version number.
-
- mov al,'.' ;
- call con_writech ; Put a decimal point for version.
-
- movzx eax,[byte dos_version+1] ;
- call con_writedec ; Print minor version number.
-
- lea si,[msg_msdos_std] ; Assume MS-DOS V6.22-
- cmp [byte dos_version],7 ; Is it V7.00+ (for Win95/98)?
- jb short @@osok ; No.
-
- lea si,[msg_msdos_win] ; It's V7.00+ (for Win95/98).
-
- @@osok: call con_writeln ; Print DOS type.
- ret
- Endp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- Proc detect_apm
- lea si,[msg_apmdet] ;
- call con_writef ; Print message for APM detection.
-
- stc ;
- mov ax,5300h ;
- mov bx,0 ;
- int 15h ; APM V1.00+: installation check.
- jnc short @@cont ; Yes, it's installed, continue.
-
- lea si,[msg_na] ;
- call con_writeln ; No APM, print N/A message.
- jmp short @@done ; Finish.
-
- @@cont: xchg al,ah ; AL = major version, AH = minor.
- mov [apm_version],ax ; Save APM version.
-
- lea si,[msg_apm] ;
- call con_writef ; Print "APM V"
-
- movzx eax,[byte apm_version] ;
- call con_writedec ; Print major version number.
-
- mov al,'.' ;
- call con_writech ; Put a decimal point for version.
-
- movzx eax,[byte apm_version+1] ;
- call con_writedec ; Print minor version number.
-
- test cx,18h ; Is the APM disabled/disengaged?
- jnz short @@off ; Yes.
-
- @@on: mov [apm_state],ON ; Mark that APM is unusable.
- lea si,[msg_apm_on] ; It's enabled.
- jmp short @@done ; Finish up.
-
- @@off: mov [apm_state],OFF ; Mark that APM is unusable.
- lea si,[msg_apm_off] ; It's disabled.
-
- @@done: call con_writeln ; Print APM state.
- ret
- Endp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- Proc detect_pm
- lea si,[msg_pmdet] ;
- call con_writef ; Print message for PM detection.
-
- lea si,[msg_raw] ; Assume raw DOS.
- test [sys_type],SYS_RAW ; Running under raw DOS?
- jnz short @@pmok ; Yes, done.
-
- lea si,[msg_vcpi] ; Assume VCPI.
- test [sys_type],SYS_VCPI ; Running under VCPI?
- jnz short @@pmok ; Yes, done.
-
- lea si,[msg_dpmi] ; Now it's DPMI for sure.
- @@pmok: call con_writeln ; Print PM system.
- ret
- Endp
-
- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
-
- Proc info_detect
- lea si,[msg_detect] ;
- call con_writeln ; Print detection message.
-
- call detect_cpu ; Print CPU detection results.
- call detect_apm ; Print APM detection results.
- call detect_os ; Print OS detection results.
- call detect_pm ; Print PM host detection results.
- ret
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Proc install_kernel
- lea si,[msg_inst] ;
- call con_writeln ; Print success message.
-
- mov cx,RESIDENT_END ;
- mov dx,KERNEL_ID ;
- mov bx,[psp_seg] ;
- mov ax,[env_seg] ;
- call tsr_install ; Make kernel TSR.
- Endp
-
-
- ;----------------------------------------------------------------------------;
-
-
- Proc main
- call init ; Do general startup work.
- call read_cmdln ; Read cmd-ln params (maybe uninstall).
-
- mov dx,KERNEL_ID ;
- call tsr_instcheck ; Is kernel installed already?
-
- lea si,[err_inst] ;
- cmp ax,1 ; AX == 1 if installed.
- je error_exit ; Yes, quit now (don't install twice).
-
- call check_system ; Check for VCPI, DPMI, etc.
- call info_detect ; Detect CPU, system, APM, etc.
- call init_modes ; Init FORCE, Test and other modes.
-
- call hook_ints ; Hook needed interrupts.
- call hook_irqs ; Hook needed IRQs.
-
- call cpu_powersave ; Enable power saving features.
- call install_kernel ; Make kernel TSR.
- Endp
-
- INITIALIZATIONCODE end
- End main
-
-