Code:
{Key kids, let's do all sorts of extended CGA adapter detection!
Tandy, PCjr, AT&T 6300, Compaq Portable III, you name it!}
{First, the PCjr/Tandy family, as they have relocatable video ram.}
{PCjr, Tandy, Tandy SL/TL code inspired by Jason Knight}
asm
mov ax,$FFFF
mov es,ax
mov di,$000E { second to last byte PCjr/Tandy BIOS info area }
cmp byte ptr es:[di],$FD { ends up $FD only on the Jr. }
jne @notJr
mov result,1 {videoCard_pcJr}
jmp @done
@notJr: { not junior, test for tandy }
cmp byte ptr es:[di],$FF { all tandys have $FF here }
jne @notTandy
mov ax,$FC00
mov es,ax
xor di,di
mov al,$21
cmp byte ptr es:[di],$21
jne @notTandy
mov ah,$C0
int $15 { Get System Environment }
jnc @tandySLTL { early Tandys error out, TL/SL does not }
mov result,2 {tandy1000}
jmp @done
@tandySLTL:
mov result,3 {tandySLTL}
jmp @done
@notTandy:
mov result,0 {all other cards eliminated, must be CGA}
@done:
end;
case result of
1:s:='IBM PCjr';
2:s:='Tandy 1000';
3:s:='Tandy 1000 SL/TL';
end;
{Now check for specific adapters based on various criteria.
This was really tough for me; I tried all sorts of ideas to detect
these adapters and modes, but in the end, such bit-banging is not
safe. A true "universal" 640x400 detector is just not possible without
the possibility of crashing unknown hardware.}
asm
{First, check for AT&T/Olivetti using the model byte, which they
have been so kind as to implement broken (returns 0000)}
mov ah,$C0
int 15h {6300 has NO 15h support in BIOS }
jc @ATTFound {if CF=1, error; try to detect 6300 some other way}
mov ax,es:[bx+2] {grab model word}
cmp ax,$01FC {See if we're on the Compaq 400-line adapter/plasma}
je @CompaqFound
jmp @error
@CompaqFound:
{We think we are on a Compaq Portable III. Let's see if we can detect
the internal plasma monitor.}
mov dx,1BC6h
in al,dx
mov cl,4
shr al,cl
mov result,al {If this is plasma, result=4 if 400-line}
jmp @done
@ATTFound:
{Let's try a second check for the 6300/M24.
Run a 6300/M24-specific BIOS INT. If it returns info, we are SURE
we are on a 6300/M24 and try to grab monitor ID bits from 3dah.
;Int 1A/AH=FEh
;AT&T 6300 - READ TIME AND DATE
;AH = FEh
;Return:
;BX = day count (0 = Jan 1, 1984)
;CH = hour
;CL = minute
;DH = second
;DL = hundredths}
xor cx,cx
mov dx,cx
mov ax,0fe00h
int 1ah
or cx,dx {if any bits are set anywhere, we have 6300/M24}
jcxz @error {no bits? No 6300/M24!}
mov dx,03dah {a monitor ID in bits 4-5 (2=colour, 3=mono}
in al,dx {If a DEB is present, bits 6 and 7 will be 0}
mov cl,4
shr al,cl {discard regular status bits}
test al,00000010b {if 2 or 3, bit 1 will be set and we have AT&T}
jz @error
mov result,al
and result,00000011b {mask off DEB bits}
test al,00001100b {if these are unset, we have a DEB}
jnz @done
or result,10000000b {set bit 7 if DEB present}
jmp @done
@error:
mov result,0 {must have made a mistake...?}
@done:
end;
{check our results and set the string}
case (result and $7F) of
2:s:='AT&T/Olivetti (Color Monitor)';
3:s:='AT&T/Olivetti (Monochrome Monitor)';
4:s:='Compaq Portable III (Internal Plasma)';
end;
if (result AND $80)=$80 then s:=s+' + DEB';
Bookmarks