mirror of
https://github.com/holub/mame
synced 2025-10-05 00:38:58 +03:00
315_5313.cpp DMA / Timer Updates, Correct refresh rate and timer rate related to systems when using mega drive VDP (#5470)
* Correct timer rate related to screen refresh rate for 315_5313.cpp, megacd.cpp, mega32x.cpp 315_5313.cpp : Simplify DMA behavior, Add notes, Simplify handlers, Fix spacing, Reduce unnecessary lines, Use shorter / correct type values, Fix debugger issue megadriv.cpp, segac2.cpp, calcune.cpp : Correct screen refresh rate, Add notes (source : https://segaretro.org/Sega_Mega_Drive/Technical_specifications) megadriv.cpp : Allow Z80 VDP reading, Correct VDP sound output calcune.cpp : Fix naming, Add notes * 315_5313.cpp : Reduce unnecessary lines, Fix spacings * 315_5313.cpp : Use struct for nametable, Reduce duplicates, Fix spacing, Reduce unnecessary lines * 315_5313.cpp : Fix spacing * 315_5313.cpp : Fix spacing, Reduce duplicates, Unnecessary lines, Fix type values
This commit is contained in:
parent
98e518f1b6
commit
d1acfba2c7
File diff suppressed because it is too large
Load Diff
@ -15,15 +15,15 @@ class sega315_5313_device : public sega315_5313_mode4_device
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
sega315_5313_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag)
|
||||
sega315_5313_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, T &&cpu_tag)
|
||||
: sega315_5313_device(mconfig, tag, owner, clock)
|
||||
{
|
||||
m_cpu68k.set_tag(std::forward<T>(cpu_tag));
|
||||
}
|
||||
|
||||
sega315_5313_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
sega315_5313_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
typedef device_delegate<void (int x, uint32_t priority, uint32_t &lineptr)> md_32x_scanline_delegate;
|
||||
typedef device_delegate<void (int x, u32 priority, u32 &lineptr)> md_32x_scanline_delegate;
|
||||
typedef device_delegate<void (int scanline, int irq6)> md_32x_interrupt_delegate;
|
||||
typedef device_delegate<void (int scanline)> md_32x_scanline_helper_delegate;
|
||||
|
||||
@ -44,8 +44,8 @@ public:
|
||||
|
||||
int m_palwrite_base; // if we want to write to the actual MAME palette..
|
||||
|
||||
DECLARE_READ16_MEMBER( vdp_r );
|
||||
DECLARE_WRITE16_MEMBER( vdp_w );
|
||||
u16 vdp_r(offs_t offset, u16 mem_mask = ~0);
|
||||
void vdp_w(offs_t offset, u16 data, u16 mem_mask = ~0);
|
||||
|
||||
int get_scanline_counter();
|
||||
|
||||
@ -65,10 +65,9 @@ public:
|
||||
void set_vdp_pal(bool pal) { m_vdp_pal = pal ? 1 : 0; }
|
||||
void set_use_cram(int cram) { m_use_cram = cram; }
|
||||
void set_dma_delay(int delay) { m_dma_delay = delay; }
|
||||
int get_framerate() { return m_framerate; }
|
||||
double get_framerate() { return has_screen() ? screen().frame_period().as_hz() : double(m_framerate); }
|
||||
int get_imode() { return m_imode; }
|
||||
|
||||
|
||||
void vdp_clear_bitmap()
|
||||
{
|
||||
if (m_render_bitmap)
|
||||
@ -76,14 +75,14 @@ public:
|
||||
}
|
||||
|
||||
std::unique_ptr<bitmap_rgb32> m_render_bitmap;
|
||||
std::unique_ptr<uint32_t[]> m_render_line;
|
||||
std::unique_ptr<uint16_t[]> m_render_line_raw;
|
||||
std::unique_ptr<u32[]> m_render_line;
|
||||
std::unique_ptr<u16[]> m_render_line_raw;
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER( megadriv_scanline_timer_callback_alt_timing );
|
||||
TIMER_DEVICE_CALLBACK_MEMBER( megadriv_scanline_timer_callback );
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(megadriv_scanline_timer_callback_alt_timing);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(megadriv_scanline_timer_callback);
|
||||
timer_device* m_megadriv_scanline_timer;
|
||||
|
||||
inline uint16_t vdp_get_word_from_68k_mem(uint32_t source);
|
||||
inline u16 vdp_get_word_from_68k_mem(u32 source);
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
@ -100,13 +99,37 @@ protected:
|
||||
md_32x_scanline_helper_delegate m_32x_scanline_helper_func;
|
||||
|
||||
private:
|
||||
// vdp code defines
|
||||
const u8 CODE_DMA() { return m_vdp_code & 0x20; }
|
||||
const u8 CODE_VRAM_COPY() { return m_vdp_code & 0x10; }
|
||||
const u8 CODE_VRAM_READ() { return (m_vdp_code & 0x0f) == 0x00; }
|
||||
const u8 CODE_VRAM_WRITE() { return (m_vdp_code & 0x0f) == 0x01; }
|
||||
const u8 CODE_CRAM_WRITE() { return (m_vdp_code & 0x0f) == 0x03; }
|
||||
const u8 CODE_VSRAM_READ() { return (m_vdp_code & 0x0f) == 0x04; }
|
||||
const u8 CODE_VSRAM_WRITE() { return (m_vdp_code & 0x0f) == 0x05; }
|
||||
const u8 CODE_CRAM_READ() { return (m_vdp_code & 0x0f) == 0x08; }
|
||||
//const u8 CODE_VRAM_READ_BYTE() { return (m_vdp_code & 0x0f) == 0x0c; } // undocumented, unhandled
|
||||
|
||||
// nametable
|
||||
struct nametable_t {
|
||||
u16 addr;
|
||||
bool xflip;
|
||||
bool yflip;
|
||||
u16 colour;
|
||||
u16 pri;
|
||||
};
|
||||
void get_window_tilebase(int &tile_base, u16 base, int vcolumn, int window_hsize, int hcolumn);
|
||||
void get_vcolumn_tilebase(int &vcolumn, int &tile_base, u16 base, int vscroll, int scanline, int vsize, int hsize, int hcolumn);
|
||||
void get_nametable(u16 tile_base, nametable_t &tile, int vcolumn);
|
||||
inline void draw_tile(nametable_t tile, int start, int end, int &dpos, bool is_fg);
|
||||
|
||||
int m_command_pending; // 2nd half of command pending..
|
||||
uint16_t m_command_part1;
|
||||
uint16_t m_command_part2;
|
||||
uint8_t m_vdp_code;
|
||||
uint16_t m_vdp_address;
|
||||
uint8_t m_vram_fill_pending;
|
||||
uint16_t m_vram_fill_length;
|
||||
u16 m_command_part1;
|
||||
u16 m_command_part2;
|
||||
u8 m_vdp_code;
|
||||
u16 m_vdp_address;
|
||||
u8 m_vram_fill_pending;
|
||||
u16 m_vram_fill_length;
|
||||
int m_irq4counter;
|
||||
int m_imode_odd_frame;
|
||||
int m_sprite_collision;
|
||||
@ -129,13 +152,13 @@ private:
|
||||
int m_use_cram; // c2 uses it's own palette ram, so it sets this to 0
|
||||
int m_dma_delay; // SVP and SegaCD have some 'lag' in DMA transfers
|
||||
|
||||
std::unique_ptr<uint16_t[]> m_regs;
|
||||
std::unique_ptr<uint16_t[]> m_vram;
|
||||
std::unique_ptr<uint16_t[]> m_cram;
|
||||
std::unique_ptr<uint16_t[]> m_vsram;
|
||||
std::unique_ptr<u16[]> m_regs;
|
||||
std::unique_ptr<u16[]> m_vram;
|
||||
std::unique_ptr<u16[]> m_cram;
|
||||
std::unique_ptr<u16[]> m_vsram;
|
||||
/* The VDP keeps a 0x400 byte on-chip cache of the Sprite Attribute Table
|
||||
to speed up processing, Castlevania Bloodlines abuses this on the upside down level */
|
||||
std::unique_ptr<uint16_t[]> m_internal_sprite_attribute_table;
|
||||
std::unique_ptr<u16[]> m_internal_sprite_attribute_table;
|
||||
|
||||
// these are used internally by the VDP to schedule when after the start of a scanline
|
||||
// to trigger the various interrupts / rendering to our bitmap, bit of a hack really
|
||||
@ -143,29 +166,30 @@ private:
|
||||
emu_timer* m_irq4_on_timer;
|
||||
emu_timer* m_render_timer;
|
||||
|
||||
uint16_t vdp_vram_r(void);
|
||||
uint16_t vdp_vsram_r(void);
|
||||
uint16_t vdp_cram_r(void);
|
||||
u16 vdp_vram_r(void);
|
||||
u16 vdp_vsram_r(void);
|
||||
u16 vdp_cram_r(void);
|
||||
|
||||
void insta_68k_to_cram_dma(uint32_t source,uint16_t length);
|
||||
void insta_68k_to_vsram_dma(uint32_t source,uint16_t length);
|
||||
void insta_68k_to_vram_dma(uint32_t source,int length);
|
||||
void insta_vram_copy(uint32_t source, uint16_t length);
|
||||
void insta_68k_to_cram_dma(u32 source, u16 length);
|
||||
void insta_68k_to_vsram_dma(u32 source, u16 length);
|
||||
void insta_68k_to_vram_dma(u32 source, int length);
|
||||
void insta_vram_copy(u32 source, u16 length);
|
||||
|
||||
void vdp_vram_write(uint16_t data);
|
||||
void vdp_cram_write(uint16_t data);
|
||||
void vdp_vram_write(u16 data);
|
||||
void vdp_cram_write(u16 data);
|
||||
void write_cram_value(int offset, int data);
|
||||
void vdp_vsram_write(uint16_t data);
|
||||
void vdp_vsram_write(u16 data);
|
||||
|
||||
void vdp_set_register(int regnum, uint8_t value);
|
||||
void vdp_address_inc();
|
||||
void vdp_set_register(int regnum, u8 value);
|
||||
|
||||
void handle_dma_bits();
|
||||
|
||||
uint16_t get_hposition();
|
||||
uint16_t megadriv_read_hv_counters();
|
||||
u16 get_hposition();
|
||||
u16 megadriv_read_hv_counters();
|
||||
|
||||
uint16_t ctrl_port_r();
|
||||
uint16_t data_port_r();
|
||||
u16 ctrl_port_r();
|
||||
u16 data_port_r();
|
||||
void data_port_w(int data);
|
||||
void ctrl_port_w(int data);
|
||||
void update_code_and_address(void);
|
||||
@ -176,10 +200,10 @@ private:
|
||||
void render_videobuffer_to_screenbuffer(int scanline);
|
||||
|
||||
/* variables used during emulation - not saved */
|
||||
std::unique_ptr<uint8_t[]> m_sprite_renderline;
|
||||
std::unique_ptr<uint8_t[]> m_highpri_renderline;
|
||||
std::unique_ptr<uint32_t[]> m_video_renderline;
|
||||
std::unique_ptr<uint16_t[]> m_palette_lookup;
|
||||
std::unique_ptr<u8[]> m_sprite_renderline;
|
||||
std::unique_ptr<u8[]> m_highpri_renderline;
|
||||
std::unique_ptr<u32[]> m_video_renderline;
|
||||
std::unique_ptr<u16[]> m_palette_lookup;
|
||||
|
||||
address_space *m_space68k;
|
||||
required_device<m68000_base_device> m_cpu68k;
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "emupal.h"
|
||||
#include "speaker.h"
|
||||
|
||||
#define MASTER_CLOCK_NTSC 53693175
|
||||
#define OSC1_CLOCK 53693175 // same as NTSC genesis / mega drive master clock
|
||||
|
||||
class calcune_state : public driver_device
|
||||
{
|
||||
@ -111,17 +111,17 @@ WRITE16_MEMBER(calcune_state::cal_770000_w)
|
||||
READ16_MEMBER(calcune_state::cal_vdp_r)
|
||||
{
|
||||
if (!vdp_state)
|
||||
return m_vdp->vdp_r(space, offset, mem_mask);
|
||||
return m_vdp->vdp_r(offset, mem_mask);
|
||||
else
|
||||
return m_vdp2->vdp_r(space, offset, mem_mask);
|
||||
return m_vdp2->vdp_r(offset, mem_mask);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(calcune_state::cal_vdp_w)
|
||||
{
|
||||
if (!vdp_state)
|
||||
m_vdp->vdp_w(space, offset, data, mem_mask);
|
||||
m_vdp->vdp_w(offset, data, mem_mask);
|
||||
else
|
||||
m_vdp2->vdp_w(space, offset, data, mem_mask);
|
||||
m_vdp2->vdp_w(offset, data, mem_mask);
|
||||
}
|
||||
|
||||
void calcune_state::calcune_map(address_map &map)
|
||||
@ -251,23 +251,24 @@ MACHINE_START_MEMBER(calcune_state,calcune)
|
||||
|
||||
void calcune_state::calcune(machine_config &config)
|
||||
{
|
||||
M68000(config, m_maincpu, MASTER_CLOCK_NTSC / 7); /* 7.67 MHz */
|
||||
M68000(config, m_maincpu, OSC1_CLOCK / 7); /* 7.67 MHz */
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &calcune_state::calcune_map);
|
||||
m_maincpu->set_irq_acknowledge_callback(FUNC(calcune_state::genesis_int_callback));
|
||||
|
||||
Z80(config, "z80", MASTER_CLOCK_NTSC / 15).set_disable(); /* 3.58 MHz, no code is ever uploaded for the Z80, so it's unused here even if it is present on the PCB */
|
||||
Z80(config, "z80", OSC1_CLOCK / 15).set_disable(); /* 3.58 MHz, no code is ever uploaded for the Z80, so it's unused here even if it is present on the PCB */
|
||||
|
||||
MCFG_MACHINE_START_OVERRIDE(calcune_state,calcune)
|
||||
MCFG_MACHINE_RESET_OVERRIDE(calcune_state,calcune)
|
||||
|
||||
screen_device &screen(SCREEN(config, "megadriv", SCREEN_TYPE_RASTER));
|
||||
screen.set_refresh_hz(60);
|
||||
screen.set_refresh_hz(double(OSC1_CLOCK) / 10.0 / 262.0 / 342.0); // same as SMS?
|
||||
// screen.set_refresh_hz(double(OSC1_CLOCK) / 8.0 / 262.0 / 427.0); // or 427 Htotal?
|
||||
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); // Vblank handled manually.
|
||||
screen.set_size(64*8, 620);
|
||||
screen.set_visarea(0, 40*8-1, 0, 28*8-1);
|
||||
screen.set_screen_update(FUNC(calcune_state::screen_update_calcune));
|
||||
|
||||
SEGA315_5313(config, m_vdp, MASTER_CLOCK_NTSC, m_maincpu);
|
||||
SEGA315_5313(config, m_vdp, OSC1_CLOCK, m_maincpu);
|
||||
m_vdp->set_is_pal(false);
|
||||
m_vdp->snd_irq().set(FUNC(calcune_state::vdp_sndirqline_callback_genesis_z80));
|
||||
m_vdp->lv6_irq().set(FUNC(calcune_state::vdp_lv6irqline_callback_genesis_68k));
|
||||
@ -278,7 +279,7 @@ void calcune_state::calcune(machine_config &config)
|
||||
m_vdp->add_route(ALL_OUTPUTS, "lspeaker", 0.25);
|
||||
m_vdp->add_route(ALL_OUTPUTS, "rspeaker", 0.25);
|
||||
|
||||
SEGA315_5313(config, m_vdp2, MASTER_CLOCK_NTSC, m_maincpu);
|
||||
SEGA315_5313(config, m_vdp2, OSC1_CLOCK, m_maincpu);
|
||||
m_vdp2->set_is_pal(false);
|
||||
// are these not hooked up or should they OR with the other lines?
|
||||
// m_vdp2->snd_irq().set(FUNC(calcune_state::vdp_sndirqline_callback_genesis_z80));
|
||||
|
@ -609,18 +609,17 @@ void md_cons_state::genesis_32x(machine_config &config)
|
||||
m_vdp->set_md_32x_scanline_helper(FUNC(md_cons_state::_32x_scanline_helper_callback), this);
|
||||
m_vdp->set_md_32x_interrupt(FUNC(md_cons_state::_32x_interrupt_callback), this);
|
||||
m_vdp->reset_routes();
|
||||
m_vdp->add_route(ALL_OUTPUTS, "lspeaker", (0.25)/2);
|
||||
m_vdp->add_route(ALL_OUTPUTS, "rspeaker", (0.25)/2);
|
||||
m_vdp->add_route(ALL_OUTPUTS, "lspeaker", (0.50)/2);
|
||||
m_vdp->add_route(ALL_OUTPUTS, "rspeaker", (0.50)/2);
|
||||
|
||||
SEGA_32X_NTSC(config, m_32x, (MASTER_CLOCK_NTSC * 3) / 7, m_maincpu, m_scan_timer);
|
||||
m_32x->set_screen("megadriv");
|
||||
|
||||
subdevice<screen_device>("megadriv")->screen_vblank().set(FUNC(md_cons_state::screen_vblank_console));
|
||||
|
||||
// we need to remove and re-add the YM because the balance is different
|
||||
// due to MAME / MESS having severe issues if the dac output is > 0.40? (sound is corrupted even if DAC is silent?!)
|
||||
config.device_remove("ymsnd");
|
||||
|
||||
YM2612(config, m_ymsnd, MASTER_CLOCK_NTSC/7);
|
||||
m_ymsnd->reset_routes();
|
||||
m_ymsnd->add_route(0, "lspeaker", (0.50)/2);
|
||||
m_ymsnd->add_route(1, "rspeaker", (0.50)/2);
|
||||
|
||||
@ -643,18 +642,17 @@ void md_cons_state::mdj_32x(machine_config &config)
|
||||
m_vdp->set_md_32x_scanline_helper(FUNC(md_cons_state::_32x_scanline_helper_callback), this);
|
||||
m_vdp->set_md_32x_interrupt(FUNC(md_cons_state::_32x_interrupt_callback), this);
|
||||
m_vdp->reset_routes();
|
||||
m_vdp->add_route(ALL_OUTPUTS, "lspeaker", (0.25)/2);
|
||||
m_vdp->add_route(ALL_OUTPUTS, "rspeaker", (0.25)/2);
|
||||
m_vdp->add_route(ALL_OUTPUTS, "lspeaker", (0.50)/2);
|
||||
m_vdp->add_route(ALL_OUTPUTS, "rspeaker", (0.50)/2);
|
||||
|
||||
SEGA_32X_NTSC(config, m_32x, (MASTER_CLOCK_NTSC * 3) / 7, m_maincpu, m_scan_timer);
|
||||
m_32x->set_screen("megadriv");
|
||||
|
||||
subdevice<screen_device>("megadriv")->screen_vblank().set(FUNC(md_cons_state::screen_vblank_console));
|
||||
|
||||
// we need to remove and re-add the sound system because the balance is different
|
||||
// due to MAME / MESS having severe issues if the dac output is > 0.40? (sound is corrupted even if DAC is silent?!)
|
||||
config.device_remove("ymsnd");
|
||||
|
||||
YM2612(config, m_ymsnd, MASTER_CLOCK_NTSC/7);
|
||||
m_ymsnd->reset_routes();
|
||||
m_ymsnd->add_route(0, "lspeaker", (0.50)/2);
|
||||
m_ymsnd->add_route(1, "rspeaker", (0.50)/2);
|
||||
|
||||
@ -677,18 +675,17 @@ void md_cons_state::md_32x(machine_config &config)
|
||||
m_vdp->set_md_32x_scanline_helper(FUNC(md_cons_state::_32x_scanline_helper_callback), this);
|
||||
m_vdp->set_md_32x_interrupt(FUNC(md_cons_state::_32x_interrupt_callback), this);
|
||||
m_vdp->reset_routes();
|
||||
m_vdp->add_route(ALL_OUTPUTS, "lspeaker", (0.25)/2);
|
||||
m_vdp->add_route(ALL_OUTPUTS, "rspeaker", (0.25)/2);
|
||||
m_vdp->add_route(ALL_OUTPUTS, "lspeaker", (0.50)/2);
|
||||
m_vdp->add_route(ALL_OUTPUTS, "rspeaker", (0.50)/2);
|
||||
|
||||
SEGA_32X_PAL(config, m_32x, (MASTER_CLOCK_PAL * 3) / 7, m_maincpu, m_scan_timer);
|
||||
m_32x->set_screen("megadriv");
|
||||
|
||||
subdevice<screen_device>("megadriv")->screen_vblank().set(FUNC(md_cons_state::screen_vblank_console));
|
||||
|
||||
// we need to remove and re-add the sound system because the balance is different
|
||||
// due to MAME / MESS having severe issues if the dac output is > 0.40? (sound is corrupted even if DAC is silent?!)
|
||||
config.device_remove("ymsnd");
|
||||
|
||||
YM2612(config, m_ymsnd, MASTER_CLOCK_NTSC/7);
|
||||
m_ymsnd->reset_routes();
|
||||
m_ymsnd->add_route(0, "lspeaker", (0.50)/2);
|
||||
m_ymsnd->add_route(1, "rspeaker", (0.50)/2);
|
||||
|
||||
@ -744,6 +741,7 @@ void md_cons_state::genesis_scd(machine_config &config)
|
||||
SEGA_SEGACD_US(config, m_segacd, 0);
|
||||
m_segacd->set_palette("gen_vdp:palette");
|
||||
m_segacd->set_hostcpu(m_maincpu);
|
||||
m_segacd->set_screen("megadriv");
|
||||
|
||||
CDROM(config, "cdrom").set_interface("scd_cdrom");
|
||||
|
||||
@ -762,6 +760,7 @@ void md_cons_state::md_scd(machine_config &config)
|
||||
SEGA_SEGACD_EUROPE(config, m_segacd, 0);
|
||||
m_segacd->set_palette("gen_vdp:palette");
|
||||
m_segacd->set_hostcpu(m_maincpu);
|
||||
m_segacd->set_screen("megadriv");
|
||||
|
||||
CDROM(config, "cdrom").set_interface("scd_cdrom");
|
||||
|
||||
@ -780,6 +779,7 @@ void md_cons_state::mdj_scd(machine_config &config)
|
||||
SEGA_SEGACD_JAPAN(config, m_segacd, 0);
|
||||
m_segacd->set_palette("gen_vdp:palette");
|
||||
m_segacd->set_hostcpu(m_maincpu);
|
||||
m_segacd->set_screen("megadriv");
|
||||
|
||||
CDROM(config, "cdrom").set_interface("scd_cdrom");
|
||||
|
||||
@ -795,6 +795,7 @@ void md_cons_state::genesis_32x_scd(machine_config &config)
|
||||
SEGA_SEGACD_US(config, m_segacd, 0);
|
||||
m_segacd->set_palette("gen_vdp:palette");
|
||||
m_segacd->set_hostcpu(m_maincpu);
|
||||
m_segacd->set_screen("megadriv");
|
||||
|
||||
CDROM(config, "cdrom").set_interface("scd_cdrom");
|
||||
|
||||
@ -814,6 +815,7 @@ void md_cons_state::md_32x_scd(machine_config &config)
|
||||
SEGA_SEGACD_EUROPE(config, m_segacd, 0);
|
||||
m_segacd->set_palette("gen_vdp:palette");
|
||||
m_segacd->set_hostcpu(m_maincpu);
|
||||
m_segacd->set_screen("megadriv");
|
||||
|
||||
CDROM(config, "cdrom").set_interface("scd_cdrom");
|
||||
|
||||
@ -833,6 +835,7 @@ void md_cons_state::mdj_32x_scd(machine_config &config)
|
||||
SEGA_SEGACD_JAPAN(config, m_segacd, 0);
|
||||
m_segacd->set_palette("gen_vdp:palette");
|
||||
m_segacd->set_hostcpu(m_maincpu);
|
||||
m_segacd->set_screen("megadriv");
|
||||
|
||||
CDROM(config, "cdrom").set_interface("scd_cdrom");
|
||||
|
||||
|
@ -1577,7 +1577,8 @@ void segac2_state::segac(machine_config &config)
|
||||
TIMER(config, "scantimer").configure_scanline("gen_vdp", FUNC(sega315_5313_device::megadriv_scanline_timer_callback_alt_timing), "megadriv", 0, 1);
|
||||
|
||||
screen_device &screen(SCREEN(config, "megadriv", SCREEN_TYPE_RASTER));
|
||||
screen.set_refresh_hz(60);
|
||||
screen.set_refresh_hz(double(XL2_CLOCK.value()) / 10.0 / 262.0 / 342.0); // same as SMS?
|
||||
// screen.set_refresh_hz(double(XL2_CLOCK.value()) / 8.0 / 262.0 / 427.0); // or 427 Htotal?
|
||||
screen.set_size(512, 262);
|
||||
screen.set_visarea(0, 32*8-1, 0, 28*8-1);
|
||||
screen.set_screen_update(FUNC(segac2_state::screen_update_segac2_new));
|
||||
|
@ -101,8 +101,8 @@ private:
|
||||
DECLARE_WRITE_LINE_MEMBER(vdp_lv6irqline_callback_s18);
|
||||
DECLARE_WRITE_LINE_MEMBER(vdp_lv4irqline_callback_s18);
|
||||
|
||||
DECLARE_READ16_MEMBER( genesis_vdp_r ) { return m_vdp->vdp_r(space, offset, mem_mask); }
|
||||
DECLARE_WRITE16_MEMBER( genesis_vdp_w ) { m_vdp->vdp_w(space, offset, data, mem_mask); }
|
||||
DECLARE_READ16_MEMBER( genesis_vdp_r ) { return m_vdp->vdp_r(offset, mem_mask); }
|
||||
DECLARE_WRITE16_MEMBER( genesis_vdp_w ) { m_vdp->vdp_w(offset, data, mem_mask); }
|
||||
DECLARE_WRITE16_MEMBER( tileram_w ) { m_segaic16vid->tileram_w(space, offset, data, mem_mask); }
|
||||
DECLARE_WRITE16_MEMBER( textram_w ) { m_segaic16vid->textram_w(space, offset, data, mem_mask); }
|
||||
|
||||
|
@ -225,6 +225,7 @@ DEFINE_DEVICE_TYPE(SEGA_32X_PAL, sega_32x_pal_device, "sega_32x_pal", "Sega 3
|
||||
sega_32x_device::sega_32x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, type, tag, owner, clock)
|
||||
, device_palette_interface(mconfig, *this)
|
||||
, device_video_interface(mconfig, *this, false)
|
||||
, m_sh2_shared(*this, "sh2_shared")
|
||||
, m_main_cpu(*this, finder_base::DUMMY_TAG)
|
||||
, m_master_cpu(*this, "32x_master_sh2")
|
||||
@ -942,21 +943,25 @@ WRITE16_MEMBER( sega_32x_device::m68k_pwm_w )
|
||||
|
||||
uint16_t sega_32x_device::get_hposition(void)
|
||||
{
|
||||
attotime time_elapsed_since_megadriv_scanline_timer;
|
||||
uint16_t value4;
|
||||
|
||||
time_elapsed_since_megadriv_scanline_timer = m_scan_timer->time_elapsed();
|
||||
|
||||
if (time_elapsed_since_megadriv_scanline_timer.attoseconds() < (ATTOSECONDS_PER_SECOND/m_framerate /m_total_scanlines))
|
||||
if (get_framerate() > 0.0)
|
||||
{
|
||||
value4 = (uint16_t)(MAX_HPOSITION*((double)(time_elapsed_since_megadriv_scanline_timer.attoseconds()) / (double)(ATTOSECONDS_PER_SECOND/m_framerate /m_total_scanlines)));
|
||||
}
|
||||
else /* in some cases (probably due to rounding errors) we get some stupid results (the odd huge value where the time elapsed is much higher than the scanline time??!).. hopefully by clamping the result to the maximum we limit errors */
|
||||
{
|
||||
value4 = MAX_HPOSITION;
|
||||
}
|
||||
attotime time_elapsed_since_megadriv_scanline_timer;
|
||||
uint16_t value4;
|
||||
|
||||
return value4;
|
||||
time_elapsed_since_megadriv_scanline_timer = m_scan_timer->time_elapsed();
|
||||
|
||||
if (time_elapsed_since_megadriv_scanline_timer.attoseconds() < (ATTOSECONDS_PER_SECOND/get_framerate() /double(m_total_scanlines)))
|
||||
{
|
||||
value4 = (uint16_t)(MAX_HPOSITION*((double)(time_elapsed_since_megadriv_scanline_timer.attoseconds()) / (double)(ATTOSECONDS_PER_SECOND/get_framerate() /double(m_total_scanlines))));
|
||||
}
|
||||
else /* in some cases (probably due to rounding errors) we get some stupid results (the odd huge value where the time elapsed is much higher than the scanline time??!).. hopefully by clamping the result to the maximum we limit errors */
|
||||
{
|
||||
value4 = MAX_HPOSITION;
|
||||
}
|
||||
|
||||
return value4;
|
||||
}
|
||||
return MAX_HPOSITION;
|
||||
}
|
||||
|
||||
READ16_MEMBER( sega_32x_device::common_vdp_regs_r )
|
||||
|
@ -12,8 +12,9 @@
|
||||
#include "machine/timer.h"
|
||||
#include "sound/dac.h"
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
|
||||
class sega_32x_device : public device_t, public device_palette_interface
|
||||
class sega_32x_device : public device_t, public device_palette_interface, public device_video_interface
|
||||
{
|
||||
public:
|
||||
void pause_cpu();
|
||||
@ -22,6 +23,7 @@ public:
|
||||
void set_framerate(int rate) { m_framerate = rate; }
|
||||
void set_32x_pal(bool pal) { m_32x_pal = pal ? 1 : 0; }
|
||||
void set_total_scanlines(int total) { m_base_total_scanlines = total; } // this get set at start only
|
||||
double get_framerate() { return has_screen() ? screen().frame_period().as_hz() : double(m_framerate); }
|
||||
|
||||
void screen_eof(bool mode3)
|
||||
{
|
||||
|
@ -327,6 +327,7 @@ void sega_segacd_device::device_add_mconfig(machine_config &config)
|
||||
sega_segacd_device::sega_segacd_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, type, tag, owner, clock)
|
||||
, device_gfx_interface(mconfig, *this, gfx_segacd)
|
||||
, device_video_interface(mconfig, *this, false)
|
||||
, m_scdcpu(*this, "segacd_68k")
|
||||
, m_hostcpu(*this, finder_base::DUMMY_TAG)
|
||||
, m_rfsnd(*this, "rfsnd")
|
||||
@ -1843,7 +1844,7 @@ TIMER_DEVICE_CALLBACK_MEMBER( sega_segacd_device::dma_timer_callback )
|
||||
// timed reset of flags
|
||||
scd_mode_dmna_ret_flags |= 0x0021;
|
||||
|
||||
m_dma_timer->adjust(attotime::from_hz(m_framerate) / m_total_scanlines);
|
||||
m_dma_timer->adjust(attotime::from_hz(get_framerate()) / double(m_total_scanlines));
|
||||
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,9 @@
|
||||
#include "machine/lc89510.h"
|
||||
#include "machine/megacdcd.h"
|
||||
#include "sound/rf5c68.h"
|
||||
#include "screen.h"
|
||||
|
||||
class sega_segacd_device : public device_t, public device_gfx_interface
|
||||
class sega_segacd_device : public device_t, public device_gfx_interface, public device_video_interface
|
||||
{
|
||||
public:
|
||||
template <typename T> void set_hostcpu(T &&tag) { m_hostcpu.set_tag(std::forward<T>(tag)); }
|
||||
@ -20,6 +21,7 @@ public:
|
||||
void set_framerate(int rate) { m_framerate = rate; }
|
||||
void set_total_scanlines(int total) { m_base_total_scanlines = total; } // this gets set at start only
|
||||
void update_total_scanlines(bool mode3) { m_total_scanlines = mode3 ? (m_base_total_scanlines * 2) : m_base_total_scanlines; } // this gets set at each EOF
|
||||
double get_framerate() { return has_screen() ? screen().frame_period().as_hz() : double(m_framerate); }
|
||||
|
||||
DECLARE_READ16_MEMBER( segacd_dmaaddr_r );
|
||||
DECLARE_WRITE16_MEMBER( segacd_dmaaddr_w );
|
||||
|
@ -703,21 +703,37 @@ WRITE8_MEMBER(md_base_state::megadriv_z80_vdp_write )
|
||||
case 0x15:
|
||||
case 0x17:
|
||||
// accessed by either segapsg_device or sn76496_device
|
||||
m_vdp->vdp_w(space, offset >> 1, data, 0x00ff);
|
||||
m_vdp->vdp_w(offset >> 1, data, 0x00ff);
|
||||
break;
|
||||
|
||||
default:
|
||||
osd_printf_debug("unhandled z80 vdp write %02x %02x\n",offset,data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
READ8_MEMBER(md_base_state::megadriv_z80_vdp_read )
|
||||
{
|
||||
osd_printf_debug("megadriv_z80_vdp_read %02x\n",offset);
|
||||
return machine().rand();
|
||||
u8 ret = 0;
|
||||
u8 shift = ((~offset & 1) << 3);
|
||||
switch (offset & ~1)
|
||||
{
|
||||
case 0x04: // ctrl_port_r
|
||||
case 0x06:
|
||||
case 0x08: // H/V counter
|
||||
case 0x0a:
|
||||
case 0x0c:
|
||||
case 0x0e:
|
||||
ret = m_vdp->vdp_r(offset >> 1, 0xff << shift) >> shift;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!machine().side_effects_disabled())
|
||||
osd_printf_debug("unhandled z80 vdp read %02x\n",offset);
|
||||
ret = machine().rand();
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
READ8_MEMBER(md_base_state::megadriv_z80_unmapped_read )
|
||||
@ -906,11 +922,12 @@ void md_base_state::md_ntsc(machine_config &config)
|
||||
m_vdp->lv6_irq().set(FUNC(md_base_state::vdp_lv6irqline_callback_genesis_68k));
|
||||
m_vdp->lv4_irq().set(FUNC(md_base_state::vdp_lv4irqline_callback_genesis_68k));
|
||||
m_vdp->set_screen("megadriv");
|
||||
m_vdp->add_route(ALL_OUTPUTS, "lspeaker", 0.25);
|
||||
m_vdp->add_route(ALL_OUTPUTS, "rspeaker", 0.25);
|
||||
m_vdp->add_route(ALL_OUTPUTS, "lspeaker", 0.50);
|
||||
m_vdp->add_route(ALL_OUTPUTS, "rspeaker", 0.50);
|
||||
|
||||
screen_device &screen(SCREEN(config, "megadriv", SCREEN_TYPE_RASTER));
|
||||
screen.set_refresh_hz(60);
|
||||
screen.set_refresh_hz(double(MASTER_CLOCK_NTSC) / 10.0 / 262.0 / 342.0); // same as SMS?
|
||||
// screen.set_refresh_hz(double(MASTER_CLOCK_NTSC) / 8.0 / 262.0 / 427.0); // or 427 Htotal?
|
||||
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); // Vblank handled manually.
|
||||
screen.set_size(64*8, 620);
|
||||
screen.set_visarea(0, 32*8-1, 0, 28*8-1);
|
||||
@ -960,11 +977,12 @@ void md_base_state::md_pal(machine_config &config)
|
||||
m_vdp->lv6_irq().set(FUNC(md_base_state::vdp_lv6irqline_callback_genesis_68k));
|
||||
m_vdp->lv4_irq().set(FUNC(md_base_state::vdp_lv4irqline_callback_genesis_68k));
|
||||
m_vdp->set_screen("megadriv");
|
||||
m_vdp->add_route(ALL_OUTPUTS, "lspeaker", 0.25);
|
||||
m_vdp->add_route(ALL_OUTPUTS, "rspeaker", 0.25);
|
||||
m_vdp->add_route(ALL_OUTPUTS, "lspeaker", 0.50);
|
||||
m_vdp->add_route(ALL_OUTPUTS, "rspeaker", 0.50);
|
||||
|
||||
screen_device &screen(SCREEN(config, "megadriv", SCREEN_TYPE_RASTER));
|
||||
screen.set_refresh_hz(50);
|
||||
screen.set_refresh_hz(double(MASTER_CLOCK_PAL) / 10.0 / 313.0 / 342.0); // same as SMS?
|
||||
// screen.set_refresh_hz(double(MASTER_CLOCK_PAL) / 8.0 / 313.0 / 423.0); // or 423 Htotal?
|
||||
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); // Vblank handled manually.
|
||||
screen.set_size(64*8, 620);
|
||||
screen.set_visarea(0, 32*8-1, 0, 28*8-1);
|
||||
|
Loading…
Reference in New Issue
Block a user