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