1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 #include "emu.h"
4 #include "includes/v1050.h"
5 
6 #include "screen.h"
7 
8 /*
9 
10     TODO:
11 
12     - bright in reverse video
13 
14 */
15 
16 #define V1050_ATTR_BRIGHT   0x01
17 #define V1050_ATTR_BLINKING 0x02
18 #define V1050_ATTR_ATTEN    0x04
19 #define V1050_ATTR_REVERSE  0x10
20 #define V1050_ATTR_BLANK    0x20
21 #define V1050_ATTR_BOLD     0x40
22 #define V1050_ATTR_BLINK    0x80
23 
24 /* Video RAM Access */
25 
attr_r()26 uint8_t v1050_state::attr_r()
27 {
28 	return m_attr;
29 }
30 
attr_w(uint8_t data)31 void v1050_state::attr_w(uint8_t data)
32 {
33 	m_attr = data;
34 }
35 
videoram_r(offs_t offset)36 uint8_t v1050_state::videoram_r(offs_t offset)
37 {
38 	if (offset >= 0x2000)
39 	{
40 		m_attr = (m_attr & 0xfc) | (m_attr_ram[offset] & 0x03);
41 	}
42 
43 	return m_video_ram[offset];
44 }
45 
videoram_w(offs_t offset,uint8_t data)46 void v1050_state::videoram_w(offs_t offset, uint8_t data)
47 {
48 	m_video_ram[offset] = data;
49 
50 	if (offset >= 0x2000 && BIT(m_attr, 2))
51 	{
52 		m_attr_ram[offset] = m_attr & 0x03;
53 	}
54 }
55 
56 /* MC6845 Interface */
57 
MC6845_UPDATE_ROW(v1050_state::crtc_update_row)58 MC6845_UPDATE_ROW( v1050_state::crtc_update_row )
59 {
60 	for (int column = 0; column < x_count; column++)
61 	{
62 		uint16_t address = (((ra & 0x03) + 1) << 13) | ((ma & 0x1fff) + column);
63 		uint8_t data = m_video_ram[address & V1050_VIDEORAM_MASK];
64 		uint8_t attr = (m_attr & 0xfc) | (m_attr_ram[address] & 0x03);
65 
66 		for (int bit = 0; bit < 8; bit++)
67 		{
68 			int x = (column * 8) + bit;
69 			int color = BIT(data, 7);
70 
71 			/* blinking */
72 			if ((attr & V1050_ATTR_BLINKING) && !(attr & V1050_ATTR_BLINK)) color = 0;
73 
74 			/* reverse video */
75 			color ^= BIT(attr, 4);
76 
77 			/* bright */
78 			if (color && (!(attr & V1050_ATTR_BOLD) ^ (attr & V1050_ATTR_BRIGHT))) color = 2;
79 
80 			/* display blank */
81 			if (attr & V1050_ATTR_BLANK) color = 0;
82 
83 			bitmap.pix(vbp + y, hbp + x) = m_palette->pen(de ? color : 0);
84 
85 			data <<= 1;
86 		}
87 	}
88 }
89 
WRITE_LINE_MEMBER(v1050_state::crtc_vs_w)90 WRITE_LINE_MEMBER( v1050_state::crtc_vs_w )
91 {
92 	m_subcpu->set_input_line(INPUT_LINE_IRQ0, state ? ASSERT_LINE : CLEAR_LINE);
93 
94 	set_interrupt(INT_VSYNC, state);
95 }
96 
97 /* Video Start */
98 
video_start()99 void v1050_state::video_start()
100 {
101 	/* allocate memory */
102 	m_attr_ram.allocate(V1050_VIDEORAM_SIZE);
103 
104 	/* register for state saving */
105 	save_item(NAME(m_attr));
106 }
107 
108 /* Machine Drivers */
109 
v1050_video(machine_config & config)110 void v1050_state::v1050_video(machine_config &config)
111 {
112 	HD6845S(config, m_crtc, 15.36_MHz_XTAL/8); // HD6845SP according to Programmer's Technical Document
113 	m_crtc->set_screen(SCREEN_TAG);
114 	m_crtc->set_show_border_area(true);
115 	m_crtc->set_char_width(8);
116 	m_crtc->set_update_row_callback(FUNC(v1050_state::crtc_update_row));
117 	m_crtc->out_vsync_callback().set(FUNC(v1050_state::crtc_vs_w));
118 
119 	screen_device &screen(SCREEN(config, SCREEN_TAG, SCREEN_TYPE_RASTER, rgb_t::green()));
120 	screen.set_screen_update(H46505_TAG, FUNC(hd6845s_device::screen_update));
121 	screen.set_refresh_hz(60);
122 	screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500));
123 	screen.set_size(640, 400);
124 	screen.set_visarea(0,640-1, 0, 400-1);
125 
126 	PALETTE(config, m_palette, palette_device::MONOCHROME_HIGHLIGHT);
127 }
128