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