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
|
// license:BSD-3-Clause
// copyright-holders:Nigel Barnes
/**********************************************************************
Acorn 40 Column VDU Interface
Part No. 200,002
http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Acorn_VDU.html
**********************************************************************/
#include "emu.h"
#include "vdu40.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(ACORN_VDU40, acorn_vdu40_device, "acorn_vdu40", "Acorn 40 Column VDU Interface")
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
void acorn_vdu40_device::device_add_mconfig(machine_config &config)
{
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(12_MHz_XTAL, 768, 132, 612, 311, 20, 270);
m_screen->set_screen_update("mc6845", FUNC(mc6845_device::screen_update));
PALETTE(config, "palette").set_entries(8);
HD6845S(config, m_crtc, 12_MHz_XTAL / 6); // "MC6845S" on schematics
m_crtc->set_screen("screen");
m_crtc->set_show_border_area(false);
m_crtc->set_char_width(12);
m_crtc->out_vsync_callback().set(FUNC(acorn_vdu40_device::vsync_changed));
m_crtc->set_update_row_callback(FUNC(acorn_vdu40_device::crtc_update_row));
SAA5050(config, m_trom, 12_MHz_XTAL / 2);
m_trom->set_screen_size(40, 25, 40);
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// acorn_vdu40_device - constructor
//-------------------------------------------------
acorn_vdu40_device::acorn_vdu40_device(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock)
: device_t(mconfig, ACORN_VDU40, tag, owner, clock)
, device_acorn_bus_interface(mconfig, *this)
, m_screen(*this, "screen")
, m_crtc(*this, "mc6845")
, m_trom(*this, "saa5050")
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void acorn_vdu40_device::device_start()
{
/* allocate m_videoram */
m_videoram = std::make_unique<uint8_t[]>(0x0400);
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void acorn_vdu40_device::device_reset()
{
address_space &space = m_bus->memspace();
space.install_ram(0x0400, 0x07ff, m_videoram.get());
space.install_readwrite_handler(0x0800, 0x0800, read8smo_delegate(*m_crtc, FUNC(mc6845_device::status_r)), write8smo_delegate(*m_crtc, FUNC(mc6845_device::address_w)));
space.install_readwrite_handler(0x0801, 0x0801, read8smo_delegate(*m_crtc, FUNC(mc6845_device::register_r)), write8smo_delegate(*m_crtc, FUNC(mc6845_device::register_w)));
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
MC6845_UPDATE_ROW(acorn_vdu40_device::crtc_update_row)
{
uint32_t *p = &bitmap.pix(y);
m_trom->lose_w(1);
m_trom->lose_w(0);
for (int column = 0; column < x_count; column++)
{
m_trom->write(m_videoram[(ma + column) & 0x3ff]);
m_trom->f1_w(1);
m_trom->f1_w(0);
for (int bit = 0; bit < 12; bit++)
{
m_trom->tr6_w(1);
m_trom->tr6_w(0);
int col = m_trom->get_rgb() ^ ((column == cursor_x) ? 7 : 0);
int r = BIT(col, 0) * 0xff;
int g = BIT(col, 1) * 0xff;
int b = BIT(col, 2) * 0xff;
*p++ = rgb_t(r, g, b);
}
}
}
WRITE_LINE_MEMBER(acorn_vdu40_device::vsync_changed)
{
m_trom->dew_w(state);
}
|