home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / AOCE / Development Tools / Sample Code / Catalog Service Access Module / DTS Sample CSAM / Src / ThinkDriverGlue.c < prev   
Encoding:
C/C++ Source or Header  |  1993-11-03  |  5.8 KB  |  176 lines  |  [TEXT/KAHL]

  1. /*                                ThinkDriverGlue.c                                */
  2. /*
  3.  * ThinkDriverGlue.c
  4.  * Copyright © 1992-93 Apple Computer Inc. All Rights Reserved.
  5.  *
  6.  * ThinkDriverGlue.c contains the driver header that
  7.  * connects our  driver to the Macintosh O.S. This file
  8.  * contains assembler code that was copied directly from
  9.  * MPWDriverGlue.a. You should refer to MPWDriverGlue.a
  10.  * for an explanation of what is going on. The documentation
  11.  * in this file is primarily intended to explain issues
  12.  * specific to Think C.
  13.  *
  14.  * Note that you must define the project as a code resource
  15.  * of type 'DRVR', id 11.
  16.  *
  17.  * The final Rez operation constructs the driver out of the
  18.  * various pieces. Be sure to use the following options when
  19.  * you set the Think Project Type parameters:
  20.  *        Code Resource
  21.  *        'DRVR' Resource Type
  22.  *        11 Resource ID
  23.  *        Custom Headers must be selected
  24.  *        The file name must be ThinkSampleDriver
  25.  * Also, in the Think C Preferences, be sure to change
  26.  * the Prefix so you do not include <MacHeaders>
  27.  *
  28.  * Unlike the driver support provided with Think C 5.0,
  29.  * you must observe the following (MPW-compatible)
  30.  * restrictions when writing your driver:
  31.  *     -- Your driver must not use global or static variables.
  32.  *        Instead, your OpenDRVR function must create and
  33.  *        initialize the driver control block defined by
  34.  *        devCtlEnt->dCtlStorage. Your driver routines
  35.  *        must also maintain the dCtlStorage value (locking
  36.  *        and unlocking it if you choose to define it as
  37.  *        a handle) and CloseDRVR must delete the storage
  38.  *        if this is appropriate.
  39.  *     --    Your driver MUST be in a single segment. The Think
  40.  *        compiler uses A4 references to access the function
  41.  *        globals for multi-segmented drivers. A4 is, however,
  42.  *        meaningless in our MPW-Think compatible design
  43.  *     --    All driver functions return the OSErr value
  44.  *        that is to be returned to the caller. Your functions
  45.  *        must also store the OSErr value in the ioResult
  46.  *        field of the parameter block. It should return +1
  47.  *        if the user request has not completed (i.e., the
  48.  *        driver was called asychronously and I/O is pending.)
  49.  *     --    You can't use the Think Debugger to debug drivers.
  50.  *
  51.  * Author:        Martin Minow
  52.  *                Apple Computer Inc.
  53.  *                Cupertino, CA, USA
  54.  * InterNet:    minow@apple.com
  55.  * AppleLink:    MINOW
  56.  */
  57. #include <Errors.h>
  58. #include <Devices.h>
  59. #include <THINK.h>
  60. /*
  61.  * Note: THINK.h defines noQueueBit as a mask, but it must
  62.  * be a number for assembler
  63.  */
  64. #define noQueueBitNumber    0x09
  65.  
  66. #define ioBusy        (1)
  67. #define JIODone        0x8FC        /* Copied from SysEqu.h            */
  68.  
  69. extern OSErr        OpenDRVR(
  70.         CntrlParam        *paramBlock,
  71.         DCtlPtr            devCtlEnt
  72.     );
  73. extern OSErr        PrimeDRVR(
  74.         CntrlParam        *paramBlock,
  75.         DCtlPtr            devCtlEnt
  76.     );
  77. extern OSErr        ControlDRVR(
  78.         CntrlParam        *paramBlock,
  79.         DCtlPtr            devCtlEnt
  80.     );
  81. extern OSErr        StatusDRVR(
  82.         CntrlParam        *paramBlock,
  83.         DCtlPtr            devCtlEnt
  84.     );
  85. extern OSErr        CloseDRVR(
  86.         CntrlParam        *paramBlock,
  87.         DCtlPtr            devCtlEnt
  88.     );
  89.  
  90. void                main(void);
  91. /*
  92.  * Think C links the file containing main at the start
  93.  * of the segment.
  94.  *
  95.  * Note: in order for the following to work, your driver
  96.  * *M*U*S*T* be written as a single segment.
  97.  */
  98. void
  99. main(void)
  100. {
  101.         asm {
  102. /*
  103.  * These word definitions create the driver prefix.
  104.  */
  105.             dc.w        (dNeedLock | dCtlEnable)    ; dCtlFlags
  106.             dc.w        0                            ; drvrDelay
  107.             dc.w        0                            ; drvrEMask
  108.             dc.w        0                            ; drvrMenu
  109. /*
  110.  * These are offsets to the driver glue code.
  111.  */
  112.             dc.w        0x32                        ; Open offset
  113.             dc.w        0x36                        ; Prime offset
  114.             dc.w        0x3A                        ; Control offset
  115.             dc.w        0x3E                        ; Status offset
  116.             dc.w        0x42                        ; Close offset
  117. /*
  118.  * This is a 32 byte string -- it must be identical to the string
  119.  * defined in DTSSampleCSAMDriver.r. Note: it *must* be exactly
  120.  * 32 bytes long for the above offsets to work correctly. Each
  121.  * line (dc.b statement) must have an even number of bytes.
  122.  */
  123.              dc.b        0x0F,'.','S','a','m','p','l','e'
  124.              dc.b        ' ','C','a','t','a','l','o','g'
  125.              dc.b        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  126. /*
  127.  * The driver glue handlers. Note: Think C compiles the PEA as an A4-relative
  128.  * operation. If the driver eventually links as a single segment, the linker
  129.  * will change the A4-relative addressing to PC-relative, which is what
  130.  * we need. If you need to support a multi-segment driver, you should use
  131.  * the Think-supplied driver header (define your project as a device driver)
  132.  * and handle compatibility between Think and MPW in some other fashion.
  133.  * Those considerations, however, are beyond the scope of this example.
  134.  */
  135.             bra.s        @openGlue
  136.             nop                                    ; For DRVR offset
  137.             bra.s        @primeGlue
  138.             nop                                    ; For DRVR offset
  139.             bra.s        @controlGlue
  140.             nop                                    ; For DRVR offset
  141.             bra.s        @statusGlue
  142.             nop                                    ; For DRVR offset
  143. closeGlue:    pea            CloseDRVR
  144.             bra.s        @common        
  145. openGlue:    pea            OpenDRVR                ; The function we want to call
  146.             bra.s        @common                    ; Continue at the common code.
  147. primeGlue:    pea            PrimeDRVR
  148.             bra.s        @common
  149. controlGlue: pea        ControlDRVR
  150.             bra.s        @common
  151. statusGlue:    pea            StatusDRVR
  152. /**            bra.s        @common        **/
  153. common:        
  154.             move.l        (a7)+,d0                ; Recover the function address
  155.             link        a6,#0                    ; Establish a stack frame
  156.             movem.l        d1-d3/a0-a4,-(a7)        ; Save registers
  157.             move.l        a1,-(a7)                ; Push DCE Ptr on the stack
  158.             move.l        a0,-(a7)                ; Push ParamBlockPtr on the stack
  159.             move.l        d0,a0                    ; Get the function to call
  160.             lea            main,a4                    ; Establish an A4 frame for Think C
  161.             jsr            (a0)                    ; Call the handler
  162.             addq.w        #8,a7                    ; Clear parameters from stack
  163.             movem.l        (a7)+,d1-d3/a0-a4        ; Restore registers
  164.             btst        #noQueueBitNumber,IOParam.ioTrap(a0) ; Is noQueueBit set?
  165.             bne.s        @exit                    ; Branch if so
  166.             cmp.w        #ioBusy,d0                ; C result "incomplete"?
  167.             beq.s        @exit                    ; Branch if so
  168.             unlk        a6                        ; I/O complete, clear linkage
  169.             move.l        JIODone,-(a7)            ; Return via jIODone
  170.             rts                                    ; Completion return
  171. exit:        unlk        a6                        ; Unlink stack frame for
  172.             rts                                    ; incomplete return
  173.         }
  174. }
  175.  
  176.