home *** CD-ROM | disk | FTP | other *** search
- PAGE 60,132
- NAME Blank
- .MODEL Small
- .CODE
-
- GoInt MACRO Num ; Quick And Dirty
- IF ((.TYPE Num) AND 4)
- Int Num ; INT for constants
- Iret
- ELSE
- Jmp SHORT Num ; Jump to address
- Nop ; Align
- ENDIF
- ENDM
-
- Inp MACRO Reg, Port ; Used to FORCE a delay after I/O
- In Reg, Port
- Jmp SHORT @F
- @@:
- ENDM
-
- Outp MACRO Port, Reg ; Used to FORCE a delay after I/O
- Out Port, Reg
- Jmp SHORT @F
- @@:
- ENDM
-
- IRQMapH Equ 20h SHR 2 ; Rom set mapped address
- IRQMap Equ 1E0h ; Linear Address of 8259 IRQ Mapping
- IRQMapB Equ IRQMap SHR 2 ; Bits to direct the 8259 to Linear Map
- NumIRQ Equ 8 ; Number of IRQ Masks
-
- Org 80h ; Data storage for Local USE
- Stat Db ? ; Video Status Byte
- ;----------------------------------------------------------------------------
- ; The following EQUs define the status Byte
- ;
- MDA Equ 80h ; Monochrome
- CGA Equ 40h ; Color Graphics Adapter
- EGA Equ 20h ; Enhanced Graphics Adapter
- VGA Equ 10h ; Video Graphics Array
- TwoMonitors Equ 08h ; A second video Adapter was found
- TimeAct Equ 04h ; S = 8259 PIC is remapped
- ; R = 8259 PIC in normal mode
- Enabled Equ 02h ; S = Screen is ACTIVE
- ; R = Screen is DISABLED
- Quicky Equ 01h ; S = Resident code to blank video
- ; R = Normal Timer Checks
- Second Equ 01h ; S = Found Resident Code
- ; R = No Resident code found
- Stat1 Db ? ; Used for Second adapter Identifier
- Click Equ 10h ; S = Do a KeyClick with KeyMake
- ; R = No KeyClick
- CtrlOn Equ 08h ; Control Key has been pressed
- EscOn Equ 04h ; The ESC key has been pressed
- EnterOn Equ 02h ; The Enter Key has been pressed
-
- CtrlKey Equ 1Dh ; Scan code for the CTRL Key
- EnterKey Equ 1Ch ; Scan code for the Enter key
- EscKey Equ 01h ; Sacn Code for the ESC Key
-
- MSR Dw ? ; MSR for primary Adapter
- MSR1 Dw ? ; MSR for seconf adapter
- TimerTic Dw ? ; Timer Tic Counter
- UsrTic Dw ? ; Usr set maximum
- OneMin Equ 1092 ; One minute of TICS
- FiveMins Equ OneMin*5 ; Five minutes of TICS
- MaxMin Equ 9 ; Nine maximum minutes
- MaxTics Equ OneMin*MaxMin ; Nine minutes maximum time allowed
-
- MSRV Db 8 DUP (?) ; Video - MSR enable values
- OldInt8 Dd ? ; Original INT Vector
-
- CPUType Dw ? ; Type of CPU - 86/286/386
- NDPType Dw ? ; Type of NDP - 87/287/387
-
- Org 100h ; Start of Logic
- Main PROC FAR
- ASSUME Cs:@code, Ds:@code, Es:@code
- Machine LABEL BYTE
- Jmp Init ; Do the Initialization
- Signature Db 'BLANK V1.0 - April 1, 1989',0
- SigLen Equ $-Signature ; Character size
-
- NewLLInt PROC NEAR
- GoInt 8
- GoInt LLInt9 ; Jump to the IRQ 1 Handler - KEYPRESS
- GoInt 10
- GoInt 11
- GoInt 12
- GoInt 13
- GoInt 14
- GoInt 15
- LLInt9:
- Cli ; Disable INTR
- Push Ax ; Save registers
- Push Bx
- Push Cx
- Push Dx
- Push Ds
-
- Push Cs ; Set local coverage
- Pop Ds
- Inp Al,60h ; Read the KBD
- Test Al,80h ; Is this KEY Release
- Jnz ChkCtrl ; Yes - Then Skip the CLICK
- Test Stat1,Click ; Do a KeyClick
- Jz ChkCtrl ; No
- Push Ax ; Save Byte
- Mov Al,0BFh ; Set clock rate
- Outp 43h,Al ; for clock 2
- Mov Al,04Bh
- Outp 42h,Al
- Mov Al,0Fh
- Outp 42h,Al
- Inp Al,61h ; read the port
- Mov Ah,Al ; save data for restore
- Or Al,3h ; enable the speaker gate
- Outp 61h,Al
- Mov Cx,100h ; Set TIME for GATE 2 Open
- @@:
- Loop @B ; loop to myself
- Mov Al,Ah ; restore data
- Outp 61h,Al
- Pop Ax ; Restore Byte
- ChkCtrl:
- Cmp Al,CtrlKey ; Is this The Control Key ?
- Jnz ChkEsc ; No - Check for the ESC Key
- Or Stat1,CtrlOn ; Set the Control Key has been Pressed
- Jmp SHORT ClearCtr ; Now check the Screen TIMEOUT
- ChkEsc:
- Cmp Al,EscKey ; IS this the ESC Key
- Jnz ChkClick ; No - Check for Click Toggle
- Or Stat1,EscOn ; Set ESC has been pressed
- Jmp SHORT ClearCtr ; Ok - now clear the counter
- ChkClick:
- Cmp Al,EnterKey ; Click Toggle Key
- Jnz ClearKeys ; No
- Or Stat1,EnterOn ; Yes - then set for check
- Jmp SHORT ClearCtr ; Now clear the TIMER Count
- ClearKeys:
- And Stat1,NOT (EscOn OR CtrlOn OR EnterOn)
- ClearCtr:
- Xor Ax,Ax ; Ok, Key was pressed - Clear
- Mov TimerTic,Ax ; the counter
-
- Mov Al,Stat1 ; Get the Status Byte
- And Al,EscOn OR CtrlOn
- Cmp Al,EscOn OR CtrlOn ; Is this a QUICK Blank?
- Jnz Chain9 ; No - then Exit
- Or Stat,Quicky ; Set for Quick Blank Of the Video
- Xor Stat1,Quicky ; Reset BIT
- IgnoreKey:
- Mov Al,0E1h ; Ack 8259 For IRQ1
- Outp 20h,Al ; Send the Ack
- Inp Al,61h ; Now reset the KBD
- Mov Ah,Al ; Save current Status
- Or Al,80h ; Enable sensw
- Outp 61h,Al
- Mov Al,Ah ; Restore Status
- And Al,7Fh ; Enable KBD
- Outp 61h,Al
- Pop Ds ; Restore registers
- Pop Dx
- Pop Cx
- Pop Bx
- Pop Ax
- Iret
- Chain9:
- Mov Al,Stat1 ; Get the Status Byte
- And Al,CtrlOn OR EnterOn
- Cmp Al,CtrlOn OR EnterOn ; Is this a Click Toggle
- Jnz Chain91 ; No - then Check QUICK Blank
- Xor Stat1,Click ; Toggle Click'ing
- Jmp IgnoreKey ; Ignore the KeyMake
- Chain91:
- Test Stat1,Quicky ; In QUICK BLANK Mode
- Jnz IgnoreKey ; Yes - then Exit
- Test Stat,Enabled ; Is the Screen Active
- Jnz LLIExit ; Yes - then pass to next
- Test Stat,EGA OR VGA ; Enhanced videos
- Jz DoMDCGA ; No
- Mov Al,20h ; Enable the EGA/VGA
- Call DoEVGA
- Jmp SHORT LLI9Exit1 ; and get out
- DoMDCGA:
- Push Ds ; Save
- Xor Ax,Ax ; Set to SEG=0
- Mov Ds,Ax
- Mov Al,Ds:[449h] ; Get Current Mode
- Pop Ds ; Restore
- Mov Dx,MSR ; Get the primary MSR
- Lea Bx,MSRV ; Point to Xlate table
- Xlat MSRV ; Translate to proper enable Value
- Outp Dx,Al ; VIDEO IS NOT ACTIVE
- LLI9Exit1:
- Mov Al,29h ; Set for Enable
- Call Adapter2 ; Enable it if present
- Or Stat,Enabled ; Display is now active
- LLIExit:
- Pop Ds ; Restore registers
- Pop Dx
- Pop Cx
- Pop Bx
- Pop Ax
- Int 9 ; CHAIN to INT 9
- Iret
- NewLLInt ENDP
-
- NewInt8 PROC NEAR
- Sti ; Enable INTR
- Pushf ; fake INTR to chained links
- Call DWORD PTR Cs:OldInt8
-
- Cmp Ax,-1 ; Check for Chained Load Checking
- Jnz NewInt81 ; Noop
- Cmp Bx,-2 ; Check Again
- Jnz NewInt81 ; Noop
- Cmp Cx,-3 ; Check again
- Jnz NewInt81 ; Noop
- Cmp Dx,-4 ; This should be enough Checking
- Jnz NewInt81 ; Noop
- Push Cs ; Must Reture Segment in ES
- Pop Es
- Jmp SHORT I8Exit ; Back to Caller
- NewInt81:
- Test Cs:Stat,TimeAct ; Are we disabled
- Jnz Update ; No then update the counter
- I8Exit:
- Iret ; Just Exit
- Update:
- Push Ax ; Save registers
- Push Bx
- Push Dx
- Push Ds
-
- Push Cs
- Pop Ds ; Get Local Coverage
- Test Stat,Quicky ; Perform a QUICKY?
- Jz NormTime ; No
- And Stat,NOT Quicky ; Clear BIT
- Jmp SHORT QuickBlank; Do it FRED
- NormTime:
- Test Stat,Enabled ; is the screen active
- Jz TExit ; No - then do not check
- Inc TimerTic ; Add to counter
- Mov Ax,TimerTic ; have we reachewd our limit?
- Cmp Ax,UsrTic ; Get usr set maximum
- Jb TExit ; No - then Exit
- QuickBlank:
- And Stat,NOT Enabled; set disabled
- Test Stat,EGA OR VGA ; is this an EGA/VGA
- Jnz DoSpecial ; Yes
- Mov Dx,MSR ; Get the Primary MSR
- Mov Al,25h ; Disable for MDA/CGA
- Outp Dx,Al
- Jmp SHORT TExit1 ; Set screen is disabled
- DoSpecial:
- Xor Al,Al ; Disable the EVGA
- Call DoEVGA ; Blank out the EGA/VGA Screen
- TExit1:
- Mov Al,25h ; Set Disable Code
- Call Adapter2 ; Check for second adapter
- TExit:
- Pop Ds ; Restore registers
- Pop Dx
- Pop Bx
- Pop Ax
- Jmp I8Exit ; Back to the shadows
- NewInt8 ENDP
-
- DoEVGA PROC NEAR
- Push Ax ; Save Command code
- Push Ds ; Save DS
- Xor Ax,Ax ; set to segment = 0
- Mov Ds,Ax
- Mov Al,Byte Ptr Ds:[465h] ; Get current 6845 MSR value
- Mov Bx,Word Ptr Ds:[463h] ; Get current CRT I/O Port
- Pop Ds ; Restore Coverage
- Add Bx,6 ; Set to Status Register
- Mov Dx,3CDh ; Assume EGA for now
- Inp Al,Dx
- Mov Ah,Al ; Save current video State
- And Al,67h
- Outp Dx,Al
- Mov Dx,Bx ; Set to Current CRT IO Port
- Inp Al,Dx ; Read current video Status
- Pop Bx ; Restore Function 0=Disable 20=Enable
- Mov Al,Bl
- Mov Dx,3C0h ; Video Attributes Register
- Outp Dx,Al ; BLANK THE SCREEN
- Mov Al,Ah ; Restore CRT Status
- And Al,0EFh ; Strip off Bit 5
- Mov Dx,3CDh
- Outp Dx,Al
- Ret ; Back to the caller
- DoEVGA ENDP
-
- Adapter2 PROC NEAR
- Test Stat,TwoMonitors; Do we have 2 videos
- Jz A2Exit ; No - then Exit
- Mov Dx,MSR1 ; Get MSR for secondary Adapter
- Outp Dx,Al ; Send command
- A2Exit:
- Ret
- Adapter2 ENDP
-
- Init: ; Initialization Routine
- Mov Ax,Cs ; Ensure DOS covers us on initialization
- Mov Ds,Ax
- Mov Es,Ax
- Lea Dx,Message ; Display ownership message
- Mov Ah,9
- Int 21h
-
- Push Es
- Mov Ax,0F000h ; Get machine type ID
- Mov Es,Ax
- Mov Al,Byte Ptr Es:[0FFFEh]
- Pop Es
- Mov Machine,Al ; Save Machine ID
-
- ; Initialize parameters
-
- Lea Si,Stat ; Point to the Parameter Table
- Cmp Byte Ptr [Si],0 ; Check for any parameter value
- Jz Default ; Ok - use default
- Inc Si ; Bump to the first character
- ParmIn:
- Lodsb ; Get parameter count
- Cmp Al,20h ; Is this a space
- Jz ParmIn ; Yes - then ignore
- Cmp Al,9h ; Is this a TAB
- Jz ParmIn ; Yes - then SKIP it
- Cmp Al,0Dh ; End of Input
- Jz Default ; Yes - then use default value
- Xor Al,30h ; Strip off ASCII
- Cbw ; Strip upper half of word
- Or Al,Al ; Anything Passed
- Jz ChkDis ; No - then check for disable
- Cmp Al,MaxMin ; Above Maximum
- Ja Default ; To high - set default
- Jmp SHORT SetTime ; Calculate TICS
- ChkDis:
- Call CheckMap ; Are we already resident - ES has Res Vector
- Jc NoGo ; Can not disable - not loaded
-
- Call GetCpu ; Get CPU Type
- Mov CPUType,Ax ; And save
- Call GetNdp ; Get NDP if any
- Mov NDPType,Ax ; And Save
- And Es:Stat,NOT TimeAct ; Set disable switch
- Mov Bl,IRQMapH ; Set Vector for 8259
- Call SetMap ; Remap the 8259
- Sti ; Enable INTR
- Lea Dx,Disabled ; Show Disabled
- Mov Ah,9
- Int 21h
- Norm:
- Mov Ax,4C00h ; Terminate normally
- Int 21h
- NoGo:
- Lea Dx,NotLoaded ; We are not loaded
- Mov Ah,9
- Int 21h
- Term:
- Mov Ax,4C01h ; Exit with error
- Int 21h
- SetTime:
- Mov Cx,OneMin ; Get TICS per minute
- Mul Cx ; Convert to TICS
- Jmp SHORT SetTICS ; Save off tics wanted
- Default:
- Mov Ax,FiveMins ; Set default to FIVE Minutes
- SetTICS:
- Mov UsrTic,Ax ; Save in local storage
- Mov TimerTic,0 ; Initialize Current TIC Counter
- Mov Stat,0
- Mov Stat1,0
-
- Call GetCpu ; Get CPU Type
- Mov CPUType,Ax ; And save
- Call GetNdp ; Get NDP if any
- Mov NDPType,Ax ; And Save
-
- Lea Di,MSRV ; Point to Local storage
- Lea Si,MSRValues ; Table of NSR Values
- Mov Cx,LenMSRV ; Get count
- Rep Movsb ; Copy to local storage
-
- Lea Di,WorkBuf ; Point to Storage Area
- Xor Bx,Bx ; Clear for Call
- Mov Ax,1B00h ; Check for a VGA
- Int 10h ; Video BIOS call
- Cmp Al,1Bh ; Is this a VGA
- Jnz ChkEGA ; No - then check for other
- Mov Al,VGA ; Set for VGA
- Jmp SHORT SetVideo ; now - mov the local to resident
- ChkEGA:
- Mov Ah,12h ; EGA Status check
- Mov Bl,10h
- Xor Cx,Cx ; Clear the status bits
- Int 10h ; Video BIOS Call
- Jcxz NoEGA ; Now check for MDA/CGA
- Mov Al,EGA ; Set for EGA
- Jmp SHORT SetVideo ; Set video type
- NoEGA:
- Mov Ah,0Fh ; Get Current Video Mode
- Int 10h
- Cmp Al,7 ; Is a monochrome?
- Je SetMono ; Yes
- Cmp Al,15 ; Graphic Mono
- Je SetMono ; Yes
- Mov Al,CGA ; no - its a CGA
- Mov Dx,3D8h ; Set CGA MSR
- Jmp SHORT SetVideo ; Save in local storage
- SetMono:
- Mov Al,MDA ; Set for Mono
- Mov Dx,3B8h ; Set MONO MSR
- SetVideo:
- Mov Stat,Al ; Set type of Video
- Mov MSR,Dx ; Save for Resident code
-
- ;----------------------------------------------------------------------------
- ; Determine if a second video adapter is present
- Mov Dx,3D4h ; Assume CGA attached
- Push Ds ; Save
- Xor Ax,Ax ; Clear
- Mov Ds,Ax ; Set SEG=0
- Cmp Dx,Ds:[463h] ; Is this a CGA ?
- Pop Ds ; Restore
- Jnz Save_Second ; No - then already set for CGA
- Mov Dx,3B4h ; Yes, look for MDA
- Save_Second:
- Mov Al,0Fh ; Select cursor low
- Outp Dx,Al
- Inc Dx ; Get initial value for reset
- Inp Al,Dx
- Mov Ah,Al ; And save it
- Find_Second:
- Mov Al,55h ; Write first pattern
- Outp Dx,Al
- Inp Al,Dx ; Read pattern back
- Cmp Al,55h ; Is pattern same?
- Jnz No_Second ; No, adapter not there
- Mov Al,0AAh ; Write second pattern
- Outp Dx,Al
- Inp Al,Dx ; Read pattern back
- Cmp Al,0AAh ; Is pattern same?
- Jnz No_Second ; No, adapter not there
- Mov Cl,TwoMonitors ; Yes, set status bits
- Jmp SHORT GSADone ; Finished
- No_Second:
- Xor Cl,Cl ; Sorry, but you only have ONE monitor
- GSADone:
- Mov Al,Ah ; Restore cursor info
- Outp Dx,Al
- Add Dx,3 ; Set to MSR of appropriate monitor
- Or Stat,Cl ; Save 2nd monitor info
- Or Cl,Cl ; Check if found for message display
- Jz CopyStorage
- Cmp Dx,3D8h ; Is the Monitor a CGA
- Jz TwoCGA ; Yes
- Or Stat1,MDA ; No Second monitor is a MDA
- Jmp SHORT TwoShow
- TwoCGA:
- Or Stat1,CGA ; Set 2nd adapter is a CGA
- TwoShow:
- Mov MSR1,Dx ; Save MSR
- Lea Dx,TwoMons ; Point to the messgae
- Mov Ah,9
- Int 21h
- CopyStorage:
- Mov Ax,UsrTic ; Get the number of TICS
- Mov Cx,OneMin ; Number of tics per minute
- Xor Dx,Dx ; Clear for Divide
- Div Cx
- Or Al,30h ; Make ASCII
- Mov Minute,Al ; Svae in the string
- Lea Dx,TimeOut
- Mov Ah,9
- Int 21h
-
- ;-----------------------------------------------------------------------------
- ; Now we must check to see if we are already Resident or not.
- ; If we are, then the new Timer value is passed to the resident code.
- ; Note - A value of ZERO will Disable the BLANK Program
- ;
- Call CheckMap ; Check for Loaded Status
- Jc ReVector ; Not loaded - Must revector
- Mov Al,Stat ; Get Current Status and pass to res code
- Mov Es:Stat,Al
- Mov Ax,MSR ; Pass Current MSR to Res Code
- Mov Es:MSR,Ax
- Mov Ax,MSR1 ; Secondary MSR to Res Code
- Mov Es:MSR1,Ax
- Xor Ax,Ax ; Clear current Count
- Mov Es:TimerTic,Ax
- Mov Ax,UsrTic ; Get the New TICS
- Mov Es:UsrTic,Ax ; and put into the resident code
- Mov Stat,Second ; And save in local
- Jmp SHORT ReMap ; No - then setup 8259 PIC mapping
- PassTic:
- Lea Dx,ParmPass ; Set parameters Passed
- Mov Ah,9
- Int 21h
- Jmp Norm ; And Exit
- ReVector:
- Mov Ax,3508h ; Get INT 8 Vector
- Int 21h
- Cli
- Mov Word Ptr OldInt8 +0,Bx ; Save offset
- Mov Word Ptr OldInt8 +2,Es ; Save segment
- Sti
- Lea Dx,NewInt8 ; Point to My Handler
- Mov Ax,2508h ; Set INT VEctor
- Int 21h ; Now legal with DOS
-
- Xor Ax,Ax ; Set to Segment 0
- Mov Ds,Ax
- Mov Si,IRQMap ; Get MAP address
- Mov Ax,OFFSET NewLLInt ; Address of my coding
- Mov Cx,NumIRQ ; Set Loop Counter
- Cli ; Ok Disable INTR
- IRQLoop:
- Mov [Si + 0],Ax ; Address of IRQ offset
- Mov [Si + 2],Cs ; Address of IRQ segment
- Add Ax,3 ; Point to the Next IRQ Mask Handler
- Add Si,4 ; Bump to Next IRQ Address
- Loop IRQLoop ; Finish the Masks
- ReMap:
- Mov Ax,Cs ; Restore Local Coverage
- Mov Ds,Ax
- Mov Bl,IRQMapB ; Set 8259 Vector Address
- Call SetMap ; Map the 8259
-
- Test Stat,Second ; Is this for already resident code
- Jz NewLoad ; No
- Or Es:Stat,TimeAct OR Enabled
- Jmp PassTic ; Exit normal
- NewLoad:
- Or Stat,TimeAct OR Enabled ; Set initial status
- Or Stat1,Click ; Set KeyClick on KeyMake
- Lea Dx,ResMsg ; Show resident message
- Mov Ah,9
- Int 21h
-
- Lea Dx,Init + 15 ; Address of End of Resident Code
- Mov Cl,4
- Shr Dx,Cl
- Mov Ax,3100h
- Int 21h
-
- CheckMap PROC NEAR
- Xor Ax,Ax ; Get segment 0 Coverage
- Mov Ds,Ax
- Les Bx,DWORD PTR Ds:[IRQMap]
- Push Cs ; Restore local coverage
- Pop Ds
- Lea Si,Signature ; Point to My Signature
- Mov Di,Si ; Should be the same in resident Coding
- Mov Cx,SigLen ; how many characters for compare
- Repz Cmpsb ; Is this My coding
- Jnz NotMe ; Not me
- Clc ; Set mapping was found
- Ret ; And exit
- NotMe:
- Mov Ax,Es ; Check for Zeor segment
- Or Ax,Ax ; to see if anyone else has this INterrupt
- Jz NotMe1 ; No one else found
- Push Cs ; For compare when return from INT
- Pop Es
- Mov Ax,-1 ; Setup for internal checking
- Mov Bx,-2
- Mov Cx,-3
- Mov Dx,-4
- Int 8 ; Use the Normal H/W Timer
- Mov Ax,Cs
- Mov Bx,Es
- Or Ax,Bx ; Is this Us
- Jz NotMe1 ; No exit
- Clc ; Yes - then ES =
- Ret
- NotMe1:
- Stc ; We are not loaded
- Ret ; Back to caller
- CheckMap ENDP
-
- SetMap PROC NEAR
- Cli
- Inp Al,21h ; Get Curent IMR
- Push Ax ; And save for a restore
- Mov Al,0FFh
- Outp 21h,Al
- Mov Cl,Machine ; Get the Machine ID
- Cmp Cl,0F8h ; Model 80
- Jz SetMap2 ; Yes - has 2 8259s
- Cmp Cl,0FCh ; AT Type?
- Jz SetMap2 ; Yes - has 2 8259s
- Mov Al,13h ; Set ICW1
- Outp 20h,Al ; Init the 8259
- Mov Al,Bl ; Get ReMapped Address
- Outp 21h,Al ; Set New Address
- Mov Al,9h ; Skip the ICW3 and DO ICW4
- Outp 21h,Al ; The 8259 is remapped
- Jmp SHORT SMExit ; Now exit
- SetMap2:
- Mov Al,11h ; Set ICW1 for MASTER/SLAVE Mode
- Outp 20h,Al ; To set IRQ address into My Coding
- Mov Al,Bl ; Remapped Address
- Outp 21h,Al ; ICW2 - Vectored Address from BL
- Mov Al,4h ; ICW3 - Set Slave Mapped to IR2 on Master
- Outp 21h,Al
- Mov Al,1 ; OCW4 - Set 8259 PIC to iAPX86/88 Mode
- Outp 21h,Al
- SMExit:
- Pop Ax ; Restore Original Mask - IMR
- Outp 21h,Al ; And reset the mask bits
- Sti
- Ret ; Back to Caller
- SetMap ENDP
-
- GetCpu PROC NEAR
- Pushf ; Save FLAG registers
- Xor Ax,Ax ; Clear AX and push onto the stack.
- Push Ax
- Popf ; Pop a zero into FLAGs register
- Pushf ; Attempt to set bit 12-15 to a zero
- Pop Ax ; Recover FLAG word
- And Ax, 0F000h ; If Bits 12-15 are set then the processor
- Cmp Ax, 0F000h ; is an 8018x or an 808x
- Jz is801x
- Mov Ax,0F000h ; Try to set FLAG bits 12-14 (NT, IOPL)
- Push Ax
- Popf ; put 07000H into flags
- Pushf
- Pop Ax
- And Ax,0F000h ; if bits 12-14 are cleared then the
- Jz is80286 ; processor is an 286
- is80386: ; Else it is a 386
- Mov Ax,386h
- Jmp Short GCExit ; Exit
- is80286:
- Mov Ax,286h ; return 286 in AX
- Jmp Short GCExit ; Get Out
- is801x: ; It is a 8086, a 80186, or a V20/V30
- Mov Ax,0FFFFh ; Set AX to all 1s
- Mov Cl,33 ; Will shift it 33 times if it is an
- ; 808x, or 1 time if it is an 8018x.
- Shl Ax,Cl ; If we shift 33 times all bits are
- Jnz is80186 ; zero. If any bits are on it's an 18x
- is8086: ; Else we have an 8086 or V20/V30.
- Xor Al,Al ; Sets ZF
- Mov Al,40h ; 64 decimal
- Mul Al ; 64**2 > 255
- Jz isv30 ; V20/V30 MUL leaves ZF untouched
- ; 8086 ZF==OF after MUL
- Mov Ax,86h ; Return 86/V20
- Jmp Short GCExit
- isv30:
- Mov Ax,30h ; Return V30
- Jmp Short GCExit
- is80186:
- Mov Ax,186h ; Return 186
- GCExit:
- Popf ; Restore flags
- Ret
- GetCpu ENDP
-
- ControlB Equ Byte Ptr [Bp - 2]
- ControlW Equ Word Ptr [Bp - 2]
-
- GetNdp PROC NEAR
- Push Bp ; Setup local storage
- Mov Bp,Sp
- Mov ControlW,0 ; Initialize storage
- Fninit ; try to initialize NDP
- Fnstcw ControlW ; put control word in mem
- Mov Ah,ControlB ; if AH is 03h, you got
- Cmp Ah,03h ; an NDP on board !!
- Jz Chk87 ; found somethin', keep goin'
- Xor Ax,Ax ; no processor found
- Jmp Short NdpExit ; retunr
- Chk87:
- And ControlW,NOT 0080h ; turn ON interrupts (IEM=0)
- Fldcw ControlW ; load control word
- Fdisi ; turn OFF interrupts (IEM=1)
- Fstcw ControlW ; store control word
- Test ControlB,80h ; iff IEM=1, 8087
- Jz Chk287 ; guess not! March on....
- Mov Ax,87h ; this is an 8087
- Jmp Short NdpExit
- Chk287:
- Finit ; set default infinity mode
- Fld1 ; make infinity
- Fldz ; by dividing
- Fdiv ; 1 by zero !!
- Fld St ; now make a
- Fchs ; negative infinity
- Fcompp ; compare Ur two infinities
- Fstsw ControlW ; if, for 8087 or 80287
- Fwait ; til status word is put away
- Push Ax ; save
- Mov Ax,ControlW ; get control word
- Sahf ; put AH into flags
- Pop Ax
- Jnz is80387 ; NO GOOD.... march on !!
- Mov Ax,287h ; set 80287
- Jmp Short NdpExit
- is80387:
- Mov Ax,387h ; must be an 80387
- NdpExit:
- Pop Bp ; Restore Stack
- Ret ; back to shadow
- GetNdp ENDP
-
- MSRValues Db 2Ch, 28h, 2Dh, 29h, 2Ah, 2Eh, 1Eh, 2Ch
- LenMSRV Equ $-MSRValues
-
- Message Db 13,10
- Db 9,' Blank v1.2 - By Richard Wissinger - April 1989',13,10,'$'
- ResMsg Db 9,9,' Resident portion of Blank loaded',13,10,'$'
- TwoMons Db 9,9,' A second video adapter was found',13,10,'$'
- ParmPass Db 9,9,' New time passed to resident code',13,10,'$'
- TimeOut Db 9,9,' Screen timeout set for '
- Minute Db '5 minutes',13,10,'$'
- NotLoaded Db 9,7,' Blank could not be found in resident memory!',13,10,'$'
- Disabled Db 9,9,' Resident Blank has been disabled',13,10,'$'
-
- WorkBuf Equ $ ; Work area for Video BIOS 1B/12
- Main ENDP
- END Main
-