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