exelv.cpp: More accurate clocks (nw)

tms7000: Add divide-by-4 mask option for clocking (nw)

tms3556: Stop defaulting device clock and disable read side effects for debugging (nw)
This commit is contained in:
AJR 2020-03-24 12:16:00 -04:00
parent 36bd4c4cab
commit d1f029ca2c
5 changed files with 50 additions and 34 deletions

View File

@ -121,7 +121,8 @@ tms7000_device::tms7000_device(const machine_config &mconfig, device_type type,
m_program_config("program", ENDIANNESS_BIG, 8, 16, 0, internal),
m_port_in_cb(*this),
m_port_out_cb(*this),
m_info_flags(info_flags)
m_info_flags(info_flags),
m_divider(2)
{
}

View File

@ -45,6 +45,10 @@ public:
auto in_porte() { return m_port_in_cb[4].bind(); }
auto out_porte() { return m_port_out_cb[4].bind(); }
// clock divider mask option
void set_divide_by_2() { m_divider = 2; }
void set_divide_by_4() { m_divider = 4; }
DECLARE_READ8_MEMBER(tms7000_unmapped_rf_r) { if (!machine().side_effects_disabled()) logerror("'%s' (%04X): unmapped_rf_r @ $%04x\n", tag(), m_pc, offset + 0x80); return 0; };
DECLARE_WRITE8_MEMBER(tms7000_unmapped_rf_w) { logerror("'%s' (%04X): unmapped_rf_w @ $%04x = $%02x\n", tag(), m_pc, offset + 0x80, data); };
@ -80,8 +84,8 @@ protected:
virtual void device_reset() override;
// device_execute_interface overrides
virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const noexcept override { return (clocks + 2 - 1) / 2; } // internal /2 divider
virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const noexcept override { return (cycles * 2); } // internal /2 divider
virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const noexcept override { return (clocks + m_divider - 1) / 2; }
virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const noexcept override { return (cycles * m_divider); }
virtual uint32_t execute_min_cycles() const noexcept override { return 5; }
virtual uint32_t execute_max_cycles() const noexcept override { return 49; }
virtual uint32_t execute_input_lines() const noexcept override { return 2; }
@ -106,7 +110,8 @@ protected:
devcb_read8::array<5> m_port_in_cb;
devcb_write8::array<5> m_port_out_cb;
uint32_t m_info_flags;
const uint32_t m_info_flags;
unsigned m_divider;
address_space *m_program;
memory_access_cache<0, 0, ENDIANNESS_BIG> *m_cache;

View File

@ -183,33 +183,40 @@ uint32_t tms3556_device::screen_update(screen_device &screen, bitmap_ind16 &bitm
uint8_t tms3556_device::vram_r()
{
uint8_t ret;
if (m_bamp_written) {
m_bamp_written=false;
m_vdp_acmpxy_mode=dma_write;
if (m_init_read)
m_vdp_acmp=VDP_BAMP;
else
m_vdp_acmp=(VDP_BAMP-1)&0xFFFF;
if (!machine().side_effects_disabled()) {
if (m_bamp_written) {
m_bamp_written=false;
m_vdp_acmpxy_mode=dma_write;
if (m_init_read)
m_vdp_acmp=VDP_BAMP;
else
m_vdp_acmp=(VDP_BAMP-1)&0xFFFF;
}
if (m_row_col_written) {
m_row_col_written=0;
m_vdp_acmpxy_mode=dma_read;
if (m_init_read)
m_vdp_acmpxy=m_colrow;
else
m_vdp_acmpxy=(m_colrow-1)&0xFFFF;
}
m_init_read=false;
}
if (m_row_col_written) {
m_row_col_written=0;
m_vdp_acmpxy_mode=dma_read;
if (m_init_read)
m_vdp_acmpxy=m_colrow;
else
m_vdp_acmpxy=(m_colrow-1)&0xFFFF;
}
m_init_read=false;
if (m_vdp_acmpxy_mode==dma_read) {
ret=readbyte(m_vdp_acmpxy);
m_vdp_acmpxy++;
if (m_vdp_acmpxy==VDP_BAMTF) m_vdp_acmpxy=VDP_BAMP;
if (!machine().side_effects_disabled()) {
m_vdp_acmpxy++;
if (m_vdp_acmpxy==VDP_BAMTF) m_vdp_acmpxy=VDP_BAMP;
}
} else {
ret=readbyte(m_vdp_acmp);
m_vdp_acmp++;
if (m_vdp_acmp==VDP_BAMTF) m_vdp_acmp=VDP_BAMP;
if (!machine().side_effects_disabled()) {
m_vdp_acmp++;
if (m_vdp_acmp==VDP_BAMTF) m_vdp_acmp=VDP_BAMP;
}
}
return ret;
}
@ -254,7 +261,8 @@ uint8_t tms3556_device::reg_r(offs_t offset)
LOG("TMS3556 Reg Read: %06x\n", offset);
int reply = 0; // FIXME : will send internal status (VBL, HBL...)
m_reg_access_phase = 0;
if (!machine().side_effects_disabled())
m_reg_access_phase = 0;
return reply;
}

View File

@ -38,7 +38,7 @@ public:
static constexpr unsigned TOTAL_HEIGHT = 250 + TOP_BORDER + BOTTOM_BORDER;
// construction/destruction
tms3556_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
tms3556_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
uint8_t vram_r();
void vram_w(uint8_t data);

View File

@ -484,7 +484,7 @@ MACHINE_START_MEMBER( exelv_state, exeltel)
void exelv_state::exl100(machine_config &config)
{
/* basic machine hardware */
TMS7020_EXL(config, m_maincpu, XTAL(4'915'200));
TMS7020_EXL(config, m_maincpu, 4.9152_MHz_XTAL);
m_maincpu->set_addrmap(AS_PROGRAM, &exelv_state::tms7020_mem);
m_maincpu->in_porta().set(FUNC(exelv_state::tms7020_porta_r));
m_maincpu->out_portb().set(FUNC(exelv_state::tms7020_portb_w));
@ -492,7 +492,7 @@ void exelv_state::exl100(machine_config &config)
TIMER(config, "scantimer").configure_scanline(FUNC(exelv_state::exelv_hblank_interrupt), "screen", 0, 1);
MCFG_MACHINE_START_OVERRIDE(exelv_state, exl100)
tms7041_device &subcpu(TMS7041(config, "tms7041", XTAL(4'915'200)));
tms7041_device &subcpu(TMS7041(config, "tms7041", 4.9152_MHz_XTAL));
subcpu.in_porta().set(FUNC(exelv_state::tms7041_porta_r));
subcpu.out_portb().set(FUNC(exelv_state::tms7041_portb_w));
subcpu.in_portc().set(FUNC(exelv_state::tms7041_portc_r));
@ -502,7 +502,7 @@ void exelv_state::exl100(machine_config &config)
config.set_perfect_quantum(m_maincpu);
TMS3556(config, m_tms3556);
TMS3556(config, m_tms3556, 18_MHz_XTAL);
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
@ -538,7 +538,8 @@ void exelv_state::exl100(machine_config &config)
void exelv_state::exeltel(machine_config &config)
{
/* basic machine hardware */
TMS7040(config, m_maincpu, XTAL(4'915'200));
TMS7040(config, m_maincpu, 9.8304_MHz_XTAL);
m_maincpu->set_divide_by_4();
m_maincpu->set_addrmap(AS_PROGRAM, &exelv_state::tms7040_mem);
m_maincpu->in_porta().set(FUNC(exelv_state::tms7020_porta_r));
m_maincpu->out_portb().set(FUNC(exelv_state::tms7020_portb_w));
@ -546,7 +547,8 @@ void exelv_state::exeltel(machine_config &config)
TIMER(config, "scantimer").configure_scanline(FUNC(exelv_state::exelv_hblank_interrupt), "screen", 0, 1);
MCFG_MACHINE_START_OVERRIDE(exelv_state, exeltel)
tms7042_device &subcpu(TMS7042(config, "tms7042", XTAL(4'915'200)));
tms7042_device &subcpu(TMS7042(config, "tms7042", 9.8304_MHz_XTAL));
subcpu.set_divide_by_4();
subcpu.in_porta().set(FUNC(exelv_state::tms7041_porta_r));
subcpu.out_portb().set(FUNC(exelv_state::tms7041_portb_w));
subcpu.in_portc().set(FUNC(exelv_state::tms7041_portc_r));
@ -556,7 +558,7 @@ void exelv_state::exeltel(machine_config &config)
config.set_perfect_quantum(m_maincpu);
TMS3556(config, m_tms3556);
TMS3556(config, m_tms3556, 18_MHz_XTAL);
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
@ -579,7 +581,7 @@ void exelv_state::exeltel(machine_config &config)
/* sound */
SPEAKER(config, "mono").front_center();
TMS5220C(config, m_tms5220c, 640000);
TMS5220C(config, m_tms5220c, 9.8304_MHz_XTAL / 15); // unknown divider for "VSPCLK" (generated by TAHC06 gate array)
m_tms5220c->set_speechrom_tag("vsm");
m_tms5220c->add_route(ALL_OUTPUTS, "mono", 1.00);
}