;*DDK*************************************************************************/
;
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
;/*****************************************************************************
;*
;* SOURCE FILE NAME = TOUMOUA.ASM
;*
;* DESCRIPTIVE NAME = Touch display mouse ABIOS device driver
;*
;*
;* VERSION      V2.0
;*
;* DATE         07/19/91
;*
;* DESCRIPTION
;*
;* FUNCTIONS    mou_strat_entry,        idc_entry,      idc_q_conf,
;*              idc_read_en,            idc_read_dis,   idc_enable_dev,
;*              idc_disable_dev,        req_deins,      req_init,
;*              hw_init.
;*
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*****************************************************************************/

.286p

.seq
DSEG    segment para public 'DATA'
DSEG    ends
CSEG    segment para public 'CODE'
CSEG    ends


.xlist
.xcref

include struc.inc
include proc.inc
include toudderr.inc
include touequ.inc
include toustruc.inc
include toumacro.inc

.cref
.list

        extrn   DOSWRITE:far
        extrn   DOSREAD:far
        extrn   putstr:near
        extrn   pstr:near
        extrn   toudd_fail:byte
        extrn   conf_data:byte
        extrn   getputmsg:near
        extrn   dev_status:word

public  mou_header, mou_int_pkt_off, mou_dddd_idc, mou_dev_status
public  mconf_irqnum


dseg    segment

mou_header      dw      -1
                dw      -1
                dw      0C080h
                dw      mou_strat_entry
                dw      idc_entry
                db      'PDIMOU$ '
                dw      0
                dw      0
                dw      0
                dw      0

devhlp          dd      0               ; DevHlp entry point (bimodal)
mou_dev_status  dw      0               ; internal DD status for mouse
mou_int_pkt_off dw      0               ; addr shared int pkt, owned by DIDD
data_pkt        db      3 dup (0)       ; interrupt routine data buffer
data_count      dw      0               ; data_pkt count
didd_name       db      'MOUSE$  '      ; name of DIDD
mou_dddd_idc    IDC     <?>             ; returned data from AttachDD

;*
;* ABIOS
;*

        extrn   abios_cmd:near
        extrn   cmd_rqb:byte


idc_table       label   word
IDC_MIN         equ     1

                dw      idc_q_conf
                dw      idc_read_en
                dw      idc_read_dis
                dw      idc_enable_dev
                dw      idc_disable_dev

IDC_MAX         equ     (($-idc_table)/2)+IDC_MIN-1

;*
;* Mouse configuration data
;*

mconf_data      dw      6               ; size
                db      50h             ; num mics
mconf_buttons   db      2               ; num buttons
mconf_irqnum    db      0               ; IRQ num
                db      5               ; (type) IBM PS/2 8516 Touch Display

END_DATA        equ     $

dseg    ends


cseg    segment
        assume  cs:cseg, ds:dseg

;/***************************************************************************
;*
;* FUNCTION NAME = mou_strat_entry
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

public          mou_strat_entry
pubdeb          mou_strat_entry
PROCEDURE       mou_strat_entry far

VARIABLE        temp_es word
VARIABLE        temp_bx word

        BEGINPROC

        mov     temp_es, es
        mov     temp_bx, bx

        .if     <<word ptr devhlp.xseg> ne 0> and
        test    mou_dev_status, DEVS_DEINS
        .if     <z>
                ;*
                ;* init done and not deinstalled
                ;*

                .if     <es:[bx].req_cmd eq CMD_DEINS>
                        ;*
                        ;* deinstall cmd
                        ;*
                        call    req_deins

                        or      mou_dev_status, DEVS_DEINS

                        DH_DEVDONE      temp_es, temp_bx

                .else                   ; not deinstall cmd

                        mov     es:[bx].req_status, STAT_UCMD

                        or      es:[bx].req_status, STAT_DONE


                .endif                  ; cmd test

        .else                           ; not init

                .if     <es:[bx].req_cmd eq CMD_INIT>
                        ;*
                        ;* init cmd
                        ;*
                        call    req_init

                .else                   ; not init cmd

                        mov     es:[bx].req_status, STAT_UCMD

                .endif                  ; cmd test

                or      es:[bx].req_status, STAT_DONE

        .endif                          ; init/deins test

FREEVAR temp_es
FREEVAR temp_bx

        ENDPROC mou_strat_entry


;/***************************************************************************
;*
;* FUNCTION NAME = idc_entry
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

idc_entry       proc    far

        push    bx

        .if     <ax ge IDC_MIN> and
        .if     <ax le IDC_MAX> and
        test    mou_dev_status, DEVS_DEINS
        .if     <z>
                ;*
                ;* IDC func valid & installed
                ;*
                sub     ax, IDC_MIN
                mov     bx, ax
                shl     bx, 1
                call    idc_table[bx]

        .else
                ;*
                ;* IDC func illegal or deinstalled
                ;*
                ;* flag error
                ;*
                stc
                mov     ax, 1

        .endif

                pop     bx
                ret

idc_entry       endp


;/***************************************************************************
;*
;* FUNCTION NAME = idc_q_conf
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

idc_q_conf      proc    near

        mov     cx, es:[di]

        .if     <cx gt 6>
                mov     cx, 6
        .endif

        mov     si, offset mconf_data
        cld
        rep     movsb

        clc
        ret

idc_q_conf      endp


;/***************************************************************************
;*
;* FUNCTION NAME = idc_read_en
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

idc_read_en     proc    near

        cli

        test    mou_dev_status, DEVS_ATTACHED
        .if     <z>
                ;*
                ;* not attached
                ;*
                ;* save shared int packet addr
                ;*
                mov     mou_int_pkt_off, di

                DH_ATTACHDD     didd_name, mou_dddd_idc
                .if     <nc>
                        ;*
                        ;* attach successful
                        ;*
                        or      mou_dev_status, DEVS_READ_EN+DEVS_ATTACHED

                        ;*
                        ;* show now attached to mou didd
                        ;*
                        or      conf_data.conf_mou_stat, MS_DI_ATTACHED

                .endif

        .else                           ; attached

                or      mou_dev_status, DEVS_READ_EN
                clc

        .endif                          ; attach test

        sti
        ret

idc_read_en     endp


;/***************************************************************************
;*
;* FUNCTION NAME = idc_read_dis
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

idc_read_dis    proc    near

        cli
        and     mou_dev_status, not DEVS_READ_EN
        sti

        clc
        ret

idc_read_dis    endp


;/***************************************************************************
;*
;* FUNCTION NAME = idc_enable_dev
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

idc_enable_dev  proc    near

        or      dev_status, DEVS_EN_DEV

        xor     ax, ax
        clc

        ret

idc_enable_dev  endp


;/***************************************************************************
;*
;* FUNCTION NAME = idc_disable_dev
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

idc_disable_dev proc    near

        and     dev_status, not DEVS_EN_DEV

        xor     ax, ax
        clc

        ret

idc_disable_dev endp


;/***************************************************************************
;*
;* FUNCTION NAME = req_deins
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

req_deins       proc    near

        test    mou_dev_status, DEVS_ATTACHED
        .if     <nz>
                ;*
                ;* attached to didd so tell it we are deinstalling
                ;*
                XIDC_DISSUP     mou_dddd_idc

        .endif

        ret

req_deins       endp


;/***************************************************************************
;*
;* FUNCTION NAME = req_init
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

PROCEDURE       req_init        near
VARIABLE        temp_es         word
VARIABLE        temp_bx         word
        BEGINPROC

        mov     temp_es, es
        mov     temp_bx, bx

        ;*
        ;* set devhlp entry
        ;*
        mov     ax, word ptr es:[bx].req_data.init_pointer_1.xoff
        mov     word ptr devhlp.xoff, ax
        mov     ax, word ptr es:[bx].req_data.init_pointer_1.xseg
        mov     word ptr devhlp.xseg, ax

        ;*
        ;* init req block status
        ;*
        mov     es:[bx].req_status, STAT_NOERR

        ;*
        ;* init HW
        ;*
        call    hw_init
        .if     <c>

req_init_bad:
        ;*
        ;* mouse failed message
        ;*
        push    INF_DD_FAILURE
        push    0
        call    getputmsg

        .if     <toudd_fail eq 0>
                ;*
                ;* jif touch dddd did NOT fail to load, so keep DD
                ;*

                jmp     short req_init_keep

        .endif
                ;*
                ;* only release DD memory if both touch & mouse failed
                ;*

                SET_REQSTAT     STAT_GENF

                mov     es, temp_es
                mov     bx, temp_bx

                ;*
                ;* release all memory & cause DD to be unloaded
                ;* mov    word ptr es:[bx].req_data.init_data_1, 0
                ;*
                mov     word ptr es:[bx].req_data.init_pointer_1.xoff, 0
                mov     word ptr es:[bx].req_data.init_pointer_1.xseg, 0

        .else                           ; init ok
                ;*
                ;* success message
                ;*
                push    INF_DD_MOULD
                push    0
                call    getputmsg

req_init_keep:
                mov     es, temp_es
                mov     bx, temp_bx

                mov     word ptr es:[bx].req_data.init_pointer_1.wlo, offset END_CODE
                mov     word ptr es:[bx].req_data.init_pointer_1.whi, offset END_DATA

        .endif

FREEVAR         temp_es
FREEVAR         temp_bx

ENDPROC         req_init


;/***************************************************************************
;*
;* FUNCTION NAME = hw_init
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

hw_init         proc    near

        ;*
        ;* get POST, system data area
        ;* for Patriot gate array
        ;*

        push    es
        mov     ax, BIOS_DATA_AREA
        mov     es, ax
        mov     si, BDA_EQUIPMENT
        mov     ax, es:[si]
        pop     es

        .if     <bit ax nand BDA_EQUIP_PD>
                ;*
                ;* mouse (P.D.) not found
                ;*
                jmp     short hw_init_pretend
        .endif

        ;*
        ;* mouse found
        ;*
        ;* disable mouse
        ;*
        mov     ax, ABIOS_DISABLE
        mov     si, offset cmd_rqb
        call    abios_cmd
        .if     <c>
                jmp     short hw_init_fail
        .endif

        ;*
        ;* reset mouse
        ;*
        mov     ax, ABIOS_RESET         ; abios func - reset
        mov     si, offset cmd_rqb
        call    abios_cmd
        .if     <c>
                jmp     short hw_init_fail
        .endif

        ;*
        ;* set sample rate
        ;*
        mov     ax, ABIOS_SETRATE
        mov     si, offset cmd_rqb
        mov     word ptr [si].abrqb_ssp.2, 60   ; sample rate (0x3C)
        call    abios_cmd
        .if     <c>
                jmp     short hw_init_fail1
        .endif

        ;*
        ;* set resolution
        ;*
        mov     ax, ABIOS_SETRESOL
        mov     si, offset cmd_rqb
        mov     word ptr [si].abrqb_ssp.2, 3    ; resolution (3 - 8 counts/mm)
        call    abios_cmd
        .if     <c>
                jmp     short hw_init_fail1
        .endif

        ;*
        ;* enable
        ;*
        mov     ax, ABIOS_ENABLE
        mov     si, offset cmd_rqb
        call    abios_cmd
        .if     <c>
                jmp     short hw_init_fail2
        .endif

hw_init_ok:

        clc                             ; no errors
        ret

hw_init_fail:
        ;*
        ;* mouse failed to reset
        ;*
        .if     <bit conf_data.conf_mou_stat and <MS_PROT_EMUL or MS_REAL_EMUL>>
                ;*
                ;* real || prot emulation enabled
                ;*
                .if     <ax eq 8001h>
                        ;*
                        ;* if emul=on  AND error == resend, ie. no response
                        ;* then pretend mouse present
                        ;*
hw_init_pretend:
                    .if <toudd_fail eq 0>
                        ;*
                        ;* touch has NOT failed to load
                        ;* no real mouse present
                        ;*
                        and     conf_data.conf_mou_stat, not MS_REAL_MOUSE

                        ;*
                        ;* change number of buttons
                        ;*
                        mov     mconf_buttons, 1

                        jmp hw_init_ok
                    .endif
                .endif
        .endif

hw_init_fail1:
hw_init_fail2:

        stc                             ; errors occurred
        ret

hw_init         endp


END_CODE        equ     $


cseg    ends

        end

;*
;* end
;*
