Previous 199869 Revisions Next

r17410 Wednesday 22nd August, 2012 at 20:16:55 UTC by Angelo Salese
(SNES) Rewritten cycle steal code from scratch and nailed it directly in the G65816 CPU core [Angelo Salese, byuu]
[src/emu/cpu/g65816]g65816.c g65816cm.h g65816op.h
[src/mame/machine]snes.c

trunk/src/mame/machine/snes.c
r17409r17410
1313  Thanks to Anomie for invaluable technical information.
1414  Thanks to byuu for invaluable technical information.
1515
16  TODO:
17  - DMA takes some Master CPU clock cycles that aren't taken into account
18    for now.
19
1620***************************************************************************/
1721#define __MACHINE_SNES_C
1822
r17409r17410
5559#include "machine/snes7110.c"
5660#include "machine/snesbsx.c"
5761
58#define USE_CYCLE_STEAL 1
59
6062// ST-010 and ST-011 RAM interface
6163UINT8 st010_read_ram(snes_state *state, UINT16 addr)
6264{
r17409r17410
892894
893895*/
894896
895#if USE_CYCLE_STEAL
896/*FIXME: missing work RAM access steal / we need to do this less "aggressive" otherwise we lose too much CPU horsepower, why? */
897static int snes_bank_0x00_0x3f_cycles(running_machine &machine,UINT32 offset)
898{
899/*
900 $00-$3F | $0000-$1FFF | Slow  | Address Bus A + /WRAM (mirror $7E:0000-$1FFF)
901         | $2000-$20FF | Fast  | Address Bus A
902         | $2100-$21FF | Fast  | Address Bus B
903         | $2200-$3FFF | Fast  | Address Bus A
904         | $4000-$41FF | XSlow | Internal CPU registers (see Note 1 below)
905         | $4200-$43FF | Fast  | Internal CPU registers (see Note 1 below)
906         | $4400-$5FFF | Fast  | Address Bus A
907         | $6000-$7FFF | Slow  | Address Bus A
908         | $8000-$FFFF | Slow  | Address Bus A + /CART
909         */
910
911   if(((offset & 0xff00) == 0x4000) || ((offset & 0xff00) == 0x4100))
912      return 0; //TODO: 12
913   if(((offset & 0xff00) == 0x4200) || ((offset & 0xff00) == 0x4300))
914      return 0; //TODO: 6
915
916   if((offset & 0xff00) <= 0x1f00)
917      return 0; //TODO: 8
918
919   if((offset & 0xff00) >= 0x6000)
920      return 8;
921
922   return 0; //TODO: 6
923}
924
925static int snes_bank_0x80_0xbf_cycles(running_machine &machine,UINT32 offset)
926{
927/*
928 $80-$BF | $0000-$1FFF | Slow  | Address Bus A + /WRAM (mirror $7E:0000-$1FFF)
929         | $2000-$20FF | Fast  | Address Bus A
930         | $2100-$21FF | Fast  | Address Bus B
931         | $2200-$3FFF | Fast  | Address Bus A
932         | $4000-$41FF | XSlow | Internal CPU registers (see Note 1 below)
933         | $4200-$43FF | Fast  | Internal CPU registers (see Note 1 below)
934         | $4400-$5FFF | Fast  | Address Bus A
935         | $6000-$7FFF | Slow  | Address Bus A
936         | $8000-$FFFF | Note2 | Address Bus A + /CART
937*/
938
939
940   if(((offset & 0xff00) == 0x4000) || ((offset & 0xff00) == 0x4100))
941      return 0; //TODO: 12
942
943   if(((offset & 0xff00) == 0x4200) || ((offset & 0xff00) == 0x4300))
944      return 0; //TODO: 6
945
946   if((offset & 0xff00) <= 0x1f00)
947      return 0; //TODO: 8
948
949   if(((offset & 0xff00) >= 0x6000) && ((offset & 0xff00) <= 0x7f00))
950      return 0; //TODO: 8
951
952   if(((offset & 0xff00) >= 0x8000) && ((offset & 0xff00) <= 0xff00))
953      return (snes_ram[MEMSEL] & 1) ? 6 : 8;
954
955   return 0; //TODO: 6
956}
957#endif
958
959897/* 0x000000 - 0x2fffff */
960898READ8_HANDLER( snes_r_bank1 )
961899{
r17409r17410
1007945   else
1008946      value = snes_ram[offset];
1009947
1010   #if USE_CYCLE_STEAL
1011   if(!space->debugger_access())
1012      device_adjust_icount(&space->device(), -snes_bank_0x00_0x3f_cycles(space->machine(), offset));
1013   #endif
1014
1015948   return value;
1016949}
1017950
r17409r17410
10741007   else
10751008      value = snes_ram[0x300000 + offset];
10761009
1077   #if USE_CYCLE_STEAL
1078   if(!space->debugger_access())
1079      device_adjust_icount(&space->device(), -snes_bank_0x00_0x3f_cycles(space->machine(), offset));
1080   #endif
1081
10821010   return value;
10831011}
10841012
r17409r17410
11171045   else                                 /* Mode 21 & 25 + SuperFX games */
11181046      value = snes_ram[0x400000 + offset];
11191047
1120   #if USE_CYCLE_STEAL
1121   if(!space->debugger_access())
1122      device_adjust_icount(&space->device(), -8);
1123   #endif
1124
11251048   return value;
11261049}
11271050
r17409r17410
11661089   else if (state->m_cart[0].mode & 0x0a)               /* Mode 21 & 25 */
11671090      value = snes_ram[0x600000 + offset];
11681091
1169   #if USE_CYCLE_STEAL
1170   if(!space->debugger_access())
1171      device_adjust_icount(&space->device(), -8);
1172   #endif
1173
11741092   return value;
11751093}
11761094
r17409r17410
12041122   else
12051123      value = snes_ram[0x700000 + offset];
12061124
1207   #if USE_CYCLE_STEAL
1208   if(!space->debugger_access())
1209      device_adjust_icount(&space->device(), -8);
1210   #endif
1211
12121125   return value;
12131126}
12141127
r17409r17410
12541167   else
12551168      value = snes_ram[0x800000 + offset];
12561169
1257   #if USE_CYCLE_STEAL
1258   if(!space->debugger_access())
1259      device_adjust_icount(&space->device(), -snes_bank_0x80_0xbf_cycles(space->machine(), offset));
1260   #endif
1261
12621170   return value;
12631171}
12641172
r17409r17410
13181226   else                        /* Mode 21 & 25 + SuperFX Games */
13191227      value = snes_ram[0xc00000 + offset];
13201228
1321   #if USE_CYCLE_STEAL
1322   if(!space->debugger_access())
1323      device_adjust_icount(&space->device(), -((snes_ram[MEMSEL] & 1) ? 6 : 8));
1324   #endif
1325
13261229   return value;
13271230}
13281231
r17409r17410
13761279         dsp_set_sr(data);
13771280   else
13781281      logerror( "(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(&space->device()),offset );
1379
1380   #if USE_CYCLE_STEAL
1381   if(!space->debugger_access())
1382      device_adjust_icount(&space->device(), -snes_bank_0x00_0x3f_cycles(space->machine(), offset));
1383   #endif
13841282}
13851283
13861284/* 0x300000 - 0x3fffff */
r17409r17410
14381336         dsp_set_sr(data);
14391337   else
14401338      logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(&space->device()),offset + 0x300000);
1441
1442   #if USE_CYCLE_STEAL
1443   if(!space->debugger_access())
1444      device_adjust_icount(&space->device(), -snes_bank_0x00_0x3f_cycles(space->machine(), offset));
1445   #endif
14461339}
14471340
14481341/* 0x600000 - 0x6fffff */
r17409r17410
14791372   }
14801373   else if (state->m_cart[0].mode & 0x0a)
14811374      logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(&space->device()),offset + 0x600000);
1482
1483   #if USE_CYCLE_STEAL
1484   if(!space->debugger_access())
1485      device_adjust_icount(&space->device(), -8);
1486   #endif
14871375}
14881376
14891377/* 0x700000 - 0x7dffff */
r17409r17410
15061394   }
15071395   else if (state->m_cart[0].mode & 0x0a)
15081396      logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(&space->device()),offset + 0x700000);
1509
1510   #if USE_CYCLE_STEAL
1511   if(!space->debugger_access())
1512      device_adjust_icount(&space->device(), -8);
1513   #endif
15141397}
15151398
15161399
r17409r17410
15621445         dsp_set_sr(data);
15631446   else
15641447      logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(&space->device()),offset + 0x800000);
1565
1566   #if USE_CYCLE_STEAL
1567   if(!space->debugger_access())
1568      device_adjust_icount(&space->device(), -snes_bank_0x80_0xbf_cycles(space->machine(), offset));
1569   #endif
15701448}
15711449
15721450
r17409r17410
16171495   }
16181496   else if (state->m_cart[0].mode & 0x0a)
16191497      logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(&space->device()),offset + 0xc00000);
1620
1621   #if USE_CYCLE_STEAL
1622   if(!space->debugger_access())
1623      device_adjust_icount(&space->device(), -((snes_ram[MEMSEL] & 1) ? 6 : 8));
1624   #endif
16251498}
16261499
16271500
r17409r17410
21432016{
21442017   snes_state *state = space->machine().driver_data<snes_state>();
21452018
2146   #if USE_CYCLE_STEAL
2147   /* every byte transfer takes 8 master cycles */
2148//  FIXME: this cycle steal makes Final Fantasy VI (III in US) very glitchy!
2149//  device_adjust_icount(&space->device(),-8);
2150   #endif
2151
21522019   if (state->m_dma_channel[dma].dmap & 0x80)   /* PPU->CPU */
21532020   {
21542021      if (bbus == 0x2180 && ((abus & 0xfe0000) == 0x7e0000 || (abus & 0x40e000) == 0x0000))
r17409r17410
23552222
23562223   /* FIXME: we also need to round to the nearest 8 master cycles */
23572224
2358   #if USE_CYCLE_STEAL
2359   /* overhead steals 8 master cycles, correct? */
2360   device_adjust_icount(&space->device(),-8);
2361   #endif
2362
23632225   /* Assume priority of the 8 DMA channels is 0-7 */
23642226   for (i = 0; i < 8; i++)
23652227   {
r17409r17410
24682330         /* We're done, so write the new abus back to the registers */
24692331         state->m_dma_channel[i].src_addr = abus;
24702332         state->m_dma_channel[i].trans_size = 0;
2471
2472         #if USE_CYCLE_STEAL
2473         /* active channel takes 8 master cycles */
2474         device_adjust_icount(&space->device(),-8);
2475         #endif
24762333      }
24772334   }
24782335
2479   /* finally, take yet another 8 master cycles for the aforementioned overhead */
2480   #if USE_CYCLE_STEAL
2481   device_adjust_icount(&space->device(),-8);
2482   #endif
24832336}
24842337
24852338READ8_HANDLER( superfx_r_bank1 )
trunk/src/emu/cpu/g65816/g65816.c
r17409r17410
143143extern void g65816i_set_line_E(g65816i_cpu_struct *cpustate, int line, int state);
144144extern int  g65816i_execute_E(g65816i_cpu_struct *cpustate, int cycles);
145145
146extern int bus_5A22_cycle_burst(g65816i_cpu_struct *cpustate, uint addr);
147
148
146149void (*const *const g65816i_opcodes[5])(g65816i_cpu_struct *cpustate) =
147150{
148151   g65816i_opcodes_M0X0,
r17409r17410
525528SNES specific, used to handle master cycles
526529*/
527530
531int bus_5A22_cycle_burst(g65816i_cpu_struct *cpustate, uint addr)
532{
533   if(cpustate->cpu_type == CPU_TYPE_G65816)
534      return 0;
535
536   if(addr & 0x408000) {
537      if(addr & 0x800000) return (1) ? 6 : 8; // TODO: fastROM setting
538      return 8;
539   }
540   if((addr + 0x6000) & 0x4000) return 8;
541   if((addr - 0x4000) & 0x7e00) return 6;
542
543   return 12;
544}
545
546
528547static CPU_INIT( 5a22 )
529548{
530549   g65816i_cpu_struct *cpustate = get_safe_token(device);
trunk/src/emu/cpu/g65816/g65816op.h
r17409r17410
5959INLINE uint g65816i_read_8_normal(g65816i_cpu_struct *cpustate, uint address)
6060{
6161   address = ADDRESS_65816(address);
62   CLOCKS -= (bus_5A22_cycle_burst(cpustate,address));
6263   return g65816_read_8(address);
6364}
6465
6566INLINE uint g65816i_read_8_immediate(g65816i_cpu_struct *cpustate, uint address)
6667{
6768   address = ADDRESS_65816(address);
69   CLOCKS -= (bus_5A22_cycle_burst(cpustate,address));
6870   return g65816_read_8_immediate(address);
6971}
7072
r17409r17410
7678#else
7779   address = ADDRESS_65816(address);
7880#endif
81   CLOCKS -= (bus_5A22_cycle_burst(cpustate,address));
7982   return g65816_read_8(address);
8083}
8184
r17409r17410
9093INLINE void g65816i_write_8_normal(g65816i_cpu_struct *cpustate, uint address, uint value)
9194{
9295   address = ADDRESS_65816(address);
96   CLOCKS -= (bus_5A22_cycle_burst(cpustate,address));
9397   g65816_write_8(address, MAKE_UINT_8(value));
9498}
9599
r17409r17410
101105#else
102106   address = ADDRESS_65816(address);
103107#endif
108   CLOCKS -= (bus_5A22_cycle_burst(cpustate,address));
104109   g65816_write_8(address, MAKE_UINT_8(value));
105110}
106111
trunk/src/emu/cpu/g65816/g65816cm.h
r17409r17410
103103   void (*set_reg)(g65816i_cpu_struct *cpustate, int regnum, uint val);
104104   void (*set_line)(g65816i_cpu_struct *cpustate, int line, int state);
105105   int  (*execute)(g65816i_cpu_struct *cpustate, int cycles);
106   int bus_5A22_cycle_burst(g65816i_cpu_struct *cpustate, uint addr);
106107   uint source;
107108   uint destination;
108109   int ICount;
r17409r17410
114115extern void (*const g65816i_set_reg[])(g65816i_cpu_struct *cpustate, int regnum, uint val);
115116extern void (*const g65816i_set_line[])(g65816i_cpu_struct *cpustate, int line, int state);
116117extern int (*const g65816i_execute[])(g65816i_cpu_struct *cpustate, int cycles);
118extern int bus_5A22_cycle_burst(g65816i_cpu_struct *cpustate, uint addr);
117119
118120#define REGISTER_A      cpustate->a      /* Accumulator */
119121#define REGISTER_B      cpustate->b      /* Accumulator hi byte */
r17409r17410
244246#define CLK_W_SIY      5
245247
246248#define CLK(A)         CLOCKS -= (cpustate->cpu_type == CPU_TYPE_G65816 ? A : A*6)
249#define CLK_BUS(A)      CLOCKS -= A
247250#define USE_ALL_CLKS()   CLOCKS = 0
248251
249252

Previous 199869 Revisions Next


© 1997-2024 The MAME Team