trunk/src/mess/machine/qimi.c
| r30839 | r30840 | |
| 2 | 2 | // copyright-holders:Curt Coder, Phill Harvey-Smith |
| 3 | 3 | /********************************************************************** |
| 4 | 4 | |
| 5 | | QL Internal Mouse Interface emulation |
| 5 | QJump/Quanta QL Internal Mouse Interface emulation |
| 6 | 6 | |
| 7 | 7 | Copyright MESS Team. |
| 8 | 8 | Visit http://mamedev.org for licensing and usage restrictions. |
| r30839 | r30840 | |
| 14 | 14 | |
| 15 | 15 | |
| 16 | 16 | //************************************************************************** |
| 17 | | // MACROS / CONSTANTS |
| 17 | // DEVICE DEFINITIONS |
| 18 | 18 | //************************************************************************** |
| 19 | 19 | |
| 20 | | #define MOUSEX_TAG "MOUSEX" |
| 21 | | #define MOUSEY_TAG "MOUSEY" |
| 22 | | #define MOUSEB_TAG "MOUSEB" |
| 20 | const device_type QIMI = &device_creator<qimi_t>; |
| 23 | 21 | |
| 24 | | // Mouse bits in Sandy port order |
| 25 | | #define MOUSE_MIDDLE 0x02 |
| 26 | | #define MOUSE_RIGHT 0x04 |
| 27 | | #define MOUSE_LEFT 0x08 |
| 28 | | #define MOUSE_DIRY 0x10 |
| 29 | | #define MOUSE_DIRX 0x20 |
| 30 | | #define MOUSE_INTY 0x40 |
| 31 | | #define MOUSE_INTX 0x80 |
| 32 | | #define MOUSE_INT_MASK (MOUSE_INTX | MOUSE_INTY) |
| 33 | 22 | |
| 34 | | #define QIMI_INTX 0x04 |
| 35 | | #define QIMI_INTY 0x20 |
| 36 | | #define QIMI_DIRX 0x10 |
| 37 | | #define QIMI_DIRY 0x01 |
| 38 | | #define QIMI_LEFT 0x20 |
| 39 | | #define QIMI_RIGHT 0x10 |
| 40 | | #define QIMI_INT_MASK (QIMI_INTX | QIMI_INTY) |
| 23 | //------------------------------------------------- |
| 24 | // INPUT_CHANGED_MEMBER( mouse_x_changed ) |
| 25 | //------------------------------------------------- |
| 41 | 26 | |
| 27 | INPUT_CHANGED_MEMBER( qimi_t::mouse_x_changed ) |
| 28 | { |
| 29 | if (newval > oldval) |
| 30 | { |
| 31 | m_status |= ST_HORZ_DIR; |
| 32 | } |
| 33 | else |
| 34 | { |
| 35 | m_status &= ~ST_HORZ_DIR; |
| 36 | } |
| 42 | 37 | |
| 38 | m_status |= ST_HORZ_MOVE; |
| 43 | 39 | |
| 44 | | //************************************************************************** |
| 45 | | // DEVICE DEFINITIONS |
| 46 | | //************************************************************************** |
| 40 | if (m_extint_en) |
| 41 | { |
| 42 | m_write_extint(ASSERT_LINE); |
| 43 | } |
| 44 | } |
| 47 | 45 | |
| 48 | | const device_type QIMI = &device_creator<qimi_t>; |
| 49 | 46 | |
| 47 | //------------------------------------------------- |
| 48 | // INPUT_CHANGED_MEMBER( mouse_y_changed ) |
| 49 | //------------------------------------------------- |
| 50 | 50 | |
| 51 | INPUT_CHANGED_MEMBER( qimi_t::mouse_y_changed ) |
| 52 | { |
| 53 | if (newval < oldval) |
| 54 | { |
| 55 | m_status |= ST_VERT_DIR; |
| 56 | } |
| 57 | else |
| 58 | { |
| 59 | m_status &= ~ST_VERT_DIR; |
| 60 | } |
| 61 | |
| 62 | m_status |= ST_VERT_MOVE; |
| 63 | |
| 64 | if (m_extint_en) |
| 65 | { |
| 66 | m_write_extint(ASSERT_LINE); |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | |
| 51 | 71 | //------------------------------------------------- |
| 52 | 72 | // INPUT_PORTS( qimi ) |
| 53 | 73 | //------------------------------------------------- |
| 54 | 74 | |
| 55 | 75 | INPUT_PORTS_START( qimi ) |
| 56 | | PORT_START(MOUSEX_TAG) |
| 57 | | PORT_BIT( 0xff, 0x00, IPT_MOUSE_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(5) PORT_MINMAX(0, 255) PORT_PLAYER(1) |
| 76 | PORT_START("mouse_x") |
| 77 | PORT_BIT( 0xff, 0x00, IPT_MOUSE_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(5) PORT_MINMAX(0, 255) PORT_PLAYER(1) PORT_CHANGED_MEMBER(DEVICE_SELF, qimi_t, mouse_x_changed, 0) |
| 58 | 78 | |
| 59 | | PORT_START(MOUSEY_TAG) |
| 60 | | PORT_BIT( 0xff, 0x00, IPT_MOUSE_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(5) PORT_MINMAX(0, 255) PORT_PLAYER(1) |
| 79 | PORT_START("mouse_y") |
| 80 | PORT_BIT( 0xff, 0x00, IPT_MOUSE_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(5) PORT_MINMAX(0, 255) PORT_PLAYER(1) PORT_CHANGED_MEMBER(DEVICE_SELF, qimi_t, mouse_y_changed, 0) |
| 61 | 81 | |
| 62 | | PORT_START(MOUSEB_TAG) /* Mouse buttons */ |
| 63 | | PORT_BIT( MOUSE_RIGHT, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Mouse Button 1") PORT_CODE(MOUSECODE_BUTTON1) |
| 64 | | PORT_BIT( MOUSE_LEFT, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("Mouse Button 2") PORT_CODE(MOUSECODE_BUTTON2) |
| 65 | | PORT_BIT( MOUSE_MIDDLE, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_NAME("Mouse Button 3") PORT_CODE(MOUSECODE_BUTTON3) |
| 82 | PORT_START("mouse_buttons") |
| 83 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Right Mouse Button") PORT_CODE(MOUSECODE_BUTTON2) |
| 84 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Left Mouse Button") PORT_CODE(MOUSECODE_BUTTON1) |
| 85 | PORT_BIT( 0xcf, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 66 | 86 | INPUT_PORTS_END |
| 67 | 87 | |
| 68 | 88 | |
| r30839 | r30840 | |
| 88 | 108 | qimi_t::qimi_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 89 | 109 | device_t(mconfig, QIMI, "QL Internal Mouse Interface", tag, owner, clock, "qimi", __FILE__), |
| 90 | 110 | m_write_extint(*this), |
| 91 | | m_mousex(*this, MOUSEX_TAG), |
| 92 | | m_mousey(*this, MOUSEY_TAG), |
| 93 | | m_mouseb(*this, MOUSEB_TAG) |
| 111 | m_buttons(*this, "mouse_buttons"), |
| 112 | m_status(0), |
| 113 | m_extint_en(false) |
| 94 | 114 | { |
| 95 | 115 | } |
| 96 | 116 | |
| r30839 | r30840 | |
| 103 | 123 | { |
| 104 | 124 | // resolve callbacks |
| 105 | 125 | m_write_extint.resolve_safe(); |
| 106 | | |
| 107 | | // allocate timer |
| 108 | | m_mouse_timer = timer_alloc(); |
| 109 | | m_mouse_timer->adjust(attotime::zero, 0, attotime::from_hz(500)); |
| 110 | 126 | } |
| 111 | 127 | |
| 112 | 128 | |
| 113 | 129 | //------------------------------------------------- |
| 114 | | // device_timer - handler timer events |
| 130 | // device_reset - device-specific reset |
| 115 | 131 | //------------------------------------------------- |
| 116 | 132 | |
| 117 | | void qimi_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) |
| 133 | void qimi_t::device_reset() |
| 118 | 134 | { |
| 119 | | UINT8 x = m_mousex->read(); |
| 120 | | UINT8 y = m_mousey->read(); |
| 121 | | UINT8 do_int = 0; |
| 122 | | |
| 123 | | //m_mouse_int = 0; |
| 124 | | |
| 125 | | // Set X interupt flag and direction if x has changed |
| 126 | | if (x > m_ql_mouse_x) |
| 127 | | { |
| 128 | | m_mouse_int |= MOUSE_INTX; |
| 129 | | m_mouse_int |= MOUSE_DIRX; |
| 130 | | } |
| 131 | | else if (x < m_ql_mouse_x) |
| 132 | | { |
| 133 | | m_mouse_int |= MOUSE_INTX; |
| 134 | | m_mouse_int &= ~MOUSE_DIRX; |
| 135 | | } |
| 136 | | |
| 137 | | // Set Y interupt flag and direction if y has changed |
| 138 | | if (y > m_ql_mouse_y) |
| 139 | | { |
| 140 | | m_mouse_int |= MOUSE_INTY; |
| 141 | | m_mouse_int &= ~MOUSE_DIRY; |
| 142 | | } |
| 143 | | else if (y < m_ql_mouse_y) |
| 144 | | { |
| 145 | | m_mouse_int |= MOUSE_INTY; |
| 146 | | m_mouse_int |= MOUSE_DIRY; |
| 147 | | } |
| 148 | | |
| 149 | | // Update saved location |
| 150 | | m_ql_mouse_x = x; |
| 151 | | m_ql_mouse_y = y; |
| 152 | | |
| 153 | | // if it is a QIMI, then always do int if triggered. |
| 154 | | // if this is a Sandy mouse, only trigger an int if it is enabled in the mask register |
| 155 | | do_int = 1; |
| 156 | | |
| 157 | | //logerror("m_mouse_int=%02X, MOUSE_INT_MASK=%02X, m_disk_io_byte=%02X, (m_disk_io_byte & SANDY_MOUSE_INTMASK)=%02x\n",m_mouse_int,MOUSE_INT_MASK,m_disk_io_byte,(m_disk_io_byte & SANDY_MOUSE_INTMASK)); |
| 158 | | |
| 159 | | // if mouse moved trigger external int |
| 160 | | if((m_mouse_int & MOUSE_INT_MASK) && do_int) |
| 161 | | { |
| 162 | | m_write_extint(ASSERT_LINE); |
| 163 | | } |
| 135 | m_status = 0; |
| 136 | m_extint_en = false; |
| 164 | 137 | } |
| 165 | 138 | |
| 166 | 139 | |
| r30839 | r30840 | |
| 168 | 141 | // read - |
| 169 | 142 | //------------------------------------------------- |
| 170 | 143 | |
| 171 | | READ8_MEMBER( qimi_t::read ) |
| 144 | UINT8 qimi_t::read(address_space &space, offs_t offset, UINT8 data) |
| 172 | 145 | { |
| 173 | | UINT8 result = 0; |
| 174 | | UINT8 buttons; |
| 175 | | |
| 176 | 146 | switch (offset) |
| 177 | 147 | { |
| 178 | | // 0x1bf9c, button status |
| 179 | | case 0x00 : |
| 180 | | buttons = m_mouseb->read(); |
| 181 | | result = ((buttons & MOUSE_RIGHT) << 2) | ((buttons & MOUSE_LEFT) << 2); |
| 182 | | break; |
| 148 | // button status |
| 149 | case 0x1bf9c: |
| 150 | data = m_buttons->read(); |
| 151 | break; |
| 183 | 152 | |
| 184 | | // 0x1bfbc, direction status |
| 185 | | case 0x20 : |
| 186 | | result = ((m_mouse_int & MOUSE_INTX) >> 5) | ((m_mouse_int & MOUSE_INTY) >> 1) | |
| 187 | | ((m_mouse_int & MOUSE_DIRX) >> 1) | ((m_mouse_int & MOUSE_DIRY) >> 4); |
| 188 | | break; |
| 189 | | case 0x22 : |
| 190 | | m_mouse_int &= ~MOUSE_INT_MASK; |
| 191 | | break; |
| 153 | // direction status |
| 154 | case 0x1bfbc: |
| 155 | data = m_status; |
| 156 | break; |
| 157 | |
| 158 | case 0x1bfbe: |
| 159 | m_status &= ~(ST_VERT_MOVE | ST_HORZ_MOVE); |
| 160 | m_extint_en = true; |
| 161 | |
| 162 | m_write_extint(CLEAR_LINE); |
| 163 | break; |
| 192 | 164 | } |
| 193 | 165 | |
| 194 | | return result; |
| 166 | return data; |
| 195 | 167 | } |
| 196 | 168 | |
| 197 | 169 | |
| r30839 | r30840 | |
| 202 | 174 | WRITE8_MEMBER( qimi_t::write ) |
| 203 | 175 | { |
| 204 | 176 | // write to 0x1bfbe resets int status |
| 205 | | if (offset == 0x22) |
| 177 | if (offset == 0x1bfbe) |
| 206 | 178 | { |
| 207 | | m_mouse_int = 0; |
| 179 | m_status &= ~(ST_VERT_MOVE | ST_HORZ_MOVE); |
| 180 | m_extint_en = true; |
| 181 | |
| 182 | m_write_extint(CLEAR_LINE); |
| 208 | 183 | } |
| 209 | 184 | } |
trunk/src/mess/machine/qimi.h
| r30839 | r30840 | |
| 2 | 2 | // copyright-holders:Curt Coder, Phill Harvey-Smith |
| 3 | 3 | /********************************************************************** |
| 4 | 4 | |
| 5 | | QL Internal Mouse Interface emulation |
| 5 | QJump/Quanta QL Internal Mouse Interface emulation |
| 6 | 6 | |
| 7 | 7 | Copyright MESS Team. |
| 8 | 8 | Visit http://mamedev.org for licensing and usage restrictions. |
| r30839 | r30840 | |
| 19 | 19 | |
| 20 | 20 | |
| 21 | 21 | //************************************************************************** |
| 22 | | // MACROS / CONSTANTS |
| 23 | | //************************************************************************** |
| 24 | | |
| 25 | | #define QIMI_IO_BASE 0x1bf9c |
| 26 | | #define QIMI_IO_LEN 0x22 |
| 27 | | #define QIMI_IO_END (QIMI_IO_BASE + QIMI_IO_LEN ) |
| 28 | | |
| 29 | | |
| 30 | | |
| 31 | | //************************************************************************** |
| 32 | 22 | // INTERFACE CONFIGURATION MACROS |
| 33 | 23 | //************************************************************************** |
| 34 | 24 | |
| r30839 | r30840 | |
| 54 | 44 | // optional information overrides |
| 55 | 45 | virtual ioport_constructor device_input_ports() const; |
| 56 | 46 | |
| 57 | | DECLARE_READ8_MEMBER( read ); |
| 47 | UINT8 read(address_space &space, offs_t offset, UINT8 data); |
| 58 | 48 | DECLARE_WRITE8_MEMBER( write ); |
| 59 | 49 | |
| 50 | DECLARE_INPUT_CHANGED_MEMBER( mouse_x_changed ); |
| 51 | DECLARE_INPUT_CHANGED_MEMBER( mouse_y_changed ); |
| 52 | |
| 60 | 53 | protected: |
| 61 | 54 | // device-level overrides |
| 62 | 55 | virtual void device_start(); |
| 63 | | virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); |
| 56 | virtual void device_reset(); |
| 64 | 57 | |
| 65 | 58 | private: |
| 59 | enum |
| 60 | { |
| 61 | ST_VERT_DIR = 0x01, |
| 62 | ST_HORZ_MOVE = 0x04, |
| 63 | ST_HORZ_DIR = 0x10, |
| 64 | ST_VERT_MOVE = 0x20 |
| 65 | }; |
| 66 | |
| 66 | 67 | devcb_write_line m_write_extint; |
| 67 | 68 | |
| 68 | | required_ioport m_mousex; |
| 69 | | required_ioport m_mousey; |
| 70 | | required_ioport m_mouseb; |
| 69 | required_ioport m_buttons; |
| 71 | 70 | |
| 72 | | UINT8 m_mouse_int; |
| 73 | | |
| 74 | | emu_timer *m_mouse_timer; |
| 75 | | |
| 76 | | UINT8 m_ql_mouse_x; |
| 77 | | UINT8 m_ql_mouse_y; |
| 71 | UINT8 m_status; |
| 72 | bool m_extint_en; |
| 78 | 73 | }; |
| 79 | 74 | |
| 80 | 75 | |
trunk/src/mess/drivers/ql.c
| r30839 | r30840 | |
| 12 | 12 | |
| 13 | 13 | TODO: |
| 14 | 14 | |
| 15 | | - QIMI/Sandy mice |
| 15 | - Sandy mouse |
| 16 | 16 | - microdrive |
| 17 | 17 | - ZX8301 memory access slowdown |
| 18 | 18 | - use resnet.h to create palette |
| r30839 | r30840 | |
| 124 | 124 | { |
| 125 | 125 | exp_romoeh = 1; |
| 126 | 126 | } |
| 127 | | if (m_qimi_enabled && offset >= QIMI_IO_BASE && offset <= QIMI_IO_END) |
| 127 | if (m_qimi_enabled) |
| 128 | 128 | { |
| 129 | | data = m_qimi->read(space, offset - QIMI_IO_BASE); |
| 129 | data = m_qimi->read(space, offset, data); |
| 130 | 130 | } |
| 131 | 131 | |
| 132 | 132 | m_cart->romoeh_w(cart_romoeh); |
| r30839 | r30840 | |
| 179 | 179 | { |
| 180 | 180 | m_zx8301->data_w(space, offset & 0x1ffff, data); |
| 181 | 181 | } |
| 182 | | if (m_qimi_enabled && offset >= QIMI_IO_BASE && offset <= QIMI_IO_END) |
| 182 | if (m_qimi_enabled) |
| 183 | 183 | { |
| 184 | | m_qimi->write(space, offset - QIMI_IO_BASE, data); |
| 184 | m_qimi->write(space, offset, data); |
| 185 | 185 | } |
| 186 | 186 | |
| 187 | 187 | m_cart->romoeh_w(0); |
| r30839 | r30840 | |
| 722 | 722 | return m_mdv1->data2_r() | m_mdv2->data2_r(); |
| 723 | 723 | } |
| 724 | 724 | |
| 725 | void ql_state::update_interrupt() |
| 726 | { |
| 727 | m_zx8302->extint_w(m_extintl || m_qimi_extint); |
| 728 | } |
| 725 | 729 | |
| 730 | WRITE_LINE_MEMBER( ql_state::exp_extintl_w ) |
| 731 | { |
| 732 | m_extintl = state; |
| 733 | update_interrupt(); |
| 734 | } |
| 726 | 735 | |
| 736 | WRITE_LINE_MEMBER( ql_state::qimi_extintl_w ) |
| 737 | { |
| 738 | if (m_qimi_enabled) |
| 739 | { |
| 740 | m_qimi_extint = state; |
| 741 | update_interrupt(); |
| 742 | } |
| 743 | } |
| 744 | |
| 745 | |
| 746 | |
| 727 | 747 | //************************************************************************** |
| 728 | 748 | // MACHINE INITIALIZATION |
| 729 | 749 | //************************************************************************** |
| r30839 | r30840 | |
| 810 | 830 | //MCFG_QL_EXPANSION_SLOT_IPL0L_CALLBACK() |
| 811 | 831 | //MCFG_QL_EXPANSION_SLOT_IPL1L_CALLBACK() |
| 812 | 832 | //MCFG_QL_EXPANSION_SLOT_BERRL_CALLBACK() |
| 813 | | MCFG_QL_EXPANSION_SLOT_EXTINTL_CALLBACK(DEVWRITELINE(ZX8302_TAG, zx8302_device, extint_w)) |
| 833 | MCFG_QL_EXPANSION_SLOT_EXTINTL_CALLBACK(WRITELINE(ql_state, exp_extintl_w)) |
| 814 | 834 | |
| 815 | 835 | MCFG_QL_ROM_CARTRIDGE_SLOT_ADD("rom", ql_rom_cartridge_cards, NULL) |
| 816 | 836 | |
| 817 | 837 | MCFG_DEVICE_ADD(QIMI_TAG, QIMI, 0) |
| 838 | MCFG_QIMI_EXTINT_CALLBACK(WRITELINE(ql_state, qimi_extintl_w)) |
| 818 | 839 | |
| 819 | 840 | // software lists |
| 820 | 841 | MCFG_SOFTWARE_LIST_ADD("cart_list", "ql_cart") |