mirror of
https://github.com/JorjBauer/aiie.git
synced 2025-01-14 13:33:08 +00:00
bios support for HD files; Teensy 32-MB HD image support
This commit is contained in:
parent
0fecbd3956
commit
8aafabc61e
@ -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).
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user