mirror of
				https://github.com/davidgiven/fluxengine.git
				synced 2025-10-24 11:11:02 -07:00 
			
		
		
		
	Merge pull request #822 from davidgiven/config
Overhaul the config file CLI.
This commit is contained in:
		
							
								
								
									
										18
									
								
								build.py
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								build.py
									
									
									
									
									
								
							| @@ -28,7 +28,7 @@ else: | ||||
|         ("acorndfs", "", "--200"), | ||||
|         ("agat", "", ""), | ||||
|         ("amiga", "", ""), | ||||
|         ("apple2", "", "--140 40track_drive"), | ||||
|         ("apple2", "", "--140 --drivetype=40"), | ||||
|         ("atarist", "", "--360"), | ||||
|         ("atarist", "", "--370"), | ||||
|         ("atarist", "", "--400"), | ||||
| @@ -38,17 +38,17 @@ else: | ||||
|         ("atarist", "", "--800"), | ||||
|         ("atarist", "", "--820"), | ||||
|         ("bk", "", ""), | ||||
|         ("brother", "", "--120 40track_drive"), | ||||
|         ("brother", "", "--120 --drivetype=40"), | ||||
|         ("brother", "", "--240"), | ||||
|         ( | ||||
|             "commodore", | ||||
|             "scripts/commodore1541_test.textpb", | ||||
|             "--171 40track_drive", | ||||
|             "--171 --drivetype=40", | ||||
|         ), | ||||
|         ( | ||||
|             "commodore", | ||||
|             "scripts/commodore1541_test.textpb", | ||||
|             "--192 40track_drive", | ||||
|             "--192 --drivetype=40", | ||||
|         ), | ||||
|         ("commodore", "", "--800"), | ||||
|         ("commodore", "", "--1620"), | ||||
| @@ -60,17 +60,17 @@ else: | ||||
|         ("ibm", "", "--1232"), | ||||
|         ("ibm", "", "--1440"), | ||||
|         ("ibm", "", "--1680"), | ||||
|         ("ibm", "", "--180 40track_drive"), | ||||
|         ("ibm", "", "--160 40track_drive"), | ||||
|         ("ibm", "", "--320 40track_drive"), | ||||
|         ("ibm", "", "--360 40track_drive"), | ||||
|         ("ibm", "", "--180 --drivetype=40"), | ||||
|         ("ibm", "", "--160 --drivetype=40"), | ||||
|         ("ibm", "", "--320 --drivetype=40"), | ||||
|         ("ibm", "", "--360 --drivetype=40"), | ||||
|         ("ibm", "", "--720_96"), | ||||
|         ("ibm", "", "--720_135"), | ||||
|         ("mac", "scripts/mac400_test.textpb", "--400"), | ||||
|         ("mac", "scripts/mac800_test.textpb", "--800"), | ||||
|         ("n88basic", "", ""), | ||||
|         ("rx50", "", ""), | ||||
|         ("tartu", "", "--390 40track_drive"), | ||||
|         ("tartu", "", "--390 --drivetype=40"), | ||||
|         ("tartu", "", "--780"), | ||||
|         ("tids990", "", ""), | ||||
|         ("victor9k", "", "--612"), | ||||
|   | ||||
| @@ -31,9 +31,9 @@ they might require nudging as the side order can't be reliably autodetected. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read acornadfs --160 -s drive:0 -o acornadfs.img` | ||||
|   - `fluxengine read acornadfs --320 -s drive:0 -o acornadfs.img` | ||||
|   - `fluxengine read acornadfs --640 -s drive:0 -o acornadfs.img` | ||||
|   - `fluxengine read acornadfs --800 -s drive:0 -o acornadfs.img` | ||||
|   - `fluxengine read acornadfs --1600 -s drive:0 -o acornadfs.img` | ||||
|   - `fluxengine read -c acornadfs --160 -s drive:0 -o acornadfs.img` | ||||
|   - `fluxengine read -c acornadfs --320 -s drive:0 -o acornadfs.img` | ||||
|   - `fluxengine read -c acornadfs --640 -s drive:0 -o acornadfs.img` | ||||
|   - `fluxengine read -c acornadfs --800 -s drive:0 -o acornadfs.img` | ||||
|   - `fluxengine read -c acornadfs --1600 -s drive:0 -o acornadfs.img` | ||||
|  | ||||
|   | ||||
| @@ -24,13 +24,13 @@ requires a bit of fiddling as they have the same tracks on twice. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read acorndfs --100 -s drive:0 -o acorndfs.img` | ||||
|   - `fluxengine read acorndfs --200 -s drive:0 -o acorndfs.img` | ||||
|   - `fluxengine read -c acorndfs --100 -s drive:0 -o acorndfs.img` | ||||
|   - `fluxengine read -c acorndfs --200 -s drive:0 -o acorndfs.img` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write acorndfs --100 -d drive:0 -i acorndfs.img` | ||||
|   - `fluxengine write acorndfs --200 -d drive:0 -i acorndfs.img` | ||||
|   - `fluxengine write -c acorndfs --100 -d drive:0 -i acorndfs.img` | ||||
|   - `fluxengine write -c acorndfs --200 -d drive:0 -i acorndfs.img` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -37,7 +37,7 @@ based on what looks right. If anyone knows _anything_ about these disks, | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read aeslanier -s drive:0 -o aeslanier.img` | ||||
|   - `fluxengine read -c aeslanier -s drive:0 -o aeslanier.img` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -20,11 +20,11 @@ profile. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read agat -s drive:0 -o agat.img` | ||||
|   - `fluxengine read -c agat -s drive:0 -o agat.img` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write agat -d drive:0 -i agat.img` | ||||
|   - `fluxengine write -c agat -d drive:0 -i agat.img` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -26,11 +26,11 @@ distinctly subpar and not particularly good at detecting errors. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read amiga -s drive:0 -o amiga.adf` | ||||
|   - `fluxengine read -c amiga -s drive:0 -o amiga.adf` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write amiga -d drive:0 -i amiga.adf` | ||||
|   - `fluxengine write -c amiga -d drive:0 -i amiga.adf` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -43,8 +43,8 @@ kayinfo.lbr | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read ampro --400 -s drive:0 -o ampro.img` | ||||
|   - `fluxengine read ampro --800 -s drive:0 -o ampro.img` | ||||
|   - `fluxengine read -c ampro --400 -s drive:0 -o ampro.img` | ||||
|   - `fluxengine read -c ampro --800 -s drive:0 -o ampro.img` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -58,13 +58,13 @@ volume. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read apple2 --140 -s drive:0 -o apple2.img` | ||||
|   - `fluxengine read apple2 --640 -s drive:0 -o apple2.img` | ||||
|   - `fluxengine read -c apple2 --140 -s drive:0 -o apple2.img` | ||||
|   - `fluxengine read -c apple2 --640 -s drive:0 -o apple2.img` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write apple2 --140 -d drive:0 -i apple2.img` | ||||
|   - `fluxengine write apple2 --640 -d drive:0 -i apple2.img` | ||||
|   - `fluxengine write -c apple2 --140 -d drive:0 -i apple2.img` | ||||
|   - `fluxengine write -c apple2 --640 -d drive:0 -i apple2.img` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -29,25 +29,25 @@ Be aware that many PC drives (including mine) won't do the 82 track formats. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read atarist --360 -s drive:0 -o atarist.img` | ||||
|   - `fluxengine read atarist --370 -s drive:0 -o atarist.img` | ||||
|   - `fluxengine read atarist --400 -s drive:0 -o atarist.img` | ||||
|   - `fluxengine read atarist --410 -s drive:0 -o atarist.img` | ||||
|   - `fluxengine read atarist --720 -s drive:0 -o atarist.img` | ||||
|   - `fluxengine read atarist --740 -s drive:0 -o atarist.img` | ||||
|   - `fluxengine read atarist --800 -s drive:0 -o atarist.img` | ||||
|   - `fluxengine read atarist --820 -s drive:0 -o atarist.img` | ||||
|   - `fluxengine read -c atarist --360 -s drive:0 -o atarist.img` | ||||
|   - `fluxengine read -c atarist --370 -s drive:0 -o atarist.img` | ||||
|   - `fluxengine read -c atarist --400 -s drive:0 -o atarist.img` | ||||
|   - `fluxengine read -c atarist --410 -s drive:0 -o atarist.img` | ||||
|   - `fluxengine read -c atarist --720 -s drive:0 -o atarist.img` | ||||
|   - `fluxengine read -c atarist --740 -s drive:0 -o atarist.img` | ||||
|   - `fluxengine read -c atarist --800 -s drive:0 -o atarist.img` | ||||
|   - `fluxengine read -c atarist --820 -s drive:0 -o atarist.img` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write atarist --360 -d drive:0 -i atarist.img` | ||||
|   - `fluxengine write atarist --370 -d drive:0 -i atarist.img` | ||||
|   - `fluxengine write atarist --400 -d drive:0 -i atarist.img` | ||||
|   - `fluxengine write atarist --410 -d drive:0 -i atarist.img` | ||||
|   - `fluxengine write atarist --720 -d drive:0 -i atarist.img` | ||||
|   - `fluxengine write atarist --740 -d drive:0 -i atarist.img` | ||||
|   - `fluxengine write atarist --800 -d drive:0 -i atarist.img` | ||||
|   - `fluxengine write atarist --820 -d drive:0 -i atarist.img` | ||||
|   - `fluxengine write -c atarist --360 -d drive:0 -i atarist.img` | ||||
|   - `fluxengine write -c atarist --370 -d drive:0 -i atarist.img` | ||||
|   - `fluxengine write -c atarist --400 -d drive:0 -i atarist.img` | ||||
|   - `fluxengine write -c atarist --410 -d drive:0 -i atarist.img` | ||||
|   - `fluxengine write -c atarist --720 -d drive:0 -i atarist.img` | ||||
|   - `fluxengine write -c atarist --740 -d drive:0 -i atarist.img` | ||||
|   - `fluxengine write -c atarist --800 -d drive:0 -i atarist.img` | ||||
|   - `fluxengine write -c atarist --820 -d drive:0 -i atarist.img` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -22,9 +22,9 @@ on what was available at the time, with the same format on both. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read bk -s drive:0 -o bk800.img` | ||||
|   - `fluxengine read -c bk -s drive:0 -o bk800.img` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write bk -d drive:0 -i bk800.img` | ||||
|   - `fluxengine write -c bk -d drive:0 -i bk800.img` | ||||
|  | ||||
|   | ||||
| @@ -44,13 +44,13 @@ investigate. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read brother --120 -s drive:0 -o brother.img` | ||||
|   - `fluxengine read brother --240 -s drive:0 -o brother.img` | ||||
|   - `fluxengine read -c brother --120 -s drive:0 -o brother.img` | ||||
|   - `fluxengine read -c brother --240 -s drive:0 -o brother.img` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write brother --120 -d drive:0 -i brother.img` | ||||
|   - `fluxengine write brother --240 -d drive:0 -i brother.img` | ||||
|   - `fluxengine write -c brother --120 -d drive:0 -i brother.img` | ||||
|   - `fluxengine write -c brother --240 -d drive:0 -i brother.img` | ||||
|  | ||||
| Dealing with misaligned disks | ||||
| ----------------------------- | ||||
|   | ||||
| @@ -54,18 +54,18 @@ A CMD FD2000 disk (a popular third-party Commodore disk drive) | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read commodore --171 -s drive:0 -o commodore.d64` | ||||
|   - `fluxengine read commodore --192 -s drive:0 -o commodore.d64` | ||||
|   - `fluxengine read commodore --800 -s drive:0 -o commodore.d64` | ||||
|   - `fluxengine read commodore --1042 -s drive:0 -o commodore.d64` | ||||
|   - `fluxengine read commodore --1620 -s drive:0 -o commodore.d64` | ||||
|   - `fluxengine read -c commodore --171 -s drive:0 -o commodore.d64` | ||||
|   - `fluxengine read -c commodore --192 -s drive:0 -o commodore.d64` | ||||
|   - `fluxengine read -c commodore --800 -s drive:0 -o commodore.d64` | ||||
|   - `fluxengine read -c commodore --1042 -s drive:0 -o commodore.d64` | ||||
|   - `fluxengine read -c commodore --1620 -s drive:0 -o commodore.d64` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write commodore --171 -d drive:0 -i commodore.d64` | ||||
|   - `fluxengine write commodore --192 -d drive:0 -i commodore.d64` | ||||
|   - `fluxengine write commodore --800 -d drive:0 -i commodore.d64` | ||||
|   - `fluxengine write commodore --1620 -d drive:0 -i commodore.d64` | ||||
|   - `fluxengine write -c commodore --171 -d drive:0 -i commodore.d64` | ||||
|   - `fluxengine write -c commodore --192 -d drive:0 -i commodore.d64` | ||||
|   - `fluxengine write -c commodore --800 -d drive:0 -i commodore.d64` | ||||
|   - `fluxengine write -c commodore --1620 -d drive:0 -i commodore.d64` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -33,7 +33,7 @@ images. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read eco1 -s drive:0 -o eco1.img` | ||||
|   - `fluxengine read -c eco1 -s drive:0 -o eco1.img` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -15,5 +15,5 @@ format itself is yet another IBM scheme variant. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read epsonpf10 -s drive:0 -o epsonpf10.img` | ||||
|   - `fluxengine read -c epsonpf10 -s drive:0 -o epsonpf10.img` | ||||
|  | ||||
|   | ||||
| @@ -36,7 +36,7 @@ touch](https://github.com/davidgiven/fluxengine/issues/new). | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read f85 -s drive:0 -o f85.img` | ||||
|   - `fluxengine read -c f85 -s drive:0 -o f85.img` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -30,7 +30,7 @@ I don't have access to one of those disks. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read fb100 -s drive:0 -o fb100.img` | ||||
|   - `fluxengine read -c fb100 -s drive:0 -o fb100.img` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -23,17 +23,17 @@ encoding scheme. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read hplif --264 -s drive:0 -o hplif.img` | ||||
|   - `fluxengine read hplif --608 -s drive:0 -o hplif.img` | ||||
|   - `fluxengine read hplif --616 -s drive:0 -o hplif.img` | ||||
|   - `fluxengine read hplif --770 -s drive:0 -o hplif.img` | ||||
|   - `fluxengine read -c hplif --264 -s drive:0 -o hplif.img` | ||||
|   - `fluxengine read -c hplif --608 -s drive:0 -o hplif.img` | ||||
|   - `fluxengine read -c hplif --616 -s drive:0 -o hplif.img` | ||||
|   - `fluxengine read -c hplif --770 -s drive:0 -o hplif.img` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write hplif --264 -d drive:0 -i hplif.img` | ||||
|   - `fluxengine write hplif --608 -d drive:0 -i hplif.img` | ||||
|   - `fluxengine write hplif --616 -d drive:0 -i hplif.img` | ||||
|   - `fluxengine write hplif --770 -d drive:0 -i hplif.img` | ||||
|   - `fluxengine write -c hplif --264 -d drive:0 -i hplif.img` | ||||
|   - `fluxengine write -c hplif --608 -d drive:0 -i hplif.img` | ||||
|   - `fluxengine write -c hplif --616 -d drive:0 -i hplif.img` | ||||
|   - `fluxengine write -c hplif --770 -d drive:0 -i hplif.img` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -55,30 +55,30 @@ image format. FluxEngine will use these parameters. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read ibm --auto -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read ibm --160 -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read ibm --180 -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read ibm --320 -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read ibm --360 -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read ibm --720_96 -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read ibm --720_135 -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read ibm --1200 -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read ibm --1232 -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read ibm --1440 -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read ibm --1680 -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read -c ibm --auto -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read -c ibm --160 -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read -c ibm --180 -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read -c ibm --320 -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read -c ibm --360 -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read -c ibm --720_96 -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read -c ibm --720_135 -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read -c ibm --1200 -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read -c ibm --1232 -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read -c ibm --1440 -s drive:0 -o ibm.img` | ||||
|   - `fluxengine read -c ibm --1680 -s drive:0 -o ibm.img` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write ibm --160 -d drive:0 -i ibm.img` | ||||
|   - `fluxengine write ibm --180 -d drive:0 -i ibm.img` | ||||
|   - `fluxengine write ibm --320 -d drive:0 -i ibm.img` | ||||
|   - `fluxengine write ibm --360 -d drive:0 -i ibm.img` | ||||
|   - `fluxengine write ibm --720_96 -d drive:0 -i ibm.img` | ||||
|   - `fluxengine write ibm --720_135 -d drive:0 -i ibm.img` | ||||
|   - `fluxengine write ibm --1200 -d drive:0 -i ibm.img` | ||||
|   - `fluxengine write ibm --1232 -d drive:0 -i ibm.img` | ||||
|   - `fluxengine write ibm --1440 -d drive:0 -i ibm.img` | ||||
|   - `fluxengine write ibm --1680 -d drive:0 -i ibm.img` | ||||
|   - `fluxengine write -c ibm --160 -d drive:0 -i ibm.img` | ||||
|   - `fluxengine write -c ibm --180 -d drive:0 -i ibm.img` | ||||
|   - `fluxengine write -c ibm --320 -d drive:0 -i ibm.img` | ||||
|   - `fluxengine write -c ibm --360 -d drive:0 -i ibm.img` | ||||
|   - `fluxengine write -c ibm --720_96 -d drive:0 -i ibm.img` | ||||
|   - `fluxengine write -c ibm --720_135 -d drive:0 -i ibm.img` | ||||
|   - `fluxengine write -c ibm --1200 -d drive:0 -i ibm.img` | ||||
|   - `fluxengine write -c ibm --1232 -d drive:0 -i ibm.img` | ||||
|   - `fluxengine write -c ibm --1440 -d drive:0 -i ibm.img` | ||||
|   - `fluxengine write -c ibm --1680 -d drive:0 -i ibm.img` | ||||
|  | ||||
| Mixed-format disks | ||||
| ------------------ | ||||
|   | ||||
| @@ -15,5 +15,5 @@ track! Other than that it's another IBM scheme variation. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read icl30 -s drive:0 -o icl30.img` | ||||
|   - `fluxengine read -c icl30 -s drive:0 -o icl30.img` | ||||
|  | ||||
|   | ||||
| @@ -47,13 +47,13 @@ standard for disk images is to omit it. If you want them, specify that you want | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read mac --400 -s drive:0 -o mac.dsk` | ||||
|   - `fluxengine read mac --800 -s drive:0 -o mac.dsk` | ||||
|   - `fluxengine read -c mac --400 -s drive:0 -o mac.dsk` | ||||
|   - `fluxengine read -c mac --800 -s drive:0 -o mac.dsk` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write mac --400 -d drive:0 -i mac.dsk` | ||||
|   - `fluxengine write mac --800 -d drive:0 -i mac.dsk` | ||||
|   - `fluxengine write -c mac --400 -d drive:0 -i mac.dsk` | ||||
|   - `fluxengine write -c mac --800 -d drive:0 -i mac.dsk` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -63,11 +63,11 @@ need to apply extra options to change the format if desired. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read micropolis -s drive:0 -o micropolis.img` | ||||
|   - `fluxengine read -c micropolis -s drive:0 -o micropolis.img` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write micropolis -d drive:0 -i micropolis.img` | ||||
|   - `fluxengine write -c micropolis -d drive:0 -i micropolis.img` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -52,10 +52,10 @@ Words are all stored little-endian. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read mx --110 -s drive:0 -o mx.img` | ||||
|   - `fluxengine read mx --220ds -s drive:0 -o mx.img` | ||||
|   - `fluxengine read mx --220ss -s drive:0 -o mx.img` | ||||
|   - `fluxengine read mx --440 -s drive:0 -o mx.img` | ||||
|   - `fluxengine read -c mx --110 -s drive:0 -o mx.img` | ||||
|   - `fluxengine read -c mx --220ds -s drive:0 -o mx.img` | ||||
|   - `fluxengine read -c mx --220ss -s drive:0 -o mx.img` | ||||
|   - `fluxengine read -c mx --440 -s drive:0 -o mx.img` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -18,9 +18,9 @@ boot ROM could only read single density data.) | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read n88basic -s drive:0 -o n88basic.img` | ||||
|   - `fluxengine read -c n88basic -s drive:0 -o n88basic.img` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write n88basic -d drive:0 -i n88basic.img` | ||||
|   - `fluxengine write -c n88basic -d drive:0 -i n88basic.img` | ||||
|  | ||||
|   | ||||
| @@ -31,15 +31,15 @@ equivalent to .img images. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read northstar --87 -s drive:0 -o northstar.nsi` | ||||
|   - `fluxengine read northstar --175 -s drive:0 -o northstar.nsi` | ||||
|   - `fluxengine read northstar --350 -s drive:0 -o northstar.nsi` | ||||
|   - `fluxengine read -c northstar --87 -s drive:0 -o northstar.nsi` | ||||
|   - `fluxengine read -c northstar --175 -s drive:0 -o northstar.nsi` | ||||
|   - `fluxengine read -c northstar --350 -s drive:0 -o northstar.nsi` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write northstar --87 -d drive:0 -i northstar.nsi` | ||||
|   - `fluxengine write northstar --175 -d drive:0 -i northstar.nsi` | ||||
|   - `fluxengine write northstar --350 -d drive:0 -i northstar.nsi` | ||||
|   - `fluxengine write -c northstar --87 -d drive:0 -i northstar.nsi` | ||||
|   - `fluxengine write -c northstar --175 -d drive:0 -i northstar.nsi` | ||||
|   - `fluxengine write -c northstar --350 -d drive:0 -i northstar.nsi` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -24,9 +24,9 @@ and, oddly, swapped sides. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read psos -s drive:0 -o pme.img` | ||||
|   - `fluxengine read -c psos -s drive:0 -o pme.img` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write psos -d drive:0 -i pme.img` | ||||
|   - `fluxengine write -c psos -d drive:0 -i pme.img` | ||||
|  | ||||
|   | ||||
| @@ -40,9 +40,9 @@ for assistance with this! | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read rolandd20 -s drive:0 -o rolandd20.img` | ||||
|   - `fluxengine read -c rolandd20 -s drive:0 -o rolandd20.img` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write rolandd20 -d drive:0 -i rolandd20.img` | ||||
|   - `fluxengine write -c rolandd20 -d drive:0 -i rolandd20.img` | ||||
|  | ||||
|   | ||||
| @@ -15,9 +15,9 @@ vanilla single-sided IBM scheme variation. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read rx50 -s drive:0 -o rx50.img` | ||||
|   - `fluxengine read -c rx50 -s drive:0 -o rx50.img` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write rx50 -d drive:0 -i rx50.img` | ||||
|   - `fluxengine write -c rx50 -d drive:0 -i rx50.img` | ||||
|  | ||||
|   | ||||
| @@ -26,7 +26,7 @@ this is completely correct, so don't trust it! | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read smaky6 -s drive:0 -o smaky6.img` | ||||
|   - `fluxengine read -c smaky6 -s drive:0 -o smaky6.img` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -34,13 +34,13 @@ FluxEngine supports reading and writing Tartu disks with CP/M filesystem access. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read tartu --390 -s drive:0 -o tartu.img` | ||||
|   - `fluxengine read tartu --780 -s drive:0 -o tartu.img` | ||||
|   - `fluxengine read -c tartu --390 -s drive:0 -o tartu.img` | ||||
|   - `fluxengine read -c tartu --780 -s drive:0 -o tartu.img` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write tartu --390 -d drive:0 -i tartu.img` | ||||
|   - `fluxengine write tartu --780 -d drive:0 -i tartu.img` | ||||
|   - `fluxengine write -c tartu --390 -d drive:0 -i tartu.img` | ||||
|   - `fluxengine write -c tartu --780 -d drive:0 -i tartu.img` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -26,11 +26,11 @@ FluxEngine will read and write these (but only the DSDD MFM variant). | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read tids990 -s drive:0 -o tids990.img` | ||||
|   - `fluxengine read -c tids990 -s drive:0 -o tids990.img` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write tids990 -d drive:0 -i tids990.img` | ||||
|   - `fluxengine write -c tids990 -d drive:0 -i tids990.img` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -20,8 +20,8 @@ on the precise format. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read tiki --90 -s drive:0 -o tiki.img` | ||||
|   - `fluxengine read tiki --200 -s drive:0 -o tiki.img` | ||||
|   - `fluxengine read tiki --400 -s drive:0 -o tiki.img` | ||||
|   - `fluxengine read tiki --800 -s drive:0 -o tiki.img` | ||||
|   - `fluxengine read -c tiki --90 -s drive:0 -o tiki.img` | ||||
|   - `fluxengine read -c tiki --200 -s drive:0 -o tiki.img` | ||||
|   - `fluxengine read -c tiki --400 -s drive:0 -o tiki.img` | ||||
|   - `fluxengine read -c tiki --800 -s drive:0 -o tiki.img` | ||||
|  | ||||
|   | ||||
| @@ -46,13 +46,13 @@ FluxEngine can read and write both the single-sided and double-sided variants. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read victor9k --612 -s drive:0 -o victor9k.img` | ||||
|   - `fluxengine read victor9k --1224 -s drive:0 -o victor9k.img` | ||||
|   - `fluxengine read -c victor9k --612 -s drive:0 -o victor9k.img` | ||||
|   - `fluxengine read -c victor9k --1224 -s drive:0 -o victor9k.img` | ||||
|  | ||||
| To write: | ||||
|  | ||||
|   - `fluxengine write victor9k --612 -d drive:0 -i victor9k.img` | ||||
|   - `fluxengine write victor9k --1224 -d drive:0 -i victor9k.img` | ||||
|   - `fluxengine write -c victor9k --612 -d drive:0 -i victor9k.img` | ||||
|   - `fluxengine write -c victor9k --1224 -d drive:0 -i victor9k.img` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
| @@ -31,7 +31,7 @@ system. | ||||
|  | ||||
| To read: | ||||
|  | ||||
|   - `fluxengine read zilogmcz -s drive:0 -o zilogmcz.img` | ||||
|   - `fluxengine read -c zilogmcz -s drive:0 -o zilogmcz.img` | ||||
|  | ||||
| ## References | ||||
|  | ||||
|   | ||||
							
								
								
									
										16
									
								
								doc/using.md
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								doc/using.md
									
									
									
									
									
								
							| @@ -82,16 +82,16 @@ Here are some sample invocations: | ||||
| ``` | ||||
| # Read an PC 1440kB disk, producing a disk image with the default name | ||||
| # (ibm.img) | ||||
| $ fluxengine read ibm --1440 | ||||
| $ fluxengine read -c ibm --1440 | ||||
|  | ||||
| # Write a PC 1440kB disk to drive 1 | ||||
| $ fluxengine write ibm --1440 -i image.img -d drive:1 | ||||
| $ fluxengine write -c ibm --1440 -i image.img -d drive:1 | ||||
|  | ||||
| # Read a Eco1 CP/M disk, making a copy of the flux into a file | ||||
| $ fluxengine read eco1 --copy-flux-to copy.flux -o eco1.ldbs | ||||
| $ fluxengine read -c eco1 --copy-flux-to copy.flux -o eco1.ldbs | ||||
|  | ||||
| # Rerun the decode from the flux file, tweaking the parameters | ||||
| $ fluxengine read eco1 -s copy.flux -o eco1.ldbs --cylinders=1 | ||||
| $ fluxengine read -c eco1 -s copy.flux -o eco1.ldbs --cylinders=1 | ||||
| ``` | ||||
|  | ||||
| ### Configuration | ||||
| @@ -146,14 +146,14 @@ different task. Run each one with `--help` to get a full list of | ||||
| (non-configuration-setting) options; this describes only basic usage of the | ||||
| more common tools. | ||||
|  | ||||
|   - `fluxengine read <profile> <options> -s <flux source> -o <image output>` | ||||
|   - `fluxengine read -c <profile> <options> -s <flux source> -o <image output>` | ||||
|  | ||||
|     Reads flux (possibly from a disk) and decodes it into a file system image. | ||||
|     `<profile>` is a reference to an internal input configuration file | ||||
|     describing the format. `<options>` may be any combination of options | ||||
|     defined by the profile. | ||||
|  | ||||
|   - `fluxengine write <profile> -i <image input> -d <flux destination>` | ||||
|   - `fluxengine write -c <profile> -i <image input> -d <flux destination>` | ||||
|  | ||||
|     Reads a filesystem image and encodes it into flux (possibly writing to a | ||||
|     disk). `<profile>` is a reference to an internal output configuration file | ||||
| @@ -489,7 +489,7 @@ containing valuable historical data, and you want to read them. | ||||
| Typically I do this: | ||||
|  | ||||
| ``` | ||||
| $ fluxengine read brother240 -s drive:0 -o brother.img --copy-flux-to=brother.flux --decoder.write_csv_to=brother.csv | ||||
| $ fluxengine read -c brother240 -s drive:0 -o brother.img --copy-flux-to=brother.flux --decoder.write_csv_to=brother.csv | ||||
| ``` | ||||
|  | ||||
| This will read the disk in drive 0 and write out an information CSV file. It'll | ||||
| @@ -499,7 +499,7 @@ settings, I can rerun the decode without having to physically touch the disk | ||||
| like this: | ||||
|  | ||||
| ``` | ||||
| $ fluxengine read brother -s brother.flux -o brother.img --decoder.write_csv_to=brother.csv | ||||
| $ fluxengine read -c brother -s brother.flux -o brother.img --decoder.write_csv_to=brother.csv | ||||
| ``` | ||||
|  | ||||
| Apart from being drastically faster, this avoids touching the (potentially | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
| #include "lib/core/utils.h" | ||||
| #include <fstream> | ||||
| #include <google/protobuf/text_format.h> | ||||
| #include <fmt/ranges.h> | ||||
|  | ||||
| static Config config; | ||||
|  | ||||
| @@ -181,35 +182,8 @@ ConfigProto* Config::combined() | ||||
|     { | ||||
|         _combinedConfig = _baseConfig; | ||||
|  | ||||
|         /* First apply any standalone options. */ | ||||
|  | ||||
|         std::set<std::string> options = _appliedOptions; | ||||
|         for (const auto& option : _baseConfig.option()) | ||||
|         { | ||||
|             if (options.find(option.name()) != options.end()) | ||||
|             { | ||||
|                 _combinedConfig.MergeFrom(option.config()); | ||||
|                 options.erase(option.name()); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /* Then apply any group options. */ | ||||
|  | ||||
|         for (auto& group : _baseConfig.option_group()) | ||||
|         { | ||||
|             const OptionProto* selectedOption = &*group.option().begin(); | ||||
|  | ||||
|             for (auto& option : group.option()) | ||||
|             { | ||||
|                 if (options.find(option.name()) != options.end()) | ||||
|                 { | ||||
|                     selectedOption = &option; | ||||
|                     options.erase(option.name()); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             _combinedConfig.MergeFrom(selectedOption->config()); | ||||
|         } | ||||
|         for (const auto& optionInfo : _appliedOptions) | ||||
|             _combinedConfig.MergeFrom(optionInfo.option->config()); | ||||
|  | ||||
|         /* Add in the user overrides. */ | ||||
|  | ||||
| @@ -241,51 +215,27 @@ std::vector<std::string> Config::validate() | ||||
| { | ||||
|     std::vector<std::string> results; | ||||
|  | ||||
|     std::set<std::string> optionNames = _appliedOptions; | ||||
|     std::set<const OptionProto*> appliedOptions; | ||||
|     for (const auto& option : _baseConfig.option()) | ||||
|     { | ||||
|         if (optionNames.find(option.name()) != optionNames.end()) | ||||
|         { | ||||
|             appliedOptions.insert(&option); | ||||
|             optionNames.erase(option.name()); | ||||
|         } | ||||
|     } | ||||
|     /* Ensure that only one item in each group is set. */ | ||||
|  | ||||
|     /* Then apply any group options. */ | ||||
|  | ||||
|     for (auto& group : _baseConfig.option_group()) | ||||
|     std::map<const OptionGroupProto*, const OptionProto*> optionsByGroup; | ||||
|     for (auto [group, option, hasArgument] : _appliedOptions) | ||||
|         if (group) | ||||
|         { | ||||
|         int count = 0; | ||||
|  | ||||
|         for (auto& option : group.option()) | ||||
|         { | ||||
|             if (optionNames.find(option.name()) != optionNames.end()) | ||||
|             { | ||||
|                 optionNames.erase(option.name()); | ||||
|                 appliedOptions.insert(&option); | ||||
|  | ||||
|                 count++; | ||||
|                 if (count == 2) | ||||
|             auto& o = optionsByGroup[group]; | ||||
|             if (o) | ||||
|                 results.push_back( | ||||
|                         fmt::format("multiple mutually exclusive options set " | ||||
|                                     "for group '{}'", | ||||
|                             group.comment())); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /* Check for unknown options. */ | ||||
|  | ||||
|     if (!optionNames.empty()) | ||||
|     { | ||||
|         for (auto& name : optionNames) | ||||
|             results.push_back(fmt::format("'{}' is not a known option", name)); | ||||
|                     fmt::format("multiple mutually exclusive values set for " | ||||
|                                 "group '{}': valid values are: {}", | ||||
|                         group->comment(), | ||||
|                         fmt::join(std::views::transform( | ||||
|                                       group->option(), &OptionProto::name), | ||||
|                             ", "))); | ||||
|             o = option; | ||||
|         } | ||||
|  | ||||
|     /* Check option requirements. */ | ||||
|  | ||||
|     for (auto& option : appliedOptions) | ||||
|     for (auto [group, option, hasArgument] : _appliedOptions) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
| @@ -360,11 +310,12 @@ void Config::readBaseConfig(std::string data) | ||||
|         error("couldn't load external config proto"); | ||||
| } | ||||
|  | ||||
| const OptionProto& Config::findOption(const std::string& optionName) | ||||
| Config::OptionInfo Config::findOption( | ||||
|     const std::string& name, const std::string value) | ||||
| { | ||||
|     const OptionProto* found = nullptr; | ||||
|  | ||||
|     auto searchOptionList = [&](auto& optionList) | ||||
|     auto searchOptionList = [&](auto& optionList, const std::string& optionName) | ||||
|     { | ||||
|         for (const auto& option : optionList) | ||||
|         { | ||||
| @@ -377,17 +328,39 @@ const OptionProto& Config::findOption(const std::string& optionName) | ||||
|         return false; | ||||
|     }; | ||||
|  | ||||
|     if (searchOptionList(base()->option())) | ||||
|         return *found; | ||||
|     /* First look for any group names which match. */ | ||||
|  | ||||
|     if (!value.empty()) | ||||
|         for (const auto& optionGroup : base()->option_group()) | ||||
|             if (optionGroup.name() == name) | ||||
|             { | ||||
|                 /* The option must therefore be one of these. */ | ||||
|  | ||||
|                 if (searchOptionList(optionGroup.option(), value)) | ||||
|                     return {&optionGroup, found, true}; | ||||
|  | ||||
|                 throw OptionNotFoundException(fmt::format( | ||||
|                     "value {} is not valid for option {}; valid values are: {}", | ||||
|                     value, | ||||
|                     name, | ||||
|                     fmt::join(std::views::transform( | ||||
|                                   optionGroup.option(), &OptionProto::name), | ||||
|                         ", "))); | ||||
|             } | ||||
|  | ||||
|     /* Now search for individual options. */ | ||||
|  | ||||
|     if (searchOptionList(base()->option(), name)) | ||||
|         return {nullptr, found, false}; | ||||
|  | ||||
|     for (const auto& optionGroup : base()->option_group()) | ||||
|     { | ||||
|         if (searchOptionList(optionGroup.option())) | ||||
|             return *found; | ||||
|         if (optionGroup.name().empty()) | ||||
|             if (searchOptionList(optionGroup.option(), name)) | ||||
|                 return {nullptr, found, false}; | ||||
|     } | ||||
|  | ||||
|     throw OptionNotFoundException( | ||||
|         fmt::format("option {} not found", optionName)); | ||||
|     throw OptionNotFoundException(fmt::format("option {} not found", name)); | ||||
| } | ||||
|  | ||||
| void Config::checkOptionValid(const OptionProto& option) | ||||
| @@ -445,22 +418,20 @@ bool Config::isOptionValid(const OptionProto& option) | ||||
|     } | ||||
| } | ||||
|  | ||||
| bool Config::isOptionValid(std::string option) | ||||
| { | ||||
|     return isOptionValid(findOption(option)); | ||||
| } | ||||
|  | ||||
| void Config::applyOption(const OptionProto& option) | ||||
| void Config::applyOption(const OptionInfo& optionInfo) | ||||
| { | ||||
|     auto* option = optionInfo.option; | ||||
|     log(OptionLogMessage{ | ||||
|         option.has_message() ? option.message() : option.comment()}); | ||||
|         option->has_message() ? option->message() : option->comment()}); | ||||
|  | ||||
|     _appliedOptions.insert(option.name()); | ||||
|     _appliedOptions.insert(optionInfo); | ||||
| } | ||||
|  | ||||
| void Config::applyOption(std::string option) | ||||
| bool Config::applyOption(const std::string& name, const std::string value) | ||||
| { | ||||
|     applyOption(findOption(option)); | ||||
|     auto optionInfo = findOption(name, value); | ||||
|     applyOption(optionInfo); | ||||
|     return optionInfo.usesValue; | ||||
| } | ||||
|  | ||||
| void Config::clearOptions() | ||||
|   | ||||
| @@ -66,6 +66,18 @@ struct FluxConstructor | ||||
|  | ||||
| class Config | ||||
| { | ||||
| private: | ||||
|     struct OptionInfo | ||||
|     { | ||||
|         bool operator==(const OptionInfo& other) const = default; | ||||
|         std::strong_ordering operator<=>( | ||||
|             const OptionInfo& other) const = default; | ||||
|  | ||||
|         const OptionGroupProto* group; | ||||
|         const OptionProto* option; | ||||
|         bool usesValue; | ||||
|     }; | ||||
|  | ||||
| public: | ||||
|     /* Direct access to the various proto layers. */ | ||||
|  | ||||
| @@ -124,12 +136,12 @@ public: | ||||
|     /* Option management: look up an option by name, determine whether an option | ||||
|      * is valid, and apply an option. */ | ||||
|  | ||||
|     const OptionProto& findOption(const std::string& option); | ||||
|     OptionInfo findOption( | ||||
|         const std::string& name, const std::string value = ""); | ||||
|     void checkOptionValid(const OptionProto& option); | ||||
|     bool isOptionValid(const OptionProto& option); | ||||
|     bool isOptionValid(std::string option); | ||||
|     void applyOption(const OptionProto& option); | ||||
|     void applyOption(std::string option); | ||||
|     void applyOption(const OptionInfo& optionInfo); | ||||
|     bool applyOption(const std::string& name, const std::string value = ""); | ||||
|     void clearOptions(); | ||||
|  | ||||
|     /* Adjust overall inputs and outputs. */ | ||||
| @@ -165,7 +177,7 @@ private: | ||||
|     ConfigProto _baseConfig; | ||||
|     ConfigProto _overridesConfig; | ||||
|     ConfigProto _combinedConfig; | ||||
|     std::set<std::string> _appliedOptions; | ||||
|     std::set<OptionInfo> _appliedOptions; | ||||
|     bool _configValid; | ||||
|  | ||||
|     FluxSourceProto _verificationFluxSourceProto; | ||||
|   | ||||
| @@ -73,5 +73,6 @@ message OptionProto | ||||
| message OptionGroupProto | ||||
| { | ||||
|     optional string comment = 1 [(help) = "help text for option group"]; | ||||
|     repeated OptionProto option = 2; | ||||
|     optional string name = 2 [(help) = "option group name"]; | ||||
|     repeated OptionProto option = 3; | ||||
| } | ||||
|   | ||||
| @@ -13,17 +13,23 @@ static std::vector<Flag*> all_flags; | ||||
| static std::map<const std::string, Flag*> flags_by_name; | ||||
|  | ||||
| static void doHelp(); | ||||
| static void doLoadConfig(const std::string& filename); | ||||
| static void doShowConfig(); | ||||
| static void doDoc(); | ||||
|  | ||||
| static FlagGroup helpGroup; | ||||
| static ActionFlag helpFlag = ActionFlag({"--help"}, "Shows the help.", doHelp); | ||||
|  | ||||
| static ActionFlag showConfigFlag = ActionFlag({"--config", "-C"}, | ||||
| static FlagGroup configGroup; | ||||
| static ActionFlag loadConfigFlag({"--config", "-c"}, | ||||
|     "Reads an internal or external configuration file.", | ||||
|     doLoadConfig); | ||||
|  | ||||
| static ActionFlag showConfigFlag({"--show-config", "-C"}, | ||||
|     "Shows the currently set configuration and halts.", | ||||
|     doShowConfig); | ||||
|  | ||||
| static ActionFlag docFlag = ActionFlag( | ||||
| static ActionFlag docFlag( | ||||
|     {"--doc"}, "Shows the available configuration options and halts.", doDoc); | ||||
|  | ||||
| FlagGroup::FlagGroup() | ||||
| @@ -152,7 +158,7 @@ std::vector<std::string> FlagGroup::parseFlagsWithFilenames(int argc, | ||||
|                         index += usesthat; | ||||
|                     } | ||||
|                     else | ||||
|                         globalConfig().applyOption(path); | ||||
|                         usesthat = globalConfig().applyOption(path, value); | ||||
|                 } | ||||
|                 else | ||||
|                     error("unrecognised flag '-{}'; try --help", key); | ||||
| @@ -182,17 +188,17 @@ void FlagGroup::parseFlags(int argc, | ||||
|             "non-option parameter '{}' seen (try --help)", *filenames.begin()); | ||||
| } | ||||
|  | ||||
| static void doLoadConfig(const std::string& filename) | ||||
| { | ||||
|     globalConfig().readBaseConfigFile(filename); | ||||
| } | ||||
|  | ||||
| void FlagGroup::parseFlagsWithConfigFiles(int argc, | ||||
|     const char* argv[], | ||||
|     const std::map<std::string, const ConfigProto*>& configFiles) | ||||
| { | ||||
|     parseFlags(argc, | ||||
|         argv, | ||||
|         [&](const auto& filename) | ||||
|         { | ||||
|             globalConfig().readBaseConfigFile(filename); | ||||
|             return true; | ||||
|         }); | ||||
|     globalConfig().readBaseConfigFile("_global_options"); | ||||
|     FlagGroup({this, &configGroup}).parseFlags(argc, argv); | ||||
| } | ||||
|  | ||||
| void FlagGroup::checkInitialised() const | ||||
|   | ||||
| @@ -83,13 +83,23 @@ public: | ||||
|         const std::string helptext, | ||||
|         std::function<void(void)> callback): | ||||
|         Flag(names, helptext), | ||||
|         _callback(callback) | ||||
|         _voidCallback(callback), | ||||
|         _hasArgument(false) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     ActionFlag(const std::vector<std::string>& names, | ||||
|         const std::string helptext, | ||||
|         std::function<void(const std::string&)> callback): | ||||
|         Flag(names, helptext), | ||||
|         _callback(callback), | ||||
|         _hasArgument(true) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     bool hasArgument() const override | ||||
|     { | ||||
|         return false; | ||||
|         return _hasArgument; | ||||
|     } | ||||
|  | ||||
|     const std::string defaultValueAsString() const override | ||||
| @@ -99,11 +109,16 @@ public: | ||||
|  | ||||
|     void set(const std::string& value) override | ||||
|     { | ||||
|         _callback(); | ||||
|         if (_hasArgument) | ||||
|             _callback(value); | ||||
|         else | ||||
|             _voidCallback(); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     const std::function<void(void)> _callback; | ||||
|     const std::function<void(const std::string&)> _callback; | ||||
|     const std::function<void(void)> _voidCallback; | ||||
|     bool _hasArgument; | ||||
| }; | ||||
|  | ||||
| class SettableFlag : public Flag | ||||
|   | ||||
| @@ -14,10 +14,10 @@ destfile=$dir/dest.img | ||||
|  | ||||
| dd if=/dev/urandom of=$srcfile bs=1048576 count=2 2>&1 | ||||
|  | ||||
| echo $fluxengine write $format -i $srcfile -d $fluxfile --drive.rotational_period_ms=200 $flags | ||||
| $fluxengine write $format -i $srcfile -d $fluxfile --drive.rotational_period_ms=200 $flags | ||||
| echo $fluxengine read $format -s $fluxfile -o $destfile --drive.rotational_period_ms=200 $flags | ||||
| $fluxengine read $format -s $fluxfile -o $destfile --drive.rotational_period_ms=200 $flags | ||||
| echo $fluxengine write -c $format -i $srcfile -d $fluxfile --drive.rotational_period_ms=200 $flags | ||||
| $fluxengine write -c $format -i $srcfile -d $fluxfile --drive.rotational_period_ms=200 $flags | ||||
| echo $fluxengine read -c $format -s $fluxfile -o $destfile --drive.rotational_period_ms=200 $flags | ||||
| $fluxengine read -c $format -s $fluxfile -o $destfile --drive.rotational_period_ms=200 $flags | ||||
| if [ ! -s $destfile ]; then | ||||
| 	echo "Zero length output file!" >&2 | ||||
| 	exit 1 | ||||
|   | ||||
| @@ -28,7 +28,7 @@ static void addExample(std::vector<std::string>& examples, | ||||
|     else | ||||
|         return; | ||||
|  | ||||
|     r += fmt::format(" {}", name); | ||||
|     r += fmt::format(" -c {}", name); | ||||
|     if (format) | ||||
|         r += fmt::format(" --{}", format->name()); | ||||
|  | ||||
|   | ||||
| @@ -43,8 +43,9 @@ int main(int argc, const char* argv[]) | ||||
|             { | ||||
|                 const auto* descriptor = | ||||
|                     FilesystemProto::FilesystemType_descriptor(); | ||||
|                 std::string name = | ||||
|                     descriptor->FindValueByNumber(fs.type())->name(); | ||||
|                 auto name = | ||||
|                     (std::string)descriptor->FindValueByNumber(fs.type()) | ||||
|                         ->name(); | ||||
|  | ||||
|                 filesystems.insert(name); | ||||
|             } | ||||
|   | ||||
| @@ -22,9 +22,7 @@ static StringFlag destFlux({"--dest", "-d"}, | ||||
|         globalConfig().setFluxSink(value); | ||||
|     }); | ||||
|  | ||||
| static IntFlag destTrack({"--cylinder", "-c"}, "track to write to", 0); | ||||
|  | ||||
| static IntFlag destHead({"--head", "-h"}, "head to write to", 0); | ||||
| static StringFlag destTracks({"--tracks", "-t"}, "tracks to write to", "c0h0"); | ||||
|  | ||||
| static DoubleFlag minInterval( | ||||
|     {"--min-interval-us"}, "Minimum pulse interval", 2.0); | ||||
| @@ -251,11 +249,14 @@ int mainAnalyseDriveResponse(int argc, const char* argv[]) | ||||
|  | ||||
|     if (globalConfig()->flux_sink().type() != FLUXTYPE_DRIVE) | ||||
|         error("this only makes sense with a real disk drive"); | ||||
|     auto tracks = parseCylinderHeadsString(destTracks); | ||||
|     if (tracks.size() != 1) | ||||
|         error("you must specify exactly one track"); | ||||
|  | ||||
|     usbSetDrive(globalConfig()->drive().drive(), | ||||
|         globalConfig()->drive().high_density(), | ||||
|         globalConfig()->drive().index_mode()); | ||||
|     usbSeek(destTrack); | ||||
|     usbSeek(tracks[0].cylinder); | ||||
|  | ||||
|     std::cout << "Measuring rotational speed...\n"; | ||||
|     nanoseconds_t period = usbGetRotationalPeriod(0); | ||||
| @@ -291,12 +292,12 @@ int mainAnalyseDriveResponse(int argc, const char* argv[]) | ||||
|                 outFluxmap.appendPulse(); | ||||
|             } | ||||
|  | ||||
|             usbWrite(destHead, outFluxmap.rawBytes(), 0); | ||||
|             usbWrite(tracks[0].head, outFluxmap.rawBytes(), 0); | ||||
|  | ||||
|             /* Read the test pattern in again. */ | ||||
|  | ||||
|             Fluxmap inFluxmap; | ||||
|             inFluxmap.appendBytes(usbRead(destHead, true, period, 0)); | ||||
|             inFluxmap.appendBytes(usbRead(tracks[0].head, true, period, 0)); | ||||
|  | ||||
|             /* Compute histogram. */ | ||||
|  | ||||
|   | ||||
| @@ -21,9 +21,7 @@ static StringFlag sourceFlux({"--source", "-s"}, | ||||
|         globalConfig().setFluxSource(value); | ||||
|     }); | ||||
|  | ||||
| static IntFlag trackFlag({"--cylinder", "-c"}, "Track to read.", 0); | ||||
|  | ||||
| static IntFlag headFlag({"--head", "-h"}, "Head to read.", 0); | ||||
| static StringFlag destTracks({"--tracks", "-t"}, "tracks to write to", "c0h0"); | ||||
|  | ||||
| static SettableFlag dumpFluxFlag( | ||||
|     {"--dump-flux", "-F"}, "Dump raw magnetic disk flux."); | ||||
| @@ -135,7 +133,10 @@ int mainInspect(int argc, const char* argv[]) | ||||
|     flags.parseFlagsWithConfigFiles(argc, argv, {}); | ||||
|  | ||||
|     auto fluxSource = FluxSource::create(globalConfig()); | ||||
|     const auto fluxmap = fluxSource->readFlux(trackFlag, headFlag)->next(); | ||||
|     auto tracks = parseCylinderHeadsString(destTracks); | ||||
|     if (tracks.size() != 1) | ||||
|         error("you must specify exactly one track"); | ||||
|     const auto fluxmap = fluxSource->readFlux(tracks[0])->next(); | ||||
|  | ||||
|     std::cout << fmt::format("0x{:x} bytes of data in {:.3f}ms\n", | ||||
|         fluxmap->bytes(), | ||||
|   | ||||
| @@ -16,7 +16,7 @@ static StringFlag sourceFlux({"-s", "--source"}, | ||||
|         globalConfig().setFluxSource(value); | ||||
|     }); | ||||
|  | ||||
| static IntFlag track({"--cylinder", "-c"}, "track to seek to", 0); | ||||
| static IntFlag track({"--cylinder", "-t"}, "track to seek to", 0); | ||||
|  | ||||
| extern const std::map<std::string, std::string> readables; | ||||
|  | ||||
|   | ||||
| @@ -1,22 +0,0 @@ | ||||
| comment: 'Adjust configuration for a 40-track drive' | ||||
| is_extension: true | ||||
|  | ||||
| documentation: | ||||
| <<< | ||||
| This is an extension profile; adding this to the command line will configure | ||||
| FluxEngine to read from 40-track, 48tpi 5.25" drives. You have to tell it because there is | ||||
| no way to detect this automatically. | ||||
|  | ||||
| For example: | ||||
|  | ||||
| ``` | ||||
| fluxengine read ibm --180 40track_drive | ||||
| ``` | ||||
| >>> | ||||
|  | ||||
| drive { | ||||
|     tracks: "c0-40h0-1" | ||||
|     drive_type: DRIVETYPE_40TRACK | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										77
									
								
								src/formats/_global_options.textpb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/formats/_global_options.textpb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| comment: 'Options which can be applied everywhere.' | ||||
| is_extension: true | ||||
|  | ||||
| option_group { | ||||
| 	comment: "Drive type" | ||||
|     name: "drivetype" | ||||
|  | ||||
| 	option { | ||||
| 		name: "80" | ||||
| 		comment: '80 track drive' | ||||
|         set_by_default: true | ||||
|  | ||||
| 		config { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	option { | ||||
| 		name: "40" | ||||
| 		comment: '40 track drive' | ||||
|  | ||||
| 		config { | ||||
|             drive { | ||||
|                 tracks: "c0-40h0-1" | ||||
|                 drive_type: DRIVETYPE_40TRACK | ||||
|             } | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	option { | ||||
| 		name: "160" | ||||
| 		comment: '160 track Apple II drive' | ||||
|  | ||||
| 		config { | ||||
|             drive { | ||||
|                 tracks: "c0-159h0" | ||||
|                 drive_type: DRIVETYPE_APPLE2 | ||||
|             } | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| option_group { | ||||
|     comment: 'Bus interface' | ||||
|     name: "bus" | ||||
|  | ||||
| 	option { | ||||
| 		name: "pc" | ||||
| 		comment: 'PC drive interface' | ||||
|         set_by_default: true | ||||
|     } | ||||
|  | ||||
| 	option { | ||||
| 		name: "shugart" | ||||
| 		comment: 'Shugart bus interface (only on Greaseweazle)' | ||||
|  | ||||
| 		config { | ||||
|             usb { | ||||
|                 greaseweazle { | ||||
|                     bus_type: SHUGART | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| 	option { | ||||
| 		name: "appleii" | ||||
| 		comment: 'Apple II bus interface (only on Greaseweazle)' | ||||
|  | ||||
| 		config { | ||||
|             usb { | ||||
|                 greaseweazle { | ||||
|                     bus_type: APPLE2 | ||||
|                 } | ||||
|             } | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -1,29 +0,0 @@ | ||||
| comment: 'Adjust configuration for a 40-track Apple II drive' | ||||
| is_extension: true | ||||
|  | ||||
| documentation: | ||||
| <<< | ||||
| This is an extension profile; adding this to the command line will configure | ||||
| FluxEngine to adjust the pinout and track spacing to work with an Apple II | ||||
| drive.  This only works on Greaseweazle hardware and requires a custom | ||||
| connector. | ||||
|  | ||||
| For example: | ||||
|  | ||||
| ``` | ||||
| fluxengine read apple2 --160 apple2_drive | ||||
| ``` | ||||
| >>> | ||||
|  | ||||
| usb { | ||||
|     greaseweazle { | ||||
|         bus_type: APPLE2 | ||||
|     } | ||||
| } | ||||
|  | ||||
| drive { | ||||
|     tracks: "c0-159h0" | ||||
|     drive_type: DRIVETYPE_APPLE2 | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -3,14 +3,13 @@ from build.c import cxxlibrary | ||||
| from scripts.build import protoencode | ||||
|  | ||||
| formats = [ | ||||
|     "40track_drive", | ||||
|     "_global_options", | ||||
|     "acornadfs", | ||||
|     "acorndfs", | ||||
|     "aeslanier", | ||||
|     "agat", | ||||
|     "amiga", | ||||
|     "ampro", | ||||
|     "apple2_drive", | ||||
|     "apple2", | ||||
|     "atarist", | ||||
|     "bk", | ||||
| @@ -33,7 +32,6 @@ formats = [ | ||||
|     "psos", | ||||
|     "rolandd20", | ||||
|     "rx50", | ||||
|     "shugart_drive", | ||||
|     "smaky6", | ||||
|     "tartu", | ||||
|     "ti99", | ||||
|   | ||||
| @@ -1,22 +0,0 @@ | ||||
| comment: 'Adjust configuration for a Shugart drive' | ||||
| is_extension: true | ||||
|  | ||||
| documentation: | ||||
| <<< | ||||
| This is an extension profile; adding this to the command line will configure | ||||
| FluxEngine to adjust the pinout to work with a Shugart drive. This only works | ||||
| on Greaseweazle hardware. | ||||
|  | ||||
| For example: | ||||
|  | ||||
| ``` | ||||
| fluxengine read ibm --720 shugart_drive | ||||
| ``` | ||||
| >>> | ||||
|  | ||||
| usb { | ||||
|     greaseweazle { | ||||
|         bus_type: SHUGART | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -55,14 +55,14 @@ static void test_option_validity() | ||||
|         } | ||||
| 	)M"); | ||||
|  | ||||
|     AssertThat( | ||||
|         globalConfig().isOptionValid(globalConfig().findOption("option1")), | ||||
|     AssertThat(globalConfig().isOptionValid( | ||||
|                    *globalConfig().findOption("option1").option), | ||||
|         Equals(true)); | ||||
|     AssertThat( | ||||
|         globalConfig().isOptionValid(globalConfig().findOption("option2")), | ||||
|     AssertThat(globalConfig().isOptionValid( | ||||
|                    *globalConfig().findOption("option2").option), | ||||
|         Equals(false)); | ||||
|     AssertThat( | ||||
|         globalConfig().isOptionValid(globalConfig().findOption("option3")), | ||||
|     AssertThat(globalConfig().isOptionValid( | ||||
|                    *globalConfig().findOption("option3").option), | ||||
|         Equals(true)); | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user