VirtualBox

Changeset 2557 in vbox


Ignore:
Timestamp:
May 9, 2007 1:03:02 PM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
21015
Message:

Fixed and simplified BIOS int15 mouse service. Avoids spurious
scancode generation.

Location:
trunk/src/VBox
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/driver.h

    r1 r2557  
    5252    POINTL  ptlOrg;                     // Where this display is anchored in
    5353                                        //   the virtual desktop.
     54    POINTL  ptlDevOrg;                  // Device origin for DualView (0,0 for primary view).
    5455    ULONG   ulMode;                     // Mode the mini-port driver is in.
    5556    LONG    lDeltaScreen;               // Distance from one scan to the next.
     
    115116} CLIPRECTS;
    116117
     118/** Escape codes used to communicate with the VBox display
     119 *  driver from userland.
     120 */
     121#define VBOX_ESC_QUERY_SUPPORT          1110
    117122
    118123BOOL vboxVbvaEnable (PPDEV ppdev);
  • trunk/src/VBox/Additions/WINNT/Graphics/Display/enable.c

    r1376 r2557  
    2626    {   INDEX_DrvDisableSurface,        (PFN) DrvDisableSurface     },  //  4
    2727    {   INDEX_DrvAssertMode,            (PFN) DrvAssertMode         },  //  5
    28     {   INDEX_DrvOffset,                (PFN) DrvOffset             },  //  6
    2928    {   INDEX_DrvDisableDriver,         (PFN) DrvDisableDriver      },  //  8
    3029    {   INDEX_DrvRealizeBrush,          (PFN) DrvRealizeBrush       },  // 12
     
    6766}
    6867
    69 ULONG APIENTRY DrvEscape(
    70     SURFOBJ *pso,
    71     ULONG    iEsc,
    72     ULONG    cjIn,
    73     PVOID    pvIn,
    74     ULONG    cjOut,
    75     PVOID    pvOut
    76     )
    77 {
    78     DISPDBG((0, "Experimental %s: %p, %p, %p, %p, %p, %p\n", __FUNCTION__, pso, iEsc, cjIn, pvIn, cjOut, pvOut));
    79     return 0;
    80 }
    81    
    8268BOOL DrvConnect (PVOID x1, PVOID x2, PVOID x3, PVOID x4)
    8369{
     
    138124    DISPDBG((0, "Experimental %s: %p, %p, %p, %p\n", __FUNCTION__, dhpdev, pCallBacks, pSurfaceCallBacks, pPaletteCallBacks));
    139125    return FALSE;
     126}
     127
     128/******************************Public*Routine******************************\
     129* DrvEscape
     130*
     131* Called by GDI in response to user level ExtEscape() calls
     132*
     133* Currently unused, but could be useful if we needed to communicate with the
     134* display driver and/or miniport from userspace apps.
     135*
     136\**************************************************************************/
     137
     138ULONG DrvEscape(
     139SURFOBJ *pso,
     140ULONG iEsc,
     141ULONG cjIn,
     142PVOID pvIn,
     143ULONG cjOut,
     144PVOID pvOut)
     145{
     146    ULONG ulResult = 0;
     147
     148    DISPDBG((0, "Experimental %s: %p, %p, %p, %p, %p, %p\n", __FUNCTION__, pso, iEsc, cjIn, pvIn, cjOut, pvOut));
     149
     150    switch(iEsc)
     151    {
     152        case VBOX_ESC_QUERY_SUPPORT:
     153            DISPDBG((3, "VBOX_ESC_QUERY_SUPPORT (PSO = %p)\n", pso));
     154            ulResult = 1;
     155            break;
     156        default:
     157            DISPDBG((3, "unknown escape %d\n", iEsc));
     158    }
     159    return ulResult;
    140160}
    141161
     
    167187    {   INDEX_DrvSaveScreenBits,        (PFN) DrvSaveScreenBits     },  // 40 0x28
    168188    {   INDEX_DrvGetModes,              (PFN) DrvGetModes           },  // 41 0x29
     189    {   INDEX_DrvNotify,                (PFN) DrvNotify             },  // 87 0x57
    169190//     /* Experimental. */
     191//     {   INDEX_DrvEscape,                (PFN) DrvEscape             },       // 24 0x18
    170192//     {   0x7,                            (PFN) DrvResetPDEV          },       // 0x7
    171193//     {   0x5b,                           (PFN) DrvNineGrid           },       // 0x5b
    172194//     {   0x2b,                           (PFN) DrvDestroyFont        },       // 0x2b
    173 //     {   0x18,                           (PFN) DrvEscape             },       // 0x18
    174195//     {   0x4d,                           (PFN) DrvConnect            },       // 0x4d
    175196//     {   0x4e,                           (PFN) DrvDisconnect         },       // 0x4e
     
    404425
    405426    EngFreeMem(dhpdev);
    406 }
    407 
    408 /******************************Public*Routine******************************\
    409 * VOID DrvOffset
    410 *
    411 * DescriptionText
    412 *
    413 \**************************************************************************/
    414 
    415 BOOL DrvOffset(
    416 SURFOBJ*    pso,
    417 LONG        x,
    418 LONG        y,
    419 FLONG       flReserved)
    420 {
    421     PDEV*   ppdev = (PDEV*) pso->dhpdev;
    422 
    423     // Add back last offset that we subtracted.  I could combine the next
    424     // two statements, but I thought this was more clear.  It's not
    425     // performance critical anyway.
    426 
    427     ppdev->pjScreen += ((ppdev->ptlOrg.y * ppdev->lDeltaScreen) +
    428                         (ppdev->ptlOrg.x * ((ppdev->ulBitCount+1) >> 3)));
    429 
    430     // Subtract out new offset
    431 
    432     ppdev->pjScreen -= ((y * ppdev->lDeltaScreen) +
    433                         (x * ((ppdev->ulBitCount+1) >> 3)));
    434 
    435     ppdev->ptlOrg.x = x;
    436     ppdev->ptlOrg.y = y;
    437 
    438     return(TRUE);
    439427}
    440428
     
    822810}
    823811
     812/******************************Public*Routine******************************\
     813* DrvNotify
     814*
     815* Called by GDI to notify us of certain "interesting" events
     816*
     817* DN_DEVICE_ORIGIN is used to communicate the X/Y offsets of individual monitors
     818*                  when DualView is in effect.
     819*
     820\**************************************************************************/
     821
     822VOID DrvNotify(
     823SURFOBJ *pso,
     824ULONG iType,
     825PVOID pvData)
     826{
     827    PDEV*   ppdev = (PDEV*) pso->dhpdev;
     828
     829    DISPDBG((0, "VBoxDisp::DrvNotify called.\n"));
     830
     831    switch(iType)
     832    {
     833        case DN_DEVICE_ORIGIN:
     834            ppdev->ptlDevOrg = *(PPOINTL)pvData;
     835            DISPDBG((3, "DN_DEVICE_ORIGIN: %d, %d (PSO = %p)\n", ppdev->ptlDevOrg.x,
     836                     ppdev->ptlDevOrg.y, pso));
     837            break;
     838        case DN_DRAWING_BEGIN:
     839            DISPDBG((3, "DN_DRAWING_BEGIN (PSO = %p)\n", pso));
     840            break;
     841    }
     842}
  • trunk/src/VBox/Devices/PC/BIOS/rombios.c

    r2535 r2557  
    890890static void           bios_printf();
    891891
    892 static Bit8u          inhibit_mouse_int_and_events();
    893 static void           enable_mouse_int_and_events();
    894892static Bit8u          send_to_mouse_ctrl();
    895893static Bit8u          get_mouse_data();
     
    18231821
    18241822    /* send cmd: scan code convert, disable mouse, enable IRQ 1 */
    1825     outb(0x60, 0x61);
     1823    outb(0x60, 0x65);
    18261824
    18271825    /* Wait until buffer is empty */
     
    40714069  Bit16u mouse_driver_seg;
    40724070  Bit16u mouse_driver_offset;
    4073   Bit8u  comm_byte, prev_command_byte;
     4071  Bit8u  mouse_cmd;
    40744072  Bit8u  ret, mouse_data1, mouse_data2, mouse_data3;
    40754073
     
    40894087      // 80/86: mouse service not implemented
    40904088
     4089      if (regs.u.r8.al > 7) {
     4090BX_DEBUG_INT15("unsupported subfn\n");
     4091        // invalid function
     4092        SET_CF();
     4093        regs.u.r8.ah = 1;
     4094        break;
     4095      }
     4096
     4097      // Valid subfn; disable AUX input and IRQ12, assume no error
     4098      set_kbd_command_byte(0x65);
     4099      CLEAR_CF();
     4100      regs.u.r8.ah = 0;
     4101
    40914102      switch (regs.u.r8.al) {
    40924103        case 0: // Disable/Enable Mouse
    4093 BX_DEBUG_INT15("case 0:\n");
    4094           switch (regs.u.r8.bh) {
    4095             case 0: // Disable Mouse
    4096 BX_DEBUG_INT15("case 0: disable mouse\n");
    4097               inhibit_mouse_int_and_events(); // disable IRQ12 and packets
    4098               ret = send_to_mouse_ctrl(0xF5); // disable mouse command
    4099               if (ret == 0) {
    4100                 ret = get_mouse_data(&mouse_data1);
    4101                 if ( (ret == 0) || (mouse_data1 == 0xFA) ) {
    4102                   CLEAR_CF();
    4103                   regs.u.r8.ah = 0;
    4104                   return;
    4105                   }
    4106                 }
    4107 
    4108               // error
    4109               SET_CF();
    4110               regs.u.r8.ah = ret;
    4111               return;
     4104BX_DEBUG_INT15("case 0: ");
     4105          if (regs.u.r8.bh > 1) {
     4106            BX_DEBUG_INT15("INT 15h C2 AL=0, BH=%02x\n", (unsigned) regs.u.r8.bh);
     4107            // invalid subfunction
     4108            SET_CF();
     4109            regs.u.r8.ah = 1;
     4110            break;
     4111          }
     4112          mouse_flags_2 = read_byte(ebda_seg, 0x0027);
     4113          if ( (mouse_flags_2 & 0x80) == 0 ) {
     4114            BX_DEBUG_INT15("INT 15h C2 Enable/Disable Mouse, no far call handler\n");
     4115            SET_CF();
     4116            regs.u.r8.ah = 5; // no far call installed
     4117            break;
     4118            }
     4119          if (regs.u.r8.bh == 0) {
     4120BX_DEBUG_INT15("Disable Mouse\n");
     4121            mouse_cmd = 0xF5;   // disable mouse command
     4122          } else {
     4123BX_DEBUG_INT15("Enable Mouse\n");
     4124            mouse_cmd = 0xF4;   // enable mouse command
     4125          }
     4126
     4127          ret = send_to_mouse_ctrl(mouse_cmd);  // disable mouse command
     4128          if (ret == 0) {
     4129            ret = get_mouse_data(&mouse_data1);
     4130            if ( (ret == 0) || (mouse_data1 == 0xFA) ) {
     4131              // success
    41124132              break;
    4113 
    4114             case 1: // Enable Mouse
    4115 BX_DEBUG_INT15("case 1: enable mouse\n");
    4116               mouse_flags_2 = read_byte(ebda_seg, 0x0027);
    4117               if ( (mouse_flags_2 & 0x80) == 0 ) {
    4118                 BX_DEBUG_INT15("INT 15h C2 Enable Mouse, no far call handler\n");
    4119                 SET_CF();  // error
    4120                 regs.u.r8.ah = 5; // no far call installed
    4121                 return;
    4122                 }
    4123               inhibit_mouse_int_and_events(); // disable IRQ12 and packets
    4124               ret = send_to_mouse_ctrl(0xF4); // enable mouse command
    4125               if (ret == 0) {
    4126                 ret = get_mouse_data(&mouse_data1);
    4127                 if ( (ret == 0) && (mouse_data1 == 0xFA) ) {
    4128                   enable_mouse_int_and_events(); // turn IRQ12 and packet generation on
    4129                   CLEAR_CF();
    4130                   regs.u.r8.ah = 0;
    4131                   return;
    4132                   }
    4133                 }
    4134               SET_CF();
    4135               regs.u.r8.ah = ret;
    4136               return;
    4137 
    4138             default: // invalid subfunction
    4139               BX_DEBUG_INT15("INT 15h C2 AL=0, BH=%02x\n", (unsigned) regs.u.r8.bh);
    4140               SET_CF();  // error
    4141               regs.u.r8.ah = 1; // invalid subfunction
    4142               return;
     4133              }
    41434134            }
     4135
     4136          // interface error
     4137          SET_CF();
     4138          regs.u.r8.ah = 3;
    41444139          break;
    41454140
     4141        case 5: // Initialize Mouse
     4142          // Valid package sizes are 1 to 8
     4143          if ( (regs.u.r8.bh < 1) || (regs.u.r8.bh > 8) ) {
     4144            SET_CF();
     4145            regs.u.r8.ah = 2; // invalid input
     4146            break;
     4147          }
     4148          mouse_flags_2 = read_byte(ebda_seg, 0x0027);
     4149          mouse_flags_2 = (mouse_flags_2 & 0xf8) | (regs.u.r8.bh - 1);
     4150          write_byte(ebda_seg, 0x0027, mouse_flags_2);
     4151          // fall through!
     4152
    41464153        case 1: // Reset Mouse
    4147         case 5: // Initialize Mouse
    41484154BX_DEBUG_INT15("case 1 or 5:\n");
    4149           if (regs.u.r8.al == 5) {
    4150             if (regs.u.r8.bh != 3) {
    4151               SET_CF();
    4152               regs.u.r8.ah = 0x02; // invalid input
    4153               return;
    4154             }
    4155 #ifndef VBOX
    4156             mouse_flags_2 = read_byte(ebda_seg, 0x0027);
    4157             mouse_flags_2 = (mouse_flags_2 & 0x00) | regs.u.r8.bh;
    4158             mouse_flags_1 = 0x00;
    4159             write_byte(ebda_seg, 0x0026, mouse_flags_1);
    4160             write_byte(ebda_seg, 0x0027, mouse_flags_2);
    4161 #endif /* !VBOX */
    4162           }
    4163 
    4164           inhibit_mouse_int_and_events(); // disable IRQ12 and packets
    4165 #ifdef VBOX
    4166           /* Moved here to eliminate the race with the IRQ12 handler
    4167            * concurrently accessing the EBDA values. It also makes no
    4168            * sense to reset the mouse and leave the mouse flags as is. */
    4169           mouse_flags_2 = read_byte(ebda_seg, 0x0027);
    4170           if (regs.u.r8.al == 5)
    4171             mouse_flags_2 = (mouse_flags_2 & 0x00) | regs.u.r8.bh;
    4172           mouse_flags_1 = 0x00;
     4155          // clear current package byte index
     4156          mouse_flags_1 = read_byte(ebda_seg, 0x0026);
     4157          mouse_flags_1 = mouse_flags_1 & 0xf8;
    41734158          write_byte(ebda_seg, 0x0026, mouse_flags_1);
    4174           write_byte(ebda_seg, 0x0027, mouse_flags_2);
    4175 #endif /* VBOX */
    41764159          ret = send_to_mouse_ctrl(0xFF); // reset mouse command
    41774160          if (ret == 0) {
     
    41804163            if (mouse_data3 == 0xfe) {
    41814164              SET_CF();
    4182               return;
     4165              regs.u.r8.ah = 4; // resend
     4166              break;
    41834167            }
    41844168            if (mouse_data3 != 0xfa)
     
    41894173                ret = get_mouse_data(&mouse_data2);
    41904174                if ( ret == 0 ) {
    4191                   // turn IRQ12 and packet generation on
    4192                   enable_mouse_int_and_events();
    4193                   CLEAR_CF();
    4194                   regs.u.r8.ah = 0;
     4175                  // success
    41954176                  regs.u.r8.bl = mouse_data1;
    41964177                  regs.u.r8.bh = mouse_data2;
    4197                   return;
     4178                  break;
    41984179                  }
    41994180                }
     
    42014182            }
    42024183
    4203           // error
     4184          // interface error
    42044185          SET_CF();
    4205           regs.u.r8.ah = ret;
    4206           return;
     4186          regs.u.r8.ah = 3;
     4187          break;
    42074188
    42084189        case 2: // Set Sample Rate
     
    42184199            default: mouse_data1 = 0;
    42194200          }
    4220 #ifdef VBOX
    4221           comm_byte = inhibit_mouse_int_and_events(); // disable IRQ12 and packets
    4222 #endif /* VBOX */
    42234201          if (mouse_data1 > 0) {
    42244202            ret = send_to_mouse_ctrl(0xF3); // set sample rate command
     
    42274205              ret = send_to_mouse_ctrl(mouse_data1);
    42284206              ret = get_mouse_data(&mouse_data2);
    4229               CLEAR_CF();
    4230               regs.u.r8.ah = 0;
     4207              // success
    42314208            } else {
    4232               // error
     4209              // interface error
    42334210              SET_CF();
    4234               regs.u.r8.ah = UNSUPPORTED_FUNCTION;
     4211              regs.u.r8.ah = 3;
    42354212            }
    42364213          } else {
    4237             // error
     4214            // invalid input
    42384215            SET_CF();
    4239             regs.u.r8.ah = UNSUPPORTED_FUNCTION;
     4216            regs.u.r8.ah = 2;
    42404217          }
    4241 #ifdef VBOX
    4242           set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable
    4243 #endif /* VBOX */
    42444218          break;
    42454219
     
    42514225          //      2 = 100 dpi, 4 counts per millimeter
    42524226          //      3 = 200 dpi, 8 counts per millimeter
    4253 #ifdef VBOX
    4254           comm_byte = inhibit_mouse_int_and_events(); // disable IRQ12 and packets
    42554227          if (regs.u.r8.bh < 4) {
    42564228            ret = send_to_mouse_ctrl(0xE8); // set resolution command
     
    42634235              if (mouse_data1 != 0xfa)
    42644236                BX_PANIC("Mouse status returned %02x (should be ack)\n", (unsigned)mouse_data1);
    4265               CLEAR_CF();
    4266               regs.u.r8.ah = 0;
     4237              // success
    42674238            } else {
    4268               // error
     4239              // interface error
    42694240              SET_CF();
    4270               regs.u.r8.ah = UNSUPPORTED_FUNCTION;
     4241              regs.u.r8.ah = 3;
    42714242            }
    42724243          } else {
    4273             // error
     4244            // invalid input
    42744245            SET_CF();
    4275             regs.u.r8.ah = UNSUPPORTED_FUNCTION;
     4246            regs.u.r8.ah = 2;
    42764247          }
    4277           set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable
    4278 #else
    4279           CLEAR_CF();
    4280           regs.u.r8.ah = 0;
    4281 #endif /* VBOX */
    42824248          break;
    42834249
    42844250        case 4: // Get Device ID
    42854251BX_DEBUG_INT15("case 4:\n");
    4286 #ifdef VBOX
    4287           comm_byte = inhibit_mouse_int_and_events(); // disable IRQ12 and packets
    4288 #else /* !VBOX */
    4289           inhibit_mouse_int_and_events(); // disable IRQ12 and packets
    4290 #endif /* !VBOX */
    42914252          ret = send_to_mouse_ctrl(0xF2); // get mouse ID command
    42924253          if (ret == 0) {
    42934254            ret = get_mouse_data(&mouse_data1);
    42944255            ret = get_mouse_data(&mouse_data2);
    4295             CLEAR_CF();
    4296             regs.u.r8.ah = 0;
    42974256            regs.u.r8.bh = mouse_data2;
     4257            // success
    42984258          } else {
    4299             // error
     4259            // interface error
    43004260            SET_CF();
    4301             regs.u.r8.ah = UNSUPPORTED_FUNCTION;
     4261            regs.u.r8.ah = 3;
    43024262          }
    4303 #ifdef VBOX
    4304           set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable
    4305 #endif /* VBOX */
    43064263          break;
    43074264
     
    43104267          switch (regs.u.r8.bh) {
    43114268            case 0: // Return Status
    4312               comm_byte = inhibit_mouse_int_and_events(); // disable IRQ12 and packets
    43134269              ret = send_to_mouse_ctrl(0xE9); // get mouse info command
    43144270              if (ret == 0) {
     
    43234279                      ret = get_mouse_data(&mouse_data3);
    43244280                      if ( ret == 0 ) {
    4325                         CLEAR_CF();
    4326                         regs.u.r8.ah = 0;
    43274281                        regs.u.r8.bl = mouse_data1;
    43284282                        regs.u.r8.cl = mouse_data2;
    43294283                        regs.u.r8.dl = mouse_data3;
    4330                         set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable
    4331                         return;
     4284                        // success
     4285                        break;
    43324286                        }
    43334287                      }
     
    43364290                }
    43374291
    4338               // error
     4292              // interface error
    43394293              SET_CF();
    4340               regs.u.r8.ah = ret;
    4341               set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable
    4342               return;
     4294              regs.u.r8.ah = 3;
     4295              break;
    43434296
    43444297            case 1: // Set Scaling Factor to 1:1
    43454298            case 2: // Set Scaling Factor to 2:1
    4346               comm_byte = inhibit_mouse_int_and_events(); // disable IRQ12 and packets
    43474299              if (regs.u.r8.bh == 1) {
    43484300                ret = send_to_mouse_ctrl(0xE6);
     
    43544306                ret = (mouse_data1 != 0xFA);
    43554307              }
    4356               if (ret == 0) {
    4357                 CLEAR_CF();
    4358                 regs.u.r8.ah = 0;
    4359               } else {
    4360                 // error
     4308              if (ret != 0) {
     4309                // interface error
    43614310                SET_CF();
    4362                 regs.u.r8.ah = UNSUPPORTED_FUNCTION;
     4311                regs.u.r8.ah = 3;
    43634312              }
    4364               set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable
    43654313              break;
    43664314
    43674315            default:
    43684316              BX_PANIC("INT 15h C2 AL=6, BH=%02x\n", (unsigned) regs.u.r8.bh);
     4317              // invalid subfunction
     4318              SET_CF();
     4319              regs.u.r8.ah = 1;
    43694320            }
    43704321          break;
     
    43814332            if ( (mouse_flags_2 & 0x80) != 0 ) {
    43824333              mouse_flags_2 &= ~0x80;
    4383               inhibit_mouse_int_and_events(); // disable IRQ12 and packets
    43844334              }
    43854335            }
     
    43894339            }
    43904340          write_byte(ebda_seg, 0x0027, mouse_flags_2);
    4391           CLEAR_CF();
    4392           regs.u.r8.ah = 0;
    43934341          break;
    43944342
    43954343        default:
    4396 BX_DEBUG_INT15("case default:\n");
    4397           regs.u.r8.ah = 1; // invalid function
     4344          BX_PANIC("INT 15h C2 default case entered\n");
     4345          // invalid subfunction
    43984346          SET_CF();
     4347          regs.u.r8.ah = 1;
    43994348        }
     4349BX_DEBUG_INT15("returning cf = %u, ah = %02x\n", (unsigned)GET_CF(), (unsigned)regs.u.r8.ah);
     4350      // Re-enable AUX input and IRQ12
     4351      set_kbd_command_byte(0x47);
    44004352      break;
    44014353
     
    48354787
    48364788  Bit8u
    4837 inhibit_mouse_int_and_events()
    4838 {
    4839   Bit8u command_byte, prev_command_byte;
    4840 
    4841   // Turn off IRQ generation and aux data line
    4842   if ( inb(0x64) & 0x02 )
    4843     BX_PANIC(panic_msg_keyb_buffer_full,"inhibmouse");
    4844   outb(0x64, 0x20); // get command byte
    4845   while ( (inb(0x64) & 0x01) != 0x01 );
    4846   prev_command_byte = inb(0x60);
    4847   command_byte = prev_command_byte;
    4848   //while ( (inb(0x64) & 0x02) );
    4849   if ( inb(0x64) & 0x02 )
    4850     BX_PANIC(panic_msg_keyb_buffer_full,"inhibmouse");
    4851   command_byte &= 0xfd; // turn off IRQ 12 generation
    4852   command_byte |= 0x20; // disable mouse serial clock line
    4853   outb(0x64, 0x60); // write command byte
    4854   outb(0x60, command_byte);
    4855   return(prev_command_byte);
    4856 }
    4857 
    4858   void
    4859 enable_mouse_int_and_events()
    4860 {
    4861   Bit8u command_byte;
    4862 
    4863   // Turn on IRQ generation and aux data line
    4864   if ( inb(0x64) & 0x02 )
    4865     BX_PANIC(panic_msg_keyb_buffer_full,"enabmouse");
    4866   outb(0x64, 0x20); // get command byte
    4867   while ( (inb(0x64) & 0x01) != 0x01 );
    4868   command_byte = inb(0x60);
    4869   //while ( (inb(0x64) & 0x02) );
    4870   if ( inb(0x64) & 0x02 )
    4871     BX_PANIC(panic_msg_keyb_buffer_full,"enabmouse");
    4872   command_byte |= 0x02; // turn on IRQ 12 generation
    4873   command_byte &= 0xdf; // enable mouse serial clock line
    4874   outb(0x64, 0x60); // write command byte
    4875   outb(0x60, command_byte);
    4876 }
    4877 
    4878   Bit8u
    48794789send_to_mouse_ctrl(sendbyte)
    48804790  Bit8u sendbyte;
     
    49144824  if ( inb(0x64) & 0x02 )
    49154825    BX_PANIC(panic_msg_keyb_buffer_full,"setkbdcomm");
    4916   outb(0x64, 0xD4);
    49174826
    49184827  outb(0x64, 0x60); // write command byte
     
    51665075  write_byte(ebda_seg, 0x28 + index, in_byte);
    51675076
    5168   if ( (index+1) >= package_count ) {
     5077  if ( index >= package_count ) {
    51695078BX_DEBUG_INT74("int74_function: make_farcall=1\n");
    51705079    status = read_byte(ebda_seg, 0x0028 + 0);
  • trunk/src/VBox/Devices/Storage/fdc.c

    r1855 r2557  
    147147} fdisk_flags_t;
    148148
     149#ifdef VBOX
     150typedef enum fdrive_drate_t {
     151    FDRIVE_RATE_500K  = 0x00, /* 500 Kbps               */
     152    FDRIVE_RATE_300K  = 0x01, /* 300 Kbps               */
     153    FDRIVE_RATE_250K  = 0x02, /* 250 Kbps               */
     154    FDRIVE_RATE_1M    = 0x03  /* 1 Mbps                 */
     155} fdrive_drate_t;
     156#endif
     157
    149158typedef struct fdrive_t {
    150159#ifndef VBOX
     
    172181    /** The Diskette present/missing flag. */
    173182    bool                            fMediaPresent;
     183    /** Data rate required by media. */
     184    fdrive_drate_t                  media_rate;
    174185#endif
    175186    /* Drive status */
     
    274285    fdrive_type_t drive;
    275286    fdisk_type_t  disk;
     287    fdrive_drate_t rate;
    276288    uint8_t last_sect;
    277289    uint8_t max_track;
     
    283295    /* First entry is default format */
    284296    /* 1.44 MB 3"1/2 floppy disks */
    285     { FDRIVE_DRV_144, FDRIVE_DISK_144, 18, 80, 1, "1.44 MB 3\"1/2", },
    286     { FDRIVE_DRV_144, FDRIVE_DISK_144, 20, 80, 1,  "1.6 MB 3\"1/2", },
    287     { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 80, 1, "1.68 MB 3\"1/2", },
    288     { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 82, 1, "1.72 MB 3\"1/2", },
    289     { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 83, 1, "1.74 MB 3\"1/2", },
    290     { FDRIVE_DRV_144, FDRIVE_DISK_144, 22, 80, 1, "1.76 MB 3\"1/2", },
    291     { FDRIVE_DRV_144, FDRIVE_DISK_144, 23, 80, 1, "1.84 MB 3\"1/2", },
    292     { FDRIVE_DRV_144, FDRIVE_DISK_144, 24, 80, 1, "1.92 MB 3\"1/2", },
     297    { FDRIVE_DRV_144, FDRIVE_DISK_144, FDRIVE_RATE_500K, 18, 80, 1, "1.44 MB 3\"1/2", },
     298    { FDRIVE_DRV_144, FDRIVE_DISK_144, FDRIVE_RATE_500K, 20, 80, 1,  "1.6 MB 3\"1/2", },
     299    { FDRIVE_DRV_144, FDRIVE_DISK_144, FDRIVE_RATE_500K, 21, 80, 1, "1.68 MB 3\"1/2", },
     300    { FDRIVE_DRV_144, FDRIVE_DISK_144, FDRIVE_RATE_500K, 21, 82, 1, "1.72 MB 3\"1/2", },
     301    { FDRIVE_DRV_144, FDRIVE_DISK_144, FDRIVE_RATE_500K, 21, 83, 1, "1.74 MB 3\"1/2", },
     302    { FDRIVE_DRV_144, FDRIVE_DISK_144, FDRIVE_RATE_500K, 22, 80, 1, "1.76 MB 3\"1/2", },
     303    { FDRIVE_DRV_144, FDRIVE_DISK_144, FDRIVE_RATE_500K, 23, 80, 1, "1.84 MB 3\"1/2", },
     304    { FDRIVE_DRV_144, FDRIVE_DISK_144, FDRIVE_RATE_500K, 24, 80, 1, "1.92 MB 3\"1/2", },
    293305    /* 2.88 MB 3"1/2 floppy disks */
    294     { FDRIVE_DRV_288, FDRIVE_DISK_288, 36, 80, 1, "2.88 MB 3\"1/2", },
    295     { FDRIVE_DRV_288, FDRIVE_DISK_288, 39, 80, 1, "3.12 MB 3\"1/2", },
    296     { FDRIVE_DRV_288, FDRIVE_DISK_288, 40, 80, 1,  "3.2 MB 3\"1/2", },
    297     { FDRIVE_DRV_288, FDRIVE_DISK_288, 44, 80, 1, "3.52 MB 3\"1/2", },
    298     { FDRIVE_DRV_288, FDRIVE_DISK_288, 48, 80, 1, "3.84 MB 3\"1/2", },
     306    { FDRIVE_DRV_288, FDRIVE_DISK_288, FDRIVE_RATE_500K, 36, 80, 1, "2.88 MB 3\"1/2", },
     307    { FDRIVE_DRV_288, FDRIVE_DISK_288, FDRIVE_RATE_500K, 39, 80, 1, "3.12 MB 3\"1/2", },
     308    { FDRIVE_DRV_288, FDRIVE_DISK_288, FDRIVE_RATE_500K, 40, 80, 1,  "3.2 MB 3\"1/2", },
     309    { FDRIVE_DRV_288, FDRIVE_DISK_288, FDRIVE_RATE_500K, 44, 80, 1, "3.52 MB 3\"1/2", },
     310    { FDRIVE_DRV_288, FDRIVE_DISK_288, FDRIVE_RATE_500K, 48, 80, 1, "3.84 MB 3\"1/2", },
    299311    /* 720 kB 3"1/2 floppy disks */
    300     { FDRIVE_DRV_144, FDRIVE_DISK_720, 9, 80, 1,  "720 kB 3\"1/2", },
    301     { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 80, 1,  "800 kB 3\"1/2", },
    302     { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 82, 1,  "820 kB 3\"1/2", },
    303     { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 83, 1,  "830 kB 3\"1/2", },
    304     { FDRIVE_DRV_144, FDRIVE_DISK_720, 13, 80, 1, "1.04 MB 3\"1/2", },
    305     { FDRIVE_DRV_144, FDRIVE_DISK_720, 14, 80, 1, "1.12 MB 3\"1/2", },
     312    { FDRIVE_DRV_144, FDRIVE_DISK_720, FDRIVE_RATE_250K, 9, 80, 1,  "720 kB 3\"1/2", },
     313    { FDRIVE_DRV_144, FDRIVE_DISK_720, FDRIVE_RATE_250K, 10, 80, 1,  "800 kB 3\"1/2", },
     314    { FDRIVE_DRV_144, FDRIVE_DISK_720, FDRIVE_RATE_250K, 10, 82, 1,  "820 kB 3\"1/2", },
     315    { FDRIVE_DRV_144, FDRIVE_DISK_720, FDRIVE_RATE_250K, 10, 83, 1,  "830 kB 3\"1/2", },
     316    { FDRIVE_DRV_144, FDRIVE_DISK_720, FDRIVE_RATE_250K, 13, 80, 1, "1.04 MB 3\"1/2", },
     317    { FDRIVE_DRV_144, FDRIVE_DISK_720, FDRIVE_RATE_250K, 14, 80, 1, "1.12 MB 3\"1/2", },
    306318    /* 1.2 MB 5"1/4 floppy disks */
    307     { FDRIVE_DRV_120, FDRIVE_DISK_288, 15, 80, 1,  "1.2 kB 5\"1/4", },
    308     { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 80, 1, "1.44 MB 5\"1/4", },
    309     { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 82, 1, "1.48 MB 5\"1/4", },
    310     { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 83, 1, "1.49 MB 5\"1/4", },
    311     { FDRIVE_DRV_120, FDRIVE_DISK_288, 20, 80, 1,  "1.6 MB 5\"1/4", },
     319    { FDRIVE_DRV_120, FDRIVE_DISK_288, FDRIVE_RATE_500K, 15, 80, 1,  "1.2 kB 5\"1/4", },
     320    { FDRIVE_DRV_120, FDRIVE_DISK_288, FDRIVE_RATE_500K, 18, 80, 1, "1.44 MB 5\"1/4", },
     321    { FDRIVE_DRV_120, FDRIVE_DISK_288, FDRIVE_RATE_500K, 18, 82, 1, "1.48 MB 5\"1/4", },
     322    { FDRIVE_DRV_120, FDRIVE_DISK_288, FDRIVE_RATE_500K, 18, 83, 1, "1.49 MB 5\"1/4", },
     323    { FDRIVE_DRV_120, FDRIVE_DISK_288, FDRIVE_RATE_500K, 20, 80, 1,  "1.6 MB 5\"1/4", },
    312324    /* 720 kB 5"1/4 floppy disks */
    313     { FDRIVE_DRV_120, FDRIVE_DISK_288, 9, 80, 1,  "720 kB 5\"1/4", },
    314     { FDRIVE_DRV_120, FDRIVE_DISK_288, 11, 80, 1,  "880 kB 5\"1/4", },
     325    { FDRIVE_DRV_120, FDRIVE_DISK_288, FDRIVE_RATE_250K, 9, 80, 1,  "720 kB 5\"1/4", },
     326    { FDRIVE_DRV_120, FDRIVE_DISK_288, FDRIVE_RATE_250K, 11, 80, 1,  "880 kB 5\"1/4", },
    315327    /* 360 kB 5"1/4 floppy disks */
    316     { FDRIVE_DRV_120, FDRIVE_DISK_288, 9, 40, 1,  "360 kB 5\"1/4", },
    317     { FDRIVE_DRV_120, FDRIVE_DISK_288, 9, 40, 0,  "180 kB 5\"1/4", },
    318     { FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 41, 1,  "410 kB 5\"1/4", },
    319     { FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 42, 1,  "420 kB 5\"1/4", },
     328    { FDRIVE_DRV_120, FDRIVE_DISK_288, FDRIVE_RATE_300K, 9, 40, 1,  "360 kB 5\"1/4", },
     329    { FDRIVE_DRV_120, FDRIVE_DISK_288, FDRIVE_RATE_300K, 9, 40, 0,  "180 kB 5\"1/4", },
     330    { FDRIVE_DRV_120, FDRIVE_DISK_288, FDRIVE_RATE_300K, 10, 41, 1,  "410 kB 5\"1/4", },
     331    { FDRIVE_DRV_120, FDRIVE_DISK_288, FDRIVE_RATE_300K, 10, 42, 1,  "420 kB 5\"1/4", },
    320332    /* 320 kB 5"1/4 floppy disks */
    321     { FDRIVE_DRV_120, FDRIVE_DISK_288, 8, 40, 1,  "320 kB 5\"1/4", },
    322     { FDRIVE_DRV_120, FDRIVE_DISK_288, 8, 40, 0,  "160 kB 5\"1/4", },
     333    { FDRIVE_DRV_120, FDRIVE_DISK_288, FDRIVE_RATE_250K, 8, 40, 1,  "320 kB 5\"1/4", },
     334    { FDRIVE_DRV_120, FDRIVE_DISK_288, FDRIVE_RATE_250K, 8, 40, 0,  "160 kB 5\"1/4", },
    323335    /* 360 kB must match 5"1/4 better than 3"1/2... */
    324     { FDRIVE_DRV_144, FDRIVE_DISK_720, 9, 80, 0,  "360 kB 3\"1/2", },
     336    { FDRIVE_DRV_144, FDRIVE_DISK_720, FDRIVE_RATE_250K, 9, 80, 0,  "360 kB 3\"1/2", },
    325337    /* end */
    326     { FDRIVE_DRV_NONE, FDRIVE_DISK_NONE, -1, -1, 0, NULL, },
     338    { FDRIVE_DRV_NONE, FDRIVE_DISK_NONE, FDRIVE_RATE_1M, -1, -1, 0, NULL, },
    327339};
    328340
     
    405417        drv->ro = ro;
    406418#ifdef VBOX
     419        drv->media_rate = parse->rate;
    407420        drv->fMediaPresent = true;
    408421#endif
     
    465478static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value);
    466479static uint32_t fdctrl_read_dir (fdctrl_t *fdctrl);
     480#ifdef VBOX
     481static void fdctrl_write_ccr (fdctrl_t *fdctrl, uint32_t value);
     482#endif
    467483
    468484enum {
     
    534550    /* precompensation */
    535551    uint8_t precomp_trk;
     552#ifdef VBOX
     553    /* data rate */
     554    uint8_t drate;
     555#endif
    536556    uint8_t config;
    537557    uint8_t lock;
     
    605625        fdctrl_write_data(fdctrl, value);
    606626        break;
     627#ifdef VBOX
     628    case 0x07:
     629        fdctrl_write_ccr(fdctrl, value);
     630        break;
     631#endif
    607632    default:
    608633        break;
     
    749774    /* Initialise controller */
    750775    fdctrl->cur_drv = 0;
     776#ifdef VBOX
     777    fdctrl->drate = 2;  /* Default to 250 Kbps*/
     778#endif
    751779    /* FIFO state */
    752780    fdctrl->data_pos = 0;
     
    923951    }
    924952/* //        fdctrl.precomp = (value >> 2) & 0x07; */
     953#ifdef VBOX
     954    fdctrl->drate = value & 0x03;
     955#endif
    925956}
    926957
     
    947978    return retval;
    948979}
     980
     981#ifdef VBOX
     982/* Configuration control register : 0x07 (write) */
     983static void fdctrl_write_ccr (fdctrl_t *fdctrl, uint32_t value)
     984{
     985    FLOPPY_DPRINTF("configuration control register set to 0x%02x\n", value);
     986    fdctrl->drate = value & 0x03;
     987}
     988#endif
    949989
    950990/* FIFO state control */
     
    10601100        break;
    10611101    }
     1102#ifdef VBOX
     1103    /* Check that selected data rate is correct.
     1104     * NB: Software may deduce media type from selected data rate, eg. 250Kbps
     1105     * in a 3.5" drive implies 720KB media, while 500Kbps implies 1.44MB.
     1106     */
     1107    if (fdctrl->drate != cur_drv->media_rate) {
     1108        FLOPPY_DPRINTF("Data rate mismatch (controller 0x%02x, media 0x%02x)\n", fdctrl->drate, cur_drv->media_rate);
     1109        fdctrl_stop_transfer(fdctrl, 0x40, 0x04, 0x00);
     1110        fdctrl->fifo[3] = kt;
     1111        fdctrl->fifo[4] = kh;
     1112        fdctrl->fifo[5] = ks;
     1113        return;
     1114    }
     1115#endif
    10621116    /* Set the FIFO state */
    10631117    fdctrl->data_dir = direction;
     
    24392493    qemu_put_8s (f, &s->timer1);
    24402494    qemu_put_8s (f, &s->precomp_trk);
     2495    qemu_put_8s (f, &s->drate);
    24412496    qemu_put_8s (f, &s->config);
    24422497    qemu_put_8s (f, &s->lock);
     
    24952550    qemu_get_8s (f, &s->timer1);
    24962551    qemu_get_8s (f, &s->precomp_trk);
     2552    qemu_get_8s (f, &s->drate);
    24972553    qemu_get_8s (f, &s->config);
    24982554    qemu_get_8s (f, &s->lock);
Note: See TracChangeset for help on using the changeset viewer.

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