1
0
Fork 0

add basic PCJr graphics functionality based on current Tandy implementation

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2399
This commit is contained in:
Sebastian Strohhäcker 2005-12-02 20:03:51 +00:00
parent 24b045e69f
commit ed1cadea92
7 changed files with 112 additions and 13 deletions

View file

@ -196,6 +196,8 @@ typedef struct {
Bit8u gfx_control;
Bit8u palette_mask;
Bit8u border_color;
bool is_32k_mode;
bool pcjr_flipflop;
} VGA_TANDY;
typedef struct {

View file

@ -502,7 +502,8 @@ void VGA_SetupDrawing(Bitu val) {
case M_TANDY2:
aspect_ratio=1.2;
doubleheight=true;
doublewidth=(vga.tandy.mode_control & 0x10)==0;
if (machine==MCH_TANDY) doublewidth=(vga.tandy.mode_control & 0x10)==0;
else doublewidth=(vga.tandy.gfx_control & 0x8)==0x00;
vga.draw.blocks=width * (doublewidth ? 4:8);
width=vga.draw.blocks*2;
VGA_DrawLine=VGA_Draw_1BPP_Line;
@ -510,7 +511,8 @@ void VGA_SetupDrawing(Bitu val) {
case M_TANDY4:
aspect_ratio=1.2;
doubleheight=true;
doublewidth=(vga.tandy.mode_control & 0x10)==0;
if (machine==MCH_TANDY) doublewidth=(vga.tandy.mode_control & 0x10)==0;
else doublewidth=(vga.tandy.gfx_control & 0x8)==0x00;
vga.draw.blocks=width * (doublewidth ? 4:8);
width=vga.draw.blocks*2;
VGA_DrawLine=VGA_Draw_2BPP_Line;
@ -518,7 +520,8 @@ void VGA_SetupDrawing(Bitu val) {
case M_TANDY16:
aspect_ratio=1.2;
doubleheight=true;
doublewidth=(vga.tandy.mode_control & 0x10)==0;
if (machine==MCH_TANDY) doublewidth=(vga.tandy.mode_control & 0x10)==0;
else doublewidth=(vga.tandy.gfx_control & 0x8)==0x00;
vga.draw.blocks=width * (doublewidth ? 2:4);
width=vga.draw.blocks*2;
VGA_DrawLine=VGA_Draw_4BPP_Line;

View file

@ -428,7 +428,7 @@ public:
phys_page-=0xb8;
return &vga.mem.linear[(vga.tandy.mem_bank << 14)+(phys_page * 4096)];
} else {
phys_page-=0x80;
if (machine==MCH_TANDY) phys_page-=0x80;
return &vga.mem.linear[phys_page * 4096];
}
}
@ -457,10 +457,14 @@ void VGA_SetupHandlers(void) {
range_handler=&vgaph.hmap;
if (vga.herc.mode_control&0x80) goto range_b800;
else goto range_b000;
case TANDY_ARCH_CASE:
case MCH_TANDY:
range_handler=&vgaph.htandy;
MEM_SetPageHandler(0x80,32,range_handler);
goto range_b800;
case MCH_PCJR:
range_handler=&vgaph.htandy;
MEM_SetPageHandler(vga.tandy.mem_bank<<2,vga.tandy.is_32k_mode ? 0x08 : 0x04,range_handler);
goto range_b800;
}
switch (vga.mode) {
case M_ERROR:

View file

@ -30,6 +30,7 @@ Bitu read_p3d5_vga(Bitu port,Bitu iolen);
static Bitu read_p3da(Bitu port,Bitu iolen) {
vga.internal.attrindex=false;
vga.tandy.pcjr_flipflop=false;
if (vga.config.retrace) {
switch (machine) {
case MCH_HERC:

View file

@ -199,9 +199,6 @@ static void write_color_select(Bit8u val) {
/* Check for BW Mode */
if (vga.tandy.mode_control & 0x4) {
VGA_SetCGA4Table(val & 0xf,3+base,4+base,7+base);
/* old code:
if (val & 0x20) VGA_SetCGA4Table(val & 0xf,3+base,4+base,7+base);
else VGA_SetCGA4Table(val & 0xf,2+base,4+base,6+base); */
} else {
if (val & 0x20) VGA_SetCGA4Table(val & 0xf,3+base,5+base,7+base);
else VGA_SetCGA4Table(val & 0xf,2+base,4+base,6+base);
@ -242,14 +239,39 @@ static void TANDY_FindMode(void) {
}
}
static void PCJr_FindMode(void) {
if (vga.tandy.mode_control & 0x2) {
if (vga.tandy.mode_control & 0x10) {
/* bit4 of mode control 1 signals 16 colour graphics mode */
VGA_SetMode(M_TANDY16);
} else if (vga.tandy.gfx_control & 0x08) {
/* bit3 of mode control 2 signals 2 colour graphics mode */
VGA_SetMode(M_TANDY2);
} else {
/* otherwise some 4-colour graphics mode */
VGA_SetMode(M_TANDY4);
}
write_color_select(vga.tandy.color_select);
} else {
VGA_SetMode(M_TANDY_TEXT);
}
}
static void write_tandy_reg(Bit8u val) {
switch (vga.tandy.reg_index) {
case 0x0:
if (machine==MCH_PCJR) {
vga.tandy.mode_control=val;
VGA_SetBlinking(val & 0x20);
PCJr_FindMode();
} else LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index);
case 0x2: /* Border color */
vga.tandy.border_color=val;
break;
case 0x3: /* More control */
vga.tandy.gfx_control=val;
TANDY_FindMode();
if (machine==MCH_TANDY) TANDY_FindMode();
else PCJr_FindMode();
break;
/* palette colors */
case 0x10: case 0x11: case 0x12: case 0x13:
@ -311,6 +333,25 @@ static void write_tandy(Bitu port,Bitu val,Bitu iolen) {
}
}
static void write_pcjr(Bitu port,Bitu val,Bitu iolen) {
switch (port) {
case 0x3d9:
write_color_select(val);
break;
case 0x3da:
if (vga.tandy.pcjr_flipflop) write_tandy_reg(val);
else vga.tandy.reg_index=val;
vga.tandy.pcjr_flipflop=!vga.tandy.pcjr_flipflop;
break;
case 0x3df:
vga.tandy.is_32k_mode=(val & 0x80)==0x80;
vga.tandy.disp_bank=val & (vga.tandy.is_32k_mode ? 0x6 : 0x7);
vga.tandy.mem_bank=(val >> 3) & (vga.tandy.is_32k_mode ? 0x6 : 0x7);
VGA_SetupHandlers();
break;
}
}
static void write_hercules(Bitu port,Bitu val,Bitu iolen) {
switch (port) {
case 0x3b8:
@ -362,13 +403,20 @@ void VGA_SetupOther(void) {
IO_RegisterWriteHandler(0x3b8,write_hercules,IO_MB);
IO_RegisterWriteHandler(0x3bf,write_hercules,IO_MB);
}
if (IS_TANDY_ARCH) {
if (machine==MCH_TANDY) {
IO_RegisterWriteHandler(0x3d8,write_tandy,IO_MB);
IO_RegisterWriteHandler(0x3d9,write_tandy,IO_MB);
IO_RegisterWriteHandler(0x3de,write_tandy,IO_MB);
IO_RegisterWriteHandler(0x3df,write_tandy,IO_MB);
IO_RegisterWriteHandler(0x3da,write_tandy,IO_MB);
}
if (machine==MCH_PCJR) {
vga.tandy.mem_bank=7;vga.tandy.disp_bank=7;
vga.tandy.is_32k_mode=false;vga.tandy.pcjr_flipflop=false;
IO_RegisterWriteHandler(0x3d9,write_pcjr,IO_MB);
IO_RegisterWriteHandler(0x3da,write_pcjr,IO_MB);
IO_RegisterWriteHandler(0x3df,write_pcjr,IO_MB);
}
if (machine==MCH_CGA || machine==MCH_HERC || IS_TANDY_ARCH) {
Bitu base=machine==MCH_HERC ? 0x3b4 : 0x3d4;
IO_RegisterWriteHandler(base,write_crtc_index_other,IO_MB);

View file

@ -85,6 +85,11 @@ static Bitu INT10_Handler(void) {
crtcpu=(crtcpu & 0xc0) | (reg_bh & 7) | ((reg_bl & 7) << 3);
break;
}
if (machine==MCH_PCJR) {
/* always return graphics mapping, even for invalid values of AL */
reg_bh=crtcpu & 7;
reg_bl=(crtcpu >> 3) & 0x7;
}
IO_WriteB(0x3df,crtcpu);
real_writeb(BIOSMEM_SEG, BIOSMEM_CRTCPU_PAGE,crtcpu);
}
@ -114,7 +119,10 @@ static Bitu INT10_Handler(void) {
INT10_SetColorSelect(reg_bl);
break;
default:
if(machine == MCH_CGA) INT10_SetColorSelect(reg_bl);
if ((machine==MCH_CGA) || (machine==MCH_PCJR)) {
/* those BIOSes check for !=0 */
INT10_SetColorSelect(reg_bl);
}
break;
}
break;

View file

@ -300,9 +300,11 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) {
break;
case M_CGA2:
scanline=2;
break;
case M_CGA4:
if (CurMode->mode!=0xa) scanline=2;
else scanline=4;
break;
case M_TANDY16:
if (CurMode->mode!=0x9) scanline=2;
else scanline=4;
@ -319,6 +321,11 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) {
0x2a,0x2e,0x1e,0x29, //4-7
0x2a,0x2b,0x3b //8-a
};
Bit8u mode_control_list_pcjr[0xa+1]={
0x0c,0x08,0x0d,0x09, //0-3
0x0a,0x0e,0x0e,0x09, //4-7
0x1a,0x1b,0x0b //8-a
};
Bit8u mode_control,color_select;
switch (machine) {
case MCH_HERC:
@ -336,10 +343,10 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) {
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,mode_control);
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select);
break;
case TANDY_ARCH_CASE:
case MCH_TANDY:
/* Init some registers */
IO_WriteB(0x3da,0x1);IO_WriteB(0x3de,0xf); //Palette mask always 0xf
IO_WriteB(0x3da,0x2);IO_WriteB(0x3de,0x0); //block border
IO_WriteB(0x3da,0x2);IO_WriteB(0x3de,0x0); //black border
IO_WriteB(0x3da,0x3); //Tandy color overrides?
switch (CurMode->mode) {
case 0x8:
@ -362,6 +369,32 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) {
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,mode_control);
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select);
break;
case MCH_PCJR:
/* Init some registers */
IO_ReadB(0x3da);
IO_WriteB(0x3da,0x1);IO_WriteB(0x3da,0xf); //Palette mask always 0xf
IO_WriteB(0x3da,0x2);IO_WriteB(0x3da,0x0); //black border
IO_WriteB(0x3da,0x3);
if (CurMode->mode<=0x04) IO_WriteB(0x3da,0x02);
else if (CurMode->mode==0x06) IO_WriteB(0x3da,0x08);
else IO_WriteB(0x3da,0x00);
/* set CRT/Processor page register */
if (CurMode->mode<0x04) crtpage=0x3f;
else if (CurMode->mode>=0x09) crtpage=0xf6;
else crtpage=0x7f;
IO_WriteB(0x3df,crtpage);
real_writeb(BIOSMEM_SEG,BIOSMEM_CRTCPU_PAGE,crtpage);
mode_control=mode_control_list_pcjr[CurMode->mode];
IO_WriteB(0x3da,0x0);IO_WriteB(0x3da,mode_control);
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,mode_control);
if (CurMode->mode == 0x6 || CurMode->mode==0xa) color_select=0x3f;
else color_select=0x30;
IO_WriteB(0x3d9,color_select);
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select);
break;
}
FinishSetMode(clearmem);
return true;