summaryrefslogtreecommitdiffstats
path: root/src/mame/machine/megadriv.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/machine/megadriv.cpp')
-rw-r--r--src/mame/machine/megadriv.cpp95
1 files changed, 59 insertions, 36 deletions
diff --git a/src/mame/machine/megadriv.cpp b/src/mame/machine/megadriv.cpp
index c0a76898b71..3f4d649db2c 100644
--- a/src/mame/machine/megadriv.cpp
+++ b/src/mame/machine/megadriv.cpp
@@ -27,22 +27,40 @@ Known Non-Issues (confirmed on Real Genesis)
#include "includes/megadriv.h"
#include "speaker.h"
+#define LOG_AUDIOBANK (1U << 1) // z80 to 68k space window access at $8000-$ffff
+#define LOG_AUDIOBUS (1U << 2) // z80 bus grants
+#define LOG_AUDIORESET (1U << 3) // z80 reset line
+
+#define VERBOSE (0)
+
+#include "logmacro.h"
+
+#define LOGAUDIOBANK(...) LOGMASKED(LOG_AUDIOBANK, __VA_ARGS__)
+#define LOGAUDIOBUS(...) LOGMASKED(LOG_AUDIOBUS, __VA_ARGS__)
+#define LOGAUDIORESET(...) LOGMASKED(LOG_AUDIORESET, __VA_ARGS__)
+
void md_base_state::megadriv_z80_bank_w(uint16_t data)
{
+ // TODO: menghu crashes here
+ // Tries to setup a bank of 0xff0000 from z80 side (PC=1131) after you talk with the cashier twice.
+ // Without a guard over it game will trash 68k memory causing a crash, works on real HW with everdrive
+ // so not coming from a cart copy protection.
+ // Update: it breaks cfodder BGM on character select at least, therefore we current don't guard against it
+ // Apparently reading 68k RAM from z80 is not recommended by Sega, so *writing* isn't possible lacking bus grant?
m_genz80.z80_bank_addr = ((m_genz80.z80_bank_addr >> 1) | (data << 23)) & 0xff8000;
}
void md_base_state::megadriv_68k_z80_bank_write(uint16_t data)
{
- //logerror("%06x: 68k writing bit to bank register %01x\n", m_maincpu->pc(),data&0x01);
megadriv_z80_bank_w(data & 0x01);
}
void md_base_state::megadriv_z80_z80_bank_w(uint8_t data)
{
- //logerror("%04x: z80 writing bit to bank register %01x\n", m_maincpu->pc(),data&0x01);
+ LOGAUDIOBANK("%s: port $6000 write 0x%02x ", machine().describe_context(), data);
megadriv_z80_bank_w(data & 0x01);
+ LOGAUDIOBANK("Current bank %08x\n", m_genz80.z80_bank_addr);
}
uint8_t md_base_state::megadriv_68k_YM2612_read(offs_t offset, uint8_t mem_mask)
@@ -54,7 +72,7 @@ uint8_t md_base_state::megadriv_68k_YM2612_read(offs_t offset, uint8_t mem_mask)
}
else
{
- logerror("%s: 68000 attempting to access YM2612 (read) without bus\n", machine().describe_context());
+ LOG("%s: 68000 attempting to access YM2612 (read) without bus\n", machine().describe_context());
return 0;
}
@@ -72,7 +90,7 @@ void md_base_state::megadriv_68k_YM2612_write(offs_t offset, uint8_t data, uint8
}
else
{
- logerror("%s: 68000 attempting to access YM2612 (write) without bus\n", machine().describe_context());
+ LOG("%s: 68000 attempting to access YM2612 (write) without bus\n", machine().describe_context());
}
}
@@ -309,8 +327,10 @@ uint16_t md_base_state::megadriv_68k_io_read(offs_t offset)
switch (offset)
{
case 0:
- logerror("%06x read version register\n", m_maincpu->pc());
- retdata = m_version_hi_nibble | 0x01; // Version number contained in bits 3-0
+ LOG("%06x read version register\n", m_maincpu->pc());
+ // Version number contained in bits 3-0
+ // TODO: non-TMSS BIOSes must return 0 here
+ retdata = m_version_hi_nibble | 0x01;
break;
/* Joystick Port Registers */
@@ -486,15 +506,13 @@ uint16_t md_base_state::megadriv_68k_read_z80_ram(offs_t offset, uint16_t mem_ma
}
else
{
- logerror("%06x: 68000 attempting to access Z80 (read) address space without bus\n", m_maincpu->pc());
+ LOG("%06x: 68000 attempting to access Z80 (read) address space without bus\n", m_maincpu->pc());
return machine().rand();
}
}
void md_base_state::megadriv_68k_write_z80_ram(offs_t offset, uint16_t data, uint16_t mem_mask)
{
- //logerror("write z80 ram\n");
-
if ((m_genz80.z80_has_bus == 0) && (m_genz80.z80_is_reset == 0))
{
if (!ACCESSING_BITS_0_7) // byte (MSB) access
@@ -505,30 +523,33 @@ void md_base_state::megadriv_68k_write_z80_ram(offs_t offset, uint16_t data, uin
{
m_genz80.z80_prgram[(offset<<1)^1] = (data & 0x00ff);
}
- else // for WORD access only the MSB is used, LSB is ignored
+ else
{
+ // for WORD access only the MSB is used, LSB is ignored
m_genz80.z80_prgram[(offset<<1)] = (data & 0xff00) >> 8;
}
}
else
{
- logerror("%06x: 68000 attempting to access Z80 (write) address space without bus\n", m_maincpu->pc());
+ LOG("%06x: 68000 attempting to access Z80 (write) address space without bus\n", m_maincpu->pc());
}
}
-
+/*
+ * ddragon, beast, superoff, and timekill have buggy sound programs.
+ * They request the bus, then have a loop which waits for the bus
+ * to be unavailable, checking for a 0 value due to bad coding. The real hardware
+ * appears to return bits of the next instruction in the unused bits, thus meaning
+ * the value is never zero. Time Killers is the most fussy, and doesn't like the
+ * read_next_instruction function from system16, so I just return a random value
+ * in the unused bits
+ */
uint16_t md_base_state::megadriv_68k_check_z80_bus(offs_t offset, uint16_t mem_mask)
{
uint16_t retvalue;
- /* Double Dragon, Shadow of the Beast, Super Off Road, and Time Killers have buggy
- sound programs. They request the bus, then have a loop which waits for the bus
- to be unavailable, checking for a 0 value due to bad coding. The real hardware
- appears to return bits of the next instruction in the unused bits, thus meaning
- the value is never zero. Time Killers is the most fussy, and doesn't like the
- read_next_instruction function from system16, so I just return a random value
- in the unused bits */
- uint16_t nextvalue = machine().rand();//read_next_instruction(space)&0xff00;
+
+ uint16_t nextvalue = machine().rand(); //read_next_instruction(space)&0xff00;
/* Check if the 68k has the z80 bus */
@@ -537,13 +558,13 @@ uint16_t md_base_state::megadriv_68k_check_z80_bus(offs_t offset, uint16_t mem_m
if (m_genz80.z80_has_bus || m_genz80.z80_is_reset) retvalue = nextvalue | 0x0100;
else retvalue = (nextvalue & 0xfeff);
- //logerror("%06x: 68000 check z80 Bus (byte MSB access) returning %04x mask %04x\n", m_maincpu->pc(),retvalue, mem_mask);
+ LOGAUDIOBUS("%06x: 68000 check z80 Bus (byte MSB access) returning %04x mask %04x\n", m_maincpu->pc(),retvalue, mem_mask);
return retvalue;
}
else if (!ACCESSING_BITS_8_15) // is this valid?
{
- //logerror("%06x: 68000 check z80 Bus (byte LSB access) %04x\n", m_maincpu->pc(),mem_mask);
+ LOGAUDIOBUS("%06x: 68000 check z80 Bus (byte LSB access) %04x\n", m_maincpu->pc(), mem_mask);
if (m_genz80.z80_has_bus || m_genz80.z80_is_reset) retvalue = 0x0001;
else retvalue = 0x0000;
@@ -551,7 +572,7 @@ uint16_t md_base_state::megadriv_68k_check_z80_bus(offs_t offset, uint16_t mem_m
}
else
{
- //logerror("%06x: 68000 check z80 Bus (word access) %04x\n", m_maincpu->pc(),mem_mask);
+ LOGAUDIOBUS("%06x: 68000 check z80 Bus (word access) %04x\n", m_maincpu->pc(),mem_mask);
if (m_genz80.z80_has_bus || m_genz80.z80_is_reset) retvalue = nextvalue | 0x0100;
else retvalue = (nextvalue & 0xfeff);
@@ -564,6 +585,7 @@ uint16_t md_base_state::megadriv_68k_check_z80_bus(offs_t offset, uint16_t mem_m
TIMER_CALLBACK_MEMBER(md_base_state::megadriv_z80_run_state)
{
/* Is the z80 RESET line pulled? */
+ // TODO: Z80 /RESET
if (m_genz80.z80_is_reset)
{
m_z80snd->reset();
@@ -573,6 +595,7 @@ TIMER_CALLBACK_MEMBER(md_base_state::megadriv_z80_run_state)
else
{
/* Check if z80 has the bus */
+ // TODO: Z80 /BUSREQ
if (m_genz80.z80_has_bus)
m_z80snd->resume(SUSPEND_REASON_HALT);
else
@@ -588,12 +611,12 @@ void md_base_state::megadriv_68k_req_z80_bus(offs_t offset, uint16_t data, uint1
{
if (data & 0x0100)
{
- //logerror("%06x: 68000 request z80 Bus (byte MSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
+ LOGAUDIOBUS("%06x: 68000 request z80 Bus (byte MSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
m_genz80.z80_has_bus = 0;
}
else
{
- //logerror("%06x: 68000 return z80 Bus (byte MSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
+ LOGAUDIOBUS("%06x: 68000 return z80 Bus (byte MSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
m_genz80.z80_has_bus = 1;
}
}
@@ -601,12 +624,12 @@ void md_base_state::megadriv_68k_req_z80_bus(offs_t offset, uint16_t data, uint1
{
if (data & 0x0001)
{
- //logerror("%06x: 68000 request z80 Bus (byte LSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
+ LOGAUDIOBUS("%06x: 68000 request z80 Bus (byte LSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
m_genz80.z80_has_bus = 0;
}
else
{
- //logerror("%06x: 68000 return z80 Bus (byte LSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
+ LOGAUDIOBUS("%06x: 68000 return z80 Bus (byte LSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
m_genz80.z80_has_bus = 1;
}
}
@@ -614,12 +637,12 @@ void md_base_state::megadriv_68k_req_z80_bus(offs_t offset, uint16_t data, uint1
{
if (data & 0x0100)
{
- //logerror("%06x: 68000 request z80 Bus (word access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
+ LOGAUDIOBUS("%06x: 68000 request z80 Bus (word access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
m_genz80.z80_has_bus = 0;
}
else
{
- //logerror("%06x: 68000 return z80 Bus (byte LSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
+ LOGAUDIOBUS("%06x: 68000 return z80 Bus (byte LSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
m_genz80.z80_has_bus = 1;
}
}
@@ -635,12 +658,12 @@ void md_base_state::megadriv_68k_req_z80_reset(offs_t offset, uint16_t data, uin
{
if (data & 0x0100)
{
- //logerror("%06x: 68000 clear z80 reset (byte MSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
+ LOGAUDIORESET("%06x: 68000 clear z80 reset (byte MSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
m_genz80.z80_is_reset = 0;
}
else
{
- //logerror("%06x: 68000 start z80 reset (byte MSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
+ LOGAUDIORESET("%06x: 68000 start z80 reset (byte MSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
m_genz80.z80_is_reset = 1;
}
}
@@ -648,12 +671,12 @@ void md_base_state::megadriv_68k_req_z80_reset(offs_t offset, uint16_t data, uin
{
if (data & 0x0001)
{
- //logerror("%06x: 68000 clear z80 reset (byte LSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
+ LOGAUDIORESET("%06x: 68000 clear z80 reset (byte LSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
m_genz80.z80_is_reset = 0;
}
else
{
- //logerror("%06x: 68000 start z80 reset (byte LSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
+ LOGAUDIORESET("%06x: 68000 start z80 reset (byte LSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
m_genz80.z80_is_reset = 1;
}
}
@@ -661,12 +684,12 @@ void md_base_state::megadriv_68k_req_z80_reset(offs_t offset, uint16_t data, uin
{
if (data & 0x0100)
{
- //logerror("%06x: 68000 clear z80 reset (word access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
+ LOGAUDIORESET("%06x: 68000 clear z80 reset (word access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
m_genz80.z80_is_reset = 0;
}
else
{
- //logerror("%06x: 68000 start z80 reset (byte LSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
+ LOGAUDIORESET("%06x: 68000 start z80 reset (byte LSB access) %04x %04x\n", m_maincpu->pc(),data,mem_mask);
m_genz80.z80_is_reset = 1;
}
}
@@ -756,7 +779,7 @@ void md_base_state::megadriv_z80_map(address_map &map)
void md_base_state::megadriv_z80_io_map(address_map &map)
{
map.global_mask(0xff);
- map(0x0000, 0xff).noprw();
+ map(0x00, 0xff).noprw();
}
uint32_t md_base_state::screen_update_megadriv(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)