Skip to content

Commit 0c0b762

Browse files
authored
Merge pull request AppleWin#222 from AppleWin/master
Fix SmartPort Status cmd when reading status to aux mem (AppleWin#1319, PR #1
2 parents df32e56 + d6c1654 commit 0c0b762

File tree

2 files changed

+65
-40
lines changed

2 files changed

+65
-40
lines changed

source/Harddisk.cpp

Lines changed: 62 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ BYTE __stdcall HarddiskInterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BY
589589
switch (addrIdx)
590590
{
591591
case 0x0: // EXECUTE & RETURN STATUS
592-
r = pCard->CmdExecute(pHDD);
592+
r = pCard->CmdExecute(pHDD, nExecutedCycles);
593593
pCard->m_command = (pCard->m_command & SP_Cmd_base) ? SP_Cmd_busyStatus : BLK_Cmd_Status; // Subsequent reads from IO addr 0x0 just executes 'Status' cmd
594594
_ASSERT(pCard->m_fifoIdx == 0);
595595
pCard->m_fifoIdx = 0;
@@ -644,7 +644,7 @@ BYTE __stdcall HarddiskInterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BY
644644
return r;
645645
}
646646

647-
BYTE HarddiskInterfaceCard::CmdExecute(HardDiskDrive* pHDD)
647+
BYTE HarddiskInterfaceCard::CmdExecute(HardDiskDrive* pHDD, const ULONG nExecutedCycles)
648648
{
649649
LOG_DISK("slot-%d, HDD-%d(%02X): Cmd=%02X ", m_slot, (m_command & SP_Cmd_base) ? m_unitNum : GetProDOSBlockDeviceUnit(), m_unitNum, m_command);
650650

@@ -679,7 +679,7 @@ BYTE HarddiskInterfaceCard::CmdExecute(HardDiskDrive* pHDD)
679679
LOG_DISK("ST-BSY: %02X\n", pHDD->m_error);
680680
break;
681681
case SP_Cmd_status:
682-
pHDD->m_error = SmartPortCmdStatus(pHDD);
682+
pHDD->m_error = SmartPortCmdStatus(pHDD, nExecutedCycles);
683683
LOG_DISK("ST: %02X (statusCode: %02X)\n", pHDD->m_error, m_statusCode);
684684
break;
685685
case BLK_Cmd_Read:
@@ -1033,26 +1033,22 @@ HardDiskDrive* HarddiskInterfaceCard::GetUnit(void)
10331033
return &m_hardDiskDrive[m_unitNum - 1];
10341034
}
10351035

1036-
void HarddiskInterfaceCard::SetIdString(WORD addr, const char* str)
1036+
void HarddiskInterfaceCard::SetIdString(std::vector<BYTE>& status, const std::string& idStr)
10371037
{
1038-
BYTE& idStrLen = mem[addr]; // ID string length
1039-
idStrLen = 0;
1038+
const BYTE kMaxIdStrLen = 16;
1039+
size_t idStrLen = idStr.length();
1040+
if (idStrLen > kMaxIdStrLen)
1041+
idStrLen = kMaxIdStrLen;
1042+
status.push_back((BYTE)idStrLen); // Set 'ID string length'
10401043

1041-
WORD idStrAddr = addr + 1;
1042-
for (UINT i = 0; i < 16; i++)
1043-
mem[idStrAddr + i] = ' '; // ID string padded with ASCII spaces
1044+
for (UINT i = 0; i < idStrLen; i++)
1045+
status.push_back(idStr[i]);
10441046

1045-
if (str == NULL)
1046-
return;
1047-
1048-
while (*str && idStrLen < 16)
1049-
{
1050-
idStrLen++;
1051-
mem[idStrAddr++] = *str++;
1052-
}
1047+
for (UINT i = idStrLen; i < kMaxIdStrLen; i++)
1048+
status.push_back(' '); // ID string padded with ASCII spaces
10531049
}
10541050

1055-
BYTE HarddiskInterfaceCard::SmartPortCmdStatus(HardDiskDrive* pHDD)
1051+
BYTE HarddiskInterfaceCard::SmartPortCmdStatus(HardDiskDrive* pHDD, const ULONG nExecutedCycles)
10561052
{
10571053
// Make Firmware version: eg. 1.30.18.0 => 130.18
10581054
UINT fwVerMajorCheck = g_AppleWinVersion[0] * 100 + g_AppleWinVersion[1];
@@ -1066,8 +1062,8 @@ BYTE HarddiskInterfaceCard::SmartPortCmdStatus(HardDiskDrive* pHDD)
10661062

10671063
//
10681064

1069-
WORD statusListAddr = pHDD->m_memblock;
10701065
BYTE r = DEVICE_OK;
1066+
std::vector<BYTE> status;
10711067

10721068
if (m_unitNum == 0) // Unit-0: SmartPort Controller
10731069
{
@@ -1079,19 +1075,18 @@ BYTE HarddiskInterfaceCard::SmartPortCmdStatus(HardDiskDrive* pHDD)
10791075
case SP_Cmd_status_GETDIB:
10801076
{
10811077
// SmartPort driver status (8 bytes)
1082-
mem[statusListAddr++] = numDevices;
1078+
status.push_back(numDevices);
10831079
for (UINT i = 0; i < 7; i++)
1084-
mem[statusListAddr++] = 0; // reserved
1080+
status.push_back(0); // reserved
10851081
if (m_statusCode == SP_Cmd_status_STATUS)
10861082
break;
10871083
// Device Information Block (DIB)
10881084
std::string idStr = "AppleWin SP";
1089-
SetIdString(statusListAddr, idStr.c_str());
1090-
statusListAddr += 17;
1091-
mem[statusListAddr++] = 0x00; // device type (0x00: Apple II memory expansion card)
1092-
mem[statusListAddr++] = 0x00; // device subtype (0x00: Apple II memory expansion card)
1093-
mem[statusListAddr++] = fwVerMajor; // f/w version (major)
1094-
mem[statusListAddr++] = fwVerMinor; // f/w version (minor)
1085+
SetIdString(status, idStr);
1086+
status.push_back(0x00); // device type (0x00: Apple II memory expansion card)
1087+
status.push_back(0x00); // device subtype (0x00: Apple II memory expansion card)
1088+
status.push_back(fwVerMajor); // f/w version (major)
1089+
status.push_back(fwVerMinor); // f/w version (minor)
10951090
break;
10961091
}
10971092
case SP_Cmd_status_GETDCB:
@@ -1117,12 +1112,12 @@ BYTE HarddiskInterfaceCard::SmartPortCmdStatus(HardDiskDrive* pHDD)
11171112
// . b3=format allowed, b2=media write protected (block devices only), b1=device currently interrupting (//c only), b0=device currently open (char device only)
11181113
BYTE generalStatus = isImageLoaded ? 0xF8 : 0xE8; // Loaded: b#11111000: bwrlf--- / Not loaded: b#11101000: bwr-f---
11191114
if (pHDD->m_bWriteProtected) generalStatus |= (1 << 2);
1120-
mem[statusListAddr++] = generalStatus;
1115+
status.push_back(generalStatus);
11211116

11221117
const UINT imageSizeInBlocks = isImageLoaded ? GetImageSizeInBlocks(pHDD->m_imagehandle) : 0;
1123-
mem[statusListAddr++] = imageSizeInBlocks & 0xff; // num blocks (lo)
1124-
mem[statusListAddr++] = (imageSizeInBlocks >> 8) & 0xff; // num blocks (med)
1125-
mem[statusListAddr++] = (imageSizeInBlocks >> 16) & 0xff; // num blocks (hi)
1118+
status.push_back(imageSizeInBlocks & 0xff); // num blocks (lo)
1119+
status.push_back((imageSizeInBlocks >> 8) & 0xff); // num blocks (med)
1120+
status.push_back((imageSizeInBlocks >> 16) & 0xff); // num blocks (hi)
11261121

11271122
if (m_statusCode == SP_Cmd_status_STATUS)
11281123
break;
@@ -1131,12 +1126,11 @@ BYTE HarddiskInterfaceCard::SmartPortCmdStatus(HardDiskDrive* pHDD)
11311126
std::string idStr = "AppleWin SP D#"; // + "01".."99" (device number in decimal)
11321127
idStr += (char)('0' + m_unitNum / 10);
11331128
idStr += (char)('0' + m_unitNum % 10);
1134-
SetIdString(statusListAddr, idStr.c_str());
1135-
statusListAddr += 17;
1136-
mem[statusListAddr++] = 0x02; // device type (0x02: Hard disk)
1137-
mem[statusListAddr++] = 0x20; // device subtype (0x20: Hard disk)
1138-
mem[statusListAddr++] = fwVerMajor; // f/w version (major)
1139-
mem[statusListAddr++] = fwVerMinor; // f/w version (minor)
1129+
SetIdString(status, idStr);
1130+
status.push_back(0x02); // device type (0x02: Hard disk)
1131+
status.push_back(0x20); // device subtype (0x20: Hard disk)
1132+
status.push_back(fwVerMajor); // f/w version (major)
1133+
status.push_back(fwVerMinor); // f/w version (minor)
11401134
break;
11411135
}
11421136
case SP_Cmd_status_GETDCB:
@@ -1148,6 +1142,37 @@ BYTE HarddiskInterfaceCard::SmartPortCmdStatus(HardDiskDrive* pHDD)
11481142
}
11491143
}
11501144

1145+
if (r == DEVICE_OK)
1146+
{
1147+
// Apple II's MMU could be setup so that read & write memory is different,
1148+
// so can't use 'mem' directly, instead use CpuWrite(). (GH#1319)
1149+
WORD statusListAddr = pHDD->m_memblock;
1150+
1151+
// Check that writes don't hit I/O space or ROM
1152+
BYTE page = statusListAddr >> 8;
1153+
const BYTE endPage = (statusListAddr + (WORD)status.size()) >> 8; // OK if endPage wraps to 0x00
1154+
do
1155+
{
1156+
if (!memwrite[page]) // I/O space or ROM
1157+
{
1158+
if (g_nAppMode == MODE_STEPPING)
1159+
DebuggerBreakOnDmaToOrFromIoMemory(page<<8, true);
1160+
//else // Show MessageBox?
1161+
1162+
pHDD->m_error = 1;
1163+
r = BADCTL;
1164+
break;
1165+
}
1166+
}
1167+
while (page++ != endPage);
1168+
1169+
if (r == DEVICE_OK)
1170+
{
1171+
for (BYTE i : status)
1172+
CpuWrite(statusListAddr++, i, nExecutedCycles);
1173+
}
1174+
}
1175+
11511176
return r;
11521177
}
11531178

source/Harddisk.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,10 @@ class HarddiskInterfaceCard : public Card
136136
BYTE GetNumConnectedDevices(void);
137137
BYTE GetProDOSBlockDeviceUnit(void);
138138
HardDiskDrive* GetUnit(void);
139-
BYTE CmdExecute(HardDiskDrive* pHDD);
139+
BYTE CmdExecute(HardDiskDrive* pHDD, const ULONG nExecutedCycles);
140140
BYTE CmdStatus(HardDiskDrive* pHDD);
141-
void SetIdString(WORD addr, const char* str);
142-
BYTE SmartPortCmdStatus(HardDiskDrive* pHDD);
141+
void SetIdString(std::vector<BYTE>& status, const std::string& idStr);
142+
BYTE SmartPortCmdStatus(HardDiskDrive* pHDD, const ULONG nExecutedCycles);
143143
UINT GetImageSizeInBlocks(ImageInfo* const pImageInfo, const bool is16bit = false);
144144
void SaveSnapshotHDDUnit(YamlSaveHelper& yamlSaveHelper, const UINT unit);
145145
bool LoadSnapshotHDDUnit(YamlLoadHelper& yamlLoadHelper, const UINT unit, const UINT version);

0 commit comments

Comments
 (0)