This commit is contained in:
Sin Shimozono 2014-07-12 22:45:56 +09:00
parent 1a384a699e
commit 87d2b6dfce
107 changed files with 2995 additions and 21031 deletions

View File

@ -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="&quot;${workspace_loc:/mac-floppy-emu/floppyemu/SdFat}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mac-floppy-emu/floppyemu/xsvf}&quot;"/>
</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="&quot;${workspace_loc:/mac-floppy-emu/floppyemu/SdFat}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mac-floppy-emu/floppyemu/xsvf}&quot;"/>
</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="&quot;${workspace_loc:/mac-floppy-emu/floppyemu/SdFat}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mac-floppy-emu/floppyemu/xsvf}&quot;"/>
</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="&quot;${workspace_loc:/mac-floppy-emu/AVR}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mac-floppy-emu/AVR/bootldr}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mac-floppy-emu/AVR/SdFat}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mac-floppy-emu/AVR/xsvf}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mac-floppy-emu/floppyemu/SdFat}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mac-floppy-emu/floppyemu/xsvf}&quot;"/>
</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="&quot;${workspace_loc:/mac-floppy-emu/AVR}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mac-floppy-emu/AVR/bootldr}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mac-floppy-emu/AVR/SdFat}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mac-floppy-emu/AVR/xsvf}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mac-floppy-emu/floppyemu/SdFat}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mac-floppy-emu/floppyemu/xsvf}&quot;"/>
</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="&quot;${workspace_loc:/mac-floppy-emu/AVR}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mac-floppy-emu/AVR/bootldr}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mac-floppy-emu/AVR/SdFat}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mac-floppy-emu/AVR/xsvf}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mac-floppy-emu/floppyemu/SdFat}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mac-floppy-emu/floppyemu/xsvf}&quot;"/>
</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>

3
arduino/.gitignore vendored
View File

@ -1,3 +0,0 @@
/Debug/
/Bootloader/
/Flash/

View File

@ -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>

View File

@ -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.

View File

@ -1 +0,0 @@
verilog work "floppyemu.v"

View File

@ -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%;

View File

@ -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

View File

@ -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="&lt;>" 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 &amp; 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>

View File

@ -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

View File

@ -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.

View File

@ -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)

View File

@ -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.

View File

@ -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.

1
floppy_emu_arduino/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/Debug/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -7,14 +7,10 @@
#include <avr/io.h>
#ifdef USE_BOOTLDR_MAIN
int main(void)
{
while(1)
{
//TODO:: Please write your application code
}
}
#endif
}

View File

@ -146,4 +146,4 @@ void LcdInit()
LcdGoto(0,0);
LcdClear();
}
}

View 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);
}

View File

@ -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
}
}
}

View File

@ -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;
}
}
}
}

View File

@ -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.

File diff suppressed because it is too large Load Diff

View File

@ -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>

View File

@ -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