summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/tutankhm.c
blob: 9bfef47d51d5be13382ac8eeffcffbeac7a66d26 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/***************************************************************************

  video.c

  Functions to emulate the video hardware of the machine.

***************************************************************************/


#include "driver.h"
#include "tutankhm.h"


#define NUM_PENS	(0x10)


UINT8 *tutankhm_scroll;

static UINT8 junofrst_blitterdata[4];
static UINT8 tutankhm_flip_screen_x;
static UINT8 tutankhm_flip_screen_y;



/*************************************
 *
 *  Write handlers
 *
 *************************************/

WRITE8_HANDLER( tutankhm_flip_screen_x_w )
{
	tutankhm_flip_screen_x = data & 0x01;
}


WRITE8_HANDLER( tutankhm_flip_screen_y_w )
{
	tutankhm_flip_screen_y = data & 0x01;
}



/*************************************
 *
 *  Palette management
 *
 *************************************/

static void get_pens(pen_t *pens)
{
	offs_t i;

	for (i = 0; i < NUM_PENS; i++)
	{
		UINT8 data = paletteram[i];

		pens[i] = MAKE_RGB(pal3bit(data >> 0), pal3bit(data >> 3), pal2bit(data >> 6));
	}
}



/*************************************
 *
 *  Video startup
 *
 *************************************/

VIDEO_START( tutankhm )
{
	state_save_register_global_array(junofrst_blitterdata);
	state_save_register_global(tutankhm_flip_screen_x);
	state_save_register_global(tutankhm_flip_screen_y);
}



/*************************************
 *
 *  Video update
 *
 *************************************/

VIDEO_UPDATE( tutankhm )
{
	int xorx = tutankhm_flip_screen_x ? 255 : 0;
	int xory = tutankhm_flip_screen_y ? 255 : 0;
	pen_t pens[NUM_PENS];
	int x, y;

	get_pens(pens);

	for (y = cliprect->min_y; y <= cliprect->max_y; y++)
	{
		UINT32 *dst = BITMAP_ADDR32(bitmap, y, 0);

		for (x = cliprect->min_x; x <= cliprect->max_x; x++)
		{
			UINT8 effx = x ^ xorx;
			UINT8 yscroll = (effx < 192) ? *tutankhm_scroll : 0;
			UINT8 effy = (y ^ xory) + yscroll;
			UINT8 vrambyte = videoram[effy * 128 + effx / 2];
			UINT8 shifted = vrambyte >> (4 * (effx % 2));
			dst[x] = pens[shifted & 0x0f];
		}
	}

	return 0;
}



/* Juno First Blitter Hardware emulation

    Juno First can blit a 16x16 graphics which comes from un-memory mapped graphics roms

    $8070->$8071 specifies the destination NIBBLE address
    $8072->$8073 specifies the source NIBBLE address

    Depending on bit 0 of the source address either the source pixels will be copied to
    the destination address, or a zero will be written.

    Only source pixels which aren't 0 are copied or cleared.

    This allows the game to quickly clear the sprites from the screen

    TODO: Does bit 1 of the source address mean something?
          We have to mask it off otherwise the "Juno First" logo on the title screen is wrong.
*/

WRITE8_HANDLER( junofrst_blitter_w )
{
	junofrst_blitterdata[offset] = data;

	/* blitter is triggered by $8073 */
	if (offset == 3)
	{
		int i;
		UINT8 *gfx_rom = memory_region(REGION_GFX1);

		offs_t src = ((junofrst_blitterdata[2] << 8) | junofrst_blitterdata[3]) & 0xfffc;
		offs_t dest = (junofrst_blitterdata[0] << 8) | junofrst_blitterdata[1];

		int copy = junofrst_blitterdata[3] & 0x01;

		/* 16x16 graphics */
		for (i = 0; i < 16; i++)
		{
			int j;

			for (j = 0; j < 16; j++)
			{
				UINT8 data;

				if (src & 1)
					data = gfx_rom[src >> 1] & 0x0f;
				else
					data = gfx_rom[src >> 1] >> 4;

				src = src + 1;

				/* if there is a source pixel either copy the pixel or clear the pixel depending on the copy flag */

				if (data)
				{
					if (copy==0)
						data = 0;

					if (dest & 1)
						videoram[dest >> 1] = (videoram[dest >> 1] & 0x0f) | (data << 4);
					else
						videoram[dest >> 1] = (videoram[dest >> 1] & 0xf0) | data;
				}

				dest = dest + 1;
			}

			dest = dest + 240;
		}
	}
}