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