1 // license:BSD-3-Clause
2 // copyright-holders:Angelo Salese
3 /************************************************************************************************
4
5 PC-6001 series (c) 1981 NEC
6
7 driver by Angelo Salese
8
9 TODO:
10 - Hook up tape loading, images that are floating around the net are already
11 ADC'ed, so they should be easy to implement (but not exactly faithful)
12 - cassette handling requires a decap of the MCU. It could be possible to
13 do some tight synch between the master CPU and a code simulation, but maybe
14 it's not worth the effort...
15 - Identify and hook-up the FDC device, apparently PC-6001 and PC-6601 doesn't
16 even use the same thing;
17 - PC-6601: mon r-0 type games doesn't seem to work at all on this system?
18 - PC-6001SR: get it to boot, also implement MK-2 compatibility mode (it changes
19 the memory map to behave like the older versions)
20 - Hookup MC6847 for vanilla PC-6001 and fix video bugs for that device;
21 - upd7752 voice speech device needs to be properly emulated (device is currently a skeleton),
22 Chrith game is a good test case, it's supposed to talk before title screen;
23
24 TODO (game specific):
25 - (several AX* games, namely Galaxy Mission Part 1/2 and others): inputs doesn't work;
26 - AX6 - Demo: When AY-based speech talks, other emus emulates the screen drawing to be
27 a solid green (plain PC-6001) or solid white (Mk2 version), but according to an
28 original video reference, that screen should actually some kind of weird garbage on it;
29 - AX6 - Powered Knight: doesn't work too well, according to the asm code it asks the
30 player to press either 'B' or 'C' then a number but nothing is shown on screen,
31 other emus behaves the same, bad dump?
32 - Dawn Patrol (cart): presumably too slow;
33 (Mk2 mode 5 games)
34 - 3D Golf Simulation Super Version: gameplay / inputs seems broken
35 - American Truck: Screen is offset at the loading screen, loading bug?
36 - Castle Excellent: copyright text drawing is quite bogus, scans text in vertical
37 instead of horizontal?
38 - Dezeni Land (ALL versions) / Hurry Fox 1/2: asks you to "load something", can't do it
39 with current cassette kludge, also, for Dezeni Land(s) keyboard irqs doesn't seem to
40 work too well with halt opcode execution?
41 - Dezeni Land 1/4: dies after loading of main program;
42 - Dezeni Land 2: dies at the "load something" screen with presumably wrong stack opcodes
43 - (MyCom BASIC games with multiple files): most of them refuses to run ... how to load them?
44 - Grobda: when "get ready" speech plays, screen should be full white but instead it's all
45 black, same issue as AX-6 Demo?
46 - Pac-Man / Tiny Xevious 2: gameplay is too fast
47 - Salad no Kunino Tomato-Hime: can't start a play
48 - Space Harrier: inputs doesn't work properly
49 - The Black Onyx: dies when it attempts to save the character, that obviously means saving
50 on the tape;
51 - Yakyukyo / Punchball Mario: waits for an irq, check which one;
52
53 =================================================================================================
54
55 PC-6001 (1981-09):
56
57 * CPU: Z80A @ 4 MHz
58 * ROM: 16KB + 4KB (chargen) - no kanji
59 * RAM: 16KB, it can be expanded to 32KB
60 * Text Mode: 32x16 and 2 colors
61 * Graphic Modes: 64x48 (9 colors), 128x192 (4 colors), 256x192 (2 colors)
62 * Sound: BEEP + PSG - Optional Voice Synth Cart
63 * Keyboard: JIS Keyboard with 5 function keys, control key, TAB key,
64 HOME/CLR key, INS key, DEL key, GRAPH key, Japanese syllabary
65 key, page key, STOP key, and cursor key (4 directions)
66 * 1 cartslot, optional floppy drive, optional serial 232 port, 2
67 joystick ports
68
69
70 PC-6001 mkII (1983-07):
71
72 * CPU: Z80A @ 4 MHz
73 * ROM: 32KB + 16KB (chargen) + 32KB (kanji) + 16KB (Voice Synth)
74 * RAM: 64KB
75 * Text Mode: same as PC-6001 with N60-BASIC; 40x20 and 15 colors with
76 N60M-BASIC
77 * Graphic Modes: same as PC-6001 with N60-BASIC; 80x40 (15 colors),
78 160x200 (15 colors), 320x200 (4 colors) with N60M-BASIC
79 * Sound: BEEP + PSG
80 * Keyboard: JIS Keyboard with 5 function keys, control key, TAB key,
81 HOME/CLR key, INS key, DEL key, CAPS key, GRAPH key, Japanese
82 syllabary key, page key, mode key, STOP key, and cursor key (4
83 directions)
84 * 1 cartslot, floppy drive, optional serial 232 port, 2 joystick ports
85
86
87 PC-6001 mkIISR (1984-12):
88
89 * CPU: Z80A @ 3.58 MHz
90 * ROM: 64KB + 16KB (chargen) + 32KB (kanji) + 32KB (Voice Synth)
91 * RAM: 64KB
92 * Text Mode: same as PC-6001/PC-6001mkII with N60-BASIC; 40x20, 40x25,
93 80x20, 80x25 and 15 colors with N66SR-BASIC
94 * Graphic Modes: same as PC-6001/PC-6001mkII with N60-BASIC; 80x40 (15 colors),
95 320x200 (15 colors), 640x200 (15 colors) with N66SR-BASIC
96 * Sound: BEEP + PSG + FM
97 * Keyboard: JIS Keyboard with 5 function keys, control key, TAB key,
98 HOME/CLR key, INS key, DEL key, CAPS key, GRAPH key, Japanese
99 syllabary key, page key, mode key, STOP key, and cursor key (4
100 directions)
101 * 1 cartslot, floppy drive, optional serial 232 port, 2 joystick ports
102
103
104 info from http://www.geocities.jp/retro_zzz/machines/nec/6001/spc60.html
105
106 =================================================================================================
107
108 PC-6001 irq table:
109 irq vector 0x00: writes 0x00 to [$fa19] ;(unused)
110 irq vector 0x02: (A = 0, B = 0) tests ppi port c, does something with ay ports (plus more?) ;keyboard data ready, no kanji lock, no caps lock
111 irq vector 0x04: ;uart irq
112 irq vector 0x06: operates with $fa28, $fa2e, $fd1b ;timer irq
113 irq vector 0x08: tests ppi port c, puts port A to $fa1d,puts 0x02 to [$fa19] ;tape data ready
114 irq vector 0x0a: writes 0x00 to [$fa19] ;(unused)
115 irq vector 0x0c: writes 0x00 to [$fa19] ;(unused)
116 irq vector 0x0e: same as 2, (A = 0x03, B = 0x00) ;keyboard data ready, unknown type
117 irq vector 0x10: same as 2, (A = 0x03, B = 0x00) ;(unused)
118 irq vector 0x12: writes 0x10 to [$fa19] ;end of tape reached
119 irq vector 0x14: same as 2, (A = 0x00, B = 0x01) ;kanji lock enabled
120 irq vector 0x16: tests ppi port c, writes the result to $feca. ;joystick
121 irq vector 0x18: ;TVR (?)
122 irq vector 0x1a: ;Date
123 irq vector 0x1c: ;(unused)
124 irq vector 0x1e: ;(unused)
125 irq vector 0x20: ;voice
126 irq vector 0x22: ;VRTC (?)
127 irq vector 0x24: ;(unused)
128 irq vector 0x26: ;(unused)
129
130 ************************************************************************************************/
131
132 #include "emu.h"
133 #include "includes/pc6001.h"
134
135 #define IRQ_LOG (0)
136
cassette_latch_control(bool new_state)137 inline void pc6001_state::cassette_latch_control(bool new_state)
138 {
139 // 0 -> 1 transition: send PLAY tape cmd to i8049
140 if((!(m_sys_latch & 8)) && new_state == true) //PLAY tape cmd
141 {
142 m_cas_switch = 1;
143 //m_cassette->change_state(CASSETTE_MOTOR_ENABLED,CASSETTE_MASK_MOTOR);
144 //m_cassette->change_state(CASSETTE_PLAY,CASSETTE_MASK_UISTATE);
145 }
146 // 1 -> 0 transition: send STOP tape cmd to i8049
147 if((m_sys_latch & 8) && new_state == false) //STOP tape cmd
148 {
149 m_cas_switch = 0;
150 //m_cassette->change_state(CASSETTE_MOTOR_DISABLED,CASSETTE_MASK_MOTOR);
151 //m_cassette->change_state(CASSETTE_STOPPED,CASSETTE_MASK_UISTATE);
152 //set_maincpu_irq_line(0x00);
153 }
154 }
155
156 // TODO: this is explicitly needed for making all machines to boot
ppi_control_hack_w(uint8_t data)157 inline void pc6001_state::ppi_control_hack_w(uint8_t data)
158 {
159 if(data & 1)
160 m_port_c_8255 |= 1<<((data>>1)&0x07);
161 else
162 m_port_c_8255 &= ~(1<<((data>>1)&0x07));
163
164 #ifdef UNUSED_FUNCTION
165 // this switch-case is overwritten below anyway!?
166 switch(data)
167 {
168 case 0x08: m_port_c_8255 |= 0x88; break;
169 case 0x09: m_port_c_8255 &= 0xf7; break;
170 case 0x0c: m_port_c_8255 |= 0x28; break;
171 case 0x0d: m_port_c_8255 &= 0xf7; break;
172 default: break;
173 }
174 #endif
175
176 m_port_c_8255 |= 0xa8;
177 }
178
set_maincpu_irq_line(uint8_t vector_num)179 inline void pc6001_state::set_maincpu_irq_line(uint8_t vector_num)
180 {
181 m_irq_vector = vector_num;
182 m_maincpu->set_input_line(0, ASSERT_LINE);
183 }
184
system_latch_w(uint8_t data)185 void pc6001_state::system_latch_w(uint8_t data)
186 {
187 static const uint16_t startaddr[] = {0xC000, 0xE000, 0x8000, 0xA000 };
188
189 m_video_ram = m_ram + startaddr[(data >> 1) & 0x03] - 0x8000;
190
191 cassette_latch_control((data & 8) == 8);
192 m_sys_latch = data;
193
194 m_timer_irq_mask = data & 1;
195 //printf("%02x\n",data);
196 }
197
198
nec_ppi8255_r(offs_t offset)199 uint8_t pc6001_state::nec_ppi8255_r(offs_t offset)
200 {
201 if (offset==2)
202 return m_port_c_8255;
203 else if(offset==0)
204 {
205 uint8_t res;
206 res = m_cur_keycode;
207 //m_cur_keycode = 0;
208 return res;
209 }
210
211 return m_ppi->read(offset);
212 }
213
nec_ppi8255_w(offs_t offset,uint8_t data)214 void pc6001_state::nec_ppi8255_w(offs_t offset, uint8_t data)
215 {
216 if (offset==3)
217 {
218 ppi_control_hack_w(data);
219 //printf("%02x\n",data);
220
221 if ((data & 0x0f) == 0x05 && m_cart_rom)
222 m_bank1->set_base(m_cart_rom->base() + 0x2000);
223 if ((data & 0x0f) == 0x04)
224 m_bank1->set_base(m_region_gfx1->base());
225 }
226
227 m_ppi->write(offset,data);
228 }
229
pc6001_map(address_map & map)230 void pc6001_state::pc6001_map(address_map &map)
231 {
232 map.unmap_value_high();
233 map(0x0000, 0x3fff).rom().nopw();
234 // map(0x4000, 0x5fff) // mapped by the cartslot
235 map(0x6000, 0x7fff).bankr("bank1");
236 map(0x8000, 0xffff).ram().share("ram");
237 }
238
pc6001_io(address_map & map)239 void pc6001_state::pc6001_io(address_map &map)
240 {
241 map.unmap_value_high();
242 map.global_mask(0xff);
243 map(0x80, 0x81).rw("uart", FUNC(i8251_device::read), FUNC(i8251_device::write));
244 map(0x90, 0x93).mirror(0x0c).rw(FUNC(pc6001_state::nec_ppi8255_r), FUNC(pc6001_state::nec_ppi8255_w));
245 map(0xa0, 0xa0).mirror(0x0c).w("ay8910", FUNC(ay8910_device::address_w));
246 map(0xa1, 0xa1).mirror(0x0c).w("ay8910", FUNC(ay8910_device::data_w));
247 map(0xa2, 0xa2).mirror(0x0c).r("ay8910", FUNC(ay8910_device::data_r));
248 map(0xa3, 0xa3).mirror(0x0c).nopw();
249 map(0xb0, 0xb0).mirror(0x0f).w(FUNC(pc6001_state::system_latch_w));
250 map(0xd0, 0xd3).mirror(0x0c).noprw(); // disk device
251 }
252
253 /*****************************************
254 *
255 * PC-6001Mk2 specific i/o
256 *
257 ****************************************/
258
259 /*
260 ROM_REGION( 0x28000, "maincpu", ROMREGION_ERASEFF )
261 ROM_LOAD( "basicrom.62", 0x10000, 0x8000, CRC(950ac401) SHA1(fbf195ba74a3b0f80b5a756befc96c61c2094182) )
262 ROM_LOAD( "voicerom.62", 0x18000, 0x4000, CRC(49b4f917) SHA1(1a2d18f52ef19dc93da3d65f19d3abbd585628af) )
263 ROM_LOAD( "cgrom60.62", 0x1c000, 0x2000, CRC(81eb5d95) SHA1(53d8ae9599306ff23bf95208d2f6cc8fed3fc39f) )
264 ROM_LOAD( "cgrom60m.62", 0x1e000, 0x2000, CRC(3ce48c33) SHA1(f3b6c63e83a17d80dde63c6e4d86adbc26f84f79) )
265 ROM_LOAD( "kanjirom.62", 0x20000, 0x8000, CRC(20c8f3eb) SHA1(4c9f30f0a2ebbe70aa8e697f94eac74d8241cadd) )
266 */
267
268 #define BASICROM(_v_) \
269 0x10000+0x2000*_v_
270 #define VOICEROM(_v_) \
271 0x18000+0x2000*_v_
272 #define TVROM(_v_) \
273 0x1c000+0x2000*_v_
274 #define KANJIROM(_v_) \
275 0x20000+0x2000*_v_
276 #define WRAM(_v_) \
277 0x28000+0x2000*_v_
278 #define EXWRAM(_v_) \
279 0x38000+0x2000*_v_
280 #define EXROM(_v_) \
281 0x48000+0x2000*_v_
282 #define INVALID(_v_) \
283 0x4c000+0x2000*_v_
284 // TODO: rewrite using bankdev
285 // TODO: some comments aren't right
286 static const uint32_t banksw_table_r0[0x10*4][4] = {
287 /* 0 */
288 { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x00: <invalid setting>
289 { BASICROM(0), BASICROM(1), BASICROM(2), BASICROM(3) }, //0x01: basic rom 0 & 1 / basic rom 2 & 3
290 { TVROM(0), TVROM(1), VOICEROM(0), VOICEROM(1) }, //0x02: tv rom 0 & 1 / voice rom 0 & 1
291 { EXROM(1), EXROM(1), EXROM(1), EXROM(1) }, //0x03: ex rom 1 & 1 / ex rom 1 & 1
292 { EXROM(0), EXROM(0), EXROM(0), EXROM(0) }, //0x04: ex rom 0 & 0 / ex rom 0 & 0
293 { TVROM(1), BASICROM(1), VOICEROM(0), BASICROM(3) }, //0x05: tv rom 1 & basic rom 1 / voice rom 0 & basic 3
294 { BASICROM(0), TVROM(2), BASICROM(2), VOICEROM(1) }, //0x06: basic rom 0 & tv rom 2 / basic rom 2 & voice 1
295 { EXROM(0), EXROM(1), EXROM(0), EXROM(1) }, //0x07: ex rom 0 & ex rom 1 / ex rom 0 & ex rom 1
296 { EXROM(1), EXROM(0), EXROM(1), EXROM(0) }, //0x08: ex rom 1 & ex rom 0 / ex rom 1 & ex rom 0
297 { EXROM(1), BASICROM(1), EXROM(1), BASICROM(3) }, //0x09: ex rom 1 & basic rom 1 / ex rom 1 & basic 3
298 { BASICROM(0), EXROM(1), BASICROM(2), EXROM(1) }, //0x0a: basic rom 0 & ex rom 1 / basic rom 2 & ex rom 1
299 { EXROM(0), TVROM(2), EXROM(0), VOICEROM(1) }, //0x0b: ex rom 0 & tv rom 2 / ex rom 0 & voice 1
300 { TVROM(1), EXROM(0), VOICEROM(0), EXROM(0) }, //0x0c: tv rom 1 & ex rom 0 / voice rom 0 & ex rom 0
301 { WRAM(0), WRAM(1), WRAM(2), WRAM(3) }, //0x0d: ram 0 & 1 / ram 2 & 3
302 { EXWRAM(0), EXWRAM(1), EXWRAM(2), EXWRAM(3) }, //0x0e: exram 0 & 1 / exram 2 & 3
303 { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x0f: <invalid setting>
304 /* 1 */
305 { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x00: <invalid setting>
306 { BASICROM(0), BASICROM(1), BASICROM(2), BASICROM(3) }, //0x01: basic rom 0 & 1 / basic rom 2 & 3
307 { KANJIROM(0), KANJIROM(1), KANJIROM(0), KANJIROM(1) }, //0x02: tv rom 0 & 1 / voice rom 0 & 1
308 { EXROM(1), EXROM(1), EXROM(1), EXROM(1) }, //0x03: ex rom 1 & 1 / ex rom 1 & 1
309 { EXROM(0), EXROM(0), EXROM(0), EXROM(0) }, //0x04: ex rom 0 & 0 / ex rom 0 & 0
310 { KANJIROM(0), BASICROM(1), KANJIROM(0), BASICROM(3) }, //0x05: tv rom 1 & basic rom 1 / voice rom 0 & basic 3
311 { BASICROM(0), KANJIROM(1), BASICROM(2), KANJIROM(1) }, //0x06: basic rom 0 & tv rom 2 / basic rom 2 & voice 1
312 { EXROM(0), EXROM(1), EXROM(0), EXROM(1) }, //0x07: ex rom 0 & ex rom 1 / ex rom 0 & ex rom 1
313 { EXROM(1), EXROM(0), EXROM(1), EXROM(0) }, //0x08: ex rom 1 & ex rom 0 / ex rom 1 & ex rom 0
314 { EXROM(1), BASICROM(1), EXROM(1), BASICROM(3) }, //0x09: ex rom 1 & basic rom 1 / ex rom 1 & basic 3
315 { BASICROM(0), EXROM(1), BASICROM(2), EXROM(1) }, //0x0a: basic rom 0 & ex rom 1 / basic rom 2 & ex rom 1
316 { EXROM(0), KANJIROM(1), EXROM(0), KANJIROM(1) }, //0x0b: ex rom 0 & tv rom 2 / ex rom 0 & voice 1
317 { KANJIROM(0), EXROM(0), KANJIROM(0), EXROM(0) }, //0x0c: tv rom 1 & ex rom 0 / voice rom 0 & ex rom 0
318 { WRAM(0), WRAM(1), WRAM(2), WRAM(3) }, //0x0d: ram 0 & 1 / ram 2 & 3
319 { EXWRAM(0), EXWRAM(1), EXWRAM(2), EXWRAM(3) }, //0x0e: exram 0 & 1 / exram 2 & 3
320 { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x0f: <invalid setting>
321 /* 2 */
322 { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x00: <invalid setting>
323 { BASICROM(0), BASICROM(1), BASICROM(2), BASICROM(3) }, //0x01: basic rom 0 & 1 / basic rom 2 & 3
324 { TVROM(0), TVROM(1), VOICEROM(0), VOICEROM(1) }, //0x02: tv rom 0 & 1 / voice rom 0 & 1
325 { EXROM(1), EXROM(1), EXROM(1), EXROM(1) }, //0x03: ex rom 1 & 1 / ex rom 1 & 1
326 { EXROM(0), EXROM(0), EXROM(0), EXROM(0) }, //0x04: ex rom 0 & 0 / ex rom 0 & 0
327 { TVROM(1), BASICROM(1), VOICEROM(0), BASICROM(3) }, //0x05: tv rom 1 & basic rom 1 / voice rom 0 & basic 3
328 { BASICROM(0), TVROM(2), BASICROM(2), VOICEROM(1) }, //0x06: basic rom 0 & tv rom 2 / basic rom 2 & voice 1
329 { EXROM(0), EXROM(1), EXROM(0), EXROM(1) }, //0x07: ex rom 0 & ex rom 1 / ex rom 0 & ex rom 1
330 { EXROM(1), EXROM(0), EXROM(1), EXROM(0) }, //0x08: ex rom 1 & ex rom 0 / ex rom 1 & ex rom 0
331 { EXROM(1), BASICROM(1), EXROM(1), BASICROM(3) }, //0x09: ex rom 1 & basic rom 1 / ex rom 1 & basic 3
332 { BASICROM(0), EXROM(1), BASICROM(2), EXROM(1) }, //0x0a: basic rom 0 & ex rom 1 / basic rom 2 & ex rom 1
333 { EXROM(0), TVROM(2), EXROM(0), VOICEROM(1) }, //0x0b: ex rom 0 & tv rom 2 / ex rom 0 & voice 1
334 { TVROM(1), EXROM(0), VOICEROM(0), EXROM(0) }, //0x0c: tv rom 1 & ex rom 0 / voice rom 0 & ex rom 0
335 { WRAM(0), WRAM(1), WRAM(2), WRAM(3) }, //0x0d: ram 0 & 1 / ram 2 & 3
336 { EXWRAM(0), EXWRAM(1), EXWRAM(2), EXWRAM(3) }, //0x0e: exram 0 & 1 / exram 2 & 3
337 { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x0f: <invalid setting>
338 /* 3 */
339 { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x00: <invalid setting>
340 { BASICROM(0), BASICROM(1), BASICROM(2), BASICROM(3) }, //0x01: basic rom 0 & 1 / basic rom 2 & 3
341 { KANJIROM(2), KANJIROM(3), KANJIROM(2), KANJIROM(3) }, //0x02: tv rom 0 & 1 / voice rom 0 & 1
342 { EXROM(1), EXROM(1), EXROM(1), EXROM(1) }, //0x03: ex rom 1 & 1 / ex rom 1 & 1
343 { EXROM(0), EXROM(0), EXROM(0), EXROM(0) }, //0x04: ex rom 0 & 0 / ex rom 0 & 0
344 { KANJIROM(2), BASICROM(1), KANJIROM(2), BASICROM(3) }, //0x05: tv rom 1 & basic rom 1 / voice rom 0 & basic 3
345 { BASICROM(0), KANJIROM(3), BASICROM(2), KANJIROM(3) }, //0x06: basic rom 0 & tv rom 2 / basic rom 2 & voice 1
346 { EXROM(0), EXROM(1), EXROM(0), EXROM(1) }, //0x07: ex rom 0 & ex rom 1 / ex rom 0 & ex rom 1
347 { EXROM(1), EXROM(0), EXROM(1), EXROM(0) }, //0x08: ex rom 1 & ex rom 0 / ex rom 1 & ex rom 0
348 { EXROM(1), BASICROM(1), EXROM(1), BASICROM(3) }, //0x09: ex rom 1 & basic rom 1 / ex rom 1 & basic 3
349 { BASICROM(0), EXROM(1), BASICROM(2), EXROM(1) }, //0x0a: basic rom 0 & ex rom 1 / basic rom 2 & ex rom 1
350 { EXROM(0), KANJIROM(3), EXROM(0), KANJIROM(3) }, //0x0b: ex rom 0 & tv rom 2 / ex rom 0 & voice 1
351 { KANJIROM(2), EXROM(0), KANJIROM(2), EXROM(0) }, //0x0c: tv rom 1 & ex rom 0 / voice rom 0 & ex rom 0
352 { WRAM(0), WRAM(1), WRAM(2), WRAM(3) }, //0x0d: ram 0 & 1 / ram 2 & 3
353 { EXWRAM(0), EXWRAM(1), EXWRAM(2), EXWRAM(3) }, //0x0e: exram 0 & 1 / exram 2 & 3
354 { INVALID(0), INVALID(0), INVALID(0), INVALID(0) } //0x0f: <invalid setting>
355 };
356
357 static const uint32_t banksw_table_r1[0x10*4][4] = {
358 /* 0 */
359 { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x00: <invalid setting>
360 { BASICROM(0), BASICROM(1), BASICROM(2), BASICROM(3) }, //0x01: basic rom 0 & 1 / basic rom 2 & 3
361 { VOICEROM(0), VOICEROM(1), VOICEROM(0), VOICEROM(1) }, //0x02: voice rom 0 & 1 / voice rom 0 & 1
362 { EXROM(1), EXROM(1), EXROM(1), EXROM(1) }, //0x03: ex rom 1 & 1 / ex rom 1 & 1
363 { EXROM(0), EXROM(0), EXROM(0), EXROM(0) }, //0x04: ex rom 0 & 0 / ex rom 0 & 0
364 { VOICEROM(0), BASICROM(1), VOICEROM(0), BASICROM(3) }, //0x05: voice rom 0 & basic rom 1 / voice rom 0 & basic 3
365 { BASICROM(0), VOICEROM(1), BASICROM(2), VOICEROM(1) }, //0x06: basic rom 0 & voice rom 1 / basic rom 2 & voice 1
366 { EXROM(0), EXROM(1), EXROM(0), EXROM(1) }, //0x07: ex rom 0 & ex rom 1 / ex rom 0 & ex rom 1
367 { EXROM(1), EXROM(0), EXROM(1), EXROM(0) }, //0x08: ex rom 1 & ex rom 0 / ex rom 1 & ex rom 0
368 { EXROM(1), BASICROM(1), EXROM(1), BASICROM(3) }, //0x09: ex rom 1 & basic rom 1 / ex rom 1 & basic 3
369 { BASICROM(0), EXROM(1), BASICROM(2), EXROM(1) }, //0x0a: basic rom 0 & ex rom 1 / basic rom 2 & ex rom 1
370 { EXROM(0), VOICEROM(1), EXROM(0), VOICEROM(1) }, //0x0b: ex rom 0 & voice rom 1 / ex rom 0 & voice 1
371 { VOICEROM(0), EXROM(0), VOICEROM(0), EXROM(0) }, //0x0c: voice rom 1 & ex rom 0 / voice rom 0 & ex rom 0
372 { WRAM(4), WRAM(5), WRAM(6), WRAM(7) }, //0x0d: ram 4 & 5 / ram 6 & 7
373 { EXWRAM(4), EXWRAM(5), EXWRAM(6), EXWRAM(7) }, //0x0e: exram 4 & 5 / exram 6 & 7
374 { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x0f: <invalid setting>
375 /* 1 */
376 { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x00: <invalid setting>
377 { BASICROM(0), BASICROM(1), BASICROM(2), BASICROM(3) }, //0x01: basic rom 0 & 1 / basic rom 2 & 3
378 { KANJIROM(0), KANJIROM(1), KANJIROM(0), KANJIROM(1) }, //0x02: kanji rom 0 & 1 / kanji rom 0 & 1
379 { EXROM(1), EXROM(1), EXROM(1), EXROM(1) }, //0x03: ex rom 1 & 1 / ex rom 1 & 1
380 { EXROM(0), EXROM(0), EXROM(0), EXROM(0) }, //0x04: ex rom 0 & 0 / ex rom 0 & 0
381 { KANJIROM(0), BASICROM(1), KANJIROM(0), BASICROM(3) }, //0x05: voice rom 0 & basic rom 1 / voice rom 0 & basic 3
382 { BASICROM(0), KANJIROM(1), BASICROM(2), KANJIROM(1) }, //0x06: basic rom 0 & voice rom 1 / basic rom 2 & voice 1
383 { EXROM(0), EXROM(1), EXROM(0), EXROM(1) }, //0x07: ex rom 0 & ex rom 1 / ex rom 0 & ex rom 1
384 { EXROM(1), EXROM(0), EXROM(1), EXROM(0) }, //0x08: ex rom 1 & ex rom 0 / ex rom 1 & ex rom 0
385 { EXROM(1), BASICROM(1), EXROM(1), BASICROM(3) }, //0x09: ex rom 1 & basic rom 1 / ex rom 1 & basic 3
386 { BASICROM(0), EXROM(1), BASICROM(2), EXROM(1) }, //0x0a: basic rom 0 & ex rom 1 / basic rom 2 & ex rom 1
387 { EXROM(0), KANJIROM(1), EXROM(0), KANJIROM(1) }, //0x0b: ex rom 0 & voice rom 1 / ex rom 0 & voice 1
388 { KANJIROM(0), EXROM(0), KANJIROM(0), EXROM(0) }, //0x0c: voice rom 1 & ex rom 0 / voice rom 0 & ex rom 0
389 { WRAM(4), WRAM(5), WRAM(6), WRAM(7) }, //0x0d: ram 4 & 5 / ram 6 & 7
390 { EXWRAM(4), EXWRAM(5), EXWRAM(6), EXWRAM(7) }, //0x0e: exram 4 & 5 / exram 6 & 7
391 { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x0f: <invalid setting>
392 /* 2 */
393 { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x00: <invalid setting>
394 { BASICROM(0), BASICROM(1), BASICROM(2), BASICROM(3) }, //0x01: basic rom 0 & 1 / basic rom 2 & 3
395 { VOICEROM(0), VOICEROM(1), VOICEROM(0), VOICEROM(1) }, //0x02: voice rom 0 & 1 / voice rom 0 & 1
396 { EXROM(1), EXROM(1), EXROM(1), EXROM(1) }, //0x03: ex rom 1 & 1 / ex rom 1 & 1
397 { EXROM(0), EXROM(0), EXROM(0), EXROM(0) }, //0x04: ex rom 0 & 0 / ex rom 0 & 0
398 { VOICEROM(0), BASICROM(1), VOICEROM(0), BASICROM(3) }, //0x05: voice rom 0 & basic rom 1 / voice rom 0 & basic 3
399 { BASICROM(0), VOICEROM(1), BASICROM(2), VOICEROM(1) }, //0x06: basic rom 0 & voice rom 1 / basic rom 2 & voice 1
400 { EXROM(0), EXROM(1), EXROM(0), EXROM(1) }, //0x07: ex rom 0 & ex rom 1 / ex rom 0 & ex rom 1
401 { EXROM(1), EXROM(0), EXROM(1), EXROM(0) }, //0x08: ex rom 1 & ex rom 0 / ex rom 1 & ex rom 0
402 { EXROM(1), BASICROM(1), EXROM(1), BASICROM(3) }, //0x09: ex rom 1 & basic rom 1 / ex rom 1 & basic 3
403 { BASICROM(0), EXROM(1), BASICROM(2), EXROM(1) }, //0x0a: basic rom 0 & ex rom 1 / basic rom 2 & ex rom 1
404 { EXROM(0), VOICEROM(1), EXROM(0), VOICEROM(1) }, //0x0b: ex rom 0 & voice rom 1 / ex rom 0 & voice 1
405 { VOICEROM(0), EXROM(0), VOICEROM(0), EXROM(0) }, //0x0c: voice rom 1 & ex rom 0 / voice rom 0 & ex rom 0
406 { WRAM(4), WRAM(5), WRAM(6), WRAM(7) }, //0x0d: ram 4 & 5 / ram 6 & 7
407 { EXWRAM(4), EXWRAM(5), EXWRAM(6), EXWRAM(7) }, //0x0e: exram 4 & 5 / exram 6 & 7
408 { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x0f: <invalid setting>
409 /* 3 */
410 { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x00: <invalid setting>
411 { BASICROM(0), BASICROM(1), BASICROM(2), BASICROM(3) }, //0x01: basic rom 0 & 1 / basic rom 2 & 3
412 { KANJIROM(2), KANJIROM(3), KANJIROM(2), KANJIROM(3) }, //0x02: kanji rom 0 & 1 / kanji rom 0 & 1
413 { EXROM(1), EXROM(1), EXROM(1), EXROM(1) }, //0x03: ex rom 1 & 1 / ex rom 1 & 1
414 { EXROM(0), EXROM(0), EXROM(0), EXROM(0) }, //0x04: ex rom 0 & 0 / ex rom 0 & 0
415 { KANJIROM(2), BASICROM(1), KANJIROM(2), BASICROM(3) }, //0x05: voice rom 0 & basic rom 1 / voice rom 0 & basic 3
416 { BASICROM(0), KANJIROM(3), BASICROM(2), KANJIROM(3) }, //0x06: basic rom 0 & voice rom 1 / basic rom 2 & voice 1
417 { EXROM(0), EXROM(1), EXROM(0), EXROM(1) }, //0x07: ex rom 0 & ex rom 1 / ex rom 0 & ex rom 1
418 { EXROM(1), EXROM(0), EXROM(1), EXROM(0) }, //0x08: ex rom 1 & ex rom 0 / ex rom 1 & ex rom 0
419 { EXROM(1), BASICROM(1), EXROM(1), BASICROM(3) }, //0x09: ex rom 1 & basic rom 1 / ex rom 1 & basic 3
420 { BASICROM(0), EXROM(1), BASICROM(2), EXROM(1) }, //0x0a: basic rom 0 & ex rom 1 / basic rom 2 & ex rom 1
421 { EXROM(0), KANJIROM(3), EXROM(0), KANJIROM(3) }, //0x0b: ex rom 0 & voice rom 1 / ex rom 0 & voice 1
422 { KANJIROM(2), EXROM(0), KANJIROM(2), EXROM(0) }, //0x0c: voice rom 1 & ex rom 0 / voice rom 0 & ex rom 0
423 { WRAM(4), WRAM(5), WRAM(6), WRAM(7) }, //0x0d: ram 4 & 5 / ram 6 & 7
424 { EXWRAM(4), EXWRAM(5), EXWRAM(6), EXWRAM(7) }, //0x0e: exram 4 & 5 / exram 6 & 7
425 { INVALID(0), INVALID(0), INVALID(0), INVALID(0) } //0x0f: <invalid setting>
426 };
427
mk2_bank_r0_w(uint8_t data)428 void pc6001mk2_state::mk2_bank_r0_w(uint8_t data)
429 {
430 uint8_t *ROM = m_region_maincpu->base();
431 uint8_t *gfx_data = m_region_gfx1->base();
432
433 // bankaddress = 0x10000 + (0x4000 * ((data & 0x40)>>6));
434 // membank(1)->set_base(&ROM[bankaddress]);
435
436 m_bank_r0 = data;
437
438 // printf("%02x BANK | %02x\n",data,m_bank_opt);
439 m_bank1->set_base(&ROM[banksw_table_r0[(data & 0xf)+(m_bank_opt*0x10)][0]]);
440 m_bank2->set_base(&ROM[banksw_table_r0[(data & 0xf)+(m_bank_opt*0x10)][1]]);
441 m_bank3->set_base(&ROM[banksw_table_r0[((data & 0xf0)>>4)+(m_bank_opt*0x10)][2]]);
442 if(!m_gfx_bank_on)
443 m_bank4->set_base(&ROM[banksw_table_r0[((m_bank_r0 & 0xf0)>>4)+(m_bank_opt*0x10)][3]]);
444 else
445 m_bank4->set_base(&gfx_data[m_cgrom_bank_addr]);
446 }
447
mk2_bank_r1_w(uint8_t data)448 void pc6001mk2_state::mk2_bank_r1_w(uint8_t data)
449 {
450 uint8_t *ROM = m_region_maincpu->base();
451
452 // bankaddress = 0x10000 + (0x4000 * ((data & 0x40)>>6));
453 // membank(1)->set_base(&ROM[bankaddress]);
454
455 m_bank_r1 = data;
456
457 // printf("%02x BANK\n",data);
458 m_bank5->set_base(&ROM[banksw_table_r1[(data & 0xf)+(m_bank_opt*0x10)][0]]);
459 m_bank6->set_base(&ROM[banksw_table_r1[(data & 0xf)+(m_bank_opt*0x10)][1]]);
460 m_bank7->set_base(&ROM[banksw_table_r1[((data & 0xf0)>>4)+(m_bank_opt*0x10)][2]]);
461 m_bank8->set_base(&ROM[banksw_table_r1[((data & 0xf0)>>4)+(m_bank_opt*0x10)][3]]);
462 }
463
mk2_bank_w0_w(uint8_t data)464 void pc6001mk2_state::mk2_bank_w0_w(uint8_t data)
465 {
466 m_bank_w = data;
467 }
468
mk2_opt_bank_w(uint8_t data)469 void pc6001mk2_state::mk2_opt_bank_w(uint8_t data)
470 {
471 uint8_t *ROM = m_region_maincpu->base();
472 uint8_t *gfx_data = m_region_gfx1->base();
473
474 /*
475 0 - TVROM / VOICE ROM
476 1 - KANJI ROM bank 0
477 2 - KANJI ROM bank 1
478 3 - TVROM / VOICE ROM
479 */
480 m_bank_opt = data & 3;
481
482 m_bank1->set_base(&ROM[banksw_table_r0[(m_bank_r0 & 0xf)+(m_bank_opt*0x10)][0]]);
483 m_bank2->set_base(&ROM[banksw_table_r0[(m_bank_r0 & 0xf)+(m_bank_opt*0x10)][1]]);
484 m_bank3->set_base(&ROM[banksw_table_r0[((m_bank_r0 & 0xf0)>>4)+(m_bank_opt*0x10)][2]]);
485 if(!m_gfx_bank_on)
486 m_bank4->set_base(&ROM[banksw_table_r0[((m_bank_r0 & 0xf0)>>4)+(m_bank_opt*0x10)][3]]);
487 else
488 m_bank4->set_base(&gfx_data[m_cgrom_bank_addr]);
489 m_bank4->set_base(&ROM[banksw_table_r0[((m_bank_r0 & 0xf0)>>4)+(m_bank_opt*0x10)][3]]);
490 m_bank5->set_base(&ROM[banksw_table_r1[(m_bank_r1 & 0xf)+(m_bank_opt*0x10)][0]]);
491 m_bank6->set_base(&ROM[banksw_table_r1[(m_bank_r1 & 0xf)+(m_bank_opt*0x10)][1]]);
492 m_bank7->set_base(&ROM[banksw_table_r1[((m_bank_r1 & 0xf0)>>4)+(m_bank_opt*0x10)][2]]);
493 m_bank8->set_base(&ROM[banksw_table_r1[((m_bank_r1 & 0xf0)>>4)+(m_bank_opt*0x10)][3]]);
494
495 }
496
mk2_work_ram0_w(offs_t offset,uint8_t data)497 void pc6001mk2_state::mk2_work_ram0_w(offs_t offset, uint8_t data)
498 {
499 uint8_t *ROM = m_region_maincpu->base();
500 ROM[offset+((m_bank_w & 0x01) ? WRAM(0) : EXWRAM(0))] = data;
501 }
502
mk2_work_ram1_w(offs_t offset,uint8_t data)503 void pc6001mk2_state::mk2_work_ram1_w(offs_t offset, uint8_t data)
504 {
505 uint8_t *ROM = m_region_maincpu->base();
506 ROM[offset+((m_bank_w & 0x01) ? WRAM(1) : EXWRAM(1))] = data;
507 }
508
mk2_work_ram2_w(offs_t offset,uint8_t data)509 void pc6001mk2_state::mk2_work_ram2_w(offs_t offset, uint8_t data)
510 {
511 uint8_t *ROM = m_region_maincpu->base();
512 ROM[offset+((m_bank_w & 0x04) ? WRAM(2) : EXWRAM(2))] = data;
513 }
514
mk2_work_ram3_w(offs_t offset,uint8_t data)515 void pc6001mk2_state::mk2_work_ram3_w(offs_t offset, uint8_t data)
516 {
517 uint8_t *ROM = m_region_maincpu->base();
518 ROM[offset+((m_bank_w & 0x04) ? WRAM(3) : EXWRAM(3))] = data;
519 }
520
mk2_work_ram4_w(offs_t offset,uint8_t data)521 void pc6001mk2_state::mk2_work_ram4_w(offs_t offset, uint8_t data)
522 {
523 uint8_t *ROM = m_region_maincpu->base();
524 ROM[offset+((m_bank_w & 0x10) ? WRAM(4) : EXWRAM(4))] = data;
525 }
526
mk2_work_ram5_w(offs_t offset,uint8_t data)527 void pc6001mk2_state::mk2_work_ram5_w(offs_t offset, uint8_t data)
528 {
529 uint8_t *ROM = m_region_maincpu->base();
530 ROM[offset+((m_bank_w & 0x10) ? WRAM(5) : EXWRAM(5))] = data;
531 }
532
mk2_work_ram6_w(offs_t offset,uint8_t data)533 void pc6001mk2_state::mk2_work_ram6_w(offs_t offset, uint8_t data)
534 {
535 uint8_t *ROM = m_region_maincpu->base();
536 ROM[offset+((m_bank_w & 0x40) ? WRAM(6) : EXWRAM(6))] = data;
537 }
538
mk2_work_ram7_w(offs_t offset,uint8_t data)539 void pc6001mk2_state::mk2_work_ram7_w(offs_t offset, uint8_t data)
540 {
541 uint8_t *ROM = m_region_maincpu->base();
542 ROM[offset+((m_bank_w & 0x40) ? WRAM(7) : EXWRAM(7))] = data;
543 }
544
545
necmk2_ppi8255_w(offs_t offset,uint8_t data)546 void pc6001mk2_state::necmk2_ppi8255_w(offs_t offset, uint8_t data)
547 {
548 if (offset==3)
549 {
550 ppi_control_hack_w(data);
551
552 if((data & 0x0f) == 0x05)
553 {
554 uint8_t *ROM = m_region_maincpu->base();
555
556 m_gfx_bank_on = 0;
557 m_bank4->set_base(&ROM[banksw_table_r0[((m_bank_r0 & 0xf0)>>4)+(m_bank_opt*0x10)][3]]);
558 }
559
560 if((data & 0x0f) == 0x04)
561 {
562 uint8_t *gfx_data = m_region_gfx1->base();
563
564 m_gfx_bank_on = 1;
565 m_bank4->set_base(&gfx_data[m_cgrom_bank_addr]);
566 }
567 }
568
569 m_ppi->write(offset,data);
570 }
571
vram_bank_change(uint8_t vram_bank)572 void pc6001mk2_state::vram_bank_change(uint8_t vram_bank)
573 {
574 uint32_t bank_base_values[8] = { 0x8000, 0xc000, 0xc000, 0xe000, 0x0000, 0x8000, 0x4000, 0xa000 };
575 uint8_t vram_bank_index = ((vram_bank & 0x60) >> 4) | ((vram_bank & 2) >> 1);
576 // uint8_t *work_ram = m_region_maincpu->base();
577
578 // bit 2 of vram_bank sets up 4 color mode
579 set_videoram_bank(0x28000 + bank_base_values[vram_bank_index]);
580
581 // popmessage("%02x",vram_bank);
582 }
583
mk2_system_latch_w(uint8_t data)584 void pc6001mk2_state::mk2_system_latch_w(uint8_t data)
585 {
586 cassette_latch_control((data & 8) == 8);
587 m_sys_latch = data;
588
589 m_timer_irq_mask = data & 1;
590 vram_bank_change((m_ex_vram_bank & 0x06) | ((m_sys_latch & 0x06) << 4));
591
592 //printf("%02x B0\n",data);
593 }
594
refresh_crtc_params()595 inline void pc6001mk2_state::refresh_crtc_params()
596 {
597 /* Apparently bitmap modes changes the screen res to 320 x 200 */
598 rectangle visarea = m_screen->visible_area();
599 int y_height;
600
601 y_height = (m_exgfx_bitmap_mode || m_exgfx_2bpp_mode) ? 200 : 240;
602
603 visarea.set(0, (320) - 1, 0, (y_height) - 1);
604
605 m_screen->configure(m_screen->width(), m_screen->height(), visarea, m_screen->frame_period().attoseconds());
606 }
607
mk2_vram_bank_w(uint8_t data)608 void pc6001mk2_state::mk2_vram_bank_w(uint8_t data)
609 {
610 //static const uint32_t startaddr[] = {WRAM(6), WRAM(6), WRAM(0), WRAM(4) };
611
612 m_ex_vram_bank = data;
613 vram_bank_change((m_ex_vram_bank & 0x06) | ((m_sys_latch & 0x06) << 4));
614
615 m_exgfx_text_mode = ((data & 2) == 0);
616 m_cgrom_bank_addr = (data & 2) ? 0x0000 : 0x2000;
617
618 m_exgfx_bitmap_mode = (data & 8);
619 m_exgfx_2bpp_mode = ((data & 6) == 0);
620
621 refresh_crtc_params();
622
623 // popmessage("%02x",data);
624
625 // m_video_ram = work_ram + startaddr[(data >> 1) & 0x03];
626 }
627
mk2_col_bank_w(uint8_t data)628 void pc6001mk2_state::mk2_col_bank_w(uint8_t data)
629 {
630 m_bgcol_bank = (data & 7);
631 }
632
633
mk2_0xf3_w(uint8_t data)634 void pc6001mk2_state::mk2_0xf3_w(uint8_t data)
635 {
636 /*
637 x--- ---- M1 (?) wait setting
638 -x-- ---- ROM wait setting
639 --x- ---- RAM wait setting
640 ---x ---- custom irq 2 address output
641 ---- x--- custom irq 1 address output
642 ---- -x-- timer irq mask 2 (mirror?)
643 ---- --x- custom irq 2 mask
644 ---- ---x custom irq 1 mask
645 */
646 m_timer_irq_mask2 = data & 4;
647 }
648
set_timer_divider(uint8_t data)649 inline void pc6001_state::set_timer_divider(uint8_t data)
650 {
651 m_timer_hz_div = data;
652 attotime period = attotime::from_hz((487.5*4)/(m_timer_hz_div+1));
653 m_timer_irq_timer->adjust(period, 0, period);
654 }
655
mk2_timer_adj_w(uint8_t data)656 void pc6001mk2_state::mk2_timer_adj_w(uint8_t data)
657 {
658 set_timer_divider(data);
659 }
660
mk2_timer_irqv_w(uint8_t data)661 void pc6001mk2_state::mk2_timer_irqv_w(uint8_t data)
662 {
663 m_timer_irq_vector = data;
664 }
665
mk2_bank_r0_r()666 uint8_t pc6001mk2_state::mk2_bank_r0_r()
667 {
668 return m_bank_r0;
669 }
670
mk2_bank_r1_r()671 uint8_t pc6001mk2_state::mk2_bank_r1_r()
672 {
673 return m_bank_r1;
674 }
675
mk2_bank_w0_r()676 uint8_t pc6001mk2_state::mk2_bank_w0_r()
677 {
678 return m_bank_w;
679 }
680
pc6001mk2_map(address_map & map)681 void pc6001mk2_state::pc6001mk2_map(address_map &map)
682 {
683 map.unmap_value_high();
684 map(0x0000, 0x1fff).bankr("bank1").w(FUNC(pc6001mk2_state::mk2_work_ram0_w));
685 map(0x2000, 0x3fff).bankr("bank2").w(FUNC(pc6001mk2_state::mk2_work_ram1_w));
686 map(0x4000, 0x5fff).bankr("bank3").w(FUNC(pc6001mk2_state::mk2_work_ram2_w));
687 map(0x6000, 0x7fff).bankr("bank4").w(FUNC(pc6001mk2_state::mk2_work_ram3_w));
688 map(0x8000, 0x9fff).bankr("bank5").w(FUNC(pc6001mk2_state::mk2_work_ram4_w));
689 map(0xa000, 0xbfff).bankr("bank6").w(FUNC(pc6001mk2_state::mk2_work_ram5_w));
690 map(0xc000, 0xdfff).bankr("bank7").w(FUNC(pc6001mk2_state::mk2_work_ram6_w));
691 map(0xe000, 0xffff).bankr("bank8").w(FUNC(pc6001mk2_state::mk2_work_ram7_w));
692 }
693
pc6001mk2_io(address_map & map)694 void pc6001mk2_state::pc6001mk2_io(address_map &map)
695 {
696 map.unmap_value_high();
697 map.global_mask(0xff);
698 map(0x80, 0x81).rw("uart", FUNC(i8251_device::read), FUNC(i8251_device::write));
699
700 map(0x90, 0x93).mirror(0x0c).rw(FUNC(pc6001mk2_state::nec_ppi8255_r), FUNC(pc6001mk2_state::necmk2_ppi8255_w));
701
702 map(0xa0, 0xa0).mirror(0x0c).w("ay8910", FUNC(ay8910_device::address_w));
703 map(0xa1, 0xa1).mirror(0x0c).w("ay8910", FUNC(ay8910_device::data_w));
704 map(0xa2, 0xa2).mirror(0x0c).r("ay8910", FUNC(ay8910_device::data_r));
705 map(0xa3, 0xa3).mirror(0x0c).noprw();
706
707 map(0xb0, 0xb0).mirror(0x0f).w(FUNC(pc6001mk2_state::mk2_system_latch_w));
708
709 map(0xc0, 0xc0).w(FUNC(pc6001mk2_state::mk2_col_bank_w));
710 map(0xc1, 0xc1).w(FUNC(pc6001mk2_state::mk2_vram_bank_w));
711 map(0xc2, 0xc2).w(FUNC(pc6001mk2_state::mk2_opt_bank_w));
712
713 map(0xd0, 0xd3).mirror(0x0c).noprw(); // disk device
714
715 map(0xe0, 0xe3).mirror(0x0c).rw("upd7752", FUNC(upd7752_device::read), FUNC(upd7752_device::write));
716
717 map(0xf0, 0xf0).rw(FUNC(pc6001mk2_state::mk2_bank_r0_r), FUNC(pc6001mk2_state::mk2_bank_r0_w));
718 map(0xf1, 0xf1).rw(FUNC(pc6001mk2_state::mk2_bank_r1_r), FUNC(pc6001mk2_state::mk2_bank_r1_w));
719 map(0xf2, 0xf2).rw(FUNC(pc6001mk2_state::mk2_bank_w0_r), FUNC(pc6001mk2_state::mk2_bank_w0_w));
720 map(0xf3, 0xf3).w(FUNC(pc6001mk2_state::mk2_0xf3_w));
721 // map(0xf4
722 // map(0xf5
723 map(0xf6, 0xf6).w(FUNC(pc6001mk2_state::mk2_timer_adj_w));
724 map(0xf7, 0xf7).w(FUNC(pc6001mk2_state::mk2_timer_irqv_w));
725 }
726
727 /*****************************************
728 *
729 * PC-6601 specific i/o
730 *
731 ****************************************/
732
733 // disk device placeholder
734 // TODO: identify & hook-up this FDC
fdc_r()735 uint8_t pc6601_state::fdc_r()
736 {
737 return machine().rand();
738 }
739
fdc_w(uint8_t data)740 void pc6601_state::fdc_w(uint8_t data)
741 {
742 }
743
pc6601_io(address_map & map)744 void pc6601_state::pc6601_io(address_map &map)
745 {
746 map.unmap_value_high();
747 map.global_mask(0xff);
748 pc6001mk2_io(map);
749
750 // these are disk related
751 // map(0xb1
752 // map(0xb2
753 // map(0xb3
754
755 map(0xd0, 0xdf).rw(FUNC(pc6601_state::fdc_r), FUNC(pc6601_state::fdc_w));
756 }
757
758 /*****************************************
759 *
760 * PC-6001 SR specific i/o
761 *
762 ****************************************/
763
764 #define SR_SYSROM_1(_v_) \
765 0x10000+(0x1000*_v_)
766 #define SR_SYSROM_2(_v_) \
767 0x20000+(0x1000*_v_)
768 #define SR_CGROM1(_v_) \
769 0x30000+(0x1000*_v_)
770 #define SR_EXROM0(_v_) \
771 0x40000+(0x1000*_v_)
772 #define SR_EXROM1(_v_) \
773 0x50000+(0x1000*_v_)
774 #define SR_EXRAM0(_v_) \
775 0x60000+(0x1000*_v_)
776 #define SR_WRAM0(_v_) \
777 0x70000+(0x1000*_v_)
778 #define SR_NULL(_v_) \
779 0x80000+(0x1000*_v_)
780
sr_bank_rn_r(offs_t offset)781 uint8_t pc6001sr_state::sr_bank_rn_r(offs_t offset)
782 {
783 return m_sr_bank_r[offset];
784 }
785
sr_bank_rn_w(offs_t offset,uint8_t data)786 void pc6001sr_state::sr_bank_rn_w(offs_t offset, uint8_t data)
787 {
788 memory_bank *bank[8] = { m_bank1, m_bank2, m_bank3, m_bank4, m_bank5, m_bank6, m_bank7, m_bank8 };
789 uint8_t *ROM = m_region_maincpu->base();
790 uint8_t bank_num;
791
792 m_sr_bank_r[offset] = data;
793 bank_num = data & 0x0f;
794
795 switch(data & 0xf0)
796 {
797 case 0xf0: bank[offset]->set_base(&ROM[SR_SYSROM_1(bank_num)]); break;
798 case 0xe0: bank[offset]->set_base(&ROM[SR_SYSROM_2(bank_num)]); break;
799 case 0xd0: bank[offset]->set_base(&ROM[SR_CGROM1(bank_num)]); break;
800 case 0xc0: bank[offset]->set_base(&ROM[SR_EXROM1(bank_num)]); break;
801 case 0xb0: bank[offset]->set_base(&ROM[SR_EXROM0(bank_num)]); break;
802 case 0x20: bank[offset]->set_base(&ROM[SR_EXRAM0(bank_num)]); break;
803 case 0x00: bank[offset]->set_base(&ROM[SR_WRAM0(bank_num)]); break;
804 default: bank[offset]->set_base(&ROM[SR_NULL(bank_num)]); break;
805 }
806 }
807
sr_bank_wn_r(offs_t offset)808 uint8_t pc6001sr_state::sr_bank_wn_r(offs_t offset)
809 {
810 return m_sr_bank_w[offset];
811 }
812
sr_bank_wn_w(offs_t offset,uint8_t data)813 void pc6001sr_state::sr_bank_wn_w(offs_t offset, uint8_t data)
814 {
815 m_sr_bank_w[offset] = data;
816 }
817
sr_bitmap_yoffs_w(uint8_t data)818 void pc6001sr_state::sr_bitmap_yoffs_w(uint8_t data)
819 {
820 m_bitmap_yoffs = data;
821 }
822
sr_bitmap_xoffs_w(uint8_t data)823 void pc6001sr_state::sr_bitmap_xoffs_w(uint8_t data)
824 {
825 m_bitmap_xoffs = data;
826 }
827
828 #define SR_WRAM_BANK_W(_v_) \
829 { \
830 uint8_t *ROM = m_region_maincpu->base(); \
831 uint8_t bank_num; \
832 bank_num = m_sr_bank_w[_v_] & 0x0e; \
833 if((m_sr_bank_w[_v_] & 0xf0) == 0x00) \
834 ROM[offset+(SR_WRAM0(bank_num))] = data; \
835 else if((m_sr_bank_w[_v_] & 0xf0) == 0x20) \
836 ROM[offset+(SR_EXRAM0(bank_num))] = data; \
837 }
838
sr_work_ram0_w(offs_t offset,uint8_t data)839 void pc6001sr_state::sr_work_ram0_w(offs_t offset, uint8_t data)
840 {
841 // TODO: not entirely correct
842 if(m_sr_text_mode == false && m_sr_bank_w[0] == 0)
843 {
844 uint32_t real_offs = (m_bitmap_xoffs*16+m_bitmap_yoffs)*256;
845 real_offs += offset;
846
847 m_gvram[real_offs] = data;
848 return;
849 }
850
851 SR_WRAM_BANK_W(0);
852 }
sr_work_ram1_w(offs_t offset,uint8_t data)853 void pc6001sr_state::sr_work_ram1_w(offs_t offset, uint8_t data){ SR_WRAM_BANK_W(1); }
sr_work_ram2_w(offs_t offset,uint8_t data)854 void pc6001sr_state::sr_work_ram2_w(offs_t offset, uint8_t data){ SR_WRAM_BANK_W(2); }
sr_work_ram3_w(offs_t offset,uint8_t data)855 void pc6001sr_state::sr_work_ram3_w(offs_t offset, uint8_t data){ SR_WRAM_BANK_W(3); }
sr_work_ram4_w(offs_t offset,uint8_t data)856 void pc6001sr_state::sr_work_ram4_w(offs_t offset, uint8_t data){ SR_WRAM_BANK_W(4); }
sr_work_ram5_w(offs_t offset,uint8_t data)857 void pc6001sr_state::sr_work_ram5_w(offs_t offset, uint8_t data){ SR_WRAM_BANK_W(5); }
sr_work_ram6_w(offs_t offset,uint8_t data)858 void pc6001sr_state::sr_work_ram6_w(offs_t offset, uint8_t data){ SR_WRAM_BANK_W(6); }
sr_work_ram7_w(offs_t offset,uint8_t data)859 void pc6001sr_state::sr_work_ram7_w(offs_t offset, uint8_t data){ SR_WRAM_BANK_W(7); }
860
sr_mode_w(uint8_t data)861 void pc6001sr_state::sr_mode_w(uint8_t data)
862 {
863 // if 1 text mode else bitmap mode
864 m_sr_text_mode = bool(BIT(data,3));
865 m_sr_text_rows = data & 4 ? 20 : 25;
866 // bit 1: bus request
867
868 if(data & 1)
869 assert("PC-6001SR in Mk-2 compatibility mode not yet supported!\n");
870 }
871
sr_vram_bank_w(uint8_t data)872 void pc6001sr_state::sr_vram_bank_w(uint8_t data)
873 {
874 set_videoram_bank(0x70000 + ((data & 0x0f)*0x1000));
875 }
876
sr_system_latch_w(uint8_t data)877 void pc6001sr_state::sr_system_latch_w(uint8_t data)
878 {
879 cassette_latch_control((data & 8) == 8);
880 m_sys_latch = data;
881
882 m_timer_irq_mask = data & 1;
883 //vram_bank_change((m_ex_vram_bank & 0x06) | ((m_sys_latch & 0x06) << 4));
884
885 //printf("%02x B0\n",data);
886 }
887
necsr_ppi8255_w(offs_t offset,uint8_t data)888 void pc6001sr_state::necsr_ppi8255_w(offs_t offset, uint8_t data)
889 {
890 if (offset==3)
891 {
892 ppi_control_hack_w(data);
893
894 if(0)
895 {
896 //printf("%02x\n",data);
897
898 if ((data & 0x0f) == 0x05 && m_cart_rom)
899 m_bank1->set_base(m_cart_rom->base() + 0x2000);
900 if ((data & 0x0f) == 0x04)
901 m_bank1->set_base(m_region_gfx1->base());
902 }
903 }
904
905 m_ppi->write(offset,data);
906 }
907
hw_rev_r()908 uint8_t pc6001sr_state::hw_rev_r()
909 {
910 // bit 1 is active for pc6601sr, causes a direct jump to "video telopper" for pc6001mk2sr
911 return 0;
912 }
913
pc6001sr_map(address_map & map)914 void pc6001sr_state::pc6001sr_map(address_map &map)
915 {
916 map.unmap_value_high();
917 map(0x0000, 0x1fff).bankr("bank1").w(FUNC(pc6001sr_state::sr_work_ram0_w));
918 map(0x2000, 0x3fff).bankr("bank2").w(FUNC(pc6001sr_state::sr_work_ram1_w));
919 map(0x4000, 0x5fff).bankr("bank3").w(FUNC(pc6001sr_state::sr_work_ram2_w));
920 map(0x6000, 0x7fff).bankr("bank4").w(FUNC(pc6001sr_state::sr_work_ram3_w));
921 map(0x8000, 0x9fff).bankr("bank5").w(FUNC(pc6001sr_state::sr_work_ram4_w));
922 map(0xa000, 0xbfff).bankr("bank6").w(FUNC(pc6001sr_state::sr_work_ram5_w));
923 map(0xc000, 0xdfff).bankr("bank7").w(FUNC(pc6001sr_state::sr_work_ram6_w));
924 map(0xe000, 0xffff).bankr("bank8").w(FUNC(pc6001sr_state::sr_work_ram7_w));
925 }
926
pc6001sr_io(address_map & map)927 void pc6001sr_state::pc6001sr_io(address_map &map)
928 {
929 map.unmap_value_high();
930 map.global_mask(0xff);
931 // 0x40-0x43 palette indexes
932 map(0x60, 0x67).rw(FUNC(pc6001sr_state::sr_bank_rn_r), FUNC(pc6001sr_state::sr_bank_rn_w));
933 map(0x68, 0x6f).rw(FUNC(pc6001sr_state::sr_bank_wn_r), FUNC(pc6001sr_state::sr_bank_wn_w));
934 map(0x80, 0x81).rw("uart", FUNC(i8251_device::read), FUNC(i8251_device::write));
935
936 map(0x90, 0x93).mirror(0x0c).rw(FUNC(pc6001sr_state::nec_ppi8255_r), FUNC(pc6001sr_state::necsr_ppi8255_w));
937
938 map(0xa0, 0xa0).mirror(0x0c).w("ay8910", FUNC(ay8910_device::address_w));
939 map(0xa1, 0xa1).mirror(0x0c).w("ay8910", FUNC(ay8910_device::data_w));
940 map(0xa2, 0xa2).mirror(0x0c).r("ay8910", FUNC(ay8910_device::data_r));
941 map(0xa3, 0xa3).mirror(0x0c).noprw();
942
943 map(0xb0, 0xb0).w(FUNC(pc6001sr_state::sr_system_latch_w));
944 /* these are disk related */
945 // map(0xb1
946 map(0xb2, 0xb2).r(FUNC(pc6001sr_state::hw_rev_r));
947 // map(0xb3
948
949 map(0xb8, 0xbf).ram().share("irq_vectors");
950 // map(0xc0, 0xc0).w(FUNC(pc6001sr_state::mk2_col_bank_w));
951 // map(0xc1, 0xc1).w(FUNC(pc6001sr_state::mk2_vram_bank_w));
952 // map(0xc2, 0xc2).w(FUNC(pc6001sr_state::opt_bank_w));
953
954 map(0xc8, 0xc8).w(FUNC(pc6001sr_state::sr_mode_w));
955 map(0xc9, 0xc9).w(FUNC(pc6001sr_state::sr_vram_bank_w));
956 map(0xce, 0xce).w(FUNC(pc6001sr_state::sr_bitmap_yoffs_w));
957 map(0xcf, 0xcf).w(FUNC(pc6001sr_state::sr_bitmap_xoffs_w));
958
959 map(0xd0, 0xdf).rw(FUNC(pc6001sr_state::fdc_r), FUNC(pc6001sr_state::fdc_w)); // disk device
960
961 map(0xe0, 0xe3).mirror(0x0c).rw("upd7752", FUNC(upd7752_device::read), FUNC(upd7752_device::write));
962
963 // map(0xf0, 0xf0).rw(FUNC(pc6001sr_state::mk2_bank_r0_r), FUNC(pc6001sr_state::mk2_bank_r0_w));
964 // map(0xf1, 0xf1).rw(FUNC(pc6001sr_state::mk2_bank_r1_r), FUNC(pc6001sr_state::mk2_bank_r1_w));
965 // map(0xf2, 0xf2).rw(FUNC(pc6001sr_state::mk2_bank_w0_r), FUNC(pc6001sr_state::mk2_bank_w0_w));
966 map(0xf3, 0xf3).w(FUNC(pc6001sr_state::mk2_0xf3_w));
967 // map(0xf4
968 // map(0xf5
969 map(0xf6, 0xf6).w(FUNC(pc6001sr_state::mk2_timer_adj_w));
970 map(0xf7, 0xf7).w(FUNC(pc6001sr_state::mk2_timer_irqv_w));
971 }
972
973 /* Input ports */
974 static INPUT_PORTS_START( pc6001 )
975 // TODO: is this really a DSW? bit arrangement is also unknown if so.
976 PORT_START("MODE4_DSW")
977 PORT_DIPNAME( 0x07, 0x00, "Mode 4 GFX colors" )
978 PORT_DIPSETTING( 0x00, "Monochrome" )
979 PORT_DIPSETTING( 0x01, "Red/Blue" )
980 PORT_DIPSETTING( 0x02, "Blue/Red" )
981 PORT_DIPSETTING( 0x03, "Pink/Green" )
982 PORT_DIPSETTING( 0x04, "Green/Pink" )
983 //5-6-7 is presumably invalid
984
985 /* TODO: these two are unchecked */
986 PORT_START("P1")
987 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY
988 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY
989 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY
990 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY
991 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
992 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 )
993 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
994 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
995
996 PORT_START("P2")
997 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
998 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2)
999 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2)
1000 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2)
1001 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
1002 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
1003 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
1004 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
1005
1006 PORT_START("key1") //0x00-0x1f
1007 PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_UNUSED) //0x00 null
1008 PORT_BIT(0x00000002,IP_ACTIVE_HIGH,IPT_UNUSED) //0x01 soh
1009 PORT_BIT(0x00000004,IP_ACTIVE_HIGH,IPT_UNUSED) //0x02 stx
1010 PORT_BIT(0x00000008,IP_ACTIVE_HIGH,IPT_UNUSED) //0x03 etx
1011 PORT_BIT(0x00000010,IP_ACTIVE_HIGH,IPT_UNUSED) //0x04 etx
1012 PORT_BIT(0x00000020,IP_ACTIVE_HIGH,IPT_UNUSED) //0x05 eot
1013 PORT_BIT(0x00000040,IP_ACTIVE_HIGH,IPT_UNUSED) //0x06 enq
1014 PORT_BIT(0x00000080,IP_ACTIVE_HIGH,IPT_UNUSED) //0x07 ack
PORT_CODE(KEYCODE_BACKSPACE)1015 PORT_BIT(0x00000100,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
1016 PORT_BIT(0x00000200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9)
1017 PORT_BIT(0x00000400,IP_ACTIVE_HIGH,IPT_UNUSED) //0x0a
1018 PORT_BIT(0x00000800,IP_ACTIVE_HIGH,IPT_UNUSED) //0x0b lf
1019 PORT_BIT(0x00001000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x0c vt
1020 PORT_BIT(0x00002000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(27)
1021 PORT_BIT(0x00004000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x0e cr
1022 PORT_BIT(0x00008000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x0f so
1023
1024 PORT_BIT(0x00010000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x10 si
1025 PORT_BIT(0x00020000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x11 dle
1026 PORT_BIT(0x00040000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x12 dc1
1027 PORT_BIT(0x00080000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x13 dc2
1028 PORT_BIT(0x00100000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x14 dc3
1029 PORT_BIT(0x00200000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x15 dc4
1030 PORT_BIT(0x00400000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x16 nak
1031 PORT_BIT(0x00800000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x17 syn
1032 PORT_BIT(0x01000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x18 etb
1033 PORT_BIT(0x02000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x19 cancel
1034 PORT_BIT(0x04000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x1a em
1035 PORT_BIT(0x08000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x1b sub
1036 PORT_BIT(0x10000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("RIGHT") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
1037 PORT_BIT(0x20000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("LEFT") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
1038 PORT_BIT(0x40000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("UP") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP))
1039 PORT_BIT(0x80000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("DOWN") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN))
1040
1041 PORT_START("key2") //0x20-0x3f
1042 PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
1043 PORT_BIT(0x00000002,IP_ACTIVE_HIGH,IPT_UNUSED) //0x21 !
1044 PORT_BIT(0x00000004,IP_ACTIVE_HIGH,IPT_UNUSED) //0x22 "
1045 PORT_BIT(0x00000008,IP_ACTIVE_HIGH,IPT_UNUSED) //0x23 #
1046 PORT_BIT(0x00000010,IP_ACTIVE_HIGH,IPT_UNUSED) //0x24 $
1047 PORT_BIT(0x00000020,IP_ACTIVE_HIGH,IPT_UNUSED) //0x25 %
1048 PORT_BIT(0x00000040,IP_ACTIVE_HIGH,IPT_UNUSED) //0x26 &
1049 PORT_BIT(0x00000080,IP_ACTIVE_HIGH,IPT_UNUSED) //0x27 '
1050 PORT_BIT(0x00000100,IP_ACTIVE_HIGH,IPT_UNUSED) //0x28 (
1051 PORT_BIT(0x00000200,IP_ACTIVE_HIGH,IPT_UNUSED) //0x29 )
1052 PORT_BIT(0x00000400,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("*") PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('*')
1053 PORT_BIT(0x00000800,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("+") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR('+')
1054 PORT_BIT(0x00001000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') //0x2c
1055 PORT_BIT(0x00002000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-')
1056 PORT_BIT(0x00004000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') //0x2e
1057 PORT_BIT(0x00008000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') //0x2f
1058
1059 PORT_BIT(0x00010000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0')
1060 PORT_BIT(0x00020000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHAR('1')
1061 PORT_BIT(0x00040000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHAR('2')
1062 PORT_BIT(0x00080000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_CHAR('3')
1063 PORT_BIT(0x00100000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_CHAR('4')
1064 PORT_BIT(0x00200000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_CHAR('5')
1065 PORT_BIT(0x00400000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_CHAR('6')
1066 PORT_BIT(0x00800000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHAR('7')
1067 PORT_BIT(0x01000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHAR('8')
1068 PORT_BIT(0x02000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9')
1069 PORT_BIT(0x04000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x3a :
1070 PORT_BIT(0x08000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x3b ;
1071 PORT_BIT(0x10000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x3c <
1072 PORT_BIT(0x20000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x3d =
1073 PORT_BIT(0x40000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x3e >
1074 PORT_BIT(0x80000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x3f ?
1075
1076 PORT_START("key3") //0x40-0x5f
1077 PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("@") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@')
1078 PORT_BIT(0x00000002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A')
1079 PORT_BIT(0x00000004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B')
1080 PORT_BIT(0x00000008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C')
1081 PORT_BIT(0x00000010,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D')
1082 PORT_BIT(0x00000020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E')
1083 PORT_BIT(0x00000040,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F')
1084 PORT_BIT(0x00000080,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('G')
1085 PORT_BIT(0x00000100,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('H')
1086 PORT_BIT(0x00000200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('I')
1087 PORT_BIT(0x00000400,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('J')
1088 PORT_BIT(0x00000800,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('K')
1089 PORT_BIT(0x00001000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('L')
1090 PORT_BIT(0x00002000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('M')
1091 PORT_BIT(0x00004000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('N')
1092 PORT_BIT(0x00008000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('O')
1093 PORT_BIT(0x00010000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('P')
1094 PORT_BIT(0x00020000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('Q')
1095 PORT_BIT(0x00040000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('R')
1096 PORT_BIT(0x00080000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('S')
1097 PORT_BIT(0x00100000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('T')
1098 PORT_BIT(0x00200000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('U')
1099 PORT_BIT(0x00400000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('V')
1100 PORT_BIT(0x00800000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('W')
1101 PORT_BIT(0x01000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('X')
1102 PORT_BIT(0x02000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y')
1103 PORT_BIT(0x04000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('Z')
1104 PORT_BIT(0x08000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("[") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('[')
1105 PORT_BIT(0x10000000,IP_ACTIVE_HIGH,IPT_UNUSED)
1106 PORT_BIT(0x20000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("]") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR(']')
1107 PORT_BIT(0x40000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("^") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('^')
1108 PORT_BIT(0x80000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("_")
1109
1110 PORT_START("key_modifiers")
1111 PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL)
1112 PORT_BIT(0x00000002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT)
1113 PORT_BIT(0x00000004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("KANA") PORT_CODE(KEYCODE_RCONTROL) PORT_TOGGLE
1114 PORT_BIT(0x00000008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("CAPS") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE
1115 PORT_BIT(0x00000010,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("GRPH") PORT_CODE(KEYCODE_LALT)
1116 PORT_BIT(0x00000020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("STOP") PORT_CODE(KEYCODE_ESC)
1117 INPUT_PORTS_END
1118
1119 TIMER_CALLBACK_MEMBER(pc6001_state::audio_callback)
1120 {
1121 if(m_cas_switch == 0 && ((m_timer_irq_mask == 0) || (m_timer_irq_mask2 == 0)))
1122 {
1123 if(IRQ_LOG) printf("Timer IRQ called %02x\n",m_timer_irq_vector);
1124 set_maincpu_irq_line(m_timer_irq_vector);
1125 }
1126 }
1127
INTERRUPT_GEN_MEMBER(pc6001_state::vrtc_irq)1128 INTERRUPT_GEN_MEMBER(pc6001_state::vrtc_irq)
1129 {
1130 m_cur_keycode = check_joy_press();
1131 if(IRQ_LOG) printf("Joystick IRQ called 0x16\n");
1132 set_maincpu_irq_line(0x16);
1133 }
1134
INTERRUPT_GEN_MEMBER(pc6001sr_state::sr_vrtc_irq)1135 INTERRUPT_GEN_MEMBER(pc6001sr_state::sr_vrtc_irq)
1136 {
1137 m_kludge ^= 1;
1138
1139 // TODO: it is unclear who is responsible of the "Joystick IRQ" vs VRTC
1140 if(m_kludge)
1141 {
1142 m_cur_keycode = check_joy_press();
1143 if(IRQ_LOG) printf("Joystick IRQ called 0x16\n");
1144 set_maincpu_irq_line(0x16);
1145 }
1146 else
1147 {
1148 set_maincpu_irq_line(m_sr_irq_vectors[VRTC_IRQ]);
1149 }
1150 }
1151
IRQ_CALLBACK_MEMBER(pc6001_state::irq_callback)1152 IRQ_CALLBACK_MEMBER(pc6001_state::irq_callback)
1153 {
1154 device.execute().set_input_line(0, CLEAR_LINE);
1155 return m_irq_vector;
1156 }
1157
ppi_porta_r()1158 uint8_t pc6001_state::ppi_porta_r()
1159 {
1160 return 0;
1161 }
1162
ppi_porta_w(uint8_t data)1163 void pc6001_state::ppi_porta_w(uint8_t data)
1164 {
1165 // if(data != 0x06)
1166 // printf("ppi_porta_w %02x\n",data);
1167 }
1168
ppi_portb_r()1169 uint8_t pc6001_state::ppi_portb_r()
1170 {
1171 return 0;
1172 }
1173
ppi_portb_w(uint8_t data)1174 void pc6001_state::ppi_portb_w(uint8_t data)
1175 {
1176 //printf("ppi_portb_w %02x\n",data);
1177 }
1178
ppi_portc_w(uint8_t data)1179 void pc6001_state::ppi_portc_w(uint8_t data)
1180 {
1181 //printf("ppi_portc_w %02x\n",data);
1182 }
1183
ppi_portc_r()1184 uint8_t pc6001_state::ppi_portc_r()
1185 {
1186 return 0x88;
1187 }
1188
check_keyboard_press()1189 uint8_t pc6001_state::check_keyboard_press()
1190 {
1191 int i,port_i,scancode;
1192 uint8_t shift_pressed,caps_lock;
1193 scancode = 0;
1194
1195 shift_pressed = (m_io_key_modifiers->read() & 2)>>1;
1196 caps_lock = (m_io_key_modifiers->read() & 8)>>3;
1197
1198 for(port_i=0;port_i<3;port_i++)
1199 {
1200 for(i=0;i<32;i++)
1201 {
1202 if((m_io_keys[port_i]->read()>>i) & 1)
1203 {
1204 if((shift_pressed != caps_lock) && scancode >= 0x41 && scancode <= 0x5f)
1205 scancode+=0x20;
1206
1207 if(shift_pressed && scancode >= 0x31 && scancode <= 0x39)
1208 scancode-=0x10;
1209
1210 if(shift_pressed && scancode == 0x30) // '0' / '='
1211 scancode = 0x3d;
1212
1213 if(shift_pressed && scancode == 0x2c) // ',' / ';'
1214 scancode = 0x3b;
1215
1216 if(shift_pressed && scancode == 0x2f) // '/' / '?'
1217 scancode = 0x3f;
1218
1219 if(shift_pressed && scancode == 0x2e) // '.' / ':'
1220 scancode = 0x3a;
1221
1222 return scancode;
1223 }
1224 scancode++;
1225 }
1226 }
1227
1228 return 0;
1229 }
1230
check_joy_press()1231 uint8_t pc6001_state::check_joy_press()
1232 {
1233 uint8_t p1_key = m_io_p1->read() ^ 0xff;
1234 uint8_t shift_key = m_io_key_modifiers->read() & 0x02;
1235 uint8_t space_key = m_io_keys[1]->read() & 0x01;
1236 uint8_t joy_press;
1237
1238 /*
1239 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY
1240 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY
1241 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY
1242 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY
1243 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
1244 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
1245 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
1246 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
1247 */
1248
1249 joy_press = 0;
1250
1251 switch(p1_key & 0xf)
1252 {
1253 case 0x01: joy_press = 0x04; break; //up
1254 case 0x02: joy_press = 0x08; break; //down
1255 case 0x04: joy_press = 0x20; break;
1256 case 0x05: joy_press = 0x24; break; //up-left
1257 case 0x06: joy_press = 0x28; break; //down-left
1258 case 0x08: joy_press = 0x10; break; //right
1259 case 0x09: joy_press = 0x14; break; //up-right
1260 case 0x0a: joy_press = 0x18; break; //down-right
1261 }
1262
1263 if(p1_key & 0x10 || space_key) { joy_press |= 0x80; } //button 1 (space)
1264 if(p1_key & 0x20 || shift_key) { joy_press |= 0x01; } //button 2 (shift)
1265
1266 return joy_press;
1267 }
1268
TIMER_DEVICE_CALLBACK_MEMBER(pc6001_state::cassette_callback)1269 TIMER_DEVICE_CALLBACK_MEMBER(pc6001_state::cassette_callback)
1270 {
1271 if(m_cas_switch == 1)
1272 {
1273 #if 0
1274 static uint8_t cas_data_i = 0x80,cas_data_poll;
1275 //m_cur_keycode = gfx_data[m_cas_offset++];
1276 if(m_cassette->input() > 0.03)
1277 cas_data_poll|= cas_data_i;
1278 else
1279 cas_data_poll&=~cas_data_i;
1280 if(cas_data_i == 1)
1281 {
1282 m_cur_keycode = cas_data_poll;
1283 cas_data_i = 0x80;
1284 /* data ready, poll irq */
1285 set_maincpu_irq_line(0x08);
1286 }
1287 else
1288 cas_data_i>>=1;
1289 #else
1290 m_cur_keycode = m_cas_hack->read_rom(m_cas_offset++);
1291 popmessage("%04x %04x", m_cas_offset, m_cas_maxsize);
1292 if(m_cas_offset > m_cas_maxsize)
1293 {
1294 m_cas_offset = 0;
1295 m_cas_switch = 0;
1296 if(IRQ_LOG) printf("Tape-E IRQ 0x12\n");
1297 set_maincpu_irq_line(0x12);
1298 }
1299 else
1300 {
1301 if(IRQ_LOG) printf("Tape-D IRQ 0x08\n");
1302 set_maincpu_irq_line(0x08);
1303 }
1304 #endif
1305 }
1306 }
1307
TIMER_DEVICE_CALLBACK_MEMBER(pc6001_state::keyboard_callback)1308 TIMER_DEVICE_CALLBACK_MEMBER(pc6001_state::keyboard_callback)
1309 {
1310 uint32_t key1 = m_io_keys[0]->read();
1311 uint32_t key2 = m_io_keys[1]->read();
1312 uint32_t key3 = m_io_keys[2]->read();
1313 // uint8_t p1_key = m_io_p1->read();
1314
1315 if(m_cas_switch == 0)
1316 {
1317 if((key1 != m_old_key1) || (key2 != m_old_key2) || (key3 != m_old_key3))
1318 {
1319 m_cur_keycode = check_keyboard_press();
1320 if(IRQ_LOG) printf("KEY IRQ 0x02\n");
1321 set_maincpu_irq_line(0x02);
1322 m_old_key1 = key1;
1323 m_old_key2 = key2;
1324 m_old_key3 = key3;
1325 }
1326 #if 0
1327 else /* joypad polling */
1328 {
1329 m_cur_keycode = check_joy_press();
1330 if(m_cur_keycode)
1331 set_maincpu_irq_line(0x16);
1332 }
1333 #endif
1334 }
1335 }
1336
machine_start()1337 void pc6001_state::machine_start()
1338 {
1339 m_timer_irq_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pc6001_state::audio_callback),this));
1340 }
1341
set_videoram_bank(uint32_t offs)1342 inline void pc6001_state::set_videoram_bank(uint32_t offs)
1343 {
1344 m_video_ram = m_region_maincpu->base() + offs;
1345 }
1346
machine_reset()1347 void pc6001_state::machine_reset()
1348 {
1349 set_videoram_bank(0xc000);
1350
1351 if (m_cart->exists())
1352 m_maincpu->space(AS_PROGRAM).install_read_handler(0x4000, 0x5fff, read8sm_delegate(*m_cart, FUNC(generic_slot_device::read_rom)));
1353
1354 std::string region_tag;
1355 m_cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
1356
1357 m_port_c_8255=0;
1358
1359 m_cas_switch = 0;
1360 m_cas_offset = 0;
1361 m_cas_maxsize = (m_cas_hack->exists()) ? m_cas_hack->get_rom_size() : 0;
1362 m_timer_irq_mask = 1;
1363 m_timer_irq_mask2 = 1;
1364 // timer irq vector is fixed in plain PC-6001
1365 m_timer_irq_vector = 0x06;
1366 set_timer_divider(3);
1367 }
1368
machine_reset()1369 void pc6001mk2_state::machine_reset()
1370 {
1371 pc6001_state::machine_reset();
1372 set_videoram_bank(0xc000 + 0x28000);
1373
1374 std::string region_tag;
1375 m_cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
1376 // TODO: hackish way to simplify bankswitch handling
1377 if (m_cart_rom)
1378 memcpy(m_region_maincpu->base() + 0x48000, m_cart_rom->base(), 0x4000);
1379
1380 /* set default bankswitch */
1381 {
1382 uint8_t *ROM = m_region_maincpu->base();
1383 m_bank_r0 = 0x71;
1384 m_bank1->set_base(&ROM[BASICROM(0)]);
1385 m_bank2->set_base(&ROM[BASICROM(1)]);
1386 m_bank3->set_base(&ROM[EXROM(0)]);
1387 m_bank4->set_base(&ROM[EXROM(1)]);
1388 m_bank_r1 = 0xdd;
1389 m_bank5->set_base(&ROM[WRAM(4)]);
1390 m_bank6->set_base(&ROM[WRAM(5)]);
1391 m_bank7->set_base(&ROM[WRAM(6)]);
1392 m_bank8->set_base(&ROM[WRAM(7)]);
1393 m_bank_opt = 0x02; //tv rom
1394 m_bank_w = 0x50; //enable write to work ram 4,5,6,7
1395 m_gfx_bank_on = 0;
1396 }
1397
1398 // refresh_crtc_params();
1399 }
1400
machine_reset()1401 void pc6001sr_state::machine_reset()
1402 {
1403 pc6001_state::machine_reset();
1404 set_videoram_bank(0x70000);
1405
1406 // default to bitmap mode
1407 m_sr_text_mode = false;
1408 m_sr_text_rows = 20;
1409
1410 std::string region_tag;
1411 m_cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
1412 // should this be mirrored into the EXROM regions? hard to tell without an actual cart dump...
1413
1414 /* set default bankswitch */
1415 {
1416 uint8_t *ROM = m_region_maincpu->base();
1417 m_sr_bank_r[0] = 0xf8; m_bank1->set_base(&ROM[SR_SYSROM_1(0x08)]);
1418 m_sr_bank_r[1] = 0xfa; m_bank2->set_base(&ROM[SR_SYSROM_1(0x0a)]);
1419 m_sr_bank_r[2] = 0xc0; m_bank3->set_base(&ROM[SR_EXROM1(0x00)]);
1420 m_sr_bank_r[3] = 0xb0; m_bank4->set_base(&ROM[SR_EXROM0(0x00)]);
1421 m_sr_bank_r[4] = 0x08; m_bank5->set_base(&ROM[SR_WRAM0(0x08)]);
1422 m_sr_bank_r[5] = 0x0a; m_bank6->set_base(&ROM[SR_WRAM0(0x0a)]);
1423 m_sr_bank_r[6] = 0x0c; m_bank7->set_base(&ROM[SR_WRAM0(0x0c)]);
1424 m_sr_bank_r[7] = 0x0e; m_bank8->set_base(&ROM[SR_WRAM0(0x0e)]);
1425 // m_bank_opt = 0x02; //tv rom
1426
1427 /* enable default work RAM writes */
1428 m_sr_bank_w[0] = 0x00;
1429 m_sr_bank_w[1] = 0x02;
1430 m_sr_bank_w[2] = 0x04;
1431 m_sr_bank_w[3] = 0x06;
1432 m_sr_bank_w[4] = 0x08;
1433 m_sr_bank_w[5] = 0x0a;
1434 m_sr_bank_w[6] = 0x0c;
1435 m_sr_bank_w[7] = 0x0e;
1436
1437 // m_gfx_bank_on = 0;
1438 }
1439 }
1440
1441
1442 static const gfx_layout char_layout =
1443 {
1444 8, 16,
1445 RGN_FRAC(1,1),
1446 1,
1447 { 0 },
1448 { 0, 1, 2, 3, 4, 5, 6, 7 },
1449 { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8,8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 },
1450 8*16
1451 };
1452
1453
1454 static const gfx_layout kanji_layout =
1455 {
1456 16, 16,
1457 RGN_FRAC(1,2),
1458 1,
1459 { 0 },
1460 { 0, 1, 2, 3, 4, 5, 6, 7,
1461 0+RGN_FRAC(1,2), 1+RGN_FRAC(1,2), 2+RGN_FRAC(1,2), 3+RGN_FRAC(1,2), 4+RGN_FRAC(1,2), 5+RGN_FRAC(1,2), 6+RGN_FRAC(1,2), 7+RGN_FRAC(1,2) },
1462 { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8,8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 },
1463 8*16
1464 };
1465
1466 static GFXDECODE_START( gfx_pc6001m2 )
1467 GFXDECODE_ENTRY( "gfx1", 0x0000, char_layout, 2, 1 )
1468 GFXDECODE_ENTRY( "gfx2", 0x0000, kanji_layout, 2, 1 )
1469 GFXDECODE_END
1470
1471 #define PC6001_MAIN_CLOCK 7987200
1472
pc6001(machine_config & config)1473 void pc6001_state::pc6001(machine_config &config)
1474 {
1475 /* basic machine hardware */
1476 Z80(config, m_maincpu, PC6001_MAIN_CLOCK / 2); // PD 780C-1, ~4 Mhz
1477 m_maincpu->set_addrmap(AS_PROGRAM, &pc6001_state::pc6001_map);
1478 m_maincpu->set_addrmap(AS_IO, &pc6001_state::pc6001_io);
1479 m_maincpu->set_vblank_int("screen", FUNC(pc6001_state::vrtc_irq));
1480 m_maincpu->set_irq_acknowledge_callback(FUNC(pc6001_state::irq_callback));
1481
1482 // I8049(config, "subcpu", 7987200);
1483
1484 GFXDECODE(config, "gfxdecode", m_palette, gfx_pc6001m2);
1485
1486 /* video hardware */
1487 SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
1488 m_screen->set_refresh_hz(60);
1489 m_screen->set_screen_update(FUNC(pc6001_state::screen_update_pc6001));
1490 m_screen->set_size(320, 25+192+26);
1491 m_screen->set_visarea(0, 319, 0, 239);
1492 m_screen->set_palette(m_palette);
1493
1494 PALETTE(config, m_palette, FUNC(pc6001_state::pc6001_palette), 16+4);
1495
1496 I8255(config, m_ppi);
1497 m_ppi->in_pa_callback().set(FUNC(pc6001_state::ppi_porta_r));
1498 m_ppi->out_pa_callback().set(FUNC(pc6001_state::ppi_porta_w));
1499 m_ppi->in_pb_callback().set(FUNC(pc6001_state::ppi_portb_r));
1500 m_ppi->out_pb_callback().set(FUNC(pc6001_state::ppi_portb_w));
1501 m_ppi->in_pc_callback().set(FUNC(pc6001_state::ppi_portc_r));
1502 m_ppi->out_pc_callback().set(FUNC(pc6001_state::ppi_portc_w));
1503
1504 /* uart */
1505 I8251(config, "uart", 0);
1506
1507 GENERIC_CARTSLOT(config, m_cart, generic_plain_slot, "pc6001_cart");
1508
1509 // CASSETTE(config, m_cassette);
1510 // m_cassette->set_formats(pc6001_cassette_formats);
1511 // m_cassette->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED);
1512 // m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05);
1513 GENERIC_CARTSLOT(config, m_cas_hack, generic_plain_slot, "pc6001_cass", "cas,p6");
1514
1515 SPEAKER(config, "mono").front_center();
1516 ay8910_device &ay8910(AY8910(config, "ay8910", PC6001_MAIN_CLOCK/4));
1517 ay8910.port_a_read_callback().set_ioport("P1");
1518 ay8910.port_b_read_callback().set_ioport("P2");
1519 ay8910.add_route(ALL_OUTPUTS, "mono", 1.00);
1520
1521 /* TODO: accurate timing on this */
1522 TIMER(config, "keyboard_timer").configure_periodic(FUNC(pc6001_state::keyboard_callback), attotime::from_hz(250));
1523 TIMER(config, "cassette_timer").configure_periodic(FUNC(pc6001_state::cassette_callback), attotime::from_hz(1200/12));
1524 }
1525
1526
1527
pc6001mk2(machine_config & config)1528 void pc6001mk2_state::pc6001mk2(machine_config &config)
1529 {
1530 pc6001(config);
1531 /* basic machine hardware */
1532 m_maincpu->set_addrmap(AS_PROGRAM, &pc6001mk2_state::pc6001mk2_map);
1533 m_maincpu->set_addrmap(AS_IO, &pc6001mk2_state::pc6001mk2_io);
1534
1535 // MCFG_MACHINE_RESET_OVERRIDE(pc6001mk2_state,pc6001mk2)
1536
1537 m_screen->set_screen_update(FUNC(pc6001mk2_state::screen_update_pc6001mk2));
1538
1539 m_palette->set_entries(16+16);
1540 m_palette->set_init(FUNC(pc6001mk2_state::pc6001mk2_palette));
1541
1542 subdevice<gfxdecode_device>("gfxdecode")->set_info(gfx_pc6001m2);
1543
1544 UPD7752(config, "upd7752", PC6001_MAIN_CLOCK/4).add_route(ALL_OUTPUTS, "mono", 1.00);
1545 }
1546
pc6601(machine_config & config)1547 void pc6601_state::pc6601(machine_config &config)
1548 {
1549 pc6001mk2(config);
1550
1551 /* basic machine hardware */
1552 Z80(config.replace(), m_maincpu, PC6001_MAIN_CLOCK / 2);
1553 m_maincpu->set_addrmap(AS_PROGRAM, &pc6601_state::pc6001mk2_map);
1554 m_maincpu->set_addrmap(AS_IO, &pc6601_state::pc6601_io);
1555 m_maincpu->set_vblank_int("screen", FUNC(pc6001_state::vrtc_irq));
1556 m_maincpu->set_irq_acknowledge_callback(FUNC(pc6001_state::irq_callback));
1557 }
1558
pc6001sr(machine_config & config)1559 void pc6001sr_state::pc6001sr(machine_config &config)
1560 {
1561 pc6001mk2(config);
1562
1563 /* basic machine hardware */
1564 //*Yes*, PC-6001 SR Z80 CPU is actually slower than older models (better waitstates tho?)
1565 Z80(config.replace(), m_maincpu, XTAL(3'579'545));
1566 m_maincpu->set_addrmap(AS_PROGRAM, &pc6001sr_state::pc6001sr_map);
1567 m_maincpu->set_addrmap(AS_IO, &pc6001sr_state::pc6001sr_io);
1568 m_maincpu->set_vblank_int("screen", FUNC(pc6001sr_state::sr_vrtc_irq));
1569 m_maincpu->set_irq_acknowledge_callback(FUNC(pc6001_state::irq_callback));
1570
1571 // MCFG_MACHINE_RESET_OVERRIDE(pc6001sr_state,pc6001sr)
1572
1573 m_screen->set_screen_update(FUNC(pc6001sr_state::screen_update_pc6001sr));
1574 }
1575
1576 /* ROM definition */
1577 ROM_START( pc6001 )
1578 ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
1579 ROM_LOAD( "basicrom.60", 0x0000, 0x4000, CRC(54c03109) SHA1(c622fefda3cdc2b87a270138f24c05828b5c41d2) )
1580
1581 ROM_REGION( 0x1000, "mcu", ROMREGION_ERASEFF )
1582 ROM_LOAD( "i8049", 0x0000, 0x1000, NO_DUMP )
1583
1584 ROM_REGION( 0x2000, "gfx1", 0 )
1585 ROM_LOAD( "cgrom60.60", 0x0000, 0x1000, CRC(b0142d32) SHA1(9570495b10af5b1785802681be94b0ea216a1e26) )
1586 ROM_RELOAD( 0x1000, 0x1000 )
1587
1588 ROM_REGION( 0x8000, "gfx2", ROMREGION_ERASEFF )
1589 ROM_END
1590
1591 ROM_START( pc6001a )
1592 ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
1593 ROM_LOAD( "basicrom.60a", 0x0000, 0x4000, CRC(fa8e88d9) SHA1(c82e30050a837e5c8ffec3e0c8e3702447ffd69c) )
1594
1595 ROM_REGION( 0x1000, "mcu", ROMREGION_ERASEFF )
1596 ROM_LOAD( "i8049", 0x0000, 0x1000, NO_DUMP )
1597
1598 ROM_REGION( 0x1000, "gfx1", 0 )
1599 ROM_LOAD( "cgrom60.60a", 0x0000, 0x1000, CRC(49c21d08) SHA1(9454d6e2066abcbd051bad9a29a5ca27b12ec897) )
1600
1601 ROM_REGION( 0x8000, "gfx2", ROMREGION_ERASEFF )
1602 ROM_END
1603
1604 ROM_START( pc6001mk2 )
1605 ROM_REGION( 0x50000, "maincpu", ROMREGION_ERASEFF )
1606 ROM_LOAD( "basicrom.62", 0x10000, 0x8000, CRC(950ac401) SHA1(fbf195ba74a3b0f80b5a756befc96c61c2094182) )
1607 ROM_LOAD( "voicerom.62", 0x18000, 0x4000, CRC(49b4f917) SHA1(1a2d18f52ef19dc93da3d65f19d3abbd585628af) )
1608 ROM_LOAD( "cgrom60.62", 0x1c000, 0x2000, CRC(81eb5d95) SHA1(53d8ae9599306ff23bf95208d2f6cc8fed3fc39f) )
1609 ROM_LOAD( "cgrom60m.62", 0x1e000, 0x2000, CRC(3ce48c33) SHA1(f3b6c63e83a17d80dde63c6e4d86adbc26f84f79) )
1610 ROM_LOAD( "kanjirom.62", 0x20000, 0x8000, CRC(20c8f3eb) SHA1(4c9f30f0a2ebbe70aa8e697f94eac74d8241cadd) )
1611 // work ram 0x28000,0x10000
1612 // extended work ram 0x38000,0x10000
1613 // exrom 0x48000, 0x4000
1614 // <invalid> 0x4c000, 0x4000
1615
1616 ROM_REGION( 0x1000, "mcu", ROMREGION_ERASEFF )
1617 ROM_LOAD( "i8049", 0x0000, 0x1000, NO_DUMP )
1618
1619 ROM_REGION( 0x4000, "gfx1", 0 )
1620 ROM_COPY( "maincpu", 0x1c000, 0x00000, 0x4000 )
1621
1622 ROM_REGION( 0x8000, "gfx2", 0 )
1623 ROM_COPY( "maincpu", 0x20000, 0x00000, 0x8000 )
1624 ROM_END
1625
1626 ROM_START( pc6601 ) /* Variant of pc6001m2 */
1627 ROM_REGION( 0x50000, "maincpu", ROMREGION_ERASEFF )
1628 ROM_LOAD( "basicrom.66", 0x10000, 0x8000, CRC(c0b01772) SHA1(9240bb6b97fe06f5f07b5d65541c4d2f8758cc2a) )
1629 ROM_LOAD( "voicerom.66", 0x18000, 0x4000, CRC(91d078c1) SHA1(6a93bd7723ef67f461394530a9feee57c8caf7b7) )
1630 ROM_LOAD( "cgrom60.66", 0x1c000, 0x2000, CRC(d2434f29) SHA1(a56d76f5cbdbcdb8759abe601eab68f01b0a8fe8) )
1631 ROM_LOAD( "cgrom66.66", 0x1e000, 0x2000, CRC(3ce48c33) SHA1(f3b6c63e83a17d80dde63c6e4d86adbc26f84f79) )
1632 ROM_LOAD( "kanjirom.66", 0x20000, 0x8000, CRC(20c8f3eb) SHA1(4c9f30f0a2ebbe70aa8e697f94eac74d8241cadd) )
1633 // exrom 0x48000, 0x4000
1634
1635 ROM_REGION( 0x1000, "mcu", ROMREGION_ERASEFF )
1636 ROM_LOAD( "i8049", 0x0000, 0x1000, NO_DUMP )
1637
1638 ROM_REGION( 0x4000, "gfx1", 0 )
1639 ROM_COPY( "maincpu", 0x1c000, 0x00000, 0x4000 )
1640
1641 ROM_REGION( 0x8000, "gfx2", 0 )
1642 ROM_COPY( "maincpu", 0x20000, 0x00000, 0x8000 )
1643 ROM_END
1644
1645 ROM_START( pc6001sr )
1646 ROM_REGION( 0x90000, "maincpu", ROMREGION_ERASEFF )
1647 ROM_LOAD( "systemrom1.64", 0x10000, 0x10000, CRC(b6fc2db2) SHA1(dd48b1eee60aa34780f153359f5da7f590f8dff4) )
1648 ROM_LOAD( "systemrom2.64", 0x20000, 0x10000, CRC(55a62a1d) SHA1(3a19855d290fd4ac04e6066fe4a80ecd81dc8dd7) )
1649 // cgrom 1 0x30000, 0x10000
1650 // exrom 0 0x40000, 0x10000
1651 // exrom 1 0x50000, 0x10000
1652 // exram 0 0x60000, 0x10000
1653 // work ram 0 0x70000, 0x10000
1654 // <invalid> 0x80000, 0x10000
1655
1656 ROM_REGION( 0x1000, "mcu", ROMREGION_ERASEFF )
1657 ROM_LOAD( "i8049", 0x0000, 0x1000, NO_DUMP )
1658
1659 ROM_REGION( 0x4000, "gfx1", 0 )
1660 ROM_LOAD( "cgrom68.64", 0x0000, 0x4000, CRC(73bc3256) SHA1(5f80d62a95331dc39b2fb448a380fd10083947eb) )
1661
1662 ROM_REGION( 0x8000, "gfx2", 0 )
1663 ROM_COPY( "maincpu", 0x28000, 0x00000, 0x8000 )
1664 ROM_END
1665
1666 // YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS
1667 COMP( 1981, pc6001, 0, 0, pc6001, pc6001, pc6001_state, empty_init, "NEC", "PC-6001 (Japan)", MACHINE_NOT_WORKING )
1668 COMP( 1981, pc6001a, pc6001, 0, pc6001, pc6001, pc6001_state, empty_init, "NEC", "PC-6001A (US)", MACHINE_NOT_WORKING ) // This version is also known as the NEC Trek
1669 COMP( 1983, pc6001mk2, pc6001, 0, pc6001mk2, pc6001, pc6001mk2_state, empty_init, "NEC", "PC-6001mkII (Japan)", MACHINE_NOT_WORKING )
1670 COMP( 1983, pc6601, pc6001, 0, pc6601, pc6001, pc6601_state, empty_init, "NEC", "PC-6601 (Japan)", MACHINE_NOT_WORKING )
1671 COMP( 1984, pc6001sr, pc6001, 0, pc6001sr, pc6001, pc6001sr_state, empty_init, "NEC", "PC-6001mkIISR (Japan)", MACHINE_NOT_WORKING )
1672