text: // license:BSD-3-Clause
  // copyright-holders:Brad Oliver,Sal and John Bugliarisi,Paul Priest
  /***************************************************************************
  
    naughtyb.cpp
  
    Functions to emulate the video hardware of the machine.
  
  ***************************************************************************/
  
  #include "emu.h"
  #include "video/resnet.h"
  #include "includes/naughtyb.h"
  
  
  #if 0
  static const res_net_decode_info naughtyb_decode_info =
  {
  	2,      /*  two proms          */
  	0,      /*  start at 0         */
  	255,    /*  end at 255         */
  	/*  R,   G,   B,   R,   G,   B */
  	{   0,   0,   0, 256, 256, 256},        /*  offsets */
  	{   0,   2,   1,  -1,   1,   0},        /*  shifts */
  	{0x01,0x01,0x01,0x02,0x02,0x02}         /*  masks */
  };
  
  static const res_net_info naughtyb_net_info =
  {
  	RES_NET_VCC_5V | RES_NET_VBIAS_5V | RES_NET_VIN_OPEN_COL,
  	{
  		{ RES_NET_AMP_NONE, 130, 270, 2, { 270, 1 } }, /* no resistor for bit1 */
  		{ RES_NET_AMP_NONE, 130, 270, 2, { 270, 1 } }, /* no resistor for bit1 */
  		{ RES_NET_AMP_NONE, 130, 270, 2, { 270, 1 } }  /* no resistor for bit1 */
  	}
  };
  #endif
  
  /***************************************************************************
  
    Convert the color PROMs into a more useable format.
  
    Naughty Boy has two 256x4 palette PROMs, one containing the high bits and
    the other the low bits (2x2x2 color space).
    The palette PROMs are connected to a 7407 (hex open collector buffer),
    which in turn is connected to the RGB output this way:
  
    bit 3 --
          -- 270 ohm resistor  -- GREEN
          -- 270 ohm resistor  -- BLUE
    bit 0 -- 270 ohm resistor  -- RED
  
    bit 3 --
          -- GREEN
          -- BLUE
    bit 0 -- RED
  
    plus 130 ohm pullup and 270 ohm pulldown resistors on all lines
  
  ***************************************************************************/
  
  void naughtyb_state::naughtyb_palette(palette_device &palette) const
  {
  	const uint8_t *color_prom = memregion("proms")->base();
  	static constexpr int resistances[2] = { 270, 130 };
  
  	// compute the color output resistor weights
  	double weights[2];
  	compute_resistor_weights(0, 255, -1.0,
  			2, resistances, weights, 0, 0,
  			2, resistances, weights, 0, 0, // FIXME: same destination twice?
  			0, nullptr, nullptr, 0, 0);
  
  	for (int i = 0;i < palette.entries(); i++)
  	{
  		int bit0, bit1;
  
  		// red component
  		bit0 = BIT(color_prom[i], 0);
  		bit1 = BIT(color_prom[i+0x100], 0);
  		int const r = combine_weights(weights, bit0, bit1);
  
  		// green component
  		bit0 = BIT(color_prom[i], 2);
  		bit1 = BIT(color_prom[i+0x100], 2);
  		int const g = combine_weights(weights, bit0, bit1);
  
  		// blue component
  		bit0 = BIT(color_prom[i], 1);
  		bit1 = BIT(color_prom[i+0x100], 1);
  		int const b = combine_weights(weights, bit0, bit1);
  
  		palette.set_pen_color(bitswap<8>(i, 5, 7, 6, 2, 1, 0, 4, 3), rgb_t(r, g, b));
  	}
  }
  
  
  /***************************************************************************
  
    Start the video hardware emulation.
  
  ***************************************************************************/
  void naughtyb_state::video_start()
  {
  	m_palreg = m_bankreg = 0;
  
  	/* Naughty Boy has a virtual screen twice as large as the visible screen */
  	m_tmpbitmap.allocate(68*8,28*8,m_screen->format());
  
  	save_item(NAME(m_cocktail));
  	save_item(NAME(m_palreg));
  	save_item(NAME(m_bankreg));
  }
  
  
  
  
  void naughtyb_state::naughtyb_videoreg_w(uint8_t data)
  {
  	// bits 4+5 control the sound circuit
  	m_naughtyb_custom->control_c_w(data);
  
  	m_cocktail =
  		( ( ioport("DSW0")->read() & 0x80 ) &&  // cabinet == cocktail
  			( data & 0x01 ) );              // handling player 2
  	m_palreg  = (data >> 1) & 0x03;         // palette sel is bit 1 & 2
  	m_bankreg = (data >> 2) & 0x01;         // banksel is just bit 2
  }
  
  void naughtyb_state::popflame_videoreg_w(uint8_t data)
  {
  	// bits 4+5 control the sound circuit
  	m_popflame_custom->control_c_w(data);
  
  	m_cocktail =
  		( ( ioport("DSW0")->read() & 0x80 ) &&  // cabinet == cocktail
  			( data & 0x01 ) );              // handling player 2
  	m_palreg  = (data >> 1) & 0x03;         // palette sel is bit 1 & 2
  	m_bankreg = (data >> 3) & 0x01;         // banksel is just bit 3
  }
  
  
  
  /***************************************************************************
  
    The Naughty Boy screen is split into two sections by the hardware
  
    NonScrolled = 28x4 - (rows 0,1,34,35, as shown below)
    this area is split between the top and bottom of the screen,
    and the address mapping is really funky.
  
    Scrolled = 28x64, with a 28x32 viewport, as shown below
    Each column in the virtual screen is 64 (40h) characters high.
    Thus, column 27 is stored in VRAm at address 0-3fh,
    column 26 is stored at 40-7f, and so on.
    This illustration shows the horizontal scroll register set to zero,
    so the topmost 32 rows of the virtual screen are shown.
  
    The following screen-to-memory mapping. This is shown from player's viewpoint,
    which with the CRT rotated 90 degrees CCW. This example shows the horizontal
    scroll register set to zero.
  
  
                            COLUMN
                  0   1   2    -    25  26  27
                -------------------------------
              0| 76E 76A 762   -   70A 706 702 |
               |                               |  Nonscrolled display
              1| 76F 76B 762   -   70B 707 703 |
               |-------------------------------| -----
              2| 6C0 680 640   -    80  40  00 |
               |                               |
          R   3| 6C1 681 641   -    81  41  01 |
          O    |                               |  28 x 32 viewport
          W   ||      |                 |      |  into 28x64 virtual,
               |                               |  scrollable screen
             32| 6DE 69E 65E        9E  5E  1E |
               |                               |
             33| 6DF 69F 65F   -    9F  5F  1F |
               |-------------------------------| -----
             34| 76C 768 764       708 704 700 |
               |                               |  Nonscrolled display
             35| 76D 769 765       709 705 701 |
                -------------------------------
  
  
  ***************************************************************************/
  uint32_t naughtyb_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
  {
  	const rectangle scrollvisiblearea(2*8, 34*8-1, 0*8, 28*8-1);
  	const rectangle leftvisiblearea(0*8, 2*8-1, 0*8, 28*8-1);
  	const rectangle rightvisiblearea(34*8, 36*8-1, 0*8, 28*8-1);
  
  	// for every character in the Video RAM
  
  	for (int offs = 0x800 - 1; offs >= 0; offs--)
  	{
  		int sx,sy;
  
  		if ( m_cocktail )
  		{
  			if (offs < 0x700)
  			{
  				sx = 63 - offs % 64;
  				sy = 27 - offs / 64;
  			}
  			else
  			{
  				sx = 64 + ( 3 - (offs - 0x700) % 4 );
  				sy = 27 - (offs - 0x700) / 4;
  			}
  		}
  		else
  		{
  			if (offs < 0x700)
  			{
  				sx = offs % 64;
  				sy = offs / 64;
  			}
  			else
  			{
  				sx = 64 + (offs - 0x700) % 4;
  				sy = (offs - 0x700) / 4;
  			}
  		}
  
  		m_gfxdecode->gfx(0)->opaque(m_tmpbitmap,m_tmpbitmap.cliprect(),
  				m_videoram2[offs] + 256 * m_bankreg,
  				(m_videoram2[offs] >> 5) + 8 * m_palreg,
  				m_cocktail,m_cocktail,
  				8*sx,8*sy);
  
  		m_gfxdecode->gfx(1)->transpen(m_tmpbitmap,m_tmpbitmap.cliprect(),
  				m_videoram[offs] + 256*m_bankreg,
  				(m_videoram[offs] >> 5) + 8 * m_palreg,
  				m_cocktail,m_cocktail,
  				8*sx,8*sy,0);
  	}
  
  	// copy the temporary bitmap to the screen
  	{
  		int scrollx;
  
  		copybitmap(bitmap,m_tmpbitmap,0,0,-66*8,0,leftvisiblearea);
  		copybitmap(bitmap,m_tmpbitmap,0,0,-30*8,0,rightvisiblearea);
  
  		scrollx = ( m_cocktail ) ? *m_scrollreg - 239 : -*m_scrollreg + 16;
  		copyscrollbitmap(bitmap,m_tmpbitmap,1,&scrollx,0,nullptr,scrollvisiblearea);
  	}
  	return 0;
  }
  