trunk/src/emu/bus/cpc/symbfac2.c
| r0 | r31524 | |
| 1 | /* |
| 2 | * symbfac2.c |
| 3 | * SYMBiFACE II expansion device |
| 4 | * - IDE |
| 5 | * - RTC (Dallas DS1287A) |
| 6 | * - PS/2 compatible mouse connector |
| 7 | * - 512kB RAM expansion |
| 8 | * - 512kB rewritable ROM |
| 9 | * |
| 10 | * Created on: 2/08/2014 |
| 11 | * |
| 12 | * TODO: |
| 13 | * - expansion RAM |
| 14 | * - rewritable ROM |
| 15 | * - mouse controls still need some work |
| 16 | */ |
| 17 | |
| 18 | #include "symbfac2.h" |
| 19 | |
| 20 | |
| 21 | const device_type CPC_SYMBIFACE2 = &device_creator<cpc_symbiface2_device>; |
| 22 | |
| 23 | //************************************************************************** |
| 24 | // DEVICE CONFIG INTERFACE |
| 25 | //************************************************************************** |
| 26 | |
| 27 | // device machine config |
| 28 | static MACHINE_CONFIG_FRAGMENT( cpc_symbiface2 ) |
| 29 | MCFG_ATA_INTERFACE_ADD("ide",ata_devices,"hdd",NULL,false) |
| 30 | MCFG_DS12885_ADD("rtc") |
| 31 | // no pass-through |
| 32 | MACHINE_CONFIG_END |
| 33 | |
| 34 | static INPUT_PORTS_START(cpc_symbiface2) |
| 35 | PORT_START("sf2_mouse_x") |
| 36 | PORT_BIT(0x3f , 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(50) PORT_KEYDELTA(0) PORT_REVERSE PORT_PLAYER(1) PORT_CODE(MOUSECODE_X) PORT_CHANGED_MEMBER(DEVICE_SELF,cpc_symbiface2_device,mouse_change_x,NULL) |
| 37 | |
| 38 | PORT_START("sf2_mouse_y") |
| 39 | PORT_BIT(0x3f , 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(50) PORT_KEYDELTA(0) PORT_PLAYER(1) PORT_CODE(MOUSECODE_Y) PORT_CHANGED_MEMBER(DEVICE_SELF,cpc_symbiface2_device,mouse_change_x,NULL) |
| 40 | |
| 41 | PORT_START("sf2_mouse_buttons") |
| 42 | PORT_BIT(0x00000001, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("PS/2 Mouse left button") PORT_CODE(MOUSECODE_BUTTON1) PORT_CHANGED_MEMBER(DEVICE_SELF,cpc_symbiface2_device,mouse_change_x,NULL) |
| 43 | PORT_BIT(0x00000002, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("PS/2 Mouse right button") PORT_CODE(MOUSECODE_BUTTON3) PORT_CHANGED_MEMBER(DEVICE_SELF,cpc_symbiface2_device,mouse_change_x,NULL) |
| 44 | PORT_BIT(0x00000004, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("PS/2 Mouse middle button") PORT_CODE(MOUSECODE_BUTTON2) PORT_CHANGED_MEMBER(DEVICE_SELF,cpc_symbiface2_device,mouse_change_x,NULL) |
| 45 | PORT_BIT(0x00000008, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("PS/2 Mouse back button") PORT_CODE(MOUSECODE_BUTTON4) PORT_CHANGED_MEMBER(DEVICE_SELF,cpc_symbiface2_device,mouse_change_x,NULL) |
| 46 | PORT_BIT(0x00000010, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("PS/2 Mouse forward button") PORT_CODE(MOUSECODE_BUTTON5) PORT_CHANGED_MEMBER(DEVICE_SELF,cpc_symbiface2_device,mouse_change_x,NULL) |
| 47 | |
| 48 | // TODO: mouse scroll wheel support |
| 49 | // PORT_START("sf2_mouse_scroll") |
| 50 | // PORT_BIT(0x1f , 0, IPT_TRACKBALL_Y) |
| 51 | // PORT_SENSITIVITY(100) |
| 52 | // PORT_KEYDELTA(10) |
| 53 | // PORT_PLAYER(1) |
| 54 | INPUT_PORTS_END |
| 55 | |
| 56 | |
| 57 | machine_config_constructor cpc_symbiface2_device::device_mconfig_additions() const |
| 58 | { |
| 59 | return MACHINE_CONFIG_NAME( cpc_symbiface2 ); |
| 60 | } |
| 61 | |
| 62 | ioport_constructor cpc_symbiface2_device::device_input_ports() const |
| 63 | { |
| 64 | return INPUT_PORTS_NAME( cpc_symbiface2 ); |
| 65 | } |
| 66 | |
| 67 | //************************************************************************** |
| 68 | // LIVE DEVICE |
| 69 | //************************************************************************** |
| 70 | |
| 71 | cpc_symbiface2_device::cpc_symbiface2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 72 | device_t(mconfig, CPC_SYMBIFACE2, "SYMBiFACE II", tag, owner, clock, "cpc_symf2", __FILE__), |
| 73 | device_cpc_expansion_card_interface(mconfig, *this), |
| 74 | m_ide(*this,"ide"), |
| 75 | m_rtc(*this,"rtc"), |
| 76 | m_mouse_x(*this,"sf2_mouse_x"), |
| 77 | m_mouse_y(*this,"sf2_mouse_y"), |
| 78 | m_mouse_buttons(*this,"sf2_mouse_buttons") |
| 79 | { |
| 80 | } |
| 81 | |
| 82 | //------------------------------------------------- |
| 83 | // device_start - device-specific startup |
| 84 | //------------------------------------------------- |
| 85 | |
| 86 | void cpc_symbiface2_device::device_start() |
| 87 | { |
| 88 | device_t* cpu = machine().device("maincpu"); |
| 89 | address_space& space = cpu->memory().space(AS_IO); |
| 90 | |
| 91 | space.install_readwrite_handler(0xfd00,0xfd07,0,0,read8_delegate(FUNC(cpc_symbiface2_device::ide_cs1_r),this),write8_delegate(FUNC(cpc_symbiface2_device::ide_cs1_w),this)); |
| 92 | space.install_readwrite_handler(0xfd08,0xfd0f,0,0,read8_delegate(FUNC(cpc_symbiface2_device::ide_cs0_r),this),write8_delegate(FUNC(cpc_symbiface2_device::ide_cs0_w),this)); |
| 93 | space.install_read_handler(0xfd10,0xfd10,0,0,read8_delegate(FUNC(cpc_symbiface2_device::mouse_r),this)); |
| 94 | space.install_readwrite_handler(0xfd14,0xfd15,0,0,read8_delegate(FUNC(cpc_symbiface2_device::rtc_r),this),write8_delegate(FUNC(cpc_symbiface2_device::rtc_w),this)); |
| 95 | } |
| 96 | |
| 97 | //------------------------------------------------- |
| 98 | // device_reset - device-specific reset |
| 99 | //------------------------------------------------- |
| 100 | |
| 101 | void cpc_symbiface2_device::device_reset() |
| 102 | { |
| 103 | m_iohigh = false; |
| 104 | m_mouse_state = PS2_MOUSE_IDLE; |
| 105 | m_input_x = m_mouse_x->read() & 0x3f; |
| 106 | m_input_y = m_mouse_y->read() & 0x3f; |
| 107 | } |
| 108 | |
| 109 | // IDE controller (custom) |
| 110 | // #FD00 - CS1 |
| 111 | // #FD08 - CS0 |
| 112 | READ8_MEMBER(cpc_symbiface2_device::ide_cs0_r) |
| 113 | { |
| 114 | // data is returned in words, so it must be buffered |
| 115 | if(offset == 0x00) // data register |
| 116 | { |
| 117 | if(m_iohigh) |
| 118 | { |
| 119 | m_iohigh = false; |
| 120 | return m_ide_data >> 8; |
| 121 | } |
| 122 | else |
| 123 | { |
| 124 | m_iohigh = true; |
| 125 | m_ide_data = m_ide->read_cs0(space,offset); |
| 126 | return m_ide_data & 0xff; |
| 127 | } |
| 128 | } |
| 129 | else |
| 130 | return m_ide->read_cs0(space,offset); |
| 131 | } |
| 132 | |
| 133 | WRITE8_MEMBER(cpc_symbiface2_device::ide_cs0_w) |
| 134 | { |
| 135 | m_ide->write_cs0(space,offset,data); |
| 136 | } |
| 137 | |
| 138 | READ8_MEMBER(cpc_symbiface2_device::ide_cs1_r) |
| 139 | { |
| 140 | return m_ide->read_cs1(space,offset); |
| 141 | } |
| 142 | |
| 143 | WRITE8_MEMBER(cpc_symbiface2_device::ide_cs1_w) |
| 144 | { |
| 145 | m_ide->write_cs1(space,offset,data); |
| 146 | } |
| 147 | |
| 148 | // RTC (Dallas DS1287A) |
| 149 | // #FD15 (write only) register select |
| 150 | // #FD14 (read/write) read from or write into selected register |
| 151 | READ8_MEMBER(cpc_symbiface2_device::rtc_r) |
| 152 | { |
| 153 | switch(offset & 0x01) |
| 154 | { |
| 155 | case 0x00: |
| 156 | return m_rtc->read(space,1); |
| 157 | case 0x01: |
| 158 | return m_rtc->read(space,0); |
| 159 | } |
| 160 | return 0; |
| 161 | } |
| 162 | |
| 163 | WRITE8_MEMBER(cpc_symbiface2_device::rtc_w) |
| 164 | { |
| 165 | switch(offset & 0x01) |
| 166 | { |
| 167 | case 0x00: |
| 168 | m_rtc->write(space,1,data); |
| 169 | break; |
| 170 | case 0x01: |
| 171 | m_rtc->write(space,0,data); |
| 172 | break; |
| 173 | } |
| 174 | } |
| 175 | |
| 176 | // PS/2 Mouse connector |
| 177 | // #FD10 (read only) read mouse status |
| 178 | /* |
| 179 | Status byte |
| 180 | Bit 76543210 |
| 181 | Use mmDDDDDD |
| 182 | |
| 183 | m: Mode |
| 184 | D: Use-Data |
| 185 | |
| 186 | If read and... |
| 187 | |
| 188 | m = 00 -> no more data available, you can stop reading the status for a while |
| 189 | m = 01 -> D = X offset (signed); you will receive positive values, if the user |
| 190 | is moving the mouse to the right |
| 191 | m = 10 -> D = Y offset (signed); you will receive positive values, if the user |
| 192 | is moving the mouse upwards |
| 193 | m = 11 -> D[bit5] = 0 -> D[bit0] = left button |
| 194 | D[bit1] = right button |
| 195 | D[bit2] = middle button |
| 196 | D[bit3] = forward button |
| 197 | D[bit4] = backward button |
| 198 | D[bit5] = 1 -> D[bit0-4] = scroll wheel offset (signed) |
| 199 | */ |
| 200 | READ8_MEMBER(cpc_symbiface2_device::mouse_r) |
| 201 | { |
| 202 | UINT8 ret = 0; |
| 203 | int input; |
| 204 | int input_diff; |
| 205 | |
| 206 | switch(m_mouse_state) |
| 207 | { |
| 208 | case PS2_MOUSE_IDLE: |
| 209 | m_mouse_state = PS2_MOUSE_IDLE; |
| 210 | ret = 0; |
| 211 | break; |
| 212 | case PS2_MOUSE_X: |
| 213 | input = m_mouse_x->read() & 0x3f; |
| 214 | input_diff = m_input_x - input; |
| 215 | ret = 0x40 | (input_diff & 0x3f); |
| 216 | m_input_x = input; |
| 217 | m_mouse_state = PS2_MOUSE_Y; |
| 218 | break; |
| 219 | case PS2_MOUSE_Y: |
| 220 | input = m_mouse_y->read() & 0x3f; |
| 221 | input_diff = m_input_y - input; |
| 222 | ret = 0x80 | (input_diff & 0x3f); |
| 223 | m_input_y = input; |
| 224 | m_mouse_state = PS2_MOUSE_BUTTONS; |
| 225 | break; |
| 226 | case PS2_MOUSE_BUTTONS: |
| 227 | ret = 0xc0 | (m_mouse_buttons->read() & 0x1f); |
| 228 | m_mouse_state = PS2_MOUSE_IDLE; |
| 229 | break; |
| 230 | case PS2_MOUSE_SCROLL: |
| 231 | m_mouse_state = PS2_MOUSE_IDLE; |
| 232 | break; // TODO |
| 233 | } |
| 234 | //popmessage("Mouse: X: %02x Y: %02x\n",m_input_x,m_input_y); |
| 235 | return ret; |
| 236 | } |
| 237 | |
| 238 | INPUT_CHANGED_MEMBER(cpc_symbiface2_device::mouse_change_x) |
| 239 | { |
| 240 | m_mouse_state = PS2_MOUSE_X; |
| 241 | } |
| 242 | |
| 243 | INPUT_CHANGED_MEMBER(cpc_symbiface2_device::mouse_change_y) |
| 244 | { |
| 245 | m_mouse_state = PS2_MOUSE_Y; |
| 246 | } |
| 247 | |
| 248 | INPUT_CHANGED_MEMBER(cpc_symbiface2_device::mouse_change_buttons) |
| 249 | { |
| 250 | m_mouse_state = PS2_MOUSE_BUTTONS; |
| 251 | } |
| 252 | |
trunk/src/emu/bus/cpc/symbfac2.h
| r0 | r31524 | |
| 1 | /* |
| 2 | * symbfac2.h |
| 3 | * |
| 4 | * Created on: 2/08/2014 |
| 5 | */ |
| 6 | |
| 7 | #ifndef SYMBFAC2_H_ |
| 8 | #define SYMBFAC2_H_ |
| 9 | |
| 10 | #include "emu.h" |
| 11 | #include "machine/ataintf.h" |
| 12 | #include "machine/ds128x.h" |
| 13 | #include "cpcexp.h" |
| 14 | |
| 15 | class cpc_symbiface2_device : public device_t, |
| 16 | public device_cpc_expansion_card_interface |
| 17 | { |
| 18 | public: |
| 19 | // construction/destruction |
| 20 | cpc_symbiface2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 21 | |
| 22 | // optional information overrides |
| 23 | virtual machine_config_constructor device_mconfig_additions() const; |
| 24 | virtual ioport_constructor device_input_ports() const; |
| 25 | |
| 26 | DECLARE_READ8_MEMBER(ide_cs0_r); |
| 27 | DECLARE_WRITE8_MEMBER(ide_cs0_w); |
| 28 | DECLARE_READ8_MEMBER(ide_cs1_r); |
| 29 | DECLARE_WRITE8_MEMBER(ide_cs1_w); |
| 30 | DECLARE_READ8_MEMBER(rtc_r); |
| 31 | DECLARE_WRITE8_MEMBER(rtc_w); |
| 32 | DECLARE_READ8_MEMBER(mouse_r); |
| 33 | DECLARE_INPUT_CHANGED_MEMBER(mouse_change_x); |
| 34 | DECLARE_INPUT_CHANGED_MEMBER(mouse_change_y); |
| 35 | DECLARE_INPUT_CHANGED_MEMBER(mouse_change_buttons); |
| 36 | |
| 37 | enum |
| 38 | { |
| 39 | PS2_MOUSE_IDLE = 0, |
| 40 | PS2_MOUSE_X, |
| 41 | PS2_MOUSE_Y, |
| 42 | PS2_MOUSE_BUTTONS, |
| 43 | PS2_MOUSE_SCROLL |
| 44 | }; |
| 45 | protected: |
| 46 | // device-level overrides |
| 47 | virtual void device_start(); |
| 48 | virtual void device_reset(); |
| 49 | |
| 50 | private: |
| 51 | //cpc_expansion_slot_device *m_slot; |
| 52 | required_device<ata_interface_device> m_ide; |
| 53 | required_device<ds12885_device> m_rtc; |
| 54 | |
| 55 | required_ioport m_mouse_x; |
| 56 | required_ioport m_mouse_y; |
| 57 | required_ioport m_mouse_buttons; |
| 58 | |
| 59 | bool m_iohigh; |
| 60 | UINT16 m_ide_data; |
| 61 | |
| 62 | UINT8 m_mouse_state; |
| 63 | UINT8 m_input_x; |
| 64 | UINT8 m_input_y; |
| 65 | }; |
| 66 | |
| 67 | // device type definition |
| 68 | extern const device_type CPC_SYMBIFACE2; |
| 69 | |
| 70 | |
| 71 | #endif /* SYMBFAC2_H_ */ |