home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_10_03 / 1003044a < prev    next >
Text File  |  1991-10-07  |  9KB  |  311 lines

  1. /* -----------------------------------------------------
  2.  *  LISTING 2
  3.  *
  4.  *  Filename:           exec.c
  5.  *  Summary:            execute driver command
  6.  *  Author:             T.W. Nelson
  7.  *  Compile options:    
  8.  *  Version:            1.00
  9.  *  Date:               05-Oct-1991
  10.  *  Notes:
  11.  *
  12.  *  Source code Copyright (c) 1991 T.W. Nelson.
  13.  *  May be used only with appropriate
  14.  *  acknowledgement of copyright.
  15.  * -------------------------------------------------- */
  16.  
  17. #include <dos.h>
  18. #include "driver.h"
  19.  
  20. extern unsigned init(void), media_check(void),
  21.        build_bpb(void), ioctl_read(void),
  22.        device_read(void), nd_read(void),
  23.        input_status(void), input_flush(void),
  24.        device_write(void), verify_write(void),
  25.        output_status(void), output_flush(void),
  26.        ioctl_write(void), device_open(void),
  27.        device_close(void), rem_media(void),
  28.        output_busy(void), generic_ioctl(void),
  29.        get_logdev(void), set_logdev(void),
  30.        bad_command(void);
  31.  
  32. static unsigned (*Dispatch[])(void) = {
  33.     init,           //0 = initialize driver
  34.     media_check,    //1
  35.     build_bpb,      //2 = build BIOS param block
  36.     ioctl_read,     //3 = read io control data
  37.     device_read,    //4
  38.     nd_read,        //5 = non-destructive read
  39.     input_status,   //6
  40.     input_flush,    //7 = flush input buffers
  41.     device_write,   //8
  42.     verify_write,   //9 = write with verify
  43.     output_status,  //10
  44.     output_flush,   //11 = flush output buffers
  45.     ioctl_write,    //12 = write io control data
  46.     device_open,    //13  (DOS 3+)
  47.     device_close,   //14  (DOS 3+)
  48.     rem_media,      //15 = removable media (3+)
  49.     output_busy,    //16 = output until busy (3+)
  50.     bad_command,    //17 = not used
  51.     bad_command,    //18 = not used
  52.     generic_ioctl,  //19 = generic io control (3.2+)
  53.     bad_command,    //20 = not used
  54.     bad_command,    //21 = not used
  55.     bad_command,    //22 = not used
  56.     get_logdev,     //23 = get logical device (3.2+)
  57.     set_logdev,     //24 = set logical device (3.2+)
  58.     };
  59.  
  60. #define NUM_CMDS (sizeof(Dispatch)/sizeof(void *))
  61.  
  62. REQHDR far *Rh = (REQHDR far *) 0;
  63. unsigned int errno = 0;     //for std library code
  64. extern unsigned tape_io(unsigned ofs, unsigned seg);
  65.  
  66. static char signon[] =
  67.         "Demo TAPE device driver, V1.00\r\n\n";
  68.  
  69. void    exec_command( REQHDR far *rhdr )
  70. {
  71.    /* Call the command-code routine from the dispatch
  72.     * table indexed by the command code.  Access to
  73.     * caller's request header is made available thru
  74.     * global pointer 'Rh'.  'DONE' bit is always set
  75.     * on exit.
  76.     */
  77.  
  78.     Rh = rhdr;      //assign to global copy
  79.     Rh->status = 0;     //clear status word
  80.  
  81.     Rh->status = ( (Rh->cmd >= NUM_CMDS) ?
  82.                            bad_command() :
  83.                            (*Dispatch[ Rh->cmd ])() );
  84.     Rh->status |= IM_DONE;      //set 'done' bit
  85. }
  86.  
  87. /* ----------------------------------------------------
  88.  * Command-code routines. Called indirectly by the
  89.  * interrupt routine thru the dispatch table. All
  90.  * routines should return the appropriate status code
  91.  * to be assigned to the request header on return to
  92.  * exec_command().  Return will be 0 if no error,
  93.  * or (IS_ERROR + error_code) (see driver.h) if an
  94.  * error was detected.
  95.  * ------------------------------------------------- */
  96.  
  97. unsigned init( void )            /* 0    */
  98. {
  99.    /* Driver initialization function. Called once
  100.     * by DOS on boot up when CONFIG.SYS is read.
  101.     * Only DOS functions 01h-0Ch and 30h can be called
  102.     * here.
  103.     */
  104.  
  105.     extern char _TheEnd;  //marks end of driver
  106.     void putstr( const char *str );   //below
  107.  
  108.     putstr( signon);
  109.  
  110.    /* Other initialization code goes here ......
  111.     * If needed, a pointer to the command line after
  112.     * 'DEVICE=' in CONFIG.SYS is available starting
  113.     * at Rh->xfer_cnt (or, Rh + 18).
  114.     */
  115.  
  116.     // Return break address to DOS .......
  117.     Rh->xfer_seg = FP_SEG( (void far *) &_TheEnd );
  118.     Rh->xfer_ofs = FP_OFF( (void far *) &_TheEnd );
  119.  
  120.     return 0;
  121. }
  122.  
  123. unsigned media_check( void )     /* 1    */
  124. {
  125.    /* Block devices only.  Function determines
  126.     * whether or not a floppy disk was changed,
  127.     * allowing DOS to bypass re-reading the FAT.
  128.     */
  129.     return 0;   }
  130.  
  131. unsigned build_bpb(void)         /* 2    */
  132. {
  133.    /* Block devices only. Builds a table of disk
  134.     * parameters when media_check() returns the
  135.     * disk-change code.
  136.     */
  137.     return 0;   }
  138.  
  139. unsigned ioctl_read(void)        /* 3    */
  140. {
  141.    /* Character and block devices. Allows device
  142.     * driver to pass data directly to application.
  143.     * Called by DOS int21h/44h subfunction 2. The
  144.     * IOCTL_RW bit (14) must be set in device block's
  145.     * attribute word.
  146.     */
  147.     return tape_io(Rh->xfer_ofs, Rh->xfer_seg);
  148. }
  149.  
  150. unsigned device_read(void)       /* 4    */
  151. {
  152.    /* Character and block devices.  Read data from
  153.     * the device into a specified buffer.  Returns
  154.     * #bytes or sectors transfered.
  155.     */
  156.     return 0;   }
  157.  
  158. unsigned nd_read(void)           /* 5    */
  159. {
  160.    /* Character devices only. Lets caller peek at
  161.     * next byte in device's buffer w/o removing it.
  162.     */
  163.     return 0;   }
  164.  
  165. unsigned input_status(void)      /* 6    */
  166. {
  167.    /* Character devices only.  Returns current input
  168.     * status for device.  Sets IM_BUSY bit if input
  169.     * request cannot proceed immediately (characters
  170.     * are waiting to be read from the input buffers).
  171.     */
  172.     return 0;   }
  173.  
  174. unsigned input_flush(void)       /* 7    */
  175. {
  176.    /* Character devices only.  Function discards any
  177.     * data pending in device's input buffers.
  178.     */
  179.     return 0;   }
  180.  
  181. unsigned device_write(void)      /* 8    */
  182. {
  183.    /* Character and block devices.  Writes data from
  184.     * the specified buffer to a device.  Returns #
  185.     * bytes or sectors written.
  186.     */
  187.     return 0;   }
  188.  
  189. unsigned verify_write(void)      /* 9    */
  190. {
  191.    /* Character and block devices.  Same as
  192.     * device_write(), but performs a read-after-
  193.     * write verification.
  194.     */
  195.     return 0;   }
  196.  
  197. unsigned output_status(void)     /* 10   */
  198. {
  199.    /* Character devices only.  Returns the current
  200.     * output status for the device.  Sets IM_BUSY bit
  201.     * if write request cannot proceed immediately.
  202.     */
  203.     return 0;   }
  204.  
  205. unsigned output_flush(void)      /* 11   */
  206. {
  207.    /* Character devices only. Function discards any
  208.     * data in output buffers and any pending output
  209.     * requests.
  210.     */
  211.     return 0;   }
  212.  
  213. unsigned ioctl_write(void)       /* 12   */
  214. {
  215.    /* Character and block devices. Allows application
  216.     * to pass control info directly to driver. Called
  217.     * by DOS int21h/44h subfunction 3.  The IOCTL_RW
  218.     * bit (14) must be set in device block's attribute
  219.     * word.
  220.     */
  221.     return tape_io(Rh->xfer_ofs, Rh->xfer_seg);
  222. }
  223.  
  224. unsigned device_open(void)       /* 13   */
  225. {
  226.    /* Character and block devices, DOS 3+.  Manages
  227.     * reference count of #open files for block devices,
  228.     * or device initialization for character devices.
  229.     * Called only if bit 11 (OCR_MEDIA) is set in
  230.     * attribute word in header block.
  231.     */
  232.     return 0;   }
  233.  
  234. unsigned device_close(void)      /* 14   */
  235. {
  236.    /* Character and block devices, DOS 3+. The
  237.     * opposite of command-code 13, device_open().
  238.     */
  239.     return 0;   }
  240.  
  241. unsigned rem_media(void)         /* 15   */
  242. {  /* Block devices only. Sets IM_BUSY if media is
  243.     * non-removable. Called only if bit 11
  244.     * (OCR_MEDIA) is set in attribute word in header
  245.     * block.
  246.     */
  247.     return 0;   }
  248.  
  249. unsigned output_busy(void)       /* 16   */
  250. {
  251.    /* Character devices only, DOS 3+.  Transfers data
  252.     * to a device from specified buffer until device
  253.     * signals busy.  Called only if attribute bit 13
  254.     * (OUTPUT_BUSY) is set.
  255.     */
  256.     return 0;   }
  257.  
  258. unsigned generic_ioctl(void)     /* 19   */
  259. {
  260.    /* Character and block devices, DOS 3.2+.  This
  261.     * function is generally the same as command-codes
  262.     * 3 and 12, with a different calling protocol. Bit
  263.     * 6 (GEN_IOCTL) must be set in attribute word.
  264.     */
  265.     return 0;   }
  266.  
  267. unsigned get_logdev(void)        /* 23   */
  268. {
  269.    /* Block devices only, DOS 3.2+. Function returns
  270.     * number of logical devices (drive letters)
  271.     * assigned to a physical device. Bit 6
  272.     * (GEN_IOCTL) must be set in attribute word.
  273.     */
  274.     return 0;   }
  275.  
  276. unsigned set_logdev(void)        /* 24   */
  277. {
  278.    /* Block devices only, DOS 3.2+. Function sets
  279.     * number of logical devices assigned to a
  280.     * physical device. Bit 6 (GEN_IOCTL) must be set
  281.     * in attribute word.
  282.     */
  283.     return 0;   }
  284.  
  285. unsigned bad_command( void )
  286. {
  287.     return IS_ERROR + INV_COMMAND;
  288. }
  289.  
  290. void putstr( const char *str )
  291. {
  292.    /* Utility function to output an asciiz-format
  293.     * string to monitor using BIOS-level output....
  294.     * Doesn't add an auto-CR; use '\r' in your
  295.     * string. Coding putstr() in C adds 200-300 more
  296.     * bytes (from int86()) to the TAPE.SYS image in
  297.     * memory, relative to an asm version.
  298.     */
  299.  
  300.     union REGS regs;
  301.  
  302.     while( *str )   {
  303.         regs.h.al = (char) *str++;
  304.         regs.h.ah = 0x0e;   //BIOS write TTY
  305.         regs.x.bx = 0;      //page 0
  306.         int86( 0x10, ®s, ®s );
  307.     }
  308. }
  309.  
  310. /* ----- End of File ------------------------------- */
  311.