Bona Fide OS Development
http://forums.osdever.net/

This is a good 320x200 code I wrote without BIOS
http://forums.osdever.net/viewtopic.php?f=4&t=2321
Page 1 of 1

Author:  ~ [ Thu Apr 12, 2012 7:36 am ]
Post subject:  This is a good 320x200 code I wrote without BIOS

Here is the full source code. It is 100% public domain. I did my best to make it work, and tested it with a Denthor of Asphyxia's programs with the BIOS call to set 13h stripped out, to make sure that my video setting sequence was correct, and it was, at least as far as I tested in my machines.

It is written in NASM and also in the language I created, called RealC, which you can see that is very easy to read (clearer than assembly or C for this kind of purely hardware/low level tasks).

http://126.sytes.net/brainstorm/320x200_noBIOS/320x200_noBIOS.zip
http://126.sytes.net/brainstorm/320x200_noBIOS/

Here is the main function that calls the rest of "API functions":

Code:
//This function makes the VGA card enter in
//standard 320x200 256-color MCGA mode,
//without using the BIOS.
//
//It performs the following sequence:
//
// 1. Turns off monitor output to completely avoid flicker,
//    frequency/synchrony issues while setting the video mode,
//    and apparently making the video mode switching much faster
//    from text to graphics.
//
// 2. Configures the Miscellaneous Output Register.
//
// 3. Configures the Feature Control Register.
//
// 4. Write the 5 Sequencer registers.
//
// 5. Unprotect CRTC registers 0-7.
//
// 6. Writes the 25 CRTC registers.
//
// 7. Protects CRTC registers 0-7.
//
// 8. Writes the 9 Graphics Controller Registers.
//
// 9. Writes the Attribute Controller Registers.
//    Here's an optimization: From its 21 registers, only
//    registers 16 to 20 are written. Registers 0 to 15
//    are left unchanged because those palette registers are
//    not useful for MCGA 320x200x256, so we skip writing those.
//
//10. Enable reads to the palette by setting bit 5 of the
//    Attribute Controller Index Register at 0x3C0, to 1.
//
//11. Turn back on monitor output to make use of the graphics mode.
//
//This sequence takes the best from all of the other programming sequences floating around
//for manually entering mode 13h, and thus has original-research optimizations
//from me (skipping configuration the 16-color palette of the Attribute Controller),
//and avoiding inferior ways of doing things (wait for vertical retrace, instead of
//doing it much better by disabling hardware video output, while reconfiguring
//the registers), etc. And it is much, much more documented and easy to read/understand,
//with nice and elegant public domain low level standard VGA "API" functions.
//
//This program does NOT reconfigure BIOS video mode metrics in the BDA, nor clears
//the screen after setting the video mode, just because those tasks are entirely
//apart from the low level hardware programming shown here. That would just add to the
//bulk of this demo program, and it will be programmed by me, but in a different, yet
//equally reusable/combinable "API" package.
///
function set_mode_MCGA_320x200x256()
{
 push $WIDEAX;
 push $WIDEBX;
 push $WIDECX;
 push $WIDESI;

 //Write to Color register address in all cases
 //that apply to our interfacing functions:
 ///
  $BX=0000000001000000b;


 //Turn monitor output off to be nicer with older
 //and delicate monitors while fiddling with the configuration:
 ///
  stdVGA_Sequencer_Monitor_Off();


 //We want to set this register to clear its bit 0,
 //to enforce activating I/O register addresses for
 //color video modes, and the rest of its configurations:
 ///
  $AL=[CGA_320x200x256Gen__MiscOutputReg];
  stdVGA_set_Miscellaneous_Output_Register();


 //Write the Feature Control Register:
 ///
  $AL=[CGA_320x200x256Gen__FeatureControlReg];
  //$BX=0000000001000000b;  //Write to Color register address
  stdVGA_set_Feature_Control_Register();


 //Write the Sequencer registers:
 ///
  $CH=0;  //Index of first register to write
  $CL=5;  //Number of registers to write
  $WIDESI=CGA_320x200x256SequencerRegs;
  stdVGA_set_Sequencer_regs();


 ///INIT: Write the CRTC registers
 ///INIT: Write the CRTC registers
 ///INIT: Write the CRTC registers
 ///INIT: Write the CRTC registers
 ///INIT: Write the CRTC registers

  //First unprotect registers 0-7:
  ///
   $CL=00000000b;          //Do Unprotect
   //$BX=0000000001000000b;  //Use Color I/O port address
   stdVGA_protect_unprotect_CRTC_regs();



  //Write the CRTC registers:
  ///
   $CH=0;   //Index of first register to write
   $CL=25;  //Number of registers to write
   //$BX=0000000001000000b;  //Use Color I/O port address
   $WIDESI=CGA_320x200x256CRTCRegs;
   stdVGA_set_CRTC_regs();



  //Finally, protect registers 0-7 again:
  ///
   $CL=10000000b;          //Do Protect
   //$BX=0000000001000000b;  //Use Color I/O port address
   stdVGA_protect_unprotect_CRTC_regs();


 ///END:  Write the CRTC registers
 ///END:  Write the CRTC registers
 ///END:  Write the CRTC registers
 ///END:  Write the CRTC registers
 ///END:  Write the CRTC registers



 //Write the Graphics Controller registers:
 ///
  $CH=0;  //Index of first register to write
  $CL=9;  //Number of registers to write
  $WIDESI=CGA_320x200x256GraphicsRegs;
  stdVGA_set_Graphics_regs();



 //Write the Attribute Controller registers. We will
 //try skipping the 16-color palette registers here,
 //since MCGA 320x200@256 colors uses the DAC instead
 //of those registers, and these registers don't care
 //in this mode:
 ///
  //Address bits of attribute flip/flop to reset it by reading it
  ///
   //$BX=0000000001000000b;
   $CH=16;     //Index of first register to write
   $CL=21-16;  //Number of registers to write
   $WIDESI=CGA_320x200x256AttributeRegs+16;
   stdVGA_set_Attribute_regs();



  //Enable the capability of reading the palette.
  //Otherwise, the screen will stay absolutely black!:
  ///
   stdVGA_set_Attribute_regs__EnablePalette();


 //Turn monitor output on (this assumes that the register
 //set values we are using keep the Sequencer's Screen Off bit
 //off at all times, to not defeat the very purpose of this
 //"protection"):
 ///
  stdVGA_Sequencer_Monitor_On();


 pop $WIDESI;
 pop $WIDECX;
 pop $WIDEBX;
 pop $WIDEAX;
}


I hope it can be useful as a tutorial for this kind topic, since information and code around isn't as documented as I tried this program to be.

If you find some error, flaw or weakness, please try to let me know so I can write an updated and corrected version of the code.

Attachments:
File comment: A "mirror" of the code in case my website is down, as is frequently.
320x200_noBIOS.zip [27.7 KiB]
Downloaded 1829 times

Author:  Kieran [ Thu Nov 29, 2012 4:48 am ]
Post subject:  Re: This is a good 320x200 code I wrote without BIOS

Great to see new content being added to Bona Fide.

I will be taking more of an interest in the site as I now have a permanent internet connection and free time to use :D

Author:  brenden [ Fri Feb 08, 2013 1:40 pm ]
Post subject:  Re: This is a good 320x200 code I wrote without BIOS

This looks pretty nifty! Why 320x200 though?

Page 1 of 1 All times are UTC - 6 hours [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/