|
|
1.1 ! root 1: /* Previous - kms.c ! 2: ! 3: This file is distributed under the GNU Public License, version 2 or at ! 4: your option any later version. Read the file gpl.txt for details. ! 5: ! 6: Keyboard, Mouse and Sound logic Emulation. ! 7: ! 8: In real hardware this logic is located in the NeXT Megapixel Display ! 9: or Soundbox ! 10: ! 11: */ ! 12: ! 13: #include "ioMem.h" ! 14: #include "ioMemTables.h" ! 15: #include "m68000.h" ! 16: #include "kms.h" ! 17: #include "sysReg.h" ! 18: #include "dma.h" ! 19: #include "rtcnvram.h" ! 20: #include "snd.h" ! 21: #include "video.h" ! 22: #include "host.h" ! 23: ! 24: #define LOG_KMS_LEVEL LOG_DEBUG ! 25: #define IO_SEG_MASK 0x1FFFF ! 26: ! 27: ! 28: struct { ! 29: struct { ! 30: Uint8 snd_dma; ! 31: Uint8 km; ! 32: Uint8 transmit; ! 33: Uint8 cmd; ! 34: } status; ! 35: ! 36: Uint32 data; ! 37: Uint32 km_data; ! 38: } kms; ! 39: ! 40: void KMS_Reset() { ! 41: kms.status.snd_dma = 0; ! 42: kms.status.km = 0; ! 43: kms.status.transmit = 0; ! 44: kms.status.cmd = 0; ! 45: kms.data = 0; ! 46: kms.km_data = 0; ! 47: } ! 48: ! 49: /* KMS control and status register (0x0200E000) ! 50: * ! 51: * x--- ---- ---- ---- ---- ---- ---- ---- sound out enable (r/w) ! 52: * -x-- ---- ---- ---- ---- ---- ---- ---- sound output request (r) ! 53: * --x- ---- ---- ---- ---- ---- ---- ---- sound output underrun detected (r/w) ! 54: * ---- x--- ---- ---- ---- ---- ---- ---- sound in enable (r/w) ! 55: * ---- -x-- ---- ---- ---- ---- ---- ---- sound input request (r) ! 56: * ---- --x- ---- ---- ---- ---- ---- ---- sound input overrun detected (r/w) ! 57: * ! 58: * ---- ---- x--- ---- ---- ---- ---- ---- keyboard interrupt (r) ! 59: * ---- ---- -x-- ---- ---- ---- ---- ---- keyboard data received (r) ! 60: * ---- ---- --x- ---- ---- ---- ---- ---- keyboard data overrun detected (r/w) ! 61: * ---- ---- ---x ---- ---- ---- ---- ---- non-maskable interrupt received (tilde and left or right cmd key) (r/w) ! 62: * ---- ---- ---- x--- ---- ---- ---- ---- kms interrupt (r) ! 63: * ---- ---- ---- -x-- ---- ---- ---- ---- kms data received (r) ! 64: * ---- ---- ---- --x- ---- ---- ---- ---- kms data overrun detected (r/w) ! 65: * ! 66: * ---- ---- ---- ---- x--- ---- ---- ---- dma sound out transmit pending (r) ! 67: * ---- ---- ---- ---- -x-- ---- ---- ---- dma sound out transmit in progress (r) ! 68: * ---- ---- ---- ---- --x- ---- ---- ---- cpu data transmit pending (r) ! 69: * ---- ---- ---- ---- ---x ---- ---- ---- cpu data transmit in progress (r) ! 70: * ---- ---- ---- ---- ---- x--- ---- ---- rtx_pend ??? ! 71: * ---- ---- ---- ---- ---- -x-- ---- ---- rtx ??? ! 72: * ---- ---- ---- ---- ---- --x- ---- ---- kms enable (return from reset state) (r/w) ! 73: * ---- ---- ---- ---- ---- ---x ---- ---- loop back transmitter data (r/w) ! 74: * ! 75: * ---- ---- ---- ---- ---- ---- xxxx xxxx command to append on kms data (r/w) ! 76: * ! 77: * ---x ---x ---- ---x ---- ---- ---- ---- zero bits ! 78: */ ! 79: ! 80: ! 81: #define SNDOUT_DMA_ENABLE 0x80 ! 82: #define SNDOUT_DMA_REQUEST 0x40 ! 83: #define SNDOUT_DMA_UNDERRUN 0x20 ! 84: #define SNDIN_DMA_ENABLE 0x08 ! 85: #define SNDIN_DMA_REQUEST 0x04 ! 86: #define SNDIN_DMA_OVERRUN 0x02 ! 87: ! 88: #define KBD_INT 0x80 ! 89: #define KBD_RECEIVED 0x40 ! 90: #define KBD_OVERRUN 0x20 ! 91: #define NMI_RECEIVED 0x10 ! 92: #define KMS_INT 0x08 ! 93: #define KMS_RECEIVED 0x04 ! 94: #define KMS_OVERRUN 0x02 ! 95: ! 96: #define TX_DMA_PENDING 0x80 ! 97: #define TX_DMA 0x40 ! 98: #define TX_CPU_PENDING 0x20 ! 99: #define TX_CPU 0x10 ! 100: #define RTX_PEND 0x08 ! 101: #define RTX 0x04 ! 102: #define KMS_ENABLE 0x02 ! 103: #define TX_LOOP 0x01 ! 104: ! 105: ! 106: /* KMS commands */ ! 107: ! 108: /* Host commands */ ! 109: #define KMSCMD_RESET 0xFF ! 110: #define KMSCMD_ASNDOUT 0xC7 /* analog sound out */ ! 111: #define KMSCMD_KMREG 0xC5 /* access keyboard or mouse register */ ! 112: #define KMSCMD_CTRLOUT 0xC4 /* access volume control logic */ ! 113: #define KMSCMD_VOLCTRL 0xC2 /* simplified access to volume control */ ! 114: ! 115: #define KMSCMD_SND_IN 0x03 /* sound in */ ! 116: #define KMSCMD_SND_OUT 0x07 /* sound out */ ! 117: #define KMSCMD_SIO_MASK 0xC7 /* mask for sound in/out */ ! 118: ! 119: #define SIO_ENABLE 0x08 /* 1=enable, 0=disable sound */ ! 120: #define SIO_DBL_SMPL 0x10 /* 1=double sample, 0=normal */ ! 121: #define SIO_ZERO 0x20 /* double sample by 1=zero filling, 0=repetition */ ! 122: ! 123: /* Commands from KMS board */ ! 124: #define KMSCMD_CODEC_IN 0xC7 /* CODEC sound in */ ! 125: #define KMSCMD_KBD_RECV 0xC6 /* receive data from keyboard/mouse */ ! 126: #define KMSCMD_SO_REQ 0x07 /* sound out request */ ! 127: #define KMSCMD_SO_UNDR 0x0F /* sound out underrun */ ! 128: ! 129: void KMS_command(Uint8 command, Uint32 data); ! 130: ! 131: ! 132: /* Keyboard Registers */ ! 133: #define KM_REG_MASK 0xE0 ! 134: #define KM_READ 0x10 ! 135: #define KM_RESET 0x0F ! 136: #define KM_SET_ADDR 0xEF ! 137: #define KM_ADDR_MASK 0x0E ! 138: #define KM_ADDR_MOUSE 0x01 ! 139: ! 140: ! 141: /* Device mask ! 142: * ! 143: * xxxx xxxx xxxx xxxx xxxx xxxx xxxx ---- polled devices (7 device addresses, 4 bit each) ! 144: * ---- ---- ---- ---- ---- ---- ---- xxxx poll speed ! 145: */ ! 146: ! 147: Uint32 km_address = 0; ! 148: Uint32 km_dev_msk = 0; ! 149: ! 150: static void access_km_reg(Uint32 data) { ! 151: Uint8 reg_addr = (data>>24)&0xFF; ! 152: Uint8 reg_data = (data>>16)&0xFF; ! 153: ! 154: if (reg_addr==KM_RESET) { ! 155: Log_Printf(LOG_KMS_LEVEL, "Keyboard/Mouse: Reset"); ! 156: kms_response(); ! 157: return; ! 158: } ! 159: if (reg_addr==KM_SET_ADDR) { ! 160: Log_Printf(LOG_KMS_LEVEL, "Keyboard/Mouse: Set address to %i",(reg_data&KM_ADDR_MASK)>>1); ! 161: km_address = reg_data&KM_ADDR_MASK; ! 162: kms_response(); ! 163: return; ! 164: } ! 165: ! 166: bool device_kbd = (reg_addr&KM_ADDR_MOUSE) ? false : true; ! 167: int device_addr = (reg_addr&KM_ADDR_MASK)>>1; ! 168: int device_reg = (reg_addr&KM_REG_MASK)>>5; ! 169: bool read_reg = (reg_addr&KM_READ) ? true : false; ! 170: ! 171: Log_Printf(LOG_KMS_LEVEL, "%s %s %i, register %i",read_reg?"Reading":"Writing", ! 172: device_kbd?"keyboard":"mouse",device_addr,device_reg); ! 173: ! 174: if (reg_addr&KM_READ) { ! 175: switch (device_reg) { ! 176: case 0: ! 177: Log_Printf(LOG_KMS_LEVEL, "Poll device"); ! 178: break; ! 179: case 7: ! 180: Log_Printf(LOG_KMS_LEVEL, "Request device revision"); ! 181: break; ! 182: default: ! 183: Log_Printf(LOG_WARN, "Unknown device register"); ! 184: break; ! 185: } ! 186: } else { // device write ! 187: switch (device_reg) { ! 188: case 0: ! 189: if (device_kbd) { ! 190: Log_Printf(LOG_KMS_LEVEL, "Turn %s keyboard LED1",(reg_data&1)?"on":"off"); ! 191: Log_Printf(LOG_KMS_LEVEL, "Turn %s keyboard LED2",(reg_data&2)?"on":"off"); ! 192: break; ! 193: } ! 194: default: ! 195: Log_Printf(LOG_WARN, "Unknown device register"); ! 196: break; ! 197: } ! 198: } ! 199: kms_response(); ! 200: } ! 201: ! 202: void KMS_command(Uint8 command, Uint32 data) { ! 203: switch (command) { ! 204: case KMSCMD_KBD_RECV: // keyboard poll ! 205: km_dev_msk=data; ! 206: return; ! 207: ! 208: case KMSCMD_RESET: ! 209: Log_Printf(LOG_KMS_LEVEL, "[KMS] Reset"); ! 210: Log_Printf(LOG_KMS_LEVEL, "[KMS] Data = %08X",data); ! 211: break; ! 212: case KMSCMD_ASNDOUT: ! 213: Log_Printf(LOG_KMS_LEVEL, "[KMS] Analog sound out"); ! 214: Log_Printf(LOG_KMS_LEVEL, "[KMS] Data = %08X",data); ! 215: break; ! 216: case KMSCMD_KMREG: ! 217: Log_Printf(LOG_KMS_LEVEL, "[KMS] Access keyboard/mouse register"); ! 218: Log_Printf(LOG_KMS_LEVEL, "[KMS] Data = %08X",data); ! 219: access_km_reg(data); ! 220: break; ! 221: case KMSCMD_CTRLOUT: ! 222: Log_Printf(LOG_KMS_LEVEL, "[KMS] Access volume control logic"); ! 223: Log_Printf(LOG_KMS_LEVEL, "[KMS] Data = %08X",data); ! 224: snd_gpo_access(data>>24); ! 225: break; ! 226: case KMSCMD_VOLCTRL: ! 227: Log_Printf(LOG_KMS_LEVEL, "[KMS] Access volume control (simple)"); ! 228: Log_Printf(LOG_KMS_LEVEL, "[KMS] Data = %08X",data); ! 229: break; ! 230: ! 231: default: // commands without data ! 232: if ((command&KMSCMD_SIO_MASK)==KMSCMD_SND_OUT) { ! 233: Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound out command:"); ! 234: ! 235: if (command&SIO_ENABLE) { ! 236: Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound out enable."); ! 237: if (command&SIO_DBL_SMPL) { ! 238: Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound out double sample."); ! 239: if (command&SIO_ZERO) { ! 240: Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound out double sample by zero filling."); ! 241: } else { ! 242: Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound out double sample by repetition."); ! 243: } ! 244: } else { ! 245: Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound out normal sample."); ! 246: } ! 247: snd_start_output(command&(SIO_DBL_SMPL|SIO_ZERO)); ! 248: } else { ! 249: Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound out disable."); ! 250: kms.status.snd_dma &= ~(SNDOUT_DMA_UNDERRUN|SNDOUT_DMA_REQUEST); ! 251: snd_stop_output(); ! 252: } ! 253: } else if ((command&KMSCMD_SIO_MASK)==KMSCMD_SND_IN) { ! 254: Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound in command"); ! 255: ! 256: if (command&SIO_ENABLE) { ! 257: Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound in enable."); ! 258: snd_start_input(command); ! 259: } else { ! 260: Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound in disable."); ! 261: kms.status.snd_dma &= ~(SNDIN_DMA_OVERRUN|SNDIN_DMA_REQUEST); ! 262: snd_stop_input(); ! 263: } ! 264: } else { ! 265: Log_Printf(LOG_WARN, "[KMS] Unknown command!"); ! 266: } ! 267: return; ! 268: } ! 269: } ! 270: ! 271: ! 272: void KMS_Ctrl_Snd_Write(void) { ! 273: Uint8 val = IoMem[IoAccessCurrentAddress&IO_SEG_MASK]; ! 274: ! 275: kms.status.snd_dma &= ~(SNDOUT_DMA_ENABLE|SNDIN_DMA_ENABLE); ! 276: kms.status.snd_dma |= (val&(SNDOUT_DMA_ENABLE|SNDIN_DMA_ENABLE)); ! 277: ! 278: if (val&SNDOUT_DMA_UNDERRUN && (!snd_output_active())) { ! 279: kms.status.snd_dma &= ~(SNDOUT_DMA_UNDERRUN|SNDOUT_DMA_REQUEST); ! 280: set_interrupt(INT_SOUND_OVRUN, RELEASE_INT); ! 281: } ! 282: if (val&SNDIN_DMA_OVERRUN && (!snd_input_active())) { ! 283: kms.status.snd_dma &= ~(SNDIN_DMA_OVERRUN|SNDIN_DMA_REQUEST); ! 284: set_interrupt(INT_SOUND_OVRUN, RELEASE_INT); ! 285: } ! 286: } ! 287: ! 288: void KMS_Stat_Snd_Read(void) { ! 289: IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = kms.status.snd_dma; ! 290: } ! 291: ! 292: void kms_sndout_underrun() { ! 293: kms.status.snd_dma |= SNDOUT_DMA_UNDERRUN|SNDOUT_DMA_REQUEST; ! 294: set_interrupt(INT_SOUND_OVRUN, SET_INT); ! 295: } ! 296: ! 297: void kms_sndin_overrun() { ! 298: kms.status.snd_dma |= SNDIN_DMA_OVERRUN|SNDIN_DMA_REQUEST; ! 299: set_interrupt(INT_SOUND_OVRUN, SET_INT); ! 300: } ! 301: ! 302: void KMS_Ctrl_KM_Write(void) { ! 303: Uint8 val = IoMem[IoAccessCurrentAddress&IO_SEG_MASK]; ! 304: ! 305: if (val&KBD_OVERRUN) { ! 306: kms.status.km &= ~(KBD_RECEIVED|KBD_OVERRUN|KBD_INT); ! 307: set_interrupt(INT_KEYMOUSE, RELEASE_INT); ! 308: } ! 309: if (val&NMI_RECEIVED) { ! 310: kms.status.km &= ~NMI_RECEIVED; ! 311: set_interrupt(INT_NMI, RELEASE_INT); ! 312: } ! 313: if (val&KMS_OVERRUN) { ! 314: kms.status.km &= ~(KMS_RECEIVED|KMS_OVERRUN|KMS_INT); ! 315: set_interrupt(INT_MONITOR, RELEASE_INT); ! 316: } ! 317: } ! 318: ! 319: void KMS_Stat_KM_Read(void) { ! 320: IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = kms.status.km; ! 321: } ! 322: ! 323: void KMS_Ctrl_TX_Write(void) { ! 324: Uint8 val = IoMem[IoAccessCurrentAddress&IO_SEG_MASK]; ! 325: ! 326: kms.status.transmit &= ~(KMS_ENABLE|TX_LOOP); ! 327: kms.status.transmit |= (val&(KMS_ENABLE|TX_LOOP)); ! 328: } ! 329: ! 330: void KMS_Stat_TX_Read(void) { ! 331: IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = kms.status.transmit; ! 332: } ! 333: ! 334: void KMS_Ctrl_Cmd_Write(void) { ! 335: kms.status.cmd = IoMem[IoAccessCurrentAddress&IO_SEG_MASK]; ! 336: } ! 337: ! 338: void KMS_Stat_Cmd_Read(void) { ! 339: IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = kms.status.cmd; ! 340: } ! 341: ! 342: ! 343: /* KMS data register (0x0200E004) */ ! 344: ! 345: void KMS_Data_Write(void) { ! 346: kms.data = IoMem_ReadLong(IoAccessCurrentAddress&IO_SEG_MASK); ! 347: KMS_command(kms.status.cmd, kms.data); ! 348: } ! 349: ! 350: void KMS_Data_Read(void) { ! 351: IoMem_WriteLong(IoAccessCurrentAddress&IO_SEG_MASK, kms.data); ! 352: } ! 353: ! 354: ! 355: /* KMS keyboard and mouse data register (0x0200E008) * ! 356: * ! 357: * x--- ---- ---- ---- ---- ---- ---- ---- always 0 ! 358: * -x-- ---- ---- ---- ---- ---- ---- ---- 1 = no response error, 0 = normal event ! 359: * --x- ---- ---- ---- ---- ---- ---- ---- 1 = user poll, 0 = internal poll ! 360: * ---x ---- ---- ---- ---- ---- ---- ---- 1 = invalid/master, 0 = valid/slave (user/internal) ! 361: * ---- xxxx ---- ---- ---- ---- ---- ---- device address (lowest bit 1 = mouse, 0 = keyboard) ! 362: * ---- ---- xxxx xxxx ---- ---- ---- ---- chip revision: 0 = old, 1 = new, 2 = digital ! 363: * ! 364: * Mouse data: ! 365: * ---- ---- ---- ---- xxxx xxx- ---- ---- mouse y ! 366: * ---- ---- ---- ---- ---- ---x ---- ---- right button up (1) or down (0) ! 367: * ---- ---- ---- ---- ---- ---- xxxx xxx- mouse x ! 368: * ---- ---- ---- ---- ---- ---- ---- ---x left button up (1) or down (0) ! 369: * ! 370: * Keyboard data: ! 371: * ---- ---- ---- ---- x--- ---- ---- ---- valid (1) or invalid (0) ! 372: * ---- ---- ---- ---- -x-- ---- ---- ---- right alt ! 373: * ---- ---- ---- ---- --x- ---- ---- ---- left alt ! 374: * ---- ---- ---- ---- ---x ---- ---- ---- right command ! 375: * ---- ---- ---- ---- ---- x--- ---- ---- left command ! 376: * ---- ---- ---- ---- ---- -x-- ---- ---- right shift ! 377: * ---- ---- ---- ---- ---- --x- ---- ---- left shift ! 378: * ---- ---- ---- ---- ---- ---x ---- ---- control ! 379: * ---- ---- ---- ---- ---- ---- x--- ---- key up (1) or down (0) ! 380: * ---- ---- ---- ---- ---- ---- -xxx xxxx keycode ! 381: */ ! 382: ! 383: #define NO_RESPONSE_ERR 0x40000000 ! 384: #define USER_POLL 0x20000000 ! 385: #define DEVICE_INVALID 0x10000000 ! 386: #define DEVICE_MASTER 0x10000000 ! 387: ! 388: #define DEVICE_ADDR_MSK 0x0E000000 ! 389: #define DEVICE_MOUSE 0x01000000 ! 390: ! 391: #define MOUSE_Y 0x0000FE00 ! 392: #define MOUSE_RIGHT_UP 0x00000100 ! 393: #define MOUSE_X 0x000000FE ! 394: #define MOUSE_LEFT_UP 0x00000001 ! 395: ! 396: #define KBD_KEY_VALID 0x00008000 ! 397: #define KBD_MOD_MASK 0x00007F00 ! 398: #define KBD_KEY_UP 0x00000080 ! 399: #define KBD_KEY_MASK 0x0000007F ! 400: ! 401: ! 402: bool m_button_right = false; ! 403: bool m_button_left = false; ! 404: bool m_move_left = false; ! 405: bool m_move_up = false; ! 406: int m_move_x = 0; ! 407: int m_move_y = 0; ! 408: int m_move_dx = 0; ! 409: int m_move_dy = 0; ! 410: void kms_mouse_move_step(void); ! 411: ! 412: ! 413: void KMS_KM_Data_Read(void) { ! 414: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, kms.km_data); ! 415: ! 416: kms.status.km &= ~(KBD_RECEIVED|KBD_INT); ! 417: set_interrupt(INT_KEYMOUSE, RELEASE_INT); ! 418: } ! 419: ! 420: static void kms_interrupt(void) { ! 421: kms.status.cmd = KMSCMD_KBD_RECV; ! 422: ! 423: if (kms.status.km&KBD_RECEIVED) { ! 424: kms.status.km |= KBD_OVERRUN; ! 425: } ! 426: kms.status.km |= (KBD_RECEIVED|KBD_INT); ! 427: set_interrupt(INT_KEYMOUSE, SET_INT); ! 428: } ! 429: ! 430: static bool kms_device_enabled(int dev_addr) { ! 431: int i,mask; ! 432: ! 433: for (i=28; i>4; i-=4) { ! 434: mask=(km_dev_msk>>i)&0xF; ! 435: if(mask==dev_addr && mask!=0xF) ! 436: return true; ! 437: } ! 438: Log_Printf(LOG_KMS_LEVEL, "[KMS] Device %i disabled (mask: %08X)",dev_addr,km_dev_msk); ! 439: return false; ! 440: } ! 441: ! 442: void kms_keydown(Uint8 modkeys, Uint8 keycode) { ! 443: if ((keycode==0x26)&&(modkeys&0x18)) { /* backquote and one or both command keys */ ! 444: Log_Printf(LOG_WARN, "Keyboard initiated NMI!"); ! 445: set_interrupt(INT_NMI, SET_INT); ! 446: return; ! 447: } ! 448: ! 449: if ((keycode==0x25)&&((modkeys&0x28)==0x28)) { /* asterisk and left alt and left command key */ ! 450: Log_Printf(LOG_WARN, "Keyboard initiated CPU reset!"); ! 451: host_darkmatter(false); ! 452: M68000_Reset(false); ! 453: return; ! 454: } ! 455: ! 456: if (keycode==0x58) { /* Power key */ ! 457: rtc_request_power_down(); ! 458: return; ! 459: } ! 460: ! 461: if (kms_device_enabled(km_address)) { ! 462: kms.km_data = (km_address<<24)|DEVICE_MASTER; /* keyboard */ ! 463: ! 464: kms.km_data |= (modkeys<<8)|keycode|KBD_KEY_VALID; ! 465: ! 466: kms_interrupt(); ! 467: } ! 468: } ! 469: ! 470: void kms_keyup(Uint8 modkeys, Uint8 keycode) { ! 471: if (keycode==0x58) { ! 472: rtc_stop_pdown_request(); ! 473: return; ! 474: } ! 475: ! 476: if (kms_device_enabled(km_address)) { ! 477: kms.km_data = (km_address<<24)|DEVICE_MASTER; /* keyboard */ ! 478: ! 479: kms.km_data |= (modkeys<<8)|keycode|KBD_KEY_VALID|KBD_KEY_UP; ! 480: ! 481: kms_interrupt(); ! 482: } ! 483: } ! 484: ! 485: void kms_mouse_button(bool left, bool down) { ! 486: if (left) { ! 487: m_button_left = down; ! 488: } else { ! 489: m_button_right = down; ! 490: } ! 491: ! 492: if (kms_device_enabled(km_address|KM_ADDR_MOUSE)) { ! 493: kms.km_data = (km_address|KM_ADDR_MOUSE)<<24; /* mouse */ ! 494: ! 495: kms.km_data |= m_button_left?0:MOUSE_LEFT_UP; ! 496: kms.km_data |= m_button_right?0:MOUSE_RIGHT_UP; ! 497: ! 498: kms_interrupt(); ! 499: } ! 500: } ! 501: ! 502: #define MOUSE_STEP_FREQ 1000 ! 503: ! 504: void kms_mouse_move(int x, bool left, int y, bool up) { ! 505: if (x<0 || y<0) abort(); ! 506: ! 507: m_move_left = left; ! 508: m_move_up = up; ! 509: ! 510: int xsteps = x / 8; if(xsteps == 0) xsteps = 1; ! 511: int ysteps = y / 8; if(ysteps == 0) ysteps = 1; ! 512: ! 513: m_move_x = x; ! 514: m_move_dx = x / xsteps; ! 515: ! 516: m_move_y = y; ! 517: m_move_dy = y / ysteps; ! 518: ! 519: CycInt_AddRelativeInterruptCycles(10, INTERRUPT_MOUSE); ! 520: } ! 521: ! 522: void kms_mouse_move_step(void) { ! 523: ! 524: int x = m_move_x > m_move_dx ? m_move_dx : m_move_x; ! 525: int y = m_move_y > m_move_dy ? m_move_dy : m_move_y; ! 526: ! 527: m_move_x -= x; ! 528: m_move_y -= y; ! 529: ! 530: if (!m_move_left && x>0) /* right */ ! 531: x=(0x40-x)|0x40; ! 532: if (!m_move_up && y>0) /* down */ ! 533: y=(0x40-y)|0x40; ! 534: ! 535: if (kms_device_enabled(km_address|KM_ADDR_MOUSE)) { ! 536: kms.km_data = (km_address|KM_ADDR_MOUSE)<<24; /* mouse */ ! 537: ! 538: kms.km_data |= (x<<1)&MOUSE_X; ! 539: kms.km_data |= (y<<9)&MOUSE_Y; ! 540: ! 541: kms.km_data |= m_button_left?0:MOUSE_LEFT_UP; ! 542: kms.km_data |= m_button_right?0:MOUSE_RIGHT_UP; ! 543: ! 544: kms_interrupt(); ! 545: } ! 546: } ! 547: ! 548: void kms_response(void) { ! 549: kms.km_data = km_address<<24; /* keyboard */ ! 550: kms.km_data |= USER_POLL; ! 551: kms.km_data |= (NO_RESPONSE_ERR|DEVICE_INVALID); /* checked on real hardware */ ! 552: ! 553: kms_interrupt(); ! 554: } ! 555: ! 556: void Mouse_Handler(void) { ! 557: CycInt_AcknowledgeInterrupt(); ! 558: ! 559: if (m_move_x > 0 || m_move_y > 0) { ! 560: kms_mouse_move_step(); ! 561: CycInt_AddRelativeInterruptUs((1000*1000)/MOUSE_STEP_FREQ, 0, INTERRUPT_MOUSE); ! 562: } ! 563: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.