genmodule: Fix handler modules types' initialization
[AROS.git] / rom / filesys / pfs3 / fs / ks13wrapper.c
blob3d84139c61fcbcd086a3d1e5ffa2444bd3284cb9
2 #include <aros/debug.h>
3 #include <exec/types.h>
4 #include <exec/memory.h>
5 #include <proto/exec.h>
7 #include <string.h>
9 #include "ks13wrapper.h"
11 #ifdef KS13WRAPPER
13 #if KS13WRAPPER_DEBUG
15 #include <hardware/intbits.h>
17 #ifndef D
18 #define D(x) ;
19 #endif
21 #define SERDATR 0x18
22 #define SERDAT 0x30
23 #define INTREQ 0x9c
24 #define SERDATR_TBE (1 << 13) /* Tx Buffer Empty */
25 #define SERDAT_STP8 (1 << 8)
26 #define SERDAT_DB8(x) ((x) & 0xff)
28 #endif
30 /* Must use DOSBase, CDTV extended ROM 2.x includes v37 SysBase replacement */
31 #define ISKS20 (DOSBase->dl_lib.lib_Version >= 37)
33 #define MIN_STACKSIZE 8000
35 static struct DosLibrary *DOSBase = (APTR)-1;
36 static struct Library *IntuitionBase = (APTR)-1;
37 struct ExecBase *SysBase = (APTR)-1;
39 #define wrapper_init() do { \
40 DOSBase = (struct DosLibrary *)OpenLibrary ("dos.library", MIN_LIB_VERSION); \
41 IntuitionBase = OpenLibrary ("intuition.library", MIN_LIB_VERSION); \
42 if (!DOSBase || !IntuitionBase) \
43 Alert(AT_DeadEnd | AG_OpenLib); \
44 } while (0)
46 #define wrapper_free() do { \
47 CloseLibrary(DOSBase); \
48 CloseLibrary(IntuitionBase); \
49 } while (0)
51 AROS_UFP2(void, StackSwap,
52 AROS_UFPA(struct StackSwapStruct*, stack, A0),
53 AROS_UFPA(struct ExecBase*, SysBase, A6));
55 LONG wrapper_stackswap(LONG (*func)(struct ExecBase *), struct ExecBase *sysBase)
57 ULONG stacksize;
58 APTR stackptr;
59 struct Task *tc;
60 struct StackSwapStruct *stack;
61 LONG ret;
63 SysBase = sysBase;
65 wrapper_init();
66 tc = FindTask(NULL);
67 stacksize = (UBYTE *)tc->tc_SPUpper - (UBYTE *)tc->tc_SPLower;
68 if (stacksize >= MIN_STACKSIZE) {
69 ret = func(SysBase);
70 wrapper_free();
71 return ret;
74 stack = AllocMem(sizeof(struct StackSwapStruct) + MIN_STACKSIZE, MEMF_CLEAR | MEMF_PUBLIC);
75 if (!stack) {
76 wrapper_free();
77 Alert(AT_DeadEnd | AG_NoMemory);
78 return RETURN_FAIL;
80 stackptr = stack + 1;
81 stack->stk_Lower = stackptr;
82 stack->stk_Upper = (APTR)((IPTR)stack->stk_Lower + MIN_STACKSIZE);
83 stack->stk_Pointer = (APTR)stack->stk_Upper;
85 if (ISKS20) {
86 AROS_LVO_CALL1(void,
87 AROS_LCA(struct StackSwapStruct*, stack, A0),
88 struct ExecBase*, SysBase, 122, );
89 ret = func(SysBase);
90 AROS_LVO_CALL1(void,
91 AROS_LCA(struct StackSwapStruct*, stack, A0),
92 struct ExecBase*, SysBase, 122, );
93 } else {
94 AROS_UFC2(void, StackSwap,
95 AROS_UFCA(struct StackSwapStruct*, stack, A0),
96 AROS_UFCA(struct ExecBase*, SysBase, A6));
97 ret = func(SysBase);
98 AROS_UFC2(void, StackSwap,
99 AROS_UFCA(struct StackSwapStruct*, stack, A0),
100 AROS_UFCA(struct ExecBase*, SysBase, A6));
103 FreeMem(stack, sizeof(struct StackSwapStruct) + MIN_STACKSIZE);
104 wrapper_free();
106 return ret;
109 #if KS13WRAPPER_DEBUG
111 static inline void reg_w(ULONG reg, UWORD val)
113 volatile UWORD *r = (void *)(0xdff000 + reg);
115 *r = val;
117 static inline UWORD reg_r(ULONG reg)
119 volatile UWORD *r = (void *)(0xdff000 + reg);
121 return *r;
123 static void DebugPutChar(register int chr)
125 if (chr == '\n')
126 DebugPutChar('\r');
128 while ((reg_r(SERDATR) & SERDATR_TBE) == 0);
129 reg_w(INTREQ, INTF_TBE);
131 /* Output a char to the debug UART */
132 reg_w(SERDAT, SERDAT_STP8 | SERDAT_DB8(chr));
134 void DebugPutStr(register const char *buff)
136 for (; *buff != 0; buff++)
137 DebugPutChar(*buff);
139 void DebugPutDec(const char *what, ULONG val)
141 int i, num;
142 DebugPutStr(what);
143 DebugPutStr(": ");
144 if (val == 0) {
145 DebugPutChar('0');
146 DebugPutChar('\n');
147 return;
150 for (i = 1000000000; i > 0; i /= 10) {
151 if (val == 0) {
152 DebugPutChar('0');
153 continue;
156 num = val / i;
157 if (num == 0)
158 continue;
160 DebugPutChar("0123456789"[num]);
161 val -= num * i;
163 DebugPutChar('\n');
165 void DebugPutHex(const char *what, ULONG val)
167 int i;
168 DebugPutStr(what);
169 DebugPutStr(": ");
170 for (i = 0; i < 8; i ++) {
171 DebugPutChar("0123456789abcdef"[(val >> (28 - (i * 4))) & 0xf]);
173 DebugPutChar('\n');
175 void DebugPutHexVal(ULONG val)
177 int i;
178 for (i = 0; i < 8; i ++) {
179 DebugPutChar("0123456789abcdef"[(val >> (28 - (i * 4))) & 0xf]);
181 DebugPutChar(' ');
184 #endif
186 APTR AllocVec(ULONG size, ULONG flags)
188 ULONG *mem;
190 mem = AllocMem(size + sizeof(ULONG), flags);
191 if (!mem)
192 return NULL;
193 mem[0] = size;
194 mem++;
195 return mem;
197 void FreeVec(APTR mem)
199 ULONG *p = mem;
200 if (!p)
201 return;
202 p--;
203 FreeMem(p, p[0]);
206 APTR CreateIORequest(struct MsgPort *ioReplyPort, ULONG size)
208 struct IORequest *ret=NULL;
209 if(ioReplyPort==NULL)
210 return NULL;
211 ret=(struct IORequest *)AllocMem(size,MEMF_PUBLIC|MEMF_CLEAR);
212 if(ret!=NULL)
214 ret->io_Message.mn_ReplyPort=ioReplyPort;
215 ret->io_Message.mn_Length=size;
217 return ret;
220 void DeleteIORequest(APTR iorequest)
222 if(iorequest != NULL)
223 FreeMem(iorequest, ((struct Message *)iorequest)->mn_Length);
226 struct MsgPort *CreateMsgPort(void)
228 struct MsgPort *ret;
229 ret=(struct MsgPort *)AllocMem(sizeof(struct MsgPort),MEMF_PUBLIC|MEMF_CLEAR);
230 if(ret!=NULL)
232 BYTE sb;
233 sb=AllocSignal(-1);
234 if (sb != -1)
236 ret->mp_Flags = PA_SIGNAL;
237 ret->mp_Node.ln_Type = NT_MSGPORT;
238 NEWLIST(&ret->mp_MsgList);
239 ret->mp_SigBit=sb;
240 ret->mp_SigTask=SysBase->ThisTask;
241 return ret;
243 FreeMem(ret,sizeof(struct MsgPort));
245 return NULL;
248 void DeleteMsgPort(struct MsgPort *port)
250 if(port!=NULL)
252 FreeSignal(port->mp_SigBit);
253 FreeMem(port,sizeof(struct MsgPort));
257 BOOL MatchPatternNoCase(CONST_STRPTR pat, CONST_STRPTR str)
259 if (ISKS20)
260 return AROS_LVO_CALL2(BOOL,
261 AROS_LCA(CONST_STRPTR, pat, D1),
262 AROS_LCA(CONST_STRPTR, str, D2),
263 struct DosLibrary*, DOSBase, 162, );
264 /* Used by ACTION_EXAMINE_ALL which is 2.0+ only packet */
265 return FALSE;
268 STRPTR FilePart(CONST_STRPTR path)
270 if(path)
272 CONST_STRPTR i;
273 if (!*path)
274 return (STRPTR)path;
275 i = path + strlen (path) -1;
276 while ((*i != ':') && (*i != '/') && (i != path))
277 i--;
278 if ((*i == ':')) i++;
279 if ((*i == '/')) i++;
280 return (STRPTR)i;
282 return NULL;
285 STRPTR PathPart(CONST_STRPTR path)
287 const char *ptr;
289 while (*path == '/')
291 ++path;
293 ptr = path;
294 while (*ptr)
296 if (*ptr == '/')
298 path = ptr;
300 else if (*ptr == ':')
302 path = ptr + 1;
304 ptr++;
306 return (STRPTR)path;
309 static BOOL CMPBSTR(BSTR s1, BSTR s2)
311 UBYTE *ss1 = BADDR(s1);
312 UBYTE *ss2 = BADDR(s2);
313 return memcmp(ss1, ss2, ss1[0] + 1);
315 static struct DosList *getdoslist(struct ExecBase *SysBase)
317 struct DosInfo *di;
319 di = BADDR(DOSBase->dl_Root->rn_Info);
320 Forbid();
321 return (struct DosList *)&di->di_DevInfo;
323 static void freedoslist(struct ExecBase *SysBase)
325 Permit();
328 struct DosList *MakeDosEntry(CONST_STRPTR name, LONG type)
330 ULONG len;
331 STRPTR s2;
332 struct DosList *dl;
334 if (ISKS20)
335 return AROS_LVO_CALL2(struct DosList*,
336 AROS_LCA(CONST_STRPTR, name, D1),
337 AROS_LCA(LONG, type, D2),
338 struct DosLibrary*, DOSBase, 116, );
340 len = strlen(name);
341 dl = (struct DosList *)AllocVec(sizeof(struct DosList),
342 MEMF_PUBLIC | MEMF_CLEAR);
344 if (dl != NULL)
346 /* Binary compatibility for BCPL string.
347 * First byte is the length then comes the string.
348 * For ease of use a zero is put at the end so it can be used as a
349 * C string
351 s2 = (STRPTR)AllocVec(len+2, MEMF_PUBLIC | MEMF_CLEAR);
352 dl->dol_Name = MKBADDR(s2);
353 if (s2 != NULL)
354 *s2++ = (UBYTE)(len > 255 ? 255 : len);
355 if (s2 != NULL)
357 strcpy(s2, name);
358 dl->dol_Type = type;
359 return dl;
361 FreeVec(dl);
363 return NULL;
366 LONG RemDosEntry(struct DosList *dlist)
368 struct DosList *dl;
370 if (ISKS20)
371 return AROS_LVO_CALL1(LONG,
372 AROS_LCA(struct DosList*, dlist, D1),
373 struct DosLibrary*, DOSBase, 112, );
375 if(dlist == NULL)
376 return 0;
378 dl = getdoslist(SysBase);
380 while(TRUE)
382 struct DosList *dl2 = BADDR(dl->dol_Next);
384 if(dl2 == dlist)
386 dl->dol_Next = dlist->dol_Next;
387 break;
390 dl = dl2;
393 freedoslist(SysBase);
395 return 1;
398 void FreeDosEntry(struct DosList *dlist)
400 if (ISKS20) {
401 AROS_LVO_CALL1(void,
402 AROS_LCA(struct DosList*, dlist, D1),
403 struct DosLibrary*, DOSBase, 117, );
404 return;
406 if (dlist == NULL)
407 return;
408 FreeVec(BADDR(dlist->dol_Name));
409 FreeVec(dlist);
412 LONG AddDosEntry(struct DosList *dlist)
414 LONG success = DOSTRUE;
415 struct DosList *dl;
417 if (ISKS20)
418 return AROS_LVO_CALL1(LONG,
419 AROS_LCA(struct DosList*, dlist, D1),
420 struct DosLibrary*, DOSBase, 113, );
422 if (dlist == NULL)
423 return success;
425 D(bug("[AddDosEntry] Adding '%b' type %d from addr %x Task '%s'\n",
426 dlist->dol_Name, dlist->dol_Type, dlist,
427 FindTask(NULL)->tc_Node.ln_Name));
429 dl = getdoslist(SysBase);
431 if(dlist->dol_Type != DLT_VOLUME)
433 while(TRUE)
435 dl = BADDR(dl->dol_Next);
437 if(dl == NULL)
438 break;
440 if(dl->dol_Type != DLT_VOLUME && !CMPBSTR(dl->dol_Name, dlist->dol_Name))
442 D(bug("[AddDosEntry] Name clash for %08lx->dol_Name: %b and %08lx->dol_Name %b\n", dl, dl->dol_Name, dlist, dlist->dol_Name));
443 success = DOSFALSE;
444 break;
449 if(success)
451 struct DosInfo *dinf = BADDR(DOSBase->dl_Root->rn_Info);
453 dlist->dol_Next = dinf->di_DevInfo;
454 dinf->di_DevInfo = MKBADDR(dlist);
457 freedoslist(SysBase);
459 return success;
462 IPTR CallHookPkt(struct Hook *hook, APTR object, APTR paramPacket)
464 return CALLHOOKPKT(hook, object, paramPacket);
467 BOOL ErrorReport(LONG code, LONG type, IPTR arg1, struct MsgPort *device)
469 if (ISKS20)
470 return AROS_LVO_CALL4(BOOL,
471 AROS_LCA(LONG, code, D1),
472 AROS_LCA(LONG, type, D2),
473 AROS_LCA(IPTR, arg1, D3),
474 AROS_LCA(struct MsgPort*, device, D4),
475 struct DosLibrary*, DOSBase, 80, );
477 return FALSE;
480 LONG EasyRequestArgs(struct Window *window, struct EasyStruct *easyStruct, ULONG *IDCMP_ptr, APTR argList)
482 if (ISKS20)
483 return AROS_LVO_CALL4(LONG,
484 AROS_LCA(struct Window*, window, A0),
485 AROS_LCA(struct EasyStruct*, easyStruct, A1),
486 AROS_LCA(ULONG*, IDCMP_ptr, A2),
487 AROS_LCA(APTR, argList, A3),
488 APTR, IntuitionBase, 98, );
489 return 1;
492 struct Window *BuildEasyRequestArgs(struct Window *RefWindow, struct EasyStruct *easyStruct, ULONG IDCMP, APTR Args)
494 if (ISKS20)
495 return AROS_LVO_CALL4(struct Window*,
496 AROS_LCA(struct Window*, RefWindow, A0),
497 AROS_LCA(struct EasyStruct*, easyStruct, A1),
498 AROS_LCA(ULONG, IDCMP, D0),
499 AROS_LCA(APTR, Args, A3),
500 APTR, IntuitionBase, 99, );
501 return NULL;
504 LONG SysReqHandler(struct Window *window, ULONG *IDCMPFlagsPtr, BOOL WaitInput)
506 if (ISKS20)
507 return AROS_LVO_CALL3(LONG,
508 AROS_LCA(struct Window*, window, A0),
509 AROS_LCA(ULONG*, IDCMPFlagsPtr, A1),
510 AROS_LCA(BOOL, WaitInput, D0),
511 APTR, IntuitionBase, 100, );
512 return 0;
515 #endif
517 #include <exec/types.h>
518 #include <exec/memory.h>
519 #include <proto/exec.h>
521 #ifdef KS13COMPATIBLE
523 APTR AllocVec(ULONG size, ULONG flags)
525 APTR mem;
527 mem = AllocMem(size + sizeof(ULONG), flags);
528 if (!mem)
529 return NULL;
530 ((ULONG*)mem)[0] = size;
531 mem += sizeof(ULONG);
532 return mem;
534 void FreeVec(APTR mem)
536 if (!mem)
537 return;
538 mem -= sizeof(ULONG);
539 FreeMem(mem, ((ULONG*)mem)[0]);
542 APTR CreateIORequest(struct MsgPort *ioReplyPort, ULONG size)
544 struct IORequest *ret=NULL;
545 if(ioReplyPort==NULL)
546 return NULL;
547 ret=(struct IORequest *)AllocMem(size,MEMF_PUBLIC|MEMF_CLEAR);
548 if(ret!=NULL)
550 ret->io_Message.mn_ReplyPort=ioReplyPort;
551 ret->io_Message.mn_Length=size;
553 return ret;
556 void DeleteIORequest(APTR iorequest)
558 if(iorequest != NULL)
559 /* Just free the memory */
560 FreeMem(iorequest, ((struct Message *)iorequest)->mn_Length);
563 struct MsgPort *CreateMsgPort(void)
565 struct MsgPort *ret;
566 ret=(struct MsgPort *)AllocMem(sizeof(struct MsgPort),MEMF_PUBLIC|MEMF_CLEAR);
567 if(ret!=NULL)
569 BYTE sb;
570 sb=AllocSignal(-1);
571 if (sb != -1)
573 ret->mp_Flags = PA_SIGNAL;
574 ret->mp_Node.ln_Type = NT_MSGPORT;
575 NEWLIST(&ret->mp_MsgList);
576 ret->mp_SigBit=sb;
577 ret->mp_SigTask=SysBase->ThisTask;
578 return ret;
580 FreeMem(ret,sizeof(struct MsgPort));
582 return NULL;
585 void DeleteMsgPort(struct MsgPort *port)
587 if(port!=NULL)
589 FreeSignal(port->mp_SigBit);
590 FreeMem(port,sizeof(struct MsgPort));
594 #endif