2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
6 #include <aros/asmcall.h>
8 #include <exec/libraries.h>
9 #include <dos/dosextens.h>
11 #include <proto/arossupport.h>
12 #include <proto/exec.h>
13 #include <proto/dos.h>
17 /* CallGlobVec lives in the private function (4) */
18 AROS_UFP5(LONG
, CallGlobVec
,
19 AROS_UFPA(LONG
, function
, D0
),
20 AROS_UFPA(LONG
, d1
, D1
),
21 AROS_UFPA(LONG
, d2
, D2
),
22 AROS_UFPA(LONG
, d3
, D3
),
23 AROS_UFPA(LONG
, d4
, D4
));
26 /* LoadSeg() needs D1-D3 parameters for overlay hunk support */
27 AROS_UFP4(BPTR
, LoadSeg_Overlay
,
28 AROS_UFPA(UBYTE
*, name
, D1
),
29 AROS_UFPA(BPTR
, hunktable
, D2
),
30 AROS_UFPA(BPTR
, fh
, D3
),
31 AROS_UFPA(struct DosLibrary
*, DosBase
, A6
));
33 static AROS_UFH2(BPTR
, NoReqLoadSeg
,
34 AROS_UFPA(BSTR
, name
, D1
),
35 AROS_UFPA(struct DosLibrary
*, DOSBase
, A6
))
42 struct Process
*me
= (struct Process
*)FindTask(NULL
);
43 int len
= AROS_BSTR_strlen(name
);
47 CopyMem(buff
, AROS_BSTR_ADDR(name
), len
);
50 oldWindowPtr
= me
->pr_WindowPtr
;
51 me
->pr_WindowPtr
= (APTR
)-1;
53 me
->pr_WindowPtr
= oldWindowPtr
;
55 SetIoErr(ERROR_OBJECT_NOT_FOUND
);
63 AROS_UFH5(BPTR
, LoadSeg_Check
,
64 AROS_UFPA(UBYTE
*, name
, D1
),
65 AROS_UFPA(BPTR
, hunktable
, D2
),
66 AROS_UFPA(BPTR
, fh
, D3
),
67 AROS_UFPA(APTR
, LoadSeg_Original
, A0
),
68 AROS_UFPA(struct DosLibrary
*, DOSBase
, A6
))
74 /* name == NULL: Overlay LoadSeg */
76 return AROS_UFC4(BPTR
, LoadSeg_Overlay
,
77 AROS_UFCA(UBYTE
*, name
, D1
),
78 AROS_UFCA(BPTR
, hunktable
, D2
),
79 AROS_UFCA(BPTR
, fh
, D3
),
80 AROS_UFCA(struct DosLibrary
*, DOSBase
, A6
));
82 filename
= FilePart(name
);
84 /* Do not allow Picasso96 to load, it is not
85 * compatible with built-in AROS RTG system */
86 if (stricmp(filename
,"rtg.library") == 0)
89 /* Call original LoadSeg function */
90 return AROS_UFC2(BPTR
, LoadSeg_Original
,
91 AROS_UFCA(UBYTE
*, name
, D1
),
92 AROS_UFCA(struct DosLibrary
*, DOSBase
, A6
));
97 extern void *BCPL_jsr
, *BCPL_rts
;
98 extern const ULONG BCPL_GlobVec
[(BCPL_GlobVec_NegSize
+ BCPL_GlobVec_PosSize
) >> 2];
100 const UWORD highfunc
= 37, lowfunc
= 5, skipfuncs
= 2;
102 #define PATCHMEM_SIZE (10 * (highfunc - lowfunc + 1 - skipfuncs) * sizeof(UWORD) + 13 * sizeof(UWORD))
104 /* This patches two compatibility problems with badly written programs:
105 * 1) Return value in both D0 and D1.
106 * 2) 1.x original DOS functions can be called without DOSBase in A6.
107 * Both "features" are original BCPL DOS side-effects.
110 static int PatchDOS(struct DosLibrary
*dosbase
)
113 UWORD
*asmcall
, *asmmem
;
117 GlobVec
= AllocMem(BCPL_GlobVec_NegSize
+ BCPL_GlobVec_PosSize
, MEMF_PUBLIC
);
121 CopyMem(BCPL_GlobVec
, GlobVec
, BCPL_GlobVec_NegSize
+ BCPL_GlobVec_PosSize
);
122 GlobVec
+= BCPL_GlobVec_NegSize
;
123 *(APTR
*)(GlobVec
+ GV_DOSBase
) = dosbase
;
127 /* Use this private slot for the C-to-BCPL thunk */
128 __AROS_INITVEC(dosbase
, 4);
129 __AROS_SETVECADDR(dosbase
, 4, CallGlobVec
);
131 asmmem
= asmcall
= AllocMem(PATCHMEM_SIZE
, MEMF_PUBLIC
);
133 for (i
= lowfunc
; i
<= highfunc
; i
++)
135 if (i
== 24 || i
== 25)
137 func
= (IPTR
)__AROS_GETJUMPVEC(dosbase
, i
)->vec
;
138 __AROS_SETVECADDR(dosbase
, i
, asmcall
);
139 *asmcall
++ = 0x2f0e; // MOVE.L A6,-(SP)
140 *asmcall
++ = 0x4df9; // LEA dosbase,A6
141 *asmcall
++ = (UWORD
)((ULONG
)dosbase
>> 16);
142 *asmcall
++ = (UWORD
)((ULONG
)dosbase
>> 0);
143 *asmcall
++ = 0x4eb9; // JSR func
144 *asmcall
++ = (UWORD
)(func
>> 16);
145 *asmcall
++ = (UWORD
)(func
>> 0);
146 *asmcall
++ = 0x2C5F; // MOVE.L (SP)+,A6
147 *asmcall
++ = 0x2200; // MOVE.L D0,D1
148 *asmcall
++ = 0x4e75; // RTS
151 /* NoReqLoadSeg() patch */
152 SetFunction((struct Library
*)dosbase
, 28, NoReqLoadSeg
);
154 /* LoadSeg() patch */
155 func
= (IPTR
)__AROS_GETJUMPVEC(dosbase
, 25)->vec
;
156 __AROS_SETVECADDR(dosbase
, 25, asmcall
);
157 *asmcall
++ = 0x2f0e; // MOVE.L A6,-(SP)
158 *asmcall
++ = 0x4df9; // LEA dosbase,A6
159 *asmcall
++ = (UWORD
)((ULONG
)dosbase
>> 16);
160 *asmcall
++ = (UWORD
)((ULONG
)dosbase
>> 0);
161 *asmcall
++ = 0x41f9; // LEA func,A0
162 *asmcall
++ = (UWORD
)(func
>> 16);
163 *asmcall
++ = (UWORD
)(func
>> 0);
164 *asmcall
++ = 0x4eb9; // jsr LoadSeg_Check
165 *asmcall
++ = (UWORD
)((ULONG
)LoadSeg_Check
>> 16);
166 *asmcall
++ = (UWORD
)((ULONG
)LoadSeg_Check
>> 0);
167 *asmcall
++ = 0x2C5F; // MOVE.L (SP)+,A6
168 *asmcall
++ = 0x2200; // MOVE.L D0,D1
169 *asmcall
++ = 0x4e75; // RTS
171 CacheClearE(asmmem
, PATCHMEM_SIZE
, CACRF_ClearI
|CACRF_ClearD
);
173 dosbase
->dl_A5
= (LONG
)&BCPL_jsr
;
174 dosbase
->dl_A6
= (LONG
)&BCPL_rts
;
175 dosbase
->dl_GV
= (APTR
)GlobVec
;
182 ADD2INITLIB(PatchDOS
, 0)
184 static int UnPatchDOS(struct DosLibrary
*dosbase
)
188 asmcall
= __AROS_GETJUMPVEC(dosbase
, lowfunc
)->vec
;
189 FreeMem(asmcall
, PATCHMEM_SIZE
);
190 FreeMem(dosbase
->dl_GV
- BCPL_GlobVec_NegSize
, BCPL_GlobVec_NegSize
+ BCPL_GlobVec_PosSize
);
195 ADD2EXPUNGELIB(UnPatchDOS
, 0)