mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00
geneve: Add PC KBD connector; allow for using XT keyboards in place of the currently high-level emulated XT/AT 101 keyboard.
This commit is contained in:
parent
ec4b8b2fa4
commit
4495c35113
@ -2941,6 +2941,8 @@ if (BUSES["TI99"]~=null) then
|
||||
MAME_DIR .. "src/devices/bus/ti99/internal/evpcconn.h",
|
||||
MAME_DIR .. "src/devices/bus/ti99/internal/genboard.cpp",
|
||||
MAME_DIR .. "src/devices/bus/ti99/internal/genboard.h",
|
||||
MAME_DIR .. "src/devices/bus/ti99/internal/genkbd.cpp",
|
||||
MAME_DIR .. "src/devices/bus/ti99/internal/genkbd.h",
|
||||
MAME_DIR .. "src/devices/bus/ti99/internal/ioport.cpp",
|
||||
MAME_DIR .. "src/devices/bus/ti99/internal/ioport.h",
|
||||
MAME_DIR .. "src/devices/bus/ti99/colorbus/busmouse.cpp",
|
||||
|
@ -16,6 +16,10 @@ The following basic program can be useful for identifying scancodes:
|
||||
#include "emu.h"
|
||||
#include "pc_kbdc.h"
|
||||
|
||||
#define LOG_SIGNALS (1U<<1)
|
||||
#define VERBOSE ( LOG_GENERAL )
|
||||
|
||||
#include "logmacro.h"
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
@ -109,7 +113,7 @@ void pc_kbdc_device::device_start()
|
||||
}
|
||||
|
||||
|
||||
void pc_kbdc_device::update_clock_state()
|
||||
void pc_kbdc_device::update_clock_state(bool fromkb)
|
||||
{
|
||||
int new_clock_state = m_mb_clock_state & m_kb_clock_state;
|
||||
|
||||
@ -117,7 +121,7 @@ void pc_kbdc_device::update_clock_state()
|
||||
{
|
||||
// We first set our state to prevent possible endless loops
|
||||
m_clock_state = new_clock_state;
|
||||
|
||||
LOGMASKED(LOG_SIGNALS, "%s Clock: %d\n", fromkb? "<-" : "->", m_clock_state);
|
||||
// Send state to keyboard interface logic on mainboard
|
||||
m_out_clock_cb(m_clock_state);
|
||||
|
||||
@ -128,7 +132,7 @@ void pc_kbdc_device::update_clock_state()
|
||||
}
|
||||
|
||||
|
||||
void pc_kbdc_device::update_data_state()
|
||||
void pc_kbdc_device::update_data_state(bool fromkb)
|
||||
{
|
||||
int new_data_state = m_mb_data_state & m_kb_data_state;
|
||||
|
||||
@ -136,6 +140,7 @@ void pc_kbdc_device::update_data_state()
|
||||
{
|
||||
// We first set our state to prevent possible endless loops
|
||||
m_data_state = new_data_state;
|
||||
LOGMASKED(LOG_SIGNALS, "%s Data: %d\n", fromkb? "<-" : "->", m_data_state);
|
||||
|
||||
// Send state to keyboard interface logic on mainboard
|
||||
m_out_data_cb(m_data_state);
|
||||
@ -150,28 +155,28 @@ void pc_kbdc_device::update_data_state()
|
||||
WRITE_LINE_MEMBER(pc_kbdc_device::clock_write_from_mb)
|
||||
{
|
||||
m_mb_clock_state = state;
|
||||
update_clock_state();
|
||||
update_clock_state(false);
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(pc_kbdc_device::data_write_from_mb)
|
||||
{
|
||||
m_mb_data_state = state;
|
||||
update_data_state();
|
||||
update_data_state(false);
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(pc_kbdc_device::clock_write_from_kb)
|
||||
{
|
||||
m_kb_clock_state = state;
|
||||
update_clock_state();
|
||||
update_clock_state(true);
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(pc_kbdc_device::data_write_from_kb)
|
||||
{
|
||||
m_kb_data_state = state;
|
||||
update_data_state();
|
||||
update_data_state(true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -79,8 +79,8 @@ protected:
|
||||
virtual void device_resolve_objects() override;
|
||||
virtual void device_start() override;
|
||||
|
||||
void update_clock_state();
|
||||
void update_data_state();
|
||||
void update_clock_state(bool fromkb);
|
||||
void update_data_state(bool fromkb);
|
||||
|
||||
devcb_write_line m_out_clock_cb;
|
||||
devcb_write_line m_out_data_cb;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -23,6 +23,7 @@
|
||||
#include "machine/mm58274c.h"
|
||||
#include "machine/at29x.h"
|
||||
#include "machine/ram.h"
|
||||
#include "bus/pc_kbd/pc_kbdc.h"
|
||||
|
||||
enum
|
||||
{
|
||||
@ -37,12 +38,12 @@ enum
|
||||
GENEVE_PFM512A
|
||||
};
|
||||
|
||||
#define GENEVE_KEYBOARD_TAG "gkeyboard"
|
||||
#define GENEVE_MAPPER_TAG "gmapper"
|
||||
#define GENEVE_GATE_ARRAY_TAG "gatearray"
|
||||
#define GENEVE_MOUSE_TAG "gmouse"
|
||||
#define GENEVE_CLOCK_TAG "mm58274c"
|
||||
#define GENEVE_PFM512_TAG "pfm512"
|
||||
#define GENEVE_PFM512A_TAG "pfm512a"
|
||||
#define GENEVE_KEYBOARD_CONN_TAG "keybconn"
|
||||
|
||||
#define GENEVE_SRAM_TAG "sram"
|
||||
#define GENEVE_DRAM_TAG "dram"
|
||||
@ -53,66 +54,10 @@ namespace bus { namespace ti99 { namespace internal {
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
class geneve_keyboard_device : public device_t
|
||||
class geneve_gate_array_device : public device_t
|
||||
{
|
||||
public:
|
||||
geneve_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
DECLARE_WRITE_LINE_MEMBER( reset_line );
|
||||
DECLARE_WRITE_LINE_MEMBER( send_scancodes );
|
||||
DECLARE_WRITE_LINE_MEMBER( clock_control );
|
||||
uint8_t get_recent_key();
|
||||
|
||||
auto int_cb() { return m_interrupt.bind(); }
|
||||
|
||||
protected:
|
||||
void device_start() override;
|
||||
void device_reset() override;
|
||||
ioport_constructor device_input_ports() const override;
|
||||
void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
|
||||
devcb_write_line m_interrupt; // Keyboard interrupt to console
|
||||
required_ioport_array<8> m_keys;
|
||||
|
||||
private:
|
||||
static constexpr unsigned KEYQUEUESIZE = 256;
|
||||
static constexpr unsigned MAXKEYMSGLENGTH = 10;
|
||||
static constexpr unsigned KEYAUTOREPEATDELAY = 30;
|
||||
static constexpr unsigned KEYAUTOREPEATRATE = 6;
|
||||
|
||||
void post_in_key_queue(int keycode);
|
||||
void signal_when_key_available();
|
||||
void poll();
|
||||
|
||||
bool m_key_reset;
|
||||
int m_key_queue_length;
|
||||
uint8_t m_key_queue[KEYQUEUESIZE];
|
||||
int m_key_queue_head;
|
||||
bool m_key_in_buffer;
|
||||
uint32_t m_key_state_save[4];
|
||||
bool m_key_numlock_state;
|
||||
|
||||
int m_key_ctrl_state;
|
||||
int m_key_alt_state;
|
||||
int m_key_real_shift_state;
|
||||
|
||||
bool m_key_fake_shift_state;
|
||||
bool m_key_fake_unshift_state;
|
||||
|
||||
int m_key_autorepeat_key;
|
||||
int m_key_autorepeat_timer;
|
||||
|
||||
bool m_keep_keybuf;
|
||||
bool m_keyboard_clock;
|
||||
|
||||
emu_timer* m_timer;
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
class geneve_mapper_device : public device_t
|
||||
{
|
||||
public:
|
||||
geneve_mapper_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
geneve_gate_array_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
void set_geneve_mode(bool geneve);
|
||||
void set_direct_mode(bool direct);
|
||||
@ -130,44 +75,24 @@ public:
|
||||
DECLARE_WRITE_LINE_MEMBER( clock_in );
|
||||
DECLARE_WRITE_LINE_MEMBER( dbin_in );
|
||||
|
||||
// Keyboard support
|
||||
DECLARE_WRITE_LINE_MEMBER( set_keyboard_clock );
|
||||
DECLARE_WRITE_LINE_MEMBER( enable_shift_register );
|
||||
DECLARE_WRITE_LINE_MEMBER( kbdclk );
|
||||
DECLARE_WRITE_LINE_MEMBER( kbddata );
|
||||
|
||||
// PFM support
|
||||
DECLARE_WRITE_LINE_MEMBER( pfm_select_lsb );
|
||||
DECLARE_WRITE_LINE_MEMBER( pfm_select_msb );
|
||||
DECLARE_WRITE_LINE_MEMBER( pfm_output_enable );
|
||||
|
||||
auto ready_cb() { return m_ready.bind(); }
|
||||
auto kbdint_cb() { return m_keyint.bind(); }
|
||||
|
||||
protected:
|
||||
geneve_mapper_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
geneve_gate_array_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
void common_reset();
|
||||
|
||||
// GROM simulation
|
||||
bool m_gromwaddr_LSB;
|
||||
bool m_gromraddr_LSB;
|
||||
int m_grom_address;
|
||||
uint8_t read_grom(offs_t offset);
|
||||
void write_grom(offs_t offset, uint8_t data);
|
||||
|
||||
// wait states
|
||||
void set_wait(int min);
|
||||
void set_video_waitcount(int min);
|
||||
bool m_video_waitstates;
|
||||
bool m_extra_waitstates;
|
||||
bool m_ready_asserted;
|
||||
|
||||
bool m_read_mode;
|
||||
|
||||
bool m_debug_no_ws;
|
||||
bool m_geneve_mode;
|
||||
bool m_direct_mode;
|
||||
int m_cartridge_size;
|
||||
bool m_cartridge_secondpage;
|
||||
bool m_cartridge6_writable;
|
||||
bool m_cartridge7_writable;
|
||||
int m_map[8];
|
||||
|
||||
/*
|
||||
Constants for mapper decoding. Naming scheme:
|
||||
M=Mapper, L=Logical space; P=Physical space
|
||||
@ -200,6 +125,39 @@ protected:
|
||||
int wait; // Wait states
|
||||
} decdata;
|
||||
|
||||
uint8_t* m_eprom;
|
||||
int m_pbox_prefix;
|
||||
int m_boot_rom;
|
||||
|
||||
private:
|
||||
void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
// GROM simulation
|
||||
bool m_gromwaddr_LSB;
|
||||
bool m_gromraddr_LSB;
|
||||
int m_grom_address;
|
||||
uint8_t read_grom(offs_t offset);
|
||||
void write_grom(offs_t offset, uint8_t data);
|
||||
|
||||
// wait states
|
||||
void set_wait(int min);
|
||||
void set_video_waitcount(int min);
|
||||
bool m_video_waitstates;
|
||||
bool m_extra_waitstates;
|
||||
bool m_ready_asserted;
|
||||
|
||||
bool m_read_mode;
|
||||
|
||||
bool m_debug_no_ws;
|
||||
bool m_geneve_mode;
|
||||
bool m_direct_mode;
|
||||
int m_cartridge_size;
|
||||
bool m_cartridge_secondpage;
|
||||
bool m_cartridge6_writable;
|
||||
bool m_cartridge7_writable;
|
||||
int m_map[8];
|
||||
|
||||
// The result of decoding
|
||||
decdata m_decoded;
|
||||
|
||||
@ -219,17 +177,6 @@ protected:
|
||||
const char* description; // Good for logging
|
||||
} logentry_t;
|
||||
|
||||
logentry_t m_logmap[7] =
|
||||
{
|
||||
{ 0xf100, 0x000e, 0x8800, 0x03fe, 0x0400, MLVIDEO, "video" },
|
||||
{ 0xf110, 0x0007, 0x8000, 0x0007, 0x0000, MLMAPPER, "mapper" },
|
||||
{ 0xf118, 0x0007, 0x8008, 0x0007, 0x0000, MLKEY, "keyboard" },
|
||||
{ 0xf120, 0x000e, 0x8400, 0x03fe, 0x0000, MLSOUND, "sound" },
|
||||
{ 0xf130, 0x000f, 0x8010, 0x000f, 0x0000, MLCLOCK, "clock" },
|
||||
{ 0x0000, 0x0000, 0x9000, 0x03fe, 0x0400, MBOX, "speech (in P-Box)" },
|
||||
{ 0x0000, 0x0000, 0x9800, 0x03fe, 0x0400, MLGROM, "GROM" },
|
||||
};
|
||||
|
||||
// Static decoder entry for the physical space
|
||||
// There are no differences between native mode and TI mode.
|
||||
typedef struct
|
||||
@ -241,13 +188,8 @@ protected:
|
||||
const char* description; // Good for logging
|
||||
} physentry_t;
|
||||
|
||||
physentry_t m_physmap[4] =
|
||||
{
|
||||
{ 0x000000, 0x07ffff, MPDRAM, 1, "DRAM" },
|
||||
{ 0x080000, 0x07ffff, MPEXP, 1, "on-board expansion" },
|
||||
{ 0x1e0000, 0x01ffff, MPEPROM, 0, "EPROM" },
|
||||
{ 0x180000, 0x07ffff, MPSRAM, 0, "SRAM" }
|
||||
};
|
||||
static const geneve_gate_array_device::logentry_t s_logmap[];
|
||||
static const geneve_gate_array_device::physentry_t s_physmap[];
|
||||
|
||||
void decode_logical(bool reading, decdata* dec);
|
||||
void map_address(bool reading, decdata* dec);
|
||||
@ -258,12 +200,9 @@ protected:
|
||||
// PFM mod (0 = none, 1 = AT29C040, 2 = AT29C040A)
|
||||
uint8_t boot_rom(offs_t offset);
|
||||
void write_to_pfm(offs_t offset, uint8_t data);
|
||||
int m_boot_rom;
|
||||
int m_pfm_bank;
|
||||
bool m_pfm_output_enable;
|
||||
|
||||
int m_pbox_prefix;
|
||||
|
||||
// SRAM access
|
||||
int m_sram_mask;
|
||||
int m_sram_val;
|
||||
@ -271,29 +210,40 @@ protected:
|
||||
// Ready line to the CPU
|
||||
devcb_write_line m_ready;
|
||||
|
||||
// Keyboard interrupt
|
||||
devcb_write_line m_keyint;
|
||||
|
||||
// Counter for the wait states.
|
||||
int m_waitcount;
|
||||
int m_video_waitcount;
|
||||
|
||||
// Keyboard support
|
||||
uint16_t m_keyboard_shift_reg;
|
||||
line_state m_keyboard_last_clock;
|
||||
line_state m_keyboard_data_in;
|
||||
bool m_shift_reg_enabled;
|
||||
void shift_reg_changed();
|
||||
|
||||
// Devices
|
||||
required_device<mm58274c_device> m_clock;
|
||||
required_device<tms9995_device> m_cpu;
|
||||
required_device<sn76496_base_device> m_sound;
|
||||
required_device<v9938_device> m_video;
|
||||
required_device<mm58274c_device> m_rtc;
|
||||
required_device<ram_device> m_sram;
|
||||
required_device<ram_device> m_dram;
|
||||
|
||||
required_device<bus::ti99::peb::peribox_device> m_peribox;
|
||||
|
||||
required_device<at29c040_device> m_pfm512;
|
||||
required_device<at29c040a_device> m_pfm512a;
|
||||
required_device<sn76496_base_device> m_sound;
|
||||
|
||||
required_device<bus::ti99::internal::geneve_keyboard_device> m_keyboard;
|
||||
required_device<v9938_device> m_video;
|
||||
required_device<bus::ti99::peb::peribox_device> m_peribox;
|
||||
uint8_t* m_eprom;
|
||||
required_device<ram_device> m_sram;
|
||||
required_device<ram_device> m_dram;
|
||||
required_device<pc_kbdc_device> m_keyb_conn;
|
||||
};
|
||||
|
||||
class genmod_mapper_device : public geneve_mapper_device
|
||||
class genmod_gate_array_device : public geneve_gate_array_device
|
||||
{
|
||||
public:
|
||||
genmod_mapper_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
genmod_gate_array_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
void decode_mod(decdata* dec) override;
|
||||
void device_reset() override;
|
||||
DECLARE_INPUT_CHANGED_MEMBER( setgm_changed );
|
||||
@ -306,8 +256,7 @@ private:
|
||||
|
||||
} } } // end namespace bus::ti99::internal
|
||||
|
||||
DECLARE_DEVICE_TYPE_NS(GENEVE_KEYBOARD, bus::ti99::internal, geneve_keyboard_device)
|
||||
DECLARE_DEVICE_TYPE_NS(GENEVE_MAPPER, bus::ti99::internal, geneve_mapper_device)
|
||||
DECLARE_DEVICE_TYPE_NS(GENMOD_MAPPER, bus::ti99::internal, genmod_mapper_device)
|
||||
DECLARE_DEVICE_TYPE_NS(GENEVE_GATE_ARRAY, bus::ti99::internal, geneve_gate_array_device)
|
||||
DECLARE_DEVICE_TYPE_NS(GENMOD_GATE_ARRAY, bus::ti99::internal, genmod_gate_array_device)
|
||||
|
||||
#endif // MAME_BUS_TI99_INTERNAL_GENBOARD_H
|
||||
|
648
src/devices/bus/ti99/internal/genkbd.cpp
Normal file
648
src/devices/bus/ti99/internal/genkbd.cpp
Normal file
@ -0,0 +1,648 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Michael Zapf
|
||||
/**********************************************************************
|
||||
|
||||
Geneve 9640 101-key XT/AT keyboard (High-level emulation)
|
||||
|
||||
Geneves may use any XT keyboard; some were delivered with a 101-key XT/AT
|
||||
keyboard.
|
||||
|
||||
This is a high-level emulation in the sense that it is only emulated
|
||||
from its behavior, not from its actual chipset. This will be done as
|
||||
soon as we have a ROM dump.
|
||||
|
||||
Although the keyboard is switchable between XT and AT mode, we will
|
||||
only emulate the XT mode here.
|
||||
|
||||
The code is copied from the previous implementation in genboard.cpp
|
||||
and appropriately adapted to use the pc_kbd interface.
|
||||
|
||||
The XT keyboard interface is described in various places on the internet.
|
||||
It does not comply with the PS2 protocol. The keyboard transmits 8-bit
|
||||
scancodes serially with one (1) or two (0,1) start bits, LSB to MSB,
|
||||
no parity and no stop bits. Each bit is read into the shift register
|
||||
when the clock line is pulled low by the keyboard.
|
||||
|
||||
MZ, August 2019
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "genkbd.h"
|
||||
|
||||
#define LOG_WARN (1U<<1)
|
||||
#define LOG_QUEUE (1U<<2)
|
||||
#define LOG_TRANSFER (1U<<3)
|
||||
#define LOG_LINES (1U<<4)
|
||||
|
||||
#define VERBOSE ( LOG_GENERAL | LOG_WARN )
|
||||
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(KBD_GENEVE_XT_101_HLE, geneve_xt_101_hle_keyboard_device, "kb_geneve_hle", "Geneve XT Keyboard 101 Keys (HLE)")
|
||||
|
||||
INPUT_PORTS_START( geneve_xt_101_hle_keyboard )
|
||||
PORT_START("KEY0") /* IN3 */
|
||||
PORT_BIT(0x0001, 0x0000, IPT_UNUSED ) /* unused scancode 0 */
|
||||
PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CODE(KEYCODE_ESC) /* Esc 01 81 */
|
||||
PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) /* 1 02 82 */
|
||||
PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("2 @") PORT_CODE(KEYCODE_2) /* 2 03 83 */
|
||||
PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("3 #") PORT_CODE(KEYCODE_3) /* 3 04 84 */
|
||||
PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) /* 4 05 85 */
|
||||
PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) /* 5 06 86 */
|
||||
PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("6 ^") PORT_CODE(KEYCODE_6) /* 6 07 87 */
|
||||
PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("7 &") PORT_CODE(KEYCODE_7) /* 7 08 88 */
|
||||
PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("8 *") PORT_CODE(KEYCODE_8) /* 8 09 89 */
|
||||
PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("9 (") PORT_CODE(KEYCODE_9) /* 9 0A 8A */
|
||||
PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("0 )") PORT_CODE(KEYCODE_0) /* 0 0B 8B */
|
||||
PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("- _") PORT_CODE(KEYCODE_MINUS) /* - 0C 8C */
|
||||
PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("= +") PORT_CODE(KEYCODE_EQUALS) /* = 0D 8D */
|
||||
PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) /* Backspace 0E 8E */
|
||||
PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) /* Tab 0F 8F */
|
||||
|
||||
PORT_START("KEY1") /* IN4 */
|
||||
PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) /* Q 10 90 */
|
||||
PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) /* W 11 91 */
|
||||
PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) /* E 12 92 */
|
||||
PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) /* R 13 93 */
|
||||
PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) /* T 14 94 */
|
||||
PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) /* Y 15 95 */
|
||||
PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) /* U 16 96 */
|
||||
PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) /* I 17 97 */
|
||||
PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) /* O 18 98 */
|
||||
PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) /* P 19 99 */
|
||||
PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("[ {") PORT_CODE(KEYCODE_OPENBRACE) /* [ 1A 9A */
|
||||
PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("] }") PORT_CODE(KEYCODE_CLOSEBRACE) /* ] 1B 9B */
|
||||
PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER) /* Enter 1C 9C */
|
||||
PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("L-Ctrl") PORT_CODE(KEYCODE_LCONTROL) /* LCtrl 1D 9D */
|
||||
PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) /* A 1E 9E */
|
||||
PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) /* S 1F 9F */
|
||||
|
||||
PORT_START("KEY2") /* IN5 */
|
||||
PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) /* D 20 A0 */
|
||||
PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) /* F 21 A1 */
|
||||
PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) /* G 22 A2 */
|
||||
PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) /* H 23 A3 */
|
||||
PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) /* J 24 A4 */
|
||||
PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) /* K 25 A5 */
|
||||
PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) /* L 26 A6 */
|
||||
PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("; :") PORT_CODE(KEYCODE_COLON) /* ; 27 A7 */
|
||||
PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("' \"") PORT_CODE(KEYCODE_QUOTE) /* ' 28 A8 */
|
||||
PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("` ~") PORT_CODE(KEYCODE_TILDE) /* ` 29 A9 */
|
||||
PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("L-Shift") PORT_CODE(KEYCODE_LSHIFT) /* LShift 2A AA */
|
||||
PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("\\ |") PORT_CODE(KEYCODE_BACKSLASH) /* \ 2B AB */
|
||||
PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) /* Z 2C AC */
|
||||
PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) /* X 2D AD */
|
||||
PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) /* C 2E AE */
|
||||
PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) /* V 2F AF */
|
||||
|
||||
PORT_START("KEY3") /* IN6 */
|
||||
PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) /* B 30 B0 */
|
||||
PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) /* N 31 B1 */
|
||||
PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) /* M 32 B2 */
|
||||
PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) /* , 33 B3 */
|
||||
PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP) /* . 34 B4 */
|
||||
PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) /* / 35 B5 */
|
||||
PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("R-Shift") PORT_CODE(KEYCODE_RSHIFT) /* RShift 36 B6 */
|
||||
PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP * (PrtScr)") PORT_CODE(KEYCODE_ASTERISK ) /* KP * (PrtSc) 37 B7 */
|
||||
PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Alt") PORT_CODE(KEYCODE_LALT) /* LAlt 38 B8 */
|
||||
PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) /* Space 39 B9 */
|
||||
PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Caps") PORT_CODE(KEYCODE_CAPSLOCK) /* Caps Lock 3A BA */
|
||||
PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) /* F1 3B BB */
|
||||
PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) /* F2 3C BC */
|
||||
PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) /* F3 3D BD */
|
||||
PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F4") PORT_CODE(KEYCODE_F4) /* F4 3E BE */
|
||||
PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F5") PORT_CODE(KEYCODE_F5) /* F5 3F BF */
|
||||
|
||||
PORT_START("KEY4") /* IN7 */
|
||||
PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F6") PORT_CODE(KEYCODE_F6) /* F6 40 C0 */
|
||||
PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F7") PORT_CODE(KEYCODE_F7) /* F7 41 C1 */
|
||||
PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F8") PORT_CODE(KEYCODE_F8) /* F8 42 C2 */
|
||||
PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F9") PORT_CODE(KEYCODE_F9) /* F9 43 C3 */
|
||||
PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F10") PORT_CODE(KEYCODE_F10) /* F10 44 C4 */
|
||||
PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("NumLock") PORT_CODE(KEYCODE_NUMLOCK) /* Num Lock 45 C5 */
|
||||
PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ScrLock (F14)") PORT_CODE(KEYCODE_SCRLOCK) /* Scroll Lock 46 C6 */
|
||||
PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 7 (Home)") PORT_CODE(KEYCODE_7_PAD) /* KP 7 (Home) 47 C7 */
|
||||
PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 8 (Up)") PORT_CODE(KEYCODE_8_PAD) /* KP 8 (Up) 48 C8 */
|
||||
PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 9 (PgUp)") PORT_CODE(KEYCODE_9_PAD) /* KP 9 (PgUp) 49 C9 */
|
||||
PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP -") PORT_CODE(KEYCODE_MINUS_PAD) /* KP - 4A CA */
|
||||
PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 4 (Left)") PORT_CODE(KEYCODE_4_PAD) /* KP 4 (Left) 4B CB */
|
||||
PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 5") PORT_CODE(KEYCODE_5_PAD) /* KP 5 4C CC */
|
||||
PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 6 (Right)") PORT_CODE(KEYCODE_6_PAD) /* KP 6 (Right)4D CD */
|
||||
PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP +") PORT_CODE(KEYCODE_PLUS_PAD) /* KP + 4E CE */
|
||||
PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 1 (End)") PORT_CODE(KEYCODE_1_PAD) /* KP 1 (End) 4F CF */
|
||||
|
||||
PORT_START("KEY5") /* IN8 */
|
||||
PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 2 (Down)") PORT_CODE(KEYCODE_2_PAD) /* KP 2 (Down) 50 D0 */
|
||||
PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 3 (PgDn)") PORT_CODE(KEYCODE_3_PAD) /* KP 3 (PgDn) 51 D1 */
|
||||
PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 0 (Ins)") PORT_CODE(KEYCODE_0_PAD) /* KP 0 (Ins) 52 D2 */
|
||||
PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP . (Del)") PORT_CODE(KEYCODE_DEL_PAD) /* KP . (Del) 53 D3 */
|
||||
PORT_BIT ( 0x0030, 0x0000, IPT_UNUSED )
|
||||
PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(84/102)\\") PORT_CODE(KEYCODE_BACKSLASH2) /* Backslash 2 56 D6 */
|
||||
PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(101)F11") PORT_CODE(KEYCODE_F11) /* F11 57 D7 */
|
||||
PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(101)F12") PORT_CODE(KEYCODE_F12) /* F12 58 D8 */
|
||||
PORT_BIT ( 0xfe00, 0x0000, IPT_UNUSED )
|
||||
|
||||
PORT_START("KEY6") /* IN9 */
|
||||
PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(101)KP Enter") PORT_CODE(KEYCODE_ENTER_PAD) /* KP Enter 60 e0 */
|
||||
PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(101)R-Control") PORT_CODE(KEYCODE_RCONTROL) /* RCtrl 61 e1 */
|
||||
PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(101)AltGr") PORT_CODE(KEYCODE_RALT) /* AltGr 64 e4 */
|
||||
|
||||
PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(101)KP /") PORT_CODE(KEYCODE_SLASH_PAD) /* KP Slash 62 e2 */
|
||||
|
||||
PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(101)Home") PORT_CODE(KEYCODE_HOME) /* Home 66 e6 */
|
||||
PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(101)Cursor Up") PORT_CODE(KEYCODE_UP) /* Up 67 e7 */
|
||||
PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(101)Page Up") PORT_CODE(KEYCODE_PGUP) /* Page Up 68 e8 */
|
||||
PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(101)Cursor Left") PORT_CODE(KEYCODE_LEFT) /* Left 69 e9 */
|
||||
PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(101)Cursor Right") PORT_CODE(KEYCODE_RIGHT) /* Right 6a ea */
|
||||
PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(101)End") PORT_CODE(KEYCODE_END) /* End 6b eb */
|
||||
PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(101)Cursor Down") PORT_CODE(KEYCODE_DOWN) /* Down 6c ec */
|
||||
PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(101)Page Down") PORT_CODE(KEYCODE_PGDN) /* Page Down 6d ed */
|
||||
PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(101)Insert") PORT_CODE(KEYCODE_INSERT) /* Insert 6e ee */
|
||||
PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(101)Delete") PORT_CODE(KEYCODE_DEL) /* Delete 6f ef */
|
||||
|
||||
PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(101)PrtScr (F13)") PORT_CODE(KEYCODE_PRTSCR) /* Print Screen 63 e3 */
|
||||
PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(101)Pause (F15)") PORT_CODE(KEYCODE_PAUSE) /* Pause 65 e5 */
|
||||
|
||||
PORT_START("KEY7") /* IN10 */
|
||||
PORT_BIT ( 0xffff, 0x0000, IPT_UNUSED )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// input_ports - device-specific input ports
|
||||
//-------------------------------------------------
|
||||
|
||||
ioport_constructor geneve_xt_101_hle_keyboard_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME( geneve_xt_101_hle_keyboard );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// ibm_pc_xt_83_keyboard_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
geneve_xt_101_hle_keyboard_device::geneve_xt_101_hle_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, KBD_GENEVE_XT_101_HLE, tag, owner, clock),
|
||||
device_pc_kbd_interface(mconfig, *this),
|
||||
m_keys(*this, "KEY%u", 0),
|
||||
m_queue_length(0),
|
||||
m_autorepeat_code(0),
|
||||
m_autorepeat_timer(0),
|
||||
m_fake_shift_state(false),
|
||||
m_fake_unshift_state(false),
|
||||
m_resetting(false),
|
||||
m_clock_line(ASSERT_LINE),
|
||||
m_data_line(ASSERT_LINE)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
Called by the poll timer
|
||||
*/
|
||||
void geneve_xt_101_hle_keyboard_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
if (id==0)
|
||||
{
|
||||
poll();
|
||||
send_key();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (id==1)
|
||||
{
|
||||
// Send timer
|
||||
if (m_shift_count==10)
|
||||
{
|
||||
// Done, all sent
|
||||
m_pc_kbdc->clock_write_from_kb(1);
|
||||
m_pc_kbdc->data_write_from_kb(1);
|
||||
m_send_timer->reset();
|
||||
m_shift_count = 0;
|
||||
|
||||
// Adjust the queue
|
||||
m_queue_head = (m_queue_head + 1) % KEYQUEUESIZE;
|
||||
m_queue_length--;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pc_kbdc->clock_write_from_kb(1);
|
||||
m_pc_kbdc->data_write_from_kb(m_shift_reg&1);
|
||||
m_pc_kbdc->clock_write_from_kb(0);
|
||||
m_shift_reg>>=1;
|
||||
m_shift_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Translations
|
||||
*/
|
||||
static const uint8_t MF1_CODE[0xe] =
|
||||
{
|
||||
// Extended keys that are equivalent to non-extended keys
|
||||
0x1c, // KP Enter -> Return
|
||||
0x1d, // RCtrl -> LCtrl
|
||||
0x38, // AltGr -> LAlt
|
||||
|
||||
// Extended key that is equivalent to a non-extended key with shift off
|
||||
0x35, // KP / -> /
|
||||
|
||||
// Extended keys that are equivalent to non-extended keys with numlock off
|
||||
0x47, // Home -> KP 7 (Home)
|
||||
0x48, // Up -> KP 8 (Up)
|
||||
0x49, // Page up -> KP 9 (PgUp)
|
||||
0x4b, // Left -> KP 4 (Left)
|
||||
0x4d, // Right -> KP 6 (Right)
|
||||
0x4f, // End -> KP 1 (End)
|
||||
0x50, // Down -> KP 2 (Down)
|
||||
0x51, // Page dn -> KP 3 (PgDn)
|
||||
0x52, // Insert -> KP 0 (Ins)
|
||||
0x53 // Delete -> KP . (Del)
|
||||
};
|
||||
|
||||
void geneve_xt_101_hle_keyboard_device::poll()
|
||||
{
|
||||
uint32_t keystate;
|
||||
uint32_t key_transitions;
|
||||
uint32_t mask;
|
||||
bool pressed = false;
|
||||
int keycode = 0;
|
||||
|
||||
if (m_resetting) return;
|
||||
|
||||
// We're testing two 16-bit ports at once
|
||||
// but only if we have enough space in the queue
|
||||
for (int i=0; (i < 4) && (m_queue_length <= (KEYQUEUESIZE-MAXKEYMSGLENGTH)); i++)
|
||||
{
|
||||
// Get those two ports and calculate the difference
|
||||
keystate = m_keys[2*i]->read() | (m_keys[2*i + 1]->read() << 16);
|
||||
key_transitions = keystate ^ m_key_state_save[i];
|
||||
if (key_transitions != 0)
|
||||
{
|
||||
mask = 0x00000001;
|
||||
// Some key(s) has/have changed (pressed/released)
|
||||
for (int j=0; (j < 32) && (m_queue_length <= (KEYQUEUESIZE-MAXKEYMSGLENGTH)); j++)
|
||||
{
|
||||
if ((key_transitions & mask)!=0)
|
||||
{
|
||||
// Found one changed key (i is a 32-key block)
|
||||
keycode = (i<<5) | j;
|
||||
pressed = (keystate & mask)!=0;
|
||||
|
||||
// Auto-repeat
|
||||
if (pressed)
|
||||
{
|
||||
m_autorepeat_code = keycode;
|
||||
m_autorepeat_timer = KEYAUTOREPEATDELAY+1;
|
||||
m_key_state_save[i] |= mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_autorepeat_code = 0;
|
||||
m_key_state_save[i] &= ~mask;
|
||||
}
|
||||
|
||||
// We are here because the set of pressed keys has changed
|
||||
// In the case that we have a fake shift/unshift,
|
||||
// we have to release it.
|
||||
|
||||
if (m_fake_shift_state)
|
||||
{
|
||||
/* Fake shift release */
|
||||
post_in_key_queue(0xe0);
|
||||
post_in_key_queue(0xaa);
|
||||
m_fake_shift_state = false;
|
||||
}
|
||||
if (m_fake_unshift_state)
|
||||
{
|
||||
/* Fake shift press */
|
||||
post_in_key_queue(0xe0);
|
||||
post_in_key_queue(0x2a);
|
||||
m_fake_unshift_state = false;
|
||||
}
|
||||
|
||||
switch (keycode)
|
||||
{
|
||||
case 0x2a:
|
||||
m_left_shift = pressed;
|
||||
break;
|
||||
case 0x36:
|
||||
m_right_shift = pressed;
|
||||
break;
|
||||
case 0x1d:
|
||||
m_left_ctrl = pressed;
|
||||
break;
|
||||
case 0x61:
|
||||
m_right_ctrl = pressed;
|
||||
break;
|
||||
case 0x38:
|
||||
m_left_alt = pressed;
|
||||
break;
|
||||
case 0x62:
|
||||
m_altgr = pressed;
|
||||
break;
|
||||
case 0x45:
|
||||
if (pressed) m_numlock = !m_numlock;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Extended keycodes
|
||||
if ((keycode >= 0x60) && (keycode < 0x6e))
|
||||
{
|
||||
if ((keycode >= 0x63) && pressed)
|
||||
{
|
||||
// Handle shift state
|
||||
if (keycode == 0x63) // Slash
|
||||
{
|
||||
if (m_left_shift || m_right_shift)
|
||||
{
|
||||
// Fake shift unpress
|
||||
m_fake_unshift_state = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Key function with NumLock=0
|
||||
if (m_numlock && (!m_left_shift) && (!m_right_shift))
|
||||
{
|
||||
// Fake shift press if numlock is active
|
||||
m_fake_shift_state = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((!m_numlock) && (m_left_shift || m_right_shift))
|
||||
{
|
||||
// Fake shift unpress if shift is down
|
||||
m_fake_unshift_state = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_fake_shift_state)
|
||||
{
|
||||
post_in_key_queue(0xe0);
|
||||
post_in_key_queue(0x2a);
|
||||
}
|
||||
|
||||
if (m_fake_unshift_state)
|
||||
{
|
||||
post_in_key_queue(0xe0);
|
||||
post_in_key_queue(0xaa);
|
||||
}
|
||||
}
|
||||
keycode = MF1_CODE[keycode-0x60];
|
||||
if (!pressed) keycode |= 0x80;
|
||||
post_in_key_queue(0xe0);
|
||||
post_in_key_queue(keycode);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (keycode == 0x6e)
|
||||
{
|
||||
// Emulate Print Screen / System Request (F13) key
|
||||
// this is a bit complex, as Alt+PrtScr -> SysRq
|
||||
// Additionally, Ctrl+PrtScr involves no fake shift press
|
||||
if (m_left_alt || m_altgr)
|
||||
{
|
||||
// SysRq
|
||||
keycode = 0x54;
|
||||
if (!pressed) keycode |= 0x80;
|
||||
post_in_key_queue(keycode);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handle shift state
|
||||
if (pressed && (!m_left_shift) && (!m_right_shift) && (!m_left_ctrl) && (!m_right_ctrl))
|
||||
{ // Fake shift press
|
||||
post_in_key_queue(0xe0);
|
||||
post_in_key_queue(0x2a);
|
||||
m_fake_shift_state = true;
|
||||
}
|
||||
|
||||
keycode = 0x37;
|
||||
if (!pressed) keycode |= 0x80;
|
||||
post_in_key_queue(0xe0);
|
||||
post_in_key_queue(keycode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (keycode == 0x6f)
|
||||
{
|
||||
// Emulate pause (F15) key
|
||||
// This is a bit complex, as Pause -> Ctrl+NumLock and
|
||||
// Ctrl+Pause -> Ctrl+ScrLock.
|
||||
// Furthermore, there is no repeat or release.
|
||||
if (pressed)
|
||||
{
|
||||
if (m_left_ctrl || m_right_ctrl)
|
||||
{
|
||||
post_in_key_queue(0xe0);
|
||||
post_in_key_queue(0x46);
|
||||
post_in_key_queue(0xe0);
|
||||
post_in_key_queue(0xc6);
|
||||
}
|
||||
else
|
||||
{
|
||||
post_in_key_queue(0xe1);
|
||||
post_in_key_queue(0x1d);
|
||||
post_in_key_queue(0x45);
|
||||
post_in_key_queue(0xe1);
|
||||
post_in_key_queue(0x9d);
|
||||
post_in_key_queue(0xc5);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!pressed) keycode |= 0x80;
|
||||
post_in_key_queue(keycode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
mask <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Implement auto repeat
|
||||
if (m_autorepeat_code != 0)
|
||||
{
|
||||
m_autorepeat_timer--;
|
||||
if ((m_autorepeat_timer == 0) && (m_queue_length <= (KEYQUEUESIZE-MAXKEYMSGLENGTH)))
|
||||
{
|
||||
// Extended code
|
||||
if ((m_autorepeat_code >= 0x60) && (m_autorepeat_code < 0x6e))
|
||||
{
|
||||
post_in_key_queue(0xe0);
|
||||
post_in_key_queue(MF1_CODE[m_autorepeat_code-0x60]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_autorepeat_code == 0x6e)
|
||||
{
|
||||
if (m_left_alt || m_altgr)
|
||||
{
|
||||
post_in_key_queue(0x54); // SysRq
|
||||
}
|
||||
else
|
||||
{
|
||||
post_in_key_queue(0xe0);
|
||||
post_in_key_queue(0x37); // PrtScr
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_autorepeat_code != 0x6f) // Pause cannot do an auto-repeat
|
||||
{
|
||||
post_in_key_queue(m_autorepeat_code);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_autorepeat_timer = KEYAUTOREPEATRATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void geneve_xt_101_hle_keyboard_device::send_key()
|
||||
{
|
||||
if (m_clock_line == CLEAR_LINE)
|
||||
{
|
||||
m_reset_timer--;
|
||||
if (m_reset_timer==0)
|
||||
{
|
||||
LOG("Reset triggered\n");
|
||||
reset_line(0);
|
||||
reset_line(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_data_line==1)
|
||||
{
|
||||
// Dequeue a key
|
||||
if (m_queue_length != 0)
|
||||
{
|
||||
LOGMASKED(LOG_TRANSFER, "Send keycode %02x\n", m_queue[m_queue_head]);
|
||||
// Get the next key, add the two start bits to the right (0,1)
|
||||
m_shift_reg = (m_queue[m_queue_head] << 2) | 0x02;
|
||||
m_send_timer->adjust(attotime::from_usec(1), 0, attotime::from_hz(10000));
|
||||
}
|
||||
}
|
||||
else
|
||||
LOGMASKED(LOG_TRANSFER, "Transfer blocked by data=0 from host\n");
|
||||
}
|
||||
}
|
||||
|
||||
void geneve_xt_101_hle_keyboard_device::post_in_key_queue(int keycode)
|
||||
{
|
||||
m_queue[(m_queue_head + m_queue_length) % KEYQUEUESIZE] = keycode;
|
||||
m_queue_length++;
|
||||
|
||||
LOGMASKED(LOG_QUEUE, "Enqueue keycode %02x, queue length=%d\n", keycode, m_queue_length);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// clock_write -
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( geneve_xt_101_hle_keyboard_device::clock_write )
|
||||
{
|
||||
LOGMASKED(LOG_LINES, "Clock write: %d\n", state);
|
||||
m_clock_line = (line_state)state;
|
||||
if (m_clock_line == CLEAR_LINE)
|
||||
{
|
||||
if (m_reset_timer == -1)
|
||||
m_reset_timer = 3; // 25 ms
|
||||
}
|
||||
else
|
||||
m_reset_timer = -1;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// data_write -
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( geneve_xt_101_hle_keyboard_device::data_write )
|
||||
{
|
||||
LOGMASKED(LOG_LINES, "Data write: %d\n", state);
|
||||
m_data_line = (line_state)state;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void geneve_xt_101_hle_keyboard_device::device_start()
|
||||
{
|
||||
set_pc_kbdc_device();
|
||||
m_poll_timer = timer_alloc(0);
|
||||
m_send_timer = timer_alloc(1);
|
||||
|
||||
// state saving
|
||||
save_item(NAME(m_queue_length));
|
||||
save_item(NAME(m_queue_head));
|
||||
save_pointer(NAME(m_key_state_save),4);
|
||||
save_pointer(NAME(m_queue),KEYQUEUESIZE);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void geneve_xt_101_hle_keyboard_device::device_reset()
|
||||
{
|
||||
// Trigger our reset line
|
||||
reset_line(0);
|
||||
reset_line(1);
|
||||
m_poll_timer->adjust(attotime::from_usec(1), 0, attotime::from_hz(120));
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER( geneve_xt_101_hle_keyboard_device::reset_line )
|
||||
{
|
||||
m_resetting = (state==0);
|
||||
|
||||
if (m_resetting)
|
||||
{
|
||||
// Reset -> clear keyboard key queue
|
||||
m_reset_timer = -1;
|
||||
m_queue_length = 0;
|
||||
m_queue_head = 0;
|
||||
memset(m_key_state_save, 0, sizeof(m_key_state_save));
|
||||
|
||||
m_numlock = false;
|
||||
m_left_shift = false;
|
||||
m_right_shift = false;
|
||||
m_left_ctrl = false;
|
||||
m_right_ctrl = false;
|
||||
m_left_alt = false;
|
||||
m_altgr = false;
|
||||
|
||||
m_fake_shift_state = false;
|
||||
m_fake_unshift_state = false;
|
||||
m_autorepeat_code = 0;
|
||||
|
||||
m_shift_reg = 0;
|
||||
m_shift_count = 0;
|
||||
|
||||
// Send the BAT (Basic assurance test) OK value (AA)
|
||||
post_in_key_queue(0xaa);
|
||||
}
|
||||
}
|
||||
|
89
src/devices/bus/ti99/internal/genkbd.h
Normal file
89
src/devices/bus/ti99/internal/genkbd.h
Normal file
@ -0,0 +1,89 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Michael Zapf
|
||||
/**********************************************************************
|
||||
|
||||
Geneve 9640 101-key XT/AT keyboard (High-level emulation)
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef MAME_BUS_TI99_INTERNAL_GENKBD_H
|
||||
#define MAME_BUS_TI99_INTERNAL_GENKBD_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bus/pc_kbd/pc_kbdc.h"
|
||||
|
||||
#define STR_KBD_GENEVE_XT_101_HLE "geneve_kb_101"
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> geneve_xt_101_hle_keyboard_device
|
||||
|
||||
class geneve_xt_101_hle_keyboard_device : public device_t, public device_pc_kbd_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
geneve_xt_101_hle_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
DECLARE_WRITE_LINE_MEMBER( reset_line );
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
void device_start() override;
|
||||
void device_reset() override;
|
||||
ioport_constructor device_input_ports() const override;
|
||||
|
||||
// device_pc_kbd_interface overrides
|
||||
DECLARE_WRITE_LINE_MEMBER( clock_write ) override;
|
||||
DECLARE_WRITE_LINE_MEMBER( data_write ) override;
|
||||
|
||||
private:
|
||||
emu_timer *m_poll_timer;
|
||||
emu_timer *m_send_timer;
|
||||
|
||||
void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
|
||||
static constexpr unsigned KEYQUEUESIZE = 256;
|
||||
static constexpr unsigned MAXKEYMSGLENGTH = 10;
|
||||
static constexpr unsigned KEYAUTOREPEATDELAY = 30;
|
||||
static constexpr unsigned KEYAUTOREPEATRATE = 6;
|
||||
|
||||
void poll();
|
||||
void send_key();
|
||||
void post_in_key_queue(int key);
|
||||
|
||||
required_ioport_array<8> m_keys;
|
||||
|
||||
int m_queue_length;
|
||||
int m_queue_head;
|
||||
uint8_t m_queue[KEYQUEUESIZE];
|
||||
uint32_t m_key_state_save[4];
|
||||
int m_autorepeat_code;
|
||||
int m_autorepeat_timer;
|
||||
bool m_fake_shift_state;
|
||||
bool m_fake_unshift_state;
|
||||
|
||||
bool m_left_shift;
|
||||
bool m_right_shift;
|
||||
bool m_left_ctrl;
|
||||
bool m_right_ctrl;
|
||||
bool m_left_alt;
|
||||
bool m_altgr;
|
||||
bool m_numlock;
|
||||
|
||||
bool m_resetting;
|
||||
|
||||
line_state m_clock_line;
|
||||
line_state m_data_line;
|
||||
int m_reset_timer;
|
||||
|
||||
int m_shift_reg;
|
||||
int m_shift_count;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(KBD_GENEVE_XT_101_HLE, geneve_xt_101_hle_keyboard_device)
|
||||
|
||||
#endif // MAME_BUS_TI99_INTERNAL_GENKBD_H
|
@ -190,23 +190,38 @@
|
||||
#include "sound/sn76496.h"
|
||||
|
||||
#include "bus/ti99/internal/genboard.h"
|
||||
#include "bus/ti99/internal/genkbd.h"
|
||||
|
||||
#include "bus/ti99/colorbus/colorbus.h"
|
||||
#include "bus/ti99/joyport/joyport.h"
|
||||
#include "bus/ti99/peb/peribox.h"
|
||||
|
||||
#include "bus/pc_kbd/keyboards.h"
|
||||
#include "bus/pc_kbd/pc_kbdc.h"
|
||||
#include "bus/pc_kbd/pcxt83.h"
|
||||
#include "bus/pc_kbd/keytro.h"
|
||||
|
||||
#include "speaker.h"
|
||||
|
||||
#define LOG_WARN (1U<<1)
|
||||
#define LOG_READY (1U<<2)
|
||||
#define LOG_LINES (1U<<3)
|
||||
#define LOG_CRU (1U<<4)
|
||||
#define LOG_CRUKEY (1U<<5)
|
||||
|
||||
// Minimum log should be settings and warnings
|
||||
#define VERBOSE ( LOG_GENERAL | LOG_WARN )
|
||||
|
||||
#include "logmacro.h"
|
||||
|
||||
|
||||
void geneve_xt_keyboards(device_slot_interface &device)
|
||||
{
|
||||
device.option_add(STR_KBD_KEYTRONIC_PC3270, PC_KBD_KEYTRONIC_PC3270);
|
||||
device.option_add(STR_KBD_IBM_PC_XT_83, PC_KBD_IBM_PC_XT_83);
|
||||
device.option_add(STR_KBD_GENEVE_XT_101_HLE, KBD_GENEVE_XT_101_HLE);
|
||||
}
|
||||
|
||||
class geneve_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -214,11 +229,11 @@ public:
|
||||
: driver_device(mconfig, type, tag),
|
||||
m_cpu(*this, "maincpu"),
|
||||
m_tms9901(*this, TI_TMS9901_TAG),
|
||||
m_keyboard(*this, GENEVE_KEYBOARD_TAG),
|
||||
m_mapper(*this, GENEVE_MAPPER_TAG),
|
||||
m_gatearray(*this, GENEVE_GATE_ARRAY_TAG),
|
||||
m_peribox(*this, TI_PERIBOX_TAG),
|
||||
m_joyport(*this, TI_JOYPORT_TAG),
|
||||
m_colorbus(*this, COLORBUS_TAG),
|
||||
m_kbdconn(*this, GENEVE_KEYBOARD_CONN_TAG),
|
||||
m_left_button(0)
|
||||
{
|
||||
}
|
||||
@ -240,9 +255,13 @@ private:
|
||||
DECLARE_WRITE_LINE_MEMBER(VDP_reset);
|
||||
DECLARE_WRITE_LINE_MEMBER(joystick_select);
|
||||
DECLARE_WRITE_LINE_MEMBER(extbus_wait_states);
|
||||
DECLARE_WRITE_LINE_MEMBER(keyboard_reset);
|
||||
DECLARE_WRITE_LINE_MEMBER(video_wait_states);
|
||||
DECLARE_WRITE_LINE_MEMBER(left_mouse_button);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(keyboard_clock_line);
|
||||
DECLARE_WRITE_LINE_MEMBER(keyboard_data_line);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(clock_out);
|
||||
|
||||
void external_operation(offs_t offset, uint8_t data);
|
||||
@ -253,16 +272,17 @@ private:
|
||||
|
||||
required_device<tms9995_device> m_cpu;
|
||||
required_device<tms9901_device> m_tms9901;
|
||||
required_device<bus::ti99::internal::geneve_keyboard_device> m_keyboard;
|
||||
required_device<bus::ti99::internal::geneve_mapper_device> m_mapper;
|
||||
required_device<bus::ti99::peb::peribox_device> m_peribox;
|
||||
required_device<bus::ti99::joyport::joyport_device> m_joyport;
|
||||
required_device<bus::ti99::internal::geneve_gate_array_device> m_gatearray;
|
||||
required_device<bus::ti99::peb::peribox_device> m_peribox;
|
||||
required_device<bus::ti99::joyport::joyport_device> m_joyport;
|
||||
required_device<bus::ti99::colorbus::v9938_colorbus_device> m_colorbus;
|
||||
required_device<pc_kbdc_device> m_kbdconn;
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER( inta );
|
||||
DECLARE_WRITE_LINE_MEMBER( intb );
|
||||
DECLARE_WRITE_LINE_MEMBER( ext_ready );
|
||||
DECLARE_WRITE_LINE_MEMBER( mapper_ready );
|
||||
DECLARE_WRITE_LINE_MEMBER( keyboard_int );
|
||||
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
@ -291,12 +311,12 @@ private:
|
||||
|
||||
void geneve_state::memmap(address_map &map)
|
||||
{
|
||||
map(0x0000, 0xffff).rw(GENEVE_MAPPER_TAG, FUNC(bus::ti99::internal::geneve_mapper_device::readm), FUNC(bus::ti99::internal::geneve_mapper_device::writem));
|
||||
map(0x0000, 0xffff).rw(GENEVE_GATE_ARRAY_TAG, FUNC(bus::ti99::internal::geneve_gate_array_device::readm), FUNC(bus::ti99::internal::geneve_gate_array_device::writem));
|
||||
}
|
||||
|
||||
void geneve_state::memmap_setaddress(address_map &map)
|
||||
{
|
||||
map(0x0000, 0xffff).w(GENEVE_MAPPER_TAG, FUNC(bus::ti99::internal::geneve_mapper_device::setaddress));
|
||||
map(0x0000, 0xffff).w(GENEVE_GATE_ARRAY_TAG, FUNC(bus::ti99::internal::geneve_gate_array_device::setaddress));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -316,7 +336,7 @@ void geneve_state::crumap(address_map &map)
|
||||
static INPUT_PORTS_START(geneve_common)
|
||||
|
||||
PORT_START( "BOOTROM" )
|
||||
PORT_CONFNAME( 0x03, GENEVE_EPROM, "Boot from" ) PORT_CHANGED_MEMBER(GENEVE_MAPPER_TAG, bus::ti99::internal::geneve_mapper_device, settings_changed, 3)
|
||||
PORT_CONFNAME( 0x03, GENEVE_EPROM, "Boot from" ) PORT_CHANGED_MEMBER(GENEVE_GATE_ARRAY_TAG, bus::ti99::internal::geneve_gate_array_device, settings_changed, 3)
|
||||
PORT_CONFSETTING( GENEVE_EPROM, "EPROM" )
|
||||
PORT_CONFSETTING( GENEVE_PFM512, "PFM 512" )
|
||||
PORT_CONFSETTING( GENEVE_PFM512A, "PFM 512A" )
|
||||
@ -343,10 +363,10 @@ static INPUT_PORTS_START(genmod)
|
||||
PORT_INCLUDE(geneve_common)
|
||||
|
||||
PORT_START( "GENMODDIPS" )
|
||||
PORT_DIPNAME( GENEVE_GM_TURBO, 0x00, "Genmod Turbo mode") PORT_CHANGED_MEMBER(GENEVE_MAPPER_TAG, bus::ti99::internal::genmod_mapper_device, setgm_changed, 1)
|
||||
PORT_DIPNAME( GENEVE_GM_TURBO, 0x00, "Genmod Turbo mode") PORT_CHANGED_MEMBER(GENEVE_GATE_ARRAY_TAG, bus::ti99::internal::genmod_gate_array_device, setgm_changed, 1)
|
||||
PORT_CONFSETTING( 0x00, DEF_STR( Off ))
|
||||
PORT_CONFSETTING( GENEVE_GM_TURBO, DEF_STR( On ))
|
||||
PORT_DIPNAME( GENEVE_GM_TIM, GENEVE_GM_TIM, "Genmod TI mode") PORT_CHANGED_MEMBER(GENEVE_MAPPER_TAG, bus::ti99::internal::genmod_mapper_device, setgm_changed, 2)
|
||||
PORT_DIPNAME( GENEVE_GM_TIM, GENEVE_GM_TIM, "Genmod TI mode") PORT_CHANGED_MEMBER(GENEVE_GATE_ARRAY_TAG, bus::ti99::internal::genmod_gate_array_device, setgm_changed, 2)
|
||||
PORT_CONFSETTING( 0x00, DEF_STR( Off ))
|
||||
PORT_CONFSETTING( GENEVE_GM_TIM, DEF_STR( On ))
|
||||
|
||||
@ -389,36 +409,36 @@ void geneve_state::cruwrite(offs_t offset, uint8_t data)
|
||||
LOGMASKED(LOG_CRU, "Set capslock flag = %02x\n", data);
|
||||
break;
|
||||
case 8:
|
||||
LOGMASKED(LOG_CRU, "Set keyboard clock flag = %02x\n", data);
|
||||
m_keyboard->clock_control((data!=0)? ASSERT_LINE : CLEAR_LINE);
|
||||
LOGMASKED(LOG_CRUKEY, "Set keyboard clock = %02x\n", data);
|
||||
m_gatearray->set_keyboard_clock(data);
|
||||
break;
|
||||
case 9:
|
||||
LOGMASKED(LOG_CRU, "Set keyboard scan flag = %02x\n", data);
|
||||
m_keyboard->send_scancodes((data!=0)? ASSERT_LINE : CLEAR_LINE);
|
||||
LOGMASKED(LOG_CRUKEY, "Enable keyboard shift reg = %02x\n", data);
|
||||
m_gatearray->enable_shift_register(data);
|
||||
break;
|
||||
case 10:
|
||||
LOGMASKED(LOG_CRU, "Geneve mode = %02x\n", data);
|
||||
m_mapper->set_geneve_mode(data!=0);
|
||||
m_gatearray->set_geneve_mode(data!=0);
|
||||
break;
|
||||
case 11:
|
||||
LOGMASKED(LOG_CRU, "Direct mode = %02x\n", data);
|
||||
m_mapper->set_direct_mode(data!=0);
|
||||
m_gatearray->set_direct_mode(data!=0);
|
||||
break;
|
||||
case 12:
|
||||
LOGMASKED(LOG_CRU, "Cartridge size 8K = %02x\n", data);
|
||||
m_mapper->set_cartridge_size((data!=0)? 0x2000 : 0x4000);
|
||||
m_gatearray->set_cartridge_size((data!=0)? 0x2000 : 0x4000);
|
||||
break;
|
||||
case 13:
|
||||
LOGMASKED(LOG_CRU, "Cartridge writable 6000 = %02x\n", data);
|
||||
m_mapper->set_cartridge_writable(0x6000, (data!=0));
|
||||
m_gatearray->set_cartridge_writable(0x6000, (data!=0));
|
||||
break;
|
||||
case 14:
|
||||
LOGMASKED(LOG_CRU, "Cartridge writable 7000 = %02x\n", data);
|
||||
m_mapper->set_cartridge_writable(0x7000, (data!=0));
|
||||
m_gatearray->set_cartridge_writable(0x7000, (data!=0));
|
||||
break;
|
||||
case 15:
|
||||
LOGMASKED(LOG_CRU, "Extra wait states = %02x\n", data==0);
|
||||
m_mapper->set_extra_waitstates(data==0); // let's use the inverse semantics
|
||||
m_gatearray->set_extra_waitstates(data==0); // let's use the inverse semantics
|
||||
break;
|
||||
default:
|
||||
LOGMASKED(LOG_WARN, "set CRU address %04x=%02x ignored\n", addroff, data);
|
||||
@ -531,6 +551,7 @@ WRITE_LINE_MEMBER( geneve_state::joystick_select )
|
||||
m_joyport->write_port((state==ASSERT_LINE)? 1:2);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Write external mem cycles (0=long, 1=short)
|
||||
*/
|
||||
@ -546,10 +567,18 @@ WRITE_LINE_MEMBER( geneve_state::extbus_wait_states )
|
||||
WRITE_LINE_MEMBER( geneve_state::video_wait_states )
|
||||
{
|
||||
LOGMASKED(LOG_LINES, "Video wait states set to %d\n", state);
|
||||
m_mapper->set_video_waitstates(state==ASSERT_LINE);
|
||||
m_gatearray->set_video_waitstates(state==ASSERT_LINE);
|
||||
m_video_wait = (state!=0)? ASSERT_LINE : CLEAR_LINE;
|
||||
}
|
||||
|
||||
/*
|
||||
Keyboard reset (active low).
|
||||
*/
|
||||
WRITE_LINE_MEMBER( geneve_state::keyboard_reset )
|
||||
{
|
||||
LOGMASKED(LOG_CRUKEY, "Keyboard reset %d\n", state);
|
||||
}
|
||||
|
||||
/*
|
||||
Called by the 9901 core whenever the state of INTREQ and IC0-3 changes.
|
||||
As with the TI-99/4A, the interrupt level is delivered as the offset,
|
||||
@ -635,7 +664,7 @@ void geneve_state::external_operation(offs_t offset, uint8_t data)
|
||||
WRITE_LINE_MEMBER( geneve_state::clock_out )
|
||||
{
|
||||
m_tms9901->phi_line(state);
|
||||
m_mapper->clock_in(state);
|
||||
m_gatearray->clock_in(state);
|
||||
}
|
||||
|
||||
void geneve_state::init_geneve()
|
||||
@ -679,9 +708,10 @@ void geneve_state::geneve(machine_config &config)
|
||||
{
|
||||
geneve_common(config);
|
||||
|
||||
// Mapper
|
||||
GENEVE_MAPPER(config, m_mapper, 0);
|
||||
m_mapper->ready_cb().set(FUNC(geneve_state::mapper_ready));
|
||||
// Gate array
|
||||
GENEVE_GATE_ARRAY(config, m_gatearray, 0);
|
||||
m_gatearray->ready_cb().set(FUNC(geneve_state::mapper_ready));
|
||||
m_gatearray->kbdint_cb().set(FUNC(geneve_state::keyboard_interrupt));
|
||||
|
||||
// Peripheral expansion box (Geneve composition)
|
||||
TI99_PERIBOX_GEN(config, m_peribox, 0);
|
||||
@ -695,8 +725,9 @@ void geneve_state::genmod(machine_config &config)
|
||||
geneve_common(config);
|
||||
|
||||
// Mapper
|
||||
GENMOD_MAPPER(config, m_mapper, 0);
|
||||
m_mapper->ready_cb().set(FUNC(geneve_state::mapper_ready));
|
||||
GENMOD_GATE_ARRAY(config, m_gatearray, 0);
|
||||
m_gatearray->ready_cb().set(FUNC(geneve_state::mapper_ready));
|
||||
m_gatearray->kbdint_cb().set(FUNC(geneve_state::keyboard_interrupt));
|
||||
|
||||
// Peripheral expansion box (Geneve composition with Genmod and plugged-in Memex)
|
||||
TI99_PERIBOX_GENMOD(config, m_peribox, 0);
|
||||
@ -737,12 +768,12 @@ void geneve_state::geneve_common(machine_config &config)
|
||||
m_tms9901->p_out_cb(0).set(FUNC(geneve_state::peripheral_bus_reset));
|
||||
m_tms9901->p_out_cb(1).set(FUNC(geneve_state::VDP_reset));
|
||||
m_tms9901->p_out_cb(2).set(FUNC(geneve_state::joystick_select));
|
||||
m_tms9901->p_out_cb(4).set(GENEVE_MAPPER_TAG, FUNC(bus::ti99::internal::geneve_mapper_device::pfm_select_lsb));
|
||||
m_tms9901->p_out_cb(5).set(GENEVE_MAPPER_TAG, FUNC(bus::ti99::internal::geneve_mapper_device::pfm_output_enable));
|
||||
m_tms9901->p_out_cb(6).set(GENEVE_KEYBOARD_TAG, FUNC(bus::ti99::internal::geneve_keyboard_device::reset_line));
|
||||
m_tms9901->p_out_cb(4).set(GENEVE_GATE_ARRAY_TAG, FUNC(bus::ti99::internal::geneve_gate_array_device::pfm_select_lsb));
|
||||
m_tms9901->p_out_cb(5).set(GENEVE_GATE_ARRAY_TAG, FUNC(bus::ti99::internal::geneve_gate_array_device::pfm_output_enable));
|
||||
m_tms9901->p_out_cb(6).set(FUNC(geneve_state::keyboard_reset));
|
||||
m_tms9901->p_out_cb(7).set(FUNC(geneve_state::extbus_wait_states));
|
||||
m_tms9901->p_out_cb(9).set(FUNC(geneve_state::video_wait_states));
|
||||
m_tms9901->p_out_cb(13).set(GENEVE_MAPPER_TAG, FUNC(bus::ti99::internal::geneve_mapper_device::pfm_select_msb));
|
||||
m_tms9901->p_out_cb(13).set(GENEVE_GATE_ARRAY_TAG, FUNC(bus::ti99::internal::geneve_gate_array_device::pfm_select_msb));
|
||||
m_tms9901->intreq_cb().set(FUNC(geneve_state::tms9901_interrupt));
|
||||
|
||||
// Clock
|
||||
@ -754,8 +785,12 @@ void geneve_state::geneve_common(machine_config &config)
|
||||
soundgen.ready_cb().set(FUNC(geneve_state::ext_ready));
|
||||
soundgen.add_route(ALL_OUTPUTS, "sound_out", 0.75);
|
||||
|
||||
// User interface devices
|
||||
GENEVE_KEYBOARD(config, m_keyboard, 0).int_cb().set(FUNC(geneve_state::keyboard_interrupt));
|
||||
// User interface devices: PC-style keyboard, joystick port, mouse connector
|
||||
PC_KBDC(config, m_kbdconn, 0);
|
||||
PC_KBDC_SLOT(config, "kbd", geneve_xt_keyboards, STR_KBD_GENEVE_XT_101_HLE).set_pc_kbdc_slot(m_kbdconn);
|
||||
m_kbdconn->out_clock_cb().set(GENEVE_GATE_ARRAY_TAG, FUNC(bus::ti99::internal::geneve_gate_array_device::kbdclk));
|
||||
m_kbdconn->out_data_cb().set(GENEVE_GATE_ARRAY_TAG, FUNC(bus::ti99::internal::geneve_gate_array_device::kbddata));
|
||||
|
||||
TI99_JOYPORT(config, m_joyport, 0, ti99_joyport_options_plain, "twinjoy");
|
||||
V9938_COLORBUS(config, m_colorbus, 0, ti99_colorbus_options, nullptr);
|
||||
m_colorbus->extra_button_cb().set(FUNC(geneve_state::left_mouse_button));
|
||||
|
Loading…
Reference in New Issue
Block a user