mirror of
https://github.com/una1veritas/mac-floppy-emu.git
synced 2024-06-15 08:29:30 +00:00
127 lines
4.4 KiB
C
Executable File
127 lines
4.4 KiB
C
Executable File
/*-------------------------------------------------------------------------/
|
|
/ Stand-alone MMC boot loader R0.01
|
|
/--------------------------------------------------------------------------/
|
|
/
|
|
/ Copyright (C) 2010, ChaN, all right reserved.
|
|
/
|
|
/ * This software 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.
|
|
/
|
|
/--------------------------------------------------------------------------/
|
|
/ Dec 6, 2010 R0.01 First release
|
|
/--------------------------------------------------------------------------/
|
|
/ This is a stand-alone MMC/SD boot loader for megaAVRs. It requires a 4KB
|
|
/ boot section for code, four GPIO pins for MMC/SD as shown in sch.jpg and
|
|
/ nothing else. To port the boot loader into your project, follow the
|
|
/ instruction sdescribed below.
|
|
/
|
|
/ 1. Setup the hardware. Attach a memory card socket to the any GPIO port
|
|
/ where you like. Select boot size at least 4KB for the boot loader with
|
|
/ BOOTSZ fuses and enable boot loader with BOOTRST fuse.
|
|
/
|
|
/ 2. Setup the software. Change the four port definitions in the asmfunc.S.
|
|
/ Change MCU_TARGET, BOOT_ADR and MCU_FREQ in the Makefile. The BOOT_ADR
|
|
/ is a BYTE address of boot section in the flash. Build the boot loader
|
|
/ and write it to the device with a programmer.
|
|
/
|
|
/ 3. Build the application program and output it in binary form instead of
|
|
/ hex format. Rename the file "app.bin" and put it into the memory card.
|
|
/
|
|
/ 4. Insert the card and turn the target power on. When the boot loader found
|
|
/ the application file, the file is written into the flash memory prior to
|
|
/ start the application program. On-board LED lights (if exist) during
|
|
/ the flash programming operation.
|
|
/
|
|
/--------------------------------------------------------------------------/
|
|
/ Modified by Steve Chamberlin for Floppy Emu, October 2013
|
|
/-------------------------------------------------------------------------*/
|
|
|
|
|
|
#include <avr/io.h>
|
|
#include <avr/pgmspace.h>
|
|
#include <util/delay.h>
|
|
#include <string.h>
|
|
#include "pff.h"
|
|
#include "lcd.h"
|
|
|
|
void flash_erase (DWORD); /* Erase a flash page (asmfunc.S) */
|
|
void flash_write (DWORD, const BYTE*); /* Program a flash page (asmfunc.S) */
|
|
|
|
FATFS Fatfs; /* Petit-FatFs work area */
|
|
BYTE Buff[SPM_PAGESIZE]; /* Page data buffer */
|
|
|
|
#define BUTTON_PORT PORTD
|
|
#define BUTTON_PIN PIND
|
|
#define SELECT_BUTTON_PIN 4
|
|
#define PREV_BUTTON_PIN 1
|
|
#define NEXT_BUTTON_PIN 2
|
|
|
|
#define LED_DDR DDRB
|
|
#define LED_PORT PORTB
|
|
#define LED_PIN_NUMBER 3
|
|
|
|
int main (void)
|
|
{
|
|
DWORD fa; /* Flash address */
|
|
WORD br; /* Bytes read */
|
|
|
|
// enable the pull-up resistor for the user buttons
|
|
BUTTON_PORT |= (1<<SELECT_BUTTON_PIN);
|
|
BUTTON_PORT |= (1<<PREV_BUTTON_PIN);
|
|
BUTTON_PORT |= (1<<NEXT_BUTTON_PIN);
|
|
|
|
_delay_ms(10);
|
|
|
|
// if PREV and SELECT are pressed, try to perform an application update
|
|
if (bit_is_clear(BUTTON_PIN, PREV_BUTTON_PIN) &&
|
|
bit_is_clear(BUTTON_PIN, SELECT_BUTTON_PIN))
|
|
{
|
|
// set LED as output
|
|
LED_DDR |= (1<<LED_PIN_NUMBER);
|
|
|
|
LcdInit();
|
|
LcdString(PSTR("FLOPPYXEMUXBOOTLOADER"));
|
|
LcdGoto(0,2);
|
|
|
|
pf_mount(&Fatfs); /* Initialize file system */
|
|
if (pf_open("femu.bin") == FR_OK) /* Open application file */
|
|
{
|
|
LcdString(PSTR("FLASHINGXFEMUQBINXQQQ"));
|
|
|
|
for (fa = 0; fa < BOOT_ADR; fa += SPM_PAGESIZE) /* Update all application pages */
|
|
{
|
|
flash_erase(fa); /* Erase a page */
|
|
memset(Buff, 0xFF, SPM_PAGESIZE); /* Clear buffer */
|
|
pf_read(Buff, SPM_PAGESIZE, &br); /* Load a page data */
|
|
if (br) flash_write(fa, Buff); /* Write it if the data is available */
|
|
|
|
// blink the LED while writing
|
|
LED_PORT ^= (1<<LED_PIN_NUMBER);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// couldn't open the application file
|
|
LcdString(PSTR("FEMUQBINXNOTXFOUND"));
|
|
}
|
|
|
|
// wait for all buttons to be released
|
|
while (bit_is_clear(BUTTON_PIN, PREV_BUTTON_PIN) ||
|
|
bit_is_clear(BUTTON_PIN, SELECT_BUTTON_PIN) ||
|
|
bit_is_clear(BUTTON_PIN, NEXT_BUTTON_PIN))
|
|
{}
|
|
}
|
|
|
|
if (pgm_read_word(0) != 0xFFFF) /* Start application if exist */
|
|
((void(*)(void))0)();
|
|
|
|
/* No application, Halt. */
|
|
LcdInit();
|
|
LcdGoto(0,0);
|
|
LcdString(PSTR("ERRORZXFLASHXISXEMPTY"));
|
|
for (;;) ;
|
|
}
|
|
|