Previous 15994 Revisions Next

r9893 Sunday 2nd January, 2011 at 22:14:20 UTC by R. Belmont
SNES: use emulated uPD7725 for DSP-n games. DSP-1 and -2 work, -3 is questionable and -4 doesn't work yet. Also submitted to MAME. [byuu, R. Belmont]
[src/emu/cpu]cpu.mak
[src/emu/cpu/upd7725]dasm7725.c* upd7725.c* upd7725.h*
[src/mame/includes]snes.h
[src/mame/machine]snes.c
[src/mess]mess.mak
[src/mess/drivers]snes.c
[src/mess/machine]snescart.c

src/mame/machine/snes.c
r9892r9893
1919#include "emu.h"
2020#include "cpu/superfx/superfx.h"
2121#include "cpu/g65816/g65816.h"
22#include "cpu/upd7725/upd7725.h"
2223#include "includes/snes.h"
2324#include "audio/snes_snd.h"
2425
r9892r9893
3637struct snes_cart_info snes_cart;
3738
3839// add-on chip emulators
39#include "machine/snesdsp1.c"
40#include "machine/snesdsp2.c"
41#include "machine/snesdsp3.c"
42#include "machine/snesdsp4.c"
4340#include "machine/snesobc1.c"
4441#include "machine/snescx4.c"
4542#include "machine/snesrtc.c"
r9892r9893
284281
285282/*************************************
286283
284    DSP I/O
285
286*************************************/
287static UINT8 dsp_get_sr(running_machine *machine)
288{
289   upd7725_device *upd7725 = machine->device<upd7725_device>("dsp");
290
291   return upd7725->snesdsp_read(false);
292}
293
294static UINT8 dsp_get_dr(running_machine *machine)
295{
296   upd7725_device *upd7725 = machine->device<upd7725_device>("dsp");
297
298   return upd7725->snesdsp_read(true);
299}
300
301static void dsp_set_sr(running_machine *machine, UINT8 data)
302{
303   upd7725_device *upd7725 = machine->device<upd7725_device>("dsp");
304
305   upd7725->snesdsp_write(false, data);
306}
307
308static void dsp_set_dr(running_machine *machine, UINT8 data)
309{
310   upd7725_device *upd7725 = machine->device<upd7725_device>("dsp");
311
312   upd7725->snesdsp_write(true, data);
313}
314
315/*************************************
316
287317    Input Handlers
288318
289319*************************************/
r9892r9893
938968      else if (state->has_addon_chip == HAS_OBC1)
939969         value = obc1_read(space, offset);
940970      else if ((state->cart[0].mode == SNES_MODE_21) && (state->has_addon_chip == HAS_DSP1) && (offset < 0x100000))
941         value = (address < 0x7000) ? dsp1_get_dr() : dsp1_get_sr();
971         value = (address < 0x7000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine);
942972      else if (state->has_addon_chip == HAS_CX4)
943973         value = CX4_read(address - 0x6000);
944974      else if (state->has_addon_chip == HAS_SPC7110 || state->has_addon_chip == HAS_SPC7110_RTC)
r9892r9893
953983      }
954984   }
955985   else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP1) && (offset >= 0x200000))
956      value = (address < 0xc000) ? dsp1_get_dr() : dsp1_get_sr();
986      value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine);
957987   else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP2) && (offset >= 0x200000))
958      value = (address < 0xc000) ? dsp2_dr_read() : dsp2_sr_read();
988      value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine);
959989   else if ((state->has_addon_chip == HAS_DSP3) && (offset >= 0x200000))
960      value = dsp3_read(address);
990      value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine);
961991   else
962992      value = snes_ram[offset];
963993
r9892r9893
10171047   }
10181048   /* some dsp1 games use these banks 0x30 to 0x3f at address 0x8000 */
10191049   else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP1))
1020      value = (address < 0xc000) ? dsp1_get_dr() : dsp1_get_sr();
1050      value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine);
10211051   else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP2))
1022      value = (address < 0xc000) ? dsp2_dr_read() : dsp2_sr_read();
1052      value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine);
10231053   else if (state->has_addon_chip == HAS_DSP3)
1024      value = dsp3_read(address);
1054      value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine);
10251055   else if (state->has_addon_chip == HAS_DSP4)
1026      value = (address < 0xc000) ? dsp4_read() : 0x80;
1056      value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine);
10271057   else
10281058      value = snes_ram[0x300000 + offset];
10291059
r9892r9893
11001130         value = snes_ram[0x600000 + offset];
11011131      /* some other dsp1 games use these banks 0x60 to 0x6f at address 0x0000 */
11021132      else if (state->has_addon_chip == HAS_DSP1)
1103         value = (address >= 0x4000) ? dsp1_get_sr() : dsp1_get_dr();
1133         value = (address >= 0x4000) ? dsp_get_sr(space->machine) : dsp_get_dr(space->machine);
11041134      else
11051135      {
11061136         logerror("(PC=%06x) snes_r_bank4: Unmapped external chip read: %04x\n",cpu_get_pc(space->cpu),address);
r9892r9893
11881218      }
11891219   }
11901220   else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP1) && (offset >= 0x200000))
1191      value = (address < 0xc000) ? dsp1_get_dr() : dsp1_get_sr();
1221      value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine);
11921222   else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP2) && (offset >= 0x200000))
1193      value = (address < 0xc000) ? dsp2_dr_read() : dsp2_sr_read();
1223      value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine);
11941224   else if ((state->has_addon_chip == HAS_DSP3) && (offset >= 0x200000))
1195      value = dsp3_read(address);
1225      value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine);
11961226   else if ((state->has_addon_chip == HAS_DSP4) && (offset >= 0x300000))
1197      value = (address < 0xc000) ? dsp4_read() : 0x80;
1227      value = (address < 0xc000) ? dsp_get_dr(space->machine) : dsp_get_sr(space->machine);
11981228   else
11991229      value = snes_ram[0x800000 + offset];
12001230
r9892r9893
12841314      else if (state->has_addon_chip == HAS_OBC1)
12851315         obc1_write(space, offset, data);
12861316      else if ((state->cart[0].mode == SNES_MODE_21) && (state->has_addon_chip == HAS_DSP1) && (offset < 0x100000))
1287         dsp1_set_dr(data);
1317         dsp_set_dr(space->machine, data);
12881318      else if (state->has_addon_chip == HAS_CX4)
12891319         CX4_write(space->machine, address - 0x6000, data);
12901320      else if (state->has_addon_chip == HAS_SPC7110 || state->has_addon_chip == HAS_SPC7110_RTC)
r9892r9893
12961326         logerror("snes_w_bank1: Attempt to write to reserved address: %x = %02x\n", offset, data);
12971327   }
12981328   else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP1) && (offset >= 0x200000))
1299      dsp1_set_dr(data);
1329      dsp_set_dr(space->machine, data);
13001330   else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP2) && (offset >= 0x200000))
13011331   {
13021332      if (address < 0xc000)
1303         dsp2_dr_write(data);
1333         dsp_set_dr(space->machine, data);
13041334      else
1305         dsp2_sr_write(data);
1335         dsp_set_sr(space->machine, data);
13061336   }
13071337   else if ((state->has_addon_chip == HAS_DSP3) && (offset >= 0x200000))
1308      dsp3_write(address, data);
1338      if (address < 0xc000)
1339         dsp_set_dr(space->machine, data);
1340      else
1341         dsp_set_sr(space->machine, data);
13091342   else
13101343      logerror( "(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(space->cpu),offset );
13111344
r9892r9893
13541387   }
13551388   /* some dsp1 games use these banks 0x30 to 0x3f at address 0x8000 */
13561389   else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP1))
1357      dsp1_set_dr(data);
1390      dsp_set_dr(space->machine, data);
13581391   else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP2))
13591392   {
13601393      if (address < 0xc000)
1361         dsp2_dr_write(data);
1394         dsp_set_dr(space->machine, data);
13621395      else
1363         dsp2_sr_write(data);
1396         dsp_set_sr(space->machine, data);
13641397   }
13651398   else if (state->has_addon_chip == HAS_DSP3)
1366      dsp3_write(address, data);
1367   else if ((state->has_addon_chip == HAS_DSP4) && (address < 0xc000))
1368      dsp4_write(data);
1399      if (address < 0xc000)
1400         dsp_set_dr(space->machine, data);
1401      else
1402         dsp_set_sr(space->machine, data);
1403   else if (state->has_addon_chip == HAS_DSP4)
1404      if (address < 0xc000)
1405         dsp_set_dr(space->machine, data);
1406      else
1407         dsp_set_sr(space->machine, data);
13691408   else
13701409      logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(space->cpu),offset + 0x300000);
13711410
r9892r9893
13901429      if (address >= 0x8000)
13911430         logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(space->cpu),offset + 0x600000);
13921431      else if (state->has_addon_chip == HAS_DSP1)
1393         dsp1_set_dr(data);
1432         dsp_set_dr(space->machine, data);
13941433      else
13951434         logerror("snes_w_bank4: Attempt to write to reserved address: %X = %02x\n", offset + 0x600000, data);
13961435   }
r9892r9893
14591498      }
14601499   }
14611500   else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP1) && (offset >= 0x200000))
1462      dsp1_set_dr(data);
1501      dsp_set_dr(space->machine, data);
14631502   else if ((state->cart[0].mode == SNES_MODE_20) && (state->has_addon_chip == HAS_DSP2) && (offset >= 0x200000))
14641503   {
14651504      if (address < 0xc000)
1466         dsp2_dr_write(data);
1505         dsp_set_dr(space->machine, data);
14671506      else
1468         dsp2_sr_write(data);
1507         dsp_set_sr(space->machine, data);
14691508   }
14701509   else if ((state->has_addon_chip == HAS_DSP3) && (offset >= 0x200000))
1471      dsp3_write(address, data);
1472   else if ((state->has_addon_chip == HAS_DSP4) && (offset >= 0x300000) && (address < 0xc000))
1473      dsp4_write(data);
1510      if (address < 0xc000)
1511         dsp_set_dr(space->machine, data);
1512      else
1513         dsp_set_sr(space->machine, data);
1514   else if ((state->has_addon_chip == HAS_DSP4) && (offset >= 0x300000))
1515      if (address < 0xc000)
1516         dsp_set_dr(space->machine, data);
1517      else
1518         dsp_set_sr(space->machine, data);
14741519   else
14751520      logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(space->cpu),offset + 0x800000);
14761521
r9892r9893
16631708   snes_ram[WRIO] = 0xff;
16641709   snes_ram[VMAIN] = 0x80;
16651710
1711   // assume no DSP and halt it...
1712   cputag_set_input_line(machine, "dsp", INPUT_LINE_RESET, ASSERT_LINE);
1713
16661714   switch (state->has_addon_chip)
16671715   {
16681716      case HAS_DSP1:
1669         dsp1_init(machine);
1670         break;
1671
16721717      case HAS_DSP2:
1673         dsp2_init(machine);
1674         break;
1675
16761718      case HAS_DSP3:
1677         dsp3_init(machine);
1678         break;
1679
16801719      case HAS_DSP4:
1681         dsp4_init(machine);
1720         // we do have a DSP, let 'er rip
1721         cputag_set_input_line(machine, "dsp", INPUT_LINE_RESET, CLEAR_LINE);
16821722         break;
16831723
16841724      case HAS_RTC:
src/mame/includes/snes.h
r9892r9893
2929
3030#define SNES_LAYER_DEBUG  0
3131
32#define SNES_DSP1B_OFFSET (0x0000)
33#define SNES_DSP1_OFFSET  (0x3000)
34#define SNES_DSP2_OFFSET  (0x6000)
35#define SNES_DSP3_OFFSET  (0x9000)
36#define SNES_DSP4_OFFSET  (0xc000)
37
3238/* Debug definitions */
3339#ifdef MAME_DEBUG
3440/* #define SNES_DBG_GENERAL*/      /* Display general debug info */
src/emu/cpu/cpu.mak
r9892r9893
12351235                  $(CPUSRC)/v810/v810.h
12361236
12371237
1238#-------------------------------------------------
1239# NEC uPD7725
1240#-------------------------------------------------
12381241
1242ifneq ($(filter UPD7725,$(CPUS)),)
1243OBJDIRS += $(CPUOBJ)/upd7725
1244CPUOBJS += $(CPUOBJ)/upd7725/upd7725.o
1245DASMOBJS += $(CPUOBJ)/upd7725/dasm7725.o
1246endif
1247
1248$(CPUOBJ)/upd7725/upd7725.o:   $(CPUSRC)/upd7725/upd7725.c \
1249                        $(CPUSRC)/upd7725/upd7725.h
1250
1251
12391252#-------------------------------------------------
12401253# NEC uPD7810 series
12411254#-------------------------------------------------
src/emu/cpu/upd7725/upd7725.h
r0r9893
1/***************************************************************************
2
3    upd7725.h
4
5    Core implementation for the portable NEC uPD7725 emulator
6
7****************************************************************************/
8
9#pragma once
10
11#ifndef __UPD7725_H__
12#define __UPD7725_H__
13
14//**************************************************************************
15//  TYPE DEFINITIONS
16//**************************************************************************
17
18// ======================> upd7725_device_config
19
20class upd7725_device_config :   public cpu_device_config
21{
22   friend class upd7725_device;
23
24   // construction/destruction
25   upd7725_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
26
27public:
28   // allocators
29   static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
30   virtual device_t *alloc_device(running_machine &machine) const;
31
32protected:
33   // device_config_execute_interface overrides
34   virtual UINT32 execute_min_cycles() const;
35   virtual UINT32 execute_max_cycles() const;
36   virtual UINT32 execute_input_lines() const;
37
38   // device_config_memory_interface overrides
39   virtual const address_space_config *memory_space_config(int spacenum = 0) const;
40
41   // device_config_disasm_interface overrides
42   virtual UINT32 disasm_min_opcode_bytes() const;
43   virtual UINT32 disasm_max_opcode_bytes() const;
44
45   // inline data
46   const address_space_config m_program_config, m_data_config;
47};
48
49// ======================> upd7725_device
50
51class upd7725_device : public cpu_device
52{
53   friend class upd7725_device_config;
54
55   // construction/destruction
56   upd7725_device(running_machine &_machine, const upd7725_device_config &config);
57
58public:
59   UINT8 snesdsp_read(bool mode);
60   void snesdsp_write(bool mode, UINT8 data);
61
62protected:
63   // device-level overrides
64   virtual void device_start();
65   virtual void device_reset();
66
67   // device_execute_interface overrides
68   virtual void execute_run();
69
70   // device_state_interface overrides
71   virtual void state_import(const device_state_entry &entry);
72   virtual void state_export(const device_state_entry &entry);
73   virtual void state_string_export(const device_state_entry &entry, astring &string);
74
75   // device_disasm_interface overrides
76   virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
77
78private:
79   struct Flag
80   {
81      bool s1, s0, c, z, ov1, ov0;
82   
83      inline operator unsigned() const
84      {
85         return (s1 << 5) + (s0 << 4) + (c << 3) + (z << 2) + (ov1 << 1) + (ov0 << 0);
86      }
87
88      inline unsigned operator=(unsigned d)
89      {
90         s1 = d & 0x20; s0 = d & 0x10; c = d & 0x08; z = d & 0x04; ov1 = d & 0x02; ov0 = d & 0x01;
91         return d;
92      }
93   };
94
95   struct Status
96   {
97      bool rqm, usf1, usf0, drs, dma, drc, soc, sic, ei, p1, p0;
98     
99      inline operator unsigned() const
100      {
101         return (rqm << 15) + (usf1 << 14) + (usf0 << 13) + (drs << 12)
102            + (dma << 11) + (drc  << 10) + (soc  <<  9) + (sic <<  8)
103            + (ei  <<  7) + (p1   <<  1) + (p0   <<  0);
104      }
105     
106      inline unsigned operator=(unsigned d)
107      {
108         rqm = d & 0x8000; usf1 = d & 0x4000; usf0 = d & 0x2000; drs = d & 0x1000;
109         dma = d & 0x0800; drc  = d & 0x0400; soc  = d & 0x0200; sic = d & 0x0100;
110         ei  = d & 0x0080; p1   = d & 0x0002; p0   = d & 0x0001;
111         return d;
112      }
113   };
114
115   struct Regs
116   {
117      UINT16 pc;        //program counter
118      UINT16 stack[4];  //LIFO
119      UINT16 rp;        //ROM pointer
120      UINT8  dp;        //data pointer
121      INT16  k;
122      INT16  l;
123      INT16  m;
124      INT16  n;
125      INT16  a;         //accumulator
126      INT16  b;         //accumulator
127      Flag  flaga;
128      Flag  flagb;
129      UINT16 tr;        //temporary register
130      UINT16 trb;       //temporary register
131      Status sr;        //status register
132      UINT16 dr;        //data register
133      bool siack;
134      bool soack;
135      UINT16 idb;
136   } regs;
137
138  void exec_op(UINT32 opcode);
139  void exec_rt(UINT32 opcode);
140  void exec_jp(UINT32 opcode);
141  void exec_ld(UINT32 opcode);
142
143  void stack_push();
144  void stack_pull();
145
146  UINT16 dataRAM[256];
147
148  int m_icount;
149
150  address_space *m_program, *m_data;
151  direct_read_data *m_direct;
152};
153
154// device type definition
155extern const device_type UPD7725;
156
157//**************************************************************************
158//  ENUMERATIONS
159//**************************************************************************
160
161// registers
162enum
163{
164   UPD7725_PC = 1,
165   UPD7725_RP,
166   UPD7725_DP,
167   UPD7725_K,
168   UPD7725_L,
169   UPD7725_M,
170   UPD7725_N,
171   UPD7725_A,
172   UPD7725_B,
173   UPD7725_FLAGA,
174   UPD7725_FLAGB,
175   UPD7725_SR,
176   UPD7725_DR
177};
178
179#endif // UPD7725
src/emu/cpu/upd7725/dasm7725.c
r0r9893
1/***************************************************************************
2
3    dasm7725.c
4    Disassembler for the portable uPD7725 emulator.
5    Written by byuu
6    MAME conversion by R. Belmont
7
8***************************************************************************/
9
10#include "emu.h"
11#include "upd7725.h"
12
13CPU_DISASSEMBLE( upd7725 )
14{
15  static char output[256];
16  UINT32 opcode = oprom[2] | (oprom[1] << 8) | (oprom[0] << 16);
17  UINT32 type = (opcode >> 22);
18
19//  printf("dasm: PC %x opcode %08x\n", pc, opcode);
20
21  memset(output, 0, sizeof(output));
22
23  if(type == 0 || type == 1) {  //OP,RT
24     UINT8 pselect = (opcode >> 20)&0x3;  //P select
25     UINT8 alu     = (opcode >> 16)&0xf;  //ALU operation mode
26     UINT8 asl     = (opcode >> 15)&0x1;  //accumulator select
27     UINT8 dpl     = (opcode >> 13)&0x3;  //DP low modify
28     UINT8 dphm    = (opcode >>  9)&0xf;  //DP high XOR modify
29     UINT8 rpdcr   = (opcode >>  8)&0x1;  //RP decrement
30     UINT8 src     = (opcode >>  4)&0xf;  //move source
31     UINT8 dst     = (opcode >>  0)&0xf;  //move destination
32
33    switch(alu) {
34      case  0: strcat(output, "nop  "); break;
35      case  1: strcat(output, "or   "); break;
36      case  2: strcat(output, "and  "); break;
37      case  3: strcat(output, "xor  "); break;
38      case  4: strcat(output, "sub  "); break;
39      case  5: strcat(output, "add  "); break;
40      case  6: strcat(output, "sbb  "); break;
41      case  7: strcat(output, "adc  "); break;
42      case  8: strcat(output, "dec  "); break;
43      case  9: strcat(output, "inc  "); break;
44      case 10: strcat(output, "cmp  "); break;
45      case 11: strcat(output, "shr1 "); break;
46      case 12: strcat(output, "shl1 "); break;
47      case 13: strcat(output, "shl2 "); break;
48      case 14: strcat(output, "shl4 "); break;
49      case 15: strcat(output, "xchg "); break;
50    }
51
52    if(alu < 8) {
53      switch(pselect) {
54        case 0: strcat(output, "ram,"); break;
55        case 1: strcat(output, "idb,"); break;
56        case 2: strcat(output, "m,"); break;
57        case 3: strcat(output, "n,"); break;
58      }
59    }
60
61    switch(asl) {
62      case 0: strcat(output, "a"); break;
63      case 1: strcat(output, "b"); break;
64    }
65
66    if(dst) {
67      strcat(output, " | mov ");
68
69      switch(src) {
70        case  0: strcat(output, "trb,"); break;
71        case  1: strcat(output, "a,"); break;
72        case  2: strcat(output, "b,"); break;
73        case  3: strcat(output, "tr,"); break;
74        case  4: strcat(output, "dp,"); break;
75        case  5: strcat(output, "rp,"); break;
76        case  6: strcat(output, "ro,"); break;
77        case  7: strcat(output, "sgn,"); break;
78        case  8: strcat(output, "dr,"); break;
79        case  9: strcat(output, "drnf,"); break;
80        case 10: strcat(output, "sr,"); break;
81        case 11: strcat(output, "sim,"); break;
82        case 12: strcat(output, "sil,"); break;
83        case 13: strcat(output, "k,"); break;
84        case 14: strcat(output, "l,"); break;
85        case 15: strcat(output, "mem,"); break;
86      }
87
88      switch(dst) {
89        case  0: strcat(output, "non"); break;
90        case  1: strcat(output, "a"); break;
91        case  2: strcat(output, "b"); break;
92        case  3: strcat(output, "tr"); break;
93        case  4: strcat(output, "dp"); break;
94        case  5: strcat(output, "rp"); break;
95        case  6: strcat(output, "dr"); break;
96        case  7: strcat(output, "sr"); break;
97        case  8: strcat(output, "sol"); break;
98        case  9: strcat(output, "som"); break;
99        case 10: strcat(output, "k"); break;
100        case 11: strcat(output, "klr"); break;
101        case 12: strcat(output, "klm"); break;
102        case 13: strcat(output, "l"); break;
103        case 14: strcat(output, "trb"); break;
104        case 15: strcat(output, "mem"); break;
105      }
106    }
107
108    if(dpl) {
109      switch(dpl) {
110        case 0: strcat(output, " | dpnop"); break;
111        case 1: strcat(output, " | dpinc"); break;
112        case 2: strcat(output, " | dpdec"); break;
113        case 3: strcat(output, " | dpclr"); break;
114      }
115    }
116
117    if(dphm) {
118      switch(dphm) {
119        case  0: strcat(output, " | m0"); break;
120        case  1: strcat(output, " | m1"); break;
121        case  2: strcat(output, " | m2"); break;
122        case  3: strcat(output, " | m3"); break;
123        case  4: strcat(output, " | m4"); break;
124        case  5: strcat(output, " | m5"); break;
125        case  6: strcat(output, " | m6"); break;
126        case  7: strcat(output, " | m7"); break;
127        case  8: strcat(output, " | m8"); break;
128        case  9: strcat(output, " | m9"); break;
129        case 10: strcat(output, " | ma"); break;
130        case 11: strcat(output, " | mb"); break;
131        case 12: strcat(output, " | mc"); break;
132        case 13: strcat(output, " | md"); break;
133        case 14: strcat(output, " | me"); break;
134        case 15: strcat(output, " | mf"); break;
135      }
136    }
137
138    if(rpdcr == 1) {
139     strcat(output, " | rpdec");
140    }
141
142    if(type == 1) {
143     strcat(output, " | ret");
144    }
145  }
146
147  if(type == 2) {  //JP
148     UINT16 brch = (opcode >> 13) & 0x1ff;  //branch
149     UINT16 na  = (opcode >>  2) & 0x7ff;  //next address
150
151    switch(brch) {
152      case 0x080: strcat(output, "jnca "); break;
153      case 0x082: strcat(output, "jca "); break;
154      case 0x084: strcat(output, "jncb "); break;
155      case 0x086: strcat(output, "jcb "); break;
156      case 0x088: strcat(output, "jnza "); break;
157      case 0x08a: strcat(output, "jza "); break;
158      case 0x08c: strcat(output, "jnzb "); break;
159      case 0x08e: strcat(output, "jzb "); break;
160      case 0x090: strcat(output, "jnova0 "); break;
161      case 0x092: strcat(output, "jova0 "); break;
162      case 0x094: strcat(output, "jnovb0 "); break;
163      case 0x096: strcat(output, "jovb0 "); break;
164      case 0x098: strcat(output, "jnova1 "); break;
165      case 0x09a: strcat(output, "jova1 "); break;
166      case 0x09c: strcat(output, "jnovb1 "); break;
167      case 0x09e: strcat(output, "jovb1 "); break;
168      case 0x0a0: strcat(output, "jnsa0 "); break;
169      case 0x0a2: strcat(output, "jsa0 "); break;
170      case 0x0a4: strcat(output, "jnsb0 "); break;
171      case 0x0a6: strcat(output, "jsb0 "); break;
172      case 0x0a8: strcat(output, "jnsa1 "); break;
173      case 0x0aa: strcat(output, "jsa1 "); break;
174      case 0x0ac: strcat(output, "jnsb1 "); break;
175      case 0x0ae: strcat(output, "jsb1 "); break;
176      case 0x0b0: strcat(output, "jdpl0 "); break;
177      case 0x0b1: strcat(output, "jdpln0 "); break;
178      case 0x0b2: strcat(output, "jdplf "); break;
179      case 0x0b3: strcat(output, "jdplnf "); break;
180      case 0x0b4: strcat(output, "jnsiak "); break;
181      case 0x0b6: strcat(output, "jsiak "); break;
182      case 0x0b8: strcat(output, "jnsoak "); break;
183      case 0x0ba: strcat(output, "jsoak "); break;
184      case 0x0bc: strcat(output, "jnrqm "); break;
185      case 0x0be: strcat(output, "jrqm "); break;
186      case 0x100: strcat(output, "jmp "); break;
187      case 0x140: strcat(output, "call "); break;
188      default:    strcat(output, "??????  "); break;
189    }
190
191   char temp[16];
192
193   sprintf(temp, "$%x", na);
194   strcat(output, temp);
195  }
196
197  if(type == 3) {  //LD
198   strcat(output, "ld ");
199    UINT16 id = opcode >> 6;
200   UINT8 dst = (opcode >> 0) & 0xf;  //destination
201
202   char temp[16];
203   sprintf(temp, "$%x,", id);
204   strcat(output, temp);
205
206    switch(dst) {
207      case  0: strcat(output, "non"); break;
208      case  1: strcat(output, "a"); break;
209      case  2: strcat(output, "b"); break;
210      case  3: strcat(output, "tr"); break;
211      case  4: strcat(output, "dp"); break;
212      case  5: strcat(output, "rp"); break;
213      case  6: strcat(output, "dr"); break;
214      case  7: strcat(output, "sr"); break;
215      case  8: strcat(output, "sol"); break;
216      case  9: strcat(output, "som"); break;
217      case 10: strcat(output, "k"); break;
218      case 11: strcat(output, "klr"); break;
219      case 12: strcat(output, "klm"); break;
220      case 13: strcat(output, "l"); break;
221      case 14: strcat(output, "trb"); break;
222      case 15: strcat(output, "mem"); break;
223    }
224  }
225
226  strcpy(buffer, output);
227
228  return 1 | DASMFLAG_SUPPORTED;
229}
230
src/emu/cpu/upd7725/upd7725.c
r0r9893
1/***************************************************************************
2
3    upd7725.h
4
5    Core implementation for the portable NEC uPD7725 emulator
6 
7    Original by byuu in the public domain.
8    MAME conversion by R. Belmont
9 
10****************************************************************************/
11
12#include "emu.h"
13#include "debugger.h"
14#include "upd7725.h"
15
16//**************************************************************************
17//  DEVICE DEFINITIONS
18//**************************************************************************
19
20const device_type UPD7725 = upd7725_device_config::static_alloc_device_config;
21
22//**************************************************************************
23//  UPD7725 DEVICE CONFIG
24//**************************************************************************
25
26//-------------------------------------------------
27//  upd7725_device_config - constructor
28//-------------------------------------------------
29
30upd7725_device_config::upd7725_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
31   : cpu_device_config(mconfig, static_alloc_device_config, "upd7725", tag, owner, clock),
32     m_program_config("program", ENDIANNESS_BIG, 32, 13, -2),   // data bus width, address bus width, -2 means DWORD-addressable
33     m_data_config("data", ENDIANNESS_BIG, 16, 11, -1)   // -1 for WORD-addressable
34{
35}
36
37
38//-------------------------------------------------
39//  static_alloc_device_config - allocate a new
40//  configuration object
41//-------------------------------------------------
42
43device_config *upd7725_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
44{
45   return global_alloc(upd7725_device_config(mconfig, tag, owner, clock));
46}
47
48
49//-------------------------------------------------
50//  alloc_device - allocate a new device object
51//-------------------------------------------------
52
53device_t *upd7725_device_config::alloc_device(running_machine &machine) const
54{
55   return auto_alloc(&machine, upd7725_device(machine, *this));
56}
57
58
59//-------------------------------------------------
60//  execute_min_cycles - return minimum number of
61//  cycles it takes for one instruction to execute
62//-------------------------------------------------
63
64UINT32 upd7725_device_config::execute_min_cycles() const
65{
66   return 4;
67}
68
69
70//-------------------------------------------------
71//  execute_max_cycles - return maximum number of
72//  cycles it takes for one instruction to execute
73//-------------------------------------------------
74
75UINT32 upd7725_device_config::execute_max_cycles() const
76{
77   return 4;
78}
79
80
81//-------------------------------------------------
82//  execute_input_lines - return the number of
83//  input/interrupt lines
84//-------------------------------------------------
85
86UINT32 upd7725_device_config::execute_input_lines() const
87{
88   return 0;
89}
90
91
92//-------------------------------------------------
93//  memory_space_config - return the configuration
94//  of the specified address space, or NULL if
95//  the space doesn't exist
96//-------------------------------------------------
97
98const address_space_config *upd7725_device_config::memory_space_config(int spacenum) const
99{
100   return (spacenum == AS_PROGRAM) ? &m_program_config : &m_data_config;
101}
102
103
104//-------------------------------------------------
105//  disasm_min_opcode_bytes - return the length
106//  of the shortest instruction, in bytes
107//-------------------------------------------------
108
109UINT32 upd7725_device_config::disasm_min_opcode_bytes() const
110{
111   return 4;
112}
113
114
115//-------------------------------------------------
116//  disasm_max_opcode_bytes - return the length
117//  of the longest instruction, in bytes
118//-------------------------------------------------
119
120UINT32 upd7725_device_config::disasm_max_opcode_bytes() const
121{
122   return 4;
123}
124
125
126
127//**************************************************************************
128//  DEVICE INTERFACE
129//**************************************************************************
130
131upd7725_device::upd7725_device(running_machine &_machine, const upd7725_device_config &config)
132   : cpu_device(_machine, config),
133   m_program(NULL),
134   m_data(NULL),
135   m_direct(NULL)
136{
137}
138
139//-------------------------------------------------
140//  device_start - start up the device
141//-------------------------------------------------
142
143void upd7725_device::device_start()
144{
145   // get our address spaces
146   m_program = space(AS_PROGRAM);
147   m_data = space(AS_DATA);
148   m_direct = &m_program->direct();
149
150   // register our state for the debugger
151   astring tempstr;
152   state_add(STATE_GENPC, "GENPC", regs.pc).noshow();
153   state_add(UPD7725_PC, "PC", regs.pc);
154   state_add(UPD7725_RP, "RP", regs.rp);
155   state_add(UPD7725_DP, "DP", regs.dp);
156   state_add(UPD7725_K, "K", regs.k);
157   state_add(UPD7725_L, "L", regs.l);
158   state_add(UPD7725_M, "M", regs.m);
159   state_add(UPD7725_N, "N", regs.n);
160   state_add(UPD7725_A, "A", regs.a);
161   state_add(UPD7725_B, "B", regs.b);
162   state_add(UPD7725_SR, "SR", regs.sr);
163   state_add(UPD7725_DR, "DR", regs.dr);
164
165   m_icountptr = &m_icount;
166}
167
168//-------------------------------------------------
169//  device_reset - reset the device
170//-------------------------------------------------
171
172void upd7725_device::device_reset()
173{
174   for (unsigned i = 0; i <  256; i++)
175   {
176      dataRAM[i] = 0x0000;
177   }
178
179   regs.pc = 0x000;
180   regs.stack[0] = 0x000;
181   regs.stack[1] = 0x000;
182   regs.stack[2] = 0x000;
183   regs.stack[3] = 0x000;
184   regs.flaga = 0x00;
185   regs.flagb = 0x00;
186   regs.sr = 0x0000;
187   regs.rp = 0x3ff;
188   regs.siack = 0;
189   regs.soack = 0;
190}
191
192//-------------------------------------------------
193//  state_import - import state into the device,
194//  after it has been set
195//-------------------------------------------------
196
197void upd7725_device::state_import(const device_state_entry &entry)
198{
199}
200
201
202//-------------------------------------------------
203//  state_export - export state from the device,
204//  to a known location where it can be read
205//-------------------------------------------------
206
207void upd7725_device::state_export(const device_state_entry &entry)
208{
209}
210
211
212//-------------------------------------------------
213//  state_string_export - export state as a string
214//  for the debugger
215//-------------------------------------------------
216
217void upd7725_device::state_string_export(const device_state_entry &entry, astring &string)
218{
219   switch (entry.index())
220   {
221      case UPD7725_FLAGA:
222         string.printf("%s %s %c%c %s %s",
223                    regs.flaga.s1 ? "S1" : "s1",
224                    regs.flaga.s0 ? "S0" : "s0",
225                    regs.flaga.c ? "C" : "c",
226                    regs.flaga.z ? "Z" : "z",
227                    regs.flaga.ov1 ? "OV1" : "ov1",
228                    regs.flaga.ov0 ? "OV0" : "ov0");
229         break;
230
231      case UPD7725_FLAGB:
232         string.printf("%s %s %c%c %s %s",
233                    regs.flagb.s1 ? "S1" : "s1",
234                    regs.flagb.s0 ? "S0" : "s0",
235                    regs.flagb.c ? "C" : "c",
236                    regs.flagb.z ? "Z" : "z",
237                    regs.flagb.ov1 ? "OV1" : "ov1",
238                    regs.flagb.ov0 ? "OV0" : "ov0");
239         break;
240   }
241}
242
243
244//-------------------------------------------------
245//  disasm_disassemble - call the disassembly
246//  helper function
247//-------------------------------------------------
248
249offs_t upd7725_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
250{
251   extern CPU_DISASSEMBLE( upd7725 );
252   return CPU_DISASSEMBLE_NAME(upd7725)(NULL, buffer, pc, oprom, opram, 0);
253}
254
255void upd7725_device::execute_run()
256{
257    UINT32 opcode;
258
259   do
260   {
261      // call debugger hook if necessary
262      if (device_t::m_machine.debug_flags & DEBUG_FLAG_ENABLED)
263      {
264         debugger_instruction_hook(this, regs.pc);
265      }
266
267      opcode = m_direct->read_decrypted_dword(regs.pc<<2)>>8;
268      regs.pc++;
269      switch(opcode >> 22)
270      {
271        case 0: exec_op(opcode); break;
272        case 1: exec_rt(opcode); break;
273        case 2: exec_jp(opcode); break;
274        case 3: exec_ld(opcode); break;
275      }
276   
277      INT32 result = (INT32)regs.k * regs.l;  //sign + 30-bit result
278      regs.m = result >> 15;  //store sign + top 15-bits
279      regs.n = result <<  1;  //store low 15-bits + zero
280
281      m_icount--;
282
283   } while (m_icount > 0);
284}
285
286void upd7725_device::exec_op(UINT32 opcode) {
287  UINT8 pselect = (opcode >> 20)&0x3;  //P select
288  UINT8 alu     = (opcode >> 16)&0xf;  //ALU operation mode
289  UINT8 asl     = (opcode >> 15)&0x1;  //accumulator select
290  UINT8 dpl     = (opcode >> 13)&0x3;  //DP low modify
291  UINT8 dphm    = (opcode >>  9)&0xf;  //DP high XOR modify
292  UINT8 rpdcr   = (opcode >>  8)&0x1;  //RP decrement
293  UINT8 src     = (opcode >>  4)&0xf;  //move source
294  UINT8 dst     = (opcode >>  0)&0xf;  //move destination
295
296  switch(src) {
297    case  0: regs.idb = regs.trb; break;
298    case  1: regs.idb = regs.a; break;
299    case  2: regs.idb = regs.b; break;
300    case  3: regs.idb = regs.tr; break;
301    case  4: regs.idb = regs.dp; break;
302    case  5: regs.idb = regs.rp; break;
303    case  6: regs.idb = m_data->read_word(regs.rp<<1); break;
304    case  7: regs.idb = 0x8000 - regs.flaga.s1; break;
305    case  8: regs.idb = regs.dr; regs.sr.rqm = 1; break;
306    case  9: regs.idb = regs.dr; break;
307    case 10: regs.idb = regs.sr; break;
308  //case 11: regs.idb = regs.sim; break;
309  //case 12: regs.idb = regs.sil; break;
310    case 13: regs.idb = regs.k; break;
311    case 14: regs.idb = regs.l; break;
312    case 15: regs.idb = dataRAM[regs.dp]; break;
313  }
314
315  if(alu) {
316    UINT16 p=0, q=0, r=0;
317    Flag flag;
318    bool c=0;
319
320    switch(pselect) {
321      case 0: p = dataRAM[regs.dp]; break;
322      case 1: p = regs.idb; break;
323      case 2: p = regs.m; break;
324      case 3: p = regs.n; break;
325    }
326
327    switch(asl) {
328      case 0: q = regs.a; flag = regs.flaga; c = regs.flagb.c; break;
329      case 1: q = regs.b; flag = regs.flagb; c = regs.flaga.c; break;
330    }
331
332    switch(alu) {
333      case  1: r = q | p; break;                    //OR
334      case  2: r = q & p; break;                    //AND
335      case  3: r = q ^ p; break;                    //XOR
336      case  4: r = q - p; break;                    //SUB
337      case  5: r = q + p; break;                    //ADD
338      case  6: r = q - p - c; break;                //SBB
339      case  7: r = q + p + c; break;                //ADC
340      case  8: r = q - 1; p = 1; break;             //DEC
341      case  9: r = q + 1; p = 1; break;             //INC
342      case 10: r = ~q; break;                       //CMP
343      case 11: r = (q >> 1) | (q & 0x8000); break;  //SHR1 (ASR)
344      case 12: r = (q << 1) | c; break;             //SHL1 (ROL)
345      case 13: r = (q << 2) | 3; break;             //SHL2
346      case 14: r = (q << 4) | 15; break;            //SHL4
347      case 15: r = (q << 8) | (q >> 8); break;      //XCHG
348    }
349
350    flag.s0 = (r & 0x8000);
351    flag.z = (r == 0);
352
353    switch(alu) {
354      case  1: case  2: case  3: case 10: case 13: case 14: case 15: {
355        flag.c = 0;
356        flag.ov0 = 0;
357        flag.ov1 = 0;
358        break;
359      }
360      case  4: case  5: case  6: case  7: case  8: case  9: {
361        if(alu & 1) {
362          //addition
363          flag.ov0 = (q ^ r) & ~(q ^ p) & 0x8000;
364          flag.c = (r < q);
365        } else {
366          //subtraction
367          flag.ov0 = (q ^ r) &  (q ^ p) & 0x8000;
368          flag.c = (r > q);
369        }
370        if(flag.ov0) {
371          flag.s1 = flag.ov1 ^ !(r & 0x8000);
372          flag.ov1 = !flag.ov1;
373        }
374        break;
375      }
376      case 11: {
377        flag.c = q & 1;
378        flag.ov0 = 0;
379        flag.ov1 = 0;
380        break;
381      }
382      case 12: {
383        flag.c = q >> 15;
384        flag.ov0 = 0;
385        flag.ov1 = 0;
386        break;
387      }
388    }
389
390    switch(asl) {
391      case 0: regs.a = r; regs.flaga = flag; break;
392      case 1: regs.b = r; regs.flagb = flag; break;
393    }
394  }
395
396  exec_ld((regs.idb << 6) + dst);
397
398  switch(dpl) {
399    case 1: regs.dp = (regs.dp & 0xf0) + ((regs.dp + 1) & 0x0f); break;  //DPINC
400    case 2: regs.dp = (regs.dp & 0xf0) + ((regs.dp - 1) & 0x0f); break;  //DPDEC
401    case 3: regs.dp = (regs.dp & 0xf0); break;  //DPCLR
402  }
403
404  regs.dp ^= dphm << 4;
405
406  if(rpdcr) regs.rp--;
407}
408
409void upd7725_device::exec_rt(UINT32 opcode) {
410  exec_op(opcode);
411  stack_pull();
412}
413
414void upd7725_device::exec_jp(UINT32 opcode) {
415  UINT16 brch = (opcode >> 13) & 0x1ff;  //branch
416  UINT16 na  = (opcode >>  2) & 0x7ff;  //next address
417
418  bool r = false;
419
420  switch(brch) {
421    case 0x080: r = (regs.flaga.c == 0);      break;  //JNCA
422    case 0x082: r = (regs.flaga.c == 1);      break;  //JCA
423    case 0x084: r = (regs.flagb.c == 0);      break;  //JNCB
424    case 0x086: r = (regs.flagb.c == 1);      break;  //JCB
425    case 0x088: r = (regs.flaga.z == 0);      break;  //JNZA
426    case 0x08a: r = (regs.flaga.z == 1);      break;  //JZA
427    case 0x08c: r = (regs.flagb.z == 0);      break;  //JNZB
428    case 0x08e: r = (regs.flagb.z == 1);      break;  //JZB
429    case 0x090: r = (regs.flaga.ov0 == 0);    break;  //JNOVA0
430    case 0x092: r = (regs.flaga.ov0 == 1);    break;  //JOVA0
431    case 0x094: r = (regs.flagb.ov0 == 0);    break;  //JNOVB0
432    case 0x096: r = (regs.flagb.ov0 == 1);    break;  //JOVB0
433    case 0x098: r = (regs.flaga.ov1 == 0);    break;  //JNOVA1
434    case 0x09a: r = (regs.flaga.ov1 == 1);    break;  //JOVA1
435    case 0x09c: r = (regs.flagb.ov1 == 0);    break;  //JNOVB1
436    case 0x09e: r = (regs.flagb.ov1 == 1);    break;  //JOVB1
437    case 0x0a0: r = (regs.flaga.s0 == 0);     break;  //JNSA0
438    case 0x0a2: r = (regs.flaga.s0 == 1);     break;  //JSA0
439    case 0x0a4: r = (regs.flagb.s0 == 0);     break;  //JNSB0
440    case 0x0a6: r = (regs.flagb.s0 == 1);     break;  //JSB0
441    case 0x0a8: r = (regs.flaga.s1 == 0);     break;  //JNSA1
442    case 0x0aa: r = (regs.flaga.s1 == 1);     break;  //JSA1
443    case 0x0ac: r = (regs.flagb.s1 == 0);     break;  //JNSB1
444    case 0x0ae: r = (regs.flagb.s1 == 1);     break;  //JSB1
445
446    case 0x0b0: r = (regs.dp & 0x0f) == 0x00; break;  //JDPL0
447    case 0x0b1: r = (regs.dp & 0x0f) != 0x00; break;  //JDPLN0
448    case 0x0b2: r = (regs.dp & 0x0f) == 0x0f; break;  //JDPLF
449    case 0x0b3: r = (regs.dp & 0x0f) != 0x0f; break;  //JDPLNF
450
451    case 0x0b4: r = (regs.siack == 0);        break;  //JNSIAK
452    case 0x0b6: r = (regs.siack == 1);        break;  //JSIAK
453
454    case 0x0b8: r = (regs.soack == 0);        break;  //JNSOAK
455    case 0x0ba: r = (regs.soack == 1);        break;  //JSOAK
456
457    case 0x0bc: r = (regs.sr.rqm == 0);       break;  //JNRQM
458    case 0x0be: r = (regs.sr.rqm == 1);       break;  //JRQM
459
460    case 0x100: r = true;                     break;  //JMP
461    case 0x140: r = true; stack_push();       break;  //CALL
462  }
463
464  if(r) regs.pc = na;
465}
466
467void upd7725_device::exec_ld(UINT32 opcode) {
468  UINT16 id = opcode >> 6;  //immediate data
469  UINT8 dst = (opcode >> 0) & 0xf;  //destination
470
471  regs.idb = id;
472
473  switch(dst) {
474    case  0: break;
475    case  1: regs.a = id; break;
476    case  2: regs.b = id; break;
477    case  3: regs.tr = id; break;
478    case  4: regs.dp = id; break;
479    case  5: regs.rp = id; break;
480    case  6: regs.dr = id; regs.sr.rqm = 1; break;
481    case  7: regs.sr = (regs.sr & 0x907c) | (id & ~0x907c); break;
482  //case  8: regs.sol = id; break;
483  //case  9: regs.som = id; break;
484    case 10: regs.k = id; break;
485    case 11: regs.k = id; regs.l = m_data->read_word(regs.rp<<1); break;
486    case 12: regs.l = id; regs.k = dataRAM[regs.dp | 0x40]; break;
487    case 13: regs.l = id; break;
488    case 14: regs.trb = id; break;
489    case 15: dataRAM[regs.dp] = id; break;
490  }
491}
492
493void upd7725_device::stack_push() {
494  regs.stack[3] = regs.stack[2];
495  regs.stack[2] = regs.stack[1];
496  regs.stack[1] = regs.stack[0];
497  regs.stack[0] = regs.pc & 0x7ff;
498}
499
500void upd7725_device::stack_pull() {
501  regs.pc = regs.stack[0] & 0x7ff;
502  regs.stack[0] = regs.stack[1];
503  regs.stack[1] = regs.stack[2];
504  regs.stack[2] = regs.stack[3];
505  regs.stack[3] = 0x000;
506}
507
508UINT8 upd7725_device::snesdsp_read(bool mode) {
509   
510   if (!mode)
511   {
512      return regs.sr >> 8;
513   }
514   
515   if (regs.sr.drc == 0)
516   {
517      //16-bit
518      if(regs.sr.drs == 0)
519      {
520         regs.sr.drs = 1;
521         return regs.dr >> 0;
522      }
523      else
524      {
525         regs.sr.rqm = 0;
526         regs.sr.drs = 0;
527         return regs.dr >> 8;
528      }
529   }
530   else
531   {
532      //8-bit
533      regs.sr.rqm = 0;
534      return regs.dr >> 0;
535   }
536}
537
538void upd7725_device::snesdsp_write(bool mode, UINT8 data) {
539   if (!mode) return;
540   
541   if (regs.sr.drc == 0)
542   {
543      //16-bit
544      if (regs.sr.drs == 0)
545      {
546         regs.sr.drs = 1;
547         regs.dr = (regs.dr & 0xff00) | (data << 0);
548      }
549      else
550      {
551         regs.sr.rqm = 0;
552         regs.sr.drs = 0;
553         regs.dr = (data << 8) | (regs.dr & 0x00ff);
554      }
555   }
556   else
557   {
558      //8-bit
559      regs.sr.rqm = 0;
560      regs.dr = (regs.dr & 0xff00) | (data << 0);
561   }
562}
src/mess/machine/snescart.c
r9892r9893
506506   snes_state *state = machine->driver_data<snes_state>();
507507   address_space *space = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM);
508508   int supported_type = 1;
509   int dsp_prg_offset = 0;
509510
510511   /* Info mostly taken from http://snesemu.black-ship.net/misc/-from%20nsrt.edgeemu.com-chipinfo.htm */
511512   switch (snes_r_bank1(space, 0x00ffd6))
r9892r9893
518519
519520      case 0x03:
520521         if (snes_r_bank1(space, 0x00ffd5) == 0x30)
522         {
521523            state->has_addon_chip = HAS_DSP4;
524            dsp_prg_offset = SNES_DSP4_OFFSET;
525         }
522526         else
527         {
523528            state->has_addon_chip = HAS_DSP1;
529            dsp_prg_offset = SNES_DSP1B_OFFSET;
530         }
524531         break;
525532
526533      case 0x04:
527534         state->has_addon_chip = HAS_DSP1;
535         dsp_prg_offset = SNES_DSP1B_OFFSET;
528536         break;
529537
530538      case 0x05:
531539         if (snes_r_bank1(space, 0x00ffd5) == 0x20)
540         {
532541            state->has_addon_chip = HAS_DSP2;
542            dsp_prg_offset = SNES_DSP2_OFFSET;
543         }
533544         /* DSP-3 is hard to detect. We exploit the fact that the only game has been manufactured by Bandai */
534545         else if ((snes_r_bank1(space, 0x00ffd5) == 0x30) && (snes_r_bank1(space, 0x00ffda) == 0xb2))
546         {
535547            state->has_addon_chip = HAS_DSP3;
536         else
548            dsp_prg_offset = SNES_DSP3_OFFSET;
549         }
550         else                   
551         {
537552            state->has_addon_chip = HAS_DSP1;
553            dsp_prg_offset = SNES_DSP1B_OFFSET;
554         }
538555         break;
539556
540557      case 0x13:   // Mario Chip 1
r9892r9893
624641         break;
625642   }
626643
644   if ((state->has_addon_chip >= HAS_DSP1) && (state->has_addon_chip <= HAS_DSP4))
645   {
646      UINT8 *dspsrc = (UINT8 *)machine->region("addons")->base();
647      UINT32 *dspprg = (UINT32 *)machine->region("dspprg")->base();
648      UINT16 *dspdata = (UINT16 *)machine->region("dspdata")->base();
649
650      // copy DSP program
651      for (int i = 0; i < 0x2000; i+= 4)
652      {
653         *dspprg = dspsrc[dsp_prg_offset+0+i]<<24 | dspsrc[dsp_prg_offset+1+i]<<16 | dspsrc[dsp_prg_offset+2+i]<<8;
654         dspprg++;
655      }
656
657      // copy DSP data
658      for (int i = 0; i < 0x800; i+= 2)
659      {
660         *dspdata++ = dspsrc[dsp_prg_offset+0x2000+i]<<8 | dspsrc[dsp_prg_offset+0x2001+i];
661      }
662   }
663
627664   return supported_type;
628665}
629666
src/mess/mess.mak
r9892r9893
133133CPUS += UNSP
134134CPUS += HCD62121
135135CPUS += PPS4
136CPUS += UPD7725
136137
137138#-------------------------------------------------
138139# specify available sound cores; some of these are
r9892r9893
17771778# miscellaneous dependencies
17781779#-------------------------------------------------
17791780
1780$(MAME_MACHINE)/snes.o:    $(MAMESRC)/machine/snesdsp1.c \
1781            $(MAMESRC)/machine/snesdsp2.c \
1782            $(MAMESRC)/machine/snesdsp3.c \
1783            $(MAMESRC)/machine/snesdsp4.c \
1784            $(MAMESRC)/machine/snesobc1.c \
1781$(MAME_MACHINE)/snes.o: $(MAMESRC)/machine/snesobc1.c \
17851782            $(MAMESRC)/machine/snescx4.c \
17861783            $(MAMESRC)/machine/cx4ops.c \
17871784            $(MAMESRC)/machine/cx4oam.c \
src/mess/drivers/snes.c
r9892r9893
88  Anthony Kruize
99  Angelo Salese
1010  Fabio Priuli
11  byuu
1112  Based on the original MESS driver by Lee Hammerton (aka Savoury Snax)
1213
1314  Driver is preliminary right now.
r9892r9893
3132#include "cpu/spc700/spc700.h"
3233#include "cpu/superfx/superfx.h"
3334#include "cpu/g65816/g65816.h"
35#include "cpu/upd7725/upd7725.h"
3436#include "includes/snes.h"
3537#include "machine/snescart.h"
3638#include "crsshair.h"
r9892r9893
8789   AM_RANGE(0xffc0, 0xffff) AM_DEVREAD("spc700", spc_ipl_r)
8890ADDRESS_MAP_END
8991
92static ADDRESS_MAP_START( dsp_prg_map, ADDRESS_SPACE_PROGRAM, 32 )
93   AM_RANGE(0x0000, 0x07ff) AM_ROM AM_REGION("dspprg", 0)
94ADDRESS_MAP_END
9095
96static ADDRESS_MAP_START( dsp_data_map, ADDRESS_SPACE_PROGRAM, 16 )
97   AM_RANGE(0x0000, 0x03ff) AM_ROM AM_REGION("dspdata", 0)
98ADDRESS_MAP_END
9199
92100/*************************************
93101 *
r9892r9893
695703   MCFG_CPU_ADD("soundcpu", SPC700, 1024000)   /* 1.024 MHz */
696704   MCFG_CPU_PROGRAM_MAP(spc_map)
697705
706   MCFG_CPU_ADD("dsp", UPD7725, 8000000)
707   MCFG_CPU_PROGRAM_MAP(dsp_prg_map)
708   MCFG_CPU_DATA_MAP(dsp_data_map)
709
698710   //MCFG_QUANTUM_TIME(HZ(48000))
699711   MCFG_QUANTUM_PERFECT_CPU("maincpu")
700712
r9892r9893
774786   ROM_REGION( 0x100, "user5", 0 )      /* IPL ROM */
775787   ROM_LOAD( "spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) )   /* boot rom */
776788
777   ROM_REGION( 0x1000, "addons", 0 )      /* add-on chip ROMs (DSP, SFX, etc) */
778   ROM_LOAD_OPTIONAL( "dsp1data.bin", 0x000000, 0x000800, CRC(4b02d66d) SHA1(1534f4403d2a0f68ba6e35186fe7595d33de34b1) )
779   ROM_LOAD_OPTIONAL( "dsp3data.bin", 0x000800, 0x000800, CRC(4a1c5453) SHA1(2f69c652109938cde21df5eb89890bf090256dbb) )
789   ROM_REGION( 0x10000, "addons", 0 )      /* add-on chip ROMs (DSP, SFX, etc) */
790   ROM_LOAD( "dsp1b.bin", SNES_DSP1B_OFFSET, 0x002800, CRC(453557e0) SHA1(3a218b0e4572a8eba6d0121b17fdac9529609220) )
791   ROM_LOAD( "dsp1.bin",  SNES_DSP1_OFFSET,  0x002800, CRC(2838f9f5) SHA1(0a03ccb1fd2bea91151c745a4d1f217ae784f889) )
792   ROM_LOAD( "dsp2.bin",  SNES_DSP2_OFFSET,  0x002800, CRC(8e9fbd9b) SHA1(06dd9fcb118d18f6bbe234e013cb8780e06d6e63) )
793   ROM_LOAD( "dsp3.bin",  SNES_DSP3_OFFSET,  0x002800, CRC(6b86728a) SHA1(1b133741fad810eb7320c21ecfdd427d25a46da1) )
794   ROM_LOAD( "dsp4.bin",  SNES_DSP4_OFFSET,  0x002800, CRC(ce0c7783) SHA1(76fd25f7dc26c3b3f7868a3aa78c7684068713e5) )
780795
781796   ROM_REGION( MAX_SNES_CART_SIZE, "cart", ROMREGION_ERASE00 )
797   ROM_REGION( 0x2000, "dspprg", ROMREGION_ERASEFF)
798   ROM_REGION( 0x800, "dspdata", ROMREGION_ERASEFF)
782799ROM_END
783800
784801ROM_START( snessfx )
r9892r9893
787804   ROM_REGION( 0x100, "user5", 0 )      /* IPL ROM */
788805   ROM_LOAD( "spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) )   /* boot rom */
789806
790   ROM_REGION( 0x1000, "addons", 0 )      /* add-on chip ROMs (DSP, SFX, etc) */
791   ROM_LOAD_OPTIONAL( "dsp1data.bin", 0x000000, 0x000800, CRC(4b02d66d) SHA1(1534f4403d2a0f68ba6e35186fe7595d33de34b1) )
807   ROM_REGION( 0x10000, "addons", ROMREGION_ERASE00 )      /* add-on chip ROMs (DSP, SFX, etc) */
792808
793809   ROM_REGION( MAX_SNES_CART_SIZE, "cart", ROMREGION_ERASE00 )
810   ROM_REGION( 0x2000, "dspprg", ROMREGION_ERASEFF)
811   ROM_REGION( 0x800, "dspdata", ROMREGION_ERASEFF)
794812ROM_END
795813
796814ROM_START( snespal )
r9892r9893
799817   ROM_REGION( 0x100, "user5", 0 )      /* IPL ROM */
800818   ROM_LOAD( "spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) )   /* boot rom */
801819
802   ROM_REGION( 0x1000, "addons", 0 )      /* add-on chip ROMs (DSP, SFX, etc) */
803   ROM_LOAD_OPTIONAL( "dsp1data.bin", 0x000000, 0x000800, CRC(4b02d66d) SHA1(1534f4403d2a0f68ba6e35186fe7595d33de34b1) )
804   ROM_LOAD_OPTIONAL( "dsp3data.bin", 0x000800, 0x000800, CRC(4a1c5453) SHA1(2f69c652109938cde21df5eb89890bf090256dbb) )
820   ROM_REGION( 0x10000, "addons", 0 )      /* add-on chip ROMs (DSP, SFX, etc) */
821   ROM_LOAD( "dsp1b.bin", SNES_DSP1B_OFFSET, 0x002800, CRC(453557e0) SHA1(3a218b0e4572a8eba6d0121b17fdac9529609220) )
822   ROM_LOAD( "dsp1.bin",  SNES_DSP1_OFFSET,  0x002800, CRC(2838f9f5) SHA1(0a03ccb1fd2bea91151c745a4d1f217ae784f889) )
823   ROM_LOAD( "dsp2.bin",  SNES_DSP2_OFFSET,  0x002800, CRC(8e9fbd9b) SHA1(06dd9fcb118d18f6bbe234e013cb8780e06d6e63) )
824   ROM_LOAD( "dsp3.bin",  SNES_DSP3_OFFSET,  0x002800, CRC(6b86728a) SHA1(1b133741fad810eb7320c21ecfdd427d25a46da1) )
825   ROM_LOAD( "dsp4.bin",  SNES_DSP4_OFFSET,  0x002800, CRC(ce0c7783) SHA1(76fd25f7dc26c3b3f7868a3aa78c7684068713e5) )
805826
806827   ROM_REGION( MAX_SNES_CART_SIZE, "cart", ROMREGION_ERASE00 )
828   ROM_REGION( 0x2000, "dspprg", ROMREGION_ERASEFF)
829   ROM_REGION( 0x800, "dspdata", ROMREGION_ERASEFF)
807830ROM_END
808831
809832ROM_START( snespsfx )
r9892r9893
812835   ROM_REGION( 0x100, "user5", 0 )      /* IPL ROM */
813836   ROM_LOAD( "spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) )   /* boot rom */
814837
815   ROM_REGION( 0x1000, "addons", 0 )      /* add-on chip ROMs (DSP, SFX, etc) */
816   ROM_LOAD_OPTIONAL( "dsp1data.bin", 0x000000, 0x000800, CRC(4b02d66d) SHA1(1534f4403d2a0f68ba6e35186fe7595d33de34b1) )
838   ROM_REGION( 0x10000, "addons", 0 )      /* add-on chip ROMs (DSP, SFX, etc) */
817839
818840   ROM_REGION( MAX_SNES_CART_SIZE, "cart", ROMREGION_ERASE00 )
841   ROM_REGION( 0x2000, "dspprg", ROMREGION_ERASEFF)
842   ROM_REGION( 0x800, "dspdata", ROMREGION_ERASEFF)
819843ROM_END
820844
821845ROM_START( snesst )
r9892r9893
824848   ROM_REGION( 0x100, "user5", 0 )      /* IPL ROM */
825849   ROM_LOAD( "spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) )   /* boot rom */
826850
827   ROM_REGION( 0x1000, "addons", ROMREGION_ERASE00 )      /* add-on chip ROMs (DSP, SFX, etc) */
851   ROM_REGION( 0x10000, "addons", ROMREGION_ERASE00 )      /* add-on chip ROMs (DSP, SFX, etc) */
828852
829853   ROM_REGION( 0x40000, "sufami", 0 )      /* add-on chip ROMs (DSP, SFX, etc) */
830854   ROM_LOAD( "shvc-qh-0.bin", 0,   0x40000, CRC(9b4ca911) SHA1(ef86ea192eed03d5c413fdbbfd46043be1d7a127) )
831855
832856   ROM_REGION( MAX_SNES_CART_SIZE, "slot_a", ROMREGION_ERASE00 )
833857   ROM_REGION( MAX_SNES_CART_SIZE, "slot_b", ROMREGION_ERASE00 )
858   ROM_REGION( 0x2000, "dspprg", ROMREGION_ERASEFF)
859   ROM_REGION( 0x800, "dspdata", ROMREGION_ERASEFF)
834860ROM_END
835861
836862ROM_START( snesbsx )
r9892r9893
839865   ROM_REGION( 0x100, "user5", 0 )      /* IPL ROM */
840866   ROM_LOAD( "spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) )   /* boot rom */
841867
842   ROM_REGION( 0x1000, "addons", 0 )      /* add-on chip ROMs (DSP, SFX, etc) */
843   ROM_LOAD_OPTIONAL( "dsp1data.bin", 0x000000, 0x000800, CRC(4b02d66d) SHA1(1534f4403d2a0f68ba6e35186fe7595d33de34b1) )
844   ROM_LOAD_OPTIONAL( "dsp3data.bin", 0x000800, 0x000800, CRC(4a1c5453) SHA1(2f69c652109938cde21df5eb89890bf090256dbb) )
868   ROM_REGION( 0x10000, "addons", 0 )      /* add-on chip ROMs (DSP, SFX, etc) */
869   ROM_LOAD( "dsp1b.bin", SNES_DSP1B_OFFSET, 0x002800, CRC(453557e0) SHA1(3a218b0e4572a8eba6d0121b17fdac9529609220) )
870   ROM_LOAD( "dsp1.bin",  SNES_DSP1_OFFSET,  0x002800, CRC(2838f9f5) SHA1(0a03ccb1fd2bea91151c745a4d1f217ae784f889) )
871   ROM_LOAD( "dsp2.bin",  SNES_DSP2_OFFSET,  0x002800, CRC(8e9fbd9b) SHA1(06dd9fcb118d18f6bbe234e013cb8780e06d6e63) )
872   ROM_LOAD( "dsp3.bin",  SNES_DSP3_OFFSET,  0x002800, CRC(6b86728a) SHA1(1b133741fad810eb7320c21ecfdd427d25a46da1) )
873   ROM_LOAD( "dsp4.bin",  SNES_DSP4_OFFSET,  0x002800, CRC(ce0c7783) SHA1(76fd25f7dc26c3b3f7868a3aa78c7684068713e5) )
845874
846875   ROM_REGION( MAX_SNES_CART_SIZE, "cart", ROMREGION_ERASE00 )
847876   ROM_REGION( MAX_SNES_CART_SIZE, "flash", ROMREGION_ERASE00 )
877   ROM_REGION( 0x2000, "dspprg", ROMREGION_ERASEFF)
878   ROM_REGION( 0x800, "dspdata", ROMREGION_ERASEFF)
848879ROM_END
849880
850881

Previous 15994 Revisions Next


© 1998-2018 The MESS Team