VirtualBox

Changeset 82133 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Nov 23, 2019 9:05:03 PM (5 years ago)
Author:
vboxsync
Message:

VGABIOS: Fixed CGA cursor emulation (new code is much more complex but also much more IBM compatible).

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Graphics/BIOS/vgabios.c

    r82113 r82133  
    173173    bda[BIOSMEM_CHAR_HEIGHT] = 16;
    174174    /* Clear the screen. */
    175     bda[BIOSMEM_VIDEO_CTL]   = 0x60;
     175    bda[BIOSMEM_VIDEO_CTL]   = 0x68;
    176176    /* Set the basic screen we have. */
    177177    bda[BIOSMEM_SWITCHES]    = 0xf9;
     
    510510// --------------------------------------------------------------------------------------------
    511511static void biosfn_set_cursor_shape(uint8_t CH, uint8_t CL)
    512 {uint16_t cheight,curs,crtc_addr;
    513  uint8_t modeset_ctl;
    514 
    515  CH&=0x3f;
    516  CL&=0x1f;
    517 
    518  curs=(CH<<8)+CL;
    519  write_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE,curs);
    520 
    521  modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL);
    522  cheight = read_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT);
    523  if((modeset_ctl&0x01) && (cheight>8) && (CL<8) && (CH<0x20))
    524   {
    525    if(CL!=(CH+1))
    526     {
    527      CH = ((CH+1) * cheight / 8) -1;
    528     }
    529    else
    530     {
    531      CH = ((CL+1) * cheight / 8) - 2;
    532     }
    533    CL = ((CL+1) * cheight / 8) - 1;
    534   }
    535 
    536  // CTRC regs 0x0a and 0x0b
    537  crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
    538  outb(crtc_addr,0x0a);
    539  outb(crtc_addr+1,CH);
    540  outb(crtc_addr,0x0b);
    541  outb(crtc_addr+1,CL);
     512{
     513  uint16_t cheight, curs, crtc_addr;
     514  int cga_emu;
     515
     516  /* Unmodified input is stored in the BDA. */
     517  curs = (CH << 8) + CL;
     518  write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_TYPE, curs);
     519
     520  /* Check if VGA is active. If not, just write the input to the CRTC. */
     521  if (read_byte(BIOSMEM_SEG, BIOSMEM_VIDEO_CTL) & 8) {
     522    /* Trying to disable the cursor? */
     523    if ((CH & 0x60) == 0x20) {
     524      /* Special IBM-compatible value to turn off cursor. */
     525      CH = 0x1E;
     526      CL = 0;
     527    } else {
     528      cga_emu = !(read_byte(BIOSMEM_SEG, BIOSMEM_VIDEO_CTL) & 1);
     529
     530      /* If CGA cursor emulation is on and this is a text mode, adjust.
     531       * But if cursor star or end is bigger than 31, don't adjust.
     532       */
     533      // @todo: Figure out if this is a text mode
     534      if (cga_emu /* && text mode*/ && (CH < 32) && (CL < 32)) {
     535        cheight = read_word(BIOSMEM_SEG, BIOSMEM_CHAR_HEIGHT);
     536
     537        /* Is the end lower than start? VGA does not wrap around.*/
     538        if (CL < CH) {
     539          /* For zero CL (end), leave values unchanged. */
     540          if (CL) {
     541            CH = 0;
     542            CL = cheight - 1;
     543          }
     544        } else {
     545          if (((CL | CH) >= cheight) || ((CL != cheight - 1) && (CH != cheight - 2))) {
     546            /* If it's an overbar cursor, don't adjust. */
     547            if (CL > 3) {
     548              if (CL <= CH + 2) {
     549                /* It's it a normal underline style cursor. */
     550                CH = CH - CL + cheight - 1;
     551                CL = cheight - 1;
     552                if (cheight >= 14) {
     553                  /* Shift up one pixel for normal EGA/VGA fonts. */
     554                  CL--;
     555                  CH--;
     556                }
     557              } else if (CH <= 2) {
     558                /* It's a full block cursor. */
     559                CL = cheight - 1;
     560              } else {
     561                /* It's a half block cursor. */
     562                CH = cheight / 2;
     563                CL = cheight - 1;
     564              }
     565            }
     566          }
     567        }
     568      }
     569    }
     570  }
     571
     572  // CTRC regs 0x0a and 0x0b
     573  crtc_addr = read_word(BIOSMEM_SEG, BIOSMEM_CRTC_ADDRESS);
     574  outb(crtc_addr, 0x0a);
     575  outb(crtc_addr + 1, CH);
     576  outb(crtc_addr, 0x0b);
     577  outb(crtc_addr + 1 ,CL);
    542578}
    543579
     
    815851 write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS,theightm1);
    816852 write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,cheight);
    817  write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|noclearmem));
     853 write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x68|noclearmem));
    818854 write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES,0xF9);
    819855 write_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f);
     
    22472283        biosfn_alternate_prtsc();
    22482284        break;
     2285       case 0x34:   /* CGA text cursor emulation control. */
     2286        if (GET_AL() < 2) {
     2287            write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,
     2288              (read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL) & ~1) | GET_AL());
     2289            SET_AL(0x12);
     2290        }
     2291        else
     2292         SET_AL(0); /* Invalid argument. */
     2293        break;
    22492294       case 0x35:
    22502295        biosfn_switch_video_interface(GET_AL(),ES,DX);
  • trunk/src/VBox/Devices/Graphics/BIOS/vgatables.h

    r76565 r82133  
    419419 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e,
    420420 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    421  0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
     421 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xc3,
    422422 0xff, /* crtc_regs */
    423423 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f,
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