Here is an AppleScript to simplify reading/writing X/ProFile CF cards.
I speculate the main advantages are:
- automagically calculates how much of the CF card is used for the STARs, and only that portion of the card is read, saving time and space.
- checks the specified volume was formatted by the X/ProFile, reducing the chance of overwriting the wrong thing
Use requires a Mac and a way to connect your CF card (or other X/ProFile media) to the Mac... typically one would use a USB CF card reader.
This was initially tested on Tiger (10.4) ... I imagine that can still be made to work, and most recently Sierra (10.12).
If you wish to port the code, note that AppleScript is 1 based, so reading bytes 9 to 12 (as in the getstarsize subroutine) gives you the 9th to 12th bytes.
To use, select & copy the following code, paste into a Script Editor document, and run it.
-- Created by James MacPhail for free distribution in the public domain.
-- Use at your own risk.
--
-- Please post improvements and bug reports to the "XProFile CF Card Image Tool" thread at LisaList2.com
--
-- this applescript is used to read/write an image of an X/ProFile CF card from/to a physical CF card using dd
-- (although developed for CF cards, this should work with any X/ProFile storage device)
--
-- administrator privileges will be requested for accessing the device
--
-- the CF card is examined to make sure it has already been formatted by the X/ProFile to ensure the correct device has been located
--
-- the image created from reading an XProFile CF card contains both STARs and the X/ProFile disk image preamble
-- when reading, the image size is adjusted to suit the size of the larger STAR
-- (so you'll have a 20-40 MB image if you have one 10MB STAR and one 5MB STAR on a 2GB CF card)
--
-- Usage Notes:
-- When inserting a CF card to read/write, it may take a while until the OS has found it; trying to access it too soon will fail with "X/ProFile CF card not found"
-- no compression or data error detection is used for the images, so zipping an image will be beneficial when sending via email etc.
-- when writing to a CF card, the file selected to write is not validated as an XProFile image, it is blindly written to the target
--
-- 1.2 : Saturday, May 16, 2020 at 2:44:04 PM : Corrected error message for touching image to read into
-- 1.1 : Friday, April 26, 2019 3:49:25 PM : Extended timeouts for read and write operations
-- 1.0 : 2017-08-12 12:55pm : First version distributed for beta testing
--
property versiondate : "Saturday, May 16, 2020 at 2:44:04 PM"
property expected : "This is an image of a ProFile hard disk in a proprietary format. This file is used by the ProFile emulator for the Apple ][, Apple ///, Apple Lisa, and Macintosh XL. http://SigmaSevenSystems.com"
--
-- ask diskutil if there is an X/ProFile volume
try
set dul to do shell script "diskutil list | grep XPROFILE"
on error err number errno
display dialog "X/ProFile CF card not found." buttons " Cancel " default button " Cancel "
return
end try
--
-- ensure there is only one
if (count paragraphs of dul) > 1 then
display dialog "More than one X/ProFile CF card is attached: too ambiguous to continue." buttons " Cancel " default button " Cancel "
return
end if
--
-- extract device of X/ProFile card
set subdisk to last word of dul
set disk to (characters 1 through -3 of subdisk) as text
--
-- read signature from card to verify it was formatted by X/ProFile
try
set chktext to do shell script ("dd bs=1 skip=97320 count=194 if=/dev/" & disk) with administrator privileges
on error err number errno
set de to my displayerror(err, errno, "Failed to read from CF card.")
return
end try
if not (chktext = expected) then
display dialog "X/ProFile signature not found on CF card" buttons " Cancel " default button " Cancel "
return
end if
--
-- determine function
set ddfn to display dialog "Read from CF card or Write to CF card?" buttons {" Cancel ", "Write", "Read"} default button "Read"
if button returned of ddfn is " Cancel " then
return
else if button returned of ddfn is "Read" then
-- read from card to create image
set {haseven, evensize, hasodd, oddsize} to {false, 0, false, 0}
-- read STAR headers from card
try
set starinfoeven to do shell script ("dd bs=1 skip=97744 count=48 if=/dev/" & disk) with administrator privileges
set starinfoodd to do shell script ("dd bs=1 skip=98256 count=48 if=/dev/" & disk) with administrator privileges
on error err number errno
set de to my displayerror(err, errno, "Failed to read STAR info from CF card.")
return
end try
set sig5aa5 to (ASCII character (90)) & (ASCII character (165)) -- $5A A5
if starinfoeven begins with sig5aa5 then set haseven to true
if starinfoodd begins with sig5aa5 then set hasodd to true
--
-- extract disk space used in number of blocks
if haseven then set evensize to my getstarsize(starinfoeven)
if hasodd then set oddsize to my getstarsize(starinfoodd)
--
-- determine larger space used
set readsize to evensize
if oddsize > readsize then set readsize to oddsize
if readsize = 0 then
set dd to display dialog ("Image size cannot be determined. Read entire card?") buttons {"OK", " Cancel "} default button " Cancel "
if button returned of dd is " Cancel " then return
set countspec to ""
set promptspec to "Name the image file (size unknown)"
else
set countspec to " count=" & (readsize + 2) -- correct size because count is 1 based, STAR last sector was zero based
set promptspec to "Name the image file (" & (round ((readsize * 512) / 10000)) / 100 & " MB)"
end if
--
-- select output file
set outfile to choose file name with prompt promptspec
--
-- if file does not exist, create it without administrator privileges so it will have the user as the owner
set crf to "touch " & quoted form of (POSIX path of outfile)
try
set crfr to do shell script crf without administrator privileges -- using administrator privileges would make it a system file the user can't overwrite
on error err number errno
set de to my displayerror(err, errno, "Failed to access or create destination image file.")
error err
end try
--
-- read CF card to image file
set rtoi to "dd bs=0x200" & countspec & " if=/dev/" & disk & " of=" & quoted form of (POSIX path of outfile)
try
with timeout of 6000 seconds
set rtoir to do shell script rtoi with administrator privileges
end timeout
on error err number errno
set de to my displayerror(err, errno, "Failed when reading CF card / writing image.")
end try
beep
set dd to display dialog "Read completed" buttons {"OK"} default button "OK"
--
else if button returned of ddfn is "Write" then
--
-- ask for image to write to card
set ff to choose file with prompt "Select X/ProFile image file"
set fp to quoted form of POSIX path of ff
--
-- unmount device
set duu to "diskutil unmountDisk force /dev/" & disk
try
set dur to do shell script duu with administrator privileges
on error err number errno
set de to my displayerror(err, errno, "Failed to unmount CF card.")
return
end try
--
-- confirm
set dd to display dialog "Ready to overwrite the CF card; are you sure? (Writing may take a few minutes)" buttons {"Continue", " Cancel "}
if button returned of dd is not "Continue" then return
--
-- write image to device
set ddc to ("sudo dd if=" & fp & " of=/dev/" & disk)
try
with timeout of 6000 seconds
set ddr to do shell script ddc with administrator privileges
end timeout
on error err number errno
set de to my displayerror(err, errno, "Failed when writing image to CF card.")
return
end try
--
beep
set dd to display dialog "Write completed" buttons {"OK"} default button "OK"
end if
return
--
--
to getstarsize(starinfo)
set starsize to 0
repeat with i from 9 to 12
set starsize to starsize * 256 + (ASCII number (character i of starinfo))
end repeat
return starsize
end getstarsize
--
--
to displayerror(err, errno, msg)
beep
set dd to display dialog (msg & " Error " & errno & ": " & err) buttons " Cancel " default button " Cancel "
return 1
end displayerror
--
-- END