Opengl output support in SDL
Removed threading support in SDL Rewrite of VGA Drawing to work line for line Rewrite of VGA Text drawing using lookup tables Rewrite of render function to handle the new line for line drawing. Changed CGA/TANDY/Hercules to be more like their original hardware. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1611
This commit is contained in:
parent
2cfb92f5c6
commit
9bf1cd50f5
11 changed files with 714 additions and 610 deletions
|
@ -31,10 +31,14 @@ VGA_Type vga;
|
|||
Bit32u CGA_2_Table[16];
|
||||
Bit32u CGA_4_Table[256];
|
||||
Bit32u CGA_16_Table[256];
|
||||
Bit32u TXT_Font_Table[16];
|
||||
Bit32u TXT_FG_Table[16];
|
||||
Bit32u TXT_BG_Table[16];
|
||||
Bit32u ExpandTable[256];
|
||||
Bit32u Expand16Table[4][16];
|
||||
Bit32u Expand16BigTable[0x10000];
|
||||
Bit32u FillTable[16];
|
||||
Bit32u ColorTable[16];
|
||||
|
||||
|
||||
|
||||
void VGA_SetMode(VGAModes mode) {
|
||||
|
@ -107,18 +111,34 @@ void VGA_Init(Section* sec) {
|
|||
#endif
|
||||
}
|
||||
for (i=0;i<16;i++) {
|
||||
TXT_FG_Table[i]=i | (i << 8)| (i <<16) | (i << 24);
|
||||
TXT_BG_Table[i]=i | (i << 8)| (i <<16) | (i << 24);
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
CGA_2_Table[i]=((i>>0)&1) | (((i>>1)&1) << 8)| (((i>>1)&1) <<16) | (((i>>3)&1) << 24);
|
||||
FillTable[i]= ((i & 1) ? 0xff000000 : 0) |
|
||||
FillTable[i]=
|
||||
((i & 1) ? 0xff000000 : 0) |
|
||||
((i & 2) ? 0x00ff0000 : 0) |
|
||||
((i & 4) ? 0x0000ff00 : 0) |
|
||||
((i & 8) ? 0x000000ff : 0) ;
|
||||
((i & 4) ? 0x0000ff00 : 0) |
|
||||
((i & 8) ? 0x000000ff : 0) ;
|
||||
TXT_Font_Table[i]=
|
||||
((i & 1) ? 0x000000ff : 0) |
|
||||
((i & 2) ? 0x0000ff00 : 0) |
|
||||
((i & 4) ? 0x00ff0000 : 0) |
|
||||
((i & 8) ? 0xff000000 : 0) ;
|
||||
#else
|
||||
CGA_2_Table[i]=((i>>3)&1) | (((i>>2)&1) << 8)| (((i>>1)&1) <<16) | (((i>>0)&1) << 24);
|
||||
FillTable[i]= ((i & 1) ? 0x000000ff : 0) |
|
||||
((i & 2) ? 0x0000ff00 : 0) |
|
||||
((i & 4) ? 0x00ff0000 : 0) |
|
||||
((i & 8) ? 0xff000000 : 0) ;
|
||||
FillTable[i]=
|
||||
((i & 1) ? 0x000000ff : 0) |
|
||||
((i & 2) ? 0x0000ff00 : 0) |
|
||||
((i & 4) ? 0x00ff0000 : 0) |
|
||||
((i & 8) ? 0xff000000 : 0) ;
|
||||
TXT_Font_Table[i]=
|
||||
((i & 1) ? 0xff000000 : 0) |
|
||||
((i & 2) ? 0x00ff0000 : 0) |
|
||||
((i & 4) ? 0x0000ff00 : 0) |
|
||||
((i & 8) ? 0x000000ff : 0) ;
|
||||
|
||||
#endif
|
||||
}
|
||||
for (j=0;j<4;j++) {
|
||||
|
@ -138,28 +158,5 @@ void VGA_Init(Section* sec) {
|
|||
#endif
|
||||
}
|
||||
}
|
||||
for (i=0;i<0x10000;i++) {
|
||||
Bit32u val=0;
|
||||
if (i & 0x1) val|=0x1 << 24;
|
||||
if (i & 0x2) val|=0x1 << 16;
|
||||
if (i & 0x4) val|=0x1 << 8;
|
||||
if (i & 0x8) val|=0x1 << 0;
|
||||
|
||||
if (i & 0x10) val|=0x4 << 24;
|
||||
if (i & 0x20) val|=0x4 << 16;
|
||||
if (i & 0x40) val|=0x4 << 8;
|
||||
if (i & 0x80) val|=0x4 << 0;
|
||||
|
||||
if (i & 0x100) val|=0x2 << 24;
|
||||
if (i & 0x200) val|=0x2 << 16;
|
||||
if (i & 0x400) val|=0x2 << 8;
|
||||
if (i & 0x800) val|=0x2 << 0;
|
||||
|
||||
if (i & 0x1000) val|=0x8 << 24;
|
||||
if (i & 0x2000) val|=0x8 << 16;
|
||||
if (i & 0x4000) val|=0x8 << 8;
|
||||
if (i & 0x8000) val|=0x8 << 0;
|
||||
Expand16BigTable[i]=val;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -127,8 +127,6 @@ void write_p3d5(Bit32u port,Bit8u val) {
|
|||
*/
|
||||
break;
|
||||
case 0x09: /* Maximum Scan Line Register */
|
||||
vga.config.vline_double=(val & 128)>1;
|
||||
vga.config.vline_height=(val & 0xf);
|
||||
vga.config.line_compare=(vga.config.line_compare & 0x5ff)|(val&0x40)<<3;
|
||||
if ((vga.crtc.maximum_scan_line ^ val) & 0xbf) {
|
||||
crtc(maximum_scan_line)=val;
|
||||
|
|
|
@ -17,73 +17,50 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "dosbox.h"
|
||||
#include "video.h"
|
||||
#include "render.h"
|
||||
#include "vga.h"
|
||||
#include "pic.h"
|
||||
|
||||
//TODO Make the full draw like the vga really does from video memory.
|
||||
#define VGA_PARTS 4
|
||||
|
||||
#define FIXED_CGA_SIZED 1
|
||||
static Bit8u VGA_DrawBuffer[2048];
|
||||
|
||||
static void VGA_HERC_Draw(Bit8u * bitdata,Bitu pitch) {
|
||||
Bit8u * reader=&vga.mem.linear[0];
|
||||
for (Bitu y=0;y<vga.draw.height;y++) {
|
||||
Bit8u * tempread=reader+((y & 3) * 8 * 1024);
|
||||
Bit8u * draw=bitdata;
|
||||
for (Bitu x=vga.draw.width>>3;x>0;x--) {
|
||||
Bit8u val=*(tempread++);
|
||||
*(Bit32u *)(draw+0)=CGA_2_Table[val >> 4];
|
||||
*(Bit32u *)(draw+4)=CGA_2_Table[val & 0xf];
|
||||
draw+=8;
|
||||
}
|
||||
if ((y & 3)==3) reader+=90;
|
||||
bitdata+=pitch;
|
||||
typedef Bit8u * (* VGA_Line_Handler)(Bitu vidstart,Bitu panning,Bitu line);
|
||||
|
||||
static VGA_Line_Handler VGA_DrawLine;
|
||||
|
||||
static Bit8u * VGA_HERC_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
Bit8u * reader=&vga.mem.linear[vidstart+(line * 8 * 1024)];
|
||||
Bit32u * draw=(Bit32u *)&VGA_DrawBuffer[0];
|
||||
for (Bitu x=vga.draw.blocks;x>0;x--) {
|
||||
Bitu val=*reader++;
|
||||
*draw++=CGA_2_Table[val >> 4];
|
||||
*draw++=CGA_2_Table[val & 0xf];
|
||||
}
|
||||
return VGA_DrawBuffer;
|
||||
}
|
||||
|
||||
static void VGA_CGA2_Draw(Bit8u * bitdata,Bitu pitch) {
|
||||
Bit8u * reader=&vga.mem.linear[0];
|
||||
Bit8u * flip=&vga.mem.linear[8*1024];
|
||||
Bit8u * draw;
|
||||
for (Bitu y=0;y<vga.draw.height;y++) {
|
||||
Bit8u * tempread=reader;
|
||||
if (y&1) {
|
||||
tempread+=8*1024;
|
||||
reader+=80;
|
||||
};
|
||||
draw=bitdata;
|
||||
for (Bitu x=vga.draw.width>>3;x>0;x--) {
|
||||
Bit8u val=*(tempread++);
|
||||
*(Bit32u *)(draw+0)=CGA_2_Table[val >> 4];
|
||||
*(Bit32u *)(draw+4)=CGA_2_Table[val & 0xf];
|
||||
draw+=8;
|
||||
}
|
||||
bitdata+=pitch;
|
||||
static Bit8u * VGA_CGA2_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
Bit8u * reader=&vga.mem.linear[vidstart+(line * 8 * 1024)];
|
||||
Bit32u * draw=(Bit32u *)&VGA_DrawBuffer[0];
|
||||
for (Bitu x=vga.draw.blocks;x>0;x--) {
|
||||
Bitu val=*reader++;
|
||||
*draw++=CGA_2_Table[val >> 4];
|
||||
*draw++=CGA_2_Table[val & 0xf];
|
||||
}
|
||||
return VGA_DrawBuffer;
|
||||
}
|
||||
|
||||
static void VGA_CGA4_Draw(Bit8u * bitdata,Bitu pitch) {
|
||||
Bit8u * reader=&vga.mem.linear[0];
|
||||
Bit8u * flip=&vga.mem.linear[8*1024];
|
||||
Bit8u * draw;
|
||||
for (Bitu y=0;y<vga.draw.height;y++) {
|
||||
Bit8u * tempread;
|
||||
tempread=reader;
|
||||
if (y&1) {
|
||||
tempread+=8*1024;
|
||||
reader+=80;
|
||||
if (reader>=flip) reader-=8*1024;
|
||||
}
|
||||
draw=bitdata;
|
||||
for (Bitu x=0;x<vga.draw.width>>2;x++) {
|
||||
Bit8u val=*(tempread++);
|
||||
*(Bit32u *)draw=CGA_4_Table[val];
|
||||
draw+=4;
|
||||
}
|
||||
bitdata+=pitch;
|
||||
static Bit8u * VGA_CGA4_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
Bit8u * reader=&vga.mem.linear[vidstart+(line * 8 * 1024)];
|
||||
Bit32u * draw=(Bit32u *)&VGA_DrawBuffer[0];
|
||||
for (Bitu x=0;x<vga.draw.blocks;x++) {
|
||||
*draw++=CGA_4_Table[*reader++];
|
||||
}
|
||||
return VGA_DrawBuffer;
|
||||
}
|
||||
|
||||
|
||||
|
@ -92,126 +69,80 @@ static Bit8u convert16[16]={
|
|||
0x6,0xa,0x8,0xb,0xd,0xe,0xc,0xf
|
||||
};
|
||||
|
||||
static void VGA_CGA16_Draw(Bit8u * bitdata,Bitu pitch) {
|
||||
Bit8u * reader=&vga.mem.linear[0];
|
||||
Bit8u * flip=&vga.mem.linear[8*1024];
|
||||
Bit8u * draw;
|
||||
for (Bitu y=0;y<200;y++) {
|
||||
Bit8u * tempread;
|
||||
tempread=reader;
|
||||
if (y&1) {
|
||||
tempread+=8*1024;
|
||||
reader+=80;
|
||||
if (reader>=flip) reader-=8*1024;
|
||||
}
|
||||
draw=bitdata;
|
||||
for (Bitu x=0;x<80;x++) {
|
||||
Bit8u val=*(tempread++);
|
||||
|
||||
Bit32u full=convert16[(val & 0xf0) >> 4] | convert16[val & 0xf] << 16;
|
||||
full|=full<<8;
|
||||
*(Bit32u *)draw=full;
|
||||
draw+=4;
|
||||
}
|
||||
bitdata+=pitch;
|
||||
static Bit8u * VGA_CGA16_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
Bit8u * reader=&vga.mem.linear[vidstart+(line * 8 * 1024)];
|
||||
Bit32u * draw=(Bit32u *)&VGA_DrawBuffer[0];
|
||||
for (Bitu x=0;x<vga.draw.blocks;x++) {
|
||||
Bitu val=*reader++;
|
||||
Bit32u full=convert16[val >> 4] | convert16[val & 0xf] << 16;
|
||||
*draw++=full|=full<<8;
|
||||
}
|
||||
return VGA_DrawBuffer;
|
||||
}
|
||||
|
||||
static void VGA_TANDY16_Draw(Bit8u * bitdata,Bitu pitch) {
|
||||
Bit8u * reader=&vga.mem.linear[(vga.tandy.disp_bank << 14) + vga.config.display_start*2];
|
||||
|
||||
for (Bitu y=0;y<vga.draw.height;y++) {
|
||||
Bit8u * tempread=reader+((y & 3) * 8 * 1024);
|
||||
Bit8u * draw=bitdata;
|
||||
for (Bitu x=0;x<vga.draw.width>>2;x++) {
|
||||
Bit8u val1=*(tempread++);
|
||||
Bit8u val2=*(tempread++);
|
||||
Bit32u full=(val1 & 0x0f) << 8 |
|
||||
(val1 & 0xf0) >> 4 |
|
||||
(val2 & 0x0f) << 24 |
|
||||
(val2 & 0xf0) << 12;
|
||||
*(Bit32u *)draw=full;
|
||||
draw+=4;
|
||||
}
|
||||
bitdata+=pitch;
|
||||
if ((y & 3)==3)reader+=160;
|
||||
static Bit8u * VGA_TANDY16_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
Bit8u * reader=&vga.mem.linear[(vga.tandy.disp_bank << 14) + vidstart + (line * 8 * 1024)];
|
||||
Bit32u * draw=(Bit32u *)&VGA_DrawBuffer[0];
|
||||
for (Bitu x=0;x<vga.draw.blocks;x++) {
|
||||
Bitu val1=*reader++;Bitu val2=*reader++;
|
||||
*draw++=(val1 & 0x0f) << 8 |
|
||||
(val1 & 0xf0) >> 4 |
|
||||
(val2 & 0x0f) << 24 |
|
||||
(val2 & 0xf0) << 12;
|
||||
}
|
||||
return VGA_DrawBuffer;
|
||||
}
|
||||
|
||||
static Bit8u * VGA_EGA_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
return &vga.mem.linear[512*1024+vidstart*8+panning];
|
||||
}
|
||||
static Bit8u * VGA_VGA_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
return &vga.mem.linear[vidstart*4+panning/2];
|
||||
}
|
||||
|
||||
void VGA_TEXT_Draw(Bit8u * bitdata,Bitu start,Bitu panning,Bitu rows) {
|
||||
Bit8u * reader=&vga.mem.linear[start*2];
|
||||
Bit8u * draw_start=bitdata;
|
||||
/* Todo Blinking and high intensity colors */
|
||||
Bitu next_charline=vga.draw.font_height*vga.draw.width;
|
||||
Bitu next_line=vga.draw.width;
|
||||
Bitu next_start=(vga.config.scan_len*2)-vga.draw.cols;
|
||||
static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
Bit8u * draw=VGA_DrawBuffer;
|
||||
Bit8u * vidmem=&vga.mem.linear[vidstart];
|
||||
for (Bitu cx=0;cx<vga.draw.blocks;cx++) {
|
||||
Bitu chr=vidmem[cx*2];
|
||||
Bitu font=vga.draw.font[chr*32+line];
|
||||
Bit32u mask1=TXT_Font_Table[font>>4];
|
||||
Bit32u mask2=TXT_Font_Table[font&0xf];
|
||||
Bitu col=vidmem[cx*2+1];
|
||||
Bit32u fg=TXT_FG_Table[col&0xf];
|
||||
Bit32u bg=TXT_BG_Table[col>>4];
|
||||
*(Bit32u*)draw=fg&mask1 | bg&~mask1;
|
||||
draw+=4;
|
||||
*(Bit32u*)draw=fg&mask2 | bg&~mask2;
|
||||
draw+=4;
|
||||
}
|
||||
return VGA_DrawBuffer;
|
||||
}
|
||||
|
||||
void VGA_TEXT_Draw(Bit8u * bitdata,Bitu start,Bitu panning,Bitu lines) {
|
||||
#if 0
|
||||
Bit8u * reader=&vga.mem.linear[start*2];Bitu rows=lines/vga.draw.font_height;
|
||||
for (Bitu cy=rows;cy>0;cy--) {
|
||||
Bit8u * draw_char=draw_start;
|
||||
/* Do first character keeping track of panning */
|
||||
{
|
||||
Bit8u c=*(reader++);
|
||||
Bit8u * findex=&vga.draw.font[c*32];
|
||||
Bit8u col=*(reader++);
|
||||
Bit8u fg=col & 0xF;
|
||||
Bit8u bg=(col>> 4);
|
||||
Bit8u * draw_line=draw_char;
|
||||
Bit8u bit_index=1 << (7-panning);
|
||||
for (Bitu y=vga.draw.font_height;y>0;y--) {
|
||||
Bit8u * draw=draw_line;
|
||||
draw_line+=next_line;
|
||||
Bit8u bit=bit_index;
|
||||
Bit8u bit_mask=*findex++;
|
||||
while (bit) {
|
||||
if (bit_mask & bit) *draw=fg;
|
||||
else *draw=bg;
|
||||
draw++;bit>>=1;
|
||||
}
|
||||
}
|
||||
draw_char+=8-panning;
|
||||
}
|
||||
for (Bitu cx=vga.draw.cols-1;cx>0;cx--) {
|
||||
Bit8u c=*(reader++);
|
||||
Bit8u * findex=&vga.draw.font[c*32];
|
||||
Bit8u col=*(reader++);
|
||||
Bit8u fg=col & 0xF;
|
||||
Bit8u bg=(col>> 4);
|
||||
Bit8u * draw=draw_char;
|
||||
for (Bitu y=vga.draw.font_height;y>0;y--) {
|
||||
Bit8u bit_mask=*findex++;
|
||||
#include "font-switch.h"
|
||||
draw+=next_line;
|
||||
}
|
||||
draw_char+=8;
|
||||
}
|
||||
/* Do last character if needed */
|
||||
if (panning) {
|
||||
Bit8u c=*(reader);
|
||||
Bit8u * findex=&vga.draw.font[c*32];
|
||||
Bit8u col=*(reader+1);
|
||||
Bit8u fg=col & 0xF;
|
||||
Bit8u bg=(col>> 4);
|
||||
Bit8u * draw_line=draw_char;
|
||||
Bit8u bit_index=1 << panning;
|
||||
for (Bitu y=vga.draw.font_height;y>0;y--) {
|
||||
Bit8u * draw=draw_line;
|
||||
draw_line+=next_line;
|
||||
Bit8u bit=bit_index;
|
||||
Bit8u bit_mask=*findex++;
|
||||
while (bit) {
|
||||
if (bit_mask & bit) *draw=fg;
|
||||
else *draw=bg;
|
||||
draw++;bit>>=1;
|
||||
}
|
||||
for (Bitu y=0;y<vga.draw.font_height;y++) {
|
||||
Bit8u * draw=bitdata;
|
||||
bitdata+=vga.draw.width;
|
||||
for (Bitu cx=0;cx<vga.draw.cols;cx++) {
|
||||
Bit8u chr=reader[cx*2];
|
||||
Bit8u font=vga.draw.font[chr*32+y];
|
||||
Bit32u mask1=TXT_Font_Table[font>>4];
|
||||
Bit32u mask2=TXT_Font_Table[font&0xf];
|
||||
Bit8u col=reader[cx*2+1];
|
||||
Bit32u fg=TXT_FG_Table[col&0xf];
|
||||
Bit32u bg=TXT_BG_Table[col>>4];
|
||||
*(Bit32u*)draw=fg&mask1 | bg&~mask1;
|
||||
draw+=4;
|
||||
*(Bit32u*)draw=fg&mask2 | bg&~mask2;
|
||||
draw+=4;
|
||||
}
|
||||
}
|
||||
draw_start+=next_charline;
|
||||
reader+=next_start;
|
||||
reader+=(vga.config.scan_len*4);
|
||||
}
|
||||
/* Cursor handling */
|
||||
vga.draw.cursor.count++;
|
||||
if (vga.draw.cursor.count>16) vga.draw.cursor.count=0;
|
||||
|
||||
if(vga.draw.cursor.enabled && (vga.draw.cursor.count>8)) { /* Draw a cursor if enabled */
|
||||
Bits cur_start=vga.config.cursor_start-start;
|
||||
if (cur_start<0) return;
|
||||
|
@ -219,8 +150,7 @@ void VGA_TEXT_Draw(Bit8u * bitdata,Bitu start,Bitu panning,Bitu rows) {
|
|||
Bitu row=cur_start / (vga.config.scan_len*2);
|
||||
Bitu col=cur_start % (vga.config.scan_len*2);
|
||||
Bit32u att=vga.mem.linear[vga.config.cursor_start*2+1]&0xf;
|
||||
att=(att << 8) | att;
|
||||
att=(att << 16) | att;
|
||||
att=TXT_BG_Table[att];
|
||||
|
||||
if ((col*8)>=vga.draw.width) return;
|
||||
if ((row*vga.draw.font_height)>=vga.draw.height) return;
|
||||
|
@ -234,118 +164,60 @@ void VGA_TEXT_Draw(Bit8u * bitdata,Bitu start,Bitu panning,Bitu rows) {
|
|||
cursor_draw+=vga.draw.width;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void EndRetrace(void) {
|
||||
/* start the actual display update now */
|
||||
RENDER_DoUpdate();
|
||||
vga.config.retrace=false;
|
||||
}
|
||||
|
||||
static void VGA_BlankTimer() {
|
||||
PIC_AddEvent(VGA_BlankTimer,vga.draw.blank);
|
||||
PIC_AddEvent(EndRetrace,667);
|
||||
/* Setup a timer to destroy the vertical retrace bit in a few microseconds */
|
||||
vga.config.real_start=vga.config.display_start;
|
||||
static void VGA_VerticalDisplayEnd(void) {
|
||||
vga.config.retrace=true;
|
||||
vga.config.real_start=vga.config.display_start;
|
||||
}
|
||||
|
||||
void VGA_DrawHandler(RENDER_Part_Handler part_handler) {
|
||||
Bit8u * buf,* bufsplit;
|
||||
/* Draw the current frame */
|
||||
if (!vga.draw.resizing) {
|
||||
if (vga.config.line_compare<vga.draw.lines) {
|
||||
Bitu stop=vga.config.line_compare/vga.draw.scaleh;
|
||||
if (stop>=vga.draw.height){
|
||||
LOG(LOG_VGAGFX,LOG_NORMAL)("Split at %d",stop);
|
||||
goto drawnormal;
|
||||
}
|
||||
switch (vga.mode) {
|
||||
case M_EGA16:
|
||||
buf=&vga.mem.linear[512*1024+vga.config.real_start*8+vga.config.pel_panning];
|
||||
bufsplit=&vga.mem.linear[512*1024];
|
||||
break;
|
||||
case M_VGA:
|
||||
case M_LIN8:
|
||||
buf=&vga.mem.linear[vga.config.real_start*4+vga.config.pel_panning];
|
||||
bufsplit=vga.mem.linear;
|
||||
break;
|
||||
case M_TEXT2:
|
||||
case M_TEXT16:
|
||||
{
|
||||
Bitu first_rows=stop/vga.draw.font_height;
|
||||
if (vga.config.hlines_skip) first_rows++;
|
||||
if (stop%vga.draw.font_height) first_rows++;
|
||||
Bitu next_rows=(vga.draw.height-stop)/vga.draw.font_height;
|
||||
if ((vga.draw.height-stop)%vga.draw.font_height) next_rows++;
|
||||
VGA_TEXT_Draw(&vga.mem.linear[512*1024],vga.config.real_start,vga.config.pel_panning,first_rows);
|
||||
VGA_TEXT_Draw(&vga.mem.linear[1024*1024],0,0,next_rows);
|
||||
buf=&vga.mem.linear[512*1024+vga.config.hlines_skip*vga.draw.width];
|
||||
bufsplit=&vga.mem.linear[1024*1024];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_VGAGFX,LOG_NORMAL)("VGA:Unhandled split screen mode %d",vga.mode);
|
||||
goto norender;
|
||||
}
|
||||
if (stop) part_handler(buf,0,0,vga.draw.width,stop);
|
||||
if (vga.draw.height-stop) part_handler(bufsplit,0,stop,vga.draw.width,vga.draw.height-stop);
|
||||
} else {
|
||||
drawnormal:
|
||||
switch (vga.mode) {
|
||||
case M_HERC:
|
||||
VGA_HERC_Draw(&vga.mem.linear[512*1024],vga.draw.width);
|
||||
buf=&vga.mem.linear[512*1024];
|
||||
break;
|
||||
case M_CGA2:
|
||||
VGA_CGA2_Draw(&vga.mem.linear[512*1024],vga.draw.width);
|
||||
buf=&vga.mem.linear[512*1024];
|
||||
break;
|
||||
case M_CGA4:
|
||||
VGA_CGA4_Draw(&vga.mem.linear[512*1024],vga.draw.width);
|
||||
buf=&vga.mem.linear[512*1024];
|
||||
break;
|
||||
case M_CGA16:
|
||||
VGA_CGA16_Draw(&vga.mem.linear[512*1024],vga.draw.width);
|
||||
buf=&vga.mem.linear[512*1024];
|
||||
break;
|
||||
case M_TANDY16:
|
||||
VGA_TANDY16_Draw(&vga.mem.linear[512*1024],vga.draw.width);
|
||||
buf=&vga.mem.linear[512*1024];
|
||||
break;
|
||||
case M_EGA16:
|
||||
buf=&vga.mem.linear[512*1024+vga.config.real_start*8+vga.config.pel_panning];
|
||||
break;
|
||||
case M_VGA:
|
||||
case M_LIN8:
|
||||
buf=&vga.mem.linear[vga.config.real_start*4+vga.config.pel_panning];
|
||||
break;
|
||||
case M_TEXT2:
|
||||
case M_TEXT16:
|
||||
{
|
||||
Bitu rows=vga.draw.rows;
|
||||
if (vga.config.hlines_skip) rows++;
|
||||
VGA_TEXT_Draw(&vga.mem.linear[512*1024],vga.config.real_start,vga.config.pel_panning,rows);
|
||||
buf=&vga.mem.linear[512*1024+vga.config.hlines_skip*vga.draw.width];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
part_handler(buf,0,0,vga.draw.width,vga.draw.height);
|
||||
static void VGA_HorizontalTimer(void) {
|
||||
|
||||
}
|
||||
|
||||
static void VGA_DrawPart(void) {
|
||||
Bitu subline=0;Bitu vidofs=vga.config.real_start;
|
||||
Bit8u * draw=0;
|
||||
while (vga.draw.lines_left) {
|
||||
vga.draw.lines_left--;
|
||||
Bit8u * data=VGA_DrawLine(vga.draw.address,vga.draw.panning,vga.draw.address_line);
|
||||
RENDER_DrawLine(data);
|
||||
vga.draw.address_line++;
|
||||
if (vga.draw.address_line>=vga.draw.address_line_total) {
|
||||
vga.draw.address_line=0;
|
||||
vga.draw.address+=vga.draw.address_add;
|
||||
}
|
||||
if (vga.draw.split_line==vga.draw.lines_left) {
|
||||
vga.draw.address=0;vga.draw.panning=0;
|
||||
}
|
||||
norender:;
|
||||
}
|
||||
|
||||
RENDER_EndUpdate();
|
||||
// vga.draw.parts_left--;
|
||||
// if (vga.draw.parts_left) PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts);
|
||||
}
|
||||
|
||||
static void VGA_VerticalTimer(void) {
|
||||
vga.config.retrace=false;
|
||||
vga.draw.cursor.count++;vga.draw.cursor.count&=0xf;
|
||||
PIC_AddEvent(VGA_VerticalTimer,vga.draw.micro.vtotal);
|
||||
PIC_AddEvent(VGA_VerticalDisplayEnd,vga.draw.micro.vend);
|
||||
vga.draw.parts_left=4;
|
||||
vga.draw.lines_left=vga.draw.lines_total;
|
||||
vga.draw.address=vga.config.real_start;
|
||||
vga.draw.address_line=vga.config.hlines_skip;
|
||||
vga.draw.split_line=vga.draw.lines_total-(vga.config.line_compare/vga.draw.lines_scaled);
|
||||
vga.draw.panning=vga.config.pel_panning;
|
||||
if (RENDER_StartUpdate()) {
|
||||
VGA_DrawPart();
|
||||
}
|
||||
}
|
||||
|
||||
void VGA_SetupDrawing(void) {
|
||||
/* Calculate the FPS for this screen */
|
||||
double fps;
|
||||
Bitu vtotal=2 + vga.crtc.vertical_total |
|
||||
((vga.crtc.overflow & 1) << 8) | ((vga.crtc.overflow & 0x20) << 4)
|
||||
;
|
||||
((vga.crtc.overflow & 1) << 8) | ((vga.crtc.overflow & 0x20) << 4);
|
||||
Bitu htotal=5 + vga.crtc.horizontal_total;
|
||||
Bitu vdispend = 1 + (vga.crtc.vertical_display_end |
|
||||
((vga.crtc.overflow & 2)<<7) | ((vga.crtc.overflow & 0x40) << 3) |
|
||||
|
@ -353,12 +225,16 @@ void VGA_SetupDrawing(void) {
|
|||
Bitu hdispend = 1 + (vga.crtc.horizontal_display_end);
|
||||
|
||||
Bitu hbstart = vga.crtc.start_horizontal_blanking;
|
||||
Bitu vbstart = vga.crtc.start_vertical_blanking | ((vga.crtc.overflow & 0x08) << 5) | ((vga.crtc.maximum_scan_line & 0x20) << 4) ;
|
||||
|
||||
if (hbstart<hdispend)
|
||||
hdispend=hbstart;
|
||||
if (vbstart<vdispend)
|
||||
vdispend=vbstart;
|
||||
Bitu vbstart = vga.crtc.start_vertical_blanking | ((vga.crtc.overflow & 0x08) << 5) |
|
||||
((vga.crtc.maximum_scan_line & 0x20) << 4) ;
|
||||
|
||||
Bitu hrstart = vga.crtc.start_horizontal_retrace;
|
||||
Bitu vrstart = vga.crtc.vertical_retrace_start + ((vga.crtc.overflow & 0x04) << 6) |
|
||||
((vga.crtc.overflow & 0x80) << 2);
|
||||
|
||||
if (hbstart<hdispend) hdispend=hbstart;
|
||||
if (vbstart<vdispend) vdispend=vbstart;
|
||||
|
||||
Bitu clock=(vga.misc_output >> 2) & 3;
|
||||
clock=1000*S3_CLOCK(vga.s3.clk[clock].m,vga.s3.clk[clock].n,vga.s3.clk[clock].r);
|
||||
/* Check for 8 for 9 character clock mode */
|
||||
|
@ -369,11 +245,20 @@ void VGA_SetupDrawing(void) {
|
|||
}
|
||||
/* Check for dual transfer whatever thing,master clock/2 */
|
||||
if (vga.s3.pll.cmd & 0x10) clock/=2;
|
||||
|
||||
|
||||
LOG(LOG_VGA,LOG_NORMAL)("H total %d, V Total %d",htotal,vtotal);
|
||||
LOG(LOG_VGA,LOG_NORMAL)("H D End %d, V D End %d",hdispend,vdispend);
|
||||
fps=clock/(vtotal*htotal);
|
||||
double linemicro=(1000000/fps);
|
||||
vga.draw.parts_total=VGA_PARTS;
|
||||
vga.draw.micro.vtotal=(Bitu)(linemicro);
|
||||
linemicro/=vtotal; //Really make it the line_micro
|
||||
vga.draw.micro.vend=(Bitu)(linemicro*vrstart);
|
||||
vga.draw.micro.parts=(Bitu)((linemicro*vdispend)/vga.draw.parts_total);
|
||||
vga.draw.micro.htotal=(Bitu)(linemicro);
|
||||
vga.draw.micro.hend=(Bitu)((linemicro/htotal)*hrstart);
|
||||
|
||||
|
||||
double correct_ratio=(100.0/525.0);
|
||||
double aspect_ratio=((double)htotal/((double)vtotal)/correct_ratio);
|
||||
|
||||
|
@ -382,80 +267,113 @@ void VGA_SetupDrawing(void) {
|
|||
Bitu scalew=1;
|
||||
Bitu scaleh=1;
|
||||
|
||||
vga.draw.lines=height=vdispend;
|
||||
width=hdispend;
|
||||
vga.draw.double_height=vga.config.vline_double;
|
||||
vga.draw.double_width=(vga.seq.clocking_mode & 0x8)>0;
|
||||
vga.draw.font_height=vga.config.vline_height+1;
|
||||
height=vdispend;
|
||||
vga.draw.double_scan=false;
|
||||
vga.draw.font_height=(vga.crtc.maximum_scan_line&0xf)+1;
|
||||
switch (vga.mode) {
|
||||
case M_VGA:
|
||||
vga.draw.double_width=true; //Hack since 256 color modes use 2 clocks for a pixel
|
||||
/* Don't know might do this different sometime, will have to do for now */
|
||||
scalew=2;
|
||||
scaleh*=vga.draw.font_height;
|
||||
if (vga.crtc.maximum_scan_line&0x80) scaleh*=2;
|
||||
vga.draw.lines_scaled=scaleh;
|
||||
height/=scaleh;
|
||||
width<<=2;
|
||||
pitch=vga.config.scan_len*8;
|
||||
vga.draw.address_add=vga.config.scan_len*2;
|
||||
vga.draw.address_line_total=1;
|
||||
VGA_DrawLine=VGA_VGA_Draw_Line;
|
||||
break;
|
||||
case M_LIN8:
|
||||
width<<=3;
|
||||
scaleh*=vga.draw.font_height;
|
||||
pitch=vga.config.scan_len*8;
|
||||
pitch=vga.config.scan_len*4;
|
||||
vga.draw.address_add=vga.config.scan_len*2;
|
||||
vga.draw.lines_scaled=scaleh;
|
||||
vga.draw.address_line_total=1;
|
||||
VGA_DrawLine=VGA_VGA_Draw_Line;
|
||||
break;
|
||||
case M_EGA16:
|
||||
width<<=3;
|
||||
pitch=vga.config.scan_len*16;
|
||||
scaleh*=vga.draw.font_height;
|
||||
if (vga.crtc.maximum_scan_line&0x80) scaleh*=2;
|
||||
vga.draw.lines_scaled=scaleh;
|
||||
height/=scaleh;
|
||||
if (vga.seq.clocking_mode & 0x8) scalew*=2;
|
||||
vga.draw.address_add=vga.config.scan_len*2;
|
||||
vga.draw.address_line_total=1;
|
||||
VGA_DrawLine=VGA_EGA_Draw_Line;
|
||||
break;
|
||||
case M_CGA4:
|
||||
case M_CGA16: //Let is use 320x200 res and double pixels myself
|
||||
vga.draw.double_width=true; //Hack if there's a runtime switch
|
||||
vga.draw.double_height=true; //Hack if there's a runtime switch
|
||||
scaleh=2;scalew=2;
|
||||
vga.draw.blocks=width;
|
||||
width<<=2;
|
||||
pitch=width;
|
||||
vga.draw.lines_scaled=1;
|
||||
vga.draw.address_line_total=2;
|
||||
vga.draw.address_add=80; //CGA doesn't have an offset reg
|
||||
VGA_DrawLine=(vga.mode == M_CGA4) ? VGA_CGA4_Draw_Line : VGA_CGA16_Draw_Line;
|
||||
break;
|
||||
case M_CGA2:
|
||||
vga.draw.double_width=false; //Hack if there's a runtime switch
|
||||
scaleh=2;
|
||||
vga.draw.address_line_total=2;
|
||||
vga.draw.blocks=width;
|
||||
width<<=3;
|
||||
pitch=width;
|
||||
vga.draw.address_line_total=2;
|
||||
vga.draw.address_add=80; //CGA doesn't have an offset reg
|
||||
vga.draw.lines_scaled=1;
|
||||
VGA_DrawLine=VGA_CGA2_Draw_Line;
|
||||
break;
|
||||
case M_HERC:
|
||||
vga.draw.double_height=false; //Hack if there's a runtime switch
|
||||
vga.draw.address_line_total=4;
|
||||
width*=9;
|
||||
vga.draw.blocks=width/8;
|
||||
vga.draw.address_add=width/8;
|
||||
vga.draw.lines_scaled=1;
|
||||
height=348;
|
||||
pitch=width;
|
||||
aspect_ratio=1.5;
|
||||
VGA_DrawLine=VGA_HERC_Draw_Line;
|
||||
break;
|
||||
case M_TANDY16:
|
||||
width<<=3;
|
||||
scaleh=2;scalew=2;
|
||||
vga.draw.blocks=width*2;
|
||||
vga.draw.address_add=160;
|
||||
vga.draw.address_line_total=4;
|
||||
vga.draw.lines_scaled=1;
|
||||
width<<=2;
|
||||
pitch=width;
|
||||
VGA_DrawLine=VGA_TANDY16_Draw_Line;
|
||||
break;
|
||||
case M_TEXT2:
|
||||
case M_TEXT16:
|
||||
aspect_ratio=1.0;
|
||||
vga.draw.font_height=vga.config.vline_height+1;
|
||||
vga.draw.address_line_total=vga.draw.font_height;
|
||||
if (vga.draw.font_height<4 && (machine<MCH_VGA || machine==MCH_AUTO)) {
|
||||
vga.draw.font_height=4;
|
||||
};
|
||||
vga.draw.cols=width;
|
||||
vga.draw.rows=(height/vga.draw.font_height);
|
||||
if (height % vga.draw.font_height) vga.draw.rows++;
|
||||
vga.draw.blocks=width;
|
||||
vga.draw.address_add=vga.config.scan_len*4;
|
||||
if (vga.seq.clocking_mode & 0x8) scalew*=2;
|
||||
if (vga.crtc.maximum_scan_line&0x80) scaleh*=2;
|
||||
vga.draw.lines_scaled=scaleh;
|
||||
height/=scaleh;
|
||||
width<<=3; /* 8 bit wide text font */
|
||||
if (width>640) width=640;
|
||||
if (height>480) height=480;
|
||||
pitch=width;
|
||||
VGA_DrawLine=VGA_TEXT_Draw_Line;
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_VGA,LOG_ERROR)("Unhandled VGA type %d while checking for resolution");
|
||||
};
|
||||
if (vga.draw.double_height) {
|
||||
scaleh*=2;
|
||||
}
|
||||
height/=scaleh;
|
||||
if (vga.draw.double_width) {
|
||||
/* Double width is dividing main clock, the width should be correct already for this */
|
||||
scalew*=2;
|
||||
}
|
||||
vga.draw.lines_total=height;
|
||||
if (( width != vga.draw.width) || (height != vga.draw.height) || (pitch != vga.draw.pitch)) {
|
||||
PIC_RemoveEvents(VGA_BlankTimer);
|
||||
PIC_RemoveEvents(VGA_VerticalTimer);
|
||||
PIC_RemoveEvents(VGA_VerticalDisplayEnd);
|
||||
vga.draw.width=width;
|
||||
vga.draw.height=height;
|
||||
vga.draw.pitch=pitch;
|
||||
|
@ -463,8 +381,7 @@ void VGA_SetupDrawing(void) {
|
|||
|
||||
LOG(LOG_VGA,LOG_NORMAL)("Width %d, Height %d, fps %f",width,height,fps);
|
||||
LOG(LOG_VGA,LOG_NORMAL)("Scalew %d, Scaleh %d aspect %f",scalew,scaleh,aspect_ratio);
|
||||
RENDER_SetSize(width,height,8,pitch,aspect_ratio,scalew,scaleh,&VGA_DrawHandler);
|
||||
vga.draw.blank=(Bitu)(1000000/fps);
|
||||
PIC_AddEvent(VGA_BlankTimer,vga.draw.blank);
|
||||
RENDER_SetSize(width,height,8,pitch,aspect_ratio,scalew,scaleh);
|
||||
PIC_AddEvent(VGA_VerticalTimer,vga.draw.micro.vtotal);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -308,6 +308,9 @@ void VGA_SetupHandlers(void) {
|
|||
}
|
||||
switch ((vga.gfx.miscellaneous >> 2) & 3) {
|
||||
case 0:
|
||||
vgapages.map_base=VGA_PAGE_A0;
|
||||
MEM_SetPageHandler(VGA_PAGE_A0,32,range_handler);
|
||||
break;
|
||||
case 1:
|
||||
vgapages.map_base=VGA_PAGE_A0;
|
||||
MEM_SetPageHandler(VGA_PAGE_A0,16,range_handler);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue