Compare commits

...

14 Commits

Author SHA1 Message Date
deadwood 3e316f92df Add functions needed for LibOpen of locale.library 2024-03-20 19:11:18 +01:00
deadwood 902b837cf4 Shallow init of layers.library and load utility.library for Intuition
Needed for LibOpen of gadtools.library
2024-03-20 19:02:18 +01:00
deadwood 48d73a41d8 Stubs needed to LibOpen workbench.library 2024-03-20 18:36:13 +01:00
deadwood 01feaa5b05 Stub AddMemHandler
Needed for LibInit of diskfont.library
2024-03-20 18:17:16 +01:00
deadwood 81f9898a02 Implement opening timer.device
Needed to complete LibInit of commodities.library
2024-03-20 18:11:36 +01:00
deadwood 16502d4fda Implement AddResource
Needed to LibInit keymap.library
2024-03-20 17:58:11 +01:00
deadwood 3b669a8ef0 Original file 2024-03-20 17:51:06 +01:00
deadwood 4c5dad6f53 Initialize all Intuition classes
This allows completing LibInit of coolimages.library
2024-03-20 17:39:44 +01:00
deadwood 83a2ad87aa Move libraries which are patches/assembled in 64-bit code to Lib32/partial
This will distinguish them from libraries that can be used as-is.
2024-03-20 17:34:47 +01:00
deadwood 2801d7d573 Initialized Intuition ROOTCLASS 2024-03-20 17:32:36 +01:00
deadwood 18aa285c81 Fill undefined symbol SysBase in kernel 2024-03-20 17:31:12 +01:00
deadwood b105bca3a2 Use shallow_InitResident32 to bring up Intuition and Gfx 2024-03-20 15:51:30 +01:00
deadwood b02c04c58f Introduce shallow_InitResident
It will create library structure with jump table, but will not run LibInit
code. This is useful for libraries which will mostly be proxies, but some
functions can be re-used.
2024-03-20 15:27:39 +01:00
deadwood a9983159d0 Proxy FreeMem 2024-03-12 20:15:18 +01:00
6 changed files with 325 additions and 14 deletions

View File

@ -17,7 +17,45 @@
BPTR LoadSeg32 (CONST_STRPTR name, struct DosLibrary *DOSBase);
struct DosLibraryV0 *abiv0DOSBase;
struct LibraryV0 *abiv0TimerBase;
struct LibraryV0 *shallow_InitResident32(struct ResidentV0 *resident, BPTR segList, struct ExecBaseV0 *SysBaseV0)
{
struct LibraryV0 *library = NULL;
D(bug("InitResident begin 0x%p (\"%s\")", resident, resident->rt_Name));
/* Check for validity */
if(resident->rt_MatchWord != RTC_MATCHWORD ||
resident->rt_MatchTag != (APTR32)(IPTR)resident)
return NULL;
/* Depending on the autoinit flag... */
if(resident->rt_Flags & RTF_AUTOINIT)
{
/* ...initialize automatically... */
struct init
{
ULONG dSize;
APTR32 vectors;
APTR32 structure;
APTR32 init;
};
struct init *init = (struct init *)(IPTR)resident->rt_Init;
init->init = 0;
library = abiv0_InitResident(resident, segList, SysBaseV0);
}
else
{
D(bug("InitResident !RTF_AUTOINIT"));
asm("int3");
}
D(bug("InitResident end 0x%p (\"%s\"), result 0x%p", resident, resident->rt_Name, library));
return library;
} /* shallow_InitResident32 */
APTR abiv0_AllocMem(ULONG byteSize, ULONG requirements, struct ExecBaseV0 *SysBaseV0)
@ -26,6 +64,12 @@ APTR abiv0_AllocMem(ULONG byteSize, ULONG requirements, struct ExecBaseV0 *SysBa
}
MAKE_PROXY_ARG_3(AllocMem)
void abiv0_FreeMem(APTR memoryBlock, ULONG byteSize, struct ExecBaseV0 *SysBaseV0)
{
return FreeMem(memoryBlock, byteSize);
}
MAKE_PROXY_ARG_3(FreeMem)
APTR abiv0_AllocVec(ULONG byteSize, ULONG requirements, struct ExecBaseV0 *SysBaseV0)
{
return AllocVec(byteSize, requirements | MEMF_31BIT);
@ -50,6 +94,24 @@ ULONG abiv0_TypeOfMem(APTR address, struct ExecBaseV0 *SysBaseV0)
}
MAKE_PROXY_ARG_2(TypeOfMem)
VOID abiv0_Forbid(struct ExecBaseV0 *SysBaseV0)
{
Forbid();
}
MAKE_PROXY_ARG_1(Forbid)
VOID abiv0_Permit(struct ExecBaseV0 *SysBaseV0)
{
Permit();
}
MAKE_PROXY_ARG_1(Permit)
VOID abiv0_AddMemHandler(APTR memHandler, struct ExecBaseV0 *SysBaseV0)
{
bug("abiv0_AddMemHandler ignored\n");
}
MAKE_PROXY_ARG_2(AddMemHandler)
struct ResidentV0 * findResident(BPTR seg, CONST_STRPTR name)
{
/* we may not have any extension fields */
@ -185,7 +247,7 @@ LONG abiv0_OpenDevice(CONST_STRPTR devName, ULONG unitNumber, struct IORequestV0
{
if (strcmp(devName, "timer.device") == 0)
{
iORequest->io_Device = (APTR32)0;
iORequest->io_Device = (APTR32)(IPTR)abiv0TimerBase;
return 0;
}
@ -195,6 +257,7 @@ asm("int3");
MAKE_PROXY_ARG_4(OpenDevice)
MAKE_PROXY_ARG_6(MakeLibrary)
MAKE_PROXY_ARG_2(AddResource)
void abiv0_CopyMem(APTR source, APTR dest, ULONG size)
{
@ -202,6 +265,24 @@ void abiv0_CopyMem(APTR source, APTR dest, ULONG size)
}
MAKE_PROXY_ARG_4(CopyMem)
struct LibraryV0 *abiv0_Intuition_OpenLib(ULONG version, struct LibraryV0* IntuitionBaseV0)
{
return IntuitionBaseV0;
}
MAKE_PROXY_ARG_2(Intuition_OpenLib)
struct LibraryV0 *abiv0_Gfx_OpenLib(ULONG version, struct LibraryV0* GfxBaseV0)
{
return GfxBaseV0;
}
MAKE_PROXY_ARG_2(Gfx_OpenLib)
struct LibraryV0 *abiv0_Layers_OpenLib(ULONG version, struct LibraryV0* LayersBaseV0)
{
return LayersBaseV0;
}
MAKE_PROXY_ARG_2(Layers_OpenLib)
struct TaskV0 *abiv0_FindTask(CONST_STRPTR name, struct ExecBaseV0 *SysBaseV0)
{
static struct ProcessV0 *dummy = NULL;
@ -209,7 +290,7 @@ struct TaskV0 *abiv0_FindTask(CONST_STRPTR name, struct ExecBaseV0 *SysBaseV0)
dummy->pr_Task.tc_Node.ln_Type = NT_PROCESS;
dummy->pr_Task.tc_Node.ln_Name = (APTR32)(IPTR)abiv0_AllocMem(10, MEMF_CLEAR, SysBaseV0);
strcpy((char *)(IPTR)dummy->pr_Task.tc_Node.ln_Name, "emulator");
dummy->pr_CLI = 0x1; //fake
dummy->pr_CLI = (BPTR32)(IPTR)abiv0_AllocMem(sizeof(struct CommandLineInterfaceV0), MEMF_CLEAR, SysBaseV0);
dummy->pr_CIS = 0x1; //fake
dummy->pr_CES = 0x1; //fake
dummy->pr_COS = 0x1; //fake
@ -224,6 +305,12 @@ LONG abiv0_SetVBuf()
}
MAKE_PROXY_ARG_5(SetVBuf)
struct ProcessV0 *abiv0_CreateNewProc()
{
return (APTR)0x1;
}
MAKE_PROXY_ARG_2(CreateNewProc)
void abiv0_GetSysTime(struct timeval *dest, struct LibraryV0 *TimerBaseV0)
{
return GetSysTime(dest);
@ -243,7 +330,11 @@ MAKE_PROXY_ARG_3(FPutC)
ULONG *execfunctable;
ULONG *dosfunctable;
ULONG *dosinitlist;
ULONG *seginitlist;
ULONG *segclassesinitlist;
APTR32 global_SysBaseV0Ptr;
LONG_FUNC run_emulation()
{
@ -256,12 +347,15 @@ LONG_FUNC run_emulation()
APTR tmp;
/* Keep it! This fills global variable */
LoadSeg32("SYS:Libs32/exec/kernel", DOSBase);
tmp = AllocMem(2048, MEMF_31BIT | MEMF_CLEAR);
struct ExecBaseV0 *sysbase = (tmp + 1024);
global_SysBaseV0Ptr = (APTR32)(IPTR)&sysbase; /* Needed for LoadSeg32 to resolve SysBase in kernel */
/* Keep it! This fills global variable */
LoadSeg32("SYS:Libs32/partial/kernel", DOSBase);
NEWLISTV0(&sysbase->LibList);
NEWLISTV0(&sysbase->ResourceList);
sysbase->LibNode.lib_Version = 51;
__AROS_SETVECADDRV0(sysbase, 92, (APTR32)(IPTR)proxy_OpenLibrary);
@ -282,16 +376,27 @@ LONG_FUNC run_emulation()
__AROS_SETVECADDRV0(sysbase, 46, execfunctable[45]); // FindName
__AROS_SETVECADDRV0(sysbase,135, execfunctable[134]); // TaggedOpenLibrary
__AROS_SETVECADDRV0(sysbase, 89, (APTR32)(IPTR)proxy_TypeOfMem);
__AROS_SETVECADDRV0(sysbase, 41, execfunctable[40]); // AddTail
__AROS_SETVECADDRV0(sysbase, 87, execfunctable[86]); // RawDoFmt
__AROS_SETVECADDRV0(sysbase, 41, execfunctable[40]); // AddTail
__AROS_SETVECADDRV0(sysbase, 87, execfunctable[86]); // RawDoFmt
__AROS_SETVECADDRV0(sysbase, 35, (APTR32)(IPTR)proxy_FreeMem);
__AROS_SETVECADDRV0(sysbase,113, execfunctable[112]); // ObtainSemaphoreShared
__AROS_SETVECADDRV0(sysbase, 94, execfunctable[93]); // ObtainSemaphore
__AROS_SETVECADDRV0(sysbase, 40, execfunctable[39]); // AddHead
__AROS_SETVECADDRV0(sysbase, 95, execfunctable[94]); // ReleaseSemaphore
__AROS_SETVECADDRV0(sysbase, 81, (APTR32)(IPTR)proxy_AddResource);
__AROS_SETVECADDRV0(sysbase, 22, (APTR32)(IPTR)proxy_Forbid);
__AROS_SETVECADDRV0(sysbase, 23, (APTR32)(IPTR)proxy_Permit);
__AROS_SETVECADDRV0(sysbase,129, (APTR32)(IPTR)proxy_AddMemHandler);
__AROS_SETVECADDRV0(sysbase, 70, execfunctable[69]); // SetFunction
__AROS_SETVECADDRV0(sysbase, 71, execfunctable[70]); // SumLibrary
tmp = AllocMem(1024, MEMF_31BIT | MEMF_CLEAR);
struct LibraryV0 *abiv0TimerBase = (tmp + 512);
abiv0TimerBase = (tmp + 512);
__AROS_SETVECADDRV0(abiv0TimerBase, 11, (APTR32)(IPTR)proxy_GetSysTime);
/* Keep it! This fills global variable */
LoadSeg32("SYS:Libs32/dos.library", DOSBase);
LoadSeg32("SYS:Libs32/partial/dos.library", DOSBase);
tmp = AllocMem(2048, MEMF_31BIT | MEMF_CLEAR);
abiv0DOSBase = (tmp + 1024);
@ -299,6 +404,7 @@ LONG_FUNC run_emulation()
abiv0DOSBase->dl_TimeReq = (APTR32)(IPTR)AllocMem(sizeof(struct timerequestV0), MEMF_31BIT | MEMF_CLEAR);
((struct timerequestV0 *)(IPTR)abiv0DOSBase->dl_TimeReq)->tr_node.io_Device = (APTR32)(IPTR)abiv0TimerBase;
/* Call SysBase_autoinit */
__asm__ volatile (
"subq $4, %%rsp\n"
"movl %0, %%eax\n"
@ -308,7 +414,7 @@ LONG_FUNC run_emulation()
"call *%%eax\n"
ENTER64
"addq $4, %%rsp\n"
::"m"(sysbase), "m"(dosinitlist[1]) : "%rax", "%rcx");
::"m"(sysbase), "m"(seginitlist[1]) : "%rax", "%rcx");
__AROS_SETVECADDRV0(abiv0DOSBase, 158, (APTR32)(IPTR)proxy_PutStr);
__AROS_SETVECADDRV0(abiv0DOSBase, 9, dosfunctable[8]); // Input
@ -318,6 +424,78 @@ LONG_FUNC run_emulation()
__AROS_SETVECADDRV0(abiv0DOSBase, 82, dosfunctable[81]); // Cli
__AROS_SETVECADDRV0(abiv0DOSBase, 159, dosfunctable[158]); // VPrintf
__AROS_SETVECADDRV0(abiv0DOSBase, 52, (APTR32)(IPTR)proxy_FPutC);
__AROS_SETVECADDRV0(abiv0DOSBase, 83, (APTR32)(IPTR)proxy_CreateNewProc);
__AROS_SETVECADDRV0(abiv0DOSBase, 77, dosfunctable[76]); // SetIoErr
BPTR cgfxseg = LoadSeg32("SYS:Libs32/partial/cybergraphics.library", DOSBase);
struct ResidentV0 *cgfxres = findResident(cgfxseg, NULL);
struct LibraryV0 *abiv0CyberGfxBase = shallow_InitResident32(cgfxres, cgfxseg, sysbase);
/* Remove all vectors for now (leave LibOpen) */
for (int i = 5; i <= 38; i++) __AROS_SETVECADDRV0(abiv0CyberGfxBase, i, 0);
BPTR intuitionseg = LoadSeg32("SYS:Libs32/partial/intuition.library", DOSBase);
struct ResidentV0 *intuitionres = findResident(intuitionseg, NULL);
struct LibraryV0 *abiv0IntuitionBase = shallow_InitResident32(intuitionres, intuitionseg, sysbase);
/* Remove all vectors for now */
const ULONG intuitionjmpsize = 165 * sizeof(APTR32);
APTR32 *intuitionjmp = AllocMem(intuitionjmpsize, MEMF_CLEAR);
CopyMem((APTR)abiv0IntuitionBase - intuitionjmpsize, intuitionjmp, intuitionjmpsize);
for (int i = 1; i <= 164; i++) __AROS_SETVECADDRV0(abiv0IntuitionBase, i, 0);
/* Call SysBase_autoinit */
__asm__ volatile (
"subq $4, %%rsp\n"
"movl %0, %%eax\n"
"movl %%eax, (%%rsp)\n"
"movl %1, %%eax\n"
ENTER32
"call *%%eax\n"
ENTER64
"addq $4, %%rsp\n"
::"m"(sysbase), "m"(seginitlist[1]) : "%rax", "%rcx");
__AROS_SETVECADDRV0(abiv0IntuitionBase, 1, (APTR32)(IPTR)proxy_Intuition_OpenLib);
__AROS_SETVECADDRV0(abiv0IntuitionBase, 113, intuitionjmp[165 - 113]); // MakeClass
__AROS_SETVECADDRV0(abiv0IntuitionBase, 112, intuitionjmp[165 - 112]); // FindClass
__AROS_SETVECADDRV0(abiv0IntuitionBase, 114, intuitionjmp[165 - 114]); // AddClass
__AROS_SETVECADDRV0(abiv0IntuitionBase, 106, intuitionjmp[165 - 106]); // NewObjectA
/* Call CLASSESINIT_LIST */
ULONG pos = 1;
APTR32 func = segclassesinitlist[pos];
while (func != 0)
{
__asm__ volatile (
"subq $4, %%rsp\n"
"movl %0, %%eax\n"
"movl %%eax, (%%rsp)\n"
"movl %1, %%eax\n"
ENTER32
"call *%%eax\n"
ENTER64
"addq $4, %%rsp\n"
::"m"(abiv0IntuitionBase), "m"(func) : "%rax", "%rcx");
pos++;
func = segclassesinitlist[pos];
}
/* Set internal Intuition pointer of utility */
*(ULONG *)((IPTR)abiv0IntuitionBase + 0x60) = (APTR32)(IPTR)abiv0_DOS_OpenLibrary("utility.library", 0L, sysbase);
BPTR graphicsseg = LoadSeg32("SYS:Libs32/partial/graphics.library", DOSBase);
struct ResidentV0 *graphicsres = findResident(graphicsseg, NULL);
struct LibraryV0 *abiv0GfxBase = shallow_InitResident32(graphicsres, graphicsseg, sysbase);
/* Remove all vectors for now */
for (int i = 1; i <= 201; i++) __AROS_SETVECADDRV0(abiv0GfxBase, i, 0);
__AROS_SETVECADDRV0(abiv0GfxBase, 1, (APTR32)(IPTR)proxy_Gfx_OpenLib);
BPTR layersseg = LoadSeg32("SYS:Libs32/partial/layers.library", DOSBase);
struct ResidentV0 *layersres = findResident(layersseg, NULL);
struct LibraryV0 *abiv0LayersBase = shallow_InitResident32(layersres, layersseg, sysbase);
/* Remove all vectors for now */
for (int i = 1; i <= 45; i++) __AROS_SETVECADDRV0(abiv0LayersBase, i, 0);
__AROS_SETVECADDRV0(abiv0LayersBase, 1, (APTR32)(IPTR)proxy_Layers_OpenLib);
/* Switch to CS = 0x23 during FAR call. This switches 32-bit emulation mode.
Next, load 0x2B to DS (needed under 32-bit) and NEAR jump to 32-bit code */

View File

@ -0,0 +1,63 @@
/*
Copyright (C) 1995-2017, The AROS Development Team. All rights reserved.
Desc: Add a resource to the public list of resources.
*/
#include <aros/debug.h>
#include "../include/exec/functions.h"
void abiv0_AddResource(APTR resource, struct ExecBaseV0 *SysBaseV0)
{
ASSERT_VALID_PTR(resource);
/* Just in case the user forgot them */
((struct NodeV0 *)resource)->ln_Type=NT_RESOURCE;
/* Arbitrate for the resource list */
// EXEC_LOCK_LIST_WRITE_AND_FORBID(&SysBase->ResourceList);
/* And add the resource */
abiv0_Enqueue(&SysBaseV0->ResourceList,(struct NodeV0 *)resource, SysBaseV0);
/* All done. */
// EXEC_UNLOCK_LIST_AND_PERMIT(&SysBase->ResourceList);
/*
* A tricky part.
* kernel.resource is the first one to get initialized. After that
* some more things can wake up (hostlib.resource for example).
* They might want to use AllocMem() and even AllocPooled().
* Here we switch off boot mode of the memory manager. Currently we
* only set up page size for pool manager. When memory protection
* is implemented, more things will be done here.
* This allows to use exec pools even in kernel.resource itself.
* To do this its startup code needs to be changed to call AddResource()
* itself. Right after this exec's pool manager will be up and running.
*/
// if (!strcmp(((struct Node *)resource)->ln_Name, "kernel.resource"))
// {
// KernelBase = resource;
// DINIT("Post-kernel init");
// /* If there's no MMU support, PageSize will stay zero */
// KrnStatMemory(0, KMS_PageSize, &PrivExecBase(SysBase)->PageSize, TAG_DONE);
// /*
// * On MMU-less hardware kernel.resource will report zero page size.
// * In this case we use MEMCHUNK_TOTAL as allocation granularity.
// * This is because our Allocate() relies on the fact that all chunks
// * are at least MemChunk-aligned, otherwise we end up in
// * "Corrupt memory list" alert.
// */
// if (!PrivExecBase(SysBase)->PageSize)
// PrivExecBase(SysBase)->PageSize = MEMCHUNK_TOTAL;
// DINIT("Memory page size: %lu", PrivExecBase(SysBase)->PageSize);
// /* We print the notice here because kprintf() works only after KernelBase is set up */
// if (PrivExecBase(SysBase)->IntFlags & EXECF_MungWall)
// RawDoFmt("[exec] Mungwall enabled\n", NULL, (VOID_FUNC)RAWFMTFUNC_SERIAL, NULL);
// }
} /* AddResource */

View File

@ -16,6 +16,18 @@ __asm__ volatile( \
#define CALL_IMPL64(name) \
" call abiv0_" #name "\n"
#define MAKE_PROXY_ARG_1(fname) \
void proxy_##fname(); \
void dummy_##fname() \
{ \
EXTER_PROXY(fname) \
ENTER64 \
COPY_ARG_1 \
CALL_IMPL64(fname) \
ENTER32 \
LEAVE_PROXY \
}
#define MAKE_PROXY_ARG_2(fname) \
void proxy_##fname(); \
void dummy_##fname() \

View File

@ -3,7 +3,52 @@
#include "../exec/structures.h"
typedef ULONG BPTR32;
typedef ULONG BPTR32;
typedef APTR32 BSTR32;
/* Structure used for CLIs and Shells. Allocate this structure with
AllocDosObject() only! */
struct CommandLineInterfaceV0
{
/* Secondary error code, set by last command. */
LONG cli_Result2;
/* Name of the current directory. */
BSTR32 cli_SetName;
/* Lock of the first directory in path. (struct FileLock *) */
BPTR32 cli_CommandDir;
/* Error code, the last command returned. See <dos/dos.h> for
definitions. */
LONG cli_ReturnCode;
/* Name of the command that is currently executed. */
BSTR32 cli_CommandName;
/* Fail-Level as set by the command "FailAt". */
LONG cli_FailLevel;
/* Current prompt in the CLI window. */
BSTR32 cli_Prompt;
/* Standard/Default input file. (struct FileLock *) */
BPTR32 cli_StandardInput;
/* Current input file. (struct FileLock *) */
BPTR32 cli_CurrentInput;
/* Name of the file that is currently executed. */
BSTR32 cli_CommandFile;
/* TRUE if the currently CLI is connected to a controlling terminal,
otherwise FALSE. */
LONG cli_Interactive;
/* FALSE if there is no controlling terminal, otherwise TRUE. */
LONG cli_Background;
/* Current output file. (struct FileLock *) */
BPTR32 cli_CurrentOutput;
/* Default stack size as set by the command "Stack". */
LONG cli_DefaultStack;
/* Standard/Default output file. (struct FileLock *) */
BPTR32 cli_StandardOutput;
/* SegList of currently loaded command. */
BPTR32 cli_Module;
/* Here begins the aros specific part */
/* Standard/Default Error file. (struct FileLock *) */
BPTR32 cli_StandardError;
};
/* Standard process structure. Processes are just extended tasks. */
struct ProcessV0

View File

@ -370,6 +370,12 @@ static int relocate
SetIoErr(ERROR_BAD_HUNK);
return 0;
}
else
{
extern ULONG global_SysBaseV0Ptr;
s = global_SysBaseV0Ptr;
}
break;
}
/* fall through */
@ -401,8 +407,14 @@ static int relocate
if ((name[0] == '_') && (strcmp(name, "__INIT_LIST__") == 0))
{
extern ULONG* dosinitlist;
dosinitlist = (APTR)(IPTR)s;
extern ULONG* seginitlist;
seginitlist = (APTR)(IPTR)s;
}
if ((name[0] == '_') && (strcmp(name, "__CLASSESINIT_LIST__") == 0))
{
extern ULONG* segclassesinitlist;
segclassesinitlist = (APTR)(IPTR)s;
}
}

View File

@ -11,6 +11,7 @@ FILES := AoA loadseg32 internalloadseg32 internalloadseg_elf32 \
abiv0/exec/enqueue \
abiv0/exec/findname \
abiv0/exec/openlibrary \
abiv0/exec/addresource \
EXEDIR := $(AROS_C)
USER_INCLUDES := -I$(SRCDIR)/rom/dos