;/*****************************************************************************
;*
;* SOURCE FILE NAME = TOUMOU.ASM
;*
;* DESCRIPTIVE NAME = Touch display mouse device driver
;*
;* COPYRIGHT    COPYRIGHT IBM CORPORATION, 1991, 1992
;*              LICENSED MATERIAL - PROGRAM PROPERTY OF IBM
;*              REFER TO COPYRIGHT INSTRUCTION FORM#G120-2083
;*              RESTRICTED MATERIALS OF IBM
;*              IBM CONFIDENTIAL
;*
;* VERSION      V2.0
;*
;* DATE         10/13/91
;*
;* DESCRIPTION
;*
;* FUNCTIONS    mou_strat_entry,        idc_entry,      idc_q_conf,
;*              idc_read_en,            idc_read_dis,   idc_enable_dev,
;*              idc_disable_dev,        disable_aux,    get_dis_resp,
;*              req_deins,              send_cmd,       send_data,
;*              send_aux_data,          get_aux_data,   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
;*   03/25/94  @V2.1llm01  76604  7554 TouchSelect not installed properly.
;*****************************************************************************/

.286p

.seq
DSEG    segment page public 'DATA'
DSEG    ends
CSEG    segment word public 'CODE'
CSEG    ends


.xlist
.xcref

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

.cref
.list


        extrn   DOSWRITE:far
        extrn   DOSREAD:far

        extrn   toudd_fail:byte
        extrn   conf_data:byte
        extrn   getputmsg:near


public  mou_header, mou_int_pkt_off, mou_dddd_idc, mou_dev_status
public  mconf_irqnum



KBAUX_DATA      equ     60h
KBAUX_STAT      equ     64h
KBAUX_CMD       equ     64h
KBAUX_STAT_TO   equ     02deh
KBAUX_OBF       equ     01h
KBAUX_IBF       equ     02h
KBAUX_AOBF      equ     20h

AUX_INT_CONT    equ     0a1h

MOU_INT_NUM     equ     12
MOU_AUX_MASK    equ     1 shl (MOU_INT_NUM-8)

DEVS_READ_EN    equ     1
DEVS_ATTACHED   equ     2
DEVS_1          equ     4
DEVS_DEINS      equ     8
DEVS_EN_DEV     equ     10h


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
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

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


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     $


mess            db      CR, LF, 'TOUMOU$'
mcrlf           db      CR, LF
mess_len        equ     $-mess
mcrlf_len       equ     $-mcrlf

fail            db      CR, LF, 'Load Failed', CR, LF
fail_len        equ     $-fail

print_err       db      CR, LF
                db      '(string too big)'
                db      CR, LF
print_err_len   equ     $-print_err

hex             db      '0123456789ABCDEF'
hex_buff        db      4 dup (?)
char_buff       db      ?
xfer_len        dw      ?

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
;*
;**************************************************************************/

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

                        ;*
                        ;* flag 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      mou_dev_status, DEVS_EN_DEV

        pushf
        cli

        in      al, AUX_INT_CONT
        and     al, not MOU_AUX_MASK
        out     AUX_INT_CONT, al

        MyIODelay

        popf
        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     mou_dev_status, not DEVS_EN_DEV

        pushf
        cli

        in      al, AUX_INT_CONT
        or      al, MOU_AUX_MASK
        out     AUX_INT_CONT, al

        MyIODelay

        popf
        clc
        ret

idc_disable_dev endp


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

disable_aux     proc    near

        cli

        mov     al, 60h
        call    send_cmd
        mov     al, 65h                 ; disable AUX & AUX ints
        call    send_data
        call    get_dis_resp

        sti

        ret

disable_aux     endp


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

get_dis_resp    proc    near

@@:     in      al, KBAUX_STAT
        and     al, KBAUX_OBF+KBAUX_AOBF
        cmp     al, KBAUX_OBF+KBAUX_AOBF
        jnz     idc_enable_dev

        in      al, KBAUX_DATA

        jmp     short @B

get_dis_resp    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

        call    disable_aux

        DH_UNSETIRQ     MOU_INT_NUM

        ret

req_deins       endp


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

send_cmd        proc    near

        push    cx
        push    ax
        mov     cx, KBAUX_STAT_TO

@@:     in      al, KBAUX_STAT
        test    al, KBAUX_IBF
        jz      @F
        loop    @B

@@:     pop     ax
        out     KBAUX_CMD, al
        pop     cx

        ret

send_cmd        endp


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

send_data       proc    near

        push    cx
        push    ax
        mov     cx, KBAUX_STAT_TO

@@:     in      al, KBAUX_STAT
        test    al, KBAUX_IBF
        jz      @F
        loop    @B

@@:     pop     ax
        cli
        out     KBAUX_DATA, al
        pop     cx

        ret

send_data       endp


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

send_aux_data   proc    near

        mov     al, 0d4h
        call    send_cmd
        .if     <z>

                mov     al, bl
@@:             call    send_data
                jz      @F
                loop    @B

        .endif

        stc
        ret

@@:     clc
        ret

send_aux_data   endp


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

get_aux_data    proc    near

        mov     dx, 01f4h

get_aux_again:

        mov     cx, 0ffffh

@@:     in      al, KBAUX_STAT
        and     al, KBAUX_OBF+KBAUX_AOBF
        cmp     al, KBAUX_OBF+KBAUX_AOBF
        jnz     get_aux_retry

        in      al, KBAUX_DATA
        cmp     ah, 0
        jz      get_aux_ok
        cmp     ah, al
        jnz     get_aux_nok

get_aux_ok:

        clc
        ret

get_aux_retry:

        loop    @B
        dec     dx
        jnz     get_aux_again

get_aux_nok:

        stc
        ret

get_aux_data    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:
                ;*
                ;* fail  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_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

        ;*
        ;* disable KB
        ;*

        mov     dx, 0bh

hw_init_again:

        cli

        mov     al, 0adh                ; disable KB
        call    send_cmd
        jnz     hw_init_retry

        mov     cx, KBAUX_STAT_TO

@@:     in      al, KBAUX_STAT
        test    al, KBAUX_IBF+KBAUX_OBF
        jz      @F

        test    al, KBAUX_OBF
        jnz     hw_init_retry

        loop    @B

hw_init_retry:

        dec     dx
        .if     <z>
                jmp     hw_init_fail1
        .endif
;*      jz      hw_init_fail1

        sti
        jmp     hw_init_again


@@:
        ;*
        ;* enable aux device
        ;*

        cli
        mov     al, 60h
        call    send_cmd
        mov     al, 54h
        call    send_data
        sti

        ;*
        ;* 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
        ;*

        ;*
        ;* reset mouse
        ;*
;* nop                                  ; XXX
        mov     bl, 0ffh                ; reset cmd
        call    send_aux_data
        jc      hw_init_fail1

        mov     ah, 0fah                ; ACK
        call    get_aux_data            ; get response
        jc      hw_init_fail

        mov     ah, 0                   ; no compare
        call    get_aux_data            ; get completion code
        jc      hw_init_fail1
        cmp     al, 0fch                ; 2 invalid commands
        jz      hw_init_fail1

        mov     ah, 0                   ; no compare
        call    get_aux_data            ; get id
        jc      hw_init_fail1

        ;*
        ;* set sample rate
        ;*

        mov     bl, 0f3h                ; set sample rate cmd
        cli
        call    send_aux_data
        sti
        jc      hw_init_fail1

        mov     ah, 0fah                ; ACK
        call    get_aux_data            ; get response
        jc      hw_init_fail1

        mov     bl, 28h                 ; 40 samples/sec
        cli
        call    send_aux_data
        sti
        jc      hw_init_fail1

        mov     ah, 0fah                ; ACK
        call    get_aux_data            ; get response
        jc      hw_init_fail1

        ;*
        ;* enable
        ;*

        mov     bl, 0f4h                ; enable cmd
        cli
        call    send_aux_data
        sti
        jc      hw_init_fail2

        mov     ah, 0fah                ; ACK
        call    get_aux_data            ; get response
        jc      hw_init_fail2

        ;*
        ;* enable KB & AUX ints
        ;*

hw_init_enable:

        cli
        mov     al, 60h
        call    send_cmd
        mov     al, 47h                 ; enable KB & KB int & AUX int
        call    send_data
        sti

hw_init_ok:

        clc                             ; set successful
        ret

hw_init_fail:
        ;*
        ;* mouse failed to reset
        ;*
        .if     <bit conf_data.conf_mou_stat and <MS_REAL_EMUL or MS_PROT_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 fialed 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_enable                  ; llm - 76604
;*                      jmp     hw_init_ok                        llm - 76604
                    .endif
                .endif
        .endif

hw_init_fail1:
hw_init_fail2:

        call    disable_aux

        stc                             ; set fail
        ret

hw_init         endp


END_CODE        equ     $


cseg    ends

        end

;*
;* end
;*
