;       SCCSID = @(#)d_devcon.asm	6.1 91/02/15
;       SCCSID = @(#)d_devcon.asm	1.5 90/01/22
; ****************************************************************************
; *									     *
; *			  IBM/Microsoft Confidential			     *
; *									     *
; *		    Copyright (c) IBM Corporation  1987, 1990		     *
; *		    Copyright (c) Microsoft Corp.  1987, 1990		     *
; *			      All Rights Reserved			     *
; *									     *
; ****************************************************************************
;***  d_devcon.asm - API stub routine DosDevConfig
;
;       Member of API library
;       Karl Schulmeisters
;       Copyright MicroSoft Corporation, 1986
;       08-May-1986
;
;       library routine for API simulator
;
;       Called from dos 2.x,3.x compatible dos 5.x applications
;
;       Special Information
;               none
;
;       Modification History
;
;       7-25-86 (billme):  add code to mask out and return display type
;
;       14-Aug-86 (billme): remove error check against against
;       reserved parameter
;
;       09-Sep-86 (billme): change removal of error check against
;       reserved parameter to an 'ignore' (return 0) for reserved parameter
;
;       06-Jan-87 (billme): Replace initial pushes and final pops
;       with calls to __api_begin and __api_end resp.  This will
;       reduce the size of FAPI and allow support for signals.
;
;       16-Feb-87 (chernow): changed method for accessing the PC_TYPE
;       and added the facility to handle sub model type.
;
;       11-June-87 (Tarng): remove cli, & check bit 0 of equip flag.
;       21-Apr -89 (chernow): zero config word before loading with info
;
;
;

include basemaca.inc
include error.inc

        EXTRN   __api_begin:near
        EXTRN   __api_end:near


MAX_ITEM        EQU     6
DISPLAY_TYPE    EQU     6
PC_TYPE         EQU     5
SUB_MODEL       EQU     4              ;@@
CO_PROC         EQU     3
DISKETTE        EQU     2
RS232           EQU     1

;; Magic MACHINE ID byte address
SEG_ID_BYTE     EQU     0F000h
OFF_ID_BYTE     EQU     0FFFEh


;; Post-Shift Masks of AX from rom Int 11
CO_PROC_MSK     EQU     1
DISKETTE_MSK    EQU     3
RS232_MSK       EQU     7
LPT_MSK         EQU     3
DSPTYP_MSK      EQU     3

;***    DOSDEVCONFIG - stub to emulate DOSDEVCONFIG function call
;
;       simulates DOS 5.0 call from DOS 2.x,3.x environment
;
;       errorcode = unsigned far pascal
;       DosDevConfig (ptr_VersionWord)
;
;       ENTRY:
;               - ptr_DeviceInfo = pointer to byte for Device info return.
;               - Item_Desired   = Device to return Info aboout
;               - Res_Parm       = Must be Zero (reserved parameter)
;
;       RETURN:
;               AX - 0 (no error)
;
;       EXIT:
;
;       USES:
;               AX
;
;       Pseudo Code:
;               Save registers
;               Use BP as pointer to stack parameters
;               IF (Item_Desired == PC TYPE || Item_Desired == SUB_MODEL)
;                   THEN
;                       IF (RC = ROM INT 15H (func C0h) use configuration table)
;                           IF (Item_Desired == PC TYPE)
;                               *ptr_DeviceInfo = .cp_model
;                           ELSE
;                               *ptr_DeviceInfo = .cp_type
;                       ELSE
;                           IF (Item_Desired == PC TYPE)
;                               *ptr_DeviceInfo = *ptr_MACHINE_ID_BYTE
;                           ELSE
;                               *ptr_DeviceInfo = 0
;                   ELSE
;                       IF (Item_Desired != DISPLAY)
;                           THEN
;                               ROM EQUIP INT (int 11h)
;                               Mask out unncessary info
;                               Shift bits to correct position
;                               *ptr_DeviceInfo = Masked and Shifted value
;                           ELSE
;                               Check for Video type
;               Restore registers
;               Return
;
;       WARNING:
;               may return error code from Dos 2.x, 3.x (see dos manuals)
;
;       EFFECTS:
;               none
;

        title   DOSDEVCONFIG - stub to emulate DOSDEVCONFIG function call
;
;       EXTRN   DOSDEVCONFIG:FAR
;
;       PUSH    @OTHER  ptr_DeviceInfo
;       PUSH    WORD    Item_Desired
;       PUSH    WORD    Parm
;       CALL    DOSDEVCONFIG
;


_TEXT   segment byte public 'CODE'

        assume  CS:_TEXT,DS:NOTHING

        public  DOSDEVCONFIG

ptr_DeviceInfo equ     [BP+0ah]
Item_Desired   equ     [BP+8]
Res_Parm       equ     [BP+6]

;     Format of configuration parameter table as returned @@
;     by Int 15h function C0h

configuration_table struc
cp_length       dw  8           ; length of table
cp_model        db  ?           ; system model byte
cp_type         db  ?           ; system type (submodel) byte
cp_BIOS         db  ?           ; BIOS revision level
cp_flags        db  ?           ; flags
                db  0           ; reserved
                db  0           ; reserved
configuration_table ends

DOSDEVCONFIG   proc    far

        call    __api_begin     ; init bp and save bp,ds,bx,cx,dx,si,di,es
                                ; required to save: bp,ds,bx

        cmp     word ptr Res_Parm, 0    ; IF (Res_Parm != 0)
        jne     DevParmErr              ;   THEN return ERROR! INVALID_FUNCTION

        mov     BX,Item_Desired         ; Range Check Item requested

; see ptms 2550 and 2904
;@@     mov     al,0                    ;  (ignore reserved item ... 9-9-86)
;@@     cmp     BX,RESERVED             ;  Since we are Zero based, we only
;@@     je      DevConRet               ;  need do an unsigned compare to

        cmp     BX,MAX_ITEM             ; MAX_ITEM, and a Check for the RESERVED
        jbe     DevConCnt               ;  Function

DevParmErr:
        mov     AX,error_invalid_parameter
        jmp     DevConRetErr           ;@@

DevConCnt:
        cmp     BX,PC_TYPE             ; Check if requesting Model @@
        je      DevInt15               ;

DevConSub:                             ; Check if requesting SubModel
        cmp     BX,SUB_MODEL
        jne     DevCon1

DevInt15:
; attempt to determine machine model and type via
; BIOS int 15 (function C0h)
; warning: interrupts are enabled
        push    bx                     ;save call type
        mov     ah,0c0h                ; set configuration parameters
        int     15h                    ;   pointer
;       cli                            ; make sure interrupts are off
        pop     dx
        jc      Dev15Fail              ;


; int 15h worked
        cmp     DX,PC_TYPE              ; did we want TYPE
        jne     Dev15Sub                ; no, submodel

        mov     AL,ES:[BX].cp_model     ; Return the MACHINE ID_BYTE
        jmp     short DevConRet

Dev15Sub:
        mov     AL,ES:[BX].cp_type      ; Return the MACHINE SUBMODEL
        jmp     short DevConRet

Dev15Fail:

; int 15 failed
        cmp     DX,PC_TYPE              ; did we want TYPE
        jne     DevSub                  ; no, submodel

        mov     AX,SEG_ID_BYTE          ; Return the MACHINE ID_BYTE
        mov     DS,AX
        mov     AL,DS:[OFF_ID_BYTE]
        jmp     short DevConRet

DevSub:
        xor     al,al                   ; 0 is submodel if int 15 not supported
        jmp     short DevConRet

DevCon1:
        int     11h                     ; ROM Equip. interrupt
        ror     AX,1                    ; save bit 0

        cmp     BX,CO_PROC
        jne     DevCon2

        and     AL,CO_PROC_MSK          ; Return Co-Processor Presence bit
        jmp     short DevConRet

DevCon2:
        shr     AX,1
        shr     AX,1
        shr     AX,1

        cmp     BX,DISPLAY_TYPE
        jne     DevCon3
                                        ; transform 0,1,2 (color display) -> 1
        and     AL,DSPTYP_MSK           ; transform 3 (b&w display) -> 0
        xor     AL,DSPTYP_MSK           ; (see also AT tech manual - int 11)
        jz      DevConRet
        mov     AL,1
        jmp     short DevConRet         ; Return the Primary Display Adapter
DevCon3:
        shr     AX,1
        shr     AX,1
        cmp     BX,DISKETTE
        jne     DevCon4

        test    ah,100b                 ; Is old bit 0 = 0?
        jnz     DevCon35                ; No, exist diskette drive
        xor     al,al                   ; no diskette drive
        jmp     short DevConRet

DevCon35:
        and     AL,DISKETTE_MSK         ; Return Number of internal floppies
        inc     AL                      ; ROM returns # diskettes - 1
        jmp     short DevConRet
DevCon4:
        shr     AX,1
        shr     AX,1
        shr     AX,1
        cmp     BX,RS232
        jne     DevCon5

        and     AL,RS232_MSK
        jmp     short DevConRet
DevCon5:
        shr     AX,1
        shr     AX,1
        shr     AX,1
        shr     AX,1
        shr     AX,1
        and     AL,LPT_MSK
DevConRet:
        lDS     BX,ptr_DeviceInfo
        mov     word ptr DS:[BX],0      ;CP12 B701317 - Zero out word first
        mov     byte ptr DS:[BX],AL
        xor     AX,AX
DevConRetErr:

        call    __api_end       ; check sigs & restore es,di,si,dx,cx,bx,ds,bp

        ret     8       ; clear stack of entry parameters (bytes)
DOSDEVCONFIG   endp

_TEXT   ends

        end
