![]() |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Ideas for the futureHere you can find some random and unsorted ideas and possibly impossible improvements which might be considered for inclusion after compatability with AmigaOS 3.1 has been more or less finished.
MiscellaneousAll lists and public structures must be protected by semaphores
A system like the hierarchical semaphores in pOS would be best. Recursive lddaemon
lddaemon should be able to load more than one library at a time thus allowing to open a library which has to be loaded from disk which opens a library in libOpen() which has also to be loaded from disk. The daemon could also search actively for a library allowing the user to specify one if it can't be found. Paths like PROGDIR: should be searched automatically. If the lib can't be found, DOS_OpenLibrary() must create a message port and a message, put the port in the reply-to field of the message as well as the name and min-version of the lib and then send the message to the lddaemon and wait for the reply. Open questions: Will this interfere with the way Exec handles libraries now (eg. single threaded libInit())? Can this introduce deadlocks in the locking of the exec library list? What happens if libClose() calls libExpunge()? Extend on the datatypes concept
Some datatypes-alike system where dataprocessing methods can be added to datatype classes. (Eg. for pictures one could add methods like Rotate(), Flip() and other typical image processing operators. Similarly one can add sound fx methods for sound data). For this to be usefull one should probably be able to add methods to a class one by one (so BOOPSI can probably not be used for this). The objects should contain the data in a raw format so that the methods can easily operate on it. One should be able to stream data in and out of the objects. One could have separate "converter objects" that can convert from a data format (eg. GIF->internal raw image format and back eg. raw->GIF.) So when you want to put a GIF file into an image object the system will automatically search for installed gif->internal raw converters and convert the GIF into a stream of raw image data passed to the image object. These data objects should of course have methods like Show() and Edit(). Edit() could invoke your favourite texteditor/paintprogram/drawprogram/etc depending on the object type. (text/image/structured drawing). Now, should these objects be able to show themselves, like the old datatypes ? Well, IMO they should not be bound to a single operating system/GUI system, but they could maybe show themselves through some RTG system (?). But the viewer could also stream out the data from the object to show. When the object's data has changed, the viewer could be notified and where in the stream the "damaged" data is. (If a text viewer GUI views the first 100 lines of a 100000 line text data object, and the last 100 lines are changed, it wouldn't need to rerender) As mentioned earlier one should be able to use this system on different OSes, and it should maybe also be possible to invoke methods on them over a network or even move the objects in a network (using CORBA?). This way a heavy operation on the data object can be done on a faster machine while you are controlling it from a slower machine. By keeping functionality into small components, 3rd party programmers can easily write freeware additional functionality. (One can add methods operating on the data one at a time.) It will provide very much reuse of code. (Just look around on Aminet: There are whole bunch of different image processing programs that implement the same functionality. This should really only have to be written once). If the system can work on other platforms too, we get even more developers that can support it. I believe that if some system should have any chance at all of taking some market share from M$ it a) has to be free. b) must be available on as many platforms as possible. c) must consist of tiny components that can be added at run-time.=>This way it'll be easier for developers to support it. HIDD Installation
When a new HIDD is installed, it should appear in the list of available HIDDs automatically (eg. by file notification on the directory). Source code converter
We need an automatic converter for the incompatible features of AROS to convert the old AmigaOS code to AROS (which can then be compiled on AmigaOS by our compatibility lib). Comment by Henning KielThe original Amiga Includes used to have an intuition/iobsolete.h AROS wants to get rid of obsolete stuff, and therefore we are not going to include iobsolete.h in our distribution. However, we are intersted in getting software for AROS and this may be old, but useful. So we need a way to support old sources, but in such a way, that the old code will be converted. (Maybe in multiple passes) This conversion-tool should do: (open, unordered list)
select() for AmigaOS file handles
I wanted to have a select() for AmigaOS filedescriptors some time ago, that's why I wrote the AbortPkt() patch which sends an ACTION_ABORT. A select/asyncio handler (AsyncIO.hidd ?) which handles allocation of buffers and IO on multiple handlers could allocate buffers, do multiple reads on behalf of a process and signal the process when input is available. The same would happen for write operations (writing would block when the select handler has queued a maximum of bytes or buffers for a single process). A process that wants to exit could just close the select handler and leave it to the handler to deallocate the buffers when they are returned one day ... Under AROS the handler would be able to use AbortPkt() and under AmigaOS it would be able to use it if the patch is installed and the underlying handler accepts the packet type ACTION_ABORT. The idea reminds me a bit of Unix STREAMS or NT device drivers: both pass packets through several layers of device abstractions. UnixIO could be one layer below the select handler and would translate it to a real select() because the buffer mechanism of the select handler is part of the Unix kernel anyway; so a write would block when the kernel buffers are full, as usual. Cache memory
I'm thinking about something called "cache memory". It should use all free memory to store "nice to have" data like for read ahead or write through caches for disks and harddisk or a printer spooler. This memory is allocated by special functions. It doesn't appear in the "memory used" list but is added to the amount of free memory. Besides allocation and freeing there are two special cases. The simple one is that some other application needs the RAM, so parts of the cache have to be purged. The other one is to avoid memory fragmentation. It's not possible or useful to use all the free memory for caching. So the cache should always be one large block divided up in several smaller chunks. If an application needs memory, parts of the cache have to be freed or they have to be copied in unused chunks (eg. it's still faster to copy 512 bytes than to read them back from HD or a printer spooler should not throw the spooled data away). Double Buffer windows
The Amiga has the Smart refreshed windows that uses an own bitmap and the Simple, that need to be refreshed because it uses the screen bitmap. I want a Double Buffered one. A simple refresh window where you allocate a bitmap and a rastport for it, and this will be send to window on Refresh (or in window's BackFill Hook) and when the Draw of All Buttons are finished, so you don't get "flickering" (I don't know the correct word) on the graphic, and uses almost the same memory of a Smart one. Child/sub windows
The Amiga needs a function for opening windows into other windows like on windows. The "Requester" does this, but stops the functionality of the window, and doesn't have all Attributes of a real window. This or something like this is needed for buttons which are over others, so the graphic of the "bottom" one will not pass over the front one. And can be created new functions for opening Windows/Screens, so you can convert a window into a screen, create Public Windows and open other windows on it... Comment by Aaron DigullaThis is dangerous; it uses a lot of memory, adds many IDCMP event loops and the same effect can be achieved when using clip regions; all we have to do is to make the gadgets public, which render a window, plus maybe a BOOPSI subwindow class which installs a clip region in another window. Comment by Bernardo InnocentiI would like to extend Layers and Intuition to support child layers. Basically, since V37 and upto V40 Intuition has undergone a major philosophical rearrangement. The old structure-centric way of doing things has been replaced by an object-centric fashon round the concept of boopsi classes. Gadgets and images have been hit first by this new technology. Windows, menus and screens would have had to, but for some reason it did not happen (lack of time or compatibility issues). If windows were boopsi classes, you could override their default behaviour simply by subclassing them. Some months ago I had a very interesting technical discussion around this topic with Massimo Tantignone, author of VisualPrefs. We talked about a possible design to implement child layers in a semi-compatible fashon, which would allow nested windows as well. The current Intuition already has some features (implemented in a non-OOP fashon) which simulate nested layers. These are GimmeZeroZero windows and requesters. Screens could be considered containers for windows, thus adding another level, but hierarchy stops here. There are ugly design asymmetries that prevent you from drawing in a Requester the same way you draw in a window and other similar problems. I must admit that in this field Windows has a cleaner design (please don't kill me). A window is just a rectangular clip region and everything from menus to buttons is represented by a window. Dialogs and frame windows are just two special kinds of windows that are attached to standard window borders and system gadgets. X11 has a very flexible concept for window borders. Insead of belonging to the application, the borders are drawn and refreshed by the window manager, which can even replaced at run-time. Comment by Georg StegerChild windows could be done similiar to MUI's virtual groups = with InstallClipRegion. Unfortunately InstallClipRegion in AmigaOS can be very slow and in case of SMART REFRESH windows also eat terrible lots of memory (hidden areas in the worst case might be backuped three times!!) because it is optimized for: one installclipregion --> many render functions --> one installclipregion instead of: many installclipregion with few render functions inbetween. It's also bad that there is no additional rastport-based clipping. Actually the gfx-functions don't know anything about a clip-region (or beginupdate state), they just clip to the cliprect list in layer->ClipRect. For AmigaOS maybe it would be easier to not add real child layers, but only child windows, which layers.library does not know about. I would also limit the child windows to SIMPLE REFRESH (and maybe SUPERREFRESH) type, as SMART REFRESH child windows would probably be too slow, and SMART REFRESH layers are the most complicated ones anyway. One would need special funcs for GetMsg/ReplyMsg on win->UserPort similiar to GT_GetIMsg and GT_ReplyIMsg from gadtools.library. This funcs would filter certain messages, for example divert IDCMP_MOUSEBUTTON to the correct child window or "add" additional IDCMP_REFRESHWINDOW messages for example because of damage resulted from a MoveChildWindow which would first add this message to a private ChildWindow port. A ??_GetMsg(realwindow->UserPort) would therefore also return messages from private ChildWindow ports. For rendering into a child-window (assuming non-SMART child windows only) I would use something like this:
ObtainChildWindowRastPort(childwindow)
{
LockLayer(realwindow->Layer);
save realwindow->Layer->ClipRect somewhere
create a realwindow->Layer->ClipRect list based on:
childwindow->visibleRegion AND visibleregion must be calculated here *
childwindow->clipRegion from a InstallChildWindowClipRegion() *
}
ReleaseChildWindowRastPort(childwindow)
{
restore realwindow->Layer->ClipRect
UnLockLayer(realwindow->Layer);
}
BeginChildWindowRefresh(childwindow)
{
LockLayer(realwindow->Layer);
save realwindow->Layer->ClipRect somewhere
create a realwindow->Layer->ClipRect list based on:
childwindow->visibleRegion AND visibleregion must be calculated here *
childwindow->clipRegion AND
childwindow->damageRegion
}
EndChildWindowRefresh(childwindow, done)
{
if (done) childwindow->damageRegion = EMPTY
restore realwindow->Layer->ClipRect
UnLockLayer(realwindow->Layer);
}
Creating Layer->ClipRect lists for non-SMART REFRESH child windows is easy as you never have to backup hidden areas, so it is basically an AllocMem and setting some coordinates. But if you want child layers for the actual AmigaOS, then you can only replace layers.library completely, but not Intuition for which you need special functions for MoveChildWindow, SizeChildWindow, ... which know about the child layers. It is not a good idea to patch the normal MoveWindow, SizeWindow, ... because child layers really need special functions like HideChildWindow, MakeChildWindowVisible. Comment by Bernardo InnocentiThis would make child layers very different from normal layers. You woudn't be able to render inside them using exactly the same code, which is bad because authors of boopsi gadgets would have to take special precautions to support child layers. The same is true for requesters: have you ever tried to add boopsi classes to requesters? Well, you would find out that most of them won't work because of bugs in both Intuition, the gadgetclass and the subclasses. I meant REALLY implemeninting child layers and child windows, not just faking them with some clever patch. Each child window would just get its own Layer structure and layers.library would have to be improved to take children into account when depth arranging or moving their parents. I was thinking about something like this:
struct Layer
{
struct Layer front, *back;
[...]
struct Layer parent, *children;
};
Where "parent" points to the parent (NULL if it's a top-level layer), and "children" points to the frontmost child layer (NULL if there are none). Children are chained together with front/back pointers in the same fashon of normal layers. This way you wouldn't need to install any additional clip regions before rendering. That's exactly like window requesters: they are just a limited special case of child layers. The main weak points of the requesters design is that you can't nest a requester into another requester, and you must use a different set of functions to manage them. Furthermore, you can't move or depth-arrange requesters. If these limitations could be removed by implementing child-layers in a simmetrical OOP fashon, you would just use Open/Close/Move/SizeWindow() on them. Another important improvement that could be done quite easily is turning Layer and Window structures into white-box instances of boopsi objects, like it has been done for Gadget and Image structures. Then the old-style functions (Open/Close/Move/Size/Window()) would just build the appropriate boopsi message and invoke the dispatcher. The same technique has been used to add boopsi support in pre-V36 functions such as ActivateGadget() and DrawImage(). Of course these ideas would require mayor reworking in both layers and Intuition, but I bet it could be done without breaking the current API and OS structures, so that unaware applications would continue to work as usual. We wanted to submit our draft proposal to the AmigaOS developers for comment. If we could convince them of taking this way for the next Kickstart release, we would have no reason for patching or replacing layers.library at all. Comment by Georg StegerRequesters aren't child windows/layers in any way. For layers.library there is no difference between a requester layer and a window layer. It's just Intuition, which when moving or depth-arranging a window, additionally to the window layer also moves/depth arranges the requester layers of a window. If you tried to directly call MoveLayer (I know, it's not allowed) on a requester Layer you would see that you can easily move it out of the (not so) parent Window's layer or depth arrange it behind the parent Window's layer. The only thing layers.library would have to do in such a case is add/remove damage to the child windows (whose coords are relative to parent window) that are non-hidden, right? Or do you think child layer cliprects should be re- "calculated" immediately as well, like what is happening with the normal layers. With the ObtainChildRastPort, ReleaseChildRastPort I was talking about this would not be done (= faster moving of top level layers) but instead ObtainChild- RastPort would take care about it = you have precalculated cliprects (= fast gfx functions) until you call ReleaseChildRastPort. It is not a good idea to patch the normal MoveWindow, SizeWindow, ... because child layers really need special functions like HideChildWindow, MakeChildWindowVisible. Comment by Bernardo InnocentiWe don't really need any special code for child layers: top-level layers would just be a special case of child layers whose parent is the screen layer_info. This asymmetry is bad, but you can't do anything about it because layer_info must be ratained for backwards compatibility. Instead of adding adding a new set of functions to layers.library, we would have rather implemented it through boopsi classes. Layers could be turned into white-box boopsi objects (i.e: have a pointer to the class at a negative offset from the Layers structure and optionally additional instance data after the old-style structure). Then most of the current layers.library code would be moved inside the dispatcher of this new "layerclass", and the old functions would become stubs for call the respective methods. I think that would be a clean and extensible design for OOP layers. Optionally they would have to clip the children to appear "inside" the parent when they are partially outside the edges of their parent. Look at Microsoft's MDI interface: if you open Word and move a document window outside Word's main window, it gets clipped inside it. Perhaps we could get the same effect of child layers without touching the layers.library at all and doing OOP magic on Intuition windows instead. What if the Window structure had a pointer to its parent window and a linked list of children? Again, Intuition's Move/Size/OpenWindow() would have to be extended to support child windows in a OOP fashon. Comment by Aaron DigullaMoving this into Intuition looks most clean to me. Basically, what will happen is that you get a window which moves with it's parent and where the code which calculates the size of the window (or the cliprect for it) takes the size and position of the parent window into account. That should work best and looks simple enough to me to work. Comment by Bernardo InnocentiOn a second thought, there would be some hard-to-solve efficiency and aestetic problems when child windows are implemented without the help of the layers.library. I think it can be explained better by showing a piece of pseudo-code:
MoveWindow(struct Window *w, int x, int y)
{
[...clip coordinates inside screen...]
move window layer (relative to parent) *
MoveLayer(w->WLayer, x + w->WParent->LeftEdge, y + w->WParent->TopEdge);
#ifdef INTUITION_CHILD_WINDOWS
struct Window *child = w->WFirstChild;
while(child)
{
MoveWindow(child, child->LeftEdge , child->TopEdge);
child = child->NextWindow;
}
#endif /* INTUITION_CHILD_WINDOWS */
[...check for damage in ANY layer on the screen and send refresh
notifications...]
}
Here we recursively call MoveWindow() on each children to adjust their relative position. Since MoveLayer() knows nothing about child windows, the effect you will see on the screen is:
This scenario is awful and must be absolutely avoided. A clever workaround could be adding a very complex function in layers.library such as MoveMultipleLayers(), which takes a linked list of layers as an argument. I can't imagine what kind of efforts this function should do to move all the layers at once in a way that minimizes damage. For sure, it would be rather complex to write. EnqueueTail
exec.library can have an EnqueueTail, and this is easy to do, so the Enqueue already exists. Refresh only once
Intuition should not send more than one REFRESH message to a window (ie. if there is already one in the queue, then it should be removed first). Clever OpenLibrary
OpenLibrary(), etc. should check for libraries in various places. It should be possible to add paths for these and similar functions and there should be a tool which checks and tells which library, etc. would be opened (eg. the path is libs,PROGDIR:libs,libs: and there is a x.library in libs and libs:. The tool should tell which one is opened and why (ie. loading libs:x.library over libs/x.library because: libs:x.library has version 41.0 and libs/x.library has 39.20). Special write protection for libraries
It should be possible to protect some files (like libraries) so that you need to call a specific OS/FS function to replace them. This would allow to fix all problems with tools replacing libraries with old versions. Maybe even a patch to Open() would be enough which checks if someone tries to write in a specific directory and calls a tool which checks if the write is ok. This is of course a bit dangerous. Memory protection
Stuff we spoke about over lunch, dating back to our days consulting for Amiga Technologies. Andy mentioned the model they use for the 3DO operating system (the original one, not the M2 version, which is supposedly more like the BeOS). In this system, each process has its own memory map, but the actual mapping is still global (eg, there's just one memory space). Your process can see the rest of the world as read-only. Functions like AllocMem() transparently work from local memory pools attached to your process, so things stay nicely page-aligned. This has the secondary effect of making AllocMem() faster than it is today, since you only have to involve Exec proper (locking the system up to keep things atomic) every so often, not at every AllocMem(). I would make the extension to this that memory contexts become first-class Exec objects. The System context would be the "root", with read/write access as we have today. Device drivers that need the direct access to hardware, or the performance of using references rather than copies, could be started on this context. You could build alternate contexts, such as the read-only underlay, as mentioned, or even fully private memory spaces, as in UNIX. Obviously this is for new code, and Exec would need to add/enhance functions for sending messages, copying, etc. between memory spaces. But since you're not expecting any old code to run in a fully separate space, some of today's bad habits wouldn't really be an issue. Installer as a library
Maybe we could rewrite Installer as library, which provides functions that are currently contained in Installers language. This would allow programmers to easily write Installer scripts in their prefered programming language, instead of learning Installer's own language. While doing this, we could also add methods to uninstall an installed package. Installing AROS in PC BIOS
There should be a tool to create a kernel which can be put into a Flash ROM or EEPROM or a boot file. The tool should be able to fix all absolute addresses in the kernel, it should be able to create the resident tags or a simple file system which allows the boot loader to find, load and init all parts it needs. The main reasons for this are: When you add a new driver (eg. a harddisk controller), you don't want to have to install a C compiler just to be able to boot from it. The ordinary user just wants to call a "install driver" tool which does all the work without him worrying. Also to reduce similar code, the boot loader will probably use the same code to load drivers as will the OS. So the "file system" which is visible to the boot loader must be similar to what the OS sees. This becomes more important if some driver in the ROM is not loaded/inited during booting. Then the OS will use its normal ways to search for the driver and at this time, the driver must be visible by some file system-like means or the searching for it will fail. Separate implementation and interface
An idea just stuck me which might safe us a lot of trouble. We should separate the code from the interface. Code is here: The code for the ROM libraries and interface is here the Exec shared library interface. As you might remember, I dream about AROS as native emulation (ie. compile Amiga apps which run as native apps without arosshell). Most of the problems we have right now (eg. in the mmakefiles) come from the fact that we can't use the systems' own way to work with shared objects but that we try to emulate Exec's way. IMHO, it would be much better if we did this: exec becomes a plain exec.lib which contains normal functions. Then we create an interface for these normal functions and this interface can be accessed as exec.library. All we have to do now is to link the interface with the standard library. If we don't need the interface (eg. because we have a cool autoinit feature like the dynamic loader from Unix), we can omit it. This way, we could separate the amiga-specific parts of AROS much better from the portable parts. Also, it would be possible to create different interfaces much better. And the interface wouldn't be intermixed with the portable code as it is now. Configuration Database
Ok, since the topic has been brought up: Here is something which I'm missing in the current config DBs/registries: There should be a way to keep histories of configurations plus "commit logs". Basically, the whole config should work with CVS. That would make debugging much more simple (just throw anything out and when it works again, do a diff to see what has changed). It would also answer the question "why did I disable that" ? And with tags, you can name stable states of the config and switch between them. Better debug support
Debugging in AROS is becoming harder as we add new functionality and the system becomes more complex. So we need more debug support in AROS. Here are some misc ideas: Debugging memoryI'm thinking of adding some tortures into AllocMem(), FreeMem() and possibly other system calls to encourage buggy code to crash. Mungwalls around allocated blocks would be another great thing. Asserting everywhereTo reach rock stability we must put all kinds of validity checks everywhere in the code. Please everybody start using those ASSERT_#? macros and create new ones for checking structures which may need further checks. I'm planning a ASSERT_VALID_LIST() macro for checking Exec lists against dangling pointers, infinite loops and succ <-> pred inconsistencies. Implementing complex checksSome of those macros might become too big to put them always inline. We may need to add some support code into exec.library or perhaps arossupport.library. Some I already feel the need for are _kassert() and _kbadpointer(). Diagnostic dumpsThe need may arise to dump some system structures in a human-readable format to help debugging. I've done some DUMP_#?() macros (such as DUMP_LAYER(l) to track bugs in my own programs in the past, but I would like to turn them into functions because they are usually too big for inlining. Tracing supportAssertions in functions such as AddNode() would be pretty useless without some facility to trace back the call stack down to the caller. A single level might not be sufficient and gdb can't be used to debug programs loaded by LoadSeg(). Unfortunately, this is a very CPU-dependent feature and I have no clue of how it should be done. Trapping exceptionsWe might benefit by implementing an handler to trap seg faults and other exceptions. This could dump the CPU registers and trace into the stack. Hits could be tracked down to the module responsable for them by adding SegTracker-like functionality into LoadSeg(). Stack tracebackWe need to provide a CPU-dependent support function to unroll the stack to help tracking the origin of a bug. Seeing that AddNode() got an illegal node pointer is no big help if you don't know where AddNode() has been called from. Tool to show the number of missing/unimplemented functions
The idea is to have a software which scans a software for AmigaOS functions and reports those which are not yet implemented. LibBase should become first argument of all functions
I would like to put LibBase as first argument for every function in every library (like in real classes). Then with __attribute__((regparm(1))) we could force compiler to pass first argument (would be LibBase) through register instead of stack. Use pipes instead of files to compile
Could we have some of this autogenerated files like "functable.c" and "endtag.c" be generated and compiled on the fly by using pipes: ~generate this files to stdout and make gcc compile from stdin? -> no more functable.c and endtag.c files on disk -> speedup!? Comment by Fabio Alemagnagcc cant accept source files from stdin. It can do that only if the switch -E is given too, that means only preprocesig is being done. In order to do that you should call cc1 manually and handle all the rest (preprocessing, switches to pass to cc1...) manually too... Native compiler for AROS
Maybe lcc would be the easies compiler to port to aros? You can find lcc at http://www.cs.princeton.edu/software/lcc/ Build Shared Thingy
AIM: The 'Build Shared Thingy' is intended to be a tool to generate all sorts of shared binaries in a common way. It should be only given a directory and produce the shared bin out of it -- or at least generate C-code which then only needs to be compiled. It might read in some global config file which contains info on the system (OS/Hardware). Mainly the tool is intended to make generation of libraries easier, but it should be also possible to create HIDDs, etc. with this tool. 'How does shared library creation work?' THINGS IT MUST DO: We must have an archive with all the functions code and the specification of the interface (ie. return-value and parameters like #?.arch), so the tool can create the library-functions itself. There must be a way to substitute system/machine-dependant functions like a dir-tree in AROS/machine/linux-i386/rom/dos for linux-i386 specific functions which will replace std or will be added to AROS/rom/dos. We must provide a short description of the library (ie. Name, LibBase, LibBaseType, Version, options like lib.conf). The tool must provide standard init, open, close, expunge and null functions, which can be overridden or better: you provide an abstract description of what is to do (ie. library dependencies, initializing code, etc. -- the tool then will create the code on its own). Archtools functionality (inherited from the gawk scripts) must be given: generate includes, merging archives, etc. AutoDocs should be integrated, too, since they are closely connected to the sources. Comment by Iain TempletonThis is the text of the file tools/buildshared/README, which I have removed and put the content in this file. It turns out that some of this functionality is implemented in the tools/genskeleton directory, and some in the new Python based archtools that Aaron Digulla has been workin on. Virtual Desktops
Enhance Intuition to support virtual desktops. This should be easily possible with the (hyper)layers.library and the ability to make layers and windows invisible. Windows by default are opened on the currently active virtual desktop, which is identified by a 32 bit identifier in the screen structure. If windows are to be opened on a different desktop this can be specified with the WA_Desktop tag when the window is opened. WA_Sticky allows to make the window sticky and it will appear on all desktops. Desktops could be identified by a bit, thus making 32 virtual desktops available on a screen with the previously mentioned 32 bit identifier. The sticky flag would therefore select the desktop identifier 0xffffffff. The window and screen structures would have to be extended with a ULONG field. Enhance Intuition with function DisplayDesktop(screen, desktopnum). The technology is out in the public with the X window system, although there is a patent on this afaik. Intuition ideasWorkbenchIn general workbench has to be reworked, made more accessible to the programming community for enhancements or even replacement.
Programs to consider for inspiration: + DOpus 5.11 + Toolmanager + Toolsdaemon IconsDiskObjects should be treated like objects, icon.library should have functions for renaming, copying, deleting, moving, loading and saving. For optimizing purposes there has to be functions for saving and loading all the icons of a drawer at once. This will allow experimentation with different icon storage schemes without many varients of icon.library. The DiskObject structure needs an extended image structure to handle palettes, multiple frames (over 2) and possibly aspect ratios. Icon storage format should be ilbm anim plus an extra block for non image icon data. This is to go further along the road to being able to use a paint program to edit icon images, more important when considering animated icons. DatatypesDatatypes should encompass more than just images for gadgets. What about are more differenciated datatypes scheme for the new os... as follows!? datatype - load-smallest-element (codec) - load-all - save-smallest-element (codec) - save-all - view (gadget) - operators
This would add the following features:
Imagine a texteditor:
You could use it to view text, but also to edit texts. And even better only viewing texts would mean that only loadtype and viewtype will be loaded, but not the operators and editor.subtype Hmmm, I am getting a bit confused with the slang... is it a subtype, a datatype sub class or what... :-) A new prefs accessing scheme could be implemented this way...
An in SYS:Prefs only the starters of all this in global mode.
main()
{
OpenLibrary("inputprefsedit.class",bla)
execute the edit function via a single call... (DoMethod?)
CloseLibrary(bla)
}
thats it, for one prefs program... all is modular... But could such a scheme be implemented without to much overhead??? GadtoolsThe functionality of gadtools should be just a top layer on top of boopsi, if not made obsolete by a layout system. It could do with a lot of improvements, most importantly though would be allowing people to remove gadgets from windows!
e.g. I would remove gadtools completely, or leave it there for compatibility reasons, but I wont enhance it, I would simply replace it with a better BOOPSI implemention... PreferencesMore preferences programs!
GUIThe operating system needs a layout system. Such a layout system should be as deluxe as the user and the programmer would like it to be or as streamlined and efficient as they would like it to be. A similar system to BOOPSI or enhancement to BOOPSI, class related with multiple inheritance and progressively complex classes that they user can choose via preferences which one to use.
Layout library references: - MUI - BGUI - TritonGUI - ClassAct Class Based LibrariesThere are several issues to be dealt with when considering adopting a class system for the amiga system libraries. One issue is fall through, if you call a library looking for a paticular function but it exists only on it's parent then the parent library has to be opened and checked for the function as well. There is the issue of what to do when a library is missing in a class based system. There is also the issue of how the user can select less complex or more complex libraries via preferences. In order for a class system to be applied to libraries additional information has to be present within the libraries themselves:
How would this work?This scheme could be implemented with a modified OpenLibrary() function or a new OpenLibraryTags() function with a matching CloseLibrary(). Upon opening a library (newly opened), the function could fill in the flag entries of any child library table with the apropriate values from that of the parents of the child library. (Talking single inheritance here). Example:
OpenLibraryTags() would return a pointer to the base of a new table formed like so:
The issue of how the user would be able to select one gui class or another is up for debate as well, any ideas? Misc thoughtsIf you open "Intuition.library" then you won't get any of the sub lasses of "Intuition.library" and if you redirect calls to it to something else you screw up the fall through aspect and get into looping. If OpenLibrary() just accepts "Intuition.library" as a flag instead of a filename to open and the actual Intuition.library is renamed to intuitionroot.library (Example) then this idea would be workable. A prefs program would setup child libraries to replace root libraries in a database for OpenLibrary(). This has a problem with only getting overrided functions in child libraries, no new functions. Good solution for setfunction though. If apps call child libraries directly then apps have to check to see if they exist and if they don't call a simpler class of library. This gets into not knowing the siblings of a paticular child class. Some standard naming perhaps could solve this or a global table of hierarchy that apps could check which could be adjusted via prefs by the user. Requires bullet-proofing. One possibility would be using the tags system of amigaos to check for advanced features akin to termcaps in unix systems. Overrided functions could be unloaded, but then they would have to be reloaded if another app loaded a child library that didn't override the unloaded functions of the parent library in question. I think that would be a good idea... partially library loading... only non overridden function will be loaded from the parent library. From practical experience with this type of system, you will find that the entire parent libraries will be loaded all the time anyway. It depends on the amount of classes being used. There is also a feature of this kind of system that you can call the parent function that your child function has overrided, this removing the need to duplicate the code of the parent function in its entirety. In amiga terms it would be like a setfunction() that wedged into a vector, did something and called the original vector. Or call the original vector first then do something. With libraries like intuition and graphics etc, they are generally loaded all the time anyway. One could make a case of making exec the root library of this system, Intuition a child of graphics, layers a child of graphics as well etc. The thing about this system is that the root library remains pretty much the same as before, just a parent field added. We need exact implementation details and programming directives or we will end up in a mess... Any child library has to have a vector table equal to or greater than that of its parent. This is to avoid overriding a function of grandparent where the parent vector table doesn't extend as far down as that of the grandparent. You could program around that, checking for vector table sizes but why bother with the headache? Standard library names for child class libraries. Intuition.library would be the simplest, Intuitionchild1.library would be the next up, Intuitionchild2.library would be the next up (Example). Via prefs you select which real library would go into each class, Intuitionchild1=MUIclass.library for example. Each standard would have to have a set API of course. If a new library wanted to implement a new API they could start a new standard class, ie. Intuitionchild3.library but would have to include the API of the parents, ie. Intuitionchild1, Intuitionchild2, and Intuition. Any ideas on a naming system? The system should get tag based whereever possible... I mean it the following. Dont let any _new_ program spy the system structures... NEVER. For the old programs, give them a fake of the needed structures as emulation. There should be function like GetTagList(object, taglist), SetTagList(object, taglist) everywhere. Exceptions from this rule _only_ where needed for efficiency. This way you dont have to rethink how to keep the system compatible with older software all the way... Just change anything you want, as long as you can provide the old tags... GeneralAbtraction and modularization is the name of the game. More power and more choices. Modularization:
advantages of this concept described in some examples:
PPaint, Wordworth, ADPro, Superview and others already have such concepts, but they are using different implementations not compatible to each other. Memory protectionWHAT IS ITMemory Protection (or short MP) means that you want to protect vital system structures against hostile programs or bugs. HOW AROS DOES ITAROS uses several different strategies to implement MP depending on the overhead for the resource. If you want more speed, you can disable this schemes altogether. AROS will then run without MP. For compatibility reasons, memory allocated with AllocMem() or similar (with or without the MEMF_PUBLIC flag) the memory may be read by and written to by every task. If you want memory which other tasks can read but must not write to, use the new MEMF_SHARED_READ (Tip: if you have put some effort in making your code use the MEMF_PUBLIC flag for this kind of memory, just #undef MEMF_PUBLIC and define it anew as MEMF_SHARED). The new AROS flag MEMF_PRIVATE makes memory inacessible for other tasks. NOTE: Memory which is currently not allocated by anyone, is protected like MEMF_PRIVATE. OTHER WAYSAROS has two more ways to protect your memory. You can change the protection for memory allocated by you with: MP_SetProtection (APTR memory, ULONG size, ULONG protection); The protection might be:
NOTE: If you call libraries, they may access your memory like you (because they can be thought of sub-functions) but there are some cases where a library doesn't do the work themself. A good example is PutMsg() and ReplyMsg(). This is how messages work on the AmigaOS:
Important are the steps 1, 2, 5, 6, and 7. Since ReplyMsg() always needs to write to your MsgPort, you must allocate it either with MEMF_PUBLIC or with the call to CreateMsgPort() (recommended since it will work on future versions of the OS, too). The same applies to the message since ReplyMsg() must remove the message from the MsgPort you sent it to and attach it to your MsgPort. So it does NOT matter if the other task needs only read the message. A message must always be allocated with MEMF_PUBLIC. If you need additional protection, for example if you are debugging the code, you can use MP_SetProtection() to protect specific parts of the message, but you should not use this function in the final version of your application since it uses lots of ressources. MMU Library/ResourceMMUInfo * MMU_QueryInfo (void)
MMUContext * MMU_NewContext (void) Create a new MMU context. There is only one context for your whole task, so if you call this function more than once, you will get the same pointer again. But note that you must pair MMU_NewContext() and MMU_DeleteContext() calls. void MMU_DeleteContext (void) Delete the MMU's context. Must be called as many times as MMU_NewContext() was called. ULONG MMU_Protect (MMUContext mmuctx, APTR Memory, ULONG Size, ULONG Mode, struct Hook * Hit)
APTR MMU_AllocMem (MMUContext * MMUCtx, ULONG Size, ULONG Flags, ULONG Mode) Is a small utility routine to allocate some memory with the mode already. Use MMU_FreeMem() to get rid of the memory again. The protection will be cleared then. The function will pool requests with the same protection flags. MMU_FreeMem (MMUContext * MMUCtx, APTR Address, ULONG Size) Free memory which was allocated by MMU_AllocMem(). The horribly complex make process, part III :-)As mentioned before the make process has to have the following properties:
My suggestion, as outlined below, is based on using a single makefile concept. This allows it to fit the second and third requirements, whether it fits the first (and probably most important) requirement is yet to be seen. How does it work?In order for this to work, every code module that can possibly build something should define a file called Makefile.inc[1]. This file will be conditionally read into the make process by some rules defined in the file $(TOP)/config/$(ARCH)-$(CPU)/Makefile.inc. This makefile is specific to the target operating system. As an example, this is what a FreeBSD system might have (for the moment not considering any device drivers):
KERNEL_MODS :=
aros battclock boot dos exec expansion filesys hidd graphics \
intuition keymap layers mathffp mathieeesingbas oop timer \
utility
kernel : arosshell
This variable will be taken by the main Makefile with a construction something like this: arosshell : arosshell.c $(foreach f, $(KERNEL_MODS), $(LIBDIR)/lib$(f).a) So by calling make kernel, you will automatically build all the required kernel modules. Not that the kernel target here is a control target, rather than one which actually builds a file. Because the kernel can take different forms under different kinds of system (it might be a monolithic kernel under an emulated system (ie arosshell), or some kind of dynamically loaded thing using a bootloader). Basically its a lot like the old MetaMake system, but without the extra program. What about machine dependance?This is where it gets tricky. Now the problem before was that the makefiles for all the different directories had no way of determining what files to add to where. Because now everything can be seen this is considerably easier. Take for example the exec.library; this needs a number of files which are dependant upon both the host CPU and the host OS, assuming that a file in the $(ARCH) directory is more important than an equivalent file in the $(CPU) directory, we can do the following: FILE_PATHS := os/$(ARCH) cpu/$(CPU) kernel stub vpath vpath %.c $(foreach f, $(FILE_PATHS), $(TOP)/src/$(f)/exec) -include $(TOP)/src/os/$(ARCH)/Makefile.inc $(TOP)/src/cpu/$(CPU)/Makefile.inc This will tell it to look in the $(ARCH), $(CPU), machine independant and finally the stubs[2] directory. This allows us to specify all the of the functions in the src/kernel/exec directory, and if a file exists in one of the machine independant directories, the use it instead[3]. There are also makefiles in these directories in case we need to add any extra files into the build, which is simply does by putting them on the right hand side of a special target. This will probably be slightly different because we wish to give priority to a %.s before a %.c if they both exist in the same directory. Note that we clear the vpath before each new module because we want to make sure that we don't get any name clashes from different modules. Different kinds of buildsHow does it handle different kinds of builds? Basically in the same way that we do at the moment. If we are building to a link library then the kernel-exec-linklib target is referenced, otherwise we would build the kernel-exec-module target. Problems with this systemThe problems with this system, whilst not catastrophic, are at least rather annoying. The biggest problem comes from no longer being able to redefine variables like $(CFLAGS), $(INCLUDES), etc. The reason for this is that the values of these are not substituted until they are used, ie when make actually runs the command to satisfy a rule. So if we declare CFLAGS in kernel/exec, but again in workbench/c we will actually get the workbench/c version in kernel/exec, because the rules will not be run until after the workbench/c makefile has been processed. This is rather annoying, but can be fiddled with judicious use of genmf and really horrible variable names (make doesn't care about the names, so we could have a variable like: WORKBENCH_C_CFLAGS := ... with later on:
$(OBJDIR)/%.o : $(CURDIR)/%.c
%compile_q opt=$(WORKBENCH_C_CFLAGS)
If you don't actually need to change the options to a build rule, then you don't have to define a command, since there can be one defined that will compile what you want, this is of most use in the kernel though, where the builds are all pretty much the same (or at least they should be). The vpath mechanism for do machine dependance is also a bit tricky, because it makes the use of archtool much more annoying, since in order to get the correct versions of files, we would need to unpack the archive before we generate the functions.c file. Mind you I don't think kernel functions should be in archives anyway, it makes the editing unwieldy, but I do agree with compiling them that way. Archives of course are of great use for OOP classes though, although again you would have to unpack and recombine in order to get the correct versions if you have to do vpath stuff (which for most OOP classes is silly, because they will already be machine dependant ie HIDDs). Biggest ProblemThe biggest problem with this is working out where to start, since it is a large task. Do I just copy all the makefiles from the MetaMake variant, and try and fix up the problems mentioned above? To be honest it is probably a multiple person job, and will probably mean that AROS will not build for a week or two. Suggested Implementation Strategy
UrkAnyway, that is the most detailed description I can really give without going and doing something, which I can't really do until everybody is happy with the idea.
Other peoples commentsNote that these aren't really in any specific order, mostly because I don't have the enthusiasm to go through it and do a really good job :-) Aaron DigullaWell, I think something between MMake and pure make is neccessary. What we need is basically an IMake-like system: The real makefiles are created with the aid of some tool and then make takes over. This new tool must allow this:
With MetaMake, you download the new package somewhere below AROS/ and just say "mmake" and it gets compiled at the right place and time. [Iain: Eh? I then commented that I could not see a use for this...] Usually, someone adds a new directory and then he has to edit a makefile in one of the parent dirs. With MetaMake, the tool itself searches for its makefiles. This way, you can't forget something and you don't have to do work which can be automated (basically, having to maintain parent makefiles is clumsy and unneccessary). Bernado InnocentiThen But how can you redefine TOP and CURDIR for each file? Consider that make is going to process all them as a _single_ Makefile, and so the variables will just the last value you give them... What about using different variables for each subdir? I mean something like EXEC_TOP, INTUITION_TOP, etc. Since make can't cd to the subproject directory, we don't need a CURDIR variable anymore. MetaMake will also create the real makefile from the template. [Iain's reply: It depends upon where you use them. If you redefine the values at the top of the makefile and use them in the dependancies, then there is no problem, since these are evaluated at the time the makefile is read. Using them in commands is a no no. (Actually $TOP never changes). CURDIR is also useful because it requires less typing, and makes moving directories easier (not that we really want to do that all that much). ] I mean something easy like this: TOP_SUBDIRS = rom workbench demos games -include $(foreach i, $(TOP_SUBDIRS), $(i)/Makefile.inc) Likewise, each makefile will include the makefiles in its subdirectories. This way the user can speed up the build process by doing: make TOP_SUBDIRS=rom Even better, all these #?_SUBDIRS stuff might be kept together in a single place, let's say in AROS/config/config.mk. This way it would be easy to switch the various targets on and off. We could even make each Makefile.inc usable as a standalone Makefile. I mean something like: cd rom/intuition ; make -f Makefile.inc If we need common variables and rules, we could move them into the file AROS/config/common.mk. Each sub-project will then do something like this: .ifndef COMMON_MK_INCLUDED -include ../../config/common.mk .endif (please forgive me, I can't remember the correct GNU make syntax for this). [Iain: That was something like what I intended, except that the rules like TOP_SUBDIRS would be defined in config/$(ARCH)-$(CPU)/Makefile.inc to enable different architectures to build only the things that make sense to them. The idea of each makefile.inc being a standalone file is quite an interesting and useful idea though. ] What??? So you mean that when I'm working on some new Intuition feature I should wait for half AROS to rebuild each time I want to recompile a file? I still think we should absolutely beek the dependencies to a risonable minimum. Anyway, you may not hope to catch all the hidden dependencies, not even using a single Makefile and generating dependencies with mkdepend. Sometimes you change something in A that will break something else in B, even if B is not #include'ing A. [Iain: Yes, but there should be nothing to recompile in all the other directories, you would probably be talking about a very short wait (a few seconds maybe - longer on Amiga's I guess) ]. Well, in AROS there are already a lot of places where we need special compiler flags for some files or some modules. Sometimes it's needed to workaround bugs in the compiler, sometimes because you're going to compile ROM code that needs to be relocatable or perhaps because there are unwanted side effects in some optimizations. [Iain: Each top level directory should have its own set of flags. Ie the kernel, the workbench/c, the workbench/libs etc. ] To show an example of this, note that I had to turn off inlining in the init code of native Amiga libraries because otherwise gcc would elect the "return -1" library entry point as a possible candidate for inlining and would move it last in the code segment. Now I've worked around this by changing the entry point to an integer containg the machine code for "moveq #-1,d0 ; rts", but it's still a horrible hack. [Iain: Isn't there a better way of doing this? I guess not otherwise you would probably have used it :-) ] Unfortunately, when you write an OS kernel you sometimes _need_ to use hacks. This is also true for NetBSD and Linux. [Iain: But I'd like to see as few of these as possible. FreeBSD has ONE set of compiler flags for everything and still manages to compile. ] Yes, it has been done like that in NetBSD. They also define DEBUG to a number such as 1, 2 or 3, each identifying a different level of verbosity. Then they use macros such as TRACE1, TRACE2 and TRACE3 that will only produce debug output if DEBUG is defined to be greater or equal to that number. We could have something like DEBUG_INTUITION, DEBUG_EXEC, and so on. If we implement function level debugging, we should make sure that defining DEBUG_EXEC also turns on debugging on ALL Exec's functions. We can obtain this effect with a very complex trick:
#ifdef DEBUG
#define DEBUG_EXEC
#endif
#ifdef DEBUG_EXEC
#ifndef DEBUG_EXEC_CacheClearE
#define DEBUG_EXEC_CacheClearE
#endif
#ifndef DEBUG_EXEC_OpenLibrary
#define DEBUG_EXEC_OpenLibrary
#endif
...
#endif
Is there a better way? Or, is it possible to autogenerate this stuff with some clever script? [Iain: Lets hope so] BootingA slightly different topic which has also come up during this discussion is that of how to load AROS into memory. Currently there are two ways in use. The first is a monolithic kernel like used by Unix systems, the other method is to add entries into the system using the existing Exec, but this will obviously only work on Amigas. I like the idea of a bootloader as now exists in FreeBSD, which is loaded into memory, parses some kind of configuration file, loads all sorts of things into memory, then commits suicide after jumping to the kernel entry. The thing about this is that it could be used on many different platforms if written properly - simply separate the MD and MI parts. I mean we could even reuse the InternalLoadSeg_XXX() code with a bit of trickery (well actually by expanding the interface to include things as symbol table loading for debugging). Anyway, here are a few comments from other people: Aaron DigullaIn reply to Iain, > What problems could we have. Easy the suggested structure here would mean > that drivers are loaded into AROS after it has already started. This > means basically we need a really clever bootloader for standalone systems, > or some interesting glue code on emulated systems (which mind you is > the way to go in my opinion). What should be the problem ? AROS can load modules... if the harddisk driver is already available :-) I think QNX uses something like this: They have a primitive NVRAM "harddisk" emulator (ie. they can create a filesystem in NVRAM and load things from it) and it should be equally easy to write a harddisk emulator for a filesystem in ROM or in the bootfile. [Iain: The thing about bootloaders is that they often can use the primitives available to other OS's. For example the PC BIOS gives us facilities for reading the hard disks without even having to worry about whether they are IDE, SCSI or whatever. Plus filesystem reading is MUCH simpler than filesystem writing, so you don't need a full filesystem implementation.] Well, I'd like to have a simple filesystem in the kernel because it's most flexible and modular. To create a new kernel, you would create a file, then a filesystem in that file, copy all parts of the OS into it and put the bootloader in front of it. Then the bootloader would only have to contain a very basic initialisation code plus the filesystem. The bootloader would put itself in the list of available modules (the same code would probably be used later to load the other modules when the whole system is up). So the bootloader would be the "kernel" of the OS and the rest would be loaded on demand. [Bernardo: In other words, you are describing the current implementation of the Amiga Kickstart. The bootstrap code is your bootloader, and the rest of the ROM contains all the modules concatenated one after the other. Each one is identified by a magic cookie (the resident tag). You can view this as a very basic ROM filesystem. The boot code will just scan the ROM and collect all the resident tags into a list sorted by priority. I guess this could be done in a regular file too. If you also need to relocate the residents, you could append reloc hunks to the resident tag just in a way similar to executable files. ] Filesystems which are loaded "later" can put themselves before the bootloader which would allow to load newer versions of the drivers and to fall back to the "compiled in" drivers if none can be found elsewhere. [Bernardo: Yes, but how can you kick the old drivers out of your way? I think this idea is rather complex to implement. Why would one need a "minimal" kickstart that loads everything else from the hard disk and then commits suicide? ;-) ] [Iain: Now that has some interesting ideas. In particular the idea of newer disk based versions. I think this could easily be done simply by concatenating all the modules into a file, called kernel, which is scanned by the loader to create a list of modules, and later you can look elsewhere if a module is yet to be loaded, and if you find a newer version then load that instead. Although this way you cannot really reclaim the memory used by the kernel.] [A (in reply):] When a driver is not used anymore, you can unload it (that's what the HIDD docs say and that's what should happen). If course, it won't be possible to change the CPU "driver" while the system is up but that's not the point (and virtually never neccessary). You need some drivers which must be in ROM (eg. the drivers for the harddisk...) Others can be loaded from disk or ROM. My point is that we could have a minimal driver in ROM and update them on harddisk. By clever use of the search path, the new drivers on harddisk would be used if the bootloader doesn't need the driver. [I: It might be difficult to unload something that is loaded into the kernel at boot time, since you would basically have to construct a list of what pages of memory it uses.] My point was this: I don't like drivers which depend on each other. I especially don't like how Linux does it: When you want to add a new driver to the kernel, you must recompile the whole thing. With my approach, you could create an image which is basically a file with a primitive filesystem inside. Adding a new driver would mean to compile the driver and copy it into the primitive filesystem. [Iain: But if we really abstract the drivers so that they have to use other HIDDs for interrupts and busses, then they will depend upon each other. I would like to know the advantages of using a file with a primitive filesystem over simply using a filesystem. I suppose the biggest one is security, in that it would take more effort to overwrite a module in the PrimFS than in the real FS. ] That's the theory. In practise, many drivers which you need and which can be compiled as a module can't be loaded if the kernel has not been compiled with the option to load that driver as a module (you will get undefined symbols). That sucks. You should be able to compile a driver completely independend if the rest of the kernel and load it without having to recompile the whole kernel. [I: Definitely, I think FreeBSD 3 can do this.] [B: That's because Linux (and NetBSD) modules are really object code that is statically linked to the kernel at run time (funny ;-). On an AmigaOS system, we don't need this. Our modules are in fact shared libraries, handlers and devices. They can be loaded "on demand" and even purged from memory when they are no longer in use. That's what both Linux and NetBSD failed to provide with their monolithic kernels. [AD: Right. Even if the rest of the boot process is similar to Linux, this must be Amiga-like :-) ] I still believe that the Amiga design beats UNIX on some important aspects. The Amiga provides dynamic linking with very little overhead. library jumptables, messages and IO requests all provide ways for modules to interface with each other in a very indepentent way. I still can't see the difference between adding a file into a primitive filesystem and appending a resident tag to a kickstart-like file. Building a kickstart at West Chester was just a matter of concatenating all parts together, being careful to support a backwards compatibility hack called "kickety split". ] [Bernardo is now chair :-)] Ok, don't call me mad. What about using a simple arhive format to store the modules? Perhaps a very simple but common format, such as tar or zip. vmlinuz is compressed by meands of gzip, and the small zlib implementation in the bootload can decompress it. So we could have a "zkick" file, which is just a zip archive (like Java classes) or perhaps a gzipped tar archive. The module "bootstrap" is a plain executable that is joined with this archive. Using a standard archive format allows us to rip out working source code from any freeware program and put it inside "bootstrap". We could then extract and initialize all the modules just after "bootstrap" has finished with the preliminary setup, and it would replace the Kickstart code that scans the ROM for magic cookies in the original AmigaOS. If instead we really need to be able to load the modules at run time, just like their file based counterparts, we could even implement a "romlib" module similar to the well known "ramlib". This one would patch itself into Exec's OpenLibrary() and OpenDevice() to extract the modules from the archive transparently. [I: Or even make this standard behaviour for Exec. Actually I think this part of the OS might need some overhaul. We would then have THREE different ways of opening libraries. From memory, from disk, from bootimage. We are now starting to get a bit messy with all the patching, there must be a nicer way of doing it. Perhaps we could have a complete redesign of the image loading system with dynamically loadable image loaders (for ELF, a.out, Amiga HUNK, etc) and also for places to load modules from (memory, library/device path, bootfile standard command path). ] |
Copyright © 1995-2009, L'équipe de développement AROS. Tous droits réservés. Amiga®, AmigaOS®, Workbench et Intuition sont des marques de Amiga Inc. Les autres marques appartiennent à leur propritaires respectifs. |