bios support for HD files; Teensy 32-MB HD image support

This commit is contained in:
Jorj Bauer 2017-12-29 15:35:47 -05:00
parent 0fecbd3956
commit 8aafabc61e
7 changed files with 113 additions and 34 deletions

View File

@ -26,17 +26,20 @@ As with many emulators, you have to go get the ROMs yourself. I've got
the ROMs that I dumped out of my Apple //e. You can probably get yours
a lot easier.
There are three files that you'll need:
There are four files that you'll need:
* apple2e.rom -- a 32k dump of the entire Apple //e ROM
* disk.rom -- a 256 byte dump of the DiskII controller ROM (16-sector P5)
* parallel.rom -- a 256 byte dump of the Apple Parallel Card
* HDDRVR.BIN -- a 256 byte hard drive driver from AppleWin
(https://github.com/AppleWin/AppleWin/blob/master/firmware/HDD/HDDRVR.BIN)
The MD5 sums of those files are:
* 003a780b461c96ae3e72861ed0f4d3d9 apple2e.rom
* 2020aa1413ff77fe29353f3ee72dc295 disk.rom
* 5902996f16dc78fc013f6e1db14805b3 parallel.rom
* e91f379957d87aa0af0c7255f6ee6ba0 HDDRVR.BIN
From those, the appropriate headers will be automatically generated by
"make roms" (or any other target that relies on the ROMs).

View File

@ -101,6 +101,11 @@ void AppleVM::insertDisk(uint8_t drivenum, const char *filename, bool drawIt)
disk6->insertDisk(drivenum, filename, drawIt);
}
const char *AppleVM::HDName(uint8_t drivenum)
{
return hd32->diskName(drivenum);
}
void AppleVM::ejectHD(uint8_t drivenum)
{
hd32->ejectDisk(drivenum);

View File

@ -30,6 +30,7 @@ class AppleVM : public VM {
void ejectDisk(uint8_t drivenum);
void insertDisk(uint8_t drivenum, const char *filename, bool drawIt = true);
const char *HDName(uint8_t drivenum);
void ejectHD(uint8_t drivenum);
void insertHD(uint8_t drivenum, const char *filename);

View File

@ -238,7 +238,7 @@ int main(int argc, char *argv[])
}
// FIXME: fixed test disk...
((AppleVM *)g_vm)->insertHD(0, "hd32.img");
// ((AppleVM *)g_vm)->insertHD(0, "hd32.img");
nonblock(NB_ENABLE);

View File

@ -12,16 +12,18 @@
enum {
ACT_EXIT = 0,
ACT_RESET = 1,
ACT_REBOOT = 2,
ACT_COLDBOOT = 2,
ACT_MONITOR = 3,
ACT_DISPLAYTYPE = 4,
ACT_DEBUG = 5,
ACT_DISK1 = 6,
ACT_DISK2 = 7,
ACT_VOLPLUS = 8,
ACT_VOLMINUS = 9,
ACT_HD1 = 8,
ACT_HD2 = 9,
ACT_VOLPLUS = 10,
ACT_VOLMINUS = 11,
NUM_ACTIONS = 10
NUM_ACTIONS = 12
};
const char *titles[NUM_ACTIONS] = { "Resume",
@ -32,6 +34,8 @@ const char *titles[NUM_ACTIONS] = { "Resume",
"Debug: %s",
"%s Disk 1",
"%s Disk 2",
"%s HD 1",
"%s HD 2",
"Volume +",
"Volume -"
};
@ -86,7 +90,7 @@ bool BIOS::runUntilDone()
switch (prevAction = GetAction(prevAction)) {
case ACT_EXIT:
goto done;
case ACT_REBOOT:
case ACT_COLDBOOT:
ColdReboot();
goto done;
case ACT_RESET:
@ -124,6 +128,26 @@ bool BIOS::runUntilDone()
}
}
break;
case ACT_HD1:
if (((AppleVM *)g_vm)->HDName(0)[0] != '\0') {
((AppleVM *)g_vm)->ejectHD(0);
} else {
if (SelectDiskImage()) {
((AppleVM *)g_vm)->insertHD(0, staticPathConcat(rootPath, fileDirectory[selectedFile]));
goto done;
}
}
break;
case ACT_HD2:
if (((AppleVM *)g_vm)->HDName(1)[0] != '\0') {
((AppleVM *)g_vm)->ejectHD(1);
} else {
if (SelectDiskImage()) {
((AppleVM *)g_vm)->insertHD(1, staticPathConcat(rootPath, fileDirectory[selectedFile]));
goto done;
}
}
break;
case ACT_VOLPLUS:
g_volume ++;
if (g_volume > 15) {
@ -204,12 +228,14 @@ bool BIOS::isActionActive(int8_t action)
switch (action) {
case ACT_EXIT:
case ACT_RESET:
case ACT_REBOOT:
case ACT_COLDBOOT:
case ACT_MONITOR:
case ACT_DISPLAYTYPE:
case ACT_DEBUG:
case ACT_DISK1:
case ACT_DISK2:
case ACT_HD1:
case ACT_HD2:
return true;
case ACT_VOLPLUS:
@ -225,11 +251,13 @@ bool BIOS::isActionActive(int8_t action)
void BIOS::DrawMainMenu(int8_t selection)
{
((TeensyDisplay *)g_display)->clrScr();
g_display->drawString(M_NORMAL, 0, 12, "BIOS Configuration");
g_display->drawString(M_NORMAL, 0, 0, "BIOS Configuration");
for (int i=0; i<NUM_ACTIONS; i++) {
char buf[25];
if (i == ACT_DISK1 || i == ACT_DISK2) {
sprintf(buf, titles[i], ((AppleVM *)g_vm)->DiskName(i - ACT_DISK1)[0] ? "Eject" : "Insert");
} else if (i == ACT_HD1 || i == ACT_HD2) {
sprintf(buf, titles[i], ((AppleVM *)g_vm)->HDName(i - ACT_HD1)[0] ? "Eject" : "Insert");
} else if (i == ACT_DISPLAYTYPE) {
switch (g_displayType) {
case m_blackAndWhite:
@ -277,9 +305,9 @@ void BIOS::DrawMainMenu(int8_t selection)
}
if (isActionActive(i)) {
g_display->drawString(selection == i ? M_SELECTED : M_NORMAL, 10, 50 + 14 * i, buf);
g_display->drawString(selection == i ? M_SELECTED : M_NORMAL, 10, 20 + 14 * i, buf);
} else {
g_display->drawString(selection == i ? M_SELECTDISABLED : M_DISABLED, 10, 50 + 14 * i, buf);
g_display->drawString(selection == i ? M_SELECTDISABLED : M_DISABLED, 10, 20 + 14 * i, buf);
}
}
@ -402,8 +430,7 @@ uint8_t BIOS::GatherFilenames(uint8_t pageOffset)
while (1) {
char fn[BIOS_MAXPATH];
// FIXME: add po, nib
int8_t idx = g_filemanager->readDir(rootPath, "dsk", fn, startNum + count, BIOS_MAXPATH);
int8_t idx = g_filemanager->readDir(rootPath, "dsk,.po,nib,img", fn, startNum + count, BIOS_MAXPATH);
if (idx == -1) {
return count;

View File

@ -10,6 +10,9 @@ DIR dir;
FILINFO fno;
FIL fil;
int8_t rawFd = -1;
FIL rawFil;
static TCHAR *char2tchar( const char *charString, int nn, TCHAR *output)
{
int ii;
@ -42,6 +45,12 @@ TeensyFileManager::~TeensyFileManager()
int8_t TeensyFileManager::openFile(const char *name)
{
// invalidate the raw file cache
if (rawFd != -1) {
f_close(&rawFil);
rawFd = -1;
}
// See if there's a hole to re-use...
for (int i=0; i<numCached; i++) {
if (cachedNames[i][0] == '\0') {
@ -68,6 +77,12 @@ int8_t TeensyFileManager::openFile(const char *name)
void TeensyFileManager::closeFile(int8_t fd)
{
// invalidate the raw file cache
if (rawFd != -1) {
f_close(&rawFil);
rawFd = -1;
}
// invalid fd provided?
if (fd < 0 || fd >= numCached)
return;
@ -136,7 +151,7 @@ int8_t TeensyFileManager::readDir(const char *where, const char *suffix, char *o
}
p = strstr(p, ",")+1;
}
if (matchesAny)
if (!matchesAny)
continue;
} else {
// one suffix to check
@ -273,6 +288,36 @@ bool TeensyFileManager::writeTrack(int8_t fd, uint8_t *fromWhere, bool isNib)
return (v == (isNib ? 0x1a00 : (256*16)));
}
bool TeensyFileManager::_prepCache(int8_t fd)
{
FRESULT rc;
if (rawFd == -1 ||
rawFd != fd) {
// Not our cached file, or we have no cached file
if (rawFd != -1) {
// Close the old one if we had one
Serial.println("closing old HD cache");
f_close(&rawFil);
rawFd = -1;
}
// Open the new one
TCHAR buf[MAXPATH];
char2tchar(cachedNames[fd], MAXPATH, buf);
rc = f_open(&rawFil, (TCHAR*) buf, FA_READ|FA_WRITE);
if (rc) {
Serial.println("readByteAt: failed to open");
return false;
}
Serial.println("new cache file open");
rawFd = fd; // cache is live
}
return (!rc);
}
uint8_t TeensyFileManager::readByteAt(int8_t fd, uint32_t pos)
{
// open, seek, read, close.
@ -282,26 +327,21 @@ uint8_t TeensyFileManager::readByteAt(int8_t fd, uint32_t pos)
if (cachedNames[fd][0] == 0)
return false;
// open, seek, read, close.
TCHAR buf[MAXPATH];
char2tchar(cachedNames[fd], MAXPATH, buf);
FRESULT rc = f_open(&fil, (TCHAR*) buf, FA_READ);
if (rc) {
Serial.println("readByteAt: failed to open");
return false;
}
FRESULT rc;
rc = f_lseek(&fil, pos);
_prepCache(fd);
rc = f_lseek(&rawFil, pos);
if (rc) {
Serial.println("readByteAt: seek failed");
f_close(&fil);
return false;
}
uint8_t b;
UINT v;
f_read(&fil, &b, 1, &v);
f_close(&fil);
return (v == 1);
f_read(&rawFil, &b, 1, &v);
// FIXME: check v == 1 & handle error
return b;
}
bool TeensyFileManager::writeByteAt(int8_t fd, uint8_t v, uint32_t pos)
@ -313,14 +353,14 @@ bool TeensyFileManager::writeByteAt(int8_t fd, uint8_t v, uint32_t pos)
if (cachedNames[fd][0] == 0)
return false;
// open, seek, write, close.
TCHAR buf[MAXPATH];
char2tchar(cachedNames[fd], MAXPATH, buf);
FRESULT rc = f_open(&fil, (TCHAR*) buf, FA_WRITE);
rc = f_lseek(&fil, pos);
FRESULT rc;
_prepCache(fd);
rc = f_lseek(&rawFil, pos);
UINT ret;
f_write(&fil, &v, 1, &ret);
f_close(&fil);
f_write(&rawFil, &v, 1, &ret);
return (ret == 1);
}

View File

@ -23,6 +23,9 @@ class TeensyFileManager : public FileManager {
virtual uint8_t readByteAt(int8_t fd, uint32_t pos);
virtual bool writeByteAt(int8_t fd, uint8_t v, uint32_t pos);
private:
bool _prepCache(int8_t fd);
private:
int8_t numCached;