home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / devddemo.zip / DDUTILS.C < prev    next >
Text File  |  1991-02-02  |  16KB  |  319 lines

  1. /*****************************************************************************/
  2. /* General Device Driver Utilities                                           */
  3. /*****************************************************************************/
  4. /* This file contains a bunch of general utility functions all DDs need.     */
  5. /* There are things like change CPU mode, get the current time, yield the    */
  6. /* CPU, block and unblock threads, generate the Dreaded Internal Error msg,  */
  7. /* send EOI, and some request packet queueing functions.                     */
  8. /*****************************************************************************/
  9. /*                                                                           */
  10. /*  void to_prot_mode(void)                                                  */
  11. /*                                                                           */
  12. /*  This function changes the CPU mode from REAL to PROTECT, if it was in    */
  13. /*  REAL mode to begin with.  It also sets a global flag indicating that     */
  14. /*  what mode the CPU was in when entered.  This lets the to_real_mode()     */
  15. /*  function know when to change it back.                                    */
  16. /*                                                                           */
  17. /*****************************************************************************/
  18. /*                                                                           */
  19. /*  void point_to_global(void)                                               */
  20. /*                                                                           */
  21. /*  This function sets up a pointer to the System Global Information         */
  22. /*  segment.  This pointer is GDT based, useable after INIT is done.         */
  23. /*                                                                           */
  24. /*  The basic operation is doen via a call to GetDOSVar DevHlp function with */
  25. /*  a variable number of 1 - SysINFOSeg.  This returns a pointer to a 2-byte */
  26. /*  value.  This value is the selector of the Global Info.  This selector is */
  27. /*  then made into a pointer.                                                */
  28. /*                                                                           */
  29. /*****************************************************************************/
  30. /*                                                                           */
  31. /*  unsigned long curr_time()                                                */
  32. /*                                                                           */
  33. /*  This function returns the current Milliseconds_Since_IPL value from the  */
  34. /*  Global Information Segment.  It is useable at any time except INIT time. */
  35. /*  It cannot be called until AFTER point_to_global() has been called.       */
  36. /*                                                                           */
  37. /*****************************************************************************/
  38. /*                                                                           */
  39. /*  void far yield()                                                         */
  40. /*                                                                           */
  41. /*  This function yields the CPU.  It does it by using the BLOCK DevHlp call */
  42. /*  rather than the YIELD call because the YIELD may not YIELD.  The BLOCK   */
  43. /*  will always work.  It BLOCKs for 32 mSec.  It generates a Block-id from  */
  44. /*  the current time.                                                        */
  45. /*                                                                           */
  46. /*  When it returns, the CPU has been yielded and other tasks have been      */
  47. /*  dispatched.                                                              */
  48. /*                                                                           */
  49. /*****************************************************************************/
  50. /*                                                                           */
  51. /*  void far block(block_id, timeout)                                        */
  52. /*  unsigned long block_id;                                                  */
  53. /*  unsigned long timeout;                                                   */
  54. /*                                                                           */
  55. /*  This function blocks the current thread for up to timeout mSec.  It uses */
  56. /*  the BLOCK DevHlp call.  The block is non-interruptable.                  */
  57. /*                                                                           */
  58. /*****************************************************************************/
  59. /*                                                                           */
  60. /*  void far unblock(block_id)                                               */
  61. /*  unsigned long block_id;                                                  */
  62. /*                                                                           */
  63. /*  This function unblocks a thread that is blocked with the given block-id. */
  64. /*                                                                           */
  65. /*****************************************************************************/
  66. /*                                                                           */
  67. /*  void far internal_error(msg_num)                                         */
  68. /*  unsigned msg_num;                                                        */
  69. /*                                                                           */
  70. /*  This function generates the Dreaded Internal Error Detected message with */
  71. /*  your own message text added.  The msg_num is an index into the err_msgs  */
  72. /*  array defined above.  So far, only 1 message is defined.  Calling this   */
  73. /*  function WILL lock up the machine so that only a power off will clear    */
  74. /*  it.  Use only in dire emergencies.                                       */
  75. /*                                                                           */
  76. /*****************************************************************************/
  77. /*                                                                           */
  78. /*  void far push_req_pkt(queue,req)                                         */
  79. /*  _32bits     *queue;                                                      */
  80. /*  reqhdr_type *req;                                                        */
  81. /*                                                                           */
  82. /*  This function adds a request packet to the end of a queue.  It uses the  */
  83. /*  PushReqPacket DevHlp call.                                               */
  84. /*                                                                           */
  85. /*****************************************************************************/
  86. /*                                                                           */
  87. /*  void var pull_req_pkt(queue,req)                                         */
  88. /*  _32bits     *queue;                                                      */
  89. /*  reqhdr_type *req;                                                        */
  90. /*                                                                           */
  91. /*  This function retrieves the next request packet from a queue.  It uses   */
  92. /*  the PullReqPacket DevHlp call.  It stores the pointer to the request     */
  93. /*  packet in req.                                                           */
  94. /*                                                                           */
  95. /*****************************************************************************/
  96. /*                                                                           */
  97. /* void far dev_done(req,status)                                             */
  98. /* reqhdr_type *req;                                                         */
  99. /* word status;                                                              */
  100. /*                                                                           */
  101. /* dev_done - Set the status in the request packet, set the done bit and     */
  102. /*            unblock the process.                                           */
  103. /*                                                                           */
  104. /* Only return code is SUCCESS.  This is the only return code from the       */
  105. /* devhlp function that is called.                                           */
  106. /*                                                                           */
  107. /*****************************************************************************/
  108. #include <string.h>
  109. #include "demo.h"
  110.  
  111. static struct global_info_seg far * near g_info;
  112.  
  113. static byte * near err_msgs[] = {"$DEMO - Big Time ERROR" };
  114.  
  115. boolean far to_prot_mode(void)
  116. {
  117.  
  118.   /* If we are in REAL mode  */
  119.   if (real_mode() == TRUE) {
  120.  
  121.      /* Change to PROT mode */
  122.      to_prot_moda();
  123.  
  124.      /* And say we did it */
  125.      return(TRUE);
  126.      }
  127.  
  128.   /* Otherwise, say we didn't */
  129.   return(FALSE);
  130. }
  131.  
  132. void far point_to_global()
  133. {
  134.   _32bits          pointer;     /* A scratch 32 bit value                   */
  135.   _32bits          gdt_virt;    /* Virtual address of the GDT               */
  136.   union cpu_regs   in_regs;     /* Structure to hand to DevHlp caller       */
  137.   union cpu_regs   out_regs;    /* Another one for return values            */
  138.   unsigned        *intermd_ptr; /* Pointer to the Global Info Seg selector  */
  139.  
  140.   /* do a GetDOSVar - Global Info Segment - Get a pointer to the selector */
  141.   in_regs.W.AX = 1;
  142.   in_regs.W.DX = devhlp_GetDOSVar;
  143.   in_regs.W.es_valid = FALSE;
  144.   in_regs.W.ds_valid = FALSE;
  145.   dev_help(&in_regs,&out_regs);
  146.  
  147.   /* AX:BX points to the selector of the Global Info Segment */
  148.   pointer._2words.high = out_regs.W.AX;
  149.   pointer._2words.low = out_regs.W.BX;
  150.   intermd_ptr = (unsigned *)pointer.fptr;
  151.  
  152.   /* Make a pointer to the Global Info Segment from that selector :0 */
  153.   pointer._2words.high = *intermd_ptr;
  154.   pointer._2words.low = 0;
  155.   g_info = (struct global_info_seg *)pointer.fptr;
  156.  
  157. }
  158.  
  159. unsigned long far curr_time()
  160. {
  161.  
  162.   /* Get the time and return it */
  163.   return(g_info->time_stuff.msec_since_IPL);
  164. }
  165.  
  166. void far yield()
  167. {
  168.   _32bits temp;
  169.   union cpu_regs in_regs;
  170.   union cpu_regs out_regs;
  171.  
  172.   enable_irpt();                     /* Let irpts through while we sleep     */
  173.   temp.phys = (physaddr)curr_time(); /* The block ID will be the current time*/
  174.   in_regs.W.BX = temp._2words.low;
  175.   in_regs.W.AX = temp._2words.high;
  176.   in_regs.W.DI = 0;                  /* Block for 32 mSec                    */
  177.   in_regs.W.CX = 32;
  178.   in_regs.B.DH = 0;                  /* It is interruptable                  */
  179.   in_regs.B.DL = devhlp_Block;
  180.   in_regs.W.es_valid = FALSE;        /* DS and ES are not used               */
  181.   in_regs.W.ds_valid = FALSE;
  182.   dev_help(&in_regs,&out_regs);      /* Do it                                */
  183.   return;
  184. }
  185.  
  186. void far block(block_id, timeout)
  187. unsigned long block_id;
  188. unsigned long timeout;
  189. {
  190.   _32bits temp;
  191.   union cpu_regs in_regs;
  192.   union cpu_regs out_regs;
  193.  
  194.   temp.phys = (physaddr)block_id;    /* Set the Block ID                     */
  195.   in_regs.W.BX = temp._2words.low;
  196.   in_regs.W.AX = temp._2words.high;
  197.   temp.phys = (physaddr)timeout;     /* Set the timeout                      */
  198.   in_regs.W.DI = temp._2words.high;
  199.   in_regs.W.CX = temp._2words.low;
  200.   in_regs.B.DH = 1;                  /* It ain't interruptable               */
  201.   in_regs.B.DL = devhlp_Block;
  202.   in_regs.W.es_valid = FALSE;        /* DS and ES are not used               */
  203.   in_regs.W.ds_valid = FALSE;
  204.   dev_help(&in_regs,&out_regs);      /* Do it                                */
  205.   return;
  206. }
  207.  
  208. void far unblock(block_id)
  209. unsigned long block_id;
  210. {
  211.   _32bits temp;
  212.   union cpu_regs in_regs;
  213.   union cpu_regs out_regs;
  214.  
  215.  
  216.   temp.phys = (physaddr)block_id;   /* Which one to unblock                 */
  217.   in_regs.W.BX = temp._2words.low;
  218.   in_regs.W.AX = temp._2words.high;
  219.   in_regs.B.DL = devhlp_Run;        /* Say we want to wake him up           */
  220.   in_regs.W.es_valid = FALSE;       /* DS and ES are not used               */
  221.   in_regs.W.ds_valid = FALSE;
  222.   dev_help(&in_regs,&out_regs);     /* Wake it                              */
  223.   return;
  224. }
  225.  
  226. void far internal_error(msg_num)
  227. word msg_num;
  228. {
  229.   _32bits temp;
  230.   union cpu_regs in_regs;
  231.   union cpu_regs out_regs;
  232.  
  233.   temp.fptr = (void far *)err_msgs[msg_num];  /* Point at the message        */
  234.   in_regs.W.SI = temp._2words.low;
  235.   in_regs.W.DS = temp._2words.high;
  236.   in_regs.W.DI = strlen(err_msgs[msg_num]);   /* Tell how big it is          */
  237.   in_regs.B.DL = devhlp_InternalError;
  238.   in_regs.W.es_valid = FALSE;                 /* DS is used, ES isn't        */
  239.   in_regs.W.ds_valid = TRUE;
  240.   dev_help(&in_regs,&out_regs);               /* Do it                       */
  241. }
  242.  
  243. void far EOI(irpt_num)
  244. word irpt_num;
  245. {
  246.   union cpu_regs in_regs;
  247.   union cpu_regs out_regs;
  248.  
  249.   in_regs.B.AL = (byte)irpt_num;  /* Which IRQ to end                     */
  250.   in_regs.B.DL = devhlp_EOI;
  251.   in_regs.W.es_valid = FALSE;     /* DS and ES are not needed             */
  252.   in_regs.W.ds_valid = FALSE;
  253.   dev_help(&in_regs,&out_regs);
  254.  
  255. }
  256.  
  257. void far push_req_pkt(queue,req)
  258. _32bits *queue;
  259. reqhdr_type *req;
  260. {
  261.   _32bits temp;
  262.   union cpu_regs in_regs;
  263.   union cpu_regs out_regs;
  264.  
  265.   temp.fptr = (void far *)queue;        /* Point at the queue               */
  266.   in_regs.W.SI = temp._segadr.offset;
  267.   temp.fptr = (void far *)req;          /* Point at the Request packet      */
  268.   in_regs.W.ES = temp._segadr.segment;
  269.   in_regs.W.BX = temp._segadr.offset;
  270.   in_regs.B.DL = devhlp_PushReqPacket;
  271.   in_regs.W.es_valid = TRUE;            /* ES is used, DS isn't             */
  272.   in_regs.W.ds_valid = FALSE;
  273.   dev_help(&in_regs,&out_regs);         /* Do it                            */
  274.  
  275. }
  276.  
  277. void far pull_part_req_pkt(queue,req)
  278. _32bits *queue;
  279. reqhdr_type *req;
  280. {
  281.   _32bits temp;
  282.   union cpu_regs in_regs;
  283.   union cpu_regs out_regs;
  284.  
  285.   temp.fptr = (void far *)queue;        /* Point at the queue               */
  286.   in_regs.W.SI = temp._segadr.offset;
  287.   temp.fptr = (void far *)req;          /* Point at the request packet      */
  288.   in_regs.W.ES = temp._segadr.segment;
  289.   in_regs.W.BX = temp._segadr.offset;
  290.   in_regs.B.DL = devhlp_PullParticular;
  291.   in_regs.W.es_valid = TRUE;            /* ES is used, DS isn't             */
  292.   in_regs.W.ds_valid = FALSE;
  293.   dev_help(&in_regs,&out_regs);         /* Do it                            */
  294.  
  295. }
  296.  
  297. void far dev_done(req,status)
  298. reqhdr_type *req;
  299. word status;
  300. {
  301.   union cpu_regs in_regs,out_regs;
  302.   _32bits pointer;
  303.  
  304.   /* Set the status field in the request packet to the requested value */
  305.   req->rh_stat = status;
  306.  
  307.   pointer.phys = (physaddr)req;
  308.   in_regs.W.BX = pointer._segadr.offset;   /* BX = offset of request packet  */
  309.   in_regs.W.ES = pointer._segadr.segment;  /* ES = segment of request packet */
  310.   in_regs.B.DL = devhlp_DevDone;           /* DL = Dev_done command          */
  311.   in_regs.W.es_valid = TRUE;               /* ES has a valid selector        */
  312.   in_regs.W.ds_valid = FALSE;              /* DS is not a valid selector     */
  313.   dev_help(&in_regs,&out_regs);            /* Do it!                         */
  314.   return;                                  /* We don't care what the return  */
  315.                                            /*    code is because DevHlp does */
  316.                                            /*    not return anything but OK  */
  317. }
  318.  
  319.