Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle mirrored SmartPort drives in ProDOS 2.x #685

Closed
inexorabletash opened this issue Mar 31, 2022 · 5 comments
Closed

Handle mirrored SmartPort drives in ProDOS 2.x #685

inexorabletash opened this issue Mar 31, 2022 · 5 comments
Labels
DeskTop DeskTop bugs or feature requests Disk Copy Issue with the sub-app feature request User-facing feature additions/enhancements
Milestone

Comments

@inexorabletash
Copy link
Collaborator

inexorabletash commented Mar 31, 2022

lib/smartport.s is used to map a ProDOS unit number (DSSSxxxx) to a SmartPort entry vector and unit, but this is limited.

ProDOS 1.2...1.9 mirror S5,D3/4 to S2,D1/2 only, and leave DEVADR entry pointing at $C5xx. Therefore, if the driver address is firmware ($Cn): If the unit number slot matches the driver slot, the device is not mirrored, and SmartPort unit is 1 or 2. Otherwise, the device is mirrored, and SmartPort unit is 3 or 4. So ProDOS 1.x is handled as best it can be.

But ProDOS 2.x mirror to non-device slots, and point DEVADR at RAM-based drivers, not firmware entry points. If the device is not mirrored, a firmware entry point will be used, and therefore the unit number slot will match the driver slot, and the drive gives the SmartPort unit as 1 or 2. But further mirrored drives are impossible to determine given data external to ProDOS, without exactly replicating ProDOS's remapping algorithm for a particular version, which is fragile.

All extant versions of ProDOS that remap (2.0 through 2.0.3, 2.4.x, and ProDOS.FX) use a similar internal approach:

  • Point the DEVADR entries at a procedure that maps ProDOS calls to SmartPort calls.
  • The procedure maps the DSSS bits of the unit number into an offset.
  • The offset is used to look up the SmartPort entry vector and unit in tables. These tables are populated on boot.

The unfortunately, the tables vary in memory location across versions of ProDOS. Fortunately, so does the map proc address placed in DEVADR. This means that the DEVADR can be used as key into a table to find the mapping tables.

Version DEVADR spunit-1 spvectlo-1 spvecthi-1
ProDOS 2.0 $FD1D $FD5C $FD6A $FD78
ProDOS 2.0.1 $FD08 $D6EF $FD6E $FD7D
ProDOS 2.0.2 $FD08 $D6EF $FD6E $FD7D
ProDOS 2.0.3 $FD08 $D6EF $FD6E $FD7D
ProDOS 2.4 $FCE6 $D6EF $FD51 $FD60
ProDOS 2.4.1 $FCE6 $D6EF $FD51 $FD60
ProDOS 2.4.2 $FCE6 $D6EF $FD51 $FD60
ProDOS FX 0.94 $FCA6 $FE6F $FE7E $FE8D
ProDOS FX HEAD $FC8B $FE54 $FE63 $FE72

NOTE: The "-1" notation is because DSSS is used as an index into a table, and because Slot 0 doesn't exist, each table has 15 entries (starting at S1,D1) rather than 16 to save space. So in the ProDOS source, spunit is actually one greater than the value given above. A byte is wasted for S0,D2.

Further observations:

  • A2D ships with ProDOS 2.4.x so supporting just that is a good starting point.
  • I looked at two different ProDOS.FX builds. On the plus side, they have different DEVADR values for mirrored drives. On the minus side, they aren't stable across FX builds, so there's a remote chance of a collision some day. But back on the plus side, they seem to be moving in a safe direction: 2.0.x = $FD08, 2.4.x = $FCE6, FX 0.94 circa 2020 = $FCA6, FX from this last week = $FC8B. Yay?
  • All the remapping procs share a similar structure in the code, so rather than hardcoding anything the following could be used:
    1. Look at the 3 bytes preceding the DEVADR entry. If it's not 4C 00 10 (JMP $1000), fail.
    2. Scan forward from that for 4A 4A 4A 4A AA (LSR x4, TAX) which maps unit number to offset.
    3. This should be followed by LDA spunit-1,X / STA ... / LDA spvecl-1,X / STA ... / LDA spvech-1,X / STA ...

...

Supporting this would enable the following functionality for mirrored drives:

  • DeskTop: Special > Eject Disk (or drag to trash)
  • DeskTop: Polling for disks manually ejected
  • DeskTop: Polling for disks inserted
  • DeskTop: Correct device names in Special > Format a Disk... and Special > Erase a Disk...
  • Disk Copy: Automatic ejection when swapping disks
@inexorabletash inexorabletash added the feature request User-facing feature additions/enhancements label Mar 31, 2022
@inexorabletash
Copy link
Collaborator Author

Also for reference, ProDOS 2.0.3 source, via the A2osX crew:

@peterferrie
Copy link
Collaborator

peterferrie commented Mar 31, 2022 via email

inexorabletash added a commit that referenced this issue Apr 1, 2022
Talking directly to the SmartPort controller is necessary for status
calls to retrieve device details and eject disks. Doing so requires
mapping a ProDOS unit number (DSSSxxxx) to a SmartPort controller and
a SmartPort unit number. ProDOS 1.x mirrors SmartPort device 3 and 4
for Slot 5 in a predictable way, so the unit numbers can be retrieved
in a predictable way.

ProDOS 2.0 and later mirror devices beyond 1 and 2 on a SmartPort
controller to any free slot/drive combinations, and maintains internal
tables mapping ProDOS unit number to SmartPort entry vector and unit.
Previously, attempts to look these up failed, so only SmartPort
devices would show with correct names in Format/Erase, correctly
eject, and have disks show and disappear automatically when
inserted/ejected.

This change introduces support specific to ProDOS 2.4 to dig this
mapping out of ProDOS itself in a mostly safe way. This should make
mirrored drives work in these cases with 2.4:

* DeskTop: Special > Eject Disk (or drag to trash)
* DeskTop: Polling for disks manually ejected
* DeskTop: Polling for disks inserted
* DeskTop: Correct device names in Special > Format/Erase a Disk...
* Disk Copy: Automatic ejection when swapping disks

A more robust solution would handle other versions of ProDOS (e.g.
2.0, 2.0.x, FX, etc), either by including more lookups or building a
mapping table on startup. A2D releases include 2.4 but will work with
any ProDOS-8 1.1 or later.
@inexorabletash
Copy link
Collaborator Author

An alternative approach would be (per the suggestion above) to construct mappings on startup. Make the MLI ONLINE call and then iterate over all SmartPort controllers/devices and grab the directory blocks, matching names as @peterferrie suggests. This could then populate tables exactly like the ProDOS internal tables mapping DSSS to spunit/spvect.

  • DeskTop would do this on startup (in desktop/init.s), and stash the tables somewhere handy in main.
  • Disk Copy is launched from DeskTop and could "steal" the tables during its bootstrap.
  • Desktop.System techncially uses this mapping code as well as of f6cdeb6, but it's really just using it to search for RAM disks, so mapped drives could simply be ignored.

@inexorabletash inexorabletash added DeskTop DeskTop bugs or feature requests Disk Copy Issue with the sub-app labels Apr 1, 2022
@inexorabletash inexorabletash added this to the 1.2 milestone Apr 1, 2022
@inexorabletash inexorabletash changed the title Handle mirrored SmartPort drives beyond 1 and 2 in ProDOS 2.x Handle mirrored SmartPort drives in ProDOS 2.x Apr 16, 2022
inexorabletash added a commit that referenced this issue Jun 30, 2022
Extend the support for mirrored SmartPort drives added in f6cdeb6
from just ProDOS 2.4 to handle ProDOS 2.0.1 through 2.0.3 as
well. This affects:

* DeskTop: Special > Eject Disk (or drag to trash)
* DeskTop: Polling for disks manually ejected
* DeskTop: Polling for disks inserted
* DeskTop: Correct device names in Special > Format/Erase a Disk...
* Disk Copy: Automatic ejection when swapping disks

For #685
@inexorabletash
Copy link
Collaborator Author

I took a stab at supporting ProDOS 2.0. The ProDOS code for that version must be buggy - with a mirrored drive (at least in GSPlus), calls to ON_LINE cause a crash.

Given that, I'm going to call this item "done" as the dominant versions of ProDOS are supported. If anyone wants to do a more robust implementation I'd accept it, though.

@peterferrie
Copy link
Collaborator

peterferrie commented Sep 12, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DeskTop DeskTop bugs or feature requests Disk Copy Issue with the sub-app feature request User-facing feature additions/enhancements
Projects
None yet
Development

No branches or pull requests

2 participants