mirror of
https://github.com/holub/mame
synced 2025-04-30 11:50:30 +03:00
socrates: reimplemented keyboard mcu hle as a separate timer-driven function, fixing issues with super painter and a few other games not recognizing keyboard input. Got rid of anonymous timers. Got rid of keyboard tagmap lookups. Added savestate support. [Lord Nightmare
This commit is contained in:
parent
be0bdba541
commit
3d98eefcf0
@ -13,16 +13,15 @@ TODO:
|
||||
apparently does away with the melody mode); the chip is running at
|
||||
800khz clock/10khz output with between 1 and 4 t6684F vsm roms
|
||||
attached; create a sound driver for this!
|
||||
* fix glitches with keyboard input (double keys still don't work, super painter letter entry still doesn't work)
|
||||
* hook up mouse
|
||||
* add waitstates for ram access (lack of this causes the system to run
|
||||
way too fast)
|
||||
This will require some probing with the LA and the fluke to figure out
|
||||
how many cycles the waitstates are for for rom/ram/etc access.
|
||||
* figure out what bit 6 of the status register actually does; is this an
|
||||
ir mcu flag?
|
||||
* keyboard IR decoder MCU is HLE'd for now, needs decap and cpu core (it
|
||||
is rather tms1000 or CIC-like iirc)
|
||||
ir mcu busy flag?
|
||||
* keyboard IR decoder MCU is HLE'd for now, needs decap and cpu core
|
||||
* iqunlimz keyboard MCU simulation does not handle key repeats
|
||||
|
||||
|
||||
Socrates Educational Video System
|
||||
@ -44,15 +43,15 @@ TODO:
|
||||
|
||||
Banked rom area (4000-7fff) bankswitching
|
||||
Bankswitching is achieved by writing to I/O port 0 (mirrored on 1-7)
|
||||
Bank ROM_REGION Contents
|
||||
0 0x00000 - 0x03fff System ROM page 0
|
||||
1 0x04000 - 0x07fff System ROM page 1
|
||||
2 0x08000 - 0x0bfff System ROM page 2
|
||||
Bank ROM_REGION Contents
|
||||
0 0x00000 - 0x03fff System ROM page 0
|
||||
1 0x04000 - 0x07fff System ROM page 1
|
||||
2 0x08000 - 0x0bfff System ROM page 2
|
||||
... etc ...
|
||||
E 0x38000 - 0x38fff System ROM page E
|
||||
F 0x3c000 - 0x3ffff System ROM page F
|
||||
10 0x40000 - 0x43fff Expansion Cartridge page 0 (cart ROM 0x0000-0x3fff)
|
||||
11 0x44000 - 0x47fff Expansion Cartridge page 1 (cart ROM 0x4000-0x7fff)
|
||||
E 0x38000 - 0x38fff System ROM page E
|
||||
F 0x3c000 - 0x3ffff System ROM page F
|
||||
10 0x40000 - 0x43fff Expansion Cartridge page 0 (cart ROM 0x0000-0x3fff)
|
||||
11 0x44000 - 0x47fff Expansion Cartridge page 1 (cart ROM 0x4000-0x7fff)
|
||||
... etc ...
|
||||
|
||||
Banked ram area (z80 0x8000-0xbfff window 0 and z80 0xc000-0xffff window 1)
|
||||
@ -99,6 +98,7 @@ class socrates_state : public driver_device
|
||||
public:
|
||||
enum
|
||||
{
|
||||
TIMER_KBMCU_SIM,
|
||||
TIMER_CLEAR_SPEECH,
|
||||
TIMER_CLEAR_IRQ
|
||||
};
|
||||
@ -114,7 +114,8 @@ public:
|
||||
m_rombank1(*this, "rombank1"),
|
||||
m_rombank2(*this, "rombank2"),
|
||||
m_rambank1(*this, "rambank1"),
|
||||
m_rambank2(*this, "rambank2")
|
||||
m_rambank2(*this, "rambank2"),
|
||||
m_kbdrow(*this, "IN%u", 0)
|
||||
{ }
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<socrates_snd_device> m_sound;
|
||||
@ -127,17 +128,18 @@ public:
|
||||
optional_device<address_map_bank_device> m_rombank2; // iqunlimz only
|
||||
required_device<address_map_bank_device> m_rambank1;
|
||||
required_device<address_map_bank_device> m_rambank2;
|
||||
optional_ioport_array<0xC> m_kbdrow;
|
||||
|
||||
rgb_t m_palette_val[256];
|
||||
|
||||
uint8_t m_data[8];
|
||||
uint8_t m_rom_bank[2];
|
||||
uint8_t m_ram_bank;
|
||||
uint16_t m_scroll_offset;
|
||||
uint8_t m_kb_latch_low[2];
|
||||
uint8_t m_kb_latch_high[2];
|
||||
uint8_t m_kb_latch_mouse;
|
||||
uint8_t m_kbmcu_rscount; // how many pokes the kbmcu has taken in the last frame
|
||||
uint16_t m_kb_spi_buffer;
|
||||
bool m_kb_spi_request;
|
||||
uint8_t m_kbmcu_type; // 0 for socrates, 1 for iqunlimz
|
||||
uint16_t m_oldkeyvalue; // previous key pressed
|
||||
uint16_t m_keyrepeat_holdoffcounter; // keyrepeat holdoff countdown
|
||||
uint8_t m_io40_latch; // what was last written to speech reg (for open bus)?
|
||||
uint8_t m_speech_running; // is speech synth talking?
|
||||
uint32_t m_speech_address; // address in speech space
|
||||
@ -151,36 +153,47 @@ public:
|
||||
DECLARE_WRITE8_MEMBER(common_ram_bank_w);
|
||||
DECLARE_READ8_MEMBER(socrates_cart_r);
|
||||
DECLARE_READ8_MEMBER(read_f3);
|
||||
DECLARE_WRITE8_MEMBER(kbmcu_strobe);
|
||||
DECLARE_WRITE8_MEMBER(kbmcu_reset);
|
||||
DECLARE_READ8_MEMBER(status_and_speech);
|
||||
DECLARE_WRITE8_MEMBER(speech_command);
|
||||
DECLARE_READ8_MEMBER(socrates_keyboard_low_r);
|
||||
DECLARE_READ8_MEMBER(socrates_keyboard_high_r);
|
||||
DECLARE_WRITE8_MEMBER(socrates_keyboard_clear);
|
||||
DECLARE_READ8_MEMBER(keyboard_buffer_read);
|
||||
DECLARE_WRITE8_MEMBER(keyboard_buffer_update);
|
||||
void kbmcu_sim_reset();
|
||||
void kbmcu_sim_fifo_enqueue(uint16_t data);
|
||||
uint16_t kbmcu_sim_fifo_dequeue();
|
||||
uint16_t kbmcu_sim_fifo_peek();
|
||||
void kbmcu_sim_fifo_head_clear();
|
||||
DECLARE_WRITE8_MEMBER(reset_speech);
|
||||
DECLARE_WRITE8_MEMBER(socrates_scroll_w);
|
||||
DECLARE_WRITE8_MEMBER(socrates_sound_w);
|
||||
DECLARE_DRIVER_INIT(socrates);
|
||||
DECLARE_DRIVER_INIT(iqunlimz);
|
||||
virtual void machine_reset() override;
|
||||
virtual void machine_start() override;
|
||||
virtual void video_start() override;
|
||||
DECLARE_PALETTE_INIT(socrates);
|
||||
uint32_t screen_update_socrates(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
INTERRUPT_GEN_MEMBER(assert_irq);
|
||||
TIMER_CALLBACK_MEMBER(kbmcu_sim_cb);
|
||||
TIMER_CALLBACK_MEMBER(clear_speech_cb);
|
||||
TIMER_CALLBACK_MEMBER(clear_irq_cb);
|
||||
void socrates_update_kb();
|
||||
void socrates_check_kb_latch();
|
||||
rgb_t socrates_create_color(uint8_t color);
|
||||
|
||||
protected:
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
emu_timer *m_kbmcu_sim_timer;
|
||||
emu_timer *m_clear_speech_timer;
|
||||
emu_timer *m_clear_irq_timer;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t buffer[8];
|
||||
int head;
|
||||
int tail;
|
||||
uint16_t buffer[8];
|
||||
uint8_t head;
|
||||
uint8_t tail;
|
||||
uint8_t count;
|
||||
} m_kb_queue;
|
||||
|
||||
protected:
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
};
|
||||
|
||||
|
||||
@ -193,8 +206,6 @@ public:
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
DECLARE_WRITE8_MEMBER( colors_w );
|
||||
DECLARE_READ8_MEMBER( keyboard_r );
|
||||
DECLARE_WRITE8_MEMBER( keyboard_clear );
|
||||
DECLARE_READ8_MEMBER( video_regs_r );
|
||||
DECLARE_WRITE8_MEMBER( video_regs_w );
|
||||
DECLARE_READ8_MEMBER( status_r );
|
||||
@ -212,81 +223,130 @@ private:
|
||||
|
||||
/* Defines */
|
||||
|
||||
// number of mcu "full cycles" before key repeat
|
||||
#define KEYREPEAT_HOLDOFF 0x1f
|
||||
// number of mcu "full cycles" between key repeats
|
||||
#define KEYREPEAT_REPEAT 1
|
||||
|
||||
/* Components */
|
||||
|
||||
/* Devices */
|
||||
|
||||
void socrates_state::socrates_update_kb( )
|
||||
/******************************************************************************
|
||||
|
||||
Socrates Keyboard MCU simulation
|
||||
|
||||
*******************************************************************************
|
||||
the tmp50c40 MCU seems to have an 8? word, 12 bit wide internal fifo, which is fed by IR decoded from the
|
||||
remote keyboard. The socrates reads this data out via SPI? by asserting a /cs? bit when keyboard_buffer_update
|
||||
is written to.
|
||||
the bits are returned in two registers, handled by keyboard_buffer_read
|
||||
bits are read out in the following order:
|
||||
offset0 offset1
|
||||
76543210 76543210
|
||||
HHHHMMMM F000LLLL
|
||||
where HHHH is the high nybble, MMMM is the middle nybble, LLLL is the low nybble
|
||||
and F is the fifo status, 1 if the fifo had any data in it at all, and 0 if not
|
||||
if the fifo is empty, the mcu shifts out nothing, and the spi reg holds 00000000 00000001
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
IQUnlimited Keyboard MCU simulation
|
||||
|
||||
*******************************************************************************
|
||||
iq unlimited has a different mcu than socrates, which has an 8-word 8-bit wide
|
||||
fifo instead.
|
||||
As in socrates, the bits are returned in two registers, handled by keyboard_buffer_read
|
||||
bits are read out in the following order:
|
||||
offset0 offset1
|
||||
76543210 76543210
|
||||
HHHHLLLL F000KACS
|
||||
where HHHH is the high nybble, LLLL is the low nybble, KACS is capslock, alt, ctrl and shift,
|
||||
and F is the fifo status, 1 if the fifo had any data in it at all, and 0 if not.
|
||||
KACS are NOT from the fifo, but a live status of the key states.
|
||||
F is also binary ORed with the vblank state???
|
||||
if the fifo is empty, the mcu shifts out nothing, and the spi reg holds 00000000 F000KACS
|
||||
******************************************************************************/
|
||||
|
||||
void socrates_state::kbmcu_sim_reset()
|
||||
{
|
||||
static const char *const rownames[] = { "keyboard_40", "keyboard_41", "keyboard_42", "keyboard_43", "keyboard_44" };
|
||||
int row, keyvalue, powerof2;
|
||||
int shift = 0;
|
||||
// first check that the kb latch[1] is clear; if it isn't, don't touch it!
|
||||
if ((m_kb_latch_low[1] != 0) || (m_kb_latch_high[1] != 1)) return;
|
||||
// next check for joypad buttons
|
||||
keyvalue = ioport("keyboard_jp")->read();
|
||||
if (keyvalue != 0)
|
||||
m_kb_queue.head = m_kb_queue.tail = m_kb_queue.count = 0;
|
||||
for (uint8_t i = 0; i < (sizeof(m_kb_queue.buffer)/sizeof(m_kb_queue.buffer[0])); i++)
|
||||
m_kb_queue.buffer[i]=0;
|
||||
}
|
||||
|
||||
|
||||
void socrates_state::kbmcu_sim_fifo_enqueue(uint16_t data)
|
||||
{
|
||||
//logerror("kbmcu_sim_fifo_enqueue called with %02x, fifo count was %d\n", data, m_kb_queue.count);
|
||||
if (m_kb_queue.count < 8)
|
||||
{
|
||||
m_kb_latch_low[1] = (keyvalue & 0xFF0)>>4;
|
||||
m_kb_latch_high[1] = 0x80 | (keyvalue & 0xF);
|
||||
return; // get out of this function; due to the way key priorities work, we're done here.
|
||||
}
|
||||
// next check for mouse movement.
|
||||
// this isn't written yet, so write me please!
|
||||
// next check if shift is down
|
||||
shift = ioport("keyboard_50")->read();
|
||||
// find key low and high byte ok keyboard section
|
||||
for (row = 4; row>=0; row--)
|
||||
{
|
||||
keyvalue = ioport(rownames[row])->read();
|
||||
if (keyvalue != 0)
|
||||
{
|
||||
for (powerof2 = 9; powerof2 >= 0; powerof2--)
|
||||
{
|
||||
if ((keyvalue&(1<<powerof2)) == (1<<powerof2))
|
||||
{
|
||||
m_kb_latch_low[1] = (shift?0x50:0x40)+row;
|
||||
m_kb_latch_high[1] = (0x80 | powerof2);
|
||||
return; // get out of the for loop; due to the way key priorities work, we're done here.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// no key was pressed... check if shift was hit then?
|
||||
if (shift != 0)
|
||||
{
|
||||
m_kb_latch_low[1] = 0x50;
|
||||
m_kb_latch_high[1] = 0x80;
|
||||
m_kb_queue.buffer[m_kb_queue.tail] = data;
|
||||
m_kb_queue.tail = (m_kb_queue.tail + 1) % (sizeof(m_kb_queue.buffer)/sizeof(m_kb_queue.buffer[0]));
|
||||
m_kb_queue.count++;
|
||||
}
|
||||
}
|
||||
|
||||
void socrates_state::socrates_check_kb_latch( ) // if kb[1] is full and kb[0] is not, shift [1] to [0] and clear [1]
|
||||
uint16_t socrates_state::kbmcu_sim_fifo_dequeue()
|
||||
{
|
||||
if (((m_kb_latch_low[1] != 0) || (m_kb_latch_high[1] != 1)) &&
|
||||
((m_kb_latch_low[0] == 0) && (m_kb_latch_high[0] == 1)))
|
||||
{
|
||||
m_kb_latch_low[0] = m_kb_latch_low[1];
|
||||
m_kb_latch_low[1] = 0;
|
||||
m_kb_latch_high[0] = m_kb_latch_high[1];
|
||||
m_kb_latch_high[1] = 1;
|
||||
}
|
||||
if (m_kb_queue.count == 0) fatalerror("kbmcu_sim_fifo_dequeue called with queue count of zero. This should never happen, contact MAMEDEV!");
|
||||
uint16_t retval = m_kb_queue.buffer[m_kb_queue.head];
|
||||
m_kb_queue.count--;
|
||||
m_kb_queue.head = (m_kb_queue.head + 1) % (sizeof(m_kb_queue.buffer)/sizeof(m_kb_queue.buffer[0]));
|
||||
//logerror("kbmcu_sim_fifo_dequeue was called, returning %02x, fifo count is now %d\n", retval, m_kb_queue.count);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void socrates_state::machine_reset()
|
||||
uint16_t socrates_state::kbmcu_sim_fifo_peek()
|
||||
{
|
||||
m_cart_reg = memregion(util::string_format("%s%s", m_cart->tag(), GENERIC_ROM_REGION_TAG).c_str());
|
||||
if (m_kb_queue.count == 0) fatalerror("kbmcu_sim_fifo_peek called with queue count of zero. This should never happen, contact MAMEDEV!");
|
||||
uint16_t retval = m_kb_queue.buffer[m_kb_queue.head];
|
||||
//logerror("kbmcu_sim_fifo_peek was called, returning %02x, fifo count is now %d\n", retval, m_kb_queue.count);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void socrates_state::kbmcu_sim_fifo_head_clear()
|
||||
{
|
||||
m_kb_queue.buffer[m_kb_queue.head] = 0;
|
||||
}
|
||||
|
||||
void socrates_state::machine_start()
|
||||
{
|
||||
m_kbmcu_sim_timer = timer_alloc(TIMER_KBMCU_SIM);
|
||||
m_kbmcu_sim_timer->adjust(attotime::from_hz((XTAL_21_4772MHz/6)/3000)); // timer rate is a massive guess, depends on instructions per loop of mcu
|
||||
m_clear_speech_timer = timer_alloc(TIMER_CLEAR_SPEECH);
|
||||
m_clear_irq_timer = timer_alloc(TIMER_CLEAR_IRQ);
|
||||
save_item(NAME(m_rom_bank));
|
||||
save_item(NAME(m_ram_bank));
|
||||
save_item(NAME(m_scroll_offset));
|
||||
save_item(NAME(m_kb_spi_request));
|
||||
save_item(NAME(m_kb_spi_buffer));
|
||||
save_item(NAME(m_oldkeyvalue));
|
||||
save_item(NAME(m_keyrepeat_holdoffcounter));
|
||||
save_item(NAME(m_io40_latch));
|
||||
save_item(NAME(m_speech_running));
|
||||
save_item(NAME(m_speech_address));
|
||||
save_item(NAME(m_speech_settings));
|
||||
save_item(NAME(m_speech_dummy_read));
|
||||
save_item(NAME(m_speech_load_address_count));
|
||||
save_item(NAME(m_speech_load_settings_count));
|
||||
m_rom_bank[0] = m_rom_bank[1] = 0x0;
|
||||
m_rombank1->set_bank(0x0); // actually set semi-randomly on real console but we need to initialize it somewhere...
|
||||
m_ram_bank = 0;
|
||||
m_rambank1->set_bank(0x0);// the actual console sets it semi randomly on power up, and the bios cleans it up.
|
||||
m_rambank2->set_bank(0x0);
|
||||
m_kb_latch_low[0] = 0xFF;
|
||||
m_kb_latch_high[0] = 0x8F;
|
||||
m_kb_latch_low[1] = 0x00;
|
||||
m_kb_latch_high[1] = 0x01;
|
||||
m_kb_latch_mouse = 0;
|
||||
m_kbmcu_rscount = 0;
|
||||
// ASIC SPI buffer starts with garbage in it for one word, simulate this
|
||||
m_kb_spi_buffer = 0xFF8F;
|
||||
}
|
||||
|
||||
void socrates_state::machine_reset()
|
||||
{
|
||||
m_cart_reg = memregion(util::string_format("%s%s", m_cart->tag(), GENERIC_ROM_REGION_TAG).c_str());
|
||||
kbmcu_sim_reset();
|
||||
m_kb_spi_request = true;
|
||||
m_oldkeyvalue = 0;
|
||||
m_keyrepeat_holdoffcounter = KEYREPEAT_HOLDOFF;
|
||||
m_io40_latch = 0;
|
||||
m_speech_running = 0;
|
||||
m_speech_address = 0;
|
||||
@ -300,6 +360,9 @@ void socrates_state::device_timer(emu_timer &timer, device_timer_id id, int para
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case TIMER_KBMCU_SIM:
|
||||
kbmcu_sim_cb(ptr, param);
|
||||
break;
|
||||
case TIMER_CLEAR_SPEECH:
|
||||
clear_speech_cb(ptr, param);
|
||||
break;
|
||||
@ -318,8 +381,19 @@ DRIVER_INIT_MEMBER(socrates_state,socrates)
|
||||
/* fill vram with its init powerup bit pattern, so startup has the checkerboard screen */
|
||||
for (int i = 0; i < 0x10000; i++)
|
||||
gfx[i] = (((i&0x1)?0x00:0xFF)^((i&0x100)?0x00:0xff));
|
||||
// init sound channels to both be on lowest pitch and max volume
|
||||
m_maincpu->set_clock_scale(0.45f); /* RAM access waitstates etc. aren't emulated - slow the CPU to compensate */
|
||||
m_maincpu->set_clock_scale(0.45f); /// TODO: RAM access waitstates etc. aren't emulated - slow the CPU to compensate
|
||||
m_kbmcu_type = 0;
|
||||
}
|
||||
|
||||
DRIVER_INIT_MEMBER(socrates_state,iqunlimz)
|
||||
{
|
||||
uint8_t *gfx = memregion("vram")->base();
|
||||
|
||||
/* fill vram with its init powerup bit pattern, so startup has the checkerboard screen... is this even right for the iqunlimz? */
|
||||
for (int i = 0; i < 0x20000; i++)
|
||||
gfx[i] = (((i&0x1)?0x00:0xFF)^((i&0x100)?0x00:0xff));
|
||||
//m_maincpu->set_clock_scale(0.45f); /// TODO: RAM access waitstates etc. aren't emulated - slow the CPU to compensate
|
||||
m_kbmcu_type = 1;
|
||||
}
|
||||
|
||||
READ8_MEMBER(socrates_state::common_rom_bank_r)
|
||||
@ -350,6 +424,7 @@ WRITE8_MEMBER(socrates_state::common_ram_bank_w)
|
||||
|
||||
READ8_MEMBER(socrates_state::socrates_cart_r)
|
||||
{
|
||||
///TODO: do m_rombank->space(AS_PROGRAM).install_write_handler(0x0002, 0x0002, write8_delegate(FUNC(dac_byte_interface::write), (dac_byte_interface *)m_dac)); style stuff
|
||||
// demangle the offset, offset passed is bits 11111111 11111111 00000000 00000000
|
||||
// where . is 0 EDCBA987 65432.10 FEDCBA98 76543210
|
||||
offset = ((offset&0x3FFFF)|((offset&0xF80000)>>1));
|
||||
@ -367,25 +442,16 @@ READ8_MEMBER(socrates_state::read_f3)// used for read-only i/o ports as mame/mes
|
||||
return 0xF3;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(socrates_state::kbmcu_strobe) // strobe the keyboard MCU
|
||||
WRITE8_MEMBER(socrates_state::kbmcu_reset) // reset the keyboard MCU, clear its fifo
|
||||
{
|
||||
//logerror("0x%04X: kbmcu written with %02X!\n", m_maincpu->pc(), data); //if (m_maincpu->pc() != 0x31D)
|
||||
// if two writes happen within one frame, reset the keyboard latches
|
||||
m_kbmcu_rscount++;
|
||||
if (m_kbmcu_rscount > 1)
|
||||
{
|
||||
m_kb_latch_low[0] = 0x00;
|
||||
m_kb_latch_high[0] = 0x01;
|
||||
m_kb_latch_low[1] = 0x00;
|
||||
m_kb_latch_high[1] = 0x01;
|
||||
m_kb_latch_mouse = 0;
|
||||
}
|
||||
kbmcu_sim_reset();
|
||||
}
|
||||
|
||||
READ8_MEMBER(socrates_state::status_and_speech)// read 0x4x, some sort of status reg
|
||||
{
|
||||
// bit 7 - speech status: high when speech is playing, low when it is not (or when speech cart is not present)
|
||||
// bit 6 - unknown, usually set, may involve the writes to 0x30, possibly some sort of fixed-length timer?
|
||||
// bit 6 - unknown, usually set, possibly mcu ready state?
|
||||
// bit 5 - vblank status, high when not in vblank
|
||||
// bit 4 - hblank status, high when not in hblank
|
||||
// bit 3 - speech chip bit 3
|
||||
@ -396,7 +462,7 @@ uint8_t *speechromint = memregion("speechint")->base();
|
||||
uint8_t *speechromext = memregion("speechext")->base();
|
||||
int temp = 0;
|
||||
temp |= (m_speech_running)?0x80:0;
|
||||
temp |= 0x40; // unknown, possibly IR mcu busy
|
||||
temp |= (1)?0x40:0; // unknown, possibly IR mcu ready?
|
||||
temp |= (m_screen->vblank())?0:0x20;
|
||||
temp |= (m_screen->hblank())?0:0x10;
|
||||
switch(m_io40_latch&0xF0) // what was last opcode sent?
|
||||
@ -511,7 +577,7 @@ SEL 5 4 3 2 1 0
|
||||
case 0x80: case 0x88: case 0x90: case 0x98: case 0xA0: case 0xA8: case 0xB0: case 0xB8:
|
||||
/* 'dumb' mode speech command: write me: start talking */
|
||||
m_speech_running = 1;
|
||||
timer_set(attotime::from_seconds(4), TIMER_CLEAR_SPEECH); // hack
|
||||
m_clear_speech_timer->adjust(attotime::from_seconds(4)); // hack
|
||||
break;
|
||||
case 0xC0: case 0xC8: // ADLD: load address to vsm
|
||||
m_speech_address |= (((int)data&0xF)<<(m_speech_load_address_count*4))<<1;
|
||||
@ -526,7 +592,7 @@ SEL 5 4 3 2 1 0
|
||||
break;
|
||||
case 0xF0: // SPEAK
|
||||
m_speech_running = 1;
|
||||
timer_set(attotime::from_seconds(4), TIMER_CLEAR_SPEECH); // hack
|
||||
m_clear_speech_timer->adjust(attotime::from_seconds(4)); // hack
|
||||
break;
|
||||
case 0xF8: // RESET
|
||||
m_speech_running = 0;
|
||||
@ -543,26 +609,24 @@ SEL 5 4 3 2 1 0
|
||||
m_io40_latch = data;
|
||||
}
|
||||
|
||||
READ8_MEMBER(socrates_state::socrates_keyboard_low_r)// keyboard code low
|
||||
READ8_MEMBER( socrates_state::keyboard_buffer_read )
|
||||
{
|
||||
socrates_update_kb();
|
||||
socrates_check_kb_latch();
|
||||
return m_kb_latch_low[0];
|
||||
if (m_kbmcu_type == 0)
|
||||
{
|
||||
if (offset == 1) return m_kb_spi_buffer&0xFF;
|
||||
else return (m_kb_spi_buffer&0xFF00)>>8;
|
||||
}
|
||||
else // (m_kbmcu_type == 1) // iqunlimz hack, the system won't work without this?!?!
|
||||
{
|
||||
if (offset == 1) return (m_screen->vblank()?0x80:0)|(m_kbdrow[0]->read()&0xf);
|
||||
else return (m_kb_spi_buffer&0xFF00)>>8;
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER(socrates_state::socrates_keyboard_high_r)// keyboard code high
|
||||
WRITE8_MEMBER( socrates_state::keyboard_buffer_update )
|
||||
{
|
||||
socrates_update_kb();
|
||||
socrates_check_kb_latch();
|
||||
return m_kb_latch_high[0];
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(socrates_state::socrates_keyboard_clear)// keyboard latch shift/clear
|
||||
{
|
||||
m_kb_latch_low[0] = m_kb_latch_low[1];
|
||||
m_kb_latch_high[0] = m_kb_latch_high[1];
|
||||
m_kb_latch_low[1] = 0;
|
||||
m_kb_latch_high[1] = 1;
|
||||
m_kb_spi_request = true;
|
||||
m_kb_spi_buffer = 0x0001;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(socrates_state::reset_speech)// i/o 60: reset speech synth
|
||||
@ -877,8 +941,7 @@ void iqunlim_state::machine_reset()
|
||||
|
||||
memset(m_colors, 0, 8);
|
||||
memset(m_video_regs, 0, 4);
|
||||
m_kb_queue.head = m_kb_queue.tail = 0;
|
||||
|
||||
kbmcu_sim_reset();
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( iqunlim_state::colors_w )
|
||||
@ -895,37 +958,10 @@ INPUT_CHANGED_MEMBER( iqunlim_state::send_input )
|
||||
|
||||
if (newval)
|
||||
{
|
||||
m_kb_queue.buffer[m_kb_queue.tail] = data;
|
||||
m_kb_queue.tail = (m_kb_queue.tail + 1) % sizeof(m_kb_queue.buffer);
|
||||
kbmcu_sim_fifo_enqueue(data<<4);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( iqunlim_state::keyboard_clear )
|
||||
{
|
||||
if(m_kb_queue.head != m_kb_queue.tail)
|
||||
m_kb_queue.head = (m_kb_queue.head + 1) % sizeof(m_kb_queue.buffer);
|
||||
}
|
||||
|
||||
READ8_MEMBER( iqunlim_state::keyboard_r )
|
||||
{
|
||||
uint8_t data = 0;
|
||||
|
||||
switch(offset)
|
||||
{
|
||||
case 0:
|
||||
if(m_kb_queue.head != m_kb_queue.tail)
|
||||
data = m_kb_queue.buffer[m_kb_queue.head];
|
||||
break;
|
||||
case 1:
|
||||
data = (m_kb_queue.head != m_kb_queue.tail ? 0x80 : 0) | (ioport("IN0")->read() & 0x7f);
|
||||
if (m_screen->vblank()) data |= 0x80; // FIXME
|
||||
break;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
Address Maps
|
||||
******************************************************************************/
|
||||
@ -967,11 +1003,10 @@ static ADDRESS_MAP_START(z80_io, AS_IO, 8, socrates_state )
|
||||
0xC0 produces a DMC wave read from an unknown address at around 342hz
|
||||
<todo: test the others, maybe take samples?>
|
||||
*/
|
||||
AM_RANGE(0x20, 0x21) AM_READWRITE(read_f3, socrates_scroll_w) AM_MIRROR (0xe)
|
||||
AM_RANGE(0x30, 0x30) AM_READWRITE(read_f3, kbmcu_strobe) AM_MIRROR (0xf) /* resets the keyboard IR decoder MCU */
|
||||
AM_RANGE(0x40, 0x40) AM_READWRITE(status_and_speech, speech_command ) AM_MIRROR(0xf) /* reads status register for vblank/hblank/speech, also reads and writes speech module */
|
||||
AM_RANGE(0x50, 0x50) AM_READWRITE(socrates_keyboard_low_r, socrates_keyboard_clear) AM_MIRROR(0xE) /* Keyboard keycode low, latched on keypress, can be unlatched by writing anything here */
|
||||
AM_RANGE(0x51, 0x51) AM_READWRITE(socrates_keyboard_high_r, socrates_keyboard_clear) AM_MIRROR(0xE) /* Keyboard keycode high, latched as above, unlatches same as above */
|
||||
AM_RANGE(0x20, 0x21) AM_READWRITE(read_f3, socrates_scroll_w) AM_MIRROR(0xE)
|
||||
AM_RANGE(0x30, 0x30) AM_READWRITE(read_f3, kbmcu_reset) AM_MIRROR(0xF) /* resets the keyboard IR decoder MCU */
|
||||
AM_RANGE(0x40, 0x40) AM_READWRITE(status_and_speech, speech_command ) AM_MIRROR(0xF) /* reads status register for vblank/hblank/speech, also reads and writes speech module */
|
||||
AM_RANGE(0x50, 0x51) AM_READWRITE(keyboard_buffer_read, keyboard_buffer_update) AM_MIRROR(0xE) /* Keyboard fifo read, pop fifo on write */
|
||||
AM_RANGE(0x60, 0x60) AM_READWRITE(read_f3, reset_speech) AM_MIRROR(0xF) /* reset the speech module, or perhaps fire an NMI? */
|
||||
AM_RANGE(0x70, 0xFF) AM_READ(read_f3) // nothing mapped here afaik
|
||||
ADDRESS_MAP_END
|
||||
@ -1001,13 +1036,16 @@ static ADDRESS_MAP_START( iqunlimz_io , AS_IO, 8, iqunlim_state)
|
||||
ADDRESS_MAP_GLOBAL_MASK(0xff)
|
||||
AM_RANGE(0x00, 0x01) AM_READWRITE(common_rom_bank_r, common_rom_bank_w) AM_MIRROR(0x06)
|
||||
AM_RANGE(0x08, 0x08) AM_READWRITE(common_ram_bank_r, common_ram_bank_w) AM_MIRROR(0x07)
|
||||
AM_RANGE(0x10, 0x17) AM_WRITE(socrates_sound_w) AM_MIRROR (0x08)
|
||||
AM_RANGE(0x20, 0x21) AM_WRITE(socrates_scroll_w) AM_MIRROR (0x0e)
|
||||
AM_RANGE(0x50, 0x51) AM_READWRITE(keyboard_r, keyboard_clear)
|
||||
AM_RANGE(0x70, 0x73) AM_READWRITE(video_regs_r, video_regs_w) AM_MIRROR (0x0c)
|
||||
AM_RANGE(0x10, 0x17) AM_WRITE(socrates_sound_w) AM_MIRROR(0x08)
|
||||
AM_RANGE(0x20, 0x21) AM_WRITE(socrates_scroll_w) AM_MIRROR(0x0E)
|
||||
// 30: writes an incrementing value here, once per keypress?
|
||||
// 40: some sort of serial select/reset or enable, related to 0x60
|
||||
AM_RANGE(0x50, 0x51) AM_READWRITE(keyboard_buffer_read, keyboard_buffer_update) AM_MIRROR(0xE)
|
||||
// 60: some sort of serial read/write port, related to 0x40
|
||||
AM_RANGE(0x70, 0x73) AM_READWRITE(video_regs_r, video_regs_w) AM_MIRROR(0x0C)
|
||||
AM_RANGE(0x80, 0x81) AM_WRITENOP // LCD
|
||||
AM_RANGE(0xb1, 0xb1) AM_WRITENOP
|
||||
AM_RANGE(0xa0, 0xa0) AM_READ(status_r) AM_MIRROR(0x0f)
|
||||
AM_RANGE(0xa0, 0xa0) AM_READ(status_r) AM_MIRROR(0x0F)
|
||||
AM_RANGE(0xe0, 0xe7) AM_WRITE(colors_w) AM_MIRROR(0x08)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
@ -1101,99 +1139,99 @@ B0 81 both buttons click (mouse movement in queue, will be in regs after next
|
||||
*/
|
||||
static INPUT_PORTS_START( socrates )
|
||||
|
||||
PORT_START("keyboard_jp") // joypad keys
|
||||
PORT_BIT(0x00000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) PORT_NAME("Left D-pad Right") // 00 81
|
||||
PORT_BIT(0x00000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) PORT_NAME("Left D-pad Up") // 00 82
|
||||
PORT_BIT(0x00000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) PORT_NAME("Left D-pad Left") // 00 84
|
||||
PORT_BIT(0x00000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) PORT_NAME("Left D-pad Down") // 00 88
|
||||
PORT_BIT(0x00000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_NAME("Right D-pad Down") // 01 80
|
||||
PORT_BIT(0x00000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_NAME("Right D-pad Left") // 02 80
|
||||
PORT_BIT(0x00000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_NAME("Right D-pad Up") // 04 80
|
||||
PORT_BIT(0x00000080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_NAME("Right D-pad Right") // 08 80
|
||||
PORT_BIT(0x00000100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) PORT_NAME("Left D-pad Button") // 10 80
|
||||
PORT_BIT(0x00000200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RALT) PORT_CHAR(UCHAR_MAMEKEY(RALT)) PORT_NAME("Right D-pad Button") // 20 80
|
||||
PORT_BIT(0xfffffc00, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
PORT_START("IN5") // joypad keys
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
PORT_BIT(0xfc00, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
/* alt w/left and right keypad keys swapped
|
||||
PORT_BIT(0x00000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_NAME("Left D-pad Right") // 00 81
|
||||
PORT_BIT(0x00000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_NAME("Left D-pad Up") // 00 82
|
||||
PORT_BIT(0x00000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_NAME("Left D-pad Left") // 00 84
|
||||
PORT_BIT(0x00000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_NAME("Left D-pad Down") // 00 88
|
||||
PORT_BIT(0x00000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) PORT_NAME("Right D-pad Down") // 01 80
|
||||
PORT_BIT(0x00000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) PORT_NAME("Right D-pad Left") // 02 80
|
||||
PORT_BIT(0x00000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) PORT_NAME("Right D-pad Up") // 04 80
|
||||
PORT_BIT(0x00000080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) PORT_NAME("Right D-pad Right") // 08 80
|
||||
PORT_BIT(0x00000100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RALT) PORT_CHAR(UCHAR_MAMEKEY(RALT)) PORT_NAME("Left D-pad Button") // 10 80
|
||||
PORT_BIT(0x00000200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) PORT_NAME("Right D-pad Button") // 20 80
|
||||
PORT_BIT(0xfffffc00, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
PORT_BIT(0xfc00, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
*/
|
||||
|
||||
PORT_START("keyboard_50") // lowest 'row' (technically the shift key is on the 5th row but it has its own keycode)
|
||||
PORT_BIT(0x00000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PORT_NAME("SHIFT") // 5x xx
|
||||
PORT_BIT(0xfffffffe, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
PORT_START("IN6") // lowest 'row' (technically the shift key is on the 5th row but it has its own keycode)
|
||||
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
|
||||
PORT_BIT(0xfffe, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
|
||||
PORT_START("keyboard_40") // 5th row
|
||||
PORT_BIT(0x00000003, IP_ACTIVE_HIGH, IPT_UNUSED) // 40 80 and 40 81
|
||||
PORT_BIT(0x00000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_NAME("SPACE") // 40 82
|
||||
PORT_BIT(0x00000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_NAME("Z") // 40 83
|
||||
PORT_BIT(0x00000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_NAME("Y") // 40 84
|
||||
PORT_BIT(0x00000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_NAME("X") // 40 85
|
||||
PORT_BIT(0x00000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_NAME("W") // 40 86
|
||||
PORT_BIT(0x00000080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_NAME("V") // 40 87
|
||||
PORT_BIT(0x00000100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_NAME("U") // 40 88
|
||||
PORT_BIT(0x00000200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_NAME("T") // 40 89
|
||||
PORT_BIT(0xfffffc00, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
PORT_START("IN0") // 5th row
|
||||
PORT_BIT(0x0003, IP_ACTIVE_HIGH, IPT_UNUSED) // 40 80 and 40 81
|
||||
PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_NAME("SPACE") // 40 82
|
||||
PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_NAME("Z") // 40 83
|
||||
PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_NAME("Y") // 40 84
|
||||
PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_NAME("X") // 40 85
|
||||
PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_NAME("W") // 40 86
|
||||
PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_NAME("V") // 40 87
|
||||
PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_NAME("U") // 40 88
|
||||
PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_NAME("T") // 40 89
|
||||
PORT_BIT(0xfc00, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
|
||||
PORT_START("keyboard_41") // 4th row
|
||||
PORT_BIT(0x00000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_NAME("J/Ti") // 41 80
|
||||
PORT_BIT(0x00000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_NAME("S") // 41 81
|
||||
PORT_BIT(0x00000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_NAME("R") // 41 82
|
||||
PORT_BIT(0x00000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_NAME("Q/NEW") // 41 83
|
||||
PORT_BIT(0x00000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_NAME("P/PLAY") // 41 84
|
||||
PORT_BIT(0x00000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_NAME("O/PAUSE") // 41 85
|
||||
PORT_BIT(0x00000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_NAME("N/Fa'") // 41 86
|
||||
PORT_BIT(0x00000080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_NAME("M/Mi'") // 41 87
|
||||
PORT_BIT(0x00000100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_NAME("L/Re'") // 41 88
|
||||
PORT_BIT(0x00000200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_NAME("K/Do'") // 41 89
|
||||
PORT_BIT(0xfffffc00, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
PORT_START("IN1") // 4th row
|
||||
PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_NAME("J/Ti") // 41 80
|
||||
PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_NAME("S") // 41 81
|
||||
PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_NAME("R") // 41 82
|
||||
PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_NAME("Q/NEW") // 41 83
|
||||
PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_NAME("P/PLAY") // 41 84
|
||||
PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_NAME("O/PAUSE") // 41 85
|
||||
PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_NAME("N/Fa'") // 41 86
|
||||
PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_NAME("M/Mi'") // 41 87
|
||||
PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_NAME("L/Re'") // 41 88
|
||||
PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_NAME("K/Do'") // 41 89
|
||||
PORT_BIT(0xfc00, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
|
||||
PORT_START("keyboard_42") // 3rd row
|
||||
PORT_BIT(0x00000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_NAME("A/So.") // 42 80
|
||||
PORT_BIT(0x00000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('-') PORT_NAME("-/.") // 42 81
|
||||
PORT_BIT(0x00000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_NAME("I/La") // 42 82
|
||||
PORT_BIT(0x00000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_NAME("H/So") // 42 83
|
||||
PORT_BIT(0x00000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_NAME("G/Fa") // 42 84
|
||||
PORT_BIT(0x00000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_NAME("F/Mi") // 42 85
|
||||
PORT_BIT(0x00000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_NAME("E/Re") // 42 86
|
||||
PORT_BIT(0x00000080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_NAME("D/Do") // 42 87
|
||||
PORT_BIT(0x00000100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_NAME("C/Ti.") // 42 88
|
||||
PORT_BIT(0x00000200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_NAME("B/La.") // 42 89
|
||||
PORT_BIT(0xfffffc00, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
PORT_START("IN2") // 3rd row
|
||||
PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_NAME("A/So.") // 42 80
|
||||
PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('-') PORT_NAME("-/.") // 42 81
|
||||
PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_NAME("I/La") // 42 82
|
||||
PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_NAME("H/So") // 42 83
|
||||
PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_NAME("G/Fa") // 42 84
|
||||
PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_NAME("F/Mi") // 42 85
|
||||
PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_NAME("E/Re") // 42 86
|
||||
PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_NAME("D/Do") // 42 87
|
||||
PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_NAME("C/Ti.") // 42 88
|
||||
PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_NAME("B/La.") // 42 89
|
||||
PORT_BIT(0xfc00, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
|
||||
PORT_START("keyboard_43") // 2nd row
|
||||
PORT_BIT(0x00000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_NAME("1") // 43 80
|
||||
PORT_BIT(0x00000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_NAME("0") // 43 81
|
||||
PORT_BIT(0x00000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_NAME("9") // 43 82
|
||||
PORT_BIT(0x00000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_NAME("8") // 43 83
|
||||
PORT_BIT(0x00000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_NAME("7") // 43 84
|
||||
PORT_BIT(0x00000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_NAME("6") // 43 85
|
||||
PORT_BIT(0x00000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_NAME("5") // 43 86
|
||||
PORT_BIT(0x00000080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_NAME("4") // 43 87
|
||||
PORT_BIT(0x00000100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_NAME("3") // 43 88
|
||||
PORT_BIT(0x00000200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_NAME("2") // 43 89
|
||||
PORT_BIT(0xfffffc00, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
PORT_START("IN3") // 2nd row
|
||||
PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_NAME("1") // 43 80
|
||||
PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_NAME("0") // 43 81
|
||||
PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_NAME("9") // 43 82
|
||||
PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_NAME("8") // 43 83
|
||||
PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_NAME("7") // 43 84
|
||||
PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_NAME("6") // 43 85
|
||||
PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_NAME("5") // 43 86
|
||||
PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_NAME("4") // 43 87
|
||||
PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_NAME("3") // 43 88
|
||||
PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_NAME("2") // 43 89
|
||||
PORT_BIT(0xfc00, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
|
||||
PORT_START("keyboard_44") // 1st row
|
||||
PORT_BIT(0x00000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('+') PORT_NAME("+") // 44 80
|
||||
PORT_BIT(0x00000002, IP_ACTIVE_HIGH, IPT_UNUSED) // 44 81
|
||||
PORT_BIT(0x00000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_NAME("ENTER") // 44 82
|
||||
PORT_BIT(0x00000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(HOME)) PORT_NAME("MENU") // 44 83
|
||||
PORT_BIT(0x00000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_PGUP) PORT_CHAR(UCHAR_MAMEKEY(PGUP)) PORT_NAME("ANSWER") // 44 84
|
||||
PORT_BIT(0x00000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_PGDN) PORT_CHAR(UCHAR_MAMEKEY(PGDN)) PORT_NAME("HELP") // 44 85
|
||||
PORT_BIT(0x00000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_NAME("ERASE") // 44 86
|
||||
PORT_BIT(0x00000080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_NAME("/") // 44 87
|
||||
PORT_BIT(0x00000100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('*') PORT_NAME("*") // 44 88
|
||||
PORT_BIT(0x00000200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_NAME("-") // 44 89
|
||||
PORT_BIT(0xfffffc00, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
PORT_START("IN4") // 1st row
|
||||
PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('+') PORT_NAME("+") // 44 80
|
||||
PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_UNUSED) // 44 81
|
||||
PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_NAME("ENTER") // 44 82
|
||||
PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(HOME)) PORT_NAME("MENU") // 44 83
|
||||
PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_PGUP) PORT_CHAR(UCHAR_MAMEKEY(PGUP)) PORT_NAME("ANSWER") // 44 84
|
||||
PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_PGDN) PORT_CHAR(UCHAR_MAMEKEY(PGDN)) PORT_NAME("HELP") // 44 85
|
||||
PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_NAME("ERASE") // 44 86
|
||||
PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_NAME("/") // 44 87
|
||||
PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('*') PORT_NAME("*") // 44 88
|
||||
PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_NAME("-") // 44 89
|
||||
PORT_BIT(0xfc00, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
|
||||
// mouse goes here
|
||||
INPUT_PORTS_END
|
||||
@ -1319,9 +1357,90 @@ TIMER_CALLBACK_MEMBER(socrates_state::clear_irq_cb)
|
||||
INTERRUPT_GEN_MEMBER(socrates_state::assert_irq)
|
||||
{
|
||||
device.execute().set_input_line(0, ASSERT_LINE);
|
||||
timer_set(downcast<cpu_device *>(&device)->cycles_to_attotime(44), TIMER_CLEAR_IRQ);
|
||||
// 44 is a complete and total guess, need to properly measure how many clocks/microseconds the int line is high for.
|
||||
m_kbmcu_rscount = 0; // clear the mcu poke count
|
||||
m_clear_irq_timer->adjust(m_maincpu->cycles_to_attotime(44));
|
||||
// 44 is a complete and total guess, need to properly measure how many clocks/microseconds the int line is high for.
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(socrates_state::kbmcu_sim_cb)
|
||||
{
|
||||
// timer rate is a massive guess; we're assuming the mcu runs at the same speed as the cpu does,
|
||||
// and the refresh rate depends on instructions per loop of mcu, which we've randomly guessed is 60 cycles.
|
||||
m_kbmcu_sim_timer->adjust(m_maincpu->cycles_to_attotime(3000));
|
||||
/// TODO: dump the mcu and get rid of this...
|
||||
if (m_kbmcu_type == 0)
|
||||
{
|
||||
// socrates keyboard MCU simulation: if a keyboard key is pressed, enqueue it into the fifo as needed
|
||||
uint16_t keyvalue = 0;
|
||||
// check for joypad buttons
|
||||
keyvalue = m_kbdrow[5]->read();
|
||||
if (keyvalue == 0) // if joypad wasn't pushed...
|
||||
{
|
||||
// next check for mouse movement.
|
||||
/// TODO: this isn't written yet
|
||||
// next check for basic keyboard "4x xx" stuff
|
||||
// check if shift is down
|
||||
keyvalue = (m_kbdrow[6]->read())?0x500:0;
|
||||
bool keyfound = false;
|
||||
// find what row and bit we're on...
|
||||
for (int8_t row = 4; row>=0; row--)
|
||||
{
|
||||
uint16_t tempkey = m_kbdrow[row]->read();
|
||||
if (tempkey != 0)
|
||||
{
|
||||
for (int8_t powerof2 = 9; ((powerof2 >= 0) && (keyfound == false)); powerof2--) // continue until we find the first key only
|
||||
{
|
||||
if ((tempkey&(1<<powerof2)) == (1<<powerof2))
|
||||
{
|
||||
keyvalue |= (0x400 | (row<<4) | powerof2);
|
||||
keyfound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (keyvalue != 0) // if a key is down...
|
||||
{
|
||||
if (keyvalue == m_oldkeyvalue) // and its the same key as it was the last run...
|
||||
{
|
||||
if (m_keyrepeat_holdoffcounter > 0) // and the key repeat holdoff counter is > 0...
|
||||
{
|
||||
m_keyrepeat_holdoffcounter--; // decrement the holdoff counter
|
||||
}
|
||||
else // the key repeat holdoff counter is zero
|
||||
{
|
||||
kbmcu_sim_fifo_enqueue(0x1000|keyvalue); // queue the key with bit 12 set as a flag that this is a repeat
|
||||
m_keyrepeat_holdoffcounter += KEYREPEAT_REPEAT; // increment the holdoff counter by the repeat value
|
||||
}
|
||||
}
|
||||
else // it isn't the same key as it was the last run
|
||||
{
|
||||
kbmcu_sim_fifo_enqueue(keyvalue); // queue the key
|
||||
m_keyrepeat_holdoffcounter = KEYREPEAT_HOLDOFF; // reset the holdoff counter
|
||||
m_oldkeyvalue = keyvalue; // set this new key to be the 'previous key'
|
||||
}
|
||||
}
|
||||
else // keyvalue is zero, reset the holdoff counter
|
||||
{
|
||||
m_keyrepeat_holdoffcounter = KEYREPEAT_HOLDOFF;
|
||||
m_oldkeyvalue = keyvalue; // set this new key to be the 'previous key'
|
||||
}
|
||||
}
|
||||
//else // m_kbmcu_type = 1 // this is currently hacked around by the input system so no code here
|
||||
//{
|
||||
//}
|
||||
|
||||
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...
|
||||
{
|
||||
uint16_t tempbuffer = 0;
|
||||
m_kb_spi_request = false;
|
||||
tempbuffer = kbmcu_sim_fifo_peek();
|
||||
if (tempbuffer&0x1000) // repeat bit was set
|
||||
{
|
||||
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...
|
||||
}
|
||||
else tempbuffer = kbmcu_sim_fifo_dequeue();
|
||||
m_kb_spi_buffer = ((tempbuffer&0xFF0)<<4)|(tempbuffer&0xF)|0x80;
|
||||
}
|
||||
}
|
||||
|
||||
static MACHINE_CONFIG_START( socrates )
|
||||
@ -1331,7 +1450,6 @@ static MACHINE_CONFIG_START( socrates )
|
||||
MCFG_CPU_IO_MAP(z80_io)
|
||||
MCFG_QUANTUM_TIME(attotime::from_hz(60))
|
||||
MCFG_CPU_VBLANK_INT_DRIVER("screen", socrates_state, assert_irq)
|
||||
//MCFG_MACHINE_START_OVERRIDE(socrates_state,socrates)
|
||||
|
||||
MCFG_DEVICE_ADD("rombank1", ADDRESS_MAP_BANK, 0)
|
||||
MCFG_DEVICE_PROGRAM_MAP(socrates_rombank_map)
|
||||
@ -1488,7 +1606,7 @@ ROM_START(socrates)
|
||||
ROM_REGION(0x10000, "vram", ROMREGION_ERASEFF) /* fill with ff, driver_init changes this to the 'correct' startup pattern */
|
||||
|
||||
ROM_REGION(0x800, "kbmcu", ROMREGION_ERASEFF)
|
||||
ROM_LOAD("tmp42c40p1844.u2", 0x000, 0x200, NO_DUMP) /* keyboard IR decoder MCU */
|
||||
ROM_LOAD("tmp42c40p1844.u6", 0x000, 0x200, NO_DUMP) /* keyboard IR decoder MCU */
|
||||
|
||||
/* english speech cart has a green QC sticker */
|
||||
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
|
||||
@ -1509,7 +1627,7 @@ ROM_START(socratfc)
|
||||
ROM_REGION(0x10000, "vram", ROMREGION_ERASEFF) /* fill with ff, driver_init changes this to the 'correct' startup pattern */
|
||||
|
||||
ROM_REGION(0x800, "kbmcu", ROMREGION_ERASEFF)
|
||||
ROM_LOAD("tmp42c40p1844.u2", 0x000, 0x200, NO_DUMP) /* keyboard IR decoder MCU */
|
||||
ROM_LOAD("tmp42c40p1844.u6", 0x000, 0x200, NO_DUMP) /* keyboard IR decoder MCU */
|
||||
|
||||
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
|
||||
ROM_LOAD_OPTIONAL("speech_fra_internal.bin", 0x0000, 0x2000, NO_DUMP)
|
||||
@ -1532,7 +1650,7 @@ ROM_START(profweis)
|
||||
ROM_REGION(0x10000, "vram", ROMREGION_ERASEFF) /* fill with ff, driver_init changes this to the 'correct' startup pattern */
|
||||
|
||||
ROM_REGION(0x800, "kbmcu", ROMREGION_ERASEFF)
|
||||
ROM_LOAD("tmp42c40p1844.u2", 0x000, 0x200, NO_DUMP) /* keyboard IR decoder MCU */
|
||||
ROM_LOAD("tmp42c40p1844.u6", 0x000, 0x200, NO_DUMP) /* keyboard IR decoder MCU */
|
||||
|
||||
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
|
||||
ROM_LOAD_OPTIONAL("speech_ger_internal.bin", 0x0000, 0x2000, CRC(5ff0fdc6) SHA1(8ef128561a846762a20e3fe9513a4a22aaadc7f6))
|
||||
@ -1555,10 +1673,10 @@ ROM_END
|
||||
******************************************************************************/
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS
|
||||
COMP( 1988, socrates, 0, 0, socrates, socrates, socrates_state, socrates, "Video Technology", "Socrates Educational Video System", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) // English NTSC, no title copyright
|
||||
COMP( 1988, socratfc, socrates, 0, socrates, socrates, socrates_state, socrates, "Video Technology", "Socrates SAITOUT", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) // French Canandian NTSC, 1988 title copyright
|
||||
COMP( 1988, profweis, socrates, 0, socrates_pal, socrates, socrates_state, socrates, "Video Technology/Yeno", "Professor Weiss-Alles", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) // German PAL, 1988 title copyright
|
||||
COMP( 1988, socrates, 0, 0, socrates, socrates, socrates_state, socrates, "Video Technology", "Socrates Educational Video System", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // English NTSC, no title copyright
|
||||
COMP( 1988, socratfc, socrates, 0, socrates, socrates, socrates_state, socrates, "Video Technology", "Socrates SAITOUT", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // French Canandian NTSC, 1988 title copyright
|
||||
COMP( 1988, profweis, socrates, 0, socrates_pal, socrates, socrates_state, socrates, "Video Technology/Yeno", "Professor Weiss-Alles", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // German PAL, 1988 title copyright
|
||||
// Yeno Professeur Saitout goes here (french SECAM)
|
||||
// ? goes here (spanish PAL)
|
||||
|
||||
COMP( 1991, iqunlimz, 0, 0, iqunlimz, iqunlimz, iqunlim_state, 0, "Video Technology", "IQ Unlimited (Z80)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
|
||||
COMP( 1991, iqunlimz, 0, 0, iqunlimz, iqunlimz, iqunlim_state, iqunlimz, "Video Technology", "IQ Unlimited (Z80)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
|
||||
|
Loading…
Reference in New Issue
Block a user