1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
#include "headers/types.h" //Basic types!
#include "headers/emu/gpu.h" //GPU support!
#include "headers/cpu/interrupts.h" //Interrupt support!
#include "headers/hardware/vga.h" //VGA support!
#include "headers/mmu/mmu.h" //BDA support!
#include "headers/mmu/bda.h" //BDA support!
#include "headers/hardware/vga_rest/colorconversion.h" //Color conversion support!
//Finally all subparts, in order of occurence:
#include "headers/hardware/vga_screen/vga_sequencer.h" //Sequencer!
#include "headers/hardware/vga_screen/vga_sequencer_textmode.h" //Text-mode!
#include "headers/hardware/vga_screen/vga_sequencer_textmode_cursor.h" //Text-mode cursor!
#include "headers/hardware/vga_screen/vga_attributecontroller.h" //Attribute controller!
#include "headers/hardware/vga_screen/vga_dac.h" //DAC operations!
#include "headers/hardware/vga_screen/vga_displaygeneration_crtcontroller.h" //CRT Controller
extern GPU_type GPU; //GPU contents!
extern BDA_type *BDA; //BIOS Data Area!
extern VGA_type VGA; //VGA!
uint_32 CurrentScanLine[1024]; //A scan line's data!
//Video padding functions:
//Display row info:
//Start Vertical Retrace=X width
//Vertical Total - Vertical Blank End = Y height
//Display type functions:
inline void dumpVGARegisters() //Dump all used VGA display registers?
{
return; //Not used for now!
int i;
int valid;
valid = 0; //Default: invalid!
for (i=0; i<NUMITEMS(VGA.registers->SequencerRegisters.DATA); i++) //Check if any value is non-0!
{
if (VGA.registers->SequencerRegisters.DATA[i]!=0) //Filled?
{
valid = 1; //Valid!
}
}
fontcolor(RGB(0xFF,0xFF,0xFF)); //White text!
if (!valid) //Not filled?
{
gotoxy(0,4);
printf("VGA Invalid!");
return; //Stop info!
}
gotoxy(0,4); //Start of info!
printf("Characters: %ix%i",getcharacterwidth(),getcharacterheight());
gotoxy(0,5);
printf("(Active area) Horiz start-end: %i-%i",getHorizontalStart(),getHorizontalEnd());
gotoxy(0,6);
printf("(Active area end, border start) Vertical display end: %i",getVerticalDisplayEnd());
gotoxy(0,7);
printf("(Border area) Vertical: >Vertical display end || < Vertical blank start");
gotoxy(0,8);
printf("(Border area) Horizontal: <Horizontal Start || (>Horizontal End & <Horizontal Blank Start)");
gotoxy(0,9);
printf("(Inactive area) Vertical blank start: %i+",getVerticalBlankingStart());
gotoxy(0,10);
printf("(Inactive area) Horizontal blank start: %i+",getHorizontalBlankingStart());
gotoxy(0,11);
printf("Screen split @%i",getTopWindowStart()); //Where to split?
gotoxy(0,12);
printf("Offset between two rows: %i",getrowsize()); //Row size!
}
inline int isvalidscanline(word ScanLine) //Are we GPU-renderable?
{
return ((NUMITEMS(GPU.emu_screenbuffer)/1024)>=(ScanLine+1)); //Enough scanlines to render?
}
inline void int10_renderScanLine(word ScanLine, byte currentscreenbottom) //Render a scanline for a top or bottom screen!
{
bzero(CurrentScanLine,sizeof(CurrentScanLine)); //No data to show by default!
if (!isvalidscanline(ScanLine) && (ScanLine<getTopWindowStart())) //Bottom and invalid?
{
return; //Disable when invalid scanline!
}
else if (!isvalidscanline(ScanLine-getTopWindowStart()) && (ScanLine>=getTopWindowStart())) //Top and invalid?
{
return; //Disable when invalid scanline!
}
dumpVGARegisters(); //Dump it if enabled!
readVGAInfo(&VGA.info); //Get the info!
if (VGA.registers->SequencerRegisters.REGISTERS.CLOCKINGMODEREGISTER.ScreenDisable) //No drawing (empty lines)?
{
//Do nothing to fill: screen is disabled, so empty buffer to show!
}
else //Fill the scan line!
{
VGA_Sequencer(ScanLine); //First, sequencer, attribute controller and special effects!
VGA_DAC(ScanLine,&VGA.info); //DAC final processing!
}
//Now copy to real video (if active screen)!
if ((ScanLine<getTopWindowStart()) && (currentscreenbottom)) //To do the bottom window?
{
memcpy(&GPU.emu_screenbuffer[ScanLine*1024],&CurrentScanLine,sizeof(CurrentScanLine)); //Copy the scan line to the screen buffer!
}
else if ((ScanLine>=getTopWindowStart()) && (!currentscreenbottom)) //To do the top window?
{
memcpy(&GPU.emu_screenbuffer[(ScanLine-getTopWindowStart())*1024],&CurrentScanLine,sizeof(CurrentScanLine)); //Copy the scan line to the screen buffer!
}
}
//To generate the screen, we use the CRTC registers!
extern int active_screen; //Active screen?
int cursorCounter = 0; //For cursor on/off!
inline void VGA_generateScreenLine() //Generate a screen line!
{
if (!GPU.video_on) //Not rendering?
{
return; //Don't do rendering!
}
if (BDA==NULL) //No BIOS Data Area set yet?
{
raiseError("vga_screen::int10_generatescreen","No BDA set!");
return; //Stop: No BDA!
}
GPU.GPU_screenxsize = getxresfull(); //X resolution we need!
GPU.GPU_screenysize = getyresfull(); //Y resolution we need!
//We work by changing one scan line at a time!
readVGAInfo(&VGA.info); //Prepare our VGA info!
int10_renderScanLine(VGA.registers->Scanline++,!active_screen); //Process the scan line (we're running the top window)!
if (VGA.registers->Scanline>VGA.info.graphics_rows) //Over the limit?
{
VGA.registers->VerticalDisplayTotalReached = 1; //Reset!
}
if (VGA.registers->VerticalDisplayTotalReached) //Total reached (to reset?)
{
VGA.registers->Scanline = 0; //Reset scan line to the top of the screen!
VGA.frameDone = 1; //We have a frame ready, so we can refresh now, GPU!
VGA.registers->VerticalDisplayTotalReached = 0; //Reset!
VGA_VBlankHandler(); //Handle all VBlank stuff!
}
//Now a scanline has been rendered!
}
|