home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cdisk.zip / MMAP / MMAP.DAT < prev    next >
Text File  |  1991-07-11  |  27KB  |  853 lines

  1. //   OS/2 Device Driver for memory mapped I/O
  2. //
  3. //                Steve Mastrianni
  4. //                15 Great Oak Lane
  5. //                Unionville, CT 06085
  6. //                (203) 693-0404 voice
  7. //                (203) 693-9042 data
  8. //                CI$ 71501,1652
  9. //                BIX smastrianni
  10. //                Internet 6099225@mcimail.com
  11. //
  12. //   This driver is loaded in the config.sys file with the DEVICE=
  13. //   statement. For ISA configuration, the first parameter to the "DEVICE="
  14. //   is the board base memory address in hex.
  15. //
  16. //   This driver also returns a boolean to the calling application to
  17. //   inform it of the bus type (Micro Channel or ISA).
  18. //
  19. //   All numbers are in hex. For MCA configuration, the board address 
  20. //   is read from the board POS regs. The POS regs data is specific for
  21. //   each adapter, so the address calculations here may not work with 
  22. //   your specific adapter. Refer to the hardware tech reference for the
  23. //   particular adapter to determine where and how the address appears
  24. //   in the POS registers.
  25. //
  26. //
  27. //   This driver allows the application I/O to run in Ring 2 with IOPL.
  28. //   The CONFIG.SYS files *must* contain the IOPL=YES statement.
  29. //
  30. //   This driver supports 4 IOCtls, Category 0x90.
  31. //
  32. //   IOCtl 0x01 test for MCA or ISA bus
  33. //   IOCtl 0x02 gets and returns a selector to fabricated board memory
  34. //   IOCtl 0x03 gets the value of a selected POS register
  35. //   IOCtl 0x04 gets the board address that the driver found
  36. //
  37. //   The driver is made by using the make file mmap.mak.
  38.  
  39. #include "drvlib.h" 
  40. #include "mmap.h"
  41.  
  42. extern void near STRATEGY();        // name of strat rout. in DDSTART      
  43.  
  44. DEVICEHDR devhdr = {
  45.         (void far *) 0xFFFFFFFF,    // link                                 
  46.         (DAW_CHR | DAW_OPN | DAW_LEVEL1),// attribute                      
  47.         (OFF) STRATEGY,             // &strategy                        
  48.         (OFF) 0,                    // &IDCroutine                        
  49.         "MMAP$   "
  50. };
  51.  
  52. FPFUNCTION  DevHlp=0;               // storage area for DevHlp calls       
  53. LHANDLE     lock_seg_han;           // handle for locking appl. segment    
  54. PHYSADDR    appl_buffer=0;          // address of caller's buffer          
  55. PREQPACKET  p=0L;                   // pointer to request packet           
  56. ERRCODE     err=0;                  // error return                        
  57. void        far *ptr;               // temp far pointer                    
  58. USHORT      i,j;                    // general counters                    
  59. PHYSADDR    board_address;          // base board address                  
  60. USHORT      opencount;              // count of DosOpens                   
  61. USHORT      savepid;                // save the caller's PID               
  62. USHORT      cntr = 0;               // misc counter                        
  63. USHORT      bus = 0;                // default ISA bus                     
  64. REQBLK      ABIOS_r_blk;            // ABIOS request block                 
  65. LIDBLK      ABIOS_l_blk;            // ABIOS LID block                     
  66. USHORT      lid_blk_size;           // size of LID block                   
  67. CARD        card[MAX_NUM_SLOTS+1];  // array for IDs and POS reg values    
  68. CARD        *pcard;                 // pointer to card array               
  69. USHORT      matches = 0;            // match flag for card ID              
  70. POS_STRUCT  pos_struct;             // struct to get POS reg               
  71. ADDR_STRUCT addr_struct;            // struct for passing addresses        
  72. USHORT      chunk1,chunk2;          // temp variables for address calc     
  73.  
  74. char     arguments[64]={0};         // save command line args in dgroup    
  75. char     NoMatchMsg[]  = " no match for selected Micro Channel card ID found.\r\n";
  76. char     MainMsgMCA[]  = "\r\nOS/2 Micro Channel memory-mapped driver installed.\r\n";
  77. char     MainMsgISA[]  = "\r\nOS/2 ISA bus memory-mapped driver installed.\r\n";
  78.  
  79. // prototypes 
  80.  
  81. int      hex2bin(char c);
  82. USHORT   get_POS();
  83. UCHAR    get_pos_data();
  84. UCHAR    nget_pos_data();
  85.  
  86. // common entry point for calls to Strategy routines 
  87.  
  88. int main(PREQPACKET rp )
  89. {
  90.     void far *ptr;
  91.     int far *pptr;
  92.     PLINFOSEG liptr;                // pointer to local info seg           
  93.     int i;
  94.     ULONG addr;
  95.     USHORT in_data;
  96.  
  97.     switch(rp->RPcommand)
  98.     {
  99.     case RPINIT:                    // 0x00                                
  100.  
  101.         // init called by kernel in protected mode ring 3 with IOPL 
  102.  
  103.         return Init(rp);
  104.  
  105.     case RPOPEN:                    // 0x0d                                
  106.  
  107.         // get current processes id 
  108.  
  109.         if (GetDOSVar(2,&ptr))
  110.             return (RPDONE | RPERR | ERROR_BAD_COMMAND);
  111.  
  112.         // get process info 
  113.  
  114.         liptr = *((PLINFOSEG far *) ptr);
  115.  
  116.         // if this device never opened, can be opened by any process       
  117.  
  118.         if (opencount == 0)    // first time this device opened       
  119.         {
  120.             opencount=1;                 // set open counter                    
  121.             savepid = liptr->pidCurrent; // save current process id   
  122.         }
  123.         else
  124.             {
  125.             if (savepid != liptr->pidCurrent) // another proc tried to open 
  126.                 return (RPDONE | RPERR | RPBUSY ); // so return error      
  127.             ++opencount;            // bump counter, same pid              
  128.         }
  129.         return (RPDONE);
  130.  
  131.     case RPCLOSE:                   // 0x0e                                
  132.  
  133.         // get process info of caller 
  134.  
  135.         if (GetDOSVar(2,&ptr))
  136.             return (RPDONE | RPERR | ERROR_BAD_COMMAND); // no info        
  137.  
  138.         // get process info from os/2 
  139.  
  140.         liptr= *((PLINFOSEG far *) ptr); // ptr to process info seg        
  141.  
  142.         // 
  143.         // make sure that process attempting to close this device 
  144.         // one that originally opened it and the device was open in
  145.         // first place.
  146.         //
  147.  
  148.         if (savepid != liptr->pidCurrent || opencount == 0)  
  149.             return (RPDONE | RPERR | ERROR_BAD_COMMAND);
  150.  
  151.         // if an LDT selector was allocated, free it 
  152.  
  153.         PhysToUVirt(board_address,0x8000,2,&addr_struct.mapped_addr);
  154.  
  155.         --opencount;                // close counts down open counter      
  156.         return (RPDONE);            // return 'done' status to caller      
  157.  
  158.     case RPREAD:                    // 0x04                                
  159.  
  160.         return(RPDONE);
  161.  
  162.     case RPWRITE:                   // 0x08                                
  163.  
  164.         return (RPDONE);
  165.  
  166.     case RPIOCTL:                   // 0x10                                
  167.  
  168.         if (rp->s.IOCtl.category != OUR_CAT) // only our category          
  169.             return (RPDONE);
  170.  
  171.         switch (rp->s.IOCtl.function)
  172.         {
  173.  
  174.           // this IOCtl returns the bus type. If the type is Micro Channel
  175.           // the return is 0xff01. If ISA, the return is ff00
  176.  
  177.         case 0x01:                  // check if MCA or ISA
  178.             return (RPDONE | RPERR | bus);
  179.  
  180.           // this IOCtl maps an adapter memory to an LDT selector:offset,
  181.           // and sends it to the application for direct application reads
  182.           // and writes
  183.  
  184.         case 0x02:                  // send memory-mapped addr to app   
  185.  
  186.             // verify caller owns this buffer area 
  187.  
  188.             if(VerifyAccess(
  189.             SELECTOROF(rp->s.IOCtl.buffer), // selector                    
  190.             OFFSETOF(rp->s.IOCtl.buffer),   // offset                      
  191.             8,                              // 8 bytes                     
  192.             1) )                            // read write                  
  193.                 return (RPDONE | RPERR | ERROR_GEN_FAILURE);
  194.  
  195.             // lock the segment down temp 
  196.  
  197.             if(LockSeg(
  198.             SELECTOROF(rp->s.IOCtl.buffer), // selector                    
  199.             0,                              // lock < 2 sec                
  200.             0,                              // wait for seg lock           
  201.             (PLHANDLE) &lock_seg_han))      // handle returned             
  202.                 return (RPDONE | RPERR | ERROR_GEN_FAILURE);
  203.  
  204.            // map the board address to an LDT entry
  205.  
  206.            if ( PhysToUVirt(board_address,0x8000,1,&addr_struct.mapped_addr)) 
  207.                return (RPDONE | RPERR | ERROR_GEN_FAILURE);
  208.  
  209.            // move data to users buffer 
  210.  
  211.            if(MoveBytes(
  212.            &addr_struct,                   // source
  213.            rp->s.IOCtl.buffer,             // dest                      
  214.            8))                             // 8 bytes                     
  215.                return (RPDONE | RPERR | ERROR_GEN_FAILURE);
  216.  
  217.            // unlock segment 
  218.  
  219.            if(UnLockSeg(lock_seg_han))
  220.                return(RPDONE | RPERR | ERROR_GEN_FAILURE);
  221.  
  222.            return (RPDONE);
  223.  
  224.           // this IOCtl demonstrates how an application program can get the
  225.           // contents of a Micro Channel Adapter's POS registers
  226.  
  227.         case 0x03:                  // get pos reg data                    
  228.  
  229.             // verify caller owns this buffer area 
  230.  
  231.             if(VerifyAccess(
  232.             SELECTOROF(rp->s.IOCtl.buffer), // selector                    
  233.             OFFSETOF(rp->s.IOCtl.buffer),   // offset                      
  234.             6,                              // 6 bytes                     
  235.             1) )                            // read write                  
  236.                 return (RPDONE | RPERR | ERROR_GEN_FAILURE);
  237.  
  238.             // lock the segment down temp 
  239.  
  240.             if(LockSeg(
  241.             SELECTOROF(rp->s.IOCtl.buffer), // selector                    
  242.             0,                              // lock < 2 sec                
  243.             0,                              // wait for seg lock           
  244.             (PLHANDLE) &lock_seg_han))      // handle returned             
  245.                 return (RPDONE | RPERR | ERROR_GEN_FAILURE);
  246.  
  247.             // move slot data to driver buffer 
  248.  
  249.             if(MoveBytes(
  250.             (FARPOINTER) appl_buffer,       // source                      
  251.             &pos_struct,                    // for pos data                
  252.             6))                             // 6 bytes                     
  253.                 return (RPDONE | RPERR | ERROR_GEN_FAILURE);
  254.  
  255.             pos_struct.data = get_pos_data(pos_struct.slot,pos_struct.reg);
  256.  
  257.             // move POS reg data to users buffer 
  258.  
  259.             if(MoveBytes(
  260.             &pos_struct,                    // for pos data                
  261.             (FARPOINTER) appl_buffer,       // source                      
  262.             6))                             // 6 bytes                     
  263.                 return (RPDONE | RPERR | ERROR_GEN_FAILURE);
  264.  
  265.             // unlock segment 
  266.  
  267.             if(UnLockSeg(lock_seg_han))
  268.  
  269.                 return(RPDONE | RPERR | ERROR_GEN_FAILURE);
  270.  
  271.             return (RPDONE);
  272.  
  273.           // this IOCtl is essentially the same as 0x02, except the
  274.           // user virtual address is mapped to a linear address in the
  275.           // process address range and then sent to the application. This
  276.           // save the SelToFlat and FlatToSel each time the pointer is
  277.           // referenced.
  278.  
  279.         case 0x04:                  // 32-bit memory-mapped addr to app   
  280.  
  281.             // verify caller owns this buffer area 
  282.  
  283.             if(VerifyAccess(
  284.             SELECTOROF(rp->s.IOCtl.buffer), // selector                    
  285.             OFFSETOF(rp->s.IOCtl.buffer),   // offset                      
  286.             8,                              // 8 bytes                     
  287.             1) )                            // read write                  
  288.                 return (RPDONE | RPERR | ERROR_GEN_FAILURE);
  289.  
  290.             // lock the segment down temp 
  291.  
  292.             if(LockSeg(
  293.             SELECTOROF(rp->s.IOCtl.buffer), // selector                    
  294.             0,                              // lock < 2 sec                
  295.             0,                              // wait for seg lock           
  296.             (PLHANDLE) &lock_seg_han))      // handle returned             
  297.                 return (RPDONE | RPERR | ERROR_GEN_FAILURE);
  298.  
  299.            // map the board address to an LDT entry
  300.  
  301.            if ( PhysToUVirt(board_address,0x8000,1,&addr_struct.mapped_addr)) 
  302.                return (RPDONE | RPERR | ERROR_GEN_FAILURE);
  303.  
  304.               // now convert it to a linear address
  305.  
  306.               if (VirtToLin(SELECTOROF(addr_struct.mapped_addr),
  307.                            (ULONG)(OFFSETOF(addr_struct.mapped_addr)),
  308.                                 (PLINADDR)&addr_struct.mapped_addr))
  309.                return (RPDONE | RPERR | ERROR_GEN_FAILURE);
  310.  
  311.            // move data to users buffer 
  312.  
  313.            if(MoveBytes(
  314.            &addr_struct,                   // source
  315.            rp->s.IOCtl.buffer,             // dest                      
  316.            8))                             // 8 bytes                     
  317.                return (RPDONE | RPERR | ERROR_GEN_FAILURE);
  318.  
  319.            // unlock segment 
  320.  
  321.            if(UnLockSeg(lock_seg_han))
  322.                return(RPDONE | RPERR | ERROR_GEN_FAILURE);
  323.  
  324.            return (RPDONE);
  325.  
  326.         } // switch (rp->s.IOCtl.function 
  327.  
  328.     case RPDEINSTALL:               // 0x14                            
  329.  
  330.         return(RPDONE | RPERR | ERROR_BAD_COMMAND);
  331.  
  332.         // all other commands are ignored 
  333.  
  334.     default:
  335.         return(RPDONE);
  336.  
  337.     }
  338. }
  339.  
  340. int  hex2bin(char c)
  341. {
  342.  if(c < 0x3a)
  343.   return (c - 48);
  344.  else
  345.   return (( c & 0xdf) - 55);
  346. }
  347.  
  348. USHORT get_POS(USHORT slot_num,USHORT far *card_ID,UCHAR far *pos_regs)
  349. {
  350. USHORT rc, i, lid;
  351.     
  352.     if (GetLIDEntry(0x10, 0, 1, &lid)) // get LID for POS   
  353.         return (1);
  354.  
  355.     // Get the size of the LID request block 
  356.  
  357.     ABIOS_l_blk.f_parms.req_blk_len = sizeof(struct lid_block_def);
  358.     ABIOS_l_blk.f_parms.LID = lid;
  359.     ABIOS_l_blk.f_parms.unit = 0;;
  360.     ABIOS_l_blk.f_parms.function = GET_LID_BLOCK_SIZE;
  361.     ABIOS_l_blk.f_parms.ret_code = 0x5a5a;
  362.     ABIOS_l_blk.f_parms.time_out = 0;
  363.  
  364.     if (ABIOSCall(lid,0,(void far *)&ABIOS_l_blk))
  365.         return (1);
  366.  
  367.     lid_blk_size = ABIOS_l_blk.s_parms.blk_size; // Get the block size  
  368.  
  369.     // Fill POS regs and card ID with FF in case this does not work          
  370.  
  371.     *card_ID = 0xFFFF;
  372.     for (i=0; i<NUM_POS_BYTES; i++) { pos_regs[i] = 0x00; }; 
  373.  
  374.     // Get the POS registers and card ID for the commanded slot 
  375.  
  376.     ABIOS_r_blk.f_parms.req_blk_len = lid_blk_size;
  377.     ABIOS_r_blk.f_parms.LID = lid;
  378.     ABIOS_r_blk.f_parms.unit = 0;;
  379.     ABIOS_r_blk.f_parms.function = READ_POS_REGS_CARD;
  380.     ABIOS_r_blk.f_parms.ret_code = 0x5a5a;
  381.     ABIOS_r_blk.f_parms.time_out = 0;
  382.     
  383.     ABIOS_r_blk.s_parms.slot_num = (UCHAR)slot_num & 0x0F;
  384.     ABIOS_r_blk.s_parms.pos_buf = (void far *)pos_regs;
  385.     ABIOS_r_blk.s_parms.card_ID = 0xFFFF;
  386.     
  387.     if (ABIOSCall(lid,0,(void far *)&ABIOS_r_blk))
  388.        rc = 1;
  389.      else {                                       // Else                 
  390.        *card_ID = ABIOS_r_blk.s_parms.card_ID;   //    Set the card ID value     
  391.        rc = 0;
  392.       }
  393.     FreeLIDEntry(lid);
  394.     return(rc);
  395.     
  396. }
  397.  
  398. UCHAR get_pos_data (int slot, int reg)
  399. {
  400.    UCHAR pos;
  401.    CARD *cptr;
  402.  
  403.    cptr = &card[slot-1];            // set pointer to beg of card array    
  404.    if (reg == 0)                    // card ID                             
  405.       pos = LOUSHORT(cptr->card_ID);
  406.    else
  407.      if ( reg == 1)
  408.       pos = HIUSHORT(cptr->card_ID);
  409.    else
  410.       pos = cptr->pos_regs[reg-2];  // POS data register                   
  411.    return (pos);
  412. }
  413.  
  414. // Device Initialization Routine 
  415.  
  416. int Init(PREQPACKET rp)
  417. {
  418.     USHORT lid;
  419.  
  420.     register char far *p;
  421.  
  422.     // store DevHlp entry point 
  423.  
  424.     DevHlp = rp->s.Init.DevHlp;  // save DevHlp entry point             
  425.  
  426.     if (!(GetLIDEntry(0x10, 0, 1, &lid))) { // get LID for POS   
  427.        FreeLIDEntry(lid);
  428.  
  429.   // Micro Channel (tm) setup section 
  430.  
  431.   bus = 1;                      // MCA bus                             
  432.  
  433.       //    Get the POS data and card ID for each of 8 possible slots 
  434.  
  435.       for (i=0;i <= MAX_NUM_SLOTS; i++) 
  436.          get_POS(i+1,(FARPOINTER)&card[i].card_ID,(FARPOINTER)card[i].pos_regs);
  437.  
  438.       matches = 0;
  439.       for (i=0, pcard = card; i <= MAX_NUM_SLOTS; i++, pcard++) {
  440.          if (pcard->card_ID == TARGET_ID) { 
  441.             matches = 1;
  442.             break;
  443.             }
  444.          }
  445.  
  446.       if (matches == 0) {           // at least one board found          
  447.    DosPutMessage(1, 8, devhdr.DHname);
  448.    DosPutMessage(1,strlen(NoMatchMsg),NoMatchMsg);
  449.      rp->s.InitExit.finalCS = (OFF) 0;
  450.    rp->s.InitExit.finalDS = (OFF) 0;
  451.    return (RPDONE | RPERR | ERROR_BAD_COMMAND);
  452.    }
  453.  
  454.       // calculate the board address from the POS regs 
  455.  
  456.     board_address = ((unsigned long) get_pos_data(i+1, 4) << 16) |
  457.     ((unsigned long)(get_pos_data(i+1, 3) & 1) << 15);
  458.   }
  459.  
  460.   else
  461.  
  462.   // ISA bus setup 
  463.  
  464.   {
  465.   bus = 0;                      // ISA bus                             
  466.  
  467.   // get parameters, IRQ (not used yet), port addr and base mem addr 
  468.   
  469.   for (p = rp->s.Init.args; *p && *p != ' ';++p);// skip driver name 
  470.   for (; *p == ' '; ++p);       // skip blanks following driver name   
  471.   if (*p)
  472.    {
  473.          board_address=0;           // i/o port address                    
  474.    for (; *p != '\0'; ++p)    // get board address                   
  475.     board_address = (board_address << 4) + (hex2bin(*p));
  476.    addr_struct.board_addr = board_address;
  477.    }
  478.   }
  479.  
  480.   if (bus)
  481.          DosPutMessage(1,strlen(MainMsgMCA),MainMsgMCA);
  482.       else
  483.          DosPutMessage(1,strlen(MainMsgISA),MainMsgISA);
  484.  
  485.   // send back our cs and ds end values to os/2 
  486.         
  487.   if (SegLimit(HIUSHORT((void far *) Init), &rp->s.InitExit.finalCS) ||
  488.      SegLimit(HIUSHORT((void far *) MainMsgISA), &rp->s.InitExit.finalDS))
  489.        Abort();
  490.   
  491.   Beep(200,500);
  492.   Beep(200,500);
  493.   Beep(250,500);
  494.   Beep(300,500);
  495.   Beep(250,500);
  496.   Beep(300,500);
  497.  
  498.   return (RPDONE);
  499.   
  500. }
  501. LIBRARY PAC
  502. PROTMODE
  503. 
  504. #  makefile for memory mapped driver
  505.  
  506. mmap.sys: ddstart.obj mmap.obj 
  507.     link /nod /noi /map ddstart+mmap,mmap.sys,mmap,c:\os2\doscalls+d:\lib\slibcep+\
  508. d:\drvlib\drvlib\drvlib,mmap.def
  509.         mapsym mmap
  510.  
  511. ddstart.obj: ddstart.asm
  512.     masm -Mx -t -L -N ddstart;
  513.  
  514. mmap.obj: mmap.c drvlib.h mmap.h 
  515.     cl -Fa -c -Asnw -Gs -G2 -Zl -Zp -Ox mmap.c
  516.  
  517. /*
  518.   include file for memory-mapped driver
  519. */
  520.  
  521. #define  OUR_CAT  0x91               /* category for DosDevIOCtl */
  522. #define  MEMSIZE  32800              /* 32 K bytes per adapter   */
  523. #define  POS_BASE 0x100              /* MCA adapter base         */
  524. #define  TARGET_ID 0x6CFD            /* adapter ID               */
  525. #define  NUM_POS_BYTES 64
  526. #define  MAX_NUM_SLOTS 8
  527. #define  MAX_DEV_NUMS 8
  528. #define  MAX_NUM_DSPS 5
  529. #define  READY  0xFFFF               /* dsp read                 */
  530. #define  POS_PORT 0x96
  531. #define  POS_BASE 0x100
  532.                
  533. /* Constants used by ABIOS calls */
  534.  
  535. #define GET_LID_BLOCK_SIZE 0x01
  536. #define POS_LID            0x10
  537. #define READ_POS_REGS      0x0B
  538. #define READ_POS_REGS_RAM  0x0B
  539. #define READ_POS_REGS_CARD 0x0D
  540.  
  541. typedef struct _POS_STRUCT {
  542.     USHORT    slot;
  543.     USHORT   reg;
  544.    USHORT   data;
  545.     } POS_STRUCT;
  546. typedef POS_STRUCT far *PPOS_STRUCT;
  547.  
  548. typedef struct _ADDR_STRUCT {
  549.     void     far *mapped_addr;
  550.     ULONG    board_addr;
  551.     } ADDR_STRUCT;
  552. typedef ADDR_STRUCT far *PADDR_STRUCT;
  553.  
  554. typedef struct function_parms_def {
  555.    USHORT    req_blk_len;
  556.    USHORT    LID;
  557.    USHORT    unit;
  558.    USHORT    function;
  559.    USHORT    resvd1;
  560.    USHORT    resvd2;
  561.    USHORT    ret_code;
  562.    USHORT    time_out;
  563.    } function_parms_type;
  564.  
  565. typedef struct service_parms_def {
  566.    UCHAR     slot_num;        /* 10h */
  567.    UCHAR     resvd3;          /* 11h */
  568.    USHORT    card_ID;         /* 12h */
  569.    USHORT    resvd4;          /* 14h */
  570.    UCHAR     far *pos_buf;    /* 16h */
  571.    USHORT    resvd5;          /* 1Ah */
  572.    USHORT    resvd6;          /* 1Ch */
  573.    UCHAR     resvd7[40];      /* 1Eh */
  574.    } service_parms_type;
  575.  
  576. typedef struct lid_service_parms_def {
  577.    UCHAR     irpt_level;          /* 10h */
  578.    UCHAR     arb_level;           /* 11h */
  579.    USHORT    device_id;       /* 12h */
  580.    USHORT    unit_count;      /* 14h */
  581.    USHORT    flags;           /* 16h */
  582.    USHORT    blk_size;        /* 18h */
  583.    USHORT    secnd_id;        /* 1Ah */
  584.    USHORT    resvd6;          /* 1Ch */
  585.    USHORT    resvd7;          /* 1Eh */
  586.    } lid_service_parms_type;
  587.  
  588. typedef struct req_block_def {
  589.    function_parms_type f_parms;
  590.    service_parms_type  s_parms;
  591.    } REQBLK;
  592.  
  593. typedef struct lid_block_def {
  594.    function_parms_type     f_parms;
  595.    lid_service_parms_type  s_parms;
  596.    } LIDBLK;
  597.  
  598. typedef struct card_def {
  599.   USHORT     card_ID;        /* ID of the card in this slot              */
  600.   UCHAR      pos_regs[NUM_POS_BYTES];
  601.   } CARD;
  602.  
  603.  
  604. #define      INCL_DOSFILEMGR
  605. #define      INCL_DOS
  606. #define      INCL_DOSDEVICES
  607. #define      INCL_DOSDEVIOCTL
  608. #include     <os2.h>
  609. #include     <stdio.h>
  610. #include     "test.h"
  611. HFILE         driver_handle=0; 
  612. USHORT       err;
  613. UCHAR        far *myptr=0;
  614. USHORT       ActionTaken;
  615. USHORT       rc;
  616. ULONG        FileSize=0;
  617. USHORT       FileAttribute;
  618. ULONG        Reserved=0L;
  619. UCHAR        Data1[8]={0};
  620. UCHAR        Data2=0;
  621. PADDR_STRUCT paddr_ptr;
  622.  
  623. void main()
  624. {
  625.  
  626.           // open the driver
  627.  
  628.         if ((rc = DosOpen("MMAP$   ",
  629.         &driver_handle,
  630.         &ActionTaken,
  631.         FileSize,
  632.         FileAttribute,
  633.         FILE_OPEN,
  634.         OPEN_SHARE_DENYNONE | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_ACCESS_READWRITE,
  635.         Reserved)) !=0) 
  636.           {
  637.             printf("\nDosOpen failed, error = %d",rc);
  638.                 DosExit(EXIT_PROCESS,0);
  639.           }
  640.  
  641.           printf ("Bus Type              = ");
  642.  
  643.         rc = DosDevIOCtl(&Data1,&Data2,0x01,OUR_CAT,driver_handle);
  644.           
  645.           if (rc & 0x01)
  646.              printf ("Micro Channel (tm)\n");
  647.           else
  648.              printf ("ISA\n");
  649.  
  650.         if (rc = DosDevIOCtl(&Data1,&Data2,0x02,OUR_CAT,driver_handle))
  651.           {
  652.              printf ("DevIOCtl failed, error code = %d\n",rc);
  653.               DosExit(EXIT_PROCESS,0);
  654.           }
  655.  
  656.           // pointer to data buffer
  657.  
  658.           paddr_ptr = (PADDR_STRUCT) Data1;
  659.  
  660.           printf ("Memory Mapped Address = %p\nPhysical Address      = %lx\n",
  661.                  paddr_ptr->mapped_addr,paddr_ptr->board_addr);
  662.  
  663.           myptr = (void far *) paddr_ptr->mapped_addr;
  664.  
  665.           printf ("First Byte Of Adapter = %x\n",*myptr);
  666.  
  667.           // close driver
  668.  
  669.           DosClose(driver_handle);
  670. }
  671. //  include file for test.c 
  672.  
  673. #define  OUR_CAT  0x91               // category for DosDevIOCtl 
  674. #define  DRIVER_BASE 0xD8000         // board address            
  675. #define  BASE_LENGTH 0x1000             // length of memory map     
  676.  
  677. typedef struct _ADDR_STRUCT {
  678.     void     far *mapped_addr;
  679.     ULONG    board_addr;
  680.     } ADDR_STRUCT;
  681. typedef ADDR_STRUCT far *PADDR_STRUCT;
  682.  
  683. protmode
  684. test.exe: test.obj
  685.      link16 test,test,test,+c:\os2\doscalls+d:\lib\llibcep,,test.def
  686.  
  687. test.obj: test.c
  688.      cl -AL -G2 -c test.c
  689.  
  690. #define INCL_DOS
  691. #include <os2.h>
  692.  
  693. #define  EABUF       0L
  694. #define  OUR_CAT  0x91L
  695. #define  BUS_TYPE 0x01L
  696. #define  GET_PTR  0x02L
  697. #define  GET_POS  0x03L
  698.  
  699. typedef struct _ADDR_STRUCT {
  700.     void     * _Seg16 mapped_addr;
  701.     ULONG    board_addr;
  702.     } ADDR_STRUCT;
  703. typedef ADDR_STRUCT *PADDR_STRUCT;
  704.  
  705.  
  706. char     buf[100] = {0};
  707. USHORT   BytesRead;
  708. ULONG    ActionTaken;               /* for file opens                      */
  709. APIRET   rc;                        /* return code for driver open         */
  710. ULONG    FileSize=0;                /* NULL file size                      */
  711. ULONG    FileAttribute;             /* attribute bits                      */
  712. HFILE    handle=0;
  713. UCHAR    parmbuf [20];
  714. UCHAR    databuf[20];
  715. ULONG    plength,dlength;
  716. PADDR_STRUCT paddr_ptr;
  717. UCHAR    * _Seg16 myptr;
  718.  
  719. main()
  720. {
  721.     rc = DosOpen("MMAP$   ",
  722.     &handle,
  723.     &ActionTaken,
  724.     FileSize,
  725.     FileAttribute,
  726.     OPEN_ACTION_OPEN_IF_EXISTS,
  727.     OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | OPEN_FLAGS_NOINHERIT, 
  728.     EABUF);
  729.       if (rc) {
  730.         printf("\nDosOpen failed, error = %ld",rc);
  731.         DosExit(EXIT_PROCESS,0);    /* exit gracefully                     */
  732.        }
  733.  
  734.      printf ("Bus Type              = ");
  735.  
  736.      rc = DosDevIOCtl(handle,OUR_CAT,BUS_TYPE,0,0L,&plength,databuf,8L,&dlength);
  737.  
  738.      if (rc & 0x01)
  739.         printf ("Micro Channel (tm)\n");
  740.      else
  741.         printf ("ISA\n");
  742.  
  743.      rc = DosDevIOCtl(handle,OUR_CAT,GET_PTR,0,0L,&plength,databuf,8L,&dlength); 
  744.  
  745.     if (rc)
  746.      {
  747.       printf ("DevIOCtl failed, error code = %ld\n",rc);
  748.         DosExit(EXIT_PROCESS,0);
  749.      }    
  750.  
  751.     paddr_ptr = (PADDR_STRUCT) databuf;
  752.  
  753.      printf ("Memory Mapped Address = %p\nPhysical Address      = %lx\n",
  754.             paddr_ptr->mapped_addr,paddr_ptr->board_addr);
  755.  
  756.      myptr = paddr_ptr->mapped_addr; 
  757.  
  758.      printf ("First Byte Of Adapter = %x\n",*myptr);
  759.  
  760.     DosClose(handle);
  761.  
  762. name test32 
  763. protmode
  764. test32.exe: test32.obj
  765.      link386 /MAP /NOI /PM:vio test32,test32,test32,,,test32.def
  766.  
  767. test32.obj: test32.c
  768.      icc /c /Gt+ test32.c
  769.  
  770. #define INCL_DOS
  771. #include <os2.h>
  772.  
  773. #define  EABUF       0L
  774. #define  OUR_CAT  0x91L
  775. #define  BUS_TYPE 0x01L
  776. #define  GET_PTR  0x02L
  777. #define  GET_POS  0x03L
  778. #define  GET_LIN  0x04L
  779.  
  780. typedef struct _ADDR_STRUCT {
  781.     void     *mapped_addr;
  782.     ULONG    board_addr;
  783.     } ADDR_STRUCT;
  784. typedef ADDR_STRUCT *PADDR_STRUCT;
  785.  
  786.  
  787. char     buf[100] = {0};
  788. USHORT   BytesRead;
  789. ULONG    ActionTaken;               /* for file opens                      */
  790. APIRET   rc;                        /* return code for driver open         */
  791. ULONG    FileSize=0;                /* NULL file size                      */
  792. ULONG    FileAttribute;             /* attribute bits                      */
  793. HFILE    handle=0;
  794. UCHAR    parmbuf [20];
  795. UCHAR    databuf[20];
  796. ULONG    plength,dlength;
  797. PADDR_STRUCT paddr_ptr;
  798. UCHAR    *myptr;
  799.  
  800. main()
  801. {
  802.     rc = DosOpen("MMAP$   ",
  803.     &handle,
  804.     &ActionTaken,
  805.     FileSize,
  806.     FileAttribute,
  807.     OPEN_ACTION_OPEN_IF_EXISTS,
  808.     OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | OPEN_FLAGS_NOINHERIT, 
  809.     EABUF);
  810.       if (rc) {
  811.         printf("\nDosOpen failed, error = %ld",rc);
  812.         DosExit(EXIT_PROCESS,0);    /* exit gracefully                     */
  813.        }
  814.  
  815.      printf ("Bus Type              = ");
  816.  
  817.      rc = DosDevIOCtl(handle,OUR_CAT,BUS_TYPE,0,0L,&plength,databuf,8L,&dlength);
  818.  
  819.      if (rc & 0x01)
  820.         printf ("Micro Channel (tm)\n");
  821.      else
  822.         printf ("ISA\n");
  823.  
  824.      rc = DosDevIOCtl(handle,OUR_CAT,GET_LIN,0,0L,&plength,databuf,8L,&dlength); 
  825.  
  826.     if (rc)
  827.      {
  828.       printf ("DevIOCtl failed, error code = %ld\n",rc);
  829.         DosExit(EXIT_PROCESS,0);
  830.      }    
  831.  
  832.     paddr_ptr = (PADDR_STRUCT) databuf;
  833.  
  834.      printf ("Memory Mapped Address = %p\nPhysical Address      = %lx\n",
  835.             paddr_ptr->mapped_addr,paddr_ptr->board_addr);
  836.  
  837.      myptr = paddr_ptr->mapped_addr; 
  838.  
  839.      printf ("First Byte Of Adapter = %x\n",*myptr);
  840.  
  841.     DosClose(handle);
  842.  
  843. protmode
  844. test32a.exe: test32a.obj
  845.      link386 /MAP /NOI /PM:vio test32a,test32a,test32a,,,test32a.def
  846.  
  847. test32a.obj: test32a.c
  848.      icc /c /Gt+ test32a.c
  849.  
  850.  
  851.