mirror of
https://github.com/holub/mame
synced 2025-06-06 04:43:45 +03:00
ef9365: simplify busy timer, change msl pins to a devcb
This commit is contained in:
parent
d6a7f2906a
commit
5b297d7854
@ -2,7 +2,7 @@
|
||||
// copyright-holders:Daniel Coulom,Sandro Ronco
|
||||
/*********************************************************************
|
||||
|
||||
ef9345.c
|
||||
ef9345.cpp
|
||||
|
||||
Thomson EF9345 video controller emulator code
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
/*********************************************************************
|
||||
|
||||
ef9365.c
|
||||
ef9365.cpp
|
||||
|
||||
Thomson EF9365/EF9366/EF9367 video controller emulator code
|
||||
|
||||
@ -162,7 +162,8 @@ const tiny_rom_entry *ef9365_device::device_rom_region() const
|
||||
// default address map
|
||||
// Up to 512*512 per bitplane, 8 bitplanes max.
|
||||
//-------------------------------------------------
|
||||
void ef9365_device::ef9365(address_map &map)
|
||||
|
||||
void ef9365_device::ef9365_map(address_map &map)
|
||||
{
|
||||
if (!has_configured_map(0))
|
||||
map(0x00000, ef9365_device::BITPLANE_MAX_SIZE * ef9365_device::MAX_BITPLANES - 1).ram();
|
||||
@ -197,12 +198,15 @@ ef9365_device::ef9365_device(const machine_config &mconfig, const char *tag, dev
|
||||
device_t(mconfig, EF9365, tag, owner, clock),
|
||||
device_memory_interface(mconfig, *this),
|
||||
device_video_interface(mconfig, *this),
|
||||
m_space_config("videoram", ENDIANNESS_LITTLE, 8, 18, 0, address_map_constructor(FUNC(ef9365_device::ef9365), this)),
|
||||
m_space_config("videoram", ENDIANNESS_LITTLE, 8, 18, 0, address_map_constructor(FUNC(ef9365_device::ef9365_map), this)),
|
||||
m_charset(*this, "ef9365"),
|
||||
m_palette(*this, finder_base::DUMMY_TAG),
|
||||
m_irq_handler(*this)
|
||||
m_irq_handler(*this),
|
||||
m_write_msl(*this)
|
||||
{
|
||||
m_clock_freq = clock;
|
||||
set_display_mode(DISPLAY_MODE_256x256);
|
||||
set_nb_bitplanes(1);
|
||||
set_color_filler(0);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -270,11 +274,7 @@ void ef9365_device::set_display_mode(int display_mode)
|
||||
break;
|
||||
default:
|
||||
logerror("Invalid EF9365 Display mode: %02x\n", display_mode);
|
||||
m_bitplane_xres = 256;
|
||||
m_bitplane_yres = 256;
|
||||
m_vsync_scanline_pos = 250;
|
||||
m_overflow_mask_x = 0xff00;
|
||||
m_overflow_mask_y = 0xff00;
|
||||
set_display_mode(DISPLAY_MODE_256x256);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -315,7 +315,6 @@ void ef9365_device::device_start()
|
||||
m_busy_timer = timer_alloc(FUNC(ef9365_device::clear_busy_flag), this);
|
||||
|
||||
m_videoram = &space(0);
|
||||
m_current_color = 0x00;
|
||||
|
||||
m_irq_vb = 0;
|
||||
m_irq_lb = 0;
|
||||
@ -324,18 +323,20 @@ void ef9365_device::device_start()
|
||||
|
||||
m_screen_out.allocate(m_bitplane_xres, screen().height());
|
||||
|
||||
save_item(NAME(m_border));
|
||||
save_item(NAME(m_registers));
|
||||
save_item(NAME(m_bf));
|
||||
save_item(NAME(m_state));
|
||||
save_item(NAME(m_msl));
|
||||
save_item(NAME(m_readback_latch_pix_offset));
|
||||
|
||||
save_item(NAME(m_irq_state));
|
||||
save_item(NAME(m_irq_vb));
|
||||
save_item(NAME(m_irq_lb));
|
||||
save_item(NAME(m_irq_rdy));
|
||||
|
||||
save_item(NAME(m_current_color));
|
||||
save_item(NAME(m_bf));
|
||||
save_item(NAME(m_registers));
|
||||
save_item(NAME(m_state));
|
||||
save_item(NAME(m_border));
|
||||
|
||||
save_item(NAME(m_readback_latch));
|
||||
save_item(NAME(m_readback_latch_pix_offset));
|
||||
|
||||
save_item(NAME(m_screen_out));
|
||||
}
|
||||
|
||||
@ -345,17 +346,19 @@ void ef9365_device::device_start()
|
||||
|
||||
void ef9365_device::device_reset()
|
||||
{
|
||||
m_state = 0;
|
||||
|
||||
m_bf = 0;
|
||||
m_irq_state = 0;
|
||||
m_irq_vb = 0;
|
||||
m_irq_lb = 0;
|
||||
m_irq_rdy = 0;
|
||||
m_bf = 0;
|
||||
m_state = 0;
|
||||
|
||||
memset(m_registers, 0, sizeof(m_registers));
|
||||
memset(m_border, 0, sizeof(m_border));
|
||||
|
||||
memset(m_readback_latch, 0, sizeof(m_readback_latch));
|
||||
m_readback_latch_pix_offset = 0;
|
||||
|
||||
m_screen_out.fill(0);
|
||||
|
||||
set_video_mode();
|
||||
@ -401,10 +404,10 @@ TIMER_CALLBACK_MEMBER(ef9365_device::clear_busy_flag)
|
||||
// timer to clear it
|
||||
//-------------------------------------------------
|
||||
|
||||
void ef9365_device::set_busy_flag(int period)
|
||||
void ef9365_device::set_busy_flag(int cycles)
|
||||
{
|
||||
m_bf = 1;
|
||||
m_busy_timer->adjust(attotime::from_usec(period));
|
||||
m_busy_timer->adjust(attotime::from_ticks(cycles, clock()));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -445,6 +448,16 @@ void ef9365_device::set_y_reg(uint16_t y)
|
||||
m_registers[EF936X_REG_Y_LSB] = y & 0xff;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// set_msl_pins: Set the MSL pins
|
||||
//-------------------------------------------------
|
||||
|
||||
void ef9365_device::set_msl_pins(uint16_t x, uint16_t y)
|
||||
{
|
||||
y = (m_bitplane_yres == 512) ? (y & 1) : 1;
|
||||
m_write_msl((x & 7) | y << 3);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// set_video_mode: Set output screen format
|
||||
//-------------------------------------------------
|
||||
@ -506,8 +519,8 @@ void ef9365_device::plot(int x_pos, int y_pos)
|
||||
if (m_registers[EF936X_REG_CTRL1] & 0x01)
|
||||
{
|
||||
y_pos = (m_bitplane_yres - 1) - y_pos;
|
||||
m_msl = (x_pos & 7) | 8;
|
||||
uint8_t mask = 0x80 >> (m_msl & 7);
|
||||
set_msl_pins(x_pos, y_pos);
|
||||
uint8_t mask = 0x80 >> (x_pos & 7);
|
||||
|
||||
if (m_registers[EF936X_REG_CTRL1] & 0x02)
|
||||
{
|
||||
@ -829,15 +842,6 @@ int ef9365_device::draw_character(uint8_t c, bool block, bool smallblock)
|
||||
return compute_cycles;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// cycles_to_us: Convert a number of clock cycles to us
|
||||
//-------------------------------------------------
|
||||
|
||||
int ef9365_device::cycles_to_us(int cycles)
|
||||
{
|
||||
return (int)(cycles * (1000000.f / m_clock_freq));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// dump_bitplanes_word: Latch the bitplane words
|
||||
// pointed by the x & y registers
|
||||
@ -873,8 +877,8 @@ void ef9365_device::screen_scanning(bool force_clear)
|
||||
{
|
||||
for (int x = 0; x < m_bitplane_xres; x++)
|
||||
{
|
||||
m_msl = (x & 7) | 8;
|
||||
uint8_t mask = 0x80 >> (m_msl & 7);
|
||||
set_msl_pins(x, y);
|
||||
uint8_t mask = 0x80 >> (x & 7);
|
||||
|
||||
for (int p = 0; p < m_nb_of_bitplanes; p++)
|
||||
{
|
||||
@ -894,8 +898,8 @@ void ef9365_device::screen_scanning(bool force_clear)
|
||||
{
|
||||
for (int x = 0; x < m_bitplane_xres; x++)
|
||||
{
|
||||
m_msl = (x & 7) | 8;
|
||||
uint8_t mask = 0x80 >> (m_msl & 7);
|
||||
set_msl_pins(x, y);
|
||||
uint8_t mask = 0x80 >> (x & 7);
|
||||
|
||||
for (int p = 0; p < m_nb_of_bitplanes; p++)
|
||||
{
|
||||
@ -987,7 +991,7 @@ void ef9365_device::ef9365_exec(uint8_t cmd)
|
||||
|
||||
if (busy_cycles)
|
||||
{
|
||||
set_busy_flag(cycles_to_us(busy_cycles));
|
||||
set_busy_flag(busy_cycles);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1041,7 +1045,7 @@ void ef9365_device::ef9365_exec(uint8_t cmd)
|
||||
busy_cycles = draw_vector(get_x_reg(), get_y_reg(), -tmp_delta_x, 0);
|
||||
break;
|
||||
}
|
||||
set_busy_flag(cycles_to_us(busy_cycles));
|
||||
set_busy_flag(busy_cycles);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1084,7 +1088,7 @@ void ef9365_device::ef9365_exec(uint8_t cmd)
|
||||
break;
|
||||
}
|
||||
|
||||
set_busy_flag(cycles_to_us(busy_cycles));
|
||||
set_busy_flag(busy_cycles);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1093,7 +1097,7 @@ void ef9365_device::ef9365_exec(uint8_t cmd)
|
||||
LOG("EF9365 Command : [0x%.2X] %s\n", cmd, commands_names[0x12]);
|
||||
|
||||
int busy_cycles = draw_character(cmd - 0x20, false, false);
|
||||
set_busy_flag(cycles_to_us(busy_cycles));
|
||||
set_busy_flag(busy_cycles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,8 @@ public:
|
||||
template <typename T> void set_palette_tag(T &&tag) { m_palette.set_tag(std::forward<T>(tag)); }
|
||||
void set_nb_bitplanes(int nb_bitplanes);
|
||||
void set_display_mode(int display_mode);
|
||||
auto irq_handler() { return m_irq_handler.bind(); }
|
||||
auto irq_handler() { return m_irq_handler.bind(); } // IRQ pin
|
||||
auto write_msl() { return m_write_msl.bind(); } // memory select during pixel write
|
||||
|
||||
// device interface
|
||||
uint8_t data_r(offs_t offset);
|
||||
@ -53,8 +54,6 @@ public:
|
||||
void update_scanline(uint16_t scanline);
|
||||
void set_color_filler(uint8_t color);
|
||||
void set_color_entry(int index, uint8_t r, uint8_t g, uint8_t b);
|
||||
|
||||
uint8_t get_msl() { return m_msl; } // during pixel write
|
||||
uint8_t get_last_readback_word(int bitplane_number, int *pixel_offset);
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
@ -82,16 +81,16 @@ private:
|
||||
uint16_t get_y_reg();
|
||||
void set_x_reg(uint16_t x);
|
||||
void set_y_reg(uint16_t y);
|
||||
void set_msl_pins(uint16_t x, uint16_t y);
|
||||
void screen_scanning(bool force_clear);
|
||||
void set_busy_flag(int period);
|
||||
void set_busy_flag(int cycles);
|
||||
void set_video_mode();
|
||||
void draw_border(uint16_t line);
|
||||
void ef9365_exec(uint8_t cmd);
|
||||
int cycles_to_us(int cycles);
|
||||
void dump_bitplanes_word();
|
||||
void update_interrupts();
|
||||
|
||||
void ef9365(address_map &map);
|
||||
void ef9365_map(address_map &map);
|
||||
|
||||
// internal state
|
||||
required_region_ptr<uint8_t> m_charset;
|
||||
@ -106,7 +105,6 @@ private:
|
||||
uint8_t m_registers[0x10]; // registers
|
||||
uint8_t m_state; // status register
|
||||
uint8_t m_border[80]; // border color
|
||||
uint8_t m_msl; // memory select signal
|
||||
|
||||
int m_nb_of_bitplanes;
|
||||
int m_nb_of_colors;
|
||||
@ -119,7 +117,6 @@ private:
|
||||
uint8_t m_readback_latch[MAX_BITPLANES]; // Last DRAM Readback buffer (Filled after a Direct Memory Access Request command)
|
||||
int m_readback_latch_pix_offset;
|
||||
|
||||
uint32_t m_clock_freq;
|
||||
bitmap_rgb32 m_screen_out;
|
||||
|
||||
// timers
|
||||
@ -127,6 +124,7 @@ private:
|
||||
|
||||
required_device<palette_device> m_palette;
|
||||
devcb_write_line m_irq_handler;
|
||||
devcb_write8 m_write_msl;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
|
@ -80,6 +80,7 @@ private:
|
||||
void vram_map(address_map &map);
|
||||
void vram_w(offs_t offset, u8 data);
|
||||
u8 vram_r(offs_t offset);
|
||||
void msl_w(u8 data) { m_pixel_offset = data & 7; }
|
||||
|
||||
void porta_w(u8 data);
|
||||
u8 porta_r();
|
||||
@ -95,6 +96,7 @@ private:
|
||||
u8 m_ccount = 0;
|
||||
u8 m_command = 0;
|
||||
u8 m_color = 0;
|
||||
u8 m_pixel_offset = 0;
|
||||
u8 m_vramdata = 0;
|
||||
};
|
||||
|
||||
@ -117,6 +119,7 @@ void videoart_state::machine_start()
|
||||
save_item(NAME(m_ccount));
|
||||
save_item(NAME(m_command));
|
||||
save_item(NAME(m_color));
|
||||
save_item(NAME(m_pixel_offset));
|
||||
save_item(NAME(m_vramdata));
|
||||
}
|
||||
|
||||
@ -176,9 +179,8 @@ u32 videoart_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, c
|
||||
|
||||
void videoart_state::vram_w(offs_t offset, u8 data)
|
||||
{
|
||||
u8 low = m_ef9367->get_msl() & 7;
|
||||
data = BIT(data, low ^ 7);
|
||||
offset = offset << 1 | BIT(low, 2);
|
||||
data = BIT(data, ~m_pixel_offset & 7);
|
||||
offset = offset << 1 | BIT(m_pixel_offset, 2);
|
||||
|
||||
if (data)
|
||||
m_vram[offset] = m_color;
|
||||
@ -188,9 +190,9 @@ void videoart_state::vram_w(offs_t offset, u8 data)
|
||||
|
||||
u8 videoart_state::vram_r(offs_t offset)
|
||||
{
|
||||
int low = 0;
|
||||
m_ef9367->get_last_readback_word(0, &low);
|
||||
offset = offset << 1 | BIT(low, 2);
|
||||
int pixel_offset = 0;
|
||||
m_ef9367->get_last_readback_word(0, &pixel_offset);
|
||||
offset = offset << 1 | BIT(pixel_offset, 2);
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
m_vramdata = m_vram[offset];
|
||||
@ -218,24 +220,24 @@ void videoart_state::porta_w(u8 data)
|
||||
|
||||
u8 videoart_state::porta_r()
|
||||
{
|
||||
u8 data = 0;
|
||||
u8 data = 0xff;
|
||||
|
||||
// read EF9367 data
|
||||
if (~m_portb & 1)
|
||||
data |= m_efdata;
|
||||
data &= m_efdata;
|
||||
|
||||
// read vram data
|
||||
if (~m_portb & 4)
|
||||
{
|
||||
u8 shift = (m_ccount & 1) * 2;
|
||||
data |= m_vramdata >> shift;
|
||||
data &= m_vramdata >> shift | 0xfc;
|
||||
}
|
||||
|
||||
// read cartridge data
|
||||
if (~m_portb & 0x10)
|
||||
{
|
||||
u16 offset = m_romlatch << 8 | m_portc;
|
||||
data |= m_cart->read_rom(offset);
|
||||
data &= m_cart->read_rom(offset);
|
||||
}
|
||||
|
||||
return data;
|
||||
@ -357,6 +359,7 @@ void videoart_state::videoart(machine_config &config)
|
||||
m_ef9367->set_nb_bitplanes(1);
|
||||
m_ef9367->set_display_mode(ef9365_device::DISPLAY_MODE_512x256);
|
||||
m_ef9367->irq_handler().set_inputline(m_maincpu, M6805_IRQ_LINE);
|
||||
m_ef9367->write_msl().set(FUNC(videoart_state::msl_w));
|
||||
|
||||
TIMER(config, "scanline").configure_scanline(FUNC(videoart_state::scanline), "screen", 0, 1);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user