Re-organisation of video emulation.
This commit is contained in:
parent
b9062a1d0c
commit
58085bcc87
86 changed files with 8087 additions and 7229 deletions
|
|
@ -19,6 +19,8 @@
|
|||
#include "timer.h"
|
||||
#include "x86.h"
|
||||
|
||||
int nmi = 0;
|
||||
|
||||
int nextcyc=0;
|
||||
int cycdiff;
|
||||
int is8086=0;
|
||||
|
|
|
|||
20
src/device.c
20
src/device.c
|
|
@ -57,3 +57,23 @@ void device_speed_changed()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *device_add_status_info(char *s, int max_len)
|
||||
{
|
||||
int c;
|
||||
|
||||
s[0] = 0;
|
||||
|
||||
for (c = 0; c < 256; c++)
|
||||
{
|
||||
if (devices[c] != NULL)
|
||||
{
|
||||
if (devices[c]->add_status_info != NULL)
|
||||
{
|
||||
int len = devices[c]->add_status_info(s, max_len, device_priv[c]);
|
||||
s += len;
|
||||
max_len -= len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@ typedef struct device_t
|
|||
{
|
||||
char name[50];
|
||||
void *(*init)();
|
||||
void (*close)(void *priv);
|
||||
void (*speed_changed)(void *priv);
|
||||
void (*close)(void *p);
|
||||
void (*speed_changed)(void *p);
|
||||
int (*add_status_info)(char *s, int max_len, void *p);
|
||||
} device_t;
|
||||
|
||||
void device_init();
|
||||
void device_add(device_t *d);
|
||||
void device_close_all();
|
||||
void device_speed_changed();
|
||||
char *device_add_status_info(char *s, int max_len);
|
||||
|
|
|
|||
11
src/dma.c
11
src/dma.c
|
|
@ -213,7 +213,7 @@ void dma_page_write(uint16_t addr, uint8_t val, void *priv)
|
|||
{
|
||||
/* if (!(addr&0xF))
|
||||
{*/
|
||||
pclog("Write page %03X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||
// pclog("Write page %03X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||
// if (val==0x29 && pc==0xD25) output=1;
|
||||
// }
|
||||
dmapages[addr&0xF]=val;
|
||||
|
|
@ -258,12 +258,12 @@ uint8_t _dma_read(uint32_t addr)
|
|||
{
|
||||
switch (addr&0xFFFF8000)
|
||||
{
|
||||
case 0xA0000: case 0xA8000:
|
||||
/* case 0xA0000: case 0xA8000:
|
||||
return video_read_a000(addr, NULL);
|
||||
case 0xB0000:
|
||||
return video_read_b000(addr, NULL);
|
||||
case 0xB8000:
|
||||
return video_read_b800(addr, NULL);
|
||||
return video_read_b800(addr, NULL);*/
|
||||
}
|
||||
if (isram[addr>>16]) return ram[addr];
|
||||
return 0xff;
|
||||
|
|
@ -271,9 +271,10 @@ uint8_t _dma_read(uint32_t addr)
|
|||
|
||||
void _dma_write(uint32_t addr, uint8_t val)
|
||||
{
|
||||
pclog("_dma_write %08X %02X\n", addr, val);
|
||||
switch (addr&0xFFFF8000)
|
||||
{
|
||||
case 0xA0000: case 0xA8000:
|
||||
/* case 0xA0000: case 0xA8000:
|
||||
video_write_a000(addr,val, NULL);
|
||||
return;
|
||||
case 0xB0000:
|
||||
|
|
@ -284,7 +285,7 @@ void _dma_write(uint32_t addr, uint8_t val)
|
|||
return;
|
||||
case 0xC0000: case 0xC8000: case 0xD0000: case 0xD8000:
|
||||
case 0xE0000: case 0xE8000: case 0xF0000: case 0xF8000:
|
||||
return;
|
||||
return;*/
|
||||
}
|
||||
if (isram[addr >> 16])
|
||||
ram[addr] = val;
|
||||
|
|
|
|||
269
src/ega.c
269
src/ega.c
|
|
@ -1,217 +1,10 @@
|
|||
#include "ibm.h"
|
||||
#include "video.h"
|
||||
|
||||
void doblit();
|
||||
|
||||
int egareads=0,egawrites=0;
|
||||
int framecount=0;
|
||||
int changeframecount=2;
|
||||
|
||||
void redotextlookup();
|
||||
int output;
|
||||
int svgaon=0;
|
||||
uint32_t svgarbank,svgawbank;
|
||||
uint8_t svgaseg,svgaseg2;
|
||||
uint8_t svga3d8;
|
||||
|
||||
uint8_t oldvram=0;
|
||||
int frames;
|
||||
int hsync;
|
||||
uint8_t cgastat;
|
||||
|
||||
uint8_t gdcreg[16];
|
||||
int gdcaddr;
|
||||
uint8_t attrregs[32];
|
||||
int attraddr,attrff=0;
|
||||
uint8_t ega3c2;
|
||||
|
||||
uint8_t rotatevga[8][256];
|
||||
uint8_t writemask,charset;
|
||||
int writemode,readmode,readplane,chain4;
|
||||
uint8_t colourcompare,colournocare;
|
||||
uint8_t la,lb,lc,ld;
|
||||
|
||||
uint8_t *vram;
|
||||
|
||||
int egares;
|
||||
|
||||
uint8_t seqregs[64];
|
||||
int seqaddr;
|
||||
|
||||
uint8_t oak_regs[32];
|
||||
int oak_index;
|
||||
|
||||
|
||||
extern int egaswitchread,egaswitches;
|
||||
/*For VGA non-interlace colour, ID bits should be 1 1 0 or 6*/
|
||||
int vres=0;
|
||||
|
||||
PALETTE vgapal;
|
||||
uint32_t *pallook,pallook16[256],pallook64[256],pallook256[256];
|
||||
int dacread,dacwrite,dacpos=0;
|
||||
int palchange=1;
|
||||
|
||||
int fullchange;
|
||||
|
||||
int dispontime,dispofftime;
|
||||
double disptime;
|
||||
|
||||
int ega_vtotal,ega_dispend,ega_vsyncstart,ega_split,ega_hdisp,ega_rowoffset;
|
||||
int vidclock;
|
||||
float cpuclock;
|
||||
|
||||
int bpp;
|
||||
|
||||
uint32_t vrammask;
|
||||
|
||||
uint8_t changedvram[(8192*1024)/1024];
|
||||
|
||||
|
||||
int charseta,charsetb;
|
||||
|
||||
int egapal[16];
|
||||
|
||||
int displine;
|
||||
|
||||
int rowdbl=0;
|
||||
int scrblank=0;
|
||||
|
||||
|
||||
|
||||
|
||||
uint8_t edatlookup[4][4];
|
||||
|
||||
uint32_t textlookup[256][2][16][16];
|
||||
|
||||
/*void redotextlookup()
|
||||
{
|
||||
int c,d,e;
|
||||
uint32_t temp;
|
||||
int coffset=(VGA)?0:64;
|
||||
for (c=0;c<256;c++)
|
||||
{
|
||||
for (d=0;d<16;d++)
|
||||
{
|
||||
// printf("ATTR %i=%02X+%02X\n",d,attrregs[d],coffset);
|
||||
for (e=0;e<16;e++)
|
||||
{
|
||||
temp=0;
|
||||
if (c&0x80) temp|=(attrregs[d]+coffset);
|
||||
else temp|=(attrregs[e]+coffset);
|
||||
if (c&0x40) temp|=(attrregs[d]+coffset)<<8;
|
||||
else temp|=(attrregs[e]+coffset)<<8;
|
||||
if (c&0x20) temp|=(attrregs[d]+coffset)<<16;
|
||||
else temp|=(attrregs[e]+coffset)<<16;
|
||||
if (c&0x10) temp|=(attrregs[d]+coffset)<<24;
|
||||
else temp|=(attrregs[e]+coffset)<<24;
|
||||
// if (c==0x5) printf("%08X %i %i %02X %02X\n",temp,d,e,attrregs[d],attrregs[e]);
|
||||
textlookup[c][0][d][e]=temp;
|
||||
temp=0;
|
||||
if (c&0x08) temp|=(attrregs[d]+coffset);
|
||||
else temp|=(attrregs[e]+coffset);
|
||||
if (c&0x04) temp|=(attrregs[d]+coffset)<<8;
|
||||
else temp|=(attrregs[e]+coffset)<<8;
|
||||
if (c&0x02) temp|=(attrregs[d]+coffset)<<16;
|
||||
else temp|=(attrregs[e]+coffset)<<16;
|
||||
if (c&0x01) temp|=(attrregs[d]+coffset)<<24;
|
||||
else temp|=(attrregs[e]+coffset)<<24;
|
||||
textlookup[c][1][d][e]=temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
void initega()
|
||||
{
|
||||
int c,d,e;
|
||||
bpp=8;
|
||||
for (c=0;c<256;c++)
|
||||
{
|
||||
e=c;
|
||||
for (d=0;d<8;d++)
|
||||
{
|
||||
rotatevga[d][c]=e;
|
||||
e=(e>>1)|((e&1)?0x80:0);
|
||||
}
|
||||
}
|
||||
crtc[0xC]=crtc[0xD]=0;
|
||||
for (c=0;c<4;c++)
|
||||
{
|
||||
for (d=0;d<4;d++)
|
||||
{
|
||||
edatlookup[c][d]=0;
|
||||
if (c&1) edatlookup[c][d]|=1;
|
||||
if (d&1) edatlookup[c][d]|=2;
|
||||
if (c&2) edatlookup[c][d]|=0x10;
|
||||
if (d&2) edatlookup[c][d]|=0x20;
|
||||
// printf("Edat %i,%i now %02X\n",c,d,edatlookup[c][d]);
|
||||
}
|
||||
}
|
||||
/*redotextlookup();*/
|
||||
for (c=0;c<256;c++)
|
||||
{
|
||||
pallook64[c]=makecol32(((c>>2)&1)*0xAA,((c>>1)&1)*0xAA,(c&1)*0xAA);
|
||||
pallook64[c]+=makecol32(((c>>5)&1)*0x55,((c>>4)&1)*0x55,((c>>3)&1)*0x55);
|
||||
pallook16[c]=makecol32(((c>>2)&1)*0xAA,((c>>1)&1)*0xAA,(c&1)*0xAA);
|
||||
pallook16[c]+=makecol32(((c>>4)&1)*0x55,((c>>4)&1)*0x55,((c>>4)&1)*0x55);
|
||||
if ((c&0x17)==6) pallook16[c]=makecol32(0xAA,0x55,0);
|
||||
// printf("%03i %08X\n",c,pallook[c]);
|
||||
}
|
||||
pallook=pallook16;
|
||||
seqregs[0xC]=0x20;
|
||||
vrammask=(ET4000)?0xFFFFF:0x1FFFFF;
|
||||
// writeega_func=writeega;
|
||||
gdcreg[6]=8;
|
||||
gdcreg[8]=0xFF;
|
||||
writemode=0;
|
||||
chain4=0;
|
||||
writemask=3;
|
||||
|
||||
et4k_b8000=0;
|
||||
|
||||
svgarbank=svgawbank=0;
|
||||
}
|
||||
uint32_t egabase,egaoffset;
|
||||
|
||||
void cacheega()
|
||||
{
|
||||
egabase=(crtc[0xC]<<8)|crtc[0xD];
|
||||
if (ET4000 || ET4000W32 || TRIDENT)
|
||||
egabase|=((crtc[0x33]&3)<<18);
|
||||
// printf("EGABASE %05X\n",egabase);
|
||||
// egaoffset=8-((attrregs[0x13])&7);
|
||||
// printf("Cache base!\n");
|
||||
}
|
||||
void cacheega2()
|
||||
{
|
||||
// egabase=(crtc[0xC]<<8)|crtc[0xD];
|
||||
if (gdcreg[5]&0x40) egaoffset=8-(((attrregs[0x13])&7)>>1);
|
||||
else egaoffset=8-((attrregs[0x13])&7);
|
||||
// printf("Cache offset!\n");
|
||||
}
|
||||
|
||||
int olddisplines,oldxsize;
|
||||
|
||||
int oldreadflash;
|
||||
int oldegaaddr,oldegasplit;
|
||||
|
||||
int vc,sc;
|
||||
int egadispon=0;
|
||||
int linepos;
|
||||
int displine;
|
||||
uint32_t ma,maback,ca;
|
||||
int firstline,lastline;
|
||||
int xsize,ysize;
|
||||
int scrollcache;
|
||||
int con,cursoron,cgablink;
|
||||
|
||||
BITMAP *buffer,*vbuf,*buffer32;
|
||||
|
||||
int linecountff=0;
|
||||
|
||||
void dumpegaregs()
|
||||
{
|
||||
int c;
|
||||
/* int c;
|
||||
printf("CRTC :");
|
||||
for (c=0;c<0x20;c++) printf(" %02X",crtc[c]);
|
||||
printf("\n");
|
||||
|
|
@ -234,64 +27,6 @@ void dumpegaregs()
|
|||
for (c=0;c<0x10;c++) printf(" %02X",gdcreg[c]);
|
||||
printf("\n");
|
||||
// printf("OLD CTRL2 = %02X NEW CTRL2 = %02X DAC = %02X 3C2 = %02X\n",tridentoldctrl2,tridentnewctrl2,tridentdac,ega3c2);
|
||||
printf("BPP = %02X\n",bpp);
|
||||
printf("BPP = %02X\n",bpp);*/
|
||||
}
|
||||
|
||||
int oddeven;
|
||||
|
||||
int wx,wy;
|
||||
int vslines;
|
||||
|
||||
int frames = 0;
|
||||
|
||||
void doblit()
|
||||
{
|
||||
startblit();
|
||||
if ((wx!=xsize || wy!=ysize) && !vid_resize)
|
||||
{
|
||||
xsize=wx;
|
||||
ysize=wy+1;
|
||||
if (xsize<64) xsize=656;
|
||||
if (ysize<32) ysize=200;
|
||||
if (vres) updatewindowsize(xsize,ysize<<1);
|
||||
else updatewindowsize(xsize,ysize);
|
||||
}
|
||||
video_blit_memtoscreen(32, 0, 0, ysize, xsize, ysize);
|
||||
if (readflash) rectfill(screen,winsizex-40,8,winsizex-8,14,0xFFFFFFFF);
|
||||
endblit();
|
||||
frames++;
|
||||
}
|
||||
|
||||
int ega_getdepth()
|
||||
{
|
||||
if (!(gdcreg[6]&1)) return 0;
|
||||
switch (gdcreg[5]&0x60)
|
||||
{
|
||||
case 0x00:
|
||||
return 4;
|
||||
case 0x20:
|
||||
return 2;
|
||||
case 0x40: case 0x60:
|
||||
if (TRIDENT || ET4000W32) return bpp;
|
||||
return 8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ega_getx()
|
||||
{
|
||||
int x;
|
||||
if (!(gdcreg[6]&1)) return (crtc[1]+1);
|
||||
if ((attrregs[0x10]&0x40) && !(tridentoldctrl2&0x10)) x=(crtc[1]+1)*4;
|
||||
else x=(crtc[1]+1)*8;
|
||||
if (TRIDENT && (bpp==15 || bpp==16)) x>>=1;
|
||||
if (TRIDENT && bpp==24) x=(x<<1)/3;
|
||||
return x;
|
||||
}
|
||||
|
||||
int ega_gety()
|
||||
{
|
||||
if (crtc[0x1E]&4) return (ega_dispend/((crtc[9]&31)+1))<<1;
|
||||
if (crtc[9]&0x80) return (ega_dispend/((crtc[9]&31)+1))>>1;
|
||||
return ega_dispend/((crtc[9]&31)+1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -458,3 +458,6 @@ extern int times;
|
|||
extern float isa_timing, bus_timing;
|
||||
|
||||
extern int frame;
|
||||
|
||||
|
||||
uint8_t *vramp;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "mem.h"
|
||||
#include "pic.h"
|
||||
#include "sound.h"
|
||||
#include "timer.h"
|
||||
|
||||
#include "keyboard.h"
|
||||
#include "keyboard_amstrad.h"
|
||||
|
|
@ -31,6 +32,7 @@ static uint8_t amstrad_systemstat_1, amstrad_systemstat_2;
|
|||
|
||||
void keyboard_amstrad_poll()
|
||||
{
|
||||
keybsenddelay += (1000 * TIMER_USEC);
|
||||
if (keyboard_amstrad.wantirq)
|
||||
{
|
||||
keyboard_amstrad.wantirq = 0;
|
||||
|
|
@ -166,4 +168,6 @@ void keyboard_amstrad_init()
|
|||
keyboard_amstrad_reset();
|
||||
keyboard_send = keyboard_amstrad_adddata;
|
||||
keyboard_poll = keyboard_amstrad_poll;
|
||||
|
||||
timer_add(keyboard_amstrad_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "mem.h"
|
||||
#include "mouse.h"
|
||||
#include "pic.h"
|
||||
#include "timer.h"
|
||||
|
||||
#include "keyboard.h"
|
||||
#include "keyboard_olim24.h"
|
||||
|
|
@ -38,6 +39,7 @@ static uint8_t mouse_scancodes[7];
|
|||
|
||||
void keyboard_olim24_poll()
|
||||
{
|
||||
keybsenddelay += (1000 * TIMER_USEC);
|
||||
//pclog("poll %i\n", keyboard_olim24.wantirq);
|
||||
if (keyboard_olim24.wantirq)
|
||||
{
|
||||
|
|
@ -283,4 +285,6 @@ void keyboard_olim24_init()
|
|||
keyboard_send = keyboard_olim24_adddata;
|
||||
keyboard_poll = keyboard_olim24_poll;
|
||||
mouse_poll = mouse_olim24_poll;
|
||||
|
||||
timer_add(keyboard_olim24_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL);
|
||||
}
|
||||
|
|
|
|||
9
src/pc.c
9
src/pc.c
|
|
@ -179,8 +179,6 @@ void pc_reset()
|
|||
// sb_reset();
|
||||
|
||||
ali1429_reset();
|
||||
et4000w32_reset();
|
||||
|
||||
// video_init();
|
||||
}
|
||||
|
||||
|
|
@ -209,8 +207,8 @@ void initpc()
|
|||
|
||||
initvideo();
|
||||
mem_init();
|
||||
loadbios();
|
||||
mem_load_video_bios();
|
||||
loadbios();
|
||||
|
||||
loaddisc(0,discfns[0]);
|
||||
loaddisc(1,discfns[1]);
|
||||
|
|
@ -221,10 +219,8 @@ void initpc()
|
|||
|
||||
//loadfont();
|
||||
loadnvr();
|
||||
resetvideo();
|
||||
sound_init();
|
||||
inithdc();
|
||||
initega();
|
||||
resetide();
|
||||
ioctl_open(cdrom_drive);
|
||||
model_init();
|
||||
|
|
@ -244,7 +240,6 @@ void initpc()
|
|||
/* if (romset==ROM_AMI386 || romset==ROM_AMI486) */fullspeed();
|
||||
mem_updatecache();
|
||||
ali1429_reset();
|
||||
et4000w32_reset();
|
||||
// CPUID=(is486 && (cpuspeed==7 || cpuspeed>=9));
|
||||
// pclog("Init - CPUID %i %i\n",CPUID,cpuspeed);
|
||||
shadowbios=0;
|
||||
|
|
@ -330,6 +325,7 @@ void runpc()
|
|||
framecount++;
|
||||
if (framecountx>=100)
|
||||
{
|
||||
pclog("onesec\n");
|
||||
framecountx=0;
|
||||
mips=(float)insc/1000000.0f;
|
||||
insc=0;
|
||||
|
|
@ -404,7 +400,6 @@ void closepc()
|
|||
{
|
||||
atapi->exit();
|
||||
// ioctl_close();
|
||||
dumpegaregs();
|
||||
dumppic();
|
||||
// output=7;
|
||||
// setpitclock(clocks[0][0][0]);
|
||||
|
|
|
|||
11
src/pc.rc
11
src/pc.rc
|
|
@ -50,8 +50,9 @@ BEGIN
|
|||
COMBOBOX IDC_COMBOSPD,62,116,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_COMBOSND,62,136,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_COMBOMEM,62,152,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||
CONTROL "Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,172,118,10
|
||||
CONTROL "Composite CGA",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,188,118,10
|
||||
CONTROL "CMS / Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,172,118,10
|
||||
CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,188,118,10
|
||||
CONTROL "Composite CGA",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,204,118,10
|
||||
LTEXT "Machine :",IDC_STATIC,15,16,40,10
|
||||
LTEXT "Video :",IDC_STATIC,15,36,34,10
|
||||
LTEXT "CPU type :",IDC_STATIC,15,56,34,10
|
||||
|
|
@ -150,9 +151,5 @@ BEGIN
|
|||
LTEXT "6",IDC_STEXT6,16,76,180,10
|
||||
LTEXT "7",IDC_STEXT7,16,88,180,10
|
||||
LTEXT "8",IDC_STEXT8,16,100,180,10
|
||||
LTEXT "9",IDC_STEXT9,16,112,180,10
|
||||
LTEXT "10",IDC_STEXT10,16,124,180,10
|
||||
LTEXT "11",IDC_STEXT11,16,136,180,10
|
||||
LTEXT "12",IDC_STEXT12,16,148,180,10
|
||||
LTEXT "13",IDC_STEXT13,16,160,180,10
|
||||
LTEXT "9",IDC_STEXT_DEVICE,16,112,180,1000
|
||||
END
|
||||
|
|
|
|||
|
|
@ -31,14 +31,15 @@ void setpitclock(float clock)
|
|||
cpuclock=clock;
|
||||
PITCONST=clock/1193182.0;
|
||||
CGACONST=(clock/(19687500.0/11.0));
|
||||
MDACONST=(clock/1813000.0);
|
||||
MDACONST=(clock/2032125.0);
|
||||
VGACONST1=(clock/25175000.0);
|
||||
VGACONST2=(clock/28322000.0);
|
||||
isa_timing = clock/8000000.0;
|
||||
bus_timing = clock/(double)cpu_busspeed;
|
||||
video_updatetiming();
|
||||
// pclog("egacycles %i egacycles2 %i temp %f clock %f\n",egacycles,egacycles2,temp,clock);
|
||||
video_recalctimings();
|
||||
/* if (video_recalctimings)
|
||||
video_recalctimings();*/
|
||||
RTCCONST=clock/32768.0;
|
||||
TIMER_USEC = (int)((clock / 1000000.0f) * (float)(1 << TIMER_SHIFT));
|
||||
device_speed_changed();
|
||||
|
|
|
|||
|
|
@ -56,8 +56,4 @@
|
|||
#define IDC_STEXT6 1105
|
||||
#define IDC_STEXT7 1106
|
||||
#define IDC_STEXT8 1107
|
||||
#define IDC_STEXT9 1108
|
||||
#define IDC_STEXT10 1109
|
||||
#define IDC_STEXT11 1110
|
||||
#define IDC_STEXT12 1111
|
||||
#define IDC_STEXT13 1112
|
||||
#define IDC_STEXT_DEVICE 1108
|
||||
|
|
|
|||
|
|
@ -58,5 +58,6 @@ device_t adlib_device =
|
|||
"AdLib",
|
||||
adlib_init,
|
||||
adlib_close,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
|
|
|||
|
|
@ -593,5 +593,6 @@ device_t adgold_device =
|
|||
"AdLib Gold",
|
||||
adgold_init,
|
||||
adgold_close,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
|
|
|||
|
|
@ -175,5 +175,6 @@ device_t cms_device =
|
|||
"Creative Music System / Game Blaster",
|
||||
cms_init,
|
||||
cms_close,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1103,5 +1103,6 @@ device_t gus_device =
|
|||
"Gravis UltraSound",
|
||||
gus_init,
|
||||
gus_close,
|
||||
gus_speed_changed
|
||||
gus_speed_changed,
|
||||
NULL
|
||||
};
|
||||
|
|
|
|||
|
|
@ -749,5 +749,6 @@ device_t pas16_device =
|
|||
"Pro Audio Spectrum 16",
|
||||
pas16_init,
|
||||
pas16_close,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
|
|
|||
|
|
@ -376,40 +376,46 @@ device_t sb_1_device =
|
|||
"Sound Blaster v1.0",
|
||||
sb_1_init,
|
||||
sb_close,
|
||||
sb_speed_changed
|
||||
sb_speed_changed,
|
||||
NULL
|
||||
};
|
||||
device_t sb_15_device =
|
||||
{
|
||||
"Sound Blaster v1.5",
|
||||
sb_15_init,
|
||||
sb_close,
|
||||
sb_speed_changed
|
||||
sb_speed_changed,
|
||||
NULL
|
||||
};
|
||||
device_t sb_2_device =
|
||||
{
|
||||
"Sound Blaster v2.0",
|
||||
sb_2_init,
|
||||
sb_close,
|
||||
sb_speed_changed
|
||||
sb_speed_changed,
|
||||
NULL
|
||||
};
|
||||
device_t sb_pro_v1_device =
|
||||
{
|
||||
"Sound Blaster Pro v1",
|
||||
sb_pro_v1_init,
|
||||
sb_close,
|
||||
sb_speed_changed
|
||||
sb_speed_changed,
|
||||
NULL
|
||||
};
|
||||
device_t sb_pro_v2_device =
|
||||
{
|
||||
"Sound Blaster Pro v2",
|
||||
sb_pro_v2_init,
|
||||
sb_close,
|
||||
sb_speed_changed
|
||||
sb_speed_changed,
|
||||
NULL
|
||||
};
|
||||
device_t sb_16_device =
|
||||
{
|
||||
"Sound Blaster 16",
|
||||
sb_16_init,
|
||||
sb_close,
|
||||
sb_speed_changed
|
||||
sb_speed_changed,
|
||||
NULL
|
||||
};
|
||||
|
|
|
|||
|
|
@ -272,6 +272,12 @@ void sb_exec_command(sb_dsp_t *dsp)
|
|||
pclog("sb_exec_command : SB command %02X\n", dsp->sb_command);
|
||||
switch (dsp->sb_command)
|
||||
{
|
||||
case 0x01: /*???*/
|
||||
sb_add_data(dsp, 0);
|
||||
break;
|
||||
case 0x03: /*ASP status*/
|
||||
sb_add_data(dsp, 0);
|
||||
break;
|
||||
case 0x10: /*8-bit direct mode*/
|
||||
dsp->sbdat = dsp->sbdatl = dsp->sbdatr = (dsp->sb_data[0] ^ 0x80) << 8;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -194,5 +194,6 @@ device_t sn76489_device =
|
|||
"TI SN74689 PSG",
|
||||
sn76489_init,
|
||||
sn76489_close,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
|
|
|||
|
|
@ -303,5 +303,6 @@ device_t wss_device =
|
|||
"Windows Sound System",
|
||||
wss_init,
|
||||
wss_close,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,142 +1,163 @@
|
|||
/*ATI 18800 emulation (VGA Edge-16)*/
|
||||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "io.h"
|
||||
#include "video.h"
|
||||
#include "vid_ati18800.h"
|
||||
#include "vid_ati_eeprom.h"
|
||||
#include "vid_svga.h"
|
||||
|
||||
static uint8_t ati_regs[256];
|
||||
static int ati_index;
|
||||
|
||||
void ati18800_out(uint16_t addr, uint8_t val, void *priv)
|
||||
typedef struct ati18800_t
|
||||
{
|
||||
svga_t svga;
|
||||
ati_eeprom_t eeprom;
|
||||
|
||||
uint8_t regs[256];
|
||||
int index;
|
||||
} ati18800_t;
|
||||
|
||||
void ati18800_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
ati18800_t *ati18800 = (ati18800_t *)p;
|
||||
svga_t *svga = &ati18800->svga;
|
||||
uint8_t old;
|
||||
|
||||
pclog("ati18800_out : %04X %02X %04X:%04X\n", addr, val, CS,pc);
|
||||
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x1ce:
|
||||
ati_index = val;
|
||||
ati18800->index = val;
|
||||
break;
|
||||
case 0x1cf:
|
||||
ati_regs[ati_index] = val;
|
||||
switch (ati_index)
|
||||
ati18800->regs[ati18800->index] = val;
|
||||
switch (ati18800->index)
|
||||
{
|
||||
case 0xb2:
|
||||
case 0xbe:
|
||||
if (ati_regs[0xbe] & 8) /*Read/write bank mode*/
|
||||
if (ati18800->regs[0xbe] & 8) /*Read/write bank mode*/
|
||||
{
|
||||
svgarbank = ((ati_regs[0xb2] >> 5) & 7) * 0x10000;
|
||||
svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000;
|
||||
svga->read_bank = ((ati18800->regs[0xb2] >> 5) & 7) * 0x10000;
|
||||
svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000;
|
||||
}
|
||||
else /*Single bank mode*/
|
||||
svgarbank = svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000;
|
||||
svga->read_bank = svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000;
|
||||
break;
|
||||
case 0xb3:
|
||||
ati_eeprom_write(val & 8, val & 2, val & 1);
|
||||
ati_eeprom_write(&ati18800->eeprom, val & 8, val & 2, val & 1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3D4:
|
||||
crtcreg = val & 0x3f;
|
||||
svga->crtcreg = val & 0x3f;
|
||||
return;
|
||||
case 0x3D5:
|
||||
if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
|
||||
old=crtc[crtcreg];
|
||||
crtc[crtcreg]=val;
|
||||
if (old!=val)
|
||||
if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
if (old != val)
|
||||
{
|
||||
if (crtcreg<0xE || crtcreg>0x10)
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
|
||||
{
|
||||
fullchange=changeframecount;
|
||||
svga_recalctimings();
|
||||
fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
svga_out(addr, val, NULL);
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
uint8_t ati18800_in(uint16_t addr, void *priv)
|
||||
uint8_t ati18800_in(uint16_t addr, void *p)
|
||||
{
|
||||
ati18800_t *ati18800 = (ati18800_t *)p;
|
||||
svga_t *svga = &ati18800->svga;
|
||||
uint8_t temp;
|
||||
|
||||
if (addr != 0x3da) pclog("ati18800_in : %04X ", addr);
|
||||
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x1ce:
|
||||
temp = ati_index;
|
||||
temp = ati18800->index;
|
||||
break;
|
||||
case 0x1cf:
|
||||
switch (ati_index)
|
||||
switch (ati18800->index)
|
||||
{
|
||||
case 0xb7:
|
||||
temp = ati_regs[ati_index] & ~8;
|
||||
if (ati_eeprom_read())
|
||||
temp = ati18800->regs[ati18800->index] & ~8;
|
||||
if (ati_eeprom_read(&ati18800->eeprom))
|
||||
temp |= 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
temp = ati_regs[ati_index];
|
||||
temp = ati18800->regs[ati18800->index];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3D4:
|
||||
temp = crtcreg;
|
||||
temp = svga->crtcreg;
|
||||
break;
|
||||
case 0x3D5:
|
||||
temp = crtc[crtcreg];
|
||||
temp = svga->crtc[svga->crtcreg];
|
||||
break;
|
||||
default:
|
||||
temp = svga_in(addr, NULL);
|
||||
temp = svga_in(addr, svga);
|
||||
break;
|
||||
}
|
||||
if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc);
|
||||
return temp;
|
||||
}
|
||||
|
||||
int ati18800_init()
|
||||
void *ati18800_init()
|
||||
{
|
||||
svga_recalctimings_ex = NULL;
|
||||
svga_vram_limit = 1 << 19; /*512kb*/
|
||||
vrammask = 0x7ffff;
|
||||
svgawbank = svgarbank = 0;
|
||||
bpp = 8;
|
||||
svga_miscout = 1;
|
||||
ati18800_t *ati18800 = malloc(sizeof(ati18800_t));
|
||||
memset(ati18800, 0, sizeof(ati18800_t));
|
||||
|
||||
io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, NULL);
|
||||
|
||||
ati_eeprom_load("ati18800.nvr", 0);
|
||||
|
||||
return svga_init();
|
||||
svga_init(&ati18800->svga, ati18800, 1 << 19, /*512kb*/
|
||||
NULL,
|
||||
ati18800_in, ati18800_out,
|
||||
NULL);
|
||||
|
||||
io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800);
|
||||
io_sethandler(0x03c0, 0x0020, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800);
|
||||
|
||||
ati18800->svga.miscout = 1;
|
||||
|
||||
ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0);
|
||||
|
||||
return ati18800;
|
||||
}
|
||||
|
||||
GFXCARD vid_ati18800 =
|
||||
void ati18800_close(void *p)
|
||||
{
|
||||
ati18800_t *ati18800 = (ati18800_t *)p;
|
||||
|
||||
svga_close(&ati18800->svga);
|
||||
|
||||
free(ati18800);
|
||||
}
|
||||
|
||||
void ati18800_speed_changed(void *p)
|
||||
{
|
||||
ati18800_t *ati18800 = (ati18800_t *)p;
|
||||
|
||||
svga_recalctimings(&ati18800->svga);
|
||||
}
|
||||
|
||||
device_t ati18800_device =
|
||||
{
|
||||
"ATI-18800",
|
||||
ati18800_init,
|
||||
/*IO at 3Cx/3Dx*/
|
||||
ati18800_out,
|
||||
ati18800_in,
|
||||
/*IO at 3Ax/3Bx*/
|
||||
video_out_null,
|
||||
video_in_null,
|
||||
|
||||
svga_poll,
|
||||
svga_recalctimings,
|
||||
|
||||
svga_write,
|
||||
video_write_null,
|
||||
video_write_null,
|
||||
|
||||
svga_read,
|
||||
video_read_null,
|
||||
video_read_null
|
||||
ati18800_close,
|
||||
ati18800_speed_changed,
|
||||
svga_add_status_info
|
||||
};
|
||||
|
||||
|
|
|
|||
1
src/vid_ati18800.h
Normal file
1
src/vid_ati18800.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
extern device_t ati18800_device;
|
||||
|
|
@ -1,161 +1,183 @@
|
|||
/*ATI 28800 emulation (VGA Charger)*/
|
||||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "io.h"
|
||||
#include "video.h"
|
||||
#include "vid_ati28800.h"
|
||||
#include "vid_ati_eeprom.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_svga_render.h"
|
||||
|
||||
static uint8_t ati_regs[256];
|
||||
static int ati_index;
|
||||
|
||||
void ati28800_out(uint16_t addr, uint8_t val, void *priv)
|
||||
typedef struct ati28800_t
|
||||
{
|
||||
svga_t svga;
|
||||
ati_eeprom_t eeprom;
|
||||
|
||||
uint8_t regs[256];
|
||||
int index;
|
||||
} ati28800_t;
|
||||
|
||||
void ati28800_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
ati28800_t *ati28800 = (ati28800_t *)p;
|
||||
svga_t *svga = &ati28800->svga;
|
||||
uint8_t old;
|
||||
|
||||
pclog("ati28800_out : %04X %02X %04X:%04X\n", addr, val, CS,pc);
|
||||
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x1ce:
|
||||
ati_index = val;
|
||||
ati28800->index = val;
|
||||
break;
|
||||
case 0x1cf:
|
||||
ati_regs[ati_index] = val;
|
||||
switch (ati_index)
|
||||
ati28800->regs[ati28800->index] = val;
|
||||
switch (ati28800->index)
|
||||
{
|
||||
case 0xb2:
|
||||
case 0xbe:
|
||||
if (ati_regs[0xbe] & 8) /*Read/write bank mode*/
|
||||
if (ati28800->regs[0xbe] & 8) /*Read/write bank mode*/
|
||||
{
|
||||
svgarbank = ((ati_regs[0xb2] >> 5) & 7) * 0x10000;
|
||||
svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000;
|
||||
svga->read_bank = ((ati28800->regs[0xb2] >> 5) & 7) * 0x10000;
|
||||
svga->write_bank = ((ati28800->regs[0xb2] >> 1) & 7) * 0x10000;
|
||||
}
|
||||
else /*Single bank mode*/
|
||||
svgarbank = svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000;
|
||||
svga->read_bank = svga->write_bank = ((ati28800->regs[0xb2] >> 1) & 7) * 0x10000;
|
||||
break;
|
||||
case 0xb3:
|
||||
ati_eeprom_write(val & 8, val & 2, val & 1);
|
||||
ati_eeprom_write(&ati28800->eeprom, val & 8, val & 2, val & 1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3D4:
|
||||
crtcreg = val & 0x3f;
|
||||
svga->crtcreg = val & 0x3f;
|
||||
return;
|
||||
case 0x3D5:
|
||||
if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
|
||||
old=crtc[crtcreg];
|
||||
crtc[crtcreg]=val;
|
||||
if (old!=val)
|
||||
if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
if (old != val)
|
||||
{
|
||||
if (crtcreg<0xE || crtcreg>0x10)
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
|
||||
{
|
||||
fullchange=changeframecount;
|
||||
svga_recalctimings();
|
||||
fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
svga_out(addr, val, NULL);
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
uint8_t ati28800_in(uint16_t addr, void *priv)
|
||||
uint8_t ati28800_in(uint16_t addr, void *p)
|
||||
{
|
||||
ati28800_t *ati28800 = (ati28800_t *)p;
|
||||
svga_t *svga = &ati28800->svga;
|
||||
uint8_t temp;
|
||||
|
||||
if (addr != 0x3da) pclog("ati28800_in : %04X ", addr);
|
||||
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x1ce:
|
||||
temp = ati_index;
|
||||
temp = ati28800->index;
|
||||
break;
|
||||
case 0x1cf:
|
||||
switch (ati_index)
|
||||
switch (ati28800->index)
|
||||
{
|
||||
case 0xb7:
|
||||
temp = ati_regs[ati_index] & ~8;
|
||||
if (ati_eeprom_read())
|
||||
temp = ati28800->regs[ati28800->index] & ~8;
|
||||
if (ati_eeprom_read(&ati28800->eeprom))
|
||||
temp |= 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
temp = ati_regs[ati_index];
|
||||
temp = ati28800->regs[ati28800->index];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3c2:
|
||||
if ((vgapal[0].r + vgapal[0].g + vgapal[0].b) >= 0x50)
|
||||
if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50)
|
||||
temp = 0;
|
||||
else
|
||||
temp = 0x10;
|
||||
break;
|
||||
case 0x3D4:
|
||||
temp = crtcreg;
|
||||
temp = svga->crtcreg;
|
||||
break;
|
||||
case 0x3D5:
|
||||
temp = crtc[crtcreg];
|
||||
temp = svga->crtc[svga->crtcreg];
|
||||
break;
|
||||
default:
|
||||
temp = svga_in(addr, NULL);
|
||||
temp = svga_in(addr, svga);
|
||||
break;
|
||||
}
|
||||
if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc);
|
||||
return temp;
|
||||
}
|
||||
|
||||
void ati28800_recalctimings()
|
||||
void ati28800_recalctimings(svga_t *svga)
|
||||
{
|
||||
ati28800_t *ati28800 = (ati28800_t *)svga->p;
|
||||
pclog("ati28800_recalctimings\n");
|
||||
if (!scrblank && (ati_regs[0xb0] & 0x20)) /*Extended 256 colour modes*/
|
||||
if (!svga->scrblank && (ati28800->regs[0xb0] & 0x20)) /*Extended 256 colour modes*/
|
||||
{
|
||||
pclog("8bpp_highres\n");
|
||||
svga_render = svga_render_8bpp_highres;
|
||||
svga_rowoffset <<= 1;
|
||||
svga_ma <<= 1;
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
svga->rowoffset <<= 1;
|
||||
svga->ma <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
int ati28800_init()
|
||||
void *ati28800_init()
|
||||
{
|
||||
svga_recalctimings_ex = ati28800_recalctimings;
|
||||
svga_vram_limit = 1 << 19; /*512kb*/
|
||||
vrammask = 0x7ffff;
|
||||
svgawbank = svgarbank = 0;
|
||||
bpp = 8;
|
||||
svga_miscout = 1;
|
||||
ati28800_t *ati28800 = malloc(sizeof(ati28800_t));
|
||||
memset(ati28800, 0, sizeof(ati28800_t));
|
||||
|
||||
io_sethandler(0x01ce, 0x0002, ati28800_in, NULL, NULL, ati28800_out, NULL, NULL, NULL);
|
||||
|
||||
ati_eeprom_load("ati28800.nvr", 0);
|
||||
|
||||
return svga_init();
|
||||
svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/
|
||||
ati28800_recalctimings,
|
||||
ati28800_in, ati28800_out,
|
||||
NULL);
|
||||
|
||||
io_sethandler(0x01ce, 0x0002, ati28800_in, NULL, NULL, ati28800_out, NULL, NULL, ati28800);
|
||||
io_sethandler(0x03c0, 0x0020, ati28800_in, NULL, NULL, ati28800_out, NULL, NULL, ati28800);
|
||||
|
||||
ati28800->svga.miscout = 1;
|
||||
|
||||
ati_eeprom_load(&ati28800->eeprom, "ati28800.nvr", 0);
|
||||
|
||||
return ati28800;
|
||||
}
|
||||
|
||||
GFXCARD vid_ati28800 =
|
||||
void ati28800_close(void *p)
|
||||
{
|
||||
ati28800_t *ati28800 = (ati28800_t *)p;
|
||||
|
||||
svga_close(&ati28800->svga);
|
||||
|
||||
free(ati28800);
|
||||
}
|
||||
|
||||
void ati28800_speed_changed(void *p)
|
||||
{
|
||||
ati28800_t *ati28800 = (ati28800_t *)p;
|
||||
|
||||
svga_recalctimings(&ati28800->svga);
|
||||
}
|
||||
|
||||
device_t ati28800_device =
|
||||
{
|
||||
"ATI-28800",
|
||||
ati28800_init,
|
||||
/*IO at 3Cx/3Dx*/
|
||||
ati28800_out,
|
||||
ati28800_in,
|
||||
/*IO at 3Ax/3Bx*/
|
||||
video_out_null,
|
||||
video_in_null,
|
||||
|
||||
svga_poll,
|
||||
svga_recalctimings,
|
||||
|
||||
svga_write,
|
||||
video_write_null,
|
||||
video_write_null,
|
||||
|
||||
svga_read,
|
||||
video_read_null,
|
||||
video_read_null
|
||||
ati28800_close,
|
||||
ati28800_speed_changed,
|
||||
svga_add_status_info
|
||||
};
|
||||
|
|
|
|||
1
src/vid_ati28800.h
Normal file
1
src/vid_ati28800.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
extern device_t ati28800_device;
|
||||
|
|
@ -23,46 +23,45 @@ bit 0 Controls 6/8bit DAC. 0: 8bit DAC/LUT, 1: 6bit DAC/LUT
|
|||
#include "vid_svga.h"
|
||||
#include "vid_ati68860_ramdac.h"
|
||||
|
||||
static uint8_t ramdac_regs[16];
|
||||
void ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv)
|
||||
void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
// pclog("ati68860_out : addr %04X val %02X %04X:%04X\n", addr, val, CS,pc);
|
||||
switch (addr)
|
||||
{
|
||||
case 0:
|
||||
svga_out(0x3c8, val, NULL);
|
||||
svga_out(0x3c8, val, svga);
|
||||
break;
|
||||
case 1:
|
||||
svga_out(0x3c9, val, NULL);
|
||||
svga_out(0x3c9, val, svga);
|
||||
break;
|
||||
case 2:
|
||||
svga_out(0x3c6, val, NULL);
|
||||
svga_out(0x3c6, val, svga);
|
||||
break;
|
||||
case 3:
|
||||
svga_out(0x3c7, val, NULL);
|
||||
svga_out(0x3c7, val, svga);
|
||||
break;
|
||||
default:
|
||||
ramdac_regs[addr & 0xf] = val;
|
||||
ramdac->regs[addr & 0xf] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ati68860_ramdac_in(uint16_t addr, void *priv)
|
||||
uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
switch (addr)
|
||||
{
|
||||
case 0:
|
||||
ret = svga_in(0x3c8, NULL);
|
||||
ret = svga_in(0x3c8, svga);
|
||||
break;
|
||||
case 1:
|
||||
ret = svga_in(0x3c9, NULL);
|
||||
ret = svga_in(0x3c9, svga);
|
||||
break;
|
||||
case 2:
|
||||
ret = svga_in(0x3c6, NULL);
|
||||
ret = svga_in(0x3c6, svga);
|
||||
break;
|
||||
case 3:
|
||||
ret = svga_in(0x3c7, NULL);
|
||||
ret = svga_in(0x3c7, svga);
|
||||
break;
|
||||
case 4: case 8:
|
||||
ret = 2;
|
||||
|
|
@ -75,7 +74,7 @@ uint8_t ati68860_ramdac_in(uint16_t addr, void *priv)
|
|||
break;
|
||||
|
||||
default:
|
||||
ret = ramdac_regs[addr & 0xf];
|
||||
ret = ramdac->regs[addr & 0xf];
|
||||
break;
|
||||
}
|
||||
// pclog("ati68860_in : addr %04X ret %02X %04X:%04X\n", addr, ret, CS,pc);
|
||||
|
|
|
|||
|
|
@ -1,2 +1,7 @@
|
|||
void ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t ati68860_ramdac_in(uint16_t addr, void *priv);
|
||||
typedef struct ati68860_ramdac_t
|
||||
{
|
||||
uint8_t regs[16];
|
||||
} ati68860_ramdac_t;
|
||||
|
||||
void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga);
|
||||
uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#include "ibm.h"
|
||||
#include "vid_ati_eeprom.h"
|
||||
|
||||
static uint16_t eeprom[256];
|
||||
enum
|
||||
{
|
||||
EEPROM_IDLE,
|
||||
|
|
@ -29,201 +28,193 @@ enum
|
|||
EEPROM_OP_EWEN = 3
|
||||
};
|
||||
|
||||
static int oldclk, oldena;
|
||||
static int eeprom_opcode, eeprom_state, eeprom_count, eeprom_out;
|
||||
static int eeprom_wp;
|
||||
static uint32_t eeprom_dat;
|
||||
static int eeprom_type;
|
||||
|
||||
static char eeprom_fn[256] = {0};
|
||||
|
||||
void ati_eeprom_load(char *fn, int type)
|
||||
void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type)
|
||||
{
|
||||
FILE *f;
|
||||
eeprom_type = type;
|
||||
strcpy(eeprom_fn, fn);
|
||||
f = romfopen(eeprom_fn, "rb");
|
||||
eeprom->type = type;
|
||||
strcpy(eeprom->fn, fn);
|
||||
f = romfopen(eeprom->fn, "rb");
|
||||
if (!f)
|
||||
{
|
||||
memset(eeprom, 0, type ? 512 : 128);
|
||||
memset(eeprom->data, 0, eeprom->type ? 512 : 128);
|
||||
return;
|
||||
}
|
||||
fread(eeprom, 1, type ? 512 : 128, f);
|
||||
fread(eeprom->data, 1, eeprom->type ? 512 : 128, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void ati_eeprom_save()
|
||||
void ati_eeprom_save(ati_eeprom_t *eeprom)
|
||||
{
|
||||
FILE *f = romfopen(eeprom_fn, "wb");
|
||||
FILE *f = romfopen(eeprom->fn, "wb");
|
||||
if (!f) return;
|
||||
fwrite(eeprom, 1, eeprom_type ? 512 : 128, f);
|
||||
fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void ati_eeprom_write(int ena, int clk, int dat)
|
||||
void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat)
|
||||
{
|
||||
int c;
|
||||
pclog("EEPROM write %i %i %i\n", ena, clk, dat);
|
||||
if (!ena)
|
||||
{
|
||||
eeprom_out = 1;
|
||||
eeprom->out = 1;
|
||||
}
|
||||
if (clk && !oldclk)
|
||||
if (clk && !eeprom->oldclk)
|
||||
{
|
||||
if (ena && !oldena)
|
||||
if (ena && !eeprom->oldena)
|
||||
{
|
||||
eeprom_state = EEPROM_WAIT;
|
||||
eeprom_opcode = 0;
|
||||
eeprom_count = 3;
|
||||
eeprom_out = 1;
|
||||
eeprom->state = EEPROM_WAIT;
|
||||
eeprom->opcode = 0;
|
||||
eeprom->count = 3;
|
||||
eeprom->out = 1;
|
||||
}
|
||||
else if (ena)
|
||||
{
|
||||
pclog("EEPROM receive %i %i %i\n", ena, clk, dat);
|
||||
switch (eeprom_state)
|
||||
switch (eeprom->state)
|
||||
{
|
||||
case EEPROM_WAIT:
|
||||
if (!dat)
|
||||
break;
|
||||
eeprom_state = EEPROM_OPCODE;
|
||||
eeprom->state = EEPROM_OPCODE;
|
||||
/* fall through */
|
||||
case EEPROM_OPCODE:
|
||||
eeprom_opcode = (eeprom_opcode << 1) | (dat ? 1 : 0);
|
||||
eeprom_count--;
|
||||
if (!eeprom_count)
|
||||
eeprom->opcode = (eeprom->opcode << 1) | (dat ? 1 : 0);
|
||||
eeprom->count--;
|
||||
if (!eeprom->count)
|
||||
{
|
||||
pclog("EEPROM opcode - %i\n", eeprom_opcode);
|
||||
switch (eeprom_opcode)
|
||||
pclog("EEPROM opcode - %i\n", eeprom->opcode);
|
||||
switch (eeprom->opcode)
|
||||
{
|
||||
case EEPROM_OP_WRITE:
|
||||
eeprom_count = eeprom_type ? 24 : 22;
|
||||
eeprom_state = EEPROM_INPUT;
|
||||
eeprom_dat = 0;
|
||||
eeprom->count = eeprom->type ? 24 : 22;
|
||||
eeprom->state = EEPROM_INPUT;
|
||||
eeprom->dat = 0;
|
||||
break;
|
||||
case EEPROM_OP_READ:
|
||||
eeprom_count = eeprom_type ? 8 : 6;
|
||||
eeprom_state = EEPROM_INPUT;
|
||||
eeprom_dat = 0;
|
||||
eeprom->count = eeprom->type ? 8 : 6;
|
||||
eeprom->state = EEPROM_INPUT;
|
||||
eeprom->dat = 0;
|
||||
break;
|
||||
case EEPROM_OP_EW:
|
||||
eeprom_count = 2;
|
||||
eeprom_state = EEPROM_INPUT;
|
||||
eeprom_dat = 0;
|
||||
eeprom->count = 2;
|
||||
eeprom->state = EEPROM_INPUT;
|
||||
eeprom->dat = 0;
|
||||
break;
|
||||
case EEPROM_OP_ERASE:
|
||||
eeprom_count = eeprom_type ? 8 : 6;
|
||||
eeprom_state = EEPROM_INPUT;
|
||||
eeprom_dat = 0;
|
||||
eeprom->count = eeprom->type ? 8 : 6;
|
||||
eeprom->state = EEPROM_INPUT;
|
||||
eeprom->dat = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EEPROM_INPUT:
|
||||
eeprom_dat = (eeprom_dat << 1) | (dat ? 1 : 0);
|
||||
eeprom_count--;
|
||||
if (!eeprom_count)
|
||||
eeprom->dat = (eeprom->dat << 1) | (dat ? 1 : 0);
|
||||
eeprom->count--;
|
||||
if (!eeprom->count)
|
||||
{
|
||||
pclog("EEPROM dat - %02X\n", eeprom_dat);
|
||||
switch (eeprom_opcode)
|
||||
pclog("EEPROM dat - %02X\n", eeprom->dat);
|
||||
switch (eeprom->opcode)
|
||||
{
|
||||
case EEPROM_OP_WRITE:
|
||||
pclog("EEPROM_OP_WRITE addr %02X eeprom_dat %04X\n", (eeprom_dat >> 16) & (eeprom_type ? 255 : 63), eeprom_dat & 0xffff);
|
||||
if (!eeprom_wp)
|
||||
pclog("EEPROM_OP_WRITE addr %02X eeprom_dat %04X\n", (eeprom->dat >> 16) & (eeprom->type ? 255 : 63), eeprom->dat & 0xffff);
|
||||
if (!eeprom->wp)
|
||||
{
|
||||
eeprom[(eeprom_dat >> 16) & (eeprom_type ? 255 : 63)] = eeprom_dat & 0xffff;
|
||||
ati_eeprom_save();
|
||||
eeprom->data[(eeprom->dat >> 16) & (eeprom->type ? 255 : 63)] = eeprom->dat & 0xffff;
|
||||
ati_eeprom_save(eeprom);
|
||||
}
|
||||
eeprom_state = EEPROM_IDLE;
|
||||
eeprom_out = 1;
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
eeprom->out = 1;
|
||||
break;
|
||||
|
||||
case EEPROM_OP_READ:
|
||||
eeprom_count = 17;
|
||||
eeprom_state = EEPROM_OUTPUT;
|
||||
eeprom_dat = eeprom[eeprom_dat];
|
||||
pclog("Trigger EEPROM_OUTPUT %04X\n", eeprom_dat);
|
||||
eeprom->count = 17;
|
||||
eeprom->state = EEPROM_OUTPUT;
|
||||
eeprom->dat = eeprom->data[eeprom->dat];
|
||||
pclog("Trigger EEPROM_OUTPUT %04X\n", eeprom->dat);
|
||||
break;
|
||||
case EEPROM_OP_EW:
|
||||
pclog("EEPROM_OP_EW %i\n", eeprom_dat);
|
||||
switch (eeprom_dat)
|
||||
pclog("EEPROM_OP_EW %i\n", eeprom->dat);
|
||||
switch (eeprom->dat)
|
||||
{
|
||||
case EEPROM_OP_EWDS:
|
||||
eeprom_wp = 1;
|
||||
eeprom->wp = 1;
|
||||
break;
|
||||
case EEPROM_OP_WRAL:
|
||||
opcode = EEPROM_OP_WRALMAIN;
|
||||
eeprom_count = 20;
|
||||
eeprom->opcode = EEPROM_OP_WRALMAIN;
|
||||
eeprom->count = 20;
|
||||
break;
|
||||
case EEPROM_OP_ERAL:
|
||||
if (!eeprom_wp)
|
||||
if (!eeprom->wp)
|
||||
{
|
||||
memset(eeprom, 0xff, 128);
|
||||
ati_eeprom_save();
|
||||
memset(eeprom->data, 0xff, 128);
|
||||
ati_eeprom_save(eeprom);
|
||||
}
|
||||
break;
|
||||
case EEPROM_OP_EWEN:
|
||||
eeprom_wp = 0;
|
||||
eeprom->wp = 0;
|
||||
break;
|
||||
}
|
||||
eeprom_state = EEPROM_IDLE;
|
||||
eeprom_out = 1;
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
eeprom->out = 1;
|
||||
break;
|
||||
|
||||
case EEPROM_OP_ERASE:
|
||||
pclog("EEPROM_OP_ERASE %i\n", eeprom_dat);
|
||||
if (!eeprom_wp)
|
||||
pclog("EEPROM_OP_ERASE %i\n", eeprom->dat);
|
||||
if (!eeprom->wp)
|
||||
{
|
||||
eeprom[eeprom_dat] = 0xffff;
|
||||
ati_eeprom_save();
|
||||
eeprom->data[eeprom->dat] = 0xffff;
|
||||
ati_eeprom_save(eeprom);
|
||||
}
|
||||
eeprom_state = EEPROM_IDLE;
|
||||
eeprom_out = 1;
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
eeprom->out = 1;
|
||||
break;
|
||||
|
||||
case EEPROM_OP_WRALMAIN:
|
||||
pclog("EEPROM_OP_WRAL %04X\n", eeprom_dat);
|
||||
if (!eeprom_wp)
|
||||
pclog("EEPROM_OP_WRAL %04X\n", eeprom->dat);
|
||||
if (!eeprom->wp)
|
||||
{
|
||||
for (c = 0; c < 256; c++)
|
||||
eeprom[c] = eeprom_dat;
|
||||
ati_eeprom_save();
|
||||
eeprom->data[c] = eeprom->dat;
|
||||
ati_eeprom_save(eeprom);
|
||||
}
|
||||
eeprom_state = EEPROM_IDLE;
|
||||
eeprom_out = 1;
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
eeprom->out = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
oldena = ena;
|
||||
eeprom->oldena = ena;
|
||||
}
|
||||
else if (!clk && oldclk)
|
||||
else if (!clk && eeprom->oldclk)
|
||||
{
|
||||
if (ena)
|
||||
{
|
||||
switch (eeprom_state)
|
||||
switch (eeprom->state)
|
||||
{
|
||||
case EEPROM_OUTPUT:
|
||||
eeprom_out = (eeprom_dat & 0x10000) ? 1 : 0;
|
||||
eeprom_dat <<= 1;
|
||||
pclog("EEPROM_OUTPUT - data %i\n", eeprom_out);
|
||||
eeprom_count--;
|
||||
if (!eeprom_count)
|
||||
eeprom->out = (eeprom->dat & 0x10000) ? 1 : 0;
|
||||
eeprom->dat <<= 1;
|
||||
pclog("EEPROM_OUTPUT - data %i\n", eeprom->out);
|
||||
eeprom->count--;
|
||||
if (!eeprom->count)
|
||||
{
|
||||
pclog("EEPROM_OUTPUT complete\n");
|
||||
eeprom_state = EEPROM_IDLE;
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
oldclk = clk;
|
||||
eeprom->oldclk = clk;
|
||||
}
|
||||
|
||||
int ati_eeprom_read()
|
||||
int ati_eeprom_read(ati_eeprom_t *eeprom)
|
||||
{
|
||||
return eeprom_out;
|
||||
return eeprom->out;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,16 @@
|
|||
void ati_eeprom_load(char *fn, int type);
|
||||
void ati_eeprom_write(int ena, int clk, int dat);
|
||||
int ati_eeprom_read();
|
||||
typedef struct ati_eeprom_t
|
||||
{
|
||||
uint16_t data[256];
|
||||
|
||||
int oldclk, oldena;
|
||||
int opcode, state, count, out;
|
||||
int wp;
|
||||
uint32_t dat;
|
||||
int type;
|
||||
|
||||
char fn[256];
|
||||
} ati_eeprom_t;
|
||||
|
||||
void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type);
|
||||
void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat);
|
||||
int ati_eeprom_read(ati_eeprom_t *eeprom);
|
||||
|
|
|
|||
1217
src/vid_ati_mach64.c
1217
src/vid_ati_mach64.c
File diff suppressed because it is too large
Load diff
1
src/vid_ati_mach64.h
Normal file
1
src/vid_ati_mach64.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
extern device_t mach64gx_device;
|
||||
577
src/vid_cga.c
577
src/vid_cga.c
|
|
@ -1,110 +1,115 @@
|
|||
/*CGA emulation*/
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "timer.h"
|
||||
#include "video.h"
|
||||
#include "vid_cga.h"
|
||||
|
||||
void cga_recalctimings();
|
||||
static int i_filt[8],q_filt[8];
|
||||
|
||||
void cga_out(uint16_t addr, uint8_t val, void *priv)
|
||||
static uint8_t crtcmask[32] =
|
||||
{
|
||||
0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
void cga_recalctimings(cga_t *cga);
|
||||
|
||||
void cga_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
cga_t *cga = (cga_t *)p;
|
||||
uint8_t old;
|
||||
// pclog("CGA_OUT %04X %02X\n", addr, val);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3D4:
|
||||
crtcreg=val&31;
|
||||
cga->crtcreg = val & 31;
|
||||
return;
|
||||
case 0x3D5:
|
||||
old=crtc[crtcreg];
|
||||
crtc[crtcreg]=val&crtcmask[crtcreg];
|
||||
if (old!=val)
|
||||
old = cga->crtc[cga->crtcreg];
|
||||
cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg];
|
||||
if (old != val)
|
||||
{
|
||||
if (crtcreg<0xE || crtcreg>0x10)
|
||||
if (cga->crtcreg < 0xe || cga->crtcreg > 0x10)
|
||||
{
|
||||
fullchange=changeframecount;
|
||||
cga_recalctimings();
|
||||
fullchange = changeframecount;
|
||||
cga_recalctimings(cga);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case 0x3D8:
|
||||
cgamode=val;
|
||||
cga->cgamode = val;
|
||||
return;
|
||||
case 0x3D9:
|
||||
cgacol=val;
|
||||
cga->cgacol = val;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t cga_in(uint16_t addr, void *priv)
|
||||
uint8_t cga_in(uint16_t addr, void *p)
|
||||
{
|
||||
cga_t *cga = (cga_t *)p;
|
||||
// pclog("CGA_IN %04X\n", addr);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3D4:
|
||||
return crtcreg;
|
||||
return cga->crtcreg;
|
||||
case 0x3D5:
|
||||
return crtc[crtcreg];
|
||||
return cga->crtc[cga->crtcreg];
|
||||
case 0x3DA:
|
||||
return cgastat;
|
||||
return cga->cgastat;
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
extern uint8_t charbuffer[256];
|
||||
|
||||
void cga_write(uint32_t addr, uint8_t val, void *priv)
|
||||
void cga_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
cga_t *cga = (cga_t *)p;
|
||||
// pclog("CGA_WRITE %04X %02X\n", addr, val);
|
||||
vram[addr&0x3FFF]=val;
|
||||
charbuffer[ ((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc] = val;
|
||||
charbuffer[(((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc) | 1] = val;
|
||||
cga->vram[addr & 0x3fff] = val;
|
||||
cga->charbuffer[ ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc] = val;
|
||||
cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = val;
|
||||
cycles -= 4;
|
||||
}
|
||||
|
||||
uint8_t cga_read(uint32_t addr, void *priv)
|
||||
uint8_t cga_read(uint32_t addr, void *p)
|
||||
{
|
||||
cga_t *cga = (cga_t *)p;
|
||||
cycles -= 4;
|
||||
charbuffer[ ((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc] = vram[addr&0x3FFF];
|
||||
charbuffer[(((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc) | 1] = vram[addr&0x3FFF];
|
||||
cga->charbuffer[ ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc] = cga->vram[addr & 0x3fff];
|
||||
cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = cga->vram[addr & 0x3fff];
|
||||
// pclog("CGA_READ %04X\n", addr);
|
||||
return vram[addr&0x3FFF];
|
||||
return cga->vram[addr & 0x3fff];
|
||||
}
|
||||
|
||||
void cga_recalctimings()
|
||||
void cga_recalctimings(cga_t *cga)
|
||||
{
|
||||
double disptime;
|
||||
double _dispontime, _dispofftime;
|
||||
pclog("Recalc - %i %i %i\n", crtc[0], crtc[1], cgamode & 1);
|
||||
if (cgamode&1)
|
||||
pclog("Recalc - %i %i %i\n", cga->crtc[0], cga->crtc[1], cga->cgamode & 1);
|
||||
if (cga->cgamode & 1)
|
||||
{
|
||||
disptime=crtc[0]+1;
|
||||
_dispontime=crtc[1];
|
||||
disptime = cga->crtc[0] + 1;
|
||||
_dispontime = cga->crtc[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
disptime=(crtc[0]+1)<<1;
|
||||
_dispontime=crtc[1]<<1;
|
||||
disptime = (cga->crtc[0] + 1) << 1;
|
||||
_dispontime = cga->crtc[1] << 1;
|
||||
}
|
||||
_dispofftime=disptime-_dispontime;
|
||||
_dispofftime = disptime - _dispontime;
|
||||
// printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]);
|
||||
_dispontime*=CGACONST;
|
||||
_dispofftime*=CGACONST;
|
||||
_dispontime *= CGACONST;
|
||||
_dispofftime *= CGACONST;
|
||||
// printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92);
|
||||
dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||
dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
cga->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||
cga->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
}
|
||||
|
||||
static int linepos,displine;
|
||||
static int sc,vc;
|
||||
static int cgadispon;
|
||||
static int con,coff,cursoron,cgablink;
|
||||
static int vsynctime,vadj;
|
||||
static uint16_t ma,maback;
|
||||
static int oddeven = 0;
|
||||
|
||||
static int ntsc_col[8][8]=
|
||||
{
|
||||
{0,0,0,0,0,0,0,0}, /*Black*/
|
||||
|
|
@ -117,326 +122,331 @@ static int ntsc_col[8][8]=
|
|||
{1,1,1,1,1,1,1,1} /*White*/
|
||||
};
|
||||
|
||||
int i_filt[8],q_filt[8];
|
||||
|
||||
|
||||
void cga_poll()
|
||||
void cga_poll(void *p)
|
||||
{
|
||||
uint16_t ca=(crtc[15]|(crtc[14]<<8))&0x3FFF;
|
||||
cga_t *cga = (cga_t *)p;
|
||||
uint16_t ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x,c;
|
||||
int x, c;
|
||||
int oldvc;
|
||||
uint8_t chr,attr;
|
||||
uint8_t chr, attr;
|
||||
uint16_t dat;
|
||||
int cols[4];
|
||||
int col;
|
||||
int oldsc;
|
||||
int y_buf[8]={0,0,0,0,0,0,0,0},y_val,y_tot;
|
||||
int i_buf[8]={0,0,0,0,0,0,0,0},i_val,i_tot;
|
||||
int q_buf[8]={0,0,0,0,0,0,0,0},q_val,q_tot;
|
||||
int r,g,b;
|
||||
if (!linepos)
|
||||
int y_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, y_val, y_tot;
|
||||
int i_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, i_val, i_tot;
|
||||
int q_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, q_val, q_tot;
|
||||
int r, g, b;
|
||||
if (!cga->linepos)
|
||||
{
|
||||
vidtime+=dispofftime;
|
||||
cgastat|=1;
|
||||
linepos=1;
|
||||
oldsc=sc;
|
||||
if ((crtc[8] & 3) == 3)
|
||||
sc = ((sc << 1) + oddeven) & 7;
|
||||
if (cgadispon)
|
||||
cga->vidtime += cga->dispofftime;
|
||||
cga->cgastat |= 1;
|
||||
cga->linepos = 1;
|
||||
oldsc = cga->sc;
|
||||
if ((cga->crtc[8] & 3) == 3)
|
||||
cga->sc = ((cga->sc << 1) + cga->oddeven) & 7;
|
||||
if (cga->cgadispon)
|
||||
{
|
||||
if (displine<firstline)
|
||||
if (cga->displine < cga->firstline)
|
||||
{
|
||||
firstline=displine;
|
||||
cga->firstline = cga->displine;
|
||||
// printf("Firstline %i\n",firstline);
|
||||
}
|
||||
lastline=displine;
|
||||
for (c=0;c<8;c++)
|
||||
cga->lastline = cga->displine;
|
||||
for (c = 0; c < 8; c++)
|
||||
{
|
||||
if ((cgamode&0x12)==0x12)
|
||||
if ((cga->cgamode & 0x12) == 0x12)
|
||||
{
|
||||
buffer->line[displine][c]=0;
|
||||
if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=0;
|
||||
else buffer->line[displine][c+(crtc[1]<<4)+8]=0;
|
||||
buffer->line[cga->displine][c] = 0;
|
||||
if (cga->cgamode & 1) buffer->line[cga->displine][c + (cga->crtc[1] << 3) + 8] = 0;
|
||||
else buffer->line[cga->displine][c + (cga->crtc[1] << 4) + 8] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer->line[displine][c]=(cgacol&15)+16;
|
||||
if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=(cgacol&15)+16;
|
||||
else buffer->line[displine][c+(crtc[1]<<4)+8]=(cgacol&15)+16;
|
||||
buffer->line[cga->displine][c] = (cga->cgacol & 15) + 16;
|
||||
if (cga->cgamode & 1) buffer->line[cga->displine][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16;
|
||||
else buffer->line[cga->displine][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16;
|
||||
}
|
||||
}
|
||||
if (cgamode&1)
|
||||
if (cga->cgamode & 1)
|
||||
{
|
||||
for (x=0;x<crtc[1];x++)
|
||||
for (x = 0; x < cga->crtc[1]; x++)
|
||||
{
|
||||
chr=charbuffer[x<<1];
|
||||
attr=charbuffer[(x<<1)+1];
|
||||
drawcursor=((ma==ca) && con && cursoron);
|
||||
if (cgamode&0x20)
|
||||
chr = cga->charbuffer[x << 1];
|
||||
attr = cga->charbuffer[(x << 1) + 1];
|
||||
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
|
||||
if (cga->cgamode & 0x20)
|
||||
{
|
||||
cols[1]=(attr&15)+16;
|
||||
cols[0]=((attr>>4)&7)+16;
|
||||
if ((cgablink&8) && (attr&0x80) && !drawcursor) cols[1]=cols[0];
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor)
|
||||
cols[1] = cols[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
cols[1]=(attr&15)+16;
|
||||
cols[0]=(attr>>4)+16;
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
}
|
||||
if (drawcursor)
|
||||
{
|
||||
for (c=0;c<8;c++)
|
||||
buffer->line[displine][(x<<3)+c+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]^15;
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer->line[cga->displine][(x << 3) + c + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (c=0;c<8;c++)
|
||||
buffer->line[displine][(x<<3)+c+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0];
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer->line[cga->displine][(x << 3) + c + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
ma++;
|
||||
cga->ma++;
|
||||
}
|
||||
}
|
||||
else if (!(cgamode&2))
|
||||
else if (!(cga->cgamode & 2))
|
||||
{
|
||||
for (x=0;x<crtc[1];x++)
|
||||
for (x = 0; x < cga->crtc[1]; x++)
|
||||
{
|
||||
chr=vram[((ma<<1)&0x3FFF)];
|
||||
attr=vram[(((ma<<1)+1)&0x3FFF)];
|
||||
drawcursor=((ma==ca) && con && cursoron);
|
||||
if (cgamode&0x20)
|
||||
chr = cga->vram[((cga->ma << 1) & 0x3fff)];
|
||||
attr = cga->vram[(((cga->ma << 1) + 1) & 0x3fff)];
|
||||
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
|
||||
if (cga->cgamode & 0x20)
|
||||
{
|
||||
cols[1]=(attr&15)+16;
|
||||
cols[0]=((attr>>4)&7)+16;
|
||||
if ((cgablink&8) && (attr&0x80)) cols[1]=cols[0];
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((cga->cgablink & 8) && (attr & 0x80)) cols[1] = cols[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
cols[1]=(attr&15)+16;
|
||||
cols[0]=(attr>>4)+16;
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
}
|
||||
ma++;
|
||||
cga->ma++;
|
||||
if (drawcursor)
|
||||
{
|
||||
for (c=0;c<8;c++)
|
||||
buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]^15;
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer->line[cga->displine][(x << 4)+(c << 1) + 8] = buffer->line[cga->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (c=0;c<8;c++)
|
||||
buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0];
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer->line[cga->displine][(x << 4) + (c << 1) + 8] = buffer->line[cga->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!(cgamode&16))
|
||||
else if (!(cga->cgamode & 16))
|
||||
{
|
||||
cols[0]=(cgacol&15)|16;
|
||||
col=(cgacol&16)?24:16;
|
||||
if (cgamode&4)
|
||||
cols[0] = (cga->cgacol & 15) | 16;
|
||||
col = (cga->cgacol & 16) ? 24 : 16;
|
||||
if (cga->cgamode & 4)
|
||||
{
|
||||
cols[1]=col|3;
|
||||
cols[2]=col|4;
|
||||
cols[3]=col|7;
|
||||
cols[1] = col | 3;
|
||||
cols[2] = col | 4;
|
||||
cols[3] = col | 7;
|
||||
}
|
||||
else if (cgacol&32)
|
||||
else if (cga->cgacol & 32)
|
||||
{
|
||||
cols[1]=col|3;
|
||||
cols[2]=col|5;
|
||||
cols[3]=col|7;
|
||||
cols[1] = col | 3;
|
||||
cols[2] = col | 5;
|
||||
cols[3] = col | 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
cols[1]=col|2;
|
||||
cols[2]=col|4;
|
||||
cols[3]=col|6;
|
||||
cols[1] = col | 2;
|
||||
cols[2] = col | 4;
|
||||
cols[3] = col | 6;
|
||||
}
|
||||
for (x=0;x<crtc[1];x++)
|
||||
for (x = 0; x < cga->crtc[1]; x++)
|
||||
{
|
||||
dat=(vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)]<<8)|vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)+1];
|
||||
ma++;
|
||||
for (c=0;c<8;c++)
|
||||
dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
|
||||
cga->ma++;
|
||||
for (c = 0; c < 8; c++)
|
||||
{
|
||||
buffer->line[displine][(x<<4)+(c<<1)+8]=
|
||||
buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[dat>>14];
|
||||
dat<<=2;
|
||||
buffer->line[cga->displine][(x << 4) + (c << 1) + 8] =
|
||||
buffer->line[cga->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14];
|
||||
dat <<= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cols[0]=0; cols[1]=(cgacol&15)+16;
|
||||
for (x=0;x<crtc[1];x++)
|
||||
cols[0] = 0; cols[1] = (cga->cgacol & 15) + 16;
|
||||
for (x = 0; x < cga->crtc[1]; x++)
|
||||
{
|
||||
dat=(vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)]<<8)|vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)+1];
|
||||
ma++;
|
||||
for (c=0;c<16;c++)
|
||||
dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
|
||||
cga->ma++;
|
||||
for (c = 0; c < 16; c++)
|
||||
{
|
||||
buffer->line[displine][(x<<4)+c+8]=cols[dat>>15];
|
||||
dat<<=1;
|
||||
buffer->line[cga->displine][(x << 4) + c + 8] = cols[dat >> 15];
|
||||
dat <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cols[0]=((cgamode&0x12)==0x12)?0:(cgacol&15)+16;
|
||||
if (cgamode&1) hline(buffer,0,displine,(crtc[1]<<3)+16,cols[0]);
|
||||
else hline(buffer,0,displine,(crtc[1]<<4)+16,cols[0]);
|
||||
cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16;
|
||||
if (cga->cgamode & 1) hline(buffer, 0, cga->displine, (cga->crtc[1] << 3) + 16, cols[0]);
|
||||
else hline(buffer, 0, cga->displine, (cga->crtc[1] << 4) + 16, cols[0]);
|
||||
}
|
||||
|
||||
if (cgamode&1) x=(crtc[1]<<3)+16;
|
||||
else x=(crtc[1]<<4)+16;
|
||||
if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16;
|
||||
else x = (cga->crtc[1] << 4) + 16;
|
||||
if (cga_comp)
|
||||
{
|
||||
for (c=0;c<x;c++)
|
||||
for (c = 0; c < x; c++)
|
||||
{
|
||||
y_buf[(c<<1)&6]=ntsc_col[buffer->line[displine][c]&7][(c<<1)&6]?0x6000:0;
|
||||
y_buf[(c<<1)&6]+=(buffer->line[displine][c]&8)?0x3000:0;
|
||||
i_buf[(c<<1)&6]=y_buf[(c<<1)&6]*i_filt[(c<<1)&6];
|
||||
q_buf[(c<<1)&6]=y_buf[(c<<1)&6]*q_filt[(c<<1)&6];
|
||||
y_tot=y_buf[0]+y_buf[1]+y_buf[2]+y_buf[3]+y_buf[4]+y_buf[5]+y_buf[6]+y_buf[7];
|
||||
i_tot=i_buf[0]+i_buf[1]+i_buf[2]+i_buf[3]+i_buf[4]+i_buf[5]+i_buf[6]+i_buf[7];
|
||||
q_tot=q_buf[0]+q_buf[1]+q_buf[2]+q_buf[3]+q_buf[4]+q_buf[5]+q_buf[6]+q_buf[7];
|
||||
y_buf[(c << 1) & 6] = ntsc_col[buffer->line[cga->displine][c] & 7][(c << 1) & 6] ? 0x6000 : 0;
|
||||
y_buf[(c << 1) & 6] += (buffer->line[cga->displine][c] & 8) ? 0x3000 : 0;
|
||||
i_buf[(c << 1) & 6] = y_buf[(c << 1) & 6] * i_filt[(c << 1) & 6];
|
||||
q_buf[(c << 1) & 6] = y_buf[(c << 1) & 6] * q_filt[(c << 1) & 6];
|
||||
y_tot = y_buf[0] + y_buf[1] + y_buf[2] + y_buf[3] + y_buf[4] + y_buf[5] + y_buf[6] + y_buf[7];
|
||||
i_tot = i_buf[0] + i_buf[1] + i_buf[2] + i_buf[3] + i_buf[4] + i_buf[5] + i_buf[6] + i_buf[7];
|
||||
q_tot = q_buf[0] + q_buf[1] + q_buf[2] + q_buf[3] + q_buf[4] + q_buf[5] + q_buf[6] + q_buf[7];
|
||||
|
||||
y_val=y_tot>>10;
|
||||
if (y_val>255) y_val=255;
|
||||
y_val<<=16;
|
||||
i_val=i_tot>>12;
|
||||
if (i_val>39041) i_val=39041;
|
||||
if (i_val<-39041) i_val=-39041;
|
||||
q_val=q_tot>>12;
|
||||
if (q_val>34249) q_val=34249;
|
||||
if (q_val<-34249) q_val=-34249;
|
||||
y_val = y_tot >> 10;
|
||||
if (y_val > 255) y_val = 255;
|
||||
y_val <<= 16;
|
||||
i_val = i_tot >> 12;
|
||||
if (i_val > 39041) i_val = 39041;
|
||||
if (i_val < -39041) i_val = -39041;
|
||||
q_val = q_tot >> 12;
|
||||
if (q_val > 34249) q_val = 34249;
|
||||
if (q_val < -34249) q_val = -34249;
|
||||
|
||||
r=(y_val+249*i_val+159*q_val)>>16;
|
||||
g=(y_val-70*i_val-166*q_val)>>16;
|
||||
b=(y_val-283*i_val+436*q_val)>>16;
|
||||
r = (y_val + 249*i_val + 159*q_val) >> 16;
|
||||
g = (y_val - 70*i_val - 166*q_val) >> 16;
|
||||
b = (y_val - 283*i_val + 436*q_val) >> 16;
|
||||
|
||||
y_buf[((c<<1)&6)+1]=ntsc_col[buffer->line[displine][c]&7][((c<<1)&6)+1]?0x6000:0;
|
||||
y_buf[((c<<1)&6)+1]+=(buffer->line[displine][c]&8)?0x3000:0;
|
||||
i_buf[((c<<1)&6)+1]=y_buf[((c<<1)&6)+1]*i_filt[((c<<1)&6)+1];
|
||||
q_buf[((c<<1)&6)+1]=y_buf[((c<<1)&6)+1]*q_filt[((c<<1)&6)+1];
|
||||
y_tot=y_buf[0]+y_buf[1]+y_buf[2]+y_buf[3]+y_buf[4]+y_buf[5]+y_buf[6]+y_buf[7];
|
||||
i_tot=i_buf[0]+i_buf[1]+i_buf[2]+i_buf[3]+i_buf[4]+i_buf[5]+i_buf[6]+i_buf[7];
|
||||
q_tot=q_buf[0]+q_buf[1]+q_buf[2]+q_buf[3]+q_buf[4]+q_buf[5]+q_buf[6]+q_buf[7];
|
||||
y_buf[((c << 1) & 6) + 1] = ntsc_col[buffer->line[cga->displine][c] & 7][((c << 1) & 6) + 1] ? 0x6000 : 0;
|
||||
y_buf[((c << 1) & 6) + 1] += (buffer->line[cga->displine][c] & 8) ? 0x3000 : 0;
|
||||
i_buf[((c << 1) & 6) + 1] = y_buf[((c << 1) & 6) + 1] * i_filt[((c << 1) & 6) + 1];
|
||||
q_buf[((c << 1) & 6) + 1] = y_buf[((c << 1) & 6) + 1] * q_filt[((c << 1) & 6) + 1];
|
||||
y_tot = y_buf[0] + y_buf[1] + y_buf[2] + y_buf[3] + y_buf[4] + y_buf[5] + y_buf[6] + y_buf[7];
|
||||
i_tot = i_buf[0] + i_buf[1] + i_buf[2] + i_buf[3] + i_buf[4] + i_buf[5] + i_buf[6] + i_buf[7];
|
||||
q_tot = q_buf[0] + q_buf[1] + q_buf[2] + q_buf[3] + q_buf[4] + q_buf[5] + q_buf[6] + q_buf[7];
|
||||
|
||||
y_val=y_tot>>10;
|
||||
if (y_val>255) y_val=255;
|
||||
y_val<<=16;
|
||||
i_val=i_tot>>12;
|
||||
if (i_val>39041) i_val=39041;
|
||||
if (i_val<-39041) i_val=-39041;
|
||||
q_val=q_tot>>12;
|
||||
if (q_val>34249) q_val=34249;
|
||||
if (q_val<-34249) q_val=-34249;
|
||||
y_val = y_tot >> 10;
|
||||
if (y_val > 255) y_val = 255;
|
||||
y_val <<= 16;
|
||||
i_val = i_tot >> 12;
|
||||
if (i_val > 39041) i_val = 39041;
|
||||
if (i_val < -39041) i_val = -39041;
|
||||
q_val = q_tot >> 12;
|
||||
if (q_val > 34249) q_val = 34249;
|
||||
if (q_val < -34249) q_val = -34249;
|
||||
|
||||
r+=(y_val+249*i_val+159*q_val)>>16;
|
||||
g+=(y_val-70*i_val-166*q_val)>>16;
|
||||
b+=(y_val-283*i_val+436*q_val)>>16;
|
||||
if (r>511) r=511;
|
||||
if (g>511) g=511;
|
||||
if (b>511) b=511;
|
||||
r = (y_val + 249*i_val + 159*q_val) >> 16;
|
||||
g = (y_val - 70*i_val - 166*q_val) >> 16;
|
||||
b = (y_val - 283*i_val + 436*q_val) >> 16;
|
||||
if (r > 511) r = 511;
|
||||
if (g > 511) g = 511;
|
||||
if (b > 511) b = 511;
|
||||
|
||||
((uint32_t *)buffer32->line[displine])[c]=makecol32(r/2,g/2,b/2);
|
||||
((uint32_t *)buffer32->line[cga->displine])[c] = makecol32(r / 2, g / 2, b / 2);
|
||||
}
|
||||
}
|
||||
|
||||
sc=oldsc;
|
||||
if (vc==crtc[7] && !sc)
|
||||
cgastat|=8;
|
||||
displine++;
|
||||
if (displine>=360) displine=0;
|
||||
cga->sc = oldsc;
|
||||
if (cga->vc == cga->crtc[7] && !cga->sc)
|
||||
cga->cgastat |= 8;
|
||||
cga->displine++;
|
||||
if (cga->displine >= 360)
|
||||
cga->displine = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vidtime+=dispontime;
|
||||
if (cgadispon) cgastat&=~1;
|
||||
linepos=0;
|
||||
if (vsynctime)
|
||||
cga->vidtime += cga->dispontime;
|
||||
if (cga->cgadispon) cga->cgastat &= ~1;
|
||||
cga->linepos = 0;
|
||||
if (cga->vsynctime)
|
||||
{
|
||||
vsynctime--;
|
||||
if (!vsynctime)
|
||||
cgastat&=~8;
|
||||
cga->vsynctime--;
|
||||
if (!cga->vsynctime)
|
||||
cga->cgastat &= ~8;
|
||||
}
|
||||
if (sc==(crtc[11]&31) || ((crtc[8]&3)==3 && sc==((crtc[11]&31)>>1))) { con=0; coff=1; }
|
||||
if ((crtc[8] & 3) == 3 && sc == (crtc[9] >> 1))
|
||||
maback = ma;
|
||||
if (vadj)
|
||||
if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[11] & 31) >> 1)))
|
||||
{
|
||||
cga->con = 0;
|
||||
cga->coff = 1;
|
||||
}
|
||||
if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1))
|
||||
cga->maback = cga->ma;
|
||||
if (cga->vadj)
|
||||
{
|
||||
sc++;
|
||||
sc&=31;
|
||||
ma=maback;
|
||||
vadj--;
|
||||
if (!vadj)
|
||||
cga->sc++;
|
||||
cga->sc &= 31;
|
||||
cga->ma = cga->maback;
|
||||
cga->vadj--;
|
||||
if (!cga->vadj)
|
||||
{
|
||||
cgadispon=1;
|
||||
ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
|
||||
sc=0;
|
||||
cga->cgadispon = 1;
|
||||
cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff;
|
||||
cga->sc = 0;
|
||||
}
|
||||
}
|
||||
else if (sc==crtc[9])
|
||||
else if (cga->sc == cga->crtc[9])
|
||||
{
|
||||
maback=ma;
|
||||
sc=0;
|
||||
oldvc=vc;
|
||||
vc++;
|
||||
vc&=127;
|
||||
cga->maback = cga->ma;
|
||||
cga->sc = 0;
|
||||
oldvc = cga->vc;
|
||||
cga->vc++;
|
||||
cga->vc &= 127;
|
||||
|
||||
if (vc==crtc[6]) cgadispon=0;
|
||||
if (cga->vc == cga->crtc[6])
|
||||
cga->cgadispon = 0;
|
||||
|
||||
if (oldvc==crtc[4])
|
||||
if (oldvc == cga->crtc[4])
|
||||
{
|
||||
vc=0;
|
||||
vadj=crtc[5];
|
||||
if (!vadj) cgadispon=1;
|
||||
if (!vadj) ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
|
||||
if ((crtc[10]&0x60)==0x20) cursoron=0;
|
||||
else cursoron=cgablink&8;
|
||||
cga->vc = 0;
|
||||
cga->vadj = cga->crtc[5];
|
||||
if (!cga->vadj) cga->cgadispon = 1;
|
||||
if (!cga->vadj) cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff;
|
||||
if ((cga->crtc[10] & 0x60) == 0x20) cga->cursoron = 0;
|
||||
else cga->cursoron = cga->cgablink & 8;
|
||||
}
|
||||
|
||||
if (vc==crtc[7])
|
||||
if (cga->vc == cga->crtc[7])
|
||||
{
|
||||
cgadispon=0;
|
||||
displine=0;
|
||||
vsynctime=(crtc[3]>>4)+1;
|
||||
if (crtc[7])
|
||||
cga->cgadispon = 0;
|
||||
cga->displine = 0;
|
||||
cga->vsynctime = (cga->crtc[3] >> 4) + 1;
|
||||
if (cga->crtc[7])
|
||||
{
|
||||
if (cgamode&1) x=(crtc[1]<<3)+16;
|
||||
else x=(crtc[1]<<4)+16;
|
||||
lastline++;
|
||||
if (x!=xsize || (lastline-firstline)!=ysize)
|
||||
if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16;
|
||||
else x = (cga->crtc[1] << 4) + 16;
|
||||
cga->lastline++;
|
||||
if (x != xsize || (cga->lastline - cga->firstline) != ysize)
|
||||
{
|
||||
xsize=x;
|
||||
ysize=lastline-firstline;
|
||||
if (xsize<64) xsize=656;
|
||||
if (ysize<32) ysize=200;
|
||||
updatewindowsize(xsize,(ysize<<1)+16);
|
||||
xsize = x;
|
||||
ysize = cga->lastline - cga->firstline;
|
||||
if (xsize < 64) xsize = 656;
|
||||
if (ysize < 32) ysize = 200;
|
||||
updatewindowsize(xsize, (ysize << 1) + 16);
|
||||
}
|
||||
|
||||
startblit();
|
||||
if (cga_comp)
|
||||
video_blit_memtoscreen(0, firstline-4, 0, (lastline-firstline)+8, xsize, (lastline-firstline)+8);
|
||||
video_blit_memtoscreen(0, cga->firstline - 4, 0, (cga->lastline - cga->firstline) + 8, xsize, (cga->lastline - cga->firstline) + 8);
|
||||
else
|
||||
video_blit_memtoscreen_8(0, firstline-4, xsize, (lastline-firstline)+8);
|
||||
if (readflash) rectfill(screen,winsizex-40,8,winsizex-8,14,0xFFFFFFFF);
|
||||
readflash=0;
|
||||
video_blit_memtoscreen_8(0, cga->firstline - 4, xsize, (cga->lastline - cga->firstline) + 8);
|
||||
if (readflash) rectfill(screen, winsizex - 40, 8, winsizex - 8, 14, 0xffffffff);
|
||||
readflash = 0;
|
||||
frames++;
|
||||
endblit();
|
||||
video_res_x = xsize - 16;
|
||||
video_res_y = ysize;
|
||||
if (cgamode & 1)
|
||||
if (cga->cgamode & 1)
|
||||
{
|
||||
video_res_x /= 8;
|
||||
video_res_y /= crtc[9] + 1;
|
||||
video_res_y /= cga->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
}
|
||||
else if (!(cgamode & 2))
|
||||
else if (!(cga->cgamode & 2))
|
||||
{
|
||||
video_res_x /= 16;
|
||||
video_res_y /= crtc[9] + 1;
|
||||
video_res_y /= cga->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
}
|
||||
else if (!(cgamode&16))
|
||||
else if (!(cga->cgamode & 16))
|
||||
{
|
||||
video_res_x /= 2;
|
||||
video_bpp = 2;
|
||||
|
|
@ -446,59 +456,72 @@ endblit();
|
|||
video_bpp = 1;
|
||||
}
|
||||
}
|
||||
firstline=1000;
|
||||
lastline=0;
|
||||
cgablink++;
|
||||
oddeven ^= 1;
|
||||
cga->firstline = 1000;
|
||||
cga->lastline = 0;
|
||||
cga->cgablink++;
|
||||
cga->oddeven ^= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sc++;
|
||||
sc&=31;
|
||||
ma=maback;
|
||||
cga->sc++;
|
||||
cga->sc &= 31;
|
||||
cga->ma = cga->maback;
|
||||
}
|
||||
if ((sc==(crtc[10]&31) || ((crtc[8]&3)==3 && sc==((crtc[10]&31)>>1)))) con=1;
|
||||
if (cgadispon && (cgamode&1))
|
||||
if ((cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1))))
|
||||
cga->con = 1;
|
||||
if (cga->cgadispon && (cga->cgamode & 1))
|
||||
{
|
||||
for (x=0;x<(crtc[1]<<1);x++)
|
||||
charbuffer[x]=vram[(((ma<<1)+x)&0x3FFF)];
|
||||
for (x = 0; x < (cga->crtc[1] << 1); x++)
|
||||
cga->charbuffer[x] = cga->vram[(((cga->ma << 1) + x) & 0x3fff)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cga_init(cga_t *cga)
|
||||
{
|
||||
}
|
||||
|
||||
int cga_init()
|
||||
void *cga_standalone_init()
|
||||
{
|
||||
int c;
|
||||
int cga_tint = -2;
|
||||
for (c=0;c<8;c++)
|
||||
cga_t *cga = malloc(sizeof(cga_t));
|
||||
memset(cga, 0, sizeof(cga_t));
|
||||
|
||||
cga->vram = malloc(0x4000);
|
||||
|
||||
for (c = 0; c < 8; c++)
|
||||
{
|
||||
i_filt[c]=512.0*cos((3.14*(cga_tint+c*4)/16.0) - 33.0/180.0);
|
||||
q_filt[c]=512.0*sin((3.14*(cga_tint+c*4)/16.0) - 33.0/180.0);
|
||||
i_filt[c] = 512.0 * cos((3.14 * (cga_tint + c * 4) / 16.0) - 33.0 / 180.0);
|
||||
q_filt[c] = 512.0 * sin((3.14 * (cga_tint + c * 4) / 16.0) - 33.0 / 180.0);
|
||||
}
|
||||
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL);
|
||||
return 0;
|
||||
timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga);
|
||||
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, cga);
|
||||
io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga);
|
||||
return cga;
|
||||
}
|
||||
|
||||
GFXCARD vid_cga =
|
||||
void cga_close(void *p)
|
||||
{
|
||||
cga_init,
|
||||
/*IO at 3Cx/3Dx*/
|
||||
cga_out,
|
||||
cga_in,
|
||||
/*IO at 3Ax/3Bx*/
|
||||
video_out_null,
|
||||
video_in_null,
|
||||
cga_t *cga = (cga_t *)p;
|
||||
|
||||
cga_poll,
|
||||
cga_recalctimings,
|
||||
free(cga->vram);
|
||||
free(cga);
|
||||
}
|
||||
|
||||
video_write_null,
|
||||
video_write_null,
|
||||
cga_write,
|
||||
void cga_speed_changed(void *p)
|
||||
{
|
||||
cga_t *cga = (cga_t *)p;
|
||||
|
||||
cga_recalctimings(cga);
|
||||
}
|
||||
|
||||
video_read_null,
|
||||
video_read_null,
|
||||
cga_read
|
||||
device_t cga_device =
|
||||
{
|
||||
"CGA",
|
||||
cga_standalone_init,
|
||||
cga_close,
|
||||
cga_speed_changed,
|
||||
NULL
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,38 @@
|
|||
int cga_init();
|
||||
void cga_out(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t cga_in(uint16_t addr, void *priv);
|
||||
void cga_poll();
|
||||
void cga_write(uint32_t addr, uint8_t val, void *priv);
|
||||
uint8_t cga_read(uint32_t addr, void *priv);
|
||||
void cga_recalctimings();
|
||||
typedef struct cga_t
|
||||
{
|
||||
int crtcreg;
|
||||
uint8_t crtc[32];
|
||||
|
||||
uint8_t cgastat;
|
||||
|
||||
uint8_t cgamode, cgacol;
|
||||
|
||||
int linepos, displine;
|
||||
int sc, vc;
|
||||
int cgadispon;
|
||||
int con, coff, cursoron, cgablink;
|
||||
int vsynctime, vadj;
|
||||
uint16_t ma, maback;
|
||||
int oddeven;
|
||||
|
||||
int dispontime, dispofftime;
|
||||
int vidtime;
|
||||
|
||||
int firstline, lastline;
|
||||
|
||||
int drawcursor;
|
||||
|
||||
uint8_t *vram;
|
||||
|
||||
uint8_t charbuffer[256];
|
||||
} cga_t;
|
||||
|
||||
void cga_init(cga_t *cga);
|
||||
void cga_out(uint16_t addr, uint8_t val, void *p);
|
||||
uint8_t cga_in(uint16_t addr, void *p);
|
||||
void cga_write(uint32_t addr, uint8_t val, void *p);
|
||||
uint8_t cga_read(uint32_t addr, void *p);
|
||||
void cga_recalctimings(cga_t *cga);
|
||||
void cga_poll(void *p);
|
||||
|
||||
extern device_t cga_device;
|
||||
|
|
|
|||
772
src/vid_cl5429.c
772
src/vid_cl5429.c
File diff suppressed because it is too large
Load diff
1
src/vid_cl5429.h
Normal file
1
src/vid_cl5429.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
extern device_t gd5429_device;
|
||||
1040
src/vid_ega.c
1040
src/vid_ega.c
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +1,71 @@
|
|||
int ega_init();
|
||||
void ega_out(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t ega_in(uint16_t addr, void *priv);
|
||||
void ega_poll();
|
||||
void ega_recalctimings();
|
||||
void ega_write(uint32_t addr, uint8_t val, void *priv);
|
||||
uint8_t ega_read(uint32_t addr, void *priv);
|
||||
typedef struct ega_t
|
||||
{
|
||||
uint8_t crtcreg;
|
||||
uint8_t crtc[32];
|
||||
uint8_t gdcreg[16];
|
||||
int gdcaddr;
|
||||
uint8_t attrregs[32];
|
||||
int attraddr, attrff;
|
||||
uint8_t seqregs[64];
|
||||
int seqaddr;
|
||||
|
||||
uint8_t miscout;
|
||||
int vidclock;
|
||||
|
||||
uint8_t la, lb, lc, ld;
|
||||
|
||||
uint8_t stat;
|
||||
|
||||
int fast;
|
||||
uint8_t colourcompare, colournocare;
|
||||
int readmode, writemode, readplane;
|
||||
int chain4;
|
||||
uint8_t writemask;
|
||||
uint32_t charseta, charsetb;
|
||||
|
||||
uint8_t egapal[16];
|
||||
uint32_t *pallook;
|
||||
|
||||
int vtotal, dispend, vsyncstart, split;
|
||||
int hdisp, htotal, hdisp_time, rowoffset;
|
||||
int lowres, interlace;
|
||||
int linedbl, rowcount;
|
||||
double clock;
|
||||
uint32_t ma_latch;
|
||||
|
||||
int vres;
|
||||
|
||||
int dispontime, dispofftime;
|
||||
int vidtime;
|
||||
|
||||
uint8_t scrblank;
|
||||
|
||||
int dispon;
|
||||
int hdisp_on;
|
||||
|
||||
uint32_t ma, maback, ca;
|
||||
int vc;
|
||||
int sc;
|
||||
int linepos, vslines, linecountff, oddeven;
|
||||
int con, cursoron, blink;
|
||||
int scrollcache;
|
||||
|
||||
int firstline, lastline;
|
||||
int firstline_draw, lastline_draw;
|
||||
int displine;
|
||||
|
||||
uint8_t *vram;
|
||||
int vrammask;
|
||||
|
||||
int video_res_x, video_res_y, video_bpp;
|
||||
} ega_t;
|
||||
|
||||
void *ega_standalone_init();
|
||||
void ega_out(uint16_t addr, uint8_t val, void *p);
|
||||
uint8_t ega_in(uint16_t addr, void *p);
|
||||
void ega_poll(void *p);
|
||||
void ega_recalctimings(struct ega_t *ega);
|
||||
void ega_write(uint32_t addr, uint8_t val, void *p);
|
||||
uint8_t ega_read(uint32_t addr, void *p);
|
||||
|
||||
extern device_t ega_device;
|
||||
|
|
|
|||
167
src/vid_et4000.c
167
src/vid_et4000.c
|
|
@ -1,141 +1,156 @@
|
|||
/*ET4000 emulation*/
|
||||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "io.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_unk_ramdac.h"
|
||||
|
||||
int et4k_b8000;
|
||||
#include "vid_et4000.h"
|
||||
|
||||
|
||||
void et4000_out(uint16_t addr, uint8_t val, void *priv)
|
||||
typedef struct et4000_t
|
||||
{
|
||||
svga_t svga;
|
||||
unk_ramdac_t ramdac;
|
||||
|
||||
uint8_t banking;
|
||||
} et4000_t;
|
||||
|
||||
void et4000_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
et4000_t *et4000 = (et4000_t *)p;
|
||||
svga_t *svga = &et4000->svga;
|
||||
|
||||
uint8_t old;
|
||||
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
pclog("ET4000 out %04X %02X\n", addr, val);
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
unk_ramdac_out(addr, val, NULL);
|
||||
unk_ramdac_out(addr, val, &et4000->ramdac, svga);
|
||||
return;
|
||||
|
||||
case 0x3CD: /*Banking*/
|
||||
svgawbank=(val&0xF)*65536;
|
||||
svgarbank=((val>>4)&0xF)*65536;
|
||||
svgaseg=val;
|
||||
pclog("Banking write %08X %08X %02X\n", svgawbank, svgarbank, val);
|
||||
svga->write_bank = (val & 0xf) * 0x10000;
|
||||
svga->read_bank = ((val >> 4) & 0xf) * 0x10000;
|
||||
et4000->banking = val;
|
||||
pclog("Banking write %08X %08X %02X\n", svga->write_bank, svga->read_bank, val);
|
||||
return;
|
||||
case 0x3CF:
|
||||
switch (gdcaddr&15)
|
||||
{
|
||||
case 6:
|
||||
et4k_b8000=((crtc[0x36]&0x38)==0x28) && ((gdcreg[6]&0xC)==4);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x3D4:
|
||||
crtcreg = val & 0x3f;
|
||||
svga->crtcreg = val & 0x3f;
|
||||
return;
|
||||
case 0x3D5:
|
||||
if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
|
||||
old=crtc[crtcreg];
|
||||
crtc[crtcreg]=val;
|
||||
et4k_b8000=((crtc[0x36]&0x38)==0x28) && ((gdcreg[6]&0xC)==4);
|
||||
if (old!=val)
|
||||
if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
if (old != val)
|
||||
{
|
||||
if (crtcreg<0xE || crtcreg>0x10)
|
||||
if (svga->crtcreg < 0xE || svga->crtcreg > 0x10)
|
||||
{
|
||||
fullchange=changeframecount;
|
||||
svga_recalctimings();
|
||||
fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x3D8:
|
||||
if (val==0xA0) svgaon=1;
|
||||
if (val==0x29) svgaon=0;
|
||||
break;
|
||||
}
|
||||
svga_out(addr, val, priv);
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
uint8_t et4000_in(uint16_t addr, void *priv)
|
||||
uint8_t et4000_in(uint16_t addr, void *p)
|
||||
{
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
et4000_t *et4000 = (et4000_t *)p;
|
||||
svga_t *svga = &et4000->svga;
|
||||
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
if (addr != 0x3da) pclog("IN ET4000 %04X\n", addr);
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3C5:
|
||||
if ((seqaddr&0xF)==7) return seqregs[seqaddr&0xF]|4;
|
||||
if ((svga->seqaddr & 0xf) == 7) return svga->seqregs[svga->seqaddr & 0xf] | 4;
|
||||
break;
|
||||
|
||||
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
return unk_ramdac_in(addr, NULL);
|
||||
return unk_ramdac_in(addr, &et4000->ramdac, svga);
|
||||
|
||||
case 0x3CD: /*Banking*/
|
||||
return svgaseg;
|
||||
return et4000->banking;
|
||||
case 0x3D4:
|
||||
return crtcreg;
|
||||
return svga->crtcreg;
|
||||
case 0x3D5:
|
||||
return crtc[crtcreg];
|
||||
return svga->crtc[svga->crtcreg];
|
||||
}
|
||||
return svga_in(addr, priv);
|
||||
return svga_in(addr, svga);
|
||||
}
|
||||
|
||||
void et4000_recalctimings()
|
||||
void et4000_recalctimings(svga_t *svga)
|
||||
{
|
||||
svga_ma|=(crtc[0x33]&3)<<16;
|
||||
if (crtc[0x35]&2) svga_vtotal+=0x400;
|
||||
if (crtc[0x35]&4) svga_dispend+=0x400;
|
||||
if (crtc[0x35]&8) svga_vsyncstart+=0x400;
|
||||
if (crtc[0x35]&0x10) svga_split+=0x400;
|
||||
if (!svga_rowoffset) svga_rowoffset=0x100;
|
||||
// if (crtc[0x3F]&0x80) svga_rowoffset+=0x100;
|
||||
if (crtc[0x3F]&1) svga_htotal+=256;
|
||||
if (attrregs[0x16]&0x20) svga_hdisp<<=1;
|
||||
et4000_t *et4000 = (et4000_t *)svga->p;
|
||||
|
||||
svga->ma_latch |= (svga->crtc[0x33]&3)<<16;
|
||||
if (svga->crtc[0x35] & 2) svga->vtotal += 0x400;
|
||||
if (svga->crtc[0x35] & 4) svga->dispend += 0x400;
|
||||
if (svga->crtc[0x35] & 8) svga->vsyncstart += 0x400;
|
||||
if (svga->crtc[0x35] & 0x10) svga->split += 0x400;
|
||||
if (!svga->rowoffset) svga->rowoffset = 0x100;
|
||||
if (svga->crtc[0x3f] & 1) svga->htotal += 256;
|
||||
if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1;
|
||||
|
||||
// pclog("Rowoffset %i\n",svga_rowoffset);
|
||||
|
||||
switch (((svga_miscout >> 2) & 3) | ((crtc[0x34] << 1) & 4))
|
||||
switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4))
|
||||
{
|
||||
case 0: case 1: break;
|
||||
case 3: svga_clock = cpuclock/40000000.0; break;
|
||||
case 5: svga_clock = cpuclock/65000000.0; break;
|
||||
default: svga_clock = cpuclock/36000000.0; break;
|
||||
case 3: svga->clock = cpuclock / 40000000.0; break;
|
||||
case 5: svga->clock = cpuclock / 65000000.0; break;
|
||||
default: svga->clock = cpuclock / 36000000.0; break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int et4000_init()
|
||||
void *et4000_init()
|
||||
{
|
||||
svga_recalctimings_ex = et4000_recalctimings;
|
||||
svga_vram_limit = 1 << 20; /*1mb*/
|
||||
vrammask = 0xfffff;
|
||||
return svga_init();
|
||||
et4000_t *et4000 = malloc(sizeof(et4000_t));
|
||||
memset(et4000, 0, sizeof(et4000_t));
|
||||
|
||||
io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000);
|
||||
|
||||
svga_init(&et4000->svga, et4000, 1 << 20, /*1mb*/
|
||||
et4000_recalctimings,
|
||||
et4000_in, et4000_out,
|
||||
NULL);
|
||||
|
||||
return et4000;
|
||||
}
|
||||
|
||||
GFXCARD vid_et4000 =
|
||||
void et4000_close(void *p)
|
||||
{
|
||||
et4000_t *et4000 = (et4000_t *)p;
|
||||
|
||||
svga_close(&et4000->svga);
|
||||
|
||||
free(et4000);
|
||||
}
|
||||
|
||||
void et4000_speed_changed(void *p)
|
||||
{
|
||||
et4000_t *et4000 = (et4000_t *)p;
|
||||
|
||||
svga_recalctimings(&et4000->svga);
|
||||
}
|
||||
|
||||
device_t et4000_device =
|
||||
{
|
||||
"Tseng Labs ET4000AX",
|
||||
et4000_init,
|
||||
/*IO at 3Cx/3Dx*/
|
||||
et4000_out,
|
||||
et4000_in,
|
||||
/*IO at 3Ax/3Bx*/
|
||||
video_out_null,
|
||||
video_in_null,
|
||||
|
||||
svga_poll,
|
||||
svga_recalctimings,
|
||||
|
||||
svga_write,
|
||||
video_write_null,
|
||||
video_write_null,
|
||||
|
||||
svga_read,
|
||||
video_read_null,
|
||||
video_read_null
|
||||
et4000_close,
|
||||
et4000_speed_changed,
|
||||
svga_add_status_info
|
||||
};
|
||||
|
|
|
|||
1
src/vid_et4000.h
Normal file
1
src/vid_et4000.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
extern device_t et4000_device;
|
||||
1147
src/vid_et4000w32.c
1147
src/vid_et4000w32.c
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1 @@
|
|||
extern device_t et4000w32p_device;
|
||||
|
|
@ -1,296 +1,358 @@
|
|||
/*Hercules emulation*/
|
||||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "mem.h"
|
||||
#include "timer.h"
|
||||
#include "video.h"
|
||||
#include "vid_hercules.h"
|
||||
|
||||
void hercules_recalctimings();
|
||||
void hercules_write(uint32_t addr, uint8_t val, void *priv);
|
||||
uint8_t hercules_read(uint32_t addr, void *priv);
|
||||
|
||||
static uint8_t hercules_ctrl, hercules_ctrl2, hercules_stat;
|
||||
uint8_t crtcm[32],crtcmreg;
|
||||
|
||||
void hercules_out(uint16_t addr, uint8_t val, void *priv)
|
||||
typedef struct hercules_t
|
||||
{
|
||||
uint8_t crtc[32];
|
||||
int crtcreg;
|
||||
|
||||
uint8_t ctrl, ctrl2, stat;
|
||||
|
||||
int dispontime, dispofftime;
|
||||
int vidtime;
|
||||
|
||||
int firstline, lastline;
|
||||
|
||||
int linepos, displine;
|
||||
int vc, sc;
|
||||
uint16_t ma, maback;
|
||||
int con, coff, cursoron;
|
||||
int dispon, blink;
|
||||
int vsynctime, vadj;
|
||||
|
||||
uint8_t *vram;
|
||||
} hercules_t;
|
||||
|
||||
static int mdacols[256][2][2];
|
||||
|
||||
void hercules_recalctimings(hercules_t *hercules);
|
||||
void hercules_write(uint32_t addr, uint8_t val, void *p);
|
||||
uint8_t hercules_read(uint32_t addr, void *p);
|
||||
|
||||
|
||||
void hercules_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
hercules_t *hercules = (hercules_t *)p;
|
||||
// pclog("Herc out %04X %02X\n",addr,val);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3B0: case 0x3B2: case 0x3B4: case 0x3B6:
|
||||
crtcmreg = val & 31;
|
||||
case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6:
|
||||
hercules->crtcreg = val & 31;
|
||||
return;
|
||||
case 0x3B1: case 0x3B3: case 0x3B5: case 0x3B7:
|
||||
crtcm[crtcmreg] = val;
|
||||
if (crtcm[10]==6 && crtcm[11]==7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/
|
||||
case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7:
|
||||
hercules->crtc[hercules->crtcreg] = val;
|
||||
if (hercules->crtc[10] == 6 && hercules->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/
|
||||
{
|
||||
crtcm[10]=0xB;
|
||||
crtcm[11]=0xC;
|
||||
hercules->crtc[10] = 0xb;
|
||||
hercules->crtc[11] = 0xc;
|
||||
}
|
||||
hercules_recalctimings();
|
||||
hercules_recalctimings(hercules);
|
||||
return;
|
||||
case 0x3B8:
|
||||
hercules_ctrl = val;
|
||||
case 0x3b8:
|
||||
hercules->ctrl = val;
|
||||
return;
|
||||
case 0x3BF:
|
||||
hercules_ctrl2 = val;
|
||||
video_write_b800 = (val&2) ? hercules_write : video_write_null;
|
||||
video_read_b800 = (val&2) ? hercules_read : video_read_null;
|
||||
case 0x3bf:
|
||||
hercules->ctrl2 = val;
|
||||
mem_removehandler(0xb8000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, hercules);
|
||||
if (val & 2)
|
||||
mem_sethandler(0xb8000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, hercules);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t hercules_in(uint16_t addr, void *priv)
|
||||
uint8_t hercules_in(uint16_t addr, void *p)
|
||||
{
|
||||
hercules_t *hercules = (hercules_t *)p;
|
||||
// pclog("Herc in %04X %02X %04X:%04X %04X\n",addr,(hercules_stat & 0xF) | ((hercules_stat & 8) << 4),CS,pc,CX);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3B0: case 0x3B2: case 0x3B4: case 0x3B6:
|
||||
return crtcmreg;
|
||||
case 0x3B1: case 0x3B3: case 0x3B5: case 0x3B7:
|
||||
return crtcm[crtcmreg];
|
||||
case 0x3BA:
|
||||
return (hercules_stat & 0xF) | ((hercules_stat & 8) << 4);
|
||||
case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6:
|
||||
return hercules->crtcreg;
|
||||
case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7:
|
||||
return hercules->crtc[hercules->crtcreg];
|
||||
case 0x3ba:
|
||||
return (hercules->stat & 0xf) | ((hercules->stat & 8) << 4);
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
void hercules_write(uint32_t addr, uint8_t val, void *priv)
|
||||
void hercules_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
hercules_t *hercules = (hercules_t *)p;
|
||||
// pclog("Herc write %08X %02X\n",addr,val);
|
||||
vram[addr&0xFFFF]=val;
|
||||
hercules->vram[addr & 0xffff] = val;
|
||||
}
|
||||
|
||||
uint8_t hercules_read(uint32_t addr, void *priv)
|
||||
uint8_t hercules_read(uint32_t addr, void *p)
|
||||
{
|
||||
return vram[addr&0xFFFF];
|
||||
hercules_t *hercules = (hercules_t *)p;
|
||||
return hercules->vram[addr & 0xffff];
|
||||
}
|
||||
|
||||
void hercules_recalctimings()
|
||||
void hercules_recalctimings(hercules_t *hercules)
|
||||
{
|
||||
double disptime;
|
||||
double _dispontime, _dispofftime;
|
||||
disptime=crtc[0]+1;
|
||||
_dispontime=crtc[1];
|
||||
_dispofftime=disptime-_dispontime;
|
||||
_dispontime*=MDACONST;
|
||||
_dispofftime*=MDACONST;
|
||||
dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||
dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
disptime = hercules->crtc[0] + 1;
|
||||
_dispontime = hercules->crtc[1];
|
||||
_dispofftime = disptime - _dispontime;
|
||||
_dispontime *= MDACONST;
|
||||
_dispofftime *= MDACONST;
|
||||
hercules->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||
hercules->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
}
|
||||
|
||||
int mdacols[256][2][2];
|
||||
|
||||
static int linepos,displine;
|
||||
static int vc,sc;
|
||||
static uint16_t ma,maback;
|
||||
static int con,coff,cursoron;
|
||||
static int cgadispon,cgablink;
|
||||
static int vsynctime,vadj;
|
||||
|
||||
void hercules_poll()
|
||||
void hercules_poll(void *p)
|
||||
{
|
||||
uint16_t ca=(crtcm[15]|(crtcm[14]<<8))&0x3FFF;
|
||||
hercules_t *hercules = (hercules_t *)p;
|
||||
uint16_t ca = (hercules->crtc[15] | (hercules->crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x,c;
|
||||
int x, c;
|
||||
int oldvc;
|
||||
uint8_t chr,attr;
|
||||
uint8_t chr, attr;
|
||||
uint16_t dat;
|
||||
int cols[4];
|
||||
int oldsc;
|
||||
int blink;
|
||||
if (!linepos)
|
||||
if (!hercules->linepos)
|
||||
{
|
||||
//pclog("Poll %i %i\n",vc,sc);
|
||||
vidtime+=dispofftime;
|
||||
hercules_stat|=1;
|
||||
linepos=1;
|
||||
oldsc=sc;
|
||||
if ((crtcm[8]&3)==3) sc=(sc<<1)&7;
|
||||
if (cgadispon)
|
||||
hercules->vidtime += hercules->dispofftime;
|
||||
hercules->stat |= 1;
|
||||
hercules->linepos = 1;
|
||||
oldsc = hercules->sc;
|
||||
if ((hercules->crtc[8] & 3) == 3)
|
||||
hercules->sc = (hercules->sc << 1) & 7;
|
||||
if (hercules->dispon)
|
||||
{
|
||||
if (displine<firstline)
|
||||
if (hercules->displine < hercules->firstline)
|
||||
{
|
||||
firstline=displine;
|
||||
hercules->firstline = hercules->displine;
|
||||
}
|
||||
lastline=displine;
|
||||
cols[0]=0;
|
||||
cols[1]=7;
|
||||
if ((hercules_ctrl & 2) && (hercules_ctrl2 & 1))
|
||||
hercules->lastline = hercules->displine;
|
||||
cols[0] = 0;
|
||||
cols[1] = 7;
|
||||
if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1))
|
||||
{
|
||||
ca=(sc&3)*0x2000;
|
||||
if ((hercules_ctrl & 0x80) && (hercules_ctrl2 & 2)) ca+=0x8000;
|
||||
ca = (hercules->sc & 3) * 0x2000;
|
||||
if ((hercules->ctrl & 0x80) && (hercules->ctrl2 & 2))
|
||||
ca += 0x8000;
|
||||
// printf("Draw herc %04X\n",ca);
|
||||
for (x=0;x<crtcm[1];x++)
|
||||
for (x = 0; x < hercules->crtc[1]; x++)
|
||||
{
|
||||
dat=(vram[((ma<<1)&0x1FFF)+ca]<<8)|vram[((ma<<1)&0x1FFF)+ca+1];
|
||||
ma++;
|
||||
for (c=0;c<16;c++)
|
||||
buffer->line[displine][(x<<4)+c]=(dat&(32768>>c))?7:0;
|
||||
dat = (hercules->vram[((hercules->ma << 1) & 0x1fff) + ca] << 8) | hercules->vram[((hercules->ma << 1) & 0x1fff) + ca + 1];
|
||||
hercules->ma++;
|
||||
for (c = 0; c < 16; c++)
|
||||
buffer->line[hercules->displine][(x << 4) + c] = (dat & (32768 >> c)) ? 7 : 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (x=0;x<crtcm[1];x++)
|
||||
for (x = 0; x < hercules->crtc[1]; x++)
|
||||
{
|
||||
chr=vram[(ma<<1)&0x3FFF];
|
||||
attr=vram[((ma<<1)+1)&0x3FFF];
|
||||
drawcursor=((ma==ca) && con && cursoron);
|
||||
blink=((cgablink&16) && (hercules_ctrl&0x20) && (attr&0x80) && !drawcursor);
|
||||
if (sc==12 && ((attr&7)==1))
|
||||
chr = hercules->vram[(hercules->ma << 1) & 0x3fff];
|
||||
attr = hercules->vram[((hercules->ma << 1) + 1) & 0x3fff];
|
||||
drawcursor = ((hercules->ma == ca) && hercules->con && hercules->cursoron);
|
||||
blink = ((hercules->blink & 16) && (hercules->ctrl & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
if (hercules->sc == 12 && ((attr & 7) == 1))
|
||||
{
|
||||
for (c=0;c<9;c++)
|
||||
buffer->line[displine][(x*9)+c]=mdacols[attr][blink][1];
|
||||
for (c = 0; c < 9; c++)
|
||||
buffer->line[hercules->displine][(x * 9) + c] = mdacols[attr][blink][1];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (c=0;c<8;c++)
|
||||
buffer->line[displine][(x*9)+c]=mdacols[attr][blink][(fontdatm[chr][sc]&(1<<(c^7)))?1:0];
|
||||
if ((chr&~0x1F)==0xC0) buffer->line[displine][(x*9)+8]=mdacols[attr][blink][fontdatm[chr][sc]&1];
|
||||
else buffer->line[displine][(x*9)+8]=mdacols[attr][blink][0];
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer->line[hercules->displine][(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][hercules->sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
if ((chr & ~0x1f) == 0xc0) buffer->line[hercules->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][hercules->sc] & 1];
|
||||
else buffer->line[hercules->displine][(x * 9) + 8] = mdacols[attr][blink][0];
|
||||
}
|
||||
ma++;
|
||||
hercules->ma++;
|
||||
if (drawcursor)
|
||||
{
|
||||
for (c=0;c<9;c++)
|
||||
buffer->line[displine][(x*9)+c]^=mdacols[attr][0][1];
|
||||
for (c = 0; c < 9; c++)
|
||||
buffer->line[hercules->displine][(x * 9) + c] ^= mdacols[attr][0][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sc=oldsc;
|
||||
if (vc==crtcm[7] && !sc)
|
||||
hercules->sc = oldsc;
|
||||
if (hercules->vc == hercules->crtc[7] && !hercules->sc)
|
||||
{
|
||||
hercules_stat|=8;
|
||||
hercules->stat |= 8;
|
||||
// printf("VSYNC on %i %i\n",vc,sc);
|
||||
}
|
||||
displine++;
|
||||
if (displine>=500) displine=0;
|
||||
hercules->displine++;
|
||||
if (hercules->displine >= 500)
|
||||
hercules->displine = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vidtime+=dispontime;
|
||||
if (cgadispon) hercules_stat&=~1;
|
||||
linepos=0;
|
||||
if (vsynctime)
|
||||
hercules->vidtime += hercules->dispontime;
|
||||
if (hercules->dispon)
|
||||
hercules->stat &= ~1;
|
||||
hercules->linepos = 0;
|
||||
if (hercules->vsynctime)
|
||||
{
|
||||
vsynctime--;
|
||||
if (!vsynctime)
|
||||
hercules->vsynctime--;
|
||||
if (!hercules->vsynctime)
|
||||
{
|
||||
hercules_stat&=~8;
|
||||
hercules->stat &= ~8;
|
||||
// printf("VSYNC off %i %i\n",vc,sc);
|
||||
}
|
||||
}
|
||||
if (sc==(crtcm[11]&31) || ((crtcm[8]&3)==3 && sc==((crtcm[11]&31)>>1))) { con=0; coff=1; }
|
||||
if (vadj)
|
||||
if (hercules->sc == (hercules->crtc[11] & 31) || ((hercules->crtc[8] & 3) == 3 && hercules->sc == ((hercules->crtc[11] & 31) >> 1)))
|
||||
{
|
||||
hercules->con = 0;
|
||||
hercules->coff = 1;
|
||||
}
|
||||
if (hercules->vadj)
|
||||
{
|
||||
sc++;
|
||||
sc&=31;
|
||||
ma=maback;
|
||||
vadj--;
|
||||
if (!vadj)
|
||||
hercules->sc++;
|
||||
hercules->sc &= 31;
|
||||
hercules->ma = hercules->maback;
|
||||
hercules->vadj--;
|
||||
if (!hercules->vadj)
|
||||
{
|
||||
cgadispon=1;
|
||||
ma=maback=(crtcm[13]|(crtcm[12]<<8))&0x3FFF;
|
||||
sc=0;
|
||||
hercules->dispon = 1;
|
||||
hercules->ma = hercules->maback = (hercules->crtc[13] | (hercules->crtc[12] << 8)) & 0x3fff;
|
||||
hercules->sc = 0;
|
||||
}
|
||||
}
|
||||
else if (sc==crtcm[9] || ((crtcm[8]&3)==3 && sc==(crtcm[9]>>1)))
|
||||
else if (hercules->sc == hercules->crtc[9] || ((hercules->crtc[8] & 3) == 3 && hercules->sc == (hercules->crtc[9] >> 1)))
|
||||
{
|
||||
maback=ma;
|
||||
sc=0;
|
||||
oldvc=vc;
|
||||
vc++;
|
||||
vc&=127;
|
||||
if (vc==crtcm[6]) cgadispon=0;
|
||||
if (oldvc==crtcm[4])
|
||||
hercules->maback = hercules->ma;
|
||||
hercules->sc = 0;
|
||||
oldvc = hercules->vc;
|
||||
hercules->vc++;
|
||||
hercules->vc &= 127;
|
||||
if (hercules->vc == hercules->crtc[6])
|
||||
hercules->dispon = 0;
|
||||
if (oldvc == hercules->crtc[4])
|
||||
{
|
||||
// printf("Display over at %i\n",displine);
|
||||
vc=0;
|
||||
vadj=crtcm[5];
|
||||
if (!vadj) cgadispon=1;
|
||||
if (!vadj) ma=maback=(crtcm[13]|(crtcm[12]<<8))&0x3FFF;
|
||||
if ((crtcm[10]&0x60)==0x20) cursoron=0;
|
||||
else cursoron=cgablink&16;
|
||||
hercules->vc = 0;
|
||||
hercules->vadj = hercules->crtc[5];
|
||||
if (!hercules->vadj) hercules->dispon=1;
|
||||
if (!hercules->vadj) hercules->ma = hercules->maback = (hercules->crtc[13] | (hercules->crtc[12] << 8)) & 0x3fff;
|
||||
if ((hercules->crtc[10] & 0x60) == 0x20) hercules->cursoron = 0;
|
||||
else hercules->cursoron = hercules->blink & 16;
|
||||
}
|
||||
if (vc==crtcm[7])
|
||||
if (hercules->vc == hercules->crtc[7])
|
||||
{
|
||||
cgadispon=0;
|
||||
displine=0;
|
||||
vsynctime=16;//(crtcm[3]>>4)+1;
|
||||
if (crtcm[7])
|
||||
hercules->dispon = 0;
|
||||
hercules->displine = 0;
|
||||
hercules->vsynctime = 16;//(crtcm[3]>>4)+1;
|
||||
if (hercules->crtc[7])
|
||||
{
|
||||
// printf("Lastline %i Firstline %i %i\n",lastline,firstline,lastline-firstline);
|
||||
if ((hercules_ctrl & 2) && (hercules_ctrl2 & 1)) x = crtcm[1] << 4;
|
||||
else x = crtcm[1] * 9;
|
||||
lastline++;
|
||||
if (x!=xsize || (lastline-firstline)!=ysize)
|
||||
if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1)) x = hercules->crtc[1] << 4;
|
||||
else x = hercules->crtc[1] * 9;
|
||||
hercules->lastline++;
|
||||
if (x != xsize || (hercules->lastline - hercules->firstline) != ysize)
|
||||
{
|
||||
xsize=x;
|
||||
ysize=lastline-firstline;
|
||||
xsize = x;
|
||||
ysize = hercules->lastline - hercules->firstline;
|
||||
// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtcm[1]);
|
||||
if (xsize<64) xsize=656;
|
||||
if (ysize<32) ysize=200;
|
||||
updatewindowsize(xsize,ysize);
|
||||
if (xsize < 64) xsize = 656;
|
||||
if (ysize < 32) ysize = 200;
|
||||
updatewindowsize(xsize, ysize);
|
||||
}
|
||||
startblit();
|
||||
video_blit_memtoscreen_8(0, firstline, xsize, ysize);
|
||||
video_blit_memtoscreen_8(0, hercules->firstline, xsize, ysize);
|
||||
endblit();
|
||||
frames++;
|
||||
if ((hercules_ctrl & 2) && (hercules_ctrl2 & 1))
|
||||
if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1))
|
||||
{
|
||||
video_res_x = crtcm[1] * 16;
|
||||
video_res_y = crtcm[6] * 4;
|
||||
video_res_x = hercules->crtc[1] * 16;
|
||||
video_res_y = hercules->crtc[6] * 4;
|
||||
video_bpp = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
video_res_x = crtcm[1];
|
||||
video_res_y = crtcm[6];
|
||||
video_res_x = hercules->crtc[1];
|
||||
video_res_y = hercules->crtc[6];
|
||||
video_bpp = 0;
|
||||
}
|
||||
}
|
||||
firstline=1000;
|
||||
lastline=0;
|
||||
cgablink++;
|
||||
hercules->firstline = 1000;
|
||||
hercules->lastline = 0;
|
||||
hercules->blink++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sc++;
|
||||
sc&=31;
|
||||
ma=maback;
|
||||
hercules->sc++;
|
||||
hercules->sc &= 31;
|
||||
hercules->ma = hercules->maback;
|
||||
}
|
||||
if ((sc==(crtcm[10]&31) || ((crtcm[8]&3)==3 && sc==((crtcm[10]&31)>>1))))
|
||||
if ((hercules->sc == (hercules->crtc[10] & 31) || ((hercules->crtc[8] & 3) == 3 && hercules->sc == ((hercules->crtc[10] & 31) >> 1))))
|
||||
{
|
||||
con=1;
|
||||
hercules->con = 1;
|
||||
// printf("Cursor on - %02X %02X %02X\n",crtcm[8],crtcm[10],crtcm[11]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int hercules_init()
|
||||
void *hercules_init()
|
||||
{
|
||||
mem_sethandler(0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, NULL);
|
||||
return 0;
|
||||
int c;
|
||||
hercules_t *hercules = malloc(sizeof(hercules_t));
|
||||
memset(hercules, 0, sizeof(hercules_t));
|
||||
|
||||
hercules->vram = malloc(0x10000);
|
||||
|
||||
timer_add(hercules_poll, &hercules->vidtime, TIMER_ALWAYS_ENABLED, hercules);
|
||||
mem_sethandler(0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, hercules);
|
||||
io_sethandler(0x03b0, 0x0010, hercules_in, NULL, NULL, hercules_out, NULL, NULL, hercules);
|
||||
|
||||
for (c = 0; c < 256; c++)
|
||||
{
|
||||
mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16;
|
||||
if (c & 8) mdacols[c][0][1] = 15 + 16;
|
||||
else mdacols[c][0][1] = 7 + 16;
|
||||
}
|
||||
mdacols[0x70][0][1] = 16;
|
||||
mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15;
|
||||
mdacols[0xF0][0][1] = 16;
|
||||
mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15;
|
||||
mdacols[0x78][0][1] = 16 + 7;
|
||||
mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15;
|
||||
mdacols[0xF8][0][1] = 16 + 7;
|
||||
mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15;
|
||||
mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16;
|
||||
mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16;
|
||||
mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16;
|
||||
mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16;
|
||||
|
||||
return hercules;
|
||||
}
|
||||
|
||||
GFXCARD vid_hercules =
|
||||
void hercules_close(void *p)
|
||||
{
|
||||
hercules_t *hercules = (hercules_t *)p;
|
||||
|
||||
free(hercules->vram);
|
||||
free(hercules);
|
||||
}
|
||||
|
||||
void hercules_speed_changed(void *p)
|
||||
{
|
||||
hercules_t *hercules = (hercules_t *)p;
|
||||
|
||||
hercules_recalctimings(hercules);
|
||||
}
|
||||
|
||||
device_t hercules_device =
|
||||
{
|
||||
"Hercules",
|
||||
hercules_init,
|
||||
/*IO at 3Cx/3Dx*/
|
||||
video_out_null,
|
||||
video_in_null,
|
||||
/*IO at 3Ax/3Bx*/
|
||||
hercules_out,
|
||||
hercules_in,
|
||||
|
||||
hercules_poll,
|
||||
hercules_recalctimings,
|
||||
|
||||
video_write_null,
|
||||
hercules_write,
|
||||
video_write_null,
|
||||
|
||||
video_read_null,
|
||||
hercules_read,
|
||||
video_read_null
|
||||
hercules_close,
|
||||
hercules_speed_changed,
|
||||
NULL
|
||||
};
|
||||
|
|
|
|||
1
src/vid_hercules.h
Normal file
1
src/vid_hercules.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
extern device_t hercules_device;
|
||||
|
|
@ -5,70 +5,62 @@
|
|||
#include "ibm.h"
|
||||
#include "vid_icd2061.h"
|
||||
|
||||
static int icd2061_state;
|
||||
static int icd2061_status = 0;
|
||||
static int icd2061_pos = 0;
|
||||
static int icd2061_unlock = 0;
|
||||
static uint32_t icd2061_data;
|
||||
|
||||
static double icd2061_freq[4];
|
||||
static uint32_t icd2061_ctrl;
|
||||
|
||||
void icd2061_write(int val)
|
||||
void icd2061_write(icd2061_t *icd2061, int val)
|
||||
{
|
||||
int q, p, m, i, a;
|
||||
if ((val & 1) && !(icd2061_state & 1))
|
||||
if ((val & 1) && !(icd2061->state & 1))
|
||||
{
|
||||
pclog("ICD2061 write %02X %i %08X %i\n", val, icd2061_unlock, icd2061_data, icd2061_pos);
|
||||
if (!icd2061_status)
|
||||
pclog("ICD2061 write %02X %i %08X %i\n", val, icd2061->unlock, icd2061->data, icd2061->pos);
|
||||
if (!icd2061->status)
|
||||
{
|
||||
if (val & 2) icd2061_unlock++;
|
||||
if (val & 2)
|
||||
icd2061->unlock++;
|
||||
else
|
||||
{
|
||||
if (icd2061_unlock >= 5)
|
||||
if (icd2061->unlock >= 5)
|
||||
{
|
||||
icd2061_status = 1;
|
||||
icd2061_pos = 0;
|
||||
icd2061->status = 1;
|
||||
icd2061->pos = 0;
|
||||
}
|
||||
else
|
||||
icd2061_unlock = 0;
|
||||
icd2061->unlock = 0;
|
||||
}
|
||||
}
|
||||
else if (val & 1)
|
||||
{
|
||||
icd2061_data = (icd2061_data >> 1) | (((val & 2) ? 1 : 0) << 24);
|
||||
icd2061_pos++;
|
||||
if (icd2061_pos == 26)
|
||||
icd2061->data = (icd2061->data >> 1) | (((val & 2) ? 1 : 0) << 24);
|
||||
icd2061->pos++;
|
||||
if (icd2061->pos == 26)
|
||||
{
|
||||
pclog("ICD2061 data - %08X\n", icd2061_data);
|
||||
a = (icd2061_data >> 21) & 0x7;
|
||||
pclog("ICD2061 data - %08X\n", icd2061->data);
|
||||
a = (icd2061->data >> 21) & 0x7;
|
||||
if (!(a & 4))
|
||||
{
|
||||
q = (icd2061_data & 0x7f) - 2;
|
||||
m = 1 << ((icd2061_data >> 7) & 0x7);
|
||||
p = ((icd2061_data >> 10) & 0x7f) - 3;
|
||||
i = (icd2061_data >> 17) & 0xf;
|
||||
q = (icd2061->data & 0x7f) - 2;
|
||||
m = 1 << ((icd2061->data >> 7) & 0x7);
|
||||
p = ((icd2061->data >> 10) & 0x7f) - 3;
|
||||
i = (icd2061->data >> 17) & 0xf;
|
||||
pclog("p %i q %i m %i\n", p, q, m);
|
||||
if (icd2061_ctrl & (1 << a))
|
||||
if (icd2061->ctrl & (1 << a))
|
||||
p <<= 1;
|
||||
icd2061_freq[a] = ((double)p / (double)q) * 2.0 * 14318184.0 / (double)m;
|
||||
pclog("ICD2061 freq %i = %f\n", a, icd2061_freq[a]);
|
||||
icd2061->freq[a] = ((double)p / (double)q) * 2.0 * 14318184.0 / (double)m;
|
||||
pclog("ICD2061 freq %i = %f\n", a, icd2061->freq[a]);
|
||||
}
|
||||
else if (a == 6)
|
||||
{
|
||||
icd2061_ctrl = val;
|
||||
icd2061->ctrl = val;
|
||||
pclog("ICD2061 ctrl = %08X\n", val);
|
||||
}
|
||||
icd2061_unlock = icd2061_data = 0;
|
||||
icd2061_status = 0;
|
||||
icd2061->unlock = icd2061->data = 0;
|
||||
icd2061->status = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
icd2061_state = val;
|
||||
icd2061->state = val;
|
||||
}
|
||||
|
||||
double icd2061_getfreq(int i)
|
||||
double icd2061_getfreq(icd2061_t *icd2061, int i)
|
||||
{
|
||||
pclog("Return freq %f\n", icd2061_freq[i]);
|
||||
return icd2061_freq[i];
|
||||
pclog("Return freq %f\n", icd2061->freq[i]);
|
||||
return icd2061->freq[i];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,14 @@
|
|||
void icd2061_write(int val);
|
||||
double icd2061_getfreq(int i);
|
||||
typedef struct icd2061_t
|
||||
{
|
||||
int state;
|
||||
int status;
|
||||
int pos;
|
||||
int unlock;
|
||||
uint32_t data;
|
||||
|
||||
double freq[4];
|
||||
uint32_t ctrl;
|
||||
} icd2061_t;
|
||||
|
||||
void icd2061_write(icd2061_t *icd2061, int val);
|
||||
double icd2061_getfreq(icd2061_t *icd2061, int i);
|
||||
|
|
|
|||
|
|
@ -6,58 +6,50 @@
|
|||
|
||||
enum
|
||||
{
|
||||
ICS2595_IDLE,
|
||||
ICS2595_IDLE = 0,
|
||||
ICS2595_WRITE,
|
||||
ICS2595_READ
|
||||
};
|
||||
|
||||
static int ics2595_oldfs3, ics2595_oldfs2;
|
||||
static int ics2595_dat;
|
||||
static int ics2595_pos;
|
||||
static int ics2595_state = ICS2595_IDLE;
|
||||
|
||||
static int ics2595_div[4] = {8, 4, 2, 1};
|
||||
|
||||
static double ics2595_clocks[16];
|
||||
double ics2595_output_clock;
|
||||
|
||||
void ics2595_write(int strobe, int dat)
|
||||
void ics2595_write(ics2595_t *ics2595, int strobe, int dat)
|
||||
{
|
||||
pclog("ics2595_write : %i %i\n", strobe, dat);
|
||||
if (strobe)
|
||||
{
|
||||
if ((dat & 8) && !ics2595_oldfs3) /*Data clock*/
|
||||
if ((dat & 8) && !ics2595->oldfs3) /*Data clock*/
|
||||
{
|
||||
pclog(" - new dat %i\n", dat & 4);
|
||||
switch (ics2595_state)
|
||||
switch (ics2595->state)
|
||||
{
|
||||
case ICS2595_IDLE:
|
||||
ics2595_state = (dat & 4) ? ICS2595_WRITE : ICS2595_IDLE;
|
||||
ics2595_pos = 0;
|
||||
ics2595->state = (dat & 4) ? ICS2595_WRITE : ICS2595_IDLE;
|
||||
ics2595->pos = 0;
|
||||
break;
|
||||
case ICS2595_WRITE:
|
||||
ics2595_dat = (ics2595_dat >> 1);
|
||||
ics2595->dat = (ics2595->dat >> 1);
|
||||
if (dat & 4)
|
||||
ics2595_dat |= (1 << 19);
|
||||
ics2595_pos++;
|
||||
if (ics2595_pos == 20)
|
||||
ics2595->dat |= (1 << 19);
|
||||
ics2595->pos++;
|
||||
if (ics2595->pos == 20)
|
||||
{
|
||||
int d, n, l;
|
||||
pclog("ICS2595_WRITE : dat %08X\n", ics2595_dat);
|
||||
l = (ics2595_dat >> 2) & 31;
|
||||
n = ((ics2595_dat >> 7) & 255) + 257;
|
||||
d = ics2595_div[(ics2595_dat >> 16) & 3];
|
||||
pclog("ICS2595_WRITE : dat %08X\n", ics2595->dat);
|
||||
l = (ics2595->dat >> 2) & 0xf;
|
||||
n = ((ics2595->dat >> 7) & 255) + 257;
|
||||
d = ics2595_div[(ics2595->dat >> 16) & 3];
|
||||
|
||||
ics2595_clocks[l] = (14318181.8 * ((double)n / 46.0)) / (double)d;
|
||||
ics2595->clocks[l] = (14318181.8 * ((double)n / 46.0)) / (double)d;
|
||||
pclog("ICS2595 clock set - L %i N %i D %i freq = %f\n", l, n, d, (14318181.8 * ((double)n / 46.0)) / (double)d);
|
||||
ics2595_state = ICS2595_IDLE;
|
||||
ics2595->state = ICS2595_IDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ics2595_oldfs2 = dat & 4;
|
||||
ics2595_oldfs3 = dat & 8;
|
||||
ics2595->oldfs2 = dat & 4;
|
||||
ics2595->oldfs3 = dat & 8;
|
||||
}
|
||||
ics2595_output_clock = ics2595_clocks[dat];
|
||||
ics2595->output_clock = ics2595->clocks[dat];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,12 @@
|
|||
void ics2595_write(int strobe, int dat);
|
||||
extern double ics2595_output_clock;
|
||||
typedef struct ics2595_t
|
||||
{
|
||||
int oldfs3, oldfs2;
|
||||
int dat;
|
||||
int pos;
|
||||
int state;
|
||||
|
||||
double clocks[16];
|
||||
double output_clock;
|
||||
} ics2595_t;
|
||||
|
||||
void ics2595_write(ics2595_t *ics2595, int strobe, int dat);
|
||||
|
|
|
|||
371
src/vid_mda.c
371
src/vid_mda.c
|
|
@ -1,259 +1,316 @@
|
|||
/*MDA emulation*/
|
||||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "timer.h"
|
||||
#include "video.h"
|
||||
#include "vid_mda.h"
|
||||
|
||||
void mda_recalctimings();
|
||||
|
||||
static uint8_t mda_ctrl,mda_stat;
|
||||
uint8_t crtcm[32],crtcmreg;
|
||||
|
||||
void mda_out(uint16_t addr, uint8_t val, void *priv)
|
||||
typedef struct mda_t
|
||||
{
|
||||
uint8_t crtc[32];
|
||||
int crtcreg;
|
||||
|
||||
uint8_t ctrl, stat;
|
||||
|
||||
int dispontime, dispofftime;
|
||||
int vidtime;
|
||||
|
||||
int firstline, lastline;
|
||||
|
||||
int linepos, displine;
|
||||
int vc, sc;
|
||||
uint16_t ma, maback;
|
||||
int con, coff, cursoron;
|
||||
int dispon, blink;
|
||||
int vsynctime, vadj;
|
||||
|
||||
uint8_t *vram;
|
||||
} mda_t;
|
||||
|
||||
static int mdacols[256][2][2];
|
||||
|
||||
void mda_recalctimings(mda_t *mda);
|
||||
|
||||
void mda_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
mda_t *mda = (mda_t *)p;
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3B0: case 0x3B2: case 0x3B4: case 0x3B6:
|
||||
crtcmreg = val & 31;
|
||||
case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6:
|
||||
mda->crtcreg = val & 31;
|
||||
return;
|
||||
case 0x3B1: case 0x3B3: case 0x3B5: case 0x3B7:
|
||||
crtcm[crtcmreg] = val;
|
||||
if (crtcm[10]==6 && crtcm[11]==7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/
|
||||
case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7:
|
||||
mda->crtc[mda->crtcreg] = val;
|
||||
if (mda->crtc[10] == 6 && mda->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/
|
||||
{
|
||||
crtcm[10]=0xB;
|
||||
crtcm[11]=0xC;
|
||||
mda->crtc[10] = 0xb;
|
||||
mda->crtc[11] = 0xc;
|
||||
}
|
||||
mda_recalctimings();
|
||||
mda_recalctimings(mda);
|
||||
return;
|
||||
case 0x3B8:
|
||||
mda_ctrl = val;
|
||||
case 0x3b8:
|
||||
mda->ctrl = val;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t mda_in(uint16_t addr, void *priv)
|
||||
uint8_t mda_in(uint16_t addr, void *p)
|
||||
{
|
||||
mda_t *mda = (mda_t *)p;
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3B0: case 0x3B2: case 0x3B4: case 0x3B6:
|
||||
return crtcmreg;
|
||||
case 0x3B1: case 0x3B3: case 0x3B5: case 0x3B7:
|
||||
return crtcm[crtcmreg];
|
||||
case 0x3BA:
|
||||
return mda_stat | 0xF0;
|
||||
case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6:
|
||||
return mda->crtcreg;
|
||||
case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7:
|
||||
return mda->crtc[mda->crtcreg];
|
||||
case 0x3ba:
|
||||
return mda->stat | 0xF0;
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
void mda_write(uint32_t addr, uint8_t val, void *priv)
|
||||
void mda_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
vram[addr&0xFFF]=val;
|
||||
mda_t *mda = (mda_t *)p;
|
||||
mda->vram[addr & 0xfff] = val;
|
||||
}
|
||||
|
||||
uint8_t mda_read(uint32_t addr, void *priv)
|
||||
uint8_t mda_read(uint32_t addr, void *p)
|
||||
{
|
||||
return vram[addr&0xFFF];
|
||||
mda_t *mda = (mda_t *)p;
|
||||
return mda->vram[addr & 0xfff];
|
||||
}
|
||||
|
||||
void mda_recalctimings()
|
||||
void mda_recalctimings(mda_t *mda)
|
||||
{
|
||||
double _dispontime, _dispofftime;
|
||||
disptime=crtc[0]+1;
|
||||
_dispontime=crtc[1];
|
||||
_dispofftime=disptime-_dispontime;
|
||||
_dispontime*=MDACONST;
|
||||
_dispofftime*=MDACONST;
|
||||
dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||
dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
double _dispontime, _dispofftime, disptime;
|
||||
disptime = mda->crtc[0] + 1;
|
||||
_dispontime = mda->crtc[1];
|
||||
_dispofftime = disptime - _dispontime;
|
||||
_dispontime *= MDACONST;
|
||||
_dispofftime *= MDACONST;
|
||||
mda->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||
mda->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
}
|
||||
|
||||
int mdacols[256][2][2];
|
||||
|
||||
static int linepos,displine;
|
||||
static int vc,sc;
|
||||
static uint16_t ma,maback;
|
||||
static int con,coff,cursoron;
|
||||
static int cgadispon,cgablink;
|
||||
static int vsynctime,vadj;
|
||||
|
||||
void mda_poll()
|
||||
void mda_poll(void *p)
|
||||
{
|
||||
uint16_t ca=(crtcm[15]|(crtcm[14]<<8))&0x3FFF;
|
||||
mda_t *mda = (mda_t *)p;
|
||||
uint16_t ca = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x,c;
|
||||
int x, c;
|
||||
int oldvc;
|
||||
uint8_t chr,attr;
|
||||
uint8_t chr, attr;
|
||||
int cols[4];
|
||||
int oldsc;
|
||||
int blink;
|
||||
if (!linepos)
|
||||
if (!mda->linepos)
|
||||
{
|
||||
vidtime+=dispofftime;
|
||||
mda_stat|=1;
|
||||
linepos=1;
|
||||
oldsc=sc;
|
||||
if ((crtcm[8]&3)==3) sc=(sc<<1)&7;
|
||||
if (cgadispon)
|
||||
mda->vidtime += mda->dispofftime;
|
||||
mda->stat |= 1;
|
||||
mda->linepos = 1;
|
||||
oldsc = mda->sc;
|
||||
if ((mda->crtc[8] & 3) == 3)
|
||||
mda->sc = (mda->sc << 1) & 7;
|
||||
if (mda->dispon)
|
||||
{
|
||||
if (displine<firstline)
|
||||
if (mda->displine < mda->firstline)
|
||||
{
|
||||
firstline=displine;
|
||||
mda->firstline = mda->displine;
|
||||
}
|
||||
lastline=displine;
|
||||
cols[0]=0;
|
||||
cols[1]=7;
|
||||
for (x=0;x<crtcm[1];x++)
|
||||
mda->lastline = mda->displine;
|
||||
cols[0] = 0;
|
||||
cols[1] = 7;
|
||||
for (x = 0; x < mda->crtc[1]; x++)
|
||||
{
|
||||
chr=vram[(ma<<1)&0x3FFF];
|
||||
attr=vram[((ma<<1)+1)&0x3FFF];
|
||||
drawcursor=((ma==ca) && con && cursoron);
|
||||
blink=((cgablink&16) && (mda_ctrl&0x20) && (attr&0x80) && !drawcursor);
|
||||
if (sc==12 && ((attr&7)==1))
|
||||
chr = mda->vram[(mda->ma << 1) & 0x3fff];
|
||||
attr = mda->vram[((mda->ma << 1) + 1) & 0x3fff];
|
||||
drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron);
|
||||
blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
if (mda->sc == 12 && ((attr & 7) == 1))
|
||||
{
|
||||
for (c=0;c<9;c++)
|
||||
buffer->line[displine][(x*9)+c]=mdacols[attr][blink][1];
|
||||
for (c = 0; c < 9; c++)
|
||||
buffer->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][1];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (c=0;c<8;c++)
|
||||
buffer->line[displine][(x*9)+c]=mdacols[attr][blink][(fontdatm[chr][sc]&(1<<(c^7)))?1:0];
|
||||
if ((chr&~0x1F)==0xC0) buffer->line[displine][(x*9)+8]=mdacols[attr][blink][fontdatm[chr][sc]&1];
|
||||
else buffer->line[displine][(x*9)+8]=mdacols[attr][blink][0];
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][mda->sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
if ((chr & ~0x1f) == 0xc0) buffer->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][mda->sc] & 1];
|
||||
else buffer->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][0];
|
||||
}
|
||||
ma++;
|
||||
mda->ma++;
|
||||
if (drawcursor)
|
||||
{
|
||||
for (c=0;c<9;c++)
|
||||
buffer->line[displine][(x*9)+c]^=mdacols[attr][0][1];
|
||||
for (c = 0; c < 9; c++)
|
||||
buffer->line[mda->displine][(x * 9) + c] ^= mdacols[attr][0][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
sc=oldsc;
|
||||
if (vc==crtcm[7] && !sc)
|
||||
mda->sc = oldsc;
|
||||
if (mda->vc == mda->crtc[7] && !mda->sc)
|
||||
{
|
||||
mda_stat|=8;
|
||||
mda->stat |= 8;
|
||||
// printf("VSYNC on %i %i\n",vc,sc);
|
||||
}
|
||||
displine++;
|
||||
if (displine>=500) displine=0;
|
||||
mda->displine++;
|
||||
if (mda->displine >= 500)
|
||||
mda->displine=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vidtime+=dispontime;
|
||||
if (cgadispon) mda_stat&=~1;
|
||||
linepos=0;
|
||||
if (vsynctime)
|
||||
mda->vidtime += mda->dispontime;
|
||||
if (mda->dispon) mda->stat&=~1;
|
||||
mda->linepos=0;
|
||||
if (mda->vsynctime)
|
||||
{
|
||||
vsynctime--;
|
||||
if (!vsynctime)
|
||||
mda->vsynctime--;
|
||||
if (!mda->vsynctime)
|
||||
{
|
||||
mda_stat&=~8;
|
||||
mda->stat&=~8;
|
||||
// printf("VSYNC off %i %i\n",vc,sc);
|
||||
}
|
||||
}
|
||||
if (sc==(crtcm[11]&31) || ((crtcm[8]&3)==3 && sc==((crtcm[11]&31)>>1))) { con=0; coff=1; }
|
||||
if (vadj)
|
||||
if (mda->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1)))
|
||||
{
|
||||
mda->con = 0;
|
||||
mda->coff = 1;
|
||||
}
|
||||
if (mda->vadj)
|
||||
{
|
||||
sc++;
|
||||
sc&=31;
|
||||
ma=maback;
|
||||
vadj--;
|
||||
if (!vadj)
|
||||
mda->sc++;
|
||||
mda->sc &= 31;
|
||||
mda->ma = mda->maback;
|
||||
mda->vadj--;
|
||||
if (!mda->vadj)
|
||||
{
|
||||
cgadispon=1;
|
||||
ma=maback=(crtcm[13]|(crtcm[12]<<8))&0x3FFF;
|
||||
sc=0;
|
||||
mda->dispon = 1;
|
||||
mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff;
|
||||
mda->sc = 0;
|
||||
}
|
||||
}
|
||||
else if (sc==crtcm[9] || ((crtcm[8]&3)==3 && sc==(crtcm[9]>>1)))
|
||||
else if (mda->sc == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->sc == (mda->crtc[9] >> 1)))
|
||||
{
|
||||
maback=ma;
|
||||
sc=0;
|
||||
oldvc=vc;
|
||||
vc++;
|
||||
vc&=127;
|
||||
if (vc==crtcm[6]) cgadispon=0;
|
||||
if (oldvc==crtcm[4])
|
||||
mda->maback = mda->ma;
|
||||
mda->sc = 0;
|
||||
oldvc = mda->vc;
|
||||
mda->vc++;
|
||||
mda->vc &= 127;
|
||||
if (mda->vc == mda->crtc[6])
|
||||
mda->dispon=0;
|
||||
if (oldvc == mda->crtc[4])
|
||||
{
|
||||
// printf("Display over at %i\n",displine);
|
||||
vc=0;
|
||||
vadj=crtcm[5];
|
||||
if (!vadj) cgadispon=1;
|
||||
if (!vadj) ma=maback=(crtcm[13]|(crtcm[12]<<8))&0x3FFF;
|
||||
if ((crtcm[10]&0x60)==0x20) cursoron=0;
|
||||
else cursoron=cgablink&16;
|
||||
mda->vc = 0;
|
||||
mda->vadj = mda->crtc[5];
|
||||
if (!mda->vadj) mda->dispon = 1;
|
||||
if (!mda->vadj) mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff;
|
||||
if ((mda->crtc[10] & 0x60) == 0x20) mda->cursoron = 0;
|
||||
else mda->cursoron = mda->blink & 16;
|
||||
}
|
||||
if (vc==crtcm[7])
|
||||
if (mda->vc == mda->crtc[7])
|
||||
{
|
||||
cgadispon=0;
|
||||
displine=0;
|
||||
vsynctime=16;//(crtcm[3]>>4)+1;
|
||||
if (crtcm[7])
|
||||
mda->dispon = 0;
|
||||
mda->displine = 0;
|
||||
mda->vsynctime = 16;
|
||||
if (mda->crtc[7])
|
||||
{
|
||||
// printf("Lastline %i Firstline %i %i\n",lastline,firstline,lastline-firstline);
|
||||
x=crtcm[1]*9;
|
||||
lastline++;
|
||||
if (x!=xsize || (lastline-firstline)!=ysize)
|
||||
x = mda->crtc[1] * 9;
|
||||
mda->lastline++;
|
||||
if (x != xsize || (mda->lastline - mda->firstline) != ysize)
|
||||
{
|
||||
xsize=x;
|
||||
ysize=lastline-firstline;
|
||||
xsize = x;
|
||||
ysize = mda->lastline - mda->firstline;
|
||||
// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtcm[1]);
|
||||
if (xsize<64) xsize=656;
|
||||
if (ysize<32) ysize=200;
|
||||
updatewindowsize(xsize,ysize);
|
||||
if (xsize < 64) xsize = 656;
|
||||
if (ysize < 32) ysize = 200;
|
||||
updatewindowsize(xsize, ysize);
|
||||
}
|
||||
startblit();
|
||||
video_blit_memtoscreen_8(0, firstline, xsize, lastline - firstline);
|
||||
video_blit_memtoscreen_8(0, mda->firstline, xsize, mda->lastline - mda->firstline);
|
||||
endblit();
|
||||
frames++;
|
||||
video_res_x = crtcm[1];
|
||||
video_res_y = crtcm[6];
|
||||
video_res_x = mda->crtc[1];
|
||||
video_res_y = mda->crtc[6];
|
||||
video_bpp = 0;
|
||||
}
|
||||
firstline=1000;
|
||||
lastline=0;
|
||||
cgablink++;
|
||||
mda->firstline = 1000;
|
||||
mda->lastline = 0;
|
||||
mda->blink++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sc++;
|
||||
sc&=31;
|
||||
ma=maback;
|
||||
mda->sc++;
|
||||
mda->sc &= 31;
|
||||
mda->ma = mda->maback;
|
||||
}
|
||||
if ((sc==(crtcm[10]&31) || ((crtcm[8]&3)==3 && sc==((crtcm[10]&31)>>1))))
|
||||
if ((mda->sc == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[10] & 31) >> 1))))
|
||||
{
|
||||
con=1;
|
||||
mda->con = 1;
|
||||
// printf("Cursor on - %02X %02X %02X\n",crtcm[8],crtcm[10],crtcm[11]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int mda_init()
|
||||
void *mda_init()
|
||||
{
|
||||
mem_sethandler(0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL);
|
||||
return 0;
|
||||
int c;
|
||||
mda_t *mda = malloc(sizeof(mda_t));
|
||||
memset(mda, 0, sizeof(mda_t));
|
||||
|
||||
mda->vram = malloc(0x1000);
|
||||
|
||||
timer_add(mda_poll, &mda->vidtime, TIMER_ALWAYS_ENABLED, mda);
|
||||
mem_sethandler(0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, mda);
|
||||
io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda);
|
||||
|
||||
for (c = 0; c < 256; c++)
|
||||
{
|
||||
mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16;
|
||||
if (c & 8) mdacols[c][0][1] = 15 + 16;
|
||||
else mdacols[c][0][1] = 7 + 16;
|
||||
}
|
||||
mdacols[0x70][0][1] = 16;
|
||||
mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15;
|
||||
mdacols[0xF0][0][1] = 16;
|
||||
mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15;
|
||||
mdacols[0x78][0][1] = 16 + 7;
|
||||
mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15;
|
||||
mdacols[0xF8][0][1] = 16 + 7;
|
||||
mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15;
|
||||
mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16;
|
||||
mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16;
|
||||
mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16;
|
||||
mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16;
|
||||
|
||||
return mda;
|
||||
}
|
||||
|
||||
GFXCARD vid_mda =
|
||||
void mda_close(void *p)
|
||||
{
|
||||
mda_t *mda = (mda_t *)p;
|
||||
|
||||
free(mda->vram);
|
||||
free(mda);
|
||||
}
|
||||
|
||||
void mda_speed_changed(void *p)
|
||||
{
|
||||
mda_t *mda = (mda_t *)p;
|
||||
|
||||
mda_recalctimings(mda);
|
||||
}
|
||||
|
||||
device_t mda_device =
|
||||
{
|
||||
"MDA",
|
||||
mda_init,
|
||||
/*IO at 3Cx/3Dx*/
|
||||
video_out_null,
|
||||
video_in_null,
|
||||
/*IO at 3Ax/3Bx*/
|
||||
mda_out,
|
||||
mda_in,
|
||||
|
||||
mda_poll,
|
||||
mda_recalctimings,
|
||||
|
||||
video_write_null,
|
||||
mda_write,
|
||||
video_write_null,
|
||||
|
||||
video_read_null,
|
||||
mda_read,
|
||||
video_read_null
|
||||
mda_close,
|
||||
mda_speed_changed,
|
||||
NULL
|
||||
};
|
||||
|
|
|
|||
1
src/vid_mda.h
Normal file
1
src/vid_mda.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
extern device_t mda_device;
|
||||
|
|
@ -1,436 +1,487 @@
|
|||
/*Olivetti M24 video emulation
|
||||
Essentially double-res CGA*/
|
||||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "timer.h"
|
||||
#include "video.h"
|
||||
#include "vid_olivetti_m24.h"
|
||||
|
||||
void m24_recalctimings();
|
||||
|
||||
static uint8_t m24_ctrl;
|
||||
static uint32_t m24_base;
|
||||
|
||||
void m24_out(uint16_t addr, uint8_t val, void *priv)
|
||||
typedef struct m24_t
|
||||
{
|
||||
uint8_t crtc[32];
|
||||
int crtcreg;
|
||||
|
||||
uint8_t *vram;
|
||||
uint8_t charbuffer[256];
|
||||
|
||||
uint8_t ctrl;
|
||||
uint32_t base;
|
||||
|
||||
uint8_t cgamode, cgacol;
|
||||
uint8_t stat;
|
||||
|
||||
int linepos, displine;
|
||||
int sc, vc;
|
||||
int con, coff, cursoron, blink;
|
||||
int vsynctime, vadj;
|
||||
int lineff;
|
||||
uint16_t ma, maback;
|
||||
int dispon;
|
||||
|
||||
int dispontime, dispofftime, vidtime;
|
||||
|
||||
int firstline, lastline;
|
||||
} m24_t;
|
||||
|
||||
static uint8_t crtcmask[32] =
|
||||
{
|
||||
0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
void m24_recalctimings(m24_t *m24);
|
||||
|
||||
|
||||
void m24_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
m24_t *m24 = (m24_t *)p;
|
||||
uint8_t old;
|
||||
pclog("m24_out %04X %02X\n", addr, val);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3D4:
|
||||
crtcreg = val & 31;
|
||||
case 0x3d4:
|
||||
m24->crtcreg = val & 31;
|
||||
return;
|
||||
case 0x3D5:
|
||||
old = crtc[crtcreg];
|
||||
crtc[crtcreg] = val & crtcmask[crtcreg];
|
||||
case 0x3d5:
|
||||
old = m24->crtc[m24->crtcreg];
|
||||
m24->crtc[m24->crtcreg] = val & crtcmask[m24->crtcreg];
|
||||
if (old != val)
|
||||
{
|
||||
if (crtcreg < 0xE || crtcreg > 0x10)
|
||||
if (m24->crtcreg < 0xe || m24->crtcreg > 0x10)
|
||||
{
|
||||
fullchange = changeframecount;
|
||||
m24_recalctimings();
|
||||
m24_recalctimings(m24);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case 0x3D8:
|
||||
cgamode = val;
|
||||
case 0x3d8:
|
||||
m24->cgamode = val;
|
||||
return;
|
||||
case 0x3D9:
|
||||
cgacol = val;
|
||||
case 0x3d9:
|
||||
m24->cgacol = val;
|
||||
return;
|
||||
case 0x3de:
|
||||
m24_ctrl = val;
|
||||
m24_base = (val & 0x08) ? 0x4000 : 0;
|
||||
m24->ctrl = val;
|
||||
m24->base = (val & 0x08) ? 0x4000 : 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t m24_in(uint16_t addr, void *priv)
|
||||
uint8_t m24_in(uint16_t addr, void *p)
|
||||
{
|
||||
m24_t *m24 = (m24_t *)p;
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3D4:
|
||||
return crtcreg;
|
||||
case 0x3D5:
|
||||
return crtc[crtcreg];
|
||||
case 0x3DA:
|
||||
return cgastat;
|
||||
case 0x3d4:
|
||||
return m24->crtcreg;
|
||||
case 0x3d5:
|
||||
return m24->crtc[m24->crtcreg];
|
||||
case 0x3da:
|
||||
return m24->stat;
|
||||
}
|
||||
return 0xFF;
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
static uint8_t charbuffer[256];
|
||||
|
||||
void m24_write(uint32_t addr, uint8_t val, void *priv)
|
||||
void m24_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
vram[addr & 0x7FFF]=val;
|
||||
charbuffer[ ((int)(((dispontime - vidtime) * 2) / (CGACONST / 2))) & 0xfc] = val;
|
||||
charbuffer[(((int)(((dispontime - vidtime) * 2) / (CGACONST / 2))) & 0xfc) | 1] = val;
|
||||
m24_t *m24 = (m24_t *)p;
|
||||
m24->vram[addr & 0x7FFF]=val;
|
||||
m24->charbuffer[ ((int)(((m24->dispontime - m24->vidtime) * 2) / (CGACONST / 2))) & 0xfc] = val;
|
||||
m24->charbuffer[(((int)(((m24->dispontime - m24->vidtime) * 2) / (CGACONST / 2))) & 0xfc) | 1] = val;
|
||||
}
|
||||
|
||||
uint8_t m24_read(uint32_t addr, void *priv)
|
||||
uint8_t m24_read(uint32_t addr, void *p)
|
||||
{
|
||||
return vram[addr & 0x7FFF];
|
||||
m24_t *m24 = (m24_t *)p;
|
||||
return m24->vram[addr & 0x7FFF];
|
||||
}
|
||||
|
||||
void m24_recalctimings()
|
||||
void m24_recalctimings(m24_t *m24)
|
||||
{
|
||||
double _dispontime, _dispofftime;
|
||||
if (cgamode & 1)
|
||||
double _dispontime, _dispofftime, disptime;
|
||||
if (m24->cgamode & 1)
|
||||
{
|
||||
disptime = crtc[0] + 1;
|
||||
_dispontime = crtc[1];
|
||||
disptime = m24->crtc[0] + 1;
|
||||
_dispontime = m24->crtc[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
disptime = (crtc[0] + 1) << 1;
|
||||
_dispontime = crtc[1] << 1;
|
||||
disptime = (m24->crtc[0] + 1) << 1;
|
||||
_dispontime = m24->crtc[1] << 1;
|
||||
}
|
||||
_dispofftime = disptime - _dispontime;
|
||||
// printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]);
|
||||
_dispontime *= CGACONST / 2;
|
||||
_dispofftime *= CGACONST / 2;
|
||||
// printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92);
|
||||
dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||
dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
m24->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||
m24->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
}
|
||||
|
||||
static int linepos,displine;
|
||||
static int sc,vc;
|
||||
static int cgadispon;
|
||||
static int con,coff,cursoron,cgablink;
|
||||
static int vsynctime,vadj;
|
||||
static int m24_lineff = 0;
|
||||
static uint16_t ma,maback;
|
||||
|
||||
void m24_poll()
|
||||
void m24_poll(void *p)
|
||||
{
|
||||
uint16_t ca=(crtc[15]|(crtc[14]<<8))&0x3FFF;
|
||||
m24_t *m24 = (m24_t *)p;
|
||||
uint16_t ca = (m24->crtc[15] | (m24->crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x,c;
|
||||
int x, c;
|
||||
int oldvc;
|
||||
uint8_t chr,attr;
|
||||
uint16_t dat,dat2;
|
||||
uint8_t chr, attr;
|
||||
uint16_t dat, dat2;
|
||||
int cols[4];
|
||||
int col;
|
||||
int oldsc;
|
||||
if (!linepos)
|
||||
if (!m24->linepos)
|
||||
{
|
||||
// pclog("Line poll %i %i %i %i - %04X %i %i %i\n", m24_lineff, vc, sc, vadj, ma, firstline, lastline, displine);
|
||||
vidtime+=dispofftime;
|
||||
cgastat|=1;
|
||||
linepos=1;
|
||||
oldsc=sc;
|
||||
if ((crtc[8]&3)==3) sc=(sc<<1)&7;
|
||||
if (cgadispon)
|
||||
m24->vidtime += m24->dispofftime;
|
||||
m24->stat |= 1;
|
||||
m24->linepos = 1;
|
||||
oldsc = m24->sc;
|
||||
if ((m24->crtc[8] & 3) == 3)
|
||||
m24->sc = (m24->sc << 1) & 7;
|
||||
if (m24->dispon)
|
||||
{
|
||||
if (displine<firstline)
|
||||
pclog("dispon %i\n", m24->linepos);
|
||||
if (m24->displine < m24->firstline)
|
||||
{
|
||||
firstline=displine;
|
||||
m24->firstline = m24->displine;
|
||||
// printf("Firstline %i\n",firstline);
|
||||
}
|
||||
lastline=displine;
|
||||
for (c=0;c<8;c++)
|
||||
m24->lastline = m24->displine;
|
||||
for (c = 0; c < 8; c++)
|
||||
{
|
||||
if ((cgamode&0x12)==0x12)
|
||||
if ((m24->cgamode & 0x12) == 0x12)
|
||||
{
|
||||
buffer->line[displine][c]=0;
|
||||
if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=0;
|
||||
else buffer->line[displine][c+(crtc[1]<<4)+8]=0;
|
||||
buffer->line[m24->displine][c] = 0;
|
||||
if (m24->cgamode & 1) buffer->line[m24->displine][c + (m24->crtc[1] << 3) + 8] = 0;
|
||||
else buffer->line[m24->displine][c + (m24->crtc[1] << 4) + 8] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer->line[displine][c]=(cgacol&15)+16;
|
||||
if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=(cgacol&15)+16;
|
||||
else buffer->line[displine][c+(crtc[1]<<4)+8]=(cgacol&15)+16;
|
||||
buffer->line[m24->displine][c] = (m24->cgacol & 15) + 16;
|
||||
if (m24->cgamode & 1) buffer->line[m24->displine][c + (m24->crtc[1] << 3) + 8] = (m24->cgacol & 15) + 16;
|
||||
else buffer->line[m24->displine][c + (m24->crtc[1] << 4) + 8] = (m24->cgacol & 15) + 16;
|
||||
}
|
||||
}
|
||||
if (cgamode&1)
|
||||
if (m24->cgamode & 1)
|
||||
{
|
||||
for (x=0;x<crtc[1];x++)
|
||||
for (x = 0; x < m24->crtc[1]; x++)
|
||||
{
|
||||
chr = charbuffer[ x << 1];
|
||||
attr = charbuffer[(x << 1) + 1];
|
||||
drawcursor=((ma==ca) && con && cursoron);
|
||||
if (cgamode&0x20)
|
||||
chr = m24->charbuffer[ x << 1];
|
||||
attr = m24->charbuffer[(x << 1) + 1];
|
||||
drawcursor = ((m24->ma == ca) && m24->con && m24->cursoron);
|
||||
if (m24->cgamode & 0x20)
|
||||
{
|
||||
cols[1]=(attr&15)+16;
|
||||
cols[0]=((attr>>4)&7)+16;
|
||||
if ((cgablink&16) && (attr&0x80) && !drawcursor) cols[1]=cols[0];
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((m24->blink & 16) && (attr & 0x80) && !drawcursor)
|
||||
cols[1] = cols[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
cols[1]=(attr&15)+16;
|
||||
cols[0]=(attr>>4)+16;
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
}
|
||||
if (drawcursor)
|
||||
{
|
||||
for (c=0;c<8;c++)
|
||||
buffer->line[displine][(x<<3)+c+8]=cols[(fontdatm[chr][((sc & 7) << 1) | m24_lineff]&(1<<(c^7)))?1:0]^15;
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer->line[m24->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (c=0;c<8;c++)
|
||||
buffer->line[displine][(x<<3)+c+8]=cols[(fontdatm[chr][((sc & 7) << 1) | m24_lineff]&(1<<(c^7)))?1:0];
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer->line[m24->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
ma++;
|
||||
m24->ma++;
|
||||
}
|
||||
}
|
||||
else if (!(cgamode&2))
|
||||
else if (!(m24->cgamode & 2))
|
||||
{
|
||||
for (x=0;x<crtc[1];x++)
|
||||
for (x = 0; x < m24->crtc[1]; x++)
|
||||
{
|
||||
chr=vram[((ma<<1)&0x3FFF) + m24_base];
|
||||
attr=vram[(((ma<<1)+1)&0x3FFF) + m24_base];
|
||||
drawcursor=((ma==ca) && con && cursoron);
|
||||
if (cgamode&0x20)
|
||||
chr = m24->vram[((m24->ma << 1) & 0x3fff) + m24->base];
|
||||
attr = m24->vram[(((m24->ma << 1) + 1) & 0x3fff) + m24->base];
|
||||
drawcursor = ((m24->ma == ca) && m24->con && m24->cursoron);
|
||||
if (m24->cgamode & 0x20)
|
||||
{
|
||||
cols[1]=(attr&15)+16;
|
||||
cols[0]=((attr>>4)&7)+16;
|
||||
if ((cgablink&16) && (attr&0x80)) cols[1]=cols[0];
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((m24->blink & 16) && (attr & 0x80))
|
||||
cols[1] = cols[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
cols[1]=(attr&15)+16;
|
||||
cols[0]=(attr>>4)+16;
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
}
|
||||
ma++;
|
||||
m24->ma++;
|
||||
if (drawcursor)
|
||||
{
|
||||
for (c=0;c<8;c++)
|
||||
buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdatm[chr][((sc & 7) << 1) | m24_lineff]&(1<<(c^7)))?1:0]^15;
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer->line[m24->displine][(x << 4) + (c << 1) + 8] =
|
||||
buffer->line[m24->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (c=0;c<8;c++)
|
||||
buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdatm[chr][((sc & 7) << 1) | m24_lineff]&(1<<(c^7)))?1:0];
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer->line[m24->displine][(x << 4) + (c << 1) + 8] =
|
||||
buffer->line[m24->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!(cgamode&16))
|
||||
else if (!(m24->cgamode & 16))
|
||||
{
|
||||
cols[0]=(cgacol&15)|16;
|
||||
col=(cgacol&16)?24:16;
|
||||
if (cgamode&4)
|
||||
cols[0] = (m24->cgacol & 15) | 16;
|
||||
col = (m24->cgacol & 16) ? 24 : 16;
|
||||
if (m24->cgamode & 4)
|
||||
{
|
||||
cols[1]=col|3;
|
||||
cols[2]=col|4;
|
||||
cols[3]=col|7;
|
||||
cols[1] = col | 3;
|
||||
cols[2] = col | 4;
|
||||
cols[3] = col | 7;
|
||||
}
|
||||
else if (cgacol&32)
|
||||
else if (m24->cgacol & 32)
|
||||
{
|
||||
cols[1]=col|3;
|
||||
cols[2]=col|5;
|
||||
cols[3]=col|7;
|
||||
cols[1] = col | 3;
|
||||
cols[2] = col | 5;
|
||||
cols[3] = col | 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
cols[1]=col|2;
|
||||
cols[2]=col|4;
|
||||
cols[3]=col|6;
|
||||
cols[1] = col | 2;
|
||||
cols[2] = col | 4;
|
||||
cols[3] = col | 6;
|
||||
}
|
||||
for (x=0;x<crtc[1];x++)
|
||||
for (x = 0; x < m24->crtc[1]; x++)
|
||||
{
|
||||
dat=(vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000) + m24_base]<<8)|vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)+1 + m24_base];
|
||||
ma++;
|
||||
for (c=0;c<8;c++)
|
||||
dat = (m24->vram[((m24->ma << 1) & 0x1fff) + ((m24->sc & 1) * 0x2000) + m24->base] << 8) |
|
||||
m24->vram[((m24->ma << 1) & 0x1fff) + ((m24->sc & 1) * 0x2000) + 1 + m24->base];
|
||||
m24->ma++;
|
||||
for (c = 0; c < 8; c++)
|
||||
{
|
||||
buffer->line[displine][(x<<4)+(c<<1)+8]=
|
||||
buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[dat>>14];
|
||||
dat<<=2;
|
||||
buffer->line[m24->displine][(x << 4) + (c << 1) + 8] =
|
||||
buffer->line[m24->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14];
|
||||
dat <<= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (m24_ctrl & 1)
|
||||
if (m24->ctrl & 1)
|
||||
{
|
||||
dat2 = ((sc & 1) * 0x4000) | (m24_lineff * 0x2000);
|
||||
cols[0]=0; cols[1]=/*(cgacol&15)*/15+16;
|
||||
dat2 = ((m24->sc & 1) * 0x4000) | (m24->lineff * 0x2000);
|
||||
cols[0] = 0; cols[1] = /*(m24->cgacol & 15)*/15 + 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
dat2 = (sc & 1) * 0x2000;
|
||||
cols[0]=0; cols[1]=(cgacol&15)+16;
|
||||
dat2 = (m24->sc & 1) * 0x2000;
|
||||
cols[0] = 0; cols[1] = (m24->cgacol & 15) + 16;
|
||||
}
|
||||
for (x=0;x<crtc[1];x++)
|
||||
for (x = 0; x < m24->crtc[1]; x++)
|
||||
{
|
||||
dat=(vram[((ma<<1)&0x1FFF) + dat2]<<8) | vram[((ma<<1)&0x1FFF) + dat2 + 1];
|
||||
ma++;
|
||||
for (c=0;c<16;c++)
|
||||
dat = (m24->vram[((m24->ma << 1) & 0x1fff) + dat2] << 8) | m24->vram[((m24->ma << 1) & 0x1fff) + dat2 + 1];
|
||||
m24->ma++;
|
||||
for (c = 0; c < 16; c++)
|
||||
{
|
||||
buffer->line[displine][(x<<4)+c+8]=cols[dat>>15];
|
||||
dat<<=1;
|
||||
buffer->line[m24->displine][(x << 4) + c + 8] = cols[dat >> 15];
|
||||
dat <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cols[0]=((cgamode&0x12)==0x12)?0:(cgacol&15)+16;
|
||||
if (cgamode&1) hline(buffer,0,displine,(crtc[1]<<3)+16,cols[0]);
|
||||
else hline(buffer,0,displine,(crtc[1]<<4)+16,cols[0]);
|
||||
cols[0] = ((m24->cgamode & 0x12) == 0x12) ? 0 : (m24->cgacol & 15) + 16;
|
||||
if (m24->cgamode & 1) hline(buffer, 0, m24->displine, (m24->crtc[1] << 3) + 16, cols[0]);
|
||||
else hline(buffer, 0, m24->displine, (m24->crtc[1] << 4) + 16, cols[0]);
|
||||
}
|
||||
|
||||
if (cgamode&1) x=(crtc[1]<<3)+16;
|
||||
else x=(crtc[1]<<4)+16;
|
||||
if (m24->cgamode & 1) x = (m24->crtc[1] << 3) + 16;
|
||||
else x = (m24->crtc[1] << 4) + 16;
|
||||
|
||||
sc=oldsc;
|
||||
if (vc==crtc[7] && !sc)
|
||||
cgastat|=8;
|
||||
displine++;
|
||||
if (displine>=720) displine=0;
|
||||
m24->sc = oldsc;
|
||||
if (m24->vc == m24->crtc[7] && !m24->sc)
|
||||
m24->stat |= 8;
|
||||
m24->displine++;
|
||||
if (m24->displine >= 720) m24->displine = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// pclog("Line poll %i %i %i %i\n", m24_lineff, vc, sc, vadj);
|
||||
vidtime+=dispontime;
|
||||
if (cgadispon) cgastat&=~1;
|
||||
linepos=0;
|
||||
m24_lineff ^= 1;
|
||||
if (m24_lineff)
|
||||
m24->vidtime += m24->dispontime;
|
||||
if (m24->dispon) m24->stat &= ~1;
|
||||
m24->linepos = 0;
|
||||
m24->lineff ^= 1;
|
||||
if (m24->lineff)
|
||||
{
|
||||
ma = maback;
|
||||
m24->ma = m24->maback;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vsynctime)
|
||||
if (m24->vsynctime)
|
||||
{
|
||||
vsynctime--;
|
||||
if (!vsynctime)
|
||||
cgastat&=~8;
|
||||
m24->vsynctime--;
|
||||
if (!m24->vsynctime)
|
||||
m24->stat &= ~8;
|
||||
}
|
||||
if (sc==(crtc[11]&31) || ((crtc[8]&3)==3 && sc==((crtc[11]&31)>>1))) { con=0; coff=1; }
|
||||
if (vadj)
|
||||
if (m24->sc == (m24->crtc[11] & 31) || ((m24->crtc[8] & 3) == 3 && m24->sc == ((m24->crtc[11] & 31) >> 1)))
|
||||
{
|
||||
m24->con = 0;
|
||||
m24->coff = 1;
|
||||
}
|
||||
if (m24->vadj)
|
||||
{
|
||||
sc++;
|
||||
sc&=31;
|
||||
ma=maback;
|
||||
vadj--;
|
||||
if (!vadj)
|
||||
m24->sc++;
|
||||
m24->sc &= 31;
|
||||
m24->ma = m24->maback;
|
||||
m24->vadj--;
|
||||
if (!m24->vadj)
|
||||
{
|
||||
cgadispon=1;
|
||||
ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
|
||||
sc=0;
|
||||
m24->dispon = 1;
|
||||
m24->ma = m24->maback = (m24->crtc[13] | (m24->crtc[12] << 8)) & 0x3fff;
|
||||
m24->sc = 0;
|
||||
}
|
||||
}
|
||||
else if (sc==crtc[9] || ((crtc[8]&3)==3 && sc==(crtc[9]>>1)))
|
||||
else if (m24->sc == m24->crtc[9] || ((m24->crtc[8] & 3) == 3 && m24->sc == (m24->crtc[9] >> 1)))
|
||||
{
|
||||
maback=ma;
|
||||
sc=0;
|
||||
oldvc=vc;
|
||||
vc++;
|
||||
vc&=127;
|
||||
m24->maback = m24->ma;
|
||||
m24->sc = 0;
|
||||
oldvc = m24->vc;
|
||||
m24->vc++;
|
||||
m24->vc &= 127;
|
||||
|
||||
if (vc==crtc[6])
|
||||
cgadispon=0;
|
||||
if (m24->vc == m24->crtc[6])
|
||||
m24->dispon=0;
|
||||
|
||||
if (oldvc==crtc[4])
|
||||
if (oldvc == m24->crtc[4])
|
||||
{
|
||||
vc=0;
|
||||
vadj=crtc[5];
|
||||
if (!vadj) cgadispon=1;
|
||||
if (!vadj) ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
|
||||
if ((crtc[10]&0x60)==0x20) cursoron=0;
|
||||
else cursoron=cgablink&16;
|
||||
m24->vc = 0;
|
||||
m24->vadj = m24->crtc[5];
|
||||
if (!m24->vadj) m24->dispon = 1;
|
||||
if (!m24->vadj) m24->ma = m24->maback = (m24->crtc[13] | (m24->crtc[12] << 8)) & 0x3fff;
|
||||
if ((m24->crtc[10] & 0x60) == 0x20) m24->cursoron = 0;
|
||||
else m24->cursoron = m24->blink & 16;
|
||||
}
|
||||
|
||||
if (vc==crtc[7])
|
||||
if (m24->vc == m24->crtc[7])
|
||||
{
|
||||
cgadispon=0;
|
||||
displine=0;
|
||||
vsynctime=(crtc[3]>>4)+1;
|
||||
if (crtc[7])
|
||||
m24->dispon = 0;
|
||||
m24->displine = 0;
|
||||
m24->vsynctime = (m24->crtc[3] >> 4) + 1;
|
||||
if (m24->crtc[7])
|
||||
{
|
||||
if (cgamode&1) x=(crtc[1]<<3)+16;
|
||||
else x=(crtc[1]<<4)+16;
|
||||
lastline++;
|
||||
if (x!=xsize || (lastline-firstline)!=ysize)
|
||||
if (m24->cgamode & 1) x = (m24->crtc[1] << 3) + 16;
|
||||
else x = (m24->crtc[1] << 4) + 16;
|
||||
m24->lastline++;
|
||||
if (x != xsize || (m24->lastline - m24->firstline) != ysize)
|
||||
{
|
||||
xsize=x;
|
||||
ysize=lastline-firstline;
|
||||
if (xsize<64) xsize=656;
|
||||
if (ysize<32) ysize=200;
|
||||
xsize = x;
|
||||
ysize = m24->lastline - m24->firstline;
|
||||
if (xsize < 64) xsize = 656;
|
||||
if (ysize < 32) ysize = 200;
|
||||
updatewindowsize(xsize, ysize + 16);
|
||||
}
|
||||
startblit();
|
||||
video_blit_memtoscreen_8(0, firstline - 8, xsize, (lastline - firstline) + 16);
|
||||
if (readflash) rectfill(screen,winsizex-40,8,winsizex-8,14,0xFFFFFFFF);
|
||||
readflash=0;
|
||||
pclog("m24 blit %i %i\n", m24->firstline, m24->lastline);
|
||||
video_blit_memtoscreen_8(0, m24->firstline - 8, xsize, (m24->lastline - m24->firstline) + 16);
|
||||
if (readflash) rectfill(screen, winsizex - 40, 8, winsizex - 8, 14, 0xFFFFFFFF);
|
||||
readflash = 0;
|
||||
frames++;
|
||||
endblit();
|
||||
video_res_x = xsize - 16;
|
||||
video_res_y = ysize;
|
||||
if (cgamode & 1)
|
||||
if (m24->cgamode & 1)
|
||||
{
|
||||
video_res_x /= 8;
|
||||
video_res_y /= (crtc[9] + 1) * 2;
|
||||
video_res_y /= (m24->crtc[9] + 1) * 2;
|
||||
video_bpp = 0;
|
||||
}
|
||||
else if (!(cgamode & 2))
|
||||
else if (!(m24->cgamode & 2))
|
||||
{
|
||||
video_res_x /= 16;
|
||||
video_res_y /= (crtc[9] + 1) * 2;
|
||||
video_res_y /= (m24->crtc[9] + 1) * 2;
|
||||
video_bpp = 0;
|
||||
}
|
||||
else if (!(cgamode&16))
|
||||
else if (!(m24->cgamode & 16))
|
||||
{
|
||||
video_res_x /= 2;
|
||||
video_res_y /= 2;
|
||||
video_bpp = 2;
|
||||
}
|
||||
else if (!(m24_ctrl & 1))
|
||||
else if (!(m24->ctrl & 1))
|
||||
{
|
||||
video_res_y /= 2;
|
||||
video_bpp = 1;
|
||||
}
|
||||
}
|
||||
firstline=1000;
|
||||
lastline=0;
|
||||
cgablink++;
|
||||
m24->firstline = 1000;
|
||||
m24->lastline = 0;
|
||||
m24->blink++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sc++;
|
||||
sc&=31;
|
||||
ma=maback;
|
||||
m24->sc++;
|
||||
m24->sc &= 31;
|
||||
m24->ma = m24->maback;
|
||||
}
|
||||
if ((sc==(crtc[10]&31) || ((crtc[8]&3)==3 && sc==((crtc[10]&31)>>1)))) con=1;
|
||||
if ((m24->sc == (m24->crtc[10] & 31) || ((m24->crtc[8] & 3) == 3 && m24->sc == ((m24->crtc[10] & 31) >> 1))))
|
||||
m24->con = 1;
|
||||
}
|
||||
if (cgadispon && (cgamode&1))
|
||||
if (m24->dispon && (m24->cgamode & 1))
|
||||
{
|
||||
for (x=0;x<(crtc[1]<<1);x++)
|
||||
charbuffer[x]=vram[(((ma<<1)+x)&0x3FFF) + m24_base];
|
||||
for (x = 0; x < (m24->crtc[1] << 1); x++)
|
||||
m24->charbuffer[x] = m24->vram[(((m24->ma << 1) + x) & 0x3fff) + m24->base];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int m24_init()
|
||||
void *m24_init()
|
||||
{
|
||||
mem_sethandler(0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL, NULL);
|
||||
return 0;
|
||||
int c;
|
||||
m24_t *m24 = malloc(sizeof(m24_t));
|
||||
memset(m24, 0, sizeof(m24_t));
|
||||
|
||||
m24->vram = malloc(0x8000);
|
||||
|
||||
timer_add(m24_poll, &m24->vidtime, TIMER_ALWAYS_ENABLED, m24);
|
||||
mem_sethandler(0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL, m24);
|
||||
io_sethandler(0x03d0, 0x0010, m24_in, NULL, NULL, m24_out, NULL, NULL, m24);
|
||||
return m24;
|
||||
}
|
||||
|
||||
GFXCARD vid_m24 =
|
||||
void m24_close(void *p)
|
||||
{
|
||||
m24_t *m24 = (m24_t *)p;
|
||||
|
||||
free(m24->vram);
|
||||
free(m24);
|
||||
}
|
||||
|
||||
void m24_speed_changed(void *p)
|
||||
{
|
||||
m24_t *m24 = (m24_t *)p;
|
||||
|
||||
m24_recalctimings(m24);
|
||||
}
|
||||
|
||||
device_t m24_device =
|
||||
{
|
||||
"Olivetti M24 (video)",
|
||||
m24_init,
|
||||
/*IO at 3Cx/3Dx*/
|
||||
m24_out,
|
||||
m24_in,
|
||||
/*IO at 3Ax/3Bx*/
|
||||
video_out_null,
|
||||
video_in_null,
|
||||
|
||||
m24_poll,
|
||||
m24_recalctimings,
|
||||
|
||||
video_write_null,
|
||||
video_write_null,
|
||||
m24_write,
|
||||
|
||||
video_read_null,
|
||||
video_read_null,
|
||||
m24_read
|
||||
m24_close,
|
||||
m24_speed_changed,
|
||||
NULL
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
extern device_t m24_device;
|
||||
141
src/vid_oti067.c
141
src/vid_oti067.c
|
|
@ -1,126 +1,151 @@
|
|||
/*Oak OTI067 emulation*/
|
||||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "io.h"
|
||||
#include "video.h"
|
||||
#include "vid_oti067.h"
|
||||
#include "vid_svga.h"
|
||||
|
||||
static int oti067_index;
|
||||
static uint8_t oti067_regs[32];
|
||||
|
||||
void oti067_out(uint16_t addr, uint8_t val, void *priv)
|
||||
typedef struct oti067_t
|
||||
{
|
||||
svga_t svga;
|
||||
|
||||
int index;
|
||||
uint8_t regs[32];
|
||||
} oti067_t;
|
||||
|
||||
void oti067_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
oti067_t *oti067 = (oti067_t *)p;
|
||||
svga_t *svga = &oti067->svga;
|
||||
uint8_t old;
|
||||
|
||||
// pclog("oti067_out : %04X %02X %02X %i\n", addr, val, ram[0x489], ins);
|
||||
|
||||
if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3D4:
|
||||
crtcreg=val&31;
|
||||
svga->crtcreg = val & 31;
|
||||
return;
|
||||
case 0x3D5:
|
||||
if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
|
||||
old=crtc[crtcreg];
|
||||
crtc[crtcreg]=val;
|
||||
if (old!=val)
|
||||
if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
if (old != val)
|
||||
{
|
||||
if (crtcreg<0xE || crtcreg>0x10)
|
||||
if (svga->crtcreg < 0xE || svga->crtcreg > 0x10)
|
||||
{
|
||||
fullchange=changeframecount;
|
||||
svga_recalctimings();
|
||||
fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3DE: oti067_index=val&0x1F; return;
|
||||
case 0x3DE:
|
||||
oti067->index = val & 0x1f;
|
||||
return;
|
||||
case 0x3DF:
|
||||
oti067_regs[oti067_index]=val;
|
||||
switch (oti067_index)
|
||||
oti067->regs[oti067->index] = val;
|
||||
switch (oti067->index)
|
||||
{
|
||||
case 0xD:
|
||||
vrammask=(val&0xC)?0x7FFFF:0x3FFFF;
|
||||
svga->vrammask = (val & 0xc) ? 0x7ffff : 0x3ffff;
|
||||
break;
|
||||
case 0x11:
|
||||
svgarbank=(val&0xF)*65536;
|
||||
svgawbank=(val>>4)*65536;
|
||||
svga->read_bank = (val & 0xf) * 65536;
|
||||
svga->write_bank = (val >> 4) * 65536;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
svga_out(addr, val, NULL);
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
uint8_t oti067_in(uint16_t addr, void *priv)
|
||||
uint8_t oti067_in(uint16_t addr, void *p)
|
||||
{
|
||||
oti067_t *oti067 = (oti067_t *)p;
|
||||
svga_t *svga = &oti067->svga;
|
||||
uint8_t temp;
|
||||
|
||||
// if (addr != 0x3da && addr != 0x3ba) pclog("oti067_in : %04X ", addr);
|
||||
|
||||
if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3D4:
|
||||
temp = crtcreg;
|
||||
temp = svga->crtcreg;
|
||||
break;
|
||||
case 0x3D5:
|
||||
temp = crtc[crtcreg];
|
||||
temp = svga->crtc[svga->crtcreg];
|
||||
break;
|
||||
|
||||
case 0x3DE:
|
||||
temp = oti067_index|(2<<5);
|
||||
temp = oti067->index | (2 << 5);
|
||||
break;
|
||||
case 0x3DF:
|
||||
if (oti067_index==0x10) temp = 0x18;
|
||||
else if (oti067_index==0xD) temp = oti067_regs[oti067_index]|0xC0;
|
||||
else temp = oti067_regs[oti067_index];
|
||||
if (oti067->index==0x10) temp = 0x18;
|
||||
else if (oti067->index==0xD) temp = oti067->regs[oti067->index]|0xC0;
|
||||
else temp = oti067->regs[oti067->index];
|
||||
break;
|
||||
|
||||
default:
|
||||
temp = svga_in(addr, NULL);
|
||||
temp = svga_in(addr, svga);
|
||||
break;
|
||||
}
|
||||
// if (addr != 0x3da && addr != 0x3ba) pclog("%02X %04X:%04X\n", temp, CS,pc);
|
||||
return temp;
|
||||
}
|
||||
|
||||
void oti067_recalctimings()
|
||||
void oti067_recalctimings(svga_t *svga)
|
||||
{
|
||||
if (oti067_regs[0x14]&0x08) svga_ma|=0x10000;
|
||||
if (oti067_regs[0x0D]&0x0C) svga_rowoffset<<=1;
|
||||
svga_interlace = oti067_regs[0x14]&0x80;
|
||||
oti067_t *oti067 = (oti067_t *)svga->p;
|
||||
|
||||
if (oti067->regs[0x14] & 0x08) svga->ma_latch |= 0x10000;
|
||||
if (oti067->regs[0x0d] & 0x0c) svga->rowoffset <<= 1;
|
||||
svga->interlace = oti067->regs[0x14] & 0x80;
|
||||
}
|
||||
|
||||
int oti067_init()
|
||||
void *oti067_init()
|
||||
{
|
||||
svga_recalctimings_ex = oti067_recalctimings;
|
||||
svga_vram_limit = 1 << 19; /*512kb*/
|
||||
vrammask = 0x7ffff;
|
||||
bpp = 8;
|
||||
svga_miscout = 1;
|
||||
return svga_init();
|
||||
oti067_t *oti067 = malloc(sizeof(oti067_t));
|
||||
memset(oti067, 0, sizeof(oti067_t));
|
||||
|
||||
svga_init(&oti067->svga, oti067, 1 << 19, /*512kb*/
|
||||
oti067_recalctimings,
|
||||
oti067_in, oti067_out,
|
||||
NULL);
|
||||
|
||||
io_sethandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067);
|
||||
|
||||
oti067->svga.miscout = 1;
|
||||
return oti067;
|
||||
}
|
||||
|
||||
GFXCARD vid_oti067 =
|
||||
void oti067_close(void *p)
|
||||
{
|
||||
oti067_t *oti067 = (oti067_t *)p;
|
||||
|
||||
svga_close(&oti067->svga);
|
||||
|
||||
free(oti067);
|
||||
}
|
||||
|
||||
void oti067_speed_changed(void *p)
|
||||
{
|
||||
oti067_t *oti067 = (oti067_t *)p;
|
||||
|
||||
svga_recalctimings(&oti067->svga);
|
||||
}
|
||||
|
||||
device_t oti067_device =
|
||||
{
|
||||
"Oak OTI-067",
|
||||
oti067_init,
|
||||
/*IO at 3Cx/3Dx*/
|
||||
oti067_out,
|
||||
oti067_in,
|
||||
/*IO at 3Ax/3Bx*/
|
||||
video_out_null,
|
||||
video_in_null,
|
||||
|
||||
svga_poll,
|
||||
svga_recalctimings,
|
||||
|
||||
svga_write,
|
||||
video_write_null,
|
||||
video_write_null,
|
||||
|
||||
svga_read,
|
||||
video_read_null,
|
||||
video_read_null
|
||||
oti067_close,
|
||||
oti067_speed_changed,
|
||||
svga_add_status_info
|
||||
};
|
||||
|
|
|
|||
1
src/vid_oti067.h
Normal file
1
src/vid_oti067.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
extern device_t oti067_device;
|
||||
|
|
@ -3,271 +3,335 @@
|
|||
PC2086, PC3086 use PVGA1A
|
||||
MegaPC uses W90C11A
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "mem.h"
|
||||
#include "video.h"
|
||||
#include "vid_paradise.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_svga_render.h"
|
||||
#include "vid_unk_ramdac.h"
|
||||
|
||||
void paradise_write(uint32_t addr, uint8_t val, void *priv);
|
||||
uint8_t paradise_read(uint32_t addr, void *priv);
|
||||
void paradise_remap();
|
||||
|
||||
enum
|
||||
typedef struct paradise_t
|
||||
{
|
||||
PVGA1A = 0,
|
||||
WD90C11
|
||||
};
|
||||
svga_t svga;
|
||||
|
||||
enum
|
||||
{
|
||||
PVGA1A = 0,
|
||||
WD90C11
|
||||
} type;
|
||||
|
||||
static int paradise_type;
|
||||
uint32_t read_bank[4], write_bank[4];
|
||||
} paradise_t;
|
||||
|
||||
static uint32_t paradise_bank_r[4], paradise_bank_w[4];
|
||||
void paradise_write(uint32_t addr, uint8_t val, void *p);
|
||||
uint8_t paradise_read(uint32_t addr, void *p);
|
||||
void paradise_remap(paradise_t *paradise);
|
||||
|
||||
void paradise_out(uint16_t addr, uint8_t val, void *priv)
|
||||
|
||||
void paradise_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
paradise_t *paradise = (paradise_t *)p;
|
||||
svga_t *svga = ¶dise->svga;
|
||||
uint8_t old;
|
||||
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
// output = 3;
|
||||
pclog("Paradise out %04X %02X %04X:%04X\n", addr, val, CS, pc);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3c5:
|
||||
if (seqaddr > 7)
|
||||
if (svga->seqaddr > 7)
|
||||
{
|
||||
if (paradise_type < WD90C11 || seqregs[6] != 0x48)
|
||||
if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48)
|
||||
return;
|
||||
seqregs[seqaddr & 0x1f] = val;
|
||||
if (seqaddr == 0x11)
|
||||
paradise_remap();
|
||||
svga->seqregs[svga->seqaddr & 0x1f] = val;
|
||||
if (svga->seqaddr == 0x11)
|
||||
paradise_remap(paradise);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3cf:
|
||||
if (gdcaddr >= 0x9 && gdcaddr < 0xf)
|
||||
if (svga->gdcaddr >= 0x9 && svga->gdcaddr < 0xf)
|
||||
{
|
||||
if ((gdcreg[0xf] & 7) != 5)
|
||||
if ((svga->gdcreg[0xf] & 7) != 5)
|
||||
return;
|
||||
}
|
||||
if (gdcaddr == 6)
|
||||
if (svga->gdcaddr == 6)
|
||||
{
|
||||
if ((gdcreg[6] & 0xc) != (val & 0xc))
|
||||
if ((svga->gdcreg[6] & 0xc) != (val & 0xc))
|
||||
{
|
||||
mem_removehandler(0xa0000, 0x20000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL);
|
||||
mem_removehandler(0xa0000, 0x20000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, paradise);
|
||||
// pclog("Write mapping %02X\n", val);
|
||||
switch (val&0xC)
|
||||
{
|
||||
case 0x0: /*128k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x20000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL);
|
||||
mem_sethandler(0xa0000, 0x20000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, paradise);
|
||||
break;
|
||||
case 0x4: /*64k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x10000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL);
|
||||
mem_sethandler(0xa0000, 0x10000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, paradise);
|
||||
break;
|
||||
case 0x8: /*32k at B0000*/
|
||||
mem_sethandler(0xb0000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL);
|
||||
mem_sethandler(0xb0000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, paradise);
|
||||
break;
|
||||
case 0xC: /*32k at B8000*/
|
||||
mem_sethandler(0xb8000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL);
|
||||
mem_sethandler(0xb8000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, paradise);
|
||||
break;
|
||||
}
|
||||
}
|
||||
gdcreg[6] = val;
|
||||
paradise_remap();
|
||||
svga->gdcreg[6] = val;
|
||||
paradise_remap(paradise);
|
||||
return;
|
||||
}
|
||||
if (gdcaddr == 0x9 || gdcaddr == 0xa)
|
||||
if (svga->gdcaddr == 0x9 || svga->gdcaddr == 0xa)
|
||||
{
|
||||
gdcreg[gdcaddr] = val;
|
||||
paradise_remap();
|
||||
svga->gdcreg[svga->gdcaddr] = val;
|
||||
paradise_remap(paradise);
|
||||
return;
|
||||
}
|
||||
if (gdcaddr == 0xe)
|
||||
if (svga->gdcaddr == 0xe)
|
||||
{
|
||||
gdcreg[0xe] = val;
|
||||
paradise_remap();
|
||||
svga->gdcreg[0xe] = val;
|
||||
paradise_remap(paradise);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3D4:
|
||||
if (paradise_type == PVGA1A)
|
||||
crtcreg = val & 0x1f;
|
||||
if (paradise->type == PVGA1A)
|
||||
svga->crtcreg = val & 0x1f;
|
||||
else
|
||||
crtcreg = val & 0x3f;
|
||||
svga->crtcreg = val & 0x3f;
|
||||
return;
|
||||
case 0x3D5:
|
||||
if (crtcreg <= 7 && crtc[0x11] & 0x80)
|
||||
if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80)
|
||||
return;
|
||||
if (crtcreg > 0x29 && (crtc[0x29] & 7) != 5)
|
||||
if (svga->crtcreg > 0x29 && (svga->crtc[0x29] & 7) != 5)
|
||||
return;
|
||||
if (crtcreg >= 0x31 && crtcreg <= 0x37)
|
||||
if (svga->crtcreg >= 0x31 && svga->crtcreg <= 0x37)
|
||||
return;
|
||||
old=crtc[crtcreg];
|
||||
crtc[crtcreg]=val;
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
|
||||
if (old!=val)
|
||||
if (old != val)
|
||||
{
|
||||
if (crtcreg<0xE || crtcreg>0x10)
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
|
||||
{
|
||||
fullchange=changeframecount;
|
||||
svga_recalctimings();
|
||||
fullchange = changeframecount;
|
||||
svga_recalctimings(¶dise->svga);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
svga_out(addr, val, NULL);
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
uint8_t paradise_in(uint16_t addr, void *priv)
|
||||
uint8_t paradise_in(uint16_t addr, void *p)
|
||||
{
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
paradise_t *paradise = (paradise_t *)p;
|
||||
svga_t *svga = ¶dise->svga;
|
||||
|
||||
// if (addr != 0x3da) pclog("Paradise in %04X\n", addr);
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
if (addr != 0x3da) pclog("Paradise in %04X\n", addr);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3c2:
|
||||
return 0x10;
|
||||
|
||||
case 0x3c5:
|
||||
if (seqaddr > 7)
|
||||
if (svga->seqaddr > 7)
|
||||
{
|
||||
if (paradise_type < WD90C11 || seqregs[6] != 0x48)
|
||||
if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48)
|
||||
return 0xff;
|
||||
if (seqaddr > 0x12)
|
||||
if (svga->seqaddr > 0x12)
|
||||
return 0xff;
|
||||
return seqregs[seqaddr & 0x1f];
|
||||
return svga->seqregs[svga->seqaddr & 0x1f];
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3cf:
|
||||
if (gdcaddr >= 0x9 && gdcaddr < 0xf)
|
||||
if (svga->gdcaddr >= 0x9 && svga->gdcaddr < 0xf)
|
||||
{
|
||||
if (gdcreg[0xf] & 0x10)
|
||||
if (svga->gdcreg[0xf] & 0x10)
|
||||
return 0xff;
|
||||
switch (gdcaddr)
|
||||
switch (svga->gdcaddr)
|
||||
{
|
||||
case 0xf:
|
||||
return (gdcreg[0xf] & 0x17) | 0x80;
|
||||
return (svga->gdcreg[0xf] & 0x17) | 0x80;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3D4:
|
||||
return crtcreg;
|
||||
return svga->crtcreg;
|
||||
case 0x3D5:
|
||||
if (crtcreg > 0x29 && crtcreg < 0x30 && (crtc[0x29] & 0x88) != 0x80)
|
||||
if (svga->crtcreg > 0x29 && svga->crtcreg < 0x30 && (svga->crtc[0x29] & 0x88) != 0x80)
|
||||
return 0xff;
|
||||
return crtc[crtcreg];
|
||||
return svga->crtc[svga->crtcreg];
|
||||
}
|
||||
return svga_in(addr, NULL);
|
||||
return svga_in(addr, svga);
|
||||
}
|
||||
|
||||
void paradise_remap()
|
||||
void paradise_remap(paradise_t *paradise)
|
||||
{
|
||||
if (seqregs[0x11] & 0x80)
|
||||
svga_t *svga = ¶dise->svga;
|
||||
|
||||
if (svga->seqregs[0x11] & 0x80)
|
||||
{
|
||||
// pclog("Remap 1\n");
|
||||
paradise_bank_r[0] = paradise_bank_r[2] = (gdcreg[0x9] & 0x7f) << 12;
|
||||
paradise_bank_r[1] = paradise_bank_r[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
paradise_bank_w[0] = paradise_bank_w[2] = (gdcreg[0xa] & 0x7f) << 12;
|
||||
paradise_bank_w[1] = paradise_bank_w[3] = ((gdcreg[0xa] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12;
|
||||
paradise->read_bank[1] = paradise->read_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0xa] & 0x7f) << 12;
|
||||
paradise->write_bank[1] = paradise->write_bank[3] = ((svga->gdcreg[0xa] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
}
|
||||
else if (gdcreg[0xe] & 0x08)
|
||||
else if (svga->gdcreg[0xe] & 0x08)
|
||||
{
|
||||
if (gdcreg[0x6] & 0xc)
|
||||
if (svga->gdcreg[0x6] & 0xc)
|
||||
{
|
||||
// pclog("Remap 2\n");
|
||||
paradise_bank_r[0] = paradise_bank_r[2] = (gdcreg[0xa] & 0x7f) << 12;
|
||||
paradise_bank_w[0] = paradise_bank_w[2] = (gdcreg[0xa] & 0x7f) << 12;
|
||||
paradise_bank_r[1] = paradise_bank_r[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
paradise_bank_w[1] = paradise_bank_w[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0xa] & 0x7f) << 12;
|
||||
paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0xa] & 0x7f) << 12;
|
||||
paradise->read_bank[1] = paradise->read_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
paradise->write_bank[1] = paradise->write_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
}
|
||||
else
|
||||
{
|
||||
// pclog("Remap 3\n");
|
||||
paradise_bank_r[0] = paradise_bank_w[0] = (gdcreg[0xa] & 0x7f) << 12;
|
||||
paradise_bank_r[1] = paradise_bank_w[1] = ((gdcreg[0xa] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
paradise_bank_r[2] = paradise_bank_w[2] = (gdcreg[0x9] & 0x7f) << 12;
|
||||
paradise_bank_r[3] = paradise_bank_w[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
paradise->read_bank[0] = paradise->write_bank[0] = (svga->gdcreg[0xa] & 0x7f) << 12;
|
||||
paradise->read_bank[1] = paradise->write_bank[1] = ((svga->gdcreg[0xa] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
paradise->read_bank[2] = paradise->write_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12;
|
||||
paradise->read_bank[3] = paradise->write_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// pclog("Remap 4\n");
|
||||
paradise_bank_r[0] = paradise_bank_r[2] = (gdcreg[0x9] & 0x7f) << 12;
|
||||
paradise_bank_r[1] = paradise_bank_r[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
paradise_bank_w[0] = paradise_bank_w[2] = (gdcreg[0x9] & 0x7f) << 12;
|
||||
paradise_bank_w[1] = paradise_bank_w[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12;
|
||||
paradise->read_bank[1] = paradise->read_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12;
|
||||
paradise->write_bank[1] = paradise->write_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
}
|
||||
// pclog("Remap - %04X %04X\n", paradise_bank_r[0], paradise_bank_w[0]);
|
||||
// pclog("Remap - %04X %04X\n", paradise->read_bank[0], paradise->write_bank[0]);
|
||||
}
|
||||
|
||||
void paradise_recalctimings()
|
||||
void paradise_recalctimings(svga_t *svga)
|
||||
{
|
||||
svga_lowres = !(gdcreg[0xe] & 0x01);
|
||||
svga->lowres = !(svga->gdcreg[0xe] & 0x01);
|
||||
if (svga->bpp == 8 && !svga->lowres)
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
}
|
||||
|
||||
#define egacycles 1
|
||||
#define egacycles2 1
|
||||
void paradise_write(uint32_t addr, uint8_t val, void *priv)
|
||||
void paradise_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
paradise_t *paradise = (paradise_t *)p;
|
||||
// pclog("paradise_write : %05X %02X ", addr, val);
|
||||
addr = (addr & 0x7fff) + paradise_bank_w[(addr >> 15) & 3];
|
||||
addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3];
|
||||
// pclog("%08X\n", addr);
|
||||
svga_write_linear(addr, val, priv);
|
||||
svga_write_linear(addr, val, ¶dise->svga);
|
||||
}
|
||||
|
||||
uint8_t paradise_read(uint32_t addr, void *priv)
|
||||
uint8_t paradise_read(uint32_t addr, void *p)
|
||||
{
|
||||
paradise_t *paradise = (paradise_t *)p;
|
||||
// pclog("paradise_read : %05X ", addr);
|
||||
addr = (addr & 0x7fff) + paradise_bank_r[(addr >> 15) & 3];
|
||||
addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3];
|
||||
// pclog("%08X\n", addr);
|
||||
return svga_read_linear(addr, priv);
|
||||
return svga_read_linear(addr, ¶dise->svga);
|
||||
}
|
||||
|
||||
int paradise_init()
|
||||
void *paradise_pvga1a_init()
|
||||
{
|
||||
if (romset == ROM_PC2086 || romset == ROM_PC3086)
|
||||
{
|
||||
paradise_type = PVGA1A;
|
||||
vrammask = 0x3ffff;
|
||||
pclog("Init PVGA1A\n");
|
||||
svga_vram_limit = 1 << 18; /*256kb*/
|
||||
}
|
||||
if (romset == ROM_MEGAPC)
|
||||
{
|
||||
paradise_type = WD90C11;
|
||||
vrammask = 0x7ffff;
|
||||
crtc[0x36] = '1';
|
||||
crtc[0x37] = '1';
|
||||
pclog("Init WD90C11\n");
|
||||
svga_vram_limit = 1 << 19; /*512kb*/
|
||||
}
|
||||
crtc[0x31] = 'W';
|
||||
crtc[0x32] = 'D';
|
||||
crtc[0x33] = '9';
|
||||
crtc[0x34] = '0';
|
||||
crtc[0x35] = 'C';
|
||||
svga_recalctimings_ex = paradise_recalctimings;
|
||||
return svga_init();
|
||||
paradise_t *paradise = malloc(sizeof(paradise_t));
|
||||
svga_t *svga = ¶dise->svga;
|
||||
memset(paradise, 0, sizeof(paradise_t));
|
||||
|
||||
io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise);
|
||||
|
||||
svga_init(¶dise->svga, paradise, 1 << 18, /*256kb*/
|
||||
NULL,
|
||||
paradise_in, paradise_out,
|
||||
NULL);
|
||||
|
||||
svga->crtc[0x31] = 'W';
|
||||
svga->crtc[0x32] = 'D';
|
||||
svga->crtc[0x33] = '9';
|
||||
svga->crtc[0x34] = '0';
|
||||
svga->crtc[0x35] = 'C';
|
||||
|
||||
svga->bpp = 8;
|
||||
svga->miscout = 1;
|
||||
|
||||
paradise->type = PVGA1A;
|
||||
|
||||
return paradise;
|
||||
}
|
||||
|
||||
GFXCARD vid_paradise =
|
||||
void *paradise_wd90c11_init()
|
||||
{
|
||||
paradise_init,
|
||||
/*IO at 3Cx/3Dx*/
|
||||
paradise_out,
|
||||
paradise_in,
|
||||
/*IO at 3Ax/3Bx*/
|
||||
video_out_null,
|
||||
video_in_null,
|
||||
paradise_t *paradise = malloc(sizeof(paradise_t));
|
||||
svga_t *svga = ¶dise->svga;
|
||||
memset(paradise, 0, sizeof(paradise_t));
|
||||
|
||||
io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise);
|
||||
|
||||
svga_poll,
|
||||
svga_recalctimings,
|
||||
svga_init(¶dise->svga, paradise, 1 << 19, /*512kb*/
|
||||
paradise_recalctimings,
|
||||
paradise_in, paradise_out,
|
||||
NULL);
|
||||
|
||||
paradise_write,
|
||||
video_write_null,
|
||||
video_write_null,
|
||||
svga->crtc[0x31] = 'W';
|
||||
svga->crtc[0x32] = 'D';
|
||||
svga->crtc[0x33] = '9';
|
||||
svga->crtc[0x34] = '0';
|
||||
svga->crtc[0x35] = 'C';
|
||||
svga->crtc[0x36] = '1';
|
||||
svga->crtc[0x37] = '1';
|
||||
|
||||
paradise_read,
|
||||
video_read_null,
|
||||
video_read_null
|
||||
svga->bpp = 8;
|
||||
svga->miscout = 1;
|
||||
|
||||
paradise->type = WD90C11;
|
||||
|
||||
return paradise;
|
||||
}
|
||||
|
||||
void paradise_close(void *p)
|
||||
{
|
||||
paradise_t *paradise = (paradise_t *)p;
|
||||
|
||||
svga_close(¶dise->svga);
|
||||
|
||||
free(paradise);
|
||||
}
|
||||
|
||||
void paradise_speed_changed(void *p)
|
||||
{
|
||||
paradise_t *paradise = (paradise_t *)p;
|
||||
|
||||
svga_recalctimings(¶dise->svga);
|
||||
}
|
||||
|
||||
device_t paradise_pvga1a_device =
|
||||
{
|
||||
"Paradise PVGA1A",
|
||||
paradise_pvga1a_init,
|
||||
paradise_close,
|
||||
paradise_speed_changed,
|
||||
svga_add_status_info
|
||||
};
|
||||
device_t paradise_wd90c11_device =
|
||||
{
|
||||
"Paradise WD90C11",
|
||||
paradise_wd90c11_init,
|
||||
paradise_close,
|
||||
paradise_speed_changed,
|
||||
svga_add_status_info
|
||||
};
|
||||
|
|
|
|||
2
src/vid_paradise.h
Normal file
2
src/vid_paradise.h
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
extern device_t paradise_pvga1a_device;
|
||||
extern device_t paradise_wd90c11_device;
|
||||
578
src/vid_pc1512.c
578
src/vid_pc1512.c
|
|
@ -6,263 +6,289 @@
|
|||
|
||||
The Technical Reference Manual lists the video waitstate time as between 12
|
||||
and 46 cycles. PCem currently always uses the lower number.*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "timer.h"
|
||||
#include "video.h"
|
||||
#include "vid_cga.h"
|
||||
#include "vid_pc1512.h"
|
||||
|
||||
static uint8_t pc1512_plane_write,pc1512_plane_read,pc1512_border;
|
||||
|
||||
void pc1512_recalctimings();
|
||||
|
||||
void pc1512_out(uint16_t addr, uint8_t val, void *priv)
|
||||
typedef struct pc1512_t
|
||||
{
|
||||
uint8_t crtc[32];
|
||||
int crtcreg;
|
||||
|
||||
uint8_t cgacol, cgamode, stat;
|
||||
|
||||
uint8_t plane_write, plane_read, border;
|
||||
|
||||
int linepos, displine;
|
||||
int sc, vc;
|
||||
int cgadispon;
|
||||
int con, coff, cursoron, cgablink;
|
||||
int vsynctime, vadj;
|
||||
uint16_t ma, maback;
|
||||
int dispon;
|
||||
int blink;
|
||||
|
||||
int dispontime, dispofftime, vidtime;
|
||||
int firstline, lastline;
|
||||
|
||||
uint8_t *vram;
|
||||
} pc1512_t;
|
||||
|
||||
static uint8_t crtcmask[32] =
|
||||
{
|
||||
0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static void pc1512_recalctimings(pc1512_t *pc1512);
|
||||
|
||||
static void pc1512_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
pc1512_t *pc1512 = (pc1512_t *)p;
|
||||
uint8_t old;
|
||||
// pclog("PC1512 out %04X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||
pclog("PC1512 out %04X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3D4:
|
||||
crtcreg=val&31;
|
||||
case 0x3d4:
|
||||
pc1512->crtcreg = val & 31;
|
||||
return;
|
||||
case 0x3D5:
|
||||
old=crtc[crtcreg];
|
||||
crtc[crtcreg]=val&crtcmask[crtcreg];
|
||||
if (old!=val)
|
||||
case 0x3d5:
|
||||
old = pc1512->crtc[pc1512->crtcreg];
|
||||
pc1512->crtc[pc1512->crtcreg] = val & crtcmask[pc1512->crtcreg];
|
||||
if (old != val)
|
||||
{
|
||||
if (crtcreg<0xE || crtcreg>0x10)
|
||||
if (pc1512->crtcreg < 0xe || pc1512->crtcreg > 0x10)
|
||||
{
|
||||
fullchange=changeframecount;
|
||||
pc1512_recalctimings();
|
||||
fullchange = changeframecount;
|
||||
pc1512_recalctimings(pc1512);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case 0x3D8:
|
||||
if ((val&0x12)==0x12 && (cgamode&0x12)!=0x12)
|
||||
case 0x3d8:
|
||||
if ((val & 0x12) == 0x12 && (pc1512->cgamode & 0x12) != 0x12)
|
||||
{
|
||||
pc1512_plane_write=0xF;
|
||||
pc1512_plane_read =0;
|
||||
pc1512->plane_write = 0xf;
|
||||
pc1512->plane_read = 0;
|
||||
}
|
||||
cgamode=val;
|
||||
pc1512->cgamode = val;
|
||||
return;
|
||||
case 0x3D9:
|
||||
cgacol=val;
|
||||
case 0x3d9:
|
||||
pc1512->cgacol = val;
|
||||
return;
|
||||
case 0x3DD:
|
||||
pc1512_plane_write=val;
|
||||
case 0x3dd:
|
||||
pc1512->plane_write = val;
|
||||
return;
|
||||
case 0x3DE:
|
||||
pc1512_plane_read=val&3;
|
||||
case 0x3de:
|
||||
pc1512->plane_read = val & 3;
|
||||
return;
|
||||
case 0x3DF:
|
||||
pc1512_border=val;
|
||||
case 0x3df:
|
||||
pc1512->border = val;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t pc1512_in(uint16_t addr, void *priv)
|
||||
static uint8_t pc1512_in(uint16_t addr, void *p)
|
||||
{
|
||||
pc1512_t *pc1512 = (pc1512_t *)p;
|
||||
// pclog("PC1512 in %04X %02X %04X:%04X\n",addr,CS,pc);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3D4:
|
||||
return crtcreg;
|
||||
case 0x3D5:
|
||||
return crtc[crtcreg];
|
||||
case 0x3DA:
|
||||
return cgastat;
|
||||
case 0x3d4:
|
||||
return pc1512->crtcreg;
|
||||
case 0x3d5:
|
||||
return pc1512->crtc[pc1512->crtcreg];
|
||||
case 0x3da:
|
||||
return pc1512->stat;
|
||||
}
|
||||
return 0xFF;
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
void pc1512_write(uint32_t addr, uint8_t val, void *priv)
|
||||
static void pc1512_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
/* if (CS==0x023E && pc==0x524E)
|
||||
pc1512_t *pc1512 = (pc1512_t *)p;
|
||||
|
||||
cycles -= 12;
|
||||
addr &= 0x3fff;
|
||||
|
||||
if ((pc1512->cgamode & 0x12) == 0x12)
|
||||
{
|
||||
dumpregs();
|
||||
exit(-1);
|
||||
}
|
||||
pclog("PC1512 write %08X %02X %02X %01X %04X:%04X\n",addr,val,cgamode&0x12,pc1512_plane_write,CS,pc);*/
|
||||
cycles-=12;
|
||||
addr&=0x7FFF;
|
||||
if ((cgamode&0x12)==0x12)
|
||||
{
|
||||
if (pc1512_plane_write&1) vram[addr]=val;
|
||||
if (pc1512_plane_write&2) vram[addr|0x10000]=val;
|
||||
if (pc1512_plane_write&4) vram[addr|0x20000]=val;
|
||||
if (pc1512_plane_write&8) vram[addr|0x30000]=val;
|
||||
if (pc1512->plane_write & 1) pc1512->vram[addr] = val;
|
||||
if (pc1512->plane_write & 2) pc1512->vram[addr | 0x4000] = val;
|
||||
if (pc1512->plane_write & 4) pc1512->vram[addr | 0x8000] = val;
|
||||
if (pc1512->plane_write & 8) pc1512->vram[addr | 0xc000] = val;
|
||||
}
|
||||
else
|
||||
vram[addr]=val;
|
||||
pc1512->vram[addr] = val;
|
||||
}
|
||||
|
||||
uint8_t pc1512_read(uint32_t addr, void *priv)
|
||||
static uint8_t pc1512_read(uint32_t addr, void *p)
|
||||
{
|
||||
// pclog("PC1512 read %08X %02X %01X\n",addr,cgamode&0x12,pc1512_plane_read);
|
||||
cycles-=12;
|
||||
addr&=0x7FFF;
|
||||
if ((cgamode&0x12)==0x12)
|
||||
return vram[addr|(pc1512_plane_read<<16)];
|
||||
return vram[addr];
|
||||
pc1512_t *pc1512 = (pc1512_t *)p;
|
||||
|
||||
cycles -= 12;
|
||||
addr &= 0x3fff;
|
||||
|
||||
if ((pc1512->cgamode & 0x12) == 0x12)
|
||||
return pc1512->vram[addr | (pc1512->plane_read << 14)];
|
||||
return pc1512->vram[addr];
|
||||
}
|
||||
|
||||
|
||||
static int linepos,displine;
|
||||
static int sc,vc;
|
||||
static int cgadispon;
|
||||
static int con,coff,cursoron,cgablink;
|
||||
static int vsynctime,vadj;
|
||||
static uint16_t ma,maback;
|
||||
|
||||
int i_filt[8],q_filt[8];
|
||||
|
||||
|
||||
void pc1512_recalctimings()
|
||||
static void pc1512_recalctimings(pc1512_t *pc1512)
|
||||
{
|
||||
double _dispontime, _dispofftime;
|
||||
double _dispontime, _dispofftime, disptime;
|
||||
disptime = 128; /*Fixed on PC1512*/
|
||||
_dispontime = 80;
|
||||
_dispofftime=disptime-_dispontime;
|
||||
_dispofftime = disptime - _dispontime;
|
||||
// printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]);
|
||||
_dispontime*=CGACONST;
|
||||
_dispofftime*=CGACONST;
|
||||
_dispontime *= CGACONST;
|
||||
_dispofftime *= CGACONST;
|
||||
// printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92);
|
||||
dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||
dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
pc1512->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||
pc1512->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
}
|
||||
|
||||
void pc1512_poll()
|
||||
static void pc1512_poll(void *p)
|
||||
{
|
||||
uint16_t ca=(crtc[15]|(crtc[14]<<8))&0x3FFF;
|
||||
pc1512_t *pc1512 = (pc1512_t *)p;
|
||||
uint16_t ca = (pc1512->crtc[15] | (pc1512->crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x,c;
|
||||
int x, c;
|
||||
int oldvc;
|
||||
uint8_t chr,attr;
|
||||
uint16_t dat,dat2,dat3,dat4;
|
||||
uint8_t chr, attr;
|
||||
uint16_t dat, dat2, dat3, dat4;
|
||||
int cols[4];
|
||||
int col;
|
||||
int oldsc;
|
||||
|
||||
if (!linepos)
|
||||
if (!pc1512->linepos)
|
||||
{
|
||||
vidtime+=dispofftime;
|
||||
cgastat|=1;
|
||||
linepos=1;
|
||||
oldsc=sc;
|
||||
if (cgadispon)
|
||||
pc1512->vidtime += pc1512->dispofftime;
|
||||
pc1512->stat |= 1;
|
||||
pc1512->linepos = 1;
|
||||
oldsc = pc1512->sc;
|
||||
if (pc1512->dispon)
|
||||
{
|
||||
if (displine<firstline) firstline=displine;
|
||||
lastline=displine;
|
||||
for (c=0;c<8;c++)
|
||||
if (pc1512->displine < pc1512->firstline)
|
||||
pc1512->firstline = pc1512->displine;
|
||||
pc1512->lastline = pc1512->displine;
|
||||
for (c = 0; c < 8; c++)
|
||||
{
|
||||
if ((cgamode&0x12)==0x12)
|
||||
if ((pc1512->cgamode & 0x12) == 0x12)
|
||||
{
|
||||
buffer->line[displine][c]=(pc1512_border&15)+16;
|
||||
if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=0;
|
||||
else buffer->line[displine][c+(crtc[1]<<4)+8]=0;
|
||||
buffer->line[pc1512->displine][c] = (pc1512->border & 15) + 16;
|
||||
if (pc1512->cgamode & 1) buffer->line[pc1512->displine][c + (pc1512->crtc[1] << 3) + 8] = 0;
|
||||
else buffer->line[pc1512->displine][c + (pc1512->crtc[1] << 4) + 8] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer->line[displine][c]=(cgacol&15)+16;
|
||||
if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=(cgacol&15)+16;
|
||||
else buffer->line[displine][c+(crtc[1]<<4)+8]=(cgacol&15)+16;
|
||||
buffer->line[pc1512->displine][c] = (pc1512->cgacol & 15) + 16;
|
||||
if (pc1512->cgamode & 1) buffer->line[pc1512->displine][c + (pc1512->crtc[1] << 3) + 8] = (pc1512->cgacol & 15) + 16;
|
||||
else buffer->line[pc1512->displine][c + (pc1512->crtc[1] << 4) + 8] = (pc1512->cgacol & 15) + 16;
|
||||
}
|
||||
}
|
||||
if (cgamode&1)
|
||||
if (pc1512->cgamode & 1)
|
||||
{
|
||||
for (x = 0; x < 80; x++)
|
||||
{
|
||||
chr=vram[((ma<<1)&0x3FFF)];
|
||||
attr=vram[(((ma<<1)+1)&0x3FFF)];
|
||||
drawcursor=((ma==ca) && con && cursoron);
|
||||
if (cgamode&0x20)
|
||||
chr = pc1512->vram[ ((pc1512->ma << 1) & 0x3fff)];
|
||||
attr = pc1512->vram[(((pc1512->ma << 1) + 1) & 0x3fff)];
|
||||
drawcursor = ((pc1512->ma == ca) && pc1512->con && pc1512->cursoron);
|
||||
if (pc1512->cgamode & 0x20)
|
||||
{
|
||||
cols[1]=(attr&15)+16;
|
||||
cols[0]=((attr>>4)&7)+16;
|
||||
if ((cgablink&16) && (attr&0x80) && !drawcursor) cols[1]=cols[0];
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((pc1512->blink & 16) && (attr & 0x80) && !drawcursor)
|
||||
cols[1] = cols[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
cols[1]=(attr&15)+16;
|
||||
cols[0]=(attr>>4)+16;
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
}
|
||||
if (drawcursor)
|
||||
{
|
||||
for (c=0;c<8;c++)
|
||||
buffer->line[displine][(x<<3)+c+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]^15;
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer->line[pc1512->displine][(x << 3) + c + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (c=0;c<8;c++)
|
||||
buffer->line[displine][(x<<3)+c+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0];
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer->line[pc1512->displine][(x << 3) + c + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
ma++;
|
||||
pc1512->ma++;
|
||||
}
|
||||
}
|
||||
else if (!(cgamode&2))
|
||||
else if (!(pc1512->cgamode & 2))
|
||||
{
|
||||
for (x = 0; x < 40; x++)
|
||||
{
|
||||
chr=vram[((ma<<1)&0x3FFF)];
|
||||
attr=vram[(((ma<<1)+1)&0x3FFF)];
|
||||
drawcursor=((ma==ca) && con && cursoron);
|
||||
if (cgamode&0x20)
|
||||
chr = pc1512->vram[ ((pc1512->ma << 1) & 0x3fff)];
|
||||
attr = pc1512->vram[(((pc1512->ma << 1) + 1) & 0x3fff)];
|
||||
drawcursor = ((pc1512->ma == ca) && pc1512->con && pc1512->cursoron);
|
||||
if (pc1512->cgamode & 0x20)
|
||||
{
|
||||
cols[1]=(attr&15)+16;
|
||||
cols[0]=((attr>>4)&7)+16;
|
||||
if ((cgablink&16) && (attr&0x80)) cols[1]=cols[0];
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((pc1512->blink & 16) && (attr & 0x80))
|
||||
cols[1] = cols[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
cols[1]=(attr&15)+16;
|
||||
cols[0]=(attr>>4)+16;
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
}
|
||||
ma++;
|
||||
pc1512->ma++;
|
||||
if (drawcursor)
|
||||
{
|
||||
for (c=0;c<8;c++)
|
||||
buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]^15;
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer->line[pc1512->displine][(x << 4) + (c << 1) + 8] =
|
||||
buffer->line[pc1512->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (c=0;c<8;c++)
|
||||
buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0];
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer->line[pc1512->displine][(x << 4) + (c << 1) + 8] =
|
||||
buffer->line[pc1512->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!(cgamode&16))
|
||||
else if (!(pc1512->cgamode&16))
|
||||
{
|
||||
cols[0]=(cgacol&15)|16;
|
||||
col=(cgacol&16)?24:16;
|
||||
if (cgamode&4)
|
||||
cols[0] = (pc1512->cgacol & 15) | 16;
|
||||
col = (pc1512->cgacol & 16) ? 24 : 16;
|
||||
if (pc1512->cgamode & 4)
|
||||
{
|
||||
cols[1]=col|3;
|
||||
cols[2]=col|4;
|
||||
cols[3]=col|7;
|
||||
cols[1] = col | 3;
|
||||
cols[2] = col | 4;
|
||||
cols[3] = col | 7;
|
||||
}
|
||||
else if (cgacol&32)
|
||||
else if (pc1512->cgacol & 32)
|
||||
{
|
||||
cols[1]=col|3;
|
||||
cols[2]=col|5;
|
||||
cols[3]=col|7;
|
||||
cols[1] = col | 3;
|
||||
cols[2] = col | 5;
|
||||
cols[3] = col | 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
cols[1]=col|2;
|
||||
cols[2]=col|4;
|
||||
cols[3]=col|6;
|
||||
cols[1] = col | 2;
|
||||
cols[2] = col | 4;
|
||||
cols[3] = col | 6;
|
||||
}
|
||||
for (x = 0; x < 40; x++)
|
||||
{
|
||||
dat=(vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)]<<8)|vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)+1];
|
||||
ma++;
|
||||
for (c=0;c<8;c++)
|
||||
dat = (pc1512->vram[((pc1512->ma << 1) & 0x1fff) + ((pc1512->sc & 1) * 0x2000)] << 8) | pc1512->vram[((pc1512->ma << 1) & 0x1fff) + ((pc1512->sc & 1) * 0x2000) + 1];
|
||||
pc1512->ma++;
|
||||
for (c = 0; c < 8; c++)
|
||||
{
|
||||
buffer->line[displine][(x<<4)+(c<<1)+8]=
|
||||
buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[dat>>14];
|
||||
dat<<=2;
|
||||
buffer->line[pc1512->displine][(x << 4) + (c << 1) + 8] =
|
||||
buffer->line[pc1512->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14];
|
||||
dat <<= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -270,169 +296,191 @@ void pc1512_poll()
|
|||
{
|
||||
for (x = 0; x < 40; x++)
|
||||
{
|
||||
ca=((ma<<1)&0x1FFF)+((sc&1)*0x2000);
|
||||
dat=(vram[ca]<<8)|vram[ca+1];
|
||||
dat2=(vram[ca+0x10000]<<8)|vram[ca+0x10001];
|
||||
dat3=(vram[ca+0x20000]<<8)|vram[ca+0x20001];
|
||||
dat4=(vram[ca+0x30000]<<8)|vram[ca+0x30001];
|
||||
ca = ((pc1512->ma << 1) & 0x1fff) + ((pc1512->sc & 1) * 0x2000);
|
||||
dat = (pc1512->vram[ca] << 8) | pc1512->vram[ca + 1];
|
||||
dat2 = (pc1512->vram[ca + 0x4000] << 8) | pc1512->vram[ca + 0x4001];
|
||||
dat3 = (pc1512->vram[ca + 0x8000] << 8) | pc1512->vram[ca + 0x8001];
|
||||
dat4 = (pc1512->vram[ca + 0xc000] << 8) | pc1512->vram[ca + 0xc001];
|
||||
|
||||
ma++;
|
||||
for (c=0;c<16;c++)
|
||||
pc1512->ma++;
|
||||
for (c = 0; c < 16; c++)
|
||||
{
|
||||
buffer->line[displine][(x<<4)+c+8]=(((dat>>15)|((dat2>>15)<<1)|((dat3>>15)<<2)|((dat4>>15)<<3))&(cgacol&15))+16;
|
||||
dat<<=1;
|
||||
dat2<<=1;
|
||||
dat3<<=1;
|
||||
dat4<<=1;
|
||||
buffer->line[pc1512->displine][(x << 4) + c + 8] = (((dat >> 15) | ((dat2 >> 15) << 1) | ((dat3 >> 15) << 2) | ((dat4 >> 15) << 3)) & (pc1512->cgacol & 15)) + 16;
|
||||
dat <<= 1;
|
||||
dat2 <<= 1;
|
||||
dat3 <<= 1;
|
||||
dat4 <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cols[0]=((cgamode&0x12)==0x12)?0:(cgacol&15)+16;
|
||||
if (cgamode&1) hline(buffer,0,displine,(crtc[1]<<3)+16,cols[0]);
|
||||
else hline(buffer,0,displine,(crtc[1]<<4)+16,cols[0]);
|
||||
cols[0] = ((pc1512->cgamode & 0x12) == 0x12) ? 0 : (pc1512->cgacol & 15) + 16;
|
||||
if (pc1512->cgamode & 1) hline(buffer, 0, pc1512->displine, (pc1512->crtc[1] << 3) + 16, cols[0]);
|
||||
else hline(buffer, 0, pc1512->displine, (pc1512->crtc[1] << 4) + 16, cols[0]);
|
||||
}
|
||||
|
||||
sc=oldsc;
|
||||
if (vsynctime)
|
||||
cgastat|=8;
|
||||
displine++;
|
||||
if (displine>=360) displine=0;
|
||||
pc1512->sc = oldsc;
|
||||
if (pc1512->vsynctime)
|
||||
pc1512->stat |= 8;
|
||||
pc1512->displine++;
|
||||
if (pc1512->displine >= 360)
|
||||
pc1512->displine = 0;
|
||||
// pclog("Line %i %i %i %i %i %i\n",displine,cgadispon,firstline,lastline,vc,sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
vidtime+=dispontime;
|
||||
if ((lastline-firstline)==199) cgadispon=0; /*Amstrad PC1512 always displays 200 lines, regardless of CRTC settings*/
|
||||
if (cgadispon) cgastat&=~1;
|
||||
linepos=0;
|
||||
if (vsynctime)
|
||||
pc1512->vidtime += pc1512->dispontime;
|
||||
if ((pc1512->lastline - pc1512->firstline) == 199)
|
||||
pc1512->dispon = 0; /*Amstrad PC1512 always displays 200 lines, regardless of CRTC settings*/
|
||||
if (pc1512->dispon)
|
||||
pc1512->stat &= ~1;
|
||||
pc1512->linepos = 0;
|
||||
if (pc1512->vsynctime)
|
||||
{
|
||||
vsynctime--;
|
||||
if (!vsynctime)
|
||||
cgastat&=~8;
|
||||
pc1512->vsynctime--;
|
||||
if (!pc1512->vsynctime)
|
||||
pc1512->stat &= ~8;
|
||||
}
|
||||
if (sc==(crtc[11]&31)) { con=0; coff=1; }
|
||||
if (vadj)
|
||||
if (pc1512->sc == (pc1512->crtc[11] & 31))
|
||||
{
|
||||
pc1512->con = 0;
|
||||
pc1512->coff = 1;
|
||||
}
|
||||
if (pc1512->vadj)
|
||||
{
|
||||
sc++;
|
||||
sc&=31;
|
||||
ma=maback;
|
||||
vadj--;
|
||||
if (!vadj)
|
||||
pc1512->sc++;
|
||||
pc1512->sc &= 31;
|
||||
pc1512->ma = pc1512->maback;
|
||||
pc1512->vadj--;
|
||||
if (!pc1512->vadj)
|
||||
{
|
||||
cgadispon=1;
|
||||
ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
|
||||
sc=0;
|
||||
pc1512->dispon = 1;
|
||||
pc1512->ma = pc1512->maback = (pc1512->crtc[13] | (pc1512->crtc[12] << 8)) & 0x3fff;
|
||||
pc1512->sc = 0;
|
||||
}
|
||||
}
|
||||
else if (sc==crtc[9])
|
||||
else if (pc1512->sc == pc1512->crtc[9])
|
||||
{
|
||||
maback=ma;
|
||||
sc=0;
|
||||
oldvc=vc;
|
||||
vc++;
|
||||
vc&=127;
|
||||
pc1512->maback = pc1512->ma;
|
||||
pc1512->sc = 0;
|
||||
oldvc = pc1512->vc;
|
||||
pc1512->vc++;
|
||||
pc1512->vc &= 127;
|
||||
|
||||
if (displine == 32)//oldvc == (cgamode & 2) ? 127 : 31)
|
||||
if (pc1512->displine == 32)//oldvc == (cgamode & 2) ? 127 : 31)
|
||||
{
|
||||
vc=0;
|
||||
vadj=6;
|
||||
if ((crtc[10]&0x60)==0x20) cursoron=0;
|
||||
else cursoron=cgablink&16;
|
||||
pc1512->vc = 0;
|
||||
pc1512->vadj = 6;
|
||||
if ((pc1512->crtc[10] & 0x60) == 0x20) pc1512->cursoron = 0;
|
||||
else pc1512->cursoron = pc1512->blink & 16;
|
||||
}
|
||||
|
||||
if (displine >= 262)//vc == (cgamode & 2) ? 111 : 27)
|
||||
if (pc1512->displine >= 262)//vc == (cgamode & 2) ? 111 : 27)
|
||||
{
|
||||
cgadispon=0;
|
||||
displine=0;
|
||||
vsynctime=46;
|
||||
pc1512->dispon = 0;
|
||||
pc1512->displine = 0;
|
||||
pc1512->vsynctime = 46;
|
||||
|
||||
if (cgamode&1) x=(crtc[1]<<3)+16;
|
||||
else x=(crtc[1]<<4)+16;
|
||||
x = 640 + 16;
|
||||
lastline++;
|
||||
if (x!=xsize || (lastline-firstline)!=ysize)
|
||||
{
|
||||
xsize=x;
|
||||
ysize=lastline-firstline;
|
||||
if (xsize<64) xsize=656;
|
||||
if (ysize<32) ysize=200;
|
||||
updatewindowsize(xsize,(ysize<<1)+16);
|
||||
}
|
||||
if (pc1512->cgamode&1) x = (pc1512->crtc[1] << 3) + 16;
|
||||
else x = (pc1512->crtc[1] << 4) + 16;
|
||||
x = 640 + 16;
|
||||
pc1512->lastline++;
|
||||
|
||||
if (x != xsize || (pc1512->lastline - pc1512->firstline) != ysize)
|
||||
{
|
||||
xsize = x;
|
||||
ysize = pc1512->lastline - pc1512->firstline;
|
||||
if (xsize < 64) xsize = 656;
|
||||
if (ysize < 32) ysize = 200;
|
||||
updatewindowsize(xsize, (ysize << 1) + 16);
|
||||
}
|
||||
startblit();
|
||||
video_blit_memtoscreen_8(0, firstline - 4, xsize, (lastline - firstline) + 8);
|
||||
video_blit_memtoscreen_8(0, pc1512->firstline - 4, xsize, (pc1512->lastline - pc1512->firstline) + 8);
|
||||
// blit(buffer,vbuf,0,firstline-4,0,0,xsize,(lastline-firstline)+8+1);
|
||||
// if (vid_resize) stretch_blit(vbuf,screen,0,0,xsize,(lastline-firstline)+8+1,0,0,winsizex,winsizey);
|
||||
// else stretch_blit(vbuf,screen,0,0,xsize,(lastline-firstline)+8+1,0,0,xsize,((lastline-firstline)<<1)+16+2);
|
||||
// if (readflash) rectfill(screen,winsizex-40,8,winsizex-8,14,0xFFFFFFFF);
|
||||
// readflash=0;
|
||||
endblit();
|
||||
video_res_x = xsize - 16;
|
||||
video_res_y = ysize;
|
||||
if (cgamode & 1)
|
||||
{
|
||||
video_res_x /= 8;
|
||||
video_res_y /= crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
}
|
||||
else if (!(cgamode & 2))
|
||||
{
|
||||
video_res_x /= 16;
|
||||
video_res_y /= crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
}
|
||||
else if (!(cgamode&16))
|
||||
{
|
||||
video_res_x /= 2;
|
||||
video_bpp = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
video_bpp = 4;
|
||||
}
|
||||
video_res_x = xsize - 16;
|
||||
video_res_y = ysize;
|
||||
if (pc1512->cgamode & 1)
|
||||
{
|
||||
video_res_x /= 8;
|
||||
video_res_y /= pc1512->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
}
|
||||
else if (!(pc1512->cgamode & 2))
|
||||
{
|
||||
video_res_x /= 16;
|
||||
video_res_y /= pc1512->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
}
|
||||
else if (!(pc1512->cgamode & 16))
|
||||
{
|
||||
video_res_x /= 2;
|
||||
video_bpp = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
video_bpp = 4;
|
||||
}
|
||||
|
||||
firstline=1000;
|
||||
lastline=0;
|
||||
cgablink++;
|
||||
pc1512->firstline = 1000;
|
||||
pc1512->lastline = 0;
|
||||
pc1512->blink++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sc++;
|
||||
sc&=31;
|
||||
ma=maback;
|
||||
pc1512->sc++;
|
||||
pc1512->sc &= 31;
|
||||
pc1512->ma = pc1512->maback;
|
||||
}
|
||||
if (sc==(crtc[10]&31)) con=1;
|
||||
if (pc1512->sc == (pc1512->crtc[10] & 31))
|
||||
pc1512->con = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int pc1512_init()
|
||||
static void *pc1512_init()
|
||||
{
|
||||
mem_sethandler(0xb8000, 0x08000, pc1512_read, NULL, NULL, pc1512_write, NULL, NULL, NULL);
|
||||
return 0;
|
||||
int c;
|
||||
pc1512_t *pc1512 = malloc(sizeof(pc1512_t));
|
||||
memset(pc1512, 0, sizeof(pc1512_t));
|
||||
|
||||
pc1512->vram = malloc(0x10000);
|
||||
|
||||
pc1512->cgacol = 7;
|
||||
pc1512->cgamode = 0x12;
|
||||
|
||||
timer_add(pc1512_poll, &pc1512->vidtime, TIMER_ALWAYS_ENABLED, pc1512);
|
||||
mem_sethandler(0xb8000, 0x08000, pc1512_read, NULL, NULL, pc1512_write, NULL, NULL, pc1512);
|
||||
io_sethandler(0x03d0, 0x0010, pc1512_in, NULL, NULL, pc1512_out, NULL, NULL, pc1512);
|
||||
return pc1512;
|
||||
}
|
||||
|
||||
GFXCARD vid_pc1512 =
|
||||
static void pc1512_close(void *p)
|
||||
{
|
||||
pc1512_t *pc1512 = (pc1512_t *)p;
|
||||
|
||||
free(pc1512->vram);
|
||||
free(pc1512);
|
||||
}
|
||||
|
||||
static void pc1512_speed_changed(void *p)
|
||||
{
|
||||
pc1512_t *pc1512 = (pc1512_t *)p;
|
||||
|
||||
pc1512_recalctimings(pc1512);
|
||||
}
|
||||
|
||||
device_t pc1512_device =
|
||||
{
|
||||
"Amstrad PC1512 (video)",
|
||||
pc1512_init,
|
||||
/*IO at 3Cx/3Dx*/
|
||||
pc1512_out,
|
||||
pc1512_in,
|
||||
/*IO at 3Ax/3Bx*/
|
||||
video_out_null,
|
||||
video_in_null,
|
||||
|
||||
pc1512_poll,
|
||||
pc1512_recalctimings,
|
||||
|
||||
video_write_null,
|
||||
video_write_null,
|
||||
pc1512_write,
|
||||
|
||||
video_read_null,
|
||||
video_read_null,
|
||||
pc1512_read
|
||||
pc1512_close,
|
||||
pc1512_speed_changed,
|
||||
NULL
|
||||
};
|
||||
|
|
|
|||
1
src/vid_pc1512.h
Normal file
1
src/vid_pc1512.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
extern device_t pc1512_device;
|
||||
164
src/vid_pc1640.c
164
src/vid_pc1640.c
|
|
@ -1,99 +1,145 @@
|
|||
/*PC1640 video emulation.
|
||||
Mostly standard EGA, but with CGA & Hercules emulation*/
|
||||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "timer.h"
|
||||
#include "video.h"
|
||||
#include "vid_cga.h"
|
||||
#include "vid_ega.h"
|
||||
#include "vid_pc1640.h"
|
||||
|
||||
static int pc1640_cga=1;
|
||||
|
||||
void pc1640_out(uint16_t addr, uint8_t val, void *priv)
|
||||
typedef struct pc1640_t
|
||||
{
|
||||
cga_t cga;
|
||||
ega_t ega;
|
||||
|
||||
int cga_enabled;
|
||||
int dispontime, dispofftime, vidtime;
|
||||
} pc1640_t;
|
||||
|
||||
void pc1640_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
pc1640_t *pc1640 = (pc1640_t *)p;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3DB:
|
||||
pc1640_cga=val&0x40;
|
||||
mem_removehandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
|
||||
mem_removehandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL);
|
||||
if (pc1640_cga)
|
||||
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL);
|
||||
case 0x3db:
|
||||
pc1640->cga_enabled = val & 0x40;
|
||||
mem_removehandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, &pc1640->ega);
|
||||
mem_removehandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, &pc1640->cga);
|
||||
if (pc1640->cga_enabled)
|
||||
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, &pc1640->cga);
|
||||
else
|
||||
{
|
||||
switch (gdcreg[6] & 0xC)
|
||||
switch (pc1640->ega.gdcreg[6] & 0xc)
|
||||
{
|
||||
case 0x0: /*128k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
|
||||
mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, &pc1640->ega);
|
||||
break;
|
||||
case 0x4: /*64k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
|
||||
mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL, &pc1640->ega);
|
||||
break;
|
||||
case 0x8: /*32k at B0000*/
|
||||
mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
|
||||
mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, &pc1640->ega);
|
||||
break;
|
||||
case 0xC: /*32k at B8000*/
|
||||
mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL);
|
||||
mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, &pc1640->ega);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pclog("3DB write %02X\n", val);
|
||||
return;
|
||||
}
|
||||
if (pc1640_cga) cga_out(addr, val, NULL);
|
||||
else ega_out(addr, val, NULL);
|
||||
if (pc1640->cga_enabled) cga_out(addr, val, &pc1640->cga);
|
||||
else ega_out(addr, val, &pc1640->ega);
|
||||
}
|
||||
|
||||
uint8_t pc1640_in(uint16_t addr, void *priv)
|
||||
uint8_t pc1640_in(uint16_t addr, void *p)
|
||||
{
|
||||
pc1640_t *pc1640 = (pc1640_t *)p;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
}
|
||||
if (pc1640_cga) return cga_in(addr, NULL);
|
||||
else return ega_in(addr, NULL);
|
||||
}
|
||||
|
||||
void pc1640_recalctimings()
|
||||
{
|
||||
if (pc1640_cga) cga_recalctimings();
|
||||
else ega_recalctimings();
|
||||
}
|
||||
|
||||
void pc1640_poll()
|
||||
{
|
||||
if (pc1640_cga) cga_poll();
|
||||
else ega_poll();
|
||||
}
|
||||
|
||||
int pc1640_init()
|
||||
{
|
||||
int r = ega_init();
|
||||
|
||||
pc1640_cga = 1;
|
||||
|
||||
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL);
|
||||
|
||||
return r;
|
||||
if (pc1640->cga_enabled) return cga_in(addr, &pc1640->cga);
|
||||
else return ega_in(addr, &pc1640->ega);
|
||||
}
|
||||
|
||||
GFXCARD vid_pc1640 =
|
||||
void pc1640_recalctimings(pc1640_t *pc1640)
|
||||
{
|
||||
if (pc1640->cga_enabled)
|
||||
{
|
||||
cga_recalctimings(&pc1640->cga);
|
||||
pc1640->dispontime = pc1640->cga.dispontime;
|
||||
pc1640->dispofftime = pc1640->cga.dispofftime;
|
||||
}
|
||||
else
|
||||
{
|
||||
ega_recalctimings(&pc1640->ega);
|
||||
pc1640->dispontime = pc1640->ega.dispontime;
|
||||
pc1640->dispofftime = pc1640->ega.dispofftime;
|
||||
}
|
||||
}
|
||||
|
||||
void pc1640_poll(void *p)
|
||||
{
|
||||
pc1640_t *pc1640 = (pc1640_t *)p;
|
||||
if (pc1640->cga_enabled)
|
||||
{
|
||||
pc1640->cga.vidtime = pc1640->vidtime;
|
||||
cga_poll(&pc1640->cga);
|
||||
pc1640->vidtime = pc1640->cga.vidtime;
|
||||
}
|
||||
else
|
||||
{
|
||||
pc1640->ega.vidtime = pc1640->vidtime;
|
||||
ega_poll(&pc1640->ega);
|
||||
pc1640->vidtime = pc1640->ega.vidtime;
|
||||
}
|
||||
}
|
||||
|
||||
void *pc1640_init()
|
||||
{
|
||||
pc1640_t *pc1640 = malloc(sizeof(pc1640_t));
|
||||
cga_t *cga = &pc1640->cga;
|
||||
ega_t *ega = &pc1640->ega;
|
||||
memset(pc1640, 0, sizeof(pc1640_t));
|
||||
|
||||
ega_init(&pc1640->ega);
|
||||
pc1640->cga.vram = pc1640->ega.vram;
|
||||
pc1640->cga_enabled = 1;
|
||||
cga_init(&pc1640->cga);
|
||||
|
||||
timer_add(pc1640_poll, &pc1640->vidtime, TIMER_ALWAYS_ENABLED, pc1640);
|
||||
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, cga);
|
||||
io_sethandler(0x03a0, 0x0040, pc1640_in, NULL, NULL, pc1640_out, NULL, NULL, pc1640);
|
||||
return cga;
|
||||
}
|
||||
|
||||
void pc1640_close(void *p)
|
||||
{
|
||||
pc1640_t *pc1640 = (pc1640_t *)p;
|
||||
|
||||
free(pc1640->ega.vram);
|
||||
free(pc1640);
|
||||
}
|
||||
|
||||
void pc1640_speed_changed(void *p)
|
||||
{
|
||||
pc1640_t *pc1640 = (pc1640_t *)p;
|
||||
|
||||
pc1640_recalctimings(pc1640);
|
||||
}
|
||||
|
||||
device_t pc1640_device =
|
||||
{
|
||||
"Amstrad PC1640 (video)",
|
||||
pc1640_init,
|
||||
/*IO at 3Cx/3Dx*/
|
||||
pc1640_out,
|
||||
pc1640_in,
|
||||
/*IO at 3Ax/3Bx*/
|
||||
video_out_null,
|
||||
video_in_null,
|
||||
|
||||
pc1640_poll,
|
||||
pc1640_recalctimings,
|
||||
|
||||
ega_write,
|
||||
video_write_null,
|
||||
video_write_null,
|
||||
|
||||
ega_read,
|
||||
video_read_null,
|
||||
video_read_null
|
||||
pc1640_close,
|
||||
pc1640_speed_changed,
|
||||
NULL
|
||||
};
|
||||
|
|
|
|||
1
src/vid_pc1640.h
Normal file
1
src/vid_pc1640.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
extern device_t pc1640_device;
|
||||
145
src/vid_pc200.c
145
src/vid_pc200.c
|
|
@ -1,104 +1,139 @@
|
|||
/*PC200 video emulation.
|
||||
CGA with some NMI stuff. But we don't need that as it's only used for TV and
|
||||
LCD displays, and we're emulating a CRT*/
|
||||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "timer.h"
|
||||
#include "video.h"
|
||||
#include "vid_cga.h"
|
||||
#include "vid_pc200.h"
|
||||
|
||||
uint8_t pc200_3dd, pc200_3de, pc200_3df;
|
||||
|
||||
void pc200_out(uint16_t addr, uint8_t val, void *priv)
|
||||
typedef struct pc200_t
|
||||
{
|
||||
cga_t cga;
|
||||
|
||||
uint8_t reg_3dd, reg_3de, reg_3df;
|
||||
} pc200_t;
|
||||
|
||||
static uint8_t crtcmask[32] =
|
||||
{
|
||||
0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
void pc200_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
pc200_t *pc200 = (pc200_t *)p;
|
||||
cga_t *cga = &pc200->cga;
|
||||
uint8_t old;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3D5:
|
||||
if (!(pc200_3de&0x40) && crtcreg<=11)
|
||||
case 0x3d5:
|
||||
if (!(pc200->reg_3de & 0x40) && cga->crtcreg <= 11)
|
||||
{
|
||||
if (pc200_3de&0x80) nmi=1;
|
||||
pc200_3dd=0x20|(crtcreg&0x1F);
|
||||
pc200_3df=val;
|
||||
if (pc200->reg_3de & 0x80)
|
||||
nmi = 1;
|
||||
|
||||
pc200->reg_3dd = 0x20 | (cga->crtcreg & 0x1f);
|
||||
pc200->reg_3df = val;
|
||||
return;
|
||||
}
|
||||
old=crtc[crtcreg];
|
||||
crtc[crtcreg]=val&crtcmask[crtcreg];
|
||||
if (old!=val)
|
||||
old = cga->crtc[cga->crtcreg];
|
||||
cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg];
|
||||
if (old != val)
|
||||
{
|
||||
if (crtcreg<0xE || crtcreg>0x10)
|
||||
if (cga->crtcreg < 0xe || cga->crtcreg > 0x10)
|
||||
{
|
||||
fullchange=changeframecount;
|
||||
cga_recalctimings();
|
||||
fullchange = changeframecount;
|
||||
cga_recalctimings(cga);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
case 0x3D8:
|
||||
old = cgamode;
|
||||
cgamode=val;
|
||||
if ((cgamode ^ old) & 3)
|
||||
cga_recalctimings();
|
||||
pc200_3dd|=0x80;
|
||||
if (pc200_3de&0x80)
|
||||
nmi=1;
|
||||
case 0x3d8:
|
||||
old = cga->cgamode;
|
||||
cga->cgamode = val;
|
||||
if ((cga->cgamode ^ old) & 3)
|
||||
cga_recalctimings(cga);
|
||||
pc200->reg_3dd |= 0x80;
|
||||
if (pc200->reg_3de & 0x80)
|
||||
nmi = 1;
|
||||
return;
|
||||
|
||||
case 0x3DE:
|
||||
pc200_3de=val;
|
||||
pc200_3dd=0x1F;
|
||||
if (val&0x80) pc200_3dd|=0x40;
|
||||
case 0x3de:
|
||||
pc200->reg_3de = val;
|
||||
pc200->reg_3dd = 0x1f;
|
||||
if (val & 0x80)
|
||||
pc200->reg_3dd |= 0x40;
|
||||
return;
|
||||
}
|
||||
cga_out(addr, val, NULL);
|
||||
cga_out(addr, val, cga);
|
||||
}
|
||||
|
||||
uint8_t pc200_in(uint16_t addr, void *priv)
|
||||
uint8_t pc200_in(uint16_t addr, void *p)
|
||||
{
|
||||
pc200_t *pc200 = (pc200_t *)p;
|
||||
cga_t *cga = &pc200->cga;
|
||||
uint8_t temp;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3D8:
|
||||
return cgamode;
|
||||
return cga->cgamode;
|
||||
|
||||
case 0x3DD:
|
||||
temp = pc200_3dd;
|
||||
pc200_3dd &= 0x1F;
|
||||
temp = pc200->reg_3dd;
|
||||
pc200->reg_3dd &= 0x1f;
|
||||
return temp;
|
||||
|
||||
case 0x3DE:
|
||||
return (pc200_3de&0xC7)| 0x18; /*External CGA*/
|
||||
return (pc200->reg_3de & 0xc7) | 0x18; /*External CGA*/
|
||||
|
||||
case 0x3DF:
|
||||
return pc200_3df;
|
||||
return pc200->reg_3df;
|
||||
}
|
||||
return cga_in(addr, NULL);
|
||||
return cga_in(addr, cga);
|
||||
}
|
||||
|
||||
int pc200_init()
|
||||
void *pc200_init()
|
||||
{
|
||||
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL);
|
||||
return cga_init();
|
||||
pc200_t *pc200 = malloc(sizeof(pc200_t));
|
||||
cga_t *cga = &pc200->cga;
|
||||
memset(pc200, 0, sizeof(pc200_t));
|
||||
|
||||
pc200->cga.vram = malloc(0x4000);
|
||||
cga_init(&pc200->cga);
|
||||
|
||||
timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga);
|
||||
mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, cga);
|
||||
io_sethandler(0x03d0, 0x0010, pc200_in, NULL, NULL, pc200_out, NULL, NULL, pc200);
|
||||
return cga;
|
||||
}
|
||||
|
||||
GFXCARD vid_pc200 =
|
||||
void pc200_close(void *p)
|
||||
{
|
||||
pc200_t *pc200 = (pc200_t *)p;
|
||||
|
||||
free(pc200->cga.vram);
|
||||
free(pc200);
|
||||
}
|
||||
|
||||
void pc200_speed_changed(void *p)
|
||||
{
|
||||
pc200_t *pc200 = (pc200_t *)p;
|
||||
|
||||
cga_recalctimings(&pc200->cga);
|
||||
}
|
||||
|
||||
device_t pc200_device =
|
||||
{
|
||||
"Amstrad PC200 (video)",
|
||||
pc200_init,
|
||||
/*IO at 3Cx/3Dx*/
|
||||
pc200_out,
|
||||
pc200_in,
|
||||
/*IO at 3Ax/3Bx*/
|
||||
video_out_null,
|
||||
video_in_null,
|
||||
|
||||
cga_poll,
|
||||
cga_recalctimings,
|
||||
|
||||
video_write_null,
|
||||
video_write_null,
|
||||
cga_write,
|
||||
|
||||
video_read_null,
|
||||
video_read_null,
|
||||
cga_read
|
||||
pc200_close,
|
||||
pc200_speed_changed,
|
||||
NULL
|
||||
};
|
||||
|
|
|
|||
1
src/vid_pc200.h
Normal file
1
src/vid_pc200.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
extern device_t pc200_device;
|
||||
1493
src/vid_s3.c
1493
src/vid_s3.c
File diff suppressed because it is too large
Load diff
2
src/vid_s3.h
Normal file
2
src/vid_s3.h
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
device_t s3_bahamas64_device;
|
||||
device_t s3_9fx_device;
|
||||
|
|
@ -1,51 +1,66 @@
|
|||
/*S3 ViRGE emulation
|
||||
|
||||
The SVGA core is largely the same as older S3 chips, but the blitter is totally different*/
|
||||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "pci.h"
|
||||
#include "video.h"
|
||||
#include "vid_s3_virge.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_svga_render.h"
|
||||
//#include "vid_sdac_ramdac.h"
|
||||
|
||||
void s3_virge_updatemapping();
|
||||
|
||||
static uint8_t s3_bank;
|
||||
static uint8_t s3_ma_ext;
|
||||
static int s3_width = 1024;
|
||||
static int s3_bpp = 0;
|
||||
|
||||
static uint8_t s3_virge_id, s3_virge_id_high, s3_virge_id_low, s3_virge_rev;
|
||||
|
||||
uint8_t s3_virge_mmio_read(uint32_t addr, void *priv);
|
||||
uint16_t s3_virge_mmio_read_w(uint32_t addr, void *priv);
|
||||
uint32_t s3_virge_mmio_read_l(uint32_t addr, void *priv);
|
||||
void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv);
|
||||
void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv);
|
||||
void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv);
|
||||
|
||||
void s3_virge_out(uint16_t addr, uint8_t val, void *priv)
|
||||
typedef struct virge_t
|
||||
{
|
||||
svga_t svga;
|
||||
|
||||
uint8_t bank;
|
||||
uint8_t ma_ext;
|
||||
int width;
|
||||
int bpp;
|
||||
|
||||
uint8_t virge_id, virge_id_high, virge_id_low, virge_rev;
|
||||
|
||||
uint32_t linear_base, linear_size;
|
||||
|
||||
uint8_t pci_regs[256];
|
||||
} virge_t;
|
||||
|
||||
void s3_virge_updatemapping(virge_t *virge);
|
||||
|
||||
uint8_t s3_virge_mmio_read(uint32_t addr, void *p);
|
||||
uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p);
|
||||
uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p);
|
||||
void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p);
|
||||
void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p);
|
||||
void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p);
|
||||
|
||||
void s3_virge_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
virge_t *virge = (virge_t *)p;
|
||||
svga_t *svga = &virge->svga;
|
||||
uint8_t old;
|
||||
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
pclog("S3 out %04X %02X %04X:%08X %04X %04X %i\n", addr, val, CS, pc, ES, BX, ins);
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3c5:
|
||||
if (seqaddr >= 0x10)
|
||||
if (svga->seqaddr >= 0x10)
|
||||
{
|
||||
seqregs[seqaddr&0x1F]=val;
|
||||
svga->seqregs[svga->seqaddr & 0x1f]=val;
|
||||
return;
|
||||
}
|
||||
if (seqaddr == 4) /*Chain-4 - update banking*/
|
||||
if (svga->seqaddr == 4) /*Chain-4 - update banking*/
|
||||
{
|
||||
if (val & 8) svgawbank = svgarbank = s3_bank << 16;
|
||||
else svgawbank = svgarbank = s3_bank << 14;
|
||||
if (val & 8) svga->write_bank = svga->read_bank = virge->bank << 16;
|
||||
else svga->write_bank = svga->read_bank = virge->bank << 14;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -54,107 +69,113 @@ void s3_virge_out(uint16_t addr, uint8_t val, void *priv)
|
|||
//sdac_ramdac_out(addr,val);
|
||||
//return;
|
||||
|
||||
case 0x3D4:
|
||||
crtcreg=val&0x7f;
|
||||
case 0x3d4:
|
||||
svga->crtcreg = val & 0x7f;
|
||||
return;
|
||||
case 0x3D5:
|
||||
case 0x3d5:
|
||||
// if (crtcreg == 0x67) pclog("Write CRTC R%02X %02X\n", crtcreg, val);
|
||||
if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
|
||||
if (crtcreg >= 0x20 && crtcreg != 0x38 && (crtc[0x38] & 0xcc) != 0x48) return;
|
||||
old=crtc[crtcreg];
|
||||
crtc[crtcreg]=val;
|
||||
switch (crtcreg)
|
||||
if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80)
|
||||
return;
|
||||
if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48)
|
||||
return;
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
switch (svga->crtcreg)
|
||||
{
|
||||
case 0x31:
|
||||
s3_ma_ext = (s3_ma_ext & 0x1c) | ((val & 0x30) >> 4);
|
||||
vrammask = (val & 8) ? 0x3fffff : 0x3ffff;
|
||||
virge->ma_ext = (virge->ma_ext & 0x1c) | ((val & 0x30) >> 4);
|
||||
svga->vrammask = (val & 8) ? 0x3fffff : 0x3ffff;
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
switch (crtc[0x50] & 0xc1)
|
||||
switch (svga->crtc[0x50] & 0xc1)
|
||||
{
|
||||
case 0x00: s3_width = (crtc[0x31] & 2) ? 2048 : 1024; break;
|
||||
case 0x01: s3_width = 1152; break;
|
||||
case 0x40: s3_width = 640; break;
|
||||
case 0x80: s3_width = 800; break;
|
||||
case 0x81: s3_width = 1600; break;
|
||||
case 0xc0: s3_width = 1280; break;
|
||||
case 0x00: virge->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; break;
|
||||
case 0x01: virge->width = 1152; break;
|
||||
case 0x40: virge->width = 640; break;
|
||||
case 0x80: virge->width = 800; break;
|
||||
case 0x81: virge->width = 1600; break;
|
||||
case 0xc0: virge->width = 1280; break;
|
||||
}
|
||||
s3_bpp = (crtc[0x50] >> 4) & 3;
|
||||
virge->bpp = (svga->crtc[0x50] >> 4) & 3;
|
||||
break;
|
||||
case 0x69:
|
||||
s3_ma_ext = val & 0x1f;
|
||||
virge->ma_ext = val & 0x1f;
|
||||
break;
|
||||
|
||||
case 0x35:
|
||||
s3_bank = (s3_bank & 0x70) | (val & 0xf);
|
||||
virge->bank = (virge->bank & 0x70) | (val & 0xf);
|
||||
// pclog("CRTC write R35 %02X\n", val);
|
||||
if (chain4) svgawbank = svgarbank = s3_bank << 16;
|
||||
else svgawbank = svgarbank = s3_bank << 14;
|
||||
if (svga->chain4) svga->write_bank = svga->read_bank = virge->bank << 16;
|
||||
else svga->write_bank = svga->read_bank = virge->bank << 14;
|
||||
break;
|
||||
case 0x51:
|
||||
s3_bank = (s3_bank & 0x4f) | ((val & 0xc) << 2);
|
||||
if (chain4) svgawbank = svgarbank = s3_bank << 16;
|
||||
else svgawbank = svgarbank = s3_bank << 14;
|
||||
s3_ma_ext = (s3_ma_ext & ~0xc) | ((val & 3) << 2);
|
||||
virge->bank = (virge->bank & 0x4f) | ((val & 0xc) << 2);
|
||||
if (svga->chain4) svga->write_bank = svga->read_bank = virge->bank << 16;
|
||||
else svga->write_bank = svga->read_bank = virge->bank << 14;
|
||||
virge->ma_ext = (virge->ma_ext & ~0xc) | ((val & 3) << 2);
|
||||
break;
|
||||
case 0x6a:
|
||||
s3_bank = val;
|
||||
virge->bank = val;
|
||||
// pclog("CRTC write R6a %02X\n", val);
|
||||
if (chain4) svgawbank = svgarbank = s3_bank << 16;
|
||||
else svgawbank = svgarbank = s3_bank << 14;
|
||||
if (svga->chain4) svga->write_bank = svga->read_bank = virge->bank << 16;
|
||||
else svga->write_bank = svga->read_bank = virge->bank << 14;
|
||||
break;
|
||||
|
||||
case 0x3a:
|
||||
if (val & 0x10) gdcreg[5] |= 0x40; /*Horrible cheat*/
|
||||
if (val & 0x10) svga->gdcreg[5] |= 0x40; /*Horrible cheat*/
|
||||
break;
|
||||
|
||||
case 0x45:
|
||||
svga_hwcursor.ena = val & 1;
|
||||
svga->hwcursor.ena = val & 1;
|
||||
break;
|
||||
case 0x48:
|
||||
svga_hwcursor.x = ((crtc[0x46] << 8) | crtc[0x47]) & 0x7ff;
|
||||
if (bpp == 32) svga_hwcursor.x >>= 1;
|
||||
svga_hwcursor.y = ((crtc[0x48] << 8) | crtc[0x49]) & 0x7ff;
|
||||
svga_hwcursor.xoff = crtc[0x4e] & 63;
|
||||
svga_hwcursor.yoff = crtc[0x4f] & 63;
|
||||
svga_hwcursor.addr = ((((crtc[0x4c] << 8) | crtc[0x4d]) & 0xfff) * 1024) + (svga_hwcursor.yoff * 16);
|
||||
svga->hwcursor.x = ((svga->crtc[0x46] << 8) | svga->crtc[0x47]) & 0x7ff;
|
||||
if (svga->bpp == 32) svga->hwcursor.x >>= 1;
|
||||
svga->hwcursor.y = ((svga->crtc[0x48] << 8) | svga->crtc[0x49]) & 0x7ff;
|
||||
svga->hwcursor.xoff = svga->crtc[0x4e] & 63;
|
||||
svga->hwcursor.yoff = svga->crtc[0x4f] & 63;
|
||||
svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16);
|
||||
break;
|
||||
|
||||
case 0x53:
|
||||
case 0x58: case 0x59: case 0x5a:
|
||||
s3_virge_updatemapping();
|
||||
s3_virge_updatemapping(virge);
|
||||
break;
|
||||
|
||||
case 0x67:
|
||||
switch (val >> 4)
|
||||
{
|
||||
case 3: bpp = 15; break;
|
||||
case 5: bpp = 16; break;
|
||||
case 7: bpp = 24; break;
|
||||
case 13: bpp = 32; break;
|
||||
default: bpp = 8; break;
|
||||
case 3: svga->bpp = 15; break;
|
||||
case 5: svga->bpp = 16; break;
|
||||
case 7: svga->bpp = 24; break;
|
||||
case 13: svga->bpp = 32; break;
|
||||
default: svga->bpp = 8; break;
|
||||
}
|
||||
break;
|
||||
//case 0x55: case 0x43:
|
||||
// pclog("Write CRTC R%02X %02X\n", crtcreg, val);
|
||||
}
|
||||
if (old!=val)
|
||||
if (old != val)
|
||||
{
|
||||
if (crtcreg<0xE || crtcreg>0x10)
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
|
||||
{
|
||||
fullchange=changeframecount;
|
||||
svga_recalctimings();
|
||||
fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
svga_out(addr, val, NULL);
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
uint8_t s3_virge_in(uint16_t addr, void *priv)
|
||||
uint8_t s3_virge_in(uint16_t addr, void *p)
|
||||
{
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
virge_t *virge = (virge_t *)p;
|
||||
svga_t *svga = &virge->svga;
|
||||
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
if (addr != 0x3da) pclog("S3 in %04X %04X:%08X\n", addr, CS, pc);
|
||||
switch (addr)
|
||||
|
|
@ -164,221 +185,221 @@ uint8_t s3_virge_in(uint16_t addr, void *priv)
|
|||
//return sdac_ramdac_in(addr);
|
||||
|
||||
case 0x3c5:
|
||||
if (seqaddr >= 0x10)
|
||||
return seqregs[seqaddr&0x1F];
|
||||
if (svga->seqaddr >= 0x10)
|
||||
return svga->seqregs[svga->seqaddr & 0x1f];
|
||||
break;
|
||||
|
||||
case 0x3D4:
|
||||
return crtcreg;
|
||||
return svga->crtcreg;
|
||||
case 0x3D5:
|
||||
// pclog("Read CRTC R%02X %04X:%04X\n", crtcreg, CS, pc);
|
||||
switch (crtcreg)
|
||||
switch (svga->crtcreg)
|
||||
{
|
||||
case 0x2d: return s3_virge_id_high; /*Extended chip ID*/
|
||||
case 0x2e: return s3_virge_id_low; /*New chip ID*/
|
||||
case 0x2f: return s3_virge_rev;
|
||||
case 0x30: return s3_virge_id; /*Chip ID*/
|
||||
case 0x31: return (crtc[0x31] & 0xcf) | ((s3_ma_ext & 3) << 4);
|
||||
case 0x35: return (crtc[0x35] & 0xf0) | (s3_bank & 0xf);
|
||||
case 0x51: return (crtc[0x51] & 0xf0) | ((s3_bank >> 2) & 0xc) | ((s3_ma_ext >> 2) & 3);
|
||||
case 0x69: return s3_ma_ext;
|
||||
case 0x6a: return s3_bank;
|
||||
case 0x2d: return virge->virge_id_high; /*Extended chip ID*/
|
||||
case 0x2e: return virge->virge_id_low; /*New chip ID*/
|
||||
case 0x2f: return virge->virge_rev;
|
||||
case 0x30: return virge->virge_id; /*Chip ID*/
|
||||
case 0x31: return (svga->crtc[0x31] & 0xcf) | ((virge->ma_ext & 3) << 4);
|
||||
case 0x35: return (svga->crtc[0x35] & 0xf0) | (virge->bank & 0xf);
|
||||
case 0x51: return (svga->crtc[0x51] & 0xf0) | ((virge->bank >> 2) & 0xc) | ((virge->ma_ext >> 2) & 3);
|
||||
case 0x69: return virge->ma_ext;
|
||||
case 0x6a: return virge->bank;
|
||||
}
|
||||
return crtc[crtcreg];
|
||||
return svga->crtc[svga->crtcreg];
|
||||
}
|
||||
return svga_in(addr, NULL);
|
||||
return svga_in(addr, svga);
|
||||
}
|
||||
|
||||
void s3_virge_recalctimings()
|
||||
void s3_virge_recalctimings(svga_t *svga)
|
||||
{
|
||||
virge_t *virge = (virge_t *)svga->p;
|
||||
// pclog("recalctimings\n");
|
||||
svga_ma |= (s3_ma_ext << 16);
|
||||
svga->ma_latch |= (virge->ma_ext << 16);
|
||||
// pclog("SVGA_MA %08X\n", svga_ma);
|
||||
// if (gdcreg[5] & 0x40) svga_lowres = !(crtc[0x3a] & 0x10);
|
||||
if ((gdcreg[5] & 0x40) && (crtc[0x3a] & 0x10))
|
||||
if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10))
|
||||
{
|
||||
switch (bpp)
|
||||
switch (svga->bpp)
|
||||
{
|
||||
case 8:
|
||||
svga_render = svga_render_8bpp_highres;
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
break;
|
||||
case 15:
|
||||
svga_render = svga_render_15bpp_highres;
|
||||
svga->render = svga_render_15bpp_highres;
|
||||
break;
|
||||
case 16:
|
||||
svga_render = svga_render_16bpp_highres;
|
||||
svga->render = svga_render_16bpp_highres;
|
||||
break;
|
||||
case 24:
|
||||
svga_render = svga_render_24bpp_highres;
|
||||
svga->render = svga_render_24bpp_highres;
|
||||
break;
|
||||
case 32:
|
||||
svga_render = svga_render_32bpp_highres;
|
||||
svga->render = svga_render_32bpp_highres;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (crtc[0x5d] & 0x01) svga_htotal += 0x100;
|
||||
if (crtc[0x5d] & 0x02) svga_hdisp += 0x100;
|
||||
if (crtc[0x5e] & 0x01) svga_vtotal += 0x400;
|
||||
if (crtc[0x5e] & 0x02) svga_dispend += 0x400;
|
||||
if (crtc[0x5e] & 0x10) svga_vsyncstart += 0x400;
|
||||
if (crtc[0x5e] & 0x40) svga_split += 0x400;
|
||||
if (crtc[0x51] & 0x30) svga_rowoffset += (crtc[0x51] & 0x30) << 4;
|
||||
else if (crtc[0x43] & 0x04) svga_rowoffset += 0x100;
|
||||
if (!svga_rowoffset) svga_rowoffset = 256;
|
||||
svga_interlace = crtc[0x42] & 0x20;
|
||||
if (bpp == 32)
|
||||
if (svga->crtc[0x5d] & 0x01) svga->htotal += 0x100;
|
||||
if (svga->crtc[0x5d] & 0x02) svga->hdisp += 0x100;
|
||||
if (svga->crtc[0x5e] & 0x01) svga->vtotal += 0x400;
|
||||
if (svga->crtc[0x5e] & 0x02) svga->dispend += 0x400;
|
||||
if (svga->crtc[0x5e] & 0x10) svga->vsyncstart += 0x400;
|
||||
if (svga->crtc[0x5e] & 0x40) svga->split += 0x400;
|
||||
if (svga->crtc[0x51] & 0x30) svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4;
|
||||
else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100;
|
||||
if (!svga->rowoffset) svga->rowoffset = 256;
|
||||
svga->interlace = svga->crtc[0x42] & 0x20;
|
||||
if (svga->bpp == 32)
|
||||
{
|
||||
svga_htotal <<= 2;
|
||||
svga_hdisp <<= 2;
|
||||
svga->htotal <<= 2;
|
||||
svga->hdisp <<= 2;
|
||||
}
|
||||
//svga_clock = cpuclock / sdac_getclock((svga_miscout >> 2) & 3);
|
||||
// pclog("SVGA_CLOCK = %f %02X %f\n", svga_clock, svga_miscout, cpuclock);
|
||||
//if (bpp > 8) svga_clock /= 2;
|
||||
}
|
||||
|
||||
static uint32_t s3_linear_base = 0, s3_linear_size = 0;
|
||||
void s3_virge_updatemapping()
|
||||
void s3_virge_updatemapping(virge_t *virge)
|
||||
{
|
||||
mem_removehandler(s3_linear_base, s3_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL);
|
||||
svga_t *svga = &virge->svga;
|
||||
|
||||
mem_removehandler(virge->linear_base, virge->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, svga);
|
||||
|
||||
// video_write_a000_w = video_write_a000_l = NULL;
|
||||
|
||||
mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
mem_removehandler(0xa0000, 0x20000, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, NULL);
|
||||
pclog("Update mapping - bank %02X ", gdcreg[6] & 0xc);
|
||||
switch (gdcreg[6] & 0xc) /*Banked framebuffer*/
|
||||
mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
|
||||
mem_removehandler(0xa0000, 0x20000, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, virge);
|
||||
pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc);
|
||||
switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/
|
||||
{
|
||||
case 0x0: /*128k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
|
||||
break;
|
||||
case 0x4: /*64k at A0000*/
|
||||
mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
|
||||
break;
|
||||
case 0x8: /*32k at B0000*/
|
||||
mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
|
||||
break;
|
||||
case 0xC: /*32k at B8000*/
|
||||
mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
|
||||
break;
|
||||
}
|
||||
|
||||
pclog("Linear framebuffer %02X ", crtc[0x58] & 0x10);
|
||||
if (crtc[0x58] & 0x10) /*Linear framebuffer*/
|
||||
pclog("Linear framebuffer %02X ", svga->crtc[0x58] & 0x10);
|
||||
if (svga->crtc[0x58] & 0x10) /*Linear framebuffer*/
|
||||
{
|
||||
s3_linear_base = (crtc[0x5a] << 16) | (crtc[0x59] << 24);
|
||||
switch (crtc[0x58] & 3)
|
||||
virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24);
|
||||
switch (svga->crtc[0x58] & 3)
|
||||
{
|
||||
case 0: /*64k*/
|
||||
s3_linear_size = 0x10000;
|
||||
virge->linear_size = 0x10000;
|
||||
break;
|
||||
case 1: /*1mb*/
|
||||
s3_linear_size = 0x100000;
|
||||
virge->linear_size = 0x100000;
|
||||
break;
|
||||
case 2: /*2mb*/
|
||||
s3_linear_size = 0x200000;
|
||||
virge->linear_size = 0x200000;
|
||||
break;
|
||||
case 3: /*8mb*/
|
||||
s3_linear_size = 0x400000;
|
||||
virge->linear_size = 0x400000;
|
||||
break;
|
||||
}
|
||||
s3_linear_base &= ~(s3_linear_size - 1);
|
||||
virge->linear_base &= ~(virge->linear_size - 1);
|
||||
// pclog("%08X %08X %02X %02X %02X\n", linear_base, linear_size, crtc[0x58], crtc[0x59], crtc[0x5a]);
|
||||
pclog("Linear framebuffer at %08X size %08X\n", s3_linear_base, s3_linear_size);
|
||||
if (s3_linear_base == 0xa0000)
|
||||
mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
|
||||
pclog("Linear framebuffer at %08X size %08X\n", virge->linear_base, virge->linear_size);
|
||||
if (virge->linear_base == 0xa0000)
|
||||
mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
|
||||
else
|
||||
mem_sethandler(s3_linear_base, s3_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL);
|
||||
mem_sethandler(virge->linear_base, virge->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, svga);
|
||||
}
|
||||
|
||||
pclog("Memory mapped IO %02X\n", crtc[0x53] & 0x18);
|
||||
output = 0;
|
||||
if ((crtc[0x53] & 0x18) == 0x10) /*Memory mapped IO*/
|
||||
pclog("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x18);
|
||||
if ((svga->crtc[0x53] & 0x18) == 0x10) /*Memory mapped IO*/
|
||||
{
|
||||
output = 3;
|
||||
if (crtc[0x53] & 0x20)
|
||||
mem_sethandler(0xb8000, 0x8000, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, NULL);
|
||||
if (svga->crtc[0x53] & 0x20)
|
||||
mem_sethandler(0xb8000, 0x8000, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, virge);
|
||||
else
|
||||
mem_sethandler(0xa8000, 0x8000, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, NULL);
|
||||
mem_sethandler(0xa8000, 0x8000, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, virge);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
uint8_t s3_virge_mmio_read(uint32_t addr, void *priv)
|
||||
uint8_t s3_virge_mmio_read(uint32_t addr, void *p)
|
||||
{
|
||||
pclog("MMIO readb %08X\n", addr);
|
||||
return 0xff;
|
||||
}
|
||||
uint16_t s3_virge_mmio_read_w(uint32_t addr, void *priv)
|
||||
uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p)
|
||||
{
|
||||
pclog("MMIO readw %08X\n", addr);
|
||||
return 0xffff;
|
||||
}
|
||||
uint32_t s3_virge_mmio_read_l(uint32_t addr, void *priv)
|
||||
uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p)
|
||||
{
|
||||
pclog("MMIO readl %08X\n", addr);
|
||||
return 0xffffffff;
|
||||
}
|
||||
void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv)
|
||||
void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
pclog("MMIO writeb %08X %02X\n", addr, val);
|
||||
}
|
||||
void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv)
|
||||
void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p)
|
||||
{
|
||||
pclog("MMIO writew %08X %04X\n", addr, val);
|
||||
}
|
||||
void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv)
|
||||
void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
|
||||
{
|
||||
pclog("MMIO writel %08X %08X\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void s3_virge_hwcursor_draw(int displine)
|
||||
void s3_virge_hwcursor_draw(svga_t *svga, int displine)
|
||||
{
|
||||
int x;
|
||||
uint16_t dat[2];
|
||||
int xx;
|
||||
int offset = svga_hwcursor_latch.x - svga_hwcursor_latch.xoff;
|
||||
int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
|
||||
|
||||
pclog("HWcursor %i %i\n", svga_hwcursor_latch.x, svga_hwcursor_latch.y);
|
||||
pclog("HWcursor %i %i\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y);
|
||||
for (x = 0; x < 64; x += 16)
|
||||
{
|
||||
dat[0] = (vram[svga_hwcursor_latch.addr] << 8) | vram[svga_hwcursor_latch.addr + 1];
|
||||
dat[1] = (vram[svga_hwcursor_latch.addr + 2] << 8) | vram[svga_hwcursor_latch.addr + 3];
|
||||
dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 8) | svga->vram[svga->hwcursor_latch.addr + 1];
|
||||
dat[1] = (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3];
|
||||
for (xx = 0; xx < 16; xx++)
|
||||
{
|
||||
if (offset >= svga_hwcursor_latch.x)
|
||||
if (offset >= svga->hwcursor_latch.x)
|
||||
{
|
||||
if (!(dat[0] & 0x8000))
|
||||
((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x8000) ? 0xffffff : 0;
|
||||
else if (dat[1] & 0x8000)
|
||||
((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff;
|
||||
// pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga_hwcursor_on, dat[0], dat[1]);
|
||||
// pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga->hwcursor_on, dat[0], dat[1]);
|
||||
}
|
||||
|
||||
offset++;
|
||||
dat[0] <<= 1;
|
||||
dat[1] <<= 1;
|
||||
}
|
||||
svga_hwcursor_latch.addr += 4;
|
||||
svga->hwcursor_latch.addr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t s3_virge_pci_regs[256];
|
||||
|
||||
uint8_t s3_virge_pci_read(int func, int addr, void *priv)
|
||||
uint8_t s3_virge_pci_read(int func, int addr, void *p)
|
||||
{
|
||||
virge_t *virge = (virge_t *)p;
|
||||
svga_t *svga = &virge->svga;
|
||||
// pclog("S3 PCI read %08X\n", addr);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x00: return 0x33; /*'S3'*/
|
||||
case 0x01: return 0x53;
|
||||
|
||||
case 0x02: return s3_virge_id_low;
|
||||
case 0x03: return s3_virge_id_high;
|
||||
case 0x02: return virge->virge_id_low;
|
||||
case 0x03: return virge->virge_id_high;
|
||||
|
||||
case 0x08: return 0; /*Revision ID*/
|
||||
case 0x09: return 0; /*Programming interface*/
|
||||
|
|
@ -389,7 +410,7 @@ uint8_t s3_virge_pci_read(int func, int addr, void *priv)
|
|||
case 0x10: return 0x00; /*Linear frame buffer address*/
|
||||
case 0x11: return 0x00;
|
||||
case 0x12: return 0x00;
|
||||
case 0x13: return crtc[0x59] & 0xfc;
|
||||
case 0x13: return svga->crtc[0x59] & 0xfc;
|
||||
|
||||
case 0x30: return 0x01; /*BIOS ROM address*/
|
||||
case 0x31: return 0x00;
|
||||
|
|
@ -397,11 +418,14 @@ uint8_t s3_virge_pci_read(int func, int addr, void *priv)
|
|||
case 0x33: return 0x00;
|
||||
|
||||
}
|
||||
return s3_virge_pci_regs[addr];
|
||||
return virge->pci_regs[addr];
|
||||
}
|
||||
|
||||
void s3_virge_pci_write(int func, int addr, uint8_t val, void *priv)
|
||||
void s3_virge_pci_write(int func, int addr, uint8_t val, void *p)
|
||||
{
|
||||
virge_t *virge = (virge_t *)p;
|
||||
svga_t *svga = &virge->svga;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x00: case 0x01: case 0x02: case 0x03:
|
||||
|
|
@ -409,59 +433,68 @@ void s3_virge_pci_write(int func, int addr, uint8_t val, void *priv)
|
|||
case 0x3d: case 0x3e: case 0x3f:
|
||||
break;
|
||||
|
||||
case 0x13: crtc[0x59] = val & 0xfc; s3_virge_updatemapping(); break;
|
||||
case 0x13:
|
||||
svga->crtc[0x59] = val & 0xfc;
|
||||
s3_virge_updatemapping(virge);
|
||||
break;
|
||||
}
|
||||
s3_virge_pci_regs[addr] = val;
|
||||
virge->pci_regs[addr] = val;
|
||||
}
|
||||
|
||||
int s3_virge_init()
|
||||
void *s3_virge_init()
|
||||
{
|
||||
s3_virge_pci_regs[4] = 3;
|
||||
s3_virge_pci_regs[5] = 0;
|
||||
s3_virge_pci_regs[6] = 0;
|
||||
s3_virge_pci_regs[7] = 2;
|
||||
s3_virge_pci_regs[0x3d] = 1;
|
||||
s3_virge_pci_regs[0x3e] = 4;
|
||||
s3_virge_pci_regs[0x3f] = 0xff;
|
||||
virge_t *virge = malloc(sizeof(virge_t));
|
||||
memset(virge, 0, sizeof(virge_t));
|
||||
|
||||
svga_init(&virge->svga, virge, 1 << 22, /*4mb*/
|
||||
s3_virge_recalctimings,
|
||||
s3_virge_in, s3_virge_out,
|
||||
s3_virge_hwcursor_draw);
|
||||
|
||||
io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge);
|
||||
|
||||
virge->pci_regs[4] = 3;
|
||||
virge->pci_regs[5] = 0;
|
||||
virge->pci_regs[6] = 0;
|
||||
virge->pci_regs[7] = 2;
|
||||
virge->pci_regs[0x3d] = 1;
|
||||
virge->pci_regs[0x3e] = 4;
|
||||
virge->pci_regs[0x3f] = 0xff;
|
||||
|
||||
s3_virge_id_high = 0x56;
|
||||
s3_virge_id_low = 0x31;
|
||||
s3_virge_rev = 0;
|
||||
s3_virge_id = 0xe1;
|
||||
virge->virge_id_high = 0x56;
|
||||
virge->virge_id_low = 0x31;
|
||||
virge->virge_rev = 0;
|
||||
virge->virge_id = 0xe1;
|
||||
|
||||
svga_recalctimings_ex = s3_virge_recalctimings;
|
||||
svga_hwcursor_draw = s3_virge_hwcursor_draw;
|
||||
|
||||
crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5);
|
||||
crtc[0x37] = 1 | (7 << 5);
|
||||
virge->svga.crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5);
|
||||
virge->svga.crtc[0x37] = 1 | (7 << 5);
|
||||
|
||||
vrammask = 0x3fffff;
|
||||
|
||||
pci_add(s3_virge_pci_read, s3_virge_pci_write, NULL);
|
||||
pci_add(s3_virge_pci_read, s3_virge_pci_write, virge);
|
||||
|
||||
svga_vram_limit = 4 << 20; /*4mb*/
|
||||
return svga_init();
|
||||
return virge;
|
||||
}
|
||||
|
||||
GFXCARD vid_s3_virge =
|
||||
void s3_virge_close(void *p)
|
||||
{
|
||||
virge_t *virge = (virge_t *)p;
|
||||
|
||||
svga_close(&virge->svga);
|
||||
|
||||
free(virge);
|
||||
}
|
||||
|
||||
void s3_virge_speed_changed(void *p)
|
||||
{
|
||||
virge_t *virge = (virge_t *)p;
|
||||
|
||||
svga_recalctimings(&virge->svga);
|
||||
}
|
||||
|
||||
device_t s3_virge_device =
|
||||
{
|
||||
"Diamond Stealth 3D 2000 (S3 VIRGE)",
|
||||
s3_virge_init,
|
||||
/*IO at 3Cx/3Dx*/
|
||||
s3_virge_out,
|
||||
s3_virge_in,
|
||||
/*IO at 3Ax/3Bx*/
|
||||
video_out_null,
|
||||
video_in_null,
|
||||
|
||||
svga_poll,
|
||||
svga_recalctimings,
|
||||
|
||||
svga_write,
|
||||
video_write_null,
|
||||
video_write_null,
|
||||
|
||||
svga_read,
|
||||
video_read_null,
|
||||
video_read_null
|
||||
s3_virge_close,
|
||||
s3_virge_speed_changed,
|
||||
svga_add_status_info
|
||||
};
|
||||
|
||||
|
|
|
|||
1
src/vid_s3_virge.h
Normal file
1
src/vid_s3_virge.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
extern device_t s3_virge_device;
|
||||
|
|
@ -5,17 +5,7 @@
|
|||
#include "vid_svga.h"
|
||||
#include "vid_sdac_ramdac.h"
|
||||
|
||||
struct
|
||||
{
|
||||
int magic_count;
|
||||
uint8_t command;
|
||||
int windex, rindex;
|
||||
uint16_t regs[256];
|
||||
int reg_ff;
|
||||
int rs2;
|
||||
} sdac_ramdac;
|
||||
|
||||
void sdac_ramdac_out(uint16_t addr, uint8_t val, void *priv)
|
||||
void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
// /*if (CS!=0xC000) */pclog("OUT RAMDAC %04X %02X %i %04X:%04X %i\n",addr,val,sdac_ramdac.magic_count,CS,pc, sdac_ramdac.rs2);
|
||||
switch (addr)
|
||||
|
|
@ -23,125 +13,125 @@ void sdac_ramdac_out(uint16_t addr, uint8_t val, void *priv)
|
|||
case 0x3C6:
|
||||
if (val == 0xff)
|
||||
{
|
||||
sdac_ramdac.rs2 = 0;
|
||||
sdac_ramdac.magic_count = 0;
|
||||
ramdac->rs2 = 0;
|
||||
ramdac->magic_count = 0;
|
||||
break;
|
||||
}
|
||||
if (sdac_ramdac.magic_count < 4) break;
|
||||
if (sdac_ramdac.magic_count == 4)
|
||||
if (ramdac->magic_count < 4) break;
|
||||
if (ramdac->magic_count == 4)
|
||||
{
|
||||
sdac_ramdac.command = val;
|
||||
ramdac->command = val;
|
||||
// pclog("RAMDAC command reg now %02X\n", val);
|
||||
switch (val >> 4)
|
||||
{
|
||||
case 2: case 3: case 0xa: bpp = 15; break;
|
||||
case 4: case 0xe: bpp = 24; break;
|
||||
case 5: case 6: case 0xc: bpp = 16; break;
|
||||
case 7: bpp = 32; break;
|
||||
case 0x2: case 0x3: case 0xa: svga->bpp = 15; break;
|
||||
case 0x4: case 0xe: svga->bpp = 24; break;
|
||||
case 0x5: case 0x6: case 0xc: svga->bpp = 16; break;
|
||||
case 0x7: svga->bpp = 32; break;
|
||||
|
||||
case 0: case 1: default: bpp = 8; break;
|
||||
case 0: case 1: default: svga->bpp = 8; break;
|
||||
}
|
||||
}
|
||||
//sdac_ramdac.magic_count = 0;
|
||||
//ramdac->magic_count = 0;
|
||||
break;
|
||||
|
||||
case 0x3C7:
|
||||
sdac_ramdac.magic_count = 0;
|
||||
if (sdac_ramdac.rs2)
|
||||
sdac_ramdac.rindex = val;
|
||||
ramdac->magic_count = 0;
|
||||
if (ramdac->rs2)
|
||||
ramdac->rindex = val;
|
||||
break;
|
||||
case 0x3C8:
|
||||
sdac_ramdac.magic_count = 0;
|
||||
if (sdac_ramdac.rs2)
|
||||
sdac_ramdac.windex = val;
|
||||
ramdac->magic_count = 0;
|
||||
if (ramdac->rs2)
|
||||
ramdac->windex = val;
|
||||
break;
|
||||
case 0x3C9:
|
||||
sdac_ramdac.magic_count = 0;
|
||||
if (sdac_ramdac.rs2)
|
||||
ramdac->magic_count = 0;
|
||||
if (ramdac->rs2)
|
||||
{
|
||||
if (!sdac_ramdac.reg_ff) sdac_ramdac.regs[sdac_ramdac.windex] = (sdac_ramdac.regs[sdac_ramdac.windex] & 0xff00) | val;
|
||||
else sdac_ramdac.regs[sdac_ramdac.windex] = (sdac_ramdac.regs[sdac_ramdac.windex] & 0x00ff) | (val << 8);
|
||||
sdac_ramdac.reg_ff = !sdac_ramdac.reg_ff;
|
||||
// pclog("RAMDAC reg %02X now %04X\n", sdac_ramdac.windex, sdac_ramdac.regs[sdac_ramdac.windex]);
|
||||
if (!sdac_ramdac.reg_ff) sdac_ramdac.windex++;
|
||||
if (!ramdac->reg_ff) ramdac->regs[ramdac->windex] = (ramdac->regs[ramdac->windex] & 0xff00) | val;
|
||||
else ramdac->regs[ramdac->windex] = (ramdac->regs[ramdac->windex] & 0x00ff) | (val << 8);
|
||||
ramdac->reg_ff = !ramdac->reg_ff;
|
||||
// pclog("RAMDAC reg %02X now %04X\n", ramdac->windex, ramdac->regs[ramdac->windex]);
|
||||
if (!ramdac->reg_ff) ramdac->windex++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
svga_out(addr, val, NULL);
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
uint8_t sdac_ramdac_in(uint16_t addr, void *priv)
|
||||
uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
uint8_t temp;
|
||||
// /*if (CS!=0xC000) */pclog("IN RAMDAC %04X %04X:%04X %i\n",addr,CS,pc, sdac_ramdac.rs2);
|
||||
// /*if (CS!=0xC000) */pclog("IN RAMDAC %04X %04X:%04X %i\n",addr,CS,pc, ramdac->rs2);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3C6:
|
||||
sdac_ramdac.reg_ff = 0;
|
||||
if (sdac_ramdac.magic_count < 5)
|
||||
sdac_ramdac.magic_count++;
|
||||
if (sdac_ramdac.magic_count == 4)
|
||||
ramdac->reg_ff = 0;
|
||||
if (ramdac->magic_count < 5)
|
||||
ramdac->magic_count++;
|
||||
if (ramdac->magic_count == 4)
|
||||
{
|
||||
temp = 0x70; /*SDAC ID*/
|
||||
sdac_ramdac.rs2 = 1;
|
||||
ramdac->rs2 = 1;
|
||||
}
|
||||
if (sdac_ramdac.magic_count == 5)
|
||||
if (ramdac->magic_count == 5)
|
||||
{
|
||||
temp = sdac_ramdac.command;
|
||||
sdac_ramdac.magic_count = 0;
|
||||
temp = ramdac->command;
|
||||
ramdac->magic_count = 0;
|
||||
}
|
||||
return temp;
|
||||
case 0x3C7:
|
||||
// if (sdac_ramdac.magic_count < 4)
|
||||
// if (ramdac->magic_count < 4)
|
||||
// {
|
||||
sdac_ramdac.magic_count=0;
|
||||
ramdac->magic_count=0;
|
||||
// break;
|
||||
// }
|
||||
if (sdac_ramdac.rs2) return sdac_ramdac.rindex;
|
||||
if (ramdac->rs2) return ramdac->rindex;
|
||||
break;
|
||||
case 0x3C8:
|
||||
// if (sdac_ramdac.magic_count < 4)
|
||||
// if (ramdac->magic_count < 4)
|
||||
// {
|
||||
sdac_ramdac.magic_count=0;
|
||||
ramdac->magic_count=0;
|
||||
// break;
|
||||
// }
|
||||
if (sdac_ramdac.rs2) return sdac_ramdac.windex;
|
||||
if (ramdac->rs2) return ramdac->windex;
|
||||
break;
|
||||
case 0x3C9:
|
||||
// if (sdac_ramdac.magic_count < 4)
|
||||
// if (ramdac->magic_count < 4)
|
||||
// {
|
||||
sdac_ramdac.magic_count=0;
|
||||
ramdac->magic_count=0;
|
||||
// break;
|
||||
// }
|
||||
if (sdac_ramdac.rs2)
|
||||
if (ramdac->rs2)
|
||||
{
|
||||
if (!sdac_ramdac.reg_ff) temp = sdac_ramdac.regs[sdac_ramdac.rindex] & 0xff;
|
||||
else temp = sdac_ramdac.regs[sdac_ramdac.rindex] >> 8;
|
||||
sdac_ramdac.reg_ff = !sdac_ramdac.reg_ff;
|
||||
if (!sdac_ramdac.reg_ff)
|
||||
if (!ramdac->reg_ff) temp = ramdac->regs[ramdac->rindex] & 0xff;
|
||||
else temp = ramdac->regs[ramdac->rindex] >> 8;
|
||||
ramdac->reg_ff = !ramdac->reg_ff;
|
||||
if (!ramdac->reg_ff)
|
||||
{
|
||||
sdac_ramdac.rindex++;
|
||||
sdac_ramdac.magic_count = 0;
|
||||
ramdac->rindex++;
|
||||
ramdac->magic_count = 0;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return svga_in(addr, NULL);
|
||||
return svga_in(addr, svga);
|
||||
}
|
||||
|
||||
float sdac_getclock(int clock)
|
||||
float sdac_getclock(int clock, sdac_ramdac_t *ramdac)
|
||||
{
|
||||
float t;
|
||||
int m, n1, n2;
|
||||
// pclog("SDAC_Getclock %i %04X\n", clock, sdac_ramdac.regs[clock]);
|
||||
// pclog("SDAC_Getclock %i %04X\n", clock, ramdac->regs[clock]);
|
||||
if (clock == 0) return 25175000.0;
|
||||
if (clock == 1) return 28322000.0;
|
||||
clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/
|
||||
m = (sdac_ramdac.regs[clock] & 0x7f) + 2;
|
||||
n1 = ((sdac_ramdac.regs[clock] >> 8) & 0x1f) + 2;
|
||||
n2 = ((sdac_ramdac.regs[clock] >> 13) & 0x07);
|
||||
m = (ramdac->regs[clock] & 0x7f) + 2;
|
||||
n1 = ((ramdac->regs[clock] >> 8) & 0x1f) + 2;
|
||||
n2 = ((ramdac->regs[clock] >> 13) & 0x07);
|
||||
t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2);
|
||||
// pclog("SDAC clock %i %i %i %f %04X %f %i\n", m, n1, n2, t, sdac_ramdac.regs[2], 14318184.0 * ((float)m / (float)n1), 1 << n2);
|
||||
// pclog("SDAC clock %i %i %i %f %04X %f %i\n", m, n1, n2, t, ramdac->regs[2], 14318184.0 * ((float)m / (float)n1), 1 << n2);
|
||||
return t;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,14 @@
|
|||
void sdac_ramdac_out(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t sdac_ramdac_in(uint16_t addr, void *priv);
|
||||
typedef struct sdac_ramdac_t
|
||||
{
|
||||
int magic_count;
|
||||
uint8_t command;
|
||||
int windex, rindex;
|
||||
uint16_t regs[256];
|
||||
int reg_ff;
|
||||
int rs2;
|
||||
} sdac_ramdac_t;
|
||||
|
||||
float sdac_getclock(int clock);
|
||||
void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga);
|
||||
uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga);
|
||||
|
||||
float sdac_getclock(int clock, sdac_ramdac_t *ramdac);
|
||||
|
|
|
|||
|
|
@ -4,101 +4,114 @@
|
|||
#include "vid_svga.h"
|
||||
#include "vid_stg_ramdac.h"
|
||||
|
||||
struct
|
||||
{
|
||||
int magic_count;
|
||||
uint8_t command;
|
||||
int index;
|
||||
uint8_t regs[256];
|
||||
} stg_ramdac;
|
||||
static int stg_state_read[2][8] = {{1,2,3,4,0,0,0,0}, {1,2,3,4,5,6,7,7}};
|
||||
static int stg_state_write[8] = {0,0,0,0,0,6,7,7};
|
||||
|
||||
int stg_state_read[2][8]={{1,2,3,4,0,0,0,0}, {1,2,3,4,5,6,7,7}};
|
||||
int stg_state_write[8]={0,0,0,0,0,6,7,7};
|
||||
|
||||
void stg_ramdac_out(uint16_t addr, uint8_t val, void *priv)
|
||||
void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
int didwrite;
|
||||
//if (CS!=0xC000) pclog("OUT RAMDAC %04X %02X %i %04X:%04X\n",addr,val,stg_ramdac.magic_count,CS,pc);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3C6:
|
||||
switch (stg_ramdac.magic_count)
|
||||
case 0x3c6:
|
||||
switch (ramdac->magic_count)
|
||||
{
|
||||
case 0: case 1: case 2: case 3: break;
|
||||
case 4: stg_ramdac.command=val; /*pclog("Write RAMDAC command %02X\n",val);*/ break;
|
||||
case 5: stg_ramdac.index=(stg_ramdac.index&0xFF00)|val; break;
|
||||
case 6: stg_ramdac.index=(stg_ramdac.index&0xFF)|(val<<8); break;
|
||||
case 0: case 1: case 2: case 3:
|
||||
break;
|
||||
case 4:
|
||||
ramdac->command = val;
|
||||
/*pclog("Write RAMDAC command %02X\n",val);*/
|
||||
break;
|
||||
case 5:
|
||||
ramdac->index = (ramdac->index & 0xff00) | val;
|
||||
break;
|
||||
case 6:
|
||||
ramdac->index = (ramdac->index & 0xff) | (val << 8);
|
||||
break;
|
||||
case 7:
|
||||
pclog("Write RAMDAC reg %02X %02X\n", stg_ramdac.index, val);
|
||||
if (stg_ramdac.index<0x100) stg_ramdac.regs[stg_ramdac.index]=val;
|
||||
stg_ramdac.index++;
|
||||
pclog("Write RAMDAC reg %02X %02X\n", ramdac->index, val);
|
||||
if (ramdac->index < 0x100)
|
||||
ramdac->regs[ramdac->index] = val;
|
||||
ramdac->index++;
|
||||
break;
|
||||
}
|
||||
didwrite = (stg_ramdac.magic_count>=4);
|
||||
stg_ramdac.magic_count=stg_state_write[stg_ramdac.magic_count&7];
|
||||
if (stg_ramdac.command&8)
|
||||
didwrite = (ramdac->magic_count >= 4);
|
||||
ramdac->magic_count = stg_state_write[ramdac->magic_count & 7];
|
||||
if (ramdac->command & 8)
|
||||
{
|
||||
switch (stg_ramdac.regs[3])
|
||||
switch (ramdac->regs[3])
|
||||
{
|
||||
case 0: case 5: case 7: bpp=8; break;
|
||||
case 1: case 2: case 8: bpp=15; break;
|
||||
case 3: case 6: bpp=16; break;
|
||||
case 4: case 9: bpp=24; break;
|
||||
default: bpp=8; break;
|
||||
case 0: case 5: case 7: svga->bpp = 8; break;
|
||||
case 1: case 2: case 8: svga->bpp = 15; break;
|
||||
case 3: case 6: svga->bpp = 16; break;
|
||||
case 4: case 9: svga->bpp = 24; break;
|
||||
default: svga->bpp = 8; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (stg_ramdac.command>>5)
|
||||
switch (ramdac->command >> 5)
|
||||
{
|
||||
case 0: bpp=8; break;
|
||||
case 5: bpp=15; break;
|
||||
case 6: bpp=16; break;
|
||||
case 7: bpp=24; break;
|
||||
default: bpp=8; break;
|
||||
case 0: svga->bpp = 8; break;
|
||||
case 5: svga->bpp = 15; break;
|
||||
case 6: svga->bpp = 16; break;
|
||||
case 7: svga->bpp = 24; break;
|
||||
default: svga->bpp = 8; break;
|
||||
}
|
||||
}
|
||||
if (didwrite) return;
|
||||
break;
|
||||
case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
stg_ramdac.magic_count=0;
|
||||
case 0x3c7: case 0x3c8: case 0x3c9:
|
||||
ramdac->magic_count=0;
|
||||
break;
|
||||
}
|
||||
svga_out(addr, val, NULL);
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
uint8_t stg_ramdac_in(uint16_t addr, void *priv)
|
||||
uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
uint8_t temp;
|
||||
//if (CS!=0xC000) pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3C6:
|
||||
switch (stg_ramdac.magic_count)
|
||||
case 0x3c6:
|
||||
switch (ramdac->magic_count)
|
||||
{
|
||||
case 0: case 1: case 2: case 3: temp=0xFF; break;
|
||||
case 4: temp=stg_ramdac.command; break;
|
||||
case 5: temp=stg_ramdac.index&0xFF; break;
|
||||
case 6: temp=stg_ramdac.index>>8; break;
|
||||
case 0: case 1: case 2: case 3:
|
||||
temp = 0xff;
|
||||
break;
|
||||
case 4:
|
||||
temp = ramdac->command;
|
||||
break;
|
||||
case 5:
|
||||
temp = ramdac->index & 0xff;
|
||||
break;
|
||||
case 6:
|
||||
temp = ramdac->index >> 8;
|
||||
break;
|
||||
case 7:
|
||||
// pclog("Read RAMDAC index %04X\n",stg_ramdac.index);
|
||||
switch (stg_ramdac.index)
|
||||
switch (ramdac->index)
|
||||
{
|
||||
case 0: temp=0x44; break;
|
||||
case 1: temp=0x02; break;
|
||||
case 0:
|
||||
temp = 0x44;
|
||||
break;
|
||||
case 1:
|
||||
temp = 0x02;
|
||||
break;
|
||||
default:
|
||||
if (stg_ramdac.index<0x100) temp=stg_ramdac.regs[stg_ramdac.index];
|
||||
else temp=0xFF;
|
||||
if (ramdac->index < 0x100) temp = ramdac->regs[ramdac->index];
|
||||
else temp = 0xff;
|
||||
break;
|
||||
}
|
||||
stg_ramdac.index++;
|
||||
ramdac->index++;
|
||||
break;
|
||||
}
|
||||
stg_ramdac.magic_count=stg_state_read[(stg_ramdac.command&0x10)?1:0][stg_ramdac.magic_count&7];
|
||||
ramdac->magic_count = stg_state_read[(ramdac->command & 0x10) ? 1 : 0][ramdac->magic_count & 7];
|
||||
return temp;
|
||||
case 0x3C8: case 0x3C9:
|
||||
stg_ramdac.magic_count=0;
|
||||
case 0x3c8: case 0x3c9:
|
||||
ramdac->magic_count=0;
|
||||
break;
|
||||
}
|
||||
return svga_in(addr, NULL);
|
||||
return svga_in(addr, svga);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,10 @@
|
|||
void stg_ramdac_out(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t stg_ramdac_in(uint16_t addr, void *priv);
|
||||
typedef struct stg_ramdac_t
|
||||
{
|
||||
int magic_count;
|
||||
uint8_t command;
|
||||
int index;
|
||||
uint8_t regs[256];
|
||||
} stg_ramdac_t;
|
||||
|
||||
void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga);
|
||||
uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga);
|
||||
|
|
|
|||
1416
src/vid_svga.c
1416
src/vid_svga.c
File diff suppressed because it is too large
Load diff
163
src/vid_svga.h
163
src/vid_svga.h
|
|
@ -1,60 +1,123 @@
|
|||
/*Vertical timings*/
|
||||
extern int svga_vtotal, svga_dispend, svga_vsyncstart, svga_split;
|
||||
/*Horizontal timings*/
|
||||
extern int svga_hdisp, svga_htotal, svga_hdisp_time, svga_rowoffset;
|
||||
/*Flags - svga_lowres = 1/2 clock in 256+ colour modes, svga_interlace = interlace mode enabled*/
|
||||
extern int svga_lowres, svga_interlace;
|
||||
|
||||
extern int svga_linedbl, svga_rowcount;
|
||||
|
||||
/*Status of display on*/
|
||||
extern int svga_hdisp_on;
|
||||
|
||||
extern double svga_clock;
|
||||
extern uint32_t svga_ma;
|
||||
extern void (*svga_recalctimings_ex)();
|
||||
|
||||
extern uint8_t svga_miscout;
|
||||
|
||||
extern int svga_init();
|
||||
extern void svga_poll();
|
||||
extern void svga_recalctimings();
|
||||
|
||||
typedef struct
|
||||
typedef struct svga_t
|
||||
{
|
||||
int ena;
|
||||
int x, y;
|
||||
int xoff, yoff;
|
||||
uint32_t addr;
|
||||
} SVGA_HWCURSOR;
|
||||
uint8_t crtcreg;
|
||||
uint8_t crtc[128];
|
||||
uint8_t gdcreg[16];
|
||||
int gdcaddr;
|
||||
uint8_t attrregs[32];
|
||||
int attraddr, attrff;
|
||||
uint8_t seqregs[64];
|
||||
int seqaddr;
|
||||
|
||||
uint8_t miscout;
|
||||
int vidclock;
|
||||
|
||||
uint32_t vram_limit;
|
||||
|
||||
uint8_t la, lb, lc, ld;
|
||||
|
||||
uint8_t dac_mask, dac_status;
|
||||
int dac_read, dac_write, dac_pos;
|
||||
|
||||
uint8_t cgastat;
|
||||
|
||||
int fast;
|
||||
uint8_t colourcompare, colournocare;
|
||||
int readmode, writemode, readplane;
|
||||
int chain4;
|
||||
uint8_t writemask;
|
||||
uint32_t charseta, charsetb;
|
||||
|
||||
uint8_t egapal[16];
|
||||
uint32_t pallook[256];
|
||||
PALETTE vgapal;
|
||||
|
||||
int vtotal, dispend, vsyncstart, split;
|
||||
int hdisp, hdisp_old, htotal, hdisp_time, rowoffset;
|
||||
int lowres, interlace;
|
||||
int linedbl, rowcount;
|
||||
double clock;
|
||||
uint32_t ma_latch;
|
||||
int bpp;
|
||||
|
||||
int dispontime, dispofftime;
|
||||
int vidtime;
|
||||
|
||||
uint8_t scrblank;
|
||||
|
||||
int dispon;
|
||||
int hdisp_on;
|
||||
|
||||
uint32_t ma, maback, ca;
|
||||
int vc;
|
||||
int sc;
|
||||
int linepos, vslines, linecountff, oddeven;
|
||||
int con, cursoron, blink;
|
||||
int scrollcache;
|
||||
|
||||
int firstline, lastline;
|
||||
int firstline_draw, lastline_draw;
|
||||
int displine;
|
||||
|
||||
uint8_t *vram;
|
||||
uint8_t *changedvram;
|
||||
int vrammask;
|
||||
|
||||
uint32_t write_bank, read_bank;
|
||||
|
||||
int fullchange;
|
||||
|
||||
int video_res_x, video_res_y, video_bpp;
|
||||
int frames, fps;
|
||||
|
||||
struct
|
||||
{
|
||||
int ena;
|
||||
int x, y;
|
||||
int xoff, yoff;
|
||||
uint32_t addr;
|
||||
} hwcursor, hwcursor_latch;
|
||||
|
||||
int hwcursor_on;
|
||||
|
||||
void (*render)(struct svga_t *svga);
|
||||
void (*recalctimings_ex)(struct svga_t *svga);
|
||||
|
||||
void (*video_out)(uint16_t addr, uint8_t val, void *p);
|
||||
uint8_t (*video_in) (uint16_t addr, void *p);
|
||||
|
||||
void (*hwcursor_draw)(struct svga_t *svga, int displine);
|
||||
|
||||
void *p;
|
||||
} svga_t;
|
||||
|
||||
extern int svga_init(svga_t *svga, void *p, int memsize,
|
||||
void (*recalctimings_ex)(struct svga_t *svga),
|
||||
uint8_t (*video_in) (uint16_t addr, void *p),
|
||||
void (*video_out)(uint16_t addr, uint8_t val, void *p),
|
||||
void (*hwcursor_draw)(struct svga_t *svga, int displine));
|
||||
extern void svga_recalctimings(svga_t *svga);
|
||||
|
||||
extern SVGA_HWCURSOR svga_hwcursor, svga_hwcursor_latch;
|
||||
|
||||
//extern int svga_hwcursor_x, svga_hwcursor_y;
|
||||
//extern int svga_hwcursor_xoff, svga_hwcursor_yoff;
|
||||
//extern uint32_t /*svga_hwcursor_addr, */svga_hwcursor_addr_cur;
|
||||
//extern int svga_hwcursor_ena;
|
||||
extern int svga_hwcursor_on;
|
||||
extern void (*svga_hwcursor_draw)(int displine);
|
||||
|
||||
uint8_t svga_read(uint32_t addr, void *priv);
|
||||
uint16_t svga_readw(uint32_t addr, void *priv);
|
||||
uint32_t svga_readl(uint32_t addr, void *priv);
|
||||
void svga_write(uint32_t addr, uint8_t val, void *priv);
|
||||
void svga_writew(uint32_t addr, uint16_t val, void *priv);
|
||||
void svga_writel(uint32_t addr, uint32_t val, void *priv);
|
||||
uint8_t svga_read_linear(uint32_t addr, void *priv);
|
||||
uint16_t svga_readw_linear(uint32_t addr, void *priv);
|
||||
uint32_t svga_readl_linear(uint32_t addr, void *priv);
|
||||
void svga_write_linear(uint32_t addr, uint8_t val, void *priv);
|
||||
void svga_writew_linear(uint32_t addr, uint16_t val, void *priv);
|
||||
void svga_writel_linear(uint32_t addr, uint32_t val, void *priv);
|
||||
uint8_t svga_read(uint32_t addr, void *p);
|
||||
uint16_t svga_readw(uint32_t addr, void *p);
|
||||
uint32_t svga_readl(uint32_t addr, void *p);
|
||||
void svga_write(uint32_t addr, uint8_t val, void *p);
|
||||
void svga_writew(uint32_t addr, uint16_t val, void *p);
|
||||
void svga_writel(uint32_t addr, uint32_t val, void *p);
|
||||
uint8_t svga_read_linear(uint32_t addr, void *p);
|
||||
uint16_t svga_readw_linear(uint32_t addr, void *p);
|
||||
uint32_t svga_readl_linear(uint32_t addr, void *p);
|
||||
void svga_write_linear(uint32_t addr, uint8_t val, void *p);
|
||||
void svga_writew_linear(uint32_t addr, uint16_t val, void *p);
|
||||
void svga_writel_linear(uint32_t addr, uint32_t val, void *p);
|
||||
|
||||
void svga_doblit(int y1, int y2);
|
||||
|
||||
extern uint32_t svga_vram_limit;
|
||||
int svga_add_status_info(char *s, int max_len, void *p);
|
||||
|
||||
extern uint8_t svga_rotate[8][256];
|
||||
|
||||
void svga_out(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t svga_in(uint16_t addr, void *priv);
|
||||
void svga_out(uint16_t addr, uint8_t val, void *p);
|
||||
uint8_t svga_in(uint16_t addr, void *p);
|
||||
|
|
|
|||
|
|
@ -3,36 +3,39 @@
|
|||
#include "vid_svga.h"
|
||||
#include "vid_svga_render.h"
|
||||
|
||||
void svga_render_blank()
|
||||
void svga_render_blank(svga_t *svga)
|
||||
{
|
||||
int x, xx;
|
||||
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
for (x=0;x<svga_hdisp;x++)
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
for (x = 0; x < svga->hdisp; x++)
|
||||
{
|
||||
switch (seqregs[1]&9)
|
||||
switch (svga->seqregs[1] & 9)
|
||||
{
|
||||
case 0:
|
||||
for (xx=0;xx<9;xx++) ((uint32_t *)buffer32->line[displine])[(x*9)+xx+32]=0;
|
||||
for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[svga->displine])[(x * 9) + xx + 32] = 0;
|
||||
break;
|
||||
case 1:
|
||||
for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[(x*8)+xx+32]=0;
|
||||
for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[svga->displine])[(x * 8) + xx + 32] = 0;
|
||||
break;
|
||||
case 8:
|
||||
for (xx=0;xx<18;xx++) ((uint32_t *)buffer32->line[displine])[(x*18)+xx+32]=0;
|
||||
for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[svga->displine])[(x * 18) + xx + 32] = 0;
|
||||
break;
|
||||
case 9:
|
||||
for (xx=0;xx<16;xx++) ((uint32_t *)buffer32->line[displine])[(x*16)+xx+32]=0;
|
||||
for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[svga->displine])[(x * 16) + xx + 32] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_text_40()
|
||||
void svga_render_text_40(svga_t *svga)
|
||||
{
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
if (fullchange)
|
||||
{
|
||||
|
|
@ -41,56 +44,59 @@ void svga_render_text_40()
|
|||
uint8_t chr, attr, dat;
|
||||
uint32_t charaddr;
|
||||
int fg, bg;
|
||||
int xinc = (seqregs[1] & 1) ? 16 : 18;
|
||||
int xinc = (svga->seqregs[1] & 1) ? 16 : 18;
|
||||
|
||||
for (x=0;x<svga_hdisp;x+=xinc)
|
||||
for (x = 0; x < svga->hdisp; x += xinc)
|
||||
{
|
||||
drawcursor=((ma==ca) && con && cursoron);
|
||||
chr=vram[(ma<<1)];
|
||||
attr=vram[(ma<<1)+4];
|
||||
if (attr&8) charaddr=charsetb+(chr*128);
|
||||
else charaddr=charseta+(chr*128);
|
||||
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
|
||||
chr = svga->vram[(svga->ma << 1) & svga->vrammask];
|
||||
attr = svga->vram[((svga->ma << 1) + 4) & svga->vrammask];
|
||||
if (attr & 8) charaddr = svga->charsetb + (chr * 128);
|
||||
else charaddr = svga->charseta + (chr * 128);
|
||||
|
||||
if (drawcursor)
|
||||
{
|
||||
bg=pallook[egapal[attr&15]];
|
||||
fg=pallook[egapal[attr>>4]];
|
||||
bg = svga->pallook[svga->egapal[attr & 15]];
|
||||
fg = svga->pallook[svga->egapal[attr >> 4]];
|
||||
}
|
||||
else
|
||||
{
|
||||
fg=pallook[egapal[attr&15]];
|
||||
bg=pallook[egapal[attr>>4]];
|
||||
if (attr&0x80 && attrregs[0x10]&8)
|
||||
fg = svga->pallook[svga->egapal[attr & 15]];
|
||||
bg = svga->pallook[svga->egapal[attr >> 4]];
|
||||
if (attr & 0x80 && svga->attrregs[0x10] & 8)
|
||||
{
|
||||
bg=pallook[egapal[(attr>>4)&7]];
|
||||
if (cgablink&16) fg=bg;
|
||||
bg = svga->pallook[svga->egapal[(attr >> 4) & 7]];
|
||||
if (svga->blink & 16)
|
||||
fg = bg;
|
||||
}
|
||||
}
|
||||
|
||||
dat=vram[charaddr+(sc<<2)];
|
||||
if (seqregs[1]&1)
|
||||
dat = svga->vram[charaddr + (svga->sc << 2)];
|
||||
if (svga->seqregs[1] & 1)
|
||||
{
|
||||
for (xx=0;xx<8;xx++)
|
||||
((uint32_t *)buffer32->line[displine])[(x+32+(xx<<1))&2047]=((uint32_t *)buffer32->line[displine])[(x+33+(xx<<1))&2047]=(dat&(0x80>>xx))?fg:bg;
|
||||
for (xx = 0; xx < 8; xx++)
|
||||
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + (xx << 1)) & 2047] = ((uint32_t *)buffer32->line[svga->displine])[(x + 33 + (xx << 1)) & 2047] = (dat & (0x80 >> xx)) ? fg : bg;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (xx=0;xx<8;xx++)
|
||||
((uint32_t *)buffer32->line[displine])[(x+32+(xx<<1))&2047]=((uint32_t *)buffer32->line[displine])[(x+33+(xx<<1))&2047]=(dat&(0x80>>xx))?fg:bg;
|
||||
if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4))
|
||||
((uint32_t *)buffer32->line[displine])[(x+32+16)&2047]=((uint32_t *)buffer32->line[displine])[(x+32+17)&2047]=bg;
|
||||
for (xx = 0; xx < 8; xx++)
|
||||
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + (xx << 1)) & 2047] = ((uint32_t *)buffer32->line[svga->displine])[(x + 33 + (xx << 1)) & 2047] = (dat & (0x80 >> xx)) ? fg : bg;
|
||||
if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4))
|
||||
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 16) & 2047] = ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 17) & 2047] = bg;
|
||||
else
|
||||
((uint32_t *)buffer32->line[displine])[(x+32+16)&2047]=((uint32_t *)buffer32->line[displine])[(x+32+17)&2047]=(dat&1)?fg:bg;
|
||||
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 16) & 2047] = ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 17) & 2047] = (dat & 1) ? fg : bg;
|
||||
}
|
||||
ma+=4; ma&=vrammask;
|
||||
svga->ma += 4;
|
||||
svga->ma &= svga->vrammask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_text_80()
|
||||
void svga_render_text_80(svga_t *svga)
|
||||
{
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
if (fullchange)
|
||||
{
|
||||
|
|
@ -99,388 +105,415 @@ void svga_render_text_80()
|
|||
uint8_t chr, attr, dat;
|
||||
uint32_t charaddr;
|
||||
int fg, bg;
|
||||
int xinc = (seqregs[1] & 1) ? 8 : 9;
|
||||
int xinc = (svga->seqregs[1] & 1) ? 8 : 9;
|
||||
|
||||
for (x=0;x<svga_hdisp;x+=xinc)
|
||||
for (x = 0; x < svga->hdisp; x += xinc)
|
||||
{
|
||||
drawcursor=((ma==ca) && con && cursoron);
|
||||
chr=vram[(ma<<1)];
|
||||
attr=vram[(ma<<1)+4];
|
||||
if (attr&8) charaddr=charsetb+(chr*128);
|
||||
else charaddr=charseta+(chr*128);
|
||||
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
|
||||
chr = svga->vram[(svga->ma << 1) & svga->vrammask];
|
||||
attr = svga->vram[((svga->ma << 1) + 4) & svga->vrammask];
|
||||
if (attr & 8) charaddr = svga->charsetb + (chr * 128);
|
||||
else charaddr = svga->charseta + (chr * 128);
|
||||
|
||||
if (drawcursor)
|
||||
{
|
||||
bg=pallook[egapal[attr&15]];
|
||||
fg=pallook[egapal[attr>>4]];
|
||||
bg = svga->pallook[svga->egapal[attr & 15]];
|
||||
fg = svga->pallook[svga->egapal[attr >> 4]];
|
||||
}
|
||||
else
|
||||
{
|
||||
fg=pallook[egapal[attr&15]];
|
||||
bg=pallook[egapal[attr>>4]];
|
||||
if (attr&0x80 && attrregs[0x10]&8)
|
||||
fg = svga->pallook[svga->egapal[attr & 15]];
|
||||
bg = svga->pallook[svga->egapal[attr >> 4]];
|
||||
if (attr & 0x80 && svga->attrregs[0x10] & 8)
|
||||
{
|
||||
bg=pallook[egapal[(attr>>4)&7]];
|
||||
if (cgablink&16) fg=bg;
|
||||
bg = svga->pallook[svga->egapal[(attr >> 4) & 7]];
|
||||
if (svga->blink & 16)
|
||||
fg = bg;
|
||||
}
|
||||
}
|
||||
|
||||
dat=vram[charaddr+(sc<<2)];
|
||||
if (seqregs[1]&1)
|
||||
dat = svga->vram[charaddr + (svga->sc << 2)];
|
||||
if (svga->seqregs[1] & 1)
|
||||
{
|
||||
for (xx=0;xx<8;xx++)
|
||||
((uint32_t *)buffer32->line[displine])[(x+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg;
|
||||
for (xx = 0; xx < 8; xx++)
|
||||
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (xx=0;xx<8;xx++)
|
||||
((uint32_t *)buffer32->line[displine])[(x+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg;
|
||||
if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4))
|
||||
((uint32_t *)buffer32->line[displine])[(x+32+8)&2047]=bg;
|
||||
for (xx = 0; xx < 8; xx++)
|
||||
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg;
|
||||
if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4))
|
||||
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 8) & 2047] = bg;
|
||||
else
|
||||
((uint32_t *)buffer32->line[displine])[(x+32+8)&2047]=(dat&1)?fg:bg;
|
||||
((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 8) & 2047] = (dat & 1) ? fg : bg;
|
||||
}
|
||||
ma+=4; ma&=vrammask;
|
||||
svga->ma += 4;
|
||||
svga->ma &= svga->vrammask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_4bpp_lowres()
|
||||
void svga_render_4bpp_lowres(svga_t *svga)
|
||||
{
|
||||
int x, offset;
|
||||
uint8_t edat[4], dat;
|
||||
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
offset=((8-scrollcache)<<1)+16;
|
||||
for (x = 0; x <= svga_hdisp; x += 16)
|
||||
offset = ((8 - svga->scrollcache) << 1) + 16;
|
||||
for (x = 0; x <= svga->hdisp; x += 16)
|
||||
{
|
||||
edat[0]=vram[ma];
|
||||
edat[1]=vram[ma|0x1];
|
||||
edat[2]=vram[ma|0x2];
|
||||
edat[3]=vram[ma|0x3];
|
||||
ma+=4; ma&=vrammask;
|
||||
edat[0] = svga->vram[svga->ma];
|
||||
edat[1] = svga->vram[svga->ma | 0x1];
|
||||
edat[2] = svga->vram[svga->ma | 0x2];
|
||||
edat[3] = svga->vram[svga->ma | 0x3];
|
||||
svga->ma += 4;
|
||||
svga->ma &= svga->vrammask;
|
||||
|
||||
dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[x+14+offset]=((uint32_t *)buffer32->line[displine])[x+15+offset]=pallook[egapal[dat&0xF]];
|
||||
((uint32_t *)buffer32->line[displine])[x+12+offset]=((uint32_t *)buffer32->line[displine])[x+13+offset]=pallook[egapal[dat>>4]];
|
||||
dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[x+10+offset]=((uint32_t *)buffer32->line[displine])[x+11+offset]=pallook[egapal[dat&0xF]];
|
||||
((uint32_t *)buffer32->line[displine])[x+8+offset]= ((uint32_t *)buffer32->line[displine])[x+9+offset]=pallook[egapal[dat>>4]];
|
||||
dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[x+6+offset]= ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[egapal[dat&0xF]];
|
||||
((uint32_t *)buffer32->line[displine])[x+4+offset]= ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[egapal[dat>>4]];
|
||||
dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[x+2+offset]= ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[egapal[dat&0xF]];
|
||||
((uint32_t *)buffer32->line[displine])[x+offset]= ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[egapal[dat>>4]];
|
||||
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 14 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 15 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 12 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 13 + offset] = svga->pallook[svga->egapal[dat >> 4]];
|
||||
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 10 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 11 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 8 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 9 + offset] = svga->pallook[svga->egapal[dat >> 4]];
|
||||
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 6 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 7 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 4 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 5 + offset] = svga->pallook[svga->egapal[dat >> 4]];
|
||||
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = svga->pallook[svga->egapal[dat >> 4]];
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_4bpp_highres()
|
||||
void svga_render_4bpp_highres(svga_t *svga)
|
||||
{
|
||||
int x, offset;
|
||||
uint8_t edat[4], dat;
|
||||
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
offset=(8-scrollcache)+24;
|
||||
for (x = 0; x <= svga_hdisp; x += 8)
|
||||
offset = (8 - svga->scrollcache) + 24;
|
||||
for (x = 0; x <= svga->hdisp; x += 8)
|
||||
{
|
||||
edat[0]=vram[ma];
|
||||
edat[1]=vram[ma|0x1];
|
||||
edat[2]=vram[ma|0x2];
|
||||
edat[3]=vram[ma|0x3];
|
||||
ma+=4; ma&=vrammask;
|
||||
edat[0] = svga->vram[svga->ma];
|
||||
edat[1] = svga->vram[svga->ma | 0x1];
|
||||
edat[2] = svga->vram[svga->ma | 0x2];
|
||||
edat[3] = svga->vram[svga->ma | 0x3];
|
||||
svga->ma += 4;
|
||||
svga->ma &= svga->vrammask;
|
||||
|
||||
dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[egapal[dat&0xF]];
|
||||
((uint32_t *)buffer32->line[displine])[x+6+offset]=pallook[egapal[dat>>4]];
|
||||
dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[egapal[dat&0xF]];
|
||||
((uint32_t *)buffer32->line[displine])[x+4+offset]=pallook[egapal[dat>>4]];
|
||||
dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[egapal[dat&0xF]];
|
||||
((uint32_t *)buffer32->line[displine])[x+2+offset]=pallook[egapal[dat>>4]];
|
||||
dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[egapal[dat&0xF]];
|
||||
((uint32_t *)buffer32->line[displine])[x+offset]= pallook[egapal[dat>>4]];
|
||||
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 7 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 6 + offset] = svga->pallook[svga->egapal[dat >> 4]];
|
||||
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 5 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 4 + offset] = svga->pallook[svga->egapal[dat >> 4]];
|
||||
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = svga->pallook[svga->egapal[dat >> 4]];
|
||||
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + offset] = svga->pallook[svga->egapal[dat >> 4]];
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_2bpp_lowres()
|
||||
void svga_render_2bpp_lowres(svga_t *svga)
|
||||
{
|
||||
int x, offset;
|
||||
uint8_t edat[4], dat;
|
||||
uint8_t edat[2], dat;
|
||||
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
offset=((8-scrollcache)<<1)+16;
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
offset = ((8 - svga->scrollcache) << 1) + 16;
|
||||
|
||||
/*Low res (320) only, though high res (640) should be possible*/
|
||||
for (x = 0; x <= svga_hdisp; x += 16)
|
||||
for (x = 0; x <= svga->hdisp; x += 16)
|
||||
{
|
||||
if (sc&1 && !(crtc[0x17]&1))
|
||||
if (svga->sc & 1 && !(svga->crtc[0x17] & 1))
|
||||
{
|
||||
edat[0]=vram[(ma<<1)+0x8000];
|
||||
edat[1]=vram[(ma<<1)+0x8004];
|
||||
edat[0] = svga->vram[(svga->ma << 1) + 0x8000];
|
||||
edat[1] = svga->vram[(svga->ma << 1) + 0x8004];
|
||||
}
|
||||
else
|
||||
{
|
||||
edat[0]=vram[(ma<<1)];
|
||||
edat[1]=vram[(ma<<1)+4];
|
||||
edat[0] = svga->vram[(svga->ma << 1)];
|
||||
edat[1] = svga->vram[(svga->ma << 1) + 4];
|
||||
}
|
||||
ma+=4; ma&=vrammask;
|
||||
svga->ma += 4; svga->ma &= svga->vrammask;
|
||||
|
||||
((uint32_t *)buffer32->line[displine])[x+14+offset]=((uint32_t *)buffer32->line[displine])[x+15+offset]=pallook[egapal[edat[1]&3]];
|
||||
((uint32_t *)buffer32->line[displine])[x+12+offset]=((uint32_t *)buffer32->line[displine])[x+13+offset]=pallook[egapal[(edat[1]>>2)&3]];
|
||||
dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[x+10+offset]=((uint32_t *)buffer32->line[displine])[x+11+offset]=pallook[egapal[(edat[1]>>4)&3]];
|
||||
((uint32_t *)buffer32->line[displine])[x+8+offset]= ((uint32_t *)buffer32->line[displine])[x+9+offset]=pallook[egapal[(edat[1]>>6)&3]];
|
||||
dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[x+6+offset]= ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[egapal[(edat[0]>>0)&3]];
|
||||
((uint32_t *)buffer32->line[displine])[x+4+offset]= ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[egapal[(edat[0]>>2)&3]];
|
||||
dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2);
|
||||
((uint32_t *)buffer32->line[displine])[x+2+offset]= ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[egapal[(edat[0]>>4)&3]];
|
||||
((uint32_t *)buffer32->line[displine])[x+offset]= ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[egapal[(edat[0]>>6)&3]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 14 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 15 + offset] = svga->pallook[svga->egapal[edat[1] & 3]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 12 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 13 + offset] = svga->pallook[svga->egapal[(edat[1] >> 2) & 3]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 10 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 11 + offset] = svga->pallook[svga->egapal[(edat[1] >> 4) & 3]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 8 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 9 + offset] = svga->pallook[svga->egapal[(edat[1] >> 6) & 3]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 6 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 7 + offset] = svga->pallook[svga->egapal[edat[0] & 3]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 4 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 5 + offset] = svga->pallook[svga->egapal[(edat[0] >> 2) & 3]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = svga->pallook[svga->egapal[(edat[0] >> 4) & 3]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = svga->pallook[svga->egapal[(edat[0] >> 6) & 3]];
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_8bpp_lowres()
|
||||
void svga_render_8bpp_lowres(svga_t *svga)
|
||||
{
|
||||
int x, offset;
|
||||
uint8_t edat[4];
|
||||
|
||||
if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
|
||||
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
|
||||
{
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
offset=(8-(scrollcache&6))+24;
|
||||
offset = (8 - (svga->scrollcache & 6)) + 24;
|
||||
|
||||
for (x = 0; x <= svga_hdisp; x += 8)
|
||||
for (x = 0; x <= svga->hdisp; x += 8)
|
||||
{
|
||||
edat[0]=vram[ma];
|
||||
edat[1]=vram[ma|0x1];
|
||||
edat[2]=vram[ma|0x2];
|
||||
edat[3]=vram[ma|0x3];
|
||||
ma+=4; ma&=vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[x+6+offset]= ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[edat[3]];
|
||||
((uint32_t *)buffer32->line[displine])[x+4+offset]= ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[edat[2]];
|
||||
((uint32_t *)buffer32->line[displine])[x+2+offset]= ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[edat[1]];
|
||||
((uint32_t *)buffer32->line[displine])[x+offset]= ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[edat[0]];
|
||||
edat[0] = svga->vram[svga->ma];
|
||||
edat[1] = svga->vram[svga->ma | 0x1];
|
||||
edat[2] = svga->vram[svga->ma | 0x2];
|
||||
edat[3] = svga->vram[svga->ma | 0x3];
|
||||
svga->ma += 4;
|
||||
svga->ma &= svga->vrammask;
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 6 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 7 + offset] = svga->pallook[edat[3]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 4 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 5 + offset] = svga->pallook[edat[2]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = svga->pallook[edat[1]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = svga->pallook[edat[0]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_8bpp_highres()
|
||||
void svga_render_8bpp_highres(svga_t *svga)
|
||||
{
|
||||
int x, offset;
|
||||
uint8_t edat[4];
|
||||
|
||||
if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
|
||||
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
|
||||
{
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
offset = (8 - ((scrollcache & 6) >> 1)) + 24;
|
||||
offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
||||
|
||||
for (x = 0; x <= svga_hdisp; x += 8)
|
||||
for (x = 0; x <= svga->hdisp; x += 8)
|
||||
{
|
||||
edat[0]=vram[ma];
|
||||
edat[1]=vram[ma|0x1];
|
||||
edat[2]=vram[ma|0x2];
|
||||
edat[3]=vram[ma|0x3];
|
||||
ma+=4; ma&=vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[x+3+offset] = pallook[edat[3]];
|
||||
((uint32_t *)buffer32->line[displine])[x+2+offset] = pallook[edat[2]];
|
||||
((uint32_t *)buffer32->line[displine])[x+1+offset] = pallook[edat[1]];
|
||||
((uint32_t *)buffer32->line[displine])[x+offset] = pallook[edat[0]];
|
||||
edat[0]=vram[ma];
|
||||
edat[1]=vram[ma|0x1];
|
||||
edat[2]=vram[ma|0x2];
|
||||
edat[3]=vram[ma|0x3];
|
||||
ma+=4; ma&=vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[x+7+offset] = pallook[edat[3]];
|
||||
((uint32_t *)buffer32->line[displine])[x+6+offset] = pallook[edat[2]];
|
||||
((uint32_t *)buffer32->line[displine])[x+5+offset] = pallook[edat[1]];
|
||||
((uint32_t *)buffer32->line[displine])[x+4+offset] = pallook[edat[0]];
|
||||
edat[0] = svga->vram[svga->ma];
|
||||
edat[1] = svga->vram[svga->ma | 0x1];
|
||||
edat[2] = svga->vram[svga->ma | 0x2];
|
||||
edat[3] = svga->vram[svga->ma | 0x3];
|
||||
svga->ma += 4;
|
||||
svga->ma &= svga->vrammask;
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = svga->pallook[edat[3]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = svga->pallook[edat[2]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = svga->pallook[edat[1]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + offset] = svga->pallook[edat[0]];
|
||||
|
||||
edat[0] = svga->vram[svga->ma];
|
||||
edat[1] = svga->vram[svga->ma | 0x1];
|
||||
edat[2] = svga->vram[svga->ma | 0x2];
|
||||
edat[3] = svga->vram[svga->ma | 0x3];
|
||||
svga->ma += 4;
|
||||
svga->ma &= svga->vrammask;
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 7 + offset] = svga->pallook[edat[3]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 6 + offset] = svga->pallook[edat[2]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 5 + offset] = svga->pallook[edat[1]];
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 4 + offset] = svga->pallook[edat[0]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_15bpp_lowres()
|
||||
void svga_render_15bpp_lowres(svga_t *svga)
|
||||
{
|
||||
int x, offset;
|
||||
uint16_t fg, bg;
|
||||
|
||||
if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
|
||||
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
|
||||
{
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
offset=(8-(scrollcache&6))+24;
|
||||
offset = (8 - (svga->scrollcache & 6)) + 24;
|
||||
|
||||
for (x = 0; x <= svga_hdisp; x += 4)
|
||||
for (x = 0; x <= svga->hdisp; x += 4)
|
||||
{
|
||||
fg=vram[ma]|(vram[ma|0x1]<<8);
|
||||
bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
|
||||
ma+=4; ma&=vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[x+2+offset]=((uint32_t *)buffer32->line[displine])[x+3+offset]=((bg&31)<<3)|(((bg>>5)&31)<<11)|(((bg>>10)&31)<<19);
|
||||
((uint32_t *)buffer32->line[displine])[x+0+offset]=((uint32_t *)buffer32->line[displine])[x+1+offset]=((fg&31)<<3)|(((fg>>5)&31)<<11)|(((fg>>10)&31)<<19);
|
||||
fg = svga->vram[svga->ma] | (svga->vram[svga->ma | 0x1] << 8);
|
||||
bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8);
|
||||
svga->ma += 4;
|
||||
svga->ma &= svga->vrammask;
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = ((bg & 31) << 3) | (((bg >> 5) & 31) << 11) | (((bg >> 10) & 31) << 19);
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = ((fg & 31) << 3) | (((fg >> 5) & 31) << 11) | (((fg >> 10) & 31) << 19);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_15bpp_highres()
|
||||
void svga_render_15bpp_highres(svga_t *svga)
|
||||
{
|
||||
int x, offset;
|
||||
uint16_t fg, bg;
|
||||
|
||||
if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
|
||||
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
|
||||
{
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
offset = (8 - ((scrollcache & 6) >> 1)) + 24;
|
||||
offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
||||
|
||||
for (x = 0; x <= svga->hdisp; x += 2)
|
||||
{
|
||||
fg = svga->vram[svga->ma] | (svga->vram[svga->ma | 0x1] << 8);
|
||||
bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8);
|
||||
svga->ma += 4;
|
||||
svga->ma &= svga->vrammask;
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = ((bg & 31) << 3) | (((bg >> 5) & 31) << 11) | (((bg >> 10) & 31) << 19);
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((fg & 31) << 3) | (((fg >> 5) & 31) << 11) | (((fg >> 10) & 31) << 19);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_16bpp_lowres(svga_t *svga)
|
||||
{
|
||||
int x, offset;
|
||||
uint16_t fg, bg;
|
||||
|
||||
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
|
||||
{
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
offset = (8 - (svga->scrollcache & 6)) + 24;
|
||||
|
||||
for (x = 0; x <= svga->hdisp; x += 4)
|
||||
{
|
||||
fg = svga->vram[svga->ma] | (svga->vram[svga->ma | 0x1] << 8);
|
||||
bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8);
|
||||
svga->ma += 4;
|
||||
svga->ma &= svga->vrammask;
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = ((bg & 31) << 3) | (((bg >> 5) & 63) << 10) | (((bg >> 11) & 31) << 19);
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = ((fg & 31) << 3) | (((fg >> 5) & 63) << 10) | (((fg >> 11) & 31) << 19);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_16bpp_highres(svga_t *svga)
|
||||
{
|
||||
int x, offset;
|
||||
uint16_t fg, bg;
|
||||
|
||||
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
|
||||
{
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
||||
|
||||
for (x = 0; x <= svga_hdisp; x += 2)
|
||||
for (x = 0; x <= svga->hdisp; x += 2)
|
||||
{
|
||||
fg=vram[ma]|(vram[ma|0x1]<<8);
|
||||
bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
|
||||
ma+=4; ma&=vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[x + 1 + offset] = ((bg&31)<<3)|(((bg>>5)&31)<<11)|(((bg>>10)&31)<<19);
|
||||
((uint32_t *)buffer32->line[displine])[x + 0 + offset] = ((fg&31)<<3)|(((fg>>5)&31)<<11)|(((fg>>10)&31)<<19);
|
||||
fg = svga->vram[svga->ma] | (svga->vram[svga->ma | 0x1] << 8);
|
||||
bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8);
|
||||
svga->ma += 4;
|
||||
svga->ma &= svga->vrammask;
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = ((bg & 31) << 3) | (((bg >> 5) & 63) << 10) | (((bg >> 11) & 31) << 19);
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + offset] = ((fg & 31) << 3) | (((fg >> 5) & 63) << 10) | (((fg >> 11) & 31) << 19);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_16bpp_lowres()
|
||||
{
|
||||
int x, offset;
|
||||
uint16_t fg, bg;
|
||||
|
||||
if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
|
||||
{
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
|
||||
offset=(8-(scrollcache&6))+24;
|
||||
|
||||
for (x = 0; x <= svga_hdisp; x += 4)
|
||||
{
|
||||
fg=vram[ma]|(vram[ma|0x1]<<8);
|
||||
bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
|
||||
ma+=4; ma&=vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[x+2+offset]=((uint32_t *)buffer32->line[displine])[x+3+offset]=((bg&31)<<3)|(((bg>>5)&63)<<10)|(((bg>>11)&31)<<19);
|
||||
((uint32_t *)buffer32->line[displine])[x+0+offset]=((uint32_t *)buffer32->line[displine])[x+1+offset]=((fg&31)<<3)|(((fg>>5)&63)<<10)|(((fg>>11)&31)<<19);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_16bpp_highres()
|
||||
{
|
||||
int x, offset;
|
||||
uint16_t fg, bg;
|
||||
|
||||
if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
|
||||
{
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
|
||||
offset = (8 - ((scrollcache & 6) >> 1)) + 24;
|
||||
|
||||
for (x = 0; x <= svga_hdisp; x += 2)
|
||||
{
|
||||
fg=vram[ma]|(vram[ma|0x1]<<8);
|
||||
bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
|
||||
ma+=4; ma&=vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[x + 1 + offset] = ((bg&31)<<3)|(((bg>>5)&63)<<10)|(((bg>>11)&31)<<19);
|
||||
((uint32_t *)buffer32->line[displine])[x + 0 + offset] = ((fg&31)<<3)|(((fg>>5)&63)<<10)|(((fg>>11)&31)<<19);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_24bpp_lowres()
|
||||
void svga_render_24bpp_lowres(svga_t *svga)
|
||||
{
|
||||
int x, offset;
|
||||
uint32_t fg;
|
||||
|
||||
if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
|
||||
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
|
||||
{
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
offset=(8-(scrollcache&6))+24;
|
||||
offset = (8 - (svga->scrollcache & 6)) + 24;
|
||||
|
||||
for (x = 0; x <= svga_hdisp; x++)
|
||||
for (x = 0; x <= svga->hdisp; x++)
|
||||
{
|
||||
fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16);
|
||||
ma+=3; ma&=vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[(x<<1)+offset]=((uint32_t *)buffer32->line[displine])[(x<<1)+1+offset]=fg;
|
||||
fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
|
||||
svga->ma += 3;
|
||||
svga->ma &= svga->vrammask;
|
||||
((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_24bpp_highres()
|
||||
void svga_render_24bpp_highres(svga_t *svga)
|
||||
{
|
||||
int x, offset;
|
||||
uint32_t fg;
|
||||
|
||||
if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
|
||||
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
|
||||
{
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
offset = (8 - ((scrollcache & 6) >> 1)) + 24;
|
||||
offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
||||
|
||||
for (x = 0; x <= svga_hdisp; x++)
|
||||
for (x = 0; x <= svga->hdisp; x++)
|
||||
{
|
||||
fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16);
|
||||
ma+=3; ma&=vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[x + offset] = fg;
|
||||
fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
|
||||
svga->ma += 3;
|
||||
svga->ma &= svga->vrammask;
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + offset] = fg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_32bpp_lowres()
|
||||
void svga_render_32bpp_lowres(svga_t *svga)
|
||||
{
|
||||
int x, offset;
|
||||
uint32_t fg;
|
||||
|
||||
if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
|
||||
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
|
||||
{
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
offset=(8-(scrollcache&6))+24;
|
||||
offset = (8 - (svga->scrollcache & 6)) + 24;
|
||||
|
||||
for (x = 0; x <= svga_hdisp; x++)
|
||||
for (x = 0; x <= svga->hdisp; x++)
|
||||
{
|
||||
fg = vram[ma] | (vram[ma + 1] << 8) | (vram[ma + 2] << 16);
|
||||
ma += 4; ma &= vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[displine])[(x << 1) + 1 + offset] = fg;
|
||||
fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
|
||||
svga->ma += 4;
|
||||
svga->ma &= svga->vrammask;
|
||||
((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_32bpp_highres()
|
||||
void svga_render_32bpp_highres(svga_t *svga)
|
||||
{
|
||||
int x, offset;
|
||||
uint32_t fg;
|
||||
|
||||
if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
|
||||
if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
|
||||
{
|
||||
if (firstline_draw == 2000) firstline_draw = displine;
|
||||
lastline_draw = displine;
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
offset = (8 - ((scrollcache & 6) >> 1)) + 24;
|
||||
offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
||||
|
||||
for (x = 0; x <= svga_hdisp; x++)
|
||||
for (x = 0; x <= svga->hdisp; x++)
|
||||
{
|
||||
fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16);
|
||||
ma+=4; ma&=vrammask;
|
||||
((uint32_t *)buffer32->line[displine])[x + offset] = fg;
|
||||
fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
|
||||
svga->ma += 4;
|
||||
svga->ma &= svga->vrammask;
|
||||
((uint32_t *)buffer32->line[svga->displine])[x + offset] = fg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,22 +9,22 @@ extern int scrollcache;
|
|||
|
||||
extern uint8_t edatlookup[4][4];
|
||||
|
||||
void svga_render_blank();
|
||||
void svga_render_text_40();
|
||||
void svga_render_text_80();
|
||||
void svga_render_blank(svga_t *svga);
|
||||
void svga_render_text_40(svga_t *svga);
|
||||
void svga_render_text_80(svga_t *svga);
|
||||
|
||||
void svga_render_2bpp_lowres();
|
||||
void svga_render_4bpp_lowres();
|
||||
void svga_render_4bpp_highres();
|
||||
void svga_render_8bpp_lowres();
|
||||
void svga_render_8bpp_highres();
|
||||
void svga_render_15bpp_lowres();
|
||||
void svga_render_15bpp_highres();
|
||||
void svga_render_16bpp_lowres();
|
||||
void svga_render_16bpp_highres();
|
||||
void svga_render_24bpp_lowres();
|
||||
void svga_render_24bpp_highres();
|
||||
void svga_render_32bpp_lowres();
|
||||
void svga_render_32bpp_highres();
|
||||
void svga_render_2bpp_lowres(svga_t *svga);
|
||||
void svga_render_4bpp_lowres(svga_t *svga);
|
||||
void svga_render_4bpp_highres(svga_t *svga);
|
||||
void svga_render_8bpp_lowres(svga_t *svga);
|
||||
void svga_render_8bpp_highres(svga_t *svga);
|
||||
void svga_render_15bpp_lowres(svga_t *svga);
|
||||
void svga_render_15bpp_highres(svga_t *svga);
|
||||
void svga_render_16bpp_lowres(svga_t *svga);
|
||||
void svga_render_16bpp_highres(svga_t *svga);
|
||||
void svga_render_24bpp_lowres(svga_t *svga);
|
||||
void svga_render_24bpp_highres(svga_t *svga);
|
||||
void svga_render_32bpp_lowres(svga_t *svga);
|
||||
void svga_render_32bpp_highres(svga_t *svga);
|
||||
|
||||
extern void (*svga_render)();
|
||||
extern void (*svga_render)(svga_t *svga);
|
||||
|
|
|
|||
787
src/vid_tandy.c
787
src/vid_tandy.c
File diff suppressed because it is too large
Load diff
1
src/vid_tandy.h
Normal file
1
src/vid_tandy.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
extern device_t tandy_device;
|
||||
|
|
@ -7,29 +7,29 @@
|
|||
static int tkd8001_state=0;
|
||||
static uint8_t tkd8001_ctrl;
|
||||
|
||||
void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *priv)
|
||||
void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
// pclog("OUT RAMDAC %04X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3C6:
|
||||
if (tkd8001_state == 4)
|
||||
if (ramdac->state == 4)
|
||||
{
|
||||
tkd8001_state = 0;
|
||||
tkd8001_ctrl = val;
|
||||
switch (val>>5)
|
||||
ramdac->state = 0;
|
||||
ramdac->ctrl = val;
|
||||
switch (val >> 5)
|
||||
{
|
||||
case 0: case 1: case 2: case 3:
|
||||
bpp = 8;
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 5:
|
||||
bpp = 15;
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 6:
|
||||
bpp = 24;
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
case 7:
|
||||
bpp = 16;
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
|
@ -37,28 +37,28 @@ void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *priv)
|
|||
// tkd8001_state = 0;
|
||||
break;
|
||||
case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
tkd8001_state = 0;
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
}
|
||||
svga_out(addr, val, NULL);
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
uint8_t tkd8001_ramdac_in(uint16_t addr, void *priv)
|
||||
uint8_t tkd8001_ramdac_in(uint16_t addr, tkd8001_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
// pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3C6:
|
||||
if (tkd8001_state == 4)
|
||||
if (ramdac->state == 4)
|
||||
{
|
||||
//tkd8001_state = 0;
|
||||
return tkd8001_ctrl;
|
||||
return ramdac->ctrl;
|
||||
}
|
||||
tkd8001_state++;
|
||||
ramdac->state++;
|
||||
break;
|
||||
case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
tkd8001_state = 0;
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
}
|
||||
return svga_in(addr, NULL);
|
||||
return svga_in(addr, svga);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,8 @@
|
|||
void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t tkd8001_ramdac_in(uint16_t addr, void *priv);
|
||||
typedef struct tkd8001_ramdac_t
|
||||
{
|
||||
int state;
|
||||
uint8_t ctrl;
|
||||
} tkd8001_ramdac_t;
|
||||
|
||||
void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga);
|
||||
uint8_t tkd8001_ramdac_in(uint16_t addr, tkd8001_ramdac_t *ramdac, svga_t *svga);
|
||||
|
|
|
|||
823
src/vid_tvga.c
823
src/vid_tvga.c
File diff suppressed because it is too large
Load diff
2
src/vid_tvga.h
Normal file
2
src/vid_tvga.h
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
extern device_t tvga8900d_device;
|
||||
extern device_t tgui9440_device;
|
||||
|
|
@ -6,61 +6,58 @@
|
|||
#include "vid_svga.h"
|
||||
#include "vid_unk_ramdac.h"
|
||||
|
||||
static int unk_state=0;
|
||||
static uint8_t unk_ctrl;
|
||||
|
||||
void unk_ramdac_out(uint16_t addr, uint8_t val, void *priv)
|
||||
void unk_ramdac_out(uint16_t addr, uint8_t val, unk_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
//pclog("OUT RAMDAC %04X %02X\n",addr,val);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3C6:
|
||||
if (unk_state == 4)
|
||||
if (ramdac->state == 4)
|
||||
{
|
||||
unk_state = 0;
|
||||
unk_ctrl = val;
|
||||
ramdac->state = 0;
|
||||
ramdac->ctrl = val;
|
||||
switch ((val&1)|((val&0xE0)>>4))
|
||||
{
|
||||
case 0: case 1: case 2: case 3:
|
||||
bpp = 8;
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 6: case 7:
|
||||
bpp = 24;
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
case 8: case 9: case 0xA: case 0xB:
|
||||
bpp = 15;
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 0xC: case 0xD: case 0xE: case 0xF:
|
||||
bpp = 16;
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
unk_state = 0;
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
unk_state = 0;
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
}
|
||||
svga_out(addr, val, NULL);
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
uint8_t unk_ramdac_in(uint16_t addr, void *priv)
|
||||
uint8_t unk_ramdac_in(uint16_t addr, unk_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
//pclog("IN RAMDAC %04X\n",addr);
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3C6:
|
||||
if (unk_state == 4)
|
||||
if (ramdac->state == 4)
|
||||
{
|
||||
unk_state = 0;
|
||||
return unk_ctrl;
|
||||
ramdac->state = 0;
|
||||
return ramdac->ctrl;
|
||||
}
|
||||
unk_state++;
|
||||
ramdac->state++;
|
||||
break;
|
||||
case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
unk_state = 0;
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
}
|
||||
return svga_in(addr, NULL);
|
||||
return svga_in(addr, svga);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,8 @@
|
|||
void unk_ramdac_out(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t unk_ramdac_in(uint16_t addr, void *priv);
|
||||
typedef struct unk_ramdac_t
|
||||
{
|
||||
int state;
|
||||
uint8_t ctrl;
|
||||
} unk_ramdac_t;
|
||||
|
||||
void unk_ramdac_out(uint16_t addr, uint8_t val, unk_ramdac_t *ramdac, svga_t *svga);
|
||||
uint8_t unk_ramdac_in(uint16_t addr, unk_ramdac_t *ramdac, svga_t *svga);
|
||||
|
|
|
|||
108
src/vid_vga.c
108
src/vid_vga.c
|
|
@ -1,92 +1,116 @@
|
|||
/*IBM VGA emulation*/
|
||||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "io.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_vga.h"
|
||||
|
||||
void vga_out(uint16_t addr, uint8_t val, void *priv)
|
||||
typedef struct vga_t
|
||||
{
|
||||
svga_t svga;
|
||||
} vga_t;
|
||||
|
||||
void vga_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
vga_t *vga = (vga_t *)p;
|
||||
svga_t *svga = &vga->svga;
|
||||
uint8_t old;
|
||||
|
||||
pclog("vga_out : %04X %02X %04X:%04X %02X %i\n", addr, val, CS,pc, ram[0x489], ins);
|
||||
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3D4:
|
||||
crtcreg = val & 0x1f;
|
||||
svga->crtcreg = val & 0x1f;
|
||||
return;
|
||||
case 0x3D5:
|
||||
if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
|
||||
old=crtc[crtcreg];
|
||||
crtc[crtcreg]=val;
|
||||
if (old!=val)
|
||||
if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
if (old != val)
|
||||
{
|
||||
if (crtcreg<0xE || crtcreg>0x10)
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
|
||||
{
|
||||
fullchange=changeframecount;
|
||||
svga_recalctimings();
|
||||
fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
svga_out(addr, val, NULL);
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
uint8_t vga_in(uint16_t addr, void *priv)
|
||||
uint8_t vga_in(uint16_t addr, void *p)
|
||||
{
|
||||
vga_t *vga = (vga_t *)p;
|
||||
svga_t *svga = &vga->svga;
|
||||
uint8_t temp;
|
||||
|
||||
if (addr != 0x3da) pclog("vga_in : %04X ", addr);
|
||||
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3D4:
|
||||
temp = crtcreg;
|
||||
temp = svga->crtcreg;
|
||||
break;
|
||||
case 0x3D5:
|
||||
temp = crtc[crtcreg];
|
||||
temp = svga->crtc[svga->crtcreg];
|
||||
break;
|
||||
default:
|
||||
temp = svga_in(addr, NULL);
|
||||
temp = svga_in(addr, svga);
|
||||
break;
|
||||
}
|
||||
if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc);
|
||||
return temp;
|
||||
}
|
||||
|
||||
int vga_init()
|
||||
void *vga_init()
|
||||
{
|
||||
svga_recalctimings_ex = NULL;
|
||||
svga_vram_limit = 1 << 18; /*256kb*/
|
||||
vrammask = 0x3ffff;
|
||||
svgawbank = svgarbank = 0;
|
||||
bpp = 8;
|
||||
svga_miscout = 1;
|
||||
return svga_init();
|
||||
vga_t *vga = malloc(sizeof(vga_t));
|
||||
memset(vga, 0, sizeof(vga_t));
|
||||
|
||||
svga_init(&vga->svga, vga, 1 << 18, /*256kb*/
|
||||
NULL,
|
||||
vga_in, vga_out,
|
||||
NULL);
|
||||
|
||||
io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga);
|
||||
|
||||
vga->svga.bpp = 8;
|
||||
vga->svga.miscout = 1;
|
||||
|
||||
return vga;
|
||||
}
|
||||
|
||||
GFXCARD vid_vga =
|
||||
void vga_close(void *p)
|
||||
{
|
||||
vga_t *vga = (vga_t *)p;
|
||||
|
||||
svga_close(&vga->svga);
|
||||
|
||||
free(vga);
|
||||
}
|
||||
|
||||
void vga_speed_changed(void *p)
|
||||
{
|
||||
vga_t *vga = (vga_t *)p;
|
||||
|
||||
svga_recalctimings(&vga->svga);
|
||||
}
|
||||
|
||||
device_t vga_device =
|
||||
{
|
||||
"VGA",
|
||||
vga_init,
|
||||
/*IO at 3Cx/3Dx*/
|
||||
vga_out,
|
||||
vga_in,
|
||||
/*IO at 3Ax/3Bx*/
|
||||
video_out_null,
|
||||
video_in_null,
|
||||
|
||||
svga_poll,
|
||||
svga_recalctimings,
|
||||
|
||||
svga_write,
|
||||
video_write_null,
|
||||
video_write_null,
|
||||
|
||||
svga_read,
|
||||
video_read_null,
|
||||
video_read_null
|
||||
vga_close,
|
||||
vga_speed_changed,
|
||||
svga_add_status_info
|
||||
};
|
||||
|
|
|
|||
1
src/vid_vga.h
Normal file
1
src/vid_vga.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
extern device_t vga_device;
|
||||
348
src/video.c
348
src/video.c
|
|
@ -1,13 +1,45 @@
|
|||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
#include "io.h"
|
||||
#include "cpu.h"
|
||||
#include "timer.h"
|
||||
|
||||
int video_timer;
|
||||
#include "vid_ati18800.h"
|
||||
#include "vid_ati28800.h"
|
||||
#include "vid_ati_mach64.h"
|
||||
#include "vid_cga.h"
|
||||
#include "vid_cl5429.h"
|
||||
#include "vid_ega.h"
|
||||
#include "vid_et4000.h"
|
||||
#include "vid_et4000w32.h"
|
||||
#include "vid_hercules.h"
|
||||
#include "vid_mda.h"
|
||||
#include "vid_olivetti_m24.h"
|
||||
#include "vid_oti067.h"
|
||||
#include "vid_paradise.h"
|
||||
#include "vid_pc1512.h"
|
||||
#include "vid_pc1640.h"
|
||||
#include "vid_pc200.h"
|
||||
#include "vid_s3.h"
|
||||
#include "vid_s3_virge.h"
|
||||
#include "vid_tandy.h"
|
||||
#include "vid_tvga.h"
|
||||
#include "vid_vga.h"
|
||||
|
||||
int egareads=0,egawrites=0;
|
||||
int changeframecount=2;
|
||||
|
||||
uint8_t rotatevga[8][256];
|
||||
|
||||
int frames = 0;
|
||||
|
||||
int fullchange;
|
||||
|
||||
uint8_t edatlookup[4][4];
|
||||
|
||||
/*Video timing settings -
|
||||
|
||||
|
|
@ -84,70 +116,6 @@ int video_res_x, video_res_y, video_bpp;
|
|||
void (*video_blit_memtoscreen)(int x, int y, int y1, int y2, int w, int h);
|
||||
void (*video_blit_memtoscreen_8)(int x, int y, int w, int h);
|
||||
|
||||
void (*video_out) (uint16_t addr, uint8_t val, void *priv);
|
||||
void (*video_mono_out)(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t (*video_in) (uint16_t addr, void *priv);
|
||||
uint8_t (*video_mono_in)(uint16_t addr, void *priv);
|
||||
|
||||
void (*video_write_a000)(uint32_t addr, uint8_t val, void *priv);
|
||||
void (*video_write_b000)(uint32_t addr, uint8_t val, void *priv);
|
||||
void (*video_write_b800)(uint32_t addr, uint8_t val, void *priv);
|
||||
|
||||
void (*video_write_a000_w)(uint32_t addr, uint16_t val, void *priv);
|
||||
void (*video_write_a000_l)(uint32_t addr, uint32_t val, void *priv);
|
||||
|
||||
uint8_t (*video_read_a000)(uint32_t addr, void *priv);
|
||||
uint8_t (*video_read_b000)(uint32_t addr, void *priv);
|
||||
uint8_t (*video_read_b800)(uint32_t addr, void *priv);
|
||||
|
||||
void (*video_recalctimings)();
|
||||
|
||||
void video_out_null(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t video_in_null(uint16_t addr, void *priv)
|
||||
{
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
void video_write_null(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t video_read_null(uint32_t addr, void *priv)
|
||||
{
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
void video_load(GFXCARD g)
|
||||
{
|
||||
io_sethandler(0x03a0, 0x0020, g.mono_in, NULL, NULL, g.mono_out, NULL, NULL, NULL);
|
||||
io_sethandler(0x03c0, 0x0020, g.in, NULL, NULL, g.out, NULL, NULL, NULL);
|
||||
|
||||
video_out = g.out;
|
||||
video_in = g.in;
|
||||
video_mono_out = g.mono_out;
|
||||
video_mono_in = g.mono_in;
|
||||
|
||||
pollvideo = g.poll;
|
||||
video_recalctimings = g.recalctimings;
|
||||
|
||||
video_write_a000 = g.write_a000;
|
||||
video_write_b000 = g.write_b000;
|
||||
video_write_b800 = g.write_b800;
|
||||
|
||||
video_read_a000 = g.read_a000;
|
||||
video_read_b000 = g.read_b000;
|
||||
video_read_b800 = g.read_b800;
|
||||
|
||||
video_write_a000_w = video_write_a000_l = NULL;
|
||||
|
||||
g.init();
|
||||
|
||||
video_timer = timer_add(pollvideo, &vidtime, TIMER_ALWAYS_ENABLED, NULL);
|
||||
}
|
||||
|
||||
void video_init()
|
||||
{
|
||||
pclog("Video_init %i %i\n",romset,gfxcard);
|
||||
|
|
@ -155,107 +123,108 @@ void video_init()
|
|||
switch (romset)
|
||||
{
|
||||
case ROM_TANDY:
|
||||
video_load(vid_tandy);
|
||||
device_add(&tandy_device);
|
||||
return;
|
||||
|
||||
case ROM_PC1512:
|
||||
video_load(vid_pc1512);
|
||||
device_add(&pc1512_device);
|
||||
return;
|
||||
|
||||
case ROM_PC1640:
|
||||
video_load(vid_pc1640);
|
||||
device_add(&pc1640_device);
|
||||
return;
|
||||
|
||||
case ROM_PC200:
|
||||
video_load(vid_pc200);
|
||||
device_add(&pc200_device);
|
||||
return;
|
||||
|
||||
case ROM_OLIM24:
|
||||
video_load(vid_m24);
|
||||
device_add(&m24_device);
|
||||
return;
|
||||
|
||||
case ROM_PC2086:
|
||||
case ROM_PC3086:
|
||||
device_add(¶dise_pvga1a_device);
|
||||
return;
|
||||
case ROM_MEGAPC:
|
||||
video_load(vid_paradise);
|
||||
device_add(¶dise_wd90c11_device);
|
||||
return;
|
||||
|
||||
case ROM_ACER386:
|
||||
video_load(vid_oti067);
|
||||
device_add(&oti067_device);
|
||||
return;
|
||||
}
|
||||
switch (gfxcard)
|
||||
{
|
||||
case GFX_MDA:
|
||||
video_load(vid_mda);
|
||||
device_add(&mda_device);
|
||||
break;
|
||||
|
||||
case GFX_HERCULES:
|
||||
video_load(vid_hercules);
|
||||
device_add(&hercules_device);
|
||||
break;
|
||||
|
||||
case GFX_CGA:
|
||||
video_load(vid_cga);
|
||||
device_add(&cga_device);
|
||||
break;
|
||||
|
||||
case GFX_EGA:
|
||||
video_load(vid_ega);
|
||||
device_add(&ega_device);
|
||||
break;
|
||||
|
||||
case GFX_TVGA:
|
||||
video_load(vid_tvga);
|
||||
device_add(&tvga8900d_device);
|
||||
break;
|
||||
|
||||
case GFX_ET4000:
|
||||
video_load(vid_et4000);
|
||||
device_add(&et4000_device);
|
||||
break;
|
||||
|
||||
case GFX_ET4000W32:
|
||||
video_load(vid_et4000w32p);
|
||||
device_add(&et4000w32p_device);
|
||||
break;
|
||||
|
||||
case GFX_BAHAMAS64:
|
||||
video_load(vid_s3);
|
||||
device_add(&s3_bahamas64_device);
|
||||
break;
|
||||
|
||||
case GFX_N9_9FX:
|
||||
video_load(vid_s3);
|
||||
device_add(&s3_9fx_device);
|
||||
break;
|
||||
|
||||
case GFX_STEALTH64:
|
||||
video_load(vid_s3);
|
||||
break;
|
||||
|
||||
case GFX_VIRGE:
|
||||
video_load(vid_s3_virge);
|
||||
device_add(&s3_virge_device);
|
||||
break;
|
||||
|
||||
case GFX_TGUI9440:
|
||||
video_load(vid_tgui9440);
|
||||
device_add(&tgui9440_device);
|
||||
break;
|
||||
|
||||
case GFX_VGA:
|
||||
video_load(vid_vga);
|
||||
device_add(&vga_device);
|
||||
break;
|
||||
|
||||
case GFX_VGAEDGE16:
|
||||
video_load(vid_ati18800);
|
||||
device_add(&ati18800_device);
|
||||
break;
|
||||
|
||||
case GFX_VGACHARGER:
|
||||
video_load(vid_ati28800);
|
||||
device_add(&ati18800_device);
|
||||
break;
|
||||
|
||||
case GFX_OTI067:
|
||||
video_load(vid_oti067);
|
||||
device_add(&oti067_device);
|
||||
return;
|
||||
|
||||
case GFX_MACH64GX:
|
||||
video_load(vid_mach64);
|
||||
device_add(&mach64gx_device);
|
||||
return;
|
||||
|
||||
case GFX_CL_GD5429:
|
||||
video_load(vid_gd5429);
|
||||
device_add(&gd5429_device);
|
||||
return;
|
||||
|
||||
default:
|
||||
|
|
@ -263,78 +232,26 @@ void video_init()
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t cga32[256];
|
||||
|
||||
BITMAP *buffer,*vbuf;//,*vbuf2;
|
||||
BITMAP *buffer32;
|
||||
int speshul=0;
|
||||
BITMAP *buffer, *buffer32;
|
||||
|
||||
uint8_t fontdat[256][8];
|
||||
uint8_t fontdatm[256][16];
|
||||
|
||||
int dispontime,dispofftime;
|
||||
double disptime;
|
||||
int svgaon;
|
||||
uint8_t cgamode=1,cgastat,cgacol=7,ocgamode;
|
||||
int linepos=0;
|
||||
int output;
|
||||
uint8_t *vram,*ram;
|
||||
|
||||
int cgadispon=0;
|
||||
int cgablink;
|
||||
|
||||
uint8_t port3de,port3dd,port3df;
|
||||
|
||||
uint8_t crtc[128],crtcreg;
|
||||
uint8_t crtcmask[128]={0xFF,0xFF,0xFF,0xFF,0x7F,0x1F,0x7F,0x7F,0xF3,0x1F,0x7F,0x1F,0x3F,0xFF,0x3F,0xFF,0xFF,0xFF};
|
||||
uint8_t charbuffer[256];
|
||||
int crtcams[64]={0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1};
|
||||
int nmi=0;
|
||||
|
||||
|
||||
int xsize=1,ysize=1;
|
||||
int firstline=1000,lastline=0;
|
||||
|
||||
int ntsc_col[8][8]=
|
||||
|
||||
PALETTE cgapal;/* =
|
||||
{
|
||||
{0,0,0,0,0,0,0,0}, /*Black*/
|
||||
{0,0,1,1,1,1,0,0}, /*Blue*/
|
||||
{1,0,0,0,0,1,1,1}, /*Green*/
|
||||
{0,0,0,0,1,1,1,1}, /*Cyan*/
|
||||
{1,1,1,1,0,0,0,0}, /*Red*/
|
||||
{0,1,1,1,1,0,0,0}, /*Magenta*/
|
||||
{1,1,0,0,0,0,1,1}, /*Yellow*/
|
||||
{1,1,1,1,1,1,1,1} /*White*/
|
||||
};
|
||||
{ 0, 0, 0},{0,42,0},{42,0,0},{42,21,0},
|
||||
{ 0, 0, 0},{0,42,42},{42,0,42},{42,42,42},
|
||||
{ 0, 0, 0},{21,63,21},{63,21,21},{63,63,21},
|
||||
{ 0, 0, 0},{21,63,63},{63,21,63},{63,63,63},
|
||||
|
||||
|
||||
extern int fullchange;
|
||||
|
||||
extern uint32_t vrammask;
|
||||
|
||||
|
||||
int mdacols[256][2][2];
|
||||
uint8_t gdcreg[16];
|
||||
|
||||
|
||||
int cga4pal[8][4]=
|
||||
{
|
||||
{0,2,4,6},{0,3,5,7},{0,3,4,7},{0,3,4,7},
|
||||
{0,10,12,14},{0,11,13,15},{0,11,12,15},{0,11,12,15}
|
||||
};
|
||||
|
||||
|
||||
PALETTE cgapal=
|
||||
{
|
||||
{0,0,0},{0,42,0},{42,0,0},{42,21,0},
|
||||
{0,0,0},{0,42,42},{42,0,42},{42,42,42},
|
||||
{0,0,0},{21,63,21},{63,21,21},{63,63,21},
|
||||
{0,0,0},{21,63,63},{63,21,63},{63,63,63},
|
||||
|
||||
{0,0,0},{0,0,42},{0,42,0},{0,42,42},
|
||||
{42,0,0},{42,0,42},{42,21,00},{42,42,42},
|
||||
{21,21,21},{21,21,63},{21,63,21},{21,63,63},
|
||||
{63,21,21},{63,21,63},{63,63,21},{63,63,63},
|
||||
{0, 0, 0}, { 0, 0, 42}, { 0, 42, 0}, { 0, 42, 42},
|
||||
{42, 0, 0}, {42, 0, 42}, {42, 21, 00}, {42, 42, 42},
|
||||
{21, 21, 21}, {21, 21, 63}, {21, 63, 21}, {21, 63, 63},
|
||||
{63, 21, 21}, {63, 21, 63}, {63, 63, 21}, {63, 63, 63},
|
||||
|
||||
{0,0,0},{0,21,0},{0,0,42},{0,42,42},
|
||||
{42,0,21},{21,10,21},{42,0,42},{42,0,63},
|
||||
|
|
@ -345,7 +262,7 @@ PALETTE cgapal=
|
|||
{0,0,0},{0,42,42},{42,0,0},{42,42,42},
|
||||
{0,0,0},{0,63,63},{63,0,0},{63,63,63},
|
||||
{0,0,0},{0,63,63},{63,0,0},{63,63,63},
|
||||
};
|
||||
};*/
|
||||
|
||||
void loadfont(char *s, int format)
|
||||
{
|
||||
|
|
@ -419,102 +336,53 @@ void loadfont(char *s, int format)
|
|||
}
|
||||
|
||||
|
||||
void drawscreen()
|
||||
{
|
||||
// printf("Drawscreen %i %i %i %i\n",gfxcard,MDA,EGA,TANDY);
|
||||
// if (EGA) drawscreenega(buffer,vbuf);
|
||||
/* else if (MDA) {}//drawscreenmda();
|
||||
else if (TANDY)
|
||||
{
|
||||
if ((cgamode&3)==3 || array[3]&0x10) drawscreentandy(tandyvram);
|
||||
else drawscreencga(tandyvram);
|
||||
}*/
|
||||
// else drawscreencga(&vram[0x8000]);
|
||||
}
|
||||
|
||||
PALETTE comppal=
|
||||
{
|
||||
{0,0,0},{0,21,0},{0,0,42},{0,42,42},
|
||||
{42,0,21},{21,10,21},{42,0,42},{42,0,63},
|
||||
{21,21,21},{21,63,21},{42,21,42},{21,63,31},
|
||||
{63,0,0},{42,42,0},{63,21,42},{41,41,41}
|
||||
};
|
||||
|
||||
void initvideo()
|
||||
{
|
||||
int c;
|
||||
// set_color_depth(desktop_color_depth());
|
||||
// if (set_gfx_mode(GFX_AUTODETECT_WINDOWED,2048,2048,0,0))
|
||||
// set_gfx_mode(GFX_AUTODETECT_WINDOWED,1024,768,0,0);
|
||||
// vbuf=create_video_bitmap(1280+32,1024+32);
|
||||
// set_color_depth(32);
|
||||
buffer32=create_bitmap(2048,2048);
|
||||
// set_color_depth(8);
|
||||
buffer=create_bitmap(2048,2048);
|
||||
// set_color_depth(32);
|
||||
for (c=0;c<64;c++)
|
||||
{
|
||||
cgapal[c+64].r=(((c&4)?2:0)|((c&0x10)?1:0))*21;
|
||||
cgapal[c+64].g=(((c&2)?2:0)|((c&0x10)?1:0))*21;
|
||||
cgapal[c+64].b=(((c&1)?2:0)|((c&0x10)?1:0))*21;
|
||||
if ((c&0x17)==6) cgapal[c+64].g>>=1;
|
||||
}
|
||||
for (c=0;c<64;c++)
|
||||
{
|
||||
cgapal[c+128].r=(((c&4)?2:0)|((c&0x20)?1:0))*21;
|
||||
cgapal[c+128].g=(((c&2)?2:0)|((c&0x10)?1:0))*21;
|
||||
cgapal[c+128].b=(((c&1)?2:0)|((c&0x08)?1:0))*21;
|
||||
}
|
||||
for (c=0;c<256;c++) cga32[c]=makecol(cgapal[c].r<<2,cgapal[c].g<<2,cgapal[c].b<<2);
|
||||
// for (c=0;c<16;c++) cgapal[c+192]=comppal[c];
|
||||
// set_palette(cgapal);
|
||||
if (MDA && !TANDY && !AMSTRAD && romset!=ROM_PC200) updatewindowsize(720,350);
|
||||
else updatewindowsize(656,416);
|
||||
for (c=17;c<64;c++) crtcmask[c]=0xFF;
|
||||
}
|
||||
int c, d, e;
|
||||
|
||||
void resetvideo()
|
||||
{
|
||||
int c;
|
||||
if (MDA && !TANDY && !AMSTRAD && romset!=ROM_PC200) updatewindowsize(720,350);
|
||||
else updatewindowsize(656,416);
|
||||
cgastat=0;
|
||||
set_palette(cgapal);
|
||||
buffer32 = create_bitmap(2048, 2048);
|
||||
|
||||
for (c=18;c<64;c++) crtcmask[c]=0xFF;
|
||||
crtc[0]=0x38;
|
||||
crtc[1]=0x28;
|
||||
// crtc[3]=0xFA;
|
||||
crtc[4]=0x7F;
|
||||
crtc[5]=0x06;
|
||||
crtc[6]=0x64;
|
||||
crtc[7]=0x70;
|
||||
crtc[8]=0x02;
|
||||
crtc[9]=1;
|
||||
buffer = create_bitmap(2048, 2048);
|
||||
|
||||
cgacol=7;
|
||||
for (c=0;c<256;c++)
|
||||
for (c = 0; c < 64; c++)
|
||||
{
|
||||
mdacols[c][0][0]=mdacols[c][1][0]=mdacols[c][1][1]=16;
|
||||
if (c&8) mdacols[c][0][1]=15+16;
|
||||
else mdacols[c][0][1]=7+16;
|
||||
cgapal[c + 64].r = (((c & 4) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
|
||||
cgapal[c + 64].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
|
||||
cgapal[c + 64].b = (((c & 1) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
|
||||
if ((c & 0x17) == 6)
|
||||
cgapal[c + 64].g >>= 1;
|
||||
}
|
||||
for (c = 0; c < 64; c++)
|
||||
{
|
||||
cgapal[c + 128].r = (((c & 4) ? 2 : 0) | ((c & 0x20) ? 1 : 0)) * 21;
|
||||
cgapal[c + 128].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
|
||||
cgapal[c + 128].b = (((c & 1) ? 2 : 0) | ((c & 0x08) ? 1 : 0)) * 21;
|
||||
}
|
||||
|
||||
for (c = 0; c < 256; c++)
|
||||
{
|
||||
e = c;
|
||||
for (d = 0; d < 8; d++)
|
||||
{
|
||||
rotatevga[d][c] = e;
|
||||
e = (e >> 1) | ((e & 1) ? 0x80 : 0);
|
||||
}
|
||||
}
|
||||
for (c = 0; c < 4; c++)
|
||||
{
|
||||
for (d = 0; d < 4; d++)
|
||||
{
|
||||
edatlookup[c][d] = 0;
|
||||
if (c & 1) edatlookup[c][d] |= 1;
|
||||
if (d & 1) edatlookup[c][d] |= 2;
|
||||
if (c & 2) edatlookup[c][d] |= 0x10;
|
||||
if (d & 2) edatlookup[c][d] |= 0x20;
|
||||
// printf("Edat %i,%i now %02X\n",c,d,edatlookup[c][d]);
|
||||
}
|
||||
}
|
||||
mdacols[0x70][0][1]=16;
|
||||
mdacols[0x70][0][0]=mdacols[0x70][1][0]=mdacols[0x70][1][1]=16+15;
|
||||
mdacols[0xF0][0][1]=16;
|
||||
mdacols[0xF0][0][0]=mdacols[0xF0][1][0]=mdacols[0xF0][1][1]=16+15;
|
||||
mdacols[0x78][0][1]=16+7;
|
||||
mdacols[0x78][0][0]=mdacols[0x78][1][0]=mdacols[0x78][1][1]=16+15;
|
||||
mdacols[0xF8][0][1]=16+7;
|
||||
mdacols[0xF8][0][0]=mdacols[0xF8][1][0]=mdacols[0xF8][1][1]=16+15;
|
||||
mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16;
|
||||
mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16;
|
||||
mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16;
|
||||
mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16;
|
||||
}
|
||||
|
||||
void closevideo()
|
||||
{
|
||||
destroy_bitmap(buffer);
|
||||
destroy_bitmap(vbuf);
|
||||
}
|
||||
|
|
|
|||
115
src/video.h
115
src/video.h
|
|
@ -1,70 +1,8 @@
|
|||
extern int egareads,egawrites;
|
||||
|
||||
extern int bpp;
|
||||
extern uint8_t svgaseg,svgaseg2;
|
||||
|
||||
extern uint8_t crtcreg;
|
||||
extern uint8_t crtc[128];
|
||||
extern uint8_t crtcmask[128];
|
||||
extern uint8_t gdcreg[16];
|
||||
extern int gdcaddr;
|
||||
extern uint8_t attrregs[32];
|
||||
extern int attraddr,attrff;
|
||||
extern uint8_t seqregs[64];
|
||||
extern int seqaddr;
|
||||
extern int svgaon;
|
||||
|
||||
extern uint8_t cgamode,cgacol,cgastat;
|
||||
extern int egapal[16];
|
||||
|
||||
extern int scrblank;
|
||||
|
||||
extern uint8_t writemask,charset;
|
||||
extern int charseta,charsetb;
|
||||
extern uint8_t colourcompare,colournocare;
|
||||
extern int readplane,readmode,writemode;
|
||||
|
||||
extern int vidclock;
|
||||
extern int vres;
|
||||
|
||||
extern uint32_t *pallook,pallook16[256],pallook64[256],pallook256[256];
|
||||
|
||||
extern int fullchange;
|
||||
extern int changeframecount;
|
||||
|
||||
extern int firstline,lastline;
|
||||
extern int ega_hdisp,ega_rowoffset,ega_split,ega_dispend,ega_vsyncstart,ega_vtotal;
|
||||
extern int dispontime,dispofftime;
|
||||
extern double disptime;
|
||||
|
||||
extern void (*video_out) (uint16_t addr, uint8_t val, void *priv);
|
||||
extern void (*video_mono_out)(uint16_t addr, uint8_t val, void *priv);
|
||||
extern uint8_t (*video_in) (uint16_t addr, void *priv);
|
||||
extern uint8_t (*video_mono_in)(uint16_t addr, void *priv);
|
||||
|
||||
extern void (*video_write_a000)(uint32_t addr, uint8_t val, void *priv);
|
||||
extern void (*video_write_b000)(uint32_t addr, uint8_t val, void *priv);
|
||||
extern void (*video_write_b800)(uint32_t addr, uint8_t val, void *priv);
|
||||
|
||||
extern uint8_t (*video_read_a000)(uint32_t addr, void *priv);
|
||||
extern uint8_t (*video_read_b000)(uint32_t addr, void *priv);
|
||||
extern uint8_t (*video_read_b800)(uint32_t addr, void *priv);
|
||||
|
||||
extern void (*video_write_a000_w)(uint32_t addr, uint16_t val, void *priv);
|
||||
extern void (*video_write_a000_l)(uint32_t addr, uint32_t val, void *priv);
|
||||
|
||||
extern void video_out_null(uint16_t addr, uint8_t val, void *priv);
|
||||
extern uint8_t video_in_null(uint16_t addr, void *priv);
|
||||
|
||||
extern void video_write_null(uint32_t addr, uint8_t val, void *priv);
|
||||
extern uint8_t video_read_null (uint32_t addr, void *priv);
|
||||
|
||||
|
||||
extern int video_timer;
|
||||
|
||||
extern uint8_t tridentoldctrl2,tridentnewctrl2;
|
||||
extern int rowdbl;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int w, h;
|
||||
|
|
@ -72,73 +10,23 @@ typedef struct
|
|||
uint8_t *line[0];
|
||||
} BITMAP;
|
||||
|
||||
extern BITMAP *buffer,*buffer32,*vbuf;
|
||||
extern BITMAP *buffer, *buffer32;
|
||||
|
||||
extern BITMAP *screen;
|
||||
|
||||
BITMAP *create_bitmap(int w, int h);
|
||||
|
||||
extern int wx,wy;
|
||||
|
||||
extern uint8_t fontdat[256][8];
|
||||
extern uint8_t fontdatm[256][16];
|
||||
|
||||
|
||||
extern int xsize,ysize;
|
||||
|
||||
extern int dacread,dacwrite,dacpos;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t r, g, b;
|
||||
} RGB;
|
||||
|
||||
typedef RGB PALETTE[256];
|
||||
extern PALETTE vgapal;
|
||||
extern int palchange;
|
||||
|
||||
|
||||
extern uint32_t vrammask;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int (*init)();
|
||||
void (*out)(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t (*in)(uint16_t addr, void *priv);
|
||||
void (*mono_out)(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t (*mono_in)(uint16_t addr, void *priv);
|
||||
void (*poll)();
|
||||
void (*recalctimings)();
|
||||
void (*write_a000)(uint32_t addr, uint8_t val, void *priv);
|
||||
void (*write_b000)(uint32_t addr, uint8_t val, void *priv);
|
||||
void (*write_b800)(uint32_t addr, uint8_t val, void *priv);
|
||||
uint8_t (*read_a000)(uint32_t addr, void *priv);
|
||||
uint8_t (*read_b000)(uint32_t addr, void *priv);
|
||||
uint8_t (*read_b800)(uint32_t addr, void *priv);
|
||||
} GFXCARD;
|
||||
|
||||
extern GFXCARD vid_cga;
|
||||
extern GFXCARD vid_mda;
|
||||
extern GFXCARD vid_hercules;
|
||||
extern GFXCARD vid_pc1512;
|
||||
extern GFXCARD vid_pc1640;
|
||||
extern GFXCARD vid_pc200;
|
||||
extern GFXCARD vid_m24;
|
||||
extern GFXCARD vid_paradise;
|
||||
extern GFXCARD vid_tandy;
|
||||
extern GFXCARD vid_ega;
|
||||
extern GFXCARD vid_oti067;
|
||||
extern GFXCARD vid_tvga;
|
||||
extern GFXCARD vid_et4000;
|
||||
extern GFXCARD vid_et4000w32p;
|
||||
extern GFXCARD vid_s3;
|
||||
extern GFXCARD vid_s3_virge;
|
||||
extern GFXCARD vid_tgui9440;
|
||||
extern GFXCARD vid_vga;
|
||||
extern GFXCARD vid_ati18800;
|
||||
extern GFXCARD vid_ati28800;
|
||||
extern GFXCARD vid_mach64;
|
||||
extern GFXCARD vid_gd5429;
|
||||
|
||||
extern float cpuclock;
|
||||
|
||||
|
|
@ -154,7 +42,6 @@ extern void (*video_recalctimings)();
|
|||
extern void (*video_blit_memtoscreen)(int x, int y, int y1, int y2, int w, int h);
|
||||
extern void (*video_blit_memtoscreen_8)(int x, int y, int w, int h);
|
||||
|
||||
|
||||
extern int video_timing_b, video_timing_w, video_timing_l;
|
||||
extern int video_speed;
|
||||
|
||||
|
|
|
|||
20
src/win.c
20
src/win.c
|
|
@ -377,6 +377,9 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
loadbios();
|
||||
|
||||
timeBeginPeriod(1);
|
||||
// soundobject=CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
// soundthreadh=CreateThread(NULL,0,soundthread,NULL,NULL,NULL);
|
||||
|
|
@ -758,8 +761,8 @@ BOOL CALLBACK configdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara
|
|||
sound_card_current = temp_sound_card_current;
|
||||
|
||||
mem_resize();
|
||||
loadbios();
|
||||
mem_load_video_bios();
|
||||
loadbios();
|
||||
resetpchard();
|
||||
}
|
||||
else
|
||||
|
|
@ -1327,6 +1330,7 @@ BOOL CALLBACK statusdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara
|
|||
{
|
||||
int egasp;
|
||||
char s[256];
|
||||
char device_s[4096];
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
|
|
@ -1350,18 +1354,8 @@ BOOL CALLBACK statusdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPara
|
|||
SendDlgItemMessage(hdlg,IDC_STEXT7,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
|
||||
sprintf(s,"Timer 0 frequency : %fHz",pit_timer0_freq());
|
||||
SendDlgItemMessage(hdlg,IDC_STEXT8,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
|
||||
if (chain4) sprintf(s,"VGA chained (possibly mode 13h)");
|
||||
else sprintf(s,"VGA unchained (possibly mode-X)");
|
||||
SendDlgItemMessage(hdlg,IDC_STEXT9,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
|
||||
/* if (!video_bpp) sprintf(s,"VGA in text mode");
|
||||
else */sprintf(s,"VGA colour depth : %i bpp", video_bpp);
|
||||
SendDlgItemMessage(hdlg,IDC_STEXT10,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
|
||||
sprintf(s,"VGA resolution : %i x %i", video_res_x, video_res_y);
|
||||
SendDlgItemMessage(hdlg,IDC_STEXT11,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
|
||||
sprintf(s,"SB frequency : %i Hz",0);
|
||||
SendDlgItemMessage(hdlg,IDC_STEXT12,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
|
||||
sprintf(s,"Video refresh rate : %i Hz", emu_fps);
|
||||
SendDlgItemMessage(hdlg,IDC_STEXT13,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
|
||||
device_add_status_info(device_s, 4096);
|
||||
SendDlgItemMessage(hdlg,IDC_STEXT_DEVICE,WM_SETTEXT,(WPARAM)NULL,(LPARAM)device_s);
|
||||
return TRUE;
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
|
|
|
|||
Loading…
Reference in a new issue