#define LSI_SCNTL0_TRG 0x01
#define LSI_SCNTL0_AAP 0x02
-#define LSI_SCNTL0_EPG 0x08
+#define LSI_SCNTL0_EPG 0x04
#define LSI_SCNTL0_EPC 0x08
#define LSI_SCNTL0_WATN 0x10,
#define LSI_SCNTL0_START 0x20
#define LSI_CTEST2_DDIR 0x80
#define LSI_CTEST4_SFWR 0x08
+#define LSI_CTEST4_SLBE 0x10
#define LSI_CTEST5_BL2 0x04
#define LSI_CTEST5_DDIR 0x08
return parity;
}
+static bool lsi_scsi_loopback(LSIState710 *s)
+{
+ return (s->ctest4 & LSI_CTEST4_SLBE) && (s->scntl1 & LSI_SCNTL1_ADB);
+}
+
static inline int lsi_irq_on_rsl(LSIState710 *s)
{
return 0; //return (s->sien0 & LSI_SIST0_RSL) && (s->scid & LSI_SCID_RRE);
/* This is needed by the linux drivers. We currently only update it
during the MSG IN phase. */
return s->sidl;
+ case 0x0a: /* SBDL */
+ return lsi_scsi_loopback(s) ? s->sodl : 0;
case 0xb: /* SBCL */
+ if (lsi_scsi_loopback(s)) {
+ tmp = s->socl;
+ if (!(s->scntl0 & LSI_SCNTL0_TRG))
+ tmp &= ~0x48;
+ return tmp;
+ }
tmp = 0;
if (s->scntl1 & LSI_SCNTL1_CON) {
/* NetBSD 1.x checks for REQ */
lsi_update_irq(s);
return tmp;
case 0x0e: /* SSTAT1 */
- return s->sstat1;
+ tmp = s->sstat1 & ~0x03;
+ if (s->scntl1 & LSI_SCNTL1_RST)
+ tmp |= 0x02;
+ if (lsi_scsi_loopback(s) && (s->scntl0 & LSI_SCNTL0_EPG) &&
+ lsi_scsi_parity(s->sodl, s->scntl1))
+ tmp |= 0x01;
+ return tmp;
case 0x0f: /* SSTAT2 */
return (s->sstat2 & 0x0f) | (s->scsi_fifo_count << 4);
CASE_GET_REG32(dsa, 0x10)
break;
case 0x01: /* SCNTL1 */
s->scntl1 = val;
- if (val & LSI_SCNTL1_ADB) {
- BADF("Immediate Arbritration not implemented\n");
- }
+ /* SCNTL1.ADB drives SODL/SOCL onto the bus; in loopback mode the
+ read handlers feed those latches back through SBDL/SBCL. */
if (val & LSI_SCNTL1_RST) {
if (!(s->sstat0 & LSI_SSTAT0_RST)) {
// qbus_reset_all(&s->bus.qbus);
s->scsi_fifo[s->scsi_fifo_count++] = (parity << 8) | val;
}
break;
+ case 0x07: /* SOCL */
+ s->socl = val;
+ break;
case 0x0b: /* SBCL */
lsi_set_phase (s, val & PHASE_MASK);
break;