EF9365 : Fix the hardware vector engine. (#2370)

This fix the ARC Squale Basic instruction and probably many others stuffs
This commit is contained in:
Jean-François DEL NERO 2017-06-08 04:53:52 +02:00 committed by Vas Crabb
parent ff01a9488f
commit 2f89a3c074
2 changed files with 69 additions and 58 deletions

View File

@ -428,27 +428,27 @@ void ef9365_device::set_busy_flag(int period)
// get_x_reg: Get the X register value // get_x_reg: Get the X register value
//------------------------------------------------- //-------------------------------------------------
unsigned int ef9365_device::get_x_reg() uint16_t ef9365_device::get_x_reg()
{ {
return (m_registers[EF936X_REG_X_MSB]<<8) | m_registers[EF936X_REG_X_LSB]; return ((m_registers[EF936X_REG_X_MSB] & 0x0F)<<8) | m_registers[EF936X_REG_X_LSB];
} }
//------------------------------------------------- //-------------------------------------------------
// get_y_reg: Get the Y register value // get_y_reg: Get the Y register value
//------------------------------------------------- //-------------------------------------------------
unsigned int ef9365_device::get_y_reg() uint16_t ef9365_device::get_y_reg()
{ {
return (m_registers[EF936X_REG_Y_MSB]<<8) | m_registers[EF936X_REG_Y_LSB]; return ((m_registers[EF936X_REG_Y_MSB] & 0x0F)<<8) | m_registers[EF936X_REG_Y_LSB];
} }
//------------------------------------------------- //-------------------------------------------------
// set_x_reg: Set the X register value // set_x_reg: Set the X register value
//------------------------------------------------- //-------------------------------------------------
void ef9365_device::set_x_reg(unsigned int x) void ef9365_device::set_x_reg(uint16_t x)
{ {
m_registers[EF936X_REG_X_MSB] = x >> 8; m_registers[EF936X_REG_X_MSB] = ( x >> 8 ) & 0x0F;
m_registers[EF936X_REG_X_LSB] = x & 0xFF; m_registers[EF936X_REG_X_LSB] = x & 0xFF;
} }
@ -456,9 +456,9 @@ void ef9365_device::set_x_reg(unsigned int x)
// set_y_reg: Set the Y register value // set_y_reg: Set the Y register value
//------------------------------------------------- //-------------------------------------------------
void ef9365_device::set_y_reg(unsigned int y) void ef9365_device::set_y_reg(uint16_t y)
{ {
m_registers[EF936X_REG_Y_MSB] = y >> 8; m_registers[EF936X_REG_Y_MSB] = ( y >> 8 ) & 0x0F;
m_registers[EF936X_REG_Y_LSB] = y & 0xFF; m_registers[EF936X_REG_Y_LSB] = y & 0xFF;
} }
@ -560,17 +560,17 @@ const static unsigned int vectortype_code[][8] =
//------------------------------------------------- //-------------------------------------------------
// draw_vector: Vector drawing function // draw_vector: Vector drawing function
// from the x1 & y1 position to the x2 & y2 position // from the start_x & start_y position to the start_x+delta_x & start_y+delta_y position
// with the m_current_color color // with the m_current_color color
// (Bresenham's line algorithm) // (Bresenham's line algorithm)
//------------------------------------------------- //-------------------------------------------------
int ef9365_device::draw_vector(int x1,int y1,int x2,int y2) int ef9365_device::draw_vector(uint16_t start_x,uint16_t start_y,short delta_x,short delta_y)
{ {
int dx; int dx;
int dy,t; int dy,t;
int e; int e;
int x,y; int x,y,dest_x,dest_y,end_x,end_y;
int incy; int incy;
int diago,horiz; int diago,horiz;
unsigned char c1; unsigned char c1;
@ -580,8 +580,16 @@ int ef9365_device::draw_vector(int x1,int y1,int x2,int y2)
int dot_code_ptr; int dot_code_ptr;
int compute_cycles; int compute_cycles;
LOG("EF9365 draw_vector : Start=(%d,%d) End=(%d,%d)\n", start_x,start_y,start_x+delta_x,start_y+delta_y);
compute_cycles = 0; compute_cycles = 0;
dest_x = start_x + delta_x;
dest_y = start_y + delta_y;
end_x = dest_x;
end_y = dest_y;
c1=0; c1=0;
incy=1; incy=1;
@ -593,25 +601,25 @@ int ef9365_device::draw_vector(int x1,int y1,int x2,int y2)
pen_state = 0; pen_state = 0;
state_counter &= ~0x80; state_counter &= ~0x80;
if(x2>x1) if( dest_x > start_x )
dx = x2 - x1; dx = dest_x - start_x;
else else
dx = x1 - x2; dx = start_x - dest_x;
if(y2>y1) if( dest_y > start_y )
dy = y2 - y1; dy = dest_y - start_y;
else else
dy = y1 - y2; dy = start_y - dest_y;
if( dy > dx ) if( dy > dx )
{ {
t = y2; t = dest_y;
y2 = x2; dest_y = dest_x;
x2 = t; dest_x = t;
t = y1; t = start_y;
y1 = x1; start_y = start_x;
x1 = t; start_x = t;
t = dx; t = dx;
dx = dy; dx = dy;
@ -620,35 +628,35 @@ int ef9365_device::draw_vector(int x1,int y1,int x2,int y2)
c1 = 1; c1 = 1;
} }
if( x1 > x2 ) if( start_x > dest_x )
{ {
t = y2; t = dest_y;
y2 = y1; dest_y = start_y;
y1 = t; start_y = t;
t = x1; t = start_x;
x1 = x2; start_x = dest_x;
x2 = t; dest_x = t;
} }
horiz = dy<<1; horiz = dy<<1;
diago = ( dy - dx )<<1; diago = ( dy - dx )<<1;
e = ( dy<<1 ) - dx; e = ( dy<<1 ) - dx;
if( y1 <= y2 ) if( start_y <= dest_y )
incy = 1; incy = 1;
else else
incy = -1; incy = -1;
x = x1; x = start_x;
y = y1; y = start_y;
if(c1) if(c1)
{ {
do do
{ {
if(pen_state) if(pen_state)
plot(y,x); plot(y % bitplane_xres, x % bitplane_yres);
compute_cycles++; compute_cycles++;
@ -693,14 +701,14 @@ int ef9365_device::draw_vector(int x1,int y1,int x2,int y2)
x++; x++;
}while( x <= x2 ); } while (x <= dest_x);
} }
else else
{ {
do do
{ {
if(pen_state) if(pen_state)
plot(x,y); plot(x % bitplane_xres, y % bitplane_yres);
compute_cycles++; compute_cycles++;
@ -745,9 +753,12 @@ int ef9365_device::draw_vector(int x1,int y1,int x2,int y2)
x++; x++;
}while( x <= x2 ); } while (x <= dest_x);
} }
set_x_reg(end_x);
set_y_reg(end_y);
return compute_cycles; return compute_cycles;
} }
@ -1077,29 +1088,29 @@ void ef9365_device::ef9365_exec(uint8_t cmd)
switch ( cmd & 0x7 ) // Direction code switch ( cmd & 0x7 ) // Direction code
{ {
case 0x1: case 0x1:
busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), get_x_reg() + tmp_delta_x, get_y_reg() + tmp_delta_y); busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), tmp_delta_x, tmp_delta_y );
break; break;
case 0x3: case 0x3:
busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), get_x_reg() - tmp_delta_x, get_y_reg() + tmp_delta_y); busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), -tmp_delta_x, tmp_delta_y );
break; break;
case 0x5: case 0x5:
busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), get_x_reg() + tmp_delta_x, get_y_reg() - tmp_delta_y); busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), tmp_delta_x, -tmp_delta_y );
break; break;
case 0x7: case 0x7:
busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), get_x_reg() - tmp_delta_x, get_y_reg() - tmp_delta_y); busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), -tmp_delta_x, -tmp_delta_y );
break; break;
case 0x0: case 0x0:
busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), get_x_reg() + tmp_delta_x, get_y_reg() ); busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), tmp_delta_x, 0 );
break; break;
case 0x2: case 0x2:
busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), get_x_reg(), get_y_reg() + tmp_delta_y); busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), 0, tmp_delta_y );
break; break;
case 0x4: case 0x4:
busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), get_x_reg(), get_y_reg() - tmp_delta_y); busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), 0, -tmp_delta_y );
break; break;
case 0x6: case 0x6:
busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), get_x_reg() - tmp_delta_x, get_y_reg() ); busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), -tmp_delta_x , 0 );
break; break;
} }
set_busy_flag( cycles_to_us( busy_cycles ) ); set_busy_flag( cycles_to_us( busy_cycles ) );
@ -1117,29 +1128,29 @@ void ef9365_device::ef9365_exec(uint8_t cmd)
switch ( cmd & 0x7 ) // Direction code switch ( cmd & 0x7 ) // Direction code
{ {
case 0x1: case 0x1:
busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), get_x_reg() + tmp_delta_x, get_y_reg() + tmp_delta_y); busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), tmp_delta_x, tmp_delta_y );
break; break;
case 0x3: case 0x3:
busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), get_x_reg() - tmp_delta_x, get_y_reg() + tmp_delta_y); busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), -tmp_delta_x, tmp_delta_y );
break; break;
case 0x5: case 0x5:
busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), get_x_reg() + tmp_delta_x, get_y_reg() - tmp_delta_y); busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), tmp_delta_x, -tmp_delta_y );
break; break;
case 0x7: case 0x7:
busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), get_x_reg() - tmp_delta_x, get_y_reg() - tmp_delta_y); busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), -tmp_delta_x, -tmp_delta_y );
break; break;
case 0x0: case 0x0:
busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), get_x_reg() + tmp_delta_x, get_y_reg() ); busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), tmp_delta_x, 0 );
break; break;
case 0x2: case 0x2:
busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), get_x_reg(), get_y_reg() + tmp_delta_y); busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), 0, tmp_delta_y );
break; break;
case 0x4: case 0x4:
busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), get_x_reg(), get_y_reg() - tmp_delta_y); busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), 0, -tmp_delta_y );
break; break;
case 0x6: case 0x6:
busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), get_x_reg() - tmp_delta_x, get_y_reg() ); busy_cycles = draw_vector ( get_x_reg(), get_y_reg(), -tmp_delta_x, 0 );
break; break;
} }

View File

@ -83,11 +83,11 @@ private:
int get_char_pix( unsigned char c, int x, int y ); int get_char_pix( unsigned char c, int x, int y );
void plot(int x_pos,int y_pos); void plot(int x_pos,int y_pos);
int draw_character( unsigned char c, int block, int smallblock ); int draw_character( unsigned char c, int block, int smallblock );
int draw_vector(int x1,int y1,int x2,int y2); int draw_vector(uint16_t start_x,uint16_t start_y,short delta_x,short delta_y);
unsigned int get_x_reg(); uint16_t get_x_reg();
unsigned int get_y_reg(); uint16_t get_y_reg();
void set_x_reg(unsigned int x); void set_x_reg(uint16_t x);
void set_y_reg(unsigned int y); void set_y_reg(uint16_t y);
void screen_scanning( int force_clear ); void screen_scanning( int force_clear );
void set_busy_flag(int period); void set_busy_flag(int period);
void set_video_mode(void); void set_video_mode(void);