Previous 199869 Revisions Next

r24766 Tuesday 6th August, 2013 at 02:49:26 UTC by R. Belmont
es5510: improved debug capabilities, better disassembly, bugfixed many opcodes.  Most effects programs now produce correct results. [Christian Brunschen]
[src/emu/cpu/es5510]es5510.c es5510.h
[src/mess/drivers]esq5505.c

trunk/src/emu/cpu/es5510/es5510.h
r24765r24766
9191      op_src_dst_t src;
9292      op_src_dst_t dst;
9393      bool accumulate;
94      INT64 cValue;
95      INT64 dValue;
94      INT32 cValue;
95      INT32 dValue;
9696      INT64 product;
9797      INT64 result;
9898      bool write_result;
r24765r24766
111111   void run_once();
112112   void list_program(void(p)(const char *, ...));
113113
114   // for testing purposes
115   UINT64 &_instr(int pc) { return instr[pc % 160]; }
116   INT16 &_dram(int addr) { return dram[addr & 0xfffff]; }
117
118   // publicly visible for testing purposes
119   INT32 read_reg(UINT8 reg);
120   void write_reg(UINT8 reg, INT32 value);
121   void write_to_dol(INT32 value);
122
114123protected:
115124   virtual void device_start();
116125   virtual void device_reset();
r24765r24766
126135   virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
127136   virtual void execute_set_input(int linenum, int state);
128137
129   INT32 read_reg(UINT8 reg);
130   void write_reg(UINT8 reg, INT32 value);
131   void write_to_dol(INT32 value);
132
133138   INT32 alu_operation(UINT8 op, INT32 aValue, INT32 bValue, UINT8 &flags);
134139   void alu_operation_end();
135140
r24765r24766
138143   bool halt_asserted;
139144   UINT8 pc;
140145   state_t state;
141   INT32 gpr[0xc0];     // 24 bits, right justified and sign extended
142   INT32 ser0r;
143   INT32 ser0l;
144   INT32 ser1r;
145   INT32 ser1l;
146   INT32 ser2r;
147   INT32 ser2l;
148   INT32 ser3r;
149   INT32 ser3l;
150   INT64 machl;      // 48 bits, right justified and sign extended
146   INT32 gpr[0xc0];     // 24 bits, right justified
147   INT16 ser0r;
148   INT16 ser0l;
149   INT16 ser1r;
150   INT16 ser1l;
151   INT16 ser2r;
152   INT16 ser2l;
153   INT16 ser3r;
154   INT16 ser3l;
155   INT64 machl;      // 48 bits, right justified and sign extended
156   bool mac_overflow;   // whether reading the MAC register should return a saturated replacement value
151157   INT32 dil;
152158   INT32 memsiz;
153159   INT32 memmask;
r24765r24766
159165   INT32 dbase;
160166   INT32 sigreg;
161167   int mulshift;
162   INT8 ccr;         // really, 5 bits, left justified
163   INT8 cmr;         // really, 6 bits, left justified
168   INT8 ccr;         // really, 5 bits, left justified
169   INT8 cmr;         // really, 6 bits, left justified
164170   INT32 dol[2];
165171   int dol_count;
166172
167173   UINT64 instr[160];    // 48 bits, right justified
168   UINT16 dram[1<<20];   // there are up to 20 address bits (at least 16 expected), left justified within the 24 bits of a gpr or dadr; we preallocate all of it.
174   INT16 dram[1<<20];   // there are up to 20 address bits (at least 16 expected), left justified within the 24 bits of a gpr or dadr; we preallocate all of it.
169175
170176   // latch registers for host interaction
171177   INT32  dol_latch;     // 24 bits
trunk/src/emu/cpu/es5510/es5510.c
r24765r24766
1414#define VERBOSE 0
1515
1616#if VERBOSE
17#define LOG(x) do { logerror x; } while(0)
17void log_to_stderr(const char *format, ...) {
18   va_list ap;
19   va_start(ap, format);
20   vfprintf(stderr, format, ap);
21   va_end(ap);
22}
23
24#define LOG(x) do { log_to_stderr x; } while(0)
1825#else
1926#define LOG(x)
2027#endif
2128
29#define VERBOSE_EXEC 0
30
31#if VERBOSE_EXEC
32static int exec_cc = 0;
33#define LOG_EXEC(x) do { if (!exec_cc) LOG(x); } while(0)
34#else
35#define LOG_EXEC(x)
36#endif
37
2238const device_type ES5510 = &device_creator<es5510_device>;
2339
2440#define FLAG_N (1 << 7)
r24765r24766
5470
5571inline static INT32 add(INT32 a, INT32 b, UINT8 &flags) {
5672   INT32 aSign = a & 0x00800000;
57   INT32 bSign = (b & 0x00800000) == 0;
73   INT32 bSign = b & 0x00800000;
5874   INT32 result = a + b;
5975   INT32 resultSign = result & 0x00800000;
6076   bool overflow = (aSign == bSign) && (aSign != resultSign);
r24765r24766
90106   return saturate(result, flags);
91107}
92108
93
94109es5510_device::es5510_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
95110: cpu_device(mconfig, ES5510, "ES5510", tag, owner, clock, "es5510", __FILE__)
96111{
r24765r24766
135150   instr_latch = 0;
136151   ram_sel = 0;
137152   host_control = 0;
138
153   
154   pc = 0;
139155   memset(&alu, 0, sizeof(alu));
140156   memset(&mulacc, 0, sizeof(mulacc));
141157}
r24765r24766
146162
147163static inline INT32 SX(INT32 x) { return (x & 0x00800000) ? x | 0xff000000 : x & 0x00ffffff; }
148164static inline INT32 SC(INT32 x) { return x & 0x00ffffff; }
149static inline INT64 SX64(INT64 x) { return (x & U64(0x0000800000000000)) ? x | U64(0xffff000000000000) : x & U64(0x0000ffffffffffff); }
150static inline INT64 SC64(INT64 x) { return x & U64(0x0000ffffffffffff); }
165static inline INT64 SX64(INT64 x) { return (x & S64(0x0000800000000000)) ? x | S64(0xffff000000000000) : x & S64(0x0000ffffffffffff); }
166static inline INT64 SC64(INT64 x) { return x & S64(0x0000ffffffffffff); }
151167
152168static inline const char * const REGNAME(UINT8 r) {
153169   static char rn[8];
r24765r24766
179195   return NULL;
180196}
181197
182static inline char * DESCRIBE_REG(char *s, UINT8 r) {
183   return stpcpy_int(s, REGNAME(r));
198static inline char * DESCRIBE_REG(char *s, UINT8 r, const char *name) {
199   if (name) {
200      return s + sprintf(s, "%s/%s", REGNAME(r), name);
201   } else {
202      return stpcpy_int(s, REGNAME(r));
203   }
184204}
185205
186206const alu_op_t es5510_device::ALU_OPS[16] = {
r24765r24766
224244   { es5510_device::SRC_DST_DELAY, es5510_device::SRC_DST_BOTH, es5510_device::SRC_DST_DELAY, es5510_device::SRC_DST_REG },
225245};
226246
227static inline char * DESCRIBE_SRC_DST(char *s, UINT8 reg, op_src_dst_t src_dst) {
247static inline char * DESCRIBE_SRC_DST(char *s, UINT8 reg, const char *regname, op_src_dst_t src_dst) {
228248   switch (src_dst) {
229249   case es5510_device::SRC_DST_REG:
230      return DESCRIBE_REG(s, reg);
250      return DESCRIBE_REG(s, reg, regname);
231251   case es5510_device::SRC_DST_DELAY:
232252      return stpcpy_int(s, "Delay");
233253   case es5510_device::SRC_DST_BOTH:
234      s = DESCRIBE_REG(s, reg);
254      s = DESCRIBE_REG(s, reg, regname);
235255      return stpcpy_int(s, ",Delay");
236256   }
237257   // should never happen!
r24765r24766
245265   { es5510_device::RAM_CYCLE_WRITE,     es5510_device::RAM_CONTROL_TABLE_A, "Write Table A+%06x" },
246266   { es5510_device::RAM_CYCLE_READ,      es5510_device::RAM_CONTROL_TABLE_B, "Read Table B+%06x" },
247267   { es5510_device::RAM_CYCLE_DUMP_FIFO, es5510_device::RAM_CONTROL_DELAY,   "Read Delay+%06x and Dump FIFO" },
248   { es5510_device::RAM_CYCLE_READ,      es5510_device::RAM_CONTROL_IO,      "Read I/O at %06x" },
249   { es5510_device::RAM_CYCLE_WRITE,     es5510_device::RAM_CONTROL_IO,      "Write I/o %06x" },
268   { es5510_device::RAM_CYCLE_READ,      es5510_device::RAM_CONTROL_IO,      "Read from I/O at %06x" },
269   { es5510_device::RAM_CYCLE_WRITE,     es5510_device::RAM_CONTROL_IO,      "Write to I/O at %06x" },
250270};
251271
252272static inline char * DESCRIBE_RAM(char *s, UINT8 ramControl, UINT32 gprContents) {
253273   return s + sprintf(s, es5510_device::RAM_CONTROL[ramControl].description, SC(gprContents));
254274}
255275
256static inline char * DESCRIBE_ALU(char *s, UINT8 opcode, UINT8 aReg, UINT8 bReg, const op_select_t &opSelect) {
276static inline char * DESCRIBE_ALU(char *s, UINT8 opcode, UINT8 aReg, const char *aName, UINT8 bReg, const char *bName, const op_select_t &opSelect) {
257277   const alu_op_t &op = es5510_device::ALU_OPS[opcode];
258278
259279   switch (op.operands) {
r24765r24766
261281      return stpcpy_int(s, op.opcode);
262282
263283   case 1:
264      s += sprintf(s, "%s %s >", op.opcode, REGNAME(bReg));
265      return DESCRIBE_SRC_DST(s, aReg, opSelect.alu_dst);
284      s += sprintf(s, "%s ", op.opcode);
285      s = DESCRIBE_SRC_DST(s, bReg, bName, opSelect.alu_src);
286      s += sprintf(s, " >");
287      return DESCRIBE_SRC_DST(s, aReg, aName, opSelect.alu_dst);
266288
267289   case 2:
268      s += sprintf(s, "%s %s,", op.opcode, REGNAME(bReg));
269      s = DESCRIBE_SRC_DST(s, aReg, opSelect.alu_src);
290      s += sprintf(s, "%s ", op.opcode);
291      s = DESCRIBE_REG(s, bReg, bName);
292      s += sprintf(s, " ");
293      s = DESCRIBE_SRC_DST(s, aReg, aName, opSelect.alu_src);
270294      s += sprintf(s, " >");
271      return DESCRIBE_SRC_DST(s, aReg, opSelect.alu_dst);
295      return DESCRIBE_SRC_DST(s, aReg, aName, opSelect.alu_dst);
272296   }
273297   return s;
274298}
275299
276static inline char * DESCRIBE_MAC(char *s, UINT8 mac, UINT8 cReg, UINT8 dReg, const op_select_t &opSelect)
300static inline char * DESCRIBE_MAC(char *s, UINT8 mac, UINT8 cReg, const char *cName, UINT8 dReg, const char *dName, const op_select_t &opSelect)
277301{
278302   if (mac)
279303   {
280304      s += sprintf(s, "MAC + ");
281305   }
282   s = DESCRIBE_REG(s, dReg);
306   s = DESCRIBE_REG(s, dReg, dName);
283307   s += sprintf(s, " * ");
284   s = DESCRIBE_SRC_DST(s, cReg, opSelect.mac_src);
308   s = DESCRIBE_SRC_DST(s, cReg, cName, opSelect.mac_src);
285309   s += sprintf(s, " >");
286   return DESCRIBE_SRC_DST(s, cReg, opSelect.mac_dst);
310   return DESCRIBE_SRC_DST(s, cReg, cName, opSelect.mac_dst);
287311}
288312
289static inline char * DESCRIBE_INSTR(char *s, UINT64 instr, UINT32 gpr)
313static inline char * DESCRIBE_INSTR(char *s, UINT64 instr, UINT32 gpr, const char *aName, const char *bName, const char *cName, const char *dName)
290314{
291315   UINT8 dReg = (UINT8)((instr >> 40) & 0xff);
292316   UINT8 cReg = (UINT8)((instr >> 32) & 0xff);
r24765r24766
300324
301325   const op_select_t &opSelect = es5510_device::OPERAND_SELECT[operandSelect];
302326
303   s = DESCRIBE_ALU(s, aluOpcode, aReg, bReg, opSelect);
327   s = DESCRIBE_ALU(s, aluOpcode, aReg, aName, bReg, bName, opSelect);
304328   s += sprintf(s, "; ");
305   s = DESCRIBE_MAC(s, mac, cReg, dReg, opSelect);
329   s = DESCRIBE_MAC(s, mac, cReg, cName, dReg, dName, opSelect);
306330   s += sprintf(s, "; ");
307331   s = DESCRIBE_RAM(s, ramControl, gpr);
308332   if (skip) {
r24765r24766
341365
342366   case 0x09: LOG(("ES5510: Host Read DIL latch[2]: %02x\n", (dil_latch >> 16) & 0xff)); return (dil_latch >> 16) & 0xff;
343367   case 0x0a: LOG(("ES5510: Host Read DIL latch[1]: %02x\n", (dil_latch >>  8) & 0xff)); return (dil_latch >>  8) & 0xff;
344   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
368   case 0x0b: LOG(("ES5510: Host Read DIL latch[0]: %02x\n", 0)); return 0;
345369
346370   case 0x0c: LOG(("ES5510: Host Read DOL latch[2]: %02x\n", (dol_latch >> 16) & 0xff)); return (dol_latch >> 16) & 0xff;
347371   case 0x0d: LOG(("ES5510: Host Read DOL latch[1]: %02x\n", (dol_latch >>  8) & 0xff)); return (dol_latch >>  8) & 0xff;
348   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
372   case 0x0e: LOG(("ES5510: Host Read DOL latch[0]: %02x\n", 0xff)); return 0xff;
349373
350374   case 0x0f: LOG(("ES5510: Host Read DADR latch[2]: %02x\n", (dadr_latch >> 16) & 0xff)); return (dadr_latch >> 16) & 0xff;
351375   case 0x10: LOG(("ES5510: Host Read DADR latch[1]: %02x\n", (dadr_latch >>  8) & 0xff)); return (dadr_latch >>  8) & 0xff;
r24765r24766
397421      dadr_latch = (dadr_latch&0x00ffff) | ((data&0xff)<<16);
398422      if (ram_sel)
399423      {
400         dil_latch = dram[dadr_latch];
424         dil_latch = dram[dadr_latch] << 8;
401425      }
402426      else
403427      {
404         dram[dadr_latch] = dol_latch;
428         dram[dadr_latch] = dol_latch >> 8;
405429      }
406430      break;
407431
r24765r24766
455479
456480   case 0xc0: /* Write select - INSTR */
457481#if VERBOSE
458      DESCRIBE_INSTR(buf, instr_latch, gpr[data]);
482      DESCRIBE_INSTR(buf, instr_latch, gpr[data], NULL, NULL, NULL, NULL);
459483      LOG(("ES5510: Host Write INSTR %02x %012" I64FMT "x: %s\n", data, instr_latch&U64(0xffffffffffff), buf));
460484#endif
461485      if (data < 0xa0) {
r24765r24766
465489
466490   case 0xe0: /* Write select - GPR + INSTR */
467491#if VERBOSE
468      DESCRIBE_INSTR(buf, instr_latch, gpr_latch);
492      DESCRIBE_INSTR(buf, instr_latch, gpr_latch, NULL, NULL, NULL, NULL);
469493      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));
470494#endif
471495      if (data < 0xa0) {
r24765r24766
560584void es5510_device::list_program(void(p)(const char *, ...)) {
561585   LOG(("ES5501: Starting!\n"));
562586
563   UINT8 addr;
564587   char buf[1024];
588   bool is_written[0xff], is_read[0xff];
589   char name[0xff][16];
590   int addr;
591
592   for (int i = 0; i < 0x100; i++) {
593      is_written[i] = is_read[i] = false;
594      name[i][0] = '\0';
595   }
596   
565597   for (addr = 0; addr < 0xa0; addr++) {
566      DESCRIBE_INSTR(buf, instr[addr], gpr[addr]);
567      p("%02x: %012" I64FMT "x %06x  %s\n", addr, instr[addr], gpr[addr]&0xffffff, buf);
598      DESCRIBE_INSTR(buf, instr[addr], gpr[addr], NULL, NULL, NULL, NULL);
599      UINT64 inst = instr[addr];
600      UINT8 aReg = (UINT8)((inst >> 16) & 0xff);
601      UINT8 bReg = (UINT8)((inst >> 24) & 0xff);
602      UINT8 cReg = (UINT8)((inst >> 32) & 0xff);
603      UINT8 dReg = (UINT8)((inst >> 40) & 0xff);
604      UINT8 alu_op = (inst >> 12) & 0x0f;
605      if (alu_op == 0x0f) {
606         // END!
607         break;
608      }
609
610      UINT8 operandSelect = (UINT8)((inst >> 8) & 0x0f);
611      const op_select_t &opSelect = OPERAND_SELECT[operandSelect];     
612
613      if (opSelect.mac_src == SRC_DST_REG) {
614         is_read[cReg] = true;
615      }
616      is_read[dReg] = true;
617      if (opSelect.mac_dst != SRC_DST_DELAY) { // either REG or BOTH
618         is_written[cReg] = true;
619      }
620     
621      alu_op_t aluOp = ALU_OPS[alu_op];
622      if (aluOp.operands == 1) {
623         if (opSelect.alu_src == SRC_DST_REG) {
624            is_read[bReg] = true;
625         }
626      } else if (aluOp.operands == 2) {
627         if (opSelect.alu_src == SRC_DST_REG) {
628            is_read[aReg] = true;
629         }
630         is_read[bReg] = true;
631      }
632      if (opSelect.mac_dst != SRC_DST_DELAY) { // either REG or BOTH
633         is_written[aReg] = true;
634      }
568635   }
636
637   int varIndex = 1;
638   int constIndex = 1;
639   for (int i = 0; i < 0xc0; i++) {
640      if (is_written[i]) {
641         // this is a variable
642         sprintf(name[i], "v_%03d", varIndex++);
643      } else if (is_read[i]) {
644         // this is only read, so a constant - or possibly something updated by the CPU
645         sprintf(name[i], "c_%03d", constIndex++);
646      } else {
647         name[i][0] = 0;
648      }
649   }
650   for (int i = 0xc0; i < 0x100; i++) {
651      name[i][0] = 0;
652   }
653   
654   for (addr = 0; addr < 0xa0; addr++) {
655      UINT8 aReg = (UINT8)((instr[addr] >> 16) & 0xff);
656      UINT8 bReg = (UINT8)((instr[addr] >> 24) & 0xff);
657      UINT8 cReg = (UINT8)((instr[addr] >> 32) & 0xff);
658      UINT8 dReg = (UINT8)((instr[addr] >> 40) & 0xff);
659      DESCRIBE_INSTR(buf, instr[addr], gpr[addr], name[aReg], name[bReg], name[cReg], name[dReg]);
660      p("%02x: %012" I64FMT "x %06x (%8d) %s\n", addr, instr[addr], gpr[addr]&0xffffff, SX(gpr[addr]&0xffffff), buf);
661   }
569662   for (; addr < 0xc0; addr++) {
570      p("%02x: %06x (%d)\n", addr, gpr[addr]&0xffffff, gpr[addr]);
663      p("%02x: %06x (%d)\n", addr, gpr[addr]&0xffffff, SX(gpr[addr]&0xffffff));
571664   }
572665}
573666
r24765r24766
587680      } else {
588681         // currently running, execute one instruction.
589682
590#if VERBOSE
683#if VERBOSE_EXEC
591684         char buf[1024];
592         DESCRIBE_INSTR(buf, instr[pc], gpr[pc]);
593         LOG(("%02x: %012" I64FMT "x %06x  %s\n", pc, instr[pc], gpr[pc]&0xffffff, buf));
685         DESCRIBE_INSTR(buf, instr[pc], gpr[pc], NULL, NULL, NULL, NULL);
686         LOG_EXEC(("EXECUTING %02x: %012" I64FMT "x %06x  %s\n", pc, instr[pc], gpr[pc]&0xffffff, buf));
594687#endif
595688
596689         ram_pp = ram_p;
597690         ram_p = ram;
598691
692         LOG_EXEC(("- T0\n"));
693
599694         // *** T0, clock high
600695         // --- nothing to do!
601696
r24765r24766
608703            if (ram_pp.io) { // read from I/O and store into DIL
609704               dil = 0; // read_io(ram_pp.address);;
610705            } else { // read from DRAM and store into DIL
611               dil = dram[ram_pp.address];
706               dil = dram[ram_pp.address] << 8;
707               LOG_EXEC(("  . RAM: read %x (%d) from address %x\n", dil, dil, ram_pp.address));
612708            }
613709         }
614710
r24765r24766
621717         INT32 offset = gpr[pc];
622718         switch(ramControl.access) {
623719         case RAM_CONTROL_DELAY:
624            ram.address = (((dbase + offset) % (dlength + 1)) & memmask) >> memshift;
720            ram.address = (((dbase + offset) % (dlength + memincrement)) & memmask) >> memshift;
721            LOG_EXEC((". Ram Control: Delay, base=%x, offset=%x, length=%x => address=%x\n", dbase >> memshift, offset >> memshift, (dlength + memincrement) >> memshift, ram.address));
625722            break;
626723         case RAM_CONTROL_TABLE_A:
627724            ram.address = ((abase + offset) & memmask) >> memshift;
725            LOG_EXEC((". Ram Control: table A = %x, offset=%x => address=%x\n", abase >> memshift, offset >> memshift, ram.address));
628726            break;
629727         case RAM_CONTROL_TABLE_B:
630728            ram.address = ((bbase + offset) & memmask) >> memshift;
729            LOG_EXEC((". Ram Control: table B = %x, offset=%x => address=%x\n", bbase >> memshift, offset >> memshift, ram.address));
631730            break;
632731         case RAM_CONTROL_IO:
633732            ram.address = offset & 0x00fffff0; // mask off the low 4 bits
733            LOG_EXEC((". Ram Control: I/O at address=%x\n", ram.address));
634734            break;
635735         }
636736
r24765r24766
638738         // --- Decode instruction N;
639739         //     we will do this both here and in stages as the different parts of the instruction complete & recommence.
640740
741         LOG_EXEC(("- T1.1\n"));
742
641743         UINT8 operandSelect = (UINT8)((instr >> 8) & 0x0f);
642744         const op_select_t &opSelect = OPERAND_SELECT[operandSelect];
643         bool skip = false;
644         bool skippable = ((instr >> 7) & 0x01) != 0; // aka the 'SKIP' bit in the instruction word
745         bool skip;
746         bool skippable = (instr & (0x01 << 7)) != 0; // aka the 'SKIP' bit in the instruction word
645747         if (skippable) {
646748            bool skipConditionSatisfied = (ccr & cmr & FLAG_MASK) != 0;
647749            if (isFlagSet(cmr, FLAG_NOT)) {
648750               skipConditionSatisfied = !skipConditionSatisfied;
649751            }
650752            skip = skipConditionSatisfied;
753            LOG_EXEC((". skippable: %x vs %x => skippable = %d\n", ccr, cmr, skip));
754         } else {
755            skip = false;
651756         }
652757
653758         // --- Write Multiplier result N-1
759         LOG_EXEC((". write mulacc:\n"));
654760         if (mulacc.write_result) {
655            mulacc.product = (mulacc.cValue * mulacc.dValue) << mulshift;
656            mulacc.result = (mulacc.accumulate ? machl : 0) + mulacc.product;
657            INT32 tmp = (mulacc.result & U64(0x0000ffffff000000)) >> 24;
761            mulacc.product = ((INT64)SX(mulacc.cValue) * (INT64)SX(mulacc.dValue)) << mulshift;
762            if (mulacc.accumulate) {
763               mulacc.result = mulacc.product + machl;
764            } else {
765               mulacc.result = mulacc.product;
766            }
767
768            INT64 result_min = ~0LL << 47;
769            INT64 result_max = (1LL << 48) - 1;
770
771            if (mulacc.result < result_min || mulacc.result > result_max) {
772               mac_overflow = true;
773            } else {
774               mac_overflow = false;
775            }
776#if VERBOSE_EXEC
777            if (mulacc.cValue || mulacc.dValue || (mulacc.accumulate && machl)) {
778               LOG_EXEC((". mulacc: %x (%d) * %x (%d) << %d", SX(mulacc.cValue), SX(mulacc.cValue), SX(mulacc.dValue), SX(mulacc.dValue), mulshift));
779               if (mulacc.accumulate) LOG_EXEC((" + %llx (%lld) ", machl, machl));
780               LOG_EXEC((" = %llx (%lld)", mulacc.result, mulacc.result));
781               if (mac_overflow) {
782                  LOG_EXEC((" overflow!\n"));
783               } else {
784                  LOG_EXEC(("\n"));
785               }
786            }
787#endif
788            machl = mulacc.result;
789            INT32 tmp = mac_overflow ? (machl < 0 ? 0x00800000 : 0x007fffff) : (mulacc.result & U64(0x0000ffffff000000)) >> 24;
658790            if (mulacc.dst & SRC_DST_REG) {
659               machl = mulacc.result;
660791               write_reg(mulacc.cReg, tmp);
661792            }
662793            if (mulacc.dst & SRC_DST_DELAY) {
r24765r24766
665796         }
666797
667798         // *** T1, clock low
799
800         LOG_EXEC(("- T1.0\n"));
801
668802         // --- Start of multiplier cycle N
803         LOG_EXEC((". start mulacc:\n"));
669804         mulacc.cReg = (UINT8)((instr >> 32) & 0xff);
670805         mulacc.dReg = (UINT8)((instr >> 40) & 0xff);
671806         mulacc.src = opSelect.mac_src;
r24765r24766
677812         if (mulacc.src == SRC_DST_REG) {
678813            mulacc.cValue = read_reg(mulacc.cReg);
679814         } else { // must be SRC_DST_DELAY
815            LOG_EXEC(("  . reading %x (%d) from dil\n", dil, SX(dil)));
680816            mulacc.cValue = dil;
681817         }
682818         mulacc.dValue = read_reg(mulacc.dReg);
683819
684820         // *** T2, clock high
821
822         LOG_EXEC(("- T2.1\n"));
823       
685824         // --- Write ALU Result N-1
825         LOG_EXEC((". write ALU:\n"));
686826         if (alu.write_result) {
687827            UINT8 flags = ccr;
688828            alu.result = alu_operation(alu.op, alu.aValue, alu.bValue, flags);
r24765r24766
698838         }
699839
700840         // *** T2, clock low
841
842         LOG_EXEC(("- T2.0\n"));
843
701844         // --- Start of ALU cycle N
845         LOG_EXEC((". start ALU:\n"));
702846         alu.aReg = (instr >> 16) & 0xff;
703847         alu.bReg = (instr >> 24) & 0xff;
704848         alu.op = (instr >> 12) & 0x0f;
r24765r24766
712856         } else {
713857            // --- Read ALU Operands N
714858            alu_op_t aluOp = ALU_OPS[alu.op];
715            if (aluOp.operands == 2) {
859            if (aluOp.operands == 1) {
716860               if (alu.src == SRC_DST_REG) {
861                  alu.bValue = read_reg(alu.bReg);
862               } else { // must be SRC_DST_DELAY
863                  alu.bValue = dil;
864               }
865            } else {
866               if (alu.src == SRC_DST_REG) {
717867                  alu.aValue = read_reg(alu.aReg);
718868               } else { // must be SRC_DST_DELAY
719869                  alu.aValue = dil;
720870               }
721            }
722            if (aluOp.operands >= 1) {
723871               alu.bValue = read_reg(alu.bReg);
724872            }
725873         }
r24765r24766
731879               if (ram_p.io) {
732880                  // write_io(ram_p.io, dol[0]);
733881               } else {
734                  dram[ram_p.address] = dol[0];
882                  dram[ram_p.address] = dol[0] >> 8;
883                  LOG_EXEC(("  . RAM: writing %x (%d) [of %x (%d)] to address %x\n", dol[0]&0xffff00, SX(dol[0]&0xffff00), dol[0], SX(dol[0]), ram_p.address));
735884               }
736885            }
737886            // If this is a Write or Dump cycle, eject the frontmost DL value.
887#if VERBOSE_EXEC
888            LOG_EXEC(("  . ejecting from DOL: [ "));
889            if (dol_count >= 1) LOG_EXEC(("{ %x (%d) }", dol[0], SX(dol[0])));
890            if (dol_count == 2) LOG_EXEC((", { %x (%d) }", dol[1], SX(dol[1])));
891            LOG_EXEC((" ] -> [ "));
892#endif
738893            dol[0] = dol[1];
739894            if (dol_count > 0) {
740895               --dol_count;
741896            }
897#if VERBOSE_EXEC
898            if (dol_count >= 1) LOG_EXEC(("{ %x (%d) }", dol[0], SX(dol[0])));
899            if (dol_count == 2) LOG_EXEC((", { %x (%d) }", dol[1], SX(dol[1])));
900            LOG_EXEC((" ]\n"));
901#endif
742902         }
743903
744904         ++pc;
r24765r24766
762922   return pc;
763923}
764924
925#if VERBOSE_EXEC
926#define RETURN_GPR(r, x) do { INT32 v = (x); LOG_EXEC(("  . reading %x (%d) from gpr_%02x\n", v, SX(v), r)); return v; } while(0)
927#define RETURN(r, x) do { INT32 v = (x); LOG_EXEC(("  . reading %x (%d) from " #r "\n", v, SX(v))); return v; } while(0)
928#define RETURN16(r, x) do { INT16 vv = (x); INT32 v = vv << 8; LOG_EXEC(("  . reading %x (%d) as %x (%d) from " #r "\n", vv, vv, v, SX(v))); return v; } while(0)
929#else
930#define RETURN_GPR(r, x) return x
931#define RETURN(r, x) return x
932#define RETURN16(r, x) return (x) << 8
933#endif
934
765935INT32 es5510_device::read_reg(UINT8 reg)
766936{
767937   if (reg < 0xc0) {
768      return gpr[reg];
938      RETURN_GPR(reg, gpr[reg]);
769939   } else {
770940      switch(reg)
771941      {
772      case 234: return ser0r;
773      case 235: return ser0l;
774      case 236: return ser1r;
775      case 237: return ser1l;
776      case 238: return ser2r;
777      case 239: return ser2l;
778      case 240: return ser3r;
779      case 241: return ser3l;
780      case 242: return (machl >>  0) & 0x00ffffff;
781      case 243: return (machl >> 24) & 0x00ffffff;
782      case 244: return dil; // DIL when reading
783      case 245: return dlength;
784      case 246: return abase;
785      case 247: return bbase;
786      case 248: return dbase;
787      case 249: return sigreg;
788      case 250: return ccr;
789      case 251: return cmr;
790      case 252: return 0x00ffffff;
791      case 253: return 0x00800000;
792      case 254: return 0x007fffff;
793      case 255: return 0x00000000;
942      case 234: RETURN16(ser0r, ser0r);
943      case 235: RETURN16(ser0l, ser0l);
944      case 236: RETURN16(ser1r, ser1r);
945      case 237: RETURN16(ser1l, ser1l);
946      case 238: RETURN16(ser2r, ser2r);
947      case 239: RETURN16(ser2l, ser2l);
948      case 240: RETURN16(ser3r, ser3r);
949      case 241: RETURN16(ser3l, ser3l);
950      case 242: /* macl */ RETURN(macl, mac_overflow ? (machl < 0 ? 0x00fffffe : 0x00000000) : (machl >>  0) & 0x00ffffff);
951      case 243: /* mach */ RETURN(mach, mac_overflow ? (machl < 0 ? 0x007fffff : 0x00800000) : (machl >> 24) & 0x00ffffff);
952      case 244: RETURN(dil, dil); // DIL when reading
953      case 245: RETURN(dlength, dlength);
954      case 246: RETURN(abase, abase);
955      case 247: RETURN(bbase, bbase);
956      case 248: RETURN(dbase, dbase);
957      case 249: RETURN(sigreg, sigreg);
958      case 250: RETURN(ccr, ccr);
959      case 251: RETURN(cmr, cmr);
960      case 252: RETURN(minus_one, 0x00ffffff);
961      case 253: RETURN(min, 0x00800000);
962      case 254: RETURN(max, 0x007fffff);
963      case 255: RETURN(zero, 0x00000000);
794964      default:
795965         // unknown SPR
796         return 0;
966         RETURN(unknown, 0);;
797967      }
798968   }
799969}
r24765r24766
826996   return n;
827997}
828998
999#if VERBOSE_EXEC
1000#define WRITE_REG(r, x) do { r = value; LOG_EXEC(("  . writing %x (%d) to " #r "\n", r, SX(r))); } while(0)
1001#define WRITE_REG16(r, x) do { r = ((value >> 8) & 0xffff); LOG_EXEC(("  . writing %x (%d) as %x (%d) to " #r "\n", value, SX(value), r, r)); } while(0)
1002#else
1003#define WRITE_REG(r, x) do { r = value; } while(0)
1004#define WRITE_REG16(r, x) do { r = ((value >> 8) & 0xffff); } while(0)
1005#endif
1006
8291007void es5510_device::write_reg(UINT8 reg, INT32 value)
8301008{
1009   #if VERBOSE_EXEC
1010   INT64 old;
1011   #endif
8311012   value &= 0x00ffffff;
8321013   if (reg < 0xc0) {
1014      LOG_EXEC(("  . writing %x (%d) to gpr_%02x\n", value, SX(value), reg));
8331015      gpr[reg] = value;
8341016   } else {
8351017      switch(reg)
8361018      {
837      case 234: ser0r = value;
1019      case 234: WRITE_REG16(ser0r, value);
8381020         break;
839      case 235: ser0l = value;
1021      case 235: WRITE_REG16(ser0l, value);
8401022         break;
841      case 236: ser1r = value;
1023      case 236: WRITE_REG16(ser1r, value);
8421024         break;
843      case 237: ser1l = value;
1025      case 237: WRITE_REG16(ser1l, value);
8441026         break;
845      case 238: ser2r = value;
1027      case 238: WRITE_REG16(ser2r, value);
8461028         break;
847      case 239: ser2l = value;
1029      case 239: WRITE_REG16(ser2l, value);
8481030         break;
849      case 240: ser3r = value;
1031      case 240: WRITE_REG16(ser3r, value);
8501032         break;
851      case 241: ser3l = value;
1033      case 241: WRITE_REG16(ser3l, value);
8521034         break;
853      case 242: machl = (machl & ~((INT64)0x00ffffff <<  0)) | (value <<  0);
1035      case 242: /* macl */ {
1036         #if VERBOSE_EXEC
1037         old = machl;
1038         #endif
1039         INT64 masked = machl & (S64(0x00ffffff) << 24);
1040         INT64 shifted = (INT64)(value & 0x00ffffff) << 0;
1041         machl = SX64(masked | shifted);
1042         #if VERBOSE_EXEC
1043         LOG_EXEC(("  . writing machl: l -> %06x => %llx -> %llx\n", value, old, machl));
1044         #endif
8541045         break;
855      case 243: machl = (machl & ~((INT64)0x00ffffff << 24)) | (value << 24);
1046      }
1047      case 243: /* mach */ {
1048         #if VERBOSE_EXEC
1049         old = machl;
1050         #endif
1051         INT64 masked = machl & (S64(0x00ffffff) << 0);
1052         INT64 shifted = (INT64)(value & 0x00ffffff) << 24;
1053         machl = SX64(masked | shifted);
1054         mac_overflow = false;
1055         #if VERBOSE_EXEC
1056         LOG_EXEC(("  . writing machl: h -> %06x => %llx -> %llx\n", value, old, machl));
1057         #endif
8561058         break;
857      case 244:
1059      }
1060      case 244: /* MEMSIZ when writing */
8581061         memshift = countLowOnes(value);
8591062         memsiz = 0x00ffffff >> (24 - memshift);
8601063         memmask = 0x00ffffff & ~memsiz;
8611064         memincrement = 1 << memshift;
1065         LOG_EXEC(("  . writing %x (%d) to memsiz => memsiz=%x, shift=%d, mask=%x, increment=%x\n", value, SX(value), memsiz, memshift, memmask, memincrement));
8621066         break;
863      case 245: dlength = value;
1067      case 245: WRITE_REG(dlength, value);
8641068         break;
865      case 246: abase = value;
1069      case 246: WRITE_REG(abase, value);
8661070         break;
867      case 247: bbase = value;
1071      case 247: WRITE_REG(bbase, value);
8681072         break;
869      case 248: dbase = value;
1073      case 248: WRITE_REG(dbase, value);
8701074         break;
871      case 249: sigreg = (value != 0);
1075      case 249: WRITE_REG(sigreg, (value != 0));
8721076         break;
873      case 250: ccr = (value >> 16) & FLAG_MASK;
1077      case 250: WRITE_REG(ccr, (value >> 16) & FLAG_MASK);
8741078         break;
875      case 251: cmr = (value >> 16) & (FLAG_MASK | FLAG_NOT);
1079      case 251: WRITE_REG(cmr, (value >> 16) & (FLAG_MASK | FLAG_NOT));
8761080         break;
877      case 252: // no-op
1081      case 252: LOG_EXEC((". not writing %x (%d) to minus_one\n", value, SX(value))); // no-op
8781082         break;
879      case 253: // no-op
1083      case 253: LOG_EXEC((". not writing %x (%d) to min\n", value, SX(value))); // no-op
8801084         break;
881      case 254: // no-op
1085      case 254: LOG_EXEC((". not writing %x (%d) to max\n", value, SX(value))); // no-op
8821086         break;
883      case 255: // no-op
1087      case 255: LOG_EXEC((". not writing %x (%d) to zero\n", value, SX(value))); // no-op
8841088         break;
8851089      default: // unknown register
8861090         break;
r24765r24766
8891093}
8901094
8911095void es5510_device::write_to_dol(INT32 value) {
1096#if VERBOSE_EXEC
1097   LOG_EXEC((". writing %x (%d) to DOL: [ ", value, value));
1098   if (dol_count >= 1) LOG_EXEC(("{ %x (%d) }", dol[0], SX(dol[0])));
1099   if (dol_count == 2) LOG_EXEC((", { %x (%d) }", dol[1], SX(dol[1])));
1100   LOG_EXEC((" ] -> [ "));
1101#endif
8921102   if (dol_count >= 2) {
8931103      dol[0] = dol[1];
8941104      dol[1] = value;
8951105   } else {
8961106      dol[dol_count++] = value;
8971107   }
1108#if VERBOSE_EXEC
1109   LOG_EXEC(("{%x (%d)}", dol[0], SX(dol[0])));
1110   if (dol_count == 2) LOG_EXEC((", {%x (%d)}", dol[1], SX(dol[1])));
1111   LOG_EXEC((" ]\n"));
1112#endif
8981113}
8991114
9001115void es5510_device::alu_operation_end() {
9011116   // Handle the END instruction separately
902   LOG(("ES5510: END\n"));
1117   LOG_EXEC(("ES5510: END\n"));
9031118   // sample the HALT line
9041119   if (halt_asserted) {
9051120      // halt
r24765r24766
9111126   if (dbase < 0) {
9121127      dbase = dlength;
9131128   }
1129   // Possibly reset the PC
1130   if (state == STATE_RUNNING) {
1131      pc = 0;
1132   }
1133
1134#if VERBOSE_EXEC
1135   // update the verbose-execution counter.
1136   exec_cc = (exec_cc + 1) % 10000;
1137#endif
9141138}
9151139
9161140INT32 es5510_device::alu_operation(UINT8 op, INT32 a, INT32 b, UINT8 &flags) {
1141   INT32 tmp;
9171142   switch(op) {
9181143   case 0x0: // ADD
919      return saturate(add(a, b, flags), flags);
1144      tmp = add(a, b, flags);
1145      return saturate(tmp, flags);
9201146
9211147   case 0x1: // SUB
922      return saturate(add(a, negate(b), flags), flags);
1148      tmp = add(a, negate(b), flags);
1149      return saturate(tmp, flags);
9231150
9241151   case 0x2: // ADDU
9251152      return add(a, b, flags);
r24765r24766
9541181      clearFlag(flags, FLAG_N);
9551182      bool isNegative = (a & 0x00800000) != 0;
9561183      setFlagTo(flags, FLAG_C, isNegative);
957      if (isNegative) {
958         a = (a ^ 0x00ffffff) + 1;
959      }
960      return a;
1184      return isNegative ? negate(a) : a;
9611185   }
9621186
9631187   case 0x9: // MOV
trunk/src/mess/drivers/esq5505.c
r24765r24766
143143   va_end(arg);
144144}
145145
146#define PUMP_DETECT_SILENCE 1
146#define PUMP_DETECT_SILENCE 0
147147#define PUMP_TRACK_SAMPLES 0
148#define PUMP_FAKE_ESP_PROCESSING 1
148#define PUMP_FAKE_ESP_PROCESSING 0
149#define PUMP_REPLACE_ESP_PROGRAM 0
150
149151class esq_5505_5510_pump : public device_t,
150152   public device_sound_interface
151153{
r24765r24766
158160      m_esp_halted = esp_halted;
159161      logerror("ESP-halted -> %d\n", m_esp_halted);
160162      if (!esp_halted) {
161         m_esp->list_program(print_to_stderr);
163
164#if PUMP_REPLACE_ESP_PROGRAM
165         m_esp->write_reg(245, 0x1d0f << 8); // dlength = 0x3fff, 16-sample delay
166         
167         int pc = 0;
168         for (pc = 0; pc < 0xc0; pc++) {
169            m_esp->write_reg(pc, 0);
170         }
171         pc = 0;
172         // replace the ESP program with a simple summing & single-sample delay
173         m_esp->_instr(pc++) = 0xffffeaa09000; // MOV SER0R > grp_a0
174         m_esp->_instr(pc++) = 0xffffeba00000; // ADD SER0L, gpr_a0 > gpr_a0
175         m_esp->_instr(pc++) = 0xffffeca00000; // ADD SER1R, gpr_a0 > gpr_a0
176         m_esp->_instr(pc++) = 0xffffeda00000; // ADD SER1L, gpr_a0 > gpr_a0
177         m_esp->_instr(pc++) = 0xffffeea00000; // ADD SER2R, gpr_a0 > gpr_a0
178
179         m_esp->_instr(pc  ) = 0xffffefa00000; // ADD SER2L, gpr_a0 > gpr_a0; prepare to read from delay 2 instructions from now, offset = 0
180            m_esp->write_reg(pc++, 0); //offset into delay
181
182         m_esp->_instr(pc  ) = 0xffffa0a09508; // MOV gpr_a0 > delay + offset
183         m_esp->write_reg(pc++, 1 << 8); // offset into delay - -1 samples
184
185         m_esp->_instr(pc++) = 0xffff00a19928; // MOV DIL > gpr_a1; read Delay and dump FIFO (so that the value gets written)
186
187         m_esp->_instr(pc++) = 0xffffa1f09000; // MOV gpr_a1 > SER3R
188         m_esp->_instr(pc++) = 0xffffa1f19000; // MOV gpr_a1 > SER3L
189
190         m_esp->_instr(pc++) = 0xffffffff0000; // NO-OP
191         m_esp->_instr(pc++) = 0xffffffff0000; // NO-OP
192         m_esp->_instr(pc++) = 0xfffffffff000; // END
193
194         while (pc < 160) {
195            m_esp->_instr(pc++) = 0xffffffffffff; // no-op
196         }
197#endif
198
199         // m_esp->list_program(print_to_stderr);
162200      }
163201   }
164202   bool get_esp_halted() {
r24765r24766
174212   // sound stream update overrides
175213   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
176214
177   // timer callback overridea
215   // timer callback overrides
178216   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
179217
180218private:
r24765r24766
209247   osd_ticks_t last_ticks;
210248   osd_ticks_t next_report_ticks;
211249#endif
250
251#if !PUMP_FAKE_ESP_PROCESSING && PUMP_REPLACE_ESP_PROGRAM
252   INT16 e[0x4000];
253   int ei;
254#endif
212255};
213256
214257const device_type ESQ_5505_5510_PUMP = &device_creator<esq_5505_5510_pump>;
r24765r24766
222265
223266void esq_5505_5510_pump::device_start()
224267{
225   INT64 nsec_per_sample = 100 * 16 * 21;
226   attotime sample_time(0, 1000000000 * nsec_per_sample);
227   attotime initial_delay(0, 0);
228268   logerror("Clock = %d\n", clock());
269
229270   m_stream = machine().sound().stream_alloc(*this, 8, 2, clock(), this);
230271   m_timer = timer_alloc(0);
231   m_timer->adjust(initial_delay, 0, sample_time);
232   m_timer->enable(true);
272   m_timer->enable(false);
233273
234274#if PUMP_DETECT_SILENCE
235275   silent_for = 500;
r24765r24766
244284   last_ticks = osd_ticks();
245285   next_report_ticks = last_ticks + osd_ticks_per_second();
246286#endif
287
288#if !PUMP_FAKE_ESP_PROCESSING && PUMP_REPLACE_ESP_PROGRAM
289   memset(e, 0, 0x4000 * sizeof(e[0]));
290   ei = 0;
291#endif
247292}
248293
249294void esq_5505_5510_pump::device_stop()
r24765r24766
253298
254299void esq_5505_5510_pump::device_reset()
255300{
301   INT64 nsec_per_sample = 100 * 16 * 21;
302   attotime sample_time(0, 1000000000 * nsec_per_sample);
303   attotime initial_delay(0, 0);
304
305   m_timer->adjust(initial_delay, 0, sample_time);
306   m_timer->enable(true);
256307}
257308
258309void esq_5505_5510_pump::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
r24765r24766
264315   stream_sample_t *left = outputs[0], *right = outputs[1];
265316   for (int i = 0; i < samples; i++)
266317   {
267      // anything for the 'aux' output?
268      INT32 l = inputs[0][i] >> 4;
269      INT32 r = inputs[1][i] >> 4;
318       // anything for the 'aux' output?
319      INT16 l = inputs[0][i] >> 4;
320      INT16 r = inputs[1][i] >> 4;
270321
271322      // push the samples into the ESP
272323      m_esp->ser_w(0, inputs[2][i] >> 4);
r24765r24766
276327      m_esp->ser_w(4, inputs[6][i] >> 4);
277328      m_esp->ser_w(5, inputs[7][i] >> 4);
278329
279      m_esp->ser_w(6, 0);
280      m_esp->ser_w(7, 0);
281
282330#if PUMP_FAKE_ESP_PROCESSING
283331      m_esp->ser_w(6, m_esp->ser_r(0) + m_esp->ser_r(2) + m_esp->ser_r(4));
284332      m_esp->ser_w(7, m_esp->ser_r(1) + m_esp->ser_r(3) + m_esp->ser_r(5));
r24765r24766
294342#endif
295343
296344      // read the processed result from the ESP and add to the saved AUX data
297      l += m_esp->ser_r(6);
298      r += m_esp->ser_r(7);
345      INT16 ll = m_esp->ser_r(6);
346      INT16 rr = m_esp->ser_r(7);
347      l += ll;
348      r += rr;
299349
350#if !PUMP_FAKE_ESP_PROCESSING && PUMP_REPLACE_ESP_PROGRAM
351      // if we're processing the fake program through the ESP, the result should just be that of adding the inputs
352      INT32 el = (inputs[2][i]) + (inputs[4][i]) + (inputs[6][i]);
353      INT32 er = (inputs[3][i]) + (inputs[5][i]) + (inputs[7][i]);
354      INT32 e_next = el + er;
355      e[(ei + 0x1d0f) % 0x4000] = e_next;
356     
357      if (l != e[ei]) {
358         fprintf(stderr, "expected (%d) but have (%d)\n", e[ei], l);
359      }
360      ei = (ei + 1) % 0x4000;
361#endif
362
300363      // write the combined data to the output
301364      *left++  = l;
302365      *right++ = r;
r24765r24766
876939   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
877940
878941   MCFG_SOUND_ADD("pump", ESQ_5505_5510_PUMP, XTAL_10MHz / (16 * 21))
879   MCFG_SOUND_ROUTE(0, "lspeaker", 2.0)
880   MCFG_SOUND_ROUTE(1, "rspeaker", 2.0)
942   MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
943   MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
881944
882945   MCFG_SOUND_ADD("otis", ES5505, XTAL_10MHz)
883946   MCFG_SOUND_CONFIG(es5505_config)
r24765r24766
930993   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
931994
932995   MCFG_SOUND_ADD("pump", ESQ_5505_5510_PUMP, XTAL_30_4761MHz / (2 * 16 * 32))
933   MCFG_SOUND_ROUTE(0, "lspeaker", 2.0)
934   MCFG_SOUND_ROUTE(1, "rspeaker", 2.0)
996   MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
997   MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
935998
936999   MCFG_SOUND_ADD("otis", ES5505, XTAL_30_4761MHz / 2)
9371000   MCFG_SOUND_CONFIG(es5505_config)

Previous 199869 Revisions Next


© 1997-2024 The MAME Team