Skip to content

[kernel] Implement XMS floppy I/O without bounce buffers#2339

Merged
ghaerr merged 6 commits intomasterfrom
xmspage
May 24, 2025
Merged

[kernel] Implement XMS floppy I/O without bounce buffers#2339
ghaerr merged 6 commits intomasterfrom
xmspage

Conversation

@ghaerr
Copy link
Copy Markdown
Owner

@ghaerr ghaerr commented May 23, 2025

Proof of concept hopefully making the impossible possible... discussed in Mellvik/TLVC#164 (comment).

Implements DMA-driven floppy I/O using direct floppy driver directly to and from XMS buffers in memory > 1MB. The top 8 bits of the XMS address (A16-A23) are written to the external page register at port 81h for DMA channel 2. In the current direct floppy driver, this was always the case, except that when XMS buffers were in use, a bounce buffer was forced. That's now turned off, and the full 24-bit source or destination XMS address (max 16MB) is used for the transfer.

This version has track caching turned off for simplicity; track caching is always turned off due to it having been tested as inefficient with faster CPUs (386+). A later version will likely dynamically allocate a track cache buffer in either XMS or low main memory, depending on whether XMS buffers are enabled.

Ultimately, more discussion is needed as to when or whether a track cache is needed at all on XMS systems, since XMS memory isn't available on PC or PC/XTs, leaving only PC/ATs and possibly some other hardware before 386+ CPUs were in use, where track caching isn't helpful. More discussion on this in Mellvik/TLVC#164.

Tested on QEMU. Not yet tested on real hardware.

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented May 24, 2025

Added commit to dynamically allocate direct floppy track cache in XMS memory when running with XMS buffers active. Track caching is now turned back on again for the direct floppy driver, whether running XMS or not.

This should eliminate the speed degradations identified when operating floppies and XMS on real hardware in Mellvik/TLVC#164 (comment), while still providing floppy I/O to/from XMS buffers as well as XMS to XMS (cache to buffer) high speed copies via unreal mode, LOADALL or INT 15/1F.

This PR (re)enables XMS track caching when running on 386+ systems, more real world testing required; I think keeping caching on will decrease boot times and performance likely increase with the typically larger number of buffers configured when running XMS. The track cache itself is only 9K of XMS memory.

The low memory track cache is still kept static and not dynamically allocated, since the BIOS driver may also be used if compiled in, and/or XMS may be disabled due to INT 15 w/kernel HMA, etc.

@ghaerr ghaerr merged commit 0be97ce into master May 24, 2025
1 check passed
@ghaerr ghaerr deleted the xmspage branch May 24, 2025 22:00
@Mellvik
Copy link
Copy Markdown
Contributor

Mellvik commented May 25, 2025

@ghaerr, unrelated to this update there is an old bug in bad_flp_intr() that will cause a probing loop if the probe never succeeds.

    if (probing) {
        probing++;
        return;           <----- this return prevents error count from increasing
    }
    errors = ++CURRENT->rq_errors;
    if (errors >= MAX_ERRORS) {
        printk("df: Max retries #%d exceeded\n", errors);
        request_done(0);
        /* don't reset/recalibrate now as extra interrupt
         * confuses redo_fd_request if no more I/O scheduled.
         */
        return;
    }
    if (probing) return;    <---- add the return here instead - or not at all

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented May 26, 2025

unrelated to this update there is an old bug in bad_flp_intr() that will cause a probing loop if the probe never succeeds.

Thanks @Mellvik. Kind of interesting that bug was in there this long! I thought I had tested the probe code also. I'll make the suggested change.

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented May 26, 2025

there is an old bug in bad_flp_intr() that will cause a probing loop if the probe never succeeds.

I thought I had tested the probe code also. I'll make the suggested change.

Actually, I had tested the probing code in my version of the driver, which operates a bit differently than yours. In testing again to make sure, my code doesn't make use of the error count (as any error just moves to the next probe rather than retries), and the following code ends up exiting the probe, which is signaled as a zero byte at the end of each probe list:

        if (!floppy) {
            tmp = probing? base_type[drive][probing-1]: base_type[drive][0];
            if (!tmp) {
                printk("df%d: Unable to determine drive type\n", drive);
                request_done(0);
                fd_probe[drive] = 1;
                goto repeat;
            }

Nonetheless, thanks for letting me know of this possible problem! I will update my driver with a few of the typos and other cleanups you made in Mellvik/TLVC#173 though.
Screen Shot 2025-05-25 at 7 48 40 PM

@Mellvik
Copy link
Copy Markdown
Contributor

Mellvik commented May 26, 2025

Yes, you're right @ghaerr. The probe mechanisms are different between the systems and this bug would never hit you.

There may still be a problem with the probe code though (I haven't looked up the code where probing´ is incremented, that would make a difference) - the same I just found and fixed in TLVC: Hitting the NULL entry at the end of the base_type` table cannot be a termination criteria because it assumes you always start probing at the first entry. If the last used format was the last valid entry in the table, the NULL entry should just send us back to the beginning. This is the reason I decided to keep the error count as a (modified) termination parameter for probing in TLVC.

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented May 26, 2025

Hitting the NULL entry at the end of the base_type` table cannot be a termination criteria because it assumes you always start probing at the first entry.

Yes, I saw that in your code. I rewrote all the probe code some time ago and probes always start at the beginning of the table thus in the same sequence, so it doesn't have a wrapping issue, and also doesn't use the error count for termination either.

@Mellvik
Copy link
Copy Markdown
Contributor

Mellvik commented May 26, 2025

I rewrote all the probe code some time ago and probes always start at the beginning of the table thus in the same sequence, so it doesn't have a wrapping issue.

ok, I suspected that to be the case. I decided against that in order to speed up probing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants