VirtualBox

Changeset 87784 in vbox for trunk/src/VBox/Devices/PC


Ignore:
Timestamp:
Feb 17, 2021 5:12:35 PM (4 years ago)
Author:
vboxsync
Message:

BIOS: Reworked INT 15h/86h to use the RTC like INT 15h/83h already does.

Location:
trunk/src/VBox/Devices/PC/BIOS
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/BIOS/notes.txt

    r77117 r87784  
    4343- NetWare 6.x is the only known guest which uses the PCI BIOS service to read
    4444  the IRQ routing table.
     45
     46- NetWare 6.5 boot CD is a rare user of INT 15h/86h, asking for 1,000,000
     47  microsecond (1 second) delays. The initial NW 6.5 release boots to Caldera
     48  DOS and does not exhibit this behavior. NetWare 6.5 SP2 and later boots
     49  straight to NetWare and uses the 1-second sleep.
    4550
    4651- Any disk reads which use bus-master DMA (AHCI, IDE BM) must use VDS
  • trunk/src/VBox/Devices/PC/BIOS/system.c

    r82968 r87784  
    285285    parm [ax] modify nomemory aborts;
    286286
    287 /// @todo This method is silly. The RTC should be programmed to fire an interrupt
    288 // instead of hogging the CPU with inaccurate code.
    289 void timer_wait(uint32_t usec_wait)
    290 {
    291     uint32_t    cycles;
    292     uint8_t     old_val;
    293     uint8_t     cur_val;
    294 
    295     /* We wait in 15 usec increments. */
    296     cycles = usec_wait / 15;
    297 
    298     old_val = inp(0x61) & 0x10;
    299     while (cycles--) {
    300         /* Wait 15us. */
    301         do {
    302             cur_val = inp(0x61) & 0x10;
    303         } while (cur_val != old_val);
    304         old_val = cur_val;
    305     }
    306 }
    307 
    308287bx_bool set_enable_a20(bx_bool val)
    309288{
     
    427406                write_word( 0x40, 0x9E, CX ); // High word, delay.
    428407                CLEAR_CF( );
     408                // Unmask IRQ8 so INT70 will get through.
    429409                irqDisable = inb( 0xA1 );
    430410                outb( 0xA1, irqDisable & 0xFE );
    431                 bRegister = inb_cmos( 0xB );  // Unmask IRQ8 so INT70 will get through.
    432                 outb_cmos( 0xB, bRegister | 0x40 ); // Turn on the Periodic Interrupt timer
     411                bRegister = inb_cmos( 0xB );
     412                // Turn on the Periodic Interrupt timer
     413                outb_cmos( 0xB, bRegister | 0x40 );
    433414            } else {
    434415                // Interval already set.
    435416                BX_DEBUG_INT15("int15: Func 83h, failed, already waiting.\n" );
    436                 SET_CF();
    437                 SET_AH(UNSUPPORTED_FUNCTION);
     417                SET_CF();   // AH is left unmodified
    438418            }
    439419        } else if( GET_AL() == 1 ) {
     
    454434
    455435    case 0x86:
    456         // Wait for CX:DX microseconds. currently using the
    457         // refresh request port 0x61 bit4, toggling every 15usec
    458         int_enable();
    459         timer_wait(((uint32_t)CX << 16) | DX);
     436        // Set Interval requested.
     437        if( ( read_byte( 0x40, 0xA0 ) & 1 ) == 0 ) {
     438            // Interval not already set.
     439            write_byte( 0x40, 0xA0, 1 );    // Set status byte.
     440            write_word( 0x40, 0x98, 0x40 ); // Byte location, segment
     441            write_word( 0x40, 0x9A, 0xA0 ); // Byte location, offset
     442            write_word( 0x40, 0x9C, DX );   // Low word, delay
     443            write_word( 0x40, 0x9E, CX );   // High word, delay.
     444            // Unmask IRQ8 so INT70 will get through.
     445            irqDisable = inb( 0xA1 );
     446            outb( 0xA1, irqDisable & 0xFE );
     447            bRegister = inb_cmos( 0xB );
     448            // Turn on the Periodic Interrupt timer
     449            outb_cmos( 0xB, bRegister | 0x40 );
     450            // Now wait until timer interrupt says wait is done.
     451            int_enable();
     452            do {
     453                halt();
     454                bRegister = read_byte( 0x40, 0xA0 );
     455            }
     456            while( !(bRegister & 0x80) );
     457            write_byte( 0x40, 0xA0, 0 );    // Deactivate wait.
     458            CLEAR_CF( );
     459        } else {
     460            // Interval already set.
     461            BX_DEBUG_INT15("int15: Func 86h, failed, already waiting.\n" );
     462            SET_CF();   // AH is left unmodified
     463        }
    460464        break;
    461465
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