Browse Source

archive MK1 AVR source

ikari 13 years ago
parent
commit
a9b84c3e0b

+ 2 - 0
cic/supercic/supercic-key.asm

@@ -673,6 +673,8 @@ longwait0
 
 ; --------change region in eeprom and die--------
 die
+	movlw	0x3a		;wait 50ms before writing
+	call	longwait	;("error" might be due to power loss)
 	banksel	EEADR
 	clrw
 	movwf	EEADR

+ 619 - 0
mk1-src/Makefile

@@ -0,0 +1,619 @@
+# Hey Emacs, this is a -*- makefile -*-
+
+# Define version number
+MAJOR = 0
+MINOR = 0
+PATCHLEVEL = 1
+FIX =
+
+# Forces bootloader version to 0, comment out for release
+#PRERELEASE =
+
+#----------------------------------------------------------------------------
+# WinAVR Makefile Template written by Eric B. Weddington, Joerg Wunsch, et al.
+#
+# Released to the Public Domain
+#
+# Additional material for this makefile was written by:
+# Peter Fleury
+# Tim Henigan
+# Colin O'Flynn
+# Reiner Patommel
+# Markus Pfaff
+# Sander Pool
+# Frederik Rouleau
+# Carlos Lamas
+#
+#
+# Extensively modified for sd2iec by Ingo Korb
+#
+# To rebuild project do "make clean" then "make all".
+#----------------------------------------------------------------------------
+
+# Read configuration file
+ifdef CONFIG
+ CONFIGSUFFIX = $(CONFIG:config%=%)
+else
+ CONFIG = config
+ CONFIGSUFFIX =
+endif
+
+# Enable verbose compilation with "make V=1"
+ifdef V
+ Q :=
+ E := @:
+else
+ Q := @
+ E := @echo
+endif
+
+# Include the configuration file
+include $(CONFIG)
+
+# Set MCU name and length of binary for bootloader
+# WARNING: Fuse settings not tested!
+MCU := $(CONFIG_MCU)
+ifeq ($(MCU),atmega128)
+  BINARY_LENGTH = 0x1f000
+#  EFUSE = 0xff
+#  HFUSE = 0x91
+#  LFUSE = 0xaf
+else ifeq ($(MCU),atmega1281)
+  BINARY_LENGTH = 0x1f000
+  BOOTLDRSIZE = 0x0800
+  EFUSE = 0xff
+  HFUSE = 0xd2
+  LFUSE = 0xfc
+else ifeq ($(MCU),atmega2561)
+  BINARY_LENGTH = 0x3f000
+  EFUSE = 0xfd
+  HFUSE = 0x93
+  LFUSE = 0xef
+else ifeq ($(MCU),atmega644)
+  BINARY_LENGTH = 0xf000
+  EFUSE = 0xfd
+  HFUSE = 0x91
+#  LFUSE = 0xef
+  LFUSE = 0xaf
+else ifeq ($(MCU),atmega644p)
+  BINARY_LENGTH = 0xf000
+  EFUSE = 0xfd
+  HFUSE = 0x91
+  LFUSE = 0xef
+else
+.PHONY: nochip
+nochip:
+	@echo '=============================================================='
+	@echo 'No known target chip specified.'
+	@echo
+	@echo 'Please edit the Makefile.'
+	@exit 1
+endif
+
+# Directory for all generated files
+OBJDIR := obj-$(CONFIG_MCU:atmega%=m%)$(CONFIGSUFFIX)
+
+# Output format. (can be srec, ihex, binary)
+FORMAT = ihex
+
+
+# Target file name (without extension).
+TARGET = $(OBJDIR)/sd2snes
+
+# List C source files here. (C dependencies are automatically generated.)
+SRC = main.c ff.c utils.c led.c diskio.c sdcard.c spi.c crc7.c snes.c fpga.c memory.c crc16.c fileops.c fpga_spi.c smc.c filetypes.c
+
+ifeq ($(CONFIG_UART_DEBUG),y)
+  SRC += uart.c
+endif
+
+# List Assembler source files here.
+#     Make them always end in a capital .S.  Files ending in a lowercase .s
+#     will not be considered source files but generated files (assembler
+#     output from the compiler), and will be deleted upon "make clean"!
+#     Even though the DOS/Win* filesystem matches both .s and .S the same,
+#     it will preserve the spelling of the filenames, and gcc itself does
+#     care about how the name is spelled on its command-line.
+ASRC =
+
+# Optimization level, can be [0, 1, 2, 3, s].
+#     0 = turn off optimization. s = optimize for size.
+#     (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
+# Use s -mcall-prologues when you really need size...
+OPT = s
+#OPT = 3 -finline-functions
+
+# Debugging format.
+#     Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
+#     AVR Studio 4.10 requires dwarf-2.
+#     AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
+DEBUG = dwarf-2
+
+
+# List any extra directories to look for include files here.
+#     Each directory must be seperated by a space.
+#     Use forward slashes for directory separators.
+#     For a directory that has spaces, enclose it in quotes.
+EXTRAINCDIRS =
+
+
+# Compiler flag to set the C Standard level.
+#     c89   = "ANSI" C
+#     gnu89 = c89 plus GCC extensions
+#     c99   = ISO C99 standard (not yet fully implemented)
+#     gnu99 = c99 plus GCC extensions
+CSTANDARD = -std=gnu99
+
+
+# Place -D or -U options here
+CDEFS = -DF_CPU=$(CONFIG_MCU_FREQ)UL
+
+# Calculate bootloader version
+ifdef PRERELEASE
+BOOT_VERSION := 0
+else
+BOOT_VERSION := 0x$(MAJOR)$(MINOR)$(PATCHLEVEL)$(FIX)
+endif
+
+# Create a version number define
+ifdef PATCHLEVEL
+ifdef FIX
+PROGRAMVERSION := $(MAJOR).$(MINOR).$(PATCHLEVEL).$(FIX)
+else
+PROGRAMVERSION := $(MAJOR).$(MINOR).$(PATCHLEVEL)
+BOOT_VERSION := $(BOOT_VERSION)0
+endif
+else
+PROGRAMVERSION := $(MAJOR).$(MINOR)
+BOOT_VERSION := $(BOOT_VERSION)00
+endif
+
+ifdef PRERELEASE
+PROGRAMVERSION := $(PROGRAMVERSION)$(PRERELEASE)
+endif
+
+LONGVERSION := -$(CONFIG_MCU:atmega%=m%)$(CONFIGSUFFIX)
+
+CDEFS += -DVERSION=\"$(PROGRAMVERSION)\" -DLONGVERSION=\"$(LONGVERSION)\"
+
+# Place -I options here
+CINCS =
+
+
+# Define programs and commands.
+# CC must be defined here to generate the correct CFLAGS
+SHELL = sh
+CC = avr-gcc
+OBJCOPY = avr-objcopy
+OBJDUMP = avr-objdump
+SIZE = avr-size
+NM = avr-nm
+AVRDUDE = avrdude
+REMOVE = rm -f
+COPY = cp
+WINSHELL = cmd
+
+
+#---------------- Compiler Options ----------------
+#  -g*:          generate debugging information
+#  -O*:          optimization level
+#  -f...:        tuning, see GCC manual and avr-libc documentation
+#  -Wall...:     warning level
+#  -Wa,...:      tell GCC to pass this to the assembler.
+#    -adhlns...: create assembler listing
+CFLAGS = -g$(DEBUG)
+CFLAGS += $(CDEFS) $(CINCS)
+CFLAGS += -O$(OPT)
+CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
+CFLAGS += -Wall -Wstrict-prototypes -Werror
+CFLAGS += -Wa,-adhlns=$(OBJDIR)/$(<:.c=.lst)
+CFLAGS += -I$(OBJDIR)
+CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
+CFLAGS += $(CSTANDARD)
+CFLAGS += -ffunction-sections -fdata-sections
+#CFLAGS += -mcall-prologues
+
+# these are needed for GCC 4.3.2, which is more aggressive at inlining
+# gcc-4.2 knows one of those, but it tends to increase code size
+ifeq ($(shell $(CC) --version|gawk -f gcctest.awk),YES)
+CFLAGS += --param inline-call-cost=3
+CFLAGS += -fno-inline-small-functions
+CFLAGS += -fno-move-loop-invariants
+CFLAGS += -fno-split-wide-types
+
+# turn these on to keep the functions in the same order as in the source
+# this is only useful if you're looking at disassembly
+#CFLAGS += -fno-reorder-blocks
+#CFLAGS += -fno-reorder-blocks-and-partition
+#CFLAGS += -fno-reorder-functions
+#CFLAGS += -fno-toplevel-reorder
+endif
+
+ifeq ($(CONFIG_STACK_TRACKING),y)
+  CFLAGS += -finstrument-functions
+endif
+
+
+#---------------- Assembler Options ----------------
+#  -Wa,...:   tell GCC to pass this to the assembler.
+#  -ahlms:    create listing
+#  -gstabs:   have the assembler create line number information; note that
+#             for use in COFF files, additional information about filenames
+#             and function names needs to be present in the assembler source
+#             files -- see avr-libc docs [FIXME: not yet described there]
+ASFLAGS = -Wa,-adhlns=$(OBJDIR)/$(<:.S=.lst),-gstabs -I$(OBJDIR)
+
+
+#---------------- Library Options ----------------
+# Minimalistic printf version
+PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
+
+# Floating point printf version (requires MATH_LIB = -lm below)
+PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
+
+# If this is left blank, then it will use the Standard printf version.
+PRINTF_LIB =
+#PRINTF_LIB = $(PRINTF_LIB_MIN)
+#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
+
+
+# Minimalistic scanf version
+SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
+
+# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
+SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
+
+# If this is left blank, then it will use the Standard scanf version.
+SCANF_LIB =
+#SCANF_LIB = $(SCANF_LIB_MIN)
+#SCANF_LIB = $(SCANF_LIB_FLOAT)
+
+
+MATH_LIB = -lm
+
+
+
+#---------------- External Memory Options ----------------
+
+# 64 KB of external RAM, starting after internal RAM (ATmega128!),
+# used for variables (.data/.bss) and heap (malloc()).
+#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
+
+# 64 KB of external RAM, starting after internal RAM (ATmega128!),
+# only used for heap (malloc()).
+#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff
+
+EXTMEMOPTS =
+
+
+
+#---------------- Linker Options ----------------
+#  -Wl,...:     tell GCC to pass this to linker.
+#    -Map:      create map file
+#    --cref:    add cross reference to  map file
+LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
+LDFLAGS += $(EXTMEMOPTS)
+LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
+LDFLAGS += -Wl,--gc-sections
+ifeq ($(CONFIG_LINKER_RELAX),y)
+  LDFLAGS += -Wl,-O9,--relax
+endif
+
+
+
+#---------------- Programming Options (avrdude) ----------------
+
+# Programming hardware: alf avr910 avrisp bascom bsd
+# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 stk500v2
+#
+# Type: avrdude -c ?
+# to get a full listing.
+#
+AVRDUDE_PROGRAMMER = dragon_isp
+
+# com1 = serial port. Use lpt1 to connect to parallel port.
+AVRDUDE_PORT = usb   # programmer connected to serial device
+
+AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
+# AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
+
+# Allow fuse overrides from the config file
+ifdef CONFIG_EFUSE
+  EFUSE := CONFIG_EFUSE
+endif
+ifdef CONFIG_HFUSE
+  HFUSE := CONFIG_HFUSE
+endif
+ifdef CONFIG_LFUSE
+  LFUSE := CONFIG_LFUSE
+endif
+
+# Calculate command line arguments for fuses
+AVRDUDE_WRITE_FUSES :=
+ifdef EFUSE
+  AVRDUDE_WRITE_FUSES += -U efuse:w:$(EFUSE):m
+endif
+ifdef HFUSE
+  AVRDUDE_WRITE_FUSES += -U hfuse:w:$(HFUSE):m
+endif
+ifdef LFUSE
+  AVRDUDE_WRITE_FUSES += -U lfuse:w:$(LFUSE):m
+endif
+
+
+# Uncomment the following if you want avrdude's erase cycle counter.
+# Note that this counter needs to be initialized first using -Yn,
+# see avrdude manual.
+AVRDUDE_ERASE_COUNTER = -y
+
+# Uncomment the following if you do /not/ wish a verification to be
+# performed after programming the device.
+#AVRDUDE_NO_VERIFY = -V
+
+# Increase verbosity level.  Please use this when submitting bug
+# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
+# to submit bug reports.
+#AVRDUDE_VERBOSE = -v -v
+
+AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
+AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
+AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
+AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
+
+
+
+#---------------- Debugging Options ----------------
+
+# For simulavr only - target MCU frequency.
+DEBUG_MFREQ = $(CONFIG_MCU_FREQ)
+
+# Set the DEBUG_UI to either gdb or insight.
+# DEBUG_UI = gdb
+DEBUG_UI = insight
+
+# Set the debugging back-end to either avarice, simulavr.
+DEBUG_BACKEND = avarice
+#DEBUG_BACKEND = simulavr
+
+# GDB Init Filename.
+GDBINIT_FILE = __avr_gdbinit
+
+# When using avarice settings for the JTAG
+JTAG_DEV = /dev/com1
+
+# Debugging port used to communicate between GDB / avarice / simulavr.
+DEBUG_PORT = 4242
+
+# Debugging host used to communicate between GDB / avarice / simulavr, normally
+#     just set to localhost unless doing some sort of crazy debugging when
+#     avarice is running on a different computer.
+DEBUG_HOST = localhost
+
+
+
+#============================================================================
+
+
+# De-dupe the list of C source files
+CSRC := $(sort $(SRC))
+
+# Define all object files.
+OBJ := $(patsubst %,$(OBJDIR)/%,$(CSRC:.c=.o) $(ASRC:.S=.o))
+
+# Define all listing files.
+LST := $(patsubst %,$(OBJDIR)/%,$(CSRC:.c=.lst) $(ASRC:.S=.lst))
+
+
+# Compiler flags to generate dependency files.
+GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
+
+
+# Combine all necessary flags and optional flags.
+# Add target processor to flags.
+ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
+ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) $(CDEFS)
+
+
+
+
+
+# Default target.
+all: build
+
+build: elf bin hex
+	$(E) "  SIZE   $(TARGET).elf"
+	$(Q)$(ELFSIZE)|grep -v debug
+
+elf: $(TARGET).elf
+bin: $(TARGET).bin
+hex: $(TARGET).hex
+eep: $(TARGET).eep
+lss: $(TARGET).lss
+sym: $(TARGET).sym
+
+# A little helper target for the maintainer =)
+copy2card:
+	mount /mnt
+	cp $(TARGET).bin /mnt
+	umount /mnt
+	sync
+
+
+# Doxygen output:
+doxygen:
+	-rm -rf doxyinput
+	mkdir doxyinput
+	cp *.h *.c doxyinput
+	src2doxy.pl doxyinput/*.h doxyinput/*.c
+	doxygen doxygen.conf
+
+# Display size of file.
+HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
+ELFSIZE = $(SIZE) -A $(TARGET).elf
+AVRMEM = avr-mem.sh $(TARGET).elf $(MCU)
+
+# Program the device.
+program: bin hex eep
+	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)  $(AVRDUDE_WRITE_EEPROM)
+
+# Set fuses of the device
+fuses: $(CONFIG)
+	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES)
+
+# Generate avr-gdb config/init file which does the following:
+#     define the reset signal, load the target file, connect to target, and set
+#     a breakpoint at main().
+gdb-config:
+	@$(REMOVE) $(GDBINIT_FILE)
+	@echo define reset >> $(GDBINIT_FILE)
+	@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
+	@echo end >> $(GDBINIT_FILE)
+	@echo file $(TARGET).elf >> $(GDBINIT_FILE)
+	@echo target remote $(DEBUG_HOST):$(DEBUG_PORT)  >> $(GDBINIT_FILE)
+ifeq ($(DEBUG_BACKEND),simulavr)
+	@echo load  >> $(GDBINIT_FILE)
+endif
+	@echo break main >> $(GDBINIT_FILE)
+
+debug: gdb-config $(TARGET).elf
+ifeq ($(DEBUG_BACKEND), avarice)
+	@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
+	@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
+	$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
+	@$(WINSHELL) /c pause
+
+else
+	@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
+	$(DEBUG_MFREQ) --port $(DEBUG_PORT)
+endif
+	@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
+
+
+
+
+# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
+COFFCONVERT=$(OBJCOPY) --debugging \
+--change-section-address .data-0x800000 \
+--change-section-address .bss-0x800000 \
+--change-section-address .noinit-0x800000 \
+--change-section-address .eeprom-0x810000
+
+
+coff: $(TARGET).elf
+	$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
+
+
+extcoff: $(TARGET).elf
+	$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
+
+
+# Generate autoconf.h from config
+.PRECIOUS : $(OBJDIR)/autoconf.h
+$(OBJDIR)/autoconf.h: $(CONFIG) | $(OBJDIR)
+	$(E) "  CONF2H $(CONFIG)"
+	$(Q)gawk -f conf2h.awk $(CONFIG) > $(OBJDIR)/autoconf.h
+
+# Create final output files (.hex, .eep) from ELF output file.
+ifeq ($(CONFIG_BOOTLOADER),y)
+$(OBJDIR)/%.bin: $(OBJDIR)/%.elf
+	$(E) "  BIN    $@"
+	$(Q)$(OBJCOPY) -O binary -R .eeprom $< $@
+	$(E) "  CRCGEN $@"
+	-$(Q)crcgen-new $@ $(BINARY_LENGTH) $(CONFIG_BOOT_DEVID) $(BOOT_VERSION)
+	$(E) "  COPY   $(CONFIG_HARDWARE_NAME)-firmware-$(PROGRAMVERSION).bin"
+	$(Q)$(COPY) $@ $(OBJDIR)/$(CONFIG_HARDWARE_NAME)-firmware-$(PROGRAMVERSION).bin
+else
+$(OBJDIR)/%.bin: $(OBJDIR)/%.elf
+	$(E) "  BIN    $@"
+	$(Q)$(OBJCOPY) -O binary -R .eeprom $< $@
+endif
+
+
+$(OBJDIR)/%.hex: $(OBJDIR)/%.elf
+	$(E) "  HEX    $@"
+	$(Q)$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
+
+$(OBJDIR)/%.eep: $(OBJDIR)/%.elf
+	-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
+	--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
+
+# Create extended listing file from ELF output file.
+$(OBJDIR)/%.lss: $(OBJDIR)/%.elf
+	$(E) "  LSS    $<"
+	$(Q)$(OBJDUMP) -h -S $< > $@
+
+# Create a symbol table from ELF output file.
+$(OBJDIR)/%.sym: $(OBJDIR)/%.elf
+	$(E) "  SYM    $<"
+	$(E)$(NM) -n $< > $@
+
+
+
+# Link: create ELF output file from object files.
+.SECONDARY : $(TARGET).elf
+.PRECIOUS : $(OBJ)
+$(OBJDIR)/%.elf: $(OBJ)
+	$(E) "  LINK   $@"
+	$(Q)$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
+
+
+# Compile: create object files from C source files.
+$(OBJDIR)/%.o : %.c | $(OBJDIR) $(OBJDIR)/autoconf.h
+	$(E) "  CC     $<"
+	$(Q)$(CC) -c $(ALL_CFLAGS) $< -o $@
+
+
+# Compile: create assembler files from C source files.
+$(OBJDIR)/%.s : %.c | $(OBJDIR) $(OBJDIR)/autoconf.h
+	$(CC) -S $(ALL_CFLAGS) $< -o $@
+
+
+# Assemble: create object files from assembler source files.
+$(OBJDIR)/%.o : %.S | $(OBJDIR) $(OBJDIR)/autoconf.h
+	$(E) "  AS     $<"
+	$(Q)$(CC) -c $(ALL_ASFLAGS) $< -o $@
+
+# Create preprocessed source for use in sending a bug report.
+$(OBJDIR)/%.i : %.c | $(OBJDIR) $(OBJDIR)/autoconf.h
+	$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
+
+# Create the output directory
+$(OBJDIR):
+	$(E) "  MKDIR  $(OBJDIR)"
+	$(Q)mkdir $(OBJDIR)
+
+# Target: clean project.
+clean: begin clean_list end
+
+clean_list :
+	$(E) "  CLEAN"
+	$(Q)$(REMOVE) $(TARGET).hex
+	$(Q)$(REMOVE) $(TARGET).bin
+	$(Q)$(REMOVE) $(TARGET).eep
+	$(Q)$(REMOVE) $(TARGET).cof
+	$(Q)$(REMOVE) $(TARGET).elf
+	$(Q)$(REMOVE) $(TARGET).map
+	$(Q)$(REMOVE) $(TARGET).sym
+	$(Q)$(REMOVE) $(TARGET).lss
+	$(Q)$(REMOVE) $(OBJ)
+	$(Q)$(REMOVE) $(OBJDIR)/autoconf.h
+	$(Q)$(REMOVE) $(OBJDIR)/*.bin
+	$(Q)$(REMOVE) $(LST)
+	$(Q)$(REMOVE) $(CSRC:.c=.s)
+	$(Q)$(REMOVE) $(CSRC:.c=.d)
+	$(Q)$(REMOVE) .dep/*
+	$(Q)$(REMOVE) -rf codedoc
+	$(Q)$(REMOVE) -rf doxyinput
+	-$(Q)rmdir $(OBJDIR)
+
+# Include the dependency files.
+-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
+
+# Manual dependency for the assembler module
+# $(OBJDIR)/fastloader-ll.o: config.h $(OBJDIR)/autoconf.h
+
+# Listing of phony targets.
+.PHONY : all begin finish end sizebefore sizeafter gccversion \
+build elf hex eep lss sym coff extcoff \
+clean clean_list program debug gdb-config doxygen
+

+ 0 - 0
src/avrcompat.h → mk1-src/avrcompat.h


+ 29 - 0
mk1-src/conf2h.awk

@@ -0,0 +1,29 @@
+#! /usr/bin/gawk -f
+
+# Trivial little script to convert from a makefile-style configuration
+# file to a C header. No copyright claimed.
+
+BEGIN {
+  print "// autoconf.h generated from " ARGV[1] " at " strftime() "\n" \
+    "#ifndef AUTOCONF_H\n" \
+    "#define AUTOCONF_H"
+}
+
+/^#/ { sub(/^#/,"//") }
+
+/^CONFIG_.*=/ {
+  if (/=n$/) {
+    sub(/^/,"// ");
+  } else {
+    sub(/^/,"#define ")
+    if (/=y$/) {
+      sub(/=.*$/,"")
+    } else {
+      sub(/=/," ")
+    }
+  }
+}
+
+{ print }
+
+END { print "#endif" }

+ 47 - 0
mk1-src/config

@@ -0,0 +1,47 @@
+# This may not look like it, but it's a -*- makefile -*-
+# sd2snes - SD card based universal cartridge for the SNES
+# Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
+#
+# This file was adapted from sd2iec, written by Ingo Korb.
+# Original disclaimer follows:
+#
+# sd2iec - SD/MMC to Commodore serial bus interface/controller
+# Copyright (C) 2007-2009  Ingo Korb <ingo@akana.de>
+#
+# Inspiration and low-level SD/MMC access based on code from MMC2IEC
+#   by Lars Pontoppidan et al., see sdcard.c|h and config.h.
+#
+#  FAT filesystem access based on code from ChaN, see tff.c|h.
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; version 2 of the License only.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+#
+# This file is included in the main sd2iec Makefile and also parsed
+# into autoconf.h.
+
+CONFIG_MCU=atmega644
+CONFIG_LINKER_RELAX=n
+CONFIG_MCU_FREQ=12288000
+CONFIG_BOOTLOADER=y
+CONFIG_BOOT_DEVID=0x4e534453
+CONFIG_UART_DEBUG=y
+CONFIG_UART_BAUDRATE=384000
+CONFIG_UART_BUF_SHIFT=7
+CONFIG_HARDWARE_NAME=sd2snes
+CONFIG_SD_AUTO_RETRIES=10
+#CONFIG_SD_DATACRC=y
+CONFIG_EEPROM_SIZE=512
+CONFIG_EEPROM_OFFSET=512
+CONFIG_MAX_PARTITIONS=1
+#CONFIG_DEADLOCK_ME_HARDER=y

+ 0 - 0
src/config.h → mk1-src/config.h


+ 0 - 0
src/crc16.c → mk1-src/crc16.c


+ 0 - 0
src/crc16.h → mk1-src/crc16.h


+ 0 - 0
src/crc32.c → mk1-src/crc32.c


+ 0 - 0
src/crc32.h → mk1-src/crc32.h


+ 0 - 0
src/crc7.c → mk1-src/crc7.c


+ 0 - 0
src/crc7.h → mk1-src/crc7.h


+ 0 - 0
src/crcgen-new.c → mk1-src/crcgen-new.c


+ 0 - 0
src/diskio.c → mk1-src/diskio.c


+ 0 - 0
src/diskio.h → mk1-src/diskio.h


+ 0 - 0
src/eeprom.c → mk1-src/eeprom.c


+ 0 - 0
src/eeprom.h → mk1-src/eeprom.h


+ 0 - 0
src/ff.c → mk1-src/ff.c


+ 0 - 0
src/ff.h → mk1-src/ff.h


+ 0 - 0
src/fileops.c → mk1-src/fileops.c


+ 0 - 0
src/fileops.h → mk1-src/fileops.h


+ 0 - 0
src/filetypes.c → mk1-src/filetypes.c


+ 0 - 0
src/filetypes.h → mk1-src/filetypes.h


+ 0 - 0
src/fpga.c → mk1-src/fpga.c


+ 0 - 0
src/fpga.h → mk1-src/fpga.h


+ 0 - 0
src/fpga_spi.c → mk1-src/fpga_spi.c


+ 0 - 0
src/fpga_spi.h → mk1-src/fpga_spi.h


+ 0 - 0
src/gcctest.awk → mk1-src/gcctest.awk


+ 0 - 0
src/integer.h → mk1-src/integer.h


+ 0 - 0
src/led.c → mk1-src/led.c


+ 0 - 0
src/led.h → mk1-src/led.h


+ 400 - 0
mk1-src/main.c

@@ -0,0 +1,400 @@
+/* sd2snes - SD card based universal cartridge for the SNES
+   Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
+   AVR firmware portion
+
+   Inspired by and based on code from sd2iec, written by Ingo Korb et al.
+   See sdcard.c|h, config.h.
+
+   FAT file system access based on code by ChaN, Jim Brain, Ingo Korb,
+   see ff.c|h.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License only.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+   main.c: initialization and flow
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <avr/boot.h>
+#include <avr/interrupt.h>
+#include <avr/pgmspace.h>
+#include <avr/power.h>
+#include <avr/wdt.h>
+#include <util/delay.h>
+#include "config.h"
+#include "diskio.h"
+#include "ff.h"
+#include "led.h"
+/* #include "timer.h" */
+#include "fpga.h"
+#include "uart.h"
+#include "ustring.h"
+#include "utils.h"
+#include "snes.h"
+#include "fileops.h"
+#include "memory.h"
+#include "fpga_spi.h"
+#include "spi.h"
+#include "avrcompat.h"
+#include "filetypes.h"
+#include "sdcard.h"
+
+void writetest(void) {
+// HERE BE LIONS, GET IN THE CAR
+	char teststring[58];
+	while(1) {
+		sram_writeblock((void*)"Testtext of DOOM!!1! 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", SRAM_SCRATCHPAD+0x20, 58);
+		sram_readblock((void*)teststring, SRAM_SCRATCHPAD+0x20, 58);
+		teststring[57]=0;
+		dprintf("%s\n", teststring);
+	}
+// END OF LIONS
+}
+
+
+void memtest(void) {
+/* HERE BE DRAGONS */
+	uint32_t dbg_i;
+	for(dbg_i=0; dbg_i < 65536; dbg_i++) {
+		sram_writeshort((uint16_t)dbg_i&0xffff, dbg_i*2);
+	}
+	save_sram((uint8_t*)"/sd2snes/memtest", 0x20000, 0);
+	set_pwr_led(0);
+	while(1);
+/* END OF DRAGONS */
+}
+
+
+/* Make sure the watchdog is disabled as soon as possible    */
+/* Copy this code to your bootloader if you use one and your */
+/* MCU doesn't disable the WDT after reset!                  */
+void get_mcusr(void) \
+      __attribute__((naked)) \
+      __attribute__((section(".init3")));
+void get_mcusr(void)
+{
+  MCUSR = 0;
+  wdt_disable();
+}
+
+#ifdef CONFIG_MEMPOISON
+void poison_memory(void) \
+  __attribute__((naked)) \
+  __attribute__((section(".init1")));
+void poison_memory(void) {
+  register uint16_t i;
+  register uint8_t  *ptr;
+
+  asm("clr r1\n");
+  /* There is no RAMSTARt variable =( */
+  if (RAMEND > 2048 && RAMEND < 4096) {
+    /* 2K memory */
+    ptr = (void *)RAMEND-2047;
+    for (i=0;i<2048;i++)
+      ptr[i] = 0x55;
+  } else if (RAMEND > 4096 && RAMEND < 8192) {
+    /* 4K memory */
+    ptr = (void *)RAMEND-4095;
+    for (i=0;i<4096;i++)
+      ptr[i] = 0x55;
+  } else {
+    /* Assume 8K memory */
+    ptr = (void *)RAMEND-8191;
+    for (i=0;i<8192;i++)
+      ptr[i] = 0x55;
+  }
+}
+#endif
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1)
+int main(void) __attribute__((OS_main));
+#endif
+int main(void) {
+#if defined __AVR_ATmega644__ || defined __AVR_ATmega644P__ || defined __AVR_ATmega2561__
+  asm volatile("in  r24, %0\n"
+               "ori r24, 0x80\n"
+               "out %0, r24\n"
+               "out %0, r24\n"
+               :
+               : "I" (_SFR_IO_ADDR(MCUCR))
+               : "r24"
+               );
+#elif defined __AVR_ATmega32__
+  asm volatile ("in  r24, %0\n"
+                "ori r24, 0x80\n"
+                "out %0, r24\n"
+                "out %0, r24\n"
+                :
+                : "I" (_SFR_IO_ADDR(MCUCSR))
+                : "r24"
+                );
+#elif defined __AVR_ATmega128__ || defined __AVR_ATmega1281__
+  /* Just assume that JTAG doesn't hurt us on the m128 */
+#else
+#  error Unknown chip!
+#endif
+
+#ifdef CLOCK_PRESCALE
+	clock_prescale_set(CLOCK_PRESCALE);
+#endif
+	set_pwr_led(0);
+	set_busy_led(1);
+	spi_none();
+	snes_reset(1);
+	uart_init();
+	sei();
+	_delay_ms(100);
+	disk_init();
+	snes_init();
+/*	timer_init(); */
+	uart_puts_P(PSTR("\nsd2snes " VERSION));
+	uart_putcrlf();
+
+	file_init();
+	FATFS fatfs;
+	f_mount(0,&fatfs);
+	uart_putc('W');
+	fpga_init();
+	fpga_pgm((uint8_t*)"/sd2snes/main.bit");
+	_delay_ms(100);
+	set_pwr_led(1);
+	fpga_spi_init();
+	uart_putc('!');
+	_delay_ms(100);
+
+restart:
+	set_avr_ena(0);
+	snes_reset(1);
+
+	*fs_path=0;
+	uint16_t saved_dir_id;
+	get_db_id(&saved_dir_id);
+
+	uint16_t mem_dir_id = sram_readshort(SRAM_DIRID);
+	uint32_t mem_magic = sram_readlong(SRAM_SCRATCHPAD);
+
+	while(0) {
+		SD_SPI_OFFLOAD=0;
+		set_avr_addr(0L);
+		sd_read(0, file_buf, 0L, 1);
+		uart_trace((void*)file_buf, 0, 0x200);
+//		sram_writeblock((void*)file_buf, 0, 0x200);
+//		sram_hexdump(0,0x200);
+		uart_putc('+');
+	}
+/* here be strange monsters */
+	while(0){
+//	uint16_t hurdur1 = 0, hurdur2 = 0;
+	spiTransferByte(0x00);
+	spiTransferByte(0x00);
+	spiTransferByte(0x00);
+	spiTransferByte(0x00);
+	spiTransferByte(0x00);
+	spiTransferByte(0x00);
+	spiTransferByte(0x00);
+	spiTransferByte(0x00);
+	spiTransferByte(0x00);
+	spiTransferByte(0x00);
+	spiTransferByte(0x00);
+	spiTransferByte(0x00);
+	spiTransferByte(0x00);
+        PORTB |= _BV(PB2);
+        DDRB |= _BV(PB2);
+        PORTB &= ~_BV(PB2);
+        DDRB &= ~_BV(PB7); // tristate SCK
+        PORTB |= _BV(PB2);
+        DDRB &= ~_BV(PB2);
+        while(!(PINB & _BV(PB2))) {
+        }
+        DDRB |= _BV(PB7);
+        _delay_ms(1);
+//	dprintf("hurdur1=%d hurdur2=%d\n", hurdur1, hurdur2);
+}
+	if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id)) {
+		uint16_t curr_dir_id = scan_dir(fs_path, 0, 0); // generate files footprint
+		dprintf("curr dir id = %x\n", curr_dir_id);
+		if((get_db_id(&saved_dir_id) != FR_OK)	// no database?
+		|| saved_dir_id != curr_dir_id) {	// files changed? // XXX
+			dprintf("saved dir id = %x\n", saved_dir_id);
+			dprintf("rebuilding database...");
+			_delay_ms(50);
+			curr_dir_id = scan_dir(fs_path, 1, 0);	// then rebuild database
+			sram_writeblock(&curr_dir_id, SRAM_DB_ADDR, 2);
+			uint32_t endaddr, direndaddr;
+			sram_readblock(&endaddr, SRAM_DB_ADDR+4, 4);
+			sram_readblock(&direndaddr, SRAM_DB_ADDR+8, 4);
+			dprintf("%lx %lx\n", endaddr, direndaddr);
+			save_sram((uint8_t*)"/sd2snes/sd2snes.db", endaddr-SRAM_DB_ADDR, SRAM_DB_ADDR);
+			save_sram((uint8_t*)"/sd2snes/sd2snes.dir", direndaddr-(SRAM_DIR_ADDR), SRAM_DIR_ADDR);
+			dprintf("done\n"); 
+//			sram_hexdump(SRAM_DB_ADDR, 0x400);
+		} else {
+			dprintf("saved dir id = %x\n", saved_dir_id);
+			dprintf("different card, consistent db, loading db...\n");
+			load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
+			load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
+		}
+//	save_sram((uint8_t*)"/debug.smc", 0x400000, 0);	
+//	uart_putc('[');
+//	load_sram((uint8_t*)"/test.srm", SRAM_SAVE_ADDR);
+//	uart_putc(']');
+
+		sram_writeshort(curr_dir_id, SRAM_DIRID);
+		sram_writelong(0x12345678, SRAM_SCRATCHPAD);
+	} else {
+		dprintf("same card, loading db...\n");
+		load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
+		load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
+	}
+
+	led_pwm();
+
+//	sram_hexdump(0, 0x200);
+	uart_putc('(');
+	load_rom((uint8_t*)"/sd2snes/menu.bin", SRAM_MENU_ADDR);
+	set_rom_mask(0x3fffff); // force mirroring off
+ 	set_avr_mapper(0x7); // menu mapper XXX
+	uart_putc(')');
+	uart_putcrlf();
+//	sram_hexdump(0x7ffff0, 0x10);
+//	sram_hexdump(0, 0x400);
+//	save_sram((uint8_t*)"/sd2snes/dump", 65536, 0);
+
+	sram_writebyte(0, SRAM_CMD_ADDR);
+
+	set_busy_led(0);
+	set_avr_ena(1);
+
+	_delay_ms(100);
+	uart_puts_P(PSTR("SNES GO!\r\n"));
+	snes_reset(0);
+// writetest();
+/*	snes_reset(1);
+	set_avr_ena(0);
+	led_std();
+	set_busy_led(1);
+	save_sram((uint8_t*)"/sd2snes/dump", 65536, SRAM_MENU_ADDR);
+	set_busy_led(0);
+	set_avr_ena(1);
+	snes_reset(0); */
+	uint8_t cmd = 0;
+
+	while(!sram_reliable());
+	while(!cmd) {
+		cmd=menu_main_loop();
+		switch(cmd) {
+			case 0x01: // SNES_CMD_LOADROM:
+				get_selected_name(file_lfn);
+				_delay_ms(100);
+//				snes_reset(1);
+				set_avr_ena(0);
+				dprintf("Selected name: %s\n", file_lfn);
+				load_rom(file_lfn, SRAM_ROM_ADDR);
+//				save_sram((uint8_t*)"/sd2snes/test.smc", romprops.romsize_bytes, 0);
+				if(romprops.ramsize_bytes) {
+					strcpy(strrchr((char*)file_lfn, (int)'.'), ".srm");
+					dprintf("SRM file: %s\n", file_lfn);
+					load_sram(file_lfn, SRAM_SAVE_ADDR);
+				} else {
+					dprintf("No SRAM\n");
+				}
+				set_avr_ena(1);
+				snes_reset(1);
+				_delay_ms(100);
+				snes_reset(0);
+				break;
+			default:
+				dprintf("unknown cmd: %d\n", cmd);
+				cmd=0; // unknown cmd: stay in loop
+			break;
+		}
+		
+	}
+	dprintf("cmd was %x, going to snes main loop\n", cmd);
+	led_std();
+	cmd=0;
+	uint8_t snes_reset_prev=0, snes_reset_now=0, snes_reset_state=0;
+	uint16_t reset_count=0;
+	while(fpga_test() == FPGA_TEST_TOKEN) {
+		snes_reset_now=get_snes_reset();
+		if(snes_reset_now) {
+			if(!snes_reset_prev) {
+				dprintf("RESET BUTTON DOWN\n");
+				snes_reset_state=1;
+				// reset reset counter
+				reset_count=0;
+			}
+		} else {
+			if(snes_reset_prev) {
+				dprintf("RESET BUTTON UP\n");
+				snes_reset_state=0;
+			}
+		}
+		if(snes_reset_state) {
+			_delay_ms(10);
+			reset_count++;
+		} else {
+			sram_reliable();
+			snes_main_loop();
+		}
+		if(reset_count>100) {
+			reset_count=0;
+			led_std();
+			set_avr_ena(0);
+			snes_reset(1);
+			_delay_ms(100);
+			if(romprops.ramsize_bytes && fpga_test() == 0xa5) {
+				set_busy_led(1);
+				save_sram(file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR);
+				set_busy_led(0);
+			}
+			_delay_ms(1000);
+			set_busy_led(1);
+			goto restart;
+		}
+		snes_reset_prev = snes_reset_now;
+	}
+	// FPGA TEST FAIL. PANIC.
+	led_panic();
+
+/* HERE BE LIONS */
+while(1)  {	
+	set_avr_addr(0x600000);
+	spi_fpga();
+	spiTransferByte(0x81); // read w/ increment... hopefully
+	spiTransferByte(0x00); // 1 dummy read
+	uart_putcrlf();
+	uint8_t buff[21];
+	for(uint8_t cnt=0; cnt<21; cnt++) {
+		uint8_t data=spiTransferByte(0x00);
+		buff[cnt]=data;
+	}
+	for(uint8_t cnt=0; cnt<21; cnt++) {
+		uint8_t data = buff[cnt];
+		_delay_ms(2);
+		if(data>=0x20 && data <= 0x7a) {
+			uart_putc(data);
+		} else {
+//			uart_putc('.');
+			uart_putc("0123456789ABCDEF"[data>>4]);
+			uart_putc("0123456789ABCDEF"[data&15]);
+			uart_putc(' ');
+		}
+//		set_avr_bank(3);
+	}
+	spi_none();
+}
+		while(1);
+}
+

+ 0 - 0
src/memory.c → mk1-src/memory.c


+ 0 - 0
src/memory.h → mk1-src/memory.h


+ 0 - 0
src/sdcard.c → mk1-src/sdcard.c


+ 0 - 0
src/sdcard.h → mk1-src/sdcard.h


+ 0 - 0
src/smc.c → mk1-src/smc.c


+ 0 - 0
src/smc.h → mk1-src/smc.h


+ 0 - 0
src/snes.c → mk1-src/snes.c


+ 0 - 0
src/snes.h → mk1-src/snes.h


+ 0 - 0
src/spi.c → mk1-src/spi.c


+ 0 - 0
src/spi.h → mk1-src/spi.h


+ 0 - 0
src/src2doxy.pl → mk1-src/src2doxy.pl


+ 0 - 0
src/time.h → mk1-src/time.h


+ 0 - 0
src/timer.c → mk1-src/timer.c


+ 0 - 0
src/timer.h → mk1-src/timer.h


+ 0 - 0
src/uart.c → mk1-src/uart.c


+ 0 - 0
src/uart.h → mk1-src/uart.h


+ 0 - 0
src/ustring.h → mk1-src/ustring.h


+ 0 - 0
src/utils.c → mk1-src/utils.c


+ 0 - 0
src/utils.h → mk1-src/utils.h


+ 48 - 356
src/Makefile

@@ -1,14 +1,5 @@
 # Hey Emacs, this is a -*- makefile -*-
 
-# Define version number
-MAJOR = 0
-MINOR = 0
-PATCHLEVEL = 1
-FIX =
-
-# Forces bootloader version to 0, comment out for release
-#PRERELEASE =
-
 #----------------------------------------------------------------------------
 # WinAVR Makefile Template written by Eric B. Weddington, Joerg Wunsch, et al.
 #
@@ -25,7 +16,7 @@ FIX =
 # Carlos Lamas
 #
 #
-# Extensively modified for sd2iec by Ingo Korb
+# Extensively modified for sd2iec and later adapted for ARM by Ingo Korb
 #
 # To rebuild project do "make clean" then "make all".
 #----------------------------------------------------------------------------
@@ -50,62 +41,22 @@ endif
 # Include the configuration file
 include $(CONFIG)
 
-# Set MCU name and length of binary for bootloader
-# WARNING: Fuse settings not tested!
-MCU := $(CONFIG_MCU)
-ifeq ($(MCU),atmega128)
-  BINARY_LENGTH = 0x1f000
-#  EFUSE = 0xff
-#  HFUSE = 0x91
-#  LFUSE = 0xaf
-else ifeq ($(MCU),atmega1281)
-  BINARY_LENGTH = 0x1f000
-  BOOTLDRSIZE = 0x0800
-  EFUSE = 0xff
-  HFUSE = 0xd2
-  LFUSE = 0xfc
-else ifeq ($(MCU),atmega2561)
-  BINARY_LENGTH = 0x3f000
-  EFUSE = 0xfd
-  HFUSE = 0x93
-  LFUSE = 0xef
-else ifeq ($(MCU),atmega644)
-  BINARY_LENGTH = 0xf000
-  EFUSE = 0xfd
-  HFUSE = 0x91
-#  LFUSE = 0xef
-  LFUSE = 0xaf
-else ifeq ($(MCU),atmega644p)
-  BINARY_LENGTH = 0xf000
-  EFUSE = 0xfd
-  HFUSE = 0x91
-  LFUSE = 0xef
-else
-.PHONY: nochip
-nochip:
-	@echo '=============================================================='
-	@echo 'No known target chip specified.'
-	@echo
-	@echo 'Please edit the Makefile.'
-	@exit 1
-endif
-
 # Directory for all generated files
-OBJDIR := obj-$(CONFIG_MCU:atmega%=m%)$(CONFIGSUFFIX)
+OBJDIR := obj$(CONFIGSUFFIX)
 
 # Output format. (can be srec, ihex, binary)
-FORMAT = ihex
+FORMAT = binary
 
+# Linker script
+LINKERSCRIPT = lpc1754.ld
 
 # Target file name (without extension).
 TARGET = $(OBJDIR)/sd2snes
 
+
 # List C source files here. (C dependencies are automatically generated.)
-SRC = main.c ff.c utils.c led.c diskio.c sdcard.c spi.c crc7.c snes.c fpga.c memory.c crc16.c fileops.c fpga_spi.c smc.c filetypes.c
+SRC = main.c
 
-ifeq ($(CONFIG_UART_DEBUG),y)
-  SRC += uart.c
-endif
 
 # List Assembler source files here.
 #     Make them always end in a capital .S.  Files ending in a lowercase .s
@@ -114,19 +65,17 @@ endif
 #     Even though the DOS/Win* filesystem matches both .s and .S the same,
 #     it will preserve the spelling of the filenames, and gcc itself does
 #     care about how the name is spelled on its command-line.
-ASRC =
+ASRC = startup.S
+
 
 # Optimization level, can be [0, 1, 2, 3, s].
 #     0 = turn off optimization. s = optimize for size.
 #     (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
 # Use s -mcall-prologues when you really need size...
+#OPT = 2
 OPT = s
-#OPT = 3 -finline-functions
 
 # Debugging format.
-#     Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
-#     AVR Studio 4.10 requires dwarf-2.
-#     AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
 DEBUG = dwarf-2
 
 
@@ -146,52 +95,33 @@ CSTANDARD = -std=gnu99
 
 
 # Place -D or -U options here
-CDEFS = -DF_CPU=$(CONFIG_MCU_FREQ)UL
+CDEFS = #-DF_CPU=$(CONFIG_MCU_FREQ)UL
 
-# Calculate bootloader version
-ifdef PRERELEASE
-BOOT_VERSION := 0
-else
-BOOT_VERSION := 0x$(MAJOR)$(MINOR)$(PATCHLEVEL)$(FIX)
-endif
-
-# Create a version number define
-ifdef PATCHLEVEL
-ifdef FIX
-PROGRAMVERSION := $(MAJOR).$(MINOR).$(PATCHLEVEL).$(FIX)
-else
-PROGRAMVERSION := $(MAJOR).$(MINOR).$(PATCHLEVEL)
-BOOT_VERSION := $(BOOT_VERSION)0
-endif
-else
-PROGRAMVERSION := $(MAJOR).$(MINOR)
-BOOT_VERSION := $(BOOT_VERSION)00
-endif
-
-ifdef PRERELEASE
-PROGRAMVERSION := $(PROGRAMVERSION)$(PRERELEASE)
-endif
-
-LONGVERSION := -$(CONFIG_MCU:atmega%=m%)$(CONFIGSUFFIX)
-
-CDEFS += -DVERSION=\"$(PROGRAMVERSION)\" -DLONGVERSION=\"$(LONGVERSION)\"
 
 # Place -I options here
 CINCS =
 
 
+# CPU-specific flags
+ifndef CPUFLAGS
+  CPUFLAGS := -mthumb -mcpu=cortex-m3
+endif
+
+ifndef ARCH
+  ARCH := arm-none-eabi
+endif
+
 # Define programs and commands.
 # CC must be defined here to generate the correct CFLAGS
 SHELL = sh
-CC = avr-gcc
-OBJCOPY = avr-objcopy
-OBJDUMP = avr-objdump
-SIZE = avr-size
-NM = avr-nm
-AVRDUDE = avrdude
+CC = $(ARCH)-gcc
+OBJCOPY = $(ARCH)-objcopy
+OBJDUMP = $(ARCH)-objdump
+SIZE = $(ARCH)-size
+NM = $(ARCH)-nm
 REMOVE = rm -f
 COPY = cp
-WINSHELL = cmd
+AWK = awk
 
 
 #---------------- Compiler Options ----------------
@@ -204,34 +134,14 @@ WINSHELL = cmd
 CFLAGS = -g$(DEBUG)
 CFLAGS += $(CDEFS) $(CINCS)
 CFLAGS += -O$(OPT)
-CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
+CFLAGS += $(CPUFLAGS) -nostartfiles
+#CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
 CFLAGS += -Wall -Wstrict-prototypes -Werror
-CFLAGS += -Wa,-adhlns=$(OBJDIR)/$(<:.c=.lst)
+#CFLAGS += -Wa,-adhlns=$(OBJDIR)/$(<:.c=.lst)
 CFLAGS += -I$(OBJDIR)
 CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
 CFLAGS += $(CSTANDARD)
 CFLAGS += -ffunction-sections -fdata-sections
-#CFLAGS += -mcall-prologues
-
-# these are needed for GCC 4.3.2, which is more aggressive at inlining
-# gcc-4.2 knows one of those, but it tends to increase code size
-ifeq ($(shell $(CC) --version|gawk -f gcctest.awk),YES)
-CFLAGS += --param inline-call-cost=3
-CFLAGS += -fno-inline-small-functions
-CFLAGS += -fno-move-loop-invariants
-CFLAGS += -fno-split-wide-types
-
-# turn these on to keep the functions in the same order as in the source
-# this is only useful if you're looking at disassembly
-#CFLAGS += -fno-reorder-blocks
-#CFLAGS += -fno-reorder-blocks-and-partition
-#CFLAGS += -fno-reorder-functions
-#CFLAGS += -fno-toplevel-reorder
-endif
-
-ifeq ($(CONFIG_STACK_TRACKING),y)
-  CFLAGS += -finstrument-functions
-endif
 
 
 #---------------- Assembler Options ----------------
@@ -241,50 +151,7 @@ endif
 #             for use in COFF files, additional information about filenames
 #             and function names needs to be present in the assembler source
 #             files -- see avr-libc docs [FIXME: not yet described there]
-ASFLAGS = -Wa,-adhlns=$(OBJDIR)/$(<:.S=.lst),-gstabs -I$(OBJDIR)
-
-
-#---------------- Library Options ----------------
-# Minimalistic printf version
-PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
-
-# Floating point printf version (requires MATH_LIB = -lm below)
-PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
-
-# If this is left blank, then it will use the Standard printf version.
-PRINTF_LIB =
-#PRINTF_LIB = $(PRINTF_LIB_MIN)
-#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
-
-
-# Minimalistic scanf version
-SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
-
-# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
-SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
-
-# If this is left blank, then it will use the Standard scanf version.
-SCANF_LIB =
-#SCANF_LIB = $(SCANF_LIB_MIN)
-#SCANF_LIB = $(SCANF_LIB_FLOAT)
-
-
-MATH_LIB = -lm
-
-
-
-#---------------- External Memory Options ----------------
-
-# 64 KB of external RAM, starting after internal RAM (ATmega128!),
-# used for variables (.data/.bss) and heap (malloc()).
-#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
-
-# 64 KB of external RAM, starting after internal RAM (ATmega128!),
-# only used for heap (malloc()).
-#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff
-
-EXTMEMOPTS =
-
+ASFLAGS = $(CPUFLAGS) -Wa,-adhlns=$(OBJDIR)/$(<:.S=.lst),-gstabs -I$(OBJDIR)
 
 
 #---------------- Linker Options ----------------
@@ -292,105 +159,13 @@ EXTMEMOPTS =
 #    -Map:      create map file
 #    --cref:    add cross reference to  map file
 LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
-LDFLAGS += $(EXTMEMOPTS)
-LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
+LDFLAGS += -T$(LINKERSCRIPT)
 LDFLAGS += -Wl,--gc-sections
 ifeq ($(CONFIG_LINKER_RELAX),y)
   LDFLAGS += -Wl,-O9,--relax
 endif
 
 
-
-#---------------- Programming Options (avrdude) ----------------
-
-# Programming hardware: alf avr910 avrisp bascom bsd
-# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 stk500v2
-#
-# Type: avrdude -c ?
-# to get a full listing.
-#
-AVRDUDE_PROGRAMMER = dragon_isp
-
-# com1 = serial port. Use lpt1 to connect to parallel port.
-AVRDUDE_PORT = usb   # programmer connected to serial device
-
-AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
-# AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
-
-# Allow fuse overrides from the config file
-ifdef CONFIG_EFUSE
-  EFUSE := CONFIG_EFUSE
-endif
-ifdef CONFIG_HFUSE
-  HFUSE := CONFIG_HFUSE
-endif
-ifdef CONFIG_LFUSE
-  LFUSE := CONFIG_LFUSE
-endif
-
-# Calculate command line arguments for fuses
-AVRDUDE_WRITE_FUSES :=
-ifdef EFUSE
-  AVRDUDE_WRITE_FUSES += -U efuse:w:$(EFUSE):m
-endif
-ifdef HFUSE
-  AVRDUDE_WRITE_FUSES += -U hfuse:w:$(HFUSE):m
-endif
-ifdef LFUSE
-  AVRDUDE_WRITE_FUSES += -U lfuse:w:$(LFUSE):m
-endif
-
-
-# Uncomment the following if you want avrdude's erase cycle counter.
-# Note that this counter needs to be initialized first using -Yn,
-# see avrdude manual.
-AVRDUDE_ERASE_COUNTER = -y
-
-# Uncomment the following if you do /not/ wish a verification to be
-# performed after programming the device.
-#AVRDUDE_NO_VERIFY = -V
-
-# Increase verbosity level.  Please use this when submitting bug
-# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
-# to submit bug reports.
-#AVRDUDE_VERBOSE = -v -v
-
-AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
-AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
-AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
-AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
-
-
-
-#---------------- Debugging Options ----------------
-
-# For simulavr only - target MCU frequency.
-DEBUG_MFREQ = $(CONFIG_MCU_FREQ)
-
-# Set the DEBUG_UI to either gdb or insight.
-# DEBUG_UI = gdb
-DEBUG_UI = insight
-
-# Set the debugging back-end to either avarice, simulavr.
-DEBUG_BACKEND = avarice
-#DEBUG_BACKEND = simulavr
-
-# GDB Init Filename.
-GDBINIT_FILE = __avr_gdbinit
-
-# When using avarice settings for the JTAG
-JTAG_DEV = /dev/com1
-
-# Debugging port used to communicate between GDB / avarice / simulavr.
-DEBUG_PORT = 4242
-
-# Debugging host used to communicate between GDB / avarice / simulavr, normally
-#     just set to localhost unless doing some sort of crazy debugging when
-#     avarice is running on a different computer.
-DEBUG_HOST = localhost
-
-
-
 #============================================================================
 
 
@@ -410,8 +185,8 @@ GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
 
 # Combine all necessary flags and optional flags.
 # Add target processor to flags.
-ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
-ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) $(CDEFS)
+ALL_CFLAGS = -I. $(CFLAGS) $(GENDEPFLAGS)
+ALL_ASFLAGS = -I. -x assembler-with-cpp $(ASFLAGS) $(CDEFS)
 
 
 
@@ -431,111 +206,38 @@ eep: $(TARGET).eep
 lss: $(TARGET).lss
 sym: $(TARGET).sym
 
-# A little helper target for the maintainer =)
-copy2card:
-	mount /mnt
-	cp $(TARGET).bin /mnt
-	umount /mnt
-	sync
+# # A little helper target for the maintainer =)
+# copy2card:
+#	cp $(TARGET).bin /mbed/hw_LPC1768.bin
+
 
+program: bin
+	utils/lpcchksum $(TARGET).bin
+	openocd -f openocd-usb.cfg -f lpc1754.cfg -f flash.cfg
 
-# Doxygen output:
-doxygen:
-	-rm -rf doxyinput
-	mkdir doxyinput
-	cp *.h *.c doxyinput
-	src2doxy.pl doxyinput/*.h doxyinput/*.c
-	doxygen doxygen.conf
+debug: bin
+	openocd -f openocd-usb.cfg -f lpc1754.cfg
 
 # Display size of file.
 HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
 ELFSIZE = $(SIZE) -A $(TARGET).elf
-AVRMEM = avr-mem.sh $(TARGET).elf $(MCU)
-
-# Program the device.
-program: bin hex eep
-	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)  $(AVRDUDE_WRITE_EEPROM)
-
-# Set fuses of the device
-fuses: $(CONFIG)
-	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES)
-
-# Generate avr-gdb config/init file which does the following:
-#     define the reset signal, load the target file, connect to target, and set
-#     a breakpoint at main().
-gdb-config:
-	@$(REMOVE) $(GDBINIT_FILE)
-	@echo define reset >> $(GDBINIT_FILE)
-	@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
-	@echo end >> $(GDBINIT_FILE)
-	@echo file $(TARGET).elf >> $(GDBINIT_FILE)
-	@echo target remote $(DEBUG_HOST):$(DEBUG_PORT)  >> $(GDBINIT_FILE)
-ifeq ($(DEBUG_BACKEND),simulavr)
-	@echo load  >> $(GDBINIT_FILE)
-endif
-	@echo break main >> $(GDBINIT_FILE)
-
-debug: gdb-config $(TARGET).elf
-ifeq ($(DEBUG_BACKEND), avarice)
-	@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
-	@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
-	$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
-	@$(WINSHELL) /c pause
-
-else
-	@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
-	$(DEBUG_MFREQ) --port $(DEBUG_PORT)
-endif
-	@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
-
-
-
-
-# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
-COFFCONVERT=$(OBJCOPY) --debugging \
---change-section-address .data-0x800000 \
---change-section-address .bss-0x800000 \
---change-section-address .noinit-0x800000 \
---change-section-address .eeprom-0x810000
 
 
-coff: $(TARGET).elf
-	$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
-
-
-extcoff: $(TARGET).elf
-	$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
-
 
 # Generate autoconf.h from config
 .PRECIOUS : $(OBJDIR)/autoconf.h
 $(OBJDIR)/autoconf.h: $(CONFIG) | $(OBJDIR)
 	$(E) "  CONF2H $(CONFIG)"
-	$(Q)gawk -f conf2h.awk $(CONFIG) > $(OBJDIR)/autoconf.h
+	$(Q)$(AWK) -f conf2h.awk $(CONFIG) > $(OBJDIR)/autoconf.h
 
-# Create final output files (.hex, .eep) from ELF output file.
-ifeq ($(CONFIG_BOOTLOADER),y)
-$(OBJDIR)/%.bin: $(OBJDIR)/%.elf
-	$(E) "  BIN    $@"
-	$(Q)$(OBJCOPY) -O binary -R .eeprom $< $@
-	$(E) "  CRCGEN $@"
-	-$(Q)crcgen-new $@ $(BINARY_LENGTH) $(CONFIG_BOOT_DEVID) $(BOOT_VERSION)
-	$(E) "  COPY   $(CONFIG_HARDWARE_NAME)-firmware-$(PROGRAMVERSION).bin"
-	$(Q)$(COPY) $@ $(OBJDIR)/$(CONFIG_HARDWARE_NAME)-firmware-$(PROGRAMVERSION).bin
-else
+# Create final output files from ELF output file.
 $(OBJDIR)/%.bin: $(OBJDIR)/%.elf
 	$(E) "  BIN    $@"
-	$(Q)$(OBJCOPY) -O binary -R .eeprom $< $@
-endif
-
+	$(Q)$(OBJCOPY) -O binary $< $@
 
 $(OBJDIR)/%.hex: $(OBJDIR)/%.elf
 	$(E) "  HEX    $@"
-	$(Q)$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
-
-$(OBJDIR)/%.eep: $(OBJDIR)/%.elf
-	-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
-	--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
+	$(Q)$(OBJCOPY) -O $(FORMAT) $< $@
 
 # Create extended listing file from ELF output file.
 $(OBJDIR)/%.lss: $(OBJDIR)/%.elf
@@ -548,7 +250,6 @@ $(OBJDIR)/%.sym: $(OBJDIR)/%.elf
 	$(E)$(NM) -n $< > $@
 
 
-
 # Link: create ELF output file from object files.
 .SECONDARY : $(TARGET).elf
 .PRECIOUS : $(OBJ)
@@ -589,8 +290,6 @@ clean_list :
 	$(E) "  CLEAN"
 	$(Q)$(REMOVE) $(TARGET).hex
 	$(Q)$(REMOVE) $(TARGET).bin
-	$(Q)$(REMOVE) $(TARGET).eep
-	$(Q)$(REMOVE) $(TARGET).cof
 	$(Q)$(REMOVE) $(TARGET).elf
 	$(Q)$(REMOVE) $(TARGET).map
 	$(Q)$(REMOVE) $(TARGET).sym
@@ -602,18 +301,11 @@ clean_list :
 	$(Q)$(REMOVE) $(CSRC:.c=.s)
 	$(Q)$(REMOVE) $(CSRC:.c=.d)
 	$(Q)$(REMOVE) .dep/*
-	$(Q)$(REMOVE) -rf codedoc
-	$(Q)$(REMOVE) -rf doxyinput
 	-$(Q)rmdir $(OBJDIR)
 
 # Include the dependency files.
 -include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
 
-# Manual dependency for the assembler module
-# $(OBJDIR)/fastloader-ll.o: config.h $(OBJDIR)/autoconf.h
-
 # Listing of phony targets.
-.PHONY : all begin finish end sizebefore sizeafter gccversion \
-build elf hex eep lss sym coff extcoff \
-clean clean_list program debug gdb-config doxygen
-
+.PHONY : all begin finish end sizebefore sizeafter \
+build elf hex lss sym clean clean_list

+ 1 - 47
src/config

@@ -1,47 +1 @@
-# This may not look like it, but it's a -*- makefile -*-
-# sd2snes - SD card based universal cartridge for the SNES
-# Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
-#
-# This file was adapted from sd2iec, written by Ingo Korb.
-# Original disclaimer follows:
-#
-# sd2iec - SD/MMC to Commodore serial bus interface/controller
-# Copyright (C) 2007-2009  Ingo Korb <ingo@akana.de>
-#
-# Inspiration and low-level SD/MMC access based on code from MMC2IEC
-#   by Lars Pontoppidan et al., see sdcard.c|h and config.h.
-#
-#  FAT filesystem access based on code from ChaN, see tff.c|h.
-#
-#  This program is free software; you can redistribute it and/or modify
-#  it under the terms of the GNU General Public License as published by
-#  the Free Software Foundation; version 2 of the License only.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-#
-#
-# This file is included in the main sd2iec Makefile and also parsed
-# into autoconf.h.
-
-CONFIG_MCU=atmega644
-CONFIG_LINKER_RELAX=n
-CONFIG_MCU_FREQ=12288000
-CONFIG_BOOTLOADER=y
-CONFIG_BOOT_DEVID=0x4e534453
-CONFIG_UART_DEBUG=y
-CONFIG_UART_BAUDRATE=384000
-CONFIG_UART_BUF_SHIFT=7
-CONFIG_HARDWARE_NAME=sd2snes
-CONFIG_SD_AUTO_RETRIES=10
-#CONFIG_SD_DATACRC=y
-CONFIG_EEPROM_SIZE=512
-CONFIG_EEPROM_OFFSET=512
-CONFIG_MAX_PARTITIONS=1
-#CONFIG_DEADLOCK_ME_HARDER=y
+# empty config file

+ 80 - 396
src/main.c

@@ -1,400 +1,84 @@
-/* sd2snes - SD card based universal cartridge for the SNES
-   Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
-   AVR firmware portion
+/* The classic embedded version of "Hello World": A blinking LED */
+#include <arm/NXP/LPC17xx/LPC17xx.h>
+
+#define BV(x) (1<<(x))
+#define BITBAND(addr,bit) (*((volatile unsigned long *)(((unsigned long)&(addr)-0x20000000)*32 + bit*4 + 0x22000000)))
+#define PLL_MULT(x)	((x)&0x7fff)
+#define PLL_PREDIV(x)	(((x)<<16)&0xff0000)
+#define CLKSRC_MAINOSC	(1)
+#define PLLE0		(1<<0)
+#define PLLC0		(1<<1)
+#define PLOCK0		(1<<26)
+#define OSCEN		(1<<5)
+#define OSCSTAT		(1<<6)
+#define EMC0TOGGLE	(3<<4)
+#define MR0R		(1<<1)
+#define FLASH5C		(0x403A)
+#define PCTIM3		(1<<23)
+
+#define PCLK_CCLK(x)	(1<<(x))
+#define PCLK_CCLK4(x)	(0)
+#define PCLK_CCLK8(x)	(3<<(x))
+#define PCLK_CCLK2(x)	(2<<(x))
+#define PCLK_TIMER3	(14)
+
+int i;
 
-   Inspired by and based on code from sd2iec, written by Ingo Korb et al.
-   See sdcard.c|h, config.h.
-
-   FAT file system access based on code by ChaN, Jim Brain, Ingo Korb,
-   see ff.c|h.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; version 2 of the License only.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-   main.c: initialization and flow
+int main(void) {
+  LPC_GPIO2->FIODIR = BV(0) | BV(1) | BV(2);
+  LPC_GPIO1->FIODIR = 0;
+  uint32_t p1;
+
+/* setup PLL0 */
+  LPC_SC->FLASHCFG=FLASH5C;
+  LPC_SC->PLL0CON &= ~PLLC0;
+  LPC_SC->PLL0FEED=0xaa;
+  LPC_SC->PLL0FEED=0x55;
+  LPC_SC->PLL0CON &= ~PLLE0;
+  LPC_SC->PLL0FEED=0xaa;
+  LPC_SC->PLL0FEED=0x55;
+
+/* PLL is disabled and disconnected. setup PCLK NOW as it cannot be changed
+   reliably with PLL0 connected.
+   see:
+   http://ics.nxp.com/support/documents/microcontrollers/pdf/errata.lpc1754.pdf
 */
-
-#include <stdio.h>
-#include <string.h>
-#include <avr/boot.h>
-#include <avr/interrupt.h>
-#include <avr/pgmspace.h>
-#include <avr/power.h>
-#include <avr/wdt.h>
-#include <util/delay.h>
-#include "config.h"
-#include "diskio.h"
-#include "ff.h"
-#include "led.h"
-/* #include "timer.h" */
-#include "fpga.h"
-#include "uart.h"
-#include "ustring.h"
-#include "utils.h"
-#include "snes.h"
-#include "fileops.h"
-#include "memory.h"
-#include "fpga_spi.h"
-#include "spi.h"
-#include "avrcompat.h"
-#include "filetypes.h"
-#include "sdcard.h"
-
-void writetest(void) {
-// HERE BE LIONS, GET IN THE CAR
-	char teststring[58];
-	while(1) {
-		sram_writeblock((void*)"Testtext of DOOM!!1! 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", SRAM_SCRATCHPAD+0x20, 58);
-		sram_readblock((void*)teststring, SRAM_SCRATCHPAD+0x20, 58);
-		teststring[57]=0;
-		dprintf("%s\n", teststring);
-	}
-// END OF LIONS
-}
-
-
-void memtest(void) {
-/* HERE BE DRAGONS */
-	uint32_t dbg_i;
-	for(dbg_i=0; dbg_i < 65536; dbg_i++) {
-		sram_writeshort((uint16_t)dbg_i&0xffff, dbg_i*2);
-	}
-	save_sram((uint8_t*)"/sd2snes/memtest", 0x20000, 0);
-	set_pwr_led(0);
-	while(1);
-/* END OF DRAGONS */
-}
-
-
-/* Make sure the watchdog is disabled as soon as possible    */
-/* Copy this code to your bootloader if you use one and your */
-/* MCU doesn't disable the WDT after reset!                  */
-void get_mcusr(void) \
-      __attribute__((naked)) \
-      __attribute__((section(".init3")));
-void get_mcusr(void)
-{
-  MCUSR = 0;
-  wdt_disable();
-}
-
-#ifdef CONFIG_MEMPOISON
-void poison_memory(void) \
-  __attribute__((naked)) \
-  __attribute__((section(".init1")));
-void poison_memory(void) {
-  register uint16_t i;
-  register uint8_t  *ptr;
-
-  asm("clr r1\n");
-  /* There is no RAMSTARt variable =( */
-  if (RAMEND > 2048 && RAMEND < 4096) {
-    /* 2K memory */
-    ptr = (void *)RAMEND-2047;
-    for (i=0;i<2048;i++)
-      ptr[i] = 0x55;
-  } else if (RAMEND > 4096 && RAMEND < 8192) {
-    /* 4K memory */
-    ptr = (void *)RAMEND-4095;
-    for (i=0;i<4096;i++)
-      ptr[i] = 0x55;
-  } else {
-    /* Assume 8K memory */
-    ptr = (void *)RAMEND-8191;
-    for (i=0;i<8192;i++)
-      ptr[i] = 0x55;
+  LPC_SC->PCLKSEL1=PCLK_CCLK(PCLK_TIMER3);
+  
+/* continue with PLL0 setup */
+  LPC_SC->SCS=OSCEN;
+  while(!(LPC_SC->SCS&OSCSTAT));
+  LPC_SC->CLKSRCSEL=CLKSRC_MAINOSC;
+  LPC_SC->PLL0CFG=PLL_MULT(428)|PLL_PREDIV(18);
+  LPC_SC->PLL0FEED=0xaa;
+  LPC_SC->PLL0FEED=0x55;
+  LPC_SC->PLL0CON |= PLLE0;
+  LPC_SC->PLL0FEED=0xaa;
+  LPC_SC->PLL0FEED=0x55;
+  LPC_SC->CCLKCFG=5;
+  while(!(LPC_SC->PLL0STAT&PLOCK0));
+  LPC_SC->PLL0CON |= PLLC0;
+  LPC_SC->PLL0FEED=0xaa;
+  LPC_SC->PLL0FEED=0x55;
+
+/* setup timer (fpga clk) */
+  LPC_SC->PCONP |= PCTIM3;	/* enable power */
+  LPC_TIM3->CTCR=0;
+  LPC_TIM3->EMR=EMC0TOGGLE;
+  LPC_PINCON->PINSEL0=(0x3<<20);
+  LPC_TIM3->MCR=MR0R;
+  LPC_TIM3->MR0=1;
+  LPC_TIM3->TCR=1;
+  
+
+  while (1) {
+    p1 = LPC_GPIO1->FIOPIN;
+    BITBAND(LPC_GPIO2->FIOPIN, 0) = (p1 & BV(29))>>29;
+    BITBAND(LPC_GPIO2->FIOSET, 2) = 1;
+    for (i=0;i<100000;i++)
+      __NOP();
+    BITBAND(LPC_GPIO2->FIOCLR, 2) = 1;
+    for (i=0;i<100000;i++)
+      __NOP();
   }
 }
-#endif
-
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1)
-int main(void) __attribute__((OS_main));
-#endif
-int main(void) {
-#if defined __AVR_ATmega644__ || defined __AVR_ATmega644P__ || defined __AVR_ATmega2561__
-  asm volatile("in  r24, %0\n"
-               "ori r24, 0x80\n"
-               "out %0, r24\n"
-               "out %0, r24\n"
-               :
-               : "I" (_SFR_IO_ADDR(MCUCR))
-               : "r24"
-               );
-#elif defined __AVR_ATmega32__
-  asm volatile ("in  r24, %0\n"
-                "ori r24, 0x80\n"
-                "out %0, r24\n"
-                "out %0, r24\n"
-                :
-                : "I" (_SFR_IO_ADDR(MCUCSR))
-                : "r24"
-                );
-#elif defined __AVR_ATmega128__ || defined __AVR_ATmega1281__
-  /* Just assume that JTAG doesn't hurt us on the m128 */
-#else
-#  error Unknown chip!
-#endif
-
-#ifdef CLOCK_PRESCALE
-	clock_prescale_set(CLOCK_PRESCALE);
-#endif
-	set_pwr_led(0);
-	set_busy_led(1);
-	spi_none();
-	snes_reset(1);
-	uart_init();
-	sei();
-	_delay_ms(100);
-	disk_init();
-	snes_init();
-/*	timer_init(); */
-	uart_puts_P(PSTR("\nsd2snes " VERSION));
-	uart_putcrlf();
-
-	file_init();
-	FATFS fatfs;
-	f_mount(0,&fatfs);
-	uart_putc('W');
-	fpga_init();
-	fpga_pgm((uint8_t*)"/sd2snes/main.bit");
-	_delay_ms(100);
-	set_pwr_led(1);
-	fpga_spi_init();
-	uart_putc('!');
-	_delay_ms(100);
-
-restart:
-	set_avr_ena(0);
-	snes_reset(1);
-
-	*fs_path=0;
-	uint16_t saved_dir_id;
-	get_db_id(&saved_dir_id);
-
-	uint16_t mem_dir_id = sram_readshort(SRAM_DIRID);
-	uint32_t mem_magic = sram_readlong(SRAM_SCRATCHPAD);
-
-	while(0) {
-		SD_SPI_OFFLOAD=0;
-		set_avr_addr(0L);
-		sd_read(0, file_buf, 0L, 1);
-		uart_trace((void*)file_buf, 0, 0x200);
-//		sram_writeblock((void*)file_buf, 0, 0x200);
-//		sram_hexdump(0,0x200);
-		uart_putc('+');
-	}
-/* here be strange monsters */
-	while(0){
-//	uint16_t hurdur1 = 0, hurdur2 = 0;
-	spiTransferByte(0x00);
-	spiTransferByte(0x00);
-	spiTransferByte(0x00);
-	spiTransferByte(0x00);
-	spiTransferByte(0x00);
-	spiTransferByte(0x00);
-	spiTransferByte(0x00);
-	spiTransferByte(0x00);
-	spiTransferByte(0x00);
-	spiTransferByte(0x00);
-	spiTransferByte(0x00);
-	spiTransferByte(0x00);
-	spiTransferByte(0x00);
-        PORTB |= _BV(PB2);
-        DDRB |= _BV(PB2);
-        PORTB &= ~_BV(PB2);
-        DDRB &= ~_BV(PB7); // tristate SCK
-        PORTB |= _BV(PB2);
-        DDRB &= ~_BV(PB2);
-        while(!(PINB & _BV(PB2))) {
-        }
-        DDRB |= _BV(PB7);
-        _delay_ms(1);
-//	dprintf("hurdur1=%d hurdur2=%d\n", hurdur1, hurdur2);
-}
-	if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id)) {
-		uint16_t curr_dir_id = scan_dir(fs_path, 0, 0); // generate files footprint
-		dprintf("curr dir id = %x\n", curr_dir_id);
-		if((get_db_id(&saved_dir_id) != FR_OK)	// no database?
-		|| saved_dir_id != curr_dir_id) {	// files changed? // XXX
-			dprintf("saved dir id = %x\n", saved_dir_id);
-			dprintf("rebuilding database...");
-			_delay_ms(50);
-			curr_dir_id = scan_dir(fs_path, 1, 0);	// then rebuild database
-			sram_writeblock(&curr_dir_id, SRAM_DB_ADDR, 2);
-			uint32_t endaddr, direndaddr;
-			sram_readblock(&endaddr, SRAM_DB_ADDR+4, 4);
-			sram_readblock(&direndaddr, SRAM_DB_ADDR+8, 4);
-			dprintf("%lx %lx\n", endaddr, direndaddr);
-			save_sram((uint8_t*)"/sd2snes/sd2snes.db", endaddr-SRAM_DB_ADDR, SRAM_DB_ADDR);
-			save_sram((uint8_t*)"/sd2snes/sd2snes.dir", direndaddr-(SRAM_DIR_ADDR), SRAM_DIR_ADDR);
-			dprintf("done\n"); 
-//			sram_hexdump(SRAM_DB_ADDR, 0x400);
-		} else {
-			dprintf("saved dir id = %x\n", saved_dir_id);
-			dprintf("different card, consistent db, loading db...\n");
-			load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
-			load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
-		}
-//	save_sram((uint8_t*)"/debug.smc", 0x400000, 0);	
-//	uart_putc('[');
-//	load_sram((uint8_t*)"/test.srm", SRAM_SAVE_ADDR);
-//	uart_putc(']');
-
-		sram_writeshort(curr_dir_id, SRAM_DIRID);
-		sram_writelong(0x12345678, SRAM_SCRATCHPAD);
-	} else {
-		dprintf("same card, loading db...\n");
-		load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
-		load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
-	}
-
-	led_pwm();
-
-//	sram_hexdump(0, 0x200);
-	uart_putc('(');
-	load_rom((uint8_t*)"/sd2snes/menu.bin", SRAM_MENU_ADDR);
-	set_rom_mask(0x3fffff); // force mirroring off
- 	set_avr_mapper(0x7); // menu mapper XXX
-	uart_putc(')');
-	uart_putcrlf();
-//	sram_hexdump(0x7ffff0, 0x10);
-//	sram_hexdump(0, 0x400);
-//	save_sram((uint8_t*)"/sd2snes/dump", 65536, 0);
-
-	sram_writebyte(0, SRAM_CMD_ADDR);
-
-	set_busy_led(0);
-	set_avr_ena(1);
-
-	_delay_ms(100);
-	uart_puts_P(PSTR("SNES GO!\r\n"));
-	snes_reset(0);
-// writetest();
-/*	snes_reset(1);
-	set_avr_ena(0);
-	led_std();
-	set_busy_led(1);
-	save_sram((uint8_t*)"/sd2snes/dump", 65536, SRAM_MENU_ADDR);
-	set_busy_led(0);
-	set_avr_ena(1);
-	snes_reset(0); */
-	uint8_t cmd = 0;
-
-	while(!sram_reliable());
-	while(!cmd) {
-		cmd=menu_main_loop();
-		switch(cmd) {
-			case 0x01: // SNES_CMD_LOADROM:
-				get_selected_name(file_lfn);
-				_delay_ms(100);
-//				snes_reset(1);
-				set_avr_ena(0);
-				dprintf("Selected name: %s\n", file_lfn);
-				load_rom(file_lfn, SRAM_ROM_ADDR);
-//				save_sram((uint8_t*)"/sd2snes/test.smc", romprops.romsize_bytes, 0);
-				if(romprops.ramsize_bytes) {
-					strcpy(strrchr((char*)file_lfn, (int)'.'), ".srm");
-					dprintf("SRM file: %s\n", file_lfn);
-					load_sram(file_lfn, SRAM_SAVE_ADDR);
-				} else {
-					dprintf("No SRAM\n");
-				}
-				set_avr_ena(1);
-				snes_reset(1);
-				_delay_ms(100);
-				snes_reset(0);
-				break;
-			default:
-				dprintf("unknown cmd: %d\n", cmd);
-				cmd=0; // unknown cmd: stay in loop
-			break;
-		}
-		
-	}
-	dprintf("cmd was %x, going to snes main loop\n", cmd);
-	led_std();
-	cmd=0;
-	uint8_t snes_reset_prev=0, snes_reset_now=0, snes_reset_state=0;
-	uint16_t reset_count=0;
-	while(fpga_test() == FPGA_TEST_TOKEN) {
-		snes_reset_now=get_snes_reset();
-		if(snes_reset_now) {
-			if(!snes_reset_prev) {
-				dprintf("RESET BUTTON DOWN\n");
-				snes_reset_state=1;
-				// reset reset counter
-				reset_count=0;
-			}
-		} else {
-			if(snes_reset_prev) {
-				dprintf("RESET BUTTON UP\n");
-				snes_reset_state=0;
-			}
-		}
-		if(snes_reset_state) {
-			_delay_ms(10);
-			reset_count++;
-		} else {
-			sram_reliable();
-			snes_main_loop();
-		}
-		if(reset_count>100) {
-			reset_count=0;
-			led_std();
-			set_avr_ena(0);
-			snes_reset(1);
-			_delay_ms(100);
-			if(romprops.ramsize_bytes && fpga_test() == 0xa5) {
-				set_busy_led(1);
-				save_sram(file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR);
-				set_busy_led(0);
-			}
-			_delay_ms(1000);
-			set_busy_led(1);
-			goto restart;
-		}
-		snes_reset_prev = snes_reset_now;
-	}
-	// FPGA TEST FAIL. PANIC.
-	led_panic();
-
-/* HERE BE LIONS */
-while(1)  {	
-	set_avr_addr(0x600000);
-	spi_fpga();
-	spiTransferByte(0x81); // read w/ increment... hopefully
-	spiTransferByte(0x00); // 1 dummy read
-	uart_putcrlf();
-	uint8_t buff[21];
-	for(uint8_t cnt=0; cnt<21; cnt++) {
-		uint8_t data=spiTransferByte(0x00);
-		buff[cnt]=data;
-	}
-	for(uint8_t cnt=0; cnt<21; cnt++) {
-		uint8_t data = buff[cnt];
-		_delay_ms(2);
-		if(data>=0x20 && data <= 0x7a) {
-			uart_putc(data);
-		} else {
-//			uart_putc('.');
-			uart_putc("0123456789ABCDEF"[data>>4]);
-			uart_putc("0123456789ABCDEF"[data&15]);
-			uart_putc(' ');
-		}
-//		set_avr_bank(3);
-	}
-	spi_none();
-}
-		while(1);
-}
-