@@ -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
0 commit comments