VirtualBox

Ignore:
Timestamp:
Aug 9, 2011 12:01:37 PM (13 years ago)
Author:
vboxsync
Message:

DevPS2: Reworked and improved the KBC emulation.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Input/DevPS2.cpp

    r37466 r38377  
    199199    uint8_t status;
    200200    uint8_t mode;
     201    uint8_t dbbout;    /* data buffer byte */
    201202    /* keyboard state */
    202203    int32_t kbd_write_cmd;
     
    311312        s->status &= ~KBD_STAT_MOUSE_OBF;
    312313        /* Keyboard data has priority if both kbd and aux data is available. */
    313         if (q->count != 0)
     314        if (q->count && !(s->mode & KBD_MODE_DISABLE_KBD))
    314315        {
    315316            s->status |= KBD_STAT_OBF;
     317            s->dbbout = q->data[q->rptr];
     318            if (++q->rptr == KBD_QUEUE_SIZE)
     319                q->rptr = 0;
     320            q->count--;
    316321        }
    317         else if (mcq->count != 0 || meq->count != 0)
     322        else if ((mcq->count || meq->count) /*&& !(s->mode & KBD_MODE_DISABLE_MOUSE)*/)
    318323        {
    319324            s->status |= KBD_STAT_OBF | KBD_STAT_MOUSE_OBF;
     325            if (mcq->count)
     326            {
     327                s->dbbout = mcq->data[mcq->rptr];
     328                if (++mcq->rptr == MOUSE_CMD_QUEUE_SIZE)
     329                    mcq->rptr = 0;
     330                mcq->count--;
     331            }
     332            else
     333            {
     334                s->dbbout = meq->data[meq->rptr];
     335                if (++meq->rptr == MOUSE_EVENT_QUEUE_SIZE)
     336                    meq->rptr = 0;
     337                meq->count--;
     338            }
    320339        }
    321340    }
     
    404423#endif /* IN_RING3 */
    405424
     425static void kbc_dbb_out(void *opaque, uint8_t val)
     426{
     427    KBDState *s = (KBDState*)opaque;
     428
     429    s->dbbout = val;
     430    /* Set the OBF and raise IRQ. */
     431    s->status |= KBD_STAT_OBF;
     432    if (s->mode & KBD_MODE_KBD_INT)
     433        PDMDevHlpISASetIrq(s->CTX_SUFF(pDevIns), 1, 1);
     434}
     435
    406436static uint32_t kbd_read_status(void *opaque, uint32_t addr)
    407437{
     
    425455    switch(val) {
    426456    case KBD_CCMD_READ_MODE:
    427         kbd_queue(s, s->mode, 0);
     457        kbc_dbb_out(s, s->mode);
    428458        break;
    429459    case KBD_CCMD_WRITE_MODE:
     
    439469    case KBD_CCMD_MOUSE_ENABLE:
    440470        s->mode &= ~KBD_MODE_DISABLE_MOUSE;
     471        /* Check for queued input. */
     472        kbd_update_irq(s);
    441473        break;
    442474    case KBD_CCMD_TEST_MOUSE:
    443         kbd_queue(s, 0x00, 0);
     475        kbc_dbb_out(s, 0x00);
    444476        break;
    445477    case KBD_CCMD_SELF_TEST:
     478        /* Enable the A20 line - that is the power-on state(!). */
     479# ifndef IN_RING3
     480        if (!PDMDevHlpA20IsEnabled(s->CTX_SUFF(pDevIns)))
     481        {
     482            rc = VINF_IOM_HC_IOPORT_WRITE;
     483            break;
     484        }
     485# else /* IN_RING3 */
     486        PDMDevHlpA20Set(s->CTX_SUFF(pDevIns), true);
     487# endif /* IN_RING3 */
    446488        s->status |= KBD_STAT_SELFTEST;
    447         kbd_queue(s, 0x55, 0);
     489        s->mode |= KBD_MODE_DISABLE_KBD;
     490        kbc_dbb_out(s, 0x55);
    448491        break;
    449492    case KBD_CCMD_KBD_TEST:
    450         kbd_queue(s, 0x00, 0);
     493        kbc_dbb_out(s, 0x00);
    451494        break;
    452495    case KBD_CCMD_KBD_DISABLE:
    453496        s->mode |= KBD_MODE_DISABLE_KBD;
    454         kbd_update_irq(s);
    455497        break;
    456498    case KBD_CCMD_KBD_ENABLE:
    457499        s->mode &= ~KBD_MODE_DISABLE_KBD;
     500        /* Check for queued input. */
    458501        kbd_update_irq(s);
    459502        break;
    460503    case KBD_CCMD_READ_INPORT:
    461         kbd_queue(s, 0x00, 0);
     504        kbc_dbb_out(s, 0x00);
    462505        break;
    463506    case KBD_CCMD_READ_OUTPORT:
     
    472515        if (s->status & KBD_STAT_MOUSE_OBF)
    473516            val |= 0x20;
    474         kbd_queue(s, val, 0);
     517        kbc_dbb_out(s, val);
    475518        break;
    476519#ifdef TARGET_I386
     
    495538        /* Keyboard clock line is zero IFF keyboard is disabled */
    496539        val = (s->mode & KBD_MODE_DISABLE_KBD) ? 0 : 1;
    497         kbd_queue(s, val, 0);
     540        kbc_dbb_out(s, val);
    498541        break;
    499542    case KBD_CCMD_RESET:
     
    516559    case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
    517560    case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
    518         kbd_queue(s, 0, 0);
     561        kbc_dbb_out(s, 0);
    519562        Log(("kbd: reading non-standard RAM addr %#x\n", val & 0x1f));
    520563        break;
     
    529572{
    530573    KBDState *s = (KBDState*)opaque;
    531     KBDQueue *q;
    532     MouseCmdQueue *mcq;
    533     MouseEventQueue *meq;
    534     int val, index, aux;
    535 
    536     q = &s->queue;
    537     mcq = &s->mouse_command_queue;
    538     meq = &s->mouse_event_queue;
    539     if (q->count == 0 && mcq->count == 0 && meq->count == 0) {
    540         /* NOTE: if no data left, we return the last keyboard one
    541            (needed for EMM386) */
    542         /* XXX: need a timer to do things correctly */
    543         index = q->rptr - 1;
    544         if (index < 0)
    545             index = KBD_QUEUE_SIZE - 1;
    546         val = q->data[index];
    547     } else {
    548         aux = (s->status & KBD_STAT_MOUSE_OBF);
    549         if (!aux)
    550         {
    551             val = q->data[q->rptr];
    552             if (++q->rptr == KBD_QUEUE_SIZE)
    553                 q->rptr = 0;
    554             q->count--;
    555         }
    556         else
    557         {
    558             if (mcq->count)
    559             {
    560                 val = mcq->data[mcq->rptr];
    561                 if (++mcq->rptr == MOUSE_CMD_QUEUE_SIZE)
    562                     mcq->rptr = 0;
    563                 mcq->count--;
    564             }
    565             else
    566             {
    567                 val = meq->data[meq->rptr];
    568                 if (++meq->rptr == MOUSE_EVENT_QUEUE_SIZE)
    569                     meq->rptr = 0;
    570                 meq->count--;
    571             }
    572         }
    573         /* reading deasserts IRQ */
    574         if (aux)
    575             PDMDevHlpISASetIrq(s->CTX_SUFF(pDevIns), 12, 0);
    576         else
    577             PDMDevHlpISASetIrq(s->CTX_SUFF(pDevIns), 1, 0);
    578         /* Reading data clears the OBF bits, too. */
    579         s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF);
    580     }
    581     /* reassert IRQs if data left */
     574    uint32_t val;
     575
     576    /* Return the current DBB contents. */
     577    val = s->dbbout;
     578
     579    /* Reading the DBB deasserts IRQs... */
     580    if (s->status & KBD_STAT_MOUSE_OBF)
     581        PDMDevHlpISASetIrq(s->CTX_SUFF(pDevIns), 12, 0);
     582    else
     583        PDMDevHlpISASetIrq(s->CTX_SUFF(pDevIns), 1, 0);
     584    /* ...and clears the OBF bits. */
     585    s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF);
     586
     587    /* Check if more data is available. */
    582588    kbd_update_irq(s);
    583589#ifdef DEBUG_KBD
     
    591597    s->scan_enabled = 1;
    592598    s->scancode_set = 2;
     599    /* Flush the keyboard queue. */
     600    s->queue.count = 0;
     601    s->queue.rptr = 0;
     602    s->queue.wptr = 0;
    593603}
    594604
     
    10551065    switch(s->write_cmd) {
    10561066    case 0:
     1067        /* Automatically enables keyboard interface. */
     1068        s->mode &= ~KBD_MODE_DISABLE_KBD;
    10571069        rc = kbd_write_keyboard(s, val);
    10581070        break;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette