1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /*
4 
5 XL 80 cartridge
6 (c) 1984 Data 20 Corporation
7 
8 PCB Layout
9 ----------
10 
11         |==================================|
12         |   LS175    LS20    LS139         |
13         |   LS157                          |
14 |=======|                                  |
15 |=|                          RAM           |
16 |=|    LS157      LS157             LS165  |
17 |=|                                        |
18 |=|                                     CN1|
19 |=|          CRTC            ROM1          |
20 |=|                                        |
21 |=|    ROM0          LS245   LS151         |
22 |=|                             14.31818MHz|
23 |=======|            LS174   LS00          |
24         |                           HCU04  |
25         |    LS74    LS161   LS74          |
26         |==================================|
27 
28 Notes:
29     All IC's shown.
30 
31     CRTC    - Hitachi HD46505SP
32     RAM     - Toshiba TMM2016AP-12 2Kx8 Static RAM
33     ROM0    - GI 9433CS-0090 8Kx8 ROM
34     ROM1    - GI 9316CS-F67 2Kx8 ROM "DTC"
35     CN1     - RCA video output
36 
37 */
38 
39 #include "emu.h"
40 #include "xl80.h"
41 #include "screen.h"
42 
43 
44 
45 //**************************************************************************
46 //  MACROS/CONSTANTS
47 //**************************************************************************
48 
49 #define RAM_SIZE            0x800
50 
51 #define HD46505SP_TAG       "mc6845"
52 #define MC6845_SCREEN_TAG   "screen80"
53 
54 
55 
56 //**************************************************************************
57 //  DEVICE DEFINITIONS
58 //**************************************************************************
59 
60 DEFINE_DEVICE_TYPE(C64_XL80, c64_xl80_device, "c64_xl80", "C64 XL 80 cartridge")
61 
62 
63 //-------------------------------------------------
64 //  ROM( c64_xl80 )
65 //-------------------------------------------------
66 
ROM_START(c64_xl80)67 ROM_START( c64_xl80 )
68 	ROM_REGION( 0x800, HD46505SP_TAG, 0 )
69 	ROM_LOAD( "dtc.u14", 0x000, 0x800, CRC(9edf5e58) SHA1(4b244e6d94a7653a2e52c351589f0b469119fb04) )
70 ROM_END
71 
72 
73 //-------------------------------------------------
74 //  rom_region - device-specific ROM region
75 //-------------------------------------------------
76 
77 const tiny_rom_entry *c64_xl80_device::device_rom_region() const
78 {
79 	return ROM_NAME( c64_xl80 );
80 }
81 
82 //-------------------------------------------------
83 //  mc6845
84 //-------------------------------------------------
85 
MC6845_UPDATE_ROW(c64_xl80_device::crtc_update_row)86 MC6845_UPDATE_ROW( c64_xl80_device::crtc_update_row )
87 {
88 	pen_t const *const pen = m_palette->pens();
89 
90 	for (int column = 0; column < x_count; column++)
91 	{
92 		uint8_t const code = m_ram[((ma + column) & 0x7ff)];
93 		uint16_t const addr = (code << 3) | (ra & 0x07);
94 		uint8_t data = m_char_rom->base()[addr & 0x7ff];
95 
96 		if (column == cursor_x)
97 		{
98 			data = 0xff;
99 		}
100 
101 		for (int bit = 0; bit < 8; bit++)
102 		{
103 			int const x = (column * 8) + bit;
104 			int const color = BIT(data, 7) && de;
105 
106 			bitmap.pix(vbp + y, hbp + x) = pen[color];
107 
108 			data <<= 1;
109 		}
110 	}
111 }
112 
113 //-------------------------------------------------
114 //  GFXDECODE( c64_xl80 )
115 //-------------------------------------------------
116 
117 static GFXDECODE_START( gfx_c64_xl80 )
118 	GFXDECODE_ENTRY(HD46505SP_TAG, 0x0000, gfx_8x8x1, 0, 1)
119 GFXDECODE_END
120 
121 
122 //-------------------------------------------------
123 //  device_add_mconfig - add device configuration
124 //-------------------------------------------------
125 
device_add_mconfig(machine_config & config)126 void c64_xl80_device::device_add_mconfig(machine_config &config)
127 {
128 	screen_device &screen(SCREEN(config, MC6845_SCREEN_TAG, SCREEN_TYPE_RASTER, rgb_t::white()));
129 	screen.set_screen_update(HD46505SP_TAG, FUNC(hd6845s_device::screen_update));
130 	screen.set_size(80*8, 24*8);
131 	screen.set_visarea(0, 80*8-1, 0, 24*8-1);
132 	screen.set_refresh_hz(50);
133 
134 	GFXDECODE(config, "gfxdecode", m_palette, gfx_c64_xl80);
135 	PALETTE(config, m_palette, palette_device::MONOCHROME);
136 
137 	HD6845S(config, m_crtc, XTAL(14'318'181) / 8);
138 	m_crtc->set_screen(MC6845_SCREEN_TAG);
139 	m_crtc->set_show_border_area(true);
140 	m_crtc->set_char_width(8);
141 	m_crtc->set_update_row_callback(FUNC(c64_xl80_device::crtc_update_row));
142 }
143 
144 
145 
146 //**************************************************************************
147 //  LIVE DEVICE
148 //**************************************************************************
149 
150 //-------------------------------------------------
151 //  c64_xl80_device - constructor
152 //-------------------------------------------------
153 
c64_xl80_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)154 c64_xl80_device::c64_xl80_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
155 	device_t(mconfig, C64_XL80, tag, owner, clock),
156 	device_c64_expansion_card_interface(mconfig, *this),
157 	m_crtc(*this, HD46505SP_TAG),
158 	m_palette(*this, "palette"),
159 	m_char_rom(*this, HD46505SP_TAG),
160 	m_ram(*this, "ram")
161 {
162 }
163 
164 
165 //-------------------------------------------------
166 //  device_start - device-specific startup
167 //-------------------------------------------------
168 
device_start()169 void c64_xl80_device::device_start()
170 {
171 	// allocate memory
172 	m_ram.allocate(RAM_SIZE);
173 }
174 
175 
176 //-------------------------------------------------
177 //  device_reset - device-specific reset
178 //-------------------------------------------------
179 
device_reset()180 void c64_xl80_device::device_reset()
181 {
182 }
183 
184 
185 //-------------------------------------------------
186 //  c64_cd_r - cartridge data read
187 //-------------------------------------------------
188 
c64_cd_r(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)189 uint8_t c64_xl80_device::c64_cd_r(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
190 {
191 	if (!io2 && BIT(offset, 2))
192 	{
193 		if (offset & 0x01)
194 		{
195 			data = m_crtc->register_r();
196 		}
197 	}
198 	else if (offset >= 0x8000 && offset < 0x9000)
199 	{
200 		data = m_roml[offset & 0xfff];
201 	}
202 	else if (offset >= 0x9800 && offset < 0xa000)
203 	{
204 		data = m_ram[offset & 0x7ff];
205 	}
206 
207 	return data;
208 }
209 
210 
211 //-------------------------------------------------
212 //  c64_cd_w - cartridge data write
213 //-------------------------------------------------
214 
c64_cd_w(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)215 void c64_xl80_device::c64_cd_w(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
216 {
217 	if (offset >= 0x9800 && offset < 0xa000)
218 	{
219 		m_ram[offset & 0x7ff] = data;
220 	}
221 	else if (!io2 && BIT(offset, 2))
222 	{
223 		if (offset & 0x01)
224 		{
225 			m_crtc->register_w(data);
226 		}
227 		else
228 		{
229 			m_crtc->address_w(data);
230 		}
231 	}
232 }
233