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

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
        !            15: mouse_setup()
        !            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.