summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/video/newbrain.c
blob: 221ea918c274a5d58f9d1c5c9fd833ac200a5cf4 (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
#include "includes/newbrain.h"
#include "newbrain.lh"

void newbrain_state::video_start()
{
	/* find memory regions */
	m_char_rom = memregion("chargen")->base();

	/* register for state saving */
	save_item(NAME(m_tvcnsl));
	save_item(NAME(m_tvctl));
	save_item(NAME(m_tvram));
	save_item(NAME(m_segment_data));
}

void newbrain_state::screen_update(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	address_space *program = m_maincpu->space(AS_PROGRAM);

	int y, sx;
	int columns = (m_tvctl & NEWBRAIN_VIDEO_80L) ? 80 : 40;
	int excess = (m_tvctl & NEWBRAIN_VIDEO_32_40) ? 24 : 4;
	int ucr = (m_tvctl & NEWBRAIN_VIDEO_UCR) ? 1 : 0;
	int fs = (m_tvctl & NEWBRAIN_VIDEO_FS) ? 1 : 0;
	int rv = (m_tvctl & NEWBRAIN_VIDEO_RV) ? 1 : 0;
	int gr = 0;

	UINT16 videoram_addr = m_tvram;
	UINT8 rc = 0;

	for (y = 0; y < 250; y++)
	{
		int x = 0;

		for (sx = 0; sx < columns; sx++)
		{
			int bit;

			UINT8 videoram_data = program->read_byte(videoram_addr + sx);
			UINT8 charrom_data;

			if (gr)
			{
				/* render video ram data */
				charrom_data = videoram_data;
			}
			else
			{
				/* render character rom data */
				UINT16 charrom_addr = (rc << 8) | ((BIT(videoram_data, 7) & fs) << 7) | (videoram_data & 0x7f);
				charrom_data = m_char_rom[charrom_addr & 0xfff];

				if ((videoram_data & 0x80) && !fs)
				{
					/* invert character */
					charrom_data ^= 0xff;
				}

				if ((videoram_data & 0x60) && !ucr)
				{
					/* strip bit D0 */
					charrom_data &= 0xfe;
				}
			}

			for (bit = 0; bit < 8; bit++)
			{
				int color = BIT(charrom_data, 7) ^ rv;

				bitmap.pix16(y, x++) = color;

				if (columns == 40)
				{
					bitmap.pix16(y, x++) = color;
				}

				charrom_data <<= 1;
			}
		}

		if (gr)
		{
			/* get new data for each line */
			videoram_addr += columns;
			videoram_addr += excess;
		}
		else
		{
			/* increase row counter */
			rc++;

			if (rc == (ucr ? 8 : 10))
			{
				/* reset row counter */
				rc = 0;

				videoram_addr += columns;
				videoram_addr += excess;
			}
		}
	}
}

UINT32 newbrain_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	if (m_enrg1 & NEWBRAIN_ENRG1_TVP)
	{
		screen_update(bitmap, cliprect);
	}
	else
	{
		bitmap.fill(get_black_pen(machine()), cliprect);
	}

	return 0;
}

/* Machine Drivers */

MACHINE_CONFIG_FRAGMENT( newbrain_video )
	MCFG_DEFAULT_LAYOUT(layout_newbrain)

	MCFG_SCREEN_ADD(SCREEN_TAG, RASTER)
	MCFG_SCREEN_UPDATE_DRIVER(newbrain_state, screen_update)
	MCFG_SCREEN_REFRESH_RATE(50)
	MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
	MCFG_SCREEN_SIZE(640, 250)
	MCFG_SCREEN_VISIBLE_AREA(0, 639, 0, 249)

	MCFG_PALETTE_LENGTH(2)
	MCFG_PALETTE_INIT(black_and_white)
MACHINE_CONFIG_END