;/*****************************************************************************
;*
;* SOURCE FILE NAME = TOUFAM1.ASM
;*
;* DESCRIPTIVE NAME =
;*
;* 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         02/18/92
;*
;* DESCRIPTION
;*
;* FUNCTIONS    prescott_io,    xabios_tsbs,    enable_all,
;*              disable_all,    disen_aux,      prescott_hw_init,
;*              prescott_hw_deinit,             mou_stream_dis,
;*              mou_stream_en,  int_service,    disable_aux1,
;*              disable_aux,    get_dis_resp,   send_cmd,
;*              send_data,      send_data1,     send_aux_data,
;*              get_aux_data,   get_data,       send_aux_str,
;*              disable_kb,     enable_kb,      disable_mou,
;*              enable_mou,     xwait_cmd,      clr_8042.
;*
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   xx/xx/xx  @V2.0xxx01  DCR1555  Micronyx Security Hook
;*
;*****************************************************************************/

;*
;* DEBUG          equ     0             ; debug is on if flag is defined
;*

.286p

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

include struc.inc
include proc.inc
include iodelay.inc
include toudderr.inc
include touequ.inc
include toustruc.inc
include toumacro.inc
include devhlpP.inc            ; 76711

;*
;* Controller Port Defn.
;*

KBAUX_DATA      equ     60h
KBAUX_STAT      equ     64h
KBAUX_CMD       equ     64h

;*
;* Controller Status Timeout
;*

KBAUX_STAT_TO   equ     02deh

;*
;* Controller Status Register Format
;*

KBAUX_OBF       equ     01h
KBAUX_IBF       equ     02h
KBAUX_AOBF      equ     20h

;*
;* Controller Command Byte Format
;*

KBAUX_CC_EKI    equ     01h             ; enable KB interrupt
KBAUX_CC_EAI    equ     02h             ; enable AUX interrupt
KBAUX_CC_SF     equ     04h             ; system flag
;* RESERVED     equ     08h             ; reserved
KBAUX_CC_DKB    equ     10h             ; disable KB
KBAUX_CC_DAD    equ     20h             ; disable AUX device
KBAUX_CC_KTM    equ     40h             ; KB xlate mode
;* RESERVED     equ     80h             ; reserved

KBAUX_CMD_RCCB  equ     020h            ; read the controller command byte
KBAUX_CMD_WCCB  equ     060h            ; write to controller command byte
KBAUX_CMD_DISAD equ     0a7h            ; disable auxiliary interface
KBAUX_CMD_ENAD  equ     0a8h            ; enable auxiliary interface
KBAUX_CMD_DISKB equ     0adh            ; disable keyboard interface
KBAUX_CMD_ENKB  equ     0aeh            ; enable keyboard interface
KBAUX_CMD_WAUX  equ     0d4h            ; write to auxiliary device


RESEND  equ     0 ;TEMP

;*
;* ??? \/ should go
;* ABIOS equates
;*

;*
;* ABIOS_RETRY_CNT        equ     0fffh ; abios cmd DIU retry count
;* ABIOS_RESEND_RESP      equ     0feh  ; abios resend response
;* ABIOS_RESEND_RETRY     equ     500   ; abios tsbs resend count
;*

;*
;* retry counter for mouse commands
;* used in stream_en & stream_dis
;*

MOUSE_CMD_RETRY         equ     200

MOU_ACK                 equ     0fah
MOU_CMD_STREAM_DIS      equ     0f5h
MOU_CMD_STREAM_EN       equ     0f4h


        public  int_pkt

;*      public  xwait_cmd

        public  prescott_io
        public  prescott_hw_init
        public  prescott_hw_deinit

        public  prescott_failed

        public  int_pkt

;*      public  read_rqb, cmd_rqb

;*      public  prescott_io_resp

        public  mou_stream_en, mou_stream_dis

        public  disable_kb, disable_mou, enable_kb, enable_mou


        extrn   devhlp:dword
        extrn   essi2dsdi:near
        extrn   dev_status:word
        extrn   idc_disable_dev:near
        extrn   idc_enable_dev:near
        extrn   dddd_idc:byte
        extrn   bmove:near
;*      extrn   emul_current:byte
        extrn   int_pkt_off:word

        extrn   process_data:near

;*      extrn   mou_int_pkt_off:word
;*      extrn   mou_dddd_idc:byte
;*      extrn   mou_dev_status:word

;*      extrn   current_row_siz:word
;*      extrn   current_col_siz:word
;*      extrn   current_col_min:word
;*      extrn   current_col_max:word
;*      extrn   current_row_min:word
;*      extrn   current_row_max:word
;*      extrn   y_offset:word
;*      extrn   x_offset:word

        extrn   prescott_io_resp:byte
        extrn   prescott_io_dat:byte
        extrn   pio_cmd_lens:byte
        extrn   pio_add_lens:byte

        extrn   conf_data:byte
        extrn   raw_mode:byte
        extrn   mconf_irqnum:byte


DSEG    segment

prescott_failed dw      0               ; permanent failure flag

prescott_lid    dw      ?               ; logical ID of prescott

public temp_cmd
temp_cmd        dw      0               ; debug current cmd

                                        ; DCR 1555                    @V2.0xxx01
DD 09CBE9F9Eh                           ; 1st half of DD  start signature
DD 0AFAB8BABh                           ; 2nd half of DD start signature
DD Security_Hook1               ; Label name/offset to security hook area start
DD Security_End1                ; Label name/offset to security hook area end
DD 0A19CBEAEh                           ; 1st half of end signature
DD 09E9FAB8Bh                           ; 2nd half of end signature


int_pkt         db      3 dup (0)       ; holding buffer for int packet
public  int_count                       ; temp
int_count       dw      0               ; counter for int packet, in ISR

;* read_rqb     ABRQB   <>      ; read request block (continuous read only)
;* cmd_rqb      ABRQB   <>      ; command request block (all other cmds)

disable_flag    db      0


DSEG    ends


CSEG    segment
        assume  cs:CSEG, ds:DSEG


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

public  prescott_io
PROCEDURE       prescott_io     near

PARAMETER       data_ptr        dword   ; far ptr to data if total length > 1
PARAMETER       cmd             word    ; prescott command

VARIABLE        ax_ret_val      word    ; ax return value

        BEGINPROC

        push    es
        pusha

        ;*
        ;* get cmd length
        ;*

        mov     bx, cmd
        mov     temp_cmd, bx
        .if     <bx b PIO_FIRST_CMD> or
        .if     <bx a PIO_LAST_CMD>
                ;*
                ;* unsupported cmd
                ;*
;*      DH_INTERR       f3, f3l
int 3
        .endif

        sub     bx, PIO_FIRST_CMD
        mov     cl, pio_cmd_lens[bx]
        xor     ch, ch                  ; ucbw

        .if     <zero cx>
                ;*
                ;* unsupported cmd
                ;*
;*      DH_INTERR       f4, f4l
int 3
        .endif

        ;*
        ;* get data for cmd (if any)
        ;*

        .if     <cx a 1>
                ;*
                ;* some data to xfer (ie. not just a single byte cmd)
                ;*

                les     si, data_ptr                    ; source
                mov     di, offset prescott_io_dat+1    ; destination

                .if     <cx eq 255>
                        ;*
                        ;* special case for dmc (variable data count = 6+n)
                        ;*
                        mov     cl, es:[si]     ; get data count from header
                        xor     ch, ch          ; ucbw
                        add     cx, 6           ; + cmd + header + crc
                .endif

                dec     cx              ; not xfering cmd
                call    essi2dsdi
                inc     cx              ; restore true size
                dec     di              ; move to begining of data

        .endif                          ; data xfer size test

        mov     ax, cmd                 ; get command parameter
        ;*
        ;* cl = count
        ;* ds:di = data ptr if cl != 1
        ;*
        call    xabios_tsbs             ; do cmd (CY if error)
        mov     ax_ret_val, ax          ; save return value

        popa
        pop     es

        .if     <c>
                ;*
                ;* an error occurred
                ;* force ax value to be returned, not preserved
                ;*
                mov     ax, ax_ret_val
mov ax, ABIOS_NAK ;TEMP
        .endif


FREEVAR         ax_ret_val

ENDPROC         prescott_io


if 1

;/***************************************************************************
;*
;* FUNCTION NAME = xabios_tsbs
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = cl - DAT count (including cmd)
;*                 al - prescott cmd
;*                 ds:di - DAT off (cl != 1)
;*
;* OUTPUT        = ch - additional respose count
;*                 dseg:di - if(ch != 0) di -> additional resp buffer
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

public          xabios_tsbs
pubdeb          xabios_tsbs
PROCEDURE       xabios_tsbs     near

VARIABLE        cmd             word
VARIABLE        ack_cnt         word
VARIABLE        add_cnt         word

        BEGINPROC

        push    dx

        ;*
        ;* set up buffer for single byte cmds
        ;*
        .if     <cl eq 1>
                mov     di, offset prescott_io_dat
        .endif

        xor     ah, ah
        mov     [di], al                ; save cmd
        mov     cmd, ax
        call    disable_all
        mov     ack_cnt, 0              ; init ACK counter
        xor     ch, ch

xabios_send:

        mov     dx, 100                 ; !!!

xabios_send_again:

        ;*
        ;* get byte & send it
        ;*

        mov     bl, [di]
        push    cx
        cli
        call    send_aux_data
        sti
        pop     cx
        jc      abios_tsbs_error

        ;*
        ;* get response
        ;*

        mov     ah, 0
        push    dx
        push    cx
        call    get_aux_data
        pop     cx
        pop     dx
        jc      abios_tsbs_error

        .if     <al ne 0CAh>
                dec     dx
                jnz     xabios_send_again
                jmp     short abios_tsbs_error
        .endif

        inc     ack_cnt
        inc     di
        loop    xabios_send
        mov     add_cnt, 0

        ;*
        ;* get additional byte count
        ;*
        mov     bx, cmd
        sub     bx, pio_first_cmd
        mov     cl, pio_add_lens[bx]
        xor     ch, ch
        .if     <nonzero cx>
                ;*
                ;* some to add resp get
                ;*

                ;*
                ;* set up buffer for additional responses
                ;*
                mov     si, offset prescott_io_resp
xabios_get:
                ;*
                ;* get response
                ;*

                mov     ah, 0
                push    cx
                call    get_aux_data
                pop     cx
                jc      abios_tsbs_error

                mov     [si], al        ; save got response
                inc     add_cnt
                inc     si

                loop    xabios_get

        .endif

        ;*
        ;* get num additional resposes rxed
        ;*
;*      mov     ch, byte ptr add_cnt
        mov     cx, add_cnt

        ;*
        ;* setup additional data ptr if any addit. resposes
        ;*
        .if     <nonzero ch>
                mov     di, offset prescott_io_resp
        .endif

        clc                             ; no erorrs

        jmp     short abios_tsbs_exit

abios_tsbs_error:
        stc

public abios_tsbs_exit
abios_tsbs_exit:

        call    enable_all

        pop     dx


FREEVAR cmd
FREEVAR ack_cnt
FREEVAR add_cnt

ENDPROC         xabios_tsbs

endif


;/***************************************************************************
;*
;* FUNCTION NAME = enable_all
;*
;* DESCRIPTION   =
;*    Enable kb & aux after a disable all. As many enables as disables
;*    must be done before the device is actually enabled when the disable
;*    count has been reduced to 1. Any further enables do nothing & do not
;*    affect the disable count.
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

public  enable_all
enable_all      proc    near

        pushf

        .if     <disable_flag eq 1>
                ;*
                ;* last disable, so enable
                ;*

                pusha
                mov     al, 02h         ; enable cmd
                call    disen_aux       ; dis/enable aux dev
                popa

;*              mov     disable_flag, 0 ; not disabled
        .endif

.if <disable_flag ne 0>
        ;*
        ;* still disabled
        ;*
        dec     disable_flag            ; reduce disable count
.endif

        popf

        ret

enable_all      endp


;/***************************************************************************
;*
;* FUNCTION NAME = disable_all
;*
;* DESCRIPTION   =
;*    Disable kb & aux so that data can be polled in/out of prescott
;*    Many disables can be done only the first actually disables the
;*    rest increase the disable count. The device is re-enabled only
;*    after the disable count has been reduced to 1, by enabling as
;*    many times as it was disabled.
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

public  disable_all
disable_all     proc    near

        .if     <disable_flag eq 0>
                ;*
                ;* not disabled, so disable
                ;*

                pusha
                mov     al, 20h         ; disable cmd
                call    disen_aux       ; dis/enable aux dev
                popa

;*              mov     disable_flag, 1 ; now disabled
        .endif
inc     disable_flag                    ; increase disable count

        ret

disable_all     endp


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

public  disen_aux
disen_aux       proc    near

        push    ax                      ; save cmd
        mov     cx, 5

disen_aux_again:

        push    cx
        call disable_kb
        pop     cx
        .if     <c>
                loop    disen_aux_again
                mov     al, 1
                stc
                jmp     short disen_aux_exit
                int     3
        .endif

        mov     al, KBAUX_CMD_DISAD     ; disable aux dev
        call    send_cmd
        .if     <nz>
                mov     al, 2
                stc
                jmp     short disen_aux_exit
                int     3
        .endif

        mov     al, KBAUX_CMD_RCCB      ; read cont-cmd-byte
        call    send_cmd
        .if     <nz>
                mov     al, 3
                stc
                jmp     short disen_aux_exit
                int     3
        .endif

        push    cx                      ; save loop counter

        ;*
        ;* wait for data to be available
        ;*
        mov     ah, 100                 ; outer loop count
        xor     cx, cx                  ; inner loop count

@@:     in      al, KBAUX_STAT
        .if     <bit al nand KBAUX_OBF>
                loop    @B              ; try again
                dec     ah              ; cx zero again
                jnz     @B              ; try again
                pop     cx
                mov     al, 4
                stc
                jmp     short disen_aux_exit
                int     3
        .endif

        mov     cx, 10
        loop    $                       ; wait around a bit

        pop     cx                      ; restore loop counter

        in      al, KBAUX_DATA          ; get cont-cmd-byte
        mov     ch, al                  ; save for later

        mov     al, KBAUX_CMD_WCCB      ; write cont-cmd-byte
        call    send_cmd
        .if     <nz>
                pop     cx
                mov     al, 5
                stc
                jmp     short disen_aux_exit
                int     3
        .endif

        pop     ax                      ; restore cmd
        and     ch, not 32h
        or      al, ch

        call    send_data1
        .if     <nz>
                xor     ch, ch          ; reset hi retry count
                loop    disen_aux_again
                mov     al, 6
                stc
                jmp     short disen_aux_exit
                int     3
        .endif

        clc                             ; no errors

disen_aux_exit:

        sti

        ret

disen_aux       endp


mou_cmd         proc    near
mou_cmd         endp


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

PROCEDURE       prescott_hw_init        near

VARIABLE        returncode      word

        BEGINPROC

;*
;* ??? build int mask ??
;*

        call    disable_kb
        .if     <c>
                mov     returncode, ERR_DD_KBDIS
                jmp     short hw_init_fail1
        .endif

        ;*
        ;* enable aux device
        ;*

;*      mov     al, 60h
        mov     al, KBAUX_CMD_WCCB      ; write controller command byte
        call    send_cmd
        sti
;* ??? errors
        mov     al, KBAUX_CC_KTM + KBAUX_CC_DKB + KBAUX_CC_SF
        call    send_data
        sti


        call    enable_kb
        .if     <c>
                mov     returncode, ERR_DD_KBEN
                jmp     short hw_init_fail1
        .endif

        ;*
        ;* hook AUX int; shared between mouse & touch display
        ;*
        DH_SETIRQ       int_service, MOU_INT_NUM, 0
        .if     <c>
                mov     returncode, ERR_DD_SIRQ
                jmp     short hw_init_fail1
        .endif

        mov     mconf_irqnum, MOU_INT_NUM
        mov     conf_data.conf_irq_num, MOU_INT_NUM

        ;*
        ;* enable interrupts
        ;*
        call    idc_enable_dev

;* ???  ; set continuous read (enables 8042 ints)

        clc
        jmp     short hw_init_exit

hw_init_fail2:
        DH_UNSETIRQ     MOU_INT_NUM

hw_init_fail1:
        call    disable_aux
        stc

hw_init_exit:
;*      mov     data_count, 0
        mov     int_count, 0

call clr_8042

FREEVAR         returncode

ENDPROC         prescott_hw_init


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

prescott_hw_deinit      proc near

        ret
        clc

prescott_hw_deinit      endp


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

mou_stream_dis  proc    near

                mov     cx, MOUSE_CMD_RETRY

stream_dis_mou_retry:

;* 1            call    disable_all
;* call disable_mou
clc                                     ; TEMP
                .if     <c>
                        .if     <ax eq RESEND>
                                loop    stream_dis_mou_retry
fatal1:

;* DH_INTERR    fm1, fm1l
int 3                                   ; TEMP for testing retry
                                stc
                        .endif
                .endif

        ret

mou_stream_dis  endp


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

mou_stream_en   proc    near

                mov     cx, MOUSE_CMD_RETRY

stream_en_mou_retry:

;* 1            call    enable_all
;* call   enable_mou

clc ;TEMP
                .if     <c>
                        .if     <ax eq RESEND>
                                loop    stream_en_mou_retry
;* jmp    fatal1
int 3
                                stc
                        .endif
                .endif

        ret

mou_stream_en   endp


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

pubdeb          int_service
PROCEDURE       int_service     far

        BEGINPROC

        cli

        call    idc_disable_dev

        ;* DH_EOI  MOU_INT_NUM             See Toumacro.inc Removed 76711
        DevEOI  <MOU_INT_NUM>,DevHlp    ;                   Add     76711

        sti
                                        ; DCR 1555 for Micronyx       @V2.0xxx01
        Security_Hook1 LABEL near       ; Do not remove this          @V2.0xxx01
                                        ;   Security Hook             @V2.0xxx01
        in      al, KBAUX_STAT          ; get status                  @V2.0xxx01
        mov     ah, al                  ;                             @V2.0xxx01
        in      al, KBAUX_DATA          ; get data                    @V2.0xxx01

        ;*
        ;* remove spurious data
        ;*
        and     ah, KBAUX_OBF or KBAUX_AOBF     ;                     @V2.0xxx01
        Security_End1 LABEL near        ; End of DCR 1555 for         @V2.0xxx01
                                        ;   Micronyx Security Hooks   @V2.0xxx01
        .if     <ah eq <KBAUX_OBF or KBAUX_AOBF>>
                ;*
                ;* if valid aux data
                ;* data is for us: stat & (obf | aobf) == (obf | aobf)
                ;*

                mov     di, int_count   ; get data count

;* ??? could remove jmp
if 0
        .if     <di ne 0> or
        .if     <bit al nand 08h> or
        .if     <bit al nand 04h>
                ....
        .endif
endif
                ;*
                ;* re-synchronise bytes
                ;*
                .if     <di eq 0> and
                .if     <bit al and 08h> and
                .if     <bit al and 04h>
                        jmp     short INT_SERV_IGNORE   ; jif out of sync data
                .endif

                mov     byte ptr int_pkt[di], al        ; save data
                inc     int_count                       ; bump byte counter

                .if     <di eq 2>
                        ;*
                        ;* packet now completly assembled (bytes 0,1 & 2 rxed)
                        ;*

                        mov     int_count, 0
                        call    process_data

                .endif                  ; packet complete test

        .endif                          ; valid data test

INT_SERV_IGNORE:

        call    idc_enable_dev

        clc                             ; indicate interrupt handler owned
                                        ;   interrupt

ENDPROC         int_service


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

disable_aux1    proc    near

        mov     al, KBAUX_CMD_DISAD     ; disable AUX
        call    send_cmd
        jnz     @F                      ; jif failed
        sti
        clc
        ret

@@:
        stc
        ret

disable_aux1    endp


;/***************************************************************************
;*
;* FUNCTION NAME = disable_aux
;*
;* DESCRIPTION   =
;*    Disable auxiliary device interface in the 8042
;*    The clock line to is driven low. Data is not sent or received.
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

disable_aux     proc    near

;*      mov     al, 60h                 ; write controller command byte
        mov     al, KBAUX_CMD_WCCB      ; write controller command byte
        call    send_cmd
;*      mov     al, 65h                 ; disable AUX & AUX ints
        mov     al, KBAUX_CC_KTM + KBAUX_CC_DAD + KBAUX_CC_SF + KBAUX_CC_EKI
        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
        jz      @F

        jmp     idc_enable_dev

@@:     in      al, KBAUX_DATA

;* ???  jmp     short @B
        jmp     short get_dis_resp

get_dis_resp    endp


;/***************************************************************************
;*
;* FUNCTION NAME = send_cmd
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = al - cmd
;*
;* OUTPUT        = zr - ok, interrupts disabled
;*                 nz - timed out, interrupts enabled
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

send_cmd        proc    near

        push    cx
        push    ax

        mov     cx, KBAUX_STAT_TO

@@:     cli
        in      al, KBAUX_STAT
        test    al, KBAUX_IBF           ; sets exit flags: zr - ok, nz - t/o
        jz      @F                      ; jif previous data now gone
        sti

        loop    @B                      ; (does not affect flags)

@@:     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
        mov     ah, al

@@:     in      al, KBAUX_STAT
        test    al, KBAUX_IBF

        loopnz  @B
        jnz     sd_exit

        mov     al, ah
        cli
        out     KBAUX_DATA, al

        mov     cx, 0
@@:     in      al, KBAUX_STAT
        and     al, KBAUX_IBF
        loopz   @B
        xor     al, KBAUX_IBF

sd_exit:
        pop     ax
        pop     cx

        ret

send_data       endp


;/***************************************************************************
;*
;* FUNCTION NAME = send_data1
;*
;* DESCRIPTION   =
;*    All regs preserved
;*    Interrupts enabled on exit
;*
;*
;* INPUT         = al - cmd
;*
;* OUTPUT        = zr - ok
;*                 nz - timed out
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

send_data1      proc    near

        push    cx
        push    ax

        mov     cx, KBAUX_STAT_TO
        mov     ah, al

@@:     in      al, KBAUX_STAT
        test    al, KBAUX_IBF

        loopnz  @B
        jnz     sd1_exit                ; jif timeout

        mov     al, ah                  ; get data
        out     KBAUX_DATA, al

        mov     cx, 0
@@:     in      al, KBAUX_STAT
        and     al, KBAUX_IBF
        loopz   @B
        xor     al, KBAUX_IBF           ; set zr flag

sd1_exit:
        sti
        pop     ax
        pop     cx

        ret

send_data1      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
        mov     al, KBAUX_CMD_WAUX      ; write to aux device
        call    send_cmd
        sti
        .if     <z>

                mov     cx, 0bh
                mov     al, bl
@@:             call    send_data

                loopnz  @B
                jz      @F              ; jif send_data OK

        .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 or KBAUX_AOBF
        cmp     al, KBAUX_OBF or 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 = get_data
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

get_data        proc    near

        mov     dx, 01f4h

get_again:

        mov     cx, 0ffffh

@@:     in      al, KBAUX_STAT
        and     al, KBAUX_OBF or KBAUX_AOBF
        cmp     al, KBAUX_OBF
        jnz     get_retry

        in      al, KBAUX_DATA
get_ok:

        clc
        ret

get_retry:

        loop    @B
        dec     dx
        jnz     get_again

        stc
        ret

get_data        endp


;/***************************************************************************
;*
;* FUNCTION NAME = send_aux_str
;*
;* DESCRIPTION   =
;*    bl - cmd
;*    es:di - data ptr or bh if cx == 1
;*    cx - data len
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

send_aux_str    proc    near

        push    cx
        cli
        call    send_aux_data           ; send cmd
        sti
        pop     cx

        .if     <cx eq 1>
                mov     bl, bh
        .else
@@:             mov     bl, es:[di]
        .endif

        push    cx
        cli
        call    send_aux_data
        sti
        pop     cx
        jc      @F                      ; abort if error

        inc     di

        loop    @B

        clc                             ; no errors

@@:     ret


send_aux_str    endp


;/***************************************************************************
;*
;* FUNCTION NAME = disable_kb
;*
;* DESCRIPTION   =
;*    Disable keyboard interface in the 8042
;*    Sets bit 4 of the controller command byte to 1
;*    The clock line kis driven low. Data is not sent or received.
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

disable_kb      proc    near

        mov     dx, 0bh

dis_kb_again:

        mov     al, KBAUX_CMD_DISKB     ; disable KB
        call    send_cmd
mov     al, 1
        jnz     dis_kb_retry

        mov     cx, KBAUX_STAT_TO

@@:     in      al, KBAUX_STAT
        test    al, KBAUX_IBF+KBAUX_OBF
        jz      dis_kb_ok               ; jif kb disabled ok

        test    al, KBAUX_OBF
mov     al, 2
        jnz     dis_kb_retry            ; jif some data rxed

        loop    @B                      ; wait for cmd go away
mov     al, 3

dis_kb_retry:
        sti
        dec     dx
        jz      dis_kb_fail             ; jif retry exhausted

        jmp     dis_kb_again            ; try it all again

dis_kb_ok:
        sti
        clc
        ret

dis_kb_fail:
        stc
        ret

disable_kb      endp


;/***************************************************************************
;*
;* FUNCTION NAME = enable_kb
;*
;* DESCRIPTION   =
;*    Enable keyboard interface in the 8042 by writing to controller
;*    command byte
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

enable_kb       proc    near

        mov     al, KBAUX_CMD_RCCB      ; read controller command byte
        call    send_cmd
        call    get_data
        and     al, not 30h             ; reset KB & AD disable bits
        or      al, 3                   ; set KB & AD enable int bits
        push    ax

        mov     al, KBAUX_CMD_WCCB      ; write controller command byte
        call    send_cmd
;*      mov     al, 47h                 ; enable KB & KB int & AUX int
        pop     ax
        call    send_data
        sti

        clc
        ret

enable_kb       endp


;/***************************************************************************
;*
;* FUNCTION NAME = disable_mou
;*
;* DESCRIPTION   =
;*    Disable mouse from streaming data, it still responds to all
;*    other commands
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

public          disable_mou
disable_mou     proc    near

        ;*
        ;* disable data
        ;*
        mov     bl, 0f5h                ; disable stream mode
        cli
        call    send_aux_data
        sti
        jc      dis_mou_fail

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

        clc

dis_mou_fail:

        ret

disable_mou     endp


;/***************************************************************************
;*
;* FUNCTION NAME = enable_mou
;*
;* DESCRIPTION   =
;*    Enable stream data in mouse
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

enable_mou      proc    near

        ;*
        ;* enable data
        ;*
        mov     bl, 0f4h                ; enable cmd
        cli
        call    send_aux_data
        sti
        jc      en_mou_fail

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

        clc

en_mou_fail:

        ret

enable_mou      endp


;/***************************************************************************
;*
;* FUNCTION NAME = xwait_cmd
;*
;* DESCRIPTION   =
;*    Wait for prescott to be ready
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

xwait_cmd       proc    near

;* ???  pushf
        pusha

@@:     mov     bl, 0b4h                ; read code level byte cmd
        cli
        call    send_aux_data
        sti
        jc      @B

        mov     ah, 0cah                ; AUX ACK
        call    get_aux_data            ; get response
        jc      @B

        mov     ah, 0
        call    get_aux_data            ; get response

        popa
;* ???  popf

        ret

xwait_cmd       endp


;/***************************************************************************
;*
;* FUNCTION NAME = clr_8042
;*
;* DESCRIPTION   =
;*    Try & clear 8042 of any outstanding data
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

clr_8042        proc    near

in al,KBAUX_DATA
MyIODelay
in al,KBAUX_DATA
MyIODelay
in al,KBAUX_DATA
MyIODelay
in al,KBAUX_DATA
MyIODelay

        mov     cx, 0

@@:     in      al, KBAUX_STAT
        and     al, KBAUX_OBF
        jnz     clr_retry

        in      al, KBAUX_DATA


clr_retry:

        loop    @B

        ret

clr_8042        endp


CSEG    ends

        end

;*
;* end
;*
