1 // license:BSD-3-Clause
2 // copyright-holders:Jonathan Gevaryahu
3 /******************************************************************************
4 *
5 * V-tech Socrates-series devices
6 * Copyright (C) 2009-2020 Jonathan Gevaryahu AKA Lord Nightmare
7 * with dumping help from Kevin 'kevtris' Horton
8 *
9 * The devices in this driver all use a similar ASIC, presumably produced by
10 * Toshiba for Vtech/Yeno, in a QFP package with 100 pins (30+20+30+20)
11 * The asic variants seen in the wild are:
12 * 27-0769 TC17G032AF-0248 (Socrates NTSC)
13 * 27-0883 1732-8277 (Video Painter and Socrates PAL)
14 *
15 TODO (socrates):
16 * The speech chip is a Toshiba tc8802AF (which is pin and speech
17 compatible with the older Toshiba t6803, but adds vsm rom read mode and
18 apparently does away with the melody mode); the chip is running at
19 800khz clock/10khz output with between 1 and 4 t6684F vsm roms
20 attached; create a sound driver for this!
21 * hook up mouse
22 * add waitstates for ram access (lack of this causes the system to run
23 way too fast)
24 This will require some probing with the LA and the fluke to figure out
25 how many cycles the waitstates are for for rom/ram/etc access.
26 * figure out what bit 6 of the status register actually does; is this an
27 ir mcu busy flag?
28 * keyboard IR decoder MCU is HLE'd for now, needs decap and cpu core
29 * iqunlimz keyboard MCU simulation does not handle key repeats
30
31
32 Socrates Educational Video System
33 FFFF|----------------|
34 | RAM (window 1) |
35 | |
36 C000|----------------|
37 | RAM (window 0) |
38 | |
39 8000|----------------|
40 | ROM (banked) |
41 | *Cartridge |
42 4000|----------------|
43 | ROM (fixed) |
44 | |
45 0000|----------------|
46
47 * cartridge lives in banks 10 onward, see below
48
49 Banked rom area (4000-7fff) bankswitching
50 Bankswitching is achieved by writing to I/O port 0 (mirrored on 1-7)
51 Bank ROM_REGION Contents
52 0 0x00000 - 0x03fff System ROM page 0
53 1 0x04000 - 0x07fff System ROM page 1
54 2 0x08000 - 0x0bfff System ROM page 2
55 ... etc ...
56 E 0x38000 - 0x38fff System ROM page E
57 F 0x3c000 - 0x3ffff System ROM page F
58 10 0x40000 - 0x43fff Expansion Cartridge page 0 (cart ROM 0x0000-0x3fff)
59 11 0x44000 - 0x47fff Expansion Cartridge page 1 (cart ROM 0x4000-0x7fff)
60 ... etc ...
61
62 Banked ram area (z80 0x8000-0xbfff window 0 and z80 0xc000-0xffff window 1)
63 Bankswitching is achieved by writing to I/O port 8 (mirrored to 9-F), only low nybble
64 byte written: 0b****BBAA
65 where BB controls ram window 1 and AA controls ram window 0
66 hence:
67 Write [window 0] [window 1]
68 0 0x0000-0x3fff 0x0000-0x3fff
69 1 0x4000-0x7fff 0x0000-0x3fff
70 2 0x8000-0xbfff 0x0000-0x3fff
71 3 0xc000-0xffff 0x0000-0x3fff
72 4 0x0000-0x3fff 0x4000-0x7fff
73 5 0x4000-0x7fff 0x4000-0x7fff
74 6 0x8000-0xbfff 0x4000-0x7fff
75 7 0xc000-0xffff 0x4000-0x7fff
76 8 0x0000-0x3fff 0x8000-0xbfff
77 9 0x4000-0x7fff 0x8000-0xbfff
78 A 0x8000-0xbfff 0x8000-0xbfff
79 B 0xc000-0xffff 0x8000-0xbfff
80 C 0x0000-0x3fff 0xc000-0xffff
81 D 0x4000-0x7fff 0xc000-0xffff
82 E 0x8000-0xbfff 0xc000-0xffff
83 F 0xc000-0xffff 0xc000-0xffff
84
85 ******************************************************************************/
86
87 #include "emu.h"
88 #include "audio/socrates.h"
89
90 #include "cpu/z80/z80.h"
91
92 #include "bus/generic/carts.h"
93 #include "bus/generic/slot.h"
94 #include "machine/bankdev.h"
95
96 #include "emupal.h"
97 #include "screen.h"
98 #include "softlist.h"
99 #include "speaker.h"
100
101
102 class socrates_state : public driver_device
103 {
104 public:
socrates_state(const machine_config & mconfig,device_type type,const char * tag)105 socrates_state(const machine_config &mconfig, device_type type, const char *tag) :
106 driver_device(mconfig, type, tag),
107 m_maincpu(*this, "maincpu"),
108 m_sound(*this, "soc_snd"),
109 m_screen(*this, "screen"),
110 m_cart(*this, "cartslot"),
111 m_bios_reg(*this, "maincpu"),
112 m_vram_reg(*this, "vram"),
113 m_rombank1(*this, "rombank1"),
114 m_rombank2(*this, "rombank2"),
115 m_rambank1(*this, "rambank1"),
116 m_rambank2(*this, "rambank2"),
117 m_kbdrow(*this, "IN%u", 0)
118 { }
119
120 void socrates(machine_config &config);
121 void socrates_pal(machine_config &config);
122 void vpainter_pal(machine_config &config);
123
124 void init_socrates();
125 void init_iqunlimz();
126 void init_vpainter();
127
128 protected:
129 enum
130 {
131 TIMER_KBMCU_SIM,
132 TIMER_CLEAR_SPEECH,
133 TIMER_CLEAR_IRQ
134 };
135
136 required_device<cpu_device> m_maincpu;
137 required_device<socrates_snd_device> m_sound;
138 required_device<screen_device> m_screen;
139 optional_device<generic_slot_device> m_cart;
140 memory_region *m_cart_reg;
141 required_memory_region m_bios_reg;
142 required_memory_region m_vram_reg;
143 required_device<address_map_bank_device> m_rombank1;
144 optional_device<address_map_bank_device> m_rombank2; // iqunlimz only
145 required_device<address_map_bank_device> m_rambank1;
146 required_device<address_map_bank_device> m_rambank2;
147 optional_ioport_array<0xC> m_kbdrow;
148
149 uint8_t m_rom_bank[2];
150 uint8_t m_ram_bank;
151 uint16_t m_scroll_offset;
152 uint16_t m_kb_spi_buffer;
153 bool m_kb_spi_request;
154 uint8_t m_kbmcu_type; // 0 for socrates, 1 for iqunlimz, 2 for vpainter
155 uint16_t m_oldkeyvalue; // previous key pressed
156 uint16_t m_keyrepeat_holdoffcounter; // keyrepeat holdoff countdown
157 uint8_t m_io40_latch; // what was last written to speech reg (for open bus)?
158 uint8_t m_speech_running; // is speech synth talking?
159 uint32_t m_speech_address; // address in speech space
160 uint8_t m_speech_settings; // speech settings (nybble 0: ? externrom ? ?; nybble 1: ? ? ? ?)
161 uint8_t m_speech_dummy_read; // have we done a dummy read yet?
162 uint8_t m_speech_load_address_count; // number of times load address has happened
163 uint8_t m_speech_load_settings_count; // number of times load settings has happened
164
165 emu_timer *m_kbmcu_sim_timer;
166 emu_timer *m_clear_speech_timer;
167 emu_timer *m_clear_irq_timer;
168
169 struct
170 {
171 uint16_t buffer[8];
172 uint8_t head;
173 uint8_t tail;
174 uint8_t count;
175 } m_kb_queue;
176
177 void socrates_palette(palette_device &palete) const;
178
179 uint8_t common_rom_bank_r(offs_t offset);
180 void common_rom_bank_w(offs_t offset, uint8_t data);
181 uint8_t common_ram_bank_r();
182 void common_ram_bank_w(uint8_t data);
183 uint8_t socrates_cart_r(offs_t offset);
184 uint8_t read_f3();
185 void kbmcu_reset(uint8_t data);
186 uint8_t socrates_status_r();
187 void speech_command(uint8_t data);
188 uint8_t keyboard_buffer_read(offs_t offset);
189 void keyboard_buffer_update(uint8_t data);
190 void kbmcu_sim_reset();
191 void kbmcu_sim_fifo_enqueue(uint16_t data);
192 uint16_t kbmcu_sim_fifo_dequeue();
193 uint16_t kbmcu_sim_fifo_peek();
194 void kbmcu_sim_fifo_head_clear();
195 void reset_speech(uint8_t data);
196 void socrates_scroll_w(offs_t offset, uint8_t data);
197 void socrates_sound_w(offs_t offset, uint8_t data);
198
199 virtual void machine_reset() override;
200 virtual void machine_start() override;
201 virtual void video_start() override;
202
203 uint32_t screen_update_socrates(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
204 INTERRUPT_GEN_MEMBER(assert_irq);
205 TIMER_CALLBACK_MEMBER(kbmcu_sim_cb);
206 TIMER_CALLBACK_MEMBER(clear_speech_cb);
207 TIMER_CALLBACK_MEMBER(clear_irq_cb);
208 void socrates_update_kb();
209 void socrates_check_kb_latch();
210 static rgb_t socrates_create_color(uint8_t color);
211
212 void socrates_rambank_map(address_map &map);
213 void socrates_rombank_map(address_map &map);
214 void socrates_io(address_map &map);
215 void socrates_mem(address_map &map);
216
217 virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
218 };
219
220
221 class iqunlimz_state : public socrates_state
222 {
223 public:
iqunlimz_state(const machine_config & mconfig,device_type type,const char * tag)224 iqunlimz_state(const machine_config &mconfig, device_type type, const char *tag) :
225 socrates_state(mconfig, type, tag)
226 { }
227
228 void iqunlimz(machine_config &config);
229
230 DECLARE_INPUT_CHANGED_MEMBER( send_input );
231
232 protected:
233 virtual void machine_reset() override;
234
235 private:
236 uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
237 void colors_w(offs_t offset, uint8_t data);
238 uint8_t video_regs_r(offs_t offset);
239 void video_regs_w(offs_t offset, uint8_t data);
240 uint8_t status_r();
241
242 void iqunlimz_io(address_map &map);
243 void iqunlimz_mem(address_map &map);
244 void iqunlimz_rambank_map(address_map &map);
245 void iqunlimz_rombank_map(address_map &map);
246
247 int get_color(int index, int y);
248
249 uint8_t m_colors[8];
250 uint8_t m_video_regs[4];
251
252 };
253
254 /* Defines */
255
256 // number of mcu "full cycles" before key repeat
257 #define KEYREPEAT_HOLDOFF 0x1f
258 // number of mcu "full cycles" between key repeats
259 #define KEYREPEAT_REPEAT 1
260
261 /* Components */
262
263 /* Devices */
264
265 /******************************************************************************
266
267 Socrates Keyboard MCU simulation
268
269 *******************************************************************************
270 the tmp50c40 MCU seems to have an 8? word, 12 bit wide internal fifo, which is fed by IR decoded from the
271 remote keyboard. The socrates reads this data out via SPI? by asserting a /cs? bit when keyboard_buffer_update
272 is written to.
273 the bits are returned in two registers, handled by keyboard_buffer_read
274 bits are read out in the following order:
275 offset0 offset1
276 76543210 76543210
277 HHHHMMMM F000LLLL
278 where HHHH is the high nybble, MMMM is the middle nybble, LLLL is the low nybble
279 and F is the fifo status, 1 if the fifo had any data in it at all, and 0 if not
280 if the fifo is empty, the mcu shifts out nothing, and the spi reg holds 00000000 00000001
281 ******************************************************************************/
282
283 /******************************************************************************
284
285 IQUnlimited Keyboard MCU simulation
286
287 *******************************************************************************
288 iq unlimited has a different mcu than socrates, which has an 8-word 8-bit wide
289 fifo instead.
290 As in socrates, the bits are returned in two registers, handled by keyboard_buffer_read
291 bits are read out in the following order:
292 offset0 offset1
293 76543210 76543210
294 HHHHLLLL F000KACS
295 where HHHH is the high nybble, LLLL is the low nybble, KACS is capslock, alt, ctrl and shift,
296 and F is the fifo status, 1 if the fifo had any data in it at all, and 0 if not.
297 KACS are NOT from the fifo, but a live status of the key states.
298 F is also binary ORed with the vblank state???
299 if the fifo is empty, the mcu shifts out nothing, and the spi reg holds 00000000 F000KACS
300 ******************************************************************************/
301
kbmcu_sim_reset()302 void socrates_state::kbmcu_sim_reset()
303 {
304 m_kb_queue.head = m_kb_queue.tail = m_kb_queue.count = 0;
305 for (uint8_t i = 0; i < (sizeof(m_kb_queue.buffer)/sizeof(m_kb_queue.buffer[0])); i++)
306 m_kb_queue.buffer[i]=0;
307 }
308
309
kbmcu_sim_fifo_enqueue(uint16_t data)310 void socrates_state::kbmcu_sim_fifo_enqueue(uint16_t data)
311 {
312 //logerror("kbmcu_sim_fifo_enqueue called with %02x, fifo count was %d\n", data, m_kb_queue.count);
313 if (m_kb_queue.count < 8)
314 {
315 m_kb_queue.buffer[m_kb_queue.tail] = data;
316 m_kb_queue.tail = (m_kb_queue.tail + 1) % (sizeof(m_kb_queue.buffer)/sizeof(m_kb_queue.buffer[0]));
317 m_kb_queue.count++;
318 }
319 }
320
kbmcu_sim_fifo_dequeue()321 uint16_t socrates_state::kbmcu_sim_fifo_dequeue()
322 {
323 if (m_kb_queue.count == 0) fatalerror("kbmcu_sim_fifo_dequeue called with queue count of zero. This should never happen, contact MAMEDEV!");
324 uint16_t retval = m_kb_queue.buffer[m_kb_queue.head];
325 m_kb_queue.count--;
326 m_kb_queue.head = (m_kb_queue.head + 1) % (sizeof(m_kb_queue.buffer)/sizeof(m_kb_queue.buffer[0]));
327 //logerror("kbmcu_sim_fifo_dequeue was called, returning %02x, fifo count is now %d\n", retval, m_kb_queue.count);
328 return retval;
329 }
330
kbmcu_sim_fifo_peek()331 uint16_t socrates_state::kbmcu_sim_fifo_peek()
332 {
333 if (m_kb_queue.count == 0) fatalerror("kbmcu_sim_fifo_peek called with queue count of zero. This should never happen, contact MAMEDEV!");
334 uint16_t retval = m_kb_queue.buffer[m_kb_queue.head];
335 //logerror("kbmcu_sim_fifo_peek was called, returning %02x, fifo count is now %d\n", retval, m_kb_queue.count);
336 return retval;
337 }
338
kbmcu_sim_fifo_head_clear()339 void socrates_state::kbmcu_sim_fifo_head_clear()
340 {
341 m_kb_queue.buffer[m_kb_queue.head] = 0;
342 }
343
machine_start()344 void socrates_state::machine_start()
345 {
346 m_kbmcu_sim_timer = timer_alloc(TIMER_KBMCU_SIM);
347 m_kbmcu_sim_timer->adjust(attotime::from_hz((XTAL(21'477'272)/6)/3000)); // timer rate is a massive guess, depends on instructions per loop of mcu
348 m_clear_speech_timer = timer_alloc(TIMER_CLEAR_SPEECH);
349 m_clear_irq_timer = timer_alloc(TIMER_CLEAR_IRQ);
350 save_item(NAME(m_rom_bank));
351 save_item(NAME(m_ram_bank));
352 save_item(NAME(m_scroll_offset));
353 save_item(NAME(m_kb_spi_request));
354 save_item(NAME(m_kb_spi_buffer));
355 save_item(NAME(m_oldkeyvalue));
356 save_item(NAME(m_keyrepeat_holdoffcounter));
357 save_item(NAME(m_io40_latch));
358 save_item(NAME(m_speech_running));
359 save_item(NAME(m_speech_address));
360 save_item(NAME(m_speech_settings));
361 save_item(NAME(m_speech_dummy_read));
362 save_item(NAME(m_speech_load_address_count));
363 save_item(NAME(m_speech_load_settings_count));
364 m_rom_bank[0] = m_rom_bank[1] = 0x0;
365 m_rombank1->set_bank(0x0); // actually set semi-randomly on real console but we need to initialize it somewhere...
366 m_ram_bank = 0;
367 m_rambank1->set_bank(0x0);// the actual console sets it semi randomly on power up, and the bios cleans it up.
368 m_rambank2->set_bank(0x0);
369 // ASIC SPI buffer starts with garbage in it for one word, simulate this
370 m_kb_spi_buffer = 0xFF8F;
371 }
372
machine_reset()373 void socrates_state::machine_reset()
374 {
375 m_cart_reg = m_cart ? memregion(util::string_format("%s%s", m_cart->tag(), GENERIC_ROM_REGION_TAG).c_str()) : nullptr;
376 kbmcu_sim_reset();
377 m_kb_spi_request = true;
378 m_oldkeyvalue = 0;
379 m_keyrepeat_holdoffcounter = KEYREPEAT_HOLDOFF;
380 m_io40_latch = 0;
381 m_speech_running = 0;
382 m_speech_address = 0;
383 m_speech_settings = 0;
384 m_speech_dummy_read = 0;
385 m_speech_load_address_count = 0;
386 m_speech_load_settings_count = 0;
387 }
388
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)389 void socrates_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
390 {
391 switch (id)
392 {
393 case TIMER_KBMCU_SIM:
394 kbmcu_sim_cb(ptr, param);
395 break;
396 case TIMER_CLEAR_SPEECH:
397 clear_speech_cb(ptr, param);
398 break;
399 case TIMER_CLEAR_IRQ:
400 clear_irq_cb(ptr, param);
401 break;
402 default:
403 throw emu_fatalerror("Unknown id in socrates_state::device_timer");
404 }
405 }
406
init_socrates()407 void socrates_state::init_socrates()
408 {
409 uint8_t *gfx = memregion("vram")->base();
410
411 /* fill vram with its init powerup bit pattern, so startup has the checkerboard screen */
412 for (int i = 0; i < 0x10000; i++)
413 gfx[i] = (((i&0x1)?0x00:0xFF)^((i&0x100)?0x00:0xff));
414 m_maincpu->set_clock_scale(0.45f); /// TODO: RAM access waitstates etc. aren't emulated - slow the CPU to compensate
415 m_kbmcu_type = 0;
416 }
417
init_iqunlimz()418 void socrates_state::init_iqunlimz()
419 {
420 uint8_t *gfx = memregion("vram")->base();
421
422 /* fill vram with its init powerup bit pattern, so startup has the checkerboard screen... is this even right for the iqunlimz? */
423 for (int i = 0; i < 0x20000; i++)
424 gfx[i] = (((i&0x1)?0x00:0xFF)^((i&0x100)?0x00:0xff));
425 //m_maincpu->set_clock_scale(0.45f); /// TODO: RAM access waitstates etc. aren't emulated - slow the CPU to compensate
426 m_kbmcu_type = 1;
427 }
428
init_vpainter()429 void socrates_state::init_vpainter()
430 {
431 uint8_t *gfx = memregion("vram")->base();
432
433 /* fill vram with its init powerup bit pattern, so startup has the checkerboard screen */
434 for (int i = 0; i < 0x10000; i++)
435 gfx[i] = (((i&0x1)?0x00:0xFF)^((i&0x100)?0x00:0xff));
436 m_maincpu->set_clock_scale(0.45f); /// TODO: RAM access waitstates etc. aren't emulated - slow the CPU to compensate
437 m_kbmcu_type = 2;
438 }
439
common_rom_bank_r(offs_t offset)440 uint8_t socrates_state::common_rom_bank_r(offs_t offset)
441 {
442 return m_rom_bank[offset];
443 }
444
common_rom_bank_w(offs_t offset,uint8_t data)445 void socrates_state::common_rom_bank_w(offs_t offset, uint8_t data)
446 {
447 m_rom_bank[offset] = data;
448 if (offset && m_rombank2)
449 m_rombank2->set_bank(data);
450 else
451 m_rombank1->set_bank(data);
452 }
453
common_ram_bank_r()454 uint8_t socrates_state::common_ram_bank_r()
455 {
456 return m_ram_bank;
457 }
458
common_ram_bank_w(uint8_t data)459 void socrates_state::common_ram_bank_w(uint8_t data)
460 {
461 m_ram_bank = data;
462 m_rambank1->set_bank(((data>>2) & 0x0c) | ((data>>0) & 0x03));
463 m_rambank2->set_bank(((data>>4) & 0x0c) | ((data>>2) & 0x03));
464 }
465
socrates_cart_r(offs_t offset)466 uint8_t socrates_state::socrates_cart_r(offs_t offset)
467 {
468 ///TODO: do m_rombank->space(AS_PROGRAM).install_write_handler(0x0002, 0x0002, write8_delegate(FUNC(dac_byte_interface::data_w), (dac_byte_interface *)m_dac)); style stuff
469 // demangle the offset, offset passed is bits 11111111 11111111 00000000 00000000
470 // where . is 0 EDCBA987 65432.10 FEDCBA98 76543210
471 offset = ((offset&0x3FFFF)|((offset&0xF80000)>>1));
472 if (m_cart_reg)
473 {
474 assert(m_cart);
475 offset &= m_cart->get_rom_size()-1;
476 return *(m_cart_reg->base()+offset);
477 }
478 else
479 return 0xF3;
480 }
481
read_f3()482 uint8_t socrates_state::read_f3()// used for read-only i/o ports as mame/mess doesn't have a way to set the unmapped area to read as 0xF3
483 {
484 return 0xF3;
485 }
486
kbmcu_reset(uint8_t data)487 void socrates_state::kbmcu_reset(uint8_t data) // reset the keyboard MCU, clear its fifo
488 {
489 //logerror("0x%04X: kbmcu written with %02X!\n", m_maincpu->pc(), data); //if (m_maincpu->pc() != 0x31D)
490 kbmcu_sim_reset();
491 }
492
socrates_status_r()493 uint8_t socrates_state::socrates_status_r()// read 0x4x, some sort of status reg
494 {
495 // bit 7 - speech status: high when speech is playing, low when it is not (or when speech cart is not present)
496 // bit 6 - unknown, usually set, possibly mcu ready state?
497 // bit 5 - vblank status, high when not in vblank
498 // bit 4 - hblank status, high when not in hblank
499 // bit 3 - speech chip bit 3
500 // bit 2 - speech chip bit 2
501 // bit 1 - speech chip bit 1
502 // bit 0 - speech chip bit 0
503 uint8_t *speechromint = memregion("speechint")->base();
504 uint8_t *speechromext = memregion("speechext")->base();
505 int temp = 0;
506 temp |= (m_speech_running)?0x80:0;
507 temp |= (1)?0x40:0; // unknown, possibly IR mcu ready?
508 temp |= (m_screen->vblank())?0:0x20;
509 temp |= (m_screen->hblank())?0:0x10;
510 switch(m_io40_latch&0xF0) // what was last opcode sent?
511 {
512 case 0x60: case 0xE0:// speech status 'read' register
513 if(m_speech_settings&0x04) // external speech roms (outside of speech ic but still in cart) enabled
514 {
515 logerror("reading external speech rom nybble from nybble address %x (byte address %x)\n",m_speech_address, m_speech_address>>1);
516 temp |= ((speechromext[((m_speech_address>>1)&0xffff)]>>((m_speech_address&1)*4))&0xF);
517 }
518 else
519 {
520 logerror("reading internal speech rom nybble from nybble address %x (byte address %x)\n",m_speech_address, m_speech_address>>1);
521 temp |= ((speechromint[((m_speech_address>>1)&0x1fff)]>>((m_speech_address&1)*4))&0xF);
522 }
523 if (m_speech_dummy_read == 0) // if we havent done the dummy read yet, do so now
524 {
525 m_speech_dummy_read++;
526 }
527 else
528 {
529 m_speech_address++;
530 }
531 break;
532 default:
533 temp |= m_io40_latch&0xF; // read open bus
534 break;
535 }
536 logerror("read from i/o 0x4x of %x\n", temp);
537 return temp;
538 }
539
TIMER_CALLBACK_MEMBER(socrates_state::clear_speech_cb)540 TIMER_CALLBACK_MEMBER(socrates_state::clear_speech_cb)
541 {
542 m_speech_running = 0;
543 m_speech_load_address_count = 0; // should this be here or in the write functuon subpart which is speak command?
544 m_speech_load_settings_count = 0;
545 }
546
speech_command(uint8_t data)547 void socrates_state::speech_command(uint8_t data) // write 0x4x
548 {
549 /*
550 * 76543210
551 * |||||||\-- SEL0
552 * ||||||\--- SEL1
553 * |||||\---- SEL2
554 * ||||\----- SEL3
555 * |||\------ SEL4
556 * ||\------- SEL5
557 * |\-------- 64UP (if LOW the chip is in 'dumb' mode and can only play 64 fixed phrases; if HIGH the chip is in 'cpu controlled' mode and commands work) (not 100% sure about this but suspect it is correct)
558 * \--------- START (in cpu mode must be toggled from low->high for a cpu command to 'take'; in 'dumb' mode must be toggled low->high to start that 'word')
559 */
560 logerror("write to i/o 0x4x of %x\n", data);
561 /*
562 // old readback test, probably get rid of this junk:
563 // 00-0f: readback: 70-7f
564 // 10-1f: readback: 70-7f
565 // 20-2f: readback: 70-7f
566 // 30-3f: readback: 70-7f
567 // 40-5f: readback: 70-7f
568 // 50-5f: readback: 70-7f
569 // 60-6f: readback: ALL 7f
570 // 70-7f: readback: 50, 71-7f (force vblank?)
571 // 80-8f: 80 starts speech reads as f0, rest read as 71-7f
572 // 90-9f: all 70-7f
573 // a0-af: 70-7f
574 // b0-bf: 70-7f
575 // c0-cf: 70-7f
576 // d0-df: 70-7f
577 // e0-ef: readback ALL 76
578 // f0-ff: 70-7f
579 */
580 /* The speech chip is a toshiba tc8802, it is NOT a t6803 since the t6803
581 does not have the rom read mode, which the socrates definitely uses! */
582 /* Commands (tc8802):
583 SEL 5 4 3 2 1 0
584 0 0 n n n n - ADLD - ADdress LoaD - writes one nybble to the address
585 of vsm rom selected (internal or external) starting
586 from the low 4 bits; each subsequent write writes to
587 the next higher 4 bits; resetting the chip resets
588 the position
589 0 1 n n n n - CNDT - CoNDiTion (aka 'setup') - writes one nybble to the
590 setting register, starting from the low 4 bits; the
591 subsequent write will be to the high 4 bits;
592 resetting the chip will reset the position
593
594 CNDT bits (? are from T6803 datasheet, which could be wrong on the tc8802AF here):
595 * 76543210
596 * |||||||\-- ?bits/frame bit 1 (0 = see bit 2; 1 = 98bits/frame (these may be backwards))
597 * ||||||\--- ?melody mode select if high
598 * |||||\---- speech rom select; 0 is internal 8k mask, 1 is external vsm bus
599 * ||||\----- ?voiced source select (0 = A; 1 = B)
600 * |||\------ ?filter stages (0 = lpc-10; 1 = lpc-8)
601 * ||\------- ?always 0
602 * |\-------- ?frame length (0 = 20ms; 1 = 10ms)
603 * \--------- ?bits/frame bit 2 (if bit 1 is not set: 0 = 56 bits/frame; 1 = 50 bits/frame)
604 *
605 1 0 x x x x - DTRD - DaTa ReaD - reads a nybble from the address as loaded
606 and increments the address by one nybble. The first
607 DTRD command after any other commands is a 'dummy
608 read' which serves to reset the bus direction of the
609 low 4 SEL lines, identical to the way the TMS5100
610 does things. it doesn't affect the bus direction of
611 the high two SEL lines.
612 1 1 0 x x x - START - Starts speech at the address as loaded.
613 1 1 1 x x x - RESET - Resets the internal chip state (clears shifters and
614 counters) and forces speech to end/silence
615 immediately.
616 */
617 switch(data&0xF8)
618 {
619 case 0x80: case 0x88: case 0x90: case 0x98: case 0xA0: case 0xA8: case 0xB0: case 0xB8:
620 /* 'dumb' mode speech command: write me: start talking */
621 m_speech_running = 1;
622 m_clear_speech_timer->adjust(attotime::from_seconds(4)); // hack
623 break;
624 case 0xC0: case 0xC8: // ADLD: load address to vsm
625 m_speech_address |= (((int)data&0xF)<<(m_speech_load_address_count*4))<<1;
626 m_speech_load_address_count++;
627 logerror("loaded address nybble %X, byte address is currently %5X with %d nybbles loaded\n", data&0xF, m_speech_address>>1, m_speech_load_address_count);
628 break;
629 case 0xD0: case 0xD8: // CNDT: load settings
630 m_speech_settings |= ((data&0xF)<<(m_speech_load_settings_count*4));
631 m_speech_load_settings_count++;
632 break;
633 case 0xE0: case 0xE8: // DTRD: read byte, handled elsewhere
634 break;
635 case 0xF0: // SPEAK
636 m_speech_running = 1;
637 m_clear_speech_timer->adjust(attotime::from_seconds(4)); // hack
638 break;
639 case 0xF8: // RESET
640 m_speech_running = 0;
641 m_speech_address = 0;
642 m_speech_settings = 0;
643 m_speech_dummy_read = 0;
644 m_speech_load_address_count = 0;
645 m_speech_load_settings_count = 0;
646 m_io40_latch &= 0x0f; // set last command to 0 to prevent problems
647 break;
648 default: // 00 through 70 are packets without the write bit set, ignore them
649 break;
650 }
651 m_io40_latch = data;
652 }
653
keyboard_buffer_read(offs_t offset)654 uint8_t socrates_state::keyboard_buffer_read(offs_t offset)
655 {
656 if (m_kbmcu_type == 0)
657 {
658 if (offset == 1) return m_kb_spi_buffer&0xFF;
659 else return (m_kb_spi_buffer&0xFF00)>>8;
660 }
661 else // if ( (m_kbmcu_type == 1) || (m_kbmcu_type == 2) ) // iqunlimz hack, the system won't work without this?!?!
662 {
663 if (offset == 1) return (m_screen->vblank()?0x80:0)|(m_kbdrow[0]->read()&0xf);
664 else return (m_kb_spi_buffer&0xFF00)>>8;
665 }
666 }
667
keyboard_buffer_update(uint8_t data)668 void socrates_state::keyboard_buffer_update(uint8_t data)
669 {
670 m_kb_spi_request = true;
671 m_kb_spi_buffer = 0x0001;
672 }
673
reset_speech(uint8_t data)674 void socrates_state::reset_speech(uint8_t data)// i/o 60: reset speech synth
675 {
676 m_speech_running = 0;
677 m_speech_address = 0;
678 m_speech_settings = 0;
679 m_speech_dummy_read = 0;
680 m_speech_load_address_count = 0;
681 m_speech_load_settings_count = 0;
682 m_io40_latch &= 0x0f; // set last command to 0 to prevent problems
683 logerror("write to i/o 0x60 of %x\n",data);
684 }
685
686 /* stuff below belongs in video/socrates.c */
687 /* graphics section:
688 0x20 - W - lsb offset of screen display
689 0x21 - W - msb offset of screen display
690 resulting screen line is one of 512 total offsets on 128-byte boundaries in the whole 64k ram
691 */
socrates_scroll_w(offs_t offset,uint8_t data)692 void socrates_state::socrates_scroll_w(offs_t offset, uint8_t data)
693 {
694 if (offset == 0)
695 m_scroll_offset = (m_scroll_offset&0x100) | data;
696 else
697 m_scroll_offset = (m_scroll_offset&0xFF) | ((data&1)<<8);
698 }
699
700 /* NTSC-based Palette stuff */
701 // max for I and Q
702 #define M_I 0.5957
703 #define M_Q 0.5226
704 /* luma amplitudes, measured on scope */
705 #define LUMAMAX 1.420
706 #define LUMA_COL_0 0.355, 0.139, 0.205, 0, 0.569, 0.355, 0.419, 0.205, 0.502, 0.288, 0.358, 0.142, 0.720, 0.502, 0.571, 0.358,
707 #define LUMA_COL_COMMON 0.52, 0.52, 0.52, 0.52, 0.734, 0.734, 0.734, 0.734, 0.667, 0.667, 0.667, 0.667, 0.885, 0.885, 0.885, 0.885,
708 #define LUMA_COL_2 0.574, 0.6565, 0.625, 0.71, 0.792, 0.87, 0.8425, 0.925, 0.724, 0.8055, 0.7825, 0.865, 0.94275, 1.0225, 0.99555, 1.07525,
709 #define LUMA_COL_5 0.4585, 0.382, 0.4065, 0.337, 0.6715, 0.5975, 0.6205, 0.5465, 0.6075, 0.531, 0.5555, 0.45, 0.8255, 0.7455, 0.774, 0.6985,
710 #define LUMA_COL_F 0.690, 0.904, 0.830, 1.053, 0.910, 1.120, 1.053, 1.270, 0.840, 1.053, 0.990, 1.202, 1.053, 1.270, 1.202, 1.420
711 /* chroma amplitudes, measured on scope */
712 #define CHROMAMAX 0.42075
713 #define CHROMA_COL_COMMON 0.148, 0.3125, 0.26475, 0.42075, 0.148, 0.3125, 0.26475, 0.42075, 0.148, 0.3125, 0.26475, 0.42075, 0.148, 0.3125, 0.26475, 0.42075,
714 #define CHROMA_COL_2 0.125125, 0.27525, 0.230225, 0.384875, 0.125125, 0.27525, 0.230225, 0.384875, 0.125125, 0.27525, 0.230225, 0.384875, 0.125125, 0.27525, 0.230225, 0.384875,
715 #define CHROMA_COL_5 0.1235, 0.2695, 0.22625, 0.378, 0.1235, 0.2695, 0.22625, 0.378, 0.1235, 0.2695, 0.22625, 0.378, 0.1235, 0.2695, 0.22625, 0.378,
716 // gamma: this needs to be messed with... may differ on different systems... attach to slider somehow?
717 #define GAMMA 1.5
718
socrates_create_color(uint8_t color)719 rgb_t socrates_state::socrates_create_color(uint8_t color)
720 {
721 static constexpr double lumatable[256] = {
722 LUMA_COL_0
723 LUMA_COL_COMMON
724 LUMA_COL_2
725 LUMA_COL_COMMON
726 LUMA_COL_COMMON
727 LUMA_COL_5
728 LUMA_COL_COMMON
729 LUMA_COL_COMMON
730 LUMA_COL_COMMON
731 LUMA_COL_COMMON
732 LUMA_COL_COMMON
733 LUMA_COL_COMMON
734 LUMA_COL_COMMON
735 LUMA_COL_COMMON
736 LUMA_COL_COMMON
737 LUMA_COL_F };
738 static constexpr double chromaintensity[256] = {
739 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
740 CHROMA_COL_COMMON
741 CHROMA_COL_2
742 CHROMA_COL_COMMON
743 CHROMA_COL_COMMON
744 CHROMA_COL_5
745 CHROMA_COL_COMMON
746 CHROMA_COL_COMMON
747 CHROMA_COL_COMMON
748 CHROMA_COL_COMMON
749 CHROMA_COL_COMMON
750 CHROMA_COL_COMMON
751 CHROMA_COL_COMMON
752 CHROMA_COL_COMMON
753 CHROMA_COL_COMMON
754 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
755 /* chroma colors and phases:
756 0: black-through-grey (0 assumed chroma)
757 1: purple (90 chroma seems correct)
758 2: light blue/green (210 or 240 chroma, 210 seems slightly closer)
759 3: bright blue (150 seems correct)
760 4: green (270 seems correct)
761 5: red (30 seems correct, does have some blue in it)
762 6: orange (0 seems correct, does have some red in it)
763 7: yellow/gold (330 is closest but conflicts with color C, hence 315 seems close, and must have its own delay line separate from the other phases which use a standard 12 phase scheme)
764 8: blue with a hint of green in it (180 seems correct)
765 9: blue-green (210 seems correct)
766 A: forest green (240 seems correct)
767 B: yellow-green (300 seems correct)
768 C: yellow-orange (330 is close but this conflicts with color 7, and is not quite the same; color 7 has more green in it than color C)
769 D: magenta (60 is closest)
770 E: blue-purple (more blue than color 1, 120 is closest)
771 F: grey-through-white (0 assumed chroma)
772 */
773 static constexpr double phaseangle[16] = { 0, 90, 220, 150, 270, 40, 0, 315, 180, 210, 240, 300, 330, 60, 120, 0 }; // note: these are guessed, not measured yet!
774 int const chromaindex = color&0x0F;
775 int const swappedcolor = ((color&0xf0)>>4)|((color&0x0f)<<4);
776 double finalY = (1/LUMAMAX) * lumatable[swappedcolor];
777 double const finalI = (M_I * (cos((phaseangle[chromaindex]/180)*3.141592653589793)))* ((1/CHROMAMAX)*chromaintensity[swappedcolor]);
778 double const finalQ = (M_Q * (sin((phaseangle[chromaindex]/180)*3.141592653589793)))* ((1/CHROMAMAX)*chromaintensity[swappedcolor]);
779 if (finalY > 1) finalY = 1; // clamp luma
780 // calculate the R, G and B values here, neato matrix math
781 double finalR = (finalY*1)+(finalI*0.9563)+(finalQ*0.6210);
782 double finalG = (finalY*1)+(finalI*-0.2721)+(finalQ*-0.6474);
783 double finalB = (finalY*1)+(finalI*-1.1070)+(finalQ*1.7046);
784 // scale/clamp to 0-255 range
785 if (finalR<0) finalR = 0;
786 if (finalR>1) finalR = 1;
787 if (finalG<0) finalG = 0;
788 if (finalG>1) finalG = 1;
789 if (finalB<0) finalB = 0;
790 if (finalB>1) finalB = 1;
791 // gamma correction: 1.0 to GAMMA:
792 finalR = pow(finalR, 1/GAMMA)*255;
793 finalG = pow(finalG, 1/GAMMA)*255;
794 finalB = pow(finalB, 1/GAMMA)*255;
795 return rgb_t((int)finalR,(int)finalG,(int)finalB);
796 }
797
798
socrates_palette(palette_device & palette) const799 void socrates_state::socrates_palette(palette_device &palette) const
800 {
801 for (int i = 0; i < 256; i++)
802 palette.set_pen_color(i, socrates_create_color(i));
803 }
804
video_start()805 void socrates_state::video_start()
806 {
807 m_scroll_offset = 0;
808 }
809
screen_update_socrates(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)810 uint32_t socrates_state::screen_update_socrates(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
811 {
812 static const uint8_t fixedcolors[8] = {
813 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0xF7 };
814 uint8_t const *const videoram = m_vram_reg->base();
815 int lineoffset = 0; // if display ever tries to display data at 0xfxxx, offset line displayed by 0x1000
816 for (int y = 0; y < 228; y++)
817 {
818 if ((((y+m_scroll_offset)*128)&0xffff) >= 0xf000) lineoffset = 0x1000; // see comment above
819 for (int x = 0; x < 264; x++)
820 {
821 int color;
822 if (x < 256)
823 {
824 int colidx =videoram[(((y+m_scroll_offset)*128)+(x>>1)+lineoffset)&0xffff];
825 if (x&1) colidx >>=4;
826 colidx &= 0xF;
827 if (colidx > 7) color=videoram[0xF000+(colidx<<8)+((y+m_scroll_offset)&0xFF)];
828 else color=fixedcolors[colidx];
829 }
830 else
831 {
832 int colidx = videoram[(((y+m_scroll_offset)*128)+(127)+lineoffset)&0xffff];
833 colidx >>=4;
834 colidx &= 0xF;
835 if (colidx > 7) color=videoram[0xF000+(colidx<<8)+((y+m_scroll_offset)&0xFF)];
836 else color=fixedcolors[colidx];
837 }
838 bitmap.pix(y, x) = color;
839 }
840 }
841 return 0;
842 }
843
844 /* below belongs in audio/socrates.cpp */
845
socrates_sound_w(offs_t offset,uint8_t data)846 void socrates_state::socrates_sound_w(offs_t offset, uint8_t data)
847 {
848 switch(offset)
849 {
850 case 0:
851 m_sound->reg0_w(data);
852 break;
853 case 1:
854 m_sound->reg1_w(data);
855 break;
856 case 2:
857 m_sound->reg2_w(data);
858 break;
859 case 3:
860 m_sound->reg3_w(data);
861 break;
862 case 4: case 5: case 6: case 7: default:
863 m_sound->reg4_w(data);
864 break;
865 }
866 }
867
868
869
870 //-----------------------------------------------------------------------------
871 //
872 // IQ Unlimited
873 //
874 //-----------------------------------------------------------------------------
875
get_color(int index,int y)876 int iqunlimz_state::get_color(int index, int y)
877 {
878 if (index < 8)
879 return m_colors[index];
880 else
881 return m_vram_reg->as_u8(0xf000 + ((index & 0x0f) << 8) + ((m_scroll_offset + y + 1) & 0xff));
882 }
883
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)884 uint32_t iqunlimz_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
885 {
886 uint8_t *videoram = m_vram_reg->base();
887
888 // bitmap layer
889 for (int y=0; y<224; y++)
890 {
891 if (y >= m_video_regs[0x03]) break;
892 for (int x=0; x<128; x++)
893 {
894 uint8_t data = videoram[(m_scroll_offset + y) * 0x80 + x];
895
896 for(int b=0; b<2; b++)
897 {
898 bitmap.pix(y, x*2 + b) = get_color(data & 0x0f, y);
899 data >>= 4;
900 }
901 }
902 }
903
904 // text layer
905 bool mode_80 = m_video_regs[0x02] & 0x02; // 80 chars mode
906 int line_len = mode_80 ? 80 : 40;
907 for (int y=0; y<28; y++)
908 {
909 for (int x=0; x<line_len; x++)
910 {
911 uint8_t c = videoram[0x8400 + (y - 1) * (mode_80 ? 0x80 : 0x40) + x];
912 uint8_t *gfx = &videoram[0x8000 + (c & 0x7f) * 8];
913
914 for (int cy=0; cy<8; cy++)
915 {
916 int py = y * 8 + cy;
917 if ((m_video_regs[0x02] & 0x01) || py >= m_video_regs[0x03])
918 {
919 uint8_t col0 = get_color(0x0e, py);
920 uint8_t col1 = get_color(0x0f, py);
921 uint8_t data = 0;
922
923 if (BIT(m_video_regs[0x02],4) && m_video_regs[0x00] == x && m_video_regs[0x01] == ((y - 1) + (0x400 / (mode_80 ? 0x80 : 0x40)))) // cursor position start at 0x8000
924 data = 0xff;
925 else if (y > 0 && y < 26)
926 data = gfx[cy] ^ (c & 0x80 ? 0xff : 0);
927
928 if (x == 0) bitmap.plot_box(0, py, 8 + line_len*6 + 8, 1, col0);
929 for (int cx=0; cx<6; cx++)
930 {
931 int px = 8 + x*6 + cx;
932 bitmap.pix(py, px) = BIT(data, 7) ? col1 : col0;
933 data <<= 1;
934 }
935 }
936 }
937 }
938 }
939
940 return 0;
941 }
942
status_r()943 uint8_t iqunlimz_state::status_r()
944 {
945 // ---x ---- main battery status
946 // --x- ---- backup battery status
947
948 return 0x30;
949 }
950
video_regs_r(offs_t offset)951 uint8_t iqunlimz_state::video_regs_r(offs_t offset)
952 {
953 return m_video_regs[offset];
954 }
955
video_regs_w(offs_t offset,uint8_t data)956 void iqunlimz_state::video_regs_w(offs_t offset, uint8_t data)
957 {
958 if (offset == 2 && ((m_video_regs[offset] ^ data) & 0x02))
959 {
960 rectangle visarea = m_screen->visible_area();
961 visarea.set(0, (data & 0x02 ? 496 : 256) - 1, 0, 224 - 1);
962 m_screen->configure(data & 0x02 ? 496 : 256 , 224, visarea, m_screen->frame_period().attoseconds());
963 }
964
965 m_video_regs[offset] = data;
966 }
967
machine_reset()968 void iqunlimz_state::machine_reset()
969 {
970 socrates_state::machine_reset();
971
972 memset(m_colors, 0, 8);
973 memset(m_video_regs, 0, 4);
974 kbmcu_sim_reset();
975 }
976
colors_w(offs_t offset,uint8_t data)977 void iqunlimz_state::colors_w(offs_t offset, uint8_t data)
978 {
979 m_colors[offset] = data;
980 }
981
982
983 // IQ Unlimited keyboard MCU simulation
984
INPUT_CHANGED_MEMBER(iqunlimz_state::send_input)985 INPUT_CHANGED_MEMBER( iqunlimz_state::send_input )
986 {
987 uint8_t data = (uint8_t)param;
988
989 if (newval)
990 {
991 kbmcu_sim_fifo_enqueue(data<<4);
992 }
993 }
994
995 /******************************************************************************
996 Address Maps
997 ******************************************************************************/
998
socrates_mem(address_map & map)999 void socrates_state::socrates_mem(address_map &map)
1000 {
1001 map.unmap_value_high();
1002 map(0x0000, 0x3fff).rom(); /* system rom, bank 0 (fixed) */
1003 map(0x4000, 0x7fff).m(m_rombank1, FUNC(address_map_bank_device::amap8)); /* banked rom space; system rom is banks 0 through F, cartridge rom is banks 10 onward, usually banks 10 through 17. area past the end of the cartridge, and the whole 10-ff area when no cartridge is inserted, reads as 0xF3 */
1004 map(0x8000, 0xbfff).m(m_rambank1, FUNC(address_map_bank_device::amap8)); /* banked ram 'window' 0 */
1005 map(0xc000, 0xffff).m(m_rambank2, FUNC(address_map_bank_device::amap8)); /* banked ram 'window' 1 */
1006 }
1007
socrates_rombank_map(address_map & map)1008 void socrates_state::socrates_rombank_map(address_map &map)
1009 {
1010 map.unmap_value_high();
1011 map(0x000000, 0x03ffff).rom().region("maincpu", 0).mirror(0xF00000); // xxxx 00** **** **** **** ****
1012 map(0x040000, 0x07ffff).r(FUNC(socrates_state::socrates_cart_r)).select(0xF80000); // **** *1** **** **** **** ****
1013 map(0x080000, 0x0bffff).r(FUNC(socrates_state::read_f3)); // xxxx 10** **** **** **** ****
1014 }
1015
socrates_rambank_map(address_map & map)1016 void socrates_state::socrates_rambank_map(address_map &map)
1017 {
1018 map.unmap_value_high();
1019 map(0x0000, 0xffff).ram().region("vram", 0).mirror(0x30000);
1020 }
1021
socrates_io(address_map & map)1022 void socrates_state::socrates_io(address_map &map)
1023 {
1024 map.unmap_value_high();
1025 map.global_mask(0xff);
1026 map(0x00, 0x00).rw(FUNC(socrates_state::common_rom_bank_r), FUNC(socrates_state::common_rom_bank_w)).mirror(0x7); /* rom bank select - RW - 8 bits */
1027 map(0x08, 0x08).rw(FUNC(socrates_state::common_ram_bank_r), FUNC(socrates_state::common_ram_bank_w)).mirror(0x7); /* ram banks select - RW - 4 low bits; Format: 0b****HHLL where LL controls whether window 0 points at ram area: 0b00: 0x0000-0x3fff; 0b01: 0x4000-0x7fff; 0b10: 0x8000-0xbfff; 0b11: 0xc000-0xffff. HH controls the same thing for window 1 */
1028 map(0x10, 0x17).rw(FUNC(socrates_state::read_f3), FUNC(socrates_state::socrates_sound_w)).mirror(0x8); /* sound section:
1029 0x10 - W - frequency control for channel 1 (louder channel) - 01=high pitch, ff=low; time between 1->0/0->1 transitions = (XTAL(21'477'272)/(512+256) / (freq_reg+1)) (note that this is double the actual frequency since each full low and high squarewave pulse is two transitions)
1030 0x11 - W - frequency control for channel 2 (softer channel) - 01=high pitch, ff=low; same equation as above
1031 0x12 - W - 0b***EVVVV enable, volume control for channel 1
1032 0x13 - W - 0b***EVVVV enable, volume control for channel 2
1033 0x14-0x17 - 0bE??????? enable, unknown for channel 3; produces well defined dmc waves when bit 7 is set, and one or two other bits
1034 This may be some sort of debug register for serial-dmc banging out some internal rom from the asic, maybe color data?
1035 No writes to ram seem to change the waveforms produced, in my limited testing.
1036 0x80 produces about a very very quiet 1/8 duty cycle wave at 60hz or so
1037 0xC0 produces a DMC wave read from an unknown address at around 342hz
1038 <todo: test the others, maybe take samples?>
1039 */
1040 map(0x20, 0x21).rw(FUNC(socrates_state::read_f3), FUNC(socrates_state::socrates_scroll_w)).mirror(0xE);
1041 map(0x30, 0x30).rw(FUNC(socrates_state::read_f3), FUNC(socrates_state::kbmcu_reset)).mirror(0xF); /* resets the keyboard IR decoder MCU */
1042 map(0x40, 0x40).rw(FUNC(socrates_state::socrates_status_r), FUNC(socrates_state::speech_command)).mirror(0xF); /* reads status register for vblank/hblank/speech, also reads and writes speech module */
1043 map(0x50, 0x51).rw(FUNC(socrates_state::keyboard_buffer_read), FUNC(socrates_state::keyboard_buffer_update)).mirror(0xE); /* Keyboard fifo read, pop fifo on write */
1044 map(0x60, 0x60).rw(FUNC(socrates_state::read_f3), FUNC(socrates_state::reset_speech)).mirror(0xF); /* reset the speech module, or perhaps fire an NMI? */
1045 map(0x70, 0xFF).r(FUNC(socrates_state::read_f3)); // nothing mapped here afaik
1046 }
1047
iqunlimz_mem(address_map & map)1048 void iqunlimz_state::iqunlimz_mem(address_map &map)
1049 {
1050 map.unmap_value_high();
1051 map(0x0000, 0x3fff).m(m_rombank2, FUNC(address_map_bank_device::amap8));
1052 map(0x4000, 0x7fff).m(m_rombank1, FUNC(address_map_bank_device::amap8));
1053 map(0x8000, 0xbfff).m(m_rambank1, FUNC(address_map_bank_device::amap8));
1054 map(0xc000, 0xffff).m(m_rambank2, FUNC(address_map_bank_device::amap8));
1055 }
1056
iqunlimz_rombank_map(address_map & map)1057 void iqunlimz_state::iqunlimz_rombank_map(address_map &map)
1058 {
1059 map.unmap_value_high();
1060 map(0x000000, 0x03ffff).rom().region("maincpu", 0).mirror(0xF00000); // xxxx 00** **** **** **** ****
1061 map(0x040000, 0x07ffff).r(FUNC(iqunlimz_state::socrates_cart_r)).select(0xF80000); // **** *1** **** **** **** ****
1062 map(0x080000, 0x0bffff).rom().region("maincpu", 0x40000).mirror(0xF00000);// xxxx 10** **** **** **** ****
1063 }
1064
iqunlimz_rambank_map(address_map & map)1065 void iqunlimz_state::iqunlimz_rambank_map(address_map &map)
1066 {
1067 map.unmap_value_high();
1068 map(0x0000, 0x3ffff).ram().region("vram", 0);
1069 }
1070
iqunlimz_io(address_map & map)1071 void iqunlimz_state::iqunlimz_io(address_map &map)
1072 {
1073 map.unmap_value_high();
1074 map.global_mask(0xff);
1075 map(0x00, 0x01).rw(FUNC(iqunlimz_state::common_rom_bank_r), FUNC(iqunlimz_state::common_rom_bank_w)).mirror(0x06);
1076 map(0x08, 0x08).rw(FUNC(iqunlimz_state::common_ram_bank_r), FUNC(iqunlimz_state::common_ram_bank_w)).mirror(0x07);
1077 map(0x10, 0x17).w(FUNC(iqunlimz_state::socrates_sound_w)).mirror(0x08);
1078 map(0x20, 0x21).w(FUNC(iqunlimz_state::socrates_scroll_w)).mirror(0x0E);
1079 // 30: writes an incrementing value here, once per keypress?
1080 // 40: some sort of serial select/reset or enable, related to 0x60
1081 map(0x50, 0x51).rw(FUNC(iqunlimz_state::keyboard_buffer_read), FUNC(iqunlimz_state::keyboard_buffer_update)).mirror(0xE);
1082 // 60: some sort of serial read/write port, related to 0x40
1083 map(0x70, 0x73).rw(FUNC(iqunlimz_state::video_regs_r), FUNC(iqunlimz_state::video_regs_w)).mirror(0x0C);
1084 map(0x80, 0x81).nopw(); // LCD
1085 map(0xb1, 0xb1).nopw();
1086 map(0xa0, 0xa0).r(FUNC(iqunlimz_state::status_r)).mirror(0x0F);
1087 map(0xe0, 0xe7).w(FUNC(iqunlimz_state::colors_w)).mirror(0x08);
1088 }
1089
1090
1091
1092 /******************************************************************************
1093 Input Ports
1094 ******************************************************************************/
1095
1096 /* socrates keyboard codes:
1097 keycode low
1098 | keycode high
1099 | | key name
1100 00 01 No key pressed
1101 // pads on the sides of the kb; this acts like a giant bitfield, both dpads/buttons can send data at once
1102 00 81 left dpad right
1103 00 82 left dpad up
1104 00 84 left dpad left
1105 00 88 left dpad down
1106 01 80 right dpad down
1107 02 80 right dpad left
1108 04 80 right dpad up
1109 08 80 right dpad right
1110 10 80 left red button
1111 20 80 right red button
1112 // top row (right to left)
1113 44 82 ENTER
1114 44 83 MENU
1115 44 84 ANSWER
1116 44 85 HELP
1117 44 86 ERASE
1118 44 87 divide_sign
1119 44 88 multiply_sign
1120 44 89 minus_sign
1121 44 80 plus_sign
1122 //second row (right to left)
1123 43 81 0
1124 43 82 9
1125 43 83 8
1126 43 84 7
1127 43 85 6
1128 43 86 5
1129 43 87 4
1130 43 88 3
1131 43 89 2
1132 43 80 1
1133 // third row (right to left)
1134 42 82 I/La
1135 42 83 H/So
1136 42 84 G/Fa
1137 42 85 F/Mi
1138 42 86 E/Re
1139 42 87 D/Do
1140 42 88 C/Ti.
1141 42 89 B/La.
1142 42 80 A/So.
1143 42 81 hyphen/period
1144 // fourth row (right to left)
1145 41 81 S
1146 41 82 R
1147 41 83 Q/NEW
1148 41 84 P/PLAY
1149 41 85 O/PAUSE
1150 41 86 N/Fa`
1151 41 87 M/Mi`
1152 41 88 L/Re`
1153 41 89 K/Do`
1154 41 80 J/Ti
1155 // fifth row (right to left)
1156 40 82 SPACE
1157 40 83 Z
1158 40 84 Y
1159 40 85 X
1160 40 86 W
1161 40 87 V
1162 40 88 U
1163 40 89 T
1164 50 80 SHIFT
1165 // socrates mouse pad (separate from keyboard)
1166 8x 8y mouse movement
1167 x: down = 1 (small) through 7 (large), up = 8 (small) through F (large)
1168 y: right = 1 (small) through 7 (large), left = 8 (small) through F (large)
1169 90 80 right click
1170 A0 80 left click
1171 B0 80 both buttons click
1172 90 81 right click (mouse movement in queue, will be in regs after next latch clear)
1173 A0 81 left click (mouse movement in queue, will be in regs after next latch clear)
1174 B0 81 both buttons click (mouse movement in queue, will be in regs after next latch clear)
1175 // socrates touch pad
1176 // unknown yet, but probably uses the 60/70/c0/d0/e0/f0 low reg vals
1177 */
1178 static INPUT_PORTS_START( socrates )
1179
1180 PORT_START("IN5") // joypad keys
PORT_CODE(KEYCODE_6_PAD)1181 PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) PORT_NAME("Left D-pad Right") // 00 81
1182 PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) PORT_NAME("Left D-pad Up") // 00 82
1183 PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) PORT_NAME("Left D-pad Left") // 00 84
1184 PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) PORT_NAME("Left D-pad Down") // 00 88
1185 PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_NAME("Right D-pad Down") // 01 80
1186 PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_NAME("Right D-pad Left") // 02 80
1187 PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_NAME("Right D-pad Up") // 04 80
1188 PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_NAME("Right D-pad Right") // 08 80
1189 PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) PORT_NAME("Left D-pad Button") // 10 80
1190 PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RALT) PORT_CHAR(UCHAR_MAMEKEY(RALT)) PORT_NAME("Right D-pad Button") // 20 80
1191 PORT_BIT(0xfc00, IP_ACTIVE_HIGH, IPT_UNUSED)
1192 /* alt w/left and right keypad keys swapped
1193 PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_NAME("Left D-pad Right") // 00 81
1194 PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_NAME("Left D-pad Up") // 00 82
1195 PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_NAME("Left D-pad Left") // 00 84
1196 PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_NAME("Left D-pad Down") // 00 88
1197 PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) PORT_NAME("Right D-pad Down") // 01 80
1198 PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) PORT_NAME("Right D-pad Left") // 02 80
1199 PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) PORT_NAME("Right D-pad Up") // 04 80
1200 PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) PORT_NAME("Right D-pad Right") // 08 80
1201 PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RALT) PORT_CHAR(UCHAR_MAMEKEY(RALT)) PORT_NAME("Left D-pad Button") // 10 80
1202 PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) PORT_NAME("Right D-pad Button") // 20 80
1203 PORT_BIT(0xfc00, IP_ACTIVE_HIGH, IPT_UNUSED)
1204 */
1205
1206 PORT_START("IN6") // lowest 'row' (technically the shift key is on the 5th row but it has its own keycode)
1207 PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PORT_NAME("SHIFT") // 5x xx
1208 PORT_BIT(0xfffe, IP_ACTIVE_HIGH, IPT_UNUSED)
1209
1210 PORT_START("IN0") // 5th row
1211 PORT_BIT(0x0003, IP_ACTIVE_HIGH, IPT_UNUSED) // 40 80 and 40 81
1212 PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_NAME("SPACE") // 40 82
1213 PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_NAME("Z") // 40 83
1214 PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_NAME("Y") // 40 84
1215 PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_NAME("X") // 40 85
1216 PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_NAME("W") // 40 86
1217 PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_NAME("V") // 40 87
1218 PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_NAME("U") // 40 88
1219 PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_NAME("T") // 40 89
1220 PORT_BIT(0xfc00, IP_ACTIVE_HIGH, IPT_UNUSED)
1221
1222 PORT_START("IN1") // 4th row
1223 PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_NAME("J/Ti") // 41 80
1224 PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_NAME("S") // 41 81
1225 PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_NAME("R") // 41 82
1226 PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_NAME("Q/NEW") // 41 83
1227 PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_NAME("P/PLAY") // 41 84
1228 PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_NAME("O/PAUSE") // 41 85
1229 PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_NAME("N/Fa'") // 41 86
1230 PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_NAME("M/Mi'") // 41 87
1231 PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_NAME("L/Re'") // 41 88
1232 PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_NAME("K/Do'") // 41 89
1233 PORT_BIT(0xfc00, IP_ACTIVE_HIGH, IPT_UNUSED)
1234
1235 PORT_START("IN2") // 3rd row
1236 PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_NAME("A/So.") // 42 80
1237 PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('-') PORT_NAME("-/.") // 42 81
1238 PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_NAME("I/La") // 42 82
1239 PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_NAME("H/So") // 42 83
1240 PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_NAME("G/Fa") // 42 84
1241 PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_NAME("F/Mi") // 42 85
1242 PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_NAME("E/Re") // 42 86
1243 PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_NAME("D/Do") // 42 87
1244 PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_NAME("C/Ti.") // 42 88
1245 PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_NAME("B/La.") // 42 89
1246 PORT_BIT(0xfc00, IP_ACTIVE_HIGH, IPT_UNUSED)
1247
1248 PORT_START("IN3") // 2nd row
1249 PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_NAME("1") // 43 80
1250 PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_NAME("0") // 43 81
1251 PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_NAME("9") // 43 82
1252 PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_NAME("8") // 43 83
1253 PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_NAME("7") // 43 84
1254 PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_NAME("6") // 43 85
1255 PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_NAME("5") // 43 86
1256 PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_NAME("4") // 43 87
1257 PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_NAME("3") // 43 88
1258 PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_NAME("2") // 43 89
1259 PORT_BIT(0xfc00, IP_ACTIVE_HIGH, IPT_UNUSED)
1260
1261 PORT_START("IN4") // 1st row
1262 PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('+') PORT_NAME("+") // 44 80
1263 PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_UNUSED) // 44 81
1264 PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_NAME("ENTER") // 44 82
1265 PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(HOME)) PORT_NAME("MENU") // 44 83
1266 PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_PGUP) PORT_CHAR(UCHAR_MAMEKEY(PGUP)) PORT_NAME("ANSWER") // 44 84
1267 PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_PGDN) PORT_CHAR(UCHAR_MAMEKEY(PGDN)) PORT_NAME("HELP") // 44 85
1268 PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_NAME("ERASE") // 44 86
1269 PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_NAME("/") // 44 87
1270 PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('*') PORT_NAME("*") // 44 88
1271 PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_NAME("-") // 44 89
1272 PORT_BIT(0xfc00, IP_ACTIVE_HIGH, IPT_UNUSED)
1273
1274 // mouse goes here
1275 INPUT_PORTS_END
1276
1277
1278 static INPUT_PORTS_START( iqunlimz )
1279 PORT_START( "IN0" )
1280 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_LSHIFT ) PORT_CODE( KEYCODE_RSHIFT )
1281 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_LCONTROL ) PORT_CODE( KEYCODE_RCONTROL )
1282 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_LALT ) PORT_CODE( KEYCODE_RALT )
1283 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_CAPSLOCK )
1284 PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNUSED )
1285
1286 PORT_START( "IN1" )
1287 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_N ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x10 )
1288 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_M ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x11 )
1289 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_COMMA ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x12 )
1290 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_B ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x13 )
1291 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_C ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x14 )
1292 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_Z ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x15 )
1293 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_V ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x16 )
1294 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_X ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x17 )
1295
1296 PORT_START( "IN2" )
1297 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) // PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x20 )
1298 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_2_PAD ) PORT_CODE( KEYCODE_DOWN ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x21 )
1299 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_5_PAD ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x22 )
1300 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_DEL_PAD ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x23 )
1301 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_SLASH_PAD ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x24 )
1302 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_8_PAD ) PORT_CODE( KEYCODE_UP ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x25 )
1303 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_ASTERISK ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x26 )
1304 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_7_PAD ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x27 )
1305
1306 PORT_START( "IN3" )
1307 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) // PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x30 )
1308 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) // PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x31 )
1309 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) // PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x32 )
1310 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) // PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x33 )
1311 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_F1 ) PORT_NAME( "Help" ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x34 )
1312 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_9 ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x35 )
1313 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_BACKSPACE ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x36 )
1314 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_0 ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x37 )
1315
1316 PORT_START( "IN4" )
1317 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_H ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x40 )
1318 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_J ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x41 )
1319 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_K ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x42 )
1320 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_G ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x43 )
1321 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_D ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x44 )
1322 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_A ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x45 )
1323 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_F ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x46 )
1324 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_S ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x47 )
1325
1326 PORT_START( "IN5" )
1327 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) // PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x50 )
1328 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) // PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x51 )
1329 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) // PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x52 )
1330 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) // PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x53 )
1331 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_EQUALS ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x54 )
1332 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_O ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x55 )
1333 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_NUMLOCK ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x56 )
1334 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_P ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x57 )
1335
1336 PORT_START( "IN6" )
1337 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_Y ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x60 )
1338 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_U ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x61 )
1339 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_I ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x62 )
1340 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_T ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x63 )
1341 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_E ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x64 )
1342 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_Q ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x65 )
1343 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_R ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x66 )
1344 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_W ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x67 )
1345
1346 PORT_START( "IN7" )
1347 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_MINUS ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x70 )
1348 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_SLASH ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x71 )
1349 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) // PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x72 )
1350 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_STOP ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x73 )
1351 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_QUOTE ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x74 )
1352 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_L ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x75 )
1353 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_ENTER ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x76 )
1354 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_COLON ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x77 )
1355
1356 PORT_START( "IN8" )
1357 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_6 ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x80 )
1358 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_7 ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x81 )
1359 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_8 ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x82 )
1360 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_5 ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x83 )
1361 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_3 ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x84 )
1362 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_1 ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x85 )
1363 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_4 ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x86 )
1364 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_2 ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x87 )
1365
1366 PORT_START( "IN9" )
1367 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_4_PAD ) PORT_CODE( KEYCODE_LEFT ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x90 )
1368 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_3_PAD ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x91 )
1369 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_6_PAD ) PORT_CODE( KEYCODE_RIGHT ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x92 )
1370 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_PLUS_PAD ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x93 )
1371 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_0_PAD ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x94 )
1372 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_9_PAD ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x95 )
1373 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_MINUS_PAD ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x96 )
1374 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_1_PAD ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0x97 )
1375
1376 PORT_START( "INA" )
1377 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) // PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0xa0 )
1378 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) // PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0xa1 )
1379 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) // PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0xa2 )
1380 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) // PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0xa3 )
1381 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_F2 ) PORT_NAME("Answer") PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0xa4 )
1382 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_ESC ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0xa5 )
1383 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_SPACE ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0xa6 )
1384 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE( KEYCODE_TAB ) PORT_CHANGED_MEMBER( DEVICE_SELF, iqunlimz_state, send_input, 0xa7 )
1385 INPUT_PORTS_END
1386
1387 /******************************************************************************
1388 Machine Drivers
1389 ******************************************************************************/
1390 TIMER_CALLBACK_MEMBER(socrates_state::clear_irq_cb)
1391 {
1392 m_maincpu->set_input_line(0, CLEAR_LINE);
1393 }
1394
INTERRUPT_GEN_MEMBER(socrates_state::assert_irq)1395 INTERRUPT_GEN_MEMBER(socrates_state::assert_irq)
1396 {
1397 device.execute().set_input_line(0, ASSERT_LINE);
1398 m_clear_irq_timer->adjust(m_maincpu->cycles_to_attotime(44));
1399 // 44 is a complete and total guess, need to properly measure how many clocks/microseconds the int line is high for.
1400 }
1401
TIMER_CALLBACK_MEMBER(socrates_state::kbmcu_sim_cb)1402 TIMER_CALLBACK_MEMBER(socrates_state::kbmcu_sim_cb)
1403 {
1404 // timer rate is a massive guess; we're assuming the mcu runs at the same speed as the cpu does,
1405 // and the refresh rate depends on instructions per loop of mcu, which we've randomly guessed is 60 cycles.
1406 m_kbmcu_sim_timer->adjust(m_maincpu->cycles_to_attotime(3000));
1407 /// TODO: dump the mcus and get rid of this...
1408 if (m_kbmcu_type == 0)
1409 {
1410 // socrates keyboard MCU simulation: if a keyboard key is pressed, enqueue it into the fifo as needed
1411 uint16_t keyvalue = 0;
1412 // check for joypad buttons
1413 keyvalue = m_kbdrow[5]->read();
1414 if (keyvalue == 0) // if joypad wasn't pushed...
1415 {
1416 // next check for mouse movement.
1417 /// TODO: this isn't written yet
1418 // next check for basic keyboard "4x xx" stuff
1419 // check if shift is down
1420 keyvalue = (m_kbdrow[6]->read())?0x500:0;
1421 bool keyfound = false;
1422 // find what row and bit we're on...
1423 for (int8_t row = 4; row>=0; row--)
1424 {
1425 uint16_t tempkey = m_kbdrow[row]->read();
1426 if (tempkey != 0)
1427 {
1428 for (int8_t powerof2 = 9; ((powerof2 >= 0) && (keyfound == false)); powerof2--) // continue until we find the first key only
1429 {
1430 if ((tempkey&(1<<powerof2)) == (1<<powerof2))
1431 {
1432 keyvalue |= (0x400 | (row<<4) | powerof2);
1433 keyfound = true;
1434 }
1435 }
1436 }
1437 }
1438 }
1439 if (keyvalue != 0) // if a key is down...
1440 {
1441 if (keyvalue == m_oldkeyvalue) // and its the same key as it was the last run...
1442 {
1443 if (m_keyrepeat_holdoffcounter > 0) // and the key repeat holdoff counter is > 0...
1444 {
1445 m_keyrepeat_holdoffcounter--; // decrement the holdoff counter
1446 }
1447 else // the key repeat holdoff counter is zero
1448 {
1449 kbmcu_sim_fifo_enqueue(0x1000|keyvalue); // queue the key with bit 12 set as a flag that this is a repeat
1450 m_keyrepeat_holdoffcounter += KEYREPEAT_REPEAT; // increment the holdoff counter by the repeat value
1451 }
1452 }
1453 else // it isn't the same key as it was the last run
1454 {
1455 kbmcu_sim_fifo_enqueue(keyvalue); // queue the key
1456 m_keyrepeat_holdoffcounter = KEYREPEAT_HOLDOFF; // reset the holdoff counter
1457 m_oldkeyvalue = keyvalue; // set this new key to be the 'previous key'
1458 }
1459 }
1460 else // keyvalue is zero, reset the holdoff counter
1461 {
1462 m_keyrepeat_holdoffcounter = KEYREPEAT_HOLDOFF;
1463 m_oldkeyvalue = keyvalue; // set this new key to be the 'previous key'
1464 }
1465 }
1466 //else if (m_kbmcu_type == 1) // this is currently hacked around by the input system so no code here
1467 //{
1468 //}
1469
1470 if ((m_kb_spi_request) && (m_kb_queue.count > 0)) // if the console requested data from the MCU AND the MCU has data to send...
1471 {
1472 uint16_t tempbuffer = 0;
1473 m_kb_spi_request = false;
1474 tempbuffer = kbmcu_sim_fifo_peek();
1475 if (tempbuffer&0x1000) // repeat bit was set
1476 {
1477 kbmcu_sim_fifo_head_clear(); // clear the head byte of the fifo, but leave it enqueued so it is returned next time. socrates wants this...
1478 }
1479 else tempbuffer = kbmcu_sim_fifo_dequeue();
1480 m_kb_spi_buffer = ((tempbuffer&0xFF0)<<4)|(tempbuffer&0xF)|0x80;
1481 }
1482 }
1483
socrates(machine_config & config)1484 void socrates_state::socrates(machine_config &config)
1485 {
1486 /* basic machine hardware */
1487 Z80(config, m_maincpu, XTAL(21'477'272)/6); /* Toshiba TMPZ84C00AP @ 3.579545 MHz, verified, xtal is divided by 6 */
1488 m_maincpu->set_addrmap(AS_PROGRAM, &socrates_state::socrates_mem);
1489 m_maincpu->set_addrmap(AS_IO, &socrates_state::socrates_io);
1490 m_maincpu->set_vblank_int("screen", FUNC(socrates_state::assert_irq));
1491 config.set_maximum_quantum(attotime::from_hz(60));
1492
1493 ADDRESS_MAP_BANK(config, "rombank1").set_map(&socrates_state::socrates_rombank_map).set_options(ENDIANNESS_LITTLE, 8, 32, 0x4000);
1494 ADDRESS_MAP_BANK(config, "rambank1").set_map(&socrates_state::socrates_rambank_map).set_options(ENDIANNESS_LITTLE, 8, 32, 0x4000);
1495 ADDRESS_MAP_BANK(config, "rambank2").set_map(&socrates_state::socrates_rambank_map).set_options(ENDIANNESS_LITTLE, 8, 32, 0x4000);
1496
1497 /* video hardware */
1498 SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
1499 m_screen->set_refresh_hz(60);
1500 m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
1501 m_screen->set_size(264, 228); // technically the screen size is 256x228 but super painter abuses what I suspect is a hardware bug to display repeated pixels of the very last pixel beyond this horizontal space, well into hblank
1502 m_screen->set_visarea(0, 263, 0, 219); // the last few rows are usually cut off by the screen bottom but are indeed displayed if you mess with v-hold
1503 m_screen->set_screen_update(FUNC(socrates_state::screen_update_socrates));
1504 m_screen->set_palette("palette");
1505
1506 PALETTE(config, "palette", FUNC(socrates_state::socrates_palette), 256);
1507
1508 /* sound hardware */
1509 SPEAKER(config, "mono").front_center();
1510 SOCRATES_SOUND(config, m_sound, XTAL(21'477'272)/(512+256)).add_route(ALL_OUTPUTS, "mono", 0.25); // this is correct, as strange as it sounds.
1511
1512 GENERIC_CARTSLOT(config, m_cart, generic_plain_slot, "socrates_cart");
1513
1514 /* Software lists */
1515 SOFTWARE_LIST(config, "cart_list").set_original("socrates");
1516 }
1517
socrates_pal(machine_config & config)1518 void socrates_state::socrates_pal(machine_config &config)
1519 {
1520 socrates(config);
1521
1522 m_maincpu->set_clock(XTAL(26'601'712)/8); // XTAL verified, divider NOT verified; this is a later ASIC so the divider may be different
1523
1524 config.set_maximum_quantum(attotime::from_hz(50));
1525
1526 m_screen->set_refresh_hz(50);
1527 m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate
1528 m_screen->set_size(264, 238); // technically the screen size is 256x228 but super painter abuses what I suspect is a hardware bug to display repeated pixels of the very last pixel beyond this horizontal space, well into hblank
1529 m_screen->set_visarea(0, 263, 0, 229); // the last few rows are usually cut off by the screen bottom but are indeed displayed if you mess with v-hold
1530 m_screen->set_screen_update(FUNC(socrates_state::screen_update_socrates));
1531
1532 m_sound->set_clock(XTAL(26'601'712)/(512+256)); // this is correct, as strange as it sounds.
1533 }
1534
vpainter_pal(machine_config & config)1535 void socrates_state::vpainter_pal(machine_config &config)
1536 {
1537 socrates_pal(config);
1538
1539 config.device_remove("cartslot");
1540 config.device_remove("cart_list");
1541 }
1542
iqunlimz(machine_config & config)1543 void iqunlimz_state::iqunlimz(machine_config &config)
1544 {
1545 /* basic machine hardware */
1546 Z80(config, m_maincpu, XTAL(4'000'000)); /* not accurate */
1547 m_maincpu->set_addrmap(AS_PROGRAM, &iqunlimz_state::iqunlimz_mem);
1548 m_maincpu->set_addrmap(AS_IO, &iqunlimz_state::iqunlimz_io);
1549 m_maincpu->set_vblank_int("screen", FUNC(iqunlimz_state::assert_irq));
1550
1551 ADDRESS_MAP_BANK(config, "rombank1").set_map(&iqunlimz_state::iqunlimz_rombank_map).set_options(ENDIANNESS_LITTLE, 8, 32, 0x4000);
1552 ADDRESS_MAP_BANK(config, "rombank2").set_map(&iqunlimz_state::iqunlimz_rombank_map).set_options(ENDIANNESS_LITTLE, 8, 32, 0x4000);
1553 ADDRESS_MAP_BANK(config, "rambank1").set_map(&iqunlimz_state::iqunlimz_rambank_map).set_options(ENDIANNESS_LITTLE, 8, 32, 0x4000);
1554 ADDRESS_MAP_BANK(config, "rambank2").set_map(&iqunlimz_state::iqunlimz_rambank_map).set_options(ENDIANNESS_LITTLE, 8, 32, 0x4000);
1555
1556 /* video hardware */
1557 SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
1558 m_screen->set_refresh_hz(60);
1559 m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
1560 m_screen->set_screen_update(FUNC(iqunlimz_state::screen_update));
1561 m_screen->set_size(256, 224);
1562 m_screen->set_visarea(0, 256-1, 0, 224-1);
1563 m_screen->set_palette("palette");
1564
1565 PALETTE(config, "palette", FUNC(iqunlimz_state::socrates_palette), 256);
1566
1567 /* sound hardware */
1568 SPEAKER(config, "mono").front_center();
1569 SOCRATES_SOUND(config, m_sound, XTAL(21'477'272)/(512+256)).add_route(ALL_OUTPUTS, "mono", 0.25);
1570
1571 GENERIC_CARTSLOT(config, m_cart, generic_plain_slot, nullptr);
1572 }
1573
1574 /******************************************************************************
1575 ROM Definitions
1576 ******************************************************************************/
1577
1578 ROM_START(socrates)
1579 ROM_REGION(0x400000, "maincpu", ROMREGION_ERASEVAL(0xF3)) /* can technically address 4mb of rom via bankswitching; open bus area reads as 0xF3 on fluke */
1580 /* Socrates English (same ROM for NTSC and PAL) */
1581 /* All cart ROMs are 28 pin 23c1000/tc531000 128Kx8 ROMs */
1582 /* Cart port pinout:
1583 (looking into end of disk-shaped cartridge with label/top side pointing to the right)
1584 A15 -> 19 18 -- VCC
1585 A14 -> 20 17 <- A16
1586 A13 -> 21 16 <- A12
1587 A8 -> 22 15 <- A7
1588 A9 -> 23 14 <- A6
1589 A11 -> 24 13 <- A5
1590 A3 -> 25 12 <- A4
1591 A2 -> 26 11 <- A10
1592 D7 <- 27 10 <- A1
1593 D6 <- 28 9 <- A0
1594 D5 <- 29 8 -> D0
1595 D4 <- 30 7 -> D1
1596 D3 <- 31 6 -> D2
1597 ? ?? 32 5 ?? ?
1598 A17 -> 33 4 ?? ?
1599 ? ?? 34 3 ?? ?
1600 /CE -> 35 2 ?? ?
1601 GND -- 36 1 -- GND
1602 Note that a17 goes to what would be pin 2 on a rom chip if a 32 pin rom were installed, which is not the case. (pins 1, 31 and 32 would be tied to vcc)
1603 It is likely that at least one of the 6 unknown lines is R/W from the z80, and another may be phi1/m1/clock etc to allow for ram to live in cart space
1604
1605 Cartridge check procedure by Socrates is, after screen init and check for speech synth,
1606 bankswitch to bank 0x10 (i.e. first 0x4000 of cart appears at 4000-7fff in z80 space),
1607 do following tests; if any tests fail, jump to 0x0015 (Socrates main menu)
1608 * read 0x7ff0(0x3ff0 in cart rom) and compare to 0xAA
1609 * read 0x7ff1(0x3ff1 in cart rom) and compare to 0x55
1610 * read 0x7ff2(0x3ff2 in cart rom) and compare to 0xE7
1611 * read 0x7ff3(0x3ff3 in cart rom) and compare to 0x18
1612 if all tests passed, jump to 0x4000 (0x0000 in cart rom)
1613 */
1614 ROM_LOAD("27-00817-000-000.u1", 0x00000, 0x40000, CRC(80f5aa20) SHA1(4fd1ff7f78b5dd2582d5de6f30633e4e4f34ca8f)) // Label: "(Vtech) 27-00817-000-000 // (C)1987 VIDEO TECHNOLOGY // 8811 D"
1615
1616 ROM_REGION(0x10000, "vram", ROMREGION_ERASEFF) /* fill with ff, driver_init changes this to the 'correct' startup pattern */
1617
1618 ROM_REGION(0x800, "kbmcu", ROMREGION_ERASEFF)
1619 ROM_LOAD("tmp42c40p1844.u6", 0x000, 0x200, NO_DUMP) /* keyboard IR decoder MCU */
1620
1621 /* english speech cart has a green QC sticker */
1622 ROM_REGION(0x2000, "speechint", ROMREGION_ERASE00) // speech data inside of the speech chip; fill with 00, if no speech cart is present socrates will see this
1623 ROM_LOAD_OPTIONAL("speech_eng_internal.bin", 0x0000, 0x2000, CRC(edc1fb3f) SHA1(78b4631fc3b1c038e14911047f9edd6c4e8bae58)) // 8k on the speech chip itself
1624
1625 ROM_REGION(0x10000, "speechext", ROMREGION_ERASE00) // speech serial modules outside of the speech chip but still on speech cart
1626 ROM_LOAD_OPTIONAL("speech_eng_vsm1.bin", 0x0000, 0x4000, CRC(888e3ddd) SHA1(33af6a21ba6d826071c9d48557b1c9012752570b)) // 16k in serial rom
1627 ROM_LOAD_OPTIONAL("speech_eng_vsm2.bin", 0x4000, 0x4000, CRC(de4ac89d) SHA1(3dfa853b02df756a9b72def94a39310992ee11c7)) // 16k in serial rom
1628 ROM_LOAD_OPTIONAL("speech_eng_vsm3.bin", 0x8000, 0x4000, CRC(972384aa) SHA1(ffcb1d633ca6bffc7f481ec505da447e5b847f16)) // 16k in serial rom
1629 ROM_FILL(0xC000, 0x4000, 0xff) // last vsm isn't present, FF fill
1630 ROM_END
1631
1632 ROM_START(socratfc)
1633 ROM_REGION(0x80000, "maincpu", ROMREGION_ERASEVAL(0xF3))
1634 /* Socrates SAITOUT (French Canadian) NTSC */
1635 ROM_LOAD("27-00884-001-000.u1", 0x00000, 0x40000, CRC(042d9d21) SHA1(9ffc67b2721683b2536727d0592798fbc4d061cb)) // Label: "(Vtech) 27-00884-001-000 // (C)1988 VIDEO TECHNOLOGY // 8911 D"
1636
1637 ROM_REGION(0x10000, "vram", ROMREGION_ERASEFF) /* fill with ff, driver_init changes this to the 'correct' startup pattern */
1638
1639 ROM_REGION(0x800, "kbmcu", ROMREGION_ERASEFF)
1640 ROM_LOAD("tmp42c40p1844.u6", 0x000, 0x200, NO_DUMP) /* keyboard IR decoder MCU */
1641
1642 ROM_REGION(0x2000, "speechint", ROMREGION_ERASE00) // speech data inside of the speech chip; fill with 00, if no speech cart is present socrates will see this
1643 ROM_LOAD_OPTIONAL("speech_fra_internal.bin", 0x0000, 0x2000, NO_DUMP)
1644
1645 ROM_REGION(0x10000, "speechext", ROMREGION_ERASE00) // speech serial modules outside of the speech chip but still on speech cart
1646 ROM_LOAD_OPTIONAL("speech_fra_vsm1.bin", 0x0000, 0x4000, NO_DUMP) // 16k in serial rom
1647 ROM_LOAD_OPTIONAL("speech_fra_vsm2.bin", 0x4000, 0x4000, NO_DUMP) // 16k in serial rom
1648 ROM_LOAD_OPTIONAL("speech_fra_vsm3.bin", 0x8000, 0x4000, NO_DUMP) // 16k in serial rom
1649 ROM_FILL(0xC000, 0x4000, 0xff) // last vsm isn't present, FF fill
1650 ROM_END
1651
1652 ROM_START(profweis)
1653 ROM_REGION(0x80000, "maincpu", ROMREGION_ERASEVAL(0xF3))
1654 /* Yeno Professor Weiss-Alles (German PAL) */
1655 ROM_SYSTEM_BIOS(0, "89", "1989")
1656 ROMX_LOAD("lh53216d.u1", 0x00000, 0x40000, CRC(6e801762) SHA1(b80574a3abacf18133dacb9d3a8d9e2916730423), ROM_BIOS(0)) // Label: "(Vtech) LH53216D // (C)1989 VIDEO TECHNOLOGY // 9119 D"
1657 ROM_SYSTEM_BIOS(1, "88", "1988")
1658 ROMX_LOAD("27-00885-000-000.u1", 0x00000, 0x40000, CRC(fcaf8850) SHA1(a99011ee6a1ef63461c00d062278951252f117db), ROM_BIOS(1)) // Label: "(Vtech) 27-00885-000-000 // (C)1988 VIDEO TECHNOLOGY // 8844 D"
1659
1660 ROM_REGION(0x10000, "vram", ROMREGION_ERASEFF) /* fill with ff, driver_init changes this to the 'correct' startup pattern */
1661
1662 ROM_REGION(0x800, "kbmcu", ROMREGION_ERASEFF)
1663 ROM_LOAD("tmp42c40p1844.u6", 0x000, 0x200, NO_DUMP) /* keyboard IR decoder MCU */
1664
1665 ROM_REGION(0x2000, "speechint", ROMREGION_ERASE00) // speech data inside of the speech chip; fill with 00, if no speech cart is present socrates will see this
1666 ROM_LOAD_OPTIONAL("speech_ger_internal.bin", 0x0000, 0x2000, CRC(5ff0fdc6) SHA1(8ef128561a846762a20e3fe9513a4a22aaadc7f6))
1667
1668 ROM_REGION(0x10000, "speechext", ROMREGION_ERASE00) // speech serial modules outside of the speech chip but still on speech cart
1669 ROM_LOAD_OPTIONAL("speech_ger_vsm1.bin", 0x0000, 0x4000, CRC(a979a00b) SHA1(0290844619dbdf336757003aaab3ffd0a75b7ee9)) // 16k in serial rom
1670 ROM_FILL(0x4000, 0xc000, 0xff) // last 3 vsms aren't present, FF fill
1671 ROM_END
1672
1673 ROM_START( iqunlimz )
1674 ROM_REGION( 0x80000, "maincpu", 0 )
1675 ROM_LOAD( "vtech.bin", 0x000000, 0x080000, CRC(f100c8a7) SHA1(6ad2a8accae2dd5c5c46ae953eef33cdd1ea3cf9) )
1676
1677 ROM_REGION(0x1000, "kbmcu", ROMREGION_ERASEFF)
1678 ROM_LOAD("kbmcu.bin", 0x0000, 0x1000, NO_DUMP) /* keyboard reader MCU */
1679
1680 ROM_REGION( 0x40000, "vram", ROMREGION_ERASE )
1681 ROM_END
1682
1683 ROM_START( vpainter )
1684 ROM_REGION(0x80000, "maincpu", ROMREGION_ERASEVAL(0xF3))
1685 ROM_LOAD("lh531g02.u1", 0x00000, 0x20000, CRC(898defac) SHA1(8307e00b5ce3675ce71960e7cf2d1334197a1dce)) // Label: "(Vtech)LH531G02 // (C)1991 VIDEO TECHNOLOGY // 9211 D"
1686
1687 ROM_REGION(0x1000, "kbmcu", ROMREGION_ERASEFF)
1688 ROM_LOAD("tmp47c241nj408.u6", 0x0000, 0x1000, NO_DUMP) /* key/touchpad reader MCU */
1689
1690 ///TODO: get rid of these regions in the status_read function or make it socrates-specific
1691 ROM_REGION(0x2000, "speechint", ROMREGION_ERASE00) // doesn't exist? on vpainter, presumably reads as all zeroes
1692 ROM_REGION(0x10000, "speechext", ROMREGION_ERASE00) // doesn't exist? on vpainter, presumably reads as all zeroes
1693
1694 ROM_REGION( 0x10000, "vram", ROMREGION_ERASE )
1695 ROM_END
1696
1697 /******************************************************************************
1698 Drivers
1699 ******************************************************************************/
1700
1701 // YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS
1702 COMP( 1988, socrates, 0, 0, socrates, socrates, socrates_state, init_socrates, "Video Technology", "Socrates Educational Video System", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // English, no title copyright, same ROM for NTSC and PAL
1703 COMP( 1988, socratfc, socrates, 0, socrates, socrates, socrates_state, init_socrates, "Video Technology", "Socrates SAITOUT", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // French Canandian NTSC, 1988 title copyright
1704 // Yeno Professeur Saitout (French SECAM) matches the Socrates SAITOUT dump (same ROM 27-00884-001-000)
1705 COMP( 1988, profweis, socrates, 0, socrates_pal, socrates, socrates_state, init_socrates, "Video Technology / Yeno", "Professor Weiss-Alles", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // German PAL, 1988 title copyright
1706 // ? goes here (Spanish PAL)
1707
1708 COMP( 1991, iqunlimz, 0, 0, iqunlimz, iqunlimz, iqunlimz_state, init_iqunlimz, "Video Technology", "IQ Unlimited (Z80)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND )
1709
1710 COMP( 1991, vpainter, 0, 0, vpainter_pal, socrates, socrates_state, init_vpainter, "Video Technology", "Video Painter (PAL)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND )
1711 // Master Video Painter goes here
1712