DumbDD

true. I didn't know about the other partitions but I agree completely with your assessment.
I could be incorrectly crossing over two separate discussions, but that was what I was trying to work out. A bit of jiggery-pokery on a modern machine to pre-tweak the image and a raw disk write could be the solution to all this.
 
On that note, for my purposes, it would be great if I could run this in System 6, 7 or 8.1 at VERY latest. saybur, what’s the minimum OS your very alpha version will run?
Should run in 6.0.4(ish) and up but it's untested on anything other than 7.5.5

if I'm then running this on a PB1400 that boots from IDE (and has the .iso on a PCMCIA->CF card), then there's no chance it'll overwrite my boot volume?
Well it shouldn't but this is hot code so I'm not comfortable saying it definitely will not. It seems unlikely unless the OS maps IDE devices onto SCSI IDs or something like that.

Would be prudent to have anything important backed up just to be on the safe side, but obviously that advice applies to any system (not great about following it myself)
 
Re-reading the other thread, the disk image should be already converted into a single multi partition disk. So that's good news :)
 
it sounds like his Whole Disc Image includes the partition table. That would cause any system that mounts the drive to ignore the unused space because it is not mapped, but should not cause any actual problems.
Correct!
The .iso will include an ISO <whateverthestandardnumberis> partition map, just as any other optical disc. If the PA-RISC system can boot from a CD it shouldn't have any trouble reading it.
That's the idea.
In the other thread Snial was talking about appending two other disks, so the data that would be ignored in that scenario would be two other disks, including their partition tables and data partitions. Unless the image he is writing has already been modified to have a valid partition table for all three partitions, or he is only writing the image from a single CD.
The whole installation is on 3 CDs. So, the first .iso would contain the normal .iso partition table and the PA-RISC system should boot from it and won't see the other CDs, but that's fine.

For the Debian installation, I understand that the first .iso is the core installation and the other(s) are additional packages. So, I think it should be possible to mount those on reboot based on the sector offset and then install the packages.

So, I was thinking this would be reasonable, because I did something similar when playing with a MAME-based SparcStation 1 emulator on my Mac mini 2012. I couldn't get the FD to work, but I could create a HD image with a missing partition; then mount that missing partition from within SunOS and dd to it. Then I could shutdown and from the host side, dd the data back out. It was very crude, but worked. In the future I plan to use the emulated ethernet to transfer data, now that I have a better grasp of how to link it up to virtual network interfaces on the Mac.

But thinking about it again, I might be wrong, or at least a bit wrong. I would need to mount the other .iso images as .iso's so that the target (the PA-RISC system) understands their partition maps too. Maybe that's reasonable: the other .iso s on the HD won't be on partitions on the HD, so it's not like it's partitions within partitions.

It does mean that DumbDD needs to be able to specify the target offset, which I hadn't considered earlier... though I could get around that too just by joining them all together. However, I might not do that as I might not want to write 2GB in one go, just 644MB at a time.
 
Correct!

That's the idea.

The whole installation is on 3 CDs. So, the first .iso would contain the normal .iso partition table and the PA-RISC system should boot from it and won't see the other CDs, but that's fine.

For the Debian installation, I understand that the first .iso is the core installation and the other(s) are additional packages. So, I think it should be possible to mount those on reboot based on the sector offset and then install the packages.

So, I was thinking this would be reasonable, because I did something similar when playing with a MAME-based SparcStation 1 emulator on my Mac mini 2012. I couldn't get the FD to work, but I could create a HD image with a missing partition; then mount that missing partition from within SunOS and dd to it. Then I could shutdown and from the host side, dd the data back out. It was very crude, but worked. In the future I plan to use the emulated ethernet to transfer data, now that I have a better grasp of how to link it up to virtual network interfaces on the Mac.

But thinking about it again, I might be wrong, or at least a bit wrong. I would need to mount the other .iso images as .iso's so that the target (the PA-RISC system) understands their partition maps too. Maybe that's reasonable: the other .iso s on the HD won't be on partitions on the HD, so it's not like it's partitions within partitions.

It does mean that DumbDD needs to be able to specify the target offset, which I hadn't considered earlier... though I could get around that too just by joining them all together. However, I might not do that as I might not want to write 2GB in one go, just 644MB at a time.
Are you sure the merge script doesn't just extend the first image and move the package files onto it?
 
Are you sure the merge script doesn't just extend the first image and move the package files onto it?
The Debian script it looks like it merges all .isos into a single readable image, complete with combined package lists and the like.
 
The Debian script it looks like it merges all .isos into a single readable image, complete with combined package lists and the like.
Aaah, OK. I'd looked at the web page talking about this and then forgot about it. So, perhaps that solves one problem: it results in a merged .iso . In this case, the .iso would be about 1.932GB I think, less than 2GB. Sorry about that.

This is from:

Of course, where it says: "I certainly don't want a partition table", it means I don't want an Apple Partition Table, the original .iso partitions are fine and expected.
 
The Debian script it looks like it merges all .isos into a single readable image, complete with combined package lists and the like.
I was thinking it would be strange if it didn't and the description on the page sounded like it did.
 
So, if I created a blank .img without a partition map I should be able to mount it on Dingus PPC; then run @saybur 's scuzImager to write a .iso to it. We don't know if it'd save it properly, but I could use scuzImager again to write it to another .iso and then compare them?
It should save properly, as it would be interpreted as an entire disk.
If the iso is from a CD, then the resulting .img might be suitable only as a CD.
I would examine the partition map of the disk image using dumpvols.sh on macOS to see if it makes sense for a CD or HD.

CDs might have block size of 2048 while HDs have block size of 512.
I've seen partition maps that support both block sizes.
 
Something like this would be great and very useful. I need to get an image of a real spinning disc A/UX SCSI volume to zigzagjoe for testing/debugging purposes and currently there is no way for me to do that with the setups I have at my disposal.

honestly for that specific task i'd suggest using a Zulu-Compatible SCSI Emulator in initiator mode
 
For fun I wrote a version of DumbDD in THINK C 5. It's <4kB and fairly crude. I transcribed the Forth routines from MacTech I linked earlier, but I have almost certainly made mistakes. I tried it on miniVMac with the actual SCSI writes blocked out (and a delay of 2/60ths of second between each sector) so I could watch it update, but the version of Dd and the project attached would do it for real (find the #if 1 in the .c and turn it to #if 0 to reenable dummy writes). I tried to try it on InfiniteMac emulating a PM6100, but I mucked something up and now it won't boot properly with Saved HD. It thinks there could be another instance in a different tab using it, but there isn't another Infinite Mac tab and I don't know how to find and delete the Saved HD cache file ( @mihai , @joevt I'm sure you know). Also the BlueSCSI support crashes now, so I don't think I can get anything in or out. I'm not yet brave enough to try it on a real Mac.

1773492328168.png 1773492397617.png 1773492489407.png
1773492238315.png
You can quit mid-way by choosing File:Quit, or by closing the window. Progress updates every 0.5s. I think I'll change Dd:Copy to Dd:Transfer, because obviously Copy belongs on the Edit menu, but I didn't want Dd to be considered an 'Edit'. You can do stupid things like switch the SCSI device mid-transfer and it will happily trash another disk half way through, so take care! In future updates I would disable those menu options during transfer, add a Filename and SCSI ID to the window update (and maybe a progress bar). I would also support Option+'.' to stop a transfer without quitting and/or Dd:Stop .

Here's the app and project as it currently stands.
 

Attachments

I was able to 'recover' the Saved HD by restarting Safari, and do some more tests that involved copying about 6MB to it. Strangely though it never seems to corrupt the Saved HD itself, which puzzles me (I expected DumbDD to scribble over the HD making it unreadable). Actually it doesn't. These days I'm using the Snow Mac IIcx emulator, because I understand it has a proper SCSI device emulator and my app is 68K anyway, so it should be fine.

I've modified DumbDD so in theory it can read from SCSI drives as well as write to them. This means it should be possible to write to a SCSI drive; read it back into a file and then compare them. I also added a '•' mark to the SCSI menu so you can see which SCSI ID you're writing to; a File:Save... menu option to specify the file to save to; Dd:From... and a Dd:Blocks... dialog so you can tell DumbDD how many blocks you want to read. Finally I changed Dd:Copy... to Dd:To... because Copy would belong on the (non-existent) Edit menu. Finally, I implemented option+'.' so that you could stop a Dd operation without having to quit the application. I added safeguards so that Dd:To... and Dd:From... were disabled if you hadn't provided the right data (a SCSI ID and an open file for Dd:To... and a SCSI ID, a Block count and a file to save to for Dd:From... .)

So, in theory it's much more usable. However, when I try and read from SCSI via Infinite Mac's Snow Mac IIcx emulator, I get:

1774048060490.png

I don't know how it's possible to do both, particularly since a device header, surely is in emulator RAM and the disk is the disk? Here's the relevant snips of code just in case anyone can see the obvious error (which I can't yet):

C:
SCSIInstr gScsiProg[kScsiProgLen]={
    { scNoInc, 0UL, 0UL },
    { scStop, 0UL, 0UL }
};

#define Wrd(aWord) ((uint8_t)((aWord>>8)&255)), ((uint8_t)(aWord&255))
#define Lng(aLong) ((uint16_t)((aLong>>16)&0xffff)), \
                    ((uint16_t)(aLong&0xffff))
uint8_t gReadBlk[]={
    6, 8, Wrd(0), 0, 0, Wrd(0),
};

uint8_t gWriteBlk[]={ // offsets 2, 3, 4 are the block num (big-endian)
    6, 0xa, Wrd(0), 0, 0, Wrd(0),
};

void ScsiInit(short aId, uint8_t *aCmdBlock)
{
    SCSIGet();
    SCSISelect(aId);
    SCSICmd((char*)&aCmdBlock[1], *aCmdBlock);
}

short ScsiFinish(int16_t *aRetMsg, uint32_t aDelay)
{
    SCSIComplete(&gScsiStat, &gScsiMess, aDelay);
    *aRetMsg=gScsiMess;
    return gScsiStat;
}

void ScsiProgSet(SCSIInstr *aProg, uint8_t *aBuff, uint32_t aBytes)
{
    aProg->scParam1=(uint32_t)aBuff;
    aProg->scParam2=(uint32_t)aBytes;
}

short ScsiDoRead(int16_t *aRetMsg, uint32_t aTicks,
            short aId, uint8_t *aCmdBlock,
            uint8_t *aBuff, uint32_t aBytes)
{
    ScsiInit( aId, aCmdBlock);
    ScsiProgSet(gScsiProg, aBuff, aBytes);
    SCSIRead((Ptr)gScsiProg);
    return ScsiFinish(aRetMsg, aTicks);
}

short ScsiDoWrite(int16_t *aRetMsg, uint32_t aTicks,
            short aId, uint8_t *aCmdBlock,
            uint8_t *aBuff, uint32_t aBytes)
{
    ScsiInit( aId, aCmdBlock);
    ScsiProgSet(gScsiProg, aBuff, aBytes);
    SCSIWrite((Ptr)gScsiProg);
    return ScsiFinish(aRetMsg, aTicks);
}

tRawCopyInfo gRawCopyInfo;

void ScsiRawCopyInit(tRawCopyInfo *aInfo, uint16_t aId, int16_t aState)
{
    aInfo->iBlkPos=0UL;
    aInfo->iId=aId;
    if((aState&kRawCopyEventScsiOpMask)==kRawCopyEventScsiWrite) {
        GetEOF(aInfo->iFd, &(aInfo->iLen));
    }
    else {
        SetFPos(aInfo->iFd, fsFromStart, 0UL); // reset the file.
    }
    aInfo->iLenBlks=(aInfo->iLen+kBlkSize-1)>>kBlkSizeBits;
    aInfo->iState=aState; //kRawCopyEventGo;
}

//#define kScsiRawCopyDummy

void ScsiRawCopy(tRawCopyEvent aEvent /* oops, unused*/ )
{
    register tRawCopyInfo *info=&gRawCopyInfo;
    int32_t count;
    OSErr err=0;
    int32_t to=In(kUpdateRate);
    while(info->iLen && !After(to)) {
        tBool readOp=(info->iState&kRawCopyEventScsiOpMask)==
                                kRawCopyEventScsiRd;
        uint8_t *blkCmd=readOp? gReadBlk:gWriteBlk;
        count=kBlkSize;
        blkCmd[2]=(uint8_t)(info->iBlkPos>>16);
        blkCmd[3]=(uint8_t)(info->iBlkPos>>8);
        blkCmd[4]=(uint8_t)(info->iBlkPos&255);
        if(readOp) {
#ifndef kScsiRawCopyDummy
            ScsiDoRead(&gScsiMess, kStdWait, info->iId, blkCmd,
                gScsiBuf, kBlkSize);
#endif
            err=FSWrite(info->iFd, &count, gScsiBuf); // gScsiMess, gScsiStat
        }
        else {
            FSRead(info->iFd, &count, gScsiBuf); // gScsiMess, gScsiStat

#ifndef kScsiRawCopyDummy
            ScsiDoWrite(&gScsiMess, kStdWait, info->iId, gWriteBlk,
                gScsiBuf, kBlkSize);
#endif
        }
#ifdef kScsiRawCopyDummy
        {
            int32_t to=In(2);
            while(!After(to)) {
                // Delay 2 ticks.
            }
        }
#endif
        ++info->iBlkPos;
        if(err==noErr && info->iLen>kBlkSize) {
            info->iLen-=kBlkSize;
        }
        else {
            info->iLen=0;
        }
    }
    if(info->iLen==0) {
        FSClose(info->iFd);
        info->iState=kRawCopyEventDone;
        info->iFd=0; // Reset FD.
        AppMenuDDEnable(info);
    }
}

It works in dummy transfer mode though, I can create files of the right number of blocks containing whatever was in gScsiBuf. I guess people know a lot more about raw SCSI transfer than I do? It's currently 5.14kB long!

Ironically although I've not been able to scramble Saved HD on infinite Mac, I did manage to corrupt the System Folder on my miniVMac during some early testing of Dd:From..., forcing me to copy a System 6.0.8 from another HD image. I've now clocked up more System 6 experience than I've ever had in my whole life!

The current project and application (including the DumbDDDummy version, which doesn't actually read or write to SCSI drives) is attached.
 

Attachments

However, when I try and read from SCSI via Infinite Mac's Snow Mac IIcx emulator, I get:
That's an Infinite Mac error message. It's not from Snow. That's a bug for @mihai to fix.
I think device header means the part of the virtual SCSI HD that is not the HFS or HFS+ partition? i.e. the Apple Partition Map which is generated programatically if a disk image does not contain an Apple Partition Map.
I suppose you can work around this by changing your code to not use block ranges that cross partition boundaries? That means you need to have code that understand the Apple Partition Map. Or you would have to read one block at a time, which is probably slow.
 
Back
Top