diff options
| author | 2015-12-29 17:30:42 +0100 | |
|---|---|---|
| committer | 2015-12-29 17:30:42 +0100 | |
| commit | dfb5b3b6fdbfc5bdc4ea19ae0314407e899da0dc (patch) | |
| tree | 098d3f7511b0e745dbe440f50aa2d4e4179dd548 /src | |
| parent | 0a9a292f68b855eadf5c369b68b7b23083b781a4 (diff) | |
| parent | 53bc3b1ad236df2c0b6a8f5c023c3b42d2b54a89 (diff) | |
Merge pull request #533 from jfdelnero/master
Some EF9365/EF9366 new features, code cleanup.
Diffstat (limited to 'src')
| -rw-r--r-- | src/devices/video/ef9365.cpp | 328 | ||||
| -rw-r--r-- | src/devices/video/ef9365.h | 29 | ||||
| -rw-r--r-- | src/mame/drivers/squale.cpp | 78 |
3 files changed, 360 insertions, 75 deletions
diff --git a/src/devices/video/ef9365.cpp b/src/devices/video/ef9365.cpp index d4aeb78914b..0a5405fcf65 100644 --- a/src/devices/video/ef9365.cpp +++ b/src/devices/video/ef9365.cpp @@ -3,20 +3,77 @@ /********************************************************************* - ef9365.c - - Thomson EF9365/EF9366 video controller emulator code - + ef9365.c + + 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", @@ -30,13 +87,14 @@ const char * register_names[]= "0x08 - X MSBs ", "0x09 - X LSBs ", "0x0A - Y MSBs ", - "0x0B - X MSBs ", + "0x0B - Y LSBs ", "0x0C - XLP ", "0x0D - YLP ", "0x0E - RESERVED ", "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,52 +444,90 @@ void ef9365_device::set_video_mode(void) memset(m_border, 0, sizeof(m_border)); } +//------------------------------------------------- +// 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( bitplane_number < nb_of_bitplanes ) + { + return m_readback_latch[bitplane_number]; + } + else + { + return 0x00; + } +} + +//------------------------------------------------- +// 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; @@ -578,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; @@ -599,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; @@ -704,47 +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 ) ); } +//------------------------------------------------- +// 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 = ( ( ( ( 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_bitplanes ; p++ ) + { + if( pixel_ptr & 0x4 ) + { + 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_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; @@ -777,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); @@ -788,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 @@ -811,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); @@ -822,7 +1013,8 @@ void ef9365_device::ef9365_exec(UINT8 cmd) set_busy_flag( cycles_to_us( 4 ) ); // Timing to check on the real hardware break; case 0xF: // Direct image memory access request for the next free cycle. - set_busy_flag( cycles_to_us( 4 ) ); // Timing to check on the real hardware + set_busy_flag( cycles_to_us( 64 ) ); // Timing to check on the real hardware + dump_bitplanes_word(); break; default: logerror("Unemulated EF9365 cmd: %02x\n", cmd); @@ -939,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); } @@ -972,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) @@ -992,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; @@ -1081,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 diff --git a/src/devices/video/ef9365.h b/src/devices/video/ef9365.h index 2b20e6bdcf4..9127bf8965e 100644 --- a/src/devices/video/ef9365.h +++ b/src/devices/video/ef9365.h @@ -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,6 +56,8 @@ 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 bitplane_number, int * pixel_offset); + UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); protected: @@ -86,8 +88,8 @@ private: void set_video_mode(void); void draw_border(UINT16 line); void ef9365_exec(UINT8 cmd); - int cycles_to_us(int cycles); - + int cycles_to_us(int cycles); + void dump_bitplanes_word(); void update_interrupts(); // internal state @@ -106,15 +108,18 @@ 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_BITPLANES]; // Last DRAM Readback buffer (Filled after a Direct Memory Access Request command) + int m_readback_latch_pix_offset; + UINT32 clock_freq; bitmap_rgb32 m_screen_out; @@ -145,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 diff --git a/src/mame/drivers/squale.cpp b/src/mame/drivers/squale.cpp index 0f667f33c52..d536d07f7b1 100644 --- a/src/mame/drivers/squale.cpp +++ b/src/mame/drivers/squale.cpp @@ -89,6 +89,8 @@ public: { } DECLARE_WRITE8_MEMBER(ctrl_w); + DECLARE_READ8_MEMBER(video_ram_read_reg1); + DECLARE_READ8_MEMBER(video_ram_read_reg2); DECLARE_WRITE8_MEMBER(fdc_sel0_w); DECLARE_READ8_MEMBER(fdc_sel0_r); DECLARE_WRITE8_MEMBER(fdc_sel1_w); @@ -157,6 +159,76 @@ WRITE8_MEMBER( squale_state::ctrl_w ) m_ef9365->set_color_filler(data & 0xF); } +READ8_MEMBER( squale_state::video_ram_read_reg1 ) +{ + UINT8 data; + int p; + + //D7 D0 + //I2R2G2B2 I3R3G3B3 + + data = 0x00; + + for(p = 0; p < 4 ; p++) + { + if( m_ef9365->get_last_readback_word(p, 0) & 8 ) + { + data |= (0x01 << p); + } + } + + data = data << 4; + + for(p = 0; p < 4 ; p++) + { + if( m_ef9365->get_last_readback_word(p, 0) & 4 ) + { + data |= (0x01 << p); + } + } + + #ifdef DBGMODE + printf("read video_ram_read_reg1 reg : 0x%X\n",data); + #endif + + return data; +} + +READ8_MEMBER( squale_state::video_ram_read_reg2 ) +{ + UINT8 data; + int p; + + //D7 D0 + //I0R0G0B0 I1R1G1B1 + + data = 0x00; + + for(p = 0; p < 4 ; p++) + { + if( m_ef9365->get_last_readback_word(p, 0) & 2 ) + { + data |= (0x01 << p); + } + } + + data = data << 4; + + for(p = 0; p < 4 ; p++) + { + if( m_ef9365->get_last_readback_word(p, 0) & 1 ) + { + data |= (0x01 << p); + } + } + + #ifdef DBGMODE + printf("read video_ram_read_reg2 reg : 0x%X\n",data); + #endif + + return data; +} + /********************************** * Floppy controller I/O Handlers * ***********************************/ @@ -542,6 +614,8 @@ static ADDRESS_MAP_START(squale_mem, AS_PROGRAM, 8, squale_state) AM_RANGE(0x0000,0xefff) AM_RAM AM_RANGE(0xf000,0xf00f) AM_DEVREADWRITE("ef9365", ef9365_device, data_r, data_w) AM_RANGE(0xf010,0xf01f) AM_WRITE( ctrl_w ) + AM_RANGE(0xf020,0xf02f) AM_READ( video_ram_read_reg1 ) + AM_RANGE(0xf030,0xf03f) AM_READ( video_ram_read_reg2 ) AM_RANGE(0xf044,0xf047) AM_DEVREADWRITE("pia_u75", pia6821_device, read, write) AM_RANGE(0xf048,0xf04b) AM_DEVREADWRITE("pia_u72", pia6821_device, read, write) AM_RANGE(0xf050,0xf05f) AM_DEVREADWRITE("ef6850", acia6850_device, data_r, data_w) @@ -744,7 +818,7 @@ static MACHINE_CONFIG_START( squale, squale_state ) MCFG_DEVICE_ADD("ef9365", EF9365, VIDEO_CLOCK) MCFG_EF936X_PALETTE("palette") - MCFG_EF936X_BITPLANS_CNT(4); + MCFG_EF936X_BITPLANES_CNT(4); MCFG_EF936X_DISPLAYMODE(EF936X_256x256_DISPLAY_MODE); MCFG_TIMER_DRIVER_ADD_SCANLINE("squale_sl", squale_state, squale_scanline, "screen", 0, 10) @@ -778,4 +852,4 @@ ROM_END /* Driver */ /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ -COMP( 1984, squale, 0, 0, squale, squale,driver_device, 0, "Apollo 7", "Squale", MACHINE_TYPE_COMPUTER | MACHINE_IMPERFECT_GRAPHICS ) +COMP( 1984, squale, 0, 0, squale, squale,driver_device, 0, "Apollo 7", "Squale", MACHINE_TYPE_COMPUTER ) |
