VirtualBox

Ignore:
Timestamp:
Feb 18, 2022 2:14:39 PM (3 years ago)
Author:
vboxsync
Message:

VGABIOS: Reworked save area management, added support for font overrides, enabled mono mode 7.

File:
1 edited

Legend:

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

    r83002 r93841  
    160160
    161161// --------------------------------------------------------------------------------------------
    162 /*
    163  *  Boot time bios area inits
    164  */
    165 void init_bios_area(void)
    166 {
    167     uint8_t __far   *bda;
    168 
    169     bda = 0x40 :> 0;
    170 
    171     /* Indicate 80x25 color was detected. */
    172     bda[BIOSMEM_INITIAL_MODE] = (bda[BIOSMEM_INITIAL_MODE] & 0xcf) | 0x20;
    173     /* Just for the first int10 find its children. */
    174 
    175     /* The default char height. */
    176     bda[BIOSMEM_CHAR_HEIGHT] = 16;
    177     /* Clear the screen. */
    178     bda[BIOSMEM_VIDEO_CTL]   = 0x60;
    179     /* Set the basic screen we have. */
    180     bda[BIOSMEM_SWITCHES]    = 0xf9;
    181     /* Set the basic mode set options. */
    182     bda[BIOSMEM_MODESET_CTL] = 0x51;
    183     /* Set the default MSR. */
    184     bda[BIOSMEM_CURRENT_MSR] = 0x09;
    185 }
     162
     163#pragma pack(0)
     164
     165/* Alphanumeric character set override. */
     166typedef struct {
     167    uint8_t       c_height;   /* Bytes/lines per character. */
     168    uint8_t       cgen_bank;  /* Character generator bank. */
     169    uint16_t      char_num;   /* Number of chars defined. */
     170    uint16_t      char_1st;   /* First char code in table. */
     171    uint16_t      font_ofs;   /* Font definition table offset. */
     172    uint16_t      font_seg;   /* Font definition table segment. */
     173    uint8_t       n_rows;     /* Number of text rows shown. */
     174    uint8_t       modes[1];   /* Applicable modes list, 0xFF terminated. */
     175} cso_txt;
     176
     177/* Graphics character set override. */
     178typedef struct {
     179    uint8_t       c_height;   /* Lines per character. */
     180    uint16_t      c_len;      /* Bytes per character. */
     181    uint16_t      font_ofs;   /* Font definition table offset. */
     182    uint16_t      font_seg;   /* Font definition table segment. */
     183    uint8_t       modes[1];   /* Applicable modes list, 0xFF terminated. */
     184} cso_grf;
    186185
    187186struct dcc {
     
    217216    &secondary_save_area
    218217};
     218
     219/*
     220 *  Boot time bios area inits
     221 */
     222void init_bios_area(void)
     223{
     224    uint8_t __far   *bda;
     225
     226    bda = 0x40 :> 0;
     227
     228    /* Indicate 80x25 color was detected. */
     229    bda[BIOSMEM_INITIAL_MODE] = (bda[BIOSMEM_INITIAL_MODE] & 0xcf) | 0x20;
     230    /* Just for the first int10 find its children. */
     231
     232    /* The default char height. */
     233    bda[BIOSMEM_CHAR_HEIGHT] = 16;
     234    /* Clear the screen. */
     235    bda[BIOSMEM_VIDEO_CTL]   = 0x60;
     236    /* Set the basic screen we have. */
     237    bda[BIOSMEM_SWITCHES]    = 0xf9;
     238    /* Set the basic mode set options. */
     239    bda[BIOSMEM_MODESET_CTL] = 0x51;
     240    /* Set the default MSR. */
     241    bda[BIOSMEM_CURRENT_MSR] = 0x09;
     242    /* Initialize the default save area pointer. */
     243    *(void __far * __far *)&bda[BIOSMEM_VS_POINTER] = video_save_pointer_table;
     244}
    219245
    220246// ============================================================================================
     
    856882}
    857883
    858 /// Recursive BIOS invocation, uses
     884/// Recursive BIOS invocation, uses vector 6Dh
    859885extern void vga_font_set(uint8_t function, uint8_t data);
    860886#pragma aux vga_font_set =  \
     
    873899    0x2C, 0x28, 0x2D, 0x29, 0x2A, 0x2E, 0x1E, 0x29
    874900};
     901
     902static void biosfn_load_text_user_pat(uint8_t AL, uint16_t ES, uint16_t BP, uint16_t CX, uint16_t DX, uint8_t BL, uint8_t BH);
    875903
    876904void biosfn_set_video_mode(uint8_t mode)
     
    884912 uint16_t i;
    885913 uint16_t crtc_addr;
     914 void __far * __far *save_area;
     915 VideoParamTableEntry __far *vpt;
    886916
    887917#ifdef VBE
     
    896926 mode=mode&0x7f;
    897927
    898  // Display switching is not supported, and mono monitors aren't either.
    899  // Requests to set mode 7 (mono) must set mode 0 instead (color).
    900  if (mode == 7)
    901      mode = 0;
     928 // Display switching is not supported; mono monitors aren't really either,
     929 // but requests to set mode 7 are honored.
    902930
    903931 // find the entry in the video modes
     
    911939  return;
    912940
     941 // Read the save area pointer.
     942 save_area = (void __far *)read_dword(BIOSMEM_SEG, BIOSMEM_VS_POINTER);
     943
    913944 vpti=line_to_vpti[line];
     945 vpt = save_area[0];
     946 vpt += vpti;
    914947
    915948#if 0   // These are unused, but perhaps they shouldn't be?
     
    9751008 for(i=0;i<=0x13;i++)
    9761009  {outb(VGAREG_ACTL_ADDRESS,i);
    977    outb(VGAREG_ACTL_WRITE_DATA,video_param_table[vpti].actl_regs[i]);
     1010   outb(VGAREG_ACTL_WRITE_DATA,vpt->actl_regs[i]);
    9781011  }
    9791012 outb(VGAREG_ACTL_ADDRESS,0x14);
    9801013 outb(VGAREG_ACTL_WRITE_DATA,0x00);
     1014
     1015 save_area[0] = video_param_table;
     1016
     1017 // Save palette into the save area if it exists.
     1018 if(save_area[1])
     1019 {
     1020    uint8_t __far *dyn_save;
     1021
     1022    dyn_save = save_area[1];
     1023    for (i = 0; i < 16; ++i)
     1024       dyn_save[i] = vpt->actl_regs[i];
     1025    dyn_save[16] = vpt->actl_regs[17];
     1026 }
    9811027
    9821028 // Set Sequencer Ctl
     
    9851031 for(i=1;i<=4;i++)
    9861032  {outb(VGAREG_SEQU_ADDRESS,i);
    987    outb(VGAREG_SEQU_DATA,video_param_table[vpti].sequ_regs[i - 1]);
     1033   outb(VGAREG_SEQU_DATA,vpt->sequ_regs[i - 1]);
    9881034  }
    9891035
     
    9911037 for(i=0;i<=8;i++)
    9921038  {outb(VGAREG_GRDC_ADDRESS,i);
    993    outb(VGAREG_GRDC_DATA,video_param_table[vpti].grdc_regs[i]);
     1039   outb(VGAREG_GRDC_DATA,vpt->grdc_regs[i]);
    9941040  }
    9951041
    9961042 // Set CRTC address VGA or MDA
    9971043 crtc_addr=vga_modes[line].memmodel==MTEXT?VGAREG_MDA_CRTC_ADDRESS:VGAREG_VGA_CRTC_ADDRESS;
     1044
     1045  // Set the misc register; may change CRTC base!
     1046 outb(VGAREG_WRITE_MISC_OUTPUT,vpt->miscreg);
    9981047
    9991048 // Disable CRTC write protection
     
    10021051 for(i=0;i<=0x18;i++)
    10031052  {outb(crtc_addr,i);
    1004    outb(crtc_addr+1,video_param_table[vpti].crtc_regs[i]);
    1005   }
    1006 
    1007  // Set the misc register
    1008  outb(VGAREG_WRITE_MISC_OUTPUT,video_param_table[vpti].miscreg);
     1053   outb(crtc_addr+1,vpt->crtc_regs[i]);
     1054  }
    10091055
    10101056 // Enable video
    10111057 outb(VGAREG_ACTL_ADDRESS,0x20);
    1012  inb(VGAREG_ACTL_RESET);
     1058 inb(crtc_addr + VGAREG_ACTL_RESET - VGAREG_VGA_CRTC_ADDRESS);
    10131059
    10141060 if(noclearmem==0x00)
     
    10371083 // Set the BIOS mem
    10381084 write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode);
    1039  write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS,video_param_table[vpti].twidth);
    1040  write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,video_param_table[vpti].slength);
     1085 write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS,vpt->twidth);
     1086 write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,vpt->slength);
    10411087 write_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_addr);
    1042  write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS,video_param_table[vpti].theightm1);
    1043  write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,video_param_table[vpti].cheight);
     1088 write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS,vpt->theightm1);
     1089 write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,vpt->cheight);
    10441090 write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|noclearmem));
    10451091 write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES,0xF9);
     
    10481094 // FIXME We nearly have the good tables. to be reworked
    10491095 write_byte(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08);    // 8 is VGA should be ok for now
    1050  write_dword(BIOSMEM_SEG,BIOSMEM_VS_POINTER, (uint32_t)(void __far *)video_save_pointer_table);
    10511096
    10521097 if (mode <= 7)
     
    10621107  }
    10631108
     1109 /// @todo Could be optimized to a memset since only BDA needs updating.
    10641110 // Set cursor pos for page 0..7
    10651111 for(i=0;i<8;i++)
     
    10721118 if(vga_modes[line].class==TEXT)
    10731119  {
     1120     cso_txt __far   *ovr = save_area[2];
     1121
    10741122     biosfn_load_text_8_16_pat(0x04, 0);    /* Load 8x16 font into page 0. */
     1123     if (ovr)
     1124      {
     1125#ifdef VGA_DEBUG
     1126         printf("Charmap override found, font at %04x:%04x\n", ovr->font_seg, ovr->font_ofs);
     1127#endif
     1128         i = 0;
     1129         // Does the override support current mode?
     1130         while (ovr->modes[i] != 0xff)
     1131          {
     1132             if (ovr->modes[i] == mode)
     1133                break;
     1134             ++i;
     1135          }
     1136         // If there is a valid font override, apply it.
     1137         if (ovr->modes[i] == mode)
     1138          {
     1139#ifdef VGA_DEBUG
     1140             printf("Loading override, %04x chars, height %02x\n", ovr->char_num, ovr->c_height);
     1141#endif
     1142             biosfn_load_text_user_pat(0x10, ovr->font_seg, ovr->font_ofs, ovr->char_num,
     1143                                       ovr->char_1st, ovr->cgen_bank, ovr->c_height);
     1144          }
     1145      }
    10751146     vga_font_set(0x03, 0);                 /* Select font page mode 0. */
    10761147  }
     
    10791150 set_int_vector(0x1f, vgafont8+128*8);
    10801151
    1081   switch(video_param_table[vpti].cheight)
     1152  switch(vpt->cheight)
    10821153   {case 8:
    10831154     set_int_vector(0x43, vgafont8);
     
    18571928}
    18581929
     1930static void biosfn_set_font_block(uint8_t BL)
     1931{
     1932 outw(VGAREG_SEQU_ADDRESS, 0x0100);
     1933 outw(VGAREG_SEQU_ADDRESS, 0x0003 | (BL << 8));
     1934 outw(VGAREG_SEQU_ADDRESS, 0x0300);
     1935}
     1936
    18591937static void biosfn_load_text_user_pat(uint8_t AL, uint16_t ES, uint16_t BP, uint16_t CX,
    18601938                                      uint16_t DX, uint8_t BL, uint8_t BH)
     
    21482226
    21492227        for(i=0;i<=0x13;i++) {
    2150             inb(VGAREG_ACTL_RESET);
     2228            inb(VGAREG_ACTL_RESET); /* Reads do not toggle flip-flop! */
    21512229            outb(VGAREG_ACTL_ADDRESS, i | (ar_index & 0x20));
    21522230            write_byte(ES, BX, inb(VGAREG_ACTL_READ_DATA)); BX++;
     
    25112589        biosfn_load_text_8_8_pat(GET_AL(),GET_BL());
    25122590        break;
     2591       case 0x03:
     2592        biosfn_set_font_block(GET_BL());
     2593        break;
    25132594       case 0x04:
    25142595       case 0x14:
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