1 #include "driver.h"
2 #include "vidhrdw/generic.h"
3 
4 
5 
6 #define VIDEORAM_SIZE 0x1c00
7 #define SPRITERAM_START 0x1800
8 #define SPRITERAM_SIZE (VIDEORAM_SIZE-SPRITERAM_START)
9 
10 static data16_t *vram,*buf_spriteram,*buf_spriteram2;
11 
12 #define VREG_SIZE 18
13 static data16_t vreg[VREG_SIZE];
14 
15 static struct tilemap *tilemap[3];
16 
17 
18 /***************************************************************************
19 
20   Callbacks for the TileMap code
21 
22 ***************************************************************************/
23 
get_tile_info(int tile_index,int plane)24 static INLINE void get_tile_info(int tile_index,int plane)
25 {
26 	data16_t attr;
27 
28 	tile_index = 2*tile_index + 0x800*plane;
29 	attr = vram[tile_index];
30 	SET_TILE_INFO(
31 			1,
32 			vram[tile_index+1],
33 			attr & 0x7f,
34 			0)
35 	tile_info.priority = (attr & 0x0600) >> 9;
36 }
37 
get_tile_info0(int tile_index)38 static void get_tile_info0(int tile_index)
39 {
40 	get_tile_info(tile_index,0);
41 }
42 
get_tile_info1(int tile_index)43 static void get_tile_info1(int tile_index)
44 {
45 	get_tile_info(tile_index,1);
46 }
47 
get_tile_info2(int tile_index)48 static void get_tile_info2(int tile_index)
49 {
50 	get_tile_info(tile_index,2);
51 }
52 
53 
54 
55 /***************************************************************************
56 
57   Start the video hardware emulation.
58 
59 ***************************************************************************/
60 
VIDEO_START(othldrby)61 VIDEO_START( othldrby )
62 {
63 	tilemap[0] = tilemap_create(get_tile_info0,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,32,32);
64 	tilemap[1] = tilemap_create(get_tile_info1,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,32,32);
65 	tilemap[2] = tilemap_create(get_tile_info2,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,32,32);
66 
67 	vram = auto_malloc(VIDEORAM_SIZE * sizeof(vram[0]));
68 	buf_spriteram = auto_malloc(2*SPRITERAM_SIZE * sizeof(buf_spriteram[0]));
69 
70 	if (!tilemap[0] || !tilemap[1] || !tilemap[2] || !vram || !buf_spriteram)
71 		return 1;
72 
73 	buf_spriteram2 = buf_spriteram + SPRITERAM_SIZE;
74 
75 	tilemap_set_transparent_pen(tilemap[0],0);
76 	tilemap_set_transparent_pen(tilemap[1],0);
77 	tilemap_set_transparent_pen(tilemap[2],0);
78 
79 	return 0;
80 }
81 
82 
83 
84 /***************************************************************************
85 
86   Memory handlers
87 
88 ***************************************************************************/
89 
90 static unsigned int vram_addr,vreg_addr;
91 
WRITE16_HANDLER(othldrby_videoram_addr_w)92 WRITE16_HANDLER( othldrby_videoram_addr_w )
93 {
94 	vram_addr = data;
95 }
96 
READ16_HANDLER(othldrby_videoram_r)97 READ16_HANDLER( othldrby_videoram_r )
98 {
99 	if (vram_addr < VIDEORAM_SIZE)
100 		return vram[vram_addr++];
101 	else
102 	{
103 		usrintf_showmessage("GFXRAM OUT OF BOUNDS %04x",vram_addr);
104 		return 0;
105 	}
106 }
107 
WRITE16_HANDLER(othldrby_videoram_w)108 WRITE16_HANDLER( othldrby_videoram_w )
109 {
110 	if (vram_addr < VIDEORAM_SIZE)
111 	{
112 		if (vram_addr < SPRITERAM_START)
113 			tilemap_mark_tile_dirty(tilemap[vram_addr/0x800],(vram_addr&0x7ff)/2);
114 		vram[vram_addr++] = data;
115 	}
116 	else
117 		usrintf_showmessage("GFXRAM OUT OF BOUNDS %04x",vram_addr);
118 }
119 
WRITE16_HANDLER(othldrby_vreg_addr_w)120 WRITE16_HANDLER( othldrby_vreg_addr_w )
121 {
122 	vreg_addr = data & 0x7f;	/* bit 7 is set when screen is flipped */
123 }
124 
WRITE16_HANDLER(othldrby_vreg_w)125 WRITE16_HANDLER( othldrby_vreg_w )
126 {
127 	if (vreg_addr < VREG_SIZE)
128 		vreg[vreg_addr++] = data;
129 	else
130 		usrintf_showmessage("%06x: VREG OUT OF BOUNDS %04x",activecpu_get_pc(),vreg_addr);
131 }
132 
133 
134 
135 /***************************************************************************
136 
137   Display refresh
138 
139 ***************************************************************************/
140 
draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int priority)141 static void draw_sprites(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int priority)
142 {
143 	int offs;
144 
145 	for (offs = 0;offs < SPRITERAM_SIZE;offs += 4)
146 	{
147 		int x,y,color,code,sx,sy,flipx,flipy,sizex,sizey,pri;
148 
149 
150 		pri = (buf_spriteram[offs] & 0x0600) >> 9;
151 		if (pri != priority) continue;
152 
153 		flipx = buf_spriteram[offs] & 0x1000;
154 		flipy = 0;
155 		color = (buf_spriteram[offs] & 0x01fc) >> 2;
156 		code = buf_spriteram[offs+1] | ((buf_spriteram[offs] & 0x0003) << 16);
157 		sx = (buf_spriteram[offs+2] >> 7);
158 		sy = (buf_spriteram[offs+3] >> 7);
159 		sizex = (buf_spriteram[offs+2] & 0x000f) + 1;
160 		sizey = (buf_spriteram[offs+3] & 0x000f) + 1;
161 
162 		if (flip_screen)
163 		{
164 			flipx = !flipx;
165 			flipy = !flipy;
166 			sx = 246 - sx;
167 			sy = 16 - sy;
168 		}
169 
170 		for (y = 0;y < sizey;y++)
171 		{
172 			for (x = 0;x < sizex;x++)
173 			{
174 				drawgfx(bitmap,Machine->gfx[0],
175 						code + x + sizex * y,
176 						color,
177 						flipx,flipy,
178 						(sx + (flipx ? (-8*(x+1)+1) : 8*x) - vreg[6]+44) & 0x1ff,(sy + (flipy ? (-8*(y+1)+1) : 8*y) - vreg[7]-9) & 0x1ff,
179 						cliprect,TRANSPARENCY_PEN,0);
180 			}
181 		}
182 	}
183 }
184 
VIDEO_UPDATE(othldrby)185 VIDEO_UPDATE( othldrby )
186 {
187 	int layer;
188 
189 
190 	flip_screen_set(vreg[0x0f] & 0x80);
191 
192 	for (layer = 0;layer < 3;layer++)
193 	{
194 		if (flip_screen)
195 		{
196 			tilemap_set_scrollx(tilemap[layer],0,vreg[2*layer]+59);
197 			tilemap_set_scrolly(tilemap[layer],0,vreg[2*layer+1]+248);
198 		}
199 		else
200 		{
201 			tilemap_set_scrollx(tilemap[layer],0,vreg[2*layer]-58);
202 			tilemap_set_scrolly(tilemap[layer],0,vreg[2*layer+1]+9);
203 		}
204 	}
205 
206 	fillbitmap(priority_bitmap,0,cliprect);
207 
208 	fillbitmap(bitmap,Machine->pens[0],cliprect);
209 
210 	for (layer = 0;layer < 3;layer++)
211 		tilemap_draw(bitmap,cliprect,tilemap[layer],0,0);
212 	draw_sprites(bitmap,cliprect,0);
213 	for (layer = 0;layer < 3;layer++)
214 		tilemap_draw(bitmap,cliprect,tilemap[layer],1,0);
215 	draw_sprites(bitmap,cliprect,1);
216 	for (layer = 0;layer < 3;layer++)
217 		tilemap_draw(bitmap,cliprect,tilemap[layer],2,0);
218 	draw_sprites(bitmap,cliprect,2);
219 	for (layer = 0;layer < 3;layer++)
220 		tilemap_draw(bitmap,cliprect,tilemap[layer],3,0);
221 	draw_sprites(bitmap,cliprect,3);
222 }
223 
VIDEO_EOF(othldrby)224 VIDEO_EOF( othldrby )
225 {
226 	/* sprites need to be delayed two frames */
227     memcpy(buf_spriteram,buf_spriteram2,SPRITERAM_SIZE*sizeof(buf_spriteram[0]));
228     memcpy(buf_spriteram2,&vram[SPRITERAM_START],SPRITERAM_SIZE*sizeof(buf_spriteram[0]));
229 }
230