Fast! CompactFlash for Macintosh PDS/NuBus

zigzagjoe

Well-known member
Early days, but I'm discovering some bits worth of note so I figured it's time for a worklog thread. I have been wanting to tinker with CF cards for a while, as the nice parallel bus should mate nicely to first PDS and later (with more work) NuBus. Due to the low complexity it should allow for good speeds.

Currently, I have built a prototype board and have bodged it to life. It's capable of 3 cycle reads and 4 cycle writes against a 16 bit CF, so this gives a theoretical maximum read speed of 6.27 MB/s into main memory (15666720 / ( 6 card cycles + 4 ram cycles) * 4 bytes) and 5.22 MB/s for writes. Subject to card's ability to sustain this. The card is being run with PIO-4 timings which every test card I've got is able to sustain.

At the moment 5 megabyte/s reads and 4 megabyte/s writes are possible, as measured by Norton System Info. Attached are some (almost legible) performance figures. Built-in SCSI tops out at 1.5MB/s, so it easily provides 3x the performance of a zuluscsi slim on the SCSI port. It's also beating Quadras' stock SCSI.

All measurements on the SE/30 are with one of my Booster 2.0 accelerators installed, though the stock CPU is not significantly slower since this is an IO-bound scenario. Both Quadras were running at 40mhz. I've just now got it booting off the CF card, which AFAIK makes this the first bootable PDS card that isn't a vintage design! It shaves a solid 7 seconds off the boot time of system 7.5.5, more than I was expecting.

1739162940179.jpeg

How to make bootable PDS/Nubus cards.
An excerpt from DC&D is attached. Fundamentally, it requires a sRsrcBootRec (type=6) entry on the sResource for your device (not the board sResource with the inits!) which points to a SExecBlock just like the Inits. The flags on the sResource must also have fOpenAtBoot set.

This BootRec entry will be executed at two times, potentially.
1) At early boot, after primaryInit, IF PRAM is appropriately set to point to this card as a bootable device
2) After SecondaryInit, after OS patches are loaded and before extensions

If bootrec is present, mac os will never open the driver under any circumstances, as it would otherwise do. You are responsible for doing that in the BootRec!
I haven't quite found documentation supporting this: if your driver is being loaded at boot it should not call PBMountVol, this will crash the system. The ROM will (try?) to mount it for you. If your driver is being loaded later (new drive number != 1), then you should mount it in the driver code. Remains to be seen if floppy boot is still possible, or what happens if the drive is not bootable.

Here's some sample code. Barely tested: I only just got this working a little bit ago!

C:
#pragma parameter __D0 BootRec(__A0)
UInt32 BootRec(SEBlock* seblock) {
    Ptr a32 = (Ptr) (0xF0000000 | ((UInt32)seblock->seSlot << 24));
    seblock->seStatus = 1; // code was executed

    dbg_labelhexl("BootRec seBootState",seblock->seBootState); // 0 = early boot, 1 = secondaryInit

    OSErr            ret;
    SlotDevParam    pb;

    char name[] = driverNamePascal;

    // lifted from SuperMario/Patches/VideoPatch.a #1006-1013
    pb.ioSlot = seblock->seSlot;
    pb.ioID = sRsrc_CFDisk; // your sResource ID containing the bootrec and driver
    pb.ioNamePtr = (StringPtr)&driverNamePascal; // (length of string).Driver_Name, must have the period denoting driver
    pb.ioSFlags = 0;
    pb.ioSPermssn = 0;
    pb.ioSMix = nil;
    ret = PBHOpen((HParamBlockRec*)&pb, false /* not async */);

    dbg_labelhexl(" HOpen", ret);

    if (ret == noErr) { // return refnum of driver
        dbg_labelhexl(" ioSRefNum", pb.ioSRefNum);
        return pb.ioSRefNum;
    } else
        dbg_prints("Failed to open drvr in BootRec\n");

    return 0;
}

You'll notice a catch 22 above, if you clear PRAM you will not be able to boot from your card! However, I think with some hueristics in primaryInit to detect empty PRAM it will be possible to fix this in a reasonably sane & user friendly manner. More testing needs to be done to make sure floppy boot still works with card boot, and similar permutations... and test the SE/30 ROM, and more.... much work remains.

Initialization (partitioning) will present a particular issue too. But, this I think I could carefully bundle some basic functionality in to the card. I particularly want to support the case where an existing hard drive image (i.e used by ZuluScsi, PiSCSI, BlueScsi, etc) can be directly copied to the card (dd) and have it just work as that's my use case :)

Other points of interest:

Partition support is tied to the SCSI manager, so your driver needs to understand partition maps if you want to support multiple volumes. And also handle this in the Prime routine.
Documentation surrounding Control/Status codes used by disk drives also seem to be MIA, my list is attached from working through SuperMario sources.
If you want to have "fast" formatting of the drive, you must support both Format and Verify Control calls (verifyCC, formatCC) but you just need to return noErr. Otherwise, mac OS will instead write every sector.

All of this is HIGHLY experimental, so take with a grain of salt.
 

Attachments

  • 1739163110416.jpeg
    1739163110416.jpeg
    542.1 KB · Views: 77
  • 1739163162297.png
    1739163162297.png
    80.4 KB · Views: 50
  • 1739163401581.png
    1739163401581.png
    470.3 KB · Views: 80
  • macDriveCodes.txt
    1.3 KB · Views: 1

David Cook

Well-known member
This is absolutely incredible!

It appears new CompactFlash cards are still being manufactured. I see 2GB for $16 and 128GB for $70. Unlike IDE/CF adapters from that era, I assume your will work with the latest and greatest cards.
 

LaPorta

Well-known member
Wow that’s…darn incredible. If you do manage a NuBus one, that would be a great IIfx mate!
 

zigzagjoe

Well-known member
This is absolutely incredible!

It appears new CompactFlash cards are still being manufactured. I see 2GB for $16 and 128GB for $70. Unlike IDE/CF adapters from that era, I assume your will work with the latest and greatest cards.

As long as the card supports IDE mode and PIO 4 timings, it ought to work. Though the value of larger cards is somewhat questionable given most systems this will target won't deal nicely with larger than 2GB. I plan to support additional partitions to help mitigate this. I've got 6 different cards to test with right now, in the range 128MB - 8GB.

The plan is to "suggest" 3 partitioning strategies if booted into Mac OS with a card with an invalid partition map. Either a single 2GB partition, as many 2GB partitions as possible on the card (up to driver limit of ~4), or a single large partition up to disk capacity (or a certain limit). Then, ideally, mac OS should be able to initialize those partitions for us. I plan to build this into the card's ROM so it should allow for driverless/utilityless operation.

Detailed partitioning beyond that would require writing the partition map directly using linux or dd'ing an existing zuluscsi image over the CF.

Wow that’s…darn incredible. If you do manage a NuBus one, that would be a great IIfx mate!

Actually, if I retime the logic to work on an IIsi the IIfx PDS ought to just work too. Not many uses for that slot otherwise!

More notes:

Drive 1 is always a floppy if installed and Bootrec is called early in the boot process (ie. PRAM points to this card). So ignore the bit about drive 1 from the first post; I'm pretty sure the driver is not supposed to be calling PBMountVol in the Open handler. This, I think, was a hack that originated in romdisk stuff for some reason but is not best behavior. I will be trying to figure out how to sort this, as I really need Mac OS to mount volumes (and offer to initialize them if invalid, to tie into that partitioning behavior above).

Bootrec booting behavior
Floppy always wins, if a disk is inserted
if the bootec device contains an invalid HFS signature or is otherwise nonbootable, it receives an eject control call...
... then system boots from SCSI as normal.

Magic XPRAM address to boot from a nubus card is 0x78, this must contain the following data: 0x0000SSRR, where SS is slot ID and RR is sResource ID on that device. In conjunction with the fOpenAtBoot and Bootrec mentione dearlier

To allow the device to be bootable with cleared PRAM, this is the behavior I've come up with:
If slot PRAM Is reset due to PRAM clear, card newly installed, or slot ID changed ->
perform one time check to make sure the bootable device is set to default boot
if it is set to default boot, startup will be set to the CF card device

On this boot and all others afterwards,
if the CF card is set as startup but is not bootable, the system will proceed to boot off SCSI as it would normally (per bootrec behavior above)
if the CF card is set as startup and becomes bootable, system will boot from it until startup device is changed using startup device control panel
if the card is not set as startup, then the startup device control panel must be used to select it as the boot device.
 

chelseayr

Well-known member
@David Cook tbh compactflash is still current (even if specifically eg in term of consumer cameras its a limited market atm) and you can still buy a new 64mb media if your particular industrial machine still needed it. like this for example https://synchrotech.com/products/compact-flash-industrial-grade?variant=42012800680024

so I guess the only real limit is that of course non-consumer medias costs a lot more tho

(even then this one has no prices but I imagine that since it seem to be consumer-facing media its likely somewhat cheap for the smallest 1gb one tho https://us.transcend-info.com/product/memory-card/compactflash-133 )
 

eharmon

Well-known member
From a technical standpoint, is this putting the IDE controller directly on PDS/NuBus together with a ROM driver? Or is the card doing more work to translate between a proprietary driver command set and ATA PIO?

At this rate, next time you start a new thread you'll be putting ISA cards in your machine...
 

zigzagjoe

Well-known member
From a technical standpoint, is this putting the IDE controller directly on PDS/NuBus together with a ROM driver? Or is the card doing more work to translate between a proprietary driver command set and ATA PIO?

At this rate, next time you start a new thread you'll be putting ISA cards in your machine...

This is the former case, in the case of this PoC: the CF card is directly on the PDS bus with a CPLD to manage adapting the bus. The driver required to implement is the hard and more interesting piece, so it makes more sense to prove it on the evil I know (68030 PDS) before implementing on NuBus. I've got my eye on the Quadralink as a starting point for the NuBus implementation, though it will require additional complexity to expand the data width and also in order to improve throughput (specifically, 32 bit reads will be needed to reduce the nubus cycles by half).

----------

So, more notes: I figured out what ROM drivers are doing wrong/suboptimally regarding volume mounting. Instead of calling PBMountVol directly, they need to be posting an event to the OS that a new disk is present. I can't take credit for this, nor can apple's missing documentation: elliotnunn on github found it while implementing the virtio driver for QEmu.

C:
// notify mac OS of the new drive
PostEvent(diskEvt, dq->dQDrive /* drive # */); // thank you elliotnunn

With this, the OS will automount it and if that fails, it will prompt for initialization. Yay!

For a bootable PDS card, this should instead be done in the BootRec process; for now, I scan all drives to look for ones handled by my driver and issue the event on each. Doing it twice when booting from the CF card doesn't seem to harm anything.
 

eharmon

Well-known member
This is the former case, in the case of this PoC: the CF card is directly on the PDS bus with a CPLD to manage adapting the bus. The driver required to implement is the hard and more interesting piece, so it makes more sense to prove it on the evil I know (68030 PDS) before implementing on NuBus. I've got my eye on the Quadralink as a starting point for the NuBus implementation, though it will require additional complexity to expand the data width and also in order to improve throughput (specifically, 32 bit reads will be needed to reduce the nubus cycles by half).
That's awesome. Theoretically you could do DMA with PDS, too?
 

Trash80toHP_Mini

NIGHT STALKER
Actually, if I retime the logic to work on an IIsi the IIfx PDS ought to just work too. Not many uses for that slot otherwise!
Oopsie, missed that in responding to @LaPorta great goings on! Indeed, the IIfx PDS is a slot dying for expansion.

How much overhead would be involved using an SD->CF adapter. If not too, too much of a hit, much higher capacity cards are available in SD, if supported?

Again, fabulous work.
 

zigzagjoe

Well-known member
That's awesome. Theoretically you could do DMA with PDS, too?

You can, but there isn't much benefit with the 030 PDS use case. The word transfer from card to main memory would take the same ~10 cycles, maybe 9 if i managed to shave one off between getting the second word out of the card - but the CPU still remains out of commission for an extended period as DMA monopolizes the bus transferring 256 words out of the card.

Essentially, it makes more sense that the CPU just do it itself as the fundamental transfer speed is about the same as all the data goes in few large chunks with minimal delay. This is opposed to a SCSI / ethernet / serial case where you might get a single byte every interrupt - so having that go into main memory directly saves interrupting the CPU incessantly.

However, DMA may make more sense with NuBus, and apple does provide some sample info on how a bus mastering nubus card would be done. I need to do some research to see if that makes sense. If burst transfers are supported between host and card, that'd be more beneficial ( but I don't know that they are ).

Oopsie, missed that in responding to @LaPorta great goings on! Indeed, the IIfx PDS is a slot dying for expansion.

How much overhead would be involved using an SD->CF adapter. If not too, too much of a hit, much higher capacity cards are available in SD, if supported?

Again, fabulous work.

I can't speculate on a SD to CF adapter.... it'd really depend on how fast the SD card is and how well implemented the adapter is. It *must* support IDE PIO mode 4 though.

Realistically, capacity isn't a huge concern seeing as these OS tend to have a 2G/volume limit. Good quality CF cards are available for cheap at that capacity, so I may bundle those for a turnkey solution.
 
Last edited:

Mk.558

Well-known member
We've known that for a long time 68K and PPC Macs have had bad busses. 16 bit bus on a 32 bit processor, bandwidth missmatching, or frequency discrepencies. Just by looking at a PowerMac G3 (beige) it doesn't take a big brain to know that a 66MHz bus on something of that timeframe was "insufficient".

So it's not really on topic here, but may I ask: what machines actually had a good bus? Did any of them have a great bus?

I was thinking about this in the shower earlier. If it didn't have a hobbled bus, it had bad internal graphics. If it didn't have bad internal graphics, it had a weak bus or lackluster SCSI. Or something else. If it didn't have any of those "issues", well it was too much of a special snowflake to really matter for very long (IIfx).
 

eharmon

Well-known member
You can, but there isn't much benefit with the 030 PDS use case. The word transfer from card to main memory would take the same ~10 cycles, maybe 9 if i managed to shave one off between getting the second word out of the card - but the CPU still remains out of commission for an extended period as DMA monopolizes the bus transferring 256 words out of the card.

Essentially, it makes more sense that the CPU just do it itself as the fundamental transfer speed is about the same as all the data goes in few large chunks with minimal delay. This is opposed to a SCSI / ethernet / serial case where you might get a single byte every interrupt - so having that go into main memory directly saves interrupting the CPU incessantly.

However, DMA may make more sense with NuBus, and apple does provide some sample info on how a bus mastering nubus card would be done. I need to do some research to see if that makes sense. If burst transfers are supported between host and card, that'd be more beneficial ( but I don't know that they are ).
Yeah that makes a lot of sense. I assume you referenced Technote 15?

Both the Rockets and the 8-24 GC can master, if you need reference examples. Based on the locked transfer count they can also do bursts of 2 and 16, respectively. I think the GC only bursts to speak to other cards (to accelerate them), not the host...but I'm unclear on the Rocket. That thing has so many tricks up its sleeve.

I don't think any logic boards ever supported burst as master, but it seems like burst should work regardless with the card mastering? @Melkhior seems to have looked at it here: https://68kmla.org/bb/index.php?threads/nubusfpga-hdmi-on-nubus-macs.40760/post-468192
 

cheesestraws

Well-known member
We've known that for a long time 68K and PPC Macs have had bad busses

everyone did. The only microcomputer processor of that era that had decent memory bandwidth as far as I know were the early ARMs.

You can, but there isn't much benefit with the 030 PDS use case.

Agreed; DMA on PDS is I think mostly useful if you are doing asynchronous things and want to reduce interrupt load; you're still effectively going to stop the CPU doing anything useful while DMA is taking place.

(This just increases my wistfulness for my vague desire for an RDMA-like NIC for 68k, for no reason other than it would be neat, but I have no competence to bring this actually about)

However, DMA may make more sense with NuBus

Also agreed.

I don't think any logic boards ever supported burst as master, but it seems like burst should work regardless with the card mastering?

My vague memory is that this is correct, but it is quite a vague memory.
 

Snial

Well-known member
So it's not really on topic here, but may I ask: what machines actually had a good bus? Did any of them have a great bus?

I was thinking about this in the shower earlier. If it didn't have a hobbled bus, it had bad internal graphics. If it didn't have bad internal graphics, it had a weak bus or lackluster SCSI. Or something else. If it didn't have any of those "issues", well it was too much of a special snowflake to really matter for very long (IIfx).
Isn't it just that all computer designs are a work-in-progress, which means that only parts of an architecture are improved at a time, and only when that part becomes the critical bottleneck?

Consider the IBM PC. The original expansion bus required 4x 4.77MHz cycles to transfer 8-bits, and were essentially 8088 PDSs. That's a maximum transfer rate of 1.2MB/s, but you couldn't achieve anywhere near that. The IBM PC/AT in 1984 increased this to, I think 3x 8MHz cycles per 16-bits: 5.3MB/s! But then they were stuck with that until the end of the 1980s, because MCA didn't take off. So, then they had 25MHz and 33MHz, 32-bit 80386 CPUs on a bus 6x or 8x slower than what could be achieved.

By contrast, NuBus was great! 10MHz x 32-bits provided up to 37.5MB/s transfer rates! At least according to TI's 1983 spec.

 

zigzagjoe

Well-known member
Yeah that makes a lot of sense. I assume you referenced Technote 15?

Both the Rockets and the 8-24 GC can master, if you need reference examples. Based on the locked transfer count they can also do bursts of 2 and 16, respectively. I think the GC only bursts to speak to other cards (to accelerate them), not the host...but I'm unclear on the Rocket. That thing has so many tricks up its sleeve.

I don't think any logic boards ever supported burst as master, but it seems like burst should work regardless with the card mastering? @Melkhior seems to have looked at it here: https://68kmla.org/bb/index.php?threads/nubusfpga-hdmi-on-nubus-macs.40760/post-468192

Not yet. I haven't sat and made a study of nubus beyond the anecdotes I pick up going through DC&D. The CF card is very burst friendly at a per sector basis, so optimizing for burst bandwidth would be the way to go for a nubus version. A set of latches would allow the logic to perform a couple of word reads/writes and assemble a complete longword in order to save on nubus cycles.
 

Trash80toHP_Mini

NIGHT STALKER
I can't speculate on a SD to CF adapter.... it'd really depend on how fast the SD card is and how well implemented the adapter is. It *must* support IDE PIO mode 4 though.
Yeah, it was a crazy notion that popped into my noggin. But the only stupid question is the one that isn't asked. ;)

Realistically, capacity isn't a huge concern seeing as these OS tend to have a 2G/volume limit. Good quality CF cards are available for cheap at that capacity, so I may bundle those for a turnkey solution.
Good point about partition capacity. Interesting, haven't looked at CF cost/capacity in a very long time. Amazon's got 4GB Transcend Cards for $21 and no-names for $17, very nice. That would be perfect for a two partition, dual boot setup. Thanks, it looks like it's time to update my PCMCIA 'Book boot/utilities/apps test card.

__________________________________________________________________________________

Just can't help myself mode:
Another crazy notion for your project? Blackbirds have their limited 030 bus available in the expansion bay. PCMCIA adapters might as well be hen's teeth, no? Might you shrink your adapter down to a fixed card (or even removable card) CF expansion module?

Given your chassis design/printing prowess, such would be a great fit for expanding your market? I'd think such a battery chassis module would be highly desirable. The Blackbird gang is far more numerous and almost as crazy as the TAM crowd!

It's only Apple's 16bit 030 PDS, slow side bus subset for PowerBooks, but that shouldn't pose much of a problem?
 
Last edited:

zigzagjoe

Well-known member
Yeah, it was a crazy notion that popped into my noggin. But the only stupid question is the one that isn't asked. ;)


Good point about partition capacity. Interesting, haven't looked at CF cost/capacity in a very long time. Amazon's got 4GB Transcend Cards for $21 and no-names for $17, very nice. That would be perfect for a two partition, dual boot setup. Thanks, it looks like it's time to update my PCMCIA 'Book boot/utilities/apps test card.

__________________________________________________________________________________

Just can't help myself mode:
Another crazy notion for your project? Blackbirds have their limited 030 bus available in the expansion bay. PCMCIA adapters might as well be hen's teeth, no? Might you shrink your adapter down to a fixed card (or even removable card) CF expansion module?

Given your chassis design/printing prowess, such would be a great fit for expanding your market? I'd think such a battery chassis module would be highly desirable. The Blackbird gang is far more numerous and almost as crazy as the TAM crowd!

It's only Apple's 16bit 030 PDS, slow side bus subset for PowerBooks, but that shouldn't pose much of a problem?

As long as that 030 PDS operates with a 15.66mhz clock then the current version would likely work directly, with appropriate addressing changes. So long as the machine implements the pseudo-nubus space anyways. I don't have any powerbooks or particular knowledge of them to really progress that further at this particular moment, but it's an idea anyways.
 
Top