Changeset 2557 in vbox for trunk/src/VBox/Devices/PC/BIOS
- Timestamp:
- May 9, 2007 1:03:02 PM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 21015
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/BIOS/rombios.c
r2535 r2557 890 890 static void bios_printf(); 891 891 892 static Bit8u inhibit_mouse_int_and_events();893 static void enable_mouse_int_and_events();894 892 static Bit8u send_to_mouse_ctrl(); 895 893 static Bit8u get_mouse_data(); … … 1823 1821 1824 1822 /* send cmd: scan code convert, disable mouse, enable IRQ 1 */ 1825 outb(0x60, 0x6 1);1823 outb(0x60, 0x65); 1826 1824 1827 1825 /* Wait until buffer is empty */ … … 4071 4069 Bit16u mouse_driver_seg; 4072 4070 Bit16u mouse_driver_offset; 4073 Bit8u comm_byte, prev_command_byte;4071 Bit8u mouse_cmd; 4074 4072 Bit8u ret, mouse_data1, mouse_data2, mouse_data3; 4075 4073 … … 4089 4087 // 80/86: mouse service not implemented 4090 4088 4089 if (regs.u.r8.al > 7) { 4090 BX_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 4091 4102 switch (regs.u.r8.al) { 4092 4103 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; 4104 BX_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) { 4120 BX_DEBUG_INT15("Disable Mouse\n"); 4121 mouse_cmd = 0xF5; // disable mouse command 4122 } else { 4123 BX_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 4112 4132 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 } 4143 4134 } 4135 4136 // interface error 4137 SET_CF(); 4138 regs.u.r8.ah = 3; 4144 4139 break; 4145 4140 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 4146 4153 case 1: // Reset Mouse 4147 case 5: // Initialize Mouse4148 4154 BX_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; 4173 4158 write_byte(ebda_seg, 0x0026, mouse_flags_1); 4174 write_byte(ebda_seg, 0x0027, mouse_flags_2);4175 #endif /* VBOX */4176 4159 ret = send_to_mouse_ctrl(0xFF); // reset mouse command 4177 4160 if (ret == 0) { … … 4180 4163 if (mouse_data3 == 0xfe) { 4181 4164 SET_CF(); 4182 return; 4165 regs.u.r8.ah = 4; // resend 4166 break; 4183 4167 } 4184 4168 if (mouse_data3 != 0xfa) … … 4189 4173 ret = get_mouse_data(&mouse_data2); 4190 4174 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 4195 4176 regs.u.r8.bl = mouse_data1; 4196 4177 regs.u.r8.bh = mouse_data2; 4197 return;4178 break; 4198 4179 } 4199 4180 } … … 4201 4182 } 4202 4183 4203 // error4184 // interface error 4204 4185 SET_CF(); 4205 regs.u.r8.ah = ret;4206 return;4186 regs.u.r8.ah = 3; 4187 break; 4207 4188 4208 4189 case 2: // Set Sample Rate … … 4218 4199 default: mouse_data1 = 0; 4219 4200 } 4220 #ifdef VBOX4221 comm_byte = inhibit_mouse_int_and_events(); // disable IRQ12 and packets4222 #endif /* VBOX */4223 4201 if (mouse_data1 > 0) { 4224 4202 ret = send_to_mouse_ctrl(0xF3); // set sample rate command … … 4227 4205 ret = send_to_mouse_ctrl(mouse_data1); 4228 4206 ret = get_mouse_data(&mouse_data2); 4229 CLEAR_CF(); 4230 regs.u.r8.ah = 0; 4207 // success 4231 4208 } else { 4232 // error4209 // interface error 4233 4210 SET_CF(); 4234 regs.u.r8.ah = UNSUPPORTED_FUNCTION;4211 regs.u.r8.ah = 3; 4235 4212 } 4236 4213 } else { 4237 // error4214 // invalid input 4238 4215 SET_CF(); 4239 regs.u.r8.ah = UNSUPPORTED_FUNCTION;4216 regs.u.r8.ah = 2; 4240 4217 } 4241 #ifdef VBOX4242 set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable4243 #endif /* VBOX */4244 4218 break; 4245 4219 … … 4251 4225 // 2 = 100 dpi, 4 counts per millimeter 4252 4226 // 3 = 200 dpi, 8 counts per millimeter 4253 #ifdef VBOX4254 comm_byte = inhibit_mouse_int_and_events(); // disable IRQ12 and packets4255 4227 if (regs.u.r8.bh < 4) { 4256 4228 ret = send_to_mouse_ctrl(0xE8); // set resolution command … … 4263 4235 if (mouse_data1 != 0xfa) 4264 4236 BX_PANIC("Mouse status returned %02x (should be ack)\n", (unsigned)mouse_data1); 4265 CLEAR_CF(); 4266 regs.u.r8.ah = 0; 4237 // success 4267 4238 } else { 4268 // error4239 // interface error 4269 4240 SET_CF(); 4270 regs.u.r8.ah = UNSUPPORTED_FUNCTION;4241 regs.u.r8.ah = 3; 4271 4242 } 4272 4243 } else { 4273 // error4244 // invalid input 4274 4245 SET_CF(); 4275 regs.u.r8.ah = UNSUPPORTED_FUNCTION;4246 regs.u.r8.ah = 2; 4276 4247 } 4277 set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable4278 #else4279 CLEAR_CF();4280 regs.u.r8.ah = 0;4281 #endif /* VBOX */4282 4248 break; 4283 4249 4284 4250 case 4: // Get Device ID 4285 4251 BX_DEBUG_INT15("case 4:\n"); 4286 #ifdef VBOX4287 comm_byte = inhibit_mouse_int_and_events(); // disable IRQ12 and packets4288 #else /* !VBOX */4289 inhibit_mouse_int_and_events(); // disable IRQ12 and packets4290 #endif /* !VBOX */4291 4252 ret = send_to_mouse_ctrl(0xF2); // get mouse ID command 4292 4253 if (ret == 0) { 4293 4254 ret = get_mouse_data(&mouse_data1); 4294 4255 ret = get_mouse_data(&mouse_data2); 4295 CLEAR_CF();4296 regs.u.r8.ah = 0;4297 4256 regs.u.r8.bh = mouse_data2; 4257 // success 4298 4258 } else { 4299 // error4259 // interface error 4300 4260 SET_CF(); 4301 regs.u.r8.ah = UNSUPPORTED_FUNCTION;4261 regs.u.r8.ah = 3; 4302 4262 } 4303 #ifdef VBOX4304 set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable4305 #endif /* VBOX */4306 4263 break; 4307 4264 … … 4310 4267 switch (regs.u.r8.bh) { 4311 4268 case 0: // Return Status 4312 comm_byte = inhibit_mouse_int_and_events(); // disable IRQ12 and packets4313 4269 ret = send_to_mouse_ctrl(0xE9); // get mouse info command 4314 4270 if (ret == 0) { … … 4323 4279 ret = get_mouse_data(&mouse_data3); 4324 4280 if ( ret == 0 ) { 4325 CLEAR_CF();4326 regs.u.r8.ah = 0;4327 4281 regs.u.r8.bl = mouse_data1; 4328 4282 regs.u.r8.cl = mouse_data2; 4329 4283 regs.u.r8.dl = mouse_data3; 4330 set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable4331 return;4284 // success 4285 break; 4332 4286 } 4333 4287 } … … 4336 4290 } 4337 4291 4338 // error4292 // interface error 4339 4293 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; 4343 4296 4344 4297 case 1: // Set Scaling Factor to 1:1 4345 4298 case 2: // Set Scaling Factor to 2:1 4346 comm_byte = inhibit_mouse_int_and_events(); // disable IRQ12 and packets4347 4299 if (regs.u.r8.bh == 1) { 4348 4300 ret = send_to_mouse_ctrl(0xE6); … … 4354 4306 ret = (mouse_data1 != 0xFA); 4355 4307 } 4356 if (ret == 0) { 4357 CLEAR_CF(); 4358 regs.u.r8.ah = 0; 4359 } else { 4360 // error 4308 if (ret != 0) { 4309 // interface error 4361 4310 SET_CF(); 4362 regs.u.r8.ah = UNSUPPORTED_FUNCTION;4311 regs.u.r8.ah = 3; 4363 4312 } 4364 set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable4365 4313 break; 4366 4314 4367 4315 default: 4368 4316 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; 4369 4320 } 4370 4321 break; … … 4381 4332 if ( (mouse_flags_2 & 0x80) != 0 ) { 4382 4333 mouse_flags_2 &= ~0x80; 4383 inhibit_mouse_int_and_events(); // disable IRQ12 and packets4384 4334 } 4385 4335 } … … 4389 4339 } 4390 4340 write_byte(ebda_seg, 0x0027, mouse_flags_2); 4391 CLEAR_CF();4392 regs.u.r8.ah = 0;4393 4341 break; 4394 4342 4395 4343 default: 4396 BX_DEBUG_INT15("case default:\n");4397 regs.u.r8.ah = 1; // invalidfunction4344 BX_PANIC("INT 15h C2 default case entered\n"); 4345 // invalid subfunction 4398 4346 SET_CF(); 4347 regs.u.r8.ah = 1; 4399 4348 } 4349 BX_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); 4400 4352 break; 4401 4353 … … 4835 4787 4836 4788 Bit8u 4837 inhibit_mouse_int_and_events()4838 {4839 Bit8u command_byte, prev_command_byte;4840 4841 // Turn off IRQ generation and aux data line4842 if ( inb(0x64) & 0x02 )4843 BX_PANIC(panic_msg_keyb_buffer_full,"inhibmouse");4844 outb(0x64, 0x20); // get command byte4845 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 generation4852 command_byte |= 0x20; // disable mouse serial clock line4853 outb(0x64, 0x60); // write command byte4854 outb(0x60, command_byte);4855 return(prev_command_byte);4856 }4857 4858 void4859 enable_mouse_int_and_events()4860 {4861 Bit8u command_byte;4862 4863 // Turn on IRQ generation and aux data line4864 if ( inb(0x64) & 0x02 )4865 BX_PANIC(panic_msg_keyb_buffer_full,"enabmouse");4866 outb(0x64, 0x20); // get command byte4867 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 generation4873 command_byte &= 0xdf; // enable mouse serial clock line4874 outb(0x64, 0x60); // write command byte4875 outb(0x60, command_byte);4876 }4877 4878 Bit8u4879 4789 send_to_mouse_ctrl(sendbyte) 4880 4790 Bit8u sendbyte; … … 4914 4824 if ( inb(0x64) & 0x02 ) 4915 4825 BX_PANIC(panic_msg_keyb_buffer_full,"setkbdcomm"); 4916 outb(0x64, 0xD4);4917 4826 4918 4827 outb(0x64, 0x60); // write command byte … … 5166 5075 write_byte(ebda_seg, 0x28 + index, in_byte); 5167 5076 5168 if ( (index+1)>= package_count ) {5077 if ( index >= package_count ) { 5169 5078 BX_DEBUG_INT74("int74_function: make_farcall=1\n"); 5170 5079 status = read_byte(ebda_seg, 0x0028 + 0);
Note:
See TracChangeset
for help on using the changeset viewer.