diff --git a/src/emu/cpu/es5510/es5510.c b/src/emu/cpu/es5510/es5510.c index 4c542be5c61..25c43be43b0 100644 --- a/src/emu/cpu/es5510/es5510.c +++ b/src/emu/cpu/es5510/es5510.c @@ -11,6 +11,14 @@ #include "es5510.h" #include "cpu/m68000/m68000.h" +#define VERBOSE 0 + +#if VERBOSE +#define LOG(x) do { logerror x; } while(0) +#else +#define LOG(x) +#endif + const device_type ES5510 = &device_creator; #define FLAG_N (1 << 7) @@ -63,9 +71,9 @@ inline static INT32 add(INT32 a, INT32 b, UINT8 &flags) { inline static INT32 saturate(INT32 value, UINT8 &flags) { if (isFlagSet(flags, FLAG_V)) { - return isFlagSet(flags, FLAG_N) ? 0x00800000 : 0x007fffff; + return isFlagSet(flags, FLAG_N) ? 0x00800000 : 0x007fffff; } else { - return value; + return value; } } @@ -84,9 +92,10 @@ inline static INT32 asl(INT32 value, int shift, UINT8 &flags) { es5510_device::es5510_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : cpu_device(mconfig, ES5510, "ES5510", tag, owner, clock) +: cpu_device(mconfig, ES5510, "ES5510", tag, owner, clock) { // Initialize ESP to mostly zeroed, configured for 64k samples of delay line memory, running (not halted) + halt_asserted = false; icount = 0; pc = 0; state = STATE_HALTED; @@ -218,12 +227,12 @@ const op_select_t es5510_device::OPERAND_SELECT[16] = { static inline char * DESCRIBE_SRC_DST(char *s, UINT8 reg, op_src_dst_t src_dst) { switch (src_dst) { case es5510_device::SRC_DST_REG: - return DESCRIBE_REG(s, reg); + return DESCRIBE_REG(s, reg); case es5510_device::SRC_DST_DELAY: - return stpcpy_int(s, "Delay"); + return stpcpy_int(s, "Delay"); case es5510_device::SRC_DST_BOTH: - s = DESCRIBE_REG(s, reg); - return stpcpy_int(s, ",Delay"); + s = DESCRIBE_REG(s, reg); + return stpcpy_int(s, ",Delay"); } // should never happen! return s; @@ -249,17 +258,17 @@ static inline char * DESCRIBE_ALU(char *s, UINT8 opcode, UINT8 aReg, UINT8 bReg, switch (op.operands) { case 0: - return stpcpy_int(s, op.opcode); + return stpcpy_int(s, op.opcode); case 1: - s += sprintf(s, "%s %s >", op.opcode, REGNAME(bReg)); - return DESCRIBE_SRC_DST(s, aReg, opSelect.alu_dst); + s += sprintf(s, "%s %s >", op.opcode, REGNAME(bReg)); + return DESCRIBE_SRC_DST(s, aReg, opSelect.alu_dst); case 2: - s += sprintf(s, "%s %s,", op.opcode, REGNAME(bReg)); - s = DESCRIBE_SRC_DST(s, aReg, opSelect.alu_src); - s += sprintf(s, " >"); - return DESCRIBE_SRC_DST(s, aReg, opSelect.alu_dst); + s += sprintf(s, "%s %s,", op.opcode, REGNAME(bReg)); + s = DESCRIBE_SRC_DST(s, aReg, opSelect.alu_src); + s += sprintf(s, " >"); + return DESCRIBE_SRC_DST(s, aReg, opSelect.alu_dst); } return s; } @@ -268,7 +277,7 @@ static inline char * DESCRIBE_MAC(char *s, UINT8 mac, UINT8 cReg, UINT8 dReg, co { if (mac) { - s += sprintf(s, "MAC + "); + s += sprintf(s, "MAC + "); } s = DESCRIBE_REG(s, dReg); s += sprintf(s, " * "); @@ -297,7 +306,7 @@ static inline char * DESCRIBE_INSTR(char *s, UINT64 instr, UINT32 gpr) s += sprintf(s, "; "); s = DESCRIBE_RAM(s, ramControl, gpr); if (skip) { - s += sprintf(s, "; skippable"); + s += sprintf(s, "; skippable"); } return s; @@ -311,38 +320,38 @@ READ8_MEMBER(es5510_device::host_r) // VFX hack if (mame_stricmp(space.machine().system().name, "vfx") == 0) { - if (space.device().safe_pc() == 0xc091f0) - { - return space.device().state().state_int(M68K_D2); - } + if (space.device().safe_pc() == 0xc091f0) + { + return space.device().state().state_int(M68K_D2); + } } switch(offset) { - case 0x00: logerror("ES5510: Read GPR latch[2]: %02x\n", (gpr_latch >> 16) & 0xff); return (gpr_latch >> 16) & 0xff; - case 0x01: logerror("ES5510: Read GPR latch[1]: %02x\n", (gpr_latch >> 8) & 0xff); return (gpr_latch >> 8) & 0xff; - case 0x02: logerror("ES5510: Read GPR latch[0]: %02x\n", (gpr_latch >> 0) & 0xff); return (gpr_latch >> 0) & 0xff; + case 0x00: LOG(("ES5510: Host Read GPR latch[2]: %02x\n", (gpr_latch >> 16) & 0xff)); return (gpr_latch >> 16) & 0xff; + case 0x01: LOG(("ES5510: Host Read GPR latch[1]: %02x\n", (gpr_latch >> 8) & 0xff)); return (gpr_latch >> 8) & 0xff; + case 0x02: LOG(("ES5510: Host Read GPR latch[0]: %02x\n", (gpr_latch >> 0) & 0xff)); return (gpr_latch >> 0) & 0xff; - case 0x03: logerror("ES5510: Read INSTR latch[5]: %02x\n", (UINT8)((instr_latch >> 40) & 0xff)); return (instr_latch >> 40) & 0xff; - case 0x04: logerror("ES5510: Read INSTR latch[4]: %02x\n", (UINT8)((instr_latch >> 32) & 0xff)); return (instr_latch >> 32) & 0xff; - case 0x05: logerror("ES5510: Read INSTR latch[3]: %02x\n", (UINT8)((instr_latch >> 24) & 0xff)); return (instr_latch >> 24) & 0xff; - case 0x06: logerror("ES5510: Read INSTR latch[2]: %02x\n", (UINT8)((instr_latch >> 16) & 0xff)); return (instr_latch >> 16) & 0xff; - case 0x07: logerror("ES5510: Read INSTR latch[1]: %02x\n", (UINT8)((instr_latch >> 8) & 0xff)); return (instr_latch >> 8) & 0xff; - case 0x08: logerror("ES5510: Read INSTR latch[0]: %02x\n", (UINT8)((instr_latch >> 0) & 0xff)); return (instr_latch >> 0) & 0xff; + case 0x03: LOG(("ES5510: Host Read INSTR latch[5]: %02x\n", (UINT8)((instr_latch >> 40) & 0xff))); return (instr_latch >> 40) & 0xff; + case 0x04: LOG(("ES5510: Host Read INSTR latch[4]: %02x\n", (UINT8)((instr_latch >> 32) & 0xff))); return (instr_latch >> 32) & 0xff; + case 0x05: LOG(("ES5510: Host Read INSTR latch[3]: %02x\n", (UINT8)((instr_latch >> 24) & 0xff))); return (instr_latch >> 24) & 0xff; + case 0x06: LOG(("ES5510: Host Read INSTR latch[2]: %02x\n", (UINT8)((instr_latch >> 16) & 0xff))); return (instr_latch >> 16) & 0xff; + case 0x07: LOG(("ES5510: Host Read INSTR latch[1]: %02x\n", (UINT8)((instr_latch >> 8) & 0xff))); return (instr_latch >> 8) & 0xff; + case 0x08: LOG(("ES5510: Host Read INSTR latch[0]: %02x\n", (UINT8)((instr_latch >> 0) & 0xff))); return (instr_latch >> 0) & 0xff; - case 0x09: logerror("ES5510: Read DIL latch[2]: %02x\n", (dil_latch >> 16) & 0xff); return (dil_latch >> 16) & 0xff; - case 0x0a: logerror("ES5510: Read DIL latch[1]: %02x\n", (dil_latch >> 8) & 0xff); return (dil_latch >> 8) & 0xff; - case 0x0b: logerror("ES5510: Read DIL latch[0]: %02x\n", (dil_latch >> 0) & 0xff); return (dil_latch >> 0) & 0xff; //TODO: docs says that this always returns 0 + case 0x09: LOG(("ES5510: Host Read DIL latch[2]: %02x\n", (dil_latch >> 16) & 0xff)); return (dil_latch >> 16) & 0xff; + case 0x0a: LOG(("ES5510: Host Read DIL latch[1]: %02x\n", (dil_latch >> 8) & 0xff)); return (dil_latch >> 8) & 0xff; + case 0x0b: LOG(("ES5510: Host Read DIL latch[0]: %02x\n", (dil_latch >> 0) & 0xff)); return (dil_latch >> 0) & 0xff; //TODO: docs says that this always returns 0 - case 0x0c: logerror("ES5510: Read DOL latch[2]: %02x\n", (dol_latch >> 16) & 0xff); return (dol_latch >> 16) & 0xff; - case 0x0d: logerror("ES5510: Read DOL latch[1]: %02x\n", (dol_latch >> 8) & 0xff); return (dol_latch >> 8) & 0xff; - case 0x0e: logerror("ES5510: Read DOL latch[0]: %02x\n", (dol_latch >> 0) & 0xff); return (dol_latch >> 0) & 0xff; //TODO: docs says that this always returns 0 + case 0x0c: LOG(("ES5510: Host Read DOL latch[2]: %02x\n", (dol_latch >> 16) & 0xff)); return (dol_latch >> 16) & 0xff; + case 0x0d: LOG(("ES5510: Host Read DOL latch[1]: %02x\n", (dol_latch >> 8) & 0xff)); return (dol_latch >> 8) & 0xff; + case 0x0e: LOG(("ES5510: Host Read DOL latch[0]: %02x\n", (dol_latch >> 0) & 0xff)); return (dol_latch >> 0) & 0xff; //TODO: docs says that this always returns 0 - case 0x0f: logerror("ES5510: Read DADR latch[2]: %02x\n", (dadr_latch >> 16) & 0xff); return (dadr_latch >> 16) & 0xff; - case 0x10: logerror("ES5510: Read DADR latch[1]: %02x\n", (dadr_latch >> 8) & 0xff); return (dadr_latch >> 8) & 0xff; - case 0x11: logerror("ES5510: Read DADR latch[0]: %02x\n", (dadr_latch >> 0) & 0xff); return (dadr_latch >> 0) & 0xff; + case 0x0f: LOG(("ES5510: Host Read DADR latch[2]: %02x\n", (dadr_latch >> 16) & 0xff)); return (dadr_latch >> 16) & 0xff; + case 0x10: LOG(("ES5510: Host Read DADR latch[1]: %02x\n", (dadr_latch >> 8) & 0xff)); return (dadr_latch >> 8) & 0xff; + case 0x11: LOG(("ES5510: Host Read DADR latch[0]: %02x\n", (dadr_latch >> 0) & 0xff)); return (dadr_latch >> 0) & 0xff; - case 0x12: logerror("ES5510: Reading Host Control\n"); return 0; // Host Control + case 0x12: LOG(("ES5510: Host Reading Host Control\n")); return 0; // Host Control case 0x16: return 0x27; // Program Counter, for test purposes only } @@ -353,111 +362,148 @@ READ8_MEMBER(es5510_device::host_r) WRITE8_MEMBER(es5510_device::host_w) { +#if VERBOSE static char buf[1024]; +#endif switch (offset) { case 0x00: - gpr_latch = (gpr_latch&0x00ffff) | ((data&0xff)<<16); - logerror("ES5510: Write GPR latch[2] = %02x -> %06x (%d)\n", data, gpr_latch, SX(gpr_latch)); - break; + gpr_latch = (gpr_latch&0x00ffff) | ((data&0xff)<<16); + LOG(("ES5510: Host Write GPR latch[2] = %02x -> %06x (%d)\n", data, gpr_latch, SX(gpr_latch))); + break; case 0x01: - gpr_latch = (gpr_latch&0xff00ff) | ((data&0xff)<< 8); - logerror("ES5510: Write GPR latch[1] = %02x -> %06x (%d)\n", data, gpr_latch, SX(gpr_latch)); - break; + gpr_latch = (gpr_latch&0xff00ff) | ((data&0xff)<< 8); + LOG(("ES5510: Host Write GPR latch[1] = %02x -> %06x (%d)\n", data, gpr_latch, SX(gpr_latch))); + break; case 0x02: - gpr_latch = (gpr_latch&0xffff00) | ((data&0xff)<< 0); - logerror("ES5510: Write GPR latch[0] = %02x -> %06x (%d)\n", data, gpr_latch, SX(gpr_latch)); - break; + gpr_latch = (gpr_latch&0xffff00) | ((data&0xff)<< 0); + LOG(("ES5510: Host Write GPR latch[0] = %02x -> %06x (%d)\n", data, gpr_latch, SX(gpr_latch))); + break; - /* 0x03 to 0x08 INSTR Register */ - case 0x03: instr_latch = ((instr_latch&U64(0x00ffffffffff)) | ((INT64)data&0xff)<<40); logerror("ES5510: Write INSTR latch[5] = %02x -> %012" I64FMT "x\n", data, instr_latch); break; - case 0x04: instr_latch = ((instr_latch&U64(0xff00ffffffff)) | ((INT64)data&0xff)<<32); logerror("ES5510: Write INSTR latch[4] = %02x -> %012" I64FMT "x\n", data, instr_latch); break; - case 0x05: instr_latch = ((instr_latch&U64(0xffff00ffffff)) | ((INT64)data&0xff)<<24); logerror("ES5510: Write INSTR latch[3] = %02x -> %012" I64FMT "x\n", data, instr_latch); break; - case 0x06: instr_latch = ((instr_latch&U64(0xffffff00ffff)) | ((INT64)data&0xff)<<16); logerror("ES5510: Write INSTR latch[2] = %02x -> %012" I64FMT "x\n", data, instr_latch); break; - case 0x07: instr_latch = ((instr_latch&U64(0xffffffff00ff)) | ((INT64)data&0xff)<< 8); logerror("ES5510: Write INSTR latch[1] = %02x -> %012" I64FMT "x\n", data, instr_latch); break; - case 0x08: instr_latch = ((instr_latch&U64(0xffffffffff00)) | ((INT64)data&0xff)<< 0); logerror("ES5510: Write INSTR latch[0] = %02x -> %012" I64FMT "x\n", data, instr_latch); break; + /* 0x03 to 0x08 INSTR Register */ + case 0x03: instr_latch = ((instr_latch&U64(0x00ffffffffff)) | ((INT64)data&0xff)<<40); LOG(("ES5510: Host Write INSTR latch[5] = %02x -> %012" I64FMT "x\n", data, instr_latch)); break; + case 0x04: instr_latch = ((instr_latch&U64(0xff00ffffffff)) | ((INT64)data&0xff)<<32); LOG(("ES5510: Host Write INSTR latch[4] = %02x -> %012" I64FMT "x\n", data, instr_latch)); break; + case 0x05: instr_latch = ((instr_latch&U64(0xffff00ffffff)) | ((INT64)data&0xff)<<24); LOG(("ES5510: Host Write INSTR latch[3] = %02x -> %012" I64FMT "x\n", data, instr_latch)); break; + case 0x06: instr_latch = ((instr_latch&U64(0xffffff00ffff)) | ((INT64)data&0xff)<<16); LOG(("ES5510: Host Write INSTR latch[2] = %02x -> %012" I64FMT "x\n", data, instr_latch)); break; + case 0x07: instr_latch = ((instr_latch&U64(0xffffffff00ff)) | ((INT64)data&0xff)<< 8); LOG(("ES5510: Host Write INSTR latch[1] = %02x -> %012" I64FMT "x\n", data, instr_latch)); break; + case 0x08: instr_latch = ((instr_latch&U64(0xffffffffff00)) | ((INT64)data&0xff)<< 0); LOG(("ES5510: Host Write INSTR latch[0] = %02x -> %012" I64FMT "x\n", data, instr_latch)); break; - /* 0x09 to 0x0b DIL Register (r/o) */ + /* 0x09 to 0x0b DIL Register (r/o) */ - case 0x0c: dol_latch = (dol_latch&0x00ffff) | ((data&0xff)<<16); logerror("ES5510: Write DOL latch[2] = %02x -> %06x (%d)\n", data, dol_latch, SX(dol_latch)); break; - case 0x0d: dol_latch = (dol_latch&0xff00ff) | ((data&0xff)<< 8); logerror("ES5510: Write DOL latch[1] = %02x -> %06x (%d)\n", data, dol_latch, SX(dol_latch)); break; - case 0x0e: dol_latch = (dol_latch&0xffff00) | ((data&0xff)<< 0); logerror("ES5510: Write DOL latch[0] = %02x -> %06x (%d)\n", data, dol_latch, SX(dol_latch)); break; //TODO: docs says that this always returns 0xff + case 0x0c: dol_latch = (dol_latch&0x00ffff) | ((data&0xff)<<16); LOG(("ES5510: Host Write DOL latch[2] = %02x -> %06x (%d)\n", data, dol_latch, SX(dol_latch))); break; + case 0x0d: dol_latch = (dol_latch&0xff00ff) | ((data&0xff)<< 8); LOG(("ES5510: Host Write DOL latch[1] = %02x -> %06x (%d)\n", data, dol_latch, SX(dol_latch))); break; + case 0x0e: dol_latch = (dol_latch&0xffff00) | ((data&0xff)<< 0); LOG(("ES5510: Host Write DOL latch[0] = %02x -> %06x (%d)\n", data, dol_latch, SX(dol_latch))); break; //TODO: docs says that this always returns 0xff case 0x0f: - dadr_latch = (dadr_latch&0x00ffff) | ((data&0xff)<<16); - if (ram_sel) - { - dil_latch = dram[dadr_latch]; - } - else - { - dram[dadr_latch] = dol_latch; - } - break; + dadr_latch = (dadr_latch&0x00ffff) | ((data&0xff)<<16); + if (ram_sel) + { + dil_latch = dram[dadr_latch]; + } + else + { + dram[dadr_latch] = dol_latch; + } + break; case 0x10: dadr_latch = (dadr_latch&0xff00ff) | ((data&0xff)<< 8); break; case 0x11: dadr_latch = (dadr_latch&0xffff00) | ((data&0xff)<< 0); break; - /* 0x12 Host Control */ + /* 0x12 Host Control */ case 0x14: ram_sel = data & 0x80; /* bit 6 is i/o select, everything else is undefined */break; - /* 0x16 Program Counter (test purpose, r/o?) */ - /* 0x17 Internal Refresh counter (test purpose) */ - /* 0x18 Host Serial Control */ + /* 0x16 Program Counter (test purpose, r/o?) */ + /* 0x17 Internal Refresh counter (test purpose) */ + /* 0x18 Host Serial Control */ case 0x18: - logerror("ES5510: Write Host Serial control %02x: %s, %s, ser3 %s, ser2 %s, ser1 %s, ser0 %s\n", data, + LOG(("ES5510: Host Write Host Serial control %02x: %s, %s, ser3 %s, ser2 %s, ser1 %s, ser0 %s\n", data, data&0x80 ? "Master" : "Slave", data&0x40 ? "Sony" : "I2S", data & 0x20 ? "Out" : "In", data & 0x10 ? "Out" : "In", data & 0x08 ? "Out" : "In", - data & 0x04 ? "Out" : "In"); - break; + data & 0x04 ? "Out" : "In")); + break; - /* 0x1f Halt enable (w) / Frame Counter (r) */ + /* 0x1f Halt enable (w) / Frame Counter (r) */ case 0x1F: - logerror("ES5510: Write Halt Enable %02x; HALT line is %d\n", data, input_state(ES5510_HALT)); - if (input_state(ES5510_HALT)) { - logerror("ES5510: Write to Halt Enable while HALT line is asserted: Halting!\n"); - state = STATE_HALTED; - } - break; + LOG(("ES5510: Host Write Halt Enable %02x; HALT line is %d\n", data, halt_asserted)); + if (halt_asserted) { + LOG(("ES5510: Host Write to Halt Enable while HALT line is asserted: Halting!\n")); + state = STATE_HALTED; + } + break; case 0x80: /* Read select - GPR + INSTR */ - logerror("ES5510: Read INSTR+GPR %02x (%s): %012" I64FMT "x %06x (%d)\n", data, REGNAME(data & 0xff), instr[data] & U64(0xffffffffffff), gpr[data] & 0xffffff, gpr[data]); + LOG(("ES5510: Host Read INSTR+GPR %02x (%s): %012" I64FMT "x %06x (%d)\n", data, REGNAME(data & 0xff), instr[data] & U64(0xffffffffffff), gpr[data] & 0xffffff, gpr[data])); - /* Check if an INSTR address is selected */ - if (data < 0xa0) { - instr_latch = instr[data]; - } - if (data < 0xc0) { - gpr_latch = gpr[data] & 0xffffff; - } else if (data >= 0xea) { - gpr_latch = read_reg(data); - } - break; + /* Check if an INSTR address is selected */ + if (data < 0xa0) { + instr_latch = instr[data]; + } + if (data < 0xc0) { + gpr_latch = gpr[data] & 0xffffff; + } else if (data >= 0xea) { + gpr_latch = read_reg(data); + } + break; case 0xa0: /* Write select - GPR */ - logerror("ES5510: Write GPR %02x (%s): %06x (%d)\n",data, REGNAME(data&0xff), gpr_latch, SX(gpr_latch)); - write_reg(data, gpr_latch); - break; + LOG(("ES5510: Host Write GPR %02x (%s): %06x (%d)\n", data, REGNAME(data&0xff), gpr_latch, SX(gpr_latch))); + write_reg(data, gpr_latch); + break; case 0xc0: /* Write select - INSTR */ - DESCRIBE_INSTR(buf, instr_latch, gpr[data]); - logerror("ES5510: Write INSTR %02x %012" I64FMT "x: %s\n",data, instr_latch&U64(0xffffffffffff), buf); - if (data < 0xa0) { - instr[data] = instr_latch&U64(0xffffffffffff); - } - break; +#if VERBOSE + DESCRIBE_INSTR(buf, instr_latch, gpr[data]); + LOG(("ES5510: Host Write INSTR %02x %012" I64FMT "x: %s\n", data, instr_latch&U64(0xffffffffffff), buf)); +#endif + if (data < 0xa0) { + instr[data] = instr_latch&U64(0xffffffffffff); + } + break; case 0xe0: /* Write select - GPR + INSTR */ - DESCRIBE_INSTR(buf, instr_latch, gpr_latch); - logerror("ES5510: Write INSTR+GPR %02x (%s): %012" I64FMT "x %06x (%d): %s\n",data, REGNAME(data&0xff), instr_latch, gpr_latch, SX(gpr_latch), buf); - if (data < 0xa0) { - instr[data] = instr_latch; +#if VERBOSE + DESCRIBE_INSTR(buf, instr_latch, gpr_latch); + LOG(("ES5510: Host Write INSTR+GPR %02x (%s): %012" I64FMT "x %06x (%d): %s\n", data, REGNAME(data&0xff), instr_latch, gpr_latch, SX(gpr_latch), buf)); +#endif + if (data < 0xa0) { + instr[data] = instr_latch; + } + write_reg(data, gpr_latch); + break; } - write_reg(data, gpr_latch); - break; +} + +INT16 es5510_device::ser_r(int offset) +{ + switch(offset) + { + case 0: return ser0l; + case 1: return ser0r; + case 2: return ser1l; + case 3: return ser1r; + case 4: return ser2l; + case 5: return ser2r; + case 6: return ser3l; + case 7: return ser3r; + } + return 0; +} + +void es5510_device::ser_w(int offset, INT16 data) +{ + switch(offset) + { + case 0: ser0l = data; break; + case 1: ser0r = data; break; + case 2: ser1l = data; break; + case 3: ser1r = data; break; + case 4: ser2l = data; break; + case 5: ser2r = data; break; + case 6: ser3l = data; break; + case 7: ser3r = data; break; } } @@ -505,177 +551,199 @@ UINT32 es5510_device::execute_input_lines() const { return 1; } -void es5510_device::execute_run() { - while (icount > 0) { - if (state == STATE_HALTED) { - // Currently halted, sample the HALT line - if (input_state(ES5510_HALT)) { - // remain halted - host_control |= 0x04; // Signal Host Access OK - } else { - logerror("ES5501: Starting!\n"); - state = STATE_RUNNING; +void es5510_device::execute_set_input(int linenum, int state) { + if (linenum == ES5510_HALT) { + halt_asserted = (state == ASSERT_LINE); + } +} +void es5510_device::list_program(void(p)(const char *, ...)) { + LOG(("ES5501: Starting!\n")); + UINT8 addr; char buf[1024]; for (addr = 0; addr < 0xa0; addr++) { DESCRIBE_INSTR(buf, instr[addr], gpr[addr]); - logerror("%02x: %012" I64FMT "x %06x %s\n", addr, instr[addr], gpr[addr]&0xffffff, buf); + p("%02x: %012" I64FMT "x %06x %s\n", addr, instr[addr], gpr[addr]&0xffffff, buf); } for (; addr < 0xc0; addr++) { - logerror("%02x: %06x (%d)\n", addr, gpr[addr]&0xffffff, gpr[addr]); + p("%02x: %06x (%d)\n", addr, gpr[addr]&0xffffff, gpr[addr]); } - } - } else { - // currently running, execute one instruction. +} - ram_pp = ram_p; - ram_p = ram; - - // *** T0, clock high - // --- nothing to do! - - // *** T0, clock low - // --- Read instruction N - UINT64 instr = this->instr[pc]; - - // --- RAM cycle N-2 (if a Read cycle): data read from bus is stored in DIL - if (ram_pp.cycle != RAM_CYCLE_WRITE) { - if (ram_pp.io) { // read from I/O and store into DIL - dil = 0; // read_io(ram_pp.address);; - } else { // read from DRAM and store into DIL - dil = dram[ram_pp.address]; - } - } - - // --- start of RAM cycle N - ram_control_t ramControl = RAM_CONTROL[((instr >> 3) & 0x07)]; - ram.cycle = ramControl.cycle; - ram.io = ramControl.access == RAM_CONTROL_IO; - - // --- RAM cycle N: read offset N - INT32 offset = gpr[pc]; - switch(ramControl.access) { - case RAM_CONTROL_DELAY: - ram.address = (((dbase + offset) % (dlength + 1)) & memmask) >> memshift; - break; - case RAM_CONTROL_TABLE_A: - ram.address = ((abase + offset) & memmask) >> memshift; - break; - case RAM_CONTROL_TABLE_B: - ram.address = ((bbase + offset) & memmask) >> memshift; - break; - case RAM_CONTROL_IO: - ram.address = offset & 0x00fffff0; // mask off the low 4 bits - break; - } - - // *** T1, clock high - // --- Decode instruction N; - // we will do this both here and in stages as the different parts of the instruction complete & recommence. - - UINT8 operandSelect = (UINT8)((instr >> 8) & 0x0f); - const op_select_t &opSelect = OPERAND_SELECT[operandSelect]; - bool skip = false; - bool skippable = ((instr >> 7) & 0x01) != 0; // aka the 'SKIP' bit in the instruction word - if (skippable) { - bool skipConditionSatisfied = (ccr & cmr & FLAG_MASK) != 0; - if (isFlagSet(cmr, FLAG_NOT)) { - skipConditionSatisfied = !skipConditionSatisfied; - } - skip = skipConditionSatisfied; - } - - // --- Write Multiplier result N-1 - if (mulacc.write_result) { - mulacc.product = (mulacc.cValue * mulacc.dValue) << mulshift; - mulacc.result = (mulacc.accumulate ? machl : 0) + mulacc.product; - INT32 tmp = (mulacc.result & U64(0x0000ffffff000000)) >> 24; - if (mulacc.dst & SRC_DST_REG) { - machl = mulacc.result; - write_reg(mulacc.cReg, tmp); - } - if (mulacc.dst & SRC_DST_DELAY) { - write_to_dol(tmp); - } - } - - // *** T1, clock low - // --- Start of multiplier cycle N - mulacc.cReg = (UINT8)((instr >> 32) & 0xff); - mulacc.dReg = (UINT8)((instr >> 40) & 0xff); - mulacc.src = opSelect.mac_src; - mulacc.dst = opSelect.mac_dst; - mulacc.accumulate = ((instr >> 6) & 0x01) != 0; - mulacc.write_result = skip; - - // --- Read Multiplier Operands N - if (mulacc.src == SRC_DST_REG) { - mulacc.cValue = read_reg(mulacc.cReg); - } else { // must be SRC_DST_DELAY - mulacc.cValue = dil; - } - mulacc.dValue = read_reg(mulacc.dReg); - - // *** T2, clock high - // --- Write ALU Result N-1 - if (alu.write_result) { - UINT8 flags = ccr; - alu.result = alu_operation(alu.op, alu.aValue, alu.bValue, flags); - if (alu.dst & SRC_DST_REG) { - write_reg(alu.aReg, alu.result); - } - if (alu.dst & SRC_DST_DELAY) { - write_to_dol(alu.result); - } - if (alu.update_ccr) { - ccr = flags; - } - } - - // *** T2, clock low - // --- Start of ALU cycle N - alu.aReg = (instr >> 16) & 0xff; - alu.bReg = (instr >> 24) & 0xff; - alu.op = (instr >> 12) & 0x0f; - alu.src = opSelect.alu_src; - alu.dst = opSelect.alu_dst; - alu.write_result = skip; - alu.update_ccr = !skippable || (alu.op == OP_CMP); - - // --- Read ALU Operands N - alu_op_t aluOp = ALU_OPS[alu.op]; - if (aluOp.operands == 2) { - if (alu.src == SRC_DST_REG) { - alu.aValue = read_reg(alu.aReg); - } else { // must be SRC_DST_DELAY - alu.aValue = dil; - } - } - if (aluOp.operands >= 1) { - alu.bValue = read_reg(alu.bReg); - } - - // --- RAM cycle N-1 - if (ram_p.cycle != RAM_CYCLE_READ) { - if (ram_p.cycle == RAM_CYCLE_WRITE) { - // If this is a write cycle, write the frontmost DOL value to RAM or I/O - if (ram_p.io) { - // write_io(ram_p.io, dol[0]); +void es5510_device::execute_run() { + while (icount > 0) { + if (state == STATE_HALTED) { + // Currently halted, sample the HALT line + if (halt_asserted) { + // remain halted + host_control |= 0x04; // Signal Host Access OK + } else { + // start from the beginning at PC 0 + state = STATE_RUNNING; + host_control &= ~0x04; // Signal Host Access not OK + pc = 0; + } } else { - dram[ram_p.address] = dol[0]; - } - } - // If this is a Write or Dump cycle, eject the frontmost DL value. - dol[0] = dol[1]; - if (dol_count > 0) { - --dol_count; - } - } + // currently running, execute one instruction. - ++pc; - } - --icount; +#if VERBOSE + char buf[1024]; + DESCRIBE_INSTR(buf, instr[pc], gpr[pc]); + LOG(("%02x: %012" I64FMT "x %06x %s\n", pc, instr[pc], gpr[pc]&0xffffff, buf)); +#endif + + ram_pp = ram_p; + ram_p = ram; + + // *** T0, clock high + // --- nothing to do! + + // *** T0, clock low + // --- Read instruction N + UINT64 instr = this->instr[pc]; + + // --- RAM cycle N-2 (if a Read cycle): data read from bus is stored in DIL + if (ram_pp.cycle != RAM_CYCLE_WRITE) { + if (ram_pp.io) { // read from I/O and store into DIL + dil = 0; // read_io(ram_pp.address);; + } else { // read from DRAM and store into DIL + dil = dram[ram_pp.address]; + } + } + + // --- start of RAM cycle N + ram_control_t ramControl = RAM_CONTROL[((instr >> 3) & 0x07)]; + ram.cycle = ramControl.cycle; + ram.io = ramControl.access == RAM_CONTROL_IO; + + // --- RAM cycle N: read offset N + INT32 offset = gpr[pc]; + switch(ramControl.access) { + case RAM_CONTROL_DELAY: + ram.address = (((dbase + offset) % (dlength + 1)) & memmask) >> memshift; + break; + case RAM_CONTROL_TABLE_A: + ram.address = ((abase + offset) & memmask) >> memshift; + break; + case RAM_CONTROL_TABLE_B: + ram.address = ((bbase + offset) & memmask) >> memshift; + break; + case RAM_CONTROL_IO: + ram.address = offset & 0x00fffff0; // mask off the low 4 bits + break; + } + + // *** T1, clock high + // --- Decode instruction N; + // we will do this both here and in stages as the different parts of the instruction complete & recommence. + + UINT8 operandSelect = (UINT8)((instr >> 8) & 0x0f); + const op_select_t &opSelect = OPERAND_SELECT[operandSelect]; + bool skip = false; + bool skippable = ((instr >> 7) & 0x01) != 0; // aka the 'SKIP' bit in the instruction word + if (skippable) { + bool skipConditionSatisfied = (ccr & cmr & FLAG_MASK) != 0; + if (isFlagSet(cmr, FLAG_NOT)) { + skipConditionSatisfied = !skipConditionSatisfied; + } + skip = skipConditionSatisfied; + } + + // --- Write Multiplier result N-1 + if (mulacc.write_result) { + mulacc.product = (mulacc.cValue * mulacc.dValue) << mulshift; + mulacc.result = (mulacc.accumulate ? machl : 0) + mulacc.product; + INT32 tmp = (mulacc.result & U64(0x0000ffffff000000)) >> 24; + if (mulacc.dst & SRC_DST_REG) { + machl = mulacc.result; + write_reg(mulacc.cReg, tmp); + } + if (mulacc.dst & SRC_DST_DELAY) { + write_to_dol(tmp); + } + } + + // *** T1, clock low + // --- Start of multiplier cycle N + mulacc.cReg = (UINT8)((instr >> 32) & 0xff); + mulacc.dReg = (UINT8)((instr >> 40) & 0xff); + mulacc.src = opSelect.mac_src; + mulacc.dst = opSelect.mac_dst; + mulacc.accumulate = ((instr >> 6) & 0x01) != 0; + mulacc.write_result = !skip; + + // --- Read Multiplier Operands N + if (mulacc.src == SRC_DST_REG) { + mulacc.cValue = read_reg(mulacc.cReg); + } else { // must be SRC_DST_DELAY + mulacc.cValue = dil; + } + mulacc.dValue = read_reg(mulacc.dReg); + + // *** T2, clock high + // --- Write ALU Result N-1 + if (alu.write_result) { + UINT8 flags = ccr; + alu.result = alu_operation(alu.op, alu.aValue, alu.bValue, flags); + if (alu.dst & SRC_DST_REG) { + write_reg(alu.aReg, alu.result); + } + if (alu.dst & SRC_DST_DELAY) { + write_to_dol(alu.result); + } + if (alu.update_ccr) { + ccr = flags; + } + } + + // *** T2, clock low + // --- Start of ALU cycle N + alu.aReg = (instr >> 16) & 0xff; + alu.bReg = (instr >> 24) & 0xff; + alu.op = (instr >> 12) & 0x0f; + alu.src = opSelect.alu_src; + alu.dst = opSelect.alu_dst; + alu.write_result = !skip; + alu.update_ccr = !skippable || (alu.op == OP_CMP); + + if (alu.op == 0xF) { + alu_operation_end(); + } else { + // --- Read ALU Operands N + alu_op_t aluOp = ALU_OPS[alu.op]; + if (aluOp.operands == 2) { + if (alu.src == SRC_DST_REG) { + alu.aValue = read_reg(alu.aReg); + } else { // must be SRC_DST_DELAY + alu.aValue = dil; + } + } + if (aluOp.operands >= 1) { + alu.bValue = read_reg(alu.bReg); + } + } + + // --- RAM cycle N-1 + if (ram_p.cycle != RAM_CYCLE_READ) { + if (ram_p.cycle == RAM_CYCLE_WRITE) { + // If this is a write cycle, write the frontmost DOL value to RAM or I/O + if (ram_p.io) { + // write_io(ram_p.io, dol[0]); + } else { + dram[ram_p.address] = dol[0]; + } + } + // If this is a Write or Dump cycle, eject the frontmost DL value. + dol[0] = dol[1]; + if (dol_count > 0) { + --dol_count; + } + } + + ++pc; + } + --icount; } } @@ -697,44 +765,63 @@ offs_t es5510_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *o INT32 es5510_device::read_reg(UINT8 reg) { if (reg < 0xc0) { - return gpr[reg]; + return gpr[reg]; } else { - switch(reg) - { - case 234: return ser0r; - case 235: return ser0l; - case 236: return ser1r; - case 237: return ser1l; - case 238: return ser2r; - case 239: return ser2l; - case 240: return ser3r; - case 241: return ser3l; - case 242: return (machl >> 0) & 0x00ffffff; - case 243: return (machl >> 24) & 0x00ffffff; - case 244: return dil; // DIL when reading - case 245: return dlength; - case 246: return abase; - case 247: return bbase; - case 248: return dbase; - case 249: return sigreg; - case 250: return ccr; - case 251: return cmr; - case 252: return 0x00ffffff; - case 253: return 0x00800000; - case 254: return 0x007fffff; - case 255: return 0x00000000; - default: - // unknown SPR - return 0; + switch(reg) + { + case 234: return ser0r; + case 235: return ser0l; + case 236: return ser1r; + case 237: return ser1l; + case 238: return ser2r; + case 239: return ser2l; + case 240: return ser3r; + case 241: return ser3l; + case 242: return (machl >> 0) & 0x00ffffff; + case 243: return (machl >> 24) & 0x00ffffff; + case 244: return dil; // DIL when reading + case 245: return dlength; + case 246: return abase; + case 247: return bbase; + case 248: return dbase; + case 249: return sigreg; + case 250: return ccr; + case 251: return cmr; + case 252: return 0x00ffffff; + case 253: return 0x00800000; + case 254: return 0x007fffff; + case 255: return 0x00000000; + default: + // unknown SPR + return 0; + } } +} + +void es5510_device::run_once() +{ + // turn HALT off + set_HALT(false); + + // run for one instruction + icount = 1; + execute_run(); + + // turn HALT on again + set_HALT(true); + + // run ESP to the end of its program, a few instructions at a time + while (state != STATE_HALTED) { + icount = 1; + execute_run(); } } INT8 countLowOnes(INT32 x) { INT8 n = 0; while ((x & 1) == 1) { - ++n; - x >>= 1; + ++n; + x >>= 1; } return n; } @@ -743,141 +830,78 @@ void es5510_device::write_reg(UINT8 reg, INT32 value) { value &= 0x00ffffff; if (reg < 0xc0) { - gpr[reg] = value; + gpr[reg] = value; } else { - switch(reg) - { - case 234: ser0r = value; - break; - case 235: ser0l = value; - break; - case 236: ser1r = value; - break; - case 237: ser1l = value; - break; - case 238: ser2r = value; - break; - case 239: ser2l = value; - break; - case 240: ser3r = value; - break; - case 241: ser3l = value; - break; - case 242: machl = (machl & ~((INT64)0x00ffffff << 0)) | (value << 0); - break; - case 243: machl = (machl & ~((INT64)0x00ffffff << 24)) | (value << 24); - break; - case 244: - memshift = countLowOnes(value); - memsiz = 0x00ffffff >> (24 - memshift); - memmask = 0x00ffffff & ~memsiz; - memincrement = 1 << memshift; - break; - case 245: dlength = value; - break; - case 246: abase = value; - break; - case 247: bbase = value; - break; - case 248: dbase = value; - break; - case 249: sigreg = (value != 0); - break; - case 250: ccr = (value >> 16) & FLAG_MASK; - break; - case 251: cmr = (value >> 16) & (FLAG_MASK | FLAG_NOT); - break; - case 252: // no-op - break; - case 253: // no-op - break; - case 254: // no-op - break; - case 255: // no-op - break; - default: // unknown register - break; - } + switch(reg) + { + case 234: ser0r = value; + break; + case 235: ser0l = value; + break; + case 236: ser1r = value; + break; + case 237: ser1l = value; + break; + case 238: ser2r = value; + break; + case 239: ser2l = value; + break; + case 240: ser3r = value; + break; + case 241: ser3l = value; + break; + case 242: machl = (machl & ~((INT64)0x00ffffff << 0)) | (value << 0); + break; + case 243: machl = (machl & ~((INT64)0x00ffffff << 24)) | (value << 24); + break; + case 244: + memshift = countLowOnes(value); + memsiz = 0x00ffffff >> (24 - memshift); + memmask = 0x00ffffff & ~memsiz; + memincrement = 1 << memshift; + break; + case 245: dlength = value; + break; + case 246: abase = value; + break; + case 247: bbase = value; + break; + case 248: dbase = value; + break; + case 249: sigreg = (value != 0); + break; + case 250: ccr = (value >> 16) & FLAG_MASK; + break; + case 251: cmr = (value >> 16) & (FLAG_MASK | FLAG_NOT); + break; + case 252: // no-op + break; + case 253: // no-op + break; + case 254: // no-op + break; + case 255: // no-op + break; + default: // unknown register + break; + } } } void es5510_device::write_to_dol(INT32 value) { if (dol_count >= 2) { - dol[0] = dol[1]; - dol[1] = value; + dol[0] = dol[1]; + dol[1] = value; } else { - dol[dol_count++] = value; + dol[dol_count++] = value; } } -INT32 es5510_device::alu_operation(UINT8 op, INT32 a, INT32 b, UINT8 &flags) { - switch(op) { - case 0x0: // ADD - return saturate(add(a, b, flags), flags); - - case 0x1: // SUB - return saturate(add(a, negate(b), flags), flags); - - case 0x2: // ADDU - return add(a, b, flags); - - case 0x3: // SUBU - return add(a, negate(b), flags); - - case 0x4: // CMP - add(a, negate(b), flags); - return a; - - case 0x5: // AND - a &= b; - setFlagTo(flags, FLAG_N, (a & 0x0080000000) != 0); - setFlagTo(flags, FLAG_Z, a == 0); - return a; - - case 0x6: // OR - a |= b; - setFlagTo(flags, FLAG_N, (a & 0x0080000000) != 0); - setFlagTo(flags, FLAG_Z, a == 0); - return a; - - case 0x7: // XOR - a ^= b; - setFlagTo(flags, FLAG_N, (a & 0x0080000000) != 0); - setFlagTo(flags, FLAG_Z, a == 0); - return a; - - case 0x8: // ABS - { - clearFlag(flags, FLAG_N); - bool isNegative = (a & 0x00800000) != 0; - setFlagTo(flags, FLAG_C, isNegative); - if (isNegative) { - a = (a ^ 0x00ffffff) + 1; - } - return a; - } - - case 0x9: // MOV - return b; - - case 0xA: // ASL2 - return asl(b, 2, flags); - - case 0xB: // ASL8 - return asl(b, 8, flags); - - case 0xC: // LS15 - return (b << 15) & 0x007fffff; - - case 0xD: // DIFF - return add(0x007fffff, negate(b), flags); - - case 0xE: // ASR - return (b >> 1) | (b & 0x00800000); - - case 0xF: // END +void es5510_device::alu_operation_end() { + // Handle the END instruction separately + LOG(("ES5510: END\n")); // sample the HALT line - if (input_state(ES5510_HALT)) { + if (halt_asserted) { // halt state = STATE_HALTED; host_control |= 0x04; // Signal Host Access OK @@ -887,8 +911,75 @@ INT32 es5510_device::alu_operation(UINT8 op, INT32 a, INT32 b, UINT8 &flags) { if (dbase < 0) { dbase = dlength; } +} +INT32 es5510_device::alu_operation(UINT8 op, INT32 a, INT32 b, UINT8 &flags) { + switch(op) { + case 0x0: // ADD + return saturate(add(a, b, flags), flags); + + case 0x1: // SUB + return saturate(add(a, negate(b), flags), flags); + + case 0x2: // ADDU + return add(a, b, flags); + + case 0x3: // SUBU + return add(a, negate(b), flags); + + case 0x4: // CMP + add(a, negate(b), flags); + return a; + + case 0x5: // AND + a &= b; + setFlagTo(flags, FLAG_N, (a & 0x0080000000) != 0); + setFlagTo(flags, FLAG_Z, a == 0); + return a; + + case 0x6: // OR + a |= b; + setFlagTo(flags, FLAG_N, (a & 0x0080000000) != 0); + setFlagTo(flags, FLAG_Z, a == 0); + return a; + + case 0x7: // XOR + a ^= b; + setFlagTo(flags, FLAG_N, (a & 0x0080000000) != 0); + setFlagTo(flags, FLAG_Z, a == 0); + return a; + + case 0x8: // ABS + { + clearFlag(flags, FLAG_N); + bool isNegative = (a & 0x00800000) != 0; + setFlagTo(flags, FLAG_C, isNegative); + if (isNegative) { + a = (a ^ 0x00ffffff) + 1; + } + return a; + } + + case 0x9: // MOV + return b; + + case 0xA: // ASL2 + return asl(b, 2, flags); + + case 0xB: // ASL8 + return asl(b, 8, flags); + + case 0xC: // LS15 + return (b << 15) & 0x007fffff; + + case 0xD: // DIFF + return add(0x007fffff, negate(b), flags); + + case 0xE: // ASR + return (b >> 1) | (b & 0x00800000); + + case 0xF: // END - handled separately in alu_operation_end() default: - return 0; + return 0; } } diff --git a/src/emu/cpu/es5510/es5510.h b/src/emu/cpu/es5510/es5510.h index cdc42b27a0c..8120d204081 100644 --- a/src/emu/cpu/es5510/es5510.h +++ b/src/emu/cpu/es5510/es5510.h @@ -13,59 +13,59 @@ #include "emu.h" class es5510_device : public cpu_device { - public: +public: es5510_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); DECLARE_READ8_MEMBER(host_r); DECLARE_WRITE8_MEMBER(host_w); - DECLARE_READ16_MEMBER(ser_r); - DECLARE_WRITE16_MEMBER(ser_w); + INT16 ser_r(int offset); + void ser_w(int offset, INT16 data); enum line_t { - ES5510_HALT = 0 + ES5510_HALT = 0 }; enum state_t { - STATE_RUNNING = 0, - STATE_HALTED = 1 + STATE_RUNNING = 0, + STATE_HALTED = 1 }; struct alu_op_t { - int operands; - const char * const opcode; + int operands; + const char * const opcode; }; enum op_src_dst_t { - SRC_DST_REG = 1 << 0, - SRC_DST_DELAY = 1 << 1, - SRC_DST_BOTH = (1 << 0) | (1 << 1) + SRC_DST_REG = 1 << 0, + SRC_DST_DELAY = 1 << 1, + SRC_DST_BOTH = (1 << 0) | (1 << 1) }; struct op_select_t { - const op_src_dst_t alu_src; - const op_src_dst_t alu_dst; - const op_src_dst_t mac_src; - const op_src_dst_t mac_dst; + const op_src_dst_t alu_src; + const op_src_dst_t alu_dst; + const op_src_dst_t mac_src; + const op_src_dst_t mac_dst; }; enum ram_control_access_t { - RAM_CONTROL_DELAY = 0, - RAM_CONTROL_TABLE_A, - RAM_CONTROL_TABLE_B, - RAM_CONTROL_IO + RAM_CONTROL_DELAY = 0, + RAM_CONTROL_TABLE_A, + RAM_CONTROL_TABLE_B, + RAM_CONTROL_IO }; enum ram_cycle_t { - RAM_CYCLE_READ = 0, - RAM_CYCLE_WRITE = 1, - RAM_CYCLE_DUMP_FIFO = 2 + RAM_CYCLE_READ = 0, + RAM_CYCLE_WRITE = 1, + RAM_CYCLE_DUMP_FIFO = 2 }; struct ram_control_t { - ram_cycle_t cycle; - ram_control_access_t access; - const char * const description; + ram_cycle_t cycle; + ram_control_access_t access; + const char * const description; }; static const alu_op_t ALU_OPS[16]; @@ -73,38 +73,45 @@ class es5510_device : public cpu_device { static const ram_control_t RAM_CONTROL[8]; struct alu_t { - UINT8 aReg; - UINT8 bReg; - op_src_dst_t src; - op_src_dst_t dst; - UINT8 op; - INT32 aValue; - INT32 bValue; - INT32 result; - bool update_ccr; - bool write_result; + UINT8 aReg; + UINT8 bReg; + op_src_dst_t src; + op_src_dst_t dst; + UINT8 op; + INT32 aValue; + INT32 bValue; + INT32 result; + bool update_ccr; + bool write_result; }; struct mulacc_t { - UINT8 cReg; - UINT8 dReg; - op_src_dst_t src; - op_src_dst_t dst; - bool accumulate; - INT64 cValue; - INT64 dValue; - INT64 product; - INT64 result; - bool write_result; + UINT8 cReg; + UINT8 dReg; + op_src_dst_t src; + op_src_dst_t dst; + bool accumulate; + INT64 cValue; + INT64 dValue; + INT64 product; + INT64 result; + bool write_result; }; struct ram_t { - INT32 address; // up to 20 bits, left-justified within the right 24 bits of the 32-bit word - bool io; // I/O space, rather than delay line memory - ram_cycle_t cycle; // cycle type + INT32 address; // up to 20 bits, left-justified within the right 24 bits of the 32-bit word + bool io; // I/O space, rather than delay line memory + ram_cycle_t cycle; // cycle type }; - protected: + // direct access to the 'HALT' pin - not just through the + void set_HALT(bool halt) { halt_asserted = halt; } + bool get_HALT() { return halt_asserted; } + + void run_once(); + void list_program(void(p)(const char *, ...)); + +protected: virtual void device_start(); virtual void device_reset(); virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const; @@ -117,15 +124,18 @@ class es5510_device : public cpu_device { virtual UINT32 disasm_min_opcode_bytes() const; virtual UINT32 disasm_max_opcode_bytes() const; virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); + virtual void execute_set_input(int linenum, int state); INT32 read_reg(UINT8 reg); void write_reg(UINT8 reg, INT32 value); void write_to_dol(INT32 value); INT32 alu_operation(UINT8 op, INT32 aValue, INT32 bValue, UINT8 &flags); + void alu_operation_end(); - private: +private: int icount; + bool halt_asserted; UINT8 pc; state_t state; INT32 gpr[0xc0]; // 24 bits, right justified and sign extended diff --git a/src/emu/sound/es5506.c b/src/emu/sound/es5506.c index 01ad725abaf..fd2a2749483 100644 --- a/src/emu/sound/es5506.c +++ b/src/emu/sound/es5506.c @@ -193,6 +193,8 @@ struct es5506_state UINT16 * volume_lookup; device_t *device; + int channels; /* the number of output stereo channels: 1..4 for 5505, 1..6 for 5506 */ + #if MAKE_WAVS void * wavraw; /* raw waveform */ #endif @@ -783,7 +785,7 @@ alldone: ***********************************************************************************************/ -static void generate_samples(es5506_state *chip, INT32 *left, INT32 *right, int samples) +static void generate_samples(es5506_state *chip, INT32 **outputs, int offset, int samples) { int v; @@ -791,9 +793,11 @@ static void generate_samples(es5506_state *chip, INT32 *left, INT32 *right, int if (!samples) return; - /* clear out the accumulator */ - memset(left, 0, samples * sizeof(left[0])); - memset(right, 0, samples * sizeof(right[0])); + /* clear out the accumulators */ + for (int i = 0; i < chip->channels << 1; i++) + { + memset(outputs[i] + offset, 0, sizeof(INT32) * samples); + } /* loop over voices */ for (v = 0; v <= chip->active_voices; v++) @@ -805,6 +809,13 @@ static void generate_samples(es5506_state *chip, INT32 *left, INT32 *right, int if (voice->start == voice->end) voice->control |= CONTROL_STOP0; + int voice_channel = (voice->control & CONTROL_CAMASK) >> 10; + int channel = voice_channel % chip->channels; + int l = channel << 1; + int r = l + 1; + INT32 *left = outputs[l] + offset; + INT32 *right = outputs[r] + offset; + /* generate from the appropriate source */ if (!base) { @@ -845,12 +856,9 @@ static void generate_samples(es5506_state *chip, INT32 *left, INT32 *right, int ***********************************************************************************************/ -static STREAM_UPDATE( es5506_update ) +STREAM_UPDATE( es5506_update ) { es5506_state *chip = (es5506_state *)param; - INT32 *lsrc = NULL, *rsrc = NULL; - stream_sample_t *ldest = outputs[0]; - stream_sample_t *rdest = outputs[1]; #if MAKE_WAVS /* start the logging once we have a sample rate */ @@ -862,30 +870,36 @@ static STREAM_UPDATE( es5506_update ) #endif /* loop until all samples are output */ + int offset = 0; while (samples) { int length = (samples > MAX_SAMPLE_CHUNK) ? MAX_SAMPLE_CHUNK : samples; - int samp; - /* determine left/right source data */ - lsrc = chip->scratch; - rsrc = chip->scratch + length; - generate_samples(chip, lsrc, rsrc, length); - - /* copy the data */ - for (samp = 0; samp < length; samp++) - { - *ldest++ = lsrc[samp] >> 4; - *rdest++ = rsrc[samp] >> 4; - } + generate_samples(chip, outputs, offset, length); #if MAKE_WAVS /* log the raw data */ - if (chip->wavraw) + if (chip->wavraw) { + /* determine left/right source data */ + INT32 *lsrc = chip->scratch, *rsrc = chip->scratch + length; + int channel; + memset(lsrc, 0, sizeof(INT32) * length * 2); + /* loop over the output channels */ + for (channel = 0; channel < chip->channels; channel++) { + INT32 *l = outputs[(channel << 1)] + offset; + INT32 *r = outputs[(channel << 1) + 1] + offset; + /* add the current channel's samples to the WAV data */ + for (samp = 0; samp < length; samp++) { + lsrc[samp] += l[samp]; + rsrc[samp] += r[samp]; + } + } wav_add_data_32lr(chip->wavraw, lsrc, rsrc, length, 4); + } #endif /* account for these samples */ + offset += length; samples -= length; } } @@ -903,13 +917,18 @@ static void es5506_start_common(device_t *device, const void *config, device_typ es5506_state *chip = get_safe_token(device); int j; UINT32 accum_mask; + int channels = 1; /* 1 channel by default, for backward compatibility */ + + /* only override the number of channels if the value is in the valid range 1 .. 6 */ + if (1 <= intf->channels && intf->channels <= 6) + channels = intf->channels; /* debugging */ if (LOG_COMMANDS && !eslog) eslog = fopen("es.log", "w"); /* create the stream */ - chip->stream = device->machine().sound().stream_alloc(*device, 0, 2, device->clock() / (16*32), chip, es5506_update); + chip->stream = device->machine().sound().stream_alloc(*device, 0, 2 * channels, device->clock() / (16*32), chip, es5506_update); /* initialize the regions */ chip->region_base[0] = intf->region0 ? (UINT16 *)device->machine().root_device().memregion(intf->region0)->base() : NULL; @@ -923,6 +942,7 @@ static void es5506_start_common(device_t *device, const void *config, device_typ chip->irq_callback.resolve(intf->irq_callback,*device); chip->port_read.resolve(intf->read_port,*device); chip->irqv = 0x80; + chip->channels = channels; /* compute the tables */ compute_tables(chip); @@ -1556,11 +1576,17 @@ static DEVICE_START( es5505 ) { const es5505_interface *intf = (const es5505_interface *)device->static_config(); es5506_interface es5506intf; + int channels = 1; /* 1 channel by default, for backward compatibility */ + + /* only override the number of channels if the value is in the valid range 1 .. 4 */ + if (1 <= intf->channels && intf->channels <= 4) + channels = intf->channels; memset(&es5506intf, 0, sizeof(es5506intf)); es5506intf.region0 = intf->region0; es5506intf.region1 = intf->region1; + es5506intf.channels = channels; es5506intf.irq_callback = intf->irq_callback; es5506intf.read_port = intf->read_port; @@ -2194,7 +2220,6 @@ void es5506_device::sound_stream_update(sound_stream &stream, stream_sample_t ** fatalerror("sound_stream_update called; not applicable to legacy sound devices\n"); } - const device_type ES5505 = &device_creator; es5505_device::es5505_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) diff --git a/src/emu/sound/es5506.h b/src/emu/sound/es5506.h index 1f410a2a0d8..1a7fd010228 100644 --- a/src/emu/sound/es5506.h +++ b/src/emu/sound/es5506.h @@ -16,6 +16,7 @@ struct es5505_interface { const char * region0; /* memory region where the sample ROM lives */ const char * region1; /* memory region where the sample ROM lives */ + int channels; /* number of output channels: 1 .. 4 */ devcb_write_line irq_callback; /* irq callback */ devcb_read16 read_port; /* input port read */ }; @@ -58,6 +59,7 @@ struct es5506_interface const char * region1; /* memory region where the sample ROM lives */ const char * region2; /* memory region where the sample ROM lives */ const char * region3; /* memory region where the sample ROM lives */ + int channels; /* number of output channels: 1 .. 6 */ devcb_write_line irq_callback; /* irq callback */ devcb_read16 read_port; /* input port read */ }; @@ -79,5 +81,6 @@ private: extern const device_type ES5505; +extern STREAM_UPDATE( es5506_update ); #endif /* __ES5506_H__ */ diff --git a/src/mame/audio/taito_en.c b/src/mame/audio/taito_en.c index 086f77b3e07..78c64157492 100644 --- a/src/mame/audio/taito_en.c +++ b/src/mame/audio/taito_en.c @@ -315,6 +315,7 @@ static const es5505_interface es5505_taito_en_config = { "ensoniq.0", /* Bank 0: Unused by F3 games? */ "ensoniq.0", /* Bank 1: All games seem to use this */ + 1, /* channels */ DEVCB_NULL /* IRQ */ }; diff --git a/src/mame/drivers/itech32.c b/src/mame/drivers/itech32.c index e3a70b64e99..b7dcc46d398 100644 --- a/src/mame/drivers/itech32.c +++ b/src/mame/drivers/itech32.c @@ -1666,7 +1666,8 @@ static const es5506_interface es5506_config = "ensoniq.0", "ensoniq.1", "ensoniq.2", - "ensoniq.3" + "ensoniq.3", + 1 /* channels */ }; diff --git a/src/mame/drivers/macrossp.c b/src/mame/drivers/macrossp.c index 07f5e348182..5ea469d0d72 100644 --- a/src/mame/drivers/macrossp.c +++ b/src/mame/drivers/macrossp.c @@ -587,6 +587,7 @@ static const es5506_interface es5506_config = "ensoniq.1", "ensoniq.2", "ensoniq.3", + 1, /* channels */ DEVCB_DRIVER_LINE_MEMBER(macrossp_state,irqhandler) }; diff --git a/src/mame/drivers/ssv.c b/src/mame/drivers/ssv.c index a21089399d8..eae976826e0 100644 --- a/src/mame/drivers/ssv.c +++ b/src/mame/drivers/ssv.c @@ -2491,7 +2491,8 @@ static const es5506_interface es5506_config = "ensoniq.0", "ensoniq.1", "ensoniq.2", - "ensoniq.3" + "ensoniq.3", + 1 /* channels */ }; /*************************************************************************** diff --git a/src/mess/drivers/esq5505.c b/src/mess/drivers/esq5505.c index af11c16af6b..740bb48da36 100644 --- a/src/mess/drivers/esq5505.c +++ b/src/mess/drivers/esq5505.c @@ -125,6 +125,221 @@ static int shift = 32; #endif +void print_to_stderr(const char *format, ...) +{ + va_list arg; + va_start(arg, format); + vfprintf(stderr, format, arg); + va_end(arg); +} + +#define PUMP_DETECT_SILENCE 1 +#define PUMP_TRACK_SAMPLES 0 +#define PUMP_FAKE_ESP_PROCESSING 1 +class esq_5505_5510_pump : public device_t, + public device_sound_interface +{ +public: + esq_5505_5510_pump(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + void set_otis(es5505_device *otis) { m_otis = otis; } + void set_esp(es5510_device *esp) { m_esp = esp; } + void set_esp_halted(bool esp_halted) { + m_esp_halted = esp_halted; + logerror("ESP-halted -> %d\n", m_esp_halted); + if (!esp_halted) { + m_esp->list_program(print_to_stderr); + } + } + bool get_esp_halted() { + return m_esp_halted; + } + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_stop(); + virtual void device_reset(); + + // sound stream update overrides + virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); + + // timer callback overridea + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + +private: + // internal state: + // sound stream + sound_stream *m_stream; + + // per-sample timer + emu_timer *m_timer; + + // OTIS sound generator + es5505_device *m_otis; + + // ESP signal processor + es5510_device *m_esp; + + // Is the ESP halted by the CPU? + bool m_esp_halted; + +#if !PUMP_FAKE_ESP_PROCESSING + osd_ticks_t ticks_spent_processing; + int samples_processed; +#endif + +#if PUMP_DETECT_SILENCE + int silent_for; + bool was_silence; +#endif + +#if PUMP_TRACK_SAMPLES + int last_samples; + osd_ticks_t last_ticks; + osd_ticks_t next_report_ticks; +#endif +}; + +const device_type ESQ_5505_5510_PUMP = &device_creator; + +esq_5505_5510_pump::esq_5505_5510_pump(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, ESQ_5505_5510_PUMP, "ESQ_5505_5510_PUMP", tag, owner, clock), + device_sound_interface(mconfig, *this), + m_esp_halted(true) +{ +} + +void esq_5505_5510_pump::device_start() +{ + INT64 nsec_per_sample = 100 * 16 * 21; + attotime sample_time(0, 1000000000 * nsec_per_sample); + attotime initial_delay(0, 0); + logerror("Clock = %d\n", clock()); + m_stream = machine().sound().stream_alloc(*this, 8, 2, clock(), this); + m_timer = timer_alloc(0); + m_timer->adjust(initial_delay, 0, sample_time); + m_timer->enable(true); + +#if PUMP_DETECT_SILENCE + silent_for = 500; + was_silence = 1; +#endif +#if !PUMP_FAKE_ESP_PROCESSING + ticks_spent_processing = 0; + samples_processed = 0; +#endif +#if PUMP_TRACK_SAMPLES + last_samples = 0; + last_ticks = osd_ticks(); + next_report_ticks = last_ticks + osd_ticks_per_second(); +#endif +} + +void esq_5505_5510_pump::device_stop() +{ + m_timer->enable(false); +} + +void esq_5505_5510_pump::device_reset() +{ +} + +void esq_5505_5510_pump::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +{ + if (samples != 1) { + logerror("Pump: request for %d samples\n", samples); + } + + stream_sample_t *left = outputs[0], *right = outputs[1]; + for (int i = 0; i < samples; i++) + { + // anything for the 'aux' output? + INT32 l = inputs[0][i] >> 4; + INT32 r = inputs[1][i] >> 4; + + // push the samples into the ESP + m_esp->ser_w(0, inputs[2][i] >> 4); + m_esp->ser_w(1, inputs[3][i] >> 4); + m_esp->ser_w(2, inputs[4][i] >> 4); + m_esp->ser_w(3, inputs[5][i] >> 4); + m_esp->ser_w(4, inputs[6][i] >> 4); + m_esp->ser_w(5, inputs[7][i] >> 4); + + m_esp->ser_w(6, 0); + m_esp->ser_w(7, 0); + +#if PUMP_FAKE_ESP_PROCESSING + m_esp->ser_w(6, m_esp->ser_r(0) + m_esp->ser_r(2) + m_esp->ser_r(4)); + m_esp->ser_w(7, m_esp->ser_r(1) + m_esp->ser_r(3) + m_esp->ser_r(5)); +#else + if (!m_esp_halted) { + logerror("passing one sample through ESP\n"); + osd_ticks_t a = osd_ticks(); + m_esp->run_once(); + osd_ticks_t b = osd_ticks(); + ticks_spent_processing += (b - a); + samples_processed++; + } +#endif + + // read the processed result from the ESP and add to the saved AUX data + l += m_esp->ser_r(6); + r += m_esp->ser_r(7); + + // write the combined data to the output + *left++ = l; + *right++ = r; + } + +#if PUMP_DETECT_SILENCE + for (int i = 0; i < samples; i++) { + if (outputs[0][i] == 0 && outputs[1][i] == 0) { + silent_for++; + } else { + silent_for = 0; + } + } + bool silence = silent_for >= 500; + if (was_silence != silence) { + if (!silence) { + fprintf(stderr, ".-*\n"); + } else { + fprintf(stderr, "*-.\n"); + } + was_silence = silence; + } +#endif + +#if PUMP_TRACK_SAMPLES + last_samples += samples; + osd_ticks_t now = osd_ticks(); + if (now >= next_report_ticks) + { + osd_ticks_t elapsed = now - last_ticks; + osd_ticks_t tps = osd_ticks_per_second(); + fprintf(stderr, "Pump: %d samples in %" I64FMT "d ticks for %f Hz\n", last_samples, elapsed, last_samples * (double)tps / (double)elapsed); + last_ticks = now; + while (next_report_ticks <= now) { + next_report_ticks += tps; + } + last_samples = 0; + +#if !PUMP_FAKE_ESP_PROCESSING + fprintf(stderr, " ESP spent %" I64FMT "d ticks on %d samples, %f ticks per sample\n", ticks_spent_processing, samples_processed, (double)ticks_spent_processing / (double)samples_processed); + ticks_spent_processing = 0; + samples_processed = 0; +#endif + } +#endif +} + +void esq_5505_5510_pump::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { + // ecery time there's a new sample period, update the stream! + m_stream->update(); +} + + class esq5505_state : public driver_device { public: @@ -132,7 +347,9 @@ public: : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), m_duart(*this, "duart"), + m_otis(*this, "otis"), m_esp(*this, "esp"), + m_pump(*this, "pump"), m_fdc(*this, "wd1772"), m_panel(*this, "panel"), m_dmac(*this, "mc68450"), @@ -141,12 +358,15 @@ public: required_device m_maincpu; required_device m_duart; + required_device m_otis; required_device m_esp; + required_device m_pump; optional_device m_fdc; required_device m_panel; optional_device m_dmac; required_device m_mdout; + virtual void machine_start(); virtual void machine_reset(); DECLARE_READ16_MEMBER(es5510_dsp_r); @@ -200,25 +420,33 @@ IRQ_CALLBACK_MEMBER(esq5505_state::maincpu_irq_acknowledge_callback) int vector = 0; switch(irqline) { case 1: - otis_irq_state = 0; - vector = M68K_INT_ACK_AUTOVECTOR; - break; + otis_irq_state = 0; + vector = M68K_INT_ACK_AUTOVECTOR; + break; case 2: - dmac_irq_state = 0; - vector = dmac_irq_vector; - break; + dmac_irq_state = 0; + vector = dmac_irq_vector; + break; case 3: - duart_irq_state = 0; - vector = duart_irq_vector; - break; + duart_irq_state = 0; + vector = duart_irq_vector; + break; default: - printf("\nUnexpected IRQ ACK Callback: IRQ %d\n", irqline); - return 0; + printf("\nUnexpected IRQ ACK Callback: IRQ %d\n", irqline); + return 0; } update_irq_to_maincpu(); return vector; } +void esq5505_state::machine_start() +{ + driver_device::machine_start(); + // tell the pump about the OTIS & ESP chips + m_pump->set_otis(m_otis); + m_pump->set_esp(m_esp); +} + void esq5505_state::machine_reset() { m_rom = (UINT16 *)(void *)memregion("osrom")->base(); @@ -229,21 +457,21 @@ void esq5505_state::machine_reset() void esq5505_state::update_irq_to_maincpu() { //printf("\nupdating IRQ state: have OTIS=%d, DMAC=%d, DUART=%d\n", otis_irq_state, dmac_irq_state, duart_irq_state); if (duart_irq_state) { - m_maincpu->set_input_line(M68K_IRQ_2, CLEAR_LINE); - m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE); - m_maincpu->set_input_line_and_vector(M68K_IRQ_3, ASSERT_LINE, duart_irq_vector); + m_maincpu->set_input_line(M68K_IRQ_2, CLEAR_LINE); + m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE); + m_maincpu->set_input_line_and_vector(M68K_IRQ_3, ASSERT_LINE, duart_irq_vector); } else if (dmac_irq_state) { - m_maincpu->set_input_line(M68K_IRQ_3, CLEAR_LINE); - m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE); - m_maincpu->set_input_line_and_vector(M68K_IRQ_2, ASSERT_LINE, dmac_irq_vector); + m_maincpu->set_input_line(M68K_IRQ_3, CLEAR_LINE); + m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE); + m_maincpu->set_input_line_and_vector(M68K_IRQ_2, ASSERT_LINE, dmac_irq_vector); } else if (otis_irq_state) { - m_maincpu->set_input_line(M68K_IRQ_3, CLEAR_LINE); - m_maincpu->set_input_line(M68K_IRQ_2, CLEAR_LINE); - m_maincpu->set_input_line(M68K_IRQ_1, ASSERT_LINE); + m_maincpu->set_input_line(M68K_IRQ_3, CLEAR_LINE); + m_maincpu->set_input_line(M68K_IRQ_2, CLEAR_LINE); + m_maincpu->set_input_line(M68K_IRQ_1, ASSERT_LINE); } else { - m_maincpu->set_input_line(M68K_IRQ_3, CLEAR_LINE); - m_maincpu->set_input_line(M68K_IRQ_2, CLEAR_LINE); - m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE); + m_maincpu->set_input_line(M68K_IRQ_3, CLEAR_LINE); + m_maincpu->set_input_line(M68K_IRQ_2, CLEAR_LINE); + m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE); } } @@ -291,7 +519,7 @@ WRITE16_MEMBER(esq5505_state::lower_w) static ADDRESS_MAP_START( vfx_map, AS_PROGRAM, 16, esq5505_state ) AM_RANGE(0x000000, 0x007fff) AM_READWRITE(lower_r, lower_w) - AM_RANGE(0x200000, 0x20001f) AM_DEVREADWRITE_LEGACY("ensoniq", es5505_r, es5505_w) + AM_RANGE(0x200000, 0x20001f) AM_DEVREADWRITE_LEGACY("otis", es5505_r, es5505_w) AM_RANGE(0x280000, 0x28001f) AM_DEVREADWRITE8("duart", duartn68681_device, read, write, 0x00ff) AM_RANGE(0x260000, 0x2601ff) AM_DEVREADWRITE8("esp", es5510_device, host_r, host_w, 0x00ff) AM_RANGE(0xc00000, 0xc1ffff) AM_ROM AM_REGION("osrom", 0) @@ -300,7 +528,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( vfxsd_map, AS_PROGRAM, 16, esq5505_state ) AM_RANGE(0x000000, 0x00ffff) AM_READWRITE(lower_r, lower_w) - AM_RANGE(0x200000, 0x20001f) AM_DEVREADWRITE_LEGACY("ensoniq", es5505_r, es5505_w) + AM_RANGE(0x200000, 0x20001f) AM_DEVREADWRITE_LEGACY("otis", es5505_r, es5505_w) AM_RANGE(0x280000, 0x28001f) AM_DEVREADWRITE8("duart", duartn68681_device, read, write, 0x00ff) AM_RANGE(0x260000, 0x2601ff) AM_DEVREADWRITE8("esp", es5510_device, host_r, host_w, 0x00ff) AM_RANGE(0x2c0000, 0x2c0007) AM_DEVREADWRITE8("wd1772", wd1772_t, read, write, 0x00ff) @@ -311,7 +539,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( eps_map, AS_PROGRAM, 16, esq5505_state ) AM_RANGE(0x000000, 0x007fff) AM_READWRITE(lower_r, lower_w) - AM_RANGE(0x200000, 0x20001f) AM_DEVREADWRITE_LEGACY("ensoniq", es5505_r, es5505_w) + AM_RANGE(0x200000, 0x20001f) AM_DEVREADWRITE_LEGACY("otis", es5505_r, es5505_w) AM_RANGE(0x240000, 0x2400ff) AM_DEVREADWRITE_LEGACY("mc68450", hd63450_r, hd63450_w) AM_RANGE(0x280000, 0x28001f) AM_DEVREADWRITE8("duart", duartn68681_device, read, write, 0x00ff) AM_RANGE(0x2c0000, 0x2c0007) AM_DEVREADWRITE8("wd1772", wd1772_t, read, write, 0x00ff) @@ -322,7 +550,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( sq1_map, AS_PROGRAM, 16, esq5505_state ) AM_RANGE(0x000000, 0x03ffff) AM_READWRITE(lower_r, lower_w) - AM_RANGE(0x200000, 0x20001f) AM_DEVREADWRITE_LEGACY("ensoniq", es5505_r, es5505_w) + AM_RANGE(0x200000, 0x20001f) AM_DEVREADWRITE_LEGACY("otis", es5505_r, es5505_w) AM_RANGE(0x260000, 0x2601ff) AM_DEVREADWRITE8("esp", es5510_device, host_r, host_w, 0x0ff) AM_RANGE(0x280000, 0x28001f) AM_DEVREADWRITE8("duart", duartn68681_device, read, write, 0x00ff) AM_RANGE(0x2c0000, 0x2c0007) AM_DEVREADWRITE8("wd1772", wd1772_t, read, write, 0x00ff) @@ -448,14 +676,14 @@ WRITE8_MEMBER(esq5505_state::duart_output) */ if (data & 0x40) { - if (!m_esp->input_state(es5510_device::ES5510_HALT)) { - logerror("ESQ5505: Asserting ESPHALT\n"); - m_esp->set_input_line(es5510_device::ES5510_HALT, ASSERT_LINE); + if (!m_pump->get_esp_halted()) { + logerror("ESQ5505: Asserting ESPHALT\n"); + m_pump->set_esp_halted(true); } } else { - if (m_esp->input_state(es5510_device::ES5510_HALT)) { - logerror("ESQ5505: Clearing ESPHALT\n"); - m_esp->set_input_line(es5510_device::ES5510_HALT, CLEAR_LINE); + if (m_pump->get_esp_halted()) { + logerror("ESQ5505: Clearing ESPHALT\n"); + m_pump->set_esp_halted(false); } } @@ -611,6 +839,7 @@ static const es5505_interface es5505_config = { "waverom", /* Bank 0 */ "waverom2", /* Bank 1 */ + 4, /* channels */ DEVCB_DRIVER_LINE_MEMBER(esq5505_state,esq5505_otis_irq), /* irq */ DEVCB_DEVICE_HANDLER(DEVICE_SELF, esq5505_read_adc) }; @@ -643,6 +872,7 @@ static MACHINE_CONFIG_START( vfx, esq5505_state ) MCFG_CPU_PROGRAM_MAP(vfx_map) MCFG_CPU_ADD("esp", ES5510, XTAL_10MHz) + MCFG_DEVICE_DISABLE() MCFG_ESQPANEL2x40_ADD("panel", esqpanel_config) @@ -652,10 +882,21 @@ static MACHINE_CONFIG_START( vfx, esq5505_state ) MCFG_SERIAL_PORT_ADD("mdout", midiout_intf, midiout_slot, "midiout") MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") - MCFG_SOUND_ADD("ensoniq", ES5505, XTAL_10MHz) - MCFG_SOUND_CONFIG(es5505_config) + + MCFG_SOUND_ADD("pump", ESQ_5505_5510_PUMP, XTAL_10MHz / (16 * 21)) MCFG_SOUND_ROUTE(0, "lspeaker", 2.0) MCFG_SOUND_ROUTE(1, "rspeaker", 2.0) + + MCFG_SOUND_ADD("otis", ES5505, XTAL_10MHz) + MCFG_SOUND_CONFIG(es5505_config) + MCFG_SOUND_ROUTE_EX(0, "pump", 1.0, 0) + MCFG_SOUND_ROUTE_EX(1, "pump", 1.0, 1) + MCFG_SOUND_ROUTE_EX(2, "pump", 1.0, 2) + MCFG_SOUND_ROUTE_EX(3, "pump", 1.0, 3) + MCFG_SOUND_ROUTE_EX(4, "pump", 1.0, 4) + MCFG_SOUND_ROUTE_EX(5, "pump", 1.0, 5) + MCFG_SOUND_ROUTE_EX(6, "pump", 1.0, 6) + MCFG_SOUND_ROUTE_EX(7, "pump", 1.0, 7) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED(eps, vfx) @@ -685,6 +926,7 @@ static MACHINE_CONFIG_START(vfx32, esq5505_state) MCFG_CPU_PROGRAM_MAP(vfxsd_map) MCFG_CPU_ADD("esp", ES5510, XTAL_10MHz) + MCFG_DEVICE_DISABLE() MCFG_ESQPANEL2x40_ADD("panel", esqpanel_config) @@ -694,11 +936,22 @@ static MACHINE_CONFIG_START(vfx32, esq5505_state) MCFG_SERIAL_PORT_ADD("mdout", midiout_intf, midiout_slot, "midiout") MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") - MCFG_SOUND_ADD("ensoniq", ES5505, XTAL_30_4761MHz / 2) - MCFG_SOUND_CONFIG(es5505_config) + + MCFG_SOUND_ADD("pump", ESQ_5505_5510_PUMP, XTAL_30_4761MHz / (2 * 16 * 32)) MCFG_SOUND_ROUTE(0, "lspeaker", 2.0) MCFG_SOUND_ROUTE(1, "rspeaker", 2.0) + MCFG_SOUND_ADD("otis", ES5505, XTAL_30_4761MHz / 2) + MCFG_SOUND_CONFIG(es5505_config) + MCFG_SOUND_ROUTE_EX(0, "pump", 1.0, 0) + MCFG_SOUND_ROUTE_EX(1, "pump", 1.0, 1) + MCFG_SOUND_ROUTE_EX(2, "pump", 1.0, 2) + MCFG_SOUND_ROUTE_EX(3, "pump", 1.0, 3) + MCFG_SOUND_ROUTE_EX(4, "pump", 1.0, 4) + MCFG_SOUND_ROUTE_EX(5, "pump", 1.0, 5) + MCFG_SOUND_ROUTE_EX(6, "pump", 1.0, 6) + MCFG_SOUND_ROUTE_EX(7, "pump", 1.0, 7) + MCFG_WD1772x_ADD("wd1772", 8000000) MCFG_FLOPPY_DRIVE_ADD("wd1772:0", ensoniq_floppies, "35dd", esq5505_state::floppy_formats) MACHINE_CONFIG_END diff --git a/src/mess/drivers/esqkt.c b/src/mess/drivers/esqkt.c index 5cf87ddb243..04ad0f666ac 100644 --- a/src/mess/drivers/esqkt.c +++ b/src/mess/drivers/esqkt.c @@ -410,6 +410,7 @@ static const es5506_interface es5506_config = "waverom2", /* Bank 1 */ "waverom3", /* Bank 0 */ "waverom4", /* Bank 1 */ + 1, /* channels */ DEVCB_DRIVER_LINE_MEMBER(esqkt_state,esq5506_otto_irq), /* irq */ DEVCB_DEVICE_HANDLER(DEVICE_SELF, esq5506_read_adc) }; @@ -420,6 +421,7 @@ static const es5506_interface es5506_2_config = "waverom2", /* Bank 1 */ "waverom3", /* Bank 0 */ "waverom4", /* Bank 1 */ + 1, /* channels */ DEVCB_NULL, DEVCB_NULL }; diff --git a/src/mess/drivers/esqmr.c b/src/mess/drivers/esqmr.c index f794c60395e..1bcbe89b1f0 100644 --- a/src/mess/drivers/esqmr.c +++ b/src/mess/drivers/esqmr.c @@ -65,6 +65,7 @@ static const es5506_interface es5506_config = "waverom2", /* Bank 1 */ "waverom3", /* Bank 0 */ "waverom4", /* Bank 1 */ + 1, /* channels */ DEVCB_LINE(esq5506_otto_irq), /* irq */ DEVCB_DEVICE_HANDLER(DEVICE_SELF, esq5506_read_adc) }; @@ -75,6 +76,7 @@ static const es5506_interface es5506_2_config = "waverom2", /* Bank 1 */ "waverom3", /* Bank 0 */ "waverom4", /* Bank 1 */ + 1, /* channels */ DEVCB_NULL, DEVCB_NULL };