This routine, called durining initialization, will attempt to detect and identify the system’s FPU.
SYS074C: MOV BX,FPU.StatusWord
Get pointer to Status Word of FPU Data.
SYS074F: XOR DI,DI
SYS0751: MOV ES,[PrefixSeg]
SYS0755: ES:
SYS0756: MOV ES,[PrefixSeg:002C]
Set ES:DI to the address of DOS environment in the PrefixSeg:002C.
SYS075A: MOV CX,7FFF
SYS075D: CLD
Prepare to search the entire segment (64K bytes ~ 32K words).
SYS075E: ES:
SYS075F: MOV AX,[DI]
SYS0761: OR AL,AL
SYS0763: JZ 0780
Check if we have reached the end of the environment string.
SYS0765: CMP AX,3738
Check if the characters in ES:DI are ‘87’.
SYS0768: JNZ 077A
SYS076A: ES:
SYS076B: MOV AX,[DI+02]
SYS076E: CMP AL,3D
SYS0770: JNZ 077A
Check if the next character is ‘=’ (3Dh).
SYS0772: AND AH,DF
SYS0775: CMP AH,59
SYS0778: JMP 079D
Check if the environment string contains the cahracters ‘87=Y’.
SYS077A: XOR AX,AX
SYS077C: REPNZ
SYS077D: SCASB
SYS077E: JZ 075E
Continue searching through the environment variables.
SYS0780: XOR AX,AX
SYS0782: PUSH SP
SYS0783: POP DX
SYS0784: CMP DX,SP
SYS0786: JNZ 078A
Check stack?
SYS0788: OUT F0,AL
Clear FPU Busy Latch (Port F0) by writing 00h to it.
SYS078A: FINIT
SYS078C: MOV [BX],AX
Intializes:
SYS078E: FSTCW [BX]
Get Control Word and Store in [BX].
SYS0790: MOV CX,0014
SYS0793: LOOP 0793
Delay?
SYS0795: MOV AX,[BX]
SYS0797: AND AX,0F3F
SYS079A: CMP AX,033F
Retrieve Control Word from [BX] then check if:
SYS079D: MOV DX,1330
SYS07A0: MOV AL,00
Set defaults:
SYS07A2: JNZ 07D1
Exit if Control Word does not match expected setting, i.e. No FPU.
SYS07A4: PUSH SP
SYS07A5: POP AX
SYS07A6: CMP AX,SP
SYS07A8: MOV AL,01
SYS07AA: JNZ 07D1
If stack behavior is different then:
SYS07AC: WAIT
SYS07AD: FINIT
Initialize FPU again.
SYS07AF: WAIT
SYS07B0: FLD1
Load 1.0 onto the stack.
SYS07B2: WAIT
SYS07B3: FLDZ
Load 0.0 onto the stack.
SYS07B5: WAIT
SYS07B6: FDIVP ST(1),ST
Divide ST(1) = ST(1) / ST = 1.0 / 0.0, then pop off the stack.
SYS07B8: WAIT
SYS07B9: FLD ST(0)
Push ST(0) onto the stack.
SYS07BB: WAIT
SYS07BC: FCHS
Change the sign of ST(0)
SYS07BE: WAIT
SYS07BF: FCOMPP ST(1)
Compare ST(0) and ST(1).
SYS07C1: WAIT
SYS07C2: FSTSW [BX]
Store Status Word in [BX] ([FPU.StatusWord]).
SYS07C4: WAIT
SYS07C5: MOV AX,[BX]
Copy Status Word to AX.
SYS07C7: SAHF
Store AH to Flags. At this point AH contains the upper-8 bits of the Status Word:
Bit | Name | Description | Flag |
---|---|---|---|
07 | B | Busy | SF |
06 | C3 | Condition Code 3 | ZF |
05 | ST | Stack Top Pointer | 0 |
04 | Stack Top Pointer | AF | |
03 | Stack Top Pointer | 0 | |
02 | C2 | Condition Code 2 | PF |
01 | C1 | Condition Code 1 | 1 |
00 | C0 | Condition Code 0 | CF |
SAHF transfers its value into the Flags register using the mapping above.
SYS07C8: MOV AL,02
SYS07CA: JZ 07D1
If ZF is set (= 1) then FPU is a 80287 (AL = 02) because it does not distinguish between a postive infinity and a negative infinity.
SYS07CC: MOV DX,1332
SYS07CF: MOV AL,03
Set:
SYS07D1: MOV [Test8087],AL
SYS07D4: MOV [FPU.ControlWord],DX
SYS07D8: RET
Set FPU type and Control Word and return.
Because it returns with a NEAR RET, it can only be called from within the system library.
See also: Test8087 (Variable), 8087/80287/80387 Control Word, 8087/80287/80387 Status Word, 8087/80287/80387 x87 FPU Evironment, 8087/80287/80387 Temporary data, or go back