arduino
This commit is contained in:
parent
1a384a699e
commit
87d2b6dfce
|
@ -1,212 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="de.innot.avreclipse.configuration.app.debug.46313178">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="de.innot.avreclipse.configuration.app.debug.46313178" moduleId="org.eclipse.cdt.core.settings" name="Flash">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="de.innot.avreclipse.buildArtefactType.app" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=de.innot.avreclipse.buildArtefactType.app" description="" id="de.innot.avreclipse.configuration.app.debug.46313178" name="Flash" parent="de.innot.avreclipse.configuration.app.debug">
|
||||
<folderInfo id="de.innot.avreclipse.configuration.app.debug.46313178." name="/" resourcePath="">
|
||||
<toolChain id="de.innot.avreclipse.toolchain.winavr.app.debug.1928898112" name="AVR-GCC Toolchain" superClass="de.innot.avreclipse.toolchain.winavr.app.debug">
|
||||
<option id="de.innot.avreclipse.toolchain.options.toolchain.objcopy.flash.app.debug.1556530364" name="Generate HEX file for Flash memory" superClass="de.innot.avreclipse.toolchain.options.toolchain.objcopy.flash.app.debug" value="true" valueType="boolean"/>
|
||||
<option id="de.innot.avreclipse.toolchain.options.toolchain.objcopy.eeprom.app.debug.308984610" name="Generate HEX file for EEPROM" superClass="de.innot.avreclipse.toolchain.options.toolchain.objcopy.eeprom.app.debug"/>
|
||||
<option id="de.innot.avreclipse.toolchain.options.toolchain.objdump.app.debug.726997292" name="Generate Extended Listing (Source + generated Assembler)" superClass="de.innot.avreclipse.toolchain.options.toolchain.objdump.app.debug"/>
|
||||
<option id="de.innot.avreclipse.toolchain.options.toolchain.size.app.debug.2041004627" name="Print Size" superClass="de.innot.avreclipse.toolchain.options.toolchain.size.app.debug"/>
|
||||
<option id="de.innot.avreclipse.toolchain.options.toolchain.avrdude.app.debug.720975396" name="AVRDude" superClass="de.innot.avreclipse.toolchain.options.toolchain.avrdude.app.debug"/>
|
||||
<targetPlatform id="de.innot.avreclipse.targetplatform.winavr.app.debug.334176018" name="AVR Cross-Target" superClass="de.innot.avreclipse.targetplatform.winavr.app.debug"/>
|
||||
<builder autoBuildTarget="all" buildPath="${workspace_loc:/mac-floppy-emu}/Debug" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="de.innot.avreclipse.target.builder.winavr.app.debug.354726525" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="AVR GNU Make Builder" parallelBuildOn="false" superClass="de.innot.avreclipse.target.builder.winavr.app.debug"/>
|
||||
<tool id="de.innot.avreclipse.tool.assembler.winavr.app.debug.1172708735" name="AVR Assembler" superClass="de.innot.avreclipse.tool.assembler.winavr.app.debug">
|
||||
<option id="de.innot.avreclipse.assembler.option.debug.level.1316218585" name="Generate Debugging Info" superClass="de.innot.avreclipse.assembler.option.debug.level"/>
|
||||
<option id="de.innot.avreclipse.asm.option.include.paths.1985090351" name="#include paths for preprocessor(-I)" superClass="de.innot.avreclipse.asm.option.include.paths" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/floppyemu/SdFat}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/floppyemu/xsvf}""/>
|
||||
</option>
|
||||
<option id="de.innot.avreclipse.asm.option.omitfcpu.511906405" name="Omit F_CPU" superClass="de.innot.avreclipse.asm.option.omitfcpu" value="false" valueType="boolean"/>
|
||||
<inputType id="de.innot.avreclipse.tool.assembler.input.1420366592" superClass="de.innot.avreclipse.tool.assembler.input"/>
|
||||
</tool>
|
||||
<tool id="de.innot.avreclipse.tool.compiler.winavr.app.debug.1667398690" name="AVR Compiler" superClass="de.innot.avreclipse.tool.compiler.winavr.app.debug">
|
||||
<option id="de.innot.avreclipse.compiler.option.debug.level.1071901049" name="Generate Debugging Info" superClass="de.innot.avreclipse.compiler.option.debug.level"/>
|
||||
<option id="de.innot.avreclipse.compiler.option.optimize.681726631" name="Optimization Level" superClass="de.innot.avreclipse.compiler.option.optimize" value="de.innot.avreclipse.compiler.optimize.size" valueType="enumerated"/>
|
||||
<option id="de.innot.avreclipse.compiler.option.incpath.1596667394" name="Include Paths (-I)" superClass="de.innot.avreclipse.compiler.option.incpath" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/floppyemu/SdFat}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/floppyemu/xsvf}""/>
|
||||
</option>
|
||||
<option id="de.innot.avreclipse.compiler.option.def.359890836" name="Define Syms (-D)" superClass="de.innot.avreclipse.compiler.option.def" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="BOOT_ADR=0x1F000"/>
|
||||
</option>
|
||||
<inputType id="de.innot.avreclipse.compiler.winavr.input.529999190" name="C Source Files" superClass="de.innot.avreclipse.compiler.winavr.input"/>
|
||||
</tool>
|
||||
<tool id="de.innot.avreclipse.tool.cppcompiler.app.debug.447087717" name="AVR C++ Compiler" superClass="de.innot.avreclipse.tool.cppcompiler.app.debug">
|
||||
<option id="de.innot.avreclipse.cppcompiler.option.debug.level.1848796785" name="Generate Debugging Info" superClass="de.innot.avreclipse.cppcompiler.option.debug.level"/>
|
||||
<option id="de.innot.avreclipse.cppcompiler.option.optimize.2093225400" name="Optimization Level" superClass="de.innot.avreclipse.cppcompiler.option.optimize" value="de.innot.avreclipse.cppcompiler.optimize.size" valueType="enumerated"/>
|
||||
<option id="de.innot.avreclipse.cppcompiler.option.incpath.2109134472" name="Include Paths (-I)" superClass="de.innot.avreclipse.cppcompiler.option.incpath" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/floppyemu/SdFat}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/floppyemu/xsvf}""/>
|
||||
</option>
|
||||
<option id="de.innot.avreclipse.cppcompiler.option.def.1974695643" name="Define Syms (-D)" superClass="de.innot.avreclipse.cppcompiler.option.def" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="BOOT_ADR=0x1F000"/>
|
||||
</option>
|
||||
<option id="de.innot.avreclipse.cppcompiler.option.undef.116399045" name="Undefine Syms (-U)" superClass="de.innot.avreclipse.cppcompiler.option.undef"/>
|
||||
<inputType id="de.innot.avreclipse.cppcompiler.input.427275686" superClass="de.innot.avreclipse.cppcompiler.input"/>
|
||||
</tool>
|
||||
<tool id="de.innot.avreclipse.tool.linker.winavr.app.debug.856276136" name="AVR C Linker" superClass="de.innot.avreclipse.tool.linker.winavr.app.debug"/>
|
||||
<tool id="de.innot.avreclipse.tool.cpplinker.app.debug.65425799" name="AVR C++ Linker" superClass="de.innot.avreclipse.tool.cpplinker.app.debug">
|
||||
<option id="de.innot.avreclipse.cpplinker.option.nostart.683661851" name="No startup or default libs (-nostdlib)" superClass="de.innot.avreclipse.cpplinker.option.nostart" value="true" valueType="boolean"/>
|
||||
<inputType id="de.innot.avreclipse.tool.cpplinker.input.1415642170" name="OBJ Files" superClass="de.innot.avreclipse.tool.cpplinker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="de.innot.avreclipse.tool.archiver.winavr.base.989913996" name="AVR Archiver" superClass="de.innot.avreclipse.tool.archiver.winavr.base"/>
|
||||
<tool id="de.innot.avreclipse.tool.objdump.winavr.app.debug.310152597" name="AVR Create Extended Listing" superClass="de.innot.avreclipse.tool.objdump.winavr.app.debug"/>
|
||||
<tool id="de.innot.avreclipse.tool.objcopy.flash.winavr.app.debug.666445574" name="AVR Create Flash image" superClass="de.innot.avreclipse.tool.objcopy.flash.winavr.app.debug"/>
|
||||
<tool id="de.innot.avreclipse.tool.objcopy.eeprom.winavr.app.debug.1978977796" name="AVR Create EEPROM image" superClass="de.innot.avreclipse.tool.objcopy.eeprom.winavr.app.debug"/>
|
||||
<tool id="de.innot.avreclipse.tool.size.winavr.app.debug.1574639643" name="Print Size" superClass="de.innot.avreclipse.tool.size.winavr.app.debug"/>
|
||||
<tool id="de.innot.avreclipse.tool.avrdude.app.debug.1681506261" name="AVRDude" superClass="de.innot.avreclipse.tool.avrdude.app.debug"/>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry excluding="bootldr|AVR/SdFat/examples" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
<cconfiguration id="de.innot.avreclipse.configuration.app.debug.46313178.1895685496">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="de.innot.avreclipse.configuration.app.debug.46313178.1895685496" moduleId="org.eclipse.cdt.core.settings" name="Bootloader">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="${ConfigName}" buildArtefactType="de.innot.avreclipse.buildArtefactType.app" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=de.innot.avreclipse.buildArtefactType.app" description="" id="de.innot.avreclipse.configuration.app.debug.46313178.1895685496" name="Bootloader" parent="de.innot.avreclipse.configuration.app.debug">
|
||||
<folderInfo id="de.innot.avreclipse.configuration.app.debug.46313178.1895685496." name="/" resourcePath="">
|
||||
<toolChain id="de.innot.avreclipse.toolchain.winavr.app.debug.907954222" name="AVR-GCC Toolchain" superClass="de.innot.avreclipse.toolchain.winavr.app.debug">
|
||||
<option id="de.innot.avreclipse.toolchain.options.toolchain.objcopy.flash.app.debug.565173578" name="Generate HEX file for Flash memory" superClass="de.innot.avreclipse.toolchain.options.toolchain.objcopy.flash.app.debug" value="true" valueType="boolean"/>
|
||||
<option id="de.innot.avreclipse.toolchain.options.toolchain.objcopy.eeprom.app.debug.110003468" name="Generate HEX file for EEPROM" superClass="de.innot.avreclipse.toolchain.options.toolchain.objcopy.eeprom.app.debug"/>
|
||||
<option id="de.innot.avreclipse.toolchain.options.toolchain.objdump.app.debug.453613451" name="Generate Extended Listing (Source + generated Assembler)" superClass="de.innot.avreclipse.toolchain.options.toolchain.objdump.app.debug"/>
|
||||
<option id="de.innot.avreclipse.toolchain.options.toolchain.size.app.debug.1654513920" name="Print Size" superClass="de.innot.avreclipse.toolchain.options.toolchain.size.app.debug"/>
|
||||
<option id="de.innot.avreclipse.toolchain.options.toolchain.avrdude.app.debug.1122910154" name="AVRDude" superClass="de.innot.avreclipse.toolchain.options.toolchain.avrdude.app.debug"/>
|
||||
<targetPlatform id="de.innot.avreclipse.targetplatform.winavr.app.debug.1905439487" name="AVR Cross-Target" superClass="de.innot.avreclipse.targetplatform.winavr.app.debug"/>
|
||||
<builder autoBuildTarget="all" buildPath="${workspace_loc:/mac-floppy-emu}/Debug" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="de.innot.avreclipse.target.builder.winavr.app.debug.421443985" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="AVR GNU Make Builder" parallelBuildOn="false" superClass="de.innot.avreclipse.target.builder.winavr.app.debug"/>
|
||||
<tool id="de.innot.avreclipse.tool.assembler.winavr.app.debug.960984784" name="AVR Assembler" superClass="de.innot.avreclipse.tool.assembler.winavr.app.debug">
|
||||
<option id="de.innot.avreclipse.assembler.option.debug.level.684450263" name="Generate Debugging Info" superClass="de.innot.avreclipse.assembler.option.debug.level"/>
|
||||
<option id="de.innot.avreclipse.asm.option.include.paths.411582041" name="#include paths for preprocessor(-I)" superClass="de.innot.avreclipse.asm.option.include.paths" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/AVR}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/AVR/bootldr}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/AVR/SdFat}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/AVR/xsvf}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/floppyemu/SdFat}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/floppyemu/xsvf}""/>
|
||||
</option>
|
||||
<option id="de.innot.avreclipse.asm.option.omitfcpu.804465170" name="Omit F_CPU" superClass="de.innot.avreclipse.asm.option.omitfcpu" value="false" valueType="boolean"/>
|
||||
<inputType id="de.innot.avreclipse.tool.assembler.input.1091218206" superClass="de.innot.avreclipse.tool.assembler.input"/>
|
||||
</tool>
|
||||
<tool id="de.innot.avreclipse.tool.compiler.winavr.app.debug.447380226" name="AVR Compiler" superClass="de.innot.avreclipse.tool.compiler.winavr.app.debug">
|
||||
<option id="de.innot.avreclipse.compiler.option.debug.level.780095625" name="Generate Debugging Info" superClass="de.innot.avreclipse.compiler.option.debug.level"/>
|
||||
<option id="de.innot.avreclipse.compiler.option.optimize.648107763" name="Optimization Level" superClass="de.innot.avreclipse.compiler.option.optimize" value="de.innot.avreclipse.compiler.optimize.size" valueType="enumerated"/>
|
||||
<option id="de.innot.avreclipse.compiler.option.incpath.1733304105" name="Include Paths (-I)" superClass="de.innot.avreclipse.compiler.option.incpath" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/AVR}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/AVR/bootldr}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/AVR/SdFat}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/AVR/xsvf}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/floppyemu/SdFat}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/floppyemu/xsvf}""/>
|
||||
</option>
|
||||
<option id="de.innot.avreclipse.compiler.option.def.347006568" name="Define Syms (-D)" superClass="de.innot.avreclipse.compiler.option.def" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="BOOT_ADR=0x1F000"/>
|
||||
</option>
|
||||
<inputType id="de.innot.avreclipse.compiler.winavr.input.57550180" name="C Source Files" superClass="de.innot.avreclipse.compiler.winavr.input"/>
|
||||
</tool>
|
||||
<tool id="de.innot.avreclipse.tool.cppcompiler.app.debug.1991756259" name="AVR C++ Compiler" superClass="de.innot.avreclipse.tool.cppcompiler.app.debug">
|
||||
<option id="de.innot.avreclipse.cppcompiler.option.debug.level.965905202" name="Generate Debugging Info" superClass="de.innot.avreclipse.cppcompiler.option.debug.level"/>
|
||||
<option id="de.innot.avreclipse.cppcompiler.option.optimize.256282861" name="Optimization Level" superClass="de.innot.avreclipse.cppcompiler.option.optimize" value="de.innot.avreclipse.cppcompiler.optimize.size" valueType="enumerated"/>
|
||||
<option id="de.innot.avreclipse.cppcompiler.option.incpath.1831223918" name="Include Paths (-I)" superClass="de.innot.avreclipse.cppcompiler.option.incpath" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/AVR}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/AVR/bootldr}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/AVR/SdFat}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/AVR/xsvf}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/floppyemu/SdFat}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/mac-floppy-emu/floppyemu/xsvf}""/>
|
||||
</option>
|
||||
<option id="de.innot.avreclipse.cppcompiler.option.def.750809700" name="Define Syms (-D)" superClass="de.innot.avreclipse.cppcompiler.option.def" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="BOOT_ADR=0x1F000"/>
|
||||
</option>
|
||||
<option id="de.innot.avreclipse.cppcompiler.option.undef.819457287" name="Undefine Syms (-U)" superClass="de.innot.avreclipse.cppcompiler.option.undef"/>
|
||||
<inputType id="de.innot.avreclipse.cppcompiler.input.586233877" superClass="de.innot.avreclipse.cppcompiler.input"/>
|
||||
</tool>
|
||||
<tool id="de.innot.avreclipse.tool.linker.winavr.app.debug.2040136235" name="AVR C Linker" superClass="de.innot.avreclipse.tool.linker.winavr.app.debug"/>
|
||||
<tool id="de.innot.avreclipse.tool.cpplinker.app.debug.1333346517" name="AVR C++ Linker" superClass="de.innot.avreclipse.tool.cpplinker.app.debug">
|
||||
<option id="de.innot.avreclipse.cpplinker.option.nostart.156731030" name="No startup or default libs (-nostdlib)" superClass="de.innot.avreclipse.cpplinker.option.nostart" value="false" valueType="boolean"/>
|
||||
<inputType id="de.innot.avreclipse.tool.cpplinker.input.550428840" name="OBJ Files" superClass="de.innot.avreclipse.tool.cpplinker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="de.innot.avreclipse.tool.archiver.winavr.base.2109674810" name="AVR Archiver" superClass="de.innot.avreclipse.tool.archiver.winavr.base"/>
|
||||
<tool id="de.innot.avreclipse.tool.objdump.winavr.app.debug.1998341406" name="AVR Create Extended Listing" superClass="de.innot.avreclipse.tool.objdump.winavr.app.debug"/>
|
||||
<tool id="de.innot.avreclipse.tool.objcopy.flash.winavr.app.debug.818265629" name="AVR Create Flash image" superClass="de.innot.avreclipse.tool.objcopy.flash.winavr.app.debug"/>
|
||||
<tool id="de.innot.avreclipse.tool.objcopy.eeprom.winavr.app.debug.671424688" name="AVR Create EEPROM image" superClass="de.innot.avreclipse.tool.objcopy.eeprom.winavr.app.debug"/>
|
||||
<tool id="de.innot.avreclipse.tool.size.winavr.app.debug.1570739038" name="Print Size" superClass="de.innot.avreclipse.tool.size.winavr.app.debug"/>
|
||||
<tool id="de.innot.avreclipse.tool.avrdude.app.debug.451487219" name="AVRDude" superClass="de.innot.avreclipse.tool.avrdude.app.debug"/>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry excluding="floppyemu|AVR/SdFat/examples" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="mac-floppy-emu.de.innot.avreclipse.project.winavr.elf_2.1.0.1811389054" name="AVR Cross Target Application" projectType="de.innot.avreclipse.project.winavr.elf_2.1.0"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
<configuration configurationName="Release">
|
||||
<resource resourceType="PROJECT" workspacePath="/mac-floppy-emu"/>
|
||||
</configuration>
|
||||
<configuration configurationName="Bootloader">
|
||||
<resource resourceType="PROJECT" workspacePath="/mac-floppy-emu"/>
|
||||
</configuration>
|
||||
<configuration configurationName="Debug">
|
||||
<resource resourceType="PROJECT" workspacePath="/mac-floppy-emu"/>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<scannerConfigBuildInfo instanceId="de.innot.avreclipse.configuration.app.debug.46313178.1895685496;de.innot.avreclipse.configuration.app.debug.46313178.1895685496.;de.innot.avreclipse.tool.compiler.winavr.app.debug.447380226;de.innot.avreclipse.compiler.winavr.input.57550180">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC"/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="de.innot.avreclipse.configuration.app.release.1158950851;de.innot.avreclipse.configuration.app.release.1158950851.;de.innot.avreclipse.tool.compiler.winavr.app.release.792334622;de.innot.avreclipse.compiler.winavr.input.1693785873">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC"/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="de.innot.avreclipse.configuration.app.debug.46313178;de.innot.avreclipse.configuration.app.debug.46313178.;de.innot.avreclipse.tool.compiler.winavr.app.debug.1667398690;de.innot.avreclipse.compiler.winavr.input.529999190">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC"/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="de.innot.avreclipse.configuration.app.debug.46313178.1895685496;de.innot.avreclipse.configuration.app.debug.46313178.1895685496.;de.innot.avreclipse.tool.cppcompiler.app.debug.1991756259;de.innot.avreclipse.cppcompiler.input.586233877">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileCPP"/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="de.innot.avreclipse.configuration.app.release.1158950851;de.innot.avreclipse.configuration.app.release.1158950851.;de.innot.avreclipse.tool.cppcompiler.app.release.95022568;de.innot.avreclipse.cppcompiler.input.1203907827">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileCPP"/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="de.innot.avreclipse.configuration.app.debug.46313178;de.innot.avreclipse.configuration.app.debug.46313178.;de.innot.avreclipse.tool.cppcompiler.app.debug.447087717;de.innot.avreclipse.cppcompiler.input.427275686">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileCPP"/>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
</cproject>
|
|
@ -1,3 +0,0 @@
|
|||
/Debug/
|
||||
/Bootloader/
|
||||
/Flash/
|
|
@ -1,28 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>mac-floppy-emu</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
<nature>de.innot.avreclipse.core.avrnature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -1,17 +0,0 @@
|
|||
eclipse.preferences.version=1
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.46313178.1895685496/LANG/delimiter=\:
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.46313178.1895685496/LANG/operation=replace
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.46313178.1895685496/LANG/value=en-US
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.46313178.1895685496/PATH/delimiter=\:
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.46313178.1895685496/PATH/operation=replace
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.46313178.1895685496/PATH/value=/opt/local/bin\:/usr/bin\:/bin\:/usr/sbin\:/sbin
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.46313178.1895685496/append=true
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.46313178.1895685496/appendContributed=true
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.46313178/LANG/delimiter=\:
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.46313178/LANG/operation=replace
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.46313178/LANG/value=en-US
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.46313178/PATH/delimiter=\:
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.46313178/PATH/operation=replace
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.46313178/PATH/value=/usr/local/arduinotool/bin\:/opt/local/bin\:/usr/bin\:/bin\:/usr/sbin\:/sbin
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.46313178/append=true
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.46313178/appendContributed=true
|
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
verilog work "floppyemu.v"
|
|
@ -1,41 +0,0 @@
|
|||
#PACE: Start of Constraints generated by PACE
|
||||
#PACE: Start of PACE I/O Pin Assignments
|
||||
NET "stepAck_diskInserted" LOC = "P8" ;
|
||||
NET "_enable" LOC = "P20" ;
|
||||
NET "_rst" LOC = "P37" ;
|
||||
NET "_wreq" LOC = "P18" ;
|
||||
NET "_wreqMCU" LOC = "P5" ;
|
||||
NET "byteReady_tk0" LOC = "P7" ;
|
||||
NET "ca0" LOC = "P12" ;
|
||||
NET "ca1" LOC = "P13" ;
|
||||
NET "ca2" LOC = "P14" ;
|
||||
NET "clk" LOC = "P43" ;
|
||||
NET "data<0>" LOC = "P31" ;
|
||||
NET "data<1>" LOC = "P32" ;
|
||||
NET "data<2>" LOC = "P33" ;
|
||||
NET "data<3>" LOC = "P34" ;
|
||||
NET "data<4>" LOC = "P36" ;
|
||||
NET "data<5>" LOC = "P38" ;
|
||||
NET "data<6>" LOC = "P41" ;
|
||||
NET "driveCurrentSide" LOC = "P3" ;
|
||||
NET "stepDirectionMotorOn" LOC = "P1" ;
|
||||
NET "driveTach" LOC = "P28" ;
|
||||
NET "ejectRequest" LOC = "P30" ;
|
||||
NET "led" LOC = "P40" ;
|
||||
NET "lstrb" LOC = "P16" ;
|
||||
NET "outputEnable" LOC = "P2" ;
|
||||
NET "rd" LOC = "P21" ;
|
||||
NET "rdAckWrTick" LOC = "P44" ;
|
||||
NET "SEL" LOC = "P19" ;
|
||||
NET "stepRequest" LOC = "P39" ;
|
||||
NET "wr" LOC = "P22" ;
|
||||
NET "zero" LOC = "P6" ;
|
||||
NET "pwm" LOC = "P23" ;
|
||||
NET "test" LOC = "P27" ;
|
||||
|
||||
#PACE: Start of PACE Area Constraints
|
||||
#PACE: Start of PACE Prohibit Constraints
|
||||
#PACE: End of Constraints generated by PACE
|
||||
#Created by Constraints Editor (xc9572xl-vq44-10) - 2013/11/07
|
||||
NET "clk" TNM_NET = clk;
|
||||
TIMESPEC TS_clk = PERIOD "clk" 50 ns HIGH 50%;
|
|
@ -1,433 +0,0 @@
|
|||
/*
|
||||
Floppy Emu, copyright 2013 Steve Chamberlin, "Big Mess o' Wires". All rights reserved.
|
||||
|
||||
Floppy Emu is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported
|
||||
license. (CC BY-NC 3.0) The terms of the license may be viewed at
|
||||
http://creativecommons.org/licenses/by-nc/3.0/
|
||||
|
||||
Based on a work at http://www.bigmessowires.com/macintosh-floppy-emu/
|
||||
|
||||
Permissions beyond the scope of this license may be available at www.bigmessowires.com
|
||||
or from mailto:steve@bigmessowires.com.
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
Disk registers (read):
|
||||
State-control lines Register
|
||||
CA2 CA1 CA0 SEL addressed Information in register
|
||||
|
||||
0 0 0 0 DIRTN Head step direction (0 = toward track 79, 1 = toward track 0)
|
||||
0 0 0 1 CSTIN Disk in place (0 = disk is inserted)
|
||||
0 0 1 0 STEP Drive head stepping (setting to 0 performs a step, returns to 1 when step is complete)
|
||||
0 0 1 1 WRTPRT Disk locked (0 = locked)
|
||||
0 1 0 0 MOTORON Drive motor running (0 = on, 1 = off)
|
||||
0 1 0 1 TK0 Head at track 0 (0 = at track 0)
|
||||
0 1 1 0 SWITCHED Disk switched (1 = yes?) SWIM3: relax, also eject in progress
|
||||
0 1 1 1 TACH GCR: Tachometer (produces 60 pulses for each rotation of the drive motor), MFM: Index pulse
|
||||
1 0 0 0 RDDATA0 Read data, lower head, side 0
|
||||
1 0 0 1 RDDATA1 Read data, upper head, side 1
|
||||
1 0 1 0 SUPERDR Drive is a Superdrive (0 = no, 1 = yes) SWIM3: two meg drive.
|
||||
1 0 1 1 MFM_MODE SWIM3: MFM_MODE, 1 = yes (opposite of writing?)
|
||||
1 1 0 0 SIDES Single- or double-sided drive (0 = single side, 1 = double side), SWIM: 0 = 4MB, 1 = not 4MB
|
||||
1 1 0 1 READY 0 = yes, SWIM3: SEEK_COMPLETE
|
||||
1 1 1 0 INSTALLED 0 = yes, only used by SWIM, not IWM? SWIM3: drive present.
|
||||
1 1 1 1 HSHK_HD 400K/800K: implements ready handshake if 1, Superdrive: Inserted disk capacity (0 = HD, 1 = DD), SWIM3: 1 = ONE_MEG_MEDIA
|
||||
|
||||
|
||||
Disk registers (write):
|
||||
Control lines Register
|
||||
CA1 CA0 SEL addressed Register function
|
||||
|
||||
0 0 0 DIRTN Set stepping direction (0 = toward track 79, 1 = toward track 0), SWIM3: SEEK_POSITIVE
|
||||
0 0 1 SWITCHED Reset disk switched flag (writing 1 sets switch flag to 0)
|
||||
0 1 0 STEP Step the drive head one track (setting to 0 performs a step, returns to 1 when step is complete)
|
||||
1 0 0 MOTORON Turn drive motor on/off (0 = on, 1 = off)
|
||||
1 0 0 TWOMEGMEDIA_CHECK The first time zero is written, changes the behavior when reading SIDES
|
||||
0 1 1 MFM_MODE 0 = MFM, 1 = GCR
|
||||
1 1 0 EJECT Eject the disk (writing 1 ejects the disk)
|
||||
1 1 0 INDEX if writing 0
|
||||
*/
|
||||
|
||||
`define DRIVE_REG_DIRTN 0
|
||||
`define DRIVE_REG_CSTIN 1
|
||||
`define DRIVE_REG_STEP 2
|
||||
`define DRIVE_REG_WRTPRT 3
|
||||
`define DRIVE_REG_MOTORON 4
|
||||
`define DRIVE_REG_TK0 5
|
||||
`define DRIVE_REG_EJECT 6
|
||||
`define DRIVE_REG_TACH 7
|
||||
`define DRIVE_REG_RDDATA0 8
|
||||
`define DRIVE_REG_RDDATA1 9
|
||||
`define DRIVE_REG_SUPERDR 10
|
||||
`define DRIVE_REG_UNUSED 11
|
||||
`define DRIVE_REG_SIDES 12
|
||||
`define DRIVE_REG_READY 13
|
||||
`define DRIVE_REG_INSTALLED 14
|
||||
`define DRIVE_REG_HSHK_HD 15
|
||||
|
||||
`define FIRMWARE_VERSION_NUMBER 11
|
||||
|
||||
module floppyemu(
|
||||
input clk,
|
||||
|
||||
// Macintosh interface
|
||||
input ca0, // PH0
|
||||
input ca1, // PH1
|
||||
input ca2, // PH2
|
||||
input lstrb, // PH3
|
||||
input SEL, // HDSEL from VIA
|
||||
input _enable,
|
||||
input wr,
|
||||
input _wreq,
|
||||
input pwm, // unused
|
||||
output rd,
|
||||
|
||||
// microcontroller interface
|
||||
input _rst,
|
||||
|
||||
output stepDirectionMotorOn,
|
||||
output reg stepRequest,
|
||||
input stepAck_diskInserted,
|
||||
|
||||
output _wreqMCU,
|
||||
output reg rdAckWrTick,
|
||||
output reg driveCurrentSide,
|
||||
output reg ejectRequest,
|
||||
|
||||
input driveTach,
|
||||
input byteReady_tk0,
|
||||
|
||||
input outputEnable,
|
||||
inout [6:0] data,
|
||||
|
||||
output zero,
|
||||
|
||||
// status display
|
||||
output led,
|
||||
|
||||
// debugging
|
||||
output test
|
||||
);
|
||||
|
||||
/********** drive state data **********/
|
||||
reg _driveRegTK0;
|
||||
reg _driveRegMotorOn;
|
||||
reg driveRegStepDirection;
|
||||
reg _driveRegWriteProtect;
|
||||
reg _driveRegDiskInserted;
|
||||
reg _driveRegMFMMode;
|
||||
|
||||
/********** serial to parallel interface **********/
|
||||
// GCR: One bit every 2 microseconds
|
||||
// The exact rate on the Macintosh is actually 16 clocks @ 7.8336 MHz = 2.04 microseconds.
|
||||
// MFM: One bit every 1 microsecond
|
||||
reg [7:0] shifter;
|
||||
reg [5:0] bitTimer;
|
||||
reg [3:0] bitCounter;
|
||||
reg [6:0] wrData;
|
||||
reg rdHead;
|
||||
reg [1:0] wrHistory;
|
||||
reg mfmWriteSynced;
|
||||
reg wrClear;
|
||||
|
||||
always @(posedge clk) begin
|
||||
wrHistory <= { wrHistory[0], wr };
|
||||
end
|
||||
|
||||
always @(posedge clk or negedge _rst) begin
|
||||
if (_rst == 0) begin
|
||||
rdAckWrTick <= 0;
|
||||
_driveRegWriteProtect <= 1;
|
||||
_driveRegDiskInserted <= 1;
|
||||
_driveRegMFMMode <= 1;
|
||||
wrData <= `FIRMWARE_VERSION_NUMBER;
|
||||
mfmWriteSynced <= 0;
|
||||
wrClear <= 0;
|
||||
end
|
||||
else begin
|
||||
// one-way switch for disk inserted register - until next reset, stepAck_diskInserted will act only as stepAck
|
||||
if (_driveRegDiskInserted == 1 && stepAck_diskInserted == 0) begin
|
||||
_driveRegDiskInserted <= 0;
|
||||
end
|
||||
// is the Macintosh currently writing to the disk?
|
||||
if (_wreq == 0) begin
|
||||
// was there a transition on the wr line?
|
||||
// GCR: any transition
|
||||
// MFM: falling edge
|
||||
if (((wrHistory[1] != wrHistory[0]) && (_driveRegMFMMode == 1)) ||
|
||||
((wrHistory[1] && ~wrHistory[0]) && (_driveRegMFMMode == 0))) begin
|
||||
// has at least half a bit cell time elpased since the last cell boundary?
|
||||
if ((bitTimer >= 20 && _driveRegMFMMode == 1) ||
|
||||
(bitTimer >= 10 && _driveRegMFMMode == 0)) begin
|
||||
shifter <= { shifter[6:0], 1'b1 };
|
||||
bitCounter <= bitCounter - 1'b1;
|
||||
end
|
||||
// do nothing if the clock count was less than half a cell
|
||||
|
||||
// reset the bit timer
|
||||
bitTimer <= 0;
|
||||
end
|
||||
else begin
|
||||
// have one and a half bit cell times elapsed?
|
||||
if ((bitTimer >= 60 && _driveRegMFMMode == 1) ||
|
||||
(bitTimer >= 30 && _driveRegMFMMode == 0)) begin
|
||||
shifter <= { shifter[6:0], 1'b0 };
|
||||
bitCounter <= bitCounter - 1'b1;
|
||||
|
||||
if (_driveRegMFMMode == 1)
|
||||
bitTimer <= 20;
|
||||
else
|
||||
bitTimer <= 10;
|
||||
end
|
||||
else begin
|
||||
// init shifter at the beginning of a write, so we can recognize the framing bits later
|
||||
if (wrClear == 0) begin
|
||||
shifter <= 0;
|
||||
wrClear <= 1;
|
||||
end
|
||||
// has a complete byte been shifted in?
|
||||
else if (_driveRegMFMMode == 1) begin
|
||||
// GCR
|
||||
if (shifter[7] == 1) begin
|
||||
// GCR: The complete byte is shifter[7:0], but only 7 bits are stored in wrData, since the MSB is always 1.
|
||||
wrData <= shifter[6:0]; // store the byte for the mcu
|
||||
shifter <= 0; // clear the byte from the shifter
|
||||
rdAckWrTick <= ~rdAckWrTick; // signal the mcu that a new byte is ready
|
||||
end
|
||||
end
|
||||
else begin
|
||||
// MFM
|
||||
// If we're in write mode, but haven't yet synched (framed the bytes in the bit stream),
|
||||
// and we see 01000100 in the shifter, assume that it's the first half of an A1 sync
|
||||
if ((bitCounter == 0) ||
|
||||
(shifter == 8'h44 && mfmWriteSynced == 0)) begin
|
||||
// MFM: send the mcu the data nibble in the low 4 bits, and clock bit C2 in bit 4
|
||||
wrData[0] <= shifter[0];
|
||||
wrData[1] <= shifter[2];
|
||||
wrData[2] <= shifter[4];
|
||||
wrData[3] <= shifter[6];
|
||||
wrData[4] <= shifter[5]; // clock bit
|
||||
bitCounter <= 8;
|
||||
|
||||
rdAckWrTick <= (shifter == 8'h44 && mfmWriteSynced == 0) ? 0 : ~rdAckWrTick; // signal the mcu that a new nibble is ready
|
||||
mfmWriteSynced <= mfmWriteSynced | (shifter == 8'h44);
|
||||
end
|
||||
end
|
||||
|
||||
bitTimer <= bitTimer + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
else begin
|
||||
mfmWriteSynced <= 0;
|
||||
wrClear <= 0;
|
||||
// is it time for a new bit?
|
||||
if ((bitTimer == 40 && _driveRegMFMMode == 1) ||
|
||||
(bitTimer == 20 && _driveRegMFMMode == 0))
|
||||
begin
|
||||
// are all the bits done?
|
||||
if (bitCounter == 0) begin
|
||||
// is there a new byte ready to read?
|
||||
if (byteReady_tk0 == 1) begin
|
||||
// if there's a byte ready, but no disk inserted, then load config options from the MCU
|
||||
if (_driveRegDiskInserted == 1) begin
|
||||
_driveRegWriteProtect <= data[0];
|
||||
_driveRegMFMMode <= data[1];
|
||||
end
|
||||
else begin
|
||||
// load the new byte.
|
||||
if (_driveRegMFMMode == 1) begin
|
||||
// Only 7 bits are transferred, since the MSB is always 1.
|
||||
shifter <= { 1'b1, data };
|
||||
end
|
||||
else begin
|
||||
// For MFM, the 7 bits received from the MCU are:
|
||||
// 0 0 m d3 d2 d1 d0
|
||||
// From this we can constuct the MFM-encoded byte with clock and data bits:
|
||||
// c3 d3 c2 d2 c1 d1 c0 d0
|
||||
// where cN = dN+1 NOR dN.
|
||||
// If m is 1, then this is part of a mark byte, and c2 should be forced to 0.
|
||||
shifter[7] <= ~(shifter[7] | data[3]);
|
||||
shifter[6] <= data[3];
|
||||
shifter[5] <= ~(data[3] | data[2]) & ~data[4];
|
||||
shifter[4] <= data[2];
|
||||
shifter[3] <= ~(data[2] | data[1]);
|
||||
shifter[2] <= data[1];
|
||||
shifter[1] <= ~(data[1] | data[0]);
|
||||
shifter[0] <= data[0];
|
||||
end
|
||||
bitCounter <= 7;
|
||||
rdAckWrTick <= 1;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
// insert a sync byte
|
||||
if (_driveRegMFMMode == 1)
|
||||
begin
|
||||
shifter <= { 8'b11111111 };
|
||||
bitCounter <= 9; // sync "byte" sends 10 bits rather than 8
|
||||
end
|
||||
else begin
|
||||
shifter <= { 8'b10101010 }; // logical 0x0, encoded 0xA. Should sync byte be 0x4E instead?
|
||||
bitCounter <= 7;
|
||||
end
|
||||
end
|
||||
end
|
||||
else begin
|
||||
if (bitCounter == 7) begin
|
||||
// Clear rdAck after the first bit is done. This gives the microcontroller 2 microseconds
|
||||
// to react to rdAck before it's deasserted.
|
||||
rdAckWrTick <= 0;
|
||||
end
|
||||
|
||||
// there are still more bits remaining, so shift the next bit
|
||||
shifter <= { shifter[6:0], 1'b0 }; // left shift
|
||||
bitCounter <= bitCounter - 1'b1;
|
||||
end
|
||||
end
|
||||
/* GCR: After the bit shift is completed, update the read head state, using the MSB of the shift register.
|
||||
A logical 1 is sent as a falling (high to low) transition on the read head at a bit cell boundary time,
|
||||
a logical 0 is sent as no falling transition. */
|
||||
else if (bitTimer == 2 && shifter[7] == 1 && _driveRegMFMMode == 1) begin
|
||||
rdHead <= 1'b0;
|
||||
end
|
||||
/* GCR: Half-way through the bit cell time, set the read head to 1
|
||||
to prepare for a possible falling transition for the next bit. */
|
||||
else if (bitTimer == 20 && _driveRegMFMMode == 1)
|
||||
begin
|
||||
rdHead <= 1'b1;
|
||||
end
|
||||
/* MFM: At the start of the bit cell time, set the read head to 0 if the logical value is 1. */
|
||||
else if (bitTimer == 2 && shifter[7] == 1 && _driveRegMFMMode == 0)
|
||||
begin
|
||||
rdHead <= 1'b0;
|
||||
end
|
||||
/* MFM: About a quarter-way through the bit cell time, always reset read head to 1. */
|
||||
else if (bitTimer == 7 && _driveRegMFMMode == 0)
|
||||
begin
|
||||
rdHead <= 1'b1;
|
||||
end
|
||||
|
||||
// increment bit timer modulo 40 (20 MFM)
|
||||
if ((bitTimer == 40 && _driveRegMFMMode == 1) ||
|
||||
(bitTimer == 20 && _driveRegMFMMode == 0))
|
||||
bitTimer <= 0;
|
||||
else
|
||||
bitTimer <= bitTimer + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// enable the data output only if the MCU says its data lines are Hi Z
|
||||
assign data = (outputEnable == 1) ? wrData : 7'hZZ;
|
||||
|
||||
/********** register read **********/
|
||||
wire [3:0] driveReadRegisterSelect = {ca2,ca1,ca0,SEL};
|
||||
|
||||
reg registerContents;
|
||||
always @* begin
|
||||
case (driveReadRegisterSelect)
|
||||
`DRIVE_REG_DIRTN:
|
||||
registerContents = driveRegStepDirection; // step direction
|
||||
`DRIVE_REG_CSTIN:
|
||||
registerContents = _driveRegDiskInserted; // disk in drive, 0 = yes
|
||||
`DRIVE_REG_STEP:
|
||||
registerContents = ~stepRequest; // STEP, 1 = complete
|
||||
`DRIVE_REG_WRTPRT:
|
||||
registerContents = _driveRegWriteProtect; // write protect, 0 = on, 1 = off
|
||||
`DRIVE_REG_MOTORON:
|
||||
registerContents = _driveRegMotorOn; // 0 = motor on
|
||||
`DRIVE_REG_TK0:
|
||||
registerContents = _driveRegTK0; // TK0: track 0 indicator
|
||||
`DRIVE_REG_EJECT:
|
||||
registerContents = 1'b0; // disk switched?
|
||||
`DRIVE_REG_TACH:
|
||||
registerContents = driveTach; // TACH: 60 pulses for each rotation of the drive motor
|
||||
`DRIVE_REG_RDDATA0:
|
||||
registerContents = rdHead; // RDDATA0
|
||||
`DRIVE_REG_RDDATA1:
|
||||
registerContents = rdHead; // RDDATA1
|
||||
`DRIVE_REG_SUPERDR:
|
||||
registerContents = 1'b1; // SUPERDR, 1 = yes
|
||||
`DRIVE_REG_UNUSED:
|
||||
registerContents = 1'b0; // UNUSED
|
||||
`DRIVE_REG_SIDES:
|
||||
registerContents = 1'b1; // SIDES = double-sided drive
|
||||
`DRIVE_REG_READY:
|
||||
registerContents = 1'b0; // READY = yes
|
||||
`DRIVE_REG_INSTALLED:
|
||||
registerContents = 1'b0; // INSTALLED = yes
|
||||
`DRIVE_REG_HSHK_HD:
|
||||
registerContents = _driveRegMFMMode; // HSHK_HD = implements ready handshake, or DD/HD media
|
||||
|
||||
endcase
|
||||
end
|
||||
assign rd = _enable == 1'b1 ? 1'bZ : registerContents;
|
||||
|
||||
always @(posedge clk or negedge _rst) begin
|
||||
if (_rst == 0) begin
|
||||
driveCurrentSide = 0;
|
||||
end
|
||||
else if (_enable == 1'b0 && lstrb == 1'b0) begin
|
||||
if (driveReadRegisterSelect == `DRIVE_REG_RDDATA0)
|
||||
driveCurrentSide = 0;
|
||||
else if (driveReadRegisterSelect == `DRIVE_REG_RDDATA1)
|
||||
driveCurrentSide = 1;
|
||||
end
|
||||
end
|
||||
|
||||
// compute the effective _wreq state for the microcontroller
|
||||
assign _wreqMCU = ~(_wreq == 0 && _enable == 0 && _driveRegMotorOn == 0);
|
||||
|
||||
// cheesy: during a step request, stepDirectionMotorOn is the step direction. Otherwise it's motorOn.
|
||||
assign stepDirectionMotorOn = stepRequest ? driveRegStepDirection : _driveRegMotorOn;
|
||||
|
||||
/********** register write **********/
|
||||
wire [2:0] driveWriteRegisterSelect = {ca1,ca0,SEL};
|
||||
|
||||
reg [4:0] lstrbHistory;
|
||||
always @(posedge clk) begin
|
||||
lstrbHistory <= { lstrbHistory[3:0], lstrb };
|
||||
end
|
||||
|
||||
always @(posedge clk or negedge _rst) begin
|
||||
if (_rst == 1'b0) begin
|
||||
_driveRegTK0 <= 0;
|
||||
_driveRegMotorOn <= 1;
|
||||
driveRegStepDirection <= 0;
|
||||
stepRequest <= 0;
|
||||
ejectRequest <= 0;
|
||||
end
|
||||
// was there a rising edge on lstrb?
|
||||
else if (_enable == 1'b0 && lstrbHistory == 5'b01111) begin
|
||||
case (driveWriteRegisterSelect)
|
||||
`DRIVE_REG_DIRTN:
|
||||
driveRegStepDirection <= ca2;
|
||||
//`DRIVE_REG_SWITCHED: // unused
|
||||
`DRIVE_REG_STEP:
|
||||
begin
|
||||
stepRequest <= 1; // tell the microcontroller that a step was performed
|
||||
end
|
||||
`DRIVE_REG_MOTORON:
|
||||
_driveRegMotorOn <= ca2;
|
||||
`DRIVE_REG_EJECT:
|
||||
if (ca2 == 1'b1) begin
|
||||
ejectRequest <= 1; // tell the microcontroller that the disk was ejected. This stays on forever (until next reset)
|
||||
end
|
||||
endcase
|
||||
end
|
||||
else begin
|
||||
// clear step request after mcu acknowledges it, and get the new track 0 state
|
||||
if (stepRequest == 1 && stepAck_diskInserted == 1'b1) begin
|
||||
stepRequest <= 0;
|
||||
_driveRegTK0 <= byteReady_tk0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
/********** Revision 1.0 board: status LEDs and fake SD writeProtect **********/
|
||||
assign led = _driveRegMotorOn;
|
||||
assign zero = 0;
|
||||
|
||||
|
||||
endmodule
|
|
@ -1,210 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
|
||||
|
||||
<header>
|
||||
<!-- ISE source project file created by Project Navigator. -->
|
||||
<!-- -->
|
||||
<!-- This file contains project source information including a list of -->
|
||||
<!-- project source files, project and process properties. This file, -->
|
||||
<!-- along with the project source files, is sufficient to open and -->
|
||||
<!-- implement in ISE Project Navigator. -->
|
||||
<!-- -->
|
||||
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
|
||||
</header>
|
||||
|
||||
<version xil_pn:ise_version="14.6" xil_pn:schema_version="2"/>
|
||||
|
||||
<files>
|
||||
<file xil_pn:name="floppyemu.v" xil_pn:type="FILE_VERILOG">
|
||||
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="1"/>
|
||||
<association xil_pn:name="Implementation" xil_pn:seqID="1"/>
|
||||
</file>
|
||||
<file xil_pn:name="testbench.v" xil_pn:type="FILE_VERILOG">
|
||||
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="2"/>
|
||||
<association xil_pn:name="PostRouteSimulation" xil_pn:seqID="2"/>
|
||||
</file>
|
||||
<file xil_pn:name="floppyemu.ucf" xil_pn:type="FILE_UCF">
|
||||
<association xil_pn:name="Implementation" xil_pn:seqID="0"/>
|
||||
</file>
|
||||
</files>
|
||||
|
||||
<properties>
|
||||
<property xil_pn:name="Add I/O Buffers" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Allow Unmatched LOC Constraints" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Allow Unmatched Timing Group Constraints" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Auto Implementation Compile Order" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Auto Implementation Top" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Automatically Insert glbl Module in the Netlist" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Autosignature Generation" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Bring Out Global Set/Reset Net as a Port" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Bus Delimiter" xil_pn:value="<>" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Case" xil_pn:value="Maintain" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Case Implementation Style" xil_pn:value="None" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Clock Enable" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Collapsing Input Limit (2-54)" xil_pn:value="54" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Collapsing Pterm Limit (1-90)" xil_pn:value="90" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Compile CPLD Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Compile SIMPRIM (Timing) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Compile UNISIM (Functional) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Compile for HDL Debugging" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Compile uni9000 (Functional) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Create IEEE 1532 Configuration File" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Create Programmable GND Pins on Unused I/O" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Default Powerup Value of Registers" xil_pn:value="Low" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Delay Values To Be Read from SDF" xil_pn:value="Setup Time" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Device" xil_pn:value="xc9572xl" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Device Family" xil_pn:value="XC9500XL CPLDs" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Do Not Escape Signal and Instance Names in Netlist" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Enable Hardware Co-Simulation" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Enable Message Filtering" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Equivalent Register Removal XST" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Evaluation Development Board" xil_pn:value="None Specified" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Exhaustive Fit Mode" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="FSM Encoding Algorithm" xil_pn:value="Auto" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Filter Files From Compile Order" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Functional Model Target Language Schematic" xil_pn:value="Verilog" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Generate Architecture Only (No Entity Declaration)" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Generate Multiple Hierarchical Netlist Files" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Generate Post-Fit Power Data" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Generate Post-Fit Simulation Model" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Generate RTL Schematic" xil_pn:value="Yes" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Generate SAIF File for Power Optimization/Estimation Par" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Generate Testbench File" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Generics, Parameters" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Global Set/Reset Port Name" xil_pn:value="GSR_PORT" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="HDL Equations Style" xil_pn:value="Source" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Hierarchy Separator" xil_pn:value="/" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="I/O Pin Termination" xil_pn:value="Keeper" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="ISim UUT Instance Name" xil_pn:value="UUT" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Implementation Template" xil_pn:value="Optimize Density" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Implementation Top" xil_pn:value="Module|floppyemu" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Implementation Top File" xil_pn:value="floppyemu.v" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Implementation Top Instance Path" xil_pn:value="/floppyemu" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Include 'uselib Directive in Verilog File" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Include SIMPRIM Models in Verilog File" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Include sdf_annotate task in Verilog File" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Incremental Compilation" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Instantiation Template Target Language Xps" xil_pn:value="Verilog" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Keep Hierarchy" xil_pn:value="No" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Keep Hierarchy CPLD" xil_pn:value="Yes" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Language" xil_pn:value="VHDL" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Last Applied Goal" xil_pn:value="Balanced" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Last Applied Strategy" xil_pn:value="Xilinx Default (unlocked)" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Last Unlock Status" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Launch SDK after Export" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Library for Verilog Sources" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Load glbl" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Logic Optimization" xil_pn:value="Density" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Macro Preserve" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Macrocell Power Setting" xil_pn:value="Std" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Manual Implementation Compile Order" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Maximum Number of Lines in Report" xil_pn:value="1000" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Maximum Signal Name Length" xil_pn:value="20" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Mux Extraction" xil_pn:value="Yes" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Netlist Hierarchy" xil_pn:value="As Optimized" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Optimization Effort" xil_pn:value="High" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Optimization Goal" xil_pn:value="Area" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Other CPLD Fitter Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Other Compiler Options" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Other Compiler Options Fit" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Other Compxlib Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Other NETGEN Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Other Ngdbuild Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Other Programming Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Other Simulator Commands Behavioral" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Other Simulator Commands Fit" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Other Timing Report Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Other XPWR Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Other XST Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Output Extended Identifiers" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Output File Name" xil_pn:value="floppyemu" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Output Slew Rate" xil_pn:value="Fast" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Overwrite Compiled Libraries" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Package" xil_pn:value="VQ44" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Port to be used" xil_pn:value="Auto - default" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Post Place & Route Simulation Model Name" xil_pn:value="floppyemu_timesim.v" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Preferred Language" xil_pn:value="Verilog" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Preserve Unused Inputs" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Produce Verbose Report" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Project Description" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Property Specification in Project File" xil_pn:value="Store all values" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Rename Design Instance in Testbench File to" xil_pn:value="UUT" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Rename Top Level Architecture To" xil_pn:value="Structure" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Rename Top Level Entity to" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Rename Top Level Module To" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Reset On Configuration Pulse Width" xil_pn:value="100" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Resource Sharing" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Retain Hierarchy" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Run for Specified Time" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Run for Specified Time Par" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Safe Implementation" xil_pn:value="No" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Selected Module Instance Name" xil_pn:value="/testbench" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Selected Simulation Root Source Node Behavioral" xil_pn:value="work.testbench" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Selected Simulation Root Source Node Post-Route" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Selected Simulation Source Node" xil_pn:value="UUT" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Show All Models" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Signature /User Code" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Simulation Model Target" xil_pn:value="Verilog" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Simulation Run Time ISim" xil_pn:value="1000 ns" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Simulation Run Time Par" xil_pn:value="1000 ns" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Simulator" xil_pn:value="ISim (VHDL/Verilog)" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Specify 'define Macro Name and Value" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Specify Top Level Instance Names Behavioral" xil_pn:value="work.testbench" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Specify Top Level Instance Names Fit" xil_pn:value="Default" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Speed Grade" xil_pn:value="-10" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Synthesis Tool" xil_pn:value="XST (VHDL/Verilog)" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Target Simulator" xil_pn:value="Please Specify" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Target UCF File Name" xil_pn:value="floppyemu.ucf" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Timing Report Format" xil_pn:value="Summary" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Top-Level Source Type" xil_pn:value="HDL" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Use Custom Project File Behavioral" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Use Custom Project File Fit" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Use Custom Simulation Command File Behavioral" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Use Custom Simulation Command File Par" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Use Custom Waveform Configuration File Behav" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Use Custom Waveform Configuration File Fit" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Use Global Clocks" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Use Global Output Enables" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Use Global Set/Reset" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Use Location Constraints" xil_pn:value="Always" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Use Multi-level Logic Optimization" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Use Smart Guide" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Use Synthesis Constraints File" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Use Timing Constraints" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="User Browsed Strategy Files" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="VCCIO Reference Voltage" xil_pn:value="LVTTL" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="VHDL Source Analysis Standard" xil_pn:value="VHDL-93" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Value Range Check" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Verilog 2001 Xst" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Verilog Macros" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="WYSIWYG" xil_pn:value="None" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Working Directory" xil_pn:value="." xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="XOR Preserve" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<!-- -->
|
||||
<!-- The following properties are for internal use only. These should not be modified.-->
|
||||
<!-- -->
|
||||
<property xil_pn:name="PROP_BehavioralSimTop" xil_pn:value="Module|testbench" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="PROP_DesignName" xil_pn:value="floppyemu" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="PROP_DevFamilyPMName" xil_pn:value="xc9500xl" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="PROP_PostFitSimTop" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="PROP_PreSynthesis" xil_pn:value="PreSynthesis" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="PROP_intProjectCreationTimestamp" xil_pn:value="2011-11-23T15:40:51" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="PROP_intWbtProjectID" xil_pn:value="EA0C44EFBDC8450DA8F8CD96D20935BA" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="PROP_intWorkingDirLocWRTProjDir" xil_pn:value="Same" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="PROP_intWorkingDirUsed" xil_pn:value="No" xil_pn:valueState="non-default"/>
|
||||
</properties>
|
||||
|
||||
<bindings/>
|
||||
|
||||
<libraries/>
|
||||
|
||||
<autoManagedFiles>
|
||||
<!-- The following files are identified by `include statements in verilog -->
|
||||
<!-- source files and are automatically managed by Project Navigator. -->
|
||||
<!-- -->
|
||||
<!-- Do not hand-edit this section, as it will be overwritten when the -->
|
||||
<!-- project is analyzed based on files automatically identified as -->
|
||||
<!-- include files. -->
|
||||
</autoManagedFiles>
|
||||
|
||||
</project>
|
|
@ -1,163 +0,0 @@
|
|||
`timescale 1ns / 1ps
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 15:13:07 11/30/2011
|
||||
// Design Name: floppyemu
|
||||
// Module Name: C:/Users/steve/Documents/floppyemu/CPLD-Xilinx/testbench.v
|
||||
// Project Name: floppyemu
|
||||
// Target Device:
|
||||
// Tool versions:
|
||||
// Description:
|
||||
//
|
||||
// Verilog Test Fixture created by ISE for module: floppyemu
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module testbench;
|
||||
|
||||
// Inputs
|
||||
reg clk;
|
||||
reg wr;
|
||||
|
||||
// Outputs
|
||||
wire [7:0] wrData;
|
||||
wire rdAckWrByte;
|
||||
|
||||
// Instantiate the Unit Under Test (UUT)
|
||||
floppyemu uut (
|
||||
.clk(clk),
|
||||
.wr(wr),
|
||||
.wrData(wrData),
|
||||
.rdAckWrByte(rdAckWrByte)
|
||||
);
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
end
|
||||
|
||||
always begin
|
||||
#70 clk = 1;
|
||||
#70 clk = 0;
|
||||
end
|
||||
|
||||
initial begin
|
||||
// Initialize Inputs
|
||||
wr = 0;
|
||||
|
||||
// Wait 100 ns for global reset to finish
|
||||
#4000;
|
||||
|
||||
// send 10-bit sync byte
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 ;
|
||||
#2000 ;
|
||||
|
||||
// send 10-bit sync byte
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 ;
|
||||
#2000 ;
|
||||
|
||||
// send 10-bit sync byte
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 ;
|
||||
#2000 ;
|
||||
|
||||
// send 10-bit sync byte
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 ;
|
||||
#2000 ;
|
||||
|
||||
// send 10-bit sync byte
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 ;
|
||||
#2000 ;
|
||||
|
||||
// D5 = 1101 0101
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 ;
|
||||
#2000 wr = ~wr;
|
||||
#2000 ;
|
||||
#2000 wr = ~wr;
|
||||
#2000 ;
|
||||
#2000 wr = ~wr;
|
||||
|
||||
// AA = 1010 1010
|
||||
#2000 wr = ~wr;
|
||||
#2000 ;
|
||||
#2000 wr = ~wr;
|
||||
#2000 ;
|
||||
#2000 wr = ~wr;
|
||||
#2000 ;
|
||||
#2000 wr = ~wr;
|
||||
#2000 ;
|
||||
|
||||
// 96 = 1001 0110
|
||||
#2000 wr = ~wr;
|
||||
#2000 ;
|
||||
#2000 ;
|
||||
#2000 wr = ~wr;
|
||||
#2000 ;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 ;
|
||||
|
||||
// 96 = 1001 0110
|
||||
#2000 wr = ~wr;
|
||||
#2000 ;
|
||||
#2000 ;
|
||||
#2000 wr = ~wr;
|
||||
#2000 ;
|
||||
#2000 wr = ~wr;
|
||||
#2000 wr = ~wr;
|
||||
#2000 ;
|
||||
|
||||
$stop;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 140 KiB |
Binary file not shown.
Before Width: | Height: | Size: 64 KiB |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -1,33 +0,0 @@
|
|||
ICs:
|
||||
XC9572XL, 44-pin TQFP package = http://search.digikey.com/us/en/products/XC9572XL-10VQG44C/122-1448-ND/966629?wt.z_cid=ref_octopart_dkc_buynow
|
||||
ATMega1284P, 44-pin TQFP package = http://search.digikey.com/us/en/products/ATMEGA1284P-AU/ATMEGA1284P-AU-ND/1914519
|
||||
74LVC244A level converter, 20-pin SSOP package = http://search.digikey.com/us/en/products/74LVC244ADB,112/568-1582-5-ND/763186
|
||||
800mA 1117 3.3V regulator, SOT223 package = http://search.digikey.com/us/en/products/LD1117S33TR/497-1242-1-ND/586242
|
||||
20 MHz 8pF SMD crystal, NX5032 package = http://search.digikey.com/us/en/products/NX5032GA-20.000000MHZ-LN-CD-1/644-1039-1-ND/1128911
|
||||
|
||||
Connectors:
|
||||
DB-19 connector, male solder type = http://www.iec-usa.com/cgi-bin/iec/fullpic?G2FS4qvh;DB19MS;41
|
||||
IDC20 connector = http://search.digikey.com/us/en/products/SBH11-PBPC-D10-ST-BK/S9172-ND/1990065
|
||||
AVR ISP connector (2x3 IDC) = http://search.digikey.com/us/en/products/75869-131LF/609-2845-ND/1302569
|
||||
8-pin male 0.1 inch header
|
||||
2-pin male 0.1 inch header
|
||||
8-pin female 0.1 inch header
|
||||
2-pin female 0.1 inch header
|
||||
|
||||
Passives:
|
||||
10x 0.1uF capacitors, 0805 package
|
||||
1x 33uF tantalum cap, 0805 package
|
||||
2x 18pF caps, 0805 package
|
||||
3x 220 ohm resistors, 0805 package
|
||||
1x 10K ohm resistor, 0805 package
|
||||
|
||||
Miscellaneous:
|
||||
Nokia 5110 graphical LCD = https://www.sparkfun.com/products/10168
|
||||
2x LEDs, 0805 package = http://search.digikey.com/us/en/products/APT2012SGC/754-1131-1-ND/1747848
|
||||
4x B3FS tactile switch, SMD = http://search.digikey.com/scripts/dksearch/dksus.dll?pname&WT.z_cid=ref_octopart_dkc_buynow&site=us&lang=en&name=SW1141-ND
|
||||
TE 2041021-4 SD card holder = http://search.digikey.com/us/en/products/2041021-4/A101492CT-ND/2571152
|
||||
|
||||
Tools:
|
||||
AVRISP mkII AVR programmer (or equivalent) = http://www.digikey.com/product-detail/en/ATAVRISP2/ATAVRISP2-ND/898891?WT.mc_id=PLA_898891&gclid=CO_xwcjWnbQCFYp_QgodXX0AUQ
|
||||
SD or SDHC card
|
||||
|
Binary file not shown.
|
@ -1,24 +0,0 @@
|
|||
To update the Xilinx CPLD firmware:
|
||||
|
||||
1. Copy firmware.xvf to the root directory of your SD card, and insert it into Floppy Emu.
|
||||
2. Hold down the PREV and NEXT buttons.
|
||||
3. Press and release the RESET button.
|
||||
4. Follow the on-screen prompts.
|
||||
|
||||
|
||||
To update the microcontroller application software:
|
||||
|
||||
If you have the SD bootloader already installed:
|
||||
1. Copy femu.bin to the root directory of your SD card, and insert it into Floppy Emu.
|
||||
2. Hold down the PREV and SELECT buttons.
|
||||
3. Press and release the RESET button.
|
||||
4. Follow the on-screen prompts.
|
||||
|
||||
If you don't have the SD bootloader installed:
|
||||
1. Use your AVR ISP programmer to flash floppyemu.hex to the microcontroller.
|
||||
|
||||
If you want to install the SD bootloader:
|
||||
1. Use your AVR ISP programmer to flash merged.hex to the microcontroller.
|
||||
2. Use the ISP programmer to set the BOOTRST fuse to 1 (on), and the BOOTSZ fuse to 2048W_F800. (Fuses should be Extended: 0xFF, High: 0xDA, Low: 0xBF)
|
||||
|
||||
|
|
@ -1,212 +0,0 @@
|
|||
################################################################################
|
||||
# Automatically-generated file. Do not edit!
|
||||
################################################################################
|
||||
|
||||
SHELL := /bin/csh
|
||||
RM := rm -rf
|
||||
|
||||
USER_OBJS :=
|
||||
|
||||
LIBS :=
|
||||
PROJ :=
|
||||
|
||||
O_SRCS :=
|
||||
C_SRCS :=
|
||||
S_SRCS :=
|
||||
S_UPPER_SRCS :=
|
||||
OBJ_SRCS :=
|
||||
ASM_SRCS :=
|
||||
PREPROCESSING_SRCS :=
|
||||
OBJS :=
|
||||
OBJS_AS_ARGS :=
|
||||
C_DEPS :=
|
||||
C_DEPS_AS_ARGS :=
|
||||
EXECUTABLES :=
|
||||
OUTPUT_FILE_PATH :=
|
||||
OUTPUT_FILE_PATH_AS_ARGS :=
|
||||
AVR_APP_PATH :=$$$AVR_APP_PATH$$$
|
||||
QUOTE := "
|
||||
ADDITIONAL_DEPENDENCIES:=
|
||||
OUTPUT_FILE_DEP:=
|
||||
|
||||
# Every subdirectory with source files must be described here
|
||||
SUBDIRS :=
|
||||
|
||||
|
||||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
C_SRCS += \
|
||||
../cardtest.cpp \
|
||||
../diskmenu.cpp \
|
||||
../floppyemu.cpp \
|
||||
../millitimer.cpp \
|
||||
../noklcd.cpp \
|
||||
../SdFat/Sd2Card.cpp \
|
||||
../SdFat/SdBaseFile.cpp \
|
||||
../SdFat/SdFat.cpp \
|
||||
../SdFat/SdVolume.cpp \
|
||||
../xsvf/lenval.cpp \
|
||||
../xsvf/micro.cpp \
|
||||
../xsvf/ports.cpp
|
||||
|
||||
|
||||
PREPROCESSING_SRCS +=
|
||||
|
||||
|
||||
ASM_SRCS +=
|
||||
|
||||
|
||||
OBJS += \
|
||||
cardtest.o \
|
||||
diskmenu.o \
|
||||
floppyemu.o \
|
||||
millitimer.o \
|
||||
noklcd.o \
|
||||
Sd2Card.o \
|
||||
SdBaseFile.o \
|
||||
SdFat.o \
|
||||
SdVolume.o \
|
||||
lenval.o \
|
||||
micro.o \
|
||||
ports.o
|
||||
|
||||
|
||||
OBJS_AS_ARGS += \
|
||||
cardtest.o \
|
||||
diskmenu.o \
|
||||
floppyemu.o \
|
||||
millitimer.o \
|
||||
noklcd.o \
|
||||
Sd2Card.o \
|
||||
SdBaseFile.o \
|
||||
SdFat.o \
|
||||
SdVolume.o \
|
||||
lenval.o \
|
||||
micro.o \
|
||||
ports.o
|
||||
|
||||
|
||||
C_DEPS += \
|
||||
cardtest.d \
|
||||
diskmenu.d \
|
||||
floppyemu.d \
|
||||
millitimer.d \
|
||||
noklcd.d \
|
||||
Sd2Card.d \
|
||||
SdBaseFile.d \
|
||||
SdFat.d \
|
||||
SdVolume.d \
|
||||
lenval.d \
|
||||
micro.d \
|
||||
ports.d
|
||||
|
||||
|
||||
C_DEPS_AS_ARGS += \
|
||||
cardtest.d \
|
||||
diskmenu.d \
|
||||
floppyemu.d \
|
||||
millitimer.d \
|
||||
noklcd.d \
|
||||
Sd2Card.d \
|
||||
SdBaseFile.d \
|
||||
SdFat.d \
|
||||
SdVolume.d \
|
||||
lenval.d \
|
||||
micro.d \
|
||||
ports.d
|
||||
|
||||
|
||||
OUTPUT_FILE_PATH +=floppyemu.elf
|
||||
|
||||
OUTPUT_FILE_PATH_AS_ARGS +=floppyemu.elf
|
||||
|
||||
ADDITIONAL_DEPENDENCIES:=
|
||||
|
||||
OUTPUT_FILE_DEP:= ./makedep.mk
|
||||
|
||||
# AVR32/GNU C Compiler
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
./%.o: .././%.cpp
|
||||
@echo Building file: $<
|
||||
@echo Invoking: AVR8/GNU C++ Compiler
|
||||
$(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-g++.exe$(QUOTE) -funsigned-char -funsigned-bitfields -DF_CPU=20000000 -I"../SdFat" -I"../xsvf" -O2 -ffunction-sections -fpack-struct -fshort-enums -Wall -c -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mmcu=atmega1284p -o"$@" "$<"
|
||||
@echo Finished building: $<
|
||||
|
||||
./%.o: ../SdFat/%.cpp
|
||||
@echo Building file: $<
|
||||
@echo Invoking: AVR8/GNU C++ Compiler
|
||||
$(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-g++.exe$(QUOTE) -funsigned-char -funsigned-bitfields -DF_CPU=20000000 -I"../SdFat" -I"../xsvf" -O2 -ffunction-sections -fpack-struct -fshort-enums -Wall -c -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mmcu=atmega1284p -o"$@" "$<"
|
||||
@echo Finished building: $<
|
||||
|
||||
./%.o: ../xsvf/%.cpp
|
||||
@echo Building file: $<
|
||||
@echo Invoking: AVR8/GNU C++ Compiler
|
||||
$(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-g++.exe$(QUOTE) -funsigned-char -funsigned-bitfields -DF_CPU=20000000 -I"../SdFat" -I"../xsvf" -O2 -ffunction-sections -fpack-struct -fshort-enums -Wall -c -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mmcu=atmega1284p -o"$@" "$<"
|
||||
@echo Finished building: $<
|
||||
|
||||
|
||||
|
||||
# AVR32/GNU Preprocessing Assembler
|
||||
|
||||
|
||||
|
||||
# AVR32/GNU Assembler
|
||||
|
||||
|
||||
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
ifneq ($(strip $(C_DEPS)),)
|
||||
-include $(C_DEPS)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
|
||||
# All Target
|
||||
all: $(OUTPUT_FILE_PATH) $(ADDITIONAL_DEPENDENCIES)
|
||||
|
||||
$(OUTPUT_FILE_PATH): $(OBJS) $(USER_OBJS) $(OUTPUT_FILE_DEP)
|
||||
@echo Building target: $@
|
||||
@echo Invoking: AVR8/GNU C++ Linker
|
||||
$(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-g++.exe$(QUOTE) -o$(OUTPUT_FILE_PATH_AS_ARGS) $(OBJS_AS_ARGS) $(USER_OBJS) $(LIBS) -Wl,-Map="floppyemu.map" -Wl,-lm -Wl,--gc-sections -mrelax -Wl,-section-start=.bootldrinfo=0x1eff8 -mmcu=atmega1284p
|
||||
@echo Finished building target: $@
|
||||
"C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature "floppyemu.elf" "floppyemu.hex"
|
||||
"C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-objcopy.exe" -O binary -R .eeprom -R .fuse -R .lock -R .signature "floppyemu.elf" "femu.bin"
|
||||
"C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-objcopy.exe" -j .eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0 --no-change-warnings -O ihex "floppyemu.elf" "floppyemu.eep" || exit 0
|
||||
"C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-objdump.exe" -h -S "floppyemu.elf" > "floppyemu.lss"
|
||||
srec_cat "floppyemu.hex" -intel "..\bootldr\bootldr\Release\bootldr.hex" -intel -o "merged.hex" -intel
|
||||
"C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-size.exe" -C --mcu=atmega1284p "floppyemu.elf"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Other Targets
|
||||
clean:
|
||||
-$(RM) $(OBJS_AS_ARGS)$(C_DEPS_AS_ARGS) $(EXECUTABLES)
|
||||
rm -rf "floppyemu.hex" "floppyemu.lss" "floppyemu.eep" "floppyemu.map"
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -1,3 +0,0 @@
|
|||
Floppy Emu was designed and developed by Steve Chamberlin, "Big Mess o' Wires", copyright 2013. The source files, schematics, and related materials are licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported license. To learn more about the CC BY-NC 3.0 license, see http://creativecommons.org/licenses/by-nc/3.0/
|
||||
|
||||
You're free to build a Floppy Emu for personal use, or adapt and share the design for other non-commercial projects. Please do not build a batch of Floppy Emus and sell them on eBay. If you need a commercial license or another non-creative-commons license, contact steve@bigmessowires.com.
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
/Debug/
|
|
@ -0,0 +1,21 @@
|
|||
eclipse.preferences.version=1
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.225132627/LANG/delimiter=\:
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.225132627/LANG/operation=append
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.225132627/LANG/value=en-US
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.225132627/append=true
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.225132627/appendContributed=true
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.276225876/LANG/delimiter=\:
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.276225876/LANG/operation=append
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.276225876/LANG/value=en-US
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.276225876/append=true
|
||||
environment/project/de.innot.avreclipse.configuration.app.debug.276225876/appendContributed=true
|
||||
environment/project/de.innot.avreclipse.configuration.app.release.472085903/LANG/delimiter=\:
|
||||
environment/project/de.innot.avreclipse.configuration.app.release.472085903/LANG/operation=append
|
||||
environment/project/de.innot.avreclipse.configuration.app.release.472085903/LANG/value=en-US
|
||||
environment/project/de.innot.avreclipse.configuration.app.release.472085903/append=true
|
||||
environment/project/de.innot.avreclipse.configuration.app.release.472085903/appendContributed=true
|
||||
environment/project/de.innot.avreclipse.configuration.app.release.924927447/LANG/delimiter=\:
|
||||
environment/project/de.innot.avreclipse.configuration.app.release.924927447/LANG/operation=append
|
||||
environment/project/de.innot.avreclipse.configuration.app.release.924927447/LANG/value=en-US
|
||||
environment/project/de.innot.avreclipse.configuration.app.release.924927447/append=true
|
||||
environment/project/de.innot.avreclipse.configuration.app.release.924927447/appendContributed=true
|
|
@ -181,7 +181,7 @@ class SdBaseFile {
|
|||
/** Create an instance. */
|
||||
SdBaseFile() : writeError(false), type_(FAT_FILE_TYPE_CLOSED) {}
|
||||
SdBaseFile(const char* path, uint8_t oflag);
|
||||
~SdBaseFile() { if(isOpen()) close(); }
|
||||
~SdBaseFile() {if(isOpen()) close();}
|
||||
/**
|
||||
* writeError is set to true if an error occurs during a write().
|
||||
* Set writeError to false before calling print() and/or write() and check
|
|
@ -48,7 +48,7 @@ init_spi:
|
|||
.global dly_100us
|
||||
.func dly_100us
|
||||
dly_100us:
|
||||
ldi r24, lo8(16000000 / 100000) ;(F_CPU / 100000) /* Loop counter */
|
||||
ldi r24, lo8(F_CPU / 100000) /* Loop counter */
|
||||
1: sbiw r30, 1 /* 10 clocks per loop */
|
||||
sbiw r30, 1
|
||||
sbiw r30, 1
|
|
@ -7,14 +7,10 @@
|
|||
|
||||
#include <avr/io.h>
|
||||
|
||||
#ifdef USE_BOOTLDR_MAIN
|
||||
|
||||
int main(void)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
//TODO:: Please write your application code
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
|
@ -146,4 +146,4 @@ void LcdInit()
|
|||
|
||||
LcdGoto(0,0);
|
||||
LcdClear();
|
||||
}
|
||||
}
|
454
arduino/floppyemu/cardtest.cpp → floppy_emu_arduino/cardtest/cardtest.cpp
Normal file → Executable file
454
arduino/floppyemu/cardtest.cpp → floppy_emu_arduino/cardtest/cardtest.cpp
Normal file → Executable file
|
@ -1,235 +1,219 @@
|
|||
/*
|
||||
Floppy Emu, copyright 2013 Steve Chamberlin, "Big Mess o' Wires". All rights reserved.
|
||||
|
||||
Floppy Emu is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported
|
||||
license. (CC BY-NC 3.0) The terms of the license may be viewed at
|
||||
http://creativecommons.org/licenses/by-nc/3.0/
|
||||
|
||||
Based on a work at http://www.bigmessowires.com/macintosh-floppy-emu/
|
||||
|
||||
Permissions beyond the scope of this license may be available at www.bigmessowires.com
|
||||
or from mailto:steve@bigmessowires.com.
|
||||
*/
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SD_SPI.h>
|
||||
#include "noklcd.h"
|
||||
|
||||
#else
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "portmacros.h"
|
||||
#include "noklcd.h"
|
||||
#include "millitimer.h"
|
||||
#include "SdFat.h"
|
||||
#include "SdBaseFile.h"
|
||||
#include "micro.h"
|
||||
#include "ports.h"
|
||||
#include "diskmenu.h"
|
||||
#include "cardtest.h"
|
||||
|
||||
#ifdef ENABLE_ORIGINAL_COMPILER_WORKAROUND
|
||||
|
||||
// work-around for compiler bug
|
||||
#undef PROGMEM
|
||||
#define PROGMEM __attribute__(( section(".progmem.data") ))
|
||||
#undef PSTR
|
||||
#define PSTR(s) (__extension__({static prog_char __c[] PROGMEM = (s); &__c[0];}))
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#define STATUS_LED_PORT B
|
||||
#define STATUS_LED_PIN 3
|
||||
|
||||
#define TEXTBUF_SIZE 22
|
||||
extern char textBuf[];
|
||||
extern uint8_t sectorBuf[512];
|
||||
|
||||
void CardTest()
|
||||
{
|
||||
LcdClear();
|
||||
|
||||
//SdFat sd;
|
||||
SDClass sd(4);
|
||||
|
||||
if (!sd.init(SPI_HALF_SPEED))
|
||||
{
|
||||
snprintf(textBuf, TEXTBUF_SIZE, "SD card error %d:%d", sd.card()->errorCode(), sd.card()->errorData());
|
||||
LcdGoto(0,0);
|
||||
LcdTinyString(textBuf, TEXT_NORMAL);
|
||||
while(1);
|
||||
}
|
||||
|
||||
cid_t cid;
|
||||
|
||||
uint32_t cardSize = sd.card()->cardSize();
|
||||
cardSize /= (2L*1024L);
|
||||
|
||||
sd.card()->readCID(&cid);
|
||||
|
||||
snprintf(textBuf, TEXTBUF_SIZE, "CID %d %c%c%c%c%c %lu MB", cid.mid, cid.pnm[0], cid.pnm[1], cid.pnm[2], cid.pnm[3], cid.pnm[4], cardSize);
|
||||
LcdGoto(0,0);
|
||||
LcdTinyString(textBuf, TEXT_NORMAL);
|
||||
|
||||
csd_t csd;
|
||||
sd.card()->readCSD(&csd);
|
||||
|
||||
uint8_t writeBlockPow; // write block length, log2
|
||||
uint8_t sectorSizeCnt; // minimum erasable size, in write blocks
|
||||
|
||||
if (csd.v1.csd_ver == 1)
|
||||
{
|
||||
csd1_t* c = &csd.v1;
|
||||
|
||||
writeBlockPow = 4*c->write_bl_len_high + c->write_bl_len_low;
|
||||
sectorSizeCnt = 2*c->sector_size_high + c->sector_size_low;
|
||||
}
|
||||
else
|
||||
{
|
||||
csd2_t* c = &csd.v2;
|
||||
|
||||
writeBlockPow = 4*c->write_bl_len_high + c->write_bl_len_low;
|
||||
sectorSizeCnt = 2*c->sector_size_high + c->sector_size_low;
|
||||
}
|
||||
|
||||
sectorSizeCnt += 1; // these all seem to be 2**n - 1?
|
||||
|
||||
uint32_t writeBlock=1;
|
||||
for (uint8_t i=0; i<writeBlockPow; i++)
|
||||
{
|
||||
writeBlock *= 2;
|
||||
}
|
||||
uint32_t sectorSize = writeBlock * sectorSizeCnt;
|
||||
sectorSize /= 1024;
|
||||
|
||||
snprintf(textBuf, TEXTBUF_SIZE, "BLK %luB ERASE %luK", writeBlock, sectorSize);
|
||||
LcdGoto(0,1);
|
||||
LcdTinyString(textBuf, TEXT_NORMAL);
|
||||
|
||||
LcdGoto(0,2);
|
||||
|
||||
SdBaseFile f;
|
||||
if (!f.open("TESTFILE.DAT", O_RDWR))
|
||||
{
|
||||
LcdTinyStringP(PSTR("TESTFILE.DAT missing"), TEXT_NORMAL);
|
||||
while(1);
|
||||
}
|
||||
|
||||
// get address of file on SD
|
||||
uint32_t imageFirstBlock, imageLastBlock;
|
||||
if (!f.contiguousRange(&imageFirstBlock, &imageLastBlock))
|
||||
{
|
||||
LcdTinyStringP(PSTR("file not contiguous"), TEXT_NORMAL);
|
||||
while(1);
|
||||
}
|
||||
|
||||
if (f.fileSize() < (unsigned long)1024 * 1024)
|
||||
{
|
||||
LcdTinyStringP(PSTR("file too small"), TEXT_NORMAL);
|
||||
while(1);
|
||||
}
|
||||
|
||||
f.close();
|
||||
|
||||
LcdTinyStringP(PSTR("Testing..."), TEXT_NORMAL);
|
||||
|
||||
uint32_t writeCount = 0;
|
||||
uint32_t writeTotalTime = 0;
|
||||
uint32_t worstTime = 0;
|
||||
uint32_t above20Count = 0;
|
||||
|
||||
for (int trial=0; trial<3; trial++)
|
||||
{
|
||||
uint32_t b = 0;
|
||||
for (uint32_t cnt=0; cnt<1600 && b<1600; cnt++)
|
||||
{
|
||||
if (!sd.card()->readBlock(imageFirstBlock + b, sectorBuf))
|
||||
{
|
||||
LcdGoto(0,2);
|
||||
LcdTinyStringP(PSTR("SD read error"), TEXT_NORMAL);
|
||||
while(1);
|
||||
}
|
||||
|
||||
// alter the data, to prevent any kind of compression/optimization on the card
|
||||
for (uint16_t i=0; i<512; i++)
|
||||
{
|
||||
sectorBuf[i] ^= sectorBuf[i+1];
|
||||
}
|
||||
|
||||
// blink the LED
|
||||
if ((writeCount & 0x7) == 0)
|
||||
PORT(STATUS_LED_PORT) ^= (1<<STATUS_LED_PIN);
|
||||
|
||||
uint32_t t0;
|
||||
|
||||
_delay_ms(3);
|
||||
|
||||
// write it
|
||||
t0 = millis();
|
||||
|
||||
if (!sd.card()->writeBlock(imageFirstBlock + b, sectorBuf))
|
||||
{
|
||||
LcdGoto(0,2);
|
||||
LcdTinyStringP(PSTR("SD write error"), TEXT_NORMAL);
|
||||
while(1);
|
||||
}
|
||||
|
||||
uint32_t writeTime = millis() - t0;
|
||||
|
||||
// update stats
|
||||
writeCount++;
|
||||
writeTotalTime += writeTime;
|
||||
if (writeTime > 20)
|
||||
above20Count++;
|
||||
if (writeTime > worstTime)
|
||||
worstTime = writeTime;
|
||||
|
||||
// pseudo-interleave
|
||||
if ((cnt & 1) == 0)
|
||||
b += 6;
|
||||
else
|
||||
b -= 5;
|
||||
|
||||
_delay_ms(3);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t avg = (writeTotalTime + (writeCount >> 1))/ writeCount;
|
||||
|
||||
LcdGoto(0,2);
|
||||
LcdTinyStringP(PSTR("AVG.ms/MAX.ms/LONG.%"), TEXT_NORMAL);
|
||||
|
||||
snprintf(textBuf, TEXTBUF_SIZE, "512B RRWI %lu/%lu/%lu", avg, worstTime, above20Count*100/writeCount);
|
||||
LcdGoto(0,3);
|
||||
LcdTinyString(textBuf, TEXT_NORMAL);
|
||||
|
||||
// Card: actual capacity, block size, erase size, best test result (random read-write interleaved) average/max/percent "long" over 20ms
|
||||
// ----------------------------------------------------------
|
||||
// PNY class 10 8GB: 7708 MB, 512B block, 64K erase. 512B RRWI 10/189/1 (random read-write interleave)
|
||||
// SanDisk unrated Ultra II 2GB: 1938 MB, 1024B block, 32K erase. 512B RRWI 7/79/0
|
||||
// Transcend unrated 2GB: 1875 MB, 1024B block, 128K erase. 512B RRWI 3/103/0
|
||||
// SanDisk unrated 128MB: 120 MB, 512B block, 16K erase. 512B RRWI 5/94/1
|
||||
|
||||
// enabling the TACH stuff seems to cause some cards to get errors during this test. Coupling between traces? Why doesn't it happen during normal operation?
|
||||
|
||||
// Transcend unrated 2GB: Finder consistently "goes to sleep" after copying first 19 tracks, but worked twice after 3 tries. Maybe it's too fast?
|
||||
|
||||
|
||||
|
||||
while(1);
|
||||
}
|
||||
/*
|
||||
Floppy Emu, copyright 2013 Steve Chamberlin, "Big Mess o' Wires". All rights reserved.
|
||||
|
||||
Floppy Emu is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported
|
||||
license. (CC BY-NC 3.0) The terms of the license may be viewed at
|
||||
http://creativecommons.org/licenses/by-nc/3.0/
|
||||
|
||||
Based on a work at http://www.bigmessowires.com/macintosh-floppy-emu/
|
||||
|
||||
Permissions beyond the scope of this license may be available at www.bigmessowires.com
|
||||
or from mailto:steve@bigmessowires.com.
|
||||
*/
|
||||
#include <math.h>
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "portmacros.h"
|
||||
#include "noklcd.h"
|
||||
#include "millitimer.h"
|
||||
#include "SdFat.h"
|
||||
#include "SdBaseFile.h"
|
||||
#include "micro.h"
|
||||
#include "ports.h"
|
||||
#include "diskmenu.h"
|
||||
#include "cardtest.h"
|
||||
|
||||
#ifdef PROGMEM_WORKAROUND
|
||||
// work-around for compiler bug
|
||||
#undef PROGMEM
|
||||
#define PROGMEM __attribute__(( section(".progmem.data") ))
|
||||
#undef PSTR
|
||||
#define PSTR(s) (__extension__({static prog_char __c[] PROGMEM = (s); &__c[0];}))
|
||||
#endif
|
||||
|
||||
|
||||
#define STATUS_LED_PORT B
|
||||
#define STATUS_LED_PIN 3
|
||||
|
||||
#define TEXTBUF_SIZE 22
|
||||
extern char textBuf[];
|
||||
extern uint8_t sectorBuf[512];
|
||||
|
||||
void CardTest()
|
||||
{
|
||||
LcdClear();
|
||||
|
||||
SdFat sd;
|
||||
if (!sd.init(SPI_HALF_SPEED))
|
||||
{
|
||||
snprintf(textBuf, TEXTBUF_SIZE, "SD card error %d:%d", sd.card()->errorCode(), sd.card()->errorData());
|
||||
LcdGoto(0,0);
|
||||
LcdTinyString(textBuf, TEXT_NORMAL);
|
||||
while(1);
|
||||
}
|
||||
|
||||
cid_t cid;
|
||||
|
||||
uint32_t cardSize = sd.card()->cardSize();
|
||||
cardSize /= (2L*1024L);
|
||||
|
||||
sd.card()->readCID(&cid);
|
||||
|
||||
snprintf(textBuf, TEXTBUF_SIZE, "CID %d %c%c%c%c%c %lu MB", cid.mid, cid.pnm[0], cid.pnm[1], cid.pnm[2], cid.pnm[3], cid.pnm[4], cardSize);
|
||||
LcdGoto(0,0);
|
||||
LcdTinyString(textBuf, TEXT_NORMAL);
|
||||
|
||||
csd_t csd;
|
||||
sd.card()->readCSD(&csd);
|
||||
|
||||
uint8_t writeBlockPow; // write block length, log2
|
||||
uint8_t sectorSizeCnt; // minimum erasable size, in write blocks
|
||||
|
||||
if (csd.v1.csd_ver == 1)
|
||||
{
|
||||
csd1_t* c = &csd.v1;
|
||||
|
||||
writeBlockPow = 4*c->write_bl_len_high + c->write_bl_len_low;
|
||||
sectorSizeCnt = 2*c->sector_size_high + c->sector_size_low;
|
||||
}
|
||||
else
|
||||
{
|
||||
csd2_t* c = &csd.v2;
|
||||
|
||||
writeBlockPow = 4*c->write_bl_len_high + c->write_bl_len_low;
|
||||
sectorSizeCnt = 2*c->sector_size_high + c->sector_size_low;
|
||||
}
|
||||
|
||||
sectorSizeCnt += 1; // these all seem to be 2**n - 1?
|
||||
|
||||
uint32_t writeBlock=1;
|
||||
for (uint8_t i=0; i<writeBlockPow; i++)
|
||||
{
|
||||
writeBlock *= 2;
|
||||
}
|
||||
uint32_t sectorSize = writeBlock * sectorSizeCnt;
|
||||
sectorSize /= 1024;
|
||||
|
||||
snprintf(textBuf, TEXTBUF_SIZE, "BLK %luB ERASE %luK", writeBlock, sectorSize);
|
||||
LcdGoto(0,1);
|
||||
LcdTinyString(textBuf, TEXT_NORMAL);
|
||||
|
||||
LcdGoto(0,2);
|
||||
|
||||
SdBaseFile f;
|
||||
if (!f.open("TESTFILE.DAT", O_RDWR))
|
||||
{
|
||||
LcdTinyStringP(PSTR("TESTFILE.DAT missing"), TEXT_NORMAL);
|
||||
while(1);
|
||||
}
|
||||
|
||||
// get address of file on SD
|
||||
uint32_t imageFirstBlock, imageLastBlock;
|
||||
if (!f.contiguousRange(&imageFirstBlock, &imageLastBlock))
|
||||
{
|
||||
LcdTinyStringP(PSTR("file not contiguous"), TEXT_NORMAL);
|
||||
while(1);
|
||||
}
|
||||
|
||||
if (f.fileSize() < (unsigned long)1024 * 1024)
|
||||
{
|
||||
LcdTinyStringP(PSTR("file too small"), TEXT_NORMAL);
|
||||
while(1);
|
||||
}
|
||||
|
||||
f.close();
|
||||
|
||||
LcdTinyStringP(PSTR("Testing..."), TEXT_NORMAL);
|
||||
|
||||
uint32_t writeCount = 0;
|
||||
uint32_t writeTotalTime = 0;
|
||||
uint32_t worstTime = 0;
|
||||
uint32_t above20Count = 0;
|
||||
|
||||
for (int trial=0; trial<3; trial++)
|
||||
{
|
||||
uint32_t b = 0;
|
||||
for (uint32_t cnt=0; cnt<1600 && b<1600; cnt++)
|
||||
{
|
||||
if (!sd.card()->readBlock(imageFirstBlock + b, sectorBuf))
|
||||
{
|
||||
LcdGoto(0,2);
|
||||
LcdTinyStringP(PSTR("SD read error"), TEXT_NORMAL);
|
||||
while(1);
|
||||
}
|
||||
|
||||
// alter the data, to prevent any kind of compression/optimization on the card
|
||||
for (uint16_t i=0; i<512; i++)
|
||||
{
|
||||
sectorBuf[i] ^= sectorBuf[i+1];
|
||||
}
|
||||
|
||||
// blink the LED
|
||||
if ((writeCount & 0x7) == 0)
|
||||
PORT(STATUS_LED_PORT) ^= (1<<STATUS_LED_PIN);
|
||||
|
||||
uint32_t t0;
|
||||
|
||||
_delay_ms(3);
|
||||
|
||||
// write it
|
||||
t0 = millis();
|
||||
|
||||
if (!sd.card()->writeBlock(imageFirstBlock + b, sectorBuf))
|
||||
{
|
||||
LcdGoto(0,2);
|
||||
LcdTinyStringP(PSTR("SD write error"), TEXT_NORMAL);
|
||||
while(1);
|
||||
}
|
||||
|
||||
uint32_t writeTime = millis() - t0;
|
||||
|
||||
// update stats
|
||||
writeCount++;
|
||||
writeTotalTime += writeTime;
|
||||
if (writeTime > 20)
|
||||
above20Count++;
|
||||
if (writeTime > worstTime)
|
||||
worstTime = writeTime;
|
||||
|
||||
// pseudo-interleave
|
||||
if ((cnt & 1) == 0)
|
||||
b += 6;
|
||||
else
|
||||
b -= 5;
|
||||
|
||||
_delay_ms(3);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t avg = (writeTotalTime + (writeCount >> 1))/ writeCount;
|
||||
|
||||
LcdGoto(0,2);
|
||||
LcdTinyStringP(PSTR("AVG.ms/MAX.ms/LONG.%"), TEXT_NORMAL);
|
||||
|
||||
snprintf(textBuf, TEXTBUF_SIZE, "512B RRWI %lu/%lu/%lu", avg, worstTime, above20Count*100/writeCount);
|
||||
LcdGoto(0,3);
|
||||
LcdTinyString(textBuf, TEXT_NORMAL);
|
||||
|
||||
// Card: actual capacity, block size, erase size, best test result (random read-write interleaved) average/max/percent "long" over 20ms
|
||||
// ----------------------------------------------------------
|
||||
// PNY class 10 8GB: 7708 MB, 512B block, 64K erase. 512B RRWI 10/189/1 (random read-write interleave)
|
||||
// SanDisk unrated Ultra II 2GB: 1938 MB, 1024B block, 32K erase. 512B RRWI 7/79/0
|
||||
// Transcend unrated 2GB: 1875 MB, 1024B block, 128K erase. 512B RRWI 3/103/0
|
||||
// SanDisk unrated 128MB: 120 MB, 512B block, 16K erase. 512B RRWI 5/94/1
|
||||
|
||||
// enabling the TACH stuff seems to cause some cards to get errors during this test. Coupling between traces? Why doesn't it happen during normal operation?
|
||||
|
||||
// Transcend unrated 2GB: Finder consistently "goes to sleep" after copying first 19 tracks, but worked twice after 3 tries. Maybe it's too fast?
|
||||
|
||||
|
||||
|
||||
while(1);
|
||||
}
|
|
@ -1,368 +1,368 @@
|
|||
/*
|
||||
Floppy Emu, copyright 2013 Steve Chamberlin, "Big Mess o' Wires". All rights reserved.
|
||||
|
||||
Floppy Emu is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported
|
||||
license. (CC BY-NC 3.0) The terms of the license may be viewed at
|
||||
http://creativecommons.org/licenses/by-nc/3.0/
|
||||
|
||||
Based on a work at http://www.bigmessowires.com/macintosh-floppy-emu/
|
||||
|
||||
Permissions beyond the scope of this license may be available at www.bigmessowires.com
|
||||
or from mailto:steve@bigmessowires.com.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <util/atomic.h>
|
||||
#include <util/delay.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "diskmenu.h"
|
||||
#include "SdFat.h"
|
||||
#include "SdBaseFile.h"
|
||||
#include "noklcd.h"
|
||||
|
||||
#define SECTORBUF_SIZE (23 * 512) // use the 24th buffer for directory breadcrumbs
|
||||
extern uint8_t sectorBuf[24][512];
|
||||
extern uint8_t extraBuf[512];
|
||||
|
||||
typedef struct FileEntry
|
||||
{
|
||||
char longName[FILENAME_LEN+1];
|
||||
char shortName[SHORTFILENAME_LEN+1];
|
||||
eImageType imageFileType;
|
||||
} FileEntry;
|
||||
|
||||
bool dirLfnNext(SdFat& sd, dir_t& dir, char* lfn)
|
||||
{
|
||||
uint8_t offset[] = {1, 3, 5, 7, 9, 14, 16, 18, 20, 22, 24, 28, 30};
|
||||
uint8_t lfnIn = 130;
|
||||
uint8_t i;
|
||||
uint8_t ndir=0;
|
||||
uint8_t sum;
|
||||
uint8_t test=0;
|
||||
bool haveLong = false;
|
||||
|
||||
while( sd.vwd()->read( &dir, 32 ) == 32 )
|
||||
{
|
||||
if( DIR_IS_LONG_NAME( &dir ) )
|
||||
{
|
||||
if( ! haveLong )
|
||||
{
|
||||
if(( dir.name[0] & 0XE0 ) != 0X40 )
|
||||
continue;
|
||||
ndir = dir.name[0] & 0X1F;
|
||||
test = dir.creationTimeTenths;
|
||||
haveLong = true;
|
||||
lfnIn = 130;
|
||||
lfn[ lfnIn ] = 0;
|
||||
}
|
||||
else if( dir.name[0] != --ndir || test != dir.creationTimeTenths )
|
||||
{
|
||||
haveLong = false;
|
||||
continue;
|
||||
}
|
||||
char *p = (char*) & dir;
|
||||
if( lfnIn > 0 )
|
||||
{
|
||||
lfnIn -= 13;
|
||||
for( i = 0; i < 13; i++ )
|
||||
lfn[lfnIn + i] = p[offset[i]];
|
||||
}
|
||||
}
|
||||
else if( DIR_IS_FILE_OR_SUBDIR( &dir )
|
||||
&& dir.name[0] != DIR_NAME_DELETED
|
||||
&& dir.name[0] != DIR_NAME_FREE
|
||||
&& dir.name[0] != '.')
|
||||
{
|
||||
if( haveLong )
|
||||
{
|
||||
for( sum = i = 0; i < 11; i++ )
|
||||
sum = (((sum & 1) << 7) | ((sum & 0xfe) >> 1)) + dir.name[i];
|
||||
if( sum != test || ndir != 1 )
|
||||
haveLong = false;
|
||||
}
|
||||
if( haveLong )
|
||||
{
|
||||
for( i = 0; lfnIn + i <= 130 ; i++ )
|
||||
lfn[i] = lfn[lfnIn + i];
|
||||
return true;
|
||||
}
|
||||
// else if( dir.reservedNT )
|
||||
// return "Reserved NT";
|
||||
else
|
||||
{
|
||||
SdBaseFile::dirName( dir, lfn );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( dir.name[0] == DIR_NAME_FREE )
|
||||
break;
|
||||
haveLong = false;
|
||||
}
|
||||
}
|
||||
lfn[ 0 ] = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
eImageType DiskImageFileType(dir_t& dir, const char *filename)
|
||||
{
|
||||
if (filename[0] == '.')
|
||||
return DISK_IMAGE_NONE;
|
||||
|
||||
if (DIR_IS_SUBDIR(&dir))
|
||||
return DISK_IMAGE_DIRECTORY;
|
||||
|
||||
if (!DIR_IS_FILE(&dir))
|
||||
return DISK_IMAGE_NONE;
|
||||
|
||||
uint32_t size = dir.fileSize;
|
||||
|
||||
if (size == (unsigned long)1024 * 400)
|
||||
return DISK_IMAGE_400K;
|
||||
else if (size == (unsigned long)1024 * 800)
|
||||
return DISK_IMAGE_800K;
|
||||
else if (size == (unsigned long)1024 * 1440)
|
||||
return DISK_IMAGE_1440K;
|
||||
else if (size > (unsigned long)1024 * 400 &&
|
||||
size < (unsigned long)1024 * 1500)
|
||||
{
|
||||
// get the 8.3 filename
|
||||
char shortName[SHORTFILENAME_LEN+1];
|
||||
SdBaseFile::dirName(dir, shortName);
|
||||
|
||||
// read the first sector of the file
|
||||
SdBaseFile f;
|
||||
if (f.open(shortName, O_RDONLY))
|
||||
{
|
||||
f.read(extraBuf, 512);
|
||||
f.close();
|
||||
|
||||
// is it a DiskCopy 4.2 image?
|
||||
if (extraBuf[0x52] == 0x01 &&
|
||||
extraBuf[0x53] == 0x00)
|
||||
{
|
||||
size = ((unsigned long)extraBuf[0x41] * 65536 + (unsigned long)extraBuf[0x42] * 256 + (unsigned long)extraBuf[0x43]) / 1024;
|
||||
|
||||
if (size == 400)
|
||||
return DISK_IMAGE_DISKCOPY_400K;
|
||||
else if (size == 800)
|
||||
return DISK_IMAGE_DISKCOPY_800K;
|
||||
else if (size == 1440)
|
||||
return DISK_IMAGE_DISKCOPY_1440K;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DISK_IMAGE_NONE;
|
||||
}
|
||||
|
||||
uint16_t diskMenuEntryCount;
|
||||
uint16_t diskMenuOffset = 0;
|
||||
uint16_t diskMenuSelection = 0;
|
||||
char selectedFile[FILENAME_LEN+1];
|
||||
char selectedLongFile[FILENAME_LEN+1];
|
||||
eImageType selectedFileType;
|
||||
uint8_t subdirDepth = 0;
|
||||
|
||||
#define LONGFILENAME_LEN 130
|
||||
|
||||
void InitDiskMenu(SdFat& sd)
|
||||
{
|
||||
dir_t dir;
|
||||
char name[LONGFILENAME_LEN+1];
|
||||
|
||||
diskMenuEntryCount = 0;
|
||||
|
||||
// use the sector buffers to hold the filenames
|
||||
uint16_t maxEntries = SECTORBUF_SIZE / sizeof(FileEntry);
|
||||
FileEntry* pFileEntries = (FileEntry*)sectorBuf;
|
||||
|
||||
sd.vwd()->rewind();
|
||||
while (dirLfnNext(sd, dir, name) && diskMenuEntryCount < maxEntries)
|
||||
{
|
||||
eImageType imageType;
|
||||
|
||||
if ((imageType = DiskImageFileType(dir, name)) != DISK_IMAGE_NONE)
|
||||
{
|
||||
strncpy(pFileEntries[diskMenuEntryCount].longName, name, FILENAME_LEN+1);
|
||||
SdBaseFile::dirName(dir, pFileEntries[diskMenuEntryCount].shortName);
|
||||
pFileEntries[diskMenuEntryCount].imageFileType = imageType;
|
||||
diskMenuEntryCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// add up directory, if not at the root
|
||||
if (!sd.vwd()->isRoot())
|
||||
{
|
||||
strncpy(pFileEntries[diskMenuEntryCount].longName, "..", FILENAME_LEN+1);
|
||||
strncpy(pFileEntries[diskMenuEntryCount].shortName, "..", SHORTFILENAME_LEN+1);
|
||||
pFileEntries[diskMenuEntryCount].imageFileType = DISK_IMAGE_UP_DIRECTORY;
|
||||
diskMenuEntryCount++;
|
||||
}
|
||||
|
||||
char file1[FILENAME_LEN+1], file2[FILENAME_LEN+1], temp[FILENAME_LEN+1];
|
||||
eImageType tempType;
|
||||
|
||||
// sort the names by longname
|
||||
for (uint16_t i=0; i<diskMenuEntryCount; i++)
|
||||
{
|
||||
for (uint16_t j=i+1; j<diskMenuEntryCount; j++)
|
||||
{
|
||||
// convert filenames to upper case, for comparison purposes
|
||||
strncpy(file1, pFileEntries[i].longName, FILENAME_LEN+1);
|
||||
for (uint8_t x=0; x<strlen(file1); x++)
|
||||
file1[x] = toupper(file1[x]);
|
||||
|
||||
strncpy(file2, pFileEntries[j].longName, FILENAME_LEN+1);
|
||||
for (uint8_t x=0; x<strlen(file2); x++)
|
||||
file2[x] = toupper(file2[x]);
|
||||
|
||||
// sort directories before regular files
|
||||
int diff = strncmp(file1, file2, FILENAME_LEN+1);
|
||||
if (pFileEntries[i].imageFileType == DISK_IMAGE_DIRECTORY ||
|
||||
pFileEntries[i].imageFileType == DISK_IMAGE_UP_DIRECTORY)
|
||||
diff -= 1000;
|
||||
if (pFileEntries[j].imageFileType == DISK_IMAGE_DIRECTORY ||
|
||||
pFileEntries[j].imageFileType == DISK_IMAGE_UP_DIRECTORY)
|
||||
diff += 1000;
|
||||
|
||||
// if file1 > file2, swap them
|
||||
if (diff > 0)
|
||||
{
|
||||
strncpy(temp, pFileEntries[i].longName, FILENAME_LEN+1);
|
||||
strncpy(pFileEntries[i].longName, pFileEntries[j].longName, FILENAME_LEN+1);
|
||||
strncpy(pFileEntries[j].longName, temp, FILENAME_LEN+1);
|
||||
|
||||
strncpy(temp, pFileEntries[i].shortName, SHORTFILENAME_LEN+1);
|
||||
strncpy(pFileEntries[i].shortName, pFileEntries[j].shortName, SHORTFILENAME_LEN+1);
|
||||
strncpy(pFileEntries[j].shortName, temp, SHORTFILENAME_LEN+1);
|
||||
|
||||
tempType = pFileEntries[i].imageFileType;
|
||||
pFileEntries[i].imageFileType = pFileEntries[j].imageFileType;
|
||||
pFileEntries[j].imageFileType = tempType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawDiskMenu(SdFat& sd)
|
||||
{
|
||||
// scroll menu if necessary
|
||||
if (diskMenuSelection < diskMenuOffset)
|
||||
diskMenuOffset = diskMenuSelection;
|
||||
if (diskMenuSelection > diskMenuOffset+4)
|
||||
diskMenuOffset = diskMenuSelection-4;
|
||||
|
||||
LcdGoto(0,0);
|
||||
LcdWrite(LCD_DATA, 0x7F);
|
||||
for (int i=0; i<19; i++)
|
||||
LcdWrite(LCD_DATA, 0x40);
|
||||
|
||||
LcdTinyStringFramed("Select Disk");
|
||||
|
||||
for (int i=0; i<19; i++)
|
||||
LcdWrite(LCD_DATA, 0x40);
|
||||
LcdWrite(LCD_DATA, 0x7F);
|
||||
|
||||
if (diskMenuEntryCount == 0)
|
||||
{
|
||||
LcdGoto(0, 1);
|
||||
LcdTinyString("no image files found", TEXT_NORMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
FileEntry* pFileEntries = (FileEntry*)sectorBuf;
|
||||
|
||||
int row = 0;
|
||||
for (uint16_t i=diskMenuOffset; i<diskMenuOffset+5 && i<diskMenuEntryCount; i++)
|
||||
{
|
||||
bool selected = (i == diskMenuSelection);
|
||||
|
||||
LcdGoto(0, row+1);
|
||||
for (int j=0; j<LCD_WIDTH; j++)
|
||||
{
|
||||
LcdWrite(LCD_DATA, selected ? 0x7F : 0x00);
|
||||
}
|
||||
|
||||
// show the image name
|
||||
LcdGoto(1, row+1);
|
||||
LcdTinyString(pFileEntries[i].longName, selected ? TEXT_INVERSE : TEXT_NORMAL, LCD_WIDTH-1);
|
||||
|
||||
// draw a folder icon for subdirectories
|
||||
if (pFileEntries[i].imageFileType == DISK_IMAGE_DIRECTORY ||
|
||||
pFileEntries[i].imageFileType == DISK_IMAGE_UP_DIRECTORY)
|
||||
{
|
||||
LcdGoto(73, row+1);
|
||||
LcdWrite(LCD_DATA, selected ? (0x7F ^ 0x00): 0x00);
|
||||
LcdWrite(LCD_DATA, selected ? (0x7F ^ 0x3C): 0x3C);
|
||||
LcdWrite(LCD_DATA, selected ? (0x7F ^ 0x22): 0x22);
|
||||
LcdWrite(LCD_DATA, selected ? (0x7F ^ 0x22): 0x22);
|
||||
LcdWrite(LCD_DATA, selected ? (0x7F ^ 0x22): 0x22);
|
||||
LcdWrite(LCD_DATA, selected ? (0x7F ^ 0x24): 0x24);
|
||||
LcdWrite(LCD_DATA, selected ? (0x7F ^ 0x24): 0x24);
|
||||
LcdWrite(LCD_DATA, selected ? (0x7F ^ 0x3C): 0x3C);
|
||||
LcdWrite(LCD_DATA, selected ? (0x7F ^ 0x00): 0x00);
|
||||
}
|
||||
|
||||
if (selected)
|
||||
{
|
||||
strncpy(selectedLongFile, pFileEntries[i].longName, FILENAME_LEN+1);
|
||||
strncpy(selectedFile, pFileEntries[i].shortName, SHORTFILENAME_LEN+1);
|
||||
selectedFileType = pFileEntries[i].imageFileType;
|
||||
}
|
||||
|
||||
row++;
|
||||
}
|
||||
|
||||
// draw the scrollbar
|
||||
if (diskMenuEntryCount <= 5)
|
||||
{
|
||||
// no scrollbar
|
||||
for (uint8_t r=1; r<6; r++)
|
||||
{
|
||||
LcdGoto(82, r);
|
||||
LcdWrite(LCD_DATA, 0x00);
|
||||
LcdWrite(LCD_DATA, 0x00);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t barEnd = 8 + (uint16_t)39 * (diskMenuOffset + 5) / diskMenuEntryCount;
|
||||
uint8_t barSize = (uint16_t)39 * 5 / diskMenuEntryCount;
|
||||
uint8_t barStart = barEnd - barSize;
|
||||
|
||||
for (uint8_t r=1; r<6; r++)
|
||||
{
|
||||
LcdGoto(82, r);
|
||||
LcdWrite(LCD_DATA, 0x00);
|
||||
|
||||
uint8_t b = 0;
|
||||
for (uint8_t y=r*8; y<=r*8+7; y++)
|
||||
{
|
||||
if (y >= barStart && y <= barEnd)
|
||||
b = 0x80 | (b >> 1);
|
||||
else
|
||||
b = (b >> 1);
|
||||
}
|
||||
|
||||
LcdWrite(LCD_DATA, b);
|
||||
}
|
||||
}
|
||||
|
||||
// prevent moving selection past end of list
|
||||
if (diskMenuSelection >= diskMenuOffset + row)
|
||||
{
|
||||
diskMenuSelection = diskMenuOffset + row - 1;
|
||||
if (row == 4 && diskMenuOffset > 0)
|
||||
{
|
||||
diskMenuOffset--; // scroll backwards
|
||||
}
|
||||
DrawDiskMenu(sd); // draw again
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
Floppy Emu, copyright 2013 Steve Chamberlin, "Big Mess o' Wires". All rights reserved.
|
||||
|
||||
Floppy Emu is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported
|
||||
license. (CC BY-NC 3.0) The terms of the license may be viewed at
|
||||
http://creativecommons.org/licenses/by-nc/3.0/
|
||||
|
||||
Based on a work at http://www.bigmessowires.com/macintosh-floppy-emu/
|
||||
|
||||
Permissions beyond the scope of this license may be available at www.bigmessowires.com
|
||||
or from mailto:steve@bigmessowires.com.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <util/atomic.h>
|
||||
#include <util/delay.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "diskmenu.h"
|
||||
#include "SdFat.h"
|
||||
#include "SdBaseFile.h"
|
||||
#include "noklcd.h"
|
||||
|
||||
#define SECTORBUF_SIZE (23 * 512) // use the 24th buffer for directory breadcrumbs
|
||||
extern uint8_t sectorBuf[24][512];
|
||||
extern uint8_t extraBuf[512];
|
||||
|
||||
typedef struct FileEntry
|
||||
{
|
||||
char longName[FILENAME_LEN+1];
|
||||
char shortName[SHORTFILENAME_LEN+1];
|
||||
eImageType imageFileType;
|
||||
} FileEntry;
|
||||
|
||||
bool dirLfnNext(SdFat& sd, dir_t& dir, char* lfn)
|
||||
{
|
||||
uint8_t offset[] = {1, 3, 5, 7, 9, 14, 16, 18, 20, 22, 24, 28, 30};
|
||||
uint8_t lfnIn = 130;
|
||||
uint8_t i;
|
||||
uint8_t ndir=0;
|
||||
uint8_t sum;
|
||||
uint8_t test=0;
|
||||
bool haveLong = false;
|
||||
|
||||
while( sd.vwd()->read( &dir, 32 ) == 32 )
|
||||
{
|
||||
if( DIR_IS_LONG_NAME( &dir ) )
|
||||
{
|
||||
if( ! haveLong )
|
||||
{
|
||||
if(( dir.name[0] & 0XE0 ) != 0X40 )
|
||||
continue;
|
||||
ndir = dir.name[0] & 0X1F;
|
||||
test = dir.creationTimeTenths;
|
||||
haveLong = true;
|
||||
lfnIn = 130;
|
||||
lfn[ lfnIn ] = 0;
|
||||
}
|
||||
else if( dir.name[0] != --ndir || test != dir.creationTimeTenths )
|
||||
{
|
||||
haveLong = false;
|
||||
continue;
|
||||
}
|
||||
char *p = (char*) & dir;
|
||||
if( lfnIn > 0 )
|
||||
{
|
||||
lfnIn -= 13;
|
||||
for( i = 0; i < 13; i++ )
|
||||
lfn[lfnIn + i] = p[offset[i]];
|
||||
}
|
||||
}
|
||||
else if( DIR_IS_FILE_OR_SUBDIR( &dir )
|
||||
&& dir.name[0] != DIR_NAME_DELETED
|
||||
&& dir.name[0] != DIR_NAME_FREE
|
||||
&& dir.name[0] != '.')
|
||||
{
|
||||
if( haveLong )
|
||||
{
|
||||
for( sum = i = 0; i < 11; i++ )
|
||||
sum = (((sum & 1) << 7) | ((sum & 0xfe) >> 1)) + dir.name[i];
|
||||
if( sum != test || ndir != 1 )
|
||||
haveLong = false;
|
||||
}
|
||||
if( haveLong )
|
||||
{
|
||||
for( i = 0; lfnIn + i <= 130 ; i++ )
|
||||
lfn[i] = lfn[lfnIn + i];
|
||||
return true;
|
||||
}
|
||||
// else if( dir.reservedNT )
|
||||
// return "Reserved NT";
|
||||
else
|
||||
{
|
||||
SdBaseFile::dirName( dir, lfn );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( dir.name[0] == DIR_NAME_FREE )
|
||||
break;
|
||||
haveLong = false;
|
||||
}
|
||||
}
|
||||
lfn[ 0 ] = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
eImageType DiskImageFileType(dir_t& dir, const char *filename)
|
||||
{
|
||||
if (filename[0] == '.')
|
||||
return DISK_IMAGE_NONE;
|
||||
|
||||
if (DIR_IS_SUBDIR(&dir))
|
||||
return DISK_IMAGE_DIRECTORY;
|
||||
|
||||
if (!DIR_IS_FILE(&dir))
|
||||
return DISK_IMAGE_NONE;
|
||||
|
||||
uint32_t size = dir.fileSize;
|
||||
|
||||
if (size == (unsigned long)1024 * 400)
|
||||
return DISK_IMAGE_400K;
|
||||
else if (size == (unsigned long)1024 * 800)
|
||||
return DISK_IMAGE_800K;
|
||||
else if (size == (unsigned long)1024 * 1440)
|
||||
return DISK_IMAGE_1440K;
|
||||
else if (size > (unsigned long)1024 * 400 &&
|
||||
size < (unsigned long)1024 * 1500)
|
||||
{
|
||||
// get the 8.3 filename
|
||||
char shortName[SHORTFILENAME_LEN+1];
|
||||
SdBaseFile::dirName(dir, shortName);
|
||||
|
||||
// read the first sector of the file
|
||||
SdBaseFile f;
|
||||
if (f.open(shortName, O_RDONLY))
|
||||
{
|
||||
f.read(extraBuf, 512);
|
||||
f.close();
|
||||
|
||||
// is it a DiskCopy 4.2 image?
|
||||
if (extraBuf[0x52] == 0x01 &&
|
||||
extraBuf[0x53] == 0x00)
|
||||
{
|
||||
size = ((unsigned long)extraBuf[0x41] * 65536 + (unsigned long)extraBuf[0x42] * 256 + (unsigned long)extraBuf[0x43]) / 1024;
|
||||
|
||||
if (size == 400)
|
||||
return DISK_IMAGE_DISKCOPY_400K;
|
||||
else if (size == 800)
|
||||
return DISK_IMAGE_DISKCOPY_800K;
|
||||
else if (size == 1440)
|
||||
return DISK_IMAGE_DISKCOPY_1440K;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DISK_IMAGE_NONE;
|
||||
}
|
||||
|
||||
uint16_t diskMenuEntryCount;
|
||||
uint16_t diskMenuOffset = 0;
|
||||
uint16_t diskMenuSelection = 0;
|
||||
char selectedFile[FILENAME_LEN+1];
|
||||
char selectedLongFile[FILENAME_LEN+1];
|
||||
eImageType selectedFileType;
|
||||
uint8_t subdirDepth = 0;
|
||||
|
||||
#define LONGFILENAME_LEN 130
|
||||
|
||||
void InitDiskMenu(SdFat& sd)
|
||||
{
|
||||
dir_t dir;
|
||||
char name[LONGFILENAME_LEN+1];
|
||||
|
||||
diskMenuEntryCount = 0;
|
||||
|
||||
// use the sector buffers to hold the filenames
|
||||
uint16_t maxEntries = SECTORBUF_SIZE / sizeof(FileEntry);
|
||||
FileEntry* pFileEntries = (FileEntry*)sectorBuf;
|
||||
|
||||
sd.vwd()->rewind();
|
||||
while (dirLfnNext(sd, dir, name) && diskMenuEntryCount < maxEntries)
|
||||
{
|
||||
eImageType imageType;
|
||||
|
||||
if ((imageType = DiskImageFileType(dir, name)) != DISK_IMAGE_NONE)
|
||||
{
|
||||
strncpy(pFileEntries[diskMenuEntryCount].longName, name, FILENAME_LEN+1);
|
||||
SdBaseFile::dirName(dir, pFileEntries[diskMenuEntryCount].shortName);
|
||||
pFileEntries[diskMenuEntryCount].imageFileType = imageType;
|
||||
diskMenuEntryCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// add up directory, if not at the root
|
||||
if (!sd.vwd()->isRoot())
|
||||
{
|
||||
strncpy(pFileEntries[diskMenuEntryCount].longName, "..", FILENAME_LEN+1);
|
||||
strncpy(pFileEntries[diskMenuEntryCount].shortName, "..", SHORTFILENAME_LEN+1);
|
||||
pFileEntries[diskMenuEntryCount].imageFileType = DISK_IMAGE_UP_DIRECTORY;
|
||||
diskMenuEntryCount++;
|
||||
}
|
||||
|
||||
char file1[FILENAME_LEN+1], file2[FILENAME_LEN+1], temp[FILENAME_LEN+1];
|
||||
eImageType tempType;
|
||||
|
||||
// sort the names by longname
|
||||
for (uint16_t i=0; i<diskMenuEntryCount; i++)
|
||||
{
|
||||
for (uint16_t j=i+1; j<diskMenuEntryCount; j++)
|
||||
{
|
||||
// convert filenames to upper case, for comparison purposes
|
||||
strncpy(file1, pFileEntries[i].longName, FILENAME_LEN+1);
|
||||
for (uint8_t x=0; x<strlen(file1); x++)
|
||||
file1[x] = toupper(file1[x]);
|
||||
|
||||
strncpy(file2, pFileEntries[j].longName, FILENAME_LEN+1);
|
||||
for (uint8_t x=0; x<strlen(file2); x++)
|
||||
file2[x] = toupper(file2[x]);
|
||||
|
||||
// sort directories before regular files
|
||||
int diff = strncmp(file1, file2, FILENAME_LEN+1);
|
||||
if (pFileEntries[i].imageFileType == DISK_IMAGE_DIRECTORY ||
|
||||
pFileEntries[i].imageFileType == DISK_IMAGE_UP_DIRECTORY)
|
||||
diff -= 1000;
|
||||
if (pFileEntries[j].imageFileType == DISK_IMAGE_DIRECTORY ||
|
||||
pFileEntries[j].imageFileType == DISK_IMAGE_UP_DIRECTORY)
|
||||
diff += 1000;
|
||||
|
||||
// if file1 > file2, swap them
|
||||
if (diff > 0)
|
||||
{
|
||||
strncpy(temp, pFileEntries[i].longName, FILENAME_LEN+1);
|
||||
strncpy(pFileEntries[i].longName, pFileEntries[j].longName, FILENAME_LEN+1);
|
||||
strncpy(pFileEntries[j].longName, temp, FILENAME_LEN+1);
|
||||
|
||||
strncpy(temp, pFileEntries[i].shortName, SHORTFILENAME_LEN+1);
|
||||
strncpy(pFileEntries[i].shortName, pFileEntries[j].shortName, SHORTFILENAME_LEN+1);
|
||||
strncpy(pFileEntries[j].shortName, temp, SHORTFILENAME_LEN+1);
|
||||
|
||||
tempType = pFileEntries[i].imageFileType;
|
||||
pFileEntries[i].imageFileType = pFileEntries[j].imageFileType;
|
||||
pFileEntries[j].imageFileType = tempType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawDiskMenu(SdFat& sd)
|
||||
{
|
||||
// scroll menu if necessary
|
||||
if (diskMenuSelection < diskMenuOffset)
|
||||
diskMenuOffset = diskMenuSelection;
|
||||
if (diskMenuSelection > diskMenuOffset+4)
|
||||
diskMenuOffset = diskMenuSelection-4;
|
||||
|
||||
LcdGoto(0,0);
|
||||
LcdWrite(LCD_DATA, 0x7F);
|
||||
for (int i=0; i<19; i++)
|
||||
LcdWrite(LCD_DATA, 0x40);
|
||||
|
||||
LcdTinyStringFramed("Select Disk");
|
||||
|
||||
for (int i=0; i<19; i++)
|
||||
LcdWrite(LCD_DATA, 0x40);
|
||||
LcdWrite(LCD_DATA, 0x7F);
|
||||
|
||||
if (diskMenuEntryCount == 0)
|
||||
{
|
||||
LcdGoto(0, 1);
|
||||
LcdTinyString("no image files found", TEXT_NORMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
FileEntry* pFileEntries = (FileEntry*)sectorBuf;
|
||||
|
||||
int row = 0;
|
||||
for (uint16_t i=diskMenuOffset; i<diskMenuOffset+5 && i<diskMenuEntryCount; i++)
|
||||
{
|
||||
bool selected = (i == diskMenuSelection);
|
||||
|
||||
LcdGoto(0, row+1);
|
||||
for (int j=0; j<LCD_WIDTH; j++)
|
||||
{
|
||||
LcdWrite(LCD_DATA, selected ? 0x7F : 0x00);
|
||||
}
|
||||
|
||||
// show the image name
|
||||
LcdGoto(1, row+1);
|
||||
LcdTinyString(pFileEntries[i].longName, selected ? TEXT_INVERSE : TEXT_NORMAL, LCD_WIDTH-1);
|
||||
|
||||
// draw a folder icon for subdirectories
|
||||
if (pFileEntries[i].imageFileType == DISK_IMAGE_DIRECTORY ||
|
||||
pFileEntries[i].imageFileType == DISK_IMAGE_UP_DIRECTORY)
|
||||
{
|
||||
LcdGoto(73, row+1);
|
||||
LcdWrite(LCD_DATA, selected ? (0x7F ^ 0x00): 0x00);
|
||||
LcdWrite(LCD_DATA, selected ? (0x7F ^ 0x3C): 0x3C);
|
||||
LcdWrite(LCD_DATA, selected ? (0x7F ^ 0x22): 0x22);
|
||||
LcdWrite(LCD_DATA, selected ? (0x7F ^ 0x22): 0x22);
|
||||
LcdWrite(LCD_DATA, selected ? (0x7F ^ 0x22): 0x22);
|
||||
LcdWrite(LCD_DATA, selected ? (0x7F ^ 0x24): 0x24);
|
||||
LcdWrite(LCD_DATA, selected ? (0x7F ^ 0x24): 0x24);
|
||||
LcdWrite(LCD_DATA, selected ? (0x7F ^ 0x3C): 0x3C);
|
||||
LcdWrite(LCD_DATA, selected ? (0x7F ^ 0x00): 0x00);
|
||||
}
|
||||
|
||||
if (selected)
|
||||
{
|
||||
strncpy(selectedLongFile, pFileEntries[i].longName, FILENAME_LEN+1);
|
||||
strncpy(selectedFile, pFileEntries[i].shortName, SHORTFILENAME_LEN+1);
|
||||
selectedFileType = pFileEntries[i].imageFileType;
|
||||
}
|
||||
|
||||
row++;
|
||||
}
|
||||
|
||||
// draw the scrollbar
|
||||
if (diskMenuEntryCount <= 5)
|
||||
{
|
||||
// no scrollbar
|
||||
for (uint8_t r=1; r<6; r++)
|
||||
{
|
||||
LcdGoto(82, r);
|
||||
LcdWrite(LCD_DATA, 0x00);
|
||||
LcdWrite(LCD_DATA, 0x00);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t barEnd = 8 + (uint16_t)39 * (diskMenuOffset + 5) / diskMenuEntryCount;
|
||||
uint8_t barSize = (uint16_t)39 * 5 / diskMenuEntryCount;
|
||||
uint8_t barStart = barEnd - barSize;
|
||||
|
||||
for (uint8_t r=1; r<6; r++)
|
||||
{
|
||||
LcdGoto(82, r);
|
||||
LcdWrite(LCD_DATA, 0x00);
|
||||
|
||||
uint8_t b = 0;
|
||||
for (uint8_t y=r*8; y<=r*8+7; y++)
|
||||
{
|
||||
if (y >= barStart && y <= barEnd)
|
||||
b = 0x80 | (b >> 1);
|
||||
else
|
||||
b = (b >> 1);
|
||||
}
|
||||
|
||||
LcdWrite(LCD_DATA, b);
|
||||
}
|
||||
}
|
||||
|
||||
// prevent moving selection past end of list
|
||||
if (diskMenuSelection >= diskMenuOffset + row)
|
||||
{
|
||||
diskMenuSelection = diskMenuOffset + row - 1;
|
||||
if (row == 4 && diskMenuOffset > 0)
|
||||
{
|
||||
diskMenuOffset--; // scroll backwards
|
||||
}
|
||||
DrawDiskMenu(sd); // draw again
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,471 @@
|
|||
/*
|
||||
* floppy_emu_arduino.ino
|
||||
*
|
||||
* Created on: 2014/07/12
|
||||
* Author: sin
|
||||
*/
|
||||
|
||||
#include <util/delay.h>
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SdFat.h>
|
||||
|
||||
#include "portmacros.h"
|
||||
|
||||
#include "millitimer.h"
|
||||
#include "diskmenu.h"
|
||||
#include "noklcd.h"
|
||||
|
||||
#include "floppyemu.h"
|
||||
|
||||
SdFat sd;
|
||||
|
||||
void setup() {
|
||||
millitimerInit();
|
||||
ResetDiskState();
|
||||
|
||||
ShowVersion();
|
||||
|
||||
LcdClear();
|
||||
|
||||
sei();
|
||||
_delay_ms(100); // wait for pending interrupts??
|
||||
|
||||
millitimerOn();
|
||||
_delay_ms(100); // wait for pending interrupts??
|
||||
|
||||
// if select and next are both held down, enter contrast adjust mode
|
||||
if (bit_is_set(PIN(PREV_BUTTON_PORT), PREV_BUTTON_PIN) &&
|
||||
bit_is_clear(PIN(NEXT_BUTTON_PORT), NEXT_BUTTON_PIN) &&
|
||||
bit_is_clear(PIN(SELECT_BUTTON_PORT),SELECT_BUTTON_PIN))
|
||||
{
|
||||
AdjustContrast();
|
||||
}
|
||||
|
||||
//SdFat sd;
|
||||
if (!sd.init(SPI_FULL_SPEED))
|
||||
{
|
||||
snprintf(textBuf, TEXTBUF_SIZE, "SD card error %d:%d", sd.card()->errorCode(), sd.card()->errorData());
|
||||
error(textBuf);
|
||||
}
|
||||
|
||||
millitimerOff();
|
||||
|
||||
// if prev and next are both held down, enter firmware update mode
|
||||
if (bit_is_clear(PIN(PREV_BUTTON_PORT), PREV_BUTTON_PIN) &&
|
||||
bit_is_clear(PIN(NEXT_BUTTON_PORT), NEXT_BUTTON_PIN) &&
|
||||
bit_is_set(PIN(SELECT_BUTTON_PORT),SELECT_BUTTON_PIN))
|
||||
{
|
||||
PromptForFirmwareUpdate();
|
||||
}
|
||||
|
||||
InitDiskMenu(sd);
|
||||
DrawDiskMenu(sd);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// main loop
|
||||
void loop() {
|
||||
if (writeError)
|
||||
{
|
||||
// report error encounted in the interrupt routine
|
||||
error(textBuf);
|
||||
}
|
||||
|
||||
cli();
|
||||
uint8_t trackNumber = currentTrack; // save track in a local var, since currentTrack is volatile
|
||||
uint8_t sideNumber = currentSide; // save side in a local var, since currentSide is volatile
|
||||
restartDisk = false;
|
||||
sei();
|
||||
|
||||
if (diskInserted)
|
||||
{
|
||||
// show the current track and side
|
||||
snprintf(textBuf, TEXTBUF_SIZE, "%02d", trackNumber);
|
||||
LcdGoto(24,4);
|
||||
LcdTinyString(textBuf, TEXT_NORMAL);
|
||||
snprintf(textBuf, TEXTBUF_SIZE, "%d ", sideNumber);
|
||||
LcdGoto(56,4);
|
||||
LcdTinyString(textBuf, TEXT_NORMAL);
|
||||
|
||||
// sync RAM buffer with SD card when switching tracks, or also when switching sides for mfmMode
|
||||
if (prevTrack != trackNumber || (mfmMode && (prevSide != sideNumber)))
|
||||
{
|
||||
// write any dirty sectors from the previous track/side back to the SD card
|
||||
FlushDirtySectors(sd, prevTrack);
|
||||
prevTrack = trackNumber;
|
||||
prevSide = sideNumber;
|
||||
|
||||
// Also mark all the buffers on this track as invalid, since they don't contain valid data for the new track.
|
||||
for (uint8_t i=0; i<NUM_BUFFERS; i++)
|
||||
bufferState[i] &= ~BUFFER_DATA_VALID;
|
||||
}
|
||||
// continuously replay sectors from this track/side until interrupted
|
||||
while (!restartDisk)
|
||||
{
|
||||
if (writeMode)
|
||||
{
|
||||
// do nothing: incoming data is processed by the interrupt handler
|
||||
|
||||
// show write state
|
||||
LcdGoto(64,4);
|
||||
LcdTinyStringP(PSTR("Write"), TEXT_NORMAL);
|
||||
|
||||
while (!restartDisk)
|
||||
{
|
||||
}
|
||||
}
|
||||
else if (trackNumber <= 79)
|
||||
{
|
||||
uint8_t trackLen = trackLength(trackNumber);
|
||||
|
||||
// when stepping from a track with more sectors to one with fewer, current sector number could potentially
|
||||
// end up out of range
|
||||
if (currentSector >= trackLen)
|
||||
currentSector = 0;
|
||||
|
||||
bool prevMotorOn = !bit_is_clear(PIN(CPLD_STEP_DIR_MOTOR_ON_PORT), CPLD_STEP_DIR_MOTOR_ON_PIN);
|
||||
|
||||
while (true)
|
||||
{
|
||||
// check for disk eject
|
||||
if (bit_is_set(PIN(CPLD_EJECT_REQ_PORT), CPLD_EJECT_REQ_PIN))
|
||||
{
|
||||
PORT(CPLD_RD_READY_TK0_PORT) &= ~(1<<CPLD_RD_READY_TK0_PIN);
|
||||
PORT(CPLD_STEP_ACK_DISK_IN_PORT) |= (1<<CPLD_STEP_ACK_DISK_IN_PIN);
|
||||
diskInserted = false;
|
||||
|
||||
// write any dirty sectors from the current track
|
||||
FlushDirtySectors(sd, trackNumber);
|
||||
|
||||
_delay_ms(100);
|
||||
ResetDiskState();
|
||||
InitDiskMenu(sd);
|
||||
DrawDiskMenu(sd);
|
||||
|
||||
goto restart;
|
||||
}
|
||||
|
||||
// show read/idle state
|
||||
bool motorOn = bit_is_clear(PIN(CPLD_STEP_DIR_MOTOR_ON_PORT), CPLD_STEP_DIR_MOTOR_ON_PIN);
|
||||
|
||||
if (!motorOn)
|
||||
{
|
||||
// write any dirty sectors from the current track, when idle
|
||||
FlushDirtySectors(sd, trackNumber);
|
||||
}
|
||||
|
||||
if (prevMotorOn != motorOn)
|
||||
{
|
||||
prevMotorOn = motorOn;
|
||||
LcdGoto(64,4);
|
||||
if (motorOn)
|
||||
LcdTinyStringP(PSTR(" Read"), TEXT_NORMAL);
|
||||
else
|
||||
{
|
||||
LcdTinyStringP(PSTR(" Idle"), TEXT_NORMAL);
|
||||
// turn LED off when idle
|
||||
PORT(STATUS_LED_PORT) |= (1<<STATUS_LED_PIN);
|
||||
|
||||
writeDisplayTimer = 1; // clear old write alerts when going idle
|
||||
}
|
||||
}
|
||||
|
||||
// remove old write alerts when writeDisplayTimer reaches 1
|
||||
if (writeDisplayTimer == 1)
|
||||
{
|
||||
writeDisplayTimer = 0;
|
||||
LcdGoto(0,5);
|
||||
LcdTinyStringP(PSTR(" "), TEXT_NORMAL);
|
||||
}
|
||||
|
||||
uint8_t bufferNumber = mfmMode ? currentSector : (sideNumber * trackLen + currentSector);
|
||||
|
||||
bool shouldReadSector = false;
|
||||
|
||||
// atomic check and acquire of buffer lock
|
||||
cli();
|
||||
if ((bufferState[bufferNumber] & BUFFER_DATA_VALID) == 0 &&
|
||||
(bufferState[bufferNumber] & BUFFER_LOCKED) == 0)
|
||||
{
|
||||
// lock the buffer, so the Mac won't write to it while we're reading it from SD
|
||||
bufferState[bufferNumber] |= BUFFER_LOCKED;
|
||||
shouldReadSector = true;
|
||||
}
|
||||
sei();
|
||||
|
||||
// read the sector from the SD card, if necessary
|
||||
if (shouldReadSector)
|
||||
{
|
||||
uint32_t blockToRead = imageFirstBlock + ((uint32_t)trackStart(trackNumber) * numberOfDiskSides + sideNumber * trackLen + currentSector);
|
||||
|
||||
millitimerOn();
|
||||
|
||||
if (selectedFileIsDiskCopyFormat)
|
||||
{
|
||||
ReadDiskCopy42Block(sd, blockToRead, bufferNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!sd.card()->readBlock(blockToRead, sectorBuf[bufferNumber]))
|
||||
error("SD read error R");
|
||||
}
|
||||
|
||||
millitimerOff();
|
||||
|
||||
bufferState[bufferNumber] |= BUFFER_DATA_VALID;
|
||||
bufferState[bufferNumber] &= ~BUFFER_LOCKED;
|
||||
}
|
||||
|
||||
if (currentSector == 0)
|
||||
{
|
||||
if (motorOn)
|
||||
{
|
||||
// toggle LED during drive activity
|
||||
PORT(STATUS_LED_PORT) ^= (1<<STATUS_LED_PIN);
|
||||
|
||||
if (writeDisplayTimer > 1)
|
||||
writeDisplayTimer--;
|
||||
}
|
||||
|
||||
// "Flutter" the drive's TACH speed slightly, every time we pass sector 0 (about every 100-150ms). This avoids a bug
|
||||
// in P_Sony_MakeSpdTbl in the 64K ROM (used in the Mac 128K and Mac 512K) where
|
||||
// the Mac will crash if two successive TACH measurements see the exact same speed.
|
||||
tachFlutter += 25;
|
||||
if (tachFlutter >= 125)
|
||||
tachFlutter = 0;
|
||||
|
||||
// Set the timeout. OC1A will toggle after this many counts. New timeout threshold won't take effect until the next timeout.
|
||||
OCR1A = driveTachHalfPeriod - tachFlutter;
|
||||
}
|
||||
|
||||
if (mfmMode)
|
||||
{
|
||||
// insert sector-to-sector gap bytes
|
||||
for (uint8_t i=0; i<50; i++)
|
||||
{
|
||||
SendMFMAndCheckRestart(0x4E);
|
||||
}
|
||||
|
||||
// insert sync bytes
|
||||
for (uint8_t i=0; i<12; i++)
|
||||
{
|
||||
SendMFMAndCheckRestart(0x00);
|
||||
}
|
||||
|
||||
// send the address block
|
||||
crc = 0xFFFF; // reset CRC
|
||||
SendMFMSync();
|
||||
SendMFMSync();
|
||||
SendMFMSync();
|
||||
SendMFMAndCheckRestart(0xFE);
|
||||
SendMFMAndCheckRestart(trackNumber);
|
||||
SendMFMAndCheckRestart(sideNumber);
|
||||
SendMFMAndCheckRestart(currentSector+1); // MFM sector numbers are 1-based
|
||||
SendMFMAndCheckRestart(2); // size = 128 * 2^N bytes, so 2 means 512
|
||||
uint8_t crc0 = (crc >> 8) & 0xFF;
|
||||
uint8_t crc1 = crc & 0xFF;
|
||||
SendMFMAndCheckRestart(crc0);
|
||||
SendMFMAndCheckRestart(crc1);
|
||||
|
||||
// insert Address to Data gap bytes
|
||||
for (uint8_t i=0; i<22; i++)
|
||||
{
|
||||
SendMFMAndCheckRestart(0x4E);
|
||||
}
|
||||
|
||||
// insert sync bytes
|
||||
for (uint8_t i=0; i<12; i++)
|
||||
{
|
||||
SendMFMAndCheckRestart(0x00);
|
||||
}
|
||||
|
||||
// send the data block
|
||||
crc = 0xFFFF; // reset CRC
|
||||
SendMFMSync();
|
||||
SendMFMSync();
|
||||
SendMFMSync();
|
||||
SendMFMAndCheckRestart(0xFB);
|
||||
|
||||
for (uint16_t i=0; i<SECTOR_DATA_SIZE; i++)
|
||||
{
|
||||
uint8_t d = sectorBuf[bufferNumber][i];
|
||||
SendMFMAndCheckRestart(d);
|
||||
}
|
||||
|
||||
crc0 = (crc >> 8) & 0xFF;
|
||||
crc1 = crc & 0xFF;
|
||||
SendMFMAndCheckRestart(crc0);
|
||||
SendMFMAndCheckRestart(crc1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ensure a short gap between sectors - otherwise once they're all cached, one sector will appear
|
||||
// to immediately follow another on disk, which may cause problems for the Mac.
|
||||
// Bad voodoo here:
|
||||
// 1. In the Finder StuffIt copy test that sometimes dies after the first 18 tracks, the length of delay here
|
||||
// seems to affect what track it will freeze on.
|
||||
// 2. With a longer delay here, the first ~10 sectors of copying seem to have fewer or no "long writes".
|
||||
// 3. Depending on the delay here, the Transcend 2GB SD card sometimes gets "writeStop fail" when saving tracks.
|
||||
for (uint16_t i=0; i<INTER_SECTOR_GAP_SIZE; i++)
|
||||
{
|
||||
SendByteAndCheckRestart(0xFF);
|
||||
}
|
||||
|
||||
// send the address block
|
||||
uint8_t format = (numberOfDiskSides == 2) ? 0x22 : 0x02; // 0x22 = MacOS double-sided, 0x02 = single sided
|
||||
uint8_t trackLow = (uint8_t)(trackNumber & 0x3F);
|
||||
uint8_t trackHigh = (uint8_t)((sideNumber << 5) | (trackNumber >> 6));
|
||||
uint8_t checksum = (uint8_t)((trackLow ^ currentSector ^ trackHigh ^ format) & 0x3F);
|
||||
|
||||
SendByteAndCheckRestart(0xD5);
|
||||
SendByteAndCheckRestart(0xAA);
|
||||
SendByteAndCheckRestart(0x96);
|
||||
SendByteAndCheckRestart(pgm_read_byte(&sony_to_disk_byte[trackLow]));
|
||||
SendByteAndCheckRestart(pgm_read_byte(&sony_to_disk_byte[currentSector]));
|
||||
SendByteAndCheckRestart(pgm_read_byte(&sony_to_disk_byte[trackHigh]));
|
||||
SendByteAndCheckRestart(pgm_read_byte(&sony_to_disk_byte[format]));
|
||||
SendByteAndCheckRestart(pgm_read_byte(&sony_to_disk_byte[checksum]));
|
||||
SendByteAndCheckRestart(0xDE);
|
||||
SendByteAndCheckRestart(0xAA);
|
||||
|
||||
// insert sync bytes between the address and data blocks
|
||||
for (uint8_t i=0; i<ADDRESS_DATA_GAP_SIZE; i++)
|
||||
{
|
||||
SendByteAndCheckRestart(0xFF);
|
||||
}
|
||||
|
||||
// send the data block
|
||||
SendByteAndCheckRestart(0xD5);
|
||||
SendByteAndCheckRestart(0xAA);
|
||||
SendByteAndCheckRestart(0xAD);
|
||||
SendByteAndCheckRestart(pgm_read_byte(&sony_to_disk_byte[currentSector]));
|
||||
|
||||
SendGCRSectorData((const uint8_t*)sectorBuf[bufferNumber]);
|
||||
|
||||
SendByteAndCheckRestart(0xDE);
|
||||
SendByteAndCheckRestart(0xAA);
|
||||
SendByteAndCheckRestart(0xFF);
|
||||
}
|
||||
|
||||
currentSector = NextInterleavedSector(trackNumber, currentSector);
|
||||
}
|
||||
}
|
||||
}
|
||||
restart:
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!restartDisk)
|
||||
{
|
||||
// check for disk eject. This shouldn't normally happen, but if the CPLD and AVR get out of sync
|
||||
// and the CPLD thinks there's a disk while the AVR doesn't, it could.
|
||||
// But don't do this is ALL the CPLD inputs are asserted - that means you're probably midway
|
||||
// through building the hardware, and the CPLD isn't there yet.
|
||||
if (bit_is_set(PIN(CPLD_EJECT_REQ_PORT), CPLD_EJECT_REQ_PIN) &&
|
||||
!(bit_is_set(PIN(CPLD_RD_ACK_WR_TICK_PORT), CPLD_RD_ACK_WR_TICK_PIN) &&
|
||||
bit_is_set(PIN(CPLD_STEP_REQ_PORT), CPLD_STEP_REQ_PIN) &&
|
||||
bit_is_set(PIN(CPLD_WR_REQ_PORT), CPLD_WR_REQ_PIN) &&
|
||||
bit_is_set(PIN(CPLD_CURRENT_SIDE_PORT), CPLD_CURRENT_SIDE_PIN)))
|
||||
{
|
||||
// reboot
|
||||
((void(*)(void))0)();
|
||||
}
|
||||
|
||||
if (bit_is_clear(PIN(PREV_BUTTON_PORT), PREV_BUTTON_PIN))
|
||||
{
|
||||
if (diskMenuSelection > 0)
|
||||
{
|
||||
diskMenuSelection--;
|
||||
DrawDiskMenu(sd);
|
||||
_delay_ms(200);
|
||||
}
|
||||
}
|
||||
else if (bit_is_clear(PIN(NEXT_BUTTON_PORT), NEXT_BUTTON_PIN))
|
||||
{
|
||||
diskMenuSelection++;
|
||||
DrawDiskMenu(sd);
|
||||
_delay_ms(200);
|
||||
}
|
||||
else if (bit_is_clear(PIN(SELECT_BUTTON_PORT), SELECT_BUTTON_PIN))
|
||||
{
|
||||
if (selectedFileType == DISK_IMAGE_DIRECTORY)
|
||||
{
|
||||
// remember where we came from, so we can get back later
|
||||
char* pSubdirName = ((char*)sectorBuf[23]) + ((SHORTFILENAME_LEN+1) * subdirDepth);
|
||||
strncpy(pSubdirName, selectedFile, SHORTFILENAME_LEN+1);
|
||||
subdirDepth++;
|
||||
|
||||
sd.chdir(selectedFile, true);
|
||||
|
||||
diskMenuSelection = 0;
|
||||
LcdClear();
|
||||
InitDiskMenu(sd);
|
||||
DrawDiskMenu(sd);
|
||||
_delay_ms(400);
|
||||
}
|
||||
else if (selectedFileType == DISK_IMAGE_UP_DIRECTORY)
|
||||
{
|
||||
subdirDepth--;
|
||||
sd.chdir(true); // go to root directory
|
||||
|
||||
for (uint8_t i=0; i<subdirDepth; i++)
|
||||
{
|
||||
char* pSubdirName = ((char*)sectorBuf[23]) + ((SHORTFILENAME_LEN+1) * i);
|
||||
sd.chdir(pSubdirName, true);
|
||||
}
|
||||
|
||||
diskMenuSelection = 0;
|
||||
LcdClear();
|
||||
InitDiskMenu(sd);
|
||||
DrawDiskMenu(sd);
|
||||
_delay_ms(400);
|
||||
}
|
||||
else
|
||||
{
|
||||
// enable the interrupts
|
||||
PCICR |= (1<<CPLD_STEP_REQ_INT_ENABLE);
|
||||
PCICR |= (1<<CPLD_CURRENT_SIDE_INT_ENABLE);
|
||||
PCICR |= (1<<CPLD_WR_REQ_INT_ENABLE);
|
||||
PCICR |= (1<<CPLD_RD_ACK_WR_TICK_INT_ENABLE);
|
||||
|
||||
currentTrack = 0;
|
||||
LcdReset(); // also resets the CPLD, ensures it knows we're now at track 0
|
||||
LcdClear();
|
||||
|
||||
// "insert" the disk
|
||||
if (OpenImageFile())
|
||||
{
|
||||
// tell the CPLD whether the disk is read-only (bit 0, active low)
|
||||
uint8_t configByte = 0;
|
||||
|
||||
if (!readOnly)
|
||||
configByte |= 0x01;
|
||||
|
||||
if (!mfmMode)
|
||||
configByte |= 0x02;
|
||||
|
||||
PORT(CPLD_DATA_PORT) = configByte;
|
||||
// asserting RD_READY without DISK_IN causes the CPLD to load config options from the data bus
|
||||
PORT(CPLD_RD_READY_TK0_PORT) |= (1<<CPLD_RD_READY_TK0_PIN);
|
||||
_delay_ms(1);
|
||||
PORT(CPLD_RD_READY_TK0_PORT) &= ~(1<<CPLD_RD_READY_TK0_PIN);
|
||||
_delay_us(10);
|
||||
|
||||
// tell the CPLD there is a disk
|
||||
PORT(CPLD_STEP_ACK_DISK_IN_PORT) &= ~(1<<CPLD_STEP_ACK_DISK_IN_PIN);
|
||||
diskInserted = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# AvrStudio Solution File, Format Version 11.00
|
||||
Project("{E66E83B9-2572-4076-B26E-6BE79FF3018A}") = "floppyemu", "floppyemu.cppproj", "{E27520EB-9B21-411F-B8C6-71C8E4B8B1B6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|AVR = Debug|AVR
|
||||
Release|AVR = Release|AVR
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{E27520EB-9B21-411F-B8C6-71C8E4B8B1B6}.Debug|AVR.ActiveCfg = Debug|AVR
|
||||
{E27520EB-9B21-411F-B8C6-71C8E4B8B1B6}.Debug|AVR.Build.0 = Debug|AVR
|
||||
{E27520EB-9B21-411F-B8C6-71C8E4B8B1B6}.Release|AVR.ActiveCfg = Release|AVR
|
||||
{E27520EB-9B21-411F-B8C6-71C8E4B8B1B6}.Release|AVR.Build.0 = Release|AVR
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
Binary file not shown.
3582
arduino/floppyemu/floppyemu.ino → floppy_emu_arduino/floppyemu.cpp
Normal file → Executable file
3582
arduino/floppyemu/floppyemu.ino → floppy_emu_arduino/floppyemu.cpp
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,189 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectVersion>5.1</ProjectVersion>
|
||||
<ProjectGuid>{e27520eb-9b21-411f-b8c6-71c8e4b8b1b6}</ProjectGuid>
|
||||
<avrdevice>ATmega1284P</avrdevice>
|
||||
<avrdeviceseries>none</avrdeviceseries>
|
||||
<OutputType>Executable</OutputType>
|
||||
<Language>CPP</Language>
|
||||
<OutputDirectory>$(MSBuildProjectDirectory)\$(Configuration)</OutputDirectory>
|
||||
<AvrGccProjectExtensions>
|
||||
</AvrGccProjectExtensions>
|
||||
<AssemblyName>floppyemu</AssemblyName>
|
||||
<Name>floppyemu</Name>
|
||||
<RootNamespace>floppyemu</RootNamespace>
|
||||
<avrtool>com.atmel.avrdbg.tool.ispmk2</avrtool>
|
||||
<ToolchainName>com.Atmel.AVRGCC8</ToolchainName>
|
||||
<ToolchainFlavour>Native</ToolchainFlavour>
|
||||
<AsfVersion>2.11.1</AsfVersion>
|
||||
<avrtoolinterface>ISP</avrtoolinterface>
|
||||
<com_atmel_avrdbg_tool_ispmk2>
|
||||
<ToolType xmlns="">com.atmel.avrdbg.tool.ispmk2</ToolType>
|
||||
<ToolName xmlns="">AVRISP mkII</ToolName>
|
||||
<ToolNumber xmlns="">000200006259</ToolNumber>
|
||||
<Channel xmlns="">
|
||||
<host>127.0.0.1</host>
|
||||
<port>49229</port>
|
||||
<ssl>False</ssl>
|
||||
</Channel>
|
||||
<ToolOptions xmlns="">
|
||||
<InterfaceName>JTAG</InterfaceName>
|
||||
<InterfaceProperties>
|
||||
<JtagDbgClock>1000000</JtagDbgClock>
|
||||
<JtagProgClock>1000000</JtagProgClock>
|
||||
<IspClock>150000</IspClock>
|
||||
<JtagInChain>false</JtagInChain>
|
||||
<JtagEnableExtResetOnStartSession>false</JtagEnableExtResetOnStartSession>
|
||||
<JtagDevicesBefore>0</JtagDevicesBefore>
|
||||
<JtagDevicesAfter>0</JtagDevicesAfter>
|
||||
<JtagInstrBitsBefore>0</JtagInstrBitsBefore>
|
||||
<JtagInstrBitsAfter>0</JtagInstrBitsAfter>
|
||||
</InterfaceProperties>
|
||||
</ToolOptions>
|
||||
</com_atmel_avrdbg_tool_ispmk2>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<OutputFileName>floppyemu</OutputFileName>
|
||||
<OutputFileExtension>.elf</OutputFileExtension>
|
||||
<ToolchainSettings>
|
||||
<AvrGccCpp>
|
||||
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||
<avrgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>True</avrgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>
|
||||
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
|
||||
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
|
||||
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
|
||||
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||
<avrgcccpp.compiler.symbols.DefSymbols>
|
||||
<ListValues>
|
||||
<Value>F_CPU=20000000</Value>
|
||||
</ListValues>
|
||||
</avrgcccpp.compiler.symbols.DefSymbols>
|
||||
<avrgcccpp.compiler.directories.IncludePaths>
|
||||
<ListValues>
|
||||
<Value>../SdFat</Value>
|
||||
<Value>../xsvf</Value>
|
||||
</ListValues>
|
||||
</avrgcccpp.compiler.directories.IncludePaths>
|
||||
<avrgcccpp.compiler.optimization.level>Optimize more (-O2)</avrgcccpp.compiler.optimization.level>
|
||||
<avrgcccpp.compiler.optimization.PrepareFunctionsForGarbageCollection>True</avrgcccpp.compiler.optimization.PrepareFunctionsForGarbageCollection>
|
||||
<avrgcccpp.compiler.optimization.PackStructureMembers>True</avrgcccpp.compiler.optimization.PackStructureMembers>
|
||||
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
|
||||
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
|
||||
<avrgcccpp.linker.libraries.Libraries>
|
||||
<ListValues>
|
||||
<Value>m</Value>
|
||||
</ListValues>
|
||||
</avrgcccpp.linker.libraries.Libraries>
|
||||
<avrgcccpp.linker.optimization.GarbageCollectUnusedSections>True</avrgcccpp.linker.optimization.GarbageCollectUnusedSections>
|
||||
<avrgcccpp.linker.optimization.RelaxBranches>True</avrgcccpp.linker.optimization.RelaxBranches>
|
||||
<avrgcccpp.linker.memorysettings.Flash>
|
||||
<ListValues>
|
||||
<Value>.bootldrinfo=0xF7FC</Value>
|
||||
</ListValues>
|
||||
</avrgcccpp.linker.memorysettings.Flash>
|
||||
</AvrGccCpp>
|
||||
</ToolchainSettings>
|
||||
<UsesExternalMakeFile>True</UsesExternalMakeFile>
|
||||
<OutputDirectory>C:\Users\chamberlin\Documents\floppyemu\AVR\Release</OutputDirectory>
|
||||
<ExternalMakeFilePath>C:\Users\chamberlin\Documents\floppyemu\AVR\Release\Makefile</ExternalMakeFilePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<OutputFileName>floppyemu</OutputFileName>
|
||||
<OutputFileExtension>.elf</OutputFileExtension>
|
||||
<ToolchainSettings>
|
||||
<AvrGccCpp>
|
||||
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
|
||||
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
|
||||
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
|
||||
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||
<avrgcccpp.compiler.optimization.PackStructureMembers>True</avrgcccpp.compiler.optimization.PackStructureMembers>
|
||||
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
|
||||
<avrgcccpp.compiler.optimization.DebugLevel>Default (-g2)</avrgcccpp.compiler.optimization.DebugLevel>
|
||||
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
|
||||
<avrgcccpp.linker.libraries.Libraries>
|
||||
<ListValues>
|
||||
<Value>m</Value>
|
||||
</ListValues>
|
||||
</avrgcccpp.linker.libraries.Libraries>
|
||||
<avrgcccpp.assembler.debugging.DebugLevel>Default (-g2)</avrgcccpp.assembler.debugging.DebugLevel>
|
||||
</AvrGccCpp>
|
||||
</ToolchainSettings>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="cardtest.cpp">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="cardtest.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="diskmenu.cpp">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="diskmenu.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="floppyemu.cpp">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="millitimer.cpp">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="millitimer.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="noklcd.cpp">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="noklcd.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SdFat\Sd2Card.cpp">
|
||||
<SubType>compile</SubType>
|
||||
<Link>Sd2Card.cpp</Link>
|
||||
</Compile>
|
||||
<Compile Include="SdFat\SdBaseFile.cpp">
|
||||
<SubType>compile</SubType>
|
||||
<Link>SdBaseFile.cpp</Link>
|
||||
</Compile>
|
||||
<Compile Include="SdFat\SdFat.cpp">
|
||||
<SubType>compile</SubType>
|
||||
<Link>SdFat.cpp</Link>
|
||||
</Compile>
|
||||
<Compile Include="SdFat\SdVolume.cpp">
|
||||
<SubType>compile</SubType>
|
||||
<Link>SdVolume.cpp</Link>
|
||||
</Compile>
|
||||
<Compile Include="xsvf\lenval.cpp">
|
||||
<SubType>compile</SubType>
|
||||
<Link>lenval.cpp</Link>
|
||||
</Compile>
|
||||
<Compile Include="xsvf\lenval.h">
|
||||
<SubType>compile</SubType>
|
||||
<Link>lenval.h</Link>
|
||||
</Compile>
|
||||
<Compile Include="xsvf\micro.cpp">
|
||||
<SubType>compile</SubType>
|
||||
<Link>micro.cpp</Link>
|
||||
</Compile>
|
||||
<Compile Include="xsvf\micro.h">
|
||||
<SubType>compile</SubType>
|
||||
<Link>micro.h</Link>
|
||||
</Compile>
|
||||
<Compile Include="xsvf\ports.cpp">
|
||||
<SubType>compile</SubType>
|
||||
<Link>ports.cpp</Link>
|
||||
</Compile>
|
||||
<Compile Include="xsvf\ports.h">
|
||||
<SubType>compile</SubType>
|
||||
<Link>ports.h</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\AvrGCC.targets" />
|
||||
</Project>
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* floppyemu.h
|
||||
*
|
||||
* Created on: 2014/07/12
|
||||
* Author: sin
|
||||
*/
|
||||
|
||||
#ifndef FLOPPYEMU_H_
|
||||
#define FLOPPYEMU_H_
|
||||
|
||||
// I/O pin assignments
|
||||
#define CPLD_RESET_PORT B
|
||||
#define CPLD_RESET_PIN 0
|
||||
|
||||
#define CPLD_STEP_DIR_MOTOR_ON_PORT C
|
||||
#define CPLD_STEP_DIR_MOTOR_ON_PIN 7
|
||||
|
||||
#define CPLD_STEP_REQ_PORT D
|
||||
#define CPLD_STEP_REQ_PIN 0 // PCINT24
|
||||
#define CPLD_STEP_REQ_INT_MSK PCMSK3
|
||||
#define CPLD_STEP_REQ_INT_PIN PCINT24
|
||||
#define CPLD_STEP_REQ_INT_ENABLE PCIE3
|
||||
|
||||
#define CPLD_CURRENT_SIDE_PORT C
|
||||
#define CPLD_CURRENT_SIDE_PIN 1 // PCINT17
|
||||
#define CPLD_CURRENT_SIDE_INT_MSK PCMSK2
|
||||
#define CPLD_CURRENT_SIDE_INT_PIN PCINT17
|
||||
#define CPLD_CURRENT_SIDE_INT_ENABLE PCIE2
|
||||
|
||||
#define CPLD_EJECT_REQ_PORT D
|
||||
#define CPLD_EJECT_REQ_PIN 3
|
||||
|
||||
#define CPLD_STEP_ACK_DISK_IN_PORT C
|
||||
#define CPLD_STEP_ACK_DISK_IN_PIN 2
|
||||
|
||||
#define CPLD_WR_REQ_PORT C
|
||||
#define CPLD_WR_REQ_PIN 0 // PCINT16
|
||||
#define CPLD_WR_REQ_INT_MSK PCMSK2
|
||||
#define CPLD_WR_REQ_INT_PIN PCINT16
|
||||
#define CPLD_WR_REQ_INT_ENABLE PCIE2
|
||||
|
||||
#define CPLD_RD_READY_TK0_PORT C
|
||||
#define CPLD_RD_READY_TK0_PIN 5
|
||||
|
||||
#define CPLD_RD_ACK_WR_TICK_PORT A
|
||||
#define CPLD_RD_ACK_WR_TICK_PIN 7 // PCINT7
|
||||
#define CPLD_RD_ACK_WR_TICK_INT_MSK PCMSK0
|
||||
#define CPLD_RD_ACK_WR_TICK_INT_PIN PCINT7
|
||||
#define CPLD_RD_ACK_WR_TICK_INT_ENABLE PCIE0
|
||||
|
||||
#define CPLD_DATA_PORT A
|
||||
|
||||
#define CPLD_DATA_HIZ_PORT C
|
||||
#define CPLD_DATA_HIZ_PIN 6
|
||||
|
||||
#define CPLD_TACH_PORT D
|
||||
#define CPLD_TACH_PIN 5
|
||||
|
||||
#define CPLD_TMS_PORT C
|
||||
#define CPLD_TMS_PIN 3
|
||||
|
||||
#define SELECT_BUTTON_PORT D
|
||||
#define SELECT_BUTTON_PIN 4
|
||||
|
||||
#define PREV_BUTTON_PORT D
|
||||
#define PREV_BUTTON_PIN 1
|
||||
|
||||
#define NEXT_BUTTON_PORT D
|
||||
#define NEXT_BUTTON_PIN 2
|
||||
|
||||
#define STATUS_LED_PORT B
|
||||
#define STATUS_LED_PIN 3
|
||||
|
||||
#define CARD_WPROT_PORT D
|
||||
#define CARD_WPROT_PIN 7
|
||||
|
||||
// global variables predefinitions
|
||||
|
||||
#define TEXTBUF_SIZE 22
|
||||
char textBuf[TEXTBUF_SIZE];
|
||||
|
||||
volatile uint8_t currentTrack;
|
||||
volatile uint8_t prevTrack;
|
||||
volatile uint8_t currentSide;
|
||||
volatile uint8_t prevSide;
|
||||
volatile uint8_t writeMode;
|
||||
volatile bool restartDisk;
|
||||
volatile bool writeError;
|
||||
|
||||
bool diskInserted;
|
||||
bool readOnly;
|
||||
bool mfmMode;
|
||||
uint16_t crc;
|
||||
uint8_t numberOfDiskSides;
|
||||
uint8_t currentSector;
|
||||
uint16_t driveTachHalfPeriod;
|
||||
uint8_t tachFlutter;
|
||||
|
||||
uint8_t writeDisplayTimer;
|
||||
uint8_t cpldFirmwareVersion;
|
||||
|
||||
// public functions predefinitions
|
||||
|
||||
void ResetDiskState();
|
||||
void ShowVersion();
|
||||
void AdjustContrast(void);
|
||||
void error(const char* msg);
|
||||
void PromptForFirmwareUpdate();
|
||||
|
||||
#endif /* FLOPPYEMU_H_ */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue