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

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

unix.superglobalmegacorp.com

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