Annotation of qemu/roms/seabios/src/mouse.c, revision 1.1.1.4

1.1       root        1: // 16bit code to handle mouse events.
                      2: //
                      3: // Copyright (C) 2008  Kevin O'Connor <[email protected]>
                      4: // Copyright (C) 2002  MandrakeSoft S.A.
                      5: //
                      6: // This file may be distributed under the terms of the GNU LGPLv3 license.
                      7: 
                      8: #include "biosvar.h" // GET_EBDA
                      9: #include "util.h" // debug_isr
                     10: #include "pic.h" // eoi_pic2
                     11: #include "bregs.h" // struct bregs
1.1.1.3   root       12: #include "ps2port.h" // ps2_mouse_command
                     13: #include "usb-hid.h" // usb_mouse_command
1.1       root       14: 
                     15: void
1.1.1.2   root       16: mouse_setup(void)
1.1       root       17: {
                     18:     if (! CONFIG_MOUSE)
                     19:         return;
                     20:     dprintf(3, "init mouse\n");
                     21:     // pointing device installed
                     22:     SETBITS_BDA(equipment_list_flags, 0x04);
                     23: }
                     24: 
1.1.1.3   root       25: static inline int
                     26: mouse_command(int command, u8 *param)
                     27: {
                     28:     if (usb_mouse_active())
                     29:         return usb_mouse_command(command, param);
                     30:     return ps2_mouse_command(command, param);
                     31: }
                     32: 
1.1       root       33: #define RET_SUCCESS      0x00
                     34: #define RET_EINVFUNCTION 0x01
                     35: #define RET_EINVINPUT    0x02
                     36: #define RET_EINTERFACE   0x03
                     37: #define RET_ENEEDRESEND  0x04
                     38: #define RET_ENOHANDLER   0x05
                     39: 
                     40: // Disable Mouse
                     41: static void
                     42: mouse_15c20000(struct bregs *regs)
                     43: {
1.1.1.4 ! root       44:     int ret = mouse_command(PSMOUSE_CMD_DISABLE, NULL);
1.1       root       45:     if (ret)
                     46:         set_code_invalid(regs, RET_ENEEDRESEND);
                     47:     else
                     48:         set_code_success(regs);
                     49: }
                     50: 
                     51: // Enable Mouse
                     52: static void
                     53: mouse_15c20001(struct bregs *regs)
                     54: {
1.1.1.4 ! root       55:     u8 mouse_flags_2 = GET_EBDA(mouse_flag2);
1.1       root       56:     if ((mouse_flags_2 & 0x80) == 0) {
                     57:         set_code_invalid(regs, RET_ENOHANDLER);
                     58:         return;
                     59:     }
                     60: 
1.1.1.3   root       61:     int ret = mouse_command(PSMOUSE_CMD_ENABLE, NULL);
1.1       root       62:     if (ret)
                     63:         set_code_invalid(regs, RET_ENEEDRESEND);
                     64:     else
                     65:         set_code_success(regs);
                     66: }
                     67: 
                     68: static void
                     69: mouse_15c200XX(struct bregs *regs)
                     70: {
                     71:     set_code_unimplemented(regs, RET_EINVFUNCTION);
                     72: }
                     73: 
                     74: // Disable/Enable Mouse
                     75: static void
                     76: mouse_15c200(struct bregs *regs)
                     77: {
                     78:     switch (regs->bh) {
                     79:     case 0x00: mouse_15c20000(regs); break;
                     80:     case 0x01: mouse_15c20001(regs); break;
                     81:     default:   mouse_15c200XX(regs); break;
                     82:     }
                     83: }
                     84: 
                     85: // Reset Mouse
                     86: static void
                     87: mouse_15c201(struct bregs *regs)
                     88: {
                     89:     u8 param[2];
1.1.1.3   root       90:     int ret = mouse_command(PSMOUSE_CMD_RESET_BAT, param);
1.1       root       91:     if (ret) {
                     92:         set_code_invalid(regs, RET_ENEEDRESEND);
                     93:         return;
                     94:     }
                     95:     regs->bl = param[0];
                     96:     regs->bh = param[1];
                     97:     set_code_success(regs);
                     98: }
                     99: 
                    100: // Set Sample Rate
                    101: static void
                    102: mouse_15c202(struct bregs *regs)
                    103: {
                    104:     static u8 VAR16 sample_rates[7] = {10, 20, 40, 60, 80, 100, 200};
                    105:     if (regs->bh >= ARRAY_SIZE(sample_rates)) {
                    106:         set_code_invalid(regs, RET_EINVINPUT);
                    107:         return;
                    108:     }
                    109:     u8 mouse_data1 = GET_GLOBAL(sample_rates[regs->bh]);
1.1.1.3   root      110:     int ret = mouse_command(PSMOUSE_CMD_SETRATE, &mouse_data1);
1.1       root      111:     if (ret)
                    112:         set_code_invalid(regs, RET_ENEEDRESEND);
                    113:     else
                    114:         set_code_success(regs);
                    115: }
                    116: 
                    117: // Set Resolution
                    118: static void
                    119: mouse_15c203(struct bregs *regs)
                    120: {
                    121:     // BH:
                    122:     //      0 =  25 dpi, 1 count  per millimeter
                    123:     //      1 =  50 dpi, 2 counts per millimeter
                    124:     //      2 = 100 dpi, 4 counts per millimeter
                    125:     //      3 = 200 dpi, 8 counts per millimeter
                    126:     if (regs->bh >= 4) {
                    127:         set_code_invalid(regs, RET_EINVINPUT);
                    128:         return;
                    129:     }
                    130:     u8 param = regs->bh;
1.1.1.3   root      131:     int ret = mouse_command(PSMOUSE_CMD_SETRES, &param);
1.1       root      132:     if (ret)
                    133:         set_code_invalid(regs, RET_ENEEDRESEND);
                    134:     else
                    135:         set_code_success(regs);
                    136: }
                    137: 
                    138: // Get Device ID
                    139: static void
                    140: mouse_15c204(struct bregs *regs)
                    141: {
                    142:     u8 param[2];
1.1.1.3   root      143:     int ret = mouse_command(PSMOUSE_CMD_GETID, param);
1.1       root      144:     if (ret) {
                    145:         set_code_invalid(regs, RET_ENEEDRESEND);
                    146:         return;
                    147:     }
                    148:     regs->bh = param[0];
                    149:     set_code_success(regs);
                    150: }
                    151: 
                    152: // Initialize Mouse
                    153: static void
                    154: mouse_15c205(struct bregs *regs)
                    155: {
                    156:     if (regs->bh != 3) {
                    157:         set_code_invalid(regs, RET_EINTERFACE);
                    158:         return;
                    159:     }
                    160:     u16 ebda_seg = get_ebda_seg();
                    161:     SET_EBDA2(ebda_seg, mouse_flag1, 0x00);
                    162:     SET_EBDA2(ebda_seg, mouse_flag2, regs->bh);
                    163: 
                    164:     // Reset Mouse
                    165:     mouse_15c201(regs);
                    166: }
                    167: 
                    168: // Return Status
                    169: static void
                    170: mouse_15c20600(struct bregs *regs)
                    171: {
                    172:     u8 param[3];
1.1.1.3   root      173:     int ret = mouse_command(PSMOUSE_CMD_GETINFO, param);
1.1       root      174:     if (ret) {
                    175:         set_code_invalid(regs, RET_ENEEDRESEND);
                    176:         return;
                    177:     }
                    178:     regs->bl = param[0];
                    179:     regs->cl = param[1];
                    180:     regs->dl = param[2];
                    181:     set_code_success(regs);
                    182: }
                    183: 
                    184: // Set Scaling Factor to 1:1
                    185: static void
                    186: mouse_15c20601(struct bregs *regs)
                    187: {
1.1.1.3   root      188:     int ret = mouse_command(PSMOUSE_CMD_SETSCALE11, NULL);
1.1       root      189:     if (ret)
                    190:         set_code_invalid(regs, RET_ENEEDRESEND);
                    191:     else
                    192:         set_code_success(regs);
                    193: }
                    194: 
                    195: // Set Scaling Factor to 2:1
                    196: static void
                    197: mouse_15c20602(struct bregs *regs)
                    198: {
1.1.1.3   root      199:     int ret = mouse_command(PSMOUSE_CMD_SETSCALE21, NULL);
1.1       root      200:     if (ret)
                    201:         set_code_invalid(regs, RET_ENEEDRESEND);
                    202:     else
                    203:         set_code_success(regs);
                    204: }
                    205: 
                    206: static void
                    207: mouse_15c206XX(struct bregs *regs)
                    208: {
                    209:     set_code_unimplemented(regs, RET_EINVFUNCTION);
                    210: }
                    211: 
                    212: // Return Status & Set Scaling Factor...
                    213: static void
                    214: mouse_15c206(struct bregs *regs)
                    215: {
                    216:     switch (regs->bh) {
                    217:     case 0x00: mouse_15c20600(regs); break;
                    218:     case 0x01: mouse_15c20601(regs); break;
                    219:     case 0x02: mouse_15c20602(regs); break;
                    220:     default:   mouse_15c206XX(regs); break;
                    221:     }
                    222: }
                    223: 
                    224: // Set Mouse Handler Address
                    225: static void
                    226: mouse_15c207(struct bregs *regs)
                    227: {
                    228:     struct segoff_s farptr = SEGOFF(regs->es, regs->bx);
                    229:     u16 ebda_seg = get_ebda_seg();
                    230:     u8 mouse_flags_2 = GET_EBDA2(ebda_seg, mouse_flag2);
                    231:     if (! farptr.segoff) {
                    232:         /* remove handler */
                    233:         if ((mouse_flags_2 & 0x80) != 0) {
                    234:             mouse_flags_2 &= ~0x80;
1.1.1.4 ! root      235:             mouse_command(PSMOUSE_CMD_DISABLE, NULL);
1.1       root      236:         }
                    237:     } else {
                    238:         /* install handler */
                    239:         mouse_flags_2 |= 0x80;
                    240:     }
                    241:     SET_EBDA2(ebda_seg, mouse_flag2, mouse_flags_2);
                    242:     SET_EBDA2(ebda_seg, far_call_pointer, farptr);
                    243:     set_code_success(regs);
                    244: }
                    245: 
                    246: static void
                    247: mouse_15c2XX(struct bregs *regs)
                    248: {
                    249:     set_code_unimplemented(regs, RET_EINVFUNCTION);
                    250: }
                    251: 
                    252: void
                    253: handle_15c2(struct bregs *regs)
                    254: {
                    255:     //debug_stub(regs);
                    256: 
                    257:     if (! CONFIG_MOUSE) {
                    258:         set_code_invalid(regs, RET_EUNSUPPORTED);
                    259:         return;
                    260:     }
                    261: 
                    262:     switch (regs->al) {
                    263:     case 0x00: mouse_15c200(regs); break;
                    264:     case 0x01: mouse_15c201(regs); break;
                    265:     case 0x02: mouse_15c202(regs); break;
                    266:     case 0x03: mouse_15c203(regs); break;
                    267:     case 0x04: mouse_15c204(regs); break;
                    268:     case 0x05: mouse_15c205(regs); break;
                    269:     case 0x06: mouse_15c206(regs); break;
                    270:     case 0x07: mouse_15c207(regs); break;
                    271:     default:   mouse_15c2XX(regs); break;
                    272:     }
                    273: }
                    274: 
1.1.1.3   root      275: void noinline
1.1       root      276: process_mouse(u8 data)
                    277: {
                    278:     if (!CONFIG_MOUSE)
                    279:         return;
                    280: 
                    281:     u16 ebda_seg = get_ebda_seg();
                    282:     u8 mouse_flags_1 = GET_EBDA2(ebda_seg, mouse_flag1);
                    283:     u8 mouse_flags_2 = GET_EBDA2(ebda_seg, mouse_flag2);
                    284: 
                    285:     if (! (mouse_flags_2 & 0x80))
                    286:         // far call handler not installed
                    287:         return;
                    288: 
                    289:     u8 package_count = mouse_flags_2 & 0x07;
                    290:     u8 index = mouse_flags_1 & 0x07;
                    291:     SET_EBDA2(ebda_seg, mouse_data[index], data);
                    292: 
                    293:     if ((index+1) < package_count) {
                    294:         mouse_flags_1++;
                    295:         SET_EBDA2(ebda_seg, mouse_flag1, mouse_flags_1);
                    296:         return;
                    297:     }
                    298: 
                    299:     u16 status = GET_EBDA2(ebda_seg, mouse_data[0]);
                    300:     u16 X      = GET_EBDA2(ebda_seg, mouse_data[1]);
                    301:     u16 Y      = GET_EBDA2(ebda_seg, mouse_data[2]);
                    302:     SET_EBDA2(ebda_seg, mouse_flag1, 0);
                    303: 
                    304:     struct segoff_s func = GET_EBDA2(ebda_seg, far_call_pointer);
1.1.1.3   root      305:     dprintf(16, "mouse farcall s=%04x x=%04x y=%04x func=%04x:%04x\n"
                    306:             , status, X, Y, func.seg, func.offset);
1.1       root      307: 
                    308:     asm volatile(
1.1.1.3   root      309:         "pushl %%ebp\n"
1.1       root      310:         "sti\n"
                    311: 
                    312:         "pushl %0\n"
                    313:         "pushw %w1\n"  // status
                    314:         "pushw %w2\n"  // X
                    315:         "pushw %w3\n"  // Y
                    316:         "pushw $0\n"   // Z
                    317:         "lcallw *8(%%esp)\n"
                    318:         "addl $12, %%esp\n"
                    319: 
                    320:         "cli\n"
                    321:         "cld\n"
1.1.1.3   root      322:         "popl %%ebp"
                    323:         : "+a"(func.segoff), "+c"(status), "+d"(X), "+b"(Y)
1.1       root      324:         :
1.1.1.3   root      325:         : "edi", "esi", "cc", "memory");
1.1       root      326: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.