2 #include <aros/debug.h>
3 #include <exec/types.h>
4 #include <exec/memory.h>
5 #include <proto/exec.h>
10 #include "ks13wrapper.h"
16 #include <hardware/intbits.h>
25 #define SERDATR_TBE (1 << 13) /* Tx Buffer Empty */
26 #define SERDAT_STP8 (1 << 8)
27 #define SERDAT_DB8(x) ((x) & 0xff)
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
));
42 static inline void reg_w(ULONG reg
, UWORD val
)
44 volatile UWORD
*r
= (void *)(0xdff000 + reg
);
48 static inline UWORD
reg_r(ULONG reg
)
50 volatile UWORD
*r
= (void *)(0xdff000 + reg
);
54 static void DebugPutChar(register int chr
)
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
++)
70 void DebugPutDec(const char *what
, ULONG val
)
73 BOOL leadingzero
= TRUE
;
83 for (i
= 1000000000; i
> 0; i
/= 10) {
90 if (num
== 0 && leadingzero
)
94 DebugPutChar("0123456789"[num
]);
99 void DebugPutHex(const char *what
, ULONG val
)
104 for (i
= 0; i
< 8; i
++) {
105 DebugPutChar("0123456789abcdef"[(val
>> (28 - (i
* 4))) & 0xf]);
109 void DebugPutHexVal(ULONG val
)
112 for (i
= 0; i
< 8; i
++) {
113 DebugPutChar("0123456789abcdef"[(val
>> (28 - (i
* 4))) & 0xf]);
118 void Trace(ULONG id
, const UBYTE
*title
, const UBYTE
*format
, ...)
122 va_start(parms
, format
);
123 vsnprintf(buffer
, sizeof buffer
- 1, format
, parms
);
133 APTR
W_AllocVec(ULONG size
, ULONG flags
, struct globaldata
*g
)
139 size
+= sizeof(ULONG
);
140 mem
= AllocMem(size
, flags
);
147 void W_FreeVec(APTR mem
, struct globaldata
*g
)
156 APTR
W_CreateIORequest(struct MsgPort
*ioReplyPort
, ULONG size
, struct globaldata
*g
)
158 struct IORequest
*ret
=NULL
;
159 if(ioReplyPort
==NULL
)
161 ret
=(struct IORequest
*)AllocMem(size
,MEMF_PUBLIC
|MEMF_CLEAR
);
164 ret
->io_Message
.mn_ReplyPort
=ioReplyPort
;
165 ret
->io_Message
.mn_Length
=size
;
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
)
179 ret
=(struct MsgPort
*)AllocMem(sizeof(struct MsgPort
),MEMF_PUBLIC
|MEMF_CLEAR
);
186 ret
->mp_Flags
= PA_SIGNAL
;
187 ret
->mp_Node
.ln_Type
= NT_MSGPORT
;
188 NEWLIST(&ret
->mp_MsgList
);
190 ret
->mp_SigTask
=FindTask(NULL
);
193 FreeMem(ret
,sizeof(struct MsgPort
));
198 void W_DeleteMsgPort(struct MsgPort
*port
, struct globaldata
*g
)
202 FreeSignal(port
->mp_SigBit
);
203 FreeMem(port
,sizeof(struct MsgPort
));
207 BOOL
W_MatchPatternNoCase(CONST_STRPTR pat
, CONST_STRPTR str
, struct globaldata
*g
)
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 */
218 STRPTR
FilePart(CONST_STRPTR path
)
225 i
= path
+ strlen (path
) -1;
226 while ((*i
!= ':') && (*i
!= '/') && (i
!= path
))
228 if ((*i
== ':')) i
++;
229 if ((*i
== '/')) i
++;
235 STRPTR
PathPart(CONST_STRPTR path
)
250 else if (*ptr
== ':')
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
)
269 di
= BADDR(DOSBase
->dl_Root
->rn_Info
);
271 return (struct DosList
*)&di
->di_DevInfo
;
273 static void freedoslist(struct globaldata
*g
)
278 struct DosList
*W_MakeDosEntry(CONST_STRPTR name
, LONG type
, struct globaldata
*g
)
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, );
291 dl
= (struct DosList
*)AllocVec(sizeof(struct DosList
),
292 MEMF_PUBLIC
| MEMF_CLEAR
);
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
301 s2
= (STRPTR
)AllocVec(len
+2, MEMF_PUBLIC
| MEMF_CLEAR
);
302 dl
->dol_Name
= MKBADDR(s2
);
304 *s2
++ = (UBYTE
)(len
> 255 ? 255 : len
);
316 LONG
W_RemDosEntry(struct DosList
*dlist
, struct globaldata
*g
)
321 return AROS_LVO_CALL1(LONG
,
322 AROS_LCA(struct DosList
*, dlist
, D1
),
323 struct DosLibrary
*, DOSBase
, 112, );
332 struct DosList
*dl2
= BADDR(dl
->dol_Next
);
336 dl
->dol_Next
= dlist
->dol_Next
;
348 void W_FreeDosEntry(struct DosList
*dlist
, struct globaldata
*g
)
352 AROS_LCA(struct DosList
*, dlist
, D1
),
353 struct DosLibrary
*, DOSBase
, 117, );
358 FreeVec(BADDR(dlist
->dol_Name
));
362 LONG
W_AddDosEntry(struct DosList
*dlist
, struct globaldata
*g
)
364 LONG success
= DOSTRUE
;
368 return AROS_LVO_CALL1(LONG
,
369 AROS_LCA(struct DosList
*, dlist
, D1
),
370 struct DosLibrary
*, DOSBase
, 113, );
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
));
381 if(dlist
->dol_Type
!= DLT_VOLUME
)
385 dl
= BADDR(dl
->dol_Next
);
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
));
401 struct DosInfo
*dinf
= BADDR(DOSBase
->dl_Root
->rn_Info
);
403 dlist
->dol_Next
= dinf
->di_DevInfo
;
404 dinf
->di_DevInfo
= MKBADDR(dlist
);
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
)
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, );
430 LONG
W_EasyRequestArgs(struct Window
*window
, struct EasyStruct
*easyStruct
, ULONG
*IDCMP_ptr
, APTR argList
, struct globaldata
*g
)
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, );
442 struct Window
*W_BuildEasyRequestArgs(struct Window
*RefWindow
, struct EasyStruct
*easyStruct
, ULONG IDCMP
, APTR Args
, struct globaldata
*g
)
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, );
454 LONG
W_SysReqHandler(struct Window
*window
, ULONG
*IDCMPFlagsPtr
, BOOL WaitInput
, struct globaldata
*g
)
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, );
468 void FixStartupPacket(struct DosPacket
*pkt
, struct globaldata
*g
)
472 /* Fix 1.3 bad boot time ACTION_STARTUP: dp_Arg3 = NULL, dp_Arg1 = uninitialized data */
473 struct DosList
*dl
= getdoslist(g
);
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
);
489 LONG
wrapper_stackswap(LONG (*func
)(struct ExecBase
*), struct ExecBase
*SysBase
)
491 struct DosLibrary
*DOSBase
;
495 struct StackSwapStruct
*stack
;
499 stacksize
= (UBYTE
*)tc
->tc_SPUpper
- (UBYTE
*)tc
->tc_SPLower
;
500 if (stacksize
>= MIN_STACKSIZE
) {
505 stack
= AllocMem(sizeof(struct StackSwapStruct
) + MIN_STACKSIZE
, MEMF_CLEAR
| MEMF_PUBLIC
);
507 Alert(AT_DeadEnd
| AG_NoMemory
);
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
);
518 AROS_LCA(struct StackSwapStruct
*, stack
, A0
),
519 struct ExecBase
*, SysBase
, 122, );
522 AROS_LCA(struct StackSwapStruct
*, stack
, A0
),
523 struct ExecBase
*, SysBase
, 122, );
525 AROS_UFC2(void, StackSwap
,
526 AROS_UFCA(struct StackSwapStruct
*, stack
, A0
),
527 AROS_UFCA(struct ExecBase
*, SysBase
, A6
));
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
);
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
))