1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /**********************************************************************
4
5 Multiscreen cartridge emulation
6
7 **********************************************************************/
8
9 /*
10
11 PCB Layout
12 ----------
13
14 |===================|
15 | ROM6 |
16 | MC14066 |
17 | |
18 |===============| ROM5 |
19 |=| |
20 |=| |
21 |=| RAM BAT ROM4 |
22 |=| |
23 |=| |
24 |=| ROM0 ROM3 |
25 |=| |
26 |=| |
27 |===============| LS138 ROM2 |
28 | LS138 |
29 | LS174 |
30 | LS133 ROM1 |
31 |===================|
32
33 BAT - BR2325 lithium battery
34 RAM - ? 8Kx8 RAM
35 ROM0 - ? 16Kx8 EPROM
36 ROM1 - ? 32Kx8 EPROM
37 ROM2 - ? 32Kx8 EPROM
38 ROM3 - ? 32Kx8 EPROM
39 ROM4 - not populated
40 ROM5 - not populated
41 ROM6 - not populated
42
43 */
44
45 /*
46
47 TODO:
48
49 - M6802 board
50 - crashes on boot
51
52 805A: lda $01
53 805C: and #$FE
54 805E: sta $01
55 8060: m6502_brk#$00 <-- BOOM!
56
57 */
58
59 #include "emu.h"
60 #include "multiscreen.h"
61
62
63
64 //**************************************************************************
65 // MACROS/CONSTANTS
66 //**************************************************************************
67
68 #define MC6802P_TAG "m6802"
69 #define MC6821P_0_TAG "m6821_0"
70 #define MC6821P_1_TAG "m6821_1"
71
72
73 #define BANK_RAM 0x0d
74
75
76
77 //**************************************************************************
78 // DEVICE DEFINITIONS
79 //**************************************************************************
80
81 DEFINE_DEVICE_TYPE(C64_MULTISCREEN, c64_multiscreen_cartridge_device, "c64_mscr", "C64 Multiscreen cartridge")
82
83
84 //-------------------------------------------------
85 // ROM( c64_multiscreen )
86 //-------------------------------------------------
87
ROM_START(c64_multiscreen)88 ROM_START( c64_multiscreen )
89 ROM_REGION( 0x2000, MC6802P_TAG, 0 )
90 ROM_LOAD( "1", 0x0000, 0x1000, CRC(35be02a8) SHA1(5912bc3d8e0c0949c1e66c19116d6b71c7574e46) )
91 ROM_LOAD( "2 cr", 0x1000, 0x1000, CRC(76a9ac6d) SHA1(87e7335e626bdb73498b46c28c7baab72df38d1f) )
92 ROM_END
93
94
95 //-------------------------------------------------
96 // rom_region - device-specific ROM region
97 //-------------------------------------------------
98
99 const tiny_rom_entry *c64_multiscreen_cartridge_device::device_rom_region() const
100 {
101 return ROM_NAME( c64_multiscreen );
102 }
103
104
multiscreen_mem(address_map & map)105 void c64_multiscreen_cartridge_device::multiscreen_mem(address_map &map)
106 {
107 map(0x0000, 0x1fff).rom().region(MC6802P_TAG, 0);
108 }
109
110
111 //-------------------------------------------------
112 // device_add_mconfig - add device configuration
113 //-------------------------------------------------
114
device_add_mconfig(machine_config & config)115 void c64_multiscreen_cartridge_device::device_add_mconfig(machine_config &config)
116 {
117 m6802_cpu_device &cpu(M6802(config, MC6802P_TAG, XTAL(4'000'000)));
118 cpu.set_addrmap(AS_PROGRAM, &c64_multiscreen_cartridge_device::multiscreen_mem);
119
120 PIA6821(config, MC6821P_0_TAG, 0);
121 PIA6821(config, MC6821P_1_TAG, 0);
122 }
123
124
125 //**************************************************************************
126 // LIVE DEVICE
127 //**************************************************************************
128
129 //-------------------------------------------------
130 // c64_multiscreen_cartridge_device - constructor
131 //-------------------------------------------------
132
c64_multiscreen_cartridge_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)133 c64_multiscreen_cartridge_device::c64_multiscreen_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
134 device_t(mconfig, C64_MULTISCREEN, tag, owner, clock),
135 device_c64_expansion_card_interface(mconfig, *this), m_bank(0)
136 {
137 }
138
139
140 //-------------------------------------------------
141 // device_start - device-specific startup
142 //-------------------------------------------------
143
device_start()144 void c64_multiscreen_cartridge_device::device_start()
145 {
146 // state saving
147 save_item(NAME(m_bank));
148 }
149
150
151 //-------------------------------------------------
152 // device_reset - device-specific reset
153 //-------------------------------------------------
154
device_reset()155 void c64_multiscreen_cartridge_device::device_reset()
156 {
157 m_bank = 0;
158 }
159
160
161 //-------------------------------------------------
162 // c64_cd_r - cartridge data read
163 //-------------------------------------------------
164
c64_cd_r(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)165 uint8_t c64_multiscreen_cartridge_device::c64_cd_r(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
166 {
167 if (!roml)
168 {
169 int bank = m_bank & 0x0f;
170
171 if (bank == BANK_RAM)
172 {
173 data = m_nvram[offset & 0x1fff];
174 }
175 else
176 {
177 data = m_roml[(bank << 14) | (offset & 0x3fff)];
178 }
179 }
180 else if (!romh)
181 {
182 int bank = m_bank & 0x0f;
183
184 if (bank == BANK_RAM)
185 {
186 data = m_roml[offset & 0x3fff];
187 }
188 else
189 {
190 data = m_roml[(bank << 14) | (offset & 0x3fff)];
191 }
192 }
193
194 return data;
195 }
196
197
198 //-------------------------------------------------
199 // c64_cd_w - cartridge data write
200 //-------------------------------------------------
201
c64_cd_w(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)202 void c64_multiscreen_cartridge_device::c64_cd_w(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
203 {
204 if (offset >= 0x8000 && offset < 0xa000)
205 {
206 int bank = m_bank & 0x0f;
207
208 if (bank == BANK_RAM)
209 {
210 m_nvram[offset & 0x1fff] = data;
211 }
212 }
213 else if (!io2)
214 {
215 m_bank = data;
216 }
217 }
218