Ok, I think I'm figuring this stuff out. I've spent several hours studying the ATMega328p datasheet and the AVRDUDE documentation as well as various forum posts.
The fuse defaults for Arduino can be gleaned from boards.txt:
pro.name=Arduino Pro or Pro Mini
pro.upload.tool=avrdude
pro.upload.protocol=arduino
pro.bootloader.tool=avrdude
pro.bootloader.unlock_bits=0x3F
pro.bootloader.lock_bits=0x0F
...
## Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328
menu.cpu.pro.8MHzatmega328=ATmega328 (3.3V, 8 MHz)
menu.cpu.pro.8MHzatmega328.upload.maximum_size=30720
menu.cpu.pro.8MHzatmega328.upload.speed=57600
menu.cpu.pro.8MHzatmega328.bootloader.low_fuses=0xFF
menu.cpu.pro.8MHzatmega328.bootloader.high_fuses=0xDA
menu.cpu.pro.8MHzatmega328.bootloader.extended_fuses=0x05
menu.cpu.pro.8MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex
I'm not sure what "unlock_bits" does, it's not mentioned in the ATMega328p data sheet, but the rest is pretty clear.
So, I whipped up a batch file to try when my Usbtiny ISP arrives (ordered it yesterday).
@rem Erase chip
avrdude -p atmega328p -c usbtiny -b57600 -e
@rem Upload the program
avrdude -p atmega328p -c usbtiny -b57600 -D -U flash:w:d:\hexfiles\MyProgram.hex:i
@rem Set Low Fuse byte exactly as Arduno does (all disabled, apparently)
avrdude -p atmega328p -c usbtiny -b57600 -D -u -U lfuse:w:0xFF:m
@rem Set High Fuse Byte to disable bootloader and just run the MyProgram directly
avrdude -p atmega328p -c usbtiny -b57600 -D -u -U hfuse:w:0xDF:m
@rem Set extended fuse to enable brownout detection at ~2.7V (Exactly the same as Arduino defaults)
avrdude -p atmega328p -c usbtiny -b57600 -D -u -U efuse:w:0x05:m
@rem Lock down the flash to disable read/write
avrdude -p atmega328p -c usbtiny -b57600 -D -u -U lock:w:0xFC:m
Now, I was careful to make sure the High fuse byte has SPIEN set to 0, meaning that serial programming is enabled.
The only other change in that byte was that I disabled the bootloader to allow my program run directly by clearing (setting to 1) the bits for BOOTRST (bit 0), BOOTSZ0 (bit 1), and BOOTSZ1 (bit 2).
So, the High fuse byte looks like this:
RSTDISBL = 1 (meaning external reset enabled)
DWEN = 1 (meaning debug wire disabled)
SPIEN = 0 (meaning serial programming is enabled)
WDTON = 1 (meaing watchdog timer is not always enabled)
EESAVE = 1 (meaning EEPROM will not be preserved during chip erase)
BOOTSZ1 = 1 (not needed since BOOTRST is not set to enable bootloader)
BOOTSZ2 = 1 (not needed since BOOTRST is not set to enable bootloader)
BOOTRST = 1 (meaning a bootloader is not used and program should start immeidately after reset)
I may first try to burn the bootloader first from the IDE as described earlier just to test the ISP is working.
I know this is a monster post, but I really want to make sure I've got my ducks in a row and there is a lot that needs to be right. I've done my homework, I just need it graded.