AppleIISd/Software/src/Flasher.c

170 lines
3.5 KiB
C
Raw Normal View History

2019-02-25 23:42:47 +00:00
#include "AppleIISd.h"
2019-02-24 10:24:04 +00:00
#include <stdio.h>
#include <errno.h>
#include <conio.h>
#include <apple2enh.h>
2019-03-04 21:01:07 +00:00
#define BIN_FILE_NAME "AppleIISd.bin"
2019-02-25 23:42:47 +00:00
typedef enum
{
2019-03-04 21:01:07 +00:00
STATE_0, // pipe
STATE_1, // slash
STATE_2, // hyphen
STATE_3, // backslash
2019-02-25 23:42:47 +00:00
STATE_LAST // don't use
} STATE_CURSOR_T;
2019-03-04 21:01:07 +00:00
const char state_char[STATE_LAST] = { '|', '/', '-', '\\' };
2019-02-25 23:42:47 +00:00
2019-03-04 21:00:36 +00:00
2019-03-05 19:41:36 +00:00
boolean writeChip(const uint8* pSource, uint8* pDest, uint16 length);
2019-03-04 21:00:36 +00:00
void printStatus(uint8 percentage);
2019-02-25 23:42:47 +00:00
// Binary can't be larger than 2k
2019-03-04 21:00:36 +00:00
uint8 buffer[2048] = { 0 };
2019-02-25 23:42:47 +00:00
2019-02-24 10:24:04 +00:00
int main()
{
2019-03-05 19:41:36 +00:00
int retval = 0;
2019-02-24 10:24:04 +00:00
FILE* pFile;
char slotNum;
2019-02-25 23:42:47 +00:00
APPLE_II_SD_T* pAIISD = (APPLE_II_SD_T*)SLOT_IO_START;
2019-03-04 21:00:36 +00:00
uint8* pSlotRom = SLOT_ROM_START;
uint8* pExtRom = EXT_ROM_START;
2019-02-25 23:42:47 +00:00
2019-03-07 20:29:29 +00:00
videomode(VIDEOMODE_40COL);
2019-02-25 23:42:47 +00:00
clrscr();
2019-03-04 21:01:07 +00:00
cprintf("AppleIISd firmware flasher\r\n");
cprintf("(c) 2019 Florian Reitz\r\n\r\n");
2019-02-24 10:24:04 +00:00
// ask for slot
cursor(1); // enable blinking cursor
cprintf("Slot number (1-7): ");
2019-03-04 21:01:07 +00:00
cscanf("%c", &slotNum);
slotNum -= 0x30;
cursor(0); // disable blinking cursor
2019-02-24 10:24:04 +00:00
// check if slot is valid
if((slotNum < 1) || (slotNum > 7))
{
2019-03-04 21:01:07 +00:00
cprintf("\r\nInvalid slot number!");
2019-03-07 20:29:29 +00:00
cgetc();
2019-02-24 10:24:04 +00:00
return 1; // failure
}
2019-03-04 21:00:36 +00:00
((uint8*)pAIISD) += slotNum << 4;
2019-02-25 23:42:47 +00:00
pSlotRom += slotNum << 8;
2019-02-24 10:24:04 +00:00
// open file
2019-03-04 21:01:07 +00:00
pFile = fopen(BIN_FILE_NAME, "rb");
2019-02-24 10:24:04 +00:00
if(pFile)
{
// read buffer
2019-03-04 21:00:36 +00:00
uint16 fileSize = fread(buffer, 1, sizeof(buffer), pFile);
fclose(pFile);
pFile = NULL;
2019-02-24 10:24:04 +00:00
2019-03-04 21:00:36 +00:00
if(fileSize == 2048)
{
2019-03-04 21:01:07 +00:00
// enable write
pAIISD->status.pgmen = 1;
2019-02-24 10:24:04 +00:00
2019-03-04 21:01:07 +00:00
// clear 0xCFFF
*CFFF = 0;
2019-02-24 10:24:04 +00:00
2019-03-04 21:01:07 +00:00
// write to SLOTROM
cprintf("\r\n\r\nFlashing SLOTROM: ");
2019-03-05 19:41:36 +00:00
if(writeChip(buffer, pSlotRom, 256))
{
// write to EXTROM
cprintf("\r\nFlashing EXTROM: ");
if(writeChip(buffer + 256, pExtRom, fileSize - 256))
{
cprintf("\r\n\r\nFlashing finished!\n");
}
else
{
retval = 1;
}
}
else
{
retval = 1;
}
2019-02-25 23:42:47 +00:00
2019-03-04 21:01:07 +00:00
// disable write
pAIISD->status.pgmen = 0;
2019-03-04 21:00:36 +00:00
}
else
2019-02-25 23:42:47 +00:00
{
2019-03-04 21:00:36 +00:00
cprintf("\r\nWrong file size: %d\r\n", fileSize);
2019-03-05 19:41:36 +00:00
retval = 1;
2019-02-25 23:42:47 +00:00
}
2019-02-24 10:24:04 +00:00
}
else
{
2019-03-04 21:01:07 +00:00
cprintf("\r\nCan't open %s file\r\n", BIN_FILE_NAME);
2019-03-05 19:41:36 +00:00
retval = 1;
2019-02-24 10:24:04 +00:00
}
2019-03-07 20:29:29 +00:00
cgetc();
2019-03-05 19:41:36 +00:00
return retval;
2019-02-24 10:24:04 +00:00
}
2019-03-05 19:41:36 +00:00
boolean writeChip(const uint8* pSource, uint8* pDest, uint16 length)
2019-02-25 23:42:47 +00:00
{
2019-03-04 21:00:36 +00:00
uint32 i;
2019-03-05 19:41:36 +00:00
uint8 data = 0;
2019-02-25 23:42:47 +00:00
for(i=0; i<length; i++)
{
2019-03-05 19:41:36 +00:00
// set 0 if no source
2019-02-25 23:42:47 +00:00
if(pSource)
{
2019-03-05 19:41:36 +00:00
data = pSource[i];
2019-02-25 23:42:47 +00:00
}
2019-03-05 19:41:36 +00:00
*pDest = data;
2019-03-07 20:29:29 +00:00
// use print as writecycle
printStatus((i * 100u / length) + 1);
2019-03-05 19:41:36 +00:00
if(*pDest != data)
2019-02-25 23:42:47 +00:00
{
2019-03-05 19:41:36 +00:00
// verification not successful
cprintf("\r\n\r\n!!! Flashing failed at %p !!!\r\n", pDest);
return FALSE;
2019-02-25 23:42:47 +00:00
}
pDest++;
}
2019-03-05 19:41:36 +00:00
return TRUE;
2019-02-25 23:42:47 +00:00
}
2019-03-04 21:00:36 +00:00
void printStatus(uint8 percentage)
2019-02-25 23:42:47 +00:00
{
static STATE_CURSOR_T state = STATE_0;
2019-03-04 21:00:36 +00:00
uint8 wait = 0;
uint8 x = wherex();
2019-03-04 21:01:07 +00:00
char cState = (percentage < 100) ? state_char[state] : ' ';
2019-03-07 20:29:29 +00:00
cprintf("% 3hhu%% %c", percentage, cState);
2019-02-25 23:42:47 +00:00
gotox(x);
2019-02-24 10:24:04 +00:00
2019-03-04 21:01:07 +00:00
while(wait < 0xff)
{
wait++;
}
2019-02-25 23:42:47 +00:00
state++;
if(state == STATE_LAST)
{
state = STATE_0;
}
}