home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 9 / FreshFishVol9-CD2.bin / bbs / gnu / libnix-0.8-src.lha / libnix-0.8 / sources / startup / devinit.c next >
Encoding:
C/C++ Source or Header  |  1994-12-12  |  10.6 KB  |  320 lines

  1. /******************************************************************************/
  2. /*                                                                            */
  3. /* this works with gcc too and makes life easier                              */
  4. /*                                                                            */
  5. /******************************************************************************/
  6.  
  7. #define __USE_SYSBASE
  8.  
  9. /******************************************************************************/
  10. /*                                                                            */
  11. /* includes                                                                   */
  12. /*                                                                            */
  13. /******************************************************************************/
  14.  
  15. #include <exec/types.h>
  16. #include <exec/resident.h>
  17. #include <proto/exec.h>
  18. #include "libinit.h"
  19. #include "stabs.h"
  20.  
  21. /******************************************************************************/
  22. /*                                                                            */
  23. /* *** FIRST *** function - prevents a crash when called from CLI!            */
  24. /*                                                                            */
  25. /******************************************************************************/
  26.  
  27. int safefail()
  28. {
  29.   return -1;
  30. }
  31.  
  32. /******************************************************************************/
  33. /*                                                                            */
  34. /* defines                                                                    */
  35. /*                                                                            */
  36. /******************************************************************************/
  37.  
  38. #define SETA4(x) asm volatile ("movel a4,sp@-; movel %0,a4" :/* */: "g" (x))
  39. #define RESA4(x) asm volatile ("movel sp@+,a4;")
  40.  
  41. /******************************************************************************/
  42. /*                                                                            */
  43. /* imports                                                                    */
  44. /*                                                                            */
  45. /******************************************************************************/
  46.  
  47. extern const UWORD DevVersion;
  48. extern const UWORD DevRevision;
  49.  
  50. extern const BYTE DevName[];
  51. extern const BYTE DevIdString[];
  52.  
  53. extern APTR  __FuncTable__[];
  54.  
  55. extern int   __UserDevInit(_DEV *);
  56. extern VOID  __UserDevCleanUp();
  57. extern int   __UserDevOpen(struct IORequest *,ULONG,ULONG);
  58. extern VOID  __UserDevClose();
  59.  
  60. /******************************************************************************/
  61. /*                                                                            */
  62. /* resident structure                                                         */
  63. /*                                                                            */
  64. /******************************************************************************/
  65.  
  66. const APTR InitTab[4];
  67.  
  68. static const struct Resident RomTag = {
  69.   RTC_MATCHWORD,
  70.   (struct Resident *)&RomTag,
  71.   (APTR)((&RomTag)+1),
  72.   RTF_AUTOINIT,
  73.   0,
  74.   NT_DEVICE,
  75.   0,
  76.   (BYTE *)DevName,
  77.   (BYTE *)DevIdString,
  78.   (APTR)&InitTab
  79. };
  80.  
  81. /******************************************************************************/
  82. /*                                                                            */
  83. /* autoinit table for use with initial MakeLibrary()                          */
  84. /*                                                                            */
  85. /******************************************************************************/
  86.  
  87. const APTR InitTab[4] = {
  88.   (APTR)sizeof(_DEV),
  89.   (APTR)&__FuncTable__[1],
  90.   0,
  91.   (APTR)DevInit
  92. };
  93.  
  94. /******************************************************************************/
  95. /*                                                                            */
  96. /* support function(s) to be inlined                                          */
  97. /*                                                                            */
  98. /******************************************************************************/
  99.  
  100. static inline APTR __GetDataSeg()
  101. {
  102.   APTR res;
  103.   asm ("lea ___a4_init,%0" : "=a" (res));
  104.   return res;
  105. }
  106.  
  107. static inline ULONG __BSize()
  108. {
  109.   ULONG res;
  110.   asm ("movel #___bss_size,%0" : "=d" (res));
  111.   return res;
  112. }
  113.  
  114. static inline ULONG *__GetBssStart()
  115. {
  116.   ULONG *res;
  117.   asm ("lea __edata,%0" : "=a" (res));
  118.   return res;
  119. }
  120.  
  121. /******************************************************************************/
  122. /*                                                                            */
  123. /* initialization function called by MakeLibrary()                            */
  124. /*                                                                            */
  125. /******************************************************************************/
  126.  
  127. struct Library *DevInit()
  128. {
  129.   register APTR SegList asm("a0");
  130.   register struct Library *dev asm("d0");
  131.   _DEV *Device = (_DEV *)dev;
  132.   ULONG size,result;
  133.  
  134.   /* init library base */
  135.  
  136.   Device->DevNode.lib_Node.ln_Type = NT_DEVICE;
  137.   Device->DevNode.lib_Node.ln_Name = (UBYTE *)DevName;
  138.   Device->DevNode.lib_Flags        = LIBF_CHANGED | LIBF_SUMUSED;
  139.   Device->DevNode.lib_Version      = (UWORD)DevVersion;
  140.   Device->DevNode.lib_Revision     = (UWORD)DevRevision;
  141.   Device->DevNode.lib_IdString     = (UBYTE *)DevIdString;
  142.   Device->SegList                  = SegList;
  143.   Device->DataSeg                  = __GetDataSeg();
  144.  
  145.   /* clear the bss part */
  146.  
  147.   if ((size=__BSize()))
  148.   {
  149.     ULONG *p=__GetBssStart();
  150.  
  151.     do
  152.     {
  153.       *p++=0;
  154.     }
  155.     while((size-=sizeof(ULONG)));
  156.   }
  157.  
  158.   /* now call user-init */
  159.  
  160.   SETA4(Device->DataSeg);
  161.   result=__UserDevInit(Device);
  162.   RESA4(0);
  163.  
  164.   /* all ok? */
  165.  
  166.   if (result!=0)
  167.     Device=NULL;
  168.  
  169.   /* this will be added to SysBase->DevList or NULL (init error) */
  170.  
  171.   return (struct Library *)Device;
  172. }
  173.  
  174. /******************************************************************************/
  175. /*                                                                            */
  176. /* DevOpen() will be called for every OpenDevice()                            */
  177. /*                                                                            */
  178. /* !!! CAUTION: This function runs in a forbidden state !!!                   */
  179. /*                                                                            */
  180. /******************************************************************************/
  181.  
  182. VOID DevOpen()
  183. {
  184.   register struct Library *dev asm("a6");
  185.   register struct IORequest *iorq asm("a1");
  186.   register ULONG flags asm("d1");
  187.   register ULONG unit asm("d0");
  188.   int result;
  189.  
  190.   /* any memory allocation can cause a call of THIS device expunge vector.
  191.      if OpenCnt is zero the library might go away ... So fake a user :-) */
  192.  
  193.   dev->lib_OpenCnt++;
  194.  
  195.   /* call user-open */
  196.  
  197.   SETA4(((_DEV *)dev)->DataSeg);
  198.   result=__UserDevOpen(iorq,unit,flags);
  199.   RESA4(0);
  200.  
  201.   if (result==0)
  202.   {
  203.     /* clear delayed expunge flag */
  204.  
  205.     dev->lib_Flags &= ~LIBF_DELEXP;
  206.  
  207.     /* one new user */
  208.  
  209.     dev->lib_OpenCnt++;
  210.   }
  211.  
  212.   /* end of expunge protection */
  213.  
  214.   --dev->lib_OpenCnt;
  215.  
  216.   /* exec returns io_error later */
  217. }
  218.  
  219. /******************************************************************************/
  220. /*                                                                            */
  221. /* DevClose() will be called for every CloseDevice()                          */
  222. /*                                                                            */
  223. /* !!! CAUTION: This function runs in a forbidden state !!!                   */
  224. /*                                                                            */
  225. /******************************************************************************/
  226.  
  227. APTR DevClose()
  228. {
  229.   register struct Library *dev asm("a6");
  230.   register struct IORequest *iorq asm("a1");
  231.   APTR SegList=0;
  232.  
  233.   SETA4(((_DEV *)dev)->DataSeg);
  234.   __UserDevClose(iorq);
  235.   RESA4(0);
  236.  
  237.   /* one less user */
  238.  
  239.   if (--dev->lib_OpenCnt==0 && (dev->lib_Flags&LIBF_DELEXP))
  240.     SegList=DevExpunge();
  241.  
  242.   /* SegList or NULL (still in use) */
  243.  
  244.   return SegList;
  245. }
  246.  
  247. /******************************************************************************/
  248. /*                                                                            */
  249. /* remove device from memory if possible                                      */
  250. /*                                                                            */
  251. /* !!! CAUTION: This function runs in a forbidden state !!!                   */
  252. /*                                                                            */
  253. /******************************************************************************/
  254.  
  255. APTR DevExpunge()
  256. {
  257.   register struct Library *dev asm("a6");
  258.   _DEV *Device = (_DEV *)dev;
  259.   APTR SegList=0;
  260.  
  261.   /* set delayed expunge flag */
  262.  
  263.   Device->DevNode.lib_Flags |= LIBF_DELEXP;
  264.  
  265.   /* still in use? */
  266.  
  267.   if (Device->DevNode.lib_OpenCnt == 0)
  268.   {
  269.     ULONG NegSize;
  270.  
  271.     /* return the seglist for UnLoadSeg() */
  272.  
  273.     SegList = Device->SegList;
  274.  
  275.     /* remove device from SysBase->DevList */
  276.  
  277.     Remove((struct Node *)Device);
  278.  
  279.     /* now call user-exit */
  280.  
  281.     SETA4(((_DEV *)dev)->DataSeg);
  282.     __UserDevCleanUp();
  283.     RESA4(0);
  284.  
  285.     /* free device */
  286.  
  287.     NegSize = Device->DevNode.lib_NegSize;
  288.     FreeMem((APTR)((UBYTE *)Device-(UBYTE *)NegSize),NegSize+Device->DevNode.lib_PosSize);
  289.   }
  290.   return SegList;
  291. }
  292.  
  293. /******************************************************************************/
  294. /*                                                                            */
  295. /* a do nothing stub (required!)                                              */
  296. /*                                                                            */
  297. /******************************************************************************/
  298.  
  299. APTR DevExtFunc()
  300. {
  301.   return 0;
  302. }
  303.  
  304. /******************************************************************************/
  305. /*                                                                            */
  306. /* add these functions to 'funclist'                                          */
  307. /*                                                                            */
  308. /******************************************************************************/
  309.  
  310. ADD2LIST(DevOpen,__FuncTable__,22);
  311. ADD2LIST(DevClose,__FuncTable__,22);
  312. ADD2LIST(DevExpunge,__FuncTable__,22);
  313. ADD2LIST(DevExtFunc,__FuncTable__,22);
  314.  
  315. /******************************************************************************/
  316. /*                                                                            */
  317. /* end of devinit.c                                                           */
  318. /*                                                                            */
  319. /******************************************************************************/
  320.