@@ -2126,6 +2126,101 @@ def _unmount_mountpoint():
21262126 temp_volicon .unlink ()
21272127
21282128
2129+ def format_volume (
2130+ image : Path ,
2131+ driver : Optional [Path ],
2132+ block_size : Optional [int ],
2133+ partition : str ,
2134+ volname : str = "Empty" ,
2135+ debug : bool = False ,
2136+ ):
2137+ import amitools .fs .DosType as DosType
2138+
2139+ # Get partition dostype from RDB
2140+ part_info = get_partition_info (image , block_size , partition )
2141+ dostype = part_info ["dostype" ]
2142+ if dostype is None :
2143+ raise SystemExit (f"Could not determine dostype for partition '{ partition } '." )
2144+ dt_str = DosType .num_to_tag_str (dostype )
2145+
2146+ # Resolve driver
2147+ temp_driver = None
2148+ if driver is None :
2149+ try :
2150+ result = extract_embedded_driver (image , block_size , partition )
2151+ except IOError as e :
2152+ raise SystemExit (f"Error: { e } " )
2153+ if result is None :
2154+ raise SystemExit (
2155+ "No embedded filesystem driver found for this partition.\n "
2156+ "You need to specify a filesystem handler with --driver"
2157+ )
2158+ temp_driver , _ , _ = result
2159+ driver = temp_driver
2160+ driver_desc = f"{ dt_str } /0x{ dostype :08x} (from RDB)"
2161+ else :
2162+ driver_desc = str (driver )
2163+
2164+ print (__banner__ )
2165+ print (f"Formatting partition '{ partition } ' in { image } " )
2166+ print (f"Filesystem driver: { driver_desc } " )
2167+ print (f"Volume name: { volname } " )
2168+ print (f"DOS type: { dt_str } (0x{ dostype :08x} )" )
2169+
2170+ try :
2171+ bridge = HandlerBridge (
2172+ image ,
2173+ driver ,
2174+ block_size = block_size ,
2175+ read_only = False ,
2176+ debug = debug ,
2177+ partition = partition ,
2178+ )
2179+
2180+ # Inhibit the volume so the handler releases it for formatting
2181+ bridge .launcher .send_inhibit (bridge .state , True )
2182+ replies = bridge ._run_until_replies ()
2183+ if debug and replies :
2184+ _ , _ , r1 , r2 = replies [- 1 ]
2185+ print (f"[amifuse] INHIBIT reply: res1={ r1 } res2={ r2 } " )
2186+
2187+ # Allocate volume name BSTR and send ACTION_FORMAT
2188+ _ , volname_bptr = bridge .launcher .alloc_bstr (volname , label = "FormatVolName" )
2189+ bridge .launcher .send_format (bridge .state , volname_bptr , dostype )
2190+ replies = bridge ._run_until_replies ()
2191+
2192+ if not replies :
2193+ raise SystemExit ("Format failed: no reply from handler." )
2194+
2195+ _ , pkt_addr , res1 , res2 = replies [- 1 ]
2196+ if res1 == 0 :
2197+ error_msgs = {
2198+ 205 : "Object in use" ,
2199+ 218 : "Not a valid DOS disk" ,
2200+ 225 : "Not a DOS disk" ,
2201+ 226 : "Wrong disk type" ,
2202+ 232 : "Disk is write-protected" ,
2203+ }
2204+ error_desc = error_msgs .get (res2 , f"error code { res2 } " )
2205+ raise SystemExit (f"Format failed: { error_desc } " )
2206+
2207+ if debug :
2208+ print (f"[amifuse] FORMAT reply: res1={ res1 } res2={ res2 } " )
2209+
2210+ # Uninhibit to re-mount the newly formatted volume
2211+ bridge .launcher .send_inhibit (bridge .state , False )
2212+ bridge ._run_until_replies ()
2213+
2214+ # Flush to ensure data is written
2215+ bridge .launcher .send_flush (bridge .state )
2216+ bridge ._run_until_replies ()
2217+
2218+ print (f"Format complete. Volume '{ volname } ' created on partition '{ partition } '." )
2219+ finally :
2220+ if temp_driver is not None and temp_driver .exists ():
2221+ temp_driver .unlink ()
2222+
2223+
21292224__version__ = "v0.3.0"
21302225__banner__ = f"amifuse { __version__ } - Copyright (C) 2025-2026 by Stefan Reinauer"
21312226
@@ -2248,6 +2343,16 @@ def cmd_mount(args):
22482343 stats .print_stats ()
22492344
22502345
2346+ def cmd_format (args ):
2347+ """Handle the 'format' subcommand."""
2348+ format_volume (
2349+ args .image , args .driver , args .block_size ,
2350+ partition = args .partition ,
2351+ volname = args .volname ,
2352+ debug = args .debug ,
2353+ )
2354+
2355+
22512356def main (argv = None ):
22522357 parser = argparse .ArgumentParser (
22532358 description = f"{ __banner__ } \n \n "
@@ -2270,6 +2375,12 @@ def main(argv=None):
22702375 --debug Enable debug logging of FUSE operations.
22712376 --trace Enable vamos instruction tracing (very noisy).
22722377 --profile Enable profiling and write stats to profile.txt.
2378+
2379+ format <image> <partition> [volname]
2380+ Format an Amiga partition.
2381+ --driver PATH Filesystem binary (default: extract from RDB).
2382+ --block-size N Override block size (defaults to auto/512).
2383+ --debug Enable debug logging.
22732384""" ,
22742385 )
22752386 parser .add_argument (
@@ -2328,6 +2439,22 @@ def main(argv=None):
23282439 )
23292440 mount_parser .set_defaults (func = cmd_mount )
23302441
2442+ # format subcommand
2443+ format_parser = subparsers .add_parser (
2444+ "format" , help = "Format an Amiga partition."
2445+ )
2446+ format_parser .add_argument ("image" , type = Path , help = "Disk image file" )
2447+ format_parser .add_argument ("partition" , type = str , help = "Partition name (e.g. DH0) or index." )
2448+ format_parser .add_argument ("volname" , nargs = "?" , default = "Empty" , help = "Volume name (default: Empty)" )
2449+ format_parser .add_argument ("--driver" , type = Path , help = "Filesystem binary (default: extract from RDB if available)" )
2450+ format_parser .add_argument (
2451+ "--block-size" , type = int , help = "Override block size (defaults to auto/512)."
2452+ )
2453+ format_parser .add_argument (
2454+ "--debug" , action = "store_true" , help = "Enable debug logging."
2455+ )
2456+ format_parser .set_defaults (func = cmd_format )
2457+
23312458 args = parser .parse_args (argv )
23322459 args .func (args )
23332460
0 commit comments