forked from Apple-2-HW/AppleIISd
Merge branch 'flasher'
This commit is contained in:
commit
2b4a8e85ae
2
.gitignore
vendored
2
.gitignore
vendored
@ -221,3 +221,5 @@ VHDL/AppleIISd\.tim
|
|||||||
VHDL/AppleIISd\.jed
|
VHDL/AppleIISd\.jed
|
||||||
|
|
||||||
Firmware/AppleIISd.bin
|
Firmware/AppleIISd.bin
|
||||||
|
|
||||||
|
Software/Flasher.bin
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -11,8 +11,8 @@
|
|||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\AppleIISd.bin.map" />
|
|
||||||
<None Include="..\README.md" />
|
<None Include="..\README.md" />
|
||||||
|
<None Include="AppleIISd.bin.map" />
|
||||||
<None Include="makefile" />
|
<None Include="makefile" />
|
||||||
<None Include="Makefile.options" />
|
<None Include="Makefile.options" />
|
||||||
<None Include="obj\AppleIISd.lst" />
|
<None Include="obj\AppleIISd.lst" />
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
</None>
|
</None>
|
||||||
<None Include="Makefile.options" />
|
<None Include="Makefile.options" />
|
||||||
<None Include="..\README.md" />
|
<None Include="..\README.md" />
|
||||||
<None Include="..\AppleIISd.bin.map" />
|
<None Include="AppleIISd.bin.map" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="src">
|
<Filter Include="src">
|
||||||
|
7
Firmware/make_image.sh
Executable file
7
Firmware/make_image.sh
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
make clean
|
||||||
|
make OPTIONS=mapfile,listing
|
||||||
|
java -jar ../Binary/AppleCommander-ac-1.5.0.jar -d ../Binary/Flasher.dsk appleiisd.bin
|
||||||
|
java -jar ../Binary/AppleCommander-ac-1.5.0.jar -p ../Binary/Flasher.dsk appleiisd.bin $00 < AppleIISd.bin
|
||||||
|
cp AppleIISd.bin ../Binary/
|
7
Software/make_image.sh
Executable file
7
Software/make_image.sh
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
make clean
|
||||||
|
make
|
||||||
|
java -jar ../Binary/AppleCommander-ac-1.5.0.jar -d ../Binary/Flasher.dsk flasher
|
||||||
|
java -jar ../Binary/AppleCommander-ac-1.5.0.jar -as ../Binary/Flasher.dsk flasher < Flasher.bin
|
||||||
|
cp Flasher.bin ../Binary/
|
@ -6,16 +6,20 @@ typedef unsigned short uint16;
|
|||||||
typedef unsigned long uint32;
|
typedef unsigned long uint32;
|
||||||
typedef unsigned char boolean;
|
typedef unsigned char boolean;
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
|
#endif
|
||||||
|
#ifndef FALSE
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SLOT_IO_START (uint8*)0xC080
|
#define SLOT_IO_START (volatile uint8*)0xC080
|
||||||
#define SLOT_ROM_START (uint8*)0xC000
|
#define SLOT_ROM_START (volatile uint8*)0xC000
|
||||||
#define EXT_ROM_START (uint8*)0xC800
|
#define EXT_ROM_START (volatile uint8*)0xC800
|
||||||
|
|
||||||
#define CFFF (uint8*)0xCFFF
|
#define CFFF (volatile uint8*)0xCFFF
|
||||||
|
|
||||||
typedef struct
|
typedef volatile struct
|
||||||
{
|
{
|
||||||
// data register
|
// data register
|
||||||
// +0
|
// +0
|
||||||
@ -40,12 +44,9 @@ typedef struct
|
|||||||
uint8 status;
|
uint8 status;
|
||||||
} status;
|
} status;
|
||||||
|
|
||||||
// clock divisor register
|
// clock divisor register, unused
|
||||||
// +2
|
// +2
|
||||||
union
|
uint8 clkDiv;
|
||||||
{
|
|
||||||
unsigned clkDiv : 2;
|
|
||||||
};
|
|
||||||
|
|
||||||
// slave select and card state register
|
// slave select and card state register
|
||||||
// +3
|
// +3
|
||||||
@ -56,8 +57,8 @@ typedef struct
|
|||||||
unsigned slaveSel : 1;
|
unsigned slaveSel : 1;
|
||||||
unsigned : 3;
|
unsigned : 3;
|
||||||
unsigned sdhc : 1;
|
unsigned sdhc : 1;
|
||||||
unsigned wp : 1;
|
const unsigned wp : 1;
|
||||||
unsigned card : 1;
|
const unsigned card : 1;
|
||||||
unsigned inited : 1;
|
unsigned inited : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
#include "AppleIISd.h"
|
#include "AppleIISd.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <conio.h>
|
#include <conio.h>
|
||||||
|
#include <string.h>
|
||||||
#include <apple2enh.h>
|
#include <apple2enh.h>
|
||||||
|
|
||||||
|
// Binary can't be larger than 2k
|
||||||
|
#define BUFFER_SIZE 2048
|
||||||
#define BIN_FILE_NAME "AppleIISd.bin"
|
#define BIN_FILE_NAME "AppleIISd.bin"
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -14,33 +18,33 @@ typedef enum
|
|||||||
STATE_2, // hyphen
|
STATE_2, // hyphen
|
||||||
STATE_3, // backslash
|
STATE_3, // backslash
|
||||||
|
|
||||||
STATE_LAST // don't use
|
STATE_LAST // don't use
|
||||||
} STATE_CURSOR_T;
|
} STATE_CURSOR_T;
|
||||||
|
|
||||||
const char state_char[STATE_LAST] = { '|', '/', '-', '\\' };
|
const char state_char[STATE_LAST] = { '|', '/', '-', '\\' };
|
||||||
|
static uint8 buffer[BUFFER_SIZE];
|
||||||
|
|
||||||
|
static void writeChip(const uint8* pSource, volatile uint8* pDest, uint16 length);
|
||||||
boolean writeChip(const uint8* pSource, uint8* pDest, uint16 length);
|
static boolean verifyChip(const uint8* pSource, volatile uint8* pDest, uint16 length);
|
||||||
void printStatus(uint8 percentage);
|
static void printStatus(uint8 percentage);
|
||||||
|
|
||||||
// Binary can't be larger than 2k
|
|
||||||
uint8 buffer[2048] = { 0 };
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
int retval = 0;
|
int retval = 1;
|
||||||
FILE* pFile;
|
FILE* pFile;
|
||||||
char slotNum;
|
char slotNum;
|
||||||
|
boolean erase = FALSE;
|
||||||
|
uint16 fileSize = 0;
|
||||||
|
|
||||||
APPLE_II_SD_T* pAIISD = (APPLE_II_SD_T*)SLOT_IO_START;
|
APPLE_II_SD_T* pAIISD = (APPLE_II_SD_T*)SLOT_IO_START;
|
||||||
uint8* pSlotRom = SLOT_ROM_START;
|
volatile uint8* pSlotRom = SLOT_ROM_START;
|
||||||
uint8* pExtRom = EXT_ROM_START;
|
volatile uint8 dummy;
|
||||||
|
|
||||||
videomode(VIDEOMODE_40COL);
|
videomode(VIDEOMODE_40COL);
|
||||||
clrscr();
|
clrscr();
|
||||||
cprintf("AppleIISd firmware flasher\r\n");
|
cprintf("AppleIISd firmware flasher V1.2\r\n");
|
||||||
cprintf("(c) 2019 Florian Reitz\r\n\r\n");
|
cprintf("(c) 2019-2020 Florian Reitz\r\n\r\n");
|
||||||
|
|
||||||
// ask for slot
|
// ask for slot
|
||||||
cursor(1); // enable blinking cursor
|
cursor(1); // enable blinking cursor
|
||||||
cprintf("Slot number (1-7): ");
|
cprintf("Slot number (1-7): ");
|
||||||
@ -48,6 +52,18 @@ int main()
|
|||||||
slotNum -= 0x30;
|
slotNum -= 0x30;
|
||||||
cursor(0); // disable blinking cursor
|
cursor(0); // disable blinking cursor
|
||||||
|
|
||||||
|
if(slotNum == 0)
|
||||||
|
{
|
||||||
|
// erase device
|
||||||
|
erase = TRUE;
|
||||||
|
// ask for slot
|
||||||
|
cursor(1); // enable blinking cursor
|
||||||
|
cprintf("Erase device in slot number (1-7): ");
|
||||||
|
cscanf("%c", &slotNum);
|
||||||
|
slotNum -= 0x30;
|
||||||
|
cursor(0); // disable blinking cursor
|
||||||
|
}
|
||||||
|
|
||||||
// check if slot is valid
|
// check if slot is valid
|
||||||
if((slotNum < 1) || (slotNum > 7))
|
if((slotNum < 1) || (slotNum > 7))
|
||||||
{
|
{
|
||||||
@ -59,94 +75,114 @@ int main()
|
|||||||
((uint8*)pAIISD) += slotNum << 4;
|
((uint8*)pAIISD) += slotNum << 4;
|
||||||
pSlotRom += slotNum << 8;
|
pSlotRom += slotNum << 8;
|
||||||
|
|
||||||
// open file
|
if(erase)
|
||||||
pFile = fopen(BIN_FILE_NAME, "rb");
|
|
||||||
if(pFile)
|
|
||||||
{
|
{
|
||||||
// read buffer
|
fileSize = BUFFER_SIZE;
|
||||||
uint16 fileSize = fread(buffer, 1, sizeof(buffer), pFile);
|
memset(buffer, 0, sizeof(buffer));
|
||||||
fclose(pFile);
|
|
||||||
pFile = NULL;
|
|
||||||
|
|
||||||
if(fileSize == 2048)
|
|
||||||
{
|
|
||||||
// enable write
|
|
||||||
pAIISD->status.pgmen = 1;
|
|
||||||
|
|
||||||
// clear 0xCFFF
|
|
||||||
*CFFF = 0;
|
|
||||||
|
|
||||||
// write to SLOTROM
|
|
||||||
cprintf("\r\n\r\nFlashing SLOTROM: ");
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// disable write
|
|
||||||
pAIISD->status.pgmen = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cprintf("\r\nWrong file size: %d\r\n", fileSize);
|
|
||||||
retval = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cprintf("\r\nCan't open %s file\r\n", BIN_FILE_NAME);
|
// open file
|
||||||
retval = 1;
|
pFile = fopen(BIN_FILE_NAME, "rb");
|
||||||
|
if(pFile)
|
||||||
|
{
|
||||||
|
// read buffer
|
||||||
|
fileSize = fread(buffer, 1, sizeof(buffer), pFile);
|
||||||
|
fclose(pFile);
|
||||||
|
pFile = NULL;
|
||||||
|
|
||||||
|
if(fileSize != BUFFER_SIZE)
|
||||||
|
{
|
||||||
|
cprintf("\r\nWrong file size: %d\r\n", fileSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cprintf("\r\nCan't open %s file\r\n", BIN_FILE_NAME);
|
||||||
|
fileSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fileSize == BUFFER_SIZE)
|
||||||
|
{
|
||||||
|
// enable write
|
||||||
|
pAIISD->status.pgmen = 1;
|
||||||
|
|
||||||
|
// write to SLOTROM
|
||||||
|
cprintf("\r\n\r\nFlashing SLOTROM: ");
|
||||||
|
writeChip(buffer, pSlotRom, 256);
|
||||||
|
|
||||||
|
cprintf("\r\nVerifying SLOTROM: ");
|
||||||
|
if(verifyChip(buffer, pSlotRom, 256))
|
||||||
|
{
|
||||||
|
// write to EXT_ROM
|
||||||
|
cprintf("\r\n\r\nFlashing EXTROM: ");
|
||||||
|
|
||||||
|
// clear CFFF and dummy read to enable correct EXT_ROM
|
||||||
|
dummy = *CFFF;
|
||||||
|
dummy = *pSlotRom;
|
||||||
|
|
||||||
|
writeChip(buffer + 256, EXT_ROM_START, fileSize - 256);
|
||||||
|
cprintf("\r\nVerifying EXTROM: ");
|
||||||
|
|
||||||
|
dummy = *CFFF;
|
||||||
|
dummy = *pSlotRom;
|
||||||
|
|
||||||
|
if(verifyChip(buffer + 256, EXT_ROM_START, fileSize - 256))
|
||||||
|
{
|
||||||
|
cprintf("\r\n\r\nFlashing finished!\n");
|
||||||
|
retval = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// disable write
|
||||||
|
pAIISD->status.pgmen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cgetc();
|
cgetc();
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean writeChip(const uint8* pSource, uint8* pDest, uint16 length)
|
static void writeChip(const uint8* pSource, volatile uint8* pDest, uint16 length)
|
||||||
{
|
{
|
||||||
uint32 i;
|
uint32 i;
|
||||||
uint8 data = 0;
|
volatile uint8 readData;
|
||||||
|
|
||||||
for(i=0; i<length; i++)
|
for(i=0; i<length; i++)
|
||||||
{
|
{
|
||||||
// set 0 if no source
|
pDest[i] = pSource[i];
|
||||||
if(pSource)
|
|
||||||
{
|
|
||||||
data = pSource[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
*pDest = data;
|
|
||||||
|
|
||||||
// use print as writecycle
|
|
||||||
printStatus((i * 100u / length) + 1);
|
printStatus((i * 100u / length) + 1);
|
||||||
|
|
||||||
if(*pDest != data)
|
// wait for write cycle
|
||||||
|
do
|
||||||
|
{
|
||||||
|
readData = pDest[i];
|
||||||
|
}
|
||||||
|
while((readData & 0x80) != (pSource[i] & 0x80));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean verifyChip(const uint8* pSource, volatile uint8* pDest, uint16 length)
|
||||||
|
{
|
||||||
|
uint32 i;
|
||||||
|
|
||||||
|
for(i=0; i<length; i++)
|
||||||
|
{
|
||||||
|
printStatus((i * 100u / length) + 1);
|
||||||
|
|
||||||
|
if(pDest[i] != pSource[i])
|
||||||
{
|
{
|
||||||
// verification not successful
|
// verification not successful
|
||||||
cprintf("\r\n\r\n!!! Flashing failed at %p !!!\r\n", pDest);
|
cprintf("\r\n\r\n!!! Verification failed at %p !!!\r\n", &pDest[i]);
|
||||||
|
cprintf("Was 0x%02hhX, should be 0x%02hhX\r\n", pDest[i], pSource[i]);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pDest++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void printStatus(uint8 percentage)
|
static void printStatus(uint8 percentage)
|
||||||
{
|
{
|
||||||
static STATE_CURSOR_T state = STATE_0;
|
static STATE_CURSOR_T state = STATE_0;
|
||||||
uint8 wait = 0;
|
uint8 wait = 0;
|
||||||
@ -156,11 +192,6 @@ void printStatus(uint8 percentage)
|
|||||||
cprintf("% 3hhu%% %c", percentage, cState);
|
cprintf("% 3hhu%% %c", percentage, cState);
|
||||||
gotox(x);
|
gotox(x);
|
||||||
|
|
||||||
while(wait < 0xff)
|
|
||||||
{
|
|
||||||
wait++;
|
|
||||||
}
|
|
||||||
|
|
||||||
state++;
|
state++;
|
||||||
if(state == STATE_LAST)
|
if(state == STATE_LAST)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user