home *** CD-ROM | disk | FTP | other *** search
/ Boston 2 / boston-2.iso / DOS / PROGRAM / C / XLIB / XLIB.MAN < prev   
Text File  |  1993-12-01  |  16KB  |  529 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.             
  8.             
  9.             
  10.             
  11.             
  12.             
  13.             
  14.             
  15.             
  16.             
  17.             
  18.             
  19.             
  20.             
  21.             
  22.             
  23.             
  24.             
  25.                       Communications and Multitasking Library
  26.                                   For Datalight C
  27.                                          by
  28.                                     Matt Brandt
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.             Overview
  74.             
  75.             This  library   contains  a   multitasking  kernel   and   a
  76.             communications kernel.  The communications kernel allows you
  77.             to control  the com ports of a PC in a simple way but allows
  78.             any  speed   the  com   port  is  capable  of  running.  The
  79.             communications routines are interrupt driven so that even in
  80.             very fast  transfers a  program will  not have  any  trouble
  81.             keeping up. The multitasking kernel allows a program to have
  82.             several apparently  simultaneous execution  threads. This is
  83.             especially  usefull   in  communications  because  there  is
  84.             usually traffic in both directions. A small terminal program
  85.             "mini.c" is  included in  this archive  to  demonstrate  the
  86.             concepts. While  you may  use  the  communications  routines
  87.             without worring  about the  multitasking I  urge you to take
  88.             the time  to understand  the multasking kernel. It will make
  89.             your life  much  easier  for  many  applications,  not  just
  90.             communications. In  the following  pages I  will discuss the
  91.             concepts of the communications and multitasking routines and
  92.             demonstrate how  each routine  is called.  The last  section
  93.             deals with  the example  program mini.c  and  shows  how  it
  94.             works.
  95.             
  96.             This package  is being distributed as shareware. You may try
  97.             it out,  see if  it is  what you want, and if it fits a need
  98.             you have  then I  ask that  you send me 20 dollars. For your
  99.             twenty dollars  you will  get the  complete source  code,  a
  100.             license to  use any  and all  of these  routines in your own
  101.             code for  profit without  any royalties, and the other three
  102.             models (P,D,  and L) of the library. If you do not need this
  103.             package and  do not  use it then you are under no obligation
  104.             to send  me any money. Please feel free to pass this archive
  105.             on in it's original form to friends and BBS's that you think
  106.             might be interested.
  107.             
  108.             If you want to send in a contribution send your check to:
  109.             
  110.                  Matt Brandt
  111.                  PO Box 920337
  112.                  Norcross, GA 30092
  113.             
  114.             Your comments and suggestions are also welcome.
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.             Multitasking Concepts
  140.             
  141.             This library  implements what  is  called  a  non-preemptive
  142.             scheduler. This  means that when one task is running it will
  143.             not be  "preempted" by  a task of higher priority. A task is
  144.             only suspended when it makes one of two tasking calls. It is
  145.             up to  the programmer  to make  sure that  all tasks  get  a
  146.             chance to run. Each task has it's own stack area. The global
  147.             and static  data of  the program  is available to all tasks.
  148.             The task  scheduler does  not "hook"  any interrupts or take
  149.             over any  of the machine resources so any task can return to
  150.             DOS at any time. This will have the effect of killing all of
  151.             the other tasks.
  152.             
  153.             There can  be up  to 32  seperate tasks. The main program is
  154.             assigned task  number zero at program startup. The tasks are
  155.             prioritized by  task number with task zero being the highest
  156.             priority task  and task 31 being the lowest priority. You do
  157.             not  need   to  assign  task  numbers  sequentially.  It  is
  158.             perfectly acceptable  to have  only tasks  zero and  ten for
  159.             instance.  The   scheduler  will  perform  slightly  better,
  160.             however, when  there are  a minimum number of "holes" in the
  161.             task assignments.
  162.             
  163.             Tasks can  syncronize and communicate through signals. It is
  164.             also possible for interrupt service routines to send signals
  165.             to tasks.  There are  32 signals available [0..31]. Any task
  166.             can wait  for a signal. It will then be suspended until that
  167.             signal is sent by another task or an interrupt routine. If a
  168.             signal is  sent and  there is  nobody waiting for it then it
  169.             will be  saved until  the next  wait is performed. That wait
  170.             will not  suspend the  task but  instead  will  receive  the
  171.             signal that  was previously sent. Only one occurance of each
  172.             signal can  be saved.  Multiple unwaited occurrances are the
  173.             same as one unwaited occurrance. More that one task may wait
  174.             for a  given signal.  In  this  case  the  highest  priority
  175.             waiting task will be readied when the signal is sent.
  176.             
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.             The task calls are as follows:
  206.             
  207.             t_create(tasknum,func,stk,stksiz);
  208.             int       tasknum;
  209.             void      (*func)();
  210.             int       *stk;
  211.             int       stksiz;
  212.             
  213.                  This call  creates a task whose task number is given by
  214.                  tasknum. If  a task  is already  running at  that  task
  215.                  number it  is replaced  by the new task. func should be
  216.                  the address  of a  function to  be executed  as the new
  217.                  task. stk  should point to an area of memory and stksiz
  218.                  should be  the size  of the task's stack area in bytes.
  219.                  If a task function returns the task is deleted. The new
  220.                  task is placed in a ready to run state but is not given
  221.                  control until  scheduling occurs  by way of a t_wait or
  222.                  t_yield call. If the new task number is the same as the
  223.                  currently running  task then  this call  will  have  no
  224.                  effect.
  225.                  
  226.                  EXAMPLE:
  227.                  
  228.                       int  t1stk[512];
  229.                  
  230.                       task1()
  231.                       {
  232.                            ..code to do a job
  233.                       }
  234.                       
  235.                       .
  236.                       t_create(1,task1,t1stk,sizeof(t1stk));
  237.                  
  238.             t_kill(tasknum)
  239.             int  tasknum;
  240.             
  241.                  This call  will delete  the task  whose task  number is
  242.                  given by tasknum. If tasknum matches the task number of
  243.                  the currently  running task  the current  task will  be
  244.                  killed and rescheduling will occur.
  245.             
  246.             t_wait(signo)
  247.             int  signo;
  248.                  
  249.                  The task  issuing this  call  will  wait  until  signal
  250.                  number signo  is issued by another task or an interrupt
  251.                  service routine.  If the signal was already issued then
  252.                  the current  task will continue unhindered. When a task
  253.                  suspends  then  the  highest  priority  ready  task  is
  254.                  continued at the point where it left off.
  255.             
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.             t_signal(signo)
  272.             
  273.                  This call  causes an occurrance of signal number signo.
  274.                  The highest  priority task waiting for that signal will
  275.                  be made  ready. This  call will NOT cause scheduling to
  276.                  occur. That  must be  done  by  a  call  to  t_wait  or
  277.                  t_yield.
  278.             
  279.             t_yield()
  280.                  
  281.                  This call  will allow  any  higher  priority  tasks  to
  282.                  execute. If  the current  task is  the highest priority
  283.                  ready task  then it  will continue.  Note that  a yield
  284.                  from the  main program  (task zero) will always have no
  285.                  effect because it is always the highest priority task.
  286.             
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.             Communications overview
  338.             
  339.             The communications  module contains procedures to initialize
  340.             either (or  both) com  ports, send and receive characters on
  341.             the ports,  and set  the mode  and baud rates for the ports.
  342.             Each routine  is  shown  below  with  a  description.  These
  343.             routines use  the task scheduler to suspend tasks and signal
  344.             when new  input is available. Signals two thru five are used
  345.             by these routines. You may ignore the multitasking, however,
  346.             with no ill effects since the main task will be the only one
  347.             running.
  348.             
  349.             int  copen(portno,ibufsiz,obufsiz)
  350.             int  portno;
  351.             int  ibufsiz;
  352.             int  obufsiz;
  353.             
  354.                  Open a  com port  and return  a port handle. The portno
  355.                  should be  0 for  com1 and 1 for com2. This sets up the
  356.                  input and  output buffers  and  "hooks"  the  interrupt
  357.                  vector used  to service  the port. ibufsiz is the input
  358.                  buffer size  in bytes  and obufsiz is the output buffer
  359.                  size in  bytes.  Note  that  the  input  buffer  should
  360.                  normally be much larger than then output buffer.
  361.             
  362.             cbaud(phand,br)
  363.             int  phand;
  364.             int  br;
  365.                  
  366.                  This routine  will set  the port  described by phand to
  367.                  the specified baud rate. Note that any baud rate can be
  368.                  used, not  just the normal ones. The maximum allowed by
  369.                  the port  is about 50K. Normally, of course, you should
  370.                  stick to the standard baud rates for compatability with
  371.                  other programs.
  372.             
  373.             cmode(phand,par,bits,stopb)
  374.             int  phand, par, bits, stopb;
  375.             
  376.                  This sets  the mode  of a  port. parity is described by
  377.                  the par  argument and can be one of ['n','e','o']. bits
  378.                  describes the  number of  bits in each byte transmitted
  379.                  (either 7  or 8)  and stopb  tells how  many stop  bits
  380.                  (either 1 or 2).
  381.             
  382.             cclose(phand)
  383.             int  phand;
  384.             
  385.                  This  routine  turns  the  port  off  and  unhooks  the
  386.                  interrupt vector.  It is  important to  do this  before
  387.                  exiting your  program so that a spurious interrupt does
  388.                  not occur.
  389.             
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.             cputc(phand,c)
  404.             int  phand, c;
  405.             
  406.                  outputs a  character to the port described by phand. If
  407.                  the output  buffer is  full then  the task  making this
  408.                  call will  be suspended  until there  is room  for  the
  409.                  character.
  410.             
  411.             int  cgetc(phand)
  412.             int  phand;
  413.             
  414.                  reads a  character from the port described by phand. If
  415.                  there are  no characters available then the task making
  416.                  this  call   will  be   suspended  until   one  becomes
  417.                  available.
  418.             
  419.             int  cpoll(phand)
  420.                  
  421.                  returns the number of characters available in the input
  422.                  buffer for  the port  described by  phand. You  can use
  423.                  this to  keep from  waiting for input if you don't want
  424.                  to use the multitasking facility.
  425.             
  426.  
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.             MiniTerminal program discussion
  470.             
  471.             The file  "mini.c" contains  an example  of the  use of this
  472.             library to  do a  standard job  in an  elegant way. The main
  473.             program of  mini opens  com1 and sets the port to 1200 baud.
  474.             It then  intercepts the keyboard interrupt and creates a new
  475.             task (task1)  and starts  an infinite loop. The main program
  476.             then becomes  a receiver  task which  just gets  a character
  477.             from the port and puts it on the screen. Meanwhile, task1 is
  478.             getting a  character from  the keyboard, checking whether or
  479.             not it  is the  key designated to terminate the program (F1)
  480.             and if  not sending  the character  out the  com port.  When
  481.             task1 tries  to get  a character  from the keyboard it first
  482.             checks to  see if  there is a character available, if not it
  483.             waits for  signal zero  which is sent by kbsvc when the next
  484.             keyboard interrupt  happens. Likewise,  when the  main  task
  485.             tries to get a character from the port it will wait till one
  486.             is available.  The multitasking  makes  the  program  a  lot
  487.             easier to follow.
  488.             
  489.             But wait,  you say!  I could  do the  same thing  without  a
  490.             multitasking kernel  and all  of that  bruhaha. In that case
  491.             you would check to see if a key was available, if so process
  492.             it, then  check to see if a com character was available, and
  493.             if so  process it,  in a  single loop. That works out ok for
  494.             the simple case but think of what you would have to do to do
  495.             the job  of the  routine escseq  which interprets  incomming
  496.             ansi escape  sequences. Remember,  you don't want to hold up
  497.             keyboard input while all the rest of the characters come in!
  498.             At 300  baud that would be a noticable delay. You would have
  499.             to keep track of what had been received already in an escape
  500.             sequence and  what the  current state  was. The  multitasker
  501.             takes a lot of the bother out of the job. You can just write
  502.             the receiver  routine as  though no  keyboard work had to be
  503.             done at all.
  504.             
  505.             To compile and link mini.c do the following command:
  506.             
  507.                  dlc mini.c xlib.lib
  508.             
  509.             Well, that  about wraps  it up.  Remember, for  just  twenty
  510.             bucks you  get the source code, all four memory models (this
  511.             is just  the small  model) and  an unlimited  license to use
  512.             this nifty  library in  your own  programs. Sorry,  no ginsu
  513.             knives.
  514.             
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.