AmigaOS 4.1FE support#5
Open
reinauer wants to merge 24 commits into
Open
Conversation
Start separating Amiga-family OS integration from the packet handler so AmigaOS 4 can grow a native frontend without cloning the OS3 handler. Select an os3 or os4 platform subdirectory from the Makefile and add shared sys_compat declarations. Route allocation, message ports, I/O requests, signals, interrupt setup, library/interface ownership, and utility hook calls through per-OS implementations. Keep -lauto out of the OS4 link. Explicitly open dos.library, obtain IDOS, open utility.library, and obtain its main interface. Move the temporary OS4 main wrapper into the OS4 frontend directory and document the remaining OS4 porting work.
Move the remaining AmigaOS 4 source differences out of the shared packet handler. Add per-target compatibility headers and route the interrupt callback ABI, FileInfoBlock entry type, and DeviceNode lock copying through sys_compat helpers. Document the CD0 default, OD0 fallback, and requester policy for unsafe conflicts. Name fallback should be quiet, while duplicate OD0 or same physical Device/Unit conflicts should fail visibly.
Teach the OS4 entry wrapper to receive and validate the initial ACTION_STARTUP packet before passing it into the shared handler loop. Add a native FileSystemVectorPort template with explicit unsupported-vector stubs. This gives the next slice a real OS4 frontend to map onto shared read-only operations.
Move the first native OS4 vector callbacks onto shared handler operations for locks, file handles, reads, seeks, and info. Keep the packet frontend on the same operations so behavior stays aligned. Add native ExamineData allocation for object, lock, and filehandle examine calls. Leave directory iteration unsupported until the OS4 private context ownership rules are confirmed.
Wire native OS4 vector callbacks for inhibit, serialize, and lock or file mode changes into the shared handler operations. Return ERROR_DISK_WRITE_PROTECTED from mutating vectors so DOS sees a deliberate read-only filesystem result instead of missing support.
Add a shared handler operation that returns the next directory entry by resume key, matching the existing packet iteration rules. Use it from FSExamineDir to allocate native ExamineData entries, recycle stale context nodes when possible, and append results to the OS4 examine context FreshNodeList.
Make always defines CC, defaulting to "cc", so the conditional assignment "CC ?= m68k-amigaos-gcc" never took effect and a plain "make amiga" tried to build the handler with the host compiler. Assign the m68k cross-compiler only when CC still carries make's built-in default, so command-line and environment overrides such as CC=ppc-amigaos-gcc keep selecting their own toolchain unchanged.
On AmigaOS 4, dos.library only calls a filesystem through its native FileSystemVectors when the handler's port validates as a vector port. The handler replied to ACTION_STARTUP with the plain process message port, so even with the vector callbacks implemented, every DOS call was forced through legacy packet emulation. Allocate the FileSystemVectorPort during startup, attach a dedicated signal to its embedded message port, and verify the object with GetFileSystemVectorPort() before relying on it. Switch the handler port to the vector port before replying to the startup packet, so the device node, volume node, locks, and the packet loop all reference the port DOS validates. If activation fails, the startup packet is rejected and the port and signal are released; on shutdown the process port is restored before the handler exits. Track the owning process port separately from the active handler port in handler_global, and introduce an ODFS_AMIGA_OS4 macro in the per-target compat headers so shared code can test the build target without scattering __amigaos4__ checks.
The SERIAL_DEBUG log sink wrote bytes to the serial port with inline m68k assembly calling exec's RawPutChar vector, which cannot build for the PPC OS4 target. Keep the raw serial path for OS3 and use exec's DebugPrintF() on OS4, which ends up in the same serial/Sashimi debug stream. This makes the SERIAL_DEBUG=1 and PACKET_TRACE=1 build variants compile for OS4.
AmigaOS 4 deprecates ACTION_DIE in favor of ACTION_SHUTDOWN (V51+), which DismountDevice() sends to ask a filesystem to remove its volume node and terminate. The handler only recognized ACTION_DIE, so an OS4 dismount would have been answered with ERROR_ACTION_NOT_KNOWN and the handler process would have stayed alive. Accept ACTION_SHUTDOWN wherever ACTION_DIE is accepted: reply DOSTRUE and leave the packet loop, which already unmounts the volume, drains outstanding locks and filehandles, and unpublishes the device node. The OS4 SDK defines no shutdown member in struct FileSystemVectors, so the packet loop remains the correct delivery path even with the native vector port active. The OS3 NDK does not define the packet number, so the OS3 target compat header supplies it; OS3 DOS never sends it, and accepting it unconditionally keeps the shared loop free of OS conditionals.
The OS4 frontend cast the portable one-argument media-change callback
directly into is_Code. On AmigaOS 4 the V50+ conventions documented
in the exec autodocs pass is_Data as the third argument:
Cause() soft interrupts:
void handler(int32 unused, struct ExecBase *sysbase,
APTR is_data);
interrupt servers (AddIntServer):
ULONG handler(struct ExceptionContext *ctx,
struct ExecBase *sysbase, APTR userData);
With the old cast, the callback's data parameter received zero (or
the exception context) instead of the change-interrupt data, so the
NULL check in the callback made the handler silently miss every
media-change event fired through TD_ADDCHANGEINT.
Install a V50-style trampoline that ignores the first two arguments
and forwards is_Data to the portable callback. Both documented
conventions place is_Data third, so one entry point covers either
delivery path. This mirrors the a1 register-binding trampoline the
OS3 frontend already uses.
The OS4 build needed -Wno-error=deprecated-declarations while the shared handler still called AllocMem(), CreateMsgPort(), CreateIORequest() and friends directly. Those calls now go through the per-OS sys_compat wrappers, and the OS4 implementations use AllocVecTags() and AllocSysObjectTags()/FreeSysObject(), so a full rebuild compiles warning-clean without the suppression. Remove it so the build fails again if a deprecated interface member sneaks back in; the SDK marks them with __attribute__((deprecated)), which -Werror turns into a hard error.
The handler built its published DeviceNode and the volume DeviceList node by hand: AllocMem of the structure plus a name buffer, then filling every field. On AmigaOS 4 those are compatibility layouts whose real definitions (struct DeviceNode, struct VolumeNode) carry a StructSize field and reserved members that DOS expects the allocator to initialize; the manual path left them zero. Add odfs_amiga_create_dos_entry()/odfs_amiga_delete_dos_entry() to the per-OS compatibility layer. The OS3 implementation keeps the manual allocation, including its deliberate avoidance of MakeDosEntry() so volume names with AmigaDOS metacharacters such as parentheses are not normalized. The OS4 implementation uses AllocDosObject(DOS_DOSLIST, ADO_Type, ADO_Name), which the dos autodoc documents as the supported allocator (MakeDosEntry() itself is a stub over it since V52.16) and which fills dol_StructSize and the V52 fields. AddDosEntry()/RemDosEntry()/AttemptLockDosList() are unchanged; they remain current API on OS4.
The OS4 dospackets autodoc states that vector-port functions are invoked from the calling process context, like library calls, and that all access to filesystem state from them must be protected by a semaphore. The vector callbacks previously called the shared handler operations with no locking, racing against each other and against the handler process (packet dispatch and media-change handling) over the lock list, filehandle list, block cache, and the single device IORequest and DMA bounce buffer. Add a SignalSemaphore to the handler globals on OS4. Every vector callback that touches handler state now holds it across the shared operation, and the handler process takes it around media-change handling and shutdown teardown. Pure stub callbacks that only return an error do not take it. Direct legacy packets are now routed through the DOSEmulatePacket() function that AllocDosObject() installs in the vector port, as the autodoc prescribes. The emulator performs the equivalent vector call under the same serialization as native DOS callers, so the handler process no longer mutates filesystem state through a second unsynchronized dispatch path. Packets are validated (non-null, dp_Link == msg) before being trusted, since hand-built packets and private messages can reach the port directly. The shared handle_packet() dispatch remains the OS3/AROS path and the OS4 fallback if the vector port is absent. Shutdown now follows the documented sequence: invalidate the vector port by zeroing FSV.Version so dos.library stops vectoring new callers, tear down DOS-visible state while holding the semaphore so in-flight calls finish first, and reply the shutdown packet only after teardown. This also moves the OS3 ACTION_DIE reply after teardown, which matches common classic handler practice.
The OS4 filesystem handler must receive ACTION_STARTUP as its first process message. Newlib startup consumes that message while probing for a Workbench launch, which can deadlock the boot mount. Link the handler without C runtime startup, provide a small _start entry that initializes the Exec interface, and add the Kickstart Resident plus FileSysEntry registration used when the module loads from Kickstart.zip. Provide the small libc surface the freestanding link still needs and translate legacy allocation flags before passing them to AllocVecTags().
Diskboot starts one filesystem handler process per CD unit. The media callback context was static, so a later process could replace the device binding used by an earlier mounted volume. Move the media callback context into handler_global and pass that per-process instance to the core media layer. Reinitialize the same context after media-change remounts.
Some OS4 device paths report phantom ATAPI units that open but hang when probed through SCSI commands. Mounting those units publishes a dead volume that DOS can keep polling. Answer allocation failures on the startup packet, remove the TEST UNIT READY probe, and use TD_GETGEOMETRY before publishing the volume. Only issue MODE SELECT after geometry proves that a usable drive is present.
Workbench and native OS4 filesystem vectors expect lock objects with the OS4 DOS lock layout. The classic handler embedded a FileLock in its private lock wrapper, which leaves OS4-only fields uninitialized. Store a DOS-allocated struct Lock in each ODFS lock on OS4, keep the classic embedded FileLock on OS3, and convert through fl_FSPrivate1. Free the DOS lock when the ODFS lock is released or drained.
Workbench exercises native filesystem vectors more strictly than shell packet paths. Several callbacks returned classic packet values, left fh_Arg1 empty, or allocated ExamineData outside the directory context that DOS owns. Return native boolean SameLock and SameFile values, preserve fh_Arg1 together with fh_Arg2, implement FileSystemAttr queries, bind ExamineDir data to the DOS context, and reject inactive directory locks before iteration.
OS4 still sends legacy packet APIs such as Lock(), Examine(), and ExNext() to the handler port. Routing those packets through DOSEmulatePacket returns vector-era semantics and can reject classic examine actions that callers still use. Leave direct packets on the shared packet dispatcher and serialize that dispatcher with the OS4 filesystem semaphore. Native vector calls and legacy packets now share the same handler state without using the vector packet emulator as an extra dispatch path.
Native OS4 vector callbacks run in the caller task, but the handler reused its device IORequest whose reply port belongs to the handler task. If a caller-task DoIO() waited for completion, the device signaled the wrong task and Workbench could hang while opening a drawer. Record the handler task at startup. When media reads run from another task, allocate a temporary reply port and IORequest for that caller while reusing the same device and unit binding.
Add explicit AmigaOS 3 and AmigaOS 4 build instructions to the README. Describe compiler target selection, separate build directories, explicit tool overrides, and per-target size limits.
Add a PPC CI job that runs in the amigappc-gcc container. Put /opt/amigappc/bin on PATH, verify ppc-amigaos-gcc, and build both release and serial-debug handler variants.
Split the draft release workflow into OS3 and OS4 builders so each target uses its matching container and toolchain. Download both artifact sets before creating the draft release, and attach the PPC release and serial-debug handlers alongside the OS3 files.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.