1 // license:BSD-3-Clause
2 // copyright-holders:Mike Balfour
3 /***************************************************************************
4 
5     Atari Subs hardware
6 
7 ***************************************************************************/
8 
9 #include "emu.h"
10 #include "includes/subs.h"
11 #include "sound/discrete.h"
12 
WRITE_LINE_MEMBER(subs_state::invert1_w)13 WRITE_LINE_MEMBER(subs_state::invert1_w)
14 {
15 	if (state)
16 	{
17 		m_palette->set_pen_color(0, rgb_t(0x00, 0x00, 0x00));
18 		m_palette->set_pen_color(1, rgb_t(0xFF, 0xFF, 0xFF));
19 	}
20 	else
21 	{
22 		m_palette->set_pen_color(1, rgb_t(0x00, 0x00, 0x00));
23 		m_palette->set_pen_color(0, rgb_t(0xFF, 0xFF, 0xFF));
24 	}
25 }
26 
WRITE_LINE_MEMBER(subs_state::invert2_w)27 WRITE_LINE_MEMBER(subs_state::invert2_w)
28 {
29 	if (state)
30 	{
31 		m_palette->set_pen_color(2, rgb_t(0x00, 0x00, 0x00));
32 		m_palette->set_pen_color(3, rgb_t(0xFF, 0xFF, 0xFF));
33 	}
34 	else
35 	{
36 		m_palette->set_pen_color(3, rgb_t(0x00, 0x00, 0x00));
37 		m_palette->set_pen_color(2, rgb_t(0xFF, 0xFF, 0xFF));
38 	}
39 }
40 
41 
screen_update_left(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)42 uint32_t subs_state::screen_update_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
43 {
44 	/* for every character in the Video RAM, check if it has been modified */
45 	/* since last time and update it accordingly. */
46 	for (int offs = 0x400 - 1; offs >= 0; offs--)
47 	{
48 		int charcode;
49 		int sx,sy;
50 		int left_enable; //,right_enable;
51 		int left_sonar_window,right_sonar_window;
52 
53 		left_sonar_window = 0;
54 		right_sonar_window = 0;
55 
56 		charcode = m_videoram[offs];
57 
58 		/* Which monitor is this for? */
59 //      right_enable = charcode & 0x40;
60 		left_enable = charcode & 0x80;
61 
62 		sx = 8 * (offs % 32);
63 		sy = 8 * (offs / 32);
64 
65 		/* Special hardware logic for sonar windows */
66 		if ((sy >= (128+64)) && (sx < 32))
67 			left_sonar_window = 1;
68 		else if ((sy >= (128+64)) && (sx >= (128+64+32)))
69 			right_sonar_window = 1;
70 		else
71 			charcode = charcode & 0x3F;
72 
73 		/* draw the left screen */
74 		if ((left_enable || left_sonar_window) && (!right_sonar_window))
75 			m_gfxdecode->gfx(0)->opaque(bitmap,cliprect,
76 					charcode, 1,
77 					0,0,sx,sy);
78 		else
79 			m_gfxdecode->gfx(0)->opaque(bitmap,cliprect,
80 					0, 1,
81 					0,0,sx,sy);
82 	}
83 
84 	/* draw the motion objects */
85 	for (int offs = 0; offs < 4; offs++)
86 	{
87 		int sx,sy;
88 		int charcode;
89 		int prom_set;
90 		int sub_enable;
91 
92 		sx = m_spriteram[0x00 + (offs * 2)] - 16;
93 		sy = m_spriteram[0x08 + (offs * 2)] - 16;
94 		charcode = m_spriteram[0x09 + (offs * 2)];
95 		if (offs < 2)
96 			sub_enable = m_spriteram[0x01 + (offs * 2)] & 0x80;
97 		else
98 			sub_enable = 1;
99 
100 		prom_set = charcode & 0x01;
101 		charcode = (charcode >> 3) & 0x1F;
102 
103 		/* left screen - special check for drawing right screen's sub */
104 		if ((offs!=0) || (sub_enable))
105 			m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
106 					charcode + 32 * prom_set,
107 					0,
108 					0,0,sx,sy,0);
109 	}
110 
111 	/* Update sound */
112 	m_discrete->write(SUBS_LAUNCH_DATA, m_spriteram[5] & 0x0f);   // Launch data
113 	m_discrete->write(SUBS_CRASH_DATA, m_spriteram[5] >> 4);      // Crash/explode data
114 	return 0;
115 }
116 
screen_update_right(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)117 uint32_t subs_state::screen_update_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
118 {
119 	/* for every character in the Video RAM, check if it has been modified */
120 	/* since last time and update it accordingly. */
121 	for (int offs = 0x400 - 1; offs >= 0; offs--)
122 	{
123 		int charcode;
124 		int sx,sy;
125 		int right_enable; //, left_enable;
126 		int left_sonar_window,right_sonar_window;
127 
128 		left_sonar_window = 0;
129 		right_sonar_window = 0;
130 
131 		charcode = m_videoram[offs];
132 
133 		/* Which monitor is this for? */
134 		right_enable = charcode & 0x40;
135 		//left_enable = charcode & 0x80;
136 
137 		sx = 8 * (offs % 32);
138 		sy = 8 * (offs / 32);
139 
140 		/* Special hardware logic for sonar windows */
141 		if ((sy >= (128+64)) && (sx < 32))
142 			left_sonar_window = 1;
143 		else if ((sy >= (128+64)) && (sx >= (128+64+32)))
144 			right_sonar_window = 1;
145 		else
146 			charcode = charcode & 0x3F;
147 
148 		/* draw the right screen */
149 		if ((right_enable || right_sonar_window) && (!left_sonar_window))
150 			m_gfxdecode->gfx(0)->opaque(bitmap,cliprect,
151 					charcode, 0,
152 					0,0,sx,sy);
153 		else
154 			m_gfxdecode->gfx(0)->opaque(bitmap,cliprect,
155 					0, 0,
156 					0,0,sx,sy);
157 	}
158 
159 	/* draw the motion objects */
160 	for (int offs = 0; offs < 4; offs++)
161 	{
162 		int sx,sy;
163 		int charcode;
164 		int prom_set;
165 		int sub_enable;
166 
167 		sx = m_spriteram[0x00 + (offs * 2)] - 16;
168 		sy = m_spriteram[0x08 + (offs * 2)] - 16;
169 		charcode = m_spriteram[0x09 + (offs * 2)];
170 		if (offs < 2)
171 			sub_enable = m_spriteram[0x01 + (offs * 2)] & 0x80;
172 		else
173 			sub_enable = 1;
174 
175 		prom_set = charcode & 0x01;
176 		charcode = (charcode >> 3) & 0x1F;
177 
178 		if ((offs!=1) || (sub_enable))
179 			m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
180 					charcode + 32 * prom_set,
181 					0,
182 					0,0,sx,sy,0);
183 	}
184 
185 	return 0;
186 }
187