64x64 and 128x128 resolutions added.

Some typo corrections, and comments added.
This commit is contained in:
Jean-François DEL NERO 2015-12-29 17:18:04 +01:00
parent 3c8d2d8597
commit 72125cade2
2 changed files with 240 additions and 79 deletions

View File

@ -3,20 +3,77 @@
/*********************************************************************
ef9365.c
ef9365.c
Thomson EF9365/EF9366 video controller emulator code
Thomson EF9365/EF9366 video controller emulator code
The EF9365/EF9366 is a video controller driving a frame buffer
and having built-in vectors and characters drawing engines.
This is natively a "black and white" chip (1 bitplane),
but it is possible to add more bitplanes to have colors with a
hardware trick. The system don't have direct access to the video
memory, but indirect access is possible through the 0x0F command
and some hardware glue logics.
The current implementation emulate the main functions :
Video modes supported (Hardware implementation dependent):
- 256 x 256 (EF9365 with 4 bits shifters per bitplane and FMAT to VSS)
- 512 x 512 interlaced (EF9365 with 8 bits shifters per bitplane and FMAT to VCC)
- 512 x 256 non interlaced (EF9366 with 8 bits shifters per bitplane)
- 128 x 128 (EF9365 with 2 bits shifters per bitplane and FMAT to VSS)
- 64 x 64 (EF9365 with FMAT to VSS)
- 1 bitplane up to 8 bitplanes hardware configuration.
- 2 up to 256 colors fixed palette.
Character & block drawing :
- Normal / Titled mode
- Horizontal / Vertical orientation
- P & Q Zoom factors (1 up to 16)
Vector drawing :
- Normal / Dotted / Dashed / Dotted-Dashed mode
- All directions and size supported.
General :
- Clear Screen
- Fill Screen
- Clear X & Y registers
- Video RAM readback supported (Command 0x0F)
What is NOT yet currently implemented:
- Light pen support
(To be done when i will find a software using the lightpen)
What is implemented but not really tested:
- Interrupts output.
My target system (Squale Apollo 7) doesn't use the interruption
for this chip. So i add the interrupt line support, but
bug(s) is possible.
The needed charset file charset_ef9365.rom (CRC 8d3053be) is available
there : http://hxc2001.free.fr/Squale/rom/charset_ef9365.zip
This ROM charset is into the EF9365/EF9366.
To see how to use this driver, have a look to the Squale machine
driver (squale.cpp).
If you have any question, don't hesitate to contact me at the email
present on this website : http://hxc2001.free.fr/
12/29/2015
Jean-François DEL NERO
*********************************************************************/
#include "emu.h"
#include "ef9365.h"
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
#ifdef DBGMODE
//-------------------------------------------------
// Some debug mode const strings
// to trace the commands and registers accesses.
//-------------------------------------------------
// Registers list
const char * register_names[]=
{
"0x00 - CMD / STATUS",
@ -37,6 +94,7 @@ const char * register_names[]=
"0x0F - RESERVED "
};
// Commands list
const char * commands_names[]=
{
"0x00 - Set bit 1 of CTRL1 : Pen selection",
@ -66,10 +124,12 @@ const char * commands_names[]=
// devices
const device_type EF9365 = &device_creator<ef9365_device>;
//-------------------------------------------------
// default address map
// Up to 512*512 per bitplan
// Up to 512*512 per bitplane, 8 bitplanes max.
//-------------------------------------------------
static ADDRESS_MAP_START( ef9365, AS_0, 8, ef9365_device )
AM_RANGE(0x00000, ( ( EF936X_BITPLAN_MAX_SIZE * EF936X_MAX_BITPLANS ) - 1 ) ) AM_RAM
AM_RANGE(0x00000, ( ( EF936X_BITPLANE_MAX_SIZE * EF936X_MAX_BITPLANES ) - 1 ) ) AM_RAM
ADDRESS_MAP_END
//-------------------------------------------------
@ -117,15 +177,15 @@ void ef9365_device::static_set_palette_tag(device_t &device, const char *tag)
}
//-------------------------------------------------
// static_set_nb_of_bitplans: Set the number of bitplans
// static_set_nb_of_bitplanes: Set the number of bitplanes
//-------------------------------------------------
void ef9365_device::static_set_nb_bitplans(device_t &device, int nb_bitplans )
void ef9365_device::static_set_nb_bitplanes(device_t &device, int nb_bitplanes )
{
if( nb_bitplans > 0 && nb_bitplans <= 8 )
if( nb_bitplanes > 0 && nb_bitplanes <= 8 )
{
downcast<ef9365_device &>(device).nb_of_bitplans = nb_bitplans;
downcast<ef9365_device &>(device).nb_of_colors = pow(2,nb_bitplans);
downcast<ef9365_device &>(device).nb_of_bitplanes = nb_bitplanes;
downcast<ef9365_device &>(device).nb_of_colors = pow(2,nb_bitplanes);
}
}
@ -138,30 +198,44 @@ void ef9365_device::static_set_display_mode(device_t &device, int display_mode )
switch(display_mode)
{
case EF936X_256x256_DISPLAY_MODE:
downcast<ef9365_device &>(device).bitplan_xres = 256;
downcast<ef9365_device &>(device).bitplan_yres = 256;
downcast<ef9365_device &>(device).bitplane_xres = 256;
downcast<ef9365_device &>(device).bitplane_yres = 256;
downcast<ef9365_device &>(device).vsync_scanline_pos = 250;
downcast<ef9365_device &>(device).overflow_mask_x = 0xFF00;
downcast<ef9365_device &>(device).overflow_mask_y = 0xFF00;
break;
case EF936X_512x512_DISPLAY_MODE:
downcast<ef9365_device &>(device).bitplan_xres = 512;
downcast<ef9365_device &>(device).bitplan_yres = 512;
downcast<ef9365_device &>(device).bitplane_xres = 512;
downcast<ef9365_device &>(device).bitplane_yres = 512;
downcast<ef9365_device &>(device).vsync_scanline_pos = 506;
downcast<ef9365_device &>(device).overflow_mask_x = 0xFE00;
downcast<ef9365_device &>(device).overflow_mask_y = 0xFE00;
break;
case EF936X_512x256_DISPLAY_MODE:
downcast<ef9365_device &>(device).bitplan_xres = 512;
downcast<ef9365_device &>(device).bitplan_yres = 256;
downcast<ef9365_device &>(device).bitplane_xres = 512;
downcast<ef9365_device &>(device).bitplane_yres = 256;
downcast<ef9365_device &>(device).vsync_scanline_pos = 250;
downcast<ef9365_device &>(device).overflow_mask_x = 0xFE00;
downcast<ef9365_device &>(device).overflow_mask_y = 0xFF00;
break;
case EF936X_128x128_DISPLAY_MODE:
downcast<ef9365_device &>(device).bitplane_xres = 128;
downcast<ef9365_device &>(device).bitplane_yres = 128;
downcast<ef9365_device &>(device).vsync_scanline_pos = 124;
downcast<ef9365_device &>(device).overflow_mask_x = 0xFF80;
downcast<ef9365_device &>(device).overflow_mask_y = 0xFF80;
break;
case EF936X_64x64_DISPLAY_MODE:
downcast<ef9365_device &>(device).bitplane_xres = 64;
downcast<ef9365_device &>(device).bitplane_yres = 64;
downcast<ef9365_device &>(device).vsync_scanline_pos = 62;
downcast<ef9365_device &>(device).overflow_mask_x = 0xFFC0;
downcast<ef9365_device &>(device).overflow_mask_y = 0xFFC0;
break;
default:
downcast<ef9365_device &>(device).logerror("Invalid EF9365 Display mode: %02x\n", display_mode);
downcast<ef9365_device &>(device).bitplan_xres = 256;
downcast<ef9365_device &>(device).bitplan_yres = 256;
downcast<ef9365_device &>(device).bitplane_xres = 256;
downcast<ef9365_device &>(device).bitplane_yres = 256;
downcast<ef9365_device &>(device).vsync_scanline_pos = 250;
downcast<ef9365_device &>(device).overflow_mask_x = 0xFF00;
downcast<ef9365_device &>(device).overflow_mask_y = 0xFF00;
@ -224,7 +298,7 @@ void ef9365_device::device_start()
palette[i] = rgb_t(255, 255, 255);
}
m_screen_out.allocate( bitplan_xres, m_screen->height() );
m_screen_out.allocate( bitplane_xres, m_screen->height() );
save_item(NAME(m_border));
save_item(NAME(m_registers));
@ -242,6 +316,7 @@ void ef9365_device::device_start()
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void ef9365_device::device_reset()
{
m_state = 0;
@ -278,10 +353,10 @@ void ef9365_device::update_interrupts()
}
}
//-------------------------------------------------
// device_timer - handler timer events
//-------------------------------------------------
void ef9365_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
switch(id)
@ -300,39 +375,62 @@ void ef9365_device::device_timer(emu_timer &timer, device_timer_id id, int param
}
}
// set busy flag and timer to clear it
//-------------------------------------------------
// set_busy_flag: set busy flag and
// timer to clear it
//-------------------------------------------------
void ef9365_device::set_busy_flag(int period)
{
m_bf = 1;
m_busy_timer->adjust(attotime::from_usec(period));
}
//-------------------------------------------------
// get_x_reg: Get the X register value
//-------------------------------------------------
unsigned int ef9365_device::get_x_reg()
{
return (m_registers[EF936X_REG_X_MSB]<<8) | m_registers[EF936X_REG_X_LSB];
}
//-------------------------------------------------
// get_y_reg: Get the Y register value
//-------------------------------------------------
unsigned int ef9365_device::get_y_reg()
{
return (m_registers[EF936X_REG_Y_MSB]<<8) | m_registers[EF936X_REG_Y_LSB];
}
//-------------------------------------------------
// set_x_reg: Set the X register value
//-------------------------------------------------
void ef9365_device::set_x_reg(unsigned int x)
{
m_registers[EF936X_REG_X_MSB] = x >> 8;
m_registers[EF936X_REG_X_LSB] = x & 0xFF;
}
//-------------------------------------------------
// set_y_reg: Set the Y register value
//-------------------------------------------------
void ef9365_device::set_y_reg(unsigned int y)
{
m_registers[EF936X_REG_Y_MSB] = y >> 8;
m_registers[EF936X_REG_Y_LSB] = y & 0xFF;
}
// set then ef9365 mode
//-------------------------------------------------
// set_video_mode: Set output screen format
//-------------------------------------------------
void ef9365_device::set_video_mode(void)
{
UINT16 new_width = bitplan_xres;
UINT16 new_width = bitplane_xres;
if (m_screen->width() != new_width)
{
@ -346,15 +444,19 @@ void ef9365_device::set_video_mode(void)
memset(m_border, 0, sizeof(m_border));
}
// Read back the latched bitplan words
UINT8 ef9365_device::get_last_readback_word(int bitplan_number, int * pixel_offset)
//-------------------------------------------------
// get_last_readback_word: Read back the latched
// bitplane words
//-------------------------------------------------
UINT8 ef9365_device::get_last_readback_word(int bitplane_number, int * pixel_offset)
{
if( pixel_offset )
*pixel_offset = m_readback_latch_pix_offset;
if( bitplan_number < nb_of_bitplans )
if( bitplane_number < nb_of_bitplanes )
{
return m_readback_latch[bitplan_number];
return m_readback_latch[bitplane_number];
}
else
{
@ -362,52 +464,70 @@ UINT8 ef9365_device::get_last_readback_word(int bitplan_number, int * pixel_offs
}
}
//-------------------------------------------------
// draw_border: Draw the left and right borders
// ( No border for the moment ;) )
//-------------------------------------------------
void ef9365_device::draw_border(UINT16 line)
{
}
//-------------------------------------------------
// plot: Plot a pixel to the bitplanes
// at the x & y position with the m_current_color color
//-------------------------------------------------
void ef9365_device::plot(int x_pos,int y_pos)
{
int p;
if( ( x_pos >= 0 && y_pos >= 0 ) && ( x_pos < bitplan_xres && y_pos < bitplan_yres ) )
if( ( x_pos >= 0 && y_pos >= 0 ) && ( x_pos < bitplane_xres && y_pos < bitplane_yres ) )
{
if ( m_registers[EF936X_REG_CTRL1] & 0x01 )
{
y_pos = ( (bitplan_yres - 1) - y_pos );
y_pos = ( (bitplane_yres - 1) - y_pos );
if( (m_registers[EF936X_REG_CTRL1] & 0x02) )
{
// Pen
for( p = 0 ; p < nb_of_bitplans ; p++ )
for( p = 0 ; p < nb_of_bitplanes ; p++ )
{
if( m_current_color & (0x01 << p) )
m_videoram->write_byte ( (EF936X_BITPLAN_MAX_SIZE*p) + (((y_pos*bitplan_xres) + x_pos)>>3), m_videoram->read_byte( (EF936X_BITPLAN_MAX_SIZE*p) + (((y_pos*bitplan_xres) + x_pos)>>3)) | (0x80 >> (((y_pos*bitplan_xres) + x_pos)&7) ) );
m_videoram->write_byte ( (EF936X_BITPLANE_MAX_SIZE*p) + (((y_pos*bitplane_xres) + x_pos)>>3), m_videoram->read_byte( (EF936X_BITPLANE_MAX_SIZE*p) + (((y_pos*bitplane_xres) + x_pos)>>3)) | (0x80 >> (((y_pos*bitplane_xres) + x_pos)&7) ) );
else
m_videoram->write_byte ( (EF936X_BITPLAN_MAX_SIZE*p) + (((y_pos*bitplan_xres) + x_pos)>>3), m_videoram->read_byte( (EF936X_BITPLAN_MAX_SIZE*p) + (((y_pos*bitplan_xres) + x_pos)>>3)) & ~(0x80 >> (((y_pos*bitplan_xres) + x_pos)&7) ) );
m_videoram->write_byte ( (EF936X_BITPLANE_MAX_SIZE*p) + (((y_pos*bitplane_xres) + x_pos)>>3), m_videoram->read_byte( (EF936X_BITPLANE_MAX_SIZE*p) + (((y_pos*bitplane_xres) + x_pos)>>3)) & ~(0x80 >> (((y_pos*bitplane_xres) + x_pos)&7) ) );
}
}
else
{
// Eraser
for( p = 0 ; p < nb_of_bitplans ; p++ )
for( p = 0 ; p < nb_of_bitplanes ; p++ )
{
m_videoram->write_byte ( (EF936X_BITPLAN_MAX_SIZE*p) + (((y_pos*bitplan_xres) + x_pos)>>3), m_videoram->read_byte( (EF936X_BITPLAN_MAX_SIZE*p) + (((y_pos*bitplan_xres) + x_pos)>>3)) | (0x80 >> (((y_pos*bitplan_xres) + x_pos)&7) ) );
m_videoram->write_byte ( (EF936X_BITPLANE_MAX_SIZE*p) + (((y_pos*bitplane_xres) + x_pos)>>3), m_videoram->read_byte( (EF936X_BITPLANE_MAX_SIZE*p) + (((y_pos*bitplane_xres) + x_pos)>>3)) | (0x80 >> (((y_pos*bitplane_xres) + x_pos)&7) ) );
}
}
}
}
}
const static unsigned int vectortype_code[][8] =
{
{0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // Continous drawing
{0x82,0x02,0x00,0x00,0x00,0x00,0x00,0x00}, // dotted - 2 dots on, 2 dots off
{0x84,0x04,0x00,0x00,0x00,0x00,0x00,0x00}, // dashed - 4 dots on, 4 dots off
{0x8A,0x02,0x82,0x02,0x00,0x00,0x00,0x00} // dotted-dashed - 10 dots on, 2 dots off, 2 dots on, 2 dots off
{0x82,0x02,0x00,0x00,0x00,0x00,0x00,0x00}, // Dotted - 2 dots on, 2 dots off
{0x84,0x04,0x00,0x00,0x00,0x00,0x00,0x00}, // Dashed - 4 dots on, 4 dots off
{0x8A,0x02,0x82,0x02,0x00,0x00,0x00,0x00} // Dotted-Dashed - 10 dots on, 2 dots off, 2 dots on, 2 dots off
};
//-------------------------------------------------
// draw_vector: Vector drawing function
// from the x1 & y1 position to the x2 & y2 position
// with the m_current_color color
// (Bresenham's line algorithm)
//-------------------------------------------------
int ef9365_device::draw_vector(int x1,int y1,int x2,int y2)
{
int dx;
@ -594,6 +714,11 @@ int ef9365_device::draw_vector(int x1,int y1,int x2,int y2)
return compute_cycles;
}
//-------------------------------------------------
// get_char_pix: Get a character pixel state
// from the charset.
//-------------------------------------------------
int ef9365_device::get_char_pix( unsigned char c, int x, int y )
{
int char_base,char_pix;
@ -615,6 +740,12 @@ int ef9365_device::get_char_pix( unsigned char c, int x, int y )
return 0;
}
//-------------------------------------------------
// draw_character: Character and block drawing function
// Set smallblock to draw a 4x4 block
// Set block to draw a 5x8 block
//-------------------------------------------------
int ef9365_device::draw_character( unsigned char c, int block, int smallblock )
{
int x_char,y_char;
@ -720,75 +851,91 @@ int ef9365_device::draw_character( unsigned char c, int block, int smallblock )
return compute_cycles;
}
//-------------------------------------------------
// cycles_to_us: Convert a number of clock cycles to us
//-------------------------------------------------
int ef9365_device::cycles_to_us(int cycles)
{
return ( (float)cycles * ( (float)1000000 / (float)clock_freq ) );
}
// Latch the bitplan words pointed by the x & y regiters (Memory read back function)
//-------------------------------------------------
// dump_bitplanes_word: Latch the bitplane words
// pointed by the x & y regiters
// (Memory read back function)
//-------------------------------------------------
void ef9365_device::dump_bitplanes_word()
{
int p;
int pixel_ptr;
pixel_ptr = ( ( ( ( bitplan_yres - 1 ) - ( get_y_reg() & ( bitplan_yres - 1 ) ) ) * bitplan_xres ) + ( get_x_reg() & ( bitplan_xres - 1 ) ) );
pixel_ptr = ( ( ( ( bitplane_yres - 1 ) - ( get_y_reg() & ( bitplane_yres - 1 ) ) ) * bitplane_xres ) + ( get_x_reg() & ( bitplane_xres - 1 ) ) );
#ifdef DBGMODE
printf("dump : x = %d , y = %d\n", get_x_reg() ,get_y_reg());
#endif
for( p = 0; p < nb_of_bitplans ; p++ )
for( p = 0; p < nb_of_bitplanes ; p++ )
{
if( pixel_ptr & 0x4 )
{
m_readback_latch[p] = ( m_videoram->read_byte( (EF936X_BITPLAN_MAX_SIZE*p) + (pixel_ptr>>3) ) ) & 0xF ;
m_readback_latch[p] = ( m_videoram->read_byte( (EF936X_BITPLANE_MAX_SIZE*p) + (pixel_ptr>>3) ) ) & 0xF ;
}
else
{
m_readback_latch[p] = ( m_videoram->read_byte( (EF936X_BITPLAN_MAX_SIZE*p) + (pixel_ptr>>3) ) >> 4 ) & 0xF ;
m_readback_latch[p] = ( m_videoram->read_byte( (EF936X_BITPLANE_MAX_SIZE*p) + (pixel_ptr>>3) ) >> 4 ) & 0xF ;
}
}
m_readback_latch_pix_offset = pixel_ptr & 0x3;
}
//-------------------------------------------------
// screen_scanning: Fill / Clear framebuffer memory
//-------------------------------------------------
void ef9365_device::screen_scanning( int force_clear )
{
int x,y,p;
if( (m_registers[EF936X_REG_CTRL1] & 0x02) && !force_clear )
{
for( y = 0; y < bitplan_yres; y++ )
for( y = 0; y < bitplane_yres; y++ )
{
for( x = 0; x < bitplan_xres; x++ )
for( x = 0; x < bitplane_xres; x++ )
{
for( p = 0 ; p < nb_of_bitplans ; p++ )
for( p = 0 ; p < nb_of_bitplanes ; p++ )
{
if( m_current_color & (0x01 << p) )
m_videoram->write_byte ( (EF936X_BITPLAN_MAX_SIZE*p) + (((y*bitplan_xres) + x)>>3), m_videoram->read_byte( (EF936X_BITPLAN_MAX_SIZE*p) + (((y*bitplan_xres) + x)>>3)) | (0x80 >> (((y*bitplan_xres) + x)&7) ) );
m_videoram->write_byte ( (EF936X_BITPLANE_MAX_SIZE*p) + (((y*bitplane_xres) + x)>>3), m_videoram->read_byte( (EF936X_BITPLANE_MAX_SIZE*p) + (((y*bitplane_xres) + x)>>3)) | (0x80 >> (((y*bitplane_xres) + x)&7) ) );
else
m_videoram->write_byte ( (EF936X_BITPLAN_MAX_SIZE*p) + (((y*bitplan_xres) + x)>>3), m_videoram->read_byte( (EF936X_BITPLAN_MAX_SIZE*p) + (((y*bitplan_xres) + x)>>3)) & ~(0x80 >> (((y*bitplan_xres) + x)&7) ) );
m_videoram->write_byte ( (EF936X_BITPLANE_MAX_SIZE*p) + (((y*bitplane_xres) + x)>>3), m_videoram->read_byte( (EF936X_BITPLANE_MAX_SIZE*p) + (((y*bitplane_xres) + x)>>3)) & ~(0x80 >> (((y*bitplane_xres) + x)&7) ) );
}
}
}
}
else
{
for( y = 0; y < bitplan_yres; y++)
for( y = 0; y < bitplane_yres; y++)
{
for( x = 0; x < bitplan_xres; x++)
for( x = 0; x < bitplane_xres; x++)
{
for( p = 0 ; p < nb_of_bitplans ; p++ )
for( p = 0 ; p < nb_of_bitplanes ; p++ )
{
m_videoram->write_byte ( (EF936X_BITPLAN_MAX_SIZE*p) + (((y*bitplan_xres) + x)>>3), m_videoram->read_byte( (EF936X_BITPLAN_MAX_SIZE*p) + (((y*bitplan_xres) + x)>>3)) | (0x80 >> (((y*bitplan_xres) + x)&7) ) );
m_videoram->write_byte ( (EF936X_BITPLANE_MAX_SIZE*p) + (((y*bitplane_xres) + x)>>3), m_videoram->read_byte( (EF936X_BITPLANE_MAX_SIZE*p) + (((y*bitplane_xres) + x)>>3)) | (0x80 >> (((y*bitplane_xres) + x)&7) ) );
}
}
}
}
}
// Execute EF9365 command
//-------------------------------------------------
// ef9365_exec: EF936X Command decoder and execution
//-------------------------------------------------
void ef9365_device::ef9365_exec(UINT8 cmd)
{
int tmp_delta_x,tmp_delta_y;
@ -821,7 +968,7 @@ void ef9365_device::ef9365_exec(UINT8 cmd)
break;
case 0x4: // Clear screen
screen_scanning(1);
set_busy_flag( cycles_to_us( bitplan_xres*bitplan_yres ) ); // Timing to check on the real hardware
set_busy_flag( cycles_to_us( bitplane_xres*bitplane_yres ) ); // Timing to check on the real hardware
break;
case 0x5: // X and Y registers reset to 0
set_x_reg(0);
@ -832,12 +979,12 @@ void ef9365_device::ef9365_exec(UINT8 cmd)
set_x_reg(0);
set_y_reg(0);
screen_scanning(1);
set_busy_flag( cycles_to_us( bitplan_xres*bitplan_yres ) ); // Timing to check on the real hardware
set_busy_flag( cycles_to_us( bitplane_xres*bitplane_yres ) ); // Timing to check on the real hardware
break;
case 0x7: // Clear screen, set CSIZE to code "minsize". All other registers reset to 0
m_registers[EF936X_REG_CSIZE] = 0x11;
screen_scanning(1);
set_busy_flag( cycles_to_us( bitplan_xres*bitplan_yres ) ); // Timing to check on the real hardware
set_busy_flag( cycles_to_us( bitplane_xres*bitplane_yres ) ); // Timing to check on the real hardware
break;
case 0x8: // Light-pen initialization (/White forced low)
set_busy_flag( cycles_to_us( 4 ) ); // Timing to check on the real hardware
@ -855,7 +1002,7 @@ void ef9365_device::ef9365_exec(UINT8 cmd)
break;
case 0xC: // Screen scanning : pen or Eraser as defined by CTRL1
screen_scanning(0);
set_busy_flag( cycles_to_us( bitplan_xres*bitplan_yres ) ); // Timing to check on the real hardware
set_busy_flag( cycles_to_us( bitplane_xres*bitplane_yres ) ); // Timing to check on the real hardware
break;
case 0xD: // X reset to 0
set_x_reg(0);
@ -984,26 +1131,26 @@ void ef9365_device::ef9365_exec(UINT8 cmd)
}
}
/**************************************************************
EF9365 interface
**************************************************************/
//-------------------------------------------------
// screen_update: Framebuffer video ouput
//-------------------------------------------------
UINT32 ef9365_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
int i,j,ptr,p;
unsigned char color_index;
for(j=0;j<bitplan_yres;j++)
for(j=0;j<bitplane_yres;j++)
{
for(i=0;i<bitplan_xres;i++)
for(i=0;i<bitplane_xres;i++)
{
color_index = 0x00;
ptr = ( bitplan_xres * j ) + i;
ptr = ( bitplane_xres * j ) + i;
for( p = 0; p < nb_of_bitplans; p++)
for( p = 0; p < nb_of_bitplanes; p++)
{
if( m_videoram->read_byte( (EF936X_BITPLAN_MAX_SIZE*p) + (ptr>>3)) & (0x80>>(ptr&7)))
if( m_videoram->read_byte( (EF936X_BITPLANE_MAX_SIZE*p) + (ptr>>3)) & (0x80>>(ptr&7)))
{
color_index |= (0x01<<p);
}
@ -1017,6 +1164,10 @@ UINT32 ef9365_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap,
return 0;
}
//-------------------------------------------------
// update_scanline: Scanline callback
//-------------------------------------------------
void ef9365_device::update_scanline(UINT16 scanline)
{
if (scanline == vsync_scanline_pos)
@ -1037,6 +1188,10 @@ void ef9365_device::update_scanline(UINT16 scanline)
}
}
//-------------------------------------------------
// data_r: Registers read access callback
//-------------------------------------------------
READ8_MEMBER( ef9365_device::data_r )
{
unsigned char return_value;
@ -1126,6 +1281,10 @@ READ8_MEMBER( ef9365_device::data_r )
return return_value;
}
//-------------------------------------------------
// data_w: Registers write access callback
//-------------------------------------------------
WRITE8_MEMBER( ef9365_device::data_w )
{
#ifdef DBGMODE

View File

@ -13,14 +13,14 @@
#ifndef __EF9365_H__
#define __EF9365_H__
#define EF936X_BITPLAN_MAX_SIZE 0x8000
#define EF936X_MAX_BITPLANS 8
#define EF936X_BITPLANE_MAX_SIZE 0x8000
#define EF936X_MAX_BITPLANES 8
#define MCFG_EF936X_PALETTE(_palette_tag) \
ef9365_device::static_set_palette_tag(*device, "^" _palette_tag);
#define MCFG_EF936X_BITPLANS_CNT(_bitplans_number) \
ef9365_device::static_set_nb_bitplans(*device,_bitplans_number);
#define MCFG_EF936X_BITPLANES_CNT(_bitplanes_number) \
ef9365_device::static_set_nb_bitplanes(*device,_bitplanes_number);
#define MCFG_EF936X_DISPLAYMODE(_display_mode) \
ef9365_device::static_set_display_mode(*device,_display_mode);
@ -44,7 +44,7 @@ public:
// static configuration
static void static_set_palette_tag(device_t &device, const char *tag);
static void static_set_nb_bitplans(device_t &device, int nb_bitplans );
static void static_set_nb_bitplanes(device_t &device, int nb_bitplanes );
static void static_set_display_mode(device_t &device, int display_mode );
template<class _Object> static devcb_base &set_irq_handler(device_t &device, _Object object) { return downcast<ef9365_device &>(device).m_irq_handler.set_callback(object); }
@ -56,7 +56,7 @@ public:
void set_color_filler( UINT8 color );
void set_color_entry( int index, UINT8 r, UINT8 g, UINT8 b );
UINT8 get_last_readback_word(int bitplan_number, int * pixel_offset);
UINT8 get_last_readback_word(int bitplane_number, int * pixel_offset);
UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
@ -108,16 +108,16 @@ private:
UINT8 m_state; //status register
UINT8 m_border[80]; //border color
rgb_t palette[256]; // 8 bitplans max -> 256 colors max
int nb_of_bitplans;
rgb_t palette[256]; // 8 bitplanes max -> 256 colors max
int nb_of_bitplanes;
int nb_of_colors;
int bitplan_xres;
int bitplan_yres;
int bitplane_xres;
int bitplane_yres;
UINT16 overflow_mask_x;
UINT16 overflow_mask_y;
int vsync_scanline_pos;
UINT8 m_readback_latch[EF936X_MAX_BITPLANS]; // Last DRAM Readback buffer (Filled after a Direct Memory Access Request command)
UINT8 m_readback_latch[EF936X_MAX_BITPLANES]; // Last DRAM Readback buffer (Filled after a Direct Memory Access Request command)
int m_readback_latch_pix_offset;
UINT32 clock_freq;
@ -150,6 +150,8 @@ extern const device_type EF9365;
#define EF936X_256x256_DISPLAY_MODE 0x00
#define EF936X_512x512_DISPLAY_MODE 0x01
#define EF936X_512x256_DISPLAY_MODE 0x02
#define EF936X_128x128_DISPLAY_MODE 0x03
#define EF936X_64x64_DISPLAY_MODE 0x04
#endif