From 5b297d7854358c279e4397a56e5d38f457b05461 Mon Sep 17 00:00:00 2001 From: hap Date: Fri, 27 Oct 2023 19:25:56 +0200 Subject: [PATCH] ef9365: simplify busy timer, change msl pins to a devcb --- src/devices/video/ef9345.cpp | 2 +- src/devices/video/ef9365.cpp | 90 +++++++++++++++++++----------------- src/devices/video/ef9365.h | 18 ++++---- src/mame/misc/videoart.cpp | 23 +++++---- 4 files changed, 69 insertions(+), 64 deletions(-) diff --git a/src/devices/video/ef9345.cpp b/src/devices/video/ef9345.cpp index df596e7f7a4..f4780a7e790 100644 --- a/src/devices/video/ef9345.cpp +++ b/src/devices/video/ef9345.cpp @@ -2,7 +2,7 @@ // copyright-holders:Daniel Coulom,Sandro Ronco /********************************************************************* - ef9345.c + ef9345.cpp Thomson EF9345 video controller emulator code diff --git a/src/devices/video/ef9365.cpp b/src/devices/video/ef9365.cpp index 215d2a0be3a..249282a819f 100644 --- a/src/devices/video/ef9365.cpp +++ b/src/devices/video/ef9365.cpp @@ -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 //------------------------------------------------- @@ -461,7 +474,7 @@ void ef9365_device::set_video_mode(void) screen().configure(new_width, screen().height(), visarea, screen().frame_period().attoseconds()); } - //border color + // border color memset(m_border, 0, sizeof(m_border)); } @@ -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); } } } diff --git a/src/devices/video/ef9365.h b/src/devices/video/ef9365.h index 928079d33cd..2a16ef5508a 100644 --- a/src/devices/video/ef9365.h +++ b/src/devices/video/ef9365.h @@ -42,9 +42,10 @@ public: // configuration template void set_palette_tag(T &&tag) { m_palette.set_tag(std::forward(tag)); } - void set_nb_bitplanes(int nb_bitplanes ); - void set_display_mode(int display_mode ); - auto irq_handler() { return m_irq_handler.bind(); } + void set_nb_bitplanes(int nb_bitplanes); + void set_display_mode(int display_mode); + 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 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 m_palette; devcb_write_line m_irq_handler; + devcb_write8 m_write_msl; }; // device type definition diff --git a/src/mame/misc/videoart.cpp b/src/mame/misc/videoart.cpp index 1a4ee3432dd..0b9b3e4ee50 100644 --- a/src/mame/misc/videoart.cpp +++ b/src/mame/misc/videoart.cpp @@ -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);