diff --git a/OSU Coursework/CS 161 - Intro to Programming I/Final/Makefile b/OSU Coursework/CS 161 - Intro to Programming I/Final/Makefile new file mode 100644 index 0000000..449e1fd --- /dev/null +++ b/OSU Coursework/CS 161 - Intro to Programming I/Final/Makefile @@ -0,0 +1,336 @@ +#---------------------------------------------------------------------------- +# Wunderboard Makefile Template written by Dan Albert +#---------------------------------------------------------------------------- +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make filename.s = Just compile filename.c into the assembler code only. +# +# To rebuild project do "make clean" then "make all". +#---------------------------------------------------------------------------- + +# Target file name. +TARGET = main + +# List C source files here. +SRC = $(TARGET).c \ + adc.c + +# MCU name, you MUST set this to match the board you are using +# type "make clean" after changing this, so all files will be rebuilt +MCU = at90usb646 + +# Detect platform +UNAME = $(shell uname) + +ifeq ($(UNAME),Linux) +ENV=unix +endif + +ifeq ($(UNAME),Darwin) +ENV=unix +endif + +ifndef ENV +ENV=windows +endif + +ifeq ($(ENV),unix) +PROGRAM = dfu-programmer +PROGRAMFLAGS = $(MCU) +ERASE = erase +FLASH = flash "$(TARGET).hex" +START = start +else +PROGRAM = "C:/Program Files (x86)/Atmel/Flip 3.4.1/bin/batchisp.exe" +PROGRAMFLAGS = -device at90usb646 -hardware USB +ERASE = -operation erase F +FLASH = -operation loadbuffer "$(TARGET).hex" program verify +START = -operation start noreset 0 +endif + +# Processor frequency. +# Normally the first thing your program should do is set the clock prescaler, +# so your program will run at the correct speed. You should also set this +# variable to same clock speed. The _delay_ms() macro uses this, and many +# examples use this variable to calculate timings. Do not add a "UL" here. +F_CPU = 8000000 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Object files directory +# To put object files in current directory, use a dot (.), do NOT make +# this an empty or blank macro! +OBJDIR = obj + +# 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.) +OPT = s + +# 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 for C sources +CDEFS = -DF_CPU=$(F_CPU)UL + +#---------------- Compiler Options C ---------------- +# -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 += $(CDEFS) +CFLAGS += -O$(OPT) +CFLAGS += -funsigned-char +CFLAGS += -funsigned-bitfields +CFLAGS += -ffunction-sections +CFLAGS += -fpack-struct +CFLAGS += -fshort-enums +CFLAGS += -Wall +CFLAGS += -Wstrict-prototypes +#CFLAGS += -mshort-calls +#CFLAGS += -fno-unit-at-a-time +#CFLAGS += -Wundef +#CFLAGS += -Wunreachable-code +#CFLAGS += -Wsign-compare +CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +CFLAGS += $(CSTANDARD) + +#---------------- 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 + +# List any extra directories to look for libraries 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. +EXTRALIBDIRS = + +#---------------- 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 += -Wl,--relax +LDFLAGS += -Wl,--gc-sections +LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS)) +LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) +#LDFLAGS += -T linker_script.x + + +#============================================================================ + +# Define programs and commands. +SHELL = sh +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +AR = avr-ar rcs +NM = avr-nm +REMOVE = rm -f +REMOVEDIR = rm -rf +COPY = cp +WINSHELL = cmd + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling C: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: +MSG_CREATING_LIBRARY = Creating library: + +# Define all object files. +OBJ = $(SRC:%.c=$(OBJDIR)/%.o) + +# Define all listing files. +LST = $(SRC:%.c=$(OBJDIR)/%.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) + +# Default target. +all: begin gccversion sizebefore build sizeafter end + +# Change the build target to build a HEX file or a library. +build: elf hex eep lss sym +#build: lib + +elf: $(TARGET).elf +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym +LIBNAME=lib$(TARGET).a +lib: $(LIBNAME) + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +end: + @echo $(MSG_END) + @echo + +# Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf + +sizebefore: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +sizeafter: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +# Display compiler version information. +gccversion : + @$(CC) --version + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -R .signature $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0 + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S -z $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + $(NM) -n $< > $@ + + +# Create library from object files. +.SECONDARY : $(TARGET).a +.PRECIOUS : $(OBJ) +%.a: $(OBJ) + @echo + @echo $(MSG_CREATING_LIBRARY) $@ + $(AR) $@ $(OBJ) + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS) + +# Compile: create object files from C source files. +$(OBJDIR)/%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + +## Program +.PHONY: program +program: all + $(PROGRAM) $(PROGRAMFLAGS) $(ERASE) + $(PROGRAM) $(PROGRAMFLAGS) $(FLASH) + $(PROGRAM) $(PROGRAMFLAGS) $(START) + +doxygen: + doxygen + +# Target: clean project. +clean: begin clean_list end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lss + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o) + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + $(REMOVEDIR) .dep + $(REMOVEDIR) $(OBJDIR) + +# Create object files directory +$(shell mkdir $(OBJDIR) 2>/dev/null) + +# Include the dependency files. +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion \ +build elf hex eep lss sym \ +clean clean_list diff --git a/OSU Coursework/CS 161 - Intro to Programming I/Final/adc.c b/OSU Coursework/CS 161 - Intro to Programming I/Final/adc.c new file mode 100644 index 0000000..8d89140 --- /dev/null +++ b/OSU Coursework/CS 161 - Intro to Programming I/Final/adc.c @@ -0,0 +1,28 @@ +/** +@file adc.c +@brief Wunderboard ADC Helper Functions +@version .01 + +@section intro Code Overview +This is the code for the Wunderboard ADC helper functions. +*/ + +#include "adc.h" + +unsigned char read_adc(uint8_t channel){ + + unsigned char test; + + ADMUX = 0x60 | channel; // Set the channel to the one we want + ADCSRA = 0b11000110; // Start a new sample. + while ((ADCSRA & 0b00010000) == 0 ); // Wait for a Valid Sample + ADCSRA |= 0b00010000; // Tell ADC you have the sample you want. + ADCSRA |= 0b01000000; // Start a new sample. + while ((ADCSRA & 0b00010000) == 0 ); // Wait for a Valid Sample + ADCSRA |= 0b00010000; // Tell ADC you have the sample you want. + + test = ADCH; + ADCSRA = 0x00; // Disable the ADC + + return (test); +} diff --git a/OSU Coursework/CS 161 - Intro to Programming I/Final/adc.h b/OSU Coursework/CS 161 - Intro to Programming I/Final/adc.h new file mode 100644 index 0000000..c3086fd --- /dev/null +++ b/OSU Coursework/CS 161 - Intro to Programming I/Final/adc.h @@ -0,0 +1,19 @@ +/** +@file adc.h +@brief Wunderboard ADC Helper Functions +@version .01 + +@section intro Code Overview +This is the code for the Wunderboard ADC helper functions. +*/ + +#include + +/** +The read_adc() function allows for taking 8 bit measurements from any of the single ended ADC inputs. The function call is blocking. eg. read_adc(5) would read from ADC channel 5. +@param channel This is the channel to be read. +@return This is the return value from the ADC. +*/ + +unsigned char read_adc(uint8_t channel); + diff --git a/OSU Coursework/CS 161 - Intro to Programming I/Final/main.c b/OSU Coursework/CS 161 - Intro to Programming I/Final/main.c new file mode 100644 index 0000000..f73cf4c --- /dev/null +++ b/OSU Coursework/CS 161 - Intro to Programming I/Final/main.c @@ -0,0 +1,228 @@ +/** +@file main.c +@brief Lab 8 Starter Code +@version .01 +@mainpage Lab 8 Starter Code + +@section intro Code Overview + +@section hw Hardware Pin Out +Port A: +A0 - A3 : Push Buttons +A4 - A7 : Slide Switches + +Port B: +B0 - B3 : SPI (SD Card) +B4 : Nothing +B5 : Audio Out +B6 : Red Enable +B7 : Green Enable + +Port C: +C0 - C7 : LED Array (Row) + +Port D: +D0 - D1 : Nothing +D2 : Serial RX +D3 : Serial TX +D4 - D7 : Nothing + +Port E: +E0 - E2 : LED Array (Column) +E3 : USB (UID) +E4 - E5 : Nothing +E6 : Relay +E7 : Nothing + +Port F: +F0 : ADC Channel 0 +F1 : ADC Channel 1 +F2 : ADC Channel 2 +F3 : ADC Channel 3 +F4 : ADC Channel 4 (Audio In) +F5 : ADC Channel 5 (Accel X Axis) +F6 : ADC Channel 6 (Accel Y Axis) +F7 : ADC Channel 7 (Accel Z Axis (if installed)) + + */ + +/** Includes */ +#include +#include +#include "adc.h" +#include +#include + +/** Constants */ +#define F_CPU 1000000U +#define DELAY .02 + +#define YMIN 180.0 +#define STEPSIZE 2.75 + +#define SLOW 50 +#define FAST 25 +#define FASTEST 10 +/** Global Variables */ + +/** Functions */ + +/** The initialize() function initializes all of the Data Direction Registers for the Wunderboard. Before making changes to DDRx registers, ensure that you have read the peripherals section of the Wunderboard user guide.*/ +void initialize (void) { + /** Port A is the switches and buttons. They should always be inputs. ( 0 = Input and 1 = Output )*/ + DDRA=0b00000000; + + /** Port B has the LED Array color control, SD card, and audio-out on it. Leave DDRB alone. ( 0 = Input and 1 = Output )*/ + DDRB=0b11000000; + + /** Port C is for the 'row' of the LED array. They should always be outputs. ( 0 = Input and 1 = Output )*/ + DDRC=0b11111111; + + /** Port D has the Serial on it. Leave DDRB alone. ( 0 = Input and 1 = Output )*/ + DDRD=0b00000000; + + /** Port E has the LED Array Column control out on it. Leave DDRE alone. ( 0 = Input and 1 = Output )*/ + DDRE=0b00000111; + + /** Port F has the accelerometer and audio-in on it. Leave DDRF alone. ( 0 = Input and 1 = Output )*/ + DDRF=0b00000000; +} + +void clearArray(void) +{ + PORTB &= ~((1 << PB6) | (1 << PB7)); // Disable latches + PORTC = 0x00; + PORTB |= (1 << PB6) | (1 << PB7); // Enable latches + PORTB &= ~((1 << PB6) | (1 << PB7)); // Disable latches +} + +int readadcval(void){ + + char adcread = read_adc(5); + + if(adcread <= 181){ + return 0; + }else if((adcread == 182) | (adcread == 183)){ + return 1; + }else if((adcread == 184) | (adcread == 185) | (adcread == 186)){ + return 2; + }else if((adcread >= 187) & (adcread <= 191)){ + return 4; + }else if((adcread == 192) | (adcread == 193) | (adcread == 194)){ + return 6; + }else if((adcread == 195) | (adcread == 196) | (adcread == 197)){ + return 7; + }else if(adcread >= 198){ + return 8; + } + +} + +void printscreen(int loop, int loop3, const int *Red, const int *Green){ + int arrval; + clearArray(); + PORTE = loop3; + arrval = (loop+loop3); + + PORTB = 0b10000000; + PORTC = Green[arrval]; + _delay_ms(DELAY); + + clearArray(); + + PORTB= 0b01000000; + PORTC = Red[arrval]; + _delay_ms(DELAY); + + clearArray(); +} + +/** Main Function */ + +int main (void) { + /** Local Varibles */ + int loop = 0; + int *looppoint = &loop; + int loop2; + int loop3; + int speed = 20; + int adcreturn; + + const int Red[136] = {0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00001000,0b00000000,0b00001000,0b00101000,0b00001000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00001000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000100,0b00000100,0b00010000,0b00010000,0b00010000,0b00010000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00010000,0b00010100,0b00000000,0b00000000,0b00001000,0b00001000,0b00000000,0b00000000,0b00001000,0b00000000,0b00101000,0b00000000,0b00001000,0b00000000,0b00000000,0b00100000,0b00100000,0b00000000,0b00000000,0b00101000,0b00100000,0b00000000,0b00000000,0b00000010,0b00000110,0b00001110,0b00000000,0b00001110,0b00000110,0b00000010,0b0000000,0b00000000,0b00000010,0b00000110,0b00001110,0b00001110,0b00000000,0b00001110,0b00000110,0b00000010,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00001000,0b00001000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000010,0b00000110,0b00001110,0b00011110,0b00011110,0b00000000,0b00000000,0b00000000,0b00000010,0b00000000,0b00000000,0b00001110,0b00111110,0b00011000,0b00111110,0b00001110,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000}; + const int Green[136] = {0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000001,0b00000001,0b01000001,0b11000001,0b01000001,0b00000001,0b00000001,0b00001001,0b00000001,0b00001001,0b00101001,0b00001001,0b00000001,0b00000001,0b00000001,0b00000001,0b10000111,0b11000111,0b01000001,0b00000001,0b00000001,0b00001111,0b00001111,0b00000001,0b00000001,0b00001111,0b00001111,0b00000001,0b00000001,0b00001111,0b00001111,0b00000001,0b00000001,0b00001001,0b00000001,0b00000001,0b01000001,0b11100001,0b11100000,0b01000000,0b00000001,0b00000101,0b00000101,0b00010001,0b00010001,0b00010001,0b00010001,0b00000001,0b00000001,0b00000000,0b00000000,0b00000000,0b00010001,0b00010101,0b00000001,0b00000001,0b01001001,0b11001001,0b11000001,0b10000001,0b00001001,0b00000001,0b00101001,0b00000001,0b00001001,0b00000001,0b00000001,0b00100001,0b00100001,0b00000001,0b00000001,0b00101001,0b00100001,0b00000001,0b00000001,0b00000011,0b00000111,0b00001111,0b00000001,0b00001111,0b00000111,0b01000011,0b11000001,0b01000001,0b00000011,0b00000111,0b00001111,0b00001111,0b00000000,0b00001111,0b00000111,0b00000011,0b00000001,0b00000111,0b00000111,0b00000001,0b00000001,0b00001001,0b00001001,0b00000001,0b00000001,0b00000001,0b00000111,0b00000111,0b00000011,0b00000111,0b00001111,0b00011111,0b00011111,0b00000001,0b01000001,0b11100001,0b11100011,0b01000001,0b00000001,0b00000001,0b00000001,0b00000001,0b00000001,0b00000001,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000}; + + initialize(); + clearArray(); + + while(1){ + + adcreturn = readadcval(); + + if(adcreturn == 4){ + + for(loop2 = 0; loop2 < 50 ; loop2++){ + for(loop3 = 7 ; loop3 > -1 ; loop3--){ + printscreen(loop, loop3, Red, Green); + } + } + + }else if(adcreturn < 4){ + for(loop ; loop >= 0 ; loop--){ + + if(adcreturn == 2){ + speed = SLOW; + }else if(adcreturn == 1){ + speed = FAST; + }else if(adcreturn == 0){ + speed = FASTEST; + } + + for(loop2 = 0 ; loop2 < speed ; loop2++){ + for(loop3 = 7 ; loop3 > -1 ; loop3--){ + + printscreen(loop, loop3, Red, Green); + + if(loop == 0){ + loop = 128; + } + } + } + + adcreturn = readadcval(); + if((adcreturn < 4) != 1){ + break; + } + } + + + + }else if(adcreturn > 4){ + for(loop ; loop <= 128 ; loop++){ + + if(adcreturn == 6){ + speed = SLOW; + }else if(adcreturn == 7){ + speed = FAST; + }else if(adcreturn == 8){ + speed = FASTEST; + } + + for(loop2 = 0 ; loop2 < speed ; loop2++){ + for(loop3 = 7 ; loop3 > -1 ; loop3--){ + + printscreen(loop, loop3, Red, Green); + + if(loop == 128){ + loop = 0; + } + } + } + + adcreturn = readadcval(); + if((adcreturn > 4) != 1){ + break; + } + } + } + } +} \ No newline at end of file diff --git a/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 6/Makefile b/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 6/Makefile new file mode 100644 index 0000000..6c38e27 --- /dev/null +++ b/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 6/Makefile @@ -0,0 +1,335 @@ +#---------------------------------------------------------------------------- +# Wunderboard Makefile Template written by Dan Albert +#---------------------------------------------------------------------------- +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make filename.s = Just compile filename.c into the assembler code only. +# +# To rebuild project do "make clean" then "make all". +#---------------------------------------------------------------------------- + +# Target file name. +TARGET = main + +# List C source files here. +SRC = $(TARGET).c \ + +# MCU name, you MUST set this to match the board you are using +# type "make clean" after changing this, so all files will be rebuilt +MCU = at90usb646 + +# Detect platform +UNAME = $(shell uname) + +ifeq ($(UNAME),Linux) +ENV=unix +endif + +ifeq ($(UNAME),Darwin) +ENV=unix +endif + +ifndef ENV +ENV=windows +endif + +ifeq ($(ENV),unix) +PROGRAM = dfu-programmer +PROGRAMFLAGS = $(MCU) +ERASE = erase +FLASH = flash "$(TARGET).hex" +START = start +else +PROGRAM = "C:/Program Files (x86)/Atmel/Flip 3.4.1/bin/batchisp.exe" +PROGRAMFLAGS = -device at90usb646 -hardware USB +ERASE = -operation erase F +FLASH = -operation loadbuffer "$(TARGET).hex" program verify +START = -operation start noreset 0 +endif + +# Processor frequency. +# Normally the first thing your program should do is set the clock prescaler, +# so your program will run at the correct speed. You should also set this +# variable to same clock speed. The _delay_ms() macro uses this, and many +# examples use this variable to calculate timings. Do not add a "UL" here. +F_CPU = 8000000 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Object files directory +# To put object files in current directory, use a dot (.), do NOT make +# this an empty or blank macro! +OBJDIR = obj + +# 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.) +OPT = s + +# 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 for C sources +CDEFS = -DF_CPU=$(F_CPU)UL + +#---------------- Compiler Options C ---------------- +# -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 += $(CDEFS) +CFLAGS += -O$(OPT) +CFLAGS += -funsigned-char +CFLAGS += -funsigned-bitfields +CFLAGS += -ffunction-sections +CFLAGS += -fpack-struct +CFLAGS += -fshort-enums +CFLAGS += -Wall +CFLAGS += -Wstrict-prototypes +#CFLAGS += -mshort-calls +#CFLAGS += -fno-unit-at-a-time +#CFLAGS += -Wundef +#CFLAGS += -Wunreachable-code +#CFLAGS += -Wsign-compare +CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +CFLAGS += $(CSTANDARD) + +#---------------- 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 + +# List any extra directories to look for libraries 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. +EXTRALIBDIRS = + +#---------------- 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 += -Wl,--relax +LDFLAGS += -Wl,--gc-sections +LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS)) +LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) +#LDFLAGS += -T linker_script.x + + +#============================================================================ + +# Define programs and commands. +SHELL = sh +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +AR = avr-ar rcs +NM = avr-nm +REMOVE = rm -f +REMOVEDIR = rm -rf +COPY = cp +WINSHELL = cmd + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling C: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: +MSG_CREATING_LIBRARY = Creating library: + +# Define all object files. +OBJ = $(SRC:%.c=$(OBJDIR)/%.o) + +# Define all listing files. +LST = $(SRC:%.c=$(OBJDIR)/%.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) + +# Default target. +all: begin gccversion sizebefore build sizeafter end + +# Change the build target to build a HEX file or a library. +build: elf hex eep lss sym +#build: lib + +elf: $(TARGET).elf +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym +LIBNAME=lib$(TARGET).a +lib: $(LIBNAME) + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +end: + @echo $(MSG_END) + @echo + +# Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf + +sizebefore: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +sizeafter: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +# Display compiler version information. +gccversion : + @$(CC) --version + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -R .signature $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0 + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S -z $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + $(NM) -n $< > $@ + + +# Create library from object files. +.SECONDARY : $(TARGET).a +.PRECIOUS : $(OBJ) +%.a: $(OBJ) + @echo + @echo $(MSG_CREATING_LIBRARY) $@ + $(AR) $@ $(OBJ) + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS) + +# Compile: create object files from C source files. +$(OBJDIR)/%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + +## Program +.PHONY: program +program: all + $(PROGRAM) $(PROGRAMFLAGS) $(ERASE) + $(PROGRAM) $(PROGRAMFLAGS) $(FLASH) + $(PROGRAM) $(PROGRAMFLAGS) $(START) + +doxygen: + doxygen + +# Target: clean project. +clean: begin clean_list end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lss + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o) + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + $(REMOVEDIR) .dep + $(REMOVEDIR) $(OBJDIR) + +# Create object files directory +$(shell mkdir $(OBJDIR) 2>/dev/null) + +# Include the dependency files. +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion \ +build elf hex eep lss sym \ +clean clean_list diff --git a/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 6/main.c b/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 6/main.c new file mode 100644 index 0000000..cb604d9 --- /dev/null +++ b/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 6/main.c @@ -0,0 +1,75 @@ +/** +@file main.c +@brief Lab 6 Starter Code +@version .01 +@mainpage Lab 6 Starter Code + +@section intro Code Overview +This first lab allows outputs to the LED array and single patteren of lights. You need to revise it so that it outputs lights based on the input from the switches. + +@section hw Hardware Pin Out +PORTA: +Switches A7 - A0 + +PORTB: + + + + */ + +/** Includes */ +#include +#include + +/** Constants */ +#define F_CPU 1000000U + +/** Global Variables */ + +/** Functions */ + +/** The initialize() function initializes all of the Data Direction Registers for the Wunderboard. Before making changes to DDRx registers, ensure that you have read the peripherals section of the Wunderboard user guide.*/ +void initialize (void) { + /** Port A is the switches and buttons. They should always be inputs. ( 0 = Input and 1 = Output )*/ + DDRA=0b00000000; + + /** Port B has the LED Array color control, SD card, and audio-out on it. Leave DDRB alone. ( 0 = Input and 1 = Output )*/ + DDRB=0b11000000; + + /** Port C is for the 'row' of the LED array. They should always be outputs. ( 0 = Input and 1 = Output )*/ + DDRC=0b11111111; + + /** Port D has the Serial on it. Leave DDRB alone. ( 0 = Input and 1 = Output )*/ + DDRD=0b00000000; + + /** Port E has the LED Array Column control out on it. Leave DDRE alone. ( 0 = Input and 1 = Output )*/ + DDRE=0b00000111; + + /** Port F has the accelerometer and audio-in on it. Leave DDRF alone. ( 0 = Input and 1 = Output )*/ + DDRF=0b00000000; +} + +void clearArray(void) +{ + PORTB &= ~((1 << PB6) | (1 << PB7)); // Disable latches + PORTC = 0x00; + PORTB |= (1 << PB6) | (1 << PB7); // Enable latches + PORTB &= ~((1 << PB6) | (1 << PB7)); // Disable latches +} + +/** Main Function */ + +int main (void) { + /** Local Varibles */ + unsigned char temp; + unsigned char switches; + + initialize(); + clearArray(); + + while(1){ + PORTB = 0b10000000; //Sets the green leds on + PORTC = PINA; //Sets led values to the switch values + } + +}//main diff --git a/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 7/Makefile b/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 7/Makefile new file mode 100644 index 0000000..6c38e27 --- /dev/null +++ b/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 7/Makefile @@ -0,0 +1,335 @@ +#---------------------------------------------------------------------------- +# Wunderboard Makefile Template written by Dan Albert +#---------------------------------------------------------------------------- +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make filename.s = Just compile filename.c into the assembler code only. +# +# To rebuild project do "make clean" then "make all". +#---------------------------------------------------------------------------- + +# Target file name. +TARGET = main + +# List C source files here. +SRC = $(TARGET).c \ + +# MCU name, you MUST set this to match the board you are using +# type "make clean" after changing this, so all files will be rebuilt +MCU = at90usb646 + +# Detect platform +UNAME = $(shell uname) + +ifeq ($(UNAME),Linux) +ENV=unix +endif + +ifeq ($(UNAME),Darwin) +ENV=unix +endif + +ifndef ENV +ENV=windows +endif + +ifeq ($(ENV),unix) +PROGRAM = dfu-programmer +PROGRAMFLAGS = $(MCU) +ERASE = erase +FLASH = flash "$(TARGET).hex" +START = start +else +PROGRAM = "C:/Program Files (x86)/Atmel/Flip 3.4.1/bin/batchisp.exe" +PROGRAMFLAGS = -device at90usb646 -hardware USB +ERASE = -operation erase F +FLASH = -operation loadbuffer "$(TARGET).hex" program verify +START = -operation start noreset 0 +endif + +# Processor frequency. +# Normally the first thing your program should do is set the clock prescaler, +# so your program will run at the correct speed. You should also set this +# variable to same clock speed. The _delay_ms() macro uses this, and many +# examples use this variable to calculate timings. Do not add a "UL" here. +F_CPU = 8000000 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Object files directory +# To put object files in current directory, use a dot (.), do NOT make +# this an empty or blank macro! +OBJDIR = obj + +# 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.) +OPT = s + +# 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 for C sources +CDEFS = -DF_CPU=$(F_CPU)UL + +#---------------- Compiler Options C ---------------- +# -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 += $(CDEFS) +CFLAGS += -O$(OPT) +CFLAGS += -funsigned-char +CFLAGS += -funsigned-bitfields +CFLAGS += -ffunction-sections +CFLAGS += -fpack-struct +CFLAGS += -fshort-enums +CFLAGS += -Wall +CFLAGS += -Wstrict-prototypes +#CFLAGS += -mshort-calls +#CFLAGS += -fno-unit-at-a-time +#CFLAGS += -Wundef +#CFLAGS += -Wunreachable-code +#CFLAGS += -Wsign-compare +CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +CFLAGS += $(CSTANDARD) + +#---------------- 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 + +# List any extra directories to look for libraries 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. +EXTRALIBDIRS = + +#---------------- 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 += -Wl,--relax +LDFLAGS += -Wl,--gc-sections +LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS)) +LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) +#LDFLAGS += -T linker_script.x + + +#============================================================================ + +# Define programs and commands. +SHELL = sh +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +AR = avr-ar rcs +NM = avr-nm +REMOVE = rm -f +REMOVEDIR = rm -rf +COPY = cp +WINSHELL = cmd + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling C: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: +MSG_CREATING_LIBRARY = Creating library: + +# Define all object files. +OBJ = $(SRC:%.c=$(OBJDIR)/%.o) + +# Define all listing files. +LST = $(SRC:%.c=$(OBJDIR)/%.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) + +# Default target. +all: begin gccversion sizebefore build sizeafter end + +# Change the build target to build a HEX file or a library. +build: elf hex eep lss sym +#build: lib + +elf: $(TARGET).elf +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym +LIBNAME=lib$(TARGET).a +lib: $(LIBNAME) + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +end: + @echo $(MSG_END) + @echo + +# Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf + +sizebefore: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +sizeafter: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +# Display compiler version information. +gccversion : + @$(CC) --version + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -R .signature $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0 + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S -z $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + $(NM) -n $< > $@ + + +# Create library from object files. +.SECONDARY : $(TARGET).a +.PRECIOUS : $(OBJ) +%.a: $(OBJ) + @echo + @echo $(MSG_CREATING_LIBRARY) $@ + $(AR) $@ $(OBJ) + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS) + +# Compile: create object files from C source files. +$(OBJDIR)/%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + +## Program +.PHONY: program +program: all + $(PROGRAM) $(PROGRAMFLAGS) $(ERASE) + $(PROGRAM) $(PROGRAMFLAGS) $(FLASH) + $(PROGRAM) $(PROGRAMFLAGS) $(START) + +doxygen: + doxygen + +# Target: clean project. +clean: begin clean_list end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lss + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o) + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + $(REMOVEDIR) .dep + $(REMOVEDIR) $(OBJDIR) + +# Create object files directory +$(shell mkdir $(OBJDIR) 2>/dev/null) + +# Include the dependency files. +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion \ +build elf hex eep lss sym \ +clean clean_list diff --git a/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 7/main.c b/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 7/main.c new file mode 100644 index 0000000..7d7c931 --- /dev/null +++ b/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 7/main.c @@ -0,0 +1,177 @@ +/** +@file main.c +@brief Lab 6 Starter Code +@version .01 +@mainpage Lab 6 Starter Code + +@section intro Code Overview +This first lab allows outputs to the LED array and single patteren of lights. You need to revise it so that it outputs lights based on the input from the switches. + +@section hw Hardware Pin Out +PORTA: +Switches A7 - A0 + +PORTB: + +*/ + +/** Includes */ +#include +#include + +/** Constants */ +#define F_CPU 1000000U +#define DELAY .01 +/** Global Variables */ + +/** Functions */ + +/** The initialize() function initializes all of the Data Direction Registers for the Wunderboard. Before making changes to DDRx registers, ensure that you have read the peripherals section of the Wunderboard user guide.*/ +void initialize (void) { + /** Port A is the switches and buttons. They should always be inputs. ( 0 = Input and 1 = Output )*/ + DDRA=0b00000000; + + /** Port B has the LED Array color control, SD card, and audio-out on it. Leave DDRB alone. ( 0 = Input and 1 = Output )*/ + DDRB=0b11000000; + + /** Port C is for the 'row' of the LED array. They should always be outputs. ( 0 = Input and 1 = Output )*/ + DDRC=0b11111111; + + /** Port D has the Serial on it. Leave DDRB alone. ( 0 = Input and 1 = Output )*/ + DDRD=0b00000000; + + /** Port E has the LED Array Column control out on it. Leave DDRE alone. ( 0 = Input and 1 = Output )*/ + DDRE=0b00000111; + + /** Port F has the accelerometer and audio-in on it. Leave DDRF alone. ( 0 = Input and 1 = Output )*/ + DDRF=0b00000000; +} + +void clearArray(void) +{ + PORTB &= ~((1 << PB6) | (1 << PB7)); // Disable latches + PORTC = 0x00; + PORTB |= (1 << PB6) | (1 << PB7); // Enable latches + PORTB &= ~((1 << PB6) | (1 << PB7)); // Disable latches +} + +/** Main Function */ + +int main (void) { + /** Local Varibles */ + //char red[8]; + //char green[8]; + char loop; + + initialize(); + clearArray(); + + + while(1){ + + if (PINA == 0b01110000){ + clearArray(); + + PORTB = 0b11000000; + + PORTE = 0b00000011; + PORTC = 0b11011010; + _delay_ms(DELAY); + clearArray(); + + + }else if (PINA == 0b10110000){ + clearArray(); + + PORTB = 0b11000000; + + PORTE = 0b00000011; + PORTC = 0b01010101; + _delay_ms(DELAY); + + clearArray(); + + PORTB = 0b11000000; + PORTE = 0b00000110; + PORTC = 0b10101010; + _delay_ms(DELAY); + clearArray(); + + + }else if (PINA == 0b11010000){ + clearArray(); + + PORTB = 0b10000000; + + PORTE = 0b00000011; + PORTC = 0b01010101; + _delay_ms(DELAY); + + clearArray(); + + PORTB = 0b01000000; + + PORTE = 0b00000110; + PORTC = 0b10101010; + _delay_ms(DELAY); + clearArray(); + + + }else if (PINA == 0b11111000){ + char red[8] = {0b10000000, 0b01000000, 0b00100000, 0b00010000, 0b00001000, 0b00000100, 0b00000010, 0b00000001}; + char green[8] = {0b01111000, 0b10111100, 0b11011110, 0b11101111, 0b11110111, 0b01111011, 0b00111101, 0b00011110}; + char orange[8] = {0b00000111, 0b00000011, 0b00000001, 0b00000000, 0b00000000, 0b10000000, 0b11000000, 0b11100000}; + + clearArray(); + + for ( loop = 0 ; loop < 8 ; loop++ ){ + + PORTB = 0b01000000; + PORTE = loop; + PORTC = red[loop]; + _delay_ms(DELAY); + + clearArray(); + + PORTB = 0b10000000; + PORTC = green[loop]; + _delay_ms(DELAY); + + clearArray(); + + PORTB = 0b11000000; + PORTC = orange[loop]; + _delay_ms(DELAY); + + clearArray(); + + } + + }else if (PINA == 0b11100000){ + char red[8] = {0b11111111, 0b01110111, 0b00100010,0b00000000, 0b00000000, 0b00100010, 0b01110111, 0b11111111}; + char green[8] = {0b00000000, 0b10001000, 0b11011101, 0b11111111, 0b11111111, 0b11011101, 0b10001000, 0b00000000}; + + clearArray(); + + for ( loop = 0 ; loop < 8 ; loop++ ){ + + PORTB = 0b01000000; + PORTE = loop; + PORTC = red[loop]; + _delay_ms(DELAY); + + clearArray(); + + PORTB = 0b10000000; + PORTC = green[loop]; + _delay_ms(DELAY); + + clearArray(); + + } + } + } + + + +}//main diff --git a/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 8/Makefile b/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 8/Makefile new file mode 100644 index 0000000..449e1fd --- /dev/null +++ b/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 8/Makefile @@ -0,0 +1,336 @@ +#---------------------------------------------------------------------------- +# Wunderboard Makefile Template written by Dan Albert +#---------------------------------------------------------------------------- +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make filename.s = Just compile filename.c into the assembler code only. +# +# To rebuild project do "make clean" then "make all". +#---------------------------------------------------------------------------- + +# Target file name. +TARGET = main + +# List C source files here. +SRC = $(TARGET).c \ + adc.c + +# MCU name, you MUST set this to match the board you are using +# type "make clean" after changing this, so all files will be rebuilt +MCU = at90usb646 + +# Detect platform +UNAME = $(shell uname) + +ifeq ($(UNAME),Linux) +ENV=unix +endif + +ifeq ($(UNAME),Darwin) +ENV=unix +endif + +ifndef ENV +ENV=windows +endif + +ifeq ($(ENV),unix) +PROGRAM = dfu-programmer +PROGRAMFLAGS = $(MCU) +ERASE = erase +FLASH = flash "$(TARGET).hex" +START = start +else +PROGRAM = "C:/Program Files (x86)/Atmel/Flip 3.4.1/bin/batchisp.exe" +PROGRAMFLAGS = -device at90usb646 -hardware USB +ERASE = -operation erase F +FLASH = -operation loadbuffer "$(TARGET).hex" program verify +START = -operation start noreset 0 +endif + +# Processor frequency. +# Normally the first thing your program should do is set the clock prescaler, +# so your program will run at the correct speed. You should also set this +# variable to same clock speed. The _delay_ms() macro uses this, and many +# examples use this variable to calculate timings. Do not add a "UL" here. +F_CPU = 8000000 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Object files directory +# To put object files in current directory, use a dot (.), do NOT make +# this an empty or blank macro! +OBJDIR = obj + +# 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.) +OPT = s + +# 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 for C sources +CDEFS = -DF_CPU=$(F_CPU)UL + +#---------------- Compiler Options C ---------------- +# -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 += $(CDEFS) +CFLAGS += -O$(OPT) +CFLAGS += -funsigned-char +CFLAGS += -funsigned-bitfields +CFLAGS += -ffunction-sections +CFLAGS += -fpack-struct +CFLAGS += -fshort-enums +CFLAGS += -Wall +CFLAGS += -Wstrict-prototypes +#CFLAGS += -mshort-calls +#CFLAGS += -fno-unit-at-a-time +#CFLAGS += -Wundef +#CFLAGS += -Wunreachable-code +#CFLAGS += -Wsign-compare +CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +CFLAGS += $(CSTANDARD) + +#---------------- 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 + +# List any extra directories to look for libraries 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. +EXTRALIBDIRS = + +#---------------- 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 += -Wl,--relax +LDFLAGS += -Wl,--gc-sections +LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS)) +LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) +#LDFLAGS += -T linker_script.x + + +#============================================================================ + +# Define programs and commands. +SHELL = sh +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +AR = avr-ar rcs +NM = avr-nm +REMOVE = rm -f +REMOVEDIR = rm -rf +COPY = cp +WINSHELL = cmd + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling C: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: +MSG_CREATING_LIBRARY = Creating library: + +# Define all object files. +OBJ = $(SRC:%.c=$(OBJDIR)/%.o) + +# Define all listing files. +LST = $(SRC:%.c=$(OBJDIR)/%.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) + +# Default target. +all: begin gccversion sizebefore build sizeafter end + +# Change the build target to build a HEX file or a library. +build: elf hex eep lss sym +#build: lib + +elf: $(TARGET).elf +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym +LIBNAME=lib$(TARGET).a +lib: $(LIBNAME) + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +end: + @echo $(MSG_END) + @echo + +# Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf + +sizebefore: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +sizeafter: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +# Display compiler version information. +gccversion : + @$(CC) --version + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -R .signature $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0 + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S -z $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + $(NM) -n $< > $@ + + +# Create library from object files. +.SECONDARY : $(TARGET).a +.PRECIOUS : $(OBJ) +%.a: $(OBJ) + @echo + @echo $(MSG_CREATING_LIBRARY) $@ + $(AR) $@ $(OBJ) + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS) + +# Compile: create object files from C source files. +$(OBJDIR)/%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + +## Program +.PHONY: program +program: all + $(PROGRAM) $(PROGRAMFLAGS) $(ERASE) + $(PROGRAM) $(PROGRAMFLAGS) $(FLASH) + $(PROGRAM) $(PROGRAMFLAGS) $(START) + +doxygen: + doxygen + +# Target: clean project. +clean: begin clean_list end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lss + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o) + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + $(REMOVEDIR) .dep + $(REMOVEDIR) $(OBJDIR) + +# Create object files directory +$(shell mkdir $(OBJDIR) 2>/dev/null) + +# Include the dependency files. +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion \ +build elf hex eep lss sym \ +clean clean_list diff --git a/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 8/adc.c b/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 8/adc.c new file mode 100644 index 0000000..8d89140 --- /dev/null +++ b/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 8/adc.c @@ -0,0 +1,28 @@ +/** +@file adc.c +@brief Wunderboard ADC Helper Functions +@version .01 + +@section intro Code Overview +This is the code for the Wunderboard ADC helper functions. +*/ + +#include "adc.h" + +unsigned char read_adc(uint8_t channel){ + + unsigned char test; + + ADMUX = 0x60 | channel; // Set the channel to the one we want + ADCSRA = 0b11000110; // Start a new sample. + while ((ADCSRA & 0b00010000) == 0 ); // Wait for a Valid Sample + ADCSRA |= 0b00010000; // Tell ADC you have the sample you want. + ADCSRA |= 0b01000000; // Start a new sample. + while ((ADCSRA & 0b00010000) == 0 ); // Wait for a Valid Sample + ADCSRA |= 0b00010000; // Tell ADC you have the sample you want. + + test = ADCH; + ADCSRA = 0x00; // Disable the ADC + + return (test); +} diff --git a/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 8/adc.h b/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 8/adc.h new file mode 100644 index 0000000..c3086fd --- /dev/null +++ b/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 8/adc.h @@ -0,0 +1,19 @@ +/** +@file adc.h +@brief Wunderboard ADC Helper Functions +@version .01 + +@section intro Code Overview +This is the code for the Wunderboard ADC helper functions. +*/ + +#include + +/** +The read_adc() function allows for taking 8 bit measurements from any of the single ended ADC inputs. The function call is blocking. eg. read_adc(5) would read from ADC channel 5. +@param channel This is the channel to be read. +@return This is the return value from the ADC. +*/ + +unsigned char read_adc(uint8_t channel); + diff --git a/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 8/main.c b/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 8/main.c new file mode 100644 index 0000000..e4d7140 --- /dev/null +++ b/OSU Coursework/CS 161 - Intro to Programming I/Labs/Lab 8/main.c @@ -0,0 +1,189 @@ +/** +@file main.c +@brief Lab 8 Starter Code +@version .01 +@mainpage Lab 8 Starter Code + +@section intro Code Overview + +@section hw Hardware Pin Out +Port A: +A0 - A3 : Push Buttons +A4 - A7 : Slide Switches + +Port B: +B0 - B3 : SPI (SD Card) +B4 : Nothing +B5 : Audio Out +B6 : Red Enable +B7 : Green Enable + +Port C: +C0 - C7 : LED Array (Row) + +Port D: +D0 - D1 : Nothing +D2 : Serial RX +D3 : Serial TX +D4 - D7 : Nothing + +Port E: +E0 - E2 : LED Array (Column) +E3 : USB (UID) +E4 - E5 : Nothing +E6 : Relay +E7 : Nothing + +Port F: +F0 : ADC Channel 0 +F1 : ADC Channel 1 +F2 : ADC Channel 2 +F3 : ADC Channel 3 +F4 : ADC Channel 4 (Audio In) +F5 : ADC Channel 5 (Accel X Axis) +F6 : ADC Channel 6 (Accel Y Axis) +F7 : ADC Channel 7 (Accel Z Axis (if installed)) + + */ + +/** Includes */ +#include +#include +#include "adc.h" +#include +#include + +/** Constants */ +#define F_CPU 1000000U +#define DELAY .02 + +#define YMIN 180.0 +#define STEPSIZE 1.375 +/** Global Variables */ + +/** Functions */ + +/** The initialize() function initializes all of the Data Direction Registers for the Wunderboard. Before making changes to DDRx registers, ensure that you have read the peripherals section of the Wunderboard user guide.*/ +void initialize (void) { + /** Port A is the switches and buttons. They should always be inputs. ( 0 = Input and 1 = Output )*/ + DDRA=0b00000000; + + /** Port B has the LED Array color control, SD card, and audio-out on it. Leave DDRB alone. ( 0 = Input and 1 = Output )*/ + DDRB=0b11000000; + + /** Port C is for the 'row' of the LED array. They should always be outputs. ( 0 = Input and 1 = Output )*/ + DDRC=0b11111111; + + /** Port D has the Serial on it. Leave DDRB alone. ( 0 = Input and 1 = Output )*/ + DDRD=0b00000000; + + /** Port E has the LED Array Column control out on it. Leave DDRE alone. ( 0 = Input and 1 = Output )*/ + DDRE=0b00000111; + + /** Port F has the accelerometer and audio-in on it. Leave DDRF alone. ( 0 = Input and 1 = Output )*/ + DDRF=0b00000000; +} + +void clearArray(void) +{ + PORTB &= ~((1 << PB6) | (1 << PB7)); // Disable latches + PORTC = 0x00; + PORTB |= (1 << PB6) | (1 << PB7); // Enable latches + PORTB &= ~((1 << PB6) | (1 << PB7)); // Disable latches +} + +int readadcval(void){ + int loop4; + int adcreturn; + char adcread = read_adc(5); + + for(loop4 = 0 ; loop4 < 16 ; loop4++){ + if(((YMIN + (loop4*STEPSIZE)) <= adcread) & (adcread < (YMIN + ((loop4 + 1)*STEPSIZE)))){ + adcreturn = 2*loop4; + } + } + return adcreturn; +} + +/** Main Function */ + +int main (void) { + /** Local Varibles */ + int loop = 50; + int loop2; + int loop3; + int speed = 20; + int *speedpoint = &speed; + + const int Red[120] = {0b00000000, 0b00000000, 0b01000000, 0b11000000, 0b01000000, 0b00000000, 0b00000000, 0b00001000, 0b00000000, 0b00001000, 0b00101000, 0b00001000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b10000000, 0b11000000, 0b01000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00001000, 0b00000000, 0b00000000, 0b01000000, 0b11000000, 0b11100000, 0b01000000, 0b00000000, 0b00000100, 0b00000100, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00010000, 0b00010100, 0b00000000, 0b00000000, 0b01001000, 0b11001000, 0b11000000, 0b10000000, 0b00001000, 0b00000000, 0b00101000, 0b00000000, 0b00001000, 0b00000000, 0b00000000, 0b00100000, 0b00100000, 0b00000000, 0b00000000, 0b00101000, 0b00100000, 0b00000000, 0b00000000, 0b00000010, 0b00000110, 0b00001110, 0b00000000, 0b00001110, 0b00000110, 0b01000010, 0b11000000, 0b01000000, 0b00000010, 0b00000110, 0b00001110, 0b00001110, 0b00000000, 0b00001110, 0b00000110, 0b00000010, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00001000, 0b00001000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000010, 0b00000110, 0b00001110, 0b00011110, 0b00011110, 0b00000000, 0b01000000, 0b11100000, 0b11100010, 0b01000000, 0b00000000, 0b00001110, 0b00111110, 0b00011000, 0b00111110, 0b00001110}; + const int Green[120] = {0b00000001, 0b00000001, 0b01000001, 0b11000001, 0b01000001, 0b00000001, 0b00000001, 0b00001001, 0b00000001, 0b00001001, 0b00101001, 0b00001001, 0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b10000111, 0b11000111, 0b01000001, 0b00000001, 0b00000001, 0b00001111, 0b00001111, 0b00000001, 0b00000001, 0b00001111, 0b00001111, 0b00000001, 0b00000001, 0b00001111, 0b00001111, 0b00000001, 0b00000001, 0b00001001, 0b00000001, 0b00000001, 0b01000001, 0b11000001, 0b11100000, 0b01000000, 0b00000001, 0b00000101, 0b00000101, 0b00010001, 0b00010001, 0b00010001, 0b00010001, 0b00000001, 0b00000001, 0b00000000, 0b00000000, 0b00000000, 0b00010001, 0b00010101, 0b00000001, 0b00000001, 0b01001001, 0b11001001, 0b11000001, 0b10000001, 0b00001001, 0b00000001, 0b00101001, 0b00000001, 0b00001001, 0b00000001, 0b00000001, 0b00100001, 0b00100001, 0b00000001, 0b00000001, 0b00101001, 0b00100001, 0b00000001, 0b00000001, 0b00000011, 0b00000111, 0b00001111, 0b00000001, 0b00001111, 0b00000111, 0b01000011, 0b11000001, 0b01000001, 0b00000011, 0b00000111, 0b00001111, 0b00001111, 0b00000000, 0b00001111, 0b00000111, 0b00000011, 0b00000001, 0b00000111, 0b00000111, 0b00000001, 0b00000001, 0b00001001, 0b00001001, 0b00000001, 0b00000001, 0b00000001, 0b00000111, 0b00000111, 0b00000011, 0b00000111, 0b00001111, 0b00011111, 0b00011111, 0b00000001, 0b01000001, 0b11100001, 0b11100011, 0b01000001, 0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000001}; + + initialize(); + clearArray(); + + while(1){ + + speedpoint = 25; + + for(loop ; loop >= 0 ; loop--){ + speedpoint = readadcval(); + + if(speedpoint == 0){ + while(speedpoint == 0){ + for(loop2 = 0 ; loop2 < 150 ; loop2++){ + for(loop3 = 7 ; loop3 > -1 ; loop3--){ + + + int arrval; + clearArray(); + PORTE = loop3; + arrval = (loop+loop3); + + PORTB = 0b10000000; + PORTC = Green[arrval]; + _delay_ms(DELAY); + + clearArray(); + + PORTB= 0b01000000; + PORTC = Red[arrval]; + _delay_ms(DELAY); + + clearArray(); + } + } + speedpoint = readadcval(); + } + }else{ + for(loop2 = 0 ; loop2 < speedpoint ; loop2++){ + for(loop3 = 7 ; loop3 > -1 ; loop3--){ + + + int arrval; + clearArray(); + PORTE = loop3; + arrval = (loop+loop3); + + PORTB = 0b10000000; + PORTC = Green[arrval]; + _delay_ms(DELAY); + + clearArray(); + + PORTB= 0b01000000; + PORTC = Red[arrval]; + _delay_ms(DELAY); + + clearArray(); + } + } + } + + if(loop == 0){ + loop = 112; + } + } + } +} + + diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 1/Assignment 1.pdf b/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 1/Assignment 1.pdf new file mode 100644 index 0000000..a1aa380 Binary files /dev/null and b/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 1/Assignment 1.pdf differ diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 2/Assignment 2.pdf b/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 2/Assignment 2.pdf new file mode 100644 index 0000000..2896bd7 Binary files /dev/null and b/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 2/Assignment 2.pdf differ diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 3/.~$a.exe.insyncdl b/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 3/.~$a.exe.insyncdl new file mode 100644 index 0000000..e69de29 diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 3/CppAssign0.cpp b/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 3/CppAssign0.cpp new file mode 100644 index 0000000..0f7e19c --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 3/CppAssign0.cpp @@ -0,0 +1,66 @@ +#include +#include +using namespace std; + +int main(void){ + + unsigned char exit; + string response; + + enum question{ + first, + second, + third + } currentquestion = first; + + while(exit != 1){ + switch(currentquestion){ + case first: + + cout << "First Question: Which is NOT an internal component of a desktop computer?\n\nA: Ram Module\nB: Power Supply\nC: Hard Drive\nD: Monitor\nPlease enter your selection: "; + cin >> response; + if((response.compare("a") == 0) | (response.compare("A") == 0)){ + cout << "\nIncorrect. Ram modules are an internal component.\nPlease try again..." << endl; + cout << string(2, '\n'); + }else if((response.compare("b") == 0) | (response.compare("B") == 0)){ + cout << "\nIncorrect. Power supplies are an internal component.\nPlease try again..." << endl; + cout << string(2, '\n'); + }else if((response.compare("c") == 0) | (response.compare("C") == 0)){ + cout << "\nIncorrect. Hard drives are an internal component.\nPlease try again..." << endl; + cout << string(2, '\n'); + }else if((response.compare("d") == 0) | (response.compare("D") == 0)){ + cout << "\nCorrect! Monitor's are external components on desktops." << endl; + cout << string(2, '\n'); + currentquestion = second; + }else{ + cout << "You have entered an invalid response, please try again..." << endl; + cout << string(2, '\n'); + } + break; + case second: + cout << "Second Question: Which is a model number for an ivy bridge processor?\nA: i5-3570K\nB: i7-2600K\nC: i3-2120\nD: i5-2400\nPlease enter your selection: "; + cin >> response; + if((response.compare("a") == 0) | (response.compare("A") == 0)){ + cout << "\nCorrect!. This is an ivy bridge processor!" << endl; + cout << string(2, '\n'); + return 0; + }else if((response.compare("b") == 0) | (response.compare("B") == 0)){ + cout << "\nIncorrect. This is a Sandy Bridge processor.\nPlease try again..." << endl; + cout << string(2, '\n'); + }else if((response.compare("c") == 0) | (response.compare("C") == 0)){ + cout << "\nIncorrect. This is a Sandy Bridge processor.\nPlease try again..." << endl; + cout << string(2, '\n'); + }else if((response.compare("d") == 0) | (response.compare("D") == 0)){ + cout << "\nIncorrect. This is a Sandy Bridge processor.\nPlease try again..." << endl; + cout << string(2, '\n'); + }else{ + cout << "\nYou have entered an invalid response, please try again..." << endl; + cout << string(2, '\n'); + } + break; + default: + cerr << "You should never see this. There has been an enum error." << endl; + } + } + return 0; +} \ No newline at end of file diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 3/a.exe b/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 3/a.exe new file mode 100644 index 0000000..4654e70 Binary files /dev/null and b/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 3/a.exe differ diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 4/CppAssign1.cpp b/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 4/CppAssign1.cpp new file mode 100644 index 0000000..c727a55 --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 4/CppAssign1.cpp @@ -0,0 +1,13 @@ +#include +#include +#include +#include "rps.h" +using namespace std; + +int main() +{ + Rps game; + + game.newgame(); + return 0; +} \ No newline at end of file diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 4/a.exe b/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 4/a.exe new file mode 100644 index 0000000..efc90ac Binary files /dev/null and b/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 4/a.exe differ diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 4/player.h b/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 4/player.h new file mode 100644 index 0000000..d137823 --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 4/player.h @@ -0,0 +1,60 @@ +#include +#include +#include +using namespace std; + + +class Player{ +public: + friend class Rps; + + Player(){ + srand ( time(NULL) ); + wins(0); + losses(0); + } + + Player + + string guess(){ + int number; + + number = ((int)(rand() * 10))%3; + if (number == 0){ + return "Rock"; + } + else if (number == 1){ + return "Paper"; + } + else if (number == 2){ + return "Scissors"; + } + else { + return "Dynamite"; + } + } + + string userguess(){ + +/*Extra Challenge 1: + Get User input for one of the guesses*/ + + } + + string wunderguess(){ + try{ + SimpleSerial wunderboard("COM3", 9600); + string mystr = wunderboard.readLine(); + cout << "Wunderboard says: " << mystr << endl; + }catch(boost::system::system_error& e){ + cout << "Error. << e.what() << endl; + } + +/*Extra Challenge 2: + Add the Players name to the object and it constructor. Add a function to get the name/change it*/ + +private: + int wins; + int losses; + +}; diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 4/rps.h b/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 4/rps.h new file mode 100644 index 0000000..8074208 --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Assignments/Assignment 4/rps.h @@ -0,0 +1,61 @@ +#include +#include +#include +#include "player.h" +using namespace std; + +class Rps{ + +public: + void newgame(){ + /*Extra Challenge 5: + Make this program a 3 player game*/ + + Player player1; + Player player2; + + string player1guess; + string player2guess; + + /*Extra Challenge 3 + Make this program Rock, Paper, Scissors, Lizard, Spock*/ + + /*Extra Challenge 4 + Make this program best 2 out of 3*/ + + cout << "Welcome to RPS (Rock, Paper, Scissors) v1.0" << endl; + cout << "Preparing to run the guess() method on both player objects" << endl; + + /*Extra Challenge 1 + Get User input for one of the guesses*/ + + player1guess = player1.guess(); + player2guess = player2.guess(); + + while (player1guess.compare(player2guess) == 0){ + player1guess = player1.guess(); + player2guess = player2.guess(); + } + + if ((player1guess.compare("Rock") == 0) && (player2guess.compare("Scissors") == 0) ) + cout << "Player 1 smashes the heck out of player 2 with a rock! Die scissors die!" << endl; + if ((player1guess.compare("Scissors") == 0) && (player2guess.compare("Rock") == 0) ) + cout << "Player 2 smashes the heck out of player 1 with a rock! Die scissors die!" << endl; + if ((player1guess.compare("Paper") == 0) && (player2guess.compare("Rock") == 0) ) + cout << "Player 1 smothers player 2 with paper! Die rock die!" << endl; + if ((player1guess.compare("Rock") == 0) && (player2guess.compare("Paper") == 0) ) + cout << "Player 2 smothers player 1 with paper! Die rock die!" << endl; + if ((player1guess.compare("Scissors") == 0) && (player2guess.compare("Paper") == 0) ) + cout << "Player 1 slices and dices player 2 with scissors! Die paper die!" << endl; + if ((player1guess.compare("Paper") == 0) && (player2guess.compare("Scissors") == 0) ) + cout << "Player 2 slices and dices player 1 with scissors! Die paper die!" << endl; + + /*Extra Challenge 6 + Actually declare a winner*/ + } + + /*Extra Challenge 7 + Keep track of number of wins and number of losses for each object of this class*/ +}; + + diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Final/PC Application/Makefile b/OSU Coursework/CS 162 - Intro to Programming II/Final/PC Application/Makefile new file mode 100644 index 0000000..5afa166 --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Final/PC Application/Makefile @@ -0,0 +1,30 @@ +# Detect platform +UNAME = $(shell uname) + +ifeq ($(UNAME),Linux) +ENV=unix +endif + +ifeq ($(UNAME),Darwin) +ENV=unix +endif + +ifndef ENV +ENV=windows +endif + +ifeq ($(ENV),unix) +CC = g++ +BOOSTFLAGS = -lboost_system +else +CC = g++ +BOOSTFLAGS = -lboost_system -lws2_32 -D _WIN32_WINNT=0x0501 +endif + +all: + $(CC) lab5.cpp -Wall $(BOOSTFLAGS) + +clean: + rm -f *.exe + rm -f *.o + \ No newline at end of file diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Final/PC Application/SimpleSerial.h b/OSU Coursework/CS 162 - Intro to Programming II/Final/PC Application/SimpleSerial.h new file mode 100644 index 0000000..57dda50 --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Final/PC Application/SimpleSerial.h @@ -0,0 +1,66 @@ +#include + +/** This code requires 'boost' to be successfully installed and when compiled will require the boost libaries to be included. +The original code source as of this writting was found here: + +http://www.webalice.it/fede.tft/serial_port/serial_port.html + +*/ + +class SimpleSerial +{ +public: + /** + * Constructor. + * \param port device name, example "/dev/ttyUSB0" or "COM4" + * \param baud_rate communication speed, example 9600 or 115200 + * \throws boost::system::system_error if cannot open the + * serial device + */ + SimpleSerial(std::string port, unsigned int baud_rate) + : io(), serial(io,port) + { + serial.set_option(boost::asio::serial_port_base::baud_rate(baud_rate)); + } + + /** + * Write a string to the serial device. + * \param s string to write + * \throws boost::system::system_error on failure + */ + void writeString(std::string s) + { + boost::asio::write(serial,boost::asio::buffer(s.c_str(),s.size())); + } + + /** + * Blocks until a line is received from the serial device. A line is denoted by a final '\n' character + * Eventual '\n' or '\r\n' characters at the end of the string are removed. + * \return a string containing the received line + * \throws boost::system::system_error on failure + */ + std::string readLine() + { + //Reading data char by char, code is optimized for simplicity, not speed + using namespace boost; + char c; + std::string result; + for(;;) + { + asio::read(serial,asio::buffer(&c,1)); + switch(c) + { + case '\r': + break; + case '\n': + return result; + default: + result+=c; + } + } + } + +private: + boost::asio::io_service io; + boost::asio::serial_port serial; +}; \ No newline at end of file diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Final/PC Application/a.exe b/OSU Coursework/CS 162 - Intro to Programming II/Final/PC Application/a.exe new file mode 100644 index 0000000..3ccf7f0 Binary files /dev/null and b/OSU Coursework/CS 162 - Intro to Programming II/Final/PC Application/a.exe differ diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Final/PC Application/conio.h b/OSU Coursework/CS 162 - Intro to Programming II/Final/PC Application/conio.h new file mode 100644 index 0000000..8a821cb --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Final/PC Application/conio.h @@ -0,0 +1,53 @@ +/* + * conio.h + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Low level console I/O functions. Pretty please try to use the ANSI + * standard ones if you are writing new code. + * + */ + +#ifndef _CONIO_H_ +#define _CONIO_H_ + +/* All the headers include this file. */ +#include <_mingw.h> + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +_CRTIMP char* __cdecl __MINGW_NOTHROW _cgets (char*); +_CRTIMP int __cdecl __MINGW_NOTHROW _cprintf (const char*, ...); +_CRTIMP int __cdecl __MINGW_NOTHROW _cputs (const char*); +_CRTIMP int __cdecl __MINGW_NOTHROW _cscanf (char*, ...); + +_CRTIMP int __cdecl __MINGW_NOTHROW _getch (void); +_CRTIMP int __cdecl __MINGW_NOTHROW _getche (void); +_CRTIMP int __cdecl __MINGW_NOTHROW _kbhit (void); +_CRTIMP int __cdecl __MINGW_NOTHROW _putch (int); +_CRTIMP int __cdecl __MINGW_NOTHROW _ungetch (int); + + +#ifndef _NO_OLDNAMES + +_CRTIMP int __cdecl __MINGW_NOTHROW getch (void); +_CRTIMP int __cdecl __MINGW_NOTHROW getche (void); +_CRTIMP int __cdecl __MINGW_NOTHROW kbhit (void); +_CRTIMP int __cdecl __MINGW_NOTHROW putch (int); +_CRTIMP int __cdecl __MINGW_NOTHROW ungetch (int); + +#endif /* Not _NO_OLDNAMES */ + + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _CONIO_H_ */ diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Final/PC Application/lab5.cpp b/OSU Coursework/CS 162 - Intro to Programming II/Final/PC Application/lab5.cpp new file mode 100644 index 0000000..7143597 --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Final/PC Application/lab5.cpp @@ -0,0 +1,35 @@ +// g++ serial.c++ -lboost_system -lws2_32 -D _WIN32_WINNT=0x0501 + +#include +#include "SimpleSerial.h" +#include "conio.h" + +using namespace std; +using namespace boost; + +int main(int argc, char* argv[]) +{ + + string inputstr; + cout << "Lab 5 Code Started" << endl; + SimpleSerial wunderboard("COM5", 9600); + + while(1){ + try { + cout << wunderboard.readLine() << endl; + if(kbhit()){ + cin >> inputstr; + wunderboard.writeString(inputstr); + if((inputstr.compare("Exit") == 0) | (inputstr.compare("EXIT") == 0) | (inputstr.compare("exit") == 0)){ + return 0; + } + } + + + } catch(boost::system::system_error& e) + { + cout<<"Error: "</dev/null; echo; fi + +sizeafter: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +# Display compiler version information. +gccversion : + @$(CC) --version + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -R .signature $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0 + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S -z $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + $(NM) -n $< > $@ + + +# Create library from object files. +.SECONDARY : $(TARGET).a +.PRECIOUS : $(OBJ) +%.a: $(OBJ) + @echo + @echo $(MSG_CREATING_LIBRARY) $@ + $(AR) $@ $(OBJ) + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS) + +# Compile: create object files from C source files. +$(OBJDIR)/%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + +## Program +.PHONY: program +program: all + $(PROGRAM) $(PROGRAMFLAGS) $(ERASE) + $(PROGRAM) $(PROGRAMFLAGS) $(FLASH) + $(PROGRAM) $(PROGRAMFLAGS) $(START) + +doxygen: + doxygen + +# Target: clean project. +clean: begin clean_list end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lss + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o) + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + $(REMOVEDIR) .dep + $(REMOVEDIR) $(OBJDIR) + +# Create object files directory +$(shell mkdir $(OBJDIR) 2>/dev/null) + +# Include the dependency files. +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion \ +build elf hex eep lss sym \ +clean clean_list diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Final/Wunderboard Firmware/main.c b/OSU Coursework/CS 162 - Intro to Programming II/Final/Wunderboard Firmware/main.c new file mode 100644 index 0000000..ed46a68 --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Final/Wunderboard Firmware/main.c @@ -0,0 +1,289 @@ +/** +@file main.` +@brief Lab 3 Starter Code +@version .01 +@mainpage Lab 3 Starter Code + +@section intro Code Overview + +@section hw Hardware Pin Out +Port A: +A0 - A3 : Push Buttons +A4 - A7 : Slide Switches + +Port B: +B0 - B3 : SPI (SD Card) +B4 : Nothing +B5 : Audio Out +B6 : Red Enable +B7 : Green Enable + +Port C: +C0 - C7 : LED Array (Row) + +Port D: +D0 - D1 : Nothing +D2 : Serial RX +D3 : Serial TX +D4 - D7 : Nothing + +Port E: +E0 - E2 : LED Array (Column) +E3 : USB (UID) +E4 - E5 : Nothing +E6 : Relay +E7 : Nothing + +Port F: +F0 : ADC Channel 0 +F1 : ADC Channel 1 +F2 : ADC Channel 2 +F3 : ADC Channel 3 +F4 : ADC Channel 4 (Audio In) +F5 : ADC Channel 5 (Accel X Axis) +F6 : ADC Channel 6 (Accel Y Axis) +F7 : ADC Channel 7 (Accel Z Axis (if installed)) + +*/ + +/** Includes */ +#include +#include +#include + + +/** Constants */ +#define F_CPU 1000000UL +#define DEBUG 1 +#ifdef DEBUG == 1 + #define SENDSPEED 3 //If less than .12, there are problems +#endif + +/** Global Variables */ +volatile unsigned char loop = 0; +volatile unsigned char throwaway = 0; +volatile unsigned char loopdir = 0; +/** Functions */ + +/** Prototypes **/ +unsigned char InitializeUART(void); +unsigned char SendByteUART (unsigned char data); +unsigned char SendStringUART (unsigned char *data); +void initialize(void); +void clearArray(void); +unsigned char initializeTIMER0(void); +unsigned char setTIMER0(unsigned char clock, unsigned char count); +ISR(TIMER0_COMPA_vect); +unsigned char myitoa(unsigned char received, unsigned char *send); + + + +#ifdef DEBUG == 1 + /** This function needs to setup the variables used by the UART to enable the UART and tramsmit at 9600bps. This + function should always return 0. Remember, by defualt the Wunderboard runs at 1mHz for its system clock.*/ + unsigned char InitializeUART (void){ + unsigned char baud = ((F_CPU/(9600*8UL))-1); + + /* Set baud rate */ + UBRR1H = (baud >> 8); + UBRR1L = baud; + /* Set the U2X1 bit */ + UCSR1A = (1 << U2X1); + /* Enable transmitter */ + UCSR1B = ((1 << TXEN1) | (1 << RXEN1)); + /* Set frame format: 8data, 1stop bit */ + UCSR1C = (3 << UCSZ10); + + return 0; + } + + /** This function needs to write a single byte to the UART. It must check that the UART is ready for a new byte + and return a 1 if the byte was not sent. + @param [in] data This is the data byte to be sent. + @return The function returns a 1 or error and 0 on successful completion.*/ + + unsigned char SendByteUART (unsigned char data){ + + /* + ** Checks the buffer empty bit so that data can either be placed in the buffer + ** or else reuturn a 1 + */ + if((UCSR1A & (1 << UDRE1)) == (1 << UDRE1)){ + UDR1 = data; //Places data into the UDR1 8-bit data buffer + }else { + return 1; + } + + return 0; + } + + /** This function needs to writes a string to the UART. It must check that the UART is ready for a new byte and + return a 1 if the string was not sent. + @param [in] data This is a pointer to the data to be sent. + @return The function returns a 1 or error and 0 on successful completion.*/ + + unsigned char SendStringUART (unsigned char *data){ + + for (int loop = 0 ; data[loop] != '\0'; loop++){ + + /* Sends the current byte based on the loop umber to SendByte */ + while(SendByteUART(data[loop])); + } + return 0; + } + + unsigned char GetByteUART(){ + if (UCSR1A & (1 << RXC1)){ + return(UDR1); + } else{ + return(-1); + } + } +#endif + +/** The initialize() function initializes all of the Data Direction Registers for the Wunderboard. Before making changes to DDRx registers, ensure that you have read the peripherals section of the Wunderboard user guide.*/ +void initialize(void){ + /** Port A is the switches and buttons. They should always be inputs. ( 0 = Input and 1 = Output )*/ + DDRA=0b00000000; + + /** Port B has the LED Array color control, SD card, and audio-out on it. Leave DDRB alone. ( 0 = Input and 1 = Output )*/ + DDRB=0b11000111; + + /** Port C is for the 'row' of the LED array. They should always be outputs. ( 0 = Input and 1 = Output )*/ + DDRC=0b11111111; + + /** Port D has the Serial on it. Leave DDRB alone. ( 0 = Input and 1 = Output )*/ + DDRD=0b00001000; + + /** Port E has the LED Array Column control out on it. Leave DDRE alone. ( 0 = Input and 1 = Output )*/ + DDRE=0b00000111; + + /** Port F has the accelerometer and audio-in on it. Leave DDRF alone. ( 0 = Input and 1 = Output )*/ + DDRF=0b00000000; +} + +void clearArray(void){ + PORTC = 0x00; + PORTB |= (1 << PB6) | (1 << PB7); /** Enable latches*/ + PORTB &= ~((1 << PB6) | (1 << PB7)); /** Disable latches*/ +} + +/** This function needs to setup the variables used by TIMER0 Compare Match (CTC) mode with +a base clock frequency of clk/1024. This function should return a 1 if it fails and a 0 if it +does not. Remember, by default the Wunderboard runs at 1mHz for its system clock. +@return This function returns a 1 is unsuccessful, else return 0.*/ +unsigned char initializeTIMER0(void){ + /* Set the CTC mode */ + TCCR0A = (1 << WGM01); + + /* Set the Clock Frequency */ + TCCR0B = ((1 << CS02) | (1 << CS00)); + + /* Set initial count value */ + OCR0A = 0; + + return 0; +} + +/** This function takes two values, clock and count. The value of count should be copied into OCR0A and the value of clock should be used to set CS02:0. The TCNT0 variable should also be reset to 0 so that the new timer rate starts from 0. +@param [in] clock Insert Comment +@param [in] count Insert Comment +@return The function returns a 1 or error and 0 on successful completion.*/ +unsigned char setTIMER0(unsigned char clock, unsigned char count){ + + if(clock > 7){ + return 1; + } + TCCR0B &= 0b11111000; //Zeros out last three bits + TCCR0B |= clock; + OCR0A = count; + TIMSK0 = 2; + TCNT0 = 0; + return 0; +} + +ISR(TIMER0_COMPA_vect){ + if(throwaway == 1){ + volatile unsigned char send[4]; + + myitoa(loop, &send); + SendStringUART(send); + SendStringUART("\n"); + throwaway = 0; + + if(loop == 50){ + loopdir = 1; + }else if(loop == 0){ + loopdir = 0; + } + + if(loopdir == 0){ + loop++; + }else{ + loop--; + } + }else{ + throwaway++; + } +} + +unsigned char myitoa(unsigned char received, unsigned char *send){ + unsigned char tmp; + + if(received > 99){ + + tmp = (received / 100); + send[0] = (tmp+48); + tmp = ((received % 100)/10); + send[1] = (tmp+48); + tmp = ((received % 100) % 10); + send[2] = (tmp+48); + send[3] = '\0'; + return 0; + + }else if(received > 9){ + + tmp = ((received % 100)/10); + send[0] = (tmp+48); + tmp = ((received % 100) % 10); + send[1] = (tmp+48); + send[2] = '\0'; + return 0; + + }else if(received < 10){ + tmp = ((received % 100) % 10); + send[0] = (tmp+48); + send[1] = '\0'; + return 0; + } +} + +/** Main Function */ +int main (void){ + + enum states{ + setup, + running + } state = setup; + + while(1){ + + switch(state){ + case setup: + + initialize(); + initializeTIMER0(); + InitializeUART(); + setTIMER0(5,120); + clearArray(); + sei(); + state = running; + SendStringUART("Initialized...\n"); + break; + + case running: + + break; + } + } +} \ No newline at end of file diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 2/Makefile b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 2/Makefile new file mode 100644 index 0000000..6c38e27 --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 2/Makefile @@ -0,0 +1,335 @@ +#---------------------------------------------------------------------------- +# Wunderboard Makefile Template written by Dan Albert +#---------------------------------------------------------------------------- +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make filename.s = Just compile filename.c into the assembler code only. +# +# To rebuild project do "make clean" then "make all". +#---------------------------------------------------------------------------- + +# Target file name. +TARGET = main + +# List C source files here. +SRC = $(TARGET).c \ + +# MCU name, you MUST set this to match the board you are using +# type "make clean" after changing this, so all files will be rebuilt +MCU = at90usb646 + +# Detect platform +UNAME = $(shell uname) + +ifeq ($(UNAME),Linux) +ENV=unix +endif + +ifeq ($(UNAME),Darwin) +ENV=unix +endif + +ifndef ENV +ENV=windows +endif + +ifeq ($(ENV),unix) +PROGRAM = dfu-programmer +PROGRAMFLAGS = $(MCU) +ERASE = erase +FLASH = flash "$(TARGET).hex" +START = start +else +PROGRAM = "C:/Program Files (x86)/Atmel/Flip 3.4.1/bin/batchisp.exe" +PROGRAMFLAGS = -device at90usb646 -hardware USB +ERASE = -operation erase F +FLASH = -operation loadbuffer "$(TARGET).hex" program verify +START = -operation start noreset 0 +endif + +# Processor frequency. +# Normally the first thing your program should do is set the clock prescaler, +# so your program will run at the correct speed. You should also set this +# variable to same clock speed. The _delay_ms() macro uses this, and many +# examples use this variable to calculate timings. Do not add a "UL" here. +F_CPU = 8000000 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Object files directory +# To put object files in current directory, use a dot (.), do NOT make +# this an empty or blank macro! +OBJDIR = obj + +# 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.) +OPT = s + +# 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 for C sources +CDEFS = -DF_CPU=$(F_CPU)UL + +#---------------- Compiler Options C ---------------- +# -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 += $(CDEFS) +CFLAGS += -O$(OPT) +CFLAGS += -funsigned-char +CFLAGS += -funsigned-bitfields +CFLAGS += -ffunction-sections +CFLAGS += -fpack-struct +CFLAGS += -fshort-enums +CFLAGS += -Wall +CFLAGS += -Wstrict-prototypes +#CFLAGS += -mshort-calls +#CFLAGS += -fno-unit-at-a-time +#CFLAGS += -Wundef +#CFLAGS += -Wunreachable-code +#CFLAGS += -Wsign-compare +CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +CFLAGS += $(CSTANDARD) + +#---------------- 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 + +# List any extra directories to look for libraries 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. +EXTRALIBDIRS = + +#---------------- 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 += -Wl,--relax +LDFLAGS += -Wl,--gc-sections +LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS)) +LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) +#LDFLAGS += -T linker_script.x + + +#============================================================================ + +# Define programs and commands. +SHELL = sh +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +AR = avr-ar rcs +NM = avr-nm +REMOVE = rm -f +REMOVEDIR = rm -rf +COPY = cp +WINSHELL = cmd + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling C: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: +MSG_CREATING_LIBRARY = Creating library: + +# Define all object files. +OBJ = $(SRC:%.c=$(OBJDIR)/%.o) + +# Define all listing files. +LST = $(SRC:%.c=$(OBJDIR)/%.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) + +# Default target. +all: begin gccversion sizebefore build sizeafter end + +# Change the build target to build a HEX file or a library. +build: elf hex eep lss sym +#build: lib + +elf: $(TARGET).elf +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym +LIBNAME=lib$(TARGET).a +lib: $(LIBNAME) + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +end: + @echo $(MSG_END) + @echo + +# Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf + +sizebefore: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +sizeafter: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +# Display compiler version information. +gccversion : + @$(CC) --version + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -R .signature $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0 + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S -z $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + $(NM) -n $< > $@ + + +# Create library from object files. +.SECONDARY : $(TARGET).a +.PRECIOUS : $(OBJ) +%.a: $(OBJ) + @echo + @echo $(MSG_CREATING_LIBRARY) $@ + $(AR) $@ $(OBJ) + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS) + +# Compile: create object files from C source files. +$(OBJDIR)/%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + +## Program +.PHONY: program +program: all + $(PROGRAM) $(PROGRAMFLAGS) $(ERASE) + $(PROGRAM) $(PROGRAMFLAGS) $(FLASH) + $(PROGRAM) $(PROGRAMFLAGS) $(START) + +doxygen: + doxygen + +# Target: clean project. +clean: begin clean_list end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lss + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o) + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + $(REMOVEDIR) .dep + $(REMOVEDIR) $(OBJDIR) + +# Create object files directory +$(shell mkdir $(OBJDIR) 2>/dev/null) + +# Include the dependency files. +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion \ +build elf hex eep lss sym \ +clean clean_list diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 2/main.c b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 2/main.c new file mode 100644 index 0000000..b8277a2 --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 2/main.c @@ -0,0 +1,192 @@ +/** +@file main.c +@brief Lab 2 Starter Code +@version .01 +@mainpage Lab 2 Starter Code + +@section intro Code Overview + +@section hw Hardware Pin Out +Port A: +A0 - A3 : Push Buttons +A4 - A7 : Slide Switches + +Port B: +B0 - B3 : SPI (SD Card) +B4 : Nothing +B5 : Audio Out +B6 : Red Enable +B7 : Green Enable + +Port C: +C0 - C7 : LED Array (Row) + +Port D: +D0 - D1 : Nothing +D2 : Serial RX +D3 : Serial TX +D4 - D7 : Nothing + +Port E: +E0 - E2 : LED Array (Column) +E3 : USB (UID) +E4 - E5 : Nothing +E6 : Relay +E7 : Nothing + +Port F: +F0 : ADC Channel 0 +F1 : ADC Channel 1 +F2 : ADC Channel 2 +F3 : ADC Channel 3 +F4 : ADC Channel 4 (Audio In) +F5 : ADC Channel 5 (Accel X Axis) +F6 : ADC Channel 6 (Accel Y Axis) +F7 : ADC Channel 7 (Accel Z Axis (if installed)) + +*/ + +/** Includes */ +#include +#include + +/** Constants */ +#define DEBUG //Comment or uncomment this to enable/disable debugging +#define F_CPU 1000000U + +/** Sets the string send speed for debugging when defined */ +#ifdef DEBUG + #define SENDSPEED .2 //If less than .2, there are problems +#endif + +/** Global Variables */ + +/** Functions */ + +/** When DEBUG is defined, this provides the functions needed to debug over serial */ +#ifdef DEBUG + /** This function needs to setup the variables used by the UART to enable the UART and tramsmit at 9600bps. This + function should always return 0. Remember, by defualt the Wunderboard runs at 1mHz for its system clock.*/ + unsigned char InitializeUART (){ + unsigned char baud = ((F_CPU/(9600*8UL))-1); + + /* Set baud rate */ + UBRR1H = (baud >> 8); + UBRR1L = baud; + /* Set the U2X1 bit */ + UCSR1A = (1 << U2X1); + /* Enable transmitter */ + UCSR1B = (1 << TXEN1); + /* Set frame format: 8data, 1stop bit */ + UCSR1C = (3 << UCSZ10); + + return 0; + } + + /** This function needs to write a single byte to the UART. It must check that the UART is ready for a new byte + and return a 1 if the byte was not sent. + @param [in] data This is the data byte to be sent. + @return The function returns a 1 or error and 0 on successful completion.*/ + + unsigned char SendByteUART (unsigned char data){ + + /* + ** Checks the buffer empty bit so that data can either be placed in the buffer + ** or else reuturn a 1 + */ + if((UCSR1A & (1 << UDRE1)) == (1 << UDRE1)){ + UDR1 = data; + _delay_ms(SENDSPEED); //Places data into the UDR1 8-bit data buffer + }else { + return 1; + } + + return 0; + } + + /** This function needs to writes a string to the UART. It must check that the UART is ready for a new byte and + return a 1 if the string was not sent. + @param [in] data This is a pointer to the data to be sent. + @return The function returns a 1 or error and 0 on successful completion.*/ + + unsigned char SendStringUART (unsigned char *data){ + + for (int loop = 0 ; data[loop] != '\0'; loop++){ + unsigned char bytereturn; //Storage for return value of SendByteUART + + /* Sends the current byte based on the loop umber to SendByte */ + bytereturn = SendByteUART(data[loop]); + + /* Stops sending if SendByteUART had an error */ + if(bytereturn == 1){ + return 1; + } + } + return 0; + } +#endif + +/** The initialize() function initializes all of the Data Direction Registers for the Wunderboard. Before making changes to DDRx registers, ensure that you have read the peripherals section of the Wunderboard user guide.*/ +void initialize (void) { + /** Port A is the switches and buttons. They should always be inputs. ( 0 = Input and 1 = Output )*/ + DDRA=0b00000000; + + /** Port B has the LED Array color control, SD card, and audio-out on it. Leave DDRB alone. ( 0 = Input and 1 = Output )*/ + DDRB=0b11000000; + + /** Port C is for the 'row' of the LED array. They should always be outputs. ( 0 = Input and 1 = Output )*/ + DDRC=0b11111111; + + /** Port D has the Serial on it. Leave DDRB alone. ( 0 = Input and 1 = Output )*/ + DDRD=0b00001000; + + /** Port E has the LED Array Column control out on it. Leave DDRE alone. ( 0 = Input and 1 = Output )*/ + DDRE=0b00000111; + + /** Port F has the accelerometer and audio-in on it. Leave DDRF alone. ( 0 = Input and 1 = Output )*/ + DDRF=0b00000000; +} + +/** The clearArray() function turns off all LEDS on the Wunderboard array. It accepts no inputs and returns nothing*/ +void clearArray(void) { + PORTC = 0x00; + PORTB |= (1 << PB6) | (1 << PB7); /** Enable latches*/ + PORTB &= ~((1 << PB6) | (1 << PB7)); /** Disable latches*/ +} + +/** Main Function */ + +int main (void) { + /** Local Varibles */ + + initialize(); + clearArray(); + + /** Initializes the serial interface if debugging is enabled */ + #ifdef DEBUG + InitializeUART(); + #endif + + PORTB = 0b10000000; + + while(1){ + unsigned char pinastatus = PINA; + unsigned char debugstring[50]; + + #ifdef DEBUG + sprintf(debugstring, "Port A is: %d.\n", pinastatus); + SendStringUART(debugstring); + #endif + + + + for (unsigned char loop = 0 ; loop < 8 ; loop++){ + PORTB = 0b10000000; + PORTE = loop; + PORTC = pinastatus; + _delay_ms(.07); + clearArray(); + + } + }//while +}//main \ No newline at end of file diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/Makefile b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/Makefile new file mode 100644 index 0000000..495854c --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/Makefile @@ -0,0 +1,337 @@ +#---------------------------------------------------------------------------- +# Wunderboard Makefile Template written by Dan Albert +#---------------------------------------------------------------------------- +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make filename.s = Just compile filename.c into the assembler code only. +# +# To rebuild project do "make clean" then "make all". +#---------------------------------------------------------------------------- + +# Target file name. +TARGET = main + +# List C source files here. +SRC = $(TARGET).c \ + ff.c \ + diskio.c \ + +# MCU name, you MUST set this to match the board you are using +# type "make clean" after changing this, so all files will be rebuilt +MCU = at90usb646 + +# Detect platform +UNAME = $(shell uname) + +ifeq ($(UNAME),Linux) +ENV=unix +endif + +ifeq ($(UNAME),Darwin) +ENV=unix +endif + +ifndef ENV +ENV=windows +endif + +ifeq ($(ENV),unix) +PROGRAM = dfu-programmer +PROGRAMFLAGS = $(MCU) +ERASE = erase +FLASH = flash "$(TARGET).hex" +START = start +else +PROGRAM = "batchisp.exe" +PROGRAMFLAGS = -device at90usb646 -hardware USB +ERASE = -operation erase F +FLASH = -operation loadbuffer "$(TARGET).hex" program verify +START = -operation start noreset 0 +endif + +# Processor frequency. +# Normally the first thing your program should do is set the clock prescaler, +# so your program will run at the correct speed. You should also set this +# variable to same clock speed. The _delay_ms() macro uses this, and many +# examples use this variable to calculate timings. Do not add a "UL" here. +F_CPU = 1000000 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Object files directory +# To put object files in current directory, use a dot (.), do NOT make +# this an empty or blank macro! +OBJDIR = obj + +# 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.) +OPT = s + +# 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 for C sources +CDEFS = -DF_CPU=$(F_CPU)UL + +#---------------- Compiler Options C ---------------- +# -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 += $(CDEFS) +CFLAGS += -O$(OPT) +CFLAGS += -funsigned-char +CFLAGS += -funsigned-bitfields +CFLAGS += -ffunction-sections +CFLAGS += -fpack-struct +CFLAGS += -fshort-enums +CFLAGS += -Wall +CFLAGS += -Wstrict-prototypes +#CFLAGS += -mshort-calls +#CFLAGS += -fno-unit-at-a-time +#CFLAGS += -Wundef +#CFLAGS += -Wunreachable-code +#CFLAGS += -Wsign-compare +CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +CFLAGS += $(CSTANDARD) + +#---------------- 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 + +# List any extra directories to look for libraries 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. +EXTRALIBDIRS = + +#---------------- 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 += -Wl,--relax +LDFLAGS += -Wl,--gc-sections +LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS)) +LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) +#LDFLAGS += -T linker_script.x + + +#============================================================================ + +# Define programs and commands. +SHELL = sh +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +AR = avr-ar rcs +NM = avr-nm +REMOVE = rm -f +REMOVEDIR = rm -rf +COPY = cp +WINSHELL = cmd + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling C: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: +MSG_CREATING_LIBRARY = Creating library: + +# Define all object files. +OBJ = $(SRC:%.c=$(OBJDIR)/%.o) + +# Define all listing files. +LST = $(SRC:%.c=$(OBJDIR)/%.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) + +# Default target. +all: begin gccversion sizebefore build sizeafter end + +# Change the build target to build a HEX file or a library. +build: elf hex eep lss sym +#build: lib + +elf: $(TARGET).elf +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym +LIBNAME=lib$(TARGET).a +lib: $(LIBNAME) + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +end: + @echo $(MSG_END) + @echo + +# Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf + +sizebefore: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +sizeafter: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +# Display compiler version information. +gccversion : + @$(CC) --version + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -R .signature $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0 + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S -z $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + $(NM) -n $< > $@ + + +# Create library from object files. +.SECONDARY : $(TARGET).a +.PRECIOUS : $(OBJ) +%.a: $(OBJ) + @echo + @echo $(MSG_CREATING_LIBRARY) $@ + $(AR) $@ $(OBJ) + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS) + +# Compile: create object files from C source files. +$(OBJDIR)/%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + +## Program +.PHONY: program +program: all + $(PROGRAM) $(PROGRAMFLAGS) $(ERASE) + $(PROGRAM) $(PROGRAMFLAGS) $(FLASH) + $(PROGRAM) $(PROGRAMFLAGS) $(START) + +doxygen: + doxygen + +# Target: clean project. +clean: begin clean_list end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lss + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o) + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + $(REMOVEDIR) .dep + $(REMOVEDIR) $(OBJDIR) + +# Create object files directory +$(shell mkdir $(OBJDIR) 2>/dev/null) + +# Include the dependency files. +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion \ +build elf hex eep lss sym \ +clean clean_list diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/diskio.c b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/diskio.c new file mode 100644 index 0000000..b2f7202 --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/diskio.c @@ -0,0 +1,623 @@ +/*-----------------------------------------------------------------------*/ +/* MMCv3/SDv1/SDv2 (in SPI mode) control module (C)ChaN, 2007 */ +/*-----------------------------------------------------------------------*/ +/* Only rcvr_spi(), xmit_spi(), disk_timerproc() and some macros */ +/* are platform dependent. */ +/*-----------------------------------------------------------------------*/ + + +#include +#include +#include "diskio.h" + + +/* Definitions for MMC/SDC command */ +#define CMD0 (0) /* GO_IDLE_STATE */ +#define CMD1 (1) /* SEND_OP_COND (MMC) */ +#define ACMD41 (0x80+41) /* SEND_OP_COND (SDC) */ +#define CMD8 (8) /* SEND_IF_COND */ +#define CMD9 (9) /* SEND_CSD */ +#define CMD10 (10) /* SEND_CID */ +#define CMD12 (12) /* STOP_TRANSMISSION */ +#define ACMD13 (0x80+13) /* SD_STATUS (SDC) */ +#define CMD16 (16) /* SET_BLOCKLEN */ +#define CMD17 (17) /* READ_SINGLE_BLOCK */ +#define CMD18 (18) /* READ_MULTIPLE_BLOCK */ +#define CMD23 (23) /* SET_BLOCK_COUNT (MMC) */ +#define ACMD23 (0x80+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */ +#define CMD24 (24) /* WRITE_BLOCK */ +#define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */ +#define CMD55 (55) /* APP_CMD */ +#define CMD58 (58) /* READ_OCR */ + + +/* Port Controls (Platform dependent) */ +#define CS_LOW() PORTB &= ~1 /* MMC CS = L */ +#define CS_HIGH() PORTB |= 1 /* MMC CS = H */ + +#define SOCKPORT PINB /* Socket contact port */ +#define SOCKWP 0x20 /* Write protect switch (PB5) */ +#define SOCKINS 0x10 /* Card detect switch (PB4) */ + +#define FCLK_SLOW() SPCR = 0x52 /* Set slow clock (100k-400k) */ +#define FCLK_FAST() SPCR = 0x50 /* Set fast clock (depends on the CSD) */ + + +/*-------------------------------------------------------------------------- + + Module Private Functions + +---------------------------------------------------------------------------*/ + +static volatile +DSTATUS Stat = STA_NOINIT; /* Disk status */ + +static volatile +BYTE Timer1, Timer2; /* 100Hz decrement timer */ + +static +BYTE CardType; /* Card type flags */ + + +/*-----------------------------------------------------------------------*/ +/* Transmit a byte to MMC via SPI (Platform dependent) */ +/*-----------------------------------------------------------------------*/ + +#define xmit_spi(dat) cli(); SPDR=(dat); loop_until_bit_is_set(SPSR,SPIF); sei() + + + +/*-----------------------------------------------------------------------*/ +/* Receive a byte from MMC via SPI (Platform dependent) */ +/*-----------------------------------------------------------------------*/ + +static +BYTE rcvr_spi (void) +{ + cli(); + SPDR = 0xFF; + loop_until_bit_is_set(SPSR, SPIF); + sei(); + return SPDR; +} + +/* Alternative macro to receive data fast */ +#define rcvr_spi_m(dst) SPDR=0xFF; loop_until_bit_is_set(SPSR,SPIF); *(dst)=SPDR + + + +/*-----------------------------------------------------------------------*/ +/* Wait for card ready */ +/*-----------------------------------------------------------------------*/ + +static +int wait_ready (void) /* 1:OK, 0:Timeout */ +{ + Timer2 = 50; /* Wait for ready in timeout of 500ms */ + rcvr_spi(); + do + if (rcvr_spi() == 0xFF) return 1; + while (Timer2); + + return 0; +} + + + +/*-----------------------------------------------------------------------*/ +/* Deselect the card and release SPI bus */ +/*-----------------------------------------------------------------------*/ + +static +void deselect (void) +{ + CS_HIGH(); + rcvr_spi(); +} + + + +/*-----------------------------------------------------------------------*/ +/* Select the card and wait for ready */ +/*-----------------------------------------------------------------------*/ + +static +int select (void) /* 1:Successful, 0:Timeout */ +{ + CS_LOW(); + if (!wait_ready()) { + deselect(); + return 0; + } + return 1; +} + + + +/*-----------------------------------------------------------------------*/ +/* Power Control (Platform dependent) */ +/*-----------------------------------------------------------------------*/ +/* When the target system does not support socket power control, there */ +/* is nothing to do in these functions and chk_power always returns 1. */ + +/* +static +void power_on (void) +{ + PORTE &= ~0x80; // Socket power ON * + for (Timer1 = 3; Timer1; ); // Wait for 30ms * + PORTB = 0b10110101; //Enable drivers * + DDRB = 0b11000111; + SPCR = 0x52; // Enable SPI function in mode 0 * + SPSR = 0x01; // 2x mode * +} + + +static +void power_off (void) +{ + select(); // Wait for card ready * + deselect(); + SPCR = 0; // Disable SPI function * + DDRB = 0b11000000; // Disable drivers * + PORTB = 0b10110000; + PORTE |= 0x80; // Socket power OFF * + Stat |= STA_NOINIT; // Set STA_NOINIT * +} +*/ + +static +int chk_power(void) /* Socket power state: 0=off, 1=on */ +{ + return 1; +} + + + +/*-----------------------------------------------------------------------*/ +/* Receive a data packet from MMC */ +/*-----------------------------------------------------------------------*/ + +static +int rcvr_datablock ( + BYTE *buff, /* Data buffer to store received data */ + UINT btr /* Byte count (must be multiple of 4) */ +) +{ + BYTE token; + + + Timer1 = 20; + do { /* Wait for data packet in timeout of 200ms */ + token = rcvr_spi(); + } while ((token == 0xFF) && Timer1); + if(token != 0xFE) return 0; /* If not valid data token, retutn with error */ + + do { /* Receive the data block into buffer */ + rcvr_spi_m(buff++); + rcvr_spi_m(buff++); + rcvr_spi_m(buff++); + rcvr_spi_m(buff++); + } while (btr -= 4); + rcvr_spi(); /* Discard CRC */ + rcvr_spi(); + + return 1; /* Return with success */ +} + + + +/*-----------------------------------------------------------------------*/ +/* Send a data packet to MMC */ +/*-----------------------------------------------------------------------*/ + +#if _READONLY == 0 +static +int xmit_datablock ( + const BYTE *buff, /* 512 byte data block to be transmitted */ + BYTE token /* Data/Stop token */ +) +{ + BYTE resp, wc; + + + if (!wait_ready()) return 0; + + xmit_spi(token); /* Xmit data token */ + if (token != 0xFD) { /* Is data token */ + wc = 0; + do { /* Xmit the 512 byte data block to MMC */ + xmit_spi(*buff++); + xmit_spi(*buff++); + } while (--wc); + xmit_spi(0xFF); /* CRC (Dummy) */ + xmit_spi(0xFF); + resp = rcvr_spi(); /* Reveive data response */ + if ((resp & 0x1F) != 0x05) /* If not accepted, return with error */ + return 0; + } + + return 1; +} +#endif /* _READONLY */ + + + +/*-----------------------------------------------------------------------*/ +/* Send a command packet to MMC */ +/*-----------------------------------------------------------------------*/ + +static +BYTE send_cmd ( /* Returns R1 resp (bit7==1:Send failed) */ + BYTE cmd, /* Command index */ + DWORD arg /* Argument */ +) +{ + BYTE n, res; + + + if (cmd & 0x80) { /* ACMD is the command sequense of CMD55-CMD */ + cmd &= 0x7F; + res = send_cmd(CMD55, 0); + if (res > 1) return res; + } + + /* Select the card and wait for ready */ + deselect(); + if (!select()) return 0xFF; + + /* Send command packet */ + xmit_spi(0x40 | cmd); /* Start + Command index */ + xmit_spi((BYTE)(arg >> 24)); /* Argument[31..24] */ + xmit_spi((BYTE)(arg >> 16)); /* Argument[23..16] */ + xmit_spi((BYTE)(arg >> 8)); /* Argument[15..8] */ + xmit_spi((BYTE)arg); /* Argument[7..0] */ + n = 0x01; /* Dummy CRC + Stop */ + if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */ + if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */ + xmit_spi(n); + + /* Receive command response */ + if (cmd == CMD12) rcvr_spi(); /* Skip a stuff byte when stop reading */ + n = 10; /* Wait for a valid response in timeout of 10 attempts */ + do + res = rcvr_spi(); + while ((res & 0x80) && --n); + + return res; /* Return with the response value */ +} + + + +/*-------------------------------------------------------------------------- + + Public Functions + +---------------------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------------*/ +/* Initialize Disk Drive */ +/*-----------------------------------------------------------------------*/ + +DSTATUS disk_initialize (BYTE drv) /* Physical drive nmuber (0) */ +{ + BYTE n, cmd, ty, ocr[4]; + + if (drv) return STA_NOINIT; /* Supports only single drive */ + if (Stat & STA_NODISK) return Stat; /* No card in the socket */ + + //power_on(); /* Force socket power on */ + PORTB |= 0b11000000; + FCLK_SLOW(); + for (n = 10; n; n--) rcvr_spi(); /* 80 dummy clocks */ + + ty = 0; + if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */ + Timer1 = 200; /* Initialization timeout of 1000 msec */ + if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2? */ + for (n = 0; n < 4; n++) ocr[n] = rcvr_spi(); /* Get trailing return value of R7 resp */ + if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */ + while (Timer1 && send_cmd(ACMD41, 1UL << 30)); /* Wait for leaving idle state (ACMD41 with HCS bit) */ + if (Timer1 && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */ + for (n = 0; n < 4; n++) ocr[n] = rcvr_spi(); + ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 */ + } + } + } else { /* SDv1 or MMCv3 */ + if (send_cmd(ACMD41, 0) <= 1) { + ty = CT_SD1; cmd = ACMD41; /* SDv1 */ + } else { + ty = CT_MMC; cmd = CMD1; /* MMCv3 */ + } + while (Timer1 && send_cmd(cmd, 0)); /* Wait for leaving idle state */ + if (!Timer1 || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */ + ty = 0; + } + } + + CardType = ty; + deselect(); + + if (ty) { /* Initialization succeded */ + Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */ + FCLK_FAST(); + } else { /* Initialization failed */ + //power_off(); + + } + + return Stat; +} + + + +/*-----------------------------------------------------------------------*/ +/* Get Disk Status */ +/*-----------------------------------------------------------------------*/ + +DSTATUS disk_status ( + BYTE drv /* Physical drive nmuber (0) */ +) +{ + if (drv) return STA_NOINIT; /* Supports only single drive */ + return Stat; +} + + + +/*-----------------------------------------------------------------------*/ +/* Read Sector(s) */ +/*-----------------------------------------------------------------------*/ + +DRESULT disk_read ( + BYTE drv, /* Physical drive nmuber (0) */ + BYTE *buff, /* Pointer to the data buffer to store read data */ + DWORD sector, /* Start sector number (LBA) */ + BYTE count /* Sector count (1..255) */ +) +{ + if (drv || !count) return RES_PARERR; + if (Stat & STA_NOINIT) return RES_NOTRDY; + + if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ + + if (count == 1) { /* Single block read */ + if ((send_cmd(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */ + && rcvr_datablock(buff, 512)) + count = 0; + } + else { /* Multiple block read */ + if (send_cmd(CMD18, sector) == 0) { /* READ_MULTIPLE_BLOCK */ + do { + if (!rcvr_datablock(buff, 512)) break; + buff += 512; + } while (--count); + send_cmd(CMD12, 0); /* STOP_TRANSMISSION */ + } + } + deselect(); + + return count ? RES_ERROR : RES_OK; +} + + + +/*-----------------------------------------------------------------------*/ +/* Write Sector(s) */ +/*-----------------------------------------------------------------------*/ + +#if _READONLY == 0 +DRESULT disk_write ( + BYTE drv, /* Physical drive nmuber (0) */ + const BYTE *buff, /* Pointer to the data to be written */ + DWORD sector, /* Start sector number (LBA) */ + BYTE count /* Sector count (1..255) */ +) +{ + if (drv || !count) return RES_PARERR; + if (Stat & STA_NOINIT) return RES_NOTRDY; + if (Stat & STA_PROTECT) return RES_WRPRT; + + if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ + + if (count == 1) { /* Single block write */ + if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */ + && xmit_datablock(buff, 0xFE)) + count = 0; + } + else { /* Multiple block write */ + if (CardType & CT_SDC) send_cmd(ACMD23, count); + if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */ + do { + if (!xmit_datablock(buff, 0xFC)) break; + buff += 512; + } while (--count); + if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */ + count = 1; + } + } + deselect(); + + return count ? RES_ERROR : RES_OK; +} +#endif /* _READONLY == 0 */ + + + +/*-----------------------------------------------------------------------*/ +/* Miscellaneous Functions */ +/*-----------------------------------------------------------------------*/ + +#if _USE_IOCTL != 0 +DRESULT disk_ioctl ( + BYTE drv, /* Physical drive nmuber (0) */ + BYTE ctrl, /* Control code */ + void *buff /* Buffer to send/receive control data */ +) +{ + DRESULT res; + BYTE n, csd[16], *ptr = buff; + WORD csize; + + + if (drv) return RES_PARERR; + + res = RES_ERROR; + + if (ctrl == CTRL_POWER) { + switch (*ptr) { + case 0: /* Sub control code == 0 (POWER_OFF) */ + if (chk_power()) + //power_off(); // Power off */ + res = RES_OK; + break; + case 1: /* Sub control code == 1 (POWER_ON) */ + //power_on(); // Power on */ + res = RES_OK; + break; + case 2: /* Sub control code == 2 (POWER_GET) */ + *(ptr+1) = (BYTE)chk_power(); + res = RES_OK; + break; + default : + res = RES_PARERR; + } + } + else { + if (Stat & STA_NOINIT) return RES_NOTRDY; + + switch (ctrl) { + case CTRL_SYNC : /* Make sure that no pending write process. Do not remove this or written sector might not left updated. */ + if (select()) { + deselect(); + res = RES_OK; + } + break; + + case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */ + if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { + if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */ + csize = csd[9] + ((WORD)csd[8] << 8) + 1; + *(DWORD*)buff = (DWORD)csize << 10; + } else { /* SDC ver 1.XX or MMC*/ + n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2; + csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1; + *(DWORD*)buff = (DWORD)csize << (n - 9); + } + res = RES_OK; + } + break; + + case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */ + *(WORD*)buff = 512; + res = RES_OK; + break; + + case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */ + if (CardType & CT_SD2) { /* SDv2? */ + if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */ + rcvr_spi(); + if (rcvr_datablock(csd, 16)) { /* Read partial block */ + for (n = 64 - 16; n; n--) rcvr_spi(); /* Purge trailing data */ + *(DWORD*)buff = 16UL << (csd[10] >> 4); + res = RES_OK; + } + } + } else { /* SDv1 or MMCv3 */ + if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { /* Read CSD */ + if (CardType & CT_SD1) { /* SDv1 */ + *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1); + } else { /* MMCv3 */ + *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1); + } + res = RES_OK; + } + } + break; + + case MMC_GET_TYPE : /* Get card type flags (1 byte) */ + *ptr = CardType; + res = RES_OK; + break; + + case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */ + if (send_cmd(CMD9, 0) == 0 /* READ_CSD */ + && rcvr_datablock(ptr, 16)) + res = RES_OK; + break; + + case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */ + if (send_cmd(CMD10, 0) == 0 /* READ_CID */ + && rcvr_datablock(ptr, 16)) + res = RES_OK; + break; + + case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */ + if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */ + for (n = 4; n; n--) *ptr++ = rcvr_spi(); + res = RES_OK; + } + break; + + case MMC_GET_SDSTAT : /* Receive SD statsu as a data block (64 bytes) */ + if (send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */ + rcvr_spi(); + if (rcvr_datablock(ptr, 64)) + res = RES_OK; + } + break; + + default: + res = RES_PARERR; + } + + deselect(); + } + + return res; +} +#endif /* _USE_IOCTL != 0 */ + + +/*-----------------------------------------------------------------------*/ +/* Device Timer Interrupt Procedure (Platform dependent) */ +/*-----------------------------------------------------------------------*/ +/* This function must be called in period of 10ms */ + +void disk_timerproc (void) +{ + static BYTE pv; + BYTE n, s; + + + n = Timer1; /* 100Hz decrement timer */ + if (n) Timer1 = --n; + n = Timer2; + if (n) Timer2 = --n; + + n = pv; + pv = SOCKPORT & (SOCKWP | SOCKINS); /* Sample socket switch */ + + if (n == pv) { /* Have contacts stabled? */ + s = Stat; + + if (pv & SOCKWP) /* WP is H (write protected) */ + s |= STA_PROTECT; + else /* WP is L (write enabled) */ + s &= ~STA_PROTECT; + + if (pv & SOCKINS) /* INS = H (Socket empty) */ + s |= (STA_NODISK | STA_NOINIT); + else /* INS = L (Card inserted) */ + s &= ~STA_NODISK; + + Stat = s; + } +} + +DWORD get_fattime () +{ + return 0; +} + diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/diskio.h b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/diskio.h new file mode 100644 index 0000000..a40cb6c --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/diskio.h @@ -0,0 +1,76 @@ +/*----------------------------------------------------------------------- +/ Low level disk interface modlue include file R0.07 (C)ChaN, 2009 +/-----------------------------------------------------------------------*/ + +#ifndef _DISKIO + +#define _READONLY 0 /* 1: Read-only mode */ +#define _USE_IOCTL 1 + +#include "integer.h" + + +/* Status of Disk Functions */ +typedef BYTE DSTATUS; + +/* Results of Disk Functions */ +typedef enum { + RES_OK = 0, /* 0: Successful */ + RES_ERROR, /* 1: R/W Error */ + RES_WRPRT, /* 2: Write Protected */ + RES_NOTRDY, /* 3: Not Ready */ + RES_PARERR /* 4: Invalid Parameter */ +} DRESULT; + + +/*---------------------------------------*/ +/* Prototypes for disk control functions */ + +DSTATUS disk_initialize (BYTE); +DSTATUS disk_status (BYTE); +DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE); +#if _READONLY == 0 +DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE); +#endif +DRESULT disk_ioctl (BYTE, BYTE, void*); + + + +/* Disk Status Bits (DSTATUS) */ + +#define STA_NOINIT 0x01 /* Drive not initialized */ +#define STA_NODISK 0x02 /* No medium in the drive */ +#define STA_PROTECT 0x04 /* Write protected */ + +/* Card type flags (CardType) */ + +#define CT_MMC 0x01 +#define CT_SD1 0x02 +#define CT_SD2 0x04 +#define CT_SDC (CT_SD1|CT_SD2) +#define CT_BLOCK 0x08 + +/* Command code for disk_ioctrl() */ + +/* Generic command */ +#define CTRL_SYNC 0 /* Mandatory for write functions */ +#define GET_SECTOR_COUNT 1 /* Mandatory for only f_mkfs() */ +#define GET_SECTOR_SIZE 2 /* Mandatory for multiple sector size cfg */ +#define GET_BLOCK_SIZE 3 /* Mandatory for only f_mkfs() */ +#define CTRL_POWER 4 +#define CTRL_LOCK 5 +#define CTRL_EJECT 6 +/* MMC/SDC command */ +#define MMC_GET_TYPE 10 +#define MMC_GET_CSD 11 +#define MMC_GET_CID 12 +#define MMC_GET_OCR 13 +#define MMC_GET_SDSTAT 14 +/* ATA/CF command */ +#define ATA_GET_REV 20 +#define ATA_GET_MODEL 21 +#define ATA_GET_SN 22 + + +#define _DISKIO +#endif diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/ff.c b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/ff.c new file mode 100644 index 0000000..236c86f --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/ff.c @@ -0,0 +1,3553 @@ +/*----------------------------------------------------------------------------/ +/ FatFs - FAT file system module R0.08 (C)ChaN, 2010 +/-----------------------------------------------------------------------------/ +/ FatFs module is a generic FAT file system module for small embedded systems. +/ This is a free software that opened for education, research and commercial +/ developments under license policy of following terms. +/ +/ Copyright (C) 2010, ChaN, all right reserved. +/ +/ * The FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/-----------------------------------------------------------------------------/ +/ Feb 26,'06 R0.00 Prototype. +/ +/ Apr 29,'06 R0.01 First stable version. +/ +/ Jun 01,'06 R0.02 Added FAT12 support. +/ Removed unbuffered mode. +/ Fixed a problem on small (<32M) partition. +/ Jun 10,'06 R0.02a Added a configuration option (_FS_MINIMUM). +/ +/ Sep 22,'06 R0.03 Added f_rename(). +/ Changed option _FS_MINIMUM to _FS_MINIMIZE. +/ Dec 11,'06 R0.03a Improved cluster scan algorithm to write files fast. +/ Fixed f_mkdir() creates incorrect directory on FAT32. +/ +/ Feb 04,'07 R0.04 Supported multiple drive system. +/ Changed some interfaces for multiple drive system. +/ Changed f_mountdrv() to f_mount(). +/ Added f_mkfs(). +/ Apr 01,'07 R0.04a Supported multiple partitions on a physical drive. +/ Added a capability of extending file size to f_lseek(). +/ Added minimization level 3. +/ Fixed an endian sensitive code in f_mkfs(). +/ May 05,'07 R0.04b Added a configuration option _USE_NTFLAG. +/ Added FSInfo support. +/ Fixed DBCS name can result FR_INVALID_NAME. +/ Fixed short seek (<= csize) collapses the file object. +/ +/ Aug 25,'07 R0.05 Changed arguments of f_read(), f_write() and f_mkfs(). +/ Fixed f_mkfs() on FAT32 creates incorrect FSInfo. +/ Fixed f_mkdir() on FAT32 creates incorrect directory. +/ Feb 03,'08 R0.05a Added f_truncate() and f_utime(). +/ Fixed off by one error at FAT sub-type determination. +/ Fixed btr in f_read() can be mistruncated. +/ Fixed cached sector is not flushed when create and close +/ without write. +/ +/ Apr 01,'08 R0.06 Added fputc(), fputs(), fprintf() and fgets(). +/ Improved performance of f_lseek() on moving to the same +/ or following cluster. +/ +/ Apr 01,'09 R0.07 Merged Tiny-FatFs as a buffer configuration option. +/ Added long file name support. +/ Added multiple code page support. +/ Added re-entrancy for multitask operation. +/ Added auto cluster size selection to f_mkfs(). +/ Added rewind option to f_readdir(). +/ Changed result code of critical errors. +/ Renamed string functions to avoid name collision. +/ Apr 14,'09 R0.07a Separated out OS dependent code on reentrant cfg. +/ Added multiple sector size support. +/ Jun 21,'09 R0.07c Fixed f_unlink() can return FR_OK on error. +/ Fixed wrong cache control in f_lseek(). +/ Added relative path feature. +/ Added f_chdir() and f_chdrive(). +/ Added proper case conversion to extended char. +/ Nov 03,'09 R0.07e Separated out configuration options from ff.h to ffconf.h. +/ Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH. +/ Fixed name matching error on the 13 char boundary. +/ Added a configuration option, _LFN_UNICODE. +/ Changed f_readdir() to return the SFN with always upper +/ case on non-LFN cfg. +/ +/ May 15,'10 R0.08 Added a memory configuration option. (_USE_LFN) +/ Added file lock feature. (_FS_SHARE) +/ Added fast seek feature. (_USE_FASTSEEK) +/ Changed some types on the API, XCHAR->TCHAR. +/ Changed fname member in the FILINFO structure on Unicode cfg. +/ String functions support UTF-8 encoding files on Unicode cfg. +/---------------------------------------------------------------------------*/ + +#include "ff.h" /* FatFs configurations and declarations */ +#include "diskio.h" /* Declarations of low level disk I/O functions */ + + +/*-------------------------------------------------------------------------- + + Module Private Definitions + +---------------------------------------------------------------------------*/ + +#if _FATFS != 8085 +#error Wrong include file (ff.h). +#endif + + +/* FAT sub-type boundaries */ +/* Note that the FAT spec by Microsoft says 4085 but Windows works with 4087! */ +#define MIN_FAT16 4086 /* Minimum number of clusters for FAT16 */ +#define MIN_FAT32 65526 /* Minimum number of clusters for FAT32 */ + + +/* Definitions corresponds to multiple sector size */ +#if _MAX_SS == 512 /* Single sector size */ +#define SS(fs) 512U +#elif _MAX_SS == 1024 || _MAX_SS == 2048 || _MAX_SS == 4096 /* Multiple sector size */ +#define SS(fs) ((fs)->ssize) +#else +#error Wrong sector size. +#endif + + +/* Reentrancy related */ +#if _FS_REENTRANT +#if _USE_LFN == 1 +#error Static LFN work area must not be used in re-entrant configuration. +#endif +#define ENTER_FF(fs) { if (!lock_fs(fs)) return FR_TIMEOUT; } +#define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; } + +#else +#define ENTER_FF(fs) +#define LEAVE_FF(fs, res) return res + +#endif + +#define ABORT(fs, res) { fp->flag |= FA__ERROR; LEAVE_FF(fs, res); } + + +/* Character code support macros */ +#define IsUpper(c) (((c)>='A')&&((c)<='Z')) +#define IsLower(c) (((c)>='a')&&((c)<='z')) +#define IsDigit(c) (((c)>='0')&&((c)<='9')) + +#if _DF1S /* Code page is DBCS */ + +#ifdef _DF2S /* Two 1st byte areas */ +#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E)) +#else /* One 1st byte area */ +#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) +#endif + +#ifdef _DS3S /* Three 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E)) +#else /* Two 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E)) +#endif + +#else /* Code page is SBCS */ + +#define IsDBCS1(c) 0 +#define IsDBCS2(c) 0 + +#endif /* _DF1S */ + + +/* Name status flags */ +#define NS 11 /* Offset of name status byte */ +#define NS_LOSS 0x01 /* Out of 8.3 format */ +#define NS_LFN 0x02 /* Force to create LFN entry */ +#define NS_LAST 0x04 /* Last segment */ +#define NS_BODY 0x08 /* Lower case flag (body) */ +#define NS_EXT 0x10 /* Lower case flag (ext) */ +#define NS_DOT 0x20 /* Dot entry */ + + + +/*------------------------------------------------------------*/ +/* Work area */ + +#if !_DRIVES +#error Number of drives must not be 0. +#endif +static +WORD Fsid; /* File system mount ID */ +static +FATFS *FatFs[_DRIVES]; /* Pointer to the file system objects (logical drives) */ + +#if _FS_RPATH +static +BYTE Drive; /* Current drive */ +#endif + + +#if _USE_LFN == 0 /* No LFN */ +#define DEF_NAMEBUF BYTE sfn[12] +#define INIT_BUF(dobj) (dobj).fn = sfn +#define FREE_BUF() + +#elif _USE_LFN == 1 /* LFN with static LFN working buffer */ +static WCHAR LfnBuf[_MAX_LFN + 1]; +#define DEF_NAMEBUF BYTE sfn[12] +#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = LfnBuf; } +#define FREE_BUF() + +#elif _USE_LFN == 2 /* LFN with dynamic LFN working buffer on the stack */ +#define DEF_NAMEBUF BYTE sfn[12]; WCHAR lbuf[_MAX_LFN + 1] +#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = lbuf; } +#define FREE_BUF() + +#elif _USE_LFN == 3 /* LFN with dynamic LFN working buffer on the heap */ +#define DEF_NAMEBUF BYTE sfn[12]; WCHAR *lfn +#define INIT_BUF(dobj) { lfn = ff_memalloc((_MAX_LFN + 1) * 2); \ + if (!lfn) LEAVE_FF((dobj).fs, FR_NOT_ENOUGH_CORE); \ + (dobj).lfn = lfn; (dobj).fn = sfn; } +#define FREE_BUF() ff_memfree(lfn) + +#else +#error Wrong LFN configuration. +#endif + + + + +/*-------------------------------------------------------------------------- + + Module Private Functions + +---------------------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------------*/ +/* String functions */ +/*-----------------------------------------------------------------------*/ + +/* Copy memory to memory */ +static +void mem_cpy (void* dst, const void* src, int cnt) { + BYTE *d = (BYTE*)dst; + const BYTE *s = (const BYTE*)src; + +#if _WORD_ACCESS == 1 + while (cnt >= sizeof(int)) { + *(int*)d = *(int*)s; + d += sizeof(int); s += sizeof(int); + cnt -= sizeof(int); + } +#endif + while (cnt--) + *d++ = *s++; +} + +/* Fill memory */ +static +void mem_set (void* dst, int val, int cnt) { + BYTE *d = (BYTE*)dst; + + while (cnt--) + *d++ = (BYTE)val; +} + +/* Compare memory to memory */ +static +int mem_cmp (const void* dst, const void* src, int cnt) { + const BYTE *d = (const BYTE *)dst, *s = (const BYTE *)src; + int r = 0; + + while (cnt-- && (r = *d++ - *s++) == 0) ; + return r; +} + +/* Check if chr is contained in the string */ +static +int chk_chr (const char* str, int chr) { + while (*str && *str != chr) str++; + return *str; +} + + + +/*-----------------------------------------------------------------------*/ +/* Request/Release grant to access the volume */ +/*-----------------------------------------------------------------------*/ +#if _FS_REENTRANT + +static +int lock_fs ( + FATFS *fs /* File system object */ +) +{ + return ff_req_grant(fs->sobj); +} + + +static +void unlock_fs ( + FATFS *fs, /* File system object */ + FRESULT res /* Result code to be returned */ +) +{ + if (res != FR_NOT_ENABLED && + res != FR_INVALID_DRIVE && + res != FR_INVALID_OBJECT && + res != FR_TIMEOUT) { + ff_rel_grant(fs->sobj); + } +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* File shareing control functions */ +/*-----------------------------------------------------------------------*/ +#if _FS_SHARE + +static +FRESULT chk_lock ( /* Check if the file can be accessed */ + DIR* dj, /* Directory object pointing the file to be checked */ + int acc /* Desired access (0:Read, 1:Write, 2:Delete/Rename) */ +) +{ + UINT i, be; + + /* Search file semaphore table */ + for (i = be = 0; i < _FS_SHARE; i++) { + if (dj->fs->flsem[i].ctr) { /* Existing entry */ + if (dj->fs->flsem[i].clu == dj->sclust && /* The file is found (identified with its location) */ + dj->fs->flsem[i].idx == dj->index) break; + } else { /* Blank entry */ + be++; + } + } + if (i == _FS_SHARE) /* The file has not been opened */ + return (be || acc != 2) ? FR_OK : FR_TOO_MANY_OPEN_FILES; /* Is there a blank entry for new file? */ + + /* The file has been opened. Reject any open against writing file and all write mode open */ + return (acc || dj->fs->flsem[i].ctr == 0x100) ? FR_LOCKED : FR_OK; +} + + +static +int enq_lock ( /* Check if an entry is available for a new file */ + FATFS* fs /* File system object */ +) +{ + UINT i; + + for (i = 0; i < _FS_SHARE && fs->flsem[i].ctr; i++) ; + return (i == _FS_SHARE) ? 0 : 1; +} + + +static +UINT inc_lock ( /* Increment file open counter and returns its index (0:int error) */ + DIR* dj, /* Directory object pointing the file to register or increment */ + int acc /* Desired access mode (0:Read, !0:Write) */ +) +{ + UINT i; + + + for (i = 0; i < _FS_SHARE; i++) { /* Find the file */ + if (dj->fs->flsem[i].ctr && + dj->fs->flsem[i].clu == dj->sclust && + dj->fs->flsem[i].idx == dj->index) break; + } + + if (i == _FS_SHARE) { /* Not opened. Register it as new. */ + for (i = 0; i < _FS_SHARE && dj->fs->flsem[i].ctr; i++) ; + if (i == _FS_SHARE) return 0; /* No space to register (int err) */ + dj->fs->flsem[i].clu = dj->sclust; + dj->fs->flsem[i].idx = dj->index; + } + + if (acc && dj->fs->flsem[i].ctr) return 0; /* Access violation (int err) */ + + dj->fs->flsem[i].ctr = acc ? 0x100 : dj->fs->flsem[i].ctr + 1; /* Set semaphore value */ + + return i + 1; +} + + +static +FRESULT dec_lock ( /* Decrement file open counter */ + FATFS* fs, /* File system object */ + UINT i /* Semaphore index */ +) +{ + WORD n; + FRESULT res; + + + if (--i < _FS_SHARE) { + n = fs->flsem[i].ctr; + if (n >= 0x100) n = 0; + if (n) n--; + fs->flsem[i].ctr = n; + res = FR_OK; + } else { + res = FR_INT_ERR; + } + return res; +} + +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Change window offset */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT move_window ( + FATFS *fs, /* File system object */ + DWORD sector /* Sector number to make appearance in the fs->win[] */ +) /* Move to zero only writes back dirty window */ +{ + DWORD wsect; + + + wsect = fs->winsect; + if (wsect != sector) { /* Changed current window */ +#if !_FS_READONLY + if (fs->wflag) { /* Write back dirty window if needed */ + if (disk_write(fs->drv, fs->win, wsect, 1) != RES_OK) + return FR_DISK_ERR; + fs->wflag = 0; + if (wsect < (fs->fatbase + fs->fsize)) { /* In FAT area */ + BYTE nf; + for (nf = fs->n_fats; nf > 1; nf--) { /* Reflect the change to all FAT copies */ + wsect += fs->fsize; + disk_write(fs->drv, fs->win, wsect, 1); + } + } + } +#endif + if (sector) { + if (disk_read(fs->drv, fs->win, sector, 1) != RES_OK) + return FR_DISK_ERR; + fs->winsect = sector; + } + } + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Clean-up cached data */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT sync ( /* FR_OK: successful, FR_DISK_ERR: failed */ + FATFS *fs /* File system object */ +) +{ + FRESULT res; + + + res = move_window(fs, 0); + if (res == FR_OK) { + /* Update FSInfo sector if needed */ + if (fs->fs_type == FS_FAT32 && fs->fsi_flag) { + fs->winsect = 0; + mem_set(fs->win, 0, 512); + ST_WORD(fs->win+BS_55AA, 0xAA55); + ST_DWORD(fs->win+FSI_LeadSig, 0x41615252); + ST_DWORD(fs->win+FSI_StrucSig, 0x61417272); + ST_DWORD(fs->win+FSI_Free_Count, fs->free_clust); + ST_DWORD(fs->win+FSI_Nxt_Free, fs->last_clust); + disk_write(fs->drv, fs->win, fs->fsi_sector, 1); + fs->fsi_flag = 0; + } + /* Make sure that no pending write process in the physical drive */ + if (disk_ioctl(fs->drv, CTRL_SYNC, (void*)0) != RES_OK) + res = FR_DISK_ERR; + } + + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Read value of a FAT entry */ +/*-----------------------------------------------------------------------*/ + + +DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to get the link information */ +) +{ + UINT wc, bc; + BYTE *p; + + + if (clst < 2 || clst >= fs->n_fatent) /* Chack range */ + return 1; + + switch (fs->fs_type) { + case FS_FAT12 : + bc = (UINT)clst; bc += bc / 2; + if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break; + wc = fs->win[bc % SS(fs)]; bc++; + if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break; + wc |= fs->win[bc % SS(fs)] << 8; + return (clst & 1) ? (wc >> 4) : (wc & 0xFFF); + + case FS_FAT16 : + if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)))) break; + p = &fs->win[clst * 2 % SS(fs)]; + return LD_WORD(p); + + case FS_FAT32 : + if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)))) break; + p = &fs->win[clst * 4 % SS(fs)]; + return LD_DWORD(p) & 0x0FFFFFFF; + } + + return 0xFFFFFFFF; /* An error occurred at the disk I/O layer */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Change value of a FAT entry */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY + +FRESULT put_fat ( + FATFS *fs, /* File system object */ + DWORD clst, /* Cluster# to be changed in range of 2 to fs->n_fatent - 1 */ + DWORD val /* New value to mark the cluster */ +) +{ + UINT bc; + BYTE *p; + FRESULT res; + + + if (clst < 2 || clst >= fs->n_fatent) { /* Check range */ + res = FR_INT_ERR; + + } else { + switch (fs->fs_type) { + case FS_FAT12 : + bc = clst; bc += bc / 2; + res = move_window(fs, fs->fatbase + (bc / SS(fs))); + if (res != FR_OK) break; + p = &fs->win[bc % SS(fs)]; + *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val; + bc++; + fs->wflag = 1; + res = move_window(fs, fs->fatbase + (bc / SS(fs))); + if (res != FR_OK) break; + p = &fs->win[bc % SS(fs)]; + *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F)); + break; + + case FS_FAT16 : + res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))); + if (res != FR_OK) break; + p = &fs->win[clst * 2 % SS(fs)]; + ST_WORD(p, (WORD)val); + break; + + case FS_FAT32 : + res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))); + if (res != FR_OK) break; + p = &fs->win[clst * 4 % SS(fs)]; + val |= LD_DWORD(p) & 0xF0000000; + ST_DWORD(p, val); + break; + + default : + res = FR_INT_ERR; + } + fs->wflag = 1; + } + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Remove a cluster chain */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT remove_chain ( + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to remove a chain from */ +) +{ + FRESULT res; + DWORD nxt; + + + if (clst < 2 || clst >= fs->n_fatent) { /* Check range */ + res = FR_INT_ERR; + + } else { + res = FR_OK; + while (clst < fs->n_fatent) { /* Not a last link? */ + nxt = get_fat(fs, clst); /* Get cluster status */ + if (nxt == 0) break; /* Empty cluster? */ + if (nxt == 1) { res = FR_INT_ERR; break; } /* Internal error? */ + if (nxt == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } /* Disk error? */ + res = put_fat(fs, clst, 0); /* Mark the cluster "empty" */ + if (res != FR_OK) break; + if (fs->free_clust != 0xFFFFFFFF) { /* Update FSInfo */ + fs->free_clust++; + fs->fsi_flag = 1; + } + clst = nxt; /* Next cluster */ + } + } + + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Stretch or Create a cluster chain */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to stretch. 0 means create a new chain. */ +) +{ + DWORD cs, ncl, scl; + + + if (clst == 0) { /* Create a new chain */ + scl = fs->last_clust; /* Get suggested start point */ + if (!scl || scl >= fs->n_fatent) scl = 1; + } + else { /* Stretch the current chain */ + cs = get_fat(fs, clst); /* Check the cluster status */ + if (cs < 2) return 1; /* It is an invalid cluster */ + if (cs < fs->n_fatent) return cs; /* It is already followed by next cluster */ + scl = clst; + } + + ncl = scl; /* Start cluster */ + for (;;) { + ncl++; /* Next cluster */ + if (ncl >= fs->n_fatent) { /* Wrap around */ + ncl = 2; + if (ncl > scl) return 0; /* No free cluster */ + } + cs = get_fat(fs, ncl); /* Get the cluster status */ + if (cs == 0) break; /* Found a free cluster */ + if (cs == 0xFFFFFFFF || cs == 1)/* An error occurred */ + return cs; + if (ncl == scl) return 0; /* No free cluster */ + } + + if (put_fat(fs, ncl, 0x0FFFFFFF)) /* Mark the new cluster "last link" */ + return 0xFFFFFFFF; + if (clst != 0) { /* Link it to the previous one if needed */ + if (put_fat(fs, clst, ncl)) + return 0xFFFFFFFF; + } + + fs->last_clust = ncl; /* Update FSINFO */ + if (fs->free_clust != 0xFFFFFFFF) { + fs->free_clust--; + fs->fsi_flag = 1; + } + + return ncl; /* Return new cluster number */ +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Get sector# from cluster# */ +/*-----------------------------------------------------------------------*/ + + +DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to be converted */ +) +{ + clst -= 2; + if (clst >= (fs->n_fatent - 2)) return 0; /* Invalid cluster# */ + return clst * fs->csize + fs->database; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Set directory index */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_sdi ( + DIR *dj, /* Pointer to directory object */ + WORD idx /* Directory index number */ +) +{ + DWORD clst; + WORD ic; + + + dj->index = idx; + clst = dj->sclust; + if (clst == 1 || clst >= dj->fs->n_fatent) /* Check start cluster range */ + return FR_INT_ERR; + if (!clst && dj->fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */ + clst = dj->fs->dirbase; + + if (clst == 0) { /* Static table */ + dj->clust = clst; + if (idx >= dj->fs->n_rootdir) /* Index is out of range */ + return FR_INT_ERR; + dj->sect = dj->fs->dirbase + idx / (SS(dj->fs) / 32); /* Sector# */ + } + else { /* Dynamic table */ + ic = SS(dj->fs) / 32 * dj->fs->csize; /* Entries per cluster */ + while (idx >= ic) { /* Follow cluster chain */ + clst = get_fat(dj->fs, clst); /* Get next cluster */ + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ + if (clst < 2 || clst >= dj->fs->n_fatent) /* Reached to end of table or int error */ + return FR_INT_ERR; + idx -= ic; + } + dj->clust = clst; + dj->sect = clust2sect(dj->fs, clst) + idx / (SS(dj->fs) / 32); /* Sector# */ + } + + dj->dir = dj->fs->win + (idx % (SS(dj->fs) / 32)) * 32; /* Ptr to the entry in the sector */ + + return FR_OK; /* Seek succeeded */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Move directory index next */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:EOT and could not stretch */ + DIR *dj, /* Pointer to directory object */ + int stretch /* 0: Do not stretch table, 1: Stretch table if needed */ +) +{ + DWORD clst; + WORD i; + + + i = dj->index + 1; + if (!i || !dj->sect) /* Report EOT when index has reached 65535 */ + return FR_NO_FILE; + + if (!(i % (SS(dj->fs) / 32))) { /* Sector changed? */ + dj->sect++; /* Next sector */ + + if (dj->clust == 0) { /* Static table */ + if (i >= dj->fs->n_rootdir) /* Report EOT when end of table */ + return FR_NO_FILE; + } + else { /* Dynamic table */ + if (((i / (SS(dj->fs) / 32)) & (dj->fs->csize - 1)) == 0) { /* Cluster changed? */ + clst = get_fat(dj->fs, dj->clust); /* Get next cluster */ + if (clst <= 1) return FR_INT_ERR; + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; + if (clst >= dj->fs->n_fatent) { /* When it reached end of dynamic table */ +#if !_FS_READONLY + BYTE c; + if (!stretch) return FR_NO_FILE; /* When do not stretch, report EOT */ + clst = create_chain(dj->fs, dj->clust); /* Stretch cluster chain */ + if (clst == 0) return FR_DENIED; /* No free cluster */ + if (clst == 1) return FR_INT_ERR; + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; + /* Clean-up stretched table */ + if (move_window(dj->fs, 0)) return FR_DISK_ERR; /* Flush active window */ + mem_set(dj->fs->win, 0, SS(dj->fs)); /* Clear window buffer */ + dj->fs->winsect = clust2sect(dj->fs, clst); /* Cluster start sector */ + for (c = 0; c < dj->fs->csize; c++) { /* Fill the new cluster with 0 */ + dj->fs->wflag = 1; + if (move_window(dj->fs, 0)) return FR_DISK_ERR; + dj->fs->winsect++; + } + dj->fs->winsect -= c; /* Rewind window address */ +#else + return FR_NO_FILE; /* Report EOT */ +#endif + } + dj->clust = clst; /* Initialize data for new cluster */ + dj->sect = clust2sect(dj->fs, clst); + } + } + } + + dj->index = i; + dj->dir = dj->fs->win + (i % (SS(dj->fs) / 32)) * 32; + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* LFN handling - Test/Pick/Fit an LFN segment from/to directory entry */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +static +const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30}; /* Offset of LFN chars in the directory entry */ + + +static +int cmp_lfn ( /* 1:Matched, 0:Not matched */ + WCHAR *lfnbuf, /* Pointer to the LFN to be compared */ + BYTE *dir /* Pointer to the directory entry containing a part of LFN */ +) +{ + int i, s; + WCHAR wc, uc; + + + i = ((dir[LDIR_Ord] & 0xBF) - 1) * 13; /* Get offset in the LFN buffer */ + s = 0; wc = 1; + do { + uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + if (wc) { /* Last char has not been processed */ + wc = ff_wtoupper(uc); /* Convert it to upper case */ + if (i >= _MAX_LFN || wc != ff_wtoupper(lfnbuf[i++])) /* Compare it */ + return 0; /* Not matched */ + } else { + if (uc != 0xFFFF) return 0; /* Check filler */ + } + } while (++s < 13); /* Repeat until all chars in the entry are checked */ + + if ((dir[LDIR_Ord] & 0x40) && wc && lfnbuf[i]) /* Last segment matched but different length */ + return 0; + + return 1; /* The part of LFN matched */ +} + + + +static +int pick_lfn ( /* 1:Succeeded, 0:Buffer overflow */ + WCHAR *lfnbuf, /* Pointer to the Unicode-LFN buffer */ + BYTE *dir /* Pointer to the directory entry */ +) +{ + int i, s; + WCHAR wc, uc; + + + i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13; /* Offset in the LFN buffer */ + + s = 0; wc = 1; + do { + uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + if (wc) { /* Last char has not been processed */ + if (i >= _MAX_LFN) return 0; /* Buffer overflow? */ + lfnbuf[i++] = wc = uc; /* Store it */ + } else { + if (uc != 0xFFFF) return 0; /* Check filler */ + } + } while (++s < 13); /* Read all character in the entry */ + + if (dir[LDIR_Ord] & 0x40) { /* Put terminator if it is the last LFN part */ + if (i >= _MAX_LFN) return 0; /* Buffer overflow? */ + lfnbuf[i] = 0; + } + + return 1; +} + + +#if !_FS_READONLY +static +void fit_lfn ( + const WCHAR *lfnbuf, /* Pointer to the LFN buffer */ + BYTE *dir, /* Pointer to the directory entry */ + BYTE ord, /* LFN order (1-20) */ + BYTE sum /* SFN sum */ +) +{ + int i, s; + WCHAR wc; + + + dir[LDIR_Chksum] = sum; /* Set check sum */ + dir[LDIR_Attr] = AM_LFN; /* Set attribute. LFN entry */ + dir[LDIR_Type] = 0; + ST_WORD(dir+LDIR_FstClusLO, 0); + + i = (ord - 1) * 13; /* Get offset in the LFN buffer */ + s = wc = 0; + do { + if (wc != 0xFFFF) wc = lfnbuf[i++]; /* Get an effective char */ + ST_WORD(dir+LfnOfs[s], wc); /* Put it */ + if (!wc) wc = 0xFFFF; /* Padding chars following last char */ + } while (++s < 13); + if (wc == 0xFFFF || !lfnbuf[i]) ord |= 0x40; /* Bottom LFN part is the start of LFN sequence */ + dir[LDIR_Ord] = ord; /* Set the LFN order */ +} + +#endif +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Create numbered name */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +void gen_numname ( + BYTE *dst, /* Pointer to generated SFN */ + const BYTE *src, /* Pointer to source SFN to be modified */ + const WCHAR *lfn, /* Pointer to LFN */ + WORD seq /* Sequence number */ +) +{ + BYTE ns[8], c; + int i, j; + + + mem_cpy(dst, src, 11); + + if (seq > 5) { /* On many collisions, generate a hash number instead of sequential number */ + do seq = (seq >> 1) + (seq << 15) + (WORD)*lfn++; while (*lfn); + } + + /* itoa */ + i = 7; + do { + c = (seq % 16) + '0'; + if (c > '9') c += 7; + ns[i--] = c; + seq /= 16; + } while (seq); + ns[i] = '~'; + + /* Append the number */ + for (j = 0; j < i && dst[j] != ' '; j++) { + if (IsDBCS1(dst[j])) { + if (j == i - 1) break; + j++; + } + } + do { + dst[j++] = (i < 8) ? ns[i++] : ' '; + } while (j < 8); +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Calculate sum of an SFN */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +static +BYTE sum_sfn ( + const BYTE *dir /* Ptr to directory entry */ +) +{ + BYTE sum = 0; + int n = 11; + + do sum = (sum >> 1) + (sum << 7) + *dir++; while (--n); + return sum; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Find an object in the directory */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_find ( + DIR *dj /* Pointer to the directory object linked to the file name */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN + BYTE a, ord, sum; +#endif + + res = dir_sdi(dj, 0); /* Rewind directory object */ + if (res != FR_OK) return res; + +#if _USE_LFN + ord = sum = 0xFF; +#endif + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + dir = dj->dir; /* Ptr to the directory entry of current index */ + c = dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ +#if _USE_LFN /* LFN configuration */ + a = dir[DIR_Attr] & AM_MASK; + if (c == 0xE5 || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ + ord = 0xFF; + } else { + if (a == AM_LFN) { /* An LFN entry is found */ + if (dj->lfn) { + if (c & 0x40) { /* Is it start of LFN sequence? */ + sum = dir[LDIR_Chksum]; + c &= 0xBF; ord = c; /* LFN start order */ + dj->lfn_idx = dj->index; + } + /* Check validity of the LFN entry and compare it with given name */ + ord = (c == ord && sum == dir[LDIR_Chksum] && cmp_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF; + } + } else { /* An SFN entry is found */ + if (!ord && sum == sum_sfn(dir)) break; /* LFN matched? */ + ord = 0xFF; dj->lfn_idx = 0xFFFF; /* Reset LFN sequence */ + if (!(dj->fn[NS] & NS_LOSS) && !mem_cmp(dir, dj->fn, 11)) break; /* SFN matched? */ + } + } +#else /* Non LFN configuration */ + if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */ + break; +#endif + res = dir_next(dj, 0); /* Next entry */ + } while (res == FR_OK); + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read an object from the directory */ +/*-----------------------------------------------------------------------*/ +#if _FS_MINIMIZE <= 1 +static +FRESULT dir_read ( + DIR *dj /* Pointer to the directory object that pointing the entry to be read */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN + BYTE a, ord = 0xFF, sum = 0xFF; +#endif + + res = FR_NO_FILE; + while (dj->sect) { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + dir = dj->dir; /* Ptr to the directory entry of current index */ + c = dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ +#if _USE_LFN /* LFN configuration */ + a = dir[DIR_Attr] & AM_MASK; + if (c == 0xE5 || (!_FS_RPATH && c == '.') || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ + ord = 0xFF; + } else { + if (a == AM_LFN) { /* An LFN entry is found */ + if (c & 0x40) { /* Is it start of LFN sequence? */ + sum = dir[LDIR_Chksum]; + c &= 0xBF; ord = c; + dj->lfn_idx = dj->index; + } + /* Check LFN validity and capture it */ + ord = (c == ord && sum == dir[LDIR_Chksum] && pick_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF; + } else { /* An SFN entry is found */ + if (ord || sum != sum_sfn(dir)) /* Is there a valid LFN? */ + dj->lfn_idx = 0xFFFF; /* It has no LFN. */ + break; + } + } +#else /* Non LFN configuration */ + if (c != 0xE5 && (_FS_RPATH || c != '.') && !(dir[DIR_Attr] & AM_VOL)) /* Is it a valid entry? */ + break; +#endif + res = dir_next(dj, 0); /* Next entry */ + if (res != FR_OK) break; + } + + if (res != FR_OK) dj->sect = 0; + + return res; +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Register an object to the directory */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT dir_register ( /* FR_OK:Successful, FR_DENIED:No free entry or too many SFN collision, FR_DISK_ERR:Disk error */ + DIR *dj /* Target directory with object name to be created */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN /* LFN configuration */ + WORD n, ne, is; + BYTE sn[12], *fn, sum; + WCHAR *lfn; + + + fn = dj->fn; lfn = dj->lfn; + mem_cpy(sn, fn, 12); + + if (_FS_RPATH && (sn[NS] & NS_DOT)) return FR_INVALID_NAME; /* Cannot create dot entry */ + + if (sn[NS] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */ + fn[NS] = 0; dj->lfn = 0; /* Find only SFN */ + for (n = 1; n < 100; n++) { + gen_numname(fn, sn, lfn, n); /* Generate a numbered name */ + res = dir_find(dj); /* Check if the name collides with existing SFN */ + if (res != FR_OK) break; + } + if (n == 100) return FR_DENIED; /* Abort if too many collisions */ + if (res != FR_NO_FILE) return res; /* Abort if the result is other than 'not collided' */ + fn[NS] = sn[NS]; dj->lfn = lfn; + } + + if (sn[NS] & NS_LFN) { /* When LFN is to be created, reserve an SFN + LFN entries. */ + for (ne = 0; lfn[ne]; ne++) ; + ne = (ne + 25) / 13; + } else { /* Otherwise reserve only an SFN entry. */ + ne = 1; + } + + /* Reserve contiguous entries */ + res = dir_sdi(dj, 0); + if (res != FR_OK) return res; + n = is = 0; + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + c = *dj->dir; /* Check the entry status */ + if (c == 0xE5 || c == 0) { /* Is it a blank entry? */ + if (n == 0) is = dj->index; /* First index of the contiguous entry */ + if (++n == ne) break; /* A contiguous entry that required count is found */ + } else { + n = 0; /* Not a blank entry. Restart to search */ + } + res = dir_next(dj, 1); /* Next entry with table stretch */ + } while (res == FR_OK); + + if (res == FR_OK && ne > 1) { /* Initialize LFN entry if needed */ + res = dir_sdi(dj, is); + if (res == FR_OK) { + sum = sum_sfn(dj->fn); /* Sum of the SFN tied to the LFN */ + ne--; + do { /* Store LFN entries in bottom first */ + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + fit_lfn(dj->lfn, dj->dir, (BYTE)ne, sum); + dj->fs->wflag = 1; + res = dir_next(dj, 0); /* Next entry */ + } while (res == FR_OK && --ne); + } + } + +#else /* Non LFN configuration */ + res = dir_sdi(dj, 0); + if (res == FR_OK) { + do { /* Find a blank entry for the SFN */ + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + c = *dj->dir; + if (c == 0xE5 || c == 0) break; /* Is it a blank entry? */ + res = dir_next(dj, 1); /* Next entry with table stretch */ + } while (res == FR_OK); + } +#endif + + if (res == FR_OK) { /* Initialize the SFN entry */ + res = move_window(dj->fs, dj->sect); + if (res == FR_OK) { + dir = dj->dir; + mem_set(dir, 0, 32); /* Clean the entry */ + mem_cpy(dir, dj->fn, 11); /* Put SFN */ +#if _USE_LFN + dir[DIR_NTres] = *(dj->fn+NS) & (NS_BODY | NS_EXT); /* Put NT flag */ +#endif + dj->fs->wflag = 1; + } + } + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Remove an object from the directory */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY && !_FS_MINIMIZE +static +FRESULT dir_remove ( /* FR_OK: Successful, FR_DISK_ERR: A disk error */ + DIR *dj /* Directory object pointing the entry to be removed */ +) +{ + FRESULT res; +#if _USE_LFN /* LFN configuration */ + WORD i; + + i = dj->index; /* SFN index */ + res = dir_sdi(dj, (WORD)((dj->lfn_idx == 0xFFFF) ? i : dj->lfn_idx)); /* Goto the SFN or top of the LFN entries */ + if (res == FR_OK) { + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + *dj->dir = 0xE5; /* Mark the entry "deleted" */ + dj->fs->wflag = 1; + if (dj->index >= i) break; /* When reached SFN, all entries of the object has been deleted. */ + res = dir_next(dj, 0); /* Next entry */ + } while (res == FR_OK); + if (res == FR_NO_FILE) res = FR_INT_ERR; + } + +#else /* Non LFN configuration */ + res = dir_sdi(dj, dj->index); + if (res == FR_OK) { + res = move_window(dj->fs, dj->sect); + if (res == FR_OK) { + *dj->dir = 0xE5; /* Mark the entry "deleted" */ + dj->fs->wflag = 1; + } + } +#endif + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Pick a segment and create the object name in directory form */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT create_name ( + DIR *dj, /* Pointer to the directory object */ + const TCHAR **path /* Pointer to pointer to the segment in the path string */ +) +{ +#ifdef _EXCVT + static const BYTE excvt[] = _EXCVT; /* Upper conversion table for extended chars */ +#endif + +#if _USE_LFN /* LFN configuration */ + BYTE b, cf; + WCHAR w, *lfn; + int i, ni, si, di; + const TCHAR *p; + + /* Create LFN in Unicode */ + si = di = 0; + p = *path; + lfn = dj->lfn; + for (;;) { + w = p[si++]; /* Get a character */ + if (w < ' ' || w == '/' || w == '\\') break; /* Break on end of segment */ + if (di >= _MAX_LFN) /* Reject too long name */ + return FR_INVALID_NAME; +#if !_LFN_UNICODE + w &= 0xFF; + if (IsDBCS1(w)) { /* If it is a DBC 1st byte */ + b = p[si++]; /* Get 2nd byte */ + if (!IsDBCS2(b)) /* Reject invalid code for DBC */ + return FR_INVALID_NAME; + w = (w << 8) + b; + } + w = ff_convert(w, 1); /* Convert OEM to Unicode */ + if (!w) return FR_INVALID_NAME; /* Reject invalid code */ +#endif + if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) /* Reject illegal chars for LFN */ + return FR_INVALID_NAME; + lfn[di++] = w; /* Store the Unicode char */ + } + *path = &p[si]; /* Return pointer to the next segment */ + cf = (w < ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ +#if _FS_RPATH + if ((di == 1 && lfn[di - 1] == '.') || /* Is this a dot entry? */ + (di == 2 && lfn[di - 1] == '.' && lfn[di - 2] == '.')) { + lfn[di] = 0; + for (i = 0; i < 11; i++) + dj->fn[i] = (i < di) ? '.' : ' '; + dj->fn[i] = cf | NS_DOT; /* This is a dot entry */ + return FR_OK; + } +#endif + while (di) { /* Strip trailing spaces and dots */ + w = lfn[di - 1]; + if (w != ' ' && w != '.') break; + di--; + } + if (!di) return FR_INVALID_NAME; /* Reject nul string */ + + lfn[di] = 0; /* LFN is created */ + + /* Create SFN in directory form */ + mem_set(dj->fn, ' ', 11); + for (si = 0; lfn[si] == ' ' || lfn[si] == '.'; si++) ; /* Strip leading spaces and dots */ + if (si) cf |= NS_LOSS | NS_LFN; + while (di && lfn[di - 1] != '.') di--; /* Find extension (di<=si: no extension) */ + + b = i = 0; ni = 8; + for (;;) { + w = lfn[si++]; /* Get an LFN char */ + if (!w) break; /* Break on end of the LFN */ + if (w == ' ' || (w == '.' && si != di)) { /* Remove spaces and dots */ + cf |= NS_LOSS | NS_LFN; continue; + } + + if (i >= ni || si == di) { /* Extension or end of SFN */ + if (ni == 11) { /* Long extension */ + cf |= NS_LOSS | NS_LFN; break; + } + if (si != di) cf |= NS_LOSS | NS_LFN; /* Out of 8.3 format */ + if (si > di) break; /* No extension */ + si = di; i = 8; ni = 11; /* Enter extension section */ + b <<= 2; continue; + } + + if (w >= 0x80) { /* Non ASCII char */ +#ifdef _EXCVT + w = ff_convert(w, 0); /* Unicode -> OEM code */ + if (w) w = excvt[w - 0x80]; /* Convert extended char to upper (SBCS) */ +#else + w = ff_convert(ff_wtoupper(w), 0); /* Upper converted Unicode -> OEM code */ +#endif + cf |= NS_LFN; /* Force create LFN entry */ + } + + if (_DF1S && w >= 0x100) { /* Double byte char */ + if (i >= ni - 1) { + cf |= NS_LOSS | NS_LFN; i = ni; continue; + } + dj->fn[i++] = (BYTE)(w >> 8); + } else { /* Single byte char */ + if (!w || chk_chr("+,;=[]", w)) { /* Replace illegal chars for SFN */ + w = '_'; cf |= NS_LOSS | NS_LFN; /* Lossy conversion */ + } else { + if (IsUpper(w)) { /* ASCII large capital */ + b |= 2; + } else { + if (IsLower(w)) { /* ASCII small capital */ + b |= 1; w -= 0x20; + } + } + } + } + dj->fn[i++] = (BYTE)w; + } + + if (dj->fn[0] == 0xE5) dj->fn[0] = 0x05; /* If the first char collides with deleted mark, replace it with 0x05 */ + + if (ni == 8) b <<= 2; + if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) /* Create LFN entry when there are composite capitals */ + cf |= NS_LFN; + if (!(cf & NS_LFN)) { /* When LFN is in 8.3 format without extended char, NT flags are created */ + if ((b & 0x03) == 0x01) cf |= NS_EXT; /* NT flag (Extension has only small capital) */ + if ((b & 0x0C) == 0x04) cf |= NS_BODY; /* NT flag (Filename has only small capital) */ + } + + dj->fn[NS] = cf; /* SFN is created */ + + return FR_OK; + + +#else /* Non-LFN configuration */ + BYTE b, c, d, *sfn; + int ni, si, i; + const char *p; + + /* Create file name in directory form */ + sfn = dj->fn; + mem_set(sfn, ' ', 11); + si = i = b = 0; ni = 8; + p = *path; +#if _FS_RPATH + if (p[si] == '.') { /* Is this a dot entry? */ + for (;;) { + c = (BYTE)p[si++]; + if (c != '.' || si >= 3) break; + sfn[i++] = c; + } + if (c != '/' && c != '\\' && c > ' ') return FR_INVALID_NAME; + *path = &p[si]; /* Return pointer to the next segment */ + sfn[NS] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT; /* Set last segment flag if end of path */ + return FR_OK; + } +#endif + for (;;) { + c = (BYTE)p[si++]; + if (c <= ' ' || c == '/' || c == '\\') break; /* Break on end of segment */ + if (c == '.' || i >= ni) { + if (ni != 8 || c != '.') return FR_INVALID_NAME; + i = 8; ni = 11; + b <<= 2; continue; + } + if (c >= 0x80) { /* Extended char */ +#ifdef _EXCVT + c = excvt[c - 0x80]; /* Convert extend char (SBCS) */ +#else + b |= 3; /* Eliminate NT flag if extended char is exist */ +#if !_DF1S /* ASCII only cfg */ + return FR_INVALID_NAME; +#endif +#endif + } + if (IsDBCS1(c)) { /* DBC 1st byte? */ + d = (BYTE)p[si++]; /* Get 2nd byte */ + if (!IsDBCS2(d) || i >= ni - 1) /* Reject invalid DBC */ + return FR_INVALID_NAME; + sfn[i++] = c; + sfn[i++] = d; + } else { /* Single byte code */ + if (chk_chr("\"*+,:<=>\?[]|\x7F", c)) /* Reject illegal chrs for SFN */ + return FR_INVALID_NAME; + if (IsUpper(c)) { /* ASCII large capital? */ + b |= 2; + } else { + if (IsLower(c)) { /* ASCII small capital? */ + b |= 1; c -= 0x20; + } + } + sfn[i++] = c; + } + } + *path = &p[si]; /* Return pointer to the next segment */ + c = (c <= ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ + + if (!i) return FR_INVALID_NAME; /* Reject nul string */ + if (sfn[0] == 0xE5) sfn[0] = 0x05; /* When first char collides with 0xE5, replace it with 0x05 */ + + if (ni == 8) b <<= 2; + if ((b & 0x03) == 0x01) c |= NS_EXT; /* NT flag (Name extension has only small capital) */ + if ((b & 0x0C) == 0x04) c |= NS_BODY; /* NT flag (Name body has only small capital) */ + + sfn[NS] = c; /* Store NT flag, File name is created */ + + return FR_OK; +#endif +} + + + + +/*-----------------------------------------------------------------------*/ +/* Get file information from directory entry */ +/*-----------------------------------------------------------------------*/ +#if _FS_MINIMIZE <= 1 +static +void get_fileinfo ( /* No return code */ + DIR *dj, /* Pointer to the directory object */ + FILINFO *fno /* Pointer to the file information to be filled */ +) +{ + int i; + BYTE nt, *dir; + TCHAR *p, c; + + + p = fno->fname; + if (dj->sect) { + dir = dj->dir; + nt = dir[DIR_NTres]; /* NT flag */ + for (i = 0; i < 8; i++) { /* Copy name body */ + c = dir[i]; + if (c == ' ') break; + if (c == 0x05) c = (TCHAR)0xE5; + if (_USE_LFN && (nt & NS_BODY) && IsUpper(c)) c += 0x20; +#if _LFN_UNICODE + if (IsDBCS1(c) && i < 7 && IsDBCS2(dir[i + 1])) + c = (c << 8) | dir[++i]; + c = ff_convert(c, 1); + if (!c) c = '?'; +#endif + *p++ = c; + } + if (dir[8] != ' ') { /* Copy name extension */ + *p++ = '.'; + for (i = 8; i < 11; i++) { + c = dir[i]; + if (c == ' ') break; + if (_USE_LFN && (nt & NS_EXT) && IsUpper(c)) c += 0x20; +#if _LFN_UNICODE + if (IsDBCS1(c) && i < 10 && IsDBCS2(dir[i + 1])) + c = (c << 8) | dir[++i]; + c = ff_convert(c, 1); + if (!c) c = '?'; +#endif + *p++ = c; + } + } + fno->fattrib = dir[DIR_Attr]; /* Attribute */ + fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */ + fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */ + fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */ + } + *p = 0; + +#if _USE_LFN + if (fno->lfname) { + TCHAR *tp = fno->lfname; + WCHAR w, *lfn; + + i = 0; + if (dj->sect && dj->lfn_idx != 0xFFFF) {/* Get LFN if available */ + lfn = dj->lfn; + while ((w = *lfn++) != 0) { /* Get an LFN char */ +#if !_LFN_UNICODE + w = ff_convert(w, 0); /* Unicode -> OEM conversion */ + if (!w) { i = 0; break; } /* Could not convert, no LFN */ + if (_DF1S && w >= 0x100) /* Put 1st byte if it is a DBC */ + tp[i++] = (TCHAR)(w >> 8); +#endif + if (i >= fno->lfsize - 1) { i = 0; break; } /* Buffer overrun, no LFN */ + tp[i++] = (TCHAR)w; + } + } + tp[i] = 0; /* Terminator */ + } +#endif +} +#endif /* _FS_MINIMIZE <= 1 */ + + + + +/*-----------------------------------------------------------------------*/ +/* Follow a file path */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ + DIR *dj, /* Directory object to return last directory and found object */ + const TCHAR *path /* Full-path string to find a file or directory */ +) +{ + FRESULT res; + BYTE *dir, ns; + + +#if _FS_RPATH + if (*path == '/' || *path == '\\') { /* There is a heading separator */ + path++; dj->sclust = 0; /* Strip it and start from the root dir */ + } else { /* No heading separator */ + dj->sclust = dj->fs->cdir; /* Start from the current dir */ + } +#else + if (*path == '/' || *path == '\\') /* Strip heading separator if exist */ + path++; + dj->sclust = 0; /* Start from the root dir */ +#endif + + if ((UINT)*path < ' ') { /* Nul path means the start directory itself */ + res = dir_sdi(dj, 0); + dj->dir = 0; + + } else { /* Follow path */ + for (;;) { + res = create_name(dj, &path); /* Get a segment */ + if (res != FR_OK) break; + res = dir_find(dj); /* Find it */ + ns = *(dj->fn+NS); + if (res != FR_OK) { /* Failed to find the object */ + if (res != FR_NO_FILE) break; /* Abort if any hard error occured */ + /* Object not found */ + if (_FS_RPATH && (ns & NS_DOT)) { /* If dot entry is not exit */ + dj->sclust = 0; dj->dir = 0; /* It is the root dir */ + res = FR_OK; + if (!(ns & NS_LAST)) continue; + } else { /* Could not find the object */ + if (!(ns & NS_LAST)) res = FR_NO_PATH; + } + break; + } + if (ns & NS_LAST) break; /* Last segment match. Function completed. */ + dir = dj->dir; /* There is next segment. Follow the sub directory */ + if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */ + res = FR_NO_PATH; break; + } + dj->sclust = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + } + } + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Load boot record and check if it is an FAT boot record */ +/*-----------------------------------------------------------------------*/ + +static +BYTE check_fs ( /* 0:The FAT BR, 1:Valid BR but not an FAT, 2:Not a BR, 3:Disk error */ + FATFS *fs, /* File system object */ + DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */ +) +{ + if (disk_read(fs->drv, fs->win, sect, 1) != RES_OK) /* Load boot record */ + return 3; + if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55) /* Check record signature (always placed at offset 510 even if the sector size is >512) */ + return 2; + + if ((LD_DWORD(&fs->win[BS_FilSysType]) & 0xFFFFFF) == 0x544146) /* Check "FAT" string */ + return 0; + if ((LD_DWORD(&fs->win[BS_FilSysType32]) & 0xFFFFFF) == 0x544146) + return 0; + + return 1; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Make sure that the file system is valid */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occurred */ + const TCHAR **path, /* Pointer to pointer to the path name (drive number) */ + FATFS **rfs, /* Pointer to pointer to the found file system object */ + BYTE chk_wp /* !=0: Check media write protection for write access */ +) +{ + BYTE fmt, b, *tbl; + UINT vol; + DSTATUS stat; + DWORD bsect, fasize, tsect, sysect, nclst, szbfat; + WORD nrsv; + const TCHAR *p = *path; + FATFS *fs; + + /* Get logical drive number from the path name */ + vol = p[0] - '0'; /* Is there a drive number? */ + if (vol <= 9 && p[1] == ':') { /* Found a drive number, get and strip it */ + p += 2; *path = p; /* Return pointer to the path name */ + } else { /* No drive number is given */ +#if _FS_RPATH + vol = Drive; /* Use current drive */ +#else + vol = 0; /* Use drive 0 */ +#endif + } + + /* Check if the logical drive is valid or not */ + if (vol >= _DRIVES) /* Is the drive number valid? */ + return FR_INVALID_DRIVE; + *rfs = fs = FatFs[vol]; /* Return pointer to the corresponding file system object */ + if (!fs) return FR_NOT_ENABLED; /* Is the file system object available? */ + + ENTER_FF(fs); /* Lock file system */ + + if (fs->fs_type) { /* If the logical drive has been mounted */ + stat = disk_status(fs->drv); + if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized (has not been changed), */ +#if !_FS_READONLY + if (chk_wp && (stat & STA_PROTECT)) /* Check write protection if needed */ + return FR_WRITE_PROTECTED; +#endif + return FR_OK; /* The file system object is valid */ + } + } + + /* The logical drive must be mounted. Following code attempts to mount the volume (initialize the file system object) */ + + fs->fs_type = 0; /* Clear the file system object */ + fs->drv = (BYTE)LD2PD(vol); /* Bind the logical drive and a physical drive */ + stat = disk_initialize(fs->drv); /* Initialize low level disk I/O layer */ + if (stat & STA_NOINIT) /* Check if the drive is ready */ + return FR_NOT_READY; +#if _MAX_SS != 512 /* Get disk sector size if needed */ + if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS) + return FR_NO_FILESYSTEM; +#endif +#if !_FS_READONLY + if (chk_wp && (stat & STA_PROTECT)) /* Check disk write protection if needed */ + return FR_WRITE_PROTECTED; +#endif + /* Search FAT partition on the drive (Supports only generic partitionings, FDISK and SFD) */ + fmt = check_fs(fs, bsect = 0); /* Check sector 0 if it is a VBR */ + if (fmt == 1) { /* Not an FAT-VBR, the disk may be partitioned */ + /* Check the partition listed in top of the partition table */ + tbl = &fs->win[MBR_Table + LD2PT(vol) * 16]; /* Partition table */ + if (tbl[4]) { /* Is the partition existing? */ + bsect = LD_DWORD(&tbl[8]); /* Partition offset in LBA */ + fmt = check_fs(fs, bsect); /* Check the partition */ + } + } + if (fmt == 3) return FR_DISK_ERR; + if (fmt) return FR_NO_FILESYSTEM; /* No FAT volume is found */ + + /* Following code initializes the file system object */ + + if (LD_WORD(fs->win+BPB_BytsPerSec) != SS(fs)) /* (BPB_BytsPerSec must be equal to the physical sector size) */ + return FR_NO_FILESYSTEM; + + fasize = LD_WORD(fs->win+BPB_FATSz16); /* Number of sectors per FAT */ + if (!fasize) fasize = LD_DWORD(fs->win+BPB_FATSz32); + fs->fsize = fasize; + + fs->n_fats = b = fs->win[BPB_NumFATs]; /* Number of FAT copies */ + if (b != 1 && b != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */ + fasize *= b; /* Number of sectors for FAT area */ + + fs->csize = b = fs->win[BPB_SecPerClus]; /* Number of sectors per cluster */ + if (!b || (b & (b - 1))) return FR_NO_FILESYSTEM; /* (Must be 1,2,4...128) */ + + fs->n_rootdir = LD_WORD(fs->win+BPB_RootEntCnt); /* Number of root directory entries */ + if (fs->n_rootdir % (SS(fs) / 32)) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be sector aligned) */ + + tsect = LD_WORD(fs->win+BPB_TotSec16); /* Number of sectors on the volume */ + if (!tsect) tsect = LD_DWORD(fs->win+BPB_TotSec32); + + nrsv = LD_WORD(fs->win+BPB_RsvdSecCnt); /* Number of reserved sectors */ + if (!nrsv) return FR_NO_FILESYSTEM; /* (BPB_RsvdSecCnt must not be 0) */ + + /* Determine the FAT sub type */ + sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / 32); /* RSV+FAT+DIR */ + if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + nclst = (tsect - sysect) / fs->csize; /* Number of clusters */ + if (!nclst) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + fmt = FS_FAT12; + if (nclst >= MIN_FAT16) fmt = FS_FAT16; + if (nclst >= MIN_FAT32) fmt = FS_FAT32; + + /* Boundaries and Limits */ + fs->n_fatent = nclst + 2; /* Number of FAT entries */ + fs->database = bsect + sysect; /* Data start sector */ + fs->fatbase = bsect + nrsv; /* FAT start sector */ + if (fmt == FS_FAT32) { + if (fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */ + fs->dirbase = LD_DWORD(fs->win+BPB_RootClus); /* Root directory start cluster */ + szbfat = fs->n_fatent * 4; /* (Required FAT size) */ + } else { + if (!fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */ + fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */ + szbfat = (fmt == FS_FAT16) ? /* (Required FAT size) */ + fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1); + } + if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) /* (FAT size must not be less than FAT sectors */ + return FR_NO_FILESYSTEM; + +#if !_FS_READONLY + /* Initialize cluster allocation information */ + fs->free_clust = 0xFFFFFFFF; + fs->last_clust = 0; + + /* Get fsinfo if available */ + if (fmt == FS_FAT32) { + fs->fsi_flag = 0; + fs->fsi_sector = bsect + LD_WORD(fs->win+BPB_FSInfo); + if (disk_read(fs->drv, fs->win, fs->fsi_sector, 1) == RES_OK && + LD_WORD(fs->win+BS_55AA) == 0xAA55 && + LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 && + LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) { + fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free); + fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count); + } + } +#endif + fs->fs_type = fmt; /* FAT sub-type */ + fs->id = ++Fsid; /* File system mount ID */ + fs->winsect = 0; /* Invalidate sector cache */ + fs->wflag = 0; +#if _FS_RPATH + fs->cdir = 0; /* Current directory (root dir) */ +#endif +#if _FS_SHARE /* Clear file lock semaphores */ + for (vol = 0; vol < _FS_SHARE; vol++) + fs->flsem[vol].ctr = 0; +#endif + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Check if the file/dir object is valid or not */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT validate ( /* FR_OK(0): The object is valid, !=0: Invalid */ + FATFS *fs, /* Pointer to the file system object */ + WORD id /* Member id of the target object to be checked */ +) +{ + if (!fs || !fs->fs_type || fs->id != id) + return FR_INVALID_OBJECT; + + ENTER_FF(fs); /* Lock file system */ + + if (disk_status(fs->drv) & STA_NOINIT) + return FR_NOT_READY; + + return FR_OK; +} + + + + +/*-------------------------------------------------------------------------- + + Public Functions + +--------------------------------------------------------------------------*/ + + + +/*-----------------------------------------------------------------------*/ +/* Mount/Unmount a Logical Drive */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mount ( + BYTE vol, /* Logical drive number to be mounted/unmounted */ + FATFS *fs /* Pointer to new file system object (NULL for unmount)*/ +) +{ + FATFS *rfs; + + + if (vol >= _DRIVES) /* Check if the drive number is valid */ + return FR_INVALID_DRIVE; + rfs = FatFs[vol]; /* Get current fs object */ + + if (rfs) { +#if _FS_REENTRANT /* Discard sync object of the current volume */ + if (!ff_del_syncobj(rfs->sobj)) return FR_INT_ERR; +#endif + rfs->fs_type = 0; /* Clear old fs object */ + } + + if (fs) { + fs->fs_type = 0; /* Clear new fs object */ +#if _FS_REENTRANT /* Create sync object for the new volume */ + if (!ff_cre_syncobj(vol, &fs->sobj)) return FR_INT_ERR; +#endif + } + FatFs[vol] = fs; /* Register new fs object */ + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Open or Create a File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_open ( + FIL *fp, /* Pointer to the blank file object */ + const TCHAR *path, /* Pointer to the file name */ + BYTE mode /* Access mode and file open mode flags */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + fp->fs = 0; /* Clear file object */ + +#if !_FS_READONLY + mode &= FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW; + res = chk_mounted(&path, &dj.fs, (BYTE)(mode & ~FA_READ)); +#else + mode &= FA_READ; + res = chk_mounted(&path, &dj.fs, 0); +#endif + INIT_BUF(dj); + if (res == FR_OK) + res = follow_path(&dj, path); /* Follow the file path */ + dir = dj.dir; + +#if !_FS_READONLY /* R/W configuration */ + if (res == FR_OK) { + if (!dir) /* Current dir itself */ + res = FR_INVALID_NAME; +#if _FS_SHARE + else + res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0); +#endif + } + /* Create or Open a file */ + if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) { + DWORD dw, cl; + + if (res != FR_OK) { /* No file, create new */ + if (res == FR_NO_FILE) /* There is no file to open, create a new entry */ +#if _FS_SHARE + res = enq_lock(dj.fs) ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES; +#else + res = dir_register(&dj); +#endif + mode |= FA_CREATE_ALWAYS; + dir = dj.dir; /* New entry */ + } + else { /* Any object is already existing */ + if (mode & FA_CREATE_NEW) { /* Cannot create new */ + res = FR_EXIST; + } else { + if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) /* Cannot overwrite it (R/O or DIR) */ + res = FR_DENIED; + } + } + if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */ + dw = get_fattime(); /* Created time */ + ST_DWORD(dir+DIR_CrtTime, dw); + dir[DIR_Attr] = 0; /* Reset attribute */ + ST_DWORD(dir+DIR_FileSize, 0); /* size = 0 */ + cl = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); /* Get start cluster */ + ST_WORD(dir+DIR_FstClusHI, 0); /* cluster = 0 */ + ST_WORD(dir+DIR_FstClusLO, 0); + dj.fs->wflag = 1; + if (cl) { /* Remove the cluster chain if exist */ + dw = dj.fs->winsect; + res = remove_chain(dj.fs, cl); + if (res == FR_OK) { + dj.fs->last_clust = cl - 1; /* Reuse the cluster hole */ + res = move_window(dj.fs, dw); + } + } + } + } + else { /* Open an existing file */ + if (res == FR_OK) { /* Follow succeeded */ + if (dir[DIR_Attr] & AM_DIR) { /* It is a directory */ + res = FR_NO_FILE; + } else { + if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */ + res = FR_DENIED; + } + } + } + if (res == FR_OK) { + if (mode & (FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) + mode |= FA__WRITTEN; /* Set file changed flag */ + fp->dir_sect = dj.fs->winsect; /* Pointer to the directory entry */ + fp->dir_ptr = dir; +#if _FS_SHARE + fp->lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0); + if (!fp->lockid) res = FR_INT_ERR; +#endif + } + +#else /* R/O configuration */ + if (res == FR_OK) { /* Follow succeeded */ + if (!dir) { /* Current dir itself */ + res = FR_INVALID_NAME; + } else { + if (dir[DIR_Attr] & AM_DIR) /* It is a directory */ + res = FR_NO_FILE; + } + } +#endif + FREE_BUF(); + + if (res == FR_OK) { + fp->flag = mode; /* File access mode */ + fp->org_clust = /* File start cluster */ + ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + fp->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */ + fp->fptr = 0; /* File pointer */ + fp->dsect = 0; +#if _USE_FASTSEEK + fp->cltbl = 0; /* No cluster link map table */ +#endif + fp->fs = dj.fs; fp->id = dj.fs->id; /* Validate file object */ + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_read ( + FIL *fp, /* Pointer to the file object */ + void *buff, /* Pointer to data buffer */ + UINT btr, /* Number of bytes to read */ + UINT *br /* Pointer to number of bytes read */ +) +{ + FRESULT res; + DWORD clst, sect, remain; + UINT rcnt, cc; + BYTE csect, *rbuff = buff; + + + *br = 0; /* Initialize byte counter */ + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_READ)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + remain = fp->fsize - fp->fptr; + if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ + + for ( ; btr; /* Repeat until all data transferred */ + rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if (!csect) { /* On the cluster boundary? */ + clst = (fp->fptr == 0) ? /* On the top of the file? */ + fp->org_clust : get_fat(fp->fs, fp->curr_clust); + if (clst <= 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->curr_clust = clst; /* Update current cluster */ + } + sect = clust2sect(fp->fs, fp->curr_clust); /* Get current sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + cc = btr / SS(fp->fs); /* When remaining bytes >= sector size, */ + if (cc) { /* Read maximum contiguous sectors directly */ + if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */ + cc = fp->fs->csize - csect; + if (disk_read(fp->fs->drv, rbuff, sect, (BYTE)cc) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#if !_FS_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */ +#if _FS_TINY + if (fp->fs->wflag && fp->fs->winsect - sect < cc) + mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs)); +#else + if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc) + mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs)); +#endif +#endif + rcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ + continue; + } +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Write sector I/O buffer if needed */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (fp->dsect != sect) { /* Fill sector buffer with file data */ + if (disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + } +#endif + fp->dsect = sect; + } + rcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs)); /* Get partial sector data from sector buffer */ + if (rcnt > btr) rcnt = btr; +#if _FS_TINY + if (move_window(fp->fs, fp->dsect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ +#else + mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ +#endif + } + + LEAVE_FF(fp->fs, FR_OK); +} + + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Write File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_write ( + FIL *fp, /* Pointer to the file object */ + const void *buff, /* Pointer to the data to be written */ + UINT btw, /* Number of bytes to write */ + UINT *bw /* Pointer to number of bytes written */ +) +{ + FRESULT res; + DWORD clst, sect; + UINT wcnt, cc; + const BYTE *wbuff = buff; + BYTE csect; + + + *bw = 0; /* Initialize byte counter */ + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_WRITE)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + if (fp->fsize + btw < fp->fsize) btw = 0; /* File size cannot reach 4GB */ + + for ( ; btw; /* Repeat until all data transferred */ + wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if (!csect) { /* On the cluster boundary? */ + if (fp->fptr == 0) { /* On the top of the file? */ + clst = fp->org_clust; /* Follow from the origin */ + if (clst == 0) /* When there is no cluster chain, */ + fp->org_clust = clst = create_chain(fp->fs, 0); /* Create a new cluster chain */ + } else { /* Middle or end of the file */ + clst = create_chain(fp->fs, fp->curr_clust); /* Follow or stretch cluster chain */ + } + if (clst == 0) break; /* Could not allocate a new cluster (disk full) */ + if (clst == 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->curr_clust = clst; /* Update current cluster */ + } +#if _FS_TINY + if (fp->fs->winsect == fp->dsect && move_window(fp->fs, 0)) /* Write back data buffer prior to following direct transfer */ + ABORT(fp->fs, FR_DISK_ERR); +#else + if (fp->flag & FA__DIRTY) { /* Write back data buffer prior to following direct transfer */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + sect = clust2sect(fp->fs, fp->curr_clust); /* Get current sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + cc = btw / SS(fp->fs); /* When remaining bytes >= sector size, */ + if (cc) { /* Write maximum contiguous sectors directly */ + if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */ + cc = fp->fs->csize - csect; + if (disk_write(fp->fs->drv, wbuff, sect, (BYTE)cc) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#if _FS_TINY + if (fp->fs->winsect - sect < cc) { /* Refill sector cache if it gets dirty by the direct write */ + mem_cpy(fp->fs->win, wbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), SS(fp->fs)); + fp->fs->wflag = 0; + } +#else + if (fp->dsect - sect < cc) { /* Refill sector cache if it gets dirty by the direct write */ + mem_cpy(fp->buf, wbuff + ((fp->dsect - sect) * SS(fp->fs)), SS(fp->fs)); + fp->flag &= ~FA__DIRTY; + } +#endif + wcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ + continue; + } +#if _FS_TINY + if (fp->fptr >= fp->fsize) { /* Avoid silly buffer filling at growing edge */ + if (move_window(fp->fs, 0)) ABORT(fp->fs, FR_DISK_ERR); + fp->fs->winsect = sect; + } +#else + if (fp->dsect != sect) { /* Fill sector buffer with file data */ + if (fp->fptr < fp->fsize && + disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + } +#endif + fp->dsect = sect; + } + wcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs)); /* Put partial sector into file I/O buffer */ + if (wcnt > btw) wcnt = btw; +#if _FS_TINY + if (move_window(fp->fs, fp->dsect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + mem_cpy(&fp->fs->win[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */ + fp->fs->wflag = 1; +#else + mem_cpy(&fp->buf[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */ + fp->flag |= FA__DIRTY; +#endif + } + + if (fp->fptr > fp->fsize) fp->fsize = fp->fptr; /* Update file size if needed */ + fp->flag |= FA__WRITTEN; /* Set file changed flag */ + + LEAVE_FF(fp->fs, FR_OK); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Synchronize the File Object */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_sync ( + FIL *fp /* Pointer to the file object */ +) +{ + FRESULT res; + DWORD tim; + BYTE *dir; + + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res == FR_OK) { + if (fp->flag & FA__WRITTEN) { /* Has the file been written? */ +#if !_FS_TINY /* Write-back dirty buffer */ + if (fp->flag & FA__DIRTY) { + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + LEAVE_FF(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + /* Update the directory entry */ + res = move_window(fp->fs, fp->dir_sect); + if (res == FR_OK) { + dir = fp->dir_ptr; + dir[DIR_Attr] |= AM_ARC; /* Set archive bit */ + ST_DWORD(dir+DIR_FileSize, fp->fsize); /* Update file size */ + ST_WORD(dir+DIR_FstClusLO, fp->org_clust); /* Update start cluster */ + ST_WORD(dir+DIR_FstClusHI, fp->org_clust >> 16); + tim = get_fattime(); /* Update updated time */ + ST_DWORD(dir+DIR_WrtTime, tim); + fp->flag &= ~FA__WRITTEN; + fp->fs->wflag = 1; + res = sync(fp->fs); + } + } + } + + LEAVE_FF(fp->fs, res); +} + +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Close File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_close ( + FIL *fp /* Pointer to the file object to be closed */ +) +{ + FRESULT res; + +#if _FS_READONLY + FATFS *fs = fp->fs; + res = validate(fs, fp->id); + if (res == FR_OK) fp->fs = 0; /* Discard file object */ + LEAVE_FF(fs, res); + +#else + res = f_sync(fp); /* Flush cached data */ +#if _FS_SHARE + if (res == FR_OK) { /* Decrement open counter */ +#if _FS_REENTRANT + res = validate(fp->fs, fp->id); + if (res == FR_OK) { + res = dec_lock(fp->fs, fp->lockid); + unlock_fs(fp->fs, FR_OK); + } +#else + res = dec_lock(fp->fs, fp->lockid); +#endif + } +#endif + if (res == FR_OK) fp->fs = 0; /* Discard file object */ + return res; +#endif +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Current Drive/Directory */ +/*-----------------------------------------------------------------------*/ + +#if _FS_RPATH + +FRESULT f_chdrive ( + BYTE drv /* Drive number */ +) +{ + if (drv >= _DRIVES) return FR_INVALID_DRIVE; + + Drive = drv; + + return FR_OK; +} + + + + +FRESULT f_chdir ( + const TCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 0); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the path */ + FREE_BUF(); + if (res == FR_OK) { /* Follow completed */ + dir = dj.dir; /* Pointer to the entry */ + if (!dir) { + dj.fs->cdir = dj.sclust; /* Start directory itself */ + } else { + if (dir[DIR_Attr] & AM_DIR) /* Reached to the directory */ + dj.fs->cdir = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + else + res = FR_NO_PATH; /* Reached but a file */ + } + } + if (res == FR_NO_FILE) res = FR_NO_PATH; + } + + LEAVE_FF(dj.fs, res); +} + +#endif + + + +#if _FS_MINIMIZE <= 2 +/*-----------------------------------------------------------------------*/ +/* Seek File R/W Pointer */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_lseek ( + FIL *fp, /* Pointer to the file object */ + DWORD ofs /* File pointer from top of file */ +) +{ + FRESULT res; + + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + +#if _USE_FASTSEEK + if (fp->cltbl) { /* Fast seek */ + DWORD cl, pcl, ncl, tcl, dsc, tlen, *tbl = fp->cltbl; + BYTE csc; + + tlen = *tbl++; + if (ofs == CREATE_LINKMAP) { /* Create link map table */ + cl = fp->org_clust; + if (cl) { + do { + if (tlen < 4) { /* Not enough table items */ + res = FR_NOT_ENOUGH_CORE; break; + } + tcl = cl; ncl = 0; + do { /* Get a fragment and store the top and length */ + pcl = cl; ncl++; + cl = get_fat(fp->fs, cl); + if (cl <= 1) ABORT(fp->fs, FR_INT_ERR); + if (cl == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + } while (cl == pcl + 1); + *tbl++ = ncl; *tbl++ = tcl; + tlen -= 2; + } while (cl < fp->fs->n_fatent); + } + *tbl = 0; /* Terminate table */ + + } else { /* Fast seek */ + if (ofs > fp->fsize) /* Clip offset at the file size */ + ofs = fp->fsize; + fp->fptr = ofs; /* Set file pointer */ + if (ofs) { + dsc = (ofs - 1) / SS(fp->fs); + cl = dsc / fp->fs->csize; + for (;;) { + ncl = *tbl++; + if (!ncl) ABORT(fp->fs, FR_INT_ERR); + if (cl < ncl) break; + cl -= ncl; tbl++; + } + fp->curr_clust = cl + *tbl; + csc = (BYTE)(dsc & (fp->fs->csize - 1)); + dsc = clust2sect(fp->fs, fp->curr_clust); + if (!dsc) ABORT(fp->fs, FR_INT_ERR); + dsc += csc; + if (fp->fptr % SS(fp->fs) && dsc != fp->dsect) { +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Flush dirty buffer if needed */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (disk_read(fp->fs->drv, fp->buf, dsc, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#endif + fp->dsect = dsc; + } + } + } + } else +#endif + + /* Normal Seek */ + { + DWORD clst, bcs, nsect, ifptr; + + if (ofs > fp->fsize /* In read-only mode, clip offset with the file size */ +#if !_FS_READONLY + && !(fp->flag & FA_WRITE) +#endif + ) ofs = fp->fsize; + + ifptr = fp->fptr; + fp->fptr = nsect = 0; + if (ofs) { + bcs = (DWORD)fp->fs->csize * SS(fp->fs); /* Cluster size (byte) */ + if (ifptr > 0 && + (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */ + fp->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */ + ofs -= fp->fptr; + clst = fp->curr_clust; + } else { /* When seek to back cluster, */ + clst = fp->org_clust; /* start from the first cluster */ +#if !_FS_READONLY + if (clst == 0) { /* If no cluster chain, create a new chain */ + clst = create_chain(fp->fs, 0); + if (clst == 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->org_clust = clst; + } +#endif + fp->curr_clust = clst; + } + if (clst != 0) { + while (ofs > bcs) { /* Cluster following loop */ +#if !_FS_READONLY + if (fp->flag & FA_WRITE) { /* Check if in write mode or not */ + clst = create_chain(fp->fs, clst); /* Force stretch if in write mode */ + if (clst == 0) { /* When disk gets full, clip file size */ + ofs = bcs; break; + } + } else +#endif + clst = get_fat(fp->fs, clst); /* Follow cluster chain if not in write mode */ + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + if (clst <= 1 || clst >= fp->fs->n_fatent) ABORT(fp->fs, FR_INT_ERR); + fp->curr_clust = clst; + fp->fptr += bcs; + ofs -= bcs; + } + fp->fptr += ofs; + if (ofs % SS(fp->fs)) { + nsect = clust2sect(fp->fs, clst); /* Current sector */ + if (!nsect) ABORT(fp->fs, FR_INT_ERR); + nsect += ofs / SS(fp->fs); + } + } + } + if (fp->fptr % SS(fp->fs) && nsect != fp->dsect) { +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Flush dirty buffer if needed */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (disk_read(fp->fs->drv, fp->buf, nsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#endif + fp->dsect = nsect; + } +#if !_FS_READONLY + if (fp->fptr > fp->fsize) { /* Set changed flag if the file size is extended */ + fp->fsize = fp->fptr; + fp->flag |= FA__WRITTEN; + } +#endif + } + + LEAVE_FF(fp->fs, res); +} + + + +#if _FS_MINIMIZE <= 1 +/*-----------------------------------------------------------------------*/ +/* Create a Directroy Object */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_opendir ( + DIR *dj, /* Pointer to directory object to create */ + const TCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + BYTE *dir; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj->fs, 0); + if (res == FR_OK) { + INIT_BUF(*dj); + res = follow_path(dj, path); /* Follow the path to the directory */ + FREE_BUF(); + if (res == FR_OK) { /* Follow completed */ + dir = dj->dir; + if (dir) { /* It is not the current dir */ + if (dir[DIR_Attr] & AM_DIR) { /* The object is a directory */ + dj->sclust = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + } else { /* The object is not a directory */ + res = FR_NO_PATH; + } + } + if (res == FR_OK) { + dj->id = dj->fs->id; + res = dir_sdi(dj, 0); /* Rewind dir */ + } + } + if (res == FR_NO_FILE) res = FR_NO_PATH; + } + + LEAVE_FF(dj->fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read Directory Entry in Sequense */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_readdir ( + DIR *dj, /* Pointer to the open directory object */ + FILINFO *fno /* Pointer to file information to return */ +) +{ + FRESULT res; + DEF_NAMEBUF; + + + res = validate(dj->fs, dj->id); /* Check validity of the object */ + if (res == FR_OK) { + if (!fno) { + res = dir_sdi(dj, 0); + } else { + INIT_BUF(*dj); + res = dir_read(dj); + if (res == FR_NO_FILE) { + dj->sect = 0; + res = FR_OK; + } + if (res == FR_OK) { /* A valid entry is found */ + get_fileinfo(dj, fno); /* Get the object information */ + res = dir_next(dj, 0); /* Increment index for next */ + if (res == FR_NO_FILE) { + dj->sect = 0; + res = FR_OK; + } + } + FREE_BUF(); + } + } + + LEAVE_FF(dj->fs, res); +} + + + +#if _FS_MINIMIZE == 0 +/*-----------------------------------------------------------------------*/ +/* Get File Status */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_stat ( + const TCHAR *path, /* Pointer to the file path */ + FILINFO *fno /* Pointer to file information to return */ +) +{ + FRESULT res; + DIR dj; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 0); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) { /* Follow completed */ + if (dj.dir) /* Found an object */ + get_fileinfo(&dj, fno); + else /* It is root dir */ + res = FR_INVALID_NAME; + } + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Get Number of Free Clusters */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_getfree ( + const TCHAR *path, /* Pointer to the logical drive number (root dir) */ + DWORD *nclst, /* Pointer to the variable to return number of free clusters */ + FATFS **fatfs /* Pointer to pointer to corresponding file system object to return */ +) +{ + FRESULT res; + DWORD n, clst, sect, stat; + UINT i; + BYTE fat, *p; + + + /* Get drive number */ + res = chk_mounted(&path, fatfs, 0); + if (res == FR_OK) { + /* If free_clust is valid, return it without full cluster scan */ + if ((*fatfs)->free_clust <= (*fatfs)->n_fatent - 2) { + *nclst = (*fatfs)->free_clust; + } else { + /* Get number of free clusters */ + fat = (*fatfs)->fs_type; + n = 0; + if (fat == FS_FAT12) { + clst = 2; + do { + stat = get_fat(*fatfs, clst); + if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } + if (stat == 1) { res = FR_INT_ERR; break; } + if (stat == 0) n++; + } while (++clst < (*fatfs)->n_fatent); + } else { + clst = (*fatfs)->n_fatent; + sect = (*fatfs)->fatbase; + i = 0; p = 0; + do { + if (!i) { + res = move_window(*fatfs, sect++); + if (res != FR_OK) break; + p = (*fatfs)->win; + i = SS(*fatfs); + } + if (fat == FS_FAT16) { + if (LD_WORD(p) == 0) n++; + p += 2; i -= 2; + } else { + if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) n++; + p += 4; i -= 4; + } + } while (--clst); + } + (*fatfs)->free_clust = n; + if (fat == FS_FAT32) (*fatfs)->fsi_flag = 1; + *nclst = n; + } + } + LEAVE_FF(*fatfs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Truncate File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_truncate ( + FIL *fp /* Pointer to the file object */ +) +{ + FRESULT res; + DWORD ncl; + + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res == FR_OK) { + if (fp->flag & FA__ERROR) { /* Check abort flag */ + res = FR_INT_ERR; + } else { + if (!(fp->flag & FA_WRITE)) /* Check access mode */ + res = FR_DENIED; + } + } + if (res == FR_OK) { + if (fp->fsize > fp->fptr) { + fp->fsize = fp->fptr; /* Set file size to current R/W point */ + fp->flag |= FA__WRITTEN; + if (fp->fptr == 0) { /* When set file size to zero, remove entire cluster chain */ + res = remove_chain(fp->fs, fp->org_clust); + fp->org_clust = 0; + } else { /* When truncate a part of the file, remove remaining clusters */ + ncl = get_fat(fp->fs, fp->curr_clust); + res = FR_OK; + if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR; + if (ncl == 1) res = FR_INT_ERR; + if (res == FR_OK && ncl < fp->fs->n_fatent) { + res = put_fat(fp->fs, fp->curr_clust, 0x0FFFFFFF); + if (res == FR_OK) res = remove_chain(fp->fs, ncl); + } + } + } + if (res != FR_OK) fp->flag |= FA__ERROR; + } + + LEAVE_FF(fp->fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Delete a File or Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_unlink ( + const TCHAR *path /* Pointer to the file or directory path */ +) +{ + FRESULT res; + DIR dj, sdj; + BYTE *dir; + DWORD dclst; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; /* Cannot remove dot entry */ +#if _FS_SHARE + if (res == FR_OK) res = chk_lock(&dj, 2); /* Cannot remove open file */ +#endif + if (res == FR_OK) { /* The object is accessible */ + dir = dj.dir; + if (!dir) { + res = FR_INVALID_NAME; /* Cannot remove the start directory */ + } else { + if (dir[DIR_Attr] & AM_RDO) + res = FR_DENIED; /* Cannot remove R/O object */ + } + dclst = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + if (res == FR_OK && (dir[DIR_Attr] & AM_DIR)) { /* Is it a sub-dir? */ + if (dclst < 2) { + res = FR_INT_ERR; + } else { + mem_cpy(&sdj, &dj, sizeof(DIR)); /* Check if the sub-dir is empty or not */ + sdj.sclust = dclst; + res = dir_sdi(&sdj, 2); /* Exclude dot entries */ + if (res == FR_OK) { + res = dir_read(&sdj); + if (res == FR_OK /* Not empty dir */ +#if _FS_RPATH + || dclst == sdj.fs->cdir /* Current dir */ +#endif + ) res = FR_DENIED; + if (res == FR_NO_FILE) res = FR_OK; /* Empty */ + } + } + } + if (res == FR_OK) { + res = dir_remove(&dj); /* Remove the directory entry */ + if (res == FR_OK) { + if (dclst) /* Remove the cluster chain if exist */ + res = remove_chain(dj.fs, dclst); + if (res == FR_OK) res = sync(dj.fs); + } + } + } + FREE_BUF(); + } + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Create a Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mkdir ( + const TCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir, n; + DWORD dsc, dcl, pcl, tim = get_fattime(); + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) res = FR_EXIST; /* Any object with same name is already existing */ + if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_NO_FILE) { /* Can create a new directory */ + dcl = create_chain(dj.fs, 0); /* Allocate a cluster for the new directory table */ + res = FR_OK; + if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster */ + if (dcl == 1) res = FR_INT_ERR; + if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR; + if (res == FR_OK) /* Flush FAT */ + res = move_window(dj.fs, 0); + if (res == FR_OK) { /* Initialize the new directory table */ + dsc = clust2sect(dj.fs, dcl); + dir = dj.fs->win; + mem_set(dir, 0, SS(dj.fs)); + mem_set(dir+DIR_Name, ' ', 8+3); /* Create "." entry */ + dir[DIR_Name] = '.'; + dir[DIR_Attr] = AM_DIR; + ST_DWORD(dir+DIR_WrtTime, tim); + ST_WORD(dir+DIR_FstClusLO, dcl); + ST_WORD(dir+DIR_FstClusHI, dcl >> 16); + mem_cpy(dir+32, dir, 32); /* Create ".." entry */ + dir[33] = '.'; pcl = dj.sclust; + if (dj.fs->fs_type == FS_FAT32 && pcl == dj.fs->dirbase) + pcl = 0; + ST_WORD(dir+32+DIR_FstClusLO, pcl); + ST_WORD(dir+32+DIR_FstClusHI, pcl >> 16); + for (n = dj.fs->csize; n; n--) { /* Write dot entries and clear following sectors */ + dj.fs->winsect = dsc++; + dj.fs->wflag = 1; + res = move_window(dj.fs, 0); + if (res != FR_OK) break; + mem_set(dir, 0, SS(dj.fs)); + } + } + if (res == FR_OK) res = dir_register(&dj); /* Register the object to the directoy */ + if (res != FR_OK) { + remove_chain(dj.fs, dcl); /* Could not register, remove cluster chain */ + } else { + dir = dj.dir; + dir[DIR_Attr] = AM_DIR; /* Attribute */ + ST_DWORD(dir+DIR_WrtTime, tim); /* Created time */ + ST_WORD(dir+DIR_FstClusLO, dcl); /* Table start cluster */ + ST_WORD(dir+DIR_FstClusHI, dcl >> 16); + dj.fs->wflag = 1; + res = sync(dj.fs); + } + } + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Attribute */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_chmod ( + const TCHAR *path, /* Pointer to the file path */ + BYTE value, /* Attribute bits */ + BYTE mask /* Attribute mask to change */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + FREE_BUF(); + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_OK) { + dir = dj.dir; + if (!dir) { /* Is it a root directory? */ + res = FR_INVALID_NAME; + } else { /* File or sub directory */ + mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */ + dir[DIR_Attr] = (value & mask) | (dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */ + dj.fs->wflag = 1; + res = sync(dj.fs); + } + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Timestamp */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_utime ( + const TCHAR *path, /* Pointer to the file/directory name */ + const FILINFO *fno /* Pointer to the time stamp to be set */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + FREE_BUF(); + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_OK) { + dir = dj.dir; + if (!dir) { /* Root directory */ + res = FR_INVALID_NAME; + } else { /* File or sub-directory */ + ST_WORD(dir+DIR_WrtTime, fno->ftime); + ST_WORD(dir+DIR_WrtDate, fno->fdate); + dj.fs->wflag = 1; + res = sync(dj.fs); + } + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Rename File/Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_rename ( + const TCHAR *path_old, /* Pointer to the old name */ + const TCHAR *path_new /* Pointer to the new name */ +) +{ + FRESULT res; + DIR djo, djn; + BYTE buf[21], *dir; + DWORD dw; + DEF_NAMEBUF; + + + res = chk_mounted(&path_old, &djo.fs, 1); + if (res == FR_OK) { + djn.fs = djo.fs; + INIT_BUF(djo); + res = follow_path(&djo, path_old); /* Check old object */ + if (_FS_RPATH && res == FR_OK && (djo.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; +#if _FS_SHARE + if (res == FR_OK) res = chk_lock(&djo, 2); +#endif + if (res == FR_OK) { /* Old object is found */ + if (!djo.dir) { /* Is root dir? */ + res = FR_NO_FILE; + } else { + mem_cpy(buf, djo.dir+DIR_Attr, 21); /* Save the object information except for name */ + mem_cpy(&djn, &djo, sizeof(DIR)); /* Check new object */ + res = follow_path(&djn, path_new); + if (res == FR_OK) res = FR_EXIST; /* The new object name is already existing */ + if (res == FR_NO_FILE) { /* Is it a valid path and no name collision? */ +/* Start critical section that any interruption or error can cause cross-link */ + res = dir_register(&djn); /* Register the new entry */ + if (res == FR_OK) { + dir = djn.dir; /* Copy object information except for name */ + mem_cpy(dir+13, buf+2, 19); + dir[DIR_Attr] = buf[0] | AM_ARC; + djo.fs->wflag = 1; + if (djo.sclust != djn.sclust && (dir[DIR_Attr] & AM_DIR)) { /* Update .. entry in the directory if needed */ + dw = clust2sect(djn.fs, (DWORD)LD_WORD(dir+DIR_FstClusHI) | LD_WORD(dir+DIR_FstClusLO)); + if (!dw) { + res = FR_INT_ERR; + } else { + res = move_window(djn.fs, dw); + dir = djn.fs->win+32; /* .. entry */ + if (res == FR_OK && dir[1] == '.') { + dw = (djn.fs->fs_type == FS_FAT32 && djn.sclust == djn.fs->dirbase) ? 0 : djn.sclust; + ST_WORD(dir+DIR_FstClusLO, dw); + ST_WORD(dir+DIR_FstClusHI, dw >> 16); + djn.fs->wflag = 1; + } + } + } + if (res == FR_OK) { + res = dir_remove(&djo); /* Remove old entry */ + if (res == FR_OK) + res = sync(djo.fs); + } + } +/* End critical section */ + } + } + } + FREE_BUF(); + } + LEAVE_FF(djo.fs, res); +} + +#endif /* !_FS_READONLY */ +#endif /* _FS_MINIMIZE == 0 */ +#endif /* _FS_MINIMIZE <= 1 */ +#endif /* _FS_MINIMIZE <= 2 */ + + + +/*-----------------------------------------------------------------------*/ +/* Forward data to the stream directly (available on only tiny cfg) */ +/*-----------------------------------------------------------------------*/ +#if _USE_FORWARD && _FS_TINY + +FRESULT f_forward ( + FIL *fp, /* Pointer to the file object */ + UINT (*func)(const BYTE*,UINT), /* Pointer to the streaming function */ + UINT btr, /* Number of bytes to forward */ + UINT *bf /* Pointer to number of bytes forwarded */ +) +{ + FRESULT res; + DWORD remain, clst, sect; + UINT rcnt; + BYTE csect; + + + *bf = 0; /* Initialize byte counter */ + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check error flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_READ)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + + remain = fp->fsize - fp->fptr; + if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ + + for ( ; btr && (*func)(0, 0); /* Repeat until all data transferred or stream becomes busy */ + fp->fptr += rcnt, *bf += rcnt, btr -= rcnt) { + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + if (!csect) { /* On the cluster boundary? */ + clst = (fp->fptr == 0) ? /* On the top of the file? */ + fp->org_clust : get_fat(fp->fs, fp->curr_clust); + if (clst <= 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->curr_clust = clst; /* Update current cluster */ + } + } + sect = clust2sect(fp->fs, fp->curr_clust); /* Get current data sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + if (move_window(fp->fs, sect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + fp->dsect = sect; + rcnt = SS(fp->fs) - (WORD)(fp->fptr % SS(fp->fs)); /* Forward data from sector window */ + if (rcnt > btr) rcnt = btr; + rcnt = (*func)(&fp->fs->win[(WORD)fp->fptr % SS(fp->fs)], rcnt); + if (!rcnt) ABORT(fp->fs, FR_INT_ERR); + } + + LEAVE_FF(fp->fs, FR_OK); +} +#endif /* _USE_FORWARD */ + + + +#if _USE_MKFS && !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Create File System on the Drive */ +/*-----------------------------------------------------------------------*/ +#define N_ROOTDIR 512 /* Multiple of 32 */ +#define N_FATS 1 /* 1 or 2 */ + + +FRESULT f_mkfs ( + BYTE drv, /* Logical drive number */ + BYTE sfd, /* Partitioning rule 0:FDISK, 1:SFD */ + UINT au /* Allocation unit size [bytes] */ +) +{ + static const WORD vst[] = { 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 0}; + static const WORD cst[] = {32768, 16384, 8192, 4096, 2048, 16384, 8192, 4096, 2048, 1024, 512}; + BYTE fmt, md, *tbl; + DWORD n_clst, vs, n; + UINT as, i; + DWORD b_vol, b_fat, b_dir, b_data; /* Area offset (LBA) */ + DWORD n_vol, n_rsv, n_fat, n_dir; /* Area size */ + FATFS *fs; + DSTATUS stat; + + + /* Check mounted drive and clear work area */ + if (drv >= _DRIVES) return FR_INVALID_DRIVE; + fs = FatFs[drv]; + if (!fs) return FR_NOT_ENABLED; + fs->fs_type = 0; + drv = LD2PD(drv); + + /* Get disk statics */ + stat = disk_initialize(drv); + if (stat & STA_NOINIT) return FR_NOT_READY; + if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; +#if _MAX_SS != 512 /* Get disk sector size */ + if (disk_ioctl(drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS) + return FR_DISK_ERR; +#endif + if (disk_ioctl(drv, GET_SECTOR_COUNT, &n_vol) != RES_OK || n_vol < 128) + return FR_DISK_ERR; + b_vol = (sfd == 1) ? 0 : 63; /* Volume start sector */ + n_vol -= b_vol; + if (au & (au - 1)) au = 0; /* Check validity of the allocation unit size */ + if (!au) { /* AU auto selection */ + vs = n_vol / (2000 / (SS(fs) / 512)); + for (i = 0; vs < vst[i]; i++) ; + au = cst[i]; + } + if (_MAX_SS != 512 && au < SS(fs)) au = SS(fs); + au /= SS(fs); /* Number of sectors per cluster */ + if (au == 0) au = 1; + if (au > 128) au = 128; + + /* Pre-compute number of clusters and FAT syb-type */ + n_clst = n_vol / au; + fmt = FS_FAT12; + if (n_clst >= MIN_FAT16) fmt = FS_FAT16; + if (n_clst >= MIN_FAT32) fmt = FS_FAT32; + + /* Determine offset and size of FAT structure */ + if (fmt == FS_FAT32) { + n_fat = ((n_clst * 4) + 8 + SS(fs) - 1) / SS(fs); + n_rsv = 32; + n_dir = 0; + } else { + n_fat = (fmt == FS_FAT12) ? (n_clst * 3 + 1) / 2 + 3 : (n_clst * 2) + 4; + n_fat = (n_fat + SS(fs) - 1) / SS(fs); + n_rsv = 1; + n_dir = N_ROOTDIR * 32UL / SS(fs); + } + b_fat = b_vol + n_rsv; /* FAT area start sector */ + b_dir = b_fat + n_fat * N_FATS; /* Directory area start sector */ + b_data = b_dir + n_dir; /* Data area start sector */ + if (n_vol < b_data + au) return FR_MKFS_ABORTED; /* Too small volume */ + + /* Align data start sector to erase block boundary (for flash memory media) */ + if (disk_ioctl(drv, GET_BLOCK_SIZE, &n) != RES_OK) return FR_DISK_ERR; + if (!n || n > 32768) return FR_MKFS_ABORTED; + n = (b_data + n - 1) & ~(n - 1); /* Next nearest boundary from current data start */ + n = (n - b_data) / N_FATS; + if (fmt == FS_FAT32) { /* FAT32: Move FAT start */ + n_rsv += n; + b_fat += n; + } else { /* FAT12/16: Expand FAT size */ + n_fat += n; + } + /* b_dir and b_data are no longer used below */ + + /* Determine number of cluster and final check of validity of the FAT sub-type */ + n_clst = (n_vol - n_rsv - n_fat * N_FATS - n_dir) / au; + if ( (fmt == FS_FAT16 && n_clst < MIN_FAT16) + || (fmt == FS_FAT32 && n_clst < MIN_FAT32)) + return FR_MKFS_ABORTED; + + /* Create partition table if required */ + if (sfd == 1) { + md = 0xF0; + } else { + DWORD n_disk = b_vol + n_vol; + + mem_set(fs->win, 0, SS(fs)); + tbl = fs->win+MBR_Table; + ST_DWORD(tbl, 0x00010180); /* Partition start in CHS */ + if (n_disk < 63UL * 255 * 1024) { /* Partition end in CHS */ + n_disk = n_disk / 63 / 255; + tbl[7] = (BYTE)n_disk; + tbl[6] = (BYTE)((n_disk >> 2) | 63); + } else { + ST_WORD(&tbl[6], 0xFFFF); + } + tbl[5] = 254; + if (fmt != FS_FAT32) /* System ID */ + tbl[4] = (n_vol < 0x10000) ? 0x04 : 0x06; + else + tbl[4] = 0x0c; + ST_DWORD(tbl+8, 63); /* Partition start in LBA */ + ST_DWORD(tbl+12, n_vol); /* Partition size in LBA */ + ST_WORD(tbl+64, 0xAA55); /* Signature */ + if (disk_write(drv, fs->win, 0, 1) != RES_OK) + return FR_DISK_ERR; + md = 0xF8; + } + + /* Create VBR */ + tbl = fs->win; /* Clear buffer */ + mem_set(tbl, 0, SS(fs)); + ST_DWORD(tbl+BS_jmpBoot, 0x90FEEB); /* Boot code (jmp $, nop) */ + as = SS(fs); /* Sector size */ + ST_WORD(tbl+BPB_BytsPerSec, as); + tbl[BPB_SecPerClus] = (BYTE)au; /* Sectors per cluster */ + ST_WORD(tbl+BPB_RsvdSecCnt, n_rsv); /* Reserved sectors */ + tbl[BPB_NumFATs] = N_FATS; /* Number of FATs */ + as = (fmt == FS_FAT32) ? 0 : N_ROOTDIR; /* Number of rootdir entries */ + ST_WORD(tbl+BPB_RootEntCnt, as); + if (n_vol < 0x10000) { /* Number of total sectors */ + ST_WORD(tbl+BPB_TotSec16, n_vol); + } else { + ST_DWORD(tbl+BPB_TotSec32, n_vol); + } + tbl[BPB_Media] = md; /* Media descriptor */ + ST_WORD(tbl+BPB_SecPerTrk, 63); /* Number of sectors per track */ + ST_WORD(tbl+BPB_NumHeads, 255); /* Number of heads */ + ST_DWORD(tbl+BPB_HiddSec, b_vol); /* Hidden sectors */ + n = get_fattime(); /* Use current time as VSN */ + if (fmt == FS_FAT32) { + ST_DWORD(tbl+BS_VolID32, n); /* VSN */ + ST_DWORD(tbl+BPB_FATSz32, n_fat); /* Number of sectors per FAT */ + ST_DWORD(tbl+BPB_RootClus, 2); /* Root directory start cluster (2) */ + ST_WORD(tbl+BPB_FSInfo, 1); /* FSInfo record offset (VBR+1) */ + ST_WORD(tbl+BPB_BkBootSec, 6); /* Backup boot record offset (VBR+6) */ + tbl[BS_DrvNum32] = 0x80; /* Drive number */ + tbl[BS_BootSig32] = 0x29; /* Extended boot signature */ + mem_cpy(tbl+BS_VolLab32, "NO NAME FAT32 ", 19); /* Volume label, FAT signature */ + } else { + ST_DWORD(tbl+BS_VolID, n); /* VSN */ + ST_WORD(tbl+BPB_FATSz16, n_fat); /* Number of sectors per FAT */ + tbl[BS_DrvNum] = 0x80; /* Drive number */ + tbl[BS_BootSig] = 0x29; /* Extended boot signature */ + mem_cpy(tbl+BS_VolLab, "NO NAME FAT ", 19); /* Volume label, FAT signature */ + } + ST_WORD(tbl+BS_55AA, 0xAA55); /* Signature (Offset is fixed here regardless of sector size) */ + if (disk_write(drv, tbl, b_vol, 1) != RES_OK) /* Original (VBR) */ + return FR_DISK_ERR; + if (fmt == FS_FAT32) /* Backup (VBR+6) */ + disk_write(drv, tbl, b_vol + 6, 1); + + /* Initialize FAT area */ + for (i = 0; i < N_FATS; i++) { + mem_set(tbl, 0, SS(fs)); /* 1st sector of the FAT */ + n = md; /* Media descriptor byte */ + if (fmt != FS_FAT32) { + n |= (fmt == FS_FAT12) ? 0x00FFFF00 : 0xFFFFFF00; + ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT12/16) */ + } else { + n |= 0x0FFFFF00; + ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT32) */ + ST_DWORD(tbl+4, 0x0FFFFFFF); + ST_DWORD(tbl+8, 0x0FFFFFFF); /* Reserve cluster #2 for root dir */ + } + if (disk_write(drv, tbl, b_fat++, 1) != RES_OK) + return FR_DISK_ERR; + mem_set(tbl, 0, SS(fs)); /* Fill following FAT entries with zero */ + for (n = 1; n < n_fat; n++) { /* This loop may take a time on FAT32 volume due to many single sector write */ + if (disk_write(drv, tbl, b_fat++, 1) != RES_OK) + return FR_DISK_ERR; + } + } + + /* Initialize root directory */ + n = (fmt == FS_FAT32) ? as : n_dir; + while (n--) { + if (disk_write(drv, tbl, b_fat++, 1) != RES_OK) + return FR_DISK_ERR; + } + + /* Create FSInfo record if needed */ + if (fmt == FS_FAT32) { + ST_WORD(tbl+BS_55AA, 0xAA55); + ST_DWORD(tbl+FSI_LeadSig, 0x41615252); + ST_DWORD(tbl+FSI_StrucSig, 0x61417272); + ST_DWORD(tbl+FSI_Free_Count, n_clst - 1); + ST_DWORD(tbl+FSI_Nxt_Free, 0xFFFFFFFF); + disk_write(drv, tbl, b_vol + 1, 1); /* Original (VBR+1) */ + disk_write(drv, tbl, b_vol + 7, 1); /* Backup (VBR+7) */ + } + + return (disk_ioctl(drv, CTRL_SYNC, (void*)0) == RES_OK) ? FR_OK : FR_DISK_ERR; +} + +#endif /* _USE_MKFS && !_FS_READONLY */ + + + + +#if _USE_STRFUNC +/*-----------------------------------------------------------------------*/ +/* Get a string from the file */ +/*-----------------------------------------------------------------------*/ +TCHAR* f_gets ( + TCHAR* buff, /* Pointer to the string buffer to read */ + int len, /* Size of string buffer (characters) */ + FIL* fil /* Pointer to the file object */ +) +{ + int n = 0; + TCHAR c, *p = buff; + BYTE s[2]; + UINT rc; + + + while (n < len - 1) { /* Read bytes until buffer gets filled */ + f_read(fil, s, 1, &rc); + if (rc != 1) break; /* Break on EOF or error */ + c = s[0]; +#if _LFN_UNICODE /* Read a character in UTF-8 encoding */ + if (c >= 0x80) { + if (c < 0xC0) continue; /* Skip stray trailer */ + if (c < 0xE0) { /* Two-byte sequense */ + f_read(fil, s, 1, &rc); + if (rc != 1) break; + c = ((c & 0x1F) << 6) | (s[0] & 0x3F); + if (c < 0x80) c = '?'; + } else { + if (c < 0xF0) { /* Three-byte sequense */ + f_read(fil, s, 2, &rc); + if (rc != 2) break; + c = (c << 12) | ((s[0] & 0x3F) << 6) | (s[1] & 0x3F); + if (c < 0x800) c = '?'; + } else { /* Reject four-byte sequense */ + c = '?'; + } + } + } +#endif +#if _USE_STRFUNC >= 2 + if (c == '\r') continue; /* Strip '\r' */ +#endif + *p++ = c; + n++; + if (c == '\n') break; /* Break on EOL */ + } + *p = 0; + return n ? buff : 0; /* When no data read (eof or error), return with error. */ +} + + + +#if !_FS_READONLY +#include +/*-----------------------------------------------------------------------*/ +/* Put a character to the file */ +/*-----------------------------------------------------------------------*/ +int f_putc ( + TCHAR c, /* A character to be output */ + FIL* fil /* Pointer to the file object */ +) +{ + UINT bw, btw; + BYTE s[3]; + + +#if _USE_STRFUNC >= 2 + if (c == '\n') f_putc ('\r', fil); /* LF -> CRLF conversion */ +#endif + +#if _LFN_UNICODE /* Write the character in UTF-8 encoding */ + if (c < 0x80) { /* 7-bit */ + s[0] = (BYTE)c; + btw = 1; + } else { + if (c < 0x800) { /* 11-bit */ + s[0] = (BYTE)(0xC0 | (c >> 6)); + s[1] = (BYTE)(0x80 | (c & 0x3F)); + btw = 2; + } else { /* 16-bit */ + s[0] = (BYTE)(0xE0 | (c >> 12)); + s[1] = (BYTE)(0x80 | ((c >> 6) & 0x3F)); + s[2] = (BYTE)(0x80 | (c & 0x3F)); + btw = 3; + } + } +#else /* Write the character without conversion */ + s[0] = (BYTE)c; + btw = 1; +#endif + f_write(fil, s, btw, &bw); /* Write the char to the file */ + return (bw == btw) ? 1 : EOF; /* Return the result */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a string to the file */ +/*-----------------------------------------------------------------------*/ +int f_puts ( + const TCHAR* str, /* Pointer to the string to be output */ + FIL* fil /* Pointer to the file object */ +) +{ + int n; + + + for (n = 0; *str; str++, n++) { + if (f_putc(*str, fil) == EOF) return EOF; + } + return n; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a formatted string to the file */ +/*-----------------------------------------------------------------------*/ +int f_printf ( + FIL* fil, /* Pointer to the file object */ + const TCHAR* str, /* Pointer to the format string */ + ... /* Optional arguments... */ +) +{ + va_list arp; + BYTE f, r; + UINT i, w; + ULONG val; + TCHAR c, d, s[16]; + int res, cc; + + + va_start(arp, str); + + for (cc = res = 0; cc != EOF; res += cc) { + c = *str++; + if (c == 0) break; /* End of string */ + if (c != '%') { /* Non escape character */ + cc = f_putc(c, fil); + if (cc != EOF) cc = 1; + continue; + } + w = f = 0; + c = *str++; + if (c == '0') { /* Flag: '0' padding */ + f = 1; c = *str++; + } + while (IsDigit(c)) { /* Precision */ + w = w * 10 + c - '0'; + c = *str++; + } + if (c == 'l' || c == 'L') { /* Prefix: Size is long int */ + f |= 2; c = *str++; + } + if (!c) break; + d = c; + if (IsLower(d)) d -= 0x20; + switch (d) { /* Type is... */ + case 'S' : /* String */ + cc = f_puts(va_arg(arp, TCHAR*), fil); continue; + case 'C' : /* Character */ + cc = f_putc((TCHAR)va_arg(arp, int), fil); continue; + case 'B' : /* Binary */ + r = 2; break; + case 'O' : /* Octal */ + r = 8; break; + case 'D' : /* Signed decimal */ + case 'U' : /* Unsigned decimal */ + r = 10; break; + case 'X' : /* Hexdecimal */ + r = 16; break; + default: /* Unknown */ + cc = f_putc(c, fil); continue; + } + + /* Get an argument */ + val = (f & 2) ? va_arg(arp, long) : ((d == 'D') ? (long)va_arg(arp, int) : va_arg(arp, unsigned int)); + if (d == 'D' && (val & 0x80000000)) { + val = 0 - val; + f |= 4; + } + /* Put it in numeral string */ + i = 0; + do { + d = (TCHAR)(val % r); val /= r; + if (d > 9) { + d += 7; + if (c == 'x') d += 0x20; + } + s[i++] = d + '0'; + } while (val && i < sizeof(s) / sizeof(s[0])); + if (f & 4) s[i++] = '-'; + cc = 0; + while (i < w-- && cc != EOF) { + cc = f_putc((TCHAR)((f & 1) ? '0' : ' '), fil); + res++; + } + do { + cc = f_putc(s[--i], fil); + res++; + } while (i && cc != EOF); + if (cc != EOF) cc = 0; + } + + va_end(arp); + return (cc == EOF) ? cc : res; +} + +#endif /* !_FS_READONLY */ +#endif /* _USE_STRFUNC */ diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/ff.h b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/ff.h new file mode 100644 index 0000000..d739704 --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/ff.h @@ -0,0 +1,613 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module include file R0.08 (C)ChaN, 2010 +/----------------------------------------------------------------------------/ +/ FatFs module is a generic FAT file system module for small embedded systems. +/ This is a free software that opened for education, research and commercial +/ developments under license policy of following trems. +/ +/ Copyright (C) 2010, ChaN, all right reserved. +/ +/ * The FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/----------------------------------------------------------------------------*/ + +#ifndef _FATFS +#define _FATFS 8085 /* Revision ID */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "integer.h" /* Basic integer types */ +#include "ffconf.h" /* FatFs configuration options */ + +#if _FATFS != _FFCONF +#error Wrong configuration file (ffconf.h). +#endif + + +/* DBCS code ranges and SBCS extend char conversion table */ + +#if _CODE_PAGE == 932 /* Japanese Shift-JIS */ +#define _DF1S 0x81 /* DBC 1st byte range 1 start */ +#define _DF1E 0x9F /* DBC 1st byte range 1 end */ +#define _DF2S 0xE0 /* DBC 1st byte range 2 start */ +#define _DF2E 0xFC /* DBC 1st byte range 2 end */ +#define _DS1S 0x40 /* DBC 2nd byte range 1 start */ +#define _DS1E 0x7E /* DBC 2nd byte range 1 end */ +#define _DS2S 0x80 /* DBC 2nd byte range 2 start */ +#define _DS2E 0xFC /* DBC 2nd byte range 2 end */ + +#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0x80 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 949 /* Korean */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x41 +#define _DS1E 0x5A +#define _DS2S 0x61 +#define _DS2E 0x7A +#define _DS3S 0x81 +#define _DS3E 0xFE + +#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0xA1 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 437 /* U.S. (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 720 /* Arabic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 737 /* Greek (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \ + 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 775 /* Baltic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF} + +#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \ + 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \ + 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 857 /* Turkish (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 862 /* Hebrew (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 866 /* Russian (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF} + +#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1253 /* Greek (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \ + 0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF} + +#elif _CODE_PAGE == 1254 /* Turkish (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1256 /* Arabic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1257 /* Baltic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F} + +#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */ +#define _DF1S 0 + +#else +#error Unknown code page + +#endif + + + +/* Definitions corresponds to volume management */ + +#if _MULTI_PARTITION /* Multiple partition configuration */ +#define LD2PD(drv) (Drives[drv].pd) /* Get physical drive# */ +#define LD2PT(drv) (Drives[drv].pt) /* Get partition# */ +typedef struct { + BYTE pd; /* Physical drive# */ + BYTE pt; /* Partition # (0-3) */ +} PARTITION; +extern const PARTITION Drives[]; /* Logical drive# to physical location conversion table */ + +#else /* Single partition configuration */ +#define LD2PD(drv) (drv) /* Physical drive# is equal to the logical drive# */ +#define LD2PT(drv) 0 /* Always mounts the 1st partition */ + +#endif + + + +/* Type of path name strings on FatFs API */ + +#if _LFN_UNICODE /* Unicode string */ +#if !_USE_LFN +#error _LFN_UNICODE must be 0 in non-LFN cfg. +#endif +#ifndef _INC_TCHAR +typedef WCHAR TCHAR; +#define _T(x) L ## x +#define _TEXT(x) L ## x +#endif + +#else /* ANSI/OEM string */ +#ifndef _INC_TCHAR +typedef char TCHAR; +#define _T(x) x +#define _TEXT(x) x +#endif + +#endif + + + +/* Definitions corresponds to file shareing feature */ + +#if _FS_SHARE +#if _FS_READONLY +#error _FS_SHARE must be 0 on R/O cfg. +#endif +typedef struct { + DWORD clu; /* File ID 1, directory */ + WORD idx; /* File ID 2, index in the directory */ + WORD ctr; /* File open counter, 0:none, 0x01..0xFF:read open count, 0x100:in write open */ +} FILESEM; +#endif + + + +/* File system object structure (FATFS) */ + +typedef struct { + BYTE fs_type; /* FAT sub-type (0:Not mounted) */ + BYTE drv; /* Physical drive number */ + BYTE csize; /* Sectors per cluster (1,2,4...128) */ + BYTE n_fats; /* Number of FAT copies (1,2) */ + BYTE wflag; /* win[] dirty flag (1:must be written back) */ + BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */ + WORD id; /* File system mount ID */ + WORD n_rootdir; /* Number of root directory entries (FAT12/16) */ +#if _MAX_SS != 512 + WORD ssize; /* Bytes per sector (512,1024,2048,4096) */ +#endif +#if _FS_REENTRANT + _SYNC_t sobj; /* Identifier of sync object */ +#endif +#if !_FS_READONLY + DWORD last_clust; /* Last allocated cluster */ + DWORD free_clust; /* Number of free clusters */ + DWORD fsi_sector; /* fsinfo sector (FAT32) */ +#endif +#if _FS_RPATH + DWORD cdir; /* Current directory start cluster (0:root) */ +#endif + DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */ + DWORD fsize; /* Sectors per FAT */ + DWORD fatbase; /* FAT start sector */ + DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */ + DWORD database; /* Data start sector */ + DWORD winsect; /* Current sector appearing in the win[] */ + BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */ +#if _FS_SHARE + FILESEM flsem[_FS_SHARE]; /* File lock semaphores */ +#endif +} FATFS; + + + +/* File object structure (FIL) */ + +typedef struct { + FATFS* fs; /* Pointer to the owner file system object */ + WORD id; /* Owner file system mount ID */ + BYTE flag; /* File status flags */ + BYTE pad1; + DWORD fptr; /* File read/write pointer */ + DWORD fsize; /* File size */ + DWORD org_clust; /* File start cluster (0 when fsize==0) */ + DWORD curr_clust; /* Current cluster */ + DWORD dsect; /* Current data sector */ +#if !_FS_READONLY + DWORD dir_sect; /* Sector containing the directory entry */ + BYTE* dir_ptr; /* Ponter to the directory entry in the window */ +#endif +#if _USE_FASTSEEK + DWORD* cltbl; /* Pointer to the cluster link map table */ +#endif +#if _FS_SHARE + UINT lockid; /* File lock ID */ +#endif +#if !_FS_TINY + BYTE buf[_MAX_SS]; /* File data read/write buffer */ +#endif +} FIL; + + + +/* Directory object structure (DIR) */ + +typedef struct { + FATFS* fs; /* Pointer to the owner file system object */ + WORD id; /* Owner file system mount ID */ + WORD index; /* Current read/write index number */ + DWORD sclust; /* Table start cluster (0:Root dir) */ + DWORD clust; /* Current cluster */ + DWORD sect; /* Current sector */ + BYTE* dir; /* Pointer to the current SFN entry in the win[] */ + BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */ +#if _USE_LFN + WCHAR* lfn; /* Pointer to the LFN working buffer */ + WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */ +#endif +} DIR; + + + +/* File status structure (FILINFO) */ + +typedef struct { + DWORD fsize; /* File size */ + WORD fdate; /* Last modified date */ + WORD ftime; /* Last modified time */ + BYTE fattrib; /* Attribute */ + TCHAR fname[13]; /* Short file name (8.3 format) */ +#if _USE_LFN + TCHAR* lfname; /* Pointer to the LFN buffer */ + int lfsize; /* Size of LFN buffer [chrs] */ +#endif +} FILINFO; + + + +/* File function return code (FRESULT) */ + +typedef enum { + FR_OK = 0, /* (0) Succeeded */ + FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */ + FR_INT_ERR, /* (2) Assertion failed */ + FR_NOT_READY, /* (3) The physical drive cannot work */ + FR_NO_FILE, /* (4) Could not find the file */ + FR_NO_PATH, /* (5) Could not find the path */ + FR_INVALID_NAME, /* (6) The path name format is invalid */ + FR_DENIED, /* (7) Acces denied due to prohibited access or directory full */ + FR_EXIST, /* (8) Acces denied due to prohibited access */ + FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */ + FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */ + FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ + FR_NOT_ENABLED, /* (12) The volume has no work area */ + FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume on the physical drive */ + FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */ + FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ + FR_LOCKED, /* (16) The operation is rejected according to the file shareing policy */ + FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ + FR_TOO_MANY_OPEN_FILES /* (18) Number of open files > _FS_SHARE */ +} FRESULT; + + + +/*--------------------------------------------------------------*/ +/* FatFs module application interface */ + +FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */ +FRESULT f_open (FIL*, const TCHAR*, BYTE); /* Open or create a file */ +FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */ +FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */ +FRESULT f_close (FIL*); /* Close an open file object */ +FRESULT f_opendir (DIR*, const TCHAR*); /* Open an existing directory */ +FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */ +FRESULT f_stat (const TCHAR*, FILINFO*); /* Get file status */ +#if !_FS_READONLY +FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */ +FRESULT f_getfree (const TCHAR*, DWORD*, FATFS**); /* Get number of free clusters on the drive */ +FRESULT f_truncate (FIL*); /* Truncate file */ +FRESULT f_sync (FIL*); /* Flush cached data of a writing file */ +FRESULT f_unlink (const TCHAR*); /* Delete an existing file or directory */ +FRESULT f_mkdir (const TCHAR*); /* Create a new directory */ +FRESULT f_chmod (const TCHAR*, BYTE, BYTE); /* Change attriburte of the file/dir */ +FRESULT f_utime (const TCHAR*, const FILINFO*); /* Change timestamp of the file/dir */ +FRESULT f_rename (const TCHAR*, const TCHAR*); /* Rename/Move a file or directory */ +#endif +#if _USE_FORWARD +FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */ +#endif +#if _USE_MKFS +FRESULT f_mkfs (BYTE, BYTE, UINT); /* Create a file system on the drive */ +#endif +#if _FS_RPATH +FRESULT f_chdir (const TCHAR*); /* Change current directory */ +FRESULT f_chdrive (BYTE); /* Change current drive */ +#endif +#if _USE_STRFUNC +int f_putc (TCHAR, FIL*); /* Put a character to the file */ +int f_puts (const TCHAR*, FIL*); /* Put a string to the file */ +int f_printf (FIL*, const TCHAR*, ...); /* Put a formatted string to the file */ +TCHAR* f_gets (TCHAR*, int, FIL*); /* Get a string from the file */ +#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0) +#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0) +#ifndef EOF +#define EOF (-1) +#endif +#endif + + + +/*--------------------------------------------------------------*/ +/* Additional user defined functions */ + +/* RTC function */ +#if !_FS_READONLY +DWORD get_fattime (void); +#endif + +/* Unicode support functions */ +#if _USE_LFN /* Unicode - OEM code conversion */ +WCHAR ff_convert (WCHAR, UINT); /* OEM-Unicode bidirectional conversion */ +WCHAR ff_wtoupper (WCHAR); /* Unicode upper-case conversion */ +#if _USE_LFN == 3 /* Memory functions */ +void* ff_memalloc (UINT); /* Allocate memory block */ +void ff_memfree (void*); /* Free memory block */ +#endif +#endif + +/* Sync functions */ +#if _FS_REENTRANT +int ff_cre_syncobj (BYTE, _SYNC_t*);/* Create a sync object */ +int ff_del_syncobj (_SYNC_t); /* Delete a sync object */ +int ff_req_grant (_SYNC_t); /* Lock sync object */ +void ff_rel_grant (_SYNC_t); /* Unlock sync object */ +#endif + + + + +/*--------------------------------------------------------------*/ +/* Flags and offset address */ + + +/* File access control and file status flags (FIL.flag) */ + +#define FA_READ 0x01 +#define FA_OPEN_EXISTING 0x00 +#define FA__ERROR 0x80 + +#if !_FS_READONLY +#define FA_WRITE 0x02 +#define FA_CREATE_NEW 0x04 +#define FA_CREATE_ALWAYS 0x08 +#define FA_OPEN_ALWAYS 0x10 +#define FA__WRITTEN 0x20 +#define FA__DIRTY 0x40 +#endif + + +/* FAT sub type (FATFS.fs_type) */ + +#define FS_FAT12 1 +#define FS_FAT16 2 +#define FS_FAT32 3 + + +/* File attribute bits for directory entry */ + +#define AM_RDO 0x01 /* Read only */ +#define AM_HID 0x02 /* Hidden */ +#define AM_SYS 0x04 /* System */ +#define AM_VOL 0x08 /* Volume label */ +#define AM_LFN 0x0F /* LFN entry */ +#define AM_DIR 0x10 /* Directory */ +#define AM_ARC 0x20 /* Archive */ +#define AM_MASK 0x3F /* Mask of defined bits */ + + +/* Fast seek function */ +#define CREATE_LINKMAP 0xFFFFFFFF + + +/* FatFs refers the members in the FAT structures with byte offset instead of +/ structure member because there are incompatibility of the packing option +/ between various compilers. */ + +#define BS_jmpBoot 0 +#define BS_OEMName 3 +#define BPB_BytsPerSec 11 +#define BPB_SecPerClus 13 +#define BPB_RsvdSecCnt 14 +#define BPB_NumFATs 16 +#define BPB_RootEntCnt 17 +#define BPB_TotSec16 19 +#define BPB_Media 21 +#define BPB_FATSz16 22 +#define BPB_SecPerTrk 24 +#define BPB_NumHeads 26 +#define BPB_HiddSec 28 +#define BPB_TotSec32 32 +#define BS_55AA 510 + +#define BS_DrvNum 36 +#define BS_BootSig 38 +#define BS_VolID 39 +#define BS_VolLab 43 +#define BS_FilSysType 54 + +#define BPB_FATSz32 36 +#define BPB_ExtFlags 40 +#define BPB_FSVer 42 +#define BPB_RootClus 44 +#define BPB_FSInfo 48 +#define BPB_BkBootSec 50 +#define BS_DrvNum32 64 +#define BS_BootSig32 66 +#define BS_VolID32 67 +#define BS_VolLab32 71 +#define BS_FilSysType32 82 + +#define FSI_LeadSig 0 +#define FSI_StrucSig 484 +#define FSI_Free_Count 488 +#define FSI_Nxt_Free 492 + +#define MBR_Table 446 + +#define DIR_Name 0 +#define DIR_Attr 11 +#define DIR_NTres 12 +#define DIR_CrtTime 14 +#define DIR_CrtDate 16 +#define DIR_FstClusHI 20 +#define DIR_WrtTime 22 +#define DIR_WrtDate 24 +#define DIR_FstClusLO 26 +#define DIR_FileSize 28 +#define LDIR_Ord 0 +#define LDIR_Attr 11 +#define LDIR_Type 12 +#define LDIR_Chksum 13 +#define LDIR_FstClusLO 26 + + + +/*--------------------------------*/ +/* Multi-byte word access macros */ + +#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val) +#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val) +#else /* Use byte-by-byte access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8) +#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _FATFS */ diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/ffconf.h b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/ffconf.h new file mode 100644 index 0000000..ca26e10 --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/ffconf.h @@ -0,0 +1,179 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module configuration file R0.08 (C)ChaN, 2010 +/----------------------------------------------------------------------------/ +/ +/ CAUTION! Do not forget to make clean the project after any changes to +/ the configuration options. +/ +/----------------------------------------------------------------------------*/ +#ifndef _FFCONF +#define _FFCONF 8085 /* Revision ID */ + + +/*---------------------------------------------------------------------------/ +/ Function and Buffer Configurations +/----------------------------------------------------------------------------*/ + +#define _FS_TINY 1 /* 0 or 1 */ +/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system +/ object instead of the sector buffer in the individual file object for file +/ data transfer. This reduces memory consumption 512 bytes each file object. */ + + +#define _FS_READONLY 0 /* 0 or 1 */ +/* Setting _FS_READONLY to 1 defines read only configuration. This removes +/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename, +/ f_truncate and useless f_getfree. */ + + +#define _FS_MINIMIZE 0 /* 0, 1, 2 or 3 */ +/* The _FS_MINIMIZE option defines minimization level to remove some functions. +/ +/ 0: Full function. +/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename +/ are removed. +/ 2: f_opendir and f_readdir are removed in addition to level 1. +/ 3: f_lseek is removed in addition to level 2. */ + + +#define _USE_STRFUNC 0 /* 0, 1 or 2 */ +/* To enable string functions, set _USE_STRFUNC to 1 or 2. */ + + +#define _USE_MKFS 1 /* 0 or 1 */ +/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */ + + +#define _USE_FORWARD 0 /* 0 or 1 */ +/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */ + + +#define _USE_FASTSEEK 0 /* 0 or 1 */ +/* To enable f_fastseek function, set _USE_FASTSEEK to 1. */ + + + +/*---------------------------------------------------------------------------/ +/ Locale and Namespace Configurations +/----------------------------------------------------------------------------*/ + +#define _CODE_PAGE 1 +/* The _CODE_PAGE specifies the OEM code page to be used on the target system. +/ Incorrect setting of the code page can cause a file open failure. +/ +/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows) +/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows) +/ 949 - Korean (DBCS, OEM, Windows) +/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) +/ 1250 - Central Europe (Windows) +/ 1251 - Cyrillic (Windows) +/ 1252 - Latin 1 (Windows) +/ 1253 - Greek (Windows) +/ 1254 - Turkish (Windows) +/ 1255 - Hebrew (Windows) +/ 1256 - Arabic (Windows) +/ 1257 - Baltic (Windows) +/ 1258 - Vietnam (OEM, Windows) +/ 437 - U.S. (OEM) +/ 720 - Arabic (OEM) +/ 737 - Greek (OEM) +/ 775 - Baltic (OEM) +/ 850 - Multilingual Latin 1 (OEM) +/ 858 - Multilingual Latin 1 + Euro (OEM) +/ 852 - Latin 2 (OEM) +/ 855 - Cyrillic (OEM) +/ 866 - Russian (OEM) +/ 857 - Turkish (OEM) +/ 862 - Hebrew (OEM) +/ 874 - Thai (OEM, Windows) +/ 1 - ASCII only (Valid for non LFN cfg.) +*/ + + +#define _USE_LFN 0 /* 0 to 3 */ +#define _MAX_LFN 128 /* Maximum LFN length to handle (12 to 255) */ +/* The _USE_LFN option switches the LFN support. +/ +/ 0: Disable LFN. _MAX_LFN and _LFN_UNICODE have no effect. +/ 1: Enable LFN with static working buffer on the bss. NOT REENTRANT. +/ 2: Enable LFN with dynamic working buffer on the STACK. +/ 3: Enable LFN with dynamic working buffer on the HEAP. +/ +/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN, +/ Unicode handling functions ff_convert() and ff_wtoupper() must be added +/ to the project. When enable to use heap, memory control functions +/ ff_memalloc() and ff_memfree() must be added to the project. */ + + +#define _LFN_UNICODE 0 /* 0 or 1 */ +/* To switch the character code set on FatFs API to Unicode, +/ enable LFN feature and set _LFN_UNICODE to 1. +*/ + + +#define _FS_RPATH 1 /* 0 or 1 */ +/* When _FS_RPATH is set to 1, relative path feature is enabled and f_chdir, +/ f_chdrive function are available. +/ Note that output of the f_readdir fnction is affected by this option. */ + + + +/*---------------------------------------------------------------------------/ +/ Physical Drive Configurations +/----------------------------------------------------------------------------*/ + +#define _DRIVES 2 +/* Number of volumes (logical drives) to be used. */ + + +#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */ +/* Maximum sector size to be handled. +/ Always set 512 for memory card and hard disk but a larger value may be +/ required for floppy disk (512/1024) and optical disk (512/2048). +/ When _MAX_SS is larger than 512, GET_SECTOR_SIZE command must be implememted +/ to the disk_ioctl function. */ + + +#define _MULTI_PARTITION 0 /* 0 or 1 */ +/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical +/ drive number and can mount only first primaly partition. When it is set to 1, +/ each volume is tied to the partitions listed in Drives[]. */ + + + +/*---------------------------------------------------------------------------/ +/ System Configurations +/----------------------------------------------------------------------------*/ + +#define _WORD_ACCESS 1 /* 0 or 1 */ +/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS +/ option defines which access method is used to the word data on the FAT volume. +/ +/ 0: Byte-by-byte access. +/ 1: Word access. Do not choose this unless following condition is met. +/ +/ When the byte order on the memory is big-endian or address miss-aligned word +/ access results incorrect behavior, the _WORD_ACCESS must be set to 0. +/ If it is not the case, the value can also be set to 1 to improve the +/ performance and code size. */ + + +#define _FS_REENTRANT 0 /* 0 or 1 */ +#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */ +#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */ +/* The _FS_REENTRANT option switches the reentrancy of the FatFs module. +/ +/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect. +/ 1: Enable reentrancy. Also user provided synchronization handlers, +/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj +/ function must be added to the project. */ + + +#define _FS_SHARE 0 /* 0 or >=1 */ +/* To enable file shareing feature, set _FS_SHARE to >= 1 and also user + provided memory handlers, ff_memalloc and ff_memfree function must be + added to the project. The value defines number of files can be opened + per volume. */ + + +#endif /* _FFCONF */ diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/integer.h b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/integer.h new file mode 100644 index 0000000..16ad408 --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/integer.h @@ -0,0 +1,37 @@ +/*-------------------------------------------*/ +/* Integer type definitions for FatFs module */ +/*-------------------------------------------*/ + +#ifndef _INTEGER +#define _INTEGER + +#ifdef _WIN32 /* FatFs development platform */ + +#include +#include + +#else /* Embedded platform */ + +/* These types must be 16-bit, 32-bit or larger integer */ +typedef int INT; +typedef unsigned int UINT; + +/* These types must be 8-bit integer */ +typedef char CHAR; +typedef unsigned char UCHAR; +typedef unsigned char BYTE; + +/* These types must be 16-bit integer */ +typedef short SHORT; +typedef unsigned short USHORT; +typedef unsigned short WORD; +typedef unsigned short WCHAR; + +/* These types must be 32-bit integer */ +typedef long LONG; +typedef unsigned long ULONG; +typedef unsigned long DWORD; + +#endif + +#endif diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/main.c b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/main.c new file mode 100644 index 0000000..683621b --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 3/main.c @@ -0,0 +1,296 @@ +/** +@file main.c +@brief Lab 3 Starter Code +@version .01 +@mainpage Lab 3 Starter Code + +@section intro Code Overview + +@section hw Hardware Pin Out +Port A: +A0 - A3 : Push Buttons +A4 - A7 : Slide Switches + +Port B: +B0 - B3 : SPI (SD Card) +B4 : Nothing +B5 : Audio Out +B6 : Red Enable +B7 : Green Enable + +Port C: +C0 - C7 : LED Array (Row) + +Port D: +D0 - D1 : Nothing +D2 : Serial RX +D3 : Serial TX +D4 - D7 : Nothing + +Port E: +E0 - E2 : LED Array (Column) +E3 : USB (UID) +E4 - E5 : Nothing +E6 : Relay +E7 : Nothing + +Port F: +F0 : ADC Channel 0 +F1 : ADC Channel 1 +F2 : ADC Channel 2 +F3 : ADC Channel 3 +F4 : ADC Channel 4 (Audio In) +F5 : ADC Channel 5 (Accel X Axis) +F6 : ADC Channel 6 (Accel Y Axis) +F7 : ADC Channel 7 (Accel Z Axis (if installed)) + +*/ + +/** Includes */ +#include +#include + + +/** Constants */ +#define F_CPU 1000000UL +#define DEBUG 1 +#ifdef DEBUG == 1 + #define SENDSPEED 3 //If less than .12, there are problems +#endif + +/** Global Variables */ + +/** Functions */ + +#ifdef DEBUG == 1 + /** This function needs to setup the variables used by the UART to enable the UART and tramsmit at 9600bps. This + function should always return 0. Remember, by defualt the Wunderboard runs at 1mHz for its system clock.*/ + unsigned char InitializeUART (){ + unsigned char baud = ((F_CPU/(9600*8UL))-1); + + /* Set baud rate */ + UBRR1H = (baud >> 8); + UBRR1L = baud; + /* Set the U2X1 bit */ + UCSR1A = (1 << U2X1); + /* Enable transmitter */ + UCSR1B = (1 << TXEN1 | 1 << RXEN1); + /* Set frame format: 8data, 1stop bit */ + UCSR1C = (3 << UCSZ10); + + return 0; + } + + /** This function needs to write a single byte to the UART. It must check that the UART is ready for a new byte + and return a 1 if the byte was not sent. + @param [in] data This is the data byte to be sent. + @return The function returns a 1 or error and 0 on successful completion.*/ + + unsigned char SendByteUART (unsigned char data){ + + /* + ** Checks the buffer empty bit so that data can either be placed in the buffer + ** or else reuturn a 1 + */ + if((UCSR1A & (1 << UDRE1)) == (1 << UDRE1)){ + UDR1 = data; + _delay_ms(SENDSPEED); //Places data into the UDR1 8-bit data buffer + }else { + return 1; + } + + return 0; + } + + /** This function needs to writes a string to the UART. It must check that the UART is ready for a new byte and + return a 1 if the string was not sent. + @param [in] data This is a pointer to the data to be sent. + @return The function returns a 1 or error and 0 on successful completion.*/ + + unsigned char SendStringUART (unsigned char *data){ + + for (int loop = 0 ; data[loop] != '\0'; loop++){ + unsigned char bytereturn; //Storage for return value of SendByteUART + + /* Sends the current byte based on the loop umber to SendByte */ + bytereturn = SendByteUART(data[loop]); + + /* Stops sending if SendByteUART had an error */ + if(bytereturn == 1){ + return 1; + } + } + return 0; + } + + unsigned char GetByteUART(){ + if (UCSR1A & (1 << RXC1)){ + return(UDR1); + } else{ + return(-1); + } + } +#endif + +/** The clearArray() function turns off all LEDS on the Wunderboard array. It accepts no inputs and returns nothing*/ +void clearArray(void){ + PORTC = 0x00; + PORTB |= (1 << PB6) | (1 << PB7); /** Enable latches*/ + PORTB &= ~((1 << PB6) | (1 << PB7)); /** Disable latches*/ +} + +/** The initialize() function initializes all of the Data Direction Registers for the Wunderboard. Before making changes to DDRx registers, ensure that you have read the peripherals section of the Wunderboard user guide.*/ +void initialize(void){ + /** Port A is the switches and buttons. They should always be inputs. ( 0 = Input and 1 = Output )*/ + DDRA=0b00000000; + + /** Port B has the LED Array color control, SD card, and audio-out on it. Leave DDRB alone. ( 0 = Input and 1 = Output )*/ + DDRB=0b11000111; + + /** Port C is for the 'row' of the LED array. They should always be outputs. ( 0 = Input and 1 = Output )*/ + DDRC=0b11111111; + + /** Port D has the Serial on it. Leave DDRB alone. ( 0 = Input and 1 = Output )*/ + DDRD=0b00000000; + + /** Port E has the LED Array Column control out on it. Leave DDRE alone. ( 0 = Input and 1 = Output )*/ + DDRE=0b00000111; + + /** Port F has the accelerometer and audio-in on it. Leave DDRF alone. ( 0 = Input and 1 = Output )*/ + DDRF=0b00000000; +} + +unsigned char read_adc(uint8_t channel){ + + unsigned char test; + + ADMUX = 0x60 | channel; // Set the channel to the one we want + ADCSRA = 0b11000110; // Start a new sample. + while ((ADCSRA & 0b00010000) == 0 ); // Wait for a Valid Sample + ADCSRA |= 0b00010000; // Tell ADC you have the sample you want. + ADCSRA |= 0b01000000; // Start a new sample. + while ((ADCSRA & 0b00010000) == 0 ); // Wait for a Valid Sample + ADCSRA |= 0b00010000; // Tell ADC you have the sample you want. + + test = ADCH; + ADCSRA = 0x00; // Disable the ADC + + return (test); +} + + +/** This function needs to setup the variables used by TIMER0 Compare Match (CTC) mode with +a base clock frequency of clk/1024. This function should return a 1 if it fails and a 0 if it +does not. Remember, by default the Wunderboard runs at 1mHz for its system clock. +@return This function returns a 1 is unsuccessful, else return 0.*/ +unsigned char initializeTIMER0(void){ + /* Set the CTC mode */ + TCCR0A = (1 << WGM01); + + /* Set the Clock Frequency */ + TCCR0B = ((1 << CS02) | (1 << CS00)); + + /* Set initial count value */ + OCR0A = 0; +} + +/** This function checks if TIMER0 has elapsed. +@return This function should return a 1 if the timer has elapsed, else return 0*/ +unsigned char checkTIMER0(void){ + if((TIFR0 & (1 << OCF0A)) == (1 << OCF0A)){ + TIFR0 |= (1 << OCF0A); + return 1; + }else { + return 0; + } +} + +/** This function takes two values, clock and count. The value of count should be copied into OCR0A and the value of clock should be used to set CS02:0. The TCNT0 variable should also be reset to 0 so that the new timer rate starts from 0. +@param [in] clock Insert Comment +@param [in] count Insert Comment +@return The function returns a 1 or error and 0 on successful completion.*/ +unsigned char setTIMER0(unsigned char clock, unsigned char count){ + + if(clock > 7){ + return 1; + } + TCCR0B &= 0b11111000; //Zeros out last three bits + TCCR0B |= clock; + OCR0A = count; + TCNT0 = 0; + return 0; +} + +/** Main Function */ +int main (void){ + + enum states { + setup, + idle, + running + } state = setup; + + unsigned char numelapsed = 0; + unsigned char debug; + unsigned char received; + unsigned char send[150]; + unsigned char adcreturn1; + unsigned char adcreturn2; + + while(1){ + + switch(state){ + case setup: + + initialize(); + initializeTIMER0(); + InitializeUART(); + clearArray(); + setTIMER0(5, 121); + PORTB = 0b11000000; + state = idle; + sprintf(send, "Initialized...\n"); + SendStringUART(send); + break; + + case idle: + if(debug != 1){ + sprintf(send, "Idling...\n"); + SendStringUART(send); + debug = 1; + } + received = GetByteUART(); + + if (received == 's'){ + state = running; + debug = 0; + break; + } + + break; + + case running: + + received = GetByteUART(); + adcreturn1 = read_adc(5); + adcreturn2 = read_adc(6); + + if (received == 's'){ + state = idle; + } + + if (checkTIMER0() == 1){ + if(numelapsed == 3){ + PORTC = ~PORTC; + numelapsed = 0; + sprintf(send, "X value: %d\tY value: %d\n", adcreturn1, adcreturn2); + SendStringUART(send); + + }else { + numelapsed++; + } + } + break; + } + } +} \ No newline at end of file diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/Makefile b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/Makefile new file mode 100644 index 0000000..495854c --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/Makefile @@ -0,0 +1,337 @@ +#---------------------------------------------------------------------------- +# Wunderboard Makefile Template written by Dan Albert +#---------------------------------------------------------------------------- +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make filename.s = Just compile filename.c into the assembler code only. +# +# To rebuild project do "make clean" then "make all". +#---------------------------------------------------------------------------- + +# Target file name. +TARGET = main + +# List C source files here. +SRC = $(TARGET).c \ + ff.c \ + diskio.c \ + +# MCU name, you MUST set this to match the board you are using +# type "make clean" after changing this, so all files will be rebuilt +MCU = at90usb646 + +# Detect platform +UNAME = $(shell uname) + +ifeq ($(UNAME),Linux) +ENV=unix +endif + +ifeq ($(UNAME),Darwin) +ENV=unix +endif + +ifndef ENV +ENV=windows +endif + +ifeq ($(ENV),unix) +PROGRAM = dfu-programmer +PROGRAMFLAGS = $(MCU) +ERASE = erase +FLASH = flash "$(TARGET).hex" +START = start +else +PROGRAM = "batchisp.exe" +PROGRAMFLAGS = -device at90usb646 -hardware USB +ERASE = -operation erase F +FLASH = -operation loadbuffer "$(TARGET).hex" program verify +START = -operation start noreset 0 +endif + +# Processor frequency. +# Normally the first thing your program should do is set the clock prescaler, +# so your program will run at the correct speed. You should also set this +# variable to same clock speed. The _delay_ms() macro uses this, and many +# examples use this variable to calculate timings. Do not add a "UL" here. +F_CPU = 1000000 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Object files directory +# To put object files in current directory, use a dot (.), do NOT make +# this an empty or blank macro! +OBJDIR = obj + +# 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.) +OPT = s + +# 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 for C sources +CDEFS = -DF_CPU=$(F_CPU)UL + +#---------------- Compiler Options C ---------------- +# -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 += $(CDEFS) +CFLAGS += -O$(OPT) +CFLAGS += -funsigned-char +CFLAGS += -funsigned-bitfields +CFLAGS += -ffunction-sections +CFLAGS += -fpack-struct +CFLAGS += -fshort-enums +CFLAGS += -Wall +CFLAGS += -Wstrict-prototypes +#CFLAGS += -mshort-calls +#CFLAGS += -fno-unit-at-a-time +#CFLAGS += -Wundef +#CFLAGS += -Wunreachable-code +#CFLAGS += -Wsign-compare +CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +CFLAGS += $(CSTANDARD) + +#---------------- 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 + +# List any extra directories to look for libraries 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. +EXTRALIBDIRS = + +#---------------- 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 += -Wl,--relax +LDFLAGS += -Wl,--gc-sections +LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS)) +LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) +#LDFLAGS += -T linker_script.x + + +#============================================================================ + +# Define programs and commands. +SHELL = sh +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +AR = avr-ar rcs +NM = avr-nm +REMOVE = rm -f +REMOVEDIR = rm -rf +COPY = cp +WINSHELL = cmd + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling C: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: +MSG_CREATING_LIBRARY = Creating library: + +# Define all object files. +OBJ = $(SRC:%.c=$(OBJDIR)/%.o) + +# Define all listing files. +LST = $(SRC:%.c=$(OBJDIR)/%.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) + +# Default target. +all: begin gccversion sizebefore build sizeafter end + +# Change the build target to build a HEX file or a library. +build: elf hex eep lss sym +#build: lib + +elf: $(TARGET).elf +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym +LIBNAME=lib$(TARGET).a +lib: $(LIBNAME) + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +end: + @echo $(MSG_END) + @echo + +# Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf + +sizebefore: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +sizeafter: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +# Display compiler version information. +gccversion : + @$(CC) --version + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -R .signature $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0 + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S -z $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + $(NM) -n $< > $@ + + +# Create library from object files. +.SECONDARY : $(TARGET).a +.PRECIOUS : $(OBJ) +%.a: $(OBJ) + @echo + @echo $(MSG_CREATING_LIBRARY) $@ + $(AR) $@ $(OBJ) + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS) + +# Compile: create object files from C source files. +$(OBJDIR)/%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + +## Program +.PHONY: program +program: all + $(PROGRAM) $(PROGRAMFLAGS) $(ERASE) + $(PROGRAM) $(PROGRAMFLAGS) $(FLASH) + $(PROGRAM) $(PROGRAMFLAGS) $(START) + +doxygen: + doxygen + +# Target: clean project. +clean: begin clean_list end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lss + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o) + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + $(REMOVEDIR) .dep + $(REMOVEDIR) $(OBJDIR) + +# Create object files directory +$(shell mkdir $(OBJDIR) 2>/dev/null) + +# Include the dependency files. +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion \ +build elf hex eep lss sym \ +clean clean_list diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/diskio.c b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/diskio.c new file mode 100644 index 0000000..b2f7202 --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/diskio.c @@ -0,0 +1,623 @@ +/*-----------------------------------------------------------------------*/ +/* MMCv3/SDv1/SDv2 (in SPI mode) control module (C)ChaN, 2007 */ +/*-----------------------------------------------------------------------*/ +/* Only rcvr_spi(), xmit_spi(), disk_timerproc() and some macros */ +/* are platform dependent. */ +/*-----------------------------------------------------------------------*/ + + +#include +#include +#include "diskio.h" + + +/* Definitions for MMC/SDC command */ +#define CMD0 (0) /* GO_IDLE_STATE */ +#define CMD1 (1) /* SEND_OP_COND (MMC) */ +#define ACMD41 (0x80+41) /* SEND_OP_COND (SDC) */ +#define CMD8 (8) /* SEND_IF_COND */ +#define CMD9 (9) /* SEND_CSD */ +#define CMD10 (10) /* SEND_CID */ +#define CMD12 (12) /* STOP_TRANSMISSION */ +#define ACMD13 (0x80+13) /* SD_STATUS (SDC) */ +#define CMD16 (16) /* SET_BLOCKLEN */ +#define CMD17 (17) /* READ_SINGLE_BLOCK */ +#define CMD18 (18) /* READ_MULTIPLE_BLOCK */ +#define CMD23 (23) /* SET_BLOCK_COUNT (MMC) */ +#define ACMD23 (0x80+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */ +#define CMD24 (24) /* WRITE_BLOCK */ +#define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */ +#define CMD55 (55) /* APP_CMD */ +#define CMD58 (58) /* READ_OCR */ + + +/* Port Controls (Platform dependent) */ +#define CS_LOW() PORTB &= ~1 /* MMC CS = L */ +#define CS_HIGH() PORTB |= 1 /* MMC CS = H */ + +#define SOCKPORT PINB /* Socket contact port */ +#define SOCKWP 0x20 /* Write protect switch (PB5) */ +#define SOCKINS 0x10 /* Card detect switch (PB4) */ + +#define FCLK_SLOW() SPCR = 0x52 /* Set slow clock (100k-400k) */ +#define FCLK_FAST() SPCR = 0x50 /* Set fast clock (depends on the CSD) */ + + +/*-------------------------------------------------------------------------- + + Module Private Functions + +---------------------------------------------------------------------------*/ + +static volatile +DSTATUS Stat = STA_NOINIT; /* Disk status */ + +static volatile +BYTE Timer1, Timer2; /* 100Hz decrement timer */ + +static +BYTE CardType; /* Card type flags */ + + +/*-----------------------------------------------------------------------*/ +/* Transmit a byte to MMC via SPI (Platform dependent) */ +/*-----------------------------------------------------------------------*/ + +#define xmit_spi(dat) cli(); SPDR=(dat); loop_until_bit_is_set(SPSR,SPIF); sei() + + + +/*-----------------------------------------------------------------------*/ +/* Receive a byte from MMC via SPI (Platform dependent) */ +/*-----------------------------------------------------------------------*/ + +static +BYTE rcvr_spi (void) +{ + cli(); + SPDR = 0xFF; + loop_until_bit_is_set(SPSR, SPIF); + sei(); + return SPDR; +} + +/* Alternative macro to receive data fast */ +#define rcvr_spi_m(dst) SPDR=0xFF; loop_until_bit_is_set(SPSR,SPIF); *(dst)=SPDR + + + +/*-----------------------------------------------------------------------*/ +/* Wait for card ready */ +/*-----------------------------------------------------------------------*/ + +static +int wait_ready (void) /* 1:OK, 0:Timeout */ +{ + Timer2 = 50; /* Wait for ready in timeout of 500ms */ + rcvr_spi(); + do + if (rcvr_spi() == 0xFF) return 1; + while (Timer2); + + return 0; +} + + + +/*-----------------------------------------------------------------------*/ +/* Deselect the card and release SPI bus */ +/*-----------------------------------------------------------------------*/ + +static +void deselect (void) +{ + CS_HIGH(); + rcvr_spi(); +} + + + +/*-----------------------------------------------------------------------*/ +/* Select the card and wait for ready */ +/*-----------------------------------------------------------------------*/ + +static +int select (void) /* 1:Successful, 0:Timeout */ +{ + CS_LOW(); + if (!wait_ready()) { + deselect(); + return 0; + } + return 1; +} + + + +/*-----------------------------------------------------------------------*/ +/* Power Control (Platform dependent) */ +/*-----------------------------------------------------------------------*/ +/* When the target system does not support socket power control, there */ +/* is nothing to do in these functions and chk_power always returns 1. */ + +/* +static +void power_on (void) +{ + PORTE &= ~0x80; // Socket power ON * + for (Timer1 = 3; Timer1; ); // Wait for 30ms * + PORTB = 0b10110101; //Enable drivers * + DDRB = 0b11000111; + SPCR = 0x52; // Enable SPI function in mode 0 * + SPSR = 0x01; // 2x mode * +} + + +static +void power_off (void) +{ + select(); // Wait for card ready * + deselect(); + SPCR = 0; // Disable SPI function * + DDRB = 0b11000000; // Disable drivers * + PORTB = 0b10110000; + PORTE |= 0x80; // Socket power OFF * + Stat |= STA_NOINIT; // Set STA_NOINIT * +} +*/ + +static +int chk_power(void) /* Socket power state: 0=off, 1=on */ +{ + return 1; +} + + + +/*-----------------------------------------------------------------------*/ +/* Receive a data packet from MMC */ +/*-----------------------------------------------------------------------*/ + +static +int rcvr_datablock ( + BYTE *buff, /* Data buffer to store received data */ + UINT btr /* Byte count (must be multiple of 4) */ +) +{ + BYTE token; + + + Timer1 = 20; + do { /* Wait for data packet in timeout of 200ms */ + token = rcvr_spi(); + } while ((token == 0xFF) && Timer1); + if(token != 0xFE) return 0; /* If not valid data token, retutn with error */ + + do { /* Receive the data block into buffer */ + rcvr_spi_m(buff++); + rcvr_spi_m(buff++); + rcvr_spi_m(buff++); + rcvr_spi_m(buff++); + } while (btr -= 4); + rcvr_spi(); /* Discard CRC */ + rcvr_spi(); + + return 1; /* Return with success */ +} + + + +/*-----------------------------------------------------------------------*/ +/* Send a data packet to MMC */ +/*-----------------------------------------------------------------------*/ + +#if _READONLY == 0 +static +int xmit_datablock ( + const BYTE *buff, /* 512 byte data block to be transmitted */ + BYTE token /* Data/Stop token */ +) +{ + BYTE resp, wc; + + + if (!wait_ready()) return 0; + + xmit_spi(token); /* Xmit data token */ + if (token != 0xFD) { /* Is data token */ + wc = 0; + do { /* Xmit the 512 byte data block to MMC */ + xmit_spi(*buff++); + xmit_spi(*buff++); + } while (--wc); + xmit_spi(0xFF); /* CRC (Dummy) */ + xmit_spi(0xFF); + resp = rcvr_spi(); /* Reveive data response */ + if ((resp & 0x1F) != 0x05) /* If not accepted, return with error */ + return 0; + } + + return 1; +} +#endif /* _READONLY */ + + + +/*-----------------------------------------------------------------------*/ +/* Send a command packet to MMC */ +/*-----------------------------------------------------------------------*/ + +static +BYTE send_cmd ( /* Returns R1 resp (bit7==1:Send failed) */ + BYTE cmd, /* Command index */ + DWORD arg /* Argument */ +) +{ + BYTE n, res; + + + if (cmd & 0x80) { /* ACMD is the command sequense of CMD55-CMD */ + cmd &= 0x7F; + res = send_cmd(CMD55, 0); + if (res > 1) return res; + } + + /* Select the card and wait for ready */ + deselect(); + if (!select()) return 0xFF; + + /* Send command packet */ + xmit_spi(0x40 | cmd); /* Start + Command index */ + xmit_spi((BYTE)(arg >> 24)); /* Argument[31..24] */ + xmit_spi((BYTE)(arg >> 16)); /* Argument[23..16] */ + xmit_spi((BYTE)(arg >> 8)); /* Argument[15..8] */ + xmit_spi((BYTE)arg); /* Argument[7..0] */ + n = 0x01; /* Dummy CRC + Stop */ + if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */ + if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */ + xmit_spi(n); + + /* Receive command response */ + if (cmd == CMD12) rcvr_spi(); /* Skip a stuff byte when stop reading */ + n = 10; /* Wait for a valid response in timeout of 10 attempts */ + do + res = rcvr_spi(); + while ((res & 0x80) && --n); + + return res; /* Return with the response value */ +} + + + +/*-------------------------------------------------------------------------- + + Public Functions + +---------------------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------------*/ +/* Initialize Disk Drive */ +/*-----------------------------------------------------------------------*/ + +DSTATUS disk_initialize (BYTE drv) /* Physical drive nmuber (0) */ +{ + BYTE n, cmd, ty, ocr[4]; + + if (drv) return STA_NOINIT; /* Supports only single drive */ + if (Stat & STA_NODISK) return Stat; /* No card in the socket */ + + //power_on(); /* Force socket power on */ + PORTB |= 0b11000000; + FCLK_SLOW(); + for (n = 10; n; n--) rcvr_spi(); /* 80 dummy clocks */ + + ty = 0; + if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */ + Timer1 = 200; /* Initialization timeout of 1000 msec */ + if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2? */ + for (n = 0; n < 4; n++) ocr[n] = rcvr_spi(); /* Get trailing return value of R7 resp */ + if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */ + while (Timer1 && send_cmd(ACMD41, 1UL << 30)); /* Wait for leaving idle state (ACMD41 with HCS bit) */ + if (Timer1 && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */ + for (n = 0; n < 4; n++) ocr[n] = rcvr_spi(); + ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 */ + } + } + } else { /* SDv1 or MMCv3 */ + if (send_cmd(ACMD41, 0) <= 1) { + ty = CT_SD1; cmd = ACMD41; /* SDv1 */ + } else { + ty = CT_MMC; cmd = CMD1; /* MMCv3 */ + } + while (Timer1 && send_cmd(cmd, 0)); /* Wait for leaving idle state */ + if (!Timer1 || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */ + ty = 0; + } + } + + CardType = ty; + deselect(); + + if (ty) { /* Initialization succeded */ + Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */ + FCLK_FAST(); + } else { /* Initialization failed */ + //power_off(); + + } + + return Stat; +} + + + +/*-----------------------------------------------------------------------*/ +/* Get Disk Status */ +/*-----------------------------------------------------------------------*/ + +DSTATUS disk_status ( + BYTE drv /* Physical drive nmuber (0) */ +) +{ + if (drv) return STA_NOINIT; /* Supports only single drive */ + return Stat; +} + + + +/*-----------------------------------------------------------------------*/ +/* Read Sector(s) */ +/*-----------------------------------------------------------------------*/ + +DRESULT disk_read ( + BYTE drv, /* Physical drive nmuber (0) */ + BYTE *buff, /* Pointer to the data buffer to store read data */ + DWORD sector, /* Start sector number (LBA) */ + BYTE count /* Sector count (1..255) */ +) +{ + if (drv || !count) return RES_PARERR; + if (Stat & STA_NOINIT) return RES_NOTRDY; + + if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ + + if (count == 1) { /* Single block read */ + if ((send_cmd(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */ + && rcvr_datablock(buff, 512)) + count = 0; + } + else { /* Multiple block read */ + if (send_cmd(CMD18, sector) == 0) { /* READ_MULTIPLE_BLOCK */ + do { + if (!rcvr_datablock(buff, 512)) break; + buff += 512; + } while (--count); + send_cmd(CMD12, 0); /* STOP_TRANSMISSION */ + } + } + deselect(); + + return count ? RES_ERROR : RES_OK; +} + + + +/*-----------------------------------------------------------------------*/ +/* Write Sector(s) */ +/*-----------------------------------------------------------------------*/ + +#if _READONLY == 0 +DRESULT disk_write ( + BYTE drv, /* Physical drive nmuber (0) */ + const BYTE *buff, /* Pointer to the data to be written */ + DWORD sector, /* Start sector number (LBA) */ + BYTE count /* Sector count (1..255) */ +) +{ + if (drv || !count) return RES_PARERR; + if (Stat & STA_NOINIT) return RES_NOTRDY; + if (Stat & STA_PROTECT) return RES_WRPRT; + + if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ + + if (count == 1) { /* Single block write */ + if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */ + && xmit_datablock(buff, 0xFE)) + count = 0; + } + else { /* Multiple block write */ + if (CardType & CT_SDC) send_cmd(ACMD23, count); + if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */ + do { + if (!xmit_datablock(buff, 0xFC)) break; + buff += 512; + } while (--count); + if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */ + count = 1; + } + } + deselect(); + + return count ? RES_ERROR : RES_OK; +} +#endif /* _READONLY == 0 */ + + + +/*-----------------------------------------------------------------------*/ +/* Miscellaneous Functions */ +/*-----------------------------------------------------------------------*/ + +#if _USE_IOCTL != 0 +DRESULT disk_ioctl ( + BYTE drv, /* Physical drive nmuber (0) */ + BYTE ctrl, /* Control code */ + void *buff /* Buffer to send/receive control data */ +) +{ + DRESULT res; + BYTE n, csd[16], *ptr = buff; + WORD csize; + + + if (drv) return RES_PARERR; + + res = RES_ERROR; + + if (ctrl == CTRL_POWER) { + switch (*ptr) { + case 0: /* Sub control code == 0 (POWER_OFF) */ + if (chk_power()) + //power_off(); // Power off */ + res = RES_OK; + break; + case 1: /* Sub control code == 1 (POWER_ON) */ + //power_on(); // Power on */ + res = RES_OK; + break; + case 2: /* Sub control code == 2 (POWER_GET) */ + *(ptr+1) = (BYTE)chk_power(); + res = RES_OK; + break; + default : + res = RES_PARERR; + } + } + else { + if (Stat & STA_NOINIT) return RES_NOTRDY; + + switch (ctrl) { + case CTRL_SYNC : /* Make sure that no pending write process. Do not remove this or written sector might not left updated. */ + if (select()) { + deselect(); + res = RES_OK; + } + break; + + case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */ + if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { + if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */ + csize = csd[9] + ((WORD)csd[8] << 8) + 1; + *(DWORD*)buff = (DWORD)csize << 10; + } else { /* SDC ver 1.XX or MMC*/ + n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2; + csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1; + *(DWORD*)buff = (DWORD)csize << (n - 9); + } + res = RES_OK; + } + break; + + case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */ + *(WORD*)buff = 512; + res = RES_OK; + break; + + case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */ + if (CardType & CT_SD2) { /* SDv2? */ + if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */ + rcvr_spi(); + if (rcvr_datablock(csd, 16)) { /* Read partial block */ + for (n = 64 - 16; n; n--) rcvr_spi(); /* Purge trailing data */ + *(DWORD*)buff = 16UL << (csd[10] >> 4); + res = RES_OK; + } + } + } else { /* SDv1 or MMCv3 */ + if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { /* Read CSD */ + if (CardType & CT_SD1) { /* SDv1 */ + *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1); + } else { /* MMCv3 */ + *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1); + } + res = RES_OK; + } + } + break; + + case MMC_GET_TYPE : /* Get card type flags (1 byte) */ + *ptr = CardType; + res = RES_OK; + break; + + case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */ + if (send_cmd(CMD9, 0) == 0 /* READ_CSD */ + && rcvr_datablock(ptr, 16)) + res = RES_OK; + break; + + case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */ + if (send_cmd(CMD10, 0) == 0 /* READ_CID */ + && rcvr_datablock(ptr, 16)) + res = RES_OK; + break; + + case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */ + if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */ + for (n = 4; n; n--) *ptr++ = rcvr_spi(); + res = RES_OK; + } + break; + + case MMC_GET_SDSTAT : /* Receive SD statsu as a data block (64 bytes) */ + if (send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */ + rcvr_spi(); + if (rcvr_datablock(ptr, 64)) + res = RES_OK; + } + break; + + default: + res = RES_PARERR; + } + + deselect(); + } + + return res; +} +#endif /* _USE_IOCTL != 0 */ + + +/*-----------------------------------------------------------------------*/ +/* Device Timer Interrupt Procedure (Platform dependent) */ +/*-----------------------------------------------------------------------*/ +/* This function must be called in period of 10ms */ + +void disk_timerproc (void) +{ + static BYTE pv; + BYTE n, s; + + + n = Timer1; /* 100Hz decrement timer */ + if (n) Timer1 = --n; + n = Timer2; + if (n) Timer2 = --n; + + n = pv; + pv = SOCKPORT & (SOCKWP | SOCKINS); /* Sample socket switch */ + + if (n == pv) { /* Have contacts stabled? */ + s = Stat; + + if (pv & SOCKWP) /* WP is H (write protected) */ + s |= STA_PROTECT; + else /* WP is L (write enabled) */ + s &= ~STA_PROTECT; + + if (pv & SOCKINS) /* INS = H (Socket empty) */ + s |= (STA_NODISK | STA_NOINIT); + else /* INS = L (Card inserted) */ + s &= ~STA_NODISK; + + Stat = s; + } +} + +DWORD get_fattime () +{ + return 0; +} + diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/diskio.h b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/diskio.h new file mode 100644 index 0000000..a40cb6c --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/diskio.h @@ -0,0 +1,76 @@ +/*----------------------------------------------------------------------- +/ Low level disk interface modlue include file R0.07 (C)ChaN, 2009 +/-----------------------------------------------------------------------*/ + +#ifndef _DISKIO + +#define _READONLY 0 /* 1: Read-only mode */ +#define _USE_IOCTL 1 + +#include "integer.h" + + +/* Status of Disk Functions */ +typedef BYTE DSTATUS; + +/* Results of Disk Functions */ +typedef enum { + RES_OK = 0, /* 0: Successful */ + RES_ERROR, /* 1: R/W Error */ + RES_WRPRT, /* 2: Write Protected */ + RES_NOTRDY, /* 3: Not Ready */ + RES_PARERR /* 4: Invalid Parameter */ +} DRESULT; + + +/*---------------------------------------*/ +/* Prototypes for disk control functions */ + +DSTATUS disk_initialize (BYTE); +DSTATUS disk_status (BYTE); +DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE); +#if _READONLY == 0 +DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE); +#endif +DRESULT disk_ioctl (BYTE, BYTE, void*); + + + +/* Disk Status Bits (DSTATUS) */ + +#define STA_NOINIT 0x01 /* Drive not initialized */ +#define STA_NODISK 0x02 /* No medium in the drive */ +#define STA_PROTECT 0x04 /* Write protected */ + +/* Card type flags (CardType) */ + +#define CT_MMC 0x01 +#define CT_SD1 0x02 +#define CT_SD2 0x04 +#define CT_SDC (CT_SD1|CT_SD2) +#define CT_BLOCK 0x08 + +/* Command code for disk_ioctrl() */ + +/* Generic command */ +#define CTRL_SYNC 0 /* Mandatory for write functions */ +#define GET_SECTOR_COUNT 1 /* Mandatory for only f_mkfs() */ +#define GET_SECTOR_SIZE 2 /* Mandatory for multiple sector size cfg */ +#define GET_BLOCK_SIZE 3 /* Mandatory for only f_mkfs() */ +#define CTRL_POWER 4 +#define CTRL_LOCK 5 +#define CTRL_EJECT 6 +/* MMC/SDC command */ +#define MMC_GET_TYPE 10 +#define MMC_GET_CSD 11 +#define MMC_GET_CID 12 +#define MMC_GET_OCR 13 +#define MMC_GET_SDSTAT 14 +/* ATA/CF command */ +#define ATA_GET_REV 20 +#define ATA_GET_MODEL 21 +#define ATA_GET_SN 22 + + +#define _DISKIO +#endif diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/ff.c b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/ff.c new file mode 100644 index 0000000..236c86f --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/ff.c @@ -0,0 +1,3553 @@ +/*----------------------------------------------------------------------------/ +/ FatFs - FAT file system module R0.08 (C)ChaN, 2010 +/-----------------------------------------------------------------------------/ +/ FatFs module is a generic FAT file system module for small embedded systems. +/ This is a free software that opened for education, research and commercial +/ developments under license policy of following terms. +/ +/ Copyright (C) 2010, ChaN, all right reserved. +/ +/ * The FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/-----------------------------------------------------------------------------/ +/ Feb 26,'06 R0.00 Prototype. +/ +/ Apr 29,'06 R0.01 First stable version. +/ +/ Jun 01,'06 R0.02 Added FAT12 support. +/ Removed unbuffered mode. +/ Fixed a problem on small (<32M) partition. +/ Jun 10,'06 R0.02a Added a configuration option (_FS_MINIMUM). +/ +/ Sep 22,'06 R0.03 Added f_rename(). +/ Changed option _FS_MINIMUM to _FS_MINIMIZE. +/ Dec 11,'06 R0.03a Improved cluster scan algorithm to write files fast. +/ Fixed f_mkdir() creates incorrect directory on FAT32. +/ +/ Feb 04,'07 R0.04 Supported multiple drive system. +/ Changed some interfaces for multiple drive system. +/ Changed f_mountdrv() to f_mount(). +/ Added f_mkfs(). +/ Apr 01,'07 R0.04a Supported multiple partitions on a physical drive. +/ Added a capability of extending file size to f_lseek(). +/ Added minimization level 3. +/ Fixed an endian sensitive code in f_mkfs(). +/ May 05,'07 R0.04b Added a configuration option _USE_NTFLAG. +/ Added FSInfo support. +/ Fixed DBCS name can result FR_INVALID_NAME. +/ Fixed short seek (<= csize) collapses the file object. +/ +/ Aug 25,'07 R0.05 Changed arguments of f_read(), f_write() and f_mkfs(). +/ Fixed f_mkfs() on FAT32 creates incorrect FSInfo. +/ Fixed f_mkdir() on FAT32 creates incorrect directory. +/ Feb 03,'08 R0.05a Added f_truncate() and f_utime(). +/ Fixed off by one error at FAT sub-type determination. +/ Fixed btr in f_read() can be mistruncated. +/ Fixed cached sector is not flushed when create and close +/ without write. +/ +/ Apr 01,'08 R0.06 Added fputc(), fputs(), fprintf() and fgets(). +/ Improved performance of f_lseek() on moving to the same +/ or following cluster. +/ +/ Apr 01,'09 R0.07 Merged Tiny-FatFs as a buffer configuration option. +/ Added long file name support. +/ Added multiple code page support. +/ Added re-entrancy for multitask operation. +/ Added auto cluster size selection to f_mkfs(). +/ Added rewind option to f_readdir(). +/ Changed result code of critical errors. +/ Renamed string functions to avoid name collision. +/ Apr 14,'09 R0.07a Separated out OS dependent code on reentrant cfg. +/ Added multiple sector size support. +/ Jun 21,'09 R0.07c Fixed f_unlink() can return FR_OK on error. +/ Fixed wrong cache control in f_lseek(). +/ Added relative path feature. +/ Added f_chdir() and f_chdrive(). +/ Added proper case conversion to extended char. +/ Nov 03,'09 R0.07e Separated out configuration options from ff.h to ffconf.h. +/ Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH. +/ Fixed name matching error on the 13 char boundary. +/ Added a configuration option, _LFN_UNICODE. +/ Changed f_readdir() to return the SFN with always upper +/ case on non-LFN cfg. +/ +/ May 15,'10 R0.08 Added a memory configuration option. (_USE_LFN) +/ Added file lock feature. (_FS_SHARE) +/ Added fast seek feature. (_USE_FASTSEEK) +/ Changed some types on the API, XCHAR->TCHAR. +/ Changed fname member in the FILINFO structure on Unicode cfg. +/ String functions support UTF-8 encoding files on Unicode cfg. +/---------------------------------------------------------------------------*/ + +#include "ff.h" /* FatFs configurations and declarations */ +#include "diskio.h" /* Declarations of low level disk I/O functions */ + + +/*-------------------------------------------------------------------------- + + Module Private Definitions + +---------------------------------------------------------------------------*/ + +#if _FATFS != 8085 +#error Wrong include file (ff.h). +#endif + + +/* FAT sub-type boundaries */ +/* Note that the FAT spec by Microsoft says 4085 but Windows works with 4087! */ +#define MIN_FAT16 4086 /* Minimum number of clusters for FAT16 */ +#define MIN_FAT32 65526 /* Minimum number of clusters for FAT32 */ + + +/* Definitions corresponds to multiple sector size */ +#if _MAX_SS == 512 /* Single sector size */ +#define SS(fs) 512U +#elif _MAX_SS == 1024 || _MAX_SS == 2048 || _MAX_SS == 4096 /* Multiple sector size */ +#define SS(fs) ((fs)->ssize) +#else +#error Wrong sector size. +#endif + + +/* Reentrancy related */ +#if _FS_REENTRANT +#if _USE_LFN == 1 +#error Static LFN work area must not be used in re-entrant configuration. +#endif +#define ENTER_FF(fs) { if (!lock_fs(fs)) return FR_TIMEOUT; } +#define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; } + +#else +#define ENTER_FF(fs) +#define LEAVE_FF(fs, res) return res + +#endif + +#define ABORT(fs, res) { fp->flag |= FA__ERROR; LEAVE_FF(fs, res); } + + +/* Character code support macros */ +#define IsUpper(c) (((c)>='A')&&((c)<='Z')) +#define IsLower(c) (((c)>='a')&&((c)<='z')) +#define IsDigit(c) (((c)>='0')&&((c)<='9')) + +#if _DF1S /* Code page is DBCS */ + +#ifdef _DF2S /* Two 1st byte areas */ +#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E)) +#else /* One 1st byte area */ +#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) +#endif + +#ifdef _DS3S /* Three 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E)) +#else /* Two 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E)) +#endif + +#else /* Code page is SBCS */ + +#define IsDBCS1(c) 0 +#define IsDBCS2(c) 0 + +#endif /* _DF1S */ + + +/* Name status flags */ +#define NS 11 /* Offset of name status byte */ +#define NS_LOSS 0x01 /* Out of 8.3 format */ +#define NS_LFN 0x02 /* Force to create LFN entry */ +#define NS_LAST 0x04 /* Last segment */ +#define NS_BODY 0x08 /* Lower case flag (body) */ +#define NS_EXT 0x10 /* Lower case flag (ext) */ +#define NS_DOT 0x20 /* Dot entry */ + + + +/*------------------------------------------------------------*/ +/* Work area */ + +#if !_DRIVES +#error Number of drives must not be 0. +#endif +static +WORD Fsid; /* File system mount ID */ +static +FATFS *FatFs[_DRIVES]; /* Pointer to the file system objects (logical drives) */ + +#if _FS_RPATH +static +BYTE Drive; /* Current drive */ +#endif + + +#if _USE_LFN == 0 /* No LFN */ +#define DEF_NAMEBUF BYTE sfn[12] +#define INIT_BUF(dobj) (dobj).fn = sfn +#define FREE_BUF() + +#elif _USE_LFN == 1 /* LFN with static LFN working buffer */ +static WCHAR LfnBuf[_MAX_LFN + 1]; +#define DEF_NAMEBUF BYTE sfn[12] +#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = LfnBuf; } +#define FREE_BUF() + +#elif _USE_LFN == 2 /* LFN with dynamic LFN working buffer on the stack */ +#define DEF_NAMEBUF BYTE sfn[12]; WCHAR lbuf[_MAX_LFN + 1] +#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = lbuf; } +#define FREE_BUF() + +#elif _USE_LFN == 3 /* LFN with dynamic LFN working buffer on the heap */ +#define DEF_NAMEBUF BYTE sfn[12]; WCHAR *lfn +#define INIT_BUF(dobj) { lfn = ff_memalloc((_MAX_LFN + 1) * 2); \ + if (!lfn) LEAVE_FF((dobj).fs, FR_NOT_ENOUGH_CORE); \ + (dobj).lfn = lfn; (dobj).fn = sfn; } +#define FREE_BUF() ff_memfree(lfn) + +#else +#error Wrong LFN configuration. +#endif + + + + +/*-------------------------------------------------------------------------- + + Module Private Functions + +---------------------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------------*/ +/* String functions */ +/*-----------------------------------------------------------------------*/ + +/* Copy memory to memory */ +static +void mem_cpy (void* dst, const void* src, int cnt) { + BYTE *d = (BYTE*)dst; + const BYTE *s = (const BYTE*)src; + +#if _WORD_ACCESS == 1 + while (cnt >= sizeof(int)) { + *(int*)d = *(int*)s; + d += sizeof(int); s += sizeof(int); + cnt -= sizeof(int); + } +#endif + while (cnt--) + *d++ = *s++; +} + +/* Fill memory */ +static +void mem_set (void* dst, int val, int cnt) { + BYTE *d = (BYTE*)dst; + + while (cnt--) + *d++ = (BYTE)val; +} + +/* Compare memory to memory */ +static +int mem_cmp (const void* dst, const void* src, int cnt) { + const BYTE *d = (const BYTE *)dst, *s = (const BYTE *)src; + int r = 0; + + while (cnt-- && (r = *d++ - *s++) == 0) ; + return r; +} + +/* Check if chr is contained in the string */ +static +int chk_chr (const char* str, int chr) { + while (*str && *str != chr) str++; + return *str; +} + + + +/*-----------------------------------------------------------------------*/ +/* Request/Release grant to access the volume */ +/*-----------------------------------------------------------------------*/ +#if _FS_REENTRANT + +static +int lock_fs ( + FATFS *fs /* File system object */ +) +{ + return ff_req_grant(fs->sobj); +} + + +static +void unlock_fs ( + FATFS *fs, /* File system object */ + FRESULT res /* Result code to be returned */ +) +{ + if (res != FR_NOT_ENABLED && + res != FR_INVALID_DRIVE && + res != FR_INVALID_OBJECT && + res != FR_TIMEOUT) { + ff_rel_grant(fs->sobj); + } +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* File shareing control functions */ +/*-----------------------------------------------------------------------*/ +#if _FS_SHARE + +static +FRESULT chk_lock ( /* Check if the file can be accessed */ + DIR* dj, /* Directory object pointing the file to be checked */ + int acc /* Desired access (0:Read, 1:Write, 2:Delete/Rename) */ +) +{ + UINT i, be; + + /* Search file semaphore table */ + for (i = be = 0; i < _FS_SHARE; i++) { + if (dj->fs->flsem[i].ctr) { /* Existing entry */ + if (dj->fs->flsem[i].clu == dj->sclust && /* The file is found (identified with its location) */ + dj->fs->flsem[i].idx == dj->index) break; + } else { /* Blank entry */ + be++; + } + } + if (i == _FS_SHARE) /* The file has not been opened */ + return (be || acc != 2) ? FR_OK : FR_TOO_MANY_OPEN_FILES; /* Is there a blank entry for new file? */ + + /* The file has been opened. Reject any open against writing file and all write mode open */ + return (acc || dj->fs->flsem[i].ctr == 0x100) ? FR_LOCKED : FR_OK; +} + + +static +int enq_lock ( /* Check if an entry is available for a new file */ + FATFS* fs /* File system object */ +) +{ + UINT i; + + for (i = 0; i < _FS_SHARE && fs->flsem[i].ctr; i++) ; + return (i == _FS_SHARE) ? 0 : 1; +} + + +static +UINT inc_lock ( /* Increment file open counter and returns its index (0:int error) */ + DIR* dj, /* Directory object pointing the file to register or increment */ + int acc /* Desired access mode (0:Read, !0:Write) */ +) +{ + UINT i; + + + for (i = 0; i < _FS_SHARE; i++) { /* Find the file */ + if (dj->fs->flsem[i].ctr && + dj->fs->flsem[i].clu == dj->sclust && + dj->fs->flsem[i].idx == dj->index) break; + } + + if (i == _FS_SHARE) { /* Not opened. Register it as new. */ + for (i = 0; i < _FS_SHARE && dj->fs->flsem[i].ctr; i++) ; + if (i == _FS_SHARE) return 0; /* No space to register (int err) */ + dj->fs->flsem[i].clu = dj->sclust; + dj->fs->flsem[i].idx = dj->index; + } + + if (acc && dj->fs->flsem[i].ctr) return 0; /* Access violation (int err) */ + + dj->fs->flsem[i].ctr = acc ? 0x100 : dj->fs->flsem[i].ctr + 1; /* Set semaphore value */ + + return i + 1; +} + + +static +FRESULT dec_lock ( /* Decrement file open counter */ + FATFS* fs, /* File system object */ + UINT i /* Semaphore index */ +) +{ + WORD n; + FRESULT res; + + + if (--i < _FS_SHARE) { + n = fs->flsem[i].ctr; + if (n >= 0x100) n = 0; + if (n) n--; + fs->flsem[i].ctr = n; + res = FR_OK; + } else { + res = FR_INT_ERR; + } + return res; +} + +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Change window offset */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT move_window ( + FATFS *fs, /* File system object */ + DWORD sector /* Sector number to make appearance in the fs->win[] */ +) /* Move to zero only writes back dirty window */ +{ + DWORD wsect; + + + wsect = fs->winsect; + if (wsect != sector) { /* Changed current window */ +#if !_FS_READONLY + if (fs->wflag) { /* Write back dirty window if needed */ + if (disk_write(fs->drv, fs->win, wsect, 1) != RES_OK) + return FR_DISK_ERR; + fs->wflag = 0; + if (wsect < (fs->fatbase + fs->fsize)) { /* In FAT area */ + BYTE nf; + for (nf = fs->n_fats; nf > 1; nf--) { /* Reflect the change to all FAT copies */ + wsect += fs->fsize; + disk_write(fs->drv, fs->win, wsect, 1); + } + } + } +#endif + if (sector) { + if (disk_read(fs->drv, fs->win, sector, 1) != RES_OK) + return FR_DISK_ERR; + fs->winsect = sector; + } + } + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Clean-up cached data */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT sync ( /* FR_OK: successful, FR_DISK_ERR: failed */ + FATFS *fs /* File system object */ +) +{ + FRESULT res; + + + res = move_window(fs, 0); + if (res == FR_OK) { + /* Update FSInfo sector if needed */ + if (fs->fs_type == FS_FAT32 && fs->fsi_flag) { + fs->winsect = 0; + mem_set(fs->win, 0, 512); + ST_WORD(fs->win+BS_55AA, 0xAA55); + ST_DWORD(fs->win+FSI_LeadSig, 0x41615252); + ST_DWORD(fs->win+FSI_StrucSig, 0x61417272); + ST_DWORD(fs->win+FSI_Free_Count, fs->free_clust); + ST_DWORD(fs->win+FSI_Nxt_Free, fs->last_clust); + disk_write(fs->drv, fs->win, fs->fsi_sector, 1); + fs->fsi_flag = 0; + } + /* Make sure that no pending write process in the physical drive */ + if (disk_ioctl(fs->drv, CTRL_SYNC, (void*)0) != RES_OK) + res = FR_DISK_ERR; + } + + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Read value of a FAT entry */ +/*-----------------------------------------------------------------------*/ + + +DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to get the link information */ +) +{ + UINT wc, bc; + BYTE *p; + + + if (clst < 2 || clst >= fs->n_fatent) /* Chack range */ + return 1; + + switch (fs->fs_type) { + case FS_FAT12 : + bc = (UINT)clst; bc += bc / 2; + if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break; + wc = fs->win[bc % SS(fs)]; bc++; + if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break; + wc |= fs->win[bc % SS(fs)] << 8; + return (clst & 1) ? (wc >> 4) : (wc & 0xFFF); + + case FS_FAT16 : + if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)))) break; + p = &fs->win[clst * 2 % SS(fs)]; + return LD_WORD(p); + + case FS_FAT32 : + if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)))) break; + p = &fs->win[clst * 4 % SS(fs)]; + return LD_DWORD(p) & 0x0FFFFFFF; + } + + return 0xFFFFFFFF; /* An error occurred at the disk I/O layer */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Change value of a FAT entry */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY + +FRESULT put_fat ( + FATFS *fs, /* File system object */ + DWORD clst, /* Cluster# to be changed in range of 2 to fs->n_fatent - 1 */ + DWORD val /* New value to mark the cluster */ +) +{ + UINT bc; + BYTE *p; + FRESULT res; + + + if (clst < 2 || clst >= fs->n_fatent) { /* Check range */ + res = FR_INT_ERR; + + } else { + switch (fs->fs_type) { + case FS_FAT12 : + bc = clst; bc += bc / 2; + res = move_window(fs, fs->fatbase + (bc / SS(fs))); + if (res != FR_OK) break; + p = &fs->win[bc % SS(fs)]; + *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val; + bc++; + fs->wflag = 1; + res = move_window(fs, fs->fatbase + (bc / SS(fs))); + if (res != FR_OK) break; + p = &fs->win[bc % SS(fs)]; + *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F)); + break; + + case FS_FAT16 : + res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))); + if (res != FR_OK) break; + p = &fs->win[clst * 2 % SS(fs)]; + ST_WORD(p, (WORD)val); + break; + + case FS_FAT32 : + res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))); + if (res != FR_OK) break; + p = &fs->win[clst * 4 % SS(fs)]; + val |= LD_DWORD(p) & 0xF0000000; + ST_DWORD(p, val); + break; + + default : + res = FR_INT_ERR; + } + fs->wflag = 1; + } + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Remove a cluster chain */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT remove_chain ( + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to remove a chain from */ +) +{ + FRESULT res; + DWORD nxt; + + + if (clst < 2 || clst >= fs->n_fatent) { /* Check range */ + res = FR_INT_ERR; + + } else { + res = FR_OK; + while (clst < fs->n_fatent) { /* Not a last link? */ + nxt = get_fat(fs, clst); /* Get cluster status */ + if (nxt == 0) break; /* Empty cluster? */ + if (nxt == 1) { res = FR_INT_ERR; break; } /* Internal error? */ + if (nxt == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } /* Disk error? */ + res = put_fat(fs, clst, 0); /* Mark the cluster "empty" */ + if (res != FR_OK) break; + if (fs->free_clust != 0xFFFFFFFF) { /* Update FSInfo */ + fs->free_clust++; + fs->fsi_flag = 1; + } + clst = nxt; /* Next cluster */ + } + } + + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Stretch or Create a cluster chain */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to stretch. 0 means create a new chain. */ +) +{ + DWORD cs, ncl, scl; + + + if (clst == 0) { /* Create a new chain */ + scl = fs->last_clust; /* Get suggested start point */ + if (!scl || scl >= fs->n_fatent) scl = 1; + } + else { /* Stretch the current chain */ + cs = get_fat(fs, clst); /* Check the cluster status */ + if (cs < 2) return 1; /* It is an invalid cluster */ + if (cs < fs->n_fatent) return cs; /* It is already followed by next cluster */ + scl = clst; + } + + ncl = scl; /* Start cluster */ + for (;;) { + ncl++; /* Next cluster */ + if (ncl >= fs->n_fatent) { /* Wrap around */ + ncl = 2; + if (ncl > scl) return 0; /* No free cluster */ + } + cs = get_fat(fs, ncl); /* Get the cluster status */ + if (cs == 0) break; /* Found a free cluster */ + if (cs == 0xFFFFFFFF || cs == 1)/* An error occurred */ + return cs; + if (ncl == scl) return 0; /* No free cluster */ + } + + if (put_fat(fs, ncl, 0x0FFFFFFF)) /* Mark the new cluster "last link" */ + return 0xFFFFFFFF; + if (clst != 0) { /* Link it to the previous one if needed */ + if (put_fat(fs, clst, ncl)) + return 0xFFFFFFFF; + } + + fs->last_clust = ncl; /* Update FSINFO */ + if (fs->free_clust != 0xFFFFFFFF) { + fs->free_clust--; + fs->fsi_flag = 1; + } + + return ncl; /* Return new cluster number */ +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Get sector# from cluster# */ +/*-----------------------------------------------------------------------*/ + + +DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to be converted */ +) +{ + clst -= 2; + if (clst >= (fs->n_fatent - 2)) return 0; /* Invalid cluster# */ + return clst * fs->csize + fs->database; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Set directory index */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_sdi ( + DIR *dj, /* Pointer to directory object */ + WORD idx /* Directory index number */ +) +{ + DWORD clst; + WORD ic; + + + dj->index = idx; + clst = dj->sclust; + if (clst == 1 || clst >= dj->fs->n_fatent) /* Check start cluster range */ + return FR_INT_ERR; + if (!clst && dj->fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */ + clst = dj->fs->dirbase; + + if (clst == 0) { /* Static table */ + dj->clust = clst; + if (idx >= dj->fs->n_rootdir) /* Index is out of range */ + return FR_INT_ERR; + dj->sect = dj->fs->dirbase + idx / (SS(dj->fs) / 32); /* Sector# */ + } + else { /* Dynamic table */ + ic = SS(dj->fs) / 32 * dj->fs->csize; /* Entries per cluster */ + while (idx >= ic) { /* Follow cluster chain */ + clst = get_fat(dj->fs, clst); /* Get next cluster */ + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ + if (clst < 2 || clst >= dj->fs->n_fatent) /* Reached to end of table or int error */ + return FR_INT_ERR; + idx -= ic; + } + dj->clust = clst; + dj->sect = clust2sect(dj->fs, clst) + idx / (SS(dj->fs) / 32); /* Sector# */ + } + + dj->dir = dj->fs->win + (idx % (SS(dj->fs) / 32)) * 32; /* Ptr to the entry in the sector */ + + return FR_OK; /* Seek succeeded */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Move directory index next */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:EOT and could not stretch */ + DIR *dj, /* Pointer to directory object */ + int stretch /* 0: Do not stretch table, 1: Stretch table if needed */ +) +{ + DWORD clst; + WORD i; + + + i = dj->index + 1; + if (!i || !dj->sect) /* Report EOT when index has reached 65535 */ + return FR_NO_FILE; + + if (!(i % (SS(dj->fs) / 32))) { /* Sector changed? */ + dj->sect++; /* Next sector */ + + if (dj->clust == 0) { /* Static table */ + if (i >= dj->fs->n_rootdir) /* Report EOT when end of table */ + return FR_NO_FILE; + } + else { /* Dynamic table */ + if (((i / (SS(dj->fs) / 32)) & (dj->fs->csize - 1)) == 0) { /* Cluster changed? */ + clst = get_fat(dj->fs, dj->clust); /* Get next cluster */ + if (clst <= 1) return FR_INT_ERR; + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; + if (clst >= dj->fs->n_fatent) { /* When it reached end of dynamic table */ +#if !_FS_READONLY + BYTE c; + if (!stretch) return FR_NO_FILE; /* When do not stretch, report EOT */ + clst = create_chain(dj->fs, dj->clust); /* Stretch cluster chain */ + if (clst == 0) return FR_DENIED; /* No free cluster */ + if (clst == 1) return FR_INT_ERR; + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; + /* Clean-up stretched table */ + if (move_window(dj->fs, 0)) return FR_DISK_ERR; /* Flush active window */ + mem_set(dj->fs->win, 0, SS(dj->fs)); /* Clear window buffer */ + dj->fs->winsect = clust2sect(dj->fs, clst); /* Cluster start sector */ + for (c = 0; c < dj->fs->csize; c++) { /* Fill the new cluster with 0 */ + dj->fs->wflag = 1; + if (move_window(dj->fs, 0)) return FR_DISK_ERR; + dj->fs->winsect++; + } + dj->fs->winsect -= c; /* Rewind window address */ +#else + return FR_NO_FILE; /* Report EOT */ +#endif + } + dj->clust = clst; /* Initialize data for new cluster */ + dj->sect = clust2sect(dj->fs, clst); + } + } + } + + dj->index = i; + dj->dir = dj->fs->win + (i % (SS(dj->fs) / 32)) * 32; + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* LFN handling - Test/Pick/Fit an LFN segment from/to directory entry */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +static +const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30}; /* Offset of LFN chars in the directory entry */ + + +static +int cmp_lfn ( /* 1:Matched, 0:Not matched */ + WCHAR *lfnbuf, /* Pointer to the LFN to be compared */ + BYTE *dir /* Pointer to the directory entry containing a part of LFN */ +) +{ + int i, s; + WCHAR wc, uc; + + + i = ((dir[LDIR_Ord] & 0xBF) - 1) * 13; /* Get offset in the LFN buffer */ + s = 0; wc = 1; + do { + uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + if (wc) { /* Last char has not been processed */ + wc = ff_wtoupper(uc); /* Convert it to upper case */ + if (i >= _MAX_LFN || wc != ff_wtoupper(lfnbuf[i++])) /* Compare it */ + return 0; /* Not matched */ + } else { + if (uc != 0xFFFF) return 0; /* Check filler */ + } + } while (++s < 13); /* Repeat until all chars in the entry are checked */ + + if ((dir[LDIR_Ord] & 0x40) && wc && lfnbuf[i]) /* Last segment matched but different length */ + return 0; + + return 1; /* The part of LFN matched */ +} + + + +static +int pick_lfn ( /* 1:Succeeded, 0:Buffer overflow */ + WCHAR *lfnbuf, /* Pointer to the Unicode-LFN buffer */ + BYTE *dir /* Pointer to the directory entry */ +) +{ + int i, s; + WCHAR wc, uc; + + + i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13; /* Offset in the LFN buffer */ + + s = 0; wc = 1; + do { + uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + if (wc) { /* Last char has not been processed */ + if (i >= _MAX_LFN) return 0; /* Buffer overflow? */ + lfnbuf[i++] = wc = uc; /* Store it */ + } else { + if (uc != 0xFFFF) return 0; /* Check filler */ + } + } while (++s < 13); /* Read all character in the entry */ + + if (dir[LDIR_Ord] & 0x40) { /* Put terminator if it is the last LFN part */ + if (i >= _MAX_LFN) return 0; /* Buffer overflow? */ + lfnbuf[i] = 0; + } + + return 1; +} + + +#if !_FS_READONLY +static +void fit_lfn ( + const WCHAR *lfnbuf, /* Pointer to the LFN buffer */ + BYTE *dir, /* Pointer to the directory entry */ + BYTE ord, /* LFN order (1-20) */ + BYTE sum /* SFN sum */ +) +{ + int i, s; + WCHAR wc; + + + dir[LDIR_Chksum] = sum; /* Set check sum */ + dir[LDIR_Attr] = AM_LFN; /* Set attribute. LFN entry */ + dir[LDIR_Type] = 0; + ST_WORD(dir+LDIR_FstClusLO, 0); + + i = (ord - 1) * 13; /* Get offset in the LFN buffer */ + s = wc = 0; + do { + if (wc != 0xFFFF) wc = lfnbuf[i++]; /* Get an effective char */ + ST_WORD(dir+LfnOfs[s], wc); /* Put it */ + if (!wc) wc = 0xFFFF; /* Padding chars following last char */ + } while (++s < 13); + if (wc == 0xFFFF || !lfnbuf[i]) ord |= 0x40; /* Bottom LFN part is the start of LFN sequence */ + dir[LDIR_Ord] = ord; /* Set the LFN order */ +} + +#endif +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Create numbered name */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +void gen_numname ( + BYTE *dst, /* Pointer to generated SFN */ + const BYTE *src, /* Pointer to source SFN to be modified */ + const WCHAR *lfn, /* Pointer to LFN */ + WORD seq /* Sequence number */ +) +{ + BYTE ns[8], c; + int i, j; + + + mem_cpy(dst, src, 11); + + if (seq > 5) { /* On many collisions, generate a hash number instead of sequential number */ + do seq = (seq >> 1) + (seq << 15) + (WORD)*lfn++; while (*lfn); + } + + /* itoa */ + i = 7; + do { + c = (seq % 16) + '0'; + if (c > '9') c += 7; + ns[i--] = c; + seq /= 16; + } while (seq); + ns[i] = '~'; + + /* Append the number */ + for (j = 0; j < i && dst[j] != ' '; j++) { + if (IsDBCS1(dst[j])) { + if (j == i - 1) break; + j++; + } + } + do { + dst[j++] = (i < 8) ? ns[i++] : ' '; + } while (j < 8); +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Calculate sum of an SFN */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +static +BYTE sum_sfn ( + const BYTE *dir /* Ptr to directory entry */ +) +{ + BYTE sum = 0; + int n = 11; + + do sum = (sum >> 1) + (sum << 7) + *dir++; while (--n); + return sum; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Find an object in the directory */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_find ( + DIR *dj /* Pointer to the directory object linked to the file name */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN + BYTE a, ord, sum; +#endif + + res = dir_sdi(dj, 0); /* Rewind directory object */ + if (res != FR_OK) return res; + +#if _USE_LFN + ord = sum = 0xFF; +#endif + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + dir = dj->dir; /* Ptr to the directory entry of current index */ + c = dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ +#if _USE_LFN /* LFN configuration */ + a = dir[DIR_Attr] & AM_MASK; + if (c == 0xE5 || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ + ord = 0xFF; + } else { + if (a == AM_LFN) { /* An LFN entry is found */ + if (dj->lfn) { + if (c & 0x40) { /* Is it start of LFN sequence? */ + sum = dir[LDIR_Chksum]; + c &= 0xBF; ord = c; /* LFN start order */ + dj->lfn_idx = dj->index; + } + /* Check validity of the LFN entry and compare it with given name */ + ord = (c == ord && sum == dir[LDIR_Chksum] && cmp_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF; + } + } else { /* An SFN entry is found */ + if (!ord && sum == sum_sfn(dir)) break; /* LFN matched? */ + ord = 0xFF; dj->lfn_idx = 0xFFFF; /* Reset LFN sequence */ + if (!(dj->fn[NS] & NS_LOSS) && !mem_cmp(dir, dj->fn, 11)) break; /* SFN matched? */ + } + } +#else /* Non LFN configuration */ + if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */ + break; +#endif + res = dir_next(dj, 0); /* Next entry */ + } while (res == FR_OK); + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read an object from the directory */ +/*-----------------------------------------------------------------------*/ +#if _FS_MINIMIZE <= 1 +static +FRESULT dir_read ( + DIR *dj /* Pointer to the directory object that pointing the entry to be read */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN + BYTE a, ord = 0xFF, sum = 0xFF; +#endif + + res = FR_NO_FILE; + while (dj->sect) { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + dir = dj->dir; /* Ptr to the directory entry of current index */ + c = dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ +#if _USE_LFN /* LFN configuration */ + a = dir[DIR_Attr] & AM_MASK; + if (c == 0xE5 || (!_FS_RPATH && c == '.') || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ + ord = 0xFF; + } else { + if (a == AM_LFN) { /* An LFN entry is found */ + if (c & 0x40) { /* Is it start of LFN sequence? */ + sum = dir[LDIR_Chksum]; + c &= 0xBF; ord = c; + dj->lfn_idx = dj->index; + } + /* Check LFN validity and capture it */ + ord = (c == ord && sum == dir[LDIR_Chksum] && pick_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF; + } else { /* An SFN entry is found */ + if (ord || sum != sum_sfn(dir)) /* Is there a valid LFN? */ + dj->lfn_idx = 0xFFFF; /* It has no LFN. */ + break; + } + } +#else /* Non LFN configuration */ + if (c != 0xE5 && (_FS_RPATH || c != '.') && !(dir[DIR_Attr] & AM_VOL)) /* Is it a valid entry? */ + break; +#endif + res = dir_next(dj, 0); /* Next entry */ + if (res != FR_OK) break; + } + + if (res != FR_OK) dj->sect = 0; + + return res; +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Register an object to the directory */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT dir_register ( /* FR_OK:Successful, FR_DENIED:No free entry or too many SFN collision, FR_DISK_ERR:Disk error */ + DIR *dj /* Target directory with object name to be created */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN /* LFN configuration */ + WORD n, ne, is; + BYTE sn[12], *fn, sum; + WCHAR *lfn; + + + fn = dj->fn; lfn = dj->lfn; + mem_cpy(sn, fn, 12); + + if (_FS_RPATH && (sn[NS] & NS_DOT)) return FR_INVALID_NAME; /* Cannot create dot entry */ + + if (sn[NS] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */ + fn[NS] = 0; dj->lfn = 0; /* Find only SFN */ + for (n = 1; n < 100; n++) { + gen_numname(fn, sn, lfn, n); /* Generate a numbered name */ + res = dir_find(dj); /* Check if the name collides with existing SFN */ + if (res != FR_OK) break; + } + if (n == 100) return FR_DENIED; /* Abort if too many collisions */ + if (res != FR_NO_FILE) return res; /* Abort if the result is other than 'not collided' */ + fn[NS] = sn[NS]; dj->lfn = lfn; + } + + if (sn[NS] & NS_LFN) { /* When LFN is to be created, reserve an SFN + LFN entries. */ + for (ne = 0; lfn[ne]; ne++) ; + ne = (ne + 25) / 13; + } else { /* Otherwise reserve only an SFN entry. */ + ne = 1; + } + + /* Reserve contiguous entries */ + res = dir_sdi(dj, 0); + if (res != FR_OK) return res; + n = is = 0; + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + c = *dj->dir; /* Check the entry status */ + if (c == 0xE5 || c == 0) { /* Is it a blank entry? */ + if (n == 0) is = dj->index; /* First index of the contiguous entry */ + if (++n == ne) break; /* A contiguous entry that required count is found */ + } else { + n = 0; /* Not a blank entry. Restart to search */ + } + res = dir_next(dj, 1); /* Next entry with table stretch */ + } while (res == FR_OK); + + if (res == FR_OK && ne > 1) { /* Initialize LFN entry if needed */ + res = dir_sdi(dj, is); + if (res == FR_OK) { + sum = sum_sfn(dj->fn); /* Sum of the SFN tied to the LFN */ + ne--; + do { /* Store LFN entries in bottom first */ + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + fit_lfn(dj->lfn, dj->dir, (BYTE)ne, sum); + dj->fs->wflag = 1; + res = dir_next(dj, 0); /* Next entry */ + } while (res == FR_OK && --ne); + } + } + +#else /* Non LFN configuration */ + res = dir_sdi(dj, 0); + if (res == FR_OK) { + do { /* Find a blank entry for the SFN */ + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + c = *dj->dir; + if (c == 0xE5 || c == 0) break; /* Is it a blank entry? */ + res = dir_next(dj, 1); /* Next entry with table stretch */ + } while (res == FR_OK); + } +#endif + + if (res == FR_OK) { /* Initialize the SFN entry */ + res = move_window(dj->fs, dj->sect); + if (res == FR_OK) { + dir = dj->dir; + mem_set(dir, 0, 32); /* Clean the entry */ + mem_cpy(dir, dj->fn, 11); /* Put SFN */ +#if _USE_LFN + dir[DIR_NTres] = *(dj->fn+NS) & (NS_BODY | NS_EXT); /* Put NT flag */ +#endif + dj->fs->wflag = 1; + } + } + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Remove an object from the directory */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY && !_FS_MINIMIZE +static +FRESULT dir_remove ( /* FR_OK: Successful, FR_DISK_ERR: A disk error */ + DIR *dj /* Directory object pointing the entry to be removed */ +) +{ + FRESULT res; +#if _USE_LFN /* LFN configuration */ + WORD i; + + i = dj->index; /* SFN index */ + res = dir_sdi(dj, (WORD)((dj->lfn_idx == 0xFFFF) ? i : dj->lfn_idx)); /* Goto the SFN or top of the LFN entries */ + if (res == FR_OK) { + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + *dj->dir = 0xE5; /* Mark the entry "deleted" */ + dj->fs->wflag = 1; + if (dj->index >= i) break; /* When reached SFN, all entries of the object has been deleted. */ + res = dir_next(dj, 0); /* Next entry */ + } while (res == FR_OK); + if (res == FR_NO_FILE) res = FR_INT_ERR; + } + +#else /* Non LFN configuration */ + res = dir_sdi(dj, dj->index); + if (res == FR_OK) { + res = move_window(dj->fs, dj->sect); + if (res == FR_OK) { + *dj->dir = 0xE5; /* Mark the entry "deleted" */ + dj->fs->wflag = 1; + } + } +#endif + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Pick a segment and create the object name in directory form */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT create_name ( + DIR *dj, /* Pointer to the directory object */ + const TCHAR **path /* Pointer to pointer to the segment in the path string */ +) +{ +#ifdef _EXCVT + static const BYTE excvt[] = _EXCVT; /* Upper conversion table for extended chars */ +#endif + +#if _USE_LFN /* LFN configuration */ + BYTE b, cf; + WCHAR w, *lfn; + int i, ni, si, di; + const TCHAR *p; + + /* Create LFN in Unicode */ + si = di = 0; + p = *path; + lfn = dj->lfn; + for (;;) { + w = p[si++]; /* Get a character */ + if (w < ' ' || w == '/' || w == '\\') break; /* Break on end of segment */ + if (di >= _MAX_LFN) /* Reject too long name */ + return FR_INVALID_NAME; +#if !_LFN_UNICODE + w &= 0xFF; + if (IsDBCS1(w)) { /* If it is a DBC 1st byte */ + b = p[si++]; /* Get 2nd byte */ + if (!IsDBCS2(b)) /* Reject invalid code for DBC */ + return FR_INVALID_NAME; + w = (w << 8) + b; + } + w = ff_convert(w, 1); /* Convert OEM to Unicode */ + if (!w) return FR_INVALID_NAME; /* Reject invalid code */ +#endif + if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) /* Reject illegal chars for LFN */ + return FR_INVALID_NAME; + lfn[di++] = w; /* Store the Unicode char */ + } + *path = &p[si]; /* Return pointer to the next segment */ + cf = (w < ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ +#if _FS_RPATH + if ((di == 1 && lfn[di - 1] == '.') || /* Is this a dot entry? */ + (di == 2 && lfn[di - 1] == '.' && lfn[di - 2] == '.')) { + lfn[di] = 0; + for (i = 0; i < 11; i++) + dj->fn[i] = (i < di) ? '.' : ' '; + dj->fn[i] = cf | NS_DOT; /* This is a dot entry */ + return FR_OK; + } +#endif + while (di) { /* Strip trailing spaces and dots */ + w = lfn[di - 1]; + if (w != ' ' && w != '.') break; + di--; + } + if (!di) return FR_INVALID_NAME; /* Reject nul string */ + + lfn[di] = 0; /* LFN is created */ + + /* Create SFN in directory form */ + mem_set(dj->fn, ' ', 11); + for (si = 0; lfn[si] == ' ' || lfn[si] == '.'; si++) ; /* Strip leading spaces and dots */ + if (si) cf |= NS_LOSS | NS_LFN; + while (di && lfn[di - 1] != '.') di--; /* Find extension (di<=si: no extension) */ + + b = i = 0; ni = 8; + for (;;) { + w = lfn[si++]; /* Get an LFN char */ + if (!w) break; /* Break on end of the LFN */ + if (w == ' ' || (w == '.' && si != di)) { /* Remove spaces and dots */ + cf |= NS_LOSS | NS_LFN; continue; + } + + if (i >= ni || si == di) { /* Extension or end of SFN */ + if (ni == 11) { /* Long extension */ + cf |= NS_LOSS | NS_LFN; break; + } + if (si != di) cf |= NS_LOSS | NS_LFN; /* Out of 8.3 format */ + if (si > di) break; /* No extension */ + si = di; i = 8; ni = 11; /* Enter extension section */ + b <<= 2; continue; + } + + if (w >= 0x80) { /* Non ASCII char */ +#ifdef _EXCVT + w = ff_convert(w, 0); /* Unicode -> OEM code */ + if (w) w = excvt[w - 0x80]; /* Convert extended char to upper (SBCS) */ +#else + w = ff_convert(ff_wtoupper(w), 0); /* Upper converted Unicode -> OEM code */ +#endif + cf |= NS_LFN; /* Force create LFN entry */ + } + + if (_DF1S && w >= 0x100) { /* Double byte char */ + if (i >= ni - 1) { + cf |= NS_LOSS | NS_LFN; i = ni; continue; + } + dj->fn[i++] = (BYTE)(w >> 8); + } else { /* Single byte char */ + if (!w || chk_chr("+,;=[]", w)) { /* Replace illegal chars for SFN */ + w = '_'; cf |= NS_LOSS | NS_LFN; /* Lossy conversion */ + } else { + if (IsUpper(w)) { /* ASCII large capital */ + b |= 2; + } else { + if (IsLower(w)) { /* ASCII small capital */ + b |= 1; w -= 0x20; + } + } + } + } + dj->fn[i++] = (BYTE)w; + } + + if (dj->fn[0] == 0xE5) dj->fn[0] = 0x05; /* If the first char collides with deleted mark, replace it with 0x05 */ + + if (ni == 8) b <<= 2; + if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) /* Create LFN entry when there are composite capitals */ + cf |= NS_LFN; + if (!(cf & NS_LFN)) { /* When LFN is in 8.3 format without extended char, NT flags are created */ + if ((b & 0x03) == 0x01) cf |= NS_EXT; /* NT flag (Extension has only small capital) */ + if ((b & 0x0C) == 0x04) cf |= NS_BODY; /* NT flag (Filename has only small capital) */ + } + + dj->fn[NS] = cf; /* SFN is created */ + + return FR_OK; + + +#else /* Non-LFN configuration */ + BYTE b, c, d, *sfn; + int ni, si, i; + const char *p; + + /* Create file name in directory form */ + sfn = dj->fn; + mem_set(sfn, ' ', 11); + si = i = b = 0; ni = 8; + p = *path; +#if _FS_RPATH + if (p[si] == '.') { /* Is this a dot entry? */ + for (;;) { + c = (BYTE)p[si++]; + if (c != '.' || si >= 3) break; + sfn[i++] = c; + } + if (c != '/' && c != '\\' && c > ' ') return FR_INVALID_NAME; + *path = &p[si]; /* Return pointer to the next segment */ + sfn[NS] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT; /* Set last segment flag if end of path */ + return FR_OK; + } +#endif + for (;;) { + c = (BYTE)p[si++]; + if (c <= ' ' || c == '/' || c == '\\') break; /* Break on end of segment */ + if (c == '.' || i >= ni) { + if (ni != 8 || c != '.') return FR_INVALID_NAME; + i = 8; ni = 11; + b <<= 2; continue; + } + if (c >= 0x80) { /* Extended char */ +#ifdef _EXCVT + c = excvt[c - 0x80]; /* Convert extend char (SBCS) */ +#else + b |= 3; /* Eliminate NT flag if extended char is exist */ +#if !_DF1S /* ASCII only cfg */ + return FR_INVALID_NAME; +#endif +#endif + } + if (IsDBCS1(c)) { /* DBC 1st byte? */ + d = (BYTE)p[si++]; /* Get 2nd byte */ + if (!IsDBCS2(d) || i >= ni - 1) /* Reject invalid DBC */ + return FR_INVALID_NAME; + sfn[i++] = c; + sfn[i++] = d; + } else { /* Single byte code */ + if (chk_chr("\"*+,:<=>\?[]|\x7F", c)) /* Reject illegal chrs for SFN */ + return FR_INVALID_NAME; + if (IsUpper(c)) { /* ASCII large capital? */ + b |= 2; + } else { + if (IsLower(c)) { /* ASCII small capital? */ + b |= 1; c -= 0x20; + } + } + sfn[i++] = c; + } + } + *path = &p[si]; /* Return pointer to the next segment */ + c = (c <= ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ + + if (!i) return FR_INVALID_NAME; /* Reject nul string */ + if (sfn[0] == 0xE5) sfn[0] = 0x05; /* When first char collides with 0xE5, replace it with 0x05 */ + + if (ni == 8) b <<= 2; + if ((b & 0x03) == 0x01) c |= NS_EXT; /* NT flag (Name extension has only small capital) */ + if ((b & 0x0C) == 0x04) c |= NS_BODY; /* NT flag (Name body has only small capital) */ + + sfn[NS] = c; /* Store NT flag, File name is created */ + + return FR_OK; +#endif +} + + + + +/*-----------------------------------------------------------------------*/ +/* Get file information from directory entry */ +/*-----------------------------------------------------------------------*/ +#if _FS_MINIMIZE <= 1 +static +void get_fileinfo ( /* No return code */ + DIR *dj, /* Pointer to the directory object */ + FILINFO *fno /* Pointer to the file information to be filled */ +) +{ + int i; + BYTE nt, *dir; + TCHAR *p, c; + + + p = fno->fname; + if (dj->sect) { + dir = dj->dir; + nt = dir[DIR_NTres]; /* NT flag */ + for (i = 0; i < 8; i++) { /* Copy name body */ + c = dir[i]; + if (c == ' ') break; + if (c == 0x05) c = (TCHAR)0xE5; + if (_USE_LFN && (nt & NS_BODY) && IsUpper(c)) c += 0x20; +#if _LFN_UNICODE + if (IsDBCS1(c) && i < 7 && IsDBCS2(dir[i + 1])) + c = (c << 8) | dir[++i]; + c = ff_convert(c, 1); + if (!c) c = '?'; +#endif + *p++ = c; + } + if (dir[8] != ' ') { /* Copy name extension */ + *p++ = '.'; + for (i = 8; i < 11; i++) { + c = dir[i]; + if (c == ' ') break; + if (_USE_LFN && (nt & NS_EXT) && IsUpper(c)) c += 0x20; +#if _LFN_UNICODE + if (IsDBCS1(c) && i < 10 && IsDBCS2(dir[i + 1])) + c = (c << 8) | dir[++i]; + c = ff_convert(c, 1); + if (!c) c = '?'; +#endif + *p++ = c; + } + } + fno->fattrib = dir[DIR_Attr]; /* Attribute */ + fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */ + fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */ + fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */ + } + *p = 0; + +#if _USE_LFN + if (fno->lfname) { + TCHAR *tp = fno->lfname; + WCHAR w, *lfn; + + i = 0; + if (dj->sect && dj->lfn_idx != 0xFFFF) {/* Get LFN if available */ + lfn = dj->lfn; + while ((w = *lfn++) != 0) { /* Get an LFN char */ +#if !_LFN_UNICODE + w = ff_convert(w, 0); /* Unicode -> OEM conversion */ + if (!w) { i = 0; break; } /* Could not convert, no LFN */ + if (_DF1S && w >= 0x100) /* Put 1st byte if it is a DBC */ + tp[i++] = (TCHAR)(w >> 8); +#endif + if (i >= fno->lfsize - 1) { i = 0; break; } /* Buffer overrun, no LFN */ + tp[i++] = (TCHAR)w; + } + } + tp[i] = 0; /* Terminator */ + } +#endif +} +#endif /* _FS_MINIMIZE <= 1 */ + + + + +/*-----------------------------------------------------------------------*/ +/* Follow a file path */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ + DIR *dj, /* Directory object to return last directory and found object */ + const TCHAR *path /* Full-path string to find a file or directory */ +) +{ + FRESULT res; + BYTE *dir, ns; + + +#if _FS_RPATH + if (*path == '/' || *path == '\\') { /* There is a heading separator */ + path++; dj->sclust = 0; /* Strip it and start from the root dir */ + } else { /* No heading separator */ + dj->sclust = dj->fs->cdir; /* Start from the current dir */ + } +#else + if (*path == '/' || *path == '\\') /* Strip heading separator if exist */ + path++; + dj->sclust = 0; /* Start from the root dir */ +#endif + + if ((UINT)*path < ' ') { /* Nul path means the start directory itself */ + res = dir_sdi(dj, 0); + dj->dir = 0; + + } else { /* Follow path */ + for (;;) { + res = create_name(dj, &path); /* Get a segment */ + if (res != FR_OK) break; + res = dir_find(dj); /* Find it */ + ns = *(dj->fn+NS); + if (res != FR_OK) { /* Failed to find the object */ + if (res != FR_NO_FILE) break; /* Abort if any hard error occured */ + /* Object not found */ + if (_FS_RPATH && (ns & NS_DOT)) { /* If dot entry is not exit */ + dj->sclust = 0; dj->dir = 0; /* It is the root dir */ + res = FR_OK; + if (!(ns & NS_LAST)) continue; + } else { /* Could not find the object */ + if (!(ns & NS_LAST)) res = FR_NO_PATH; + } + break; + } + if (ns & NS_LAST) break; /* Last segment match. Function completed. */ + dir = dj->dir; /* There is next segment. Follow the sub directory */ + if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */ + res = FR_NO_PATH; break; + } + dj->sclust = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + } + } + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Load boot record and check if it is an FAT boot record */ +/*-----------------------------------------------------------------------*/ + +static +BYTE check_fs ( /* 0:The FAT BR, 1:Valid BR but not an FAT, 2:Not a BR, 3:Disk error */ + FATFS *fs, /* File system object */ + DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */ +) +{ + if (disk_read(fs->drv, fs->win, sect, 1) != RES_OK) /* Load boot record */ + return 3; + if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55) /* Check record signature (always placed at offset 510 even if the sector size is >512) */ + return 2; + + if ((LD_DWORD(&fs->win[BS_FilSysType]) & 0xFFFFFF) == 0x544146) /* Check "FAT" string */ + return 0; + if ((LD_DWORD(&fs->win[BS_FilSysType32]) & 0xFFFFFF) == 0x544146) + return 0; + + return 1; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Make sure that the file system is valid */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occurred */ + const TCHAR **path, /* Pointer to pointer to the path name (drive number) */ + FATFS **rfs, /* Pointer to pointer to the found file system object */ + BYTE chk_wp /* !=0: Check media write protection for write access */ +) +{ + BYTE fmt, b, *tbl; + UINT vol; + DSTATUS stat; + DWORD bsect, fasize, tsect, sysect, nclst, szbfat; + WORD nrsv; + const TCHAR *p = *path; + FATFS *fs; + + /* Get logical drive number from the path name */ + vol = p[0] - '0'; /* Is there a drive number? */ + if (vol <= 9 && p[1] == ':') { /* Found a drive number, get and strip it */ + p += 2; *path = p; /* Return pointer to the path name */ + } else { /* No drive number is given */ +#if _FS_RPATH + vol = Drive; /* Use current drive */ +#else + vol = 0; /* Use drive 0 */ +#endif + } + + /* Check if the logical drive is valid or not */ + if (vol >= _DRIVES) /* Is the drive number valid? */ + return FR_INVALID_DRIVE; + *rfs = fs = FatFs[vol]; /* Return pointer to the corresponding file system object */ + if (!fs) return FR_NOT_ENABLED; /* Is the file system object available? */ + + ENTER_FF(fs); /* Lock file system */ + + if (fs->fs_type) { /* If the logical drive has been mounted */ + stat = disk_status(fs->drv); + if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized (has not been changed), */ +#if !_FS_READONLY + if (chk_wp && (stat & STA_PROTECT)) /* Check write protection if needed */ + return FR_WRITE_PROTECTED; +#endif + return FR_OK; /* The file system object is valid */ + } + } + + /* The logical drive must be mounted. Following code attempts to mount the volume (initialize the file system object) */ + + fs->fs_type = 0; /* Clear the file system object */ + fs->drv = (BYTE)LD2PD(vol); /* Bind the logical drive and a physical drive */ + stat = disk_initialize(fs->drv); /* Initialize low level disk I/O layer */ + if (stat & STA_NOINIT) /* Check if the drive is ready */ + return FR_NOT_READY; +#if _MAX_SS != 512 /* Get disk sector size if needed */ + if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS) + return FR_NO_FILESYSTEM; +#endif +#if !_FS_READONLY + if (chk_wp && (stat & STA_PROTECT)) /* Check disk write protection if needed */ + return FR_WRITE_PROTECTED; +#endif + /* Search FAT partition on the drive (Supports only generic partitionings, FDISK and SFD) */ + fmt = check_fs(fs, bsect = 0); /* Check sector 0 if it is a VBR */ + if (fmt == 1) { /* Not an FAT-VBR, the disk may be partitioned */ + /* Check the partition listed in top of the partition table */ + tbl = &fs->win[MBR_Table + LD2PT(vol) * 16]; /* Partition table */ + if (tbl[4]) { /* Is the partition existing? */ + bsect = LD_DWORD(&tbl[8]); /* Partition offset in LBA */ + fmt = check_fs(fs, bsect); /* Check the partition */ + } + } + if (fmt == 3) return FR_DISK_ERR; + if (fmt) return FR_NO_FILESYSTEM; /* No FAT volume is found */ + + /* Following code initializes the file system object */ + + if (LD_WORD(fs->win+BPB_BytsPerSec) != SS(fs)) /* (BPB_BytsPerSec must be equal to the physical sector size) */ + return FR_NO_FILESYSTEM; + + fasize = LD_WORD(fs->win+BPB_FATSz16); /* Number of sectors per FAT */ + if (!fasize) fasize = LD_DWORD(fs->win+BPB_FATSz32); + fs->fsize = fasize; + + fs->n_fats = b = fs->win[BPB_NumFATs]; /* Number of FAT copies */ + if (b != 1 && b != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */ + fasize *= b; /* Number of sectors for FAT area */ + + fs->csize = b = fs->win[BPB_SecPerClus]; /* Number of sectors per cluster */ + if (!b || (b & (b - 1))) return FR_NO_FILESYSTEM; /* (Must be 1,2,4...128) */ + + fs->n_rootdir = LD_WORD(fs->win+BPB_RootEntCnt); /* Number of root directory entries */ + if (fs->n_rootdir % (SS(fs) / 32)) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be sector aligned) */ + + tsect = LD_WORD(fs->win+BPB_TotSec16); /* Number of sectors on the volume */ + if (!tsect) tsect = LD_DWORD(fs->win+BPB_TotSec32); + + nrsv = LD_WORD(fs->win+BPB_RsvdSecCnt); /* Number of reserved sectors */ + if (!nrsv) return FR_NO_FILESYSTEM; /* (BPB_RsvdSecCnt must not be 0) */ + + /* Determine the FAT sub type */ + sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / 32); /* RSV+FAT+DIR */ + if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + nclst = (tsect - sysect) / fs->csize; /* Number of clusters */ + if (!nclst) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + fmt = FS_FAT12; + if (nclst >= MIN_FAT16) fmt = FS_FAT16; + if (nclst >= MIN_FAT32) fmt = FS_FAT32; + + /* Boundaries and Limits */ + fs->n_fatent = nclst + 2; /* Number of FAT entries */ + fs->database = bsect + sysect; /* Data start sector */ + fs->fatbase = bsect + nrsv; /* FAT start sector */ + if (fmt == FS_FAT32) { + if (fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */ + fs->dirbase = LD_DWORD(fs->win+BPB_RootClus); /* Root directory start cluster */ + szbfat = fs->n_fatent * 4; /* (Required FAT size) */ + } else { + if (!fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */ + fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */ + szbfat = (fmt == FS_FAT16) ? /* (Required FAT size) */ + fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1); + } + if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) /* (FAT size must not be less than FAT sectors */ + return FR_NO_FILESYSTEM; + +#if !_FS_READONLY + /* Initialize cluster allocation information */ + fs->free_clust = 0xFFFFFFFF; + fs->last_clust = 0; + + /* Get fsinfo if available */ + if (fmt == FS_FAT32) { + fs->fsi_flag = 0; + fs->fsi_sector = bsect + LD_WORD(fs->win+BPB_FSInfo); + if (disk_read(fs->drv, fs->win, fs->fsi_sector, 1) == RES_OK && + LD_WORD(fs->win+BS_55AA) == 0xAA55 && + LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 && + LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) { + fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free); + fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count); + } + } +#endif + fs->fs_type = fmt; /* FAT sub-type */ + fs->id = ++Fsid; /* File system mount ID */ + fs->winsect = 0; /* Invalidate sector cache */ + fs->wflag = 0; +#if _FS_RPATH + fs->cdir = 0; /* Current directory (root dir) */ +#endif +#if _FS_SHARE /* Clear file lock semaphores */ + for (vol = 0; vol < _FS_SHARE; vol++) + fs->flsem[vol].ctr = 0; +#endif + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Check if the file/dir object is valid or not */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT validate ( /* FR_OK(0): The object is valid, !=0: Invalid */ + FATFS *fs, /* Pointer to the file system object */ + WORD id /* Member id of the target object to be checked */ +) +{ + if (!fs || !fs->fs_type || fs->id != id) + return FR_INVALID_OBJECT; + + ENTER_FF(fs); /* Lock file system */ + + if (disk_status(fs->drv) & STA_NOINIT) + return FR_NOT_READY; + + return FR_OK; +} + + + + +/*-------------------------------------------------------------------------- + + Public Functions + +--------------------------------------------------------------------------*/ + + + +/*-----------------------------------------------------------------------*/ +/* Mount/Unmount a Logical Drive */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mount ( + BYTE vol, /* Logical drive number to be mounted/unmounted */ + FATFS *fs /* Pointer to new file system object (NULL for unmount)*/ +) +{ + FATFS *rfs; + + + if (vol >= _DRIVES) /* Check if the drive number is valid */ + return FR_INVALID_DRIVE; + rfs = FatFs[vol]; /* Get current fs object */ + + if (rfs) { +#if _FS_REENTRANT /* Discard sync object of the current volume */ + if (!ff_del_syncobj(rfs->sobj)) return FR_INT_ERR; +#endif + rfs->fs_type = 0; /* Clear old fs object */ + } + + if (fs) { + fs->fs_type = 0; /* Clear new fs object */ +#if _FS_REENTRANT /* Create sync object for the new volume */ + if (!ff_cre_syncobj(vol, &fs->sobj)) return FR_INT_ERR; +#endif + } + FatFs[vol] = fs; /* Register new fs object */ + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Open or Create a File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_open ( + FIL *fp, /* Pointer to the blank file object */ + const TCHAR *path, /* Pointer to the file name */ + BYTE mode /* Access mode and file open mode flags */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + fp->fs = 0; /* Clear file object */ + +#if !_FS_READONLY + mode &= FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW; + res = chk_mounted(&path, &dj.fs, (BYTE)(mode & ~FA_READ)); +#else + mode &= FA_READ; + res = chk_mounted(&path, &dj.fs, 0); +#endif + INIT_BUF(dj); + if (res == FR_OK) + res = follow_path(&dj, path); /* Follow the file path */ + dir = dj.dir; + +#if !_FS_READONLY /* R/W configuration */ + if (res == FR_OK) { + if (!dir) /* Current dir itself */ + res = FR_INVALID_NAME; +#if _FS_SHARE + else + res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0); +#endif + } + /* Create or Open a file */ + if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) { + DWORD dw, cl; + + if (res != FR_OK) { /* No file, create new */ + if (res == FR_NO_FILE) /* There is no file to open, create a new entry */ +#if _FS_SHARE + res = enq_lock(dj.fs) ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES; +#else + res = dir_register(&dj); +#endif + mode |= FA_CREATE_ALWAYS; + dir = dj.dir; /* New entry */ + } + else { /* Any object is already existing */ + if (mode & FA_CREATE_NEW) { /* Cannot create new */ + res = FR_EXIST; + } else { + if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) /* Cannot overwrite it (R/O or DIR) */ + res = FR_DENIED; + } + } + if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */ + dw = get_fattime(); /* Created time */ + ST_DWORD(dir+DIR_CrtTime, dw); + dir[DIR_Attr] = 0; /* Reset attribute */ + ST_DWORD(dir+DIR_FileSize, 0); /* size = 0 */ + cl = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); /* Get start cluster */ + ST_WORD(dir+DIR_FstClusHI, 0); /* cluster = 0 */ + ST_WORD(dir+DIR_FstClusLO, 0); + dj.fs->wflag = 1; + if (cl) { /* Remove the cluster chain if exist */ + dw = dj.fs->winsect; + res = remove_chain(dj.fs, cl); + if (res == FR_OK) { + dj.fs->last_clust = cl - 1; /* Reuse the cluster hole */ + res = move_window(dj.fs, dw); + } + } + } + } + else { /* Open an existing file */ + if (res == FR_OK) { /* Follow succeeded */ + if (dir[DIR_Attr] & AM_DIR) { /* It is a directory */ + res = FR_NO_FILE; + } else { + if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */ + res = FR_DENIED; + } + } + } + if (res == FR_OK) { + if (mode & (FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) + mode |= FA__WRITTEN; /* Set file changed flag */ + fp->dir_sect = dj.fs->winsect; /* Pointer to the directory entry */ + fp->dir_ptr = dir; +#if _FS_SHARE + fp->lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0); + if (!fp->lockid) res = FR_INT_ERR; +#endif + } + +#else /* R/O configuration */ + if (res == FR_OK) { /* Follow succeeded */ + if (!dir) { /* Current dir itself */ + res = FR_INVALID_NAME; + } else { + if (dir[DIR_Attr] & AM_DIR) /* It is a directory */ + res = FR_NO_FILE; + } + } +#endif + FREE_BUF(); + + if (res == FR_OK) { + fp->flag = mode; /* File access mode */ + fp->org_clust = /* File start cluster */ + ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + fp->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */ + fp->fptr = 0; /* File pointer */ + fp->dsect = 0; +#if _USE_FASTSEEK + fp->cltbl = 0; /* No cluster link map table */ +#endif + fp->fs = dj.fs; fp->id = dj.fs->id; /* Validate file object */ + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_read ( + FIL *fp, /* Pointer to the file object */ + void *buff, /* Pointer to data buffer */ + UINT btr, /* Number of bytes to read */ + UINT *br /* Pointer to number of bytes read */ +) +{ + FRESULT res; + DWORD clst, sect, remain; + UINT rcnt, cc; + BYTE csect, *rbuff = buff; + + + *br = 0; /* Initialize byte counter */ + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_READ)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + remain = fp->fsize - fp->fptr; + if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ + + for ( ; btr; /* Repeat until all data transferred */ + rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if (!csect) { /* On the cluster boundary? */ + clst = (fp->fptr == 0) ? /* On the top of the file? */ + fp->org_clust : get_fat(fp->fs, fp->curr_clust); + if (clst <= 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->curr_clust = clst; /* Update current cluster */ + } + sect = clust2sect(fp->fs, fp->curr_clust); /* Get current sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + cc = btr / SS(fp->fs); /* When remaining bytes >= sector size, */ + if (cc) { /* Read maximum contiguous sectors directly */ + if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */ + cc = fp->fs->csize - csect; + if (disk_read(fp->fs->drv, rbuff, sect, (BYTE)cc) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#if !_FS_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */ +#if _FS_TINY + if (fp->fs->wflag && fp->fs->winsect - sect < cc) + mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs)); +#else + if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc) + mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs)); +#endif +#endif + rcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ + continue; + } +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Write sector I/O buffer if needed */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (fp->dsect != sect) { /* Fill sector buffer with file data */ + if (disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + } +#endif + fp->dsect = sect; + } + rcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs)); /* Get partial sector data from sector buffer */ + if (rcnt > btr) rcnt = btr; +#if _FS_TINY + if (move_window(fp->fs, fp->dsect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ +#else + mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ +#endif + } + + LEAVE_FF(fp->fs, FR_OK); +} + + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Write File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_write ( + FIL *fp, /* Pointer to the file object */ + const void *buff, /* Pointer to the data to be written */ + UINT btw, /* Number of bytes to write */ + UINT *bw /* Pointer to number of bytes written */ +) +{ + FRESULT res; + DWORD clst, sect; + UINT wcnt, cc; + const BYTE *wbuff = buff; + BYTE csect; + + + *bw = 0; /* Initialize byte counter */ + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_WRITE)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + if (fp->fsize + btw < fp->fsize) btw = 0; /* File size cannot reach 4GB */ + + for ( ; btw; /* Repeat until all data transferred */ + wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if (!csect) { /* On the cluster boundary? */ + if (fp->fptr == 0) { /* On the top of the file? */ + clst = fp->org_clust; /* Follow from the origin */ + if (clst == 0) /* When there is no cluster chain, */ + fp->org_clust = clst = create_chain(fp->fs, 0); /* Create a new cluster chain */ + } else { /* Middle or end of the file */ + clst = create_chain(fp->fs, fp->curr_clust); /* Follow or stretch cluster chain */ + } + if (clst == 0) break; /* Could not allocate a new cluster (disk full) */ + if (clst == 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->curr_clust = clst; /* Update current cluster */ + } +#if _FS_TINY + if (fp->fs->winsect == fp->dsect && move_window(fp->fs, 0)) /* Write back data buffer prior to following direct transfer */ + ABORT(fp->fs, FR_DISK_ERR); +#else + if (fp->flag & FA__DIRTY) { /* Write back data buffer prior to following direct transfer */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + sect = clust2sect(fp->fs, fp->curr_clust); /* Get current sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + cc = btw / SS(fp->fs); /* When remaining bytes >= sector size, */ + if (cc) { /* Write maximum contiguous sectors directly */ + if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */ + cc = fp->fs->csize - csect; + if (disk_write(fp->fs->drv, wbuff, sect, (BYTE)cc) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#if _FS_TINY + if (fp->fs->winsect - sect < cc) { /* Refill sector cache if it gets dirty by the direct write */ + mem_cpy(fp->fs->win, wbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), SS(fp->fs)); + fp->fs->wflag = 0; + } +#else + if (fp->dsect - sect < cc) { /* Refill sector cache if it gets dirty by the direct write */ + mem_cpy(fp->buf, wbuff + ((fp->dsect - sect) * SS(fp->fs)), SS(fp->fs)); + fp->flag &= ~FA__DIRTY; + } +#endif + wcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ + continue; + } +#if _FS_TINY + if (fp->fptr >= fp->fsize) { /* Avoid silly buffer filling at growing edge */ + if (move_window(fp->fs, 0)) ABORT(fp->fs, FR_DISK_ERR); + fp->fs->winsect = sect; + } +#else + if (fp->dsect != sect) { /* Fill sector buffer with file data */ + if (fp->fptr < fp->fsize && + disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + } +#endif + fp->dsect = sect; + } + wcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs)); /* Put partial sector into file I/O buffer */ + if (wcnt > btw) wcnt = btw; +#if _FS_TINY + if (move_window(fp->fs, fp->dsect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + mem_cpy(&fp->fs->win[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */ + fp->fs->wflag = 1; +#else + mem_cpy(&fp->buf[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */ + fp->flag |= FA__DIRTY; +#endif + } + + if (fp->fptr > fp->fsize) fp->fsize = fp->fptr; /* Update file size if needed */ + fp->flag |= FA__WRITTEN; /* Set file changed flag */ + + LEAVE_FF(fp->fs, FR_OK); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Synchronize the File Object */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_sync ( + FIL *fp /* Pointer to the file object */ +) +{ + FRESULT res; + DWORD tim; + BYTE *dir; + + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res == FR_OK) { + if (fp->flag & FA__WRITTEN) { /* Has the file been written? */ +#if !_FS_TINY /* Write-back dirty buffer */ + if (fp->flag & FA__DIRTY) { + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + LEAVE_FF(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + /* Update the directory entry */ + res = move_window(fp->fs, fp->dir_sect); + if (res == FR_OK) { + dir = fp->dir_ptr; + dir[DIR_Attr] |= AM_ARC; /* Set archive bit */ + ST_DWORD(dir+DIR_FileSize, fp->fsize); /* Update file size */ + ST_WORD(dir+DIR_FstClusLO, fp->org_clust); /* Update start cluster */ + ST_WORD(dir+DIR_FstClusHI, fp->org_clust >> 16); + tim = get_fattime(); /* Update updated time */ + ST_DWORD(dir+DIR_WrtTime, tim); + fp->flag &= ~FA__WRITTEN; + fp->fs->wflag = 1; + res = sync(fp->fs); + } + } + } + + LEAVE_FF(fp->fs, res); +} + +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Close File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_close ( + FIL *fp /* Pointer to the file object to be closed */ +) +{ + FRESULT res; + +#if _FS_READONLY + FATFS *fs = fp->fs; + res = validate(fs, fp->id); + if (res == FR_OK) fp->fs = 0; /* Discard file object */ + LEAVE_FF(fs, res); + +#else + res = f_sync(fp); /* Flush cached data */ +#if _FS_SHARE + if (res == FR_OK) { /* Decrement open counter */ +#if _FS_REENTRANT + res = validate(fp->fs, fp->id); + if (res == FR_OK) { + res = dec_lock(fp->fs, fp->lockid); + unlock_fs(fp->fs, FR_OK); + } +#else + res = dec_lock(fp->fs, fp->lockid); +#endif + } +#endif + if (res == FR_OK) fp->fs = 0; /* Discard file object */ + return res; +#endif +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Current Drive/Directory */ +/*-----------------------------------------------------------------------*/ + +#if _FS_RPATH + +FRESULT f_chdrive ( + BYTE drv /* Drive number */ +) +{ + if (drv >= _DRIVES) return FR_INVALID_DRIVE; + + Drive = drv; + + return FR_OK; +} + + + + +FRESULT f_chdir ( + const TCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 0); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the path */ + FREE_BUF(); + if (res == FR_OK) { /* Follow completed */ + dir = dj.dir; /* Pointer to the entry */ + if (!dir) { + dj.fs->cdir = dj.sclust; /* Start directory itself */ + } else { + if (dir[DIR_Attr] & AM_DIR) /* Reached to the directory */ + dj.fs->cdir = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + else + res = FR_NO_PATH; /* Reached but a file */ + } + } + if (res == FR_NO_FILE) res = FR_NO_PATH; + } + + LEAVE_FF(dj.fs, res); +} + +#endif + + + +#if _FS_MINIMIZE <= 2 +/*-----------------------------------------------------------------------*/ +/* Seek File R/W Pointer */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_lseek ( + FIL *fp, /* Pointer to the file object */ + DWORD ofs /* File pointer from top of file */ +) +{ + FRESULT res; + + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + +#if _USE_FASTSEEK + if (fp->cltbl) { /* Fast seek */ + DWORD cl, pcl, ncl, tcl, dsc, tlen, *tbl = fp->cltbl; + BYTE csc; + + tlen = *tbl++; + if (ofs == CREATE_LINKMAP) { /* Create link map table */ + cl = fp->org_clust; + if (cl) { + do { + if (tlen < 4) { /* Not enough table items */ + res = FR_NOT_ENOUGH_CORE; break; + } + tcl = cl; ncl = 0; + do { /* Get a fragment and store the top and length */ + pcl = cl; ncl++; + cl = get_fat(fp->fs, cl); + if (cl <= 1) ABORT(fp->fs, FR_INT_ERR); + if (cl == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + } while (cl == pcl + 1); + *tbl++ = ncl; *tbl++ = tcl; + tlen -= 2; + } while (cl < fp->fs->n_fatent); + } + *tbl = 0; /* Terminate table */ + + } else { /* Fast seek */ + if (ofs > fp->fsize) /* Clip offset at the file size */ + ofs = fp->fsize; + fp->fptr = ofs; /* Set file pointer */ + if (ofs) { + dsc = (ofs - 1) / SS(fp->fs); + cl = dsc / fp->fs->csize; + for (;;) { + ncl = *tbl++; + if (!ncl) ABORT(fp->fs, FR_INT_ERR); + if (cl < ncl) break; + cl -= ncl; tbl++; + } + fp->curr_clust = cl + *tbl; + csc = (BYTE)(dsc & (fp->fs->csize - 1)); + dsc = clust2sect(fp->fs, fp->curr_clust); + if (!dsc) ABORT(fp->fs, FR_INT_ERR); + dsc += csc; + if (fp->fptr % SS(fp->fs) && dsc != fp->dsect) { +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Flush dirty buffer if needed */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (disk_read(fp->fs->drv, fp->buf, dsc, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#endif + fp->dsect = dsc; + } + } + } + } else +#endif + + /* Normal Seek */ + { + DWORD clst, bcs, nsect, ifptr; + + if (ofs > fp->fsize /* In read-only mode, clip offset with the file size */ +#if !_FS_READONLY + && !(fp->flag & FA_WRITE) +#endif + ) ofs = fp->fsize; + + ifptr = fp->fptr; + fp->fptr = nsect = 0; + if (ofs) { + bcs = (DWORD)fp->fs->csize * SS(fp->fs); /* Cluster size (byte) */ + if (ifptr > 0 && + (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */ + fp->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */ + ofs -= fp->fptr; + clst = fp->curr_clust; + } else { /* When seek to back cluster, */ + clst = fp->org_clust; /* start from the first cluster */ +#if !_FS_READONLY + if (clst == 0) { /* If no cluster chain, create a new chain */ + clst = create_chain(fp->fs, 0); + if (clst == 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->org_clust = clst; + } +#endif + fp->curr_clust = clst; + } + if (clst != 0) { + while (ofs > bcs) { /* Cluster following loop */ +#if !_FS_READONLY + if (fp->flag & FA_WRITE) { /* Check if in write mode or not */ + clst = create_chain(fp->fs, clst); /* Force stretch if in write mode */ + if (clst == 0) { /* When disk gets full, clip file size */ + ofs = bcs; break; + } + } else +#endif + clst = get_fat(fp->fs, clst); /* Follow cluster chain if not in write mode */ + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + if (clst <= 1 || clst >= fp->fs->n_fatent) ABORT(fp->fs, FR_INT_ERR); + fp->curr_clust = clst; + fp->fptr += bcs; + ofs -= bcs; + } + fp->fptr += ofs; + if (ofs % SS(fp->fs)) { + nsect = clust2sect(fp->fs, clst); /* Current sector */ + if (!nsect) ABORT(fp->fs, FR_INT_ERR); + nsect += ofs / SS(fp->fs); + } + } + } + if (fp->fptr % SS(fp->fs) && nsect != fp->dsect) { +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Flush dirty buffer if needed */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (disk_read(fp->fs->drv, fp->buf, nsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#endif + fp->dsect = nsect; + } +#if !_FS_READONLY + if (fp->fptr > fp->fsize) { /* Set changed flag if the file size is extended */ + fp->fsize = fp->fptr; + fp->flag |= FA__WRITTEN; + } +#endif + } + + LEAVE_FF(fp->fs, res); +} + + + +#if _FS_MINIMIZE <= 1 +/*-----------------------------------------------------------------------*/ +/* Create a Directroy Object */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_opendir ( + DIR *dj, /* Pointer to directory object to create */ + const TCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + BYTE *dir; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj->fs, 0); + if (res == FR_OK) { + INIT_BUF(*dj); + res = follow_path(dj, path); /* Follow the path to the directory */ + FREE_BUF(); + if (res == FR_OK) { /* Follow completed */ + dir = dj->dir; + if (dir) { /* It is not the current dir */ + if (dir[DIR_Attr] & AM_DIR) { /* The object is a directory */ + dj->sclust = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + } else { /* The object is not a directory */ + res = FR_NO_PATH; + } + } + if (res == FR_OK) { + dj->id = dj->fs->id; + res = dir_sdi(dj, 0); /* Rewind dir */ + } + } + if (res == FR_NO_FILE) res = FR_NO_PATH; + } + + LEAVE_FF(dj->fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read Directory Entry in Sequense */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_readdir ( + DIR *dj, /* Pointer to the open directory object */ + FILINFO *fno /* Pointer to file information to return */ +) +{ + FRESULT res; + DEF_NAMEBUF; + + + res = validate(dj->fs, dj->id); /* Check validity of the object */ + if (res == FR_OK) { + if (!fno) { + res = dir_sdi(dj, 0); + } else { + INIT_BUF(*dj); + res = dir_read(dj); + if (res == FR_NO_FILE) { + dj->sect = 0; + res = FR_OK; + } + if (res == FR_OK) { /* A valid entry is found */ + get_fileinfo(dj, fno); /* Get the object information */ + res = dir_next(dj, 0); /* Increment index for next */ + if (res == FR_NO_FILE) { + dj->sect = 0; + res = FR_OK; + } + } + FREE_BUF(); + } + } + + LEAVE_FF(dj->fs, res); +} + + + +#if _FS_MINIMIZE == 0 +/*-----------------------------------------------------------------------*/ +/* Get File Status */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_stat ( + const TCHAR *path, /* Pointer to the file path */ + FILINFO *fno /* Pointer to file information to return */ +) +{ + FRESULT res; + DIR dj; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 0); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) { /* Follow completed */ + if (dj.dir) /* Found an object */ + get_fileinfo(&dj, fno); + else /* It is root dir */ + res = FR_INVALID_NAME; + } + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Get Number of Free Clusters */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_getfree ( + const TCHAR *path, /* Pointer to the logical drive number (root dir) */ + DWORD *nclst, /* Pointer to the variable to return number of free clusters */ + FATFS **fatfs /* Pointer to pointer to corresponding file system object to return */ +) +{ + FRESULT res; + DWORD n, clst, sect, stat; + UINT i; + BYTE fat, *p; + + + /* Get drive number */ + res = chk_mounted(&path, fatfs, 0); + if (res == FR_OK) { + /* If free_clust is valid, return it without full cluster scan */ + if ((*fatfs)->free_clust <= (*fatfs)->n_fatent - 2) { + *nclst = (*fatfs)->free_clust; + } else { + /* Get number of free clusters */ + fat = (*fatfs)->fs_type; + n = 0; + if (fat == FS_FAT12) { + clst = 2; + do { + stat = get_fat(*fatfs, clst); + if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } + if (stat == 1) { res = FR_INT_ERR; break; } + if (stat == 0) n++; + } while (++clst < (*fatfs)->n_fatent); + } else { + clst = (*fatfs)->n_fatent; + sect = (*fatfs)->fatbase; + i = 0; p = 0; + do { + if (!i) { + res = move_window(*fatfs, sect++); + if (res != FR_OK) break; + p = (*fatfs)->win; + i = SS(*fatfs); + } + if (fat == FS_FAT16) { + if (LD_WORD(p) == 0) n++; + p += 2; i -= 2; + } else { + if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) n++; + p += 4; i -= 4; + } + } while (--clst); + } + (*fatfs)->free_clust = n; + if (fat == FS_FAT32) (*fatfs)->fsi_flag = 1; + *nclst = n; + } + } + LEAVE_FF(*fatfs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Truncate File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_truncate ( + FIL *fp /* Pointer to the file object */ +) +{ + FRESULT res; + DWORD ncl; + + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res == FR_OK) { + if (fp->flag & FA__ERROR) { /* Check abort flag */ + res = FR_INT_ERR; + } else { + if (!(fp->flag & FA_WRITE)) /* Check access mode */ + res = FR_DENIED; + } + } + if (res == FR_OK) { + if (fp->fsize > fp->fptr) { + fp->fsize = fp->fptr; /* Set file size to current R/W point */ + fp->flag |= FA__WRITTEN; + if (fp->fptr == 0) { /* When set file size to zero, remove entire cluster chain */ + res = remove_chain(fp->fs, fp->org_clust); + fp->org_clust = 0; + } else { /* When truncate a part of the file, remove remaining clusters */ + ncl = get_fat(fp->fs, fp->curr_clust); + res = FR_OK; + if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR; + if (ncl == 1) res = FR_INT_ERR; + if (res == FR_OK && ncl < fp->fs->n_fatent) { + res = put_fat(fp->fs, fp->curr_clust, 0x0FFFFFFF); + if (res == FR_OK) res = remove_chain(fp->fs, ncl); + } + } + } + if (res != FR_OK) fp->flag |= FA__ERROR; + } + + LEAVE_FF(fp->fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Delete a File or Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_unlink ( + const TCHAR *path /* Pointer to the file or directory path */ +) +{ + FRESULT res; + DIR dj, sdj; + BYTE *dir; + DWORD dclst; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; /* Cannot remove dot entry */ +#if _FS_SHARE + if (res == FR_OK) res = chk_lock(&dj, 2); /* Cannot remove open file */ +#endif + if (res == FR_OK) { /* The object is accessible */ + dir = dj.dir; + if (!dir) { + res = FR_INVALID_NAME; /* Cannot remove the start directory */ + } else { + if (dir[DIR_Attr] & AM_RDO) + res = FR_DENIED; /* Cannot remove R/O object */ + } + dclst = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + if (res == FR_OK && (dir[DIR_Attr] & AM_DIR)) { /* Is it a sub-dir? */ + if (dclst < 2) { + res = FR_INT_ERR; + } else { + mem_cpy(&sdj, &dj, sizeof(DIR)); /* Check if the sub-dir is empty or not */ + sdj.sclust = dclst; + res = dir_sdi(&sdj, 2); /* Exclude dot entries */ + if (res == FR_OK) { + res = dir_read(&sdj); + if (res == FR_OK /* Not empty dir */ +#if _FS_RPATH + || dclst == sdj.fs->cdir /* Current dir */ +#endif + ) res = FR_DENIED; + if (res == FR_NO_FILE) res = FR_OK; /* Empty */ + } + } + } + if (res == FR_OK) { + res = dir_remove(&dj); /* Remove the directory entry */ + if (res == FR_OK) { + if (dclst) /* Remove the cluster chain if exist */ + res = remove_chain(dj.fs, dclst); + if (res == FR_OK) res = sync(dj.fs); + } + } + } + FREE_BUF(); + } + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Create a Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mkdir ( + const TCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir, n; + DWORD dsc, dcl, pcl, tim = get_fattime(); + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) res = FR_EXIST; /* Any object with same name is already existing */ + if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_NO_FILE) { /* Can create a new directory */ + dcl = create_chain(dj.fs, 0); /* Allocate a cluster for the new directory table */ + res = FR_OK; + if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster */ + if (dcl == 1) res = FR_INT_ERR; + if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR; + if (res == FR_OK) /* Flush FAT */ + res = move_window(dj.fs, 0); + if (res == FR_OK) { /* Initialize the new directory table */ + dsc = clust2sect(dj.fs, dcl); + dir = dj.fs->win; + mem_set(dir, 0, SS(dj.fs)); + mem_set(dir+DIR_Name, ' ', 8+3); /* Create "." entry */ + dir[DIR_Name] = '.'; + dir[DIR_Attr] = AM_DIR; + ST_DWORD(dir+DIR_WrtTime, tim); + ST_WORD(dir+DIR_FstClusLO, dcl); + ST_WORD(dir+DIR_FstClusHI, dcl >> 16); + mem_cpy(dir+32, dir, 32); /* Create ".." entry */ + dir[33] = '.'; pcl = dj.sclust; + if (dj.fs->fs_type == FS_FAT32 && pcl == dj.fs->dirbase) + pcl = 0; + ST_WORD(dir+32+DIR_FstClusLO, pcl); + ST_WORD(dir+32+DIR_FstClusHI, pcl >> 16); + for (n = dj.fs->csize; n; n--) { /* Write dot entries and clear following sectors */ + dj.fs->winsect = dsc++; + dj.fs->wflag = 1; + res = move_window(dj.fs, 0); + if (res != FR_OK) break; + mem_set(dir, 0, SS(dj.fs)); + } + } + if (res == FR_OK) res = dir_register(&dj); /* Register the object to the directoy */ + if (res != FR_OK) { + remove_chain(dj.fs, dcl); /* Could not register, remove cluster chain */ + } else { + dir = dj.dir; + dir[DIR_Attr] = AM_DIR; /* Attribute */ + ST_DWORD(dir+DIR_WrtTime, tim); /* Created time */ + ST_WORD(dir+DIR_FstClusLO, dcl); /* Table start cluster */ + ST_WORD(dir+DIR_FstClusHI, dcl >> 16); + dj.fs->wflag = 1; + res = sync(dj.fs); + } + } + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Attribute */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_chmod ( + const TCHAR *path, /* Pointer to the file path */ + BYTE value, /* Attribute bits */ + BYTE mask /* Attribute mask to change */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + FREE_BUF(); + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_OK) { + dir = dj.dir; + if (!dir) { /* Is it a root directory? */ + res = FR_INVALID_NAME; + } else { /* File or sub directory */ + mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */ + dir[DIR_Attr] = (value & mask) | (dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */ + dj.fs->wflag = 1; + res = sync(dj.fs); + } + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Timestamp */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_utime ( + const TCHAR *path, /* Pointer to the file/directory name */ + const FILINFO *fno /* Pointer to the time stamp to be set */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + FREE_BUF(); + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_OK) { + dir = dj.dir; + if (!dir) { /* Root directory */ + res = FR_INVALID_NAME; + } else { /* File or sub-directory */ + ST_WORD(dir+DIR_WrtTime, fno->ftime); + ST_WORD(dir+DIR_WrtDate, fno->fdate); + dj.fs->wflag = 1; + res = sync(dj.fs); + } + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Rename File/Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_rename ( + const TCHAR *path_old, /* Pointer to the old name */ + const TCHAR *path_new /* Pointer to the new name */ +) +{ + FRESULT res; + DIR djo, djn; + BYTE buf[21], *dir; + DWORD dw; + DEF_NAMEBUF; + + + res = chk_mounted(&path_old, &djo.fs, 1); + if (res == FR_OK) { + djn.fs = djo.fs; + INIT_BUF(djo); + res = follow_path(&djo, path_old); /* Check old object */ + if (_FS_RPATH && res == FR_OK && (djo.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; +#if _FS_SHARE + if (res == FR_OK) res = chk_lock(&djo, 2); +#endif + if (res == FR_OK) { /* Old object is found */ + if (!djo.dir) { /* Is root dir? */ + res = FR_NO_FILE; + } else { + mem_cpy(buf, djo.dir+DIR_Attr, 21); /* Save the object information except for name */ + mem_cpy(&djn, &djo, sizeof(DIR)); /* Check new object */ + res = follow_path(&djn, path_new); + if (res == FR_OK) res = FR_EXIST; /* The new object name is already existing */ + if (res == FR_NO_FILE) { /* Is it a valid path and no name collision? */ +/* Start critical section that any interruption or error can cause cross-link */ + res = dir_register(&djn); /* Register the new entry */ + if (res == FR_OK) { + dir = djn.dir; /* Copy object information except for name */ + mem_cpy(dir+13, buf+2, 19); + dir[DIR_Attr] = buf[0] | AM_ARC; + djo.fs->wflag = 1; + if (djo.sclust != djn.sclust && (dir[DIR_Attr] & AM_DIR)) { /* Update .. entry in the directory if needed */ + dw = clust2sect(djn.fs, (DWORD)LD_WORD(dir+DIR_FstClusHI) | LD_WORD(dir+DIR_FstClusLO)); + if (!dw) { + res = FR_INT_ERR; + } else { + res = move_window(djn.fs, dw); + dir = djn.fs->win+32; /* .. entry */ + if (res == FR_OK && dir[1] == '.') { + dw = (djn.fs->fs_type == FS_FAT32 && djn.sclust == djn.fs->dirbase) ? 0 : djn.sclust; + ST_WORD(dir+DIR_FstClusLO, dw); + ST_WORD(dir+DIR_FstClusHI, dw >> 16); + djn.fs->wflag = 1; + } + } + } + if (res == FR_OK) { + res = dir_remove(&djo); /* Remove old entry */ + if (res == FR_OK) + res = sync(djo.fs); + } + } +/* End critical section */ + } + } + } + FREE_BUF(); + } + LEAVE_FF(djo.fs, res); +} + +#endif /* !_FS_READONLY */ +#endif /* _FS_MINIMIZE == 0 */ +#endif /* _FS_MINIMIZE <= 1 */ +#endif /* _FS_MINIMIZE <= 2 */ + + + +/*-----------------------------------------------------------------------*/ +/* Forward data to the stream directly (available on only tiny cfg) */ +/*-----------------------------------------------------------------------*/ +#if _USE_FORWARD && _FS_TINY + +FRESULT f_forward ( + FIL *fp, /* Pointer to the file object */ + UINT (*func)(const BYTE*,UINT), /* Pointer to the streaming function */ + UINT btr, /* Number of bytes to forward */ + UINT *bf /* Pointer to number of bytes forwarded */ +) +{ + FRESULT res; + DWORD remain, clst, sect; + UINT rcnt; + BYTE csect; + + + *bf = 0; /* Initialize byte counter */ + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check error flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_READ)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + + remain = fp->fsize - fp->fptr; + if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ + + for ( ; btr && (*func)(0, 0); /* Repeat until all data transferred or stream becomes busy */ + fp->fptr += rcnt, *bf += rcnt, btr -= rcnt) { + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + if (!csect) { /* On the cluster boundary? */ + clst = (fp->fptr == 0) ? /* On the top of the file? */ + fp->org_clust : get_fat(fp->fs, fp->curr_clust); + if (clst <= 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->curr_clust = clst; /* Update current cluster */ + } + } + sect = clust2sect(fp->fs, fp->curr_clust); /* Get current data sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + if (move_window(fp->fs, sect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + fp->dsect = sect; + rcnt = SS(fp->fs) - (WORD)(fp->fptr % SS(fp->fs)); /* Forward data from sector window */ + if (rcnt > btr) rcnt = btr; + rcnt = (*func)(&fp->fs->win[(WORD)fp->fptr % SS(fp->fs)], rcnt); + if (!rcnt) ABORT(fp->fs, FR_INT_ERR); + } + + LEAVE_FF(fp->fs, FR_OK); +} +#endif /* _USE_FORWARD */ + + + +#if _USE_MKFS && !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Create File System on the Drive */ +/*-----------------------------------------------------------------------*/ +#define N_ROOTDIR 512 /* Multiple of 32 */ +#define N_FATS 1 /* 1 or 2 */ + + +FRESULT f_mkfs ( + BYTE drv, /* Logical drive number */ + BYTE sfd, /* Partitioning rule 0:FDISK, 1:SFD */ + UINT au /* Allocation unit size [bytes] */ +) +{ + static const WORD vst[] = { 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 0}; + static const WORD cst[] = {32768, 16384, 8192, 4096, 2048, 16384, 8192, 4096, 2048, 1024, 512}; + BYTE fmt, md, *tbl; + DWORD n_clst, vs, n; + UINT as, i; + DWORD b_vol, b_fat, b_dir, b_data; /* Area offset (LBA) */ + DWORD n_vol, n_rsv, n_fat, n_dir; /* Area size */ + FATFS *fs; + DSTATUS stat; + + + /* Check mounted drive and clear work area */ + if (drv >= _DRIVES) return FR_INVALID_DRIVE; + fs = FatFs[drv]; + if (!fs) return FR_NOT_ENABLED; + fs->fs_type = 0; + drv = LD2PD(drv); + + /* Get disk statics */ + stat = disk_initialize(drv); + if (stat & STA_NOINIT) return FR_NOT_READY; + if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; +#if _MAX_SS != 512 /* Get disk sector size */ + if (disk_ioctl(drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS) + return FR_DISK_ERR; +#endif + if (disk_ioctl(drv, GET_SECTOR_COUNT, &n_vol) != RES_OK || n_vol < 128) + return FR_DISK_ERR; + b_vol = (sfd == 1) ? 0 : 63; /* Volume start sector */ + n_vol -= b_vol; + if (au & (au - 1)) au = 0; /* Check validity of the allocation unit size */ + if (!au) { /* AU auto selection */ + vs = n_vol / (2000 / (SS(fs) / 512)); + for (i = 0; vs < vst[i]; i++) ; + au = cst[i]; + } + if (_MAX_SS != 512 && au < SS(fs)) au = SS(fs); + au /= SS(fs); /* Number of sectors per cluster */ + if (au == 0) au = 1; + if (au > 128) au = 128; + + /* Pre-compute number of clusters and FAT syb-type */ + n_clst = n_vol / au; + fmt = FS_FAT12; + if (n_clst >= MIN_FAT16) fmt = FS_FAT16; + if (n_clst >= MIN_FAT32) fmt = FS_FAT32; + + /* Determine offset and size of FAT structure */ + if (fmt == FS_FAT32) { + n_fat = ((n_clst * 4) + 8 + SS(fs) - 1) / SS(fs); + n_rsv = 32; + n_dir = 0; + } else { + n_fat = (fmt == FS_FAT12) ? (n_clst * 3 + 1) / 2 + 3 : (n_clst * 2) + 4; + n_fat = (n_fat + SS(fs) - 1) / SS(fs); + n_rsv = 1; + n_dir = N_ROOTDIR * 32UL / SS(fs); + } + b_fat = b_vol + n_rsv; /* FAT area start sector */ + b_dir = b_fat + n_fat * N_FATS; /* Directory area start sector */ + b_data = b_dir + n_dir; /* Data area start sector */ + if (n_vol < b_data + au) return FR_MKFS_ABORTED; /* Too small volume */ + + /* Align data start sector to erase block boundary (for flash memory media) */ + if (disk_ioctl(drv, GET_BLOCK_SIZE, &n) != RES_OK) return FR_DISK_ERR; + if (!n || n > 32768) return FR_MKFS_ABORTED; + n = (b_data + n - 1) & ~(n - 1); /* Next nearest boundary from current data start */ + n = (n - b_data) / N_FATS; + if (fmt == FS_FAT32) { /* FAT32: Move FAT start */ + n_rsv += n; + b_fat += n; + } else { /* FAT12/16: Expand FAT size */ + n_fat += n; + } + /* b_dir and b_data are no longer used below */ + + /* Determine number of cluster and final check of validity of the FAT sub-type */ + n_clst = (n_vol - n_rsv - n_fat * N_FATS - n_dir) / au; + if ( (fmt == FS_FAT16 && n_clst < MIN_FAT16) + || (fmt == FS_FAT32 && n_clst < MIN_FAT32)) + return FR_MKFS_ABORTED; + + /* Create partition table if required */ + if (sfd == 1) { + md = 0xF0; + } else { + DWORD n_disk = b_vol + n_vol; + + mem_set(fs->win, 0, SS(fs)); + tbl = fs->win+MBR_Table; + ST_DWORD(tbl, 0x00010180); /* Partition start in CHS */ + if (n_disk < 63UL * 255 * 1024) { /* Partition end in CHS */ + n_disk = n_disk / 63 / 255; + tbl[7] = (BYTE)n_disk; + tbl[6] = (BYTE)((n_disk >> 2) | 63); + } else { + ST_WORD(&tbl[6], 0xFFFF); + } + tbl[5] = 254; + if (fmt != FS_FAT32) /* System ID */ + tbl[4] = (n_vol < 0x10000) ? 0x04 : 0x06; + else + tbl[4] = 0x0c; + ST_DWORD(tbl+8, 63); /* Partition start in LBA */ + ST_DWORD(tbl+12, n_vol); /* Partition size in LBA */ + ST_WORD(tbl+64, 0xAA55); /* Signature */ + if (disk_write(drv, fs->win, 0, 1) != RES_OK) + return FR_DISK_ERR; + md = 0xF8; + } + + /* Create VBR */ + tbl = fs->win; /* Clear buffer */ + mem_set(tbl, 0, SS(fs)); + ST_DWORD(tbl+BS_jmpBoot, 0x90FEEB); /* Boot code (jmp $, nop) */ + as = SS(fs); /* Sector size */ + ST_WORD(tbl+BPB_BytsPerSec, as); + tbl[BPB_SecPerClus] = (BYTE)au; /* Sectors per cluster */ + ST_WORD(tbl+BPB_RsvdSecCnt, n_rsv); /* Reserved sectors */ + tbl[BPB_NumFATs] = N_FATS; /* Number of FATs */ + as = (fmt == FS_FAT32) ? 0 : N_ROOTDIR; /* Number of rootdir entries */ + ST_WORD(tbl+BPB_RootEntCnt, as); + if (n_vol < 0x10000) { /* Number of total sectors */ + ST_WORD(tbl+BPB_TotSec16, n_vol); + } else { + ST_DWORD(tbl+BPB_TotSec32, n_vol); + } + tbl[BPB_Media] = md; /* Media descriptor */ + ST_WORD(tbl+BPB_SecPerTrk, 63); /* Number of sectors per track */ + ST_WORD(tbl+BPB_NumHeads, 255); /* Number of heads */ + ST_DWORD(tbl+BPB_HiddSec, b_vol); /* Hidden sectors */ + n = get_fattime(); /* Use current time as VSN */ + if (fmt == FS_FAT32) { + ST_DWORD(tbl+BS_VolID32, n); /* VSN */ + ST_DWORD(tbl+BPB_FATSz32, n_fat); /* Number of sectors per FAT */ + ST_DWORD(tbl+BPB_RootClus, 2); /* Root directory start cluster (2) */ + ST_WORD(tbl+BPB_FSInfo, 1); /* FSInfo record offset (VBR+1) */ + ST_WORD(tbl+BPB_BkBootSec, 6); /* Backup boot record offset (VBR+6) */ + tbl[BS_DrvNum32] = 0x80; /* Drive number */ + tbl[BS_BootSig32] = 0x29; /* Extended boot signature */ + mem_cpy(tbl+BS_VolLab32, "NO NAME FAT32 ", 19); /* Volume label, FAT signature */ + } else { + ST_DWORD(tbl+BS_VolID, n); /* VSN */ + ST_WORD(tbl+BPB_FATSz16, n_fat); /* Number of sectors per FAT */ + tbl[BS_DrvNum] = 0x80; /* Drive number */ + tbl[BS_BootSig] = 0x29; /* Extended boot signature */ + mem_cpy(tbl+BS_VolLab, "NO NAME FAT ", 19); /* Volume label, FAT signature */ + } + ST_WORD(tbl+BS_55AA, 0xAA55); /* Signature (Offset is fixed here regardless of sector size) */ + if (disk_write(drv, tbl, b_vol, 1) != RES_OK) /* Original (VBR) */ + return FR_DISK_ERR; + if (fmt == FS_FAT32) /* Backup (VBR+6) */ + disk_write(drv, tbl, b_vol + 6, 1); + + /* Initialize FAT area */ + for (i = 0; i < N_FATS; i++) { + mem_set(tbl, 0, SS(fs)); /* 1st sector of the FAT */ + n = md; /* Media descriptor byte */ + if (fmt != FS_FAT32) { + n |= (fmt == FS_FAT12) ? 0x00FFFF00 : 0xFFFFFF00; + ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT12/16) */ + } else { + n |= 0x0FFFFF00; + ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT32) */ + ST_DWORD(tbl+4, 0x0FFFFFFF); + ST_DWORD(tbl+8, 0x0FFFFFFF); /* Reserve cluster #2 for root dir */ + } + if (disk_write(drv, tbl, b_fat++, 1) != RES_OK) + return FR_DISK_ERR; + mem_set(tbl, 0, SS(fs)); /* Fill following FAT entries with zero */ + for (n = 1; n < n_fat; n++) { /* This loop may take a time on FAT32 volume due to many single sector write */ + if (disk_write(drv, tbl, b_fat++, 1) != RES_OK) + return FR_DISK_ERR; + } + } + + /* Initialize root directory */ + n = (fmt == FS_FAT32) ? as : n_dir; + while (n--) { + if (disk_write(drv, tbl, b_fat++, 1) != RES_OK) + return FR_DISK_ERR; + } + + /* Create FSInfo record if needed */ + if (fmt == FS_FAT32) { + ST_WORD(tbl+BS_55AA, 0xAA55); + ST_DWORD(tbl+FSI_LeadSig, 0x41615252); + ST_DWORD(tbl+FSI_StrucSig, 0x61417272); + ST_DWORD(tbl+FSI_Free_Count, n_clst - 1); + ST_DWORD(tbl+FSI_Nxt_Free, 0xFFFFFFFF); + disk_write(drv, tbl, b_vol + 1, 1); /* Original (VBR+1) */ + disk_write(drv, tbl, b_vol + 7, 1); /* Backup (VBR+7) */ + } + + return (disk_ioctl(drv, CTRL_SYNC, (void*)0) == RES_OK) ? FR_OK : FR_DISK_ERR; +} + +#endif /* _USE_MKFS && !_FS_READONLY */ + + + + +#if _USE_STRFUNC +/*-----------------------------------------------------------------------*/ +/* Get a string from the file */ +/*-----------------------------------------------------------------------*/ +TCHAR* f_gets ( + TCHAR* buff, /* Pointer to the string buffer to read */ + int len, /* Size of string buffer (characters) */ + FIL* fil /* Pointer to the file object */ +) +{ + int n = 0; + TCHAR c, *p = buff; + BYTE s[2]; + UINT rc; + + + while (n < len - 1) { /* Read bytes until buffer gets filled */ + f_read(fil, s, 1, &rc); + if (rc != 1) break; /* Break on EOF or error */ + c = s[0]; +#if _LFN_UNICODE /* Read a character in UTF-8 encoding */ + if (c >= 0x80) { + if (c < 0xC0) continue; /* Skip stray trailer */ + if (c < 0xE0) { /* Two-byte sequense */ + f_read(fil, s, 1, &rc); + if (rc != 1) break; + c = ((c & 0x1F) << 6) | (s[0] & 0x3F); + if (c < 0x80) c = '?'; + } else { + if (c < 0xF0) { /* Three-byte sequense */ + f_read(fil, s, 2, &rc); + if (rc != 2) break; + c = (c << 12) | ((s[0] & 0x3F) << 6) | (s[1] & 0x3F); + if (c < 0x800) c = '?'; + } else { /* Reject four-byte sequense */ + c = '?'; + } + } + } +#endif +#if _USE_STRFUNC >= 2 + if (c == '\r') continue; /* Strip '\r' */ +#endif + *p++ = c; + n++; + if (c == '\n') break; /* Break on EOL */ + } + *p = 0; + return n ? buff : 0; /* When no data read (eof or error), return with error. */ +} + + + +#if !_FS_READONLY +#include +/*-----------------------------------------------------------------------*/ +/* Put a character to the file */ +/*-----------------------------------------------------------------------*/ +int f_putc ( + TCHAR c, /* A character to be output */ + FIL* fil /* Pointer to the file object */ +) +{ + UINT bw, btw; + BYTE s[3]; + + +#if _USE_STRFUNC >= 2 + if (c == '\n') f_putc ('\r', fil); /* LF -> CRLF conversion */ +#endif + +#if _LFN_UNICODE /* Write the character in UTF-8 encoding */ + if (c < 0x80) { /* 7-bit */ + s[0] = (BYTE)c; + btw = 1; + } else { + if (c < 0x800) { /* 11-bit */ + s[0] = (BYTE)(0xC0 | (c >> 6)); + s[1] = (BYTE)(0x80 | (c & 0x3F)); + btw = 2; + } else { /* 16-bit */ + s[0] = (BYTE)(0xE0 | (c >> 12)); + s[1] = (BYTE)(0x80 | ((c >> 6) & 0x3F)); + s[2] = (BYTE)(0x80 | (c & 0x3F)); + btw = 3; + } + } +#else /* Write the character without conversion */ + s[0] = (BYTE)c; + btw = 1; +#endif + f_write(fil, s, btw, &bw); /* Write the char to the file */ + return (bw == btw) ? 1 : EOF; /* Return the result */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a string to the file */ +/*-----------------------------------------------------------------------*/ +int f_puts ( + const TCHAR* str, /* Pointer to the string to be output */ + FIL* fil /* Pointer to the file object */ +) +{ + int n; + + + for (n = 0; *str; str++, n++) { + if (f_putc(*str, fil) == EOF) return EOF; + } + return n; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a formatted string to the file */ +/*-----------------------------------------------------------------------*/ +int f_printf ( + FIL* fil, /* Pointer to the file object */ + const TCHAR* str, /* Pointer to the format string */ + ... /* Optional arguments... */ +) +{ + va_list arp; + BYTE f, r; + UINT i, w; + ULONG val; + TCHAR c, d, s[16]; + int res, cc; + + + va_start(arp, str); + + for (cc = res = 0; cc != EOF; res += cc) { + c = *str++; + if (c == 0) break; /* End of string */ + if (c != '%') { /* Non escape character */ + cc = f_putc(c, fil); + if (cc != EOF) cc = 1; + continue; + } + w = f = 0; + c = *str++; + if (c == '0') { /* Flag: '0' padding */ + f = 1; c = *str++; + } + while (IsDigit(c)) { /* Precision */ + w = w * 10 + c - '0'; + c = *str++; + } + if (c == 'l' || c == 'L') { /* Prefix: Size is long int */ + f |= 2; c = *str++; + } + if (!c) break; + d = c; + if (IsLower(d)) d -= 0x20; + switch (d) { /* Type is... */ + case 'S' : /* String */ + cc = f_puts(va_arg(arp, TCHAR*), fil); continue; + case 'C' : /* Character */ + cc = f_putc((TCHAR)va_arg(arp, int), fil); continue; + case 'B' : /* Binary */ + r = 2; break; + case 'O' : /* Octal */ + r = 8; break; + case 'D' : /* Signed decimal */ + case 'U' : /* Unsigned decimal */ + r = 10; break; + case 'X' : /* Hexdecimal */ + r = 16; break; + default: /* Unknown */ + cc = f_putc(c, fil); continue; + } + + /* Get an argument */ + val = (f & 2) ? va_arg(arp, long) : ((d == 'D') ? (long)va_arg(arp, int) : va_arg(arp, unsigned int)); + if (d == 'D' && (val & 0x80000000)) { + val = 0 - val; + f |= 4; + } + /* Put it in numeral string */ + i = 0; + do { + d = (TCHAR)(val % r); val /= r; + if (d > 9) { + d += 7; + if (c == 'x') d += 0x20; + } + s[i++] = d + '0'; + } while (val && i < sizeof(s) / sizeof(s[0])); + if (f & 4) s[i++] = '-'; + cc = 0; + while (i < w-- && cc != EOF) { + cc = f_putc((TCHAR)((f & 1) ? '0' : ' '), fil); + res++; + } + do { + cc = f_putc(s[--i], fil); + res++; + } while (i && cc != EOF); + if (cc != EOF) cc = 0; + } + + va_end(arp); + return (cc == EOF) ? cc : res; +} + +#endif /* !_FS_READONLY */ +#endif /* _USE_STRFUNC */ diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/ff.h b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/ff.h new file mode 100644 index 0000000..d739704 --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/ff.h @@ -0,0 +1,613 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module include file R0.08 (C)ChaN, 2010 +/----------------------------------------------------------------------------/ +/ FatFs module is a generic FAT file system module for small embedded systems. +/ This is a free software that opened for education, research and commercial +/ developments under license policy of following trems. +/ +/ Copyright (C) 2010, ChaN, all right reserved. +/ +/ * The FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/----------------------------------------------------------------------------*/ + +#ifndef _FATFS +#define _FATFS 8085 /* Revision ID */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "integer.h" /* Basic integer types */ +#include "ffconf.h" /* FatFs configuration options */ + +#if _FATFS != _FFCONF +#error Wrong configuration file (ffconf.h). +#endif + + +/* DBCS code ranges and SBCS extend char conversion table */ + +#if _CODE_PAGE == 932 /* Japanese Shift-JIS */ +#define _DF1S 0x81 /* DBC 1st byte range 1 start */ +#define _DF1E 0x9F /* DBC 1st byte range 1 end */ +#define _DF2S 0xE0 /* DBC 1st byte range 2 start */ +#define _DF2E 0xFC /* DBC 1st byte range 2 end */ +#define _DS1S 0x40 /* DBC 2nd byte range 1 start */ +#define _DS1E 0x7E /* DBC 2nd byte range 1 end */ +#define _DS2S 0x80 /* DBC 2nd byte range 2 start */ +#define _DS2E 0xFC /* DBC 2nd byte range 2 end */ + +#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0x80 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 949 /* Korean */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x41 +#define _DS1E 0x5A +#define _DS2S 0x61 +#define _DS2E 0x7A +#define _DS3S 0x81 +#define _DS3E 0xFE + +#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0xA1 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 437 /* U.S. (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 720 /* Arabic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 737 /* Greek (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \ + 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 775 /* Baltic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF} + +#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \ + 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \ + 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 857 /* Turkish (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 862 /* Hebrew (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 866 /* Russian (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF} + +#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1253 /* Greek (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \ + 0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF} + +#elif _CODE_PAGE == 1254 /* Turkish (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1256 /* Arabic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1257 /* Baltic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F} + +#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */ +#define _DF1S 0 + +#else +#error Unknown code page + +#endif + + + +/* Definitions corresponds to volume management */ + +#if _MULTI_PARTITION /* Multiple partition configuration */ +#define LD2PD(drv) (Drives[drv].pd) /* Get physical drive# */ +#define LD2PT(drv) (Drives[drv].pt) /* Get partition# */ +typedef struct { + BYTE pd; /* Physical drive# */ + BYTE pt; /* Partition # (0-3) */ +} PARTITION; +extern const PARTITION Drives[]; /* Logical drive# to physical location conversion table */ + +#else /* Single partition configuration */ +#define LD2PD(drv) (drv) /* Physical drive# is equal to the logical drive# */ +#define LD2PT(drv) 0 /* Always mounts the 1st partition */ + +#endif + + + +/* Type of path name strings on FatFs API */ + +#if _LFN_UNICODE /* Unicode string */ +#if !_USE_LFN +#error _LFN_UNICODE must be 0 in non-LFN cfg. +#endif +#ifndef _INC_TCHAR +typedef WCHAR TCHAR; +#define _T(x) L ## x +#define _TEXT(x) L ## x +#endif + +#else /* ANSI/OEM string */ +#ifndef _INC_TCHAR +typedef char TCHAR; +#define _T(x) x +#define _TEXT(x) x +#endif + +#endif + + + +/* Definitions corresponds to file shareing feature */ + +#if _FS_SHARE +#if _FS_READONLY +#error _FS_SHARE must be 0 on R/O cfg. +#endif +typedef struct { + DWORD clu; /* File ID 1, directory */ + WORD idx; /* File ID 2, index in the directory */ + WORD ctr; /* File open counter, 0:none, 0x01..0xFF:read open count, 0x100:in write open */ +} FILESEM; +#endif + + + +/* File system object structure (FATFS) */ + +typedef struct { + BYTE fs_type; /* FAT sub-type (0:Not mounted) */ + BYTE drv; /* Physical drive number */ + BYTE csize; /* Sectors per cluster (1,2,4...128) */ + BYTE n_fats; /* Number of FAT copies (1,2) */ + BYTE wflag; /* win[] dirty flag (1:must be written back) */ + BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */ + WORD id; /* File system mount ID */ + WORD n_rootdir; /* Number of root directory entries (FAT12/16) */ +#if _MAX_SS != 512 + WORD ssize; /* Bytes per sector (512,1024,2048,4096) */ +#endif +#if _FS_REENTRANT + _SYNC_t sobj; /* Identifier of sync object */ +#endif +#if !_FS_READONLY + DWORD last_clust; /* Last allocated cluster */ + DWORD free_clust; /* Number of free clusters */ + DWORD fsi_sector; /* fsinfo sector (FAT32) */ +#endif +#if _FS_RPATH + DWORD cdir; /* Current directory start cluster (0:root) */ +#endif + DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */ + DWORD fsize; /* Sectors per FAT */ + DWORD fatbase; /* FAT start sector */ + DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */ + DWORD database; /* Data start sector */ + DWORD winsect; /* Current sector appearing in the win[] */ + BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */ +#if _FS_SHARE + FILESEM flsem[_FS_SHARE]; /* File lock semaphores */ +#endif +} FATFS; + + + +/* File object structure (FIL) */ + +typedef struct { + FATFS* fs; /* Pointer to the owner file system object */ + WORD id; /* Owner file system mount ID */ + BYTE flag; /* File status flags */ + BYTE pad1; + DWORD fptr; /* File read/write pointer */ + DWORD fsize; /* File size */ + DWORD org_clust; /* File start cluster (0 when fsize==0) */ + DWORD curr_clust; /* Current cluster */ + DWORD dsect; /* Current data sector */ +#if !_FS_READONLY + DWORD dir_sect; /* Sector containing the directory entry */ + BYTE* dir_ptr; /* Ponter to the directory entry in the window */ +#endif +#if _USE_FASTSEEK + DWORD* cltbl; /* Pointer to the cluster link map table */ +#endif +#if _FS_SHARE + UINT lockid; /* File lock ID */ +#endif +#if !_FS_TINY + BYTE buf[_MAX_SS]; /* File data read/write buffer */ +#endif +} FIL; + + + +/* Directory object structure (DIR) */ + +typedef struct { + FATFS* fs; /* Pointer to the owner file system object */ + WORD id; /* Owner file system mount ID */ + WORD index; /* Current read/write index number */ + DWORD sclust; /* Table start cluster (0:Root dir) */ + DWORD clust; /* Current cluster */ + DWORD sect; /* Current sector */ + BYTE* dir; /* Pointer to the current SFN entry in the win[] */ + BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */ +#if _USE_LFN + WCHAR* lfn; /* Pointer to the LFN working buffer */ + WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */ +#endif +} DIR; + + + +/* File status structure (FILINFO) */ + +typedef struct { + DWORD fsize; /* File size */ + WORD fdate; /* Last modified date */ + WORD ftime; /* Last modified time */ + BYTE fattrib; /* Attribute */ + TCHAR fname[13]; /* Short file name (8.3 format) */ +#if _USE_LFN + TCHAR* lfname; /* Pointer to the LFN buffer */ + int lfsize; /* Size of LFN buffer [chrs] */ +#endif +} FILINFO; + + + +/* File function return code (FRESULT) */ + +typedef enum { + FR_OK = 0, /* (0) Succeeded */ + FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */ + FR_INT_ERR, /* (2) Assertion failed */ + FR_NOT_READY, /* (3) The physical drive cannot work */ + FR_NO_FILE, /* (4) Could not find the file */ + FR_NO_PATH, /* (5) Could not find the path */ + FR_INVALID_NAME, /* (6) The path name format is invalid */ + FR_DENIED, /* (7) Acces denied due to prohibited access or directory full */ + FR_EXIST, /* (8) Acces denied due to prohibited access */ + FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */ + FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */ + FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ + FR_NOT_ENABLED, /* (12) The volume has no work area */ + FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume on the physical drive */ + FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */ + FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ + FR_LOCKED, /* (16) The operation is rejected according to the file shareing policy */ + FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ + FR_TOO_MANY_OPEN_FILES /* (18) Number of open files > _FS_SHARE */ +} FRESULT; + + + +/*--------------------------------------------------------------*/ +/* FatFs module application interface */ + +FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */ +FRESULT f_open (FIL*, const TCHAR*, BYTE); /* Open or create a file */ +FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */ +FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */ +FRESULT f_close (FIL*); /* Close an open file object */ +FRESULT f_opendir (DIR*, const TCHAR*); /* Open an existing directory */ +FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */ +FRESULT f_stat (const TCHAR*, FILINFO*); /* Get file status */ +#if !_FS_READONLY +FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */ +FRESULT f_getfree (const TCHAR*, DWORD*, FATFS**); /* Get number of free clusters on the drive */ +FRESULT f_truncate (FIL*); /* Truncate file */ +FRESULT f_sync (FIL*); /* Flush cached data of a writing file */ +FRESULT f_unlink (const TCHAR*); /* Delete an existing file or directory */ +FRESULT f_mkdir (const TCHAR*); /* Create a new directory */ +FRESULT f_chmod (const TCHAR*, BYTE, BYTE); /* Change attriburte of the file/dir */ +FRESULT f_utime (const TCHAR*, const FILINFO*); /* Change timestamp of the file/dir */ +FRESULT f_rename (const TCHAR*, const TCHAR*); /* Rename/Move a file or directory */ +#endif +#if _USE_FORWARD +FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */ +#endif +#if _USE_MKFS +FRESULT f_mkfs (BYTE, BYTE, UINT); /* Create a file system on the drive */ +#endif +#if _FS_RPATH +FRESULT f_chdir (const TCHAR*); /* Change current directory */ +FRESULT f_chdrive (BYTE); /* Change current drive */ +#endif +#if _USE_STRFUNC +int f_putc (TCHAR, FIL*); /* Put a character to the file */ +int f_puts (const TCHAR*, FIL*); /* Put a string to the file */ +int f_printf (FIL*, const TCHAR*, ...); /* Put a formatted string to the file */ +TCHAR* f_gets (TCHAR*, int, FIL*); /* Get a string from the file */ +#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0) +#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0) +#ifndef EOF +#define EOF (-1) +#endif +#endif + + + +/*--------------------------------------------------------------*/ +/* Additional user defined functions */ + +/* RTC function */ +#if !_FS_READONLY +DWORD get_fattime (void); +#endif + +/* Unicode support functions */ +#if _USE_LFN /* Unicode - OEM code conversion */ +WCHAR ff_convert (WCHAR, UINT); /* OEM-Unicode bidirectional conversion */ +WCHAR ff_wtoupper (WCHAR); /* Unicode upper-case conversion */ +#if _USE_LFN == 3 /* Memory functions */ +void* ff_memalloc (UINT); /* Allocate memory block */ +void ff_memfree (void*); /* Free memory block */ +#endif +#endif + +/* Sync functions */ +#if _FS_REENTRANT +int ff_cre_syncobj (BYTE, _SYNC_t*);/* Create a sync object */ +int ff_del_syncobj (_SYNC_t); /* Delete a sync object */ +int ff_req_grant (_SYNC_t); /* Lock sync object */ +void ff_rel_grant (_SYNC_t); /* Unlock sync object */ +#endif + + + + +/*--------------------------------------------------------------*/ +/* Flags and offset address */ + + +/* File access control and file status flags (FIL.flag) */ + +#define FA_READ 0x01 +#define FA_OPEN_EXISTING 0x00 +#define FA__ERROR 0x80 + +#if !_FS_READONLY +#define FA_WRITE 0x02 +#define FA_CREATE_NEW 0x04 +#define FA_CREATE_ALWAYS 0x08 +#define FA_OPEN_ALWAYS 0x10 +#define FA__WRITTEN 0x20 +#define FA__DIRTY 0x40 +#endif + + +/* FAT sub type (FATFS.fs_type) */ + +#define FS_FAT12 1 +#define FS_FAT16 2 +#define FS_FAT32 3 + + +/* File attribute bits for directory entry */ + +#define AM_RDO 0x01 /* Read only */ +#define AM_HID 0x02 /* Hidden */ +#define AM_SYS 0x04 /* System */ +#define AM_VOL 0x08 /* Volume label */ +#define AM_LFN 0x0F /* LFN entry */ +#define AM_DIR 0x10 /* Directory */ +#define AM_ARC 0x20 /* Archive */ +#define AM_MASK 0x3F /* Mask of defined bits */ + + +/* Fast seek function */ +#define CREATE_LINKMAP 0xFFFFFFFF + + +/* FatFs refers the members in the FAT structures with byte offset instead of +/ structure member because there are incompatibility of the packing option +/ between various compilers. */ + +#define BS_jmpBoot 0 +#define BS_OEMName 3 +#define BPB_BytsPerSec 11 +#define BPB_SecPerClus 13 +#define BPB_RsvdSecCnt 14 +#define BPB_NumFATs 16 +#define BPB_RootEntCnt 17 +#define BPB_TotSec16 19 +#define BPB_Media 21 +#define BPB_FATSz16 22 +#define BPB_SecPerTrk 24 +#define BPB_NumHeads 26 +#define BPB_HiddSec 28 +#define BPB_TotSec32 32 +#define BS_55AA 510 + +#define BS_DrvNum 36 +#define BS_BootSig 38 +#define BS_VolID 39 +#define BS_VolLab 43 +#define BS_FilSysType 54 + +#define BPB_FATSz32 36 +#define BPB_ExtFlags 40 +#define BPB_FSVer 42 +#define BPB_RootClus 44 +#define BPB_FSInfo 48 +#define BPB_BkBootSec 50 +#define BS_DrvNum32 64 +#define BS_BootSig32 66 +#define BS_VolID32 67 +#define BS_VolLab32 71 +#define BS_FilSysType32 82 + +#define FSI_LeadSig 0 +#define FSI_StrucSig 484 +#define FSI_Free_Count 488 +#define FSI_Nxt_Free 492 + +#define MBR_Table 446 + +#define DIR_Name 0 +#define DIR_Attr 11 +#define DIR_NTres 12 +#define DIR_CrtTime 14 +#define DIR_CrtDate 16 +#define DIR_FstClusHI 20 +#define DIR_WrtTime 22 +#define DIR_WrtDate 24 +#define DIR_FstClusLO 26 +#define DIR_FileSize 28 +#define LDIR_Ord 0 +#define LDIR_Attr 11 +#define LDIR_Type 12 +#define LDIR_Chksum 13 +#define LDIR_FstClusLO 26 + + + +/*--------------------------------*/ +/* Multi-byte word access macros */ + +#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val) +#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val) +#else /* Use byte-by-byte access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8) +#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _FATFS */ diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/ffconf.h b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/ffconf.h new file mode 100644 index 0000000..ca26e10 --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/ffconf.h @@ -0,0 +1,179 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module configuration file R0.08 (C)ChaN, 2010 +/----------------------------------------------------------------------------/ +/ +/ CAUTION! Do not forget to make clean the project after any changes to +/ the configuration options. +/ +/----------------------------------------------------------------------------*/ +#ifndef _FFCONF +#define _FFCONF 8085 /* Revision ID */ + + +/*---------------------------------------------------------------------------/ +/ Function and Buffer Configurations +/----------------------------------------------------------------------------*/ + +#define _FS_TINY 1 /* 0 or 1 */ +/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system +/ object instead of the sector buffer in the individual file object for file +/ data transfer. This reduces memory consumption 512 bytes each file object. */ + + +#define _FS_READONLY 0 /* 0 or 1 */ +/* Setting _FS_READONLY to 1 defines read only configuration. This removes +/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename, +/ f_truncate and useless f_getfree. */ + + +#define _FS_MINIMIZE 0 /* 0, 1, 2 or 3 */ +/* The _FS_MINIMIZE option defines minimization level to remove some functions. +/ +/ 0: Full function. +/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename +/ are removed. +/ 2: f_opendir and f_readdir are removed in addition to level 1. +/ 3: f_lseek is removed in addition to level 2. */ + + +#define _USE_STRFUNC 0 /* 0, 1 or 2 */ +/* To enable string functions, set _USE_STRFUNC to 1 or 2. */ + + +#define _USE_MKFS 1 /* 0 or 1 */ +/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */ + + +#define _USE_FORWARD 0 /* 0 or 1 */ +/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */ + + +#define _USE_FASTSEEK 0 /* 0 or 1 */ +/* To enable f_fastseek function, set _USE_FASTSEEK to 1. */ + + + +/*---------------------------------------------------------------------------/ +/ Locale and Namespace Configurations +/----------------------------------------------------------------------------*/ + +#define _CODE_PAGE 1 +/* The _CODE_PAGE specifies the OEM code page to be used on the target system. +/ Incorrect setting of the code page can cause a file open failure. +/ +/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows) +/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows) +/ 949 - Korean (DBCS, OEM, Windows) +/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) +/ 1250 - Central Europe (Windows) +/ 1251 - Cyrillic (Windows) +/ 1252 - Latin 1 (Windows) +/ 1253 - Greek (Windows) +/ 1254 - Turkish (Windows) +/ 1255 - Hebrew (Windows) +/ 1256 - Arabic (Windows) +/ 1257 - Baltic (Windows) +/ 1258 - Vietnam (OEM, Windows) +/ 437 - U.S. (OEM) +/ 720 - Arabic (OEM) +/ 737 - Greek (OEM) +/ 775 - Baltic (OEM) +/ 850 - Multilingual Latin 1 (OEM) +/ 858 - Multilingual Latin 1 + Euro (OEM) +/ 852 - Latin 2 (OEM) +/ 855 - Cyrillic (OEM) +/ 866 - Russian (OEM) +/ 857 - Turkish (OEM) +/ 862 - Hebrew (OEM) +/ 874 - Thai (OEM, Windows) +/ 1 - ASCII only (Valid for non LFN cfg.) +*/ + + +#define _USE_LFN 0 /* 0 to 3 */ +#define _MAX_LFN 128 /* Maximum LFN length to handle (12 to 255) */ +/* The _USE_LFN option switches the LFN support. +/ +/ 0: Disable LFN. _MAX_LFN and _LFN_UNICODE have no effect. +/ 1: Enable LFN with static working buffer on the bss. NOT REENTRANT. +/ 2: Enable LFN with dynamic working buffer on the STACK. +/ 3: Enable LFN with dynamic working buffer on the HEAP. +/ +/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN, +/ Unicode handling functions ff_convert() and ff_wtoupper() must be added +/ to the project. When enable to use heap, memory control functions +/ ff_memalloc() and ff_memfree() must be added to the project. */ + + +#define _LFN_UNICODE 0 /* 0 or 1 */ +/* To switch the character code set on FatFs API to Unicode, +/ enable LFN feature and set _LFN_UNICODE to 1. +*/ + + +#define _FS_RPATH 1 /* 0 or 1 */ +/* When _FS_RPATH is set to 1, relative path feature is enabled and f_chdir, +/ f_chdrive function are available. +/ Note that output of the f_readdir fnction is affected by this option. */ + + + +/*---------------------------------------------------------------------------/ +/ Physical Drive Configurations +/----------------------------------------------------------------------------*/ + +#define _DRIVES 2 +/* Number of volumes (logical drives) to be used. */ + + +#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */ +/* Maximum sector size to be handled. +/ Always set 512 for memory card and hard disk but a larger value may be +/ required for floppy disk (512/1024) and optical disk (512/2048). +/ When _MAX_SS is larger than 512, GET_SECTOR_SIZE command must be implememted +/ to the disk_ioctl function. */ + + +#define _MULTI_PARTITION 0 /* 0 or 1 */ +/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical +/ drive number and can mount only first primaly partition. When it is set to 1, +/ each volume is tied to the partitions listed in Drives[]. */ + + + +/*---------------------------------------------------------------------------/ +/ System Configurations +/----------------------------------------------------------------------------*/ + +#define _WORD_ACCESS 1 /* 0 or 1 */ +/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS +/ option defines which access method is used to the word data on the FAT volume. +/ +/ 0: Byte-by-byte access. +/ 1: Word access. Do not choose this unless following condition is met. +/ +/ When the byte order on the memory is big-endian or address miss-aligned word +/ access results incorrect behavior, the _WORD_ACCESS must be set to 0. +/ If it is not the case, the value can also be set to 1 to improve the +/ performance and code size. */ + + +#define _FS_REENTRANT 0 /* 0 or 1 */ +#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */ +#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */ +/* The _FS_REENTRANT option switches the reentrancy of the FatFs module. +/ +/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect. +/ 1: Enable reentrancy. Also user provided synchronization handlers, +/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj +/ function must be added to the project. */ + + +#define _FS_SHARE 0 /* 0 or >=1 */ +/* To enable file shareing feature, set _FS_SHARE to >= 1 and also user + provided memory handlers, ff_memalloc and ff_memfree function must be + added to the project. The value defines number of files can be opened + per volume. */ + + +#endif /* _FFCONF */ diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/integer.h b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/integer.h new file mode 100644 index 0000000..16ad408 --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/integer.h @@ -0,0 +1,37 @@ +/*-------------------------------------------*/ +/* Integer type definitions for FatFs module */ +/*-------------------------------------------*/ + +#ifndef _INTEGER +#define _INTEGER + +#ifdef _WIN32 /* FatFs development platform */ + +#include +#include + +#else /* Embedded platform */ + +/* These types must be 16-bit, 32-bit or larger integer */ +typedef int INT; +typedef unsigned int UINT; + +/* These types must be 8-bit integer */ +typedef char CHAR; +typedef unsigned char UCHAR; +typedef unsigned char BYTE; + +/* These types must be 16-bit integer */ +typedef short SHORT; +typedef unsigned short USHORT; +typedef unsigned short WORD; +typedef unsigned short WCHAR; + +/* These types must be 32-bit integer */ +typedef long LONG; +typedef unsigned long ULONG; +typedef unsigned long DWORD; + +#endif + +#endif diff --git a/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/main.c b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/main.c new file mode 100644 index 0000000..1e55354 --- /dev/null +++ b/OSU Coursework/CS 162 - Intro to Programming II/Labs/Lab 4/main.c @@ -0,0 +1,300 @@ +/** +@file main.c +@brief Lab 3 Starter Code +@version .01 +@mainpage Lab 3 Starter Code + +@section intro Code Overview + +@section hw Hardware Pin Out +Port A: +A0 - A3 : Push Buttons +A4 - A7 : Slide Switches + +Port B: +B0 - B3 : SPI (SD Card) +B4 : Nothing +B5 : Audio Out +B6 : Red Enable +B7 : Green Enable + +Port C: +C0 - C7 : LED Array (Row) + +Port D: +D0 - D1 : Nothing +D2 : Serial RX +D3 : Serial TX +D4 - D7 : Nothing + +Port E: +E0 - E2 : LED Array (Column) +E3 : USB (UID) +E4 - E5 : Nothing +E6 : Relay +E7 : Nothing + +Port F: +F0 : ADC Channel 0 +F1 : ADC Channel 1 +F2 : ADC Channel 2 +F3 : ADC Channel 3 +F4 : ADC Channel 4 (Audio In) +F5 : ADC Channel 5 (Accel X Axis) +F6 : ADC Channel 6 (Accel Y Axis) +F7 : ADC Channel 7 (Accel Z Axis (if installed)) + +*/ + +/** Includes */ +#include +#include +#include + + +/** Constants */ +#define F_CPU 1000000UL +#define DEBUG 1 +#ifdef DEBUG == 1 + #define SENDSPEED 3 //If less than .12, there are problems +#endif + +/** Global Variables */ + +volatile unsigned char numelapsed = 0; + +/** Functions */ + +#ifdef DEBUG == 1 + /** This function needs to setup the variables used by the UART to enable the UART and tramsmit at 9600bps. This + function should always return 0. Remember, by defualt the Wunderboard runs at 1mHz for its system clock.*/ + unsigned char InitializeUART (){ + unsigned char baud = ((F_CPU/(9600*8UL))-1); + + /* Set baud rate */ + UBRR1H = (baud >> 8); + UBRR1L = baud; + /* Set the U2X1 bit */ + UCSR1A = (1 << U2X1); + /* Enable transmitter */ + UCSR1B = (1 << TXEN1 | 1 << RXEN1); + /* Set frame format: 8data, 1stop bit */ + UCSR1C = (3 << UCSZ10); + + return 0; + } + + /** This function needs to write a single byte to the UART. It must check that the UART is ready for a new byte + and return a 1 if the byte was not sent. + @param [in] data This is the data byte to be sent. + @return The function returns a 1 or error and 0 on successful completion.*/ + + unsigned char SendByteUART (unsigned char data){ + + /* + ** Checks the buffer empty bit so that data can either be placed in the buffer + ** or else reuturn a 1 + */ + if((UCSR1A & (1 << UDRE1)) == (1 << UDRE1)){ + UDR1 = data; //Places data into the UDR1 8-bit data buffer + }else { + return 1; + } + + return 0; + } + + /** This function needs to writes a string to the UART. It must check that the UART is ready for a new byte and + return a 1 if the string was not sent. + @param [in] data This is a pointer to the data to be sent. + @return The function returns a 1 or error and 0 on successful completion.*/ + + unsigned char SendStringUART (unsigned char *data){ + + for (int loop = 0 ; data[loop] != '\0'; loop++){ + unsigned char bytereturn; //Storage for return value of SendByteUART + + /* Sends the current byte based on the loop umber to SendByte */ + while(SendByteUART(data[loop])); + + /* Stops sending if SendByteUART had an error */ + if(bytereturn == 1){ + return 1; + } + } + return 0; + } + + unsigned char GetByteUART(){ + if (UCSR1A & (1 << RXC1)){ + return(UDR1); + } else{ + return(-1); + } + } +#endif + +/** The clearArray() function turns off all LEDS on the Wunderboard array. It accepts no inputs and returns nothing*/ +void clearArray(void){ + PORTC = 0x00; + PORTB |= (1 << PB6) | (1 << PB7); /** Enable latches*/ + PORTB &= ~((1 << PB6) | (1 << PB7)); /** Disable latches*/ +} + +/** The initialize() function initializes all of the Data Direction Registers for the Wunderboard. Before making changes to DDRx registers, ensure that you have read the peripherals section of the Wunderboard user guide.*/ +void initialize(void){ + /** Port A is the switches and buttons. They should always be inputs. ( 0 = Input and 1 = Output )*/ + DDRA=0b00000000; + + /** Port B has the LED Array color control, SD card, and audio-out on it. Leave DDRB alone. ( 0 = Input and 1 = Output )*/ + DDRB=0b11000111; + + /** Port C is for the 'row' of the LED array. They should always be outputs. ( 0 = Input and 1 = Output )*/ + DDRC=0b11111111; + + /** Port D has the Serial on it. Leave DDRB alone. ( 0 = Input and 1 = Output )*/ + DDRD=0b00000000; + + /** Port E has the LED Array Column control out on it. Leave DDRE alone. ( 0 = Input and 1 = Output )*/ + DDRE=0b00000111; + + /** Port F has the accelerometer and audio-in on it. Leave DDRF alone. ( 0 = Input and 1 = Output )*/ + DDRF=0b00000000; +} + +unsigned char read_adc(uint8_t channel){ + + unsigned char test; + + ADMUX = 0x60 | channel; // Set the channel to the one we want + ADCSRA = 0b11000110; // Start a new sample. + while ((ADCSRA & 0b00010000) == 0 ); // Wait for a Valid Sample + ADCSRA |= 0b00010000; // Tell ADC you have the sample you want. + ADCSRA |= 0b01000000; // Start a new sample. + while ((ADCSRA & 0b00010000) == 0 ); // Wait for a Valid Sample + ADCSRA |= 0b00010000; // Tell ADC you have the sample you want. + + test = ADCH; + ADCSRA = 0x00; // Disable the ADC + + return (test); +} + + +/** This function needs to setup the variables used by TIMER0 Compare Match (CTC) mode with +a base clock frequency of clk/1024. This function should return a 1 if it fails and a 0 if it +does not. Remember, by default the Wunderboard runs at 1mHz for its system clock. +@return This function returns a 1 is unsuccessful, else return 0.*/ +unsigned char initializeTIMER0(void){ + /* Set the CTC mode */ + TCCR0A = (1 << WGM01); + + /* Set the Clock Frequency */ + TCCR0B = ((1 << CS02) | (1 << CS00)); + + /* Set initial count value */ + OCR0A = 0; +} + +/** This function takes two values, clock and count. The value of count should be copied into OCR0A and the value of clock should be used to set CS02:0. The TCNT0 variable should also be reset to 0 so that the new timer rate starts from 0. +@param [in] clock Insert Comment +@param [in] count Insert Comment +@return The function returns a 1 or error and 0 on successful completion.*/ +unsigned char setTIMER0(unsigned char clock, unsigned char count){ + + if(clock > 7){ + return 1; + } + TCCR0B &= 0b11111000; //Zeros out last three bits + TCCR0B |= clock; + OCR0A = count; + TIMSK0 = 2; + TCNT0 = 0; + return 0; +} + +ISR(TIMER0_COMPA_vect){ + unsigned char adcreturn1; + unsigned char adcreturn2; + unsigned char send[50]; + + + adcreturn1 = read_adc(5); + adcreturn2 = read_adc(6); + + if(numelapsed == 3){ + + PORTC = ~PORTC; + + numelapsed = 0; + + SendStringUART("X Value: "); + itoa(adcreturn1, send, 2); + SendStringUART(send); + SendStringUART("\tY Value: "); + itoa(adcreturn2, send, 2); + SendStringUART(send); + SendStringUART("\n"); + + }else { + numelapsed++; + } +} + +/** Main Function */ +int main (void){ + + enum states{ + setup, + idle, + running + } state = setup; + + unsigned char debug; + unsigned char received; + + while(1){ + + switch(state){ + case setup: + + initialize(); + initializeTIMER0(); + InitializeUART(); + clearArray(); + setTIMER0(5,120); + PORTB = 0b11000000; + state = idle; + SendStringUART("Initialized...\n"); + break; + + case idle: + cli(); + + if(debug != 1){ + SendStringUART("Idling...\n"); + debug = 1; + } + received = GetByteUART(); + + if (received == 's'){ + state = running; + debug = 0; + break; + } + + break; + + case running: + sei(); + + received = GetByteUART(); + + if (received == 's'){ + state = idle; + } + + break; + } + } +} \ No newline at end of file diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 2/.cproject b/OSU Coursework/CS 261 - Data Structures/Assignment 2/.cproject new file mode 100644 index 0000000..12222bf --- /dev/null +++ b/OSU Coursework/CS 261 - Data Structures/Assignment 2/.cproject @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 2/.project b/OSU Coursework/CS 261 - Data Structures/Assignment 2/.project new file mode 100644 index 0000000..6520da1 --- /dev/null +++ b/OSU Coursework/CS 261 - Data Structures/Assignment 2/.project @@ -0,0 +1,26 @@ + + + Assignment 2 + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 2/calc.c b/OSU Coursework/CS 261 - Data Structures/Assignment 2/calc.c new file mode 100644 index 0000000..d4e0d87 --- /dev/null +++ b/OSU Coursework/CS 261 - Data Structures/Assignment 2/calc.c @@ -0,0 +1,146 @@ +#include +#include +#include +#include "dynamicArray.h" + + +/* param: s the string + param: num a pointer to double + returns: true (1) if s is a number else 0 or false. + postcondition: if it is a number, num will hold + the value of the number +*/ +int isNumber(char *s, double *num) +{ + char *end; + double returnNum; + + if(strcmp(s, "0") == 0) + { + *num = 0; + return 1; + } + else + { + returnNum = strtod(s, &end); + /* If there's anythin in end, it's bad */ + if((returnNum != 0.0) && (strcmp(end, "") == 0)) + { + *num = returnNum; + return 1; + } + } + return 0; //if got here, it was not a number +} + +/* param: stack the stack being manipulated + pre: the stack contains at least two elements + post: the top two elements are popped and + their sum is pushed back onto the stack. +*/ +void add (struct DynArr *stack) +{ + /* FIXME: You will write this function */ +} + +/* param: stack the stack being manipulated + pre: the stack contains at least two elements + post: the top two elements are popped and + their difference is pushed back onto the stack. +*/ +void subtract(struct DynArr *stack) +{ + /* FIXME: You will write this function */ +} + +/* param: stack the stack being manipulated + pre: the stack contains at least two elements + post: the top two elements are popped and + their quotient is pushed back onto the stack. +*/ +void divide(struct DynArr *stack) +{ + /* FIXME: You will write this function */ +} + +double calculate(int numInputTokens, char **inputString) +{ + int i; + double result = 0.0; + char *s; + struct DynArr *stack; + + //set up the stack + stack = createDynArr(20); + + // start at 1 to skip the name of the calculator calc + for(i=1;i < numInputTokens;i++) + { + s = inputString[i]; + + // Hint: General algorithm: + // (1) Check if the string s is in the list of operators. + // (1a) If it is, perform corresponding operations. + // (1b) Otherwise, check if s is a number. + // (1b - I) If s is not a number, produce an error. + // (1b - II) If s is a number, push it onto the stack + + if(strcmp(s, "+") == 0) + add(stack); + else if(strcmp(s,"-") == 0) + subtract(stack); + else if(strcmp(s, "/") == 0) + divide(stack); + else if(strcmp(s, "x") == 0) + /* FIXME: replace printf with your own function */ + printf("Multiplying\n"); + else if(strcmp(s, "^") == 0) + /* FIXME: replace printf with your own function */ + printf("Power\n"); + else if(strcmp(s, "^2") == 0) + /* FIXME: replace printf with your own function */ + printf("Squaring\n"); + else if(strcmp(s, "^3") == 0) + /* FIXME: replace printf with your own function */ + printf("Cubing\n"); + else if(strcmp(s, "abs") == 0) + /* FIXME: replace printf with your own function */ + printf("Absolute value\n"); + else if(strcmp(s, "sqrt") == 0) + /* FIXME: replace printf with your own function */ + printf("Square root\n"); + else if(strcmp(s, "exp") == 0) + /* FIXME: replace printf with your own function */ + printf("Exponential\n"); + else if(strcmp(s, "ln") == 0) + /* FIXME: replace printf with your own function */ + printf("Natural Log\n"); + else if(strcmp(s, "log") == 0) + /* FIXME: replace printf with your own function */ + printf("Log\n"); + else + { + // FIXME: You need to develop the code here (when s is not an operator) + // Remember to deal with special values ("pi" and "e") + + } + } //end for + + /* FIXME: You will write this part of the function (2 steps below) + * (1) Check if everything looks OK and produce an error if needed. + * (2) Store the final value in result and print it out. + */ + + return result; +} + +int main(int argc , char** argv) +{ + // assume each argument is contained in the argv array + // argc-1 determines the number of operands + operators + if (argc == 1) + return 0; + + calculate(argc,argv); + return 0; +} diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 2/dynamicArray.c b/OSU Coursework/CS 261 - Data Structures/Assignment 2/dynamicArray.c new file mode 100644 index 0000000..8d42d81 --- /dev/null +++ b/OSU Coursework/CS 261 - Data Structures/Assignment 2/dynamicArray.c @@ -0,0 +1,291 @@ +/* dynamicArray.c: Dynamic Array implementation. */ +#include +#include +#include "dynamicArray.h" + +struct DynArr +{ + TYPE *data; /* pointer to the data array */ + int size; /* Number of elements in the array */ + int capacity; /* capacity ofthe array */ +}; + + +/* ************************************************************************ + Dynamic Array Functions +************************************************************************ */ + +/* Initialize (including allocation of data array) dynamic array. + + param: v pointer to the dynamic array + param: cap capacity of the dynamic array + pre: v is not null + post: internal data array can hold cap elements + post: v->data is not null +*/ +void initDynArr(DynArr *v, int capacity) +{ + assert(capacity > 0); + assert(v!= 0); + v->data = (TYPE *) malloc(sizeof(TYPE) * capacity); + assert(v->data != 0); + v->size = 0; + v->capacity = capacity; +} + +/* Allocate and initialize dynamic array. + + param: cap desired capacity for the dyn array + pre: none + post: none + ret: a non-null pointer to a dynArr of cap capacity + and 0 elements in it. +*/ +DynArr* createDynArr(int cap) +{ + assert(cap > 0); + DynArr *r = (DynArr *)malloc(sizeof( DynArr)); + assert(r != 0); + initDynArr(r,cap); + return r; +} + +/* Deallocate data array in dynamic array. + + param: v pointer to the dynamic array + pre: none + post: d.data points to null + post: size and capacity are 0 + post: the memory used by v->data is freed +*/ +void freeDynArr(DynArr *v) +{ + if(v->data != 0) + { + free(v->data); /* free the space on the heap */ + v->data = 0; /* make it point to null */ + } + v->size = 0; + v->capacity = 0; +} + +/* Deallocate data array and the dynamic array ure. + + param: v pointer to the dynamic array + pre: none + post: the memory used by v->data is freed + post: the memory used by d is freed +*/ +void deleteDynArr(DynArr *v) +{ + freeDynArr(v); + free(v); +} + +/* Resizes the underlying array to be the size cap + + param: v pointer to the dynamic array + param: cap the new desired capacity + pre: v is not null + post: v has capacity newCap +*/ +void _dynArrSetCapacity(DynArr *v, int newCap) +{ + /* FIXME: You will write this function */ + +} + +/* Get the size of the dynamic array + + param: v pointer to the dynamic array + pre: v is not null + post: none + ret: the size of the dynamic array +*/ +int sizeDynArr(DynArr *v) +{ + return v->size; +} + +/* Adds an element to the end of the dynamic array + + param: v pointer to the dynamic array + param: val the value to add to the end of the dynamic array + pre: the dynArry is not null + post: size increases by 1 + post: if reached capacity, capacity is doubled + post: val is in the last utilized position in the array +*/ +void addDynArr(DynArr *v, TYPE val) +{ + /* FIXME: You will write this function */ + +} + +/* Get an element from the dynamic array from a specified position + + param: v pointer to the dynamic array + param: pos integer index to get the element from + pre: v is not null + pre: v is not empty + pre: pos < size of the dyn array and >= 0 + post: no changes to the dyn Array + ret: value stored at index pos +*/ + +TYPE getDynArr(DynArr *v, int pos) +{ + /* FIXME: You will write this function */ + + /* FIXME: you must change this return value */ + return 1; +} + +/* Put an item into the dynamic array at the specified location, + overwriting the element that was there + + param: v pointer to the dynamic array + param: pos the index to put the value into + param: val the value to insert + pre: v is not null + pre: v is not empty + pre: pos >= 0 and pos < size of the array + post: index pos contains new value, val +*/ +void putDynArr(DynArr *v, int pos, TYPE val) +{ + /* FIXME: You will write this function */ +} + +/* Swap two specified elements in the dynamic array + + param: v pointer to the dynamic array + param: i,j the elements to be swapped + pre: v is not null + pre: v is not empty + pre: i, j >= 0 and i,j < size of the dynamic array + post: index i now holds the value at j and index j now holds the value at i +*/ +void swapDynArr(DynArr *v, int i, int j) +{ + /* FIXME: You will write this function */ +} + +/* Remove the element at the specified location from the array, + shifts other elements back one to fill the gap + + param: v pointer to the dynamic array + param: idx location of element to remove + pre: v is not null + pre: v is not empty + pre: idx < size and idx >= 0 + post: the element at idx is removed + post: the elements past idx are moved back one +*/ +void removeAtDynArr(DynArr *v, int idx) +{ + /* FIXME: You will write this function */ +} + + + +/* ************************************************************************ + Stack Interface Functions +************************************************************************ */ + +/* Returns boolean (encoded in an int) demonstrating whether or not the + dynamic array stack has an item on it. + + param: v pointer to the dynamic array + pre: the dynArr is not null + post: none + ret: 1 if empty, otherwise 0 +*/ +int isEmptyDynArr(DynArr *v) +{ + /* FIXME: You will write this function */ + + /* FIXME: You will change this return value*/ + return 1; +} + +/* Push an element onto the top of the stack + + param: v pointer to the dynamic array + param: val the value to push onto the stack + pre: v is not null + post: size increases by 1 + if reached capacity, capacity is doubled + val is on the top of the stack +*/ +void pushDynArr(DynArr *v, TYPE val) +{ + /* FIXME: You will write this function */ +} + +/* Returns the element at the top of the stack + + param: v pointer to the dynamic array + pre: v is not null + pre: v is not empty + post: no changes to the stack +*/ +TYPE topDynArr(DynArr *v) +{ + /* FIXME: You will write this function */ + + /* FIXME: You will change this return value*/ + return 1; +} + +/* Removes the element on top of the stack + + param: v pointer to the dynamic array + pre: v is not null + pre: v is not empty + post: size is decremented by 1 + the top has been removed +*/ +void popDynArr(DynArr *v) +{ + /* FIXME: You will write this function */ +} + +/* ************************************************************************ + Bag Interface Functions +************************************************************************ */ + +/* Returns boolean (encoded as an int) demonstrating whether or not + the specified value is in the collection + true = 1 + false = 0 + + param: v pointer to the dynamic array + param: val the value to look for in the bag + pre: v is not null + pre: v is not empty + post: no changes to the bag +*/ +int containsDynArr(DynArr *v, TYPE val) +{ + /* FIXME: You will write this function */ + + /* FIXME: You will change this return value */ + return 1; + +} + +/* Removes the first occurrence of the specified value from the collection + if it occurs + + param: v pointer to the dynamic array + param: val the value to remove from the array + pre: v is not null + pre: v is not empty + post: val has been removed + post: size of the bag is reduced by 1 +*/ +void removeDynArr(DynArr *v, TYPE val) +{ + /* FIXME: You will write this function */ +} diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 2/dynamicArray.h b/OSU Coursework/CS 261 - Data Structures/Assignment 2/dynamicArray.h new file mode 100644 index 0000000..816006f --- /dev/null +++ b/OSU Coursework/CS 261 - Data Structures/Assignment 2/dynamicArray.h @@ -0,0 +1,41 @@ +/* dynamicArray.h : Dynamic Array implementation. */ +#include + +#ifndef DYNAMIC_ARRAY_INCLUDED +#define DYNAMIC_ARRAY_INCLUDED 1 + + +# ifndef TYPE +# define TYPE double +# define TYPE_SIZE sizeof(double) +# endif + +# ifndef EQ +# define EQ(A, B) (fabs(A - B) < 10e-7) +# endif + +typedef struct DynArr DynArr; + +/* Dynamic Array Functions */ +DynArr *createDynArr(int cap); +void deleteDynArr(DynArr *v); + +int sizeDynArr(DynArr *v); + +void addDynArr(DynArr *v, TYPE val); +TYPE getDynArr(DynArr *v, int pos); +void putDynArr(DynArr *v, int pos, TYPE val); +void swapDynArr(DynArr *v, int i, int j); +void removeAtDynArr(DynArr *v, int idx); + +/* Stack interface. */ +int isEmptyDynArr(DynArr *v); +void pushDynArr(DynArr *v, TYPE val); +TYPE topDynArr(DynArr *v); +void popDynArr(DynArr *v); + +/* Bag Interface */ +int containsDynArr(DynArr *v, TYPE val); +void removeDynArr(DynArr *v, TYPE val); + +#endif diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 2/makefile b/OSU Coursework/CS 261 - Data Structures/Assignment 2/makefile new file mode 100644 index 0000000..b6a6cc5 --- /dev/null +++ b/OSU Coursework/CS 261 - Data Structures/Assignment 2/makefile @@ -0,0 +1,23 @@ +all: calc testda + +calc: dynamicArray.o calc.o + gcc -g -Wall -std=c99 -o calc dynamicArray.o calc.o -lm + +testda: dynamicArray.o testDynArray.o + gcc -g -Wall -std=c99 -o testda dynamicArray.o testDynArray.o + +calc.o: calc.c dynamicArray.h + gcc -g -Wall -std=c99 -c calc.c + +testDynArray.o: testDynArray.c dynamicArray.h + gcc -g -Wall -std=c99 -c testDynArray.c + +dynamicArray.o: dynamicArray.c dynamicArray.h + gcc -g -Wall -std=c99 -c dynamicArray.c + +clean: + rm dynamicArray.o + rm calc.o + rm testDynArray.o + rm calc + rm testda diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 2/testDynArray.c b/OSU Coursework/CS 261 - Data Structures/Assignment 2/testDynArray.c new file mode 100644 index 0000000..d0907e7 --- /dev/null +++ b/OSU Coursework/CS 261 - Data Structures/Assignment 2/testDynArray.c @@ -0,0 +1,87 @@ +/* testDynArray.c + * This file is used for testing the dynamicArray.c file. + * This test suite is by no means complete or thorough. + * More testing is needed on your own. + */ +#include +#include +#include "dynamicArray.h" + + +void assertTrue(int predicate, char *message) +{ + printf("%s: ", message); + if (predicate) + printf("PASSED\n"); + else + printf("FAILED\n"); +} + + +// this main function contains some +int main(int argc, char* argv[]){ + + DynArr *dyn; + dyn = createDynArr(2); + + printf("\n\nTesting addDynArr...\n"); + addDynArr(dyn, 3); + addDynArr(dyn, 4); + addDynArr(dyn, 10); + addDynArr(dyn, 5); + addDynArr(dyn, 6); + + printf("The array's content: [3,4,10,5,6]\n"); + assertTrue(EQ(getDynArr(dyn, 0), 3), "Test 1st element == 3"); + assertTrue(EQ(getDynArr(dyn, 1), 4), "Test 2nd element == 4"); + assertTrue(EQ(getDynArr(dyn, 2), 10), "Test 3rd element == 10"); + assertTrue(EQ(getDynArr(dyn, 3), 5), "Test 4th element == 5"); + assertTrue(EQ(getDynArr(dyn, 4), 6), "Test 5th element == 6"); + assertTrue(sizeDynArr(dyn) == 5, "Test size = 5"); + + printf("\n\nTesting putDynArr...\nCalling putDynArr(dyn, 2, 7)\n"); + putDynArr(dyn, 2, 7); + printf("The array's content: [3,4,7,5,6]\n"); + assertTrue(EQ(getDynArr(dyn, 2), 7), "Test 3rd element == 7"); + assertTrue(sizeDynArr(dyn) == 5, "Test size = 5"); + + printf("\n\nTesting swapDynArr...\nCalling swapDynArr(dyn, 2, 4)\n"); + swapDynArr(dyn, 2, 4); + printf("The array's content: [3,4,6,5,7]\n"); + assertTrue(EQ(getDynArr(dyn, 2), 6), "Test 3rd element == 6"); + assertTrue(EQ(getDynArr(dyn, 4), 7), "Test 5th element == 7"); + + printf("\n\nTesting removeAtDynArr...\nCalling removeAtDynArr(dyn, 1)\n"); + removeAtDynArr(dyn, 1); + printf("The array's content: [3,6,5,7]\n"); + assertTrue(EQ(getDynArr(dyn, 0), 3), "Test 1st element == 3"); + assertTrue(EQ(getDynArr(dyn, 3), 7), "Test 4th element == 7"); + assertTrue(sizeDynArr(dyn) == 4, "Test size = 4"); + + printf("\n\nTesting stack interface...\n"); + printf("The stack's content: [3,6,5,7] <- top\n"); + assertTrue(!isEmptyDynArr(dyn), "Testing isEmptyDynArr"); + assertTrue(EQ(topDynArr(dyn), 7), "Test topDynArr == 7"); + + popDynArr(dyn); + printf("Poping...\nThe stack's content: [3,6,5] <- top\n"); + assertTrue(EQ(topDynArr(dyn), 5), "Test topDynArr == 5"); + + pushDynArr(dyn, 9); + printf("Pushing 9...\nThe stack's content: [3,6,5,9] <- top\n"); + assertTrue(EQ(topDynArr(dyn), 9), "Test topDynArr == 9"); + + printf("\n\nTesting bag interface...\n"); + printf("The bag's content: [3,6,5,9]\n"); + assertTrue(containsDynArr(dyn, 3), "Test containing 3"); + assertTrue(containsDynArr(dyn, 6), "Test containing 6"); + assertTrue(containsDynArr(dyn, 5), "Test containing 5"); + assertTrue(containsDynArr(dyn, 9), "Test containing 9"); + assertTrue(!containsDynArr(dyn, 7), "Test not containing 7"); + + removeDynArr(dyn, 3); + printf("Removing 3...\nThe stack's content: [6,5,9]\n"); + assertTrue(!containsDynArr(dyn, 3), "Test not containing 3"); + + return 0; +} \ No newline at end of file diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 5/.cproject b/OSU Coursework/CS 261 - Data Structures/Assignment 5/.cproject new file mode 100644 index 0000000..8bb1489 --- /dev/null +++ b/OSU Coursework/CS 261 - Data Structures/Assignment 5/.cproject @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 5/.fuse_hidden00004383000000f5 b/OSU Coursework/CS 261 - Data Structures/Assignment 5/.fuse_hidden00004383000000f5 new file mode 100644 index 0000000..cfa1bc0 Binary files /dev/null and b/OSU Coursework/CS 261 - Data Structures/Assignment 5/.fuse_hidden00004383000000f5 differ diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 5/.project b/OSU Coursework/CS 261 - Data Structures/Assignment 5/.project new file mode 100644 index 0000000..4e73944 --- /dev/null +++ b/OSU Coursework/CS 261 - Data Structures/Assignment 5/.project @@ -0,0 +1,26 @@ + + + assign5 + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 5/Makefile b/OSU Coursework/CS 261 - Data Structures/Assignment 5/Makefile new file mode 100644 index 0000000..3ecb6b2 --- /dev/null +++ b/OSU Coursework/CS 261 - Data Structures/Assignment 5/Makefile @@ -0,0 +1,27 @@ +all: prog1 prog2 + +prog1: dynamicArray.o main.o toDoList.o + gcc -g -Wall -std=c99 -o prog1 dynamicArray.o toDoList.o main.o + +prog2: dynamicArray.o main2.o toDoList.o + gcc -g -Wall -std=c99 -o prog2 dynamicArray.o toDoList.o main2.o + +main.o: main.c dynamicArray.h type.h toDoList.h + gcc -g -Wall -std=c99 -c main.c + +main2.o: main2.c dynamicArray.h type.h toDoList.h + gcc -g -Wall -std=c99 -c main2.c + +dynamicArray.o: dynamicArray.c dynamicArray.h + gcc -g -Wall -std=c99 -c dynamicArray.c + +toDoList.o: toDoList.c toDoList.h + gcc -g -Wall -std=c99 -c toDoList.c + +clean: + rm dynamicArray.o + rm toDoList.o + rm main.o + rm main2.o + rm prog1 + rm prog2 diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 5/dynamicArray.c b/OSU Coursework/CS 261 - Data Structures/Assignment 5/dynamicArray.c new file mode 100644 index 0000000..5eebd7a --- /dev/null +++ b/OSU Coursework/CS 261 - Data Structures/Assignment 5/dynamicArray.c @@ -0,0 +1,572 @@ +/* dynArr.c: Dynamic Array implementation. */ +#include +#include +#include +#include "dynamicArray.h" + +struct DynArr +{ + TYPE *data; /* pointer to the data array */ + int size; /* Number of elements in the array */ + int capacity; /* capacity ofthe array */ +}; + +struct bag +{ + struct DynArr *dynArr; +}; + + +/* ************************************************************************ + Dynamic Array Functions +************************************************************************ */ + +/* Initialize (including allocation of data array) dynamic array. + + param: v pointer to the dynamic array + param: cap capacity of the dynamic array + pre: v is not null + post: internal data array can hold capacity elements + post: v->data is not null +*/ +void _initDynArr(DynArr *v, int capacity) +{ + assert(capacity > 0); + assert(v!= 0); + v->data = malloc(sizeof(TYPE) * capacity); + assert(v->data != 0); + v->size = 0; + v->capacity = capacity; + +} + +/* Allocate and initialize dynamic array. + + param: cap desired capacity for the dyn array + pre: none + post: none + ret: a non-null pointer to a dynArr of cap capacity + and 0 elements in it. +*/ +DynArr* createDynArr(int cap) +{ + DynArr *r; + assert(cap > 0); + r = malloc(sizeof( DynArr)); + assert(r != 0); + _initDynArr(r,cap); + return r; +} + +/* Deallocate data array in dynamic array. + + param: v pointer to the dynamic array + pre: v is not null + post: d.data points to null + post: size and capacity are 0 + post: the memory used by v->data is freed +*/ +void freeDynArr(DynArr *v) +{ + assert(v!=0); + + if(v->data != 0) + { + free(v->data); /* free the space on the heap */ + v->data = 0; /* make it point to null */ + } + v->size = 0; + v->capacity = 0; +} + +/* Deallocate data array and the dynamic array ure. + + param: v pointer to the dynamic array + pre: v is not null + post: the memory used by v->data is freed + post: the memory used by d is freed +*/ +void deleteDynArr(DynArr *v) +{ + assert (v!= 0); + freeDynArr(v); + free(v); +} + +/* Resizes the underlying array to be the size cap + + param: v pointer to the dynamic array + param: cap the new desired capacity + pre: v is not null + post: v has capacity newCap +*/ +void _dynArrSetCapacity(DynArr *v, int newCap) +{ + int i; + TYPE *oldData; + int oldSize = v->size; + oldData = v->data; + + printf("========Resizing========\n"); + /* Create a new dyn array with larger underlying array */ + _initDynArr(v, newCap); + + for(i = 0; i < oldSize; i++){ + v->data[i] = oldData[i]; + } + + v->size = oldSize; + /* Remember, init did not free the original data */ + free(oldData); + +#ifdef ALTERNATIVE + int i; + + /* Create a new underlying array*/ + TYPE *newData = (TYPE*)malloc(sizeof(TYPE)*newCap); + assert(newData != 0); + + /* copy elements to it */ + + for(i = 0; i < v->size; i++) + { + newData[i] = v->data[i]; + } + + /* Delete the oldunderlying array*/ + free(v->data); + /* update capacity and size and data*/ + v->data = newData; + v->capacity = newCap;struct Task { + char description[TASK_DESC_SIZE]; /* description of the task */ + int priority; /* task priority */ + }; +#endif +} + +/* Get the size of the dynamic array + + param: v pointer to the dynamic array + pre: v is not null + post: none + ret: the size of the dynamic array +*/ +int sizeDynArr(DynArr *v) +{ + assert(v!=0); + return v->size; +} + +/* Adds an element to the end of the dynamic array + + param: v pointer to the dynamic array + param: val the value to add to the end of the dynamic array + pre: the dynArry is not null + post: size increases by 1 + post: if reached capacity, capacity is doubled + post: val is in the last utilized position in the array +*/ +void addDynArr(DynArr *v, TYPE val) +{ + + assert(v!=0); + + /* Check to see if a resize is necessary */ + if(v->size >= v->capacity) + _dynArrSetCapacity(v, 2 * v->capacity); + + v->data[v->size] = val; + v->size++; + +} + +/* Get an element from the dynamic array from a specified position + + param: v pointer to the dynamic array + param: pos integer index to get the element from + pre: v is not null + pre: v is not empty + pre: pos < size of the dyn array and >= 0 + post: no changes to the dyn Array + ret: value stored at index pos +*/ +TYPE getDynArr(DynArr *v, int pos) +{ + assert(v!=0); + assert(pos < v->size); + assert(pos >= 0); + + return v->data[pos]; +} + +/* Put an item into the dynamic array at the specified location, + overwriting the element that was there + + param: v pointer to the dynamic array + param: pos the index to put the value into + param: val the value to insert + pre: v is not null + pre: v is not empty + pre: pos >= 0 and pos < size of the array + post: index pos contains new value, val +*/ +void putDynArr(DynArr *v, int pos, TYPE val) +{ + assert(v!=0); + assert(pos < v->size); + assert(pos >= 0); + v->data[pos] = val; +} + +/* Swap two specified elements in the dynamic array + + param: v pointer to the dynamic array + param: i,j the elements to be swapped + pre: v is not null + pre: v is not empty + pre: i, j >= 0 and i,j < size of the dynamic array + post: index i now holds the value at j and index j now holds the value at i +*/ +void swapDynArr(DynArr *v, int i, int j) +{ + TYPE temp; + assert(v!=0); + assert(i < v->size); + assert(j < v->size); + assert(i >= 0); + assert(j >= 0); + + temp = v->data[i]; + v->data[i] = v->data[j]; + v->data[j] = temp; + +} + +/* Remove the element at the specified location from the array, + shifts other elements back one to fill the gap + + param: v pointer to the dynamic array + param: idx location of element to remove + pre: v is not null + pre: v is not empty + pre: idx < size and idx >= 0 + post: the element at idx is removed + post: the elements past idx are moved back one +*/ +void removeAtDynArr(DynArr *v, int idx){ + int i; + assert(v!= 0); + assert(idx < v->size); + assert(idx >= 0); + + //Move all elements up + + for(i = idx; i < v->size-1; i++){ + v->data[i] = v->data[i+1]; + } + + v->size--; + +} + + + +/* ************************************************************************ + Stack Interface Functions +************************************************************************ */ + +/* Returns boolean (encoded in an int) demonstrating whether or not the + dynamic array stack has an item on it. + + param: v pointer to the dynamic array + pre: v is not null + post: none + ret: >0 if empty, otherwise 0 +*/ +int isEmptyDynArr(DynArr *v) +{ + assert(v!= 0); + return !(v->size); + /* alternatively: + + if(v->size == 0) + return 1; + else return 0; + + */ + + + +} + +/* Push an element onto the top of the stack + + param: v pointer to the dynamic array + param: val the value to push onto the stack + pre: v is not null + post: size increases by 1 + if reached capacity, capacity is doubled + val is on the top of the stack +*/ +void pushDynArr(DynArr *v, TYPE val) +{ + assert(v!=0); + addDynArr(v, val); +} + +/* Returns the element at the top of the stack + + param: v pointer to the dynamic array + pre: v is not null + pre: v is not empty + post: no changes to the stack +*/ +TYPE topDynArr(DynArr *v) +{ + assert(v!=0); + assert(!isEmptyDynArr(v)); + return v->data[v->size-1]; +} + +/* Removes the element on top of the stack + + param: v pointer to the dynamic array + pre: v is not null + pre: v is not empty + post: size is decremented by 1 + the top has been removed +*/ +void popDynArr(DynArr *v) +{ + assert(v!=0); + assert(! isEmptyDynArr(v)); + v->size--; +} + +/* ************************************************************************ + Bag Interface Functions +************************************************************************ */ + +/* Returns boolean (encoded as an int) demonstrating whether or not + the specified value is in the collection + true = 1 + false = 0 + + param: v pointer to the dynamic array + param: val the value to look for in the bag + pre: v is not null + pre: v is not empty + post: no changes to the bag +*/ +int containsDynArr(DynArr *v, TYPE val) +{ + int i = 0; + + assert(v!=0); + assert(!isEmptyDynArr(v)); + + for(i = 0; i < sizeDynArr(v); i++) + if(compare(v->data[i], val) == 0) + return 1; + return 0; + +} + +/* Removes the first occurrence of the specified value from the collection + if it occurs + + param: v pointer to the dynamic array + param: val the value to remove from the array + pre: v is not null + pre: v is not empty + post: val has been removed + post: size of the bag is reduced by 1 +*/ +void removeDynArr(DynArr *v, TYPE val) +{ + int i = 0; + assert(v!=0); + assert(!isEmptyDynArr(v)); + assert(containsDynArr(v,val)); /* Design decision: Error if they try to remove something not in there! */ + + for(i = 0; i < sizeDynArr(v); i++) + if(compare(v->data[i], val) == 0) + { + removeAtDynArr(v,i); + break; + } +} + +/* Copy elements from a dynamic array to another dynamic array + + param: source pointer to the source dynamic array + param: destination pointer to the destination dynamic array + pre: s is not null and s is not empty + post: destination is initialized + post: the elements from source are copied to destination +*/ +void copyDynArr(DynArr *source, DynArr *destination) +{ + int i; + assert(source->size > 0); + _initDynArr(destination, source->capacity); + /* copy elements to destination array */ + for(i = 0; i < source->size; i++) + destination->data[i] = source->data[i]; + + destination->size = source->size; +} + + +/* ************************************************************************ + Heap-based Priority Queue Implementation +************************************************************************ */ + +/* internal function prototypes */ +int _smallerIndexHeap(DynArr *heap, int i, int j); +void _adjustHeap(DynArr *heap, int max, int pos); + +/* Get the index of the smaller node between two nodes in a heap + + param: heap pointer to the heap + param: i index of one node + param: j index of other node + pre: i < size and j < size + ret: the index of the smaller node +*/ +int _smallerIndexHeap(DynArr *heap, int i, int j) +{ + /* FIXME */ + /* DONE */ + assert(i < heap->size); + assert(j < heap->size); + if(((struct Task*)heap->data[i])->priority > ((struct Task*)heap->data[j])->priority){ + return j; + }else{ + return i; + } +} + +/* Get the first node, which has the min priority, from the heap + + param: heap pointer to the heap + pre: heap is not empty + ret: value of first node +*/ +TYPE getMinHeap(DynArr *heap) +{ + /* FIXME */ + /* DONE */ + assert(heap != 0); + return heap->data[0]; +} + +/* Add a node to the heap + + param: heap pointer to the heap + param: node node to be added to the heap + pre: heap is not null + post: node is added to the heap +*/ +void addHeap(DynArr *heap, TYPE val) +{ + /* FIXME */ + /* DONE */ + int pos; + int parent; + assert(heap != 0); + addDynArr(heap, val); + pos = sizeDynArr(heap)-1; + while(pos != 0){ + parent = (pos -1)/2; + if(((struct Task*)heap->data[pos])->priority < ((struct Task*)heap->data[parent])->priority){ + swapDynArr(heap, pos, parent); + pos = parent; + }else{ + return; + } + } +} + +/* Adjust heap to maintain heap property + + param: heap pointer to the heap + param: max index to adjust up to (but not included) + param: pos position index where the adjustment starts + pre: max <= size + post: heap property is maintained for nodes from index pos to index max-1 (ie. up to, but not including max) +*/ +void _adjustHeap(DynArr *heap, int max, int pos) +{ + /* FIXME */ + /* DONE */ + int leftChild = 2*pos + 1; + int rightChild = 2*pos + 2; + + if(rightChild < max){ + int smallestindex = _smallerIndexHeap(heap, leftChild, rightChild); + if(((struct Task*)heap->data[pos])->priority > ((struct Task*)heap->data[smallestindex])->priority){ + swapDynArr(heap, pos, smallestindex); + _adjustHeap(heap, max, smallestindex); + } + }else if(leftChild < max){ + if(((struct Task*)heap->data[pos])->priority > ((struct Task*)heap->data[leftChild])->priority){ + swapDynArr(heap, pos, leftChild); + _adjustHeap(heap, max, leftChild); + } + } +} + +/* Remove the first node, which has the min priority, from the heap + + param: heap pointer to the heap + pre: heap is not empty + post: the first node is removed from the heap +*/ +void removeMinHeap(DynArr *heap) +{ + /* FIXME */ + /* DONE */ + int last = sizeDynArr(heap)-1; + //assert(last !=0); + putDynArr(heap, 0, getDynArr(heap, last)); + removeAtDynArr(heap, last); + _adjustHeap(heap, last, 0); +} + +/* builds a heap from an arbitrary dynArray + + param: v dynamicArray + pre: v is not empty + post: v is a proper heap +*/ + +void _buildHeap(DynArr *heap) +{ + /* FIXME */ + /* DONE */ + int max = sizeDynArr(heap); + for(int i = max/2 -1 ; i >=0 ; i--){ + _adjustHeap(heap, max, i); + } +} +/* + In-place sort of the heap + + param: heap pointer to the heap + pre: heap is not empty + post: the dynArr is in reverse sorted order +*/ + +void sortHeap(DynArr *heap) +{ + /* FIXME */ + /* DONE */ + _buildHeap(heap); + for(int i = sizeDynArr(heap)-1 ; i > 0 ; i--){ + swapDynArr(heap, 0, i); + _adjustHeap(heap, i, 0); + } + +} + diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 5/dynamicArray.h b/OSU Coursework/CS 261 - Data Structures/Assignment 5/dynamicArray.h new file mode 100644 index 0000000..5728a64 --- /dev/null +++ b/OSU Coursework/CS 261 - Data Structures/Assignment 5/dynamicArray.h @@ -0,0 +1,52 @@ +/* dynArr.h : Dynamic Array implementation. */ +#ifndef DYNAMIC_ARRAY_INCLUDED +#define DYNAMIC_ARRAY_INCLUDED 1 +#include "type.h" + +# ifndef TYPE +# define TYPE void* +# endif + +/* function used to compare two TYPE values to each other, define this in your compare.c file */ +int compare(TYPE left, TYPE right); +/* function used to print TYPE values, define this in your compare.c file */ +void print_type(TYPE curval); + +typedef struct DynArr DynArr; +struct bag; + +/* Dynamic Array Functions */ +DynArr *createDynArr(int cap); +void deleteDynArr(DynArr *v); + +int sizeDynArr(DynArr *v); + +void addDynArr(DynArr *v, TYPE val); +TYPE getDynArr(DynArr *v, int pos); +void putDynArr(DynArr *v, int pos, TYPE val); +void swapDynArr(DynArr *v, int i, int j); +void removeAtDynArr(DynArr *v, int idx); + +/* Stack interface. */ +int isEmptyDynArr(DynArr *v); +void pushDynArr(DynArr *v, TYPE val); +TYPE topDynArr(DynArr *v); +void popDynArr(DynArr *v); + +/* Bag Interface */ +int containsDynArr(DynArr *v, TYPE val); +void removeDynArr(DynArr *v, TYPE val); + + +/* Heap-based Priority Queue Interface */ +TYPE getMinHeap(DynArr *heap); +void addHeap(DynArr *heap, TYPE node); +void removeMinHeap(DynArr *heap); +void sortHeap(DynArr *heap); + + +/* Utility function*/ +void copyDynArr(DynArr *source, DynArr *destination); + + +#endif diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 5/dynamicArray.o b/OSU Coursework/CS 261 - Data Structures/Assignment 5/dynamicArray.o new file mode 100644 index 0000000..1a6d7a3 Binary files /dev/null and b/OSU Coursework/CS 261 - Data Structures/Assignment 5/dynamicArray.o differ diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 5/main.c b/OSU Coursework/CS 261 - Data Structures/Assignment 5/main.c new file mode 100644 index 0000000..5c8e0fb --- /dev/null +++ b/OSU Coursework/CS 261 - Data Structures/Assignment 5/main.c @@ -0,0 +1,164 @@ +#include +#include +#include +#include +#include "toDoList.h" + +int main (int argc, const char * argv[]) +{ + Task* newTask; + Task* firstTask; + char desc[TASK_DESC_SIZE], filename[50], *nlptr; + int priority; + char cmd = ' '; + FILE *filePointer; + DynArr* mainList = createDynArr(10); + + printf("\n\n** TO-DO LIST APPLICATION **\n\n"); + + do + { + printf("Press:\n" + "'l' to load to-do list from a file\n" + "'s' to save to-do list to a file\n" + "'a' to add a new task\n" + "'g' to get the first task\n" + "'r' to remove the first task\n" + "'p' to print the list\n" + "'e' to exit the program\n" + ); + /* get input command (from the keyboard) */ + cmd = getchar(); + /* clear the trailing newline character */ + while (getchar() != '\n'); + + switch (cmd) + { + case 'a': /* add new task */ + printf("Please enter the task description: "); + /* get task description from user input (from keyboard) */ + if (fgets(desc, sizeof(desc), stdin) != NULL) + { + /* remove trailing newline character */ + nlptr = strchr(desc, '\n'); + if (nlptr) + *nlptr = '\0'; + } + /* get task priority from user input (from keyboard) */ + do { + printf("Please enter the task priority (0-999): "); + scanf("%d", &priority); + } while(!(priority >= 0 && priority <= 999)); + + /* clear the trailing newline character */ + while (getchar() != '\n'); + + /* create task and add the task to the heap */ + newTask = createTask(priority, desc); + addHeap(mainList, newTask); + printf("The task '%s' has been added to your to-do list.\n\n", desc); + break; + + case 'g': /* get the first task */ + if (sizeDynArr(mainList) > 0) + { + firstTask = (Task*)getMinHeap(mainList); + printf("Your first task is: %s\n\n", firstTask->description); + } + else + printf("Your to-do list is empty!\n\n"); + + break; + + case 'r': /* remove the first task */ + if (sizeDynArr(mainList) > 0) + { + firstTask = (Task*)getMinHeap(mainList); + removeMinHeap(mainList); + printf("Your first task '%s' has been removed from the list.\n\n", firstTask->description); + /* need to free up memory occupied by this task */ + free(firstTask); + } + else + printf("Your to-do list is empty!\n\n"); + + break; + + case 'p': /* print the list */ + if (sizeDynArr(mainList) > 0) + { + printList(mainList); + } + else + printf("Your to-do list is empty!\n\n"); + + break; + + + case 's': /* save the list to file */ + if (sizeDynArr(mainList) > 0) + { + /* get filename from user input (from keyboard) */ + printf("Please enter the filename: "); + if (fgets(filename, sizeof(filename), stdin) != NULL) + { + /* remove trailing newline character */ + nlptr = strchr(filename, '\n'); + if (nlptr) + *nlptr = '\0'; + } + /* open the file */ + filePointer = fopen(filename, "w"); + if (filePointer == NULL) { + fprintf(stderr, "Cannot open %s\n", filename); + break; + } + /* save the list to the file */ + saveList(mainList, filePointer); + /* close the file */ + fclose(filePointer); + printf("The list has been saved into the file successfully.\n\n"); + } + else + printf("Your to-do list is empty!\n\n"); + + break; + + case 'l': /* load the list from the file */ + printf("Please enter the filename: "); + /* get filename from user input (from keyboard) */ + if (fgets(filename, sizeof(filename), stdin) != NULL) + { + /* remove trailing newline character */ + nlptr = strchr(filename, '\n'); + if (nlptr) + *nlptr = '\0'; + } + /* open the file */ + filePointer = fopen(filename, "r"); + if (filePointer == NULL) { + fprintf(stderr, "Cannot open %s\n", filename); + break; + } + /* load the list from the file */ + loadList(mainList, filePointer); + /* close the file */ + fclose(filePointer); + printf("The list has been loaded from file successfully.\n\n"); + break; + + case 'e': /* exit the program */ + printf("Bye!\n\n"); + break; + + default: + printf("What is your command anyway?\n\n" ); + break; + } + } + while(cmd != 'e'); + /* delete the list */ + deleteList(mainList); + + return 0; +} diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 5/main.o b/OSU Coursework/CS 261 - Data Structures/Assignment 5/main.o new file mode 100644 index 0000000..67c1c87 Binary files /dev/null and b/OSU Coursework/CS 261 - Data Structures/Assignment 5/main.o differ diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 5/main2.c b/OSU Coursework/CS 261 - Data Structures/Assignment 5/main2.c new file mode 100644 index 0000000..b8ff87b --- /dev/null +++ b/OSU Coursework/CS 261 - Data Structures/Assignment 5/main2.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include "dynamicArray.h" +#include "toDoList.h" + +/* NOTE: Switch between TESTSORT and TESTHEAP to test either the heap sort algoritm or the heap operations*/ +#define TESTHEAP + +int main(int argc, const char * argv[]) +{ + Task *task1, *task2, *task3, *task4, *task5, *task6, *task7, *task8, *task9, *task10; + DynArr *mainList; + int i; + mainList = createDynArr(10); + + /* create tasks */ + task1 = createTask(9, "task 1"); + task2 = createTask(3, "task 2"); + task3 = createTask(2, "task 3"); + task4 = createTask(4, "task 4"); + task5 = createTask(5, "task 5"); + task6 = createTask(7, "task 6"); + task7 = createTask(8, "task 7"); + task8 = createTask(6, "task 8"); + task9 = createTask(1, "task 9"); + task10 = createTask(0, "task 10"); + + /* add tasks to the dynamic array */ + addHeap(mainList, task1); + addHeap(mainList, task2); + addHeap(mainList, task3); + addHeap(mainList, task4); + addHeap(mainList, task5); + addHeap(mainList, task6); + addHeap(mainList, task7); + addHeap(mainList, task8); + addHeap(mainList, task9); + addHeap(mainList, task10); + +#ifdef TESTHEAP + for(i = 0; i < sizeDynArr(mainList);i++) + printf("DynArr[%d] = %d\n", i, ((Task*)getDynArr(mainList,i))->priority); + + + while(!isEmptyDynArr(mainList)) + { + Task* v; + v = getMinHeap(mainList); + printf("Val = %s___%d\n", v->description, v->priority); + removeMinHeap(mainList); + } +#endif + +#ifdef TESTSORT + + printf("Before Sort Called \n"); + for(i = 0; i < sizeDynArr(mainList);i++) + printf("DynArr[%d] = %d\n", i, ((Task*)getDynArr(mainList,i))->priority); + + + /* sort tasks */ + sortHeap(mainList); + printf("After Sort Called \n"); + + /* print sorted tasks from the dynamic array */ + for(i = 0; i < sizeDynArr(mainList);i++) + printf("DynArr[%d] = %d\n", i, ((Task*)getDynArr(mainList,i))->priority); + + return 0; + +#endif +} diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 5/main2.o b/OSU Coursework/CS 261 - Data Structures/Assignment 5/main2.o new file mode 100644 index 0000000..5959d2b Binary files /dev/null and b/OSU Coursework/CS 261 - Data Structures/Assignment 5/main2.o differ diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 5/prog1 b/OSU Coursework/CS 261 - Data Structures/Assignment 5/prog1 new file mode 100644 index 0000000..3e4ae94 Binary files /dev/null and b/OSU Coursework/CS 261 - Data Structures/Assignment 5/prog1 differ diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 5/prog2 b/OSU Coursework/CS 261 - Data Structures/Assignment 5/prog2 new file mode 100644 index 0000000..27c4494 Binary files /dev/null and b/OSU Coursework/CS 261 - Data Structures/Assignment 5/prog2 differ diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 5/program_demo.txt b/OSU Coursework/CS 261 - Data Structures/Assignment 5/program_demo.txt new file mode 100644 index 0000000..7197f6f --- /dev/null +++ b/OSU Coursework/CS 261 - Data Structures/Assignment 5/program_demo.txt @@ -0,0 +1,223 @@ +flip ~/cs261/as5/todo_list 605% ./prog + + +** TO-DO LIST APPLICATION ** + +Press: +'l' to load to-do list from a file +'s' to save to-do list to a file +'a' to add a new task +'g' to get the first task +'r' to remove the first task +'p' to print the list +'e' to exit the program +g +Your to-do list is empty! + +Press: +'l' to load to-do list from a file +'s' to save to-do list to a file +'a' to add a new task +'g' to get the first task +'r' to remove the first task +'p' to print the list +'e' to exit the program +a +Please enter the task description: do assignment 5 +Please enter the task priority (0-999): 3 +The task 'do assignment 5' has been added to your to-do list. + +Press: +'l' to load to-do list from a file +'s' to save to-do list to a file +'a' to add a new task +'g' to get the first task +'r' to remove the first task +'p' to print the list +'e' to exit the program +a +Please enter the task description: study heap-based priority queue +Please enter the task priority (0-999): 1 +The task 'study heap-based priority queue' has been added to your to-do list. + +Press: +'l' to load to-do list from a file +'s' to save to-do list to a file +'a' to add a new task +'g' to get the first task +'r' to remove the first task +'p' to print the list +'e' to exit the program +a +Please enter the task description: review trees for Final exam +Please enter the task priority (0-999): 101 +The task 'review trees for Final exam' has been added to your to-do list. + +Press: +'l' to load to-do list from a file +'s' to save to-do list to a file +'a' to add a new task +'g' to get the first task +'r' to remove the first task +'p' to print the list +'e' to exit the program +g +Your first task is: study heap-based priority queue + +Press: +'l' to load to-do list from a file +'s' to save to-do list to a file +'a' to add a new task +'g' to get the first task +'r' to remove the first task +'p' to print the list +'e' to exit the program +a +Please enter the task description: take a nap +Please enter the task priority (0-999): 0 +The task 'take a nap' has been added to your to-do list. + +Press: +'l' to load to-do list from a file +'s' to save to-do list to a file +'a' to add a new task +'g' to get the first task +'r' to remove the first task +'p' to print the list +'e' to exit the program +s +Please enter the filename: todo.txt +The list has been saved into the file successfully. + +Press: +'l' to load to-do list from a file +'s' to save to-do list to a file +'a' to add a new task +'g' to get the first task +'r' to remove the first task +'p' to print the list +'e' to exit the program +e +Bye! + +============ + +flip ~/cs261/as5/todo_list 613% ./prog + + +** TO-DO LIST APPLICATION ** + +Press: +'l' to load to-do list from a file +'s' to save to-do list to a file +'a' to add a new task +'g' to get the first task +'r' to remove the first task +'p' to print the list +'e' to exit the program +g +Your to-do list is empty! + +Press: +'l' to load to-do list from a file +'s' to save to-do list to a file +'a' to add a new task +'g' to get the first task +'r' to remove the first task +'p' to print the list +'e' to exit the program +l +Please enter the filename: todo.txt +The list has been loaded from file successfully. + +Press: +'l' to load to-do list from a file +'s' to save to-do list to a file +'a' to add a new task +'g' to get the first task +'r' to remove the first task +'p' to print the list +'e' to exit the program +g +Your first task is: take a nap + +Press: +'l' to load to-do list from a file +'s' to save to-do list to a file +'a' to add a new task +'g' to get the first task +'r' to remove the first task +'p' to print the list +'e' to exit the program +r +Your first task 'take a nap' has been removed from the list. + +Press: +'l' to load to-do list from a file +'s' to save to-do list to a file +'a' to add a new task +'g' to get the first task +'r' to remove the first task +'p' to print the list +'e' to exit the program +p +study heap-based priority queue + +do assignment 5 + +review trees for Final exam + +Press: +'l' to load to-do list from a file +'s' to save to-do list to a file +'a' to add a new task +'g' to get the first task +'r' to remove the first task +'p' to print the list +'e' to exit the program +r +Your first task 'study heap-based priority queue' has been removed from the list. + +Press: +'l' to load to-do list from a file +'s' to save to-do list to a file +'a' to add a new task +'g' to get the first task +'r' to remove the first task +'p' to print the list +'e' to exit the program +r +Your first task 'do assignment 5' has been removed from the list. + +Press: +'l' to load to-do list from a file +'s' to save to-do list to a file +'a' to add a new task +'g' to get the first task +'r' to remove the first task +'p' to print the list +'e' to exit the program +r +Your first task 'review trees for Final exam' has been removed from the list. + +Press: +'l' to load to-do list from a file +'s' to save to-do list to a file +'a' to add a new task +'g' to get the first task +'r' to remove the first task +'p' to print the list +'e' to exit the program +r +Your to-do list is empty! + +Press: +'l' to load to-do list from a file +'s' to save to-do list to a file +'a' to add a new task +'g' to get the first task +'r' to remove the first task +'p' to print the list +'e' to exit the program +e +Bye! diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 5/toDoList.c b/OSU Coursework/CS 261 - Data Structures/Assignment 5/toDoList.c new file mode 100644 index 0000000..97dc381 --- /dev/null +++ b/OSU Coursework/CS 261 - Data Structures/Assignment 5/toDoList.c @@ -0,0 +1,180 @@ +#include +#include +#include +#include +#include "toDoList.h" + + +/* Create a task from the description and the priority + + param: priority priority of the task + param: desc pointer to the description string + pre: none + post: none + ret: a task with description and priority +*/ +Task* createTask (int priority, char *desc) +{ + /* FIXME */ + /* DONE */ + struct Task *temp = malloc(sizeof(struct Task)); + strcpy(temp->description, desc); + temp->priority = priority; + return temp; +} + +/* Save the list to a file + + param: heap pointer to the list + param: filePtr pointer to the file to which the list is saved + pre: The list is not empty + post: The list is saved to the file in tab-delimited format. + Each line in the file stores a task, starting with the + task priority, followed by a tab character (\t), and + the task description. + + The tasks are not necessarily stored in the file in + priority order. + +*/ +void saveList(DynArr *heap, FILE *filePtr) +{ + int i; + Task* task; + assert(sizeDynArr(heap) > 0); + for(i = 0; i < sizeDynArr(heap); i++) + { + task = getDynArr(heap, i); + fprintf(filePtr, "%d\t%s\n", task->priority, task->description); + } +} + +/* Load the list from a file + + param: heap pointer to the list + param: filePtr pointer to the file + pre: none + post: The tasks are retrieved from the file and are added to the list. + Refer to the saveList() function for the format of tasks in the file +*/ +void loadList(DynArr *heap, FILE *filePtr) +{ + Task* task; + char line[100]; /* Assume lines < 100 */ + char desc[TASK_DESC_SIZE], *nlptr; + int priority; + + /* Read the priority first, then the description. + * fgets() is used to read string with spaces + */ +#ifdef NOTDEF + while (fscanf(filePtr, "%d\t", &priority) != EOF) + { + /* fgets() stops reading at \n character */ + fgets(desc, sizeof(desc), filePtr); + /* remove trailing newline character */ + nlptr = strchr(desc, '\n'); + if (nlptr) + *nlptr = '\0'; + + task = createTask(priority, desc); + addHeap(heap, task); + } +#endif + + while(fgets(line, sizeof(line), filePtr) != 0) + { + sscanf(line, "%d\t%[^\n]", &priority, desc); + task = createTask(priority, desc); + addHeap(heap, task); + } /* should use feof to make sure it found eof and not error*/ + +} + +/* Print the list + + param: heap pointer to the list + pre: the list is not empty + post: The tasks from the list are printed out in priority order. + The tasks are not removed from the list. +*/ +void printList(DynArr *heap) +{ + /* FIXME: Write this */ + /* DONE: May need adjustment */ + Task *temp; + + for(int i = 0 ; i < sizeDynArr(heap) ; i++){ + temp = (Task*)getDynArr(heap, i); + printf("Priority: %d\tDescription: %s\n", temp->priority, temp->description); + } +} + +/* Delete the list + + param: heap pointer to the list + post: The tasks from the list are removed and their occupied memories are freed + +*/ +void deleteList(DynArr *heap) +{ + + Task* task; + while(sizeDynArr(heap) > 0) + { + /* get the task */ + task = getMinHeap(heap); + /* remove the task */ + removeMinHeap(heap); + /* free the task */ + free(task); + } + /* free the heap */ + deleteDynArr(heap); +} + +/* Compare two tasks by priority + + param: left first task + param: right second task + pre: none + post: none + ret: -1 if priority of left < priority of right + 1 if priority of left > priority of right + 0 if priority of left = priority of right +*/ +/*Define this function, type casting the value of void * to the desired type. + The current definition of TYPE in dynamicArray.h is void*, which means that left and + right are void pointers. To compare left and right, you should first cast + left and right to the corresponding pointer type (struct Task*), and then + compare the values pointed by the casted pointers. + + DO NOT compare the addresses pointed by left and right, i.e. "if (left < right)", + which is really wrong. + */ +int compare(TYPE left, TYPE right) +{ + /*FIXME: write this*/ + /* DONE */ + struct Task *temp1 = (struct Task*)left; + struct Task *temp2 = (struct Task*)right; + + if(temp1->priority < temp2->priority){ + return -1; + }else if(temp1->priority > temp2->priority){ + return 1; + }else{ + return 0; + } +} + +/*Define this function, type casting the value of void * to the desired type*/ +void print_type(TYPE curval) +{ + /*FIXME: write this*/ + /* DONE */ + Task* data1; + data1 = (Task*)curval; + printf("Priority: %d\tDescription: %s\n", data1->priority, data1->description); +} + diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 5/toDoList.h b/OSU Coursework/CS 261 - Data Structures/Assignment 5/toDoList.h new file mode 100644 index 0000000..10d1ef2 --- /dev/null +++ b/OSU Coursework/CS 261 - Data Structures/Assignment 5/toDoList.h @@ -0,0 +1,17 @@ +#ifndef __TODOLIST_H +#define __TODOLIST_H + +#include "dynamicArray.h" +#include "type.h" + +Task* createTask (int priority, char *desc); + +void saveList(DynArr *heap, FILE *filePtr); + +void loadList(DynArr *heap, FILE *filePtr); + +void printList(DynArr *heap); + +void deleteList(DynArr *heap); + +#endif diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 5/toDoList.o b/OSU Coursework/CS 261 - Data Structures/Assignment 5/toDoList.o new file mode 100644 index 0000000..89a13e2 Binary files /dev/null and b/OSU Coursework/CS 261 - Data Structures/Assignment 5/toDoList.o differ diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 5/todo.txt b/OSU Coursework/CS 261 - Data Structures/Assignment 5/todo.txt new file mode 100644 index 0000000..eea6cdf --- /dev/null +++ b/OSU Coursework/CS 261 - Data Structures/Assignment 5/todo.txt @@ -0,0 +1,3 @@ +1 pet kitty +101 review trees for Midterm 2 +3 do assignment 5 diff --git a/OSU Coursework/CS 261 - Data Structures/Assignment 5/type.h b/OSU Coursework/CS 261 - Data Structures/Assignment 5/type.h new file mode 100644 index 0000000..ec78957 --- /dev/null +++ b/OSU Coursework/CS 261 - Data Structures/Assignment 5/type.h @@ -0,0 +1,16 @@ +/* You can modify the structure to store whatever you'd like in your dynamic array. +We define struct Task for the to-do list application in this example */ + +#ifndef __TYPE_H +#define __TYPE_H + +#define TASK_DESC_SIZE 128 + +struct Task { + char description[TASK_DESC_SIZE]; /* description of the task */ + int priority; /* task priority */ +}; + +typedef struct Task Task; + +#endif diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/ASM_Project.exe b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/ASM_Project.exe new file mode 100644 index 0000000..b732577 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/ASM_Project.exe differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/Assignment1.sdf b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/Assignment1.sdf new file mode 100644 index 0000000..1050693 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/Assignment1.sdf differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/Assignment1.sln b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/Assignment1.sln new file mode 100644 index 0000000..8fb02a9 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/Assignment1.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ASM_Project", "Assignment1.vcxproj", "{4164AA65-1EF9-4E69-899B-D1BED776070B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Debug|Win32.ActiveCfg = Debug|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Debug|Win32.Build.0 = Debug|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Release|Win32.ActiveCfg = Release|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/Assignment1.v12.suo b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/Assignment1.v12.suo new file mode 100644 index 0000000..9a4fc86 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/Assignment1.v12.suo differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/Assignment1.vcxproj b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/Assignment1.vcxproj new file mode 100644 index 0000000..ec0f08e --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/Assignment1.vcxproj @@ -0,0 +1,79 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + {4164AA65-1EF9-4E69-899B-D1BED776070B} + ASM_Project + + + + Application + v120 + + + Application + v120 + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + $(Configuration)\ + + + + c:\Irvine + + + user32.lib;irvine32.lib;%(AdditionalDependencies) + c:\Irvine;%(AdditionalLibraryDirectories) + true + Console + false + + + false + + + + + false + + + c:\Irvine;%(AdditionalLibraryDirectories) + Console + false + user32.lib;irvine32.lib;%(AdditionalDependencies) + + + c:\Irvine + + + + + + + \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/Assignment1.vcxproj.user b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/Assignment1.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/Assignment1.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/main.asm b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/main.asm new file mode 100644 index 0000000..9267cfc --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 1/main.asm @@ -0,0 +1,59 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +TITLE Assignment 1 (main.asm) +;Author: Corwin Perren +;Date: 1/19/2014 +;Description: +; This program will request two numbers from the user, perform common +; mathematical calculations on them, and print the results +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +INCLUDE Irvine32.inc +.data +ProgramTitle BYTE "CS 271 - Assignment 1",0dh,0ah,0 +CreatorName BYTE "Creator: Corwin Peren",0dh,0ah,0 + +Prompt1 BYTE "Please enter the first number: ",0 +Prompt2 BYTE "Please enter the second number: ",0 + +SumMessage BYTE "Sum: ",0 +DifMessage BYTE "Difference: ",0 +ProdMessage BYTE "Product: ",0 +QuotMessage BYTE "Quotient: ",0 +RemainMessage BYTE "Remainder: ",0 + +TermMessage BYTE "Computations Complete...",0dh,0ah,0 + +FirstNumber DWORD ? +SecondNumber DWORD ? + +FinalSum DWORD ? +FinalDif DWORD ? +FinalProd DWORD ? +FinalQuot DWORD ? +FinalRemain DWORD ? + + +.code + +NineToFive PROC uses EAX + mov eax, 9 + call WriteInt + mov eax, 8 + call WriteInt + mov eax, 7 + call WriteInt + mov eax, 6 + call WriteInt + mov eax, 5 + call WriteInt + + ret +NineToFive ENDP + +main PROC + + call NineToFive + exit +main ENDP + +END main \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 2/Assignement 2.sdf b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 2/Assignement 2.sdf new file mode 100644 index 0000000..72ad6c0 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 2/Assignement 2.sdf differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 2/Assignement 2.sln b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 2/Assignement 2.sln new file mode 100644 index 0000000..6e3145c --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 2/Assignement 2.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ASM_Project", "Assignement 2.vcxproj", "{4164AA65-1EF9-4E69-899B-D1BED776070B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Debug|Win32.ActiveCfg = Debug|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Debug|Win32.Build.0 = Debug|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Release|Win32.ActiveCfg = Release|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 2/Assignement 2.v12.suo b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 2/Assignement 2.v12.suo new file mode 100644 index 0000000..e12e504 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 2/Assignement 2.v12.suo differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 2/Assignement 2.vcxproj b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 2/Assignement 2.vcxproj new file mode 100644 index 0000000..ec0f08e --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 2/Assignement 2.vcxproj @@ -0,0 +1,79 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + {4164AA65-1EF9-4E69-899B-D1BED776070B} + ASM_Project + + + + Application + v120 + + + Application + v120 + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + $(Configuration)\ + + + + c:\Irvine + + + user32.lib;irvine32.lib;%(AdditionalDependencies) + c:\Irvine;%(AdditionalLibraryDirectories) + true + Console + false + + + false + + + + + false + + + c:\Irvine;%(AdditionalLibraryDirectories) + Console + false + user32.lib;irvine32.lib;%(AdditionalDependencies) + + + c:\Irvine + + + + + + + \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 2/Assignment 2.sln b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 2/Assignment 2.sln new file mode 100644 index 0000000..469d991 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 2/Assignment 2.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ASM_Project", "Project 2.vcxproj", "{4164AA65-1EF9-4E69-899B-D1BED776070B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Debug|Win32.ActiveCfg = Debug|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Debug|Win32.Build.0 = Debug|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Release|Win32.ActiveCfg = Release|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 2/main.asm b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 2/main.asm new file mode 100644 index 0000000..1f99ba6 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 2/main.asm @@ -0,0 +1,268 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +TITLE Assignment 2 (main.asm) +;Author: Corwin Perren +;Date: 1/28/2014 +;Description: +; This program will calculate and display the nth iteration of the fibonacci +; sequence for n values between 1 and 46 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +INCLUDE Irvine32.inc +.data +ProgramTitle BYTE "CS 271 - Assignment 2",0 +ProgrammersName BYTE "Programmed By: Corwin Perren",0 + +NamePrompt BYTE "By what name may I call you?",0 +NamePrompt2 BYTE "Your name: ", 0 + +NameResponse BYTE "Welcome, ", 0 +NameResponse2 BYTE ".", 0 + +FibPrompt BYTE "How many values of the fibonacci sequence would you like to calculate?", 0 +FibPrompt2 BYTE "Enter a value from 1 to 46: ", 0 +FibPromptIncorrect BYTE "Value was not between 1 and 46. Please try again.", 0 + +TabString BYTE 9, 0 +ExtraTab DWORD 1346269 + +TryAgainMessage BYTE "Would you like to run the program again?", 0 +TryAgainMessage2 BYTE "Answer (y/n): ", 0 + +IncorrectTryMessage BYTE "Please enter y or n....", 0 + +TermMessage BYTE "Goodbye, ", 0 +TermMessage2 BYTE ".", 0 + +FibMax DWORD 46 +FibMin DWORD 1 + +UserName BYTE 25 dup(0) +KeyAnswer BYTE 2 dup(0) +NumFib DWORD ? + +FibVal DWORD 1 +FibVal2 DWORD 1 + +CurCol DWORD 0 +ColMax DWORD 5 + +Yep BYTE "y", 0 +Nope BYTE "n", 0 + +.code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Simple procedure for printing a tab to the screen +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +InsertTab PROC + mov edx,OFFSET TabString ;Moves the tab character into the buffer + call WriteString ;Writes the tab to the screen + ret ;Returns out of the procedure +InsertTab ENDP + +main PROC + call Clrscr ;Clears the screen + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Write title and programmers name to screen + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov edx,OFFSET ProgramTitle ;Gets title ready to print + call WriteString ;Prints title + call Crlf ;Prints a new line + + mov edx,OFFSET ProgrammersName ;Gets programmers name ready to print + call WriteString ;Prints programmers name + call Crlf ;Prints newline + call Crlf ;Prints newline + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Prompt user for their name + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov edx,OFFSET NamePrompt ;Gets username prompt ready + call WriteString ;Prints username prompt + call Crlf ;Prints newline + + mov edx,OFFSET NamePrompt2 ;Gets second half of username prompt ready + call WriteString ;Prints username prompt part 2 + mov edx,OFFSET UserName ;Moves offset for username storage var into edx + mov ecx,SIZEOF UserName ;Sets max number of characters to read in + call ReadString ;Reads in username string from user + call Crlf ;Prints newline + call Crlf ;Prints newline + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Write user welcome message, with their name + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +DoAgain: + call Clrscr ;Clears the screen to clean up output + mov edx,OFFSET NameResponse ;Gets the welcome message part 1 ready to print + call WriteString ;Prints welcome message part 1 + mov edx,OFFSET UserName ;Gets username ready to print + call WriteString ;Prints username + mov edx,OFFSET NameResponse2 ;Gets welcome message part 2 redy to print + call WriteString ;Prints welcome message part 2 + call Crlf ;Prints a new line + call Crlf ;Prints a new line + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Prompt user for number of fibonacci to calculate + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov edx,OFFSET FibPrompt ;Gets prompt for fibonacci number ready + call WriteString ;Prints fib prompt + call Crlf ;Prints a new line + + jmp EnterNumber ;Jumps to enter number label to begin input + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;This prompt shows when the number enterred is not within 1 to 46 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IncorrectInput: + call Crlf ;Prints a new line + mov edx,OFFSET FibPromptIncorrect ;Gets incorrect range prompt ready to print + call WriteString ;Prints incorrect range prompt + call Crlf ;Prints a new line + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Main prompt and read-in of fibonacci value from user + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +EnterNumber: + mov edx,OFFSET FibPrompt2 ;Get main number entry prompt ready to print + call WriteString ;Prints main input prompt + call ReadInt ;Reads in int from user + + cmp eax, FibMin ;Checks if input is less than 1 + jl IncorrectInput ;Jumps to incorrect input if true + + cmp eax, FibMax ;Checks if input is greater than 46 + jg IncorrectInput ;Jumps to incorrect input if true + + mov NumFib, eax ;Copies number to variable if in correct range + call Crlf ;Prints a new line + + mov FibVal, 1 ;Reset fib start vals + mov FibVal2, 1 ;Reset fib start vals + mov CurCol, 0 ;Reset current column position + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;This section prints the first fibonacci sequence value + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov eax, FibVal ;Gets first value of fibonacci sequence ready to print (1) + call WriteInt ;Writes value to screen + cmp NumFib, 1 ;Checks if only this one value should be displayed + je FibDone ;If true, jump to end of program + inc CurCol ;Increment column index + call InsertTab ;Prints tab for column alignment + call InsertTab ;Prints tab for column alignment + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;This section prints the second fibonacci sequence value + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + Call WriteInt ;Prints the second value of the fibonacci sequence (also 1) + cmp NumFib, 2 ;Checks if only these two should be displayed + je FibDone ;If true, jump to end of program + + inc CurCol ;Otherwise, increment column index + call InsertTab ;Prints tab for column alignment + call InsertTab ;Prints tab for column alignment + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Setup of registers for the impending loop + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ecx, NumFib ;Sets loop ecx value + sub ecx, 2 ;Subtracts two because of the first two have already been printed + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Main fibonacci calculation and print loop + ;PSEUDO + ;newval = FibVal2 + Fibval + ;print newval + ;FibVal = FibVal2 + ;FibVal2 = newval; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +CalcFib: + mov eax, FibVal2 ;Moves most recent fibonacci value into one reg + add eax, FibVal ;Adds second to last to most recent + call WriteInt ;Prints this fibonacci value to screen + + push FibVal2 ;Moves old most recent to temp spot for move + pop FibVal ;Replaces second to last old val + mov FibVal2, eax ;Moves new most recent val to FibVal2 + + call InsertTab ;Prints tab for column alignment + cmp eax, ExtraTab ;Check if output val requires extra tab on output + jl OneExtra ;Jump to extra tab output label if necessary + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Return jump point for extra tab printing to make output alignment nice + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +MidCalcFib: + inc CurCol ;Increment column index + mov edx, CurCol ;Place index in reg for compare + cmp edx, ColMax ;Compare current col index with max + jne CalcFibLoop ;Jump to rest of loop if newline not needed + + call Crlf ;Prints newline when needed + mov CurCol, 0 ;Resets current column index + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Jump location used for avoiding printing a newline from above + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +CalcFibLoop: + loop CalcFib ;Loops fib calc sequence until ecx counter 0 + jmp TryAgain ;Jumps to program end if loop done + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Jump location used for printing on screen tabs + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +OneExtra: + call InsertTab ;Calls procedure to input tab when necessary + jmp MidCalcFib ;Jumps back to where it was called + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;This section deals with jumping if the user wants to calculate more values + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IncorrectTry: + call Crlf ;Prints a new line + mov edx,OFFSET IncorrectTryMessage ;Gets ready to print the incorrect try message + call Writestring ;Prints the incorrect try message + +TryAgain: + call Crlf ;Prints a new line + call Crlf ;Prints a new line + mov edx,OFFSET TryAgainMessage ;Gets ready to print the try again message + call WriteString ;Prints the try again message + call Crlf ;Prints a new line + + mov edx,OFFSET TryAgainMessage2 ;Gets ready to print the try again message part 2 + call WriteString ;Prints the try again message 2 + mov edx,OFFSET KeyAnswer ;Assigns edx to offset of keyanswer for keyboard input + mov ecx,SIZEOF KeyAnswer ;Sets number of characters to read in + call ReadString ;Reads in keyboard input + + INVOKE Str_compare,OFFSET KeyAnswer,OFFSET Yep ;Uses a multi-input irvine procedure to do a string comparison + je DoAgain ;Jump to DoAgain if the user answered 'y' + + INVOKE Str_compare,OFFSET KeyAnswer,OFFSET Nope ;Uses a multi-input irvine procedure to do a string comparison + je FibDone ;Jumps to end if user answered 'n' + + jmp IncorrectTry ;Jumps to an incorrect input section if user enterred wrong values + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Section to show the termination message + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +FibDone: + call Crlf ;Prints a new line + call Crlf ;Prints a new line + mov edx,OFFSET TermMessage ;Gets termination message part 1 ready to print + call WriteString ;Prints termination message + + mov edx,OFFSET UserName ;Gets username ready to print + call WriteString ;Prints username + + mov edx,OFFSET TermMessage2 ;Gets termination message part 2 ready to print + call WriteString ;Prints termination messag part 2 + + call Crlf ;Prints a new line + exit ;Ends main program +main ENDP +END main \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/ASM_Project.exe b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/ASM_Project.exe new file mode 100644 index 0000000..26a93f8 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/ASM_Project.exe differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/Assignment1.v12.suo b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/Assignment1.v12.suo new file mode 100644 index 0000000..333fea3 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/Assignment1.v12.suo differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/Assignment3.sdf b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/Assignment3.sdf new file mode 100644 index 0000000..fe1a9b0 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/Assignment3.sdf differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/Assignment3.sln b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/Assignment3.sln new file mode 100644 index 0000000..0555468 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/Assignment3.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ASM_Project", "Assignment3.vcxproj", "{4164AA65-1EF9-4E69-899B-D1BED776070B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Debug|Win32.ActiveCfg = Debug|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Debug|Win32.Build.0 = Debug|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Release|Win32.ActiveCfg = Release|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/Assignment3.v12.suo b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/Assignment3.v12.suo new file mode 100644 index 0000000..2df46a7 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/Assignment3.v12.suo differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/Assignment3.vcxproj b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/Assignment3.vcxproj new file mode 100644 index 0000000..ec0f08e --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/Assignment3.vcxproj @@ -0,0 +1,79 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + {4164AA65-1EF9-4E69-899B-D1BED776070B} + ASM_Project + + + + Application + v120 + + + Application + v120 + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + $(Configuration)\ + + + + c:\Irvine + + + user32.lib;irvine32.lib;%(AdditionalDependencies) + c:\Irvine;%(AdditionalLibraryDirectories) + true + Console + false + + + false + + + + + false + + + c:\Irvine;%(AdditionalLibraryDirectories) + Console + false + user32.lib;irvine32.lib;%(AdditionalDependencies) + + + c:\Irvine + + + + + + + \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/Assignment3.vcxproj.user b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/Assignment3.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/Assignment3.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/main.asm b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/main.asm new file mode 100644 index 0000000..7bdcd8f --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 3/main.asm @@ -0,0 +1,441 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +TITLE Assignment 5 (main.asm) +;Author: Corwin Perren +;Date: 3/3/2014 +;Description: +; This program runs all three programs from assignment 5 from a menu screen +; These programs include an array reverser, frequency table generator, and +; prime number generator +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +INCLUDE Irvine32.inc + +.data + +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Variables to change for testing program capabilities +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +SieveArray BYTE 1000000 dup(?) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Globally relevant vars +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +ProgramTitle BYTE "CS 271 - Assignment 5",0 +ProgrammerName BYTE "Written by: Corwin Perren",0 + +SelectInstructions BYTE "Please enter 1-4 to run desired program.", 0 + +MenuItem1 BYTE "1: Reverse Array In Place (Chapter 4, Exercise 5)",0 +MenuItem2 BYTE "2: Frequency Table (Chapter 9, Exercise 6)",0 +MenuItem3 BYTE "3: Sieve of Eratosthenes (Chapter 9, Exercise 7)",0 +MenuItem4 BYTE "4: Exit",0 + +Selection BYTE "Selection: ",0 + +IncorrectNumberEntry BYTE "You did not enter 1-4. Press enter to try again.", 0 +ReturnToSelect BYTE "Program Complete. Press enter to return to selection screen.", 0 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Vars for Prog 1 +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +ArrayToReverse BYTE 1,2,3,4,5,6,7,8,9,10, 11, 12, 13, 14 +PressEnter BYTE "Press enter to reverse the currently reversed array. Enter 1 to quit.", 0 +OriginalArray BYTE "Original Array:", 0 +ReversedArray BYTE "Reversed Array:", 0 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Vars for Prog 2 +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +StringEntry BYTE "Please enter a string to create a frequency table for.", 0 +StringThing BYTE "Your string: ", 0 + +StringArray BYTE 256 dup(?) +FrequencyTable DWORD 256 dup(?) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Vars for Prog 3 +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +EnterPrimes1 BYTE "Press enter to calculate primes up to ", 0 +EnterPrimes2 BYTE ".", 0 + + +.code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure for writing string with newline +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Write_String_NL PROC uses EDX, + StringPtr:Ptr BYTE ;Varible to store string offset pointer + + mov edx, StringPtr ;Moves the string to the proper register + call WriteString ;Prints the string + call Crlf ;Prints a new line + + ret ;Return from procedure +Write_String_NL ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure for writing string without newline + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Write_String PROC uses EDX, + StringPtr:Ptr BYTE ;Variable to store string offset pointer + + mov edx, StringPtr ;Moves the string to the proper registers + call WriteString ;Prints the string + + ret +Write_String ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure for printing program title and programmer name + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +PrintTitle PROC + INVOKE Write_String_NL, OFFSET ProgramTitle ;Prints the program title + INVOKE Write_String_NL, OFFSET ProgrammerName ;prints the programmer's name + call Crlf ;Prints a new line + INVOKE Write_String_NL, OFFSET SelectInstructions ;Prints the selection screen instructions + call Crlf ;Prints a new line + INVOKE Write_String_NL, OFFSET MenuItem1 ;Prints menu item 1 + INVOKE Write_String_NL, OFFSET MenuItem2 ;Prints menu item 2 + INVOKE Write_String_NL, OFFSET MenuItem3 ;Prints menu item 3 + INVOKE Write_String_NL, OFFSET MenuItem4 ;Prints menu item 4 + INVOKE Write_String, OFFSET Selection ;Print selction prompt + ret +PrintTitle ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure to fill array with zeros using stosb + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +FillWithZeros PROC + mov al, 0 ;Set al with value we want to fill array with + cld ;Clear Direction Flag + mov edi, OFFSET SieveArray ;Point edi to array + mov ecx, LENGTHOF SieveArray ;Set counter so instruction knows when to end + dec ecx ;Subtract one because it's starting at zero instead of one + rep stosb ;Repeats the fill operation until the array is full + ret ;Returns from function +FillWithZeros ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure to mark multiples of primes with ones + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +MarkMultiples PROC + + mov esi, OFFSET SieveArray ;Move into esi to get easy access + mov BYTE PTR [esi], 1 ;Mark zero as non-prime + mov BYTE PTR [esi+1], 1 ;Mark one as non-prime + mov eax, 2 ;Set cursor position + mov ebx, 2 ;Multiplication value + jmp Inner + +Outer: + pop eax ;Pop eax if we got here so the stack gets aligned and we know where we are +LookForOne: + inc eax ;Go up by one + cmp BYTE PTR [esi+eax], 1 ;Check to see if the new value at that position of the array has been marked + je LookForOne ;If so, increment again to find an unmarked one + + cmp eax, LENGTHOF SieveArray ;Once an unmarked is found, make sure it's not outside our array size + jg MultEnd ;If it's out of array bounds, we're done so exit + mov ebx, 2 ;Otherwise, get ready to mark multiples of current prime starting with two times the prime +Inner: + push eax ;Save our original prime we're using + mul ebx ;Multiply prime by scaler + cmp eax, LENGTHOF SieveArray ;Make sure new value is not out of array size + jg Outer ;If it is, we're done with this prime + + mov BYTE PTR [esi+eax], 1 ;Otherwise, mark the multiple with a one + inc ebx ;Increase our scaler + pop eax ;Restore the prime we're on + + jmp Inner ;Re-do for next scaler + +MultEnd: + ret ;Return from procedure +MarkMultiples ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure to print out unmarked values in array, which are primes + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +PrintPrimes PROC + mov esi, OFFSET SieveArray ;Load array into esi to get ready to print + mov eax, 0 ;Set our cursor to zero +LookForZeros: + inc eax ;Move cursor forward one + cmp eax, LENGTHOF SieveArray ;Check if cursor is out of array bounds + jg PrintExit ;If so, exit because we are done + + cmp BYTE PTR [esi+eax], 1 ;If we're in bounds, check if the position is marked + je LookForZeros ;If so, don't print and look at the next position + call WriteDec ;If unmarked, print the prime number sotred here + call Crlf ;Print a new line to make things look nice + jmp LookForZeros ;Continue for the next array position + +PrintExit: + ret ;Return from procedure +PrintPrimes ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure to run program 3 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Program3 PROC + call ClrScr ;Clears the screen + INVOKE Write_String, OFFSET EnterPrimes1 ;Prints prompt part one + mov eax, LENGTHOF SieveArray ;Moves number of primes to calculate to print + call WriteDec ;Prints number of primes to calculate + INVOKE Write_String_NL, OFFSET EnterPrimes2 ;Prints end of prompt line + call ReadInt ;Waits for any key + call FillWithZeros ;Fills the sieve array with zeros using stosb method + call MarkMultiples ;Marks positions that are multiples of primes + call PrintPrimes ;Prints remaining prime numbers + ret ;Returns from procedure +Program3 ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure to determine the character frequency of a string + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Get_Frequencies PROC InputString:PTR BYTE, OutputTable:PTR DWORD + mov esi, InputString ;Moves string to parse into esi + mov edi, OutputTable ;Moves output table into edi + +FreqLoop: + mov eax, 0 ;Zeros eax to make things work right + mov al, BYTE PTR [esi] ;Moves ascii decimal value into eax + mov ecx, eax ;Saves current decimal value + mov ebx, 4 ;Multiply eax by four because it's stored in DWORD and not BYTE array + mul ebx ;Actual multiplication + add DWORD PTR [edi+eax], 1 ;Increments frequency table position by one for this character + + cmp ecx, 0 ;Checks if we've hit the NUL character + je FreqDone ;Exit if it's found because we're done + + inc esi ;Otherwise, move to the next string array position + jmp FreqLoop ;Do above again for next character + +FreqDone: + ret ;Return from procedure +Get_Frequencies ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure to read in string from user + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +GetNewString PROC StringPtr:PTR BYTE + mov edx, StringPtr ;Move string array into edx for read in + mov ecx, 256 ;Read in a max of 256 characters + call ReadString ;Read in string from user + + ret ;Exit from procedure +GetNewString ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure to print out the frequency table + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +PrintFreqTable PROC TablePtr:PTR DWORD + mov esi, TablePtr ;Move frequency table into esi + mov ecx, 256 ;Set number of elements + mov ebx, 4 ;Set size of storage elements + call DumpMem ;Dump memory for the array + ret +PrintFreqTable ENDP + +ZeroProg2 PROC + mov eax, 0 ;Set al with value we want to fill array with + cld ;Clear Direction Flag + mov edi, OFFSET StringArray ;Point edi to array + mov ecx, 256 ;Set counter so instruction knows when to end + dec ecx ;Subtract one because it's starting at zero instead of one + rep stosb ;Repeats the fill operation until the array is full + + mov eax, 0 ;Set al with value we want to fill array with + cld ;Clear Direction Flag + mov edi, OFFSET FrequencyTable ;Point edi to array + mov ecx, 1024 ;Set counter so instruction knows when to end + dec ecx ;Subtract one because it's starting at zero instead of one + rep stosb ;Repeats the fill operation until the array is full + + ret ;Returns from function +ZeroProg2 ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure to run program 2 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Program2 PROC + call ClrScr ;Clear the screen + call ZeroProg2 ;Zeros string and freq table array + INVOKE Write_String_NL, OFFSET StringEntry ;Prompts the user to enter a string + INVOKE Write_String, OFFSET StringThing ;Line prompt for above + INVOKE GetNewString, OFFSET StringArray ;Reads in user string + INVOKE Get_Frequencies, OFFSET StringArray, OFFSET FrequencyTable ;Runs frequency procedure on input string + INVOKE PrintFreqTable, OFFSET FrequencyTable ;Prints out the new frequency table + ret ;Returns from procedure +Program2 ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure to run program 1 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Program1 PROC + call ClrScr ;Clears the screen + INVOKE Write_String_NL, OFFSET OriginalArray ;Prints header for original array + + mov eax, TYPE ArrayToReverse ;Moves the array type into eax + + cmp eax, 1 ;Checks if it's a BYTE array + je ITSBYTE ;Jumps to BYTE section if so + + cmp eax, 2 ;Checks if WORD array + je ITSWORD ;Jumps to WORD section if so + + cmp eax, 4 ;Check if DWORD array + je ITSDWORD ;Jumps to DWORD section if so + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Run for BYTE Array + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +ITSBYTE: + mov esi, OFFSET ArrayToReverse ;Moves array into esi + mov ecx, LENGTHOF ArrayToReverse ;Moves number of elements in array into ecx + mov ebx, TYPE ArrayToReverse ;Moves type of array into ebx + call DumpMem ;Shows original array + + mov esi, OFFSET ArrayToReverse ;Re-moves array into esi + mov edi, OFFSET ArrayToReverse + SIZEOF ArrayToReverse - TYPE ArrayToReverse ;Moves the pointer to the last value of the array into edi + mov eax, LENGTHOF ArrayToReverse ;Moves number of elements in array into eax + mov edx, 0 ;Sets remainder to zero by default + mov ebx, 2 ;Moves two into ebx + div ebx ;Divides number of elements by two + mov ecx, eax ;Puts that number into our loop counter + +ReverseBYTE: + mov bl, [esi] ;Move data at beginning cursor to tmp storage + mov dl, [edi] ;Move data at end cursor to tmp storage + mov [esi], dl ;Move end data to beginning + mov [edi], bl ;Move beginning data to end + + add esi, TYPE ArrayToReverse ;Move beginning cursor forward + sub edi, TYPE ArrayToReverse ;Move ending cursor back + loop ReverseBYTE ;Loop until count expired + + jmp Prog1Ret ;Jump to procedure end when done + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Run for WORD Array + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +ITSWORD: + mov esi, OFFSET ArrayToReverse ;Moves array into esi + mov ecx, LENGTHOF ArrayToReverse ;Moves number of elements in array into ecx + mov ebx, TYPE ArrayToReverse ;Moves type of array into ebx + call DumpMem ;Shows original array + + mov esi, OFFSET ArrayToReverse ;Re-moves array into esi + mov edi, OFFSET ArrayToReverse + SIZEOF ArrayToReverse - TYPE ArrayToReverse ;Moves the pointer to the last value of the array into edi + mov eax, LENGTHOF ArrayToReverse ;Moves number of elements in array into eax + mov edx, 0 ;Sets remainder to zero by default + mov ebx, 2 ;Moves two into ebx + div ebx ;Divides number of elements by two + mov ecx, eax ;Puts that number into our loop counter + +ReverseWORD: + mov bx, [esi] ;Move data at beginning cursor to tmp storage + mov dx, [edi] ;Move data at end cursor to tmp storage + mov [esi], dx ;Move end data to beginning + mov [edi], bx ;Move beginning data to end + + add esi, TYPE ArrayToReverse ;Move beginning cursor forward + sub edi, TYPE ArrayToReverse ;Move ending cursor back + loop ReverseWORD ;Loop until count expired + + jmp Prog1Ret + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Run for DWORD Array + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +ITSDWORD: + mov esi, OFFSET ArrayToReverse ;Moves array into esi + mov ecx, LENGTHOF ArrayToReverse ;Moves number of elements in array into ecx + mov ebx, TYPE ArrayToReverse ;Moves type of array into ebx + call DumpMem ;Shows original array + + mov esi, OFFSET ArrayToReverse ;Re-moves array into esi + mov edi, OFFSET ArrayToReverse + SIZEOF ArrayToReverse - TYPE ArrayToReverse ;Moves the pointer to the last value of the array into edi + mov eax, LENGTHOF ArrayToReverse ;Moves number of elements in array into eax + mov edx, 0 ;Sets remainder to zero by default + mov ebx, 2 ;Moves two into ebx + div ebx ;Divides number of elements by two + mov ecx, eax ;Puts that number into our loop counter + +ReverseDWORD: + mov ebx, [esi] ;Move data at beginning cursor to tmp storage + mov edx, [edi] ;Move data at end cursor to tmp storage + mov [esi], edx ;Move end data to beginning + mov [edi], ebx ;Move beginning data to end + + add esi, TYPE ArrayToReverse ;Move beginning cursor forward + sub edi, TYPE ArrayToReverse ;Move ending cursor back + loop ReverseWORD ;Loop until count expired + + + +Prog1Ret: + call Crlf ;Print a new line + call Crlf ;Print a second new line + INVOKE Write_String_NL, OFFSET ReversedArray ;Print header to say this is the reversed array + mov esi, OFFSET ArrayToReverse ;Move array into esi + mov ecx, LENGTHOF ArrayToReverse ;Set number of elements + mov ebx, TYPE ArrayToReverse ;Set size of elements + call DumpMem ;Display array + + ret ;Return from procedure +Program1 ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Main Procedure + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +main PROC +MainTitle: + call ClrScr ;Clear screen + call PrintTitle ;Print the title screen + call ReadInt ;Read in user selection + + cmp eax, 1 ;Check if user selected entry item 1 + je Prog1Jmp ;If so, jump to that program + + cmp eax, 2 ;Check if user selected entry item 2 + je Prog2Jmp ;If so, jump to that program + + cmp eax, 3 ;Check if user selected entry item 3 + je Prog3Jmp ;If so, jump to that program + + cmp eax, 4 ;Check if user selected exit + je MainExit ;If so, jump to end of program + + call ClrScr ;Clear screeen + INVOKE Write_String_NL, OFFSET IncorrectNumberEntry ;Scold user for not entering one to four + call ReadInt ;Wait for enter key + jmp MainTitle ;Jump back to main screen + +Prog1Jmp: + call Program1 ;Call array reverse program + call Crlf ;Print new line + INVOKE Write_String_NL, OFFSET ReturnToSelect ;Print hit enter to return to screen + call ReadInt ;Wait for enter + jmp MainTitle ;Jump to main screen +Prog2Jmp: + call Program2 ;Call String frequency program + call Crlf ;Print new line + INVOKE Write_String_NL, OFFSET ReturnToSelect ;Print hit enter to return to screen + call ReadInt ;Wait for enter + jmp MainTitle ;Jump to main screen +Prog3Jmp: + call Program3 ;Call prime generator program + call Crlf ;Print new line + INVOKE Write_String_NL, OFFSET ReturnToSelect ;Print hit enter to return to screen + call ReadInt ;Wait for enter + jmp MainTitle ;Jump to main screen +MainExit: + exit +main ENDP + +END main \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/ASM_Project.exe b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/ASM_Project.exe new file mode 100644 index 0000000..7b922a2 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/ASM_Project.exe differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment1.v12.suo b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment1.v12.suo new file mode 100644 index 0000000..333fea3 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment1.v12.suo differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment3.v12.suo b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment3.v12.suo new file mode 100644 index 0000000..4777516 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment3.v12.suo differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment4.sdf b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment4.sdf new file mode 100644 index 0000000..640cdfb Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment4.sdf differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment4.sln b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment4.sln new file mode 100644 index 0000000..0555468 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment4.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ASM_Project", "Assignment3.vcxproj", "{4164AA65-1EF9-4E69-899B-D1BED776070B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Debug|Win32.ActiveCfg = Debug|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Debug|Win32.Build.0 = Debug|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Release|Win32.ActiveCfg = Release|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment4.v12.suo b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment4.v12.suo new file mode 100644 index 0000000..7c3dea7 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment4.v12.suo differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment4.vcxproj b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment4.vcxproj new file mode 100644 index 0000000..c770474 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment4.vcxproj @@ -0,0 +1,79 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + {4164AA65-1EF9-4E69-899B-D1BED776070B} + ASM_Project + + + + Application + v120 + + + Application + v120 + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + $(Configuration)\ + + + + c:\Irvine + + + user32.lib;irvine32.lib;%(AdditionalDependencies) + c:\Irvine;%(AdditionalLibraryDirectories) + true + Console + false + + + false + + + + + false + + + c:\Irvine;%(AdditionalLibraryDirectories) + Console + false + user32.lib;irvine32.lib;%(AdditionalDependencies) + + + c:\Irvine + + + + + + + \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment4.vcxproj.user b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment4.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment4.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment4_perrenc.asm b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment4_perrenc.asm new file mode 100644 index 0000000..66461f7 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 4/Assignment4_perrenc.asm @@ -0,0 +1,254 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +TITLE Assignment 3 (main.asm) +;Author: Corwin Perren +;Date: 2/05/2014 +;Description: +; This program greets a user by name, takes in ten integers, sums +; non-negative ones, and computers the average of that sum before saying +; goodbye to the user +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +INCLUDE Irvine32.inc + +.data +ProgramTitle BYTE "CS 271 - Assignment 3",0 +ProgrammerName BYTE "Written by: Corwin Perren",0 + +NamePrompt BYTE "By what name may I call you?",0 +NamePrompt2 BYTE "Your name: ", 0 + +NameResponse BYTE "Welcome, ", 0 +NameResponse2 BYTE ".", 0 + +EnterNumPrompt BYTE "Please enter ten numbers between 0 and 100.", 0 +TooGreat BYTE "The number you entered was too large, please try again.", 0 +IncorrectInputMessage BYTE "You did not enter a valid number.", 0 + +ListingPrint BYTE "Number ", 0 +ListingPrint2 BYTE ":", 0 + +NoPosMessage BYTE "No Positive Integers Entered...", 0 +NumPosMessage BYTE "Number of Positive Integers: ", 0 +SumMessage BYTE "Sum of Positive Integers: ", 0 +AvgMessage BYTE "Average of Positive Integers: ", 0 + +TermMessage BYTE "Goodbye, ", 0 +TermMessage2 BYTE ".", 0 + +TESTMessage BYTE "Equal to Zero", 0 + +NumEntries DWORD 10 +MaxEntryVal DWORD 100 + +StorArray DWORD 10 dup(0) +UserName BYTE 25 dup(0) + +NumPos DWORD 0 +FinalSum DWORD 0 +FinalAvg DWORD 0 + + +.code + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure for writing string with newline + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Write_String_NL PROC uses EDX, + StringPtr:Ptr BYTE ;Varible to store string offset pointer + + mov edx, StringPtr ;Moves the string to the proper register + call WriteString ;Prints the string + call Crlf ;Prints a new line + + ret +Write_String_NL ENDP + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure for writing string without newline + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Write_String PROC uses EDX, + StringPtr:Ptr BYTE ;Variable to store string offset pointer + + mov edx, StringPtr ;Moves the string to the proper registers + call WriteString ;Prints the string + + ret +Write_String ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure for printing program title and programmer name + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +PrintTitle PROC + INVOKE Write_String_NL, OFFSET ProgramTitle ;Prints the program title + INVOKE Write_String_NL, OFFSET ProgrammerName ;prints the programmer's name' + call Crlf ;Prints a new line + ret +PrintTitle ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure for getting user's name and greeting them + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +MeetAndGreet PROC + INVOKE Write_String_NL, OFFSET NamePrompt ;Gets username prompt ready + + INVOKE Write_String, OFFSET NamePrompt2 ;Gets second half of username prompt ready + + mov edx,OFFSET UserName ;Moves offset for username storage var into edx + mov ecx,SIZEOF UserName ;Sets max number of characters to read in + call ReadString ;Reads in username string from user + + call Clrscr ;Clears the screen to clean up output + INVOKE Write_String, OFFSET NameResponse ;Prints the first part of the welcome message + INVOKE Write_String, OFFSET UserName ;Prints the user's name + INVOKE Write_String_NL, OFFSET NameResponse2 ;Prints teh second half of the welcome message + call Crlf ;Prints a new line + + ret +MeetAndGreet ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure for printing what the user may enter + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +PrintEnterNumPrompt PROC + INVOKE Write_String_NL, OFFSET EnterNumPrompt ;Gets welcome message part 2 redy to print + ret +PrintEnterNumPrompt ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure for retreiving integer inputs from user + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +GetNumbers PROC + + mov ecx, NumEntries ;Sets loop count variable + mov esi, OFFSET StorArray ;Puts storage array into esi reg + jmp EnterNum ;Jump to beginning of number entry + +IncorrectInput: + INVOKE Write_String_NL, OFFSET IncorrectInputMessage ;Displays incorrect input message + jmp EnterNum ;Jumps to beginning of number entry +GreaterThanMax: + INVOKE Write_String_NL, OFFSET TooGreat ;Displays number to great message +EnterNum: + INVOKE Write_String, OFFSET ListingPrint ;Prints number entry listing + + mov eax, NumEntries ;Moves total entries to eax + inc eax ;Increments by one to start at 1 rather than 0 + sub eax, ecx ;Subracts current loop var to determine count val + call WriteInt ;Writes for number entry listing + + INVOKE Write_String, OFFSET ListingPrint2 ;Finishes priting number entry listing + + call ReadInt ;Reads in int from user + jo IncorrectInput ;Re-do previous if incorrect input + cmp eax, MaxEntryVal ;Check if number too great + jg GreaterThanMax ;Jump if number too great + + mov [esi], eax ;Move number if valid into array + add esi, 4 ;Increment array pointer + + loop EnterNum ;Loop unti ecx equals 0 + ret +GetNumbers ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure for determining number of positive integers, summing them, and + ;calculating their average + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +CalcStuff PROC + mov ecx, NumEntries ;Puts loop counter in + mov esi, OFFSET StorArray ;Gets array ready to loop through + mov eax, 0 ;Makes sum register zero + +ArrayLoop: + mov edx, [esi] ;Read out one array value + add esi, 4 ;Increment array pointer + cmp edx, 0 ;Check if negative + jl ArrayLoopEnd ;Jump to ignore if negative + + add eax, edx ;If non-negative, add to sum reg + inc NumPos ;Increment number of positive found + + +ArrayLoopEnd: + loop ArrayLoop ;Loop until array empty + + cmp NumPos, 0 ;Check if any positive found + jne MoreThanZero ;Jump if there are positive integers + + Invoke Write_String_NL, OFFSET NoPosMessage ;Write no positive intergers message + jmp QuickEnd ;End program because no positive integers + +MoreThanZero: + mov FinalSum, eax ;Move positive integers sum to variable + mov edx, 0 ;Zero upper of numerator + mov ebx, NumPos ;Put value in lower of numerator + div ebx ;Divide sum by number of positive integers + mov FinalAvg, eax ;Take result which is average and store in varible + + call Crlf ;Print a new line + ret +CalcStuff ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Prints the number of positive integers + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +PrintNumPos PROC + Invoke Write_String, OFFSET NumPosMessage ;Print string for number of positive integers + mov eax, NumPos ;Move varaible into printing register + call WriteInt ;Print number of positive integers + call Crlf ;Print a new line + ret +PrintNumPos ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Prints the sum of the positive integers + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +PrintSumOf PROC + Invoke Write_String, OFFSET SumMessage ;Print the message for the sum + mov eax, FinalSum ;Move sum into printing register + call WriteInt ;Print sum + call Crlf ;Print new line + ret +PrintSumOf ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Prints the average of the positive integers + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +PrintAverageOf PROC + Invoke Write_String, OFFSET AvgMessage ;Print message for the average + mov eax, FinalAvg ;Move average into printing register + call WriteInt ;Print the average + call Crlf ;Print a new line + ret +PrintAverageOf ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure for printing the termination message + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +PrintTerm PROC + Invoke Write_String, OFFSET TermMessage ;Print the first part of the termination message + Invoke Write_String, OFFSET UserName ;Print the user's name + Invoke Write_String_NL, OFFSET TermMessage2 ;Print the second part of the termination message + ret +PrintTerm ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Main Procedure + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +main PROC + call PrintTitle ;Prints title + call MeetAndGreet ;Greets user by name + call PrintEnterNumPrompt ;Print prompt for program use + call GetNumbers ;Retrieves user integer entries + call CalcStuff ;Performs math on numbers entered + call PrintNumPos ;Prints number of positive integers + call PrintSumOf ;Prints sum of positive integers + call PrintAverageOf ;Prints average of positive integers +QuickEnd:: + call PrintTerm ;Prints termination message + + exit +main ENDP + +END main \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/5.user b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/5.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/5.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/ASM_Project.exe b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/ASM_Project.exe new file mode 100644 index 0000000..26a93f8 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/ASM_Project.exe differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/Assignment5.sdf b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/Assignment5.sdf new file mode 100644 index 0000000..dfc8860 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/Assignment5.sdf differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/Assignment5.sln b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/Assignment5.sln new file mode 100644 index 0000000..f7444b6 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/Assignment5.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ASM_Project", "Assignment5.vcxproj", "{4164AA65-1EF9-4E69-899B-D1BED776070B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Debug|Win32.ActiveCfg = Debug|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Debug|Win32.Build.0 = Debug|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Release|Win32.ActiveCfg = Release|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/Assignment5.v12.suo b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/Assignment5.v12.suo new file mode 100644 index 0000000..c5e7a75 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/Assignment5.v12.suo differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/Assignment5.v52.suo b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/Assignment5.v52.suo new file mode 100644 index 0000000..e35f81a Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/Assignment5.v52.suo differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/Assignment5.vcxproj b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/Assignment5.vcxproj new file mode 100644 index 0000000..2360b1d --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/Assignment5.vcxproj @@ -0,0 +1,79 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + {4164AA65-1EF9-4E69-899B-D1BED776070B} + ASM_Project + + + + Application + v120 + + + Application + v120 + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + $(Configuration)\ + + + + c:\Irvine + + + user32.lib;irvine32.lib;%(AdditionalDependencies) + c:\Irvine;%(AdditionalLibraryDirectories) + true + Console + false + + + false + + + + + false + + + c:\Irvine;%(AdditionalLibraryDirectories) + Console + false + user32.lib;irvine32.lib;%(AdditionalDependencies) + + + c:\Irvine + + + + + + + \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/CS271_proj5_perrenc.asm b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/CS271_proj5_perrenc.asm new file mode 100644 index 0000000..fc2a63a --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/CS271_proj5_perrenc.asm @@ -0,0 +1,441 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +TITLE Assignment 5 (main.asm) +;Author: Corwin Perren +;Date: 3/3/2014 +;Description: +; This program runs all three programs from assignment 5 from a menu screen +; These programs include an array reverser, frequency table generator, and +; prime number generator +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +INCLUDE Irvine32.inc + +.data + +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Variables to change for testing program capabilities +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +SieveArray BYTE 5000 dup(?) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Globally relevant vars +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +ProgramTitle BYTE "CS 271 - Assignment 5",0 +ProgrammerName BYTE "Written by: Corwin Perren",0 + +SelectInstructions BYTE "Please enter 1-4 to run desired program.", 0 + +MenuItem1 BYTE "1: Reverse Array In Place (Chapter 4, Exercise 5)",0 +MenuItem2 BYTE "2: Frequency Table (Chapter 9, Exercise 6)",0 +MenuItem3 BYTE "3: Sieve of Eratosthenes (Chapter 9, Exercise 7)",0 +MenuItem4 BYTE "4: Exit",0 + +Selection BYTE "Selection: ",0 + +IncorrectNumberEntry BYTE "You did not enter 1-4. Press enter to try again.", 0 +ReturnToSelect BYTE "Program Complete. Press enter to return to selection screen.", 0 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Vars for Prog 1 +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +ArrayToReverse BYTE 1,2,3,4,5,6,7,8,9,10, 11, 12, 13, 14 +PressEnter BYTE "Press enter to reverse the currently reversed array. Enter 1 to quit.", 0 +OriginalArray BYTE "Original Array:", 0 +ReversedArray BYTE "Reversed Array:", 0 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Vars for Prog 2 +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +StringEntry BYTE "Please enter a string to create a frequency table for.", 0 +StringThing BYTE "Your string: ", 0 + +StringArray BYTE 256 dup(?) +FrequencyTable DWORD 256 dup(?) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Vars for Prog 3 +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +EnterPrimes1 BYTE "Press enter to calculate primes up to ", 0 +EnterPrimes2 BYTE ".", 0 + + +.code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure for writing string with newline +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Write_String_NL PROC uses EDX, + StringPtr:Ptr BYTE ;Varible to store string offset pointer + + mov edx, StringPtr ;Moves the string to the proper register + call WriteString ;Prints the string + call Crlf ;Prints a new line + + ret ;Return from procedure +Write_String_NL ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure for writing string without newline + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Write_String PROC uses EDX, + StringPtr:Ptr BYTE ;Variable to store string offset pointer + + mov edx, StringPtr ;Moves the string to the proper registers + call WriteString ;Prints the string + + ret +Write_String ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure for printing program title and programmer name + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +PrintTitle PROC + INVOKE Write_String_NL, OFFSET ProgramTitle ;Prints the program title + INVOKE Write_String_NL, OFFSET ProgrammerName ;prints the programmer's name + call Crlf ;Prints a new line + INVOKE Write_String_NL, OFFSET SelectInstructions ;Prints the selection screen instructions + call Crlf ;Prints a new line + INVOKE Write_String_NL, OFFSET MenuItem1 ;Prints menu item 1 + INVOKE Write_String_NL, OFFSET MenuItem2 ;Prints menu item 2 + INVOKE Write_String_NL, OFFSET MenuItem3 ;Prints menu item 3 + INVOKE Write_String_NL, OFFSET MenuItem4 ;Prints menu item 4 + INVOKE Write_String, OFFSET Selection ;Print selction prompt + ret +PrintTitle ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure to fill array with zeros using stosb + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +FillWithZeros PROC + mov al, 0 ;Set al with value we want to fill array with + cld ;Clear Direction Flag + mov edi, OFFSET SieveArray ;Point edi to array + mov ecx, LENGTHOF SieveArray ;Set counter so instruction knows when to end + dec ecx ;Subtract one because it's starting at zero instead of one + rep stosb ;Repeats the fill operation until the array is full + ret ;Returns from function +FillWithZeros ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure to mark multiples of primes with ones + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +MarkMultiples PROC + + mov esi, OFFSET SieveArray ;Move into esi to get easy access + mov BYTE PTR [esi], 1 ;Mark zero as non-prime + mov BYTE PTR [esi+1], 1 ;Mark one as non-prime + mov eax, 2 ;Set cursor position + mov ebx, 2 ;Multiplication value + jmp Inner + +Outer: + pop eax ;Pop eax if we got here so the stack gets aligned and we know where we are +LookForOne: + inc eax ;Go up by one + cmp BYTE PTR [esi+eax], 1 ;Check to see if the new value at that position of the array has been marked + je LookForOne ;If so, increment again to find an unmarked one + + cmp eax, LENGTHOF SieveArray ;Once an unmarked is found, make sure it's not outside our array size + jg MultEnd ;If it's out of array bounds, we're done so exit + mov ebx, 2 ;Otherwise, get ready to mark multiples of current prime starting with two times the prime +Inner: + push eax ;Save our original prime we're using + mul ebx ;Multiply prime by scaler + cmp eax, LENGTHOF SieveArray ;Make sure new value is not out of array size + jg Outer ;If it is, we're done with this prime + + mov BYTE PTR [esi+eax], 1 ;Otherwise, mark the multiple with a one + inc ebx ;Increase our scaler + pop eax ;Restore the prime we're on + + jmp Inner ;Re-do for next scaler + +MultEnd: + ret ;Return from procedure +MarkMultiples ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure to print out unmarked values in array, which are primes + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +PrintPrimes PROC + mov esi, OFFSET SieveArray ;Load array into esi to get ready to print + mov eax, 0 ;Set our cursor to zero +LookForZeros: + inc eax ;Move cursor forward one + cmp eax, LENGTHOF SieveArray ;Check if cursor is out of array bounds + jg PrintExit ;If so, exit because we are done + + cmp BYTE PTR [esi+eax], 1 ;If we're in bounds, check if the position is marked + je LookForZeros ;If so, don't print and look at the next position + call WriteDec ;If unmarked, print the prime number sotred here + call Crlf ;Print a new line to make things look nice + jmp LookForZeros ;Continue for the next array position + +PrintExit: + ret ;Return from procedure +PrintPrimes ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure to run program 3 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Program3 PROC + call ClrScr ;Clears the screen + INVOKE Write_String, OFFSET EnterPrimes1 ;Prints prompt part one + mov eax, LENGTHOF SieveArray ;Moves number of primes to calculate to print + call WriteDec ;Prints number of primes to calculate + INVOKE Write_String_NL, OFFSET EnterPrimes2 ;Prints end of prompt line + call ReadInt ;Waits for any key + call FillWithZeros ;Fills the sieve array with zeros using stosb method + call MarkMultiples ;Marks positions that are multiples of primes + call PrintPrimes ;Prints remaining prime numbers + ret ;Returns from procedure +Program3 ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure to determine the character frequency of a string + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Get_Frequencies PROC InputString:PTR BYTE, OutputTable:PTR DWORD + mov esi, InputString ;Moves string to parse into esi + mov edi, OutputTable ;Moves output table into edi + +FreqLoop: + mov eax, 0 ;Zeros eax to make things work right + mov al, BYTE PTR [esi] ;Moves ascii decimal value into eax + mov ecx, eax ;Saves current decimal value + mov ebx, 4 ;Multiply eax by four because it's stored in DWORD and not BYTE array + mul ebx ;Actual multiplication + add DWORD PTR [edi+eax], 1 ;Increments frequency table position by one for this character + + cmp ecx, 0 ;Checks if we've hit the NUL character + je FreqDone ;Exit if it's found because we're done + + inc esi ;Otherwise, move to the next string array position + jmp FreqLoop ;Do above again for next character + +FreqDone: + ret ;Return from procedure +Get_Frequencies ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure to read in string from user + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +GetNewString PROC StringPtr:PTR BYTE + mov edx, StringPtr ;Move string array into edx for read in + mov ecx, 256 ;Read in a max of 256 characters + call ReadString ;Read in string from user + + ret ;Exit from procedure +GetNewString ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure to print out the frequency table + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +PrintFreqTable PROC TablePtr:PTR DWORD + mov esi, TablePtr ;Move frequency table into esi + mov ecx, 256 ;Set number of elements + mov ebx, 4 ;Set size of storage elements + call DumpMem ;Dump memory for the array + ret +PrintFreqTable ENDP + +ZeroProg2 PROC + mov eax, 0 ;Set al with value we want to fill array with + cld ;Clear Direction Flag + mov edi, OFFSET StringArray ;Point edi to array + mov ecx, 256 ;Set counter so instruction knows when to end + dec ecx ;Subtract one because it's starting at zero instead of one + rep stosb ;Repeats the fill operation until the array is full + + mov eax, 0 ;Set al with value we want to fill array with + cld ;Clear Direction Flag + mov edi, OFFSET FrequencyTable ;Point edi to array + mov ecx, 1024 ;Set counter so instruction knows when to end + dec ecx ;Subtract one because it's starting at zero instead of one + rep stosb ;Repeats the fill operation until the array is full + + ret ;Returns from function +ZeroProg2 ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure to run program 2 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Program2 PROC + call ClrScr ;Clear the screen + call ZeroProg2 ;Zeros string and freq table array + INVOKE Write_String_NL, OFFSET StringEntry ;Prompts the user to enter a string + INVOKE Write_String, OFFSET StringThing ;Line prompt for above + INVOKE GetNewString, OFFSET StringArray ;Reads in user string + INVOKE Get_Frequencies, OFFSET StringArray, OFFSET FrequencyTable ;Runs frequency procedure on input string + INVOKE PrintFreqTable, OFFSET FrequencyTable ;Prints out the new frequency table + ret ;Returns from procedure +Program2 ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure to run program 1 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Program1 PROC + call ClrScr ;Clears the screen + INVOKE Write_String_NL, OFFSET OriginalArray ;Prints header for original array + + mov eax, TYPE ArrayToReverse ;Moves the array type into eax + + cmp eax, 1 ;Checks if it's a BYTE array + je ITSBYTE ;Jumps to BYTE section if so + + cmp eax, 2 ;Checks if WORD array + je ITSWORD ;Jumps to WORD section if so + + cmp eax, 4 ;Check if DWORD array + je ITSDWORD ;Jumps to DWORD section if so + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Run for BYTE Array + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +ITSBYTE: + mov esi, OFFSET ArrayToReverse ;Moves array into esi + mov ecx, LENGTHOF ArrayToReverse ;Moves number of elements in array into ecx + mov ebx, TYPE ArrayToReverse ;Moves type of array into ebx + call DumpMem ;Shows original array + + mov esi, OFFSET ArrayToReverse ;Re-moves array into esi + mov edi, OFFSET ArrayToReverse + SIZEOF ArrayToReverse - TYPE ArrayToReverse ;Moves the pointer to the last value of the array into edi + mov eax, LENGTHOF ArrayToReverse ;Moves number of elements in array into eax + mov edx, 0 ;Sets remainder to zero by default + mov ebx, 2 ;Moves two into ebx + div ebx ;Divides number of elements by two + mov ecx, eax ;Puts that number into our loop counter + +ReverseBYTE: + mov bl, [esi] ;Move data at beginning cursor to tmp storage + mov dl, [edi] ;Move data at end cursor to tmp storage + mov [esi], dl ;Move end data to beginning + mov [edi], bl ;Move beginning data to end + + add esi, TYPE ArrayToReverse ;Move beginning cursor forward + sub edi, TYPE ArrayToReverse ;Move ending cursor back + loop ReverseBYTE ;Loop until count expired + + jmp Prog1Ret ;Jump to procedure end when done + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Run for WORD Array + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +ITSWORD: + mov esi, OFFSET ArrayToReverse ;Moves array into esi + mov ecx, LENGTHOF ArrayToReverse ;Moves number of elements in array into ecx + mov ebx, TYPE ArrayToReverse ;Moves type of array into ebx + call DumpMem ;Shows original array + + mov esi, OFFSET ArrayToReverse ;Re-moves array into esi + mov edi, OFFSET ArrayToReverse + SIZEOF ArrayToReverse - TYPE ArrayToReverse ;Moves the pointer to the last value of the array into edi + mov eax, LENGTHOF ArrayToReverse ;Moves number of elements in array into eax + mov edx, 0 ;Sets remainder to zero by default + mov ebx, 2 ;Moves two into ebx + div ebx ;Divides number of elements by two + mov ecx, eax ;Puts that number into our loop counter + +ReverseWORD: + mov bx, [esi] ;Move data at beginning cursor to tmp storage + mov dx, [edi] ;Move data at end cursor to tmp storage + mov [esi], dx ;Move end data to beginning + mov [edi], bx ;Move beginning data to end + + add esi, TYPE ArrayToReverse ;Move beginning cursor forward + sub edi, TYPE ArrayToReverse ;Move ending cursor back + loop ReverseWORD ;Loop until count expired + + jmp Prog1Ret + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Run for DWORD Array + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +ITSDWORD: + mov esi, OFFSET ArrayToReverse ;Moves array into esi + mov ecx, LENGTHOF ArrayToReverse ;Moves number of elements in array into ecx + mov ebx, TYPE ArrayToReverse ;Moves type of array into ebx + call DumpMem ;Shows original array + + mov esi, OFFSET ArrayToReverse ;Re-moves array into esi + mov edi, OFFSET ArrayToReverse + SIZEOF ArrayToReverse - TYPE ArrayToReverse ;Moves the pointer to the last value of the array into edi + mov eax, LENGTHOF ArrayToReverse ;Moves number of elements in array into eax + mov edx, 0 ;Sets remainder to zero by default + mov ebx, 2 ;Moves two into ebx + div ebx ;Divides number of elements by two + mov ecx, eax ;Puts that number into our loop counter + +ReverseDWORD: + mov ebx, [esi] ;Move data at beginning cursor to tmp storage + mov edx, [edi] ;Move data at end cursor to tmp storage + mov [esi], edx ;Move end data to beginning + mov [edi], ebx ;Move beginning data to end + + add esi, TYPE ArrayToReverse ;Move beginning cursor forward + sub edi, TYPE ArrayToReverse ;Move ending cursor back + loop ReverseWORD ;Loop until count expired + + + +Prog1Ret: + call Crlf ;Print a new line + call Crlf ;Print a second new line + INVOKE Write_String_NL, OFFSET ReversedArray ;Print header to say this is the reversed array + mov esi, OFFSET ArrayToReverse ;Move array into esi + mov ecx, LENGTHOF ArrayToReverse ;Set number of elements + mov ebx, TYPE ArrayToReverse ;Set size of elements + call DumpMem ;Display array + + ret ;Return from procedure +Program1 ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Main Procedure + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +main PROC +MainTitle: + call ClrScr ;Clear screen + call PrintTitle ;Print the title screen + call ReadInt ;Read in user selection + + cmp eax, 1 ;Check if user selected entry item 1 + je Prog1Jmp ;If so, jump to that program + + cmp eax, 2 ;Check if user selected entry item 2 + je Prog2Jmp ;If so, jump to that program + + cmp eax, 3 ;Check if user selected entry item 3 + je Prog3Jmp ;If so, jump to that program + + cmp eax, 4 ;Check if user selected exit + je MainExit ;If so, jump to end of program + + call ClrScr ;Clear screeen + INVOKE Write_String_NL, OFFSET IncorrectNumberEntry ;Scold user for not entering one to four + call ReadInt ;Wait for enter key + jmp MainTitle ;Jump back to main screen + +Prog1Jmp: + call Program1 ;Call array reverse program + call Crlf ;Print new line + INVOKE Write_String_NL, OFFSET ReturnToSelect ;Print hit enter to return to screen + call ReadInt ;Wait for enter + jmp MainTitle ;Jump to main screen +Prog2Jmp: + call Program2 ;Call String frequency program + call Crlf ;Print new line + INVOKE Write_String_NL, OFFSET ReturnToSelect ;Print hit enter to return to screen + call ReadInt ;Wait for enter + jmp MainTitle ;Jump to main screen +Prog3Jmp: + call Program3 ;Call prime generator program + call Crlf ;Print new line + INVOKE Write_String_NL, OFFSET ReturnToSelect ;Print hit enter to return to screen + call ReadInt ;Wait for enter + jmp MainTitle ;Jump to main screen +MainExit: + exit +main ENDP + +END main \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/Tasks.docx b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/Tasks.docx new file mode 100644 index 0000000..806b62c Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 5/Tasks.docx differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/ASM_Project.exe b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/ASM_Project.exe new file mode 100644 index 0000000..9f6f522 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/ASM_Project.exe differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.opensdf b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.opensdf new file mode 100644 index 0000000..7f3b791 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.opensdf differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.sdf b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.sdf new file mode 100644 index 0000000..ad1cecb Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.sdf differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.sln b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.sln new file mode 100644 index 0000000..6669396 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ASM_Project", "Assignment6.vcxproj", "{4164AA65-1EF9-4E69-899B-D1BED776070B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Debug|Win32.ActiveCfg = Debug|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Debug|Win32.Build.0 = Debug|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Release|Win32.ActiveCfg = Release|Win32 + {4164AA65-1EF9-4E69-899B-D1BED776070B}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.user b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.v12.suo b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.v12.suo new file mode 100644 index 0000000..3785692 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.v12.suo differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.v52.suo b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.v52.suo new file mode 100644 index 0000000..e35f81a Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.v52.suo differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.vcxproj b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.vcxproj new file mode 100644 index 0000000..d85431e --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Assignment6.vcxproj @@ -0,0 +1,79 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + {4164AA65-1EF9-4E69-899B-D1BED776070B} + ASM_Project + + + + Application + v120 + + + Application + v120 + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + $(Configuration)\ + + + + c:\Irvine + + + user32.lib;irvine32.lib;%(AdditionalDependencies) + c:\Irvine;%(AdditionalLibraryDirectories) + true + Console + false + + + false + + + + + false + + + c:\Irvine;%(AdditionalLibraryDirectories) + Console + false + user32.lib;irvine32.lib;%(AdditionalDependencies) + + + c:\Irvine + + + + + + + \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/CS271_proj6_perrenc.asm b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/CS271_proj6_perrenc.asm new file mode 100644 index 0000000..81eb7f3 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/CS271_proj6_perrenc.asm @@ -0,0 +1,632 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +TITLE Assignment 6 (main.asm) +;Author: Corwin Perren +;Date: 3/13/2014 +;Description: +; This program runs all five programs from assignment 6 from a menu screen +; These programs include a letter matrix generator, array row sum calculator, +; a floating point comparator, circle area computer, and quadratic formula +; calculator +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +INCLUDE Irvine32.inc + +.data + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Program Variables +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Global Relevant Variables +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +ProgramTitle BYTE "CS 271 - Assignment 6",0 +ProgrammerName BYTE "Written by: Corwin Perren",0 + +SelectInstructions BYTE "Please enter 1-6 to run desired program.", 0 + +MenuItem1 BYTE "1: Letter Matrix Generator (Chapter 9, Exercise 10)",0 +MenuItem2 BYTE "2: Two Dimensional Array Row Summer (Chapter 9, Exercise 12)",0 +MenuItem3 BYTE "3: Floating Point Comparator (Chapter 12, Exercise 1)",0 +MenuItem4 BYTE "4: Area of Circle Calculator (Chapter 12, Exercise 5)",0 +MenuItem5 BYTE "5: Quadratic Formula Calculator (Chapter 12, Exercise 6)",0 +MenuItem6 BYTE "6: Exit",0 + +Selection BYTE "Selection: ",0 + +IncorrectNumberEntry BYTE "You did not enter 1-7. Press enter to try again.", 0 +ReturnToSelect BYTE "Program Complete. Press enter to return to selection screen.", 0 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Letter Matrix Generator Variables +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +NumVowels DWORD 6 +VowelArray BYTE "AEIOUY" +NumConsonants DWORD 20 +ConsonantArray BYTE "BCDFGHJKLMNPQRSTVWXZ" + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Two Dimensional Array Row Summer Variables +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +CurrentArrayContents BYTE "Array Contents:",0 + +TableRow1 BYTE "1 2 3 4 5",0 ;For printing to display only +TableRow2 BYTE "6 7 8 9 10",0 ;For printing to display only +TableRow3 BYTE "11 12 13 14 15",0 ;For printing to display only +TableRow4 BYTE "16 17 18 19 20",0 ;For printing to display only +TableRow5 BYTE "21 22 23 24 25",0 ;For printing to display only + + +SummerPleaseEnterIndex BYTE "Enter a row to sum between 1 and 5.",0 +SummerIndexPrompt BYTE "Row: ",0 + +TableArrayIndex DWORD ? + +TableArrayBYTE BYTE 1,2,3,4,5 ;Row 1 +TableArrayRowSizeBYTE = ($-TableArrayBYTE) ;Size of single row + BYTE 6,7,8,9,10 ;Row 2 + BYTE 11,12,13,14,15 ;Row 3 + BYTE 16,17,18,19,20 ;Row 4 + BYTE 21,22,23,24,25 ;Row 5 + +TableArrayWORD WORD 1,2,3,4,5 ;Row 1 +TableArrayRowSizeWORD = ($-TableArrayWORD) ;Size of single row + WORD 6,7,8,9,10 ;Row 2 + WORD 11,12,13,14,15 ;Row 3 + WORD 16,17,18,19,20 ;Row 4 + WORD 21,22,23,24,25 ;Row 5 + +TableArrayDWORD DWORD 1,2,3,4,5 ;Row 1 +TableArrayRowSizeDWORD = ($-TableArrayDWORD) ;Size of single row + DWORD 6,7,8,9,10 ;Row 2 + DWORD 11,12,13,14,15 ;Row 3 + DWORD 16,17,18,19,20 ;Row 4 + DWORD 21,22,23,24,25 ;Row 5 + + +SummerBYTE BYTE "Sum using BYTE array: ",0 +SummerWORD BYTE "Sum using WORD array: ",0 +SummerDWORD BYTE"Sum using DWORD array: ",0 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Floating Point Comparator Variables +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +EnterTwoFloat BYTE "Please enter two floating point numbers to compare.",0 +Float1Prompt BYTE "First Number : ", 0 +Float2Prompt BYTE "Second Number: ", 0 + +FirstLargerThanFloat BYTE "The first value you entered was larger than the second.", 0 +SecondLargerThanFloat BYTE "The second value you entered was larger than the first.", 0 +EqualFloat BYTE "The numbers you entered were equal",0 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Area of Circle Calculator Variables +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +EnterRadius BYTE "Enter the radius of a circle to calculate it's area.",0 +RadiusPrompt BYTE "Radius: ",0 + +CircleAreaCalculated BYTE "The area for this circle is: ",0 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Quadratic Formula Calculator Variables +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +PleaseEnterCoeff BYTE "Please enter coefficients a, b, and c for a quadratic forumula in the form", 10, 13, "ax",253," + bx + c = 0 to calculate it's real roots.",0 +RootsNonRealMsg BYTE "These coefficients result in non-real roots. Exiting.",0 + +Root1Msg BYTE "Root1: ",0 +Root2Msg BYTE "Root2: ",0 + +CoeffA BYTE "a: ",0 +CoeffB BYTE "b: ",0 +CoeffC BYTE "c: ",0 + +Stores2 DWORD 2 +Stores4 DWORD 4 + +FloatA REAL10 ? +FloatB REAL10 ? +FloatC REAL10 ? + +AfterRootTaken REAL10 ? +Root1 REAL10 ? +Root2 REAL10 ? + +.code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Globally Useful Procedures +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure for writing string with newline +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Write_String_NL PROC uses EDX, + StringPtr:Ptr BYTE ;Varible to store string offset pointer + + mov edx, StringPtr ;Moves the string to the proper register + call WriteString ;Prints the string + call Crlf ;Prints a new line + + ret ;Return from procedure +Write_String_NL ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure for writing string without newline + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Write_String PROC uses EDX, + StringPtr:Ptr BYTE ;Variable to store string offset pointer + + mov edx, StringPtr ;Moves the string to the proper registers + call WriteString ;Prints the string + + ret +Write_String ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure for printing program title and programmer name + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +PrintTitle PROC + INVOKE Write_String_NL, OFFSET ProgramTitle ;Prints the program title + INVOKE Write_String_NL, OFFSET ProgrammerName ;prints the programmer's name + call Crlf ;Prints a new line + INVOKE Write_String_NL, OFFSET SelectInstructions ;Prints the selection screen instructions + call Crlf ;Prints a new line + INVOKE Write_String_NL, OFFSET MenuItem1 ;Prints menu item 1 + INVOKE Write_String_NL, OFFSET MenuItem2 ;Prints menu item 2 + INVOKE Write_String_NL, OFFSET MenuItem3 ;Prints menu item 3 + INVOKE Write_String_NL, OFFSET MenuItem4 ;Prints menu item 4 + INVOKE Write_String_NL, OFFSET MenuItem5 ;Prints menu item 2 + INVOKE Write_String_NL, OFFSET MenuItem6 ;Prints menu item 3 + INVOKE Write_String, OFFSET Selection ;Print selction prompt + ret +PrintTitle ENDP + +ClearFPU PROC + FFREE ST(0) + FFREE ST(1) + FFREE ST(2) + FFREE ST(3) + FFREE ST(4) + FFREE ST(5) + FFREE ST(6) + FFREE ST(7) + ret +ClearFPU ENDP +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Letter Matrix Generator Procedures +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure returns a random consonant + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +GetRandomConsonant PROC uses EBX + mov EAX, NumConsonants ;Set up range for random generator + mov EBX, offset ConsonantArray ;Move ConsonantArray into ebp for dereferencing + call RandomRange ;Get random number within range + add EBX, EAX ;Point to element in ebp + mov AL, [EBX] ;Store pointed to value in AL + ret ;Return from procedure +GetRandomConsonant ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure returns a random vowel + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +GetRandomVowel PROC uses EBX + mov EAX, NumVowels ;Set up range for random generator + mov EBX, offset VowelArray ;Move VowelArray into ebp for dereferencing + call RandomRange ;Get random number within range + add EBX, EAX ;Point to element in ebp + mov AL, [EBX] ;Store pointed to value in AL + ret ;Return from procedure +GetRandomVowel ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure prints the matrixes in proper rows with random chars + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +PrintMatrix PROC uses EAX ECX EDX + mov ECX, 4 ;Move column count into ECX +PrintLineLoop: + mov EDX, 4 ;Move row count into EDX + call CrLf ;Print new line +PrintShortLoop: + mov EAX, 2 ;Put in range for RandomRange of 2 (0-1) + call RandomRange ;Get random 0 to 1 + cmp EAX, 0 ;Check if zero + jnz GetConsonant ;If one, print consonant + call GetRandomVowel ;Get Vowel from generator + jmp WriteCharToMatrix ;Go print the character +GetConsonant: + call GetRandomConsonant ;Get consonant from generator +WriteCharToMatrix: + call WriteChar ;Print current character + dec EDX ;Move forward one column + jnz PrintShortLoop ;Repeat column print until at column end + dec ECX ;Move down one row + jnz PrintLineLoop ;Print out column on new row + call CrLf ;Print a new line + ret ;Return from procedure +PrintMatrix ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure for running program1 functions + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Program1 PROC + call ClrScr + call Randomize ;Seeds the random number generator + mov ECX, 5 ;Set loop counter to 5 to display matrix five times +Program1Loop: + call PrintMatrix ;Call procedure to print out one matrix + loop Program1Loop ;Continue printing until 5 arrays are one screen + ret ;Return from Program1 procedure +Program1 ENDP + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Two Dimensional Array Row Summer Procedures +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure calculates the sum for a row using stack passed parameters + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Calc_Row_Sum PROC + + mov ebp, esp ;Get access to the stack + mov ebx, [ebp+4] ;Save users selected row index + dec ebx ;Remove one to make math simpler + + mov edx, [ebp+8] ;Save table type + + mov ecx, [ebp+12] ;Setup counter with row length + mov esi, [ebp+16] ;Move array into array reg + + + cmp edx, 1 ;Check if it's a BYTE + je RowSumBYTE ;Jump if BYTE + + cmp edx, 2 ;Check if it's a WORD + je RowSumWORD ;Jump if WORD + + cmp edx, 4 ;Check if DWORD + je RowSumDWORD ;Jump if DWORD + +RowSumBYTE: + mov eax, ecx ;Move row length into eax + mul ebx ;Mutiply by row index + add esi, eax ;Add this offset to esi + mov eax, 0 ;Zero accumulator +RowSumBYTELoop: + add al, [esi] ;Add value to al + inc esi ;Move to the next value in the array + loop RowSumBYTELoop ;Loop until row finished + jmp CalcRowSumEnd ;Jump when finished + +RowSumWORD: + push edx ;Save EDX to stack + mov eax, ecx ;Set up multiplication of 2 + mul ebx ;Multiply user index by two (Now if WORD format) + add esi, eax ;Move cursor to index location using offset + pop edx ;Return EDX to reg + + mov ebx, edx ;Store TYPE in EBX + mov edx, 0 ;Zero upper half for multiplication + mov eax, ecx ;Set lower half to row size + div ebx ;Divide by TYPE + mov ecx, eax ;Set this number in the loop count reg + + mov eax, 0 ;Zero accumulator +RowSumWORDLoop: + add ax, [esi] ;Add value to ax + add esi, 2 ;Move to the next value in the array + loop RowSumWORDLoop ;Loop until row finished + jmp CalcRowSumEnd ;Jump when finished + +RowSumDWORD: + push edx ;Save EDX to stack + mov eax, ecx ;Set up multiplication of 4 + mul ebx ;Multiply user index by four (Now in DWORD format) + add esi, eax ;Move cursor to index location using offset + pop edx ;Return EDX to reg + + mov ebx, edx ;Store TYPE in EBX + mov edx, 0 ;Zero upper half for multiplication + mov eax, ecx ;Set lower half to row size + div ebx ;Divide by TYPE + mov ecx, eax ;Set this number in the loop count reg + + mov eax, 0 ;Zero accumulator +RowSumDWORDLoop: + add eax, [esi] ;Add value to ax + add esi, 4 ;Move to the next value in the array + loop RowSumDWORDLoop ;Loop until row finished + +CalcRowSumEnd: + ret ;Return from procedure +Calc_Row_Sum ENDP + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Program2 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Program2 PROC + call ClrScr ;Clears the screen + INVOKE Write_String_NL, OFFSET CurrentArrayContents ;Prints out array contents header + INVOKE Write_String_NL, OFFSET TableRow1 ;Prints table row 1 + INVOKE Write_String_NL, OFFSET TableRow2 ;Prints table row 2 + INVOKE Write_String_NL, OFFSET TableRow3 ;Prints table row 3 + INVOKE Write_String_NL, OFFSET TableRow4 ;Prints table row 4 + INVOKE Write_String_NL, OFFSET TableRow5 ;Prints table row 5 + + INVOKE Write_String_NL, OFFSET SummerPleaseEnterIndex ;Asks user to enter index value + INVOKE Write_String, OFFSET SummerIndexPrompt ;Row prompt for niceity + call ReadInt ;Read in Index from user + mov TableArrayIndex, EAX ;Moves user selection into variable + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Using BYTES + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push OFFSET TableArrayBYTE ;Pushes the offset for the table array (32-bit) + + mov eax, 0 ;Clears the eax register + mov eax, TableArrayRowSizeBYTE ;Moves the table array row size into eax + push eax ;Pushes that number onto the stack (32-bit) + + mov eax, 0 ;Clears the eax register + mov eax, TYPE TableArrayBYTE ;Moves the type of table array into eax + push eax ;Pushes the type of the array onto the stack (32-bit) + + push TableArrayIndex ;Pushes the index selected by the user onto the stack (32-bit) + call Calc_Row_Sum ;Calculates sum for row and prints it + INVOKE Write_String, OFFSET SummerBYTE ;Prints out what array was used to sum + call WriteInt ;Writes to display + call Crlf ;Prints a new line + add esp, 16 ;Cleanup the stack (4 times 32-bit) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Using WORDS + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push OFFSET TableArrayWORD ;Pushes the offset for the table array (32-bit) + + mov eax, 0 ;Clears the eax register + mov eax, TableArrayRowSizeWORD ;Moves the table array row size into eax + push eax ;Pushes that number onto the stack (32-bit) + + mov eax, 0 ;Clears the eax register + mov eax, TYPE TableArrayWORD ;Moves the type of table array into eax + push eax ;Pushes the type of the array onto the stack (32-bit) + + push TableArrayIndex ;Pushes the index selected by the user onto the stack (32-bit) + call Calc_Row_Sum ;Calculates sum for row and prints it + INVOKE Write_String, OFFSET SummerWORD ;Prints out what array was used to sum + call WriteInt ;Writes sum to display + call Crlf ;Prints a new line + add esp, 16 ;Cleanup the stack (4 times 32-bit) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Using DWORDS + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push OFFSET TableArrayDWORD ;Pushes the offset for the table array (32-bit) + + mov eax, 0 ;Clears the eax register + mov eax, TableArrayRowSizeDWORD ;Moves the table array row size into eax + push eax ;Pushes that number onto the stack (32-bit) + + mov eax, 0 ;Clears the eax register + mov eax, TYPE TableArrayDWORD ;Moves the type of table array into eax + push eax ;Pushes the type of the array onto the stack (32-bit) + + push TableArrayIndex ;Pushes the index selected by the user onto the stack (32-bit) + call Calc_Row_Sum ;Calculates sum for row and prints it + INVOKE Write_String, OFFSET SummerDWORD ;Prints out what array was used to sum + call WriteInt ;Writes sum to the screen + + add esp, 16 ;Cleanup the stack (4 times 32-bit) + ret ;Return from Program2 procedure +Program2 ENDP + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Floating Point Comparator Procedures +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure runs program 3 functions + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Program3 PROC + call ClrScr + INVOKE Write_String_NL, OFFSET EnterTwoFloat ;Prompt to enter two floating point numbers + INVOKE Write_String, OFFSET Float1Prompt ;Prompt for first val + call ReadFloat ;Read in value + INVOKE Write_String, OFFSET Float2Prompt ;Prompt for second val + call ReadFloat ;Read in value + call CRLF ;Print newline + FCOMI ST(0), ST(1) ;Compare second value entered to first + ja SecondWasGreater ;If the second is above the first, it's greater so jump + INVOKE Write_String_NL, OFFSET FirstLargerThanFloat ;Otherwise, the first was greater and we print a message saying so + jmp Prog3Ending ;Then we jump to program end + +SecondWasGreater: + INVOKE Write_String_NL, OFFSET SecondLargerThanFloat ;In the case the second is greater than the first, we will print that instead + +Prog3Ending: + ret ;Return from Program3 procedure +Program3 ENDP + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Area of Circle Calculator Procedures +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure runs program 4 functions + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Program4 PROC + call ClrScr ;Clear the screen + INVOKE Write_String_NL, OFFSET EnterRadius ;Prompt the user to enter the radius + INVOKE Write_String, OFFSET RadiusPrompt ;Provide nice header + FLDPI ;Load pi onto floating point unit stack + call ReadFloat ;Read in float from user + fld ST(0) ;Load a second radius onto floating point stack + FMULP ;Mulitply and pop + FMULP ;Multiply and pop + INVOKE Write_String, OFFSET CircleAreaCalculated ;Print header for final value + call WriteFloat ;Write calculated value to screen + FFREE ST(0) ;Free FPU stack + ret ;Return from Program4 procedure +Program4 ENDP + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Quadratic Formula Calculator Procedures +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure reads in float coefficients from user + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +GetCoefficients PROC + INVOKE Write_String_NL, OFFSET PleaseEnterCoeff ;Asks user to enter coefficients + call Crlf ;Prints a new line + + INVOKE Write_String, OFFSET CoeffA ;Asks for a + call ReadFloat ;Reads in a + + INVOKE Write_String, OFFSET CoeffB ;Asks for b + call ReadFloat ;Reads in b + + INVOKE Write_String, OFFSET CoeffC ;Asks for c + call ReadFloat ;Reads in c + + FSTP FloatC ;Store coeff c in var + FSTP FloatB ;Store coeff b in var + FSTP FloatA ;Store coeff a in var + ret ;Return from procedure +GetCoefficients ENDP + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Procedure runs program5 functions + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Program5 PROC + call ClrScr ;Clear the screen + call GetCoefficients ;Reading in coefficients from user + + FLD FLoatB ;Load b + FMUL ST(0), ST(0) ;Square b + FLD FloatA ;Load a + FLD FloatC ;Load c + FIMUL Stores4 ;Multiply c by 4 + FMULP ST(1), ST(0) ;End result is 4*a*c + FSUBP ST(1), ST(0) ;End result is b^2-4ac + FLDZ ;Load zero onto stack for comparison + FCOMIP ST(0), ST(1) ;Check if roots are going to be real or not + ja NonRealRoots ;Jump to message if roots are non-real and exit + FSQRT ;Take square root as it's real + FSTP AfterRootTaken ;Store for use later on other root + + FLD FloatB ;Load b + FCHS ;Negate b + FLD AfterRootTaken ;Load rooted val + FSUB ;Subtract rooted val from negated b (-b - sqrt(b^2-4ac)) + FLD FloatA ;Load a + FIMUL Stores2 ;Multiply a by 2 + FDIV ;Divide numerator by denominator + FSTP Root1 ;Store first root value + + FLD FloatB ;Load b + FCHS ;Negate b + FLD AfterRootTaken ;Load rooted val + FADD ;Add rooted val from negated b (-b - sqrt(b^2-4ac)) + FLD FloatA ;Load a + FIMUL Stores2 ;Multiply a by 2 + FDIV ;Divide numerator by denominator + FSTP Root2 ;Store second root value + + call Crlf + + INVOKE Write_String, OFFSET Root1Msg ;Print Root1 Header + FLD Root1 ;Load root1 into register + call WriteFloat ;Print root1 + FFREE ST(0) ;Free FPU register + call Crlf ;Print new line + + INVOKE Write_String, OFFSET Root2Msg ;Print root2 header + FLD Root2 ;Load root2 into register + call WriteFloat ;Print root2 + FFREE ST(0) ;Free FPU register + call Crlf ;Print a new line + + jmp Program5Ending ;Jump to program end + + +NonRealRoots: + FFREE ST(0) ;Free up register so it can be used again + INVOKE Write_String_NL, OFFSET RootsNonRealMsg ;Print message saying there are no real roots + +Program5Ending: + ret ;Return from Program5 procedure +Program5 ENDP + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Program Main Function +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;Main Procedure + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +main PROC + FINIT ;Initialize floating point unit +MainTitle: + call ClrScr ;Clear screen + call PrintTitle ;Print the title screen + call ReadInt ;Read in user selection + + cmp eax, 1 ;Check if user selected entry item 1 + je Prog1Jmp ;If so, jump to that program + + cmp eax, 2 ;Check if user selected entry item 2 + je Prog2Jmp ;If so, jump to that program + + cmp eax, 3 ;Check if user selected entry item 3 + je Prog3Jmp ;If so, jump to that program + + cmp eax, 4 ;Check if user selected entry item 4 + je Prog4Jmp ;If so, jump to that program + + cmp eax, 5 ;Check if user selected entry item 5 + je Prog5Jmp ;If so, jump to that program + + cmp eax, 6 ;Check if user selected exit + je MainExit ;If so, jump to end of program + + + call ClrScr ;Clear screeen + INVOKE Write_String_NL, OFFSET IncorrectNumberEntry ;Scold user for not entering one to six + call ReadInt ;Wait for enter key + jmp MainTitle ;Jump back to main screen + +Prog1Jmp: + call Program1 ;Call program1 + call Crlf ;Print new line + INVOKE Write_String_NL, OFFSET ReturnToSelect ;Print hit enter to return to screen + call ReadInt ;Wait for enter + jmp MainTitle ;Jump to main screen +Prog2Jmp: + call Program2 ;Call program2 + call Crlf ;Print new line + INVOKE Write_String_NL, OFFSET ReturnToSelect ;Print hit enter to return to screen + call ReadInt ;Wait for enter + jmp MainTitle ;Jump to main screen +Prog3Jmp: + call ClearFPU ;Empties FPU Registers to keep things from crashing + call Program3 ;Call program3 + call Crlf ;Print new line + INVOKE Write_String_NL, OFFSET ReturnToSelect ;Print hit enter to return to screen + call ReadInt ;Wait for enter + jmp MainTitle ;Jump to main screen +Prog4Jmp: + call ClearFPU ;Empties FPU Registers to keep things from crashing + call Program4 ;Call program4 + call Crlf ;Print new line + INVOKE Write_String_NL, OFFSET ReturnToSelect ;Print hit enter to return to screen + call ReadInt ;Wait for enter + jmp MainTitle ;Jump to main screen +Prog5Jmp: + call ClearFPU ;Empties FPU Registers to keep things from crashing + call Program5 ;Call program5 + call Crlf ;Print new line + INVOKE Write_String_NL, OFFSET ReturnToSelect ;Print hit enter to return to screen + call ReadInt ;Wait for enter + jmp MainTitle ;Jump to main screen +MainExit: + exit +main ENDP + +END main \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Tasks.docx b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Tasks.docx new file mode 100644 index 0000000..4eeee49 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Assignments/Assignment 6/Tasks.docx differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/CS271_perrenc_FinalPaper.pdf b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/CS271_perrenc_FinalPaper.pdf new file mode 100644 index 0000000..eeee5d1 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/CS271_perrenc_FinalPaper.pdf differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.axf b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.axf new file mode 100644 index 0000000..572d5ac Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.axf differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.build_log.htm b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.build_log.htm new file mode 100644 index 0000000..b36afee --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.build_log.htm @@ -0,0 +1,25 @@ + + +
+

µVision Build Log

+

Project:

+D:\Google Drive\_School\Current Term\CS 271\Final Paper\Code\Program1\ARMv7\Proj.uvproj +Project File Date: 03/18/2014 + +

Output:

+Rebuild target 'Target 1' +assembling assem.s... +linking... +Program Size: Code=96 RO-data=0 RW-data=0 ZI-data=0 +".\Proj.axf" - 0 Error(s), 0 Warning(s). +
+ + +.\Proj.axf" - 2 Error(s), 0 Warning(s). +Target not created +(s). +Target not created +g(s). +Target not created +" - 3 Error(s), 0 Warning(s). +Target not created diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.htm b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.htm new file mode 100644 index 0000000..bf8112e --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.htm @@ -0,0 +1,20 @@ + + +Static Call Graph - [.\Proj.axf] +
+

Static Call Graph for image .\Proj.axf


+

#<CALLGRAPH># ARM Linker, 5.03 [Build 76]: Last Updated: Tue Mar 18 03:46:41 2014 +

+

Maximum Stack Usage = 0 bytes

+Call chain for Maximum Stack Depth:

+ +

+

+Global Symbols +

+

+Local Symbols +

+

+Undefined Global Symbols +


diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.lnp b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.lnp new file mode 100644 index 0000000..5941464 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.lnp @@ -0,0 +1,5 @@ +--cpu ARM7TDMI +".\assem.o" +--ro-base 0x00000000 --entry 0x00000000 --rw-base 0x00000000 --strict --summary_stderr --info summarysizes --map --xref --callgraph --symbols +--info sizes --info totals --info unused --info veneers +--list ".\Proj.map" -o .\Proj.axf \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.map b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.map new file mode 100644 index 0000000..4cfb908 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.map @@ -0,0 +1,89 @@ +ARM Linker, 5.03 [Build 76] [MDK-ARM Lite] + +============================================================================== + +Section Cross References + + + +============================================================================== + +Image Symbol Table + + Local Symbols + + Symbol Name Value Ov Type Size Object(Section) + + ConstrainProg 0x00000000 Section 96 assem.o(ConstrainProg) + assem.s 0x00000000 Number 0 assem.o ABSOLUTE + + Global Symbols + + Symbol Name Value Ov Type Size Object(Section) + + BuildAttributes$$THM_ISAv1$ARM_ISAv4$S$PE$A:L22$X:L11$S22$IEEE1$IW$USESV6$~STKCKD$USESV7$~SHL$OSPACE$EBA8$STANDARDLIB$EABIv2 0x00000000 Number 0 anon$$obj.o ABSOLUTE + + + +============================================================================== + +Memory Map of the image + + Image Entry point : 0x00000000 + + Load Region LR_1 (Base: 0x00000000, Size: 0x00000060, Max: 0xffffffff, ABSOLUTE) + + Execution Region ER_RO (Base: 0x00000000, Size: 0x00000000, Max: 0xffffffff, ABSOLUTE) + + **** No section assigned to this execution region **** + + + Execution Region ER_RW (Base: 0x00000000, Size: 0x00000060, Max: 0xffffffff, ABSOLUTE) + + Base Addr Size Type Attr Idx E Section Name Object + + 0x00000000 0x00000060 Code RW 1 * ConstrainProg assem.o + + + Execution Region ER_ZI (Base: 0x00000060, Size: 0x00000000, Max: 0xffffffff, ABSOLUTE) + + **** No section assigned to this execution region **** + + +============================================================================== + +Image component sizes + + + Code (inc. data) RO Data RW Data ZI Data Debug Object Name + + 96 16 0 0 0 248 assem.o + + ---------------------------------------------------------------------- + 96 16 0 0 0 248 Object Totals + 0 0 0 0 0 0 (incl. Generated) + 0 0 0 0 0 0 (incl. Padding) + + ---------------------------------------------------------------------- + 0 0 0 0 0 0 Library Totals + 0 0 0 0 0 0 (incl. Padding) + + ---------------------------------------------------------------------- + +============================================================================== + + + Code (inc. data) RO Data RW Data ZI Data Debug + + 96 16 0 0 0 248 Grand Totals + 96 16 0 0 0 248 ELF Image Totals + 96 16 0 0 0 0 ROM Totals + +============================================================================== + + Total RO Size (Code + RO Data) 96 ( 0.09kB) + Total RW Size (RW Data + ZI Data) 0 ( 0.00kB) + Total ROM Size (Code + RO Data + RW Data) 96 ( 0.09kB) + +============================================================================== + diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.uvgui.corwin b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.uvgui.corwin new file mode 100644 index 0000000..bc52162 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.uvgui.corwin @@ -0,0 +1,2601 @@ + + + + -4.1 + +
### uVision Project, (C) Keil Software
+ + + + + + 38003 + Registers + 115 255 + + + 346 + Code Coverage + 1350 160 + + + 204 + Performance Analyzer + 1510 226 226 100 + + + + + + 1506 + Symbols + + 133 133 133 + + + 1936 + Watch 1 + + 133 133 133 + + + 1937 + Watch 2 + + 133 133 133 + + + 1935 + Call Stack + Locals + + 133 133 133 + + + 2506 + Trace Data + + 75 135 130 95 70 230 200 + + + + + + 0 + 0 + 0 + + + + + + + 44 + 0 + 1 + + -1 + -1 + + + -1 + -1 + + + 321 + 312 + 2232 + 1350 + + + + 0 + + 280 + 01000000040000000100000001000000010000000100000000000000020000000000000001000000010000000000000028000000280000000100000001000000000000000100000053443A5C476F6F676C652044726976655C5F5363686F6F6C5C43757272656E74205465726D5C4353203237315C46696E616C2050617065725C436F64655C50726F6772616D315C41524D76375C617373656D2E730000000007617373656D2E7300000000FFDC7800FFFFFFFF0100000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD500010000000000000002000000C0020000AF010000B008000061040000 + + + + 0 + Build + + -1 + -1 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 800100004F0000007007000015010000 + + + 16 + C0020000AF010000B008000075020000 + + + + 1005 + 1005 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000E8020000 + + + 16 + 560000006D000000D201000085030000 + + + + 109 + 109 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000E8020000 + + + 16 + 560000006D000000D201000085030000 + + + + 1465 + 1465 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1466 + 1466 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1467 + 1467 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1468 + 1468 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1506 + 1506 + 0 + 0 + 0 + 0 + 32767 + 0 + 16384 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 1913 + 1913 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1935 + 1935 + 0 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 1936 + 1936 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 1937 + 1937 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 1939 + 1939 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1940 + 1940 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1941 + 1941 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1942 + 1942 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 195 + 195 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000E8020000 + + + 16 + 560000006D000000D201000085030000 + + + + 196 + 196 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000E8020000 + + + 16 + 560000006D000000D201000085030000 + + + + 197 + 197 + 1 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 000000001903000070070000CB030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 198 + 198 + 0 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 00000000F102000070070000CB030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 199 + 199 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000001C0300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 203 + 203 + 0 + 0 + 0 + 0 + 32767 + 0 + 8192 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 204 + 204 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 221 + 221 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 00000000000000000000000000000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 2506 + 2506 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 2507 + 2507 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 343 + 343 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 346 + 346 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 35824 + 35824 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 35885 + 35885 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35886 + 35886 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35887 + 35887 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35888 + 35888 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35889 + 35889 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35890 + 35890 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35891 + 35891 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35892 + 35892 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35893 + 35893 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35894 + 35894 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35895 + 35895 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35896 + 35896 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35897 + 35897 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35898 + 35898 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35899 + 35899 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35900 + 35900 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35901 + 35901 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35902 + 35902 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35903 + 35903 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35904 + 35904 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35905 + 35905 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 38003 + 38003 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000E8020000 + + + 16 + 560000006D000000D201000085030000 + + + + 38007 + 38007 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000001C0300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 436 + 436 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000001C0300006D070000B2030000 + + + 16 + 560000006D000000D201000085030000 + + + + 437 + 437 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 440 + 440 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 59392 + 59392 + 1 + 0 + 0 + 0 + 940 + 0 + 8192 + 0 + + 16 + 0000000000000000B70300001C000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59393 + 0 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 00000000CB03000070070000DE030000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59399 + 59399 + 1 + 0 + 0 + 0 + 439 + 0 + 8192 + 1 + + 16 + 000000001C000000C201000038000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59400 + 59400 + 0 + 0 + 0 + 0 + 612 + 0 + 8192 + 2 + + 16 + 00000000380000006F02000054000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 2619 + 000000000B000000000000000020000000000000FFFFFFFFFFFFFFFF80010000150100007007000019010000000000000100000004000000010000000000000000000000FFFFFFFF06000000CB00000057010000CC000000F08B00005A01000079070000FFFF02000B004354616262656450616E650020000000000000C0020000AF010000B008000075020000800100004F00000070070000150100000000000040280046060000000B446973617373656D626C7900000000CB00000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A6572000000005701000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A657200000000CC00000001000000FFFFFFFFFFFFFFFF0E4C6F67696320416E616C797A657200000000F08B000001000000FFFFFFFFFFFFFFFF0D436F646520436F766572616765000000005A01000001000000FFFFFFFFFFFFFFFF11496E737472756374696F6E205472616365000000007907000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFCB00000001000000FFFFFFFFCB000000000000000040000000000000FFFFFFFFFFFFFFFFDC0500004F000000E005000001030000000000000200000004000000010000000000000000000000FFFFFFFF17000000E2050000CA0900002D8C00002E8C00002F8C0000308C0000318C0000328C0000338C0000348C0000358C0000368C0000378C0000388C0000398C00003A8C00003B8C00003C8C00003D8C00003E8C00003F8C0000408C0000418C00000180004000000000000020070000AF010000B008000061040000E00500004F00000070070000010300000000000040410046170000000753796D626F6C7300000000E205000001000000FFFFFFFFFFFFFFFF0A5472616365204461746100000000CA09000001000000FFFFFFFFFFFFFFFF00000000002D8C000001000000FFFFFFFFFFFFFFFF00000000002E8C000001000000FFFFFFFFFFFFFFFF00000000002F8C000001000000FFFFFFFFFFFFFFFF0000000000308C000001000000FFFFFFFFFFFFFFFF0000000000318C000001000000FFFFFFFFFFFFFFFF0000000000328C000001000000FFFFFFFFFFFFFFFF0000000000338C000001000000FFFFFFFFFFFFFFFF0000000000348C000001000000FFFFFFFFFFFFFFFF0000000000358C000001000000FFFFFFFFFFFFFFFF0000000000368C000001000000FFFFFFFFFFFFFFFF0000000000378C000001000000FFFFFFFFFFFFFFFF0000000000388C000001000000FFFFFFFFFFFFFFFF0000000000398C000001000000FFFFFFFFFFFFFFFF00000000003A8C000001000000FFFFFFFFFFFFFFFF00000000003B8C000001000000FFFFFFFFFFFFFFFF00000000003C8C000001000000FFFFFFFFFFFFFFFF00000000003D8C000001000000FFFFFFFFFFFFFFFF00000000003E8C000001000000FFFFFFFFFFFFFFFF00000000003F8C000001000000FFFFFFFFFFFFFFFF0000000000408C000001000000FFFFFFFFFFFFFFFF0000000000418C000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFE205000001000000FFFFFFFFE2050000000000000010000001000000FFFFFFFFFFFFFFFF7C0100004F0000008001000001030000010000000200001004000000010000000000000000000000FFFFFFFF05000000ED0300006D000000C3000000C4000000739400000180001000000100000040010000AF010000BC02000061040000000000004F0000007C010000010300000000000040140056050000000750726F6A65637401000000ED03000001000000FFFFFFFFFFFFFFFF05426F6F6B73010000006D00000001000000FFFFFFFFFFFFFFFF0946756E6374696F6E7301000000C300000001000000FFFFFFFFFFFFFFFF0954656D706C6174657301000000C400000001000000FFFFFFFFFFFFFFFF09526567697374657273000000007394000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFED03000001000000FFFFFFFFED030000000000000080000000000000FFFFFFFFFFFFFFFF00000000ED02000070070000F102000000000000010000000400000001000000000000000000000000000000000000000000000001000000C6000000FFFFFFFF0E0000008F070000930700009407000095070000960700009007000091070000B5010000B8010000B9050000BA050000BB050000BC050000CB090000018000800000000000004001000051040000B00800002B05000000000000F102000070070000CB03000000000000404100460E0000001343616C6C20537461636B202B204C6F63616C73000000008F07000001000000FFFFFFFFFFFFFFFF0755415254202331000000009307000001000000FFFFFFFFFFFFFFFF0755415254202332000000009407000001000000FFFFFFFFFFFFFFFF0755415254202333000000009507000001000000FFFFFFFFFFFFFFFF15446562756720287072696E74662920566965776572000000009607000001000000FFFFFFFFFFFFFFFF0757617463682031000000009007000001000000FFFFFFFFFFFFFFFF0757617463682032000000009107000001000000FFFFFFFFFFFFFFFF10547261636520457863657074696F6E7300000000B501000001000000FFFFFFFFFFFFFFFF0E4576656E7420436F756E7465727300000000B801000001000000FFFFFFFFFFFFFFFF084D656D6F7279203100000000B905000001000000FFFFFFFFFFFFFFFF084D656D6F7279203200000000BA05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203300000000BB05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203400000000BC05000001000000FFFFFFFFFFFFFFFF105472616365204E617669676174696F6E00000000CB09000001000000FFFFFFFFFFFFFFFFFFFFFFFF0000000001000000000000000000000001000000FFFFFFFFB8030000F1020000BC030000CB03000000000000020000000400000000000000000000000000000000000000000000000000000002000000C6000000FFFFFFFF8F07000001000000FFFFFFFF8F07000001000000C6000000000000000080000001000000FFFFFFFFFFFFFFFF00000000010300007007000005030000010000000100001004000000010000000000000000000000FFFFFFFF04000000C5000000C7000000B401000077940000018000800000010000004001000065040000B00800002B050000000000000503000070070000CB0300000000000040820056040000000C4275696C64204F757470757401000000C500000001000000FFFFFFFFFFFFFFFF0D46696E6420496E2046696C657300000000C700000001000000FFFFFFFFFFFFFFFF0A4572726F72204C69737400000000B401000001000000FFFFFFFFFFFFFFFF0742726F77736572000000007794000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFC500000001000000FFFFFFFFC5000000000000000000000000000000 + + + 59392 + File + + 2002 + 00200000010000002800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000040004000000000000000000000000000000000100000001000000018022E100000000040005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000004000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000004000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000004000C0000000000000000000000000000000001000000010000000180F4B00000000004000D000000000000000000000000000000000100000001000000018036B10000000004000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF88000000000400460000000000000000000000000000000001000000010000000180FE880000000004004500000000000000000000000000000000010000000100000001800B810000000004001300000000000000000000000000000000010000000100000001800C810000000004001400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F0880000020000000F000000000000000000000000000000000100000001000000FFFF0100120043555646696E64436F6D626F427574746F6EE803000000000000000000000000000000000000000000000001000000010000009600000002002050FFFFFFFF0096000000000000000000018024E10000000000001100000000000000000000000000000000010000000100000001800A810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000020000001500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000160000000000000000000000000000000001000000010000000180C988000000000400180000000000000000000000000000000001000000010000000180C788000000000000190000000000000000000000000000000001000000010000000180C8880000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E4C010000020000001A0000000F50726F6A6563742057696E646F7773000000000000000000000000010000000100000000000000000000000100000008002880DD880000000000001A0000000750726F6A656374000000000000000000000000010000000100000000000000000000000100000000002880DC8B0000000000003A00000005426F6F6B73000000000000000000000000010000000100000000000000000000000100000000002880E18B0000000000003B0000000946756E6374696F6E73000000000000000000000000010000000100000000000000000000000100000000002880E28B000000000000400000000954656D706C6174657300000000000000000000000001000000010000000000000000000000010000000000288018890000000000003D0000000E536F757263652042726F777365720000000000000000000000000100000001000000000000000000000001000000000028800000000000000400FFFFFFFF00000000000000000001000000000000000100000000000000000000000100000000002880D988000000000000390000000C4275696C64204F7574707574000000000000000000000000010000000100000000000000000000000100000000002880E38B000000000000410000000B46696E64204F75747075740000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001B000000000000000000000000000000000100000001000000000000000446696C65AC030000 + + + 1423 + 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E1000000000000FFFFFFFF000100000000000000010000000000000001000000018001E1000000000000FFFFFFFF000100000000000000010000000000000001000000018003E1000000000000FFFFFFFF0001000000000000000100000000000000010000000180CD7F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF000000000000000000010000000000000001000000018023E1000000000000FFFFFFFF000100000000000000010000000000000001000000018022E1000000000000FFFFFFFF000100000000000000010000000000000001000000018025E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802BE1000000000000FFFFFFFF00010000000000000001000000000000000100000001802CE1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001807A8A000000000000FFFFFFFF00010000000000000001000000000000000100000001807B8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180D3B0000000000000FFFFFFFF000100000000000000010000000000000001000000018015B1000000000000FFFFFFFF0001000000000000000100000000000000010000000180F4B0000000000000FFFFFFFF000100000000000000010000000000000001000000018036B1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FF88000000000000FFFFFFFF0001000000000000000100000000000000010000000180FE88000000000000FFFFFFFF00010000000000000001000000000000000100000001800B81000000000000FFFFFFFF00010000000000000001000000000000000100000001800C81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180F088000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE7F000000000000FFFFFFFF000100000000000000010000000000000001000000018024E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800A81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802280000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C488000000000000FFFFFFFF0001000000000000000100000000000000010000000180C988000000000000FFFFFFFF0001000000000000000100000000000000010000000180C788000000000000FFFFFFFF0001000000000000000100000000000000010000000180C888000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180DD88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FB7F000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 1423 + 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000000004000000000000000000000000000000000100000001000000018022E100000000000005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000000000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000000000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000000000C0000000000000000000000000000000001000000010000000180F4B00000000000000D000000000000000000000000000000000100000001000000018036B10000000000000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF880000000000000F0000000000000000000000000000000001000000010000000180FE880000000000001000000000000000000000000000000000010000000100000001800B810000000000001100000000000000000000000000000000010000000100000001800C810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F088000000000000130000000000000000000000000000000001000000010000000180EE7F00000000000014000000000000000000000000000000000100000001000000018024E10000000000001500000000000000000000000000000000010000000100000001800A810000000000001600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000180000000000000000000000000000000001000000010000000180C988000000000000190000000000000000000000000000000001000000010000000180C7880000000000001A0000000000000000000000000000000001000000010000000180C8880000000000001B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180DD880000000000001C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001D000000000000000000000000000000000100000001000000 + + + + 59399 + Build + + 643 + 00200000010000000F00FFFF01001100434D4643546F6F6C426172427574746F6ECF7F0000000000001C0000000000000000000000000000000001000000010000000180D07F0000000000001D000000000000000000000000000000000100000001000000018030800000000000001E00000000000000000000000000000000010000000100000001809E8A0000000004001F0000000000000000000000000000000001000000010000000180D17F0000000004002000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000004002100000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6EBA000000000000000000000000000000000000000000000000010000000100000096000000030020500000000008546172676574203196000000000000000100085461726765742031000000000180EB880000000000002200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000230000000000000000000000000000000001000000010000000180B08A000000000400240000000000000000000000000000000001000000010000000180A8010000000004004E0000000000000000000000000000000001000000010000000180BE010000000004005000000000000000000000000000000000010000000100000000000000054275696C64B7010000 + + + 548 + 0F00FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000FFFFFFFF0001000000000000000100000000000000010000000180D07F000000000000FFFFFFFF00010000000000000001000000000000000100000001803080000000000000FFFFFFFF00010000000000000001000000000000000100000001809E8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D17F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001804C8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001806680000000000000FFFFFFFF0001000000000000000100000000000000010000000180EB88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180B08A000000000000FFFFFFFF0001000000000000000100000000000000010000000180A801000000000000FFFFFFFF0001000000000000000100000000000000010000000180BE01000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 548 + 0F00FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000000000000000000000000000000000000001000000010000000180D07F00000000000001000000000000000000000000000000000100000001000000018030800000000000000200000000000000000000000000000000010000000100000001809E8A000000000000030000000000000000000000000000000001000000010000000180D17F0000000000000400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000000500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001806680000000000000060000000000000000000000000000000001000000010000000180EB880000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000080000000000000000000000000000000001000000010000000180B08A000000000000090000000000000000000000000000000001000000010000000180A8010000000000000A0000000000000000000000000000000001000000010000000180BE010000000000000B000000000000000000000000000000000100000001000000 + + + + 59400 + Debug + + 2220 + 00200000000000001900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000002500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000002600000000000000000000000000000000010000000100000001801D800000000000002700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000002800000000000000000000000000000000010000000100000001801B80000000000000290000000000000000000000000000000001000000010000000180E57F0000000000002A00000000000000000000000000000000010000000100000001801C800000000000002B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000002C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B0000000000002D0000000000000000000000000000000001000000010000000180F07F0000000000002E0000000000000000000000000000000001000000010000000180E8880000000000003700000000000000000000000000000000010000000100000001803B010000000000002F0000000000000000000000000000000001000000010000000180BB8A00000000000030000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E0E01000000000000310000000D57617463682057696E646F7773000000000000000000000000010000000100000000000000000000000100000002001380D88B000000000000310000000757617463682031000000000000000000000000010000000100000000000000000000000100000000001380D98B0000000000003100000007576174636820320000000000000000000000000100000001000000000000000000000001000000000013800F01000000000000320000000E4D656D6F72792057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380D28B00000000000032000000084D656D6F72792031000000000000000000000000010000000100000000000000000000000100000000001380D38B00000000000032000000084D656D6F72792032000000000000000000000000010000000100000000000000000000000100000000001380D48B00000000000032000000084D656D6F72792033000000000000000000000000010000000100000000000000000000000100000000001380D58B00000000000032000000084D656D6F727920340000000000000000000000000100000001000000000000000000000001000000000013801001000000000000330000000E53657269616C2057696E646F77730000000000000000000000000100000001000000000000000000000001000000040013809307000000000000330000000755415254202331000000000000000000000000010000000100000000000000000000000100000000001380940700000000000033000000075541525420233200000000000000000000000001000000010000000000000000000000010000000000138095070000000000003300000007554152542023330000000000000000000000000100000001000000000000000000000001000000000013809607000000000000330000000E49544D2F525441205669657765720000000000000000000000000100000001000000000000000000000001000000000013803C010000000000003400000010416E616C797369732057696E646F7773000000000000000000000000010000000100000000000000000000000100000003001380658A000000000000340000000E4C6F67696320416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380DC7F0000000000003E00000014506572666F726D616E636520416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380E788000000000000380000000D436F646520436F76657261676500000000000000000000000001000000010000000000000000000000010000000000138053010000000000003F0000000D54726163652057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013805401000000000000FFFFFFFF115472616365204D656E7520416E63686F720000000000000000010000000000000001000000000000000000000001000000000013802901000000000000350000001553797374656D205669657765722057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013804B01000000000000FFFFFFFF1453797374656D2056696577657220416E63686F720000000000000000010000000000000001000000000000000000000001000000000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000138001890000000000003600000007546F6F6C626F7800000000000000000000000001000000010000000000000000000000010000000300138044C5000000000000FFFFFFFF0E5570646174652057696E646F77730000000000000000010000000000000001000000000000000000000001000000000013800000000000000400FFFFFFFF000000000000000000010000000000000001000000000000000000000001000000000013805B01000000000000FFFFFFFF12546F6F6C626F78204D656E75416E63686F72000000000000000001000000000000000100000000000000000000000100000000000000000005446562756764020000 + + + 898 + 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801780000000000000FFFFFFFF00010000000000000001000000000000000100000001801D80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801A80000000000000FFFFFFFF00010000000000000001000000000000000100000001801B80000000000000FFFFFFFF0001000000000000000100000000000000010000000180E57F000000000000FFFFFFFF00010000000000000001000000000000000100000001801C80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800089000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180E48B000000000000FFFFFFFF0001000000000000000100000000000000010000000180F07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180E888000000000000FFFFFFFF00010000000000000001000000000000000100000001803B01000000000000FFFFFFFF0001000000000000000100000000000000010000000180BB8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D88B000000000000FFFFFFFF0001000000000000000100000000000000010000000180D28B000000000000FFFFFFFF00010000000000000001000000000000000100000001809307000000000000FFFFFFFF0001000000000000000100000000000000010000000180658A000000000000FFFFFFFF0001000000000000000100000000000000010000000180C18A000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE8B000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800189000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 898 + 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000000000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000000100000000000000000000000000000000010000000100000001801D800000000000000200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000000300000000000000000000000000000000010000000100000001801B80000000000000040000000000000000000000000000000001000000010000000180E57F0000000000000500000000000000000000000000000000010000000100000001801C800000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B000000000000080000000000000000000000000000000001000000010000000180F07F000000000000090000000000000000000000000000000001000000010000000180E8880000000000000A00000000000000000000000000000000010000000100000001803B010000000000000B0000000000000000000000000000000001000000010000000180BB8A0000000000000C0000000000000000000000000000000001000000010000000180D88B0000000000000D0000000000000000000000000000000001000000010000000180D28B0000000000000E000000000000000000000000000000000100000001000000018093070000000000000F0000000000000000000000000000000001000000010000000180658A000000000000100000000000000000000000000000000001000000010000000180C18A000000000000110000000000000000000000000000000001000000010000000180EE8B0000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180018900000000000013000000000000000000000000000000000100000001000000 + + + + 0 + 2560 + 1440 + + + + 1 + Debug + + -1 + -1 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 800100004F0000007007000015010000 + + + 16 + C0020000AF010000B008000075020000 + + + + 1005 + 1005 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000D4020000 + + + 16 + 560000006D000000D201000085030000 + + + + 109 + 109 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000D4020000 + + + 16 + 560000006D000000D201000085030000 + + + + 1465 + 1465 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1466 + 1466 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1467 + 1467 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1468 + 1468 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1506 + 1506 + 0 + 0 + 0 + 0 + 32767 + 0 + 16384 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 1913 + 1913 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1935 + 1935 + 1 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 1936 + 1936 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 1937 + 1937 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 1939 + 1939 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1940 + 1940 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1941 + 1941 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1942 + 1942 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 195 + 195 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000D4020000 + + + 16 + 560000006D000000D201000085030000 + + + + 196 + 196 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000D4020000 + + + 16 + 560000006D000000D201000085030000 + + + + 197 + 197 + 0 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 030000001C0300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 198 + 198 + 1 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 00000000F1020000B8030000CB030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 199 + 199 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000001C0300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 203 + 203 + 1 + 0 + 0 + 0 + 32767 + 0 + 8192 + 0 + + 16 + 80010000630000007007000015010000 + + + 16 + 560000006D0000000E04000033010000 + + + + 204 + 204 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 221 + 221 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 00000000000000000000000000000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 2506 + 2506 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 2507 + 2507 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 343 + 343 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 346 + 346 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 35824 + 35824 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 35885 + 35885 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35886 + 35886 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35887 + 35887 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35888 + 35888 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35889 + 35889 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35890 + 35890 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35891 + 35891 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35892 + 35892 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35893 + 35893 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35894 + 35894 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35895 + 35895 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35896 + 35896 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35897 + 35897 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35898 + 35898 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35899 + 35899 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35900 + 35900 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35901 + 35901 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35902 + 35902 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35903 + 35903 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35904 + 35904 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35905 + 35905 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 38003 + 38003 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000D4020000 + + + 16 + 560000006D000000D201000085030000 + + + + 38007 + 38007 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000001C0300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 436 + 436 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000001C0300006D070000B2030000 + + + 16 + 560000006D000000D201000085030000 + + + + 437 + 437 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 440 + 440 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 59392 + 59392 + 1 + 0 + 0 + 0 + 940 + 0 + 8192 + 0 + + 16 + 0000000000000000B70300001C000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59393 + 0 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 00000000CB03000070070000DE030000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59399 + 59399 + 0 + 0 + 0 + 0 + 439 + 0 + 8192 + 1 + + 16 + 000000001C000000C201000038000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59400 + 59400 + 1 + 0 + 0 + 0 + 612 + 0 + 8192 + 2 + + 16 + 000000001C0000006F02000038000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 2618 + 000000000B000000000000000020000001000000FFFFFFFFFFFFFFFF80010000150100007007000019010000010000000100001004000000010000000000000000000000FFFFFFFF06000000CB00000057010000CC000000F08B00005A01000079070000FFFF02000B004354616262656450616E650020000001000000C0020000AF010000B008000075020000800100004F00000070070000150100000000000040280056060000000B446973617373656D626C7901000000CB00000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A6572000000005701000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A657200000000CC00000001000000FFFFFFFFFFFFFFFF0E4C6F67696320416E616C797A657200000000F08B000001000000FFFFFFFFFFFFFFFF0D436F646520436F766572616765000000005A01000001000000FFFFFFFFFFFFFFFF11496E737472756374696F6E205472616365000000007907000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFCB00000001000000FFFFFFFFCB000000000000000040000000000000FFFFFFFFFFFFFFFFDC0500004F000000E005000001030000000000000200000004000000010000000000000000000000FFFFFFFF17000000E2050000CA0900002D8C00002E8C00002F8C0000308C0000318C0000328C0000338C0000348C0000358C0000368C0000378C0000388C0000398C00003A8C00003B8C00003C8C00003D8C00003E8C00003F8C0000408C0000418C00000180004000000000000020070000AF010000B008000061040000E00500004F00000070070000010300000000000040410046170000000753796D626F6C7300000000E205000001000000FFFFFFFFFFFFFFFF0A5472616365204461746100000000CA09000001000000FFFFFFFFFFFFFFFF00000000002D8C000001000000FFFFFFFFFFFFFFFF00000000002E8C000001000000FFFFFFFFFFFFFFFF00000000002F8C000001000000FFFFFFFFFFFFFFFF0000000000308C000001000000FFFFFFFFFFFFFFFF0000000000318C000001000000FFFFFFFFFFFFFFFF0000000000328C000001000000FFFFFFFFFFFFFFFF0000000000338C000001000000FFFFFFFFFFFFFFFF0000000000348C000001000000FFFFFFFFFFFFFFFF0000000000358C000001000000FFFFFFFFFFFFFFFF0000000000368C000001000000FFFFFFFFFFFFFFFF0000000000378C000001000000FFFFFFFFFFFFFFFF0000000000388C000001000000FFFFFFFFFFFFFFFF0000000000398C000001000000FFFFFFFFFFFFFFFF00000000003A8C000001000000FFFFFFFFFFFFFFFF00000000003B8C000001000000FFFFFFFFFFFFFFFF00000000003C8C000001000000FFFFFFFFFFFFFFFF00000000003D8C000001000000FFFFFFFFFFFFFFFF00000000003E8C000001000000FFFFFFFFFFFFFFFF00000000003F8C000001000000FFFFFFFFFFFFFFFF0000000000408C000001000000FFFFFFFFFFFFFFFF0000000000418C000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFE205000001000000FFFFFFFFE2050000000000000010000001000000FFFFFFFFFFFFFFFF7C0100004F00000080010000ED020000010000000200001004000000010000000000000000000000FFFFFFFF05000000ED0300006D000000C3000000C4000000739400000180001000000100000040010000AF010000BC0200004D040000000000004F0000007C010000ED0200000000000040140056050000000750726F6A65637401000000ED03000001000000FFFFFFFFFFFFFFFF05426F6F6B73000000006D00000001000000FFFFFFFFFFFFFFFF0946756E6374696F6E7300000000C300000001000000FFFFFFFFFFFFFFFF0954656D706C6174657300000000C400000001000000FFFFFFFFFFFFFFFF09526567697374657273010000007394000001000000FFFFFFFFFFFFFFFF04000000000000000000000000000000000000000000000001000000FFFFFFFFED03000001000000FFFFFFFFED030000000000000080000001000000FFFFFFFFFFFFFFFF00000000ED02000070070000F102000001000000010000100400000001000000000000000000000000000000000000000000000001000000C6000000FFFFFFFF0E0000008F070000930700009407000095070000960700009007000091070000B5010000B8010000B9050000BA050000BB050000BC050000CB09000001800080000001000000FC04000051040000B00800002B050000BC030000F102000070070000CB03000000000000404100560E0000001343616C6C20537461636B202B204C6F63616C73010000008F07000001000000FFFFFFFFFFFFFFFF0755415254202331000000009307000001000000FFFFFFFFFFFFFFFF0755415254202332000000009407000001000000FFFFFFFFFFFFFFFF0755415254202333000000009507000001000000FFFFFFFFFFFFFFFF15446562756720287072696E74662920566965776572000000009607000001000000FFFFFFFFFFFFFFFF0757617463682031000000009007000001000000FFFFFFFFFFFFFFFF0757617463682032000000009107000001000000FFFFFFFFFFFFFFFF10547261636520457863657074696F6E7300000000B501000001000000FFFFFFFFFFFFFFFF0E4576656E7420436F756E7465727300000000B801000001000000FFFFFFFFFFFFFFFF084D656D6F7279203101000000B905000001000000FFFFFFFFFFFFFFFF084D656D6F7279203200000000BA05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203300000000BB05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203400000000BC05000001000000FFFFFFFFFFFFFFFF105472616365204E617669676174696F6E00000000CB09000001000000FFFFFFFFFFFFFFFF000000000000000001000000000000000100000001000000FFFFFFFFB8030000F1020000BC030000CB03000001000000020000100400000000000000000000000000000000000000000000000000000002000000C6000000FFFFFFFF8F07000001000000FFFFFFFF8F07000001000000C6000000000000000080000000000000FFFFFFFFFFFFFFFF00000000010300007007000005030000000000000100000004000000010000000000000000000000FFFFFFFF04000000C5000000C7000000B401000077940000018000800000000000004001000065040000B00800002B050000000000000503000070070000CB0300000000000040820046040000000C4275696C64204F757470757400000000C500000001000000FFFFFFFFFFFFFFFF0D46696E6420496E2046696C657300000000C700000001000000FFFFFFFFFFFFFFFF0A4572726F72204C69737400000000B401000001000000FFFFFFFFFFFFFFFF0642726F777365000000007794000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFC500000001000000FFFFFFFFC5000000000000000000000000000000 + + + 59392 + File + + 2002 + 00200000010000002800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000000004000000000000000000000000000000000100000001000000018022E100000000000005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000004000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000004000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000004000C0000000000000000000000000000000001000000010000000180F4B00000000004000D000000000000000000000000000000000100000001000000018036B10000000004000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF88000000000000460000000000000000000000000000000001000000010000000180FE880000000000004500000000000000000000000000000000010000000100000001800B810000000000001300000000000000000000000000000000010000000100000001800C810000000000001400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F0880000020000000F000000000000000000000000000000000100000001000000FFFF0100120043555646696E64436F6D626F427574746F6EE803000000000000000000000000000000000000000000000001000000010000009600000002002050FFFFFFFF0096000000000000000000018024E10000000000001100000000000000000000000000000000010000000100000001800A810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000020001001500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000400160000000000000000000000000000000001000000010000000180C988000000000400180000000000000000000000000000000001000000010000000180C788000000000000190000000000000000000000000000000001000000010000000180C8880000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E4C010000020001001A0000000F50726F6A6563742057696E646F7773000000000000000000000000010000000100000000000000000000000100000008002880DD880000000000001A0000000750726F6A656374000000000000000000000000010000000100000000000000000000000100000000002880DC8B0000000000003A00000005426F6F6B73000000000000000000000000010000000100000000000000000000000100000000002880E18B0000000000003B0000000946756E6374696F6E73000000000000000000000000010000000100000000000000000000000100000000002880E28B000000000000400000000954656D706C6174657300000000000000000000000001000000010000000000000000000000010000000000288018890000000000003D0000000E536F757263652042726F777365720000000000000000000000000100000001000000000000000000000001000000000028800000000000000400FFFFFFFF00000000000000000001000000000000000100000000000000000000000100000000002880D988000000000000390000000C4275696C64204F7574707574000000000000000000000000010000000100000000000000000000000100000000002880E38B000000000000410000000B46696E64204F75747075740000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001B000000000000000000000000000000000100000001000000000000000446696C65AC030000 + + + 1423 + 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E1000000000000FFFFFFFF000100000000000000010000000000000001000000018001E1000000000000FFFFFFFF000100000000000000010000000000000001000000018003E1000000000000FFFFFFFF0001000000000000000100000000000000010000000180CD7F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF000000000000000000010000000000000001000000018023E1000000000000FFFFFFFF000100000000000000010000000000000001000000018022E1000000000000FFFFFFFF000100000000000000010000000000000001000000018025E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802BE1000000000000FFFFFFFF00010000000000000001000000000000000100000001802CE1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001807A8A000000000000FFFFFFFF00010000000000000001000000000000000100000001807B8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180D3B0000000000000FFFFFFFF000100000000000000010000000000000001000000018015B1000000000000FFFFFFFF0001000000000000000100000000000000010000000180F4B0000000000000FFFFFFFF000100000000000000010000000000000001000000018036B1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FF88000000000000FFFFFFFF0001000000000000000100000000000000010000000180FE88000000000000FFFFFFFF00010000000000000001000000000000000100000001800B81000000000000FFFFFFFF00010000000000000001000000000000000100000001800C81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180F088000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE7F000000000000FFFFFFFF000100000000000000010000000000000001000000018024E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800A81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802280000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C488000000000000FFFFFFFF0001000000000000000100000000000000010000000180C988000000000000FFFFFFFF0001000000000000000100000000000000010000000180C788000000000000FFFFFFFF0001000000000000000100000000000000010000000180C888000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180DD88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FB7F000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 1423 + 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000000004000000000000000000000000000000000100000001000000018022E100000000000005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000000000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000000000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000000000C0000000000000000000000000000000001000000010000000180F4B00000000000000D000000000000000000000000000000000100000001000000018036B10000000000000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF880000000000000F0000000000000000000000000000000001000000010000000180FE880000000000001000000000000000000000000000000000010000000100000001800B810000000000001100000000000000000000000000000000010000000100000001800C810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F088000000000000130000000000000000000000000000000001000000010000000180EE7F00000000000014000000000000000000000000000000000100000001000000018024E10000000000001500000000000000000000000000000000010000000100000001800A810000000000001600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000180000000000000000000000000000000001000000010000000180C988000000000000190000000000000000000000000000000001000000010000000180C7880000000000001A0000000000000000000000000000000001000000010000000180C8880000000000001B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180DD880000000000001C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001D000000000000000000000000000000000100000001000000 + + + + 59399 + Build + + 622 + 00200000000000000F00FFFF01001100434D4643546F6F6C426172427574746F6ECF7F0000000000001C0000000000000000000000000000000001000000010000000180D07F0000000000001D000000000000000000000000000000000100000001000000018030800000000000001E00000000000000000000000000000000010000000100000001809E8A0000000000001F0000000000000000000000000000000001000000010000000180D17F0000000000002000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000002100000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6EBA00000000000000000000000000000000000000000000000001000000010000009600000003002050FFFFFFFF00960000000000000000000180EB880000000000002200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000230000000000000000000000000000000001000000010000000180B08A000000000000240000000000000000000000000000000001000000010000000180A8010000000000004E0000000000000000000000000000000001000000010000000180BE010000000000005000000000000000000000000000000000010000000100000000000000054275696C64B7010000 + + + 548 + 0F00FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000FFFFFFFF0001000000000000000100000000000000010000000180D07F000000000000FFFFFFFF00010000000000000001000000000000000100000001803080000000000000FFFFFFFF00010000000000000001000000000000000100000001809E8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D17F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001804C8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001806680000000000000FFFFFFFF0001000000000000000100000000000000010000000180EB88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180B08A000000000000FFFFFFFF0001000000000000000100000000000000010000000180A801000000000000FFFFFFFF0001000000000000000100000000000000010000000180BE01000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 548 + 0F00FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000000000000000000000000000000000000001000000010000000180D07F00000000000001000000000000000000000000000000000100000001000000018030800000000000000200000000000000000000000000000000010000000100000001809E8A000000000000030000000000000000000000000000000001000000010000000180D17F0000000000000400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000000500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001806680000000000000060000000000000000000000000000000001000000010000000180EB880000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000080000000000000000000000000000000001000000010000000180B08A000000000000090000000000000000000000000000000001000000010000000180A8010000000000000A0000000000000000000000000000000001000000010000000180BE010000000000000B000000000000000000000000000000000100000001000000 + + + + 59400 + Debug + + 2220 + 00200000010000001900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000002500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000002600000000000000000000000000000000010000000100000001801D800000000004002700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000002800000000000000000000000000000000010000000100000001801B80000000000000290000000000000000000000000000000001000000010000000180E57F0000000000002A00000000000000000000000000000000010000000100000001801C800000000000002B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000002C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B0000020001002D0000000000000000000000000000000001000000010000000180F07F0000020001002E0000000000000000000000000000000001000000010000000180E8880000020000003700000000000000000000000000000000010000000100000001803B010000020001002F0000000000000000000000000000000001000000010000000180BB8A00000200010030000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E0E01000002000000310000000D57617463682057696E646F7773000000000000000000000000010000000100000000000000000000000100000002001380D88B000000000000310000000757617463682031000000000000000000000000010000000100000000000000000000000100000000001380D98B0000000000003100000007576174636820320000000000000000000000000100000001000000000000000000000001000000000013800F01000002000100320000000E4D656D6F72792057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380D28B00000000000032000000084D656D6F72792031000000000000000000000000010000000100000000000000000000000100000000001380D38B00000000000032000000084D656D6F72792032000000000000000000000000010000000100000000000000000000000100000000001380D48B00000000000032000000084D656D6F72792033000000000000000000000000010000000100000000000000000000000100000000001380D58B00000000000032000000084D656D6F727920340000000000000000000000000100000001000000000000000000000001000000000013801001000002000000330000000E53657269616C2057696E646F77730000000000000000000000000100000001000000000000000000000001000000040013809307000000000000330000000755415254202331000000000000000000000000010000000100000000000000000000000100000000001380940700000000000033000000075541525420233200000000000000000000000001000000010000000000000000000000010000000000138095070000000000003300000007554152542023330000000000000000000000000100000001000000000000000000000001000000000013809607000000000000330000000E49544D2F525441205669657765720000000000000000000000000100000001000000000000000000000001000000000013803C010000020000003400000010416E616C797369732057696E646F7773000000000000000000000000010000000100000000000000000000000100000003001380658A000000000000340000000E4C6F67696320416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380DC7F0000000000003E00000014506572666F726D616E636520416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380E788000000000000380000000D436F646520436F76657261676500000000000000000000000001000000010000000000000000000000010000000000138053010000000000003F0000000D54726163652057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013805401000000000000FFFFFFFF115472616365204D656E7520416E63686F720000000000000000010000000000000001000000000000000000000001000000000013802901000000000000350000001553797374656D205669657765722057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013804B01000000000000FFFFFFFF1453797374656D2056696577657220416E63686F720000000000000000010000000000000001000000000000000000000001000000000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000138001890000020000003600000007546F6F6C626F7800000000000000000000000001000000010000000000000000000000010000000300138044C5000000000000FFFFFFFF0E5570646174652057696E646F77730000000000000000010000000000000001000000000000000000000001000000000013800000000000000400FFFFFFFF000000000000000000010000000000000001000000000000000000000001000000000013805B01000000000000FFFFFFFF12546F6F6C626F78204D656E75416E63686F72000000000000000001000000000000000100000000000000000000000100000000000000000005446562756764020000 + + + 898 + 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801780000000000000FFFFFFFF00010000000000000001000000000000000100000001801D80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801A80000000000000FFFFFFFF00010000000000000001000000000000000100000001801B80000000000000FFFFFFFF0001000000000000000100000000000000010000000180E57F000000000000FFFFFFFF00010000000000000001000000000000000100000001801C80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800089000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180E48B000000000000FFFFFFFF0001000000000000000100000000000000010000000180F07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180E888000000000000FFFFFFFF00010000000000000001000000000000000100000001803B01000000000000FFFFFFFF0001000000000000000100000000000000010000000180BB8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D88B000000000000FFFFFFFF0001000000000000000100000000000000010000000180D28B000000000000FFFFFFFF00010000000000000001000000000000000100000001809307000000000000FFFFFFFF0001000000000000000100000000000000010000000180658A000000000000FFFFFFFF0001000000000000000100000000000000010000000180C18A000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE8B000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800189000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 898 + 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000000000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000000100000000000000000000000000000000010000000100000001801D800000000000000200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000000300000000000000000000000000000000010000000100000001801B80000000000000040000000000000000000000000000000001000000010000000180E57F0000000000000500000000000000000000000000000000010000000100000001801C800000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B000000000000080000000000000000000000000000000001000000010000000180F07F000000000000090000000000000000000000000000000001000000010000000180E8880000000000000A00000000000000000000000000000000010000000100000001803B010000000000000B0000000000000000000000000000000001000000010000000180BB8A0000000000000C0000000000000000000000000000000001000000010000000180D88B0000000000000D0000000000000000000000000000000001000000010000000180D28B0000000000000E000000000000000000000000000000000100000001000000018093070000000000000F0000000000000000000000000000000001000000010000000180658A000000000000100000000000000000000000000000000001000000010000000180C18A000000000000110000000000000000000000000000000001000000010000000180EE8B0000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180018900000000000013000000000000000000000000000000000100000001000000 + + + + 0 + 2560 + 1440 + + + + + + + + 1 + 0 + + 100 + 0 + + .\assem.s + 0 + 1 + 1 + 1 + + 0 + + + + +
diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.uvgui_corwin.bak b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.uvgui_corwin.bak new file mode 100644 index 0000000..cff2267 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.uvgui_corwin.bak @@ -0,0 +1,2601 @@ + + + + -4.1 + +
### uVision Project, (C) Keil Software
+ + + + + + 38003 + Registers + 115 255 + + + 346 + Code Coverage + 1350 160 + + + 204 + Performance Analyzer + 1510 226 226 100 + + + + + + 1506 + Symbols + + 133 133 133 + + + 1936 + Watch 1 + + 133 133 133 + + + 1937 + Watch 2 + + 133 133 133 + + + 1935 + Call Stack + Locals + + 133 133 133 + + + 2506 + Trace Data + + 75 135 130 95 70 230 200 + + + + + + 0 + 0 + 0 + + + + + + + 44 + 0 + 1 + + -1 + -1 + + + -1 + -1 + + + 78 + 78 + 1998 + 1107 + + + + 0 + + 293 + 01000000040000000100000001000000010000000100000000000000020000000000000001000000010000000000000028000000280000000100000001000000000000000100000060433A5C55736572735C636F7277696E5C476F6F676C652044726976655C5F5363686F6F6C5C43757272656E74205465726D5C4353203237315C46696E616C2050617065725C436F64655C50726F6772616D315C41524D76375C617373656D2E730000000007617373656D2E7300000000C5D4F200FFFFFFFF0100000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD500010000000000000002000000D6010000BC000000C60700006E030000 + + + + 0 + Build + + -1 + -1 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 800100004F0000007007000015010000 + + + 16 + D6010000BC000000C607000082010000 + + + + 1005 + 1005 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000E8020000 + + + 16 + 560000006D000000D201000085030000 + + + + 109 + 109 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000E8020000 + + + 16 + 560000006D000000D201000085030000 + + + + 1465 + 1465 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1466 + 1466 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1467 + 1467 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1468 + 1468 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1506 + 1506 + 0 + 0 + 0 + 0 + 32767 + 0 + 16384 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 1913 + 1913 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1935 + 1935 + 0 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 1936 + 1936 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 1937 + 1937 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 1939 + 1939 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1940 + 1940 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1941 + 1941 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1942 + 1942 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 195 + 195 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000E8020000 + + + 16 + 560000006D000000D201000085030000 + + + + 196 + 196 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000E8020000 + + + 16 + 560000006D000000D201000085030000 + + + + 197 + 197 + 1 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 000000001903000070070000CB030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 198 + 198 + 0 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 00000000F102000070070000CB030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 199 + 199 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000001C0300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 203 + 203 + 0 + 0 + 0 + 0 + 32767 + 0 + 8192 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 204 + 204 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 221 + 221 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 00000000000000000000000000000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 2506 + 2506 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 2507 + 2507 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 343 + 343 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 346 + 346 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 35824 + 35824 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 35885 + 35885 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35886 + 35886 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35887 + 35887 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35888 + 35888 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35889 + 35889 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35890 + 35890 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35891 + 35891 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35892 + 35892 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35893 + 35893 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35894 + 35894 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35895 + 35895 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35896 + 35896 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35897 + 35897 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35898 + 35898 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35899 + 35899 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35900 + 35900 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35901 + 35901 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35902 + 35902 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35903 + 35903 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35904 + 35904 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35905 + 35905 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 38003 + 38003 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000E8020000 + + + 16 + 560000006D000000D201000085030000 + + + + 38007 + 38007 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000001C0300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 436 + 436 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000001C0300006D070000B2030000 + + + 16 + 560000006D000000D201000085030000 + + + + 437 + 437 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 440 + 440 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 59392 + 59392 + 1 + 0 + 0 + 0 + 940 + 0 + 8192 + 0 + + 16 + 0000000000000000B70300001C000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59393 + 0 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 00000000CB03000070070000DE030000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59399 + 59399 + 1 + 0 + 0 + 0 + 439 + 0 + 8192 + 1 + + 16 + 000000001C000000C201000038000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59400 + 59400 + 0 + 0 + 0 + 0 + 612 + 0 + 8192 + 2 + + 16 + 00000000380000006F02000054000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 2619 + 000000000B000000000000000020000000000000FFFFFFFFFFFFFFFF80010000150100007007000019010000000000000100000004000000010000000000000000000000FFFFFFFF06000000CB00000057010000CC000000F08B00005A01000079070000FFFF02000B004354616262656450616E650020000000000000D6010000BC000000C607000082010000800100004F00000070070000150100000000000040280046060000000B446973617373656D626C7900000000CB00000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A6572000000005701000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A657200000000CC00000001000000FFFFFFFFFFFFFFFF0E4C6F67696320416E616C797A657200000000F08B000001000000FFFFFFFFFFFFFFFF0D436F646520436F766572616765000000005A01000001000000FFFFFFFFFFFFFFFF11496E737472756374696F6E205472616365000000007907000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFCB00000001000000FFFFFFFFCB000000000000000040000000000000FFFFFFFFFFFFFFFFDC0500004F000000E005000001030000000000000200000004000000010000000000000000000000FFFFFFFF17000000E2050000CA0900002D8C00002E8C00002F8C0000308C0000318C0000328C0000338C0000348C0000358C0000368C0000378C0000388C0000398C00003A8C00003B8C00003C8C00003D8C00003E8C00003F8C0000408C0000418C00000180004000000000000036060000BC000000C60700006E030000E00500004F00000070070000010300000000000040410046170000000753796D626F6C7300000000E205000001000000FFFFFFFFFFFFFFFF0A5472616365204461746100000000CA09000001000000FFFFFFFFFFFFFFFF00000000002D8C000001000000FFFFFFFFFFFFFFFF00000000002E8C000001000000FFFFFFFFFFFFFFFF00000000002F8C000001000000FFFFFFFFFFFFFFFF0000000000308C000001000000FFFFFFFFFFFFFFFF0000000000318C000001000000FFFFFFFFFFFFFFFF0000000000328C000001000000FFFFFFFFFFFFFFFF0000000000338C000001000000FFFFFFFFFFFFFFFF0000000000348C000001000000FFFFFFFFFFFFFFFF0000000000358C000001000000FFFFFFFFFFFFFFFF0000000000368C000001000000FFFFFFFFFFFFFFFF0000000000378C000001000000FFFFFFFFFFFFFFFF0000000000388C000001000000FFFFFFFFFFFFFFFF0000000000398C000001000000FFFFFFFFFFFFFFFF00000000003A8C000001000000FFFFFFFFFFFFFFFF00000000003B8C000001000000FFFFFFFFFFFFFFFF00000000003C8C000001000000FFFFFFFFFFFFFFFF00000000003D8C000001000000FFFFFFFFFFFFFFFF00000000003E8C000001000000FFFFFFFFFFFFFFFF00000000003F8C000001000000FFFFFFFFFFFFFFFF0000000000408C000001000000FFFFFFFFFFFFFFFF0000000000418C000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFE205000001000000FFFFFFFFE2050000000000000010000001000000FFFFFFFFFFFFFFFF7C0100004F0000008001000001030000010000000200001004000000010000000000000000000000FFFFFFFF05000000ED0300006D000000C3000000C4000000739400000180001000000100000056000000BC000000D20100006E030000000000004F0000007C010000010300000000000040140056050000000750726F6A65637401000000ED03000001000000FFFFFFFFFFFFFFFF05426F6F6B73010000006D00000001000000FFFFFFFFFFFFFFFF0946756E6374696F6E7301000000C300000001000000FFFFFFFFFFFFFFFF0954656D706C6174657301000000C400000001000000FFFFFFFFFFFFFFFF09526567697374657273000000007394000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFED03000001000000FFFFFFFFED030000000000000080000000000000FFFFFFFFFFFFFFFF00000000ED02000070070000F102000000000000010000000400000001000000000000000000000000000000000000000000000001000000C6000000FFFFFFFF0E0000008F070000930700009407000095070000960700009007000091070000B5010000B8010000B9050000BA050000BB050000BC050000CB09000001800080000000000000560000005E030000C60700003804000000000000F102000070070000CB03000000000000404100460E0000001343616C6C20537461636B202B204C6F63616C73000000008F07000001000000FFFFFFFFFFFFFFFF0755415254202331000000009307000001000000FFFFFFFFFFFFFFFF0755415254202332000000009407000001000000FFFFFFFFFFFFFFFF0755415254202333000000009507000001000000FFFFFFFFFFFFFFFF15446562756720287072696E74662920566965776572000000009607000001000000FFFFFFFFFFFFFFFF0757617463682031000000009007000001000000FFFFFFFFFFFFFFFF0757617463682032000000009107000001000000FFFFFFFFFFFFFFFF10547261636520457863657074696F6E7300000000B501000001000000FFFFFFFFFFFFFFFF0E4576656E7420436F756E7465727300000000B801000001000000FFFFFFFFFFFFFFFF084D656D6F7279203100000000B905000001000000FFFFFFFFFFFFFFFF084D656D6F7279203200000000BA05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203300000000BB05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203400000000BC05000001000000FFFFFFFFFFFFFFFF105472616365204E617669676174696F6E00000000CB09000001000000FFFFFFFFFFFFFFFFFFFFFFFF0000000001000000000000000000000001000000FFFFFFFFB8030000F1020000BC030000CB03000000000000020000000400000000000000000000000000000000000000000000000000000002000000C6000000FFFFFFFF8F07000001000000FFFFFFFF8F07000001000000C6000000000000000080000001000000FFFFFFFFFFFFFFFF00000000010300007007000005030000010000000100001004000000010000000000000000000000FFFFFFFF04000000C5000000C7000000B401000077940000018000800000010000005600000072030000C607000038040000000000000503000070070000CB0300000000000040820056040000000C4275696C64204F757470757401000000C500000001000000FFFFFFFFFFFFFFFF0D46696E6420496E2046696C657300000000C700000001000000FFFFFFFFFFFFFFFF0A4572726F72204C69737400000000B401000001000000FFFFFFFFFFFFFFFF0742726F77736572000000007794000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFC500000001000000FFFFFFFFC5000000000000000000000000000000 + + + 59392 + File + + 2002 + 00200000010000002800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000040004000000000000000000000000000000000100000001000000018022E100000000040005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000004000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000004000900000000000000000000000000000000010000000100000001807B8A0000000004000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000004000C0000000000000000000000000000000001000000010000000180F4B00000000004000D000000000000000000000000000000000100000001000000018036B10000000004000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF88000000000400460000000000000000000000000000000001000000010000000180FE880000000004004500000000000000000000000000000000010000000100000001800B810000000004001300000000000000000000000000000000010000000100000001800C810000000004001400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F0880000020000000F000000000000000000000000000000000100000001000000FFFF0100120043555646696E64436F6D626F427574746F6EE803000000000000000000000000000000000000000000000001000000010000009600000002002050FFFFFFFF0096000000000000000000018024E10000000000001100000000000000000000000000000000010000000100000001800A810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000020000001500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000160000000000000000000000000000000001000000010000000180C988000000000400180000000000000000000000000000000001000000010000000180C788000000000000190000000000000000000000000000000001000000010000000180C8880000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E4C010000020000001A0000000F50726F6A6563742057696E646F7773000000000000000000000000010000000100000000000000000000000100000008002880DD880000000000001A0000000750726F6A656374000000000000000000000000010000000100000000000000000000000100000000002880DC8B0000000000003A00000005426F6F6B73000000000000000000000000010000000100000000000000000000000100000000002880E18B0000000000003B0000000946756E6374696F6E73000000000000000000000000010000000100000000000000000000000100000000002880E28B000000000000400000000954656D706C6174657300000000000000000000000001000000010000000000000000000000010000000000288018890000000000003D0000000E536F757263652042726F777365720000000000000000000000000100000001000000000000000000000001000000000028800000000000000400FFFFFFFF00000000000000000001000000000000000100000000000000000000000100000000002880D988000000000000390000000C4275696C64204F7574707574000000000000000000000000010000000100000000000000000000000100000000002880E38B000000000000410000000B46696E64204F75747075740000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001B000000000000000000000000000000000100000001000000000000000446696C65AC030000 + + + 1423 + 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E1000000000000FFFFFFFF000100000000000000010000000000000001000000018001E1000000000000FFFFFFFF000100000000000000010000000000000001000000018003E1000000000000FFFFFFFF0001000000000000000100000000000000010000000180CD7F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF000000000000000000010000000000000001000000018023E1000000000000FFFFFFFF000100000000000000010000000000000001000000018022E1000000000000FFFFFFFF000100000000000000010000000000000001000000018025E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802BE1000000000000FFFFFFFF00010000000000000001000000000000000100000001802CE1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001807A8A000000000000FFFFFFFF00010000000000000001000000000000000100000001807B8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180D3B0000000000000FFFFFFFF000100000000000000010000000000000001000000018015B1000000000000FFFFFFFF0001000000000000000100000000000000010000000180F4B0000000000000FFFFFFFF000100000000000000010000000000000001000000018036B1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FF88000000000000FFFFFFFF0001000000000000000100000000000000010000000180FE88000000000000FFFFFFFF00010000000000000001000000000000000100000001800B81000000000000FFFFFFFF00010000000000000001000000000000000100000001800C81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180F088000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE7F000000000000FFFFFFFF000100000000000000010000000000000001000000018024E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800A81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802280000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C488000000000000FFFFFFFF0001000000000000000100000000000000010000000180C988000000000000FFFFFFFF0001000000000000000100000000000000010000000180C788000000000000FFFFFFFF0001000000000000000100000000000000010000000180C888000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180DD88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FB7F000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 1423 + 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000000004000000000000000000000000000000000100000001000000018022E100000000000005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000000000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000000000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000000000C0000000000000000000000000000000001000000010000000180F4B00000000000000D000000000000000000000000000000000100000001000000018036B10000000000000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF880000000000000F0000000000000000000000000000000001000000010000000180FE880000000000001000000000000000000000000000000000010000000100000001800B810000000000001100000000000000000000000000000000010000000100000001800C810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F088000000000000130000000000000000000000000000000001000000010000000180EE7F00000000000014000000000000000000000000000000000100000001000000018024E10000000000001500000000000000000000000000000000010000000100000001800A810000000000001600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000180000000000000000000000000000000001000000010000000180C988000000000000190000000000000000000000000000000001000000010000000180C7880000000000001A0000000000000000000000000000000001000000010000000180C8880000000000001B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180DD880000000000001C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001D000000000000000000000000000000000100000001000000 + + + + 59399 + Build + + 643 + 00200000010000000F00FFFF01001100434D4643546F6F6C426172427574746F6ECF7F0000000000001C0000000000000000000000000000000001000000010000000180D07F0000000000001D000000000000000000000000000000000100000001000000018030800000000000001E00000000000000000000000000000000010000000100000001809E8A0000000004001F0000000000000000000000000000000001000000010000000180D17F0000000004002000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000004002100000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6EBA000000000000000000000000000000000000000000000000010000000100000096000000030020500000000008546172676574203196000000000000000100085461726765742031000000000180EB880000000000002200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000230000000000000000000000000000000001000000010000000180B08A000000000400240000000000000000000000000000000001000000010000000180A8010000000004004E0000000000000000000000000000000001000000010000000180BE010000000004005000000000000000000000000000000000010000000100000000000000054275696C64B7010000 + + + 548 + 0F00FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000FFFFFFFF0001000000000000000100000000000000010000000180D07F000000000000FFFFFFFF00010000000000000001000000000000000100000001803080000000000000FFFFFFFF00010000000000000001000000000000000100000001809E8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D17F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001804C8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001806680000000000000FFFFFFFF0001000000000000000100000000000000010000000180EB88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180B08A000000000000FFFFFFFF0001000000000000000100000000000000010000000180A801000000000000FFFFFFFF0001000000000000000100000000000000010000000180BE01000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 548 + 0F00FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000000000000000000000000000000000000001000000010000000180D07F00000000000001000000000000000000000000000000000100000001000000018030800000000000000200000000000000000000000000000000010000000100000001809E8A000000000000030000000000000000000000000000000001000000010000000180D17F0000000000000400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000000500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001806680000000000000060000000000000000000000000000000001000000010000000180EB880000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000080000000000000000000000000000000001000000010000000180B08A000000000000090000000000000000000000000000000001000000010000000180A8010000000000000A0000000000000000000000000000000001000000010000000180BE010000000000000B000000000000000000000000000000000100000001000000 + + + + 59400 + Debug + + 2220 + 00200000000000001900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000002500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000002600000000000000000000000000000000010000000100000001801D800000000000002700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000002800000000000000000000000000000000010000000100000001801B80000000000000290000000000000000000000000000000001000000010000000180E57F0000000000002A00000000000000000000000000000000010000000100000001801C800000000000002B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000002C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B0000000000002D0000000000000000000000000000000001000000010000000180F07F0000000000002E0000000000000000000000000000000001000000010000000180E8880000000000003700000000000000000000000000000000010000000100000001803B010000000000002F0000000000000000000000000000000001000000010000000180BB8A00000000000030000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E0E01000000000000310000000D57617463682057696E646F7773000000000000000000000000010000000100000000000000000000000100000002001380D88B000000000000310000000757617463682031000000000000000000000000010000000100000000000000000000000100000000001380D98B0000000000003100000007576174636820320000000000000000000000000100000001000000000000000000000001000000000013800F01000000000000320000000E4D656D6F72792057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380D28B00000000000032000000084D656D6F72792031000000000000000000000000010000000100000000000000000000000100000000001380D38B00000000000032000000084D656D6F72792032000000000000000000000000010000000100000000000000000000000100000000001380D48B00000000000032000000084D656D6F72792033000000000000000000000000010000000100000000000000000000000100000000001380D58B00000000000032000000084D656D6F727920340000000000000000000000000100000001000000000000000000000001000000000013801001000000000000330000000E53657269616C2057696E646F77730000000000000000000000000100000001000000000000000000000001000000040013809307000000000000330000000755415254202331000000000000000000000000010000000100000000000000000000000100000000001380940700000000000033000000075541525420233200000000000000000000000001000000010000000000000000000000010000000000138095070000000000003300000007554152542023330000000000000000000000000100000001000000000000000000000001000000000013809607000000000000330000000E49544D2F525441205669657765720000000000000000000000000100000001000000000000000000000001000000000013803C010000000000003400000010416E616C797369732057696E646F7773000000000000000000000000010000000100000000000000000000000100000003001380658A000000000000340000000E4C6F67696320416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380DC7F0000000000003E00000014506572666F726D616E636520416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380E788000000000000380000000D436F646520436F76657261676500000000000000000000000001000000010000000000000000000000010000000000138053010000000000003F0000000D54726163652057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013805401000000000000FFFFFFFF115472616365204D656E7520416E63686F720000000000000000010000000000000001000000000000000000000001000000000013802901000000000000350000001553797374656D205669657765722057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013804B01000000000000FFFFFFFF1453797374656D2056696577657220416E63686F720000000000000000010000000000000001000000000000000000000001000000000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000138001890000000000003600000007546F6F6C626F7800000000000000000000000001000000010000000000000000000000010000000300138044C5000000000000FFFFFFFF0E5570646174652057696E646F77730000000000000000010000000000000001000000000000000000000001000000000013800000000000000400FFFFFFFF000000000000000000010000000000000001000000000000000000000001000000000013805B01000000000000FFFFFFFF12546F6F6C626F78204D656E75416E63686F72000000000000000001000000000000000100000000000000000000000100000000000000000005446562756764020000 + + + 898 + 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801780000000000000FFFFFFFF00010000000000000001000000000000000100000001801D80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801A80000000000000FFFFFFFF00010000000000000001000000000000000100000001801B80000000000000FFFFFFFF0001000000000000000100000000000000010000000180E57F000000000000FFFFFFFF00010000000000000001000000000000000100000001801C80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800089000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180E48B000000000000FFFFFFFF0001000000000000000100000000000000010000000180F07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180E888000000000000FFFFFFFF00010000000000000001000000000000000100000001803B01000000000000FFFFFFFF0001000000000000000100000000000000010000000180BB8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D88B000000000000FFFFFFFF0001000000000000000100000000000000010000000180D28B000000000000FFFFFFFF00010000000000000001000000000000000100000001809307000000000000FFFFFFFF0001000000000000000100000000000000010000000180658A000000000000FFFFFFFF0001000000000000000100000000000000010000000180C18A000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE8B000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800189000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 898 + 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000000000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000000100000000000000000000000000000000010000000100000001801D800000000000000200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000000300000000000000000000000000000000010000000100000001801B80000000000000040000000000000000000000000000000001000000010000000180E57F0000000000000500000000000000000000000000000000010000000100000001801C800000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B000000000000080000000000000000000000000000000001000000010000000180F07F000000000000090000000000000000000000000000000001000000010000000180E8880000000000000A00000000000000000000000000000000010000000100000001803B010000000000000B0000000000000000000000000000000001000000010000000180BB8A0000000000000C0000000000000000000000000000000001000000010000000180D88B0000000000000D0000000000000000000000000000000001000000010000000180D28B0000000000000E000000000000000000000000000000000100000001000000018093070000000000000F0000000000000000000000000000000001000000010000000180658A000000000000100000000000000000000000000000000001000000010000000180C18A000000000000110000000000000000000000000000000001000000010000000180EE8B0000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180018900000000000013000000000000000000000000000000000100000001000000 + + + + 0 + 2560 + 1440 + + + + 1 + Debug + + -1 + -1 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 800100004F0000007007000015010000 + + + 16 + D6010000BC000000C607000082010000 + + + + 1005 + 1005 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000D4020000 + + + 16 + 560000006D000000D201000085030000 + + + + 109 + 109 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000D4020000 + + + 16 + 560000006D000000D201000085030000 + + + + 1465 + 1465 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1466 + 1466 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1467 + 1467 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1468 + 1468 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1506 + 1506 + 0 + 0 + 0 + 0 + 32767 + 0 + 16384 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 1913 + 1913 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1935 + 1935 + 1 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 1936 + 1936 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 1937 + 1937 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 1939 + 1939 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1940 + 1940 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1941 + 1941 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 1942 + 1942 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 195 + 195 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000D4020000 + + + 16 + 560000006D000000D201000085030000 + + + + 196 + 196 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000D4020000 + + + 16 + 560000006D000000D201000085030000 + + + + 197 + 197 + 0 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 030000001C0300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 198 + 198 + 1 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 00000000F1020000B8030000CB030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 199 + 199 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000001C0300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 203 + 203 + 1 + 0 + 0 + 0 + 32767 + 0 + 8192 + 0 + + 16 + 80010000630000007007000015010000 + + + 16 + 560000006D0000000E04000033010000 + + + + 204 + 204 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 221 + 221 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 00000000000000000000000000000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 2506 + 2506 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 2507 + 2507 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 343 + 343 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 346 + 346 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 35824 + 35824 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 83010000660000006D070000FC000000 + + + 16 + 560000006D0000000E04000033010000 + + + + 35885 + 35885 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35886 + 35886 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35887 + 35887 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35888 + 35888 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35889 + 35889 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35890 + 35890 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35891 + 35891 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35892 + 35892 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35893 + 35893 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35894 + 35894 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35895 + 35895 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35896 + 35896 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35897 + 35897 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35898 + 35898 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35899 + 35899 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35900 + 35900 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35901 + 35901 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35902 + 35902 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35903 + 35903 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35904 + 35904 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 35905 + 35905 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + E3050000660000006D070000E8020000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 38003 + 38003 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000079010000D4020000 + + + 16 + 560000006D000000D201000085030000 + + + + 38007 + 38007 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000001C0300006D070000B2030000 + + + 16 + 560000006D0000000E04000033010000 + + + + 436 + 436 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000001C0300006D070000B2030000 + + + 16 + 560000006D000000D201000085030000 + + + + 437 + 437 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 440 + 440 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + BF030000080300006D070000B2030000 + + + 16 + 560000006D000000E6010000FD010000 + + + + 59392 + 59392 + 1 + 0 + 0 + 0 + 940 + 0 + 8192 + 0 + + 16 + 0000000000000000B70300001C000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59393 + 0 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 00000000CB03000070070000DE030000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59399 + 59399 + 0 + 0 + 0 + 0 + 439 + 0 + 8192 + 1 + + 16 + 000000001C000000C201000038000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59400 + 59400 + 1 + 0 + 0 + 0 + 612 + 0 + 8192 + 2 + + 16 + 000000001C0000006F02000038000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 2618 + 000000000B000000000000000020000001000000FFFFFFFFFFFFFFFF80010000150100007007000019010000010000000100001004000000010000000000000000000000FFFFFFFF06000000CB00000057010000CC000000F08B00005A01000079070000FFFF02000B004354616262656450616E650020000001000000D6010000BC000000C607000082010000800100004F00000070070000150100000000000040280056060000000B446973617373656D626C7901000000CB00000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A6572000000005701000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A657200000000CC00000001000000FFFFFFFFFFFFFFFF0E4C6F67696320416E616C797A657200000000F08B000001000000FFFFFFFFFFFFFFFF0D436F646520436F766572616765000000005A01000001000000FFFFFFFFFFFFFFFF11496E737472756374696F6E205472616365000000007907000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFCB00000001000000FFFFFFFFCB000000000000000040000000000000FFFFFFFFFFFFFFFFDC0500004F000000E005000001030000000000000200000004000000010000000000000000000000FFFFFFFF17000000E2050000CA0900002D8C00002E8C00002F8C0000308C0000318C0000328C0000338C0000348C0000358C0000368C0000378C0000388C0000398C00003A8C00003B8C00003C8C00003D8C00003E8C00003F8C0000408C0000418C00000180004000000000000036060000BC000000C60700006E030000E00500004F00000070070000010300000000000040410046170000000753796D626F6C7300000000E205000001000000FFFFFFFFFFFFFFFF0A5472616365204461746100000000CA09000001000000FFFFFFFFFFFFFFFF00000000002D8C000001000000FFFFFFFFFFFFFFFF00000000002E8C000001000000FFFFFFFFFFFFFFFF00000000002F8C000001000000FFFFFFFFFFFFFFFF0000000000308C000001000000FFFFFFFFFFFFFFFF0000000000318C000001000000FFFFFFFFFFFFFFFF0000000000328C000001000000FFFFFFFFFFFFFFFF0000000000338C000001000000FFFFFFFFFFFFFFFF0000000000348C000001000000FFFFFFFFFFFFFFFF0000000000358C000001000000FFFFFFFFFFFFFFFF0000000000368C000001000000FFFFFFFFFFFFFFFF0000000000378C000001000000FFFFFFFFFFFFFFFF0000000000388C000001000000FFFFFFFFFFFFFFFF0000000000398C000001000000FFFFFFFFFFFFFFFF00000000003A8C000001000000FFFFFFFFFFFFFFFF00000000003B8C000001000000FFFFFFFFFFFFFFFF00000000003C8C000001000000FFFFFFFFFFFFFFFF00000000003D8C000001000000FFFFFFFFFFFFFFFF00000000003E8C000001000000FFFFFFFFFFFFFFFF00000000003F8C000001000000FFFFFFFFFFFFFFFF0000000000408C000001000000FFFFFFFFFFFFFFFF0000000000418C000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFE205000001000000FFFFFFFFE2050000000000000010000001000000FFFFFFFFFFFFFFFF7C0100004F00000080010000ED020000010000000200001004000000010000000000000000000000FFFFFFFF05000000ED0300006D000000C3000000C4000000739400000180001000000100000056000000BC000000D20100005A030000000000004F0000007C010000ED0200000000000040140056050000000750726F6A65637401000000ED03000001000000FFFFFFFFFFFFFFFF05426F6F6B73000000006D00000001000000FFFFFFFFFFFFFFFF0946756E6374696F6E7300000000C300000001000000FFFFFFFFFFFFFFFF0954656D706C6174657300000000C400000001000000FFFFFFFFFFFFFFFF09526567697374657273010000007394000001000000FFFFFFFFFFFFFFFF04000000000000000000000000000000000000000000000001000000FFFFFFFFED03000001000000FFFFFFFFED030000000000000080000001000000FFFFFFFFFFFFFFFF00000000ED02000070070000F102000001000000010000100400000001000000000000000000000000000000000000000000000001000000C6000000FFFFFFFF0E0000008F070000930700009407000095070000960700009007000091070000B5010000B8010000B9050000BA050000BB050000BC050000CB09000001800080000001000000120400005E030000C607000038040000BC030000F102000070070000CB03000000000000404100560E0000001343616C6C20537461636B202B204C6F63616C73010000008F07000001000000FFFFFFFFFFFFFFFF0755415254202331000000009307000001000000FFFFFFFFFFFFFFFF0755415254202332000000009407000001000000FFFFFFFFFFFFFFFF0755415254202333000000009507000001000000FFFFFFFFFFFFFFFF15446562756720287072696E74662920566965776572000000009607000001000000FFFFFFFFFFFFFFFF0757617463682031000000009007000001000000FFFFFFFFFFFFFFFF0757617463682032000000009107000001000000FFFFFFFFFFFFFFFF10547261636520457863657074696F6E7300000000B501000001000000FFFFFFFFFFFFFFFF0E4576656E7420436F756E7465727300000000B801000001000000FFFFFFFFFFFFFFFF084D656D6F7279203101000000B905000001000000FFFFFFFFFFFFFFFF084D656D6F7279203200000000BA05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203300000000BB05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203400000000BC05000001000000FFFFFFFFFFFFFFFF105472616365204E617669676174696F6E00000000CB09000001000000FFFFFFFFFFFFFFFF000000000000000001000000000000000100000001000000FFFFFFFFB8030000F1020000BC030000CB03000001000000020000100400000000000000000000000000000000000000000000000000000002000000C6000000FFFFFFFF8F07000001000000FFFFFFFF8F07000001000000C6000000000000000080000000000000FFFFFFFFFFFFFFFF00000000010300007007000005030000000000000100000004000000010000000000000000000000FFFFFFFF04000000C5000000C7000000B401000077940000018000800000000000005600000072030000C607000038040000000000000503000070070000CB0300000000000040820046040000000C4275696C64204F757470757400000000C500000001000000FFFFFFFFFFFFFFFF0D46696E6420496E2046696C657300000000C700000001000000FFFFFFFFFFFFFFFF0A4572726F72204C69737400000000B401000001000000FFFFFFFFFFFFFFFF0642726F777365000000007794000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFC500000001000000FFFFFFFFC5000000000000000000000000000000 + + + 59392 + File + + 2002 + 00200000010000002800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000040004000000000000000000000000000000000100000001000000018022E100000000040005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000004000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000004000900000000000000000000000000000000010000000100000001807B8A0000000004000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000004000C0000000000000000000000000000000001000000010000000180F4B00000000004000D000000000000000000000000000000000100000001000000018036B10000000004000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF88000000000400460000000000000000000000000000000001000000010000000180FE880000000004004500000000000000000000000000000000010000000100000001800B810000000004001300000000000000000000000000000000010000000100000001800C810000000004001400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F0880000020000000F000000000000000000000000000000000100000001000000FFFF0100120043555646696E64436F6D626F427574746F6EE803000000000000000000000000000000000000000000000001000000010000009600000002002050FFFFFFFF0096000000000000000000018024E10000000000001100000000000000000000000000000000010000000100000001800A810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000020001001500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000400160000000000000000000000000000000001000000010000000180C988000000000400180000000000000000000000000000000001000000010000000180C788000000000000190000000000000000000000000000000001000000010000000180C8880000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E4C010000020001001A0000000F50726F6A6563742057696E646F7773000000000000000000000000010000000100000000000000000000000100000008002880DD880000000000001A0000000750726F6A656374000000000000000000000000010000000100000000000000000000000100000000002880DC8B0000000000003A00000005426F6F6B73000000000000000000000000010000000100000000000000000000000100000000002880E18B0000000000003B0000000946756E6374696F6E73000000000000000000000000010000000100000000000000000000000100000000002880E28B000000000000400000000954656D706C6174657300000000000000000000000001000000010000000000000000000000010000000000288018890000000000003D0000000E536F757263652042726F777365720000000000000000000000000100000001000000000000000000000001000000000028800000000000000400FFFFFFFF00000000000000000001000000000000000100000000000000000000000100000000002880D988000000000000390000000C4275696C64204F7574707574000000000000000000000000010000000100000000000000000000000100000000002880E38B000000000000410000000B46696E64204F75747075740000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001B000000000000000000000000000000000100000001000000000000000446696C65AC030000 + + + 1423 + 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E1000000000000FFFFFFFF000100000000000000010000000000000001000000018001E1000000000000FFFFFFFF000100000000000000010000000000000001000000018003E1000000000000FFFFFFFF0001000000000000000100000000000000010000000180CD7F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF000000000000000000010000000000000001000000018023E1000000000000FFFFFFFF000100000000000000010000000000000001000000018022E1000000000000FFFFFFFF000100000000000000010000000000000001000000018025E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802BE1000000000000FFFFFFFF00010000000000000001000000000000000100000001802CE1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001807A8A000000000000FFFFFFFF00010000000000000001000000000000000100000001807B8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180D3B0000000000000FFFFFFFF000100000000000000010000000000000001000000018015B1000000000000FFFFFFFF0001000000000000000100000000000000010000000180F4B0000000000000FFFFFFFF000100000000000000010000000000000001000000018036B1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FF88000000000000FFFFFFFF0001000000000000000100000000000000010000000180FE88000000000000FFFFFFFF00010000000000000001000000000000000100000001800B81000000000000FFFFFFFF00010000000000000001000000000000000100000001800C81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180F088000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE7F000000000000FFFFFFFF000100000000000000010000000000000001000000018024E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800A81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802280000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C488000000000000FFFFFFFF0001000000000000000100000000000000010000000180C988000000000000FFFFFFFF0001000000000000000100000000000000010000000180C788000000000000FFFFFFFF0001000000000000000100000000000000010000000180C888000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180DD88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FB7F000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 1423 + 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000000004000000000000000000000000000000000100000001000000018022E100000000000005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000000000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000000000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000000000C0000000000000000000000000000000001000000010000000180F4B00000000000000D000000000000000000000000000000000100000001000000018036B10000000000000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF880000000000000F0000000000000000000000000000000001000000010000000180FE880000000000001000000000000000000000000000000000010000000100000001800B810000000000001100000000000000000000000000000000010000000100000001800C810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F088000000000000130000000000000000000000000000000001000000010000000180EE7F00000000000014000000000000000000000000000000000100000001000000018024E10000000000001500000000000000000000000000000000010000000100000001800A810000000000001600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000180000000000000000000000000000000001000000010000000180C988000000000000190000000000000000000000000000000001000000010000000180C7880000000000001A0000000000000000000000000000000001000000010000000180C8880000000000001B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180DD880000000000001C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001D000000000000000000000000000000000100000001000000 + + + + 59399 + Build + + 622 + 00200000000000000F00FFFF01001100434D4643546F6F6C426172427574746F6ECF7F0000000000001C0000000000000000000000000000000001000000010000000180D07F0000000000001D000000000000000000000000000000000100000001000000018030800000000000001E00000000000000000000000000000000010000000100000001809E8A0000000000001F0000000000000000000000000000000001000000010000000180D17F0000000000002000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000002100000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6EBA00000000000000000000000000000000000000000000000001000000010000009600000003002050FFFFFFFF00960000000000000000000180EB880000000000002200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000230000000000000000000000000000000001000000010000000180B08A000000000000240000000000000000000000000000000001000000010000000180A8010000000000004E0000000000000000000000000000000001000000010000000180BE010000000000005000000000000000000000000000000000010000000100000000000000054275696C64B7010000 + + + 548 + 0F00FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000FFFFFFFF0001000000000000000100000000000000010000000180D07F000000000000FFFFFFFF00010000000000000001000000000000000100000001803080000000000000FFFFFFFF00010000000000000001000000000000000100000001809E8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D17F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001804C8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001806680000000000000FFFFFFFF0001000000000000000100000000000000010000000180EB88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180B08A000000000000FFFFFFFF0001000000000000000100000000000000010000000180A801000000000000FFFFFFFF0001000000000000000100000000000000010000000180BE01000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 548 + 0F00FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000000000000000000000000000000000000001000000010000000180D07F00000000000001000000000000000000000000000000000100000001000000018030800000000000000200000000000000000000000000000000010000000100000001809E8A000000000000030000000000000000000000000000000001000000010000000180D17F0000000000000400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000000500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001806680000000000000060000000000000000000000000000000001000000010000000180EB880000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000080000000000000000000000000000000001000000010000000180B08A000000000000090000000000000000000000000000000001000000010000000180A8010000000000000A0000000000000000000000000000000001000000010000000180BE010000000000000B000000000000000000000000000000000100000001000000 + + + + 59400 + Debug + + 2220 + 00200000010000001900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000002500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000002600000000000000000000000000000000010000000100000001801D800000000004002700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000002800000000000000000000000000000000010000000100000001801B80000000000000290000000000000000000000000000000001000000010000000180E57F0000000000002A00000000000000000000000000000000010000000100000001801C800000000000002B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000002C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B0000020001002D0000000000000000000000000000000001000000010000000180F07F0000020001002E0000000000000000000000000000000001000000010000000180E8880000020000003700000000000000000000000000000000010000000100000001803B010000020001002F0000000000000000000000000000000001000000010000000180BB8A00000200010030000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E0E01000002000000310000000D57617463682057696E646F7773000000000000000000000000010000000100000000000000000000000100000002001380D88B000000000000310000000757617463682031000000000000000000000000010000000100000000000000000000000100000000001380D98B0000000000003100000007576174636820320000000000000000000000000100000001000000000000000000000001000000000013800F01000002000100320000000E4D656D6F72792057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380D28B00000000000032000000084D656D6F72792031000000000000000000000000010000000100000000000000000000000100000000001380D38B00000000000032000000084D656D6F72792032000000000000000000000000010000000100000000000000000000000100000000001380D48B00000000000032000000084D656D6F72792033000000000000000000000000010000000100000000000000000000000100000000001380D58B00000000000032000000084D656D6F727920340000000000000000000000000100000001000000000000000000000001000000000013801001000002000000330000000E53657269616C2057696E646F77730000000000000000000000000100000001000000000000000000000001000000040013809307000000000000330000000755415254202331000000000000000000000000010000000100000000000000000000000100000000001380940700000000000033000000075541525420233200000000000000000000000001000000010000000000000000000000010000000000138095070000000000003300000007554152542023330000000000000000000000000100000001000000000000000000000001000000000013809607000000000000330000000E49544D2F525441205669657765720000000000000000000000000100000001000000000000000000000001000000000013803C010000020000003400000010416E616C797369732057696E646F7773000000000000000000000000010000000100000000000000000000000100000003001380658A000000000000340000000E4C6F67696320416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380DC7F0000000000003E00000014506572666F726D616E636520416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380E788000000000000380000000D436F646520436F76657261676500000000000000000000000001000000010000000000000000000000010000000000138053010000000000003F0000000D54726163652057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013805401000000000000FFFFFFFF115472616365204D656E7520416E63686F720100000000000000010000000000000001000000000000000000000001000000000013802901000000000000350000001553797374656D205669657765722057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013804B01000000000000FFFFFFFF1453797374656D2056696577657220416E63686F720100000000000000010000000000000001000000000000000000000001000000000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000138001890000020000003600000007546F6F6C626F7800000000000000000000000001000000010000000000000000000000010000000300138044C5000000000000FFFFFFFF0E5570646174652057696E646F77730100000000000000010000000000000001000000000000000000000001000000000013800000000000000400FFFFFFFF000000000000000000010000000000000001000000000000000000000001000000000013805B01000000000000FFFFFFFF12546F6F6C626F78204D656E75416E63686F72010000000000000001000000000000000100000000000000000000000100000000000000000005446562756764020000 + + + 898 + 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801780000000000000FFFFFFFF00010000000000000001000000000000000100000001801D80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801A80000000000000FFFFFFFF00010000000000000001000000000000000100000001801B80000000000000FFFFFFFF0001000000000000000100000000000000010000000180E57F000000000000FFFFFFFF00010000000000000001000000000000000100000001801C80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800089000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180E48B000000000000FFFFFFFF0001000000000000000100000000000000010000000180F07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180E888000000000000FFFFFFFF00010000000000000001000000000000000100000001803B01000000000000FFFFFFFF0001000000000000000100000000000000010000000180BB8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D88B000000000000FFFFFFFF0001000000000000000100000000000000010000000180D28B000000000000FFFFFFFF00010000000000000001000000000000000100000001809307000000000000FFFFFFFF0001000000000000000100000000000000010000000180658A000000000000FFFFFFFF0001000000000000000100000000000000010000000180C18A000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE8B000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800189000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 898 + 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000000000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000000100000000000000000000000000000000010000000100000001801D800000000000000200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000000300000000000000000000000000000000010000000100000001801B80000000000000040000000000000000000000000000000001000000010000000180E57F0000000000000500000000000000000000000000000000010000000100000001801C800000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B000000000000080000000000000000000000000000000001000000010000000180F07F000000000000090000000000000000000000000000000001000000010000000180E8880000000000000A00000000000000000000000000000000010000000100000001803B010000000000000B0000000000000000000000000000000001000000010000000180BB8A0000000000000C0000000000000000000000000000000001000000010000000180D88B0000000000000D0000000000000000000000000000000001000000010000000180D28B0000000000000E000000000000000000000000000000000100000001000000018093070000000000000F0000000000000000000000000000000001000000010000000180658A000000000000100000000000000000000000000000000001000000010000000180C18A000000000000110000000000000000000000000000000001000000010000000180EE8B0000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180018900000000000013000000000000000000000000000000000100000001000000 + + + + 0 + 2560 + 1440 + + + + + + + + 1 + 0 + + 100 + 0 + + .\assem.s + 10 + 1 + 2 + 1 + + 0 + + + + +
diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.uvopt b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.uvopt new file mode 100644 index 0000000..afce8d9 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.uvopt @@ -0,0 +1,193 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + + + + 0 + 0 + + + + Target 1 + 0x4 + ARM-ADS + + 60000000 + + 0 + 1 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 255 + + SARM.DLL + + DARMP.DLL + + SARM.DLL + + TARMP.DLL + + + + 1 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + -1 + + + + + + + + + + + + + + + 0 + DLGDARM + (134=-1,-1,-1,-1,0)(135=-1,-1,-1,-1,0)(107=-1,-1,-1,-1,0)(108=-1,-1,-1,-1,0)(106=-1,-1,-1,-1,0)(105=-1,-1,-1,-1,0)(80=-1,-1,-1,-1,0)(104=-1,-1,-1,-1,0)(100=-1,-1,-1,-1,0)(113=-1,-1,-1,-1,0)(112=-1,-1,-1,-1,0)(136=-1,-1,-1,-1,0)(117=-1,-1,-1,-1,0)(110=-1,-1,-1,-1,0)(111=-1,-1,-1,-1,0)(114=-1,-1,-1,-1,0)(115=-1,-1,-1,-1,0)(116=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + -T5F + + + + + 0 + + + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + Source Group 1 + 1 + 0 + 0 + 0 + + 1 + 1 + 2 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + .\assem.s + assem.s + 0 + 0 + + + +
diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.uvproj b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.uvproj new file mode 100644 index 0000000..8b37adb --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj.uvproj @@ -0,0 +1,412 @@ + + + + 1.1 + +
### uVision Project, (C) Keil Software
+ + + + Target 1 + 0x4 + ARM-ADS + + + ARM7 (Little Endian) + ARM + CLOCK(60000000) CPUTYPE(ARM7TDMI) + + + + 3654 + + + + + + + + + + + + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\ + Proj + 1 + 0 + 0 + 1 + 1 + .\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARM.DLL + + DARMP.DLL + + SARM.DLL + + TARMP.DLL + + + + + 1 + 0 + 0 + 0 + 16 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + + + 0 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 1 + + 0 + -1 + + + + + + + + + + + + + + + + + + + 0 + 0 + 0 + 0 + 0 + -1 + + 0 + + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + ARM7TDMI + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x00000000 + + + + + + + + + + + + Source Group 1 + + + assem.s + 2 + .\assem.s + + + + + + + +
diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj_Target 1.dep b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj_Target 1.dep new file mode 100644 index 0000000..86c9bff --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/Proj_Target 1.dep @@ -0,0 +1,2 @@ +Dependencies for Project 'Proj', Target 'Target 1': (DO NOT MODIFY !) +F (.\assem.s)(0x53282410)(--cpu ARM7TDMI --pd "__EVAL SETA 1" -g --apcs=interwork -I C:\Keil\ARM\RV31\INC -I C:\Keil\ARM\CMSIS\Include --list .\assem.lst --xref -o .\assem.o --depend .\assem.d) diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/assem.d b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/assem.d new file mode 100644 index 0000000..5a48a32 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/assem.d @@ -0,0 +1 @@ +.\assem.o: assem.s diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/assem.lst b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/assem.lst new file mode 100644 index 0000000..8a9065e --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/assem.lst @@ -0,0 +1,124 @@ + + + +ARM Macro Assembler Page 1 + + + 1 00000000 AREA ConstrainProg, CODE, READWRITE + 2 00000000 ENTRY + 3 00000000 Start + 4 00000000 E28FD054 ADR sp, Base ;Point to the base + of the stack + 5 00000004 E59F004C LDR r0, LowerVal ;Load the lower va + lue into r0 + 6 00000008 E59F1044 LDR r1, UpperVal ;Load the upper va + lue in r1 + 7 0000000C E59F203C LDR r2, ParamToConstrain ;Load the + value to constrain + into r2 + 8 00000010 E50D0004 STR r0,[sp,#-4] ;Load r0 onto the s + tack pointer + 9 00000014 E50D1004 STR r1,[sp,#-4] ;Load r1 onto the s + tack pointer + 10 00000018 E50D2004 STR r2,[sp,#-4] ;Load r2 onto the s + tack pointer + 11 0000001C EB000001 BL Constrain ;Call constrain pro + cedure + 12 00000020 E59D2000 LDR r2, [sp] ;Load constrained v + alue back into r2 + 13 00000024 ;r2 should now contain 2000 + 14 00000024 E28DD008 ADD sp, sp, #8 ;Fix the stack poin + ter + 15 00000028 Constrain + 16 00000028 E50DE004 STR LR, [sp, #-4] + 17 0000002C E59D500C LDR r5, [sp, #12] + 18 00000030 E59D4008 LDR r4, [sp, #8] + 19 00000034 E59D3004 LDR r3, [sp, #4] + 20 00000038 E1530004 CMP r3, r4 + 21 0000003C 359D3008 LDRLO r3, [sp, #8] + 22 00000040 E1530005 CMP r3, r5 + 23 00000044 859D300C LDRHI r3, [sp, #12] + 24 00000048 E58D3004 STR r3, [sp, #4] + 25 0000004C E49DF004 LDR PC, [sp], #4 + 26 00000050 00000898 + ParamToConstrain + DCD 2200 ;Value to constrain + + 27 00000054 000007D0 + UpperVal + DCD 2000 ;Value to constrain + + 28 00000058 000003E8 + LowerVal + DCD 1000 ;Value to constrain + + 29 0000005C AAAAAAAA + Base DCD 0xAAAAAAAA + 30 00000060 END +Command Line: --debug --xref --apcs=interwork --depend=.\assem.d -o.\assem.o -I +C:\Keil\ARM\RV31\INC -IC:\Keil\ARM\CMSIS\Include --predefine="__EVAL SETA 1" -- +list=.\assem.lst assem.s + + + +ARM Macro Assembler Page 1 Alphabetic symbol ordering +Relocatable symbols + +Base 0000005C + +Symbol: Base + Definitions + At line 29 in file assem.s + Uses + At line 4 in file assem.s +Comment: Base used once +Constrain 00000028 + +Symbol: Constrain + Definitions + At line 15 in file assem.s + Uses + At line 11 in file assem.s +Comment: Constrain used once +ConstrainProg 00000000 + +Symbol: ConstrainProg + Definitions + At line 1 in file assem.s + Uses + None +Comment: ConstrainProg unused +LowerVal 00000058 + +Symbol: LowerVal + Definitions + At line 28 in file assem.s + Uses + At line 5 in file assem.s +Comment: LowerVal used once +ParamToConstrain 00000050 + +Symbol: ParamToConstrain + Definitions + At line 26 in file assem.s + Uses + At line 7 in file assem.s +Comment: ParamToConstrain used once +Start 00000000 + +Symbol: Start + Definitions + At line 3 in file assem.s + Uses + None +Comment: Start unused +UpperVal 00000054 + +Symbol: UpperVal + Definitions + At line 27 in file assem.s + Uses + At line 6 in file assem.s +Comment: UpperVal used once +7 symbols +338 symbols in table diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/assem.o b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/assem.o new file mode 100644 index 0000000..9c9bdf3 Binary files /dev/null and b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/assem.o differ diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/assem.s b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/assem.s new file mode 100644 index 0000000..b61fe68 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Keil ARMv7/assem.s @@ -0,0 +1,30 @@ + AREA ConstrainProg, CODE, READWRITE + ENTRY +Start + ADR sp, Base ;Point to the base of the stack + LDR r0, LowerVal ;Load the lower value into r0 + LDR r1, UpperVal ;Load the upper value in r1 + LDR r2, ParamToConstrain ;Load the value to constrain into r2 + STR r0,[sp,#-4] ;Load r0 onto the stack pointer + STR r1,[sp,#-4] ;Load r1 onto the stack pointer + STR r2,[sp,#-4] ;Load r2 onto the stack pointer + BL Constrain ;Call constrain procedure + LDR r2, [sp] ;Load constrained value back into r2 + ;r2 should now contain 2000 + ADD sp, sp, #8 ;Fix the stack pointer +Constrain + STR LR, [sp, #-4] ;Store return address + LDR r5, [sp, #12] ;Retrieve lower + LDR r4, [sp, #8] ;Retrieve upper + LDR r3, [sp, #4] ;Retrieve val to constrain + CMP r3, r4 ;Check if higher than max + LDRHI r3, [sp, #8] ;If so, load max + CMP r3, r5 ;Check if lower than min + LDRLO r3, [sp, #12] ;If so, load min + STR r3, [sp, #4] ;Overwrite constrained val + LDR PC, [sp], #4 ;Return from procedure +ParamToConstrain DCD 2200 ;Value to constrain +UpperVal DCD 2000 ;Value to constrain +LowerVal DCD 1000 ;Value to constrain +Base DCD 0xAAAAAAAA + END \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Turned In/LoopAndMul.s b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Turned In/LoopAndMul.s new file mode 100644 index 0000000..a7d04c7 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Turned In/LoopAndMul.s @@ -0,0 +1,3 @@ + AREA Pointers, CODE, READONLY + ENTRY +Start ADR r0, List \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Turned In/LoopandMulARMv7.txt b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Turned In/LoopandMulARMv7.txt new file mode 100644 index 0000000..2b32d90 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Turned In/LoopandMulARMv7.txt @@ -0,0 +1,17 @@ + AREA Pointers, CODE, READONLY + ENTRY +Start + ADR r0, Array ;Point to address of array + MOV r1, #5 ;Set up a loop counter for array + MOV r2, #1 ;Set first val to one so math works +MultLoop + LDR r3,[r0] ;Put current array value into r3 + MUL r2,r3,r2 ;Multiply array val by stored product + ADD r0,r0,#4 ;Move forward by one array element + SUBS r1,r1,#1 ;Decrease loop counter + BNE MultLoop ;repeat until all elements added + + ;Final value in r2 (0x78 == 120 == 5!) + +Array DCD 1,2,3,4,5 ;Array to hold values + END \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Turned In/LoopandMulx86.txt b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Turned In/LoopandMulx86.txt new file mode 100644 index 0000000..4a793c4 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Turned In/LoopandMulx86.txt @@ -0,0 +1,32 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +TITLE LoopArrayMultiply (main.asm) +;Author: Corwin Perren +;Date: 3/13/2014 +;Description: +; This program runs through an array and multiplies each value until all +; array elements have been iterated through +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +INCLUDE Irvine32.inc + +.data + Array DWORD 1,2,3,4,5 ;Array with five values + +.code + +main PROC + cld ;Set direction forward + mov esi, OFFSET Array ;Point esi to offset for array + mov ecx, LENGTHOF Array ;Set loop counter to length of array + mov ebx, 1 ;Set storage reg to 1 so initial multiplication works +MultLoop: + lodsd ;Load current array value into eax + mul ebx ;Multiply eax by ebx + mov ebx, eax ;Store result in ebx + loop MultLoop ;Loop until array empty + mov eax, ebx ;Move final value into eax for printing + call WriteDec ;Print to screen + call Crlf ;Print line + exit ;Exit program +main ENDP +END main \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Turned In/ParamProcARMv7.txt b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Turned In/ParamProcARMv7.txt new file mode 100644 index 0000000..b61fe68 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Turned In/ParamProcARMv7.txt @@ -0,0 +1,30 @@ + AREA ConstrainProg, CODE, READWRITE + ENTRY +Start + ADR sp, Base ;Point to the base of the stack + LDR r0, LowerVal ;Load the lower value into r0 + LDR r1, UpperVal ;Load the upper value in r1 + LDR r2, ParamToConstrain ;Load the value to constrain into r2 + STR r0,[sp,#-4] ;Load r0 onto the stack pointer + STR r1,[sp,#-4] ;Load r1 onto the stack pointer + STR r2,[sp,#-4] ;Load r2 onto the stack pointer + BL Constrain ;Call constrain procedure + LDR r2, [sp] ;Load constrained value back into r2 + ;r2 should now contain 2000 + ADD sp, sp, #8 ;Fix the stack pointer +Constrain + STR LR, [sp, #-4] ;Store return address + LDR r5, [sp, #12] ;Retrieve lower + LDR r4, [sp, #8] ;Retrieve upper + LDR r3, [sp, #4] ;Retrieve val to constrain + CMP r3, r4 ;Check if higher than max + LDRHI r3, [sp, #8] ;If so, load max + CMP r3, r5 ;Check if lower than min + LDRLO r3, [sp, #12] ;If so, load min + STR r3, [sp, #4] ;Overwrite constrained val + LDR PC, [sp], #4 ;Return from procedure +ParamToConstrain DCD 2200 ;Value to constrain +UpperVal DCD 2000 ;Value to constrain +LowerVal DCD 1000 ;Value to constrain +Base DCD 0xAAAAAAAA + END \ No newline at end of file diff --git a/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Turned In/ParamProcx86.txt b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Turned In/ParamProcx86.txt new file mode 100644 index 0000000..e956f09 --- /dev/null +++ b/OSU Coursework/CS 271 - Computer Architecture and Assembly Language/Final/Turned In/ParamProcx86.txt @@ -0,0 +1,48 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +TITLE Constrain (main.asm) +;Author: Corwin Perren +;Date: 3/13/2014 +;Description: +; This program runs passes an argument via stack to a constain function +; based off of hobby R/C pulse times (1000-2000 microseconds) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +INCLUDE Irvine32.inc + +.data + ParamToConstrain DWORD 2500 ;;;;Value to constrain + UpperVal DWORD 2000 ;;;;Upper limit for constraint + LowerVal DWORD 1000 ;;;;Lower limit for constraint +.code + +Constrain PROC + mov ebp, esp ;;;;Move stack pointer into ebp + mov eax, [ebp+4] ;;;;Move the param to constrain into eax + cmp eax, [ebp+8] ;;;;Compare param to constrain to upper val + jg IsGreater ;;;;If it's greater, jump to isgreater + cmp eax, [ebp+12] ;;;;If it's not greater check if it's lower than lower val + jg NoChange ;;;;If it's not lower, jump to end of procedure + mov eax, [ebp+12] ;;;;If lower, move lower constrain value into eax + mov [ebp+4], eax ;;;;Replace value to constrain with eax + jmp NoChange ;;;;Just to end of procedure +IsGreater: + mov eax, [ebp+8] ;;;;If greater, move upper val into eax + mov [ebp+4], eax ;;;;Replace value to constrain with eax +NoChange: + ret ;;;;Return from procedure +Constrain ENDP + +main PROC + +MultLoop: + push LowerVal ;;;;Push lower constraint to the stack + push UpperVal ;;;;Push upper constraint to the stack + push ParamToConstrain ;;;;Push value onto the stack + call Constrain ;;;;Constrain this value + pop eax ;;;;Pop constrained value off the stack + add esp, 8 ;;;;Clean up stack + call WriteDec ;;;;Write value to screen + call Crlf ;;;;Prints a new line + exit ;;;;Exits the program +main ENDP +END main \ No newline at end of file