├── .clang-format ├── .github └── workflows │ ├── ccpp.yml │ └── release.yml ├── .gitignore ├── .hgignore ├── COPYING.md ├── FluxEngine.cydsn ├── CortexM3 │ └── ARM_GCC_541 │ │ └── Release │ │ └── FluxEngine.hex ├── FIFOin │ ├── API │ │ ├── c.c │ │ └── h.h │ ├── FIFOin.cysym │ └── FIFOin.v ├── FIFOout │ ├── API │ │ ├── c.c │ │ └── h.h │ ├── FIFOout.cysym │ └── FIFOout.v ├── FluxEngine.cydwr ├── FluxEngine.cyprj ├── PulseGen │ ├── PulseGen.cysym │ └── PulseGen.cyudb ├── Sampler │ ├── Sampler.cysym │ └── Sampler.v ├── Sequencer │ ├── Sequencer.cysym │ └── Sequencer.v ├── SuperCounter │ ├── SuperCounter.cysym │ └── SuperCounter.v ├── TopDesign │ └── TopDesign.cysch ├── cyapicallbacks.h └── main.c ├── Makefile ├── README.md ├── arch ├── aeslanier │ ├── aeslanier.h │ ├── aeslanier.proto │ └── decoder.cc ├── agat │ ├── agat.cc │ ├── agat.h │ ├── agat.proto │ ├── decoder.cc │ └── encoder.cc ├── amiga │ ├── amiga.cc │ ├── amiga.h │ ├── amiga.proto │ ├── decoder.cc │ └── encoder.cc ├── apple2 │ ├── apple2.h │ ├── apple2.proto │ ├── data_gcr.h │ ├── decoder.cc │ └── encoder.cc ├── arch.cc ├── arch.h ├── brother │ ├── brother.h │ ├── brother.proto │ ├── data_gcr.h │ ├── decoder.cc │ ├── encoder.cc │ └── header_gcr.h ├── build.py ├── c64 │ ├── c64.cc │ ├── c64.h │ ├── c64.proto │ ├── data_gcr.h │ ├── decoder.cc │ └── encoder.cc ├── f85 │ ├── data_gcr.h │ ├── decoder.cc │ ├── f85.h │ └── f85.proto ├── fb100 │ ├── decoder.cc │ ├── fb100.h │ └── fb100.proto ├── ibm │ ├── decoder.cc │ ├── encoder.cc │ ├── ibm.h │ └── ibm.proto ├── macintosh │ ├── data_gcr.h │ ├── decoder.cc │ ├── encoder.cc │ ├── macintosh.h │ └── macintosh.proto ├── micropolis │ ├── decoder.cc │ ├── encoder.cc │ ├── micropolis.h │ └── micropolis.proto ├── mx │ ├── decoder.cc │ ├── mx.h │ └── mx.proto ├── northstar │ ├── decoder.cc │ ├── encoder.cc │ ├── northstar.h │ └── northstar.proto ├── rolandd20 │ ├── decoder.cc │ ├── rolandd20.h │ └── rolandd20.proto ├── smaky6 │ ├── decoder.cc │ ├── smaky6.h │ └── smaky6.proto ├── tartu │ ├── decoder.cc │ ├── encoder.cc │ ├── tartu.h │ └── tartu.proto ├── tids990 │ ├── decoder.cc │ ├── encoder.cc │ ├── tids990.h │ └── tids990.proto ├── victor9k │ ├── data_gcr.h │ ├── decoder.cc │ ├── encoder.cc │ ├── victor9k.h │ └── victor9k.proto └── zilogmcz │ ├── decoder.cc │ ├── zilogmcz.h │ └── zilogmcz.proto ├── build.py ├── build ├── _objectify.py ├── _sandbox.py ├── _zip.py ├── ab.mk ├── ab.py ├── c.py ├── pkg.py ├── protobuf.py ├── toolchain.py ├── utils.py └── zip.py ├── config.py ├── dep ├── adflib │ ├── .gitignore │ ├── AUTHORS │ ├── COPYING │ ├── README │ ├── UPSTREAM.md │ ├── adf_nativ.h │ ├── build.py │ ├── config.h │ └── src │ │ ├── Makefile.am │ │ ├── adf_bitm.c │ │ ├── adf_bitm.h │ │ ├── adf_blk.h │ │ ├── adf_cache.c │ │ ├── adf_cache.h │ │ ├── adf_defs.h │ │ ├── adf_dir.c │ │ ├── adf_dir.h │ │ ├── adf_disk.c │ │ ├── adf_disk.h │ │ ├── adf_dump.c │ │ ├── adf_dump.h │ │ ├── adf_env.c │ │ ├── adf_env.h │ │ ├── adf_err.h │ │ ├── adf_file.c │ │ ├── adf_file.h │ │ ├── adf_hd.c │ │ ├── adf_hd.h │ │ ├── adf_link.c │ │ ├── adf_link.h │ │ ├── adf_raw.c │ │ ├── adf_raw.h │ │ ├── adf_salv.c │ │ ├── adf_salv.h │ │ ├── adf_str.h │ │ ├── adf_util.c │ │ ├── adf_util.h │ │ ├── adflib.h │ │ ├── defendian.h │ │ ├── hd_blk.h │ │ └── prefix.h ├── agg │ ├── AUTHORS │ ├── README │ ├── README.md │ ├── UPSTREAM.md │ ├── build.py │ ├── include │ │ ├── Makefile.am │ │ ├── agg2d.h │ │ ├── agg_alpha_mask_u8.h │ │ ├── agg_arc.h │ │ ├── agg_array.h │ │ ├── agg_arrowhead.h │ │ ├── agg_basics.h │ │ ├── agg_bezier_arc.h │ │ ├── agg_bitset_iterator.h │ │ ├── agg_blur.h │ │ ├── agg_bounding_rect.h │ │ ├── agg_bspline.h │ │ ├── agg_clip_liang_barsky.h │ │ ├── agg_color_gray.h │ │ ├── agg_color_rgba.h │ │ ├── agg_config.h │ │ ├── agg_conv_adaptor_vcgen.h │ │ ├── agg_conv_adaptor_vpgen.h │ │ ├── agg_conv_bspline.h │ │ ├── agg_conv_clip_polygon.h │ │ ├── agg_conv_clip_polyline.h │ │ ├── agg_conv_close_polygon.h │ │ ├── agg_conv_concat.h │ │ ├── agg_conv_contour.h │ │ ├── agg_conv_curve.h │ │ ├── agg_conv_dash.h │ │ ├── agg_conv_gpc.h │ │ ├── agg_conv_marker.h │ │ ├── agg_conv_marker_adaptor.h │ │ ├── agg_conv_segmentator.h │ │ ├── agg_conv_shorten_path.h │ │ ├── agg_conv_smooth_poly1.h │ │ ├── agg_conv_stroke.h │ │ ├── agg_conv_transform.h │ │ ├── agg_conv_unclose_polygon.h │ │ ├── agg_curves.h │ │ ├── agg_dda_line.h │ │ ├── agg_ellipse.h │ │ ├── agg_ellipse_bresenham.h │ │ ├── agg_embedded_raster_fonts.h │ │ ├── agg_font_cache_manager.h │ │ ├── agg_font_cache_manager2.h │ │ ├── agg_gamma_functions.h │ │ ├── agg_gamma_lut.h │ │ ├── agg_glyph_raster_bin.h │ │ ├── agg_gradient_lut.h │ │ ├── agg_gsv_text.h │ │ ├── agg_image_accessors.h │ │ ├── agg_image_filters.h │ │ ├── agg_line_aa_basics.h │ │ ├── agg_math.h │ │ ├── agg_math_stroke.h │ │ ├── agg_path_length.h │ │ ├── agg_path_storage.h │ │ ├── agg_path_storage_integer.h │ │ ├── agg_pattern_filters_rgba.h │ │ ├── agg_pixfmt_amask_adaptor.h │ │ ├── agg_pixfmt_base.h │ │ ├── agg_pixfmt_gray.h │ │ ├── agg_pixfmt_rgb.h │ │ ├── agg_pixfmt_rgb_packed.h │ │ ├── agg_pixfmt_rgba.h │ │ ├── agg_pixfmt_transposer.h │ │ ├── agg_rasterizer_cells_aa.h │ │ ├── agg_rasterizer_compound_aa.h │ │ ├── agg_rasterizer_outline.h │ │ ├── agg_rasterizer_outline_aa.h │ │ ├── agg_rasterizer_scanline_aa.h │ │ ├── agg_rasterizer_scanline_aa_nogamma.h │ │ ├── agg_rasterizer_sl_clip.h │ │ ├── agg_renderer_base.h │ │ ├── agg_renderer_markers.h │ │ ├── agg_renderer_mclip.h │ │ ├── agg_renderer_outline_aa.h │ │ ├── agg_renderer_outline_image.h │ │ ├── agg_renderer_primitives.h │ │ ├── agg_renderer_raster_text.h │ │ ├── agg_renderer_scanline.h │ │ ├── agg_rendering_buffer.h │ │ ├── agg_rendering_buffer_dynarow.h │ │ ├── agg_rounded_rect.h │ │ ├── agg_scanline_bin.h │ │ ├── agg_scanline_boolean_algebra.h │ │ ├── agg_scanline_p.h │ │ ├── agg_scanline_storage_aa.h │ │ ├── agg_scanline_storage_bin.h │ │ ├── agg_scanline_u.h │ │ ├── agg_shorten_path.h │ │ ├── agg_simul_eq.h │ │ ├── agg_span_allocator.h │ │ ├── agg_span_converter.h │ │ ├── agg_span_gouraud.h │ │ ├── agg_span_gouraud_gray.h │ │ ├── agg_span_gouraud_rgba.h │ │ ├── agg_span_gradient.h │ │ ├── agg_span_gradient_alpha.h │ │ ├── agg_span_gradient_contour.h │ │ ├── agg_span_gradient_image.h │ │ ├── agg_span_image_filter.h │ │ ├── agg_span_image_filter_gray.h │ │ ├── agg_span_image_filter_rgb.h │ │ ├── agg_span_image_filter_rgba.h │ │ ├── agg_span_interpolator_adaptor.h │ │ ├── agg_span_interpolator_linear.h │ │ ├── agg_span_interpolator_persp.h │ │ ├── agg_span_interpolator_trans.h │ │ ├── agg_span_pattern_gray.h │ │ ├── agg_span_pattern_rgb.h │ │ ├── agg_span_pattern_rgba.h │ │ ├── agg_span_solid.h │ │ ├── agg_span_subdiv_adaptor.h │ │ ├── agg_trans_affine.h │ │ ├── agg_trans_bilinear.h │ │ ├── agg_trans_double_path.h │ │ ├── agg_trans_perspective.h │ │ ├── agg_trans_single_path.h │ │ ├── agg_trans_viewport.h │ │ ├── agg_trans_warp_magnifier.h │ │ ├── agg_vcgen_bspline.h │ │ ├── agg_vcgen_contour.h │ │ ├── agg_vcgen_dash.h │ │ ├── agg_vcgen_markers_term.h │ │ ├── agg_vcgen_smooth_poly1.h │ │ ├── agg_vcgen_stroke.h │ │ ├── agg_vcgen_vertex_sequence.h │ │ ├── agg_vertex_sequence.h │ │ ├── agg_vpgen_clip_polygon.h │ │ ├── agg_vpgen_clip_polyline.h │ │ ├── agg_vpgen_segmentator.h │ │ └── util │ │ │ ├── Makefile.am │ │ │ ├── agg_color_conv.h │ │ │ ├── agg_color_conv_rgb16.h │ │ │ └── agg_color_conv_rgb8.h │ └── src │ │ ├── agg2d.cpp │ │ ├── agg_arc.cpp │ │ ├── agg_arrowhead.cpp │ │ ├── agg_bezier_arc.cpp │ │ ├── agg_bspline.cpp │ │ ├── agg_color_rgba.cpp │ │ ├── agg_curves.cpp │ │ ├── agg_embedded_raster_fonts.cpp │ │ ├── agg_gsv_text.cpp │ │ ├── agg_image_filters.cpp │ │ ├── agg_line_aa_basics.cpp │ │ ├── agg_line_profile_aa.cpp │ │ ├── agg_rounded_rect.cpp │ │ ├── agg_sqrt_tables.cpp │ │ ├── agg_trans_affine.cpp │ │ ├── agg_trans_double_path.cpp │ │ ├── agg_trans_single_path.cpp │ │ ├── agg_trans_warp_magnifier.cpp │ │ ├── agg_vcgen_bspline.cpp │ │ ├── agg_vcgen_contour.cpp │ │ ├── agg_vcgen_dash.cpp │ │ ├── agg_vcgen_markers_term.cpp │ │ ├── agg_vcgen_smooth_poly1.cpp │ │ ├── agg_vcgen_stroke.cpp │ │ ├── agg_vpgen_clip_polygon.cpp │ │ ├── agg_vpgen_clip_polyline.cpp │ │ └── agg_vpgen_segmentator.cpp ├── emu │ ├── UPSTREAM.md │ ├── build.py │ ├── charclass.h │ ├── fnmatch.c │ └── fnmatch.h ├── fatfs │ ├── LICENSE.txt │ ├── UPSTREAM.md │ ├── build.py │ └── source │ │ ├── 00history.txt │ │ ├── 00readme.txt │ │ ├── diskio.c │ │ ├── diskio.h │ │ ├── ff.c │ │ ├── ff.h │ │ ├── ffconf.h │ │ ├── ffsystem.c │ │ └── ffunicode.c ├── fmt │ ├── .clang-format │ ├── CONTRIBUTING.md │ ├── ChangeLog.md │ ├── LICENSE │ ├── README.md │ ├── UPSTREAM.md │ ├── build.py │ ├── include │ │ └── fmt │ │ │ ├── args.h │ │ │ ├── base.h │ │ │ ├── chrono.h │ │ │ ├── color.h │ │ │ ├── compile.h │ │ │ ├── core.h │ │ │ ├── format-inl.h │ │ │ ├── format.h │ │ │ ├── os.h │ │ │ ├── ostream.h │ │ │ ├── printf.h │ │ │ ├── ranges.h │ │ │ ├── std.h │ │ │ └── xchar.h │ └── src │ │ ├── fmt.cc │ │ ├── format.cc │ │ └── os.cc ├── hfsutils │ ├── COPYING │ ├── COPYRIGHT │ ├── CREDITS │ ├── README │ ├── UPSTREAM.md │ ├── build.py │ └── libhfs │ │ ├── apple.h │ │ ├── block.c │ │ ├── block.h │ │ ├── btree.c │ │ ├── btree.h │ │ ├── config.h │ │ ├── data.c │ │ ├── data.h │ │ ├── file.c │ │ ├── file.h │ │ ├── hfs.c │ │ ├── hfs.h │ │ ├── libhfs.h │ │ ├── low.c │ │ ├── low.h │ │ ├── medium.c │ │ ├── medium.h │ │ ├── memcmp.c │ │ ├── node.c │ │ ├── node.h │ │ ├── os.h │ │ ├── record.c │ │ ├── record.h │ │ ├── version.c │ │ ├── version.h │ │ ├── volume.c │ │ └── volume.h ├── libusbp │ ├── .dir-locals.el │ ├── CMakeLists.txt │ ├── CONTRIBUTING.md │ ├── Doxyfile │ ├── LICENSE.txt │ ├── PLATFORM_NOTES.md │ ├── README.md │ ├── THREADS.md │ ├── UPSTREAM.md │ ├── build.py │ ├── examples │ │ ├── CMakeLists.txt │ │ ├── async_in │ │ │ ├── CMakeLists.txt │ │ │ └── async_in.cpp │ │ ├── drop_in │ │ │ ├── .gitignore │ │ │ └── build.sh │ │ ├── lsport │ │ │ ├── CMakeLists.txt │ │ │ └── lsport.cpp │ │ ├── lsusb │ │ │ ├── CMakeLists.txt │ │ │ └── lsusb.cpp │ │ └── port_name │ │ │ ├── CMakeLists.txt │ │ │ └── port_name.cpp │ ├── include │ │ ├── libusbp.h │ │ ├── libusbp.hpp │ │ └── libusbp_config.h │ ├── install_helper │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── dll.def │ │ └── install_helper_windows.c │ ├── manual_tests │ │ ├── CMakeLists.txt │ │ ├── test_async_in │ │ │ ├── CMakeLists.txt │ │ │ └── test_async_in.cpp │ │ ├── test_long_read │ │ │ ├── CMakeLists.txt │ │ │ └── test_long_read.cpp │ │ ├── test_long_write │ │ │ ├── CMakeLists.txt │ │ │ └── test_long_write.cpp │ │ └── test_transitions │ │ │ ├── CMakeLists.txt │ │ │ └── test_transitions.cpp │ ├── src │ │ ├── CMakeLists.txt │ │ ├── async_in_pipe.c │ │ ├── dummy.c │ │ ├── error.c │ │ ├── error_hresult.c │ │ ├── find_device.c │ │ ├── info.rc.in │ │ ├── libusbp.pc.in │ │ ├── libusbp_config.h.in │ │ ├── libusbp_internal.h │ │ ├── linux │ │ │ ├── async_in_transfer_linux.c │ │ │ ├── device_linux.c │ │ │ ├── error_linux.c │ │ │ ├── generic_handle_linux.c │ │ │ ├── generic_interface_linux.c │ │ │ ├── list_linux.c │ │ │ ├── serial_port_linux.c │ │ │ ├── udev_linux.c │ │ │ └── usbfd_linux.c │ │ ├── list.c │ │ ├── mac │ │ │ ├── async_in_transfer_mac.c │ │ │ ├── device_mac.c │ │ │ ├── error_mac.c │ │ │ ├── generic_handle_mac.c │ │ │ ├── generic_interface_mac.c │ │ │ ├── iokit_mac.c │ │ │ ├── list_mac.c │ │ │ └── serial_port_mac.c │ │ ├── pipe_id.c │ │ ├── string.c │ │ └── windows │ │ │ ├── async_in_transfer_windows.c │ │ │ ├── device_instance_id_windows.c │ │ │ ├── device_windows.c │ │ │ ├── error_windows.c │ │ │ ├── generic_handle_windows.c │ │ │ ├── generic_interface_windows.c │ │ │ ├── interface_windows.c │ │ │ ├── list_windows.c │ │ │ └── serial_port_windows.c │ └── test │ │ ├── CMakeLists.txt │ │ ├── async_in_pipe_test.cpp │ │ ├── control_sync_test.cpp │ │ ├── device_test.cpp │ │ ├── drivers │ │ ├── pololu.cat │ │ ├── usb_test_a_native.inf │ │ ├── usb_test_a_serial.inf │ │ └── usb_test_b_native.inf │ │ ├── error_message_test.cpp │ │ ├── error_test.cpp │ │ ├── firmware │ │ └── wixel │ │ │ ├── .gitignore │ │ │ ├── Makefile │ │ │ ├── cdc_acm_constants.h │ │ │ ├── main.c │ │ │ └── prepare_sdk.sh │ │ ├── generic_handle_test.cpp │ │ ├── generic_interface_test.cpp │ │ ├── list_test.cpp │ │ ├── main_test.cpp │ │ ├── read_pipe_test.cpp │ │ ├── serial_port_test.cpp │ │ ├── test_helper.cpp │ │ ├── test_helper.h │ │ ├── usbfd_test.cpp │ │ ├── windows_test.cpp │ │ └── write_pipe_test.cpp ├── snowhouse │ ├── CMakeLists.txt │ ├── LICENSE_1_0.txt │ ├── README.md │ ├── UPSTREAM.md │ ├── build.py │ ├── example │ │ ├── basic_assertions.cpp │ │ ├── boolean_operators.cpp │ │ ├── container_spec.cpp │ │ ├── custom_matchers_test.cpp │ │ ├── exceptions_tests.cpp │ │ ├── expression_error_handling.cpp │ │ ├── main.cpp │ │ ├── map_tests.cpp │ │ ├── operator_tests.cpp │ │ ├── sequence_container_tests.cpp │ │ ├── string_line_tests.cpp │ │ ├── string_tests.cpp │ │ ├── stringize_tests.cpp │ │ └── tests.h │ ├── include │ │ └── snowhouse │ │ │ ├── assert.h │ │ │ ├── assertionexception.h │ │ │ ├── constraints │ │ │ ├── constraints.h │ │ │ ├── containsconstraint.h │ │ │ ├── endswithconstraint.h │ │ │ ├── equalsconstraint.h │ │ │ ├── equalscontainerconstraint.h │ │ │ ├── equalswithdeltaconstraint.h │ │ │ ├── expressions │ │ │ │ ├── andexpression.h │ │ │ │ ├── expression.h │ │ │ │ ├── expression_fwd.h │ │ │ │ ├── notexpression.h │ │ │ │ └── orexpression.h │ │ │ ├── fulfillsconstraint.h │ │ │ ├── haslengthconstraint.h │ │ │ ├── isemptyconstraint.h │ │ │ ├── isgreaterthanconstraint.h │ │ │ ├── isgreaterthanorequaltoconstraint.h │ │ │ ├── islessthanconstraint.h │ │ │ ├── islessthanorequaltoconstraint.h │ │ │ └── startswithconstraint.h │ │ │ ├── exceptions.h │ │ │ ├── fluent │ │ │ ├── constraintadapter.h │ │ │ ├── constraintlist.h │ │ │ ├── expressionbuilder.h │ │ │ ├── fluent.h │ │ │ └── operators │ │ │ │ ├── andoperator.h │ │ │ │ ├── collections │ │ │ │ ├── alloperator.h │ │ │ │ ├── atleastoperator.h │ │ │ │ ├── atmostoperator.h │ │ │ │ ├── collectionconstraintevaluator.h │ │ │ │ ├── collectionoperator.h │ │ │ │ ├── exactlyoperator.h │ │ │ │ └── noneoperator.h │ │ │ │ ├── constraintoperator.h │ │ │ │ ├── invalidexpressionexception.h │ │ │ │ ├── notoperator.h │ │ │ │ └── oroperator.h │ │ │ ├── macros.h │ │ │ ├── snowhouse.h │ │ │ ├── stringize.h │ │ │ └── stringizers.h │ └── util │ │ ├── build-in-container.sh │ │ ├── build.sh │ │ └── format.sh └── stb │ ├── LICENSE │ ├── UPSTREAM.md │ ├── build.py │ ├── stb_image_write.c │ └── stb_image_write.h ├── doc ├── 525-floppy.webp ├── FluxEngine_eagle_pcb.zip ├── Index_sensor_mod_FDD_1.1.pdf ├── applesauce.md ├── building.md ├── closeup1.jpg ├── closeup2.jpg ├── disk-40track_drive.md ├── disk-acornadfs.md ├── disk-acorndfs.md ├── disk-aeslanier.md ├── disk-agat.md ├── disk-amiga.md ├── disk-ampro.md ├── disk-apple2.md ├── disk-apple2_drive.md ├── disk-atarist.md ├── disk-bk.md ├── disk-brother.md ├── disk-commodore.md ├── disk-eco1.md ├── disk-epsonpf10.md ├── disk-f85.md ├── disk-fb100.md ├── disk-hplif.md ├── disk-ibm.md ├── disk-icl30.md ├── disk-mac.md ├── disk-micropolis.md ├── disk-ms2000.md ├── disk-mx.md ├── disk-n88basic.md ├── disk-northstar.md ├── disk-psos.md ├── disk-rolandd20.md ├── disk-rx50.md ├── disk-shugart_drive.md ├── disk-smaky6.md ├── disk-tartu.md ├── disk-tids990.md ├── disk-tiki.md ├── disk-victor9k.md ├── disk-zilogmcz.md ├── driveresponse.md ├── drives.md ├── durangof85.jpg ├── dvk3m.jpg ├── faq.md ├── fdd-90206-dd.png ├── fdd-90206-hd.png ├── filebrowser.jpg ├── filesystem.md ├── greaseweazle.md ├── ju475-dd-hi.png ├── ju475-dd-lo.png ├── ju475-hd-hi.png ├── ju475-hd-lo.png ├── mpf90-dd-lo.png ├── mpf90-hd-hi.png ├── mpf90-hd-lo.png ├── pcb.png ├── problems.md ├── screenshot-details.png ├── screenshot.jpg ├── tartu-fdc.jpg ├── tartu.jpg ├── technical.md ├── tids990.jpg ├── tpdd.jpg ├── using.md ├── vds-eco1.jpg ├── visualiser.jpg └── zilogmcz.jpg ├── extras ├── FluxEngine.app.template │ └── Contents │ │ ├── Info.plist │ │ └── MacOS │ │ └── FluxEngine.sh ├── build.py ├── fluxfile.piko ├── fluxfile.png ├── hardware.piko ├── hardware.png ├── icon.piko ├── icon.png ├── imagefile.piko ├── imagefile.png └── windows-installer.nsi ├── lib ├── algorithms │ ├── build.py │ ├── readerwriter.cc │ └── readerwriter.h ├── config │ ├── build.py │ ├── common.proto │ ├── config.cc │ ├── config.h │ ├── config.proto │ ├── drive.proto │ ├── flags.cc │ ├── flags.h │ ├── layout.proto │ ├── proto.cc │ └── proto.h ├── core │ ├── bitmap.cc │ ├── bitmap.h │ ├── build.py │ ├── bytes.cc │ ├── bytes.h │ ├── crc.cc │ ├── crc.h │ ├── globals.h │ ├── hexdump.cc │ ├── logger.cc │ ├── logger.h │ ├── logrenderer.cc │ ├── utils.cc │ └── utils.h ├── data │ ├── build.py │ ├── flux.h │ ├── fluxmap.cc │ ├── fluxmap.h │ ├── fluxmapreader.cc │ ├── fluxmapreader.h │ ├── fluxpattern.cc │ ├── fluxpattern.h │ ├── image.cc │ ├── image.h │ ├── layout.cc │ ├── layout.h │ ├── sector.cc │ └── sector.h ├── decoders │ ├── build.py │ ├── decoders.cc │ ├── decoders.h │ ├── decoders.proto │ ├── fluxdecoder.cc │ ├── fluxdecoder.h │ ├── fmmfm.cc │ └── rawbits.h ├── encoders │ ├── build.py │ ├── encoders.cc │ ├── encoders.h │ └── encoders.proto ├── external │ ├── a2r.h │ ├── applesauce.h │ ├── build.py │ ├── catweasel.cc │ ├── catweasel.h │ ├── csvreader.cc │ ├── csvreader.h │ ├── fl2.cc │ ├── fl2.h │ ├── fl2.proto │ ├── flx.cc │ ├── flx.h │ ├── greaseweazle.cc │ ├── greaseweazle.h │ ├── kryoflux.cc │ ├── kryoflux.h │ ├── ldbs.cc │ ├── ldbs.h │ └── scp.h ├── fluxsink │ ├── a2rfluxsink.cc │ ├── aufluxsink.cc │ ├── build.py │ ├── fl2fluxsink.cc │ ├── fluxsink.cc │ ├── fluxsink.h │ ├── fluxsink.proto │ ├── hardwarefluxsink.cc │ ├── scpfluxsink.cc │ └── vcdfluxsink.cc ├── fluxsource │ ├── a2rfluxsource.cc │ ├── build.py │ ├── cwffluxsource.cc │ ├── dmkfluxsource.cc │ ├── erasefluxsource.cc │ ├── fl2fluxsource.cc │ ├── fluxsource.cc │ ├── fluxsource.h │ ├── fluxsource.proto │ ├── flxfluxsource.cc │ ├── hardwarefluxsource.cc │ ├── kryofluxfluxsource.cc │ ├── memoryfluxsource.cc │ ├── scpfluxsource.cc │ └── testpatternfluxsource.cc ├── imagereader │ ├── build.py │ ├── d64imagereader.cc │ ├── d88imagereader.cc │ ├── dimimagereader.cc │ ├── diskcopyimagereader.cc │ ├── fdiimagereader.cc │ ├── imagereader.cc │ ├── imagereader.h │ ├── imagereader.proto │ ├── imdimagereader.cc │ ├── imgimagereader.cc │ ├── jv3imagereader.cc │ ├── nfdimagereader.cc │ ├── nsiimagereader.cc │ └── td0imagereader.cc ├── imagewriter │ ├── build.py │ ├── d64imagewriter.cc │ ├── d88imagewriter.cc │ ├── diskcopyimagewriter.cc │ ├── imagewriter.cc │ ├── imagewriter.h │ ├── imagewriter.proto │ ├── imdimagewriter.cc │ ├── imgimagewriter.cc │ ├── ldbsimagewriter.cc │ ├── nsiimagewriter.cc │ └── rawimagewriter.cc ├── usb │ ├── applesauceusb.cc │ ├── build.py │ ├── fluxengineusb.cc │ ├── greaseweazleusb.cc │ ├── serial.cc │ ├── serial.h │ ├── usb.cc │ ├── usb.h │ ├── usb.proto │ ├── usbfinder.cc │ └── usbfinder.h └── vfs │ ├── acorndfs.cc │ ├── amigaffs.cc │ ├── appledos.cc │ ├── applesingle.cc │ ├── applesingle.h │ ├── brother120fs.cc │ ├── build.py │ ├── cbmfs.cc │ ├── cpmfs.cc │ ├── fatfs.cc │ ├── fluxsectorinterface.cc │ ├── imagesectorinterface.cc │ ├── lif.cc │ ├── machfs.cc │ ├── microdos.cc │ ├── philefs.cc │ ├── prodos.cc │ ├── roland.cc │ ├── sectorinterface.h │ ├── smaky6fs.cc │ ├── vfs.cc │ ├── vfs.h │ ├── vfs.proto │ └── zdos.cc ├── protocol.h ├── scripts ├── analysedriveresponse.py ├── build.py ├── commodore1541_test.textpb ├── encodedecodetest.sh ├── mac400_test.textpb ├── mac800_test.textpb ├── mkdoc.cc ├── mkdocindex.cc ├── mktable.sh └── protoencode.cc ├── src ├── build.py ├── fe-analysedriveresponse.cc ├── fe-analyselayout.cc ├── fe-format.cc ├── fe-getdiskinfo.cc ├── fe-getfile.cc ├── fe-getfileinfo.cc ├── fe-inspect.cc ├── fe-ls.cc ├── fe-merge.cc ├── fe-mkdir.cc ├── fe-mv.cc ├── fe-putfile.cc ├── fe-rawread.cc ├── fe-rawwrite.cc ├── fe-read.cc ├── fe-rm.cc ├── fe-rpm.cc ├── fe-seek.cc ├── fe-testbandwidth.cc ├── fe-testdevices.cc ├── fe-testvoltages.cc ├── fe-write.cc ├── fileutils.cc ├── fileutils.h ├── fluxengine.cc ├── fluxengine.h ├── formats │ ├── 40track_drive.textpb │ ├── acornadfs.textpb │ ├── acorndfs.textpb │ ├── aeslanier.textpb │ ├── agat.textpb │ ├── amiga.textpb │ ├── ampro.textpb │ ├── apple2.textpb │ ├── apple2_drive.textpb │ ├── atarist.textpb │ ├── bk.textpb │ ├── brother.textpb │ ├── build.py │ ├── commodore.textpb │ ├── eco1.textpb │ ├── epsonpf10.textpb │ ├── f85.textpb │ ├── fb100.textpb │ ├── hplif.textpb │ ├── ibm.textpb │ ├── icl30.textpb │ ├── mac.textpb │ ├── micropolis.textpb │ ├── ms2000.textpb │ ├── mx.textpb │ ├── n88basic.textpb │ ├── northstar.textpb │ ├── psos.textpb │ ├── rolandd20.textpb │ ├── rx50.textpb │ ├── shugart_drive.textpb │ ├── smaky6.textpb │ ├── tartu.textpb │ ├── tids990.textpb │ ├── tiki.textpb │ ├── victor9k.textpb │ └── zilogmcz.textpb ├── gui │ ├── browserpanel.cc │ ├── build.py │ ├── context.cc │ ├── context.h │ ├── customstatusbar.cc │ ├── customstatusbar.h │ ├── drivetypes │ │ ├── 40track.textpb │ │ ├── 80track.textpb │ │ ├── apple2.textpb │ │ └── build.py │ ├── explorerpanel.cc │ ├── filesystemmodel.cc │ ├── filesystemmodel.h │ ├── fileviewerwindow.cc │ ├── fileviewerwindow.h │ ├── fluxviewercontrol.cc │ ├── fluxviewercontrol.h │ ├── fluxviewerwindow.cc │ ├── fluxviewerwindow.h │ ├── gui.h │ ├── histogramviewer.cc │ ├── histogramviewer.h │ ├── icon.png.h │ ├── iconbutton.cc │ ├── iconbutton.h │ ├── idlepanel.cc │ ├── imagerpanel.cc │ ├── jobqueue.cc │ ├── jobqueue.h │ ├── layout.cpp │ ├── layout.fbp │ ├── layout.h │ ├── main.cc │ ├── mainwindow.cc │ ├── manifest.xml │ ├── texteditorwindow.cc │ ├── texteditorwindow.h │ ├── textviewerwindow.cc │ ├── textviewerwindow.h │ ├── visualisationcontrol.cc │ ├── visualisationcontrol.h │ └── windres.rc └── readibm.h ├── tests ├── agg.cc ├── amiga.cc ├── applesingle.cc ├── bitaccumulator.cc ├── build.py ├── bytes.cc ├── compression.cc ├── configs.cc ├── cpmfs.cc ├── csvreader.cc ├── docker │ ├── Dockerfile.debian11 │ ├── Dockerfile.debian12 │ ├── Dockerfile.fedora40 │ ├── Dockerfile.fedora41 │ └── Dockerfile.manjaro ├── flags.cc ├── fluxmapreader.cc ├── fluxpattern.cc ├── flx.cc ├── fmmfm.cc ├── greaseweazle.cc ├── kryoflux.cc ├── layout.cc ├── ldbs.cc ├── options.cc ├── proto.cc ├── testproto.proto ├── testproto.textpb ├── tests.h ├── utils.cc └── vfs.cc └── tools ├── brother120tool.cc ├── brother240tool.cc ├── build.py └── upgrade-flux-file.cc /.gitignore: -------------------------------------------------------------------------------- 1 | .obj 2 | .project 3 | /.ninja* 4 | /brother120tool 5 | /brother120tool-* 6 | /brother240tool 7 | /brother240tool-* 8 | /fluxengine 9 | /fluxengine-* 10 | /upgrade-flux-file 11 | -------------------------------------------------------------------------------- /.hgignore: -------------------------------------------------------------------------------- 1 | .obj 2 | .git 3 | streams 4 | .*\.flux 5 | .*\.img 6 | .*\.raw 7 | .*\.orig 8 | .vscode 9 | remote 10 | FluxEngine.cydsn/CortexM3 11 | FluxEngine.cydsn/Generated_Source 12 | FluxEngine.cydsn/codegentemp 13 | 14 | -------------------------------------------------------------------------------- /COPYING.md: -------------------------------------------------------------------------------- 1 | Copyright © 2018-2019 David Given 2 | 3 | - Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to 5 | deal in the Software without restriction, including without limitation 6 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | and/or sell copies of the Software, and to permit persons to whom the 8 | Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included 11 | in all copies or substantial portions of the Software. 12 | 13 | - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 14 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 16 | NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 18 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 19 | USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /FluxEngine.cydsn/FIFOin/API/c.c: -------------------------------------------------------------------------------- 1 | #include "cyfitter_cfg.h" 2 | #include "cydevice_trm.h" 3 | #include "cyfitter.h" 4 | #include "`$INSTANCE_NAME`_h.h" 5 | 6 | void `$INSTANCE_NAME`_Start() 7 | { 8 | `$INSTANCE_NAME`_Init(); 9 | } 10 | 11 | void `$INSTANCE_NAME`_Stop() 12 | { 13 | `$INSTANCE_NAME`_Disable(); 14 | } 15 | 16 | void `$INSTANCE_NAME`_Init() 17 | { 18 | `$INSTANCE_NAME`_Enable(); 19 | 20 | } 21 | void `$INSTANCE_NAME`_Enable() 22 | { 23 | } 24 | 25 | void `$INSTANCE_NAME`_Disable() 26 | { 27 | } 28 | -------------------------------------------------------------------------------- /FluxEngine.cydsn/FIFOin/FIFOin.cysym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/FluxEngine.cydsn/FIFOin/FIFOin.cysym -------------------------------------------------------------------------------- /FluxEngine.cydsn/FIFOout/API/c.c: -------------------------------------------------------------------------------- 1 | #include "cyfitter_cfg.h" 2 | #include "cydevice_trm.h" 3 | #include "cyfitter.h" 4 | #include "`$INSTANCE_NAME`_h.h" 5 | 6 | void `$INSTANCE_NAME`_Start() 7 | { 8 | `$INSTANCE_NAME`_Init(); 9 | } 10 | 11 | void `$INSTANCE_NAME`_Stop() 12 | { 13 | `$INSTANCE_NAME`_Disable(); 14 | } 15 | 16 | void `$INSTANCE_NAME`_Init() 17 | { 18 | `$INSTANCE_NAME`_Enable(); 19 | 20 | } 21 | void `$INSTANCE_NAME`_Enable() 22 | { 23 | } 24 | 25 | void `$INSTANCE_NAME`_Disable() 26 | { 27 | } 28 | -------------------------------------------------------------------------------- /FluxEngine.cydsn/FIFOout/FIFOout.cysym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/FluxEngine.cydsn/FIFOout/FIFOout.cysym -------------------------------------------------------------------------------- /FluxEngine.cydsn/PulseGen/PulseGen.cysym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/FluxEngine.cydsn/PulseGen/PulseGen.cysym -------------------------------------------------------------------------------- /FluxEngine.cydsn/PulseGen/PulseGen.cyudb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/FluxEngine.cydsn/PulseGen/PulseGen.cyudb -------------------------------------------------------------------------------- /FluxEngine.cydsn/Sampler/Sampler.cysym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/FluxEngine.cydsn/Sampler/Sampler.cysym -------------------------------------------------------------------------------- /FluxEngine.cydsn/Sequencer/Sequencer.cysym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/FluxEngine.cydsn/Sequencer/Sequencer.cysym -------------------------------------------------------------------------------- /FluxEngine.cydsn/SuperCounter/SuperCounter.cysym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/FluxEngine.cydsn/SuperCounter/SuperCounter.cysym -------------------------------------------------------------------------------- /FluxEngine.cydsn/TopDesign/TopDesign.cysch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/FluxEngine.cydsn/TopDesign/TopDesign.cysch -------------------------------------------------------------------------------- /FluxEngine.cydsn/cyapicallbacks.h: -------------------------------------------------------------------------------- 1 | /* ======================================== 2 | * 3 | * Copyright YOUR COMPANY, THE YEAR 4 | * All Rights Reserved 5 | * UNPUBLISHED, LICENSED SOFTWARE. 6 | * 7 | * CONFIDENTIAL AND PROPRIETARY INFORMATION 8 | * WHICH IS THE PROPERTY OF your company. 9 | * 10 | * ======================================== 11 | */ 12 | #ifndef CYAPICALLBACKS_H 13 | #define CYAPICALLBACKS_H 14 | 15 | 16 | /*Define your macro callbacks here */ 17 | /*For more information, refer to the Writing Code topic in the PSoC Creator Help.*/ 18 | 19 | 20 | #endif /* CYAPICALLBACKS_H */ 21 | /* [] */ 22 | -------------------------------------------------------------------------------- /arch/aeslanier/aeslanier.h: -------------------------------------------------------------------------------- 1 | #ifndef AESLANIER_H 2 | #define AESLANIER_H 3 | 4 | #define AESLANIER_RECORD_SEPARATOR 0x55555122 5 | #define AESLANIER_SECTOR_LENGTH 256 6 | #define AESLANIER_RECORD_SIZE (AESLANIER_SECTOR_LENGTH + 5) 7 | 8 | extern std::unique_ptr createAesLanierDecoder( 9 | const DecoderProto& config); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /arch/aeslanier/aeslanier.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message AesLanierDecoderProto {} 4 | 5 | -------------------------------------------------------------------------------- /arch/agat/agat.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/decoders/decoders.h" 3 | #include "arch/agat/agat.h" 4 | #include "lib/core/bytes.h" 5 | #include "fmt/format.h" 6 | 7 | uint8_t agatChecksum(const Bytes& bytes) 8 | { 9 | uint16_t checksum = 0; 10 | 11 | for (uint8_t b : bytes) 12 | { 13 | if (checksum > 0xff) 14 | checksum = (checksum + 1) & 0xff; 15 | 16 | checksum += b; 17 | } 18 | 19 | return checksum & 0xff; 20 | } 21 | -------------------------------------------------------------------------------- /arch/agat/agat.h: -------------------------------------------------------------------------------- 1 | #ifndef AGAT_H 2 | #define AGAT_H 3 | 4 | #define AGAT_SECTOR_SIZE 256 5 | 6 | static constexpr uint64_t SECTOR_ID = 0x8924555549111444; 7 | static constexpr uint64_t DATA_ID = 0x8924555514444911; 8 | 9 | class Encoder; 10 | class EncoderProto; 11 | class Decoder; 12 | class DecoderProto; 13 | 14 | extern std::unique_ptr createAgatDecoder(const DecoderProto& config); 15 | extern std::unique_ptr createAgatEncoder(const EncoderProto& config); 16 | 17 | extern uint8_t agatChecksum(const Bytes& bytes); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /arch/agat/agat.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "lib/config/common.proto"; 4 | 5 | message AgatDecoderProto {} 6 | 7 | message AgatEncoderProto { 8 | optional double target_clock_period_us = 1 9 | [default=2.00, (help)="Data clock period of target format."]; 10 | optional double target_rotational_period_ms = 2 11 | [default=200.0, (help)="Rotational period of target format."]; 12 | optional int32 post_index_gap_bytes = 3 13 | [default=40, (help)="Post-index gap before first sector header."]; 14 | optional int32 pre_sector_gap_bytes = 4 15 | [default=11, (help)="Gap before each sector header."]; 16 | optional int32 pre_data_gap_bytes = 5 17 | [default=2, (help)="Gap before each sector data record."]; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /arch/amiga/amiga.h: -------------------------------------------------------------------------------- 1 | #ifndef AMIGA_H 2 | #define AMIGA_H 3 | 4 | #include "lib/encoders/encoders.h" 5 | 6 | #define AMIGA_SECTOR_RECORD 0xaaaa44894489LL 7 | 8 | #define AMIGA_TRACKS_PER_DISK 80 9 | #define AMIGA_SECTORS_PER_TRACK 11 10 | #define AMIGA_RECORD_SIZE 0x21c 11 | 12 | extern std::unique_ptr createAmigaDecoder(const DecoderProto& config); 13 | extern std::unique_ptr createAmigaEncoder(const EncoderProto& config); 14 | 15 | extern uint32_t amigaChecksum(const Bytes& bytes); 16 | extern Bytes amigaInterleave(const Bytes& input); 17 | extern Bytes amigaDeinterleave(const uint8_t*& input, size_t len); 18 | extern Bytes amigaDeinterleave(const Bytes& input); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /arch/amiga/amiga.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "lib/config/common.proto"; 4 | 5 | message AmigaDecoderProto {} 6 | 7 | message AmigaEncoderProto { 8 | optional double clock_rate_us = 1 9 | [default=2.00, (help)="Encoded data clock rate."]; 10 | optional double post_index_gap_ms = 2 11 | [default=0.5, (help)="Post-index gap before first sector header."]; 12 | } 13 | 14 | -------------------------------------------------------------------------------- /arch/apple2/apple2.h: -------------------------------------------------------------------------------- 1 | #ifndef APPLE2_H 2 | #define APPLE2_H 3 | 4 | #include 5 | #include "lib/decoders/decoders.h" 6 | #include "lib/encoders/encoders.h" 7 | 8 | #define APPLE2_SECTOR_RECORD 0xd5aa96 9 | #define APPLE2_DATA_RECORD 0xd5aaad 10 | 11 | #define APPLE2_SECTOR_LENGTH 256 12 | #define APPLE2_ENCODED_SECTOR_LENGTH 342 13 | 14 | #define APPLE2_SECTORS 16 15 | 16 | extern std::unique_ptr createApple2Decoder(const DecoderProto& config); 17 | extern std::unique_ptr createApple2Encoder(const EncoderProto& config); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /arch/apple2/apple2.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "lib/config/common.proto"; 4 | 5 | message Apple2DecoderProto { 6 | optional uint32 side_one_track_offset = 1 7 | [ default = 0, (help) = "offset to apply to track numbers on side 1" ]; 8 | } 9 | 10 | message Apple2EncoderProto 11 | { 12 | /* 245kHz. */ 13 | optional double clock_period_us = 1 14 | [ default = 4, (help) = "clock rate on the real device" ]; 15 | 16 | /* Apple II disk drives spin at 300rpm. */ 17 | optional double rotational_period_ms = 2 18 | [ default = 200.0, (help) = "rotational period on the real device" ]; 19 | 20 | optional uint32 side_one_track_offset = 3 21 | [ default = 0, (help) = "offset to apply to track numbers on side 1" ]; 22 | } 23 | -------------------------------------------------------------------------------- /arch/arch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class Encoder; 4 | class Decoder; 5 | class DecoderProto; 6 | class EncoderProto; 7 | class Config; 8 | 9 | namespace Arch 10 | { 11 | std::unique_ptr createDecoder(Config& config); 12 | std::unique_ptr createDecoder(const DecoderProto& config); 13 | 14 | std::unique_ptr createEncoder(Config& config); 15 | std::unique_ptr createEncoder(const EncoderProto& config); 16 | } 17 | -------------------------------------------------------------------------------- /arch/brother/brother.h: -------------------------------------------------------------------------------- 1 | #ifndef BROTHER_H 2 | #define BROTHER_H 3 | 4 | /* Brother word processor format (or at least, one of them) */ 5 | 6 | #define BROTHER_SECTOR_RECORD 0xFFFFFD57 7 | #define BROTHER_DATA_RECORD 0xFFFFFDDB 8 | #define BROTHER_DATA_RECORD_PAYLOAD 256 9 | #define BROTHER_DATA_RECORD_CHECKSUM 3 10 | #define BROTHER_DATA_RECORD_ENCODED_SIZE 415 11 | 12 | #define BROTHER_TRACKS_PER_240KB_DISK 78 13 | #define BROTHER_TRACKS_PER_120KB_DISK 39 14 | #define BROTHER_SECTORS_PER_TRACK 12 15 | 16 | extern std::unique_ptr createBrotherDecoder( 17 | const DecoderProto& config); 18 | extern std::unique_ptr createBrotherEncoder( 19 | const EncoderProto& config); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /arch/brother/brother.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message BrotherDecoderProto {} 4 | 5 | enum BrotherFormat { 6 | BROTHER240 = 0; 7 | BROTHER120 = 1; 8 | }; 9 | 10 | message BrotherEncoderProto { 11 | optional double clock_rate_us = 1 [default = 3.83]; 12 | optional double post_index_gap_ms = 2 [default = 1.0]; 13 | optional double sector_spacing_ms = 3 [default = 16.2]; 14 | optional double post_header_spacing_ms = 4 [default = 0.69]; 15 | 16 | optional BrotherFormat format = 6 [default = BROTHER240]; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /arch/brother/data_gcr.h: -------------------------------------------------------------------------------- 1 | GCR_ENTRY(0x55, 0) // 00000 2 | GCR_ENTRY(0x57, 1) // 00001 3 | GCR_ENTRY(0x5b, 2) // 00010 4 | GCR_ENTRY(0x5d, 3) // 00011 5 | GCR_ENTRY(0x5f, 4) // 00100 6 | GCR_ENTRY(0x6b, 5) // 00101 7 | GCR_ENTRY(0x6d, 6) // 00110 8 | GCR_ENTRY(0x6f, 7) // 00111 9 | GCR_ENTRY(0x75, 8) // 01000 10 | GCR_ENTRY(0x77, 9) // 01001 11 | GCR_ENTRY(0x7b, 10) // 01010 12 | GCR_ENTRY(0x7d, 11) // 01011 13 | GCR_ENTRY(0x7f, 12) // 01100 14 | GCR_ENTRY(0xab, 13) // 01101 15 | GCR_ENTRY(0xad, 14) // 01110 16 | GCR_ENTRY(0xaf, 15) // 01111 17 | GCR_ENTRY(0xb5, 16) // 10000 18 | GCR_ENTRY(0xb7, 17) // 10001 19 | GCR_ENTRY(0xbb, 18) // 10010 20 | GCR_ENTRY(0xbd, 19) // 10011 21 | GCR_ENTRY(0xbf, 20) // 10100 22 | GCR_ENTRY(0xd5, 21) // 10101 23 | GCR_ENTRY(0xd7, 22) // 10110 24 | GCR_ENTRY(0xdb, 23) // 10111 25 | GCR_ENTRY(0xdd, 24) // 11000 26 | GCR_ENTRY(0xdf, 25) // 11001 27 | GCR_ENTRY(0xeb, 26) // 11010 28 | GCR_ENTRY(0xed, 27) // 11011 29 | GCR_ENTRY(0xef, 28) // 11100 30 | GCR_ENTRY(0xf5, 29) // 11101 31 | GCR_ENTRY(0xf7, 30) // 11110 32 | GCR_ENTRY(0xfb, 31) // 11111 33 | -------------------------------------------------------------------------------- /arch/c64/c64.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "arch/c64/c64.h" 3 | 4 | /* 5 | * Track Sectors/track # Sectors Storage in Bytes Clock rate 6 | * ----- ------------- --------- ---------------- ---------- 7 | * 1-17 21 357 7820 3.25 8 | * 18-24 19 133 7170 3.5 9 | * 25-30 18 108 6300 3.75 10 | * 31-40(*) 17 85 6020 4 11 | * --- 12 | * 683 (for a 35 track image) 13 | * 14 | * The clock rate is normalised for a 200ms drive. 15 | */ 16 | 17 | nanoseconds_t clockPeriodForC64Track(unsigned track) 18 | { 19 | constexpr double b = 8.0; 20 | 21 | if (track < 17) 22 | return 26.0 / b; 23 | if (track < 24) 24 | return 28.0 / b; 25 | if (track < 30) 26 | return 30.0 / b; 27 | return 32.0 / b; 28 | } 29 | -------------------------------------------------------------------------------- /arch/c64/c64.h: -------------------------------------------------------------------------------- 1 | #ifndef C64_H 2 | #define C64_H 3 | 4 | #include "lib/decoders/decoders.h" 5 | #include "lib/encoders/encoders.h" 6 | 7 | #define C64_SECTOR_RECORD 0xffd49 8 | #define C64_DATA_RECORD 0xffd57 9 | #define C64_SECTOR_LENGTH 256 10 | 11 | /* Source: http://www.unusedino.de/ec64/technical/formats/g64.html 12 | 1. Header sync FF FF FF FF FF (40 'on' bits, not GCR) 13 | 2. Header info 52 54 B5 29 4B 7A 5E 95 55 55 (10 GCR bytes) 14 | 3. Header gap 55 55 55 55 55 55 55 55 55 (9 bytes, never read) 15 | 4. Data sync FF FF FF FF FF (40 'on' bits, not GCR) 16 | 5. Data block 55...4A (325 GCR bytes) 17 | 6. Inter-sector gap 55 55 55 55...55 55 (4 to 12 bytes, never read) 18 | 1. Header sync (SYNC for the next sector) 19 | */ 20 | #define C64_HEADER_DATA_SYNC 0xFF 21 | #define C64_HEADER_BLOCK_ID 0x08 22 | #define C64_DATA_BLOCK_ID 0x07 23 | #define C64_HEADER_GAP 0x55 24 | #define C64_INTER_SECTOR_GAP 0x55 25 | #define C64_PADDING 0x0F 26 | 27 | #define C64_TRACKS_PER_DISK 40 28 | #define C64_BAM_TRACK 17 29 | 30 | extern std::unique_ptr createCommodore64Decoder( 31 | const DecoderProto& config); 32 | extern std::unique_ptr createCommodore64Encoder( 33 | const EncoderProto& config); 34 | 35 | extern nanoseconds_t clockPeriodForC64Track(unsigned track); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /arch/c64/c64.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "lib/config/common.proto"; 4 | 5 | message Commodore64DecoderProto {} 6 | 7 | message Commodore64EncoderProto { 8 | optional double post_index_gap_us = 1 [default=0.0, 9 | (help) = "post-index gap before first sector header."]; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /arch/c64/data_gcr.h: -------------------------------------------------------------------------------- 1 | GCR_ENTRY(0x0a, 0x0); 2 | GCR_ENTRY(0x0b, 0x1); 3 | GCR_ENTRY(0x12, 0x2); 4 | GCR_ENTRY(0x13, 0x3); 5 | GCR_ENTRY(0x0e, 0x4); 6 | GCR_ENTRY(0x0f, 0x5); 7 | GCR_ENTRY(0x16, 0x6); 8 | GCR_ENTRY(0x17, 0x7); 9 | GCR_ENTRY(0x09, 0x8); 10 | GCR_ENTRY(0x19, 0x9); 11 | GCR_ENTRY(0x1a, 0xa); 12 | GCR_ENTRY(0x1b, 0xb); 13 | GCR_ENTRY(0x0d, 0xc); 14 | GCR_ENTRY(0x1d, 0xd); 15 | GCR_ENTRY(0x1e, 0xe); 16 | GCR_ENTRY(0x15, 0xf); 17 | -------------------------------------------------------------------------------- /arch/f85/data_gcr.h: -------------------------------------------------------------------------------- 1 | GCR_ENTRY(0x19, 0x00); 2 | GCR_ENTRY(0x1b, 0x01); 3 | GCR_ENTRY(0x12, 0x02); 4 | GCR_ENTRY(0x13, 0x03); 5 | GCR_ENTRY(0x1d, 0x04); 6 | GCR_ENTRY(0x15, 0x05); 7 | GCR_ENTRY(0x16, 0x06); 8 | GCR_ENTRY(0x17, 0x07); 9 | GCR_ENTRY(0x1a, 0x08); 10 | GCR_ENTRY(0x09, 0x09); 11 | GCR_ENTRY(0x0a, 0x0a); 12 | GCR_ENTRY(0x0b, 0x0b); 13 | GCR_ENTRY(0x1e, 0x0c); 14 | GCR_ENTRY(0x0d, 0x0d); 15 | GCR_ENTRY(0x0e, 0x0e); 16 | GCR_ENTRY(0x0f, 0x0f); 17 | -------------------------------------------------------------------------------- /arch/f85/f85.h: -------------------------------------------------------------------------------- 1 | #ifndef F85_H 2 | #define F85_H 3 | 4 | #define F85_SECTOR_RECORD 0xffffce /* 1111 1111 1111 1111 1100 1110 */ 5 | #define F85_DATA_RECORD 0xffffcb /* 1111 1111 1111 1111 1100 1101 */ 6 | #define F85_SECTOR_LENGTH 512 7 | 8 | extern std::unique_ptr createDurangoF85Decoder( 9 | const DecoderProto& config); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /arch/f85/f85.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message F85DecoderProto {} 4 | 5 | -------------------------------------------------------------------------------- /arch/fb100/fb100.h: -------------------------------------------------------------------------------- 1 | #ifndef FB100_H 2 | #define FB100_H 3 | 4 | #define FB100_RECORD_SIZE 0x516 /* bytes */ 5 | #define FB100_ID_SIZE 17 6 | #define FB100_PAYLOAD_SIZE 0x500 7 | 8 | extern std::unique_ptr createFb100Decoder(const DecoderProto& config); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /arch/fb100/fb100.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message Fb100DecoderProto {} 4 | 5 | -------------------------------------------------------------------------------- /arch/ibm/ibm.h: -------------------------------------------------------------------------------- 1 | #ifndef IBM_H 2 | #define IBM_H 3 | 4 | /* IBM format (i.e. ordinary PC floppies). */ 5 | 6 | #define IBM_MFM_SYNC 0xA1 /* sync byte for MFM */ 7 | #define IBM_IAM 0xFC /* start-of-track record */ 8 | #define IBM_IAM_LEN 1 /* plus prologue */ 9 | #define IBM_IDAM 0xFE /* sector header */ 10 | #define IBM_IDAM_LEN 7 /* plus prologue */ 11 | #define IBM_DAM1 0xF8 /* sector data (type 1) */ 12 | #define IBM_DAM2 0xFB /* sector data (type 2) */ 13 | #define IBM_TRS80DAM1 0xF9 /* sector data (TRS-80 directory) */ 14 | #define IBM_TRS80DAM2 0xFA /* sector data (TRS-80 directory) */ 15 | #define IBM_DAM_LEN 1 /* plus prologue and user data */ 16 | 17 | /* Length of a DAM record is determined by the previous sector header. */ 18 | 19 | struct IbmIdam 20 | { 21 | uint8_t id; 22 | uint8_t track; 23 | uint8_t side; 24 | uint8_t sector; 25 | uint8_t sectorSize; 26 | uint8_t crc[2]; 27 | }; 28 | 29 | class Encoder; 30 | class Decoder; 31 | class DecoderProto; 32 | class EncoderProto; 33 | 34 | extern std::unique_ptr createIbmDecoder(const DecoderProto& config); 35 | extern std::unique_ptr createIbmEncoder(const EncoderProto& config); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /arch/macintosh/macintosh.h: -------------------------------------------------------------------------------- 1 | #ifndef MACINTOSH_H 2 | #define MACINTOSH_H 3 | 4 | #define MAC_SECTOR_RECORD 0xd5aa96 /* 1101 0101 1010 1010 1001 0110 */ 5 | #define MAC_DATA_RECORD 0xd5aaad /* 1101 0101 1010 1010 1010 1101 */ 6 | 7 | #define MAC_SECTOR_LENGTH 524 /* yes, really */ 8 | #define MAC_ENCODED_SECTOR_LENGTH 703 9 | #define MAC_FORMAT_BYTE 0x22 10 | 11 | #define MAC_TRACKS_PER_DISK 80 12 | 13 | class Encoder; 14 | class Decoder; 15 | class DecoderProto; 16 | class EncoderProto; 17 | 18 | extern std::unique_ptr createMacintoshDecoder( 19 | const DecoderProto& config); 20 | extern std::unique_ptr createMacintoshEncoder( 21 | const EncoderProto& config); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /arch/macintosh/macintosh.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "lib/config/common.proto"; 4 | 5 | message MacintoshDecoderProto {} 6 | 7 | message MacintoshEncoderProto { 8 | optional double post_index_gap_us = 1 [default = 0.0, 9 | (help) = "post-index gap before first sector header (microseconds)."]; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /arch/micropolis/micropolis.h: -------------------------------------------------------------------------------- 1 | #ifndef MICROPOLIS_H 2 | #define MICROPOLIS_H 3 | 4 | #define MICROPOLIS_PAYLOAD_SIZE (256) 5 | #define MICROPOLIS_HEADER_SIZE (1 + 2 + 10) 6 | #define MICROPOLIS_ENCODED_SECTOR_SIZE \ 7 | (MICROPOLIS_HEADER_SIZE + MICROPOLIS_PAYLOAD_SIZE + 6) 8 | 9 | class Decoder; 10 | class Encoder; 11 | class EncoderProto; 12 | class DecoderProto; 13 | 14 | extern std::unique_ptr createMicropolisDecoder( 15 | const DecoderProto& config); 16 | extern std::unique_ptr createMicropolisEncoder( 17 | const EncoderProto& config); 18 | 19 | extern uint8_t micropolisChecksum(const Bytes& bytes); 20 | extern uint32_t vectorGraphicEcc(const Bytes& bytes); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /arch/micropolis/micropolis.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "lib/config/common.proto"; 4 | 5 | message MicropolisDecoderProto { 6 | enum ChecksumType { 7 | AUTO = 0; 8 | MICROPOLIS = 1; 9 | MZOS = 2; 10 | } 11 | enum EccType { 12 | NONE = 0; 13 | VECTOR = 1; 14 | } 15 | 16 | optional int32 sector_output_size = 1 [default = 256, 17 | (help) = "How much of the raw sector should be saved. Must be 256 or 275"]; 18 | optional ChecksumType checksum_type = 2 [default = AUTO, 19 | (help) = "Checksum type to use: AUTO, MICROPOLIS, MZOS"]; 20 | optional EccType ecc_type = 3 [default = NONE, 21 | (help) = "ECC type to use: NONE, VECTOR"]; 22 | } 23 | 24 | message MicropolisEncoderProto { 25 | enum EccType { 26 | NONE = 0; 27 | VECTOR = 1; 28 | } 29 | 30 | optional double clock_period_us = 1 31 | [ default = 2.0, (help) = "clock rate on the real device" ]; 32 | optional double rotational_period_ms = 2 33 | [ default = 200.0, (help) = "rotational period on the real device" ]; 34 | optional EccType ecc_type = 3 [default = NONE, 35 | (help) = "ECC type to use for IMG data: NONE, VECTOR"]; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /arch/mx/mx.h: -------------------------------------------------------------------------------- 1 | #ifndef MX_H 2 | #define MX_H 3 | 4 | #include "lib/decoders/decoders.h" 5 | 6 | extern std::unique_ptr createMxDecoder(const DecoderProto& config); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /arch/mx/mx.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message MxDecoderProto {} 4 | 5 | -------------------------------------------------------------------------------- /arch/northstar/northstar.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "lib/config/common.proto"; 4 | 5 | message NorthstarDecoderProto {} 6 | 7 | message NorthstarEncoderProto { 8 | optional double clock_period_us = 1 9 | [ default = 4.0, (help) = "clock rate on the real device (for FM)" ]; 10 | optional double rotational_period_ms = 2 11 | [ default = 166.0, (help) = "rotational period on the real device" ]; 12 | } 13 | 14 | -------------------------------------------------------------------------------- /arch/rolandd20/rolandd20.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | extern std::unique_ptr createRolandD20Decoder( 4 | const DecoderProto& config); 5 | -------------------------------------------------------------------------------- /arch/rolandd20/rolandd20.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message RolandD20DecoderProto {} 4 | 5 | 6 | -------------------------------------------------------------------------------- /arch/smaky6/smaky6.h: -------------------------------------------------------------------------------- 1 | #ifndef SMAKY6_H 2 | #define SMAKY6_H 3 | 4 | #define SMAKY6_SECTOR_SIZE 256 5 | #define SMAKY6_RECORD_SIZE (1 + SMAKY6_SECTOR_SIZE + 1) 6 | 7 | extern std::unique_ptr createSmaky6Decoder(const DecoderProto& config); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /arch/smaky6/smaky6.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message Smaky6DecoderProto {} 4 | 5 | -------------------------------------------------------------------------------- /arch/tartu/tartu.h: -------------------------------------------------------------------------------- 1 | #ifndef TARTU_H 2 | #define TARTU_H 3 | 4 | extern std::unique_ptr createTartuDecoder(const DecoderProto& config); 5 | extern std::unique_ptr createTartuEncoder(const EncoderProto& config); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /arch/tartu/tartu.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "lib/config/common.proto"; 4 | 5 | message TartuDecoderProto {} 6 | 7 | message TartuEncoderProto { 8 | optional double clock_period_us = 1 9 | [ default = 2.0, (help) = "clock rate on the real device (for MFM)" ]; 10 | optional double target_rotational_period_ms = 2 11 | [ default=200, (help) = "rotational period of target disk" ]; 12 | optional double gap1_us = 3 13 | [ default = 1200, 14 | (help) = "size of gap 1 (the post-index gap)" ]; 15 | optional double gap3_us = 4 16 | [ default = 150, 17 | (help) = "size of gap 3 (the pre-data gap)" ]; 18 | optional double gap4_us = 5 19 | [ default = 180, 20 | (help) = "size of gap 4 (the post-data or format gap)" ]; 21 | optional uint64 header_marker = 6 22 | [ default = 0xaaaaaaaa44895554, 23 | (help) = "64-bit raw bit pattern of header record marker" ]; 24 | optional uint64 data_marker = 7 25 | [ default = 0xaaaaaaaa44895545, 26 | (help) = "64-bit raw bit pattern of data record marker" ]; 27 | } 28 | -------------------------------------------------------------------------------- /arch/tids990/tids990.h: -------------------------------------------------------------------------------- 1 | #ifndef TIDS990_H 2 | #define TIDS990_H 3 | 4 | #define TIDS990_PAYLOAD_SIZE 288 /* bytes */ 5 | #define TIDS990_SECTOR_RECORD_SIZE 10 /* bytes */ 6 | #define TIDS990_DATA_RECORD_SIZE (TIDS990_PAYLOAD_SIZE + 4) /* bytes */ 7 | 8 | class Encoder; 9 | class Decoder; 10 | class DecoderProto; 11 | class EncoderProto; 12 | 13 | extern std::unique_ptr createTids990Decoder( 14 | const DecoderProto& config); 15 | extern std::unique_ptr createTids990Encoder( 16 | const EncoderProto& config); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /arch/tids990/tids990.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "lib/config/common.proto"; 4 | 5 | message Tids990DecoderProto {} 6 | 7 | message Tids990EncoderProto { 8 | optional double rotational_period_ms = 1 [ default = 166, 9 | (help) = "length of a track" ]; 10 | optional int32 sector_count = 2 [ default = 26, 11 | (help) = "number of sectors per track" ]; 12 | optional double clock_period_us = 3 [ default = 2, 13 | (help) = "clock rate of data to write" ]; 14 | optional int32 am1_byte = 4 [ default = 0x2244, 15 | (help) = "16-bit RAW bit pattern to use for the AM1 ID byte" ]; 16 | optional int32 am2_byte = 5 [ default = 0x2245, 17 | (help) = "16-bit RAW bit pattern to use for the AM2 ID byte" ]; 18 | optional int32 gap1_bytes = 6 [ default = 80, 19 | (help) = "size of gap 1 (the post-index gap)" ]; 20 | optional int32 gap2_bytes = 7 [ default = 21, 21 | (help) = "size of gap 2 (the post-ID gap)" ]; 22 | optional int32 gap3_bytes = 8 [ default = 51, 23 | (help) = "size of gap 3 (the post-data or format gap)" ]; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /arch/victor9k/data_gcr.h: -------------------------------------------------------------------------------- 1 | GCR_ENTRY(0x0a, 0x0); 2 | GCR_ENTRY(0x0b, 0x1); 3 | GCR_ENTRY(0x12, 0x2); 4 | GCR_ENTRY(0x13, 0x3); 5 | GCR_ENTRY(0x0e, 0x4); 6 | GCR_ENTRY(0x0f, 0x5); 7 | GCR_ENTRY(0x16, 0x6); 8 | GCR_ENTRY(0x17, 0x7); 9 | GCR_ENTRY(0x09, 0x8); 10 | GCR_ENTRY(0x19, 0x9); 11 | GCR_ENTRY(0x1a, 0xa); 12 | GCR_ENTRY(0x1b, 0xb); 13 | GCR_ENTRY(0x0d, 0xc); 14 | GCR_ENTRY(0x1d, 0xd); 15 | GCR_ENTRY(0x1e, 0xe); 16 | GCR_ENTRY(0x15, 0xf); 17 | -------------------------------------------------------------------------------- /arch/victor9k/victor9k.h: -------------------------------------------------------------------------------- 1 | #ifndef VICTOR9K_H 2 | #define VICTOR9K_H 3 | 4 | class Encoder; 5 | class Decoder; 6 | class EncoderProto; 7 | class DecoderProto; 8 | 9 | /* ... 1101 0101 0111 10 | * ^^ ^^^^ ^^^^ ten bit IO byte */ 11 | #define VICTOR9K_SECTOR_RECORD 0xfffffd57 12 | #define VICTOR9K_HEADER_ID 0x7 13 | 14 | /* ... 1101 0100 1001 15 | * ^^ ^^^^ ^^^^ ten bit IO byte */ 16 | #define VICTOR9K_DATA_RECORD 0xfffffd49 17 | #define VICTOR9K_DATA_ID 0x8 18 | 19 | #define VICTOR9K_SECTOR_LENGTH 512 20 | 21 | extern std::unique_ptr createVictor9kDecoder( 22 | const DecoderProto& config); 23 | extern std::unique_ptr createVictor9kEncoder( 24 | const EncoderProto& config); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /arch/zilogmcz/zilogmcz.h: -------------------------------------------------------------------------------- 1 | #ifndef ZILOGMCZ_H 2 | #define ZILOGMCZ_H 3 | 4 | extern std::unique_ptr createZilogMczDecoder( 5 | const DecoderProto& config); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /arch/zilogmcz/zilogmcz.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | message ZilogMczDecoderProto {} 4 | 5 | -------------------------------------------------------------------------------- /build/_objectify.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from functools import partial 3 | 4 | if len(sys.argv) != 3: 5 | sys.exit("Usage: %s " % sys.argv[0]) 6 | filename = sys.argv[1] 7 | symbol = sys.argv[2] 8 | 9 | print("const uint8_t " + symbol + "[] = {") 10 | n = 0 11 | with open(filename, "rb") as in_file: 12 | for c in iter(partial(in_file.read, 1), b""): 13 | print("0x%02X," % ord(c), end="") 14 | n += 1 15 | if n % 16 == 0: 16 | print() 17 | print("};") 18 | 19 | print("const size_t " + symbol + "_len = sizeof(" + symbol + ");") 20 | -------------------------------------------------------------------------------- /build/_zip.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from os.path import * 4 | import argparse 5 | import os 6 | from zipfile import ZipFile 7 | 8 | 9 | def main(): 10 | parser = argparse.ArgumentParser() 11 | parser.add_argument("-z", "--zipfile") 12 | parser.add_argument("-v", "--verbose", action="store_true") 13 | parser.add_argument("-f", "--file", nargs=2, action="append") 14 | args = parser.parse_args() 15 | 16 | assert args.zipfile, "You must specify a zipfile to create" 17 | 18 | with ZipFile(args.zipfile, mode="w") as zf: 19 | for zipname, filename in args.file: 20 | if args.verbose: 21 | print(filename, "->", zipname) 22 | zf.write(filename, arcname=zipname) 23 | 24 | 25 | main() 26 | -------------------------------------------------------------------------------- /build/toolchain.py: -------------------------------------------------------------------------------- 1 | class Toolchain: 2 | PREFIX = "" 3 | 4 | 5 | class HostToolchain(Toolchain): 6 | PREFIX = "HOST" 7 | -------------------------------------------------------------------------------- /build/zip.py: -------------------------------------------------------------------------------- 1 | from build.ab import ( 2 | Rule, 3 | simplerule, 4 | TargetsMap, 5 | filenameof, 6 | ) 7 | 8 | 9 | @Rule 10 | def zip( 11 | self, name, flags="", items: TargetsMap = {}, extension="zip", label="ZIP" 12 | ): 13 | cs = ["$(PYTHON) build/_zip.py -z $[outs]"] 14 | 15 | ins = [] 16 | for k, v in items.items(): 17 | cs += [f"-f {k} {filenameof(v)}"] 18 | ins += [v] 19 | 20 | simplerule( 21 | replaces=self, 22 | ins=ins, 23 | deps=["build/_zip.py"], 24 | outs=[f"={self.localname}." + extension], 25 | commands=[" ".join(cs)], 26 | label=label, 27 | ) 28 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | import platform 2 | import os 3 | 4 | if os.getenv("BUILDTYPE") == "windows": 5 | windows = True 6 | osx = False 7 | unix = False 8 | else: 9 | windows = False 10 | osx = platform.system() == "Darwin" 11 | unix = True 12 | -------------------------------------------------------------------------------- /dep/adflib/.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.lo 4 | 5 | # Libraries 6 | .libs 7 | *.lib 8 | *.a 9 | *.la 10 | 11 | # Shared objects (inc. Windows DLLs) 12 | *.dll 13 | *.so 14 | *.so.* 15 | *.dylib 16 | 17 | # Executables 18 | *.exe 19 | *.out 20 | *.app 21 | 22 | # generated by autogen.sh 23 | INSTALL 24 | Makefile.in 25 | aclocal.m4 26 | autom4te.cache 27 | compile 28 | config.guess 29 | config.h.in 30 | config.sub 31 | configure 32 | depcomp 33 | install-sh 34 | ltmain.sh 35 | missing 36 | 37 | # generated by configure 38 | .deps 39 | Makefile 40 | adflib.pc 41 | config.h 42 | config.log 43 | config.status 44 | libtool 45 | stamp-h1 46 | -------------------------------------------------------------------------------- /dep/adflib/AUTHORS: -------------------------------------------------------------------------------- 1 | 2 | The main developper is 3 | Laurent Clévy (laurent.clevy@club-internet.fr) 4 | 5 | Contributors are: 6 | Bjarne Viksoe 7 | (C++ wrapper, lot of bug fixes) 8 | Gary Harris 9 | (bug fixes and W32 support) 10 | Dan Sutherland 11 | (bug fixes and W32 support) 12 | 13 | See CHANGES.txt for detailed contributions. 14 | -------------------------------------------------------------------------------- /dep/adflib/UPSTREAM.md: -------------------------------------------------------------------------------- 1 | This is head of git downloaded from https://github.com/lclevy/ADFlib on 2 | 2022-08-28. 3 | -------------------------------------------------------------------------------- /dep/adflib/adf_nativ.h: -------------------------------------------------------------------------------- 1 | #ifndef ADF_NATIV_H 2 | #define ADF_NATIV_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" 6 | { 7 | #endif 8 | 9 | #include "adf_str.h" 10 | 11 | #define NATIVE_FILE 8001 12 | 13 | struct nativeDevice 14 | { 15 | FILE* fd; 16 | }; 17 | 18 | struct nativeFunctions 19 | { 20 | /* called by adfMount() */ 21 | RETCODE (*adfInitDevice)(struct Device*, char*, BOOL); 22 | /* called by adfReadBlock() */ 23 | RETCODE (*adfNativeReadSector)(struct Device*, int32_t, int, uint8_t*); 24 | /* called by adfWriteBlock() */ 25 | RETCODE (*adfNativeWriteSector)(struct Device*, int32_t, int, uint8_t*); 26 | /* called by adfMount() */ 27 | BOOL (*adfIsDevNative)(char*); 28 | /* called by adfUnMount() */ 29 | RETCODE (*adfReleaseDevice)(struct Device*); 30 | }; 31 | 32 | extern void adfInitNativeFct(); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /dep/adflib/config.h: -------------------------------------------------------------------------------- 1 | /* empty config.h to keep the source happy */ 2 | -------------------------------------------------------------------------------- /dep/adflib/src/adf_link.h: -------------------------------------------------------------------------------- 1 | #ifndef ADF_LINK_H 2 | #define ADF_LINK_H 1 3 | 4 | /* 5 | * ADF Library. (C) 1997-2002 Laurent Clevy 6 | * 7 | * adf_link.h 8 | * 9 | * $Id$ 10 | * 11 | * This file is part of ADFLib. 12 | * 13 | * ADFLib is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License as published by 15 | * the Free Software Foundation; either version 2 of the License, or 16 | * (at your option) any later version. 17 | * 18 | * ADFLib is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with Foobar; if not, write to the Free Software 25 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 26 | * 27 | */ 28 | 29 | #include "prefix.h" 30 | #include 31 | PREFIX RETCODE adfBlockPtr2EntryName(struct Volume* vol, 32 | SECTNUM nSect, 33 | SECTNUM lPar, 34 | char** name, 35 | int32_t* size); 36 | 37 | #endif /* ADF_LINK_H */ 38 | /*##########################################################################*/ 39 | -------------------------------------------------------------------------------- /dep/adflib/src/defendian.h: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | 3 | #ifndef LITT_ENDIAN 4 | #if defined(__hppa__) || defined(__m68k__) || defined(mc68000) || \ 5 | defined(_M_M68K) || (defined(__MIPS__) && defined(__MISPEB__)) || \ 6 | defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \ 7 | defined(__sparc__) 8 | #else 9 | #define LITT_ENDIAN 1 10 | #endif 11 | #endif 12 | -------------------------------------------------------------------------------- /dep/adflib/src/prefix.h: -------------------------------------------------------------------------------- 1 | #ifndef _PREFIX_H 2 | #define _PREFIX_H 1 3 | 4 | /* 5 | * prefix.h 6 | * 7 | * $Id$ 8 | * 9 | * adds symbol export directive under windows 10 | * does nothing under Linux 11 | * 12 | * This file is part of ADFLib. 13 | * 14 | * ADFLib is free software; you can redistribute it and/or modify 15 | * it under the terms of the GNU General Public License as published by 16 | * the Free Software Foundation; either version 2 of the License, or 17 | * (at your option) any later version. 18 | * 19 | * ADFLib is distributed in the hope that it will be useful, 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | * GNU General Public License for more details. 23 | * 24 | * You should have received a copy of the GNU General Public License 25 | * along with Foobar; if not, write to the Free Software 26 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 27 | * 28 | */ 29 | 30 | #ifdef WIN32DLL 31 | #define PREFIX __declspec(dllexport) 32 | #else 33 | #define PREFIX 34 | #endif /* WIN32DLL */ 35 | 36 | #endif /* _PREFIX_H */ 37 | -------------------------------------------------------------------------------- /dep/agg/AUTHORS: -------------------------------------------------------------------------------- 1 | Anti-Grain Geometry - Version 2.4 2 | Copyright (C) 2002-2005 Maxim Shemanarev (McSeem) 3 | -------------------------------------------------------------------------------- /dep/agg/README.md: -------------------------------------------------------------------------------- 1 | This is a vary stripped down copy of the Anti-Grain Antialiasing graphics 2 | rendering library --- I've removed all the platform-specific and control stuff 3 | so that it can be used to generate memory images only. 4 | 5 | The original AGG site is dead, so this version is cloned from 6 | https://github.com/NNemec/antigrain. 7 | 8 | -------------------------------------------------------------------------------- /dep/agg/UPSTREAM.md: -------------------------------------------------------------------------------- 1 | This is a vary stripped down copy of the Anti-Grain Antialiasing graphics 2 | rendering library --- I've removed all the platform-specific and control stuff 3 | so that it can be used to generate memory images only. 4 | 5 | The original AGG site is dead, so this version is cloned from 6 | https://github.com/NNemec/antigrain. 7 | 8 | -------------------------------------------------------------------------------- /dep/agg/include/util/Makefile.am: -------------------------------------------------------------------------------- 1 | myincludedir = $(includedir)/agg2/util 2 | myinclude_HEADERS = agg_color_conv.h agg_color_conv_rgb8.h agg_color_conv_rgb16.h 3 | -------------------------------------------------------------------------------- /dep/agg/src/agg_color_rgba.cpp: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Anti-Grain Geometry - Version 2.4 3 | // Copyright (C) 2009 John Horigan (http://www.antigrain.com) 4 | // 5 | // Permission to copy, use, modify, sell and distribute this software 6 | // is granted provided this copyright notice appears in all copies. 7 | // This software is provided "as is" without express or implied 8 | // warranty, and with no claim as to its suitability for any purpose. 9 | // 10 | //---------------------------------------------------------------------------- 11 | // 12 | // Contact: john@glyphic.com.com 13 | // http://www.antigrain.com 14 | //---------------------------------------------------------------------------- 15 | 16 | // rgbaN construction from grayN types is no longer required, 17 | // as grayN types now define their own conversions to rgbaN. 18 | -------------------------------------------------------------------------------- /dep/emu/UPSTREAM.md: -------------------------------------------------------------------------------- 1 | This contains selected (and slightly tweaked where appropriate) files from 2 | https://github.com/openbsd/src/tree/master/lib/libc/gen. 3 | -------------------------------------------------------------------------------- /dep/emu/build.py: -------------------------------------------------------------------------------- 1 | from build.c import clibrary 2 | 3 | clibrary( 4 | name="emu", 5 | srcs=["./fnmatch.c", "./charclass.h"], 6 | hdrs={"fnmatch.h": "./fnmatch.h"}, 7 | ) 8 | -------------------------------------------------------------------------------- /dep/emu/charclass.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Public domain, 2008, Todd C. Miller 3 | * 4 | * $OpenBSD: charclass.h,v 1.1 2008/10/01 23:04:13 millert Exp $ 5 | */ 6 | 7 | /* 8 | * POSIX character class support for fnmatch() and glob(). 9 | */ 10 | static struct cclass 11 | { 12 | const char* name; 13 | int (*isctype)(int); 14 | } cclasses[] = { 15 | {"alnum", isalnum }, 16 | {"alpha", isalpha }, 17 | {"blank", isblank }, 18 | {"cntrl", iscntrl }, 19 | {"digit", isdigit }, 20 | {"graph", isgraph }, 21 | {"lower", islower }, 22 | {"print", isprint }, 23 | {"punct", ispunct }, 24 | {"space", isspace }, 25 | {"upper", isupper }, 26 | {"xdigit", isxdigit}, 27 | {NULL, NULL } 28 | }; 29 | 30 | #define NCCLASSES (sizeof(cclasses) / sizeof(cclasses[0]) - 1) 31 | -------------------------------------------------------------------------------- /dep/emu/fnmatch.h: -------------------------------------------------------------------------------- 1 | #ifndef FNMATCH_H 2 | #define FNMATCH_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" 6 | { 7 | #endif 8 | 9 | #define FNM_NOMATCH 1 /* Match failed. */ 10 | 11 | #define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */ 12 | #define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */ 13 | #define FNM_PERIOD 0x04 /* Period must be matched by period. */ 14 | #define FNM_CASEFOLD 0x08 /* Fold cases */ 15 | 16 | extern int fnmatch(const char* pattern, const char* string, int flags); 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /dep/fatfs/UPSTREAM.md: -------------------------------------------------------------------------------- 1 | This is fatfs 0.14b from http://elm-chan.org/fsw/ff/00index_e.html (with the 2 | documentation removed). 3 | 4 | It's then been patch by me, dtrg, for... reasons. 5 | 6 | -------------------------------------------------------------------------------- /dep/fatfs/build.py: -------------------------------------------------------------------------------- 1 | from build.c import clibrary 2 | 3 | clibrary( 4 | name="fatfs", 5 | srcs=[ 6 | "./source/ff.c", 7 | "./source/ffsystem.c", 8 | "./source/ffunicode.c", 9 | "./source/ff.h", 10 | "./source/ffconf.h", 11 | "./source/diskio.h", 12 | ], 13 | hdrs={ 14 | "ff.h": "./source/ff.h", 15 | "ffconf.h": "./source/ffconf.h", 16 | "diskio.h": "./source/diskio.h", 17 | }, 18 | cflags=["-Wno-pointer-sign"], 19 | ) 20 | -------------------------------------------------------------------------------- /dep/fatfs/source/00readme.txt: -------------------------------------------------------------------------------- 1 | FatFs Module Source Files R0.14b 2 | 3 | 4 | FILES 5 | 6 | 00readme.txt This file. 7 | 00history.txt Revision history. 8 | ff.c FatFs module. 9 | ffconf.h Configuration file of FatFs module. 10 | ff.h Common include file for FatFs and application module. 11 | diskio.h Common include file for FatFs and disk I/O module. 12 | diskio.c An example of glue function to attach existing disk I/O module to FatFs. 13 | ffunicode.c Optional Unicode utility functions. 14 | ffsystem.c An example of optional O/S related functions. 15 | 16 | 17 | Low level disk I/O module is not included in this archive because the FatFs 18 | module is only a generic file system layer and it does not depend on any specific 19 | storage device. You need to provide a low level disk I/O module written to 20 | control the storage device that attached to the target system. 21 | 22 | -------------------------------------------------------------------------------- /dep/fmt/.clang-format: -------------------------------------------------------------------------------- 1 | # Run manually to reformat a file: 2 | # clang-format -i --style=file 3 | Language: Cpp 4 | BasedOnStyle: Google 5 | IndentPPDirectives: AfterHash 6 | IndentCaseLabels: false 7 | AlwaysBreakTemplateDeclarations: false 8 | DerivePointerAlignment: false 9 | AllowShortCaseLabelsOnASingleLine: true 10 | AlignConsecutiveShortCaseStatements: 11 | Enabled: true 12 | AcrossEmptyLines: true 13 | AcrossComments: true 14 | AlignCaseColons: false -------------------------------------------------------------------------------- /dep/fmt/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing to {fmt} 2 | ===================== 3 | 4 | By submitting a pull request or a patch, you represent that you have the right 5 | to license your contribution to the {fmt} project owners and the community, 6 | agree that your contributions are licensed under the {fmt} license, and agree 7 | to future changes to the licensing. 8 | 9 | All C++ code must adhere to [Google C++ Style Guide]( 10 | https://google.github.io/styleguide/cppguide.html) with the following 11 | exceptions: 12 | 13 | * Exceptions are permitted 14 | * snake_case should be used instead of UpperCamelCase for function and type 15 | names 16 | 17 | All documentation must adhere to the [Google Developer Documentation Style 18 | Guide](https://developers.google.com/style). 19 | 20 | Thanks for contributing! 21 | -------------------------------------------------------------------------------- /dep/fmt/UPSTREAM.md: -------------------------------------------------------------------------------- 1 | This is a pruned version of fmt 11.1.4, obtained from 2 | https://github.com/fmtlib/fmt/releases/tag/11.1.4. -------------------------------------------------------------------------------- /dep/fmt/build.py: -------------------------------------------------------------------------------- 1 | from build.c import cxxlibrary 2 | 3 | cxxlibrary( 4 | name="fmt", 5 | srcs=[ 6 | "./src/format.cc", 7 | "./src/os.cc", 8 | ], 9 | cflags=["-Idep/fmt/include"], 10 | hdrs={ 11 | "fmt/args.h": "./include/fmt/args.h", 12 | "fmt/base.h": "./include/fmt/base.h", 13 | "fmt/chrono.h": "./include/fmt/chrono.h", 14 | "fmt/color.h": "./include/fmt/color.h", 15 | "fmt/compile.h": "./include/fmt/compile.h", 16 | "fmt/core.h": "./include/fmt/core.h", 17 | "fmt/format.h": "./include/fmt/format.h", 18 | "fmt/format-inl.h": "./include/fmt/format-inl.h", 19 | "fmt/os.h": "./include/fmt/os.h", 20 | "fmt/ostream.h": "./include/fmt/ostream.h", 21 | "fmt/printf.h": "./include/fmt/printf.h", 22 | "fmt/ranges.h": "./include/fmt/ranges.h", 23 | "fmt/std.h": "./include/fmt/std.h", 24 | "fmt/xchar.h": "./include/fmt/xchar.h", 25 | }, 26 | ) 27 | -------------------------------------------------------------------------------- /dep/fmt/include/fmt/core.h: -------------------------------------------------------------------------------- 1 | // This file is only provided for compatibility and may be removed in future 2 | // versions. Use fmt/base.h if you don't need fmt::format and fmt/format.h 3 | // otherwise. 4 | 5 | #include "format.h" 6 | -------------------------------------------------------------------------------- /dep/hfsutils/COPYRIGHT: -------------------------------------------------------------------------------- 1 | 2 | hfsutils - tools for reading and writing Macintosh HFS volumes 3 | Copyright (C) 1996-1998 Robert Leslie 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | 19 | If you would like to negotiate alternate licensing terms, you may do 20 | so by contacting the author: Robert Leslie 21 | 22 | -------------------------------------------------------------------------------- /dep/hfsutils/UPSTREAM.md: -------------------------------------------------------------------------------- 1 | This is a very heavily pruned copy of hfsutils, as I only need libhfs from it, 2 | taken from https://www.mars.org/home/rob/proj/hfs/. This is version 3.2.6. 3 | -------------------------------------------------------------------------------- /dep/hfsutils/build.py: -------------------------------------------------------------------------------- 1 | from build.c import clibrary 2 | 3 | clibrary( 4 | name="hfsutils", 5 | srcs=[ 6 | "./libhfs/block.c", 7 | "./libhfs/block.h", 8 | "./libhfs/btree.c", 9 | "./libhfs/btree.h", 10 | "./libhfs/data.c", 11 | "./libhfs/data.h", 12 | "./libhfs/file.c", 13 | "./libhfs/file.h", 14 | "./libhfs/hfs.c", 15 | "./libhfs/hfs.h", 16 | "./libhfs/low.c", 17 | "./libhfs/low.h", 18 | "./libhfs/medium.c", 19 | "./libhfs/medium.h", 20 | "./libhfs/memcmp.c", 21 | "./libhfs/node.c", 22 | "./libhfs/node.h", 23 | "./libhfs/record.c", 24 | "./libhfs/record.h", 25 | "./libhfs/version.c", 26 | "./libhfs/version.h", 27 | "./libhfs/volume.c", 28 | "./libhfs/volume.h", 29 | ], 30 | hdrs={ 31 | "apple.h": "./libhfs/apple.h", 32 | "hfs.h": "./libhfs/hfs.h", 33 | "libhfs.h": "./libhfs/libhfs.h", 34 | "os.h": "./libhfs/os.h", 35 | }, 36 | cflags=["-Wno-pointer-sign"], 37 | ) 38 | -------------------------------------------------------------------------------- /dep/hfsutils/libhfs/btree.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libhfs - library for reading and writing Macintosh HFS volumes 3 | * Copyright (C) 1996-1998 Robert Leslie 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | * 19 | * $Id: btree.h,v 1.8 1998/11/02 22:08:55 rob Exp $ 20 | */ 21 | 22 | int bt_getnode(node*, btree*, unsigned long); 23 | int bt_putnode(node*); 24 | 25 | int bt_readhdr(btree*); 26 | int bt_writehdr(btree*); 27 | 28 | int bt_space(btree*, unsigned int); 29 | 30 | int bt_insert(btree*, const byte*, unsigned int); 31 | int bt_delete(btree*, const byte*); 32 | 33 | int bt_search(btree*, const byte*, node*); 34 | -------------------------------------------------------------------------------- /dep/hfsutils/libhfs/node.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libhfs - library for reading and writing Macintosh HFS volumes 3 | * Copyright (C) 1996-1998 Robert Leslie 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | * 19 | * $Id: node.h,v 1.7 1998/11/02 22:09:06 rob Exp $ 20 | */ 21 | 22 | void n_init(node*, btree*, int, int); 23 | 24 | int n_new(node*); 25 | int n_free(node*); 26 | 27 | int n_search(node*, const byte*); 28 | 29 | void n_index(const node*, byte*, unsigned int*); 30 | 31 | void n_insertx(node*, const byte*, unsigned int); 32 | int n_insert(node*, byte*, unsigned int*); 33 | 34 | int n_delete(node*, byte*, int*); 35 | -------------------------------------------------------------------------------- /dep/hfsutils/libhfs/os.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libhfs - library for reading and writing Macintosh HFS volumes 3 | * Copyright (C) 1996-1998 Robert Leslie 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | * 19 | * $Id: os.h,v 1.6 1998/09/15 19:21:05 rob Exp $ 20 | */ 21 | 22 | int os_open(void**, const char*, int); 23 | int os_close(void**); 24 | 25 | int os_same(void**, const char*); 26 | 27 | unsigned long os_seek(void**, unsigned long); 28 | unsigned long os_read(void**, void*, unsigned long); 29 | unsigned long os_write(void**, const void*, unsigned long); 30 | -------------------------------------------------------------------------------- /dep/hfsutils/libhfs/version.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libhfs - library for reading and writing Macintosh HFS volumes 3 | * Copyright (C) 1996-1998 Robert Leslie 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | * 19 | * $Id: version.c,v 1.11 1998/11/02 22:09:09 rob Exp $ 20 | */ 21 | 22 | # include "version.h" 23 | 24 | const char libhfs_rcsid[] = 25 | "$Id: version.c,v 1.11 1998/11/02 22:09:09 rob Exp $"; 26 | 27 | const char libhfs_version[] = "libhfs version 3.2.6"; 28 | const char libhfs_copyright[] = "Copyright (C) 1996-1998 Robert Leslie"; 29 | const char libhfs_author[] = "Robert Leslie "; 30 | -------------------------------------------------------------------------------- /dep/hfsutils/libhfs/version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libhfs - library for reading and writing Macintosh HFS volumes 3 | * Copyright (C) 1996-1998 Robert Leslie 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | * 19 | * $Id: version.h,v 1.6 1998/09/18 22:56:38 rob Exp $ 20 | */ 21 | 22 | extern const char libhfs_rcsid[]; 23 | 24 | extern const char libhfs_version[]; 25 | extern const char libhfs_copyright[]; 26 | extern const char libhfs_author[]; 27 | -------------------------------------------------------------------------------- /dep/libusbp/.dir-locals.el: -------------------------------------------------------------------------------- 1 | ( 2 | (c-default-style . "BSD") 3 | (c-mode . ((c-basic-offset . 4) (tab-width . 4) (indent-tabs-mode . nil))) 4 | (nil . ((fill-column . 80))) 5 | ) 6 | -------------------------------------------------------------------------------- /dep/libusbp/Doxyfile: -------------------------------------------------------------------------------- 1 | # Doxygen configuration file for generating documentation. 2 | PROJECT_NAME = "libusbp" 3 | OUTPUT_DIRECTORY = docs 4 | INLINE_INHERITED_MEMB = YES 5 | INPUT = README.md PLATFORM_NOTES.md CONTRIBUTING.md THREADS.md include 6 | USE_MDFILE_AS_MAINPAGE = README.md 7 | RECURSIVE = YES 8 | SOURCE_BROWSER = YES 9 | USE_MATHJAX = YES 10 | GENERATE_LATEX = NO 11 | # TYPEDEF_HIDES_STRUCT = YES 12 | 13 | MACRO_EXPANSION = YES 14 | EXPAND_ONLY_PREDEF = YES 15 | PREDEFINED = \ 16 | LIBUSBP_API= \ 17 | LIBUSBP_WARN_UNUSED= \ 18 | _WIN32=1 \ 19 | __linux__=1 \ 20 | __APPLE__=1 21 | 22 | EXCLUDE_SYMBOLS = \ 23 | LIBUSBP_API \ 24 | LIBUSBP_DLL_EXPORT \ 25 | LIBUSBP_DLL_IMPORT \ 26 | LIBUSBP_WARN_UNUSED -------------------------------------------------------------------------------- /dep/libusbp/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015-2017 Pololu Corporation. For more information, see 2 | 3 | http://www.pololu.com/ 4 | http://forum.pololu.com/ 5 | 6 | Permission is hereby granted, free of charge, to any person 7 | obtaining a copy of this software and associated documentation 8 | files (the "Software"), to deal in the Software without 9 | restriction, including without limitation the rights to use, 10 | copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following 13 | conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | OTHER DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /dep/libusbp/UPSTREAM.md: -------------------------------------------------------------------------------- 1 | This is version 1.3.0 taken from https://github.com/pololu/libusbp on 2 | 2023-05-06. 3 | 4 | -------------------------------------------------------------------------------- /dep/libusbp/examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(async_in) 2 | add_subdirectory(lsport) 3 | add_subdirectory(lsusb) 4 | add_subdirectory(port_name) 5 | -------------------------------------------------------------------------------- /dep/libusbp/examples/async_in/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(async_in async_in.cpp) 2 | 3 | include_directories ( 4 | "${CMAKE_SOURCE_DIR}/include" 5 | ) 6 | 7 | target_link_libraries(async_in usbp) -------------------------------------------------------------------------------- /dep/libusbp/examples/drop_in/.gitignore: -------------------------------------------------------------------------------- 1 | /libusbp* 2 | /lsusb* 3 | -------------------------------------------------------------------------------- /dep/libusbp/examples/drop_in/build.sh: -------------------------------------------------------------------------------- 1 | # This script converts libusbp into a format that can easily be dropped into 2 | # other projects: one source file, one C header file, and one C++ header file. 3 | # 4 | # This is handy for people who want to use libusbp in their own C/C++ software 5 | # projects but don't want to deal with the issues that come with having one more 6 | # dependency. 7 | # 8 | # It also compiles the lsusb example program using the drop-in library. 9 | 10 | set -eou pipefail 11 | 12 | cd `dirname $0` 13 | SRC=../../src 14 | 15 | { 16 | echo "#if 0" 17 | cat $SRC/../LICENSE.txt 18 | echo "#endif" 19 | cat $SRC/libusbp_internal.h 20 | cat $SRC/*.c 21 | echo "#ifdef _WIN32" 22 | cat $SRC/windows/*.c 23 | echo "#endif" 24 | echo "#ifdef __linux__" 25 | cat $SRC/linux/*.c 26 | echo "#endif" 27 | echo "#ifdef __APPLE__" 28 | cat $SRC/mac/*.c 29 | echo "#endif" 30 | } | sed 's/#include //' > libusbp.c 31 | 32 | cp ../lsusb/lsusb.cpp $SRC/../include/libusbp.h* . 33 | 34 | # TODO: fix the library so we don't need -fpermissive here 35 | 36 | g++ -std=gnu++11 -Wall -fpermissive -g -O2 -I. \ 37 | -DLIBUSBP_DROP_IN -DLIBUSBP_STATIC \ 38 | lsusb.cpp libusbp.c -ludev -o lsusb 39 | -------------------------------------------------------------------------------- /dep/libusbp/examples/lsport/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(lsport lsport.cpp) 2 | 3 | include_directories ( 4 | "${CMAKE_SOURCE_DIR}/include" 5 | ) 6 | 7 | target_link_libraries(lsport usbp) 8 | -------------------------------------------------------------------------------- /dep/libusbp/examples/lsusb/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(lsusb lsusb.cpp) 2 | 3 | include_directories ( 4 | "${CMAKE_SOURCE_DIR}/include" 5 | ) 6 | 7 | target_link_libraries(lsusb usbp) -------------------------------------------------------------------------------- /dep/libusbp/examples/port_name/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(port_name port_name.cpp) 2 | 3 | include_directories ( 4 | "${CMAKE_SOURCE_DIR}/include" 5 | ) 6 | 7 | target_link_libraries(port_name usbp) 8 | -------------------------------------------------------------------------------- /dep/libusbp/examples/port_name/port_name.cpp: -------------------------------------------------------------------------------- 1 | // This example shows how to get the name of a USB serial port (e.g. "COM6") 2 | // for a single USB device. 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | const uint16_t vendor_id = 0x1FFB; 9 | const uint16_t product_id = 0xDA01; 10 | const uint8_t interface_number = 2; 11 | const bool composite = true; 12 | 13 | int main_with_exceptions() 14 | { 15 | libusbp::device device = libusbp::find_device_with_vid_pid(vendor_id, product_id); 16 | if (!device) 17 | { 18 | std::cerr << "Device not found." << std::endl; 19 | return 1; 20 | } 21 | 22 | libusbp::serial_port port(device, interface_number, composite); 23 | std::string port_name = port.get_name(); 24 | std::cout << port_name << std::endl; 25 | 26 | return 0; 27 | } 28 | 29 | int main(int argc, char ** argv) 30 | { 31 | // Suppress unused parameter warnings. 32 | (void)argc; 33 | (void)argv; 34 | 35 | try 36 | { 37 | return main_with_exceptions(); 38 | } 39 | catch(const std::exception & error) 40 | { 41 | std::cerr << "Error: " << error.what() << std::endl; 42 | } 43 | return 1; 44 | } 45 | -------------------------------------------------------------------------------- /dep/libusbp/include/libusbp_config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define BUILD_SYSTEM_LIBUSBP_VERSION_MAJOR 1 4 | #define LIBUSBP_STATIC 5 | #undef LIBUSBP_LOG 6 | #undef VBOX_LINUX_ON_WINDOWS 7 | #undef USE_TEST_DEVICE_A 8 | #undef USE_TEST_DEVICE_B 9 | -------------------------------------------------------------------------------- /dep/libusbp/install_helper/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library (install_helper SHARED install_helper_windows.c dll.def) 2 | 3 | target_link_libraries (install_helper setupapi msi) 4 | 5 | set_target_properties (install_helper PROPERTIES 6 | OUTPUT_NAME usbp-install-helper-${LIBUSBP_VERSION_MAJOR} 7 | LINK_FLAGS "-Wl,--enable-stdcall-fixup -static" 8 | ) 9 | 10 | install (TARGETS install_helper 11 | RUNTIME DESTINATION bin 12 | LIBRARY DESTINATION lib 13 | ARCHIVE DESTINATION lib) 14 | -------------------------------------------------------------------------------- /dep/libusbp/install_helper/README.md: -------------------------------------------------------------------------------- 1 | The files in this directory compile a separate, statically linked DLL named 2 | `libusbp-install-helper-.dll` that can be useful in installers of USB 3 | software. -------------------------------------------------------------------------------- /dep/libusbp/install_helper/dll.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | libusbp_install_inf 3 | libusbp_install_infW 4 | libusbp_broadcast_setting_change 5 | libusbp_broadcast_setting_changeW 6 | -------------------------------------------------------------------------------- /dep/libusbp/manual_tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(test_async_in) 2 | add_subdirectory(test_long_read) 3 | add_subdirectory(test_long_write) 4 | add_subdirectory(test_transitions) 5 | -------------------------------------------------------------------------------- /dep/libusbp/manual_tests/test_async_in/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(test_async_in test_async_in.cpp) 2 | 3 | include_directories ( 4 | "${CMAKE_SOURCE_DIR}/include" 5 | ) 6 | 7 | target_link_libraries(test_async_in usbp) 8 | -------------------------------------------------------------------------------- /dep/libusbp/manual_tests/test_long_read/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(test_long_read test_long_read.cpp) 2 | 3 | include_directories ( 4 | "${CMAKE_SOURCE_DIR}/include" 5 | ) 6 | 7 | target_link_libraries(test_long_read usbp) 8 | -------------------------------------------------------------------------------- /dep/libusbp/manual_tests/test_long_write/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(test_long_write test_long_write.cpp) 2 | 3 | include_directories ( 4 | "${CMAKE_SOURCE_DIR}/include" 5 | ) 6 | 7 | target_link_libraries(test_long_write usbp) 8 | -------------------------------------------------------------------------------- /dep/libusbp/manual_tests/test_transitions/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(test_transitions test_transitions.cpp) 2 | 3 | include_directories ( 4 | "${CMAKE_SOURCE_DIR}/include" 5 | ) 6 | 7 | target_link_libraries(test_transitions usbp) -------------------------------------------------------------------------------- /dep/libusbp/src/error_hresult.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #if defined(_WIN32) || defined(__APPLE__) 4 | 5 | libusbp_error * error_create_hr(HRESULT hr, const char * format, ...) 6 | { 7 | // HRESULT should be an int32_t on the systems we care about (Mac OS X, 8 | // Win32, Win64), but let's assert it here in case that ever changes. 9 | assert(sizeof(HRESULT) == 4); 10 | assert((HRESULT)-1 < (HRESULT)0); 11 | 12 | libusbp_error * error = error_create("HRESULT error code 0x%x.", (int32_t)hr); 13 | 14 | va_list ap; 15 | va_start(ap, format); 16 | error = error_add_v(error, format, ap); 17 | va_end(ap); 18 | return error; 19 | } 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /dep/libusbp/src/info.rc.in: -------------------------------------------------------------------------------- 1 | #define VERSION ${LIBUSBP_VERSION_MAJOR},${LIBUSBP_VERSION_MINOR},${LIBUSBP_VERSION_PATCH},0 2 | #define VERSION_STR "${LIBUSBP_VERSION_MAJOR}.${LIBUSBP_VERSION_MINOR}.${LIBUSBP_VERSION_PATCH}" 3 | 4 | #include 5 | VS_VERSION_INFO VERSIONINFO 6 | FILEVERSION VERSION 7 | PRODUCTVERSION VERSION 8 | FILEOS VOS_NT_WINDOWS32 9 | FILETYPE VFT_DLL 10 | BEGIN 11 | BLOCK "StringFileInfo" 12 | BEGIN 13 | BLOCK "040904E4" 14 | BEGIN 15 | VALUE "CompanyName", "Pololu Corporation" 16 | VALUE "FileDescription", "Pololu USB Library" 17 | VALUE "FileVersion", VERSION_STR 18 | VALUE "ProductName", "Pololu USB Library (${CMAKE_BUILD_TYPE})" 19 | VALUE "ProductVersion", VERSION_STR 20 | VALUE "LegalCopyright", "Copyright (C) ${YEAR} Pololu Corporation" 21 | END 22 | END 23 | 24 | BLOCK "VarFileInfo" 25 | BEGIN 26 | VALUE "Translation", 0x409, 1252 27 | END 28 | END 29 | -------------------------------------------------------------------------------- /dep/libusbp/src/libusbp.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | libdir=${prefix}/lib 3 | includedir=${prefix}/include 4 | 5 | Name: libusbp 6 | Version: @LIBUSBP_VERSION@ 7 | Description: Library for accessing USB devices. 8 | Requires: @PC_REQUIRES@ 9 | Libs: -L${libdir} -lusbp-@LIBUSBP_VERSION_MAJOR@ @PC_MORE_LIBS@ 10 | Cflags: -I${includedir}/libusbp-@LIBUSBP_VERSION_MAJOR@ @PC_MORE_CFLAGS@ 11 | -------------------------------------------------------------------------------- /dep/libusbp/src/libusbp_config.h.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define BUILD_SYSTEM_LIBUSBP_VERSION_MAJOR @LIBUSBP_VERSION_MAJOR@ 4 | 5 | #cmakedefine LIBUSBP_LOG 6 | 7 | #cmakedefine VBOX_LINUX_ON_WINDOWS 8 | 9 | #cmakedefine USE_TEST_DEVICE_A 10 | 11 | #cmakedefine USE_TEST_DEVICE_B 12 | -------------------------------------------------------------------------------- /dep/libusbp/src/pipe_id.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | static libusbp_error * error_invalid_pipe_id(uint8_t pipe_id) 4 | { 5 | return error_create("Invalid pipe ID 0x%02x.", pipe_id); 6 | } 7 | 8 | libusbp_error * check_pipe_id(uint8_t pipe_id) 9 | { 10 | if ((pipe_id & ~0x80) > MAX_ENDPOINT_NUMBER || pipe_id == 0x80) 11 | { 12 | return error_invalid_pipe_id(pipe_id); 13 | } 14 | return NULL; 15 | } 16 | 17 | libusbp_error * check_pipe_id_in(uint8_t pipe_id) 18 | { 19 | if (!(pipe_id & 0x80)) 20 | { 21 | return error_invalid_pipe_id(pipe_id); 22 | } 23 | return check_pipe_id(pipe_id); 24 | } 25 | 26 | libusbp_error * check_pipe_id_out(uint8_t pipe_id) 27 | { 28 | if (pipe_id & 0x80) 29 | { 30 | return error_invalid_pipe_id(pipe_id); 31 | } 32 | return check_pipe_id(pipe_id); 33 | } 34 | -------------------------------------------------------------------------------- /dep/libusbp/src/string.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // Simple wrapper around strdup to make a copy of a string, either for internal 4 | // use or for returning the string to the user. 5 | libusbp_error * string_copy(const char * input_string, char ** output_string) 6 | { 7 | assert(input_string != NULL); 8 | assert(output_string != NULL); 9 | 10 | *output_string = NULL; 11 | 12 | char * new_string = strdup(input_string); 13 | if (new_string == NULL) 14 | { 15 | return &error_no_memory; 16 | } 17 | 18 | *output_string = new_string; 19 | return NULL; 20 | } 21 | 22 | void libusbp_string_free(char * string) 23 | { 24 | free(string); 25 | } 26 | -------------------------------------------------------------------------------- /dep/libusbp/src/windows/device_instance_id_windows.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | libusbp_error * create_id_string(HDEVINFO list, PSP_DEVINFO_DATA info, char ** id) 4 | { 5 | assert(list != INVALID_HANDLE_VALUE); 6 | assert(info != NULL); 7 | assert(id != NULL); 8 | 9 | DWORD size = MAX_DEVICE_ID_LEN + 1; 10 | char * new_id = malloc(size); 11 | if (new_id == NULL) 12 | { 13 | return &error_no_memory; 14 | } 15 | 16 | bool success = SetupDiGetDeviceInstanceId(list, info, new_id, size, NULL); 17 | if (!success) 18 | { 19 | free(new_id); 20 | return error_create_winapi("Error getting device instance ID."); 21 | } 22 | 23 | *id = new_id; 24 | return NULL; 25 | } 26 | -------------------------------------------------------------------------------- /dep/libusbp/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | INCLUDE (CheckIncludeFileCXX) 2 | 3 | # If catch.hpp is not present, we want to simply skip compiling the tests. 4 | # Download catch.hpp and put it in this directory: 5 | # https://raw.githubusercontent.com/catchorg/Catch2/v2.x/single_include/catch2/catch.hpp 6 | set (CMAKE_REQUIRED_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}") 7 | CHECK_INCLUDE_FILE_CXX (catch.hpp HAVE_CATCH_FRAMEWORK) 8 | if (NOT HAVE_CATCH_FRAMEWORK) 9 | message (STATUS "The test suite will not be built.") 10 | return () 11 | endif () 12 | 13 | set(USE_TEST_DEVICE_A FALSE CACHE BOOL 14 | "Run tests that require Test Device A.") 15 | 16 | set(USE_TEST_DEVICE_B FALSE CACHE BOOL 17 | "Run tests that require Test Device B.") 18 | 19 | file(GLOB test_sources *.cpp) 20 | 21 | if (APPLE) 22 | set (link_flags "-framework CoreFoundation ${link_flags}") 23 | endif () 24 | 25 | add_executable(run_test ${test_sources}) 26 | 27 | set_target_properties(run_test PROPERTIES 28 | LINK_FLAGS "${link_flags}" 29 | ) 30 | 31 | include_directories ( 32 | "${CMAKE_CURRENT_SOURCE_DIR}" 33 | "${CMAKE_SOURCE_DIR}/include" 34 | "${CMAKE_SOURCE_DIR}/src" 35 | "${CMAKE_BINARY_DIR}/src" 36 | ) 37 | 38 | target_link_libraries(run_test usbp) 39 | -------------------------------------------------------------------------------- /dep/libusbp/test/drivers/pololu.cat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/dep/libusbp/test/drivers/pololu.cat -------------------------------------------------------------------------------- /dep/libusbp/test/firmware/wixel/.gitignore: -------------------------------------------------------------------------------- 1 | /wixel-sdk 2 | *.hex 3 | *.ihx 4 | *.rel 5 | *.d 6 | *.sym 7 | *.cdb 8 | *.mem 9 | *.rst 10 | *.map 11 | *.lst 12 | *.lk 13 | *.asm 14 | *.omf 15 | *.adb 16 | *.cdb -------------------------------------------------------------------------------- /dep/libusbp/test/firmware/wixel/prepare_sdk.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | git clone git@github.com:pololu/wixel-sdk 3 | cd wixel-sdk 4 | make libs 5 | -------------------------------------------------------------------------------- /dep/libusbp/test/main_test.cpp: -------------------------------------------------------------------------------- 1 | #define CATCH_CONFIG_RUNNER 2 | #include 3 | 4 | int main (int argc, char ** argv) 5 | { 6 | #ifndef USE_TEST_DEVICE_A 7 | std::cerr << "Warning: Tests involving Test Device A will be skipped," << std::endl; 8 | std::cerr << " so a lot of the library's features will not be tested." << std::endl; 9 | #endif 10 | 11 | #ifndef USE_TEST_DEVICE_B 12 | std::cerr << "Warning: Tests involving Test Device B will be skipped," << std::endl; 13 | std::cerr << " so bugs related to non-composite devices might be missed." << std::endl; 14 | #endif 15 | 16 | #ifdef NDEBUG 17 | std::cerr << "Warning: skipping unit tests because this is not a debug build.\n"; 18 | #endif 19 | 20 | // If the last argument is "-p", then pause after the tests are run. 21 | // This allows us to run "leaks" on Mac OS X to check for memory leaks. 22 | bool pause_after_test = false; 23 | if (argc && std::string(argv[argc - 1]) == "-p") 24 | { 25 | pause_after_test = true; 26 | argc--; 27 | } 28 | 29 | int result = Catch::Session().run(argc, argv); 30 | 31 | if (pause_after_test) 32 | { 33 | printf("Press enter to continue."); 34 | std::string s; 35 | std::cin >> s; 36 | } 37 | 38 | return result; 39 | } 40 | -------------------------------------------------------------------------------- /dep/libusbp/test/test_helper.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | libusbp::device find_by_vendor_id_product_id(uint16_t vendor_id, uint16_t product_id) 4 | { 5 | std::vector list = libusbp::list_connected_devices(); 6 | for (auto it = list.begin(); it != list.end(); ++it) 7 | { 8 | libusbp::device device = *it; 9 | if (device.get_vendor_id() == vendor_id && device.get_product_id() == product_id) 10 | { 11 | return device; 12 | } 13 | } 14 | throw "Device not found."; 15 | } 16 | 17 | libusbp::device find_test_device_a() 18 | { 19 | return find_by_vendor_id_product_id(0x1FFB, 0xDA01); 20 | } 21 | 22 | libusbp::device find_test_device_b() 23 | { 24 | return find_by_vendor_id_product_id(0x1FFB, 0xDA02); 25 | } 26 | -------------------------------------------------------------------------------- /dep/libusbp/test/usbfd_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #if defined(__linux__) && !defined(NDEBUG) 4 | 5 | TEST_CASE("usbfd_check_existence") 6 | { 7 | SECTION("gives a nice error if the file does not exist") 8 | { 9 | libusbp::error error(usbfd_check_existence("doesnt-exist-%%%")); 10 | REQUIRE(error.has_code(LIBUSBP_ERROR_NOT_READY)); 11 | } 12 | 13 | SECTION("gives a nice error if part of the file path does not exist") 14 | { 15 | libusbp::error error(usbfd_check_existence("doesnt-exist-%%%/xx")); 16 | REQUIRE(error.has_code(LIBUSBP_ERROR_NOT_READY)); 17 | } 18 | } 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /dep/libusbp/test/windows_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef _WIN32 4 | 5 | TEST_CASE("CM_Locate_DevNode", "[cmld]") 6 | { 7 | CONFIGRET cr; 8 | DEVINST dev_inst; 9 | 10 | SECTION("totally invalid id") 11 | { 12 | char id[] = "totally invalid"; 13 | cr = CM_Locate_DevNode(&dev_inst, id, CM_LOCATE_DEVNODE_NORMAL); 14 | REQUIRE(cr == CR_INVALID_DEVICE_ID); 15 | } 16 | 17 | SECTION("non-existent ID") 18 | { 19 | char id[] = "USB\\VID_1FFB&PID_0001\\01eeca1"; 20 | cr = CM_Locate_DevNode(&dev_inst, id, CM_LOCATE_DEVNODE_NORMAL); 21 | REQUIRE(cr == CR_NO_SUCH_DEVNODE); 22 | } 23 | 24 | SECTION("unplugged USB device") 25 | { 26 | // To make this test do something, set the id below to the 27 | // device instance ID of a USB device that is currently 28 | // unplugged from your computer, but was plugged in at one 29 | // point. Also, uncomment the early return. 30 | 31 | char id[] = "USB\\VID_1FFB&PID_0100\\6E-D7-65-51"; 32 | return; 33 | 34 | cr = CM_Locate_DevNode(&dev_inst, id, CM_LOCATE_DEVNODE_NORMAL); 35 | CHECK(cr == CR_NO_SUCH_DEVNODE); 36 | cr = CM_Locate_DevNode(&dev_inst, id, CM_LOCATE_DEVNODE_PHANTOM); 37 | CHECK(cr == CR_SUCCESS); 38 | } 39 | } 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /dep/snowhouse/UPSTREAM.md: -------------------------------------------------------------------------------- 1 | This comes from https://github.com/banditcpp/snowhouse, version 5.0.0. 2 | -------------------------------------------------------------------------------- /dep/snowhouse/example/boolean_operators.cpp: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | 3 | using namespace snowhouse; 4 | 5 | void BooleanOperators() 6 | { 7 | describe("Boolean operators"); 8 | 9 | it("handles IsFalse()"); 10 | { 11 | AssertThat(false, IsFalse()); 12 | } 13 | 14 | it("handles failing IsFalse()"); 15 | { 16 | AssertTestFails(AssertThat(true, IsFalse()), "Expected: false"); 17 | } 18 | 19 | it("handles IsTrue()"); 20 | { 21 | AssertThat(true, IsTrue()); 22 | } 23 | 24 | it("handles failing IsTrue()"); 25 | { 26 | AssertTestFails(AssertThat(false, IsTrue()), "Expected: true"); 27 | } 28 | 29 | it("handles Is().True()"); 30 | { 31 | AssertThat(true, Is().True()); 32 | AssertTestFails(AssertThat(false, Is().True()), "Expected: true"); 33 | } 34 | 35 | it("handles Is().False()"); 36 | { 37 | AssertThat(false, Is().False()); 38 | AssertTestFails(AssertThat(true, Is().False()), "Expected: false"); 39 | } 40 | 41 | it("treats assert without constraint as boolean constrains"); 42 | { 43 | Assert::That(true); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /dep/snowhouse/example/expression_error_handling.cpp: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | 3 | using namespace snowhouse; 4 | 5 | void ExpressionErrorHandling() 6 | { 7 | describe("Expression error handling"); 8 | 9 | std::vector collection; 10 | collection.push_back(1); 11 | collection.push_back(2); 12 | collection.push_back(3); 13 | 14 | it("reports an invalid All() properly"); 15 | { 16 | AssertTestFails(AssertThat(collection, Has().All()), 17 | "The expression after \"all\" operator does not yield any result"); 18 | } 19 | 20 | it("reports an invalid AtLeast() properly"); 21 | { 22 | AssertTestFails(AssertThat(collection, Has().AtLeast(2)), 23 | "The expression after \"at least 2\" operator does not yield any result"); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /dep/snowhouse/example/main.cpp: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | 3 | using namespace snowhouse; 4 | 5 | void BooleanOperators(); 6 | void BasicAssertions(); 7 | void ContainerConstraints(); 8 | void CustomMatchers(); 9 | void ExceptionTests(); 10 | void ExpressionErrorHandling(); 11 | void MapTests(); 12 | void OperatorTests(); 13 | void SequenceContainerTests(); 14 | void StringLineTests(); 15 | void StringTests(); 16 | void StringizeTests(); 17 | 18 | int main() 19 | { 20 | std::cout << "Spec for Snowhouse " SNOWHOUSE_VERSION << std::endl; 21 | 22 | try 23 | { 24 | BasicAssertions(); 25 | BooleanOperators(); 26 | ContainerConstraints(); 27 | CustomMatchers(); 28 | ExceptionTests(); 29 | ExpressionErrorHandling(); 30 | MapTests(); 31 | OperatorTests(); 32 | SequenceContainerTests(); 33 | StringLineTests(); 34 | StringTests(); 35 | StringizeTests(); 36 | } 37 | catch (const AssertionException& e) 38 | { 39 | std::cout << "Tests failed!" << std::endl; 40 | std::cout << e.what() << std::endl; 41 | return 1; 42 | } 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /dep/snowhouse/example/map_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | 3 | using namespace snowhouse; 4 | 5 | void MapTests() 6 | { 7 | describe("Containing (std::map)"); 8 | 9 | std::map ages; 10 | ages["joakim"] = 38; 11 | ages["maria"] = 36; 12 | ages["hanna"] = 6; 13 | ages["moa"] = 4; 14 | 15 | it("determines if key exists"); 16 | { 17 | AssertThat(ages, Is().Containing("joakim")); 18 | } 19 | 20 | it("gives a proper message when fails"); 21 | { 22 | AssertTestFails(AssertThat(ages, Is().Not().Containing("hanna")), 23 | "Expected: not contains \"hanna\""); 24 | } 25 | 26 | it("determines if key exists"); 27 | { 28 | AssertThat(ages, Contains("joakim")); 29 | } 30 | 31 | it("gives a proper message when Contains() fails"); 32 | { 33 | AssertTestFails(AssertThat(ages, !Contains("hanna")), 34 | "Expected: not contains \"hanna\""); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /dep/snowhouse/example/tests.h: -------------------------------------------------------------------------------- 1 | #ifndef SNOWHOUSE_EXAMPLES_TEST_H 2 | #define SNOWHOUSE_EXAMPLES_TEST_H 3 | 4 | #include 5 | 6 | // clang-format off 7 | #define AssertTestFails(assertion, expected_error_text) \ 8 | std::string SNOWHOUSE_INTERNAL_expected_error = "Test did not fail"; \ 9 | try \ 10 | { \ 11 | assertion; \ 12 | } \ 13 | catch (const AssertionException& exception_from_snowhouse_assertion) \ 14 | { \ 15 | SNOWHOUSE_INTERNAL_expected_error = exception_from_snowhouse_assertion.what(); \ 16 | } \ 17 | AssertThat(SNOWHOUSE_INTERNAL_expected_error, Is().Containing(expected_error_text)); 18 | // clang-format on 19 | 20 | inline void describe(const char* title) 21 | { 22 | std::cout << std::endl << title << ":" << std::endl; 23 | } 24 | 25 | inline void it(const char* title) 26 | { 27 | std::cout << " - " << title << std::endl; 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /dep/snowhouse/include/snowhouse/assertionexception.h: -------------------------------------------------------------------------------- 1 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 2 | // Distributed under the Boost Software License, Version 1.0. 3 | // (See accompanying file LICENSE_1_0.txt or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | #ifndef SNOWHOUSE_ASSERTIONEXCEPTION_H 7 | #define SNOWHOUSE_ASSERTIONEXCEPTION_H 8 | 9 | #include 10 | #include 11 | 12 | #include "macros.h" 13 | 14 | namespace snowhouse 15 | { 16 | struct AssertionException : public std::runtime_error 17 | { 18 | explicit AssertionException(const std::string& message, 19 | const std::string& filename, 20 | unsigned int line_number): 21 | std::runtime_error(message), 22 | m_file(filename), 23 | m_line(line_number) 24 | { 25 | } 26 | 27 | explicit AssertionException(const std::string& message): 28 | AssertionException(message, "", 0) 29 | { 30 | } 31 | 32 | std::string file() const 33 | { 34 | return m_file; 35 | } 36 | 37 | unsigned int line() const 38 | { 39 | return m_line; 40 | } 41 | 42 | private: 43 | std::string m_file; 44 | unsigned int m_line; 45 | }; 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /dep/snowhouse/include/snowhouse/constraints/constraints.h: -------------------------------------------------------------------------------- 1 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 2 | // Distributed under the Boost Software License, Version 1.0. 3 | // (See accompanying file LICENSE_1_0.txt or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | #ifndef SNOWHOUSE_CONSTRAINTS_H 7 | #define SNOWHOUSE_CONSTRAINTS_H 8 | 9 | #include "containsconstraint.h" 10 | #include "endswithconstraint.h" 11 | #include "equalsconstraint.h" 12 | #include "haslengthconstraint.h" 13 | #include "isemptyconstraint.h" 14 | #include "isgreaterthanconstraint.h" 15 | #include "isgreaterthanorequaltoconstraint.h" 16 | #include "islessthanconstraint.h" 17 | #include "islessthanorequaltoconstraint.h" 18 | #include "startswithconstraint.h" 19 | #include "fulfillsconstraint.h" 20 | #include "equalswithdeltaconstraint.h" 21 | #include "equalscontainerconstraint.h" 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /dep/snowhouse/include/snowhouse/constraints/expressions/expression.h: -------------------------------------------------------------------------------- 1 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 2 | // Distributed under the Boost Software License, Version 1.0. 3 | // (See accompanying file LICENSE_1_0.txt or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | #ifndef SNOWHOUSE_EXPRESSION_H 7 | #define SNOWHOUSE_EXPRESSION_H 8 | 9 | #include "notexpression.h" 10 | #include "andexpression.h" 11 | #include "orexpression.h" 12 | 13 | namespace snowhouse 14 | { 15 | template 16 | struct Expression 17 | { 18 | NotExpression operator!() const 19 | { 20 | return NotExpression(static_cast(*this)); 21 | } 22 | 23 | template 24 | AndExpression operator&&(const Right& right) const 25 | { 26 | return AndExpression(static_cast(*this), right); 27 | } 28 | 29 | template 30 | OrExpression operator||(const Right& right) const 31 | { 32 | return OrExpression(static_cast(*this), right); 33 | } 34 | }; 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /dep/snowhouse/include/snowhouse/constraints/expressions/expression_fwd.h: -------------------------------------------------------------------------------- 1 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 2 | // Distributed under the Boost Software License, Version 1.0. 3 | // (See accompanying file LICENSE_1_0.txt or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | #ifndef SNOWHOUSE_EXPRESSION_FWD_H 7 | #define SNOWHOUSE_EXPRESSION_FWD_H 8 | 9 | namespace snowhouse 10 | { 11 | template 12 | struct Expression; 13 | } 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /dep/snowhouse/include/snowhouse/constraints/isemptyconstraint.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 Stephan Beyer 2 | // Distributed under the Boost Software License, Version 1.0. 3 | // (See accompanying file LICENSE_1_0.txt or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | #ifndef SNOWHOUSE_ISEMPTYCONSTRAINT_H 7 | #define SNOWHOUSE_ISEMPTYCONSTRAINT_H 8 | 9 | #include "expressions/expression.h" 10 | 11 | namespace snowhouse 12 | { 13 | struct IsEmptyConstraint : Expression 14 | { 15 | // The ignored default argument is a workaround to make this class 16 | // compatible to ConstraintAdapterType 17 | IsEmptyConstraint(int = 0) {} 18 | 19 | template 20 | bool operator()(const ActualType& actual) const 21 | { 22 | return actual.empty(); 23 | } 24 | }; 25 | 26 | inline IsEmptyConstraint IsEmpty() 27 | { 28 | return IsEmptyConstraint(); 29 | } 30 | 31 | template <> 32 | struct Stringizer 33 | { 34 | static std::string ToString(const IsEmptyConstraint&) 35 | { 36 | return "empty"; 37 | } 38 | }; 39 | } 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /dep/snowhouse/include/snowhouse/fluent/fluent.h: -------------------------------------------------------------------------------- 1 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 2 | // Distributed under the Boost Software License, Version 1.0. 3 | // (See accompanying file LICENSE_1_0.txt or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | #ifndef SNOWHOUSE_FLUENT_H 7 | #define SNOWHOUSE_FLUENT_H 8 | 9 | #include "expressionbuilder.h" 10 | 11 | namespace snowhouse 12 | { 13 | inline ExpressionBuilder Is() 14 | { 15 | return ExpressionBuilder(Nil()); 16 | } 17 | 18 | inline ExpressionBuilder Has() 19 | { 20 | return ExpressionBuilder(Nil()); 21 | } 22 | } 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /dep/snowhouse/include/snowhouse/fluent/operators/collections/collectionoperator.h: -------------------------------------------------------------------------------- 1 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 2 | // Distributed under the Boost Software License, Version 1.0. 3 | // (See accompanying file LICENSE_1_0.txt or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | #ifndef SNOWHOUSE_COLLECTIONOPERATOR_H 7 | #define SNOWHOUSE_COLLECTIONOPERATOR_H 8 | 9 | #include "../constraintoperator.h" 10 | 11 | namespace snowhouse 12 | { 13 | struct CollectionOperator : public ConstraintOperator 14 | { 15 | void PerformOperation(ResultStack&) override {} 16 | 17 | int Precedence() const override 18 | { 19 | return 1; 20 | } 21 | }; 22 | } 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /dep/snowhouse/include/snowhouse/fluent/operators/invalidexpressionexception.h: -------------------------------------------------------------------------------- 1 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 2 | // Distributed under the Boost Software License, Version 1.0. 3 | // (See accompanying file LICENSE_1_0.txt or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | #ifndef SNOWHOUSE_INVALIDEXPRESSIONEXCEPTION_H 7 | #define SNOWHOUSE_INVALIDEXPRESSIONEXCEPTION_H 8 | 9 | #include 10 | #include 11 | 12 | namespace snowhouse 13 | { 14 | struct InvalidExpressionException : public std::runtime_error 15 | { 16 | using std::runtime_error::runtime_error; 17 | }; 18 | } 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /dep/snowhouse/include/snowhouse/macros.h: -------------------------------------------------------------------------------- 1 | #ifndef SNOWHOUSE_MACROS_H 2 | #define SNOWHOUSE_MACROS_H 3 | // clang-format off 4 | 5 | #define SNOWHOUSE_MAJOR 5 6 | #define SNOWHOUSE_MINOR 0 7 | #define SNOWHOUSE_PATCH 0 8 | 9 | #define SNOWHOUSE_TOSTRING(x) #x 10 | #define SNOWHOUSE_MACROTOSTRING(x) SNOWHOUSE_TOSTRING(x) 11 | #define SNOWHOUSE_VERSION \ 12 | SNOWHOUSE_MACROTOSTRING(SNOWHOUSE_MAJOR) "." \ 13 | SNOWHOUSE_MACROTOSTRING(SNOWHOUSE_MINOR) "." \ 14 | SNOWHOUSE_MACROTOSTRING(SNOWHOUSE_PATCH) 15 | #endif 16 | -------------------------------------------------------------------------------- /dep/snowhouse/include/snowhouse/snowhouse.h: -------------------------------------------------------------------------------- 1 | #ifndef SNOWHOUSE_H 2 | #define SNOWHOUSE_H 3 | 4 | #include "fluent/fluent.h" 5 | #include "stringizers.h" 6 | #include "assert.h" 7 | #include "exceptions.h" 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /dep/snowhouse/util/build-in-container.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if test "$#" -ne 2 4 | then 5 | echo "Usage: $0 (11|14|17) " >&2 6 | exit 2 7 | fi 8 | 9 | SRCDIR=/usr/src/snowhouse 10 | docker run \ 11 | -v "$PWD":"$SRCDIR" \ 12 | -e "SRCDIR=$SRCDIR" \ 13 | -e "CC=$CC" \ 14 | -e "CXX=$CXX" \ 15 | "$2" "$SRCDIR"/util/build.sh "$1" "$2" 16 | -------------------------------------------------------------------------------- /dep/snowhouse/util/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | test -n "$SRCDIR" || SRCDIR="$(pwd)" 4 | test -n "$CC" || CC=cc 5 | test -n "$CXX" || CXX=c++ 6 | 7 | cxxstandard="$1" 8 | case "$cxxstandard" in 9 | 11|14|17) 10 | ;; 11 | *) 12 | echo "Usage: $0 (11|14|17) [image name]" >&2 13 | exit 1 14 | esac 15 | 16 | image="$2" 17 | test -n "$image" || image=default 18 | 19 | buildpath="builds/$(basename "$image" | sed 's/^.*://')/$(basename "$CXX")/std$cxxstandard" 20 | 21 | echo "Build settings:" 22 | echo " * source directory: $SRCDIR" 23 | echo " * C compiler: $CC" 24 | echo " * C++ compiler: $CXX" 25 | echo " * C++ standard: C++$cxxstandard" 26 | echo " * image: $image" 27 | echo " * build path: $buildpath" 28 | 29 | mkdir -p "$SRCDIR/$buildpath" 30 | cd "$SRCDIR/$buildpath" || exit 31 | cmake -DSNOWHOUSE_BUILD_TESTS=1 -DSNOWHOUSE_RUN_TESTS=1 -D"SNOWHOUSE_CXX_STANDARD=C++$cxxstandard" "$SRCDIR" || exit 32 | cmake --build . || exit 33 | -------------------------------------------------------------------------------- /dep/snowhouse/util/format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Reformat all tracked files (run this from snowhouse git root directory, 3 | # not from util!) 4 | 5 | DEFAULT_FORMAT_TOOL=clang-format-9 6 | test -n "$FORMATTER" || FORMATTER="$(command -v "$DEFAULT_FORMAT_TOOL")" 7 | 8 | if test -z "$FORMATTER" 9 | then 10 | echo "Error: No '$DEFAULT_FORMAT_TOOL' executable found in PATH" >&2 11 | echo "You can define your clang-format path by setting the FORMATTER variable" >&2 12 | exit 2 13 | fi 14 | 15 | git ls-files '*.cpp' '*.h' | xargs "$FORMATTER" -i 16 | -------------------------------------------------------------------------------- /dep/stb/UPSTREAM.md: -------------------------------------------------------------------------------- 1 | This comes from https://github.com/nothings/stb, circa commit 2 | af1a5bc352164740c1cc1354942b1c6b72eacb8a. 3 | -------------------------------------------------------------------------------- /dep/stb/build.py: -------------------------------------------------------------------------------- 1 | from build.c import clibrary 2 | 3 | clibrary( 4 | name="stb", 5 | srcs=["./stb_image_write.c"], 6 | hdrs={"stb_image_write.h": "./stb_image_write.h"}, 7 | ) 8 | -------------------------------------------------------------------------------- /dep/stb/stb_image_write.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | static uint8_t* stbiw_compress(uint8_t *data, int data_len, int *out_len, int quality); 7 | 8 | #define STB_IMAGE_WRITE_IMPLEMENTATION 9 | 10 | #if defined NDEBUG 11 | #define STBIW_ASSERT(x) /* */ 12 | #endif 13 | 14 | #define STBIW_ZLIB_COMPRESS stbiw_compress 15 | 16 | #include "stb_image_write.h" 17 | 18 | static uint8_t* stbiw_compress(uint8_t *data, int data_len, int *out_len, int quality) 19 | { 20 | unsigned long size = compressBound(data_len); 21 | uint8_t* buf = (uint8_t*)malloc(size); 22 | 23 | if (buf == NULL) 24 | return NULL; 25 | 26 | if (compress2(buf, &size, data, data_len, quality) != Z_OK) 27 | { 28 | free(buf); 29 | return NULL; 30 | } 31 | 32 | *out_len = size; 33 | return buf; 34 | } 35 | -------------------------------------------------------------------------------- /doc/525-floppy.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/525-floppy.webp -------------------------------------------------------------------------------- /doc/FluxEngine_eagle_pcb.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/FluxEngine_eagle_pcb.zip -------------------------------------------------------------------------------- /doc/Index_sensor_mod_FDD_1.1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/Index_sensor_mod_FDD_1.1.pdf -------------------------------------------------------------------------------- /doc/closeup1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/closeup1.jpg -------------------------------------------------------------------------------- /doc/closeup2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/closeup2.jpg -------------------------------------------------------------------------------- /doc/disk-40track_drive.md: -------------------------------------------------------------------------------- 1 | 40track_drive 2 | ==== 3 | ## Adjust configuration for a 40-track drive 4 | 5 | 6 | This is an extension profile; adding this to the command line will configure 7 | FluxEngine to read from 40-track, 48tpi 5.25" drives. You have to tell it because there is 8 | no way to detect this automatically. 9 | 10 | For example: 11 | 12 | ``` 13 | fluxengine read ibm --180 40track_drive 14 | ``` 15 | 16 | -------------------------------------------------------------------------------- /doc/disk-acorndfs.md: -------------------------------------------------------------------------------- 1 | acorndfs 2 | ==== 3 | ## Acorn Atom, BBC Micro series 4 | 5 | 6 | Acorn DFS disks are used by the Acorn Atom and BBC Micro series of computers. 7 | They are pretty standard FM encoded IBM scheme disks, with 256-sectors and 8 | 0-based sector identifiers. There's nothing particularly special here. 9 | 10 | DFS disks are all single-sided, but allow the other side of the disk to be 11 | used as another volume. 12 | 13 | They come in two varieties, 40 track and 80 track. These should both work. 14 | Some rare disks are both at the same time. FluxEngine can read these but it 15 | requires a bit of fiddling as they have the same tracks on twice. 16 | 17 | ## Options 18 | 19 | - Format variants: 20 | - `100`: 100kB 40-track SSSD 21 | - `200`: 200kB 80-track SSSD 22 | 23 | ## Examples 24 | 25 | To read: 26 | 27 | - `fluxengine read acorndfs --100 -s drive:0 -o acorndfs.img` 28 | - `fluxengine read acorndfs --200 -s drive:0 -o acorndfs.img` 29 | 30 | To write: 31 | 32 | - `fluxengine write acorndfs --100 -d drive:0 -i acorndfs.img` 33 | - `fluxengine write acorndfs --200 -d drive:0 -i acorndfs.img` 34 | 35 | ## References 36 | 37 | - [The Acorn DFS disc format](https://beebwiki.mdfs.net/Acorn_DFS_disc_format) 38 | 39 | -------------------------------------------------------------------------------- /doc/disk-agat.md: -------------------------------------------------------------------------------- 1 | agat 2 | ==== 3 | ## 840kB 5.25" 80-track DS 4 | 5 | 6 | The Agat (Russian: ↊fd74 7 | 1983. These were based around a 6502 and were nominally Apple II-compatible 8 | although with enough differences to be problematic. 9 | 10 | They could use either standard Apple II 140kB disks, or a proprietary 840kb 11 | MFM-based double-sided format. FluxEngine supports both of these; this profile 12 | is for the proprietary format. for the Apple II format, use the `apple2` 13 | profile. 14 | 15 | ## Options 16 | 17 | (no options) 18 | 19 | ## Examples 20 | 21 | To read: 22 | 23 | - `fluxengine read agat -s drive:0 -o agat.img` 24 | 25 | To write: 26 | 27 | - `fluxengine write agat -d drive:0 -i agat.img` 28 | 29 | ## References 30 | 31 | - [Magazine article on the 32 | Agat](https://sudonull.com/post/54185-Is-AGAT-a-bad-copy-of-Apple) 33 | 34 | - [Forum thread with (some) documentation on the 35 | format](https://torlus.com/floppy/forum/viewtopic.php?t=1385) 36 | 37 | -------------------------------------------------------------------------------- /doc/disk-apple2_drive.md: -------------------------------------------------------------------------------- 1 | apple2_drive 2 | ==== 3 | ## Adjust configuration for a 40-track Apple II drive 4 | 5 | 6 | This is an extension profile; adding this to the command line will configure 7 | FluxEngine to adjust the pinout and track spacing to work with an Apple II 8 | drive. This only works on Greaseweazle hardware and requires a custom 9 | connector. 10 | 11 | For example: 12 | 13 | ``` 14 | fluxengine read apple2 --160 apple2_drive 15 | ``` 16 | 17 | -------------------------------------------------------------------------------- /doc/disk-bk.md: -------------------------------------------------------------------------------- 1 | bk 2 | ==== 3 | ## 800kB 5.25"/3.5" 80-track 10-sector DSDD 4 | 5 | 6 | The BK (an abbreviation for 1ba9 7 | is a Soviet era personal computer from Elektronika based on a PDP-11 8 | single-chip processor. It was the _only_ official, government approved home 9 | computer in mass production at the time. 10 | 11 | It got a floppy interface in 1989 when the 128kB BK-0011 was released. This 12 | used a relatively normal double-sided IBM scheme format with 80 sectors and ten 13 | sectors per track, resulting in 800kB disks. The format is, in fact, identical 14 | to the Atari ST 800kB format. Either 5.25" or 3.5" drives were used depending 15 | on what was available at the time, with the same format on both. 16 | 17 | ## Options 18 | 19 | (no options) 20 | 21 | ## Examples 22 | 23 | To read: 24 | 25 | - `fluxengine read bk -s drive:0 -o bk800.img` 26 | 27 | To write: 28 | 29 | - `fluxengine write bk -d drive:0 -i bk800.img` 30 | 31 | -------------------------------------------------------------------------------- /doc/disk-epsonpf10.md: -------------------------------------------------------------------------------- 1 | epsonpf10 2 | ==== 3 | ## CP/M; 3.5" 40-track DSDD 4 | 5 | 6 | The Epson PF10 is the disk unit for the Epson Z80 series of 'laptops', running 7 | CP/M. It uses a single-sided 40-track 3.5" format, which is unusual, but the 8 | format itself is yet another IBM scheme variant. 9 | 10 | ## Options 11 | 12 | (no options) 13 | 14 | ## Examples 15 | 16 | To read: 17 | 18 | - `fluxengine read epsonpf10 -s drive:0 -o epsonpf10.img` 19 | 20 | -------------------------------------------------------------------------------- /doc/disk-icl30.md: -------------------------------------------------------------------------------- 1 | icl30 2 | ==== 3 | ## CP/M; 263kB 35-track DSSD 4 | 5 | 6 | The ICL Model 30 is a reasonably standard CP/M machine using 35-track single 7 | density disks and the traditional CP/M 128-byte secotrs --- 30 of them per 8 | track! Other than that it's another IBM scheme variation. 9 | 10 | ## Options 11 | 12 | (no options) 13 | 14 | ## Examples 15 | 16 | To read: 17 | 18 | - `fluxengine read icl30 -s drive:0 -o icl30.img` 19 | 20 | -------------------------------------------------------------------------------- /doc/disk-ms2000.md: -------------------------------------------------------------------------------- 1 | ms2000 2 | ==== 3 | ## MS2000 Microdisk Development System 4 | 5 | 6 | The RCA MicroDisk Development System MS2000 is a highly obscure (i.e. I gather 7 | that single digit numbers of original machines exist) development system for the 8 | RCA1802 series of CPUs, as made famous by the Cosmac ELF. It was a fairly 9 | straightforward big bag o'RAM system with a 2kB boot ROM, 62kB of RAM, twin 10 | floppy drives and a serial terminal --- CP/M users will find it very familiar. 11 | 12 | Read and writing disks is currently not supported by FluxEngine, but there is 13 | basic support for the MicroDisk operating system's file system. This should 14 | allow files to be read from MS2000 disk images. 15 | 16 | The disks are normal DD 3.5" disks, using a 70-track, single sided variation of 17 | the venerable IBM floppy disk scheme, so allowing 315kB of storage per disk. 18 | 19 | If you have access to flux files for MS2000 disks, please [get in 20 | touch](https://github.com/davidgiven/cpm65/issues/new) --- I would like to add 21 | better support for these. 22 | 23 | ## Options 24 | 25 | (no options) 26 | 27 | ## Examples 28 | 29 | ## References 30 | 31 | - [The EMMA-02 emulator](https://www.emma02.hobby-site.com/ms2000.html), which 32 | supports the MS2000 and provides information on it. 33 | 34 | -------------------------------------------------------------------------------- /doc/disk-n88basic.md: -------------------------------------------------------------------------------- 1 | n88basic 2 | ==== 3 | ## PC8800/PC98 5.25" 77-track 26-sector DSHD 4 | 5 | 6 | The N88-BASIC disk format is the one used by the operating system of the same 7 | name for the Japanese PC8800 and PC98 computers. It is another IBM scheme 8 | variant, and is very similar to some mixed-format CP/M disk formats, where 9 | track 0 side 0 uses 128-byte single density sectors and the rest of the disk 10 | uses 512-byte double density sectors. (The reason for this is that the PC8800 11 | boot ROM could only read single density data.) 12 | 13 | ## Options 14 | 15 | (no options) 16 | 17 | ## Examples 18 | 19 | To read: 20 | 21 | - `fluxengine read n88basic -s drive:0 -o n88basic.img` 22 | 23 | To write: 24 | 25 | - `fluxengine write n88basic -d drive:0 -i n88basic.img` 26 | 27 | -------------------------------------------------------------------------------- /doc/disk-psos.md: -------------------------------------------------------------------------------- 1 | psos 2 | ==== 3 | ## 800kB DSDD with PHILE 4 | 5 | 6 | pSOS was an influential real-time operating system from the 1980s, used mainly 7 | on 68000-based machines, lasting up until about 2000 when it was bought (and 8 | cancelled) by Wind River. It had its own floppy disk format and file system, 9 | both of which are partially supported here. 10 | 11 | The PHILE file system is almost completely undocumented and so many of the data 12 | structures have had to be reverse engineered and are not well known. Please 13 | [get in touch](https://github.com/davidgiven/fluxengine/issues/new) if you know 14 | anything about it. 15 | 16 | The floppy disk format itself is an IBM scheme variation with 1024-byte sectors 17 | and, oddly, swapped sides. 18 | 19 | ## Options 20 | 21 | (no options) 22 | 23 | ## Examples 24 | 25 | To read: 26 | 27 | - `fluxengine read psos -s drive:0 -o pme.img` 28 | 29 | To write: 30 | 31 | - `fluxengine write psos -d drive:0 -i pme.img` 32 | 33 | -------------------------------------------------------------------------------- /doc/disk-rx50.md: -------------------------------------------------------------------------------- 1 | rx50 2 | ==== 3 | ## 400kB 5.25" 80-track 10-sector SSDD 4 | 5 | 6 | The Digital RX50 is one of the external floppy drive units used by Digital's 7 | range of computers, especially the DEC Rainbow microcomputer. It is a fairly 8 | vanilla single-sided IBM scheme variation. 9 | 10 | ## Options 11 | 12 | (no options) 13 | 14 | ## Examples 15 | 16 | To read: 17 | 18 | - `fluxengine read rx50 -s drive:0 -o rx50.img` 19 | 20 | To write: 21 | 22 | - `fluxengine write rx50 -d drive:0 -i rx50.img` 23 | 24 | -------------------------------------------------------------------------------- /doc/disk-shugart_drive.md: -------------------------------------------------------------------------------- 1 | shugart_drive 2 | ==== 3 | ## Adjust configuration for a Shugart drive 4 | 5 | 6 | This is an extension profile; adding this to the command line will configure 7 | FluxEngine to adjust the pinout to work with a Shugart drive. This only works 8 | on Greaseweazle hardware. 9 | 10 | For example: 11 | 12 | ``` 13 | fluxengine read ibm --720 shugart_drive 14 | ``` 15 | 16 | -------------------------------------------------------------------------------- /doc/disk-smaky6.md: -------------------------------------------------------------------------------- 1 | smaky6 2 | ==== 3 | ## 308kB 5.25" 77-track 16-sector SSDD, hard sectored 4 | 5 | 6 | The Smaky 6 is a Swiss computer from 1978 produced by Epsitec. It's based 7 | around a Z80 processor and has one or two Micropolis 5.25" drives which use 8 | 16-sector hard sectored disks. The disk format is single-sided with 77 tracks 9 | and 256-byte sectors, resulting in 308kB disks. It uses MFM with a custom 10 | sector record scheme. It was later superceded by a 68000-based Smaky which used 11 | different disks. 12 | 13 | FluxEngine supports these, although because the Micropolis drives use a 100tpi 14 | track pitch, you can't read Smaky 6 disks with a normal PC 96tpi drive. You 15 | will have to find a 100tpi drive from somewhere (they're rare). 16 | 17 | There is experimental read-only support for the Smaky 6 filesystem, allowing 18 | the directory to be listed and files read from disks. It's not known whether 19 | this is completely correct, so don't trust it! 20 | 21 | ## Options 22 | 23 | (no options) 24 | 25 | ## Examples 26 | 27 | To read: 28 | 29 | - `fluxengine read smaky6 -s drive:0 -o smaky6.img` 30 | 31 | ## References 32 | 33 | - [Smaky Info, 1978-2002 (in French)](https://www.smaky.ch/theme.php?id=sminfo) 34 | 35 | -------------------------------------------------------------------------------- /doc/disk-tids990.md: -------------------------------------------------------------------------------- 1 | tids990 2 | ==== 3 | ## 1126kB 8" DSSD 4 | 5 | 6 | The Texas Instruments DS990 was a multiuser modular computing system from 1998, 7 | based around the TMS-9900 processor (as used by the TI-99). It had an 8" floppy 8 | drive module, the FD1000, which was a 77-track, 288-byte sector FM/MFM system 9 | with 26 sectors per track. The encoding scheme was very similar to a simplified 10 | version of the IBM scheme, but of course not compatible. A double-sided disk 11 | would store a very satisfactory 1126kB of data; here's one at old-computers.com: 13 | 14 |
15 | 16 | A DS990 at old-computers.com 17 |
18 | 19 | FluxEngine will read and write these (but only the DSDD MFM variant). 20 | 21 | ## Options 22 | 23 | (no options) 24 | 25 | ## Examples 26 | 27 | To read: 28 | 29 | - `fluxengine read tids990 -s drive:0 -o tids990.img` 30 | 31 | To write: 32 | 33 | - `fluxengine write tids990 -d drive:0 -i tids990.img` 34 | 35 | ## References 36 | 37 | - [The FD1000 Depot Maintenance 38 | Manual](http://www.bitsavers.org/pdf/ti/990/disk/2261885-9701_FD1000depotVo1_Jan81.pdf) 39 | 40 | -------------------------------------------------------------------------------- /doc/disk-tiki.md: -------------------------------------------------------------------------------- 1 | tiki 2 | ==== 3 | ## CP/M 4 | 5 | 6 | The Tiki 100 is a Z80-based Norwegian microcomputer from the mid 1980s intended 7 | for eductional use. It mostly ran an unbranded CP/M clone, and uses fairly 8 | normal CP/M disks --- IBM scheme and from 128 to 512 bytes per sector depending 9 | on the precise format. 10 | 11 | ## Options 12 | 13 | - Format variants: 14 | - `90`: 90kB 40-track 18-sector SSSD 15 | - `200`: 200kB 40-track 10-sector SSDD 16 | - `400`: 400kB 40-track 10-sector DSDD 17 | - `800`: 800kB 80-track 10-sector DSDD 18 | 19 | ## Examples 20 | 21 | To read: 22 | 23 | - `fluxengine read tiki --90 -s drive:0 -o tiki.img` 24 | - `fluxengine read tiki --200 -s drive:0 -o tiki.img` 25 | - `fluxengine read tiki --400 -s drive:0 -o tiki.img` 26 | - `fluxengine read tiki --800 -s drive:0 -o tiki.img` 27 | 28 | -------------------------------------------------------------------------------- /doc/durangof85.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/durangof85.jpg -------------------------------------------------------------------------------- /doc/dvk3m.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/dvk3m.jpg -------------------------------------------------------------------------------- /doc/fdd-90206-dd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/fdd-90206-dd.png -------------------------------------------------------------------------------- /doc/fdd-90206-hd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/fdd-90206-hd.png -------------------------------------------------------------------------------- /doc/filebrowser.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/filebrowser.jpg -------------------------------------------------------------------------------- /doc/ju475-dd-hi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/ju475-dd-hi.png -------------------------------------------------------------------------------- /doc/ju475-dd-lo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/ju475-dd-lo.png -------------------------------------------------------------------------------- /doc/ju475-hd-hi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/ju475-hd-hi.png -------------------------------------------------------------------------------- /doc/ju475-hd-lo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/ju475-hd-lo.png -------------------------------------------------------------------------------- /doc/mpf90-dd-lo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/mpf90-dd-lo.png -------------------------------------------------------------------------------- /doc/mpf90-hd-hi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/mpf90-hd-hi.png -------------------------------------------------------------------------------- /doc/mpf90-hd-lo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/mpf90-hd-lo.png -------------------------------------------------------------------------------- /doc/pcb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/pcb.png -------------------------------------------------------------------------------- /doc/screenshot-details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/screenshot-details.png -------------------------------------------------------------------------------- /doc/screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/screenshot.jpg -------------------------------------------------------------------------------- /doc/tartu-fdc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/tartu-fdc.jpg -------------------------------------------------------------------------------- /doc/tartu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/tartu.jpg -------------------------------------------------------------------------------- /doc/tids990.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/tids990.jpg -------------------------------------------------------------------------------- /doc/tpdd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/tpdd.jpg -------------------------------------------------------------------------------- /doc/vds-eco1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/vds-eco1.jpg -------------------------------------------------------------------------------- /doc/visualiser.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/visualiser.jpg -------------------------------------------------------------------------------- /doc/zilogmcz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/doc/zilogmcz.jpg -------------------------------------------------------------------------------- /extras/FluxEngine.app.template/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | FluxEngine.sh 9 | CFBundleGetInfoString 10 | FluxEngine 1.0 11 | CFBundleIconFile 12 | FluxEngine.icns 13 | CFBundleIdentifier 14 | com.cowlark.fluxengine.gui 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleLocalizations 18 | 19 | en 20 | 21 | CFBundleName 22 | FluxEngine 23 | CFBundleDisplayName 24 | FluxEngine 25 | CFBundlePackageType 26 | APPL 27 | CFBundleShortVersionString 28 | 1.0 29 | CFBundleSignature 30 | FluxEngine 31 | CFBundleVersion 32 | 1.0 33 | LSMinimumSystemVersion 34 | 10.13.0 35 | LSRequiresCarbon 36 | 37 | NSAppleScriptEnabled 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /extras/FluxEngine.app.template/Contents/MacOS/FluxEngine.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | dir=`dirname "$0"` 3 | cd "$dir" 4 | export DYLD_FALLBACK_LIBRARY_PATH=../Resources:/opt/local/lib 5 | exec ./fluxengine-gui "$@" 6 | -------------------------------------------------------------------------------- /extras/fluxfile.piko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/extras/fluxfile.piko -------------------------------------------------------------------------------- /extras/fluxfile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/extras/fluxfile.png -------------------------------------------------------------------------------- /extras/hardware.piko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/extras/hardware.piko -------------------------------------------------------------------------------- /extras/hardware.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/extras/hardware.png -------------------------------------------------------------------------------- /extras/icon.piko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/extras/icon.piko -------------------------------------------------------------------------------- /extras/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/extras/icon.png -------------------------------------------------------------------------------- /extras/imagefile.piko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/extras/imagefile.piko -------------------------------------------------------------------------------- /extras/imagefile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidgiven/fluxengine/5293e1c18bd5c36f197ba496435388d8019fd5a3/extras/imagefile.png -------------------------------------------------------------------------------- /lib/algorithms/build.py: -------------------------------------------------------------------------------- 1 | from build.c import cxxlibrary 2 | 3 | cxxlibrary( 4 | name="algorithms", 5 | srcs=["./readerwriter.cc"], 6 | hdrs={ 7 | "lib/algorithms/readerwriter.h": "./readerwriter.h", 8 | }, 9 | deps=[ 10 | "lib/core", 11 | "lib/config", 12 | "lib/data", 13 | "lib/usb", 14 | "lib/encoders", 15 | "lib/decoders", 16 | "lib/fluxsource", 17 | "lib/fluxsink", 18 | "lib/imagereader", 19 | "lib/imagewriter", 20 | ], 21 | ) 22 | -------------------------------------------------------------------------------- /lib/config/common.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "google/protobuf/descriptor.proto"; 4 | 5 | message RangeProto { 6 | optional int32 start = 1 [default = 0, (help) = "start value"]; 7 | optional int32 step = 2 [default = 1, (help) = "amount to step by (positive)"]; 8 | optional int32 end = 3 [(help) = "inclusive end value, defaulting to the start value"]; 9 | } 10 | 11 | extend google.protobuf.FieldOptions { 12 | optional string help = 50000; 13 | optional bool recurse = 50001 [default = true]; 14 | } 15 | 16 | enum IndexMode { 17 | INDEXMODE_DRIVE = 0; 18 | INDEXMODE_300 = 1; 19 | INDEXMODE_360 = 2; 20 | } 21 | 22 | enum FluxSourceSinkType { 23 | FLUXTYPE_NOT_SET = 0; 24 | FLUXTYPE_A2R = 1; 25 | FLUXTYPE_AU = 2; 26 | FLUXTYPE_CWF = 3; 27 | FLUXTYPE_DRIVE = 4; 28 | FLUXTYPE_ERASE = 5; 29 | FLUXTYPE_FLUX = 6; 30 | FLUXTYPE_FLX = 7; 31 | FLUXTYPE_KRYOFLUX = 8; 32 | FLUXTYPE_SCP = 9; 33 | FLUXTYPE_TEST_PATTERN = 10; 34 | FLUXTYPE_VCD = 11; 35 | FLUXTYPE_DMK = 12; 36 | } 37 | 38 | enum ImageReaderWriterType { 39 | IMAGETYPE_NOT_SET = 0; 40 | IMAGETYPE_D64 = 1; 41 | IMAGETYPE_D88 = 2; 42 | IMAGETYPE_DIM = 3; 43 | IMAGETYPE_DISKCOPY = 4; 44 | IMAGETYPE_FDI = 5; 45 | IMAGETYPE_IMD = 6; 46 | IMAGETYPE_IMG = 7; 47 | IMAGETYPE_JV3 = 8; 48 | IMAGETYPE_LDBS = 9; 49 | IMAGETYPE_NFD = 10; 50 | IMAGETYPE_NSI = 11; 51 | IMAGETYPE_RAW = 12; 52 | IMAGETYPE_TD0 = 13; 53 | } 54 | 55 | 56 | -------------------------------------------------------------------------------- /lib/core/bitmap.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "agg2d.h" 3 | #include "stb_image_write.h" 4 | #include "lib/core/utils.h" 5 | #include "lib/core/bitmap.h" 6 | #include 7 | #include 8 | 9 | Bitmap::Bitmap(const std::string filename, unsigned width, unsigned height): 10 | filename(filename), 11 | width(width), 12 | height(height), 13 | initialised(true) 14 | { 15 | } 16 | 17 | Agg2D& Bitmap::painter() 18 | { 19 | if (!_painter) 20 | { 21 | _bitmap.resize(width * height * 4, 255); 22 | _painter.reset(new Agg2D()); 23 | _painter->attach(&_bitmap[0], width, height, width * 4); 24 | } 25 | return *_painter; 26 | } 27 | 28 | void Bitmap::save() 29 | { 30 | if (endsWith(filename, ".png")) 31 | stbi_write_png( 32 | filename.c_str(), width, height, 4, &_bitmap[0], width * 4); 33 | else if (endsWith(filename, ".bmp")) 34 | stbi_write_bmp(filename.c_str(), width, height, 4, &_bitmap[0]); 35 | else if (endsWith(filename, ".tga")) 36 | stbi_write_tga(filename.c_str(), width, height, 4, &_bitmap[0]); 37 | else if (endsWith(filename, ".jpg")) 38 | stbi_write_jpg(filename.c_str(), width, height, 4, &_bitmap[0], 80); 39 | else 40 | error("don't know how to write that image format"); 41 | } 42 | -------------------------------------------------------------------------------- /lib/core/bitmap.h: -------------------------------------------------------------------------------- 1 | #ifndef BITMAP_H 2 | #define BITMAP_H 3 | 4 | class Agg2D; 5 | 6 | class Bitmap 7 | { 8 | public: 9 | Bitmap(const std::string filename, unsigned width, unsigned height); 10 | 11 | Agg2D& painter(); 12 | void save(); 13 | 14 | private: 15 | std::vector _bitmap; 16 | std::unique_ptr _painter; 17 | 18 | public: 19 | std::string filename; 20 | unsigned width; 21 | unsigned height; 22 | bool initialised : 1; 23 | }; 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /lib/core/build.py: -------------------------------------------------------------------------------- 1 | from build.c import cxxlibrary 2 | 3 | cxxlibrary( 4 | name="core", 5 | srcs=[ 6 | "./bitmap.cc", 7 | "./bytes.cc", 8 | "./crc.cc", 9 | "./hexdump.cc", 10 | "./utils.cc", 11 | "./logger.cc", 12 | "./logrenderer.cc", 13 | ], 14 | hdrs={ 15 | "lib/core/bitmap.h": "./bitmap.h", 16 | "lib/core/bytes.h": "./bytes.h", 17 | "lib/core/crc.h": "./crc.h", 18 | "lib/core/globals.h": "./globals.h", 19 | "lib/core/utils.h": "./utils.h", 20 | "lib/core/logger.h": "./logger.h", 21 | }, 22 | deps=[ 23 | "dep/agg", 24 | "dep/stb", 25 | "+fmt_lib", 26 | ], 27 | ) 28 | -------------------------------------------------------------------------------- /lib/core/crc.h: -------------------------------------------------------------------------------- 1 | #ifndef CRC_H 2 | #define CRC_H 3 | 4 | #define CCITT_POLY 0x1021 5 | #define MODBUS_POLY 0x8005 6 | #define MODBUS_POLY_REF 0xa001 7 | #define BROTHER_POLY 0x000201 8 | 9 | struct crcspec 10 | { 11 | unsigned width; 12 | uint64_t poly; 13 | uint64_t init; 14 | uint64_t xorout; 15 | bool refin; 16 | bool refout; 17 | }; 18 | 19 | extern uint64_t generic_crc(const struct crcspec& spec, const Bytes& bytes); 20 | 21 | extern uint16_t sumBytes(const Bytes& bytes); 22 | extern uint8_t xorBytes(const Bytes& bytes); 23 | extern uint16_t crc16(uint16_t poly, uint16_t init, const Bytes& bytes); 24 | extern uint16_t crc16ref(uint16_t poly, uint16_t init, const Bytes& bytes); 25 | extern uint32_t crcbrother(const Bytes& bytes); 26 | 27 | static inline uint16_t crc16(uint16_t poly, const Bytes& bytes) 28 | { 29 | return crc16(poly, 0xffff, bytes); 30 | } 31 | 32 | static inline uint16_t crc16ref(uint16_t poly, const Bytes& bytes) 33 | { 34 | return crc16ref(poly, 0xffff, bytes); 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /lib/core/hexdump.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/core/bytes.h" 3 | 4 | void hexdump(std::ostream& stream, const Bytes& buffer) 5 | { 6 | size_t pos = 0; 7 | 8 | while (pos < buffer.size()) 9 | { 10 | stream << fmt::format("{:05x} : ", pos); 11 | for (int i = 0; i < 16; i++) 12 | { 13 | if ((pos + i) < buffer.size()) 14 | stream << fmt::format("{:02x} ", buffer[pos + i]); 15 | else 16 | stream << "-- "; 17 | } 18 | stream << " : "; 19 | for (int i = 0; i < 16; i++) 20 | { 21 | if ((pos + i) >= buffer.size()) 22 | break; 23 | 24 | uint8_t c = buffer[pos + i]; 25 | if ((c >= 32) && (c <= 126)) 26 | stream << (char)c; 27 | else 28 | stream << '.'; 29 | } 30 | stream << std::endl; 31 | 32 | pos += 16; 33 | } 34 | } 35 | 36 | void hexdumpForSrp16(std::ostream& stream, const Bytes& buffer) 37 | { 38 | for (uint8_t byte : buffer) 39 | stream << fmt::format("{:02x}", byte); 40 | stream << std::endl; 41 | } 42 | -------------------------------------------------------------------------------- /lib/core/logger.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/core/bytes.h" 3 | #include "lib/core/logger.h" 4 | 5 | static bool indented = false; 6 | 7 | static std::function loggerImpl = 8 | [](const auto& message) 9 | { 10 | static auto r = LogRenderer::create(std::cout); 11 | r->add(message); 12 | }; 13 | 14 | void log(const char* m) 15 | { 16 | log(std::string(m)); 17 | } 18 | 19 | void log(const AnyLogMessage& message) 20 | { 21 | loggerImpl(message); 22 | } 23 | 24 | void Logger::setLogger(std::function cb) 25 | { 26 | loggerImpl = cb; 27 | } 28 | 29 | void renderLogMessage( 30 | LogRenderer& r, std::shared_ptr msg) 31 | { 32 | r.newline().add("Error:").add(msg->message).newline(); 33 | } 34 | 35 | void renderLogMessage( 36 | LogRenderer& r, std::shared_ptr msg) 37 | { 38 | r.newline().add("Stop!").newline(); 39 | } 40 | 41 | void renderLogMessage(LogRenderer& r, std::shared_ptr msg) 42 | { 43 | r.newline().add(*msg).newline(); 44 | } 45 | 46 | LogRenderer& LogRenderer::add(const AnyLogMessage& message) 47 | { 48 | std::visit( 49 | [&](const auto& arg) 50 | { 51 | renderLogMessage(*this, arg); 52 | }, 53 | message); 54 | 55 | return *this; 56 | } 57 | -------------------------------------------------------------------------------- /lib/data/build.py: -------------------------------------------------------------------------------- 1 | from build.c import cxxlibrary 2 | 3 | cxxlibrary( 4 | name="data", 5 | srcs=[ 6 | "./fluxmap.cc", 7 | "./sector.cc", 8 | "./layout.cc", 9 | "./image.cc", 10 | "./fluxmapreader.cc", 11 | "./fluxpattern.cc", 12 | ], 13 | hdrs={ 14 | "lib/data/flux.h": "./flux.h", 15 | "lib/data/fluxmap.h": "./fluxmap.h", 16 | "lib/data/sector.h": "./sector.h", 17 | "lib/data/layout.h": "./layout.h", 18 | "lib/data/image.h": "./image.h", 19 | "lib/data/fluxmapreader.h": "./fluxmapreader.h", 20 | "lib/data/fluxpattern.h": "./fluxpattern.h", 21 | }, 22 | deps=["lib/core", "lib/config", "+protocol"], 23 | ) 24 | -------------------------------------------------------------------------------- /lib/data/flux.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUX_H 2 | #define FLUX_H 3 | 4 | #include "lib/core/bytes.h" 5 | 6 | class Fluxmap; 7 | class Sector; 8 | class Image; 9 | class TrackInfo; 10 | 11 | struct Record 12 | { 13 | nanoseconds_t clock = 0; 14 | nanoseconds_t startTime = 0; 15 | nanoseconds_t endTime = 0; 16 | uint32_t position = 0; 17 | Bytes rawData; 18 | }; 19 | 20 | struct TrackDataFlux 21 | { 22 | std::shared_ptr trackInfo; 23 | std::shared_ptr fluxmap; 24 | std::vector> records; 25 | std::vector> sectors; 26 | }; 27 | 28 | struct TrackFlux 29 | { 30 | std::shared_ptr trackInfo; 31 | std::vector> trackDatas; 32 | std::set> sectors; 33 | }; 34 | 35 | struct DiskFlux 36 | { 37 | std::vector> tracks; 38 | std::shared_ptr image; 39 | }; 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /lib/decoders/build.py: -------------------------------------------------------------------------------- 1 | from build.protobuf import proto, protocc 2 | from build.c import cxxlibrary 3 | 4 | proto( 5 | name="proto", 6 | srcs=["./decoders.proto"], 7 | deps=["lib/config+common_proto", "arch+proto", "lib/fluxsink+proto"], 8 | ) 9 | 10 | protocc( 11 | name="proto_lib", 12 | srcs=[".+proto"], 13 | deps=[ 14 | "lib/config+common_proto_lib", 15 | "arch+proto_lib", 16 | "lib/fluxsink+proto_lib", 17 | ], 18 | ) 19 | 20 | cxxlibrary( 21 | name="decoders", 22 | srcs=["./decoders.cc", "./fluxdecoder.cc", "./fmmfm.cc"], 23 | hdrs={ 24 | "lib/decoders/decoders.h": "./decoders.h", 25 | "lib/decoders/fluxdecoder.h": "./fluxdecoder.h", 26 | "lib/decoders/rawbits.h": "./rawbits.h", 27 | }, 28 | deps=["lib/core", "lib/config", "lib/data", ".+proto_lib"], 29 | ) 30 | -------------------------------------------------------------------------------- /lib/decoders/fluxdecoder.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUXDECODER_H 2 | #define FLUXDECODER_H 3 | 4 | class FluxmapReader; 5 | 6 | class FluxDecoder 7 | { 8 | public: 9 | FluxDecoder( 10 | FluxmapReader* fmr, nanoseconds_t bitcell, const DecoderProto& config); 11 | 12 | bool readBit(); 13 | std::vector readBits(unsigned count); 14 | std::vector readBits(const Fluxmap::Position& until); 15 | 16 | std::vector readBits() 17 | { 18 | return readBits(UINT_MAX); 19 | } 20 | 21 | private: 22 | nanoseconds_t nextFlux(); 23 | 24 | private: 25 | FluxmapReader* _fmr; 26 | double _pll_phase; 27 | double _pll_adjust; 28 | double _flux_scale; 29 | nanoseconds_t _clock = 0; 30 | nanoseconds_t _clock_centre; 31 | nanoseconds_t _clock_min; 32 | nanoseconds_t _clock_max; 33 | nanoseconds_t _flux = 0; 34 | unsigned _clocked_zeroes = 0; 35 | unsigned _goodbits = 0; 36 | bool _index = false; 37 | bool _sync_lost = false; 38 | int _leading_zeroes; 39 | }; 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /lib/decoders/rawbits.h: -------------------------------------------------------------------------------- 1 | #ifndef RAWBITS_H 2 | #define RAWBITS_H 3 | 4 | class RawBits 5 | { 6 | public: 7 | RawBits(std::unique_ptr> bits, 8 | std::unique_ptr> indices): 9 | _bits(std::move(bits)), 10 | _indices(std::move(indices)) 11 | { 12 | } 13 | 14 | typedef std::vector::const_iterator const_iterator; 15 | 16 | const_iterator begin() const 17 | { 18 | return _bits->begin(); 19 | } 20 | 21 | const_iterator end() const 22 | { 23 | return _bits->end(); 24 | } 25 | 26 | size_t size() const 27 | { 28 | return _bits->size(); 29 | } 30 | 31 | const bool operator[](size_t pos) const 32 | { 33 | return _bits->at(pos); 34 | } 35 | 36 | const std::vector indices() const 37 | { 38 | return *_indices; 39 | } 40 | 41 | private: 42 | std::unique_ptr> _bits; 43 | std::unique_ptr> _indices; 44 | }; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /lib/encoders/build.py: -------------------------------------------------------------------------------- 1 | from build.protobuf import proto, protocc 2 | from build.c import cxxlibrary 3 | 4 | proto( 5 | name="proto", 6 | srcs=["./encoders.proto"], 7 | deps=["lib/config+common_proto", "arch+proto"], 8 | ) 9 | protocc( 10 | name="proto_lib", 11 | srcs=[".+proto"], 12 | deps=["lib/config+common_proto_lib", "arch+proto_lib"], 13 | ) 14 | 15 | cxxlibrary( 16 | name="encoders", 17 | srcs=["./encoders.cc"], 18 | hdrs={"lib/encoders/encoders.h": "./encoders.h"}, 19 | deps=["lib/core", "lib/data", "lib/config", ".+proto_lib"], 20 | ) 21 | -------------------------------------------------------------------------------- /lib/encoders/encoders.h: -------------------------------------------------------------------------------- 1 | #ifndef ENCODERS_H 2 | #define ENCODERS_H 3 | 4 | class EncoderProto; 5 | class Fluxmap; 6 | class Image; 7 | class Layout; 8 | class Sector; 9 | class TrackInfo; 10 | class Config; 11 | 12 | class Encoder 13 | { 14 | public: 15 | Encoder(const EncoderProto& config) {} 16 | virtual ~Encoder() {} 17 | 18 | static std::unique_ptr create(Config& config); 19 | 20 | public: 21 | virtual std::shared_ptr getSector( 22 | std::shared_ptr&, 23 | const Image& image, 24 | unsigned sectorId); 25 | 26 | virtual std::vector> collectSectors( 27 | std::shared_ptr&, const Image& image); 28 | 29 | virtual std::unique_ptr encode( 30 | std::shared_ptr& trackInfo, 31 | const std::vector>& sectors, 32 | const Image& image) = 0; 33 | 34 | nanoseconds_t calculatePhysicalClockPeriod( 35 | nanoseconds_t targetClockPeriod, nanoseconds_t targetRotationalPeriod); 36 | }; 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /lib/encoders/encoders.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "arch/agat/agat.proto"; 4 | import "arch/amiga/amiga.proto"; 5 | import "arch/apple2/apple2.proto"; 6 | import "arch/brother/brother.proto"; 7 | import "arch/c64/c64.proto"; 8 | import "arch/ibm/ibm.proto"; 9 | import "arch/macintosh/macintosh.proto"; 10 | import "arch/micropolis/micropolis.proto"; 11 | import "arch/northstar/northstar.proto"; 12 | import "arch/tartu/tartu.proto"; 13 | import "arch/tids990/tids990.proto"; 14 | import "arch/victor9k/victor9k.proto"; 15 | 16 | message EncoderProto 17 | { 18 | oneof format 19 | { 20 | IbmEncoderProto ibm = 3; 21 | BrotherEncoderProto brother = 4; 22 | AmigaEncoderProto amiga = 5; 23 | MacintoshEncoderProto macintosh = 6; 24 | Tids990EncoderProto tids990 = 7; 25 | Commodore64EncoderProto c64 = 8; 26 | NorthstarEncoderProto northstar = 9; 27 | MicropolisEncoderProto micropolis = 10; 28 | Victor9kEncoderProto victor9k = 11; 29 | Apple2EncoderProto apple2 = 12; 30 | AgatEncoderProto agat = 13; 31 | TartuEncoderProto tartu = 14; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/external/a2r.h: -------------------------------------------------------------------------------- 1 | #ifndef A2R_H 2 | #define A2R_H 3 | 4 | // The canonical reference for the A2R format is: 5 | // https://applesaucefdc.com/a2r2-reference/ All data is stored little-endian 6 | 7 | // Note: The first chunk begins at byte offset 8, not 12 as given in a2r2 8 | // reference version 2.0.1 9 | 10 | #define A2R_CHUNK_INFO (0x4F464E49) 11 | #define A2R_CHUNK_STRM (0x4D525453) 12 | #define A2R_CHUNK_META (0x4154454D) 13 | 14 | #define A2R_INFO_CHUNK_VERSION (1) 15 | 16 | enum A2RDiskType 17 | { 18 | A2R_DISK_525 = 1, 19 | A2R_DISK_35 = 2, 20 | }; 21 | 22 | enum A2RCaptureType 23 | { 24 | A2R_TIMING = 1, 25 | A2R_BITS = 2, 26 | A2R_XTIMING = 3, 27 | }; 28 | 29 | extern const uint8_t a2r2_fileheader[8]; 30 | 31 | #define A2R_NS_PER_TICK (125) 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /lib/external/applesauce.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define APPLESAUCE_VID 0x16c0 4 | #define APPLESAUCE_PID 0x0483 5 | 6 | #define APPLESAUCE_ID ((APPLESAUCE_VID << 16) | APPLESAUCE_PID) 7 | -------------------------------------------------------------------------------- /lib/external/build.py: -------------------------------------------------------------------------------- 1 | from build.c import cxxlibrary 2 | from build.protobuf import proto, protocc 3 | 4 | proto(name="fl2_proto", srcs=["./fl2.proto"]) 5 | protocc(name="fl2_proto_lib", srcs=[".+fl2_proto"], deps=["+protobuf_lib"]) 6 | 7 | cxxlibrary( 8 | name="external", 9 | srcs=[ 10 | "./catweasel.cc", 11 | "./csvreader.cc", 12 | "./fl2.cc", 13 | "./flx.cc", 14 | "./greaseweazle.cc", 15 | "./kryoflux.cc", 16 | "./ldbs.cc", 17 | ], 18 | hdrs={ 19 | "lib/external/a2r.h": "./a2r.h", 20 | "lib/external/applesauce.h": "./applesauce.h", 21 | "lib/external/catweasel.h": "./catweasel.h", 22 | "lib/external/csvreader.h": "./csvreader.h", 23 | "lib/external/fl2.h": "./fl2.h", 24 | "lib/external/flx.h": "./flx.h", 25 | "lib/external/greaseweazle.h": "./greaseweazle.h", 26 | "lib/external/kryoflux.h": "./kryoflux.h", 27 | "lib/external/ldbs.h": "./ldbs.h", 28 | "lib/external/scp.h": "./scp.h", 29 | }, 30 | deps=["lib/core", ".+fl2_proto_lib", "lib/data"], 31 | ) 32 | -------------------------------------------------------------------------------- /lib/external/catweasel.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/data/fluxmap.h" 3 | #include "lib/core/bytes.h" 4 | #include "lib/external/catweasel.h" 5 | 6 | std::unique_ptr decodeCatweaselData( 7 | const Bytes& bytes, nanoseconds_t clock) 8 | { 9 | std::unique_ptr fluxmap(new Fluxmap); 10 | uint32_t pending = 0; 11 | bool oldindex = true; 12 | const uint8_t* ptr = bytes.begin(); 13 | while (ptr != bytes.end()) 14 | { 15 | uint32_t b = *ptr++; 16 | bool index = !!(b & 0x80); 17 | b &= 0x7f; 18 | if (b == 0x7f) 19 | { 20 | pending += 0x7f; 21 | continue; 22 | } 23 | b += pending; 24 | pending = 0; 25 | 26 | double interval_ns = b * clock; 27 | fluxmap->appendInterval(interval_ns / NS_PER_TICK); 28 | fluxmap->appendPulse(); 29 | 30 | if (index && !oldindex) 31 | fluxmap->appendIndex(); 32 | oldindex = index; 33 | } 34 | 35 | return fluxmap; 36 | } 37 | -------------------------------------------------------------------------------- /lib/external/catweasel.h: -------------------------------------------------------------------------------- 1 | #ifndef CATWEASEL_H 2 | #define CATWEASEL_H 3 | 4 | class Fluxmap; 5 | class Bytes; 6 | 7 | extern std::unique_ptr decodeCatweaselData( 8 | const Bytes& bytes, nanoseconds_t clock); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /lib/external/csvreader.h: -------------------------------------------------------------------------------- 1 | #ifndef CSVREADER_H 2 | #define CSVREADER_H 3 | 4 | #include 5 | 6 | class CsvReader 7 | { 8 | public: 9 | CsvReader(std::istream& istream): _istream(istream) {} 10 | 11 | std::vector readLine(); 12 | 13 | private: 14 | std::istream& _istream; 15 | }; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /lib/external/fl2.h: -------------------------------------------------------------------------------- 1 | #ifndef FL2_H 2 | #define FL2_H 3 | 4 | class FluxFileProto; 5 | 6 | extern FluxFileProto loadFl2File(const std::string filename); 7 | extern void saveFl2File(const std::string filename, FluxFileProto& proto); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /lib/external/fl2.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | enum FluxMagic { 4 | MAGIC = 0x466c7578; 5 | } 6 | 7 | enum FluxFileVersion { 8 | VERSION_1 = 1; 9 | VERSION_2 = 2; 10 | } 11 | 12 | message TrackFluxProto { 13 | optional int32 track = 1; 14 | optional int32 head = 2; 15 | repeated bytes flux = 3; 16 | } 17 | 18 | enum DriveType { 19 | DRIVETYPE_UNKNOWN = 0; 20 | DRIVETYPE_40TRACK = 1; 21 | DRIVETYPE_80TRACK = 2; 22 | DRIVETYPE_APPLE2 = 3; 23 | } 24 | 25 | enum FormatType { 26 | FORMATTYPE_UNKNOWN = 0; 27 | FORMATTYPE_40TRACK = 1; 28 | FORMATTYPE_80TRACK = 2; 29 | } 30 | 31 | // NEXT: 8 32 | message FluxFileProto { 33 | optional int32 magic = 1; 34 | optional FluxFileVersion version = 2; 35 | repeated TrackFluxProto track = 3; 36 | optional double rotational_period_ms = 4; 37 | optional DriveType drive_type = 6 [default = DRIVETYPE_UNKNOWN]; 38 | optional FormatType format_type = 7 [default = FORMATTYPE_UNKNOWN]; 39 | 40 | reserved 5; 41 | } 42 | 43 | -------------------------------------------------------------------------------- /lib/external/flx.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/data/fluxmap.h" 3 | #include "lib/external/kryoflux.h" 4 | #include "protocol.h" 5 | #include "lib/external/flx.h" 6 | 7 | std::unique_ptr readFlxBytes(const Bytes& bytes) 8 | { 9 | ByteReader br(bytes); 10 | 11 | /* Skip header. */ 12 | 13 | for (;;) 14 | { 15 | if (br.eof()) 16 | error("malformed FLX stream"); 17 | uint8_t b = br.read_8(); 18 | if (b == 0) 19 | break; 20 | } 21 | 22 | auto fluxmap = std::make_unique(); 23 | while (!br.eof()) 24 | { 25 | uint8_t b = br.read_8(); 26 | switch (b) 27 | { 28 | case FLX_INDEX: 29 | fluxmap->appendIndex(); 30 | continue; 31 | 32 | case FLX_STOP: 33 | goto stop; 34 | 35 | default: 36 | { 37 | if (b < 32) 38 | error("unknown FLX opcode 0x{:2x}", b); 39 | nanoseconds_t interval = b * FLX_TICK_NS; 40 | fluxmap->appendInterval(interval / NS_PER_TICK); 41 | fluxmap->appendPulse(); 42 | break; 43 | } 44 | } 45 | } 46 | stop: 47 | 48 | return fluxmap; 49 | } 50 | -------------------------------------------------------------------------------- /lib/external/flx.h: -------------------------------------------------------------------------------- 1 | #ifndef FLX_H 2 | #define FLX_H 3 | 4 | #define FLX_TICK_NS 40 /* ns per tick */ 5 | 6 | /* Special FLX opcodes */ 7 | 8 | enum 9 | { 10 | FLX_INDEX = 0x08, 11 | FLX_STOP = 0x0d 12 | }; 13 | 14 | extern std::unique_ptr readFlxBytes(const Bytes& bytes); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /lib/external/kryoflux.h: -------------------------------------------------------------------------------- 1 | #ifndef STREAM_H 2 | #define STREAM_H 3 | 4 | extern std::unique_ptr readStream( 5 | std::string dir, unsigned track, unsigned side); 6 | extern std::unique_ptr readStream(const std::string& path); 7 | extern std::unique_ptr readStream(const Bytes& bytes); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /lib/external/ldbs.h: -------------------------------------------------------------------------------- 1 | #ifndef LDBS_H 2 | #define LDBS_H 3 | 4 | class Bytes; 5 | 6 | /* A very simple interface to John Elliott's LDBS image format: 7 | * http://www.seasip.info/Unix/LibDsk/ldbs.html 8 | */ 9 | 10 | #define LDBS_FILE_MAGIC 0x4C425301 /* "LBS\01" */ 11 | #define LDBS_FILE_TYPE 0x44534B02 /* "DSK\02" */ 12 | #define LDBS_BLOCK_MAGIC 0x4C444201 /* "LDB\01" */ 13 | #define LDBS_TRACK_BLOCK 0x44495201 /* "DIR\01" */ 14 | 15 | class LDBS 16 | { 17 | public: 18 | LDBS(); 19 | 20 | public: 21 | const Bytes& get(uint32_t address) const 22 | { 23 | return blocks.at(address).data; 24 | } 25 | 26 | uint32_t put(const Bytes& data, uint32_t type); 27 | 28 | public: 29 | const Bytes write(uint32_t trackDirectory); 30 | uint32_t read(const Bytes& bytes); 31 | 32 | private: 33 | struct Block 34 | { 35 | uint32_t type; 36 | Bytes data; 37 | }; 38 | 39 | std::map blocks; 40 | unsigned top = 20; 41 | }; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /lib/fluxsink/build.py: -------------------------------------------------------------------------------- 1 | from build.protobuf import proto, protocc 2 | from build.c import cxxlibrary 3 | 4 | proto(name="proto", srcs=["./fluxsink.proto"], deps=["lib/config+common_proto"]) 5 | protocc( 6 | name="proto_lib", srcs=[".+proto"], deps=["lib/config+common_proto_lib"] 7 | ) 8 | 9 | cxxlibrary( 10 | name="fluxsink", 11 | srcs=[ 12 | "./a2rfluxsink.cc", 13 | "./aufluxsink.cc", 14 | "./fl2fluxsink.cc", 15 | "./fluxsink.cc", 16 | "./hardwarefluxsink.cc", 17 | "./scpfluxsink.cc", 18 | "./vcdfluxsink.cc", 19 | ], 20 | hdrs={"lib/fluxsink/fluxsink.h": "./fluxsink.h"}, 21 | deps=["lib/core", "lib/config", "lib/data", "lib/external", "lib/usb"], 22 | ) 23 | -------------------------------------------------------------------------------- /lib/fluxsink/fluxsink.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/config/flags.h" 3 | #include "lib/config/config.h" 4 | #include "lib/fluxsink/fluxsink.h" 5 | #include "lib/config/config.pb.h" 6 | #include "lib/config/proto.h" 7 | #include "lib/core/utils.h" 8 | #include 9 | 10 | std::unique_ptr FluxSink::create(Config& config) 11 | { 12 | if (!config.hasFluxSink()) 13 | error("no flux sink configured"); 14 | return create(config->flux_sink()); 15 | } 16 | 17 | std::unique_ptr FluxSink::create(const FluxSinkProto& config) 18 | { 19 | switch (config.type()) 20 | { 21 | case FLUXTYPE_DRIVE: 22 | return createHardwareFluxSink(config.drive()); 23 | 24 | case FLUXTYPE_A2R: 25 | return createA2RFluxSink(config.a2r()); 26 | 27 | case FLUXTYPE_AU: 28 | return createAuFluxSink(config.au()); 29 | 30 | case FLUXTYPE_VCD: 31 | return createVcdFluxSink(config.vcd()); 32 | 33 | case FLUXTYPE_SCP: 34 | return createScpFluxSink(config.scp()); 35 | 36 | case FLUXTYPE_FLUX: 37 | return createFl2FluxSink(config.fl2()); 38 | 39 | default: 40 | return std::unique_ptr(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/fluxsource/build.py: -------------------------------------------------------------------------------- 1 | from build.protobuf import proto, protocc 2 | from build.c import cxxlibrary 3 | 4 | proto( 5 | name="proto", srcs=["./fluxsource.proto"], deps=["lib/config+common_proto"] 6 | ) 7 | 8 | protocc( 9 | name="proto_lib", 10 | srcs=[".+proto"], 11 | deps=["lib/config+common_proto", "lib/config+common_proto_lib"], 12 | ) 13 | 14 | cxxlibrary( 15 | name="fluxsource", 16 | srcs=[ 17 | "./a2rfluxsource.cc", 18 | "./cwffluxsource.cc", 19 | "./dmkfluxsource.cc", 20 | "./erasefluxsource.cc", 21 | "./fl2fluxsource.cc", 22 | "./fluxsource.cc", 23 | "./flxfluxsource.cc", 24 | "./hardwarefluxsource.cc", 25 | "./kryofluxfluxsource.cc", 26 | "./memoryfluxsource.cc", 27 | "./scpfluxsource.cc", 28 | "./testpatternfluxsource.cc", 29 | ], 30 | hdrs={"lib/fluxsource/fluxsource.h": "./fluxsource.h"}, 31 | deps=["lib/core", "lib/data", "lib/external", "lib/usb", ".+proto_lib"], 32 | ) 33 | -------------------------------------------------------------------------------- /lib/fluxsource/erasefluxsource.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/data/fluxmap.h" 3 | #include "lib/fluxsource/fluxsource.h" 4 | #include "lib/fluxsource/fluxsource.pb.h" 5 | 6 | class EraseFluxSource : public TrivialFluxSource 7 | { 8 | public: 9 | EraseFluxSource(const EraseFluxSourceProto& config) {} 10 | ~EraseFluxSource() {} 11 | 12 | public: 13 | std::unique_ptr readSingleFlux(int track, int side) override 14 | { 15 | return std::unique_ptr(); 16 | } 17 | 18 | void recalibrate() override {} 19 | }; 20 | 21 | std::unique_ptr FluxSource::createEraseFluxSource( 22 | const EraseFluxSourceProto& config) 23 | { 24 | return std::make_unique(config); 25 | } 26 | -------------------------------------------------------------------------------- /lib/fluxsource/flxfluxsource.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/data/fluxmap.h" 3 | #include "lib/fluxsource/fluxsource.pb.h" 4 | #include "lib/fluxsource/fluxsource.h" 5 | #include "lib/external/flx.h" 6 | 7 | class FlxFluxSource : public TrivialFluxSource 8 | { 9 | public: 10 | FlxFluxSource(const FlxFluxSourceProto& config): _path(config.directory()) 11 | { 12 | } 13 | 14 | public: 15 | std::unique_ptr readSingleFlux(int track, int side) override 16 | { 17 | std::string path = 18 | fmt::format("{}/@TR{:02}S{}@.FLX", _path, track, side + 1); 19 | return readFlxBytes(Bytes::readFromFile(path)); 20 | } 21 | 22 | void recalibrate() override {} 23 | 24 | private: 25 | const std::string _path; 26 | }; 27 | 28 | std::unique_ptr FluxSource::createFlxFluxSource( 29 | const FlxFluxSourceProto& config) 30 | { 31 | return std::make_unique(config); 32 | } 33 | -------------------------------------------------------------------------------- /lib/fluxsource/kryofluxfluxsource.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/data/fluxmap.h" 3 | #include "lib/external/kryoflux.h" 4 | #include "lib/fluxsource/fluxsource.pb.h" 5 | #include "lib/fluxsource/fluxsource.h" 6 | 7 | class KryofluxFluxSource : public TrivialFluxSource 8 | { 9 | public: 10 | KryofluxFluxSource(const KryofluxFluxSourceProto& config): 11 | _path(config.directory()) 12 | { 13 | } 14 | 15 | public: 16 | std::unique_ptr readSingleFlux(int track, int side) override 17 | { 18 | return readStream(_path, track, side); 19 | } 20 | 21 | void recalibrate() override {} 22 | 23 | private: 24 | const std::string _path; 25 | }; 26 | 27 | std::unique_ptr FluxSource::createKryofluxFluxSource( 28 | const KryofluxFluxSourceProto& config) 29 | { 30 | return std::make_unique(config); 31 | } 32 | -------------------------------------------------------------------------------- /lib/fluxsource/testpatternfluxsource.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/data/fluxmap.h" 3 | #include "lib/fluxsource/fluxsource.h" 4 | #include "lib/fluxsource/fluxsource.pb.h" 5 | 6 | class TestPatternFluxSource : public TrivialFluxSource 7 | { 8 | public: 9 | TestPatternFluxSource(const TestPatternFluxSourceProto& config): 10 | _config(config) 11 | { 12 | } 13 | 14 | ~TestPatternFluxSource() {} 15 | 16 | public: 17 | std::unique_ptr readSingleFlux(int track, int side) override 18 | { 19 | auto fluxmap = std::make_unique(); 20 | 21 | while (fluxmap->duration() < (_config.sequence_length_ms() * 1e6)) 22 | { 23 | fluxmap->appendInterval(_config.interval_us() * TICKS_PER_US); 24 | fluxmap->appendPulse(); 25 | } 26 | 27 | return fluxmap; 28 | } 29 | 30 | void recalibrate() override {} 31 | 32 | private: 33 | const TestPatternFluxSourceProto& _config; 34 | }; 35 | 36 | std::unique_ptr FluxSource::createTestPatternFluxSource( 37 | const TestPatternFluxSourceProto& config) 38 | { 39 | return std::make_unique(config); 40 | } 41 | -------------------------------------------------------------------------------- /lib/imagereader/build.py: -------------------------------------------------------------------------------- 1 | from build.protobuf import proto, protocc 2 | from build.c import cxxlibrary 3 | 4 | proto( 5 | name="proto", 6 | srcs=["./imagereader.proto"], 7 | deps=["lib/config+common_proto"], 8 | ) 9 | protocc( 10 | name="proto_lib", 11 | srcs=[".+proto"], 12 | deps=["lib/config+common_proto_lib"], 13 | ) 14 | 15 | cxxlibrary( 16 | name="imagereader", 17 | srcs=[ 18 | "./d64imagereader.cc", 19 | "./d88imagereader.cc", 20 | "./dimimagereader.cc", 21 | "./diskcopyimagereader.cc", 22 | "./fdiimagereader.cc", 23 | "./imagereader.cc", 24 | "./imdimagereader.cc", 25 | "./imgimagereader.cc", 26 | "./jv3imagereader.cc", 27 | "./nfdimagereader.cc", 28 | "./nsiimagereader.cc", 29 | "./td0imagereader.cc", 30 | ], 31 | hdrs={"lib/imagereader/imagereader.h": "./imagereader.h"}, 32 | deps=["lib/core", "lib/config", "lib/data", ".+proto_lib"], 33 | ) 34 | -------------------------------------------------------------------------------- /lib/imagereader/imagereader.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "lib/config/common.proto"; 4 | 5 | message ImgInputOutputProto {} 6 | 7 | message DiskCopyInputProto {} 8 | message ImdInputProto {} 9 | message Jv3InputProto {} 10 | message D64InputProto {} 11 | message NsiInputProto {} 12 | message Td0InputProto {} 13 | message DimInputProto {} 14 | message FdiInputProto {} 15 | message D88InputProto {} 16 | message NfdInputProto {} 17 | 18 | // NEXT_TAG: 15 19 | message ImageReaderProto 20 | { 21 | optional string filename = 1 [ (help) = "filename of input sector image" ]; 22 | optional bool filesystem_sector_order = 13 [ 23 | (help) = "read/write sector image in filesystem order", 24 | default = false 25 | ]; 26 | 27 | optional ImageReaderWriterType type = 14 28 | [default = IMAGETYPE_NOT_SET, (help) = "input image type"]; 29 | 30 | optional ImgInputOutputProto img = 2; 31 | optional DiskCopyInputProto diskcopy = 3; 32 | optional ImdInputProto imd = 4; 33 | optional Jv3InputProto jv3 = 5; 34 | optional D64InputProto d64 = 6; 35 | optional NsiInputProto nsi = 7; 36 | optional Td0InputProto td0 = 8; 37 | optional DimInputProto dim = 9; 38 | optional FdiInputProto fdi = 10; 39 | optional D88InputProto d88 = 11; 40 | optional NfdInputProto nfd = 12; 41 | } 42 | -------------------------------------------------------------------------------- /lib/imagewriter/build.py: -------------------------------------------------------------------------------- 1 | from build.protobuf import proto, protocc 2 | from build.c import cxxlibrary 3 | 4 | proto( 5 | name="proto", 6 | srcs=["./imagewriter.proto"], 7 | deps=["lib/config+common_proto", "lib/imagereader+proto"], 8 | ) 9 | protocc( 10 | name="proto_lib", 11 | srcs=[".+proto"], 12 | deps=["lib/config+common_proto_lib", "lib/imagereader+proto_lib"], 13 | ) 14 | 15 | cxxlibrary( 16 | name="imagewriter", 17 | srcs=[ 18 | "./d64imagewriter.cc", 19 | "./d88imagewriter.cc", 20 | "./diskcopyimagewriter.cc", 21 | "./imagewriter.cc", 22 | "./imdimagewriter.cc", 23 | "./imgimagewriter.cc", 24 | "./ldbsimagewriter.cc", 25 | "./nsiimagewriter.cc", 26 | "./rawimagewriter.cc", 27 | ], 28 | hdrs={ 29 | "lib/imagewriter/imagewriter.h": "./imagewriter.h", 30 | }, 31 | deps=["lib/core", "lib/data", "lib/external", ".+proto_lib"], 32 | ) 33 | -------------------------------------------------------------------------------- /lib/usb/build.py: -------------------------------------------------------------------------------- 1 | from build.protobuf import proto, protocc 2 | from build.c import cxxlibrary 3 | 4 | proto(name="proto", srcs=["./usb.proto"], deps=["lib/config+common_proto"]) 5 | protocc( 6 | name="proto_lib", srcs=[".+proto"], deps=["lib/config+common_proto_lib"] 7 | ) 8 | 9 | cxxlibrary( 10 | name="usb", 11 | srcs=[ 12 | "./applesauceusb.cc", 13 | "./fluxengineusb.cc", 14 | "./greaseweazleusb.cc", 15 | "./serial.cc", 16 | "./usb.cc", 17 | "./usbfinder.cc", 18 | ], 19 | hdrs={"lib/usb/usb.h": "./usb.h", "lib/usb/usbfinder.h": "./usbfinder.h", "lib/usb/serial.h": "./serial.h"}, 20 | deps=["lib/core", "lib/config", "lib/external", "dep/libusbp", "+protocol"], 21 | ) 22 | -------------------------------------------------------------------------------- /lib/usb/serial.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIAL_H 2 | #define SERIAL_H 3 | 4 | class SerialPort 5 | { 6 | public: 7 | static std::unique_ptr openSerialPort(const std::string& path); 8 | 9 | public: 10 | virtual ~SerialPort(); 11 | virtual ssize_t readImpl(uint8_t* buffer, size_t len) = 0; 12 | virtual ssize_t write(const uint8_t* buffer, size_t len) = 0; 13 | virtual void setBaudRate(int baudRate) = 0; 14 | virtual void toggleDtr() = 0; 15 | 16 | void read(uint8_t* buffer, size_t len); 17 | void read(Bytes& bytes); 18 | Bytes readBytes(size_t count); 19 | uint8_t readByte(); 20 | void writeByte(uint8_t b); 21 | void write(const Bytes& bytes); 22 | 23 | void writeLine(const std::string& chars); 24 | std::string readLine(); 25 | 26 | private: 27 | uint8_t _readbuffer[4096]; 28 | size_t _readbuffer_ptr = 0; 29 | size_t _readbuffer_fill = 0; 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /lib/usb/usb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "lib/config/common.proto"; 4 | 5 | message GreaseweazleProto { 6 | enum BusType { /* note that these must match CMD_SET_BUS codes */ 7 | BUSTYPE_INVALID = 0; 8 | IBMPC = 1; 9 | SHUGART = 2; 10 | APPLE2 = 3; 11 | }; 12 | 13 | optional string port = 1 14 | [(help) = "Greaseweazle serial port to use"]; 15 | optional BusType bus_type = 2 16 | [(help) = "which FDD bus type is in use", default = IBMPC]; 17 | } 18 | 19 | message ApplesauceProto { 20 | optional string port = 1 21 | [(help) = "Applesauce serial port to use"]; 22 | optional bool verbose = 2 23 | [(help) = "Enable verbose protocol logging", default = false]; 24 | } 25 | 26 | message UsbProto { 27 | optional string serial = 1 28 | [(help) = "serial number of FluxEngine or Greaseweazle device to use"]; 29 | 30 | optional GreaseweazleProto greaseweazle = 2 [(help) = "Greaseweazle-specific options"]; 31 | optional ApplesauceProto applesauce = 3 [(help) = "Applesauce-specific options"]; 32 | } 33 | -------------------------------------------------------------------------------- /lib/usb/usbfinder.h: -------------------------------------------------------------------------------- 1 | #ifndef USBSERIAL_H 2 | #define USBSERIAL_H 3 | 4 | #include "libusbp_config.h" 5 | #include "libusbp.hpp" 6 | 7 | enum DeviceType 8 | { 9 | DEVICE_FLUXENGINE, 10 | DEVICE_GREASEWEAZLE, 11 | DEVICE_APPLESAUCE, 12 | }; 13 | 14 | extern std::string getDeviceName(DeviceType type); 15 | 16 | struct CandidateDevice 17 | { 18 | DeviceType type; 19 | libusbp::device device; 20 | uint32_t id; 21 | std::string serial; 22 | std::string serialPort; 23 | }; 24 | 25 | extern std::vector> findUsbDevices(); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /lib/vfs/applesingle.h: -------------------------------------------------------------------------------- 1 | #ifndef APPLESINGLE_H 2 | #define APPLESINGLE_H 3 | 4 | class AppleSingleException 5 | { 6 | }; 7 | 8 | class InvalidFileException : public AppleSingleException 9 | { 10 | }; 11 | 12 | class AppleSingle 13 | { 14 | public: 15 | static constexpr uint32_t OVERHEAD = 0x5e; 16 | 17 | public: 18 | void parse(const Bytes& combined); 19 | Bytes render(); 20 | 21 | public: 22 | Bytes data; 23 | Bytes rsrc; 24 | Bytes creator; 25 | Bytes type; 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /lib/vfs/sectorinterface.h: -------------------------------------------------------------------------------- 1 | #ifndef SECTORINTERFACE_H 2 | #define SECTORINTERFACE_H 3 | 4 | class ImageReader; 5 | class ImageWriter; 6 | class Sector; 7 | class FluxSource; 8 | class FluxSink; 9 | class Decoder; 10 | class Encoder; 11 | 12 | class SectorInterface 13 | { 14 | public: 15 | virtual ~SectorInterface() {} 16 | 17 | public: 18 | virtual std::shared_ptr get( 19 | unsigned track, unsigned side, unsigned sectorId) = 0; 20 | virtual std::shared_ptr put( 21 | unsigned track, unsigned side, unsigned sectorId) = 0; 22 | 23 | virtual bool isReadOnly() 24 | { 25 | return true; 26 | } 27 | 28 | virtual bool needsFlushing() 29 | { 30 | return false; 31 | } 32 | 33 | virtual void flushChanges() {} 34 | 35 | virtual void discardChanges() {} 36 | 37 | public: 38 | static std::unique_ptr createImageSectorInterface( 39 | std::shared_ptr reader, 40 | std::shared_ptr writer); 41 | static std::unique_ptr createFluxSectorInterface( 42 | std::shared_ptr fluxSource, 43 | std::shared_ptr fluxSink, 44 | std::shared_ptr encoder, 45 | std::shared_ptr decoder); 46 | }; 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /scripts/analysedriveresponse.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | import matplotlib.pyplot as plt 3 | import matplotlib.animation as animation 4 | 5 | TICK_FREQUENCY = 12e6 6 | TICKS_PER_US = TICK_FREQUENCY / 1e6 7 | print(TICKS_PER_US) 8 | 9 | # Load data. 10 | data = numpy.loadtxt(open("driveresponse.csv", "rb"), delimiter=",", skiprows=1) 11 | 12 | labels = data[:, 0] 13 | frequencies = data[:, 1:] 14 | 15 | 16 | # Scale the frequencies. 17 | def scaled(row): 18 | m = row.mean() 19 | if m != 0: 20 | return row / m 21 | else: 22 | return row 23 | 24 | 25 | scaledfreq = numpy.array([scaled(row) for row in frequencies]) 26 | 27 | # Create new Figure with black background 28 | fig = plt.figure(figsize=(8, 8), facecolor="#aaa") 29 | 30 | plt.imshow( 31 | scaledfreq, 32 | extent=[0, 512 / TICKS_PER_US, labels[0], labels[-1]], 33 | cmap="jet", 34 | vmin=0, 35 | vmax=1, 36 | origin="lower", 37 | aspect="auto", 38 | ) 39 | plt.colorbar() 40 | plt.ylabel("Interval period (us)") 41 | plt.xlabel("Response (us)") 42 | plt.grid(True, dashes=(2, 2)) 43 | plt.show() 44 | 45 | plt.show() 46 | -------------------------------------------------------------------------------- /scripts/commodore1541_test.textpb: -------------------------------------------------------------------------------- 1 | image_reader { 2 | d64 {} 3 | } 4 | 5 | image_writer { 6 | d64 {} 7 | } 8 | 9 | -------------------------------------------------------------------------------- /scripts/encodedecodetest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | format="$1" 5 | ext="$2" 6 | fluxengine="$3" 7 | script="$4" 8 | flags="$5" 9 | dir="$6" 10 | 11 | srcfile=$dir/src.img 12 | fluxfile=$dir/flux.$ext 13 | destfile=$dir/dest.img 14 | 15 | dd if=/dev/urandom of=$srcfile bs=1048576 count=2 2>&1 16 | 17 | echo $fluxengine write $format -i $srcfile -d $fluxfile --drive.rotational_period_ms=200 $flags 18 | $fluxengine write $format -i $srcfile -d $fluxfile --drive.rotational_period_ms=200 $flags 19 | echo $fluxengine read $format -s $fluxfile -o $destfile --drive.rotational_period_ms=200 $flags 20 | $fluxengine read $format -s $fluxfile -o $destfile --drive.rotational_period_ms=200 $flags 21 | if [ ! -s $destfile ]; then 22 | echo "Zero length output file!" >&2 23 | exit 1 24 | fi 25 | 26 | truncate -r $destfile $srcfile 27 | if ! cmp $srcfile $destfile; then 28 | echo "Comparison failed!" >&2 29 | echo "Run this to repeat:" >&2 30 | echo "./scripts/encodedecodetest.sh \"$1\" \"$2\" \"$3\" \"$4\" \"$5\" \"$6\"" >&2 31 | exit 1 32 | fi 33 | exit 0 34 | 35 | -------------------------------------------------------------------------------- /scripts/mac400_test.textpb: -------------------------------------------------------------------------------- 1 | image_reader { 2 | img {} 3 | } 4 | 5 | image_writer { 6 | img {} 7 | } 8 | -------------------------------------------------------------------------------- /scripts/mac800_test.textpb: -------------------------------------------------------------------------------- 1 | image_reader { 2 | img {} 3 | } 4 | 5 | image_writer { 6 | img {} 7 | } 8 | 9 | 10 | -------------------------------------------------------------------------------- /scripts/mktable.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "#include " 3 | echo "#include " 4 | echo "class ConfigProto;" 5 | 6 | word=$1 7 | shift 8 | 9 | for a in "$@"; do 10 | echo "extern const ConfigProto ${word}_${a}_pb;" 11 | done 12 | 13 | echo "extern const std::map ${word};" 14 | echo "const std::map ${word} = {" 15 | for a in "$@"; do 16 | echo " { \"${a}\", &${word}_${a}_pb }," 17 | done 18 | echo "};" 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/fe-format.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/config/flags.h" 3 | #include "lib/data/fluxmap.h" 4 | #include "lib/data/sector.h" 5 | #include "lib/config/proto.h" 6 | #include "lib/imagereader/imagereader.h" 7 | #include "lib/imagewriter/imagewriter.h" 8 | #include "lib/fluxsource/fluxsource.h" 9 | #include "lib/decoders/decoders.h" 10 | #include "fluxengine.h" 11 | #include "lib/vfs/sectorinterface.h" 12 | #include "lib/vfs/vfs.h" 13 | #include "src/fileutils.h" 14 | #include 15 | #include 16 | 17 | static FlagGroup flags({&fileFlags}); 18 | 19 | static StringFlag volumeName({"-n", "--name"}, "volume name", "FluxEngine"); 20 | static SettableFlag quick({"-q", "--quick"}, 21 | "perform quick format (requires the disk to be previously formatted)"); 22 | 23 | int mainFormat(int argc, const char* argv[]) 24 | { 25 | if (argc == 1) 26 | showProfiles("format", formats); 27 | flags.parseFlagsWithConfigFiles(argc, argv, formats); 28 | 29 | try 30 | { 31 | auto filesystem = Filesystem::createFilesystemFromConfig(); 32 | filesystem->create(quick, volumeName); 33 | filesystem->flushChanges(); 34 | } 35 | catch (const FilesystemException& e) 36 | { 37 | error("{}", e.message); 38 | } 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /src/fe-getdiskinfo.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/config/flags.h" 3 | #include "lib/data/fluxmap.h" 4 | #include "lib/data/sector.h" 5 | #include "lib/config/proto.h" 6 | #include "lib/imagereader/imagereader.h" 7 | #include "lib/imagewriter/imagewriter.h" 8 | #include "lib/fluxsource/fluxsource.h" 9 | #include "lib/decoders/decoders.h" 10 | #include "fluxengine.h" 11 | #include "lib/vfs/sectorinterface.h" 12 | #include "lib/vfs/vfs.h" 13 | #include "lib/core/utils.h" 14 | #include "src/fileutils.h" 15 | #include 16 | #include 17 | 18 | static FlagGroup flags({&fileFlags}); 19 | 20 | int mainGetDiskInfo(int argc, const char* argv[]) 21 | { 22 | if (argc == 1) 23 | showProfiles("getdiskinfo", formats); 24 | flags.parseFlagsWithConfigFiles(argc, argv, formats); 25 | 26 | try 27 | { 28 | auto filesystem = Filesystem::createFilesystemFromConfig(); 29 | auto attributes = filesystem->getMetadata(); 30 | 31 | for (const auto& e : attributes) 32 | fmt::print("{}={}\n", e.first, quote(e.second)); 33 | } 34 | catch (const FilesystemException& e) 35 | { 36 | error("{}", e.message); 37 | } 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /src/fe-getfileinfo.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/config/flags.h" 3 | #include "lib/data/fluxmap.h" 4 | #include "lib/data/sector.h" 5 | #include "lib/config/proto.h" 6 | #include "lib/imagereader/imagereader.h" 7 | #include "lib/imagewriter/imagewriter.h" 8 | #include "lib/fluxsource/fluxsource.h" 9 | #include "lib/decoders/decoders.h" 10 | #include "fluxengine.h" 11 | #include "lib/vfs/sectorinterface.h" 12 | #include "lib/vfs/vfs.h" 13 | #include "lib/core/utils.h" 14 | #include "src/fileutils.h" 15 | #include 16 | #include 17 | 18 | static FlagGroup flags({&fileFlags}); 19 | 20 | static StringFlag directory({"-p", "--path"}, "path to work on", ""); 21 | 22 | int mainGetFileInfo(int argc, const char* argv[]) 23 | { 24 | if (argc == 1) 25 | showProfiles("getfileinfo", formats); 26 | flags.parseFlagsWithConfigFiles(argc, argv, formats); 27 | 28 | try 29 | { 30 | auto filesystem = Filesystem::createFilesystemFromConfig(); 31 | auto dirent = filesystem->getDirent(Path(directory)); 32 | 33 | for (const auto& e : dirent->attributes) 34 | fmt::print("{}={}\n", e.first, quote(e.second)); 35 | } 36 | catch (const FilesystemException& e) 37 | { 38 | error("{}", e.message); 39 | } 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /src/fe-mkdir.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/config/flags.h" 3 | #include "lib/config/proto.h" 4 | #include "fluxengine.h" 5 | #include "lib/vfs/vfs.h" 6 | #include "lib/core/utils.h" 7 | #include "src/fileutils.h" 8 | #include 9 | #include 10 | 11 | static FlagGroup flags({&fileFlags}); 12 | 13 | static StringFlag filename({"-p", "--path"}, "directory to create", ""); 14 | 15 | int mainMkDir(int argc, const char* argv[]) 16 | { 17 | if (argc == 1) 18 | showProfiles("mkdir", formats); 19 | flags.parseFlagsWithConfigFiles(argc, argv, formats); 20 | 21 | try 22 | { 23 | auto filesystem = Filesystem::createFilesystemFromConfig(); 24 | 25 | Path path(filename); 26 | if (path.size() == 0) 27 | error("filename missing"); 28 | 29 | filesystem->createDirectory(path); 30 | filesystem->flushChanges(); 31 | } 32 | catch (const FilesystemException& e) 33 | { 34 | error("{}", e.message); 35 | } 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /src/fe-mv.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/config/flags.h" 3 | #include "lib/config/proto.h" 4 | #include "fluxengine.h" 5 | #include "lib/vfs/vfs.h" 6 | #include "lib/core/utils.h" 7 | #include "src/fileutils.h" 8 | #include 9 | #include 10 | 11 | static FlagGroup flags({&fileFlags}); 12 | 13 | static StringFlag oldFilename({"--path1"}, "old filename", ""); 14 | static StringFlag newFilename({"--path2"}, "new filename", ""); 15 | 16 | int mainMv(int argc, const char* argv[]) 17 | { 18 | if (argc == 1) 19 | showProfiles("mv", formats); 20 | flags.parseFlagsWithConfigFiles(argc, argv, formats); 21 | 22 | try 23 | { 24 | auto filesystem = Filesystem::createFilesystemFromConfig(); 25 | 26 | Path oldPath(oldFilename); 27 | if (oldPath.size() == 0) 28 | error("old filename missing"); 29 | 30 | Path newPath(newFilename); 31 | if (newPath.size() == 0) 32 | error("new filename missing"); 33 | 34 | filesystem->moveFile(oldPath, newPath); 35 | filesystem->flushChanges(); 36 | } 37 | catch (const FilesystemException& e) 38 | { 39 | error("{}", e.message); 40 | } 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /src/fe-rm.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/config/flags.h" 3 | #include "lib/config/proto.h" 4 | #include "fluxengine.h" 5 | #include "lib/vfs/vfs.h" 6 | #include "lib/core/utils.h" 7 | #include "src/fileutils.h" 8 | #include 9 | #include 10 | 11 | static FlagGroup flags({&fileFlags}); 12 | 13 | static StringFlag filename({"-p", "--path"}, "filename to remove", ""); 14 | 15 | int mainRm(int argc, const char* argv[]) 16 | { 17 | if (argc == 1) 18 | showProfiles("rm", formats); 19 | flags.parseFlagsWithConfigFiles(argc, argv, formats); 20 | 21 | try 22 | { 23 | auto filesystem = Filesystem::createFilesystemFromConfig(); 24 | 25 | Path path(filename); 26 | if (path.size() == 0) 27 | error("filename missing"); 28 | 29 | filesystem->deleteFile(path); 30 | filesystem->flushChanges(); 31 | } 32 | catch (const FilesystemException& e) 33 | { 34 | error("{}", e.message); 35 | } 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /src/fe-seek.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/config/config.h" 3 | #include "lib/config/flags.h" 4 | #include "lib/usb/usb.h" 5 | #include "lib/fluxsource/fluxsource.h" 6 | #include "lib/config/proto.h" 7 | #include "protocol.h" 8 | 9 | static FlagGroup flags; 10 | 11 | static StringFlag sourceFlux({"-s", "--source"}, 12 | "'drive:' flux source to use", 13 | "", 14 | [](const auto& value) 15 | { 16 | globalConfig().setFluxSource(value); 17 | }); 18 | 19 | static IntFlag track({"--cylinder", "-c"}, "track to seek to", 0); 20 | 21 | extern const std::map readables; 22 | 23 | int mainSeek(int argc, const char* argv[]) 24 | { 25 | flags.parseFlagsWithConfigFiles(argc, argv, {}); 26 | 27 | if (globalConfig()->flux_source().type() != FLUXTYPE_DRIVE) 28 | error("this only makes sense with a real disk drive"); 29 | 30 | usbSetDrive(globalConfig()->drive().drive(), 31 | false, 32 | globalConfig()->drive().index_mode()); 33 | usbSeek(track); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /src/fe-testbandwidth.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/config/flags.h" 3 | #include "lib/usb/usb.h" 4 | 5 | static FlagGroup flags; 6 | 7 | int mainTestBandwidth(int argc, const char* argv[]) 8 | { 9 | flags.parseFlagsWithConfigFiles(argc, argv, {}); 10 | usbTestBulkWrite(); 11 | usbTestBulkRead(); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /src/fe-testdevices.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/config/flags.h" 3 | #include "lib/usb/usbfinder.h" 4 | #include "fmt/format.h" 5 | 6 | static FlagGroup flags; 7 | 8 | int mainTestDevices(int argc, const char* argv[]) 9 | { 10 | flags.parseFlagsWithConfigFiles(argc, argv, {}); 11 | 12 | auto candidates = findUsbDevices(); 13 | switch (candidates.size()) 14 | { 15 | case 0: 16 | fmt::print("Detected no devices.\n"); 17 | break; 18 | 19 | case 1: 20 | fmt::print("Detected one device:\n"); 21 | break; 22 | 23 | default: 24 | fmt::print("Detected {} devices:\n", candidates.size()); 25 | } 26 | 27 | if (!candidates.empty()) 28 | { 29 | fmt::print( 30 | "{:15} {:30} {}\n", "Type", "Serial number", "Port (if any)"); 31 | for (auto& candidate : candidates) 32 | { 33 | fmt::print("{:15} {:30} {}\n", 34 | getDeviceName(candidate->type), 35 | candidate->serial, 36 | candidate->serialPort); 37 | } 38 | } 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /src/fileutils.h: -------------------------------------------------------------------------------- 1 | #ifndef FILEUTILS_H 2 | #define FILEUTILS_H 3 | 4 | extern FlagGroup fileFlags; 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/fluxengine.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUXENGINE_H 2 | #define FLUXENGINE_H 3 | 4 | extern void showProfiles(const std::string& command, 5 | const std::map& profiles); 6 | 7 | extern const std::map formats; 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/formats/40track_drive.textpb: -------------------------------------------------------------------------------- 1 | comment: 'Adjust configuration for a 40-track drive' 2 | is_extension: true 3 | 4 | documentation: 5 | <<< 6 | This is an extension profile; adding this to the command line will configure 7 | FluxEngine to read from 40-track, 48tpi 5.25" drives. You have to tell it because there is 8 | no way to detect this automatically. 9 | 10 | For example: 11 | 12 | ``` 13 | fluxengine read ibm --180 40track_drive 14 | ``` 15 | >>> 16 | 17 | drive { 18 | tracks: 40 19 | drive_type: DRIVETYPE_40TRACK 20 | } 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/formats/agat.textpb: -------------------------------------------------------------------------------- 1 | shortname: 'Agat' 2 | comment: '840kB 5.25" 80-track DS' 3 | read_support_status: DINOSAUR 4 | write_support_status: DINOSAUR 5 | 6 | documentation: 7 | <<< 8 | The Agat (Russian: Агат) was a series Soviet-era computer, first released about 9 | 1983. These were based around a 6502 and were nominally Apple II-compatible 10 | although with enough differences to be problematic. 11 | 12 | They could use either standard Apple II 140kB disks, or a proprietary 840kb 13 | MFM-based double-sided format. FluxEngine supports both of these; this profile 14 | is for the proprietary format. for the Apple II format, use the `apple2` 15 | profile. 16 | >>> 17 | 18 | documentation: 19 | <<< 20 | ## References 21 | 22 | - [Magazine article on the 23 | Agat](https://sudonull.com/post/54185-Is-AGAT-a-bad-copy-of-Apple) 24 | 25 | - [Forum thread with (some) documentation on the 26 | format](https://torlus.com/floppy/forum/viewtopic.php?t=1385) 27 | >>> 28 | 29 | image_writer { 30 | filename: "agat.img" 31 | type: IMAGETYPE_IMG 32 | } 33 | 34 | layout { 35 | format_type: FORMATTYPE_80TRACK 36 | tracks: 80 37 | sides: 2 38 | layoutdata { 39 | sector_size: 256 40 | physical { 41 | start_sector: 0 42 | count: 21 43 | } 44 | } 45 | } 46 | 47 | decoder { 48 | agat {} 49 | } 50 | 51 | encoder { 52 | agat {} 53 | } 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/formats/apple2_drive.textpb: -------------------------------------------------------------------------------- 1 | comment: 'Adjust configuration for a 40-track Apple II drive' 2 | is_extension: true 3 | 4 | documentation: 5 | <<< 6 | This is an extension profile; adding this to the command line will configure 7 | FluxEngine to adjust the pinout and track spacing to work with an Apple II 8 | drive. This only works on Greaseweazle hardware and requires a custom 9 | connector. 10 | 11 | For example: 12 | 13 | ``` 14 | fluxengine read apple2 --160 apple2_drive 15 | ``` 16 | >>> 17 | 18 | usb { 19 | greaseweazle { 20 | bus_type: APPLE2 21 | } 22 | } 23 | 24 | drive { 25 | tracks: 160 26 | heads: 1 27 | drive_type: DRIVETYPE_APPLE2 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/formats/epsonpf10.textpb: -------------------------------------------------------------------------------- 1 | shortname: 'Epson PF-10' 2 | comment: 'CP/M; 3.5" 40-track DSDD' 3 | read_support_status: DINOSAUR 4 | 5 | documentation: 6 | <<< 7 | The Epson PF10 is the disk unit for the Epson Z80 series of 'laptops', running 8 | CP/M. It uses a single-sided 40-track 3.5" format, which is unusual, but the 9 | format itself is yet another IBM scheme variant. 10 | >>> 11 | 12 | image_writer { 13 | filename: "epsonpf10.img" 14 | type: IMAGETYPE_IMG 15 | } 16 | 17 | layout { 18 | format_type: FORMATTYPE_40TRACK 19 | tracks: 40 20 | sides: 2 21 | layoutdata { 22 | sector_size: 512 23 | physical { 24 | start_sector: 1 25 | count: 9 26 | } 27 | } 28 | } 29 | 30 | decoder { 31 | ibm {} 32 | } 33 | 34 | filesystem { 35 | type: CPMFS 36 | cpmfs { 37 | filesystem_start { 38 | track: 4 39 | } 40 | block_size: 2048 41 | dir_entries: 64 42 | padding { 43 | amount: 1 44 | every: 8 45 | } 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /src/formats/rx50.textpb: -------------------------------------------------------------------------------- 1 | shortname: 'Digital RX50' 2 | comment: '400kB 5.25" 80-track 10-sector SSDD' 3 | read_support_status: DINOSAUR 4 | write_support_status: DINOSAUR 5 | 6 | documentation: 7 | <<< 8 | The Digital RX50 is one of the external floppy drive units used by Digital's 9 | range of computers, especially the DEC Rainbow microcomputer. It is a fairly 10 | vanilla single-sided IBM scheme variation. 11 | >>> 12 | 13 | drive { 14 | high_density: true 15 | } 16 | 17 | image_reader { 18 | filename: "rx50.img" 19 | type: IMAGETYPE_IMG 20 | } 21 | 22 | image_writer { 23 | filename: "rx50.img" 24 | type: IMAGETYPE_IMG 25 | } 26 | 27 | layout { 28 | format_type: FORMATTYPE_80TRACK 29 | tracks: 80 30 | sides: 1 31 | layoutdata { 32 | sector_size: 512 33 | physical { 34 | start_sector: 1 35 | count: 10 36 | } 37 | } 38 | } 39 | 40 | encoder { 41 | ibm { 42 | trackdata { 43 | target_rotational_period_ms: 167 44 | target_clock_period_us: 3.333 45 | gap3: 30 46 | } 47 | } 48 | } 49 | 50 | decoder { 51 | ibm {} 52 | } 53 | 54 | -------------------------------------------------------------------------------- /src/formats/shugart_drive.textpb: -------------------------------------------------------------------------------- 1 | comment: 'Adjust configuration for a Shugart drive' 2 | is_extension: true 3 | 4 | documentation: 5 | <<< 6 | This is an extension profile; adding this to the command line will configure 7 | FluxEngine to adjust the pinout to work with a Shugart drive. This only works 8 | on Greaseweazle hardware. 9 | 10 | For example: 11 | 12 | ``` 13 | fluxengine read ibm --720 shugart_drive 14 | ``` 15 | >>> 16 | 17 | usb { 18 | greaseweazle { 19 | bus_type: SHUGART 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /src/gui/context.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class FluxSource; 4 | class FluxSink; 5 | class ImageReader; 6 | class ImageWriter; 7 | class Encoder; 8 | class Decoder; 9 | 10 | class Context 11 | { 12 | public: 13 | virtual ~Context() {} 14 | 15 | public: 16 | virtual FluxSource* GetFluxSource() = 0; 17 | virtual FluxSource* GetVerificationFluxSource() = 0; 18 | virtual FluxSink* GetFluxSink() = 0; 19 | virtual ImageReader* GetImageReader() = 0; 20 | virtual ImageWriter* GetImageWriter() = 0; 21 | virtual Encoder* GetEncoder() = 0; 22 | virtual Decoder* GetDecoder() = 0; 23 | 24 | static std::unique_ptr Create(); 25 | }; -------------------------------------------------------------------------------- /src/gui/customstatusbar.h: -------------------------------------------------------------------------------- 1 | #ifndef CUSTOMSTATUSBAR_H 2 | #define CUSTOMSTATUSBAR_H 3 | 4 | class wxGauge; 5 | class wxButton; 6 | 7 | wxDECLARE_EVENT(PROGRESSBAR_STOP_EVENT, wxCommandEvent); 8 | 9 | class CustomStatusBar : public wxStatusBar 10 | { 11 | public: 12 | CustomStatusBar(wxWindow* parent, wxWindowID id); 13 | 14 | public: 15 | void ShowProgressBar(); 16 | void HideProgressBar(); 17 | void SetProgress(int amount); 18 | void SetLeftLabel(const std::string& text); 19 | void SetRightLabel(const std::string& text); 20 | 21 | private: 22 | void OnSize(wxSizeEvent& event); 23 | 24 | private: 25 | std::unique_ptr _progressBar; 26 | std::unique_ptr _stopButton; 27 | std::unique_ptr _rightLabel; 28 | 29 | DECLARE_EVENT_TABLE(); 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/gui/drivetypes/40track.textpb: -------------------------------------------------------------------------------- 1 | comment: '8", 5.25" or 3.5" 40 track' 2 | 3 | drive { 4 | drive_type: DRIVETYPE_40TRACK 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/gui/drivetypes/80track.textpb: -------------------------------------------------------------------------------- 1 | comment: '8", 5.25" or 3.5" 80 track' 2 | 3 | drive { 4 | drive_type: DRIVETYPE_80TRACK 5 | } 6 | -------------------------------------------------------------------------------- /src/gui/drivetypes/apple2.textpb: -------------------------------------------------------------------------------- 1 | comment: '5.25" 40-track Apple II drive (Greaseweazle only)' 2 | 3 | usb { 4 | greaseweazle { 5 | bus_type: APPLE2 6 | } 7 | } 8 | 9 | drive { 10 | tracks: 160 11 | heads: 1 12 | drive_type: DRIVETYPE_APPLE2 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/gui/drivetypes/build.py: -------------------------------------------------------------------------------- 1 | from build.ab import simplerule 2 | from build.c import cxxlibrary 3 | from scripts.build import protoencode 4 | 5 | drivetypes = [ 6 | "40track", 7 | "80track", 8 | "apple2", 9 | ] 10 | 11 | simplerule( 12 | name="drivetypes_table_cc", 13 | ins=[f"./{name}.textpb" for name in drivetypes], 14 | deps=["scripts/mktable.sh"], 15 | outs=["=table.cc"], 16 | commands=[ 17 | "sh scripts/mktable.sh drivetypes " 18 | + (" ".join(drivetypes)) 19 | + " > $[outs]" 20 | ], 21 | label="MKTABLE", 22 | ) 23 | 24 | 25 | protoencode( 26 | name="drivetypes_cc", 27 | srcs={name: f"./{name}.textpb" for name in drivetypes}, 28 | proto="ConfigProto", 29 | symbol="drivetypes", 30 | ) 31 | 32 | cxxlibrary( 33 | name="drivetypes", 34 | srcs=[".+drivetypes_cc", ".+drivetypes_table_cc"], 35 | deps=["lib/core", "lib/config"], 36 | ) 37 | -------------------------------------------------------------------------------- /src/gui/filesystemmodel.h: -------------------------------------------------------------------------------- 1 | #ifndef FILESYSTEMMODEL_H 2 | #define FILESYSTEMMODEL_H 3 | 4 | #include 5 | class Dirent; 6 | class Path; 7 | 8 | class FilesystemNode 9 | { 10 | public: 11 | FilesystemNode(std::shared_ptr dirent); 12 | 13 | wxDataViewItem item; 14 | bool populated = false; 15 | bool populating = false; 16 | bool stub = false; 17 | std::shared_ptr dirent; 18 | std::map> children; 19 | 20 | std::string newname; /* used for inline renames */ 21 | }; 22 | 23 | class FilesystemModel : public wxDataViewModel 24 | { 25 | public: 26 | virtual void Clear(const Path& path) = 0; 27 | virtual std::shared_ptr Find(const Path& path) const = 0; 28 | virtual std::shared_ptr Find( 29 | const wxDataViewItem& item) const = 0; 30 | virtual void Delete(const Path& path) = 0; 31 | virtual void RemoveStub(const Path& path) = 0; 32 | virtual void Add(std::shared_ptr dirent) = 0; 33 | 34 | public: 35 | static FilesystemModel* Associate(wxDataViewCtrl* control); 36 | }; 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/gui/fileviewerwindow.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/core/utils.h" 3 | #include "lib/core/bytes.h" 4 | #include "gui.h" 5 | #include "lib/data/layout.h" 6 | #include "fileviewerwindow.h" 7 | 8 | FileViewerWindow::FileViewerWindow( 9 | wxWindow* parent, const std::string& title, const Bytes& data): 10 | FileViewerWindowGen(parent) 11 | { 12 | auto size = hexControl->GetTextExtent("M"); 13 | SetSize(size.Scale(85, 25)); 14 | SetTitle(title); 15 | 16 | { 17 | std::stringstream ss; 18 | hexdump(ss, data); 19 | hexControl->SetValue(ss.str()); 20 | } 21 | 22 | { 23 | std::stringstream ss; 24 | bool nl = false; 25 | for (uint8_t c : data) 26 | { 27 | if ((c == '\r') && nl) 28 | { 29 | nl = false; 30 | continue; 31 | } 32 | 33 | if ((c == '\n') || (c == '\t') || ((c >= 32) && (c <= 126))) 34 | ss << (char)c; 35 | else if (c == '\r') 36 | ss << '\n'; 37 | else 38 | ss << fmt::format("\\x{:02x}", c); 39 | 40 | nl = (c == '\n'); 41 | } 42 | textControl->SetValue(ss.str()); 43 | } 44 | } 45 | 46 | void FileViewerWindow::OnClose(wxCloseEvent& event) 47 | { 48 | Destroy(); 49 | } 50 | -------------------------------------------------------------------------------- /src/gui/fileviewerwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef FILEVIEWERWINDOW_H 2 | #define FILEVIEWERWINDOW_H 3 | 4 | #include "layout.h" 5 | 6 | class FileViewerWindow : public FileViewerWindowGen 7 | { 8 | public: 9 | FileViewerWindow( 10 | wxWindow* parent, const std::string& title, const Bytes& data); 11 | 12 | private: 13 | void OnClose(wxCloseEvent& event); 14 | }; 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/gui/fluxviewerwindow.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "gui.h" 3 | #include "lib/data/layout.h" 4 | #include "fluxviewerwindow.h" 5 | #include "fluxviewercontrol.h" 6 | #include "lib/data/flux.h" 7 | #include "lib/data/layout.h" 8 | 9 | FluxViewerWindow::FluxViewerWindow( 10 | wxWindow* parent, std::shared_ptr flux): 11 | FluxViewerWindowGen(parent), 12 | _flux(flux) 13 | { 14 | fluxviewer->SetScrollbar(scrollbar); 15 | fluxviewer->SetFlux(flux); 16 | SetTitle(fmt::format("Flux for c{} h{}", 17 | flux->trackInfo->physicalTrack, 18 | flux->trackInfo->physicalSide)); 19 | } 20 | 21 | void FluxViewerWindow::OnExit(wxCommandEvent& event) 22 | { 23 | Close(true); 24 | } 25 | -------------------------------------------------------------------------------- /src/gui/fluxviewerwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUXVIEWERWINDOW_H 2 | #define FLUXVIEWERWINDOW_H 3 | 4 | #include "layout.h" 5 | 6 | class TrackFlux; 7 | 8 | class FluxViewerWindow : public FluxViewerWindowGen 9 | { 10 | public: 11 | FluxViewerWindow(wxWindow* parent, std::shared_ptr flux); 12 | 13 | private: 14 | void OnExit(wxCommandEvent& event); 15 | 16 | private: 17 | std::shared_ptr _flux; 18 | }; 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/gui/histogramviewer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "lib/core/globals.h" 4 | #include "lib/data/fluxmap.h" 5 | #include "lib/data/fluxmapreader.h" 6 | 7 | class HistogramViewer : public wxWindow 8 | { 9 | public: 10 | HistogramViewer(wxWindow* parent, 11 | wxWindowID winid, 12 | const wxPoint& pos = wxDefaultPosition, 13 | const wxSize& size = wxDefaultSize, 14 | long style = 0); 15 | virtual ~HistogramViewer() {} 16 | 17 | public: 18 | void Redraw(const Fluxmap& fluxmap, nanoseconds_t clock = 0); 19 | 20 | void Redraw(const Fluxmap* fluxmap, nanoseconds_t clock = 0) 21 | { 22 | Redraw(*fluxmap, clock); 23 | } 24 | 25 | nanoseconds_t GetMedian() const 26 | { 27 | return _data.median; 28 | } 29 | 30 | private: 31 | void OnPaint(wxPaintEvent&); 32 | 33 | private: 34 | bool _blank = true; 35 | FluxmapReader::ClockData _data; 36 | wxFont _font; 37 | nanoseconds_t _clock; 38 | wxDECLARE_EVENT_TABLE(); 39 | }; 40 | -------------------------------------------------------------------------------- /src/gui/iconbutton.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class wxToggleButton; 4 | 5 | class IconButton : public wxPanel 6 | { 7 | public: 8 | IconButton(wxWindow* parent, 9 | wxWindowID id = wxID_ANY, 10 | const wxPoint& pos = wxDefaultPosition, 11 | const wxSize& size = wxDefaultSize, 12 | long style = wxTAB_TRAVERSAL, 13 | const wxString& name = wxPanelNameStr); 14 | 15 | void SetBitmapAndLabel(const wxBitmap bitmap, const std::string text); 16 | void SetSelected(bool selected); 17 | 18 | private: 19 | void OnMouseClick(wxMouseEvent& e); 20 | 21 | private: 22 | wxFlexGridSizer* _sizer; 23 | wxStaticBitmap* _bitmap; 24 | wxStaticText* _text; 25 | bool _selected; 26 | }; 27 | -------------------------------------------------------------------------------- /src/gui/jobqueue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class JobQueue 5 | { 6 | public: 7 | void QueueJob(std::function f); 8 | bool IsQueueEmpty() const; 9 | bool IsQueueRunning(); 10 | 11 | public: 12 | virtual void OnQueueFailed() 13 | { 14 | OnQueueEmpty(); 15 | } 16 | virtual void OnQueueEmpty() {} 17 | 18 | private: 19 | std::deque> _jobQueue; 20 | }; 21 | -------------------------------------------------------------------------------- /src/gui/manifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | FluxEngine 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/gui/texteditorwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef TEXTEDITORWINDOW_H 2 | #define TEXTEDITORWINDOW_H 3 | 4 | #include "layout.h" 5 | 6 | class EditorSaveEvent : public wxEvent 7 | { 8 | public: 9 | EditorSaveEvent(wxEventType eventType, int winId): wxEvent(winId, eventType) 10 | { 11 | } 12 | 13 | wxEvent* Clone() const override 14 | { 15 | return new EditorSaveEvent(*this); 16 | } 17 | 18 | std::string text; 19 | }; 20 | 21 | wxDECLARE_EVENT(EDITOR_SAVE_EVENT, EditorSaveEvent); 22 | 23 | class TextEditorWindow : public TextEditorWindowGen 24 | { 25 | public: 26 | TextEditorWindow( 27 | wxWindow* parent, const std::string& title, const std::string& text); 28 | 29 | static TextEditorWindow* Create( 30 | wxWindow* parent, const std::string& title, const std::string& text); 31 | 32 | public: 33 | wxTextCtrl* GetTextControl() const; 34 | 35 | private: 36 | void OnClose(wxCloseEvent& event) override; 37 | void OnSave(wxCommandEvent& event) override; 38 | void OnCancel(wxCommandEvent& event) override; 39 | }; 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/gui/textviewerwindow.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "gui.h" 3 | #include "lib/data/layout.h" 4 | #include "textviewerwindow.h" 5 | 6 | TextViewerWindow::TextViewerWindow(wxWindow* parent, 7 | const std::string& title, 8 | const std::string& text, 9 | bool autodestroy): 10 | TextViewerWindowGen(parent), 11 | _autodestroy(autodestroy) 12 | { 13 | auto size = textControl->GetTextExtent("M"); 14 | SetSize(size.Scale(85, 25)); 15 | SetTitle(title); 16 | textControl->SetValue(text); 17 | } 18 | 19 | TextViewerWindow* TextViewerWindow::Create(wxWindow* parent, 20 | const std::string& title, 21 | const std::string& text, 22 | bool autodestroy) 23 | { 24 | return new TextViewerWindow(parent, title, text, autodestroy); 25 | } 26 | 27 | wxTextCtrl* TextViewerWindow::GetTextControl() const 28 | { 29 | return textControl; 30 | } 31 | 32 | std::streamsize TextViewerWindow::xsputn(const char* s, std::streamsize n) 33 | { 34 | textControl->AppendText(std::string(s, n)); 35 | return n; 36 | } 37 | 38 | int TextViewerWindow::overflow(int c) 39 | { 40 | char b = c; 41 | return xsputn(&b, 1); 42 | } 43 | 44 | void TextViewerWindow::OnClose(wxCloseEvent& event) 45 | { 46 | if (_autodestroy) 47 | Destroy(); 48 | else 49 | Hide(); 50 | } 51 | -------------------------------------------------------------------------------- /src/gui/textviewerwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef TEXTVIEWERWINDOW_H 2 | #define TEXTVIEWERWINDOW_H 3 | 4 | #include "layout.h" 5 | 6 | class TextViewerWindow : public TextViewerWindowGen, public std::streambuf 7 | { 8 | public: 9 | TextViewerWindow(wxWindow* parent, 10 | const std::string& title, 11 | const std::string& text, 12 | bool autodestroy); 13 | 14 | static TextViewerWindow* Create(wxWindow* parent, 15 | const std::string& title, 16 | const std::string& text, 17 | bool autodestroy = true); 18 | 19 | public: 20 | wxTextCtrl* GetTextControl() const; 21 | 22 | public: 23 | std::streamsize xsputn(const char* s, std::streamsize n) override; 24 | int overflow(int c) override; 25 | 26 | private: 27 | void OnClose(wxCloseEvent& event) override; 28 | 29 | private: 30 | bool _autodestroy; 31 | }; 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/gui/windres.rc: -------------------------------------------------------------------------------- 1 | /* © 2023 David Given. 2 | * FluxEngine is licensed under the MIT open source license. See the COPYING 3 | * file in this distribution for the full text. 4 | */ 5 | 6 | #include "winuser.h" 7 | 8 | CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "src/gui/manifest.xml" 9 | 101 ICON DISCARDABLE ".obj/windows/extras/+fluxengine_ico/fluxengine.ico" 10 | -------------------------------------------------------------------------------- /src/readibm.h: -------------------------------------------------------------------------------- 1 | #ifndef READIBM_H 2 | #define READIBM_H 3 | 4 | #include "lib/config/flags.h" 5 | #include "dataspec.h" 6 | 7 | extern IntFlag sectorIdBase; 8 | extern BoolFlag ignoreSideByte; 9 | extern RangeFlag requiredSectors; 10 | 11 | extern int mainReadIBM(int argc, const char* argv[]); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /tests/agg.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/core/bytes.h" 3 | #include "agg2d.h" 4 | #include "stb_image_write.h" 5 | #include 6 | 7 | static void test_agg(void) 8 | { 9 | const int WIDTH = 640; 10 | const int HEIGHT = 480; 11 | const int DEPTH = 4; 12 | const int STRIDE = WIDTH * DEPTH; 13 | 14 | std::vector data(STRIDE * HEIGHT, 255); 15 | 16 | Agg2D painter; 17 | painter.attach(&data[0], WIDTH, HEIGHT, STRIDE); 18 | painter.line(0, 0, WIDTH, HEIGHT); 19 | 20 | stbi_write_png("/tmp/test.png", WIDTH, HEIGHT, 4, &data[0], STRIDE); 21 | } 22 | 23 | int main(int argc, const char* argv[]) 24 | { 25 | test_agg(); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /tests/amiga.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/core/bytes.h" 3 | #include "lib/decoders/decoders.h" 4 | #include "arch/amiga/amiga.h" 5 | #include 6 | 7 | static const Bytes testData = { 8 | 0x52, /* 0101 0010 */ 9 | 0xff, /* 1111 1111 */ 10 | 0x4a, /* 0100 1010 */ 11 | 0x22, /* 0010 0010 */ 12 | }; 13 | static const Bytes testDataInterleaved = { 14 | 0x1f, /* 0001 1111 */ 15 | 0x35, /* 0011 0101 */ 16 | 0xcf, /* 1100 1111 */ 17 | 0x80, /* 1000 0000 */ 18 | }; 19 | 20 | static void testInterleave(void) 21 | { 22 | Bytes interleaved = amigaInterleave(testData); 23 | assert(interleaved == testDataInterleaved); 24 | } 25 | 26 | static void testDeinterleave(void) 27 | { 28 | Bytes deinterleaved = amigaDeinterleave(testDataInterleaved); 29 | assert(deinterleaved == testData); 30 | } 31 | 32 | int main(int argc, const char* argv[]) 33 | { 34 | testDeinterleave(); 35 | testInterleave(); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /tests/applesingle.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/core/bytes.h" 3 | #include "lib/vfs/applesingle.h" 4 | #include "snowhouse/snowhouse.h" 5 | 6 | using namespace snowhouse; 7 | 8 | static void testOverhead() 9 | { 10 | AppleSingle t; 11 | t.data = Bytes("This is the data fork"); 12 | t.rsrc = Bytes("This is the resource fork"); 13 | 14 | AssertThat(t.render().size(), 15 | Equals(t.data.size() + t.rsrc.size() + AppleSingle::OVERHEAD)); 16 | } 17 | 18 | static void testRoundtrip() 19 | { 20 | AppleSingle t; 21 | t.data = Bytes("This is the data fork"); 22 | t.rsrc = Bytes("This is the resource fork"); 23 | t.creator = Bytes("CREA"); 24 | t.type = Bytes("TYPE"); 25 | 26 | Bytes tb = t.render(); 27 | AppleSingle s; 28 | s.parse(tb); 29 | 30 | AssertThat(s.data, Equals(t.data)); 31 | AssertThat(s.rsrc, Equals(t.rsrc)); 32 | AssertThat(s.creator, Equals(t.creator)); 33 | AssertThat(s.type, Equals(t.type)); 34 | } 35 | 36 | int main(void) 37 | { 38 | testOverhead(); 39 | testRoundtrip(); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /tests/bitaccumulator.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/core/bytes.h" 3 | #include 4 | 5 | int main(int argc, const char* argv[]) 6 | { 7 | Bytes bytes; 8 | ByteWriter bw(bytes); 9 | BitWriter bitw(bw); 10 | 11 | bitw.push(0x1e, 5); 12 | bitw.flush(); 13 | 14 | assert(bytes == Bytes{0x1e}); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /tests/compression.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/core/bytes.h" 3 | 4 | static void test_roundtrip() 5 | { 6 | Bytes source = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 7 | 8 | auto compressed = source.compress(); 9 | auto decompressed = compressed.decompress(); 10 | 11 | assert(decompressed == source); 12 | } 13 | 14 | int main(int argc, const char* argv[]) 15 | { 16 | test_roundtrip(); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /tests/csvreader.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/external/csvreader.h" 3 | #include 4 | 5 | typedef std::vector strings; 6 | 7 | static void test_csvreader() 8 | { 9 | std::string data( 10 | "header1,header2,header3\n" 11 | "1,2,3\n" 12 | "foo bar\n" 13 | "1,\"2,3\",4\n"); 14 | std::istringstream istream(data); 15 | CsvReader reader(istream); 16 | 17 | assert((reader.readLine() == strings{"header1", "header2", "header3"})); 18 | assert((reader.readLine() == strings{"1", "2", "3"})); 19 | assert((reader.readLine() == strings{"foo bar"})); 20 | assert((reader.readLine() == strings{"1", "2,3", "4"})); 21 | } 22 | 23 | int main(int argc, const char* argv[]) 24 | { 25 | test_csvreader(); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /tests/docker/Dockerfile.debian11: -------------------------------------------------------------------------------- 1 | FROM debian:11 2 | 3 | RUN apt-get update 4 | RUN apt install -y python3 make xz-utils python3 python3-hamcrest \ 5 | protobuf-compiler libprotobuf-dev libsqlite3-dev \ 6 | libfmt-dev libprotobuf-dev wx-common pkg-config \ 7 | libudev-dev g++ libwxgtk3.0-gtk3-dev 8 | 9 | RUN useradd app 10 | RUN mkdir -p /home/app 11 | RUN chown app /home/app 12 | USER app 13 | WORKDIR /home/app 14 | 15 | COPY --chown=app:app arch arch 16 | COPY --chown=app:app build build 17 | COPY --chown=app:app dep dep 18 | COPY --chown=app:app doc doc 19 | COPY --chown=app:app extras extras 20 | COPY --chown=app:app lib lib 21 | COPY --chown=app:app scripts scripts 22 | COPY --chown=app:app src src 23 | COPY --chown=app:app tests tests 24 | COPY --chown=app:app tools tools 25 | COPY --chown=app:app Makefile . 26 | COPY --chown=app:app build.py . 27 | COPY --chown=app:app config.py . 28 | COPY --chown=app:app protocol.h . 29 | COPY --chown=app:app README.md . 30 | 31 | RUN make 32 | -------------------------------------------------------------------------------- /tests/docker/Dockerfile.debian12: -------------------------------------------------------------------------------- 1 | FROM debian:12 2 | 3 | RUN apt-get update 4 | RUN apt install -y python3 make xz-utils python3 python3-hamcrest \ 5 | protobuf-compiler libprotobuf-dev libsqlite3-dev \ 6 | libfmt-dev libprotobuf-dev wx-common pkg-config \ 7 | libudev-dev g++ libwxgtk3.2-dev 8 | 9 | RUN useradd app 10 | RUN mkdir -p /home/app 11 | RUN chown app /home/app 12 | USER app 13 | WORKDIR /home/app 14 | 15 | COPY --chown=app:app arch arch 16 | COPY --chown=app:app build build 17 | COPY --chown=app:app dep dep 18 | COPY --chown=app:app doc doc 19 | COPY --chown=app:app extras extras 20 | COPY --chown=app:app lib lib 21 | COPY --chown=app:app scripts scripts 22 | COPY --chown=app:app src src 23 | COPY --chown=app:app tests tests 24 | COPY --chown=app:app tools tools 25 | COPY --chown=app:app Makefile . 26 | COPY --chown=app:app build.py . 27 | COPY --chown=app:app config.py . 28 | COPY --chown=app:app protocol.h . 29 | COPY --chown=app:app README.md . 30 | 31 | RUN make 32 | -------------------------------------------------------------------------------- /tests/docker/Dockerfile.fedora40: -------------------------------------------------------------------------------- 1 | FROM fedora:40 2 | 3 | RUN dnf update -y 4 | RUN dnf -y install https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-40.noarch.rpm 5 | RUN dnf -y install https://github.com/rpmsphere/noarch/raw/master/r/rpmsphere-release-40-1.noarch.rpm 6 | RUN dnf -y install \ 7 | protobuf-compiler protobuf-devel sqlite-devel libudev-devel \ 8 | wxGTK-devel gcc gcc-c++ fmt-devel png2ico 9 | 10 | RUN useradd app 11 | RUN mkdir -p /home/app 12 | RUN chown app /home/app 13 | USER app 14 | WORKDIR /home/app 15 | 16 | COPY --chown=app:app arch arch 17 | COPY --chown=app:app build build 18 | COPY --chown=app:app dep dep 19 | COPY --chown=app:app doc doc 20 | COPY --chown=app:app extras extras 21 | COPY --chown=app:app lib lib 22 | COPY --chown=app:app scripts scripts 23 | COPY --chown=app:app src src 24 | COPY --chown=app:app tests tests 25 | COPY --chown=app:app tools tools 26 | COPY --chown=app:app Makefile . 27 | COPY --chown=app:app build.py . 28 | COPY --chown=app:app config.py . 29 | COPY --chown=app:app protocol.h . 30 | COPY --chown=app:app README.md . 31 | 32 | RUN make 33 | -------------------------------------------------------------------------------- /tests/docker/Dockerfile.fedora41: -------------------------------------------------------------------------------- 1 | FROM fedora:41 2 | 3 | RUN dnf update -y 4 | RUN dnf -y install https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-41.noarch.rpm 5 | RUN dnf -y install https://github.com/rpmsphere/noarch/raw/master/r/rpmsphere-release-40-1.noarch.rpm 6 | RUN dnf -y install \ 7 | protobuf-compiler protobuf-devel sqlite-devel libudev-devel \ 8 | wxGTK-devel gcc gcc-c++ fmt-devel png2ico 9 | 10 | RUN useradd app 11 | RUN mkdir -p /home/app 12 | RUN chown app /home/app 13 | USER app 14 | WORKDIR /home/app 15 | 16 | COPY --chown=app:app arch arch 17 | COPY --chown=app:app build build 18 | COPY --chown=app:app dep dep 19 | COPY --chown=app:app doc doc 20 | COPY --chown=app:app extras extras 21 | COPY --chown=app:app lib lib 22 | COPY --chown=app:app scripts scripts 23 | COPY --chown=app:app src src 24 | COPY --chown=app:app tests tests 25 | COPY --chown=app:app tools tools 26 | COPY --chown=app:app Makefile . 27 | COPY --chown=app:app build.py . 28 | COPY --chown=app:app config.py . 29 | COPY --chown=app:app protocol.h . 30 | COPY --chown=app:app README.md . 31 | 32 | RUN make 33 | -------------------------------------------------------------------------------- /tests/docker/Dockerfile.manjaro: -------------------------------------------------------------------------------- 1 | FROM manjarolinux/base:latest 2 | 3 | RUN pacman -Sy --noconfirm base-devel protobuf wxwidgets-gtk3 4 | 5 | RUN useradd app 6 | RUN mkdir -p /home/app 7 | RUN chown app /home/app 8 | USER app 9 | WORKDIR /home/app 10 | 11 | COPY --chown=app:app arch arch 12 | COPY --chown=app:app build build 13 | COPY --chown=app:app dep dep 14 | COPY --chown=app:app doc doc 15 | COPY --chown=app:app extras extras 16 | COPY --chown=app:app lib lib 17 | COPY --chown=app:app scripts scripts 18 | COPY --chown=app:app src src 19 | COPY --chown=app:app tests tests 20 | COPY --chown=app:app tools tools 21 | COPY --chown=app:app Makefile . 22 | COPY --chown=app:app build.py . 23 | COPY --chown=app:app config.py . 24 | COPY --chown=app:app protocol.h . 25 | COPY --chown=app:app README.md . 26 | 27 | RUN make 28 | -------------------------------------------------------------------------------- /tests/flags.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/config/flags.h" 3 | #include 4 | 5 | static void testDefaultIntValue() 6 | { 7 | FlagGroup flags; 8 | 9 | IntFlag intFlag({"--intFlag"}, "a global integer flag", 1); 10 | 11 | intFlag.setDefaultValue(2); 12 | const char* argv[] = {"prog", NULL}; 13 | flags.parseFlags(1, argv); 14 | assert(intFlag.get() == 2); 15 | } 16 | 17 | static void testOverriddenIntValue() 18 | { 19 | FlagGroup flags; 20 | 21 | IntFlag intFlag({"--intFlag"}, "a global integer flag", 1); 22 | 23 | intFlag.setDefaultValue(2); 24 | const char* argv[] = {"prog", "--intFlag=3"}; 25 | flags.parseFlags(2, argv); 26 | assert(intFlag.get() == 3); 27 | } 28 | 29 | int main(int argc, const char* argv[]) 30 | { 31 | testDefaultIntValue(); 32 | testOverriddenIntValue(); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /tests/flx.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "lib/core/globals.h" 5 | #include "lib/data/fluxmap.h" 6 | #include "lib/external/flx.h" 7 | 8 | static void test_convert(const Bytes& flxbytes, const Bytes& fluxmapbytes) 9 | { 10 | std::unique_ptr fluxmap = readFlxBytes(flxbytes); 11 | 12 | if (fluxmap->rawBytes() != fluxmapbytes) 13 | { 14 | std::cout << "FLX bytes:" << std::endl; 15 | hexdump(std::cout, flxbytes); 16 | std::cout << std::endl << "Produced this:" << std::endl; 17 | hexdump(std::cout, fluxmap->rawBytes()); 18 | std::cout << std::endl << "Expected this:" << std::endl; 19 | hexdump(std::cout, fluxmapbytes); 20 | abort(); 21 | } 22 | } 23 | 24 | static void test_stream_reader() 25 | { 26 | test_convert(Bytes{0}, Bytes{}); 27 | 28 | /* Simple one-byte intervals */ 29 | test_convert(Bytes{0, 0x64, FLX_STOP}, Bytes{0xb0}); 30 | 31 | /* Index pulse */ 32 | test_convert(Bytes{0, 0x64, FLX_INDEX, 0x64, FLX_STOP}, Bytes{0xf0, 0xb0}); 33 | } 34 | 35 | int main(int argc, const char* argv[]) 36 | { 37 | test_stream_reader(); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /tests/testproto.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "lib/config/common.proto"; 4 | 5 | message TestProto { 6 | message SubMessageProto { 7 | optional string s = 1; 8 | } 9 | 10 | optional int64 i64 = 1 [(help)="i64"]; 11 | optional int32 i32 = 2; 12 | optional uint64 u64 = 3; 13 | optional uint32 u32 = 4; 14 | optional double d = 5; 15 | optional double f = 11; 16 | optional SubMessageProto m = 6; 17 | repeated SubMessageProto r = 7; 18 | 19 | oneof alt { 20 | SubMessageProto firstoption = 8; 21 | SubMessageProto secondoption = 9; 22 | } 23 | 24 | optional RangeProto range = 10; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /tests/testproto.textpb: -------------------------------------------------------------------------------- 1 | u64: 42 2 | r {} 3 | secondoption {} 4 | 5 | -------------------------------------------------------------------------------- /tests/tests.h: -------------------------------------------------------------------------------- 1 | #ifndef TESTS_H 2 | #define TESTS_H 3 | 4 | class AssertionError 5 | { 6 | }; 7 | 8 | template 9 | class Subject 10 | { 11 | public: 12 | Subject(const std::string& filename, int lineno, T value): 13 | _filename(filename), 14 | _lineno(lineno), 15 | _value(value) 16 | { 17 | } 18 | 19 | public: 20 | void isEqualTo(T wanted) 21 | { 22 | if (_value != wanted) 23 | fail(fmt::format("wanted {}, got {}", wanted, _value)); 24 | } 25 | 26 | private: 27 | void fail(const std::string& message) 28 | { 29 | error("assertion failed: {}: {}: {}", _filename, _lineno, message); 30 | } 31 | 32 | private: 33 | const std::string _filename; 34 | int _lineno; 35 | T _value; 36 | }; 37 | 38 | #define assertThat(value) Subject(__FILE__, __LINE__, value) 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /tests/vfs.cc: -------------------------------------------------------------------------------- 1 | #include "lib/core/globals.h" 2 | #include "lib/config/config.h" 3 | #include "lib/vfs/vfs.h" 4 | #include "snowhouse/snowhouse.h" 5 | 6 | using namespace snowhouse; 7 | 8 | static void testPathParsing() 9 | { 10 | AssertThat(Path(""), Equals(std::vector{})); 11 | AssertThat(Path("/"), Equals(std::vector{})); 12 | AssertThat(Path("one"), Equals(std::vector{"one"})); 13 | AssertThat(Path("one/two"), Equals(std::vector{"one", "two"})); 14 | AssertThat( 15 | Path("/one/two"), Equals(std::vector{"one", "two"})); 16 | } 17 | 18 | static void testPathParenthood() 19 | { 20 | AssertThat(Path("").parent(), Equals(std::vector{})); 21 | AssertThat(Path("one").parent(), Equals(std::vector{})); 22 | AssertThat( 23 | Path("one/two").parent(), Equals(std::vector{"one"})); 24 | AssertThat(Path("one/two/three").parent(), 25 | Equals(std::vector{"one", "two"})); 26 | } 27 | 28 | int main(void) 29 | { 30 | testPathParsing(); 31 | testPathParenthood(); 32 | return 0; 33 | } 34 | --------------------------------------------------------------------------------