From: Bernie Innocenti Date: Thu, 9 Jul 2026 09:36:09 +0000 (+0200) Subject: lsi53c710: reject illegal group-3 SCRIPTS opcodes X-Git-Url: https://gitweb.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=76f2bbeddff383a317004b3a28823b6d03d05d6a;p=francis%2Fwinuae.git lsi53c710: reject illegal group-3 SCRIPTS opcodes The 53C710 only supports Memory Move in SCRIPTS group 3. Opcodes with reserved bits set, including the 53C810+ Load/Store-register forms, should raise DSTAT.IID instead of being executed. This prevents garbage fetched from non-responding addresses from causing stray DMA or register accesses during the ncr7xx bus access test. --- diff --git a/qemuvga/lsi53c710.cpp b/qemuvga/lsi53c710.cpp index b61eaf83..72441145 100644 --- a/qemuvga/lsi53c710.cpp +++ b/qemuvga/lsi53c710.cpp @@ -1419,40 +1419,22 @@ again: break; case 3: - if ((insn & (1 << 29)) == 0) { - /* Memory move. */ + /* Memory Move (DCMD 0xc0) is the only group-3 instruction on the + 53C710; the Load/Store forms are 53C810+. Reject anything else as + an illegal instruction rather than running away on garbage fetched + from a non-responding address. */ + if ((insn >> 24) != 0xc0) { + lsi_script_dma_interrupt(s, LSI_DSTAT_IID); + break; + } + { uint32_t dest; /* ??? The docs imply the destination address is loaded into the TEMP register. However the Linux drivers rely on - the value being presrved. */ + the value being preserved. */ dest = read_dword(s, s->dsp); s->dsp += 4; lsi_memcpy(s, dest, addr, insn & 0xffffff); - } else { - uint8_t data[7]; - int reg; - int n; - int i; - - if (insn & (1 << 28)) { - addr = s->dsa + sextract32(addr, 0, 24); - } - n = (insn & 7); - reg = (insn >> 16) & 0xff; - if (insn & (1 << 24)) { - pci710_dma_read(pci_dev, addr, data, n); - DPRINTF("Load reg 0x%x size %d addr 0x%08x = %08x\n", reg, n, - addr, *(int *)data); - for (i = 0; i < n; i++) { - lsi_reg_writeb(s, reg + i, data[i]); - } - } else { - DPRINTF("Store reg 0x%x size %d addr 0x%08x\n", reg, n, addr); - for (i = 0; i < n; i++) { - data[i] = lsi_reg_readb(s, reg + i); - } - pci710_dma_write(pci_dev, addr, data, n); - } } } if (insn_processed > 10000 && !s->waiting) {