;; ------------------------------------------------------------------------ ;;
;;  @@ SOURCE DOCUMENTATION                 *** MASM 6.0 Version ***        ;;
;;                                                                          ;;
;;  TITLE : CALLBACK.ASM                                                    ;;
;;                                                                          ;;
;;  DESCRIPTION :                                                           ;;
;;      This file contains assembly language coded functions used by        ;;
;;      program MIDIIN.BAS. The three and only three functions are          ;;
;;          sbkMidiCallBack                                                 ;;
;;          lpMidiCallBack                                                  ;;
;;          DisplayHexByte.                                                 ;;
;;                                                                          ;;
;;      Function lpMidiCallBack is declared in the program MIDIIN.BAS.      ;;
;;      Compile this file to object file and link with MIDIIN.OBJ.          ;;
;;                                                                          ;;
;;      ML /c CALLBACK.ASM                                                  ;;
;;                                                                          ;;
;;  Copyright (c) Creative Technology Ltd, 1993. All rights reserved.       ;;
;;                                                                          ;;
;; ------------------------------------------------------------------------ ;;

        .DOSSEG

        .MODEL large, BASIC

        .CODE   CT_TEXT

;; ------------------------------------------------------------------------ ;;
;;  @@ Usage                                                                ;;
;;                                                                          ;;
;;  sbkMidiCallBack% (lpMidiCode AS LONG, dwToken AS LONG)                  ;;
;;                                                                          ;;
;;  Description :                                                           ;;
;;      Call back function by CTMIDI.DRV driver which displays the MIDI     ;;
;;      codes to the screen. The method of displaying is as below:-         ;;
;;                                                                          ;;
;;          Code-Time_stamp                                                 ;;
;;      where                                                               ;;
;;          Code       :- Status, data, control number or control value     ;;
;;          Time_stamp :- Signifies the time (in milisecond) the Code is    ;;
;;                        received. Either in DIFFERENTIATE_MODE or         ;;
;;                        ELAPSED_MODE.                                     ;;
;;                                                                          ;;
;;  Entry :                                                                 ;;
;;      lpMidiCode :- far pointer to the MIDI code.                         ;;
;;                    lower one byte is the Code and upper three bytes      ;;
;;                    are Time_stamp.                                       ;;
;;      dwToken    :- contains the value which passed to the function       ;;
;;                    ctmdSetMidiCallBackFunct through the second           ;;
;;                    parameter. For example If default data segment        ;;
;;                    need to be accessed, an address of the default        ;;
;;                    data segment can be passed as second parameter        ;;
;;                    during call to ctmdSetMidiCallBackFunct function.     ;;
;;                                                                          ;;
;;  Exit :                                                                  ;;
;;      none.                                                               ;;
;;                                                                          ;;
;;  NOTE !!!!                                                               ;;
;;      1. Call back function must be in Pascal calling convention.         ;;
;;      2. Turn check_stack off.                                            ;;
;;      3. Data segment is belong to CTMIDI.DRV driver. You need to swap    ;;
;;         to application data segment if you want to access global         ;;
;;         variables.                                                       ;;
;;      4. Stack segment is belong to CTMIDI.DRV driver.                    ;;
;;      5. Cannot call DOS INT 21 functions since it is not re-entrance.    ;;
;;                                                                          ;;
;; ------------------------------------------------------------------------ ;;

sbkMidiCallBack PROC    FAR     Uses es di, lpMidiCode : far ptr byte,
                                               dwToken : dword

    les     di, lpMidiCode

    mov     al, byte ptr es:[di]    ; MIDI event or data
    push    ax
    Call    DisplayHexByte          ; display code in hexa

    MOV     AH,0EH
    MOV     BL,7
    MOV     AL,'-'
    INT     10H

    mov     al, byte ptr es:[di+3]  ; the following three bytes
    push    ax                      ; are time-stamp
    Call    DisplayHexByte
    mov     al, byte ptr es:[di+2]
    push    ax
    Call    DisplayHexByte
    mov     al, byte ptr es:[di+1]
    push    ax
    Call    DisplayHexByte

    MOV     AH,0EH
    MOV     BL,7
    MOV     AL,' '
    INT     10H

    ret

sbkMidiCallBack     ENDP


;;--------------------------------------------------------------------------;;
;;  lpMidiCallBack&                                                         ;;
;;                                                                          ;;
;;  Description :                                                           ;;
;;      Get the MIDI call back function address.                            ;;
;;                                                                          ;;
;;  Entry :                                                                 ;;
;;      None.                                                               ;;
;;                                                                          ;;
;;  Exit :                                                                  ;;
;;      return far address of the MIDI call back function.                  ;;
;;                                                                          ;;
;;  Note :                                                                  ;;
;;      You need to define a MIDI call back function named sbkMidiCallBack. ;;
;;      Otherwise when link with this function lpMidiCallBack, the linker   ;;
;;      will report errors.                                                 ;;
;;--------------------------------------------------------------------------;;

lpMidiCallBack  PROC    FAR

    mov     ax, offset sbkMidiCallBack
    mov     dx, seg sbkMidiCallBack

    ret

lpMidiCallBack  ENDP


;; ------------------------------------------------------------------------ ;;
;;  Display Hexadecimal character                                           ;;
;;                                                                          ;;
;;  DisplayHexByte (bDispChar AS STRING * 1)                                ;;
;;                                                                          ;;
;;  Description :                                                           ;;
;;      To display a byte in hexadecimal. This function is used mainly by   ;;
;;      MIDI call back function to display an input MIDI code during call   ;;
;;      back period by the MIDI driver in which the call back function      ;;
;;      cannot perform any DOS function call.                               ;;
;;                                                                          ;;
;;  Entry :                                                                 ;;
;;      bDispChar :- byte to be displayed.                                  ;;
;;                                                                          ;;
;;  Exit :                                                                  ;;
;;      none.                                                               ;;
;; ------------------------------------------------------------------------ ;;

DisplayHexByte  PROC        bDispChar : byte

        push    bx

        mov     dh,0
        mov     dl,bDispChar

        push    dx
        shr     dx,1                ; shift the high nibble to lsb
        shr     dx,1
        shr     dx,1
        shr     dx,1
        and     dx,0Fh

            clc                     ; clear CARRY flag
            cmp     DL,9
            jg      DISPH10

            add     dl,'0'
            jmp     DISPH20

        DISPH10:
            sub     dl,0Ah
            add     dl,'A'

        DISPH20:
            mov     al,dl
            mov     ah,0Eh
            mov     bl,7
            int     10h

        pop     dx
        and     dx,0Fh

            clc                  ; clear CARRY flag
            cmp     dl,9
            jg      DISPH30

            add     dl,'0'
            jmp     DISPH40

        DISPH30:
            sub     dl,0Ah
            add     dl,'A'

        DISPH40:
            mov     al,dl
            mov     ah,0Eh
            MOV     bl,7
            int     10h

        pop     bx

        ret

DisplayHexByte   ENDP

        END     ;; End of code
