VirtualBox

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


Ignore:
Timestamp:
Jul 3, 2013 5:39:01 PM (12 years ago)
Author:
vboxsync
Message:

VBoxPcBios: Use HLT while waiting for floppy interrupts. Added comment on seemingly missing 00440h updating in the int08_handler.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/BIOS/floppy.c

    r44528 r46947  
    7272extern  int     diskette_param_table;   /* At a fixed location. */
    7373
     74#ifndef VBOX_WITH_FLOPPY_IRQ_POLLING
     75
     76/**
     77 * Wait for the 7th bit of 0040:003e to be set by int0e_handler.
     78 * @returns first 7 bits of byte 0040:003e, interrupts disabled.
     79 */
     80uint8_t floppy_wait_for_interrupt(void)
     81{
     82    int_disable();
     83    for (;;)
     84    {
     85        uint8_t val8 = read_byte(0x0040, 0x003e);
     86        if (val8 & 0x80)
     87            return val8 & ~0x7f;
     88        int_enable_hlt_disable();
     89    }
     90}
     91
     92/**
     93 * Wait for the 7th bit of 0040:003e to be set by int0e_handler or 0040:0040 to
     94 * be cleared by the timer, clearing the interrupt flag on success.
     95 *
     96 * @returns 0 on timeout with interrupts enabled.
     97 *          All 8 bits at 0040:003e on interrupt with interrupts disabled (i.e.
     98 *          non-zero), after first clearing the 7th bit at 0040:003e.
     99 */
     100uint8_t floppy_wait_for_interrupt_or_timeout(void)
     101{
     102    int_disable();
     103    for (;;)
     104    {
     105        uint8_t val8 = read_byte(0x0040, 0x0040);
     106        if (val8 == 0) {
     107            int_enable();
     108            return 0;
     109        }
     110
     111        val8 = read_byte(0x0040, 0x003e);
     112        if (val8 & 0x80) {
     113            write_byte(0x0040, 0x003e, val8 & 0x7f);
     114            return val8;
     115        }
     116        int_enable_hlt_disable();
     117    }
     118}
     119
     120#endif /* !VBOX_WITH_FLOPPY_IRQ_POLLING */
     121
    74122void floppy_reset_controller(void)
    75123{
     
    107155   
    108156    // reset the disk motor timeout value of INT 08
    109     write_byte(0x40,0x40, BX_FLOPPY_ON_CNT);
     157    write_byte(0x0040,0x0040, BX_FLOPPY_ON_CNT);
    110158   
    111159    // program data rate
     
    120168   
    121169    if (prev_reset == 0) {
     170#ifdef VBOX_WITH_FLOPPY_IRQ_POLLING
    122171        // turn on interrupts
    123172        int_enable();
     
    128177        val8 &= 0x7f;
    129178        int_disable();
     179#else
     180        val8 = floppy_wait_for_interrupt(); /* (7th bit cleared in ret val) */
     181#endif
    130182        write_byte(0x0040, 0x003e, val8);
    131183    }
     
    159211bx_bool floppy_read_id(uint16_t drive)
    160212{
     213#ifdef VBOX_WITH_FLOPPY_IRQ_POLLING
    161214    uint8_t     val8;
     215#endif
    162216    uint8_t     return_status[7];
    163217    int         i;
     
    169223    outb(0x03f5, drive); // 0=drive0, 1=drive1, head always 0
    170224   
     225#ifdef VBOX_WITH_FLOPPY_IRQ_POLLING
    171226    // turn on interrupts
    172227    int_enable();
     
    180235    // turn off interrupts
    181236    int_disable();
     237#else
     238    floppy_wait_for_interrupt();
     239#endif
    182240   
    183241    // read 7 return status bytes from controller
     
    203261    outb(0x03f5, drive); // 0=drive0, 1=drive1
    204262   
     263#ifdef VBOX_WITH_FLOPPY_IRQ_POLLING
    205264    // turn on interrupts
    206265    int_enable();
     
    214273    // turn off interrupts
    215274    int_disable();
    216    
     275
    217276    // set 40:3e bit 7 to 0, and calibrated bit
    218277    val8 = read_byte(0x0040, 0x003e);
    219278    val8 &= 0x7f;
     279#else
     280    val8 = floppy_wait_for_interrupt(); /* (7th bit cleared in ret val) */
     281
     282    // set 40:3e bit 7 to 0, and calibrated bit
     283#endif
    220284    if (drive) {
    221285        val8 |= 0x02; // Drive 1 calibrated
     
    563627            outb(0x03f5, 0xff); // Gap length
    564628           
     629#ifdef VBOX_WITH_FLOPPY_IRQ_POLLING
    565630            // turn on interrupts
    566631            int_enable();
    567632           
    568             // wait on 40:3e bit 7 to become 1
     633            // wait on 40:3e bit 7 to become 1 or timeout (latter isn't armed so it won't happen)
    569634            do {
    570                     val8 = read_byte(0x0040, 0x0040);
     635                val8 = read_byte(0x0040, 0x0040);
    571636                if (val8 == 0) {
    572637                    floppy_reset_controller();
     
    583648            // turn off interrupts
    584649            int_disable();
    585            
     650
    586651            // set 40:3e bit 7 to 0
    587652            val8 = read_byte(0x0040, 0x003e);
    588653            val8 &= 0x7f;
    589654            write_byte(0x0040, 0x003e, val8);
     655
     656#else
     657            val8 = floppy_wait_for_interrupt_or_timeout();
     658            if (val8 == 0) { /* Note! Interrupts enabled in this branch. */
     659                floppy_reset_controller();
     660                SET_AH(0x80); // drive not ready (timeout)
     661                set_diskette_ret_status(0x80);
     662                SET_AL(0); // no sectors read
     663                SET_CF(); // error occurred
     664                return;
     665            }
     666#endif
    590667           
    591668            // check port 3f4 for accessibility to status bytes
     
    686763            outb(0x03f5, 0xff); // Gap length
    687764           
     765#ifdef VBOX_WITH_FLOPPY_IRQ_POLLING
    688766            // turn on interrupts
    689767            int_enable();
     
    706784            // turn off interrupts
    707785            int_disable();
    708            
     786
    709787            // set 40:3e bit 7 to 0
    710788            val8 = read_byte(0x0040, 0x003e);
    711789            val8 &= 0x7f;
    712790            write_byte(0x0040, 0x003e, val8);
     791#else
     792            val8 = floppy_wait_for_interrupt_or_timeout();
     793            if (val8 == 0) { /* Note! Interrupts enabled in this branch. */
     794                floppy_reset_controller();
     795                SET_AH(0x80); // drive not ready (timeout)
     796                set_diskette_ret_status(0x80);
     797                SET_AL(0); // no sectors written
     798                SET_CF(); // error occurred
     799                return;
     800            }
     801#endif
    713802           
    714803            // check port 3f4 for accessibility to status bytes
     
    835924        outb(0x03f5, 0); // Gap length
    836925        outb(0x03f5, 0xf6); // Fill byte
     926
     927#ifdef VBOX_WITH_FLOPPY_IRQ_POLLING
    837928        // turn on interrupts
    838929        int_enable();
     
    854945        // turn off interrupts
    855946        int_disable();
     947
    856948        // set 40:3e bit 7 to 0
    857949        val8 = read_byte(0x0040, 0x003e);
    858950        val8 &= 0x7f;
    859951        write_byte(0x0040, 0x003e, val8);
     952#else
     953        val8 = floppy_wait_for_interrupt_or_timeout();
     954        if (val8 == 0) { /* Note! Interrupts enabled in this branch. */
     955            floppy_reset_controller();
     956            SET_AH(0x80); // drive not ready (timeout)
     957            set_diskette_ret_status(0x80);
     958            SET_CF(); // error occurred
     959            return;
     960        }
     961#endif
     962
    860963        // check port 3f4 for accessibility to status bytes
    861964        val8 = inb(0x3f4);
  • trunk/src/VBox/Devices/PC/BIOS/inlines.h

    r44528 r46947  
    3838void int_disable(void);
    3939#pragma aux int_disable = "cli" modify exact [] nomemory;
     40
     41void int_enable_hlt_disable(void);
     42#pragma aux int_enable_hlt_disable = \
     43    "sti" \
     44    "hlt" \
     45    "cli" \
     46    modify exact [] nomemory;
    4047
    4148uint16_t int_query(void);
  • trunk/src/VBox/Devices/PC/BIOS/orgs.asm

    r45669 r46947  
    17221722
    17231723                ;; time to turn off floppy driv motor(s)?
    1724                 mov     al, ds:[440h]
     1724                mov     al, ds:[440h]    ;; @todo Shouldn't this be decreased if > 0? How would we ever get to zero otherwise?
    17251725                or      al, al
    17261726                jz      int08_floppy_off
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