revert between 56095 -> 55830 in arch
[AROS.git] / rom / filesys / pfs3 / fs / ks13wrapper.c
blobe2bcbff3acba93be52b98f03f7e4a976d9fd53ea
2 #include <aros/debug.h>
3 #include <exec/types.h>
4 #include <exec/memory.h>
5 #include <proto/exec.h>
7 #include <string.h>
8 #include <stdio.h>
10 #include "ks13wrapper.h"
12 #ifdef KS13WRAPPER
14 #if KS13WRAPPER_DEBUG
16 #include <hardware/intbits.h>
18 #ifndef D
19 #define D(x) ;
20 #endif
22 #define SERDATR 0x18
23 #define SERDAT 0x30
24 #define INTREQ 0x9c
25 #define SERDATR_TBE (1 << 13) /* Tx Buffer Empty */
26 #define SERDAT_STP8 (1 << 8)
27 #define SERDAT_DB8(x) ((x) & 0xff)
29 #endif
31 /* Must use DOSBase, CDTV extended ROM 2.x includes v37 SysBase replacement */
32 #define ISKS20 (DOSBase->dl_lib.lib_Version >= 37)
34 #define MIN_STACKSIZE 8000
36 AROS_UFP2(void, StackSwap,
37 AROS_UFPA(struct StackSwapStruct*, stack, A0),
38 AROS_UFPA(struct ExecBase*, SysBase, A6));
40 #if KS13WRAPPER_DEBUG
42 static inline void reg_w(ULONG reg, UWORD val)
44 volatile UWORD *r = (void *)(0xdff000 + reg);
46 *r = val;
48 static inline UWORD reg_r(ULONG reg)
50 volatile UWORD *r = (void *)(0xdff000 + reg);
52 return *r;
54 static void DebugPutChar(register int chr)
56 if (chr == '\n')
57 DebugPutChar('\r');
59 while ((reg_r(SERDATR) & SERDATR_TBE) == 0);
60 reg_w(INTREQ, INTF_TBE);
62 /* Output a char to the debug UART */
63 reg_w(SERDAT, SERDAT_STP8 | SERDAT_DB8(chr));
65 void DebugPutStr(register const char *buff)
67 for (; *buff != 0; buff++)
68 DebugPutChar(*buff);
70 void DebugPutDec(const char *what, ULONG val)
72 int i, num;
73 BOOL leadingzero = TRUE;
75 DebugPutStr(what);
76 DebugPutStr(": ");
77 if (val == 0) {
78 DebugPutChar('0');
79 DebugPutChar('\n');
80 return;
83 for (i = 1000000000; i > 0; i /= 10) {
84 if (val == 0) {
85 DebugPutChar('0');
86 continue;
89 num = val / i;
90 if (num == 0 && leadingzero)
91 continue;
92 leadingzero = FALSE;
94 DebugPutChar("0123456789"[num]);
95 val -= num * i;
97 DebugPutChar('\n');
99 void DebugPutHex(const char *what, ULONG val)
101 int i;
102 DebugPutStr(what);
103 DebugPutStr(": ");
104 for (i = 0; i < 8; i ++) {
105 DebugPutChar("0123456789abcdef"[(val >> (28 - (i * 4))) & 0xf]);
107 DebugPutChar('\n');
109 void DebugPutHexVal(ULONG val)
111 int i;
112 for (i = 0; i < 8; i ++) {
113 DebugPutChar("0123456789abcdef"[(val >> (28 - (i * 4))) & 0xf]);
115 DebugPutChar(' ');
118 void Trace(ULONG id, const UBYTE *title, const UBYTE *format, ...)
120 UBYTE buffer[256];
121 va_list parms;
122 va_start(parms, format);
123 vsnprintf(buffer, sizeof buffer - 1, format, parms);
124 DebugPutStr(title);
125 DebugPutStr(":");
126 DebugPutStr(buffer);
127 DebugPutStr("\n");
128 va_end(parms);
131 #endif
133 APTR W_AllocVec(ULONG size, ULONG flags, struct globaldata *g)
135 ULONG *mem;
137 if (!size)
138 return NULL;
139 size += sizeof(ULONG);
140 mem = AllocMem(size, flags);
141 if (!mem)
142 return NULL;
143 mem[0] = size;
144 mem++;
145 return mem;
147 void W_FreeVec(APTR mem, struct globaldata *g)
149 ULONG *p = mem;
150 if (!p)
151 return;
152 p--;
153 FreeMem(p, p[0]);
156 APTR W_CreateIORequest(struct MsgPort *ioReplyPort, ULONG size, struct globaldata *g)
158 struct IORequest *ret=NULL;
159 if(ioReplyPort==NULL)
160 return NULL;
161 ret=(struct IORequest *)AllocMem(size,MEMF_PUBLIC|MEMF_CLEAR);
162 if(ret!=NULL)
164 ret->io_Message.mn_ReplyPort=ioReplyPort;
165 ret->io_Message.mn_Length=size;
167 return ret;
170 void W_DeleteIORequest(APTR iorequest, struct globaldata *g)
172 if(iorequest != NULL)
173 FreeMem(iorequest, ((struct Message *)iorequest)->mn_Length);
176 struct MsgPort *W_CreateMsgPort(struct globaldata *g)
178 struct MsgPort *ret;
179 ret=(struct MsgPort *)AllocMem(sizeof(struct MsgPort),MEMF_PUBLIC|MEMF_CLEAR);
180 if(ret!=NULL)
182 BYTE sb;
183 sb=AllocSignal(-1);
184 if (sb != -1)
186 ret->mp_Flags = PA_SIGNAL;
187 ret->mp_Node.ln_Type = NT_MSGPORT;
188 NEWLIST(&ret->mp_MsgList);
189 ret->mp_SigBit=sb;
190 ret->mp_SigTask=FindTask(NULL);
191 return ret;
193 FreeMem(ret,sizeof(struct MsgPort));
195 return NULL;
198 void W_DeleteMsgPort(struct MsgPort *port, struct globaldata *g)
200 if(port!=NULL)
202 FreeSignal(port->mp_SigBit);
203 FreeMem(port,sizeof(struct MsgPort));
207 BOOL W_MatchPatternNoCase(CONST_STRPTR pat, CONST_STRPTR str, struct globaldata *g)
209 if (ISKS20)
210 return AROS_LVO_CALL2(BOOL,
211 AROS_LCA(CONST_STRPTR, pat, D1),
212 AROS_LCA(CONST_STRPTR, str, D2),
213 struct DosLibrary*, DOSBase, 162, );
214 /* Used by ACTION_EXAMINE_ALL which is 2.0+ only packet */
215 return FALSE;
218 STRPTR FilePart(CONST_STRPTR path)
220 if(path)
222 CONST_STRPTR i;
223 if (!*path)
224 return (STRPTR)path;
225 i = path + strlen (path) -1;
226 while ((*i != ':') && (*i != '/') && (i != path))
227 i--;
228 if ((*i == ':')) i++;
229 if ((*i == '/')) i++;
230 return (STRPTR)i;
232 return NULL;
235 STRPTR PathPart(CONST_STRPTR path)
237 const char *ptr;
239 while (*path == '/')
241 ++path;
243 ptr = path;
244 while (*ptr)
246 if (*ptr == '/')
248 path = ptr;
250 else if (*ptr == ':')
252 path = ptr + 1;
254 ptr++;
256 return (STRPTR)path;
259 static BOOL CMPBSTR(BSTR s1, BSTR s2)
261 UBYTE *ss1 = BADDR(s1);
262 UBYTE *ss2 = BADDR(s2);
263 return memcmp(ss1, ss2, ss1[0] + 1);
265 static struct DosList *getdoslist(struct globaldata *g)
267 struct DosInfo *di;
269 di = BADDR(DOSBase->dl_Root->rn_Info);
270 Forbid();
271 return (struct DosList *)&di->di_DevInfo;
273 static void freedoslist(struct globaldata *g)
275 Permit();
278 struct DosList *W_MakeDosEntry(CONST_STRPTR name, LONG type, struct globaldata *g)
280 ULONG len;
281 STRPTR s2;
282 struct DosList *dl;
284 if (ISKS20)
285 return AROS_LVO_CALL2(struct DosList*,
286 AROS_LCA(CONST_STRPTR, name, D1),
287 AROS_LCA(LONG, type, D2),
288 struct DosLibrary*, DOSBase, 116, );
290 len = strlen(name);
291 dl = (struct DosList *)AllocVec(sizeof(struct DosList),
292 MEMF_PUBLIC | MEMF_CLEAR);
294 if (dl != NULL)
296 /* Binary compatibility for BCPL string.
297 * First byte is the length then comes the string.
298 * For ease of use a zero is put at the end so it can be used as a
299 * C string
301 s2 = (STRPTR)AllocVec(len+2, MEMF_PUBLIC | MEMF_CLEAR);
302 dl->dol_Name = MKBADDR(s2);
303 if (s2 != NULL)
304 *s2++ = (UBYTE)(len > 255 ? 255 : len);
305 if (s2 != NULL)
307 strcpy(s2, name);
308 dl->dol_Type = type;
309 return dl;
311 FreeVec(dl);
313 return NULL;
316 LONG W_RemDosEntry(struct DosList *dlist, struct globaldata *g)
318 struct DosList *dl;
320 if (ISKS20)
321 return AROS_LVO_CALL1(LONG,
322 AROS_LCA(struct DosList*, dlist, D1),
323 struct DosLibrary*, DOSBase, 112, );
325 if(dlist == NULL)
326 return 0;
328 dl = getdoslist(g);
330 while(dl->dol_Next)
332 struct DosList *dl2 = BADDR(dl->dol_Next);
334 if(dl2 == dlist)
336 dl->dol_Next = dlist->dol_Next;
337 break;
340 dl = dl2;
343 freedoslist(g);
345 return 1;
348 void W_FreeDosEntry(struct DosList *dlist, struct globaldata *g)
350 if (ISKS20) {
351 AROS_LVO_CALL1(void,
352 AROS_LCA(struct DosList*, dlist, D1),
353 struct DosLibrary*, DOSBase, 117, );
354 return;
356 if (dlist == NULL)
357 return;
358 FreeVec(BADDR(dlist->dol_Name));
359 FreeVec(dlist);
362 LONG W_AddDosEntry(struct DosList *dlist, struct globaldata *g)
364 LONG success = DOSTRUE;
365 struct DosList *dl;
367 if (ISKS20)
368 return AROS_LVO_CALL1(LONG,
369 AROS_LCA(struct DosList*, dlist, D1),
370 struct DosLibrary*, DOSBase, 113, );
372 if (dlist == NULL)
373 return success;
375 D(bug("[AddDosEntry] Adding '%b' type %d from addr %x Task '%s'\n",
376 dlist->dol_Name, dlist->dol_Type, dlist,
377 FindTask(NULL)->tc_Node.ln_Name));
379 dl = getdoslist(g);
381 if(dlist->dol_Type != DLT_VOLUME)
383 while(TRUE)
385 dl = BADDR(dl->dol_Next);
387 if(dl == NULL)
388 break;
390 if(dl->dol_Type != DLT_VOLUME && !CMPBSTR(dl->dol_Name, dlist->dol_Name))
392 D(bug("[AddDosEntry] Name clash for %08lx->dol_Name: %b and %08lx->dol_Name %b\n", dl, dl->dol_Name, dlist, dlist->dol_Name));
393 success = DOSFALSE;
394 break;
399 if(success)
401 struct DosInfo *dinf = BADDR(DOSBase->dl_Root->rn_Info);
403 dlist->dol_Next = dinf->di_DevInfo;
404 dinf->di_DevInfo = MKBADDR(dlist);
407 freedoslist(g);
409 return success;
412 IPTR CallHookPkt(struct Hook *hook, APTR object, APTR paramPacket)
414 return CALLHOOKPKT(hook, object, paramPacket);
417 BOOL W_ErrorReport(LONG code, LONG type, IPTR arg1, struct MsgPort *device, struct globaldata *g)
419 if (ISKS20)
420 return AROS_LVO_CALL4(BOOL,
421 AROS_LCA(LONG, code, D1),
422 AROS_LCA(LONG, type, D2),
423 AROS_LCA(IPTR, arg1, D3),
424 AROS_LCA(struct MsgPort*, device, D4),
425 struct DosLibrary*, DOSBase, 80, );
427 return FALSE;
430 LONG W_EasyRequestArgs(struct Window *window, struct EasyStruct *easyStruct, ULONG *IDCMP_ptr, APTR argList, struct globaldata *g)
432 if (ISKS20)
433 return AROS_LVO_CALL4(LONG,
434 AROS_LCA(struct Window*, window, A0),
435 AROS_LCA(struct EasyStruct*, easyStruct, A1),
436 AROS_LCA(ULONG*, IDCMP_ptr, A2),
437 AROS_LCA(APTR, argList, A3),
438 APTR, IntuitionBase, 98, );
439 return 1;
442 struct Window *W_BuildEasyRequestArgs(struct Window *RefWindow, struct EasyStruct *easyStruct, ULONG IDCMP, APTR Args, struct globaldata *g)
444 if (ISKS20)
445 return AROS_LVO_CALL4(struct Window*,
446 AROS_LCA(struct Window*, RefWindow, A0),
447 AROS_LCA(struct EasyStruct*, easyStruct, A1),
448 AROS_LCA(ULONG, IDCMP, D0),
449 AROS_LCA(APTR, Args, A3),
450 APTR, IntuitionBase, 99, );
451 return NULL;
454 LONG W_SysReqHandler(struct Window *window, ULONG *IDCMPFlagsPtr, BOOL WaitInput, struct globaldata *g)
456 if (ISKS20)
457 return AROS_LVO_CALL3(LONG,
458 AROS_LCA(struct Window*, window, A0),
459 AROS_LCA(ULONG*, IDCMPFlagsPtr, A1),
460 AROS_LCA(BOOL, WaitInput, D0),
461 APTR, IntuitionBase, 100, );
462 return 0;
465 #undef SysBase
466 #undef DOSBase
468 void FixStartupPacket(struct DosPacket *pkt, struct globaldata *g)
470 if (pkt->dp_Arg3)
471 return;
472 /* Fix 1.3 bad boot time ACTION_STARTUP: dp_Arg3 = NULL, dp_Arg1 = uninitialized data */
473 struct DosList *dl = getdoslist(g);
474 while(dl->dol_Next)
476 dl = BADDR(dl->dol_Next);
477 if (dl->dol_Type == DLT_DEVICE && dl->dol_misc.dol_handler.dol_Startup == pkt->dp_Arg2) {
478 /* This is safe, Startup Packet is allocated from BCPL stack
479 * that goes away after DOS gets message reply.
481 pkt->dp_Arg1 = dl->dol_Name;
482 pkt->dp_Arg3 = MKBADDR(dl);
483 break;
486 freedoslist(g);
489 LONG wrapper_stackswap(LONG (*func)(struct ExecBase *), struct ExecBase *SysBase)
491 struct DosLibrary *DOSBase;
492 ULONG stacksize;
493 APTR stackptr;
494 struct Task *tc;
495 struct StackSwapStruct *stack;
496 LONG ret;
498 tc = FindTask(NULL);
499 stacksize = (UBYTE *)tc->tc_SPUpper - (UBYTE *)tc->tc_SPLower;
500 if (stacksize >= MIN_STACKSIZE) {
501 ret = func(SysBase);
502 return ret;
505 stack = AllocMem(sizeof(struct StackSwapStruct) + MIN_STACKSIZE, MEMF_CLEAR | MEMF_PUBLIC);
506 if (!stack) {
507 Alert(AT_DeadEnd | AG_NoMemory);
508 return RETURN_FAIL;
510 stackptr = stack + 1;
511 stack->stk_Lower = stackptr;
512 stack->stk_Upper = (APTR)((IPTR)stack->stk_Lower + MIN_STACKSIZE);
513 stack->stk_Pointer = (APTR)stack->stk_Upper;
515 DOSBase = (struct DosLibrary *)OpenLibrary ("dos.library", MIN_LIB_VERSION);
516 if (ISKS20) {
517 AROS_LVO_CALL1(void,
518 AROS_LCA(struct StackSwapStruct*, stack, A0),
519 struct ExecBase*, SysBase, 122, );
520 ret = func(SysBase);
521 AROS_LVO_CALL1(void,
522 AROS_LCA(struct StackSwapStruct*, stack, A0),
523 struct ExecBase*, SysBase, 122, );
524 } else {
525 AROS_UFC2(void, StackSwap,
526 AROS_UFCA(struct StackSwapStruct*, stack, A0),
527 AROS_UFCA(struct ExecBase*, SysBase, A6));
528 ret = func(SysBase);
529 AROS_UFC2(void, StackSwap,
530 AROS_UFCA(struct StackSwapStruct*, stack, A0),
531 AROS_UFCA(struct ExecBase*, SysBase, A6));
533 FreeMem(stack, sizeof(struct StackSwapStruct) + MIN_STACKSIZE);
534 CloseLibrary((struct Library*)DOSBase);
536 return ret;
539 #endif
541 size_t strcspn (const char * str, const char * reject)
543 size_t n = 0; /* Must set this to zero */
545 while (*str && !strchr (reject, *str))
547 str ++;
548 n ++;
551 return n;