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