home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / C / SASC6571.LZX / examples / example_device / serial.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-24  |  4.8 KB  |  180 lines

  1. /* Example device that implements the CMD_READ and CMD_WRITE */
  2. /* commands. This device will only run under AmigaDOS 2.0 or */
  3. /* greater because of the use of CreateNewProc().            */
  4.  
  5. #define  _USEOLDEXEC_ 1
  6. #include <exec/types.h>
  7. #include <exec/nodes.h>
  8. #include <exec/memory.h>
  9. #include <exec/resident.h>
  10. #include <exec/libraries.h>
  11. #include <exec/execbase.h>
  12. #include <exec/io.h>
  13. #include <exec/errors.h>
  14. #include <libraries/dos.h>
  15. #include <devices/serial.h>
  16. #include <dos/dostags.h>
  17. #include <utility/tagitem.h>
  18. #include <proto/exec.h>
  19. #include <proto/dos.h>
  20.  
  21. #include <string.h>
  22. #include <dos.h>
  23.  
  24. #define CMD_TERM     0x7ff0
  25. #define CMD_STARTUP  0x7ff1
  26.  
  27. struct MsgPort *myPort;
  28. extern struct ExecBase *SysBase;
  29.  
  30. struct START_MSG {
  31.         struct Message msg;
  32.         long devbase;
  33. };
  34.  
  35. void cmd_handler(void)
  36. {
  37.     struct IORequest *ior;
  38.     struct IOExtSer *ioes;
  39.     long input, output;
  40.     struct Process *proc;   
  41.     struct START_MSG *msg;
  42.  
  43.     proc = (struct Process *)FindTask((char *)NULL);
  44.  
  45.     /* get the startup message */
  46.     while((msg = (struct START_MSG *)GetMsg(&proc->pr_MsgPort)) == NULL) 
  47.         WaitPort(&proc->pr_MsgPort);
  48.     
  49.     /* builtin compiler functions to set A4 to the global */
  50.     /* data area */
  51.     putreg(REG_A6, msg->devbase); 
  52.     geta4();
  53.     myPort = CreatePort(0,0);
  54.     ReplyMsg((struct Message *)msg);
  55.  
  56.     if (myPort == NULL) return;
  57.  
  58.     input = Open("con:0/0/400/100/Input", MODE_NEWFILE);
  59.     if (input == NULL) return;
  60.     output = Open("con:0/110/400/100/Output", MODE_NEWFILE);
  61.     if (output == NULL)
  62.     {
  63.         Close(input);
  64.         return;
  65.     }
  66.     
  67.     while (1) 
  68.     {
  69.         WaitPort(myPort);
  70.         while (ior = (struct IORequest *)GetMsg(myPort)) 
  71.         {
  72.         switch(ior->io_Command) 
  73.             {
  74.                 case CMD_TERM:
  75.                     Close(input);
  76.                     Close(output);
  77.                     Forbid();
  78.                     ReplyMsg(&ior->io_Message);
  79.                     return;
  80.                     
  81.                 case CMD_READ:
  82.                     ioes = (struct IOExtSer *)ior;
  83.                     ioes->IOSer.io_Actual = Read(input, 
  84.                                            ioes->IOSer.io_Data, 
  85.                                            ioes->IOSer.io_Length);
  86.                     break;
  87.                     
  88.                 case CMD_WRITE:
  89.                      Write(output, ioes->IOSer.io_Data, 
  90.                            ioes->IOSer.io_Length);
  91.                      break;
  92.             }
  93.             ReplyMsg(&ior->io_Message);
  94.         }
  95.     }
  96. }
  97.  
  98.  
  99. int  __saveds __asm __UserDevInit(register __d0 long unit,
  100.                                   register __a0 struct IORequest *ior,
  101.                                   register __a6 struct MyLibrary *libbase)
  102. {
  103.       struct Process *myProc;
  104.       struct START_MSG msg;
  105.       
  106.       if (SysBase->LibNode.lib_Version < 36)
  107.           return 1; /* can only run under 2.0 or greater */ 
  108.       
  109.       myProc = CreateNewProcTags(NP_Entry, cmd_handler,
  110.                                  NP_StackSize, 4096,
  111.                                  NP_Name, "CMD_Handler",
  112.                                  TAG_DONE);
  113.       if (myProc == NULL) 
  114.         return 1;
  115.  
  116.       /* Send the startup message with the library base pointer */
  117.       msg.msg.mn_Length = sizeof(struct START_MSG) - 
  118.                           sizeof (struct Message);
  119.       msg.msg.mn_ReplyPort = CreatePort(0,0);
  120.       msg.msg.mn_Node.ln_Type = NT_MESSAGE;
  121.       msg.devbase = getreg(REG_A6);
  122.       PutMsg(&myProc->pr_MsgPort, (struct Message *)&msg);
  123.       WaitPort(msg.msg.mn_ReplyPort);
  124.  
  125.       if (myPort == NULL) /* CMD_Handler allocates this */
  126.         return NULL;
  127.       
  128.       DeletePort(msg.msg.mn_ReplyPort);
  129.       
  130.       return 0;
  131. }
  132.  
  133.  
  134. void __saveds __asm __UserDevCleanup(register __a0 struct IORequest *ior,
  135.                                      register __a6 struct MyLibrary *libbase)
  136. {
  137.     struct IORequest newior;    
  138.         
  139.     /* send a message to the child process to shut down. */
  140.     newior.io_Message.mn_ReplyPort = CreateMsgPort();
  141.     newior.io_Command = CMD_TERM;
  142.     newior.io_Unit = ior->io_Unit;
  143.  
  144.     PutMsg(myPort, &newior.io_Message);
  145.     WaitPort(newior.io_Message.mn_ReplyPort);
  146.     DeleteMsgPort(newior.io_Message.mn_ReplyPort);
  147.     DeletePort(myPort);
  148. }
  149.  
  150.  
  151. void __saveds __asm DevBeginIO(register __a1 struct IORequest *ior)
  152. {
  153.     ior->io_Error = 0;
  154.  
  155.     ior->io_Flags &= ~IOF_QUICK;
  156.     switch(ior->io_Command) 
  157.     {
  158.         case CMD_READ:
  159.         case CMD_WRITE:
  160.           PutMsg(myPort, &ior->io_Message);
  161.           break;
  162.  
  163.         case CMD_RESET:
  164.         case CMD_UPDATE:
  165.         case CMD_CLEAR:
  166.         case CMD_STOP:
  167.         case CMD_START:
  168.         case CMD_FLUSH:
  169.         case CMD_INVALID:
  170.         default:
  171.             ior->io_Error = IOERR_NOCMD;
  172.          ReplyMsg(&ior->io_Message);
  173.            break;
  174.     }
  175. }
  176.  
  177. void __saveds __asm DevAbortIO(register __a1 struct IORequest *ior)
  178. {
  179. }
  180.