home *** CD-ROM | disk | FTP | other *** search
- ;«RM82»«TS8,16,24,32,40,48,56»
- ;Updated 12/13/90
-
- ;============================================================================
- ; Copyright (C) Copr. 1990 by Sidney J. Kelly
- ; All Rights Reserved.
- ; Sidney J. Kelly
- ; 150 Woodhaven Drive
- ; Pittsburgh, PA 15228
- ; home phone 412-561-0950 (7pm to 9:30pm EST)
- ;============================================================================
-
- DOSSEG
- .model medium
- .code
-
- public PRINTRDY, CHECK87, FREERAM, EQUIPMENT, OTHERMEMORY, FINDDRIVES, ANSICHECK, ACTUALEXTND
-
- ; Please do not remove
- Copyright DB 13,10,'Copyright Copr. (C) 1990 Sidney J. Kelly',13,10
- Copyright1 DB 'All Rights Reserved',13,10,26
-
- ;==========================================================================
- ;DECLARE FUNCTION PRINTRDY%(Lpt%)
- ; Input:
- ; Lpt% gives portnumber to test
- ; Lpt%=1 for LPT1:, 2 for LPT2:, etc
- ;
- ; Returns:
- ; 0 if not ready
- ; -1 (True) if ready
- ;===========================================================================
-
- EVEN
- PRINTRDY PROC FAR ; Check LPT(Lpt%):
- Push BP
- Mov BP,SP
- Mov BX,[BP+6]
- Mov DX,[BX]
- Dec DX ; 0 biased
- Cmp DX,4 ; make sure Lpt# is 0 to 3
- JB @f ;
- Xor AX,AX ; report out of range error
- Jmp Short EXIT_1
- @@:
- Mov AH, 2 ; Check printer status for
- Int 17h ; Printer bios interrupt
- Mov DX, AX ; Put result in DX &
- Xor AX, AX ; assume no printer
- TEST DH, 00101001b ; Are any error bits on?
- JNE EXIT_1 ; Yes? Error so exit
- TEST DH, 10010000b ; Are both operation bits on?
- JZ EXIT_1 ; No? Error so exit
- Mov AX,-1 ; Printer on line, returns -1
- EXIT_1: ; Error or offline, returns 0
- Pop BP
- Ret 2 ; quits program & clears parameter
- PRINTRDY Endp
-
- ;=======================================================================
- ;DECLARE FUNCTION CHECK87%()
- ;Returns:
- ; 0 if no 80x87, or system equipment word not set.
- ; 87 if an 8087
- ; -87 if 8087 emulation in use on an 80286 or 80386. Because the
- ; the 80287 has almost exactly the same instruction set as the
- ; 8087 few have felt a need to emulate the 80287. I have not
- ; seen an 80387 emulator in software. The 80827 just includes
- ; one new instruction (protected mode), nothing for use in
- ; real mode. 80387 has transendental math routines.*
- ;
- ; 287 if an 80827
- ; 387 if an 80387 or 80487
- ; More accurate than checking the equipment word. QBX, Version 7
- ; merely checks the equipment word to determine if an 80x87 is installed.
- ; I guess that can be used as a software toggle.
- ;
- ; * Intel recently released an 80287 that has 80387 transendental math
- ; routines in it. If someone sends me a new chip, I will write code
- ; to test for it.
- ;
- ; Because of complaints about the traditional test with inexpensive clones
- ; (See Jon Waterhouse letter in Byte, Nov. 1990, page 40)
- ; routine first tests the equipment word in RAM bios.
- ;=======================================================================
- ;
- ; REFERENCES:
- ; basic info is adopted from Ted Forgeron's article in PC
- ; Tech Journal, Aug '87 p43.
- ; Copr. 1987 Pat Shea - Psi! (that Copr. is on there cuz my
- ; lawyer sez I should, but feel
- ; free to hack away!!! pats.)
- ; In the event of subsequent republication of this function,
- ; please carry forward reference to these two gentlemen as
- ; original authors.
- ;
- ; Minor beautification, addition of MASM 5.1 simplified
- ; directives, detection of emulation, additional commentary by SJK 12/12/90
- ;
- ; The CX loop idea for slow PC's with a math chip is from the public
- ; domain INFOPLUS Version 1.35, Andrew Rossman 10/7/90
- ;=======================================================================
-
- EVEN
- CTRL_Word dw 0 ; CTRL_Word word needed for the NDP test.
- ; In OS/2 probably will have to make
- ; this a local variable on the stack
- ; because cannot write to CSegment in
- ; OS/2.
- EVEN
- CHECK87 PROC FAR
- Pushf ; save flags
-
- ; in response to clone errors, test to see if system knows
- ; if math chip is installed. If Int 11h sez no, then
- ; report no mathchip. Can't check AT CMOS mathchip bit
- ; because some clones do not set the bit in the CMOS, but
- ; only set the bit in the Int 11h equipment word. E.g. ACER 910
-
- Int 11h
- Test AL,10b ; is mathchip bit Set?
- JZ No_Math_Chip ; no mathchip
-
- ;Test for any mathchip
- Mov Word Ptr CTRL_Word,0h ; clear CTRL_Word
-
- CLI ; prevent interrupts so routine will work on slow PC's
- ; The next two 80x87 instructions cannot carry the WAIT prefix,
- ; because there may not be an 80x87 for which to wait. The WAIT is
- ; therefore emulated with a MOV CX,<value>! LOOP $ combination. This
- ; allow use of routine on an old PC with an 8087.
-
- Fninit ; try to initialize the NDP
- ; use the no-wait state version of the op code so will not
- ; hang a machine without a NDP. Loop allows test of a PC that
- ; does have an 8087.
-
- Mov CX,2 ; a time waste loop
- Loop $ ; allow 8087 time to react
-
- Fnstcw CTRL_Word ; put CTRL_Word in memory
- ; use the no-wait state version of the op code so will not
- ; hang a machine without a NDP. Loop allows test of a PC that
- ; does have an 8087.
- Mov CX,14h
- Loop $
-
- STI ; allow interrupts again
- Cmp byte ptr CTRL_Word+1, 3 ; if high byte = 3h then NDP found
- Je chk_87 ; found something, so keep going
-
- No_Math_Chip:
- Xor AX,AX ; else zero AX to show
- Jmp SHORT CHK_87_END ; no NDP
-
- ;Test for 8087
- chk_87:
- And CTRL_Word,NOT 0080h ; turn ON interrupts (IEM = 0)
- Fldcw CTRL_Word ; load CTRL_Word word
- Fdisi ; turn OFF interrupts (IEM = 1)
- Fstcw CTRL_Word ; store CTRL_Word word
- Test CTRL_Word,0080h ; if IEM=1, 8087 (only 8087 pays
- ; attention to IEM)
- Jz Chk_287 ; not an 8087, test for 80287
-
- ;-------------------------------------------------------------------------
- ; Test for 8087 emulation by software. Emulation only can be done on an
- ; 80286 or 80386. So test for an 80286 or 80386 using quirk with flags
- ; I haven't seen a routine that emulates the 80287 so this is not tested
- ; for. I am sure one exists though. Emulation of an 8087/808287 is possible
- ; because of a special bit on the 80287 machine status register. Exactly how
- ; this emulation is done is light years beyond me.
- ; The only reason for testing for emulation is suggest to user that he
- ; would get faster results if he relied on MS QuickBasic built in
- ; software emulation rather than other forms of software emulation.
- ;-------------------------------------------------------------------------
- Xor AX,AX ; clear AX
- Push AX ; put on stack
- Popf ; put in flags
- Pushf ; put back on stack
- Pop AX ; get flags back in AX
- And AX,0F000h ; clear all but upper 4 bits
- Cmp AX,0F000h ; if bits 12-15 are set then CPU
- JE @f ; is not an 80286, 80386 or 80486
- Mov AX,-87 ; put -87 in AX to show that
- Jmp SHORT CHK_87_END ; emulation is detected
- @@:
- ; CPU is a NEC, 8086/88 or 80186/88
- Mov AX,87 ; put 87 in AX to show
- Jmp SHORT CHK_87_END ; found an 8087
-
- ;Test for 80287
- Chk_287:
- Finit ; set default infinity mode
- Fld1 ; push 1 on stack
- Fldz ; push 0 on stack
- Fdiv ; then divide. Make infinity
- ; by dividing 1 by zero
- Fld St ; push back on stack. Change
- Fchs ; sign & make negative infinity
- Fcompp ; compare the two infinities
-
- ; Default after FINIT for 80287 & 8087 is projective infinity where
- ; both positive and negative infinity are equal. 80387 & 80486 use
- ; affine infinity, and ignore projective infinity. Under affine
- ; infinity positive and negative infinity are at opposite ends of the
- ; number line and are not equal. (SJK Who thinks of these things???)
-
- Fstsw CTRL_Word ; store status for result
- Fwait ; wait until status word is stored
- Mov AX,CTRL_Word ; get CTRL_Word word
- Sahf ; put highbyte (AH) into flags
- Jnz Got_387 ; If bit 6 (infinity control)
- ; not set then it is a 80387
- Mov AX,287 ; report that it is an 80287
- ; since we tested for an 8087
- Jmp SHORT CHK_87_END
-
- ; NDP not an 8087 or an 80287 so it must be an 80387. The 80387 ignores
- ; the infinity control (IC) flag, 80287/8087 does not. SJK
-
- Got_387:
- Mov AX,387 ; return 387
- CHK_87_END:
- Popf ; restore flags
- ret ; end, return to main routine
- CHECK87 ENDP
-
- ;===========================================================================
- ; DECLARE SUB EQUIPMENT(ConvMem%,PrinterPorts%,ComPorts%)
- ; Returns amount of Conventional Memory in KB
- ; number of Parallel Ports
- ; number of COM ports
- ;===========================================================================
-
- ConvMem EQU [BP+10]
- PrinterPorts EQU [BP+8]
- ComPorts EQU [BP+6]
-
- EVEN
- EQUIPMENT PROC FAR
- Push BP ; save stack frame
- Mov BP,SP ; address stack
- Int 12h ; get conventional memory
- Mov BX,ConvMem ; point to ConvMem%
- Mov [BX],AX ; Place value in ConvMem%
- Xor DX,DX ; clear DX for use
- Int 11h ; Call get equipment interrupt
- Mov AL,AH ; just look at top 8 bits
- ; save them in AH
- ; use AL to manipulate
- Mov CL,06 ; Dump bits 8-13,
- SHR AL,CL ; and move 14 & 15 to lower positions
- And AL,03 ; mask any other positions
- Mov DL,AL ; Move Printers%
- Mov BX,PrinterPorts ; Point to PrinterPorts%
- Mov [BX],DX ; And store in PrinterPorts%
- Mov AL,AH ; Get top 8 bits again
- SHR AL,1 ; This time look at bits 9, 10 & 11
- And AL,07 ; by masking for 3 bits
- Mov DL,AL ; And move ComPorts to DL
- Mov BX,ComPorts ; Point to ComPorts%
- Mov [BX],DX ; And store in ComPorts%
- Pop BP ; restore BP
- Ret 6 ; remove 2*3 parameters
- EQUIPMENT Endp
-
- ;======================================================================
- ; DECLARE SUB OTHERMEMORY(EXTENDED%,EXPANDED%,XMS%)
- ; Returns size of extended, expanded, and XMS memory.
- ; Extended = only size that BIOS reports is free
- ; Expanded = total installed.
- ; XMS = total installed.
- ;
- ; Uses the rom ID byte approach to determine if extended memory supported.
- ;======================================================================
-
- .code
- EXPMEM DB "EMMXXXX0"
- EXPMEM_LENGTH EQU $-EXPMEM
- EVEN
- Drv_ADDR DD 0 ; This will hold address of
- ; HIMEM.SYS driver
-
- EVEN
- OTHERMEMORY PROC FAR
- Push BP
- Mov BP,SP ; save all registers used
- Push DI
- Push SI
-
- ;---------------------------------------------------------------------------
- ; Find Extended Memory Size
- ;---------------------------------------------------------------------------
-
- Xor BX,BX ; assume no extended memory
- Mov AX,0FFFFh ; Read system byte
- Mov ES,AX ; Store segment in ES
- Mov AL,ES:[0EH] ; Get System ID.
- Cmp AL,0FCh ; Check if AT, PS/2 Model 50 & 60
- ; most AT clones use same code too
- ; including COMPAQ 286 & 386 machines
- ; PS/2 Model 30/286, AT&T 6300 Plus
- ; Tandy AT clones, etc.
- JZ Find_Extended ; If AT, get extended.
- Cmp AL,0F8h ; Check if &HF8: Model 80 & Model 70
- ; or Model 55SX
- JZ Find_Extended ; OK, get extended.
- Jmp Short Exnted_Exit ; else exit, because PC, XT, JR,
- ; Convertible, Model 25, 30, other.
- Find_Extended:
- Mov AH,88h ; Retrieve extended memory size.
- CLC ; a fix for IBMCACHE
- ; documented in P.C. Mag
- ; June 27, 1989, page 303 EMS40.SYS
- ; same fix in XMS.SYS version 2.03
- Int 15h ; value returned in AX
- JC Exnted_Exit ; If carry set, then error.
- ; This should stop errors in clones
- ; too.
- Mov BX,AX ; o.k., store value in BX temporarily
-
- Exnted_Exit:
- STI ; I think this will prevent crash on
- ; AT&T 6300 (though an AT&T 6300 would
- ; not get this far). AT&T bios error
- ; is the failure to reset interrupts??
- ; This should not be a problem with
- ; AT&T 6300 Plus and later models
- ; after calling Int 15h
- Mov AX,BX ; get value from BX & store in AX
- Mov BX,[BP+10]
- Mov [BX],AX ; store back in integer variable
-
- ;---------------------------------------------------------------------------
- ;Find Expanded Memory Size
- ;---------------------------------------------------------------------------
-
- Mov AX,3567h ; Retrieve EMM interrupt vector.
- Int 21h ; stores result in ES:BX
- Xor BX,BX ; Assume no expanded memory.
- Mov DI,0Ah ; Set DI to offset 10 of vector
- Cld ; clear the direction flag
- Push DS ; Save DS
- Mov AX,CS
- Mov DS,AX ; Set DS to CS
-
- Assume DS:@code
-
- Mov SI,OFFSET CS:EXPMEM ; DS:SI points to EMMXXXX0.
- Mov CX,EXPMEM_LENGTH ; CX has length of "EMMXXXX0"
- REPZ CMPSB ; ES:DI destination, DS:SI source
- Pop DS ; restore DS
-
- Assume DS:@data
-
- JNZ EXPANDED_EXIT ; If no, then no LIM manager.
- Mov AH,42h ; Else, retrieve free expanded.
- Int 67h ; returns free pages in BX
- ; total pages in DX
- Xor BX,BX ; clear BX to catch errors
- Or AH,AH ; if AH = 0 then EMS is ok
- JZ @f ; so jump forward, else
- Mov BX,-1 ; report EMS with error
- Jmp Short EXPANDED_EXIT ; EMS error so exit
- @@:
- Mov AX,16 ; multiply total page count by 16
- Mul DX ; this converts DX pages to KB
- ; result in DX:AX
- Mov BX,AX ; store AX in BX temporarily
-
- EXPANDED_EXIT:
- Mov AX,BX ; get value from BX & store in AX
- Mov BX,[BP+8]
- Mov [BX],AX
-
- ;---------------------------------------------------------------------------
- ; XMS Memory test
- ; Source: XMS Specs (Microsoft 1989)
- ; Note unless you have version 2.06 or higher, information is not accurate
- ; i.e. 64kb of HIMEM area is reported as free when that is not so.
- ; This routine will adjust free XMS if version <2.06 and >1.xx. The only
- ; common version with this error is Version 2.04.
- ;---------------------------------------------------------------------------
- Mov AH,30h ; test DOS version
- Int 21h ; if less than 3.x XMS does
- Cmp AL,3 ; not exist
- JB XMS_err ; so quit now
- Mov AX,4300h ; call Int 2Fh function. Int 2Fh
- Int 2Fh ; wasn't initialized before DOS 3.xx
- Cmp AL,80h
- Je XMS1 ; XMS exists so jump forward
- XMS_err:
- Mov AX,0 ; XMS does not exist or error
- Jmp Short XMS_end ; so exit
- XMS1:
- Mov AX,4310h ; get address of XMS driver
- Int 2Fh ; from ES:BX
- Mov Word Ptr Drv_ADDR,BX ; save far pointer
- Mov Word Ptr Drv_ADDR+2, ES ; from XMS for use below
- Xor AH,AH ; call function 0
- Call [Drv_ADDR] ; indirect far call to driver
- Cmp AX,0200h ; if not version 2 or above
- Jb XMS_err ; then quit, too old to be useful
- Xor DI,DI ; Assume minor version is 2.06 or
- ; above
- Cmp BX,0206h ; check minor version (BCD number)
- Jae FindFree ; verion o.k., so we will skip ahead
-
- ;---------------------------------------------------------------------------
- ; Minor versions before Version 2.06 incorrectly reported HMA as part of free
- ; XMS space, SO LONG AS none of the XMS had been allocated. As soon as any
- ; space was allocated the amount of purported free space was corrected.
- ; Version 2.06 corrected this bug. Most recent version of HIMEM.SYS is
- ; Version 2.60, July 1990. Existence of error observed with Version 2.04,
- ; (10/6/88), the version that came with Windows 286.
- ;---------------------------------------------------------------------------
-
- Mov DI,64 ; remember to eliminate 64kb from
- ; amount reported as free
- FindFree:
- Mov AH,08
- Call [Drv_ADDR] ; indirect far call to driver
- Or AX,AX ; if AX <> 0
- JNZ XMS2 ; then no error occured
- Cmp BL,0A0h ; if BL set (all XMS allocated)
- JZ XMS2 ; then no error,
-
- BadNum:
- Mov DX,-1 ; else report XMS error
- ; for all other error codes
- Jmp Short PropVer
-
- XMS2:
- Or DI,DI ; was version less than 2.06?
- JZ PropVer ; nope, so skip ahead
- Mov CX,DX ; store DX in CX
- ; CMOS routine destroys AX,DX
-
- ;------------------------------------------------------------------------------
- ; Solution to problem is to compare amount of Extended Memory installed
- ; with amount of XMS free. If number is the same, the HIMEM area is
- ; erronously included in XMS free number and we have to reduce XMS free
- ; by 64 kb in verions before 2.06.
- ;------------------------------------------------------------------------------
-
- Mov AL,48 ; tell CMOS want to look at
- Out 70h,AL ; byte in register 48
- In AL,71h ; the low byte of extended memory
- Mov BL,AL ; store in BL
- Mov AL,49 ; tell CMOS want to look at
- Out 70h,AL ; byte in register 49
- In AL,71h ; the high byte of extended memory
- Mov BH,AL ; store in BH
- Mov DX,CX ; get XMS free value back again
- Cmp DX,BX ; total free = total installed?
- ; if no, then some space has been
- ; allocated in XMS so do not have to
- ; make a correction.
- JNE PropVer ; no, so skip ahead as no adjustment
- ; is necessary
- Sub DX,DI ; else reduce free mem. by HMA space
-
- PropVer:
- Mov AX,DX ; store free memory in AX
- ; KB of free extended in AX
- XMS_end:
- Mov BX,[BP+6] ; get address of last parameter
- Mov [BX],AX ; store AX in XMS%
-
- ;Final Cleanup
-
- Pop SI ; restore all the registers we used
- Pop DI
- Pop BP
- Ret 6 ; 2 * 3 parameters
- OTHERMEMORY Endp
-
- ;===========================================================================
- ; DECLARE FUNCTION FINDDRIVES% ()
- ; Returns number of current logical drives w/o any errors
- ;
- ; Because LASTDRIVE default value = 5, it is likely that
- ; number of logical drives will be less than LASTDRIVE in CONFIG.SYS
- ; This routine will miss a drive if there are gaps between logical drives
- ; as can occur if SUBST is used.
- ;===========================================================================
-
- .code
- EVEN
- Storage DB 0
-
- EVEN
- FINDDRIVES PROC FAR
- Push BP
- Mov BP,SP
- Mov AH,19h ; read default drive
- Int 21h
- Mov CS:Storage,AL ; store default in Storage
- Mov AH,30h ; read DOS version
- Int 21h
- Cmp AL,02 ; if less than 3.xx then exit
- JBE Dos_Ver2 ; because DOS ver <3.xx returns total number
- ; of logical drives in AL so we don't
- ; need to test.
- Mov DL,CS:Storage ; put default back in DL
-
- Main_Loop:
- Mov AH,0Eh ; select default drive
- Inc DL ; add one to the current default
- Int 21h ; read next drive above current
- Mov AH,19h ; read default drive
- Int 21h
- Cmp AL,DL ; did default change?
- JZ Main_Loop ; yes so jump back
- Push DX ; save next drive
- Mov DL,CS:Storage ; reload current
- Mov AH,0Eh ; select orginal drive
- Int 21h
- Pop DX ; get next drive
- Mov AL,DL ; store in AL
- Jmp Short Exit_Routine
-
- Dos_Ver2:
- Mov DL,CS:Storage ; reset current
- Mov AH,0Eh ; In version 2, max logical drives in AL
- Int 21h ; in version 2, min number of drives is 2
-
- Exit_Routine:
- Xor AH,AH ; clear AH, since limit is 26 logical drives
- Xor DX,DX
- Pop BP
- Ret ; exit
- FINDDRIVES Endp
-
- ;============================================================================
- ; DECLARE FUNCTION ANSICHECK%()
- ; IF ANSICHECK% THEN
- ; PRINT "ANSI.SYS is installed."
- ;
- ; Source: Disassembled COMMAND.COM Version 3.3 of CLS command
- ; xxxx:2B62h is the beginning of the routine
- ;
- ; VERY FAST and NOT MESSY!!!!
- ;
- ;This is the same method that COMMAND.COM uses to test for ANSI.SYS
- ;so every utility had better allow for this testing method.
- ;
- ; NOTE: PC Magazine's ANSI.COM even if turned off will still report ANSI.SYS
- ; present, (it was planned that way so it would handle CLS).
- ;============================================================================
-
- EVEN
- ANSICHECK PROC FAR
- Push BP
- Mov CX,-1 ; assume that ANSI is installed
- Mov AX,3529h ; get address of INT 29h (FAST PUTCHAR)
- Int 21h
- Mov DX,ES ; store segment in DX
- Mov AX,3520h ; get address of INT 20h, terminate function
- Int 21h ; INT 20h usually points to COMMAND.COM
- Mov AX,ES
- Cmp DX,AX ; if segment for INT 29 > INT 20 then ANSI
- JA Ender1 ; is installed
- Xor CX,CX ; else, ANSI not installed
- Ender1:
- Mov AX,CX ; store status in AX
- Xor DX,DX
- Pop BP
- Ret
- ANSICHECK ENDP
-
- COMMENT |
- The following routine is included just to show an alternative method. To use
- remove the comment and add name to PUBLIC
- ;===========================================================================
- ; DECLARE FUNCTION OTHERANSI ()
- ; OTHERANSI
- ;
- ; RETURNS
- ; 0 if ANSI.SYS or ANSI.COM not installed
- ; -1 if ANSI.SYS or ANSI.COM installed
- ;
- ; Theory:
- ; Uses DOS CON driver to request ANSI cursor report. If ANSI is
- ; installed cursor report will store current cursor location in CON.
- ; The curor report is a minimum of 6 bytes long, and it could
- ; be longer. Therefore, routine clears out CON driver.
- ;
- ; Failure to clean out CON means DOS will read garbage as a file
- ; load request at end of QBASIC program. QBASIC never reads CON,
- ; only reads the keyboard. DOS reads CON when running COMMAND.COM.
- ; This detection method is a reliable, though messy way, to do it
- ; because it will overwrite display if ANSI is not installed.
- ;
- ; Caution:
- ; If ANSI is not loaded will overwrite display at current BIOS cursor
- ; location. QBASIC routine should set cursor with LOCATE and overwrite
- ; area with text if ANSI not found. DOS appears to write only to page 0
- ;===========================================================================
-
- .code
-
- EVEN
- CursReport DB 27,'[6n$' ; ANSI Report Cursor sequence
-
- EVEN
- OTHERANSI PROC FAR
- Push BP
- Push DS
- Mov AX,0C00h ; clear keyboard buffer
- Int 21h ; using a safe method
- ; there are faster methods
- Mov AX,CS
- Mov DS,AX ; make DS == CS
-
- Assume DS:@code ; DOS uses DS:DX to point to
- ; source of Output String
-
- Mov DX, OFFSET CursReport ; ANSI CMD to get cursor position
- Mov AH, 9 ; Write ANSI escape sequence DS:DX
- Int 21h ; to display with DOS String output
-
- Mov AH, 6 ; Read & ignore Esc character
- Mov DL, 0FFh ; in keyboard buffer
- Int 21h
- JZ ErrorExit ; If ZF set, then ANSI not loaded
- Mov AH, 6 ; Read & ignore "[" character
- Int 21h
- JZ ErrorExit ; If ZF set, then ANSI not loaded
- Mov AH, 6 ; Get 1st digit of cursor row
- Int 21h
- JZ ErrorExit ; If ZF set, then ANSI not loaded
-
- Mov BX, -1 ; Return -1 if ANSI is installed
- Jmp SHORT Clear_CON_Loop
-
- ErrorExit:
- Sub BX, BX ; Return 0 if ANSI
- ; driver not installed
- Clear_CON_Loop:
- Mov AH, 6 ; clear out rest of control
- Mov DL, 0FFh ; information from CON
- Int 21h ; driver if ANSI is installed
- JNZ Clear_CON_Loop ; and cursor not at LOCATE 1,1
-
- Mov AX,BX ; restore value from BX in AX
- ; for return through function
- Pop DS ; restore DS
-
- Assume DS:@data
-
- Pop BP ; restore BP
- Ret
- OTHERANSI ENDP
- |
-
-
- ;============================================================================
- ; DECLARE FUNCTION ACTUALEXTND% ()
- ; Returns:
- ; Actual amount of extended memory installed on 80286, 80386 or 80486
- ; machine as stored in CMOS RAM
- ; If clock battery is bad, will return a -1
- ;============================================================================
-
- EVEN
- ACTUALEXTND PROC FAR
- Xor BX,BX ; assume no extended memory
- Mov AX,0FFFFh ; Read system byte
- Mov ES,AX ; Store segment in ES
- Mov AL,ES:[0EH] ; Get System ID.
- Cmp AL,0FCh ; Check if AT, PS/2 Model 50 & 60
- ; most AT clones use same code too
- ; including COMPAQ 286 & 386 machines
- ; PS/2 Model 30/286, AT&T 6300 Plus
- JZ Find_Extended1 ; If AT, get extended.
- Cmp AL,0F8h ; Check if &HF8: Model 80 & Model 70
- ; or Model 55SX
- JZ Find_Extended1 ; OK, get extended.
- Jmp Short Finis2 ; else exit, because PC, XT, JR,
- ; Convertible, Model 25, 30, other.
- ; Can't just test for 80286 chip
- ; because could be on an accelerator
- ; board
- Find_Extended1:
- Mov AL,14 ; see if battery good in
- Out 70h,AL ; CMOS status register D
- In AL,71h
- Test AL,80h ; bit 7 set if battery bad
- JNZ Finis3 ; if set quit
-
- Mov AL,48 ; tell CMOS want to look at
- Out 70h,AL ; byte in register 48
- In AL,71h ; the low byte of extended memory
- Mov BL,AL ; store in BL
-
- Mov AL,49 ; tell CMOS want to look at
- Out 70h,AL ; byte in register 49
- In AL,71h ; the high byte of extended memory
- Mov BH,AL ; store in BH
-
- Finis2:
- Mov AX,BX ; put BX in AX to report size
- Xor DX,DX ; in case call as Long
- Ret
- Finis3:
- Mov BX,-1 ; put -1 in BX if clock battery bad
- Jmp Short Finis2
- ACTUALEXTND ENDP
- END