소스 검색

Support Amiga driver for DaynaPort

Changes required for amiga scsi.device and gvpscsi.device
to use the daynaport properly
Rob Smith 1 년 전
부모
커밋
ff41bbb109
2개의 변경된 파일74개의 추가작업 그리고 17개의 파일을 삭제
  1. 67 17
      lib/SCSI2SD/src/firmware/network.c
  2. 7 0
      lib/SCSI2SD/src/firmware/network.h

+ 67 - 17
lib/SCSI2SD/src/firmware/network.c

@@ -105,6 +105,12 @@ int scsiNetworkCommand()
 
 	DBGMSG_F("------ in scsiNetworkCommand with command 0x%02x (size %d)", command, size);
 
+	// Rather than duplicating code, this just diverts a 'fake' read request to make the gvpscsi.device happy on the Amiga
+	if ((scsiDev.cdb[0] == SCSI_NETWORK_WIFI_CMD) && (scsiDev.cdb[1] == SCSI_NETWORK_WIFI_CMD_ALTREAD)) {
+		// Redirect the command as a READ.
+		command = 0x08;
+	}
+
 	switch (command) {
 	case 0x08:
 		// read(6)
@@ -157,26 +163,62 @@ int scsiNetworkCommand()
 
 			DBGMSG_BUF(scsiDev.data, scsiDev.dataLen);
 		}
+		// Patches around the weirdness on the Amiga SCSI devices
+		if ((scsiDev.cdb[0] == SCSI_NETWORK_WIFI_CMD) && (scsiDev.cdb[1] == SCSI_NETWORK_WIFI_CMD_ALTREAD)) {
+			scsiDev.data[2] = scsiDev.cdb[2];	// for me really
+			int extra = 0;
+			if (scsiDev.cdb[2] == AMIGASCSI_PATCH_24BYTE_BLOCKSIZE) {
+				if (scsiDev.dataLen<90) scsiDev.dataLen = 90;
+				int missing = (scsiDev.dataLen-90) % 24;
+				if (missing) {
+					scsiDev.dataLen += 24 - missing;
+					if (scsiDev.dataLen>NETWORK_PACKET_MAX_SIZE) {
+						extra = scsiDev.dataLen - NETWORK_PACKET_MAX_SIZE;
+						scsiDev.dataLen = NETWORK_PACKET_MAX_SIZE;
+					}
+				}
+				scsiEnterPhase(DATA_IN);
+				scsiWrite(scsiDev.data, scsiDev.dataLen);
+				while (!scsiIsWriteFinished(NULL))
+				{
+					platform_poll();
+				}
+				scsiFinishWrite();
+			} else {
+				extra = scsiDev.dataLen;     // F9 means send in ONE transaction
+				if (extra) scsiEnterPhase(DATA_IN);
+			}
 
-		// DaynaPort driver needs a delay between reading the initial packet size and the data so manually do two transfers
-		scsiEnterPhase(DATA_IN);
-		scsiWrite(scsiDev.data, 6);
-		while (!scsiIsWriteFinished(NULL))
-		{
-			platform_poll();
-		}
-		scsiFinishWrite();
-
-		if (scsiDev.dataLen > 6)
-		{
-			s2s_delay_us(80);
-
-			scsiWrite(scsiDev.data + 6, scsiDev.dataLen - 6);
+			if (extra) {
+				// Just write the extra data to make the padding work for such a large packet
+				scsiWrite(scsiDev.data, extra);
+				while (!scsiIsWriteFinished(NULL))
+				{
+					platform_poll();
+				}
+				scsiFinishWrite();
+			}
+		} else {
+			// DaynaPort driver needs a delay between reading the initial packet size and the data so manually do two transfers
+			scsiEnterPhase(DATA_IN);
+			scsiWrite(scsiDev.data, 6);
 			while (!scsiIsWriteFinished(NULL))
 			{
 				platform_poll();
 			}
 			scsiFinishWrite();
+
+			if (scsiDev.dataLen > 6)
+			{
+				s2s_delay_us(80);
+
+				scsiWrite(scsiDev.data + 6, scsiDev.dataLen - 6);
+				while (!scsiIsWriteFinished(NULL))
+				{
+					platform_poll();
+				}
+				scsiFinishWrite();
+			}
 		}
 
 		scsiDev.status = GOOD;
@@ -395,6 +437,14 @@ int scsiNetworkCommand()
 			scsiDev.phase = STATUS;
 			break;
 		}
+
+		case SCSI_NETWORK_WIFI_CMD_GETMACADDRESS:
+			// Update for the gvpscsi.device on the Amiga as it doesn't like 0x09 command being called! - NOTE this only sends 6 bytes back
+			memcpy(scsiDev.data, scsiDev.boardCfg.wifiMACAddress, sizeof(scsiDev.boardCfg.wifiMACAddress));
+			memset(scsiDev.data + sizeof(scsiDev.boardCfg.wifiMACAddress), 0, sizeof(scsiDev.data) - sizeof(scsiDev.boardCfg.wifiMACAddress));
+
+			scsiDev.dataLen = 6;
+			scsiDev.phase = DATA_IN;
 		}
 		break;
 
@@ -434,7 +484,7 @@ int scsiNetworkEnqueue(const uint8_t *buf, size_t len)
 	{
 		DBGMSG_F("%s: dropping packets in ring, write index caught up to read index", __func__);
 	}
-	
+
 	return 1;
 }
 
@@ -453,10 +503,10 @@ int scsiNetworkPurge(void)
 			scsiNetworkOutboundQueue.readIndex = 0;
 		else
 			scsiNetworkOutboundQueue.readIndex++;
-		
+
 		sent++;
 	}
 
 	return sent;
 }
-#endif // ZULUSCSI_NETWORK
+#endif // ZULUSCSI_NETWORK

+ 7 - 0
lib/SCSI2SD/src/firmware/network.h

@@ -30,6 +30,13 @@ extern "C" {
 #define SCSI_NETWORK_WIFI_CMD_INFO			0x04
 #define SCSI_NETWORK_WIFI_CMD_JOIN			0x05
 
+// Patches to make the DaynaPORT (or whats left of it) work on the Amiga - RobSmithDev
+#define SCSI_NETWORK_WIFI_CMD_ALTREAD       0x08   // gvpscsi.device on AMIGA doesnt like the standard version
+#define SCSI_NETWORK_WIFI_CMD_GETMACADDRESS 0x09   // gvpscsi.device on AMIGA doesnt like the standard version
+
+#define AMIGASCSI_PATCH_24BYTE_BLOCKSIZE 	0xA8   // In this mode, data written is rounded up to the nearest 24-byte boundary
+#define AMIGASCSI_PATCH_SINGLEWRITE_ONLY 	0xA9   // In this mode, data written is always ONLY as one single write command
+
 #ifndef NETWORK_PACKET_QUEUE_SIZE
 # define NETWORK_PACKET_QUEUE_SIZE   20		// must be <= 255
 #endif